@ricsam/quickjs-test-utils 1.0.18 → 1.0.19

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.
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/native-input-test.ts"],
4
+ "sourcesContent": [
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport { marshal } from \"@ricsam/quickjs-core\";\n\nexport interface TestRuntime {\n logs: Record<string, unknown>;\n result: unknown;\n}\n\nexport interface TestRunner {\n input(inputs: Record<string, unknown>): TestRuntime;\n}\n\n/**\n * Run QJS code with native objects as input and capture logs\n *\n * This utility allows testing whether native objects passed INTO QuickJS\n * behave like QJS instances. It converts native web API classes (Headers,\n * Request, Response, URL, Blob, File, FormData) to their QJS equivalents\n * before executing the test code.\n *\n * @example\n * const runtime = runTestCode(ctx.context, `\n * const headers = testingInput.headers;\n * log(\"instanceof\", headers instanceof Headers);\n * log(\"contentType\", headers.get(\"content-type\"));\n * `).input({\n * headers: new Headers({ \"content-type\": \"application/json\" })\n * });\n *\n * expect(runtime.logs).toEqual({\n * instanceof: true,\n * contentType: \"application/json\"\n * });\n */\nexport function runTestCode(context: QuickJSContext, code: string): TestRunner {\n return {\n input(inputs: Record<string, unknown>): TestRuntime {\n const logs: Record<string, unknown> = {};\n\n // Setup log capture - log(tag, value) stores as logs[tag] = value\n // Values are unmarshalled back to native types for bidirectional testing\n const logFn = context.newFunction(\"log\", (tagHandle, valueHandle) => {\n const tag = context.getString(tagHandle);\n const value = unmarshalWithClassConversion(context, valueHandle);\n logs[tag] = value;\n });\n context.setProp(context.global, \"log\", logFn);\n logFn.dispose();\n\n // Marshal inputs with special handling for native web API classes\n const inputHandle = marshalWithClassConversion(context, inputs);\n context.setProp(context.global, \"testingInput\", inputHandle);\n inputHandle.dispose();\n\n // Run the code\n const result = context.evalCode(code);\n let returnValue: unknown = undefined;\n\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n // Clean up before throwing\n context.setProp(context.global, \"testingInput\", context.undefined);\n context.setProp(context.global, \"log\", context.undefined);\n throw new Error(`Test code failed: ${JSON.stringify(error)}`);\n } else {\n returnValue = context.dump(result.value);\n result.value.dispose();\n }\n\n // Cleanup\n context.setProp(context.global, \"testingInput\", context.undefined);\n context.setProp(context.global, \"log\", context.undefined);\n\n return { logs, result: returnValue };\n },\n };\n}\n\n/**\n * Marshal with special handling for native web API classes.\n * Converts native Headers/Request/Response/URL/Blob/File/FormData to QJS instances.\n */\nfunction marshalWithClassConversion(\n context: QuickJSContext,\n value: unknown\n): QuickJSHandle {\n // Check for native Headers\n if (value instanceof Headers) {\n return createQJSHeadersFromNative(context, value);\n }\n\n // Check for native Request\n if (value instanceof Request) {\n return createQJSRequestFromNative(context, value);\n }\n\n // Check for native Response\n if (value instanceof Response) {\n return createQJSResponseFromNative(context, value);\n }\n\n // Check for native URL\n if (value instanceof URL) {\n return createQJSURLFromNative(context, value);\n }\n\n // Check for native Blob (but not File, which extends Blob)\n if (value instanceof Blob && !(value instanceof File)) {\n return createQJSBlobFromNative(context, value);\n }\n\n // Check for native File\n if (value instanceof File) {\n return createQJSFileFromNative(context, value);\n }\n\n // Check for native FormData\n if (value instanceof FormData) {\n return createQJSFormDataFromNative(context, value);\n }\n\n // Handle arrays recursively\n if (Array.isArray(value)) {\n const arr = context.newArray();\n for (let i = 0; i < value.length; i++) {\n const itemHandle = marshalWithClassConversion(context, value[i]);\n context.setProp(arr, i, itemHandle);\n itemHandle.dispose();\n }\n return arr;\n }\n\n // Handle plain objects recursively\n if (value && typeof value === \"object\" && value.constructor === Object) {\n const obj = context.newObject();\n for (const [key, val] of Object.entries(value)) {\n const valHandle = marshalWithClassConversion(context, val);\n context.setProp(obj, key, valHandle);\n valHandle.dispose();\n }\n return obj;\n }\n\n // Fall back to standard marshal for primitives and other types\n return marshal(context, value);\n}\n\n/**\n * Create a QJS Headers instance from native Headers\n */\nfunction createQJSHeadersFromNative(\n context: QuickJSContext,\n native: Headers\n): QuickJSHandle {\n // Convert to array of pairs\n const pairs: [string, string][] = [];\n native.forEach((value, key) => {\n pairs.push([key, value]);\n });\n\n // Create via evalCode to get proper instance\n const pairsJson = JSON.stringify(pairs);\n const result = context.evalCode(`new Headers(${pairsJson})`);\n\n if (result.error) {\n const err = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to create Headers from native: ${JSON.stringify(err)}`);\n }\n\n return result.value;\n}\n\n/**\n * Create a QJS Request instance from native Request\n *\n * Note: This is a simplified conversion that doesn't handle body streaming.\n * For requests with bodies, the body will need to be consumed and buffered.\n */\nfunction createQJSRequestFromNative(\n context: QuickJSContext,\n native: Request\n): QuickJSHandle {\n // Create headers first\n const headersHandle = createQJSHeadersFromNative(context, native.headers);\n context.setProp(context.global, \"__nativeRequestHeaders__\", headersHandle);\n headersHandle.dispose();\n\n // Marshal the options\n const urlJson = JSON.stringify(native.url);\n const methodJson = JSON.stringify(native.method);\n const modeJson = JSON.stringify(native.mode);\n const credentialsJson = JSON.stringify(native.credentials);\n const cacheJson = JSON.stringify(native.cache);\n const redirectJson = JSON.stringify(native.redirect);\n const referrerJson = JSON.stringify(native.referrer);\n const referrerPolicyJson = JSON.stringify(native.referrerPolicy);\n const integrityJson = JSON.stringify(native.integrity);\n\n const result = context.evalCode(`\n (function() {\n const req = new Request(${urlJson}, {\n method: ${methodJson},\n headers: __nativeRequestHeaders__,\n mode: ${modeJson},\n credentials: ${credentialsJson},\n cache: ${cacheJson},\n redirect: ${redirectJson},\n referrer: ${referrerJson},\n referrerPolicy: ${referrerPolicyJson},\n integrity: ${integrityJson},\n });\n delete globalThis.__nativeRequestHeaders__;\n return req;\n })()\n `);\n\n if (result.error) {\n const err = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to create Request from native: ${JSON.stringify(err)}`);\n }\n\n return result.value;\n}\n\n/**\n * Create a QJS Response instance from native Response\n *\n * Note: This is a simplified conversion that doesn't handle body streaming.\n * For responses with bodies, the body will need to be consumed and buffered.\n */\nfunction createQJSResponseFromNative(\n context: QuickJSContext,\n native: Response\n): QuickJSHandle {\n // Create headers first\n const headersHandle = createQJSHeadersFromNative(context, native.headers);\n context.setProp(context.global, \"__nativeResponseHeaders__\", headersHandle);\n headersHandle.dispose();\n\n // Marshal the options\n const statusJson = JSON.stringify(native.status);\n const statusTextJson = JSON.stringify(native.statusText);\n\n const result = context.evalCode(`\n (function() {\n const res = new Response(null, {\n status: ${statusJson},\n statusText: ${statusTextJson},\n headers: __nativeResponseHeaders__,\n });\n delete globalThis.__nativeResponseHeaders__;\n return res;\n })()\n `);\n\n if (result.error) {\n const err = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to create Response from native: ${JSON.stringify(err)}`);\n }\n\n return result.value;\n}\n\n/**\n * Create a QJS URL instance from native URL\n */\nfunction createQJSURLFromNative(\n context: QuickJSContext,\n native: URL\n): QuickJSHandle {\n const hrefJson = JSON.stringify(native.href);\n const result = context.evalCode(`new URL(${hrefJson})`);\n\n if (result.error) {\n const err = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to create URL from native: ${JSON.stringify(err)}`);\n }\n\n return result.value;\n}\n\n/**\n * Create a QJS Blob instance from native Blob\n *\n * Note: This requires reading the blob content synchronously,\n * which may not work for large blobs. For testing purposes,\n * we assume blobs are small enough to buffer.\n */\nfunction createQJSBlobFromNative(\n context: QuickJSContext,\n native: Blob\n): QuickJSHandle {\n // For now, create an empty blob with the same type\n // Full blob data would require async operation\n const typeJson = JSON.stringify(native.type);\n const result = context.evalCode(`new Blob([], { type: ${typeJson} })`);\n\n if (result.error) {\n const err = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to create Blob from native: ${JSON.stringify(err)}`);\n }\n\n return result.value;\n}\n\n/**\n * Create a QJS File instance from native File\n *\n * Note: This requires reading the file content synchronously,\n * which may not work for large files. For testing purposes,\n * we assume files are small enough to buffer.\n */\nfunction createQJSFileFromNative(\n context: QuickJSContext,\n native: File\n): QuickJSHandle {\n // For now, create an empty file with the same name and type\n // Full file data would require async operation\n const nameJson = JSON.stringify(native.name);\n const typeJson = JSON.stringify(native.type);\n const lastModifiedJson = JSON.stringify(native.lastModified);\n\n const result = context.evalCode(`\n new File([], ${nameJson}, { type: ${typeJson}, lastModified: ${lastModifiedJson} })\n `);\n\n if (result.error) {\n const err = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to create File from native: ${JSON.stringify(err)}`);\n }\n\n return result.value;\n}\n\n/**\n * Create a QJS FormData instance from native FormData\n */\nfunction createQJSFormDataFromNative(\n context: QuickJSContext,\n native: FormData\n): QuickJSHandle {\n // Create empty FormData first\n const result = context.evalCode(`new FormData()`);\n\n if (result.error) {\n const err = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to create FormData from native: ${JSON.stringify(err)}`);\n }\n\n const formDataHandle = result.value;\n\n // Add entries - note that File entries will be converted to empty Files\n for (const [key, entryValue] of native.entries()) {\n const keyJson = JSON.stringify(key);\n\n // FormDataEntryValue is string | File\n if (typeof entryValue !== \"string\") {\n // For File entries, we need special handling\n const fileValue = entryValue as File;\n const nameJson = JSON.stringify(fileValue.name);\n const typeJson = JSON.stringify(fileValue.type);\n const appendResult = context.evalCode(`\n (function(fd) {\n const file = new File([], ${nameJson}, { type: ${typeJson} });\n fd.append(${keyJson}, file);\n return fd;\n })\n `);\n\n if (appendResult.error) {\n appendResult.error.dispose();\n formDataHandle.dispose();\n throw new Error(\"Failed to create append function for File\");\n }\n\n const appendFn = appendResult.value;\n const callResult = context.callFunction(appendFn, context.undefined, formDataHandle);\n appendFn.dispose();\n\n if (callResult.error) {\n callResult.error.dispose();\n formDataHandle.dispose();\n throw new Error(\"Failed to append File to FormData\");\n }\n callResult.value.dispose();\n } else {\n // String value\n const valueJson = JSON.stringify(entryValue);\n const appendResult = context.evalCode(`\n (function(fd) {\n fd.append(${keyJson}, ${valueJson});\n return fd;\n })\n `);\n\n if (appendResult.error) {\n appendResult.error.dispose();\n formDataHandle.dispose();\n throw new Error(\"Failed to create append function\");\n }\n\n const appendFn = appendResult.value;\n const callResult = context.callFunction(appendFn, context.undefined, formDataHandle);\n appendFn.dispose();\n\n if (callResult.error) {\n callResult.error.dispose();\n formDataHandle.dispose();\n throw new Error(\"Failed to append to FormData\");\n }\n callResult.value.dispose();\n }\n }\n\n return formDataHandle;\n}\n\n/**\n * Unmarshal with special handling for QJS web API classes.\n * Converts QJS Headers/Request/Response/URL/Blob/File/FormData back to native instances.\n */\nfunction unmarshalWithClassConversion(\n context: QuickJSContext,\n handle: QuickJSHandle\n): unknown {\n // Check if it's a Headers instance\n if (isInstanceOf(context, handle, \"Headers\")) {\n return createNativeHeadersFromQJS(context, handle);\n }\n\n // Check if it's a Request instance\n if (isInstanceOf(context, handle, \"Request\")) {\n return createNativeRequestFromQJS(context, handle);\n }\n\n // Check if it's a Response instance\n if (isInstanceOf(context, handle, \"Response\")) {\n return createNativeResponseFromQJS(context, handle);\n }\n\n // Check if it's a URL instance\n if (isInstanceOf(context, handle, \"URL\")) {\n return createNativeURLFromQJS(context, handle);\n }\n\n // Check if it's a File instance (before Blob, since File extends Blob)\n if (isInstanceOf(context, handle, \"File\")) {\n return createNativeFileFromQJS(context, handle);\n }\n\n // Check if it's a Blob instance\n if (isInstanceOf(context, handle, \"Blob\")) {\n return createNativeBlobFromQJS(context, handle);\n }\n\n // Check if it's a FormData instance\n if (isInstanceOf(context, handle, \"FormData\")) {\n return createNativeFormDataFromQJS(context, handle);\n }\n\n // Check if it's an array - recursively unmarshal elements\n const typeofResult = context.typeof(handle);\n if (typeofResult === \"object\") {\n const isArrayResult = context.evalCode(`(function(obj) { return Array.isArray(obj); })`);\n if (!isArrayResult.error) {\n const checkResult = context.callFunction(isArrayResult.value, context.undefined, handle);\n isArrayResult.value.dispose();\n if (!checkResult.error && context.dump(checkResult.value) === true) {\n checkResult.value.dispose();\n return unmarshalArray(context, handle);\n }\n if (checkResult.error) checkResult.error.dispose();\n else if (checkResult.value) checkResult.value.dispose();\n } else {\n isArrayResult.error.dispose();\n }\n\n // Check if it's a plain object - recursively unmarshal properties\n const isPlainObjectResult = context.evalCode(`(function(obj) {\n return obj !== null && typeof obj === 'object' && obj.constructor === Object;\n })`);\n if (!isPlainObjectResult.error) {\n const checkResult = context.callFunction(isPlainObjectResult.value, context.undefined, handle);\n isPlainObjectResult.value.dispose();\n if (!checkResult.error && context.dump(checkResult.value) === true) {\n checkResult.value.dispose();\n return unmarshalObject(context, handle);\n }\n if (checkResult.error) checkResult.error.dispose();\n else if (checkResult.value) checkResult.value.dispose();\n } else {\n isPlainObjectResult.error.dispose();\n }\n }\n\n // Fall back to standard dump for primitives and unrecognized types\n return context.dump(handle);\n}\n\n/**\n * Check if a QJS handle is an instance of a given class\n */\nfunction isInstanceOf(\n context: QuickJSContext,\n handle: QuickJSHandle,\n className: string\n): boolean {\n const checkResult = context.evalCode(`(function(obj) { return obj instanceof ${className}; })`);\n if (checkResult.error) {\n checkResult.error.dispose();\n return false;\n }\n\n const result = context.callFunction(checkResult.value, context.undefined, handle);\n checkResult.value.dispose();\n\n if (result.error) {\n result.error.dispose();\n return false;\n }\n\n const isInstance = context.dump(result.value) === true;\n result.value.dispose();\n return isInstance;\n}\n\n/**\n * Unmarshal a QJS array, recursively converting elements\n */\nfunction unmarshalArray(context: QuickJSContext, handle: QuickJSHandle): unknown[] {\n const lengthHandle = context.getProp(handle, \"length\");\n const length = context.dump(lengthHandle) as number;\n lengthHandle.dispose();\n\n const result: unknown[] = [];\n for (let i = 0; i < length; i++) {\n const itemHandle = context.getProp(handle, i);\n result.push(unmarshalWithClassConversion(context, itemHandle));\n itemHandle.dispose();\n }\n return result;\n}\n\n/**\n * Unmarshal a QJS plain object, recursively converting properties\n */\nfunction unmarshalObject(\n context: QuickJSContext,\n handle: QuickJSHandle\n): Record<string, unknown> {\n const keysResult = context.evalCode(`(function(obj) { return Object.keys(obj); })`);\n if (keysResult.error) {\n keysResult.error.dispose();\n return context.dump(handle) as Record<string, unknown>;\n }\n\n const keysCallResult = context.callFunction(keysResult.value, context.undefined, handle);\n keysResult.value.dispose();\n\n if (keysCallResult.error) {\n keysCallResult.error.dispose();\n return context.dump(handle) as Record<string, unknown>;\n }\n\n const keys = context.dump(keysCallResult.value) as string[];\n keysCallResult.value.dispose();\n\n const result: Record<string, unknown> = {};\n for (const key of keys) {\n const propHandle = context.getProp(handle, key);\n result[key] = unmarshalWithClassConversion(context, propHandle);\n propHandle.dispose();\n }\n return result;\n}\n\n/**\n * Create a native Headers instance from QJS Headers\n */\nfunction createNativeHeadersFromQJS(\n context: QuickJSContext,\n qjsHandle: QuickJSHandle\n): Headers {\n // Extract all headers as array of pairs\n const extractResult = context.evalCode(`\n (function(headers) {\n const pairs = [];\n for (const [key, value] of headers) {\n pairs.push([key, value]);\n }\n return pairs;\n })\n `);\n\n if (extractResult.error) {\n extractResult.error.dispose();\n throw new Error(\"Failed to create extract function for Headers\");\n }\n\n const result = context.callFunction(extractResult.value, context.undefined, qjsHandle);\n extractResult.value.dispose();\n\n if (result.error) {\n result.error.dispose();\n throw new Error(\"Failed to call header extraction function\");\n }\n\n const pairs = context.dump(result.value) as [string, string][];\n result.value.dispose();\n\n // Create native Headers from pairs\n const native = new Headers();\n for (const [key, value] of pairs) {\n native.append(key, value);\n }\n\n return native;\n}\n\n/**\n * Create a native Request instance from QJS Request\n */\nfunction createNativeRequestFromQJS(\n context: QuickJSContext,\n qjsHandle: QuickJSHandle\n): Request {\n // Extract request properties\n const extractResult = context.evalCode(`\n (function(req) {\n const headers = [];\n for (const [key, value] of req.headers) {\n headers.push([key, value]);\n }\n return {\n url: req.url,\n method: req.method,\n headers: headers,\n mode: req.mode,\n credentials: req.credentials,\n cache: req.cache,\n redirect: req.redirect,\n referrer: req.referrer,\n referrerPolicy: req.referrerPolicy,\n integrity: req.integrity,\n };\n })\n `);\n\n if (extractResult.error) {\n extractResult.error.dispose();\n throw new Error(\"Failed to create extract function for Request\");\n }\n\n const result = context.callFunction(extractResult.value, context.undefined, qjsHandle);\n extractResult.value.dispose();\n\n if (result.error) {\n result.error.dispose();\n throw new Error(\"Failed to call request extraction function\");\n }\n\n const props = context.dump(result.value) as {\n url: string;\n method: string;\n headers: [string, string][];\n mode: RequestMode;\n credentials: RequestCredentials;\n cache: RequestCache;\n redirect: RequestRedirect;\n referrer: string;\n referrerPolicy: ReferrerPolicy;\n integrity: string;\n };\n result.value.dispose();\n\n // Create native Request\n const headers = new Headers();\n for (const [key, value] of props.headers) {\n headers.append(key, value);\n }\n\n return new Request(props.url, {\n method: props.method,\n headers: headers,\n mode: props.mode,\n credentials: props.credentials,\n cache: props.cache,\n redirect: props.redirect,\n referrer: props.referrer,\n referrerPolicy: props.referrerPolicy,\n integrity: props.integrity,\n });\n}\n\n/**\n * Create a native Response instance from QJS Response\n */\nfunction createNativeResponseFromQJS(\n context: QuickJSContext,\n qjsHandle: QuickJSHandle\n): Response {\n // Extract response properties\n const extractResult = context.evalCode(`\n (function(res) {\n const headers = [];\n for (const [key, value] of res.headers) {\n headers.push([key, value]);\n }\n return {\n status: res.status,\n statusText: res.statusText,\n headers: headers,\n };\n })\n `);\n\n if (extractResult.error) {\n extractResult.error.dispose();\n throw new Error(\"Failed to create extract function for Response\");\n }\n\n const result = context.callFunction(extractResult.value, context.undefined, qjsHandle);\n extractResult.value.dispose();\n\n if (result.error) {\n result.error.dispose();\n throw new Error(\"Failed to call response extraction function\");\n }\n\n const props = context.dump(result.value) as {\n status: number;\n statusText: string;\n headers: [string, string][];\n };\n result.value.dispose();\n\n // Create native Response\n const headers = new Headers();\n for (const [key, value] of props.headers) {\n headers.append(key, value);\n }\n\n return new Response(null, {\n status: props.status,\n statusText: props.statusText,\n headers: headers,\n });\n}\n\n/**\n * Create a native URL instance from QJS URL\n */\nfunction createNativeURLFromQJS(\n context: QuickJSContext,\n qjsHandle: QuickJSHandle\n): URL {\n const hrefHandle = context.getProp(qjsHandle, \"href\");\n const href = context.dump(hrefHandle) as string;\n hrefHandle.dispose();\n\n return new URL(href);\n}\n\n/**\n * Create a native Blob instance from QJS Blob\n */\nfunction createNativeBlobFromQJS(\n context: QuickJSContext,\n qjsHandle: QuickJSHandle\n): Blob {\n // Extract blob properties\n const typeHandle = context.getProp(qjsHandle, \"type\");\n const type = context.dump(typeHandle) as string;\n typeHandle.dispose();\n\n // Note: We can't easily extract blob content synchronously\n // Creating an empty blob with the same type\n return new Blob([], { type });\n}\n\n/**\n * Create a native File instance from QJS File\n */\nfunction createNativeFileFromQJS(\n context: QuickJSContext,\n qjsHandle: QuickJSHandle\n): File {\n // Extract file properties\n const nameHandle = context.getProp(qjsHandle, \"name\");\n const name = context.dump(nameHandle) as string;\n nameHandle.dispose();\n\n const typeHandle = context.getProp(qjsHandle, \"type\");\n const type = context.dump(typeHandle) as string;\n typeHandle.dispose();\n\n const lastModifiedHandle = context.getProp(qjsHandle, \"lastModified\");\n const lastModified = context.dump(lastModifiedHandle) as number;\n lastModifiedHandle.dispose();\n\n // Note: We can't easily extract file content synchronously\n // Creating an empty file with the same properties\n return new File([], name, { type, lastModified });\n}\n\n/**\n * Create a native FormData instance from QJS FormData\n */\nfunction createNativeFormDataFromQJS(\n context: QuickJSContext,\n qjsHandle: QuickJSHandle\n): FormData {\n // Extract formdata entries\n const extractResult = context.evalCode(`\n (function(fd) {\n const entries = [];\n for (const [key, value] of fd) {\n if (value instanceof File) {\n entries.push([key, { type: 'file', name: value.name, fileType: value.type, lastModified: value.lastModified }]);\n } else {\n entries.push([key, { type: 'string', value: value }]);\n }\n }\n return entries;\n })\n `);\n\n if (extractResult.error) {\n extractResult.error.dispose();\n throw new Error(\"Failed to create extract function for FormData\");\n }\n\n const result = context.callFunction(extractResult.value, context.undefined, qjsHandle);\n extractResult.value.dispose();\n\n if (result.error) {\n result.error.dispose();\n throw new Error(\"Failed to call formdata extraction function\");\n }\n\n const entries = context.dump(result.value) as [\n string,\n { type: \"string\"; value: string } | { type: \"file\"; name: string; fileType: string; lastModified: number }\n ][];\n result.value.dispose();\n\n // Create native FormData\n const formData = new FormData();\n for (const [key, entry] of entries) {\n if (entry.type === \"file\") {\n formData.append(key, new File([], entry.name, { type: entry.fileType, lastModified: entry.lastModified }));\n } else {\n formData.append(key, entry.value);\n }\n }\n\n return formData;\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "A14BDC5D5B1C027164756E2164756E21",
9
+ "names": []
10
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/quickjs-test-utils",
3
- "version": "1.0.18",
3
+ "version": "1.0.19",
4
4
  "type": "commonjs"
5
5
  }
