@poe-platform/safe-js 0.1.730 → 0.1.732

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.
Files changed (100) hide show
  1. package/README.md +5 -5
  2. package/dist/safe-js/chunks/{chunk-SJZWSPWD.js → chunk-2GVBG23M.js} +1 -1
  3. package/dist/safe-js/chunks/{chunk-SJZWSPWD.js.map → chunk-2GVBG23M.js.map} +1 -1
  4. package/dist/safe-js/chunks/{chunk-MW2QLYVN.js → chunk-3ITVV2R6.js} +77 -66
  5. package/dist/safe-js/chunks/chunk-3ITVV2R6.js.map +7 -0
  6. package/dist/safe-js/chunks/{chunk-VIMROAQA.js → chunk-E4XLBT7R.js} +2 -2
  7. package/dist/safe-js/chunks/chunk-F6CV74HU.js +114 -0
  8. package/dist/safe-js/chunks/chunk-F6CV74HU.js.map +7 -0
  9. package/dist/safe-js/chunks/{chunk-OZLTLIHX.js → chunk-G6WTEIJJ.js} +2 -2
  10. package/dist/safe-js/chunks/{chunk-XX57YCGZ.js → chunk-GNEORAQI.js} +55 -50
  11. package/dist/safe-js/chunks/chunk-GNEORAQI.js.map +7 -0
  12. package/dist/safe-js/chunks/chunk-GVKXZW53.js +76 -0
  13. package/dist/safe-js/chunks/chunk-GVKXZW53.js.map +7 -0
  14. package/dist/safe-js/chunks/{chunk-MRULOD5J.js → chunk-K4T4EBED.js} +59 -38
  15. package/dist/safe-js/chunks/chunk-K4T4EBED.js.map +7 -0
  16. package/dist/safe-js/chunks/{chunk-MFCEBCGV.js → chunk-KETIFEA7.js} +17 -8
  17. package/dist/safe-js/chunks/chunk-KETIFEA7.js.map +7 -0
  18. package/dist/safe-js/chunks/{chunk-S5YDMMM3.js → chunk-MDIWQFYU.js} +95 -169
  19. package/dist/safe-js/chunks/{chunk-S5YDMMM3.js.map → chunk-MDIWQFYU.js.map} +4 -4
  20. package/dist/safe-js/chunks/{chunk-EN724VH3.js → chunk-O4IDRXW7.js} +4 -4
  21. package/dist/safe-js/chunks/{chunk-3LSNBW5N.js → chunk-P64CQIUA.js} +4 -4
  22. package/dist/safe-js/chunks/{chunk-EA7AHM2X.js → chunk-PSVV3IG2.js} +3 -3
  23. package/dist/safe-js/chunks/{chunk-Y5EZYHU6.js → chunk-QKO4FATZ.js} +33 -5
  24. package/dist/safe-js/chunks/chunk-QKO4FATZ.js.map +7 -0
  25. package/dist/safe-js/chunks/{chunk-EG3QWREA.js → chunk-RULU2F5J.js} +2 -2
  26. package/dist/safe-js/chunks/chunk-UQPYTZOZ.js +72 -0
  27. package/dist/safe-js/chunks/chunk-UQPYTZOZ.js.map +7 -0
  28. package/dist/safe-js/chunks/{chunk-LRSWTDIV.js → chunk-W4SWUHCQ.js} +58 -23
  29. package/dist/safe-js/chunks/chunk-W4SWUHCQ.js.map +7 -0
  30. package/dist/safe-js/chunks/{chunk-W3IY6FKO.js → chunk-WS2FJBH6.js} +2 -2
  31. package/dist/safe-js/chunks/{chunk-MVLDRXWS.js → chunk-X3CKAZQ4.js} +3 -3
  32. package/dist/safe-js/chunks/chunk-YUQFFRUF.js +26 -0
  33. package/dist/safe-js/chunks/chunk-YUQFFRUF.js.map +7 -0
  34. package/dist/safe-js/chunks/{cli-runtime-WSVW5DNT.js → cli-runtime-ZSOTNIVC.js} +51 -30
  35. package/dist/safe-js/chunks/cli-runtime-ZSOTNIVC.js.map +7 -0
  36. package/dist/safe-js/chunks/{dump-UNYK24YS.js → dump-RGRC3CG3.js} +5 -4
  37. package/dist/safe-js/chunks/harness-UMOMFXDT.js +11 -0
  38. package/dist/safe-js/chunks/mcp-2Z4XWHKW.js +12 -0
  39. package/dist/safe-js/chunks/migration-file-KRXQYI3Q.js +15 -0
  40. package/dist/safe-js/chunks/restore-GEO7VN2R.js +14 -0
  41. package/dist/safe-js/chunks/run-ZSFX66RN.js +20 -0
  42. package/dist/safe-js/chunks/runtime-modules-A3U2DKFL.js +11 -0
  43. package/dist/safe-js/chunks/source-files-L3SGK63Z.js +10 -0
  44. package/dist/safe-js/cli-runtime.d.ts +2 -0
  45. package/dist/safe-js/cli.js +4 -4
  46. package/dist/safe-js/core.d.ts +1 -0
  47. package/dist/safe-js/core.js +15 -8
  48. package/dist/safe-js/error/shape.js +170 -0
  49. package/dist/safe-js/index.js +42 -33
  50. package/dist/safe-js/index.js.map +2 -2
  51. package/dist/safe-js/interp/budget.js +600 -0
  52. package/dist/safe-js/interp/internal-symbols.js +1 -0
  53. package/dist/safe-js/interp/promise-replay.d.ts +1 -1
  54. package/dist/safe-js/interp/template-cache.js +7 -0
  55. package/dist/safe-js/migration-file.d.ts +2 -0
  56. package/dist/safe-js/modules/fs-config.d.ts +3 -1
  57. package/dist/safe-js/modules/fs.d.ts +8 -4
  58. package/dist/safe-js/modules/fs.js +16 -0
  59. package/dist/safe-js/modules/source-files.d.ts +3 -2
  60. package/dist/safe-js/platform/context.js +58 -0
  61. package/dist/safe-js/platform/node.js +64 -0
  62. package/dist/safe-js/platform/types.js +63 -0
  63. package/dist/safe-js/platform/workerd.js +39 -0
  64. package/dist/safe-js/runner/run-harness.d.ts +2 -0
  65. package/dist/safe-js/snapshot/backend.d.ts +2 -0
  66. package/package.json +9 -2
  67. package/dist/safe-js/chunks/chunk-FCCA27RC.js +0 -69
  68. package/dist/safe-js/chunks/chunk-FCCA27RC.js.map +0 -7
  69. package/dist/safe-js/chunks/chunk-LRSWTDIV.js.map +0 -7
  70. package/dist/safe-js/chunks/chunk-MFCEBCGV.js.map +0 -7
  71. package/dist/safe-js/chunks/chunk-MRULOD5J.js.map +0 -7
  72. package/dist/safe-js/chunks/chunk-MW2QLYVN.js.map +0 -7
  73. package/dist/safe-js/chunks/chunk-XX57YCGZ.js.map +0 -7
  74. package/dist/safe-js/chunks/chunk-Y5EZYHU6.js.map +0 -7
  75. package/dist/safe-js/chunks/cli-runtime-WSVW5DNT.js.map +0 -7
  76. package/dist/safe-js/chunks/fs-AOV77RQC.js +0 -13
  77. package/dist/safe-js/chunks/harness-ZIEO7NAV.js +0 -10
  78. package/dist/safe-js/chunks/mcp-E2AJXEQM.js +0 -11
  79. package/dist/safe-js/chunks/migration-file-3SWGNDS2.js +0 -12
  80. package/dist/safe-js/chunks/restore-FCTWPLU3.js +0 -13
  81. package/dist/safe-js/chunks/run-ESJHEXCE.js +0 -17
  82. package/dist/safe-js/chunks/runtime-modules-7V6BWCRK.js +0 -10
  83. package/dist/safe-js/chunks/source-files-73OHLNGH.js +0 -8
  84. /package/dist/safe-js/chunks/{chunk-VIMROAQA.js.map → chunk-E4XLBT7R.js.map} +0 -0
  85. /package/dist/safe-js/chunks/{chunk-OZLTLIHX.js.map → chunk-G6WTEIJJ.js.map} +0 -0
  86. /package/dist/safe-js/chunks/{chunk-EN724VH3.js.map → chunk-O4IDRXW7.js.map} +0 -0
  87. /package/dist/safe-js/chunks/{chunk-3LSNBW5N.js.map → chunk-P64CQIUA.js.map} +0 -0
  88. /package/dist/safe-js/chunks/{chunk-EA7AHM2X.js.map → chunk-PSVV3IG2.js.map} +0 -0
  89. /package/dist/safe-js/chunks/{chunk-EG3QWREA.js.map → chunk-RULU2F5J.js.map} +0 -0
  90. /package/dist/safe-js/chunks/{chunk-W3IY6FKO.js.map → chunk-WS2FJBH6.js.map} +0 -0
  91. /package/dist/safe-js/chunks/{chunk-MVLDRXWS.js.map → chunk-X3CKAZQ4.js.map} +0 -0
  92. /package/dist/safe-js/chunks/{dump-UNYK24YS.js.map → dump-RGRC3CG3.js.map} +0 -0
  93. /package/dist/safe-js/chunks/{fs-AOV77RQC.js.map → harness-UMOMFXDT.js.map} +0 -0
  94. /package/dist/safe-js/chunks/{harness-ZIEO7NAV.js.map → mcp-2Z4XWHKW.js.map} +0 -0
  95. /package/dist/safe-js/chunks/{mcp-E2AJXEQM.js.map → migration-file-KRXQYI3Q.js.map} +0 -0
  96. /package/dist/safe-js/chunks/{migration-file-3SWGNDS2.js.map → restore-GEO7VN2R.js.map} +0 -0
  97. /package/dist/safe-js/chunks/{restore-FCTWPLU3.js.map → run-ZSFX66RN.js.map} +0 -0
  98. /package/dist/safe-js/chunks/{run-ESJHEXCE.js.map → runtime-modules-A3U2DKFL.js.map} +0 -0
  99. /package/dist/safe-js/chunks/{runtime-modules-7V6BWCRK.js.map → source-files-L3SGK63Z.js.map} +0 -0
  100. /package/dist/safe-js/{chunks/source-files-73OHLNGH.js.map → modules/fs.js.map} +0 -0
