From 5080750a0d25f717576c2bcf3c3f2fdb2670bf06 Mon Sep 17 00:00:00 2001 From: Shigma Date: Sun, 8 Dec 2024 23:13:04 +0800 Subject: [PATCH] feat(satori): rename satori to internal --- adapters/satori/src/bot.ts | 7 ++--- packages/core/src/bot.ts | 22 +++++++++------- packages/core/src/index.ts | 26 +++++++++---------- packages/core/src/{virtual.ts => internal.ts} | 26 ++++++++++++------- packages/protocol/src/index.ts | 2 +- packages/server/src/index.ts | 7 +++-- 6 files changed, 48 insertions(+), 42 deletions(-) rename packages/core/src/{virtual.ts => internal.ts} (79%) diff --git a/adapters/satori/src/bot.ts b/adapters/satori/src/bot.ts index 269600cf..7964e6eb 100644 --- a/adapters/satori/src/bot.ts +++ b/adapters/satori/src/bot.ts @@ -61,11 +61,8 @@ export class SatoriBot extends Bot { - const search = query.toString() - let path = `/v1/proxy/satori:${this.platform}/${this.selfId}/${params.path}` - if (search) path += '?' + search - return await this.http(path, { + this.defineInternalRoute('/*path', async ({ method, params, query }) => { + return await this.http(`/v1/${this.getInternalUrl(params.path, query, true)}`, { method, responseType: 'arraybuffer', }) diff --git a/packages/core/src/bot.ts b/packages/core/src/bot.ts index d709cbaf..908d2ebe 100644 --- a/packages/core/src/bot.ts +++ b/packages/core/src/bot.ts @@ -4,7 +4,7 @@ import h from '@satorijs/element' import { Adapter } from './adapter' import { MessageEncoder } from './message' import { defineAccessor, Session } from './session' -import { ExtractParams, VirtualRequest, VirtualRouter } from './virtual' +import { ExtractParams, InternalRequest, InternalRouter } from './internal' import { Event, List, Login, Methods, Response, SendOptions, Status, Upload, User } from '@satorijs/protocol' /* eslint-enable @typescript-eslint/no-unused-vars */ @@ -41,7 +41,7 @@ export abstract class Bot { public callbacks: Dict = {} public logger: Logger - public _virtual: VirtualRouter + public _internalRouter: InternalRouter // Same as `this.ctx`, but with a more specific type. protected context: Context @@ -49,7 +49,7 @@ export abstract class Bot { constructor(public ctx: C, public config: T, platform?: string) { this.internal = null - this._virtual = new VirtualRouter(ctx) + this._internalRouter = new InternalRouter(ctx) this.context = ctx ctx.bots.push(this) this.context.emit('bot-added', this) @@ -58,7 +58,7 @@ export abstract class Bot { this.platform = platform } - this.proxyUrls = [`satori://temp/${ctx.satori.uid}/`] + this.proxyUrls = [] this.features = Object.entries(Methods) .filter(([, value]) => this[value.name]) .map(([key]) => key) @@ -77,12 +77,14 @@ export abstract class Bot { }) } - getVirtualUrl(path: string) { - return `satori:${this.platform}/${this.selfId}${path}` + getInternalUrl(path: string, init?: ConstructorParameters[0], slash?: boolean) { + let search = new URLSearchParams(init).toString() + if (search) search = '?' + search + return `internal${slash ? '/' : ':'}${this.platform}/${this.selfId}${path}${search}` } - defineVirtualRoute

(path: P, callback: (request: VirtualRequest>) => Promise) { - return this._virtual.define(path, callback) + defineInternalRoute

(path: P, callback: (request: InternalRequest>) => Promise) { + return this._internalRouter.define(path, callback) } update(login: Login) { @@ -215,7 +217,7 @@ export abstract class Bot { } this.ctx.satori._tempStore[id] = { status: 200, - data: upload.data, + body: upload.data, headers, } ids.push(id) @@ -229,7 +231,7 @@ export abstract class Bot { } } const _dispose = this.ctx.on('dispose', dispose) - return ids.map(id => this.getVirtualUrl(`/_tmp/${id}`)) + return ids.map(id => this.getInternalUrl(`/_tmp/${id}`)) } async supports(name: string, session: Partial = {}) { diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 4a1b6500..4d593c7c 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,7 +1,7 @@ import { Context, Logger, Service, z } from 'cordis' import { Awaitable, defineProperty, Dict } from 'cosmokit' import { Bot } from './bot' -import { ExtractParams, VirtualRequest, VirtualRouter } from './virtual' +import { ExtractParams, InternalRequest, InternalRouter } from './internal' import { Session } from './session' import { HTTP } from '@cordisjs/plugin-http' import { Response, SendOptions } from '@satorijs/protocol' @@ -23,7 +23,7 @@ export * as Universal from '@satorijs/protocol' export * from './bot' export * from './adapter' export * from './message' -export * from './virtual' +export * from './internal' export * from './session' declare module 'cordis' { @@ -120,15 +120,15 @@ export class Satori extends Service { public uid = Math.random().toString(36).slice(2) - public _virtual: VirtualRouter + public _internalRouter: InternalRouter public _tempStore: Dict = Object.create(null) constructor(ctx?: C) { super(ctx) ctx.mixin('satori', ['bots', 'component']) - this._virtual = new VirtualRouter(ctx) - this.defineVirtualRoute('/_tmp/:id', async ({ params }) => { + this._internalRouter = new InternalRouter(ctx) + this.defineInternalRoute('/_tmp/:id', async ({ params }) => { return this._tempStore[params.id] ?? { status: 404 } }) @@ -137,8 +137,8 @@ export class Satori extends Service { const self = this ;(ctx as Context).on('http/file', async function (_url, options) { const url = new URL(_url) - if (url.protocol !== 'satori:') return - const { status, data, headers } = await self.handleVirtualRoute('GET', url) + if (url.protocol !== 'internal:') return + const { status, body, headers } = await self.handleInternalRoute('GET', url) if (status >= 400) throw new Error(`Failed to fetch ${_url}, status code: ${status}`) if (status >= 300) { const location = headers?.get('location') @@ -146,7 +146,7 @@ export class Satori extends Service { } const type = headers?.get('content-type') const filename = headers?.get('content-disposition')?.split('filename=')[1] - return { data, filename, type, mime: type } + return { data: body, filename, type, mime: type } }) } @@ -179,18 +179,18 @@ export class Satori extends Service { return this.ctx.set('component:' + name, render) } - defineVirtualRoute

(path: P, callback: (request: VirtualRequest>) => Promise) { - return this._virtual.define(path, callback) + defineInternalRoute

(path: P, callback: (request: InternalRequest>) => Promise) { + return this._internalRouter.define(path, callback) } - async handleVirtualRoute(method: HTTP.Method, url: URL): Promise { + async handleInternalRoute(method: HTTP.Method, url: URL, headers = new Headers(), body?: any): Promise { const capture = /^([^/]+)\/([^/]+)(\/.+)$/.exec(url.pathname) if (!capture) return { status: 400 } const [, platform, selfId, path] = capture const bot = this.bots[`${platform}:${selfId}`] if (!bot) return { status: 404 } - let response = await bot._virtual.handle(method, path, url.searchParams) - response ??= await this._virtual.handle(method, path, url.searchParams) + let response = await bot._internalRouter.handle(method, path, url.searchParams, headers, body) + response ??= await this._internalRouter.handle(method, path, url.searchParams, headers, body) if (!response) return { status: 404 } return response } diff --git a/packages/core/src/virtual.ts b/packages/core/src/internal.ts similarity index 79% rename from packages/core/src/virtual.ts rename to packages/core/src/internal.ts index 12ad8e68..6e981181 100644 --- a/packages/core/src/virtual.ts +++ b/packages/core/src/internal.ts @@ -5,16 +5,18 @@ import { Response } from '@satorijs/protocol' import { Key, pathToRegexp } from 'path-to-regexp' import { Context } from '.' -export interface VirtualRequest

{ +export interface InternalRequest

{ method: HTTP.Method params: P query: URLSearchParams + headers: Dict // Headers + body: any } -export interface VirtualRoute { +export interface InternalRoute { regexp: RegExp keys: Key[] - callback: (request: VirtualRequest) => Promise + callback: (request: InternalRequest) => Promise } type Upper = @@ -63,18 +65,18 @@ export type ExtractParams : O -export class VirtualRouter { +export class InternalRouter { public [Service.tracker] = { property: 'ctx', } - routes: VirtualRoute[] = [] + routes: InternalRoute[] = [] constructor(public ctx: Context) {} - define

(path: P, callback: (request: VirtualRequest>) => Promise) { + define

(path: P, callback: (request: InternalRequest>) => Promise) { return this.ctx.effect(() => { - const route: VirtualRoute = { + const route: InternalRoute = { ...pathToRegexp(path), callback, } @@ -83,7 +85,7 @@ export class VirtualRouter { }) } - handle(method: HTTP.Method, path: string, query: URLSearchParams): undefined | Promise { + handle(method: HTTP.Method, path: string, query: URLSearchParams, headers: Headers, body: any): undefined | Promise { for (const route of this.routes) { const capture = route.regexp.exec(path) if (!capture) continue @@ -91,7 +93,13 @@ export class VirtualRouter { route.keys.forEach(({ name }, index) => { params[name] = capture[index + 1] }) - return route.callback({ method, params, query }) + return route.callback({ + method, + params, + query, + body, + headers: Object.fromEntries(headers.entries()), + }) } } } diff --git a/packages/protocol/src/index.ts b/packages/protocol/src/index.ts index d52648c9..23304cfe 100644 --- a/packages/protocol/src/index.ts +++ b/packages/protocol/src/index.ts @@ -14,7 +14,7 @@ export interface Upload { export interface Response { status: number statusText?: string - data?: ArrayBuffer + body?: ArrayBuffer headers?: Headers } diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index e5ce60b1..191b8849 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -2,7 +2,6 @@ import { Binary, camelCase, Context, Dict, makeArray, sanitize, Schema, Service, import {} from '@cordisjs/plugin-server' import WebSocket from 'ws' import { Readable } from 'node:stream' -import { ReadableStream } from 'node:stream/web' import { readFile } from 'node:fs/promises' import { ParameterizedContext } from 'koa' @@ -166,14 +165,14 @@ class SatoriServer extends Service { } koa.header['Access-Control-Allow-Origin'] = ctx.server.config.selfUrl || '*' - if (url.protocol === 'satori:') { - const { status, statusText, data, headers } = await ctx.satori.handleVirtualRoute('GET', url) + if (url.protocol === 'internal:') { + const { status, statusText, body, headers } = await ctx.satori.handleInternalRoute('GET', url) koa.status = status for (const [key, value] of headers || new Headers()) { koa.set(key, value) } if (status >= 200 && status < 300) { - koa.body = data instanceof ReadableStream ? Readable.fromWeb(data) : data ? Buffer.from(data) : null + koa.body = body ? Buffer.from(body) : null } else { koa.body = statusText }