@wener/common 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/lib/cn/DivisionCode.js.map +1 -1
  2. package/lib/cn/Mod11Checksum.js.map +1 -1
  3. package/lib/cn/Mod31Checksum.js.map +1 -1
  4. package/lib/cn/ResidentIdentityCardNumber.js.map +1 -1
  5. package/lib/cn/UnifiedSocialCreditCode.js.map +1 -1
  6. package/lib/cn/formatDate.js.map +1 -1
  7. package/lib/cn/parseSex.js.map +1 -1
  8. package/lib/cn/types.d.js.map +1 -1
  9. package/lib/consola/createStandardConsolaReporter.js +18 -0
  10. package/lib/consola/createStandardConsolaReporter.js.map +1 -0
  11. package/lib/consola/formatLogObject.js +125 -0
  12. package/lib/consola/formatLogObject.js.map +1 -0
  13. package/lib/consola/index.js +3 -0
  14. package/lib/consola/index.js.map +1 -0
  15. package/lib/data/formatSort.js +15 -0
  16. package/lib/data/formatSort.js.map +1 -0
  17. package/lib/data/index.js +4 -0
  18. package/lib/data/index.js.map +1 -0
  19. package/lib/data/maybeNumber.js +22 -0
  20. package/lib/data/maybeNumber.js.map +1 -0
  21. package/lib/data/parseSort.js +95 -0
  22. package/lib/data/parseSort.js.map +1 -0
  23. package/lib/data/resolvePagination.js +36 -0
  24. package/lib/data/resolvePagination.js.map +1 -0
  25. package/lib/data/types.d.js +3 -0
  26. package/lib/data/types.d.js.map +1 -0
  27. package/lib/index.js +6 -2
  28. package/lib/index.js.map +1 -1
  29. package/lib/jsonschema/JsonSchema.js +6 -6
  30. package/lib/jsonschema/JsonSchema.js.map +1 -1
  31. package/lib/jsonschema/types.d.js.map +1 -1
  32. package/lib/meta/defineFileType.js.map +1 -1
  33. package/lib/meta/defineInit.js.map +1 -1
  34. package/lib/meta/defineMetadata.js.map +1 -1
  35. package/lib/password/PHC.js +8 -8
  36. package/lib/password/PHC.js.map +1 -1
  37. package/lib/password/Password.js.map +1 -1
  38. package/lib/password/createArgon2PasswordAlgorithm.js.map +1 -1
  39. package/lib/password/createBase64PasswordAlgorithm.js.map +1 -1
  40. package/lib/password/createBcryptPasswordAlgorithm.js.map +1 -1
  41. package/lib/password/createPBKDF2PasswordAlgorithm.js.map +1 -1
  42. package/lib/password/createScryptPasswordAlgorithm.js.map +1 -1
  43. package/lib/search/AdvanceSearch.js.map +1 -1
  44. package/lib/search/formatAdvanceSearch.js.map +1 -1
  45. package/lib/search/optimizeAdvanceSearch.js.map +1 -1
  46. package/lib/search/parseAdvanceSearch.js.map +1 -1
  47. package/lib/search/parser.d.js.map +1 -1
  48. package/lib/search/types.d.js.map +1 -1
  49. package/lib/tools/generateSchema.js +43 -0
  50. package/lib/tools/generateSchema.js.map +1 -0
  51. package/lib/tools/renderJsonSchemaToMarkdownDoc.js.map +1 -1
  52. package/package.json +19 -5
  53. package/src/cn/DivisionCode.test.ts +38 -45
  54. package/src/cn/DivisionCode.ts +140 -184
  55. package/src/cn/Mod11Checksum.ts +17 -17
  56. package/src/cn/Mod31Checksum.ts +25 -25
  57. package/src/cn/ResidentIdentityCardNumber.test.ts +12 -16
  58. package/src/cn/ResidentIdentityCardNumber.ts +82 -82
  59. package/src/cn/UnifiedSocialCreditCode.test.ts +11 -11
  60. package/src/cn/UnifiedSocialCreditCode.ts +115 -120
  61. package/src/cn/__snapshots__/ResidentIdentityCardNumber.test.ts.snap +1 -1
  62. package/src/cn/formatDate.ts +10 -10
  63. package/src/cn/parseSex.ts +11 -25
  64. package/src/cn/types.d.ts +43 -43
  65. package/src/consola/createStandardConsolaReporter.ts +31 -0
  66. package/src/consola/formatLogObject.ts +171 -0
  67. package/src/consola/index.ts +2 -0
  68. package/src/data/formatSort.test.ts +13 -0
  69. package/src/data/formatSort.ts +18 -0
  70. package/src/data/index.ts +5 -0
  71. package/src/data/maybeNumber.ts +23 -0
  72. package/src/data/parseSort.test.ts +67 -0
  73. package/src/data/parseSort.ts +108 -0
  74. package/src/data/resolvePagination.test.ts +58 -0
  75. package/src/data/resolvePagination.ts +60 -0
  76. package/src/data/types.d.ts +33 -0
  77. package/src/index.ts +8 -2
  78. package/src/jsonschema/JsonSchema.test.ts +13 -22
  79. package/src/jsonschema/JsonSchema.ts +146 -178
  80. package/src/jsonschema/types.d.ts +151 -161
  81. package/src/meta/defineFileType.tsx +54 -54
  82. package/src/meta/defineInit.ts +32 -53
  83. package/src/meta/defineMetadata.test.ts +5 -7
  84. package/src/meta/defineMetadata.ts +28 -46
  85. package/src/password/PHC.test.ts +186 -277
  86. package/src/password/PHC.ts +243 -243
  87. package/src/password/Password.test.ts +38 -50
  88. package/src/password/Password.ts +73 -95
  89. package/src/password/createArgon2PasswordAlgorithm.ts +65 -69
  90. package/src/password/createBase64PasswordAlgorithm.ts +9 -9
  91. package/src/password/createBcryptPasswordAlgorithm.ts +20 -22
  92. package/src/password/createPBKDF2PasswordAlgorithm.ts +49 -61
  93. package/src/password/createScryptPasswordAlgorithm.ts +48 -59
  94. package/src/search/AdvanceSearch.test.ts +136 -143
  95. package/src/search/AdvanceSearch.ts +6 -6
  96. package/src/search/formatAdvanceSearch.ts +44 -53
  97. package/src/search/optimizeAdvanceSearch.ts +70 -83
  98. package/src/search/parseAdvanceSearch.ts +16 -19
  99. package/src/search/parser.d.ts +3 -3
  100. package/src/search/types.d.ts +28 -54
  101. package/src/tools/generateSchema.ts +39 -0
  102. package/src/tools/renderJsonSchemaToMarkdownDoc.ts +69 -69
  103. package/lib/normalizePagination.js +0 -14
  104. package/lib/normalizePagination.js.map +0 -1
  105. package/lib/parseSort.js +0 -106
  106. package/lib/parseSort.js.map +0 -1
  107. package/src/normalizePagination.ts +0 -25
  108. package/src/parseSort.test.ts +0 -42
  109. package/src/parseSort.ts +0 -133
