@socketsecurity/lib 6.0.8 → 6.0.9

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 (119) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/ai/route.d.mts +21 -8
  3. package/dist/ai/route.js +21 -6
  4. package/dist/ai/spawn.d.mts +32 -0
  5. package/dist/ai/spawn.js +91 -2
  6. package/dist/ai/types.d.mts +10 -0
  7. package/dist/bin/prim.cjs +18797 -13627
  8. package/dist/bin/resolve.js +1 -1
  9. package/dist/cache/ttl/store.js +1 -1
  10. package/dist/compression/brotli.js +1 -1
  11. package/dist/compression/gzip.js +1 -1
  12. package/dist/config/layers.d.ts +53 -0
  13. package/dist/config/layers.js +83 -0
  14. package/dist/constants/socket.js +1 -1
  15. package/dist/debug/caller-info.js +1 -1
  16. package/dist/dlx/binary-cache.js +1 -1
  17. package/dist/dlx/binary-resolution.js +1 -1
  18. package/dist/dlx/firewall.js +1 -1
  19. package/dist/dlx/lockfile.js +1 -1
  20. package/dist/eco/npm/npm/parse-lockfile.js +1 -1
  21. package/dist/eco/npm/yarnpkg/yarn/parse-lockfile.js +1 -1
  22. package/dist/env/rewire.d.ts +5 -3
  23. package/dist/env/rewire.js +6 -7
  24. package/dist/env/xdg.d.ts +17 -0
  25. package/dist/env/xdg.js +21 -1
  26. package/dist/errors/stack.js +1 -2
  27. package/dist/external/@npmcli/package-json.js +3455 -4881
  28. package/dist/external/@yarnpkg/extensions.js +1 -1
  29. package/dist/external/external-pack.js +1 -1
  30. package/dist/external/npm-pack.js +29164 -31799
  31. package/dist/external/tar-fs.js +63 -16
  32. package/dist/external-tools/jre/detect-platform-arch.js +1 -1
  33. package/dist/external-tools/manifest.js +1 -1
  34. package/dist/external-tools/python/asset-names.js +1 -1
  35. package/dist/external-tools/python/uv-install.d.ts +89 -0
  36. package/dist/external-tools/python/uv-install.js +165 -0
  37. package/dist/external-tools/skillspector/from-uv.d.ts +30 -0
  38. package/dist/external-tools/skillspector/from-uv.js +56 -0
  39. package/dist/external-tools/skillspector/resolve.d.ts +18 -3
  40. package/dist/external-tools/skillspector/resolve.js +21 -8
  41. package/dist/external-tools/skillspector/types.d.ts +3 -1
  42. package/dist/external-tools/uv/asset-names.d.ts +36 -0
  43. package/dist/external-tools/uv/asset-names.js +73 -0
  44. package/dist/external-tools/uv/from-download.d.ts +17 -0
  45. package/dist/external-tools/uv/from-download.js +50 -0
  46. package/dist/external-tools/uv/from-path.d.ts +5 -0
  47. package/dist/external-tools/uv/from-path.js +22 -0
  48. package/dist/external-tools/uv/from-vfs.d.ts +7 -0
  49. package/dist/external-tools/uv/from-vfs.js +26 -0
  50. package/dist/external-tools/uv/resolve.d.ts +25 -0
  51. package/dist/external-tools/uv/resolve.js +61 -0
  52. package/dist/external-tools/uv/types.d.ts +24 -0
  53. package/dist/external-tools/uv/types.js +2 -0
  54. package/dist/fleet/repo-config.d.ts +53 -0
  55. package/dist/fleet/repo-config.js +79 -0
  56. package/dist/fs/allowed-dirs-cache.js +3 -5
  57. package/dist/fs/copy.d.ts +88 -0
  58. package/dist/fs/copy.js +89 -0
  59. package/dist/fs/safe.js +1 -1
  60. package/dist/git/_internal.js +2 -2
  61. package/dist/github/refs.js +10 -15
  62. package/dist/globs/_internal.js +1 -1
  63. package/dist/http-request/browser.js +1 -1
  64. package/dist/http-request/checksum-file.js +1 -1
  65. package/dist/http-request/headers.js +1 -1
  66. package/dist/integrity.d.ts +125 -78
  67. package/dist/integrity.js +168 -84
  68. package/dist/logger/colors.d.ts +1 -2
  69. package/dist/logger/colors.js +2 -2
  70. package/dist/logger/symbols-builder.js +7 -8
  71. package/dist/logger/symbols.js +8 -8
  72. package/dist/node/module.d.ts +73 -2
  73. package/dist/node/module.js +97 -12
  74. package/dist/objects/predicates.js +1 -1
  75. package/dist/packages/exports.js +2 -2
  76. package/dist/packages/isolation.js +1 -1
  77. package/dist/packages/manifest.d.ts +29 -0
  78. package/dist/packages/manifest.js +38 -2
  79. package/dist/packages/normalize.js +1 -1
  80. package/dist/packages/provenance.js +2 -2
  81. package/dist/packages/specs.js +1 -1
  82. package/dist/paths/_internal.d.ts +1 -7
  83. package/dist/paths/_internal.js +9 -15
  84. package/dist/paths/conversion.js +1 -1
  85. package/dist/paths/normalize.js +1 -1
  86. package/dist/paths/predicates.js +2 -1
  87. package/dist/paths/socket.d.ts +74 -23
  88. package/dist/paths/socket.js +97 -23
  89. package/dist/perf/metrics.js +1 -1
  90. package/dist/perf/report.js +1 -1
  91. package/dist/regexps/spec.js +1 -1
  92. package/dist/schema/validate.js +1 -1
  93. package/dist/secrets/broker.d.ts +35 -0
  94. package/dist/secrets/broker.js +72 -0
  95. package/dist/secrets/find.d.ts +6 -4
  96. package/dist/secrets/find.js +15 -1
  97. package/dist/secrets/rc.js +1 -1
  98. package/dist/smol/detect.js +1 -1
  99. package/dist/smol/http.js +1 -1
  100. package/dist/smol/https.js +1 -1
  101. package/dist/smol/manifest.js +1 -1
  102. package/dist/smol/path.js +1 -1
  103. package/dist/smol/primordial.js +1 -1
  104. package/dist/smol/purl.js +1 -1
  105. package/dist/smol/versions.js +1 -1
  106. package/dist/smol/vfs.js +1 -1
  107. package/dist/sorts/_internal.d.ts +1 -2
  108. package/dist/sorts/_internal.js +2 -6
  109. package/dist/sorts/semver.js +2 -2
  110. package/dist/spinner/create-spinner-class.js +1 -1
  111. package/dist/stdio/progress.js +1 -1
  112. package/dist/stdio/prompts.d.ts +0 -8
  113. package/dist/stdio/prompts.js +10 -23
  114. package/dist/strings/format.js +1 -1
  115. package/dist/strings/search.js +1 -1
  116. package/dist/themes/context.d.ts +5 -3
  117. package/dist/themes/context.js +5 -6
  118. package/llms.txt +750 -0
  119. package/package.json +79 -13
