@base-web-kits/base-tools-web 1.1.0 → 1.1.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/dist/base-tools-web.umd.global.js +53 -3
- package/dist/base-tools-web.umd.global.js.map +1 -1
- package/dist/index.cjs +53 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +53 -3
- package/dist/index.js.map +1 -1
- package/dist/network/request.d.ts +2 -2
- package/dist/network/request.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/web/network/request.ts +73 -10
|
@@ -63,7 +63,7 @@ export interface RequestTask {
|
|
|
63
63
|
/** 取消请求 */
|
|
64
64
|
abort: () => void;
|
|
65
65
|
/** 监听流式数据块接收事件 */
|
|
66
|
-
|
|
66
|
+
onProgressUpdate: (callback: ChunkCallback) => void;
|
|
67
67
|
/** 取消监听流式数据块接收事件 */
|
|
68
68
|
offChunkReceived: () => void;
|
|
69
69
|
}
|
|
@@ -138,7 +138,7 @@ export type ChunkCallback = (response: {
|
|
|
138
138
|
*
|
|
139
139
|
* const { task } = apiChatStream({question: '你好'}); // 发起流式请求
|
|
140
140
|
*
|
|
141
|
-
* task.
|
|
141
|
+
* task.onProgressUpdate((res) => {
|
|
142
142
|
* console.log('ArrayBuffer', res.data); // 接收流式数据
|
|
143
143
|
* });
|
|
144
144
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/web/network/request.ts"],"names":[],"mappings":"AAWA,aAAa;AACb,MAAM,MAAM,aAAa,GACrB,KAAK,GACL,MAAM,GACN,KAAK,GACL,QAAQ,GACR,SAAS,GACT,MAAM,GACN,SAAS,GACT,OAAO,GACP,OAAO,CAAC;AAEZ;;;GAGG;AACH,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,WAAW,GACX,eAAe,GACf,IAAI,GACJ,QAAQ,GACR,eAAe,GACf,cAAc,CAAC,UAAU,CAAC,GAC1B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,OAAO,EAAE,GACT,IAAI,CAAC;AAET;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,WAAW,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;AAEpG;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;AAE/F;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,IAAI;IACnE,WAAW;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW;IACX,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,UAAU;IACV,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,WAAW;IACX,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,0BAA0B;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,uDAAuD;IACvD,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;IAEvB,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IAEf,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAEhB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,YAAY;IACZ,WAAW,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAEjC,cAAc;IACd,WAAW,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAEjC,uBAAuB;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,wBAAwB;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,sBAAsB;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnC,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,uBAAuB;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,MAAM,CAAC;IAE/C,WAAW;IACX,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,YAAY,CAAC;CAC5D,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,WAAW;IACX,KAAK,EAAE,MAAM,IAAI,CAAC;IAElB,kBAAkB;IAClB,
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/web/network/request.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -113,7 +113,7 @@ export interface RequestTask {
|
|
|
113
113
|
abort: () => void;
|
|
114
114
|
|
|
115
115
|
/** 监听流式数据块接收事件 */
|
|
116
|
-
|
|
116
|
+
onProgressUpdate: (callback: ChunkCallback) => void;
|
|
117
117
|
|
|
118
118
|
/** 取消监听流式数据块接收事件 */
|
|
119
119
|
offChunkReceived: () => void;
|
|
@@ -192,7 +192,7 @@ const requestCache = new Map<string, { res: unknown; expire: number }>();
|
|
|
192
192
|
*
|
|
193
193
|
* const { task } = apiChatStream({question: '你好'}); // 发起流式请求
|
|
194
194
|
*
|
|
195
|
-
* task.
|
|
195
|
+
* task.onProgressUpdate((res) => {
|
|
196
196
|
* console.log('ArrayBuffer', res.data); // 接收流式数据
|
|
197
197
|
* });
|
|
198
198
|
*
|
|
@@ -208,7 +208,7 @@ export function request<T, D extends RequestData = RequestData>(config: RequestC
|
|
|
208
208
|
// 构造 Task 对象
|
|
209
209
|
const task: RequestTask = {
|
|
210
210
|
abort: () => controller.abort(),
|
|
211
|
-
|
|
211
|
+
onProgressUpdate: (cb) => {
|
|
212
212
|
chunkCallback = cb;
|
|
213
213
|
},
|
|
214
214
|
offChunkReceived: () => {
|
|
@@ -250,7 +250,13 @@ export function request<T, D extends RequestData = RequestData>(config: RequestC
|
|
|
250
250
|
// 请求头: 过滤空值 (undefined 、null 、"" 、false 、0), 因为服务器端接收到的都是字符串
|
|
251
251
|
const fillHeader = (header ? pickBy(header, (val) => !!val) : {}) as Record<string, string>;
|
|
252
252
|
|
|
253
|
-
|
|
253
|
+
// 获取 Content-Type (忽略大小写)
|
|
254
|
+
const contentTypeKey = Object.keys(fillHeader).find(
|
|
255
|
+
(k) => k.toLowerCase() === 'content-type',
|
|
256
|
+
);
|
|
257
|
+
const contentType = contentTypeKey ? fillHeader[contentTypeKey].toLowerCase() : '';
|
|
258
|
+
|
|
259
|
+
if (!isGet && fillData && (isObjectData || isArrayData) && !contentType) {
|
|
254
260
|
fillHeader['Content-Type'] = 'application/json';
|
|
255
261
|
}
|
|
256
262
|
|
|
@@ -258,12 +264,23 @@ export function request<T, D extends RequestData = RequestData>(config: RequestC
|
|
|
258
264
|
const fillUrl =
|
|
259
265
|
isGet && isObjectData ? appendUrlParam(url, fillData as Record<string, unknown>) : url;
|
|
260
266
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
+
let fillBody: BodyInit | null | undefined;
|
|
268
|
+
|
|
269
|
+
if (!isGet && fillData) {
|
|
270
|
+
if (isObjectData && contentType.includes('application/x-www-form-urlencoded')) {
|
|
271
|
+
// application/x-www-form-urlencoded: 转换为 URLSearchParams
|
|
272
|
+
fillBody = toSearchParams(fillData as Record<string, unknown>);
|
|
273
|
+
} else if (isObjectData && contentType.includes('multipart/form-data')) {
|
|
274
|
+
// multipart/form-data: 转换为 FormData
|
|
275
|
+
fillBody = toFormData(fillData as Record<string, unknown>);
|
|
276
|
+
// 删除 Content-Type, 让 fetch 自动生成 boundary
|
|
277
|
+
if (contentTypeKey) delete fillHeader[contentTypeKey];
|
|
278
|
+
} else if (isObjectData || isArrayData) {
|
|
279
|
+
fillBody = JSON.stringify(fillData);
|
|
280
|
+
} else {
|
|
281
|
+
fillBody = fillData as BodyInit;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
267
284
|
|
|
268
285
|
// 2.3 日志与缓存配置
|
|
269
286
|
const logConfig = { ...config, data: fillData, header: fillHeader, url: fillUrl };
|
|
@@ -489,3 +506,49 @@ async function parseResponse(response: Response, responseType: string) {
|
|
|
489
506
|
}
|
|
490
507
|
return resData;
|
|
491
508
|
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* 转换为 URLSearchParams
|
|
512
|
+
*/
|
|
513
|
+
function toSearchParams(data: Record<string, unknown>) {
|
|
514
|
+
const params = new URLSearchParams();
|
|
515
|
+
for (const key in data) {
|
|
516
|
+
const val = data[key];
|
|
517
|
+
// undefined 已在 fillData 阶段过滤,此处仅需判断 null
|
|
518
|
+
// null 在 Form 中会被转为字符串 "null",通常不符合预期,故过滤
|
|
519
|
+
if (val === null) continue;
|
|
520
|
+
if (Array.isArray(val)) {
|
|
521
|
+
val.forEach((v) => params.append(key, typeof v === 'object' ? JSON.stringify(v) : String(v)));
|
|
522
|
+
} else {
|
|
523
|
+
params.append(key, typeof val === 'object' ? JSON.stringify(val) : String(val));
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
return params;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* 转换为 FormData
|
|
531
|
+
*/
|
|
532
|
+
function toFormData(data: Record<string, unknown>) {
|
|
533
|
+
const formData = new FormData();
|
|
534
|
+
for (const key in data) {
|
|
535
|
+
const val = data[key];
|
|
536
|
+
// undefined 已在 fillData 阶段过滤,此处仅需判断 null
|
|
537
|
+
// null 在 Form 中会被转为字符串 "null",通常不符合预期,故过滤
|
|
538
|
+
if (val === null) continue;
|
|
539
|
+
if (Array.isArray(val)) {
|
|
540
|
+
val.forEach((v) =>
|
|
541
|
+
formData.append(
|
|
542
|
+
key,
|
|
543
|
+
v instanceof Blob ? v : typeof v === 'object' ? JSON.stringify(v) : String(v),
|
|
544
|
+
),
|
|
545
|
+
);
|
|
546
|
+
} else {
|
|
547
|
+
formData.append(
|
|
548
|
+
key,
|
|
549
|
+
val instanceof Blob ? val : typeof val === 'object' ? JSON.stringify(val) : String(val),
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
return formData;
|
|
554
|
+
}
|