@wener/utils 1.1.37 → 1.1.38

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.
Files changed (108) hide show
  1. package/lib/browsers/download.js +20 -11
  2. package/lib/browsers/download.js.map +1 -1
  3. package/lib/cn/division/DivisionCode.js +204 -0
  4. package/lib/cn/division/DivisionCode.js.map +1 -0
  5. package/lib/cn/id/Mod11Checksum.js +46 -0
  6. package/lib/cn/id/Mod11Checksum.js.map +1 -0
  7. package/lib/cn/id/ResidentIdNumber.js +89 -0
  8. package/lib/cn/id/ResidentIdNumber.js.map +1 -0
  9. package/lib/cn/id/types.js +8 -0
  10. package/lib/cn/id/types.js.map +1 -0
  11. package/lib/cn/index.js +9 -1
  12. package/lib/cn/index.js.map +1 -1
  13. package/lib/cn/uscc/Mod31Checksum.js +52 -0
  14. package/lib/cn/uscc/Mod31Checksum.js.map +1 -0
  15. package/lib/cn/uscc/USCC.js +97 -0
  16. package/lib/cn/uscc/USCC.js.map +1 -0
  17. package/lib/cn/uscc/isUSCC.js +8 -0
  18. package/lib/cn/uscc/isUSCC.js.map +1 -0
  19. package/lib/crypto/getRandomValues.js +1 -1
  20. package/lib/crypto/getRandomValues.js.map +1 -1
  21. package/lib/crypto/randomUUID.js +1 -1
  22. package/lib/crypto/randomUUID.js.map +1 -1
  23. package/lib/crypto/randomUUIDv7.js +3 -0
  24. package/lib/crypto/randomUUIDv7.js.map +1 -0
  25. package/lib/errors/Errors.js +1 -1
  26. package/lib/errors/Errors.js.map +1 -1
  27. package/lib/fetch/HttpStatus.js.map +1 -0
  28. package/lib/fetch/createFetchWith.js +1 -1
  29. package/lib/fetch/createFetchWith.js.map +1 -1
  30. package/lib/fetch/createFetchWithRetry.js +1 -1
  31. package/lib/fetch/createFetchWithRetry.js.map +1 -1
  32. package/lib/index.js +7 -5
  33. package/lib/index.js.map +1 -1
  34. package/lib/io/ArrayBuffers.js +58 -4
  35. package/lib/io/ArrayBuffers.js.map +1 -1
  36. package/lib/io/isTransferable.js +1 -1
  37. package/lib/io/isTransferable.js.map +1 -1
  38. package/lib/io/parseDataUri.js +57 -0
  39. package/lib/io/parseDataUri.js.map +1 -0
  40. package/lib/objects/computeIfAbsent.js +14 -0
  41. package/lib/objects/computeIfAbsent.js.map +1 -0
  42. package/lib/runtime/AsyncCloser.js.map +1 -0
  43. package/lib/runtime/Closer.js.map +1 -0
  44. package/lib/runtime/getGlobalThis.js.map +1 -0
  45. package/lib/runtime/structuredClone.js.map +1 -0
  46. package/lib/server/fetch/createFetchWithProxyByNodeFetch.js +1 -1
  47. package/lib/server/fetch/createFetchWithProxyByNodeFetch.js.map +1 -1
  48. package/lib/server/fetch/createFetchWithProxyByUndici.js +1 -1
  49. package/lib/server/fetch/createFetchWithProxyByUndici.js.map +1 -1
  50. package/lib/server/getPackageDir.js +5 -4
  51. package/lib/server/getPackageDir.js.map +1 -1
  52. package/lib/server/polyfill/polyfillCrypto.js +1 -1
  53. package/lib/server/polyfill/polyfillCrypto.js.map +1 -1
  54. package/lib/server/polyfill/polyfillJsDom.js +1 -1
  55. package/lib/server/polyfill/polyfillJsDom.js.map +1 -1
  56. package/lib/server/polyfill/polyfillWebSocket.js +1 -1
  57. package/lib/server/polyfill/polyfillWebSocket.js.map +1 -1
  58. package/package.json +18 -15
  59. package/src/browsers/download.ts +20 -13
  60. package/src/cn/division/DivisionCode.ts +109 -0
  61. package/src/cn/id/Mod11Checksum.ts +29 -0
  62. package/src/cn/id/ResidentIdNumber.ts +102 -0
  63. package/src/cn/id/id.test.ts +20 -0
  64. package/src/cn/id/types.ts +26 -0
  65. package/src/cn/index.ts +13 -0
  66. package/src/cn/uscc/Mod31Checksum.ts +42 -0
  67. package/src/cn/uscc/USCC.ts +98 -0
  68. package/src/cn/uscc/isUSCC.ts +8 -0
  69. package/src/cn/uscc/uscc.test.ts +16 -0
  70. package/src/crypto/getRandomValues.ts +1 -1
  71. package/src/crypto/randomUUID.ts +1 -1
  72. package/src/crypto/randomUUIDv7.ts +1 -0
  73. package/src/errors/Errors.ts +1 -1
  74. package/src/fetch/createFetchWith.ts +1 -1
  75. package/src/fetch/createFetchWithRetry.ts +1 -1
  76. package/src/index.ts +7 -5
  77. package/src/io/ArrayBuffers.base64.test.ts +24 -0
  78. package/src/io/ArrayBuffers.ts +106 -4
  79. package/src/io/isTransferable.ts +1 -1
  80. package/src/io/parseDataUri.test.ts +34 -0
  81. package/src/io/parseDataUri.ts +66 -0
  82. package/src/objects/computeIfAbsent.ts +15 -0
  83. package/src/schema/typebox/gen/README.md +2 -0
  84. package/src/server/fetch/createFetchWithProxyByNodeFetch.ts +1 -1
  85. package/src/server/fetch/createFetchWithProxyByUndici.ts +1 -1
  86. package/src/server/getPackageDir.ts +6 -4
  87. package/src/server/polyfill/polyfillCrypto.ts +1 -1
  88. package/src/server/polyfill/polyfillJsDom.ts +1 -1
  89. package/src/server/polyfill/polyfillWebSocket.ts +1 -1
  90. package/lib/http/HttpStatus.js.map +0 -1
  91. package/lib/io/Bytes.js +0 -51
  92. package/lib/io/Bytes.js.map +0 -1
  93. package/lib/isomorphics/getGlobalThis.js.map +0 -1
  94. package/lib/isomorphics/structuredClone.js.map +0 -1
  95. package/lib/langs/AsyncCloser.js.map +0 -1
  96. package/lib/langs/Closer.js.map +0 -1
  97. package/src/io/Bytes.ts +0 -64
  98. /package/lib/{http → fetch}/HttpStatus.js +0 -0
  99. /package/lib/{langs → runtime}/AsyncCloser.js +0 -0
  100. /package/lib/{langs → runtime}/Closer.js +0 -0
  101. /package/lib/{isomorphics → runtime}/getGlobalThis.js +0 -0
  102. /package/lib/{isomorphics → runtime}/structuredClone.js +0 -0
  103. /package/src/{http → fetch}/HttpStatus.ts +0 -0
  104. /package/src/{langs → runtime}/AsyncCloser.ts +0 -0
  105. /package/src/{langs → runtime}/Closer.ts +0 -0
  106. /package/src/{isomorphics → runtime}/getGlobalThis.ts +0 -0
  107. /package/src/{isomorphics → runtime}/structuredClone.test.ts +0 -0
  108. /package/src/{isomorphics → runtime}/structuredClone.ts +0 -0
