export-runtime 0.0.17 → 0.0.19
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/bin/generate-types.mjs +40 -20
- package/handler.js +25 -5
- package/package.json +1 -1
package/bin/generate-types.mjs
CHANGED
|
@@ -10,40 +10,55 @@ import { fileURLToPath } from "url";
|
|
|
10
10
|
const cwd = process.cwd();
|
|
11
11
|
|
|
12
12
|
// --- Read package.json for configuration ---
|
|
13
|
+
// First check local package.json, then parent (for exportc-style projects)
|
|
13
14
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
const localPkgPath = path.join(cwd, "package.json");
|
|
16
|
+
const parentPkgPath = path.join(cwd, "..", "package.json");
|
|
17
|
+
|
|
18
|
+
let pkg = null;
|
|
19
|
+
let rootPkg = null;
|
|
20
|
+
let isExportcProject = false;
|
|
21
|
+
|
|
22
|
+
if (fs.existsSync(localPkgPath)) {
|
|
23
|
+
pkg = JSON.parse(fs.readFileSync(localPkgPath, "utf8"));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Check if parent has cloudflare config (exportc-style project)
|
|
27
|
+
if (fs.existsSync(parentPkgPath)) {
|
|
28
|
+
rootPkg = JSON.parse(fs.readFileSync(parentPkgPath, "utf8"));
|
|
29
|
+
if (rootPkg.cloudflare) {
|
|
30
|
+
isExportcProject = true;
|
|
31
|
+
}
|
|
18
32
|
}
|
|
19
33
|
|
|
20
|
-
|
|
34
|
+
// Use root package.json's cloudflare config if available (exportc project)
|
|
35
|
+
const cloudflareConfig = isExportcProject ? (rootPkg.cloudflare || {}) : (pkg?.cloudflare || {});
|
|
36
|
+
const securityConfig = isExportcProject ? (rootPkg.security || {}) : (pkg?.security || {});
|
|
21
37
|
|
|
22
|
-
//
|
|
23
|
-
const workerName =
|
|
38
|
+
// Worker name - from cloudflare.name, or package name
|
|
39
|
+
const workerName = cloudflareConfig.name || pkg?.name;
|
|
24
40
|
if (!workerName) {
|
|
25
|
-
console.error("
|
|
41
|
+
console.error("Worker name required: set 'cloudflare.name' in package.json or provide a package 'name'");
|
|
26
42
|
process.exit(1);
|
|
27
43
|
}
|
|
28
44
|
|
|
29
|
-
|
|
45
|
+
// Source entry - from cloudflare.exports or package exports
|
|
46
|
+
const exportsEntry = cloudflareConfig.exports || pkg?.exports;
|
|
30
47
|
if (!exportsEntry) {
|
|
31
|
-
console.error("package.json must have
|
|
48
|
+
console.error("package.json must have 'cloudflare.exports' or 'exports' field pointing to the source entry (e.g., './src' or './')");
|
|
32
49
|
process.exit(1);
|
|
33
50
|
}
|
|
34
51
|
|
|
35
|
-
// Optional: static assets directory
|
|
36
|
-
const assetsDir =
|
|
52
|
+
// Optional: static assets directory (from cloudflare.assets only, not main)
|
|
53
|
+
const assetsDir = cloudflareConfig.assets || null;
|
|
37
54
|
|
|
38
|
-
//
|
|
39
|
-
const cloudflareConfig = pkg.cloudflare || {};
|
|
55
|
+
// Cloudflare bindings configuration (d1, r2, kv, auth)
|
|
40
56
|
const d1Bindings = cloudflareConfig.d1 || [];
|
|
41
57
|
const r2Bindings = cloudflareConfig.r2 || [];
|
|
42
58
|
const kvBindings = cloudflareConfig.kv || [];
|
|
43
59
|
const authConfig = cloudflareConfig.auth || null;
|
|
44
60
|
|
|
45
|
-
//
|
|
46
|
-
const securityConfig = pkg.security || {};
|
|
61
|
+
// Security configuration
|
|
47
62
|
const accessConfig = securityConfig.access || {};
|
|
48
63
|
const allowedOrigins = accessConfig.origin || []; // empty = allow all (default Workers behavior)
|
|
49
64
|
|
|
@@ -68,7 +83,9 @@ validateBindings(kvBindings, "KV");
|
|
|
68
83
|
|
|
69
84
|
// --- Resolve source directory from exports field ---
|
|
70
85
|
|
|
71
|
-
|
|
86
|
+
// For exportc projects, resolve relative to parent directory
|
|
87
|
+
const baseDir = isExportcProject ? path.join(cwd, "..") : cwd;
|
|
88
|
+
const exportsPath = path.resolve(baseDir, exportsEntry.replace(/^\.\//, ""));
|
|
72
89
|
const srcDir = fs.existsSync(exportsPath) && fs.statSync(exportsPath).isDirectory()
|
|
73
90
|
? exportsPath
|
|
74
91
|
: path.dirname(exportsPath);
|
|
@@ -397,14 +414,17 @@ const wranglerLines = [
|
|
|
397
414
|
``,
|
|
398
415
|
];
|
|
399
416
|
|
|
400
|
-
// Add static assets configuration if
|
|
417
|
+
// Add static assets configuration if assets is specified and directory exists
|
|
401
418
|
if (assetsDir) {
|
|
419
|
+
// For exportc projects, assets path is relative to parent directory
|
|
402
420
|
const normalizedAssetsDir = assetsDir.startsWith("./") ? assetsDir : `./${assetsDir}`;
|
|
403
|
-
const absoluteAssetsDir = path.resolve(
|
|
421
|
+
const absoluteAssetsDir = path.resolve(baseDir, normalizedAssetsDir);
|
|
422
|
+
// In wrangler.toml, path should be relative to export/ directory for exportc projects
|
|
423
|
+
const wranglerAssetsPath = isExportcProject ? `../${normalizedAssetsDir.replace(/^\.\//, "")}` : normalizedAssetsDir;
|
|
404
424
|
if (fs.existsSync(absoluteAssetsDir)) {
|
|
405
425
|
wranglerLines.push(
|
|
406
426
|
`[assets]`,
|
|
407
|
-
`directory = "${
|
|
427
|
+
`directory = "${wranglerAssetsPath}"`,
|
|
408
428
|
`binding = "ASSETS"`,
|
|
409
429
|
`run_worker_first = true`,
|
|
410
430
|
``,
|
package/handler.js
CHANGED
|
@@ -320,10 +320,22 @@ export const createHandler = (moduleMap, generatedTypes, minifiedCore, coreId, m
|
|
|
320
320
|
};
|
|
321
321
|
|
|
322
322
|
const wireWebSocket = (server, dispatcher, env, onClose) => {
|
|
323
|
-
// Track session state for this WebSocket connection
|
|
323
|
+
// Track session state and connection state for this WebSocket connection
|
|
324
324
|
const wsSession = { token: null };
|
|
325
|
+
let isClosed = false;
|
|
326
|
+
|
|
327
|
+
// Safe send that ignores errors when connection is closed
|
|
328
|
+
const safeSend = (data) => {
|
|
329
|
+
if (isClosed) return;
|
|
330
|
+
try {
|
|
331
|
+
server.send(data);
|
|
332
|
+
} catch {
|
|
333
|
+
// Connection already closed, ignore
|
|
334
|
+
}
|
|
335
|
+
};
|
|
325
336
|
|
|
326
337
|
server.addEventListener("message", async (event) => {
|
|
338
|
+
if (isClosed) return;
|
|
327
339
|
let id;
|
|
328
340
|
try {
|
|
329
341
|
const msg = parse(event.data);
|
|
@@ -333,7 +345,7 @@ export const createHandler = (moduleMap, generatedTypes, minifiedCore, coreId, m
|
|
|
333
345
|
if (msg.type === "auth" && msg.token && !msg.method) {
|
|
334
346
|
// Direct token send on reconnect - just update session
|
|
335
347
|
wsSession.token = msg.token;
|
|
336
|
-
|
|
348
|
+
safeSend(stringify({ type: "auth-result", id, success: true }));
|
|
337
349
|
return;
|
|
338
350
|
}
|
|
339
351
|
|
|
@@ -344,12 +356,20 @@ export const createHandler = (moduleMap, generatedTypes, minifiedCore, coreId, m
|
|
|
344
356
|
wsSession.token = result.value.token;
|
|
345
357
|
}
|
|
346
358
|
|
|
347
|
-
if (result)
|
|
359
|
+
if (result) safeSend(stringify({ ...result, id }));
|
|
348
360
|
} catch (err) {
|
|
349
|
-
if (id !== undefined)
|
|
361
|
+
if (id !== undefined) safeSend(stringify({ type: "error", id, error: String(err) }));
|
|
350
362
|
}
|
|
351
363
|
});
|
|
352
|
-
|
|
364
|
+
|
|
365
|
+
server.addEventListener("close", () => {
|
|
366
|
+
isClosed = true;
|
|
367
|
+
if (onClose) onClose();
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
server.addEventListener("error", () => {
|
|
371
|
+
isClosed = true;
|
|
372
|
+
});
|
|
353
373
|
};
|
|
354
374
|
|
|
355
375
|
return {
|