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.
@@ -9,25 +9,43 @@ import { fileURLToPath } from "url";
9
9
 
10
10
  const cwd = process.cwd();
11
11
 
12
- // Read wrangler.toml to find source root
13
- const wranglerPath = path.join(cwd, "wrangler.toml");
14
- if (!fs.existsSync(wranglerPath)) {
15
- console.error("wrangler.toml not found in", cwd);
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
- const wranglerContent = fs.readFileSync(wranglerPath, "utf8");
19
- const aliasMatch = wranglerContent.match(/"__USER_MODULE__"\s*=\s*"([^"]+)"/);
20
- if (!aliasMatch) {
21
- console.error('Could not find __USER_MODULE__ alias in wrangler.toml');
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
- // Derive source root directory from the alias (e.g., "./src/index.ts" → "./src")
26
- const aliasTarget = aliasMatch[1];
27
- // If alias points to the module map, resolve src dir from it; otherwise derive from file
28
- const srcDir = aliasTarget.includes(".export-module-map")
29
- ? path.resolve(cwd, "src")
30
- : path.resolve(cwd, path.dirname(aliasTarget.replace(/^\.\//, "")));
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
- moduleExportKeys[route] = Object.keys(mod);
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) return new Response("Not found", { status: 404 });
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "export-runtime",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "description": "Cloudflare Workers ESM Export Framework Runtime",
5
5
  "keywords": [
6
6
  "cloudflare",
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