@wener/utils 1.1.49 → 1.1.50
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/lib/arrays/MaybeArray.js.map +1 -1
- package/lib/arrays/arrayFromAsync.js.map +1 -1
- package/lib/asyncs/AsyncInterval.js.map +1 -1
- package/lib/asyncs/MaybePromise.js.map +1 -1
- package/lib/asyncs/Promises.js.map +1 -1
- package/lib/asyncs/createAsyncIterator.js.map +1 -1
- package/lib/asyncs/createLazyPromise.js.map +1 -1
- package/lib/asyncs/firstOfAsyncIterator.js.map +1 -1
- package/lib/asyncs/generatorOfStream.js.map +1 -1
- package/lib/asyncs/isIterator.js.map +1 -1
- package/lib/asyncs/isPromise.js.map +1 -1
- package/lib/asyncs/isThenable.js.map +1 -1
- package/lib/asyncs/nextOfAsyncIterator.js.map +1 -1
- package/lib/asyncs/promiseOfCallback.js.map +1 -1
- package/lib/asyncs/timeout.js.map +1 -1
- package/lib/browsers/copy.js.map +1 -1
- package/lib/browsers/download.js.map +1 -1
- package/lib/browsers/getFileFromDataTransfer.js.map +1 -1
- package/lib/browsers/loaders.js.map +1 -1
- package/lib/cn/division/DivisionCode.js.map +1 -1
- package/lib/cn/division/binarySearch.js.map +1 -1
- package/lib/cn/formatChineseAmount.js.map +1 -1
- package/lib/cn/id/Mod11.js.map +1 -1
- package/lib/cn/id/ResidentIdNumber.js.map +1 -1
- package/lib/cn/id/types.js.map +1 -1
- package/lib/cn/index.js.map +1 -1
- package/lib/cn/parseChineseNumber.js.map +1 -1
- package/lib/cn/pinyin/cartesianProduct.js.map +1 -1
- package/lib/cn/pinyin/loader.js.map +1 -1
- package/lib/cn/pinyin/preload.js.map +1 -1
- package/lib/cn/pinyin/toPinyinPure.js.map +1 -1
- package/lib/cn/pinyin/transform.js.map +1 -1
- package/lib/cn/types.js.map +1 -1
- package/lib/cn/uscc/Mod31.js.map +1 -1
- package/lib/cn/uscc/USCC.js.map +1 -1
- package/lib/cn/uscc/isUSCC.js.map +1 -1
- package/lib/crypto/base.js.map +1 -1
- package/lib/crypto/getNodeCrypto.js.map +1 -1
- package/lib/crypto/getRandomValues.js.map +1 -1
- package/lib/crypto/hashing.js.map +1 -1
- package/lib/crypto/md5.bench.js.map +1 -1
- package/lib/crypto/md5.d.js.map +1 -1
- package/lib/crypto/md5.js.map +1 -1
- package/lib/crypto/pem/pem.js.map +1 -1
- package/lib/crypto/randomUUID.js.map +1 -1
- package/lib/crypto/randomUUIDv7.js.map +1 -1
- package/lib/crypto/ulid.js.map +1 -1
- package/lib/emitter/types.js.map +1 -1
- package/lib/errors/Errors.js +38 -17
- package/lib/errors/Errors.js.map +1 -1
- package/lib/fetch/HttpStatus.js.map +1 -1
- package/lib/fetch/createFetchWith.js.map +1 -1
- package/lib/fetch/createFetchWithLogging.js.map +1 -1
- package/lib/fetch/createFetchWithRetry.js.map +1 -1
- package/lib/fetch/dumpRequest.js.map +1 -1
- package/lib/fetch/dumpResponse.js.map +1 -1
- package/lib/fetch/http.types.js.map +1 -1
- package/lib/fetch/index.js.map +1 -1
- package/lib/fetch/types.js.map +1 -1
- package/lib/i18n/createTranslate.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/io/AbstractEncoding.js.map +1 -1
- package/lib/io/ArrayBuffer.test-d.js.map +1 -1
- package/lib/io/ArrayBuffers.js +217 -173
- package/lib/io/ArrayBuffers.js.map +1 -1
- package/lib/io/Buffer.js.map +1 -1
- package/lib/io/ByteBuffer.js.map +1 -1
- package/lib/io/base64.js +2 -2
- package/lib/io/base64.js.map +1 -1
- package/lib/io/dump.js.map +1 -1
- package/lib/io/isBuffer.js.map +1 -1
- package/lib/io/isTransferable.js.map +1 -1
- package/lib/io/parseDataUri.js.map +1 -1
- package/lib/langs/MaybeFunction.js.map +1 -1
- package/lib/langs/classOf.js.map +1 -1
- package/lib/langs/deepEqual.js.map +1 -1
- package/lib/langs/deepFreeze.js.map +1 -1
- package/lib/langs/getGlobalStates.js.map +1 -1
- package/lib/langs/getObjectId.js +1 -1
- package/lib/langs/getObjectId.js.map +1 -1
- package/lib/langs/isClass.js.map +1 -1
- package/lib/langs/isDefined.js.map +1 -1
- package/lib/langs/isEmptyObject.js.map +1 -1
- package/lib/langs/isFunction.js.map +1 -1
- package/lib/langs/isNullish.js.map +1 -1
- package/lib/langs/isPlainObject.js.map +1 -1
- package/lib/langs/memoize.js.map +1 -1
- package/lib/langs/mixin.js.map +1 -1
- package/lib/langs/parseBoolean.js.map +1 -1
- package/lib/langs/shallowClone.js.map +1 -1
- package/lib/langs/shallowEqual.js.map +1 -1
- package/lib/libs/ms.js.map +1 -1
- package/lib/logging/Logger.js.map +1 -1
- package/lib/logging/createChildLogger.js.map +1 -1
- package/lib/logging/createLogger.js.map +1 -1
- package/lib/logging/createNoopLogger.js.map +1 -1
- package/lib/logging/slog.js.map +1 -1
- package/lib/maths/clamp.js.map +1 -1
- package/lib/maths/random.js.map +1 -1
- package/lib/mitt/index.js.map +1 -1
- package/lib/modules/isModule.js.map +1 -1
- package/lib/modules/parseModuleId.js.map +1 -1
- package/lib/objects/computeIfAbsent.js.map +1 -1
- package/lib/objects/get.js.map +1 -1
- package/lib/objects/get.test-d.js.map +1 -1
- package/lib/objects/merge/index.js.map +1 -1
- package/lib/objects/merge/isMergeableObject.js.map +1 -1
- package/lib/objects/merge/merge.js.map +1 -1
- package/lib/objects/parseObjectPath.js.map +1 -1
- package/lib/objects/set.js.map +1 -1
- package/lib/runtime/AsyncCloser.js.map +1 -1
- package/lib/runtime/Closer.js.map +1 -1
- package/lib/runtime/getGlobalThis.js.map +1 -1
- package/lib/runtime/structuredClone.js.map +1 -1
- package/lib/schema/typebox/index.js.map +1 -1
- package/lib/schema/typebox/typebox.js.map +1 -1
- package/lib/scripts/getGenerateContext.js.map +1 -1
- package/lib/server/crypto/md5.js.map +1 -1
- package/lib/server/fetch/createFetchWithProxy.js.map +1 -1
- package/lib/server/fetch/createFetchWithProxyByNodeFetch.js.map +1 -1
- package/lib/server/fetch/createFetchWithProxyByUndici.js.map +1 -1
- package/lib/server/getPackageDir.js.map +1 -1
- package/lib/server/index.js.map +1 -1
- package/lib/server/jsdom.js.map +1 -1
- package/lib/server/node-fetch.js.map +1 -1
- package/lib/server/polyfill/polyfillBrowser.js.map +1 -1
- package/lib/server/polyfill/polyfillCrypto.js.map +1 -1
- package/lib/server/polyfill/polyfillFetch.js.map +1 -1
- package/lib/server/polyfill/polyfillJsDom.js.map +1 -1
- package/lib/server/polyfill/polyfillWebSocket.js.map +1 -1
- package/lib/server/ws.js.map +1 -1
- package/lib/strings/camelCase.js.map +1 -1
- package/lib/strings/formatBytes.js.map +1 -1
- package/lib/strings/renderTemplate.js.map +1 -1
- package/lib/typedoc.js.map +1 -1
- package/lib/types.d.js.map +1 -1
- package/lib/validations/asserts.js.map +1 -1
- package/lib/validations/isUUID.js.map +1 -1
- package/lib/validations/parseTimestamp.js.map +1 -1
- package/package.json +4 -4
- package/src/errors/Errors.ts +37 -16
- package/src/io/ArrayBuffers.base64.test.ts +7 -0
- package/src/io/ArrayBuffers.ts +272 -271
- package/src/io/base64.ts +2 -2
- package/src/langs/getObjectId.ts +1 -1
package/src/io/ArrayBuffers.ts
CHANGED
|
@@ -1,252 +1,153 @@
|
|
|
1
1
|
import { classOf } from '../langs/classOf';
|
|
2
2
|
import { getGlobalThis } from '../runtime/getGlobalThis';
|
|
3
|
-
import {
|
|
3
|
+
import { decodeBase64ToUint8Array, encodeArrayBufferToBase64 } from './base64';
|
|
4
4
|
import { isBuffer } from './isBuffer';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Various utils to work with {@link ArrayBuffer}
|
|
8
8
|
*
|
|
9
|
-
* @see https://github.com/tc39/proposal-arraybuffer-base64
|
|
10
9
|
* @see https://github.com/tc39/proposal-resizablearraybuffer
|
|
11
10
|
*/
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*
|
|
21
|
-
* @see {@link https://nodejs.org/api/buffer.html#bufslicestart-end Buffer.slice}
|
|
22
|
-
*/
|
|
23
|
-
slice<T extends ArrayBufferView>(o: T, start?: number, end?: number): T;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* asView convert the given value to given {@link TypedArray} view
|
|
27
|
-
*
|
|
28
|
-
* TypedArray can be {@link Buffer}, will avoid copy
|
|
29
|
-
*/
|
|
30
|
-
asView<C extends ArrayBufferViewConstructor<unknown>>(
|
|
31
|
-
TypedArray: C,
|
|
32
|
-
v: BufferSource,
|
|
33
|
-
byteOffset?: number,
|
|
34
|
-
byteLength?: number,
|
|
35
|
-
): InstanceType<C>;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* toString convert the given {@link BufferSource} to string
|
|
39
|
-
*/
|
|
40
|
-
toString(v: BufferSource | string, encoding?: ToStringEncoding): string;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Returns true if encoding is the name of a supported character encoding, or false otherwise.
|
|
44
|
-
*/
|
|
45
|
-
isEncoding(v?: string): v is ToStringEncoding;
|
|
46
|
-
|
|
47
|
-
toJSON<T = any>(v: BufferSource | string, reviver?: (this: any, key: string, value: any) => any): T;
|
|
11
|
+
export namespace ArrayBuffers {
|
|
12
|
+
/*
|
|
13
|
+
Uint8Array to/from base64 and hex
|
|
14
|
+
Stage 3
|
|
15
|
+
Uint8Array.fromBase64, Uint8Array.prototype.toBase64
|
|
16
|
+
Uint8Array.fromHex, Uint8Array.prototype.toHex
|
|
17
|
+
https://github.com/tc39/proposal-arraybuffer-base64
|
|
18
|
+
*/
|
|
48
19
|
|
|
49
|
-
|
|
50
|
-
|
|
20
|
+
/*
|
|
21
|
+
In-Place Resizable and Growable ArrayBuffers
|
|
22
|
+
Stage 4
|
|
23
|
+
Chrome 111, Nodejs 20, Safari 16.4
|
|
24
|
+
|
|
25
|
+
SharedArrayBuffer & ArrayBuffer
|
|
26
|
+
constructor(byteLength, {maxByteLength})
|
|
27
|
+
prototype.resize(newByteLength)
|
|
28
|
+
prototype.slice(start, end)
|
|
29
|
+
prototype.{resizable,maxByteLength}
|
|
30
|
+
https://github.com/tc39/proposal-resizablearraybuffer
|
|
51
31
|
*/
|
|
52
|
-
from(v: string | BufferSource, encoding?: ToStringEncoding): ArrayBuffer;
|
|
53
32
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
33
|
+
export type BinaryStringEncoding =
|
|
34
|
+
| 'ascii'
|
|
35
|
+
| 'utf16le'
|
|
36
|
+
// | 'utf-16le'
|
|
37
|
+
| 'ucs2'
|
|
38
|
+
| 'ucs-2'
|
|
39
|
+
| 'base64'
|
|
40
|
+
| 'base64url'
|
|
41
|
+
| 'latin1'
|
|
42
|
+
| 'binary'
|
|
43
|
+
| 'utf8'
|
|
44
|
+
| 'utf-8'
|
|
45
|
+
| 'hex';
|
|
46
|
+
|
|
47
|
+
let nativeBufferAllowed: boolean = true;
|
|
48
|
+
let isBufferAvailable: undefined | boolean;
|
|
59
49
|
|
|
60
50
|
/**
|
|
61
|
-
*
|
|
51
|
+
* isNativeBufferAvailable check if the native {@link Buffer} is available
|
|
62
52
|
*/
|
|
63
|
-
|
|
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;
|
|
74
|
-
|
|
75
|
-
// truncate(v: ArrayBufferLike, len?: number): ArrayBufferLike;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
type ToStringEncoding =
|
|
79
|
-
| 'ascii'
|
|
80
|
-
| 'utf16le'
|
|
81
|
-
// | 'utf-16le'
|
|
82
|
-
| 'ucs2'
|
|
83
|
-
| 'ucs-2'
|
|
84
|
-
| 'base64'
|
|
85
|
-
| 'base64url'
|
|
86
|
-
| 'latin1'
|
|
87
|
-
| 'binary'
|
|
88
|
-
| 'utf8'
|
|
89
|
-
| 'utf-8'
|
|
90
|
-
| 'hex';
|
|
91
|
-
|
|
92
|
-
export class ArrayBuffers {
|
|
93
|
-
static #nativeBufferAllowed: boolean = true;
|
|
94
|
-
static #isBufferAvailable: undefined | boolean;
|
|
95
|
-
|
|
96
|
-
static isNativeBufferAvailable() {
|
|
53
|
+
export function isNativeBufferAvailable(): boolean {
|
|
97
54
|
// eslint-disable-next-line no-return-assign
|
|
98
|
-
return (
|
|
55
|
+
return (isBufferAvailable ??= !(getGlobalThis().Buffer as any)?.isPollyfill?.());
|
|
99
56
|
}
|
|
100
57
|
|
|
101
|
-
|
|
102
|
-
return
|
|
58
|
+
export function isNativeBufferAllowed(): boolean {
|
|
59
|
+
return Boolean(nativeBufferAllowed && isBufferAvailable);
|
|
103
60
|
}
|
|
104
61
|
|
|
105
|
-
|
|
106
|
-
|
|
62
|
+
export function setNativeBufferAllowed(v: boolean): void {
|
|
63
|
+
nativeBufferAllowed = v;
|
|
107
64
|
}
|
|
108
65
|
|
|
109
|
-
|
|
66
|
+
/**
|
|
67
|
+
* isArrayBuffer check if the given value is an {@link ArrayBuffer}
|
|
68
|
+
*/
|
|
69
|
+
export function isArrayBuffer(v: any): v is ArrayBuffer {
|
|
110
70
|
return v instanceof ArrayBuffer;
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
static toArrayBuffer(v: BufferSource): ArrayBuffer {
|
|
114
|
-
return v instanceof ArrayBuffer ? v : (v.buffer as ArrayBuffer);
|
|
115
71
|
}
|
|
116
72
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return this.toUint8Array(v).toBase64();
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (ArrayBuffers.isNativeBufferAllowed()) {
|
|
127
|
-
return Buffer.from(ArrayBuffers.asView(Uint8Array, v)).toString('base64');
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return encodeArrayBufferToBase64(this.toArrayBuffer(v));
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
static toHex = (v: BufferSource) => {
|
|
134
|
-
if ('toHex' in Uint8Array.prototype) {
|
|
135
|
-
return this.toUint8Array(v).toHex();
|
|
136
|
-
}
|
|
137
|
-
if (ArrayBuffers.isNativeBufferAllowed()) {
|
|
138
|
-
return Buffer.from(ArrayBuffers.asView(Uint8Array, v)).toString('hex');
|
|
139
|
-
}
|
|
140
|
-
return ArrayBuffers.toString(v, 'hex');
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
static fromBase64 = (v: string) => {
|
|
144
|
-
if ('fromBase64' in Uint8Array) {
|
|
145
|
-
return Uint8Array.fromBase64(v);
|
|
146
|
-
}
|
|
147
|
-
if (ArrayBuffers.isNativeBufferAllowed()) {
|
|
148
|
-
return Buffer.from(v, 'base64');
|
|
149
|
-
}
|
|
150
|
-
return this.toUint8Array(decodeBase64ToArrayBuffer(v));
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
static fromHex = (v: string) => {
|
|
154
|
-
if ('fromHex' in Uint8Array) {
|
|
155
|
-
return Uint8Array.fromHex(v);
|
|
156
|
-
}
|
|
157
|
-
return this.toUint8Array(ArrayBuffers.from(v, 'hex'));
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
static resize = (v: ArrayBuffer, newByteLength?: number, maxByteLength?: number): ArrayBuffer => {
|
|
161
|
-
if (newByteLength === undefined || newByteLength === null) {
|
|
162
|
-
return v;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Chrome 111, Nodejs 20
|
|
166
|
-
if ('resize' in v && typeof v.resize === 'function') {
|
|
167
|
-
if ('resizable' in v && v.resizable) {
|
|
168
|
-
if ('maxByteLength' in v && typeof v.maxByteLength === 'number' && v.maxByteLength >= newByteLength) {
|
|
169
|
-
v.resize(newByteLength);
|
|
170
|
-
return v as ArrayBuffer;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const old = v;
|
|
176
|
-
const newBuf = new ArrayBuffer(newByteLength, { maxByteLength: maxByteLength });
|
|
177
|
-
const oldView = new Uint8Array(old);
|
|
178
|
-
const newView = new Uint8Array(newBuf);
|
|
179
|
-
newView.set(oldView);
|
|
180
|
-
return newBuf;
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
static slice = (o: TypedArray, start?: number, end?: number) => {
|
|
73
|
+
/**
|
|
74
|
+
* slice the given view with the given offset and length, will handle the {@link Buffer} as well
|
|
75
|
+
*
|
|
76
|
+
* @see {@link https://nodejs.org/api/buffer.html#bufslicestart-end Buffer.slice}
|
|
77
|
+
*/
|
|
78
|
+
export function slice<T extends TypedArray>(o: T, start?: number, end?: number): T {
|
|
184
79
|
// NodeJS Buffer slice is not the same as UInt8Array slice
|
|
185
80
|
// https://nodejs.org/api/buffer.html#bufslicestart-end
|
|
186
81
|
if (isBuffer(o)) {
|
|
187
|
-
return Uint8Array.prototype.slice.call(o, start, end);
|
|
82
|
+
return Uint8Array.prototype.slice.call(o, start, end) as T;
|
|
188
83
|
}
|
|
189
|
-
return o.slice(start, end);
|
|
190
|
-
}
|
|
84
|
+
return o.slice(start, end) as T;
|
|
85
|
+
}
|
|
191
86
|
|
|
192
|
-
|
|
87
|
+
/**
|
|
88
|
+
* asView convert the given value to given {@link TypedArray} view
|
|
89
|
+
*
|
|
90
|
+
* TypedArray can be {@link Buffer}, will avoid copy
|
|
91
|
+
*/
|
|
92
|
+
export function asView<C extends ArrayBufferViewConstructor<unknown>>(
|
|
193
93
|
TypedArray: C,
|
|
194
94
|
v: BufferSource,
|
|
195
95
|
byteOffset?: number,
|
|
196
96
|
byteLength?: number,
|
|
197
|
-
):
|
|
97
|
+
): InstanceType<C> {
|
|
198
98
|
if (v instanceof TypedArray && (byteOffset ?? 0) === 0 && byteLength === undefined) {
|
|
199
|
-
return v as
|
|
99
|
+
return v as InstanceType<C>;
|
|
200
100
|
}
|
|
201
101
|
if (ArrayBuffer.isView(v) || isBuffer(v)) {
|
|
202
|
-
if (
|
|
102
|
+
if (isNativeBufferAllowed() && (TypedArray as any) === Buffer) {
|
|
203
103
|
// new Buffer() is deprecated
|
|
204
|
-
return Buffer.from(v.buffer, byteOffset, byteLength) as
|
|
104
|
+
return Buffer.from(v.buffer, byteOffset, byteLength) as InstanceType<C>;
|
|
205
105
|
}
|
|
206
|
-
return new TypedArray(v.buffer, v.byteOffset + (byteOffset ?? 0), byteLength ?? v.byteLength) as
|
|
106
|
+
return new TypedArray(v.buffer, v.byteOffset + (byteOffset ?? 0), byteLength ?? v.byteLength) as InstanceType<C>;
|
|
207
107
|
}
|
|
208
|
-
return new TypedArray(v, byteOffset, byteLength) as
|
|
209
|
-
}
|
|
108
|
+
return new TypedArray(v, byteOffset, byteLength) as InstanceType<C>;
|
|
109
|
+
}
|
|
210
110
|
|
|
211
|
-
|
|
111
|
+
/**
|
|
112
|
+
* toString convert the given {@link BufferSource} to string
|
|
113
|
+
*/
|
|
114
|
+
export function toString(source: BufferSource | string, encoding: BinaryStringEncoding = 'utf8'): string {
|
|
212
115
|
// 'ascii' 'utf16le' | 'ucs2' | 'ucs-2' | 'base64' | 'base64url' | 'latin1' | 'binary' | 'hex'
|
|
213
|
-
if (typeof
|
|
116
|
+
if (typeof source === 'string') {
|
|
214
117
|
switch (encoding) {
|
|
215
118
|
case 'base64':
|
|
216
|
-
return btoa(
|
|
119
|
+
return btoa(source);
|
|
217
120
|
case 'utf-8':
|
|
218
121
|
case 'utf8':
|
|
219
|
-
return
|
|
122
|
+
return source;
|
|
220
123
|
default:
|
|
221
124
|
throw new Error(`[ArrayBuffers.toString] Unsupported encoding for string: ${encoding}`);
|
|
222
125
|
}
|
|
223
126
|
}
|
|
224
|
-
|
|
225
|
-
|
|
127
|
+
let u8 = asView(Uint8Array, source);
|
|
128
|
+
if (isNativeBufferAllowed()) {
|
|
129
|
+
return Buffer.from(u8).toString(encoding);
|
|
226
130
|
}
|
|
227
131
|
// reference
|
|
228
132
|
// https://github.com/feross/buffer/blob/master/index.js
|
|
229
133
|
switch (encoding) {
|
|
230
134
|
case 'hex': {
|
|
231
|
-
|
|
232
|
-
return [...view].map((b) => hexLookupTable[b]).join('');
|
|
135
|
+
return [...u8].map((b) => hexLookupTable[b]).join('');
|
|
233
136
|
}
|
|
234
137
|
case 'base64': {
|
|
235
|
-
return encodeArrayBufferToBase64(
|
|
138
|
+
return encodeArrayBufferToBase64(u8);
|
|
236
139
|
}
|
|
237
140
|
case 'utf8':
|
|
238
141
|
// falls through
|
|
239
142
|
case 'utf-8':
|
|
240
|
-
return new TextDecoder().decode(
|
|
143
|
+
return new TextDecoder().decode(source);
|
|
241
144
|
case 'ascii': {
|
|
242
|
-
|
|
243
|
-
return String.fromCharCode(...view.map((v) => v & 0x7f));
|
|
145
|
+
return String.fromCharCode(...u8.map((v) => v & 0x7f));
|
|
244
146
|
}
|
|
245
147
|
case 'latin1':
|
|
246
148
|
// falls through
|
|
247
149
|
case 'binary': {
|
|
248
|
-
|
|
249
|
-
return String.fromCharCode(...view);
|
|
150
|
+
return String.fromCharCode(...u8);
|
|
250
151
|
}
|
|
251
152
|
case 'ucs2':
|
|
252
153
|
// falls through
|
|
@@ -254,120 +155,113 @@ export class ArrayBuffers {
|
|
|
254
155
|
// case 'utf-16le':
|
|
255
156
|
// falls through
|
|
256
157
|
case 'utf16le': {
|
|
257
|
-
const view: Uint8Array = ArrayBuffers.asView(Uint8Array, buf);
|
|
258
158
|
let res = '';
|
|
259
159
|
// If length is odd, the last 8 bits must be ignored (same as node.js)
|
|
260
|
-
for (let i = 0; i <
|
|
261
|
-
res += String.fromCharCode(
|
|
160
|
+
for (let i = 0; i < u8.length - 1; i += 2) {
|
|
161
|
+
res += String.fromCharCode(u8[i] + u8[i + 1] * 256);
|
|
262
162
|
}
|
|
263
163
|
return res;
|
|
264
164
|
}
|
|
265
165
|
default:
|
|
266
166
|
throw new Error(`[ArrayBuffers.toString] Unknown encoding: ${encoding}`);
|
|
267
167
|
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
static toJSON = (v: BufferSource | string, reviver?: (this: any, key: string, value: any) => any) => {
|
|
271
|
-
return JSON.parse(ArrayBuffers.toString(v), reviver);
|
|
272
|
-
};
|
|
168
|
+
}
|
|
273
169
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
170
|
+
function normalizeEncoding(encoding: string | undefined) {
|
|
171
|
+
switch (encoding?.toLowerCase()) {
|
|
172
|
+
case 'utf-8':
|
|
173
|
+
case 'utf8':
|
|
174
|
+
return 'utf8';
|
|
175
|
+
case 'utf-16le':
|
|
176
|
+
case 'ucs2':
|
|
177
|
+
case 'ucs-2':
|
|
178
|
+
return 'utf16le';
|
|
179
|
+
case 'hex':
|
|
180
|
+
case 'ascii':
|
|
181
|
+
case 'latin1':
|
|
182
|
+
case 'binary':
|
|
183
|
+
case 'base64':
|
|
184
|
+
case 'utf16le':
|
|
185
|
+
return encoding;
|
|
186
|
+
default:
|
|
187
|
+
return undefined;
|
|
282
188
|
}
|
|
283
|
-
|
|
284
|
-
};
|
|
189
|
+
}
|
|
285
190
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
191
|
+
/**
|
|
192
|
+
* Returns true if encoding is the name of a supported character encoding, or false otherwise.
|
|
193
|
+
*/
|
|
194
|
+
export function isEncoding(v?: string): v is BinaryStringEncoding {
|
|
195
|
+
return normalizeEncoding(v) !== undefined;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function toJSON<T = any>(v: BufferSource | string, reviver?: (this: any, key: string, value: any) => any): T {
|
|
199
|
+
return JSON.parse(toString(v), reviver);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* from convert the given value to {@link ArrayBuffer} like
|
|
204
|
+
*/
|
|
205
|
+
export function from(
|
|
206
|
+
src: string | BufferSource | Array<number> | Iterable<number>,
|
|
207
|
+
encoding?: BinaryStringEncoding,
|
|
208
|
+
): ArrayBuffer | TypedArray;
|
|
209
|
+
/**
|
|
210
|
+
* from convert the given value to {@link TypedArray}
|
|
211
|
+
*/
|
|
212
|
+
export function from<C extends ArrayBufferViewConstructor<unknown>>(
|
|
213
|
+
src: string | BufferSource | Array<number> | Iterable<number>,
|
|
214
|
+
encoding: BinaryStringEncoding,
|
|
215
|
+
TypedArray: C,
|
|
216
|
+
): InstanceType<C>;
|
|
217
|
+
export function from(
|
|
218
|
+
src: string | BufferSource | Array<number> | Iterable<number>,
|
|
219
|
+
encoding: BinaryStringEncoding = 'utf8',
|
|
289
220
|
view?: any,
|
|
290
|
-
): any
|
|
291
|
-
if (
|
|
292
|
-
return
|
|
221
|
+
): any {
|
|
222
|
+
if (!src) {
|
|
223
|
+
return new (view || ArrayBuffer)(0);
|
|
224
|
+
}
|
|
225
|
+
if (isBufferSource(src)) {
|
|
226
|
+
return view ? asView(view, src) : src;
|
|
293
227
|
}
|
|
294
|
-
|
|
295
|
-
|
|
228
|
+
// Array<number> | Iterable<number>
|
|
229
|
+
if ((typeof src !== 'string' && isIterable(src)) || Array.isArray(src)) {
|
|
230
|
+
return (view || Uint8Array).from(src);
|
|
296
231
|
}
|
|
297
|
-
if (
|
|
298
|
-
|
|
299
|
-
|
|
232
|
+
if (view) {
|
|
233
|
+
return asView(view, from(src, encoding));
|
|
234
|
+
}
|
|
235
|
+
if (typeof src === 'string') {
|
|
236
|
+
// is string
|
|
237
|
+
if (isNativeBufferAllowed()) {
|
|
238
|
+
return Buffer.from(src, encoding);
|
|
300
239
|
}
|
|
301
|
-
|
|
302
240
|
switch (encoding) {
|
|
303
241
|
case 'utf-8':
|
|
304
242
|
// falls through
|
|
305
243
|
case 'utf8':
|
|
306
|
-
return new TextEncoder().encode(
|
|
244
|
+
return new TextEncoder().encode(src).buffer;
|
|
307
245
|
case 'base64':
|
|
308
246
|
// replaceAll need higher version of nodejs
|
|
309
|
-
return decodeBase64ToArrayBuffer(v.replace(/[^0-9a-zA-Z=+/_]/g, ''));
|
|
247
|
+
// return decodeBase64ToArrayBuffer(v.replace(/[^0-9a-zA-Z=+/_]/g, ''));
|
|
248
|
+
return fromBase64(src);
|
|
310
249
|
case 'hex':
|
|
311
|
-
return new Uint8Array(v.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))).buffer;
|
|
250
|
+
// return new Uint8Array(v.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))).buffer;
|
|
251
|
+
return fromHex(src);
|
|
312
252
|
default:
|
|
313
|
-
throw new Error(`
|
|
253
|
+
throw new Error(`ArrayBuffers.from unsupported encoding: ${encoding}`);
|
|
314
254
|
}
|
|
315
255
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
}
|
|
319
|
-
// lost length
|
|
320
|
-
if (ArrayBuffer.isView(v) || isBuffer(v)) {
|
|
321
|
-
if (v.byteOffset !== 0) {
|
|
322
|
-
// return v.buffer.slice(v.byteOffset, v.byteOffset + v.byteLength)
|
|
323
|
-
throw new Error('ArrayBuffers.from do not support view with offset');
|
|
324
|
-
}
|
|
325
|
-
return v.buffer;
|
|
326
|
-
}
|
|
327
|
-
if (Array.isArray(v)) {
|
|
328
|
-
return new Uint8Array(v);
|
|
329
|
-
}
|
|
330
|
-
const type = classOf(v);
|
|
256
|
+
|
|
257
|
+
const type = classOf(src);
|
|
331
258
|
throw new TypeError(`ArrayBuffers.from unsupported type ${type}`);
|
|
332
|
-
}
|
|
259
|
+
}
|
|
333
260
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
case 'utf-8':
|
|
339
|
-
case 'ascii':
|
|
340
|
-
case 'latin1':
|
|
341
|
-
case 'binary':
|
|
342
|
-
case 'base64':
|
|
343
|
-
case 'ucs2':
|
|
344
|
-
case 'ucs-2':
|
|
345
|
-
case 'utf16le':
|
|
346
|
-
// case 'utf-16le':
|
|
347
|
-
return true;
|
|
348
|
-
default:
|
|
349
|
-
return false;
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
// static truncate = (a: ArrayBufferLike, len?: number) => {
|
|
354
|
-
// if (len === 0) {
|
|
355
|
-
// return new ArrayBuffer(0);
|
|
356
|
-
// }
|
|
357
|
-
// if (!len) {
|
|
358
|
-
// return a;
|
|
359
|
-
// }
|
|
360
|
-
// if (a.byteLength > len) {
|
|
361
|
-
// return a.slice(0, len);
|
|
362
|
-
// } else if (a.byteLength < len) {
|
|
363
|
-
// let b = new Uint8Array(len);
|
|
364
|
-
// b.set(new Uint8Array(a));
|
|
365
|
-
// return b;
|
|
366
|
-
// }
|
|
367
|
-
// return a;
|
|
368
|
-
// };
|
|
369
|
-
|
|
370
|
-
static concat = (buffers: Array<BufferSource>, result?: ArrayBuffer, offset = 0): ArrayBuffer => {
|
|
261
|
+
/**
|
|
262
|
+
* concat the given {@link BufferSource} to a new {@link ArrayBuffer}
|
|
263
|
+
*/
|
|
264
|
+
export function concat(buffers: Array<BufferSource>, result?: ArrayBuffer, offset = 0): ArrayBuffer {
|
|
371
265
|
// https://stackoverflow.com/questions/10786128/appending-arraybuffers
|
|
372
266
|
|
|
373
267
|
const length = buffers.reduce((a, b) => a + b.byteLength, 0);
|
|
@@ -386,7 +280,106 @@ export class ArrayBuffers {
|
|
|
386
280
|
offset += buffer.byteLength;
|
|
387
281
|
}
|
|
388
282
|
return r.buffer;
|
|
389
|
-
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export function fromBase64(v: string): Uint8Array {
|
|
286
|
+
if ('fromBase64' in Uint8Array) {
|
|
287
|
+
return Uint8Array.fromBase64(v);
|
|
288
|
+
}
|
|
289
|
+
if (isNativeBufferAllowed()) {
|
|
290
|
+
return Buffer.from(v, 'base64');
|
|
291
|
+
}
|
|
292
|
+
return decodeBase64ToUint8Array(v.replace(/[^0-9a-zA-Z=+/_]/g, ''));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export function fromHex(v: string): Uint8Array {
|
|
296
|
+
if ('fromHex' in Uint8Array) {
|
|
297
|
+
return Uint8Array.fromHex(v);
|
|
298
|
+
}
|
|
299
|
+
if (isNativeBufferAllowed()) {
|
|
300
|
+
return Buffer.from(v, 'hex');
|
|
301
|
+
}
|
|
302
|
+
return new Uint8Array(v.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16)));
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* toBase64 convert the given {@link BufferSource} to base64 string
|
|
307
|
+
* @param source if string, will be encoded as utf8
|
|
308
|
+
*/
|
|
309
|
+
export function toBase64(source: BufferSource | string): string {
|
|
310
|
+
if (typeof source === 'string') {
|
|
311
|
+
source = new TextEncoder().encode(source);
|
|
312
|
+
}
|
|
313
|
+
if ('toBase64' in Uint8Array.prototype) {
|
|
314
|
+
return toUint8Array(source).toBase64();
|
|
315
|
+
}
|
|
316
|
+
if (isNativeBufferAllowed()) {
|
|
317
|
+
return Buffer.from(asView(Uint8Array, source)).toString('base64');
|
|
318
|
+
}
|
|
319
|
+
return encodeArrayBufferToBase64(toArrayBuffer(source));
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export function toHex(v: BufferSource): string {
|
|
323
|
+
if ('toHex' in Uint8Array.prototype) {
|
|
324
|
+
return toUint8Array(v).toHex();
|
|
325
|
+
}
|
|
326
|
+
if (isNativeBufferAllowed()) {
|
|
327
|
+
return Buffer.from(asView(Uint8Array, v)).toString('hex');
|
|
328
|
+
}
|
|
329
|
+
return toString(v, 'hex');
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export function resize(v: ArrayBuffer, newByteLength?: number, maxByteLength?: number): ArrayBuffer {
|
|
333
|
+
if (newByteLength === undefined || newByteLength === null) {
|
|
334
|
+
return v;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Chrome 111, Nodejs 20
|
|
338
|
+
if ('resize' in v && typeof v.resize === 'function') {
|
|
339
|
+
if ('resizable' in v && v.resizable) {
|
|
340
|
+
if ('maxByteLength' in v && typeof v.maxByteLength === 'number' && v.maxByteLength >= newByteLength) {
|
|
341
|
+
v.resize(newByteLength);
|
|
342
|
+
return v as ArrayBuffer;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const old = v;
|
|
348
|
+
const newBuf = new ArrayBuffer(newByteLength, { maxByteLength: maxByteLength });
|
|
349
|
+
const oldView = new Uint8Array(old);
|
|
350
|
+
const newView = new Uint8Array(newBuf);
|
|
351
|
+
newView.set(oldView);
|
|
352
|
+
return newBuf;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export function toArrayBuffer(v: BufferSource): ArrayBuffer {
|
|
356
|
+
if (v instanceof ArrayBuffer) {
|
|
357
|
+
return v;
|
|
358
|
+
}
|
|
359
|
+
if (ArrayBuffer.isView(v)) {
|
|
360
|
+
if (v.byteOffset > 0) {
|
|
361
|
+
throw new Error('ArrayBuffers.toArrayBuffer do not support view with offset');
|
|
362
|
+
}
|
|
363
|
+
return v.buffer;
|
|
364
|
+
}
|
|
365
|
+
throw new Error(`ArrayBuffers.toArrayBuffer unsupported type ${classOf(v)}`);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export function toUint8Array(v: BufferSource): Uint8Array {
|
|
369
|
+
return asView(Uint8Array, v);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export function alloc(size: number, fill?: string | number, encoding?: BinaryStringEncoding): ArrayBuffer {
|
|
373
|
+
if (fill !== undefined) {
|
|
374
|
+
if (typeof fill === 'number') {
|
|
375
|
+
return new Uint8Array(size).fill(fill);
|
|
376
|
+
}
|
|
377
|
+
// as cast
|
|
378
|
+
// https://stackoverflow.com/questions/73994091
|
|
379
|
+
return asView(Uint8Array, from(fill, encoding)).slice(0, size);
|
|
380
|
+
}
|
|
381
|
+
return new ArrayBuffer(size);
|
|
382
|
+
}
|
|
390
383
|
}
|
|
391
384
|
|
|
392
385
|
export type TypedArray =
|
|
@@ -443,3 +436,11 @@ declare global {
|
|
|
443
436
|
fromHex(v: string): Uint8Array;
|
|
444
437
|
}
|
|
445
438
|
}
|
|
439
|
+
|
|
440
|
+
function isIterable(obj: any): obj is Iterable<any> {
|
|
441
|
+
return typeof obj?.[Symbol.iterator] === 'function';
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function isBufferSource(v: any): v is BufferSource {
|
|
445
|
+
return ArrayBuffer.isView(v) || v instanceof ArrayBuffer;
|
|
446
|
+
}
|
package/src/io/base64.ts
CHANGED
|
@@ -29,7 +29,7 @@ export function encodeArrayBufferToBase64(arraybuffer: ArrayBuffer): string {
|
|
|
29
29
|
return base64;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
export function
|
|
32
|
+
export function decodeBase64ToUint8Array(base64: string): Uint8Array {
|
|
33
33
|
const len = base64.length;
|
|
34
34
|
let bufferLength = base64.length * 0.75;
|
|
35
35
|
let i;
|
|
@@ -60,5 +60,5 @@ export function decodeBase64ToArrayBuffer(base64: string): ArrayBuffer {
|
|
|
60
60
|
bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
return
|
|
63
|
+
return bytes;
|
|
64
64
|
}
|