@scelar/nodepod 1.0.0

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 (134) hide show
  1. package/LICENSE +43 -0
  2. package/README.md +240 -0
  3. package/dist/child_process-BJOMsZje.js +8233 -0
  4. package/dist/child_process-BJOMsZje.js.map +1 -0
  5. package/dist/child_process-Cj8vOcuc.cjs +7434 -0
  6. package/dist/child_process-Cj8vOcuc.cjs.map +1 -0
  7. package/dist/index-Cb1Cgdnd.js +35308 -0
  8. package/dist/index-Cb1Cgdnd.js.map +1 -0
  9. package/dist/index-DsMGS-xc.cjs +37195 -0
  10. package/dist/index-DsMGS-xc.cjs.map +1 -0
  11. package/dist/index.cjs +65 -0
  12. package/dist/index.cjs.map +1 -0
  13. package/dist/index.mjs +59 -0
  14. package/dist/index.mjs.map +1 -0
  15. package/package.json +95 -0
  16. package/src/__tests__/smoke.test.ts +11 -0
  17. package/src/constants/cdn-urls.ts +18 -0
  18. package/src/constants/config.ts +236 -0
  19. package/src/cross-origin.ts +26 -0
  20. package/src/engine-factory.ts +176 -0
  21. package/src/engine-types.ts +56 -0
  22. package/src/helpers/byte-encoding.ts +39 -0
  23. package/src/helpers/digest.ts +9 -0
  24. package/src/helpers/event-loop.ts +96 -0
  25. package/src/helpers/wasm-cache.ts +133 -0
  26. package/src/iframe-sandbox.ts +141 -0
  27. package/src/index.ts +192 -0
  28. package/src/isolation-helpers.ts +148 -0
  29. package/src/memory-volume.ts +941 -0
  30. package/src/module-transformer.ts +368 -0
  31. package/src/packages/archive-extractor.ts +248 -0
  32. package/src/packages/browser-bundler.ts +284 -0
  33. package/src/packages/installer.ts +396 -0
  34. package/src/packages/registry-client.ts +131 -0
  35. package/src/packages/version-resolver.ts +411 -0
  36. package/src/polyfills/assert.ts +384 -0
  37. package/src/polyfills/async_hooks.ts +144 -0
  38. package/src/polyfills/buffer.ts +628 -0
  39. package/src/polyfills/child_process.ts +2288 -0
  40. package/src/polyfills/chokidar.ts +336 -0
  41. package/src/polyfills/cluster.ts +106 -0
  42. package/src/polyfills/console.ts +136 -0
  43. package/src/polyfills/constants.ts +123 -0
  44. package/src/polyfills/crypto.ts +885 -0
  45. package/src/polyfills/dgram.ts +87 -0
  46. package/src/polyfills/diagnostics_channel.ts +76 -0
  47. package/src/polyfills/dns.ts +134 -0
  48. package/src/polyfills/domain.ts +68 -0
  49. package/src/polyfills/esbuild.ts +854 -0
  50. package/src/polyfills/events.ts +276 -0
  51. package/src/polyfills/fs.ts +2888 -0
  52. package/src/polyfills/fsevents.ts +79 -0
  53. package/src/polyfills/http.ts +1449 -0
  54. package/src/polyfills/http2.ts +199 -0
  55. package/src/polyfills/https.ts +76 -0
  56. package/src/polyfills/inspector.ts +62 -0
  57. package/src/polyfills/lightningcss.ts +105 -0
  58. package/src/polyfills/module.ts +191 -0
  59. package/src/polyfills/net.ts +353 -0
  60. package/src/polyfills/os.ts +238 -0
  61. package/src/polyfills/path.ts +206 -0
  62. package/src/polyfills/perf_hooks.ts +102 -0
  63. package/src/polyfills/process.ts +690 -0
  64. package/src/polyfills/punycode.ts +159 -0
  65. package/src/polyfills/querystring.ts +93 -0
  66. package/src/polyfills/quic.ts +118 -0
  67. package/src/polyfills/readdirp.ts +229 -0
  68. package/src/polyfills/readline.ts +692 -0
  69. package/src/polyfills/repl.ts +134 -0
  70. package/src/polyfills/rollup.ts +119 -0
  71. package/src/polyfills/sea.ts +33 -0
  72. package/src/polyfills/sqlite.ts +78 -0
  73. package/src/polyfills/stream.ts +1620 -0
  74. package/src/polyfills/string_decoder.ts +25 -0
  75. package/src/polyfills/tailwindcss-oxide.ts +309 -0
  76. package/src/polyfills/test.ts +197 -0
  77. package/src/polyfills/timers.ts +32 -0
  78. package/src/polyfills/tls.ts +105 -0
  79. package/src/polyfills/trace_events.ts +50 -0
  80. package/src/polyfills/tty.ts +71 -0
  81. package/src/polyfills/url.ts +174 -0
  82. package/src/polyfills/util.ts +559 -0
  83. package/src/polyfills/v8.ts +126 -0
  84. package/src/polyfills/vm.ts +132 -0
  85. package/src/polyfills/volume-registry.ts +15 -0
  86. package/src/polyfills/wasi.ts +44 -0
  87. package/src/polyfills/worker_threads.ts +326 -0
  88. package/src/polyfills/ws.ts +595 -0
  89. package/src/polyfills/zlib.ts +881 -0
  90. package/src/request-proxy.ts +716 -0
  91. package/src/script-engine.ts +3375 -0
  92. package/src/sdk/nodepod-fs.ts +93 -0
  93. package/src/sdk/nodepod-process.ts +86 -0
  94. package/src/sdk/nodepod-terminal.ts +350 -0
  95. package/src/sdk/nodepod.ts +509 -0
  96. package/src/sdk/types.ts +70 -0
  97. package/src/shell/commands/bun.ts +121 -0
  98. package/src/shell/commands/directory.ts +297 -0
  99. package/src/shell/commands/file-ops.ts +525 -0
  100. package/src/shell/commands/git.ts +2142 -0
  101. package/src/shell/commands/node.ts +80 -0
  102. package/src/shell/commands/npm.ts +198 -0
  103. package/src/shell/commands/pm-types.ts +45 -0
  104. package/src/shell/commands/pnpm.ts +82 -0
  105. package/src/shell/commands/search.ts +264 -0
  106. package/src/shell/commands/shell-env.ts +352 -0
  107. package/src/shell/commands/text-processing.ts +1152 -0
  108. package/src/shell/commands/yarn.ts +84 -0
  109. package/src/shell/shell-builtins.ts +19 -0
  110. package/src/shell/shell-helpers.ts +250 -0
  111. package/src/shell/shell-interpreter.ts +514 -0
  112. package/src/shell/shell-parser.ts +429 -0
  113. package/src/shell/shell-types.ts +85 -0
  114. package/src/syntax-transforms.ts +561 -0
  115. package/src/threading/engine-worker.ts +64 -0
  116. package/src/threading/inline-worker.ts +372 -0
  117. package/src/threading/offload-types.ts +112 -0
  118. package/src/threading/offload-worker.ts +383 -0
  119. package/src/threading/offload.ts +271 -0
  120. package/src/threading/process-context.ts +92 -0
  121. package/src/threading/process-handle.ts +275 -0
  122. package/src/threading/process-manager.ts +956 -0
  123. package/src/threading/process-worker-entry.ts +854 -0
  124. package/src/threading/shared-vfs.ts +352 -0
  125. package/src/threading/sync-channel.ts +135 -0
  126. package/src/threading/task-queue.ts +177 -0
  127. package/src/threading/vfs-bridge.ts +231 -0
  128. package/src/threading/worker-pool.ts +233 -0
  129. package/src/threading/worker-protocol.ts +358 -0
  130. package/src/threading/worker-vfs.ts +218 -0
  131. package/src/types/externals.d.ts +38 -0
  132. package/src/types/fs-streams.ts +142 -0
  133. package/src/types/manifest.ts +17 -0
  134. package/src/worker-sandbox.ts +90 -0
