@wevu/web-apis 1.2.42 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -146,3 +146,31 @@ pnpm --filter @wevu/web-apis typecheck
146
146
 
147
147
  - 新项目建议使用 `installWebRuntimeGlobals()`
148
148
  - `installRequestGlobals()` 仍保留为兼容别名,后续会逐步淡出文档主叙事
149
+
150
+ ## 11. Body 与 Blob 契约
151
+
152
+ `RequestPolyfill` 和 `ResponsePolyfill` 提供 `bytes()`、`arrayBuffer()`、`text()`、`json()`、`blob()`。非 null body 只能消费一次;读取开始时 `bodyUsed` 就会变成 `true`,重复或并发读取会拒绝为 `TypeError`,读取后调用 `clone()` 也会抛错。需要多种读取方式时,请在消费前 clone:
153
+
154
+ ```ts
155
+ import { ResponsePolyfill } from '@wevu/web-apis'
156
+
157
+ const response = new ResponsePolyfill('{"ok":true}', {
158
+ headers: { 'content-type': 'application/json' },
159
+ })
160
+ const copy = response.clone()
161
+ const payload = await response.json()
162
+ const bytes = await copy.bytes()
163
+ ```
164
+
165
+ null body 读取为空且保持未消费;空字符串和零长度二进制属于非 null body。JSON 解析失败或底层读取失败后,非 null body 仍保持已消费。`fetch(request)` 消费被继承的请求 body;`new RequestPolyfill(request)` 转移该 body,消费前 `request.clone()` 则保留两份独立的读取状态。
166
+
167
+ | 能力 | 支持范围 |
168
+ | ----------------- | ---------------------------------------------------------------------------------------------------------- |
169
+ | Body 读取与 clone | 缓冲 body 的单次消费、独立 clone、MIME 传递;ponyfill 的 `blob()` 不要求先安装全局 Blob |
170
+ | Blob / File | UTF-8 字节长度、BufferSource 构造快照、独立 `bytes()`、负索引及越界 `slice()`、MIME 规范化 |
171
+ | Headers.forEach | 回调参数 `(value, key, headers)` 和可选 `thisArg` |
172
+ | BlobLike 扩展输入 | 保留异步 `arrayBuffer()` 兼容;无有效 `size` 的自定义对象不保证同步 size/切片语义,也不保证其自身不可变 |
173
+ | Streams | 未支持;`Request.body` / `Response.body` 仍为 null,不能据此判断缓冲 body 是否为空;未提供 `Blob.stream()` |
174
+ | formData() | 未支持响应解析;FormData 请求上传继续支持 multipart 编码 |
175
+
176
+ 这些是本包 ponyfill 的能力边界。安装器保留可用的宿主实现,宿主对象的方法完整性应按目标基础库确认。
package/dist/abort.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { RequestGlobalsEventTarget } from "./shared.mjs";
1
+ import { i as RequestGlobalsEventTarget } from "./shared-Dc42USJC.mjs";
2
2
  //#region src/abort.d.ts
