@ricsam/quickjs-test-utils 1.0.16 → 1.0.18

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.
package/README.md CHANGED
@@ -73,7 +73,8 @@ import {
73
73
  CORE_TYPES, // ReadableStream, Blob, File, URL, etc.
74
74
  FETCH_TYPES, // fetch, Request, Response, serve, etc.
75
75
  FS_TYPES, // fs.getDirectory, FileSystemHandle, etc.
76
- TYPE_DEFINITIONS // All types as { core, fetch, fs }
76
+ CRYPTO_TYPES, // crypto.subtle, CryptoKey, etc.
77
+ TYPE_DEFINITIONS // All types as { core, fetch, fs, crypto, ... }
77
78
  } from "@ricsam/quickjs-test-utils";
78
79
 
79
80
  // Use with your own ts-morph project
@@ -93,7 +94,8 @@ Each package also exports `.d.ts` files for use with `tsconfig.json`:
93
94
  "references": [
94
95
  { "path": "./node_modules/@ricsam/quickjs-core/src/quickjs.d.ts" },
95
96
  { "path": "./node_modules/@ricsam/quickjs-fetch/src/quickjs.d.ts" },
96
- { "path": "./node_modules/@ricsam/quickjs-fs/src/quickjs.d.ts" }
97
+ { "path": "./node_modules/@ricsam/quickjs-fs/src/quickjs.d.ts" },
98
+ { "path": "./node_modules/@ricsam/quickjs-crypto/src/quickjs.d.ts" }
97
99
  ]
98
100
  }
