Skip to content

Commit

Permalink
feat(satori): support access to bot in internal routers
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Dec 23, 2024
1 parent 0bd1f86 commit 9616045
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 27 deletions.
5 changes: 0 additions & 5 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,6 @@
"utilities",
"cordis"
],
"scripts": {
"compile:cjs": "esbuild src/index.ts --outfile=lib/index.cjs --bundle --sourcemap --sources-content=false --platform=node --external:cosmokit --external:cordis --target=es2022",
"compile:esm": "esbuild src/index.ts --outfile=lib/index.mjs --bundle --sourcemap --sources-content=false --platform=neutral --external:cosmokit --external:cordis --target=es2022",
"build": "yarn compile:cjs && yarn compile:esm && yarn dtsc"
},
"cordis": {
"ecosystem": {
"name": "satori",
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export abstract class Bot<C extends Context = Context, T = any> {
public callbacks: Dict<Function> = {}
public logger: Logger

public _internalRouter: InternalRouter
public _internalRouter: InternalRouter<C>

// Same as `this.ctx`, but with a more specific type.
protected context: Context
Expand Down Expand Up @@ -83,7 +83,7 @@ export abstract class Bot<C extends Context = Context, T = any> {
return `internal${slash ? '/' : ':'}${this.platform}/${this.selfId}${path}${search}`
}

defineInternalRoute<P extends string>(path: P, callback: (request: InternalRequest<ExtractParams<P>>) => Promise<Response>) {
defineInternalRoute<P extends string>(path: P, callback: (request: InternalRequest<C, ExtractParams<P>>) => Promise<Response>) {
return this._internalRouter.define(path, callback)
}

Expand Down
20 changes: 11 additions & 9 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,13 @@ export class Satori<C extends Context = Context> extends Service<unknown, C> {

public uid = Math.random().toString(36).slice(2)

public _internalRouter: InternalRouter
public _internalRouter: InternalRouter<C>
public _tempStore: Dict<Response> = Object.create(null)

constructor(ctx?: C) {
super(ctx)
ctx.mixin('satori', ['bots', 'component'])

this._internalRouter = new InternalRouter(ctx)
this.defineInternalRoute('/_tmp/:id', async ({ params }) => {
return this._tempStore[params.id] ?? { status: 404 }
})

defineProperty(this.bots, Service.tracker, {})

const self = this
Expand All @@ -148,6 +143,13 @@ export class Satori<C extends Context = Context> extends Service<unknown, C> {
const filename = headers?.get('content-disposition')?.split('filename=')[1]
return { data: body, filename, type, mime: type }
})

this._internalRouter = new InternalRouter(ctx)

this.defineInternalRoute('/_tmp/:id', async ({ params, method }) => {
if (method !== 'GET') return { status: 405 }
return this._tempStore[params.id] ?? { status: 404 }
})
}

public bots = new Proxy([], {
Expand Down Expand Up @@ -179,7 +181,7 @@ export class Satori<C extends Context = Context> extends Service<unknown, C> {
return this.ctx.set('component:' + name, render)
}

defineInternalRoute<P extends string>(path: P, callback: (request: InternalRequest<ExtractParams<P>>) => Promise<Response>) {
defineInternalRoute<P extends string>(path: P, callback: (request: InternalRequest<C, ExtractParams<P>>) => Promise<Response>) {
return this._internalRouter.define(path, callback)
}

Expand All @@ -189,8 +191,8 @@ export class Satori<C extends Context = Context> extends Service<unknown, C> {
const [, platform, selfId, path] = capture
const bot = this.bots[`${platform}:${selfId}`]
if (!bot) return { status: 404 }
let response = await bot._internalRouter.handle(method, path, url.searchParams, headers, body)
response ??= await this._internalRouter.handle(method, path, url.searchParams, headers, body)
let response = await bot._internalRouter.handle(bot, method, path, url.searchParams, headers, body)
response ??= await this._internalRouter.handle(bot, method, path, url.searchParams, headers, body)
if (!response) return { status: 404 }
return response
}
Expand Down
22 changes: 12 additions & 10 deletions packages/core/src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@ import { Dict, remove } from 'cosmokit'
import { HTTP } from '@cordisjs/plugin-http'
import { Response } from '@satorijs/protocol'
import { Key, pathToRegexp } from 'path-to-regexp'
import { Context } from '.'
import { Bot, Context } from '.'

export interface InternalRequest<P = any> {
export interface InternalRequest<C extends Context, P = any> {
bot: Bot<C>
method: HTTP.Method
params: P
query: URLSearchParams
headers: Dict<string> // Headers
body: any
body: ArrayBuffer
}

export interface InternalRoute {
export interface InternalRoute<C extends Context> {
regexp: RegExp
keys: Key[]
callback: (request: InternalRequest) => Promise<Response>
callback: (request: InternalRequest<C>) => Promise<Response>
}

type Upper =
Expand Down Expand Up @@ -65,18 +66,18 @@ export type ExtractParams<S extends string, O extends {} = {}, A extends 0[] = [
: ExtractParams<S, O, A>
: O

export class InternalRouter {
export class InternalRouter<C extends Context> {
public [Service.tracker] = {
property: 'ctx',
}

routes: InternalRoute[] = []
routes: InternalRoute<C>[] = []

constructor(public ctx: Context) {}

define<P extends string>(path: P, callback: (request: InternalRequest<ExtractParams<P>>) => Promise<Response>) {
define<P extends string>(path: P, callback: (request: InternalRequest<C, ExtractParams<P>>) => Promise<Response>) {
return this.ctx.effect(() => {
const route: InternalRoute = {
const route: InternalRoute<C> = {
...pathToRegexp(path),
callback,
}
Expand All @@ -85,7 +86,7 @@ export class InternalRouter {
})
}

handle(method: HTTP.Method, path: string, query: URLSearchParams, headers: Headers, body: any): undefined | Promise<Response> {
handle(bot: Bot<C>, method: HTTP.Method, path: string, query: URLSearchParams, headers: Headers, body: any): undefined | Promise<Response> {
for (const route of this.routes) {
const capture = route.regexp.exec(path)
if (!capture) continue
Expand All @@ -94,6 +95,7 @@ export class InternalRouter {
params[name] = capture[index + 1]
})
return route.callback({
bot,
method,
params,
query,
Expand Down
1 change: 0 additions & 1 deletion tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"compilerOptions": {
"target": "es2022",
"module": "esnext",
"sourceMap": true,
"declaration": true,
"emitDeclarationOnly": true,
"composite": true,
Expand Down

0 comments on commit 9616045

Please sign in to comment.