devflare 1.0.0-next.20 → 1.0.0-next.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LLM.md +9 -4
- package/README.md +10 -2
- package/dist/bridge/gateway-runtime.d.ts +1 -1
- package/dist/bridge/gateway-runtime.d.ts.map +1 -1
- package/dist/bridge/proxy.d.ts +2 -0
- package/dist/bridge/proxy.d.ts.map +1 -1
- package/dist/bridge/server.d.ts.map +1 -1
- package/dist/browser.js +3 -3
- package/dist/build-b1z6wqet.js +54 -0
- package/dist/build-qsgnme4z.js +54 -0
- package/dist/build-x7maz3eb.js +54 -0
- package/dist/cli/commands/config.d.ts.map +1 -1
- package/dist/cli/commands/dev.d.ts +1 -0
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/help-pages/pages/core.d.ts.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/config-qj5jw8km.js +93 -0
- package/dist/deploy-jf3yczsz.js +1055 -0
- package/dist/deploy-nh5tbv45.js +1055 -0
- package/dist/deploy-xqm869nf.js +1055 -0
- package/dist/dev-bgpxrwms.js +2551 -0
- package/dist/dev-cme5de75.js +2551 -0
- package/dist/dev-kzs65xcr.js +2551 -0
- package/dist/dev-server/dev-server-state.d.ts +2 -0
- package/dist/dev-server/dev-server-state.d.ts.map +1 -1
- package/dist/dev-server/miniflare-dev-config.d.ts +4 -0
- package/dist/dev-server/miniflare-dev-config.d.ts.map +1 -1
- package/dist/dev-server/server.d.ts.map +1 -1
- package/dist/dev-zgx7fhe9.js +2553 -0
- package/dist/doctor-0a2brpyz.js +259 -0
- package/dist/index-05pbj4hy.js +1193 -0
- package/dist/index-35bmgpfw.js +573 -0
- package/dist/index-3edvz3hs.js +124 -0
- package/dist/index-4se6krdj.js +574 -0
- package/dist/index-50em8s6c.js +898 -0
- package/dist/index-666tdx14.js +895 -0
- package/dist/index-8p7rxkbs.js +1426 -0
- package/dist/index-aqrwyy57.js +288 -0
- package/dist/index-bj5avaba.js +109 -0
- package/dist/index-c1cj9085.js +2250 -0
- package/dist/index-dgww0ewn.js +574 -0
- package/dist/index-f1yshy4s.js +412 -0
- package/dist/index-hbxkmb1q.js +1426 -0
- package/dist/index-hpwa6vsw.js +239 -0
- package/dist/index-jwd3fanx.js +412 -0
- package/dist/index-kxc4gtyt.js +574 -0
- package/dist/index-nxkesg55.js +68 -0
- package/dist/index-p7q23nce.js +1031 -0
- package/dist/index-pt49cgjv.js +1426 -0
- package/dist/index-rp0aye39.js +1426 -0
- package/dist/index-s9q605sq.js +1033 -0
- package/dist/index-tknbyxzn.js +2202 -0
- package/dist/index-w36q6819.js +895 -0
- package/dist/index-xp0qkkxf.js +68 -0
- package/dist/index-zawn5tte.js +109 -0
- package/dist/index-zpy9caxn.js +1193 -0
- package/dist/index.js +4 -4
- package/dist/runtime/index.js +4 -4
- package/dist/sveltekit/index.js +5 -4
- package/dist/sveltekit/local-bindings.d.ts.map +1 -1
- package/dist/test/index.js +62 -440
- package/dist/test/resolve-service-bindings.d.ts +63 -3
- package/dist/test/resolve-service-bindings.d.ts.map +1 -1
- package/dist/types-vhvt4hvm.js +693 -0
- package/dist/utils/send-email.d.ts.map +1 -1
- package/dist/utils/send-email.js +1 -1
- package/dist/vite/index.js +4 -3
- package/dist/vite/plugin-context.d.ts +3 -1
- package/dist/vite/plugin-context.d.ts.map +1 -1
- package/dist/vite/plugin-programmatic.d.ts.map +1 -1
- package/dist/vite/plugin-service-bindings.d.ts +13 -0
- package/dist/vite/plugin-service-bindings.d.ts.map +1 -0
- package/dist/vite/plugin.d.ts +4 -2
- package/dist/vite/plugin.d.ts.map +1 -1
- package/dist/worker-entrypoint-3rmzd4c1.js +15 -0
- package/package.json +1 -1
package/dist/test/index.js
CHANGED
|
@@ -2,47 +2,41 @@ import {
|
|
|
2
2
|
getRemoteModeStatus,
|
|
3
3
|
isRemoteModeActive
|
|
4
4
|
} from "../index-d8bdkx2h.js";
|
|
5
|
-
import {
|
|
6
|
-
discoverEntrypointsSync
|
|
7
|
-
} from "../index-gj5qh491.js";
|
|
8
|
-
import {
|
|
9
|
-
resolvePackageSpecifier
|
|
10
|
-
} from "../index-t4fhcx1n.js";
|
|
11
5
|
import {
|
|
12
6
|
canProceedWithTest
|
|
13
7
|
} from "../index-15fpa5tx.js";
|
|
14
8
|
import {
|
|
15
|
-
transformWorkerEntrypoint
|
|
16
|
-
} from "../index-7k278fgz.js";
|
|
17
|
-
import {
|
|
18
|
-
buildHyperdrivesConfig,
|
|
19
9
|
bundleWorkflowEntrypointScript
|
|
20
|
-
} from "../index-
|
|
21
|
-
import"../index-
|
|
10
|
+
} from "../index-zawn5tte.js";
|
|
11
|
+
import"../index-w36q6819.js";
|
|
22
12
|
import {
|
|
23
13
|
createRouteResolve,
|
|
24
14
|
invokeFetchModule,
|
|
25
15
|
matchFetchRoute,
|
|
26
16
|
resolveFetchHandler
|
|
27
|
-
} from "../index-
|
|
17
|
+
} from "../index-jwd3fanx.js";
|
|
28
18
|
import {
|
|
29
19
|
__clearTestContext,
|
|
30
20
|
__setTestContext,
|
|
31
21
|
env
|
|
32
|
-
} from "../index-
|
|
22
|
+
} from "../index-xp0qkkxf.js";
|
|
33
23
|
import"../index-a855bdsx.js";
|
|
34
24
|
import {
|
|
35
|
-
|
|
36
|
-
|
|
25
|
+
buildHyperdrivesConfig,
|
|
26
|
+
clearBundleCache,
|
|
27
|
+
discoverRoutes,
|
|
28
|
+
hasCrossWorkerDOs,
|
|
29
|
+
hasServiceBindings,
|
|
30
|
+
resolveDOBindings,
|
|
31
|
+
resolveServiceBindings
|
|
32
|
+
} from "../index-s9q605sq.js";
|
|
33
|
+
import"../index-3edvz3hs.js";
|
|
37
34
|
import {
|
|
38
35
|
DEFAULT_DO_PATTERN,
|
|
39
|
-
findFiles
|
|
40
|
-
findFilesSync
|
|
36
|
+
findFiles
|
|
41
37
|
} from "../index-qwgr4q7s.js";
|
|
42
|
-
import"../index-
|
|
43
|
-
import
|
|
44
|
-
findDurableObjectClasses
|
|
45
|
-
} from "../index-vhqww6tt.js";
|
|
38
|
+
import"../index-aqrwyy57.js";
|
|
39
|
+
import"../index-vhqww6tt.js";
|
|
46
40
|
import {
|
|
47
41
|
createLocalWorkerLoaderBinding,
|
|
48
42
|
disposeLocalWorkerLoaderBindings,
|
|
@@ -66,11 +60,11 @@ import {
|
|
|
66
60
|
runWithContext,
|
|
67
61
|
runWithEventContext,
|
|
68
62
|
setBindingHints
|
|
69
|
-
} from "../index-
|
|
63
|
+
} from "../index-c1cj9085.js";
|
|
70
64
|
import {
|
|
71
65
|
createLocalSendEmailBinding,
|
|
72
66
|
wrapEnvSendEmailBindings
|
|
73
|
-
} from "../index-
|
|
67
|
+
} from "../index-hpwa6vsw.js";
|
|
74
68
|
import {
|
|
75
69
|
applyLocalDevVarsToConfig
|
|
76
70
|
} from "../index-c3nxftnp.js";
|
|
@@ -103,382 +97,10 @@ import {
|
|
|
103
97
|
__require
|
|
104
98
|
} from "../index-37x76zdn.js";
|
|
105
99
|
|
|
106
|
-
// src/test/resolve-service-bindings.ts
|
|
107
|
-
import { dirname, join, resolve } from "path";
|
|
108
|
-
import { existsSync, readFileSync } from "fs";
|
|
109
|
-
function getBunRuntime() {
|
|
110
|
-
const g = globalThis;
|
|
111
|
-
if (typeof g.Bun === "object" && g.Bun !== null) {
|
|
112
|
-
return g.Bun;
|
|
113
|
-
}
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
function discoverDOFilesSync(dir) {
|
|
117
|
-
const classToPath = new Map;
|
|
118
|
-
try {
|
|
119
|
-
const files = findFilesSync(DEFAULT_DO_PATTERN, { cwd: dir });
|
|
120
|
-
for (const filePath of files) {
|
|
121
|
-
try {
|
|
122
|
-
const code = readFileSync(filePath, "utf-8");
|
|
123
|
-
const classNames = findDurableObjectClasses(code);
|
|
124
|
-
for (const className of classNames) {
|
|
125
|
-
if (!classToPath.has(className)) {
|
|
126
|
-
classToPath.set(className, filePath);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
} catch {}
|
|
130
|
-
}
|
|
131
|
-
} catch {}
|
|
132
|
-
return classToPath;
|
|
133
|
-
}
|
|
134
|
-
var bundleCache = new Map;
|
|
135
|
-
function clearBundleCache() {
|
|
136
|
-
bundleCache.clear();
|
|
137
|
-
}
|
|
138
|
-
function findDefaultServiceWorkerEntrypoint(refConfigDir) {
|
|
139
|
-
for (const candidate of ["src/worker.ts", "src/worker.js"]) {
|
|
140
|
-
const absolutePath = resolve(refConfigDir, candidate);
|
|
141
|
-
if (existsSync(absolutePath)) {
|
|
142
|
-
return absolutePath;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
147
|
-
function hasServiceBindings(config) {
|
|
148
|
-
const services = config.bindings?.services;
|
|
149
|
-
if (!services)
|
|
150
|
-
return false;
|
|
151
|
-
return Object.keys(services).length > 0;
|
|
152
|
-
}
|
|
153
|
-
async function resolveServiceBindings(config, configDir) {
|
|
154
|
-
const services = config.bindings?.services;
|
|
155
|
-
if (!services) {
|
|
156
|
-
return { workers: [], primaryServiceBindings: {} };
|
|
157
|
-
}
|
|
158
|
-
const workersByName = new Map;
|
|
159
|
-
const primaryServiceBindings = {};
|
|
160
|
-
for (const [bindingName, binding] of Object.entries(services)) {
|
|
161
|
-
const workerBinding = binding;
|
|
162
|
-
const ref = workerBinding.__ref;
|
|
163
|
-
if (ref) {
|
|
164
|
-
if ("__import" in ref && typeof ref.__import === "function") {
|
|
165
|
-
await ref.resolve();
|
|
166
|
-
}
|
|
167
|
-
const workerName = ref.name;
|
|
168
|
-
const entrypoint = workerBinding.entrypoint;
|
|
169
|
-
if (!workersByName.has(workerName)) {
|
|
170
|
-
const worker = await resolveRefWorker(ref, entrypoint, configDir);
|
|
171
|
-
if (worker) {
|
|
172
|
-
workersByName.set(workerName, worker);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
primaryServiceBindings[bindingName] = {
|
|
176
|
-
name: workerName,
|
|
177
|
-
...entrypoint && { entrypoint }
|
|
178
|
-
};
|
|
179
|
-
} else {
|
|
180
|
-
primaryServiceBindings[bindingName] = {
|
|
181
|
-
name: workerBinding.service,
|
|
182
|
-
...workerBinding.entrypoint && { entrypoint: workerBinding.entrypoint }
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
return {
|
|
187
|
-
workers: [...workersByName.values()],
|
|
188
|
-
primaryServiceBindings
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
async function resolveRefWorker(ref, _entrypoint, parentConfigDir) {
|
|
192
|
-
const config = ref.config;
|
|
193
|
-
if (!config)
|
|
194
|
-
return null;
|
|
195
|
-
const configPath = ref.configPath;
|
|
196
|
-
if (!configPath || configPath === "<resolved>") {
|
|
197
|
-
console.warn(`[devflare] Cannot resolve worker "${ref.name}" - configPath not available`);
|
|
198
|
-
return null;
|
|
199
|
-
}
|
|
200
|
-
const refConfigDir = resolve(parentConfigDir, dirname(configPath));
|
|
201
|
-
const entrypoints = [];
|
|
202
|
-
const workerEntrypointPath = findDefaultServiceWorkerEntrypoint(refConfigDir);
|
|
203
|
-
if (workerEntrypointPath) {
|
|
204
|
-
entrypoints.push({
|
|
205
|
-
path: workerEntrypointPath,
|
|
206
|
-
className: "Worker",
|
|
207
|
-
isWorkerTs: true
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
if (config.files?.entrypoints !== false) {
|
|
211
|
-
const discoveredEntrypoints = discoverEntrypointsSync(refConfigDir, typeof config.files?.entrypoints === "string" ? config.files.entrypoints : undefined);
|
|
212
|
-
for (const ep of discoveredEntrypoints) {
|
|
213
|
-
entrypoints.push({
|
|
214
|
-
path: ep.filePath,
|
|
215
|
-
className: ep.className,
|
|
216
|
-
isWorkerTs: false
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
if (entrypoints.length === 0) {
|
|
221
|
-
console.warn(`[devflare] Worker "${ref.name}" has no entry points`);
|
|
222
|
-
return null;
|
|
223
|
-
}
|
|
224
|
-
const script = await bundleAllEntrypoints(entrypoints, ref.name);
|
|
225
|
-
if (!script)
|
|
226
|
-
return null;
|
|
227
|
-
return {
|
|
228
|
-
name: ref.name,
|
|
229
|
-
script,
|
|
230
|
-
modules: true,
|
|
231
|
-
compatibilityDate: config.compatibilityDate ?? "2025-01-01"
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
async function bundleAllEntrypoints(entrypoints, workerName) {
|
|
235
|
-
const cacheKey = entrypoints.map((ep) => `${ep.path}::${ep.className}`).join("|");
|
|
236
|
-
const cached = bundleCache.get(cacheKey);
|
|
237
|
-
if (cached) {
|
|
238
|
-
return cached;
|
|
239
|
-
}
|
|
240
|
-
const bun = getBunRuntime();
|
|
241
|
-
if (!bun) {
|
|
242
|
-
console.warn("[devflare] Bun runtime required for bundling worker scripts");
|
|
243
|
-
return null;
|
|
244
|
-
}
|
|
245
|
-
try {
|
|
246
|
-
const { readFileSync: readFileSync2, writeFileSync, mkdirSync, unlinkSync } = await import("fs");
|
|
247
|
-
const imports = [];
|
|
248
|
-
const exports = [];
|
|
249
|
-
let defaultExportClass = null;
|
|
250
|
-
for (let i = 0;i < entrypoints.length; i++) {
|
|
251
|
-
const ep = entrypoints[i];
|
|
252
|
-
const sourceCode = readFileSync2(ep.path, "utf-8");
|
|
253
|
-
if (ep.isWorkerTs) {
|
|
254
|
-
const result = transformWorkerEntrypoint(sourceCode, ep.path, {
|
|
255
|
-
className: ep.className,
|
|
256
|
-
injectContext: false
|
|
257
|
-
});
|
|
258
|
-
if (result) {
|
|
259
|
-
const tempDir2 = join(dirname(ep.path), ".devflare");
|
|
260
|
-
mkdirSync(tempDir2, { recursive: true });
|
|
261
|
-
const tempPath = join(tempDir2, `__${ep.className}_${i}.ts`);
|
|
262
|
-
writeFileSync(tempPath, result.code);
|
|
263
|
-
imports.push(`import { ${ep.className} } from '${tempPath.replace(/\\/g, "/")}'`);
|
|
264
|
-
exports.push(ep.className);
|
|
265
|
-
if (!defaultExportClass) {
|
|
266
|
-
defaultExportClass = ep.className;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
} else {
|
|
270
|
-
imports.push(`import { ${ep.className} } from '${ep.path.replace(/\\/g, "/")}'`);
|
|
271
|
-
exports.push(ep.className);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
const defaultExport = defaultExportClass ? `
|
|
275
|
-
export default ${defaultExportClass}` : "";
|
|
276
|
-
const entryCode = `
|
|
277
|
-
${imports.join(`
|
|
278
|
-
`)}
|
|
279
|
-
export { ${exports.join(", ")} }${defaultExport}
|
|
280
|
-
`;
|
|
281
|
-
const tempDir = join(dirname(entrypoints[0].path), ".devflare");
|
|
282
|
-
mkdirSync(tempDir, { recursive: true });
|
|
283
|
-
const entryPath = join(tempDir, `__entry_${workerName}.ts`);
|
|
284
|
-
writeFileSync(entryPath, entryCode);
|
|
285
|
-
try {
|
|
286
|
-
const result = await bun.build({
|
|
287
|
-
entrypoints: [entryPath],
|
|
288
|
-
target: "browser",
|
|
289
|
-
format: "esm",
|
|
290
|
-
minify: false,
|
|
291
|
-
external: ["cloudflare:workers", "cloudflare:*"]
|
|
292
|
-
});
|
|
293
|
-
if (!result.success) {
|
|
294
|
-
console.warn(`[devflare] Failed to bundle worker "${workerName}": ${result.logs.join(`
|
|
295
|
-
`)}`);
|
|
296
|
-
return null;
|
|
297
|
-
}
|
|
298
|
-
const bundledCode = await result.outputs[0].text();
|
|
299
|
-
bundleCache.set(cacheKey, bundledCode);
|
|
300
|
-
return bundledCode;
|
|
301
|
-
} finally {
|
|
302
|
-
try {
|
|
303
|
-
unlinkSync(entryPath);
|
|
304
|
-
} catch {}
|
|
305
|
-
}
|
|
306
|
-
} catch (error) {
|
|
307
|
-
console.warn(`[devflare] Error bundling worker "${workerName}":`, error);
|
|
308
|
-
return null;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
function hasCrossWorkerDOs(config) {
|
|
312
|
-
const dos = config.bindings?.durableObjects;
|
|
313
|
-
if (!dos)
|
|
314
|
-
return false;
|
|
315
|
-
for (const doConfig of Object.values(dos)) {
|
|
316
|
-
const normalized = normalizeDOBinding(doConfig);
|
|
317
|
-
if (normalized.__ref)
|
|
318
|
-
return true;
|
|
319
|
-
}
|
|
320
|
-
return false;
|
|
321
|
-
}
|
|
322
|
-
async function resolveDOBindings(config, configDir) {
|
|
323
|
-
const dos = config.bindings?.durableObjects;
|
|
324
|
-
if (!dos) {
|
|
325
|
-
return { workers: [], crossWorkerDOBindings: {} };
|
|
326
|
-
}
|
|
327
|
-
const workersByName = new Map;
|
|
328
|
-
const crossWorkerDOBindings = {};
|
|
329
|
-
for (const [bindingName, rawDoConfig] of Object.entries(dos)) {
|
|
330
|
-
const hasRef = typeof rawDoConfig === "object" && "__ref" in rawDoConfig;
|
|
331
|
-
if (!hasRef) {
|
|
332
|
-
continue;
|
|
333
|
-
}
|
|
334
|
-
const ref = rawDoConfig.__ref;
|
|
335
|
-
if ("__import" in ref && typeof ref.__import === "function") {
|
|
336
|
-
await ref.resolve();
|
|
337
|
-
}
|
|
338
|
-
const doConfig = normalizeDOBinding(rawDoConfig);
|
|
339
|
-
const workerName = ref.name;
|
|
340
|
-
if (!workersByName.has(workerName)) {
|
|
341
|
-
const worker = await resolveDORefWorker(ref, configDir);
|
|
342
|
-
if (worker) {
|
|
343
|
-
workersByName.set(workerName, worker);
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
crossWorkerDOBindings[bindingName] = {
|
|
347
|
-
className: doConfig.className,
|
|
348
|
-
scriptName: workerName
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
return {
|
|
352
|
-
workers: [...workersByName.values()],
|
|
353
|
-
crossWorkerDOBindings
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
async function resolveDORefWorker(ref, parentConfigDir) {
|
|
357
|
-
const config = ref.config;
|
|
358
|
-
if (!config)
|
|
359
|
-
return null;
|
|
360
|
-
const configPath = ref.configPath;
|
|
361
|
-
if (!configPath || configPath === "<resolved>") {
|
|
362
|
-
console.warn(`[devflare] Cannot resolve DO worker "${ref.name}" - configPath not available`);
|
|
363
|
-
return null;
|
|
364
|
-
}
|
|
365
|
-
const resolvedConfigPath = resolvePackageSpecifier(configPath, parentConfigDir);
|
|
366
|
-
const refConfigDir = dirname(resolvedConfigPath);
|
|
367
|
-
const dosConfig = config.bindings?.durableObjects;
|
|
368
|
-
if (!dosConfig || Object.keys(dosConfig).length === 0) {
|
|
369
|
-
console.warn(`[devflare] Referenced worker "${ref.name}" has no Durable Objects`);
|
|
370
|
-
return null;
|
|
371
|
-
}
|
|
372
|
-
const discoveredDOs = discoverDOFilesSync(refConfigDir);
|
|
373
|
-
const doClasses = [];
|
|
374
|
-
for (const [bindingName, rawDoConfig] of Object.entries(dosConfig)) {
|
|
375
|
-
const doConfig = normalizeDOBinding(rawDoConfig);
|
|
376
|
-
const className = doConfig.className;
|
|
377
|
-
const scriptName = doConfig.scriptName;
|
|
378
|
-
if (scriptName) {
|
|
379
|
-
const scriptPath = resolve(refConfigDir, "src", scriptName);
|
|
380
|
-
if (!existsSync(scriptPath)) {
|
|
381
|
-
const altPath = resolve(refConfigDir, scriptName);
|
|
382
|
-
if (!existsSync(altPath)) {
|
|
383
|
-
console.warn(`[devflare] DO script not found: ${scriptPath} or ${altPath}`);
|
|
384
|
-
continue;
|
|
385
|
-
}
|
|
386
|
-
doClasses.push({ bindingName, className, scriptPath: altPath });
|
|
387
|
-
} else {
|
|
388
|
-
doClasses.push({ bindingName, className, scriptPath });
|
|
389
|
-
}
|
|
390
|
-
} else {
|
|
391
|
-
const discoveredPath = discoveredDOs.get(className);
|
|
392
|
-
if (discoveredPath) {
|
|
393
|
-
doClasses.push({ bindingName, className, scriptPath: discoveredPath });
|
|
394
|
-
} else {
|
|
395
|
-
console.warn(`[devflare] DO "${bindingName}" (class: ${className}) not found in do.*.ts files in "${ref.name}"`);
|
|
396
|
-
continue;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
if (doClasses.length === 0) {
|
|
401
|
-
console.warn(`[devflare] No valid DO classes found in "${ref.name}"`);
|
|
402
|
-
return null;
|
|
403
|
-
}
|
|
404
|
-
const script = await bundleDOClasses(doClasses, ref.name);
|
|
405
|
-
if (!script)
|
|
406
|
-
return null;
|
|
407
|
-
const durableObjects = {};
|
|
408
|
-
for (const do_ of doClasses) {
|
|
409
|
-
durableObjects[do_.bindingName] = do_.className;
|
|
410
|
-
}
|
|
411
|
-
return {
|
|
412
|
-
name: ref.name,
|
|
413
|
-
script,
|
|
414
|
-
modules: true,
|
|
415
|
-
compatibilityDate: config.compatibilityDate ?? "2025-01-01",
|
|
416
|
-
durableObjects
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
async function bundleDOClasses(doClasses, workerName) {
|
|
420
|
-
const cacheKey = `do:${doClasses.map((d) => `${d.scriptPath}::${d.className}`).join("|")}`;
|
|
421
|
-
const cached = bundleCache.get(cacheKey);
|
|
422
|
-
if (cached)
|
|
423
|
-
return cached;
|
|
424
|
-
const bun = getBunRuntime();
|
|
425
|
-
if (!bun) {
|
|
426
|
-
console.warn("[devflare] Bun runtime required for bundling DO classes");
|
|
427
|
-
return null;
|
|
428
|
-
}
|
|
429
|
-
try {
|
|
430
|
-
const { writeFileSync, mkdirSync, unlinkSync } = await import("fs");
|
|
431
|
-
const imports = doClasses.map((d) => `import { ${d.className} } from '${d.scriptPath.replace(/\\/g, "/")}'`).join(`
|
|
432
|
-
`);
|
|
433
|
-
const exports = doClasses.map((d) => d.className).join(", ");
|
|
434
|
-
const entryCode = `
|
|
435
|
-
${imports}
|
|
436
|
-
|
|
437
|
-
// Re-export DO classes for Miniflare binding
|
|
438
|
-
export { ${exports} }
|
|
439
|
-
|
|
440
|
-
// Default export with fetch handler
|
|
441
|
-
export default {
|
|
442
|
-
async fetch(request, env) {
|
|
443
|
-
return new Response('DO Worker: ${workerName}')
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
`;
|
|
447
|
-
const tempDir = join(dirname(doClasses[0].scriptPath), ".devflare");
|
|
448
|
-
mkdirSync(tempDir, { recursive: true });
|
|
449
|
-
const entryPath = join(tempDir, `__do_entry_${workerName}.ts`);
|
|
450
|
-
writeFileSync(entryPath, entryCode);
|
|
451
|
-
try {
|
|
452
|
-
const result = await bun.build({
|
|
453
|
-
entrypoints: [entryPath],
|
|
454
|
-
target: "browser",
|
|
455
|
-
format: "esm",
|
|
456
|
-
minify: false,
|
|
457
|
-
external: ["cloudflare:workers", "cloudflare:*"]
|
|
458
|
-
});
|
|
459
|
-
if (!result.success) {
|
|
460
|
-
console.warn(`[devflare] Failed to bundle DO worker "${workerName}": ${result.logs.join(`
|
|
461
|
-
`)}`);
|
|
462
|
-
return null;
|
|
463
|
-
}
|
|
464
|
-
const bundledCode = await result.outputs[0].text();
|
|
465
|
-
bundleCache.set(cacheKey, bundledCode);
|
|
466
|
-
return bundledCode;
|
|
467
|
-
} finally {
|
|
468
|
-
try {
|
|
469
|
-
unlinkSync(entryPath);
|
|
470
|
-
} catch {}
|
|
471
|
-
}
|
|
472
|
-
} catch (error) {
|
|
473
|
-
console.warn(`[devflare] Error bundling DO worker "${workerName}":`, error);
|
|
474
|
-
return null;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
|
|
478
100
|
// src/test/simple-context-durable-objects.ts
|
|
479
101
|
import { mkdirSync, writeFileSync } from "fs";
|
|
480
102
|
import { readFile } from "fs/promises";
|
|
481
|
-
import { dirname as
|
|
103
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
482
104
|
|
|
483
105
|
// src/test/simple-context-gateway-script.ts
|
|
484
106
|
function buildGatewayScript(bundledCode, wrappers, nativeRpcBindingNames = []) {
|
|
@@ -695,9 +317,9 @@ function __normalizeEmailMessage(message) {
|
|
|
695
317
|
}
|
|
696
318
|
|
|
697
319
|
// src/test/simple-context-paths.ts
|
|
698
|
-
import { existsSync
|
|
320
|
+
import { existsSync } from "fs";
|
|
699
321
|
import { createServer } from "net";
|
|
700
|
-
import { dirname
|
|
322
|
+
import { dirname, join } from "path";
|
|
701
323
|
import { fileURLToPath } from "url";
|
|
702
324
|
var DEFAULT_TRANSPORT_ENTRY_FILES = [
|
|
703
325
|
"src/transport.ts",
|
|
@@ -705,8 +327,8 @@ var DEFAULT_TRANSPORT_ENTRY_FILES = [
|
|
|
705
327
|
"src/transport.mts",
|
|
706
328
|
"src/transport.mjs"
|
|
707
329
|
];
|
|
708
|
-
var CURRENT_PACKAGE_ROOT = findPackageRoot(
|
|
709
|
-
function
|
|
330
|
+
var CURRENT_PACKAGE_ROOT = findPackageRoot(dirname(fileURLToPath(import.meta.url)));
|
|
331
|
+
function getBunRuntime() {
|
|
710
332
|
const g = globalThis;
|
|
711
333
|
if (typeof g.Bun === "object" && g.Bun !== null) {
|
|
712
334
|
return g.Bun;
|
|
@@ -728,8 +350,8 @@ function getStackCallerDirectory() {
|
|
|
728
350
|
const stack = err.stack;
|
|
729
351
|
for (const site of stack ?? []) {
|
|
730
352
|
const filename = site.getFileName?.();
|
|
731
|
-
if (filename && !isInsideCurrentPackage(filename) && !filename.includes("simple-context") && !filename.includes("node_modules") && !filename.includes("[") &&
|
|
732
|
-
return
|
|
353
|
+
if (filename && !isInsideCurrentPackage(filename) && !filename.includes("simple-context") && !filename.includes("node_modules") && !filename.includes("[") && existsSync(filename)) {
|
|
354
|
+
return dirname(filename);
|
|
733
355
|
}
|
|
734
356
|
}
|
|
735
357
|
} finally {
|
|
@@ -740,10 +362,10 @@ function getStackCallerDirectory() {
|
|
|
740
362
|
function findPackageRoot(startDir) {
|
|
741
363
|
let currentDir = startDir;
|
|
742
364
|
while (true) {
|
|
743
|
-
if (
|
|
365
|
+
if (existsSync(join(currentDir, "package.json"))) {
|
|
744
366
|
return currentDir;
|
|
745
367
|
}
|
|
746
|
-
const parentDir =
|
|
368
|
+
const parentDir = dirname(currentDir);
|
|
747
369
|
if (parentDir === currentDir) {
|
|
748
370
|
return startDir;
|
|
749
371
|
}
|
|
@@ -762,7 +384,7 @@ async function findNearestConfig(startDir) {
|
|
|
762
384
|
if (configPath) {
|
|
763
385
|
return configPath;
|
|
764
386
|
}
|
|
765
|
-
const parentDir =
|
|
387
|
+
const parentDir = dirname(currentDir);
|
|
766
388
|
if (parentDir === currentDir) {
|
|
767
389
|
return null;
|
|
768
390
|
}
|
|
@@ -798,7 +420,7 @@ function resolveTransportFile(configDir, configuredPath) {
|
|
|
798
420
|
return null;
|
|
799
421
|
}
|
|
800
422
|
for (const defaultEntry of DEFAULT_TRANSPORT_ENTRY_FILES) {
|
|
801
|
-
if (
|
|
423
|
+
if (existsSync(join(configDir, defaultEntry))) {
|
|
802
424
|
return defaultEntry;
|
|
803
425
|
}
|
|
804
426
|
}
|
|
@@ -857,7 +479,7 @@ async function resolveLocalDurableObjects(config, configDir) {
|
|
|
857
479
|
let scriptPath;
|
|
858
480
|
let nativeRpc = false;
|
|
859
481
|
if (doInfo.kind === "cross-worker" && doInfo.scriptName) {
|
|
860
|
-
scriptPath =
|
|
482
|
+
scriptPath = join2(configDir, "src", doInfo.scriptName);
|
|
861
483
|
try {
|
|
862
484
|
const code = await readFile(scriptPath, "utf-8");
|
|
863
485
|
nativeRpc = classSupportsNativeDurableObjectRpc(code, doInfo.className);
|
|
@@ -943,7 +565,7 @@ async function bundleDurableObjectModules(configDir, doInfos, transportFile) {
|
|
|
943
565
|
const virtualImports = [];
|
|
944
566
|
const virtualExports = [];
|
|
945
567
|
if (transportFile) {
|
|
946
|
-
const transportPath =
|
|
568
|
+
const transportPath = join2(configDir, transportFile);
|
|
947
569
|
virtualImports.push(`import { transport } from '${transportPath.replace(/\\/g, "/")}'`);
|
|
948
570
|
virtualExports.push("export { transport }");
|
|
949
571
|
}
|
|
@@ -956,10 +578,10 @@ async function bundleDurableObjectModules(configDir, doInfos, transportFile) {
|
|
|
956
578
|
}
|
|
957
579
|
const virtualEntry = [...virtualImports, "", ...virtualExports].join(`
|
|
958
580
|
`);
|
|
959
|
-
const virtualPath =
|
|
960
|
-
mkdirSync(
|
|
581
|
+
const virtualPath = join2(configDir, ".devflare", "__test_entry.ts");
|
|
582
|
+
mkdirSync(dirname2(virtualPath), { recursive: true });
|
|
961
583
|
writeFileSync(virtualPath, virtualEntry);
|
|
962
|
-
const bun =
|
|
584
|
+
const bun = getBunRuntime();
|
|
963
585
|
if (!bun) {
|
|
964
586
|
throw new Error("Bun runtime is required for createTestContext with Durable Objects");
|
|
965
587
|
}
|
|
@@ -2159,7 +1781,7 @@ function buildRemoteAndStaticBindings(config) {
|
|
|
2159
1781
|
}
|
|
2160
1782
|
|
|
2161
1783
|
// src/test/email.ts
|
|
2162
|
-
import { join as
|
|
1784
|
+
import { join as join3 } from "path";
|
|
2163
1785
|
var miniflarePort = 8787;
|
|
2164
1786
|
var emailListeners = [];
|
|
2165
1787
|
var sentEmails = [];
|
|
@@ -2244,7 +1866,7 @@ function getRecordedRawContent(raw) {
|
|
|
2244
1866
|
async function send(options) {
|
|
2245
1867
|
const raw = buildRawEmail(options);
|
|
2246
1868
|
if (emailHandlerPath && configDir && testEnvGetter) {
|
|
2247
|
-
const absolutePath =
|
|
1869
|
+
const absolutePath = join3(configDir, emailHandlerPath);
|
|
2248
1870
|
const handlerModule = await import(absolutePath);
|
|
2249
1871
|
const emailHandler = resolveEmailHandler(handlerModule);
|
|
2250
1872
|
if (!emailHandler) {
|
|
@@ -2346,7 +1968,7 @@ var email = {
|
|
|
2346
1968
|
};
|
|
2347
1969
|
|
|
2348
1970
|
// src/test/queue.ts
|
|
2349
|
-
import { join as
|
|
1971
|
+
import { join as join4 } from "path";
|
|
2350
1972
|
var queueHandlerPath = null;
|
|
2351
1973
|
var configDir2 = null;
|
|
2352
1974
|
var testEnvGetter2 = null;
|
|
@@ -2414,7 +2036,7 @@ async function trigger(messages) {
|
|
|
2414
2036
|
if (!configDir2 || !testEnvGetter2) {
|
|
2415
2037
|
throw new Error("Queue helper not initialized. Call createTestContext() before using cf.queue.trigger()");
|
|
2416
2038
|
}
|
|
2417
|
-
const absolutePath =
|
|
2039
|
+
const absolutePath = join4(configDir2, queueHandlerPath);
|
|
2418
2040
|
const handlerModule = await import(absolutePath);
|
|
2419
2041
|
const queueHandler = handlerModule.default ?? handlerModule.queue;
|
|
2420
2042
|
if (typeof queueHandler !== "function") {
|
|
@@ -2473,7 +2095,7 @@ var queue2 = {
|
|
|
2473
2095
|
};
|
|
2474
2096
|
|
|
2475
2097
|
// src/test/scheduled.ts
|
|
2476
|
-
import { join as
|
|
2098
|
+
import { join as join5 } from "path";
|
|
2477
2099
|
var scheduledHandlerPath = null;
|
|
2478
2100
|
var configDir3 = null;
|
|
2479
2101
|
var testEnvGetter3 = null;
|
|
@@ -2497,7 +2119,7 @@ async function trigger2(cronOrOptions) {
|
|
|
2497
2119
|
const options = typeof cronOrOptions === "string" ? { cron: cronOrOptions } : cronOrOptions ?? {};
|
|
2498
2120
|
const cron = options.cron ?? "* * * * *";
|
|
2499
2121
|
const scheduledTime = options.scheduledTime instanceof Date ? options.scheduledTime.getTime() : options.scheduledTime ?? Date.now();
|
|
2500
|
-
const absolutePath =
|
|
2122
|
+
const absolutePath = join5(configDir3, scheduledHandlerPath);
|
|
2501
2123
|
const handlerModule = await import(absolutePath);
|
|
2502
2124
|
const scheduledHandler = handlerModule.default ?? handlerModule.scheduled;
|
|
2503
2125
|
if (typeof scheduledHandler !== "function") {
|
|
@@ -2541,7 +2163,7 @@ var scheduled = {
|
|
|
2541
2163
|
};
|
|
2542
2164
|
|
|
2543
2165
|
// src/test/tail.ts
|
|
2544
|
-
import { join as
|
|
2166
|
+
import { join as join6 } from "path";
|
|
2545
2167
|
var tailHandlerPath = null;
|
|
2546
2168
|
var configDir4 = null;
|
|
2547
2169
|
var testEnvGetter4 = null;
|
|
@@ -2587,7 +2209,7 @@ async function trigger3(items) {
|
|
|
2587
2209
|
}
|
|
2588
2210
|
return createTraceItem(item);
|
|
2589
2211
|
});
|
|
2590
|
-
const absolutePath =
|
|
2212
|
+
const absolutePath = join6(configDir4, tailHandlerPath);
|
|
2591
2213
|
const handlerModule = await import(absolutePath);
|
|
2592
2214
|
const defaultExport = handlerModule.default;
|
|
2593
2215
|
const tailHandler = typeof defaultExport === "function" ? defaultExport : defaultExport && typeof defaultExport.tail === "function" ? defaultExport.tail.bind(defaultExport) : handlerModule.tail;
|
|
@@ -2629,7 +2251,7 @@ var tail = {
|
|
|
2629
2251
|
};
|
|
2630
2252
|
|
|
2631
2253
|
// src/test/worker.ts
|
|
2632
|
-
import { join as
|
|
2254
|
+
import { join as join7 } from "path";
|
|
2633
2255
|
var fetchHandlerPath = null;
|
|
2634
2256
|
var configDir5 = null;
|
|
2635
2257
|
var testEnvGetter5 = null;
|
|
@@ -2678,11 +2300,11 @@ async function fetch2(request, options) {
|
|
|
2678
2300
|
} else {
|
|
2679
2301
|
req = request;
|
|
2680
2302
|
}
|
|
2681
|
-
const handlerModule = fetchHandlerPath ? await import(
|
|
2303
|
+
const handlerModule = fetchHandlerPath ? await import(join7(workerConfigDir, fetchHandlerPath)) : {};
|
|
2682
2304
|
const routeModules = await Promise.all(fileRoutes.map(async (route) => {
|
|
2683
2305
|
return {
|
|
2684
2306
|
...route,
|
|
2685
|
-
module: await import(
|
|
2307
|
+
module: await import(join7(workerConfigDir, route.filePath))
|
|
2686
2308
|
};
|
|
2687
2309
|
}));
|
|
2688
2310
|
const methodExports = ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "ALL"];
|
|
@@ -2813,7 +2435,7 @@ function createMultiWorkerEnvAccessor(state) {
|
|
|
2813
2435
|
}
|
|
2814
2436
|
|
|
2815
2437
|
// src/test/simple-context-handlers.ts
|
|
2816
|
-
import { join as
|
|
2438
|
+
import { join as join8 } from "path";
|
|
2817
2439
|
var DEFAULT_FETCH_PATH = "src/fetch.ts";
|
|
2818
2440
|
var DEFAULT_QUEUE_PATH = "src/queue.ts";
|
|
2819
2441
|
var DEFAULT_SCHEDULED_PATH = "src/scheduled.ts";
|
|
@@ -2826,7 +2448,7 @@ async function resolveHandlerPath(configDir6, configValue, defaultPath) {
|
|
|
2826
2448
|
if (configValue === false) {
|
|
2827
2449
|
return null;
|
|
2828
2450
|
}
|
|
2829
|
-
const defaultAbsolute =
|
|
2451
|
+
const defaultAbsolute = join8(configDir6, defaultPath);
|
|
2830
2452
|
try {
|
|
2831
2453
|
const fs = await import("fs/promises");
|
|
2832
2454
|
await fs.access(defaultAbsolute);
|
|
@@ -2848,14 +2470,14 @@ async function resolveHandlerPaths(configDir6, config) {
|
|
|
2848
2470
|
}
|
|
2849
2471
|
|
|
2850
2472
|
// src/test/simple-context-lifecycle.ts
|
|
2851
|
-
import { dirname as
|
|
2473
|
+
import { dirname as dirname4, resolve as resolve2 } from "path";
|
|
2852
2474
|
|
|
2853
2475
|
// src/test/containers.ts
|
|
2854
2476
|
import { createHash, randomUUID } from "node:crypto";
|
|
2855
|
-
import { existsSync as
|
|
2477
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
2856
2478
|
import { stat } from "node:fs/promises";
|
|
2857
2479
|
import { createConnection } from "node:net";
|
|
2858
|
-
import { basename, dirname as
|
|
2480
|
+
import { basename, dirname as dirname3, isAbsolute, join as join9, resolve } from "node:path";
|
|
2859
2481
|
import { setTimeout as delay } from "node:timers/promises";
|
|
2860
2482
|
import { execa } from "execa";
|
|
2861
2483
|
var realContainerCommandRunner = {
|
|
@@ -3034,11 +2656,11 @@ async function resolveContainerStart(className, options, cwd) {
|
|
|
3034
2656
|
};
|
|
3035
2657
|
}
|
|
3036
2658
|
async function loadContainerConfig(configPath, cwd) {
|
|
3037
|
-
const absolutePath = configPath ?
|
|
2659
|
+
const absolutePath = configPath ? resolve(cwd, configPath) : await findNearestConfig(cwd);
|
|
3038
2660
|
if (!absolutePath) {
|
|
3039
2661
|
throw new Error(`Could not find a devflare config file for container lookup. Searched upward from: ${cwd}`);
|
|
3040
2662
|
}
|
|
3041
|
-
const configDir6 =
|
|
2663
|
+
const configDir6 = dirname3(absolutePath);
|
|
3042
2664
|
const loadedConfig = await loadConfig({
|
|
3043
2665
|
cwd: configDir6,
|
|
3044
2666
|
configFile: basename(absolutePath)
|
|
@@ -3073,11 +2695,11 @@ async function prepareImage(options) {
|
|
|
3073
2695
|
return { image: options.image };
|
|
3074
2696
|
}
|
|
3075
2697
|
async function buildLocalImage(options) {
|
|
3076
|
-
const imagePath =
|
|
2698
|
+
const imagePath = resolve(options.configDir, options.image);
|
|
3077
2699
|
const imageStat = await stat(imagePath);
|
|
3078
|
-
const dockerfile = imageStat.isDirectory() ?
|
|
3079
|
-
const context2 =
|
|
3080
|
-
if (!
|
|
2700
|
+
const dockerfile = imageStat.isDirectory() ? join9(imagePath, "Dockerfile") : imagePath;
|
|
2701
|
+
const context2 = resolve(options.configDir, options.imageBuildContext ?? (imageStat.isDirectory() ? options.image : dirname3(options.image)));
|
|
2702
|
+
if (!existsSync2(dockerfile)) {
|
|
3081
2703
|
throw new Error(`Container Dockerfile does not exist: ${dockerfile}`);
|
|
3082
2704
|
}
|
|
3083
2705
|
const tag = makeLocalImageTag(options.className, options.configDir, options.image);
|
|
@@ -3293,7 +2915,7 @@ function isTruthyEnvFlag(value) {
|
|
|
3293
2915
|
async function resolveTestContextConfig(configPath, callerDir = getCallerDirectory()) {
|
|
3294
2916
|
let absolutePath;
|
|
3295
2917
|
if (configPath) {
|
|
3296
|
-
absolutePath =
|
|
2918
|
+
absolutePath = resolve2(callerDir, configPath);
|
|
3297
2919
|
} else {
|
|
3298
2920
|
const found = await findNearestConfig(callerDir);
|
|
3299
2921
|
if (!found) {
|
|
@@ -3303,7 +2925,7 @@ async function resolveTestContextConfig(configPath, callerDir = getCallerDirecto
|
|
|
3303
2925
|
}
|
|
3304
2926
|
absolutePath = found;
|
|
3305
2927
|
}
|
|
3306
|
-
const configDir6 =
|
|
2928
|
+
const configDir6 = dirname4(absolutePath);
|
|
3307
2929
|
const loadedConfig = await loadConfig({
|
|
3308
2930
|
cwd: configDir6,
|
|
3309
2931
|
configFile: absolutePath.split(/[/\\]/).pop()
|
|
@@ -3352,10 +2974,10 @@ function isRetriableTestContextStartupError(error) {
|
|
|
3352
2974
|
return message.includes("websocket connection failed") || message.includes("connection timeout: ws://") || message.includes("econnrefused") || message.includes("eaddrinuse") || message.includes("address already in use");
|
|
3353
2975
|
}
|
|
3354
2976
|
async function waitForTestContextStartupRetry() {
|
|
3355
|
-
await new Promise((
|
|
2977
|
+
await new Promise((resolve3) => setTimeout(resolve3, TEST_CONTEXT_STARTUP_RETRY_DELAY_MS));
|
|
3356
2978
|
}
|
|
3357
2979
|
async function waitForBridgeClientRetry() {
|
|
3358
|
-
await new Promise((
|
|
2980
|
+
await new Promise((resolve3) => setTimeout(resolve3, TEST_CONTEXT_BRIDGE_CONNECT_RETRY_DELAY_MS));
|
|
3359
2981
|
}
|
|
3360
2982
|
async function connectBridgeClientWithRetry(url) {
|
|
3361
2983
|
let lastError;
|
|
@@ -3476,9 +3098,9 @@ async function bootTestRuntime(mfConfig, usesMultiWorker) {
|
|
|
3476
3098
|
}
|
|
3477
3099
|
|
|
3478
3100
|
// src/test/simple-context-transport.ts
|
|
3479
|
-
import { join as
|
|
3101
|
+
import { join as join10 } from "path";
|
|
3480
3102
|
async function loadTransportDecoders(configDir6, transportFile) {
|
|
3481
|
-
const transportPath =
|
|
3103
|
+
const transportPath = join10(configDir6, transportFile);
|
|
3482
3104
|
const transportModule = await import(transportPath);
|
|
3483
3105
|
if (!transportModule.transport) {
|
|
3484
3106
|
console.warn(`[devflare] Warning: Transport file "${transportFile}" does not export a named "transport" object.
|