export-runtime 0.0.9 → 0.0.10
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 +78 -14
- package/handler.js +13 -2
- package/package.json +1 -1
- package/rpc.js +2 -0
package/bin/generate-types.mjs
CHANGED
|
@@ -9,25 +9,43 @@ import { fileURLToPath } from "url";
|
|
|
9
9
|
|
|
10
10
|
const cwd = process.cwd();
|
|
11
11
|
|
|
12
|
-
// Read
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
// --- Read package.json for configuration ---
|
|
13
|
+
|
|
14
|
+
const pkgPath = path.join(cwd, "package.json");
|
|
15
|
+
if (!fs.existsSync(pkgPath)) {
|
|
16
|
+
console.error("package.json not found in", cwd);
|
|
16
17
|
process.exit(1);
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
|
|
20
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
21
|
+
|
|
22
|
+
// Required fields
|
|
23
|
+
const workerName = pkg.name;
|
|
24
|
+
if (!workerName) {
|
|
25
|
+
console.error("package.json must have a 'name' field for the Worker name");
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const exportsEntry = pkg.exports;
|
|
30
|
+
if (!exportsEntry) {
|
|
31
|
+
console.error("package.json must have an 'exports' field pointing to the source entry (e.g., './src' or './src/index.ts')");
|
|
22
32
|
process.exit(1);
|
|
23
33
|
}
|
|
24
34
|
|
|
25
|
-
//
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
// Optional: static assets directory
|
|
36
|
+
const assetsDir = pkg.main || null;
|
|
37
|
+
|
|
38
|
+
// --- Resolve source directory from exports field ---
|
|
39
|
+
|
|
40
|
+
const exportsPath = path.resolve(cwd, exportsEntry.replace(/^\.\//, ""));
|
|
41
|
+
const srcDir = fs.existsSync(exportsPath) && fs.statSync(exportsPath).isDirectory()
|
|
42
|
+
? exportsPath
|
|
43
|
+
: path.dirname(exportsPath);
|
|
44
|
+
|
|
45
|
+
if (!fs.existsSync(srcDir)) {
|
|
46
|
+
console.error(`Source directory not found: ${srcDir}`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
31
49
|
|
|
32
50
|
// --- Discover all source files under srcDir ---
|
|
33
51
|
|
|
@@ -327,7 +345,53 @@ for (const mod of modules) {
|
|
|
327
345
|
sharedLines.push(`export { getStub };`);
|
|
328
346
|
fs.writeFileSync(sharedModulePath, sharedLines.join("\n") + "\n");
|
|
329
347
|
|
|
348
|
+
// --- Generate wrangler.toml ---
|
|
349
|
+
|
|
350
|
+
const wranglerLines = [
|
|
351
|
+
`# Auto-generated by export-runtime. Do not edit manually.`,
|
|
352
|
+
`name = "${workerName}"`,
|
|
353
|
+
`main = "node_modules/export-runtime/entry.js"`,
|
|
354
|
+
`compatibility_date = "2024-11-01"`,
|
|
355
|
+
``,
|
|
356
|
+
];
|
|
357
|
+
|
|
358
|
+
// Add static assets configuration if main is specified
|
|
359
|
+
if (assetsDir) {
|
|
360
|
+
const normalizedAssetsDir = assetsDir.startsWith("./") ? assetsDir : `./${assetsDir}`;
|
|
361
|
+
wranglerLines.push(
|
|
362
|
+
`[assets]`,
|
|
363
|
+
`directory = "${normalizedAssetsDir}"`,
|
|
364
|
+
`binding = "ASSETS"`,
|
|
365
|
+
`run_worker_first = true`,
|
|
366
|
+
``,
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Add Durable Objects for shared state
|
|
371
|
+
wranglerLines.push(
|
|
372
|
+
`[durable_objects]`,
|
|
373
|
+
`bindings = [`,
|
|
374
|
+
` { name = "SHARED_EXPORT", class_name = "SharedExportDO" }`,
|
|
375
|
+
`]`,
|
|
376
|
+
``,
|
|
377
|
+
`[[migrations]]`,
|
|
378
|
+
`tag = "v1"`,
|
|
379
|
+
`new_classes = ["SharedExportDO"]`,
|
|
380
|
+
``,
|
|
381
|
+
`[alias]`,
|
|
382
|
+
`"__USER_MODULE__" = "./.export-module-map.js"`,
|
|
383
|
+
`"__GENERATED_TYPES__" = "./.export-types.js"`,
|
|
384
|
+
`"__SHARED_MODULE__" = "./.export-shared.js"`,
|
|
385
|
+
``,
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
const wranglerPath = path.join(cwd, "wrangler.toml");
|
|
389
|
+
fs.writeFileSync(wranglerPath, wranglerLines.join("\n"));
|
|
390
|
+
|
|
391
|
+
// --- Output summary ---
|
|
392
|
+
|
|
330
393
|
console.log(`Discovered ${modules.length} module(s): ${modules.map(m => m.routePath || "/").join(", ")}`);
|
|
331
394
|
console.log("Generated type definitions + minified core →", outPath);
|
|
332
395
|
console.log("Generated module map →", moduleMapPath);
|
|
333
396
|
console.log("Generated shared import module →", sharedModulePath);
|
|
397
|
+
console.log("Generated wrangler.toml →", wranglerPath);
|
package/handler.js
CHANGED
|
@@ -18,7 +18,12 @@ export const createHandler = (moduleMap, generatedTypes, minifiedCore, coreId, m
|
|
|
18
18
|
const moduleRoutes = Object.keys(moduleMap); // e.g. ["", "greet", "utils/math"]
|
|
19
19
|
const moduleExportKeys = {};
|
|
20
20
|
for (const [route, mod] of Object.entries(moduleMap)) {
|
|
21
|
-
|
|
21
|
+
const keys = Object.keys(mod);
|
|
22
|
+
if (keys.includes("default")) {
|
|
23
|
+
const modulePath = route || "(root)";
|
|
24
|
+
console.warn(`[export-runtime] WARN: default export in "${modulePath}" is ignored. Use named exports instead.`);
|
|
25
|
+
}
|
|
26
|
+
moduleExportKeys[route] = keys.filter(k => k !== "default");
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
const coreModuleCode = minifiedCore || CORE_CODE;
|
|
@@ -154,7 +159,13 @@ export const createHandler = (moduleMap, generatedTypes, minifiedCore, coreId, m
|
|
|
154
159
|
const cpath = isShared ? sharedCorePath : corePath;
|
|
155
160
|
|
|
156
161
|
const resolved = resolveRoute(pathname);
|
|
157
|
-
if (!resolved)
|
|
162
|
+
if (!resolved) {
|
|
163
|
+
// Fallback to static assets if ASSETS binding is available
|
|
164
|
+
if (env?.ASSETS) {
|
|
165
|
+
return env.ASSETS.fetch(request);
|
|
166
|
+
}
|
|
167
|
+
return new Response("Not found", { status: 404 });
|
|
168
|
+
}
|
|
158
169
|
|
|
159
170
|
const { route, exportName } = resolved;
|
|
160
171
|
|
package/package.json
CHANGED
package/rpc.js
CHANGED
|
@@ -65,6 +65,8 @@ export function createRpcDispatcher(moduleMap) {
|
|
|
65
65
|
// path = [route, ...exportPath] — route selects the module, exportPath walks its exports
|
|
66
66
|
const splitPath = (path) => {
|
|
67
67
|
const [route, ...rest] = path;
|
|
68
|
+
// Reject default export access
|
|
69
|
+
if (rest[0] === "default") throw new Error("Export not found: default");
|
|
68
70
|
return { exports: resolveModule(route), exportPath: rest };
|
|
69
71
|
};
|
|
70
72
|
|