gemi 0.113.0 → 0.115.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/index.js +32 -32
- package/dist/ai/index.js.map +3 -5
- package/dist/app/App.d.ts.map +1 -1
- package/dist/app/index.js +1 -1
- package/dist/bin/gemi.js +8 -1
- package/dist/bin/gemi.js.map +3 -3
- package/dist/bun/plugin.js +1 -1
- package/dist/bun/preload.js +1 -1
- package/dist/{chunk-1p85fdrk.js → chunk-0av6xvm6.js} +2 -2
- package/dist/{chunk-1p85fdrk.js.map → chunk-0av6xvm6.js.map} +1 -1
- package/dist/chunk-0z8ejxre.js +5 -0
- package/dist/chunk-0z8ejxre.js.map +12 -0
- package/dist/{chunk-r7b12dmm.js → chunk-15c2vgaf.js} +2 -2
- package/dist/{chunk-r7b12dmm.js.map → chunk-15c2vgaf.js.map} +1 -1
- package/dist/{chunk-fr0arqdj.js → chunk-1hr4xht1.js} +2 -2
- package/dist/{chunk-fr0arqdj.js.map → chunk-1hr4xht1.js.map} +1 -1
- package/dist/{chunk-4t1pbt9p.js → chunk-1myhm0g3.js} +3 -3
- package/dist/{chunk-4t1pbt9p.js.map → chunk-1myhm0g3.js.map} +1 -1
- package/dist/{chunk-v4gwmhtf.js → chunk-1vzks22y.js} +2 -2
- package/dist/{chunk-v4gwmhtf.js.map → chunk-1vzks22y.js.map} +1 -1
- package/dist/{chunk-vzf5pbx3.js → chunk-2tzm58j3.js} +2 -2
- package/dist/{chunk-vzf5pbx3.js.map → chunk-2tzm58j3.js.map} +1 -1
- package/dist/{chunk-qx87cdfg.js → chunk-2z1981d0.js} +2 -2
- package/dist/{chunk-qx87cdfg.js.map → chunk-2z1981d0.js.map} +1 -1
- package/dist/{chunk-mepaedy5.js → chunk-3hrj5rwm.js} +2 -2
- package/dist/{chunk-mepaedy5.js.map → chunk-3hrj5rwm.js.map} +1 -1
- package/dist/{chunk-rh2fad7n.js → chunk-41da9628.js} +1 -1
- package/dist/{chunk-5q4a7yqf.js → chunk-56jky6vf.js} +2 -2
- package/dist/{chunk-5q4a7yqf.js.map → chunk-56jky6vf.js.map} +1 -1
- package/dist/{chunk-5x0aacrn.js → chunk-785b41h1.js} +2 -2
- package/dist/{chunk-5x0aacrn.js.map → chunk-785b41h1.js.map} +1 -1
- package/dist/{chunk-nysqgzp1.js → chunk-7g9yh5ae.js} +2 -2
- package/dist/{chunk-nysqgzp1.js.map → chunk-7g9yh5ae.js.map} +1 -1
- package/dist/{chunk-g8kx549d.js → chunk-7vb4eey2.js} +3 -3
- package/dist/{chunk-g8kx549d.js.map → chunk-7vb4eey2.js.map} +1 -1
- package/dist/{chunk-szr1k584.js → chunk-8rv62v14.js} +2 -2
- package/dist/{chunk-szr1k584.js.map → chunk-8rv62v14.js.map} +1 -1
- package/dist/{chunk-68s1f5d5.js → chunk-98m15b9x.js} +2 -2
- package/dist/{chunk-68s1f5d5.js.map → chunk-98m15b9x.js.map} +1 -1
- package/dist/{chunk-y596ghpz.js → chunk-9b4erdy2.js} +2 -2
- package/dist/{chunk-y596ghpz.js.map → chunk-9b4erdy2.js.map} +1 -1
- package/dist/{chunk-rg4hhxj3.js → chunk-9n1hx3mq.js} +2 -2
- package/dist/{chunk-rg4hhxj3.js.map → chunk-9n1hx3mq.js.map} +1 -1
- package/dist/{chunk-9tpx9ag3.js → chunk-aazmrxj9.js} +2 -2
- package/dist/{chunk-9tpx9ag3.js.map → chunk-aazmrxj9.js.map} +1 -1
- package/dist/{chunk-01qd6xx3.js → chunk-aeh67ynz.js} +3 -3
- package/dist/{chunk-01qd6xx3.js.map → chunk-aeh67ynz.js.map} +1 -1
- package/dist/{chunk-5nqkwa2w.js → chunk-agyfv3f8.js} +1 -1
- package/dist/{chunk-sr18y2ck.js → chunk-bra1a1fq.js} +2 -2
- package/dist/{chunk-sr18y2ck.js.map → chunk-bra1a1fq.js.map} +1 -1
- package/dist/{chunk-y6v0x869.js → chunk-cbqazg9k.js} +2 -2
- package/dist/{chunk-y6v0x869.js.map → chunk-cbqazg9k.js.map} +1 -1
- package/dist/{chunk-k2fh4r0p.js → chunk-d2gfcf85.js} +2 -2
- package/dist/{chunk-k2fh4r0p.js.map → chunk-d2gfcf85.js.map} +1 -1
- package/dist/chunk-d6591xck.js +46 -0
- package/dist/{chunk-6g20zec2.js.map → chunk-d6591xck.js.map} +6 -6
- package/dist/{chunk-fnkjmq94.js → chunk-d9mar37g.js} +2 -2
- package/dist/{chunk-fnkjmq94.js.map → chunk-d9mar37g.js.map} +1 -1
- package/dist/chunk-dexdkh3z.js +14 -0
- package/dist/{chunk-cqnfp0n9.js.map → chunk-dexdkh3z.js.map} +7 -7
- package/dist/{chunk-bq5nqqeq.js → chunk-e573yxpq.js} +1 -1
- package/dist/{chunk-p3zmc8k8.js → chunk-eqse2m6n.js} +2 -2
- package/dist/{chunk-p3zmc8k8.js.map → chunk-eqse2m6n.js.map} +1 -1
- package/dist/{chunk-yyzexrnb.js → chunk-er3wf6ng.js} +2 -2
- package/dist/{chunk-yyzexrnb.js.map → chunk-er3wf6ng.js.map} +1 -1
- package/dist/{chunk-3f1kq32g.js → chunk-fre6f4nk.js} +2 -2
- package/dist/{chunk-3f1kq32g.js.map → chunk-fre6f4nk.js.map} +1 -1
- package/dist/{chunk-qt8nvpqp.js → chunk-fxgxf16k.js} +2 -2
- package/dist/{chunk-qt8nvpqp.js.map → chunk-fxgxf16k.js.map} +1 -1
- package/dist/{chunk-6wymbbes.js → chunk-gts5p6mw.js} +3 -3
- package/dist/{chunk-6wymbbes.js.map → chunk-gts5p6mw.js.map} +1 -1
- package/dist/{chunk-571rvxe6.js → chunk-hdps9n52.js} +2 -2
- package/dist/{chunk-571rvxe6.js.map → chunk-hdps9n52.js.map} +1 -1
- package/dist/{chunk-w45agtch.js → chunk-hytt9qyj.js} +2 -2
- package/dist/{chunk-w45agtch.js.map → chunk-hytt9qyj.js.map} +1 -1
- package/dist/{chunk-de03dewf.js → chunk-jafm3613.js} +2 -2
- package/dist/{chunk-de03dewf.js.map → chunk-jafm3613.js.map} +1 -1
- package/dist/{chunk-dbwhgyg3.js → chunk-jdhdrr2k.js} +2 -2
- package/dist/{chunk-dbwhgyg3.js.map → chunk-jdhdrr2k.js.map} +1 -1
- package/dist/{chunk-d04r0hdf.js → chunk-jmpw6bqz.js} +2 -2
- package/dist/{chunk-d04r0hdf.js.map → chunk-jmpw6bqz.js.map} +1 -1
- package/dist/{chunk-vwprq300.js → chunk-kejwjerj.js} +2 -2
- package/dist/{chunk-vwprq300.js.map → chunk-kejwjerj.js.map} +1 -1
- package/dist/{chunk-wr3e4sez.js → chunk-kqxdsv22.js} +2 -2
- package/dist/{chunk-wr3e4sez.js.map → chunk-kqxdsv22.js.map} +1 -1
- package/dist/{chunk-9vsj0ksk.js → chunk-ktr3k768.js} +3 -3
- package/dist/{chunk-9vsj0ksk.js.map → chunk-ktr3k768.js.map} +1 -1
- package/dist/{chunk-kz4yp5n7.js → chunk-m54s6jpr.js} +2 -2
- package/dist/{chunk-8mbyyh8j.js.map → chunk-m54s6jpr.js.map} +1 -1
- package/dist/{chunk-xqwdn9kb.js → chunk-mazznq15.js} +3 -3
- package/dist/{chunk-xqwdn9kb.js.map → chunk-mazznq15.js.map} +1 -1
- package/dist/{chunk-zng3qexn.js → chunk-mps6ynbh.js} +2 -2
- package/dist/{chunk-zng3qexn.js.map → chunk-mps6ynbh.js.map} +1 -1
- package/dist/{chunk-vdwagp7y.js → chunk-mqfzdfnz.js} +2 -2
- package/dist/{chunk-vdwagp7y.js.map → chunk-mqfzdfnz.js.map} +1 -1
- package/dist/{chunk-mk0rtgd1.js → chunk-mschc94q.js} +2 -2
- package/dist/{chunk-mk0rtgd1.js.map → chunk-mschc94q.js.map} +1 -1
- package/dist/{chunk-x5yq097b.js → chunk-mtbygktb.js} +3 -3
- package/dist/{chunk-x5yq097b.js.map → chunk-mtbygktb.js.map} +1 -1
- package/dist/{chunk-f1y8eggf.js → chunk-n672d4g8.js} +2 -2
- package/dist/{chunk-f1y8eggf.js.map → chunk-n672d4g8.js.map} +1 -1
- package/dist/{chunk-4tp2cr02.js → chunk-pyk3gzvc.js} +2 -2
- package/dist/{chunk-4tp2cr02.js.map → chunk-pyk3gzvc.js.map} +1 -1
- package/dist/{chunk-agw3anaf.js → chunk-qjhw8nje.js} +1 -1
- package/dist/{chunk-vqa3agzw.js → chunk-qsrcdzan.js} +3 -3
- package/dist/{chunk-vqa3agzw.js.map → chunk-qsrcdzan.js.map} +1 -1
- package/dist/{chunk-nksn6xcd.js → chunk-sr942vb1.js} +2 -2
- package/dist/{chunk-nksn6xcd.js.map → chunk-sr942vb1.js.map} +1 -1
- package/dist/{chunk-kexsfyjj.js → chunk-t04f3akb.js} +2 -2
- package/dist/{chunk-kexsfyjj.js.map → chunk-t04f3akb.js.map} +1 -1
- package/dist/chunk-t24p7gc6.js +5 -0
- package/dist/{chunk-fsfbyg5e.js.map → chunk-t24p7gc6.js.map} +1 -1
- package/dist/chunk-t4t3hqe0.js +10 -0
- package/dist/chunk-t4t3hqe0.js.map +38 -0
- package/dist/{chunk-z5hrymvn.js → chunk-t4yh4nf9.js} +3 -3
- package/dist/{chunk-z5hrymvn.js.map → chunk-t4yh4nf9.js.map} +1 -1
- package/dist/{chunk-c7mp2kyp.js → chunk-tn2bryy2.js} +2 -2
- package/dist/{chunk-c7mp2kyp.js.map → chunk-tn2bryy2.js.map} +1 -1
- package/dist/chunk-tw5kwbx4.js +4 -0
- package/dist/{chunk-kp7k4s5c.js.map → chunk-tw5kwbx4.js.map} +3 -3
- package/dist/{chunk-zyer1g7k.js → chunk-tzm3c7n6.js} +4 -4
- package/dist/{chunk-zyer1g7k.js.map → chunk-tzm3c7n6.js.map} +1 -1
- package/dist/{chunk-1se4t9rg.js → chunk-vbdty91k.js} +3 -3
- package/dist/{chunk-1se4t9rg.js.map → chunk-vbdty91k.js.map} +1 -1
- package/dist/{chunk-8mbyyh8j.js → chunk-vw8849ys.js} +2 -2
- package/dist/{chunk-kz4yp5n7.js.map → chunk-vw8849ys.js.map} +1 -1
- package/dist/{chunk-g8sc6scv.js → chunk-vxm6yevm.js} +2 -2
- package/dist/{chunk-g8sc6scv.js.map → chunk-vxm6yevm.js.map} +1 -1
- package/dist/{chunk-qpttgn4k.js → chunk-whtzggn6.js} +3 -3
- package/dist/{chunk-qpttgn4k.js.map → chunk-whtzggn6.js.map} +1 -1
- package/dist/{chunk-7jnpnjth.js → chunk-wyw6p3fg.js} +2 -2
- package/dist/{chunk-7jnpnjth.js.map → chunk-wyw6p3fg.js.map} +1 -1
- package/dist/{chunk-atmzm0z3.js → chunk-wzrt5mac.js} +2 -2
- package/dist/{chunk-atmzm0z3.js.map → chunk-wzrt5mac.js.map} +1 -1
- package/dist/{chunk-y6frz1vm.js → chunk-x7cpth2f.js} +1 -1
- package/dist/{chunk-essqp1ek.js → chunk-xt9tv99x.js} +2 -2
- package/dist/{chunk-essqp1ek.js.map → chunk-xt9tv99x.js.map} +1 -1
- package/dist/{chunk-x5sert1k.js → chunk-yhrye9cm.js} +2 -2
- package/dist/{chunk-x5sert1k.js.map → chunk-yhrye9cm.js.map} +1 -1
- package/dist/{chunk-vc9phr57.js → chunk-zyt2w03d.js} +2 -2
- package/dist/{chunk-vc9phr57.js.map → chunk-zyt2w03d.js.map} +1 -1
- package/dist/config/index.js +1 -1
- package/dist/console/run.js +2 -2
- package/dist/console/run.js.map +1 -1
- package/dist/container/index.js +2 -2
- package/dist/container/index.js.map +1 -1
- package/dist/database/index.js +2 -2
- package/dist/database/index.js.map +1 -1
- package/dist/email/index.js +2 -2
- package/dist/email/index.js.map +1 -1
- package/dist/facades/Storage.d.ts +25 -1
- package/dist/facades/Storage.d.ts.map +1 -1
- package/dist/facades/index.js +2 -2
- package/dist/facades/index.js.map +1 -1
- package/dist/foundation/index.js +2 -2
- package/dist/foundation/index.js.map +1 -1
- package/dist/http/HttpRequest.d.ts +31 -0
- package/dist/http/HttpRequest.d.ts.map +1 -1
- package/dist/http/McpRouter.d.ts +54 -1
- package/dist/http/McpRouter.d.ts.map +1 -1
- package/dist/http/RateLimitMiddleware.d.ts +4 -1
- package/dist/http/RateLimitMiddleware.d.ts.map +1 -1
- package/dist/http/index.d.ts +1 -0
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/index.js +2 -2
- package/dist/http/index.js.map +1 -1
- package/dist/http/modelOriginated.d.ts +36 -2
- package/dist/http/modelOriginated.d.ts.map +1 -1
- package/dist/i18n/dictionaryRuntime.js +2 -2
- package/dist/i18n/dictionaryRuntime.js.map +1 -1
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/index.js.map +1 -1
- package/dist/kernel/Kernel.d.ts +3 -0
- package/dist/kernel/Kernel.d.ts.map +1 -1
- package/dist/kernel/index.js +3 -3
- package/dist/kernel/index.js.map +3 -3
- package/dist/orm/index.js +2 -2
- package/dist/orm/index.js.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/index.js.map +1 -1
- package/dist/services/file-storage/drivers/AzureBlobDriver.d.ts +12 -1
- package/dist/services/file-storage/drivers/AzureBlobDriver.d.ts.map +1 -1
- package/dist/services/file-storage/drivers/FileStorageDriver.d.ts +32 -1
- package/dist/services/file-storage/drivers/FileStorageDriver.d.ts.map +1 -1
- package/dist/services/file-storage/drivers/FileSystemDriver.d.ts +22 -1
- package/dist/services/file-storage/drivers/FileSystemDriver.d.ts.map +1 -1
- package/dist/services/file-storage/drivers/S3Driver.d.ts +14 -1
- package/dist/services/file-storage/drivers/S3Driver.d.ts.map +1 -1
- package/dist/services/file-storage/drivers/types.d.ts +26 -0
- package/dist/services/file-storage/drivers/types.d.ts.map +1 -1
- package/dist/services/index.d.ts +8 -3
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +44 -9
- package/dist/services/index.js.map +8 -5
- package/dist/services/mcp/McpRegistry.d.ts +190 -29
- package/dist/services/mcp/McpRegistry.d.ts.map +1 -1
- package/dist/services/mcp/http/McpHttpServer.d.ts +153 -0
- package/dist/services/mcp/http/McpHttpServer.d.ts.map +1 -0
- package/dist/services/mcp/http/callers.d.ts +131 -0
- package/dist/services/mcp/http/callers.d.ts.map +1 -0
- package/dist/services/mcp/http/limits.d.ts +11 -0
- package/dist/services/mcp/http/limits.d.ts.map +1 -0
- package/dist/services/mcp/http/oauth/McpOAuthServer.d.ts +150 -0
- package/dist/services/mcp/http/oauth/McpOAuthServer.d.ts.map +1 -0
- package/dist/services/mcp/http/oauth/consentPage.d.ts +14 -0
- package/dist/services/mcp/http/oauth/consentPage.d.ts.map +1 -0
- package/dist/services/mcp/http/oauth/store.d.ts +98 -0
- package/dist/services/mcp/http/oauth/store.d.ts.map +1 -0
- package/dist/services/mcp/http/protocol.d.ts +95 -0
- package/dist/services/mcp/http/protocol.d.ts.map +1 -0
- package/dist/services/mcp/http/signedState.d.ts +25 -0
- package/dist/services/mcp/http/signedState.d.ts.map +1 -0
- package/dist/services/queue/work.js +2 -2
- package/dist/services/queue/work.js.map +1 -1
- package/dist/services/router/ApiRouteDispatcher.d.ts +29 -0
- package/dist/services/router/ApiRouteDispatcher.d.ts.map +1 -1
- package/dist/services/router/RouteServiceProvider.d.ts +6 -0
- package/dist/services/router/RouteServiceProvider.d.ts.map +1 -1
- package/dist/services/router/config.d.ts +16 -0
- package/dist/services/router/config.d.ts.map +1 -1
- package/dist/stats/route-table.js +1 -1
- package/dist/support/index.js +2 -2
- package/dist/support/index.js.map +1 -1
- package/dist/vitest/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-3z9vhjd7.js +0 -5
- package/dist/chunk-3z9vhjd7.js.map +0 -10
- package/dist/chunk-5zzhypmt.js +0 -5
- package/dist/chunk-5zzhypmt.js.map +0 -33
- package/dist/chunk-6g20zec2.js +0 -46
- package/dist/chunk-cqnfp0n9.js +0 -14
- package/dist/chunk-fsfbyg5e.js +0 -5
- package/dist/chunk-kp7k4s5c.js +0 -4
- /package/dist/{chunk-rh2fad7n.js.map → chunk-41da9628.js.map} +0 -0
- /package/dist/{chunk-5nqkwa2w.js.map → chunk-agyfv3f8.js.map} +0 -0
- /package/dist/{chunk-bq5nqqeq.js.map → chunk-e573yxpq.js.map} +0 -0
- /package/dist/{chunk-agw3anaf.js.map → chunk-qjhw8nje.js.map} +0 -0
- /package/dist/{chunk-y6frz1vm.js.map → chunk-x7cpth2f.js.map} +0 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { User } from "../../../../auth/types";
|
|
2
|
+
import { type McpCallerResolver, type McpResolution, type McpResolveContext } from "../callers";
|
|
3
|
+
import { type Budget } from "../limits";
|
|
4
|
+
import type { McpOAuthStore } from "./store";
|
|
5
|
+
export type McpOAuthServerOptions = {
|
|
6
|
+
/** Where clients, codes and tokens are kept. `MemoryMcpOAuthStore` for one process; a database for more. */
|
|
7
|
+
store: McpOAuthStore;
|
|
8
|
+
/**
|
|
9
|
+
* Loads the user a token was issued to, by the id it was issued under
|
|
10
|
+
* (`String(user.id)`), on every request: a deleted user's tokens stop
|
|
11
|
+
* working, and routes see the user as they are now. Answer the same shape a
|
|
12
|
+
* signed-in request's `req.ctx().user` has.
|
|
13
|
+
*/
|
|
14
|
+
findUser(id: string): Promise<User | null>;
|
|
15
|
+
/**
|
|
16
|
+
* The app's own consent page: a view (behind `auth`) that the browser is
|
|
17
|
+
* sent to as `<consentPath>?request=…`. It calls `consent(request, user)`
|
|
18
|
+
* and renders what that answers — the client, the scopes, and a form to
|
|
19
|
+
* post. Without it gemi serves a plain page of its own.
|
|
20
|
+
*/
|
|
21
|
+
consentPath?: string;
|
|
22
|
+
/** Where a signed-out user is sent from gemi's own consent page. Default: `auth.signInPath`. */
|
|
23
|
+
signInPath?: string;
|
|
24
|
+
/** The app's name on gemi's own consent page. Default: the endpoint's host. */
|
|
25
|
+
appName?: string;
|
|
26
|
+
/** How the signed-in user is named on the consent page. Default: email, name, or id. */
|
|
27
|
+
userLabel?(user: User): string;
|
|
28
|
+
/** Access token lifetime, in seconds. Default one hour. */
|
|
29
|
+
accessTokenTtl?: number;
|
|
30
|
+
/** Refresh token lifetime, in seconds; each refresh rotates it. Default 30 days. */
|
|
31
|
+
refreshTokenTtl?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Dynamic client registration (RFC 7591), which is how MCP clients
|
|
34
|
+
* (Claude, the Inspector) register themselves. On by default; `false`
|
|
35
|
+
* turns the endpoint off, for an app that registers its clients itself.
|
|
36
|
+
*/
|
|
37
|
+
registration?: false | {
|
|
38
|
+
/** Registrations per client address. Default 20 an hour. */
|
|
39
|
+
rateLimit?: Budget;
|
|
40
|
+
/**
|
|
41
|
+
* Narrows which redirect URIs a client may register, beyond gemi's
|
|
42
|
+
* own rule (https, or http on a loopback address). Answer `false` to
|
|
43
|
+
* refuse one — to allow only the clients you know, say.
|
|
44
|
+
*/
|
|
45
|
+
allowRedirectUri?(uri: URL): boolean;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
/** What the consent page shows and posts, from `McpOAuthServer.consent`. */
|
|
49
|
+
export type McpConsent = {
|
|
50
|
+
client: {
|
|
51
|
+
id: string;
|
|
52
|
+
/** What the client calls itself. Unverified: show it as such. */
|
|
53
|
+
name: string | null;
|
|
54
|
+
/** The host the user will be sent to after deciding — the one fact about the client that is verified. */
|
|
55
|
+
redirectHost: string;
|
|
56
|
+
};
|
|
57
|
+
scopes: {
|
|
58
|
+
name: string;
|
|
59
|
+
description: string;
|
|
60
|
+
}[];
|
|
61
|
+
user: {
|
|
62
|
+
id: string;
|
|
63
|
+
label: string;
|
|
64
|
+
};
|
|
65
|
+
/** The form to render: post `fields` and `decision=allow` or `decision=deny` to `action`. */
|
|
66
|
+
form: {
|
|
67
|
+
action: string;
|
|
68
|
+
method: "POST";
|
|
69
|
+
fields: {
|
|
70
|
+
request: string;
|
|
71
|
+
csrf: string;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* An OAuth 2.1 authorization server for the MCP endpoint, and the resolver
|
|
77
|
+
* for the tokens it issues: what lets a hosted MCP client (Claude.ai's
|
|
78
|
+
* connectors) act for a user who signed in and agreed (#762).
|
|
79
|
+
*
|
|
80
|
+
* - Discovery: protected resource metadata (RFC 9728) and authorization
|
|
81
|
+
* server metadata (RFC 8414). `WWW-Authenticate` on a 401 points at them.
|
|
82
|
+
* - Dynamic client registration (RFC 7591).
|
|
83
|
+
* - Authorization code with PKCE (S256 only), consent by the signed-in user
|
|
84
|
+
* on a page that cannot be framed, with a CSRF token bound to the request
|
|
85
|
+
* and the user, `iss` in the response (RFC 9207).
|
|
86
|
+
* - Tokens are opaque, stored hashed, and bound to the endpoint as their
|
|
87
|
+
* audience (RFC 8707). Refresh tokens rotate; a replayed one, like a
|
|
88
|
+
* replayed code, revokes the whole grant. Revocation (RFC 7009).
|
|
89
|
+
*
|
|
90
|
+
* The endpoints live under the MCP endpoint's path (`/mcp/oauth/…`) and the
|
|
91
|
+
* metadata at the origin's `/.well-known/…`, all on the configured host
|
|
92
|
+
* only.
|
|
93
|
+
*/
|
|
94
|
+
export declare class McpOAuthServer implements McpCallerResolver {
|
|
95
|
+
private readonly options;
|
|
96
|
+
readonly name = "oauth";
|
|
97
|
+
private context;
|
|
98
|
+
private issuer;
|
|
99
|
+
private base;
|
|
100
|
+
private readonly accessTtl;
|
|
101
|
+
private readonly refreshTtl;
|
|
102
|
+
constructor(options: McpOAuthServerOptions);
|
|
103
|
+
get store(): McpOAuthStore;
|
|
104
|
+
boot(context: McpResolveContext): void;
|
|
105
|
+
resolve(req: Request): Promise<McpResolution | null>;
|
|
106
|
+
challenge(): string;
|
|
107
|
+
handle(req: Request): Promise<Response | null>;
|
|
108
|
+
/**
|
|
109
|
+
* The consent request a consent page was sent with, for the signed-in
|
|
110
|
+
* `user`: what to show, and the form to post. `null` when the request is
|
|
111
|
+
* not one this server made, has expired, or names a client that is gone —
|
|
112
|
+
* render an error and offer no form.
|
|
113
|
+
*
|
|
114
|
+
* ```ts
|
|
115
|
+
* // a view behind `auth`, at consentPath
|
|
116
|
+
* const consent = await mcpOAuth.consent(req.search.get("request"), req.ctx().user);
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
consent(request: unknown, user: User | null | undefined): Promise<McpConsent | null>;
|
|
120
|
+
private resourceMetadata;
|
|
121
|
+
private serverMetadata;
|
|
122
|
+
private register;
|
|
123
|
+
private authorize;
|
|
124
|
+
/** gemi's own consent page, for an app without a `consentPath`. */
|
|
125
|
+
private consentScreen;
|
|
126
|
+
/**
|
|
127
|
+
* The user's decision, posted from a consent page. Only from this origin
|
|
128
|
+
* (`Origin`, or `Sec-Fetch-Site` when a browser sends no `Origin`), only by
|
|
129
|
+
* the user the page was rendered for (the CSRF token is bound to them and
|
|
130
|
+
* to the request), and only once.
|
|
131
|
+
*/
|
|
132
|
+
private decide;
|
|
133
|
+
private token;
|
|
134
|
+
private issue;
|
|
135
|
+
/** RFC 7009: revokes the grant the token belongs to. Answers 200 whatever the token was. */
|
|
136
|
+
private revoke;
|
|
137
|
+
/**
|
|
138
|
+
* The client a token or revocation request is from. A public client names
|
|
139
|
+
* itself; a confidential one proves it with its secret, in the body or in
|
|
140
|
+
* Basic auth.
|
|
141
|
+
*/
|
|
142
|
+
private authenticateClient;
|
|
143
|
+
private redirectBack;
|
|
144
|
+
/** The user signed in to this app in the browser: the session cookie only. */
|
|
145
|
+
private sessionUser;
|
|
146
|
+
private userLabel;
|
|
147
|
+
private scopeNames;
|
|
148
|
+
private resourceMetadataUrl;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=McpOAuthServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"McpOAuthServer.d.ts","sourceRoot":"","sources":["../../../../../services/mcp/http/oauth/McpOAuthServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { McpConsent } from "./McpOAuthServer";
|
|
2
|
+
/**
|
|
3
|
+
* Headers for any page that asks for consent: it must never be framed (a
|
|
4
|
+
* framed "Allow" button can be clicked through an overlay), cached, or leak
|
|
5
|
+
* its URL — which carries the request — in a `Referer`.
|
|
6
|
+
*/
|
|
7
|
+
export declare const CONSENT_PAGE_HEADERS: Readonly<Record<string, string>>;
|
|
8
|
+
/** The consent page gemi serves when the app has no `consentPath` of its own. */
|
|
9
|
+
export declare function consentPage(consent: McpConsent, app: {
|
|
10
|
+
name: string;
|
|
11
|
+
}): string;
|
|
12
|
+
/** A plain page for an authorization request that cannot be sent back to the client. */
|
|
13
|
+
export declare function errorPage(message: string): string;
|
|
14
|
+
//# sourceMappingURL=consentPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consentPage.d.ts","sourceRoot":"","sources":["../../../../../services/mcp/http/oauth/consentPage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAShE,CAAC;AAEH,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CA4C9E;AAED,wFAAwF;AACxF,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjD"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What `McpOAuthServer` keeps: the clients that registered, the authorization
|
|
3
|
+
* codes it handed out, and the tokens it issued.
|
|
4
|
+
*
|
|
5
|
+
* No secret is stored. A client secret, a code and a token are kept as their
|
|
6
|
+
* SHA-256 (`hash`), and looked up by it, so a read of the store is not a list
|
|
7
|
+
* of working credentials.
|
|
8
|
+
*
|
|
9
|
+
* Every code and token belongs to a *family*: one user's consent to one client.
|
|
10
|
+
* The family is what a refresh rotates within, what a replayed code or refresh
|
|
11
|
+
* token revokes, and what an app's "connected apps" screen lists and revokes.
|
|
12
|
+
*/
|
|
13
|
+
export interface McpOAuthStore {
|
|
14
|
+
createClient(client: McpOAuthClient): Promise<void>;
|
|
15
|
+
findClient(clientId: string): Promise<McpOAuthClient | null>;
|
|
16
|
+
saveCode(code: McpOAuthCode): Promise<void>;
|
|
17
|
+
findCode(hash: string): Promise<McpOAuthCode | null>;
|
|
18
|
+
saveToken(token: McpOAuthToken): Promise<void>;
|
|
19
|
+
/** The token with this hash, or `null` when there is none or its family was revoked. */
|
|
20
|
+
findToken(hash: string): Promise<McpOAuthToken | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Spends a single-use credential (a code, a refresh token): `true` when this
|
|
23
|
+
* call is the one that spent it, `false` when it was already spent. Must be
|
|
24
|
+
* atomic across every process sharing the store — two exchanges of one code
|
|
25
|
+
* racing must not both win. Kept until `expiresAt` (epoch ms).
|
|
26
|
+
*/
|
|
27
|
+
use(hash: string, expiresAt: number): Promise<boolean>;
|
|
28
|
+
/** Revokes every code and token of a family. Idempotent. */
|
|
29
|
+
revokeFamily(familyId: string): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
export type McpOAuthTokenEndpointAuthMethod = "none" | "client_secret_post" | "client_secret_basic";
|
|
32
|
+
export type McpOAuthClient = {
|
|
33
|
+
clientId: string;
|
|
34
|
+
/** SHA-256 hex of the secret, for a confidential client; `null` for a public one. */
|
|
35
|
+
clientSecretHash: string | null;
|
|
36
|
+
tokenEndpointAuthMethod: McpOAuthTokenEndpointAuthMethod;
|
|
37
|
+
redirectUris: string[];
|
|
38
|
+
/** What the client calls itself: unverified, shown on the consent screen as such. */
|
|
39
|
+
clientName: string | null;
|
|
40
|
+
clientUri: string | null;
|
|
41
|
+
/** Epoch ms. */
|
|
42
|
+
createdAt: number;
|
|
43
|
+
};
|
|
44
|
+
export type McpOAuthCode = {
|
|
45
|
+
hash: string;
|
|
46
|
+
clientId: string;
|
|
47
|
+
userId: string;
|
|
48
|
+
redirectUri: string;
|
|
49
|
+
/** The S256 PKCE challenge the code is redeemed against. */
|
|
50
|
+
codeChallenge: string;
|
|
51
|
+
scopes: string[];
|
|
52
|
+
/** The resource (audience) the tokens will be for. */
|
|
53
|
+
resource: string;
|
|
54
|
+
familyId: string;
|
|
55
|
+
/** Epoch ms. */
|
|
56
|
+
expiresAt: number;
|
|
57
|
+
};
|
|
58
|
+
export type McpOAuthToken = {
|
|
59
|
+
hash: string;
|
|
60
|
+
kind: "access" | "refresh";
|
|
61
|
+
clientId: string;
|
|
62
|
+
userId: string;
|
|
63
|
+
scopes: string[];
|
|
64
|
+
/** The audience: the MCP endpoint's URL. A token is accepted nowhere else. */
|
|
65
|
+
resource: string;
|
|
66
|
+
familyId: string;
|
|
67
|
+
/** Epoch ms. */
|
|
68
|
+
expiresAt: number;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* `McpOAuthStore` in this process's memory: for development, tests, and an
|
|
72
|
+
* app with one instance that accepts every connection being lost on a
|
|
73
|
+
* restart. With more than one instance use a shared store (a database), or a
|
|
74
|
+
* token issued by one instance is unknown to the next.
|
|
75
|
+
*/
|
|
76
|
+
export declare class MemoryMcpOAuthStore implements McpOAuthStore {
|
|
77
|
+
private readonly clients;
|
|
78
|
+
private readonly codes;
|
|
79
|
+
private readonly tokens;
|
|
80
|
+
private readonly used;
|
|
81
|
+
private readonly revoked;
|
|
82
|
+
createClient(client: McpOAuthClient): Promise<void>;
|
|
83
|
+
findClient(clientId: string): Promise<McpOAuthClient>;
|
|
84
|
+
saveCode(code: McpOAuthCode): Promise<void>;
|
|
85
|
+
findCode(hash: string): Promise<McpOAuthCode>;
|
|
86
|
+
saveToken(token: McpOAuthToken): Promise<void>;
|
|
87
|
+
findToken(hash: string): Promise<McpOAuthToken>;
|
|
88
|
+
use(hash: string, expiresAt: number): Promise<boolean>;
|
|
89
|
+
revokeFamily(familyId: string): Promise<void>;
|
|
90
|
+
/** Every family a user has, for a "connected apps" screen. */
|
|
91
|
+
families(userId: string): Promise<{
|
|
92
|
+
familyId: string;
|
|
93
|
+
clientId: string;
|
|
94
|
+
scopes: string[];
|
|
95
|
+
}[]>;
|
|
96
|
+
private sweep;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../../services/mcp/http/oauth/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { McpToolDescriptor } from "../McpRegistry";
|
|
2
|
+
/**
|
|
3
|
+
* The MCP wire vocabulary the transport speaks, kept apart from the transport
|
|
4
|
+
* so the shapes can be read in one place.
|
|
5
|
+
*
|
|
6
|
+
* Two eras share the endpoint (see "Versioning" in the 2026-07-28 spec):
|
|
7
|
+
*
|
|
8
|
+
* - **modern** (`2026-07-28`): stateless. Every request carries its protocol
|
|
9
|
+
* version and the client's capabilities in `_meta`, and the transport keeps
|
|
10
|
+
* nothing between requests. Server-to-client requests (elicitation) are
|
|
11
|
+
* returned as an `input_required` result and the client retries.
|
|
12
|
+
* - **legacy** (`2025-03-26` to `2025-11-25`): an `initialize` handshake opens
|
|
13
|
+
* a session named by `Mcp-Session-Id`, and the server sends its own requests
|
|
14
|
+
* on the response stream of the call they belong to.
|
|
15
|
+
*/
|
|
16
|
+
export declare const MODERN_VERSIONS: readonly ["2026-07-28"];
|
|
17
|
+
export declare const LEGACY_VERSIONS: readonly ["2025-11-25", "2025-06-18", "2025-03-26"];
|
|
18
|
+
export declare const SUPPORTED_VERSIONS: readonly string[];
|
|
19
|
+
export type LegacyVersion = (typeof LEGACY_VERSIONS)[number];
|
|
20
|
+
export declare const META_PROTOCOL_VERSION = "io.modelcontextprotocol/protocolVersion";
|
|
21
|
+
export declare const META_CLIENT_CAPABILITIES = "io.modelcontextprotocol/clientCapabilities";
|
|
22
|
+
export declare const META_CLIENT_INFO = "io.modelcontextprotocol/clientInfo";
|
|
23
|
+
export declare const META_SERVER_INFO = "io.modelcontextprotocol/serverInfo";
|
|
24
|
+
/** JSON-RPC's own codes, and the ones the MCP spec allocates. */
|
|
25
|
+
export declare const ErrorCode: {
|
|
26
|
+
readonly ParseError: -32700;
|
|
27
|
+
readonly InvalidRequest: -32600;
|
|
28
|
+
readonly MethodNotFound: -32601;
|
|
29
|
+
readonly InvalidParams: -32602;
|
|
30
|
+
readonly InternalError: -32603;
|
|
31
|
+
readonly HeaderMismatch: -32020;
|
|
32
|
+
readonly MissingRequiredClientCapability: -32021;
|
|
33
|
+
readonly UnsupportedProtocolVersion: -32022;
|
|
34
|
+
};
|
|
35
|
+
export type JsonRpcId = string | number;
|
|
36
|
+
export type JsonRpcRequest = {
|
|
37
|
+
jsonrpc: "2.0";
|
|
38
|
+
id?: JsonRpcId;
|
|
39
|
+
method: string;
|
|
40
|
+
params?: Record<string, unknown>;
|
|
41
|
+
};
|
|
42
|
+
export type JsonRpcResponse = {
|
|
43
|
+
jsonrpc: "2.0";
|
|
44
|
+
id: JsonRpcId | null;
|
|
45
|
+
result?: unknown;
|
|
46
|
+
error?: {
|
|
47
|
+
code: number;
|
|
48
|
+
message: string;
|
|
49
|
+
data?: unknown;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
export declare class JsonRpcError extends Error {
|
|
53
|
+
readonly code: number;
|
|
54
|
+
readonly data?: unknown;
|
|
55
|
+
/** The HTTP status the response goes out with. */
|
|
56
|
+
readonly status: number;
|
|
57
|
+
constructor(code: number, message: string, data?: unknown,
|
|
58
|
+
/** The HTTP status the response goes out with. */
|
|
59
|
+
status?: number);
|
|
60
|
+
}
|
|
61
|
+
export declare function errorResponse(id: JsonRpcId | null, error: JsonRpcError): JsonRpcResponse;
|
|
62
|
+
/** A JSON-RPC message, told apart by its members. */
|
|
63
|
+
export type Incoming = {
|
|
64
|
+
kind: "request";
|
|
65
|
+
message: JsonRpcRequest & {
|
|
66
|
+
id: JsonRpcId;
|
|
67
|
+
};
|
|
68
|
+
} | {
|
|
69
|
+
kind: "notification";
|
|
70
|
+
message: JsonRpcRequest;
|
|
71
|
+
} | {
|
|
72
|
+
kind: "response";
|
|
73
|
+
message: JsonRpcResponse & {
|
|
74
|
+
id: JsonRpcId;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
export declare function classify(body: unknown): Incoming;
|
|
78
|
+
/**
|
|
79
|
+
* A tool as `tools/list` describes it.
|
|
80
|
+
*
|
|
81
|
+
* `outputSchema` goes out as written for a modern client, which takes any
|
|
82
|
+
* JSON Schema. A legacy one requires an object at its root, as it requires
|
|
83
|
+
* `structuredContent` to be an object, so a tool whose output is not one is
|
|
84
|
+
* listed without it there and answers text only.
|
|
85
|
+
*/
|
|
86
|
+
export declare function toolJson(tool: McpToolDescriptor, modern: boolean): Record<string, unknown>;
|
|
87
|
+
/** Whether a legacy client may be handed `value` as `structuredContent`. */
|
|
88
|
+
export declare function isObject(value: unknown): value is Record<string, unknown>;
|
|
89
|
+
/**
|
|
90
|
+
* The value of an `Mcp-Name` (or `Mcp-Param-*`) header, decoded from the
|
|
91
|
+
* `=?base64?…?=` sentinel when it is in one. `null` for a value the header
|
|
92
|
+
* could not legally carry.
|
|
93
|
+
*/
|
|
94
|
+
export declare function decodeHeaderValue(value: string): string | null;
|
|
95
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../../services/mcp/http/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,eAAe,yBAA0B,CAAC;AACvD,eAAO,MAAM,eAAe,qDAAsD,CAAC;AACnF,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAA6C,CAAC;AAE9F,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,eAAO,MAAM,qBAAqB,4CAA4C,CAAC;AAC/E,eAAO,MAAM,wBAAwB,+CAA+C,CAAC;AACrF,eAAO,MAAM,gBAAgB,uCAAuC,CAAC;AACrE,eAAO,MAAM,gBAAgB,uCAAuC,CAAC;AAErE,iEAAiE;AACjE,eAAO,MAAM,SAAS;;;;;;;;;CASZ,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAExC,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,CAAC,EAAE,SAAS,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,SAAS,GAAG,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC3D,CAAC;AAEF,qBAAa,YAAa,SAAQ,KAAK;IAEnC,QAAQ,CAAC,IAAI,EAAE,MAAM;IAErB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO;IACvB,kDAAkD;IAClD,QAAQ,CAAC,MAAM;gBAJN,IAAI,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACN,IAAI,CAAC,EAAE,OAAO;IACvB,kDAAkD;IACzC,MAAM,SAAM;CAKxB;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI,EAAE,KAAK,EAAE,YAAY,GAAG,eAAe,CAUxF;AAED,qDAAqD;AACrD,MAAM,MAAM,QAAQ,GAChB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,cAAc,GAAG;QAAE,EAAE,EAAE,SAAS,CAAA;KAAE,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,eAAe,GAAG;QAAE,EAAE,EAAE,SAAS,CAAA;KAAE,CAAA;CAAE,CAAC;AAEvE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CA0BhD;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAW1F;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS9D"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State the transport hands a client and takes back: a legacy session id, an
|
|
3
|
+
* elicitation's `requestState`. Both pass through the client, so both are
|
|
4
|
+
* attacker-controlled on the way back in, and both are signed.
|
|
5
|
+
*
|
|
6
|
+
* `<tag>.<payload>.<mac>`: the payload is base64url JSON, the MAC is
|
|
7
|
+
* HMAC-SHA256 over the tag and the payload under a key HKDF-derived from the
|
|
8
|
+
* app's `SECRET` for this purpose alone (`purposeKey`), so a value signed for
|
|
9
|
+
* one use can never verify as another — a session id is not a request state.
|
|
10
|
+
* It is signed, not encrypted: nothing in it is a secret, and the client may
|
|
11
|
+
* read it.
|
|
12
|
+
*
|
|
13
|
+
* Expiry is in the payload and checked here. Anything else a value is bound
|
|
14
|
+
* to — the principal, the tool, the arguments — is the caller's to compare.
|
|
15
|
+
*/
|
|
16
|
+
export declare function sign(purpose: string, tag: string, payload: Record<string, unknown>): string;
|
|
17
|
+
/**
|
|
18
|
+
* The payload of a value `sign` made for `purpose` and `tag`, or `null` when
|
|
19
|
+
* it is malformed, forged, signed for something else, or expired (`exp`, in
|
|
20
|
+
* epoch milliseconds, is required).
|
|
21
|
+
*/
|
|
22
|
+
export declare function verify<T extends {
|
|
23
|
+
exp: number;
|
|
24
|
+
}>(purpose: string, tag: string, value: unknown, now?: number): T | null;
|
|
25
|
+
//# sourceMappingURL=signedState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signedState.d.ts","sourceRoot":"","sources":["../../../../services/mcp/http/signedState.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAG3F;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,EAC9C,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,GAAG,SAAa,GACf,CAAC,GAAG,IAAI,CAiBV"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
2
|
+
import{Ec as E,Hc as T}from"../../chunk-7vb4eey2.js";import"../../chunk-tn2bryy2.js";import"../../chunk-cbqazg9k.js";import"../../chunk-1myhm0g3.js";import"../../chunk-kejwjerj.js";import"../../chunk-t4yh4nf9.js";import"../../chunk-1vzks22y.js";import{fi as I,gi as J,ji as O}from"../../chunk-zyt2w03d.js";import{ni as N}from"../../chunk-1hr4xht1.js";import"../../chunk-vw8849ys.js";import L from"path";class F extends Error{name="QueueWorkerRefused"}class H{kernel;stopping;keepAlive;settings;constructor(y,z={}){this.kernel=y;this.settings={...J(),...z}}async start(){if(await this.kernel.waitForBoot(),this.stopping)return;let y=this.kernel.app;if(!y.bound(E))throw new F("[gemi] `gemi queue:work` has no queue to claim from: this application does not register QueueServiceProvider.");let z=y.make(E);if(!z.durable)throw new F('[gemi] `gemi queue:work` refuses to start: the queue uses the memory driver, which keeps each job in the process that dispatched it, so a worker never sees one. Set `driver: "database"` (or another driver every process can reach) in app/config/queue.ts, or run jobs in the server and drop the worker.');z.start(),this.keepAlive=setInterval(()=>{},1073741824),console.log(`[gemi] Queue worker started: claiming up to ${z.config.concurrency} job(s) at a time.`)}stop(y={}){return this.stopping??=this.drain({...this.settings,...y}),this.stopping}async drain(y){I();let z=this.kernel.app,A=z.resolved(E)?z.make(E):void 0;if(A)console.log(`[gemi] Shutting down: waiting for ${A.running} running job(s) (up to ${y.timeoutMs/1000}s).`),await A.drain(y.timeoutMs);let B=await this.kernel.shutdown({timeoutMs:y.providerTimeoutMs});clearInterval(this.keepAlive);let C=(A?.running??0)===0&&B.failed.length===0&&B.timedOut.length===0;return console.log(`[gemi] Shutdown ${C?"complete":"finished with errors"}.`),C?0:1}}async function U(){let y=N();process.env.ROOT_DIR=y,process.env.APP_DIR=L.join(y,"app"),T();let z=L.join(y,"app/kernel/Kernel.ts"),{default:A}=await import(z);if(typeof A!=="function")return console.error(`[gemi] ${z} has no default export to boot the worker from.`),1;let B=new A;B.boot();let C=new H(B);O(()=>C.stop());try{await C.start()}catch(G){if(!(G instanceof F))throw G;return console.error(G.message),1}return}U().then((y)=>{if(y!==void 0)process.exit(y)},(y)=>{console.error("[gemi] The queue worker failed to start:",y),process.exit(1)});
|
|
3
3
|
|
|
4
|
-
//# debugId=
|
|
4
|
+
//# debugId=94D4E3D8DDBEA88A64756E2164756E21
|
|
@@ -6,6 +6,6 @@
|
|
|
6
6
|
"import type { Application, ShutdownReport } from \"../../foundation/Application\";\nimport { markShuttingDown, shutdownSettings, type ShutdownSettings } from \"../../server/shutdown\";\nimport { QueueManager } from \"./QueueManager\";\n\n/** The part of a `Kernel` a worker drives. */\nexport type WorkerKernel = {\n readonly app: Application;\n waitForBoot(): Promise<void>;\n shutdown(options?: { timeoutMs?: number }): Promise<ShutdownReport>;\n};\n\n/**\n * A worker that was told to start in an application it cannot claim for. The\n * message is written for the operator reading the deploy's logs.\n */\nexport class QueueWorkerRefused extends Error {\n name = \"QueueWorkerRefused\";\n}\n\n/**\n * The process `gemi queue:work` runs: the application booted as a server boots\n * it, claiming from the queue, and no `Bun.serve`. It exists so job capacity\n * can be scaled apart from request traffic, which needs a driver both kinds of\n * process can reach; see `start` for why the memory driver is refused.\n *\n * The caller marks the process as a worker (`markQueueWorker`) before the\n * kernel registers, so every claim rule that asks `claimsInThisProcess` sees a\n * process that claims, whatever `GEMI_QUEUE_CLAIM` says.\n */\nexport class QueueWorker {\n private stopping: Promise<number> | undefined;\n private keepAlive: ReturnType<typeof setInterval> | undefined;\n private readonly settings: ShutdownSettings;\n\n /**\n * `settings` default to the `GEMI_SHUTDOWN_*` variables, read here rather\n * than at the signal so a bad value is warned about while the deploy is\n * being watched, as `Server.start` does.\n */\n constructor(\n private readonly kernel: WorkerKernel,\n settings: Partial<ShutdownSettings> = {},\n ) {\n this.settings = { ...shutdownSettings(), ...settings };\n }\n\n /**\n * Boots the application and starts claiming. Rejects with\n * `QueueWorkerRefused` when the application has no queue, or its queue uses\n * the memory driver.\n *\n * Refused rather than warned about, because a memory worker can never do\n * anything: its jobs live in a `Map` in the process that dispatched them,\n * so a worker's is always empty. Left running, it looks like a healthy\n * deploy — a process up, no errors — that runs nothing, and scaling it out\n * adds no capacity. An exit the platform reports as a crash loop is a form\n * of the mistake someone will see.\n */\n async start(): Promise<void> {\n await this.kernel.waitForBoot();\n // A signal during the boot has already drained and cleared the handle\n // below. Going on would start the loop again and arm a handle nothing\n // clears, holding open a worker that has finished shutting down.\n if (this.stopping) return;\n\n const application = this.kernel.app;\n // `bound`, not `make` in a try: an application built without the queue\n // provider is a configuration to name, not an unbound-token stack trace.\n if (!application.bound(QueueManager)) {\n throw new QueueWorkerRefused(\n \"[gemi] `gemi queue:work` has no queue to claim from: this application \" +\n \"does not register QueueServiceProvider.\",\n );\n }\n const queue = application.make(QueueManager);\n if (!queue.durable) {\n throw new QueueWorkerRefused(\n \"[gemi] `gemi queue:work` refuses to start: the queue uses the memory \" +\n \"driver, which keeps each job in the process that dispatched it, so \" +\n 'a worker never sees one. Set `driver: \"database\"` (or another driver ' +\n \"every process can reach) in app/config/queue.ts, or run jobs in the \" +\n \"server and drop the worker.\",\n );\n }\n\n // Idempotent: a production boot with a durable driver has already started\n // it (`startClaimingIfServing`). Development has not, and a worker claims\n // in either.\n queue.start();\n // The queue's poll timer is unref'd, so that a script's queue does not\n // hold it open; here the queue is the process, and without a handle of its\n // own an idle worker would exit 0 as soon as it booted.\n this.keepAlive = setInterval(() => {}, 1 << 30);\n console.log(\n `[gemi] Queue worker started: claiming up to ${queue.config.concurrency} job(s) at a time.`,\n );\n }\n\n /**\n * Stops claiming, waits for the running jobs, runs every provider's\n * `shutdown()`, and resolves with the exit code: 0 when no job was left\n * running and every provider finished in time, 1 otherwise. Idempotent.\n *\n * `gemi start`'s drain, with the jobs where the requests were:\n * `isShuttingDown()` turns true, which stops a durable queue claiming;\n * running jobs get `timeoutMs` (`GEMI_SHUTDOWN_TIMEOUT`), which a server\n * spends on requests; then `Application.shutdown` gets `providerTimeoutMs`,\n * and in it the queue provider waits for whatever is still running and\n * names it. The two budgets add up as they do for a server, so a worker\n * fits the same grace period. `delayMs` is not waited: it is for a load\n * balancer, and nothing routes to a worker.\n */\n stop(settings: Partial<ShutdownSettings> = {}): Promise<number> {\n this.stopping ??= this.drain({ ...this.settings, ...settings });\n return this.stopping;\n }\n\n private async drain(settings: ShutdownSettings): Promise<number> {\n markShuttingDown();\n const application = this.kernel.app;\n // Resolving the manager now would build a driver only to stop it, which\n // is what a signal during the boot, before the provider resolved it, finds.\n const queue = application.resolved(QueueManager) ? application.make(QueueManager) : undefined;\n if (queue) {\n console.log(\n `[gemi] Shutting down: waiting for ${queue.running} running job(s) ` +\n `(up to ${settings.timeoutMs / 1000}s).`,\n );\n await queue.drain(settings.timeoutMs);\n }\n\n const report = await this.kernel.shutdown({ timeoutMs: settings.providerTimeoutMs });\n clearInterval(this.keepAlive);\n const clean =\n (queue?.running ?? 0) === 0 && report.failed.length === 0 && report.timedOut.length === 0;\n console.log(`[gemi] Shutdown ${clean ? \"complete\" : \"finished with errors\"}.`);\n return clean ? 0 : 1;\n }\n}\n"
|
|
7
7
|
],
|
|
8
8
|
"mappings": ";iZAYA,kBCGO,IAAM,QAA2B,GAAM,DAC5C,GAAO,kBACT,DAYO,IAAM,CAAY,CAWJ,OAVX,SACA,UACS,SAOjB,WAAW,CACQ,EACjB,EAAsC,CAAC,EACvC,CAFiB,cAGjB,KAAK,SAAW,IAAK,EAAiB,KAAM,CAAS,OAejD,MAAK,EAAkB,CAK3B,GAJA,MAAM,KAAK,OAAO,YAAY,EAI1B,KAAK,SAAU,OAEnB,IAAM,EAAc,KAAK,OAAO,IAGhC,GAAI,CAAC,EAAY,MAAM,CAAY,EACjC,MAAM,IAAI,EACR,+GAEF,EAEF,IAAM,EAAQ,EAAY,KAAK,CAAY,EAC3C,GAAI,CAAC,EAAM,QACT,MAAM,IAAI,EACR,8SAKF,EAMF,EAAM,MAAM,EAIZ,KAAK,UAAY,YAAY,IAAM,GAAI,UAAO,EAC9C,QAAQ,IACN,+CAA+C,EAAM,OAAO,+BAC9D,EAiBF,IAAI,CAAC,EAAsC,CAAC,EAAoB,CAE9D,OADA,KAAK,WAAa,KAAK,MAAM,IAAK,KAAK,YAAa,CAAS,CAAC,EACvD,KAAK,cAGA,MAAK,CAAC,EAA6C,CAC/D,EAAiB,EACjB,IAAM,EAAc,KAAK,OAAO,IAG1B,EAAQ,EAAY,SAAS,CAAY,EAAI,EAAY,KAAK,CAAY,EAAI,OACpF,GAAI,EACF,QAAQ,IACN,qCAAqC,EAAM,iCAC/B,EAAS,UAAY,SACnC,EACA,MAAM,EAAM,MAAM,EAAS,SAAS,EAGtC,IAAM,EAAS,MAAM,KAAK,OAAO,SAAS,CAAE,UAAW,EAAS,iBAAkB,CAAC,EACnF,cAAc,KAAK,SAAS,EAC5B,IAAM,GACH,GAAO,SAAW,KAAO,GAAK,EAAO,OAAO,SAAW,GAAK,EAAO,SAAS,SAAW,EAE1F,OADA,QAAQ,IAAI,mBAAmB,EAAQ,WAAa,yBAAyB,EACtE,EAAQ,EAAI,EAEvB,CDvHA,eAAe,CAAI,EAAgC,CACjD,IAAM,EAAU,EAAY,EAI5B,QAAQ,IAAI,SAAW,EACvB,QAAQ,IAAI,QAAU,EAAK,KAAK,EAAS,KAAK,EAE9C,EAAgB,EAEhB,IAAM,EAAa,EAAK,KAAK,EAAS,sBAAsB,GACpD,QAAS,GAAY,MAAa,UAG1C,GAAI,OAAO,IAAW,WAEpB,OADA,QAAQ,MAAM,UAAU,kDAA2D,EAC5E,EAET,IAAM,EAAS,IAAI,EACnB,EAAO,KAAK,EAEZ,IAAM,EAAS,IAAI,EAAY,CAAM,EAKrC,EAAuB,IAAM,EAAO,KAAK,CAAC,EAE1C,GAAI,CACF,MAAM,EAAO,MAAM,EACnB,MAAO,EAAO,CACd,GAAI,EAAE,aAAiB,GAAqB,MAAM,EAElD,OADA,QAAQ,MAAM,EAAM,OAAO,EACpB,EAGT,OAGF,EAAK,EAAE,KACL,CAAC,IAAS,CACR,GAAI,IAAS,OAAW,QAAQ,KAAK,CAAI,GAE3C,CAAC,IAAU,CACT,QAAQ,MAAM,2CAA4C,CAAK,EAC/D,QAAQ,KAAK,CAAC,EAElB",
|
|
9
|
-
"debugId": "
|
|
9
|
+
"debugId": "94D4E3D8DDBEA88A64756E2164756E21",
|
|
10
10
|
"names": []
|
|
11
11
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { User } from "../../auth/types";
|
|
2
|
+
import type { McpGrant, ProgressSink } from "../../http/modelOriginated";
|
|
1
3
|
import { HttpRequest } from "../../http";
|
|
2
4
|
import { type CarriedContext } from "../../http/requestContext";
|
|
3
5
|
import { type ApiRouteConfig } from "./config";
|
|
@@ -18,6 +20,33 @@ export type DispatchCredentials = {
|
|
|
18
20
|
};
|
|
19
21
|
export type DispatchAsOptions = {
|
|
20
22
|
credentials?: DispatchCredentials;
|
|
23
|
+
/**
|
|
24
|
+
* Dispatches as this user instead of copying the initiator's access token
|
|
25
|
+
* (#762): the user is on the request context before the route's middleware
|
|
26
|
+
* runs, as a global middleware's would be, so `auth` passes and policies
|
|
27
|
+
* see them. For a caller whose identity was verified some other way than a
|
|
28
|
+
* gemi session — a remote MCP client's OAuth token or API key — which has
|
|
29
|
+
* no session token to copy, and whose own credential must not be passed on.
|
|
30
|
+
*
|
|
31
|
+
* Only trusted code builds one: it is exactly as powerful as an app
|
|
32
|
+
* middleware calling `setUser`, and gemi's only writer is the MCP registry,
|
|
33
|
+
* from a principal a caller resolver verified. With it, nothing of the
|
|
34
|
+
* initiator's credentials is copied — not its `access_token` cookie or
|
|
35
|
+
* header — so a request that carried both cannot run as the session's user.
|
|
36
|
+
* `grant` is what `req.mcpGrant()` answers on the dispatched request.
|
|
37
|
+
*/
|
|
38
|
+
identity?: DispatchIdentity;
|
|
39
|
+
/** Aborts the dispatched request: its `req.signal`, for a route that honours it. */
|
|
40
|
+
signal?: AbortSignal;
|
|
41
|
+
/**
|
|
42
|
+
* Receives what the route reports with `req.reportProgress` — a remote MCP
|
|
43
|
+
* client's `notifications/progress`.
|
|
44
|
+
*/
|
|
45
|
+
progress?: ProgressSink;
|
|
46
|
+
};
|
|
47
|
+
export type DispatchIdentity = {
|
|
48
|
+
user: User;
|
|
49
|
+
grant?: McpGrant;
|
|
21
50
|
};
|
|
22
51
|
/**
|
|
23
52
|
* A RequestBreakerError's `api` payload as a Response, from a middleware or a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiRouteDispatcher.d.ts","sourceRoot":"","sources":["../../../services/router/ApiRouteDispatcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,WAAW,EAAE,MAAM,YAAY,CAAC;AAIpD,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,2BAA2B,CAAC;AAIhF,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAsChF,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE1E;;;;;;;;GAQG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,CAAC,EAAE,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"ApiRouteDispatcher.d.ts","sourceRoot":"","sources":["../../../services/router/ApiRouteDispatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,12 @@ import { ServiceProvider } from "../../support/ServiceProvider";
|
|
|
6
6
|
*/
|
|
7
7
|
export declare class RouteServiceProvider extends ServiceProvider {
|
|
8
8
|
register(): void;
|
|
9
|
+
/**
|
|
10
|
+
* Bound here and built at boot when `route.mcp.remote.enabled`, so a
|
|
11
|
+
* misconfigured endpoint — no resolver, no url, no SECRET — fails the boot,
|
|
12
|
+
* not the first client that connects.
|
|
13
|
+
*/
|
|
14
|
+
private registerMcpHttp;
|
|
9
15
|
/**
|
|
10
16
|
* The dispatchers of every host group, and the MCP registry when an app declares one, must
|
|
11
17
|
* not be built lazily: constructing the dispatchers flattens the route
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouteServiceProvider.d.ts","sourceRoot":"","sources":["../../../services/router/RouteServiceProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"RouteServiceProvider.d.ts","sourceRoot":"","sources":["../../../services/router/RouteServiceProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAmBhE;;;;GAIG;AACH,qBAAa,oBAAqB,SAAQ,eAAe;IACvD,QAAQ;IAgDR;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAUvB;;;;;;;;OAQG;IACH,IAAI;CAeL"}
|
|
@@ -2,6 +2,8 @@ import type { JSX } from "react";
|
|
|
2
2
|
import type { HttpRequest } from "../../http/HttpRequest";
|
|
3
3
|
import type { ApiRouter } from "../../http/ApiRouter";
|
|
4
4
|
import type { McpRouter } from "../../http/McpRouter";
|
|
5
|
+
import type { McpRemoteFileOptions } from "../mcp/McpRegistry";
|
|
6
|
+
import type { McpRemoteHttpConfig } from "../mcp/http/McpHttpServer";
|
|
5
7
|
import type { ViewRouter } from "../../http/ViewRouter";
|
|
6
8
|
import type { StreamSummary } from "./ServerQueryStore";
|
|
7
9
|
export interface ApiRouteConfig {
|
|
@@ -44,6 +46,20 @@ export interface ViewRouteConfig {
|
|
|
44
46
|
}
|
|
45
47
|
export interface McpRouteConfig {
|
|
46
48
|
router: new () => McpRouter<any>;
|
|
49
|
+
/** Remote MCP callers (#762). */
|
|
50
|
+
remote?: McpRemoteConfig;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The MCP endpoint remote clients connect to (#762). Off unless `enabled`.
|
|
54
|
+
* See `McpRemoteHttpConfig`.
|
|
55
|
+
*/
|
|
56
|
+
export interface McpRemoteConfig extends McpRemoteHttpConfig {
|
|
57
|
+
/**
|
|
58
|
+
* How a remote caller's file arguments are read: the largest file, and
|
|
59
|
+
* whether an `https` URL may be fetched instead of base64 bytes (off by
|
|
60
|
+
* default). See `McpRemoteFileOptions`.
|
|
61
|
+
*/
|
|
62
|
+
files?: McpRemoteFileOptions;
|
|
47
63
|
}
|
|
48
64
|
export interface DomainGroupRouters {
|
|
49
65
|
api?: Partial<ApiRouteConfig> & Pick<ApiRouteConfig, "rootRouter">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../services/router/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,MAAM,WAAW,cAAc;IAI7B,UAAU,EAAE,OAAO,SAAS,CAAC;IAE7B,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE;AAGD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC,OAAO,CAAC;IAClC,UAAU,EAAE,UAAU,UAAU,CAAC;IAEjC;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvE;;;;;;;;;;;;;OAaG;IACH,gBAAgB,CAAC,EAAE,CACjB,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,aAAa,KACnB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAID,MAAM,WAAW,cAAc;IAG7B,MAAM,EAAE,UAAU,SAAS,CAAC,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../services/router/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import"../chunk-
|
|
2
|
+
import"../chunk-vw8849ys.js";import M from"path";import{writeFileSync as Q}from"fs";var L=new Set(["FILE","REDIRECT"]);function H(j){return j.run(()=>{let x=[];for(let{group:z,view:D}of j.domains().viewGroups())for(let[G,B]of Object.entries(D.flatViewRoutes)){let C=D.routeManifest[G]??B.segments.map((K)=>K.viewPath);if(C.length===0||L.has(C.at(-1)))continue;x.push({path:G,group:z,views:C,...B.static?{static:B.static.layout?{layout:B.static.layout}:{}}:{}})}return x})}var J=process.argv[2];async function U(){if(!J)throw Error("usage: route-table <out.json>");let j=M.resolve(process.cwd(),"app/kernel/Kernel.ts"),x=await import(j);if(typeof x.default!=="function")throw Error(`${j} has no default export (the Kernel subclass).`);let z=new x.default;z.boot();try{Q(J,JSON.stringify(H(z)))}finally{z.destroy()}}U().then(()=>process.exit(0),(j)=>{console.error(j?.stack??String(j)),process.exit(1)});
|
|
3
3
|
|
|
4
4
|
//# debugId=2C354352EBF6475164756E2164756E21
|
package/dist/support/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
2
|
+
import{Lc as Y}from"../chunk-n672d4g8.js";import{_g as M}from"../chunk-cbqazg9k.js";import{$h as P,bi as R}from"../chunk-t4yh4nf9.js";import"../chunk-1vzks22y.js";import{ki as Q,li as U,mi as V,ni as W}from"../chunk-1hr4xht1.js";import"../chunk-vw8849ys.js";class S{static token;async boot(){}static inject(){if(!this.token)throw Error(`Service [${this.name}] does not declare a \`static token\`, so the container has no key to resolve it by.`);try{return R(this)}catch(x){throw Error(`Could not inject [${this.name}]. Services are constructed when the kernel boots, so `+"inject() only works from code that runs after that \u2014 a constructor default or a method "+`body, never module top level. Check that [${this.name}] is listed in \`services\` on your Kernel.`,{cause:x})}}static with(x){let f=new this;for(let[C,g]of Object.entries(x))if(g!==void 0)f[C]=g;return f}}import{readdir as z}from"fs/promises";import{join as B,parse as j}from"path";var H=[".ts",".tsx",".js",".mjs",".jsx"];function J(x={}){let f={};for(let[C,g]of Object.entries(x))f[C]=q(g);return new P(f)}async function L(x,f=new P){let C=[];try{C=await z(x)}catch(D){return f}let g=C.filter((D)=>{let{ext:v,name:F}=j(D);return H.includes(v)&&!F.startsWith(".")}).sort();for(let D of g){let{name:v}=j(D),F=await import(B(x,D));f.set(v,q(F))}return f}function q(x){if(x&&typeof x==="object"&&"default"in x)return x.default;return x}export{M as withDefaults,Q as sourceFiles,W as projectRoot,L as loadConfigFrom,V as discoverClasses,J as createConfigRepository,Y as ServiceProvider,S as Service,P as Repository,U as DiscoveryError};
|
|
3
3
|
|
|
4
|
-
//# debugId=
|
|
4
|
+
//# debugId=6197F3E996C8C49964756E2164756E21
|
|
@@ -6,6 +6,6 @@
|
|
|
6
6
|
"import { readdir } from \"node:fs/promises\";\nimport { join, parse } from \"node:path\";\n\nimport { Repository } from \"./Repository\";\n\nconst CONFIG_EXTENSIONS = [\".ts\", \".tsx\", \".js\", \".mjs\", \".jsx\"];\n\n// Builds a Repository from an already-imported map of config modules. The map\n// key becomes the top-level config key, so `{ mail: mailModule }` is readable\n// as `config.get(\"mail.driver\")`. Each entry may be either the module namespace\n// (its `default` export is unwrapped) or the config object itself.\nexport function createConfigRepository(\n modules: Record<string, any> = {},\n): Repository {\n const items: Record<string, any> = {};\n\n for (const [key, mod] of Object.entries(modules)) {\n items[key] = unwrap(mod);\n }\n\n return new Repository(items);\n}\n\n// Reads every config module in an app's `app/config` directory into a\n// Repository. The file's basename is the top-level key: `app/config/mail.ts`\n// populates `mail.*`. A missing directory yields an empty Repository so apps\n// that declare no config still boot.\nexport async function loadConfigFrom(\n directory: string,\n repository = new Repository(),\n): Promise<Repository> {\n let entries: string[] = [];\n\n try {\n entries = await readdir(directory);\n } catch (err) {\n return repository;\n }\n\n const files = entries\n .filter((entry) => {\n const { ext, name } = parse(entry);\n return CONFIG_EXTENSIONS.includes(ext) && !name.startsWith(\".\");\n })\n .sort();\n\n for (const file of files) {\n const { name } = parse(file);\n const mod = await import(join(directory, file));\n repository.set(name, unwrap(mod));\n }\n\n return repository;\n}\n\nfunction unwrap(mod: any) {\n if (mod && typeof mod === \"object\" && \"default\" in mod) {\n return mod.default;\n }\n return mod;\n}\n"
|
|
7
7
|
],
|
|
8
8
|
"mappings": ";2RAgCO,CAAe,JAAQ,EAOrB,OAMD,AAAI,EAAkB,QAmBrB,OAAS,EAKX,CACH,GAAI,CAAC,KAAK,MACR,MAAU,MACR,YAAY,KAAK,0FACnB,EAGF,GAAI,CACF,OAAO,EAAI,IAAuB,EAClC,MAAO,EAAO,CACd,MAAU,MACR,qBAAqB,KAAK,6DACxB,+FACA,6CAA6C,KAAK,kDAEpD,CAAE,OAAM,CACV,SAoBG,KAAuB,CAAoB,EAA0B,CAC1E,IAAM,EAAW,IAAI,KACrB,QAAY,EAAK,KAAU,OAAO,QAAQ,CAAS,EACjD,GAAI,IAAU,OAAW,EAAS,GAAO,EAE3C,OAAO,EAEX,CChHA,kBAAS,oBACT,eAAS,WAAM,aAIf,IAAM,EAAoB,CAAC,MAAO,OAAQ,MAAO,OAAQ,MAAM,EAMxD,SAAS,CAAsB,CACpC,EAA+B,CAAC,EACpB,CACZ,IAAM,EAA6B,CAAC,EAEpC,QAAY,EAAK,KAAQ,OAAO,QAAQ,CAAO,EAC7C,EAAM,GAAO,EAAO,CAAG,EAGzB,OAAO,IAAI,EAAW,CAAK,EAO7B,eAAsB,CAAc,CAClC,EACA,EAAa,IAAI,EACI,CACrB,IAAI,EAAoB,CAAC,EAEzB,GAAI,CACF,EAAU,MAAM,EAAQ,CAAS,EACjC,MAAO,EAAK,CACZ,OAAO,EAGT,IAAM,EAAQ,EACX,OAAO,CAAC,IAAU,CACjB,IAAQ,MAAK,QAAS,EAAM,CAAK,EACjC,OAAO,EAAkB,SAAS,CAAG,GAAK,CAAC,EAAK,WAAW,GAAG,EAC/D,EACA,KAAK,EAER,QAAW,KAAQ,EAAO,CACxB,IAAQ,QAAS,EAAM,CAAI,EACrB,EAAM,MAAa,SAAK,EAAW,CAAI,GAC7C,EAAW,IAAI,EAAM,EAAO,CAAG,CAAC,EAGlC,OAAO,EAGT,SAAS,CAAM,CAAC,EAAU,CACxB,GAAI,GAAO,OAAO,IAAQ,UAAY,YAAa,EACjD,OAAO,EAAI,QAEb,OAAO",
|
|
9
|
-
"debugId": "
|
|
9
|
+
"debugId": "6197F3E996C8C49964756E2164756E21",
|
|
10
10
|
"names": []
|
|
11
11
|
}
|
package/dist/vitest/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{ea as B,fa as D}from"../chunk-
|
|
2
|
+
import{ea as B,fa as D}from"../chunk-gts5p6mw.js";import"../chunk-9n1hx3mq.js";import"../chunk-hdps9n52.js";import{za as J}from"../chunk-p1aqq0ga.js";import"../chunk-4mfrgd5m.js";import"../chunk-vw8849ys.js";function N(){return{name:"gemi-custom-request",enforce:"pre",async transform(G,H){let j=H.split("?",1)[0];if(j.includes("/node_modules/")||!B.test(j))return null;return{code:await D(G),map:null}}}}export{N as gemiRequestPlugin,J as gemiIslandPlugin};
|
|
3
3
|
|
|
4
4
|
//# debugId=69032BE0B0AA208664756E2164756E21
|