@@ -1,247 +1,247 @@
1
1
  import { ArrayBuffers } from '@wener/utils';
2
2
 
3
3
  export namespace PHC {
4
- // https://github.com/simonepri/phc-format/blob/master/index.js
5
-
6
- const idRegex = /^[a-z0-9-]{1,32}$/;
7
- const nameRegex = /^[a-z0-9-]{1,32}$/;
8
- const valueRegex = /^[a-zA-Z0-9/+.-]+$/;
9
- const b64Regex = /^([a-zA-Z0-9/+.-]+|)$/;
10
- const decimalRegex = /^((-)?[1-9]\d*|0)$/;
11
- const versionRegex = /^v=(\d+)$/;
12
-
13
- const fromBase64 = ArrayBuffers.fromBase64;
14
- const toBase64 = ArrayBuffers.toBase64;
15
- const isBuffer = (v: any): v is Uint8Array => {
16
- return v instanceof Uint8Array;
17
- };
18
-
19
- function objToKeyVal(obj: Record<string, any>): string {
20
- return objectKeys(obj)
21
- .map((k) => [k, obj[k]].join('='))
22
- .join(',');
23
- }
24
-
25
- function keyValtoObj(str: string): Record<string, string> {
26
- const obj: Record<string, string> = {};
27
- str.split(',').forEach((ps) => {
28
- const pss = ps.split('=');
29
- if (pss.length < 2) {
30
- throw new TypeError(`params must be in the format name=value`);
31
- }
32
-
33
- const key = pss.shift();
34
- if (key !== undefined) {
35
- obj[key] = pss.join('=');
36
- }
37
- });
38
- return obj;
39
- }
40
-
41
- function objectKeys<T extends object>(object: T): Array<keyof T> {
42
- return Object.keys(object) as Array<keyof T>;
43
- }
44
-
45
- function objectValues<T extends object>(object: T): Array<T[keyof T]> {
46
- if (typeof Object.values === 'function') return Object.values(object);
47
- return objectKeys(object).map((k) => object[k]);
48
- }
49
-
50
- interface SerializeOptions {
51
- id: string;
52
- version?: number;
53
- params?: Record<string, string | number | Uint8Array>;
54
- salt?: Uint8Array;
55
- hash?: Uint8Array;
56
- }
57
-
58
- /**
59
- * Generates a PHC string using the data provided.
60
- * @param {SerializeOptions} opts Object that holds the data needed to generate the PHC string.
61
- * @return {string} The hash string adhering to the PHC format.
62
- */
63
- export function serialize(opts: SerializeOptions): string {
64
- const fields: string[] = [''];
65
-
66
- if (typeof opts !== 'object' || opts === null) {
67
- throw new TypeError('opts must be an object');
68
- }
69
-
70
- // Identifier Validation
71
- if (typeof opts.id !== 'string') {
72
- throw new TypeError('id must be a string');
73
- }
74
-
75
- if (!idRegex.test(opts.id)) {
76
- throw new TypeError(`id must satisfy ${idRegex}`);
77
- }
78
-
79
- fields.push(opts.id);
80
-
81
- if (typeof opts.version !== 'undefined') {
82
- if (typeof opts.version !== 'number' || opts.version < 0 || !Number.isInteger(opts.version)) {
83
- throw new TypeError('version must be a positive integer number');
84
- }
85
-
86
- fields.push(`v=${opts.version}`);
87
- }
88
-
89
- // Parameters Validation
90
- if (typeof opts.params !== 'undefined') {
91
- if (typeof opts.params !== 'object' || opts.params === null) {
92
- throw new TypeError('params must be an object');
93
- }
94
-
95
- const pk = objectKeys(opts.params);
96
- if (!pk.every((p) => nameRegex.test(p.toString()))) {
97
- throw new TypeError(`params names must satisfy ${nameRegex}`);
98
- }
99
-
100
- // Convert Numbers into Numeric Strings and Buffers into B64 encoded strings.
101
- pk.forEach((k) => {
102
- const value = opts.params![k];
103
- if (typeof value === 'number') {
104
- opts.params![k] = value.toString();
105
- } else if (value instanceof Uint8Array) {
106
- opts.params![k] = toBase64(value).split('=')[0];
107
- }
108
- });
109
- const pv = objectValues(opts.params);
110
- if (!pv.every((v) => typeof v === 'string')) {
111
- throw new TypeError('params values must be strings');
112
- }
113
-
114
- if (!pv.every((v) => valueRegex.test(v))) {
115
- throw new TypeError(`params values must satisfy ${valueRegex}`);
116
- }
117
-
118
- const strpar = objToKeyVal(opts.params as Record<string, string>);
119
- fields.push(strpar);
120
- }
121
-
122
- if (typeof opts.salt !== 'undefined') {
123
- // Salt Validation
124
- if (!isBuffer(opts.salt)) {
125
- throw new TypeError('salt must be a Buffer');
126
- }
127
-
128
- fields.push(toBase64(opts.salt).split('=')[0]);
129
-
130
- if (typeof opts.hash !== 'undefined') {
131
- // Hash Validation
132
- if (!isBuffer(opts.hash)) {
133
- throw new TypeError('hash must be a Buffer');
134
- }
135
-
136
- fields.push(toBase64(opts.hash).split('=')[0]);
137
- }
138
- }
139
-
140
- // Create the PHC formatted string
141
- const phcstr = fields.join('$');
142
-
143
- return phcstr;
144
- }
145
-
146
- interface DeserializeResult {
147
- id: string;
148
- version?: number;
149
- params?: Record<string, string | number>;
150
- salt?: Uint8Array;
151
- hash?: Uint8Array;
152
- }
153
-
154
- /**
155
- * Parses data from a PHC string.
156
- * @param {string} phcstr A PHC string to parse.
157
- * @return {DeserializeResult} The object containing the data parsed from the PHC string.
158
- */
159
- export function deserialize(phcstr: string): DeserializeResult {
160
- if (typeof phcstr !== 'string' || phcstr === '') {
161
- throw new TypeError('pchstr must be a non-empty string');
162
- }
163
-
164
- if (phcstr[0] !== '$') {
165
- throw new TypeError('pchstr must contain a $ as first char');
166
- }
167
-
168
- const fields = phcstr.split('$');
169
- // Remove first empty $
170
- fields.shift();
171
-
172
- // Parse Fields
173
- let maxf = 5;
174
- if (!versionRegex.test(fields[1])) maxf--;
175
- if (fields.length > maxf) {
176
- throw new TypeError(`pchstr contains too many fileds: ${fields.length}/${maxf}`);
177
- }
178
-
179
- // Parse Identifier
180
- const id = fields.shift();
181
- if (!id || !idRegex.test(id)) {
182
- throw new TypeError(`id must satisfy ${idRegex}`);
183
- }
184
-
185
- let version: number | undefined;
186
- // Parse Version
187
- if (fields[0] && versionRegex.test(fields[0])) {
188
- const versionMatch = fields.shift()?.match(versionRegex);
189
- version = versionMatch ? parseInt(versionMatch[1], 10) : undefined;
190
- }
191
-
192
- let hash: Uint8Array | undefined;
193
- let salt: Uint8Array | undefined;
194
- if (fields[fields.length - 1] && b64Regex.test(fields[fields.length - 1])) {
195
- if (fields.length > 1 && b64Regex.test(fields[fields.length - 2])) {
196
- // Parse Hash
197
- const hashStr = fields.pop();
198
- if (hashStr) hash = fromBase64(hashStr);
199
- // Parse Salt
200
- const saltStr = fields.pop();
201
- if (saltStr !== undefined) salt = fromBase64(saltStr);
202
- } else {
203
- // Parse Salt
204
- const saltStr = fields.pop();
205
- if (saltStr !== undefined) salt = fromBase64(saltStr);
206
- }
207
- }
208
-
209
- // Parse Parameters
210
- let params: Record<string, string | number> | undefined;
211
- if (fields.length > 0) {
212
- const parstr = fields.pop();
213
- if (parstr) {
214
- params = keyValtoObj(parstr);
215
- if (!Object.keys(params).every((p) => nameRegex.test(p))) {
216
- throw new TypeError(`params names must satisfy ${nameRegex}}`);
217
- }
218
-
219
- const pv = Object.values(params);
220
- if (!pv.every((v) => valueRegex.test(String(v)))) {
221
- throw new TypeError(`params values must satisfy ${valueRegex}`);
222
- }
223
-
224
- // Convert Decimal Strings into Numbers
225
- Object.keys(params).forEach((k) => {
226
- const value = params![k];
227
- if (typeof value === 'string' && decimalRegex.test(value)) {
228
- params![k] = parseInt(value, 10);
229
- }
230
- });
231
- }
232
- }
233
-
234
- if (fields.length > 0) {
235
- throw new TypeError(`pchstr contains unrecognized fileds: ${fields}`);
236
- }
237
-
238
- // Build the output object
239
- const phcobj: DeserializeResult = { id };
240
- if (version !== undefined) phcobj.version = version;
241
- if (params) phcobj.params = params;
242
- if (salt) phcobj.salt = salt;
243
- if (hash) phcobj.hash = hash;
244
-
245
- return phcobj;
246
- }
4
+ // https://github.com/simonepri/phc-format/blob/master/index.js
5
+
6
+ const idRegex = /^[a-z0-9-]{1,32}$/;
7
+ const nameRegex = /^[a-z0-9-]{1,32}$/;
8
+ const valueRegex = /^[a-zA-Z0-9/+.-]+$/;
9
+ const b64Regex = /^([a-zA-Z0-9/+.-]+|)$/;
10
+ const decimalRegex = /^((-)?[1-9]\d*|0)$/;
11
+ const versionRegex = /^v=(\d+)$/;
12
+
13
+ const fromBase64 = ArrayBuffers.fromBase64;
14
+ const toBase64 = ArrayBuffers.toBase64;
15
+ const isBuffer = (v: any): v is Uint8Array => {
16
+ return v instanceof Uint8Array;
17
+ };
18
+
19
+ function objToKeyVal(obj: Record<string, any>): string {
20
+ return objectKeys(obj)
21
+ .map((k) => [k, obj[k]].join('='))
22
+ .join(',');
23
+ }
24
+
25
+ function keyValtoObj(str: string): Record<string, string> {
26
+ const obj: Record<string, string> = {};
27
+ str.split(',').forEach((ps) => {
28
+ const pss = ps.split('=');
29
+ if (pss.length < 2) {
30
+ throw new TypeError(`params must be in the format name=value`);
31
+ }
32
+
33
+ const key = pss.shift();
34
+ if (key !== undefined) {
35
+ obj[key] = pss.join('=');
36
+ }
37
+ });
38
+ return obj;
39
+ }
40
+
41
+ function objectKeys<T extends object>(object: T): Array<keyof T> {
42
+ return Object.keys(object) as Array<keyof T>;
43
+ }
44
+
45
+ function objectValues<T extends object>(object: T): Array<T[keyof T]> {
46
+ if (typeof Object.values === 'function') return Object.values(object);
47
+ return objectKeys(object).map((k) => object[k]);
48
+ }
49
+
50
+ interface SerializeOptions {
51
+ id: string;
52
+ version?: number;
53
+ params?: Record<string, string | number | Uint8Array>;
54
+ salt?: Uint8Array;
55
+ hash?: Uint8Array;
56
+ }
57
+
58
+ /**
59
+ * Generates a PHC string using the data provided.
60
+ * @param {SerializeOptions} opts Object that holds the data needed to generate the PHC string.
61
+ * @return {string} The hash string adhering to the PHC format.
62
+ */
63
+ export function serialize(opts: SerializeOptions): string {
64
+ const fields: string[] = [''];
65
+
66
+ if (typeof opts !== 'object' || opts === null) {
67
+ throw new TypeError('opts must be an object');
68
+ }
69
+
70
+ // Identifier Validation
71
+ if (typeof opts.id !== 'string') {
72
+ throw new TypeError('id must be a string');
73
+ }
74
+
75
+ if (!idRegex.test(opts.id)) {
76
+ throw new TypeError(`id must satisfy ${idRegex}`);
77
+ }
78
+
79
+ fields.push(opts.id);
80
+
81
+ if (typeof opts.version !== 'undefined') {
82
+ if (typeof opts.version !== 'number' || opts.version < 0 || !Number.isInteger(opts.version)) {
83
+ throw new TypeError('version must be a positive integer number');
84
+ }
85
+
86
+ fields.push(`v=${opts.version}`);
87
+ }
88
+
89
+ // Parameters Validation
90
+ if (typeof opts.params !== 'undefined') {
91
+ if (typeof opts.params !== 'object' || opts.params === null) {
92
+ throw new TypeError('params must be an object');
93
+ }
94
+
95
+ const pk = objectKeys(opts.params);
96
+ if (!pk.every((p) => nameRegex.test(p.toString()))) {
97
+ throw new TypeError(`params names must satisfy ${nameRegex}`);
98
+ }
99
+
100
+ // Convert Numbers into Numeric Strings and Buffers into B64 encoded strings.
101
+ pk.forEach((k) => {
102
+ const value = opts.params![k];
103
+ if (typeof value === 'number') {
104
+ opts.params![k] = value.toString();
105
+ } else if (value instanceof Uint8Array) {
106
+ opts.params![k] = toBase64(value).split('=')[0];
107
+ }
108
+ });
109
+ const pv = objectValues(opts.params);
110
+ if (!pv.every((v) => typeof v === 'string')) {
111
+ throw new TypeError('params values must be strings');
112
+ }
113
+
114
+ if (!pv.every((v) => valueRegex.test(v))) {
115
+ throw new TypeError(`params values must satisfy ${valueRegex}`);
116
+ }
117
+
118
+ const strpar = objToKeyVal(opts.params as Record<string, string>);
119
+ fields.push(strpar);
120
+ }
121
+
122
+ if (typeof opts.salt !== 'undefined') {
123
+ // Salt Validation
124
+ if (!isBuffer(opts.salt)) {
125
+ throw new TypeError('salt must be a Buffer');
126
+ }
127
+
128
+ fields.push(toBase64(opts.salt).split('=')[0]);
129
+
130
+ if (typeof opts.hash !== 'undefined') {
131
+ // Hash Validation
132
+ if (!isBuffer(opts.hash)) {
133
+ throw new TypeError('hash must be a Buffer');
134
+ }
135
+
136
+ fields.push(toBase64(opts.hash).split('=')[0]);
137
+ }
138
+ }
139
+
140
+ // Create the PHC formatted string
141
+ const phcstr = fields.join('$');
142
+
143
+ return phcstr;
144
+ }
145
+
146
+ interface DeserializeResult {
147
+ id: string;
148
+ version?: number;
149
+ params?: Record<string, string | number>;
150
+ salt?: Uint8Array;
151
+ hash?: Uint8Array;
152
+ }
153
+
154
+ /**
155
+ * Parses data from a PHC string.
156
+ * @param {string} phcstr A PHC string to parse.
157
+ * @return {DeserializeResult} The object containing the data parsed from the PHC string.
158
+ */
159
+ export function deserialize(phcstr: string): DeserializeResult {
160
+ if (typeof phcstr !== 'string' || phcstr === '') {
161
+ throw new TypeError('pchstr must be a non-empty string');
162
+ }
163
+
164
+ if (phcstr[0] !== '$') {
165
+ throw new TypeError('pchstr must contain a $ as first char');
166
+ }
167
+
168
+ const fields = phcstr.split('$');
169
+ // Remove first empty $
170
+ fields.shift();
171
+
172
+ // Parse Fields
173
+ let maxf = 5;
174
+ if (!versionRegex.test(fields[1])) maxf--;
175
+ if (fields.length > maxf) {
176
+ throw new TypeError(`pchstr contains too many fileds: ${fields.length}/${maxf}`);
177
+ }
178
+
179
+ // Parse Identifier
180
+ const id = fields.shift();
181
+ if (!id || !idRegex.test(id)) {
182
+ throw new TypeError(`id must satisfy ${idRegex}`);
183
+ }
184
+
185
+ let version: number | undefined;
186
+ // Parse Version
187
+ if (fields[0] && versionRegex.test(fields[0])) {
188
+ const versionMatch = fields.shift()?.match(versionRegex);
189
+ version = versionMatch ? parseInt(versionMatch[1], 10) : undefined;
190
+ }
191
+
192
+ let hash: Uint8Array | undefined;
193
+ let salt: Uint8Array | undefined;
194
+ if (fields[fields.length - 1] && b64Regex.test(fields[fields.length - 1])) {
195
+ if (fields.length > 1 && b64Regex.test(fields[fields.length - 2])) {
196
+ // Parse Hash
197
+ const hashStr = fields.pop();
198
+ if (hashStr) hash = fromBase64(hashStr);
199
+ // Parse Salt
200
+ const saltStr = fields.pop();
201
+ if (saltStr !== undefined) salt = fromBase64(saltStr);
202
+ } else {
203
+ // Parse Salt
204
+ const saltStr = fields.pop();
205
+ if (saltStr !== undefined) salt = fromBase64(saltStr);
206
+ }
207
+ }
208
+
209
+ // Parse Parameters
210
+ let params: Record<string, string | number> | undefined;
211
+ if (fields.length > 0) {
212
+ const parstr = fields.pop();
213
+ if (parstr) {
214
+ params = keyValtoObj(parstr);
215
+ if (!Object.keys(params).every((p) => nameRegex.test(p))) {
216
+ throw new TypeError(`params names must satisfy ${nameRegex}}`);
217
+ }
218
+
219
+ const pv = Object.values(params);
220
+ if (!pv.every((v) => valueRegex.test(String(v)))) {
221
+ throw new TypeError(`params values must satisfy ${valueRegex}`);
222
+ }
223
+
224
+ // Convert Decimal Strings into Numbers
225
+ Object.keys(params).forEach((k) => {
226
+ const value = params![k];
227
+ if (typeof value === 'string' && decimalRegex.test(value)) {
228
+ params![k] = parseInt(value, 10);
229
+ }
230
+ });
231
+ }
232
+ }
233
+
234
+ if (fields.length > 0) {
235
+ throw new TypeError(`pchstr contains unrecognized fileds: ${fields}`);
236
+ }
237
+
238
+ // Build the output object
239
+ const phcobj: DeserializeResult = { id };
240
+ if (version !== undefined) phcobj.version = version;
241
+ if (params) phcobj.params = params;
242
+ if (salt) phcobj.salt = salt;
243
+ if (hash) phcobj.hash = hash;
244
+
245
+ return phcobj;
246
+ }
247
247
  }
