@secure-exec/core 0.2.1 → 0.3.0-rc.2

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 (248) hide show
  1. package/README.md +5 -5
  2. package/dist/binary.d.ts +4 -0
  3. package/dist/binary.js +25 -0
  4. package/dist/bytes.d.ts +2 -0
  5. package/dist/bytes.js +6 -0
  6. package/dist/callbacks.d.ts +41 -0
  7. package/dist/callbacks.js +94 -0
  8. package/dist/cargo.d.ts +2 -0
  9. package/dist/cargo.js +142 -0
  10. package/dist/correlation.d.ts +10 -0
  11. package/dist/correlation.js +49 -0
  12. package/dist/descriptors.d.ts +34 -0
  13. package/dist/descriptors.js +37 -0
  14. package/dist/event-buffer.d.ts +90 -0
  15. package/dist/event-buffer.js +313 -0
  16. package/dist/ext.d.ts +7 -0
  17. package/dist/ext.js +13 -0
  18. package/dist/filesystem.d.ts +41 -0
  19. package/dist/filesystem.js +70 -0
  20. package/dist/frame-payload-codec.d.ts +8 -0
  21. package/dist/frame-payload-codec.js +14 -0
  22. package/dist/frame-rpc.d.ts +38 -0
  23. package/dist/frame-rpc.js +73 -0
  24. package/dist/frame-stream.d.ts +27 -0
  25. package/dist/frame-stream.js +99 -0
  26. package/dist/framing.d.ts +7 -0
  27. package/dist/framing.js +22 -0
  28. package/dist/generated/AcpLimitsConfig.d.ts +4 -0
  29. package/dist/generated/AcpLimitsConfig.js +2 -0
  30. package/dist/generated/CreateVmConfig.d.ts +19 -0
  31. package/dist/generated/FsPermissionRule.d.ts +6 -0
  32. package/dist/generated/FsPermissionRuleSet.d.ts +6 -0
  33. package/dist/generated/FsPermissionRuleSet.js +1 -0
  34. package/dist/generated/FsPermissionScope.d.ts +3 -0
  35. package/dist/generated/FsPermissionScope.js +1 -0
  36. package/dist/generated/HttpLimitsConfig.d.ts +3 -0
  37. package/dist/generated/HttpLimitsConfig.js +2 -0
  38. package/dist/generated/JsModuleResolution.d.ts +1 -0
  39. package/dist/generated/JsModuleResolution.js +2 -0
  40. package/dist/generated/JsRuntimeConfig.d.ts +26 -0
  41. package/dist/generated/JsRuntimeConfig.js +1 -0
  42. package/dist/generated/JsRuntimeLimitsConfig.d.ts +7 -0
  43. package/dist/generated/JsRuntimeLimitsConfig.js +2 -0
  44. package/dist/generated/JsRuntimePlatform.d.ts +1 -0
  45. package/dist/generated/JsRuntimePlatform.js +2 -0
  46. package/dist/generated/MountPluginDescriptor.d.ts +4 -0
  47. package/dist/generated/MountPluginDescriptor.js +2 -0
  48. package/dist/generated/NativeRootFilesystemConfig.d.ts +5 -0
  49. package/dist/generated/NativeRootFilesystemConfig.js +1 -0
  50. package/dist/generated/PatternPermissionRule.d.ts +6 -0
  51. package/dist/generated/PatternPermissionRule.js +1 -0
  52. package/dist/generated/PatternPermissionRuleSet.d.ts +6 -0
  53. package/dist/generated/PatternPermissionRuleSet.js +1 -0
  54. package/dist/generated/PatternPermissionScope.d.ts +3 -0
  55. package/dist/generated/PatternPermissionScope.js +1 -0
  56. package/dist/generated/PermissionMode.d.ts +1 -0
  57. package/dist/generated/PermissionMode.js +2 -0
  58. package/dist/generated/PermissionsPolicy.d.ts +10 -0
  59. package/dist/generated/PermissionsPolicy.js +1 -0
  60. package/dist/generated/PluginLimitsConfig.d.ts +4 -0
  61. package/dist/generated/PluginLimitsConfig.js +2 -0
  62. package/dist/generated/PythonLimitsConfig.d.ts +5 -0
  63. package/dist/generated/PythonLimitsConfig.js +2 -0
  64. package/dist/generated/ResourceLimitsConfig.d.ts +22 -0
  65. package/dist/generated/ResourceLimitsConfig.js +2 -0
  66. package/dist/generated/RootFilesystemConfig.d.ts +9 -0
  67. package/dist/generated/RootFilesystemConfig.js +1 -0
  68. package/dist/generated/RootFilesystemEntry.d.ts +13 -0
  69. package/dist/generated/RootFilesystemEntry.js +1 -0
  70. package/dist/generated/RootFilesystemEntryEncoding.d.ts +1 -0
  71. package/dist/generated/RootFilesystemEntryEncoding.js +2 -0
  72. package/dist/generated/RootFilesystemEntryKind.d.ts +1 -0
  73. package/dist/generated/RootFilesystemEntryKind.js +2 -0
  74. package/dist/generated/RootFilesystemLowerDescriptor.d.ts +7 -0
  75. package/dist/generated/RootFilesystemLowerDescriptor.js +1 -0
  76. package/dist/generated/RootFilesystemMode.d.ts +1 -0
  77. package/dist/generated/RootFilesystemMode.js +2 -0
  78. package/dist/generated/ToolLimitsConfig.d.ts +10 -0
  79. package/dist/generated/ToolLimitsConfig.js +2 -0
  80. package/dist/generated/VmDnsConfig.d.ts +6 -0
  81. package/dist/generated/VmDnsConfig.js +2 -0
  82. package/dist/generated/VmLimitsConfig.d.ts +18 -0
  83. package/dist/generated/VmLimitsConfig.js +1 -0
  84. package/dist/generated/VmListenPolicyConfig.d.ts +5 -0
  85. package/dist/generated/VmListenPolicyConfig.js +2 -0
  86. package/dist/generated/WasmLimitsConfig.d.ts +5 -0
  87. package/dist/generated/WasmLimitsConfig.js +2 -0
  88. package/dist/generated-protocol.d.ts +1037 -0
  89. package/dist/generated-protocol.js +2887 -0
  90. package/dist/index.d.ts +24 -62
  91. package/dist/index.js +24 -53
  92. package/dist/json.d.ts +2 -0
  93. package/dist/json.js +20 -0
  94. package/dist/kernel-proxy.d.ts +149 -0
  95. package/dist/kernel-proxy.js +1733 -0
  96. package/dist/native-client.d.ts +41 -0
  97. package/dist/native-client.js +124 -0
  98. package/dist/node-runtime.d.ts +490 -0
  99. package/dist/node-runtime.js +585 -0
  100. package/dist/numbers.d.ts +1 -0
  101. package/dist/numbers.js +8 -0
  102. package/dist/ownership.d.ts +18 -0
  103. package/dist/ownership.js +77 -0
  104. package/dist/permissions.d.ts +29 -0
  105. package/dist/permissions.js +68 -0
  106. package/dist/process.d.ts +35 -0
  107. package/dist/process.js +125 -0
  108. package/dist/protocol-client.d.ts +46 -0
  109. package/dist/protocol-client.js +180 -0
  110. package/dist/protocol-frames.d.ts +68 -0
  111. package/dist/protocol-frames.js +139 -0
  112. package/dist/protocol-maps.d.ts +28 -0
  113. package/dist/protocol-maps.js +217 -0
  114. package/dist/protocol-schema.d.ts +10 -0
  115. package/dist/protocol-schema.js +11 -0
  116. package/dist/request-payloads.d.ts +137 -0
  117. package/dist/request-payloads.js +210 -0
  118. package/dist/response-payloads.d.ts +107 -0
  119. package/dist/response-payloads.js +161 -0
  120. package/dist/sidecar-client.d.ts +242 -0
  121. package/dist/sidecar-client.js +797 -0
  122. package/dist/state.d.ts +40 -0
  123. package/dist/state.js +44 -0
  124. package/dist/test-runtime.d.ts +526 -0
  125. package/dist/test-runtime.js +2119 -0
  126. package/dist/vm-config.d.ts +31 -0
  127. package/dist/vm-config.js +1 -0
  128. package/fixtures/alpine-defaults.json +520 -0
  129. package/fixtures/base-filesystem.json +528 -0
  130. package/package.json +193 -115
  131. package/LICENSE +0 -191
  132. package/dist/bridge-setup.d.ts +0 -6
  133. package/dist/bridge-setup.js +0 -9
  134. package/dist/esm-compiler.d.ts +0 -18
  135. package/dist/esm-compiler.js +0 -72
  136. package/dist/fs-helpers.d.ts +0 -23
  137. package/dist/fs-helpers.js +0 -41
  138. package/dist/generated/isolate-runtime.d.ts +0 -19
  139. package/dist/generated/isolate-runtime.js +0 -21
  140. package/dist/generated/polyfills.d.ts +0 -82
  141. package/dist/generated/polyfills.js +0 -82
  142. package/dist/isolate-runtime/apply-custom-global-policy.js +0 -53
  143. package/dist/isolate-runtime/apply-timing-mitigation-freeze.js +0 -130
  144. package/dist/isolate-runtime/apply-timing-mitigation-off.js +0 -14
  145. package/dist/isolate-runtime/bridge-attach.js +0 -29
  146. package/dist/isolate-runtime/bridge-initial-globals.js +0 -385
  147. package/dist/isolate-runtime/eval-script-result.js +0 -8
  148. package/dist/isolate-runtime/global-exposure-helpers.js +0 -36
  149. package/dist/isolate-runtime/init-commonjs-module-globals.js +0 -28
  150. package/dist/isolate-runtime/override-process-cwd.js +0 -8
  151. package/dist/isolate-runtime/override-process-env.js +0 -8
  152. package/dist/isolate-runtime/require-setup.js +0 -4153
  153. package/dist/isolate-runtime/set-commonjs-file-globals.js +0 -36
  154. package/dist/isolate-runtime/set-stdin-data.js +0 -10
  155. package/dist/isolate-runtime/setup-dynamic-import.js +0 -123
  156. package/dist/isolate-runtime/setup-fs-facade.js +0 -87
  157. package/dist/kernel/command-registry.d.ts +0 -44
  158. package/dist/kernel/command-registry.js +0 -114
  159. package/dist/kernel/device-backend.d.ts +0 -14
  160. package/dist/kernel/device-backend.js +0 -251
  161. package/dist/kernel/device-layer.d.ts +0 -12
  162. package/dist/kernel/device-layer.js +0 -271
  163. package/dist/kernel/dns-cache.d.ts +0 -29
  164. package/dist/kernel/dns-cache.js +0 -52
  165. package/dist/kernel/fd-table.d.ts +0 -84
  166. package/dist/kernel/fd-table.js +0 -278
  167. package/dist/kernel/file-lock.d.ts +0 -34
  168. package/dist/kernel/file-lock.js +0 -122
  169. package/dist/kernel/host-adapter.d.ts +0 -50
  170. package/dist/kernel/host-adapter.js +0 -8
  171. package/dist/kernel/index.d.ts +0 -36
  172. package/dist/kernel/index.js +0 -34
  173. package/dist/kernel/kernel.d.ts +0 -9
  174. package/dist/kernel/kernel.js +0 -1415
  175. package/dist/kernel/mount-table.d.ts +0 -75
  176. package/dist/kernel/mount-table.js +0 -353
  177. package/dist/kernel/permissions.d.ts +0 -36
  178. package/dist/kernel/permissions.js +0 -150
  179. package/dist/kernel/pipe-manager.d.ts +0 -64
  180. package/dist/kernel/pipe-manager.js +0 -267
  181. package/dist/kernel/proc-backend.d.ts +0 -30
  182. package/dist/kernel/proc-backend.js +0 -428
  183. package/dist/kernel/proc-layer.d.ts +0 -11
  184. package/dist/kernel/proc-layer.js +0 -507
  185. package/dist/kernel/process-table.d.ts +0 -126
  186. package/dist/kernel/process-table.js +0 -651
  187. package/dist/kernel/pty.d.ts +0 -109
  188. package/dist/kernel/pty.js +0 -552
  189. package/dist/kernel/socket-table.d.ts +0 -312
  190. package/dist/kernel/socket-table.js +0 -1188
  191. package/dist/kernel/timer-table.d.ts +0 -54
  192. package/dist/kernel/timer-table.js +0 -108
  193. package/dist/kernel/types.d.ts +0 -541
  194. package/dist/kernel/types.js +0 -98
  195. package/dist/kernel/user.d.ts +0 -29
  196. package/dist/kernel/user.js +0 -35
  197. package/dist/kernel/vfs.d.ts +0 -82
  198. package/dist/kernel/vfs.js +0 -25
  199. package/dist/kernel/wait.d.ts +0 -45
  200. package/dist/kernel/wait.js +0 -112
  201. package/dist/kernel/wstatus.d.ts +0 -21
  202. package/dist/kernel/wstatus.js +0 -33
  203. package/dist/module-resolver.d.ts +0 -29
  204. package/dist/module-resolver.js +0 -314
  205. package/dist/package-bundler.d.ts +0 -41
  206. package/dist/package-bundler.js +0 -497
  207. package/dist/runtime-driver.d.ts +0 -66
  208. package/dist/shared/api-types.d.ts +0 -83
  209. package/dist/shared/bridge-contract.d.ts +0 -772
  210. package/dist/shared/bridge-contract.js +0 -169
  211. package/dist/shared/console-formatter.d.ts +0 -22
  212. package/dist/shared/console-formatter.js +0 -161
  213. package/dist/shared/constants.d.ts +0 -3
  214. package/dist/shared/constants.js +0 -3
  215. package/dist/shared/errors.d.ts +0 -16
  216. package/dist/shared/errors.js +0 -21
  217. package/dist/shared/esm-utils.d.ts +0 -28
  218. package/dist/shared/esm-utils.js +0 -97
  219. package/dist/shared/global-exposure.d.ts +0 -38
  220. package/dist/shared/global-exposure.js +0 -876
  221. package/dist/shared/in-memory-fs.d.ts +0 -16
  222. package/dist/shared/in-memory-fs.js +0 -115
  223. package/dist/shared/permissions.d.ts +0 -36
  224. package/dist/shared/permissions.js +0 -314
  225. package/dist/shared/require-setup.d.ts +0 -6
  226. package/dist/shared/require-setup.js +0 -9
  227. package/dist/test/block-store-conformance.d.ts +0 -34
  228. package/dist/test/block-store-conformance.js +0 -251
  229. package/dist/test/metadata-store-conformance.d.ts +0 -37
  230. package/dist/test/metadata-store-conformance.js +0 -646
  231. package/dist/test/vfs-conformance.d.ts +0 -65
  232. package/dist/test/vfs-conformance.js +0 -842
  233. package/dist/types.d.ts +0 -98
  234. package/dist/types.js +0 -6
  235. package/dist/vfs/chunked-vfs.d.ts +0 -66
  236. package/dist/vfs/chunked-vfs.js +0 -1290
  237. package/dist/vfs/host-block-store.d.ts +0 -19
  238. package/dist/vfs/host-block-store.js +0 -97
  239. package/dist/vfs/memory-block-store.d.ts +0 -16
  240. package/dist/vfs/memory-block-store.js +0 -45
  241. package/dist/vfs/memory-metadata.d.ts +0 -75
  242. package/dist/vfs/memory-metadata.js +0 -528
  243. package/dist/vfs/sqlite-metadata.d.ts +0 -91
  244. package/dist/vfs/sqlite-metadata.js +0 -582
  245. package/dist/vfs/types.d.ts +0 -210
  246. package/dist/vfs/types.js +0 -8
  247. /package/dist/{runtime-driver.js → generated/CreateVmConfig.js} +0 -0
  248. /package/dist/{shared/api-types.js → generated/FsPermissionRule.js} +0 -0
