devflare 1.0.0-next.19 → 1.0.0-next.20
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/LLM.md +6807 -888
- package/README.md +375 -957
- package/dist/account-05zgta47.js +475 -0
- package/dist/account-b2ag1esh.js +475 -0
- package/dist/account-bxtcz61a.js +475 -0
- package/dist/account-gyfqg964.js +475 -0
- package/dist/account-q6pvs9d9.js +475 -0
- package/dist/account-rp4zbvw1.js +475 -0
- package/dist/bridge/client.d.ts +5 -0
- package/dist/bridge/client.d.ts.map +1 -1
- package/dist/bridge/gateway-runtime.d.ts +1 -1
- package/dist/bridge/gateway-runtime.d.ts.map +1 -1
- package/dist/bridge/miniflare.d.ts +67 -0
- package/dist/bridge/miniflare.d.ts.map +1 -1
- package/dist/bridge/proxy.d.ts +2 -1
- package/dist/bridge/proxy.d.ts.map +1 -1
- package/dist/bridge/server.d.ts.map +1 -1
- package/dist/browser.d.ts +2520 -40
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +3 -3
- package/dist/build-2s5paw5p.js +54 -0
- package/dist/build-4c350cp7.js +54 -0
- package/dist/build-e7wym63t.js +54 -0
- package/dist/build-ge6qp3t4.js +54 -0
- package/dist/build-ta8c6t11.js +54 -0
- package/dist/build-wvjj8f28.js +54 -0
- package/dist/build-ypg6f2kw.js +54 -0
- package/dist/build-yts8wwgf.js +54 -0
- package/dist/build-yzkdqexs.js +54 -0
- package/dist/cli/build-manifest.d.ts +12 -0
- package/dist/cli/build-manifest.d.ts.map +1 -1
- package/dist/cli/commands/deploy/metadata.d.ts +18 -0
- package/dist/cli/commands/deploy/metadata.d.ts.map +1 -0
- package/dist/cli/commands/deploy/prepare.d.ts +23 -0
- package/dist/cli/commands/deploy/prepare.d.ts.map +1 -0
- package/dist/cli/commands/deploy/runtime.d.ts +4 -0
- package/dist/cli/commands/deploy/runtime.d.ts.map +1 -0
- package/dist/cli/commands/deploy/verification.d.ts +36 -0
- package/dist/cli/commands/deploy/verification.d.ts.map +1 -0
- package/dist/cli/commands/deploy.d.ts +2 -2
- package/dist/cli/commands/deploy.d.ts.map +1 -1
- package/dist/cli/commands/secrets.d.ts +4 -0
- package/dist/cli/commands/secrets.d.ts.map +1 -0
- package/dist/cli/commands/type-generation/generator.d.ts +67 -1
- package/dist/cli/commands/type-generation/generator.d.ts.map +1 -1
- package/dist/cli/help-pages/pages/core.d.ts +1 -1
- package/dist/cli/help-pages/pages/core.d.ts.map +1 -1
- package/dist/cli/help-pages/shared.d.ts +1 -1
- package/dist/cli/help-pages/shared.d.ts.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/package-metadata.d.ts.map +1 -1
- package/dist/cli/preview-bindings.d.ts.map +1 -1
- package/dist/cloudflare/index.js +2 -2
- package/dist/cloudflare/preview-registry-store.d.ts +1 -1
- package/dist/cloudflare/preview-registry-store.d.ts.map +1 -1
- package/dist/cloudflare/types.d.ts +1 -1
- package/dist/cloudflare/types.d.ts.map +1 -1
- package/dist/config/binding-resolution-helpers.d.ts +5 -0
- package/dist/config/binding-resolution-helpers.d.ts.map +1 -1
- package/dist/config/compiler/bindings.d.ts +14 -0
- package/dist/config/compiler/bindings.d.ts.map +1 -0
- package/dist/config/compiler/core-helpers.d.ts +6 -0
- package/dist/config/compiler/core-helpers.d.ts.map +1 -0
- package/dist/config/compiler/do-workers.d.ts +34 -0
- package/dist/config/compiler/do-workers.d.ts.map +1 -0
- package/dist/config/compiler/paths.d.ts +18 -0
- package/dist/config/compiler/paths.d.ts.map +1 -0
- package/dist/config/compiler/types.d.ts +267 -0
- package/dist/config/compiler/types.d.ts.map +1 -0
- package/dist/config/compiler.d.ts +11 -175
- package/dist/config/compiler.d.ts.map +1 -1
- package/dist/config/deploy-resources.d.ts.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/local-dev-vars.d.ts +15 -0
- package/dist/config/local-dev-vars.d.ts.map +1 -0
- package/dist/config/preview-resources.d.ts.map +1 -1
- package/dist/config/preview.d.ts.map +1 -1
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resource-resolution.d.ts.map +1 -1
- package/dist/config/schema-bindings.d.ts +559 -19
- package/dist/config/schema-bindings.d.ts.map +1 -1
- package/dist/config/schema-env.d.ts +1306 -34
- package/dist/config/schema-env.d.ts.map +1 -1
- package/dist/config/schema-normalization.d.ts +97 -1
- package/dist/config/schema-normalization.d.ts.map +1 -1
- package/dist/config/schema-runtime.d.ts +245 -7
- package/dist/config/schema-runtime.d.ts.map +1 -1
- package/dist/config/schema.d.ts +2976 -57
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config-6m0n7d84.js +59 -0
- package/dist/config-7cf004ag.js +59 -0
- package/dist/config-b98dp58n.js +59 -0
- package/dist/config-cf3djhqy.js +59 -0
- package/dist/config-entry.js +1 -1
- package/dist/config-wa7hm0w9.js +59 -0
- package/dist/deploy-1jfagtn9.js +1055 -0
- package/dist/deploy-2afw0jfg.js +1055 -0
- package/dist/deploy-2fzj68kq.js +1055 -0
- package/dist/deploy-57nzn9wj.js +1045 -0
- package/dist/deploy-asyryrvm.js +1055 -0
- package/dist/deploy-hc927rw6.js +1045 -0
- package/dist/deploy-pnnf8tgy.js +1045 -0
- package/dist/deploy-q33bw715.js +1055 -0
- package/dist/deploy-tmdgecs3.js +1055 -0
- package/dist/deploy-v0y8kczr.js +1055 -0
- package/dist/deploy-xhj6zbcx.js +1055 -0
- package/dist/dev-1mvcts8w.js +2515 -0
- package/dist/dev-2a283xts.js +2515 -0
- package/dist/dev-62nhytf8.js +2505 -0
- package/dist/dev-75acm2xj.js +2478 -0
- package/dist/dev-802rg9dp.js +2515 -0
- package/dist/dev-d1bb2t0f.js +2515 -0
- package/dist/dev-dwry8494.js +2489 -0
- package/dist/dev-g6112y4w.js +2515 -0
- package/dist/dev-h2kneh95.js +2496 -0
- package/dist/dev-kybq3mwr.js +2489 -0
- package/dist/dev-n8qndkyg.js +2512 -0
- package/dist/dev-p32fkbwf.js +2489 -0
- package/dist/dev-qm9d4mfh.js +2478 -0
- package/dist/dev-rcthnse5.js +2473 -0
- package/dist/dev-server/dev-server-state.d.ts +1 -0
- package/dist/dev-server/dev-server-state.d.ts.map +1 -1
- package/dist/dev-server/miniflare-bindings.d.ts +44 -1
- package/dist/dev-server/miniflare-bindings.d.ts.map +1 -1
- package/dist/dev-server/miniflare-dev-config.d.ts +1 -0
- package/dist/dev-server/miniflare-dev-config.d.ts.map +1 -1
- package/dist/dev-server/miniflare-log.d.ts +8 -0
- package/dist/dev-server/miniflare-log.d.ts.map +1 -1
- package/dist/dev-server/miniflare-worker-config.d.ts +31 -1
- package/dist/dev-server/miniflare-worker-config.d.ts.map +1 -1
- package/dist/dev-server/server.d.ts.map +1 -1
- package/dist/dev-server/vite-process.d.ts +1 -0
- package/dist/dev-server/vite-process.d.ts.map +1 -1
- package/dist/dev-tgwja5mz.js +2496 -0
- package/dist/doctor-2shhdak6.js +245 -0
- package/dist/doctor-5g73w40j.js +245 -0
- package/dist/doctor-gamefzcs.js +245 -0
- package/dist/doctor-rn53ctfs.js +245 -0
- package/dist/index-01kehw41.js +348 -0
- package/dist/index-06bg0z9y.js +185 -0
- package/dist/index-0d7tw5r4.js +136 -0
- package/dist/index-0m6e4mxz.js +133 -0
- package/dist/index-0vah20er.js +1410 -0
- package/dist/index-0wa0ebm1.js +68 -0
- package/dist/index-1714y3cz.js +1410 -0
- package/dist/index-1qs5gcm7.js +895 -0
- package/dist/index-29k04v43.js +574 -0
- package/dist/index-2jywf4pz.js +1372 -0
- package/dist/index-2qhk9nbx.js +1372 -0
- package/dist/index-2vq6bveq.js +574 -0
- package/dist/index-36h8gkhb.js +1088 -0
- package/dist/index-38fq7pww.js +560 -0
- package/dist/index-3bxqn033.js +1410 -0
- package/dist/index-3jme4hgw.js +1234 -0
- package/dist/index-3p7s9mk9.js +360 -0
- package/dist/index-47w35sft.js +244 -0
- package/dist/index-4by4c7rm.js +52 -0
- package/dist/index-4phjwd6h.js +412 -0
- package/dist/index-4z5jrw0j.js +594 -0
- package/dist/index-51mzqy0d.js +895 -0
- package/dist/index-53pqqpq9.js +74 -0
- package/dist/index-5enq8ntr.js +1766 -0
- package/dist/index-5fnq9r9m.js +1410 -0
- package/dist/index-5w9f2b17.js +695 -0
- package/dist/index-627srx16.js +45 -0
- package/dist/index-6bqgf5x8.js +227 -0
- package/dist/index-6xknvbyk.js +1088 -0
- package/dist/index-7ef3ktz5.js +1372 -0
- package/dist/index-7hpjfdzh.js +185 -0
- package/dist/index-8052df4m.js +627 -0
- package/dist/index-82epjzrr.js +1410 -0
- package/dist/index-82z7rvz6.js +1238 -0
- package/dist/index-8atc1yb9.js +68 -0
- package/dist/index-8tj0awnv.js +476 -0
- package/dist/index-8x745h59.js +1069 -0
- package/dist/index-9bawzcny.js +574 -0
- package/dist/index-9bjjqdfc.js +236 -0
- package/dist/index-9d7x3vfr.js +236 -0
- package/dist/index-9nf8zs4p.js +1069 -0
- package/dist/index-acwbmagz.js +412 -0
- package/dist/index-aqjdaem7.js +74 -0
- package/dist/index-b6448fd0.js +133 -0
- package/dist/index-b9j55r7q.js +240 -0
- package/dist/index-bdatd1za.js +1372 -0
- package/dist/index-c3nxftnp.js +699 -0
- package/dist/index-c643s0gv.js +488 -0
- package/dist/index-d2md1j3d.js +185 -0
- package/dist/index-dbr6bfz6.js +528 -0
- package/dist/index-dd1g0g7e.js +360 -0
- package/dist/index-dktb9az5.js +1372 -0
- package/dist/index-dm9q84c7.js +360 -0
- package/dist/index-f51mkh13.js +1088 -0
- package/dist/index-f86n1fpd.js +55 -0
- package/dist/index-fnk0tkw7.js +412 -0
- package/dist/index-g5aq66bj.js +1534 -0
- package/dist/index-gj5qh491.js +54 -0
- package/dist/index-gq39t0rx.js +895 -0
- package/dist/index-h5dqna7q.js +1410 -0
- package/dist/index-hjs9j2g9.js +895 -0
- package/dist/index-hn5nbxbt.js +147 -0
- package/dist/index-hpjh0qjx.js +1723 -0
- package/dist/index-hs6ekcfs.js +412 -0
- package/dist/index-jdzrvnfj.js +52 -0
- package/dist/index-jg720mq7.js +476 -0
- package/dist/index-jrzddxvt.js +2167 -0
- package/dist/index-kgstnk6g.js +239 -0
- package/dist/index-khnw972v.js +117 -0
- package/dist/index-kwqff3ba.js +1410 -0
- package/dist/index-m2v0fj08.js +74 -0
- package/dist/index-mjve6tqn.js +447 -0
- package/dist/index-mkxzgn0q.js +1372 -0
- package/dist/index-mzmq3v0d.js +1088 -0
- package/dist/index-ng9n3znd.js +1372 -0
- package/dist/index-nhbkm2ba.js +467 -0
- package/dist/index-nrfhk0k5.js +1088 -0
- package/dist/index-p0zppqxm.js +467 -0
- package/dist/index-pkxf6h87.js +895 -0
- package/dist/index-pqp4312v.js +52 -0
- package/dist/index-pw9jn6kz.js +574 -0
- package/dist/index-q31ne0xa.js +412 -0
- package/dist/index-qf2dkqxh.js +249 -0
- package/dist/index-qmtdf7k5.js +639 -0
- package/dist/index-qwgr4q7s.js +37 -0
- package/dist/index-rab2dfh3.js +494 -0
- package/dist/index-rz7rx80s.js +1410 -0
- package/dist/index-s37h3jgk.js +572 -0
- package/dist/index-sb705m7d.js +52 -0
- package/dist/index-syscwrjp.js +1576 -0
- package/dist/index-t14zr0ys.js +1063 -0
- package/dist/index-tjc99447.js +68 -0
- package/dist/index-v35460hf.js +574 -0
- package/dist/index-v7q00d1e.js +1410 -0
- package/dist/index-vkkmx4xe.js +1372 -0
- package/dist/index-vrps1gky.js +2202 -0
- package/dist/index-w4c9vmvg.js +1517 -0
- package/dist/index-wqd8n2qk.js +574 -0
- package/dist/index-x12e6fzy.js +476 -0
- package/dist/index-xagpz645.js +2199 -0
- package/dist/index-xbth1r6e.js +572 -0
- package/dist/index-xm9fqhcb.js +447 -0
- package/dist/index-y59hnmd0.js +132 -0
- package/dist/index-y7mkb00x.js +133 -0
- package/dist/index-z40mjts9.js +212 -0
- package/dist/index-z5k5bjc7.js +1218 -0
- package/dist/index-z73sytma.js +895 -0
- package/dist/index-zjv6apef.js +1410 -0
- package/dist/index.js +8 -8
- package/dist/init-cwpergap.js +180 -0
- package/dist/login-83bjfhvz.js +77 -0
- package/dist/login-ddw888xb.js +77 -0
- package/dist/login-e7pytkdc.js +77 -0
- package/dist/login-fe0brfcr.js +77 -0
- package/dist/login-h7sm5trm.js +77 -0
- package/dist/login-vd0m3xr4.js +77 -0
- package/dist/previews-2wfvsjfy.js +1337 -0
- package/dist/previews-31feb8r3.js +1337 -0
- package/dist/previews-3w4pxqby.js +1337 -0
- package/dist/previews-93ttrf5f.js +1337 -0
- package/dist/previews-bdrefjzx.js +1337 -0
- package/dist/previews-cfcn56b4.js +1337 -0
- package/dist/previews-mssq1hrm.js +1337 -0
- package/dist/previews-tcaz1gt8.js +1337 -0
- package/dist/productions-4h80j2c7.js +505 -0
- package/dist/productions-86jaqt7m.js +505 -0
- package/dist/productions-bn2q31my.js +505 -0
- package/dist/productions-dv8g7f6g.js +505 -0
- package/dist/productions-e2m9s4tr.js +505 -0
- package/dist/productions-fgshs1m7.js +505 -0
- package/dist/productions-hphmt68n.js +505 -0
- package/dist/productions-vhq7yx86.js +505 -0
- package/dist/runtime/index.js +8 -8
- package/dist/secrets/local-secrets.d.ts +46 -0
- package/dist/secrets/local-secrets.d.ts.map +1 -0
- package/dist/secrets-8wcj47nh.js +91 -0
- package/dist/secrets-b2ww34ta.js +91 -0
- package/dist/secrets-b7g4z621.js +91 -0
- package/dist/shims/local-media-bindings.d.ts +19 -0
- package/dist/shims/local-media-bindings.d.ts.map +1 -0
- package/dist/shims/local-worker-loader.d.ts +3 -0
- package/dist/shims/local-worker-loader.d.ts.map +1 -0
- package/dist/sveltekit/index.js +163 -26
- package/dist/sveltekit/local-bindings.d.ts +4 -0
- package/dist/sveltekit/local-bindings.d.ts.map +1 -0
- package/dist/sveltekit/platform.d.ts +8 -0
- package/dist/sveltekit/platform.d.ts.map +1 -1
- package/dist/test/ai-search.d.ts +39 -0
- package/dist/test/ai-search.d.ts.map +1 -0
- package/dist/test/binding-hints.d.ts.map +1 -1
- package/dist/test/cf.d.ts +3 -3
- package/dist/test/containers.d.ts +87 -0
- package/dist/test/containers.d.ts.map +1 -0
- package/dist/test/index.d.ts +4 -1
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/index.js +2833 -543
- package/dist/test/local-worker-loader.d.ts +3 -0
- package/dist/test/local-worker-loader.d.ts.map +1 -0
- package/dist/test/offline-bindings.d.ts +65 -0
- package/dist/test/offline-bindings.d.ts.map +1 -0
- package/dist/test/queue.d.ts.map +1 -1
- package/dist/test/remote-ai.d.ts.map +1 -1
- package/dist/test/should-skip.d.ts +14 -0
- package/dist/test/should-skip.d.ts.map +1 -1
- package/dist/test/simple-context-bindings.d.ts.map +1 -1
- package/dist/test/simple-context-durable-objects.d.ts.map +1 -1
- package/dist/test/simple-context-gateway-script.d.ts +1 -1
- package/dist/test/simple-context-gateway-script.d.ts.map +1 -1
- package/dist/test/simple-context-lifecycle.d.ts.map +1 -1
- package/dist/test/simple-context-mfconfig.d.ts +4 -1
- package/dist/test/simple-context-mfconfig.d.ts.map +1 -1
- package/dist/test/simple-context-multi-worker.d.ts.map +1 -1
- package/dist/test/simple-context-startup.d.ts.map +1 -1
- package/dist/test/tail.d.ts.map +1 -1
- package/dist/test/utilities/artifacts.d.ts +11 -0
- package/dist/test/utilities/artifacts.d.ts.map +1 -0
- package/dist/test/utilities/context.d.ts +39 -0
- package/dist/test/utilities/context.d.ts.map +1 -0
- package/dist/test/utilities/d1.d.ts +21 -0
- package/dist/test/utilities/d1.d.ts.map +1 -0
- package/dist/test/utilities/env.d.ts +40 -0
- package/dist/test/utilities/env.d.ts.map +1 -0
- package/dist/test/utilities/kv.d.ts +11 -0
- package/dist/test/utilities/kv.d.ts.map +1 -0
- package/dist/test/utilities/media.d.ts +16 -0
- package/dist/test/utilities/media.d.ts.map +1 -0
- package/dist/test/utilities/platform.d.ts +38 -0
- package/dist/test/utilities/platform.d.ts.map +1 -0
- package/dist/test/utilities/queue.d.ts +5 -0
- package/dist/test/utilities/queue.d.ts.map +1 -0
- package/dist/test/utilities/r2.d.ts +12 -0
- package/dist/test/utilities/r2.d.ts.map +1 -0
- package/dist/test/utilities/workflows.d.ts +26 -0
- package/dist/test/utilities/workflows.d.ts.map +1 -0
- package/dist/test/utilities.d.ts +10 -106
- package/dist/test/utilities.d.ts.map +1 -1
- package/dist/types-2ejrbba1.js +695 -0
- package/dist/types-7jkbm95a.js +695 -0
- package/dist/types-a2fk9yns.js +695 -0
- package/dist/types-dyb3c6zw.js +695 -0
- package/dist/types-e2n9f3pd.js +695 -0
- package/dist/types-j4s6qcrc.js +695 -0
- package/dist/utils/send-email.d.ts.map +1 -1
- package/dist/utils/send-email.js +1 -1
- package/dist/vite/index.js +6 -6
- package/dist/vite/plugin-context.d.ts.map +1 -1
- package/dist/worker-663em30d.js +513 -0
- package/dist/worker-argxc7fb.js +513 -0
- package/dist/worker-entry/composed-worker.d.ts.map +1 -1
- package/dist/worker-entry/surface-paths.d.ts +2 -0
- package/dist/worker-entry/surface-paths.d.ts.map +1 -1
- package/dist/worker-fcdsnj14.js +513 -0
- package/dist/worker-fk42rzse.js +513 -0
- package/dist/worker-jkemk8d2.js +513 -0
- package/dist/worker-m4ze8djx.js +513 -0
- package/dist/worker-wnan5dca.js +513 -0
- package/dist/worker-yw3atfb1.js +513 -0
- package/dist/workflows/local-workflow-entrypoints.d.ts +7 -0
- package/dist/workflows/local-workflow-entrypoints.d.ts.map +1 -0
- package/package.json +13 -12
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
// src/dev-server/miniflare-log.ts
|
|
2
|
+
var ANSI_ESCAPE_REGEX = /\u001B\[[0-9;]*m/g;
|
|
3
|
+
var COMPATIBILITY_DATE_FALLBACK_REGEX = /^The latest compatibility date supported by the installed Cloudflare Workers Runtime is "([^"]+)", but you've requested "([^"]+)"\. Falling back to "([^"]+)"\.\.\.$/;
|
|
4
|
+
var MINIFLARE_LOG_LEVEL_FALLBACKS = {
|
|
5
|
+
WARN: 2,
|
|
6
|
+
DEBUG: 4
|
|
7
|
+
};
|
|
8
|
+
function normalizeMiniflareMessage(message) {
|
|
9
|
+
return message.replace(ANSI_ESCAPE_REGEX, "").replace(/\s+/g, " ").trim();
|
|
10
|
+
}
|
|
11
|
+
function formatCompatibilityDateFallbackNotice(message) {
|
|
12
|
+
const normalizedMessage = normalizeMiniflareMessage(message);
|
|
13
|
+
const match = COMPATIBILITY_DATE_FALLBACK_REGEX.exec(normalizedMessage);
|
|
14
|
+
if (!match) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const [, _supportedDate, requestedDate, fallbackDate] = match;
|
|
18
|
+
return `Using latest supported Cloudflare Workers Runtime compatibility date ${fallbackDate} (requested ${requestedDate})`;
|
|
19
|
+
}
|
|
20
|
+
function resolveMiniflareLogLevel(logLevel, levelName) {
|
|
21
|
+
return logLevel?.[levelName] ?? MINIFLARE_LOG_LEVEL_FALLBACKS[levelName];
|
|
22
|
+
}
|
|
23
|
+
function createCompatibilityAwareMiniflareLog(BaseLog, level, logger) {
|
|
24
|
+
const log = new BaseLog(level);
|
|
25
|
+
const originalWarn = log.warn.bind(log);
|
|
26
|
+
const originalInfo = log.info.bind(log);
|
|
27
|
+
log.warn = (message) => {
|
|
28
|
+
const notice = formatCompatibilityDateFallbackNotice(message);
|
|
29
|
+
if (!notice) {
|
|
30
|
+
originalWarn(message);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (logger) {
|
|
34
|
+
logger.info(notice);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
originalInfo(notice);
|
|
38
|
+
};
|
|
39
|
+
return log;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/bridge/gateway-runtime.ts
|
|
43
|
+
var GATEWAY_RUNTIME_JS = `
|
|
44
|
+
const RAW_EMAIL = 'EmailMessage::raw'
|
|
45
|
+
|
|
46
|
+
function arrayBufferToBase64(buffer) {
|
|
47
|
+
const bytes = new Uint8Array(buffer)
|
|
48
|
+
let binary = ''
|
|
49
|
+
for (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i])
|
|
50
|
+
return btoa(binary)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function base64ToArrayBuffer(base64) {
|
|
54
|
+
const binary = atob(base64)
|
|
55
|
+
const bytes = new Uint8Array(binary.length)
|
|
56
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)
|
|
57
|
+
return bytes.buffer
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function serializeR2Object(obj) {
|
|
61
|
+
if (!obj) return null
|
|
62
|
+
return {
|
|
63
|
+
__type: 'R2Object',
|
|
64
|
+
key: obj.key,
|
|
65
|
+
version: obj.version,
|
|
66
|
+
size: obj.size,
|
|
67
|
+
etag: obj.etag,
|
|
68
|
+
httpEtag: obj.httpEtag,
|
|
69
|
+
checksums: obj.checksums,
|
|
70
|
+
uploaded: obj.uploaded?.toISOString(),
|
|
71
|
+
httpMetadata: obj.httpMetadata,
|
|
72
|
+
customMetadata: obj.customMetadata,
|
|
73
|
+
range: obj.range,
|
|
74
|
+
storageClass: obj.storageClass
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function serializeR2ObjectBody(obj, bodyData) {
|
|
79
|
+
if (!obj) return null
|
|
80
|
+
return {
|
|
81
|
+
__type: 'R2ObjectBody',
|
|
82
|
+
key: obj.key,
|
|
83
|
+
version: obj.version,
|
|
84
|
+
size: obj.size,
|
|
85
|
+
etag: obj.etag,
|
|
86
|
+
httpEtag: obj.httpEtag,
|
|
87
|
+
checksums: obj.checksums,
|
|
88
|
+
uploaded: obj.uploaded?.toISOString(),
|
|
89
|
+
httpMetadata: obj.httpMetadata,
|
|
90
|
+
customMetadata: obj.customMetadata,
|
|
91
|
+
range: obj.range,
|
|
92
|
+
storageClass: obj.storageClass,
|
|
93
|
+
bodyData
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function serializeR2Objects(result) {
|
|
98
|
+
if (!result) return null
|
|
99
|
+
return {
|
|
100
|
+
objects: result.objects.map(serializeR2Object),
|
|
101
|
+
truncated: result.truncated,
|
|
102
|
+
cursor: result.cursor,
|
|
103
|
+
delimitedPrefixes: result.delimitedPrefixes
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function serializeResponse(response) {
|
|
108
|
+
let body = null
|
|
109
|
+
if (response.body) {
|
|
110
|
+
const bytes = await response.arrayBuffer()
|
|
111
|
+
if (bytes.byteLength > 0) {
|
|
112
|
+
body = { type: 'bytes', data: arrayBufferToBase64(bytes) }
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
status: response.status,
|
|
117
|
+
statusText: response.statusText,
|
|
118
|
+
headers: [...response.headers.entries()],
|
|
119
|
+
body
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function createEmailMessageRaw(raw) {
|
|
124
|
+
if (typeof raw === 'string' || raw instanceof ReadableStream) {
|
|
125
|
+
return raw
|
|
126
|
+
}
|
|
127
|
+
if (raw instanceof ArrayBuffer || raw instanceof Uint8Array) {
|
|
128
|
+
return new Response(raw).body
|
|
129
|
+
}
|
|
130
|
+
throw new Error('Unsupported EmailMessage raw payload')
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function isDurableObjectNamespace(binding) {
|
|
134
|
+
return !!binding
|
|
135
|
+
&& typeof binding.idFromName === 'function'
|
|
136
|
+
&& typeof binding.idFromString === 'function'
|
|
137
|
+
&& typeof binding.newUniqueId === 'function'
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Execute an RPC method against the gateway's bindings.
|
|
142
|
+
*
|
|
143
|
+
* Method format: "binding.operation". Operations must be namespaced by
|
|
144
|
+
* binding kind (e.g. "kv.get", "r2.head", "d1.stmt.first", "do.fetch",
|
|
145
|
+
* "queue.send", "email.send", "ai.run"). Bare verbs and the legacy
|
|
146
|
+
* "stmt.*" / "stub.*" sub-prefixes were removed in B3-final and now throw.
|
|
147
|
+
* Method vocabulary must stay in sync with the canonical server in
|
|
148
|
+
* src/bridge/server.ts.
|
|
149
|
+
*/
|
|
150
|
+
async function executeRpcMethod(method, params, env, _ctx) {
|
|
151
|
+
const parts = method.split('.')
|
|
152
|
+
if (parts.length < 2) throw new Error('Invalid method format: ' + method)
|
|
153
|
+
|
|
154
|
+
const bindingName = parts[0]
|
|
155
|
+
const operation = parts.slice(1).join('.')
|
|
156
|
+
const binding = env[bindingName]
|
|
157
|
+
|
|
158
|
+
if (!binding) throw new Error('Binding not found: ' + bindingName)
|
|
159
|
+
|
|
160
|
+
const isNamespaced =
|
|
161
|
+
operation.indexOf('kv.') === 0 ||
|
|
162
|
+
operation.indexOf('r2.') === 0 ||
|
|
163
|
+
operation.indexOf('d1.') === 0 ||
|
|
164
|
+
operation.indexOf('do.') === 0 ||
|
|
165
|
+
operation.indexOf('queue.') === 0 ||
|
|
166
|
+
operation.indexOf('email.') === 0 ||
|
|
167
|
+
operation.indexOf('ai.') === 0 ||
|
|
168
|
+
operation.indexOf('var.') === 0
|
|
169
|
+
if (!isNamespaced) {
|
|
170
|
+
throw new Error(
|
|
171
|
+
"[devflare][bridge] Unsupported bridge operation '" + operation + "' for binding '" + bindingName + "'. "
|
|
172
|
+
+ "Bare verbs and the legacy stmt.*/stub.* sub-prefixes were removed in B3-final; "
|
|
173
|
+
+ "use the namespaced form (e.g. kv.get, r2.put, d1.stmt.first, do.fetch)."
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// KV
|
|
178
|
+
if (operation === 'kv.get') return binding.get(params[0], params[1])
|
|
179
|
+
if (operation === 'kv.put') return binding.put(params[0], params[1], params[2])
|
|
180
|
+
if (operation === 'kv.delete') return binding.delete(params[0])
|
|
181
|
+
if (operation === 'kv.list') return binding.list(params[0])
|
|
182
|
+
if (operation === 'kv.getWithMetadata') return binding.getWithMetadata(params[0], params[1])
|
|
183
|
+
|
|
184
|
+
// DO get (returns DOStub reference)
|
|
185
|
+
if (operation === 'do.get') {
|
|
186
|
+
return { __type: 'DOStub', binding: bindingName, id: params[0] }
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// R2
|
|
190
|
+
if (operation === 'r2.head') return serializeR2Object(await binding.head(params[0]))
|
|
191
|
+
if (operation === 'r2.get') {
|
|
192
|
+
const obj = await binding.get(params[0], params[1])
|
|
193
|
+
if (!obj) return null
|
|
194
|
+
const body = await obj.arrayBuffer()
|
|
195
|
+
return serializeR2ObjectBody(obj, arrayBufferToBase64(body))
|
|
196
|
+
}
|
|
197
|
+
if (operation === 'r2.put') {
|
|
198
|
+
let value = params[1]
|
|
199
|
+
if (value && typeof value === 'object') {
|
|
200
|
+
if (value.__type === 'ArrayBuffer' || value.__type === 'Uint8Array') {
|
|
201
|
+
value = base64ToArrayBuffer(value.data)
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return serializeR2Object(await binding.put(params[0], value, params[2]))
|
|
205
|
+
}
|
|
206
|
+
if (operation === 'r2.delete') return binding.delete(params[0])
|
|
207
|
+
if (operation === 'r2.list') return serializeR2Objects(await binding.list(params[0]))
|
|
208
|
+
|
|
209
|
+
// D1
|
|
210
|
+
if (operation === 'd1.exec') return binding.exec(params[0])
|
|
211
|
+
if (operation === 'd1.batch') {
|
|
212
|
+
const statements = params[0].map((s) => binding.prepare(s.sql).bind(...(s.bindings || [])))
|
|
213
|
+
return binding.batch(statements)
|
|
214
|
+
}
|
|
215
|
+
if (operation.indexOf('d1.stmt.') === 0) {
|
|
216
|
+
const mode = operation.split('.')[2]
|
|
217
|
+
const [sql, ...rest] = params
|
|
218
|
+
let bindings = rest
|
|
219
|
+
let extraParam
|
|
220
|
+
if (mode === 'first' || mode === 'raw') {
|
|
221
|
+
extraParam = rest[rest.length - 1]
|
|
222
|
+
bindings = rest.slice(0, -1)
|
|
223
|
+
}
|
|
224
|
+
let stmt = binding.prepare(sql)
|
|
225
|
+
if (bindings.length > 0) stmt = stmt.bind(...bindings)
|
|
226
|
+
if (mode === 'first') {
|
|
227
|
+
if (typeof extraParam === 'string' && extraParam.length > 0) return stmt.first(extraParam)
|
|
228
|
+
return stmt.first()
|
|
229
|
+
}
|
|
230
|
+
if (mode === 'all') return stmt.all()
|
|
231
|
+
if (mode === 'run') return stmt.run()
|
|
232
|
+
if (mode === 'raw') return stmt.raw(extraParam)
|
|
233
|
+
throw new Error('Unknown stmt mode: ' + mode)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Durable Objects
|
|
237
|
+
if (operation === 'do.idFromName') {
|
|
238
|
+
const id = binding.idFromName(params[0])
|
|
239
|
+
return { __type: 'DOId', hex: id.toString() }
|
|
240
|
+
}
|
|
241
|
+
if (operation === 'do.idFromString') {
|
|
242
|
+
const id = binding.idFromString(params[0])
|
|
243
|
+
return { __type: 'DOId', hex: id.toString() }
|
|
244
|
+
}
|
|
245
|
+
if (operation === 'do.newUniqueId') {
|
|
246
|
+
const id = binding.newUniqueId(params[0])
|
|
247
|
+
return { __type: 'DOId', hex: id.toString() }
|
|
248
|
+
}
|
|
249
|
+
if (operation === 'do.fetch') {
|
|
250
|
+
const [, serializedId, serializedReq] = params
|
|
251
|
+
const id = binding.idFromString(serializedId.hex)
|
|
252
|
+
const stub = binding.get(id)
|
|
253
|
+
const response = await stub.fetch(new Request(serializedReq.url, {
|
|
254
|
+
method: serializedReq.method,
|
|
255
|
+
headers: serializedReq.headers,
|
|
256
|
+
body: serializedReq.body?.type === 'bytes'
|
|
257
|
+
? base64ToArrayBuffer(serializedReq.body.data)
|
|
258
|
+
: undefined
|
|
259
|
+
}))
|
|
260
|
+
return serializeResponse(response)
|
|
261
|
+
}
|
|
262
|
+
if (operation === 'do.rpc') {
|
|
263
|
+
const [, serializedId, methodName, args] = params
|
|
264
|
+
const id = binding.idFromString(serializedId.hex)
|
|
265
|
+
const stub = binding.get(id)
|
|
266
|
+
const response = await stub.fetch(new Request('http://do/_rpc', {
|
|
267
|
+
method: 'POST',
|
|
268
|
+
headers: { 'Content-Type': 'application/json' },
|
|
269
|
+
body: JSON.stringify({ method: methodName, params: args })
|
|
270
|
+
}))
|
|
271
|
+
const result = await response.json()
|
|
272
|
+
if (!result.ok) throw new Error(result.error?.message || 'RPC failed')
|
|
273
|
+
return result.result
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Queues
|
|
277
|
+
if (operation === 'queue.send') return binding.send(params[0], params[1])
|
|
278
|
+
if (operation === 'queue.sendBatch') return binding.sendBatch(params[0], params[1])
|
|
279
|
+
|
|
280
|
+
// Send Email
|
|
281
|
+
if (operation === 'email.send') {
|
|
282
|
+
if (binding && typeof binding.send === 'function') {
|
|
283
|
+
const message = params[0]
|
|
284
|
+
if (message && typeof message === 'object' && 'from' in message && 'to' in message && 'raw' in message) {
|
|
285
|
+
return binding.send({
|
|
286
|
+
from: message.from,
|
|
287
|
+
to: message.to,
|
|
288
|
+
[RAW_EMAIL]: createEmailMessageRaw(message.raw)
|
|
289
|
+
})
|
|
290
|
+
}
|
|
291
|
+
return binding.send(message)
|
|
292
|
+
}
|
|
293
|
+
return { ok: true, simulated: true }
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// AI / generic run()
|
|
297
|
+
if (operation === 'ai.run') {
|
|
298
|
+
if (typeof binding.run !== 'function') {
|
|
299
|
+
throw new Error('Binding ' + bindingName + ' does not support run(): ' + method)
|
|
300
|
+
}
|
|
301
|
+
return binding.run(params[0], params[1])
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
throw new Error('Unknown operation: ' + method)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// ---------------------------------------------------------------------------
|
|
308
|
+
// WebSocket bridge (shared with src/bridge/server.ts in shape)
|
|
309
|
+
// ---------------------------------------------------------------------------
|
|
310
|
+
// NOTE: wsProxies is intentionally created per handleBridgeWebSocket call so
|
|
311
|
+
// state never leaks across connections or across gateway-script regenerations.
|
|
312
|
+
|
|
313
|
+
async function handleBridgeRpcCall(msg, ws, env, ctx) {
|
|
314
|
+
try {
|
|
315
|
+
const result = await executeRpcMethod(msg.method, msg.params, env, ctx)
|
|
316
|
+
ws.send(JSON.stringify({ t: 'rpc.ok', id: msg.id, result }))
|
|
317
|
+
} catch (error) {
|
|
318
|
+
ws.send(JSON.stringify({
|
|
319
|
+
t: 'rpc.err',
|
|
320
|
+
id: msg.id,
|
|
321
|
+
error: {
|
|
322
|
+
code: error?.code || 'INTERNAL_ERROR',
|
|
323
|
+
message: error?.message || String(error)
|
|
324
|
+
}
|
|
325
|
+
}))
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
async function handleBridgeWsOpen(msg, ws, env, wsProxies) {
|
|
330
|
+
try {
|
|
331
|
+
const binding = env[msg.target.binding]
|
|
332
|
+
const id = binding.idFromString(msg.target.id)
|
|
333
|
+
const stub = binding.get(id)
|
|
334
|
+
|
|
335
|
+
const headers = new Headers(msg.target.headers || [])
|
|
336
|
+
headers.set('Upgrade', 'websocket')
|
|
337
|
+
|
|
338
|
+
const response = await stub.fetch(new Request(msg.target.url, { method: 'GET', headers }))
|
|
339
|
+
const doWs = response.webSocket
|
|
340
|
+
|
|
341
|
+
if (!doWs) {
|
|
342
|
+
ws.send(JSON.stringify({
|
|
343
|
+
t: 'rpc.err',
|
|
344
|
+
id: 'ws_' + msg.wid,
|
|
345
|
+
error: { code: 'WS_FAILED', message: 'No WebSocket returned' }
|
|
346
|
+
}))
|
|
347
|
+
return
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
doWs.accept()
|
|
351
|
+
wsProxies.set(msg.wid, { doWs })
|
|
352
|
+
|
|
353
|
+
doWs.addEventListener('message', (event) => {
|
|
354
|
+
const isText = typeof event.data === 'string'
|
|
355
|
+
const data = isText ? event.data : arrayBufferToBase64(event.data)
|
|
356
|
+
ws.send(JSON.stringify({ t: 'ws.data', wid: msg.wid, data, isText }))
|
|
357
|
+
})
|
|
358
|
+
|
|
359
|
+
doWs.addEventListener('close', (event) => {
|
|
360
|
+
ws.send(JSON.stringify({ t: 'ws.close', wid: msg.wid, code: event.code, reason: event.reason }))
|
|
361
|
+
wsProxies.delete(msg.wid)
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
ws.send(JSON.stringify({ t: 'ws.opened', wid: msg.wid }))
|
|
365
|
+
} catch (error) {
|
|
366
|
+
ws.send(JSON.stringify({
|
|
367
|
+
t: 'rpc.err',
|
|
368
|
+
id: 'ws_' + msg.wid,
|
|
369
|
+
error: { code: 'WS_FAILED', message: error.message }
|
|
370
|
+
}))
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function handleBridgeWsClose(msg, wsProxies) {
|
|
375
|
+
const proxy = wsProxies.get(msg.wid)
|
|
376
|
+
if (proxy) {
|
|
377
|
+
proxy.doWs.close(msg.code, msg.reason)
|
|
378
|
+
wsProxies.delete(msg.wid)
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
async function handleBridgeJsonMessage(data, ws, env, ctx, wsProxies) {
|
|
383
|
+
const msg = JSON.parse(data)
|
|
384
|
+
switch (msg.t) {
|
|
385
|
+
case 'hello':
|
|
386
|
+
// v2 handshake — acknowledge with welcome echoing the negotiated
|
|
387
|
+
// capability intersection. Capabilities advertised by the gateway
|
|
388
|
+
// are kept in sync with src/bridge/client.ts (BRIDGE_CLIENT_CAPABILITIES).
|
|
389
|
+
ws.send(JSON.stringify({
|
|
390
|
+
t: 'welcome',
|
|
391
|
+
protocolVersion: 2,
|
|
392
|
+
capabilities: ['streams', 'ws-relay', 'http-transfer']
|
|
393
|
+
.filter((c) => Array.isArray(msg.capabilities) && msg.capabilities.includes(c))
|
|
394
|
+
.sort()
|
|
395
|
+
}))
|
|
396
|
+
break
|
|
397
|
+
case 'rpc.call':
|
|
398
|
+
await handleBridgeRpcCall(msg, ws, env, ctx)
|
|
399
|
+
break
|
|
400
|
+
case 'ws.open':
|
|
401
|
+
await handleBridgeWsOpen(msg, ws, env, wsProxies)
|
|
402
|
+
break
|
|
403
|
+
case 'ws.close':
|
|
404
|
+
handleBridgeWsClose(msg, wsProxies)
|
|
405
|
+
break
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function handleBridgeWebSocket(request, env, ctx) {
|
|
410
|
+
const { 0: client, 1: server } = new WebSocketPair()
|
|
411
|
+
server.accept()
|
|
412
|
+
|
|
413
|
+
// Per-connection state: recreated for every bridge client so reloads and
|
|
414
|
+
// concurrent clients never share WS proxy entries.
|
|
415
|
+
const wsProxies = new Map()
|
|
416
|
+
|
|
417
|
+
server.addEventListener('message', async (event) => {
|
|
418
|
+
try {
|
|
419
|
+
if (typeof event.data === 'string') {
|
|
420
|
+
await handleBridgeJsonMessage(event.data, server, env, ctx, wsProxies)
|
|
421
|
+
}
|
|
422
|
+
} catch (error) {
|
|
423
|
+
console.error('[Gateway] Error:', error)
|
|
424
|
+
}
|
|
425
|
+
})
|
|
426
|
+
|
|
427
|
+
server.addEventListener('close', () => {
|
|
428
|
+
for (const proxy of wsProxies.values()) {
|
|
429
|
+
// Best-effort cleanup: the DO-side WS may already be closed or in an
|
|
430
|
+
// invalid state; any throw here would abort sibling closes. Surface
|
|
431
|
+
// the swallowed error when DEVFLARE_DEBUG_BRIDGE is enabled.
|
|
432
|
+
try { proxy.doWs.close() } catch (error) {
|
|
433
|
+
if (globalThis.DEVFLARE_DEBUG_BRIDGE) {
|
|
434
|
+
console.warn('[devflare:bridge] proxy.doWs.close() failed', error)
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
wsProxies.clear()
|
|
439
|
+
})
|
|
440
|
+
|
|
441
|
+
return new Response(null, { status: 101, webSocket: client })
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// ---------------------------------------------------------------------------
|
|
445
|
+
// HTTP transfer for R2 bodies (shared with src/bridge/server.ts in shape)
|
|
446
|
+
// ---------------------------------------------------------------------------
|
|
447
|
+
|
|
448
|
+
async function handleHttpTransfer(request, env, url) {
|
|
449
|
+
const transferIdEncoded = url.pathname.split('/').pop()
|
|
450
|
+
const transferId = decodeURIComponent(transferIdEncoded || '')
|
|
451
|
+
const [binding, ...keyParts] = transferId.split(':')
|
|
452
|
+
const key = keyParts.join(':')
|
|
453
|
+
const bucket = env[binding]
|
|
454
|
+
|
|
455
|
+
if (!bucket) return new Response('Bucket not found: ' + binding, { status: 404 })
|
|
456
|
+
|
|
457
|
+
if (request.method === 'PUT' || request.method === 'POST') {
|
|
458
|
+
const result = await bucket.put(key, request.body)
|
|
459
|
+
return new Response(JSON.stringify(serializeR2Object(result)), {
|
|
460
|
+
headers: { 'Content-Type': 'application/json' }
|
|
461
|
+
})
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
if (request.method === 'GET') {
|
|
465
|
+
const object = await bucket.get(key)
|
|
466
|
+
if (!object) return new Response('Not found', { status: 404 })
|
|
467
|
+
return new Response(object.body, {
|
|
468
|
+
headers: {
|
|
469
|
+
'Content-Type': object.httpMetadata?.contentType || 'application/octet-stream',
|
|
470
|
+
'Content-Length': String(object.size)
|
|
471
|
+
}
|
|
472
|
+
})
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
return new Response('Method not allowed', { status: 405 })
|
|
476
|
+
}
|
|
477
|
+
`;
|
|
478
|
+
|
|
479
|
+
// src/bridge/miniflare.ts
|
|
480
|
+
function isIgnorableMiniflareDisposeError(error) {
|
|
481
|
+
if (!(error instanceof Error)) {
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
484
|
+
const details = error;
|
|
485
|
+
return details.code === "EBADF" && details.syscall === "kill";
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
export { resolveMiniflareLogLevel, createCompatibilityAwareMiniflareLog, GATEWAY_RUNTIME_JS, isIgnorableMiniflareDisposeError };
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveConfigForEnvironment
|
|
3
|
+
} from "./index-w4c9vmvg.js";
|
|
4
|
+
|
|
5
|
+
// src/cli/commands/previews-support/family.ts
|
|
6
|
+
function compareConfiguredWorkerFamilies(left, right) {
|
|
7
|
+
if (left.role === "primary" && right.role !== "primary") {
|
|
8
|
+
return -1;
|
|
9
|
+
}
|
|
10
|
+
if (left.role !== "primary" && right.role === "primary") {
|
|
11
|
+
return 1;
|
|
12
|
+
}
|
|
13
|
+
return left.baseName.localeCompare(right.baseName);
|
|
14
|
+
}
|
|
15
|
+
function comparePreviewScopeRows(left, right) {
|
|
16
|
+
const leftTime = left.updatedAt?.getTime() ?? 0;
|
|
17
|
+
const rightTime = right.updatedAt?.getTime() ?? 0;
|
|
18
|
+
if (rightTime !== leftTime) {
|
|
19
|
+
return rightTime - leftTime;
|
|
20
|
+
}
|
|
21
|
+
return left.scope.localeCompare(right.scope);
|
|
22
|
+
}
|
|
23
|
+
function collectConfiguredWorkerFamilies(config, environment) {
|
|
24
|
+
const resolvedConfig = resolveConfigForEnvironment(config, environment);
|
|
25
|
+
const families = new Map;
|
|
26
|
+
families.set(resolvedConfig.name, {
|
|
27
|
+
baseName: resolvedConfig.name,
|
|
28
|
+
roleLabel: "primary",
|
|
29
|
+
role: "primary"
|
|
30
|
+
});
|
|
31
|
+
for (const [bindingName, binding] of Object.entries(resolvedConfig.bindings?.services ?? {})) {
|
|
32
|
+
const existing = families.get(binding.service);
|
|
33
|
+
if (existing) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
families.set(binding.service, {
|
|
37
|
+
baseName: binding.service,
|
|
38
|
+
roleLabel: bindingName,
|
|
39
|
+
role: "service"
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return Array.from(families.values()).sort(compareConfiguredWorkerFamilies);
|
|
43
|
+
}
|
|
44
|
+
function getWorkerUrl(workerName, workersSubdomain) {
|
|
45
|
+
if (!workersSubdomain) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
return `https://${workerName}.${workersSubdomain}.workers.dev`;
|
|
49
|
+
}
|
|
50
|
+
function getWorkerScopeSuffix(workerName, baseName) {
|
|
51
|
+
if (!workerName.startsWith(`${baseName}-`)) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const suffix = workerName.slice(baseName.length + 1).trim();
|
|
55
|
+
return suffix || undefined;
|
|
56
|
+
}
|
|
57
|
+
function buildStableWorkerRowsFromLiveWorkers(families, workers, workersSubdomain) {
|
|
58
|
+
const workersByName = new Map(workers.map((worker) => [worker.name, worker]));
|
|
59
|
+
return families.map((family) => {
|
|
60
|
+
const worker = workersByName.get(family.baseName);
|
|
61
|
+
const status = worker ? "active" : "missing";
|
|
62
|
+
return {
|
|
63
|
+
workerName: family.baseName,
|
|
64
|
+
role: family.roleLabel,
|
|
65
|
+
status,
|
|
66
|
+
updatedAt: worker?.modifiedOn,
|
|
67
|
+
url: worker ? getWorkerUrl(family.baseName, workersSubdomain) : undefined
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function getDedicatedPreviewFamilyNamesFromWorkers(families, workers) {
|
|
72
|
+
const familyNames = new Set;
|
|
73
|
+
const workerNames = workers.map((worker) => worker.name);
|
|
74
|
+
for (const family of families) {
|
|
75
|
+
if (family.role === "primary") {
|
|
76
|
+
familyNames.add(family.baseName);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (workerNames.some((workerName) => Boolean(getWorkerScopeSuffix(workerName, family.baseName)))) {
|
|
80
|
+
familyNames.add(family.baseName);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return familyNames;
|
|
84
|
+
}
|
|
85
|
+
function buildPreviewScopeRowsFromLiveWorkers(families, workers, workersSubdomain) {
|
|
86
|
+
const workersByName = new Map(workers.map((worker) => [worker.name, worker]));
|
|
87
|
+
const previewFamilyNames = getDedicatedPreviewFamilyNamesFromWorkers(families, workers);
|
|
88
|
+
const expectedFamilies = families.filter((family) => previewFamilyNames.has(family.baseName));
|
|
89
|
+
const workerCandidatesByScope = buildPreviewWorkerCandidatesByScope(families, workers);
|
|
90
|
+
return Array.from(workerCandidatesByScope.keys()).map((scope) => {
|
|
91
|
+
const resolvedFamilies = expectedFamilies.map((family) => ({
|
|
92
|
+
family,
|
|
93
|
+
worker: workersByName.get(`${family.baseName}-${scope}`)
|
|
94
|
+
}));
|
|
95
|
+
const presentFamilies = resolvedFamilies.filter((entry) => entry.worker);
|
|
96
|
+
const updatedAt = presentFamilies.reduce((latest, entry) => {
|
|
97
|
+
const currentDate = entry.worker?.modifiedOn;
|
|
98
|
+
if (!currentDate) {
|
|
99
|
+
return latest;
|
|
100
|
+
}
|
|
101
|
+
if (!latest || currentDate.getTime() > latest.getTime()) {
|
|
102
|
+
return currentDate;
|
|
103
|
+
}
|
|
104
|
+
return latest;
|
|
105
|
+
}, undefined);
|
|
106
|
+
const primaryEntry = resolvedFamilies.find((entry) => entry.family.role === "primary");
|
|
107
|
+
const entryWorker = primaryEntry?.worker ?? presentFamilies[0]?.worker;
|
|
108
|
+
const missingLabels = resolvedFamilies.filter((entry) => !entry.worker).map((entry) => entry.family.role === "primary" ? "primary" : entry.family.roleLabel);
|
|
109
|
+
const notes = [];
|
|
110
|
+
if (missingLabels.length > 0) {
|
|
111
|
+
notes.push(`missing ${missingLabels.join(", ")}`);
|
|
112
|
+
}
|
|
113
|
+
const strategy = "dedicated workers";
|
|
114
|
+
const status = presentFamilies.length === resolvedFamilies.length ? "ready" : "partial";
|
|
115
|
+
return {
|
|
116
|
+
scope,
|
|
117
|
+
strategy,
|
|
118
|
+
workersLabel: `${presentFamilies.length}/${resolvedFamilies.length}`,
|
|
119
|
+
status,
|
|
120
|
+
updatedAt,
|
|
121
|
+
notes: notes.length > 0 ? notes.join(" · ") : undefined,
|
|
122
|
+
entryUrl: entryWorker ? getWorkerUrl(entryWorker.name, workersSubdomain) : undefined
|
|
123
|
+
};
|
|
124
|
+
}).sort(comparePreviewScopeRows);
|
|
125
|
+
}
|
|
126
|
+
function buildPreviewWorkerCandidatesByScope(families, workers) {
|
|
127
|
+
const candidates = new Map;
|
|
128
|
+
for (const worker of workers) {
|
|
129
|
+
for (const family of families) {
|
|
130
|
+
const scope = getWorkerScopeSuffix(worker.name, family.baseName);
|
|
131
|
+
if (!scope) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const names = candidates.get(scope) ?? new Set;
|
|
135
|
+
names.add(worker.name);
|
|
136
|
+
candidates.set(scope, names);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return new Map(Array.from(candidates.entries()).map(([scope, workerNames]) => {
|
|
140
|
+
return [scope, Array.from(workerNames).sort((left, right) => left.localeCompare(right))];
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
function orderPreviewWorkerNamesForDeletion(workerNames, scope, families) {
|
|
144
|
+
const familyPriority = new Map;
|
|
145
|
+
for (const family of families) {
|
|
146
|
+
familyPriority.set(family.baseName, {
|
|
147
|
+
priority: family.role === "primary" ? 0 : 1,
|
|
148
|
+
roleLabel: family.roleLabel
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
const resolveFamilyForWorker = (workerName) => {
|
|
152
|
+
for (const family of families) {
|
|
153
|
+
if (getWorkerScopeSuffix(workerName, family.baseName) === scope) {
|
|
154
|
+
const resolved = familyPriority.get(family.baseName);
|
|
155
|
+
if (resolved) {
|
|
156
|
+
return {
|
|
157
|
+
priority: resolved.priority,
|
|
158
|
+
roleLabel: resolved.roleLabel,
|
|
159
|
+
baseName: family.baseName
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
priority: 2,
|
|
166
|
+
roleLabel: workerName
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
return [...workerNames].sort((left, right) => {
|
|
170
|
+
const leftFamily = resolveFamilyForWorker(left);
|
|
171
|
+
const rightFamily = resolveFamilyForWorker(right);
|
|
172
|
+
if (leftFamily.priority !== rightFamily.priority) {
|
|
173
|
+
return leftFamily.priority - rightFamily.priority;
|
|
174
|
+
}
|
|
175
|
+
if (leftFamily.roleLabel !== rightFamily.roleLabel) {
|
|
176
|
+
return leftFamily.roleLabel.localeCompare(rightFamily.roleLabel);
|
|
177
|
+
}
|
|
178
|
+
if (leftFamily.baseName && rightFamily.baseName && leftFamily.baseName !== rightFamily.baseName) {
|
|
179
|
+
return leftFamily.baseName.localeCompare(rightFamily.baseName);
|
|
180
|
+
}
|
|
181
|
+
return left.localeCompare(right);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export { collectConfiguredWorkerFamilies, buildStableWorkerRowsFromLiveWorkers, buildPreviewScopeRowsFromLiveWorkers, buildPreviewWorkerCandidatesByScope, orderPreviewWorkerNamesForDeletion };
|