@@ -5,54 +5,42 @@ import { createBcryptPasswordAlgorithm } from './createBcryptPasswordAlgorithm';
5
5
  import { Password } from './Password';
6
6
 
7
7
  describe('Password', () => {
8
- const check = async ({
9
- password = '1',
10
- ...rest
11
- }: Password.PasswordHashOptions & {
12
- password?: string;
13
- }) => {
14
- let out = await Password.hash(password, rest);
15
- console.log(`${rest.algorithm || 'default'}: hash ${out}`);
16
- let result = await Password.verify(password, out);
17
- expect(result).toBe(true);
18
- };
19
-
20
- Password.addAlgorithm(createBcryptPasswordAlgorithm());
21
- Password.addAlgorithm(createBase64PasswordAlgorithm());
22
- Password.addAlgorithm(
23
- createArgon2PasswordAlgorithm({
24
- provide: import('argon2'),
25
- }),
26
- );
27
- // Password.addAlgorithm(createScryptPasswordAlgorithm());
28
-
29
- test('base', async () => {
30
- await check({});
31
-
32
- await check({ algorithm: 'bcrypt' });
33
-
34
- await check({ algorithm: 'base64' });
35
- // invalid base 64
36
- await check({ algorithm: 'base64', password: '你好' });
37
-
38
- await check({ algorithm: '5' });
39
- await check({ algorithm: '6' });
40
- await check({ algorithm: '7' });
41
- });
42
-
43
- test('should verify manual created hash', async () => {
44
- const tests: Array<{
45
- password?: string;
46
- hash: string;
47
- }> = [
48
- { hash: '$2y$10$MQ057tMbDG6/lVkGFWrNwOR9kh/5rzbkhBPrwNPTPuZ5wBpGNbWLa' },
49
- { hash: '$argon2i$v=19$m=16,t=2,p=1$SDZBU29LRUp0eTJyRDJqZg$76L95nAjG4SjjdoR0YZyFw' },
50
- { hash: '$argon2d$v=19$m=16,t=2,p=1$SDZBU29LRUp0eTJyRDJqZg$+cB2R45sauVlfxbGslAmOw' },
51
- { hash: '$argon2id$v=19$m=16,t=2,p=1$SDZBU29LRUp0eTJyRDJqZg$iP9HYuSDXgG2lW7KARBuQQ' },
52
- ];
53
-
54
- for (const { password = '1', hash } of tests) {
55
- expect(await Password.verify(password, hash)).toBe(true);
56
- }
57
- });
8
+ const check = async ({ password = '1', ...rest }: Password.PasswordHashOptions & { password?: string }) => {
9
+ let out = await Password.hash(password, rest);
10
+ console.log(`${rest.algorithm || 'default'}: hash ${out}`);
11
+ let result = await Password.verify(password, out);
12
+ expect(result).toBe(true);
13
+ };
14
+
15
+ Password.addAlgorithm(createBcryptPasswordAlgorithm());
16
+ Password.addAlgorithm(createBase64PasswordAlgorithm());
17
+ Password.addAlgorithm(createArgon2PasswordAlgorithm({ provide: import('argon2') }));
18
+ // Password.addAlgorithm(createScryptPasswordAlgorithm());
19
+
20
+ test('base', async () => {
21
+ await check({});
22
+
23
+ await check({ algorithm: 'bcrypt' });
24
+
25
+ await check({ algorithm: 'base64' });
26
+ // invalid base 64
27
+ await check({ algorithm: 'base64', password: '你好' });
28
+
29
+ await check({ algorithm: '5' });
30
+ await check({ algorithm: '6' });
31
+ await check({ algorithm: '7' });
32
+ });
33
+
34
+ test('should verify manual created hash', async () => {
35
+ const tests: Array<{ password?: string; hash: string }> = [
36
+ { hash: '$2y$10$MQ057tMbDG6/lVkGFWrNwOR9kh/5rzbkhBPrwNPTPuZ5wBpGNbWLa' },
37
+ { hash: '$argon2i$v=19$m=16,t=2,p=1$SDZBU29LRUp0eTJyRDJqZg$76L95nAjG4SjjdoR0YZyFw' },
38
+ { hash: '$argon2d$v=19$m=16,t=2,p=1$SDZBU29LRUp0eTJyRDJqZg$+cB2R45sauVlfxbGslAmOw' },
39
+ { hash: '$argon2id$v=19$m=16,t=2,p=1$SDZBU29LRUp0eTJyRDJqZg$iP9HYuSDXgG2lW7KARBuQQ' },
40
+ ];
41
+
42
+ for (const { password = '1', hash } of tests) {
43
+ expect(await Password.verify(password, hash)).toBe(true);
44
+ }
45
+ });
58
46
  });