@twin.org/core 0.0.2-next.9 → 0.0.3-next.2
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/es/encoding/base32.js +75 -0
- package/dist/es/encoding/base32.js.map +1 -0
- package/dist/es/encoding/base58.js +124 -0
- package/dist/es/encoding/base58.js.map +1 -0
- package/dist/es/encoding/base64.js +231 -0
- package/dist/es/encoding/base64.js.map +1 -0
- package/dist/es/encoding/base64Url.js +42 -0
- package/dist/es/encoding/base64Url.js.map +1 -0
- package/dist/es/errors/alreadyExistsError.js +22 -0
- package/dist/es/errors/alreadyExistsError.js.map +1 -0
- package/dist/es/errors/baseError.js +257 -0
- package/dist/es/errors/baseError.js.map +1 -0
- package/dist/es/errors/conflictError.js +23 -0
- package/dist/es/errors/conflictError.js.map +1 -0
- package/dist/es/errors/generalError.js +21 -0
- package/dist/es/errors/generalError.js.map +1 -0
- package/dist/es/errors/guardError.js +27 -0
- package/dist/es/errors/guardError.js.map +1 -0
- package/dist/es/errors/notFoundError.js +22 -0
- package/dist/es/errors/notFoundError.js.map +1 -0
- package/dist/es/errors/notImplementedError.js +24 -0
- package/dist/es/errors/notImplementedError.js.map +1 -0
- package/dist/es/errors/notSupportedError.js +21 -0
- package/dist/es/errors/notSupportedError.js.map +1 -0
- package/dist/es/errors/unauthorizedError.js +21 -0
- package/dist/es/errors/unauthorizedError.js.map +1 -0
- package/dist/es/errors/unprocessableError.js +21 -0
- package/dist/es/errors/unprocessableError.js.map +1 -0
- package/dist/es/errors/validationError.js +23 -0
- package/dist/es/errors/validationError.js.map +1 -0
- package/dist/es/factories/componentFactory.js +9 -0
- package/dist/es/factories/componentFactory.js.map +1 -0
- package/dist/es/factories/factory.js +256 -0
- package/dist/es/factories/factory.js.map +1 -0
- package/dist/es/helpers/arrayHelper.js +44 -0
- package/dist/es/helpers/arrayHelper.js.map +1 -0
- package/dist/es/helpers/envHelper.js +39 -0
- package/dist/es/helpers/envHelper.js.map +1 -0
- package/dist/es/helpers/errorHelper.js +100 -0
- package/dist/es/helpers/errorHelper.js.map +1 -0
- package/dist/es/helpers/filenameHelper.js +32 -0
- package/dist/es/helpers/filenameHelper.js.map +1 -0
- package/dist/es/helpers/hexHelper.js +45 -0
- package/dist/es/helpers/hexHelper.js.map +1 -0
- package/dist/es/helpers/jsonHelper.js +163 -0
- package/dist/es/helpers/jsonHelper.js.map +1 -0
- package/dist/es/helpers/numberHelper.js +30 -0
- package/dist/es/helpers/numberHelper.js.map +1 -0
- package/dist/es/helpers/objectHelper.js +333 -0
- package/dist/es/helpers/objectHelper.js.map +1 -0
- package/dist/es/helpers/randomHelper.js +18 -0
- package/dist/es/helpers/randomHelper.js.map +1 -0
- package/dist/es/helpers/stringHelper.js +241 -0
- package/dist/es/helpers/stringHelper.js.map +1 -0
- package/dist/es/helpers/uint8ArrayHelper.js +26 -0
- package/dist/es/helpers/uint8ArrayHelper.js.map +1 -0
- package/dist/es/index.js +57 -0
- package/dist/es/index.js.map +1 -0
- package/dist/es/models/IComponent.js +4 -0
- package/dist/es/models/IComponent.js.map +1 -0
- package/dist/es/models/IError.js +4 -0
- package/dist/es/models/IError.js.map +1 -0
- package/dist/es/models/II18nShared.js +2 -0
- package/dist/es/models/II18nShared.js.map +1 -0
- package/dist/es/models/IKeyValue.js +2 -0
- package/dist/es/models/IKeyValue.js.map +1 -0
- package/dist/es/models/ILabelledValue.js +2 -0
- package/dist/es/models/ILabelledValue.js.map +1 -0
- package/dist/es/models/ILocale.js +2 -0
- package/dist/es/models/ILocale.js.map +1 -0
- package/dist/es/models/ILocaleDictionary.js +4 -0
- package/dist/es/models/ILocaleDictionary.js.map +1 -0
- package/dist/es/models/ILocalesIndex.js +2 -0
- package/dist/es/models/ILocalesIndex.js.map +1 -0
- package/dist/es/models/IPatchOperation.js +4 -0
- package/dist/es/models/IPatchOperation.js.map +1 -0
- package/dist/es/models/IUrlParts.js +4 -0
- package/dist/es/models/IUrlParts.js.map +1 -0
- package/dist/es/models/IValidationFailure.js +2 -0
- package/dist/es/models/IValidationFailure.js.map +1 -0
- package/dist/es/models/coerceType.js +49 -0
- package/dist/es/models/coerceType.js.map +1 -0
- package/dist/es/models/compressionType.js +17 -0
- package/dist/es/models/compressionType.js.map +1 -0
- package/dist/es/models/objectOrArray.js +2 -0
- package/dist/es/models/objectOrArray.js.map +1 -0
- package/dist/es/types/bitString.js +98 -0
- package/dist/es/types/bitString.js.map +1 -0
- package/dist/es/types/url.js +144 -0
- package/dist/es/types/url.js.map +1 -0
- package/dist/es/types/urn.js +212 -0
- package/dist/es/types/urn.js.map +1 -0
- package/dist/es/utils/asyncCache.js +179 -0
- package/dist/es/utils/asyncCache.js.map +1 -0
- package/dist/es/utils/coerce.js +269 -0
- package/dist/es/utils/coerce.js.map +1 -0
- package/dist/es/utils/compression.js +49 -0
- package/dist/es/utils/compression.js.map +1 -0
- package/dist/es/utils/converter.js +256 -0
- package/dist/es/utils/converter.js.map +1 -0
- package/dist/es/utils/guards.js +369 -0
- package/dist/es/utils/guards.js.map +1 -0
- package/dist/es/utils/i18n.js +243 -0
- package/dist/es/utils/i18n.js.map +1 -0
- package/dist/es/utils/is.js +351 -0
- package/dist/es/utils/is.js.map +1 -0
- package/dist/es/utils/sharedStore.js +48 -0
- package/dist/es/utils/sharedStore.js.map +1 -0
- package/dist/es/utils/validation.js +774 -0
- package/dist/es/utils/validation.js.map +1 -0
- package/dist/types/encoding/base32.d.ts +4 -0
- package/dist/types/encoding/base58.d.ts +4 -0
- package/dist/types/encoding/base64.d.ts +4 -0
- package/dist/types/encoding/base64Url.d.ts +4 -0
- package/dist/types/errors/alreadyExistsError.d.ts +5 -2
- package/dist/types/errors/baseError.d.ts +1 -1
- package/dist/types/errors/conflictError.d.ts +5 -2
- package/dist/types/errors/generalError.d.ts +1 -1
- package/dist/types/errors/guardError.d.ts +1 -1
- package/dist/types/errors/notFoundError.d.ts +5 -2
- package/dist/types/errors/notImplementedError.d.ts +6 -2
- package/dist/types/errors/notSupportedError.d.ts +5 -2
- package/dist/types/errors/unauthorizedError.d.ts +5 -2
- package/dist/types/errors/unprocessableError.d.ts +1 -1
- package/dist/types/errors/validationError.d.ts +2 -2
- package/dist/types/factories/componentFactory.d.ts +2 -2
- package/dist/types/factories/factory.d.ts +4 -0
- package/dist/types/helpers/arrayHelper.d.ts +1 -1
- package/dist/types/helpers/errorHelper.d.ts +1 -1
- package/dist/types/helpers/jsonHelper.d.ts +5 -1
- package/dist/types/helpers/numberHelper.d.ts +17 -0
- package/dist/types/helpers/objectHelper.d.ts +14 -0
- package/dist/types/helpers/stringHelper.d.ts +6 -6
- package/dist/types/index.d.ts +54 -53
- package/dist/types/models/IComponent.d.ts +6 -7
- package/dist/types/models/ILocalesIndex.d.ts +1 -1
- package/dist/types/models/IValidationFailure.d.ts +0 -4
- package/dist/types/types/bitString.d.ts +4 -0
- package/dist/types/types/url.d.ts +8 -3
- package/dist/types/types/urn.d.ts +7 -2
- package/dist/types/utils/coerce.d.ts +1 -1
- package/dist/types/utils/compression.d.ts +5 -1
- package/dist/types/utils/guards.d.ts +2 -3
- package/dist/types/utils/i18n.d.ts +16 -1
- package/dist/types/utils/is.d.ts +1 -1
- package/dist/types/utils/validation.d.ts +1 -1
- package/docs/changelog.md +283 -0
- package/docs/reference/classes/AlreadyExistsError.md +8 -4
- package/docs/reference/classes/AsyncCache.md +5 -5
- package/docs/reference/classes/Base32.md +8 -0
- package/docs/reference/classes/Base58.md +8 -0
- package/docs/reference/classes/Base64.md +8 -0
- package/docs/reference/classes/Base64Url.md +8 -0
- package/docs/reference/classes/BaseError.md +3 -3
- package/docs/reference/classes/BitString.md +8 -0
- package/docs/reference/classes/Coerce.md +20 -20
- package/docs/reference/classes/Compression.md +8 -0
- package/docs/reference/classes/ConflictError.md +8 -4
- package/docs/reference/classes/ErrorHelper.md +2 -2
- package/docs/reference/classes/Factory.md +11 -3
- package/docs/reference/classes/GeneralError.md +3 -3
- package/docs/reference/classes/GuardError.md +3 -3
- package/docs/reference/classes/Guards.md +8 -4
- package/docs/reference/classes/I18n.md +54 -2
- package/docs/reference/classes/Is.md +10 -4
- package/docs/reference/classes/JsonHelper.md +8 -0
- package/docs/reference/classes/NotFoundError.md +8 -4
- package/docs/reference/classes/NotImplementedError.md +14 -4
- package/docs/reference/classes/NotSupportedError.md +8 -4
- package/docs/reference/classes/NumberHelper.md +55 -0
- package/docs/reference/classes/ObjectHelper.md +58 -8
- package/docs/reference/classes/SharedStore.md +2 -2
- package/docs/reference/classes/StringHelper.md +8 -8
- package/docs/reference/classes/UnauthorizedError.md +8 -4
- package/docs/reference/classes/UnprocessableError.md +3 -3
- package/docs/reference/classes/Url.md +17 -3
- package/docs/reference/classes/Urn.md +19 -5
- package/docs/reference/classes/Validation.md +2 -2
- package/docs/reference/classes/ValidationError.md +3 -3
- package/docs/reference/index.md +1 -0
- package/docs/reference/interfaces/IComponent.md +19 -25
- package/docs/reference/interfaces/IValidationFailure.md +0 -8
- package/locales/.validate-ignore +1 -0
- package/locales/en.json +4 -5
- package/package.json +22 -10
- package/dist/cjs/index.cjs +0 -5175
- package/dist/esm/index.mjs +0 -5133
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// Copyright 2024 IOTA Stiftung.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
+
import { Is } from "./is.js";
|
|
4
|
+
import { SharedStore } from "./sharedStore.js";
|
|
5
|
+
/**
|
|
6
|
+
* Cache the results from asynchronous requests.
|
|
7
|
+
*/
|
|
8
|
+
export class AsyncCache {
|
|
9
|
+
/**
|
|
10
|
+
* Execute an async request and cache the result.
|
|
11
|
+
* @param key The key for the entry in the cache.
|
|
12
|
+
* @param ttlMs The TTL of the entry in the cache.
|
|
13
|
+
* @param requestMethod The method to call if not cached.
|
|
14
|
+
* @param cacheFailures Cache failure results, defaults to false.
|
|
15
|
+
* @returns The response.
|
|
16
|
+
*/
|
|
17
|
+
static exec(key, ttlMs, requestMethod, cacheFailures) {
|
|
18
|
+
const cacheEnabled = Is.integer(ttlMs) && ttlMs >= 0;
|
|
19
|
+
if (cacheEnabled) {
|
|
20
|
+
AsyncCache.cleanupExpired();
|
|
21
|
+
const cache = AsyncCache.getSharedCache();
|
|
22
|
+
// Do we have a cache entry for the key
|
|
23
|
+
if (cache[key]) {
|
|
24
|
+
if (!Is.empty(cache[key].result)) {
|
|
25
|
+
// If the cache has already resulted in a value, resolve it
|
|
26
|
+
return Promise.resolve(cache[key].result);
|
|
27
|
+
}
|
|
28
|
+
else if (!Is.empty(cache[key].error)) {
|
|
29
|
+
// If the cache has already resulted in an error, reject it
|
|
30
|
+
return Promise.reject(cache[key].error);
|
|
31
|
+
}
|
|
32
|
+
// Otherwise create a promise to return and store the resolver
|
|
33
|
+
// and rejector in the cache entry, so that we can call then
|
|
34
|
+
// when the request is done
|
|
35
|
+
let storedResolve;
|
|
36
|
+
let storedReject;
|
|
37
|
+
const wait = new Promise((resolve, reject) => {
|
|
38
|
+
storedResolve = resolve;
|
|
39
|
+
storedReject = reject;
|
|
40
|
+
});
|
|
41
|
+
if (!Is.empty(storedResolve) && !Is.empty(storedReject)) {
|
|
42
|
+
cache[key].promiseQueue.push({
|
|
43
|
+
requestMethod,
|
|
44
|
+
resolve: storedResolve,
|
|
45
|
+
reject: storedReject
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return wait;
|
|
49
|
+
}
|
|
50
|
+
// If we don't have a cache entry, create a new one
|
|
51
|
+
cache[key] = {
|
|
52
|
+
promiseQueue: [],
|
|
53
|
+
expires: ttlMs === 0 ? 0 : Date.now() + ttlMs
|
|
54
|
+
};
|
|
55
|
+
// Return a promise that wraps the original request method
|
|
56
|
+
// so that we can store any results or errors in the cache
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
// Call the request method and store the result
|
|
59
|
+
requestMethod()
|
|
60
|
+
// eslint-disable-next-line promise/prefer-await-to-then
|
|
61
|
+
.then(res => {
|
|
62
|
+
// If the request was successful, store the result
|
|
63
|
+
cache[key].result = res;
|
|
64
|
+
// and resolve both this promise and all the waiters
|
|
65
|
+
resolve(res);
|
|
66
|
+
for (const wait of cache[key].promiseQueue) {
|
|
67
|
+
wait.resolve(res);
|
|
68
|
+
}
|
|
69
|
+
return res;
|
|
70
|
+
})
|
|
71
|
+
// eslint-disable-next-line promise/prefer-await-to-then
|
|
72
|
+
.catch((err) => {
|
|
73
|
+
// Reject the promise
|
|
74
|
+
reject(err);
|
|
75
|
+
// Handle the waiters based on the cacheFailures flag
|
|
76
|
+
if (cacheFailures ?? false) {
|
|
77
|
+
// If we are caching failures, store the error and reject the waiters
|
|
78
|
+
cache[key].error = err;
|
|
79
|
+
for (const wait of cache[key].promiseQueue) {
|
|
80
|
+
wait.reject(err);
|
|
81
|
+
}
|
|
82
|
+
// Clear the waiters so we don't call them again
|
|
83
|
+
cache[key].promiseQueue = [];
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// If not caching failures for any queued requests we
|
|
87
|
+
// have no value to either resolve or reject, so we
|
|
88
|
+
// just resolve with the original request method
|
|
89
|
+
for (const wait of cache[key].promiseQueue) {
|
|
90
|
+
wait.resolve(wait.requestMethod());
|
|
91
|
+
}
|
|
92
|
+
delete cache[key];
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get an entry from the cache.
|
|
100
|
+
* @param key The key to get from the cache.
|
|
101
|
+
* @returns The item from the cache if it exists.
|
|
102
|
+
*/
|
|
103
|
+
static async get(key) {
|
|
104
|
+
const cache = AsyncCache.getSharedCache();
|
|
105
|
+
if (!Is.empty(cache[key].result)) {
|
|
106
|
+
// If the cache has already resulted in a value, resolve it
|
|
107
|
+
return cache[key].result;
|
|
108
|
+
}
|
|
109
|
+
else if (!Is.empty(cache[key].error)) {
|
|
110
|
+
// If the cache has already resulted in an error, reject it
|
|
111
|
+
throw cache[key].error;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Set an entry into the cache.
|
|
116
|
+
* @param key The key to set in the cache.
|
|
117
|
+
* @param value The value to set in the cache.
|
|
118
|
+
* @param ttlMs The TTL of the entry in the cache in ms, defaults to 1s.
|
|
119
|
+
* @returns Nothing.
|
|
120
|
+
*/
|
|
121
|
+
static async set(key, value, ttlMs) {
|
|
122
|
+
const cache = AsyncCache.getSharedCache();
|
|
123
|
+
cache[key] = {
|
|
124
|
+
result: value,
|
|
125
|
+
promiseQueue: [],
|
|
126
|
+
expires: Date.now() + (ttlMs ?? 1000)
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Remove an entry from the cache.
|
|
131
|
+
* @param key The key to remove from the cache.
|
|
132
|
+
*/
|
|
133
|
+
static remove(key) {
|
|
134
|
+
const cache = AsyncCache.getSharedCache();
|
|
135
|
+
delete cache[key];
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Clear the cache.
|
|
139
|
+
* @param prefix Optional prefix to clear only entries with that prefix.
|
|
140
|
+
*/
|
|
141
|
+
static clearCache(prefix) {
|
|
142
|
+
const cache = AsyncCache.getSharedCache();
|
|
143
|
+
if (Is.stringValue(prefix)) {
|
|
144
|
+
for (const entry in cache) {
|
|
145
|
+
if (entry.startsWith(prefix)) {
|
|
146
|
+
delete cache[entry];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
SharedStore.set("asyncCache", {});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Perform a cleanup of the expired entries in the cache.
|
|
156
|
+
*/
|
|
157
|
+
static cleanupExpired() {
|
|
158
|
+
const cache = AsyncCache.getSharedCache();
|
|
159
|
+
for (const entry in cache) {
|
|
160
|
+
if (cache[entry].expires > 0 && cache[entry].expires < Date.now()) {
|
|
161
|
+
delete cache[entry];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get the shared cache.
|
|
167
|
+
* @returns The shared cache.
|
|
168
|
+
* @internal
|
|
169
|
+
*/
|
|
170
|
+
static getSharedCache() {
|
|
171
|
+
let sharedCache = SharedStore.get("asyncCache");
|
|
172
|
+
if (Is.undefined(sharedCache)) {
|
|
173
|
+
sharedCache = {};
|
|
174
|
+
SharedStore.set("asyncCache", sharedCache);
|
|
175
|
+
}
|
|
176
|
+
return sharedCache;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=asyncCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asyncCache.js","sourceRoot":"","sources":["../../../src/utils/asyncCache.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { Is } from \"./is.js\";\nimport { SharedStore } from \"./sharedStore.js\";\n\n/**\n * Cache the results from asynchronous requests.\n */\nexport class AsyncCache {\n\t/**\n\t * Execute an async request and cache the result.\n\t * @param key The key for the entry in the cache.\n\t * @param ttlMs The TTL of the entry in the cache.\n\t * @param requestMethod The method to call if not cached.\n\t * @param cacheFailures Cache failure results, defaults to false.\n\t * @returns The response.\n\t */\n\tpublic static exec<T = unknown>(\n\t\tkey: string,\n\t\tttlMs: number | undefined,\n\t\trequestMethod: () => Promise<T>,\n\t\tcacheFailures?: boolean\n\t): Promise<T> | undefined {\n\t\tconst cacheEnabled = Is.integer(ttlMs) && ttlMs >= 0;\n\t\tif (cacheEnabled) {\n\t\t\tAsyncCache.cleanupExpired();\n\n\t\t\tconst cache = AsyncCache.getSharedCache<T>();\n\n\t\t\t// Do we have a cache entry for the key\n\t\t\tif (cache[key]) {\n\t\t\t\tif (!Is.empty(cache[key].result)) {\n\t\t\t\t\t// If the cache has already resulted in a value, resolve it\n\t\t\t\t\treturn Promise.resolve(cache[key].result);\n\t\t\t\t} else if (!Is.empty(cache[key].error)) {\n\t\t\t\t\t// If the cache has already resulted in an error, reject it\n\t\t\t\t\treturn Promise.reject(cache[key].error);\n\t\t\t\t}\n\n\t\t\t\t// Otherwise create a promise to return and store the resolver\n\t\t\t\t// and rejector in the cache entry, so that we can call then\n\t\t\t\t// when the request is done\n\n\t\t\t\tlet storedResolve: ((value: T | PromiseLike<T>) => void) | undefined;\n\t\t\t\tlet storedReject: ((reason?: unknown) => void) | undefined;\n\t\t\t\tconst wait = new Promise<T>((resolve, reject) => {\n\t\t\t\t\tstoredResolve = resolve;\n\t\t\t\t\tstoredReject = reject;\n\t\t\t\t});\n\t\t\t\tif (!Is.empty(storedResolve) && !Is.empty(storedReject)) {\n\t\t\t\t\tcache[key].promiseQueue.push({\n\t\t\t\t\t\trequestMethod,\n\t\t\t\t\t\tresolve: storedResolve,\n\t\t\t\t\t\treject: storedReject\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn wait;\n\t\t\t}\n\n\t\t\t// If we don't have a cache entry, create a new one\n\t\t\tcache[key] = {\n\t\t\t\tpromiseQueue: [],\n\t\t\t\texpires: ttlMs === 0 ? 0 : Date.now() + ttlMs\n\t\t\t};\n\n\t\t\t// Return a promise that wraps the original request method\n\t\t\t// so that we can store any results or errors in the cache\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\t// Call the request method and store the result\n\t\t\t\trequestMethod()\n\t\t\t\t\t// eslint-disable-next-line promise/prefer-await-to-then\n\t\t\t\t\t.then(res => {\n\t\t\t\t\t\t// If the request was successful, store the result\n\t\t\t\t\t\tcache[key].result = res;\n\n\t\t\t\t\t\t// and resolve both this promise and all the waiters\n\t\t\t\t\t\tresolve(res);\n\t\t\t\t\t\tfor (const wait of cache[key].promiseQueue) {\n\t\t\t\t\t\t\twait.resolve(res);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn res;\n\t\t\t\t\t})\n\t\t\t\t\t// eslint-disable-next-line promise/prefer-await-to-then\n\t\t\t\t\t.catch((err: Error) => {\n\t\t\t\t\t\t// Reject the promise\n\t\t\t\t\t\treject(err);\n\n\t\t\t\t\t\t// Handle the waiters based on the cacheFailures flag\n\t\t\t\t\t\tif (cacheFailures ?? false) {\n\t\t\t\t\t\t\t// If we are caching failures, store the error and reject the waiters\n\t\t\t\t\t\t\tcache[key].error = err;\n\t\t\t\t\t\t\tfor (const wait of cache[key].promiseQueue) {\n\t\t\t\t\t\t\t\twait.reject(err);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Clear the waiters so we don't call them again\n\t\t\t\t\t\t\tcache[key].promiseQueue = [];\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// If not caching failures for any queued requests we\n\t\t\t\t\t\t\t// have no value to either resolve or reject, so we\n\t\t\t\t\t\t\t// just resolve with the original request method\n\t\t\t\t\t\t\tfor (const wait of cache[key].promiseQueue) {\n\t\t\t\t\t\t\t\twait.resolve(wait.requestMethod());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tdelete cache[key];\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Get an entry from the cache.\n\t * @param key The key to get from the cache.\n\t * @returns The item from the cache if it exists.\n\t */\n\tpublic static async get<T = unknown>(key: string): Promise<T | undefined> {\n\t\tconst cache = AsyncCache.getSharedCache<T>();\n\t\tif (!Is.empty(cache[key].result)) {\n\t\t\t// If the cache has already resulted in a value, resolve it\n\t\t\treturn cache[key].result;\n\t\t} else if (!Is.empty(cache[key].error)) {\n\t\t\t// If the cache has already resulted in an error, reject it\n\t\t\tthrow cache[key].error;\n\t\t}\n\t}\n\n\t/**\n\t * Set an entry into the cache.\n\t * @param key The key to set in the cache.\n\t * @param value The value to set in the cache.\n\t * @param ttlMs The TTL of the entry in the cache in ms, defaults to 1s.\n\t * @returns Nothing.\n\t */\n\tpublic static async set<T = unknown>(key: string, value: T, ttlMs?: number): Promise<void> {\n\t\tconst cache = AsyncCache.getSharedCache();\n\t\tcache[key] = {\n\t\t\tresult: value,\n\t\t\tpromiseQueue: [],\n\t\t\texpires: Date.now() + (ttlMs ?? 1000)\n\t\t};\n\t}\n\n\t/**\n\t * Remove an entry from the cache.\n\t * @param key The key to remove from the cache.\n\t */\n\tpublic static remove(key: string): void {\n\t\tconst cache = AsyncCache.getSharedCache();\n\t\tdelete cache[key];\n\t}\n\n\t/**\n\t * Clear the cache.\n\t * @param prefix Optional prefix to clear only entries with that prefix.\n\t */\n\tpublic static clearCache(prefix?: string): void {\n\t\tconst cache = AsyncCache.getSharedCache();\n\t\tif (Is.stringValue(prefix)) {\n\t\t\tfor (const entry in cache) {\n\t\t\t\tif (entry.startsWith(prefix)) {\n\t\t\t\t\tdelete cache[entry];\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tSharedStore.set(\"asyncCache\", {});\n\t\t}\n\t}\n\n\t/**\n\t * Perform a cleanup of the expired entries in the cache.\n\t */\n\tpublic static cleanupExpired(): void {\n\t\tconst cache = AsyncCache.getSharedCache();\n\t\tfor (const entry in cache) {\n\t\t\tif (cache[entry].expires > 0 && cache[entry].expires < Date.now()) {\n\t\t\t\tdelete cache[entry];\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the shared cache.\n\t * @returns The shared cache.\n\t * @internal\n\t */\n\tprivate static getSharedCache<T = unknown>(): {\n\t\t[url: string]: {\n\t\t\tresult?: T;\n\t\t\terror?: Error;\n\t\t\tpromiseQueue: {\n\t\t\t\trequestMethod: () => Promise<T>;\n\t\t\t\tresolve: (value: T | PromiseLike<T>) => void;\n\t\t\t\treject: (reason?: unknown) => void;\n\t\t\t}[];\n\t\t\texpires: number;\n\t\t};\n\t} {\n\t\tlet sharedCache = SharedStore.get<{\n\t\t\t[url: string]: {\n\t\t\t\tresult?: T;\n\t\t\t\terror?: Error;\n\t\t\t\tpromiseQueue: {\n\t\t\t\t\trequestMethod: () => Promise<T>;\n\t\t\t\t\tresolve: (value: T | PromiseLike<T>) => void;\n\t\t\t\t\treject: (reason?: unknown) => void;\n\t\t\t\t}[];\n\t\t\t\texpires: number;\n\t\t\t};\n\t\t}>(\"asyncCache\");\n\n\t\tif (Is.undefined(sharedCache)) {\n\t\t\tsharedCache = {};\n\t\t\tSharedStore.set(\"asyncCache\", sharedCache);\n\t\t}\n\n\t\treturn sharedCache;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
// Copyright 2024 IOTA Stiftung.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
+
import { Converter } from "./converter.js";
|
|
4
|
+
import { Is } from "./is.js";
|
|
5
|
+
import { CoerceType } from "../models/coerceType.js";
|
|
6
|
+
/**
|
|
7
|
+
* Coerce an object from one type to another.
|
|
8
|
+
*/
|
|
9
|
+
export class Coerce {
|
|
10
|
+
/**
|
|
11
|
+
* Coerce the value to a string.
|
|
12
|
+
* @param value The value to coerce.
|
|
13
|
+
* @throws TypeError If the value can not be coerced.
|
|
14
|
+
* @returns The value if it can be coerced.
|
|
15
|
+
*/
|
|
16
|
+
static string(value) {
|
|
17
|
+
if (Is.undefined(value)) {
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
if (Is.string(value)) {
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
if (Is.number(value)) {
|
|
24
|
+
return value.toString();
|
|
25
|
+
}
|
|
26
|
+
if (Is.boolean(value)) {
|
|
27
|
+
return value ? "true" : "false";
|
|
28
|
+
}
|
|
29
|
+
if (Is.date(value)) {
|
|
30
|
+
return value.toISOString();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Coerce the value to a number.
|
|
35
|
+
* @param value The value to coerce.
|
|
36
|
+
* @throws TypeError If the value can not be coerced.
|
|
37
|
+
* @returns The value if it can be coerced.
|
|
38
|
+
*/
|
|
39
|
+
static number(value) {
|
|
40
|
+
if (Is.undefined(value)) {
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
if (Is.number(value)) {
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
if (Is.string(value)) {
|
|
47
|
+
const parsed = Number.parseFloat(value);
|
|
48
|
+
if (Is.number(parsed)) {
|
|
49
|
+
return parsed;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (Is.boolean(value)) {
|
|
53
|
+
return value ? 1 : 0;
|
|
54
|
+
}
|
|
55
|
+
if (Is.date(value)) {
|
|
56
|
+
return value.getTime();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Coerce the value to an integer.
|
|
61
|
+
* @param value The value to coerce.
|
|
62
|
+
* @throws TypeError If the value can not be coerced.
|
|
63
|
+
* @returns The value if it can be coerced.
|
|
64
|
+
*/
|
|
65
|
+
static integer(value) {
|
|
66
|
+
const num = Coerce.number(value);
|
|
67
|
+
if (!Is.undefined(num)) {
|
|
68
|
+
return Math.trunc(num);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Coerce the value to a bigint.
|
|
73
|
+
* @param value The value to coerce.
|
|
74
|
+
* @throws TypeError If the value can not be coerced.
|
|
75
|
+
* @returns The value if it can be coerced.
|
|
76
|
+
*/
|
|
77
|
+
static bigint(value) {
|
|
78
|
+
if (Is.undefined(value)) {
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
if (Is.bigint(value)) {
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
if (Is.number(value)) {
|
|
85
|
+
return BigInt(value);
|
|
86
|
+
}
|
|
87
|
+
if (Is.string(value)) {
|
|
88
|
+
const parsed = Number.parseFloat(value);
|
|
89
|
+
if (Is.integer(parsed)) {
|
|
90
|
+
return BigInt(parsed);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (Is.boolean(value)) {
|
|
94
|
+
return value ? 1n : 0n;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Coerce the value to a boolean.
|
|
99
|
+
* @param value The value to coerce.
|
|
100
|
+
* @throws TypeError If the value can not be coerced.
|
|
101
|
+
* @returns The value if it can be coerced.
|
|
102
|
+
*/
|
|
103
|
+
static boolean(value) {
|
|
104
|
+
if (Is.undefined(value)) {
|
|
105
|
+
return value;
|
|
106
|
+
}
|
|
107
|
+
if (Is.boolean(value)) {
|
|
108
|
+
return value;
|
|
109
|
+
}
|
|
110
|
+
if (Is.number(value)) {
|
|
111
|
+
// eslint-disable-next-line no-unneeded-ternary
|
|
112
|
+
return value ? true : false;
|
|
113
|
+
}
|
|
114
|
+
if (Is.string(value)) {
|
|
115
|
+
if (/true/i.test(value)) {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
if (/false/i.test(value)) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Coerce the value to a date.
|
|
125
|
+
* @param value The value to coerce.
|
|
126
|
+
* @throws TypeError If the value can not be coerced.
|
|
127
|
+
* @returns The value if it can be coerced.
|
|
128
|
+
*/
|
|
129
|
+
static date(value) {
|
|
130
|
+
if (Is.undefined(value)) {
|
|
131
|
+
return value;
|
|
132
|
+
}
|
|
133
|
+
if (Is.date(value)) {
|
|
134
|
+
return value;
|
|
135
|
+
}
|
|
136
|
+
if (Is.number(value)) {
|
|
137
|
+
return new Date(value);
|
|
138
|
+
}
|
|
139
|
+
if (Is.string(value)) {
|
|
140
|
+
const dt = new Date(value);
|
|
141
|
+
if (!Number.isNaN(dt.getTime())) {
|
|
142
|
+
const utc = Date.UTC(dt.getUTCFullYear(), dt.getUTCMonth(), dt.getUTCDate());
|
|
143
|
+
return new Date(utc);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Coerce the value to a date/time.
|
|
149
|
+
* @param value The value to coerce.
|
|
150
|
+
* @throws TypeError If the value can not be coerced.
|
|
151
|
+
* @returns The value if it can be coerced.
|
|
152
|
+
*/
|
|
153
|
+
static dateTime(value) {
|
|
154
|
+
if (Is.undefined(value)) {
|
|
155
|
+
return value;
|
|
156
|
+
}
|
|
157
|
+
if (Is.date(value)) {
|
|
158
|
+
return value;
|
|
159
|
+
}
|
|
160
|
+
if (Is.number(value)) {
|
|
161
|
+
return new Date(value);
|
|
162
|
+
}
|
|
163
|
+
if (Is.string(value)) {
|
|
164
|
+
const dt = new Date(value);
|
|
165
|
+
if (!Number.isNaN(dt.getTime())) {
|
|
166
|
+
const utc = Date.UTC(dt.getUTCFullYear(), dt.getUTCMonth(), dt.getUTCDate(), dt.getUTCHours(), dt.getUTCMinutes(), dt.getUTCSeconds(), dt.getUTCMilliseconds());
|
|
167
|
+
return new Date(utc);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Coerce the value to a time.
|
|
173
|
+
* @param value The value to coerce.
|
|
174
|
+
* @throws TypeError If the value can not be coerced.
|
|
175
|
+
* @returns The value if it can be coerced.
|
|
176
|
+
*/
|
|
177
|
+
static time(value) {
|
|
178
|
+
if (Is.undefined(value)) {
|
|
179
|
+
return value;
|
|
180
|
+
}
|
|
181
|
+
if (Is.date(value)) {
|
|
182
|
+
return value;
|
|
183
|
+
}
|
|
184
|
+
if (Is.number(value)) {
|
|
185
|
+
const dt = new Date(value);
|
|
186
|
+
dt.setFullYear(1970, 0, 1);
|
|
187
|
+
return dt;
|
|
188
|
+
}
|
|
189
|
+
if (Is.string(value)) {
|
|
190
|
+
const dt = new Date(value);
|
|
191
|
+
if (!Number.isNaN(dt.getTime())) {
|
|
192
|
+
const utc = Date.UTC(1970, 0, 1, dt.getUTCHours(), dt.getUTCMinutes(), dt.getUTCSeconds(), dt.getUTCMilliseconds());
|
|
193
|
+
return new Date(utc);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Coerce the value to an object.
|
|
199
|
+
* @param value The value to coerce.
|
|
200
|
+
* @throws TypeError If the value can not be coerced.
|
|
201
|
+
* @returns The value if it can be coerced.
|
|
202
|
+
*/
|
|
203
|
+
static object(value) {
|
|
204
|
+
if (Is.undefined(value)) {
|
|
205
|
+
return value;
|
|
206
|
+
}
|
|
207
|
+
if (Is.object(value)) {
|
|
208
|
+
return value;
|
|
209
|
+
}
|
|
210
|
+
if (Is.stringValue(value)) {
|
|
211
|
+
try {
|
|
212
|
+
return JSON.parse(value);
|
|
213
|
+
}
|
|
214
|
+
catch { }
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Coerce the value to a Uint8Array.
|
|
219
|
+
* @param value The value to coerce.
|
|
220
|
+
* @throws TypeError If the value can not be coerced.
|
|
221
|
+
* @returns The value if it can be coerced.
|
|
222
|
+
*/
|
|
223
|
+
static uint8Array(value) {
|
|
224
|
+
if (Is.undefined(value)) {
|
|
225
|
+
return value;
|
|
226
|
+
}
|
|
227
|
+
if (Is.string(value)) {
|
|
228
|
+
if (Is.stringHex(value.toLowerCase(), true)) {
|
|
229
|
+
return Converter.hexToBytes(value.toLowerCase());
|
|
230
|
+
}
|
|
231
|
+
if (Is.stringBase64(value)) {
|
|
232
|
+
return Converter.base64ToBytes(value);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Coerces a value based on the coercion type.
|
|
238
|
+
* @param value The value to coerce.
|
|
239
|
+
* @param type The coercion type to perform.
|
|
240
|
+
* @returns The coerced value.
|
|
241
|
+
*/
|
|
242
|
+
static byType(value, type) {
|
|
243
|
+
switch (type) {
|
|
244
|
+
case CoerceType.String:
|
|
245
|
+
return Coerce.string(value);
|
|
246
|
+
case CoerceType.Number:
|
|
247
|
+
return Coerce.number(value);
|
|
248
|
+
case CoerceType.Integer:
|
|
249
|
+
return Coerce.integer(value);
|
|
250
|
+
case CoerceType.BigInt:
|
|
251
|
+
return Coerce.bigint(value);
|
|
252
|
+
case CoerceType.Boolean:
|
|
253
|
+
return Coerce.boolean(value);
|
|
254
|
+
case CoerceType.Date:
|
|
255
|
+
return Coerce.date(value);
|
|
256
|
+
case CoerceType.DateTime:
|
|
257
|
+
return Coerce.dateTime(value);
|
|
258
|
+
case CoerceType.Time:
|
|
259
|
+
return Coerce.time(value);
|
|
260
|
+
case CoerceType.Object:
|
|
261
|
+
return Coerce.object(value);
|
|
262
|
+
case CoerceType.Uint8Array:
|
|
263
|
+
return Coerce.uint8Array(value);
|
|
264
|
+
default:
|
|
265
|
+
return value;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=coerce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coerce.js","sourceRoot":"","sources":["../../../src/utils/coerce.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { Converter } from \"./converter.js\";\nimport { Is } from \"./is.js\";\nimport { CoerceType } from \"../models/coerceType.js\";\n\n/**\n * Coerce an object from one type to another.\n */\nexport class Coerce {\n\t/**\n\t * Coerce the value to a string.\n\t * @param value The value to coerce.\n\t * @throws TypeError If the value can not be coerced.\n\t * @returns The value if it can be coerced.\n\t */\n\tpublic static string(value: unknown): string | undefined {\n\t\tif (Is.undefined(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.string(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.number(value)) {\n\t\t\treturn value.toString();\n\t\t}\n\t\tif (Is.boolean(value)) {\n\t\t\treturn value ? \"true\" : \"false\";\n\t\t}\n\t\tif (Is.date(value)) {\n\t\t\treturn value.toISOString();\n\t\t}\n\t}\n\n\t/**\n\t * Coerce the value to a number.\n\t * @param value The value to coerce.\n\t * @throws TypeError If the value can not be coerced.\n\t * @returns The value if it can be coerced.\n\t */\n\tpublic static number(value: unknown): number | undefined {\n\t\tif (Is.undefined(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.number(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.string(value)) {\n\t\t\tconst parsed = Number.parseFloat(value);\n\t\t\tif (Is.number(parsed)) {\n\t\t\t\treturn parsed;\n\t\t\t}\n\t\t}\n\t\tif (Is.boolean(value)) {\n\t\t\treturn value ? 1 : 0;\n\t\t}\n\t\tif (Is.date(value)) {\n\t\t\treturn value.getTime();\n\t\t}\n\t}\n\n\t/**\n\t * Coerce the value to an integer.\n\t * @param value The value to coerce.\n\t * @throws TypeError If the value can not be coerced.\n\t * @returns The value if it can be coerced.\n\t */\n\tpublic static integer(value: unknown): number | undefined {\n\t\tconst num = Coerce.number(value);\n\t\tif (!Is.undefined(num)) {\n\t\t\treturn Math.trunc(num);\n\t\t}\n\t}\n\n\t/**\n\t * Coerce the value to a bigint.\n\t * @param value The value to coerce.\n\t * @throws TypeError If the value can not be coerced.\n\t * @returns The value if it can be coerced.\n\t */\n\tpublic static bigint(value: unknown): bigint | undefined {\n\t\tif (Is.undefined(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.bigint(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.number(value)) {\n\t\t\treturn BigInt(value);\n\t\t}\n\t\tif (Is.string(value)) {\n\t\t\tconst parsed = Number.parseFloat(value);\n\t\t\tif (Is.integer(parsed)) {\n\t\t\t\treturn BigInt(parsed);\n\t\t\t}\n\t\t}\n\t\tif (Is.boolean(value)) {\n\t\t\treturn value ? 1n : 0n;\n\t\t}\n\t}\n\n\t/**\n\t * Coerce the value to a boolean.\n\t * @param value The value to coerce.\n\t * @throws TypeError If the value can not be coerced.\n\t * @returns The value if it can be coerced.\n\t */\n\tpublic static boolean(value: unknown): boolean | undefined {\n\t\tif (Is.undefined(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.boolean(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.number(value)) {\n\t\t\t// eslint-disable-next-line no-unneeded-ternary\n\t\t\treturn value ? true : false;\n\t\t}\n\t\tif (Is.string(value)) {\n\t\t\tif (/true/i.test(value)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (/false/i.test(value)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Coerce the value to a date.\n\t * @param value The value to coerce.\n\t * @throws TypeError If the value can not be coerced.\n\t * @returns The value if it can be coerced.\n\t */\n\tpublic static date(value: unknown): Date | undefined {\n\t\tif (Is.undefined(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.date(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.number(value)) {\n\t\t\treturn new Date(value);\n\t\t}\n\t\tif (Is.string(value)) {\n\t\t\tconst dt = new Date(value);\n\t\t\tif (!Number.isNaN(dt.getTime())) {\n\t\t\t\tconst utc = Date.UTC(dt.getUTCFullYear(), dt.getUTCMonth(), dt.getUTCDate());\n\t\t\t\treturn new Date(utc);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Coerce the value to a date/time.\n\t * @param value The value to coerce.\n\t * @throws TypeError If the value can not be coerced.\n\t * @returns The value if it can be coerced.\n\t */\n\tpublic static dateTime(value: unknown): Date | undefined {\n\t\tif (Is.undefined(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.date(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.number(value)) {\n\t\t\treturn new Date(value);\n\t\t}\n\t\tif (Is.string(value)) {\n\t\t\tconst dt = new Date(value);\n\t\t\tif (!Number.isNaN(dt.getTime())) {\n\t\t\t\tconst utc = Date.UTC(\n\t\t\t\t\tdt.getUTCFullYear(),\n\t\t\t\t\tdt.getUTCMonth(),\n\t\t\t\t\tdt.getUTCDate(),\n\t\t\t\t\tdt.getUTCHours(),\n\t\t\t\t\tdt.getUTCMinutes(),\n\t\t\t\t\tdt.getUTCSeconds(),\n\t\t\t\t\tdt.getUTCMilliseconds()\n\t\t\t\t);\n\t\t\t\treturn new Date(utc);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Coerce the value to a time.\n\t * @param value The value to coerce.\n\t * @throws TypeError If the value can not be coerced.\n\t * @returns The value if it can be coerced.\n\t */\n\tpublic static time(value: unknown): Date | undefined {\n\t\tif (Is.undefined(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.date(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.number(value)) {\n\t\t\tconst dt = new Date(value);\n\t\t\tdt.setFullYear(1970, 0, 1);\n\t\t\treturn dt;\n\t\t}\n\t\tif (Is.string(value)) {\n\t\t\tconst dt = new Date(value);\n\t\t\tif (!Number.isNaN(dt.getTime())) {\n\t\t\t\tconst utc = Date.UTC(\n\t\t\t\t\t1970,\n\t\t\t\t\t0,\n\t\t\t\t\t1,\n\t\t\t\t\tdt.getUTCHours(),\n\t\t\t\t\tdt.getUTCMinutes(),\n\t\t\t\t\tdt.getUTCSeconds(),\n\t\t\t\t\tdt.getUTCMilliseconds()\n\t\t\t\t);\n\t\t\t\treturn new Date(utc);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Coerce the value to an object.\n\t * @param value The value to coerce.\n\t * @throws TypeError If the value can not be coerced.\n\t * @returns The value if it can be coerced.\n\t */\n\tpublic static object<T = unknown>(value: unknown): T | undefined {\n\t\tif (Is.undefined(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.object<T>(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.stringValue(value)) {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(value) as T;\n\t\t\t} catch {}\n\t\t}\n\t}\n\n\t/**\n\t * Coerce the value to a Uint8Array.\n\t * @param value The value to coerce.\n\t * @throws TypeError If the value can not be coerced.\n\t * @returns The value if it can be coerced.\n\t */\n\tpublic static uint8Array(value: unknown): Uint8Array | undefined {\n\t\tif (Is.undefined(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (Is.string(value)) {\n\t\t\tif (Is.stringHex(value.toLowerCase(), true)) {\n\t\t\t\treturn Converter.hexToBytes(value.toLowerCase());\n\t\t\t}\n\t\t\tif (Is.stringBase64(value)) {\n\t\t\t\treturn Converter.base64ToBytes(value);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Coerces a value based on the coercion type.\n\t * @param value The value to coerce.\n\t * @param type The coercion type to perform.\n\t * @returns The coerced value.\n\t */\n\tpublic static byType(value: unknown, type?: CoerceType): unknown {\n\t\tswitch (type) {\n\t\t\tcase CoerceType.String:\n\t\t\t\treturn Coerce.string(value);\n\t\t\tcase CoerceType.Number:\n\t\t\t\treturn Coerce.number(value);\n\t\t\tcase CoerceType.Integer:\n\t\t\t\treturn Coerce.integer(value);\n\t\t\tcase CoerceType.BigInt:\n\t\t\t\treturn Coerce.bigint(value);\n\t\t\tcase CoerceType.Boolean:\n\t\t\t\treturn Coerce.boolean(value);\n\t\t\tcase CoerceType.Date:\n\t\t\t\treturn Coerce.date(value);\n\t\t\tcase CoerceType.DateTime:\n\t\t\t\treturn Coerce.dateTime(value);\n\t\t\tcase CoerceType.Time:\n\t\t\t\treturn Coerce.time(value);\n\t\t\tcase CoerceType.Object:\n\t\t\t\treturn Coerce.object(value);\n\t\t\tcase CoerceType.Uint8Array:\n\t\t\t\treturn Coerce.uint8Array(value);\n\t\t\tdefault:\n\t\t\t\treturn value;\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Guards } from "./guards.js";
|
|
2
|
+
import { CompressionType } from "../models/compressionType.js";
|
|
3
|
+
/**
|
|
4
|
+
* A class to handle compression.
|
|
5
|
+
*/
|
|
6
|
+
export class Compression {
|
|
7
|
+
/**
|
|
8
|
+
* Runtime name for the class.
|
|
9
|
+
*/
|
|
10
|
+
static CLASS_NAME = "Compression";
|
|
11
|
+
/**
|
|
12
|
+
* Compress bytes using GZIP.
|
|
13
|
+
* @param bytes The bytes to compress.
|
|
14
|
+
* @param type The type of compression to use.
|
|
15
|
+
* @returns The compressed bytes.
|
|
16
|
+
*/
|
|
17
|
+
static async compress(bytes, type) {
|
|
18
|
+
Guards.uint8Array(Compression.CLASS_NAME, "bytes", bytes);
|
|
19
|
+
Guards.arrayOneOf(Compression.CLASS_NAME, "type", type, Object.values(CompressionType));
|
|
20
|
+
const blob = new Blob([new Uint8Array(bytes)]);
|
|
21
|
+
const compressionStream = new CompressionStream(type);
|
|
22
|
+
const compressionPipe = blob.stream().pipeThrough(compressionStream);
|
|
23
|
+
const compressedBlob = await new Response(compressionPipe).blob();
|
|
24
|
+
const compressedBytes = new Uint8Array(await compressedBlob.arrayBuffer());
|
|
25
|
+
// GZIP header contains a byte which specifies the OS the
|
|
26
|
+
// compression was performed on. We set this to 3 (Unix) to ensure
|
|
27
|
+
// that we produce consistent results.
|
|
28
|
+
if (type === CompressionType.Gzip && compressedBytes.length >= 10) {
|
|
29
|
+
compressedBytes[9] = 3;
|
|
30
|
+
}
|
|
31
|
+
return compressedBytes;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Decompress a gzipped compressed byte array.
|
|
35
|
+
* @param compressedBytes The compressed bytes.
|
|
36
|
+
* @param type The type of compression to use.
|
|
37
|
+
* @returns The decompressed bytes.
|
|
38
|
+
*/
|
|
39
|
+
static async decompress(compressedBytes, type) {
|
|
40
|
+
Guards.uint8Array(Compression.CLASS_NAME, "compressedBytes", compressedBytes);
|
|
41
|
+
Guards.arrayOneOf(Compression.CLASS_NAME, "type", type, Object.values(CompressionType));
|
|
42
|
+
const blob = new Blob([new Uint8Array(compressedBytes)]);
|
|
43
|
+
const decompressionStream = new DecompressionStream(type);
|
|
44
|
+
const decompressionPipe = blob.stream().pipeThrough(decompressionStream);
|
|
45
|
+
const decompressedBlob = await new Response(decompressionPipe).blob();
|
|
46
|
+
return new Uint8Array(await decompressedBlob.bytes());
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=compression.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compression.js","sourceRoot":"","sources":["../../../src/utils/compression.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D;;GAEG;AACH,MAAM,OAAO,WAAW;IACvB;;OAEG;IACI,MAAM,CAAU,UAAU,iBAAiC;IAElE;;;;;OAKG;IACI,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAiB,EAAE,IAAqB;QACpE,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,UAAU,WAAiB,KAAK,CAAC,CAAC;QAChE,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,UAAU,UAAgB,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;QAE9F,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;QACrE,MAAM,cAAc,GAAG,MAAM,IAAI,QAAQ,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAAC;QAElE,MAAM,eAAe,GAAG,IAAI,UAAU,CAAC,MAAM,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC;QAE3E,yDAAyD;QACzD,kEAAkE;QAClE,sCAAsC;QACtC,IAAI,IAAI,KAAK,eAAe,CAAC,IAAI,IAAI,eAAe,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACnE,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;QAED,OAAO,eAAe,CAAC;IACxB,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,KAAK,CAAC,UAAU,CAC7B,eAA2B,EAC3B,IAAqB;QAErB,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,UAAU,qBAA2B,eAAe,CAAC,CAAC;QACpF,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,UAAU,UAAgB,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;QAE9F,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,mBAAmB,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC;QACzE,MAAM,gBAAgB,GAAG,MAAM,IAAI,QAAQ,CAAC,iBAAiB,CAAC,CAAC,IAAI,EAAE,CAAC;QAEtE,OAAO,IAAI,UAAU,CAAC,MAAM,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC;IACvD,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { nameof } from \"@twin.org/nameof\";\nimport { Guards } from \"./guards.js\";\nimport { CompressionType } from \"../models/compressionType.js\";\n\n/**\n * A class to handle compression.\n */\nexport class Compression {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<Compression>();\n\n\t/**\n\t * Compress bytes using GZIP.\n\t * @param bytes The bytes to compress.\n\t * @param type The type of compression to use.\n\t * @returns The compressed bytes.\n\t */\n\tpublic static async compress(bytes: Uint8Array, type: CompressionType): Promise<Uint8Array> {\n\t\tGuards.uint8Array(Compression.CLASS_NAME, nameof(bytes), bytes);\n\t\tGuards.arrayOneOf(Compression.CLASS_NAME, nameof(type), type, Object.values(CompressionType));\n\n\t\tconst blob = new Blob([new Uint8Array(bytes)]);\n\t\tconst compressionStream = new CompressionStream(type);\n\t\tconst compressionPipe = blob.stream().pipeThrough(compressionStream);\n\t\tconst compressedBlob = await new Response(compressionPipe).blob();\n\n\t\tconst compressedBytes = new Uint8Array(await compressedBlob.arrayBuffer());\n\n\t\t// GZIP header contains a byte which specifies the OS the\n\t\t// compression was performed on. We set this to 3 (Unix) to ensure\n\t\t// that we produce consistent results.\n\t\tif (type === CompressionType.Gzip && compressedBytes.length >= 10) {\n\t\t\tcompressedBytes[9] = 3;\n\t\t}\n\n\t\treturn compressedBytes;\n\t}\n\n\t/**\n\t * Decompress a gzipped compressed byte array.\n\t * @param compressedBytes The compressed bytes.\n\t * @param type The type of compression to use.\n\t * @returns The decompressed bytes.\n\t */\n\tpublic static async decompress(\n\t\tcompressedBytes: Uint8Array,\n\t\ttype: CompressionType\n\t): Promise<Uint8Array> {\n\t\tGuards.uint8Array(Compression.CLASS_NAME, nameof(compressedBytes), compressedBytes);\n\t\tGuards.arrayOneOf(Compression.CLASS_NAME, nameof(type), type, Object.values(CompressionType));\n\n\t\tconst blob = new Blob([new Uint8Array(compressedBytes)]);\n\t\tconst decompressionStream = new DecompressionStream(type);\n\t\tconst decompressionPipe = blob.stream().pipeThrough(decompressionStream);\n\t\tconst decompressedBlob = await new Response(decompressionPipe).blob();\n\n\t\treturn new Uint8Array(await decompressedBlob.bytes());\n\t}\n}\n"]}
|