@hlw-uni-mp/request 1.0.6 → 1.0.8

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/index.mjs CHANGED
@@ -91,15 +91,7 @@ function bytesToBase64(bytes) {
91
91
  return res;
92
92
  }
93
93
  function stringToUtf8(str) {
94
- if (typeof TextEncoder !== "undefined") {
95
- return new TextEncoder().encode(str);
96
- }
97
- const code = unescape(encodeURIComponent(str));
98
- const bytes = new Uint8Array(code.length);
99
- for (let i = 0; i < code.length; i++) {
100
- bytes[i] = code.charCodeAt(i);
101
- }
102
- return bytes;
94
+ return new TextEncoder().encode(str);
103
95
  }
104
96
  function modPow(base, exp, mod) {
105
97
  let res = 1n;
@@ -262,40 +254,6 @@ function calculateSign(options) {
262
254
  return sha256(raw);
263
255
  }
264
256
 
265
- // src/oss.ts
266
- async function uploadOss(oss, source) {
267
- const filePath = typeof source === "string" ? source : source.path || source.tempFilePath || "";
268
- const name = oss.filename || filePath.split("/").pop() || "file";
269
- const formData = {
270
- key: oss.key || "",
271
- success_action_status: oss.successActionStatus || "200"
272
- };
273
- if (oss.policy) formData.policy = oss.policy;
274
- if (oss.OSSAccessKeyId) formData.OSSAccessKeyId = oss.OSSAccessKeyId;
275
- if (oss.signature) formData.signature = oss.signature;
276
- if (oss["x-oss-security-token"]) formData["x-oss-security-token"] = String(oss["x-oss-security-token"]);
277
- const target2 = oss.host || "";
278
- return new Promise((resolve, reject) => {
279
- uni.uploadFile({
280
- url: target2,
281
- filePath,
282
- name: "file",
283
- formData,
284
- header: {
285
- "Content-Disposition": `inline;filename=${encodeURIComponent(name || "file")}`
286
- },
287
- success: (res) => {
288
- if (res.statusCode === 200 || res.statusCode === 204) {
289
- resolve(oss.url || "");
290
- } else {
291
- reject(new Error(`\u4E0A\u4F20\u963F\u91CC\u4E91\u5931\u8D25 (${res.statusCode}): ${res.data || ""}`));
292
- }
293
- },
294
- fail: (error) => reject(new Error(error.errMsg || "\u4E0A\u4F20\u963F\u91CC\u4E91\u5931\u8D25"))
295
- });
296
- });
297
- }
298
-
299
257
  // src/upload.ts
300
258
  function getFileExt(filePath) {
301
259
  const ext = filePath.split("?")[0].split(".").pop()?.toLowerCase() || "";
@@ -387,249 +345,149 @@ var HttpError = class extends Error {
387
345
  this.config = options?.config;
388
346
  }
389
347
  };
390
- var InterceptorManager = class {
391
- constructor() {
392
- this.handlers = [];
393
- }
394
- use(fulfilled, rejected) {
395
- this.handlers.push({ fulfilled, rejected });
396
- return this.handlers.length - 1;
397
- }
398
- eject(id) {
399
- if (this.handlers[id]) {
400
- this.handlers[id] = null;
401
- }
402
- }
403
- forEach(fn) {
404
- for (const h of this.handlers) {
405
- if (h !== null) fn(h);
406
- }
407
- }
408
- };
409
- var UniHttpClient = class {
410
- constructor(options = {}) {
411
- this.defaults = {
412
- baseURL: "",
413
- timeout: 15e3,
414
- headers: {
415
- "Content-Type": "application/json",
416
- Accept: "application/json"
417
- }
418
- };
419
- this.interceptors = {
420
- request: new InterceptorManager(),
421
- response: new InterceptorManager()
422
- };
423
- if (options.baseURL) this.defaults.baseURL = options.baseURL.replace(/\/+$/, "");
424
- if (options.timeout) this.defaults.timeout = options.timeout;
425
- if (options.headers) this.defaults.headers = { ...this.defaults.headers, ...options.headers };
426
- }
427
- async request(config) {
428
- const cfg = {
429
- method: "GET",
430
- ...config,
431
- baseURL: config.baseURL ?? this.defaults.baseURL,
432
- headers: { ...this.defaults.headers, ...config.headers },
433
- timeout: config.timeout ?? this.defaults.timeout
434
- };
435
- const requestChain = [];
436
- this.interceptors.request.forEach((h) => {
437
- requestChain.push(h.fulfilled, h.rejected);
438
- });
439
- let promise = Promise.resolve(cfg);
440
- while (requestChain.length) {
441
- promise = promise.then(requestChain.shift(), requestChain.shift());
442
- }
443
- let responsePromise = promise.then(async (finalConfig) => {
444
- const fullUrl = this.resolveUrl(finalConfig.url, finalConfig.baseURL);
445
- return this.send(fullUrl, finalConfig);
446
- });
447
- const responseChain = [];
448
- this.interceptors.response.forEach((h) => {
449
- responseChain.push(h.fulfilled, h.rejected);
450
- });
451
- while (responseChain.length) {
452
- responsePromise = responsePromise.then(responseChain.shift(), responseChain.shift());
453
- }
454
- return responsePromise;
455
- }
456
- get(url, config) {
457
- return this.request({ ...config, url, method: "GET" });
458
- }
459
- post(url, data, config) {
460
- return this.request({ ...config, url, method: "POST", data });
461
- }
462
- put(url, data, config) {
463
- return this.request({ ...config, url, method: "PUT", data });
464
- }
465
- delete(url, config) {
466
- return this.request({ ...config, url, method: "DELETE" });
467
- }
468
- resolveUrl(url, baseURL) {
469
- if (/^(https?:)?\/\//.test(url) || url.startsWith("file://")) return url;
470
- const base = (baseURL || this.defaults.baseURL || "").replace(/\/+$/, "");
471
- const path = url.startsWith("/") ? url : `/${url}`;
472
- return base ? `${base}${path}` : path;
473
- }
474
- send(url, cfg) {
475
- return new Promise((resolve, reject) => {
476
- const isGet = (cfg.method || "GET").toUpperCase() === "GET";
477
- const requestData = isGet ? cfg.params ?? cfg.data : cfg.data ?? cfg.params;
478
- const method = cfg.method?.toUpperCase() || "GET";
479
- uni.request({
480
- url,
481
- method,
482
- data: requestData,
483
- header: cfg.headers,
484
- timeout: cfg.timeout,
485
- success: (res) => {
486
- const response = {
487
- data: res.data,
488
- status: res.statusCode,
489
- statusText: String(res.statusCode),
490
- headers: res.header || {},
491
- config: cfg
492
- };
493
- if (res.statusCode >= 200 && res.statusCode < 300) {
494
- resolve(response);
495
- } else {
496
- const body = res.data;
497
- const msg = typeof body?.msg === "string" ? body.msg : `\u8BF7\u6C42\u5931\u8D25: ${res.statusCode}`;
498
- reject(new HttpError(msg, { response, status: res.statusCode, config: cfg }));
499
- }
500
- },
501
- fail: (errorResult) => {
502
- reject(new HttpError(errorResult.errMsg || "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25", { config: cfg }));
503
- }
504
- });
505
- });
506
- }
507
- };
508
- var target = null;
509
348
  var currentOptions = {};
510
349
  var lastToastTime = 0;
511
- function handleUnauthorized(message, callback) {
350
+ function resolveUrl(url, baseURL) {
351
+ if (/^(https?:)?\/\//.test(url) || url.startsWith("file://")) {
352
+ return url;
353
+ }
354
+ const base = (baseURL || currentOptions.baseURL || "").replace(/\/+$/, "");
355
+ const path = url.startsWith("/") ? url : `/${url}`;
356
+ return base ? `${base}${path}` : path;
357
+ }
358
+ function handleUnauthorized(message) {
512
359
  const now = Date.now();
513
360
  if (now - lastToastTime > 3e3) {
514
361
  lastToastTime = now;
515
362
  uni.showToast({ title: message, icon: "none" });
516
363
  }
517
- if (callback) {
518
- callback(message);
519
- }
364
+ currentOptions.onUnauthorized?.(message);
520
365
  }
521
- function getClient() {
522
- if (target) {
523
- if (currentOptions.baseURL && !target.defaults.baseURL) {
524
- target.defaults.baseURL = currentOptions.baseURL;
525
- }
526
- return target;
527
- }
528
- const base = currentOptions.baseURL || "";
529
- const inst = new UniHttpClient({
530
- baseURL: base,
531
- timeout: currentOptions.timeout || 15e3
366
+ function buildSecurityHeaders(config) {
367
+ const devInfo = currentOptions.getDevice?.() || getDevice();
368
+ const token = currentOptions.getToken?.() || "";
369
+ const timestamp = Date.now();
370
+ const nonce = Math.random().toString(36).substring(2, 12);
371
+ const pubKey = currentOptions.publicKey || "";
372
+ const secret = currentOptions.secret || "";
373
+ const contextPayload = JSON.stringify({ ...devInfo, token });
374
+ const cipher = pubKey ? encryptRsa(contextPayload, pubKey) : encodeURIComponent(contextPayload);
375
+ const signData = config.data || config.params || {};
376
+ const sign = calculateSign({
377
+ timestamp,
378
+ nonce,
379
+ context: cipher,
380
+ secret,
381
+ data: signData
532
382
  });
533
- inst.interceptors.request.use(
534
- async (config) => {
535
- const devInfo = currentOptions.getDevice?.() || getDevice();
536
- const token = currentOptions.getToken?.() || "";
537
- const time = Date.now();
538
- const nonce = Math.random().toString(36).substring(2, 12);
539
- const payload = {
540
- ...devInfo,
541
- token
542
- };
543
- const jsonStr = JSON.stringify(payload);
544
- const pubKey = currentOptions.publicKey || "";
545
- const secret = currentOptions.secret || "";
546
- let cipher = "";
547
- if (pubKey) {
548
- cipher = encryptRsa(jsonStr, pubKey);
549
- } else {
550
- cipher = encodeURIComponent(jsonStr);
551
- }
552
- const signData = config.data || config.params || {};
553
- const sign = calculateSign({
554
- timestamp: time,
555
- nonce,
556
- context: cipher,
557
- secret,
558
- data: signData
559
- });
560
- config.headers = config.headers || {};
561
- config.headers["X-Client-Timestamp"] = String(time);
562
- config.headers["X-Client-Nonce"] = nonce;
563
- config.headers["X-Client-Sign"] = sign;
564
- config.headers["X-Client-Context"] = cipher;
565
- if ("appid" in devInfo && devInfo.appid) {
566
- config.headers["x-appid"] = String(devInfo.appid);
567
- }
568
- return config;
569
- },
570
- (error) => Promise.reject(error)
571
- );
572
- inst.interceptors.response.use(
573
- async (response) => {
574
- const res = response.data;
575
- if (res && (res.code === 401 || res.code === 403)) {
576
- const message = res.msg || "\u767B\u5F55\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55";
577
- handleUnauthorized(message, currentOptions.onUnauthorized);
578
- }
579
- return response;
580
- },
581
- (error) => {
582
- const httpErr = error instanceof HttpError ? error : void 0;
583
- const status = httpErr?.status ?? httpErr?.response?.status;
584
- const body = httpErr?.response?.data;
585
- const message = body?.msg || (error instanceof Error ? error.message : "\u7F51\u7EDC\u8FDE\u63A5\u5F02\u5E38");
586
- if (status === 401 || status === 403) {
587
- handleUnauthorized(message, currentOptions.onUnauthorized);
383
+ const headers = {
384
+ "Content-Type": "application/json",
385
+ Accept: "application/json",
386
+ ...config.headers,
387
+ "X-Client-Timestamp": String(timestamp),
388
+ "X-Client-Nonce": nonce,
389
+ "X-Client-Sign": sign,
390
+ "X-Client-Context": cipher
391
+ };
392
+ if ("appid" in devInfo && devInfo.appid) {
393
+ headers["x-appid"] = String(devInfo.appid);
394
+ }
395
+ return headers;
396
+ }
397
+ function sendRequest(url, config) {
398
+ return new Promise((resolve, reject) => {
399
+ const method = config.method?.toUpperCase() || "GET";
400
+ const isGet = method === "GET";
401
+ const requestData = isGet ? config.params ?? config.data : config.data ?? config.params;
402
+ uni.request({
403
+ url,
404
+ method,
405
+ data: requestData,
406
+ header: config.headers,
407
+ timeout: config.timeout ?? currentOptions.timeout ?? 15e3,
408
+ success: (res) => {
409
+ const response = {
410
+ data: res.data,
411
+ status: res.statusCode,
412
+ statusText: String(res.statusCode),
413
+ headers: res.header || {},
414
+ config
415
+ };
416
+ if (res.statusCode >= 200 && res.statusCode < 300) {
417
+ resolve(response);
418
+ } else {
419
+ const body = res.data;
420
+ const msg = typeof body?.msg === "string" ? body.msg : `\u8BF7\u6C42\u5931\u8D25: ${res.statusCode}`;
421
+ reject(new HttpError(msg, { response, status: res.statusCode, config }));
422
+ }
423
+ },
424
+ fail: (err) => {
425
+ reject(new HttpError(err.errMsg || "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25", { config }));
588
426
  }
589
- return Promise.reject(error);
590
- }
591
- );
592
- target = inst;
593
- return inst;
427
+ });
428
+ });
594
429
  }
595
- function setupHttp(options = {}) {
596
- currentOptions = { ...currentOptions, ...options };
597
- if (target && options.baseURL) {
598
- target.defaults.baseURL = options.baseURL;
430
+ async function request(config) {
431
+ const finalConfig = {
432
+ method: "GET",
433
+ ...config,
434
+ headers: buildSecurityHeaders(config)
435
+ };
436
+ const fullUrl = resolveUrl(finalConfig.url, finalConfig.baseURL);
437
+ try {
438
+ const response = await sendRequest(fullUrl, finalConfig);
439
+ const resData = response.data;
440
+ if (resData && (resData.code === 401 || resData.code === 403)) {
441
+ handleUnauthorized(resData.msg || "\u767B\u5F55\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55");
442
+ }
443
+ return resData;
444
+ } catch (error) {
445
+ const httpErr = error instanceof HttpError ? error : void 0;
446
+ const status = httpErr?.status ?? httpErr?.response?.status;
447
+ const body = httpErr?.response?.data;
448
+ const message = body?.msg || (error instanceof Error ? error.message : "\u7F51\u7EDC\u8FDE\u63A5\u5F02\u5E38");
449
+ if (status === 401 || status === 403) {
450
+ handleUnauthorized(message);
451
+ }
452
+ return Promise.reject(error);
599
453
  }
600
- return getClient();
601
454
  }
602
- function request(config) {
603
- return getClient().request(config).then((res) => res.data);
455
+ function get(url, params, config) {
456
+ return request({ ...config, url, method: "GET", params });
604
457
  }
605
- function get(url, params) {
606
- return request({ url, method: "GET", params });
458
+ function post(url, data, config) {
459
+ return request({ ...config, url, method: "POST", data });
607
460
  }
608
- function post(url, data) {
609
- return request({ url, method: "POST", data });
461
+ function put(url, data, config) {
462
+ return request({ ...config, url, method: "PUT", data });
610
463
  }
611
- function put(url, data) {
612
- return request({ url, method: "PUT", data });
464
+ function del(url, params, config) {
465
+ return request({ ...config, url, method: "DELETE", params });
466
+ }
467
+ var http = {
468
+ request,
469
+ get,
470
+ post,
471
+ put,
472
+ delete: del,
473
+ del,
474
+ setup: setupHttp,
475
+ getOptions: getHttpOptions
476
+ };
477
+ var client = http;
478
+ function getClient() {
479
+ return http;
613
480
  }
614
- function del(url, params) {
615
- return request({ url, method: "DELETE", params });
481
+ function setupHttp(options = {}) {
482
+ currentOptions = { ...currentOptions, ...options };
483
+ return http;
616
484
  }
617
485
  function getHttpOptions() {
618
486
  return currentOptions;
619
487
  }
620
- var client = new Proxy({}, {
621
- get(_, prop) {
622
- const inst = getClient();
623
- const val = Reflect.get(inst, prop);
624
- return typeof val === "function" ? val.bind(inst) : val;
625
- }
626
- });
627
- var http = client;
628
488
  var index_default = request;
629
489
  export {
630
490
  HttpError,
631
- InterceptorManager,
632
- UniHttpClient,
633
491
  calculateSign,
634
492
  client,
635
493
  index_default as default,
@@ -648,6 +506,5 @@ export {
648
506
  setupHttp,
649
507
  sha256,
650
508
  sortString,
651
- uploadFile,
652
- uploadOss
509
+ uploadFile
653
510
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hlw-uni-mp/request",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Universal Uni-App HTTP and upload client with RSA encryption & sign verification",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -16,11 +16,6 @@
16
16
  "files": [
17
17
  "dist"
18
18
  ],
19
- "scripts": {
20
- "build": "tsup",
21
- "dev": "tsup --watch",
22
- "publish:npm": "pnpm build && npm publish --access public"
23
- },
24
19
  "publishConfig": {
25
20
  "access": "public"
26
21
  },
@@ -42,5 +37,10 @@
42
37
  "@types/crypto-js": "^4.2.2",
43
38
  "tsup": "^8.5.1",
44
39
  "typescript": "^5.8.3"
40
+ },
41
+ "scripts": {
42
+ "build": "tsup",
43
+ "dev": "tsup --watch",
44
+ "publish:npm": "pnpm build && npm publish --access public"
45
45
  }
46
- }
46
+ }