@@ -0,0 +1,98 @@
1
+ import { Mod31Checksum } from './Mod31Checksum';
2
+
3
+ /**
4
+ * - GB 32100-2015 法人和其他组织统一社会信用代码编码规则
5
+ * - USCI -> UnifiedSocialCreditIdentifier
6
+ * - USCC -> Unified Social Credit Code - 官方叫法
7
+ * - Business License
8
+ *
9
+ * @see https://en.wikipedia.org/wiki/Unified_Social_Credit_Identifier
10
+ */
11
+ export class USCC {
12
+ registryCodeLabels: Record<string, Code> = {
13
+ 1: {
14
+ label: '机构编制',
15
+ children: {
16
+ 1: { label: '机关' },
17
+ 2: { label: '事业单位' },
18
+ 3: { label: '中央编办直接管理机构编制的群众团体' },
19
+ 9: { label: '其他' },
20
+ },
21
+ },
22
+ 5: {
23
+ label: '民政',
24
+ children: {
25
+ 1: { label: '社会团体' },
26
+ 2: { label: '民办非企业单位' },
27
+ 3: { label: '基金会' },
28
+ 9: { label: '其他' },
29
+ },
30
+ },
31
+ 9: {
32
+ label: '工商',
33
+ children: {
34
+ 1: { label: '企业' },
35
+ 2: { label: '个体工商户' },
36
+ 3: { label: '农民专业合作社' },
37
+ 9: { label: '其他' },
38
+ },
39
+ },
40
+ Y: {
41
+ label: '其他',
42
+ children: {
43
+ 1: { label: '其他' },
44
+ },
45
+ },
46
+ };
47
+
48
+ /* 16 位 */
49
+ regex = /^([159][1239]|Y1)[0-9]{6}[0-9A-HJ-NP-RTUWXY]{10}$/; // 无 I O Z S V
50
+ checksum = Mod31Checksum.get();
51
+
52
+ static instance: USCC;
53
+
54
+ static get() {
55
+ return (this.instance ||= new USCC());
56
+ }
57
+
58
+ parse(s: string): ParsedUSCC {
59
+ let registryCode = s[0];
60
+ let l1 = this.registryCodeLabels[registryCode];
61
+ let organizationTypeCode = s[1];
62
+ return {
63
+ registryAuthorityCode: registryCode,
64
+ registryAuthorityCodeLabel: l1?.label,
65
+ organizationTypeCode,
66
+ organizationTypeLabel: l1?.children?.[organizationTypeCode]?.label,
67
+ registryDivisionCode: s.slice(3, 6),
68
+ // GB 11714-1997 全国组织机构代码编制规则
69
+ subject: s.slice(6, 15),
70
+ checksum: s.slice(17, 18),
71
+ };
72
+ }
73
+
74
+ verify(s: string) {
75
+ return this.regex.test(s) && this.checksum.verify(s);
76
+ }
77
+ }
78
+
79
+ interface Code {
80
+ label: string;
81
+ children?: Record<string, Code>;
82
+ }
83
+
84
+ interface ParsedUSCC {
85
+ // 登记管理部门码
86
+ registryAuthorityCode: string;
87
+ registryAuthorityCodeLabel?: string;
88
+ // 机构类别代码
89
+ organizationTypeCode: string;
90
+ organizationTypeLabel?: string;
91
+ // 登记管理机关行政区划代码
92
+ registryDivisionCode: string;
93
+ registryDivisionLabel?: string;
94
+ // 主体标识码
95
+ subject: string;
96
+ // 校验码
97
+ checksum: string;
98
+ }
@@ -0,0 +1,8 @@
1
+ import { USCC } from './USCC';
2
+
3
+ /**
4
+ * USCC - 统一社会信用代码
5
+ */
6
+ export function isUSCC(s: string) {
7
+ return USCC.get().verify(s);
8
+ }
@@ -0,0 +1,16 @@
1
+ import { test, expect } from 'vitest';
2
+ import { Mod31Checksum } from './Mod31Checksum';
3
+ import { USCC } from './USCC';
4
+ import { isUSCC } from './isUSCC';
5
+
6
+ test('uscc', () => {
7
+ let cs = Mod31Checksum.get();
8
+
9
+ // 阿里云计算
10
+ expect(cs.verify('91330106673959654P')).toBeTruthy();
11
+ expect(cs.generate('91330106673959654')).toBe('P');
12
+
13
+ expect(isUSCC('91330106673959654P')).toBeTruthy();
14
+
15
+ console.log(USCC.get().parse('91330106673959654P'));
16
+ });
@@ -1,6 +1,6 @@
1
1
  // eslint-disable-next-line @typescript-eslint/consistent-type-imports
2
2
  import type { TypedArray } from '../io/ArrayBuffers';
3
- import { getGlobalThis } from '../isomorphics/getGlobalThis';
3
+ import { getGlobalThis } from '../runtime/getGlobalThis';
4
4
  import { getNodeCrypto } from './getNodeCrypto';
5
5
 
6
6
  const globalThis = getGlobalThis();
@@ -1,4 +1,4 @@
1
- import { getGlobalThis } from '../isomorphics/getGlobalThis';
1
+ import { getGlobalThis } from '../runtime/getGlobalThis';
2
2
 
3
3
  const globalThis = getGlobalThis();
4
4
 
@@ -0,0 +1 @@
1
+ // https://github.com/LiosK/uuidv7/blob/main/src/index.ts
@@ -1,4 +1,4 @@
1
- import { getHttpStatusText } from '../http/HttpStatus';
1
+ import { getHttpStatusText } from '../fetch/HttpStatus';
2
2
 
3
3
  export interface ErrorDetailInit {
4
4
  message?: string;
@@ -1,5 +1,5 @@
1
1
  import { MaybePromise } from '../asyncs/MaybePromise';
2
- import { getGlobalThis } from '../isomorphics/getGlobalThis';
2
+ import { getGlobalThis } from '../runtime/getGlobalThis';
3
3
  import { type FetchLike } from './types';
4
4
 
5
5
  export function createFetchWith({
@@ -1,4 +1,4 @@
1
- import { getGlobalThis } from '../isomorphics/getGlobalThis';
1
+ import { getGlobalThis } from '../runtime/getGlobalThis';
2
2
  import { FetchLike } from './types';
3
3
 
4
4
  type RequestDelayFunction = (attempt: number, error: Error | null, response: Response | null) => number;
package/src/index.ts CHANGED
@@ -12,6 +12,7 @@ export { arrayFromAsync } from './arrays/arrayFromAsync';
12
12
  export { get } from './objects/get';
13
13
  export { set } from './objects/set';
14
14
  export { parseObjectPath } from './objects/parseObjectPath';
15
+ export { computeIfAbsent } from './objects/computeIfAbsent';
15
16
  export { merge, type MergeOptions } from './objects/merge';
16
17
 
17
18
  // async
@@ -42,8 +43,8 @@ export { isPlainObject } from './langs/isPlainObject';
42
43
  export { parseBoolean } from './langs/parseBoolean';
43
44
  export { maybeFunction, type MaybeFunction } from './langs/MaybeFunction';
44
45
  export { memoize } from './langs/memoize';
45
- export { AsyncCloser } from './langs/AsyncCloser';
46
- export { Closer } from './langs/Closer';
46
+ export { AsyncCloser } from './runtime/AsyncCloser';
47
+ export { Closer } from './runtime/Closer';
47
48
 
48
49
  export { isUUID } from './validations/isUUID';
49
50
  export { parseTimestamp } from './validations/parseTimestamp';
@@ -71,6 +72,7 @@ export { isBuffer } from './io/isBuffer';
71
72
  export { isTransferable } from './io/isTransferable';
72
73
  export { ArrayBuffers } from './io/ArrayBuffers';
73
74
  export { Buffer } from './io/Buffer';
75
+ export { parseDataUri, type ParsedDataUri } from './io/parseDataUri';
74
76
  export type { AbstractEncoding } from './io/AbstractEncoding';
75
77
 
76
78
  // browser
@@ -80,8 +82,8 @@ export { loadScripts, loadStyles } from './browsers/loaders';
80
82
  export { getFileFromDataTransfer } from './browsers/getFileFromDataTransfer';
81
83
 
82
84
  // polyfills
83
- export { getGlobalThis } from './isomorphics/getGlobalThis';
84
- export { structuredClone } from './isomorphics/structuredClone';
85
+ export { getGlobalThis } from './runtime/getGlobalThis';
86
+ export { structuredClone } from './runtime/structuredClone';
85
87
 
86
88
  // crypto
87
89
  export { randomUUID } from './crypto/randomUUID';
@@ -113,6 +115,6 @@ export { default as ms } from './libs/ms';
113
115
  // error
114
116
  export { Errors, DetailError, type ErrorDetail, type ErrorDetailInit } from './errors/Errors';
115
117
  // http
116
- export { getHttpStatusText, isRetryableHttpStatus } from './http/HttpStatus';
118
+ export { getHttpStatusText, isRetryableHttpStatus } from './fetch/HttpStatus';
117
119
 
118
120
  export type * from './types';
@@ -60,3 +60,27 @@ test('base64: high byte', function () {
60
60
  const highByte = ArrayBuffers.from([128]);
61
61
  assert.deepEqual(ArrayBuffers.alloc(1, ArrayBuffers.toString(highByte, 'base64'), 'base64'), highByte);
62
62
  });
63
+
64
+ test('fromBase64', () => {
65
+ const text = 'aoeu';
66
+ const buf = ArrayBuffers.from(text, 'utf8', Uint8Array);
67
+ expect(ArrayBuffers.fromBase64(ArrayBuffers.toBase64(buf))).toEqual(buf);
68
+ });
69
+
70
+ test('fromHex', () => {
71
+ const text = 'aoeu';
72
+ const buf = ArrayBuffers.from(text, 'utf8', Uint8Array);
73
+ expect(ArrayBuffers.fromHex(ArrayBuffers.toHex(buf))).toEqual(buf);
74
+ });
75
+
76
+ test('toHex', () => {
77
+ const text = 'aoeu';
78
+ const buf = ArrayBuffers.from(text, 'utf8', Uint8Array);
79
+ expect(ArrayBuffers.toHex(buf)).toEqual('616f6575');
80
+ });
81
+
82
+ test('toBase64', () => {
83
+ const text = 'aoeu';
84
+ const buf = ArrayBuffers.from(text, 'utf8', Uint8Array);
85
+ expect(ArrayBuffers.toBase64(buf)).toEqual('YW9ldQ==');
86
+ });
@@ -1,10 +1,13 @@
1
- import { getGlobalThis } from '../isomorphics/getGlobalThis';
2
1
  import { classOf } from '../langs/classOf';
2
+ import { getGlobalThis } from '../runtime/getGlobalThis';
3
3
  import { decodeBase64ToArrayBuffer, encodeArrayBufferToBase64 } from './base64';
4
4
  import { isBuffer } from './isBuffer';
5
5
 
6
6
  /**
7
7
  * Various utils to work with {@link ArrayBuffer}
8
+ *
9
+ * @see https://github.com/tc39/proposal-arraybuffer-base64
10
+ * @see https://github.com/tc39/proposal-resizablearraybuffer
8
11
  */
9
12
  export interface ArrayBuffers {
10
13
  /**
@@ -48,10 +51,26 @@ export interface ArrayBuffers {
48
51
  */
49
52
  from(v: string | BufferSource, encoding?: ToStringEncoding): ArrayBuffer;
50
53
 
54
+ from<C extends ArrayBufferViewConstructor<unknown>>(
55
+ v: string | BufferSource,
56
+ encoding: ToStringEncoding,
57
+ TypedArray: C,
58
+ ): C;
59
+
51
60
  /**
52
61
  * concat the given {@link BufferSource} to a new {@link ArrayBuffer}
53
62
  */
54
63
  concat(buffers: Array<BufferSource>, result?: ArrayBuffer, offset?: number): ArrayBuffer;
64
+
65
+ fromBase64(v: string): Uint8Array;
66
+
67
+ fromHex(v: string): Uint8Array;
68
+
69
+ toBase64(v: BufferSource): string;
70
+
71
+ toHex(v: BufferSource): string;
72
+
73
+ resize(v: ArrayBuffer, newByteLength: number): ArrayBuffer;
55
74
  }
56
75
 
57
76
  type ToStringEncoding =
@@ -89,6 +108,67 @@ export class ArrayBuffers {
89
108
  return v instanceof ArrayBuffer;
90
109
  };
91
110
 
111
+ static toArrayBuffer(v: BufferSource): ArrayBuffer {
112
+ return v instanceof ArrayBuffer ? v : (v.buffer as ArrayBuffer);
113
+ }
114
+
115
+ static toUint8Array(v: BufferSource) {
116
+ return ArrayBuffers.asView(Uint8Array, v);
117
+ }
118
+
119
+ static toBase64 = (v: BufferSource) => {
120
+ if ('toBase64' in Uint8Array.prototype) {
121
+ return this.toUint8Array(v).toBase64();
122
+ }
123
+
124
+ if (ArrayBuffers.isNativeBufferAllowed()) {
125
+ return Buffer.from(ArrayBuffers.asView(Uint8Array, v)).toString('base64');
126
+ }
127
+
128
+ return encodeArrayBufferToBase64(this.toArrayBuffer(v));
129
+ };
130
+
131
+ static toHex = (v: BufferSource) => {
132
+ if ('toHex' in Uint8Array.prototype) {
133
+ return this.toUint8Array(v).toHex();
134
+ }
135
+ if (ArrayBuffers.isNativeBufferAllowed()) {
136
+ return Buffer.from(ArrayBuffers.asView(Uint8Array, v)).toString('hex');
137
+ }
138
+ return ArrayBuffers.toString(v, 'hex');
139
+ };
140
+
141
+ static fromBase64 = (v: string) => {
142
+ if ('fromBase64' in Uint8Array) {
143
+ return Uint8Array.fromBase64(v);
144
+ }
145
+ if (ArrayBuffers.isNativeBufferAllowed()) {
146
+ return Buffer.from(v, 'base64');
147
+ }
148
+ return this.toUint8Array(decodeBase64ToArrayBuffer(v));
149
+ };
150
+
151
+ static fromHex = (v: string) => {
152
+ if ('fromHex' in Uint8Array) {
153
+ return Uint8Array.fromHex(v);
154
+ }
155
+ return this.toUint8Array(ArrayBuffers.from(v, 'hex'));
156
+ };
157
+
158
+ static resize = (v: ArrayBuffer, newByteLength: number): ArrayBuffer => {
159
+ if ('resize' in v) {
160
+ (v as any).resize(newByteLength);
161
+ return v;
162
+ }
163
+
164
+ const old = v;
165
+ const newBuf = new ArrayBuffer(newByteLength);
166
+ const oldView = new Uint8Array(old);
167
+ const newView = new Uint8Array(newBuf);
168
+ newView.set(oldView);
169
+ return newBuf;
170
+ };
171
+
92
172
  static slice = (o: TypedArray, start?: number, end?: number) => {
93
173
  // NodeJS Buffer slice is not the same as UInt8Array slice
94
174
  // https://nodejs.org/api/buffer.html#bufslicestart-end
@@ -195,7 +275,11 @@ export class ArrayBuffers {
195
275
  static from = (
196
276
  v: string | BufferSource | ArrayLike<number> | Iterable<number>,
197
277
  encoding: ToStringEncoding = 'utf8',
198
- ): BufferSource => {
278
+ view?: any,
279
+ ): any => {
280
+ if (view) {
281
+ return this.asView(view, this.from(v, encoding));
282
+ }
199
283
  if (!v) {
200
284
  return new ArrayBuffer(0);
201
285
  }
@@ -212,8 +296,8 @@ export class ArrayBuffers {
212
296
  case 'base64':
213
297
  // replaceAll need higher version of nodejs
214
298
  return decodeBase64ToArrayBuffer(v.replace(/[^0-9a-zA-Z=+/_]/g, ''));
215
- // error in nodejs 18
216
- // return Uint8Array.from(atob(v.replace(/[^0-9a-zA-Z=+/_ \r\n]/g, '')), (c) => c.charCodeAt(0));
299
+ case 'hex':
300
+ return new Uint8Array(v.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))).buffer;
217
301
  default:
218
302
  throw new Error(`[ArrayBuffers.from] Unknown encoding: ${encoding}`);
219
303
  }
@@ -303,3 +387,21 @@ const hexLookupTable = (function () {
303
387
  }
304
388
  return table;
305
389
  })();
390
+
391
+ declare global {
392
+ interface ArrayBuffer {
393
+ // resize(newByteLength: number): void;
394
+ }
395
+
396
+ interface Uint8Array {
397
+ toBase64(): string;
398
+
399
+ toHex(): string;
400
+ }
401
+
402
+ interface Uint8ArrayConstructor {
403
+ fromBase64(v: string): Uint8Array;
404
+
405
+ fromHex(v: string): Uint8Array;
406
+ }
407
+ }
@@ -1,4 +1,4 @@
1
- import { getGlobalThis } from '../isomorphics/getGlobalThis';
1
+ import { getGlobalThis } from '../runtime/getGlobalThis';
2
2
 
3
3
  const globalThis = getGlobalThis();
4
4
 
@@ -0,0 +1,34 @@
1
+ import { assert, test } from 'vitest';
2
+ import { ArrayBuffers } from './ArrayBuffers';
3
+ import { parseDataUri } from './parseDataUri';
4
+
5
+ test('parseDataUri', async () => {
6
+ {
7
+ let uri = 'data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==';
8
+ const { getData, ...out } = parseDataUri(uri)!;
9
+ assert.deepEqual(out, {
10
+ type: 'text/plain',
11
+ params: { base64: true },
12
+ content: 'SGVsbG8sIFdvcmxkIQ==',
13
+ base64: true,
14
+ });
15
+ assert.equal(await getData('utf-8'), await fetch(uri).then((v) => v.text()));
16
+ assert.equal(await getData('base64'), 'SGVsbG8sIFdvcmxkIQ==');
17
+ }
18
+ {
19
+ // text
20
+ let uri = 'data:text/plain,Hello%2C%20World!';
21
+ const { getData, ...out } = parseDataUri(uri)!;
22
+ assert.deepEqual(out, {
23
+ type: 'text/plain',
24
+ params: {},
25
+ content: 'Hello%2C%20World!',
26
+ base64: false,
27
+ });
28
+
29
+ assert.equal(await getData('utf-8'), 'Hello, World!');
30
+ assert.deepEqual(ArrayBuffers.asView(Uint8Array, await getData()), new TextEncoder().encode('Hello, World!'));
31
+ assert.equal(await getData('utf-8'), await fetch(uri).then((v) => v.text()));
32
+ assert.equal(await getData('base64'), 'SGVsbG8sIFdvcmxkIQ==');
33
+ }
34
+ });
@@ -0,0 +1,66 @@
1
+ import { ArrayBuffers } from './ArrayBuffers';
2
+
3
+ export interface ParsedDataUri {
4
+ type: string;
5
+ params: Record<string, string | boolean>;
6
+ content: string;
7
+ base64: boolean;
8
+
9
+ getData(enc: 'utf-8' | 'base64'): Promise<string>;
10
+
11
+ getData(): Promise<ArrayBuffer>;
12
+ }
13
+
14
+ export function parseDataUri(data: string): undefined | ParsedDataUri {
15
+ if (!data || !data.startsWith('data:')) {
16
+ return;
17
+ }
18
+ // https://en.wikipedia.org/wiki/Data_URI_scheme
19
+ // data:content/type;base64,
20
+ // data:content/type;a=b,content
21
+ const [header, body] = data.split(',');
22
+ const [type, ...paramsStr] = header.slice('data:'.length).split(';');
23
+ const content = body;
24
+ const params: Record<string, string | boolean> = Object.fromEntries(
25
+ paramsStr.map((s) => {
26
+ const [k, v] = s.trim().split('=');
27
+ return [k, v ?? true];
28
+ }),
29
+ );
30
+ // params charset=utf-8
31
+ // params base64
32
+ // params a=b
33
+ let base64 = Boolean(params['base64']);
34
+ return {
35
+ type,
36
+ params,
37
+ content,
38
+ base64,
39
+ getData: async (enc?: 'utf-8' | 'base64') => {
40
+ if (!enc) {
41
+ return await fetch(data).then((v) => v.arrayBuffer());
42
+ }
43
+ //
44
+ let buf: BufferSource;
45
+ if (base64) {
46
+ if (enc === 'base64') {
47
+ return content;
48
+ }
49
+ buf = await fetch(data).then((v) => v.arrayBuffer());
50
+ } else {
51
+ let raw = decodeURIComponent(content);
52
+ if (enc === 'utf-8') {
53
+ return raw;
54
+ }
55
+ buf = ArrayBuffers.from(raw, 'utf-8');
56
+ }
57
+ if (enc === 'utf-8') {
58
+ return new TextDecoder(enc).decode(buf);
59
+ }
60
+ if (enc === 'base64') {
61
+ return ArrayBuffers.toString(buf, 'base64');
62
+ }
63
+ return buf;
64
+ },
65
+ } as ParsedDataUri;
66
+ }
@@ -0,0 +1,15 @@
1
+ export function computeIfAbsent<K, V>(map: Map<K, V>, key: K, fn: () => V): V ;
2
+ export function computeIfAbsent<K extends string | symbol | number, V>(map: Record<K, V>, key: K, fn: () => V): V ;
3
+ export function computeIfAbsent<K, V>(map: any, key: K, fn: () => V): V {
4
+ if (map instanceof Map) {
5
+ if (!map.has(key)) {
6
+ map.set(key, fn());
7
+ }
8
+ return map.get(key)!;
9
+ }
10
+
11
+ if (!map[key]) {
12
+ map[key] = fn();
13
+ }
14
+ return map[key];
15
+ }
@@ -0,0 +1,2 @@
1
+ - 增加了 literal 处理
2
+ - 关闭了内置 prettier
@@ -1,5 +1,5 @@
1
1
  import { type FetchLike } from '../../fetch';
2
- import { getGlobalThis } from '../../isomorphics/getGlobalThis';
2
+ import { getGlobalThis } from '../../runtime/getGlobalThis';
3
3
 
4
4
  export function createFetchWithProxyByNodeFetch({
5
5
  proxy,
@@ -1,6 +1,6 @@
1
1
  import { MaybePromise } from '../../asyncs/MaybePromise';
2
2
  import { createFetchWith, FetchLike } from '../../fetch';
3
- import { getGlobalThis } from '../../isomorphics/getGlobalThis';
3
+ import { getGlobalThis } from '../../runtime/getGlobalThis';
4
4
 
5
5
  export function createFetchWithProxyByUndici({
6
6
  proxy,
@@ -1,11 +1,11 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
3
 
5
- const __filename = fileURLToPath(import.meta.url);
6
- const __dirname = path.dirname(__filename);
4
+ // import { fileURLToPath } from 'node:url';
5
+ // const __filename = fileURLToPath(import.meta.url);
6
+ // const __dirname = path.dirname(__filename);
7
7
 
8
- export function getPackageDir(currentDir: string = __dirname) {
8
+ export function getPackageDir(currentDir: string = process.cwd()) {
9
9
  while (!fs.existsSync(path.join(currentDir, 'package.json'))) {
10
10
  currentDir = path.resolve(currentDir, '..');
11
11
  if (currentDir === '/') {
@@ -14,3 +14,5 @@ export function getPackageDir(currentDir: string = __dirname) {
14
14
  }
15
15
  return currentDir;
16
16
  }
17
+
18
+ function findUp() {}
@@ -1,4 +1,4 @@
1
- import { getGlobalThis } from '../../isomorphics/getGlobalThis';
1
+ import { getGlobalThis } from '../../runtime/getGlobalThis';
2
2
 
3
3
  export async function polyfillCrypto() {
4
4
  const globalThis = getGlobalThis();
@@ -1,5 +1,5 @@
1
1
  import type { ConstructorOptions, ResourceLoaderConstructorOptions } from 'jsdom';
2
- import { getGlobalThis } from '../../isomorphics/getGlobalThis';
2
+ import { getGlobalThis } from '../../runtime/getGlobalThis';
3
3
 
4
4
  export async function polyfillJsDom() {
5
5
  if (typeof window !== 'undefined') {
@@ -1,5 +1,5 @@
1
1
  import type { MaybePromise } from '../../asyncs/MaybePromise';
2
- import { getGlobalThis } from '../../isomorphics/getGlobalThis';
2
+ import { getGlobalThis } from '../../runtime/getGlobalThis';
3
3
 
4
4
  export function polyfillWebSocket(ws: any): boolean;
5
5
  export function polyfillWebSocket(ws?: undefined): Promise<boolean>;
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/http/HttpStatus.ts"],"sourcesContent":["// http://httpstat.us/\n// https://en.wikipedia.org/wiki/List_of_HTTP_status_codes\nconst HttpStatus: Record<string, string> = {\n 100: 'Continue',\n 101: 'Switching Protocols',\n 102: 'Processing',\n 103: 'Early Hints',\n 200: 'OK',\n 201: 'Created',\n 202: 'Accepted',\n 203: 'Non-Authoritative Information',\n 204: 'No Content',\n 205: 'Reset Content',\n 206: 'Partial Content',\n 207: 'Multi-Status',\n 208: 'Already Reported',\n 226: 'IM Used',\n 300: 'Multiple Choices',\n 301: 'Moved Permanently',\n 302: 'Found',\n 303: 'See Other',\n 304: 'Not Modified',\n 305: 'Use Proxy',\n 306: 'Unused',\n 307: 'Temporary Redirect',\n 308: 'Permanent Redirect',\n\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 402: 'Payment Required',\n 403: 'Forbidden',\n 404: 'Not Found',\n 405: 'Method Not Allowed',\n 406: 'Not Acceptable',\n 407: 'Proxy Authentication Required',\n 408: 'Request Timeout',\n 409: 'Conflict',\n 410: 'Gone',\n 411: 'Length Required',\n 412: 'Precondition Required',\n 413: 'Request Entry Too Large',\n 414: 'Request-URI Too Long',\n 415: 'Unsupported Media Type',\n 416: 'Requested Range Not Satisfiable',\n 417: 'Expectation Failed',\n 418: \"I'm a teapot\",\n 421: 'Misdirected Request',\n 422: 'Unprocessable Entity',\n 423: 'Locked',\n 424: 'Failed Dependency',\n 425: 'Too Early',\n 426: 'Upgrade Required',\n 428: 'Precondition Required',\n 429: 'Too Many Requests',\n 431: 'Request Header Fields Too Large',\n 451: 'Unavailable For Legal Reasons',\n 500: 'Internal Server Error',\n 501: 'Not Implemented',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n 505: 'HTTP Version Not Supported',\n 506: 'Variant Also Negotiates',\n 507: 'Insufficient Storage',\n 508: 'Loop Detected',\n 509: 'Bandwidth Limit Exceeded',\n 510: 'Not Extended',\n 511: 'Network Authentication Required',\n};\n\nexport function getHttpStatusText(status: number | string): string | undefined {\n return HttpStatus[status];\n}\n\nexport function isRetryableHttpStatus(status: number) {\n switch (status) {\n /*\n408 Request Timeout\n425 Too Early\n429 Too Many Requests\n500 Internal Server Error\n502 Bad Gateway\n503 Service Unavailable\n504 Gateway Timeout\n */\n case 408:\n case 425:\n case 429:\n case 502:\n case 503:\n case 504:\n return true;\n default:\n return false;\n }\n}\n"],"names":["HttpStatus","getHttpStatusText","status","isRetryableHttpStatus"],"mappings":"AAAA,sBAAsB;AACtB,0DAA0D;AAC1D,MAAMA,aAAqC;IACzC,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IAEL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;AACP;AAEA,OAAO,SAASC,kBAAkBC,MAAuB;IACvD,OAAOF,UAAU,CAACE,OAAO;AAC3B;AAEA,OAAO,SAASC,sBAAsBD,MAAc;IAClD,OAAQA;QACN;;;;;;;;KAQC,GACD,KAAK;QACL,KAAK;QACL,KAAK;QACL,KAAK;QACL,KAAK;QACL,KAAK;YACH,OAAO;QACT;YACE,OAAO;IACX;AACF"}
package/lib/io/Bytes.js DELETED
@@ -1,51 +0,0 @@
1
- const objectToString = Object.prototype.toString;
2
- const uint8ArrayStringified = '[object Uint8Array]';
3
- /**
4
- * Utils for UInt8Array
5
- *
6
- * @see https://github.com/sindresorhus/uint8array-extras/blob/main/index.js
7
- */ export class Bytes {
8
- static #decoder = new globalThis.TextDecoder();
9
- static isUint8Array(value) {
10
- if (!value) {
11
- return false;
12
- }
13
- if (value.constructor === Uint8Array) {
14
- return true;
15
- }
16
- return objectToString.call(value) === uint8ArrayStringified;
17
- }
18
- static require(value) {
19
- if (!this.isUint8Array(value)) {
20
- throw new TypeError(`Expected \`Uint8Array\`, got \`${typeof value}\``);
21
- }
22
- return value;
23
- }
24
- static toUint8Array(value) {
25
- if (value instanceof ArrayBuffer) {
26
- return new Uint8Array(value);
27
- }
28
- if (ArrayBuffer.isView(value)) {
29
- return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
30
- }
31
- throw new TypeError(`Unsupported value, got \`${typeof value}\`.`);
32
- }
33
- static concat(arrays, totalLength) {
34
- if (arrays.length === 0) {
35
- return new Uint8Array(0);
36
- }
37
- totalLength ??= arrays.reduce((accumulator, currentValue)=>accumulator + currentValue.length, 0);
38
- const returnValue = new Uint8Array(totalLength);
39
- let offset = 0;
40
- for (const array of arrays){
41
- returnValue.set(this.require(array), offset);
42
- offset += array.length;
43
- }
44
- return returnValue;
45
- }
46
- static toString(value) {
47
- return this.#decoder.decode(value);
48
- }
49
- }
50
-
51
- //# sourceMappingURL=Bytes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/io/Bytes.ts"],"sourcesContent":["const objectToString = Object.prototype.toString;\nconst uint8ArrayStringified = '[object Uint8Array]';\n\n/**\n * Utils for UInt8Array\n *\n * @see https://github.com/sindresorhus/uint8array-extras/blob/main/index.js\n */\nexport class Bytes {\n static #decoder = new globalThis.TextDecoder();\n\n static isUint8Array(value: any): value is Uint8Array {\n if (!value) {\n return false;\n }\n\n if (value.constructor === Uint8Array) {\n return true;\n }\n\n return objectToString.call(value) === uint8ArrayStringified;\n }\n\n static require(value: any): Uint8Array {\n if (!this.isUint8Array(value)) {\n throw new TypeError(`Expected \\`Uint8Array\\`, got \\`${typeof value}\\``);\n }\n return value;\n }\n\n static toUint8Array(value: ArrayBuffer | ArrayBufferView): Uint8Array {\n if (value instanceof ArrayBuffer) {\n return new Uint8Array(value);\n }\n\n if (ArrayBuffer.isView(value)) {\n return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n }\n\n throw new TypeError(`Unsupported value, got \\`${typeof value}\\`.`);\n }\n\n static concat(arrays: Uint8Array[], totalLength: number): Uint8Array {\n if (arrays.length === 0) {\n return new Uint8Array(0);\n }\n\n totalLength ??= arrays.reduce((accumulator, currentValue) => accumulator + currentValue.length, 0);\n\n const returnValue = new Uint8Array(totalLength);\n\n let offset = 0;\n for (const array of arrays) {\n returnValue.set(this.require(array), offset);\n offset += array.length;\n }\n\n return returnValue;\n }\n\n static toString(value: Uint8Array) {\n return this.#decoder.decode(value);\n }\n}\n"],"names":["objectToString","Object","prototype","toString","uint8ArrayStringified","Bytes","decoder","globalThis","TextDecoder","isUint8Array","value","constructor","Uint8Array","call","require","TypeError","toUint8Array","ArrayBuffer","isView","buffer","byteOffset","byteLength","concat","arrays","totalLength","length","reduce","accumulator","currentValue","returnValue","offset","array","set","decode"],"mappings":"AAAA,MAAMA,iBAAiBC,OAAOC,SAAS,CAACC,QAAQ;AAChD,MAAMC,wBAAwB;AAE9B;;;;CAIC,GACD,OAAO,MAAMC;IACX,OAAO,CAACC,OAAO,GAAG,IAAIC,WAAWC,WAAW,GAAG;IAE/C,OAAOC,aAAaC,KAAU,EAAuB;QACnD,IAAI,CAACA,OAAO;YACV,OAAO;QACT;QAEA,IAAIA,MAAMC,WAAW,KAAKC,YAAY;YACpC,OAAO;QACT;QAEA,OAAOZ,eAAea,IAAI,CAACH,WAAWN;IACxC;IAEA,OAAOU,QAAQJ,KAAU,EAAc;QACrC,IAAI,CAAC,IAAI,CAACD,YAAY,CAACC,QAAQ;YAC7B,MAAM,IAAIK,UAAU,CAAC,+BAA+B,EAAE,OAAOL,MAAM,EAAE,CAAC;QACxE;QACA,OAAOA;IACT;IAEA,OAAOM,aAAaN,KAAoC,EAAc;QACpE,IAAIA,iBAAiBO,aAAa;YAChC,OAAO,IAAIL,WAAWF;QACxB;QAEA,IAAIO,YAAYC,MAAM,CAACR,QAAQ;YAC7B,OAAO,IAAIE,WAAWF,MAAMS,MAAM,EAAET,MAAMU,UAAU,EAAEV,MAAMW,UAAU;QACxE;QAEA,MAAM,IAAIN,UAAU,CAAC,yBAAyB,EAAE,OAAOL,MAAM,GAAG,CAAC;IACnE;IAEA,OAAOY,OAAOC,MAAoB,EAAEC,WAAmB,EAAc;QACnE,IAAID,OAAOE,MAAM,KAAK,GAAG;YACvB,OAAO,IAAIb,WAAW;QACxB;QAEAY,gBAAgBD,OAAOG,MAAM,CAAC,CAACC,aAAaC,eAAiBD,cAAcC,aAAaH,MAAM,EAAE;QAEhG,MAAMI,cAAc,IAAIjB,WAAWY;QAEnC,IAAIM,SAAS;QACb,KAAK,MAAMC,SAASR,OAAQ;YAC1BM,YAAYG,GAAG,CAAC,IAAI,CAAClB,OAAO,CAACiB,QAAQD;YACrCA,UAAUC,MAAMN,MAAM;QACxB;QAEA,OAAOI;IACT;IAEA,OAAO1B,SAASO,KAAiB,EAAE;QACjC,OAAO,IAAI,CAAC,CAACJ,OAAO,CAAC2B,MAAM,CAACvB;IAC9B;AACF"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/isomorphics/getGlobalThis.ts"],"sourcesContent":["declare const global: typeof globalThis;\n\n/**\n * isomorphic globalThis\n *\n * globalThis supported by ff 65, Chrome 71, Node 12, babel\n *\n * non-standard globalThis supported for Alipay Miniprogram\n *\n * @see https://caniuse.com/#search=globalThis\n * @see https://v8.dev/features/globalthis\n */\nexport const getGlobalThis = (): typeof globalThis => {\n if (typeof globalThis !== 'undefined') return globalThis;\n if (typeof self !== 'undefined') return self;\n if (typeof window !== 'undefined') return window;\n if (typeof global !== 'undefined') return global as any;\n if (typeof this !== 'undefined') return this as any;\n throw new Error('Unable to locate global `this`');\n};\n"],"names":["getGlobalThis","globalThis","self","window","global","Error"],"mappings":"AAEA;;;;;;;;;CASC,GACD,OAAO,MAAMA,gBAAgB;IAC3B,IAAI,OAAOC,eAAe,aAAa,OAAOA;IAC9C,IAAI,OAAOC,SAAS,aAAa,OAAOA;IACxC,IAAI,OAAOC,WAAW,aAAa,OAAOA;IAC1C,IAAI,OAAOC,WAAW,aAAa,OAAOA;IAC1C,IAAI,OAAO,IAAI,KAAK,aAAa,OAAO,IAAI;IAC5C,MAAM,IAAIC,MAAM;AAClB,EAAE"}