99
101
  ```
@@ -36,6 +36,7 @@ module.exports = __toCommonJS(exports_integration_server);
36
36
  var import_quickjs_emscripten = require("quickjs-emscripten");
37
37
  var import_quickjs_fetch = require("@ricsam/quickjs-fetch");
38
38
  var import_quickjs_core = require("@ricsam/quickjs-core");
39
+ var import_quickjs_console = require("@ricsam/quickjs-console");
39
40
  async function startIntegrationServer(quickJSCode, options) {
40
41
  const QuickJS = await import_quickjs_emscripten.getQuickJS();
41
42
  const runtime = QuickJS.newRuntime();
@@ -45,6 +46,7 @@ async function startIntegrationServer(quickJSCode, options) {
45
46
  coreHandle,
46
47
  onFetch: options?.onFetch
47
48
  });
49
+ const consoleHandle = options?.consoleHandlers ? import_quickjs_console.setupConsole(context, { handlers: options.consoleHandlers, coreHandle }) : undefined;
48
50
  const wsConnections = new Map;
49
51
  fetchHandle.onWebSocketCommand((cmd) => {
50
52
  const ws = wsConnections.get(cmd.connectionId);
@@ -118,6 +120,7 @@ async function startIntegrationServer(quickJSCode, options) {
118
120
  context,
119
121
  runtime,
120
122
  coreHandle,
123
+ consoleHandle,
121
124
  async stop() {
122
125
  for (const ws of wsConnections.values()) {
123
126
  ws.close(1000, "Server stopping");
@@ -125,6 +128,7 @@ async function startIntegrationServer(quickJSCode, options) {
125
128
  wsConnections.clear();
126
129
  server.stop(true);
127
130
  fetchHandle.dispose();
131
+ consoleHandle?.dispose();
128
132
  coreHandle.dispose();
129
133
  context.dispose();
130
134
  runtime.dispose();
@@ -133,4 +137,4 @@ async function startIntegrationServer(quickJSCode, options) {
133
137
  }
134
138
  })
135
139
 
136
- //# debugId=C6A40A02405DC16F64756E2164756E21
140
+ //# debugId=815B5672C4B716AE64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/integration-server.ts"],
4
4
  "sourcesContent": [
5
- "import { getQuickJS, type QuickJSContext, type QuickJSRuntime } from \"quickjs-emscripten\";\nimport { setupFetch, type FetchHandle, type WebSocketCommand, type SetupFetchOptions } from \"@ricsam/quickjs-fetch\";\nimport { setupCore, type CoreHandle } from \"@ricsam/quickjs-core\";\nimport type { Server, ServerWebSocket } from \"bun\";\n\ninterface WsData {\n connectionId: string;\n}\n\nexport interface IntegrationTestServer {\n baseURL: string;\n wsURL: string;\n port: number;\n fetchHandle: FetchHandle;\n context: QuickJSContext;\n runtime: QuickJSRuntime;\n coreHandle: CoreHandle;\n stop(): Promise<void>;\n}\n\nexport interface StartIntegrationServerOptions {\n /** Handler for outbound fetch() calls from QuickJS */\n onFetch?: SetupFetchOptions[\"onFetch\"];\n}\n\n/**\n * Start a real HTTP server that dispatches requests to a QuickJS serve() handler.\n *\n * @param quickJSCode - JavaScript code to run in QuickJS, should call serve()\n * @param options - Optional configuration\n * @returns Server info including baseURL, wsURL, and stop function\n *\n * @example\n * const server = await startIntegrationServer(`\n * serve({\n * fetch(request) {\n * return new Response(\"Hello!\");\n * }\n * });\n * `);\n *\n * const response = await fetch(\\`\\${server.baseURL}/test\\`);\n * expect(await response.text()).toBe(\"Hello!\");\n *\n * await server.stop();\n */\nexport async function startIntegrationServer(\n quickJSCode: string,\n options?: StartIntegrationServerOptions\n): Promise<IntegrationTestServer> {\n const QuickJS = await getQuickJS();\n const runtime = QuickJS.newRuntime();\n const context = runtime.newContext();\n\n // Setup core and fetch APIs\n const coreHandle = setupCore(context);\n const fetchHandle = setupFetch(context, {\n coreHandle,\n onFetch: options?.onFetch,\n });\n\n // Track WebSocket connections\n const wsConnections = new Map<string, ServerWebSocket<WsData>>();\n\n // Handle outgoing WebSocket commands from QuickJS\n fetchHandle.onWebSocketCommand((cmd: WebSocketCommand) => {\n const ws = wsConnections.get(cmd.connectionId);\n if (!ws) return;\n\n if (cmd.type === \"message\") {\n ws.send(cmd.data);\n } else if (cmd.type === \"close\") {\n ws.close(cmd.code, cmd.reason);\n }\n });\n\n // Run the user's QuickJS code\n const result = context.evalCode(quickJSCode);\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n fetchHandle.dispose();\n coreHandle.dispose();\n context.dispose();\n runtime.dispose();\n throw new Error(`Failed to evaluate QuickJS code: ${JSON.stringify(error)}`);\n }\n result.value.dispose();\n\n // Start Bun server with port 0 for dynamic assignment\n const server: Server<WsData> = Bun.serve<WsData>({\n port: 0,\n async fetch(req, server) {\n try {\n // Dispatch to QuickJS handler\n const response = await fetchHandle.dispatchRequest(req);\n\n // Check if QuickJS requested a WebSocket upgrade\n const upgrade = fetchHandle.getUpgradeRequest();\n if (upgrade?.requested) {\n // The connectionId is generated by QuickJS in server.upgrade()\n // User data is stored in QuickJS registry - we just pass the connectionId\n const success = server.upgrade(req, {\n data: { connectionId: upgrade.connectionId },\n });\n if (success) {\n return undefined;\n }\n return new Response(\"WebSocket upgrade failed\", { status: 500 });\n }\n\n return response;\n } catch (error) {\n console.error(\"Integration test request failed:\", error);\n return new Response(\"Internal Server Error\", { status: 500 });\n }\n },\n websocket: {\n open(ws) {\n const { connectionId } = ws.data;\n wsConnections.set(connectionId, ws);\n // User data is looked up from QuickJS registry using connectionId\n fetchHandle.dispatchWebSocketOpen(connectionId);\n },\n message(ws, message) {\n const msg = typeof message === \"string\" ? message : message.buffer;\n fetchHandle.dispatchWebSocketMessage(ws.data.connectionId, msg as string | ArrayBuffer);\n },\n close(ws, code, reason) {\n fetchHandle.dispatchWebSocketClose(ws.data.connectionId, code, reason);\n wsConnections.delete(ws.data.connectionId);\n },\n },\n });\n\n const port = server.port;\n if (port === undefined) {\n throw new Error(\"Server failed to get port\");\n }\n const baseURL = `http://localhost:${port}`;\n const wsURL = `ws://localhost:${port}`;\n\n return {\n baseURL,\n wsURL,\n port,\n fetchHandle,\n context,\n runtime,\n coreHandle,\n async stop() {\n // Close all WebSocket connections\n for (const ws of wsConnections.values()) {\n ws.close(1000, \"Server stopping\");\n }\n wsConnections.clear();\n\n // Stop the server\n server.stop(true);\n\n // Dispose QuickJS resources\n fetchHandle.dispose();\n coreHandle.dispose();\n context.dispose();\n runtime.dispose();\n },\n };\n}\n"
5
+ "import { getQuickJS, type QuickJSContext, type QuickJSRuntime } from \"quickjs-emscripten\";\nimport { setupFetch, type FetchHandle, type WebSocketCommand, type SetupFetchOptions } from \"@ricsam/quickjs-fetch\";\nimport { setupCore, type CoreHandle } from \"@ricsam/quickjs-core\";\nimport type { Server, ServerWebSocket } from \"bun\";\nimport { setupConsole, type ConsoleOutputHandler, type ConsoleHandle } from \"@ricsam/quickjs-console\";\n\ninterface WsData {\n connectionId: string;\n}\n\nexport interface IntegrationTestServer {\n baseURL: string;\n wsURL: string;\n port: number;\n fetchHandle: FetchHandle;\n context: QuickJSContext;\n runtime: QuickJSRuntime;\n coreHandle: CoreHandle;\n consoleHandle?: ConsoleHandle;\n stop(): Promise<void>;\n}\n\nexport interface StartIntegrationServerOptions {\n /** Handler for outbound fetch() calls from QuickJS */\n onFetch?: SetupFetchOptions[\"onFetch\"];\n /** Handlers for console output from QuickJS */\n consoleHandlers?: ConsoleOutputHandler;\n}\n\n/**\n * Start a real HTTP server that dispatches requests to a QuickJS serve() handler.\n *\n * @param quickJSCode - JavaScript code to run in QuickJS, should call serve()\n * @param options - Optional configuration\n * @returns Server info including baseURL, wsURL, and stop function\n *\n * @example\n * const server = await startIntegrationServer(`\n * serve({\n * fetch(request) {\n * return new Response(\"Hello!\");\n * }\n * });\n * `);\n *\n * const response = await fetch(\\`\\${server.baseURL}/test\\`);\n * expect(await response.text()).toBe(\"Hello!\");\n *\n * await server.stop();\n */\nexport async function startIntegrationServer(\n quickJSCode: string,\n options?: StartIntegrationServerOptions\n): Promise<IntegrationTestServer> {\n const QuickJS = await getQuickJS();\n const runtime = QuickJS.newRuntime();\n const context = runtime.newContext();\n\n // Setup core and fetch APIs\n const coreHandle = setupCore(context);\n const fetchHandle = setupFetch(context, {\n coreHandle,\n onFetch: options?.onFetch,\n });\n\n // Setup console if handlers provided\n const consoleHandle = options?.consoleHandlers\n ? setupConsole(context, { handlers: options.consoleHandlers, coreHandle })\n : undefined;\n\n // Track WebSocket connections\n const wsConnections = new Map<string, ServerWebSocket<WsData>>();\n\n // Handle outgoing WebSocket commands from QuickJS\n fetchHandle.onWebSocketCommand((cmd: WebSocketCommand) => {\n const ws = wsConnections.get(cmd.connectionId);\n if (!ws) return;\n\n if (cmd.type === \"message\") {\n ws.send(cmd.data);\n } else if (cmd.type === \"close\") {\n ws.close(cmd.code, cmd.reason);\n }\n });\n\n // Run the user's QuickJS code\n const result = context.evalCode(quickJSCode);\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n fetchHandle.dispose();\n coreHandle.dispose();\n context.dispose();\n runtime.dispose();\n throw new Error(`Failed to evaluate QuickJS code: ${JSON.stringify(error)}`);\n }\n result.value.dispose();\n\n // Start Bun server with port 0 for dynamic assignment\n const server: Server<WsData> = Bun.serve<WsData>({\n port: 0,\n async fetch(req, server) {\n try {\n // Dispatch to QuickJS handler\n const response = await fetchHandle.dispatchRequest(req);\n\n // Check if QuickJS requested a WebSocket upgrade\n const upgrade = fetchHandle.getUpgradeRequest();\n if (upgrade?.requested) {\n // The connectionId is generated by QuickJS in server.upgrade()\n // User data is stored in QuickJS registry - we just pass the connectionId\n const success = server.upgrade(req, {\n data: { connectionId: upgrade.connectionId },\n });\n if (success) {\n return undefined;\n }\n return new Response(\"WebSocket upgrade failed\", { status: 500 });\n }\n\n return response;\n } catch (error) {\n console.error(\"Integration test request failed:\", error);\n return new Response(\"Internal Server Error\", { status: 500 });\n }\n },\n websocket: {\n open(ws) {\n const { connectionId } = ws.data;\n wsConnections.set(connectionId, ws);\n // User data is looked up from QuickJS registry using connectionId\n fetchHandle.dispatchWebSocketOpen(connectionId);\n },\n message(ws, message) {\n const msg = typeof message === \"string\" ? message : message.buffer;\n fetchHandle.dispatchWebSocketMessage(ws.data.connectionId, msg as string | ArrayBuffer);\n },\n close(ws, code, reason) {\n fetchHandle.dispatchWebSocketClose(ws.data.connectionId, code, reason);\n wsConnections.delete(ws.data.connectionId);\n },\n },\n });\n\n const port = server.port;\n if (port === undefined) {\n throw new Error(\"Server failed to get port\");\n }\n const baseURL = `http://localhost:${port}`;\n const wsURL = `ws://localhost:${port}`;\n\n return {\n baseURL,\n wsURL,\n port,\n fetchHandle,\n context,\n runtime,\n coreHandle,\n consoleHandle,\n async stop() {\n // Close all WebSocket connections\n for (const ws of wsConnections.values()) {\n ws.close(1000, \"Server stopping\");\n }\n wsConnections.clear();\n\n // Stop the server\n server.stop(true);\n\n // Dispose QuickJS resources\n fetchHandle.dispose();\n consoleHandle?.dispose();\n coreHandle.dispose();\n context.dispose();\n runtime.dispose();\n },\n };\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "C6A40A02405DC16F64756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "815B5672C4B716AE64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/quickjs-test-utils",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "type": "commonjs"
5
5
  }
@@ -36,6 +36,7 @@ __export(exports_quickjs_types, {
36
36
  FS_TYPES: () => FS_TYPES,
37
37
  FETCH_TYPES: () => FETCH_TYPES,
38
38
  ENCODING_TYPES: () => ENCODING_TYPES,
39
+ CRYPTO_TYPES: () => CRYPTO_TYPES,
39
40
  CORE_TYPES: () => CORE_TYPES,
40
41
  CONSOLE_TYPES: () => CONSOLE_TYPES
41
42
  });
@@ -1168,6 +1169,294 @@ declare global {
1168
1169
  function btoa(stringToEncode: string): string;
1169
1170
  }
1170
1171
  `;
1172
+ var CRYPTO_TYPES = `/**
1173
+ * QuickJS Global Type Definitions for @ricsam/quickjs-crypto
1174
+ *
1175
+ * These types define the globals injected by setupCrypto() into a QuickJS context.
1176
+ * Use these types to typecheck user code that will run inside QuickJS.
1177
+ *
1178
+ * @example
1179
+ * // Generate random bytes
1180
+ * const arr = new Uint8Array(16);
1181
+ * crypto.getRandomValues(arr);
1182
+ *
1183
+ * // Generate UUID
1184
+ * const uuid = crypto.randomUUID();
1185
+ *
1186
+ * // Use SubtleCrypto
1187
+ * const key = await crypto.subtle.generateKey(
1188
+ * { name: "AES-GCM", length: 256 },
1189
+ * true,
1190
+ * ["encrypt", "decrypt"]
1191
+ * );
1192
+ */
1193
+
1194
+ export {};
1195
+
1196
+ declare global {
1197
+ /**
1198
+ * CryptoKey represents a cryptographic key.
1199
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey
1200
+ */
1201
+ interface CryptoKey {
1202
+ /**
1203
+ * The type of key: "public", "private", or "secret".
1204
+ */
1205
+ readonly type: "public" | "private" | "secret";
1206
+
1207
+ /**
1208
+ * Whether the key can be exported.
1209
+ */
1210
+ readonly extractable: boolean;
1211
+
1212
+ /**
1213
+ * The algorithm used by this key.
1214
+ */
1215
+ readonly algorithm: KeyAlgorithm;
1216
+
1217
+ /**
1218
+ * The usages allowed for this key.
1219
+ */
1220
+ readonly usages: ReadonlyArray<KeyUsage>;
1221
+ }
1222
+
1223
+ /**
1224
+ * CryptoKey constructor (keys cannot be constructed directly).
1225
+ */
1226
+ const CryptoKey: {
1227
+ prototype: CryptoKey;
1228
+ };
1229
+
1230
+ /**
1231
+ * SubtleCrypto interface for cryptographic operations.
1232
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
1233
+ */
1234
+ interface SubtleCrypto {
1235
+ /**
1236
+ * Generate a digest (hash) of the given data.
1237
+ *
1238
+ * @param algorithm - Hash algorithm (e.g., "SHA-256", "SHA-384", "SHA-512")
1239
+ * @param data - Data to hash
1240
+ * @returns Promise resolving to the hash as ArrayBuffer
1241
+ */
1242
+ digest(
1243
+ algorithm: AlgorithmIdentifier,
1244
+ data: BufferSource
1245
+ ): Promise<ArrayBuffer>;
1246
+
1247
+ /**
1248
+ * Generate a new cryptographic key or key pair.
1249
+ *
1250
+ * @param algorithm - Key generation algorithm
1251
+ * @param extractable - Whether the key can be exported
1252
+ * @param keyUsages - Allowed key usages
1253
+ * @returns Promise resolving to a CryptoKey or CryptoKeyPair
1254
+ */
1255
+ generateKey(
1256
+ algorithm: RsaHashedKeyGenParams | EcKeyGenParams | AesKeyGenParams | HmacKeyGenParams,
1257
+ extractable: boolean,
1258
+ keyUsages: KeyUsage[]
1259
+ ): Promise<CryptoKey | CryptoKeyPair>;
1260
+
1261
+ /**
1262
+ * Sign data using a private key.
1263
+ *
1264
+ * @param algorithm - Signing algorithm
1265
+ * @param key - Private key to sign with
1266
+ * @param data - Data to sign
1267
+ * @returns Promise resolving to the signature as ArrayBuffer
1268
+ */
1269
+ sign(
1270
+ algorithm: AlgorithmIdentifier,
1271
+ key: CryptoKey,
1272
+ data: BufferSource
1273
+ ): Promise<ArrayBuffer>;
1274
+
1275
+ /**
1276
+ * Verify a signature.
1277
+ *
1278
+ * @param algorithm - Signing algorithm
1279
+ * @param key - Public key to verify with
1280
+ * @param signature - Signature to verify
1281
+ * @param data - Data that was signed
1282
+ * @returns Promise resolving to true if valid, false otherwise
1283
+ */
1284
+ verify(
1285
+ algorithm: AlgorithmIdentifier,
1286
+ key: CryptoKey,
1287
+ signature: BufferSource,
1288
+ data: BufferSource
1289
+ ): Promise<boolean>;
1290
+
1291
+ /**
1292
+ * Encrypt data.
1293
+ *
1294
+ * @param algorithm - Encryption algorithm
1295
+ * @param key - Encryption key
1296
+ * @param data - Data to encrypt
1297
+ * @returns Promise resolving to encrypted data as ArrayBuffer
1298
+ */
1299
+ encrypt(
1300
+ algorithm: AlgorithmIdentifier,
1301
+ key: CryptoKey,
1302
+ data: BufferSource
1303
+ ): Promise<ArrayBuffer>;
1304
+
1305
+ /**
1306
+ * Decrypt data.
1307
+ *
1308
+ * @param algorithm - Decryption algorithm
1309
+ * @param key - Decryption key
1310
+ * @param data - Data to decrypt
1311
+ * @returns Promise resolving to decrypted data as ArrayBuffer
1312
+ */
1313
+ decrypt(
1314
+ algorithm: AlgorithmIdentifier,
1315
+ key: CryptoKey,
1316
+ data: BufferSource
1317
+ ): Promise<ArrayBuffer>;
1318
+
1319
+ /**
1320
+ * Import a key from external data.
1321
+ *
1322
+ * @param format - Key format ("raw", "pkcs8", "spki", "jwk")
1323
+ * @param keyData - Key data
1324
+ * @param algorithm - Key algorithm
1325
+ * @param extractable - Whether the key can be exported
1326
+ * @param keyUsages - Allowed key usages
1327
+ * @returns Promise resolving to a CryptoKey
1328
+ */
1329
+ importKey(
1330
+ format: "raw" | "pkcs8" | "spki" | "jwk",
1331
+ keyData: BufferSource | JsonWebKey,
1332
+ algorithm: AlgorithmIdentifier,
1333
+ extractable: boolean,
1334
+ keyUsages: KeyUsage[]
1335
+ ): Promise<CryptoKey>;
1336
+
1337
+ /**
1338
+ * Export a key.
1339
+ *
1340
+ * @param format - Export format ("raw", "pkcs8", "spki", "jwk")
1341
+ * @param key - Key to export
1342
+ * @returns Promise resolving to ArrayBuffer or JsonWebKey
1343
+ */
1344
+ exportKey(
1345
+ format: "raw" | "pkcs8" | "spki" | "jwk",
1346
+ key: CryptoKey
1347
+ ): Promise<ArrayBuffer | JsonWebKey>;
1348
+
1349
+ /**
1350
+ * Derive bits from a key.
1351
+ *
1352
+ * @param algorithm - Derivation algorithm
1353
+ * @param baseKey - Base key for derivation
1354
+ * @param length - Number of bits to derive
1355
+ * @returns Promise resolving to derived bits as ArrayBuffer
1356
+ */
1357
+ deriveBits(
1358
+ algorithm: AlgorithmIdentifier,
1359
+ baseKey: CryptoKey,
1360
+ length: number
1361
+ ): Promise<ArrayBuffer>;
1362
+
1363
+ /**
1364
+ * Derive a new key from a base key.
1365
+ *
1366
+ * @param algorithm - Derivation algorithm
1367
+ * @param baseKey - Base key for derivation
1368
+ * @param derivedKeyType - Type of key to derive
1369
+ * @param extractable - Whether the derived key can be exported
1370
+ * @param keyUsages - Allowed usages for derived key
1371
+ * @returns Promise resolving to a CryptoKey
1372
+ */
1373
+ deriveKey(
1374
+ algorithm: AlgorithmIdentifier,
1375
+ baseKey: CryptoKey,
1376
+ derivedKeyType: AlgorithmIdentifier,
1377
+ extractable: boolean,
1378
+ keyUsages: KeyUsage[]
1379
+ ): Promise<CryptoKey>;
1380
+
1381
+ /**
1382
+ * Wrap a key for secure export.
1383
+ *
1384
+ * @param format - Key format
1385
+ * @param key - Key to wrap
1386
+ * @param wrappingKey - Key to wrap with
1387
+ * @param wrapAlgorithm - Wrapping algorithm
1388
+ * @returns Promise resolving to wrapped key as ArrayBuffer
1389
+ */
1390
+ wrapKey(
1391
+ format: "raw" | "pkcs8" | "spki" | "jwk",
1392
+ key: CryptoKey,
1393
+ wrappingKey: CryptoKey,
1394
+ wrapAlgorithm: AlgorithmIdentifier
1395
+ ): Promise<ArrayBuffer>;
1396
+
1397
+ /**
1398
+ * Unwrap a wrapped key.
1399
+ *
1400
+ * @param format - Key format
1401
+ * @param wrappedKey - Wrapped key data
1402
+ * @param unwrappingKey - Key to unwrap with
1403
+ * @param unwrapAlgorithm - Unwrapping algorithm
1404
+ * @param unwrappedKeyAlgorithm - Algorithm for the unwrapped key
1405
+ * @param extractable - Whether the unwrapped key can be exported
1406
+ * @param keyUsages - Allowed usages for unwrapped key
1407
+ * @returns Promise resolving to a CryptoKey
1408
+ */
1409
+ unwrapKey(
1410
+ format: "raw" | "pkcs8" | "spki" | "jwk",
1411
+ wrappedKey: BufferSource,
1412
+ unwrappingKey: CryptoKey,
1413
+ unwrapAlgorithm: AlgorithmIdentifier,
1414
+ unwrappedKeyAlgorithm: AlgorithmIdentifier,
1415
+ extractable: boolean,
1416
+ keyUsages: KeyUsage[]
1417
+ ): Promise<CryptoKey>;
1418
+ }
1419
+
1420
+ /**
1421
+ * Crypto interface providing cryptographic functionality.
1422
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Crypto
1423
+ */
1424
+ interface Crypto {
1425
+ /**
1426
+ * SubtleCrypto interface for cryptographic operations.
1427
+ */
1428
+ readonly subtle: SubtleCrypto;
1429
+
1430
+ /**
1431
+ * Fill a TypedArray with cryptographically random values.
1432
+ *
1433
+ * @param array - TypedArray to fill (max 65536 bytes)
1434
+ * @returns The same array, filled with random values
1435
+ *
1436
+ * @example
1437
+ * const arr = new Uint8Array(16);
1438
+ * crypto.getRandomValues(arr);
1439
+ */
1440
+ getRandomValues<T extends ArrayBufferView | null>(array: T): T;
1441
+
1442
+ /**
1443
+ * Generate a random UUID v4.
1444
+ *
1445
+ * @returns A random UUID string
1446
+ *
1447
+ * @example
1448
+ * const uuid = crypto.randomUUID();
1449
+ * // "550e8400-e29b-41d4-a716-446655440000"
1450
+ */
1451
+ randomUUID(): string;
1452
+ }
1453
+
1454
+ /**
1455
+ * Crypto object providing cryptographic functionality.
1456
+ */
1457
+ const crypto: Crypto;
1458
+ }
1459
+ `;
1171
1460
  var TIMERS_TYPES = `/**
1172
1461
  * QuickJS Global Type Definitions for @ricsam/quickjs-timers
1173
1462
  *
@@ -1252,6 +1541,7 @@ declare global {
1252
1541
  var TYPE_DEFINITIONS = {
1253
1542
  core: CORE_TYPES,
1254
1543
  console: CONSOLE_TYPES,
1544
+ crypto: CRYPTO_TYPES,
1255
1545
  encoding: ENCODING_TYPES,
1256
1546
  fetch: FETCH_TYPES,
1257
1547
  fs: FS_TYPES,
@@ -1260,4 +1550,4 @@ var TYPE_DEFINITIONS = {
1260
1550
  };
1261
1551
  })
1262
1552
 
1263
- //# debugId=D9337DFBBDE4C79F64756E2164756E21
1553
+ //# debugId=0BC014EC5A81951964756E2164756E21