@veryfront/ext-content-mdx 0.1.1186 → 0.1.1189

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 (163) hide show
  1. package/esm/_dnt.polyfills.d.ts +6 -6
  2. package/esm/_dnt.polyfills.d.ts.map +1 -1
  3. package/esm/deno.d.ts +18 -0
  4. package/esm/deno.js +30 -9
  5. package/esm/src/config/defaults.d.ts +31 -24
  6. package/esm/src/config/defaults.d.ts.map +1 -1
  7. package/esm/src/config/defaults.js +25 -18
  8. package/esm/src/errors/diagnostic-policy.d.ts +35 -0
  9. package/esm/src/errors/diagnostic-policy.d.ts.map +1 -0
  10. package/esm/src/errors/diagnostic-policy.js +100 -0
  11. package/esm/src/errors/error-registry/boundary.d.ts +2 -0
  12. package/esm/src/errors/error-registry/boundary.d.ts.map +1 -1
  13. package/esm/src/errors/error-registry/boundary.js +8 -0
  14. package/esm/src/errors/error-registry/config.d.ts.map +1 -1
  15. package/esm/src/errors/error-registry/config.js +3 -3
  16. package/esm/src/errors/error-registry/deploy.js +1 -1
  17. package/esm/src/errors/error-registry/server.d.ts +2 -0
  18. package/esm/src/errors/error-registry/server.d.ts.map +1 -1
  19. package/esm/src/errors/error-registry/server.js +8 -0
  20. package/esm/src/errors/error-registry-helpers.d.ts +11 -2
  21. package/esm/src/errors/error-registry-helpers.d.ts.map +1 -1
  22. package/esm/src/errors/error-registry-helpers.js +70 -1
  23. package/esm/src/errors/error-registry.d.ts +85 -73
  24. package/esm/src/errors/error-registry.d.ts.map +1 -1
  25. package/esm/src/errors/error-registry.js +2 -14
  26. package/esm/src/errors/types.d.ts +44 -5
  27. package/esm/src/errors/types.d.ts.map +1 -1
  28. package/esm/src/errors/types.js +148 -24
  29. package/esm/src/errors/veryfront-error.d.ts +25 -2
  30. package/esm/src/errors/veryfront-error.d.ts.map +1 -1
  31. package/esm/src/errors/veryfront-error.js +638 -28
  32. package/esm/src/observability/limits.d.ts +20 -0
  33. package/esm/src/observability/limits.d.ts.map +1 -0
  34. package/esm/src/observability/limits.js +19 -0
  35. package/esm/src/observability/telemetry-error.d.ts +22 -0
  36. package/esm/src/observability/telemetry-error.d.ts.map +1 -0
  37. package/esm/src/observability/telemetry-error.js +377 -0
  38. package/esm/src/observability/tracing/api-shim.d.ts +39 -0
  39. package/esm/src/observability/tracing/api-shim.d.ts.map +1 -1
  40. package/esm/src/observability/tracing/api-shim.js +196 -69
  41. package/esm/src/observability/tracing/context-callback.d.ts +14 -0
  42. package/esm/src/observability/tracing/context-callback.d.ts.map +1 -0
  43. package/esm/src/observability/tracing/context-callback.js +111 -0
  44. package/esm/src/observability/tracing/otlp-setup.d.ts.map +1 -1
  45. package/esm/src/observability/tracing/otlp-setup.js +190 -46
  46. package/esm/src/platform/adapters/base.d.ts +51 -7
  47. package/esm/src/platform/adapters/base.d.ts.map +1 -1
  48. package/esm/src/platform/adapters/base.js +4 -2
  49. package/esm/src/platform/adapters/bounded-file-read.d.ts +9 -0
  50. package/esm/src/platform/adapters/bounded-file-read.d.ts.map +1 -1
  51. package/esm/src/platform/adapters/bounded-file-read.js +11 -5
  52. package/esm/src/platform/adapters/file-snapshot-error.d.ts +2 -0
  53. package/esm/src/platform/adapters/file-snapshot-error.d.ts.map +1 -1
  54. package/esm/src/platform/adapters/file-snapshot-error.js +2 -0
  55. package/esm/src/platform/adapters/file-system-capabilities.d.ts +74 -0
  56. package/esm/src/platform/adapters/file-system-capabilities.d.ts.map +1 -0
  57. package/esm/src/platform/adapters/file-system-capabilities.js +508 -0
  58. package/esm/src/platform/adapters/native-file-system-provenance.d.ts +6 -0
  59. package/esm/src/platform/adapters/native-file-system-provenance.d.ts.map +1 -0
  60. package/esm/src/platform/adapters/native-file-system-provenance.js +15 -0
  61. package/esm/src/platform/adapters/runtime/deno/filesystem-adapter.d.ts +45 -0
  62. package/esm/src/platform/adapters/runtime/deno/filesystem-adapter.d.ts.map +1 -0
  63. package/esm/src/platform/adapters/runtime/deno/filesystem-adapter.js +291 -0
  64. package/esm/src/platform/adapters/runtime/shared/node-filesystem-adapter.d.ts +71 -0
  65. package/esm/src/platform/adapters/runtime/shared/node-filesystem-adapter.d.ts.map +1 -0
  66. package/esm/src/platform/adapters/runtime/shared/node-filesystem-adapter.js +471 -0
  67. package/esm/src/platform/adapters/runtime/shared/shared-watcher.d.ts +16 -0
  68. package/esm/src/platform/adapters/runtime/shared/shared-watcher.d.ts.map +1 -0
  69. package/esm/src/platform/adapters/runtime/shared/shared-watcher.js +140 -0
  70. package/esm/src/platform/adapters/runtime/shared/temp-dir.d.ts +2 -0
  71. package/esm/src/platform/adapters/runtime/shared/temp-dir.d.ts.map +1 -0
  72. package/esm/src/platform/adapters/runtime/shared/temp-dir.js +10 -0
  73. package/esm/src/platform/adapters/runtime/shared/watcher-queue.d.ts +5 -0
  74. package/esm/src/platform/adapters/runtime/shared/watcher-queue.d.ts.map +1 -0
  75. package/esm/src/platform/adapters/runtime/shared/watcher-queue.js +75 -0
  76. package/esm/src/platform/compat/abort-signal.d.ts +20 -0
  77. package/esm/src/platform/compat/abort-signal.d.ts.map +1 -0
  78. package/esm/src/platform/compat/abort-signal.js +64 -0
  79. package/esm/src/platform/compat/constants.d.ts +2 -2
  80. package/esm/src/platform/compat/constants.d.ts.map +1 -1
  81. package/esm/src/platform/compat/constants.js +2 -2
  82. package/esm/src/platform/compat/error-introspection.d.ts +37 -0
  83. package/esm/src/platform/compat/error-introspection.d.ts.map +1 -0
  84. package/esm/src/platform/compat/error-introspection.js +258 -0
  85. package/esm/src/platform/compat/fs.d.ts +29 -8
  86. package/esm/src/platform/compat/fs.d.ts.map +1 -1
  87. package/esm/src/platform/compat/fs.js +123 -57
  88. package/esm/src/platform/compat/native-brand-checks.d.ts +14 -0
  89. package/esm/src/platform/compat/native-brand-checks.d.ts.map +1 -0
  90. package/esm/src/platform/compat/native-brand-checks.js +68 -0
  91. package/esm/src/platform/compat/not-found-error.d.ts +8 -3
  92. package/esm/src/platform/compat/not-found-error.d.ts.map +1 -1
  93. package/esm/src/platform/compat/not-found-error.js +164 -31
  94. package/esm/src/platform/compat/path/security.d.ts.map +1 -1
  95. package/esm/src/platform/compat/path/security.js +3 -5
  96. package/esm/src/platform/compat/process/command.d.ts +24 -1
  97. package/esm/src/platform/compat/process/command.d.ts.map +1 -1
  98. package/esm/src/platform/compat/process/command.js +393 -78
  99. package/esm/src/platform/compat/process/env.d.ts +11 -0
  100. package/esm/src/platform/compat/process/env.d.ts.map +1 -1
  101. package/esm/src/platform/compat/process/env.js +28 -38
  102. package/esm/src/platform/compat/process/global-error.d.ts +19 -0
  103. package/esm/src/platform/compat/process/global-error.d.ts.map +1 -0
  104. package/esm/src/platform/compat/process/global-error.js +57 -0
  105. package/esm/src/platform/compat/process/lifecycle.d.ts +10 -3
  106. package/esm/src/platform/compat/process/lifecycle.d.ts.map +1 -1
  107. package/esm/src/platform/compat/process/lifecycle.js +74 -23
  108. package/esm/src/platform/compat/process/project-env-contract.d.ts +19 -0
  109. package/esm/src/platform/compat/process/project-env-contract.d.ts.map +1 -0
  110. package/esm/src/platform/compat/process/project-env-contract.js +19 -0
  111. package/esm/src/platform/compat/runtime.d.ts +14 -5
  112. package/esm/src/platform/compat/runtime.d.ts.map +1 -1
  113. package/esm/src/platform/compat/runtime.js +34 -9
  114. package/esm/src/platform/compat/std/front-matter-yaml.d.ts +12 -0
  115. package/esm/src/platform/compat/std/front-matter-yaml.d.ts.map +1 -1
  116. package/esm/src/platform/compat/std/front-matter-yaml.js +35 -3
  117. package/esm/src/platform/compat/temp-directory-prefix.d.ts +8 -0
  118. package/esm/src/platform/compat/temp-directory-prefix.d.ts.map +1 -0
  119. package/esm/src/platform/compat/temp-directory-prefix.js +15 -0
  120. package/esm/src/utils/abort.d.ts +10 -0
  121. package/esm/src/utils/abort.d.ts.map +1 -0
  122. package/esm/src/utils/abort.js +35 -0
  123. package/esm/src/utils/constants/build.d.ts +3 -0
  124. package/esm/src/utils/constants/build.d.ts.map +1 -1
  125. package/esm/src/utils/constants/build.js +5 -1
  126. package/esm/src/utils/constants/cache.d.ts +21 -0
  127. package/esm/src/utils/constants/cache.d.ts.map +1 -1
  128. package/esm/src/utils/constants/cache.js +101 -39
  129. package/esm/src/utils/constants/css.d.ts +20 -0
  130. package/esm/src/utils/constants/css.d.ts.map +1 -0
  131. package/esm/src/utils/constants/css.js +19 -0
  132. package/esm/src/utils/constants/limits.d.ts +4 -0
  133. package/esm/src/utils/constants/limits.d.ts.map +1 -1
  134. package/esm/src/utils/constants/limits.js +4 -0
  135. package/esm/src/utils/constants/project-identity.d.ts +5 -0
  136. package/esm/src/utils/constants/project-identity.d.ts.map +1 -0
  137. package/esm/src/utils/constants/project-identity.js +4 -0
  138. package/esm/src/utils/constants/retry.d.ts +18 -0
  139. package/esm/src/utils/constants/retry.d.ts.map +1 -1
  140. package/esm/src/utils/constants/retry.js +18 -0
  141. package/esm/src/utils/constants/security.d.ts +4 -0
  142. package/esm/src/utils/constants/security.d.ts.map +1 -1
  143. package/esm/src/utils/constants/security.js +4 -0
  144. package/esm/src/utils/index.d.ts +3 -1
  145. package/esm/src/utils/index.d.ts.map +1 -1
  146. package/esm/src/utils/index.js +3 -1
  147. package/esm/src/utils/logger/core.d.ts +5 -0
  148. package/esm/src/utils/logger/core.d.ts.map +1 -1
  149. package/esm/src/utils/logger/core.js +67 -2
  150. package/esm/src/utils/logger/redact.d.ts +36 -13
  151. package/esm/src/utils/logger/redact.d.ts.map +1 -1
  152. package/esm/src/utils/logger/redact.js +573 -83
  153. package/esm/src/utils/parallel.d.ts.map +1 -1
  154. package/esm/src/utils/parallel.js +11 -1
  155. package/esm/src/utils/project-identity.d.ts +11 -0
  156. package/esm/src/utils/project-identity.d.ts.map +1 -0
  157. package/esm/src/utils/project-identity.js +69 -0
  158. package/esm/src/utils/version-constant.d.ts +1 -1
  159. package/esm/src/utils/version-constant.js +1 -1
  160. package/package.json +3 -3
  161. package/esm/src/platform/adapters/runtime/shared/native-file-capabilities.d.ts +0 -33
  162. package/esm/src/platform/adapters/runtime/shared/native-file-capabilities.d.ts.map +0 -1
  163. package/esm/src/platform/adapters/runtime/shared/native-file-capabilities.js +0 -205