package/dist/integrity.js CHANGED
@@ -5,100 +5,129 @@ const require_runtime = require('./_virtual/_rolldown/runtime.js');
5
5
  const require_crypto_hash = require('./crypto/hash.js');
6
6
  const require_primordials_buffer = require('./primordials/buffer.js');
7
7
  const require_primordials_error = require('./primordials/error.js');
8
+ const require_primordials_object = require('./primordials/object.js');
9
+ const require_primordials_string = require('./primordials/string.js');
8
10
  let node_crypto = require("node:crypto");
9
11
  node_crypto = require_runtime.__toESM(node_crypto);
10
12
 
11
13
  //#region src/integrity.ts
12
14
  /**
13
- * @file Integrity + checksum helpers. The fleet uses two named hash flavors:
14
- *
15
- * - **integrity** — W3C Subresource Integrity string:
16
- * `sha(256|384|512)-<base64>`. The same shape the npm registry returns and
17
- * the `<script integrity>` HTML attribute accepts. Algorithm is embedded.
18
- * - **checksum** sha256 hex digest, exactly 64 lowercase chars. The shape
19
- * produced by `shasum -a 256` and used in GitHub-release SHA256SUMS files.
20
- * Conversion is direction-specific so the names read in English:
21
- * `checksumToIntegrity(hex)` and `integrityToChecksum(sri)`. Both are
22
- * idempotent on the destination format (pass an SRI to
23
- * `checksumToIntegrity`, get the same SRI back) so callers can apply them
24
- * without first sniffing the input shape. "SSRI" is just another name for
25
- * Subresource Integrity this module is the only one that should mention
26
- * it, and only inside `parseIntegrity` to extract the embedded algorithm +
27
- * body.
15
+ * @file Integrity + checksum helpers. One concept a {@link Hash} (algorithm +
16
+ * digest) — in two encodings:
17
+ *
18
+ * - **hex** lowercase hex digest (`shasum -a 256` / GitHub `SHA256SUMS`).
19
+ * - **sri** W3C Subresource Integrity `sha(256|384|512)-<base64>` (npm
20
+ * `dist.integrity`, the `<script integrity>` attribute). Both are views of
21
+ * the same digest. The algorithm is EXPLICIT on every `Hash` — never
22
+ * inferred from which function produced it or sniffed from a string's
23
+ * shape. `verifyHash(bytes, expected)` honors whatever algorithm the
24
+ * expected hash declares, so a sha256 `SHA256SUMS` digest and a sha512 npm
25
+ * integrity both "just verify" with no manual conversion. Role split (see
26
+ * `docs/hash-algorithms.md`, unchanged): we PIN sha512 (`computeHash`
27
+ * default, `computeHashes().integrity`); sha256 is the upstream-interop
28
+ * shape (`fetchChecksumFile`, `computeHashes().checksum`). The two only
29
+ * meet at verify-upstream-256 → pin-512. Algorithms are never flipped —
30
+ * relabeling a 256-bit digest as sha512 would be a lie, and you can't
31
+ * re-hash without the bytes. "SSRI" is just another name for Subresource
32
+ * Integrity — only this module should mention it, inside `parseIntegrity`.
28
33
  */
29
34
  const INTEGRITY_RE = /^(sha(?:256|384|512))-([A-Za-z0-9+/]+=*)$/;
35
+ const HEX_RE = /^[a-f0-9]+$/i;
30
36
  const CHECKSUM_RE = /^[a-f0-9]{64}$/i;
