@kevisual/query 0.0.40 → 0.0.41

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.
@@ -1,131 +1,114 @@
1
- const isTextForContentType = (contentType) => {
2
- if (!contentType)
3
- return false;
4
- const textTypes = ['text/', 'xml', 'html', 'javascript', 'css', 'csv', 'plain', 'x-www-form-urlencoded', 'md'];
5
- return textTypes.some((type) => contentType.includes(type));
1
+ // src/adapter.ts
2
+ var isTextForContentType = (contentType) => {
3
+ if (!contentType)
4
+ return false;
5
+ const textTypes = ["text/", "xml", "html", "javascript", "css", "csv", "plain", "x-www-form-urlencoded", "md"];
6
+ return textTypes.some((type) => contentType.includes(type));
6
7
  };
7
- /**
8
- *
9
- * @param opts
10
- * @param overloadOpts 覆盖fetch的默认配置
11
- * @returns
12
- */
13
- const adapter = async (opts = {}, overloadOpts) => {
14
- const controller = new AbortController();
15
- const signal = controller.signal;
16
- const isPostFile = opts.isPostFile || false; // 是否为文件上传
17
- let responseType = opts.responseType || 'json'; // 响应类型
18
- if (opts.isBlob) {
19
- responseType = 'blob';
20
- }
21
- else if (opts.isText) {
22
- responseType = 'text';
23
- }
24
- const timeout = opts.timeout || 60000 * 3; // 默认超时时间为 60s * 3
25
- const timer = setTimeout(() => {
26
- controller.abort();
27
- }, timeout);
28
- let method = overloadOpts?.method || opts?.method || 'POST';
29
- let headers = { ...opts?.headers, ...overloadOpts?.headers };
30
- let origin = '';
31
- let url;
32
- if (opts?.url?.startsWith('http')) {
33
- url = new URL(opts.url);
34
- }
35
- else {
36
- origin = window?.location?.origin || 'http://localhost:51515';
37
- url = new URL(opts?.url || '', origin);
38
- }
39
- const isGet = method === 'GET';
40
- const oldSearchParams = url.searchParams;
41
- if (isGet) {
42
- let searchParams = new URLSearchParams({ ...Object.fromEntries(oldSearchParams), ...opts?.params, ...opts?.body });
43
- url.search = searchParams.toString();
44
- }
45
- else {
46
- const params = {
47
- ...Object.fromEntries(oldSearchParams),
48
- ...opts.params,
49
- };
50
- const searchParams = new URLSearchParams(params);
51
- if (typeof opts.body === 'object' && opts.body !== null) {
52
- // 浏览器环境下,自动将 body 中的 path 和 key 提取到查询参数中, 更容易排查问题
53
- let body = opts.body || {};
54
- if (!params.path && body?.path) {
55
- searchParams.set('path', body.path);
56
- if (body?.key) {
57
- searchParams.set('key', body.key);
58
- }
59
- }
60
- }
61
- url.search = searchParams.toString();
62
- }
63
- let body = undefined;
64
- if (isGet) {
65
- body = undefined;
66
- }
67
- else if (isPostFile) {
68
- body = opts.body; // 如果是文件上传,直接使用 FormData
69
- }
70
- else {
71
- if (opts.body && typeof opts.body === 'object' && !(opts.body instanceof FormData)) {
72
- headers = {
73
- 'Content-Type': 'application/json',
74
- ...headers,
75
- };
76
- body = JSON.stringify(opts.body); // 否则将对象转换为 JSON 字符串
77
- }
78
- }
79
- return fetch(url, {
80
- method: method.toUpperCase(),
81
- signal,
82
- body: body,
83
- ...overloadOpts,
84
- headers: headers,
85
- })
86
- .then(async (response) => {
87
- // 获取 Content-Type 头部信息
88
- const contentType = response.headers.get('Content-Type');
89
- if (responseType === 'blob') {
90
- return await response.blob(); // 直接返回 Blob 对象
91
- }
92
- const isText = responseType === 'text';
93
- const isJson = contentType && contentType.includes('application/json');
94
- // 判断返回的数据类型
95
- if (isJson && !isText) {
96
- return await response.json(); // 解析为 JSON
97
- }
98
- else if (isTextForContentType(contentType)) {
99
- return {
100
- code: response.status,
101
- status: response.status,
102
- data: await response.text(), // 直接返回文本内容
103
- };
104
- }
105
- else {
106
- return response;
107
- }
108
- })
109
- .catch((err) => {
110
- if (err.name === 'AbortError') {
111
- return {
112
- code: 408,
113
- message: '请求超时',
114
- };
115
- }
116
- return {
117
- code: 500,
118
- message: err.message || '网络错误',
119
- };
120
- })
121
- .finally(() => {
122
- clearTimeout(timer);
123
- });
8
+ var adapter = async (opts = {}, overloadOpts) => {
9
+ const controller = new AbortController;
10
+ const signal = controller.signal;
11
+ const isPostFile = opts.isPostFile || false;
12
+ let responseType = opts.responseType || "json";
13
+ if (opts.isBlob) {
14
+ responseType = "blob";
15
+ } else if (opts.isText) {
16
+ responseType = "text";
17
+ }
18
+ const timeout = opts.timeout || 60000 * 3;
19
+ const timer = setTimeout(() => {
20
+ controller.abort();
21
+ }, timeout);
22
+ let method = overloadOpts?.method || opts?.method || "POST";
23
+ let headers = { ...opts?.headers, ...overloadOpts?.headers };
24
+ let origin = "";
25
+ let url;
26
+ if (opts?.url?.startsWith("http")) {
27
+ url = new URL(opts.url);
28
+ } else {
29
+ origin = globalThis?.location?.origin || "http://localhost:51515";
30
+ url = new URL(opts?.url || "", origin);
31
+ }
32
+ const isGet = method === "GET";
33
+ const oldSearchParams = url.searchParams;
34
+ if (isGet) {
35
+ let searchParams = new URLSearchParams({ ...Object.fromEntries(oldSearchParams), ...opts?.params, ...opts?.body });
36
+ url.search = searchParams.toString();
37
+ } else {
38
+ const params = {
39
+ ...Object.fromEntries(oldSearchParams),
40
+ ...opts.params
41
+ };
42
+ const searchParams = new URLSearchParams(params);
43
+ if (typeof opts.body === "object" && opts.body !== null) {
44
+ let body2 = opts.body || {};
45
+ if (!params.path && body2?.path) {
46
+ searchParams.set("path", body2.path);
47
+ if (body2?.key) {
48
+ searchParams.set("key", body2.key);
49
+ }
50
+ }
51
+ }
52
+ url.search = searchParams.toString();
53
+ }
54
+ let body = undefined;
55
+ if (isGet) {
56
+ body = undefined;
57
+ } else if (isPostFile) {
58
+ body = opts.body;
59
+ } else {
60
+ if (opts.body && typeof opts.body === "object" && !(opts.body instanceof FormData)) {
61
+ headers = {
62
+ "Content-Type": "application/json",
63
+ ...headers
64
+ };
65
+ body = JSON.stringify(opts.body);
66
+ }
67
+ }
68
+ return fetch(url, {
69
+ method: method.toUpperCase(),
70
+ signal,
71
+ body,
72
+ ...overloadOpts,
73
+ headers
74
+ }).then(async (response) => {
75
+ const contentType = response.headers.get("Content-Type");
76
+ if (responseType === "blob") {
77
+ return await response.blob();
78
+ }
79
+ const isText = responseType === "text";
80
+ const isJson = contentType && contentType.includes("application/json");
81
+ if (isJson && !isText) {
82
+ return await response.json();
83
+ } else if (isTextForContentType(contentType)) {
84
+ return {
85
+ code: response.status,
86
+ status: response.status,
87
+ data: await response.text()
88
+ };
89
+ } else {
90
+ return response;
91
+ }
92
+ }).catch((err) => {
93
+ if (err.name === "AbortError") {
94
+ return {
95
+ code: 408,
96
+ message: "请求超时"
97
+ };
98
+ }
99
+ return {
100
+ code: 500,
101
+ message: err.message || "网络错误"
102
+ };
103
+ }).finally(() => {
104
+ clearTimeout(timer);
105
+ });
124
106
  };
125
107
 
126
- const createStoreImpl = (createState) => {
108
+ // node_modules/.pnpm/zustand@5.0.11/node_modules/zustand/esm/vanilla.mjs
109
+ var createStoreImpl = (createState) => {
127
110
  let state;
128
- const listeners = /* @__PURE__ */ new Set();
111
+ const listeners = /* @__PURE__ */ new Set;
129
112
  const setState = (partial, replace) => {
130
113
  const nextState = typeof partial === "function" ? partial(state) : partial;
131
114
  if (!Object.is(nextState, state)) {
@@ -144,479 +127,403 @@ const createStoreImpl = (createState) => {
144
127
  const initialState = state = createState(setState, getState, api);
145
128
  return api;
146
129
  };
147
- const createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);
130
+ var createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;
148
131
 
149
- const parseWsUrl = (url) => {
150
- try {
151
- new URL(url);
152
- return url;
153
- }
154
- catch (e) {
155
- const _url = new URL(url, location.origin);
156
- if (_url.protocol === 'http:') {
157
- _url.protocol = 'ws:';
158
- }
159
- if (_url.protocol === 'https:') {
160
- _url.protocol = 'wss:';
161
- }
162
- return _url.href;
163
- }
132
+ // src/utils.ts
133
+ var parseWsUrl = (url) => {
134
+ try {
135
+ new URL(url);
136
+ return url;
137
+ } catch (e) {
138
+ const _url = new URL(url, location.origin);
139
+ if (_url.protocol === "http:") {
140
+ _url.protocol = "ws:";
141
+ }
142
+ if (_url.protocol === "https:") {
143
+ _url.protocol = "wss:";
144
+ }
145
+ return _url.href;
146
+ }
164
147
  };
165
148
 
149
+ // src/ws.ts
166
150
  class QueryWs {
167
- url;
168
- store;
169
- ws;
170
- constructor(opts) {
171
- const url = opts?.url || '/api/router';
172
- if (opts?.store) {
173
- this.store = opts.store;
174
- }
175
- else {
176
- const store = createStore((set) => ({
177
- connected: false,
178
- status: 'connecting',
179
- setConnected: (connected) => set({ connected }),
180
- setStatus: (status) => set({ status }),
181
- }));
182
- this.store = store;
183
- }
184
- const wsUrl = parseWsUrl(url);
185
- if (opts?.ws && opts.ws instanceof WebSocket) {
186
- this.ws = opts.ws;
187
- }
188
- else {
189
- this.ws = new WebSocket(wsUrl);
190
- }
191
- this.connect();
192
- }
193
- /**
194
- * 连接 WebSocket
195
- */
196
- async connect(opts) {
197
- const store = this.store;
198
- const that = this;
199
- const connected = store.getState().connected;
200
- if (connected) {
201
- return Promise.resolve(true);
202
- }
203
- return new Promise((resolve, reject) => {
204
- const ws = that.ws || new WebSocket(that.url);
205
- const timeout = opts?.timeout || 5 * 60 * 1000; // 默认 5 分钟
206
- let timer = setTimeout(() => {
207
- const isOpen = ws.readyState === WebSocket.OPEN;
208
- if (isOpen) {
209
- console.log('WebSocket 连接成功 in timer');
210
- resolve(true);
211
- return;
212
- }
213
- console.error('WebSocket 连接超时', that.url);
214
- resolve(false);
215
- }, timeout);
216
- ws.onopen = (ev) => {
217
- store.getState().setConnected(true);
218
- store.getState().setStatus('connected');
219
- resolve(true);
220
- clearTimeout(timer);
221
- };
222
- ws.onclose = (ev) => {
223
- store.getState().setConnected(false);
224
- store.getState().setStatus('disconnected');
225
- this.ws = null;
226
- };
227
- });
228
- }
229
- /**
230
- * ws.onopen 必须用这个去获取,否者会丢失链接信息
231
- * @param callback
232
- * @returns
233
- */
234
- listenConnect(callback) {
235
- const store = this.store;
236
- const { connected } = store.getState();
237
- if (connected) {
238
- callback();
239
- return;
240
- }
241
- const subscriptionOne = (selector, listener) => {
242
- const unsubscribe = store.subscribe((newState, oldState) => {
243
- if (selector(newState) !== selector(oldState)) {
244
- listener(newState, oldState);
245
- unsubscribe();
246
- }
247
- });
248
- return unsubscribe;
249
- };
250
- const cancel = subscriptionOne((state) => state.connected, () => {
251
- callback();
252
- });
253
- return cancel;
254
- }
255
- listenClose(callback) {
256
- const store = this.store;
257
- const { status } = store.getState();
258
- if (status === 'disconnected') {
259
- callback();
260
- }
261
- const subscriptionOne = (selector, listener) => {
262
- const unsubscribe = store.subscribe((newState, oldState) => {
263
- if (selector(newState) !== selector(oldState)) {
264
- listener(newState, oldState);
265
- unsubscribe();
266
- }
267
- });
268
- return unsubscribe;
269
- };
270
- const cancel = subscriptionOne((state) => state.status, (newState, oldState) => {
271
- if (newState.status === 'disconnected') {
272
- callback();
273
- }
274
- });
275
- return cancel;
276
- }
277
- onMessage(fn, opts) {
278
- const ws = this.ws;
279
- const isJson = opts?.isJson ?? true;
280
- const selector = opts?.selector;
281
- const parseIfJson = (data) => {
282
- try {
283
- return JSON.parse(data);
284
- }
285
- catch (e) {
286
- return data;
287
- }
288
- };
289
- const listener = (event) => {
290
- const received = parseIfJson(event.data);
291
- if (typeof received === 'string' && !isJson) {
292
- fn(received, event);
293
- }
294
- else if (typeof received === 'object' && isJson) {
295
- fn(selector ? selector(received) : received, event);
296
- }
297
- else ;
298
- };
299
- ws.addEventListener('message', listener);
300
- return () => {
301
- ws.removeEventListener('message', listener);
302
- };
303
- }
304
- close() {
305
- const ws = this.ws;
306
- const store = this.store;
307
- ws?.close?.();
308
- this.ws = null;
151
+ url;
152
+ store;
153
+ ws;
154
+ constructor(opts) {
155
+ const url = opts?.url || "/api/router";
156
+ if (opts?.store) {
157
+ this.store = opts.store;
158
+ } else {
159
+ const store = createStore((set) => ({
160
+ connected: false,
161
+ status: "connecting",
162
+ setConnected: (connected) => set({ connected }),
163
+ setStatus: (status) => set({ status })
164
+ }));
165
+ this.store = store;
166
+ }
167
+ const wsUrl = parseWsUrl(url);
168
+ if (opts?.ws && opts.ws instanceof WebSocket) {
169
+ this.ws = opts.ws;
170
+ } else {
171
+ this.ws = new WebSocket(wsUrl);
172
+ }
173
+ this.connect();
174
+ }
175
+ async connect(opts) {
176
+ const store = this.store;
177
+ const that = this;
178
+ const connected = store.getState().connected;
179
+ if (connected) {
180
+ return Promise.resolve(true);
181
+ }
182
+ return new Promise((resolve, reject) => {
183
+ const ws = that.ws || new WebSocket(that.url);
184
+ const timeout = opts?.timeout || 5 * 60 * 1000;
185
+ let timer = setTimeout(() => {
186
+ const isOpen = ws.readyState === WebSocket.OPEN;
187
+ if (isOpen) {
188
+ console.log("WebSocket 连接成功 in timer");
189
+ resolve(true);
190
+ return;
191
+ }
192
+ console.error("WebSocket 连接超时", that.url);
193
+ resolve(false);
194
+ }, timeout);
195
+ ws.onopen = (ev) => {
196
+ store.getState().setConnected(true);
197
+ store.getState().setStatus("connected");
198
+ resolve(true);
199
+ clearTimeout(timer);
200
+ };
201
+ ws.onclose = (ev) => {
309
202
  store.getState().setConnected(false);
310
- store.getState().setStatus('disconnected');
311
- }
312
- /**
313
- * 发送消息
314
- *
315
- * @param data
316
- * @param opts
317
- * @returns
318
- */
319
- send(data, opts) {
320
- const ws = this.ws;
321
- const isJson = opts?.isJson ?? true;
322
- const wrapper = opts?.wrapper;
323
- if (!ws || ws.readyState !== WebSocket.OPEN) {
324
- console.error('WebSocket is not open');
325
- return;
326
- }
327
- if (isJson) {
328
- ws.send(JSON.stringify(wrapper ? wrapper(data) : data));
329
- }
330
- else {
331
- ws.send(data);
332
- }
333
- }
334
- getOpen() {
335
- if (!this.ws) {
336
- return false;
337
- }
338
- return this.ws.readyState === WebSocket.OPEN;
339
- }
203
+ store.getState().setStatus("disconnected");
204
+ this.ws = null;
205
+ };
206
+ });
207
+ }
208
+ listenConnect(callback) {
209
+ const store = this.store;
210
+ const { connected } = store.getState();
211
+ if (connected) {
212
+ callback();
213
+ return;
214
+ }
215
+ const subscriptionOne = (selector, listener) => {
216
+ const unsubscribe = store.subscribe((newState, oldState) => {
217
+ if (selector(newState) !== selector(oldState)) {
218
+ listener(newState, oldState);
219
+ unsubscribe();
220
+ }
221
+ });
222
+ return unsubscribe;
223
+ };
224
+ const cancel = subscriptionOne((state) => state.connected, () => {
225
+ callback();
226
+ });
227
+ return cancel;
228
+ }
229
+ listenClose(callback) {
230
+ const store = this.store;
231
+ const { status } = store.getState();
232
+ if (status === "disconnected") {
233
+ callback();
234
+ }
235
+ const subscriptionOne = (selector, listener) => {
236
+ const unsubscribe = store.subscribe((newState, oldState) => {
237
+ if (selector(newState) !== selector(oldState)) {
238
+ listener(newState, oldState);
239
+ unsubscribe();
240
+ }
241
+ });
242
+ return unsubscribe;
243
+ };
244
+ const cancel = subscriptionOne((state) => state.status, (newState, oldState) => {
245
+ if (newState.status === "disconnected") {
246
+ callback();
247
+ }
248
+ });
249
+ return cancel;
250
+ }
251
+ onMessage(fn, opts) {
252
+ const ws = this.ws;
253
+ const isJson = opts?.isJson ?? true;
254
+ const selector = opts?.selector;
255
+ const parseIfJson = (data) => {
256
+ try {
257
+ return JSON.parse(data);
258
+ } catch (e) {
259
+ return data;
260
+ }
261
+ };
262
+ const listener = (event) => {
263
+ const received = parseIfJson(event.data);
264
+ if (typeof received === "string" && !isJson) {
265
+ fn(received, event);
266
+ } else if (typeof received === "object" && isJson) {
267
+ fn(selector ? selector(received) : received, event);
268
+ } else {}
269
+ };
270
+ ws.addEventListener("message", listener);
271
+ return () => {
272
+ ws.removeEventListener("message", listener);
273
+ };
274
+ }
275
+ close() {
276
+ const ws = this.ws;
277
+ const store = this.store;
278
+ ws?.close?.();
279
+ this.ws = null;
280
+ store.getState().setConnected(false);
281
+ store.getState().setStatus("disconnected");
282
+ }
283
+ send(data, opts) {
284
+ const ws = this.ws;
285
+ const isJson = opts?.isJson ?? true;
286
+ const wrapper = opts?.wrapper;
287
+ if (!ws || ws.readyState !== WebSocket.OPEN) {
288
+ console.error("WebSocket is not open");
289
+ return;
290
+ }
291
+ if (isJson) {
292
+ ws.send(JSON.stringify(wrapper ? wrapper(data) : data));
293
+ } else {
294
+ ws.send(data);
295
+ }
296
+ }
297
+ getOpen() {
298
+ if (!this.ws) {
299
+ return false;
300
+ }
301
+ return this.ws.readyState === WebSocket.OPEN;
302
+ }
340
303
  }
341
304
 
342
- const wrapperError = ({ code, message }) => {
343
- const result = {
344
- code: code || 500,
345
- success: false,
346
- message: message || 'api request error',
347
- showError: (fn) => {
348
- //
349
- },
350
- noMsg: true,
351
- };
352
- return result;
305
+ // src/query.ts
306
+ var wrapperError = ({ code, message }) => {
307
+ const result = {
308
+ code: code || 500,
309
+ success: false,
310
+ message: message || "api request error",
311
+ showError: (fn) => {},
312
+ noMsg: true
313
+ };
314
+ return result;
353
315
  };
354
- /**
355
- * const query = new Query();
356
- * const res = await query.post({
357
- * path: 'demo',
358
- * key: '1',
359
- * });
360
- *
361
- * U是参数 V是返回值
362
- */
316
+
363
317
  class Query {
364
- adapter;
365
- url;
366
- /**
367
- * 请求前处理函数
368
- */
369
- beforeRequest;
370
- /**
371
- * 请求后处理函数
372
- */
373
- afterResponse;
374
- headers;
375
- timeout;
376
- /**
377
- * 需要突然停止请求,比如401的时候
378
- */
379
- stop;
380
- // 默认不使用ws
381
- qws;
382
- /**
383
- * 默认是 /client/router或者 默认是 /api/router
384
- */
385
- isClient = false;
386
- constructor(opts) {
387
- this.adapter = opts?.adapter || adapter;
388
- const defaultURL = opts?.isClient ? '/client/router' : '/api/router';
389
- this.url = opts?.url || defaultURL;
390
- this.headers = opts?.headers || {
391
- 'Content-Type': 'application/json',
392
- };
393
- this.timeout = opts?.timeout || 60000 * 3; // 默认超时时间为 60s * 3
394
- if (opts?.beforeRequest) {
395
- this.beforeRequest = opts.beforeRequest;
396
- }
397
- else {
398
- this.beforeRequest = async (opts) => {
399
- const token = globalThis?.localStorage?.getItem('token');
400
- if (token) {
401
- opts.headers = {
402
- ...opts.headers,
403
- Authorization: `Bearer ${token}`,
404
- };
405
- }
406
- return opts;
407
- };
408
- }
409
- }
410
- setQueryWs(qws) {
411
- this.qws = qws;
412
- }
413
- /**
414
- * 突然停止请求
415
- */
416
- setStop(stop) {
417
- this.stop = stop;
418
- }
419
- /**
420
- * 发送 get 请求,转到 post 请求
421
- * T是请求类型自定义
422
- * S是返回类型自定义
423
- * @param params 请求参数
424
- * @param options 请求配置
425
- * @returns 请求结果
426
- */
427
- async get(params, options) {
428
- return this.post(params, options);
429
- }
430
- /**
431
- * 发送 post 请求
432
- * T是请求类型自定义
433
- * S是返回类型自定义
434
- * @param body 请求体
435
- * @param options 请求配置
436
- * @returns 请求结果
437
- */
438
- async post(body, options) {
439
- const url = options?.url || this.url;
440
- const { headers, adapter, beforeRequest, afterResponse, timeout, ...rest } = options || {};
441
- const _headers = { ...this.headers, ...headers };
442
- const _adapter = adapter || this.adapter;
443
- const _beforeRequest = beforeRequest || this.beforeRequest;
444
- const _afterResponse = afterResponse || this.afterResponse;
445
- const _timeout = timeout || this.timeout;
446
- const req = {
447
- url: url,
448
- headers: _headers,
449
- body,
450
- timeout: _timeout,
451
- ...rest,
452
- };
453
- try {
454
- if (_beforeRequest) {
455
- const res = await _beforeRequest(req);
456
- if (res === false) {
457
- return wrapperError({
458
- code: 500,
459
- message: 'request is cancel',
460
- // @ts-ignore
461
- req: req,
462
- });
463
- }
464
- }
465
- }
466
- catch (e) {
467
- console.error('request beforeFn error', e, req);
468
- return wrapperError({
469
- code: 500,
470
- message: 'api request beforeFn error'});
471
- }
472
- if (this.stop && !options?.noStop) {
473
- const that = this;
474
- await new Promise((resolve) => {
475
- let timer = 0;
476
- const detect = setInterval(() => {
477
- if (!that.stop) {
478
- clearInterval(detect);
479
- resolve(true);
480
- }
481
- timer++;
482
- if (timer > 30) {
483
- console.error('request stop: timeout', req.url, timer);
484
- }
485
- }, 1000);
486
- });
487
- }
488
- return _adapter(req).then(async (res) => {
489
- try {
490
- if (_afterResponse) {
491
- return await _afterResponse(res, {
492
- req,
493
- res,
494
- fetch: adapter,
495
- });
496
- }
497
- return res;
498
- }
499
- catch (e) {
500
- console.error('request afterFn error', e, req);
501
- return wrapperError({
502
- code: 500,
503
- message: 'api request afterFn error'});
504
- }
505
- });
506
- }
507
- /**
508
- * 设置请求前处理,设置请求前处理函数
509
- * @param fn 处理函数
510
- */
511
- before(fn) {
512
- this.beforeRequest = fn;
513
- }
514
- /**
515
- * 设置请求后处理,设置请求后处理函数
516
- * @param fn 处理函数
517
- */
518
- after(fn) {
519
- this.afterResponse = fn;
520
- }
521
- async fetchText(urlOrOptions, options) {
522
- let _options = { ...options };
523
- if (typeof urlOrOptions === 'string' && !_options.url) {
524
- _options.url = urlOrOptions;
525
- }
526
- if (typeof urlOrOptions === 'object') {
527
- _options = { ...urlOrOptions, ..._options };
528
- }
529
- const res = await adapter({
530
- method: 'GET',
531
- ..._options,
532
- headers: {
533
- ...this.headers,
534
- ...(_options?.headers || {}),
535
- },
536
- });
537
- if (res && !res.code) {
538
- return {
539
- code: 200,
540
- data: res,
541
- };
318
+ adapter;
319
+ url;
320
+ beforeRequest;
321
+ afterResponse;
322
+ headers;
323
+ timeout;
324
+ stop;
325
+ qws;
326
+ isClient = false;
327
+ constructor(opts) {
328
+ this.adapter = opts?.adapter || adapter;
329
+ const defaultURL = opts?.isClient ? "/client/router" : "/api/router";
330
+ this.url = opts?.url || defaultURL;
331
+ this.headers = opts?.headers || {
332
+ "Content-Type": "application/json"
333
+ };
334
+ this.timeout = opts?.timeout || 60000 * 3;
335
+ if (opts?.beforeRequest) {
336
+ this.beforeRequest = opts.beforeRequest;
337
+ } else {
338
+ this.beforeRequest = async (opts2) => {
339
+ const token = globalThis?.localStorage?.getItem("token");
340
+ if (token) {
341
+ opts2.headers = {
342
+ ...opts2.headers,
343
+ Authorization: `Bearer ${token}`
344
+ };
345
+ }
346
+ return opts2;
347
+ };
348
+ }
349
+ }
350
+ setQueryWs(qws) {
351
+ this.qws = qws;
352
+ }
353
+ setStop(stop) {
354
+ this.stop = stop;
355
+ }
356
+ async get(params, options) {
357
+ return this.post(params, options);
358
+ }
359
+ async post(body, options) {
360
+ const url = options?.url || this.url;
361
+ console.log("query post", url, body, options);
362
+ const { headers, adapter: adapter2, beforeRequest, afterResponse, timeout, ...rest } = options || {};
363
+ const _headers = { ...this.headers, ...headers };
364
+ const _adapter = adapter2 || this.adapter;
365
+ const _beforeRequest = beforeRequest || this.beforeRequest;
366
+ const _afterResponse = afterResponse || this.afterResponse;
367
+ const _timeout = timeout || this.timeout;
368
+ const req = {
369
+ url,
370
+ headers: _headers,
371
+ body,
372
+ timeout: _timeout,
373
+ ...rest
374
+ };
375
+ try {
376
+ if (_beforeRequest) {
377
+ const res = await _beforeRequest(req);
378
+ if (res === false) {
379
+ return wrapperError({
380
+ code: 500,
381
+ message: "request is cancel",
382
+ req
383
+ });
384
+ }
385
+ }
386
+ } catch (e) {
387
+ console.error("request beforeFn error", e, req);
388
+ return wrapperError({
389
+ code: 500,
390
+ message: "api request beforeFn error",
391
+ req
392
+ });
393
+ }
394
+ if (this.stop && !options?.noStop) {
395
+ const that = this;
396
+ await new Promise((resolve) => {
397
+ let timer = 0;
398
+ const detect = setInterval(() => {
399
+ if (!that.stop) {
400
+ clearInterval(detect);
401
+ resolve(true);
402
+ }
403
+ timer++;
404
+ if (timer > 30) {
405
+ console.error("request stop: timeout", req.url, timer);
406
+ }
407
+ }, 1000);
408
+ });
409
+ }
410
+ return _adapter(req).then(async (res) => {
411
+ try {
412
+ if (_afterResponse) {
413
+ return await _afterResponse(res, {
414
+ req,
415
+ res,
416
+ fetch: adapter2
417
+ });
542
418
  }
543
419
  return res;
544
- }
420
+ } catch (e) {
421
+ console.error("request afterFn error", e, req);
422
+ return wrapperError({
423
+ code: 500,
424
+ message: "api request afterFn error",
425
+ req
426
+ });
427
+ }
428
+ });
429
+ }
430
+ before(fn) {
431
+ this.beforeRequest = fn;
432
+ }
433
+ after(fn) {
434
+ this.afterResponse = fn;
435
+ }
436
+ async fetchText(urlOrOptions, options) {
437
+ let _options = { ...options };
438
+ if (typeof urlOrOptions === "string" && !_options.url) {
439
+ _options.url = urlOrOptions;
440
+ }
441
+ if (typeof urlOrOptions === "object") {
442
+ _options = { ...urlOrOptions, ..._options };
443
+ }
444
+ const res = await adapter({
445
+ method: "GET",
446
+ ..._options,
447
+ headers: {
448
+ ...this.headers,
449
+ ..._options?.headers || {}
450
+ }
451
+ });
452
+ if (res && !res.code) {
453
+ return {
454
+ code: 200,
455
+ data: res
456
+ };
457
+ }
458
+ return res;
459
+ }
545
460
  }
546
461
  class BaseQuery {
547
- query;
548
- queryDefine;
549
- constructor(opts) {
550
- if (opts?.clientQuery) {
551
- this.query = opts.clientQuery;
552
- }
553
- else {
554
- this.query = opts?.query;
555
- }
556
- if (opts.queryDefine) {
557
- this.queryDefine = opts.queryDefine;
558
- this.queryDefine.query = this.query;
559
- }
560
- }
561
- get chain() {
562
- return this.queryDefine.queryChain;
563
- }
564
- post(data, options) {
565
- return this.query.post(data, options);
566
- }
567
- get(data, options) {
568
- return this.query.get(data, options);
569
- }
570
- }
571
- /**
572
- * @deprecated
573
- * 前端调用后端QueryRouter, 默认路径 /client/router
574
- */
575
- class ClientQuery extends Query {
576
- constructor(opts) {
577
- super({ ...opts, url: opts?.url || '/client/router' });
578
- }
462
+ query;
463
+ queryDefine;
464
+ constructor(opts) {
465
+ if (opts?.clientQuery) {
466
+ this.query = opts.clientQuery;
467
+ } else {
468
+ this.query = opts?.query;
469
+ }
470
+ if (opts.queryDefine) {
471
+ this.queryDefine = opts.queryDefine;
472
+ this.queryDefine.query = this.query;
473
+ }
474
+ }
475
+ get chain() {
476
+ return this.queryDefine.queryChain;
477
+ }
478
+ post(data, options) {
479
+ return this.query.post(data, options);
480
+ }
481
+ get(data, options) {
482
+ return this.query.get(data, options);
483
+ }
579
484
  }
580
485
 
581
- /**
582
- * 前端调用后端QueryRouter, 封装 beforeRequest 和 wss
583
- */
486
+ // src/query-browser.ts
584
487
  class QueryClient extends Query {
585
- tokenName;
586
- storage;
587
- token;
588
- constructor(opts) {
589
- super(opts);
590
- this.tokenName = opts?.tokenName || 'token';
591
- this.storage = opts?.storage || globalThis.localStorage;
592
- this.beforeRequest = async (opts) => {
593
- const token = this.token || this.getToken();
594
- if (token) {
595
- opts.headers = {
596
- ...opts.headers,
597
- Authorization: `Bearer ${token}`,
598
- };
599
- }
600
- return opts;
488
+ tokenName;
489
+ storage;
490
+ token;
491
+ constructor(opts) {
492
+ super(opts);
493
+ this.tokenName = opts?.tokenName || "token";
494
+ this.storage = opts?.storage || globalThis.localStorage;
495
+ this.beforeRequest = async (opts2) => {
496
+ const token = this.token || this.getToken();
497
+ if (token) {
498
+ opts2.headers = {
499
+ ...opts2.headers,
500
+ Authorization: `Bearer ${token}`
601
501
  };
602
- if (opts?.io) {
603
- this.createWs();
604
- }
605
- }
606
- createWs(opts) {
607
- this.qws = new QueryWs({ url: this.url, ...opts });
608
- }
609
- getToken() {
610
- return this.storage.getItem(this.tokenName);
611
- }
612
- saveToken(token) {
613
- this.storage.setItem(this.tokenName, token);
614
- }
615
- removeToken() {
616
- this.storage.removeItem(this.tokenName);
617
- }
502
+ }
503
+ return opts2;
504
+ };
505
+ if (opts?.io) {
506
+ this.createWs();
507
+ }
508
+ }
509
+ createWs(opts) {
510
+ this.qws = new QueryWs({ url: this.url, ...opts });
511
+ }
512
+ getToken() {
513
+ return this.storage.getItem(this.tokenName);
514
+ }
515
+ saveToken(token) {
516
+ this.storage.setItem(this.tokenName, token);
517
+ }
518
+ removeToken() {
519
+ this.storage.removeItem(this.tokenName);
520
+ }
618
521
  }
619
- // 移除默认生成的实例
620
- // export const client = new QueryClient();
621
-
622
- export { BaseQuery, ClientQuery, Query, QueryClient, QueryWs, adapter, wrapperError };
522
+ export {
523
+ wrapperError,
524
+ adapter,
525
+ QueryWs,
526
+ QueryClient,
527
+ Query,
528
+ BaseQuery
529
+ };