env-runner 0.3.1 → 0.3.3

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.
@@ -68,7 +68,10 @@ export interface MiniflareEnvRunnerOptions {
68
68
  persistent?: boolean;
69
69
  /** Wrap the user's `fetch` in a try/catch that returns structured JSON error responses. Default: `true`. */
70
70
  captureErrors?: boolean;
71
- /** Export conditions for the fallback service (default `["workerd", "worker"]`). */
71
+ /**
72
+ * Export conditions for the fallback service (default `["workerd", "worker"]`),
73
+ * plus `import` or `require` matching how the module is loaded.
74
+ */
72
75
  exportConditions?: string[];
73
76
  /**
74
77
  * Load a wrangler config into Miniflare options (compat date/flags, bindings).
@@ -1269,6 +1269,7 @@ var MiniflareEnvRunner = class extends BaseEnvRunner {
1269
1269
  };
1270
1270
  options.unsafeUseModuleFallbackService = true;
1271
1271
  const modulePathMap = /* @__PURE__ */ new Map();
1272
+ const _redirects = /* @__PURE__ */ new Map();
1272
1273
  const _lexersReady = Promise.all([ensureCjsLexer(), init]);
1273
1274
  options.unsafeModuleFallbackService = async (request) => {
1274
1275
  await _lexersReady;
@@ -1279,6 +1280,7 @@ var MiniflareEnvRunner = class extends BaseEnvRunner {
1279
1280
  if (!specifier) return new Response(null, { status: 404 });
1280
1281
  const cleanSpecifier = specifier.split("?")[0] || specifier;
1281
1282
  const cleanRaw = rawSpecifier?.split("?")[0];
1283
+ const method = request.headers.get("x-resolve-method") === "require" ? "require" : "import";
1282
1284
  const bareSpecifier = cleanSpecifier.startsWith("/") ? cleanSpecifier.slice(1) : cleanSpecifier;
1283
1285
  const referrerKey = referrer.startsWith("/") ? referrer.slice(1) : referrer;
1284
1286
  const referrerPath = modulePathMap.get(referrerKey);
@@ -1312,6 +1314,7 @@ var MiniflareEnvRunner = class extends BaseEnvRunner {
1312
1314
  let resolvedPath;
1313
1315
  let resolvedId;
1314
1316
  let pluginResolved = false;
1317
+ let bareResolved = false;
1315
1318
  const _resolvePlugins = _livePlugins();
1316
1319
  const rawSource = rawSpecifier ? stripInternalQuery(rawSpecifier, version) : bareSpecifier + query;
1317
1320
  const _pluginResolve = async (fallback) => {
@@ -1347,9 +1350,21 @@ var MiniflareEnvRunner = class extends BaseEnvRunner {
1347
1350
  return _pluginErrorModule(name, error);
1348
1351
  }
1349
1352
  };
1350
- const pluginPath = await _pluginResolve(false);
1351
- if (pluginPath instanceof Response) return pluginPath;
1352
- resolvedPath = pluginPath;
1353
+ const redirected = _redirects.get(specifier);
1354
+ if (redirected) {
1355
+ _redirects.delete(specifier);
1356
+ resolvedPath = redirected.path;
1357
+ resolvedId = redirected.id;
1358
+ pluginResolved = redirected.id !== void 0;
1359
+ } else if (method === "require" && cleanRaw?.startsWith("node:") && specifier === cleanRaw + NODE_REQUIRE_SUFFIX) return Response.json({
1360
+ name: specifier,
1361
+ esModule: createNodeRequireShim(cleanRaw)
1362
+ });
1363
+ else {
1364
+ const pluginPath = await _pluginResolve(false);
1365
+ if (pluginPath instanceof Response) return pluginPath;
1366
+ resolvedPath = pluginPath;
1367
+ }
1353
1368
  const fileUrlRaw = cleanRaw || cleanSpecifier;
1354
1369
  if (resolvedPath !== void 0) {} else if (fileUrlRaw.startsWith("file://")) try {
1355
1370
  resolvedPath = fileURLToPath(fileUrlRaw);
@@ -1361,16 +1376,19 @@ var MiniflareEnvRunner = class extends BaseEnvRunner {
1361
1376
  const contextRequire = referrerReal ? createRequire(referrerReal) : _require;
1362
1377
  if (cleanRaw.startsWith("cloudflare:")) return new Response(null, { status: 404 });
1363
1378
  if (cleanRaw.startsWith("node:")) {
1364
- const nodeName = cleanRaw.slice(5);
1365
- try {
1366
- resolvedPath = contextRequire.resolve(`unenv/node/${nodeName}`);
1367
- } catch {
1368
- return new Response(null, { status: 404 });
1379
+ if (method === "require") {
1380
+ const location = cleanRaw + NODE_REQUIRE_SUFFIX;
1381
+ return new Response(null, {
1382
+ status: 301,
1383
+ headers: { location }
1384
+ });
1369
1385
  }
1370
- } else try {
1386
+ return new Response(null, { status: 404 });
1387
+ }
1388
+ try {
1371
1389
  resolvedPath = resolveModulePath(cleanRaw, {
1372
1390
  from: referrerReal || entryBase,
1373
- conditions: _exportConditions,
1391
+ conditions: [..._exportConditions, method],
1374
1392
  try: true
1375
1393
  }) || contextRequire.resolve(cleanRaw);
1376
1394
  } catch {
@@ -1385,6 +1403,7 @@ var MiniflareEnvRunner = class extends BaseEnvRunner {
1385
1403
  }
1386
1404
  resolvedPath = failed;
1387
1405
  }
1406
+ bareResolved = true;
1388
1407
  } else {
1389
1408
  const referrerReal = referrerPath || (referrer.startsWith("/") ? referrer : "/" + referrer);
1390
1409
  const referrerDir = dirname(referrerReal);
@@ -1406,6 +1425,20 @@ var MiniflareEnvRunner = class extends BaseEnvRunner {
1406
1425
  if (failed instanceof Response) return failed;
1407
1426
  resolvedPath = failed ?? resolvedPath;
1408
1427
  }
1428
+ if (bareResolved || pluginResolved) {
1429
+ const path = toWorkerdPath(resolvedPath);
1430
+ if (cleanSpecifier !== path) {
1431
+ const location = pluginResolved ? restoreInternalQuery(path + queryOf(resolvedId), specifier) : path + rawQuery;
1432
+ _redirects.set(location, {
1433
+ path: resolvedPath,
1434
+ id: pluginResolved ? resolvedId : void 0
1435
+ });
1436
+ return new Response(null, {
1437
+ status: 301,
1438
+ headers: { location: Buffer.from(location, "utf8").toString("latin1") }
1439
+ });
1440
+ }
1441
+ }
1409
1442
  if (_transformRequest) try {
1410
1443
  const result = await _transformRequest(resolvedPath);
1411
1444
  if (result?.code) {
@@ -1711,6 +1744,19 @@ function commonJSExports(contents) {
1711
1744
  return [];
1712
1745
  }
1713
1746
  }
1747
+ const NODE_REQUIRE_SUFFIX = "?__require";
1748
+ function createNodeRequireShim(specifier) {
1749
+ const quoted = JSON.stringify(specifier);
1750
+ const notFound = JSON.stringify(`No such module ${quoted}.`);
1751
+ return [
1752
+ `import * as __mod__ from ${quoted};`,
1753
+ `export * from ${quoted};`,
1754
+ `let __default__;`,
1755
+ `try { __default__ = __mod__.default ?? __mod__; } catch { throw new Error(${notFound}); }`,
1756
+ `export default __default__;`,
1757
+ ``
1758
+ ].join("\n");
1759
+ }
1714
1760
  function createCjsEsmShim(cjsSpecifier, contents) {
1715
1761
  const namedExports = commonJSExports(contents).filter((e) => e !== "default" && e !== "__esModule");
1716
1762
  let shim = `import __cjs_mod__ from ${JSON.stringify(cjsSpecifier)};\nexport default __cjs_mod__;\n`;
package/dist/cli.mjs CHANGED
File without changes
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "env-runner",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Generic environment runner for JavaScript runtimes.",
5
5
  "license": "MIT",
6
- "repository": "unjs/env-runner",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "unjs/env-runner"
9
+ },
7
10
  "bin": {
8
11
  "env-runner": "./dist/cli.mjs"
9
12
  },
@@ -31,17 +34,6 @@
31
34
  "./runners/netlify/worker": "./dist/runners/netlify/worker.mjs",
32
35
  "./vite": "./dist/vite.mjs"
33
36
  },
34
- "scripts": {
35
- "build": "obuild",
36
- "dev": "vitest dev",
37
- "fmt": "automd && oxlint . --fix && oxfmt .",
38
- "lint": "oxlint . && oxfmt --check .",
39
- "prepack": "pnpm build",
40
- "env-runner": "node ./src/cli.ts",
41
- "release": "pnpm test && pnpm build && changelogen --release && pnpm publish && git push --follow-tags",
42
- "test": "pnpm lint && pnpm typecheck && vitest run --coverage",
43
- "typecheck": "tsc --noEmit --skipLibCheck"
44
- },
45
37
  "dependencies": {
46
38
  "crossws": "^0.4.12",
47
39
  "exsolve": "^1.1.1",
@@ -50,9 +42,9 @@
50
42
  },
51
43
  "devDependencies": {
52
44
  "@netlify/runtime": "^5.0.5",
53
- "@types/node": "^26.6.2",
45
+ "@types/node": "^26.6.3",
54
46
  "@vercel/queue": "^0.7.0",
55
- "@vitest/coverage-v8": "^5.0.1",
47
+ "@vitest/coverage-v8": "^5.0.2",
56
48
  "automd": "^0.4.3",
57
49
  "changelogen": "^0.6.2",
58
50
  "cjs-module-lexer": "^2.2.1",
@@ -64,8 +56,17 @@
64
56
  "oxfmt": ">=0.70.0",
65
57
  "oxlint": "^1.85.0",
66
58
  "typescript": "^7.0.2",
67
- "vitest": "^5.0.1",
68
- "wrangler": "^4.140.0"
59
+ "vitest": "^5.0.2",
60
+ "wrangler": "^4.141.0"
69
61
  },
70
- "packageManager": "pnpm@12.6.0"
71
- }
62
+ "scripts": {
63
+ "build": "obuild",
64
+ "dev": "vitest dev",
65
+ "fmt": "automd && oxlint . --fix && oxfmt .",
66
+ "lint": "oxlint . && oxfmt --check .",
67
+ "env-runner": "node ./src/cli.ts",
68
+ "release": "pnpm test && pnpm build && changelogen --release && pnpm publish && git push --follow-tags",
69
+ "test": "pnpm lint && pnpm typecheck && vitest run --coverage",
70
+ "typecheck": "tsc --noEmit --skipLibCheck"
71
+ }
72
+ }