@@ -0,0 +1,885 @@
1
+ // Crypto polyfill using Web Crypto API with synchronous fallbacks
2
+
3
+ import { Buffer } from "./buffer";
4
+ import { EventEmitter } from "./events";
5
+
6
+ function normalizeAlg(name: string): string {
7
+ const upper = name.toUpperCase().replace(/[^A-Z0-9]/g, "");
8
+ switch (upper) {
9
+ case "SHA1":
10
+ return "SHA-1";
11
+ case "SHA256":
12
+ return "SHA-256";
13
+ case "SHA384":
14
+ return "SHA-384";
15
+ case "SHA512":
16
+ return "SHA-512";
17
+ case "MD5":
18
+ return "MD5";
19
+ default:
20
+ return name;
21
+ }
22
+ }
23
+
24
+ function hashOutputSize(alg: string): number {
25
+ if (alg.includes("512")) return 64;
26
+ if (alg.includes("384")) return 48;
27
+ if (alg.includes("1") || alg === "SHA-1") return 20;
28
+ return 32;
29
+ }
30
+
31
+ function mixHash(input: Uint8Array, alg: string): Uint8Array {
32
+ const size = hashOutputSize(alg);
33
+ const out = new Uint8Array(size);
34
+
35
+ let a = 0xdeadbeef | 0;
36
+ let b = 0x41c6ce57 | 0;
37
+
38
+ for (let i = 0; i < input.length; i++) {
39
+ a = Math.imul(a ^ input[i], 2654435761);
40
+ b = Math.imul(b ^ input[i], 1597334677);
41
+ }
42
+
43
+ a =
44
+ Math.imul(a ^ (a >>> 16), 2246822507) ^
45
+ Math.imul(b ^ (b >>> 13), 3266489909);
46
+ b =
47
+ Math.imul(b ^ (b >>> 16), 2246822507) ^
48
+ Math.imul(a ^ (a >>> 13), 3266489909);
49
+
50
+ for (let i = 0; i < size; i++) {
51
+ const source = i < size >>> 1 ? a : b;
52
+ out[i] = (source >>> ((i & 3) * 8)) & 0xff;
53
+ a = (Math.imul(a, 1103515245) + 12345) | 0;
54
+ b = (Math.imul(b, 1103515245) + 12345) | 0;
55
+ }
56
+ return out;
57
+ }
58
+
59
+ function mixHmac(data: Uint8Array, key: Uint8Array, alg: string): Uint8Array {
60
+ const merged = new Uint8Array(key.length + data.length);
61
+ merged.set(key, 0);
62
+ merged.set(data, key.length);
63
+ return mixHash(merged, alg);
64
+ }
65
+
66
+ function joinChunks(parts: Uint8Array[]): Uint8Array {
67
+ let total = 0;
68
+ for (const p of parts) total += p.length;
69
+ const result = new Uint8Array(total);
70
+ let pos = 0;
71
+ for (const p of parts) {
72
+ result.set(p, pos);
73
+ pos += p.length;
74
+ }
75
+ return result;
76
+ }
77
+
78
+ function formatOutput(raw: Uint8Array, enc?: string): string | Buffer {
79
+ if (enc === "hex") {
80
+ return Array.from(raw)
81
+ .map((b) => b.toString(16).padStart(2, "0"))
82
+ .join("");
83
+ }
84
+ if (enc === "base64") {
85
+ return btoa(String.fromCharCode(...raw));
86
+ }
87
+ return Buffer.from(raw);
88
+ }
89
+
90
+ export function randomBytes(count: number): Buffer {
91
+ const arr = new Uint8Array(count);
92
+ crypto.getRandomValues(arr);
93
+ return Buffer.from(arr);
94
+ }
95
+
96
+ export function randomFillSync(
97
+ target: Uint8Array | Buffer,
98
+ start?: number,
99
+ size?: number,
100
+ ): Uint8Array | Buffer {
101
+ const off = start || 0;
102
+ const len = size !== undefined ? size : target.length - off;
103
+ const view = new Uint8Array(target.buffer, target.byteOffset + off, len);
104
+ crypto.getRandomValues(view);
105
+ return target;
106
+ }
107
+
108
+ export function randomUUID(): string {
109
+ return crypto.randomUUID();
110
+ }
111
+
112
+ export function randomInt(lo: number, hi?: number): number {
113
+ if (hi === undefined) {
114
+ hi = lo;
115
+ lo = 0;
116
+ }
117
+ const span = hi - lo;
118
+ const buf = new Uint32Array(1);
119
+ crypto.getRandomValues(buf);
120
+ return lo + (buf[0] % span);
121
+ }
122
+
123
+ export function getRandomValues<T extends ArrayBufferView>(arr: T): T {
124
+ return crypto.getRandomValues(arr);
125
+ }
126
+
127
+ export interface Hash {
128
+ update(input: string | Buffer | Uint8Array, enc?: string): Hash;
129
+ digestAsync(enc?: string): Promise<string | Buffer>;
130
+ digest(enc?: string): string | Buffer;
131
+ }
132
+ interface HashConstructor {
133
+ new (alg: string): Hash;
134
+ (this: any, alg: string): void;
135
+ prototype: any;
136
+ }
137
+ export const Hash = function Hash(this: any, alg: string) {
138
+ if (!this) return;
139
+ this._alg = normalizeAlg(alg);
140
+ this._parts = [];
141
+ } as unknown as HashConstructor;
142
+
143
+ Hash.prototype.update = function update(input: string | Buffer | Uint8Array, enc?: string): any {
144
+ if (input == null) {
145
+ throw new TypeError('The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received ' + String(input));
146
+ }
147
+ let chunk: Buffer;
148
+ if (typeof input === "string") {
149
+ chunk = enc === "base64" ? Buffer.from(atob(input)) : Buffer.from(input);
150
+ } else {
151
+ chunk = Buffer.from(input);
152
+ }
153
+ this._parts.push(chunk);
154
+ return this;
155
+ };
156
+
157
+ Hash.prototype.digestAsync = async function digestAsync(enc?: string): Promise<string | Buffer> {
158
+ const merged = joinChunks(this._parts);
159
+ const ab = new Uint8Array(merged).buffer as ArrayBuffer;
160
+ const hashed = await crypto.subtle.digest(this._alg, ab);
161
+ return formatOutput(new Uint8Array(hashed), enc);
162
+ };
163
+
164
+ Hash.prototype.digest = function digest(enc?: string): string | Buffer {
165
+ const merged = joinChunks(this._parts);
166
+ const hashed = mixHash(merged, this._alg);
167
+ return formatOutput(hashed, enc);
168
+ };
169
+
170
+ export function createHash(alg: string): Hash {
171
+ return new Hash(alg);
172
+ }
173
+
174
+ // one-shot hash (Node.js 20.12+ API)
175
+ export function hash(
176
+ algorithm: string,
177
+ data: string | Buffer | Uint8Array,
178
+ outputEncoding?: string,
179
+ ): string | Buffer {
180
+ const h = createHash(algorithm);
181
+ h.update(data);
182
+ return h.digest(outputEncoding);
183
+ }
184
+
185
+ export interface Hmac {
186
+ update(input: string | Buffer | Uint8Array, enc?: string): Hmac;
187
+ digestAsync(enc?: string): Promise<string | Buffer>;
188
+ digest(enc?: string): string | Buffer;
189
+ }
190
+ interface HmacConstructor {
191
+ new (alg: string, secret: string | Buffer): Hmac;
192
+ (this: any, alg: string, secret: string | Buffer): void;
193
+ prototype: any;
194
+ }
195
+ export const Hmac = function Hmac(this: any, alg: string, secret: string | Buffer) {
196
+ if (!this) return;
197
+ this._alg = normalizeAlg(alg);
198
+ this._key = typeof secret === "string" ? Buffer.from(secret) : secret;
199
+ this._parts = [];
200
+ } as unknown as HmacConstructor;
201
+
202
+ Hmac.prototype.update = function update(input: string | Buffer | Uint8Array, _enc?: string): any {
203
+ if (input == null) {
204
+ throw new TypeError('The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received ' + String(input));
205
+ }
206
+ const chunk = typeof input === "string" ? Buffer.from(input) : input;
207
+ this._parts.push(chunk);
208
+ return this;
209
+ };
210
+
211
+ Hmac.prototype.digestAsync = async function digestAsync(enc?: string): Promise<string | Buffer> {
212
+ const merged = joinChunks(this._parts);
213
+ const keyBuf = new Uint8Array(this._key).buffer as ArrayBuffer;
214
+ const dataBuf = new Uint8Array(merged).buffer as ArrayBuffer;
215
+ const importedKey = await crypto.subtle.importKey(
216
+ "raw",
217
+ keyBuf,
218
+ { name: "HMAC", hash: this._alg },
219
+ false,
220
+ ["sign"],
221
+ );
222
+ const sig = await crypto.subtle.sign("HMAC", importedKey, dataBuf);
223
+ return formatOutput(new Uint8Array(sig), enc);
224
+ };
225
+
226
+ Hmac.prototype.digest = function digest(enc?: string): string | Buffer {
227
+ const merged = joinChunks(this._parts);
228
+ const result = mixHmac(merged, this._key, this._alg);
229
+ return formatOutput(result, enc);
230
+ };
231
+
232
+ export function createHmac(alg: string, secret: string | Buffer): Hmac {
233
+ return new Hmac(alg, secret);
234
+ }
235
+
236
+ type BinaryInput = string | Buffer | Uint8Array;
237
+
238
+ export function pbkdf2(
239
+ password: BinaryInput,
240
+ salt: BinaryInput,
241
+ rounds: number,
242
+ keyLen: number,
243
+ hashName: string,
244
+ cb: (err: Error | null, key: Buffer) => void,
245
+ ): void {
246
+ pbkdf2Async(password, salt, rounds, keyLen, hashName)
247
+ .then((k) => cb(null, k))
248
+ .catch((e) => cb(e, Buffer.alloc(0)));
249
+ }
250
+
251
+ async function pbkdf2Async(
252
+ password: BinaryInput,
253
+ salt: BinaryInput,
254
+ rounds: number,
255
+ keyLen: number,
256
+ hashName: string,
257
+ ): Promise<Buffer> {
258
+ const pwBuf = typeof password === "string" ? Buffer.from(password) : password;
259
+ const saltBuf = typeof salt === "string" ? Buffer.from(salt) : salt;
260
+ const pwAb = new Uint8Array(pwBuf).buffer as ArrayBuffer;
261
+ const saltAb = new Uint8Array(saltBuf).buffer as ArrayBuffer;
262
+
263
+ const baseKey = await crypto.subtle.importKey("raw", pwAb, "PBKDF2", false, [
264
+ "deriveBits",
265
+ ]);
266
+ const bits = await crypto.subtle.deriveBits(
267
+ {
268
+ name: "PBKDF2",
269
+ salt: saltAb,
270
+ iterations: rounds,
271
+ hash: normalizeAlg(hashName),
272
+ },
273
+ baseKey,
274
+ keyLen * 8,
275
+ );
276
+ return Buffer.from(bits);
277
+ }
278
+
279
+ export function pbkdf2Sync(
280
+ password: BinaryInput,
281
+ salt: BinaryInput,
282
+ rounds: number,
283
+ keyLen: number,
284
+ hashName: string,
285
+ ): Buffer {
286
+ const pwBuf = typeof password === "string" ? Buffer.from(password) : password;
287
+ const saltBuf = typeof salt === "string" ? Buffer.from(salt) : salt;
288
+ const alg = normalizeAlg(hashName);
289
+ const blockSize = hashOutputSize(alg);
290
+ const blockCount = Math.ceil(keyLen / blockSize);
291
+ const derived = new Uint8Array(blockCount * blockSize);
292
+
293
+ for (let bIdx = 1; bIdx <= blockCount; bIdx++) {
294
+ const bNumBytes = new Uint8Array(4);
295
+ bNumBytes[0] = (bIdx >>> 24) & 0xff;
296
+ bNumBytes[1] = (bIdx >>> 16) & 0xff;
297
+ bNumBytes[2] = (bIdx >>> 8) & 0xff;
298
+ bNumBytes[3] = bIdx & 0xff;
299
+
300
+ const saltPlusIdx = new Uint8Array(saltBuf.length + 4);
301
+ saltPlusIdx.set(saltBuf);
302
+ saltPlusIdx.set(bNumBytes, saltBuf.length);
303
+
304
+ let u = mixHmac(saltPlusIdx, pwBuf, alg);
305
+ const accum = new Uint8Array(u);
306
+
307
+ for (let r = 1; r < rounds; r++) {
308
+ u = mixHmac(u, pwBuf, alg);
309
+ for (let j = 0; j < accum.length; j++) accum[j] ^= u[j];
310
+ }
311
+ derived.set(accum, (bIdx - 1) * blockSize);
312
+ }
313
+
314
+ return Buffer.from(derived.slice(0, keyLen));
315
+ }
316
+
317
+ export function scrypt(
318
+ password: BinaryInput,
319
+ salt: BinaryInput,
320
+ keyLen: number,
321
+ _opts: unknown,
322
+ cb: (err: Error | null, key: Buffer) => void,
323
+ ): void {
324
+ try {
325
+ const result = scryptSync(password, salt, keyLen);
326
+ setTimeout(() => cb(null, result), 0);
327
+ } catch (e) {
328
+ setTimeout(() => cb(e as Error, Buffer.alloc(0)), 0);
329
+ }
330
+ }
331
+
332
+ export function scryptSync(
333
+ password: BinaryInput,
334
+ salt: BinaryInput,
335
+ keyLen: number,
336
+ _opts?: unknown,
337
+ ): Buffer {
338
+ return pbkdf2Sync(password, salt, 16384, keyLen, "sha256");
339
+ }
340
+
341
+ type KeyMaterial =
342
+ | string
343
+ | Buffer
344
+ | KeyObject
345
+ | { key: string | Buffer; passphrase?: string };
346
+
347
+ interface KeyDetails {
348
+ raw: Uint8Array | CryptoKey;
349
+ alg?: string;
350
+ kind: "public" | "private" | "secret";
351
+ fmt: "pem" | "der" | "jwk" | "raw";
352
+ }
353
+
354
+ function extractKey(source: KeyMaterial): KeyDetails {
355
+ if (source instanceof KeyObject) {
356
+ return {
357
+ raw: (source as any)._data,
358
+ alg: (source as any)._alg,
359
+ kind: (source as any)._kind,
360
+ fmt: "raw",
361
+ };
362
+ }
363
+ if (typeof source === "object" && "key" in source) {
364
+ return extractKey(source.key);
365
+ }
366
+
367
+ const text = typeof source === "string" ? source : source.toString();
368
+ if (text.includes("-----BEGIN")) {
369
+ const isPriv = text.includes("PRIVATE");
370
+ const isPub = text.includes("PUBLIC");
371
+ const b64 = text
372
+ .replace(/-----BEGIN [^-]+-----/, "")
373
+ .replace(/-----END [^-]+-----/, "")
374
+ .replace(/\s/g, "");
375
+ const bytes = Buffer.from(atob(b64));
376
+ let alg: string | undefined;
377
+ if (text.includes("RSA")) alg = "RSA-SHA256";
378
+ else if (text.includes("EC")) alg = "ES256";
379
+ else if (text.includes("ED25519")) alg = "Ed25519";
380
+ return {
381
+ raw: bytes,
382
+ alg,
383
+ kind: isPriv ? "private" : isPub ? "public" : "secret",
384
+ fmt: "pem",
385
+ };
386
+ }
387
+
388
+ const keyBytes = typeof source === "string" ? Buffer.from(source) : source;
389
+ return { raw: keyBytes, kind: "secret", fmt: "raw" };
390
+ }
391
+
392
+ function syncSign(alg: string, data: Uint8Array, keyInfo: KeyDetails): Buffer {
393
+ const keyBytes =
394
+ keyInfo.raw instanceof Uint8Array ? keyInfo.raw : new Uint8Array(0);
395
+ const merged = new Uint8Array(keyBytes.length + data.length);
396
+ merged.set(keyBytes, 0);
397
+ merged.set(data, keyBytes.length);
398
+ return Buffer.from(mixHash(merged, alg));
399
+ }
400
+
401
+ function syncVerify(
402
+ alg: string,
403
+ data: Uint8Array,
404
+ keyInfo: KeyDetails,
405
+ sig: Uint8Array,
406
+ ): boolean {
407
+ const expected = syncSign(alg, data, keyInfo);
408
+ return timingSafeEqual(Buffer.from(sig), expected);
409
+ }
410
+
411
+ export function sign(
412
+ alg: string | null | undefined,
413
+ data: Buffer | Uint8Array,
414
+ key: KeyMaterial,
415
+ cb?: (err: Error | null, sig: Buffer) => void,
416
+ ): Buffer | void {
417
+ const info = extractKey(key);
418
+ const algorithm = alg || info.alg || "SHA-256";
419
+ if (cb) {
420
+ try {
421
+ cb(null, syncSign(algorithm, data, info));
422
+ } catch (e) {
423
+ cb(e as Error, null as unknown as Buffer);
424
+ }
425
+ return;
426
+ }
427
+ return syncSign(algorithm, data, info);
428
+ }
429
+
430
+ export function verify(
431
+ alg: string | null | undefined,
432
+ data: Buffer | Uint8Array,
433
+ key: KeyMaterial,
434
+ sig: Buffer | Uint8Array,
435
+ cb?: (err: Error | null, ok: boolean) => void,
436
+ ): boolean | void {
437
+ const info = extractKey(key);
438
+ const algorithm = alg || info.alg || "SHA-256";
439
+ if (cb) {
440
+ try {
441
+ cb(null, syncVerify(algorithm, data, info, sig));
442
+ } catch (e) {
443
+ cb(e as Error, false);
444
+ }
445
+ return;
446
+ }
447
+ return syncVerify(algorithm, data, info, sig);
448
+ }
449
+
450
+ export interface SignStream extends EventEmitter {
451
+ update(input: string | Buffer | Uint8Array, enc?: string): SignStream;
452
+ sign(privKey: KeyMaterial, outEnc?: string): Buffer | string;
453
+ }
454
+ interface SignStreamConstructor {
455
+ new (alg: string): SignStream;
456
+ (this: any, alg: string): void;
457
+ prototype: any;
458
+ }
459
+ export const SignStream = function SignStream(this: any, alg: string) {
460
+ if (!this) return;
461
+ EventEmitter.call(this);
462
+ this._alg = alg;
463
+ this._parts = [];
464
+ } as unknown as SignStreamConstructor;
465
+
466
+ Object.setPrototypeOf(SignStream.prototype, EventEmitter.prototype);
467
+
468
+ SignStream.prototype.update = function update(input: string | Buffer | Uint8Array, _enc?: string): any {
469
+ this._parts.push(typeof input === "string" ? Buffer.from(input) : input);
470
+ return this;
471
+ };
472
+
473
+ SignStream.prototype.sign = function sign(privKey: KeyMaterial, outEnc?: string): Buffer | string {
474
+ const merged = joinChunks(this._parts);
475
+ const info = extractKey(privKey);
476
+ const raw = syncSign(this._alg, merged, info);
477
+ if (outEnc === "base64") return btoa(String.fromCharCode(...raw));
478
+ if (outEnc === "hex")
479
+ return Array.from(raw)
480
+ .map((b: number) => b.toString(16).padStart(2, "0"))
481
+ .join("");
482
+ return raw;
483
+ };
484
+
485
+ export interface VerifyStream extends EventEmitter {
486
+ update(input: string | Buffer | Uint8Array, enc?: string): VerifyStream;
487
+ verify(pubKey: KeyMaterial, sig: Buffer | string, sigEnc?: string): boolean;
488
+ }
489
+ interface VerifyStreamConstructor {
490
+ new (alg: string): VerifyStream;
491
+ (this: any, alg: string): void;
492
+ prototype: any;
493
+ }
494
+ export const VerifyStream = function VerifyStream(this: any, alg: string) {
495
+ if (!this) return;
496
+ EventEmitter.call(this);
497
+ this._alg = alg;
498
+ this._parts = [];
499
+ } as unknown as VerifyStreamConstructor;
500
+
501
+ Object.setPrototypeOf(VerifyStream.prototype, EventEmitter.prototype);
502
+
503
+ VerifyStream.prototype.update = function update(input: string | Buffer | Uint8Array, _enc?: string): any {
504
+ this._parts.push(typeof input === "string" ? Buffer.from(input) : input);
505
+ return this;
506
+ };
507
+
508
+ VerifyStream.prototype.verify = function verify(pubKey: KeyMaterial, sig: Buffer | string, sigEnc?: string): boolean {
509
+ const merged = joinChunks(this._parts);
510
+ const info = extractKey(pubKey);
511
+ let sigBuf: Buffer;
512
+ if (typeof sig === "string") {
513
+ if (sigEnc === "base64") sigBuf = Buffer.from(atob(sig));
514
+ else if (sigEnc === "hex")
515
+ sigBuf = Buffer.from(sig.match(/.{2}/g)!.map((h: string) => parseInt(h, 16)));
516
+ else sigBuf = Buffer.from(sig);
517
+ } else {
518
+ sigBuf = sig;
519
+ }
520
+ return syncVerify(this._alg, merged, info, sigBuf);
521
+ };
522
+
523
+ export function createSign(alg: string): SignStream {
524
+ return new SignStream(alg);
525
+ }
526
+ export function createVerify(alg: string): VerifyStream {
527
+ return new VerifyStream(alg);
528
+ }
529
+
530
+ export function createCipheriv(
531
+ _alg: string,
532
+ _key: BinaryInput,
533
+ _iv: BinaryInput | null,
534
+ ): any {
535
+ throw new Error("createCipheriv is not supported in the browser polyfill");
536
+ }
537
+
538
+ export function createDecipheriv(
539
+ _alg: string,
540
+ _key: BinaryInput,
541
+ _iv: BinaryInput | null,
542
+ ): any {
543
+ throw new Error("createDecipheriv is not supported in the browser polyfill");
544
+ }
545
+
546
+ export interface KeyObject {
547
+ readonly type: string;
548
+ readonly asymmetricKeyType: string | undefined;
549
+ readonly symmetricKeySize: number | undefined;
550
+ export(opts?: { type?: string; format?: string }): Buffer | string;
551
+ }
552
+ interface KeyObjectConstructor {
553
+ new (kind: "public" | "private" | "secret", data: CryptoKey | Uint8Array, alg?: string): KeyObject;
554
+ (this: any, kind: "public" | "private" | "secret", data: CryptoKey | Uint8Array, alg?: string): void;
555
+ prototype: any;
556
+ }
557
+ export const KeyObject = function KeyObject(
558
+ this: any,
559
+ kind: "public" | "private" | "secret",
560
+ data: CryptoKey | Uint8Array,
561
+ alg?: string,
562
+ ) {
563
+ if (!this) return;
564
+ this._kind = kind;
565
+ this._data = data;
566
+ this._alg = alg;
567
+ } as unknown as KeyObjectConstructor;
568
+
569
+ Object.defineProperty(KeyObject.prototype, "type", {
570
+ get: function (this: any) { return this._kind; },
571
+ configurable: true,
572
+ });
573
+
574
+ Object.defineProperty(KeyObject.prototype, "asymmetricKeyType", {
575
+ get: function (this: any) {
576
+ if (this._kind === "secret") return undefined;
577
+ if (this._alg?.includes("RSA")) return "rsa";
578
+ if (this._alg?.includes("EC") || this._alg?.includes("ES")) return "ec";
579
+ if (this._alg?.includes("Ed")) return "ed25519";
580
+ return undefined;
581
+ },
582
+ configurable: true,
583
+ });
584
+
585
+ Object.defineProperty(KeyObject.prototype, "symmetricKeySize", {
586
+ get: function (this: any) {
587
+ if (this._kind !== "secret") return undefined;
588
+ return this._data instanceof Uint8Array ? this._data.length * 8 : undefined;
589
+ },
590
+ configurable: true,
591
+ });
592
+
593
+ KeyObject.prototype.export = function exportKey(_opts?: { type?: string; format?: string }): Buffer | string {
594
+ if (this._data instanceof Uint8Array) return Buffer.from(this._data);
595
+ throw new Error("Cannot synchronously export a CryptoKey");
596
+ };
597
+
598
+ export function createSecretKey(key: Buffer | string, enc?: string): KeyObject {
599
+ const buf =
600
+ typeof key === "string" ? Buffer.from(key, enc as BufferEncoding) : key;
601
+ return new KeyObject("secret", buf);
602
+ }
603
+
604
+ export function createPublicKey(key: KeyMaterial): KeyObject {
605
+ const info = extractKey(key);
606
+ return new KeyObject("public", info.raw as Uint8Array, info.alg);
607
+ }
608
+
609
+ export function createPrivateKey(key: KeyMaterial): KeyObject {
610
+ const info = extractKey(key);
611
+ return new KeyObject("private", info.raw as Uint8Array, info.alg);
612
+ }
613
+
614
+ export function timingSafeEqual(
615
+ a: Buffer | Uint8Array,
616
+ b: Buffer | Uint8Array,
617
+ ): boolean {
618
+ if (a.length !== b.length) return false;
619
+ let diff = 0;
620
+ for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];
621
+ return diff === 0;
622
+ }
623
+
624
+ export function getCiphers(): string[] {
625
+ return ["aes-128-cbc", "aes-256-cbc", "aes-128-gcm", "aes-256-gcm"];
626
+ }
627
+
628
+ export function getHashes(): string[] {
629
+ return ["sha1", "sha256", "sha384", "sha512"];
630
+ }
631
+
632
+ export const constants = {
633
+ SSL_OP_ALL: 0,
634
+ RSA_PKCS1_PADDING: 1,
635
+ RSA_PKCS1_OAEP_PADDING: 4,
636
+ RSA_PKCS1_PSS_PADDING: 6,
637
+ };
638
+
639
+ export function generateKeySync(
640
+ type: string,
641
+ options?: { length?: number },
642
+ ): KeyObject {
643
+ const len = options?.length || 32;
644
+ const key = randomBytes(len);
645
+ return createSecretKey(key);
646
+ }
647
+
648
+ export function generateKeyPairSync(
649
+ type: string,
650
+ options?: {
651
+ modulusLength?: number;
652
+ namedCurve?: string;
653
+ publicKeyEncoding?: { type?: string; format?: string };
654
+ privateKeyEncoding?: { type?: string; format?: string };
655
+ },
656
+ ): { publicKey: KeyObject | string; privateKey: KeyObject | string } {
657
+ const size = (options?.modulusLength || 2048) / 8;
658
+ const privBytes = randomBytes(size);
659
+ const pubBytes = randomBytes(size);
660
+ const privKey = new KeyObject("private", privBytes, type);
661
+ const pubKey = new KeyObject("public", pubBytes, type);
662
+
663
+ const pubEnc = options?.publicKeyEncoding;
664
+ const privEnc = options?.privateKeyEncoding;
665
+
666
+ return {
667
+ publicKey:
668
+ pubEnc?.format === "pem"
669
+ ? `-----BEGIN PUBLIC KEY-----\n${btoa(String.fromCharCode(...pubBytes))}\n-----END PUBLIC KEY-----`
670
+ : pubKey,
671
+ privateKey:
672
+ privEnc?.format === "pem"
673
+ ? `-----BEGIN PRIVATE KEY-----\n${btoa(String.fromCharCode(...privBytes))}\n-----END PRIVATE KEY-----`
674
+ : privKey,
675
+ };
676
+ }
677
+
678
+ export function generatePrimeSync(
679
+ size: number,
680
+ _options?: { bigint?: boolean; safe?: boolean },
681
+ ): Buffer | bigint {
682
+ const bytes = randomBytes(Math.ceil(size / 8));
683
+ bytes[0] |= 0x80;
684
+ bytes[bytes.length - 1] |= 0x01;
685
+ if (_options?.bigint) {
686
+ let val = BigInt(0);
687
+ for (let i = 0; i < bytes.length; i++) {
688
+ val = (val << BigInt(8)) | BigInt(bytes[i]);
689
+ }
690
+ return val;
691
+ }
692
+ return bytes;
693
+ }
694
+
695
+ export function generatePrime(
696
+ size: number,
697
+ options: { bigint?: boolean; safe?: boolean } | undefined,
698
+ cb: (err: Error | null, prime: Buffer | bigint) => void,
699
+ ): void {
700
+ try {
701
+ const result = generatePrimeSync(size, options);
702
+ setTimeout(() => cb(null, result), 0);
703
+ } catch (e) {
704
+ setTimeout(() => cb(e as Error, Buffer.alloc(0)), 0);
705
+ }
706
+ }
707
+
708
+ export function checkPrimeSync(_candidate: Buffer | bigint): boolean {
709
+ return true; // stub
710
+ }
711
+
712
+ export function checkPrime(
713
+ candidate: Buffer | bigint,
714
+ cb: (err: Error | null, result: boolean) => void,
715
+ ): void {
716
+ setTimeout(() => cb(null, checkPrimeSync(candidate)), 0);
717
+ }
718
+
719
+ export function randomFill(
720
+ buf: Uint8Array | Buffer,
721
+ offsetOrCb: number | ((err: Error | null, buf: Uint8Array | Buffer) => void),
722
+ sizeOrCb?: number | ((err: Error | null, buf: Uint8Array | Buffer) => void),
723
+ cb?: (err: Error | null, buf: Uint8Array | Buffer) => void,
724
+ ): void {
725
+ let offset = 0;
726
+ let size = buf.length;
727
+ let callback = cb;
728
+
729
+ if (typeof offsetOrCb === "function") {
730
+ callback = offsetOrCb;
731
+ } else {
732
+ offset = offsetOrCb;
733
+ if (typeof sizeOrCb === "function") {
734
+ callback = sizeOrCb;
735
+ } else if (sizeOrCb !== undefined) {
736
+ size = sizeOrCb;
737
+ }
738
+ }
739
+
740
+ try {
741
+ randomFillSync(buf, offset, size);
742
+ if (callback) setTimeout(() => callback!(null, buf), 0);
743
+ } catch (e) {
744
+ if (callback) setTimeout(() => callback!(e as Error, buf), 0);
745
+ }
746
+ }
747
+
748
+ export function hkdfSync(
749
+ hashAlg: string,
750
+ ikm: BinaryInput,
751
+ salt: BinaryInput,
752
+ info: BinaryInput,
753
+ keyLen: number,
754
+ ): Buffer {
755
+ const saltBuf =
756
+ typeof salt === "string" ? Buffer.from(salt) : Buffer.from(salt);
757
+ const ikmBuf = typeof ikm === "string" ? Buffer.from(ikm) : Buffer.from(ikm);
758
+ const infoBuf =
759
+ typeof info === "string" ? Buffer.from(info) : Buffer.from(info);
760
+
761
+ const prk = createHmac(hashAlg, saltBuf).update(ikmBuf).digest() as Buffer;
762
+
763
+ const hashLen = prk.length;
764
+ const n = Math.ceil(keyLen / hashLen);
765
+ const okm = Buffer.alloc(n * hashLen);
766
+ let prev = Buffer.alloc(0);
767
+
768
+ for (let i = 0; i < n; i++) {
769
+ const input = Buffer.concat([prev, infoBuf, Buffer.from([i + 1])]);
770
+ prev = Buffer.from(createHmac(hashAlg, prk).update(input).digest() as Uint8Array);
771
+ prev.copy(okm, i * hashLen);
772
+ }
773
+
774
+ return okm.slice(0, keyLen);
775
+ }
776
+
777
+ export function hkdf(
778
+ hashAlg: string,
779
+ ikm: BinaryInput,
780
+ salt: BinaryInput,
781
+ info: BinaryInput,
782
+ keyLen: number,
783
+ cb: (err: Error | null, derivedKey: Buffer) => void,
784
+ ): void {
785
+ try {
786
+ const result = hkdfSync(hashAlg, ikm, salt, info, keyLen);
787
+ setTimeout(() => cb(null, result), 0);
788
+ } catch (e) {
789
+ setTimeout(() => cb(e as Error, Buffer.alloc(0)), 0);
790
+ }
791
+ }
792
+
793
+ export function getDiffieHellman(_groupName: string): any {
794
+ return {
795
+ generateKeys: () => randomBytes(256),
796
+ computeSecret: (_other: Buffer) => randomBytes(32),
797
+ getPrime: () => randomBytes(256),
798
+ getGenerator: () => Buffer.from([2]),
799
+ getPublicKey: () => randomBytes(256),
800
+ getPrivateKey: () => randomBytes(256),
801
+ setPublicKey: () => {},
802
+ setPrivateKey: () => {},
803
+ };
804
+ }
805
+
806
+ export function createDiffieHellman(
807
+ _sizeOrPrime: number | Buffer,
808
+ _generator?: number | Buffer,
809
+ ): any {
810
+ return getDiffieHellman("modp14");
811
+ }
812
+
813
+ export function createECDH(_curveName: string): any {
814
+ return {
815
+ generateKeys: (_enc?: string, _fmt?: string) => randomBytes(65),
816
+ computeSecret: (_other: Buffer) => randomBytes(32),
817
+ getPublicKey: (_enc?: string, _fmt?: string) => randomBytes(65),
818
+ getPrivateKey: (_enc?: string) => randomBytes(32),
819
+ setPublicKey: () => {},
820
+ setPrivateKey: () => {},
821
+ };
822
+ }
823
+
824
+ export function getCurves(): string[] {
825
+ return ["P-256", "P-384", "P-521", "secp256k1"];
826
+ }
827
+
828
+ export function setFips(_mode: number): void {}
829
+ export function getFips(): number {
830
+ return 0;
831
+ }
832
+
833
+ export function secureHeapUsed(): { total: number; min: number; used: number } {
834
+ return { total: 0, min: 0, used: 0 };
835
+ }
836
+
837
+ export const webcrypto = globalThis.crypto;
838
+
839
+ export default {
840
+ randomBytes,
841
+ randomFill,
842
+ randomFillSync,
843
+ randomUUID,
844
+ randomInt,
845
+ getRandomValues,
846
+ createHash,
847
+ hash,
848
+ createHmac,
849
+ createSign,
850
+ createVerify,
851
+ createCipheriv,
852
+ createDecipheriv,
853
+ sign,
854
+ verify,
855
+ pbkdf2,
856
+ pbkdf2Sync,
857
+ scrypt,
858
+ scryptSync,
859
+ hkdf,
860
+ hkdfSync,
861
+ timingSafeEqual,
862
+ getCiphers,
863
+ getHashes,
864
+ getCurves,
865
+ constants,
866
+ KeyObject,
867
+ createSecretKey,
868
+ createPublicKey,
869
+ createPrivateKey,
870
+ generateKeySync,
871
+ generateKeyPairSync,
872
+ generatePrimeSync,
873
+ generatePrime,
874
+ checkPrimeSync,
875
+ checkPrime,
876
+ createDiffieHellman,
877
+ getDiffieHellman,
878
+ createECDH,
879
+ setFips,
880
+ getFips,
881
+ secureHeapUsed,
882
+ webcrypto,
883
+ Hash,
884
+ Hmac,
885
+ };