3
3
  export declare class AbortSignalPolyfill extends RequestGlobalsEventTarget {
4
4
  aborted: boolean;
package/dist/fetch.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { RequestGlobalsMiniProgramOptions } from "./networkDefaults.mjs";
2
- import { URLPolyfill } from "./url.mjs";
2
+ import { t as URLPolyfill } from "./url-D0ANYIyk.mjs";
3
3
  //#region src/fetch.d.ts
4
4
  interface RequestLikeInput {
5
5
  url: string;
package/dist/fetch.mjs CHANGED
@@ -1,3 +1,188 @@
1
- import "./http.mjs";
2
- import { t as fetch } from "./fetch-BPqcYqI3.mjs";
1
+ import { d as normalizeHeaderName, h as isUrlSearchParamsInstance, l as isArrayBufferLike, m as isUrlInstance, n as cloneArrayBuffer, r as cloneArrayBufferView, u as isBlobLike } from "./shared-BsJRaiBh.mjs";
2
+ import { a as encodeMultipartFormData, i as consumeBodyValue, n as RequestPolyfill, o as HeadersPolyfill, t as ResponsePolyfill } from "./http-C-VyEBss.mjs";
3
+ import { t as FormDataPolyfill } from "./web-kSAO_PSD.mjs";
4
+ import { resolveRequestMiniProgramOptions } from "./networkDefaults.mjs";
5
+ import { wpi } from "@wevu/api";
6
+ //#region src/fetch.ts
7
+ const REQUEST_METHODS = [
8
+ "GET",
9
+ "HEAD",
10
+ "OPTIONS",
11
+ "POST",
12
+ "PUT",
13
+ "DELETE",
14
+ "TRACE",
15
+ "CONNECT"
16
+ ];
17
+ const hasOwn = Object.prototype.hasOwnProperty;
18
+ function isObject(value) {
19
+ return typeof value === "object" && value !== null;
20
+ }
21
+ function createAbortError() {
22
+ if (typeof DOMException === "function") return new DOMException("The operation was aborted.", "AbortError");
23
+ const error = /* @__PURE__ */ new Error("The operation was aborted.");
24
+ error.name = "AbortError";
25
+ return error;
26
+ }
27
+ function normalizeMethod(method) {
28
+ const normalized = (method ?? "GET").toUpperCase();
29
+ if (REQUEST_METHODS.includes(normalized)) return normalized;
30
+ return "GET";
31
+ }
32
+ function setHeader(target, key, value) {
33
+ const normalizedKey = normalizeHeaderName(key);
34
+ if (!normalizedKey) return;
35
+ const nextValue = String(value);
36
+ for (const currentKey of Object.keys(target)) if (normalizeHeaderName(currentKey) === normalizedKey) delete target[currentKey];
37
+ target[key] = nextValue;
38
+ }
39
+ function hasHeader(target, key) {
40
+ const normalizedKey = normalizeHeaderName(key);
41
+ return Object.keys(target).some((currentKey) => normalizeHeaderName(currentKey) === normalizedKey);
42
+ }
43
+ function mergeHeaderSource(target, source) {
44
+ if (!source) return;
45
+ if (typeof source[Symbol.iterator] === "function") {
46
+ for (const entry of source) {
47
+ if (!entry || entry.length < 2) continue;
48
+ setHeader(target, entry[0], entry[1]);
49
+ }
50
+ return;
51
+ }
52
+ if (typeof source.forEach === "function") {
53
+ source.forEach((value, key) => {
54
+ setHeader(target, key, value);
55
+ });
56
+ return;
57
+ }
58
+ if (!isObject(source)) return;
59
+ for (const [key, value] of Object.entries(source)) {
60
+ if (Array.isArray(value)) {
61
+ setHeader(target, key, value.join(", "));
62
+ continue;
63
+ }
64
+ setHeader(target, key, value);
65
+ }
66
+ }
67
+ function toHeaderMap(source) {
68
+ const headers = {};
69
+ mergeHeaderSource(headers, source);
70
+ return headers;
71
+ }
72
+ function isRequestLikeInput(input) {
73
+ return isObject(input) && typeof input.url === "string";
74
+ }
75
+ function isFormDataInstance(value) {
76
+ return Boolean(value && typeof value === "object" && (typeof FormData !== "undefined" && value instanceof FormData || value instanceof FormDataPolyfill));
77
+ }
78
+ async function extractRequestBodyFromInput(input) {
79
+ if (!input || typeof input.clone !== "function") return;
80
+ if (input.bodyUsed) throw new TypeError("Failed to execute fetch: request body is already used");
81
+ if (input instanceof RequestPolyfill) return consumeBodyValue(input);
82
+ const body = input;
83
+ if (body.arrayBuffer) return body.arrayBuffer();
84
+ if (body.text) return body.text();
85
+ const cloned = input.clone();
86
+ if (cloned?.arrayBuffer) return cloned.arrayBuffer();
87
+ if (cloned?.text) return cloned.text();
88
+ }
89
+ async function normalizeRequestBody(body, headers) {
90
+ if (body == null) return;
91
+ if (typeof body === "string") {
92
+ if (!hasHeader(headers, "content-type")) headers["content-type"] = "text/plain;charset=UTF-8";
93
+ return body;
94
+ }
95
+ if (isUrlSearchParamsInstance(body)) {
96
+ if (!hasHeader(headers, "content-type")) headers["content-type"] = "application/x-www-form-urlencoded;charset=UTF-8";
97
+ return body.toString();
98
+ }
99
+ if (isArrayBufferLike(body)) return cloneArrayBuffer(body);
100
+ if (ArrayBuffer.isView(body)) return cloneArrayBufferView(body);
101
+ if (isBlobLike(body)) {
102
+ if (body.type && !hasHeader(headers, "content-type")) headers["content-type"] = body.type;
103
+ return body.arrayBuffer();
104
+ }
105
+ if (isFormDataInstance(body)) {
106
+ const payload = await encodeMultipartFormData(body);
107
+ if (!hasHeader(headers, "content-type")) headers["content-type"] = payload.contentType;
108
+ return payload.body;
109
+ }
110
+ return String(body);
111
+ }
112
+ async function resolveRequestMeta(input, init = {}) {
113
+ const requestInput = isRequestLikeInput(input) ? input : void 0;
114
+ const url = typeof input === "string" ? input : isUrlInstance(input) ? input.toString() : requestInput?.url;
115
+ if (!url) throw new TypeError("Failed to execute fetch: invalid request url");
116
+ const method = normalizeMethod(init.method ?? requestInput?.method);
117
+ const headers = toHeaderMap(requestInput?.headers);
118
+ mergeHeaderSource(headers, init.headers);
119
+ const hasBodyInInit = hasOwn.call(init, "body");
120
+ let rawBody = hasBodyInInit ? init.body : await extractRequestBodyFromInput(requestInput);
121
+ if (!hasBodyInInit && requestInput && (method === "GET" || method === "HEAD")) rawBody = void 0;
122
+ if ((method === "GET" || method === "HEAD") && rawBody != null) throw new TypeError("Failed to execute fetch: GET/HEAD request cannot have body");
123
+ return {
124
+ miniProgram: resolveRequestMiniProgramOptions(init.miniProgram, init.miniprogram),
125
+ url,
126
+ method,
127
+ headers,
128
+ body: await normalizeRequestBody(rawBody, headers),
129
+ signal: init.signal ?? requestInput?.signal ?? null
130
+ };
131
+ }
132
+ function createFetchResponse(data, status, headers, url) {
133
+ return new ResponsePolyfill(data instanceof Uint8Array ? cloneArrayBufferView(data) : data, {
134
+ status,
135
+ headers: new HeadersPolyfill(headers),
136
+ url
137
+ });
138
+ }
139
+ function isRequestTask(value) {
140
+ return isObject(value) && typeof value.abort === "function";
141
+ }
142
+ /**
143
+ * @description 使用 @wevu/api 的 request 能力实现 fetch 语义对齐。
144
+ */
145
+ function fetch(input, init) {
146
+ return resolveRequestMeta(input, init).then((meta) => {
147
+ if (meta.signal?.aborted) return Promise.reject(createAbortError());
148
+ return new Promise((resolve, reject) => {
149
+ let settled = false;
150
+ let requestTask;
151
+ function onAbort() {
152
+ if (settled) return;
153
+ requestTask?.abort();
154
+ settled = true;
155
+ if (meta.signal) meta.signal.removeEventListener("abort", onAbort);
156
+ reject(createAbortError());
157
+ }
158
+ function cleanup() {
159
+ if (meta.signal) meta.signal.removeEventListener("abort", onAbort);
160
+ }
161
+ if (meta.signal) meta.signal.addEventListener("abort", onAbort, { once: true });
162
+ const requestResult = wpi.request({
163
+ ...meta.miniProgram,
164
+ url: meta.url,
165
+ method: meta.method,
166
+ header: meta.headers,
167
+ data: meta.body,
168
+ responseType: "arraybuffer",
169
+ success: (res) => {
170
+ if (settled) return;
171
+ settled = true;
172
+ cleanup();
173
+ resolve(createFetchResponse(res.data, res.statusCode, toHeaderMap(res.header), meta.url));
174
+ },
175
+ fail: (error) => {
176
+ if (settled) return;
177
+ settled = true;
178
+ cleanup();
179
+ const message = isObject(error) && typeof error.errMsg === "string" ? error.errMsg : String(error);
180
+ reject(new TypeError(message));
181
+ }
182
+ });
183
+ requestTask = isRequestTask(requestResult) ? requestResult : void 0;
184
+ });
185
+ });
186
+ }
187
+ //#endregion
3
188
  export { fetch };
@@ -0,0 +1,303 @@
1
+ import { d as normalizeHeaderName, h as isUrlSearchParamsInstance, i as decodeText, l as isArrayBufferLike, m as isUrlInstance, n as cloneArrayBuffer, o as encodeText, r as cloneArrayBufferView, u as isBlobLike } from "./shared-BsJRaiBh.mjs";
2
+ import { r as BlobPolyfill, t as FormDataPolyfill } from "./web-kSAO_PSD.mjs";
3
+ //#region src/http/headers.ts
4
+ const SET_COOKIE_HEADER_NAME = "set-cookie";
5
+ function isIterableHeaders(input) {
6
+ return Boolean(input) && typeof input[Symbol.iterator] === "function";
7
+ }
8
+ function isHeaderObject(input) {
9
+ return typeof input === "object" && input !== null;
10
+ }
11
+ var HeadersPolyfill = class {
12
+ store = /* @__PURE__ */ new Map();
13
+ constructor(init) {
14
+ if (!init) return;
15
+ if (isIterableHeaders(init)) {
16
+ for (const [key, value] of init) this.append(key, value);
17
+ return;
18
+ }
19
+ if (typeof init.forEach === "function") {
20
+ init.forEach((value, key) => {
21
+ this.set(key, value);
22
+ });
23
+ return;
24
+ }
25
+ if (isHeaderObject(init)) for (const [key, value] of Object.entries(init)) this.append(key, Array.isArray(value) ? value.join(", ") : String(value));
26
+ }
27
+ append(key, value) {
28
+ const normalized = normalizeHeaderName(key);
29
+ if (!normalized) return;
30
+ const item = this.store.get(normalized);
31
+ if (item) {
32
+ item.values.push(String(value));
33
+ return;
34
+ }
35
+ this.store.set(normalized, {
36
+ key,
37
+ values: [String(value)]
38
+ });
39
+ }
40
+ set(key, value) {
41
+ const normalized = normalizeHeaderName(key);
42
+ if (!normalized) return;
43
+ this.store.set(normalized, {
44
+ key,
45
+ values: [String(value)]
46
+ });
47
+ }
48
+ get(key) {
49
+ return this.store.get(normalizeHeaderName(key))?.values.join(", ") ?? null;
50
+ }
51
+ getSetCookie() {
52
+ return this.store.get(SET_COOKIE_HEADER_NAME)?.values.slice() ?? [];
53
+ }
54
+ has(key) {
55
+ return this.store.has(normalizeHeaderName(key));
56
+ }
57
+ delete(key) {
58
+ this.store.delete(normalizeHeaderName(key));
59
+ }
60
+ forEach(callback, thisArg) {
61
+ for (const { key, values } of this.store.values()) callback.call(thisArg, values.join(", "), key, this);
62
+ }
63
+ entries() {
64
+ return Array.from(this.store.values(), (item) => [item.key, item.values.join(", ")])[Symbol.iterator]();
65
+ }
66
+ keys() {
67
+ return Array.from(this.store.values(), (item) => item.key)[Symbol.iterator]();
68
+ }
69
+ values() {
70
+ return Array.from(this.store.values(), (item) => item.values.join(", "))[Symbol.iterator]();
71
+ }
72
+ [Symbol.iterator]() {
73
+ return this.entries();
74
+ }
75
+ };
76
+ function headersToObject(headers) {
77
+ const result = {};
78
+ headers.forEach((value, key) => {
79
+ result[key] = value;
80
+ });
81
+ return result;
82
+ }
83
+ //#endregion
84
+ //#region src/multipart.ts
85
+ const CRLF = "\r\n";
86
+ function createMultipartBoundary() {
87
+ return `----weapp-vite-formdata-${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;
88
+ }
89
+ function escapeMultipartName(value) {
90
+ return String(value).replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\r/g, "%0D").replace(/\n/g, "%0A");
91
+ }
92
+ function concatArrayBuffers(buffers) {
93
+ const totalLength = buffers.reduce((sum, buffer) => sum + buffer.byteLength, 0);
94
+ const merged = new Uint8Array(totalLength);
95
+ let offset = 0;
96
+ for (const buffer of buffers) {
97
+ merged.set(new Uint8Array(buffer), offset);
98
+ offset += buffer.byteLength;
99
+ }
100
+ return merged.buffer;
101
+ }
102
+ function isBlobFormDataValue(value) {
103
+ return typeof value !== "string" && typeof value?.arrayBuffer === "function";
104
+ }
105
+ function getMultipartFilename(value) {
106
+ const name = value.name;
107
+ return typeof name === "string" && name.length > 0 ? name : "blob";
108
+ }
109
+ async function createMultipartPart(name, value) {
110
+ if (!isBlobFormDataValue(value)) return [
111
+ encodeText(`Content-Disposition: form-data; name="${escapeMultipartName(name)}"${CRLF}${CRLF}`),
112
+ encodeText(String(value)),
113
+ encodeText(CRLF)
114
+ ];
115
+ const filename = getMultipartFilename(value);
116
+ const headers = [
117
+ `Content-Disposition: form-data; name="${escapeMultipartName(name)}"; filename="${escapeMultipartName(filename)}"`,
118
+ `Content-Type: ${value.type || "application/octet-stream"}`,
119
+ "",
120
+ ""
121
+ ].join(CRLF);
122
+ return [
123
+ encodeText(headers),
124
+ await value.arrayBuffer(),
125
+ encodeText(CRLF)
126
+ ];
127
+ }
128
+ async function encodeMultipartFormData(formData) {
129
+ const boundary = createMultipartBoundary();
130
+ const buffers = [];
131
+ for (const [name, value] of formData) {
132
+ buffers.push(encodeText(`--${boundary}${CRLF}`));
133
+ buffers.push(...await createMultipartPart(name, value));
134
+ }
135
+ buffers.push(encodeText(`--${boundary}--${CRLF}`));
136
+ return {
137
+ body: concatArrayBuffers(buffers),
138
+ contentType: `multipart/form-data; boundary=${boundary}`
139
+ };
140
+ }
141
+ //#endregion
142
+ //#region src/http/body.ts
143
+ const bodies = /* @__PURE__ */ new WeakMap();
144
+ function isFormData(value) {
145
+ return value instanceof FormDataPolyfill || typeof FormData === "function" && value instanceof FormData;
146
+ }
147
+ function initializeBody(owner, input) {
148
+ let value;
149
+ let contentType = "";
150
+ if (input == null) value = null;
151
+ else if (isArrayBufferLike(input)) value = cloneArrayBuffer(input);
152
+ else if (ArrayBuffer.isView(input)) value = cloneArrayBufferView(input);
153
+ else if (isBlobLike(input)) {
154
+ value = input;
155
+ contentType = input.type ?? "";
156
+ } else if (isFormData(input)) value = input;
157
+ else if (isUrlSearchParamsInstance(input)) {
158
+ value = input.toString();
159
+ contentType = "application/x-www-form-urlencoded;charset=UTF-8";
160
+ } else {
161
+ value = String(input);
162
+ contentType = "text/plain;charset=UTF-8";
163
+ }
164
+ if (contentType && !owner.headers.has("content-type")) owner.headers.set("content-type", contentType);
165
+ bodies.set(owner, {
166
+ value,
167
+ used: false
168
+ });
169
+ }
170
+ function getBodyValue(owner) {
171
+ return bodies.get(owner)?.value;
172
+ }
173
+ function assertBodyUnused(owner) {
174
+ if (bodies.get(owner)?.used) throw new TypeError("Body has already been consumed");
175
+ }
176
+ /** 在异步转换之前同步占用 body,确保并发读取与请求发送共享消费状态。 */
177
+ function consumeBodyValue(owner) {
178
+ assertBodyUnused(owner);
179
+ const state = bodies.get(owner);
180
+ if (state && state.value != null) state.used = true;
181
+ return state?.value;
182
+ }
183
+ async function bodyBytes(value) {
184
+ if (value == null) return /* @__PURE__ */ new ArrayBuffer(0);
185
+ if (typeof value === "string") return encodeText(value);
186
+ if (isArrayBufferLike(value)) return cloneArrayBuffer(value);
187
+ if (ArrayBuffer.isView(value)) return cloneArrayBufferView(value);
188
+ if (isBlobLike(value)) return cloneArrayBuffer(await value.arrayBuffer());
189
+ return (await encodeMultipartFormData(value)).body;
190
+ }
191
+ /** 仅供 Request/Response 内部复用,不作为包的公开导出。 */
192
+ var HttpBody = class {
193
+ get body() {
194
+ return null;
195
+ }
196
+ get bodyUsed() {
197
+ return bodies.get(this)?.used === true;
198
+ }
199
+ async arrayBuffer() {
200
+ return bodyBytes(consumeBodyValue(this));
201
+ }
202
+ async bytes() {
203
+ return new Uint8Array(await this.arrayBuffer());
204
+ }
205
+ async text() {
206
+ return decodeText(await this.arrayBuffer());
207
+ }
208
+ async json() {
209
+ return JSON.parse(await this.text());
210
+ }
211
+ async blob() {
212
+ const bytes = await this.arrayBuffer();
213
+ const contentType = this.headers.get("content-type") ?? "";
214
+ const type = /^[!#$%&'*+.^`|~\w-]+\/[!#$%&'*+.^`|~\w-]+(?:\s*;[^\r\n]*)?$/.test(contentType) ? contentType : "";
215
+ return new (typeof Blob === "function" ? Blob : BlobPolyfill)([bytes], { type });
216
+ }
217
+ async formData() {
218
+ throw new TypeError("formData is not supported in Body polyfill");
219
+ }
220
+ };
221
+ //#endregion
222
+ //#region src/http/request.ts
223
+ var RequestPolyfill = class RequestPolyfill extends HttpBody {
224
+ url;
225
+ method;
226
+ headers;
227
+ signal;
228
+ [Symbol.toStringTag] = "Request";
229
+ constructor(input, init = {}) {
230
+ super();
231
+ const request = input instanceof RequestPolyfill ? input : void 0;
232
+ this.url = typeof input === "string" ? input : isUrlInstance(input) ? input.toString() : request?.url ?? "";
233
+ this.method = String(init.method ?? request?.method ?? "GET").toUpperCase();
234
+ this.headers = new HeadersPolyfill(init.headers ?? request?.headers);
235
+ this.signal = init.signal ?? request?.signal ?? null;
236
+ const inherited = init.body == null && request;
237
+ if (inherited) assertBodyUnused(request);
238
+ initializeBody(this, init.body ?? (request ? getBodyValue(request) : void 0));
239
+ if (inherited) consumeBodyValue(request);
240
+ }
241
+ clone() {
242
+ assertBodyUnused(this);
243
+ return new RequestPolyfill(this.url, {
244
+ method: this.method,
245
+ headers: this.headers,
246
+ signal: this.signal,
247
+ body: getBodyValue(this)
248
+ });
249
+ }
250
+ };
251
+ function getRequestBodyValue(request) {
252
+ return request ? getBodyValue(request) : void 0;
253
+ }
254
+ //#endregion
255
+ //#region src/http/response.ts
256
+ var ResponsePolyfill = class ResponsePolyfill extends HttpBody {
257
+ headers;
258
+ status;
259
+ statusText;
260
+ ok;
261
+ url;
262
+ redirected = false;
263
+ type;
264
+ [Symbol.toStringTag] = "Response";
265
+ constructor(body, init = {}) {
266
+ super();
267
+ this.status = Number.isFinite(init.status) ? init.status : 200;
268
+ this.statusText = init.statusText ?? "";
269
+ this.ok = this.status >= 200 && this.status < 300;
270
+ this.headers = new HeadersPolyfill(init.headers);
271
+ this.url = init.url ?? "";
272
+ this.type = init.type ?? "basic";
273
+ initializeBody(this, body);
274
+ }
275
+ static error() {
276
+ return new ResponsePolyfill(null, {
277
+ status: 0,
278
+ type: "error"
279
+ });
280
+ }
281
+ static json(data, init = {}) {
282
+ const body = JSON.stringify(data);
283
+ if (body === void 0) throw new TypeError("Failed to execute 'json' on 'Response': data is not JSON serializable");
284
+ const headers = new HeadersPolyfill(init.headers);
285
+ if (!headers.has("content-type")) headers.set("content-type", "application/json");
286
+ return new ResponsePolyfill(body, {
287
+ ...init,
288
+ headers
289
+ });
290
+ }
291
+ clone() {
292
+ assertBodyUnused(this);
293
+ return new ResponsePolyfill(getBodyValue(this), {
294
+ status: this.status,
295
+ statusText: this.statusText,
296
+ headers: this.headers,
297
+ url: this.url,
298
+ type: this.type
299
+ });
300
+ }
301
+ };
302
+ //#endregion
303
+ export { encodeMultipartFormData as a, consumeBodyValue as i, RequestPolyfill as n, HeadersPolyfill as o, getRequestBodyValue as r, headersToObject as s, ResponsePolyfill as t };
@@ -0,0 +1,66 @@
1
+ import { t as RequestGlobalsBlobLike } from "./shared-Dc42USJC.mjs";
2
+ import { t as URLPolyfill } from "./url-D0ANYIyk.mjs";
3
+ import { n as FormDataPolyfill, o as BlobPolyfill } from "./web-DNBBg6y9.mjs";
4
+ //#region src/http/headers.d.ts
5
+ type HeaderRecord = Record<string, string>;
6
+ declare class HeadersPolyfill {
7
+ private readonly store;
8
+ constructor(init?: unknown);
9
+ append(key: string, value: string): void;
10
+ set(key: string, value: string): void;
11
+ get(key: string): string | null;
12
+ getSetCookie(): string[];
13
+ has(key: string): boolean;
14
+ delete(key: string): void;
15
+ forEach(callback: (value: string, key: string, parent: HeadersPolyfill) => void, thisArg?: unknown): void;
16
+ entries(): ArrayIterator<[string, string]>;
17
+ keys(): ArrayIterator<string>;
18
+ values(): ArrayIterator<string>;
19
+ [Symbol.iterator](): ArrayIterator<[string, string]>;
20
+ }
21
+ declare function headersToObject(headers: HeadersPolyfill | Headers): HeaderRecord;
22
+ //#endregion
23
+ //#region src/http/body.d.ts
24
+ type RequestBodyLike = string | ArrayBuffer | ArrayBufferView | Blob | RequestGlobalsBlobLike | FormData | FormDataPolyfill | null | undefined;
25
+ /** 仅供 Request/Response 内部复用,不作为包的公开导出。 */
26
+ declare abstract class HttpBody {
27
+ abstract readonly headers: HeadersPolyfill;
28
+ get body(): ReadableStream<Uint8Array> | null;
29
+ get bodyUsed(): boolean;
30
+ arrayBuffer(): Promise<ArrayBuffer>;
31
+ bytes(): Promise<Uint8Array<ArrayBuffer>>;
32
+ text(): Promise<string>;
33
+ json(): Promise<any>;
34
+ blob(): Promise<Blob | BlobPolyfill>;
35
+ formData(): Promise<FormData>;
36
+ }
37
+ //#endregion
38
+ //#region src/http/request.d.ts
39
+ declare class RequestPolyfill extends HttpBody {
40
+ readonly url: string;
41
+ readonly method: string;
42
+ readonly headers: HeadersPolyfill;
43
+ readonly signal: AbortSignal | null;
44
+ readonly [Symbol.toStringTag] = "Request";
45
+ constructor(input: string | URL | URLPolyfill | RequestPolyfill, init?: Record<string, any>);
46
+ clone(): RequestPolyfill;
47
+ }
48
+ declare function getRequestBodyValue(request?: RequestPolyfill): RequestBodyLike;
49
+ //#endregion
50
+ //#region src/http/response.d.ts
51
+ declare class ResponsePolyfill extends HttpBody {
52
+ readonly headers: HeadersPolyfill;
53
+ readonly status: number;
54
+ readonly statusText: string;
55
+ readonly ok: boolean;
56
+ readonly url: string;
57
+ readonly redirected = false;
58
+ readonly type: ResponseType;
59
+ readonly [Symbol.toStringTag] = "Response";
60
+ constructor(body?: RequestBodyLike, init?: Record<string, any>);
61
+ static error(): ResponsePolyfill;
62
+ static json(data: unknown, init?: Record<string, any>): ResponsePolyfill;
63
+ clone(): ResponsePolyfill;
64
+ }
65
+ //#endregion
66
+ export { headersToObject as a, HeadersPolyfill as i, RequestPolyfill as n, getRequestBodyValue as r, ResponsePolyfill as t };
package/dist/http.d.mts CHANGED
@@ -1,58 +1,2 @@
1
- import { RequestGlobalsBlobLike } from "./shared.mjs";
2
- import { URLPolyfill } from "./url.mjs";
3
- import { FormDataPolyfill } from "./web.mjs";
4
- //#region src/http.d.ts
5
- type HeaderRecord = Record<string, string>;
6
- export declare class HeadersPolyfill {
7
- private readonly store;
8
- constructor(init?: unknown);
9
- append(key: string, value: string): void;
10
- set(key: string, value: string): void;
11
- get(key: string): string | null;
12
- getSetCookie(): string[];
13
- has(key: string): boolean;
14
- delete(key: string): void;
15
- forEach(callback: (value: string, key: string) => void): void;
16
- entries(): ArrayIterator<[string, string]>;
17
- keys(): ArrayIterator<string>;
18
- values(): ArrayIterator<string>;
19
- [Symbol.iterator](): ArrayIterator<[string, string]>;
20
- }
21
- type RequestBodyLike = string | ArrayBuffer | ArrayBufferView | Blob | RequestGlobalsBlobLike | FormData | FormDataPolyfill | null | undefined;
22
- export declare function getRequestBodyValue(request?: RequestPolyfill): RequestBodyLike;
23
- export declare class RequestPolyfill {
24
- readonly url: string;
25
- readonly method: string;
26
- readonly headers: HeadersPolyfill;
27
- readonly signal: AbortSignal | null;
28
- readonly [Symbol.toStringTag] = "Request";
29
- constructor(input: string | URL | URLPolyfill | RequestPolyfill, init?: Record<string, any>);
30
- get body(): ReadableStream<Uint8Array> | null;
31
- get bodyUsed(): boolean;
32
- arrayBuffer(): Promise<ArrayBuffer>;
33
- text(): Promise<string>;
34
- clone(): RequestPolyfill;
35
- }
36
- export declare class ResponsePolyfill {
37
- readonly headers: HeadersPolyfill;
38
- readonly status: number;
39
- readonly statusText: string;
40
- readonly ok: boolean;
41
- readonly url: string;
42
- readonly redirected = false;
43
- readonly type: ResponseType;
44
- readonly [Symbol.toStringTag] = "Response";
45
- constructor(body?: RequestBodyLike, init?: Record<string, any>);
46
- static error(): ResponsePolyfill;
47
- static json(data: unknown, init?: Record<string, any>): ResponsePolyfill;
48
- get body(): ReadableStream<Uint8Array> | null;
49
- get bodyUsed(): boolean;
50
- arrayBuffer(): Promise<ArrayBuffer>;
51
- blob(): Promise<Blob>;
52
- formData(): Promise<void>;
53
- json(): Promise<any>;
54
- text(): Promise<string>;
55
- clone(): ResponsePolyfill;
56
- }
57
- export declare function headersToObject(headers: HeadersPolyfill | Headers): HeaderRecord;
58
- //#endregion
1
+ import { a as headersToObject, i as HeadersPolyfill, n as RequestPolyfill, r as getRequestBodyValue, t as ResponsePolyfill } from "./http-CE8-CIHE.mjs";
2
+ export { HeadersPolyfill, RequestPolyfill, ResponsePolyfill, getRequestBodyValue, headersToObject };