37
+ const ALGORITHM_HEX_LENGTH = {
38
+ sha256: 64,
39
+ sha384: 96,
40
+ sha512: 128
41
+ };
42
+ const HEX_LENGTH_TO_ALGORITHM = {
43
+ 64: "sha256",
44
+ 96: "sha384",
45
+ 128: "sha512"
46
+ };
31
47
  /**
32
- * Convert a sha256 hex checksum to its SRI integrity form (`sha256-<base64>`).
33
- * Idempotent on integrity input — call this on user-supplied data without first
34
- * sniffing the format.
35
- *
36
- * The default algorithm is `'sha256'` because this converts a _checksum_, and
37
- * checksums are sha256 by fleet convention (the GitHub-SHA256SUMS interop shape
38
- * its only caller, `checksum-file.ts`, parses). Do NOT flip this default to
39
- * sha512: this function only relabels the hex bytes, it does not re-hash, so a
40
- * sha512 label on a 256-bit digest would be a lie. The canonical algorithm for
41
- * OUR-side integrity values is sha512 — emitted by `computeHashes` as the
42
- * `integrity` (`sha512-<base64>`) field; sha256 is reserved for
43
- * upstream-SHASUMS interop and content addressing. Pass an explicit algorithm
44
- * if you have a hex digest from `sha384` or `sha512` (the function does not
45
- * verify hex length against the algorithm — caller's responsibility).
46
- *
47
- * @example
48
- * ;```typescript
49
- * checksumToIntegrity(
50
- * '3620a0fcaf81ecd3aaeccd5965919d90dbc913f4d07a96e11e7cafc2c785054b',
51
- * )
52
- * // 'sha256-NiCg/K+B7NOq7M1ZZZGdkNvJE/TQepbhHnyvwseFBUs='
48
+ * Convert a hex checksum to its SRI integrity form.
53
49
  *
54
- * checksumToIntegrity('sha256-NiCg/K+B7NOq7M1ZZZGdkNvJE/TQepbhHnyvwseFBUs=')
55
- * // 'sha256-NiCg/K+B7NOq7M1ZZZGdkNvJE/TQepbhHnyvwseFBUs=' (idempotent)
56
- * ```
50
+ * @deprecated Prefer `parseHash(x).sri`, which is total across all algorithms
51
+ * and infers the algorithm from a bare hex digest. This shim defaults to
52
+ * `'sha256'` because it only relabels the hex bytes — it does NOT re-hash, so
53
+ * a sha512 label on a 256-bit digest would be a lie. Idempotent on SRI input.
57
54
  *
58
55
  * @throws TypeError when the input is neither a recognized SRI nor a hex
59
56
  * digest.
60
57
  */
61
58
  function checksumToIntegrity(input, algorithm = "sha256") {
62
59
  if (isIntegrity(input)) return input;
63
- if (!/^[a-f0-9]+$/i.test(input)) throw new require_primordials_error.TypeErrorCtor(`checksumToIntegrity: expected a hex digest or SRI string, got: ${input}`);
64
- return `${algorithm}-${require_primordials_buffer.BufferPrototypeToString(require_primordials_buffer.BufferFrom(input, "hex"), "base64")}`;
60
+ if (!HEX_RE.test(input)) throw new require_primordials_error.TypeErrorCtor(`checksumToIntegrity: expected a hex digest or SRI string, got: ${input}`);
61
+ return makeHash(algorithm, input).sri;
65
62
  }
66
63
  /**
67
- * Compute both integrity (sha512 SRI) and checksum (sha256 hex) for a buffer of
68
- * bytes.
64
+ * Compute a single {@link Hash} of `bytes`. Defaults to sha512 the canonical
65
+ * trust string we pin against. Pass `'sha256'` for the upstream-interop digest.
66
+ *
67
+ * @example
68
+ * ;```typescript
69
+ * computeHash(bytes).sri // 'sha512-…' (pin this)
70
+ * computeHash(bytes, 'sha256').hex // '3620a0…' (compare to SHA256SUMS)
71
+ * ```
72
+ */
73
+ function computeHash(bytes, algorithm = "sha512") {
74
+ return makeHash(algorithm, require_crypto_hash.hash(algorithm, bytes, "hex"));
75
+ }
76
+ /**
77
+ * Compute both pinned formats for `bytes`: the sha512 SRI integrity and the
78
+ * sha256 hex checksum. Use when a config records both (e.g.
79
+ * `external-tools.json`, dlx lockfiles).
69
80
  */
70
81
  function computeHashes(bytes) {
71
82
  return {
72
- integrity: `sha512-${require_crypto_hash.hash("sha512", bytes, "base64")}`,
73
- checksum: require_crypto_hash.hash("sha256", bytes, "hex")
83
+ integrity: computeHash(bytes, "sha512").sri,
84
+ checksum: computeHash(bytes, "sha256").hex
74
85
  };
75
86
  }
76
87
  /**
77
- * Convert a sha256 SRI integrity string to its hex checksum form (64 lowercase
78
- * chars). Idempotent on checksum input.
88
+ * Compare two hashes for equality, ENCODING-agnostically. Parses both and
89
+ * only when they share an algorithm — timing-safe compares the digests.
90
+ *
91
+ * Returns false when the algorithms differ. A sha512 and a sha256 are different
92
+ * functions of the same bytes: their digests are unrelated values, so they can
93
+ * never be "equal", and you CANNOT derive or check one against the other
94
+ * without the original bytes. To confirm a sha256 and a sha512 describe the
95
+ * same content, hash the bytes both ways (`computeHashes`) or `verifyHash` the
96
+ * bytes against each — there is no hash-to-hash shortcut across algorithms.
79
97
  *
80
- * Throws on `sha384` and `sha512` SRI checksums are sha256-only by fleet
81
- * convention. Callers that need a hex digest for those algorithms can call
82
- * `parseIntegrity(sri)` and decode `.body` manually.
98
+ * What this DOES solve is the cross-ENCODING case that bites string `===`: a
99
+ * sha256 SRI and the same sha256 hex compare equal here.
83
100
  *
84
101
  * @example
85
102
  * ;```typescript
86
- * integrityToChecksum('sha256-NiCg/K+B7NOq7M1ZZZGdkNvJE/TQepbhHnyvwseFBUs=')
87
- * // '3620a0fcaf81ecd3aaeccd5965919d90dbc913f4d07a96e11e7cafc2c785054b'
88
- *
89
- * integrityToChecksum(
90
- * '3620a0fcaf81ecd3aaeccd5965919d90dbc913f4d07a96e11e7cafc2c785054b',
91
- * )
92
- * // '3620a0fcaf81ecd3aaeccd5965919d90dbc913f4d07a96e11e7cafc2c785054b' (idempotent)
103
+ * equalHashes('sha256-NiCg', '3620a0fc…') // true (same digest, SRI vs hex)
104
+ * equalHashes('sha512-…', '3620a0fc…') // false (different algorithms)
93
105
  * ```
94
106
  *
107
+ * @throws TypeError when either input is not a recognized hash.
108
+ */
109
+ function equalHashes(a, b) {
110
+ const aHash = parseHash(a);
111
+ const bHash = parseHash(b);
112
+ if (aHash.algorithm !== bHash.algorithm) return false;
113
+ const aBuf = require_primordials_buffer.BufferFrom(aHash.hex, "hex");
114
+ const bBuf = require_primordials_buffer.BufferFrom(bHash.hex, "hex");
115
+ return aBuf.length === bBuf.length && node_crypto.default.timingSafeEqual(aBuf, bBuf);
116
+ }
117
+ /**
118
+ * Convert an SRI integrity string to its hex checksum form.
119
+ *
120
+ * @deprecated Prefer `parseHash(x).hex`, which is total across all algorithms.
121
+ * This shim is sha256-only (throws on sha384 / sha512) to preserve its
122
+ * historical "checksums are sha256" contract. Idempotent on hex input.
123
+ *
95
124
  * @throws TypeError when the input is neither a recognized SRI nor a hex
96
125
  * checksum, or when the input is a non-sha256 SRI.
97
126
  */
98
127
  function integrityToChecksum(input) {
99
128
  if (isChecksum(input)) return input;
100
129
  const parsed = parseIntegrity(input);
101
- if (parsed.algorithm !== "sha256") throw new require_primordials_error.TypeErrorCtor(`integrityToChecksum: ${parsed.algorithm} integrity has no 64-hex-char checksum form — checksums are sha256-only by fleet convention.`);
130
+ if (parsed.algorithm !== "sha256") throw new require_primordials_error.TypeErrorCtor(`integrityToChecksum: ${parsed.algorithm} integrity has no 64-hex-char checksum form — checksums are sha256-only by fleet convention. Use parseHash(x).hex for any algorithm.`);
102
131
  return require_primordials_buffer.BufferPrototypeToString(require_primordials_buffer.BufferFrom(parsed.body, "base64"), "hex");
103
132
  }
104
133
  /**
@@ -108,18 +137,36 @@ function isChecksum(s) {
108
137
  return CHECKSUM_RE.test(s);
109
138
  }
110
139
  /**
140
+ * True when `s` is a bare hex digest of a recognized length (sha256 / sha384 /
141
+ * sha512).
142
+ */
143
+ function isHex(s) {
144
+ return HEX_RE.test(s) && HEX_LENGTH_TO_ALGORITHM[s.length] !== void 0;
145
+ }
146
+ /**
111
147
  * True when `s` is a W3C SRI integrity string: `sha(256|384|512)-<base64>`.
112
148
  */
113
149
  function isIntegrity(s) {
114
150
  return INTEGRITY_RE.test(s);
115
151
  }
116
152
  /**
153
+ * Build a frozen {@link Hash} from an algorithm and a hex digest. The internal
154
+ * constructor — trusts its inputs (lowercases the hex, computes the SRI view);
155
+ * use {@link parseHash} for untrusted strings, which validates first.
156
+ */
157
+ function makeHash(algorithm, hex) {
158
+ const lowerHex = require_primordials_string.StringPrototypeToLowerCase(hex);
159
+ return require_primordials_object.ObjectFreeze({
160
+ algorithm,
161
+ hex: lowerHex,
162
+ sri: `${algorithm}-${require_primordials_buffer.BufferPrototypeToString(require_primordials_buffer.BufferFrom(lowerHex, "hex"), "base64")}`
163
+ });
164
+ }
165
+ /**
117
166
  * Normalize a {@link HashSpec} to its canonical `{ type, value }` form.
118
167
  *
119
- * - Object form is trusted (its `value` is validated for shape).
120
- * - Bare string matching SRI integrity.
121
- * - Bare string of 64 hex chars → checksum.
122
- * - Anything else throws TypeError.
168
+ * @deprecated Prefer {@link parseHash}, which returns an algorithm-tagged
169
+ * {@link Hash}. Kept for callers that branch on integrity-vs-checksum type.
123
170
  *
124
171
  * @throws TypeError if the string is not a recognized format, or if an explicit
125
172
  * object's value doesn't match its declared type.
@@ -154,14 +201,37 @@ function normalizeHash(spec) {
154
201
  throw new require_primordials_error.TypeErrorCtor(`normalizeHash: unrecognized hash format. Expected SRI integrity ("sha(256|384|512)-<base64>") or sha256 hex checksum (64 hex chars), got: ${spec}`);
155
202
  }
156
203
  /**
157
- * Split an integrity string into its `{ algorithm, body }` components. `body`
158
- * is the base64-encoded digest (everything after the algorithm + dash).
204
+ * Parse any {@link HashInput} into a canonical {@link Hash}. The one entry
205
+ * point for untrusted input validates shape + length, then freezes.
159
206
  *
160
- * @example
161
- * ;```typescript
162
- * parseIntegrity('sha256-NiCg/K+B7NOq7M1ZZZGdkNvJE/TQepbhHnyvwseFBUs=')
163
- * // { algorithm: 'sha256', body: 'NiCg/K+B7NOq7M1ZZZGdkNvJE/TQepbhHnyvwseFBUs=' }
164
- * ```
207
+ * - A {@link Hash} object is re-canonicalized from its `algorithm` + `hex`.
208
+ * - An SRI string carries its algorithm in the prefix (the body length is checked
209
+ * against it).
210
+ * - A bare hex digest infers the algorithm from its length (64 / 96 / 128).
211
+ *
212
+ * @throws TypeError when the input is not a recognized SRI or hex digest, or
213
+ * when an SRI body's length doesn't match its declared algorithm.
214
+ */
215
+ function parseHash(input) {
216
+ if (typeof input === "object" && input !== null) return makeHash(input.algorithm, input.hex);
217
+ const sriMatch = INTEGRITY_RE.exec(input);
218
+ if (sriMatch) {
219
+ const algorithm = sriMatch[1];
220
+ const hex = require_primordials_buffer.BufferPrototypeToString(require_primordials_buffer.BufferFrom(sriMatch[2], "base64"), "hex");
221
+ const expectedLength = ALGORITHM_HEX_LENGTH[algorithm];
222
+ if (hex.length !== expectedLength) throw new require_primordials_error.TypeErrorCtor(`parseHash: ${algorithm} SRI body decodes to ${hex.length} hex chars, expected ${expectedLength}: ${input}`);
223
+ return makeHash(algorithm, hex);
224
+ }
225
+ if (HEX_RE.test(input)) {
226
+ const algorithm = HEX_LENGTH_TO_ALGORITHM[input.length];
227
+ if (algorithm === void 0) throw new require_primordials_error.TypeErrorCtor(`parseHash: hex digest is ${input.length} chars; expected 64 (sha256), 96 (sha384), or 128 (sha512): ${input}`);
228
+ return makeHash(algorithm, input);
229
+ }
230
+ throw new require_primordials_error.TypeErrorCtor(`parseHash: expected an SRI string ("sha(256|384|512)-<base64>") or a hex digest, got: ${input}`);
231
+ }
232
+ /**
233
+ * Split an SRI integrity string into its `{ algorithm, body }` components.
234
+ * `body` is the base64-encoded digest.
165
235
  *
166
236
  * @throws Error when the input is not a valid SRI integrity string.
167
237
  */
@@ -174,41 +244,55 @@ function parseIntegrity(sri) {
174
244
  };
175
245
  }
176
246
  /**
177
- * Verify computed hashes against an expected {@link NormalizedHash}. Uses
178
- * `crypto.timingSafeEqual` for constant-time comparison.
247
+ * Verify `bytes` against an expected hash. Reads the algorithm the expected
248
+ * hash declares, computes only that digest, and compares with
249
+ * `crypto.timingSafeEqual` — so any encoding (hex / SRI / {@link Hash}) and any
250
+ * algorithm (sha256 / sha384 / sha512) verifies without the caller reconciling
251
+ * formats first.
179
252
  *
180
- * @throws DlxHashMismatchError when the hash of the matching type doesn't match
181
- * the expected value.
253
+ * @throws HashMismatchError when the recomputed digest doesn't match.
254
+ * @throws TypeError when `expected` is not a recognized hash.
182
255
  */
183
- function verifyHash(expected, computed) {
184
- const actual = expected.type === "integrity" ? computed.integrity : computed.checksum;
185
- const expectedBuf = require_primordials_buffer.BufferFrom(expected.value);
186
- const actualBuf = require_primordials_buffer.BufferFrom(actual);
187
- if (expectedBuf.length !== actualBuf.length || !node_crypto.default.timingSafeEqual(expectedBuf, actualBuf)) throw new DlxHashMismatchError(expected, computed);
256
+ function verifyHash(bytes, expected) {
257
+ const expectedHash = parseHash(expected);
258
+ const actualHash = computeHash(bytes, expectedHash.algorithm);
259
+ const expectedBuf = require_primordials_buffer.BufferFrom(expectedHash.hex, "hex");
260
+ const actualBuf = require_primordials_buffer.BufferFrom(actualHash.hex, "hex");
261
+ if (expectedBuf.length !== actualBuf.length || !node_crypto.default.timingSafeEqual(expectedBuf, actualBuf)) throw new HashMismatchError(expectedHash, actualHash);
188
262
  }
189
263
  /**
190
- * Thrown when an expected hash doesn't match the computed hash of the
191
- * downloaded bytes. Carries both sides for diagnostics.
264
+ * Thrown when an expected hash doesn't match the computed hash of the verified
265
+ * bytes. Carries both sides (as {@link Hash}) for diagnostics.
192
266
  */
193
- var DlxHashMismatchError = class extends Error {
267
+ var HashMismatchError = class extends Error {
194
268
  expected;
195
269
  actual;
196
270
  constructor(expected, actual) {
197
- const actualValue = expected.type === "integrity" ? actual.integrity : actual.checksum;
198
- super(`Hash mismatch (${expected.type}): expected ${expected.value}, got ${actualValue}`);
199
- this.name = "DlxHashMismatchError";
271
+ super(`Hash mismatch (${expected.algorithm}): expected ${expected.sri}, got ${actual.sri}`);
272
+ this.name = "HashMismatchError";
200
273
  this.expected = expected;
201
274
  this.actual = actual;
202
275
  }
203
276
  };
277
+ /**
278
+ * @deprecated Renamed to {@link HashMismatchError}. Alias kept for callers that
279
+ * catch the old name.
280
+ */
281
+ const DlxHashMismatchError = HashMismatchError;
204
282
 
205
283
  //#endregion
206
284
  exports.DlxHashMismatchError = DlxHashMismatchError;
285
+ exports.HashMismatchError = HashMismatchError;
207
286
  exports.checksumToIntegrity = checksumToIntegrity;
287
+ exports.computeHash = computeHash;
208
288
  exports.computeHashes = computeHashes;
289
+ exports.equalHashes = equalHashes;
209
290
  exports.integrityToChecksum = integrityToChecksum;
210
291
  exports.isChecksum = isChecksum;
292
+ exports.isHex = isHex;
211
293
  exports.isIntegrity = isIntegrity;
294
+ exports.makeHash = makeHash;
212
295
  exports.normalizeHash = normalizeHash;
296
+ exports.parseHash = parseHash;
213
297
  exports.parseIntegrity = parseIntegrity;
214
298
  exports.verifyHash = verifyHash;
@@ -5,13 +5,12 @@
5
5
  * emitted via the 24-bit `[38;2;...m` escape because `yoctocolors-cjs`
6
6
  * doesn't ship an `rgb()` helper.
7
7
  */
8
- import yoctocolorsCjs from '../external/yoctocolors-cjs';
9
8
  import type { ColorValue } from '../colors/types';
10
9
  /**
11
10
  * Apply a color to text using yoctocolors. Handles both named colors and RGB
12
11
  * tuples.
13
12
  */
14
- export declare function applyColor(text: string, color: ColorValue, colors: typeof yoctocolorsCjs): string;
13
+ export declare function applyColor(text: string, color: ColorValue): string;
15
14
  /**
16
15
  * Get the yoctocolors module for terminal colors.
17
16
  */
@@ -17,9 +17,9 @@ src_external_yoctocolors_cjs = require_runtime.__toESM(src_external_yoctocolors_
17
17
  * Apply a color to text using yoctocolors. Handles both named colors and RGB
18
18
  * tuples.
19
19
  */
20
- function applyColor(text, color, colors) {
20
+ function applyColor(text, color) {
21
21
  if (typeof color === "string") {
22
- const formatter = colors[color];
22
+ const formatter = src_external_yoctocolors_cjs.default[color];
23
23
  return formatter ? formatter(text) : text;
24
24
  }
25
25
  const { 0: r, 1: g, 2: b } = color;
@@ -26,18 +26,17 @@ src_external__socketregistry_is_unicode_supported = require_runtime.__toESM(src_
26
26
  */
27
27
  function buildLoggerSymbols(theme) {
28
28
  const supported = (0, src_external__socketregistry_is_unicode_supported.default)();
29
- const colors = require_logger_colors.getYoctocolors();
30
29
  /* c8 ignore start - ASCII-fallback symbol arms only fire on
31
30
  terminals without unicode support; tests run on unicode TTYs. */
32
31
  return {
33
32
  __proto__: null,
34
- fail: require_logger_colors.applyColor(supported ? "✖" : "×", theme.colors.error, colors),
35
- info: require_logger_colors.applyColor(supported ? "ℹ" : "i", theme.colors.info, colors),
36
- progress: require_logger_colors.applyColor(supported ? "∴" : ":.", theme.colors.step, colors),
37
- skip: require_logger_colors.applyColor(supported ? "↻" : "@", theme.colors.step, colors),
38
- step: require_logger_colors.applyColor(supported ? "→" : ">", theme.colors.step, colors),
39
- success: require_logger_colors.applyColor(supported ? "✔" : "√", theme.colors.success, colors),
40
- warn: require_logger_colors.applyColor(supported ? "⚠" : "‼", theme.colors.warning, colors)
33
+ fail: require_logger_colors.applyColor(supported ? "✖" : "×", theme.colors.error),
34
+ info: require_logger_colors.applyColor(supported ? "ℹ" : "i", theme.colors.info),
35
+ progress: require_logger_colors.applyColor(supported ? "∴" : ":.", theme.colors.step),
36
+ skip: require_logger_colors.applyColor(supported ? "↻" : "@", theme.colors.step),
37
+ step: require_logger_colors.applyColor(supported ? "→" : ">", theme.colors.step),
38
+ success: require_logger_colors.applyColor(supported ? "✔" : "√", theme.colors.success),
39
+ warn: require_logger_colors.applyColor(supported ? "⚠" : "‼", theme.colors.warning)
41
40
  };
42
41
  /* c8 ignore stop */
43
42
  }
@@ -39,14 +39,14 @@ function createLogSymbols() {
39
39
  const stepColor = theme.colors.step;
40
40
  /* c8 ignore start - ASCII-fallback symbol arms only fire on
41
41
  terminals without unicode support; tests run on unicode TTYs. */
42
- target["fail"] = require_logger_colors.applyColor(supported ? "✖" : "×", errorColor, colors);
43
- target["info"] = require_logger_colors.applyColor(supported ? "ℹ" : "i", infoColor, colors);
44
- target["progress"] = require_logger_colors.applyColor(supported ? "∴" : ":.", stepColor, colors);
45
- target["reason"] = colors.dim(require_logger_colors.applyColor(supported ? "∴" : ":.", warningColor, colors));
46
- target["skip"] = require_logger_colors.applyColor(supported ? "↻" : "@", stepColor, colors);
47
- target["step"] = require_logger_colors.applyColor(supported ? "→" : ">", stepColor, colors);
48
- target["success"] = require_logger_colors.applyColor(supported ? "✔" : "√", successColor, colors);
49
- target["warn"] = require_logger_colors.applyColor(supported ? "⚠" : "‼", warningColor, colors);
42
+ target["fail"] = require_logger_colors.applyColor(supported ? "✖" : "×", errorColor);
43
+ target["info"] = require_logger_colors.applyColor(supported ? "ℹ" : "i", infoColor);
44
+ target["progress"] = require_logger_colors.applyColor(supported ? "∴" : ":.", stepColor);
45
+ target["reason"] = colors.dim(require_logger_colors.applyColor(supported ? "∴" : ":.", warningColor));
46
+ target["skip"] = require_logger_colors.applyColor(supported ? "↻" : "@", stepColor);
47
+ target["step"] = require_logger_colors.applyColor(supported ? "→" : ">", stepColor);
48
+ target["success"] = require_logger_colors.applyColor(supported ? "✔" : "√", successColor);
49
+ target["warn"] = require_logger_colors.applyColor(supported ? "⚠" : "‼", warningColor);
50
50
  /* c8 ignore stop */
51
51
  };
52
52
  const init = () => {
@@ -1,7 +1,78 @@
1
1
  /**
2
- * @file Lazy-loader for `node:module`. See `node/fs.ts` for the design
3
- * rationale shared across all `node/*.ts` lazy-loaders.
2
+ * @file Accessors for `node:module` that work across runtimes. Ambient
3
+ * `require` is bound in CommonJS but unbound in ESM and inside
4
+ * ahead-of-time-compiled package modules (e.g. Perry), where reading it
5
+ * throws. And Perry's `require('module')` value omits `isBuiltin`. So instead
6
+ * of the ambient `require('module')` lazy-loader, `isBuiltin`/`createRequire`
7
+ * are imported as named values from the bare `module` specifier — which
8
+ * resolves on Node and Perry, and which browser bundlers can stub via
9
+ * resolve.fallback (a `node:` prefix would throw UnhandledSchemeError
10
+ * there).
11
+ * `require` is DIRECTORY-SPECIFIC: `createRequire(base)` resolves relative
12
+ * specifiers (`./x`, `../y`) from `base`'s directory. For builtins and bare
13
+ * packages that's irrelevant (they resolve the same anywhere), so the cached
14
+ * `getRequire` / `requireBuiltin` bind to THIS file. A RELATIVE specifier
15
+ * must resolve from the CALLER's directory, so use `requireFrom` with the
16
+ * caller's `import.meta.url` — binding such a load to this file would resolve
17
+ * it against `src/node/` instead. Bundled, every module collapses to one base
18
+ * and either works; unbundled (e.g. AOT-compiled from source), each module
19
+ * sits at its own nested path and the base matters.
4
20
  */
5
21
  import type * as NodeModule from 'node:module';
22
+ /**
23
+ * Bind a working `require`. Ambient `require` exists in CommonJS; in ESM and
24
+ * ahead-of-time-compiled package modules it is unbound (reading it throws or
25
+ * yields undefined), so fall back to `createRequire`. Returns undefined off
26
+ * Node and in browsers, where neither is available.
27
+ *
28
+ * `fromUrl` sets the resolution base — pass a caller's `import.meta.url` to
29
+ * resolve that caller's RELATIVE specifiers. When omitted, the base is this
30
+ * file, which is correct only for builtins / bare packages (dir-independent).
31
+ * With `fromUrl` the ambient `require` is skipped: it is bound to THIS file, so
32
+ * it would resolve a relative specifier from the wrong directory.
33
+ */
34
+ export declare function bindRequire(fromUrl?: string | undefined): ((id: string) => unknown) | undefined;
35
+ /**
36
+ * Returns `node:module` (or undefined off Node), loaded through the bound
37
+ * `require`. Cached across calls.
38
+ */
6
39
  export declare function getNodeModule(): typeof NodeModule;
40
+ /**
41
+ * Returns a working `require` bound to THIS file, binding one on first call
42
+ * (see bindRequire). Cached across calls; undefined off Node / in browsers.
43
+ *
44
+ * For builtins and bare packages only — the resolution base is this file, so a
45
+ * relative specifier would resolve from `src/node/`. Use `requireFrom` for
46
+ * relative loads.
47
+ */
48
+ export declare function getRequire(): ((id: string) => unknown) | undefined;
49
+ /**
50
+ * Is `name` a Node built-in module? Resolved from the statically-imported
51
+ * `isBuiltin`, so it works on Node and on ahead-of-time-compiled binaries
52
+ * (Perry), where ambient `require('module')` would lack `isBuiltin`. Returns
53
+ * false in browsers, where the bare `module` import is stubbed away.
54
+ *
55
+ * Single source of truth for "is this a Node builtin?" probes across socket-lib
56
+ * (used by the smol-binding loaders to gate their `node:smol-*` loads).
57
+ */
7
58
  export declare function isNodeBuiltin(name: string): boolean;
59
+ /**
60
+ * Load a built-in module by *computed* specifier through the bound `require`
61
+ * (see getRequire). The specifier is a parameter — never a literal at the call
62
+ * site — so browser bundlers neither walk nor bundle it. Returns undefined
63
+ * where no `require` can be bound.
64
+ *
65
+ * Builtins / bare packages only (dir-independent); for a relative specifier use
66
+ * `requireFrom`. Used by `getNodeModule` for `node:module`, and by the
67
+ * smol-binding loaders for the optional `node:smol-*` native bindings (gated
68
+ * behind `isNodeBuiltin`, true only on socket-btm's smol Node binary).
69
+ */
70
+ export declare function requireBuiltin(specifier: string): unknown;
71
+ /**
72
+ * Load a module by specifier from a CALLER-supplied base (its
73
+ * `import.meta.url`). Use this for RELATIVE specifiers (`./x`, `../y`), whose
74
+ * resolution depends on the caller's directory — `requireBuiltin` binds to this
75
+ * file and would resolve them from `src/node/`. Not cached: the binding is
76
+ * per-caller. Returns undefined where no `require` can be bound.
77
+ */
78
+ export declare function requireFrom(fromUrl: string, specifier: string): unknown;
@@ -2,30 +2,115 @@
2
2
  /* Socket Lib - Built with rolldown */
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
  const require_constants_runtime = require('../constants/runtime.js');
5
+ let module$1 = require("module");
5
6
 
6
7
  //#region src/node/module.ts
8
+ /**
9
+ * @file Accessors for `node:module` that work across runtimes. Ambient
10
+ * `require` is bound in CommonJS but unbound in ESM and inside
11
+ * ahead-of-time-compiled package modules (e.g. Perry), where reading it
12
+ * throws. And Perry's `require('module')` value omits `isBuiltin`. So instead
13
+ * of the ambient `require('module')` lazy-loader, `isBuiltin`/`createRequire`
14
+ * are imported as named values from the bare `module` specifier — which
15
+ * resolves on Node and Perry, and which browser bundlers can stub via
16
+ * resolve.fallback (a `node:` prefix would throw UnhandledSchemeError
17
+ * there).
18
+ * `require` is DIRECTORY-SPECIFIC: `createRequire(base)` resolves relative
19
+ * specifiers (`./x`, `../y`) from `base`'s directory. For builtins and bare
20
+ * packages that's irrelevant (they resolve the same anywhere), so the cached
21
+ * `getRequire` / `requireBuiltin` bind to THIS file. A RELATIVE specifier
22
+ * must resolve from the CALLER's directory, so use `requireFrom` with the
23
+ * caller's `import.meta.url` — binding such a load to this file would resolve
24
+ * it against `src/node/` instead. Bundled, every module collapses to one base
25
+ * and either works; unbundled (e.g. AOT-compiled from source), each module
26
+ * sits at its own nested path and the base matters.
27
+ */
7
28
  let cachedModule;
8
- function getNodeModule() {
29
+ let cachedRequire;
30
+ /**
31
+ * Bind a working `require`. Ambient `require` exists in CommonJS; in ESM and
32
+ * ahead-of-time-compiled package modules it is unbound (reading it throws or
33
+ * yields undefined), so fall back to `createRequire`. Returns undefined off
34
+ * Node and in browsers, where neither is available.
35
+ *
36
+ * `fromUrl` sets the resolution base — pass a caller's `import.meta.url` to
37
+ * resolve that caller's RELATIVE specifiers. When omitted, the base is this
38
+ * file, which is correct only for builtins / bare packages (dir-independent).
39
+ * With `fromUrl` the ambient `require` is skipped: it is bound to THIS file, so
40
+ * it would resolve a relative specifier from the wrong directory.
41
+ */
42
+ function bindRequire(fromUrl) {
9
43
  if (!require_constants_runtime.IS_NODE) return;
10
- return cachedModule ??= /*@__PURE__*/ require("module");
44
+ if (!fromUrl && typeof require === "function") return require;
45
+ if (typeof module$1.createRequire === "function") try {
46
+ return (0, module$1.createRequire)(fromUrl ?? require("url").pathToFileURL(__filename).href);
47
+ } catch {
48
+ return;
49
+ }
50
+ }
51
+ /**
52
+ * Returns `node:module` (or undefined off Node), loaded through the bound
53
+ * `require`. Cached across calls.
54
+ */
55
+ function getNodeModule() {
56
+ return cachedModule ??= requireBuiltin("module");
11
57
  }
12
58
  /**
13
- * Lazy + cached reference to `node:module`'s `isBuiltin(name)`. First call
14
- * resolves the binding; subsequent calls dispatch through the cached function
15
- * reference. Safe to detach — `isBuiltin` is `this`-free.
59
+ * Returns a working `require` bound to THIS file, binding one on first call
60
+ * (see bindRequire). Cached across calls; undefined off Node / in browsers.
16
61
  *
17
- * Returns `false` in browser / non-CJS environments where `require` is
18
- * undefined no `node:` modules are built-in there.
62
+ * For builtins and bare packages only the resolution base is this file, so a
63
+ * relative specifier would resolve from `src/node/`. Use `requireFrom` for
64
+ * relative loads.
65
+ */
66
+ function getRequire() {
67
+ if (cachedRequire === void 0) cachedRequire = bindRequire();
68
+ return cachedRequire;
69
+ }
70
+ /**
71
+ * Is `name` a Node built-in module? Resolved from the statically-imported
72
+ * `isBuiltin`, so it works on Node and on ahead-of-time-compiled binaries
73
+ * (Perry), where ambient `require('module')` would lack `isBuiltin`. Returns
74
+ * false in browsers, where the bare `module` import is stubbed away.
19
75
  *
20
76
  * Single source of truth for "is this a Node builtin?" probes across socket-lib
21
- * (used by the smol-binding loaders to gate `require('node:smol-*')`).
77
+ * (used by the smol-binding loaders to gate their `node:smol-*` loads).
22
78
  */
23
- let cachedIsBuiltin;
24
79
  function isNodeBuiltin(name) {
25
- if (!require_constants_runtime.IS_NODE) return false;
26
- return (cachedIsBuiltin ??= getNodeModule().isBuiltin)(name);
80
+ if (!require_constants_runtime.IS_NODE || typeof module$1.isBuiltin !== "function") return false;
81
+ return (0, module$1.isBuiltin)(name);
82
+ }
83
+ /**
84
+ * Load a built-in module by *computed* specifier through the bound `require`
85
+ * (see getRequire). The specifier is a parameter — never a literal at the call
86
+ * site — so browser bundlers neither walk nor bundle it. Returns undefined
87
+ * where no `require` can be bound.
88
+ *
89
+ * Builtins / bare packages only (dir-independent); for a relative specifier use
90
+ * `requireFrom`. Used by `getNodeModule` for `node:module`, and by the
91
+ * smol-binding loaders for the optional `node:smol-*` native bindings (gated
92
+ * behind `isNodeBuiltin`, true only on socket-btm's smol Node binary).
93
+ */
94
+ function requireBuiltin(specifier) {
95
+ const req = getRequire();
96
+ if (req) return req(specifier);
97
+ }
98
+ /**
99
+ * Load a module by specifier from a CALLER-supplied base (its
100
+ * `import.meta.url`). Use this for RELATIVE specifiers (`./x`, `../y`), whose
101
+ * resolution depends on the caller's directory — `requireBuiltin` binds to this
102
+ * file and would resolve them from `src/node/`. Not cached: the binding is
103
+ * per-caller. Returns undefined where no `require` can be bound.
104
+ */
105
+ function requireFrom(fromUrl, specifier) {
106
+ const req = bindRequire(fromUrl);
107
+ if (req) return req(specifier);
27
108
  }
28
109
 
29
110
  //#endregion
111
+ exports.bindRequire = bindRequire;
30
112
  exports.getNodeModule = getNodeModule;
31
- exports.isNodeBuiltin = isNodeBuiltin;
113
+ exports.getRequire = getRequire;
114
+ exports.isNodeBuiltin = isNodeBuiltin;
115
+ exports.requireBuiltin = requireBuiltin;
116
+ exports.requireFrom = requireFrom;