@@ -1,16 +0,0 @@
1
- /**
2
- * Factory for creating an in-memory VirtualFileSystem backed by ChunkedVFS.
3
- *
4
- * Replaces the old monolithic InMemoryFileSystem with
5
- * ChunkedVFS(InMemoryMetadataStore + InMemoryBlockStore).
6
- */
7
- import type { VirtualFileSystem } from "../kernel/vfs.js";
8
- /**
9
- * Create an in-memory VirtualFileSystem using the chunked storage architecture.
10
- *
11
- * The returned VFS stores all data in memory via InMemoryMetadataStore and
12
- * InMemoryBlockStore, composed through ChunkedVFS. It also includes a
13
- * synchronous `prepareOpenSync` method used by the kernel for O_CREAT/O_EXCL/O_TRUNC
14
- * handling during fdOpen.
15
- */
16
- export declare function createInMemoryFileSystem(): VirtualFileSystem;
@@ -1,115 +0,0 @@
1
- /**
2
- * Factory for creating an in-memory VirtualFileSystem backed by ChunkedVFS.
3
- *
4
- * Replaces the old monolithic InMemoryFileSystem with
5
- * ChunkedVFS(InMemoryMetadataStore + InMemoryBlockStore).
6
- */
7
- import { KernelError, O_CREAT, O_EXCL, O_TRUNC } from "../kernel/types.js";
8
- import { createChunkedVfs } from "../vfs/chunked-vfs.js";
9
- import { InMemoryMetadataStore } from "../vfs/memory-metadata.js";
10
- import { InMemoryBlockStore } from "../vfs/memory-block-store.js";
11
- /**
12
- * Create an in-memory VirtualFileSystem using the chunked storage architecture.
13
- *
14
- * The returned VFS stores all data in memory via InMemoryMetadataStore and
15
- * InMemoryBlockStore, composed through ChunkedVFS. It also includes a
16
- * synchronous `prepareOpenSync` method used by the kernel for O_CREAT/O_EXCL/O_TRUNC
17
- * handling during fdOpen.
18
- */
19
- export function createInMemoryFileSystem() {
20
- const metadata = new InMemoryMetadataStore();
21
- const blocks = new InMemoryBlockStore();
22
- const vfs = createChunkedVfs({ metadata, blocks });
23
- // The kernel's fdOpen calls prepareOpenSync synchronously for O_CREAT,
24
- // O_EXCL, and O_TRUNC flags. Since InMemoryMetadataStore is backed by
25
- // synchronous Maps, we use its synchronous accessor methods directly.
26
- function prepareOpenSync(path, flags) {
27
- const hasCreate = (flags & O_CREAT) !== 0;
28
- const hasExcl = (flags & O_EXCL) !== 0;
29
- const hasTrunc = (flags & O_TRUNC) !== 0;
30
- // Check if path exists via synchronous resolution.
31
- let resolvedIno;
32
- try {
33
- resolvedIno = metadata.resolvePathSync(path);
34
- }
35
- catch {
36
- // ENOENT is expected when the file doesn't exist yet.
37
- }
38
- const exists = resolvedIno !== undefined;
39
- if (hasCreate && hasExcl && exists) {
40
- throw new KernelError("EEXIST", `file already exists, open '${path}'`);
41
- }
42
- let created = false;
43
- if (!exists && hasCreate) {
44
- // Create parent directories and the file synchronously.
45
- const parts = path.replace(/\/+/g, "/").replace(/\/$/, "").split("/").filter(Boolean);
46
- let parentIno = 1; // root
47
- for (let i = 0; i < parts.length - 1; i++) {
48
- const childIno = metadata.lookupSync(parentIno, parts[i]);
49
- if (childIno === null) {
50
- const newIno = metadata.createInodeSync({
51
- type: "directory",
52
- mode: 0o755,
53
- uid: 0,
54
- gid: 0,
55
- });
56
- metadata.updateInodeSync(newIno, { nlink: 2 });
57
- metadata.createDentrySync(parentIno, parts[i], newIno, "directory");
58
- // Increment parent nlink for subdirectory
59
- const parentMeta = metadata.getInodeSync(parentIno);
60
- if (parentMeta) {
61
- metadata.updateInodeSync(parentIno, { nlink: parentMeta.nlink + 1 });
62
- }
63
- parentIno = newIno;
64
- }
65
- else {
66
- parentIno = childIno;
67
- }
68
- }
69
- // Create the file inode.
70
- const fileName = parts[parts.length - 1];
71
- if (fileName) {
72
- const fileIno = metadata.createInodeSync({
73
- type: "file",
74
- mode: 0o644,
75
- uid: 0,
76
- gid: 0,
77
- });
78
- metadata.updateInodeSync(fileIno, {
79
- nlink: 1,
80
- size: 0,
81
- storageMode: "inline",
82
- inlineContent: new Uint8Array(0),
83
- });
84
- try {
85
- metadata.createDentrySync(parentIno, fileName, fileIno, "file");
86
- created = true;
87
- }
88
- catch {
89
- // EEXIST from race condition, ignore.
90
- }
91
- }
92
- }
93
- if (hasTrunc && resolvedIno !== undefined) {
94
- // Check that the target is a file, not a directory.
95
- const meta = metadata.getInodeSync(resolvedIno);
96
- if (meta && meta.type === "directory") {
97
- throw new KernelError("EISDIR", `illegal operation on a directory, open '${path}'`);
98
- }
99
- // Truncate file to 0 bytes.
100
- metadata.updateInodeSync(resolvedIno, {
101
- size: 0,
102
- storageMode: "inline",
103
- inlineContent: new Uint8Array(0),
104
- });
105
- // Delete any existing chunks synchronously.
106
- const keys = metadata.deleteAllChunksSync(resolvedIno);
107
- if (keys.length > 0) {
108
- // Fire-and-forget async block deletion. Blocks are in memory so this resolves immediately.
109
- void blocks.deleteMany(keys);
110
- }
111
- }
112
- return created;
113
- }
114
- return Object.assign(vfs, { prepareOpenSync });
115
- }
@@ -1,36 +0,0 @@
1
- /**
2
- * Permission enforcement layer.
3
- *
4
- * Wraps filesystem, network, and command-executor adapters with permission
5
- * checks that throw EACCES on denial. When no permission callback is provided
6
- * for a category, guarded operations in that category are denied by default.
7
- */
8
- import type { EnvAccessRequest, Permissions } from "../kernel/types.js";
9
- import type { VirtualFileSystem } from "../kernel/vfs.js";
10
- import type { CommandExecutor, NetworkAdapter } from "../types.js";
11
- export declare const allowAllFs: Pick<Permissions, "fs">;
12
- export declare const allowAllNetwork: Pick<Permissions, "network">;
13
- export declare const allowAllChildProcess: Pick<Permissions, "childProcess">;
14
- export declare const allowAllEnv: Pick<Permissions, "env">;
15
- export declare const allowAll: Permissions;
16
- /**
17
- * Wrap a VirtualFileSystem so every operation passes through the fs permission check.
18
- * Throws EACCES if the permission callback denies or is absent.
19
- */
20
- export declare function wrapFileSystem(fs: VirtualFileSystem, permissions?: Permissions): VirtualFileSystem;
21
- /** Wrap a NetworkAdapter so external client operations pass through the network permission check. */
22
- export declare function wrapNetworkAdapter(adapter: NetworkAdapter, permissions?: Permissions): NetworkAdapter;
23
- /** Wrap a CommandExecutor so spawn passes through the childProcess permission check. */
24
- export declare function wrapCommandExecutor(executor: CommandExecutor, permissions?: Permissions): CommandExecutor;
25
- export declare function envAccessAllowed(permissions: Permissions | undefined, request: EnvAccessRequest): void;
26
- /** Create a stub VFS where every operation throws ENOSYS (no filesystem configured). */
27
- export declare function createFsStub(): VirtualFileSystem;
28
- /** Create a stub network adapter where every operation throws ENOSYS. */
29
- export declare function createNetworkStub(): NetworkAdapter;
30
- /** Create a stub executor where spawn throws ENOSYS. */
31
- export declare function createCommandExecutorStub(): CommandExecutor;
32
- /**
33
- * Filter an env record through the env permission check, returning only
34
- * allowed key-value pairs. Returns empty object if no permissions configured.
35
- */
36
- export declare function filterEnv(env: Record<string, string> | undefined, permissions?: Permissions): Record<string, string>;
@@ -1,314 +0,0 @@
1
- /**
2
- * Permission enforcement layer.
3
- *
4
- * Wraps filesystem, network, and command-executor adapters with permission
5
- * checks that throw EACCES on denial. When no permission callback is provided
6
- * for a category, guarded operations in that category are denied by default.
7
- */
8
- import { createEaccesError, createEnosysError } from "./errors.js";
9
- /** Normalize a filesystem path: collapse //, resolve . and .., strip trailing /. */
10
- function normalizeFsPath(path) {
11
- // Collapse repeated slashes
12
- let p = path.replace(/\/+/g, "/");
13
- // Resolve . and .. segments
14
- const parts = p.split("/");
15
- const resolved = [];
16
- for (const seg of parts) {
17
- if (seg === ".")
18
- continue;
19
- if (seg === "..") {
20
- // Don't pop past root
21
- if (resolved.length > 1)
22
- resolved.pop();
23
- }
24
- else {
25
- resolved.push(seg);
26
- }
27
- }
28
- p = resolved.join("/") || "/";
29
- // Strip trailing slash (except root)
30
- if (p.length > 1 && p.endsWith("/")) {
31
- p = p.slice(0, -1);
32
- }
33
- return p;
34
- }
35
- /** Run the permission check; throw the deny error if no checker exists or it denies. */
36
- function checkPermission(check, request, onDenied) {
37
- if (!check) {
38
- throw onDenied(request);
39
- }
40
- const decision = check(request);
41
- if (!decision?.allow) {
42
- throw onDenied(request, decision?.reason);
43
- }
44
- }
45
- // Permission callbacks must be self-contained (no closures) because they are
46
- // serialized via `.toString()` for transfer to the browser Web Worker.
47
- export const allowAllFs = {
48
- fs: () => ({ allow: true }),
49
- };
50
- export const allowAllNetwork = {
51
- network: () => ({ allow: true }),
52
- };
53
- export const allowAllChildProcess = {
54
- childProcess: () => ({ allow: true }),
55
- };
56
- export const allowAllEnv = {
57
- env: () => ({ allow: true }),
58
- };
59
- export const allowAll = {
60
- ...allowAllFs,
61
- ...allowAllNetwork,
62
- ...allowAllChildProcess,
63
- ...allowAllEnv,
64
- };
65
- function fsOpToSyscall(op) {
66
- switch (op) {
67
- case "read":
68
- return "open";
69
- case "write":
70
- return "write";
71
- case "mkdir":
72
- case "createDir":
73
- return "mkdir";
74
- case "readdir":
75
- return "scandir";
76
- case "stat":
77
- return "stat";
78
- case "rm":
79
- return "unlink";
80
- case "rename":
81
- return "rename";
82
- case "exists":
83
- return "access";
84
- case "chmod":
85
- return "chmod";
86
- case "chown":
87
- return "chown";
88
- case "link":
89
- return "link";
90
- case "symlink":
91
- return "symlink";
92
- case "readlink":
93
- return "readlink";
94
- case "truncate":
95
- return "open";
96
- case "utimes":
97
- return "utimes";
98
- default:
99
- return "open";
100
- }
101
- }
102
- /**
103
- * Wrap a VirtualFileSystem so every operation passes through the fs permission check.
104
- * Throws EACCES if the permission callback denies or is absent.
105
- */
106
- export function wrapFileSystem(fs, permissions) {
107
- /** Check fs permission with normalized path to prevent traversal bypasses. */
108
- function checkFs(op, path, reason) {
109
- checkPermission(permissions?.fs, { op, path: normalizeFsPath(path) }, (req, r) => createEaccesError(fsOpToSyscall(req.op), req.path, r));
110
- }
111
- return {
112
- readFile: async (path) => {
113
- checkFs("read", path);
114
- return fs.readFile(path);
115
- },
116
- readTextFile: async (path) => {
117
- checkFs("read", path);
118
- return fs.readTextFile(path);
119
- },
120
- readDir: async (path) => {
121
- checkFs("readdir", path);
122
- return fs.readDir(path);
123
- },
124
- readDirWithTypes: async (path) => {
125
- checkFs("readdir", path);
126
- return fs.readDirWithTypes(path);
127
- },
128
- writeFile: async (path, content) => {
129
- checkFs("write", path);
130
- return fs.writeFile(path, content);
131
- },
132
- createDir: async (path) => {
133
- checkFs("createDir", path);
134
- return fs.createDir(path);
135
- },
136
- mkdir: async (path, options) => {
137
- checkFs("mkdir", path);
138
- return fs.mkdir(path, options);
139
- },
140
- exists: async (path) => {
141
- checkFs("exists", path);
142
- return fs.exists(path);
143
- },
144
- stat: async (path) => {
145
- checkFs("stat", path);
146
- return fs.stat(path);
147
- },
148
- removeFile: async (path) => {
149
- checkFs("rm", path);
150
- return fs.removeFile(path);
151
- },
152
- removeDir: async (path) => {
153
- checkFs("rm", path);
154
- return fs.removeDir(path);
155
- },
156
- rename: async (oldPath, newPath) => {
157
- checkFs("rename", oldPath);
158
- checkFs("rename", newPath);
159
- return fs.rename(oldPath, newPath);
160
- },
161
- symlink: async (target, linkPath) => {
162
- checkFs("symlink", linkPath);
163
- return fs.symlink(target, linkPath);
164
- },
165
- readlink: async (path) => {
166
- checkFs("readlink", path);
167
- return fs.readlink(path);
168
- },
169
- lstat: async (path) => {
170
- checkFs("stat", path);
171
- return fs.lstat(path);
172
- },
173
- link: async (oldPath, newPath) => {
174
- checkFs("link", newPath);
175
- return fs.link(oldPath, newPath);
176
- },
177
- chmod: async (path, mode) => {
178
- checkFs("chmod", path);
179
- return fs.chmod(path, mode);
180
- },
181
- chown: async (path, uid, gid) => {
182
- checkFs("chown", path);
183
- return fs.chown(path, uid, gid);
184
- },
185
- utimes: async (path, atime, mtime) => {
186
- checkFs("utimes", path);
187
- return fs.utimes(path, atime, mtime);
188
- },
189
- truncate: async (path, length) => {
190
- checkFs("truncate", path);
191
- return fs.truncate(path, length);
192
- },
193
- realpath: async (path) => {
194
- checkFs("read", path);
195
- return fs.realpath(path);
196
- },
197
- pread: async (path, offset, length) => {
198
- checkFs("read", path);
199
- return fs.pread(path, offset, length);
200
- },
201
- pwrite: async (path, offset, data) => {
202
- checkFs("write", path);
203
- return fs.pwrite(path, offset, data);
204
- },
205
- };
206
- }
207
- /** Wrap a NetworkAdapter so external client operations pass through the network permission check. */
208
- export function wrapNetworkAdapter(adapter, permissions) {
209
- const loopbackAwareAdapter = adapter;
210
- const wrapped = {
211
- fetch: async (url, options) => {
212
- checkPermission(permissions?.network, { op: "fetch", url, method: options?.method }, (req, reason) => createEaccesError("connect", req.url, reason));
213
- return adapter.fetch(url, options);
214
- },
215
- dnsLookup: async (hostname) => {
216
- checkPermission(permissions?.network, { op: "dns", hostname }, (req, reason) => createEaccesError("connect", req.hostname, reason));
217
- return adapter.dnsLookup(hostname);
218
- },
219
- httpRequest: async (url, options) => {
220
- checkPermission(permissions?.network, { op: "http", url, method: options?.method }, (req, reason) => createEaccesError("connect", req.url, reason));
221
- return adapter.httpRequest(url, options);
222
- },
223
- // Forward upgrade socket methods for bidirectional WebSocket relay
224
- upgradeSocketWrite: adapter.upgradeSocketWrite?.bind(adapter),
225
- upgradeSocketEnd: adapter.upgradeSocketEnd?.bind(adapter),
226
- upgradeSocketDestroy: adapter.upgradeSocketDestroy?.bind(adapter),
227
- setUpgradeSocketCallbacks: adapter.setUpgradeSocketCallbacks?.bind(adapter),
228
- };
229
- if (typeof loopbackAwareAdapter.__setLoopbackPortChecker === "function") {
230
- wrapped.__setLoopbackPortChecker = (checker) => loopbackAwareAdapter.__setLoopbackPortChecker(checker);
231
- }
232
- return wrapped;
233
- }
234
- /** Wrap a CommandExecutor so spawn passes through the childProcess permission check. */
235
- export function wrapCommandExecutor(executor, permissions) {
236
- return {
237
- spawn: (command, args, options) => {
238
- checkPermission(permissions?.childProcess, { command, args, cwd: options.cwd, env: options.env }, (req, reason) => createEaccesError("spawn", req.command, reason));
239
- return executor.spawn(command, args, options);
240
- },
241
- };
242
- }
243
- export function envAccessAllowed(permissions, request) {
244
- checkPermission(permissions?.env, request, (req, reason) => createEaccesError("access", req.key, reason));
245
- }
246
- /** Create a stub VFS where every operation throws ENOSYS (no filesystem configured). */
247
- export function createFsStub() {
248
- const stub = (op, path) => {
249
- throw createEnosysError(op, path);
250
- };
251
- return {
252
- readFile: async (path) => stub("open", path),
253
- readTextFile: async (path) => stub("open", path),
254
- readDir: async (path) => stub("scandir", path),
255
- readDirWithTypes: async (path) => stub("scandir", path),
256
- writeFile: async (path) => stub("write", path),
257
- createDir: async (path) => stub("mkdir", path),
258
- mkdir: async (path) => stub("mkdir", path),
259
- exists: async (path) => stub("access", path),
260
- stat: async (path) => stub("stat", path),
261
- removeFile: async (path) => stub("unlink", path),
262
- removeDir: async (path) => stub("rmdir", path),
263
- rename: async (oldPath, newPath) => stub("rename", `${oldPath}->${newPath}`),
264
- symlink: async (_target, linkPath) => stub("symlink", linkPath),
265
- readlink: async (path) => stub("readlink", path),
266
- lstat: async (path) => stub("stat", path),
267
- link: async (_oldPath, newPath) => stub("link", newPath),
268
- chmod: async (path) => stub("chmod", path),
269
- chown: async (path) => stub("chown", path),
270
- utimes: async (path) => stub("utimes", path),
271
- truncate: async (path) => stub("open", path),
272
- realpath: async (path) => stub("realpath", path),
273
- pread: async (path) => stub("open", path),
274
- pwrite: async (path) => stub("open", path),
275
- };
276
- }
277
- /** Create a stub network adapter where every operation throws ENOSYS. */
278
- export function createNetworkStub() {
279
- const stub = (op, path) => {
280
- throw createEnosysError(op, path);
281
- };
282
- return {
283
- fetch: async (url) => stub("connect", url),
284
- dnsLookup: async (hostname) => stub("connect", hostname),
285
- httpRequest: async (url) => stub("connect", url),
286
- };
287
- }
288
- /** Create a stub executor where spawn throws ENOSYS. */
289
- export function createCommandExecutorStub() {
290
- return {
291
- spawn: () => {
292
- throw createEnosysError("spawn");
293
- },
294
- };
295
- }
296
- /**
297
- * Filter an env record through the env permission check, returning only
298
- * allowed key-value pairs. Returns empty object if no permissions configured.
299
- */
300
- export function filterEnv(env, permissions) {
301
- if (!env)
302
- return {};
303
- if (!permissions?.env)
304
- return {};
305
- const result = {};
306
- for (const [key, value] of Object.entries(env)) {
307
- const request = { op: "read", key, value };
308
- const decision = permissions.env(request);
309
- if (decision?.allow) {
310
- result[key] = value;
311
- }
312
- }
313
- return result;
314
- }
@@ -1,6 +0,0 @@
1
- /**
2
- * Get the isolate-side script that installs the global `require()` function,
3
- * `_requireFrom()`, and require helpers (for example `require.resolve` and
4
- * `require.cache` wiring to the pre-initialized `_moduleCache`).
5
- */
6
- export declare function getRequireSetupCode(): string;
@@ -1,9 +0,0 @@
1
- import { getIsolateRuntimeSource } from "../generated/isolate-runtime.js";
2
- /**
3
- * Get the isolate-side script that installs the global `require()` function,
4
- * `_requireFrom()`, and require helpers (for example `require.resolve` and
5
- * `require.cache` wiring to the pre-initialized `_moduleCache`).
6
- */
7
- export function getRequireSetupCode() {
8
- return getIsolateRuntimeSource("requireSetup");
9
- }
@@ -1,34 +0,0 @@
1
- /**
2
- * Shared FsBlockStore conformance test suite.
3
- *
4
- * Every FsBlockStore implementation must pass the tests in this suite.
5
- * Optional test groups are gated on capability flags declared in the config.
6
- *
7
- * Usage:
8
- *
9
- * ```typescript
10
- * import { defineBlockStoreTests } from "@secure-exec/core/test/block-store-conformance";
11
- *
12
- * defineBlockStoreTests({
13
- * name: "InMemoryBlockStore",
14
- * createStore: () => new InMemoryBlockStore(),
15
- * capabilities: { copy: true },
16
- * });
17
- * ```
18
- */
19
- import type { FsBlockStore } from "../vfs/types.js";
20
- export interface BlockStoreConformanceCapabilities {
21
- /** Whether the store implements the optional copy() method. */
22
- copy: boolean;
23
- }
24
- export interface BlockStoreConformanceConfig {
25
- /** Human-readable name shown in the describe block. */
26
- name: string;
27
- /** Create a fresh block store instance for each test. */
28
- createStore: () => Promise<FsBlockStore> | FsBlockStore;
29
- /** Optional teardown called after each test. */
30
- cleanup?: () => Promise<void>;
31
- /** Which optional capabilities the store supports. */
32
- capabilities: BlockStoreConformanceCapabilities;
33
- }
34
- export declare function defineBlockStoreTests(config: BlockStoreConformanceConfig): void;