@@ -11,6 +11,9 @@ import {
11
11
  useFetchTestContext
12
12
  } from "./fetch-context.mjs";
13
13
  import { evalCode, evalCodeAsync } from "./eval.mjs";
14
+ import {
15
+ runTestCode
16
+ } from "./native-input-test.mjs";
14
17
  import {
15
18
  startIntegrationServer
16
19
  } from "./integration-server.mjs";
@@ -29,6 +32,7 @@ export {
29
32
  useFetchTestContext,
30
33
  typecheckQuickJSCode,
31
34
  startIntegrationServer,
35
+ runTestCode,
32
36
  formatTypecheckErrors,
33
37
  evalCodeAsync,
34
38
  evalCode,
@@ -42,4 +46,4 @@ export {
42
46
  CORE_TYPES
43
47
  };
44
48
 
45
- //# debugId=E7F326004DCE839564756E2164756E21
49
+ //# debugId=D68E092BABACFD0664756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts"],
4
4
  "sourcesContent": [
5
- "export {\n createTestContext,\n disposeTestContext,\n useTestContext,\n type TestContext,\n} from \"./context.mjs\";\n\nexport {\n createFetchTestContext,\n disposeFetchTestContext,\n useFetchTestContext,\n type FetchTestContext,\n type CreateFetchTestContextOptions,\n} from \"./fetch-context.mjs\";\n\nexport { evalCode, evalCodeAsync } from \"./eval.mjs\";\n\nexport {\n startIntegrationServer,\n type IntegrationTestServer,\n type StartIntegrationServerOptions,\n} from \"./integration-server.mjs\";\n\nexport {\n typecheckQuickJSCode,\n formatTypecheckErrors,\n type TypecheckResult,\n type TypecheckError,\n type TypecheckOptions,\n type LibraryTypes,\n type LibraryTypeFile,\n} from \"./typecheck.mjs\";\n\nexport {\n CORE_TYPES,\n FETCH_TYPES,\n FS_TYPES,\n TYPE_DEFINITIONS,\n type TypeDefinitionKey,\n} from \"./quickjs-types.mjs\";\n\n// For fs and runtime contexts, import from subpaths:\n// import { createFsTestContext } from \"@ricsam/quickjs-test-utils/fs\";\n// import { createRuntimeTestContext } from \"@ricsam/quickjs-test-utils/runtime\";\n"
5
+ "export {\n createTestContext,\n disposeTestContext,\n useTestContext,\n type TestContext,\n} from \"./context.mjs\";\n\nexport {\n createFetchTestContext,\n disposeFetchTestContext,\n useFetchTestContext,\n type FetchTestContext,\n type CreateFetchTestContextOptions,\n} from \"./fetch-context.mjs\";\n\nexport { evalCode, evalCodeAsync } from \"./eval.mjs\";\n\nexport {\n runTestCode,\n type TestRuntime,\n type TestRunner,\n} from \"./native-input-test.mjs\";\n\nexport {\n startIntegrationServer,\n type IntegrationTestServer,\n type StartIntegrationServerOptions,\n} from \"./integration-server.mjs\";\n\nexport {\n typecheckQuickJSCode,\n formatTypecheckErrors,\n type TypecheckResult,\n type TypecheckError,\n type TypecheckOptions,\n type LibraryTypes,\n type LibraryTypeFile,\n} from \"./typecheck.mjs\";\n\nexport {\n CORE_TYPES,\n FETCH_TYPES,\n FS_TYPES,\n TYPE_DEFINITIONS,\n type TypeDefinitionKey,\n} from \"./quickjs-types.mjs\";\n\n// For fs and runtime contexts, import from subpaths:\n// import { createFsTestContext } from \"@ricsam/quickjs-test-utils/fs\";\n// import { createRuntimeTestContext } from \"@ricsam/quickjs-test-utils/runtime\";\n"
6
6
  ],
7
- "mappings": ";;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;AAAA;AAAA;AAAA;AAAA;AAQA;AAEA;AAAA;AAAA;AAMA;AAAA;AAAA;AAAA;AAUA;AAAA;AAAA;AAAA;AAAA;AAAA;",
8
- "debugId": "E7F326004DCE839564756E2164756E21",
7
+ "mappings": ";;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;AAAA;AAAA;AAAA;AAAA;AAQA;AAEA;AAAA;AAAA;AAMA;AAAA;AAAA;AAMA;AAAA;AAAA;AAAA;AAUA;AAAA;AAAA;AAAA;AAAA;AAAA;",
8
+ "debugId": "D68E092BABACFD0664756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -0,0 +1,534 @@
1
+ // @bun
2
+ // packages/test-utils/src/native-input-test.ts
3
+ import { marshal } from "@ricsam/quickjs-core";
4
+ function runTestCode(context, code) {
5
+ return {
6
+ input(inputs) {
7
+ const logs = {};
8
+ const logFn = context.newFunction("log", (tagHandle, valueHandle) => {
9
+ const tag = context.getString(tagHandle);
10
+ const value = unmarshalWithClassConversion(context, valueHandle);
11
+ logs[tag] = value;
12
+ });
13
+ context.setProp(context.global, "log", logFn);
14
+ logFn.dispose();
15
+ const inputHandle = marshalWithClassConversion(context, inputs);
16
+ context.setProp(context.global, "testingInput", inputHandle);
17
+ inputHandle.dispose();
18
+ const result = context.evalCode(code);
19
+ let returnValue = undefined;
20
+ if (result.error) {
21
+ const error = context.dump(result.error);
22
+ result.error.dispose();
23
+ context.setProp(context.global, "testingInput", context.undefined);
24
+ context.setProp(context.global, "log", context.undefined);
25
+ throw new Error(`Test code failed: ${JSON.stringify(error)}`);
26
+ } else {
27
+ returnValue = context.dump(result.value);
28
+ result.value.dispose();
29
+ }
30
+ context.setProp(context.global, "testingInput", context.undefined);
31
+ context.setProp(context.global, "log", context.undefined);
32
+ return { logs, result: returnValue };
33
+ }
34
+ };
35
+ }
36
+ function marshalWithClassConversion(context, value) {
37
+ if (value instanceof Headers) {
38
+ return createQJSHeadersFromNative(context, value);
39
+ }
40
+ if (value instanceof Request) {
41
+ return createQJSRequestFromNative(context, value);
42
+ }
43
+ if (value instanceof Response) {
44
+ return createQJSResponseFromNative(context, value);
45
+ }
46
+ if (value instanceof URL) {
47
+ return createQJSURLFromNative(context, value);
48
+ }
49
+ if (value instanceof Blob && !(value instanceof File)) {
50
+ return createQJSBlobFromNative(context, value);
51
+ }
52
+ if (value instanceof File) {
53
+ return createQJSFileFromNative(context, value);
54
+ }
55
+ if (value instanceof FormData) {
56
+ return createQJSFormDataFromNative(context, value);
57
+ }
58
+ if (Array.isArray(value)) {
59
+ const arr = context.newArray();
60
+ for (let i = 0;i < value.length; i++) {
61
+ const itemHandle = marshalWithClassConversion(context, value[i]);
62
+ context.setProp(arr, i, itemHandle);
63
+ itemHandle.dispose();
64
+ }
65
+ return arr;
66
+ }
67
+ if (value && typeof value === "object" && value.constructor === Object) {
68
+ const obj = context.newObject();
69
+ for (const [key, val] of Object.entries(value)) {
70
+ const valHandle = marshalWithClassConversion(context, val);
71
+ context.setProp(obj, key, valHandle);
72
+ valHandle.dispose();
73
+ }
74
+ return obj;
75
+ }
76
+ return marshal(context, value);
77
+ }
78
+ function createQJSHeadersFromNative(context, native) {
79
+ const pairs = [];
80
+ native.forEach((value, key) => {
81
+ pairs.push([key, value]);
82
+ });
83
+ const pairsJson = JSON.stringify(pairs);
84
+ const result = context.evalCode(`new Headers(${pairsJson})`);
85
+ if (result.error) {
86
+ const err = context.dump(result.error);
87
+ result.error.dispose();
88
+ throw new Error(`Failed to create Headers from native: ${JSON.stringify(err)}`);
89
+ }
90
+ return result.value;
91
+ }
92
+ function createQJSRequestFromNative(context, native) {
93
+ const headersHandle = createQJSHeadersFromNative(context, native.headers);
94
+ context.setProp(context.global, "__nativeRequestHeaders__", headersHandle);
95
+ headersHandle.dispose();
96
+ const urlJson = JSON.stringify(native.url);
97
+ const methodJson = JSON.stringify(native.method);
98
+ const modeJson = JSON.stringify(native.mode);
99
+ const credentialsJson = JSON.stringify(native.credentials);
100
+ const cacheJson = JSON.stringify(native.cache);
101
+ const redirectJson = JSON.stringify(native.redirect);
102
+ const referrerJson = JSON.stringify(native.referrer);
103
+ const referrerPolicyJson = JSON.stringify(native.referrerPolicy);
104
+ const integrityJson = JSON.stringify(native.integrity);
105
+ const result = context.evalCode(`
106
+ (function() {
107
+ const req = new Request(${urlJson}, {
108
+ method: ${methodJson},
109
+ headers: __nativeRequestHeaders__,
110
+ mode: ${modeJson},
111
+ credentials: ${credentialsJson},
112
+ cache: ${cacheJson},
113
+ redirect: ${redirectJson},
114
+ referrer: ${referrerJson},
115
+ referrerPolicy: ${referrerPolicyJson},
116
+ integrity: ${integrityJson},
117
+ });
118
+ delete globalThis.__nativeRequestHeaders__;
119
+ return req;
120
+ })()
121
+ `);
122
+ if (result.error) {
123
+ const err = context.dump(result.error);
124
+ result.error.dispose();
125
+ throw new Error(`Failed to create Request from native: ${JSON.stringify(err)}`);
126
+ }
127
+ return result.value;
128
+ }
129
+ function createQJSResponseFromNative(context, native) {
130
+ const headersHandle = createQJSHeadersFromNative(context, native.headers);
131
+ context.setProp(context.global, "__nativeResponseHeaders__", headersHandle);
132
+ headersHandle.dispose();
133
+ const statusJson = JSON.stringify(native.status);
134
+ const statusTextJson = JSON.stringify(native.statusText);
135
+ const result = context.evalCode(`
136
+ (function() {
137
+ const res = new Response(null, {
138
+ status: ${statusJson},
139
+ statusText: ${statusTextJson},
140
+ headers: __nativeResponseHeaders__,
141
+ });
142
+ delete globalThis.__nativeResponseHeaders__;
143
+ return res;
144
+ })()
145
+ `);
146
+ if (result.error) {
147
+ const err = context.dump(result.error);
148
+ result.error.dispose();
149
+ throw new Error(`Failed to create Response from native: ${JSON.stringify(err)}`);
150
+ }
151
+ return result.value;
152
+ }
153
+ function createQJSURLFromNative(context, native) {
154
+ const hrefJson = JSON.stringify(native.href);
155
+ const result = context.evalCode(`new URL(${hrefJson})`);
156
+ if (result.error) {
157
+ const err = context.dump(result.error);
158
+ result.error.dispose();
159
+ throw new Error(`Failed to create URL from native: ${JSON.stringify(err)}`);
160
+ }
161
+ return result.value;
162
+ }
163
+ function createQJSBlobFromNative(context, native) {
164
+ const typeJson = JSON.stringify(native.type);
165
+ const result = context.evalCode(`new Blob([], { type: ${typeJson} })`);
166
+ if (result.error) {
167
+ const err = context.dump(result.error);
168
+ result.error.dispose();
169
+ throw new Error(`Failed to create Blob from native: ${JSON.stringify(err)}`);
170
+ }
171
+ return result.value;
172
+ }
173
+ function createQJSFileFromNative(context, native) {
174
+ const nameJson = JSON.stringify(native.name);
175
+ const typeJson = JSON.stringify(native.type);
176
+ const lastModifiedJson = JSON.stringify(native.lastModified);
177
+ const result = context.evalCode(`
178
+ new File([], ${nameJson}, { type: ${typeJson}, lastModified: ${lastModifiedJson} })
179
+ `);
180
+ if (result.error) {
181
+ const err = context.dump(result.error);
182
+ result.error.dispose();
183
+ throw new Error(`Failed to create File from native: ${JSON.stringify(err)}`);
184
+ }
185
+ return result.value;
186
+ }
187
+ function createQJSFormDataFromNative(context, native) {
188
+ const result = context.evalCode(`new FormData()`);
189
+ if (result.error) {
190
+ const err = context.dump(result.error);
191
+ result.error.dispose();
192
+ throw new Error(`Failed to create FormData from native: ${JSON.stringify(err)}`);
193
+ }
194
+ const formDataHandle = result.value;
195
+ for (const [key, entryValue] of native.entries()) {
196
+ const keyJson = JSON.stringify(key);
197
+ if (typeof entryValue !== "string") {
198
+ const fileValue = entryValue;
199
+ const nameJson = JSON.stringify(fileValue.name);
200
+ const typeJson = JSON.stringify(fileValue.type);
201
+ const appendResult = context.evalCode(`
202
+ (function(fd) {
203
+ const file = new File([], ${nameJson}, { type: ${typeJson} });
204
+ fd.append(${keyJson}, file);
205
+ return fd;
206
+ })
207
+ `);
208
+ if (appendResult.error) {
209
+ appendResult.error.dispose();
210
+ formDataHandle.dispose();
211
+ throw new Error("Failed to create append function for File");
212
+ }
213
+ const appendFn = appendResult.value;
214
+ const callResult = context.callFunction(appendFn, context.undefined, formDataHandle);
215
+ appendFn.dispose();
216
+ if (callResult.error) {
217
+ callResult.error.dispose();
218
+ formDataHandle.dispose();
219
+ throw new Error("Failed to append File to FormData");
220
+ }
221
+ callResult.value.dispose();
222
+ } else {
223
+ const valueJson = JSON.stringify(entryValue);
224
+ const appendResult = context.evalCode(`
225
+ (function(fd) {
226
+ fd.append(${keyJson}, ${valueJson});
227
+ return fd;
228
+ })
229
+ `);
230
+ if (appendResult.error) {
231
+ appendResult.error.dispose();
232
+ formDataHandle.dispose();
233
+ throw new Error("Failed to create append function");
234
+ }
235
+ const appendFn = appendResult.value;
236
+ const callResult = context.callFunction(appendFn, context.undefined, formDataHandle);
237
+ appendFn.dispose();
238
+ if (callResult.error) {
239
+ callResult.error.dispose();
240
+ formDataHandle.dispose();
241
+ throw new Error("Failed to append to FormData");
242
+ }
243
+ callResult.value.dispose();
244
+ }
245
+ }
246
+ return formDataHandle;
247
+ }
248
+ function unmarshalWithClassConversion(context, handle) {
249
+ if (isInstanceOf(context, handle, "Headers")) {
250
+ return createNativeHeadersFromQJS(context, handle);
251
+ }
252
+ if (isInstanceOf(context, handle, "Request")) {
253
+ return createNativeRequestFromQJS(context, handle);
254
+ }
255
+ if (isInstanceOf(context, handle, "Response")) {
256
+ return createNativeResponseFromQJS(context, handle);
257
+ }
258
+ if (isInstanceOf(context, handle, "URL")) {
259
+ return createNativeURLFromQJS(context, handle);
260
+ }
261
+ if (isInstanceOf(context, handle, "File")) {
262
+ return createNativeFileFromQJS(context, handle);
263
+ }
264
+ if (isInstanceOf(context, handle, "Blob")) {
265
+ return createNativeBlobFromQJS(context, handle);
266
+ }
267
+ if (isInstanceOf(context, handle, "FormData")) {
268
+ return createNativeFormDataFromQJS(context, handle);
269
+ }
270
+ const typeofResult = context.typeof(handle);
271
+ if (typeofResult === "object") {
272
+ const isArrayResult = context.evalCode(`(function(obj) { return Array.isArray(obj); })`);
273
+ if (!isArrayResult.error) {
274
+ const checkResult = context.callFunction(isArrayResult.value, context.undefined, handle);
275
+ isArrayResult.value.dispose();
276
+ if (!checkResult.error && context.dump(checkResult.value) === true) {
277
+ checkResult.value.dispose();
278
+ return unmarshalArray(context, handle);
279
+ }
280
+ if (checkResult.error)
281
+ checkResult.error.dispose();
282
+ else if (checkResult.value)
283
+ checkResult.value.dispose();
284
+ } else {
285
+ isArrayResult.error.dispose();
286
+ }
287
+ const isPlainObjectResult = context.evalCode(`(function(obj) {
288
+ return obj !== null && typeof obj === 'object' && obj.constructor === Object;
289
+ })`);
290
+ if (!isPlainObjectResult.error) {
291
+ const checkResult = context.callFunction(isPlainObjectResult.value, context.undefined, handle);
292
+ isPlainObjectResult.value.dispose();
293
+ if (!checkResult.error && context.dump(checkResult.value) === true) {
294
+ checkResult.value.dispose();
295
+ return unmarshalObject(context, handle);
296
+ }
297
+ if (checkResult.error)
298
+ checkResult.error.dispose();
299
+ else if (checkResult.value)
300
+ checkResult.value.dispose();
301
+ } else {
302
+ isPlainObjectResult.error.dispose();
303
+ }
304
+ }
305
+ return context.dump(handle);
306
+ }
307
+ function isInstanceOf(context, handle, className) {
308
+ const checkResult = context.evalCode(`(function(obj) { return obj instanceof ${className}; })`);
309
+ if (checkResult.error) {
310
+ checkResult.error.dispose();
311
+ return false;
312
+ }
313
+ const result = context.callFunction(checkResult.value, context.undefined, handle);
314
+ checkResult.value.dispose();
315
+ if (result.error) {
316
+ result.error.dispose();
317
+ return false;
318
+ }
319
+ const isInstance = context.dump(result.value) === true;
320
+ result.value.dispose();
321
+ return isInstance;
322
+ }
323
+ function unmarshalArray(context, handle) {
324
+ const lengthHandle = context.getProp(handle, "length");
325
+ const length = context.dump(lengthHandle);
326
+ lengthHandle.dispose();
327
+ const result = [];
328
+ for (let i = 0;i < length; i++) {
329
+ const itemHandle = context.getProp(handle, i);
330
+ result.push(unmarshalWithClassConversion(context, itemHandle));
331
+ itemHandle.dispose();
332
+ }
333
+ return result;
334
+ }
335
+ function unmarshalObject(context, handle) {
336
+ const keysResult = context.evalCode(`(function(obj) { return Object.keys(obj); })`);
337
+ if (keysResult.error) {
338
+ keysResult.error.dispose();
339
+ return context.dump(handle);
340
+ }
341
+ const keysCallResult = context.callFunction(keysResult.value, context.undefined, handle);
342
+ keysResult.value.dispose();
343
+ if (keysCallResult.error) {
344
+ keysCallResult.error.dispose();
345
+ return context.dump(handle);
346
+ }
347
+ const keys = context.dump(keysCallResult.value);
348
+ keysCallResult.value.dispose();
349
+ const result = {};
350
+ for (const key of keys) {
351
+ const propHandle = context.getProp(handle, key);
352
+ result[key] = unmarshalWithClassConversion(context, propHandle);
353
+ propHandle.dispose();
354
+ }
355
+ return result;
356
+ }
357
+ function createNativeHeadersFromQJS(context, qjsHandle) {
358
+ const extractResult = context.evalCode(`
359
+ (function(headers) {
360
+ const pairs = [];
361
+ for (const [key, value] of headers) {
362
+ pairs.push([key, value]);
363
+ }
364
+ return pairs;
365
+ })
366
+ `);
367
+ if (extractResult.error) {
368
+ extractResult.error.dispose();
369
+ throw new Error("Failed to create extract function for Headers");
370
+ }
371
+ const result = context.callFunction(extractResult.value, context.undefined, qjsHandle);
372
+ extractResult.value.dispose();
373
+ if (result.error) {
374
+ result.error.dispose();
375
+ throw new Error("Failed to call header extraction function");
376
+ }
377
+ const pairs = context.dump(result.value);
378
+ result.value.dispose();
379
+ const native = new Headers;
380
+ for (const [key, value] of pairs) {
381
+ native.append(key, value);
382
+ }
383
+ return native;
384
+ }
385
+ function createNativeRequestFromQJS(context, qjsHandle) {
386
+ const extractResult = context.evalCode(`
387
+ (function(req) {
388
+ const headers = [];
389
+ for (const [key, value] of req.headers) {
390
+ headers.push([key, value]);
391
+ }
392
+ return {
393
+ url: req.url,
394
+ method: req.method,
395
+ headers: headers,
396
+ mode: req.mode,
397
+ credentials: req.credentials,
398
+ cache: req.cache,
399
+ redirect: req.redirect,
400
+ referrer: req.referrer,
401
+ referrerPolicy: req.referrerPolicy,
402
+ integrity: req.integrity,
403
+ };
404
+ })
405
+ `);
406
+ if (extractResult.error) {
407
+ extractResult.error.dispose();
408
+ throw new Error("Failed to create extract function for Request");
409
+ }
410
+ const result = context.callFunction(extractResult.value, context.undefined, qjsHandle);
411
+ extractResult.value.dispose();
412
+ if (result.error) {
413
+ result.error.dispose();
414
+ throw new Error("Failed to call request extraction function");
415
+ }
416
+ const props = context.dump(result.value);
417
+ result.value.dispose();
418
+ const headers = new Headers;
419
+ for (const [key, value] of props.headers) {
420
+ headers.append(key, value);
421
+ }
422
+ return new Request(props.url, {
423
+ method: props.method,
424
+ headers,
425
+ mode: props.mode,
426
+ credentials: props.credentials,
427
+ cache: props.cache,
428
+ redirect: props.redirect,
429
+ referrer: props.referrer,
430
+ referrerPolicy: props.referrerPolicy,
431
+ integrity: props.integrity
432
+ });
433
+ }
434
+ function createNativeResponseFromQJS(context, qjsHandle) {
435
+ const extractResult = context.evalCode(`
436
+ (function(res) {
437
+ const headers = [];
438
+ for (const [key, value] of res.headers) {
439
+ headers.push([key, value]);
440
+ }
441
+ return {
442
+ status: res.status,
443
+ statusText: res.statusText,
444
+ headers: headers,
445
+ };
446
+ })
447
+ `);
448
+ if (extractResult.error) {
449
+ extractResult.error.dispose();
450
+ throw new Error("Failed to create extract function for Response");
451
+ }
452
+ const result = context.callFunction(extractResult.value, context.undefined, qjsHandle);
453
+ extractResult.value.dispose();
454
+ if (result.error) {
455
+ result.error.dispose();
456
+ throw new Error("Failed to call response extraction function");
457
+ }
458
+ const props = context.dump(result.value);
459
+ result.value.dispose();
460
+ const headers = new Headers;
461
+ for (const [key, value] of props.headers) {
462
+ headers.append(key, value);
463
+ }
464
+ return new Response(null, {
465
+ status: props.status,
466
+ statusText: props.statusText,
467
+ headers
468
+ });
469
+ }
470
+ function createNativeURLFromQJS(context, qjsHandle) {
471
+ const hrefHandle = context.getProp(qjsHandle, "href");
472
+ const href = context.dump(hrefHandle);
473
+ hrefHandle.dispose();
474
+ return new URL(href);
475
+ }
476
+ function createNativeBlobFromQJS(context, qjsHandle) {
477
+ const typeHandle = context.getProp(qjsHandle, "type");
478
+ const type = context.dump(typeHandle);
479
+ typeHandle.dispose();
480
+ return new Blob([], { type });
481
+ }
482
+ function createNativeFileFromQJS(context, qjsHandle) {
483
+ const nameHandle = context.getProp(qjsHandle, "name");
484
+ const name = context.dump(nameHandle);
485
+ nameHandle.dispose();
486
+ const typeHandle = context.getProp(qjsHandle, "type");
487
+ const type = context.dump(typeHandle);
488
+ typeHandle.dispose();
489
+ const lastModifiedHandle = context.getProp(qjsHandle, "lastModified");
490
+ const lastModified = context.dump(lastModifiedHandle);
491
+ lastModifiedHandle.dispose();
492
+ return new File([], name, { type, lastModified });
493
+ }
494
+ function createNativeFormDataFromQJS(context, qjsHandle) {
495
+ const extractResult = context.evalCode(`
496
+ (function(fd) {
497
+ const entries = [];
498
+ for (const [key, value] of fd) {
499
+ if (value instanceof File) {
500
+ entries.push([key, { type: 'file', name: value.name, fileType: value.type, lastModified: value.lastModified }]);
501
+ } else {
502
+ entries.push([key, { type: 'string', value: value }]);
503
+ }
504
+ }
505
+ return entries;
506
+ })
507
+ `);
508
+ if (extractResult.error) {
509
+ extractResult.error.dispose();
510
+ throw new Error("Failed to create extract function for FormData");
511
+ }
512
+ const result = context.callFunction(extractResult.value, context.undefined, qjsHandle);
513
+ extractResult.value.dispose();
514
+ if (result.error) {
515
+ result.error.dispose();
516
+ throw new Error("Failed to call formdata extraction function");
517
+ }
518
+ const entries = context.dump(result.value);
519
+ result.value.dispose();
520
+ const formData = new FormData;
521
+ for (const [key, entry] of entries) {
522
+ if (entry.type === "file") {
523
+ formData.append(key, new File([], entry.name, { type: entry.fileType, lastModified: entry.lastModified }));
524
+ } else {
525
+ formData.append(key, entry.value);
526
+ }
527
+ }
528
+ return formData;
529
+ }
530
+ export {
531
+ runTestCode
532
+ };
533
+
534
+ //# debugId=69B05738000763A164756E2164756E21