@ricsam/quickjs-fetch 0.2.4 → 0.2.5

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.
@@ -33,12 +33,15 @@ __export(exports_form_data, {
33
33
  serializeFormData: () => serializeFormData,
34
34
  parseUrlEncodedFormData: () => parseUrlEncodedFormData,
35
35
  parseMultipartFormData: () => parseMultipartFormData,
36
- createFormDataClass: () => createFormDataClass
36
+ createFormDataClass: () => createFormDataClass,
37
+ addFormDataFileMethods: () => addFormDataFileMethods,
38
+ FORMDATA_FILE_MARKER: () => FORMDATA_FILE_MARKER
37
39
  });
38
40
  module.exports = __toCommonJS(exports_form_data);
39
41
  var import_quickjs_core = require("@ricsam/quickjs-core");
42
+ var FORMDATA_FILE_MARKER = "__formDataFile__";
40
43
  function isFileValue(value) {
41
- return value !== null && typeof value === "object" && "data" in value && "filename" in value;
44
+ return value !== null && typeof value === "object" && FORMDATA_FILE_MARKER in value && value[FORMDATA_FILE_MARKER] === true;
42
45
  }
43
46
  function createFormDataClass(context, stateMap) {
44
47
  return import_quickjs_core.defineClass(context, stateMap, {
@@ -49,21 +52,54 @@ function createFormDataClass(context, stateMap) {
49
52
  methods: {
50
53
  append(name, value, filename) {
51
54
  const nameStr = String(name);
55
+ if (import_quickjs_core.isInstanceOf(value, "File")) {
56
+ const fileState = import_quickjs_core.getClassInstanceState(value);
57
+ if (fileState) {
58
+ const data = concatenateParts(fileState.parts);
59
+ const fileValue = {
60
+ [FORMDATA_FILE_MARKER]: true,
61
+ data,
62
+ filename: filename !== undefined ? String(filename) : fileState.name,
63
+ type: fileState.type || "application/octet-stream"
64
+ };
65
+ this.entries.push({ name: nameStr, value: fileValue });
66
+ return;
67
+ }
68
+ }
69
+ if (import_quickjs_core.isInstanceOf(value, "Blob")) {
70
+ const blobState = import_quickjs_core.getClassInstanceState(value);
71
+ if (blobState) {
72
+ const data = concatenateParts(blobState.parts);
73
+ const fileValue = {
74
+ [FORMDATA_FILE_MARKER]: true,
75
+ data,
76
+ filename: filename !== undefined ? String(filename) : "blob",
77
+ type: blobState.type || "application/octet-stream"
78
+ };
79
+ this.entries.push({ name: nameStr, value: fileValue });
80
+ return;
81
+ }
82
+ }
52
83
  if (value && typeof value === "object" && "parts" in value) {
53
84
  const blobLike = value;
54
85
  const data = concatenateParts(blobLike.parts);
55
86
  const fileValue = {
87
+ [FORMDATA_FILE_MARKER]: true,
56
88
  data,
57
89
  filename: filename !== undefined ? String(filename) : blobLike.name || "blob",
58
90
  type: blobLike.type || "application/octet-stream"
59
91
  };
60
92
  this.entries.push({ name: nameStr, value: fileValue });
61
93
  } else if (value && typeof value === "object" && "data" in value && "filename" in value) {
94
+ const fileVal = value;
95
+ const data = Array.isArray(fileVal.data) ? new Uint8Array(fileVal.data) : fileVal.data;
62
96
  this.entries.push({
63
97
  name: nameStr,
64
98
  value: {
65
- ...value,
66
- filename: filename !== undefined ? String(filename) : value.filename
99
+ [FORMDATA_FILE_MARKER]: true,
100
+ data,
101
+ filename: filename !== undefined ? String(filename) : fileVal.filename,
102
+ type: fileVal.type
67
103
  }
68
104
  });
69
105
  } else {
@@ -90,21 +126,54 @@ function createFormDataClass(context, stateMap) {
90
126
  set(name, value, filename) {
91
127
  const nameStr = String(name);
92
128
  this.entries = this.entries.filter((e) => e.name !== nameStr);
129
+ if (import_quickjs_core.isInstanceOf(value, "File")) {
130
+ const fileState = import_quickjs_core.getClassInstanceState(value);
131
+ if (fileState) {
132
+ const data = concatenateParts(fileState.parts);
133
+ const fileValue = {
134
+ [FORMDATA_FILE_MARKER]: true,
135
+ data,
136
+ filename: filename !== undefined ? String(filename) : fileState.name,
137
+ type: fileState.type || "application/octet-stream"
138
+ };
139
+ this.entries.push({ name: nameStr, value: fileValue });
140
+ return;
141
+ }
142
+ }
143
+ if (import_quickjs_core.isInstanceOf(value, "Blob")) {
144
+ const blobState = import_quickjs_core.getClassInstanceState(value);
145
+ if (blobState) {
146
+ const data = concatenateParts(blobState.parts);
147
+ const fileValue = {
148
+ [FORMDATA_FILE_MARKER]: true,
149
+ data,
150
+ filename: filename !== undefined ? String(filename) : "blob",
151
+ type: blobState.type || "application/octet-stream"
152
+ };
153
+ this.entries.push({ name: nameStr, value: fileValue });
154
+ return;
155
+ }
156
+ }
93
157
  if (value && typeof value === "object" && "parts" in value) {
94
158
  const blobLike = value;
95
159
  const data = concatenateParts(blobLike.parts);
96
160
  const fileValue = {
161
+ [FORMDATA_FILE_MARKER]: true,
97
162
  data,
98
163
  filename: filename !== undefined ? String(filename) : blobLike.name || "blob",
99
164
  type: blobLike.type || "application/octet-stream"
100
165
  };
101
166
  this.entries.push({ name: nameStr, value: fileValue });
102
167
  } else if (value && typeof value === "object" && "data" in value && "filename" in value) {
168
+ const fileVal = value;
169
+ const data = Array.isArray(fileVal.data) ? new Uint8Array(fileVal.data) : fileVal.data;
103
170
  this.entries.push({
104
171
  name: nameStr,
105
172
  value: {
106
- ...value,
107
- filename: filename !== undefined ? String(filename) : value.filename
173
+ [FORMDATA_FILE_MARKER]: true,
174
+ data,
175
+ filename: filename !== undefined ? String(filename) : fileVal.filename,
176
+ type: fileVal.type
108
177
  }
109
178
  });
110
179
  } else {
@@ -198,7 +267,7 @@ function parseMultipartFormData(body, contentType) {
198
267
  const type = headers["content-type"] || "application/octet-stream";
199
268
  entries.push({
200
269
  name,
201
- value: { data: content, filename, type }
270
+ value: { [FORMDATA_FILE_MARKER]: true, data: content, filename, type }
202
271
  });
203
272
  } else {
204
273
  entries.push({
@@ -284,6 +353,43 @@ function serializeFormData(state) {
284
353
  contentType: `multipart/form-data; boundary=${boundary}`
285
354
  };
286
355
  }
356
+ function addFormDataFileMethods(context) {
357
+ const result = context.evalCode(`
358
+ (function() {
359
+ const FILE_MARKER = "${FORMDATA_FILE_MARKER}";
360
+
361
+ function toFile(value) {
362
+ if (!value || typeof value !== "object") return value;
363
+ if (value instanceof File) return value;
364
+ if (value[FILE_MARKER] === true) {
365
+ // Reconstruct File from stored data
366
+ const data = Array.isArray(value.data)
367
+ ? new Uint8Array(value.data)
368
+ : value.data;
369
+ return new File([data], value.filename, { type: value.type });
370
+ }
371
+ return value;
372
+ }
373
+
374
+ const originalGet = FormData.prototype.get;
375
+ FormData.prototype.get = function(name) {
376
+ return toFile(originalGet.call(this, name));
377
+ };
378
+
379
+ const originalGetAll = FormData.prototype.getAll;
380
+ FormData.prototype.getAll = function(name) {
381
+ return originalGetAll.call(this, name).map(toFile);
382
+ };
383
+ })();
384
+ `);
385
+ if (result.error) {
386
+ const errorMsg = context.dump(result.error);
387
+ result.error.dispose();
388
+ throw new Error(`Failed to add FormData file methods: ${JSON.stringify(errorMsg)}`);
389
+ } else {
390
+ result.value.dispose();
391
+ }
392
+ }
287
393
  })
288
394
 
289
- //# debugId=B8A8E8E47E566E3764756E2164756E21
395
+ //# debugId=E3D4034C748F5E3564756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/globals/form-data.ts"],
4
4
  "sourcesContent": [
5
- "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass } from \"@ricsam/quickjs-core\";\n\n/**\n * Internal state for FormData entries\n * Each entry can have multiple values (same key appended multiple times)\n */\nexport interface FormDataEntry {\n name: string;\n value: string | FormDataFileValue;\n}\n\nexport interface FormDataFileValue {\n data: Uint8Array;\n filename: string;\n type: string;\n}\n\nexport interface FormDataState {\n entries: FormDataEntry[];\n}\n\nfunction isFileValue(value: unknown): value is FormDataFileValue {\n return (\n value !== null &&\n typeof value === \"object\" &&\n \"data\" in value &&\n \"filename\" in value\n );\n}\n\n/**\n * Create the FormData class for QuickJS\n */\nexport function createFormDataClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<FormDataState>(context, stateMap, {\n name: \"FormData\",\n construct: () => {\n return { entries: [] };\n },\n methods: {\n append(this: FormDataState, name: unknown, value: unknown, filename?: unknown) {\n const nameStr = String(name);\n\n if (value && typeof value === \"object\" && \"parts\" in value) {\n // Blob-like value\n const blobLike = value as { parts: Uint8Array[]; type?: string; name?: string };\n const data = concatenateParts(blobLike.parts);\n const fileValue: FormDataFileValue = {\n data,\n filename: filename !== undefined ? String(filename) : (blobLike.name || \"blob\"),\n type: blobLike.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n } else if (value && typeof value === \"object\" && \"data\" in value && \"filename\" in value) {\n // Already a FormDataFileValue\n this.entries.push({\n name: nameStr,\n value: {\n ...(value as FormDataFileValue),\n filename: filename !== undefined ? String(filename) : (value as FormDataFileValue).filename,\n },\n });\n } else {\n // String value\n this.entries.push({ name: nameStr, value: String(value) });\n }\n },\n delete(this: FormDataState, name: unknown) {\n const nameStr = String(name);\n this.entries = this.entries.filter((e) => e.name !== nameStr);\n },\n get(this: FormDataState, name: unknown): string | FormDataFileValue | null {\n const nameStr = String(name);\n const entry = this.entries.find((e) => e.name === nameStr);\n return entry ? entry.value : null;\n },\n getAll(this: FormDataState, name: unknown): Array<string | FormDataFileValue> {\n const nameStr = String(name);\n return this.entries\n .filter((e) => e.name === nameStr)\n .map((e) => e.value);\n },\n has(this: FormDataState, name: unknown): boolean {\n const nameStr = String(name);\n return this.entries.some((e) => e.name === nameStr);\n },\n set(this: FormDataState, name: unknown, value: unknown, filename?: unknown) {\n const nameStr = String(name);\n // Remove all existing entries with this name\n this.entries = this.entries.filter((e) => e.name !== nameStr);\n\n // Add the new entry (using append logic)\n if (value && typeof value === \"object\" && \"parts\" in value) {\n const blobLike = value as { parts: Uint8Array[]; type?: string; name?: string };\n const data = concatenateParts(blobLike.parts);\n const fileValue: FormDataFileValue = {\n data,\n filename: filename !== undefined ? String(filename) : (blobLike.name || \"blob\"),\n type: blobLike.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n } else if (value && typeof value === \"object\" && \"data\" in value && \"filename\" in value) {\n this.entries.push({\n name: nameStr,\n value: {\n ...(value as FormDataFileValue),\n filename: filename !== undefined ? String(filename) : (value as FormDataFileValue).filename,\n },\n });\n } else {\n this.entries.push({ name: nameStr, value: String(value) });\n }\n },\n entries(this: FormDataState): Array<[string, string | FormDataFileValue]> {\n return this.entries.map((e) => [e.name, e.value]);\n },\n keys(this: FormDataState): string[] {\n // Return unique keys in order of first appearance\n const seen = new Set<string>();\n const result: string[] = [];\n for (const entry of this.entries) {\n if (!seen.has(entry.name)) {\n seen.add(entry.name);\n result.push(entry.name);\n }\n }\n return result;\n },\n values(this: FormDataState): Array<string | FormDataFileValue> {\n return this.entries.map((e) => e.value);\n },\n forEach(this: FormDataState, callback: unknown) {\n if (typeof callback !== \"function\") {\n throw new TypeError(\"callback must be a function\");\n }\n for (const entry of this.entries) {\n (callback as (value: string | FormDataFileValue, key: string, parent: FormDataState) => void)(\n entry.value,\n entry.name,\n this\n );\n }\n },\n },\n });\n}\n\n/**\n * Concatenate Uint8Arrays into a single Uint8Array\n */\nfunction concatenateParts(parts: Uint8Array[]): Uint8Array {\n const totalLength = parts.reduce((sum, part) => sum + part.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n result.set(part, offset);\n offset += part.length;\n }\n return result;\n}\n\n/**\n * Parse multipart/form-data body\n */\nexport function parseMultipartFormData(\n body: Uint8Array,\n contentType: string\n): FormDataState {\n const entries: FormDataEntry[] = [];\n\n // Extract boundary from content-type\n const boundaryMatch = contentType.match(/boundary=([^;]+)/i);\n if (!boundaryMatch || !boundaryMatch[1]) {\n return { entries };\n }\n\n const boundary = boundaryMatch[1].replace(/^[\"']|[\"']$/g, \"\");\n const boundaryBytes = new TextEncoder().encode(`--${boundary}`);\n const endBoundaryBytes = new TextEncoder().encode(`--${boundary}--`);\n\n // Find all parts\n const decoder = new TextDecoder();\n let pos = 0;\n\n // Skip preamble and first boundary\n pos = findSequence(body, boundaryBytes, pos);\n if (pos === -1) return { entries };\n pos += boundaryBytes.length;\n\n while (pos < body.length) {\n // Skip CRLF after boundary\n if (body[pos] === 0x0d && body[pos + 1] === 0x0a) {\n pos += 2;\n } else if (body[pos] === 0x0a) {\n pos += 1;\n }\n\n // Check for end boundary\n if (pos + 2 <= body.length && body[pos] === 0x2d && body[pos + 1] === 0x2d) {\n break; // End of multipart\n }\n\n // Parse headers\n const headersEnd = findSequence(body, new Uint8Array([0x0d, 0x0a, 0x0d, 0x0a]), pos);\n if (headersEnd === -1) break;\n\n const headersText = decoder.decode(body.slice(pos, headersEnd));\n const headers = parseHeaders(headersText);\n pos = headersEnd + 4;\n\n // Find next boundary\n const nextBoundary = findSequence(body, boundaryBytes, pos);\n if (nextBoundary === -1) break;\n\n // Content is between current position and next boundary (minus CRLF)\n let contentEnd = nextBoundary;\n if (contentEnd > 0 && body[contentEnd - 1] === 0x0a) contentEnd--;\n if (contentEnd > 0 && body[contentEnd - 1] === 0x0d) contentEnd--;\n\n const content = body.slice(pos, contentEnd);\n\n // Parse Content-Disposition header\n const disposition = headers[\"content-disposition\"] || \"\";\n const nameMatch = disposition.match(/name=\"([^\"]+)\"/);\n const filenameMatch = disposition.match(/filename=\"([^\"]+)\"/);\n\n if (nameMatch && nameMatch[1]) {\n const name = nameMatch[1];\n if (filenameMatch && filenameMatch[1]) {\n // File entry\n const filename = filenameMatch[1];\n const type = headers[\"content-type\"] || \"application/octet-stream\";\n entries.push({\n name,\n value: { data: content, filename, type },\n });\n } else {\n // String entry\n entries.push({\n name,\n value: decoder.decode(content),\n });\n }\n }\n\n pos = nextBoundary + boundaryBytes.length;\n }\n\n return { entries };\n}\n\n/**\n * Parse URL-encoded form data\n */\nexport function parseUrlEncodedFormData(body: Uint8Array): FormDataState {\n const text = new TextDecoder().decode(body);\n const entries: FormDataEntry[] = [];\n\n const params = new URLSearchParams(text);\n for (const [name, value] of params) {\n entries.push({ name, value });\n }\n\n return { entries };\n}\n\nfunction findSequence(haystack: Uint8Array, needle: Uint8Array, start: number): number {\n outer: for (let i = start; i <= haystack.length - needle.length; i++) {\n for (let j = 0; j < needle.length; j++) {\n if (haystack[i + j] !== needle[j]) continue outer;\n }\n return i;\n }\n return -1;\n}\n\nfunction parseHeaders(text: string): Record<string, string> {\n const headers: Record<string, string> = {};\n const lines = text.split(/\\r?\\n/);\n for (const line of lines) {\n const colonIndex = line.indexOf(\":\");\n if (colonIndex > 0) {\n const name = line.slice(0, colonIndex).trim().toLowerCase();\n const value = line.slice(colonIndex + 1).trim();\n headers[name] = value;\n }\n }\n return headers;\n}\n\n/**\n * Serialize FormData to multipart/form-data format\n */\nexport function serializeFormData(state: FormDataState): { body: Uint8Array; contentType: string } {\n const boundary = `----FormDataBoundary${Math.random().toString(36).slice(2)}`;\n const encoder = new TextEncoder();\n const parts: Uint8Array[] = [];\n\n for (const entry of state.entries) {\n const headerLines: string[] = [];\n headerLines.push(`--${boundary}`);\n\n if (isFileValue(entry.value)) {\n headerLines.push(\n `Content-Disposition: form-data; name=\"${entry.name}\"; filename=\"${entry.value.filename}\"`\n );\n headerLines.push(`Content-Type: ${entry.value.type}`);\n headerLines.push(\"\");\n\n parts.push(encoder.encode(headerLines.join(\"\\r\\n\") + \"\\r\\n\"));\n parts.push(entry.value.data);\n parts.push(encoder.encode(\"\\r\\n\"));\n } else {\n headerLines.push(`Content-Disposition: form-data; name=\"${entry.name}\"`);\n headerLines.push(\"\");\n headerLines.push(entry.value);\n\n parts.push(encoder.encode(headerLines.join(\"\\r\\n\") + \"\\r\\n\"));\n }\n }\n\n parts.push(encoder.encode(`--${boundary}--\\r\\n`));\n\n // Concatenate all parts\n const totalLength = parts.reduce((sum, part) => sum + part.length, 0);\n const body = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n body.set(part, offset);\n offset += part.length;\n }\n\n return {\n body,\n contentType: `multipart/form-data; boundary=${boundary}`,\n };\n}\n"
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass, isInstanceOf, getClassInstanceState } from \"@ricsam/quickjs-core\";\n\n/**\n * Marker to identify FormData file entries that need File reconstruction\n */\nexport const FORMDATA_FILE_MARKER = \"__formDataFile__\";\n\n/**\n * Internal state for Blob/File classes (from packages/core)\n */\ninterface BlobInternalState {\n parts: Uint8Array[];\n type: string;\n size: number;\n}\n\ninterface FileInternalState extends BlobInternalState {\n name: string;\n lastModified: number;\n webkitRelativePath: string;\n}\n\n/**\n * Internal state for FormData entries\n * Each entry can have multiple values (same key appended multiple times)\n */\nexport interface FormDataEntry {\n name: string;\n value: string | FormDataFileValue;\n}\n\nexport interface FormDataFileValue {\n [FORMDATA_FILE_MARKER]: true;\n data: Uint8Array;\n filename: string;\n type: string;\n}\n\nexport interface FormDataState {\n entries: FormDataEntry[];\n}\n\nfunction isFileValue(value: unknown): value is FormDataFileValue {\n return (\n value !== null &&\n typeof value === \"object\" &&\n FORMDATA_FILE_MARKER in value &&\n (value as FormDataFileValue)[FORMDATA_FILE_MARKER] === true\n );\n}\n\n/**\n * Create the FormData class for QuickJS\n */\nexport function createFormDataClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<FormDataState>(context, stateMap, {\n name: \"FormData\",\n construct: () => {\n return { entries: [] };\n },\n methods: {\n append(this: FormDataState, name: unknown, value: unknown, filename?: unknown) {\n const nameStr = String(name);\n\n // Check for File instance using class identity (preferred method)\n if (isInstanceOf(value, \"File\")) {\n const fileState = getClassInstanceState<FileInternalState>(value);\n if (fileState) {\n const data = concatenateParts(fileState.parts);\n const fileValue: FormDataFileValue = {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : fileState.name,\n type: fileState.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n return;\n }\n }\n\n // Check for Blob instance using class identity\n if (isInstanceOf(value, \"Blob\")) {\n const blobState = getClassInstanceState<BlobInternalState>(value);\n if (blobState) {\n const data = concatenateParts(blobState.parts);\n const fileValue: FormDataFileValue = {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : \"blob\",\n type: blobState.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n return;\n }\n }\n\n // Fallback: duck-typing for Blob-like objects (backwards compatibility)\n if (value && typeof value === \"object\" && \"parts\" in value) {\n const blobLike = value as { parts: Uint8Array[]; type?: string; name?: string };\n const data = concatenateParts(blobLike.parts);\n const fileValue: FormDataFileValue = {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : (blobLike.name || \"blob\"),\n type: blobLike.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n } else if (value && typeof value === \"object\" && \"data\" in value && \"filename\" in value) {\n // Already a FormDataFileValue (or similar structure with data, filename, type)\n const fileVal = value as { data: Uint8Array | number[]; filename: string; type: string };\n // Handle both Uint8Array and number array (for safe cross-context marshalling)\n const data = Array.isArray(fileVal.data)\n ? new Uint8Array(fileVal.data)\n : fileVal.data;\n this.entries.push({\n name: nameStr,\n value: {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : fileVal.filename,\n type: fileVal.type,\n },\n });\n } else {\n // String value\n this.entries.push({ name: nameStr, value: String(value) });\n }\n },\n delete(this: FormDataState, name: unknown) {\n const nameStr = String(name);\n this.entries = this.entries.filter((e) => e.name !== nameStr);\n },\n get(this: FormDataState, name: unknown): string | FormDataFileValue | null {\n const nameStr = String(name);\n const entry = this.entries.find((e) => e.name === nameStr);\n return entry ? entry.value : null;\n },\n getAll(this: FormDataState, name: unknown): Array<string | FormDataFileValue> {\n const nameStr = String(name);\n return this.entries\n .filter((e) => e.name === nameStr)\n .map((e) => e.value);\n },\n has(this: FormDataState, name: unknown): boolean {\n const nameStr = String(name);\n return this.entries.some((e) => e.name === nameStr);\n },\n set(this: FormDataState, name: unknown, value: unknown, filename?: unknown) {\n const nameStr = String(name);\n // Remove all existing entries with this name\n this.entries = this.entries.filter((e) => e.name !== nameStr);\n\n // Check for File instance using class identity (preferred method)\n if (isInstanceOf(value, \"File\")) {\n const fileState = getClassInstanceState<FileInternalState>(value);\n if (fileState) {\n const data = concatenateParts(fileState.parts);\n const fileValue: FormDataFileValue = {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : fileState.name,\n type: fileState.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n return;\n }\n }\n\n // Check for Blob instance using class identity\n if (isInstanceOf(value, \"Blob\")) {\n const blobState = getClassInstanceState<BlobInternalState>(value);\n if (blobState) {\n const data = concatenateParts(blobState.parts);\n const fileValue: FormDataFileValue = {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : \"blob\",\n type: blobState.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n return;\n }\n }\n\n // Fallback: duck-typing for Blob-like objects (backwards compatibility)\n if (value && typeof value === \"object\" && \"parts\" in value) {\n const blobLike = value as { parts: Uint8Array[]; type?: string; name?: string };\n const data = concatenateParts(blobLike.parts);\n const fileValue: FormDataFileValue = {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : (blobLike.name || \"blob\"),\n type: blobLike.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n } else if (value && typeof value === \"object\" && \"data\" in value && \"filename\" in value) {\n // Already a FormDataFileValue (or similar structure with data, filename, type)\n const fileVal = value as { data: Uint8Array | number[]; filename: string; type: string };\n // Handle both Uint8Array and number array (for safe cross-context marshalling)\n const data = Array.isArray(fileVal.data)\n ? new Uint8Array(fileVal.data)\n : fileVal.data;\n this.entries.push({\n name: nameStr,\n value: {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : fileVal.filename,\n type: fileVal.type,\n },\n });\n } else {\n this.entries.push({ name: nameStr, value: String(value) });\n }\n },\n entries(this: FormDataState): Array<[string, string | FormDataFileValue]> {\n return this.entries.map((e) => [e.name, e.value]);\n },\n keys(this: FormDataState): string[] {\n // Return unique keys in order of first appearance\n const seen = new Set<string>();\n const result: string[] = [];\n for (const entry of this.entries) {\n if (!seen.has(entry.name)) {\n seen.add(entry.name);\n result.push(entry.name);\n }\n }\n return result;\n },\n values(this: FormDataState): Array<string | FormDataFileValue> {\n return this.entries.map((e) => e.value);\n },\n forEach(this: FormDataState, callback: unknown) {\n if (typeof callback !== \"function\") {\n throw new TypeError(\"callback must be a function\");\n }\n for (const entry of this.entries) {\n (callback as (value: string | FormDataFileValue, key: string, parent: FormDataState) => void)(\n entry.value,\n entry.name,\n this\n );\n }\n },\n },\n });\n}\n\n/**\n * Concatenate Uint8Arrays into a single Uint8Array\n */\nfunction concatenateParts(parts: Uint8Array[]): Uint8Array {\n const totalLength = parts.reduce((sum, part) => sum + part.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n result.set(part, offset);\n offset += part.length;\n }\n return result;\n}\n\n/**\n * Parse multipart/form-data body\n */\nexport function parseMultipartFormData(\n body: Uint8Array,\n contentType: string\n): FormDataState {\n const entries: FormDataEntry[] = [];\n\n // Extract boundary from content-type\n const boundaryMatch = contentType.match(/boundary=([^;]+)/i);\n if (!boundaryMatch || !boundaryMatch[1]) {\n return { entries };\n }\n\n const boundary = boundaryMatch[1].replace(/^[\"']|[\"']$/g, \"\");\n const boundaryBytes = new TextEncoder().encode(`--${boundary}`);\n const endBoundaryBytes = new TextEncoder().encode(`--${boundary}--`);\n\n // Find all parts\n const decoder = new TextDecoder();\n let pos = 0;\n\n // Skip preamble and first boundary\n pos = findSequence(body, boundaryBytes, pos);\n if (pos === -1) return { entries };\n pos += boundaryBytes.length;\n\n while (pos < body.length) {\n // Skip CRLF after boundary\n if (body[pos] === 0x0d && body[pos + 1] === 0x0a) {\n pos += 2;\n } else if (body[pos] === 0x0a) {\n pos += 1;\n }\n\n // Check for end boundary\n if (pos + 2 <= body.length && body[pos] === 0x2d && body[pos + 1] === 0x2d) {\n break; // End of multipart\n }\n\n // Parse headers\n const headersEnd = findSequence(body, new Uint8Array([0x0d, 0x0a, 0x0d, 0x0a]), pos);\n if (headersEnd === -1) break;\n\n const headersText = decoder.decode(body.slice(pos, headersEnd));\n const headers = parseHeaders(headersText);\n pos = headersEnd + 4;\n\n // Find next boundary\n const nextBoundary = findSequence(body, boundaryBytes, pos);\n if (nextBoundary === -1) break;\n\n // Content is between current position and next boundary (minus CRLF)\n let contentEnd = nextBoundary;\n if (contentEnd > 0 && body[contentEnd - 1] === 0x0a) contentEnd--;\n if (contentEnd > 0 && body[contentEnd - 1] === 0x0d) contentEnd--;\n\n const content = body.slice(pos, contentEnd);\n\n // Parse Content-Disposition header\n const disposition = headers[\"content-disposition\"] || \"\";\n const nameMatch = disposition.match(/name=\"([^\"]+)\"/);\n const filenameMatch = disposition.match(/filename=\"([^\"]+)\"/);\n\n if (nameMatch && nameMatch[1]) {\n const name = nameMatch[1];\n if (filenameMatch && filenameMatch[1]) {\n // File entry\n const filename = filenameMatch[1];\n const type = headers[\"content-type\"] || \"application/octet-stream\";\n entries.push({\n name,\n value: { [FORMDATA_FILE_MARKER]: true, data: content, filename, type },\n });\n } else {\n // String entry\n entries.push({\n name,\n value: decoder.decode(content),\n });\n }\n }\n\n pos = nextBoundary + boundaryBytes.length;\n }\n\n return { entries };\n}\n\n/**\n * Parse URL-encoded form data\n */\nexport function parseUrlEncodedFormData(body: Uint8Array): FormDataState {\n const text = new TextDecoder().decode(body);\n const entries: FormDataEntry[] = [];\n\n const params = new URLSearchParams(text);\n for (const [name, value] of params) {\n entries.push({ name, value });\n }\n\n return { entries };\n}\n\nfunction findSequence(haystack: Uint8Array, needle: Uint8Array, start: number): number {\n outer: for (let i = start; i <= haystack.length - needle.length; i++) {\n for (let j = 0; j < needle.length; j++) {\n if (haystack[i + j] !== needle[j]) continue outer;\n }\n return i;\n }\n return -1;\n}\n\nfunction parseHeaders(text: string): Record<string, string> {\n const headers: Record<string, string> = {};\n const lines = text.split(/\\r?\\n/);\n for (const line of lines) {\n const colonIndex = line.indexOf(\":\");\n if (colonIndex > 0) {\n const name = line.slice(0, colonIndex).trim().toLowerCase();\n const value = line.slice(colonIndex + 1).trim();\n headers[name] = value;\n }\n }\n return headers;\n}\n\n/**\n * Serialize FormData to multipart/form-data format\n */\nexport function serializeFormData(state: FormDataState): { body: Uint8Array; contentType: string } {\n const boundary = `----FormDataBoundary${Math.random().toString(36).slice(2)}`;\n const encoder = new TextEncoder();\n const parts: Uint8Array[] = [];\n\n for (const entry of state.entries) {\n const headerLines: string[] = [];\n headerLines.push(`--${boundary}`);\n\n if (isFileValue(entry.value)) {\n headerLines.push(\n `Content-Disposition: form-data; name=\"${entry.name}\"; filename=\"${entry.value.filename}\"`\n );\n headerLines.push(`Content-Type: ${entry.value.type}`);\n headerLines.push(\"\");\n\n parts.push(encoder.encode(headerLines.join(\"\\r\\n\") + \"\\r\\n\"));\n parts.push(entry.value.data);\n parts.push(encoder.encode(\"\\r\\n\"));\n } else {\n headerLines.push(`Content-Disposition: form-data; name=\"${entry.name}\"`);\n headerLines.push(\"\");\n headerLines.push(entry.value);\n\n parts.push(encoder.encode(headerLines.join(\"\\r\\n\") + \"\\r\\n\"));\n }\n }\n\n parts.push(encoder.encode(`--${boundary}--\\r\\n`));\n\n // Concatenate all parts\n const totalLength = parts.reduce((sum, part) => sum + part.length, 0);\n const body = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n body.set(part, offset);\n offset += part.length;\n }\n\n return {\n body,\n contentType: `multipart/form-data; boundary=${boundary}`,\n };\n}\n\n/**\n * Add JavaScript overrides for FormData.get() and FormData.getAll() to reconstruct File instances\n *\n * This is needed because defineClass methods can only return plain objects when marshalling,\n * but we want formData.get(\"file\") to return actual File instances with working methods.\n *\n * @param context The QuickJS context (must have FormData and File classes already defined)\n */\nexport function addFormDataFileMethods(context: QuickJSContext): void {\n const result = context.evalCode(`\n (function() {\n const FILE_MARKER = \"${FORMDATA_FILE_MARKER}\";\n\n function toFile(value) {\n if (!value || typeof value !== \"object\") return value;\n if (value instanceof File) return value;\n if (value[FILE_MARKER] === true) {\n // Reconstruct File from stored data\n const data = Array.isArray(value.data)\n ? new Uint8Array(value.data)\n : value.data;\n return new File([data], value.filename, { type: value.type });\n }\n return value;\n }\n\n const originalGet = FormData.prototype.get;\n FormData.prototype.get = function(name) {\n return toFile(originalGet.call(this, name));\n };\n\n const originalGetAll = FormData.prototype.getAll;\n FormData.prototype.getAll = function(name) {\n return originalGetAll.call(this, name).map(toFile);\n };\n })();\n `);\n if (result.error) {\n const errorMsg = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to add FormData file methods: ${JSON.stringify(errorMsg)}`);\n } else {\n result.value.dispose();\n }\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "B8A8E8E47E566E3764756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "E3D4034C748F5E3564756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -31,7 +31,8 @@ var __export = (target, all) => {
31
31
  var exports_request = {};
32
32
  __export(exports_request, {
33
33
  createRequestStateFromNative: () => createRequestStateFromNative,
34
- createRequestClass: () => createRequestClass
34
+ createRequestClass: () => createRequestClass,
35
+ addRequestFormDataMethod: () => addRequestFormDataMethod
35
36
  });
36
37
  module.exports = __toCommonJS(exports_request);
37
38
  var import_quickjs_core = require("@ricsam/quickjs-core");
@@ -271,7 +272,7 @@ function createRequestClass(context, stateMap, createStream) {
271
272
  }
272
273
  return new TextDecoder().decode(this.body);
273
274
  },
274
- async formData() {
275
+ async __getFormDataEntries__() {
275
276
  if (this.bodyUsed) {
276
277
  throw new TypeError("Body has already been consumed");
277
278
  }
@@ -280,16 +281,60 @@ function createRequestClass(context, stateMap, createStream) {
280
281
  return { entries: [] };
281
282
  }
282
283
  const contentType = this.headersState.headers.get("content-type")?.[0] || "";
284
+ let formDataState;
283
285
  if (contentType.includes("multipart/form-data")) {
284
- return import_form_data.parseMultipartFormData(this.body, contentType);
286
+ formDataState = import_form_data.parseMultipartFormData(this.body, contentType);
285
287
  } else if (contentType.includes("application/x-www-form-urlencoded")) {
286
- return import_form_data.parseUrlEncodedFormData(this.body);
288
+ formDataState = import_form_data.parseUrlEncodedFormData(this.body);
289
+ } else {
290
+ throw new TypeError("Could not parse content as FormData");
287
291
  }
288
- throw new TypeError("Could not parse content as FormData");
292
+ return {
293
+ entries: formDataState.entries.map((entry) => {
294
+ if (typeof entry.value === "string") {
295
+ return { name: entry.name, value: entry.value };
296
+ }
297
+ return {
298
+ name: entry.name,
299
+ value: {
300
+ __formDataFile__: true,
301
+ data: Array.from(entry.value.data),
302
+ filename: entry.value.filename,
303
+ type: entry.value.type
304
+ }
305
+ };
306
+ })
307
+ };
289
308
  }
290
309
  }
291
310
  });
292
311
  }
312
+ function addRequestFormDataMethod(context) {
313
+ const result = context.evalCode(`
314
+ Request.prototype.formData = async function() {
315
+ // Get raw entries from private method
316
+ // Note: File data comes as plain number arrays (converted in host side)
317
+ const rawData = await this.__getFormDataEntries__();
318
+
319
+ // Create a proper FormData instance
320
+ const formData = new FormData();
321
+
322
+ // Populate with entries
323
+ // FormData.append handles both string values and file-like objects
324
+ // with number arrays (converted to Uint8Array on the host side)
325
+ for (const entry of rawData.entries) {
326
+ formData.append(entry.name, entry.value);
327
+ }
328
+
329
+ return formData;
330
+ };
331
+ `);
332
+ if (result.error) {
333
+ result.error.dispose();
334
+ } else {
335
+ result.value.dispose();
336
+ }
337
+ }
293
338
  async function createRequestStateFromNative(request) {
294
339
  const body = request.body ? new Uint8Array(await request.arrayBuffer()) : null;
295
340
  return {
@@ -312,4 +357,4 @@ async function createRequestStateFromNative(request) {
312
357
  }
313
358
  })
314
359
 
315
- //# debugId=D1048399CA8D1EB164756E2164756E21
360
+ //# debugId=C39079D8C2092BD064756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/globals/request.ts"],
4
4
  "sourcesContent": [
5
- "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass } from \"@ricsam/quickjs-core\";\nimport type { RequestState, HeadersState, AbortSignalState, FormDataState } from \"../types.cjs\";\nimport { createHeadersStateFromNative, createHeadersLike } from \"./headers.cjs\";\nimport { parseMultipartFormData, parseUrlEncodedFormData } from \"./form-data.cjs\";\n\n/**\n * Type for the stream factory function\n */\ntype StreamFactory = (source: UnderlyingSource) => QuickJSHandle;\n\n/**\n * Create the Request class for QuickJS\n */\nexport function createRequestClass(\n context: QuickJSContext,\n stateMap: StateMap,\n createStream?: StreamFactory\n): QuickJSHandle {\n return defineClass<RequestState>(context, stateMap, {\n name: \"Request\",\n construct: (args) => {\n const input = args[0];\n const init = args[1] as {\n method?: string;\n headers?: object;\n body?: unknown;\n cache?: string;\n credentials?: string;\n integrity?: string;\n keepalive?: boolean;\n mode?: string;\n redirect?: string;\n referrer?: string;\n referrerPolicy?: string;\n signal?: AbortSignalState;\n } | undefined;\n\n let url = \"\";\n let method = \"GET\";\n let headersState: HeadersState = { headers: new Map() };\n let body: Uint8Array | null = null;\n let signal: AbortSignalState | null = null;\n\n // Handle input\n if (typeof input === \"string\") {\n url = input;\n } else if (input && typeof input === \"object\") {\n // Could be URL or Request-like\n if (\"url\" in input) {\n url = String((input as { url: string }).url);\n }\n if (\"method\" in input) {\n method = String((input as { method: string }).method);\n }\n if (\"headersState\" in input) {\n const inputHeaders = (input as RequestState).headersState;\n headersState = {\n headers: new Map(inputHeaders.headers),\n };\n }\n if (\"body\" in input && (input as RequestState).body) {\n body = (input as RequestState).body;\n }\n if (\"signal\" in input) {\n signal = (input as RequestState).signal;\n }\n }\n\n // Apply init options\n if (init) {\n if (init.method) {\n method = init.method.toUpperCase();\n }\n if (init.headers) {\n if (init.headers && typeof init.headers === \"object\") {\n if (\"headers\" in init.headers && init.headers.headers instanceof Map) {\n headersState = {\n headers: new Map((init.headers as HeadersState).headers),\n };\n } else {\n headersState = { headers: new Map() };\n for (const [key, value] of Object.entries(init.headers)) {\n headersState.headers.set(key.toLowerCase(), [String(value)]);\n }\n }\n }\n }\n if (init.body !== undefined && init.body !== null) {\n if (typeof init.body === \"string\") {\n body = new TextEncoder().encode(init.body);\n } else if (init.body instanceof ArrayBuffer) {\n body = new Uint8Array(init.body);\n } else if (init.body instanceof Uint8Array) {\n body = init.body;\n }\n }\n if (init.signal) {\n signal = init.signal;\n }\n }\n\n return {\n method,\n url,\n headersState,\n body,\n bodyUsed: false,\n cache: init?.cache || \"default\",\n credentials: init?.credentials || \"same-origin\",\n destination: \"\",\n integrity: init?.integrity || \"\",\n keepalive: init?.keepalive || false,\n mode: init?.mode || \"cors\",\n redirect: init?.redirect || \"follow\",\n referrer: init?.referrer || \"about:client\",\n referrerPolicy: init?.referrerPolicy || \"\",\n signal,\n };\n },\n properties: {\n method: {\n get(this: RequestState) {\n return this.method;\n },\n },\n url: {\n get(this: RequestState) {\n return this.url;\n },\n },\n headers: {\n get(this: RequestState) {\n return createHeadersLike(this.headersState);\n },\n },\n body: {\n get(this: RequestState) {\n if (!this.body) return null;\n if (!createStream) {\n // Fallback: return raw body if no stream factory\n return this.body;\n }\n // Create a ReadableStream from the body data\n const bodyData = this.body;\n let offset = 0;\n const chunkSize = 65536; // 64KB chunks\n return createStream({\n pull(controller) {\n if (offset >= bodyData.length) {\n controller.close();\n return;\n }\n const chunk = bodyData.slice(offset, Math.min(offset + chunkSize, bodyData.length));\n offset += chunk.length;\n controller.enqueue(chunk);\n },\n });\n },\n },\n bodyUsed: {\n get(this: RequestState) {\n return this.bodyUsed;\n },\n },\n cache: {\n get(this: RequestState) {\n return this.cache;\n },\n },\n credentials: {\n get(this: RequestState) {\n return this.credentials;\n },\n },\n destination: {\n get(this: RequestState) {\n return this.destination;\n },\n },\n integrity: {\n get(this: RequestState) {\n return this.integrity;\n },\n },\n keepalive: {\n get(this: RequestState) {\n return this.keepalive;\n },\n },\n mode: {\n get(this: RequestState) {\n return this.mode;\n },\n },\n redirect: {\n get(this: RequestState) {\n return this.redirect;\n },\n },\n referrer: {\n get(this: RequestState) {\n return this.referrer;\n },\n },\n referrerPolicy: {\n get(this: RequestState) {\n return this.referrerPolicy;\n },\n },\n signal: {\n get(this: RequestState) {\n return this.signal;\n },\n },\n },\n methods: {\n async arrayBuffer(this: RequestState): Promise<ArrayBuffer> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return new ArrayBuffer(0);\n }\n return this.body.buffer.slice(\n this.body.byteOffset,\n this.body.byteOffset + this.body.byteLength\n ) as ArrayBuffer;\n },\n async blob(this: RequestState): Promise<object> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n return {\n parts: this.body ? [this.body] : [],\n type: contentType,\n size: this.body?.length || 0,\n };\n },\n clone(this: RequestState): RequestState {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n return {\n ...this,\n headersState: {\n headers: new Map(this.headersState.headers),\n },\n body: this.body ? new Uint8Array(this.body) : null,\n bodyUsed: false,\n };\n },\n async json(this: RequestState): Promise<unknown> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return JSON.parse(\"\");\n }\n const text = new TextDecoder().decode(this.body);\n return JSON.parse(text);\n },\n async text(this: RequestState): Promise<string> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return \"\";\n }\n return new TextDecoder().decode(this.body);\n },\n async formData(this: RequestState): Promise<FormDataState> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return { entries: [] };\n }\n\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n\n if (contentType.includes(\"multipart/form-data\")) {\n return parseMultipartFormData(this.body, contentType);\n } else if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n return parseUrlEncodedFormData(this.body);\n }\n\n throw new TypeError(\"Could not parse content as FormData\");\n },\n },\n });\n}\n\n/**\n * Create a RequestState from a native Request object\n */\nexport async function createRequestStateFromNative(\n request: Request\n): Promise<RequestState> {\n const body = request.body\n ? new Uint8Array(await request.arrayBuffer())\n : null;\n\n return {\n method: request.method,\n url: request.url,\n headersState: createHeadersStateFromNative(request.headers),\n body,\n bodyUsed: false,\n cache: request.cache,\n credentials: request.credentials,\n destination: request.destination,\n integrity: request.integrity,\n keepalive: request.keepalive,\n mode: request.mode,\n redirect: request.redirect,\n referrer: request.referrer,\n referrerPolicy: request.referrerPolicy,\n signal: null, // Signal handling is complex, simplified here\n };\n}\n"
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass } from \"@ricsam/quickjs-core\";\nimport type { RequestState, HeadersState, AbortSignalState, FormDataState } from \"../types.cjs\";\nimport { createHeadersStateFromNative, createHeadersLike } from \"./headers.cjs\";\nimport { parseMultipartFormData, parseUrlEncodedFormData } from \"./form-data.cjs\";\n\n/**\n * Type for the stream factory function\n */\ntype StreamFactory = (source: UnderlyingSource) => QuickJSHandle;\n\n/**\n * Create the Request class for QuickJS\n */\nexport function createRequestClass(\n context: QuickJSContext,\n stateMap: StateMap,\n createStream?: StreamFactory\n): QuickJSHandle {\n return defineClass<RequestState>(context, stateMap, {\n name: \"Request\",\n construct: (args) => {\n const input = args[0];\n const init = args[1] as {\n method?: string;\n headers?: object;\n body?: unknown;\n cache?: string;\n credentials?: string;\n integrity?: string;\n keepalive?: boolean;\n mode?: string;\n redirect?: string;\n referrer?: string;\n referrerPolicy?: string;\n signal?: AbortSignalState;\n } | undefined;\n\n let url = \"\";\n let method = \"GET\";\n let headersState: HeadersState = { headers: new Map() };\n let body: Uint8Array | null = null;\n let signal: AbortSignalState | null = null;\n\n // Handle input\n if (typeof input === \"string\") {\n url = input;\n } else if (input && typeof input === \"object\") {\n // Could be URL or Request-like\n if (\"url\" in input) {\n url = String((input as { url: string }).url);\n }\n if (\"method\" in input) {\n method = String((input as { method: string }).method);\n }\n if (\"headersState\" in input) {\n const inputHeaders = (input as RequestState).headersState;\n headersState = {\n headers: new Map(inputHeaders.headers),\n };\n }\n if (\"body\" in input && (input as RequestState).body) {\n body = (input as RequestState).body;\n }\n if (\"signal\" in input) {\n signal = (input as RequestState).signal;\n }\n }\n\n // Apply init options\n if (init) {\n if (init.method) {\n method = init.method.toUpperCase();\n }\n if (init.headers) {\n if (init.headers && typeof init.headers === \"object\") {\n if (\"headers\" in init.headers && init.headers.headers instanceof Map) {\n headersState = {\n headers: new Map((init.headers as HeadersState).headers),\n };\n } else {\n headersState = { headers: new Map() };\n for (const [key, value] of Object.entries(init.headers)) {\n headersState.headers.set(key.toLowerCase(), [String(value)]);\n }\n }\n }\n }\n if (init.body !== undefined && init.body !== null) {\n if (typeof init.body === \"string\") {\n body = new TextEncoder().encode(init.body);\n } else if (init.body instanceof ArrayBuffer) {\n body = new Uint8Array(init.body);\n } else if (init.body instanceof Uint8Array) {\n body = init.body;\n }\n }\n if (init.signal) {\n signal = init.signal;\n }\n }\n\n return {\n method,\n url,\n headersState,\n body,\n bodyUsed: false,\n cache: init?.cache || \"default\",\n credentials: init?.credentials || \"same-origin\",\n destination: \"\",\n integrity: init?.integrity || \"\",\n keepalive: init?.keepalive || false,\n mode: init?.mode || \"cors\",\n redirect: init?.redirect || \"follow\",\n referrer: init?.referrer || \"about:client\",\n referrerPolicy: init?.referrerPolicy || \"\",\n signal,\n };\n },\n properties: {\n method: {\n get(this: RequestState) {\n return this.method;\n },\n },\n url: {\n get(this: RequestState) {\n return this.url;\n },\n },\n headers: {\n get(this: RequestState) {\n return createHeadersLike(this.headersState);\n },\n },\n body: {\n get(this: RequestState) {\n if (!this.body) return null;\n if (!createStream) {\n // Fallback: return raw body if no stream factory\n return this.body;\n }\n // Create a ReadableStream from the body data\n const bodyData = this.body;\n let offset = 0;\n const chunkSize = 65536; // 64KB chunks\n return createStream({\n pull(controller) {\n if (offset >= bodyData.length) {\n controller.close();\n return;\n }\n const chunk = bodyData.slice(offset, Math.min(offset + chunkSize, bodyData.length));\n offset += chunk.length;\n controller.enqueue(chunk);\n },\n });\n },\n },\n bodyUsed: {\n get(this: RequestState) {\n return this.bodyUsed;\n },\n },\n cache: {\n get(this: RequestState) {\n return this.cache;\n },\n },\n credentials: {\n get(this: RequestState) {\n return this.credentials;\n },\n },\n destination: {\n get(this: RequestState) {\n return this.destination;\n },\n },\n integrity: {\n get(this: RequestState) {\n return this.integrity;\n },\n },\n keepalive: {\n get(this: RequestState) {\n return this.keepalive;\n },\n },\n mode: {\n get(this: RequestState) {\n return this.mode;\n },\n },\n redirect: {\n get(this: RequestState) {\n return this.redirect;\n },\n },\n referrer: {\n get(this: RequestState) {\n return this.referrer;\n },\n },\n referrerPolicy: {\n get(this: RequestState) {\n return this.referrerPolicy;\n },\n },\n signal: {\n get(this: RequestState) {\n return this.signal;\n },\n },\n },\n methods: {\n async arrayBuffer(this: RequestState): Promise<ArrayBuffer> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return new ArrayBuffer(0);\n }\n return this.body.buffer.slice(\n this.body.byteOffset,\n this.body.byteOffset + this.body.byteLength\n ) as ArrayBuffer;\n },\n async blob(this: RequestState): Promise<object> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n return {\n parts: this.body ? [this.body] : [],\n type: contentType,\n size: this.body?.length || 0,\n };\n },\n clone(this: RequestState): RequestState {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n return {\n ...this,\n headersState: {\n headers: new Map(this.headersState.headers),\n },\n body: this.body ? new Uint8Array(this.body) : null,\n bodyUsed: false,\n };\n },\n async json(this: RequestState): Promise<unknown> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return JSON.parse(\"\");\n }\n const text = new TextDecoder().decode(this.body);\n return JSON.parse(text);\n },\n async text(this: RequestState): Promise<string> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return \"\";\n }\n return new TextDecoder().decode(this.body);\n },\n /**\n * Private method that returns raw FormData entries.\n * Used by the formData() method added via evalCode (see addRequestFormDataMethod).\n *\n * Note: File data is converted to plain number arrays to avoid memory issues\n * when marshalling Uint8Array between host and QuickJS contexts.\n */\n async __getFormDataEntries__(this: RequestState): Promise<{\n entries: Array<{\n name: string;\n value: string | { __formDataFile__: true; data: number[]; filename: string; type: string };\n }>;\n }> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return { entries: [] };\n }\n\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n\n let formDataState: FormDataState;\n if (contentType.includes(\"multipart/form-data\")) {\n formDataState = parseMultipartFormData(this.body, contentType);\n } else if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n formDataState = parseUrlEncodedFormData(this.body);\n } else {\n throw new TypeError(\"Could not parse content as FormData\");\n }\n\n // Convert Uint8Array data to plain number arrays for safe marshalling\n // Include marker so FormData.get() can reconstruct File instances\n type SerializedFileValue = { __formDataFile__: true; data: number[]; filename: string; type: string };\n type SerializedEntry = { name: string; value: string | SerializedFileValue };\n return {\n entries: formDataState.entries.map((entry): SerializedEntry => {\n if (typeof entry.value === \"string\") {\n return { name: entry.name, value: entry.value };\n }\n // Convert Uint8Array to number array and include marker\n return {\n name: entry.name,\n value: {\n __formDataFile__: true,\n data: Array.from(entry.value.data),\n filename: entry.value.filename,\n type: entry.value.type,\n },\n };\n }),\n };\n },\n },\n });\n}\n\n/**\n * Add the formData() method to Request.prototype via evalCode.\n *\n * This must be called AFTER both Request and FormData classes are on global.\n * The method creates a proper FormData instance with all entries.\n *\n * @see PATTERNS.md section 2 (Class Methods That Return Instances)\n */\nexport function addRequestFormDataMethod(context: QuickJSContext): void {\n const result = context.evalCode(`\n Request.prototype.formData = async function() {\n // Get raw entries from private method\n // Note: File data comes as plain number arrays (converted in host side)\n const rawData = await this.__getFormDataEntries__();\n\n // Create a proper FormData instance\n const formData = new FormData();\n\n // Populate with entries\n // FormData.append handles both string values and file-like objects\n // with number arrays (converted to Uint8Array on the host side)\n for (const entry of rawData.entries) {\n formData.append(entry.name, entry.value);\n }\n\n return formData;\n };\n `);\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n}\n\n/**\n * Create a RequestState from a native Request object\n */\nexport async function createRequestStateFromNative(\n request: Request\n): Promise<RequestState> {\n const body = request.body\n ? new Uint8Array(await request.arrayBuffer())\n : null;\n\n return {\n method: request.method,\n url: request.url,\n headersState: createHeadersStateFromNative(request.headers),\n body,\n bodyUsed: false,\n cache: request.cache,\n credentials: request.credentials,\n destination: request.destination,\n integrity: request.integrity,\n keepalive: request.keepalive,\n mode: request.mode,\n redirect: request.redirect,\n referrer: request.referrer,\n referrerPolicy: request.referrerPolicy,\n signal: null, // Signal handling is complex, simplified here\n };\n}\n"
6
6
  ],
7
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE4B,IAA5B;AAEgE,IAAhE;AACgE,IAAhE;AAUO,SAAS,kBAAkB,CAChC,SACA,UACA,cACe;AAAA,EACf,OAAO,gCAA0B,SAAS,UAAU;AAAA,IAClD,MAAM;AAAA,IACN,WAAW,CAAC,SAAS;AAAA,MACnB,MAAM,QAAQ,KAAK;AAAA,MACnB,MAAM,OAAO,KAAK;AAAA,MAelB,IAAI,MAAM;AAAA,MACV,IAAI,SAAS;AAAA,MACb,IAAI,eAA6B,EAAE,SAAS,IAAI,IAAM;AAAA,MACtD,IAAI,OAA0B;AAAA,MAC9B,IAAI,SAAkC;AAAA,MAGtC,IAAI,OAAO,UAAU,UAAU;AAAA,QAC7B,MAAM;AAAA,MACR,EAAO,SAAI,SAAS,OAAO,UAAU,UAAU;AAAA,QAE7C,IAAI,SAAS,OAAO;AAAA,UAClB,MAAM,OAAQ,MAA0B,GAAG;AAAA,QAC7C;AAAA,QACA,IAAI,YAAY,OAAO;AAAA,UACrB,SAAS,OAAQ,MAA6B,MAAM;AAAA,QACtD;AAAA,QACA,IAAI,kBAAkB,OAAO;AAAA,UAC3B,MAAM,eAAgB,MAAuB;AAAA,UAC7C,eAAe;AAAA,YACb,SAAS,IAAI,IAAI,aAAa,OAAO;AAAA,UACvC;AAAA,QACF;AAAA,QACA,IAAI,UAAU,SAAU,MAAuB,MAAM;AAAA,UACnD,OAAQ,MAAuB;AAAA,QACjC;AAAA,QACA,IAAI,YAAY,OAAO;AAAA,UACrB,SAAU,MAAuB;AAAA,QACnC;AAAA,MACF;AAAA,MAGA,IAAI,MAAM;AAAA,QACR,IAAI,KAAK,QAAQ;AAAA,UACf,SAAS,KAAK,OAAO,YAAY;AAAA,QACnC;AAAA,QACA,IAAI,KAAK,SAAS;AAAA,UAChB,IAAI,KAAK,WAAW,OAAO,KAAK,YAAY,UAAU;AAAA,YACpD,IAAI,aAAa,KAAK,WAAW,KAAK,QAAQ,mBAAmB,KAAK;AAAA,cACpE,eAAe;AAAA,gBACb,SAAS,IAAI,IAAK,KAAK,QAAyB,OAAO;AAAA,cACzD;AAAA,YACF,EAAO;AAAA,cACL,eAAe,EAAE,SAAS,IAAI,IAAM;AAAA,cACpC,YAAY,KAAK,UAAU,OAAO,QAAQ,KAAK,OAAO,GAAG;AAAA,gBACvD,aAAa,QAAQ,IAAI,IAAI,YAAY,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC;AAAA,cAC7D;AAAA;AAAA,UAEJ;AAAA,QACF;AAAA,QACA,IAAI,KAAK,SAAS,aAAa,KAAK,SAAS,MAAM;AAAA,UACjD,IAAI,OAAO,KAAK,SAAS,UAAU;AAAA,YACjC,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK,IAAI;AAAA,UAC3C,EAAO,SAAI,KAAK,gBAAgB,aAAa;AAAA,YAC3C,OAAO,IAAI,WAAW,KAAK,IAAI;AAAA,UACjC,EAAO,SAAI,KAAK,gBAAgB,YAAY;AAAA,YAC1C,OAAO,KAAK;AAAA,UACd;AAAA,QACF;AAAA,QACA,IAAI,KAAK,QAAQ;AAAA,UACf,SAAS,KAAK;AAAA,QAChB;AAAA,MACF;AAAA,MAEA,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV,OAAO,MAAM,SAAS;AAAA,QACtB,aAAa,MAAM,eAAe;AAAA,QAClC,aAAa;AAAA,QACb,WAAW,MAAM,aAAa;AAAA,QAC9B,WAAW,MAAM,aAAa;AAAA,QAC9B,MAAM,MAAM,QAAQ;AAAA,QACpB,UAAU,MAAM,YAAY;AAAA,QAC5B,UAAU,MAAM,YAAY;AAAA,QAC5B,gBAAgB,MAAM,kBAAkB;AAAA,QACxC;AAAA,MACF;AAAA;AAAA,IAEF,YAAY;AAAA,MACV,QAAQ;AAAA,QACN,GAAG,GAAqB;AAAA,UACtB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,KAAK;AAAA,QACH,GAAG,GAAqB;AAAA,UACtB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,SAAS;AAAA,QACP,GAAG,GAAqB;AAAA,UACtB,OAAO,iCAAkB,KAAK,YAAY;AAAA;AAAA,MAE9C;AAAA,MACA,MAAM;AAAA,QACJ,GAAG,GAAqB;AAAA,UACtB,IAAI,CAAC,KAAK;AAAA,YAAM,OAAO;AAAA,UACvB,IAAI,CAAC,cAAc;AAAA,YAEjB,OAAO,KAAK;AAAA,UACd;AAAA,UAEA,MAAM,WAAW,KAAK;AAAA,UACtB,IAAI,SAAS;AAAA,UACb,MAAM,YAAY;AAAA,UAClB,OAAO,aAAa;AAAA,YAClB,IAAI,CAAC,YAAY;AAAA,cACf,IAAI,UAAU,SAAS,QAAQ;AAAA,gBAC7B,WAAW,MAAM;AAAA,gBACjB;AAAA,cACF;AAAA,cACA,MAAM,QAAQ,SAAS,MAAM,QAAQ,KAAK,IAAI,SAAS,WAAW,SAAS,MAAM,CAAC;AAAA,cAClF,UAAU,MAAM;AAAA,cAChB,WAAW,QAAQ,KAAK;AAAA;AAAA,UAE5B,CAAC;AAAA;AAAA,MAEL;AAAA,MACA,UAAU;AAAA,QACR,GAAG,GAAqB;AAAA,UACtB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,OAAO;AAAA,QACL,GAAG,GAAqB;AAAA,UACtB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,aAAa;AAAA,QACX,GAAG,GAAqB;AAAA,UACtB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,aAAa;AAAA,QACX,GAAG,GAAqB;AAAA,UACtB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,WAAW;AAAA,QACT,GAAG,GAAqB;AAAA,UACtB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,WAAW;AAAA,QACT,GAAG,GAAqB;AAAA,UACtB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,MAAM;AAAA,QACJ,GAAG,GAAqB;AAAA,UACtB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,UAAU;AAAA,QACR,GAAG,GAAqB;AAAA,UACtB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,UAAU;AAAA,QACR,GAAG,GAAqB;AAAA,UACtB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,gBAAgB;AAAA,QACd,GAAG,GAAqB;AAAA,UACtB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,MACA,QAAQ;AAAA,QACN,GAAG,GAAqB;AAAA,UACtB,OAAO,KAAK;AAAA;AAAA,MAEhB;AAAA,IACF;AAAA,IACA,SAAS;AAAA,WACD,YAAW,GAA2C;AAAA,QAC1D,IAAI,KAAK,UAAU;AAAA,UACjB,MAAM,IAAI,UAAU,gCAAgC;AAAA,QACtD;AAAA,QACA,KAAK,WAAW;AAAA,QAChB,IAAI,CAAC,KAAK,MAAM;AAAA,UACd,OAAO,IAAI,YAAY,CAAC;AAAA,QAC1B;AAAA,QACA,OAAO,KAAK,KAAK,OAAO,MACtB,KAAK,KAAK,YACV,KAAK,KAAK,aAAa,KAAK,KAAK,UACnC;AAAA;AAAA,WAEI,KAAI,GAAsC;AAAA,QAC9C,IAAI,KAAK,UAAU;AAAA,UACjB,MAAM,IAAI,UAAU,gCAAgC;AAAA,QACtD;AAAA,QACA,KAAK,WAAW;AAAA,QAChB,MAAM,cAAc,KAAK,aAAa,QAAQ,IAAI,cAAc,IAAI,MAAM;AAAA,QAC1E,OAAO;AAAA,UACL,OAAO,KAAK,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC;AAAA,UAClC,MAAM;AAAA,UACN,MAAM,KAAK,MAAM,UAAU;AAAA,QAC7B;AAAA;AAAA,MAEF,KAAK,GAAmC;AAAA,QACtC,IAAI,KAAK,UAAU;AAAA,UACjB,MAAM,IAAI,UAAU,gCAAgC;AAAA,QACtD;AAAA,QACA,OAAO;AAAA,aACF;AAAA,UACH,cAAc;AAAA,YACZ,SAAS,IAAI,IAAI,KAAK,aAAa,OAAO;AAAA,UAC5C;AAAA,UACA,MAAM,KAAK,OAAO,IAAI,WAAW,KAAK,IAAI,IAAI;AAAA,UAC9C,UAAU;AAAA,QACZ;AAAA;AAAA,WAEI,KAAI,GAAuC;AAAA,QAC/C,IAAI,KAAK,UAAU;AAAA,UACjB,MAAM,IAAI,UAAU,gCAAgC;AAAA,QACtD;AAAA,QACA,KAAK,WAAW;AAAA,QAChB,IAAI,CAAC,KAAK,MAAM;AAAA,UACd,OAAO,KAAK,MAAM,EAAE;AAAA,QACtB;AAAA,QACA,MAAM,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK,IAAI;AAAA,QAC/C,OAAO,KAAK,MAAM,IAAI;AAAA;AAAA,WAElB,KAAI,GAAsC;AAAA,QAC9C,IAAI,KAAK,UAAU;AAAA,UACjB,MAAM,IAAI,UAAU,gCAAgC;AAAA,QACtD;AAAA,QACA,KAAK,WAAW;AAAA,QAChB,IAAI,CAAC,KAAK,MAAM;AAAA,UACd,OAAO;AAAA,QACT;AAAA,QACA,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK,IAAI;AAAA;AAAA,WAErC,SAAQ,GAA6C;AAAA,QACzD,IAAI,KAAK,UAAU;AAAA,UACjB,MAAM,IAAI,UAAU,gCAAgC;AAAA,QACtD;AAAA,QACA,KAAK,WAAW;AAAA,QAChB,IAAI,CAAC,KAAK,MAAM;AAAA,UACd,OAAO,EAAE,SAAS,CAAC,EAAE;AAAA,QACvB;AAAA,QAEA,MAAM,cAAc,KAAK,aAAa,QAAQ,IAAI,cAAc,IAAI,MAAM;AAAA,QAE1E,IAAI,YAAY,SAAS,qBAAqB,GAAG;AAAA,UAC/C,OAAO,wCAAuB,KAAK,MAAM,WAAW;AAAA,QACtD,EAAO,SAAI,YAAY,SAAS,mCAAmC,GAAG;AAAA,UACpE,OAAO,yCAAwB,KAAK,IAAI;AAAA,QAC1C;AAAA,QAEA,MAAM,IAAI,UAAU,qCAAqC;AAAA;AAAA,IAE7D;AAAA,EACF,CAAC;AAAA;AAMH,eAAsB,4BAA4B,CAChD,SACuB;AAAA,EACvB,MAAM,OAAO,QAAQ,OACjB,IAAI,WAAW,MAAM,QAAQ,YAAY,CAAC,IAC1C;AAAA,EAEJ,OAAO;AAAA,IACL,QAAQ,QAAQ;AAAA,IAChB,KAAK,QAAQ;AAAA,IACb,cAAc,4CAA6B,QAAQ,OAAO;AAAA,IAC1D;AAAA,IACA,UAAU;AAAA,IACV,OAAO,QAAQ;AAAA,IACf,aAAa,QAAQ;AAAA,IACrB,aAAa,QAAQ;AAAA,IACrB,WAAW,QAAQ;AAAA,IACnB,WAAW,QAAQ;AAAA,IACnB,MAAM,QAAQ;AAAA,IACd,UAAU,QAAQ;AAAA,IAClB,UAAU,QAAQ;AAAA,IAClB,gBAAgB,QAAQ;AAAA,IACxB,QAAQ;AAAA,EACV;AAAA;",
8
- "debugId": "D1048399CA8D1EB164756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "C39079D8C2092BD064756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/quickjs-fetch",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "type": "commonjs"
5
5
  }
@@ -94,6 +94,8 @@ function setupFetch(context, options = {}) {
94
94
  } else {
95
95
  formDataIteratorResult.value.dispose();
96
96
  }
97
+ import_request.addRequestFormDataMethod(context);
98
+ import_form_data.addFormDataFileMethods(context);
97
99
  const ServerWebSocketClass = import_serve.createServerWebSocketClass(context, stateMap, dispatchWsCommand);
98
100
  context.setProp(context.global, "__ServerWebSocket__", ServerWebSocketClass);
99
101
  ServerWebSocketClass.dispose();
@@ -116,4 +118,4 @@ function setupFetch(context, options = {}) {
116
118
  }
117
119
  })
118
120
 
119
- //# debugId=C5F1D3027B34425964756E2164756E21
121
+ //# debugId=E9774DA93B26BC8B64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/setup.ts"],
4
4
  "sourcesContent": [
5
- "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport { setupCore, createStateMap, createReadableStream } from \"@ricsam/quickjs-core\";\nimport type { SetupFetchOptions, FetchHandle, ServeState } from \"./types.cjs\";\nimport { createHeadersClass } from \"./globals/headers.cjs\";\nimport { createRequestClass } from \"./globals/request.cjs\";\nimport { createResponseClass, addResponseStaticMethods } from \"./globals/response.cjs\";\nimport { setupAbortControllerAndSignal } from \"./globals/abort-controller.cjs\";\nimport { createFormDataClass } from \"./globals/form-data.cjs\";\nimport { createFetchFunction } from \"./globals/fetch.cjs\";\nimport {\n createServeFunction,\n createServerClass,\n createServerWebSocketClass,\n} from \"./globals/serve.cjs\";\nimport { createFetchHandle } from \"./handle.cjs\";\n\n/**\n * Setup Fetch API in a QuickJS context\n *\n * Injects the following globals:\n * - fetch\n * - Request\n * - Response\n * - Headers\n * - AbortController\n * - AbortSignal\n * - serve\n * - FormData\n *\n * Also sets up Core APIs (Streams, Blob, File) if not already present.\n *\n * **Private globals (internal use):**\n * - `__Server__` - Server class for serve() handler, instantiated via evalCode\n * - `__ServerWebSocket__` - WebSocket class for connection handling\n * - `__scheduleTimeout__` - Host function to schedule AbortSignal.timeout()\n * - `__checkTimeout__` - Host function to check if timeout elapsed\n *\n * These private globals follow the `__Name__` convention and are required for\n * JavaScript code in QuickJS to create class instances via evalCode.\n * See PATTERNS.md section 5 for details.\n *\n * @example\n * const handle = setupFetch(context, {\n * onFetch: async (request) => {\n * // Proxy to real fetch\n * return fetch(request);\n * }\n * });\n *\n * context.evalCode(`\n * serve({\n * fetch(request, server) {\n * return new Response(\"Hello!\");\n * }\n * });\n * `);\n *\n * const response = await handle.dispatchRequest(\n * new Request(\"http://localhost/\")\n * );\n */\nexport function setupFetch(\n context: QuickJSContext,\n options: SetupFetchOptions = {}\n): FetchHandle {\n // Setup core if not already done\n const coreHandle =\n options.coreHandle ??\n setupCore(context, {\n stateMap: options.stateMap,\n });\n\n const stateMap = options.stateMap ?? coreHandle.stateMap;\n\n // Create serve state\n const serveState: ServeState = {\n fetchHandler: null,\n websocketHandlers: {},\n pendingUpgrade: null,\n activeConnections: new Map(),\n };\n\n // WebSocket command dispatcher\n const wsCommandCallbacks = new Set<\n (cmd: import(\"./types.cjs\").WebSocketCommand) => void\n >();\n const dispatchWsCommand = (cmd: import(\"./types.cjs\").WebSocketCommand) => {\n for (const cb of wsCommandCallbacks) {\n cb(cmd);\n }\n };\n\n // Create stream factory for Request/Response body\n const streamFactory = (source: UnderlyingSource) =>\n createReadableStream(context, stateMap, source);\n\n // Create Headers class\n const HeadersClass = createHeadersClass(context, stateMap);\n context.setProp(context.global, \"Headers\", HeadersClass);\n HeadersClass.dispose();\n\n // Add Symbol.iterator support for Headers (for...of, Array.from, spread)\n const iteratorResult = context.evalCode(`\n Headers.prototype[Symbol.iterator] = function() {\n return this.entries()[Symbol.iterator]();\n };\n `);\n if (iteratorResult.error) {\n iteratorResult.error.dispose();\n } else {\n iteratorResult.value.dispose();\n }\n\n // Create Request class\n const RequestClass = createRequestClass(context, stateMap, streamFactory);\n context.setProp(context.global, \"Request\", RequestClass);\n RequestClass.dispose();\n\n // Create Response class\n const ResponseClass = createResponseClass(context, stateMap, streamFactory);\n context.setProp(context.global, \"Response\", ResponseClass);\n ResponseClass.dispose();\n\n // Add Response static methods (must be after Response and Headers are on global)\n addResponseStaticMethods(context);\n\n // Create AbortSignal and AbortController classes (pure QuickJS implementation)\n setupAbortControllerAndSignal(context);\n\n // Create FormData class\n const FormDataClass = createFormDataClass(context, stateMap);\n context.setProp(context.global, \"FormData\", FormDataClass);\n FormDataClass.dispose();\n\n // Add Symbol.iterator support for FormData (for...of, Array.from, spread)\n const formDataIteratorResult = context.evalCode(`\n FormData.prototype[Symbol.iterator] = function() {\n return this.entries()[Symbol.iterator]();\n };\n `);\n if (formDataIteratorResult.error) {\n formDataIteratorResult.error.dispose();\n } else {\n formDataIteratorResult.value.dispose();\n }\n\n // Create ServerWebSocket class (internal, for WebSocket handling)\n const ServerWebSocketClass = createServerWebSocketClass(\n context,\n stateMap,\n dispatchWsCommand\n );\n // Set on global with internal name so we can use evalCode to instantiate\n context.setProp(context.global, \"__ServerWebSocket__\", ServerWebSocketClass);\n ServerWebSocketClass.dispose();\n // Note: ServerWebSocketClass handle is now owned by global\n\n // Create Server class (internal, passed to fetch handler)\n const ServerClass = createServerClass(context, stateMap, serveState);\n // Set on global with internal name so we can use evalCode to instantiate\n context.setProp(context.global, \"__Server__\", ServerClass);\n ServerClass.dispose();\n // Note: ServerClass handle is now owned by global\n\n // Create fetch function\n const fetchFn = createFetchFunction(context, options.onFetch);\n context.setProp(context.global, \"fetch\", fetchFn);\n fetchFn.dispose();\n\n // Create serve function\n const serveFn = createServeFunction(context, stateMap, serveState);\n context.setProp(context.global, \"serve\", serveFn);\n serveFn.dispose();\n\n // Create and return the handle\n const fetchHandle = createFetchHandle(\n context,\n stateMap,\n serveState\n );\n\n // Wire up WebSocket command callbacks\n const originalOnWebSocketCommand = fetchHandle.onWebSocketCommand;\n fetchHandle.onWebSocketCommand = (callback) => {\n wsCommandCallbacks.add(callback);\n return () => wsCommandCallbacks.delete(callback);\n };\n\n return fetchHandle;\n}\n"
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport { setupCore, createStateMap, createReadableStream } from \"@ricsam/quickjs-core\";\nimport type { SetupFetchOptions, FetchHandle, ServeState } from \"./types.cjs\";\nimport { createHeadersClass } from \"./globals/headers.cjs\";\nimport { createRequestClass, addRequestFormDataMethod } from \"./globals/request.cjs\";\nimport { createResponseClass, addResponseStaticMethods } from \"./globals/response.cjs\";\nimport { setupAbortControllerAndSignal } from \"./globals/abort-controller.cjs\";\nimport { createFormDataClass, addFormDataFileMethods } from \"./globals/form-data.cjs\";\nimport { createFetchFunction } from \"./globals/fetch.cjs\";\nimport {\n createServeFunction,\n createServerClass,\n createServerWebSocketClass,\n} from \"./globals/serve.cjs\";\nimport { createFetchHandle } from \"./handle.cjs\";\n\n/**\n * Setup Fetch API in a QuickJS context\n *\n * Injects the following globals:\n * - fetch\n * - Request\n * - Response\n * - Headers\n * - AbortController\n * - AbortSignal\n * - serve\n * - FormData\n *\n * Also sets up Core APIs (Streams, Blob, File) if not already present.\n *\n * **Private globals (internal use):**\n * - `__Server__` - Server class for serve() handler, instantiated via evalCode\n * - `__ServerWebSocket__` - WebSocket class for connection handling\n * - `__scheduleTimeout__` - Host function to schedule AbortSignal.timeout()\n * - `__checkTimeout__` - Host function to check if timeout elapsed\n *\n * These private globals follow the `__Name__` convention and are required for\n * JavaScript code in QuickJS to create class instances via evalCode.\n * See PATTERNS.md section 5 for details.\n *\n * @example\n * const handle = setupFetch(context, {\n * onFetch: async (request) => {\n * // Proxy to real fetch\n * return fetch(request);\n * }\n * });\n *\n * context.evalCode(`\n * serve({\n * fetch(request, server) {\n * return new Response(\"Hello!\");\n * }\n * });\n * `);\n *\n * const response = await handle.dispatchRequest(\n * new Request(\"http://localhost/\")\n * );\n */\nexport function setupFetch(\n context: QuickJSContext,\n options: SetupFetchOptions = {}\n): FetchHandle {\n // Setup core if not already done\n const coreHandle =\n options.coreHandle ??\n setupCore(context, {\n stateMap: options.stateMap,\n });\n\n const stateMap = options.stateMap ?? coreHandle.stateMap;\n\n // Create serve state\n const serveState: ServeState = {\n fetchHandler: null,\n websocketHandlers: {},\n pendingUpgrade: null,\n activeConnections: new Map(),\n };\n\n // WebSocket command dispatcher\n const wsCommandCallbacks = new Set<\n (cmd: import(\"./types.cjs\").WebSocketCommand) => void\n >();\n const dispatchWsCommand = (cmd: import(\"./types.cjs\").WebSocketCommand) => {\n for (const cb of wsCommandCallbacks) {\n cb(cmd);\n }\n };\n\n // Create stream factory for Request/Response body\n const streamFactory = (source: UnderlyingSource) =>\n createReadableStream(context, stateMap, source);\n\n // Create Headers class\n const HeadersClass = createHeadersClass(context, stateMap);\n context.setProp(context.global, \"Headers\", HeadersClass);\n HeadersClass.dispose();\n\n // Add Symbol.iterator support for Headers (for...of, Array.from, spread)\n const iteratorResult = context.evalCode(`\n Headers.prototype[Symbol.iterator] = function() {\n return this.entries()[Symbol.iterator]();\n };\n `);\n if (iteratorResult.error) {\n iteratorResult.error.dispose();\n } else {\n iteratorResult.value.dispose();\n }\n\n // Create Request class\n const RequestClass = createRequestClass(context, stateMap, streamFactory);\n context.setProp(context.global, \"Request\", RequestClass);\n RequestClass.dispose();\n\n // Create Response class\n const ResponseClass = createResponseClass(context, stateMap, streamFactory);\n context.setProp(context.global, \"Response\", ResponseClass);\n ResponseClass.dispose();\n\n // Add Response static methods (must be after Response and Headers are on global)\n addResponseStaticMethods(context);\n\n // Create AbortSignal and AbortController classes (pure QuickJS implementation)\n setupAbortControllerAndSignal(context);\n\n // Create FormData class\n const FormDataClass = createFormDataClass(context, stateMap);\n context.setProp(context.global, \"FormData\", FormDataClass);\n FormDataClass.dispose();\n\n // Add Symbol.iterator support for FormData (for...of, Array.from, spread)\n const formDataIteratorResult = context.evalCode(`\n FormData.prototype[Symbol.iterator] = function() {\n return this.entries()[Symbol.iterator]();\n };\n `);\n if (formDataIteratorResult.error) {\n formDataIteratorResult.error.dispose();\n } else {\n formDataIteratorResult.value.dispose();\n }\n\n // Add Request.formData() method that returns a proper FormData instance\n // Must be after both Request and FormData are on global\n addRequestFormDataMethod(context);\n\n // Add FormData.get()/getAll() overrides to reconstruct File instances\n // Must be after both FormData and File are on global\n addFormDataFileMethods(context);\n\n // Create ServerWebSocket class (internal, for WebSocket handling)\n const ServerWebSocketClass = createServerWebSocketClass(\n context,\n stateMap,\n dispatchWsCommand\n );\n // Set on global with internal name so we can use evalCode to instantiate\n context.setProp(context.global, \"__ServerWebSocket__\", ServerWebSocketClass);\n ServerWebSocketClass.dispose();\n // Note: ServerWebSocketClass handle is now owned by global\n\n // Create Server class (internal, passed to fetch handler)\n const ServerClass = createServerClass(context, stateMap, serveState);\n // Set on global with internal name so we can use evalCode to instantiate\n context.setProp(context.global, \"__Server__\", ServerClass);\n ServerClass.dispose();\n // Note: ServerClass handle is now owned by global\n\n // Create fetch function\n const fetchFn = createFetchFunction(context, options.onFetch);\n context.setProp(context.global, \"fetch\", fetchFn);\n fetchFn.dispose();\n\n // Create serve function\n const serveFn = createServeFunction(context, stateMap, serveState);\n context.setProp(context.global, \"serve\", serveFn);\n serveFn.dispose();\n\n // Create and return the handle\n const fetchHandle = createFetchHandle(\n context,\n stateMap,\n serveState\n );\n\n // Wire up WebSocket command callbacks\n const originalOnWebSocketCommand = fetchHandle.onWebSocketCommand;\n fetchHandle.onWebSocketCommand = (callback) => {\n wsCommandCallbacks.add(callback);\n return () => wsCommandCallbacks.delete(callback);\n };\n\n return fetchHandle;\n}\n"
6
6
  ],
7
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACgE,IAAhE;AAEmC,IAAnC;AACmC,IAAnC;AAC8D,IAA9D;AAC8C,IAA9C;AACoC,IAApC;AACoC,IAApC;AAKO,IAJP;AAKkC,IAAlC;AA+CO,SAAS,UAAU,CACxB,SACA,UAA6B,CAAC,GACjB;AAAA,EAEb,MAAM,aACJ,QAAQ,cACR,8BAAU,SAAS;AAAA,IACjB,UAAU,QAAQ;AAAA,EACpB,CAAC;AAAA,EAEH,MAAM,WAAW,QAAQ,YAAY,WAAW;AAAA,EAGhD,MAAM,aAAyB;AAAA,IAC7B,cAAc;AAAA,IACd,mBAAmB,CAAC;AAAA,IACpB,gBAAgB;AAAA,IAChB,mBAAmB,IAAI;AAAA,EACzB;AAAA,EAGA,MAAM,qBAAqB,IAAI;AAAA,EAG/B,MAAM,oBAAoB,CAAC,QAAgD;AAAA,IACzE,WAAW,MAAM,oBAAoB;AAAA,MACnC,GAAG,GAAG;AAAA,IACR;AAAA;AAAA,EAIF,MAAM,gBAAgB,CAAC,WACrB,yCAAqB,SAAS,UAAU,MAAM;AAAA,EAGhD,MAAM,eAAe,kCAAmB,SAAS,QAAQ;AAAA,EACzD,QAAQ,QAAQ,QAAQ,QAAQ,WAAW,YAAY;AAAA,EACvD,aAAa,QAAQ;AAAA,EAGrB,MAAM,iBAAiB,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,GAIvC;AAAA,EACD,IAAI,eAAe,OAAO;AAAA,IACxB,eAAe,MAAM,QAAQ;AAAA,EAC/B,EAAO;AAAA,IACL,eAAe,MAAM,QAAQ;AAAA;AAAA,EAI/B,MAAM,eAAe,kCAAmB,SAAS,UAAU,aAAa;AAAA,EACxE,QAAQ,QAAQ,QAAQ,QAAQ,WAAW,YAAY;AAAA,EACvD,aAAa,QAAQ;AAAA,EAGrB,MAAM,gBAAgB,oCAAoB,SAAS,UAAU,aAAa;AAAA,EAC1E,QAAQ,QAAQ,QAAQ,QAAQ,YAAY,aAAa;AAAA,EACzD,cAAc,QAAQ;AAAA,EAGtB,yCAAyB,OAAO;AAAA,EAGhC,sDAA8B,OAAO;AAAA,EAGrC,MAAM,gBAAgB,qCAAoB,SAAS,QAAQ;AAAA,EAC3D,QAAQ,QAAQ,QAAQ,QAAQ,YAAY,aAAa;AAAA,EACzD,cAAc,QAAQ;AAAA,EAGtB,MAAM,yBAAyB,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,GAI/C;AAAA,EACD,IAAI,uBAAuB,OAAO;AAAA,IAChC,uBAAuB,MAAM,QAAQ;AAAA,EACvC,EAAO;AAAA,IACL,uBAAuB,MAAM,QAAQ;AAAA;AAAA,EAIvC,MAAM,uBAAuB,wCAC3B,SACA,UACA,iBACF;AAAA,EAEA,QAAQ,QAAQ,QAAQ,QAAQ,uBAAuB,oBAAoB;AAAA,EAC3E,qBAAqB,QAAQ;AAAA,EAI7B,MAAM,cAAc,+BAAkB,SAAS,UAAU,UAAU;AAAA,EAEnE,QAAQ,QAAQ,QAAQ,QAAQ,cAAc,WAAW;AAAA,EACzD,YAAY,QAAQ;AAAA,EAIpB,MAAM,UAAU,iCAAoB,SAAS,QAAQ,OAAO;AAAA,EAC5D,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,OAAO;AAAA,EAChD,QAAQ,QAAQ;AAAA,EAGhB,MAAM,UAAU,iCAAoB,SAAS,UAAU,UAAU;AAAA,EACjE,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,OAAO;AAAA,EAChD,QAAQ,QAAQ;AAAA,EAGhB,MAAM,cAAc,gCAClB,SACA,UACA,UACF;AAAA,EAGA,MAAM,6BAA6B,YAAY;AAAA,EAC/C,YAAY,qBAAqB,CAAC,aAAa;AAAA,IAC7C,mBAAmB,IAAI,QAAQ;AAAA,IAC/B,OAAO,MAAM,mBAAmB,OAAO,QAAQ;AAAA;AAAA,EAGjD,OAAO;AAAA;",
8
- "debugId": "C5F1D3027B34425964756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "E9774DA93B26BC8B64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,8 +1,9 @@
1
1
  // @bun
2
2
  // packages/fetch/src/globals/form-data.ts
3
- import { defineClass } from "@ricsam/quickjs-core";
3
+ import { defineClass, isInstanceOf, getClassInstanceState } from "@ricsam/quickjs-core";
4
+ var FORMDATA_FILE_MARKER = "__formDataFile__";
4
5
  function isFileValue(value) {
5
- return value !== null && typeof value === "object" && "data" in value && "filename" in value;
6
+ return value !== null && typeof value === "object" && FORMDATA_FILE_MARKER in value && value[FORMDATA_FILE_MARKER] === true;
6
7
  }
7
8
  function createFormDataClass(context, stateMap) {
8
9
  return defineClass(context, stateMap, {
@@ -13,21 +14,54 @@ function createFormDataClass(context, stateMap) {
13
14
  methods: {
14
15
  append(name, value, filename) {
15
16
  const nameStr = String(name);
17
+ if (isInstanceOf(value, "File")) {
18
+ const fileState = getClassInstanceState(value);
19
+ if (fileState) {
20
+ const data = concatenateParts(fileState.parts);
21
+ const fileValue = {
22
+ [FORMDATA_FILE_MARKER]: true,
23
+ data,
24
+ filename: filename !== undefined ? String(filename) : fileState.name,
25
+ type: fileState.type || "application/octet-stream"
26
+ };
27
+ this.entries.push({ name: nameStr, value: fileValue });
28
+ return;
29
+ }
30
+ }
31
+ if (isInstanceOf(value, "Blob")) {
32
+ const blobState = getClassInstanceState(value);
33
+ if (blobState) {
34
+ const data = concatenateParts(blobState.parts);
35
+ const fileValue = {
36
+ [FORMDATA_FILE_MARKER]: true,
37
+ data,
38
+ filename: filename !== undefined ? String(filename) : "blob",
39
+ type: blobState.type || "application/octet-stream"
40
+ };
41
+ this.entries.push({ name: nameStr, value: fileValue });
42
+ return;
43
+ }
44
+ }
16
45
  if (value && typeof value === "object" && "parts" in value) {
17
46
  const blobLike = value;
18
47
  const data = concatenateParts(blobLike.parts);
19
48
  const fileValue = {
49
+ [FORMDATA_FILE_MARKER]: true,
20
50
  data,
21
51
  filename: filename !== undefined ? String(filename) : blobLike.name || "blob",
22
52
  type: blobLike.type || "application/octet-stream"
23
53
  };
24
54
  this.entries.push({ name: nameStr, value: fileValue });
25
55
  } else if (value && typeof value === "object" && "data" in value && "filename" in value) {
56
+ const fileVal = value;
57
+ const data = Array.isArray(fileVal.data) ? new Uint8Array(fileVal.data) : fileVal.data;
26
58
  this.entries.push({
27
59
  name: nameStr,
28
60
  value: {
29
- ...value,
30
- filename: filename !== undefined ? String(filename) : value.filename
61
+ [FORMDATA_FILE_MARKER]: true,
62
+ data,
63
+ filename: filename !== undefined ? String(filename) : fileVal.filename,
64
+ type: fileVal.type
31
65
  }
32
66
  });
33
67
  } else {
@@ -54,21 +88,54 @@ function createFormDataClass(context, stateMap) {
54
88
  set(name, value, filename) {
55
89
  const nameStr = String(name);
56
90
  this.entries = this.entries.filter((e) => e.name !== nameStr);
91
+ if (isInstanceOf(value, "File")) {
92
+ const fileState = getClassInstanceState(value);
93
+ if (fileState) {
94
+ const data = concatenateParts(fileState.parts);
95
+ const fileValue = {
96
+ [FORMDATA_FILE_MARKER]: true,
97
+ data,
98
+ filename: filename !== undefined ? String(filename) : fileState.name,
99
+ type: fileState.type || "application/octet-stream"
100
+ };
101
+ this.entries.push({ name: nameStr, value: fileValue });
102
+ return;
103
+ }
104
+ }
105
+ if (isInstanceOf(value, "Blob")) {
106
+ const blobState = getClassInstanceState(value);
107
+ if (blobState) {
108
+ const data = concatenateParts(blobState.parts);
109
+ const fileValue = {
110
+ [FORMDATA_FILE_MARKER]: true,
111
+ data,
112
+ filename: filename !== undefined ? String(filename) : "blob",
113
+ type: blobState.type || "application/octet-stream"
114
+ };
115
+ this.entries.push({ name: nameStr, value: fileValue });
116
+ return;
117
+ }
118
+ }
57
119
  if (value && typeof value === "object" && "parts" in value) {
58
120
  const blobLike = value;
59
121
  const data = concatenateParts(blobLike.parts);
60
122
  const fileValue = {
123
+ [FORMDATA_FILE_MARKER]: true,
61
124
  data,
62
125
  filename: filename !== undefined ? String(filename) : blobLike.name || "blob",
63
126
  type: blobLike.type || "application/octet-stream"
64
127
  };
65
128
  this.entries.push({ name: nameStr, value: fileValue });
66
129
  } else if (value && typeof value === "object" && "data" in value && "filename" in value) {
130
+ const fileVal = value;
131
+ const data = Array.isArray(fileVal.data) ? new Uint8Array(fileVal.data) : fileVal.data;
67
132
  this.entries.push({
68
133
  name: nameStr,
69
134
  value: {
70
- ...value,
71
- filename: filename !== undefined ? String(filename) : value.filename
135
+ [FORMDATA_FILE_MARKER]: true,
136
+ data,
137
+ filename: filename !== undefined ? String(filename) : fileVal.filename,
138
+ type: fileVal.type
72
139
  }
73
140
  });
74
141
  } else {
@@ -162,7 +229,7 @@ function parseMultipartFormData(body, contentType) {
162
229
  const type = headers["content-type"] || "application/octet-stream";
163
230
  entries.push({
164
231
  name,
165
- value: { data: content, filename, type }
232
+ value: { [FORMDATA_FILE_MARKER]: true, data: content, filename, type }
166
233
  });
167
234
  } else {
168
235
  entries.push({
@@ -248,11 +315,50 @@ function serializeFormData(state) {
248
315
  contentType: `multipart/form-data; boundary=${boundary}`
249
316
  };
250
317
  }
318
+ function addFormDataFileMethods(context) {
319
+ const result = context.evalCode(`
320
+ (function() {
321
+ const FILE_MARKER = "${FORMDATA_FILE_MARKER}";
322
+
323
+ function toFile(value) {
324
+ if (!value || typeof value !== "object") return value;
325
+ if (value instanceof File) return value;
326
+ if (value[FILE_MARKER] === true) {
327
+ // Reconstruct File from stored data
328
+ const data = Array.isArray(value.data)
329
+ ? new Uint8Array(value.data)
330
+ : value.data;
331
+ return new File([data], value.filename, { type: value.type });
332
+ }
333
+ return value;
334
+ }
335
+
336
+ const originalGet = FormData.prototype.get;
337
+ FormData.prototype.get = function(name) {
338
+ return toFile(originalGet.call(this, name));
339
+ };
340
+
341
+ const originalGetAll = FormData.prototype.getAll;
342
+ FormData.prototype.getAll = function(name) {
343
+ return originalGetAll.call(this, name).map(toFile);
344
+ };
345
+ })();
346
+ `);
347
+ if (result.error) {
348
+ const errorMsg = context.dump(result.error);
349
+ result.error.dispose();
350
+ throw new Error(`Failed to add FormData file methods: ${JSON.stringify(errorMsg)}`);
351
+ } else {
352
+ result.value.dispose();
353
+ }
354
+ }
251
355
  export {
252
356
  serializeFormData,
253
357
  parseUrlEncodedFormData,
254
358
  parseMultipartFormData,
255
- createFormDataClass
359
+ createFormDataClass,
360
+ addFormDataFileMethods,
361
+ FORMDATA_FILE_MARKER
256
362
  };
257
363
 
258
- //# debugId=84B55DCACAA9340664756E2164756E21
364
+ //# debugId=D50F63F639F0720E64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/globals/form-data.ts"],
4
4
  "sourcesContent": [
5
- "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass } from \"@ricsam/quickjs-core\";\n\n/**\n * Internal state for FormData entries\n * Each entry can have multiple values (same key appended multiple times)\n */\nexport interface FormDataEntry {\n name: string;\n value: string | FormDataFileValue;\n}\n\nexport interface FormDataFileValue {\n data: Uint8Array;\n filename: string;\n type: string;\n}\n\nexport interface FormDataState {\n entries: FormDataEntry[];\n}\n\nfunction isFileValue(value: unknown): value is FormDataFileValue {\n return (\n value !== null &&\n typeof value === \"object\" &&\n \"data\" in value &&\n \"filename\" in value\n );\n}\n\n/**\n * Create the FormData class for QuickJS\n */\nexport function createFormDataClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<FormDataState>(context, stateMap, {\n name: \"FormData\",\n construct: () => {\n return { entries: [] };\n },\n methods: {\n append(this: FormDataState, name: unknown, value: unknown, filename?: unknown) {\n const nameStr = String(name);\n\n if (value && typeof value === \"object\" && \"parts\" in value) {\n // Blob-like value\n const blobLike = value as { parts: Uint8Array[]; type?: string; name?: string };\n const data = concatenateParts(blobLike.parts);\n const fileValue: FormDataFileValue = {\n data,\n filename: filename !== undefined ? String(filename) : (blobLike.name || \"blob\"),\n type: blobLike.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n } else if (value && typeof value === \"object\" && \"data\" in value && \"filename\" in value) {\n // Already a FormDataFileValue\n this.entries.push({\n name: nameStr,\n value: {\n ...(value as FormDataFileValue),\n filename: filename !== undefined ? String(filename) : (value as FormDataFileValue).filename,\n },\n });\n } else {\n // String value\n this.entries.push({ name: nameStr, value: String(value) });\n }\n },\n delete(this: FormDataState, name: unknown) {\n const nameStr = String(name);\n this.entries = this.entries.filter((e) => e.name !== nameStr);\n },\n get(this: FormDataState, name: unknown): string | FormDataFileValue | null {\n const nameStr = String(name);\n const entry = this.entries.find((e) => e.name === nameStr);\n return entry ? entry.value : null;\n },\n getAll(this: FormDataState, name: unknown): Array<string | FormDataFileValue> {\n const nameStr = String(name);\n return this.entries\n .filter((e) => e.name === nameStr)\n .map((e) => e.value);\n },\n has(this: FormDataState, name: unknown): boolean {\n const nameStr = String(name);\n return this.entries.some((e) => e.name === nameStr);\n },\n set(this: FormDataState, name: unknown, value: unknown, filename?: unknown) {\n const nameStr = String(name);\n // Remove all existing entries with this name\n this.entries = this.entries.filter((e) => e.name !== nameStr);\n\n // Add the new entry (using append logic)\n if (value && typeof value === \"object\" && \"parts\" in value) {\n const blobLike = value as { parts: Uint8Array[]; type?: string; name?: string };\n const data = concatenateParts(blobLike.parts);\n const fileValue: FormDataFileValue = {\n data,\n filename: filename !== undefined ? String(filename) : (blobLike.name || \"blob\"),\n type: blobLike.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n } else if (value && typeof value === \"object\" && \"data\" in value && \"filename\" in value) {\n this.entries.push({\n name: nameStr,\n value: {\n ...(value as FormDataFileValue),\n filename: filename !== undefined ? String(filename) : (value as FormDataFileValue).filename,\n },\n });\n } else {\n this.entries.push({ name: nameStr, value: String(value) });\n }\n },\n entries(this: FormDataState): Array<[string, string | FormDataFileValue]> {\n return this.entries.map((e) => [e.name, e.value]);\n },\n keys(this: FormDataState): string[] {\n // Return unique keys in order of first appearance\n const seen = new Set<string>();\n const result: string[] = [];\n for (const entry of this.entries) {\n if (!seen.has(entry.name)) {\n seen.add(entry.name);\n result.push(entry.name);\n }\n }\n return result;\n },\n values(this: FormDataState): Array<string | FormDataFileValue> {\n return this.entries.map((e) => e.value);\n },\n forEach(this: FormDataState, callback: unknown) {\n if (typeof callback !== \"function\") {\n throw new TypeError(\"callback must be a function\");\n }\n for (const entry of this.entries) {\n (callback as (value: string | FormDataFileValue, key: string, parent: FormDataState) => void)(\n entry.value,\n entry.name,\n this\n );\n }\n },\n },\n });\n}\n\n/**\n * Concatenate Uint8Arrays into a single Uint8Array\n */\nfunction concatenateParts(parts: Uint8Array[]): Uint8Array {\n const totalLength = parts.reduce((sum, part) => sum + part.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n result.set(part, offset);\n offset += part.length;\n }\n return result;\n}\n\n/**\n * Parse multipart/form-data body\n */\nexport function parseMultipartFormData(\n body: Uint8Array,\n contentType: string\n): FormDataState {\n const entries: FormDataEntry[] = [];\n\n // Extract boundary from content-type\n const boundaryMatch = contentType.match(/boundary=([^;]+)/i);\n if (!boundaryMatch || !boundaryMatch[1]) {\n return { entries };\n }\n\n const boundary = boundaryMatch[1].replace(/^[\"']|[\"']$/g, \"\");\n const boundaryBytes = new TextEncoder().encode(`--${boundary}`);\n const endBoundaryBytes = new TextEncoder().encode(`--${boundary}--`);\n\n // Find all parts\n const decoder = new TextDecoder();\n let pos = 0;\n\n // Skip preamble and first boundary\n pos = findSequence(body, boundaryBytes, pos);\n if (pos === -1) return { entries };\n pos += boundaryBytes.length;\n\n while (pos < body.length) {\n // Skip CRLF after boundary\n if (body[pos] === 0x0d && body[pos + 1] === 0x0a) {\n pos += 2;\n } else if (body[pos] === 0x0a) {\n pos += 1;\n }\n\n // Check for end boundary\n if (pos + 2 <= body.length && body[pos] === 0x2d && body[pos + 1] === 0x2d) {\n break; // End of multipart\n }\n\n // Parse headers\n const headersEnd = findSequence(body, new Uint8Array([0x0d, 0x0a, 0x0d, 0x0a]), pos);\n if (headersEnd === -1) break;\n\n const headersText = decoder.decode(body.slice(pos, headersEnd));\n const headers = parseHeaders(headersText);\n pos = headersEnd + 4;\n\n // Find next boundary\n const nextBoundary = findSequence(body, boundaryBytes, pos);\n if (nextBoundary === -1) break;\n\n // Content is between current position and next boundary (minus CRLF)\n let contentEnd = nextBoundary;\n if (contentEnd > 0 && body[contentEnd - 1] === 0x0a) contentEnd--;\n if (contentEnd > 0 && body[contentEnd - 1] === 0x0d) contentEnd--;\n\n const content = body.slice(pos, contentEnd);\n\n // Parse Content-Disposition header\n const disposition = headers[\"content-disposition\"] || \"\";\n const nameMatch = disposition.match(/name=\"([^\"]+)\"/);\n const filenameMatch = disposition.match(/filename=\"([^\"]+)\"/);\n\n if (nameMatch && nameMatch[1]) {\n const name = nameMatch[1];\n if (filenameMatch && filenameMatch[1]) {\n // File entry\n const filename = filenameMatch[1];\n const type = headers[\"content-type\"] || \"application/octet-stream\";\n entries.push({\n name,\n value: { data: content, filename, type },\n });\n } else {\n // String entry\n entries.push({\n name,\n value: decoder.decode(content),\n });\n }\n }\n\n pos = nextBoundary + boundaryBytes.length;\n }\n\n return { entries };\n}\n\n/**\n * Parse URL-encoded form data\n */\nexport function parseUrlEncodedFormData(body: Uint8Array): FormDataState {\n const text = new TextDecoder().decode(body);\n const entries: FormDataEntry[] = [];\n\n const params = new URLSearchParams(text);\n for (const [name, value] of params) {\n entries.push({ name, value });\n }\n\n return { entries };\n}\n\nfunction findSequence(haystack: Uint8Array, needle: Uint8Array, start: number): number {\n outer: for (let i = start; i <= haystack.length - needle.length; i++) {\n for (let j = 0; j < needle.length; j++) {\n if (haystack[i + j] !== needle[j]) continue outer;\n }\n return i;\n }\n return -1;\n}\n\nfunction parseHeaders(text: string): Record<string, string> {\n const headers: Record<string, string> = {};\n const lines = text.split(/\\r?\\n/);\n for (const line of lines) {\n const colonIndex = line.indexOf(\":\");\n if (colonIndex > 0) {\n const name = line.slice(0, colonIndex).trim().toLowerCase();\n const value = line.slice(colonIndex + 1).trim();\n headers[name] = value;\n }\n }\n return headers;\n}\n\n/**\n * Serialize FormData to multipart/form-data format\n */\nexport function serializeFormData(state: FormDataState): { body: Uint8Array; contentType: string } {\n const boundary = `----FormDataBoundary${Math.random().toString(36).slice(2)}`;\n const encoder = new TextEncoder();\n const parts: Uint8Array[] = [];\n\n for (const entry of state.entries) {\n const headerLines: string[] = [];\n headerLines.push(`--${boundary}`);\n\n if (isFileValue(entry.value)) {\n headerLines.push(\n `Content-Disposition: form-data; name=\"${entry.name}\"; filename=\"${entry.value.filename}\"`\n );\n headerLines.push(`Content-Type: ${entry.value.type}`);\n headerLines.push(\"\");\n\n parts.push(encoder.encode(headerLines.join(\"\\r\\n\") + \"\\r\\n\"));\n parts.push(entry.value.data);\n parts.push(encoder.encode(\"\\r\\n\"));\n } else {\n headerLines.push(`Content-Disposition: form-data; name=\"${entry.name}\"`);\n headerLines.push(\"\");\n headerLines.push(entry.value);\n\n parts.push(encoder.encode(headerLines.join(\"\\r\\n\") + \"\\r\\n\"));\n }\n }\n\n parts.push(encoder.encode(`--${boundary}--\\r\\n`));\n\n // Concatenate all parts\n const totalLength = parts.reduce((sum, part) => sum + part.length, 0);\n const body = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n body.set(part, offset);\n offset += part.length;\n }\n\n return {\n body,\n contentType: `multipart/form-data; boundary=${boundary}`,\n };\n}\n"
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass, isInstanceOf, getClassInstanceState } from \"@ricsam/quickjs-core\";\n\n/**\n * Marker to identify FormData file entries that need File reconstruction\n */\nexport const FORMDATA_FILE_MARKER = \"__formDataFile__\";\n\n/**\n * Internal state for Blob/File classes (from packages/core)\n */\ninterface BlobInternalState {\n parts: Uint8Array[];\n type: string;\n size: number;\n}\n\ninterface FileInternalState extends BlobInternalState {\n name: string;\n lastModified: number;\n webkitRelativePath: string;\n}\n\n/**\n * Internal state for FormData entries\n * Each entry can have multiple values (same key appended multiple times)\n */\nexport interface FormDataEntry {\n name: string;\n value: string | FormDataFileValue;\n}\n\nexport interface FormDataFileValue {\n [FORMDATA_FILE_MARKER]: true;\n data: Uint8Array;\n filename: string;\n type: string;\n}\n\nexport interface FormDataState {\n entries: FormDataEntry[];\n}\n\nfunction isFileValue(value: unknown): value is FormDataFileValue {\n return (\n value !== null &&\n typeof value === \"object\" &&\n FORMDATA_FILE_MARKER in value &&\n (value as FormDataFileValue)[FORMDATA_FILE_MARKER] === true\n );\n}\n\n/**\n * Create the FormData class for QuickJS\n */\nexport function createFormDataClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<FormDataState>(context, stateMap, {\n name: \"FormData\",\n construct: () => {\n return { entries: [] };\n },\n methods: {\n append(this: FormDataState, name: unknown, value: unknown, filename?: unknown) {\n const nameStr = String(name);\n\n // Check for File instance using class identity (preferred method)\n if (isInstanceOf(value, \"File\")) {\n const fileState = getClassInstanceState<FileInternalState>(value);\n if (fileState) {\n const data = concatenateParts(fileState.parts);\n const fileValue: FormDataFileValue = {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : fileState.name,\n type: fileState.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n return;\n }\n }\n\n // Check for Blob instance using class identity\n if (isInstanceOf(value, \"Blob\")) {\n const blobState = getClassInstanceState<BlobInternalState>(value);\n if (blobState) {\n const data = concatenateParts(blobState.parts);\n const fileValue: FormDataFileValue = {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : \"blob\",\n type: blobState.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n return;\n }\n }\n\n // Fallback: duck-typing for Blob-like objects (backwards compatibility)\n if (value && typeof value === \"object\" && \"parts\" in value) {\n const blobLike = value as { parts: Uint8Array[]; type?: string; name?: string };\n const data = concatenateParts(blobLike.parts);\n const fileValue: FormDataFileValue = {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : (blobLike.name || \"blob\"),\n type: blobLike.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n } else if (value && typeof value === \"object\" && \"data\" in value && \"filename\" in value) {\n // Already a FormDataFileValue (or similar structure with data, filename, type)\n const fileVal = value as { data: Uint8Array | number[]; filename: string; type: string };\n // Handle both Uint8Array and number array (for safe cross-context marshalling)\n const data = Array.isArray(fileVal.data)\n ? new Uint8Array(fileVal.data)\n : fileVal.data;\n this.entries.push({\n name: nameStr,\n value: {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : fileVal.filename,\n type: fileVal.type,\n },\n });\n } else {\n // String value\n this.entries.push({ name: nameStr, value: String(value) });\n }\n },\n delete(this: FormDataState, name: unknown) {\n const nameStr = String(name);\n this.entries = this.entries.filter((e) => e.name !== nameStr);\n },\n get(this: FormDataState, name: unknown): string | FormDataFileValue | null {\n const nameStr = String(name);\n const entry = this.entries.find((e) => e.name === nameStr);\n return entry ? entry.value : null;\n },\n getAll(this: FormDataState, name: unknown): Array<string | FormDataFileValue> {\n const nameStr = String(name);\n return this.entries\n .filter((e) => e.name === nameStr)\n .map((e) => e.value);\n },\n has(this: FormDataState, name: unknown): boolean {\n const nameStr = String(name);\n return this.entries.some((e) => e.name === nameStr);\n },\n set(this: FormDataState, name: unknown, value: unknown, filename?: unknown) {\n const nameStr = String(name);\n // Remove all existing entries with this name\n this.entries = this.entries.filter((e) => e.name !== nameStr);\n\n // Check for File instance using class identity (preferred method)\n if (isInstanceOf(value, \"File\")) {\n const fileState = getClassInstanceState<FileInternalState>(value);\n if (fileState) {\n const data = concatenateParts(fileState.parts);\n const fileValue: FormDataFileValue = {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : fileState.name,\n type: fileState.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n return;\n }\n }\n\n // Check for Blob instance using class identity\n if (isInstanceOf(value, \"Blob\")) {\n const blobState = getClassInstanceState<BlobInternalState>(value);\n if (blobState) {\n const data = concatenateParts(blobState.parts);\n const fileValue: FormDataFileValue = {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : \"blob\",\n type: blobState.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n return;\n }\n }\n\n // Fallback: duck-typing for Blob-like objects (backwards compatibility)\n if (value && typeof value === \"object\" && \"parts\" in value) {\n const blobLike = value as { parts: Uint8Array[]; type?: string; name?: string };\n const data = concatenateParts(blobLike.parts);\n const fileValue: FormDataFileValue = {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : (blobLike.name || \"blob\"),\n type: blobLike.type || \"application/octet-stream\",\n };\n this.entries.push({ name: nameStr, value: fileValue });\n } else if (value && typeof value === \"object\" && \"data\" in value && \"filename\" in value) {\n // Already a FormDataFileValue (or similar structure with data, filename, type)\n const fileVal = value as { data: Uint8Array | number[]; filename: string; type: string };\n // Handle both Uint8Array and number array (for safe cross-context marshalling)\n const data = Array.isArray(fileVal.data)\n ? new Uint8Array(fileVal.data)\n : fileVal.data;\n this.entries.push({\n name: nameStr,\n value: {\n [FORMDATA_FILE_MARKER]: true,\n data,\n filename: filename !== undefined ? String(filename) : fileVal.filename,\n type: fileVal.type,\n },\n });\n } else {\n this.entries.push({ name: nameStr, value: String(value) });\n }\n },\n entries(this: FormDataState): Array<[string, string | FormDataFileValue]> {\n return this.entries.map((e) => [e.name, e.value]);\n },\n keys(this: FormDataState): string[] {\n // Return unique keys in order of first appearance\n const seen = new Set<string>();\n const result: string[] = [];\n for (const entry of this.entries) {\n if (!seen.has(entry.name)) {\n seen.add(entry.name);\n result.push(entry.name);\n }\n }\n return result;\n },\n values(this: FormDataState): Array<string | FormDataFileValue> {\n return this.entries.map((e) => e.value);\n },\n forEach(this: FormDataState, callback: unknown) {\n if (typeof callback !== \"function\") {\n throw new TypeError(\"callback must be a function\");\n }\n for (const entry of this.entries) {\n (callback as (value: string | FormDataFileValue, key: string, parent: FormDataState) => void)(\n entry.value,\n entry.name,\n this\n );\n }\n },\n },\n });\n}\n\n/**\n * Concatenate Uint8Arrays into a single Uint8Array\n */\nfunction concatenateParts(parts: Uint8Array[]): Uint8Array {\n const totalLength = parts.reduce((sum, part) => sum + part.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n result.set(part, offset);\n offset += part.length;\n }\n return result;\n}\n\n/**\n * Parse multipart/form-data body\n */\nexport function parseMultipartFormData(\n body: Uint8Array,\n contentType: string\n): FormDataState {\n const entries: FormDataEntry[] = [];\n\n // Extract boundary from content-type\n const boundaryMatch = contentType.match(/boundary=([^;]+)/i);\n if (!boundaryMatch || !boundaryMatch[1]) {\n return { entries };\n }\n\n const boundary = boundaryMatch[1].replace(/^[\"']|[\"']$/g, \"\");\n const boundaryBytes = new TextEncoder().encode(`--${boundary}`);\n const endBoundaryBytes = new TextEncoder().encode(`--${boundary}--`);\n\n // Find all parts\n const decoder = new TextDecoder();\n let pos = 0;\n\n // Skip preamble and first boundary\n pos = findSequence(body, boundaryBytes, pos);\n if (pos === -1) return { entries };\n pos += boundaryBytes.length;\n\n while (pos < body.length) {\n // Skip CRLF after boundary\n if (body[pos] === 0x0d && body[pos + 1] === 0x0a) {\n pos += 2;\n } else if (body[pos] === 0x0a) {\n pos += 1;\n }\n\n // Check for end boundary\n if (pos + 2 <= body.length && body[pos] === 0x2d && body[pos + 1] === 0x2d) {\n break; // End of multipart\n }\n\n // Parse headers\n const headersEnd = findSequence(body, new Uint8Array([0x0d, 0x0a, 0x0d, 0x0a]), pos);\n if (headersEnd === -1) break;\n\n const headersText = decoder.decode(body.slice(pos, headersEnd));\n const headers = parseHeaders(headersText);\n pos = headersEnd + 4;\n\n // Find next boundary\n const nextBoundary = findSequence(body, boundaryBytes, pos);\n if (nextBoundary === -1) break;\n\n // Content is between current position and next boundary (minus CRLF)\n let contentEnd = nextBoundary;\n if (contentEnd > 0 && body[contentEnd - 1] === 0x0a) contentEnd--;\n if (contentEnd > 0 && body[contentEnd - 1] === 0x0d) contentEnd--;\n\n const content = body.slice(pos, contentEnd);\n\n // Parse Content-Disposition header\n const disposition = headers[\"content-disposition\"] || \"\";\n const nameMatch = disposition.match(/name=\"([^\"]+)\"/);\n const filenameMatch = disposition.match(/filename=\"([^\"]+)\"/);\n\n if (nameMatch && nameMatch[1]) {\n const name = nameMatch[1];\n if (filenameMatch && filenameMatch[1]) {\n // File entry\n const filename = filenameMatch[1];\n const type = headers[\"content-type\"] || \"application/octet-stream\";\n entries.push({\n name,\n value: { [FORMDATA_FILE_MARKER]: true, data: content, filename, type },\n });\n } else {\n // String entry\n entries.push({\n name,\n value: decoder.decode(content),\n });\n }\n }\n\n pos = nextBoundary + boundaryBytes.length;\n }\n\n return { entries };\n}\n\n/**\n * Parse URL-encoded form data\n */\nexport function parseUrlEncodedFormData(body: Uint8Array): FormDataState {\n const text = new TextDecoder().decode(body);\n const entries: FormDataEntry[] = [];\n\n const params = new URLSearchParams(text);\n for (const [name, value] of params) {\n entries.push({ name, value });\n }\n\n return { entries };\n}\n\nfunction findSequence(haystack: Uint8Array, needle: Uint8Array, start: number): number {\n outer: for (let i = start; i <= haystack.length - needle.length; i++) {\n for (let j = 0; j < needle.length; j++) {\n if (haystack[i + j] !== needle[j]) continue outer;\n }\n return i;\n }\n return -1;\n}\n\nfunction parseHeaders(text: string): Record<string, string> {\n const headers: Record<string, string> = {};\n const lines = text.split(/\\r?\\n/);\n for (const line of lines) {\n const colonIndex = line.indexOf(\":\");\n if (colonIndex > 0) {\n const name = line.slice(0, colonIndex).trim().toLowerCase();\n const value = line.slice(colonIndex + 1).trim();\n headers[name] = value;\n }\n }\n return headers;\n}\n\n/**\n * Serialize FormData to multipart/form-data format\n */\nexport function serializeFormData(state: FormDataState): { body: Uint8Array; contentType: string } {\n const boundary = `----FormDataBoundary${Math.random().toString(36).slice(2)}`;\n const encoder = new TextEncoder();\n const parts: Uint8Array[] = [];\n\n for (const entry of state.entries) {\n const headerLines: string[] = [];\n headerLines.push(`--${boundary}`);\n\n if (isFileValue(entry.value)) {\n headerLines.push(\n `Content-Disposition: form-data; name=\"${entry.name}\"; filename=\"${entry.value.filename}\"`\n );\n headerLines.push(`Content-Type: ${entry.value.type}`);\n headerLines.push(\"\");\n\n parts.push(encoder.encode(headerLines.join(\"\\r\\n\") + \"\\r\\n\"));\n parts.push(entry.value.data);\n parts.push(encoder.encode(\"\\r\\n\"));\n } else {\n headerLines.push(`Content-Disposition: form-data; name=\"${entry.name}\"`);\n headerLines.push(\"\");\n headerLines.push(entry.value);\n\n parts.push(encoder.encode(headerLines.join(\"\\r\\n\") + \"\\r\\n\"));\n }\n }\n\n parts.push(encoder.encode(`--${boundary}--\\r\\n`));\n\n // Concatenate all parts\n const totalLength = parts.reduce((sum, part) => sum + part.length, 0);\n const body = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n body.set(part, offset);\n offset += part.length;\n }\n\n return {\n body,\n contentType: `multipart/form-data; boundary=${boundary}`,\n };\n}\n\n/**\n * Add JavaScript overrides for FormData.get() and FormData.getAll() to reconstruct File instances\n *\n * This is needed because defineClass methods can only return plain objects when marshalling,\n * but we want formData.get(\"file\") to return actual File instances with working methods.\n *\n * @param context The QuickJS context (must have FormData and File classes already defined)\n */\nexport function addFormDataFileMethods(context: QuickJSContext): void {\n const result = context.evalCode(`\n (function() {\n const FILE_MARKER = \"${FORMDATA_FILE_MARKER}\";\n\n function toFile(value) {\n if (!value || typeof value !== \"object\") return value;\n if (value instanceof File) return value;\n if (value[FILE_MARKER] === true) {\n // Reconstruct File from stored data\n const data = Array.isArray(value.data)\n ? new Uint8Array(value.data)\n : value.data;\n return new File([data], value.filename, { type: value.type });\n }\n return value;\n }\n\n const originalGet = FormData.prototype.get;\n FormData.prototype.get = function(name) {\n return toFile(originalGet.call(this, name));\n };\n\n const originalGetAll = FormData.prototype.getAll;\n FormData.prototype.getAll = function(name) {\n return originalGetAll.call(this, name).map(toFile);\n };\n })();\n `);\n if (result.error) {\n const errorMsg = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to add FormData file methods: ${JSON.stringify(errorMsg)}`);\n } else {\n result.value.dispose();\n }\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "84B55DCACAA9340664756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "D50F63F639F0720E64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -237,7 +237,7 @@ function createRequestClass(context, stateMap, createStream) {
237
237
  }
238
238
  return new TextDecoder().decode(this.body);
239
239
  },
240
- async formData() {
240
+ async __getFormDataEntries__() {
241
241
  if (this.bodyUsed) {
242
242
  throw new TypeError("Body has already been consumed");
243
243
  }
@@ -246,16 +246,60 @@ function createRequestClass(context, stateMap, createStream) {
246
246
  return { entries: [] };
247
247
  }
248
248
  const contentType = this.headersState.headers.get("content-type")?.[0] || "";
249
+ let formDataState;
249
250
  if (contentType.includes("multipart/form-data")) {
250
- return parseMultipartFormData(this.body, contentType);
251
+ formDataState = parseMultipartFormData(this.body, contentType);
251
252
  } else if (contentType.includes("application/x-www-form-urlencoded")) {
252
- return parseUrlEncodedFormData(this.body);
253
+ formDataState = parseUrlEncodedFormData(this.body);
254
+ } else {
255
+ throw new TypeError("Could not parse content as FormData");
253
256
  }
254
- throw new TypeError("Could not parse content as FormData");
257
+ return {
258
+ entries: formDataState.entries.map((entry) => {
259
+ if (typeof entry.value === "string") {
260
+ return { name: entry.name, value: entry.value };
261
+ }
262
+ return {
263
+ name: entry.name,
264
+ value: {
265
+ __formDataFile__: true,
266
+ data: Array.from(entry.value.data),
267
+ filename: entry.value.filename,
268
+ type: entry.value.type
269
+ }
270
+ };
271
+ })
272
+ };
255
273
  }
256
274
  }
257
275
  });
258
276
  }
277
+ function addRequestFormDataMethod(context) {
278
+ const result = context.evalCode(`
279
+ Request.prototype.formData = async function() {
280
+ // Get raw entries from private method
281
+ // Note: File data comes as plain number arrays (converted in host side)
282
+ const rawData = await this.__getFormDataEntries__();
283
+
284
+ // Create a proper FormData instance
285
+ const formData = new FormData();
286
+
287
+ // Populate with entries
288
+ // FormData.append handles both string values and file-like objects
289
+ // with number arrays (converted to Uint8Array on the host side)
290
+ for (const entry of rawData.entries) {
291
+ formData.append(entry.name, entry.value);
292
+ }
293
+
294
+ return formData;
295
+ };
296
+ `);
297
+ if (result.error) {
298
+ result.error.dispose();
299
+ } else {
300
+ result.value.dispose();
301
+ }
302
+ }
259
303
  async function createRequestStateFromNative(request) {
260
304
  const body = request.body ? new Uint8Array(await request.arrayBuffer()) : null;
261
305
  return {
@@ -278,7 +322,8 @@ async function createRequestStateFromNative(request) {
278
322
  }
279
323
  export {
280
324
  createRequestStateFromNative,
281
- createRequestClass
325
+ createRequestClass,
326
+ addRequestFormDataMethod
282
327
  };
283
328
 
284
- //# debugId=0046C87C5631304864756E2164756E21
329
+ //# debugId=9CDFB08BC3F7DEBF64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/globals/request.ts"],
4
4
  "sourcesContent": [
5
- "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass } from \"@ricsam/quickjs-core\";\nimport type { RequestState, HeadersState, AbortSignalState, FormDataState } from \"../types.mjs\";\nimport { createHeadersStateFromNative, createHeadersLike } from \"./headers.mjs\";\nimport { parseMultipartFormData, parseUrlEncodedFormData } from \"./form-data.mjs\";\n\n/**\n * Type for the stream factory function\n */\ntype StreamFactory = (source: UnderlyingSource) => QuickJSHandle;\n\n/**\n * Create the Request class for QuickJS\n */\nexport function createRequestClass(\n context: QuickJSContext,\n stateMap: StateMap,\n createStream?: StreamFactory\n): QuickJSHandle {\n return defineClass<RequestState>(context, stateMap, {\n name: \"Request\",\n construct: (args) => {\n const input = args[0];\n const init = args[1] as {\n method?: string;\n headers?: object;\n body?: unknown;\n cache?: string;\n credentials?: string;\n integrity?: string;\n keepalive?: boolean;\n mode?: string;\n redirect?: string;\n referrer?: string;\n referrerPolicy?: string;\n signal?: AbortSignalState;\n } | undefined;\n\n let url = \"\";\n let method = \"GET\";\n let headersState: HeadersState = { headers: new Map() };\n let body: Uint8Array | null = null;\n let signal: AbortSignalState | null = null;\n\n // Handle input\n if (typeof input === \"string\") {\n url = input;\n } else if (input && typeof input === \"object\") {\n // Could be URL or Request-like\n if (\"url\" in input) {\n url = String((input as { url: string }).url);\n }\n if (\"method\" in input) {\n method = String((input as { method: string }).method);\n }\n if (\"headersState\" in input) {\n const inputHeaders = (input as RequestState).headersState;\n headersState = {\n headers: new Map(inputHeaders.headers),\n };\n }\n if (\"body\" in input && (input as RequestState).body) {\n body = (input as RequestState).body;\n }\n if (\"signal\" in input) {\n signal = (input as RequestState).signal;\n }\n }\n\n // Apply init options\n if (init) {\n if (init.method) {\n method = init.method.toUpperCase();\n }\n if (init.headers) {\n if (init.headers && typeof init.headers === \"object\") {\n if (\"headers\" in init.headers && init.headers.headers instanceof Map) {\n headersState = {\n headers: new Map((init.headers as HeadersState).headers),\n };\n } else {\n headersState = { headers: new Map() };\n for (const [key, value] of Object.entries(init.headers)) {\n headersState.headers.set(key.toLowerCase(), [String(value)]);\n }\n }\n }\n }\n if (init.body !== undefined && init.body !== null) {\n if (typeof init.body === \"string\") {\n body = new TextEncoder().encode(init.body);\n } else if (init.body instanceof ArrayBuffer) {\n body = new Uint8Array(init.body);\n } else if (init.body instanceof Uint8Array) {\n body = init.body;\n }\n }\n if (init.signal) {\n signal = init.signal;\n }\n }\n\n return {\n method,\n url,\n headersState,\n body,\n bodyUsed: false,\n cache: init?.cache || \"default\",\n credentials: init?.credentials || \"same-origin\",\n destination: \"\",\n integrity: init?.integrity || \"\",\n keepalive: init?.keepalive || false,\n mode: init?.mode || \"cors\",\n redirect: init?.redirect || \"follow\",\n referrer: init?.referrer || \"about:client\",\n referrerPolicy: init?.referrerPolicy || \"\",\n signal,\n };\n },\n properties: {\n method: {\n get(this: RequestState) {\n return this.method;\n },\n },\n url: {\n get(this: RequestState) {\n return this.url;\n },\n },\n headers: {\n get(this: RequestState) {\n return createHeadersLike(this.headersState);\n },\n },\n body: {\n get(this: RequestState) {\n if (!this.body) return null;\n if (!createStream) {\n // Fallback: return raw body if no stream factory\n return this.body;\n }\n // Create a ReadableStream from the body data\n const bodyData = this.body;\n let offset = 0;\n const chunkSize = 65536; // 64KB chunks\n return createStream({\n pull(controller) {\n if (offset >= bodyData.length) {\n controller.close();\n return;\n }\n const chunk = bodyData.slice(offset, Math.min(offset + chunkSize, bodyData.length));\n offset += chunk.length;\n controller.enqueue(chunk);\n },\n });\n },\n },\n bodyUsed: {\n get(this: RequestState) {\n return this.bodyUsed;\n },\n },\n cache: {\n get(this: RequestState) {\n return this.cache;\n },\n },\n credentials: {\n get(this: RequestState) {\n return this.credentials;\n },\n },\n destination: {\n get(this: RequestState) {\n return this.destination;\n },\n },\n integrity: {\n get(this: RequestState) {\n return this.integrity;\n },\n },\n keepalive: {\n get(this: RequestState) {\n return this.keepalive;\n },\n },\n mode: {\n get(this: RequestState) {\n return this.mode;\n },\n },\n redirect: {\n get(this: RequestState) {\n return this.redirect;\n },\n },\n referrer: {\n get(this: RequestState) {\n return this.referrer;\n },\n },\n referrerPolicy: {\n get(this: RequestState) {\n return this.referrerPolicy;\n },\n },\n signal: {\n get(this: RequestState) {\n return this.signal;\n },\n },\n },\n methods: {\n async arrayBuffer(this: RequestState): Promise<ArrayBuffer> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return new ArrayBuffer(0);\n }\n return this.body.buffer.slice(\n this.body.byteOffset,\n this.body.byteOffset + this.body.byteLength\n ) as ArrayBuffer;\n },\n async blob(this: RequestState): Promise<object> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n return {\n parts: this.body ? [this.body] : [],\n type: contentType,\n size: this.body?.length || 0,\n };\n },\n clone(this: RequestState): RequestState {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n return {\n ...this,\n headersState: {\n headers: new Map(this.headersState.headers),\n },\n body: this.body ? new Uint8Array(this.body) : null,\n bodyUsed: false,\n };\n },\n async json(this: RequestState): Promise<unknown> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return JSON.parse(\"\");\n }\n const text = new TextDecoder().decode(this.body);\n return JSON.parse(text);\n },\n async text(this: RequestState): Promise<string> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return \"\";\n }\n return new TextDecoder().decode(this.body);\n },\n async formData(this: RequestState): Promise<FormDataState> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return { entries: [] };\n }\n\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n\n if (contentType.includes(\"multipart/form-data\")) {\n return parseMultipartFormData(this.body, contentType);\n } else if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n return parseUrlEncodedFormData(this.body);\n }\n\n throw new TypeError(\"Could not parse content as FormData\");\n },\n },\n });\n}\n\n/**\n * Create a RequestState from a native Request object\n */\nexport async function createRequestStateFromNative(\n request: Request\n): Promise<RequestState> {\n const body = request.body\n ? new Uint8Array(await request.arrayBuffer())\n : null;\n\n return {\n method: request.method,\n url: request.url,\n headersState: createHeadersStateFromNative(request.headers),\n body,\n bodyUsed: false,\n cache: request.cache,\n credentials: request.credentials,\n destination: request.destination,\n integrity: request.integrity,\n keepalive: request.keepalive,\n mode: request.mode,\n redirect: request.redirect,\n referrer: request.referrer,\n referrerPolicy: request.referrerPolicy,\n signal: null, // Signal handling is complex, simplified here\n };\n}\n"
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass } from \"@ricsam/quickjs-core\";\nimport type { RequestState, HeadersState, AbortSignalState, FormDataState } from \"../types.mjs\";\nimport { createHeadersStateFromNative, createHeadersLike } from \"./headers.mjs\";\nimport { parseMultipartFormData, parseUrlEncodedFormData } from \"./form-data.mjs\";\n\n/**\n * Type for the stream factory function\n */\ntype StreamFactory = (source: UnderlyingSource) => QuickJSHandle;\n\n/**\n * Create the Request class for QuickJS\n */\nexport function createRequestClass(\n context: QuickJSContext,\n stateMap: StateMap,\n createStream?: StreamFactory\n): QuickJSHandle {\n return defineClass<RequestState>(context, stateMap, {\n name: \"Request\",\n construct: (args) => {\n const input = args[0];\n const init = args[1] as {\n method?: string;\n headers?: object;\n body?: unknown;\n cache?: string;\n credentials?: string;\n integrity?: string;\n keepalive?: boolean;\n mode?: string;\n redirect?: string;\n referrer?: string;\n referrerPolicy?: string;\n signal?: AbortSignalState;\n } | undefined;\n\n let url = \"\";\n let method = \"GET\";\n let headersState: HeadersState = { headers: new Map() };\n let body: Uint8Array | null = null;\n let signal: AbortSignalState | null = null;\n\n // Handle input\n if (typeof input === \"string\") {\n url = input;\n } else if (input && typeof input === \"object\") {\n // Could be URL or Request-like\n if (\"url\" in input) {\n url = String((input as { url: string }).url);\n }\n if (\"method\" in input) {\n method = String((input as { method: string }).method);\n }\n if (\"headersState\" in input) {\n const inputHeaders = (input as RequestState).headersState;\n headersState = {\n headers: new Map(inputHeaders.headers),\n };\n }\n if (\"body\" in input && (input as RequestState).body) {\n body = (input as RequestState).body;\n }\n if (\"signal\" in input) {\n signal = (input as RequestState).signal;\n }\n }\n\n // Apply init options\n if (init) {\n if (init.method) {\n method = init.method.toUpperCase();\n }\n if (init.headers) {\n if (init.headers && typeof init.headers === \"object\") {\n if (\"headers\" in init.headers && init.headers.headers instanceof Map) {\n headersState = {\n headers: new Map((init.headers as HeadersState).headers),\n };\n } else {\n headersState = { headers: new Map() };\n for (const [key, value] of Object.entries(init.headers)) {\n headersState.headers.set(key.toLowerCase(), [String(value)]);\n }\n }\n }\n }\n if (init.body !== undefined && init.body !== null) {\n if (typeof init.body === \"string\") {\n body = new TextEncoder().encode(init.body);\n } else if (init.body instanceof ArrayBuffer) {\n body = new Uint8Array(init.body);\n } else if (init.body instanceof Uint8Array) {\n body = init.body;\n }\n }\n if (init.signal) {\n signal = init.signal;\n }\n }\n\n return {\n method,\n url,\n headersState,\n body,\n bodyUsed: false,\n cache: init?.cache || \"default\",\n credentials: init?.credentials || \"same-origin\",\n destination: \"\",\n integrity: init?.integrity || \"\",\n keepalive: init?.keepalive || false,\n mode: init?.mode || \"cors\",\n redirect: init?.redirect || \"follow\",\n referrer: init?.referrer || \"about:client\",\n referrerPolicy: init?.referrerPolicy || \"\",\n signal,\n };\n },\n properties: {\n method: {\n get(this: RequestState) {\n return this.method;\n },\n },\n url: {\n get(this: RequestState) {\n return this.url;\n },\n },\n headers: {\n get(this: RequestState) {\n return createHeadersLike(this.headersState);\n },\n },\n body: {\n get(this: RequestState) {\n if (!this.body) return null;\n if (!createStream) {\n // Fallback: return raw body if no stream factory\n return this.body;\n }\n // Create a ReadableStream from the body data\n const bodyData = this.body;\n let offset = 0;\n const chunkSize = 65536; // 64KB chunks\n return createStream({\n pull(controller) {\n if (offset >= bodyData.length) {\n controller.close();\n return;\n }\n const chunk = bodyData.slice(offset, Math.min(offset + chunkSize, bodyData.length));\n offset += chunk.length;\n controller.enqueue(chunk);\n },\n });\n },\n },\n bodyUsed: {\n get(this: RequestState) {\n return this.bodyUsed;\n },\n },\n cache: {\n get(this: RequestState) {\n return this.cache;\n },\n },\n credentials: {\n get(this: RequestState) {\n return this.credentials;\n },\n },\n destination: {\n get(this: RequestState) {\n return this.destination;\n },\n },\n integrity: {\n get(this: RequestState) {\n return this.integrity;\n },\n },\n keepalive: {\n get(this: RequestState) {\n return this.keepalive;\n },\n },\n mode: {\n get(this: RequestState) {\n return this.mode;\n },\n },\n redirect: {\n get(this: RequestState) {\n return this.redirect;\n },\n },\n referrer: {\n get(this: RequestState) {\n return this.referrer;\n },\n },\n referrerPolicy: {\n get(this: RequestState) {\n return this.referrerPolicy;\n },\n },\n signal: {\n get(this: RequestState) {\n return this.signal;\n },\n },\n },\n methods: {\n async arrayBuffer(this: RequestState): Promise<ArrayBuffer> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return new ArrayBuffer(0);\n }\n return this.body.buffer.slice(\n this.body.byteOffset,\n this.body.byteOffset + this.body.byteLength\n ) as ArrayBuffer;\n },\n async blob(this: RequestState): Promise<object> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n return {\n parts: this.body ? [this.body] : [],\n type: contentType,\n size: this.body?.length || 0,\n };\n },\n clone(this: RequestState): RequestState {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n return {\n ...this,\n headersState: {\n headers: new Map(this.headersState.headers),\n },\n body: this.body ? new Uint8Array(this.body) : null,\n bodyUsed: false,\n };\n },\n async json(this: RequestState): Promise<unknown> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return JSON.parse(\"\");\n }\n const text = new TextDecoder().decode(this.body);\n return JSON.parse(text);\n },\n async text(this: RequestState): Promise<string> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return \"\";\n }\n return new TextDecoder().decode(this.body);\n },\n /**\n * Private method that returns raw FormData entries.\n * Used by the formData() method added via evalCode (see addRequestFormDataMethod).\n *\n * Note: File data is converted to plain number arrays to avoid memory issues\n * when marshalling Uint8Array between host and QuickJS contexts.\n */\n async __getFormDataEntries__(this: RequestState): Promise<{\n entries: Array<{\n name: string;\n value: string | { __formDataFile__: true; data: number[]; filename: string; type: string };\n }>;\n }> {\n if (this.bodyUsed) {\n throw new TypeError(\"Body has already been consumed\");\n }\n this.bodyUsed = true;\n if (!this.body) {\n return { entries: [] };\n }\n\n const contentType = this.headersState.headers.get(\"content-type\")?.[0] || \"\";\n\n let formDataState: FormDataState;\n if (contentType.includes(\"multipart/form-data\")) {\n formDataState = parseMultipartFormData(this.body, contentType);\n } else if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n formDataState = parseUrlEncodedFormData(this.body);\n } else {\n throw new TypeError(\"Could not parse content as FormData\");\n }\n\n // Convert Uint8Array data to plain number arrays for safe marshalling\n // Include marker so FormData.get() can reconstruct File instances\n type SerializedFileValue = { __formDataFile__: true; data: number[]; filename: string; type: string };\n type SerializedEntry = { name: string; value: string | SerializedFileValue };\n return {\n entries: formDataState.entries.map((entry): SerializedEntry => {\n if (typeof entry.value === \"string\") {\n return { name: entry.name, value: entry.value };\n }\n // Convert Uint8Array to number array and include marker\n return {\n name: entry.name,\n value: {\n __formDataFile__: true,\n data: Array.from(entry.value.data),\n filename: entry.value.filename,\n type: entry.value.type,\n },\n };\n }),\n };\n },\n },\n });\n}\n\n/**\n * Add the formData() method to Request.prototype via evalCode.\n *\n * This must be called AFTER both Request and FormData classes are on global.\n * The method creates a proper FormData instance with all entries.\n *\n * @see PATTERNS.md section 2 (Class Methods That Return Instances)\n */\nexport function addRequestFormDataMethod(context: QuickJSContext): void {\n const result = context.evalCode(`\n Request.prototype.formData = async function() {\n // Get raw entries from private method\n // Note: File data comes as plain number arrays (converted in host side)\n const rawData = await this.__getFormDataEntries__();\n\n // Create a proper FormData instance\n const formData = new FormData();\n\n // Populate with entries\n // FormData.append handles both string values and file-like objects\n // with number arrays (converted to Uint8Array on the host side)\n for (const entry of rawData.entries) {\n formData.append(entry.name, entry.value);\n }\n\n return formData;\n };\n `);\n\n if (result.error) {\n result.error.dispose();\n } else {\n result.value.dispose();\n }\n}\n\n/**\n * Create a RequestState from a native Request object\n */\nexport async function createRequestStateFromNative(\n request: Request\n): Promise<RequestState> {\n const body = request.body\n ? new Uint8Array(await request.arrayBuffer())\n : null;\n\n return {\n method: request.method,\n url: request.url,\n headersState: createHeadersStateFromNative(request.headers),\n body,\n bodyUsed: false,\n cache: request.cache,\n credentials: request.credentials,\n destination: request.destination,\n integrity: request.integrity,\n keepalive: request.keepalive,\n mode: request.mode,\n redirect: request.redirect,\n referrer: request.referrer,\n referrerPolicy: request.referrerPolicy,\n signal: null, // Signal handling is complex, simplified here\n };\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "0046C87C5631304864756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "9CDFB08BC3F7DEBF64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/quickjs-fetch",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "type": "module"
5
5
  }
@@ -2,10 +2,10 @@
2
2
  // packages/fetch/src/setup.ts
3
3
  import { setupCore, createReadableStream } from "@ricsam/quickjs-core";
4
4
  import { createHeadersClass } from "./globals/headers.mjs";
5
- import { createRequestClass } from "./globals/request.mjs";
5
+ import { createRequestClass, addRequestFormDataMethod } from "./globals/request.mjs";
6
6
  import { createResponseClass, addResponseStaticMethods } from "./globals/response.mjs";
7
7
  import { setupAbortControllerAndSignal } from "./globals/abort-controller.mjs";
8
- import { createFormDataClass } from "./globals/form-data.mjs";
8
+ import { createFormDataClass, addFormDataFileMethods } from "./globals/form-data.mjs";
9
9
  import { createFetchFunction } from "./globals/fetch.mjs";
10
10
  import {
11
11
  createServeFunction,
@@ -65,6 +65,8 @@ function setupFetch(context, options = {}) {
65
65
  } else {
66
66
  formDataIteratorResult.value.dispose();
67
67
  }
68
+ addRequestFormDataMethod(context);
69
+ addFormDataFileMethods(context);
68
70
  const ServerWebSocketClass = createServerWebSocketClass(context, stateMap, dispatchWsCommand);
69
71
  context.setProp(context.global, "__ServerWebSocket__", ServerWebSocketClass);
70
72
  ServerWebSocketClass.dispose();
@@ -89,4 +91,4 @@ export {
89
91
  setupFetch
90
92
  };
91
93
 
92
- //# debugId=26DA993899A1635164756E2164756E21
94
+ //# debugId=E9661F932BB0303C64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/setup.ts"],
4
4
  "sourcesContent": [
5
- "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport { setupCore, createStateMap, createReadableStream } from \"@ricsam/quickjs-core\";\nimport type { SetupFetchOptions, FetchHandle, ServeState } from \"./types.mjs\";\nimport { createHeadersClass } from \"./globals/headers.mjs\";\nimport { createRequestClass } from \"./globals/request.mjs\";\nimport { createResponseClass, addResponseStaticMethods } from \"./globals/response.mjs\";\nimport { setupAbortControllerAndSignal } from \"./globals/abort-controller.mjs\";\nimport { createFormDataClass } from \"./globals/form-data.mjs\";\nimport { createFetchFunction } from \"./globals/fetch.mjs\";\nimport {\n createServeFunction,\n createServerClass,\n createServerWebSocketClass,\n} from \"./globals/serve.mjs\";\nimport { createFetchHandle } from \"./handle.mjs\";\n\n/**\n * Setup Fetch API in a QuickJS context\n *\n * Injects the following globals:\n * - fetch\n * - Request\n * - Response\n * - Headers\n * - AbortController\n * - AbortSignal\n * - serve\n * - FormData\n *\n * Also sets up Core APIs (Streams, Blob, File) if not already present.\n *\n * **Private globals (internal use):**\n * - `__Server__` - Server class for serve() handler, instantiated via evalCode\n * - `__ServerWebSocket__` - WebSocket class for connection handling\n * - `__scheduleTimeout__` - Host function to schedule AbortSignal.timeout()\n * - `__checkTimeout__` - Host function to check if timeout elapsed\n *\n * These private globals follow the `__Name__` convention and are required for\n * JavaScript code in QuickJS to create class instances via evalCode.\n * See PATTERNS.md section 5 for details.\n *\n * @example\n * const handle = setupFetch(context, {\n * onFetch: async (request) => {\n * // Proxy to real fetch\n * return fetch(request);\n * }\n * });\n *\n * context.evalCode(`\n * serve({\n * fetch(request, server) {\n * return new Response(\"Hello!\");\n * }\n * });\n * `);\n *\n * const response = await handle.dispatchRequest(\n * new Request(\"http://localhost/\")\n * );\n */\nexport function setupFetch(\n context: QuickJSContext,\n options: SetupFetchOptions = {}\n): FetchHandle {\n // Setup core if not already done\n const coreHandle =\n options.coreHandle ??\n setupCore(context, {\n stateMap: options.stateMap,\n });\n\n const stateMap = options.stateMap ?? coreHandle.stateMap;\n\n // Create serve state\n const serveState: ServeState = {\n fetchHandler: null,\n websocketHandlers: {},\n pendingUpgrade: null,\n activeConnections: new Map(),\n };\n\n // WebSocket command dispatcher\n const wsCommandCallbacks = new Set<\n (cmd: import(\"./types.mjs\").WebSocketCommand) => void\n >();\n const dispatchWsCommand = (cmd: import(\"./types.mjs\").WebSocketCommand) => {\n for (const cb of wsCommandCallbacks) {\n cb(cmd);\n }\n };\n\n // Create stream factory for Request/Response body\n const streamFactory = (source: UnderlyingSource) =>\n createReadableStream(context, stateMap, source);\n\n // Create Headers class\n const HeadersClass = createHeadersClass(context, stateMap);\n context.setProp(context.global, \"Headers\", HeadersClass);\n HeadersClass.dispose();\n\n // Add Symbol.iterator support for Headers (for...of, Array.from, spread)\n const iteratorResult = context.evalCode(`\n Headers.prototype[Symbol.iterator] = function() {\n return this.entries()[Symbol.iterator]();\n };\n `);\n if (iteratorResult.error) {\n iteratorResult.error.dispose();\n } else {\n iteratorResult.value.dispose();\n }\n\n // Create Request class\n const RequestClass = createRequestClass(context, stateMap, streamFactory);\n context.setProp(context.global, \"Request\", RequestClass);\n RequestClass.dispose();\n\n // Create Response class\n const ResponseClass = createResponseClass(context, stateMap, streamFactory);\n context.setProp(context.global, \"Response\", ResponseClass);\n ResponseClass.dispose();\n\n // Add Response static methods (must be after Response and Headers are on global)\n addResponseStaticMethods(context);\n\n // Create AbortSignal and AbortController classes (pure QuickJS implementation)\n setupAbortControllerAndSignal(context);\n\n // Create FormData class\n const FormDataClass = createFormDataClass(context, stateMap);\n context.setProp(context.global, \"FormData\", FormDataClass);\n FormDataClass.dispose();\n\n // Add Symbol.iterator support for FormData (for...of, Array.from, spread)\n const formDataIteratorResult = context.evalCode(`\n FormData.prototype[Symbol.iterator] = function() {\n return this.entries()[Symbol.iterator]();\n };\n `);\n if (formDataIteratorResult.error) {\n formDataIteratorResult.error.dispose();\n } else {\n formDataIteratorResult.value.dispose();\n }\n\n // Create ServerWebSocket class (internal, for WebSocket handling)\n const ServerWebSocketClass = createServerWebSocketClass(\n context,\n stateMap,\n dispatchWsCommand\n );\n // Set on global with internal name so we can use evalCode to instantiate\n context.setProp(context.global, \"__ServerWebSocket__\", ServerWebSocketClass);\n ServerWebSocketClass.dispose();\n // Note: ServerWebSocketClass handle is now owned by global\n\n // Create Server class (internal, passed to fetch handler)\n const ServerClass = createServerClass(context, stateMap, serveState);\n // Set on global with internal name so we can use evalCode to instantiate\n context.setProp(context.global, \"__Server__\", ServerClass);\n ServerClass.dispose();\n // Note: ServerClass handle is now owned by global\n\n // Create fetch function\n const fetchFn = createFetchFunction(context, options.onFetch);\n context.setProp(context.global, \"fetch\", fetchFn);\n fetchFn.dispose();\n\n // Create serve function\n const serveFn = createServeFunction(context, stateMap, serveState);\n context.setProp(context.global, \"serve\", serveFn);\n serveFn.dispose();\n\n // Create and return the handle\n const fetchHandle = createFetchHandle(\n context,\n stateMap,\n serveState\n );\n\n // Wire up WebSocket command callbacks\n const originalOnWebSocketCommand = fetchHandle.onWebSocketCommand;\n fetchHandle.onWebSocketCommand = (callback) => {\n wsCommandCallbacks.add(callback);\n return () => wsCommandCallbacks.delete(callback);\n };\n\n return fetchHandle;\n}\n"
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport { setupCore, createStateMap, createReadableStream } from \"@ricsam/quickjs-core\";\nimport type { SetupFetchOptions, FetchHandle, ServeState } from \"./types.mjs\";\nimport { createHeadersClass } from \"./globals/headers.mjs\";\nimport { createRequestClass, addRequestFormDataMethod } from \"./globals/request.mjs\";\nimport { createResponseClass, addResponseStaticMethods } from \"./globals/response.mjs\";\nimport { setupAbortControllerAndSignal } from \"./globals/abort-controller.mjs\";\nimport { createFormDataClass, addFormDataFileMethods } from \"./globals/form-data.mjs\";\nimport { createFetchFunction } from \"./globals/fetch.mjs\";\nimport {\n createServeFunction,\n createServerClass,\n createServerWebSocketClass,\n} from \"./globals/serve.mjs\";\nimport { createFetchHandle } from \"./handle.mjs\";\n\n/**\n * Setup Fetch API in a QuickJS context\n *\n * Injects the following globals:\n * - fetch\n * - Request\n * - Response\n * - Headers\n * - AbortController\n * - AbortSignal\n * - serve\n * - FormData\n *\n * Also sets up Core APIs (Streams, Blob, File) if not already present.\n *\n * **Private globals (internal use):**\n * - `__Server__` - Server class for serve() handler, instantiated via evalCode\n * - `__ServerWebSocket__` - WebSocket class for connection handling\n * - `__scheduleTimeout__` - Host function to schedule AbortSignal.timeout()\n * - `__checkTimeout__` - Host function to check if timeout elapsed\n *\n * These private globals follow the `__Name__` convention and are required for\n * JavaScript code in QuickJS to create class instances via evalCode.\n * See PATTERNS.md section 5 for details.\n *\n * @example\n * const handle = setupFetch(context, {\n * onFetch: async (request) => {\n * // Proxy to real fetch\n * return fetch(request);\n * }\n * });\n *\n * context.evalCode(`\n * serve({\n * fetch(request, server) {\n * return new Response(\"Hello!\");\n * }\n * });\n * `);\n *\n * const response = await handle.dispatchRequest(\n * new Request(\"http://localhost/\")\n * );\n */\nexport function setupFetch(\n context: QuickJSContext,\n options: SetupFetchOptions = {}\n): FetchHandle {\n // Setup core if not already done\n const coreHandle =\n options.coreHandle ??\n setupCore(context, {\n stateMap: options.stateMap,\n });\n\n const stateMap = options.stateMap ?? coreHandle.stateMap;\n\n // Create serve state\n const serveState: ServeState = {\n fetchHandler: null,\n websocketHandlers: {},\n pendingUpgrade: null,\n activeConnections: new Map(),\n };\n\n // WebSocket command dispatcher\n const wsCommandCallbacks = new Set<\n (cmd: import(\"./types.mjs\").WebSocketCommand) => void\n >();\n const dispatchWsCommand = (cmd: import(\"./types.mjs\").WebSocketCommand) => {\n for (const cb of wsCommandCallbacks) {\n cb(cmd);\n }\n };\n\n // Create stream factory for Request/Response body\n const streamFactory = (source: UnderlyingSource) =>\n createReadableStream(context, stateMap, source);\n\n // Create Headers class\n const HeadersClass = createHeadersClass(context, stateMap);\n context.setProp(context.global, \"Headers\", HeadersClass);\n HeadersClass.dispose();\n\n // Add Symbol.iterator support for Headers (for...of, Array.from, spread)\n const iteratorResult = context.evalCode(`\n Headers.prototype[Symbol.iterator] = function() {\n return this.entries()[Symbol.iterator]();\n };\n `);\n if (iteratorResult.error) {\n iteratorResult.error.dispose();\n } else {\n iteratorResult.value.dispose();\n }\n\n // Create Request class\n const RequestClass = createRequestClass(context, stateMap, streamFactory);\n context.setProp(context.global, \"Request\", RequestClass);\n RequestClass.dispose();\n\n // Create Response class\n const ResponseClass = createResponseClass(context, stateMap, streamFactory);\n context.setProp(context.global, \"Response\", ResponseClass);\n ResponseClass.dispose();\n\n // Add Response static methods (must be after Response and Headers are on global)\n addResponseStaticMethods(context);\n\n // Create AbortSignal and AbortController classes (pure QuickJS implementation)\n setupAbortControllerAndSignal(context);\n\n // Create FormData class\n const FormDataClass = createFormDataClass(context, stateMap);\n context.setProp(context.global, \"FormData\", FormDataClass);\n FormDataClass.dispose();\n\n // Add Symbol.iterator support for FormData (for...of, Array.from, spread)\n const formDataIteratorResult = context.evalCode(`\n FormData.prototype[Symbol.iterator] = function() {\n return this.entries()[Symbol.iterator]();\n };\n `);\n if (formDataIteratorResult.error) {\n formDataIteratorResult.error.dispose();\n } else {\n formDataIteratorResult.value.dispose();\n }\n\n // Add Request.formData() method that returns a proper FormData instance\n // Must be after both Request and FormData are on global\n addRequestFormDataMethod(context);\n\n // Add FormData.get()/getAll() overrides to reconstruct File instances\n // Must be after both FormData and File are on global\n addFormDataFileMethods(context);\n\n // Create ServerWebSocket class (internal, for WebSocket handling)\n const ServerWebSocketClass = createServerWebSocketClass(\n context,\n stateMap,\n dispatchWsCommand\n );\n // Set on global with internal name so we can use evalCode to instantiate\n context.setProp(context.global, \"__ServerWebSocket__\", ServerWebSocketClass);\n ServerWebSocketClass.dispose();\n // Note: ServerWebSocketClass handle is now owned by global\n\n // Create Server class (internal, passed to fetch handler)\n const ServerClass = createServerClass(context, stateMap, serveState);\n // Set on global with internal name so we can use evalCode to instantiate\n context.setProp(context.global, \"__Server__\", ServerClass);\n ServerClass.dispose();\n // Note: ServerClass handle is now owned by global\n\n // Create fetch function\n const fetchFn = createFetchFunction(context, options.onFetch);\n context.setProp(context.global, \"fetch\", fetchFn);\n fetchFn.dispose();\n\n // Create serve function\n const serveFn = createServeFunction(context, stateMap, serveState);\n context.setProp(context.global, \"serve\", serveFn);\n serveFn.dispose();\n\n // Create and return the handle\n const fetchHandle = createFetchHandle(\n context,\n stateMap,\n serveState\n );\n\n // Wire up WebSocket command callbacks\n const originalOnWebSocketCommand = fetchHandle.onWebSocketCommand;\n fetchHandle.onWebSocketCommand = (callback) => {\n wsCommandCallbacks.add(callback);\n return () => wsCommandCallbacks.delete(callback);\n };\n\n return fetchHandle;\n}\n"
6
6
  ],
7
- "mappings": ";;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAKA;AA+CO,SAAS,UAAU,CACxB,SACA,UAA6B,CAAC,GACjB;AAAA,EAEb,MAAM,aACJ,QAAQ,cACR,UAAU,SAAS;AAAA,IACjB,UAAU,QAAQ;AAAA,EACpB,CAAC;AAAA,EAEH,MAAM,WAAW,QAAQ,YAAY,WAAW;AAAA,EAGhD,MAAM,aAAyB;AAAA,IAC7B,cAAc;AAAA,IACd,mBAAmB,CAAC;AAAA,IACpB,gBAAgB;AAAA,IAChB,mBAAmB,IAAI;AAAA,EACzB;AAAA,EAGA,MAAM,qBAAqB,IAAI;AAAA,EAG/B,MAAM,oBAAoB,CAAC,QAAgD;AAAA,IACzE,WAAW,MAAM,oBAAoB;AAAA,MACnC,GAAG,GAAG;AAAA,IACR;AAAA;AAAA,EAIF,MAAM,gBAAgB,CAAC,WACrB,qBAAqB,SAAS,UAAU,MAAM;AAAA,EAGhD,MAAM,eAAe,mBAAmB,SAAS,QAAQ;AAAA,EACzD,QAAQ,QAAQ,QAAQ,QAAQ,WAAW,YAAY;AAAA,EACvD,aAAa,QAAQ;AAAA,EAGrB,MAAM,iBAAiB,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,GAIvC;AAAA,EACD,IAAI,eAAe,OAAO;AAAA,IACxB,eAAe,MAAM,QAAQ;AAAA,EAC/B,EAAO;AAAA,IACL,eAAe,MAAM,QAAQ;AAAA;AAAA,EAI/B,MAAM,eAAe,mBAAmB,SAAS,UAAU,aAAa;AAAA,EACxE,QAAQ,QAAQ,QAAQ,QAAQ,WAAW,YAAY;AAAA,EACvD,aAAa,QAAQ;AAAA,EAGrB,MAAM,gBAAgB,oBAAoB,SAAS,UAAU,aAAa;AAAA,EAC1E,QAAQ,QAAQ,QAAQ,QAAQ,YAAY,aAAa;AAAA,EACzD,cAAc,QAAQ;AAAA,EAGtB,yBAAyB,OAAO;AAAA,EAGhC,8BAA8B,OAAO;AAAA,EAGrC,MAAM,gBAAgB,oBAAoB,SAAS,QAAQ;AAAA,EAC3D,QAAQ,QAAQ,QAAQ,QAAQ,YAAY,aAAa;AAAA,EACzD,cAAc,QAAQ;AAAA,EAGtB,MAAM,yBAAyB,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,GAI/C;AAAA,EACD,IAAI,uBAAuB,OAAO;AAAA,IAChC,uBAAuB,MAAM,QAAQ;AAAA,EACvC,EAAO;AAAA,IACL,uBAAuB,MAAM,QAAQ;AAAA;AAAA,EAIvC,MAAM,uBAAuB,2BAC3B,SACA,UACA,iBACF;AAAA,EAEA,QAAQ,QAAQ,QAAQ,QAAQ,uBAAuB,oBAAoB;AAAA,EAC3E,qBAAqB,QAAQ;AAAA,EAI7B,MAAM,cAAc,kBAAkB,SAAS,UAAU,UAAU;AAAA,EAEnE,QAAQ,QAAQ,QAAQ,QAAQ,cAAc,WAAW;AAAA,EACzD,YAAY,QAAQ;AAAA,EAIpB,MAAM,UAAU,oBAAoB,SAAS,QAAQ,OAAO;AAAA,EAC5D,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,OAAO;AAAA,EAChD,QAAQ,QAAQ;AAAA,EAGhB,MAAM,UAAU,oBAAoB,SAAS,UAAU,UAAU;AAAA,EACjE,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,OAAO;AAAA,EAChD,QAAQ,QAAQ;AAAA,EAGhB,MAAM,cAAc,kBAClB,SACA,UACA,UACF;AAAA,EAGA,MAAM,6BAA6B,YAAY;AAAA,EAC/C,YAAY,qBAAqB,CAAC,aAAa;AAAA,IAC7C,mBAAmB,IAAI,QAAQ;AAAA,IAC/B,OAAO,MAAM,mBAAmB,OAAO,QAAQ;AAAA;AAAA,EAGjD,OAAO;AAAA;",
8
- "debugId": "26DA993899A1635164756E2164756E21",
7
+ "mappings": ";;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAKA;AA+CO,SAAS,UAAU,CACxB,SACA,UAA6B,CAAC,GACjB;AAAA,EAEb,MAAM,aACJ,QAAQ,cACR,UAAU,SAAS;AAAA,IACjB,UAAU,QAAQ;AAAA,EACpB,CAAC;AAAA,EAEH,MAAM,WAAW,QAAQ,YAAY,WAAW;AAAA,EAGhD,MAAM,aAAyB;AAAA,IAC7B,cAAc;AAAA,IACd,mBAAmB,CAAC;AAAA,IACpB,gBAAgB;AAAA,IAChB,mBAAmB,IAAI;AAAA,EACzB;AAAA,EAGA,MAAM,qBAAqB,IAAI;AAAA,EAG/B,MAAM,oBAAoB,CAAC,QAAgD;AAAA,IACzE,WAAW,MAAM,oBAAoB;AAAA,MACnC,GAAG,GAAG;AAAA,IACR;AAAA;AAAA,EAIF,MAAM,gBAAgB,CAAC,WACrB,qBAAqB,SAAS,UAAU,MAAM;AAAA,EAGhD,MAAM,eAAe,mBAAmB,SAAS,QAAQ;AAAA,EACzD,QAAQ,QAAQ,QAAQ,QAAQ,WAAW,YAAY;AAAA,EACvD,aAAa,QAAQ;AAAA,EAGrB,MAAM,iBAAiB,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,GAIvC;AAAA,EACD,IAAI,eAAe,OAAO;AAAA,IACxB,eAAe,MAAM,QAAQ;AAAA,EAC/B,EAAO;AAAA,IACL,eAAe,MAAM,QAAQ;AAAA;AAAA,EAI/B,MAAM,eAAe,mBAAmB,SAAS,UAAU,aAAa;AAAA,EACxE,QAAQ,QAAQ,QAAQ,QAAQ,WAAW,YAAY;AAAA,EACvD,aAAa,QAAQ;AAAA,EAGrB,MAAM,gBAAgB,oBAAoB,SAAS,UAAU,aAAa;AAAA,EAC1E,QAAQ,QAAQ,QAAQ,QAAQ,YAAY,aAAa;AAAA,EACzD,cAAc,QAAQ;AAAA,EAGtB,yBAAyB,OAAO;AAAA,EAGhC,8BAA8B,OAAO;AAAA,EAGrC,MAAM,gBAAgB,oBAAoB,SAAS,QAAQ;AAAA,EAC3D,QAAQ,QAAQ,QAAQ,QAAQ,YAAY,aAAa;AAAA,EACzD,cAAc,QAAQ;AAAA,EAGtB,MAAM,yBAAyB,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,GAI/C;AAAA,EACD,IAAI,uBAAuB,OAAO;AAAA,IAChC,uBAAuB,MAAM,QAAQ;AAAA,EACvC,EAAO;AAAA,IACL,uBAAuB,MAAM,QAAQ;AAAA;AAAA,EAKvC,yBAAyB,OAAO;AAAA,EAIhC,uBAAuB,OAAO;AAAA,EAG9B,MAAM,uBAAuB,2BAC3B,SACA,UACA,iBACF;AAAA,EAEA,QAAQ,QAAQ,QAAQ,QAAQ,uBAAuB,oBAAoB;AAAA,EAC3E,qBAAqB,QAAQ;AAAA,EAI7B,MAAM,cAAc,kBAAkB,SAAS,UAAU,UAAU;AAAA,EAEnE,QAAQ,QAAQ,QAAQ,QAAQ,cAAc,WAAW;AAAA,EACzD,YAAY,QAAQ;AAAA,EAIpB,MAAM,UAAU,oBAAoB,SAAS,QAAQ,OAAO;AAAA,EAC5D,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,OAAO;AAAA,EAChD,QAAQ,QAAQ;AAAA,EAGhB,MAAM,UAAU,oBAAoB,SAAS,UAAU,UAAU;AAAA,EACjE,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,OAAO;AAAA,EAChD,QAAQ,QAAQ;AAAA,EAGhB,MAAM,cAAc,kBAClB,SACA,UACA,UACF;AAAA,EAGA,MAAM,6BAA6B,YAAY;AAAA,EAC/C,YAAY,qBAAqB,CAAC,aAAa;AAAA,IAC7C,mBAAmB,IAAI,QAAQ;AAAA,IAC/B,OAAO,MAAM,mBAAmB,OAAO,QAAQ;AAAA;AAAA,EAGjD,OAAO;AAAA;",
8
+ "debugId": "E9661F932BB0303C64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,9 @@
1
1
  import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
2
2
  import type { StateMap } from "@ricsam/quickjs-core";
3
+ /**
4
+ * Marker to identify FormData file entries that need File reconstruction
5
+ */
6
+ export declare const FORMDATA_FILE_MARKER = "__formDataFile__";
3
7
  /**
4
8
  * Internal state for FormData entries
5
9
  * Each entry can have multiple values (same key appended multiple times)
@@ -9,6 +13,7 @@ export interface FormDataEntry {
9
13
  value: string | FormDataFileValue;
10
14
  }
11
15
  export interface FormDataFileValue {
16
+ [FORMDATA_FILE_MARKER]: true;
12
17
  data: Uint8Array;
13
18
  filename: string;
14
19
  type: string;
@@ -35,3 +40,12 @@ export declare function serializeFormData(state: FormDataState): {
35
40
  body: Uint8Array;
36
41
  contentType: string;
37
42
  };
43
+ /**
44
+ * Add JavaScript overrides for FormData.get() and FormData.getAll() to reconstruct File instances
45
+ *
46
+ * This is needed because defineClass methods can only return plain objects when marshalling,
47
+ * but we want formData.get("file") to return actual File instances with working methods.
48
+ *
49
+ * @param context The QuickJS context (must have FormData and File classes already defined)
50
+ */
51
+ export declare function addFormDataFileMethods(context: QuickJSContext): void;
@@ -9,6 +9,15 @@ type StreamFactory = (source: UnderlyingSource) => QuickJSHandle;
9
9
  * Create the Request class for QuickJS
10
10
  */
11
11
  export declare function createRequestClass(context: QuickJSContext, stateMap: StateMap, createStream?: StreamFactory): QuickJSHandle;
12
+ /**
13
+ * Add the formData() method to Request.prototype via evalCode.
14
+ *
15
+ * This must be called AFTER both Request and FormData classes are on global.
16
+ * The method creates a proper FormData instance with all entries.
17
+ *
18
+ * @see PATTERNS.md section 2 (Class Methods That Return Instances)
19
+ */
20
+ export declare function addRequestFormDataMethod(context: QuickJSContext): void;
12
21
  /**
13
22
  * Create a RequestState from a native Request object
14
23
  */
@@ -162,6 +162,7 @@ export interface AbortSignalState {
162
162
  listeners: Set<() => void>;
163
163
  }
164
164
  export interface FormDataFileValue {
165
+ __formDataFile__: true;
165
166
  data: Uint8Array;
166
167
  filename: string;
167
168
  type: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ricsam/quickjs-fetch",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "main": "./dist/cjs/index.cjs",
5
5
  "types": "./dist/types/index.d.ts",
6
6
  "exports": {
@@ -16,7 +16,7 @@
16
16
  "typecheck": "tsc --noEmit"
17
17
  },
18
18
  "dependencies": {
19
- "@ricsam/quickjs-core": "^0.2.4",
19
+ "@ricsam/quickjs-core": "^0.2.5",
20
20
  "quickjs-emscripten": "^0.31.0"
21
21
  },
22
22
  "peerDependencies": {