gemi 0.117.0 → 0.119.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 +2 -2
- package/dist/ai/index.js.map +1 -1
- package/dist/app/index.js +1 -1
- package/dist/auth/AuthController.d.ts +12 -1
- package/dist/auth/AuthController.d.ts.map +1 -1
- package/dist/auth/connections/OAuthConnectionProvider.d.ts +4 -1
- package/dist/auth/connections/OAuthConnectionProvider.d.ts.map +1 -1
- package/dist/auth/oauth/OAuthProvider.d.ts +25 -0
- package/dist/auth/oauth/OAuthProvider.d.ts.map +1 -1
- package/dist/bun/plugin.js +1 -1
- package/dist/bun/preload.js +1 -1
- package/dist/{chunk-6y4nk9f1.js → chunk-01ehxca0.js} +2 -2
- package/dist/{chunk-6y4nk9f1.js.map → chunk-01ehxca0.js.map} +1 -1
- package/dist/{chunk-gn7kne7r.js → chunk-1m3hvy3q.js} +2 -2
- package/dist/{chunk-gn7kne7r.js.map → chunk-1m3hvy3q.js.map} +1 -1
- package/dist/{chunk-1ckha5dt.js → chunk-1z1rj2zq.js} +2 -2
- package/dist/{chunk-1ckha5dt.js.map → chunk-1z1rj2zq.js.map} +1 -1
- package/dist/{chunk-n9jyjp4a.js → chunk-30xxc6r7.js} +2 -2
- package/dist/{chunk-n9jyjp4a.js.map → chunk-30xxc6r7.js.map} +1 -1
- package/dist/{chunk-077rea02.js → chunk-33s2xqv1.js} +1 -1
- package/dist/{chunk-5m8vvtvn.js → chunk-39kyz4k6.js} +2 -2
- package/dist/{chunk-5m8vvtvn.js.map → chunk-39kyz4k6.js.map} +1 -1
- package/dist/chunk-3nf95j9e.js +5 -0
- package/dist/{chunk-63ewmmhc.js.map → chunk-3nf95j9e.js.map} +1 -1
- package/dist/{chunk-kpn7f58a.js → chunk-3zxfd7pn.js} +3 -3
- package/dist/{chunk-kpn7f58a.js.map → chunk-3zxfd7pn.js.map} +1 -1
- package/dist/{chunk-62jw0vsf.js → chunk-453rmkpm.js} +2 -2
- package/dist/{chunk-62jw0vsf.js.map → chunk-453rmkpm.js.map} +1 -1
- package/dist/{chunk-x84as3vy.js → chunk-490sbcma.js} +2 -2
- package/dist/{chunk-x84as3vy.js.map → chunk-490sbcma.js.map} +1 -1
- package/dist/{chunk-stnd9qht.js → chunk-4c1kdd8p.js} +2 -2
- package/dist/{chunk-stnd9qht.js.map → chunk-4c1kdd8p.js.map} +1 -1
- package/dist/{chunk-j1453bn1.js → chunk-5cgq9c43.js} +2 -2
- package/dist/{chunk-j1453bn1.js.map → chunk-5cgq9c43.js.map} +1 -1
- package/dist/{chunk-hr61ekcr.js → chunk-5dbpgyrx.js} +2 -2
- package/dist/{chunk-hr61ekcr.js.map → chunk-5dbpgyrx.js.map} +1 -1
- package/dist/{chunk-wzzrz612.js → chunk-5ses4tcz.js} +2 -2
- package/dist/{chunk-wzzrz612.js.map → chunk-5ses4tcz.js.map} +1 -1
- package/dist/{chunk-pepzecrm.js → chunk-675kzd7z.js} +2 -2
- package/dist/{chunk-pepzecrm.js.map → chunk-675kzd7z.js.map} +1 -1
- package/dist/{chunk-yhp6bvhj.js → chunk-76p0rf4d.js} +3 -3
- package/dist/{chunk-yhp6bvhj.js.map → chunk-76p0rf4d.js.map} +1 -1
- package/dist/{chunk-bvqae0px.js → chunk-8t6dwwz6.js} +1 -1
- package/dist/{chunk-a32wfzdq.js → chunk-8wcpxm41.js} +2 -2
- package/dist/{chunk-a32wfzdq.js.map → chunk-8wcpxm41.js.map} +1 -1
- package/dist/{chunk-ntxsdchf.js → chunk-9pkj7sk6.js} +2 -2
- package/dist/{chunk-ntxsdchf.js.map → chunk-9pkj7sk6.js.map} +1 -1
- package/dist/{chunk-w4e480he.js → chunk-a1qt8aky.js} +2 -2
- package/dist/{chunk-w4e480he.js.map → chunk-a1qt8aky.js.map} +1 -1
- package/dist/{chunk-e7ezmag9.js → chunk-aedkrck1.js} +1 -1
- package/dist/{chunk-arwmvgrz.js → chunk-aqpaw4jq.js} +2 -2
- package/dist/{chunk-arwmvgrz.js.map → chunk-aqpaw4jq.js.map} +1 -1
- package/dist/{chunk-hvpn18bb.js → chunk-bgwtdbfw.js} +3 -3
- package/dist/{chunk-hvpn18bb.js.map → chunk-bgwtdbfw.js.map} +1 -1
- package/dist/{chunk-gjy2qjcr.js → chunk-bz8xssrc.js} +2 -2
- package/dist/{chunk-gjy2qjcr.js.map → chunk-bz8xssrc.js.map} +1 -1
- package/dist/{chunk-yvtmygrk.js → chunk-cte6ysqd.js} +4 -4
- package/dist/{chunk-yvtmygrk.js.map → chunk-cte6ysqd.js.map} +1 -1
- package/dist/{chunk-3w4hk6q2.js → chunk-cvfg88cx.js} +3 -3
- package/dist/{chunk-3w4hk6q2.js.map → chunk-cvfg88cx.js.map} +1 -1
- package/dist/{chunk-wk1tp1f1.js → chunk-d806cy7p.js} +2 -2
- package/dist/{chunk-wk1tp1f1.js.map → chunk-d806cy7p.js.map} +1 -1
- package/dist/{chunk-zkjs3m5m.js → chunk-dwpn6fze.js} +2 -2
- package/dist/{chunk-zkjs3m5m.js.map → chunk-dwpn6fze.js.map} +1 -1
- package/dist/{chunk-mhteg4yz.js → chunk-dxag6enj.js} +6 -6
- package/dist/{chunk-mhteg4yz.js.map → chunk-dxag6enj.js.map} +4 -4
- package/dist/{chunk-5p4z1fgc.js → chunk-e7jr64q9.js} +2 -2
- package/dist/{chunk-5p4z1fgc.js.map → chunk-e7jr64q9.js.map} +1 -1
- package/dist/{chunk-nb2gggba.js → chunk-ebret82e.js} +3 -3
- package/dist/{chunk-nb2gggba.js.map → chunk-ebret82e.js.map} +1 -1
- package/dist/{chunk-g2wncay4.js → chunk-eke2frrm.js} +3 -3
- package/dist/{chunk-g2wncay4.js.map → chunk-eke2frrm.js.map} +1 -1
- package/dist/{chunk-ffgmqwzy.js → chunk-fsj5k511.js} +2 -2
- package/dist/{chunk-ffgmqwzy.js.map → chunk-fsj5k511.js.map} +1 -1
- package/dist/{chunk-076jezzg.js → chunk-g5ppst76.js} +3 -3
- package/dist/{chunk-076jezzg.js.map → chunk-g5ppst76.js.map} +1 -1
- package/dist/{chunk-37pk2cjg.js → chunk-g9hhdcax.js} +2 -2
- package/dist/{chunk-37pk2cjg.js.map → chunk-g9hhdcax.js.map} +1 -1
- package/dist/{chunk-dz99g58c.js → chunk-gqfqnv3f.js} +2 -2
- package/dist/{chunk-dz99g58c.js.map → chunk-gqfqnv3f.js.map} +1 -1
- package/dist/{chunk-51w202vr.js → chunk-hkf2k2eq.js} +3 -3
- package/dist/{chunk-51w202vr.js.map → chunk-hkf2k2eq.js.map} +1 -1
- package/dist/{chunk-dcgvq79a.js → chunk-hm9cjxy2.js} +2 -2
- package/dist/{chunk-dcgvq79a.js.map → chunk-hm9cjxy2.js.map} +1 -1
- package/dist/{chunk-5w6kyxsj.js → chunk-hr1r3g0d.js} +2 -2
- package/dist/{chunk-5w6kyxsj.js.map → chunk-hr1r3g0d.js.map} +1 -1
- package/dist/{chunk-fnwbbmnk.js → chunk-hzepfrzy.js} +2 -2
- package/dist/{chunk-fnwbbmnk.js.map → chunk-hzepfrzy.js.map} +1 -1
- package/dist/{chunk-pgy3mfxw.js → chunk-j5858bz7.js} +2 -2
- package/dist/{chunk-pgy3mfxw.js.map → chunk-j5858bz7.js.map} +1 -1
- package/dist/{chunk-c2n6zdyd.js → chunk-jf6qqzat.js} +2 -2
- package/dist/{chunk-c2n6zdyd.js.map → chunk-jf6qqzat.js.map} +1 -1
- package/dist/{chunk-8gtc3s1y.js → chunk-jg79n382.js} +2 -2
- package/dist/{chunk-8gtc3s1y.js.map → chunk-jg79n382.js.map} +1 -1
- package/dist/{chunk-t65074mw.js → chunk-kkte8nze.js} +3 -3
- package/dist/{chunk-t65074mw.js.map → chunk-kkte8nze.js.map} +1 -1
- package/dist/{chunk-x7qwx07b.js → chunk-m4kmetpb.js} +2 -2
- package/dist/{chunk-x7qwx07b.js.map → chunk-m4kmetpb.js.map} +1 -1
- package/dist/{chunk-ge9xjwgq.js → chunk-n4sdm0jn.js} +3 -3
- package/dist/{chunk-ge9xjwgq.js.map → chunk-n4sdm0jn.js.map} +1 -1
- package/dist/chunk-nang3847.js +416 -0
- package/dist/chunk-nang3847.js.map +24 -0
- package/dist/{chunk-vj5necm0.js → chunk-nrezmscd.js} +1 -1
- package/dist/{chunk-v8vnxkvp.js → chunk-p83erprx.js} +2 -2
- package/dist/{chunk-v8vnxkvp.js.map → chunk-p83erprx.js.map} +1 -1
- package/dist/{chunk-sj4f7x4p.js → chunk-pkr5dsbk.js} +2 -2
- package/dist/{chunk-sj4f7x4p.js.map → chunk-pkr5dsbk.js.map} +1 -1
- package/dist/{chunk-f8vcwzgd.js → chunk-pqc16rrx.js} +2 -2
- package/dist/{chunk-f8vcwzgd.js.map → chunk-pqc16rrx.js.map} +1 -1
- package/dist/{chunk-hvgmqt6z.js → chunk-pvz90a49.js} +2 -2
- package/dist/{chunk-hvgmqt6z.js.map → chunk-pvz90a49.js.map} +1 -1
- package/dist/{chunk-s4f56035.js → chunk-q290tgza.js} +2 -2
- package/dist/{chunk-s4f56035.js.map → chunk-q290tgza.js.map} +1 -1
- package/dist/{chunk-vtc23xpk.js → chunk-q86tfx95.js} +2 -2
- package/dist/{chunk-vtc23xpk.js.map → chunk-q86tfx95.js.map} +1 -1
- package/dist/{chunk-wgb79ysr.js → chunk-qf4bmee9.js} +2 -2
- package/dist/{chunk-wgb79ysr.js.map → chunk-qf4bmee9.js.map} +1 -1
- package/dist/{chunk-a7r39713.js → chunk-qkxnvpaj.js} +2 -2
- package/dist/{chunk-a7r39713.js.map → chunk-qkxnvpaj.js.map} +1 -1
- package/dist/{chunk-t87w4h84.js → chunk-qntv7bms.js} +2 -2
- package/dist/{chunk-t87w4h84.js.map → chunk-qntv7bms.js.map} +1 -1
- package/dist/chunk-r1favzz4.js +19 -0
- package/dist/{chunk-rhmpphhc.js.map → chunk-r1favzz4.js.map} +5 -4
- package/dist/{chunk-veq07rp8.js → chunk-razjfecn.js} +1 -1
- package/dist/{chunk-a77586gv.js → chunk-scc0j5k9.js} +2 -2
- package/dist/{chunk-a77586gv.js.map → chunk-scc0j5k9.js.map} +1 -1
- package/dist/{chunk-cytss9mb.js → chunk-sce5jes2.js} +2 -2
- package/dist/{chunk-cytss9mb.js.map → chunk-sce5jes2.js.map} +1 -1
- package/dist/{chunk-1zzd39qg.js → chunk-sn04cyw0.js} +2 -2
- package/dist/{chunk-1zzd39qg.js.map → chunk-sn04cyw0.js.map} +1 -1
- package/dist/{chunk-wwdbgshx.js → chunk-tfdmvxza.js} +2 -2
- package/dist/{chunk-wwdbgshx.js.map → chunk-tfdmvxza.js.map} +1 -1
- package/dist/{chunk-jqrs16g2.js → chunk-tzdenj0n.js} +3 -3
- package/dist/{chunk-jqrs16g2.js.map → chunk-tzdenj0n.js.map} +1 -1
- package/dist/chunk-vkkt7j2y.js +10 -0
- package/dist/{chunk-2czfefn2.js.map → chunk-vkkt7j2y.js.map} +3 -3
- package/dist/{chunk-qhw0hej0.js → chunk-x6v2zex2.js} +2 -2
- package/dist/{chunk-qhw0hej0.js.map → chunk-x6v2zex2.js.map} +1 -1
- package/dist/{chunk-yfwrbfnw.js → chunk-xfw8zyvn.js} +2 -2
- package/dist/{chunk-yfwrbfnw.js.map → chunk-xfw8zyvn.js.map} +1 -1
- package/dist/{chunk-sksmnjkn.js → chunk-xtzn0qfh.js} +2 -2
- package/dist/{chunk-sksmnjkn.js.map → chunk-xtzn0qfh.js.map} +1 -1
- package/dist/{chunk-jpetnpzn.js → chunk-xx3zvc3g.js} +2 -2
- package/dist/{chunk-jpetnpzn.js.map → chunk-xx3zvc3g.js.map} +1 -1
- package/dist/chunk-xx7necqt.js +71 -0
- package/dist/{chunk-00n3gwr8.js.map → chunk-xx7necqt.js.map} +3 -3
- package/dist/{chunk-fk6nxhxn.js → chunk-xzn2nmny.js} +2 -2
- package/dist/{chunk-fk6nxhxn.js.map → chunk-xzn2nmny.js.map} +1 -1
- package/dist/{chunk-fa37qzm3.js → chunk-y09r0wsw.js} +3 -3
- package/dist/{chunk-fa37qzm3.js.map → chunk-y09r0wsw.js.map} +1 -1
- package/dist/{chunk-zw6843j3.js → chunk-z759yah5.js} +2 -2
- package/dist/{chunk-zw6843j3.js.map → chunk-z759yah5.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/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/index.js +2 -2
- package/dist/http/index.js.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/index.js +2 -2
- package/dist/kernel/index.js.map +1 -1
- 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/discovery.d.ts +8 -0
- package/dist/services/discovery.d.ts.map +1 -1
- package/dist/services/index.d.ts +8 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +3 -3
- package/dist/services/index.js.map +2 -2
- package/dist/services/queue/DatabaseQueueDriver.d.ts +23 -2
- package/dist/services/queue/DatabaseQueueDriver.d.ts.map +1 -1
- package/dist/services/queue/Job.d.ts +3 -0
- package/dist/services/queue/Job.d.ts.map +1 -1
- package/dist/services/queue/MemoryQueueDriver.d.ts +10 -0
- package/dist/services/queue/MemoryQueueDriver.d.ts.map +1 -1
- package/dist/services/queue/QueueDriver.d.ts +9 -0
- package/dist/services/queue/QueueDriver.d.ts.map +1 -1
- package/dist/services/queue/QueueManager.d.ts +33 -7
- package/dist/services/queue/QueueManager.d.ts.map +1 -1
- package/dist/services/queue/QueueServiceProvider.d.ts.map +1 -1
- package/dist/services/queue/backoff.d.ts +6 -0
- package/dist/services/queue/backoff.d.ts.map +1 -0
- package/dist/services/queue/config.d.ts +9 -0
- package/dist/services/queue/config.d.ts.map +1 -1
- package/dist/services/queue/work.js +2 -2
- package/dist/services/queue/work.js.map +1 -1
- package/dist/services/queue/workflow/DatabaseWorkflowStore.d.ts +89 -0
- package/dist/services/queue/workflow/DatabaseWorkflowStore.d.ts.map +1 -0
- package/dist/services/queue/workflow/MemoryWorkflowStore.d.ts +43 -0
- package/dist/services/queue/workflow/MemoryWorkflowStore.d.ts.map +1 -0
- package/dist/services/queue/workflow/Step.d.ts +202 -0
- package/dist/services/queue/workflow/Step.d.ts.map +1 -0
- package/dist/services/queue/workflow/Workflow.d.ts +124 -0
- package/dist/services/queue/workflow/Workflow.d.ts.map +1 -0
- package/dist/services/queue/workflow/WorkflowRuntime.d.ts +60 -0
- package/dist/services/queue/workflow/WorkflowRuntime.d.ts.map +1 -0
- package/dist/services/queue/workflow/WorkflowStore.d.ts +184 -0
- package/dist/services/queue/workflow/WorkflowStore.d.ts.map +1 -0
- package/dist/services/queue/workflow/duration.d.ts +8 -0
- package/dist/services/queue/workflow/duration.d.ts.map +1 -0
- package/dist/services/queue/workflow/workflowContract.d.ts +30 -0
- package/dist/services/queue/workflow/workflowContract.d.ts.map +1 -0
- 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-00n3gwr8.js +0 -71
- package/dist/chunk-2czfefn2.js +0 -10
- package/dist/chunk-63ewmmhc.js +0 -5
- package/dist/chunk-rhmpphhc.js +0 -19
- package/dist/chunk-y0en07zh.js +0 -302
- package/dist/chunk-y0en07zh.js.map +0 -17
- /package/dist/{chunk-077rea02.js.map → chunk-33s2xqv1.js.map} +0 -0
- /package/dist/{chunk-bvqae0px.js.map → chunk-8t6dwwz6.js.map} +0 -0
- /package/dist/{chunk-e7ezmag9.js.map → chunk-aedkrck1.js.map} +0 -0
- /package/dist/{chunk-vj5necm0.js.map → chunk-nrezmscd.js.map} +0 -0
- /package/dist/{chunk-veq07rp8.js.map → chunk-razjfecn.js.map} +0 -0
package/dist/support/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
2
|
+
import{Yc as Y}from"../chunk-30xxc6r7.js";import{Nh as M}from"../chunk-gqfqnv3f.js";import{Pi as P,Ri as R}from"../chunk-g5ppst76.js";import"../chunk-d806cy7p.js";import{$i as U,_i as Q,aj as V,bj as W}from"../chunk-jg79n382.js";import"../chunk-hm9cjxy2.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=FCAD65B465AB6EA064756E2164756E21
|
|
@@ -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": "FCAD65B465AB6EA064756E2164756E21",
|
|
10
10
|
"names": []
|
|
11
11
|
}
|
package/dist/vitest/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{fa as B,ga as D}from"../chunk-
|
|
2
|
+
import{fa as B,ga as D}from"../chunk-n4sdm0jn.js";import"../chunk-5dbpgyrx.js";import"../chunk-m4kmetpb.js";import{Aa as J}from"../chunk-6ggmk2eg.js";import"../chunk-kk77x2v4.js";import"../chunk-hm9cjxy2.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=C11E8611E15123D864756E2164756E21
|
package/package.json
CHANGED
package/dist/chunk-00n3gwr8.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import{Vg as R}from"./chunk-fa37qzm3.js";import{Bh as L}from"./chunk-jpetnpzn.js";import{gi as T}from"./chunk-5w6kyxsj.js";import{Gi as D}from"./chunk-076jezzg.js";class X{rows=new Map;async find(j,B){for(let G of this.rows.values())if(G.userId===j&&G.provider===B)return{...G};return null}async list(j){return[...this.rows.values()].filter((B)=>B.userId===j).map((B)=>({...B}))}async save(j,B,G){let K=await this.find(j,B),J=new Date,Q={id:K?.id??Bun.randomUUIDv7(),userId:j,provider:B,...P(G),needsReconnect:!1,revision:(K?.revision??0)+1,createdAt:K?.createdAt??J,updatedAt:J};return this.rows.set(Q.id,Q),{...Q}}async updateTokens(j,B,G){let K=this.rows.get(j);if(!K||K.revision!==B)return null;let J={...K,...P(G),needsReconnect:!1,revision:B+1,updatedAt:new Date};return this.rows.set(j,J),{...J}}async markNeedsReconnect(j){let B=this.rows.get(j);if(B)this.rows.set(j,{...B,needsReconnect:!0,updatedAt:new Date})}async delete(j){this.rows.delete(j)}}class F{encrypter;table;sql;dialect;constructor(j,B,G={}){this.encrypter=B;let K=G.table??"gemi_oauth_connections";if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(K))throw Error(`The connections table name "${K}" is not a plain identifier.`);this.table=K,this.sql=j.sql,this.dialect=j.dialect}async createTable(){for(let j of A(this.dialect,this.table))await this.sql.unsafe(j)}async find(j,B){let G=this.sql,K=await G`
|
|
3
|
-
SELECT * FROM ${this.name(G)} WHERE user_id = ${j} AND provider = ${B}
|
|
4
|
-
`;return K[0]?this.decode(K[0]):null}async list(j){let B=this.sql;return(await B`
|
|
5
|
-
SELECT * FROM ${this.name(B)} WHERE user_id = ${j} ORDER BY provider
|
|
6
|
-
`).map((K)=>this.decode(K))}async save(j,B,G){let K=this.sql,J=this.encode(G),Q=Date.now(),V=async()=>x(await K`
|
|
7
|
-
UPDATE ${this.name(K)}
|
|
8
|
-
SET provider_account_id = ${J.providerAccountId}, scopes = ${J.scopes},
|
|
9
|
-
access_token = ${J.accessToken}, refresh_token = ${J.refreshToken},
|
|
10
|
-
token_type = ${J.tokenType}, expires_at = ${J.expiresAt},
|
|
11
|
-
needs_reconnect = 0, revision = revision + 1, updated_at = ${Q}
|
|
12
|
-
WHERE user_id = ${j} AND provider = ${B}
|
|
13
|
-
`);if(await V()===0)try{await K`
|
|
14
|
-
INSERT INTO ${this.name(K)} (id, user_id, provider, provider_account_id, scopes,
|
|
15
|
-
access_token, refresh_token, token_type, expires_at, needs_reconnect, revision,
|
|
16
|
-
created_at, updated_at)
|
|
17
|
-
VALUES (${Bun.randomUUIDv7()}, ${j}, ${B}, ${J.providerAccountId},
|
|
18
|
-
${J.scopes}, ${J.accessToken}, ${J.refreshToken}, ${J.tokenType},
|
|
19
|
-
${J.expiresAt}, 0, 1, ${Q}, ${Q})
|
|
20
|
-
`}catch(W){if(await V()===0)throw W}let Z=await this.find(j,B);if(!Z)throw Error("The OAuth connection vanished while it was being saved.");return Z}async updateTokens(j,B,G){let K=this.sql,J=this.encode(G),Q=await K`
|
|
21
|
-
UPDATE ${this.name(K)}
|
|
22
|
-
SET provider_account_id = COALESCE(${J.providerAccountId}, provider_account_id),
|
|
23
|
-
scopes = ${J.scopes}, access_token = ${J.accessToken},
|
|
24
|
-
refresh_token = ${J.refreshToken}, token_type = ${J.tokenType},
|
|
25
|
-
expires_at = ${J.expiresAt}, needs_reconnect = 0, revision = revision + 1,
|
|
26
|
-
updated_at = ${Date.now()}
|
|
27
|
-
WHERE id = ${j} AND revision = ${B}
|
|
28
|
-
`;if(x(Q)===0)return null;let V=await K`SELECT * FROM ${this.name(K)} WHERE id = ${j}`;return V[0]?this.decode(V[0]):null}async markNeedsReconnect(j){let B=this.sql;await B`UPDATE ${this.name(B)} SET needs_reconnect = 1, updated_at = ${Date.now()} WHERE id = ${j}`}async delete(j){let B=this.sql;await B`DELETE FROM ${this.name(B)} WHERE id = ${j}`}async rotateEncryption(j={}){let B=this.sql,G=this.encrypter(),K=await B`
|
|
29
|
-
SELECT id, access_token, refresh_token, revision FROM ${this.name(B)} ORDER BY id
|
|
30
|
-
`,J=0;for(let Q of K){let V=(W)=>typeof W==="string"&&G.needsReencryption(W);if(!V(Q.access_token)&&!V(Q.refresh_token))continue;if(J+=1,j.dryRun)continue;let Z=(W)=>W===null?null:G.encrypt(G.decrypt(W));await B`
|
|
31
|
-
UPDATE ${this.name(B)}
|
|
32
|
-
SET access_token = ${Z(Q.access_token)}, refresh_token = ${Z(Q.refresh_token)},
|
|
33
|
-
revision = revision + 1
|
|
34
|
-
WHERE id = ${Q.id} AND revision = ${Number(Q.revision)}
|
|
35
|
-
`}return{scanned:K.length,rotated:J}}encode(j){let B=this.encrypter();return{providerAccountId:j.providerAccountId,scopes:j.scopes.join(" "),accessToken:B.encrypt(j.accessToken),refreshToken:j.refreshToken===null?null:B.encrypt(j.refreshToken),tokenType:j.tokenType,expiresAt:j.expiresAt===null?null:j.expiresAt.getTime()}}decode(j){let B=this.encrypter();return{id:String(j.id),userId:String(j.user_id),provider:String(j.provider),providerAccountId:j.provider_account_id===null?null:String(j.provider_account_id),scopes:String(j.scopes??"").split(" ").filter(Boolean),accessToken:B.decrypt(String(j.access_token)),refreshToken:j.refresh_token===null?null:B.decrypt(String(j.refresh_token)),tokenType:j.token_type===null?null:String(j.token_type),expiresAt:j.expires_at===null?null:new Date(Number(j.expires_at)),needsReconnect:Number(j.needs_reconnect)===1,revision:Number(j.revision),createdAt:new Date(Number(j.created_at)),updatedAt:new Date(Number(j.updated_at))}}get mysql(){return this.dialect==="mysql"||this.dialect==="mariadb"}name(j){return j.unsafe(this.mysql?`\`${this.table}\``:`"${this.table}"`)}}function P(j){return{providerAccountId:j.providerAccountId,scopes:[...j.scopes],accessToken:j.accessToken,refreshToken:j.refreshToken,tokenType:j.tokenType,expiresAt:j.expiresAt}}function x(j){let B=j;return Math.max(Number(B.count??0),Number(B.affectedRows??0))}function A(j,B){if(j==="mysql"||j==="mariadb")return[`CREATE TABLE IF NOT EXISTS \`${B}\` (
|
|
36
|
-
\`id\` VARCHAR(191) NOT NULL,
|
|
37
|
-
\`user_id\` VARCHAR(191) NOT NULL,
|
|
38
|
-
\`provider\` VARCHAR(191) NOT NULL,
|
|
39
|
-
\`provider_account_id\` VARCHAR(191) NULL,
|
|
40
|
-
\`scopes\` TEXT NOT NULL,
|
|
41
|
-
\`access_token\` TEXT NOT NULL,
|
|
42
|
-
\`refresh_token\` TEXT NULL,
|
|
43
|
-
\`token_type\` VARCHAR(191) NULL,
|
|
44
|
-
\`expires_at\` BIGINT NULL,
|
|
45
|
-
\`needs_reconnect\` INTEGER NOT NULL DEFAULT 0,
|
|
46
|
-
\`revision\` BIGINT NOT NULL DEFAULT 0,
|
|
47
|
-
\`created_at\` BIGINT NOT NULL,
|
|
48
|
-
\`updated_at\` BIGINT NOT NULL,
|
|
49
|
-
|
|
50
|
-
UNIQUE INDEX \`${B}_user_id_provider_key\`(\`user_id\`, \`provider\`),
|
|
51
|
-
PRIMARY KEY (\`id\`)
|
|
52
|
-
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci`];let G=j==="sqlite"?'"id" TEXT NOT NULL PRIMARY KEY,':'"id" TEXT NOT NULL,',K=j==="sqlite"?"":`,
|
|
53
|
-
|
|
54
|
-
CONSTRAINT "${B}_pkey" PRIMARY KEY ("id")`;return[`CREATE TABLE IF NOT EXISTS "${B}" (
|
|
55
|
-
${G}
|
|
56
|
-
"user_id" TEXT NOT NULL,
|
|
57
|
-
"provider" TEXT NOT NULL,
|
|
58
|
-
"provider_account_id" TEXT,
|
|
59
|
-
"scopes" TEXT NOT NULL,
|
|
60
|
-
"access_token" TEXT NOT NULL,
|
|
61
|
-
"refresh_token" TEXT,
|
|
62
|
-
"token_type" TEXT,
|
|
63
|
-
"expires_at" BIGINT,
|
|
64
|
-
"needs_reconnect" INTEGER NOT NULL DEFAULT 0,
|
|
65
|
-
"revision" BIGINT NOT NULL DEFAULT 0,
|
|
66
|
-
"created_at" BIGINT NOT NULL,
|
|
67
|
-
"updated_at" BIGINT NOT NULL${K}
|
|
68
|
-
)`,`CREATE UNIQUE INDEX IF NOT EXISTS "${B}_user_id_provider_key" ON "${B}"("user_id", "provider")`]}class Y extends Error{code;status;providerError;constructor(j,B,G={}){super(B,G.cause!==void 0?{cause:G.cause}:void 0);this.code=j;this.name="OAuthConnectionError",this.status=G.status,this.providerError=G.providerError}}class _ extends Y{provider;constructor(j,B={}){super("reconnect_required",`The ${j} connection needs to be reconnected: its tokens were refused and could not be refreshed.`,B);this.provider=j;this.name="OAuthReconnectRequiredError"}}class O{config;constructor(j){for(let B of["authorizeUrl","tokenUrl"])H(B,j[B]);if(j.revokeUrl!==void 0)H("revokeUrl",j.revokeUrl);if(j.apiBaseUrl===void 0||j.apiBaseUrl===null||j.apiBaseUrl==="")throw Error(`OAuthConnectionProvider: apiBaseUrl is required. Set it to the provider's API origin (e.g. apiBaseUrl: "https://api.figma.com"); connection.fetch only sends the token there.`);H("apiBaseUrl",j.apiBaseUrl),this.config={scopeSeparator:" ",clientAuth:"body",pkce:!0,authorizationParams:{},refreshLeewaySeconds:60,...j}}authorizationUrl(j){let B=new URL(this.config.authorizeUrl),G={...this.config.authorizationParams,response_type:"code",client_id:this.config.clientId,redirect_uri:j.redirectUri,scope:this.config.scopes.join(this.config.scopeSeparator),state:j.state};if(this.config.pkce)G.code_challenge=j.codeChallenge,G.code_challenge_method="S256";for(let[K,J]of Object.entries(G))B.searchParams.set(K,J);return B.toString()}exchangeCode(j){let B=new URLSearchParams({grant_type:"authorization_code",code:j.code,redirect_uri:j.redirectUri});if(this.config.pkce)B.set("code_verifier",j.codeVerifier);return this.tokenRequest(B,{scopes:this.config.scopes,refreshToken:null,phase:"exchange"})}refresh(j,B){let G=new URLSearchParams({grant_type:"refresh_token",refresh_token:j});return this.tokenRequest(G,{scopes:B,refreshToken:j,phase:"refresh"})}async revoke(j,B){if(!this.config.revokeUrl)throw new Y("revoke_unsupported","This provider has no revokeUrl configured. Use disconnect() to forget the tokens locally.");let G=new URLSearchParams({token:j,token_type_hint:B}),K;try{K=await fetch(this.config.revokeUrl,this.post(G))}catch(J){throw new Y("revoke_failed","The revocation request failed.",{cause:J})}if(!K.ok)throw new Y("revoke_failed",`The provider refused the revocation (HTTP ${K.status}).`,{status:K.status})}post(j){let B={"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"};if(this.config.clientAuth==="basic"){let G=`${encodeURIComponent(this.config.clientId)}:${encodeURIComponent(this.config.clientSecret)}`;B.Authorization=`Basic ${Buffer.from(G).toString("base64")}`}else j.set("client_id",this.config.clientId),j.set("client_secret",this.config.clientSecret);return{method:"POST",headers:B,body:j.toString(),redirect:"error"}}async tokenRequest(j,B){let G=B.phase==="exchange"?"exchange_failed":"refresh_failed",K;try{K=await fetch(this.config.tokenUrl,this.post(j))}catch(W){throw new Y(G,"The token request failed.",{cause:W})}let J=await K.json().catch(()=>({}));if(!K.ok||typeof J.access_token!=="string"||J.access_token===""){let W=typeof J.error==="string"&&/^[a-z0-9_]{1,64}$/.test(J.error)?J.error:void 0;throw new Y(G,`The token endpoint refused the ${B.phase==="exchange"?"code":"refresh token"} (HTTP ${K.status}${W?`, ${W}`:""}).`,{status:K.status,providerError:W})}let Q=Number(J.expires_in),V=typeof J.scope==="string"?J.scope:void 0,Z=J.user_id??J.account_id;return{accessToken:J.access_token,refreshToken:typeof J.refresh_token==="string"&&J.refresh_token!==""?J.refresh_token:B.refreshToken,tokenType:typeof J.token_type==="string"?J.token_type:null,expiresAt:Number.isFinite(Q)&&Q>0?new Date(Date.now()+Q*1000):null,scopes:V!==void 0?V.split(/[\s,]+/).filter(Boolean):B.scopes,providerAccountId:typeof Z==="string"||typeof Z==="number"?String(Z):null}}}function H(j,B){let G;try{G=new URL(String(B))}catch{G=void 0}if(!G||G.protocol!=="https:"&&!(G.protocol==="http:"&&U(G.hostname)))throw Error(`OAuthConnectionProvider: ${j} must be an https URL (http only for localhost), got ${JSON.stringify(B)}.`)}function U(j){return j==="localhost"||j==="127.0.0.1"||j==="[::1]"||j==="::1"}class E{options;static token="auth.connections";resolvedStore;refreshing=new Map;fakes;fakeStore;fakeRequests=[];constructor(j){this.options=j}get providers(){return this.options.providers}get store(){if(this.fakeStore)return this.fakeStore;if(!this.resolvedStore){let j=this.options.store;this.resolvedStore=typeof j==="function"?j():j??new F(D(T).connection(),()=>R())}return this.resolvedStore}provider(j){let B=this.options.providers[j];if(!B){let G=Object.keys(this.options.providers);throw new Y("unknown_provider",`No OAuth connection provider "${j}" in auth.connections`+(G.length>0?` (configured: ${G.join(", ")}).`:" (none are configured)."))}return B}async for(j,B){this.provider(B);let G=await this.store.find(z(j),B);return G?new N(this,G):null}async list(j){return(await this.store.list(z(j))).filter((G)=>(G.provider in this.options.providers)).map((G)=>new N(this,G))}async save(j,B,G){let K=this.provider(B),J=await this.store.save(z(j),B,{refreshToken:null,tokenType:null,expiresAt:null,providerAccountId:null,scopes:K.config.scopes,...G});return new N(this,J)}fake(j={}){return this.fakes=new Map(Object.entries(j)),this.fakeStore=new X,this.fakeRequests.length=0,this}restore(){this.fakes=void 0,this.fakeStore=void 0,this.fakeRequests.length=0}get faked(){return this.fakes!==void 0}async send(j,B){if(!this.fakes)return fetch(B);this.fakeRequests.push(B.clone());let G=this.fakes.get(j);if(!G)throw Error(`Connections.fake() has no handler for "${j}". Pass one: Connections.fake({ ${j}: (req) => ... }).`);return G(B)}refresh(j){let B=this.refreshing.get(j.id);if(B)return B;let G=this.withLock(j.id,()=>this.refreshOnce(j)).finally(()=>this.refreshing.delete(j.id));return this.refreshing.set(j.id,G),G}async refreshOnce(j){let B=await this.store.find(j.userId,j.provider);if(!B||B.id!==j.id)throw new _(j.provider);if(B.revision!==j.revision&&!B.needsReconnect)return B;if(B.needsReconnect)throw new _(j.provider);let G=this.provider(B.provider);if(this.faked||B.refreshToken===null){if(this.faked)return B;throw await this.store.markNeedsReconnect(B.id),new _(B.provider)}let K;try{K=await G.refresh(B.refreshToken,B.scopes)}catch(V){if(V instanceof Y&&V.status!==void 0&&V.status>=400&&V.status<500)throw await this.store.markNeedsReconnect(B.id),new _(B.provider,{cause:V,status:V.status,providerError:V.providerError});throw V}let J=await this.store.updateTokens(B.id,B.revision,K);if(J)return J;let Q=await this.store.find(B.userId,B.provider);if(!Q)throw new _(B.provider);return Q}async withLock(j,B){let G=D();if(this.faked||!G.bound(L))return B();let K=await G.make(L).run(`gemi:oauth-connection:${j}`,{ttl:30000,wait:20000},()=>B());if(!K.acquired)throw new Y("refresh_failed","Timed out waiting for another refresh of this connection to finish.");return K.value}}class N{manager;record;constructor(j,B){this.manager=j;this.record=B}get provider(){return this.record.provider}get userId(){return this.record.userId}get providerAccountId(){return this.record.providerAccountId}get scopes(){return this.record.scopes}get expiresAt(){return this.record.expiresAt}get needsReconnect(){return this.record.needsReconnect}get connectedAt(){return this.record.createdAt}hasScopes(...j){return j.every((B)=>this.record.scopes.includes(B))}async fetch(j,B={}){let G=this.resolveUrl(j),K=await this.current(),J=await this.send(G,B,K.accessToken);if(J.response.status!==401||!J.authorized||B.body instanceof ReadableStream)return J.response;await J.response.body?.cancel().catch(()=>{});let Q=await this.refreshFrom(K);return(await this.send(G,B,Q.accessToken)).response}async accessToken(){return(await this.current()).accessToken}async refresh(){await this.refreshFrom(this.record)}async revoke(){if(!this.manager.faked){let j=this.manager.provider(this.record.provider);if(this.record.refreshToken!==null)await j.revoke(this.record.refreshToken,"refresh_token");else await j.revoke(this.record.accessToken,"access_token")}await this.manager.store.delete(this.record.id)}async disconnect(){await this.manager.store.delete(this.record.id)}toJSON(){return{provider:this.provider,providerAccountId:this.providerAccountId,scopes:[...this.scopes],expiresAt:this.expiresAt,needsReconnect:this.needsReconnect,connectedAt:this.connectedAt}}[Symbol.for("nodejs.util.inspect.custom")](){return{ProviderConnection:this.toJSON()}}async current(){if(this.record.needsReconnect)throw new _(this.record.provider);let j=this.manager.provider(this.record.provider).config.refreshLeewaySeconds*1000,B=this.record.expiresAt?.getTime();if(B!==void 0&&B-Date.now()<=j)return this.refreshFrom(this.record);return this.record}async refreshFrom(j){try{this.record=await this.manager.refresh(j)}catch(B){if(B instanceof _)this.record={...this.record,needsReconnect:!0};throw B}return this.record}resolveUrl(j){let B=this.manager.provider(this.record.provider).config.apiBaseUrl,G;try{G=new URL(String(j),B)}catch{throw new Y("forbidden_url",`connection.fetch was given ${JSON.stringify(String(j))}, which is not a URL.`)}if(G.origin!==new URL(B).origin)throw new Y("forbidden_url",`connection.fetch only sends the ${this.record.provider} token to ${new URL(B).origin} (apiBaseUrl), not to ${G.origin}.`);if(G.protocol!=="https:"&&!(G.protocol==="http:"&&U(G.hostname)))throw new Y("forbidden_url",`connection.fetch only sends a token over https, not to ${G.origin}.`);return G}async send(j,B,G){let K=j,J=(B.method??"GET").toUpperCase(),Q=B.body,V=!0;if(B.redirect==="manual"||B.redirect==="error")return{response:await this.manager.send(this.record.provider,this.request(K,B,J,Q,G)),authorized:V};for(let Z=0;;Z++){let W=this.request(K,{...B,redirect:"manual"},J,Q,V?G:null),$=await this.manager.send(this.record.provider,W),M=$.headers.get("location");if(!C.has($.status)||M===null||Z>=5)return{response:$,authorized:V};await $.body?.cancel().catch(()=>{});let S=new URL(M,K);if(S.origin!==K.origin)V=!1;if($.status===303||($.status===301||$.status===302)&&J==="POST")J="GET",Q=void 0;K=S}}request(j,B,G,K,J){let Q=new Headers(B.headers);if(J===null)Q.delete("authorization");else Q.set("Authorization",`Bearer ${J}`);return new Request(j,{...B,method:G,body:K,headers:Q})}}var C=new Set([301,302,303,307,308]);function z(j){let B=typeof j==="object"&&j!==null?j.id:j;if(B===void 0||B===null||B==="")throw TypeError("An OAuth connection belongs to a user: pass the user (or its id).");return String(B)}
|
|
69
|
-
export{X as Eg,F as Fg,Y as Gg,_ as Hg,O as Ig,E as Jg,N as Kg};
|
|
70
|
-
|
|
71
|
-
//# debugId=BEC29388D06EAD9164756E2164756E21
|
package/dist/chunk-2czfefn2.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import{Ub as eZ,Xb as t,Yb as Z3,fc as YZ}from"./chunk-5m8vvtvn.js";import{qc as LZ,sc as ZZ,uc as B3,vc as F3,xc as L3}from"./chunk-rhmpphhc.js";import{Cc as _3,Ec as K3,Fc as H3,Gc as D,Hc as U3,Ic as Q3,Kc as V3,zc as Y3}from"./chunk-y0en07zh.js";import{Nc as J}from"./chunk-n9jyjp4a.js";import{Ce as m,De as zZ,Ee as AZ,Nd as p,Xd as x3,Yd as qZ,ae as r,cd as q3,gd as v,jd as rZ,ke as MZ,me as GZ,nd as T3,qe as kZ,ye as l}from"./chunk-mhteg4yz.js";import{If as b,Kf as CZ,Zf as jZ,lg as gZ,pg as $Z,qg as a,rg as i}from"./chunk-kpn7f58a.js";import{Dg as aZ}from"./chunk-x84as3vy.js";import{Jg as DZ}from"./chunk-00n3gwr8.js";import{Mg as N3,Ng as OZ,Qg as e,Rg as SZ,Ug as C3}from"./chunk-fa37qzm3.js";import{Bh as k,zh as X3}from"./chunk-jpetnpzn.js";import{Ch as _}from"./chunk-dz99g58c.js";import{Ih as A3}from"./chunk-t65074mw.js";import{wi as TZ}from"./chunk-3w4hk6q2.js";import{Di as J3,Gi as g}from"./chunk-076jezzg.js";var k3="mcp",R3=/^[\x21\x23-\x5B\x5D-\x7E]+$/;class L extends YZ{status;constructor(Z,$){super(Z);this.status=$;this.name="McpToolError"}}class d extends Error{reason;constructor(Z,$){super(Z);this.reason=$;this.name="McpCallRefusedError"}}var w3=/^[A-Za-z0-9_-]{1,64}$/,E3=/:([A-Za-z_][A-Za-z0-9_]*)([?*+]?)/g,RZ=4000,f=1e5,b3=/^(text\/|application\/([\w.+-]*\+)?(json|xml))/i;class y{router;dispatcher;static token="router.mcp";plans=new Map;scopeTools=new Map;files;constructor(Z,$,G={}){this.router=Z;this.dispatcher=$;this.files=y3(G.files);for(let[W,z]of Object.entries(Z.routes??{}))this.plans.set(W,this.plan(W,z));this.resolveScopes()}list(Z,$){if(wZ(Z),Z.kind==="local")return this.descriptors($);let G=[];for(let[W,z]of this.plans){if(!z.remote||!this.grants(Z.principal,W))continue;if(EZ(z.remote,$))G.push(z.remote)}return G}descriptors(Z){let $=[];for(let{descriptor:G}of this.plans.values())if(EZ(G,Z))$.push(G);return $}get maxFileBytes(){return this.files.maxBytes}scopes(){return[...this.scopeTools].map(([Z,{description:$}])=>({name:Z,description:$}))}scopesFor(Z){return[...this.scopeTools].filter(([,{tools:$}])=>$.has(Z)).map(([$])=>$)}async execute(Z,$,G,W,z={}){wZ(Z);let X=this.plans.get($);if(Z.kind==="remote"){if(!X?.remote||!this.grants(Z.principal,$))throw new d(`There is no tool named "${$}".`,"unknown-tool");if(X.descriptor.requiresApproval&&z.approved!==!0)throw new d(`"${$}" needs the user's approval, and this call does not have it.`,"approval-required");W=void 0}if(!X)throw Error(`McpRegistry: there is no tool named "${$}".`);let Y=X,K=Z.kind==="remote"?Y.remote:Y.descriptor,U=K.inputSchema.safeParse(G);if(U.ok===!1)throw new L(`Invalid arguments for "${$}": ${U.errors.join(", ")}`);let H=U.value,Q={caller:Z,req:Z.req,tool:K,input:H,ctx:W},V=await this.fillPath(Y,Q),{path:I}=this.dispatcher.getRouteHandlerAndParams(new Request(`http://gemi.internal/api${V}`));if(I!==K.url)throw new L(`"${$}" has nothing at ${V}.`,404);let C={};for(let q of Y.jsonKeys)if(H[q]!==void 0)C[q]=H[q];let P,x="";if(Y.fileFields.length>0)P=await this.formData(Y,C,Q);else if(K.method==="GET")x=n3(C);else if(Y.jsonKeys.length>0)P=C;let j=this.router.credentials?await this.bind(Y,"the credentials",()=>this.router.credentials(Q)):void 0,E={...j?{credentials:j}:{},...z.signal?{signal:z.signal}:{},...z.progress?{progress:z.progress}:{},...Z.kind==="remote"?{identity:{user:Z.principal.user,grant:{via:Z.principal.via,id:Z.principal.id,scopes:Z.principal.scopes,...Z.principal.clientId?{clientId:Z.principal.clientId}:{}}}}:{}},u;try{let q=x?`${V}?${x}`:V;u=Object.keys(E).length>0?await this.dispatcher.dispatchAs(Z.req,K.method,q,P,E):await this.dispatcher.dispatchAs(Z.req,K.method,q,P)}catch(q){throw console.error(`[gemi/mcp] Dispatching "${$}" failed:`,q),new L(`"${$}" failed on the server.`,500)}if(!Y.result&&!K.outputSchema)return await vZ($,u);return await this.project(Y,Q,u)}plan(Z,$){if(!w3.test(Z))throw Error(`McpRouter: "${Z}" is not a valid tool name. A routes key is the tool's name as a model and an MCP client see it, used verbatim \u2014 letters, digits, "_" and "-", at most 64.`);let G=`McpRouter: "${Z}" (${$?.method} ${$?.url})`;if(!($ instanceof Object)||$.__internal_brand!=="McpRoute")throw Error(`McpRouter: "${Z}" is not a route. Declare it with this.fromApiRoute(...).`);let{method:W,url:z,meta:X}=$;if(z.startsWith("/__gemi__"))throw Error(`${G} is a framework route, not an app route.`);let Y=this.dispatcher.flatRoutes[z]?.[W];if(!Y)throw Error(`${G} names no route of this app. Expose a route by the path and verb it is mounted at.`);let K=[...z.matchAll(E3)].map(([,B,A])=>({name:B,modifier:A})),U=X.params??{};for(let B of K)if(!(B.name in U))throw Error(`${G}: the path param "${B.name}" must be bound or declared "input".`);for(let[B,A]of Object.entries(U)){if(!K.some((M)=>M.name===B))throw Error(`${G}: "${B}" in params is not a param of the url.`);if(fZ(A))u3(G,`params.${B}`,A);else bZ(G,`params.${B}`,A)}let H=[],Q;if(X.input){if(Q=X.input.toJSONSchema(),Q.type!=="object"||!Q.properties)throw Error(`${G}: input must be an s.object(...), the fields of the request body.`);H=Object.keys(Q.properties)}let V=Object.entries(X.files??{}).map(([B,A])=>({name:B,binder:A}));for(let B of V)bZ(G,`files.${B.name}`,B.binder);if(X.result!==void 0&&typeof X.result!=="function")throw Error(`${G}: result must be a function.`);if(X.output!==void 0&&typeof X.output?.safeParse!=="function")throw Error(`${G}: output must be a schema, built with s.`);if(X.title!==void 0&&(typeof X.title!=="string"||X.title===""))throw Error(`${G}: title must be a non-empty string.`);let I=p3(G,W,X.annotations);if(V.length>0&&W==="GET")throw Error(`${G}: a GET has no body to carry a file.`);let C={},P=(B,A)=>{if(B in C)throw Error(`${G}: "${B}" is the input key of two params or files, and the model can only send one.`);C[B]=A},x=new Map,j=new Map;for(let B of K){let A=U[B.name];if(A==="input"){let M=b.string().describe(`The ":${B.name}" segment of the url.`);P(B.name,B.modifier==="?"||B.modifier==="*"?M.optional():M)}else if(fZ(A)){let M=A.as??B.name;P(M,A.input),j.set(B.name,{key:M,param:A})}else x.set(B.name,A)}let E={};for(let B of V)if(B.binder==="input")P(B.name,b.string().describe("The id of an attachment the user uploaded or a tool produced (gemi_att_\u2026), whose file is sent as this field.")),E[B.name]=this.remoteFileSchema();let u=[...Object.keys(C),...V.map((B)=>B.name)];for(let B of new Set(u))if(H.includes(B))throw Error(`${G}: "${B}" is both an input field and a param or file, and the model can only send one.`);let q=Object.freeze({name:Z,description:X.description,method:W,url:z,inputSchema:yZ(X.input,Q,b.object(C)),...X.output?{outputSchema:X.output}:{},...X.title?{title:X.title}:{},annotations:I,tags:Object.freeze([...X.tags??[]]),requiresApproval:X.requiresApproval===!0,...Y.source?{source:Y.source}:{}}),M3=!V.every((B)=>B.binder==="input")?null:V.length===0?q:Object.freeze({...q,inputSchema:yZ(X.input,Q,b.object(i3(C,Object.keys(E))),E)});return{descriptor:q,remote:M3,params:K,paramBinders:x,modelParams:j,fileFields:V,jsonKeys:H,...X.result?{result:X.result}:{}}}remoteFileSchema(){let{maxBytes:Z,fetch:$}=this.files,G={name:{type:"string",description:"The file's name, like report.pdf."},mimeType:{type:"string",description:"The file's media type, like application/pdf."},data:{type:"string",contentEncoding:"base64",description:`The file's bytes, base64-encoded (RFC 4648, standard alphabet). At most ${Z} bytes decoded.`}};if($)G.url={type:"string",format:"uri",description:"An https URL the server downloads the file from, instead of data."};let W={type:"object",description:$?"A file, sent as base64 in data or fetched from url: exactly one of the two.":"A file, sent as base64 in data.",properties:G,required:["name","mimeType"],additionalProperties:!1},z=Object.keys(G),X=(Y)=>{if(typeof Y!=="object"||Y===null||Array.isArray(Y))return{ok:!1,errors:["a file must be an object"]};let K=[],U={};for(let H of Object.keys(Y))if(!z.includes(H))K.push(`a file has no field "${H}"`);for(let H of z){let Q=Y[H];if(Q===void 0||Q===null){if(H==="name"||H==="mimeType")K.push(`a file needs "${H}"`);continue}if(typeof Q!=="string")K.push(`a file's "${H}" must be a string`);else U[H]=Q}return K.length>0?{ok:!1,errors:K}:{ok:!0,value:U}};return{toJSONSchema:()=>W,safeParse:X,parse(Y){let K=X(Y);if(K.ok===!1)throw Error(K.errors.join(", "));return K.value}}}async fillPath(Z,$){let{input:G,req:W}=$,z=Z.descriptor.url;for(let X of Z.params){let Y=Z.paramBinders.get(X.name),K=Z.modelParams.get(X.name),U;if(Y||K){if(U=K?await this.bind(Z,`the param "${X.name}"`,()=>K.param.bind(G[K.key],W,$),{refusals:!0}):await this.bind(Z,`the param "${X.name}"`,()=>Y(W,$)),U===void 0||U===null||U==="")throw console.error(`[gemi/mcp] The ${K?"resolver":"binder"} for "${X.name}" of "${Z.descriptor.name}" returned ${JSON.stringify(U)}.`),new L(`"${Z.descriptor.name}" failed on the server.`,500)}else U=G[X.name];let H=`:${X.name}${X.modifier}`;if(U===void 0||U===null||U===""){if(X.modifier!=="?"&&X.modifier!=="*")throw new L(`"${X.name}" of "${Z.descriptor.name}" must not be empty.`);z=z.replace(`/${H}`,"");continue}z=z.replace(H,l3(Z.descriptor.name,X,String(U)))}return z}async formData(Z,$,G){let{input:W,ctx:z}=G,X=Z.descriptor.name;if(G.caller.kind==="remote"){let K=new FormData;for(let[U,H]of Object.entries($))XZ(K,U,H);for(let U of Z.fileFields)K.append(U.name,await this.remoteFile(X,U.name,W[U.name]));return K}if(!z)throw Error(`McpRegistry: "${X}" sends a file, which is resolved through the tool context's attachments, and none was passed to execute().`);let Y=new FormData;for(let[K,U]of Object.entries($))XZ(Y,K,U);for(let K of Z.fileFields){let U=K.binder==="input"?W[K.name]:await this.bind(Z,`the file "${K.name}"`,()=>K.binder(z,G));if(typeof U!=="string"||U==="")throw new L(`"${X}" needs a file for "${K.name}", and this turn has none. Ask the user to attach one.`);Y.append(K.name,await z.attachments.file(U))}return Y}async remoteFile(Z,$,G){let W=(Q)=>new L(`"${$}" of "${Z}" ${Q}`,400),z=G,{maxBytes:X,fetch:Y}=this.files;if(!v3(z.name))throw W("needs a name of 1 to 255 characters, without control characters or slashes.");if(!g3.test(z.mimeType))throw W(`has a mimeType that is not a media type: "${z.mimeType.slice(0,100)}".`);let K=typeof z.data==="string",U=typeof z.url==="string";if(K===U)throw W(Y?"needs exactly one of data or url.":"needs its bytes, base64, in data.");if(K){let Q=z.data.replace(/\s+/g,"");if(Math.floor(Q.length*3/4)-m3(Q)>X)throw W(`is larger than the ${X} bytes a file may be.`);if(Q.length%4!==0||!h3.test(Q))throw W("has data that is not base64 (RFC 4648, standard alphabet, padded).");return new File([Buffer.from(Q,"base64")],z.name,{type:z.mimeType})}if(!Y)throw W("cannot be fetched from a URL here. Send its bytes, base64, in data.");let H;try{H=new URL(z.url)}catch{throw W("has a url that is not a URL.")}if(H.protocol!=="https:")throw W("can only be fetched from an https URL.");try{let Q=await gZ(H.href,{...Y,maxSize:Math.min(Y.maxSize??X,X),redirect:"follow"});if(!Q.ok)throw W(`could not be fetched: ${H.host} answered ${Q.status}.`);let V=await Q.arrayBuffer();return new File([V],z.name,{type:z.mimeType})}catch(Q){if(Q instanceof L)throw Q;throw W(`could not be fetched from ${H.host}: ${Q instanceof Error?Q.message:"failed"}.`)}}grants(Z,$){for(let G of Z.scopes??[])if(this.scopeTools.get(G)?.tools.has($))return!0;return!1}resolveScopes(){let Z=this.router.scopes;if(Z===void 0){this.scopeTools.set(k3,{description:"Use this app's tools as you",tools:new Set(this.plans.keys())});return}if(typeof Z!=="object"||Z===null)throw Error("McpRouter: scopes must be an object of scope names.");let $=new Set([...this.plans.values()].flatMap(({descriptor:G})=>G.tags));for(let[G,W]of Object.entries(Z)){let z=`McpRouter: scope "${G}"`;if(!R3.test(G))throw Error(`${z} is not a valid OAuth scope: printable ASCII, no spaces or quotes.`);if(typeof W?.description!=="string"||W.description==="")throw Error(`${z} needs a description: it is what a consent screen shows.`);let X=new Set;for(let Y of W.tags??[]){if(!$.has(Y))throw Error(`${z} names the tag "${Y}", which no tool has.`);for(let[K,{descriptor:U}]of this.plans)if(U.tags.includes(Y))X.add(K)}for(let Y of W.names??[]){if(!this.plans.has(Y))throw Error(`${z} names "${Y}", which is no tool.`);X.add(Y)}if(X.size===0)throw Error(`${z} reaches no tool. Give it tags or names.`);this.scopeTools.set(G,{description:W.description,tools:X})}}async project(Z,$,G){let{name:W,outputSchema:z}=Z.descriptor;if(G.status<200||G.status>=300)return await vZ(W,G);let X=(V,I)=>{if(I===void 0)console.error(`[gemi/mcp] "${W}" ${V}`);else console.error(`[gemi/mcp] "${W}" ${V}`,I);return new L(`"${W}" failed on the server.`,500)},Y=G.headers.get("Content-Type"),K=await G.text(),U=null;if(K!=="")try{U=JSON.parse(K)}catch{throw X(`answered ${Y??"a body with no content-type"} that is not JSON, and its result or output needs JSON.`)}let H=U;if(Z.result)try{H=await Z.result(U,$)}catch(V){throw X("failed in its result projection:",V)}if(z){let V=z.safeParse(H);if(V.ok===!1)throw X(`answered what its output schema refuses: ${V.errors.join(", ")}`);H=V.value}if(H===void 0)return null;let Q=JSON.stringify(H);if(Q!==void 0&&Q.length>f)return`${Q.slice(0,f)}\u2026 [cut at ${f} of ${Q.length} characters]`;return H}async bind(Z,$,G,W={}){try{return await G()}catch(z){if(W.refusals&&z instanceof YZ)throw z;throw console.error(`[gemi/mcp] Binding ${$} of "${Z.descriptor.name}" failed:`,z),new L(`"${Z.descriptor.name}" failed on the server.`,500)}}}function wZ(Z){if(Z?.kind==="local"&&Z.req)return;if(Z?.kind==="remote"&&Z.req&&Z.principal?.user&&typeof Z.principal.id==="string"&&Array.isArray(Z.principal.scopes))return;throw Error('McpRegistry: a caller is { kind: "local", req } or { kind: "remote", req, principal }, with the principal a caller resolver verified.')}function EZ(Z,$){if($?.names&&!$.names.includes(Z.name))return!1;if($?.tags&&!Z.tags.some((G)=>$.tags.includes(G)))return!1;return!0}var f3=10485760;function y3(Z){let $=Z?.maxBytes??f3;if(!Number.isSafeInteger($)||$<=0)throw Error("McpRegistry: files.maxBytes must be a positive whole number of bytes.");let G=Z?.fetchUrls===!0?{}:typeof Z?.fetchUrls==="object"&&Z.fetchUrls!==null?Z.fetchUrls:null;return{maxBytes:$,fetch:G}}function v3(Z){if(Z.length===0||Z.length>255)return!1;for(let $ of Z){let G=$.codePointAt(0);if(G<32||G===127||$==="/"||$==="\\")return!1}return!0}var g3=/^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}\/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}(\s*;.{0,200})?$/,h3=/^[A-Za-z0-9+/]*={0,2}$/;function m3(Z){return Z.endsWith("==")?2:Z.endsWith("=")?1:0}function bZ(Z,$,G){if(G!=="input"&&typeof G!=="function")throw Error(`${Z}: ${$} must be a function or "input".`)}function fZ(Z){return Z instanceof Object&&Z.__internal_brand==="McpModelParam"}function u3(Z,$,G){if(G.as!==void 0&&(typeof G.as!=="string"||G.as===""))throw Error(`${Z}: ${$}.as must be a non-empty string.`);let W=G.input;if(typeof W?.safeParse!=="function"||typeof W.toJSONSchema!=="function")throw Error(`${Z}: ${$}.input must be a schema, built with s.`);if(typeof G.bind!=="function")throw Error(`${Z}: ${$}.bind must be a function.`)}var d3=new Set(["readOnlyHint","destructiveHint","idempotentHint","openWorldHint"]);function c3(Z){switch(Z){case"GET":return{readOnlyHint:!0};case"DELETE":return{destructiveHint:!0};case"PUT":return{idempotentHint:!0};default:return{}}}function p3(Z,$,G){if(G!==void 0&&(typeof G!=="object"||G===null))throw Error(`${Z}: annotations must be an object of hints.`);let W=c3($);for(let[z,X]of Object.entries(G??{})){if(!d3.has(z))throw Error(`${Z}: "${z}" is not a tool annotation. Use readOnlyHint, destructiveHint, idempotentHint or openWorldHint.`);if(X===void 0)continue;if(typeof X!=="boolean")throw Error(`${Z}: annotations.${z} must be true or false.`);W[z]=X}if(W.readOnlyHint===!0&&(W.destructiveHint||W.idempotentHint))throw Error(`${Z} is read-only${G?.readOnlyHint?"":` (a ${$})`} and also ${W.destructiveHint?"destructive":"idempotent"}, which only a tool that is not read-only can be. Set readOnlyHint: false if it changes something.`);return Object.freeze(W)}function yZ(Z,$,G,W={}){let z=G.toJSONSchema(),X=Object.fromEntries(Object.entries(W).map(([U,H])=>[U,H.toJSONSchema()])),Y={...$??{},type:"object",properties:{...$?.properties??{},...z.properties,...X},required:[...$?.required??[],...z.required??[],...Object.keys(W)],additionalProperties:!1},K=(U)=>{if(typeof U!=="object"||U===null||Array.isArray(U))return{ok:!1,errors:["expected an object"]};let H=[],Q={};if(Z){let I=Z.safeParse(U);if(I.ok===!1)H.push(...I.errors);else Q={...I.value}}let V=G.safeParse(U);if(V.ok===!1)H.push(...V.errors);else Q={...Q,...V.value};for(let[I,C]of Object.entries(W)){let P=U[I];if(P===void 0){H.push(`"${I}" is required`);continue}let x=C.safeParse(P);if(x.ok===!1)H.push(...x.errors.map((j)=>`${I}: ${j}`));else Q[I]=x.value}return H.length>0?{ok:!1,errors:H}:{ok:!0,value:Q}};return{toJSONSchema:()=>Y,safeParse:K,parse(U){let H=K(U);if(H.ok===!1)throw Error(H.errors.join(", "));return H.value}}}function i3(Z,$){return Object.fromEntries(Object.entries(Z).filter(([G])=>!$.includes(G)))}function l3(Z,$,G){let W=$.modifier==="*"||$.modifier==="+"?G.split("/"):[G];if(W.some((z)=>z==="."||z===".."))throw new L(`"${G}" is not a valid value for "${$.name}" of "${Z}".`);return W.map(encodeURIComponent).join("/")}function XZ(Z,$,G){if(G===void 0||G===null)return;if(Array.isArray(G)){for(let W of G)XZ(Z,$,W);return}Z.append($,typeof G==="object"?JSON.stringify(G):String(G))}function n3(Z){let $=new URLSearchParams,G=(W,z)=>{if(z===void 0||z===null)return;if(Array.isArray(z)){for(let X of z)G(W,X);return}$.append(W,typeof z==="object"?JSON.stringify(z):String(z))};for(let[W,z]of Object.entries(Z))G(W,z);return $.toString()}async function vZ(Z,$){if($.status>=200&&$.status<300){let W=$.headers.get("Content-Type");if(W&&!b3.test(W)){let X=(await $.arrayBuffer()).byteLength;return`"${Z}" answered with ${X} bytes of ${W}, which is not shown.`}let z=await $.text();if(z==="")return null;if(z.length>f)return`${z.slice(0,f)}\u2026 [cut at ${f} of ${z.length} characters]`;try{return JSON.parse(z)}catch{return z}}let G=await $.text();if($.status>=400&&$.status<500){let W=G.length>RZ?`${G.slice(0,RZ)}\u2026`:G;throw new L(`"${Z}" was refused with ${$.status}${W?`: ${W}`:"."}`,$.status)}if($.status<500)console.error(`[gemi/mcp] "${Z}" answered ${$.status}${$.headers.get("Location")?` to ${$.headers.get("Location")}`:""}, which a tool call cannot follow.`);throw new L(`"${Z}" failed on the server.`,$.status)}import{createHash as t3,randomBytes as s3,timingSafeEqual as o3}from"crypto";function KZ(Z){let $=Z.headers.get("authorization");if(!$)return null;let G=/^Bearer[ ]+([\x21-\x7e]+)$/i.exec($.trim());return G?G[1]:null}class a3{options;name="api-key";constructor(Z){this.options=Z;if(typeof Z?.prefix!=="string"||!/^[A-Za-z0-9_-]{3,32}$/.test(Z.prefix))throw Error('McpApiKeyResolver: prefix is required: 3 to 32 letters, digits, _ or -, like "myapp_mcp_".');if(typeof Z.verify!=="function")throw Error("McpApiKeyResolver: verify must be a function that looks a key up.")}static generate(Z){return`${Z}${s3(32).toString("base64url")}`}static hash(Z){return t3("sha256").update(Z).digest("hex")}static hashesMatch(Z,$){let G=Buffer.from(Z),W=Buffer.from($);return G.length===W.length&&o3(G,W)}async resolve(Z){let $=KZ(Z);if(!$?.startsWith(this.options.prefix))return null;let G=await this.options.verify($,Z);if(!G)return{ok:!1,error:"invalid_token",description:"The API key is not valid."};if(!G.user||typeof G.id!=="string"||G.id===""||!Array.isArray(G.scopes))throw Error("McpApiKeyResolver: verify must answer { user, id, scopes } for a key it knows, or null.");return{ok:!0,principal:{user:G.user,via:this.name,id:G.id,scopes:[...G.scopes]}}}}import{createHash as $3,randomBytes as dZ}from"crypto";async function HZ(Z,$){let G=r3();if(!G)return null;let W=await G.consume(Z,$);return W.allowed?null:Math.max(1,Math.ceil(W.retryAfter/1000))}function r3(){try{let Z=g();return Z.bound(v)?Z.make(v):null}catch{return null}}var UZ=["2026-07-28"],n=["2025-11-25","2025-06-18","2025-03-26"],QZ=[...UZ,...n],VZ="io.modelcontextprotocol/protocolVersion",BZ="io.modelcontextprotocol/clientCapabilities";var IZ="io.modelcontextprotocol/serverInfo",N={ParseError:-32700,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602,InternalError:-32603,HeaderMismatch:-32020,MissingRequiredClientCapability:-32021,UnsupportedProtocolVersion:-32022};class F extends Error{code;data;status;constructor(Z,$,G,W=200){super($);this.code=Z;this.data=G;this.status=W;this.name="JsonRpcError"}}function T(Z,$){return{jsonrpc:"2.0",id:Z,error:{code:$.code,message:$.message,...$.data!==void 0?{data:$.data}:{}}}}function hZ(Z){if(Array.isArray(Z))throw new F(N.InvalidRequest,"Batched requests are not supported.",void 0,400);if(typeof Z!=="object"||Z===null||Z.jsonrpc!=="2.0")throw new F(N.InvalidRequest,"Not a JSON-RPC 2.0 message.",void 0,400);let $=Z,G=$.id,W=typeof G==="string"||typeof G==="number"&&Number.isFinite(G);if(typeof $.method==="string"){if($.params!==void 0&&(typeof $.params!=="object"||$.params===null||Array.isArray($.params)))throw new F(N.InvalidRequest,"params must be an object.",void 0,400);if(G===void 0)return{kind:"notification",message:$};if(!W)throw new F(N.InvalidRequest,"id must be a string or a number.",void 0,400);return{kind:"request",message:$}}if(W&&(("result"in $)||("error"in $)))return{kind:"response",message:$};throw new F(N.InvalidRequest,"Not a JSON-RPC request, notification or response.",void 0,400)}function JZ(Z,$){let G=Z.outputSchema?.toJSONSchema(),W={...Z.annotations,...Z.title&&!$?{title:Z.title}:{}};return{name:Z.name,...Z.title?{title:Z.title}:{},description:Z.description,inputSchema:Z.inputSchema.toJSONSchema(),...G&&($||G.type==="object")?{outputSchema:G}:{},...Object.keys(W).length>0?{annotations:W}:{}}}function O(Z){return typeof Z==="object"&&Z!==null&&!Array.isArray(Z)}function mZ(Z){let $=/^=\?base64\?([A-Za-z0-9+/]*={0,2})\?=$/.exec(Z);if(!$)return Z;try{let G=Buffer.from($[1],"base64");return new TextDecoder("utf-8",{fatal:!0}).decode(G)}catch{return null}}import{createHmac as e3,timingSafeEqual as Z9}from"crypto";function FZ(Z,$,G){let W=Buffer.from(JSON.stringify(G)).toString("base64url");return`${$}.${W}.${uZ(Z,$,W).toString("base64url")}`}function NZ(Z,$,G,W=Date.now()){if(typeof G!=="string"||G.length>8192)return null;let z=G.split(".");if(z.length!==3||z[0]!==$)return null;let[,X,Y]=z,K=Buffer.from(Y,"base64url"),U=uZ(Z,$,X);if(K.length!==U.length||!Z9(K,U))return null;let H;try{H=JSON.parse(Buffer.from(X,"base64url").toString("utf8"))}catch{return null}if(typeof H!=="object"||H===null)return null;if(typeof H.exp!=="number"||H.exp<=W)return null;return H}function uZ(Z,$,G){return e3("sha256",t(Z)).update(`${$}.${G}`).digest()}var xZ="gemi.mcp.request-state.v1",cZ="gemi.mcp.session.v1",$9=86400000,pZ=600000,iZ="gemi_approval",PZ=2000,G9={limit:600,window:60},W9={limit:30,window:60};class c{registry;static token="router.mcp.http";endpoint;resolvers;context;allowedOrigins;rateLimit;maxBodyBytes;serverInfo;instructions;nonces;approvalTimeoutMs;pending=new Map;inflight=new Map;constructor(Z,$){this.registry=Z;if(typeof $.url!=="string")throw Error(`route.mcp.remote.url is required: the endpoint's canonical URL, like "https://example.com/mcp".`);this.endpoint=Y9($.url);let G=$.resolvers??[];if(!Array.isArray(G)||G.length===0)throw Error("route.mcp.remote is enabled without a caller resolver. Configure route.mcp.remote.resolvers \u2014 an McpOAuthServer, an McpApiKeyResolver, or your own \u2014 or leave the endpoint off. Without one every request would be refused, or answered as nobody.");for(let W of G)if(typeof W?.resolve!=="function"||typeof W.name!=="string"||W.name==="")throw Error("route.mcp.remote.resolvers: each resolver needs a name and a resolve().");this.resolvers=G,t(xZ),this.context={resource:this.resource,registry:Z},this.allowedOrigins=new Set(($.allowedOrigins??[]).map((W)=>{if(new URL(W).origin!==W)throw Error(`route.mcp.remote.allowedOrigins: "${W}" is not an origin (scheme://host[:port]).`);return W})),this.allowedOrigins.add(this.endpoint.origin),this.rateLimit=$.rateLimit===!1?!1:$.rateLimit??G9,this.maxBodyBytes=$.maxBodyBytes??Math.ceil(Z.maxFileBytes*1.4)+1048576,this.serverInfo={name:$.server?.name??"gemi",version:$.server?.version??"1.0.0"},this.instructions=$.server?.instructions,this.nonces=$.nonces??new eZ,this.approvalTimeoutMs=$.approvalTimeoutMs??pZ;for(let W of G)W.boot?.(this.context)}get resource(){return this.endpoint.href.replace(/\/$/,"")}async handle(Z){let $=new URL(Z.url);if($.host!==this.endpoint.host)return null;for(let z of this.resolvers){let X=await z.handle?.(Z,this.context);if(X)return X}if($.pathname!==this.endpoint.pathname)return null;let G=Z.headers.get("origin");if(G!==null&&!this.allowedOrigins.has(G))return S(T(null,new F(N.InvalidRequest,"Origin not allowed.")),403);let W=G?X9(G):{};if(Z.method==="OPTIONS")return new Response(null,{status:204,headers:{...W,"Access-Control-Allow-Methods":"POST","Access-Control-Allow-Headers":"Authorization, Content-Type, Accept, MCP-Protocol-Version, Mcp-Session-Id, Mcp-Method, Mcp-Name, Last-Event-ID","Access-Control-Max-Age":"600"}});if(Z.method!=="POST")return lZ(new Response(null,{status:405,headers:{Allow:"POST, OPTIONS"}}),W);return lZ(await this.post(Z),W)}async post(Z){let $=null;for(let Y of this.resolvers){let K=await Y.resolve(Z,this.context);if(K===null)continue;if(K.ok===!1)return await this.failedAttempt(Z)??this.unauthorized(K.description);$={...K.principal,via:Y.name};break}if(!$)return(KZ(Z)!==null?await this.failedAttempt(Z):null)??this.unauthorized();let G=await this.spend($);if(G)return G;let W=Z.headers.get("content-type")??"";if(!/^application\/json\s*(;|$)/i.test(W))return new Response("Content-Type must be application/json.",{status:415});let z;try{z=JSON.parse(await z9(Z,this.maxBodyBytes))}catch(Y){if(Y instanceof o)return S(T(null,new F(N.InvalidRequest,`The request is larger than ${this.maxBodyBytes} bytes.`)),413);return S(T(null,new F(N.ParseError,"Parse error.")),400)}let X=new CZ(Z,{},"api",this.endpoint.pathname);return await aZ.run(X,async()=>{try{return await this.dispatch(Z,X,$,z)}catch(Y){if(Y instanceof F){let K=O(z)&&(typeof z.id==="string"||typeof z.id==="number")?z.id:null;return S(T(K,Y),Y.status)}return console.error("[gemi/mcp] The MCP endpoint failed:",Y),S(T(null,new F(N.InternalError,"Internal error.")),500)}},{user:$.user})}async dispatch(Z,$,G,W){let z=hZ(W),X={kind:"remote",req:$,principal:G};if(z.kind==="response"){let P=this.session(Z,G),x=this.pending.get(String(z.message.id));if(x&&x.session===P.id)this.pending.delete(String(z.message.id)),x.resolve(z.message);return new Response(null,{status:202})}let{message:Y}=z,K=Y.params??{},U=O(K._meta)?K._meta:{};if(typeof U[VZ]==="string"){if(this.checkModernHeaders(Z,Y,U[VZ]),z.kind==="notification")return new Response(null,{status:202});return await this.respond(Y,async(P,x)=>this.modern({principal:G,caller:X,message:Y,params:K,era:{modern:!0},stream:P,signal:x}),tZ(K),Z.signal)}if(Y.method==="initialize"){if(z.kind!=="request")throw new F(N.InvalidRequest,"initialize is a request.",void 0,400);return this.initialize(z.message,K,G)}let H=this.session(Z,G),Q=Z.headers.get("mcp-protocol-version");if(Q!==null&&Q!==H.state.v)throw new F(N.InvalidRequest,`MCP-Protocol-Version ${Q} is not the session's ${H.state.v}.`,void 0,400);if(z.kind==="notification"){if(Y.method==="notifications/cancelled"){let P=K.requestId;this.inflight.get(`${H.id}:${String(P)}`)?.abort()}return new Response(null,{status:202})}let V=`${H.id}:${String(Y.id)}`,I=new AbortController;this.inflight.set(V,I);let C=AbortSignal.any([I.signal,Z.signal]);try{return await this.respond(Y,async(P,x)=>this.legacy({principal:G,caller:X,message:Y,params:K,era:{modern:!1,session:H.state,sessionId:H.id},stream:P,signal:x}),tZ(K)||H9(this.registry,Y,H.state),C,()=>this.inflight.delete(V))}catch(P){throw this.inflight.delete(V),P}}async modern(Z){switch(Z.message.method){case"server/discover":return this.complete({supportedVersions:QZ,capabilities:{tools:{}},...this.instructions?{instructions:this.instructions}:{},ttlMs:60000,cacheScope:"private"});case"tools/list":return this.complete({tools:this.registry.list(Z.caller).map(($)=>JZ($,!0)),ttlMs:60000,cacheScope:"private"});case"tools/call":return await this.callTool(Z);default:throw new F(N.MethodNotFound,`Method not found: ${Z.message.method}`,void 0,404)}}async legacy(Z){switch(Z.message.method){case"ping":return{};case"tools/list":return{tools:this.registry.list(Z.caller).map(($)=>JZ($,!1))};case"tools/call":return await this.callTool(Z);default:throw new F(N.MethodNotFound,`Method not found: ${Z.message.method}`)}}complete(Z){return{resultType:"complete",...Z,_meta:{[IZ]:this.serverInfo}}}initialize(Z,$,G){let W=$.protocolVersion,z=n.includes(W)?W:n[0],X=O($.capabilities)?$.capabilities:{},Y={v:z,e:nZ(X.elicitation),p:s(G),exp:Date.now()+$9},K=FZ(cZ,"gms1",Y);return S({jsonrpc:"2.0",id:Z.id,result:{protocolVersion:z,capabilities:{tools:{listChanged:!1}},serverInfo:this.serverInfo,...this.instructions?{instructions:this.instructions}:{}}},200,{"Mcp-Session-Id":K})}session(Z,$){let G=Z.headers.get("mcp-session-id");if(!G)throw new F(N.InvalidRequest,"Missing Mcp-Session-Id. Send initialize first, or a request carrying io.modelcontextprotocol/protocolVersion in _meta.",void 0,400);let W=NZ(cZ,"gms1",G);if(!W||W.p!==s($))throw new F(N.InvalidRequest,"Session not found.",void 0,404);return{id:G,state:W}}checkModernHeaders(Z,$,G){if(!UZ.includes(G))throw new F(N.UnsupportedProtocolVersion,"Unsupported protocol version",{supported:QZ,requested:G},400);let W=(Y)=>new F(N.HeaderMismatch,`Header mismatch: ${Y}`,void 0,400);if(Z.headers.get("mcp-protocol-version")!==G)throw W("MCP-Protocol-Version does not match the protocol version in _meta.");if(Z.headers.get("mcp-method")!==$.method)throw W("Mcp-Method does not match the method.");let z=$.params??{},X=$.method==="tools/call"||$.method==="prompts/get"?z.name:$.method==="resources/read"?z.uri:void 0;if(X!==void 0){let Y=Z.headers.get("mcp-name");if(Y===null||mZ(Y)!==X)throw W("Mcp-Name does not match the request's name.")}}async callTool(Z){let{params:$,caller:G,principal:W}=Z,z=$.name;if(typeof z!=="string")throw new F(N.InvalidParams,"tools/call needs a tool name.");let X=$.arguments??{},Y=this.registry.list(G,{names:[z]})[0];if(!Y)throw new F(N.InvalidParams,`Unknown tool: ${z}`);let K=!1;if(Y.requiresApproval){let I=Y.inputSchema.safeParse(X);if(I.ok===!1)return this.toolResult(Z,{content:[{type:"text",text:`Invalid arguments for "${z}": ${I.errors.join(", ")}`}],isError:!0});let C=await this.approval(Z,Y,X);if(C.kind==="answer")return C.result;K=!0}let U=U9(Z),H;try{H=await this.registry.execute(G,z,X,void 0,{approved:K,signal:Z.signal,...U?{progress:U}:{}})}catch(I){if(I instanceof L)return this.toolResult(Z,{content:[{type:"text",text:I.message}],isError:!0});if(I instanceof d)throw new F(N.InvalidParams,I.reason==="unknown-tool"?`Unknown tool: ${z}`:I.message);return console.error(`[gemi/mcp] "${z}" failed for ${W.via}:${W.id}:`,I),this.toolResult(Z,{content:[{type:"text",text:`"${z}" failed on the server.`}],isError:!0})}let Q=typeof H==="string"?H:JSON.stringify(H??null),V=Y.outputSchema&&(Z.era.modern||O(H))?{structuredContent:H}:{};return this.toolResult(Z,{content:[{type:"text",text:Q}],...V,isError:!1})}toolResult(Z,$){return Z.era.modern?this.complete($):$}async approval(Z,$,G){let W=Q9($,G),z=(H)=>({kind:"answer",result:this.toolResult(Z,{content:[{type:"text",text:H}],isError:!0})});if(Z.era.modern){let H=O(Z.params._meta)?Z.params._meta:{},Q=O(H[BZ])?H[BZ]:{},V=O(Z.params.inputResponses)?Z.params.inputResponses:null,I=Z.params.requestState,C=K9(G);if(V&&I!==void 0){let x=NZ(xZ,"grs1",I);if(!x||x.p!==s(Z.principal)||x.t!==$.name||x.a!==C)throw new F(N.InvalidParams,"requestState is not valid for this call.");if(!await this.spendNonce(x.n,x.exp))throw new F(N.InvalidParams,"requestState has already been used.");return sZ(V[iZ])?{kind:"approved"}:z(`The user did not approve "${$.name}", and it did not run.`)}if(!nZ(Q.elicitation))throw new F(N.MissingRequiredClientCapability,`"${$.name}" needs the user's approval, and this client cannot ask for it (elicitation).`,{requiredCapabilities:{elicitation:{form:{}}}},400);let P={p:s(Z.principal),t:$.name,a:C,n:dZ(16).toString("base64url"),exp:Date.now()+pZ};return{kind:"answer",result:{resultType:"input_required",inputRequests:{[iZ]:{method:"elicitation/create",params:{mode:"form",...W}}},requestState:FZ(xZ,"grs1",P),_meta:{[IZ]:this.serverInfo}}}}let X=Z.era;if(!X.session.e||!Z.stream)return z(`"${$.name}" needs the user's approval, and this client cannot ask for it (elicitation). It did not run.`);let Y=`gemi-approval-${dZ(12).toString("base64url")}`,K=X.sessionId,U=await new Promise((H)=>{let Q=setTimeout(()=>{this.pending.delete(Y),H(null)},this.approvalTimeoutMs),V=(I)=>{clearTimeout(Q),H(I)};this.pending.set(Y,{session:K,resolve:V}),Z.signal.addEventListener("abort",()=>{this.pending.delete(Y),V(null)}),Z.stream.send({jsonrpc:"2.0",id:Y,method:"elicitation/create",params:X.session.v==="2025-11-25"?{mode:"form",...W}:W})});return U&&!U.error&&sZ(U.result)?{kind:"approved"}:z(`The user did not approve "${$.name}", and it did not run.`)}async spendNonce(Z,$){try{return await this.nonces.consume(Z,$)}catch(G){return console.error("[gemi/mcp] Spending an approval failed:",G),!1}}async respond(Z,$,G,W,z){if(!G)try{let U=await $(null,W);return S({jsonrpc:"2.0",id:Z.id,result:U},200)}finally{z?.()}let X=new AbortController,Y=AbortSignal.any([X.signal,W]),K=new G3(()=>X.abort());return(async()=>{try{let U=await $(K,Y);K.send({jsonrpc:"2.0",id:Z.id,result:U})}catch(U){if(U instanceof F)K.send(T(Z.id,U));else console.error("[gemi/mcp] The MCP endpoint failed:",U),K.send(T(Z.id,new F(N.InternalError,"Internal error.")))}finally{z?.(),K.close()}})(),new Response(K.readable,{status:200,headers:{"Content-Type":"text/event-stream","Cache-Control":"no-store","X-Accel-Buffering":"no"}})}unauthorized(Z){let $=this.resolvers.map((W)=>W.challenge?.(this.context)).find(Boolean)??'Bearer realm="mcp"',G=Z?`${$}, error="invalid_token", error_description="${Z.replace(/["\\]/g,"")}"`:$;return S(T(null,new F(N.InvalidRequest,"Unauthorized.")),401,{"WWW-Authenticate":G})}async failedAttempt(Z){let $=rZ(new CZ(Z,{},"api",this.endpoint.pathname)),G=await HZ(`mcp-auth-failed:${$}`,W9);return G===null?null:oZ(G)}async spend(Z){if(!this.rateLimit)return null;let $=await HZ(`mcp-endpoint:${Z.via}:${Z.id}`,this.rateLimit);return $===null?null:oZ($)}}class G3{readable;controller;closed=!1;encoder=new TextEncoder;constructor(Z){this.readable=new ReadableStream({start:($)=>{this.controller=$},cancel:()=>{this.closed=!0,Z()}})}send(Z){if(this.closed)return;this.controller.enqueue(this.encoder.encode(`event: message
|
|
3
|
-
data: ${JSON.stringify(Z)}
|
|
4
|
-
|
|
5
|
-
`))}close(){if(this.closed)return;this.closed=!0,this.controller.close()}}class o extends Error{}async function z9(Z,$){let G=Number(Z.headers.get("content-length"));if(Number.isFinite(G)&&G>$)throw new o;if(!Z.body)return"";let W=Z.body.getReader(),z=[],X=0;for(;;){let{done:Y,value:K}=await W.read();if(Y)break;if(X+=K.byteLength,X>$)throw await W.cancel(),new o;z.push(K)}return Buffer.concat(z).toString("utf8")}function S(Z,$,G={}){return new Response(JSON.stringify(Z),{status:$,headers:{"Content-Type":"application/json","Cache-Control":"no-store",...G}})}function lZ(Z,$){for(let[G,W]of Object.entries($))Z.headers.set(G,W);return Z}function X9(Z){return{"Access-Control-Allow-Origin":Z,"Access-Control-Expose-Headers":"Mcp-Session-Id, WWW-Authenticate",Vary:"Origin"}}function Y9(Z){let $;try{$=new URL(Z)}catch{throw Error(`route.mcp.remote.url: "${Z}" is not a URL.`)}let G=$.hostname==="localhost"||$.hostname==="127.0.0.1"||$.hostname==="[::1]";if($.protocol!=="https:"&&!($.protocol==="http:"&&G))throw Error("route.mcp.remote.url must be https (http only on localhost): tokens travel to it.");if($.search||$.hash||$.username||$.password)throw Error("route.mcp.remote.url must have no query, fragment or credentials.");if($.pathname==="/"||$.pathname.endsWith("/"))throw Error('route.mcp.remote.url needs a path of its own, like "/mcp", without a trailing slash.');return $}function s(Z){return $3("sha256").update(`${Z.via}\x00${Z.id}\x00${Z.user?.id}`).digest("base64url").slice(0,32)}function K9(Z){return $3("sha256").update(Z3(Z??{})).digest("base64url")}function nZ(Z){if(!O(Z))return!1;if(Object.keys(Z).length===0)return!0;return"form"in Z}function tZ(Z){let $=O(Z._meta)?Z._meta:{};return typeof $.progressToken==="string"||typeof $.progressToken==="number"}function H9(Z,$,G){if($.method!=="tools/call"||!G.e)return!1;let W=$.params?.name;return typeof W==="string"&&Z.descriptors({names:[W]})[0]?.requiresApproval===!0}function U9(Z){let G=(O(Z.params._meta)?Z.params._meta:{}).progressToken;if(!Z.stream||typeof G!=="string"&&typeof G!=="number")return;let W=-1/0;return(z)=>{if(typeof z?.progress!=="number"||!Number.isFinite(z.progress)||z.progress<=W)return;W=z.progress,Z.stream.send({jsonrpc:"2.0",method:"notifications/progress",params:{progressToken:G,progress:z.progress,...typeof z.total==="number"?{total:z.total}:{},...typeof z.message==="string"?{message:z.message.slice(0,1000)}:{}}})}}function Q9(Z,$){let G=JSON.stringify($??{},null,1),W=G.length>PZ?`${G.slice(0,PZ)}\u2026 (${G.length-PZ} more characters not shown)`:G;return{message:`Allow "${Z.title??Z.name}" to run? ${Z.description}
|
|
6
|
-
|
|
7
|
-
Arguments: ${W}`,requestedSchema:{type:"object",properties:{approve:{type:"boolean",title:"Approve",description:`Run "${Z.title??Z.name}" with these arguments.`}},required:["approve"]}}}function sZ(Z){return O(Z)&&Z.action==="accept"&&O(Z.content)&&Z.content.approve===!0}function oZ(Z){return S(T(null,new F(N.InvalidRequest,"Rate limit exceeded.")),429,{"Retry-After":String(Z)})}async function V9(Z,$={}){try{if(!await Z.shouldRun.call(Z))return}catch(z){console.error(`Error evaluating shouldRun for cron job ${Z.name}:`,z);return}let G=B9(Z.withoutOverlapping);if(!Z.onOneServer&&G===void 0){await _Z(Z);return}let W;try{if(W=$.locks?.()??I9(),Z.onOneServer){let z=Math.floor(($.now??Date.now())/60000);if(!await W.store.advance(`gemi:cron-tick:${Z.name}`,z))return}}catch(z){console.error(`Could not claim the tick of cron job ${Z.name}; skipped it:`,z);return}if(G===void 0){await _Z(Z);return}try{await W.run(`gemi:cron:${Z.name}`,{ttl:G},(z)=>_Z(Z,z))}catch(z){if(z instanceof X3)console.error(`Cron job ${Z.name} lost its withoutOverlapping lock while running: another tick may have started alongside it.`,z);else console.error(`Could not take the withoutOverlapping lock of cron job ${Z.name}:`,z)}}var W3=300000;function B9(Z){if(!Z)return;if(Z===!0)return W3;return Z.expiresAfter??W3}var z3;function I9(){return z3??=new k(new Y3),z3}async function _Z(Z,$){try{await Z.onTick.call(Z)}catch(G){console.error(`Error executing cron job ${Z.name}:`,G)}try{await Z.callback.call(Z,$)}catch(G){console.error(`Error in cron job ${Z.name}:`,G)}try{await Z.onComplete.call(Z)}catch(G){console.error(`Error completing cron job ${Z.name}:`,G)}}class R{static token="scheduler";handles=[];resolved;inFlight=new Map;stopped=!1;locks;constructor(Z){this.resolved=Z.jobs}get jobs(){return[...this.resolved]}useJobs(Z){this.resolved=Z}useLocks(Z){this.locks=Z}start(Z=($)=>$()){if(this.stopped=!1,this.resolved.length===0)return;let $=globalThis.__gemiCronJobs??=new Map,G=new Map;for(let W of this.resolved){let z=new W;if(!z.name){console.error(`Cron job must have a name \u2014 ${W.name||"an anonymous class"} has none, so it is not scheduled. If this is a base class that other jobs extend, move it out of the discovered directory: \`abstract\` does not survive to runtime, so a class under app/cron is indistinguishable from a job.`);continue}if(!z.cron){console.error(`Cron job must have an expression. Job: ${z.name}`);continue}let X=G.get(z.name);if(X!==void 0){console.error(`Two cron jobs claim the name "${z.name}" \u2014 ${X} is scheduled and ${W.name||"an anonymous class"} is not. A name is the scheduler's key, so only one job can hold it. Rename one.`);continue}G.set(z.name,W.name||"an anonymous class"),$.get(z.name)?.stop();let Y=Bun.cron(z.cron,()=>{if(this.stopped)return;let K=this.locks;return this.track(z.name,()=>Z(()=>V9(z,{locks:K})))});$.set(z.name,Y),this.handles.push(Y)}}stop(){this.stopped=!0;for(let Z of this.handles)Z.stop();this.handles=[]}async drain(Z=1/0){this.stop();let $,G=new Promise((W)=>{if(Z!==1/0)$=setTimeout(W,Z)});return await Promise.race([Promise.allSettled([...this.inFlight.values()].map((W)=>W.done)),G]),clearTimeout($),{unfinished:[...this.inFlight.values()].map((W)=>({...W.tick}))}}get running(){return this.inFlight.size}track(Z,$){let G={},W=Promise.resolve().then($).finally(()=>this.inFlight.delete(G));return this.inFlight.set(G,{tick:{name:Z,startedAt:new Date},done:W}),W}}import{isMainThread as J9}from"worker_threads";var F9=100,N9=(Z)=>Math.min(F9,Math.floor(Z/10));class x9 extends J{register(){this.app.singleton(D,()=>new D(this.app.config.get("queue",{}),{application:this.app})),this.app.singleton(k,()=>this.app.make(D).locks)}async boot(){let Z=this.app.config.get("queue",{});if(Z.jobs!==void 0)return;let{jobsDir:$}=_(K3(),Z);this.app.make(D).useJobs(await B3($))}async shutdown(Z){if(!this.app.resolved(D))return;let $=this.app.make(D);if($.running>0)console.log(`[gemi] Shutting down: waiting for ${$.running} running queued job(s).`);let G=Z?.timeoutMs,{unfinished:W}=await $.drain(G===void 0?1/0:Math.max(0,G-N9(G)));if(W.length>0)return console.error("[gemi] Queued jobs still running at shutdown: "+W.map((z)=>`${z.name} (${z.id})`).join(", ")),{abandoned:!0}}}function q$(Z){if(C9(Z),Bun.env.NODE_ENV!=="production")return _9(Z);if(I3(Z))return;if(!U3())return;if(!Z.bound(D))return;Z.make(D).start()}function I3(Z){let $=Z.config.get("queue",{}).driver??"memory";return $==="memory"||$ instanceof H3}function P9(Z){if(I3(Z))return!0;if(typeof Z.config.get("queue",{}).driver!=="function"||!Z.bound(D))return!1;try{return!Z.make(D).durable}catch{return!1}}function C9(Z){let $=process.env.GEMI_QUEUE_CLAIM;if($===void 0||V3())return;if(process.env.ROOT_DIR===void 0||!J9)return;if(Q3()){if(!P9(Z))return;console.warn('[gemi] GEMI_QUEUE_CLAIM=off is ignored: the memory queue driver keeps jobs in the process that dispatched them, so no worker could run them. This server runs its own jobs. Use a driver other processes can read, such as "database", to hand jobs to `gemi queue:work`.')}else if($.trim().toLowerCase()!=="on")console.warn(`[gemi] GEMI_QUEUE_CLAIM="${$}" is not "off" or "on", so this server claims jobs. Set it to "off" to leave them to \`gemi queue:work\`.`)}function _9(Z){let $=globalThis.__gemiDevQueue;if(!$)return;if(globalThis.__gemiDevQueue=void 0,$.stop(),Z.bound(D))Z.make(D).start()}class D9 extends J{register(){this.app.singleton(p,()=>new p(this.app.config.get("changeFeed",{}),{application:this.app}))}async shutdown(){if(!this.app.resolved(p))return;await this.app.make(p).close()}}class A9 extends J{register(){this.app.singleton(AZ,()=>new AZ(this.app.config.get("auth",{}))),this.app.singleton(DZ,()=>{let Z=this.app.config.get("auth",{});return new DZ({providers:Z.connections??{},store:Z.connectionStore??void 0})})}}var L9=100,O9=(Z)=>Math.min(L9,Math.floor(Z/10));class q9 extends J{register(){this.app.singleton(R,()=>new R(_(LZ(),this.app.config.get("schedule",{}))))}async boot(){let Z=this.app.make(R),$=this.app.config.get("schedule",{});if($.jobs===void 0){let{jobsDir:W}=_(LZ(),$);Z.useJobs(await F3(W))}if(process.env.GEMI_NO_SCHEDULE==="1")return;let G=this.app;if(G.bound(k))Z.useLocks(()=>G.make(k));Z.start((W)=>J3.run(G,W))}async shutdown(Z){if(!this.app.resolved(R))return;let $=this.app.make(R);if($.running>0)console.log(`[gemi] Shutting down: waiting for ${$.running} running cron tick(s).`);let G=Z?.timeoutMs,{unfinished:W}=await $.drain(G===void 0?1/0:Math.max(0,G-O9(G)));if(W.length>0)return console.error("[gemi] Cron jobs still running at shutdown: "+W.map((z)=>`${z.name} (started ${z.startedAt.toISOString()})`).join(", ")),{abandoned:!0}}}class h extends x3{modelName;constructor(Z="FeatureFlag"){super();this.modelName=Z}get available(){return N3(this.modelName)}async load(){if(!this.available)throw new qZ(this.modelName);let Z=OZ(this.modelName);return await Z.asSystem(()=>Z.findMany())}async write(Z,$,G){if(!this.available)throw new qZ(this.modelName);let W=OZ(this.modelName),z=this.hasActorColumn(W),X={active:$};if(z)X.updatedBy=G.actor;return await W.asSystem(()=>W.upsert({where:{key:Z},create:{key:Z,...X},update:X})),{actorRecorded:z}}hasActorColumn(Z){let $=Z?.$schema?.fields?.updatedBy;return $!==void 0&&$.type==="String"}}function l$(Z){return Z}function P3(){return{features:void 0,enabled:!0,source:new h,model:"FeatureFlag",ttl:30,context:void 0,onEvaluate:void 0,maxClientFlags:200}}class T9 extends J{register(){this.app.singleton(r,()=>{let Z=this.app.config.get("features",{}),$=_(P3(),Z);if(Z?.model!==void 0&&Z?.source===void 0)$.source=new h(Z.model);else if(Z?.model!==void 0&&Z.source instanceof h&&Z.source.modelName!==Z.model)a.warning(`app/config/features.ts sets \`model: "${Z.model}"\` and a source reading "${Z.source.modelName}". The source wins; drop \`model\` to silence this.`);return new r($,(G)=>a.warning(G))})}async boot(){let Z=this.app.make(r);if(!Z.config.enabled)return;try{await Z.refresh()}catch($){a.error(`Could not warm the feature flag cache at boot. ${$ instanceof Error?$.message:String($)}`)}}}class S9 extends J{register(){this.app.singleton(TZ,()=>new TZ(this.app.config.get("mail",{})))}}class j9 extends J{register(){this.app.singleton(e,()=>new e(this.app.config.get("encryption",{})))}boot(){if(this.app.make(e).configured)return;let $=this.app.config.get("auth",{}),G=Object.keys($?.connections??{});if(G.length>0&&!$?.connectionStore)throw new SZ(`auth.connections (${G.join(", ")}) keeps OAuth tokens encrypted, but no encryption key is configured. Add app/config/encryption.ts (defineEncryptionConfig({ keys: { k1: process.env.APP_ENCRYPTION_KEY } })) and list it as \`encryption\` in your Kernel's config. Generate a key with \`openssl rand -base64 32\`.`);let W=C3();if(W.length===0)return;throw new SZ(`${W.join(", ")} ${W.length===1?"is an encrypted column":"are encrypted columns"}, but no encryption key is configured. Add app/config/encryption.ts (defineEncryptionConfig({ keys: { k1: process.env.APP_ENCRYPTION_KEY } })) and list it as \`encryption\` in your Kernel's config. Generate a key with \`openssl rand -base64 32\`.`)}}function M9(Z){return`listener:${Z}`}function D3(Z,$){k9(Z);let{maxAttempts:G,backoff:W,worker:z}=$,X=Z.event.name,Y=class extends _3{maxAttempts=G;backoff=W;worker=z;async run(...K){let[U,H]=R9(K),Q=g(w).rehydrate(U,H);await new Z().handle(Q)}onFail(K){console.error(`The listener ${Z.name} threw while handling ${X} off the queue. The queue will retry it up to ${G} times in total; nothing the dispatcher did is waiting on it.`,K)}onDeadletter(K){console.error(`The listener ${Z.name} failed every one of its ${G} attempts at ${X} and has been dead-lettered, so this side effect did not happen and will not be retried.`,K)}};return Object.defineProperty(Y,"name",{value:M9(Z.name),writable:!0}),Y}function k9(Z){if(Object.getOwnPropertyDescriptor(Z,"name")?.writable)return;throw Error(`The listener ${Z.name} sets \`queued = true\` but does not declare \`static name\`, so it would be registered with the queue `+"under its class name \u2014 which a production build renames while the "+`payload that names it does not. Add: static name = "${Z.name}";`)}function R9(Z){return typeof Z[0]==="string"?Z:Z[0]}class w{static token="events";listeners={};events={};warnedFor=new Set;warnedAboutWaiting=new Set;config;constructor(Z={}){this.config=_(ZZ(),Z),this.useListeners(this.config.listeners)}useListeners(Z){this.config.listeners=Z,this.listeners={},this.events={};let $=new Set;for(let G of Z){if(!G.event){console.error(`Listener ${G.name} does not declare \`static event\`, so there is no event name to register it under and its handle will never run. Add: static event = SomeEvent;`);continue}if($.has(G.name)){console.error(`Two event listeners are named "${G.name}" \u2014 the first is `+"registered and this one is not. A listener's name identifies it across the framework, so only one class can hold it. Rename one.");continue}$.add(G.name);let W=G.event.name,z=new G;this.events[W]??=G.event,(this.listeners[W]??=[]).push({listener:G,job:z.queued?D3(G,z):null})}}get queuedListenerJobs(){return Object.values(this.listeners).flat().flatMap(({job:Z})=>Z?[Z]:[])}get registeredListeners(){return[...this.config.listeners]}dispatch(Z,$){if(this.deferToCommit(Z,$,!1))return;this.runListeners(Z,$)}async dispatchAndWait(Z,$){if(this.deferToCommit(Z,$,!0))return;return this.runListeners(Z,$)}deferToCommit(Z,$,G){let{name:W,afterCommit:z}=Z.constructor;if(!z)return!1;let X=A3(()=>this.runListeners(Z,$));if(X&&G)this.warnNothingIsWaitedFor(W);return X}async runListeners(Z,$){let G=Z.constructor.name,W=this.listeners[G];if(!W?.length){this.warnNothingIsListening(G);return}for(let{listener:z,job:X}of W){if(X){this.enqueue(X,z,G,$);continue}try{await new z().handle(Z)}catch(Y){console.error(`The listener ${z.name} threw while handling ${G}. The `+"listeners after it still ran \u2014 a listener's failure is its own.",Y)}}}rehydrate(Z,$=[]){let G=this.events[Z];if(!G)throw Error(`Cannot rebuild the event "${Z}" that came off the queue: no registered listener binds to an event of that name, so there is no class to construct. A queued listener runs in an application that `+"discovered its own listeners \u2014 check that this process sees the "+`same app/listeners as the one that dispatched, and that the event declares \`static name = "${Z}"\`.`);return new G(...$)}enqueue(Z,$,G,W){if(W===void 0){console.error(`The listener ${$.name} is queued, but ${G} reached the dispatcher without its constructor arguments, so there is nothing for the queue to rebuild it from and the listener was skipped. Dispatch through ${G}.dispatch(...) or ${G}.dispatchAndWait(...), which carry them.`);return}let z=(X)=>console.error(`The listener ${$.name} could not be queued for ${G}, so it did not run and will not be retried. The listeners after it still ran.`,X);try{g(D).push(Z,JSON.stringify([G,W]),{reportFailure:!1}).catch(z)}catch(X){z(X)}}warnNothingIsWaitedFor(Z){if(Bun.env.NODE_ENV==="production")return;if(this.warnedAboutWaiting.has(Z))return;this.warnedAboutWaiting.add(Z),console.warn(`[gemi] ${Z}.dispatchAndWait() was called inside a transaction and ${Z} declares \`static afterCommit = true\`, so it resolved `+"immediately with no listener having run \u2014 they run when the "+"transaction commits. Await the transaction instead, or drop afterCommit if the caller needs the side effects first. Development only.")}warnNothingIsListening(Z){if(Bun.env.NODE_ENV==="production")return;if(this.warnedFor.has(Z))return;this.warnedFor.add(Z),console.warn(`[gemi] ${Z} was dispatched and nothing is listening for it. A listener registers under the name its event declares, so check that app/listeners holds a Listener with \`static event = ${Z}\` and that ${Z} declares \`static name = "${Z}"\`. Development only.`)}}class w9 extends J{register(){this.app.singleton(w,()=>new w(this.app.config.get("events",{})))}async boot(){let Z=this.app.make(w),$=this.app.config.get("events",{});if($.listeners===void 0){let{listenersDir:z}=_(ZZ(),$);Z.useListeners(await L3(z))}let G=Z.queuedListenerJobs;if(G.length===0)return;let W=this.app.make(D);for(let z of G)W.registerJob(z)}}class E9 extends J{register(){this.app.singleton(jZ,()=>new jZ(this.app.config.get("filesystem",{})))}}class b9 extends J{register(){this.app.singleton(MZ,()=>new MZ(this.app.config.get("image",{})))}}class f9 extends J{register(){this.app.instance(kZ,new kZ)}}function y2(Z){return Z}function O3(){return{maxFileSize:10485760,onLogFileClosed:()=>{},onLogCreated:()=>{}}}class y9 extends J{register(){this.app.singleton($Z,()=>new $Z(_(O3(),this.app.config.get("log",{}))))}async boot(){if(!process.env.ROOT_DIR)return;await this.app.make($Z).boot()}}class v9 extends J{register(){this.app.singleton(GZ,()=>new GZ(_(q3(),this.app.config.get("middleware",{}))))}boot(){this.app.make(GZ).assertGlobalMiddleware()}}function s2(Z){return Z}function S3(){return{driver:new T3,limit:1000,window:60}}class g9 extends J{register(){this.app.singleton(v,()=>new v(_(S3(),this.app.config.get("ratelimiter",{}))))}}function G6(Z){return Z}function j3(){return{url:process.env.REDIS_URL,options:void 0}}class h9 extends J{register(){this.app.singleton(i,()=>new i(_(j3(),this.app.config.get("redis",{}))))}shutdown(){if(!this.app.resolved(i))return;this.app.make(i).close()}}function WZ(Z,$){let G=Z.get($);if(!G)throw Error(`Missing "${$}" configuration. Route dispatching needs a root router \u2014 declare it in "app/config/route.ts".`);return G}class m9 extends J{register(){this.app.singleton(m,()=>new m(WZ(this.app.config,"route.api"))),this.app.singleton(l,()=>new l(WZ(this.app.config,"route.view"))),this.app.singleton(zZ,()=>new zZ({api:this.app.make(m),view:this.app.make(l)},{api:WZ(this.app.config,"route.api"),view:WZ(this.app.config,"route.view"),domains:this.app.config.get("route.domains")})),this.app.singleton(y,()=>{let Z=this.app.config.get("route.mcp");if(!Z?.router)throw Error('No MCP router is configured. Declare one as `mcp: { router }` in "app/config/route.ts".');return new y(new Z.router,this.app.make(m),{files:Z.remote?.files})}),this.registerMcpHttp()}registerMcpHttp(){this.app.singleton(c,()=>{let Z=this.app.config.get("route.mcp");if(!Z?.remote?.enabled)throw Error("The MCP endpoint is not enabled: set route.mcp.remote.enabled.");return new c(this.app.make(y),Z.remote)})}boot(){if(this.app.make(m),this.app.make(l),this.app.make(zZ),this.app.config.get("route.mcp"))this.app.make(y);let Z=this.app.config.get("route.mcp.remote");if(Z?.enabled===!0)this.app.make(c);else if(Z?.enabled!==void 0&&Z.enabled!==!1)throw Error("route.mcp.remote.enabled must be true or false.")}}
|
|
8
|
-
export{k3 as ib,L as jb,d as kb,y as lb,KZ as mb,a3 as nb,HZ as ob,FZ as pb,NZ as qb,c as rb,R as sb,x9 as tb,q$ as ub,D9 as vb,A9 as wb,q9 as xb,h as yb,l$ as zb,P3 as Ab,T9 as Bb,S9 as Cb,j9 as Db,w as Eb,w9 as Fb,E9 as Gb,b9 as Hb,f9 as Ib,y2 as Jb,O3 as Kb,y9 as Lb,v9 as Mb,s2 as Nb,S3 as Ob,g9 as Pb,G6 as Qb,j3 as Rb,h9 as Sb,m9 as Tb};
|
|
9
|
-
|
|
10
|
-
//# debugId=AB2BC57546C7A4A264756E2164756E21
|
package/dist/chunk-63ewmmhc.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import{Mc as o}from"./chunk-jqrs16g2.js";import{Nc as i}from"./chunk-n9jyjp4a.js";import{Ch as t}from"./chunk-dz99g58c.js";import{Ci as r}from"./chunk-zw6843j3.js";class n extends i{register(){this.app.singleton(r,()=>new r(t(o(),this.app.config.get("translation",{}))))}}
|
|
3
|
-
export{n as fb};
|
|
4
|
-
|
|
5
|
-
//# debugId=90A6C1D8AB2BAFFE64756E2164756E21
|
package/dist/chunk-rhmpphhc.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import{yc as B}from"./chunk-pepzecrm.js";import{Cc as L,Ec as T}from"./chunk-y0en07zh.js";import{Qi as M,Ri as Y,Si as W}from"./chunk-8gtc3s1y.js";class D extends Error{code;constructor(q,z=1){super(q);this.code=z;this.name="CommandFailed"}}class X{static commandName="unset";static description="";static args=[];static options=[];run(q){}}function u(q){return q}function _(){return{commands:[],commandsDir:"app/commands"}}var S=Symbol.for("gemi.console.builder");function E(q){if(q.trim()==="")throw Error("A command name cannot be empty.");if(/[{}]/.test(q)||/\s/.test(q))throw Error(`Invalid command name ${JSON.stringify(q)}. gemi does not parse a signature string; the name is the whole of it. Declare arguments with .arg() and flags with .option():
|
|
3
|
-
|
|
4
|
-
defineCommand("mail:send")
|
|
5
|
-
.arg("user", { required: true })
|
|
6
|
-
.option("queue", { type: "boolean" })
|
|
7
|
-
.handle(async ({ args, options }) => { ... })`)}function p(q){E(q);let z=[],F=[],$="",Q={[S]:q,describe(G){return $=G,Q},arg(G,H={}){if(H.required&&H.default!==void 0)throw Error(`Argument "${G}" of command "${q}" is both required and has a default. An argument that is supplied when absent cannot also be `+"absent \u2014 drop one.");if(H.variadic&&H.default!==void 0)throw Error(`Argument "${G}" of command "${q}" is variadic and has a default. A variadic argument collects the remaining values and is an empty list when there are none, so the default could never `+"apply \u2014 drop it, or drop `variadic`.");let P=z.find((O)=>O.variadic);if(P)throw Error(`Argument "${G}" of command "${q}" is declared after the variadic argument "${P.name}", which collects everything that follows, so "${G}" could never receive a value. A variadic argument must be declared last.`);if(z.some((O)=>O.name===G))throw Error(`Command "${q}" declares the argument "${G}" twice.`);return z.push({...H,name:G}),Q},option(G,H){if(F.some((V)=>V.name===G))throw Error(`Command "${q}" declares the option "${G}" twice.`);let P="alias"in H?H.alias:void 0,O=P===void 0?void 0:F.find((V)=>("alias"in V)&&V.alias===P);if(O)throw Error(`Options "${O.name}" and "${G}" of command "${q}" both use the alias "-${P}".`);return F.push({...H,name:G}),Q},handle(G){let H=q,P=$,O=class extends X{static commandName=H;static description=P;static args=[...z];static options=[...F];run(V){return G(V)}};return delete Q[S],Object.defineProperty(O,"name",{value:H,configurable:!0}),O}};return Q}function A(q){return typeof q==="object"&&q!==null&&typeof q[S]==="string"}function m(q){return q}function C(){return{jobs:[],jobsDir:"app/cron"}}function l(q){return q}function I(){return{listeners:[],listenersDir:"app/listeners"}}class Z{static name="unset";static event;queued=!1;maxAttempts=3;backoff=0;worker=!1}import{existsSync as U}from"fs";import{dirname as k,isAbsolute as R,join as j}from"path";function J(q){return R(q)?q:j(W(),q)}function K(q,z,F){if(U(q)||U(k(q)))return;console.warn(`No ${z} were discovered: neither ${q} nor the directory above it exists, so this process cannot see the application's source. If this is a deploy that ships only the build output, list the classes explicitly in app/config/${F}.ts so they travel with it.`)}async function Pq(q=T().jobsDir){let z=J(q);K(z,"queue jobs","queue");let F=await Y(z,L);return x(F),F}function x(q){for(let z of q){if(Object.getOwnPropertyDescriptor(z,"name")?.writable)continue;console.warn(`Queued job ${z.name} does not declare \`static name\`, so it is registered under its class name. A production build minifies the class that dispatches it and renames it, while discovery reads this `+"file from source and does not \u2014 so the dispatch would be dropped in "+`production and nowhere else. Add: static name = "${z.name}";`)}}async function Qq(q=C().jobsDir){let z=J(q);return K(z,"cron jobs","schedule"),await Y(z,B)}async function Vq(q=_().commandsDir){let z=J(q);K(z,"commands","command");let F=[],$=await Y(z,X,[],(Q,G)=>{if(A(Q))F.push(G)});return w(F),$}function w(q){if(q.length===0)return;let z=q.length===1?`${q[0]} exports a command builder that never called \`.handle()\``:`${q.length} files export a command builder that never called \`.handle()\`:
|
|
8
|
-
${q.join(`
|
|
9
|
-
`)}`;throw new M(`${z}, so there is no command to run. \`.handle()\` is what turns `+`the chain into a command \u2014 finish it:
|
|
10
|
-
|
|
11
|
-
`+` export default defineCommand("my-command")
|
|
12
|
-
.handle(async ({ line }) => { line("hello") })`)}async function Xq(q=I().listenersDir){let z=J(q);K(z,"event listeners","events");let F=await Y(z,Z);return y(F),N(F),b(F),F}function y(q){let z=q.filter((F)=>!F.event);if(z.length===0)return;throw new M(`${z.map((F)=>F.name).join(", ")} declare no \`static event\`, so there is no event name to register them under and their \`handle\` would never run. Every listener binds to exactly one event:
|
|
13
|
-
|
|
14
|
-
static event = UserRegistered;
|
|
15
|
-
|
|
16
|
-
If this is an abstract base its subclasses extend, move it out of the `+"listeners directory \u2014 the walk excludes gemi's `Listener` and "+"nothing else, so a base sitting beside its subclasses is registered and run like one of them.")}function N(q){for(let z of q){if(Object.getOwnPropertyDescriptor(z,"name")?.writable)continue;console.warn(`Event listener ${z.name} does not declare \`static name\`, so it is registered under its class name, which a production build renames. Nothing reads that name across a build boundary while the `+"listener is sync, which is why this is a warning \u2014 but adding "+`\`queued = true\` to it is refused at boot for the same reason, because the queue's key is that string. Add: static name = "${z.name}";`)}}function b(q){let z=new Set;for(let{event:F}of q){if(z.has(F))continue;if(Object.getOwnPropertyDescriptor(F,"name")?.writable)continue;z.add(F),console.warn(`Event ${F.name} does not declare \`static name\`, so it is dispatched under its class name. A production build minifies the code that dispatches it and renames the class, while discovery reads `+"the listener's copy from source and does not \u2014 so the dispatch would "+`reach no listener in production and nowhere else. Add: static name = "${F.name}";`)}}
|
|
17
|
-
export{D as kc,X as lc,u as mc,_ as nc,p as oc,m as pc,C as qc,l as rc,I as sc,Z as tc,Pq as uc,Qq as vc,Vq as wc,Xq as xc};
|
|
18
|
-
|
|
19
|
-
//# debugId=4CF47CD0D00FFD0364756E2164756E21
|