@@ -1,9 +1,45 @@
1
1
  import * as dntShim from "../../../_dnt.shims.js";
2
2
  import { createError, toError } from "../../errors/veryfront-error.js";
3
3
  import { isBun, isDeno, isNode } from "./runtime.js";
4
+ import { validateTempDirectoryPrefix } from "./temp-directory-prefix.js";
4
5
  import { readFileWithinLimit } from "../adapters/bounded-file-read.js";
5
- import { readNodeFileSnapshotWithinLimit, supportsNativeFileSnapshots, } from "../adapters/runtime/shared/native-file-capabilities.js";
6
- export { isNotFoundError } from "./not-found-error.js";
6
+ import { captureExclusiveCreateCapability, captureSnapshotReadCapability, } from "../adapters/file-system-capabilities.js";
7
+ import { isProxyWithoutHooks } from "./error-introspection.js";
8
+ import { isNotFoundError } from "./not-found-error.js";
9
+ export { isNotFoundError };
10
+ const DEFAULT_TEMP_DIRECTORY_PREFIX = "tmp-";
11
+ const UNSUPPORTED_CHMOD_ERROR_CODES = new Set([
12
+ "ENOSYS",
13
+ "ENOTSUP",
14
+ "EOPNOTSUPP",
15
+ ]);
16
+ const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
17
+ const hasOwnProperty = Object.prototype.hasOwnProperty;
18
+ const reflectApply = Reflect.apply;
19
+ function hasOwnDataValue(value, key, expected) {
20
+ const descriptor = getOwnPropertyDescriptor(value, key);
21
+ return descriptor !== undefined &&
22
+ reflectApply(hasOwnProperty, descriptor, ["value"]) === true &&
23
+ descriptor.value === expected;
24
+ }
25
+ function isUnsupportedChmodError(error) {
26
+ if (!(error instanceof Error))
27
+ return false;
28
+ if (error.name === "NotSupported")
29
+ return true;
30
+ const code = error.code;
31
+ return typeof code === "string" && UNSUPPORTED_CHMOD_ERROR_CODES.has(code);
32
+ }
33
+ function normalizePathIdentity(device, inode) {
34
+ const isValidPart = (value) => (typeof value === "bigint" && value >= 0n) ||
35
+ (typeof value === "number" && Number.isSafeInteger(value) && value >= 0);
36
+ if (!isValidPart(device) || !isValidPart(inode))
37
+ return undefined;
38
+ return Object.freeze({
39
+ device: String(device),
40
+ inode: String(inode),
41
+ });
42
+ }
7
43
  /**
8
44
  * Typed accessor for the Deno global.
9
45
  *
@@ -16,9 +52,6 @@ function denoGlobal() {
16
52
  return dntShim.dntGlobalThis.Deno;
17
53
  }
18
54
  class NodeFileSystem {
19
- readFileSnapshotWithinLimit = supportsNativeFileSnapshots()
20
- ? (path, containmentRoot, byteLimit) => readNodeFileSnapshotWithinLimit(path, containmentRoot, byteLimit)
21
- : undefined;
22
55
  fs;
23
56
  os;
24
57
  path;
@@ -72,10 +105,7 @@ class NodeFileSystem {
72
105
  const handle = await this.getFs().open(path, "r");
73
106
  return {
74
107
  close: () => handle.close(),
75
- read: async (buffer) => {
76
- const { bytesRead } = await handle.read(buffer, 0, buffer.byteLength, null);
77
- return bytesRead === 0 ? null : bytesRead;
78
- },
108
+ read: async (buffer) => (await handle.read(buffer)).bytesRead,
79
109
  };
80
110
  }, byteLimit);
81
111
  }
@@ -87,10 +117,6 @@ class NodeFileSystem {
87
117
  await this.ensureInitialized();
88
118
  await this.getFs().writeFile(path, data);
89
119
  }
90
- async createFileBytesExclusive(path, data) {
91
- await this.ensureInitialized();
92
- await this.getFs().writeFile(path, data, { flag: "wx" });
93
- }
94
120
  async rename(from, to) {
95
121
  await this.ensureInitialized();
96
122
  await this.getFs().rename(from, to);
@@ -102,7 +128,7 @@ class NodeFileSystem {
102
128
  return true;
103
129
  }
104
130
  catch (error) {
105
- if (error?.code === "ENOENT")
131
+ if (isNotFoundError(error))
106
132
  return false;
107
133
  throw error;
108
134
  }
@@ -148,30 +174,30 @@ class NodeFileSystem {
148
174
  async remove(path, options) {
149
175
  await this.ensureInitialized();
150
176
  const recursive = options?.recursive ?? false;
151
- await this.getFs().rm(path, { recursive, force: recursive });
177
+ await this.getFs().rm(path, { recursive, force: false });
152
178
  }
153
179
  async makeTempDir(options) {
154
180
  await this.ensureInitialized();
155
- const tempDir = this.getPath().join(this.getOs().tmpdir(), `${options?.prefix ?? "tmp-"}${dntShim.crypto.randomUUID().slice(0, 8)}`);
156
- await this.getFs().mkdir(tempDir, { recursive: true });
157
- return tempDir;
181
+ const prefix = validateTempDirectoryPrefix(options?.prefix ?? DEFAULT_TEMP_DIRECTORY_PREFIX);
182
+ const tempRoot = this.getOs().tmpdir();
183
+ const separator = this.getPath().sep;
184
+ const tempRootPrefix = tempRoot.endsWith(separator) ? tempRoot : `${tempRoot}${separator}`;
185
+ return await this.getFs().mkdtemp(`${tempRootPrefix}${prefix}`);
158
186
  }
159
187
  async chmod(path, mode) {
160
188
  await this.ensureInitialized();
161
189
  try {
162
190
  await this.getFs().chmod(path, mode);
163
191
  }
164
- catch {
165
- // Ignore errors on Windows where chmod is not fully supported.
166
- // Intentionally not logged: this low-level compat module must stay
167
- // importable without `--allow-env` (the logger reads env at import).
192
+ catch (error) {
193
+ if (this.getOs().platform() === "win32" && isUnsupportedChmodError(error)) {
194
+ return;
195
+ }
196
+ throw error;
168
197
  }
169
198
  }
170
199
  }
171
200
  class DenoFileSystem {
172
- readFileSnapshotWithinLimit = supportsNativeFileSnapshots()
173
- ? (path, containmentRoot, byteLimit) => readNodeFileSnapshotWithinLimit(path, containmentRoot, byteLimit)
174
- : undefined;
175
201
  readTextFile(path) {
176
202
  return denoGlobal().readTextFile(path);
177
203
  }
@@ -181,7 +207,10 @@ class DenoFileSystem {
181
207
  async readFileBytesWithinLimit(path, byteLimit) {
182
208
  return await readFileWithinLimit(async () => {
183
209
  const file = await denoGlobal().open(path, { read: true });
184
- return { close: () => file.close(), read: (buffer) => file.read(buffer) };
210
+ return {
211
+ close: () => file.close(),
212
+ read: (buffer) => file.read(buffer),
213
+ };
185
214
  }, byteLimit);
186
215
  }
187
216
  async writeTextFile(path, data) {
@@ -190,22 +219,6 @@ class DenoFileSystem {
190
219
  async writeFile(path, data) {
191
220
  await denoGlobal().writeFile(path, data);
192
221
  }
193
- async createFileBytesExclusive(path, data) {
194
- const file = await denoGlobal().open(path, { write: true, createNew: true });
195
- let offset = 0;
196
- try {
197
- while (offset < data.byteLength) {
198
- const written = await file.write(data.subarray(offset));
199
- if (!Number.isSafeInteger(written) || written <= 0 || written > data.byteLength - offset) {
200
- throw new Error("Deno exclusive create write made no forward progress");
201
- }
202
- offset += written;
203
- }
204
- }
205
- finally {
206
- file.close();
207
- }
208
- }
209
222
  async rename(from, to) {
210
223
  await denoGlobal().rename(from, to);
211
224
  }
@@ -215,7 +228,7 @@ class DenoFileSystem {
215
228
  return true;
216
229
  }
217
230
  catch (error) {
218
- if (error instanceof denoGlobal().errors.NotFound)
231
+ if (isNotFoundError(error))
219
232
  return false;
220
233
  throw error;
221
234
  }
@@ -256,21 +269,52 @@ class DenoFileSystem {
256
269
  async remove(path, options) {
257
270
  await denoGlobal().remove(path, { recursive: options?.recursive ?? false });
258
271
  }
259
- makeTempDir(options) {
260
- return denoGlobal().makeTempDir({ prefix: options?.prefix });
272
+ async makeTempDir(options) {
273
+ const prefix = validateTempDirectoryPrefix(options?.prefix ?? DEFAULT_TEMP_DIRECTORY_PREFIX);
274
+ return await denoGlobal().makeTempDir({ prefix });
261
275
  }
262
276
  async chmod(path, mode) {
263
277
  try {
264
278
  await denoGlobal().chmod(path, mode);
265
279
  }
266
- catch (_) {
267
- /* expected: chmod is not fully supported on Windows */
280
+ catch (error) {
281
+ if (denoGlobal().build.os === "windows" && isUnsupportedChmodError(error)) {
282
+ return;
283
+ }
284
+ throw error;
268
285
  }