@@ -0,0 +1,16 @@
1
+ import {
2
+ FS_OPTION_SURFACE,
3
+ makeFsModule
4
+ } from "../chunks/chunk-K4T4EBED.js";
5
+ import "../chunks/chunk-GVKXZW53.js";
6
+ import "../chunks/chunk-2GVBG23M.js";
7
+ import "../chunks/chunk-MDIWQFYU.js";
8
+ import "../chunks/chunk-QKO4FATZ.js";
9
+ import "../chunks/chunk-YUQFFRUF.js";
10
+ import "../chunks/chunk-UQPYTZOZ.js";
11
+ import "../chunks/chunk-4YIDX44G.js";
12
+ export {
13
+ FS_OPTION_SURFACE,
14
+ makeFsModule
15
+ };
16
+ //# sourceMappingURL=fs.js.map
@@ -1,5 +1,6 @@
1
+ import { type FileSystem } from "@poe-platform/safe-fs/core";
1
2
  import type { SourceResolver } from "./source-graph.js";
2
- /** Explicit Node host grant. No package lookup, extension search, or URL loading. */
3
- export declare function createRootedSourceResolver(root: string): Promise<SourceResolver & {
3
+ /** Explicit filesystem grant. No package lookup, extension search, or URL loading. */
4
+ export declare function createRootedSourceResolver(root: string, adapter?: FileSystem): Promise<SourceResolver & {
4
5
  entryId(filename?: string): Promise<string>;
5
6
  }>;
@@ -0,0 +1,58 @@
1
+ /** Stack-scoped context for hosts without native asynchronous context support.
2
+ * Continuations scheduled by SafeJS capture and restore these stacks explicitly.
3
+ */
4
+ export class StackContext {
5
+ static stores = new Set();
6
+ value;
7
+ generation = 0;
8
+ constructor() { StackContext.stores.add(new WeakRef(this)); }
9
+ getStore() { return this.value; }
10
+ run(value, callback) {
11
+ const previous = this.value;
12
+ const generation = this.generation;
13
+ this.value = value;
14
+ try {
15
+ return callback();
16
+ }
17
+ finally {
18
+ if (this.generation === generation)
19
+ this.value = previous;
20
+ }
21
+ }
22
+ exit(callback) {
23
+ const previous = this.value;
24
+ const generation = this.generation;
25
+ this.value = undefined;
26
+ try {
27
+ return callback();
28
+ }
29
+ finally {
30
+ if (this.generation === generation)
31
+ this.value = previous;
32
+ }
33
+ }
34
+ disable() { this.value = undefined; this.generation++; }
35
+ static snapshot() {
36
+ const values = [];
37
+ for (const reference of StackContext.stores) {
38
+ const store = reference.deref();
39
+ if (store === undefined)
40
+ StackContext.stores.delete(reference);
41
+ else
42
+ values.push([store, store.value, store.generation]);
43
+ }
44
+ return callback => {
45
+ const restore = values.map(([store]) => store.value);
46
+ for (const [store, value, generation] of values)
47
+ if (store.generation === generation)
48
+ store.value = value;
49
+ try {
50
+ return callback();
51
+ }
52
+ finally {
53
+ values.forEach(([store, , generation], index) => { if (store.generation === generation)
54
+ store.value = restore[index]; });
55
+ }
56
+ };
57
+ }
58
+ }
@@ -0,0 +1,64 @@
1
+ import * as nodeUtil from "node:util";
2
+ import * as nativeFsPromises from "node:fs/promises";
3
+ import { AsyncLocalStorage } from "node:async_hooks";
4
+ import { MessageChannel, MessagePort, receiveMessageOnPort } from "node:worker_threads";
5
+ const nativeClone = structuredClone;
6
+ const sharedByteLength = Object.getOwnPropertyDescriptor(SharedArrayBuffer.prototype, "byteLength").get;
7
+ const postMessage = MessagePort.prototype.postMessage;
8
+ const closePort = MessagePort.prototype.close;
9
+ // Probe private storage once: a broken native clone must never copy a guest's
10
+ // potentially large allocation before selecting the shared-wrapper fallback.
11
+ const probe = new SharedArrayBuffer(1);
12
+ let nativeSharesStorage = false;
13
+ try {
14
+ const copy = nativeClone(probe);
15
+ Reflect.apply(sharedByteLength, copy, []);
16
+ new Uint8Array(copy)[0] = 1;
17
+ nativeSharesStorage = copy !== probe && new Uint8Array(probe)[0] === 1;
18
+ }
19
+ catch {
20
+ // Some supported hosts do not implement shared-buffer structured cloning.
21
+ }
22
+ export const cloneSharedBufferWrapper = nativeSharesStorage
23
+ ? nativeClone
24
+ : (value) => {
25
+ Reflect.apply(sharedByteLength, value, []);
26
+ const { port1, port2 } = new MessageChannel();
27
+ try {
28
+ Reflect.apply(postMessage, port1, [value]);
29
+ const copy = receiveMessageOnPort(port2)?.message;
30
+ Reflect.apply(sharedByteLength, copy, []);
31
+ if (copy === value)
32
+ throw new TypeError("Shared storage requires a distinct wrapper.");
33
+ return copy;
34
+ }
35
+ finally {
36
+ Reflect.apply(closePort, port1, []);
37
+ Reflect.apply(closePort, port2, []);
38
+ }
39
+ };
40
+ export function createHostCallbackContext() {
41
+ return new AsyncLocalStorage();
42
+ }
43
+ export const accessDeniedSystemError = readSystemError("EACCES");
44
+ function readSystemError(code) {
45
+ const fallback = new Map([
46
+ [process.platform === "win32" ? -4092 : -13, ["EACCES", "permission denied"]]
47
+ ]);
48
+ const systemErrors = nodeUtil.getSystemErrorMap?.() ?? fallback;
49
+ for (const [errno, [name, message]] of systemErrors) {
50
+ if (name === code) {
51
+ return [errno, message];
52
+ }
53
+ }
54
+ throw new Error(`node does not define the ${code} system error.`);
55
+ }
56
+ export { AsyncLocalStorage };
57
+ export const types = nodeUtil.types;
58
+ export { setImmediate as yieldToHost } from "node:timers/promises";
59
+ export { inspect } from "node:util";
60
+ export { formatWithOptions } from "node:util";
61
+ export { constants as fsConstants } from "node:fs";
62
+ export const hostFs = nativeFsPromises;
63
+ export const hostCwd = process.cwd.bind(process);
64
+ export const hostPlatform = process.platform;
@@ -0,0 +1,63 @@
1
+ // Slot probes do not read user properties or Symbol.toStringTag.
2
+ function slot(method, value) {
3
+ if (typeof value !== "object" || value === null)
4
+ return false;
5
+ try {
6
+ Reflect.apply(method, value, []);
7
+ return true;
8
+ }
9
+ catch {
10
+ return false;
11
+ }
12
+ }
13
+ const getter = (prototype, key) => Object.getOwnPropertyDescriptor(prototype, key).get;
14
+ const regexpPrototype = RegExp.prototype;
15
+ const regexpSource = getter(regexpPrototype, "source");
16
+ const booleanValue = Boolean.prototype.valueOf;
17
+ const numberValue = Number.prototype.valueOf;
18
+ const stringValue = String.prototype.valueOf;
19
+ const bigintValue = BigInt.prototype.valueOf;
20
+ const symbolValue = Symbol.prototype.valueOf;
21
+ const dateValue = Date.prototype.getTime;
22
+ const asyncFunctionPrototype = Object.getPrototypeOf(async function () { });
23
+ const generatorFunctionPrototype = Object.getPrototypeOf(function* () { });
24
+ const arrayBufferLength = getter(ArrayBuffer.prototype, "byteLength");
25
+ const dataViewBuffer = getter(DataView.prototype, "buffer");
26
+ const mapSize = getter(Map.prototype, "size");
27
+ const promiseThen = Promise.prototype.then;
28
+ const NativeError = Error;
29
+ const nativeIsError = Reflect.get(NativeError, "isError");
30
+ const proxies = new WeakSet();
31
+ export function createTrackedProxy(target, handler) {
32
+ const proxy = new Proxy(target, handler);
33
+ proxies.add(proxy);
34
+ return proxy;
35
+ }
36
+ export const types = {
37
+ isProxy: (value) => (typeof value === "object" && value !== null || typeof value === "function") && proxies.has(value),
38
+ isBooleanObject: (value) => typeof value === "object" && value !== null && slot(booleanValue, value),
39
+ isNumberObject: (value) => typeof value === "object" && value !== null && slot(numberValue, value),
40
+ isStringObject: (value) => typeof value === "object" && slot(stringValue, value),
41
+ isBigIntObject: (value) => typeof value === "object" && value !== null && slot(bigintValue, value),
42
+ isSymbolObject: (value) => typeof value === "object" && value !== null && slot(symbolValue, value),
43
+ isDate: (value) => slot(dateValue, value),
44
+ isRegExp: (value) => value !== regexpPrototype && slot(regexpSource, value),
45
+ isArrayBuffer: (value) => slot(arrayBufferLength, value),
46
+ isDataView: (value) => slot(dataViewBuffer, value),
47
+ isMap: (value) => slot(mapSize, value),
48
+ isPromise(value) {
49
+ // Promise has no exposed slot getter. Handle both branches so the probe
50
+ // cannot introduce an unhandled rejection.
51
+ try {
52
+ Reflect.apply(promiseThen, value, [() => undefined, () => undefined]);
53
+ return true;
54
+ }
55
+ catch {
56
+ return false;
57
+ }
58
+ },
59
+ isAsyncFunction: (value) => typeof value === "function" && Object.getPrototypeOf(value) === asyncFunctionPrototype,
60
+ isGeneratorFunction: (value) => typeof value === "function" && Object.getPrototypeOf(value) === generatorFunctionPrototype,
61
+ isNativeError: (value) => typeof value === "object" && value !== null &&
62
+ (typeof nativeIsError === "function" ? Reflect.apply(nativeIsError, NativeError, [value]) === true : value instanceof NativeError)
63
+ };
@@ -0,0 +1,39 @@
1
+ import { StackContext } from "./context.js";
2
+ // Hosts may supply native asynchronous context without Node module resolution.
3
+ export const AsyncLocalStorage = Reflect.get(globalThis, "AsyncLocalStorage") ?? StackContext;
4
+ export { types } from "./types.js";
5
+ import { SandboxError } from "../interp/budget.js";
6
+ export const cloneSharedBufferWrapper = structuredClone;
7
+ export function createHostCallbackContext() {
8
+ let storage = new AsyncLocalStorage();
9
+ return {
10
+ run(value, callback) {
11
+ if (storage === undefined)
12
+ throw new SandboxError("reentry");
13
+ return storage.run(value, callback);
14
+ },
15
+ getStore() {
16
+ return storage?.getStore();
17
+ },
18
+ disable() {
19
+ // Workerd has no native disable. Retire access even in retained async contexts.
20
+ storage = undefined;
21
+ }
22
+ };
23
+ }
24
+ export const accessDeniedSystemError = [-13, "permission denied"];
25
+ export const yieldToHost = () => new Promise(resolve => setTimeout(resolve, 0));
26
+ export const hostCwd = () => "/";
27
+ export const hostPlatform = "workerd";
28
+ export const fsConstants = { F_OK: 0, R_OK: 4, W_OK: 2, X_OK: 1, COPYFILE_EXCL: 1 };
29
+ export const hostFs = new Proxy({}, {
30
+ get() { throw new TypeError("A filesystem adapter is required on this host."); }
31
+ });
32
+ // Diagnostics use data descriptors and never invoke a caller's toString.
33
+ export function inspect(value, _options) {
34
+ if (typeof value === "string")
35
+ return "'" + value.replaceAll("'", "\\'") + "'";
36
+ if (typeof value === "object" && value !== null)
37
+ return Array.isArray(value) ? "[Array]" : "[Object]";
38
+ return String(value);
39
+ }
@@ -1,3 +1,4 @@
1
+ import { type FileSystem } from "@poe-platform/safe-fs/core";
1
2
  import { type Diagnostic } from "../lint.js";
2
3
  import type { ModuleRegistry } from "../modules/registry.js";
3
4
  import type { OtelSink } from "../observability/otel.js";
@@ -9,6 +10,7 @@ type HarnessMeta = {
9
10
  version: unknown;
10
11
  };
11
12
  export type RunHarnessOptions = {
13
+ adapter?: FileSystem;
12
14
  budget?: RunOptions["budget"];
13
15
  modulesFor: (frontmatter: Record<string, unknown>, meta: HarnessMeta) => ModuleRegistry;
14
16
  otelSink?: OtelSink;
@@ -1,3 +1,4 @@
1
+ import { type FileSystem } from "@poe-platform/safe-fs/core";
1
2
  import type { SafeJSSnapshot } from "../restore.js";
2
3
  export type Snapshot = SafeJSSnapshot;
3
4
  export interface SnapshotBackend {
@@ -6,6 +7,7 @@ export interface SnapshotBackend {
6
7
  remove(): Promise<void>;
7
8
  }
8
9
  export type FileSnapshotBackendOptions = {
10
+ adapter?: FileSystem;
9
11
  writeMaxAttempts?: number;
10
12
  writeRetryDelayMs?: number;
11
13
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poe-platform/safe-js",
3
- "version": "0.1.730",
3
+ "version": "0.1.732",
4
4
  "description": "Budgeted JavaScript interpreter with explicit host capabilities and resumable execution",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -58,7 +58,7 @@
58
58
  "access": "public"
59
59
  },
60
60
  "dependencies": {
61
- "@poe-platform/safe-fs": "0.1.730",
61
+ "@poe-platform/safe-fs": "0.1.732",
62
62
  "@petamoriken/float16": "^3.9.3",
63
63
  "@noble/hashes": "2.4.0",
64
64
  "@formatjs/intl-localematcher": "0.8.13",
@@ -70,6 +70,13 @@
70
70
  "@formatjs/intl-numberformat": "9.4.0",
71
71
  "@types/node": "^25.2.2"
72
72
  },
73
+ "imports": {
74
+ "#safe-js-platform": {
75
+ "workerd": "./dist/safe-js/platform/workerd.js",
76
+ "browser": "./dist/safe-js/platform/workerd.js",
77
+ "default": "./dist/safe-js/platform/node.js"
78
+ }
79
+ },
73
80
  "bin": {
74
81
  "poe-safejs": "./dist/safe-js/cli.js",
75
82
  "poe-safe-js": "./dist/safe-js/cli.js"
@@ -1,69 +0,0 @@
1
- // packages/safe-js/src/modules/source-files.ts
2
- import { open, realpath, stat } from "node:fs/promises";
3
- import { constants } from "node:fs";
4
- import path from "node:path";
5
- async function createRootedSourceResolver(root) {
6
- const directory = await realpath(root);
7
- const granted = path.resolve(root);
8
- if (!(await stat(directory)).isDirectory()) throw new TypeError("Source module root must be a directory.");
9
- const contains = (filename) => {
10
- const relative = path.relative(directory, filename);
11
- return relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
12
- };
13
- const resolver = async (specifier, referrer, { signal }) => {
14
- signal?.throwIfAborted();
15
- if (!specifier.startsWith("./") && !specifier.startsWith("../") || !path.isAbsolute(referrer)) return void 0;
16
- const relative = path.relative(granted, referrer);
17
- const canonicalReferrer = relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative) ? path.resolve(directory, relative) : referrer;
18
- if (!contains(canonicalReferrer)) return void 0;
19
- const candidate = path.resolve(path.dirname(canonicalReferrer), specifier);
20
- if (!contains(candidate)) return void 0;
21
- try {
22
- const id = await realpath(candidate);
23
- signal?.throwIfAborted();
24
- if (!contains(id)) return void 0;
25
- const expected = await stat(id);
26
- signal?.throwIfAborted();
27
- if (!expected.isFile()) return void 0;
28
- const handle = await open(id, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
29
- try {
30
- signal?.throwIfAborted();
31
- const actual = await handle.stat();
32
- signal?.throwIfAborted();
33
- if (!actual.isFile() || actual.dev !== expected.dev || actual.ino !== expected.ino) return void 0;
34
- const currentId = await realpath(id);
35
- signal?.throwIfAborted();
36
- if (currentId !== id) return void 0;
37
- const source = await handle.readFile({ encoding: "utf8", signal });
38
- signal?.throwIfAborted();
39
- return { id, source };
40
- } finally {
41
- await handle.close();
42
- }
43
- } catch (error) {
44
- signal?.throwIfAborted();
45
- if (error !== null && typeof error === "object" && "code" in error && ["ENOENT", "ENOTDIR", "ELOOP"].includes(String(error.code))) return void 0;
46
- throw error;
47
- }
48
- };
49
- return Object.assign(resolver, { async entryId(filename) {
50
- if (filename === void 0) return path.join(directory, "<entry>");
51
- const supplied = path.resolve(granted, filename);
52
- const relative = path.relative(granted, supplied);
53
- const candidate = relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative) ? path.resolve(directory, relative) : supplied;
54
- if (!contains(candidate)) throw new TypeError("Source entry must be inside its granted root.");
55
- try {
56
- const id = await realpath(candidate);
57
- if (!contains(id)) throw new TypeError("Source entry must be inside its granted root.");
58
- return id;
59
- } catch (error) {
60
- if (error !== null && typeof error === "object" && "code" in error && error.code === "ENOENT") return candidate;
61
- throw error;
62
- }
63
- } });
64
- }
65
-
66
- export {
67
- createRootedSourceResolver
68
- };
69
- //# sourceMappingURL=chunk-FCCA27RC.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/modules/source-files.ts"],
4
- "sourcesContent": ["import {open,realpath,stat} from \"node:fs/promises\";\nimport {constants} from \"node:fs\";\nimport path from \"node:path\";\nimport type {SourceResolver} from \"./source-graph.js\";\n\n/** Explicit Node host grant. No package lookup, extension search, or URL loading. */\nexport async function createRootedSourceResolver(root: string): Promise<SourceResolver & {\n entryId(filename?: string): Promise<string>;\n}> {\n const directory = await realpath(root);\n const granted = path.resolve(root);\n if (!(await stat(directory)).isDirectory()) throw new TypeError(\"Source module root must be a directory.\");\n const contains = (filename: string) => {\n const relative = path.relative(directory,filename);\n return relative !== \"..\" && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);\n };\n const resolver: SourceResolver = async (specifier,referrer,{signal}) => {\n signal?.throwIfAborted();\n if ((!specifier.startsWith(\"./\") && !specifier.startsWith(\"../\")) || !path.isAbsolute(referrer)) return undefined;\n const relative = path.relative(granted,referrer);\n const canonicalReferrer = relative !== \"..\" && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative)\n ? path.resolve(directory,relative) : referrer;\n if (!contains(canonicalReferrer)) return undefined;\n const candidate = path.resolve(path.dirname(canonicalReferrer),specifier);\n if (!contains(candidate)) return undefined;\n try {\n const id = await realpath(candidate);\n signal?.throwIfAborted();\n if (!contains(id)) return undefined;\n const expected = await stat(id);\n signal?.throwIfAborted();\n if (!expected.isFile()) return undefined;\n const handle = await open(id,constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);\n try {\n signal?.throwIfAborted();\n const actual = await handle.stat();\n signal?.throwIfAborted();\n // Read the checked inode, never reopen its pathname. These checks deny\n // observed replacements; Node's path APIs do not provide atomic ancestor\n // confinement against an adversary repeatedly swapping directories.\n if (!actual.isFile() || actual.dev !== expected.dev || actual.ino !== expected.ino) return undefined;\n const currentId = await realpath(id);\n signal?.throwIfAborted();\n if (currentId !== id) return undefined;\n const source = await handle.readFile({encoding:\"utf8\",signal});\n signal?.throwIfAborted();\n return {id,source};\n } finally {await handle.close();}\n } catch (error) {\n signal?.throwIfAborted();\n if (error !== null && typeof error === \"object\" && \"code\" in error &&\n [\"ENOENT\",\"ENOTDIR\",\"ELOOP\"].includes(String(error.code))) return undefined;\n throw error;\n }\n };\n return Object.assign(resolver, {async entryId(filename?: string): Promise<string> {\n if (filename === undefined) return path.join(directory,\"<entry>\");\n const supplied = path.resolve(granted,filename);\n const relative = path.relative(granted,supplied);\n const candidate = relative !== \"..\" && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative)\n ? path.resolve(directory,relative) : supplied;\n if (!contains(candidate)) throw new TypeError(\"Source entry must be inside its granted root.\");\n try {\n const id = await realpath(candidate);\n if (!contains(id)) throw new TypeError(\"Source entry must be inside its granted root.\");\n return id;\n } catch (error) {\n if (error !== null && typeof error === \"object\" && \"code\" in error && error.code === \"ENOENT\") return candidate;\n throw error;\n }\n }});\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/migration-file.ts", "../../src/migrate.ts"],
4
- "sourcesContent": ["import { randomUUID } from \"node:crypto\";\nimport { link, open, readFile, unlink } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { hasOwnErrorCode } from \"./error-codes.js\";\n\nimport {\n inspectSnapshotMigration,\n migrateSnapshot,\n type SnapshotMigrationOptions\n} from \"./migrate.js\";\nimport type { SafeJSSnapshot } from \"./restore.js\";\nimport { serializeSafeJSSnapshot } from \"./snapshot/dump-format.js\";\n\nexport type SnapshotMigrationFileOptions = {\n snapshotPath: string;\n sourcePath: string;\n targetSourcePath?: string;\n planPath?: string;\n outputPath?: string;\n inspect?: boolean;\n dryRun?: boolean;\n cwd?: string;\n};\n\nexport async function migrateSnapshotFile(options: SnapshotMigrationFileOptions) {\n const cwd = options.cwd ?? process.cwd();\n const resolvePath = (value: string | undefined, label: string) => {\n if (typeof value !== \"string\" || value.trim().length === 0)\n throw new TypeError(`Migration requires ${label}.`);\n return path.resolve(cwd, value);\n };\n const snapshotPath = resolvePath(options.snapshotPath, \"a snapshot path\");\n const sourcePath = resolvePath(options.sourcePath, \"--from <original.ajs>\");\n if (\n options.inspect &&\n [options.targetSourcePath, options.planPath, options.outputPath].some(\n (value) => value !== undefined\n )\n )\n throw new TypeError(\"Migration --inspect cannot be combined with --to, --plan, or --output.\");\n const outputPath = options.inspect\n ? undefined\n : resolvePath(options.outputPath, \"--output <new-checkpoint.json>\");\n const targetSourcePath = options.inspect\n ? undefined\n : resolvePath(options.targetSourcePath, \"--to <continuation.ajs>\");\n const planPath = options.inspect\n ? undefined\n : resolvePath(options.planPath, \"--plan <migration.json>\");\n for (const filepath of [sourcePath, targetSourcePath]) {\n if (filepath !== undefined && ![\".ajs\", \".safejs\"].includes(path.extname(filepath)))\n throw new TypeError(\n \"Migration source paths must name executable .ajs or .safejs files, not harness Markdown.\"\n );\n }\n const snapshot: SafeJSSnapshot = JSON.parse(await readFile(snapshotPath, \"utf8\"));\n const source = await readFile(sourcePath, \"utf8\");\n const inspection = inspectSnapshotMigration(snapshot, { source });\n if (options.inspect) return { inspection };\n const plan: unknown = JSON.parse(await readFile(planPath!, \"utf8\"));\n if (\n plan === null ||\n typeof plan !== \"object\" ||\n !Object.hasOwn(plan, \"state\") ||\n !Object.hasOwn(plan, \"reconciliation\")\n )\n throw new TypeError(\"Migration plan requires explicit state and reconciliation fields.\");\n const targetSource = await readFile(targetSourcePath!, \"utf8\");\n const migrated = migrateSnapshot(snapshot, {\n source,\n targetSource,\n state: (plan as SnapshotMigrationOptions).state,\n reconciliation: (plan as SnapshotMigrationOptions).reconciliation\n });\n const contents = serializeSafeJSSnapshot(migrated);\n if (!options.dryRun) {\n const temporaryPath = path.join(\n path.dirname(outputPath!),\n `.safejs-migration-${randomUUID()}.tmp`\n );\n let created = false;\n try {\n const handle = await open(temporaryPath, \"wx\", 0o600);\n created = true;\n try {\n await handle.writeFile(contents, \"utf8\");\n await handle.sync();\n } finally {\n await handle.close();\n }\n try {\n await link(temporaryPath, outputPath!);\n } catch (error) {\n if (hasOwnErrorCode(error, \"EEXIST\"))\n throw Object.assign(\n new Error(\n `Migration output already exists: ${JSON.stringify(outputPath)}. Choose a new output path; existing files are never overwritten.`,\n { cause: error }\n ),\n { code: \"EEXIST\" }\n );\n throw error;\n }\n } finally {\n if (created) await unlink(temporaryPath);\n }\n }\n return { inspection, outputPath, dryRun: options.dryRun === true };\n}\n", "import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { bytesToHex } from \"@noble/hashes/utils.js\";\n\nimport { assertSnapshotInactive } from \"./interp/running-state.js\";\nimport { deepCopyToSandbox } from \"./interp/values.js\";\nimport { hashSource } from \"./parse/hash.js\";\nimport { parseModule } from \"./parse/parser.js\";\nimport type { SafeJSSnapshot } from \"./restore.js\";\nimport { DUMP_FORMAT_VERSION, EXECUTION_SEMANTICS } from \"./snapshot/dump-format.js\";\nimport {\n validateMigrationJournal,\n validateMigrationReconciliation,\n validateMigrationSemantics,\n validateSnapshotMigration,\n type SnapshotMigration,\n type SnapshotMigrationReconciliation\n} from \"./snapshot/migration.js\";\nimport { encodeReplayData } from \"./snapshot/replay-data.js\";\nimport { validateDumpEnvelope, validateSnapshotData } from \"./snapshot/validation.js\";\n\nexport type {\n SnapshotMigration,\n SnapshotMigrationReconciliation,\n SnapshotMigrationResolution\n} from \"./snapshot/migration.js\";\n\nexport type SnapshotMigrationOptions = {\n source: string;\n targetSource: string;\n state: unknown;\n reconciliation: SnapshotMigrationReconciliation;\n};\n\nexport function inspectSnapshotMigration(snapshot: SafeJSSnapshot, options: { source: string }) {\n assertSnapshotInactive(snapshot);\n validateSnapshotData(snapshot);\n validateDumpEnvelope(snapshot);\n validateMigrationSemantics(snapshot.executionSemantics);\n const sourceHash = hashSource(\n options.source,\n undefined,\n snapshot.executionSemantics === \"jobs-v8\" || snapshot.executionSemantics === EXECUTION_SEMANTICS\n );\n if (snapshot.sourceHash !== sourceHash)\n throw new TypeError(\n `Migration requires the original executable source (checkpoint hash ${snapshot.sourceHash}, supplied ${sourceHash}). Preserve the checkpoint; do not replace its hash.`\n );\n validateSnapshotMigration(snapshot.migration, sourceHash);\n const replay = validateMigrationJournal(sourceHash, snapshot.replay, snapshot.hostCalls);\n return {\n checkpointDigest: bytesToHex(sha256(new TextEncoder().encode(canonicalData(snapshot)))),\n sourceHash,\n executionSemantics: snapshot.executionSemantics,\n calls: replay.calls,\n unresolvedCalls: replay.calls.filter(\n (call) => ![\"settled\", \"consumed\"].includes(call.lifecycle)\n )\n };\n}\n\nexport function migrateSnapshot(\n snapshot: SafeJSSnapshot,\n options: SnapshotMigrationOptions\n): SafeJSSnapshot & { migration: SnapshotMigration } {\n if (!Object.hasOwn(options, \"state\"))\n throw new TypeError(\"Migration requires explicit application state.\");\n const inspection = inspectSnapshotMigration(snapshot, { source: options.source });\n parseModule(options.targetSource);\n const targetSourceHash = hashSource(options.targetSource);\n validateMigrationReconciliation(\n options.reconciliation,\n inspection.checkpointDigest,\n inspection.calls\n );\n const state = encodeReplayData(deepCopyToSandbox(options.state));\n const previous = snapshot.migration as SnapshotMigration | undefined;\n const migration: SnapshotMigration = {\n version: 1,\n state,\n history: [\n ...structuredClone(previous?.history ?? []),\n {\n sourceHash: inspection.sourceHash,\n targetSourceHash,\n executionSemantics: inspection.executionSemantics,\n replay: { version: 1, calls: inspection.calls },\n reconciliation: structuredClone(options.reconciliation)\n }\n ]\n };\n validateSnapshotMigration(migration, targetSourceHash);\n return {\n version: DUMP_FORMAT_VERSION,\n executionSemantics: EXECUTION_SEMANTICS,\n sourceHash: targetSourceHash,\n bindings: {},\n replay: { version: 1, calls: [] },\n migration\n };\n}\n\nfunction canonicalData(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonicalData).join(\",\")}]`;\n if (value !== null && typeof value === \"object\")\n return `{${Object.keys(value)\n .sort()\n .map(\n (key) => `${JSON.stringify(key)}:${canonicalData((value as Record<string, unknown>)[key])}`\n )\n .join(\",\")}}`;\n return JSON.stringify(value);\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }