@wener/common 2.0.5 → 2.0.6
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/ai/qwen3vl/index.js +1 -1
- package/lib/ai/qwen3vl/utils.js +15 -15
- package/lib/ai/vision/DocLayoutElementTypeSchema.js +22 -22
- package/lib/ai/vision/ImageAnnotationSchema.js +63 -47
- package/lib/ai/vision/index.js +2 -2
- package/lib/ai/vision/resolveImageAnnotation.js +81 -95
- package/lib/cn/ChineseResidentIdNo.js +55 -41
- package/lib/cn/ChineseResidentIdNo.mod.js +6 -1
- package/lib/cn/ChineseResidentIdNo.test.js +22 -21
- package/lib/cn/DivisionCode.js +220 -235
- package/lib/cn/DivisionCode.mod.js +6 -1
- package/lib/cn/DivisionCode.test.js +92 -121
- package/lib/cn/Mod11.js +18 -37
- package/lib/cn/Mod31.js +23 -41
- package/lib/cn/UnifiedSocialCreditCode.js +143 -137
- package/lib/cn/UnifiedSocialCreditCode.mod.js +6 -1
- package/lib/cn/UnifiedSocialCreditCode.test.js +21 -15
- package/lib/cn/formatChineseAmount.js +46 -71
- package/lib/cn/index.js +6 -6
- package/lib/cn/mod.js +5 -3
- package/lib/cn/parseChineseNumber.js +81 -85
- package/lib/cn/parseChineseNumber.test.js +183 -261
- package/lib/cn/pinyin/cartesianProduct.js +19 -19
- package/lib/cn/pinyin/cartesianProduct.test.js +78 -178
- package/lib/cn/pinyin/loader.js +13 -11
- package/lib/cn/pinyin/preload.js +2 -1
- package/lib/cn/pinyin/toPinyin.test.js +149 -161
- package/lib/cn/pinyin/toPinyinPure.js +28 -23
- package/lib/cn/pinyin/transform.js +11 -11
- package/lib/cn/types.d.js +2 -2
- package/lib/consola/createStandardConsolaReporter.js +14 -15
- package/lib/consola/formatLogObject.js +149 -133
- package/lib/consola/formatLogObject.test.js +167 -178
- package/lib/consola/index.js +2 -2
- package/lib/data/formatSort.js +14 -12
- package/lib/data/formatSort.test.js +33 -33
- package/lib/data/index.js +3 -3
- package/lib/data/maybeNumber.js +23 -23
- package/lib/data/parseSort.js +75 -68
- package/lib/data/parseSort.test.js +196 -187
- package/lib/data/resolvePagination.js +38 -39
- package/lib/data/resolvePagination.test.js +228 -218
- package/lib/data/types.d.js +2 -2
- package/lib/dayjs/dayjs.js +20 -20
- package/lib/dayjs/formatDuration.js +56 -56
- package/lib/dayjs/formatDuration.test.js +63 -77
- package/lib/dayjs/index.js +4 -4
- package/lib/dayjs/parseDuration.js +21 -26
- package/lib/dayjs/parseRelativeTime.js +65 -66
- package/lib/dayjs/parseRelativeTime.test.js +227 -243
- package/lib/dayjs/resolveRelativeTime.js +73 -72
- package/lib/dayjs/resolveRelativeTime.test.js +296 -307
- package/lib/decimal/index.js +1 -1
- package/lib/decimal/parseDecimal.js +12 -12
- package/lib/drain3/Drain.js +303 -338
- package/lib/drain3/LogCluster.js +25 -25
- package/lib/drain3/Node.js +24 -24
- package/lib/drain3/TemplateMiner.js +197 -196
- package/lib/drain3/index.js +5 -5
- package/lib/drain3/persistence/FilePersistence.js +19 -19
- package/lib/drain3/persistence/MemoryPersistence.js +8 -8
- package/lib/drain3/persistence/PersistenceHandler.js +2 -2
- package/lib/drain3/types.js +2 -2
- package/lib/emittery/emitter.js +7 -7
- package/lib/emittery/index.js +1 -1
- package/lib/foundation/schema/SexType.js +15 -12
- package/lib/foundation/schema/index.js +1 -1
- package/lib/foundation/schema/parseSexType.js +15 -16
- package/lib/foundation/schema/types.js +8 -6
- package/lib/fs/FileSystemError.js +18 -18
- package/lib/fs/IFileSystem.d.js +2 -2
- package/lib/fs/MemoryFileSystem.test.js +172 -181
- package/lib/fs/createBrowserFileSystem.js +222 -235
- package/lib/fs/createMemoryFileSystem.js +472 -510
- package/lib/fs/createSandboxFileSystem.js +102 -101
- package/lib/fs/createWebDavFileSystem.js +162 -149
- package/lib/fs/createWebFileSystem.js +197 -220
- package/lib/fs/findMimeType.js +14 -14
- package/lib/fs/index.js +7 -7
- package/lib/fs/minio/createMinioFileSystem.js +959 -956
- package/lib/fs/minio/index.js +1 -1
- package/lib/fs/orpc/FileSystemContract.js +57 -57
- package/lib/fs/orpc/createContractClientFileSystem.js +88 -88
- package/lib/fs/orpc/index.js +2 -2
- package/lib/fs/orpc/server/createFileSystemContractImpl.js +62 -60
- package/lib/fs/orpc/server/index.js +1 -1
- package/lib/fs/s3/createS3MiniFileSystem.js +756 -737
- package/lib/fs/s3/index.js +1 -1
- package/lib/fs/s3/s3mini.test.js +524 -553
- package/lib/fs/scandir.js +56 -56
- package/lib/fs/server/createDatabaseFileSystem.js +834 -741
- package/lib/fs/server/createNodeFileSystem.js +407 -405
- package/lib/fs/server/dbfs.test.js +201 -214
- package/lib/fs/server/index.js +1 -1
- package/lib/fs/server/loadTestDatabase.js +40 -43
- package/lib/fs/tests/runFileSystemTest.js +352 -316
- package/lib/fs/types.js +17 -20
- package/lib/fs/utils/getFileUrl.js +24 -30
- package/lib/fs/utils.js +17 -17
- package/lib/fs/webdav/index.js +1 -1
- package/lib/index.js +2 -2
- package/lib/jsonschema/JsonSchema.js +216 -155
- package/lib/jsonschema/JsonSchema.test.js +123 -124
- package/lib/jsonschema/forEachJsonSchema.js +41 -41
- package/lib/jsonschema/index.js +2 -2
- package/lib/jsonschema/types.d.js +2 -2
- package/lib/meta/defineFileType.js +32 -38
- package/lib/meta/defineInit.js +39 -35
- package/lib/meta/defineMetadata.js +37 -34
- package/lib/meta/defineMetadata.test.js +13 -12
- package/lib/meta/index.js +3 -3
- package/lib/orpc/createOpenApiContractClient.js +26 -24
- package/lib/orpc/createRpcContractClient.js +37 -31
- package/lib/orpc/index.js +2 -2
- package/lib/orpc/resolveLinkPlugins.js +25 -25
- package/lib/password/PHC.js +187 -189
- package/lib/password/PHC.test.js +517 -535
- package/lib/password/Password.js +85 -80
- package/lib/password/Password.test.js +330 -364
- package/lib/password/createArgon2PasswordAlgorithm.js +50 -51
- package/lib/password/createBase64PasswordAlgorithm.js +11 -11
- package/lib/password/createBcryptPasswordAlgorithm.js +20 -18
- package/lib/password/createPBKDF2PasswordAlgorithm.js +65 -52
- package/lib/password/createScryptPasswordAlgorithm.js +74 -63
- package/lib/password/index.js +5 -5
- package/lib/password/server/index.js +1 -1
- package/lib/resource/Identifiable.js +2 -2
- package/lib/resource/ListQuery.js +42 -42
- package/lib/resource/getTitleOfResource.js +5 -5
- package/lib/resource/index.js +2 -2
- package/lib/resource/schema/AnyResourceSchema.js +91 -89
- package/lib/resource/schema/BaseResourceSchema.js +26 -26
- package/lib/resource/schema/ResourceActionType.js +117 -115
- package/lib/resource/schema/ResourceStatus.js +94 -92
- package/lib/resource/schema/ResourceType.js +25 -23
- package/lib/resource/schema/index.js +5 -5
- package/lib/resource/schema/types.js +86 -55
- package/lib/resource/schema/types.test.js +16 -13
- package/lib/s3/formatS3Url.js +60 -60
- package/lib/s3/formatS3Url.test.js +238 -261
- package/lib/s3/index.js +2 -2
- package/lib/s3/parseS3Url.js +61 -60
- package/lib/s3/parseS3Url.test.js +270 -269
- package/lib/schema/SchemaRegistry.js +41 -42
- package/lib/schema/SchemaRegistry.mod.js +1 -1
- package/lib/schema/TypeSchema.d.js +2 -2
- package/lib/schema/createSchemaData.js +113 -67
- package/lib/schema/findJsonSchemaByPath.js +28 -23
- package/lib/schema/formatZodError.js +112 -131
- package/lib/schema/formatZodError.test.js +192 -195
- package/lib/schema/getSchemaCache.js +7 -7
- package/lib/schema/getSchemaOptions.js +17 -16
- package/lib/schema/index.js +6 -6
- package/lib/schema/toJsonSchema.js +195 -189
- package/lib/schema/toJsonSchema.test.js +34 -26
- package/lib/schema/validate.js +105 -96
- package/lib/tools/generateSchema.js +40 -40
- package/lib/tools/renderJsonSchemaToMarkdownDoc.js +74 -74
- package/lib/utils/buildBaseUrl.js +8 -8
- package/lib/utils/buildRedactorFormSchema.js +54 -53
- package/lib/utils/getEstimateProcessTime.js +24 -19
- package/lib/utils/index.js +3 -3
- package/lib/utils/resolveFeatureOptions.js +9 -9
- package/package.json +14 -14
- package/src/ai/vision/index.ts +2 -2
- package/src/cn/index.ts +1 -2
- package/src/consola/index.ts +1 -1
- package/src/data/index.ts +3 -4
- package/src/data/resolvePagination.ts +2 -2
- package/src/dayjs/formatDuration.ts +8 -9
- package/src/dayjs/index.ts +1 -1
- package/src/dayjs/parseRelativeTime.ts +1 -1
- package/src/dayjs/resolveRelativeTime.ts +1 -1
- package/src/drain3/Drain.test.ts +2 -2
- package/src/drain3/index.ts +2 -4
- package/src/fs/createWebDavFileSystem.ts +2 -7
- package/src/fs/createWebFileSystem.ts +1 -1
- package/src/fs/index.ts +4 -4
- package/src/fs/minio/createMinioFileSystem.ts +2 -2
- package/src/fs/minio/index.ts +1 -1
- package/src/fs/s3/createS3MiniFileSystem.ts +1 -1
- package/src/fs/server/createDatabaseFileSystem.ts +84 -120
- package/src/fs/server/dbfs.test.ts +14 -10
- package/src/fs/server/index.ts +1 -0
- package/src/fs/server/loadTestDatabase.ts +8 -119
- package/src/jsonschema/index.ts +1 -1
- package/src/meta/index.ts +2 -3
- package/src/orm/createSqliteDialect.ts +17 -0
- package/src/orm/index.ts +1 -0
- package/src/orpc/createOpenApiContractClient.ts +1 -1
- package/src/orpc/index.ts +1 -1
- package/src/password/createArgon2PasswordAlgorithm.ts +1 -1
- package/src/password/index.ts +2 -2
- package/src/resource/index.ts +3 -3
- package/src/resource/schema/index.ts +4 -4
- package/src/s3/index.ts +1 -1
- package/src/schema/SchemaRegistry.ts +1 -1
- package/src/schema/createSchemaData.ts +1 -1
- package/src/schema/findJsonSchemaByPath.ts +1 -1
- package/src/schema/index.ts +5 -5
- package/src/schema/validate.ts +1 -1
- package/src/utils/buildRedactorFormSchema.ts +1 -1
- package/src/utils/formatNumber.ts +18 -0
- package/src/utils/formatPercent.ts +17 -0
- package/src/utils/index.ts +3 -3
- package/src/utils/resolveFeatureOptions.ts +1 -1
|
@@ -1,27 +1,29 @@
|
|
|
1
|
-
import { createORPCClient } from
|
|
2
|
-
import { OpenAPILink } from
|
|
3
|
-
import { buildBaseUrl } from
|
|
4
|
-
import { resolveLinkPlugins } from
|
|
1
|
+
import { createORPCClient } from '@orpc/client';
|
|
2
|
+
import { OpenAPILink } from '@orpc/openapi-client/fetch';
|
|
3
|
+
import { buildBaseUrl } from '../utils/buildBaseUrl.js';
|
|
4
|
+
import { resolveLinkPlugins } from './resolveLinkPlugins.js';
|
|
5
5
|
export function createOpenApiContractClient(contract, options) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
6
|
+
let { url, baseUrl, apiKey, getApiKey, getHeaders } = options;
|
|
7
|
+
const baseHeaders = new Headers(options.headers);
|
|
8
|
+
if (apiKey) {
|
|
9
|
+
baseHeaders.set('Authorization', `Bearer ${apiKey}`);
|
|
10
|
+
}
|
|
11
|
+
url = buildBaseUrl(url, baseUrl);
|
|
12
|
+
return createORPCClient(
|
|
13
|
+
new OpenAPILink(contract, {
|
|
14
|
+
url,
|
|
15
|
+
headers: () => {
|
|
16
|
+
let headers = new Headers(baseHeaders);
|
|
17
|
+
let accessToken = getApiKey?.();
|
|
18
|
+
if (accessToken) {
|
|
19
|
+
headers.set('Authorization', `Bearer ${accessToken}`);
|
|
20
|
+
}
|
|
21
|
+
headers = getHeaders?.(headers) ?? headers;
|
|
22
|
+
return headers;
|
|
23
|
+
},
|
|
24
|
+
plugins: resolveLinkPlugins(options),
|
|
25
|
+
fetch: options.fetch,
|
|
26
|
+
}),
|
|
27
|
+
);
|
|
26
28
|
}
|
|
27
29
|
//# sourceMappingURL=createOpenApiContractClient.js.map
|
|
@@ -1,34 +1,40 @@
|
|
|
1
|
-
import { createORPCClient } from
|
|
2
|
-
import { RPCLink } from
|
|
3
|
-
import { buildBaseUrl } from
|
|
4
|
-
import { resolveLinkPlugins } from
|
|
1
|
+
import { createORPCClient } from '@orpc/client';
|
|
2
|
+
import { RPCLink } from '@orpc/client/fetch';
|
|
3
|
+
import { buildBaseUrl } from '../utils/buildBaseUrl.js';
|
|
4
|
+
import { resolveLinkPlugins } from './resolveLinkPlugins.js';
|
|
5
5
|
export function createRpcContractClient(options = {}) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
6
|
+
let {
|
|
7
|
+
url = '/api/rpc',
|
|
8
|
+
baseUrl = globalThis.location?.origin || 'http://localhost',
|
|
9
|
+
apiKey,
|
|
10
|
+
getApiKey,
|
|
11
|
+
getHeaders,
|
|
12
|
+
} = options;
|
|
13
|
+
url = buildBaseUrl(url, baseUrl);
|
|
14
|
+
const baseHeaders = new Headers(options.headers);
|
|
15
|
+
if (apiKey) {
|
|
16
|
+
baseHeaders.set('Authorization', `Bearer ${apiKey}`);
|
|
17
|
+
}
|
|
18
|
+
const plugins = resolveLinkPlugins({
|
|
19
|
+
dedup: true,
|
|
20
|
+
batch: true,
|
|
21
|
+
...options,
|
|
22
|
+
});
|
|
23
|
+
const link = new RPCLink({
|
|
24
|
+
url,
|
|
25
|
+
headers: () => {
|
|
26
|
+
let headers = new Headers(baseHeaders);
|
|
27
|
+
let accessToken = getApiKey?.();
|
|
28
|
+
if (accessToken) {
|
|
29
|
+
headers.set('Authorization', `Bearer ${accessToken}`);
|
|
30
|
+
}
|
|
31
|
+
headers = getHeaders?.(headers) ?? headers;
|
|
32
|
+
return headers;
|
|
33
|
+
},
|
|
34
|
+
fetch: options.fetch,
|
|
35
|
+
plugins,
|
|
36
|
+
});
|
|
37
|
+
const client = createORPCClient(link);
|
|
38
|
+
return client;
|
|
33
39
|
}
|
|
34
40
|
//# sourceMappingURL=createRpcContractClient.js.map
|
package/lib/orpc/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
1
|
+
export { createOpenApiContractClient } from './createOpenApiContractClient.js';
|
|
2
|
+
export { createRpcContractClient } from './createRpcContractClient.js';
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { BatchLinkPlugin, DedupeRequestsPlugin } from
|
|
2
|
-
import { resolveFeatureOptions } from
|
|
1
|
+
import { BatchLinkPlugin, DedupeRequestsPlugin } from '@orpc/client/plugins';
|
|
2
|
+
import { resolveFeatureOptions } from '../utils/resolveFeatureOptions.js';
|
|
3
3
|
export function resolveLinkPlugins({ plugins = [], dedup, batch }) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
4
|
+
batch = resolveFeatureOptions(batch, {
|
|
5
|
+
groups: [
|
|
6
|
+
{
|
|
7
|
+
condition: () => true,
|
|
8
|
+
context: {},
|
|
9
|
+
},
|
|
10
|
+
],
|
|
11
|
+
});
|
|
12
|
+
if (batch) {
|
|
13
|
+
plugins.push(new BatchLinkPlugin(batch));
|
|
14
|
+
}
|
|
15
|
+
dedup = resolveFeatureOptions(dedup, {
|
|
16
|
+
groups: [
|
|
17
|
+
{
|
|
18
|
+
condition: () => true,
|
|
19
|
+
context: {},
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
});
|
|
23
|
+
if (dedup) {
|
|
24
|
+
plugins.push(new DedupeRequestsPlugin(dedup));
|
|
25
|
+
}
|
|
26
|
+
return plugins;
|
|
27
27
|
}
|
|
28
28
|
//# sourceMappingURL=resolveLinkPlugins.js.map
|
package/lib/password/PHC.js
CHANGED
|
@@ -1,195 +1,193 @@
|
|
|
1
|
-
import { ArrayBuffers } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
1
|
+
import { ArrayBuffers } from '@wener/utils';
|
|
2
|
+
|
|
3
|
+
((PHC) => {
|
|
4
|
+
// https://github.com/simonepri/phc-format/blob/master/index.js
|
|
5
|
+
const idRegex = /^[a-z0-9-]{1,32}$/;
|
|
6
|
+
const nameRegex = /^[a-z0-9-]{1,32}$/;
|
|
7
|
+
const valueRegex = /^[a-zA-Z0-9/+.-]+$/;
|
|
8
|
+
const b64Regex = /^([a-zA-Z0-9/+.-]+|)$/;
|
|
9
|
+
const decimalRegex = /^((-)?[1-9]\d*|0)$/;
|
|
10
|
+
const versionRegex = /^v=(\d+)$/;
|
|
11
|
+
const fromBase64 = ArrayBuffers.fromBase64;
|
|
12
|
+
const toBase64 = ArrayBuffers.toBase64;
|
|
13
|
+
const isBuffer = (v) => {
|
|
14
|
+
return v instanceof Uint8Array;
|
|
15
|
+
};
|
|
16
|
+
function objToKeyVal(obj) {
|
|
17
|
+
return objectKeys(obj)
|
|
18
|
+
.map((k) => [k, obj[k]].join('='))
|
|
19
|
+
.join(',');
|
|
20
|
+
}
|
|
21
|
+
function keyValtoObj(str) {
|
|
22
|
+
const obj = {};
|
|
23
|
+
str.split(',').forEach((ps) => {
|
|
24
|
+
const pss = ps.split('=');
|
|
25
|
+
if (pss.length < 2) {
|
|
26
|
+
throw new TypeError(`params must be in the format name=value`);
|
|
27
|
+
}
|
|
28
|
+
const key = pss.shift();
|
|
29
|
+
if (key !== undefined) {
|
|
30
|
+
obj[key] = pss.join('=');
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
return obj;
|
|
34
|
+
}
|
|
35
|
+
function objectKeys(object) {
|
|
36
|
+
return Object.keys(object);
|
|
37
|
+
}
|
|
38
|
+
function objectValues(object) {
|
|
39
|
+
if (typeof Object.values === 'function') return Object.values(object);
|
|
40
|
+
return objectKeys(object).map((k) => object[k]);
|
|
41
|
+
}
|
|
42
|
+
function serialize(opts) {
|
|
43
|
+
const fields = [''];
|
|
44
|
+
if (typeof opts !== 'object' || opts === null) {
|
|
45
|
+
throw new TypeError('opts must be an object');
|
|
46
|
+
}
|
|
47
|
+
// Identifier Validation
|
|
48
|
+
if (typeof opts.id !== 'string') {
|
|
49
|
+
throw new TypeError('id must be a string');
|
|
50
|
+
}
|
|
51
|
+
if (!idRegex.test(opts.id)) {
|
|
52
|
+
throw new TypeError(`id must satisfy ${idRegex}`);
|
|
53
|
+
}
|
|
54
|
+
fields.push(opts.id);
|
|
55
|
+
if (typeof opts.version !== 'undefined') {
|
|
56
|
+
if (typeof opts.version !== 'number' || opts.version < 0 || !Number.isInteger(opts.version)) {
|
|
57
|
+
throw new TypeError('version must be a positive integer number');
|
|
58
|
+
}
|
|
59
|
+
fields.push(`v=${opts.version}`);
|
|
60
|
+
}
|
|
61
|
+
// Parameters Validation
|
|
62
|
+
if (typeof opts.params !== 'undefined') {
|
|
63
|
+
if (typeof opts.params !== 'object' || opts.params === null) {
|
|
64
|
+
throw new TypeError('params must be an object');
|
|
65
|
+
}
|
|
66
|
+
const pk = objectKeys(opts.params);
|
|
67
|
+
if (!pk.every((p) => nameRegex.test(p.toString()))) {
|
|
68
|
+
throw new TypeError(`params names must satisfy ${nameRegex}`);
|
|
69
|
+
}
|
|
70
|
+
// Convert Numbers into Numeric Strings and Buffers into B64 encoded strings.
|
|
71
|
+
pk.forEach((k) => {
|
|
72
|
+
const value = opts.params?.[k];
|
|
73
|
+
if (typeof value === 'number') {
|
|
74
|
+
opts.params[k] = value.toString();
|
|
75
|
+
} else if (value instanceof Uint8Array) {
|
|
76
|
+
opts.params[k] = toBase64(value).split('=')[0];
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
const pv = objectValues(opts.params);
|
|
80
|
+
if (!pv.every((v) => typeof v === 'string')) {
|
|
81
|
+
throw new TypeError('params values must be strings');
|
|
82
|
+
}
|
|
83
|
+
if (!pv.every((v) => valueRegex.test(v))) {
|
|
84
|
+
throw new TypeError(`params values must satisfy ${valueRegex}`);
|
|
85
|
+
}
|
|
86
|
+
const strpar = objToKeyVal(opts.params);
|
|
87
|
+
fields.push(strpar);
|
|
88
|
+
}
|
|
89
|
+
if (typeof opts.salt !== 'undefined') {
|
|
90
|
+
// Salt Validation
|
|
91
|
+
if (!isBuffer(opts.salt)) {
|
|
92
|
+
throw new TypeError('salt must be a Buffer');
|
|
93
|
+
}
|
|
94
|
+
fields.push(toBase64(opts.salt).split('=')[0]);
|
|
95
|
+
if (typeof opts.hash !== 'undefined') {
|
|
96
|
+
// Hash Validation
|
|
97
|
+
if (!isBuffer(opts.hash)) {
|
|
98
|
+
throw new TypeError('hash must be a Buffer');
|
|
99
|
+
}
|
|
100
|
+
fields.push(toBase64(opts.hash).split('=')[0]);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Create the PHC formatted string
|
|
104
|
+
const phcstr = fields.join('$');
|
|
105
|
+
return phcstr;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
110
108
|
* Generates a PHC string using the data provided.
|
|
111
109
|
* @param {SerializeOptions} opts Object that holds the data needed to generate the PHC string.
|
|
112
110
|
* @return {string} The hash string adhering to the PHC format.
|
|
113
111
|
*/ PHC.serialize = serialize;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
112
|
+
function deserialize(phcstr) {
|
|
113
|
+
if (typeof phcstr !== 'string' || phcstr === '') {
|
|
114
|
+
throw new TypeError('pchstr must be a non-empty string');
|
|
115
|
+
}
|
|
116
|
+
if (phcstr[0] !== '$') {
|
|
117
|
+
throw new TypeError('pchstr must contain a $ as first char');
|
|
118
|
+
}
|
|
119
|
+
const fields = phcstr.split('$');
|
|
120
|
+
// Remove first empty $
|
|
121
|
+
fields.shift();
|
|
122
|
+
// Parse Fields
|
|
123
|
+
let maxf = 5;
|
|
124
|
+
if (!versionRegex.test(fields[1])) maxf--;
|
|
125
|
+
if (fields.length > maxf) {
|
|
126
|
+
throw new TypeError(`pchstr contains too many fileds: ${fields.length}/${maxf}`);
|
|
127
|
+
}
|
|
128
|
+
// Parse Identifier
|
|
129
|
+
const id = fields.shift();
|
|
130
|
+
if (!id || !idRegex.test(id)) {
|
|
131
|
+
throw new TypeError(`id must satisfy ${idRegex}`);
|
|
132
|
+
}
|
|
133
|
+
let version;
|
|
134
|
+
// Parse Version
|
|
135
|
+
if (fields[0] && versionRegex.test(fields[0])) {
|
|
136
|
+
const versionMatch = fields.shift()?.match(versionRegex);
|
|
137
|
+
version = versionMatch ? parseInt(versionMatch[1], 10) : undefined;
|
|
138
|
+
}
|
|
139
|
+
let hash;
|
|
140
|
+
let salt;
|
|
141
|
+
if (fields[fields.length - 1] && b64Regex.test(fields[fields.length - 1])) {
|
|
142
|
+
if (fields.length > 1 && b64Regex.test(fields[fields.length - 2])) {
|
|
143
|
+
// Parse Hash
|
|
144
|
+
const hashStr = fields.pop();
|
|
145
|
+
if (hashStr) hash = fromBase64(hashStr);
|
|
146
|
+
// Parse Salt
|
|
147
|
+
const saltStr = fields.pop();
|
|
148
|
+
if (saltStr !== undefined) salt = fromBase64(saltStr);
|
|
149
|
+
} else {
|
|
150
|
+
// Parse Salt
|
|
151
|
+
const saltStr = fields.pop();
|
|
152
|
+
if (saltStr !== undefined) salt = fromBase64(saltStr);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Parse Parameters
|
|
156
|
+
let params;
|
|
157
|
+
if (fields.length > 0) {
|
|
158
|
+
const parstr = fields.pop();
|
|
159
|
+
if (parstr) {
|
|
160
|
+
params = keyValtoObj(parstr);
|
|
161
|
+
if (!Object.keys(params).every((p) => nameRegex.test(p))) {
|
|
162
|
+
throw new TypeError(`params names must satisfy ${nameRegex}}`);
|
|
163
|
+
}
|
|
164
|
+
const pv = Object.values(params);
|
|
165
|
+
if (!pv.every((v) => valueRegex.test(String(v)))) {
|
|
166
|
+
throw new TypeError(`params values must satisfy ${valueRegex}`);
|
|
167
|
+
}
|
|
168
|
+
// Convert Decimal Strings into Numbers
|
|
169
|
+
Object.keys(params).forEach((k) => {
|
|
170
|
+
const value = params?.[k];
|
|
171
|
+
if (typeof value === 'string' && decimalRegex.test(value)) {
|
|
172
|
+
params[k] = parseInt(value, 10);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (fields.length > 0) {
|
|
178
|
+
throw new TypeError(`pchstr contains unrecognized fileds: ${fields}`);
|
|
179
|
+
}
|
|
180
|
+
// Build the output object
|
|
181
|
+
const phcobj = {
|
|
182
|
+
id,
|
|
183
|
+
};
|
|
184
|
+
if (version !== undefined) phcobj.version = version;
|
|
185
|
+
if (params) phcobj.params = params;
|
|
186
|
+
if (salt) phcobj.salt = salt;
|
|
187
|
+
if (hash) phcobj.hash = hash;
|
|
188
|
+
return phcobj;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
193
191
|
* Parses data from a PHC string.
|
|
194
192
|
* @param {string} phcstr A PHC string to parse.
|
|
195
193
|
* @return {DeserializeResult} The object containing the data parsed from the PHC string.
|
|
@@ -197,4 +195,4 @@ import { ArrayBuffers } from "@wener/utils";
|
|
|
197
195
|
})(PHC || (PHC = {}));
|
|
198
196
|
export var PHC;
|
|
199
197
|
|
|
200
|
-
//# sourceMappingURL=PHC.js.map
|
|
198
|
+
//# sourceMappingURL=PHC.js.map
|