269
286
  }
270
287
  }
271
- /** Create file system. */
288
+ /** Create the runtime-native filesystem implementation. */
272
289
  export function createFileSystem() {
273
- return isDeno ? new DenoFileSystem() : new NodeFileSystem();
290
+ const fileSystem = isDeno ? new DenoFileSystem() : new NodeFileSystem();
291
+ let semanticAdapter;
292
+ const loadSemanticAdapter = () => semanticAdapter ??= isDeno
293
+ ? import("../adapters/runtime/deno/filesystem-adapter.js")
294
+ .then(({ DenoFileSystemAdapter }) => new DenoFileSystemAdapter())
295
+ : import("../adapters/runtime/shared/node-filesystem-adapter.js")
296
+ .then(({ NodeCompatibleFileSystemAdapter }) => new NodeCompatibleFileSystemAdapter());
297
+ Object.defineProperty(fileSystem, "readFileSnapshotWithinLimit", {
298
+ value: async (path, containmentRoot, byteLimit) => {
299
+ const snapshotReader = captureSnapshotReadCapability(await loadSemanticAdapter(), "Native filesystem adapter");
300
+ if (snapshotReader === undefined) {
301
+ throw new Error("Native filesystem adapter does not support snapshot reads");
302
+ }
303
+ return await snapshotReader.read(path, containmentRoot, byteLimit);
304
+ },
305
+ enumerable: true,
306
+ });
307
+ Object.defineProperty(fileSystem, "createFileBytesExclusive", {
308
+ value: async (path, content) => {
309
+ const exclusiveCreator = captureExclusiveCreateCapability(await loadSemanticAdapter(), "Native filesystem adapter");
310
+ if (exclusiveCreator === undefined) {
311
+ throw new Error("Native filesystem adapter does not support exclusive creates");
312
+ }
313
+ await exclusiveCreator.create(path, content);
314
+ },
315
+ enumerable: true,
316
+ });
317
+ return fileSystem;
274
318
  }
