devflare 1.0.0-next.39 → 1.0.0-next.40
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/_chunks/account-BtWcv3X9.js +462 -0
- package/dist/_chunks/account-resources-CsmVowJp.js +159 -0
- package/dist/_chunks/ai-CBEuLdoP.js +322 -0
- package/dist/_chunks/api-TzdliH-6.js +568 -0
- package/dist/_chunks/build-3T6O4uIg.js +24 -0
- package/dist/_chunks/build-artifacts-8TqBSQkG.js +483 -0
- package/dist/_chunks/cli-BTF1X4SG.js +1128 -0
- package/dist/_chunks/cloudflare-BaloqI3H.js +157 -0
- package/dist/_chunks/colors-DiK6wPJ5.js +13 -0
- package/dist/_chunks/command-utils-BsfkmTqh.js +45 -0
- package/dist/_chunks/compiler-uoyAQ8zW.js +424 -0
- package/dist/_chunks/config-D5u-bEkn.js +78 -0
- package/dist/_chunks/config-path-DCPto4XB.js +42 -0
- package/dist/_chunks/context-CX50Y2Kb.js +2250 -0
- package/dist/_chunks/decorators-QmV57ixr.js +19 -0
- package/dist/_chunks/dependencies-C2oxFjU_.js +57 -0
- package/dist/_chunks/deploy-DMTr6JeR.js +915 -0
- package/dist/_chunks/dev-CvRHmRFZ.js +3456 -0
- package/dist/_chunks/doctor-DIG8DoFU.js +219 -0
- package/dist/_chunks/durable-object-DMtH0XYX.js +234 -0
- package/dist/_chunks/env-S0_nMVz1.js +125 -0
- package/dist/_chunks/family-DXC5SdFK.js +143 -0
- package/dist/_chunks/generated-artifacts-dMJY4KAt.js +32 -0
- package/dist/_chunks/glob-CmQOvunB.js +56 -0
- package/dist/_chunks/init-3moXTgpb.js +165 -0
- package/dist/_chunks/loader-DLXO60RO.js +1153 -0
- package/dist/_chunks/local-dev-vars-CTSa-wvF.js +81 -0
- package/dist/_chunks/local-hyperdrive-CJ90j46O.js +119 -0
- package/dist/_chunks/local-media-bindings-DsAW4AMF.js +335 -0
- package/dist/_chunks/local-secrets-DMmEOygL.js +123 -0
- package/dist/_chunks/local-workflow-entrypoints-Wip3o1u8.js +90 -0
- package/dist/_chunks/login-BmnDzDlH.js +51 -0
- package/dist/_chunks/package-metadata-DAuCkyvK.js +39 -0
- package/dist/_chunks/preferences-BKp_7XJx.js +241 -0
- package/dist/_chunks/preview-BhqDmq8I.js +456 -0
- package/dist/_chunks/preview-registry-ClAbLTHH.js +1186 -0
- package/dist/_chunks/preview-resources-DdXj8LMM.js +358 -0
- package/dist/_chunks/previews-Dlr13x5M.js +1134 -0
- package/dist/_chunks/productions-D3AnOHac.js +411 -0
- package/dist/_chunks/ref-CYJNAAe_.js +178 -0
- package/dist/_chunks/remote-CZnP-HLJ.js +79 -0
- package/dist/_chunks/remote-config-D39BY9ji.js +132 -0
- package/dist/_chunks/resolve-package-Y84HB3Nt.js +133 -0
- package/dist/_chunks/rolldown-runtime-CvQ6eiug.js +14 -0
- package/dist/_chunks/routes-C3FqES2W.js +796 -0
- package/dist/_chunks/runtime-FvXvfuZ2.js +550 -0
- package/dist/_chunks/schema-normalization-DWVleVxo.js +477 -0
- package/dist/_chunks/secrets-70eN0Q6C.js +95 -0
- package/dist/_chunks/token-kguIDmej.js +333 -0
- package/dist/_chunks/tokens-iVcgNXi-.js +221 -0
- package/dist/_chunks/types-OrLbzv4I.js +476 -0
- package/dist/_chunks/ui-BUoZApvE.js +103 -0
- package/dist/_chunks/usage-BBTGzjon.js +272 -0
- package/dist/_chunks/vite-CsI0E-uV.js +1235 -0
- package/dist/_chunks/vite-utils-OVLMV605.js +183 -0
- package/dist/_chunks/worker-CS1jgNFE.js +410 -0
- package/dist/_chunks/worker-bundler-dTTnYU3n.js +458 -0
- package/dist/_chunks/worker-entrypoint-CQW77lG8.js +247 -0
- package/dist/_chunks/workerName-CFJsLZA-.js +23 -0
- package/dist/bridge/index.d.ts +6 -6
- package/dist/bridge/miniflare.d.ts +2 -2
- package/dist/bridge/proxy.d.ts +1 -1
- package/dist/bridge/v2/body-streams.d.ts +1 -1
- package/dist/bridge/v2/codec.d.ts +4 -4
- package/dist/bridge/v2/index.d.ts +10 -10
- package/dist/bridge/v2/serialization.d.ts +1 -1
- package/dist/bridge/v2/value-codec.d.ts +1 -1
- package/dist/bridge/v2/value-serialization.d.ts.map +1 -1
- package/dist/bridge/v2/ws-relay.d.ts +3 -3
- package/dist/browser-shim/index.d.ts +2 -2
- package/dist/browser.d.ts +70 -70
- package/dist/browser.js +74 -2462
- package/dist/bundler/do-bundler.d.ts +1 -1
- package/dist/bundler/index.d.ts +3 -3
- package/dist/bundler/rolldown-shared.d.ts +1 -1
- package/dist/bundler/worker-bundler.d.ts +1 -1
- package/dist/cli/build-manifest.d.ts +1 -1
- package/dist/cli/command-utils.d.ts +1 -1
- package/dist/cli/commands/account.d.ts +1 -1
- package/dist/cli/commands/ai.d.ts +1 -1
- package/dist/cli/commands/build-artifacts.d.ts +5 -5
- package/dist/cli/commands/build.d.ts +1 -1
- package/dist/cli/commands/config.d.ts +1 -1
- package/dist/cli/commands/deploy/prepare.d.ts +2 -2
- package/dist/cli/commands/deploy/runtime.d.ts +1 -1
- package/dist/cli/commands/deploy/verification.d.ts +1 -1
- package/dist/cli/commands/deploy.d.ts +1 -1
- package/dist/cli/commands/dev.d.ts +1 -1
- package/dist/cli/commands/doctor.d.ts +1 -1
- package/dist/cli/commands/init.d.ts +1 -1
- package/dist/cli/commands/login.d.ts +1 -1
- package/dist/cli/commands/previews-support/cleanup.d.ts +1 -1
- package/dist/cli/commands/previews-support/family.d.ts +3 -3
- package/dist/cli/commands/previews-support/render.d.ts +3 -3
- package/dist/cli/commands/previews-support/theme.d.ts +2 -2
- package/dist/cli/commands/previews-support/types.d.ts +2 -2
- package/dist/cli/commands/previews.d.ts +1 -1
- package/dist/cli/commands/productions.d.ts +1 -1
- package/dist/cli/commands/remote.d.ts +1 -1
- package/dist/cli/commands/secrets.d.ts +1 -1
- package/dist/cli/commands/token.d.ts +1 -1
- package/dist/cli/commands/type-generation/discovery.d.ts +2 -2
- package/dist/cli/commands/type-generation/generator.d.ts +3 -3
- package/dist/cli/commands/type-generation/models.d.ts +1 -1
- package/dist/cli/commands/types.d.ts +1 -1
- package/dist/cli/commands/worker.d.ts +1 -1
- package/dist/cli/deploy-strategy.d.ts +1 -1
- package/dist/cli/deploy-target.d.ts +1 -1
- package/dist/cli/help-pages/pages/account.d.ts +1 -1
- package/dist/cli/help-pages/pages/core.d.ts +1 -1
- package/dist/cli/help-pages/pages/index.d.ts +1 -1
- package/dist/cli/help-pages/pages/misc.d.ts +1 -1
- package/dist/cli/help-pages/pages/previews.d.ts +1 -1
- package/dist/cli/help-pages/pages/productions.d.ts +1 -1
- package/dist/cli/help-pages/render.d.ts +2 -2
- package/dist/cli/help-pages/shared.d.ts +1 -1
- package/dist/cli/help.d.ts +2 -2
- package/dist/cli/index.js +2 -1383
- package/dist/cli/preview-bindings.d.ts +3 -3
- package/dist/cli/preview.d.ts +1 -1
- package/dist/cli/wrangler-auth.d.ts +1 -1
- package/dist/cloudflare/account-core.d.ts +2 -2
- package/dist/cloudflare/account-resources.d.ts +2 -2
- package/dist/cloudflare/account-status.d.ts +1 -1
- package/dist/cloudflare/account-workers.d.ts +2 -2
- package/dist/cloudflare/account.d.ts +7 -7
- package/dist/cloudflare/auth.d.ts +1 -1
- package/dist/cloudflare/index.d.ts +13 -13
- package/dist/cloudflare/index.js +4 -59
- package/dist/cloudflare/kv-namespace.d.ts +1 -1
- package/dist/cloudflare/preview-registry-cache.d.ts +1 -1
- package/dist/cloudflare/preview-registry-inference.d.ts +2 -2
- package/dist/cloudflare/preview-registry-records.d.ts +3 -3
- package/dist/cloudflare/preview-registry-shape.d.ts +2 -2
- package/dist/cloudflare/preview-registry-store.d.ts +3 -3
- package/dist/cloudflare/preview-registry-transport.d.ts +2 -2
- package/dist/cloudflare/preview-registry-types.d.ts +2 -2
- package/dist/cloudflare/preview-registry.d.ts +5 -5
- package/dist/cloudflare/tokens.d.ts +2 -2
- package/dist/cloudflare/usage.d.ts +2 -2
- package/dist/config/binding-resolution-helpers.d.ts +1 -1
- package/dist/config/compiler/bindings.d.ts +2 -2
- package/dist/config/compiler/core-helpers.d.ts +2 -2
- package/dist/config/compiler/do-workers.d.ts +2 -2
- package/dist/config/compiler/paths.d.ts +1 -1
- package/dist/config/compiler.d.ts +6 -6
- package/dist/config/define.d.ts +2 -2
- package/dist/config/deploy-resources.d.ts +5 -5
- package/dist/config/env-vars.d.ts +1 -1
- package/dist/config/framework-providers.d.ts +1 -1
- package/dist/config/index.d.ts +12 -12
- package/dist/config/loader.d.ts +2 -2
- package/dist/config/local-dev-vars.d.ts +1 -1
- package/dist/config/preview-resources.d.ts +4 -4
- package/dist/config/preview.d.ts +1 -1
- package/dist/config/ref.d.ts +2 -2
- package/dist/config/resolve-phased.d.ts +4 -4
- package/dist/config/resolve.d.ts +1 -1
- package/dist/config/resource-resolution.d.ts +6 -6
- package/dist/config/schema-env.d.ts +20 -20
- package/dist/config/schema-normalization.d.ts +1 -1
- package/dist/config/schema-types-bindings.d.ts +4 -4
- package/dist/config/schema-types-build.d.ts +1 -1
- package/dist/config/schema-types.d.ts +7 -7
- package/dist/config/schema.d.ts +46 -46
- package/dist/config/service-bindings-validation.d.ts +1 -1
- package/dist/config-entry.d.ts +6 -6
- package/dist/config-entry.js +3 -8
- package/dist/decorators/index.d.ts +2 -2
- package/dist/decorators/index.js +2 -9
- package/dist/dev-server/d1-migrations.d.ts +1 -1
- package/dist/dev-server/dev-server-state.d.ts +6 -6
- package/dist/dev-server/gateway-script.d.ts +1 -1
- package/dist/dev-server/index.d.ts +1 -1
- package/dist/dev-server/miniflare-bindings.d.ts +1 -1
- package/dist/dev-server/miniflare-dev-config.d.ts +5 -5
- package/dist/dev-server/miniflare-worker-config.d.ts +3 -3
- package/dist/dev-server/server-startup-helpers.d.ts +6 -6
- package/dist/dev-server/worker-surface-paths.d.ts +2 -2
- package/dist/index.d.ts +8 -8
- package/dist/index.js +9 -22
- package/dist/runtime/context-events.d.ts +1 -1
- package/dist/runtime/context.d.ts +3 -3
- package/dist/runtime/exports.d.ts +2 -2
- package/dist/runtime/index.d.ts +10 -10
- package/dist/runtime/index.js +5 -57
- package/dist/runtime/middleware.d.ts +1 -1
- package/dist/runtime/router/index.d.ts +3 -3
- package/dist/runtime/validation.d.ts +1 -1
- package/dist/secrets/local-secrets.d.ts +1 -1
- package/dist/shims/local-media-bindings.d.ts +1 -1
- package/dist/sveltekit/index.d.ts +1 -1
- package/dist/sveltekit/index.js +327 -9
- package/dist/sveltekit/local-bindings.d.ts +1 -1
- package/dist/sveltekit/platform.d.ts +1 -1
- package/dist/test/binding-hints.d.ts +2 -2
- package/dist/test/cf.d.ts +19 -19
- package/dist/test/index.d.ts +18 -18
- package/dist/test/index.js +4495 -46
- package/dist/test/offline-bindings.d.ts +3 -3
- package/dist/test/resolve-service-bindings.d.ts +1 -1
- package/dist/test/simple-context-bindings.d.ts +1 -1
- package/dist/test/simple-context-durable-objects.d.ts +1 -1
- package/dist/test/simple-context-env.d.ts +2 -2
- package/dist/test/simple-context-handlers.d.ts +2 -2
- package/dist/test/simple-context-lifecycle.d.ts +2 -2
- package/dist/test/simple-context-mfconfig.d.ts +1 -1
- package/dist/test/simple-context-multi-worker.d.ts +2 -2
- package/dist/test/simple-context-runtime.d.ts +1 -1
- package/dist/test/simple-context-startup.d.ts +1 -1
- package/dist/test/simple-context.d.ts +1 -1
- package/dist/test/utilities/env.d.ts +3 -3
- package/dist/test/utilities.d.ts +10 -10
- package/dist/test/worker.d.ts +1 -1
- package/dist/transform/index.d.ts +2 -2
- package/dist/utils/send-email.js +163 -19
- package/dist/vite/config-file.d.ts +2 -2
- package/dist/vite/index.d.ts +3 -3
- package/dist/vite/index.js +2 -31
- package/dist/vite/plugin-config-hook.d.ts +1 -1
- package/dist/vite/plugin-context.d.ts +3 -3
- package/dist/vite/plugin-durable-objects.d.ts +2 -2
- package/dist/vite/plugin-programmatic.d.ts +1 -1
- package/dist/vite/plugin-service-bindings.d.ts +2 -2
- package/dist/vite/plugin.d.ts +3 -3
- package/dist/worker-entry/composed-worker.d.ts +1 -1
- package/dist/worker-entry/routes.d.ts +2 -2
- package/dist/worker-entry/surface-paths.d.ts +1 -1
- package/dist/workflows/local-workflow-entrypoints.d.ts +1 -1
- package/package.json +5 -3
- package/dist/account-4tgh03a8.js +0 -484
- package/dist/ai-r3zqmxan.js +0 -261
- package/dist/api-6z01z734.js +0 -33
- package/dist/build-kw625v84.js +0 -51
- package/dist/config-ghk2bxj3.js +0 -102
- package/dist/deploy-9kee65n9.js +0 -1062
- package/dist/dev-x8zr249a.js +0 -3569
- package/dist/doctor-0ng5qrr1.js +0 -258
- package/dist/durable-object-0ybmg08a.js +0 -13
- package/dist/index-04wh9bxx.js +0 -514
- package/dist/index-0cc05hzv.js +0 -74
- package/dist/index-2yv7w548.js +0 -185
- package/dist/index-37x76zdn.js +0 -4
- package/dist/index-3cpzsr47.js +0 -125
- package/dist/index-3t6rypgc.js +0 -13
- package/dist/index-4mmpccrb.js +0 -309
- package/dist/index-5dkjffqz.js +0 -25
- package/dist/index-5hy7jmv3.js +0 -890
- package/dist/index-627srx16.js +0 -45
- package/dist/index-7m557715.js +0 -283
- package/dist/index-a8pnvg3r.js +0 -52
- package/dist/index-aabgympv.js +0 -39
- package/dist/index-atwc3csp.js +0 -256
- package/dist/index-cv4cvrxe.js +0 -2046
- package/dist/index-h7r11y4a.js +0 -539
- package/dist/index-hvtd936d.js +0 -1229
- package/dist/index-kcp7y951.js +0 -136
- package/dist/index-maw0jjnn.js +0 -147
- package/dist/index-mek9msfv.js +0 -705
- package/dist/index-n4xkaymm.js +0 -236
- package/dist/index-nkk59p3y.js +0 -579
- package/dist/index-phcrvs6d.js +0 -342
- package/dist/index-se4kw8tm.js +0 -460
- package/dist/index-x8s9rwfh.js +0 -2020
- package/dist/index-y7w3x9p1.js +0 -18
- package/dist/index-z9gy8w6b.js +0 -57
- package/dist/index-zdd0d9qa.js +0 -199
- package/dist/init-tb8jqgvr.js +0 -180
- package/dist/login-4h1sfsed.js +0 -75
- package/dist/previews-qr7c5j8h.js +0 -1336
- package/dist/productions-xpmd6bw8.js +0 -505
- package/dist/remote-kqcvhnfx.js +0 -192
- package/dist/secrets-6wbdsdek.js +0 -89
- package/dist/token-yp1qa70y.js +0 -419
- package/dist/types-15yv4cj3.js +0 -701
- package/dist/worker-1yg72jxg.js +0 -510
- package/dist/worker-entrypoint-y8s9kdcx.js +0 -15
package/dist/index-cv4cvrxe.js
DELETED
|
@@ -1,2046 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
discoverEntrypointsSync,
|
|
3
|
-
resolvePackageSpecifier
|
|
4
|
-
} from "./index-3cpzsr47.js";
|
|
5
|
-
import {
|
|
6
|
-
DEFAULT_DO_PATTERN,
|
|
7
|
-
findFiles,
|
|
8
|
-
findFilesSync
|
|
9
|
-
} from "./index-5dkjffqz.js";
|
|
10
|
-
import {
|
|
11
|
-
compileBuildConfig,
|
|
12
|
-
compileConfig,
|
|
13
|
-
compileToProgrammaticConfig,
|
|
14
|
-
isolateViteBuildOutputPaths,
|
|
15
|
-
rebaseWranglerConfigPaths,
|
|
16
|
-
writeWranglerConfig
|
|
17
|
-
} from "./index-mek9msfv.js";
|
|
18
|
-
import {
|
|
19
|
-
configSchema,
|
|
20
|
-
getLocalD1DatabaseIdentifier,
|
|
21
|
-
getLocalKVNamespaceIdentifier,
|
|
22
|
-
loadConfig,
|
|
23
|
-
normalizeArtifactsBinding,
|
|
24
|
-
normalizeDOBinding,
|
|
25
|
-
normalizeDispatchNamespaceBinding,
|
|
26
|
-
normalizeHyperdriveBinding,
|
|
27
|
-
normalizeImagesBinding,
|
|
28
|
-
normalizeMediaBinding,
|
|
29
|
-
normalizeMtlsCertificateBinding,
|
|
30
|
-
normalizePipelineBinding,
|
|
31
|
-
normalizeSecretsStoreBinding,
|
|
32
|
-
normalizeWorkflowBinding,
|
|
33
|
-
resolveConfigEnvVars,
|
|
34
|
-
resolveConfigForEnvironment,
|
|
35
|
-
resolveConfigPath,
|
|
36
|
-
resolveResources
|
|
37
|
-
} from "./index-x8s9rwfh.js";
|
|
38
|
-
import {
|
|
39
|
-
SUPPORTED_WORKER_EXTENSIONS,
|
|
40
|
-
transformWorkerEntrypoint
|
|
41
|
-
} from "./index-7m557715.js";
|
|
42
|
-
import {
|
|
43
|
-
findDurableObjectClasses
|
|
44
|
-
} from "./index-4mmpccrb.js";
|
|
45
|
-
import {
|
|
46
|
-
__require
|
|
47
|
-
} from "./index-37x76zdn.js";
|
|
48
|
-
// src/vite/plugin.ts
|
|
49
|
-
import { dirname as dirname3, resolve as resolve6 } from "pathe";
|
|
50
|
-
|
|
51
|
-
// src/vite/plugin-config-hook.ts
|
|
52
|
-
async function tryLoadDevflareConfig(cwd, configPath, command) {
|
|
53
|
-
try {
|
|
54
|
-
return await loadConfig({ cwd, configFile: configPath });
|
|
55
|
-
} catch (error) {
|
|
56
|
-
if (command === "build") {
|
|
57
|
-
console.warn("[devflare] Could not load config:", error);
|
|
58
|
-
}
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
function buildWorkerNameDefine(lfConfig, existing) {
|
|
63
|
-
const workerNameValue = lfConfig.name ?? "unknown";
|
|
64
|
-
return {
|
|
65
|
-
...existing,
|
|
66
|
-
__DEVFLARE_WORKER_NAME__: JSON.stringify(workerNameValue)
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
function buildWebSocketProxyConfig(lfConfig, bridgePort, wsProxyPatterns) {
|
|
70
|
-
const patterns = [...wsProxyPatterns];
|
|
71
|
-
if (lfConfig.wsRoutes && lfConfig.wsRoutes.length > 0) {
|
|
72
|
-
for (const route of lfConfig.wsRoutes) {
|
|
73
|
-
if (!patterns.includes(route.pattern)) {
|
|
74
|
-
patterns.push(route.pattern);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
if (patterns.length === 0)
|
|
79
|
-
return null;
|
|
80
|
-
const proxyConfig = {};
|
|
81
|
-
for (const pattern of patterns) {
|
|
82
|
-
proxyConfig[pattern] = {
|
|
83
|
-
target: `http://127.0.0.1:${bridgePort}`,
|
|
84
|
-
changeOrigin: true,
|
|
85
|
-
ws: true,
|
|
86
|
-
configure: (proxy) => {
|
|
87
|
-
proxy.on("error", (err) => {
|
|
88
|
-
console.error(`[devflare] Proxy error: ${err.message}`);
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
if (Object.keys(proxyConfig).length === 0)
|
|
94
|
-
return null;
|
|
95
|
-
console.log(`[devflare] WebSocket proxy configured for: ${patterns.join(", ")}`);
|
|
96
|
-
return proxyConfig;
|
|
97
|
-
}
|
|
98
|
-
async function buildPluginConfigHookResult(cwd, options, command, existingDefine) {
|
|
99
|
-
const lfConfig = await tryLoadDevflareConfig(cwd, options.configPath, command);
|
|
100
|
-
const returnConfig = {};
|
|
101
|
-
if (lfConfig) {
|
|
102
|
-
returnConfig.define = buildWorkerNameDefine(lfConfig, existingDefine);
|
|
103
|
-
}
|
|
104
|
-
if (command === "serve" && process.env.DEVFLARE_DEV && lfConfig) {
|
|
105
|
-
const port = options.bridgePort ?? 8787;
|
|
106
|
-
const proxyConfig = buildWebSocketProxyConfig(lfConfig, port, options.wsProxyPatterns);
|
|
107
|
-
if (proxyConfig) {
|
|
108
|
-
returnConfig.server = { proxy: proxyConfig };
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return Object.keys(returnConfig).length > 0 ? returnConfig : undefined;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// src/vite/plugin-context.ts
|
|
115
|
-
import { isAbsolute, relative as relative3, resolve as resolve5 } from "pathe";
|
|
116
|
-
|
|
117
|
-
// src/test/resolve-service-bindings.ts
|
|
118
|
-
import { existsSync, readFileSync } from "fs";
|
|
119
|
-
import { dirname, join, resolve } from "path";
|
|
120
|
-
|
|
121
|
-
// src/dev-server/miniflare-bindings.ts
|
|
122
|
-
function buildQueueProducers(bindings) {
|
|
123
|
-
if (!bindings.queues?.producers) {
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
const producers = {};
|
|
127
|
-
for (const [bindingName, queueName] of Object.entries(bindings.queues.producers)) {
|
|
128
|
-
producers[bindingName] = { queueName };
|
|
129
|
-
}
|
|
130
|
-
return producers;
|
|
131
|
-
}
|
|
132
|
-
function buildQueueConsumers(bindings) {
|
|
133
|
-
if (!bindings.queues?.consumers || bindings.queues.consumers.length === 0) {
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
const consumers = {};
|
|
137
|
-
for (const consumer of bindings.queues.consumers) {
|
|
138
|
-
consumers[consumer.queue] = {
|
|
139
|
-
...consumer.maxBatchSize !== undefined && { maxBatchSize: consumer.maxBatchSize },
|
|
140
|
-
...consumer.maxBatchTimeout !== undefined && { maxBatchTimeout: consumer.maxBatchTimeout },
|
|
141
|
-
...consumer.maxRetries !== undefined && { maxRetries: consumer.maxRetries },
|
|
142
|
-
...consumer.deadLetterQueue && { deadLetterQueue: consumer.deadLetterQueue },
|
|
143
|
-
...consumer.maxConcurrency !== undefined && { maxConcurrency: consumer.maxConcurrency },
|
|
144
|
-
...consumer.retryDelay !== undefined && { retryDelay: consumer.retryDelay }
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
return consumers;
|
|
148
|
-
}
|
|
149
|
-
function buildRateLimitsConfig(bindings) {
|
|
150
|
-
if (!bindings.rateLimits) {
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
return Object.fromEntries(Object.entries(bindings.rateLimits).map(([name, binding]) => [
|
|
154
|
-
name,
|
|
155
|
-
{
|
|
156
|
-
simple: {
|
|
157
|
-
limit: binding.simple.limit,
|
|
158
|
-
period: binding.simple.period
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
]));
|
|
162
|
-
}
|
|
163
|
-
function buildVersionMetadataConfig(bindings) {
|
|
164
|
-
return bindings.versionMetadata?.binding;
|
|
165
|
-
}
|
|
166
|
-
function buildWorkerLoadersConfig(bindings) {
|
|
167
|
-
if (!bindings.workerLoaders) {
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
return Object.fromEntries(Object.keys(bindings.workerLoaders).map((bindingName) => [bindingName, {}]));
|
|
171
|
-
}
|
|
172
|
-
function buildMtlsCertificatesConfig(bindings) {
|
|
173
|
-
if (!bindings.mtlsCertificates) {
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
return Object.fromEntries(Object.entries(bindings.mtlsCertificates).map(([bindingName, binding]) => {
|
|
177
|
-
const normalized = normalizeMtlsCertificateBinding(binding);
|
|
178
|
-
return [
|
|
179
|
-
bindingName,
|
|
180
|
-
{
|
|
181
|
-
certificate_id: normalized.certificateId
|
|
182
|
-
}
|
|
183
|
-
];
|
|
184
|
-
}));
|
|
185
|
-
}
|
|
186
|
-
function buildDispatchNamespacesConfig(bindings) {
|
|
187
|
-
if (!bindings.dispatchNamespaces) {
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
return Object.fromEntries(Object.entries(bindings.dispatchNamespaces).map(([bindingName, binding]) => {
|
|
191
|
-
const normalized = normalizeDispatchNamespaceBinding(binding);
|
|
192
|
-
return [
|
|
193
|
-
bindingName,
|
|
194
|
-
{
|
|
195
|
-
namespace: normalized.namespace
|
|
196
|
-
}
|
|
197
|
-
];
|
|
198
|
-
}));
|
|
199
|
-
}
|
|
200
|
-
function buildWorkflowsConfig(bindings) {
|
|
201
|
-
if (!bindings.workflows) {
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
return Object.fromEntries(Object.entries(bindings.workflows).map(([bindingName, binding]) => {
|
|
205
|
-
const normalized = normalizeWorkflowBinding(binding);
|
|
206
|
-
return [
|
|
207
|
-
bindingName,
|
|
208
|
-
{
|
|
209
|
-
name: normalized.name,
|
|
210
|
-
className: normalized.className,
|
|
211
|
-
...normalized.scriptName && { scriptName: normalized.scriptName },
|
|
212
|
-
...normalized.limits && { stepLimit: normalized.limits.steps }
|
|
213
|
-
}
|
|
214
|
-
];
|
|
215
|
-
}));
|
|
216
|
-
}
|
|
217
|
-
function buildPipelinesConfig(bindings) {
|
|
218
|
-
if (!bindings.pipelines) {
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
return Object.fromEntries(Object.entries(bindings.pipelines).map(([bindingName, binding]) => {
|
|
222
|
-
const normalized = normalizePipelineBinding(binding);
|
|
223
|
-
return [
|
|
224
|
-
bindingName,
|
|
225
|
-
typeof binding === "string" ? normalized.pipeline : { pipeline: normalized.pipeline }
|
|
226
|
-
];
|
|
227
|
-
}));
|
|
228
|
-
}
|
|
229
|
-
function getHyperdriveLocalConnectionString(bindingName, binding) {
|
|
230
|
-
const cloudflareEnvName = `CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_${bindingName}`;
|
|
231
|
-
const wranglerEnvName = `WRANGLER_HYPERDRIVE_LOCAL_CONNECTION_STRING_${bindingName}`;
|
|
232
|
-
const envValue = process.env[cloudflareEnvName] ?? process.env[wranglerEnvName];
|
|
233
|
-
if (envValue?.trim()) {
|
|
234
|
-
return envValue;
|
|
235
|
-
}
|
|
236
|
-
const normalized = normalizeHyperdriveBinding(binding);
|
|
237
|
-
return normalized.localConnectionString;
|
|
238
|
-
}
|
|
239
|
-
function buildHyperdrivesConfig(bindings) {
|
|
240
|
-
if (!bindings.hyperdrive) {
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
const hyperdrives = Object.fromEntries(Object.entries(bindings.hyperdrive).map(([bindingName, binding]) => {
|
|
244
|
-
const localConnectionString = getHyperdriveLocalConnectionString(bindingName, binding);
|
|
245
|
-
return localConnectionString ? [bindingName, localConnectionString] : null;
|
|
246
|
-
}).filter((entry) => entry !== null));
|
|
247
|
-
return Object.keys(hyperdrives).length > 0 ? hyperdrives : undefined;
|
|
248
|
-
}
|
|
249
|
-
function buildImagesConfig(bindings) {
|
|
250
|
-
if (!bindings.images) {
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
const [entry] = Object.entries(bindings.images);
|
|
254
|
-
if (!entry) {
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
const [bindingName, binding] = entry;
|
|
258
|
-
const normalized = normalizeImagesBinding(bindingName, binding);
|
|
259
|
-
return {
|
|
260
|
-
binding: normalized.binding
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
function buildMediaConfig(bindings) {
|
|
264
|
-
if (!bindings.media) {
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
const [entry] = Object.entries(bindings.media);
|
|
268
|
-
if (!entry) {
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
const [bindingName, binding] = entry;
|
|
272
|
-
const normalized = normalizeMediaBinding(bindingName, binding);
|
|
273
|
-
return {
|
|
274
|
-
binding: normalized.binding
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
function buildArtifactsConfig(bindings) {
|
|
278
|
-
if (!bindings.artifacts) {
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
return Object.fromEntries(Object.entries(bindings.artifacts).map(([bindingName, binding]) => {
|
|
282
|
-
const normalized = normalizeArtifactsBinding(binding);
|
|
283
|
-
return [
|
|
284
|
-
bindingName,
|
|
285
|
-
{
|
|
286
|
-
namespace: normalized.namespace
|
|
287
|
-
}
|
|
288
|
-
];
|
|
289
|
-
}));
|
|
290
|
-
}
|
|
291
|
-
function buildAiSearchNamespacesConfig(bindings) {
|
|
292
|
-
if (!bindings.aiSearchNamespaces) {
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
return Object.fromEntries(Object.entries(bindings.aiSearchNamespaces).map(([bindingName, binding]) => [
|
|
296
|
-
bindingName,
|
|
297
|
-
{
|
|
298
|
-
namespace: binding.namespace
|
|
299
|
-
}
|
|
300
|
-
]));
|
|
301
|
-
}
|
|
302
|
-
function buildAiSearchInstancesConfig(bindings) {
|
|
303
|
-
if (!bindings.aiSearch) {
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
return Object.fromEntries(Object.entries(bindings.aiSearch).map(([bindingName, binding]) => [
|
|
307
|
-
bindingName,
|
|
308
|
-
{
|
|
309
|
-
instance_name: binding.instanceName
|
|
310
|
-
}
|
|
311
|
-
]));
|
|
312
|
-
}
|
|
313
|
-
function buildSecretsStoreConfig(bindings, defaultSecretsStoreId, excludedBindingNames = new Set) {
|
|
314
|
-
if (!bindings.secretsStore) {
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
const entries = Object.entries(bindings.secretsStore).flatMap(([bindingName, binding]) => {
|
|
318
|
-
if (excludedBindingNames.has(bindingName)) {
|
|
319
|
-
return [];
|
|
320
|
-
}
|
|
321
|
-
const normalized = normalizeSecretsStoreBinding(binding, defaultSecretsStoreId, bindingName);
|
|
322
|
-
return [
|
|
323
|
-
[
|
|
324
|
-
bindingName,
|
|
325
|
-
{
|
|
326
|
-
store_id: normalized.storeId,
|
|
327
|
-
secret_name: normalized.secretName
|
|
328
|
-
}
|
|
329
|
-
]
|
|
330
|
-
];
|
|
331
|
-
});
|
|
332
|
-
return entries.length > 0 ? Object.fromEntries(entries) : undefined;
|
|
333
|
-
}
|
|
334
|
-
function buildSendEmailConfig(bindings) {
|
|
335
|
-
if (!bindings.sendEmail) {
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
return {
|
|
339
|
-
send_email: Object.entries(bindings.sendEmail).map(([name, binding]) => ({
|
|
340
|
-
name,
|
|
341
|
-
...binding.destinationAddress && {
|
|
342
|
-
destination_address: binding.destinationAddress
|
|
343
|
-
},
|
|
344
|
-
...binding.allowedDestinationAddresses && {
|
|
345
|
-
allowed_destination_addresses: binding.allowedDestinationAddresses
|
|
346
|
-
},
|
|
347
|
-
...binding.allowedSenderAddresses && {
|
|
348
|
-
allowed_sender_addresses: binding.allowedSenderAddresses
|
|
349
|
-
}
|
|
350
|
-
}))
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// src/test/resolve-service-bindings.ts
|
|
355
|
-
function getBunRuntime() {
|
|
356
|
-
const g = globalThis;
|
|
357
|
-
if (typeof g.Bun === "object" && g.Bun !== null) {
|
|
358
|
-
return g.Bun;
|
|
359
|
-
}
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
function discoverDOFilesSync(dir, pattern = DEFAULT_DO_PATTERN) {
|
|
363
|
-
const classToPath = new Map;
|
|
364
|
-
try {
|
|
365
|
-
const files = findFilesSync(pattern, { cwd: dir });
|
|
366
|
-
for (const filePath of files) {
|
|
367
|
-
try {
|
|
368
|
-
const code = readFileSync(filePath, "utf-8");
|
|
369
|
-
const classNames = findDurableObjectClasses(code);
|
|
370
|
-
for (const className of classNames) {
|
|
371
|
-
if (!classToPath.has(className)) {
|
|
372
|
-
classToPath.set(className, filePath);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
} catch {}
|
|
376
|
-
}
|
|
377
|
-
} catch {}
|
|
378
|
-
return classToPath;
|
|
379
|
-
}
|
|
380
|
-
var bundleCache = new Map;
|
|
381
|
-
function findDefaultServiceWorkerEntrypoint(refConfigDir) {
|
|
382
|
-
for (const candidate of ["worker.ts", "worker.js", "src/worker.ts", "src/worker.js"]) {
|
|
383
|
-
const absolutePath = resolve(refConfigDir, candidate);
|
|
384
|
-
if (existsSync(absolutePath)) {
|
|
385
|
-
return absolutePath;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
return null;
|
|
389
|
-
}
|
|
390
|
-
function buildRawServiceBindings(services) {
|
|
391
|
-
if (!services || Object.keys(services).length === 0) {
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
394
|
-
return Object.fromEntries(Object.entries(services).map(([bindingName, binding]) => [
|
|
395
|
-
bindingName,
|
|
396
|
-
{
|
|
397
|
-
name: binding.service,
|
|
398
|
-
...binding.entrypoint && { entrypoint: binding.entrypoint }
|
|
399
|
-
}
|
|
400
|
-
]));
|
|
401
|
-
}
|
|
402
|
-
function buildReferencedWorkerRuntimeConfig(config) {
|
|
403
|
-
const bindings = config.bindings ?? {};
|
|
404
|
-
const queueProducers = buildQueueProducers(bindings);
|
|
405
|
-
const queueConsumers = buildQueueConsumers(bindings);
|
|
406
|
-
const rateLimits = buildRateLimitsConfig(bindings);
|
|
407
|
-
const versionMetadata = buildVersionMetadataConfig(bindings);
|
|
408
|
-
const workerLoaders = buildWorkerLoadersConfig(bindings);
|
|
409
|
-
const mtlsCertificates = buildMtlsCertificatesConfig(bindings);
|
|
410
|
-
const dispatchNamespaces = buildDispatchNamespacesConfig(bindings);
|
|
411
|
-
const workflows = buildWorkflowsConfig(bindings);
|
|
412
|
-
const pipelines = buildPipelinesConfig(bindings);
|
|
413
|
-
const hyperdrives = buildHyperdrivesConfig(bindings);
|
|
414
|
-
const media = buildMediaConfig(bindings);
|
|
415
|
-
const artifacts = buildArtifactsConfig(bindings);
|
|
416
|
-
const aiSearchNamespaces = buildAiSearchNamespacesConfig(bindings);
|
|
417
|
-
const aiSearchInstances = buildAiSearchInstancesConfig(bindings);
|
|
418
|
-
const secretsStoreSecrets = buildSecretsStoreConfig(bindings, config.secretsStoreId);
|
|
419
|
-
const email = buildSendEmailConfig(bindings);
|
|
420
|
-
const serviceBindings = buildRawServiceBindings(bindings.services);
|
|
421
|
-
return {
|
|
422
|
-
...config.compatibilityFlags && { compatibilityFlags: config.compatibilityFlags },
|
|
423
|
-
...config.vars && { bindings: config.vars },
|
|
424
|
-
...bindings.kv && {
|
|
425
|
-
kvNamespaces: Object.fromEntries(Object.entries(bindings.kv).map(([bindingName, bindingConfig]) => [
|
|
426
|
-
bindingName,
|
|
427
|
-
getLocalKVNamespaceIdentifier(bindingConfig)
|
|
428
|
-
]))
|
|
429
|
-
},
|
|
430
|
-
...bindings.r2 && { r2Buckets: bindings.r2 },
|
|
431
|
-
...bindings.d1 && {
|
|
432
|
-
d1Databases: Object.fromEntries(Object.entries(bindings.d1).map(([bindingName, bindingConfig]) => [
|
|
433
|
-
bindingName,
|
|
434
|
-
getLocalD1DatabaseIdentifier(bindingConfig)
|
|
435
|
-
]))
|
|
436
|
-
},
|
|
437
|
-
...queueProducers && { queueProducers },
|
|
438
|
-
...queueConsumers && { queueConsumers },
|
|
439
|
-
...rateLimits && { ratelimits: rateLimits },
|
|
440
|
-
...versionMetadata && { versionMetadata },
|
|
441
|
-
...workerLoaders && { workerLoaders },
|
|
442
|
-
...mtlsCertificates && { mtlsCertificates },
|
|
443
|
-
...dispatchNamespaces && { dispatchNamespaces },
|
|
444
|
-
...workflows && { workflows },
|
|
445
|
-
...pipelines && { pipelines },
|
|
446
|
-
...hyperdrives && { hyperdrives },
|
|
447
|
-
...media && { media },
|
|
448
|
-
...artifacts && { artifacts },
|
|
449
|
-
...aiSearchNamespaces && { aiSearchNamespaces },
|
|
450
|
-
...aiSearchInstances && { aiSearchInstances },
|
|
451
|
-
...secretsStoreSecrets && { secretsStoreSecrets },
|
|
452
|
-
...email && { email },
|
|
453
|
-
...serviceBindings && { serviceBindings }
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
function normalizeReferencedConfig(config) {
|
|
457
|
-
return configSchema.parse(config);
|
|
458
|
-
}
|
|
459
|
-
function resolveReferencedConfigDir(ref, parentConfigDir) {
|
|
460
|
-
const configPath = ref.configPath;
|
|
461
|
-
if (!configPath || configPath === "<resolved>") {
|
|
462
|
-
return null;
|
|
463
|
-
}
|
|
464
|
-
return dirname(resolvePackageSpecifier(configPath, parentConfigDir));
|
|
465
|
-
}
|
|
466
|
-
async function resolveReferencedLocalDurableObjects(config, configDir, workerName, serviceBindings = {}) {
|
|
467
|
-
const doPattern = config.files?.durableObjects;
|
|
468
|
-
const dosConfig = config.bindings?.durableObjects;
|
|
469
|
-
if (typeof doPattern !== "string" || !dosConfig || Object.keys(dosConfig).length === 0) {
|
|
470
|
-
return { workers: [], bindings: {} };
|
|
471
|
-
}
|
|
472
|
-
const discoveredDOs = discoverDOFilesSync(configDir, doPattern);
|
|
473
|
-
const doClasses = [];
|
|
474
|
-
for (const [bindingName, rawDoConfig] of Object.entries(dosConfig)) {
|
|
475
|
-
const doConfig = normalizeDOBinding(rawDoConfig);
|
|
476
|
-
if (doConfig.kind !== "local") {
|
|
477
|
-
continue;
|
|
478
|
-
}
|
|
479
|
-
const scriptPath = discoveredDOs.get(doConfig.className);
|
|
480
|
-
if (!scriptPath) {
|
|
481
|
-
console.warn(`[devflare] DO "${bindingName}" (class: ${doConfig.className}) not found in files.durableObjects for "${workerName}"`);
|
|
482
|
-
continue;
|
|
483
|
-
}
|
|
484
|
-
doClasses.push({ bindingName, className: doConfig.className, scriptPath });
|
|
485
|
-
}
|
|
486
|
-
if (doClasses.length === 0) {
|
|
487
|
-
return { workers: [], bindings: {} };
|
|
488
|
-
}
|
|
489
|
-
const doWorkerName = `${workerName}-durable-objects`;
|
|
490
|
-
const script = await bundleDOClasses(doClasses, doWorkerName);
|
|
491
|
-
if (!script) {
|
|
492
|
-
return { workers: [], bindings: {} };
|
|
493
|
-
}
|
|
494
|
-
const durableObjects = Object.fromEntries(doClasses.map((do_) => [do_.bindingName, do_.className]));
|
|
495
|
-
const runtimeConfig = buildReferencedWorkerRuntimeConfig(config);
|
|
496
|
-
const doRuntimeConfig = { ...runtimeConfig };
|
|
497
|
-
delete doRuntimeConfig.queueConsumers;
|
|
498
|
-
const mergedServiceBindings = {
|
|
499
|
-
...runtimeConfig.serviceBindings ?? {},
|
|
500
|
-
...serviceBindings
|
|
501
|
-
};
|
|
502
|
-
return {
|
|
503
|
-
workers: [
|
|
504
|
-
{
|
|
505
|
-
name: doWorkerName,
|
|
506
|
-
script,
|
|
507
|
-
modules: true,
|
|
508
|
-
compatibilityDate: config.compatibilityDate,
|
|
509
|
-
...doRuntimeConfig,
|
|
510
|
-
...Object.keys(mergedServiceBindings).length > 0 && {
|
|
511
|
-
serviceBindings: mergedServiceBindings
|
|
512
|
-
},
|
|
513
|
-
durableObjects
|
|
514
|
-
}
|
|
515
|
-
],
|
|
516
|
-
bindings: Object.fromEntries(doClasses.map((do_) => [
|
|
517
|
-
do_.bindingName,
|
|
518
|
-
{
|
|
519
|
-
className: do_.className,
|
|
520
|
-
scriptName: doWorkerName
|
|
521
|
-
}
|
|
522
|
-
]))
|
|
523
|
-
};
|
|
524
|
-
}
|
|
525
|
-
async function resolveServiceBindings(config, configDir, seenWorkers = new Set) {
|
|
526
|
-
const services = config.bindings?.services;
|
|
527
|
-
if (!services) {
|
|
528
|
-
return { workers: [], primaryServiceBindings: {} };
|
|
529
|
-
}
|
|
530
|
-
const workersByName = new Map;
|
|
531
|
-
const primaryServiceBindings = {};
|
|
532
|
-
for (const [bindingName, binding] of Object.entries(services)) {
|
|
533
|
-
const workerBinding = binding;
|
|
534
|
-
const ref = workerBinding.__ref;
|
|
535
|
-
if (ref) {
|
|
536
|
-
if ("__import" in ref && typeof ref.__import === "function") {
|
|
537
|
-
await ref.resolve();
|
|
538
|
-
}
|
|
539
|
-
const workerName = ref.name;
|
|
540
|
-
const entrypoint = workerBinding.entrypoint;
|
|
541
|
-
if (!workersByName.has(workerName) && !seenWorkers.has(workerName)) {
|
|
542
|
-
const refConfig = normalizeReferencedConfig(ref.config);
|
|
543
|
-
const worker = await resolveRefWorker(ref, entrypoint, configDir, refConfig);
|
|
544
|
-
if (worker) {
|
|
545
|
-
const refConfigDir = resolveReferencedConfigDir(ref, configDir);
|
|
546
|
-
if (ref.config && refConfigDir) {
|
|
547
|
-
const nested = await resolveServiceBindings(refConfig, refConfigDir, new Set([...seenWorkers, workerName]));
|
|
548
|
-
worker.serviceBindings = {
|
|
549
|
-
...worker.serviceBindings ?? {},
|
|
550
|
-
...nested.primaryServiceBindings
|
|
551
|
-
};
|
|
552
|
-
for (const nestedWorker of nested.workers) {
|
|
553
|
-
if (!workersByName.has(nestedWorker.name)) {
|
|
554
|
-
workersByName.set(nestedWorker.name, nestedWorker);
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
const localDOs = await resolveReferencedLocalDurableObjects(refConfig, refConfigDir, workerName, nested.primaryServiceBindings);
|
|
558
|
-
worker.durableObjects = {
|
|
559
|
-
...worker.durableObjects ?? {},
|
|
560
|
-
...localDOs.bindings
|
|
561
|
-
};
|
|
562
|
-
for (const doWorker of localDOs.workers) {
|
|
563
|
-
if (!workersByName.has(doWorker.name)) {
|
|
564
|
-
workersByName.set(doWorker.name, doWorker);
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
workersByName.set(workerName, worker);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
primaryServiceBindings[bindingName] = {
|
|
572
|
-
name: workerName,
|
|
573
|
-
...entrypoint && { entrypoint }
|
|
574
|
-
};
|
|
575
|
-
} else {
|
|
576
|
-
primaryServiceBindings[bindingName] = {
|
|
577
|
-
name: workerBinding.service,
|
|
578
|
-
...workerBinding.entrypoint && { entrypoint: workerBinding.entrypoint }
|
|
579
|
-
};
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
return {
|
|
583
|
-
workers: [...workersByName.values()],
|
|
584
|
-
primaryServiceBindings
|
|
585
|
-
};
|
|
586
|
-
}
|
|
587
|
-
async function resolveRefWorker(ref, _entrypoint, parentConfigDir, resolvedConfig) {
|
|
588
|
-
const config = resolvedConfig ?? normalizeReferencedConfig(ref.config);
|
|
589
|
-
if (!config)
|
|
590
|
-
return null;
|
|
591
|
-
const refConfigDir = resolveReferencedConfigDir(ref, parentConfigDir);
|
|
592
|
-
if (!refConfigDir) {
|
|
593
|
-
console.warn(`[devflare] Cannot resolve worker "${ref.name}" - configPath not available`);
|
|
594
|
-
return null;
|
|
595
|
-
}
|
|
596
|
-
const entrypoints = [];
|
|
597
|
-
const workerEntrypointPath = findDefaultServiceWorkerEntrypoint(refConfigDir);
|
|
598
|
-
if (workerEntrypointPath) {
|
|
599
|
-
entrypoints.push({
|
|
600
|
-
path: workerEntrypointPath,
|
|
601
|
-
className: "Worker",
|
|
602
|
-
isWorkerTs: true
|
|
603
|
-
});
|
|
604
|
-
}
|
|
605
|
-
if (config.files?.entrypoints !== false) {
|
|
606
|
-
const discoveredEntrypoints = discoverEntrypointsSync(refConfigDir, typeof config.files?.entrypoints === "string" ? config.files.entrypoints : undefined);
|
|
607
|
-
for (const ep of discoveredEntrypoints) {
|
|
608
|
-
entrypoints.push({
|
|
609
|
-
path: ep.filePath,
|
|
610
|
-
className: ep.className,
|
|
611
|
-
isWorkerTs: false
|
|
612
|
-
});
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
if (entrypoints.length === 0) {
|
|
616
|
-
console.warn(`[devflare] Worker "${ref.name}" has no entry points`);
|
|
617
|
-
return null;
|
|
618
|
-
}
|
|
619
|
-
const script = await bundleAllEntrypoints(entrypoints, ref.name);
|
|
620
|
-
if (!script)
|
|
621
|
-
return null;
|
|
622
|
-
return {
|
|
623
|
-
name: ref.name,
|
|
624
|
-
script,
|
|
625
|
-
modules: true,
|
|
626
|
-
compatibilityDate: config.compatibilityDate ?? "2025-01-01",
|
|
627
|
-
...buildReferencedWorkerRuntimeConfig(config)
|
|
628
|
-
};
|
|
629
|
-
}
|
|
630
|
-
async function bundleAllEntrypoints(entrypoints, workerName) {
|
|
631
|
-
const cacheKey = entrypoints.map((ep) => `${ep.path}::${ep.className}`).join("|");
|
|
632
|
-
const cached = bundleCache.get(cacheKey);
|
|
633
|
-
if (cached) {
|
|
634
|
-
return cached;
|
|
635
|
-
}
|
|
636
|
-
const bun = getBunRuntime();
|
|
637
|
-
if (!bun) {
|
|
638
|
-
console.warn(`[devflare] Cannot bundle service worker "${workerName}" — the Bun runtime is required to bundle worker scripts, ` + "but this process is not running under Bun. The service binding will be left unresolved. " + "Run your tests with `bun test` (or the devflare test runner) to enable multi-worker service bindings.");
|
|
639
|
-
return null;
|
|
640
|
-
}
|
|
641
|
-
try {
|
|
642
|
-
const { readFileSync: readFileSync2, writeFileSync, mkdirSync, unlinkSync } = await import("fs");
|
|
643
|
-
const imports = [];
|
|
644
|
-
const exports = [];
|
|
645
|
-
let defaultExportClass = null;
|
|
646
|
-
for (let i = 0;i < entrypoints.length; i++) {
|
|
647
|
-
const ep = entrypoints[i];
|
|
648
|
-
const sourceCode = readFileSync2(ep.path, "utf-8");
|
|
649
|
-
if (ep.isWorkerTs) {
|
|
650
|
-
const result = transformWorkerEntrypoint(sourceCode, ep.path, {
|
|
651
|
-
className: ep.className,
|
|
652
|
-
injectContext: false
|
|
653
|
-
});
|
|
654
|
-
if (result) {
|
|
655
|
-
const tempDir2 = join(dirname(ep.path), ".devflare");
|
|
656
|
-
mkdirSync(tempDir2, { recursive: true });
|
|
657
|
-
const tempPath = join(tempDir2, `__${ep.className}_${i}.ts`);
|
|
658
|
-
writeFileSync(tempPath, result.code);
|
|
659
|
-
imports.push(`import { ${ep.className} } from '${tempPath.replace(/\\/g, "/")}'`);
|
|
660
|
-
exports.push(ep.className);
|
|
661
|
-
if (!defaultExportClass) {
|
|
662
|
-
defaultExportClass = ep.className;
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
} else {
|
|
666
|
-
imports.push(`import { ${ep.className} } from '${ep.path.replace(/\\/g, "/")}'`);
|
|
667
|
-
exports.push(ep.className);
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
const defaultExport = defaultExportClass ? `
|
|
671
|
-
export default ${defaultExportClass}` : "";
|
|
672
|
-
const entryCode = `
|
|
673
|
-
${imports.join(`
|
|
674
|
-
`)}
|
|
675
|
-
export { ${exports.join(", ")} }${defaultExport}
|
|
676
|
-
`;
|
|
677
|
-
const tempDir = join(dirname(entrypoints[0].path), ".devflare");
|
|
678
|
-
mkdirSync(tempDir, { recursive: true });
|
|
679
|
-
const entryPath = join(tempDir, `__entry_${workerName}.ts`);
|
|
680
|
-
writeFileSync(entryPath, entryCode);
|
|
681
|
-
try {
|
|
682
|
-
const result = await bun.build({
|
|
683
|
-
entrypoints: [entryPath],
|
|
684
|
-
target: "browser",
|
|
685
|
-
format: "esm",
|
|
686
|
-
minify: false,
|
|
687
|
-
external: ["cloudflare:workers", "cloudflare:*"]
|
|
688
|
-
});
|
|
689
|
-
if (!result.success) {
|
|
690
|
-
console.warn(`[devflare] Failed to bundle worker "${workerName}": ${result.logs.join(`
|
|
691
|
-
`)}`);
|
|
692
|
-
return null;
|
|
693
|
-
}
|
|
694
|
-
const bundledCode = await result.outputs[0].text();
|
|
695
|
-
bundleCache.set(cacheKey, bundledCode);
|
|
696
|
-
return bundledCode;
|
|
697
|
-
} finally {
|
|
698
|
-
try {
|
|
699
|
-
unlinkSync(entryPath);
|
|
700
|
-
} catch {}
|
|
701
|
-
}
|
|
702
|
-
} catch (error) {
|
|
703
|
-
console.warn(`[devflare] Error bundling worker "${workerName}":`, error);
|
|
704
|
-
return null;
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
async function bundleDOClasses(doClasses, workerName) {
|
|
708
|
-
const cacheKey = `do:${doClasses.map((d) => `${d.scriptPath}::${d.className}`).join("|")}`;
|
|
709
|
-
const cached = bundleCache.get(cacheKey);
|
|
710
|
-
if (cached)
|
|
711
|
-
return cached;
|
|
712
|
-
const bun = getBunRuntime();
|
|
713
|
-
if (!bun) {
|
|
714
|
-
console.warn(`[devflare] Cannot bundle Durable Object worker "${workerName}" — the Bun runtime is required to bundle DO classes, ` + "but this process is not running under Bun. The Durable Object binding will be left unresolved. Run your tests with `bun test` (or the devflare test runner) to enable cross-worker Durable Objects.");
|
|
715
|
-
return null;
|
|
716
|
-
}
|
|
717
|
-
try {
|
|
718
|
-
const { writeFileSync, mkdirSync, unlinkSync } = await import("fs");
|
|
719
|
-
const imports = doClasses.map((d) => `import { ${d.className} } from '${d.scriptPath.replace(/\\/g, "/")}'`).join(`
|
|
720
|
-
`);
|
|
721
|
-
const exports = doClasses.map((d) => d.className).join(", ");
|
|
722
|
-
const entryCode = `
|
|
723
|
-
${imports}
|
|
724
|
-
|
|
725
|
-
// Re-export DO classes for Miniflare binding
|
|
726
|
-
export { ${exports} }
|
|
727
|
-
|
|
728
|
-
// Default export with fetch handler
|
|
729
|
-
export default {
|
|
730
|
-
async fetch(request, env) {
|
|
731
|
-
return new Response('DO Worker: ${workerName}')
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
`;
|
|
735
|
-
const tempDir = join(dirname(doClasses[0].scriptPath), ".devflare");
|
|
736
|
-
mkdirSync(tempDir, { recursive: true });
|
|
737
|
-
const entryPath = join(tempDir, `__do_entry_${workerName}.ts`);
|
|
738
|
-
writeFileSync(entryPath, entryCode);
|
|
739
|
-
try {
|
|
740
|
-
const result = await bun.build({
|
|
741
|
-
entrypoints: [entryPath],
|
|
742
|
-
target: "browser",
|
|
743
|
-
format: "esm",
|
|
744
|
-
minify: false,
|
|
745
|
-
external: ["cloudflare:workers", "cloudflare:*"]
|
|
746
|
-
});
|
|
747
|
-
if (!result.success) {
|
|
748
|
-
console.warn(`[devflare] Failed to bundle DO worker "${workerName}": ${result.logs.join(`
|
|
749
|
-
`)}`);
|
|
750
|
-
return null;
|
|
751
|
-
}
|
|
752
|
-
const bundledCode = await result.outputs[0].text();
|
|
753
|
-
bundleCache.set(cacheKey, bundledCode);
|
|
754
|
-
return bundledCode;
|
|
755
|
-
} finally {
|
|
756
|
-
try {
|
|
757
|
-
unlinkSync(entryPath);
|
|
758
|
-
} catch {}
|
|
759
|
-
}
|
|
760
|
-
} catch (error) {
|
|
761
|
-
console.warn(`[devflare] Error bundling DO worker "${workerName}":`, error);
|
|
762
|
-
return null;
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
// src/worker-entry/composed-worker.ts
|
|
767
|
-
import { dirname as dirname2, relative as relative2, resolve as resolve4 } from "pathe";
|
|
768
|
-
|
|
769
|
-
// src/worker-entry/durable-object-discovery.ts
|
|
770
|
-
async function discoverDurableObjectFiles(cwd, pattern) {
|
|
771
|
-
const result = new Map;
|
|
772
|
-
const matchedFiles = await findFiles(pattern, { cwd });
|
|
773
|
-
const fs = await import("node:fs/promises");
|
|
774
|
-
for (const filePath of matchedFiles) {
|
|
775
|
-
try {
|
|
776
|
-
const code = await fs.readFile(filePath, "utf-8");
|
|
777
|
-
const classNames = findDurableObjectClasses(code);
|
|
778
|
-
if (classNames.length > 0) {
|
|
779
|
-
result.set(filePath, classNames);
|
|
780
|
-
}
|
|
781
|
-
} catch (error) {
|
|
782
|
-
console.warn(`[devflare] Failed to read DO file: ${filePath}`, error);
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
return result;
|
|
786
|
-
}
|
|
787
|
-
async function discoverDurableObjects(projectRoot, pattern, workerName) {
|
|
788
|
-
const files = await discoverDurableObjectFiles(projectRoot, pattern);
|
|
789
|
-
return { files, workerName };
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
// src/worker-entry/routes.ts
|
|
793
|
-
import { relative, resolve as resolve2 } from "pathe";
|
|
794
|
-
var DEFAULT_ROUTE_DIR = "src/routes";
|
|
795
|
-
var DEFAULT_ROUTE_FILE_PATTERNS = SUPPORTED_WORKER_EXTENSIONS.map((ext) => `**/*${ext}`);
|
|
796
|
-
function normalizeRoutePrefix(prefix) {
|
|
797
|
-
if (!prefix || prefix === "/") {
|
|
798
|
-
return "";
|
|
799
|
-
}
|
|
800
|
-
const normalized = prefix.startsWith("/") ? prefix : `/${prefix}`;
|
|
801
|
-
return normalized.replace(/\/+$/g, "");
|
|
802
|
-
}
|
|
803
|
-
function createStaticSegmentsFromPrefix(prefix) {
|
|
804
|
-
if (!prefix) {
|
|
805
|
-
return [];
|
|
806
|
-
}
|
|
807
|
-
return prefix.split("/").filter(Boolean).map((value) => ({
|
|
808
|
-
type: "static",
|
|
809
|
-
value
|
|
810
|
-
}));
|
|
811
|
-
}
|
|
812
|
-
function shouldIgnoreRouteFile(relativePath) {
|
|
813
|
-
return relativePath.split("/").some((segment) => segment.startsWith("_"));
|
|
814
|
-
}
|
|
815
|
-
function toRoutePath(segments) {
|
|
816
|
-
if (segments.length === 0) {
|
|
817
|
-
return "/";
|
|
818
|
-
}
|
|
819
|
-
return `/${segments.map((segment) => {
|
|
820
|
-
if (segment.type === "static") {
|
|
821
|
-
return segment.value;
|
|
822
|
-
}
|
|
823
|
-
if (segment.type === "param") {
|
|
824
|
-
return `[${segment.name}]`;
|
|
825
|
-
}
|
|
826
|
-
if (segment.type === "rest") {
|
|
827
|
-
return `[...${segment.name}]`;
|
|
828
|
-
}
|
|
829
|
-
return `[[...${segment.name}]]`;
|
|
830
|
-
}).join("/")}`;
|
|
831
|
-
}
|
|
832
|
-
function getRouteSignature(segments) {
|
|
833
|
-
if (segments.length === 0) {
|
|
834
|
-
return "/";
|
|
835
|
-
}
|
|
836
|
-
return segments.map((segment) => {
|
|
837
|
-
if (segment.type === "static") {
|
|
838
|
-
return `static:${segment.value}`;
|
|
839
|
-
}
|
|
840
|
-
if (segment.type === "param") {
|
|
841
|
-
return "param";
|
|
842
|
-
}
|
|
843
|
-
if (segment.type === "rest") {
|
|
844
|
-
return "rest";
|
|
845
|
-
}
|
|
846
|
-
return "optional-rest";
|
|
847
|
-
}).join("/");
|
|
848
|
-
}
|
|
849
|
-
function getSegmentPriority(segment) {
|
|
850
|
-
if (segment.type === "static") {
|
|
851
|
-
return 4;
|
|
852
|
-
}
|
|
853
|
-
if (segment.type === "param") {
|
|
854
|
-
return 3;
|
|
855
|
-
}
|
|
856
|
-
if (segment.type === "rest") {
|
|
857
|
-
return 1;
|
|
858
|
-
}
|
|
859
|
-
return 0;
|
|
860
|
-
}
|
|
861
|
-
function compareRoutes(a, b) {
|
|
862
|
-
const maxLength = Math.max(a.segments.length, b.segments.length);
|
|
863
|
-
for (let index = 0;index < maxLength; index += 1) {
|
|
864
|
-
const left = a.segments[index];
|
|
865
|
-
const right = b.segments[index];
|
|
866
|
-
if (!left && !right) {
|
|
867
|
-
break;
|
|
868
|
-
}
|
|
869
|
-
if (!left) {
|
|
870
|
-
return 1;
|
|
871
|
-
}
|
|
872
|
-
if (!right) {
|
|
873
|
-
return -1;
|
|
874
|
-
}
|
|
875
|
-
const priorityDifference = getSegmentPriority(right) - getSegmentPriority(left);
|
|
876
|
-
if (priorityDifference !== 0) {
|
|
877
|
-
return priorityDifference;
|
|
878
|
-
}
|
|
879
|
-
if (left.type === "static" && right.type === "static") {
|
|
880
|
-
const lexicalDifference = left.value.localeCompare(right.value);
|
|
881
|
-
if (lexicalDifference !== 0) {
|
|
882
|
-
return lexicalDifference;
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
return a.filePath.localeCompare(b.filePath);
|
|
887
|
-
}
|
|
888
|
-
function parseRouteSegments(relativePath, prefixSegments) {
|
|
889
|
-
const withoutExtension = relativePath.replace(/\.[^.]+$/u, "");
|
|
890
|
-
const rawSegments = withoutExtension.split("/").filter(Boolean);
|
|
891
|
-
const routeSegments = [...prefixSegments];
|
|
892
|
-
for (let index = 0;index < rawSegments.length; index += 1) {
|
|
893
|
-
const segment = rawSegments[index];
|
|
894
|
-
const isLastSegment = index === rawSegments.length - 1;
|
|
895
|
-
if (segment === "index" && isLastSegment) {
|
|
896
|
-
continue;
|
|
897
|
-
}
|
|
898
|
-
const optionalRestMatch = segment.match(/^\[\[\.\.\.(.+)\]\]$/u);
|
|
899
|
-
if (optionalRestMatch) {
|
|
900
|
-
if (!isLastSegment) {
|
|
901
|
-
throw new Error(`Optional rest segment must be the final segment: ${relativePath}`);
|
|
902
|
-
}
|
|
903
|
-
routeSegments.push({
|
|
904
|
-
type: "optional-rest",
|
|
905
|
-
name: optionalRestMatch[1]
|
|
906
|
-
});
|
|
907
|
-
continue;
|
|
908
|
-
}
|
|
909
|
-
const restMatch = segment.match(/^\[\.\.\.(.+)\]$/u);
|
|
910
|
-
if (restMatch) {
|
|
911
|
-
if (!isLastSegment) {
|
|
912
|
-
throw new Error(`Rest segment must be the final segment: ${relativePath}`);
|
|
913
|
-
}
|
|
914
|
-
routeSegments.push({
|
|
915
|
-
type: "rest",
|
|
916
|
-
name: restMatch[1]
|
|
917
|
-
});
|
|
918
|
-
continue;
|
|
919
|
-
}
|
|
920
|
-
const dynamicMatch = segment.match(/^\[(.+)\]$/u);
|
|
921
|
-
if (dynamicMatch) {
|
|
922
|
-
routeSegments.push({
|
|
923
|
-
type: "param",
|
|
924
|
-
name: dynamicMatch[1]
|
|
925
|
-
});
|
|
926
|
-
continue;
|
|
927
|
-
}
|
|
928
|
-
routeSegments.push({
|
|
929
|
-
type: "static",
|
|
930
|
-
value: segment
|
|
931
|
-
});
|
|
932
|
-
}
|
|
933
|
-
return routeSegments;
|
|
934
|
-
}
|
|
935
|
-
async function directoryExists(dirPath) {
|
|
936
|
-
const fs = await import("node:fs/promises");
|
|
937
|
-
try {
|
|
938
|
-
const stat = await fs.stat(dirPath);
|
|
939
|
-
return stat.isDirectory();
|
|
940
|
-
} catch {
|
|
941
|
-
return false;
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
function getRouteDirectoryCandidate(cwd, config) {
|
|
945
|
-
const routesConfig = config.files?.routes;
|
|
946
|
-
if (routesConfig === false) {
|
|
947
|
-
return null;
|
|
948
|
-
}
|
|
949
|
-
const dir = routesConfig?.dir ?? DEFAULT_ROUTE_DIR;
|
|
950
|
-
return {
|
|
951
|
-
dir,
|
|
952
|
-
absoluteDir: resolve2(cwd, dir),
|
|
953
|
-
prefix: normalizeRoutePrefix(routesConfig?.prefix)
|
|
954
|
-
};
|
|
955
|
-
}
|
|
956
|
-
async function discoverRoutes(cwd, config) {
|
|
957
|
-
const routeDirectory = getRouteDirectoryCandidate(cwd, config);
|
|
958
|
-
if (!routeDirectory) {
|
|
959
|
-
return null;
|
|
960
|
-
}
|
|
961
|
-
if (!await directoryExists(routeDirectory.absoluteDir)) {
|
|
962
|
-
return null;
|
|
963
|
-
}
|
|
964
|
-
const prefixSegments = createStaticSegmentsFromPrefix(routeDirectory.prefix);
|
|
965
|
-
const files = await findFiles(DEFAULT_ROUTE_FILE_PATTERNS, {
|
|
966
|
-
cwd: routeDirectory.absoluteDir,
|
|
967
|
-
absolute: true
|
|
968
|
-
});
|
|
969
|
-
const discoveredRoutes = [];
|
|
970
|
-
const routeSignatures = new Map;
|
|
971
|
-
for (const absolutePath of files) {
|
|
972
|
-
const relativeToRouteDir = relative(routeDirectory.absoluteDir, absolutePath).replace(/\\/g, "/");
|
|
973
|
-
if (shouldIgnoreRouteFile(relativeToRouteDir)) {
|
|
974
|
-
continue;
|
|
975
|
-
}
|
|
976
|
-
const segments = parseRouteSegments(relativeToRouteDir, prefixSegments);
|
|
977
|
-
const routePath = toRoutePath(segments);
|
|
978
|
-
const filePath = relative(cwd, absolutePath).replace(/\\/g, "/");
|
|
979
|
-
const signature = getRouteSignature(segments);
|
|
980
|
-
const existingFilePath = routeSignatures.get(signature);
|
|
981
|
-
if (existingFilePath) {
|
|
982
|
-
throw new Error(`Conflicting file routes detected for "${routePath}". Both "${existingFilePath}" and "${filePath}" resolve to the same route.`);
|
|
983
|
-
}
|
|
984
|
-
routeSignatures.set(signature, filePath);
|
|
985
|
-
discoveredRoutes.push({
|
|
986
|
-
absolutePath,
|
|
987
|
-
filePath,
|
|
988
|
-
routePath,
|
|
989
|
-
segments
|
|
990
|
-
});
|
|
991
|
-
}
|
|
992
|
-
if (discoveredRoutes.length === 0) {
|
|
993
|
-
return null;
|
|
994
|
-
}
|
|
995
|
-
discoveredRoutes.sort(compareRoutes);
|
|
996
|
-
return {
|
|
997
|
-
dir: routeDirectory.dir,
|
|
998
|
-
absoluteDir: routeDirectory.absoluteDir,
|
|
999
|
-
prefix: routeDirectory.prefix,
|
|
1000
|
-
routes: discoveredRoutes
|
|
1001
|
-
};
|
|
1002
|
-
}
|
|
1003
|
-
|
|
1004
|
-
// src/worker-entry/surface-paths.ts
|
|
1005
|
-
import { resolve as resolve3 } from "pathe";
|
|
1006
|
-
var defaultEntriesFor = (surface) => SUPPORTED_WORKER_EXTENSIONS.map((ext) => `src/${surface}${ext}`);
|
|
1007
|
-
var DEFAULT_FETCH_ENTRY_FILES = defaultEntriesFor("fetch");
|
|
1008
|
-
var DEFAULT_QUEUE_ENTRY_FILES = defaultEntriesFor("queue");
|
|
1009
|
-
var DEFAULT_SCHEDULED_ENTRY_FILES = defaultEntriesFor("scheduled");
|
|
1010
|
-
var DEFAULT_EMAIL_ENTRY_FILES = defaultEntriesFor("email");
|
|
1011
|
-
var DEFAULT_TAIL_ENTRY_FILES = defaultEntriesFor("tail");
|
|
1012
|
-
var BUILD_OUTPUT_PATH_PREFIXES = [
|
|
1013
|
-
".svelte-kit/",
|
|
1014
|
-
".adapter-cloudflare/",
|
|
1015
|
-
".next/",
|
|
1016
|
-
".nuxt/",
|
|
1017
|
-
".output/",
|
|
1018
|
-
".vercel/",
|
|
1019
|
-
"dist/",
|
|
1020
|
-
"build/",
|
|
1021
|
-
".vinxi/",
|
|
1022
|
-
".solid/"
|
|
1023
|
-
];
|
|
1024
|
-
function looksLikeBuildArtifactPath(configuredPath) {
|
|
1025
|
-
const normalised = configuredPath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
1026
|
-
return BUILD_OUTPUT_PATH_PREFIXES.some((prefix) => normalised.startsWith(prefix));
|
|
1027
|
-
}
|
|
1028
|
-
async function resolveWorkerHandlerPath(cwd, configuredPath, defaultEntries, surfaceName = "worker") {
|
|
1029
|
-
if (configuredPath === false) {
|
|
1030
|
-
return null;
|
|
1031
|
-
}
|
|
1032
|
-
const fs = await import("node:fs/promises");
|
|
1033
|
-
if (typeof configuredPath === "string" && configuredPath) {
|
|
1034
|
-
const absolutePath = resolve3(cwd, configuredPath);
|
|
1035
|
-
try {
|
|
1036
|
-
await fs.access(absolutePath);
|
|
1037
|
-
return absolutePath;
|
|
1038
|
-
} catch {
|
|
1039
|
-
if (looksLikeBuildArtifactPath(configuredPath)) {
|
|
1040
|
-
throw new Error(`Configured ${surfaceName} handler "${configuredPath}" was not found.
|
|
1041
|
-
|
|
1042
|
-
This path looks like a framework build output (e.g. SvelteKit / Vite / Next).
|
|
1043
|
-
Devflare resolves handler paths BEFORE your framework runs its build, so the file
|
|
1044
|
-
does not exist yet at this stage.
|
|
1045
|
-
|
|
1046
|
-
` + `Recommended fix — point devflare at the build artifact via wrangler passthrough
|
|
1047
|
-
` + `instead of files.${surfaceName}, so devflare skips composition and lets your
|
|
1048
|
-
framework write the worker entry that wrangler/vite then picks up:
|
|
1049
|
-
|
|
1050
|
-
files: { ${surfaceName}: false },
|
|
1051
|
-
wrangler: {
|
|
1052
|
-
passthrough: { main: '${configuredPath}' }
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
Alternatively, run your framework build (e.g. \`vite build\`) before \`devflare build\`,
|
|
1056
|
-
or move the handler to a source file that exists at config time.`);
|
|
1057
|
-
}
|
|
1058
|
-
throw new Error(`Configured ${surfaceName} handler "${configuredPath}" was not found`);
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
for (const defaultEntry of defaultEntries) {
|
|
1062
|
-
const absolutePath = resolve3(cwd, defaultEntry);
|
|
1063
|
-
try {
|
|
1064
|
-
await fs.access(absolutePath);
|
|
1065
|
-
return absolutePath;
|
|
1066
|
-
} catch {}
|
|
1067
|
-
}
|
|
1068
|
-
return null;
|
|
1069
|
-
}
|
|
1070
|
-
async function resolveWorkerSurfacePaths(cwd, config) {
|
|
1071
|
-
return {
|
|
1072
|
-
fetch: await resolveWorkerHandlerPath(cwd, config.files?.fetch, DEFAULT_FETCH_ENTRY_FILES, "fetch"),
|
|
1073
|
-
queue: await resolveWorkerHandlerPath(cwd, config.files?.queue, DEFAULT_QUEUE_ENTRY_FILES, "queue"),
|
|
1074
|
-
scheduled: await resolveWorkerHandlerPath(cwd, config.files?.scheduled, DEFAULT_SCHEDULED_ENTRY_FILES, "scheduled"),
|
|
1075
|
-
email: await resolveWorkerHandlerPath(cwd, config.files?.email, DEFAULT_EMAIL_ENTRY_FILES, "email"),
|
|
1076
|
-
tail: await resolveWorkerHandlerPath(cwd, config.files?.tail, DEFAULT_TAIL_ENTRY_FILES, "tail")
|
|
1077
|
-
};
|
|
1078
|
-
}
|
|
1079
|
-
function hasWorkerSurfacePaths(surfacePaths) {
|
|
1080
|
-
return Object.values(surfacePaths).some((surfacePath) => typeof surfacePath === "string" && surfacePath.length > 0);
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
// src/worker-entry/composed-worker.ts
|
|
1084
|
-
class CodeBuilder {
|
|
1085
|
-
sections = [];
|
|
1086
|
-
importStatement(specifiers, from) {
|
|
1087
|
-
this.sections.push(`import { ${specifiers.join(", ")} } from '${from}'`);
|
|
1088
|
-
return this;
|
|
1089
|
-
}
|
|
1090
|
-
importNamespace(identifier, from) {
|
|
1091
|
-
this.sections.push(`import * as ${identifier} from '${from}'`);
|
|
1092
|
-
return this;
|
|
1093
|
-
}
|
|
1094
|
-
reExport(names, from) {
|
|
1095
|
-
this.sections.push(`export { ${names.join(", ")} } from '${from}'`);
|
|
1096
|
-
return this;
|
|
1097
|
-
}
|
|
1098
|
-
constDeclaration(name, value) {
|
|
1099
|
-
this.sections.push(`const ${name} = ${value}`);
|
|
1100
|
-
return this;
|
|
1101
|
-
}
|
|
1102
|
-
classDeclaration(body) {
|
|
1103
|
-
this.sections.push(body);
|
|
1104
|
-
return this;
|
|
1105
|
-
}
|
|
1106
|
-
exportDefault(body) {
|
|
1107
|
-
this.sections.push(`export default ${body}`);
|
|
1108
|
-
return this;
|
|
1109
|
-
}
|
|
1110
|
-
raw(text) {
|
|
1111
|
-
this.sections.push(text);
|
|
1112
|
-
return this;
|
|
1113
|
-
}
|
|
1114
|
-
blank() {
|
|
1115
|
-
this.sections.push("");
|
|
1116
|
-
return this;
|
|
1117
|
-
}
|
|
1118
|
-
toString() {
|
|
1119
|
-
return this.sections.join(`
|
|
1120
|
-
`);
|
|
1121
|
-
}
|
|
1122
|
-
}
|
|
1123
|
-
var DEV_ONLY_EMAIL_HOOKS_SOURCE = `
|
|
1124
|
-
function __devflareCreateEmailHeaders(rawBody) {
|
|
1125
|
-
const headers = new Headers()
|
|
1126
|
-
const lines = rawBody.split(/\\r?\\n/)
|
|
1127
|
-
|
|
1128
|
-
for (const line of lines) {
|
|
1129
|
-
if (line.trim() === '') {
|
|
1130
|
-
break
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
|
-
const colonIndex = line.indexOf(':')
|
|
1134
|
-
if (colonIndex <= 0) {
|
|
1135
|
-
continue
|
|
1136
|
-
}
|
|
1137
|
-
|
|
1138
|
-
headers.append(line.slice(0, colonIndex).trim(), line.slice(colonIndex + 1).trim())
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
return headers
|
|
1142
|
-
}
|
|
1143
|
-
|
|
1144
|
-
function __devflareCreateEmailRawStream(rawBody) {
|
|
1145
|
-
return new ReadableStream({
|
|
1146
|
-
start(controller) {
|
|
1147
|
-
controller.enqueue(new TextEncoder().encode(rawBody))
|
|
1148
|
-
controller.close()
|
|
1149
|
-
}
|
|
1150
|
-
})
|
|
1151
|
-
}
|
|
1152
|
-
|
|
1153
|
-
async function __devflareHandleInternalEmail(request, env, ctx) {
|
|
1154
|
-
if (!__devflareEmailHandler) {
|
|
1155
|
-
return new Response('Email handler not configured', { status: 501 })
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
const from = request.headers.get('x-devflare-email-from') || 'unknown@example.com'
|
|
1159
|
-
const to = request.headers.get('x-devflare-email-to') || 'worker@example.com'
|
|
1160
|
-
const rawBody = await request.text()
|
|
1161
|
-
const emailMessage = {
|
|
1162
|
-
from,
|
|
1163
|
-
to,
|
|
1164
|
-
headers: __devflareCreateEmailHeaders(rawBody),
|
|
1165
|
-
raw: __devflareCreateEmailRawStream(rawBody),
|
|
1166
|
-
rawSize: rawBody.length,
|
|
1167
|
-
setReject(reason) {
|
|
1168
|
-
console.warn('[Devflare email rejected]', reason)
|
|
1169
|
-
},
|
|
1170
|
-
async forward(rcptTo) {
|
|
1171
|
-
console.log('[Devflare email forwarded]', rcptTo)
|
|
1172
|
-
return Promise.resolve()
|
|
1173
|
-
},
|
|
1174
|
-
async reply(message) {
|
|
1175
|
-
console.log('[Devflare email reply sent]', message?.from)
|
|
1176
|
-
return Promise.resolve()
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
const __devflareEvent = createEmailEvent(emailMessage, env, ctx)
|
|
1181
|
-
|
|
1182
|
-
await runWithEventContext(
|
|
1183
|
-
__devflareEvent,
|
|
1184
|
-
() => __devflareEmailHandler(__devflareEvent, env, ctx)
|
|
1185
|
-
)
|
|
1186
|
-
|
|
1187
|
-
return new Response(JSON.stringify({ ok: true, from, to }), {
|
|
1188
|
-
headers: { 'Content-Type': 'application/json' }
|
|
1189
|
-
})
|
|
1190
|
-
}
|
|
1191
|
-
`;
|
|
1192
|
-
function emitDevOnlyEmailHooks(builder, options) {
|
|
1193
|
-
if (!options.enabled) {
|
|
1194
|
-
return;
|
|
1195
|
-
}
|
|
1196
|
-
builder.raw(DEV_ONLY_EMAIL_HOOKS_SOURCE);
|
|
1197
|
-
}
|
|
1198
|
-
var RESOLVE_HANDLER_DECLARATION = `const __devflareResolveHandler = (module, namedExport) => {
|
|
1199
|
-
const defaultExport = module.default
|
|
1200
|
-
|
|
1201
|
-
if (typeof defaultExport === 'function') {
|
|
1202
|
-
return defaultExport
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
if (defaultExport && typeof defaultExport[namedExport] === 'function') {
|
|
1206
|
-
return defaultExport[namedExport].bind(defaultExport)
|
|
1207
|
-
}
|
|
1208
|
-
|
|
1209
|
-
if (typeof module[namedExport] === 'function') {
|
|
1210
|
-
return module[namedExport]
|
|
1211
|
-
}
|
|
1212
|
-
|
|
1213
|
-
return null
|
|
1214
|
-
}`;
|
|
1215
|
-
function buildDefaultExportBody(options) {
|
|
1216
|
-
const devOnlyEmailEntry = options.includeDevOnlyHooks ? `const url = new URL(request.url)
|
|
1217
|
-
|
|
1218
|
-
if (
|
|
1219
|
-
request.headers.get('x-devflare-event') === 'email'
|
|
1220
|
-
&& url.pathname === '/_devflare/internal/email'
|
|
1221
|
-
) {
|
|
1222
|
-
return __devflareHandleInternalEmail(request, env, ctx)
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
|
-
` : "";
|
|
1226
|
-
return `{
|
|
1227
|
-
...(${options.hasFetchDispatch ? "true" : "false"}
|
|
1228
|
-
? {
|
|
1229
|
-
async fetch(request, env, ctx) {
|
|
1230
|
-
${devOnlyEmailEntry}const __devflareInitialRouteMatch = __devflareHasRoutes ? matchFetchRoute(__devflareRoutes, request) : null
|
|
1231
|
-
const __devflareEvent = createFetchEvent(request, env, ctx, {
|
|
1232
|
-
params: __devflareInitialRouteMatch?.params ?? {}
|
|
1233
|
-
})
|
|
1234
|
-
return runWithEventContext(
|
|
1235
|
-
__devflareEvent,
|
|
1236
|
-
() => invokeFetchModule(
|
|
1237
|
-
__devflareFetchModule,
|
|
1238
|
-
__devflareEvent,
|
|
1239
|
-
__devflareHasRoutes
|
|
1240
|
-
? createRouteResolve(__devflareRoutes, __devflareEvent)
|
|
1241
|
-
: undefined
|
|
1242
|
-
)
|
|
1243
|
-
)
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
: {}),
|
|
1247
|
-
...(__devflareQueueHandler
|
|
1248
|
-
? {
|
|
1249
|
-
async queue(batch, env, ctx) {
|
|
1250
|
-
assertExplicitQueueHandlerStyle(__devflareQueueHandler)
|
|
1251
|
-
const __devflareEvent = createQueueEvent(batch, env, ctx)
|
|
1252
|
-
return runWithEventContext(
|
|
1253
|
-
__devflareEvent,
|
|
1254
|
-
() => __devflareQueueHandler(__devflareEvent, env, ctx)
|
|
1255
|
-
)
|
|
1256
|
-
}
|
|
1257
|
-
}
|
|
1258
|
-
: {}),
|
|
1259
|
-
...(__devflareScheduledHandler
|
|
1260
|
-
? {
|
|
1261
|
-
async scheduled(controller, env, ctx) {
|
|
1262
|
-
assertExplicitScheduledHandlerStyle(__devflareScheduledHandler)
|
|
1263
|
-
const __devflareEvent = createScheduledEvent(controller, env, ctx)
|
|
1264
|
-
return runWithEventContext(
|
|
1265
|
-
__devflareEvent,
|
|
1266
|
-
() => __devflareScheduledHandler(__devflareEvent, env, ctx)
|
|
1267
|
-
)
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
1270
|
-
: {}),
|
|
1271
|
-
...(__devflareEmailHandler
|
|
1272
|
-
? {
|
|
1273
|
-
async email(message, env, ctx) {
|
|
1274
|
-
const __devflareEvent = createEmailEvent(message, env, ctx)
|
|
1275
|
-
return runWithEventContext(
|
|
1276
|
-
__devflareEvent,
|
|
1277
|
-
() => __devflareEmailHandler(__devflareEvent, env, ctx)
|
|
1278
|
-
)
|
|
1279
|
-
}
|
|
1280
|
-
}
|
|
1281
|
-
: {}),
|
|
1282
|
-
...(__devflareTailHandler
|
|
1283
|
-
? {
|
|
1284
|
-
async tail(events, env, ctx) {
|
|
1285
|
-
const __devflareEvent = createTailEvent(events, env, ctx)
|
|
1286
|
-
return runWithEventContext(
|
|
1287
|
-
__devflareEvent,
|
|
1288
|
-
() => __devflareTailHandler.length >= 2
|
|
1289
|
-
? __devflareTailHandler(events, env, ctx)
|
|
1290
|
-
: __devflareTailHandler(__devflareEvent, env, ctx)
|
|
1291
|
-
)
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
: {})
|
|
1295
|
-
}`;
|
|
1296
|
-
}
|
|
1297
|
-
function getComposedWorkerEntrypointSource(surfaceImportPaths, configuredLocalSendEmailBindings = {}, durableObjectExports = [], routeImports = [], options = {}) {
|
|
1298
|
-
const includeDevOnlyHooks = options.includeDevOnlyHooks ?? options.devInternalEmail === true;
|
|
1299
|
-
const importsBuilder = new CodeBuilder;
|
|
1300
|
-
importsBuilder.importStatement([
|
|
1301
|
-
"assertExplicitQueueHandlerStyle",
|
|
1302
|
-
"assertExplicitScheduledHandlerStyle",
|
|
1303
|
-
"createEmailEvent",
|
|
1304
|
-
"createFetchEvent",
|
|
1305
|
-
"createQueueEvent",
|
|
1306
|
-
"createRouteResolve",
|
|
1307
|
-
"createScheduledEvent",
|
|
1308
|
-
"createTailEvent",
|
|
1309
|
-
"invokeFetchModule",
|
|
1310
|
-
"matchFetchRoute",
|
|
1311
|
-
"runWithEventContext",
|
|
1312
|
-
"setLocalSendEmailBindings"
|
|
1313
|
-
], "devflare/runtime");
|
|
1314
|
-
const fallbackModules = [
|
|
1315
|
-
{ identifier: "__devflareFetchModule", importPath: surfaceImportPaths.fetch },
|
|
1316
|
-
{ identifier: "__devflareQueueModule", importPath: surfaceImportPaths.queue },
|
|
1317
|
-
{ identifier: "__devflareScheduledModule", importPath: surfaceImportPaths.scheduled },
|
|
1318
|
-
{ identifier: "__devflareEmailModule", importPath: surfaceImportPaths.email },
|
|
1319
|
-
{ identifier: "__devflareTailModule", importPath: surfaceImportPaths.tail }
|
|
1320
|
-
];
|
|
1321
|
-
const fallbacksBuilder = new CodeBuilder;
|
|
1322
|
-
for (const { identifier, importPath } of fallbackModules) {
|
|
1323
|
-
if (importPath) {
|
|
1324
|
-
importsBuilder.importNamespace(identifier, importPath);
|
|
1325
|
-
} else {
|
|
1326
|
-
fallbacksBuilder.constDeclaration(identifier, "{}");
|
|
1327
|
-
}
|
|
1328
|
-
}
|
|
1329
|
-
for (const routeImport of routeImports) {
|
|
1330
|
-
importsBuilder.importNamespace(routeImport.identifier, routeImport.importPath);
|
|
1331
|
-
}
|
|
1332
|
-
const reExportsBuilder = new CodeBuilder;
|
|
1333
|
-
for (const { classNames, importPath } of durableObjectExports) {
|
|
1334
|
-
reExportsBuilder.reExport(classNames, importPath);
|
|
1335
|
-
}
|
|
1336
|
-
const routeManifestEntries = routeImports.map(({ identifier, filePath, routePath, segmentsJson }) => {
|
|
1337
|
-
return ` { filePath: ${JSON.stringify(filePath)}, routePath: ${JSON.stringify(routePath)}, segments: ${segmentsJson}, module: ${identifier} }`;
|
|
1338
|
-
});
|
|
1339
|
-
const builder = new CodeBuilder;
|
|
1340
|
-
builder.raw(importsBuilder.toString());
|
|
1341
|
-
builder.raw(fallbacksBuilder.toString());
|
|
1342
|
-
builder.raw(reExportsBuilder.toString());
|
|
1343
|
-
builder.blank();
|
|
1344
|
-
builder.raw(`setLocalSendEmailBindings(${JSON.stringify(configuredLocalSendEmailBindings)})`);
|
|
1345
|
-
builder.blank();
|
|
1346
|
-
builder.constDeclaration("__devflareHasFetchModule", surfaceImportPaths.fetch ? "true" : "false");
|
|
1347
|
-
builder.raw(`const __devflareRoutes = [
|
|
1348
|
-
${routeManifestEntries.join(`,
|
|
1349
|
-
`)}
|
|
1350
|
-
]`);
|
|
1351
|
-
builder.constDeclaration("__devflareHasRoutes", "__devflareRoutes.length > 0");
|
|
1352
|
-
builder.blank();
|
|
1353
|
-
builder.raw(RESOLVE_HANDLER_DECLARATION);
|
|
1354
|
-
builder.blank();
|
|
1355
|
-
builder.constDeclaration("__devflareQueueHandler", "__devflareResolveHandler(__devflareQueueModule, 'queue')");
|
|
1356
|
-
builder.constDeclaration("__devflareScheduledHandler", "__devflareResolveHandler(__devflareScheduledModule, 'scheduled')");
|
|
1357
|
-
builder.constDeclaration("__devflareEmailHandler", "__devflareResolveHandler(__devflareEmailModule, 'email')");
|
|
1358
|
-
builder.constDeclaration("__devflareTailHandler", "__devflareResolveHandler(__devflareTailModule, 'tail')");
|
|
1359
|
-
emitDevOnlyEmailHooks(builder, { enabled: includeDevOnlyHooks });
|
|
1360
|
-
builder.blank();
|
|
1361
|
-
builder.exportDefault(buildDefaultExportBody({
|
|
1362
|
-
hasFetchDispatch: Boolean(surfaceImportPaths.fetch) || routeImports.length > 0 || includeDevOnlyHooks,
|
|
1363
|
-
includeDevOnlyHooks
|
|
1364
|
-
}));
|
|
1365
|
-
builder.raw("");
|
|
1366
|
-
return builder.toString();
|
|
1367
|
-
}
|
|
1368
|
-
function toImportSpecifier(fromFilePath, toFilePath) {
|
|
1369
|
-
const specifier = relative2(dirname2(fromFilePath), toFilePath).replace(/\\/g, "/");
|
|
1370
|
-
return specifier.startsWith(".") ? specifier : `./${specifier}`;
|
|
1371
|
-
}
|
|
1372
|
-
function createGeneratedRouteModuleImports(entryPath, routeDiscovery) {
|
|
1373
|
-
if (!routeDiscovery) {
|
|
1374
|
-
return [];
|
|
1375
|
-
}
|
|
1376
|
-
return routeDiscovery.routes.map((route, index) => ({
|
|
1377
|
-
identifier: `__devflareRouteModule${index}`,
|
|
1378
|
-
importPath: toImportSpecifier(entryPath, route.absolutePath),
|
|
1379
|
-
filePath: route.filePath,
|
|
1380
|
-
routePath: route.routePath,
|
|
1381
|
-
segmentsJson: JSON.stringify(route.segments)
|
|
1382
|
-
}));
|
|
1383
|
-
}
|
|
1384
|
-
async function createGeneratedDurableObjectExports(entryPath, cwd, config) {
|
|
1385
|
-
if (config.files?.durableObjects === false || !config.bindings?.durableObjects) {
|
|
1386
|
-
return [];
|
|
1387
|
-
}
|
|
1388
|
-
const localClassNames = new Set(Object.values(config.bindings.durableObjects).map((binding) => normalizeDOBinding(binding)).filter((binding) => binding.kind === "local").map((binding) => binding.className));
|
|
1389
|
-
if (localClassNames.size === 0) {
|
|
1390
|
-
return [];
|
|
1391
|
-
}
|
|
1392
|
-
const pattern = typeof config.files?.durableObjects === "string" ? config.files.durableObjects : DEFAULT_DO_PATTERN;
|
|
1393
|
-
const discoveredFiles = await discoverDurableObjectFiles(cwd, pattern);
|
|
1394
|
-
const exports = [];
|
|
1395
|
-
const discoveredClassNames = new Set;
|
|
1396
|
-
for (const [filePath, allClassNames] of discoveredFiles) {
|
|
1397
|
-
const classNames = allClassNames.filter((className) => localClassNames.has(className));
|
|
1398
|
-
if (classNames.length === 0) {
|
|
1399
|
-
continue;
|
|
1400
|
-
}
|
|
1401
|
-
for (const className of classNames) {
|
|
1402
|
-
discoveredClassNames.add(className);
|
|
1403
|
-
}
|
|
1404
|
-
exports.push({
|
|
1405
|
-
importPath: toImportSpecifier(entryPath, filePath),
|
|
1406
|
-
filePath,
|
|
1407
|
-
classNames
|
|
1408
|
-
});
|
|
1409
|
-
}
|
|
1410
|
-
const missingClassNames = Array.from(localClassNames).filter((className) => !discoveredClassNames.has(className));
|
|
1411
|
-
if (missingClassNames.length > 0) {
|
|
1412
|
-
throw new Error(`Failed to discover local Durable Object class${missingClassNames.length === 1 ? "" : "es"} ${missingClassNames.join(", ")} for worker composition. ` + `Ensure files.durableObjects matches the source file pattern for your do.* files.`);
|
|
1413
|
-
}
|
|
1414
|
-
return exports;
|
|
1415
|
-
}
|
|
1416
|
-
function mayRequireCompositionBesidesFetch(config) {
|
|
1417
|
-
const files = config.files ?? {};
|
|
1418
|
-
if (typeof files.queue === "string" && files.queue)
|
|
1419
|
-
return true;
|
|
1420
|
-
if (typeof files.scheduled === "string" && files.scheduled)
|
|
1421
|
-
return true;
|
|
1422
|
-
if (typeof files.email === "string" && files.email)
|
|
1423
|
-
return true;
|
|
1424
|
-
if (typeof files.tail === "string" && files.tail)
|
|
1425
|
-
return true;
|
|
1426
|
-
if (files.durableObjects)
|
|
1427
|
-
return true;
|
|
1428
|
-
if (files.routes)
|
|
1429
|
-
return true;
|
|
1430
|
-
const bindings = config.bindings ?? {};
|
|
1431
|
-
const doBindings = bindings.durableObjects;
|
|
1432
|
-
if (doBindings && Object.keys(doBindings).length > 0)
|
|
1433
|
-
return true;
|
|
1434
|
-
const sendEmail = bindings.sendEmail;
|
|
1435
|
-
if (sendEmail && Object.keys(sendEmail).length > 0)
|
|
1436
|
-
return true;
|
|
1437
|
-
return false;
|
|
1438
|
-
}
|
|
1439
|
-
function needsComposedWorkerEntrypoint(cwd, surfacePaths, config, routeDiscovery) {
|
|
1440
|
-
const hasAdditionalWorkerSurfaces = Boolean(surfacePaths.queue || surfacePaths.scheduled || surfacePaths.email || surfacePaths.tail || routeDiscovery?.routes.length);
|
|
1441
|
-
if (hasAdditionalWorkerSurfaces) {
|
|
1442
|
-
return true;
|
|
1443
|
-
}
|
|
1444
|
-
if (!surfacePaths.fetch) {
|
|
1445
|
-
return false;
|
|
1446
|
-
}
|
|
1447
|
-
const assetsDirectory = config.assets?.directory;
|
|
1448
|
-
if (assetsDirectory) {
|
|
1449
|
-
const generatedAssetsWorkerPath = resolve4(cwd, assetsDirectory, "_worker.js");
|
|
1450
|
-
if (surfacePaths.fetch === generatedAssetsWorkerPath) {
|
|
1451
|
-
return false;
|
|
1452
|
-
}
|
|
1453
|
-
}
|
|
1454
|
-
return Boolean(surfacePaths.fetch);
|
|
1455
|
-
}
|
|
1456
|
-
async function prepareComposedWorkerEntrypoint(cwd, config, environment, options = {}) {
|
|
1457
|
-
const resolvedConfig = resolveConfigForEnvironment(config, environment);
|
|
1458
|
-
if (resolvedConfig.wrangler?.passthrough && Object.prototype.hasOwnProperty.call(resolvedConfig.wrangler.passthrough, "main")) {
|
|
1459
|
-
return null;
|
|
1460
|
-
}
|
|
1461
|
-
const configuredFetch = resolvedConfig.files?.fetch;
|
|
1462
|
-
if (typeof configuredFetch === "string" && looksLikeBuildArtifactPath(configuredFetch)) {
|
|
1463
|
-
const fs2 = await import("node:fs/promises");
|
|
1464
|
-
const fetchAbsolute = resolve4(cwd, configuredFetch);
|
|
1465
|
-
let fetchExists = true;
|
|
1466
|
-
try {
|
|
1467
|
-
await fs2.access(fetchAbsolute);
|
|
1468
|
-
} catch {
|
|
1469
|
-
fetchExists = false;
|
|
1470
|
-
}
|
|
1471
|
-
if (!fetchExists && !mayRequireCompositionBesidesFetch(resolvedConfig)) {
|
|
1472
|
-
return null;
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
|
-
const surfacePaths = await resolveWorkerSurfacePaths(cwd, resolvedConfig);
|
|
1476
|
-
const routeDiscovery = await discoverRoutes(cwd, resolvedConfig);
|
|
1477
|
-
if (!needsComposedWorkerEntrypoint(cwd, surfacePaths, resolvedConfig, routeDiscovery)) {
|
|
1478
|
-
return null;
|
|
1479
|
-
}
|
|
1480
|
-
const fs = await import("node:fs/promises");
|
|
1481
|
-
const entryDir = resolve4(cwd, ".devflare", "worker-entrypoints");
|
|
1482
|
-
const entryPath = resolve4(entryDir, "main.ts");
|
|
1483
|
-
await fs.mkdir(entryDir, { recursive: true });
|
|
1484
|
-
const surfaceImportPaths = {
|
|
1485
|
-
fetch: surfacePaths.fetch ? toImportSpecifier(entryPath, surfacePaths.fetch) : null,
|
|
1486
|
-
queue: surfacePaths.queue ? toImportSpecifier(entryPath, surfacePaths.queue) : null,
|
|
1487
|
-
scheduled: surfacePaths.scheduled ? toImportSpecifier(entryPath, surfacePaths.scheduled) : null,
|
|
1488
|
-
email: surfacePaths.email ? toImportSpecifier(entryPath, surfacePaths.email) : null,
|
|
1489
|
-
tail: surfacePaths.tail ? toImportSpecifier(entryPath, surfacePaths.tail) : null
|
|
1490
|
-
};
|
|
1491
|
-
const durableObjectExports = await createGeneratedDurableObjectExports(entryPath, cwd, resolvedConfig);
|
|
1492
|
-
const routeImports = createGeneratedRouteModuleImports(entryPath, routeDiscovery);
|
|
1493
|
-
await fs.writeFile(entryPath, getComposedWorkerEntrypointSource(surfaceImportPaths, resolvedConfig.bindings?.sendEmail ?? {}, durableObjectExports, routeImports, options));
|
|
1494
|
-
return entryPath;
|
|
1495
|
-
}
|
|
1496
|
-
|
|
1497
|
-
// src/vite/plugin-durable-objects.ts
|
|
1498
|
-
var VIRTUAL_DO_ENTRY = "virtual:devflare-do-entry";
|
|
1499
|
-
var RESOLVED_VIRTUAL_DO_ENTRY = "\x00" + VIRTUAL_DO_ENTRY;
|
|
1500
|
-
function generateVirtualDOEntry(discovery) {
|
|
1501
|
-
const lines = [
|
|
1502
|
-
"// Auto-generated by devflare — DO entry module",
|
|
1503
|
-
"// Re-exports all Durable Object classes discovered from files.durableObjects pattern",
|
|
1504
|
-
""
|
|
1505
|
-
];
|
|
1506
|
-
for (const [filePath, classNames] of discovery.files) {
|
|
1507
|
-
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
1508
|
-
lines.push(`export { ${classNames.join(", ")} } from '${normalizedPath}'`);
|
|
1509
|
-
}
|
|
1510
|
-
lines.push("");
|
|
1511
|
-
lines.push("// Default fetch handler for DO worker");
|
|
1512
|
-
lines.push("export default {");
|
|
1513
|
-
lines.push("\tasync fetch(request: Request): Promise<Response> {");
|
|
1514
|
-
lines.push('\t\treturn new Response("Devflare DO Worker", { status: 200 })');
|
|
1515
|
-
lines.push("\t}");
|
|
1516
|
-
lines.push("}");
|
|
1517
|
-
return lines.join(`
|
|
1518
|
-
`);
|
|
1519
|
-
}
|
|
1520
|
-
function createAuxiliaryWorkerConfig(wranglerConfig, discovery) {
|
|
1521
|
-
const doBindings = wranglerConfig.durable_objects?.bindings?.map((binding) => ({
|
|
1522
|
-
name: binding.name,
|
|
1523
|
-
class_name: binding.class_name
|
|
1524
|
-
})) ?? [];
|
|
1525
|
-
return {
|
|
1526
|
-
config: {
|
|
1527
|
-
name: discovery.workerName,
|
|
1528
|
-
main: VIRTUAL_DO_ENTRY,
|
|
1529
|
-
compatibility_date: wranglerConfig.compatibility_date,
|
|
1530
|
-
compatibility_flags: wranglerConfig.compatibility_flags,
|
|
1531
|
-
durable_objects: { bindings: doBindings },
|
|
1532
|
-
migrations: wranglerConfig.migrations,
|
|
1533
|
-
kv_namespaces: wranglerConfig.kv_namespaces,
|
|
1534
|
-
d1_databases: wranglerConfig.d1_databases,
|
|
1535
|
-
r2_buckets: wranglerConfig.r2_buckets,
|
|
1536
|
-
browser: wranglerConfig.browser
|
|
1537
|
-
}
|
|
1538
|
-
};
|
|
1539
|
-
}
|
|
1540
|
-
function logDiscoveredDurableObjects(projectRoot, discovery) {
|
|
1541
|
-
if (!discovery || discovery.files.size === 0) {
|
|
1542
|
-
return;
|
|
1543
|
-
}
|
|
1544
|
-
console.log(`[devflare] Discovered ${discovery.files.size} DO file(s):`);
|
|
1545
|
-
for (const [filePath, classes] of discovery.files) {
|
|
1546
|
-
console.log(` • ${filePath.replace(projectRoot, ".")} → ${classes.join(", ")}`);
|
|
1547
|
-
}
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
// src/vite/plugin-service-bindings.ts
|
|
1551
|
-
var VIRTUAL_SERVICE_WORKER_PREFIX = "virtual:devflare-service-worker/";
|
|
1552
|
-
var RESOLVED_VIRTUAL_SERVICE_WORKER_PREFIX = "\x00" + VIRTUAL_SERVICE_WORKER_PREFIX;
|
|
1553
|
-
function virtualServiceWorkerId(workerName) {
|
|
1554
|
-
return `${VIRTUAL_SERVICE_WORKER_PREFIX}${encodeURIComponent(workerName)}`;
|
|
1555
|
-
}
|
|
1556
|
-
function resolvedVirtualServiceWorkerId(workerName) {
|
|
1557
|
-
return `${RESOLVED_VIRTUAL_SERVICE_WORKER_PREFIX}${encodeURIComponent(workerName)}`;
|
|
1558
|
-
}
|
|
1559
|
-
function objectEntries(record) {
|
|
1560
|
-
return record ? Object.entries(record) : [];
|
|
1561
|
-
}
|
|
1562
|
-
function toWranglerDurableObjectBinding(name, value) {
|
|
1563
|
-
if (typeof value === "string") {
|
|
1564
|
-
return { name, class_name: value };
|
|
1565
|
-
}
|
|
1566
|
-
return {
|
|
1567
|
-
name,
|
|
1568
|
-
class_name: value.className,
|
|
1569
|
-
script_name: value.scriptName
|
|
1570
|
-
};
|
|
1571
|
-
}
|
|
1572
|
-
function toWranglerWorkerConfig(worker) {
|
|
1573
|
-
const queueProducers = worker.queueProducers ? objectEntries(worker.queueProducers).map(([binding, producer]) => ({
|
|
1574
|
-
binding,
|
|
1575
|
-
queue: producer.queueName
|
|
1576
|
-
})) : undefined;
|
|
1577
|
-
const queueConsumers = worker.queueConsumers ? objectEntries(worker.queueConsumers).map(([queue, consumer]) => ({
|
|
1578
|
-
queue,
|
|
1579
|
-
...consumer.maxBatchSize !== undefined && {
|
|
1580
|
-
max_batch_size: consumer.maxBatchSize
|
|
1581
|
-
},
|
|
1582
|
-
...consumer.maxBatchTimeout !== undefined && {
|
|
1583
|
-
max_batch_timeout: consumer.maxBatchTimeout
|
|
1584
|
-
},
|
|
1585
|
-
...consumer.maxRetries !== undefined && { max_retries: consumer.maxRetries },
|
|
1586
|
-
...typeof consumer.deadLetterQueue === "string" && {
|
|
1587
|
-
dead_letter_queue: consumer.deadLetterQueue
|
|
1588
|
-
},
|
|
1589
|
-
...consumer.maxConcurrency !== undefined && {
|
|
1590
|
-
max_concurrency: consumer.maxConcurrency
|
|
1591
|
-
},
|
|
1592
|
-
...consumer.retryDelay !== undefined && { retry_delay: consumer.retryDelay }
|
|
1593
|
-
})) : undefined;
|
|
1594
|
-
const queues = queueProducers || queueConsumers ? {
|
|
1595
|
-
...queueProducers && { producers: queueProducers },
|
|
1596
|
-
...queueConsumers && { consumers: queueConsumers }
|
|
1597
|
-
} : undefined;
|
|
1598
|
-
const durableObjectBindings = worker.durableObjects ? objectEntries(worker.durableObjects).map(([name, value]) => toWranglerDurableObjectBinding(name, value)) : [];
|
|
1599
|
-
const serviceBindings = worker.serviceBindings ? objectEntries(worker.serviceBindings).map(([binding, target]) => ({
|
|
1600
|
-
binding,
|
|
1601
|
-
service: target.name,
|
|
1602
|
-
...target.entrypoint && { entrypoint: target.entrypoint }
|
|
1603
|
-
})) : [];
|
|
1604
|
-
const config = {
|
|
1605
|
-
name: worker.name,
|
|
1606
|
-
main: virtualServiceWorkerId(worker.name),
|
|
1607
|
-
compatibility_date: worker.compatibilityDate,
|
|
1608
|
-
...worker.compatibilityFlags && { compatibility_flags: worker.compatibilityFlags },
|
|
1609
|
-
...worker.bindings && { vars: worker.bindings },
|
|
1610
|
-
...worker.kvNamespaces && {
|
|
1611
|
-
kv_namespaces: objectEntries(worker.kvNamespaces).map(([binding, id]) => ({
|
|
1612
|
-
binding,
|
|
1613
|
-
id
|
|
1614
|
-
}))
|
|
1615
|
-
},
|
|
1616
|
-
...worker.r2Buckets && {
|
|
1617
|
-
r2_buckets: objectEntries(worker.r2Buckets).map(([binding, bucket_name]) => ({
|
|
1618
|
-
binding,
|
|
1619
|
-
bucket_name
|
|
1620
|
-
}))
|
|
1621
|
-
},
|
|
1622
|
-
...worker.d1Databases && {
|
|
1623
|
-
d1_databases: objectEntries(worker.d1Databases).map(([binding, database_id]) => ({
|
|
1624
|
-
binding,
|
|
1625
|
-
database_id,
|
|
1626
|
-
database_name: database_id
|
|
1627
|
-
}))
|
|
1628
|
-
},
|
|
1629
|
-
...durableObjectBindings.length > 0 && {
|
|
1630
|
-
durable_objects: {
|
|
1631
|
-
bindings: durableObjectBindings
|
|
1632
|
-
}
|
|
1633
|
-
},
|
|
1634
|
-
...serviceBindings.length > 0 && {
|
|
1635
|
-
services: serviceBindings
|
|
1636
|
-
},
|
|
1637
|
-
...queues && { queues }
|
|
1638
|
-
};
|
|
1639
|
-
return config;
|
|
1640
|
-
}
|
|
1641
|
-
function createAuxiliaryServiceWorkerConfigs(resolution) {
|
|
1642
|
-
if (!resolution || resolution.workers.length === 0) {
|
|
1643
|
-
return { auxiliaryWorkers: [], virtualModules: new Map };
|
|
1644
|
-
}
|
|
1645
|
-
const virtualModules = new Map;
|
|
1646
|
-
const auxiliaryWorkers = resolution.workers.map((worker) => {
|
|
1647
|
-
virtualModules.set(resolvedVirtualServiceWorkerId(worker.name), worker.script);
|
|
1648
|
-
return {
|
|
1649
|
-
config: toWranglerWorkerConfig(worker)
|
|
1650
|
-
};
|
|
1651
|
-
});
|
|
1652
|
-
return { auxiliaryWorkers, virtualModules };
|
|
1653
|
-
}
|
|
1654
|
-
|
|
1655
|
-
// src/vite/plugin-context.ts
|
|
1656
|
-
var CONFIG_DIR = ".devflare";
|
|
1657
|
-
function removeDevflareHandledServeBindings(config) {
|
|
1658
|
-
const next = { ...config };
|
|
1659
|
-
delete next.workflows;
|
|
1660
|
-
delete next.media;
|
|
1661
|
-
return next;
|
|
1662
|
-
}
|
|
1663
|
-
async function buildPluginContextState(projectRoot, devflareConfig, environment, mode = "serve", configDir = projectRoot) {
|
|
1664
|
-
const resourceResolvedConfig = mode === "build" ? await resolveResources(devflareConfig, { phase: "build", environment }) : await resolveResources(devflareConfig, { phase: "local", environment });
|
|
1665
|
-
const effectiveConfig = await resolveConfigEnvVars(resourceResolvedConfig, {
|
|
1666
|
-
cwd: configDir,
|
|
1667
|
-
mode: mode === "build" ? "build" : "dev"
|
|
1668
|
-
});
|
|
1669
|
-
const compiledWranglerConfig = mode === "build" ? compileBuildConfig(effectiveConfig) : compileConfig(effectiveConfig);
|
|
1670
|
-
const wranglerConfig = mode === "build" ? isolateViteBuildOutputPaths(projectRoot, compiledWranglerConfig) : removeDevflareHandledServeBindings(compiledWranglerConfig);
|
|
1671
|
-
const cloudflareConfig = {
|
|
1672
|
-
...mode === "build" ? isolateViteBuildOutputPaths(projectRoot, compileToProgrammaticConfig(effectiveConfig, environment, {
|
|
1673
|
-
preserveNamedBindings: true
|
|
1674
|
-
})) : removeDevflareHandledServeBindings(compileToProgrammaticConfig(effectiveConfig, environment))
|
|
1675
|
-
};
|
|
1676
|
-
const composedMainEntry = mode === "build" ? null : await prepareComposedWorkerEntrypoint(projectRoot, effectiveConfig, environment);
|
|
1677
|
-
if (composedMainEntry) {
|
|
1678
|
-
const relativeMain = relative3(projectRoot, composedMainEntry);
|
|
1679
|
-
wranglerConfig.main = relativeMain;
|
|
1680
|
-
cloudflareConfig.main = relativeMain;
|
|
1681
|
-
}
|
|
1682
|
-
let durableObjects = null;
|
|
1683
|
-
let auxiliaryWorkerConfig = null;
|
|
1684
|
-
let serviceWorkerVirtualModules = new Map;
|
|
1685
|
-
let serviceAuxiliaryWorkerConfigs = [];
|
|
1686
|
-
const doPatternConfig = effectiveConfig.files?.durableObjects;
|
|
1687
|
-
const doPattern = typeof doPatternConfig === "string" ? doPatternConfig : DEFAULT_DO_PATTERN;
|
|
1688
|
-
if (doPatternConfig !== false) {
|
|
1689
|
-
const doWorkerName = `${wranglerConfig.name}-do`;
|
|
1690
|
-
const discovery = await discoverDurableObjects(projectRoot, doPattern, doWorkerName);
|
|
1691
|
-
if (discovery.files.size > 0) {
|
|
1692
|
-
durableObjects = discovery;
|
|
1693
|
-
if (wranglerConfig.durable_objects?.bindings) {
|
|
1694
|
-
for (const binding of wranglerConfig.durable_objects.bindings) {
|
|
1695
|
-
binding.script_name = doWorkerName;
|
|
1696
|
-
}
|
|
1697
|
-
}
|
|
1698
|
-
if (cloudflareConfig.durable_objects) {
|
|
1699
|
-
const doConfig = cloudflareConfig.durable_objects;
|
|
1700
|
-
for (const binding of doConfig.bindings) {
|
|
1701
|
-
binding.script_name = doWorkerName;
|
|
1702
|
-
}
|
|
1703
|
-
}
|
|
1704
|
-
auxiliaryWorkerConfig = createAuxiliaryWorkerConfig(wranglerConfig, discovery);
|
|
1705
|
-
}
|
|
1706
|
-
}
|
|
1707
|
-
if (mode === "serve" && effectiveConfig.bindings?.services) {
|
|
1708
|
-
const serviceBindingResolution = await resolveServiceBindings(effectiveConfig, configDir);
|
|
1709
|
-
const serviceWorkers = createAuxiliaryServiceWorkerConfigs(serviceBindingResolution);
|
|
1710
|
-
serviceAuxiliaryWorkerConfigs = serviceWorkers.auxiliaryWorkers;
|
|
1711
|
-
serviceWorkerVirtualModules = serviceWorkers.virtualModules;
|
|
1712
|
-
}
|
|
1713
|
-
const auxiliaryWorkerConfigs = [
|
|
1714
|
-
...auxiliaryWorkerConfig ? [auxiliaryWorkerConfig] : [],
|
|
1715
|
-
...serviceAuxiliaryWorkerConfigs
|
|
1716
|
-
];
|
|
1717
|
-
return {
|
|
1718
|
-
wranglerConfig,
|
|
1719
|
-
cloudflareConfig,
|
|
1720
|
-
auxiliaryWorkerConfigs,
|
|
1721
|
-
serviceWorkerVirtualModules,
|
|
1722
|
-
durableObjects,
|
|
1723
|
-
auxiliaryWorkerConfig
|
|
1724
|
-
};
|
|
1725
|
-
}
|
|
1726
|
-
async function ensureGeneratedConfigDir(projectRoot) {
|
|
1727
|
-
const configDir = resolve5(projectRoot, CONFIG_DIR);
|
|
1728
|
-
const fs = await import("node:fs/promises");
|
|
1729
|
-
await fs.mkdir(configDir, { recursive: true });
|
|
1730
|
-
const gitignorePath = resolve5(configDir, ".gitignore");
|
|
1731
|
-
try {
|
|
1732
|
-
await fs.access(gitignorePath);
|
|
1733
|
-
} catch {
|
|
1734
|
-
await fs.writeFile(gitignorePath, `*
|
|
1735
|
-
`, "utf-8");
|
|
1736
|
-
}
|
|
1737
|
-
return configDir;
|
|
1738
|
-
}
|
|
1739
|
-
async function writeGeneratedWranglerConfig(projectRoot, wranglerConfig) {
|
|
1740
|
-
const configDir = await ensureGeneratedConfigDir(projectRoot);
|
|
1741
|
-
const wranglerFileConfig = rebaseWranglerConfigPaths(projectRoot, configDir, wranglerConfig);
|
|
1742
|
-
await writeWranglerConfig(configDir, wranglerFileConfig, "wrangler.jsonc");
|
|
1743
|
-
}
|
|
1744
|
-
async function resolvePluginConfigPath(projectRoot, configPath) {
|
|
1745
|
-
if (configPath) {
|
|
1746
|
-
return isAbsolute(configPath) ? configPath : resolve5(projectRoot, configPath);
|
|
1747
|
-
}
|
|
1748
|
-
return await resolveConfigPath(projectRoot) ?? null;
|
|
1749
|
-
}
|
|
1750
|
-
|
|
1751
|
-
// src/vite/plugin-transform.ts
|
|
1752
|
-
var TRANSFORMABLE_EXTENSIONS = [".ts", ".tsx", ".js"];
|
|
1753
|
-
function isTransformCandidate(id) {
|
|
1754
|
-
if (id.includes("node_modules"))
|
|
1755
|
-
return false;
|
|
1756
|
-
return TRANSFORMABLE_EXTENSIONS.some((ext) => id.endsWith(ext));
|
|
1757
|
-
}
|
|
1758
|
-
async function runWorkerEntryTransform(code, id) {
|
|
1759
|
-
if (!id.endsWith("worker.ts") && !id.endsWith("worker.js")) {
|
|
1760
|
-
return null;
|
|
1761
|
-
}
|
|
1762
|
-
const { shouldTransformWorker, transformWorkerEntrypoint: transformWorkerEntrypoint2 } = await import("./worker-entrypoint-y8s9kdcx.js");
|
|
1763
|
-
if (!shouldTransformWorker(code, id)) {
|
|
1764
|
-
return null;
|
|
1765
|
-
}
|
|
1766
|
-
const result = transformWorkerEntrypoint2(code, id);
|
|
1767
|
-
if (!result)
|
|
1768
|
-
return null;
|
|
1769
|
-
return {
|
|
1770
|
-
code: result.code,
|
|
1771
|
-
map: result.map
|
|
1772
|
-
};
|
|
1773
|
-
}
|
|
1774
|
-
async function runDurableObjectTransform(code, id, options) {
|
|
1775
|
-
if (!options.doTransforms)
|
|
1776
|
-
return null;
|
|
1777
|
-
if (!code.includes("DurableObject") && !code.includes("@durableObject")) {
|
|
1778
|
-
return null;
|
|
1779
|
-
}
|
|
1780
|
-
const { transformDurableObject } = await import("./durable-object-0ybmg08a.js");
|
|
1781
|
-
return transformDurableObject(code, id);
|
|
1782
|
-
}
|
|
1783
|
-
async function runDevflareTransform(code, id, options) {
|
|
1784
|
-
if (!isTransformCandidate(id))
|
|
1785
|
-
return null;
|
|
1786
|
-
const workerResult = await runWorkerEntryTransform(code, id);
|
|
1787
|
-
if (workerResult)
|
|
1788
|
-
return workerResult;
|
|
1789
|
-
return await runDurableObjectTransform(code, id, options);
|
|
1790
|
-
}
|
|
1791
|
-
|
|
1792
|
-
// src/vite/plugin.ts
|
|
1793
|
-
var CONFIG_DIR2 = ".devflare";
|
|
1794
|
-
function createPluginState() {
|
|
1795
|
-
return {
|
|
1796
|
-
context: {
|
|
1797
|
-
wranglerConfig: null,
|
|
1798
|
-
cloudflareConfig: null,
|
|
1799
|
-
projectRoot: process.cwd(),
|
|
1800
|
-
auxiliaryWorkerConfig: null,
|
|
1801
|
-
auxiliaryWorkerConfigs: [],
|
|
1802
|
-
serviceWorkerVirtualModules: new Map,
|
|
1803
|
-
durableObjects: null
|
|
1804
|
-
},
|
|
1805
|
-
projectRoot: process.cwd(),
|
|
1806
|
-
devflareConfig: null,
|
|
1807
|
-
resolvedPluginConfigPath: null
|
|
1808
|
-
};
|
|
1809
|
-
}
|
|
1810
|
-
async function loadAndApplyConfig(state, options, mode, onContextUpdated) {
|
|
1811
|
-
state.devflareConfig = await loadConfig({
|
|
1812
|
-
cwd: state.projectRoot,
|
|
1813
|
-
configFile: options.configPath
|
|
1814
|
-
});
|
|
1815
|
-
const pluginState = await buildPluginContextState(state.projectRoot, state.devflareConfig, options.environment, mode, state.resolvedPluginConfigPath ? dirname3(state.resolvedPluginConfigPath) : state.projectRoot);
|
|
1816
|
-
Object.assign(state.context, {
|
|
1817
|
-
projectRoot: state.projectRoot,
|
|
1818
|
-
...pluginState
|
|
1819
|
-
});
|
|
1820
|
-
onContextUpdated(state.context);
|
|
1821
|
-
logDiscoveredDurableObjects(state.projectRoot, pluginState.durableObjects);
|
|
1822
|
-
await writeGeneratedWranglerConfig(state.projectRoot, pluginState.wranglerConfig);
|
|
1823
|
-
}
|
|
1824
|
-
var lastPluginContext = createPluginState().context;
|
|
1825
|
-
function devflarePlugin(options = {}) {
|
|
1826
|
-
const {
|
|
1827
|
-
configPath,
|
|
1828
|
-
environment,
|
|
1829
|
-
doTransforms = true,
|
|
1830
|
-
watchConfig = true,
|
|
1831
|
-
bridgePort = process.env.DEVFLARE_BRIDGE_PORT ? Number.parseInt(process.env.DEVFLARE_BRIDGE_PORT, 10) : undefined,
|
|
1832
|
-
wsProxyPatterns = []
|
|
1833
|
-
} = options;
|
|
1834
|
-
const state = createPluginState();
|
|
1835
|
-
return {
|
|
1836
|
-
name: "devflare",
|
|
1837
|
-
enforce: "pre",
|
|
1838
|
-
async config(config, { command }) {
|
|
1839
|
-
const cwd = config.root ?? process.cwd();
|
|
1840
|
-
return buildPluginConfigHookResult(cwd, { configPath, bridgePort, wsProxyPatterns }, command, config.define ?? {});
|
|
1841
|
-
},
|
|
1842
|
-
resolveId(id) {
|
|
1843
|
-
if (id === VIRTUAL_DO_ENTRY) {
|
|
1844
|
-
return RESOLVED_VIRTUAL_DO_ENTRY;
|
|
1845
|
-
}
|
|
1846
|
-
if (id.startsWith(VIRTUAL_SERVICE_WORKER_PREFIX)) {
|
|
1847
|
-
return "\x00" + id;
|
|
1848
|
-
}
|
|
1849
|
-
return null;
|
|
1850
|
-
},
|
|
1851
|
-
async load(id) {
|
|
1852
|
-
if (id === RESOLVED_VIRTUAL_DO_ENTRY) {
|
|
1853
|
-
if (!state.context.durableObjects) {
|
|
1854
|
-
return `// No Durable Objects configured
|
|
1855
|
-
export default { fetch: () => new Response("No DOs") }`;
|
|
1856
|
-
}
|
|
1857
|
-
return generateVirtualDOEntry(state.context.durableObjects);
|
|
1858
|
-
}
|
|
1859
|
-
if (id.startsWith(RESOLVED_VIRTUAL_SERVICE_WORKER_PREFIX)) {
|
|
1860
|
-
return state.context.serviceWorkerVirtualModules.get(id) ?? null;
|
|
1861
|
-
}
|
|
1862
|
-
return null;
|
|
1863
|
-
},
|
|
1864
|
-
async configResolved(config) {
|
|
1865
|
-
state.projectRoot = config.root;
|
|
1866
|
-
state.context.projectRoot = state.projectRoot;
|
|
1867
|
-
state.resolvedPluginConfigPath = await resolvePluginConfigPath(state.projectRoot, configPath);
|
|
1868
|
-
try {
|
|
1869
|
-
await loadAndApplyConfig(state, { configPath, environment }, config.command === "build" ? "build" : "serve", (ctx) => {
|
|
1870
|
-
lastPluginContext = ctx;
|
|
1871
|
-
});
|
|
1872
|
-
if (config.command === "serve") {
|
|
1873
|
-
console.log("[devflare] Config generated to .devflare/wrangler.jsonc");
|
|
1874
|
-
if (state.context.auxiliaryWorkerConfig) {
|
|
1875
|
-
console.log("[devflare] ✓ Auxiliary DO worker configured");
|
|
1876
|
-
}
|
|
1877
|
-
}
|
|
1878
|
-
if (config.command === "build") {
|
|
1879
|
-
console.log(`[devflare] Generated ${CONFIG_DIR2}/wrangler.jsonc`);
|
|
1880
|
-
}
|
|
1881
|
-
} catch (error) {
|
|
1882
|
-
if (error instanceof Error) {
|
|
1883
|
-
console.error("[devflare] Config error:", error.message);
|
|
1884
|
-
}
|
|
1885
|
-
throw error;
|
|
1886
|
-
}
|
|
1887
|
-
},
|
|
1888
|
-
configureServer(server) {
|
|
1889
|
-
if (!watchConfig)
|
|
1890
|
-
return;
|
|
1891
|
-
const fullConfigPath = state.resolvedPluginConfigPath ?? resolve6(state.projectRoot, configPath || "devflare.config.ts");
|
|
1892
|
-
server.watcher.add(fullConfigPath);
|
|
1893
|
-
server.watcher.on("change", async (changedPath) => {
|
|
1894
|
-
if (changedPath === fullConfigPath) {
|
|
1895
|
-
console.log("[devflare] Config changed, reloading...");
|
|
1896
|
-
try {
|
|
1897
|
-
await loadAndApplyConfig(state, { configPath, environment }, "serve", (ctx) => {
|
|
1898
|
-
lastPluginContext = ctx;
|
|
1899
|
-
});
|
|
1900
|
-
console.log("[devflare] Config reloaded");
|
|
1901
|
-
server.ws.send({
|
|
1902
|
-
type: "full-reload",
|
|
1903
|
-
path: "*"
|
|
1904
|
-
});
|
|
1905
|
-
} catch (error) {
|
|
1906
|
-
console.error("[devflare] Failed to reload config:", error);
|
|
1907
|
-
}
|
|
1908
|
-
}
|
|
1909
|
-
});
|
|
1910
|
-
},
|
|
1911
|
-
async transform(code, id) {
|
|
1912
|
-
return runDevflareTransform(code, id, { doTransforms });
|
|
1913
|
-
}
|
|
1914
|
-
};
|
|
1915
|
-
}
|
|
1916
|
-
|
|
1917
|
-
// src/vite/config-file.ts
|
|
1918
|
-
var CONFIG_DIR3 = ".devflare";
|
|
1919
|
-
var GENERATED_VITE_CONFIG_FILENAME = "vite.config.mjs";
|
|
1920
|
-
function hasInlineViteConfig(viteConfig) {
|
|
1921
|
-
return Boolean(viteConfig && Object.keys(viteConfig).length > 0);
|
|
1922
|
-
}
|
|
1923
|
-
function resolveEffectiveViteProject(detection, config, environment) {
|
|
1924
|
-
const resolvedConfig = resolveConfigForEnvironment(config, environment);
|
|
1925
|
-
const hasDevflareConfig = hasInlineViteConfig(resolvedConfig.vite);
|
|
1926
|
-
return {
|
|
1927
|
-
...detection,
|
|
1928
|
-
hasDevflareViteConfig: hasDevflareConfig,
|
|
1929
|
-
shouldStartVite: detection.shouldStartVite || hasDevflareConfig,
|
|
1930
|
-
wantsViteIntegration: detection.wantsViteIntegration || hasDevflareConfig
|
|
1931
|
-
};
|
|
1932
|
-
}
|
|
1933
|
-
function isPromiseLike(value) {
|
|
1934
|
-
return (typeof value === "object" || typeof value === "function") && value !== null && typeof value.then === "function";
|
|
1935
|
-
}
|
|
1936
|
-
function normalizePluginOptions(pluginOption) {
|
|
1937
|
-
if (typeof pluginOption === "undefined") {
|
|
1938
|
-
return [];
|
|
1939
|
-
}
|
|
1940
|
-
return Array.isArray(pluginOption) ? pluginOption : [pluginOption];
|
|
1941
|
-
}
|
|
1942
|
-
function removePluginByName(pluginOption, pluginName) {
|
|
1943
|
-
if (Array.isArray(pluginOption)) {
|
|
1944
|
-
const filteredPlugins = pluginOption.map((nestedPlugin) => removePluginByName(nestedPlugin, pluginName)).filter((nestedPlugin) => typeof nestedPlugin !== "undefined");
|
|
1945
|
-
return filteredPlugins.length > 0 ? filteredPlugins : undefined;
|
|
1946
|
-
}
|
|
1947
|
-
if (!pluginOption || typeof pluginOption === "boolean" || isPromiseLike(pluginOption)) {
|
|
1948
|
-
return pluginOption;
|
|
1949
|
-
}
|
|
1950
|
-
return pluginOption.name === pluginName ? undefined : pluginOption;
|
|
1951
|
-
}
|
|
1952
|
-
function withInjectedDevflarePlugin(config, pluginOptions) {
|
|
1953
|
-
const existingPlugins = normalizePluginOptions(config.plugins).map((pluginOption) => removePluginByName(pluginOption, "devflare")).filter((pluginOption) => typeof pluginOption !== "undefined");
|
|
1954
|
-
return {
|
|
1955
|
-
...config,
|
|
1956
|
-
plugins: [devflarePlugin(pluginOptions), ...existingPlugins]
|
|
1957
|
-
};
|
|
1958
|
-
}
|
|
1959
|
-
async function resolveViteUserConfig(configEnv, options = {}) {
|
|
1960
|
-
const { loadConfigFromFile, mergeConfig } = await import("vite");
|
|
1961
|
-
const cwd = options.cwd ?? process.cwd();
|
|
1962
|
-
const devflareConfig = await loadConfig({
|
|
1963
|
-
cwd,
|
|
1964
|
-
configFile: options.configPath
|
|
1965
|
-
});
|
|
1966
|
-
const resolvedDevflareConfig = resolveConfigForEnvironment(devflareConfig, options.environment);
|
|
1967
|
-
const inlineViteConfig = resolvedDevflareConfig.vite ?? {};
|
|
1968
|
-
const localConfig = options.localConfigPath ? (await loadConfigFromFile(configEnv, options.localConfigPath, cwd))?.config ?? {} : {};
|
|
1969
|
-
const mergedConfig = mergeConfig(localConfig, inlineViteConfig);
|
|
1970
|
-
const normalizedConfig = mergedConfig.root ? mergedConfig : {
|
|
1971
|
-
...mergedConfig,
|
|
1972
|
-
root: cwd
|
|
1973
|
-
};
|
|
1974
|
-
return withInjectedDevflarePlugin(normalizedConfig, {
|
|
1975
|
-
configPath: options.configPath,
|
|
1976
|
-
environment: options.environment,
|
|
1977
|
-
bridgePort: options.bridgePort
|
|
1978
|
-
});
|
|
1979
|
-
}
|
|
1980
|
-
async function ensureGeneratedConfigDir2(cwd) {
|
|
1981
|
-
const fs = await import("node:fs/promises");
|
|
1982
|
-
const { resolve: resolve7 } = await import("pathe");
|
|
1983
|
-
const configDir = resolve7(cwd, CONFIG_DIR3);
|
|
1984
|
-
await fs.mkdir(configDir, { recursive: true });
|
|
1985
|
-
const gitignorePath = resolve7(configDir, ".gitignore");
|
|
1986
|
-
try {
|
|
1987
|
-
await fs.access(gitignorePath);
|
|
1988
|
-
} catch {
|
|
1989
|
-
await fs.writeFile(gitignorePath, `*
|
|
1990
|
-
`, "utf-8");
|
|
1991
|
-
}
|
|
1992
|
-
return configDir;
|
|
1993
|
-
}
|
|
1994
|
-
async function resolveDevflarePackageRoot(currentFilePath) {
|
|
1995
|
-
const fs = await import("node:fs/promises");
|
|
1996
|
-
const { dirname: dirname4, resolve: resolve7 } = await import("pathe");
|
|
1997
|
-
let currentDir = dirname4(currentFilePath);
|
|
1998
|
-
while (true) {
|
|
1999
|
-
const packageJsonPath = resolve7(currentDir, "package.json");
|
|
2000
|
-
try {
|
|
2001
|
-
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8"));
|
|
2002
|
-
if (packageJson.name === "devflare") {
|
|
2003
|
-
return currentDir;
|
|
2004
|
-
}
|
|
2005
|
-
} catch {}
|
|
2006
|
-
const parentDir = dirname4(currentDir);
|
|
2007
|
-
if (parentDir === currentDir) {
|
|
2008
|
-
break;
|
|
2009
|
-
}
|
|
2010
|
-
currentDir = parentDir;
|
|
2011
|
-
}
|
|
2012
|
-
throw new Error("Could not resolve the devflare package root for generated Vite config imports.");
|
|
2013
|
-
}
|
|
2014
|
-
async function resolveGeneratedViteImportPath(configDir) {
|
|
2015
|
-
const { fileURLToPath } = await import("node:url");
|
|
2016
|
-
const { extname, normalize, relative: relative4, resolve: resolve7 } = await import("pathe");
|
|
2017
|
-
const currentFilePath = normalize(fileURLToPath(import.meta.url));
|
|
2018
|
-
const currentExtension = extname(currentFilePath);
|
|
2019
|
-
const packageRoot = await resolveDevflarePackageRoot(currentFilePath);
|
|
2020
|
-
const viteEntryPath = currentFilePath.includes("/dist/") ? resolve7(packageRoot, "dist/vite/index.js") : resolve7(packageRoot, `src/vite/index${currentExtension}`);
|
|
2021
|
-
const relativeImportPath = relative4(configDir, viteEntryPath);
|
|
2022
|
-
return relativeImportPath.startsWith(".") ? relativeImportPath : `./${relativeImportPath}`;
|
|
2023
|
-
}
|
|
2024
|
-
async function writeGeneratedViteConfig(options) {
|
|
2025
|
-
const fs = await import("node:fs/promises");
|
|
2026
|
-
const { resolve: resolve7 } = await import("pathe");
|
|
2027
|
-
const configDir = await ensureGeneratedConfigDir2(options.cwd);
|
|
2028
|
-
const generatedConfigPath = resolve7(configDir, GENERATED_VITE_CONFIG_FILENAME);
|
|
2029
|
-
const viteImportPath = await resolveGeneratedViteImportPath(configDir);
|
|
2030
|
-
const content = `import { defineConfig } from 'vite'
|
|
2031
|
-
import { resolveViteUserConfig } from ${JSON.stringify(viteImportPath)}
|
|
2032
|
-
|
|
2033
|
-
export default defineConfig(async (env) => {
|
|
2034
|
-
return await resolveViteUserConfig(env, {
|
|
2035
|
-
cwd: ${JSON.stringify(options.cwd)},
|
|
2036
|
-
configPath: ${JSON.stringify(options.configPath)},
|
|
2037
|
-
environment: ${JSON.stringify(options.environment)},
|
|
2038
|
-
localConfigPath: ${JSON.stringify(options.localConfigPath)},
|
|
2039
|
-
bridgePort: ${JSON.stringify(options.bridgePort)}
|
|
2040
|
-
})
|
|
2041
|
-
})
|
|
2042
|
-
`;
|
|
2043
|
-
await fs.writeFile(generatedConfigPath, content, "utf-8");
|
|
2044
|
-
return generatedConfigPath;
|
|
2045
|
-
}
|
|
2046
|
-
export { discoverDurableObjectFiles, buildQueueProducers, buildQueueConsumers, buildRateLimitsConfig, buildVersionMetadataConfig, buildWorkerLoadersConfig, buildMtlsCertificatesConfig, buildDispatchNamespacesConfig, buildWorkflowsConfig, buildPipelinesConfig, buildHyperdrivesConfig, buildImagesConfig, buildMediaConfig, buildArtifactsConfig, buildAiSearchNamespacesConfig, buildAiSearchInstancesConfig, buildSecretsStoreConfig, buildSendEmailConfig, resolveServiceBindings, getRouteDirectoryCandidate, discoverRoutes, DEFAULT_FETCH_ENTRY_FILES, DEFAULT_QUEUE_ENTRY_FILES, DEFAULT_SCHEDULED_ENTRY_FILES, DEFAULT_EMAIL_ENTRY_FILES, resolveWorkerSurfacePaths, hasWorkerSurfacePaths, prepareComposedWorkerEntrypoint, hasInlineViteConfig, resolveEffectiveViteProject, resolveViteUserConfig, writeGeneratedViteConfig, devflarePlugin2 as devflarePlugin, getPluginContext, getCloudflareConfig, getDevflareConfigs, devflarePlugin3 as devflarePlugin1 };
|