@ricsam/quickjs-fetch 0.2.14 → 0.2.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/globals/fetch.cjs +19 -22
- package/dist/cjs/globals/fetch.cjs.map +3 -3
- package/dist/cjs/globals/headers.cjs +12 -80
- package/dist/cjs/globals/headers.cjs.map +3 -3
- package/dist/cjs/globals/request.cjs +194 -70
- package/dist/cjs/globals/request.cjs.map +3 -3
- package/dist/cjs/globals/response.cjs +130 -58
- package/dist/cjs/globals/response.cjs.map +3 -3
- package/dist/cjs/handle.cjs +9 -6
- package/dist/cjs/handle.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/setup.cjs +5 -1
- package/dist/cjs/setup.cjs.map +3 -3
- package/dist/cjs/types.cjs +50 -1
- package/dist/cjs/types.cjs.map +4 -3
- package/dist/mjs/globals/fetch.mjs +20 -23
- package/dist/mjs/globals/fetch.mjs.map +3 -3
- package/dist/mjs/globals/headers.mjs +13 -81
- package/dist/mjs/globals/headers.mjs.map +3 -3
- package/dist/mjs/globals/request.mjs +203 -72
- package/dist/mjs/globals/request.mjs.map +3 -3
- package/dist/mjs/globals/response.mjs +136 -60
- package/dist/mjs/globals/response.mjs.map +3 -3
- package/dist/mjs/handle.mjs +9 -6
- package/dist/mjs/handle.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/setup.mjs +7 -3
- package/dist/mjs/setup.mjs.map +3 -3
- package/dist/mjs/types.mjs +42 -1
- package/dist/mjs/types.mjs.map +4 -3
- package/dist/types/globals/headers.d.ts +0 -21
- package/dist/types/globals/request.d.ts +18 -0
- package/dist/types/globals/response.d.ts +18 -0
- package/dist/types/types.d.ts +48 -0
- package/package.json +2 -2
|
@@ -34,6 +34,7 @@ __export(exports_fetch, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(exports_fetch);
|
|
36
36
|
var import_quickjs_core = require("@ricsam/quickjs-core");
|
|
37
|
+
var import_types = require("../types.cjs");
|
|
37
38
|
var import_headers = require("./headers.cjs");
|
|
38
39
|
var import_response = require("./response.cjs");
|
|
39
40
|
function createFetchFunction(context, onFetch) {
|
|
@@ -108,13 +109,17 @@ function createFetchFunction(context, onFetch) {
|
|
|
108
109
|
let body = null;
|
|
109
110
|
if (typeof input === "string") {
|
|
110
111
|
url = input;
|
|
112
|
+
} else if (import_types.isRequestState(input)) {
|
|
113
|
+
url = input.url;
|
|
114
|
+
method = input.method;
|
|
115
|
+
headers = import_headers.headersStateToNative(input.headersState);
|
|
116
|
+
if (input.body) {
|
|
117
|
+
body = input.body.buffer.slice(input.body.byteOffset, input.body.byteOffset + input.body.byteLength);
|
|
118
|
+
}
|
|
111
119
|
} else if (input && typeof input === "object" && "url" in input) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
headers = import_headers.headersStateToNative(reqState.headersState);
|
|
116
|
-
if (reqState.body) {
|
|
117
|
-
body = reqState.body;
|
|
120
|
+
url = String(input.url);
|
|
121
|
+
if ("method" in input && typeof input.method === "string") {
|
|
122
|
+
method = input.method;
|
|
118
123
|
}
|
|
119
124
|
}
|
|
120
125
|
if (init) {
|
|
@@ -122,8 +127,9 @@ function createFetchFunction(context, onFetch) {
|
|
|
122
127
|
method = init.method;
|
|
123
128
|
}
|
|
124
129
|
if (init.headers) {
|
|
125
|
-
|
|
126
|
-
|
|
130
|
+
const coerced = import_quickjs_core.coerceHeaders.safeParse(init.headers);
|
|
131
|
+
if (coerced.success) {
|
|
132
|
+
headers = import_headers.headersStateToNative(coerced.value);
|
|
127
133
|
} else {
|
|
128
134
|
headers = new Headers;
|
|
129
135
|
for (const [key, value] of Object.entries(init.headers)) {
|
|
@@ -132,22 +138,13 @@ function createFetchFunction(context, onFetch) {
|
|
|
132
138
|
}
|
|
133
139
|
}
|
|
134
140
|
if (init.body !== undefined) {
|
|
135
|
-
|
|
141
|
+
const coercedBody = import_quickjs_core.coerceBody(init.body);
|
|
142
|
+
if (coercedBody) {
|
|
143
|
+
body = coercedBody.buffer.slice(coercedBody.byteOffset, coercedBody.byteOffset + coercedBody.byteLength);
|
|
144
|
+
} else if (typeof init.body === "string") {
|
|
136
145
|
body = init.body;
|
|
137
146
|
} else if (init.body instanceof ArrayBuffer) {
|
|
138
147
|
body = init.body;
|
|
139
|
-
} else if (init.body instanceof Uint8Array) {
|
|
140
|
-
body = init.body;
|
|
141
|
-
} else if (init.body && typeof init.body === "object" && "parts" in init.body) {
|
|
142
|
-
const parts = init.body.parts;
|
|
143
|
-
const totalLength = parts.reduce((sum, p) => sum + p.length, 0);
|
|
144
|
-
const combined = new Uint8Array(totalLength);
|
|
145
|
-
let offset = 0;
|
|
146
|
-
for (const part of parts) {
|
|
147
|
-
combined.set(part, offset);
|
|
148
|
-
offset += part.length;
|
|
149
|
-
}
|
|
150
|
-
body = combined;
|
|
151
148
|
}
|
|
152
149
|
}
|
|
153
150
|
}
|
|
@@ -196,4 +193,4 @@ function createFetchFunction(context, onFetch) {
|
|
|
196
193
|
}
|
|
197
194
|
})
|
|
198
195
|
|
|
199
|
-
//# debugId=
|
|
196
|
+
//# debugId=554F66EBEA7125CA64756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/globals/fetch.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport { unmarshal, marshal } from \"@ricsam/quickjs-core\";\nimport type { RequestState, HeadersState } from \"../types.cjs\";\nimport { headersStateToNative } from \"./headers.cjs\";\nimport { createResponseStateFromNative } from \"./response.cjs\";\n\n/**\n * Create the fetch function for QuickJS\n */\nexport function createFetchFunction(\n context: QuickJSContext,\n onFetch?: (request: Request) => Promise<Response>\n): QuickJSHandle {\n return context.newFunction(\"fetch\", (...argHandles) => {\n // Create promise first\n const deferred = context.newPromise();\n\n const inputHandle = argHandles[0];\n const initHandle = argHandles[1];\n\n // Extract signal BEFORE unmarshalling (keep as handle)\n let signalHandle: QuickJSHandle | null = null;\n // Check if initHandle exists and is a valid QuickJS handle (not JS undefined)\n if (initHandle !== undefined) {\n const initType = context.typeof(initHandle);\n if (initType === \"object\") {\n const tempSignal = context.getProp(initHandle, \"signal\");\n const signalType = context.typeof(tempSignal);\n if (signalType !== \"undefined\" && signalType !== \"null\") {\n signalHandle = tempSignal;\n } else {\n tempSignal.dispose();\n }\n }\n }\n\n // Check if signal is pre-aborted\n let isPreAborted = false;\n let abortReason: { message?: string } | undefined;\n if (signalHandle) {\n const abortedHandle = context.getProp(signalHandle, \"aborted\");\n isPreAborted = Boolean(context.dump(abortedHandle));\n abortedHandle.dispose();\n\n if (isPreAborted) {\n const reasonHandle = context.getProp(signalHandle, \"reason\");\n abortReason = context.dump(reasonHandle) as { message?: string } | undefined;\n reasonHandle.dispose();\n signalHandle.dispose();\n signalHandle = null;\n }\n }\n\n // If pre-aborted, reject immediately in a microtask\n if (isPreAborted) {\n Promise.resolve().then(() => {\n // Create DOMException and reject\n const errorMessage = abortReason?.message || \"signal is aborted without reason\";\n // Escape quotes in the message for safety\n const safeMessage = errorMessage.replace(/\"/g, '\\\\\"');\n const errorResult = context.evalCode(\n `new DOMException(\"${safeMessage}\", \"AbortError\")`\n );\n if (\"value\" in errorResult) {\n deferred.reject(errorResult.value);\n errorResult.value.dispose();\n } else {\n // If evalCode failed, create a plain error\n const fallbackError = marshal(context, { name: \"AbortError\", message: errorMessage });\n deferred.reject(fallbackError);\n fallbackError.dispose();\n errorResult.error.dispose();\n }\n context.runtime.executePendingJobs();\n });\n return deferred.handle;\n }\n\n // Create native AbortController\n const nativeController = new AbortController();\n\n // Wire QuickJS signal to native controller\n if (signalHandle) {\n // Create callback that aborts native controller when QuickJS signal aborts\n const abortCallback = context.newFunction(\"__fetchAbortCallback__\", () => {\n nativeController.abort();\n return context.undefined;\n });\n\n // Call addEventListener on the QuickJS signal\n const addEventListenerHandle = context.getProp(signalHandle, \"addEventListener\");\n const typeHandle = context.newString(\"abort\");\n\n context.callFunction(addEventListenerHandle, signalHandle, typeHandle, abortCallback);\n\n typeHandle.dispose();\n addEventListenerHandle.dispose();\n abortCallback.dispose();\n signalHandle.dispose();\n }\n\n // Unmarshal arguments\n const input = inputHandle ? unmarshal(context, inputHandle) : undefined;\n const init = initHandle ? unmarshal(context, initHandle) as {\n method?: string;\n headers?: object;\n body?: unknown;\n } | undefined : undefined;\n\n // Build the request\n let url = \"\";\n let method = \"GET\";\n let headers = new Headers();\n let body: BodyInit | null = null;\n\n if (typeof input === \"string\") {\n url = input;\n } else if (input && typeof input === \"object\" && \"url\" in input) {\n //
|
|
5
|
+
"import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport { unmarshal, marshal, coerceHeaders, coerceBody } from \"@ricsam/quickjs-core\";\nimport type { RequestState, HeadersState } from \"../types.cjs\";\nimport { isRequestState } from \"../types.cjs\";\nimport { headersStateToNative } from \"./headers.cjs\";\nimport { createResponseStateFromNative } from \"./response.cjs\";\n\n/**\n * Create the fetch function for QuickJS\n */\nexport function createFetchFunction(\n context: QuickJSContext,\n onFetch?: (request: Request) => Promise<Response>\n): QuickJSHandle {\n return context.newFunction(\"fetch\", (...argHandles) => {\n // Create promise first\n const deferred = context.newPromise();\n\n const inputHandle = argHandles[0];\n const initHandle = argHandles[1];\n\n // Extract signal BEFORE unmarshalling (keep as handle)\n let signalHandle: QuickJSHandle | null = null;\n // Check if initHandle exists and is a valid QuickJS handle (not JS undefined)\n if (initHandle !== undefined) {\n const initType = context.typeof(initHandle);\n if (initType === \"object\") {\n const tempSignal = context.getProp(initHandle, \"signal\");\n const signalType = context.typeof(tempSignal);\n if (signalType !== \"undefined\" && signalType !== \"null\") {\n signalHandle = tempSignal;\n } else {\n tempSignal.dispose();\n }\n }\n }\n\n // Check if signal is pre-aborted\n let isPreAborted = false;\n let abortReason: { message?: string } | undefined;\n if (signalHandle) {\n const abortedHandle = context.getProp(signalHandle, \"aborted\");\n isPreAborted = Boolean(context.dump(abortedHandle));\n abortedHandle.dispose();\n\n if (isPreAborted) {\n const reasonHandle = context.getProp(signalHandle, \"reason\");\n abortReason = context.dump(reasonHandle) as { message?: string } | undefined;\n reasonHandle.dispose();\n signalHandle.dispose();\n signalHandle = null;\n }\n }\n\n // If pre-aborted, reject immediately in a microtask\n if (isPreAborted) {\n Promise.resolve().then(() => {\n // Create DOMException and reject\n const errorMessage = abortReason?.message || \"signal is aborted without reason\";\n // Escape quotes in the message for safety\n const safeMessage = errorMessage.replace(/\"/g, '\\\\\"');\n const errorResult = context.evalCode(\n `new DOMException(\"${safeMessage}\", \"AbortError\")`\n );\n if (\"value\" in errorResult) {\n deferred.reject(errorResult.value);\n errorResult.value.dispose();\n } else {\n // If evalCode failed, create a plain error\n const fallbackError = marshal(context, { name: \"AbortError\", message: errorMessage });\n deferred.reject(fallbackError);\n fallbackError.dispose();\n errorResult.error.dispose();\n }\n context.runtime.executePendingJobs();\n });\n return deferred.handle;\n }\n\n // Create native AbortController\n const nativeController = new AbortController();\n\n // Wire QuickJS signal to native controller\n if (signalHandle) {\n // Create callback that aborts native controller when QuickJS signal aborts\n const abortCallback = context.newFunction(\"__fetchAbortCallback__\", () => {\n nativeController.abort();\n return context.undefined;\n });\n\n // Call addEventListener on the QuickJS signal\n const addEventListenerHandle = context.getProp(signalHandle, \"addEventListener\");\n const typeHandle = context.newString(\"abort\");\n\n context.callFunction(addEventListenerHandle, signalHandle, typeHandle, abortCallback);\n\n typeHandle.dispose();\n addEventListenerHandle.dispose();\n abortCallback.dispose();\n signalHandle.dispose();\n }\n\n // Unmarshal arguments\n const input = inputHandle ? unmarshal(context, inputHandle) : undefined;\n const init = initHandle ? unmarshal(context, initHandle) as {\n method?: string;\n headers?: object;\n body?: unknown;\n } | undefined : undefined;\n\n // Build the request\n let url = \"\";\n let method = \"GET\";\n let headers = new Headers();\n let body: BodyInit | null = null;\n\n if (typeof input === \"string\") {\n url = input;\n } else if (isRequestState(input)) {\n // Full RequestState object - extract properties with type safety\n url = input.url;\n method = input.method;\n headers = headersStateToNative(input.headersState);\n if (input.body) {\n // Convert Uint8Array to ArrayBuffer for BodyInit compatibility\n body = input.body.buffer.slice(\n input.body.byteOffset,\n input.body.byteOffset + input.body.byteLength\n ) as ArrayBuffer;\n }\n } else if (input && typeof input === \"object\" && \"url\" in input) {\n // Partial object with url property - extract what we can\n url = String((input as Record<string, unknown>).url);\n if (\"method\" in input && typeof (input as Record<string, unknown>).method === \"string\") {\n method = (input as Record<string, unknown>).method as string;\n }\n }\n\n // Apply init overrides\n if (init) {\n if (init.method) {\n method = init.method;\n }\n if (init.headers) {\n // Use coercion system for type-safe headers handling\n const coerced = coerceHeaders.safeParse(init.headers);\n if (coerced.success) {\n headers = headersStateToNative(coerced.value);\n } else {\n // Fallback for plain objects\n headers = new Headers();\n for (const [key, value] of Object.entries(init.headers)) {\n headers.set(key, String(value));\n }\n }\n }\n if (init.body !== undefined) {\n // Use coerceBody for type-safe body handling\n const coercedBody = coerceBody(init.body);\n if (coercedBody) {\n // Convert Uint8Array to ArrayBuffer for BodyInit compatibility\n body = coercedBody.buffer.slice(\n coercedBody.byteOffset,\n coercedBody.byteOffset + coercedBody.byteLength\n ) as ArrayBuffer;\n } else if (typeof init.body === \"string\") {\n body = init.body;\n } else if (init.body instanceof ArrayBuffer) {\n body = init.body;\n }\n }\n }\n\n // Run the async fetch operation in a microtask to ensure proper promise settling\n Promise.resolve().then(async () => {\n try {\n if (!onFetch) {\n throw new Error(\n \"fetch is not configured - no onFetch handler provided to setupFetch\"\n );\n }\n\n // Create native Request with signal\n const nativeRequest = new Request(url, {\n method,\n headers,\n body: method !== \"GET\" && method !== \"HEAD\" ? body : undefined,\n signal: nativeController.signal,\n });\n\n // Call the host fetch handler\n const nativeResponse = await onFetch(nativeRequest);\n\n // Convert to ResponseState for QuickJS\n const responseState = await createResponseStateFromNative(nativeResponse);\n const resultHandle = marshal(context, responseState);\n deferred.resolve(resultHandle);\n resultHandle.dispose();\n } catch (error) {\n // Handle abort errors specially\n if (error instanceof DOMException && error.name === \"AbortError\") {\n const safeMessage = error.message.replace(/\"/g, '\\\\\"');\n const errorResult = context.evalCode(\n `new DOMException(\"${safeMessage}\", \"AbortError\")`\n );\n if (\"value\" in errorResult) {\n deferred.reject(errorResult.value);\n errorResult.value.dispose();\n } else {\n const fallbackError = marshal(context, { name: \"AbortError\", message: error.message });\n deferred.reject(fallbackError);\n fallbackError.dispose();\n errorResult.error.dispose();\n }\n } else {\n const errorHandle = marshal(context, {\n name: error instanceof Error ? error.name : \"Error\",\n message: error instanceof Error ? error.message : String(error),\n });\n deferred.reject(errorHandle);\n errorHandle.dispose();\n }\n }\n context.runtime.executePendingJobs();\n });\n\n return deferred.handle;\n });\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "554F66EBEA7125CA64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -32,7 +32,6 @@ var exports_headers = {};
|
|
|
32
32
|
__export(exports_headers, {
|
|
33
33
|
headersStateToNative: () => headersStateToNative,
|
|
34
34
|
createHeadersStateFromNative: () => createHeadersStateFromNative,
|
|
35
|
-
createHeadersLike: () => createHeadersLike,
|
|
36
35
|
createHeadersClass: () => createHeadersClass
|
|
37
36
|
});
|
|
38
37
|
module.exports = __toCommonJS(exports_headers);
|
|
@@ -42,36 +41,11 @@ function createHeadersClass(context, stateMap) {
|
|
|
42
41
|
name: "Headers",
|
|
43
42
|
construct: (args) => {
|
|
44
43
|
const init = args[0];
|
|
45
|
-
const
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
for (const pair of init) {
|
|
49
|
-
if (Array.isArray(pair) && pair.length >= 2) {
|
|
50
|
-
const key = String(pair[0]).toLowerCase();
|
|
51
|
-
const value = String(pair[1]);
|
|
52
|
-
const existing = headers.get(key) || [];
|
|
53
|
-
existing.push(value);
|
|
54
|
-
headers.set(key, existing);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
} else if (typeof init === "object" && init !== null) {
|
|
58
|
-
if ("headers" in init && init.headers instanceof Map) {
|
|
59
|
-
for (const [key, values] of init.headers) {
|
|
60
|
-
headers.set(key, [...values]);
|
|
61
|
-
}
|
|
62
|
-
} else {
|
|
63
|
-
for (const [key, value] of Object.entries(init)) {
|
|
64
|
-
const normalizedKey = key.toLowerCase();
|
|
65
|
-
if (Array.isArray(value)) {
|
|
66
|
-
headers.set(normalizedKey, value.map(String));
|
|
67
|
-
} else {
|
|
68
|
-
headers.set(normalizedKey, [String(value)]);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
44
|
+
const coerced = import_quickjs_core.coerceHeaders.safeParse(init);
|
|
45
|
+
if (coerced.success) {
|
|
46
|
+
return coerced.value;
|
|
73
47
|
}
|
|
74
|
-
return { headers };
|
|
48
|
+
return { headers: new Map };
|
|
75
49
|
},
|
|
76
50
|
methods: {
|
|
77
51
|
append(name, value) {
|
|
@@ -120,6 +94,13 @@ function createHeadersClass(context, stateMap) {
|
|
|
120
94
|
},
|
|
121
95
|
getSetCookie() {
|
|
122
96
|
return this.headers.get("set-cookie") || [];
|
|
97
|
+
},
|
|
98
|
+
__linkToParent__(parentInstanceId) {
|
|
99
|
+
const id = typeof parentInstanceId === "number" ? parentInstanceId : 0;
|
|
100
|
+
const parentState = import_quickjs_core.getInstanceStateById(id);
|
|
101
|
+
if (parentState?.headersState) {
|
|
102
|
+
this.headers = parentState.headersState.headers;
|
|
103
|
+
}
|
|
123
104
|
}
|
|
124
105
|
}
|
|
125
106
|
});
|
|
@@ -142,55 +123,6 @@ function headersStateToNative(state) {
|
|
|
142
123
|
}
|
|
143
124
|
return headers;
|
|
144
125
|
}
|
|
145
|
-
function createHeadersLike(state) {
|
|
146
|
-
return {
|
|
147
|
-
headers: state.headers,
|
|
148
|
-
append(name, value) {
|
|
149
|
-
const key = name.toLowerCase();
|
|
150
|
-
const existing = state.headers.get(key) || [];
|
|
151
|
-
existing.push(value);
|
|
152
|
-
state.headers.set(key, existing);
|
|
153
|
-
},
|
|
154
|
-
delete(name) {
|
|
155
|
-
state.headers.delete(name.toLowerCase());
|
|
156
|
-
},
|
|
157
|
-
get(name) {
|
|
158
|
-
const values = state.headers.get(name.toLowerCase());
|
|
159
|
-
return values ? values.join(", ") : null;
|
|
160
|
-
},
|
|
161
|
-
has(name) {
|
|
162
|
-
return state.headers.has(name.toLowerCase());
|
|
163
|
-
},
|
|
164
|
-
set(name, value) {
|
|
165
|
-
state.headers.set(name.toLowerCase(), [value]);
|
|
166
|
-
},
|
|
167
|
-
entries() {
|
|
168
|
-
const result = [];
|
|
169
|
-
for (const [key, values] of state.headers) {
|
|
170
|
-
result.push([key, values.join(", ")]);
|
|
171
|
-
}
|
|
172
|
-
return result;
|
|
173
|
-
},
|
|
174
|
-
keys() {
|
|
175
|
-
return Array.from(state.headers.keys());
|
|
176
|
-
},
|
|
177
|
-
values() {
|
|
178
|
-
const result = [];
|
|
179
|
-
for (const values of state.headers.values()) {
|
|
180
|
-
result.push(values.join(", "));
|
|
181
|
-
}
|
|
182
|
-
return result;
|
|
183
|
-
},
|
|
184
|
-
forEach(callback) {
|
|
185
|
-
for (const [key, values] of state.headers) {
|
|
186
|
-
callback(values.join(", "), key);
|
|
187
|
-
}
|
|
188
|
-
},
|
|
189
|
-
getSetCookie() {
|
|
190
|
-
return state.headers.get("set-cookie") || [];
|
|
191
|
-
}
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
126
|
})
|
|
195
127
|
|
|
196
|
-
//# debugId=
|
|
128
|
+
//# debugId=B5952F5F1FA917C664756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/globals/headers.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 { HeadersState } from \"../types.cjs\";\n\n/**\n * Create the Headers class for QuickJS\n */\nexport function createHeadersClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<HeadersState>(context, stateMap, {\n name: \"Headers\",\n construct: (args) => {\n const init = args[0];\n
|
|
5
|
+
"import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"@ricsam/quickjs-core\";\nimport { defineClass, coerceHeaders, getInstanceStateById } from \"@ricsam/quickjs-core\";\nimport type { HeadersState } from \"../types.cjs\";\n\n/**\n * Create the Headers class for QuickJS\n */\nexport function createHeadersClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<HeadersState>(context, stateMap, {\n name: \"Headers\",\n construct: (args) => {\n const init = args[0];\n // Use coercion to handle all input types consistently\n const coerced = coerceHeaders.safeParse(init);\n if (coerced.success) {\n return coerced.value;\n }\n // Fallback to empty headers if coercion fails\n return { headers: new Map<string, string[]>() };\n },\n methods: {\n append(this: HeadersState, name: unknown, value: unknown) {\n const key = String(name).toLowerCase();\n const existing = this.headers.get(key) || [];\n existing.push(String(value));\n this.headers.set(key, existing);\n },\n delete(this: HeadersState, name: unknown) {\n this.headers.delete(String(name).toLowerCase());\n },\n get(this: HeadersState, name: unknown): string | null {\n const values = this.headers.get(String(name).toLowerCase());\n return values ? values.join(\", \") : null;\n },\n has(this: HeadersState, name: unknown): boolean {\n return this.headers.has(String(name).toLowerCase());\n },\n set(this: HeadersState, name: unknown, value: unknown) {\n this.headers.set(String(name).toLowerCase(), [String(value)]);\n },\n entries(this: HeadersState): Array<[string, string]> {\n const result: Array<[string, string]> = [];\n for (const [key, values] of this.headers) {\n result.push([key, values.join(\", \")]);\n }\n return result;\n },\n keys(this: HeadersState): string[] {\n return Array.from(this.headers.keys());\n },\n values(this: HeadersState): string[] {\n const result: string[] = [];\n for (const values of this.headers.values()) {\n result.push(values.join(\", \"));\n }\n return result;\n },\n forEach(this: HeadersState, callback: unknown) {\n if (typeof callback !== \"function\") {\n throw new TypeError(\"callback must be a function\");\n }\n for (const [key, values] of this.headers) {\n (callback as (value: string, key: string, parent: HeadersState) => void)(\n values.join(\", \"),\n key,\n this\n );\n }\n },\n getSetCookie(this: HeadersState): string[] {\n return this.headers.get(\"set-cookie\") || [];\n },\n /**\n * Private method to link this Headers instance to a parent Request/Response.\n * Called from the cached headers getter to share state.\n */\n __linkToParent__(this: HeadersState, parentInstanceId: unknown) {\n const id = typeof parentInstanceId === \"number\" ? parentInstanceId : 0;\n const parentState = getInstanceStateById<{ headersState: HeadersState }>(id);\n if (parentState?.headersState) {\n this.headers = parentState.headersState.headers;\n }\n },\n },\n });\n}\n\n/**\n * Create a HeadersState from a native Headers object\n */\nexport function createHeadersStateFromNative(headers: Headers): HeadersState {\n const map = new Map<string, string[]>();\n headers.forEach((value, key) => {\n const existing = map.get(key.toLowerCase()) || [];\n existing.push(value);\n map.set(key.toLowerCase(), existing);\n });\n return { headers: map };\n}\n\n/**\n * Convert HeadersState to native Headers\n */\nexport function headersStateToNative(state: HeadersState): Headers {\n const headers = new Headers();\n for (const [key, values] of state.headers) {\n for (const value of values) {\n headers.append(key, value);\n }\n }\n return headers;\n}\n\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "B5952F5F1FA917C664756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|