275
319
  let _fs = null;
276
320
  function getFs() {
@@ -293,7 +337,7 @@ export function writeTextFile(path, data) {
293
337
  export function writeFile(path, data) {
294
338
  return getFs().writeFile(path, data);
295
339
  }
296
- /** Check whether a path exists. */
340
+ /** Return false for a missing path and propagate every other filesystem error. */
297
341
  export function exists(path) {
298
342
  return getFs().exists(path);
299
343
  }
@@ -323,11 +367,25 @@ export async function lstat(path) {
323
367
  mtime: info.mtime,
324
368
  };
325
369
  }
370
+ /**
371
+ * Read a path's native device/inode identity without following a terminal
372
+ * symbolic link. Returns undefined only when the runtime cannot expose a
373
+ * stable identity for the backing filesystem.
374
+ */
375
+ export async function getPathIdentity(path) {
376
+ if (isDeno) {
377
+ const info = await denoGlobal().lstat(path);
378
+ return normalizePathIdentity(info.dev, info.ino);
379
+ }
380
+ const fs = await import("node:fs/promises");
381
+ const info = await fs.lstat(path, { bigint: true });
382
+ return normalizePathIdentity(info.dev, info.ino);
383
+ }
326
384
  /** Create a directory. */
327
385
  export function mkdir(path, options) {
328
386
  return getFs().mkdir(path, options);
329
387
  }
330
- /** Remove a file or directory. */
388
+ /** Remove a file or directory, rejecting when the path does not exist. */
331
389
  export function remove(path, options) {
332
390
  return getFs().remove(path, options);
333
391
  }
@@ -335,11 +393,11 @@ export function remove(path, options) {
335
393
  export function readDir(path) {
336
394
  return getFs().readDir(path);
337
395
  }
338
- /** Create temp dir. */
396
+ /** Atomically create a unique directory beneath the operating-system temp root. */
339
397
  export function makeTempDir(options) {
340
398
  return getFs().makeTempDir(options);
341
399
  }
342
- /** Change file permissions. */
400
+ /** Change file permissions, rejecting operational failures. */
343
401
  export function chmod(path, mode) {
344
402
  return getFs().chmod(path, mode);
345
403
  }
@@ -365,8 +423,16 @@ export async function realPath(path) {
365
423
  }
366
424
  /** Error shape for is already exists. */
367
425
  export function isAlreadyExistsError(error) {
368
- const AlreadyExists = dntShim.dntGlobalThis.Deno?.errors?.AlreadyExists;
369
- if (isDeno && AlreadyExists && error instanceof AlreadyExists)
370
- return true;
371
- return error?.code === "EEXIST";
426
+ if (typeof error !== "object" || error === null || isProxyWithoutHooks(error)) {
427
+ return false;
428
+ }
429
+ try {
430
+ const AlreadyExists = isDeno ? denoGlobal().errors.AlreadyExists : undefined;
431
+ if (AlreadyExists && error instanceof AlreadyExists)
432
+ return true;
433
+ return hasOwnDataValue(error, "code", "EEXIST");
434
+ }
435
+ catch {
436
+ return false;
437
+ }
372
438
  }
@@ -0,0 +1,14 @@
1
+ export interface NativeBrandChecks {
2
+ isAsyncFunction(value: unknown): boolean;
3
+ isNativeError(value: unknown): boolean;
4
+ isPromise(value: unknown): boolean;
5
+ isProxy(value: unknown): boolean;
6
+ isUint8Array(value: unknown): boolean;
7
+ }
8
+ /**
9
+ * Immutable host brand checks captured once at the runtime trust boundary.
10
+ * Browser and edge hosts without Node-compatible primitives remain linkable
11
+ * and use the conservative callers in error-introspection.ts.
12
+ */
13
+ export declare const nativeBrandChecks: NativeBrandChecks | undefined;
14
+ //# sourceMappingURL=native-brand-checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-brand-checks.d.ts","sourceRoot":"","sources":["../../../../src/src/platform/compat/native-brand-checks.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACzC,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACvC,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACnC,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACjC,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;CACvC;AA+ED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,+BAE7B,CAAC"}
@@ -0,0 +1,68 @@
1
+ import * as dntShim from "../../../_dnt.shims.js";
2
+ import { isBun, isDeno, isNode } from "./runtime.js";
3
+ const apply = Reflect.apply;
4
+ const createObject = Object.create;
5
+ const defineProperty = Object.defineProperty;
6
+ const freeze = Object.freeze;
7
+ const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
8
+ const objectHasOwnProperty = Object.prototype.hasOwnProperty;
9
+ function hasOwn(object, key) {
10
+ return apply(objectHasOwnProperty, object, [key]);
11
+ }
12
+ function readOwnDataFunction(source, key) {
13
+ const descriptor = getOwnPropertyDescriptor(source, key);
14
+ if (!descriptor || !hasOwn(descriptor, "value"))
15
+ return undefined;
16
+ return typeof descriptor.value === "function" ? descriptor.value : undefined;
17
+ }
18
+ function snapshotNativeBrandChecks(value) {
19
+ if ((typeof value !== "object" && typeof value !== "function") || value === null) {
20
+ return undefined;
21
+ }
22
+ const snapshot = createObject(null);
23
+ for (const key of [
24
+ "isAsyncFunction",
25
+ "isNativeError",
26
+ "isPromise",
27
+ "isProxy",
28
+ "isUint8Array",
29
+ ]) {
30
+ const check = readOwnDataFunction(value, key);
31
+ if (!check)
32
+ return undefined;
33
+ defineProperty(snapshot, key, {
34
+ configurable: false,
35
+ enumerable: true,
36
+ value: check,
37
+ writable: false,
38
+ });
39
+ }
40
+ return freeze(snapshot);
41
+ }
42
+ function loadNativeBrandCheckModule() {
43
+ if (!isBun && !isDeno && !isNode)
44
+ return undefined;
45
+ const hostProcess = dntShim.dntGlobalThis.process;
46
+ if (hostProcess) {
47
+ const getBuiltinModule = readOwnDataFunction(hostProcess, "getBuiltinModule");
48
+ if (getBuiltinModule) {
49
+ return apply(getBuiltinModule, hostProcess, ["node:util/types"]);
50
+ }
51
+ }
52
+ // Bun exposes synchronous require() in ESM. This retains compatibility with
53
+ // Bun releases that predate process.getBuiltinModule without adding a Node
54
+ // builtin to browser module graphs.
55
+ if (isBun && typeof require === "function") {
56
+ return apply(require, undefined, ["node:util/types"]);
57
+ }
58
+ return undefined;
59
+ }
60
+ /**
61
+ * Immutable host brand checks captured once at the runtime trust boundary.
62
+ * Browser and edge hosts without Node-compatible primitives remain linkable
63
+ * and use the conservative callers in error-introspection.ts.
64
+ */
65
+ export const nativeBrandChecks = snapshotNativeBrandChecks(loadNativeBrandCheckModule());
66
+ if ((isBun || isDeno || isNode) && !nativeBrandChecks) {
67
+ throw new Error("The current server runtime does not expose complete node:util/types brand checks");
68
+ }
@@ -1,7 +1,12 @@
1
1
  /**
2
- * Return whether an error or its cause chain represents a path that cannot be
3
- * resolved. ENOTDIR is included because a missing candidate beneath a file is
4
- * just as absent as an ENOENT candidate during filesystem lookup.
2
+ * Strict absence classifier for fail-closed filesystem boundaries.
3
+ *
4
+ * Every value in the inspected cause chain must carry the runtime's native
5
+ * Error brand. This keeps arbitrary error-shaped records such as
6
+ * `{ code: "ENOENT" }` from being converted into ordinary absence while still
7
+ * recognizing native Deno, Node, and Veryfront not-found errors without
8
+ * invoking project-owned hooks.
5
9
  */
10
+ export declare function isCanonicalNotFoundError(error: unknown): boolean;
6
11
  export declare function isNotFoundError(error: unknown, seen?: Set<unknown>): boolean;
7
12
  //# sourceMappingURL=not-found-error.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"not-found-error.d.ts","sourceRoot":"","sources":["../../../../src/src/platform/compat/not-found-error.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,GAAE,GAAG,CAAC,OAAO,CAAa,GAAG,OAAO,CAuCvF"}
1
+ {"version":3,"file":"not-found-error.d.ts","sourceRoot":"","sources":["../../../../src/src/platform/compat/not-found-error.ts"],"names":[],"mappings":"AAqMA;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEhE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,GAAE,GAAG,CAAC,OAAO,CAAa,GAAG,OAAO,CAEvF"}
@@ -1,41 +1,174 @@
1
1
  import * as dntShim from "../../../_dnt.shims.js";
2
+ import { isNativeErrorWithoutHooks, isProxyWithoutHooks, readNativeErrorNameWithoutHooks, } from "./error-introspection.js";
2
3
  import { isDeno } from "./runtime.js";
3
- /**
4
- * Return whether an error or its cause chain represents a path that cannot be
5
- * resolved. ENOTDIR is included because a missing candidate beneath a file is
6
- * just as absent as an ENOENT candidate during filesystem lookup.
7
- */
8
- export function isNotFoundError(error, seen = new Set()) {
9
- if (seen.has(error))
10
- return false;
11
- seen.add(error);
4
+ const MAX_CAUSE_DEPTH = 64;
5
+ const MAX_PROTOTYPE_DEPTH = 32;
6
+ const NO_DATA_VALUE = Symbol("no-data-value");
7
+ const NO_OWN_PROPERTY = Symbol("no-own-property");
8
+ const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
9
+ const getPrototypeOf = Object.getPrototypeOf;
10
+ const hasOwnProperty = Object.prototype.hasOwnProperty;
11
+ const reflectApply = Reflect.apply;
12
+ const setAdd = Set.prototype.add;
13
+ const setHas = Set.prototype.has;
14
+ function hasOwn(value, key) {
15
+ return reflectApply(hasOwnProperty, value, [key]);
16
+ }
17
+ function readOwnDataValue(value, key) {
18
+ if (isProxyWithoutHooks(value))
19
+ return NO_DATA_VALUE;
12
20
  try {
13
- const NotFound = dntShim.dntGlobalThis.Deno?.errors?.NotFound;
14
- if (isDeno && NotFound && error instanceof NotFound)
21
+ const descriptor = getOwnPropertyDescriptor(value, key);
22
+ if (!descriptor)
23
+ return NO_OWN_PROPERTY;
24
+ return hasOwn(descriptor, "value") ? descriptor.value : NO_DATA_VALUE;
25
+ }
26
+ catch {
27
+ return NO_DATA_VALUE;
28
+ }
29
+ }
30
+ function readDataValue(value, key) {
31
+ let owner = value;
32
+ for (let depth = 0; owner !== null && depth < MAX_PROTOTYPE_DEPTH; depth++) {
33
+ const result = readOwnDataValue(owner, key);
34
+ if (result === NO_DATA_VALUE)
35
+ return NO_DATA_VALUE;
36
+ if (result !== NO_OWN_PROPERTY)
37
+ return result;
38
+ if (isProxyWithoutHooks(owner))
39
+ return NO_DATA_VALUE;
40
+ try {
41
+ owner = getPrototypeOf(owner);
42
+ }
43
+ catch {
44
+ return NO_DATA_VALUE;
45
+ }
46
+ }
47
+ return NO_DATA_VALUE;
48
+ }
49
+ function readClassifiedDataValue(value, key, ownOnly) {
50
+ if (!ownOnly)
51
+ return readDataValue(value, key);
52
+ const result = readOwnDataValue(value, key);
53
+ return result === NO_OWN_PROPERTY ? NO_DATA_VALUE : result;
54
+ }
55
+ function captureDenoNotFoundPrototype() {
56
+ if (!isDeno)
57
+ return undefined;
58
+ const deno = readOwnDataValue(dntShim.dntGlobalThis, "Deno");
59
+ if (typeof deno !== "object" || deno === null)
60
+ return undefined;
61
+ const errors = readOwnDataValue(deno, "errors");
62
+ if (typeof errors !== "object" || errors === null)
63
+ return undefined;
64
+ const NotFound = readOwnDataValue(errors, "NotFound");
65
+ if (typeof NotFound !== "function" || isProxyWithoutHooks(NotFound))
66
+ return undefined;
67
+ const prototype = readOwnDataValue(NotFound, "prototype");
68
+ return typeof prototype === "object" && prototype !== null ? prototype : undefined;
69
+ }
70
+ const denoNotFoundPrototype = captureDenoNotFoundPrototype();
71
+ function inheritsFrom(value, expectedPrototype) {
72
+ let prototype = value;
73
+ for (let depth = 0; prototype !== null && depth < MAX_PROTOTYPE_DEPTH; depth++) {
74
+ if (isProxyWithoutHooks(prototype))
75
+ return false;
76
+ try {
77
+ prototype = getPrototypeOf(prototype);
78
+ }
79
+ catch {
80
+ return false;
81
+ }
82
+ if (prototype === expectedPrototype)
15
83
  return true;
16
- const code = error?.code;
84
+ }
85
+ return false;
86
+ }
87
+ function normalizeSeenSet(seen) {
88
+ try {
89
+ reflectApply(setHas, seen, [seen]);
90
+ return seen;
91
+ }
92
+ catch {
93
+ return new Set();
94
+ }
95
+ }
96
+ function markSeen(seen, value) {
97
+ if (reflectApply(setHas, seen, [value]))
98
+ return false;
99
+ reflectApply(setAdd, seen, [value]);
100
+ return true;
101
+ }
102
+ function isLegacyFileNotFoundError(error, name, ownDataOnly) {
103
+ if (name !== "VeryfrontError[file]")
104
+ return false;
105
+ const context = readClassifiedDataValue(error, "context", ownDataOnly);
106
+ if (typeof context !== "object" || context === null ||
107
+ isProxyWithoutHooks(context)) {
108
+ return false;
109
+ }
110
+ const type = readClassifiedDataValue(context, "type", ownDataOnly);
111
+ const message = readClassifiedDataValue(context, "message", ownDataOnly);
112
+ return type === "file" &&
113
+ typeof message === "string" &&
114
+ /^(?:File|Path) not found:/.test(message);
115
+ }
116
+ /**
117
+ * Return whether an error or its bounded cause chain represents a path that
118
+ * cannot be resolved. ENOTDIR is included because a missing candidate beneath
119
+ * a file is just as absent as an ENOENT candidate during filesystem lookup.
120
+ * Project-owned accessors and Proxy traps are never evaluated.
121
+ */
122
+ function classifyNotFoundError(error, seen, requireNativeCauseChain) {
123
+ const visited = normalizeSeenSet(seen);
124
+ let current = error;
125
+ for (let depth = 0; depth < MAX_CAUSE_DEPTH; depth++) {
126
+ if (typeof current !== "object" || current === null ||
127
+ isProxyWithoutHooks(current) || !markSeen(visited, current)) {
128
+ return false;
129
+ }
130
+ if (requireNativeCauseChain && !isNativeErrorWithoutHooks(current)) {
131
+ return false;
132
+ }
133
+ const code = readClassifiedDataValue(current, "code", requireNativeCauseChain);
17
134
  if (code === "ENOENT" || code === "ENOTDIR")
18
135
  return true;
19
- if (error instanceof Error) {
20
- if (error.name === "VeryfrontError" &&
21
- error.slug === "file-not-found") {
22
- return true;
23
- }
24
- const legacyContext = error.context;
25
- if (error.name === "VeryfrontError[file]" &&
26
- typeof legacyContext === "object" &&
27
- legacyContext !== null &&
28
- legacyContext.type === "file" &&
29
- typeof legacyContext.message === "string" &&
30
- /^(?:File|Path) not found:/.test(legacyContext.message)) {
31
- return true;
32
- }
33
- if ("cause" in error)
34
- return isNotFoundError(error.cause, seen);
136
+ if (!isNativeErrorWithoutHooks(current))
137
+ return false;
138
+ if (denoNotFoundPrototype && inheritsFrom(current, denoNotFoundPrototype)) {
139
+ return true;
35
140
  }
36
- }
37
- catch {
38
- // Error classifiers must not replace the original filesystem failure.
141
+ const name = readNativeErrorNameWithoutHooks(current);
142
+ const structuralName = requireNativeCauseChain
143
+ ? readClassifiedDataValue(current, "name", true)
144
+ : name;
145
+ if (structuralName === "VeryfrontError" &&
146
+ readClassifiedDataValue(current, "slug", requireNativeCauseChain) === "file-not-found") {
147
+ return true;
148
+ }
149
+ if (typeof structuralName === "string" &&
150
+ isLegacyFileNotFoundError(current, structuralName, requireNativeCauseChain)) {
151
+ return true;
152
+ }
153
+ const cause = readClassifiedDataValue(current, "cause", requireNativeCauseChain);
154
+ if (cause === NO_DATA_VALUE)
155
+ return false;
156
+ current = cause;
39
157
  }
40
158
  return false;
41
159
  }
160
+ /**
161
+ * Strict absence classifier for fail-closed filesystem boundaries.
162
+ *
163
+ * Every value in the inspected cause chain must carry the runtime's native
164
+ * Error brand. This keeps arbitrary error-shaped records such as
165
+ * `{ code: "ENOENT" }` from being converted into ordinary absence while still
166
+ * recognizing native Deno, Node, and Veryfront not-found errors without
167
+ * invoking project-owned hooks.
168
+ */
169
+ export function isCanonicalNotFoundError(error) {
170
+ return classifyNotFoundError(error, new Set(), true);
171
+ }
172
+ export function isNotFoundError(error, seen = new Set()) {
173
+ return classifyNotFoundError(error, seen, false);
174
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/compat/path/security.ts"],"names":[],"mappings":"AAMA,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAsB1D"}
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/compat/path/security.ts"],"names":[],"mappings":"AAEA,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAmB1D"}
@@ -1,13 +1,11 @@
1
- import { FORBIDDEN_PATH_PATTERNS, MAX_PATH_LENGTH, MAX_PATH_TRAVERSAL_DEPTH, } from "../../../utils/constants/security.js";
1
+ import { MAX_PATH_LENGTH, MAX_PATH_TRAVERSAL_DEPTH } from "../../../utils/constants/security.js";
2
2
  export function validatePathSecurity(path) {
3
3
  if (path == null)
4
4
  return false;
5
5
  if (path.length > MAX_PATH_LENGTH)
6
6
  return false;
7
- for (const pattern of FORBIDDEN_PATH_PATTERNS) {
8
- if (pattern.test(path))
9
- return false;
10
- }
7
+ if (path.includes("\0"))
8
+ return false;
11
9
  const parts = path.split(/[\/\\]/);
12
10
  let depth = 0;
13
11
  for (const part of parts) {