unrun 0.2.9 → 0.2.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/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { n as unrunCli, r as unrunSync, t as unrun } from "./src-D87jO6Ui.mjs";
1
+ import { n as unrunCli, r as unrunSync, t as unrun } from "./src-Dsr1Mx3W.mjs";
2
2
 
3
3
  export { unrun, unrunCli, unrunSync };
@@ -111,18 +111,42 @@ function isPathWithinDirectory(parent, child) {
111
111
  * nested node_modules so they keep working once executed from .unrun.
112
112
  */
113
113
  function createExternalResolver(options) {
114
- const projectNodeModules = path.resolve(process.cwd(), "node_modules");
114
+ const entryDir = path.dirname(options.path);
115
+ const entryRequire = createRequire(options.path);
116
+ const canResolveFromEntry = (specifier) => {
117
+ try {
118
+ entryRequire.resolve(specifier);
119
+ return true;
120
+ } catch {
121
+ return false;
122
+ }
123
+ };
115
124
  return function external(id, importer) {
116
125
  if (!id || id.startsWith("\0")) return false;
117
126
  if (id.startsWith(".") || id.startsWith("#") || path.isAbsolute(id)) return false;
118
127
  if (isBuiltinModuleSpecifier(id)) return true;
119
128
  const importerPath = normalizeImporterPath(importer, options.path);
120
129
  try {
121
- if (!isPathWithinDirectory(projectNodeModules, createRequire(importerPath).resolve(id))) return false;
130
+ const containingNodeModules = findContainingNodeModules(createRequire(importerPath).resolve(id));
131
+ if (!containingNodeModules) return false;
132
+ const ownerDir = path.dirname(containingNodeModules);
133
+ const ownerInsideEntry = isPathWithinDirectory(entryDir, ownerDir);
134
+ const entryInsideOwner = isPathWithinDirectory(ownerDir, entryDir);
135
+ if (ownerInsideEntry && !entryInsideOwner) return false;
136
+ if (!canResolveFromEntry(id)) return false;
122
137
  } catch {}
123
138
  return true;
124
139
  };
125
140
  }
141
+ function findContainingNodeModules(filePath) {
142
+ let current = path.dirname(filePath);
143
+ const { root } = path.parse(current);
144
+ while (true) {
145
+ if (path.basename(current) === "node_modules") return current;
146
+ if (current === root) break;
147
+ current = path.dirname(current);
148
+ }
149
+ }
126
150
 
127
151
  //#endregion
128
152
  //#region src/plugins/console-output-customizer.ts
@@ -382,6 +406,7 @@ function createSourceContextShimsPlugin() {
382
406
  return null;
383
407
  }
384
408
  let __MODIFIED_CODE__ = false;
409
+ if (id.replaceAll("\\", "/").includes("/node_modules/")) return null;
385
410
  if (code.includes("import.meta.resolve")) {
386
411
  const replaced = code.replaceAll(/import\.meta\.resolve!?\s*\(\s*(["'])([^"']+)\1\s*\)/g, (_m, _q, spec) => {
387
412
  const url = pathToFileURL(path.resolve(path.dirname(id), spec)).href;
@@ -392,21 +417,36 @@ function createSourceContextShimsPlugin() {
392
417
  __MODIFIED_CODE__ = true;
393
418
  }
394
419
  }
395
- if (/__filename|__dirname|import\s*\.\s*meta\s*\.\s*url/.test(code)) {
420
+ const usesFilename = /\b__filename\b/.test(code);
421
+ const declaresFilename = /\b(?:const|let|var)\s+__filename\b/.test(code);
422
+ const usesDirname = /\b__dirname\b/.test(code);
423
+ const declaresDirname = /\b(?:const|let|var)\s+__dirname\b/.test(code);
424
+ const hasImportMetaUrl = /\bimport\s*\.\s*meta\s*\.\s*url\b/.test(code);
425
+ const needsFilenameShim = usesFilename && !declaresFilename;
426
+ const needsDirnameShim = usesDirname && !declaresDirname;
427
+ if (needsFilenameShim || needsDirnameShim || hasImportMetaUrl) {
396
428
  const file = id;
397
429
  const dir = path.dirname(id);
398
430
  const url = pathToFileURL(id).href;
399
- const prologue = `const __filename = ${JSON.stringify(file)}\nconst __dirname = ${JSON.stringify(dir)}\n`;
400
- const protectedStrings = [];
401
- let protectedCode = code.replaceAll(/(["'])[^"']*import\s*\.\s*meta\s*\.\s*url[^"']*\1\s*:/g, (match) => {
402
- const placeholder = `__PROTECTED_STRING_${protectedStrings.length}__`;
403
- protectedStrings.push(match);
404
- return placeholder;
405
- });
406
- protectedCode = protectedCode.replaceAll(/\bimport\s*\.\s*meta\s*\.\s*url\b/g, JSON.stringify(url));
407
- for (const [i, protectedString] of protectedStrings.entries()) protectedCode = protectedCode.replace(`__PROTECTED_STRING_${i}__`, protectedString);
408
- code = prologue + protectedCode;
409
- __MODIFIED_CODE__ = true;
431
+ const prologueLines = [];
432
+ if (needsFilenameShim) prologueLines.push(`const __filename = ${JSON.stringify(file)}`);
433
+ if (needsDirnameShim) prologueLines.push(`const __dirname = ${JSON.stringify(dir)}`);
434
+ let transformedCode = code;
435
+ if (hasImportMetaUrl) {
436
+ const protectedStrings = [];
437
+ transformedCode = transformedCode.replaceAll(/(["'])[^"']*import\s*\.\s*meta\s*\.\s*url[^"']*\1\s*:/g, (match) => {
438
+ const placeholder = `__PROTECTED_STRING_${protectedStrings.length}__`;
439
+ protectedStrings.push(match);
440
+ return placeholder;
441
+ });
442
+ transformedCode = transformedCode.replaceAll(/\bimport\s*\.\s*meta\s*\.\s*url\b/g, JSON.stringify(url));
443
+ for (const [i, protectedString] of protectedStrings.entries()) transformedCode = transformedCode.replace(`__PROTECTED_STRING_${i}__`, protectedString);
444
+ }
445
+ if (prologueLines.length > 0) transformedCode = `${prologueLines.join("\n")}\n${transformedCode}`;
446
+ if (transformedCode !== code) {
447
+ code = transformedCode;
448
+ __MODIFIED_CODE__ = true;
449
+ }
410
450
  }
411
451
  return __MODIFIED_CODE__ ? { code } : null;
412
452
  }
@@ -1,4 +1,4 @@
1
- import { t as unrun } from "../src-D87jO6Ui.mjs";
1
+ import { t as unrun } from "../src-Dsr1Mx3W.mjs";
2
2
  import { runAsWorker } from "synckit";
3
3
 
4
4
  //#region src/sync/worker.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unrun",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
4
4
  "description": "A tool to load and execute any JavaScript or TypeScript code at runtime.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -72,18 +72,20 @@
72
72
  "reflect-metadata": "^0.2.2",
73
73
  "synckit": "^0.11.11",
74
74
  "tinyexec": "^1.0.2",
75
- "tsdown": "^0.16.3",
75
+ "tsdown": "^0.16.4",
76
76
  "tsx": "^4.20.6",
77
77
  "typedoc": "^0.28.14",
78
78
  "typedoc-plugin-markdown": "^4.9.0",
79
79
  "typedoc-vitepress-theme": "^1.1.2",
80
80
  "typescript": "^5.9.3",
81
81
  "unconfig": "^7.4.1",
82
+ "unplugin-vue": "^7.0.7",
82
83
  "vite": "^7.2.2",
83
84
  "vitepress": "2.0.0-alpha.12",
84
85
  "vitepress-plugin-group-icons": "^1.6.5",
85
86
  "vitest": "4.0.8",
86
87
  "vue": "^3.5.24",
88
+ "vue-tsc": "^3.1.4",
87
89
  "zod": "^4.1.12"
88
90
  },
89
91
  "engines": {
@@ -95,8 +97,12 @@
95
97
  "lint:fix": "pnpm run lint --fix",
96
98
  "build": "tsdown",
97
99
  "dev": "tsdown --watch",
100
+ "pretest": "node ./scripts/manage-pnpm-override.mjs add",
98
101
  "test": "vitest",
102
+ "posttest": "node ./scripts/manage-pnpm-override.mjs remove",
103
+ "pretest:run": "node ./scripts/manage-pnpm-override.mjs add",
99
104
  "test:run": "vitest run",
105
+ "posttest:run": "node ./scripts/manage-pnpm-override.mjs remove",
100
106
  "test:update-fixtures": "node ./dist/cli.mjs ./scripts/update-fixtures.ts",
101
107
  "benchmark": "tsdown -c benchmark/tsdown.config.ts && node ./benchmark/dist/benchmark.mjs",
102
108
  "typecheck": "tsc --noEmit",