@wener/common 2.0.3 → 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.
Files changed (312) hide show
  1. package/lib/ai/qwen3vl/index.js +1 -1
  2. package/lib/ai/qwen3vl/utils.js +15 -15
  3. package/lib/ai/qwen3vl/utils.js.map +1 -1
  4. package/lib/ai/vision/DocLayoutElementTypeSchema.js +22 -22
  5. package/lib/ai/vision/ImageAnnotationSchema.js +63 -47
  6. package/lib/ai/vision/index.js +2 -2
  7. package/lib/ai/vision/resolveImageAnnotation.js +81 -95
  8. package/lib/cn/ChineseResidentIdNo.js +55 -41
  9. package/lib/cn/ChineseResidentIdNo.js.map +1 -1
  10. package/lib/cn/ChineseResidentIdNo.mod.js +6 -1
  11. package/lib/cn/ChineseResidentIdNo.test.js +22 -21
  12. package/lib/cn/DivisionCode.js +220 -235
  13. package/lib/cn/DivisionCode.mod.js +6 -1
  14. package/lib/cn/DivisionCode.test.js +92 -121
  15. package/lib/cn/Mod11.js +18 -37
  16. package/lib/cn/Mod11.js.map +1 -1
  17. package/lib/cn/Mod31.js +23 -41
  18. package/lib/cn/UnifiedSocialCreditCode.js +143 -137
  19. package/lib/cn/UnifiedSocialCreditCode.mod.js +6 -1
  20. package/lib/cn/UnifiedSocialCreditCode.test.js +21 -15
  21. package/lib/cn/formatChineseAmount.js +46 -71
  22. package/lib/cn/index.js +6 -6
  23. package/lib/cn/mod.js +5 -3
  24. package/lib/cn/parseChineseNumber.js +81 -85
  25. package/lib/cn/parseChineseNumber.test.js +183 -261
  26. package/lib/cn/pinyin/cartesianProduct.js +19 -19
  27. package/lib/cn/pinyin/cartesianProduct.test.js +78 -178
  28. package/lib/cn/pinyin/loader.js +13 -11
  29. package/lib/cn/pinyin/preload.js +2 -1
  30. package/lib/cn/pinyin/toPinyin.test.js +149 -161
  31. package/lib/cn/pinyin/toPinyinPure.js +28 -23
  32. package/lib/cn/pinyin/transform.js +11 -11
  33. package/lib/cn/types.d.js +2 -2
  34. package/lib/consola/createStandardConsolaReporter.js +14 -15
  35. package/lib/consola/formatLogObject.js +149 -133
  36. package/lib/consola/formatLogObject.js.map +1 -1
  37. package/lib/consola/formatLogObject.test.js +167 -178
  38. package/lib/consola/index.js +2 -2
  39. package/lib/data/formatSort.js +14 -12
  40. package/lib/data/formatSort.test.js +33 -33
  41. package/lib/data/index.js +3 -3
  42. package/lib/data/maybeNumber.js +23 -23
  43. package/lib/data/maybeNumber.js.map +1 -1
  44. package/lib/data/parseSort.js +75 -68
  45. package/lib/data/parseSort.test.js +196 -187
  46. package/lib/data/resolvePagination.js +38 -39
  47. package/lib/data/resolvePagination.test.js +228 -218
  48. package/lib/data/types.d.js +2 -2
  49. package/lib/data/types.d.js.map +1 -1
  50. package/lib/dayjs/dayjs.js +20 -20
  51. package/lib/dayjs/formatDuration.js +56 -56
  52. package/lib/dayjs/formatDuration.js.map +1 -1
  53. package/lib/dayjs/formatDuration.test.js +63 -77
  54. package/lib/dayjs/index.js +4 -4
  55. package/lib/dayjs/parseDuration.js +21 -26
  56. package/lib/dayjs/parseRelativeTime.js +65 -66
  57. package/lib/dayjs/parseRelativeTime.test.js +227 -243
  58. package/lib/dayjs/resolveRelativeTime.js +74 -144
  59. package/lib/dayjs/resolveRelativeTime.js.map +1 -1
  60. package/lib/dayjs/resolveRelativeTime.test.js +296 -307
  61. package/lib/decimal/index.js +1 -1
  62. package/lib/decimal/parseDecimal.js +12 -12
  63. package/lib/drain3/Drain.js +321 -0
  64. package/lib/drain3/Drain.js.map +1 -0
  65. package/lib/drain3/LogCluster.js +38 -0
  66. package/lib/drain3/LogCluster.js.map +1 -0
  67. package/lib/drain3/Node.js +39 -0
  68. package/lib/drain3/Node.js.map +1 -0
  69. package/lib/drain3/TemplateMiner.js +205 -0
  70. package/lib/drain3/TemplateMiner.js.map +1 -0
  71. package/lib/drain3/index.js +31 -0
  72. package/lib/drain3/index.js.map +1 -0
  73. package/lib/drain3/persistence/FilePersistence.js +24 -0
  74. package/lib/drain3/persistence/FilePersistence.js.map +1 -0
  75. package/lib/drain3/persistence/MemoryPersistence.js +18 -0
  76. package/lib/drain3/persistence/MemoryPersistence.js.map +1 -0
  77. package/lib/drain3/persistence/PersistenceHandler.js +5 -0
  78. package/lib/drain3/persistence/PersistenceHandler.js.map +1 -0
  79. package/lib/drain3/types.js +7 -0
  80. package/lib/drain3/types.js.map +1 -0
  81. package/lib/emittery/emitter.js +7 -7
  82. package/lib/emittery/index.js +1 -1
  83. package/lib/foundation/schema/SexType.js +15 -12
  84. package/lib/foundation/schema/index.js +1 -1
  85. package/lib/foundation/schema/parseSexType.js +15 -16
  86. package/lib/foundation/schema/types.js +8 -6
  87. package/lib/fs/FileSystemError.js +18 -18
  88. package/lib/fs/IFileSystem.d.js +2 -2
  89. package/lib/fs/IFileSystem.d.js.map +1 -1
  90. package/lib/fs/MemoryFileSystem.test.js +172 -181
  91. package/lib/fs/createBrowserFileSystem.js +222 -233
  92. package/lib/fs/createBrowserFileSystem.js.map +1 -1
  93. package/lib/fs/createMemoryFileSystem.js +473 -510
  94. package/lib/fs/createMemoryFileSystem.js.map +1 -1
  95. package/lib/fs/createSandboxFileSystem.js +102 -101
  96. package/lib/fs/createSandboxFileSystem.js.map +1 -1
  97. package/lib/fs/createWebDavFileSystem.js +162 -132
  98. package/lib/fs/createWebDavFileSystem.js.map +1 -1
  99. package/lib/fs/createWebFileSystem.js +202 -0
  100. package/lib/fs/createWebFileSystem.js.map +1 -0
  101. package/lib/fs/findMimeType.js +14 -14
  102. package/lib/fs/findMimeType.js.map +1 -1
  103. package/lib/fs/index.js +7 -7
  104. package/lib/fs/index.js.map +1 -1
  105. package/lib/fs/minio/createMinioFileSystem.js +977 -0
  106. package/lib/fs/minio/createMinioFileSystem.js.map +1 -0
  107. package/lib/fs/minio/index.js +2 -0
  108. package/lib/fs/minio/index.js.map +1 -0
  109. package/lib/fs/orpc/FileSystemContract.js +57 -57
  110. package/lib/fs/orpc/createContractClientFileSystem.js +88 -88
  111. package/lib/fs/orpc/createContractClientFileSystem.js.map +1 -1
  112. package/lib/fs/orpc/index.js +2 -2
  113. package/lib/fs/orpc/server/createFileSystemContractImpl.js +62 -60
  114. package/lib/fs/orpc/server/createFileSystemContractImpl.js.map +1 -1
  115. package/lib/fs/orpc/server/index.js +1 -1
  116. package/lib/fs/s3/createS3MiniFileSystem.js +756 -689
  117. package/lib/fs/s3/createS3MiniFileSystem.js.map +1 -1
  118. package/lib/fs/s3/index.js +1 -1
  119. package/lib/fs/s3/s3mini.test.js +524 -553
  120. package/lib/fs/scandir.js +56 -56
  121. package/lib/fs/server/createDatabaseFileSystem.js +834 -741
  122. package/lib/fs/server/createDatabaseFileSystem.js.map +1 -1
  123. package/lib/fs/server/createNodeFileSystem.js +407 -380
  124. package/lib/fs/server/createNodeFileSystem.js.map +1 -1
  125. package/lib/fs/server/dbfs.test.js +201 -214
  126. package/lib/fs/server/index.js +1 -1
  127. package/lib/fs/server/loadTestDatabase.js +40 -43
  128. package/lib/fs/tests/runFileSystemTest.js +352 -315
  129. package/lib/fs/tests/runFileSystemTest.js.map +1 -1
  130. package/lib/fs/types.js +17 -20
  131. package/lib/fs/utils/getFileUrl.js +24 -30
  132. package/lib/fs/utils.js +17 -17
  133. package/lib/fs/utils.js.map +1 -1
  134. package/lib/fs/webdav/index.js +2 -0
  135. package/lib/fs/webdav/index.js.map +1 -0
  136. package/lib/index.js +2 -2
  137. package/lib/jsonschema/JsonSchema.js +216 -155
  138. package/lib/jsonschema/JsonSchema.js.map +1 -1
  139. package/lib/jsonschema/JsonSchema.test.js +123 -124
  140. package/lib/jsonschema/forEachJsonSchema.js +41 -41
  141. package/lib/jsonschema/forEachJsonSchema.js.map +1 -1
  142. package/lib/jsonschema/index.js +2 -2
  143. package/lib/jsonschema/types.d.js +2 -2
  144. package/lib/jsonschema/types.d.js.map +1 -1
  145. package/lib/meta/defineFileType.js +32 -38
  146. package/lib/meta/defineInit.js +39 -35
  147. package/lib/meta/defineMetadata.js +37 -34
  148. package/lib/meta/defineMetadata.js.map +1 -1
  149. package/lib/meta/defineMetadata.test.js +13 -12
  150. package/lib/meta/index.js +3 -3
  151. package/lib/orpc/createOpenApiContractClient.js +26 -24
  152. package/lib/orpc/createOpenApiContractClient.js.map +1 -1
  153. package/lib/orpc/createRpcContractClient.js +37 -31
  154. package/lib/orpc/index.js +2 -2
  155. package/lib/orpc/resolveLinkPlugins.js +25 -25
  156. package/lib/password/PHC.js +187 -189
  157. package/lib/password/PHC.js.map +1 -1
  158. package/lib/password/PHC.test.js +517 -535
  159. package/lib/password/Password.js +85 -80
  160. package/lib/password/Password.test.js +330 -364
  161. package/lib/password/createArgon2PasswordAlgorithm.js +50 -51
  162. package/lib/password/createArgon2PasswordAlgorithm.js.map +1 -1
  163. package/lib/password/createBase64PasswordAlgorithm.js +11 -11
  164. package/lib/password/createBase64PasswordAlgorithm.js.map +1 -1
  165. package/lib/password/createBcryptPasswordAlgorithm.js +20 -18
  166. package/lib/password/createBcryptPasswordAlgorithm.js.map +1 -1
  167. package/lib/password/createPBKDF2PasswordAlgorithm.js +65 -52
  168. package/lib/password/createPBKDF2PasswordAlgorithm.js.map +1 -1
  169. package/lib/password/createScryptPasswordAlgorithm.js +74 -63
  170. package/lib/password/createScryptPasswordAlgorithm.js.map +1 -1
  171. package/lib/password/index.js +5 -5
  172. package/lib/password/server/index.js +1 -1
  173. package/lib/resource/Identifiable.js +2 -2
  174. package/lib/resource/ListQuery.js +42 -42
  175. package/lib/resource/ListQuery.js.map +1 -1
  176. package/lib/resource/getTitleOfResource.js +5 -5
  177. package/lib/resource/index.js +2 -2
  178. package/lib/resource/index.js.map +1 -1
  179. package/lib/resource/schema/AnyResourceSchema.js +91 -89
  180. package/lib/resource/schema/BaseResourceSchema.js +26 -26
  181. package/lib/resource/schema/ResourceActionType.js +117 -115
  182. package/lib/resource/schema/ResourceStatus.js +94 -92
  183. package/lib/resource/schema/ResourceType.js +25 -23
  184. package/lib/resource/schema/index.js +5 -5
  185. package/lib/resource/schema/types.js +86 -55
  186. package/lib/resource/schema/types.test.js +16 -13
  187. package/lib/s3/formatS3Url.js +60 -60
  188. package/lib/s3/formatS3Url.js.map +1 -1
  189. package/lib/s3/formatS3Url.test.js +238 -261
  190. package/lib/s3/index.js +2 -2
  191. package/lib/s3/parseS3Url.js +61 -60
  192. package/lib/s3/parseS3Url.js.map +1 -1
  193. package/lib/s3/parseS3Url.test.js +270 -269
  194. package/lib/schema/SchemaRegistry.js +41 -42
  195. package/lib/schema/SchemaRegistry.js.map +1 -1
  196. package/lib/schema/SchemaRegistry.mod.js +1 -1
  197. package/lib/schema/TypeSchema.d.js +2 -2
  198. package/lib/schema/TypeSchema.d.js.map +1 -1
  199. package/lib/schema/createSchemaData.js +113 -67
  200. package/lib/schema/createSchemaData.js.map +1 -1
  201. package/lib/schema/findJsonSchemaByPath.js +28 -23
  202. package/lib/schema/findJsonSchemaByPath.js.map +1 -1
  203. package/lib/schema/formatZodError.js +113 -134
  204. package/lib/schema/formatZodError.js.map +1 -1
  205. package/lib/schema/formatZodError.test.js +192 -195
  206. package/lib/schema/getSchemaCache.js +7 -7
  207. package/lib/schema/getSchemaOptions.js +17 -16
  208. package/lib/schema/index.js +6 -6
  209. package/lib/schema/toJsonSchema.js +196 -190
  210. package/lib/schema/toJsonSchema.js.map +1 -1
  211. package/lib/schema/toJsonSchema.test.js +34 -26
  212. package/lib/schema/validate.js +106 -97
  213. package/lib/schema/validate.js.map +1 -1
  214. package/lib/tools/generateSchema.js +40 -40
  215. package/lib/tools/renderJsonSchemaToMarkdownDoc.js +74 -74
  216. package/lib/utils/buildBaseUrl.js +8 -8
  217. package/lib/utils/buildRedactorFormSchema.js +55 -54
  218. package/lib/utils/buildRedactorFormSchema.js.map +1 -1
  219. package/lib/utils/getEstimateProcessTime.js +24 -19
  220. package/lib/utils/index.js +3 -3
  221. package/lib/utils/resolveFeatureOptions.js +9 -9
  222. package/package.json +37 -18
  223. package/src/ai/qwen3vl/utils.ts +1 -1
  224. package/src/ai/vision/index.ts +2 -2
  225. package/src/cn/ChineseResidentIdNo.ts +1 -1
  226. package/src/cn/Mod11.ts +1 -1
  227. package/src/cn/__snapshots__/ChineseResidentIdNo.test.ts.snap +1 -1
  228. package/src/cn/__snapshots__/UnifiedSocialCreditCode.test.ts.snap +0 -23
  229. package/src/cn/index.ts +1 -2
  230. package/src/cn/parseChineseNumber.test.ts +4 -4
  231. package/src/consola/formatLogObject.ts +6 -6
  232. package/src/consola/index.ts +1 -1
  233. package/src/data/index.ts +3 -4
  234. package/src/data/maybeNumber.ts +1 -1
  235. package/src/data/parseSort.test.ts +0 -1
  236. package/src/data/resolvePagination.ts +2 -2
  237. package/src/data/types.d.ts +2 -2
  238. package/src/dayjs/formatDuration.ts +10 -11
  239. package/src/dayjs/index.ts +1 -1
  240. package/src/dayjs/parseRelativeTime.ts +1 -1
  241. package/src/dayjs/resolveRelativeTime.ts +11 -14
  242. package/src/drain3/Drain.test.ts +378 -0
  243. package/src/drain3/Drain.ts +394 -0
  244. package/src/drain3/LogCluster.ts +46 -0
  245. package/src/drain3/Node.ts +53 -0
  246. package/src/drain3/TemplateMiner.ts +246 -0
  247. package/src/drain3/index.ts +34 -0
  248. package/src/drain3/persistence/FilePersistence.ts +24 -0
  249. package/src/drain3/persistence/MemoryPersistence.ts +23 -0
  250. package/src/drain3/persistence/PersistenceHandler.ts +19 -0
  251. package/src/drain3/types.ts +75 -0
  252. package/src/fs/IFileSystem.d.ts +1 -2
  253. package/src/fs/createBrowserFileSystem.ts +7 -5
  254. package/src/fs/createMemoryFileSystem.ts +9 -13
  255. package/src/fs/createSandboxFileSystem.ts +1 -1
  256. package/src/fs/createWebDavFileSystem.ts +30 -17
  257. package/src/fs/createWebFileSystem.ts +242 -0
  258. package/src/fs/findMimeType.ts +1 -4
  259. package/src/fs/index.ts +5 -5
  260. package/src/fs/minio/createMinioFileSystem.ts +1148 -0
  261. package/src/fs/minio/index.ts +1 -0
  262. package/src/fs/orpc/createContractClientFileSystem.ts +5 -5
  263. package/src/fs/orpc/server/createFileSystemContractImpl.ts +1 -1
  264. package/src/fs/s3/createS3MiniFileSystem.ts +120 -79
  265. package/src/fs/s3/s3fs.test.ts +441 -0
  266. package/src/fs/s3/s3mini.test.ts +2 -2
  267. package/src/fs/server/createDatabaseFileSystem.ts +78 -114
  268. package/src/fs/server/createNodeFileSystem.ts +32 -13
  269. package/src/fs/server/dbfs.test.ts +13 -8
  270. package/src/fs/server/index.ts +1 -0
  271. package/src/fs/server/loadTestDatabase.ts +8 -119
  272. package/src/fs/tests/runFileSystemTest.ts +29 -28
  273. package/src/fs/utils.ts +1 -1
  274. package/src/fs/webdav/index.ts +1 -0
  275. package/src/jsonschema/JsonSchema.ts +5 -5
  276. package/src/jsonschema/forEachJsonSchema.ts +1 -1
  277. package/src/jsonschema/index.ts +1 -1
  278. package/src/jsonschema/types.d.ts +1 -1
  279. package/src/meta/defineMetadata.ts +1 -1
  280. package/src/meta/index.ts +2 -3
  281. package/src/orm/createSqliteDialect.ts +17 -0
  282. package/src/orm/index.ts +1 -0
  283. package/src/orpc/createOpenApiContractClient.ts +3 -3
  284. package/src/orpc/index.ts +1 -1
  285. package/src/password/PHC.ts +3 -3
  286. package/src/password/createArgon2PasswordAlgorithm.ts +2 -2
  287. package/src/password/createBase64PasswordAlgorithm.ts +2 -2
  288. package/src/password/createBcryptPasswordAlgorithm.ts +4 -2
  289. package/src/password/createPBKDF2PasswordAlgorithm.ts +2 -2
  290. package/src/password/createScryptPasswordAlgorithm.ts +4 -4
  291. package/src/password/index.ts +2 -2
  292. package/src/resource/ListQuery.ts +4 -1
  293. package/src/resource/index.ts +3 -3
  294. package/src/resource/schema/index.ts +4 -4
  295. package/src/s3/formatS3Url.test.ts +1 -1
  296. package/src/s3/formatS3Url.ts +2 -2
  297. package/src/s3/index.ts +1 -1
  298. package/src/s3/parseS3Url.ts +1 -1
  299. package/src/schema/SchemaRegistry.ts +2 -2
  300. package/src/schema/TypeSchema.d.ts +6 -6
  301. package/src/schema/createSchemaData.ts +5 -5
  302. package/src/schema/findJsonSchemaByPath.ts +5 -5
  303. package/src/schema/formatZodError.test.ts +2 -1
  304. package/src/schema/formatZodError.ts +50 -62
  305. package/src/schema/index.ts +5 -5
  306. package/src/schema/toJsonSchema.ts +6 -6
  307. package/src/schema/validate.ts +2 -2
  308. package/src/utils/buildRedactorFormSchema.ts +4 -4
  309. package/src/utils/formatNumber.ts +18 -0
  310. package/src/utils/formatPercent.ts +17 -0
  311. package/src/utils/index.ts +3 -3
  312. package/src/utils/resolveFeatureOptions.ts +1 -1
@@ -1,195 +1,193 @@
1
- import { ArrayBuffers } from "@wener/utils";
2
- (function(PHC) {
3
- // https://github.com/simonepri/phc-format/blob/master/index.js
4
- const idRegex = /^[a-z0-9-]{1,32}$/;
5
- const nameRegex = /^[a-z0-9-]{1,32}$/;
6
- const valueRegex = /^[a-zA-Z0-9/+.-]+$/;
7
- const b64Regex = /^([a-zA-Z0-9/+.-]+|)$/;
8
- const decimalRegex = /^((-)?[1-9]\d*|0)$/;
9
- const versionRegex = /^v=(\d+)$/;
10
- const fromBase64 = ArrayBuffers.fromBase64;
11
- const toBase64 = ArrayBuffers.toBase64;
12
- const isBuffer = (v)=>{
13
- return v instanceof Uint8Array;
14
- };
15
- function objToKeyVal(obj) {
16
- return objectKeys(obj).map((k)=>[
17
- k,
18
- obj[k]
19
- ].join('=')).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
- ''
45
- ];
46
- if (typeof opts !== 'object' || opts === null) {
47
- throw new TypeError('opts must be an object');
48
- }
49
- // Identifier Validation
50
- if (typeof opts.id !== 'string') {
51
- throw new TypeError('id must be a string');
52
- }
53
- if (!idRegex.test(opts.id)) {
54
- throw new TypeError(`id must satisfy ${idRegex}`);
55
- }
56
- fields.push(opts.id);
57
- if (typeof opts.version !== 'undefined') {
58
- if (typeof opts.version !== 'number' || opts.version < 0 || !Number.isInteger(opts.version)) {
59
- throw new TypeError('version must be a positive integer number');
60
- }
61
- fields.push(`v=${opts.version}`);
62
- }
63
- // Parameters Validation
64
- if (typeof opts.params !== 'undefined') {
65
- if (typeof opts.params !== 'object' || opts.params === null) {
66
- throw new TypeError('params must be an object');
67
- }
68
- const pk = objectKeys(opts.params);
69
- if (!pk.every((p)=>nameRegex.test(p.toString()))) {
70
- throw new TypeError(`params names must satisfy ${nameRegex}`);
71
- }
72
- // Convert Numbers into Numeric Strings and Buffers into B64 encoded strings.
73
- pk.forEach((k)=>{
74
- const value = opts.params[k];
75
- if (typeof value === 'number') {
76
- opts.params[k] = value.toString();
77
- } else if (value instanceof Uint8Array) {
78
- opts.params[k] = toBase64(value).split('=')[0];
79
- }
80
- });
81
- const pv = objectValues(opts.params);
82
- if (!pv.every((v)=>typeof v === 'string')) {
83
- throw new TypeError('params values must be strings');
84
- }
85
- if (!pv.every((v)=>valueRegex.test(v))) {
86
- throw new TypeError(`params values must satisfy ${valueRegex}`);
87
- }
88
- const strpar = objToKeyVal(opts.params);
89
- fields.push(strpar);
90
- }
91
- if (typeof opts.salt !== 'undefined') {
92
- // Salt Validation
93
- if (!isBuffer(opts.salt)) {
94
- throw new TypeError('salt must be a Buffer');
95
- }
96
- fields.push(toBase64(opts.salt).split('=')[0]);
97
- if (typeof opts.hash !== 'undefined') {
98
- // Hash Validation
99
- if (!isBuffer(opts.hash)) {
100
- throw new TypeError('hash must be a Buffer');
101
- }
102
- fields.push(toBase64(opts.hash).split('=')[0]);
103
- }
104
- }
105
- // Create the PHC formatted string
106
- const phcstr = fields.join('$');
107
- return phcstr;
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
- function deserialize(phcstr) {
115
- if (typeof phcstr !== 'string' || phcstr === '') {
116
- throw new TypeError('pchstr must be a non-empty string');
117
- }
118
- if (phcstr[0] !== '$') {
119
- throw new TypeError('pchstr must contain a $ as first char');
120
- }
121
- const fields = phcstr.split('$');
122
- // Remove first empty $
123
- fields.shift();
124
- // Parse Fields
125
- let maxf = 5;
126
- if (!versionRegex.test(fields[1])) maxf--;
127
- if (fields.length > maxf) {
128
- throw new TypeError(`pchstr contains too many fileds: ${fields.length}/${maxf}`);
129
- }
130
- // Parse Identifier
131
- const id = fields.shift();
132
- if (!id || !idRegex.test(id)) {
133
- throw new TypeError(`id must satisfy ${idRegex}`);
134
- }
135
- let version;
136
- // Parse Version
137
- if (fields[0] && versionRegex.test(fields[0])) {
138
- const versionMatch = fields.shift()?.match(versionRegex);
139
- version = versionMatch ? parseInt(versionMatch[1], 10) : undefined;
140
- }
141
- let hash;
142
- let salt;
143
- if (fields[fields.length - 1] && b64Regex.test(fields[fields.length - 1])) {
144
- if (fields.length > 1 && b64Regex.test(fields[fields.length - 2])) {
145
- // Parse Hash
146
- const hashStr = fields.pop();
147
- if (hashStr) hash = fromBase64(hashStr);
148
- // Parse Salt
149
- const saltStr = fields.pop();
150
- if (saltStr !== undefined) salt = fromBase64(saltStr);
151
- } else {
152
- // Parse Salt
153
- const saltStr = fields.pop();
154
- if (saltStr !== undefined) salt = fromBase64(saltStr);
155
- }
156
- }
157
- // Parse Parameters
158
- let params;
159
- if (fields.length > 0) {
160
- const parstr = fields.pop();
161
- if (parstr) {
162
- params = keyValtoObj(parstr);
163
- if (!Object.keys(params).every((p)=>nameRegex.test(p))) {
164
- throw new TypeError(`params names must satisfy ${nameRegex}}`);
165
- }
166
- const pv = Object.values(params);
167
- if (!pv.every((v)=>valueRegex.test(String(v)))) {
168
- throw new TypeError(`params values must satisfy ${valueRegex}`);
169
- }
170
- // Convert Decimal Strings into Numbers
171
- Object.keys(params).forEach((k)=>{
172
- const value = params[k];
173
- if (typeof value === 'string' && decimalRegex.test(value)) {
174
- params[k] = parseInt(value, 10);
175
- }
176
- });
177
- }
178
- }
179
- if (fields.length > 0) {
180
- throw new TypeError(`pchstr contains unrecognized fileds: ${fields}`);
181
- }
182
- // Build the output object
183
- const phcobj = {
184
- id
185
- };
186
- if (version !== undefined) phcobj.version = version;
187
- if (params) phcobj.params = params;
188
- if (salt) phcobj.salt = salt;
189
- if (hash) phcobj.hash = hash;
190
- return phcobj;
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
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/password/PHC.ts"],"sourcesContent":["import { ArrayBuffers } from '@wener/utils';\n\nexport namespace PHC {\n\t// https://github.com/simonepri/phc-format/blob/master/index.js\n\n\tconst idRegex = /^[a-z0-9-]{1,32}$/;\n\tconst nameRegex = /^[a-z0-9-]{1,32}$/;\n\tconst valueRegex = /^[a-zA-Z0-9/+.-]+$/;\n\tconst b64Regex = /^([a-zA-Z0-9/+.-]+|)$/;\n\tconst decimalRegex = /^((-)?[1-9]\\d*|0)$/;\n\tconst versionRegex = /^v=(\\d+)$/;\n\n\tconst fromBase64 = ArrayBuffers.fromBase64;\n\tconst toBase64 = ArrayBuffers.toBase64;\n\tconst isBuffer = (v: any): v is Uint8Array => {\n\t\treturn v instanceof Uint8Array;\n\t};\n\n\tfunction objToKeyVal(obj: Record<string, any>): string {\n\t\treturn objectKeys(obj)\n\t\t\t.map((k) => [k, obj[k]].join('='))\n\t\t\t.join(',');\n\t}\n\n\tfunction keyValtoObj(str: string): Record<string, string> {\n\t\tconst obj: Record<string, string> = {};\n\t\tstr.split(',').forEach((ps) => {\n\t\t\tconst pss = ps.split('=');\n\t\t\tif (pss.length < 2) {\n\t\t\t\tthrow new TypeError(`params must be in the format name=value`);\n\t\t\t}\n\n\t\t\tconst key = pss.shift();\n\t\t\tif (key !== undefined) {\n\t\t\t\tobj[key] = pss.join('=');\n\t\t\t}\n\t\t});\n\t\treturn obj;\n\t}\n\n\tfunction objectKeys<T extends object>(object: T): Array<keyof T> {\n\t\treturn Object.keys(object) as Array<keyof T>;\n\t}\n\n\tfunction objectValues<T extends object>(object: T): Array<T[keyof T]> {\n\t\tif (typeof Object.values === 'function') return Object.values(object);\n\t\treturn objectKeys(object).map((k) => object[k]);\n\t}\n\n\tinterface SerializeOptions {\n\t\tid: string;\n\t\tversion?: number;\n\t\tparams?: Record<string, string | number | Uint8Array>;\n\t\tsalt?: Uint8Array;\n\t\thash?: Uint8Array;\n\t}\n\n\t/**\n\t * Generates a PHC string using the data provided.\n\t * @param {SerializeOptions} opts Object that holds the data needed to generate the PHC string.\n\t * @return {string} The hash string adhering to the PHC format.\n\t */\n\texport function serialize(opts: SerializeOptions): string {\n\t\tconst fields: string[] = [''];\n\n\t\tif (typeof opts !== 'object' || opts === null) {\n\t\t\tthrow new TypeError('opts must be an object');\n\t\t}\n\n\t\t// Identifier Validation\n\t\tif (typeof opts.id !== 'string') {\n\t\t\tthrow new TypeError('id must be a string');\n\t\t}\n\n\t\tif (!idRegex.test(opts.id)) {\n\t\t\tthrow new TypeError(`id must satisfy ${idRegex}`);\n\t\t}\n\n\t\tfields.push(opts.id);\n\n\t\tif (typeof opts.version !== 'undefined') {\n\t\t\tif (typeof opts.version !== 'number' || opts.version < 0 || !Number.isInteger(opts.version)) {\n\t\t\t\tthrow new TypeError('version must be a positive integer number');\n\t\t\t}\n\n\t\t\tfields.push(`v=${opts.version}`);\n\t\t}\n\n\t\t// Parameters Validation\n\t\tif (typeof opts.params !== 'undefined') {\n\t\t\tif (typeof opts.params !== 'object' || opts.params === null) {\n\t\t\t\tthrow new TypeError('params must be an object');\n\t\t\t}\n\n\t\t\tconst pk = objectKeys(opts.params);\n\t\t\tif (!pk.every((p) => nameRegex.test(p.toString()))) {\n\t\t\t\tthrow new TypeError(`params names must satisfy ${nameRegex}`);\n\t\t\t}\n\n\t\t\t// Convert Numbers into Numeric Strings and Buffers into B64 encoded strings.\n\t\t\tpk.forEach((k) => {\n\t\t\t\tconst value = opts.params![k];\n\t\t\t\tif (typeof value === 'number') {\n\t\t\t\t\topts.params![k] = value.toString();\n\t\t\t\t} else if (value instanceof Uint8Array) {\n\t\t\t\t\topts.params![k] = toBase64(value as BufferSource).split('=')[0];\n\t\t\t\t}\n\t\t\t});\n\t\t\tconst pv = objectValues(opts.params);\n\t\t\tif (!pv.every((v) => typeof v === 'string')) {\n\t\t\t\tthrow new TypeError('params values must be strings');\n\t\t\t}\n\n\t\t\tif (!pv.every((v) => valueRegex.test(v))) {\n\t\t\t\tthrow new TypeError(`params values must satisfy ${valueRegex}`);\n\t\t\t}\n\n\t\t\tconst strpar = objToKeyVal(opts.params as Record<string, string>);\n\t\t\tfields.push(strpar);\n\t\t}\n\n\t\tif (typeof opts.salt !== 'undefined') {\n\t\t\t// Salt Validation\n\t\t\tif (!isBuffer(opts.salt)) {\n\t\t\t\tthrow new TypeError('salt must be a Buffer');\n\t\t\t}\n\n\t\t\tfields.push(toBase64(opts.salt as BufferSource).split('=')[0]);\n\n\t\t\tif (typeof opts.hash !== 'undefined') {\n\t\t\t\t// Hash Validation\n\t\t\t\tif (!isBuffer(opts.hash)) {\n\t\t\t\t\tthrow new TypeError('hash must be a Buffer');\n\t\t\t\t}\n\n\t\t\t\tfields.push(toBase64(opts.hash as BufferSource).split('=')[0]);\n\t\t\t}\n\t\t}\n\n\t\t// Create the PHC formatted string\n\t\tconst phcstr = fields.join('$');\n\n\t\treturn phcstr;\n\t}\n\n\tinterface DeserializeResult {\n\t\tid: string;\n\t\tversion?: number;\n\t\tparams?: Record<string, string | number>;\n\t\tsalt?: Uint8Array;\n\t\thash?: Uint8Array;\n\t}\n\n\t/**\n\t * Parses data from a PHC string.\n\t * @param {string} phcstr A PHC string to parse.\n\t * @return {DeserializeResult} The object containing the data parsed from the PHC string.\n\t */\n\texport function deserialize(phcstr: string): DeserializeResult {\n\t\tif (typeof phcstr !== 'string' || phcstr === '') {\n\t\t\tthrow new TypeError('pchstr must be a non-empty string');\n\t\t}\n\n\t\tif (phcstr[0] !== '$') {\n\t\t\tthrow new TypeError('pchstr must contain a $ as first char');\n\t\t}\n\n\t\tconst fields = phcstr.split('$');\n\t\t// Remove first empty $\n\t\tfields.shift();\n\n\t\t// Parse Fields\n\t\tlet maxf = 5;\n\t\tif (!versionRegex.test(fields[1])) maxf--;\n\t\tif (fields.length > maxf) {\n\t\t\tthrow new TypeError(`pchstr contains too many fileds: ${fields.length}/${maxf}`);\n\t\t}\n\n\t\t// Parse Identifier\n\t\tconst id = fields.shift();\n\t\tif (!id || !idRegex.test(id)) {\n\t\t\tthrow new TypeError(`id must satisfy ${idRegex}`);\n\t\t}\n\n\t\tlet version: number | undefined;\n\t\t// Parse Version\n\t\tif (fields[0] && versionRegex.test(fields[0])) {\n\t\t\tconst versionMatch = fields.shift()?.match(versionRegex);\n\t\t\tversion = versionMatch ? parseInt(versionMatch[1], 10) : undefined;\n\t\t}\n\n\t\tlet hash: Uint8Array | undefined;\n\t\tlet salt: Uint8Array | undefined;\n\t\tif (fields[fields.length - 1] && b64Regex.test(fields[fields.length - 1])) {\n\t\t\tif (fields.length > 1 && b64Regex.test(fields[fields.length - 2])) {\n\t\t\t\t// Parse Hash\n\t\t\t\tconst hashStr = fields.pop();\n\t\t\t\tif (hashStr) hash = fromBase64(hashStr);\n\t\t\t\t// Parse Salt\n\t\t\t\tconst saltStr = fields.pop();\n\t\t\t\tif (saltStr !== undefined) salt = fromBase64(saltStr);\n\t\t\t} else {\n\t\t\t\t// Parse Salt\n\t\t\t\tconst saltStr = fields.pop();\n\t\t\t\tif (saltStr !== undefined) salt = fromBase64(saltStr);\n\t\t\t}\n\t\t}\n\n\t\t// Parse Parameters\n\t\tlet params: Record<string, string | number> | undefined;\n\t\tif (fields.length > 0) {\n\t\t\tconst parstr = fields.pop();\n\t\t\tif (parstr) {\n\t\t\t\tparams = keyValtoObj(parstr);\n\t\t\t\tif (!Object.keys(params).every((p) => nameRegex.test(p))) {\n\t\t\t\t\tthrow new TypeError(`params names must satisfy ${nameRegex}}`);\n\t\t\t\t}\n\n\t\t\t\tconst pv = Object.values(params);\n\t\t\t\tif (!pv.every((v) => valueRegex.test(String(v)))) {\n\t\t\t\t\tthrow new TypeError(`params values must satisfy ${valueRegex}`);\n\t\t\t\t}\n\n\t\t\t\t// Convert Decimal Strings into Numbers\n\t\t\t\tObject.keys(params).forEach((k) => {\n\t\t\t\t\tconst value = params![k];\n\t\t\t\t\tif (typeof value === 'string' && decimalRegex.test(value)) {\n\t\t\t\t\t\tparams![k] = parseInt(value, 10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (fields.length > 0) {\n\t\t\tthrow new TypeError(`pchstr contains unrecognized fileds: ${fields}`);\n\t\t}\n\n\t\t// Build the output object\n\t\tconst phcobj: DeserializeResult = { id };\n\t\tif (version !== undefined) phcobj.version = version;\n\t\tif (params) phcobj.params = params;\n\t\tif (salt) phcobj.salt = salt;\n\t\tif (hash) phcobj.hash = hash;\n\n\t\treturn phcobj;\n\t}\n}\n"],"names":["ArrayBuffers","PHC","idRegex","nameRegex","valueRegex","b64Regex","decimalRegex","versionRegex","fromBase64","toBase64","isBuffer","v","Uint8Array","objToKeyVal","obj","objectKeys","map","k","join","keyValtoObj","str","split","forEach","ps","pss","length","TypeError","key","shift","undefined","object","Object","keys","objectValues","values","serialize","opts","fields","id","test","push","version","Number","isInteger","params","pk","every","p","toString","value","pv","strpar","salt","hash","phcstr","deserialize","maxf","versionMatch","match","parseInt","hashStr","pop","saltStr","parstr","String","phcobj"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/password/PHC.ts"],"sourcesContent":["import { ArrayBuffers } from '@wener/utils';\n\nexport namespace PHC {\n\t// https://github.com/simonepri/phc-format/blob/master/index.js\n\n\tconst idRegex = /^[a-z0-9-]{1,32}$/;\n\tconst nameRegex = /^[a-z0-9-]{1,32}$/;\n\tconst valueRegex = /^[a-zA-Z0-9/+.-]+$/;\n\tconst b64Regex = /^([a-zA-Z0-9/+.-]+|)$/;\n\tconst decimalRegex = /^((-)?[1-9]\\d*|0)$/;\n\tconst versionRegex = /^v=(\\d+)$/;\n\n\tconst fromBase64 = ArrayBuffers.fromBase64;\n\tconst toBase64 = ArrayBuffers.toBase64;\n\tconst isBuffer = (v: any): v is Uint8Array => {\n\t\treturn v instanceof Uint8Array;\n\t};\n\n\tfunction objToKeyVal(obj: Record<string, any>): string {\n\t\treturn objectKeys(obj)\n\t\t\t.map((k) => [k, obj[k]].join('='))\n\t\t\t.join(',');\n\t}\n\n\tfunction keyValtoObj(str: string): Record<string, string> {\n\t\tconst obj: Record<string, string> = {};\n\t\tstr.split(',').forEach((ps) => {\n\t\t\tconst pss = ps.split('=');\n\t\t\tif (pss.length < 2) {\n\t\t\t\tthrow new TypeError(`params must be in the format name=value`);\n\t\t\t}\n\n\t\t\tconst key = pss.shift();\n\t\t\tif (key !== undefined) {\n\t\t\t\tobj[key] = pss.join('=');\n\t\t\t}\n\t\t});\n\t\treturn obj;\n\t}\n\n\tfunction objectKeys<T extends object>(object: T): Array<keyof T> {\n\t\treturn Object.keys(object) as Array<keyof T>;\n\t}\n\n\tfunction objectValues<T extends object>(object: T): Array<T[keyof T]> {\n\t\tif (typeof Object.values === 'function') return Object.values(object);\n\t\treturn objectKeys(object).map((k) => object[k]);\n\t}\n\n\tinterface SerializeOptions {\n\t\tid: string;\n\t\tversion?: number;\n\t\tparams?: Record<string, string | number | Uint8Array>;\n\t\tsalt?: Uint8Array;\n\t\thash?: Uint8Array;\n\t}\n\n\t/**\n\t * Generates a PHC string using the data provided.\n\t * @param {SerializeOptions} opts Object that holds the data needed to generate the PHC string.\n\t * @return {string} The hash string adhering to the PHC format.\n\t */\n\texport function serialize(opts: SerializeOptions): string {\n\t\tconst fields: string[] = [''];\n\n\t\tif (typeof opts !== 'object' || opts === null) {\n\t\t\tthrow new TypeError('opts must be an object');\n\t\t}\n\n\t\t// Identifier Validation\n\t\tif (typeof opts.id !== 'string') {\n\t\t\tthrow new TypeError('id must be a string');\n\t\t}\n\n\t\tif (!idRegex.test(opts.id)) {\n\t\t\tthrow new TypeError(`id must satisfy ${idRegex}`);\n\t\t}\n\n\t\tfields.push(opts.id);\n\n\t\tif (typeof opts.version !== 'undefined') {\n\t\t\tif (typeof opts.version !== 'number' || opts.version < 0 || !Number.isInteger(opts.version)) {\n\t\t\t\tthrow new TypeError('version must be a positive integer number');\n\t\t\t}\n\n\t\t\tfields.push(`v=${opts.version}`);\n\t\t}\n\n\t\t// Parameters Validation\n\t\tif (typeof opts.params !== 'undefined') {\n\t\t\tif (typeof opts.params !== 'object' || opts.params === null) {\n\t\t\t\tthrow new TypeError('params must be an object');\n\t\t\t}\n\n\t\t\tconst pk = objectKeys(opts.params);\n\t\t\tif (!pk.every((p) => nameRegex.test(p.toString()))) {\n\t\t\t\tthrow new TypeError(`params names must satisfy ${nameRegex}`);\n\t\t\t}\n\n\t\t\t// Convert Numbers into Numeric Strings and Buffers into B64 encoded strings.\n\t\t\tpk.forEach((k) => {\n\t\t\t\tconst value = opts.params?.[k];\n\t\t\t\tif (typeof value === 'number') {\n\t\t\t\t\topts.params![k] = value.toString();\n\t\t\t\t} else if (value instanceof Uint8Array) {\n\t\t\t\t\topts.params![k] = toBase64(value as BufferSource).split('=')[0];\n\t\t\t\t}\n\t\t\t});\n\t\t\tconst pv = objectValues(opts.params);\n\t\t\tif (!pv.every((v) => typeof v === 'string')) {\n\t\t\t\tthrow new TypeError('params values must be strings');\n\t\t\t}\n\n\t\t\tif (!pv.every((v) => valueRegex.test(v))) {\n\t\t\t\tthrow new TypeError(`params values must satisfy ${valueRegex}`);\n\t\t\t}\n\n\t\t\tconst strpar = objToKeyVal(opts.params as Record<string, string>);\n\t\t\tfields.push(strpar);\n\t\t}\n\n\t\tif (typeof opts.salt !== 'undefined') {\n\t\t\t// Salt Validation\n\t\t\tif (!isBuffer(opts.salt)) {\n\t\t\t\tthrow new TypeError('salt must be a Buffer');\n\t\t\t}\n\n\t\t\tfields.push(toBase64(opts.salt as BufferSource).split('=')[0]);\n\n\t\t\tif (typeof opts.hash !== 'undefined') {\n\t\t\t\t// Hash Validation\n\t\t\t\tif (!isBuffer(opts.hash)) {\n\t\t\t\t\tthrow new TypeError('hash must be a Buffer');\n\t\t\t\t}\n\n\t\t\t\tfields.push(toBase64(opts.hash as BufferSource).split('=')[0]);\n\t\t\t}\n\t\t}\n\n\t\t// Create the PHC formatted string\n\t\tconst phcstr = fields.join('$');\n\n\t\treturn phcstr;\n\t}\n\n\texport interface DeserializeResult {\n\t\tid: string;\n\t\tversion?: number;\n\t\tparams?: Record<string, string | number>;\n\t\tsalt?: Uint8Array;\n\t\thash?: Uint8Array;\n\t}\n\n\t/**\n\t * Parses data from a PHC string.\n\t * @param {string} phcstr A PHC string to parse.\n\t * @return {DeserializeResult} The object containing the data parsed from the PHC string.\n\t */\n\texport function deserialize(phcstr: string): DeserializeResult {\n\t\tif (typeof phcstr !== 'string' || phcstr === '') {\n\t\t\tthrow new TypeError('pchstr must be a non-empty string');\n\t\t}\n\n\t\tif (phcstr[0] !== '$') {\n\t\t\tthrow new TypeError('pchstr must contain a $ as first char');\n\t\t}\n\n\t\tconst fields = phcstr.split('$');\n\t\t// Remove first empty $\n\t\tfields.shift();\n\n\t\t// Parse Fields\n\t\tlet maxf = 5;\n\t\tif (!versionRegex.test(fields[1])) maxf--;\n\t\tif (fields.length > maxf) {\n\t\t\tthrow new TypeError(`pchstr contains too many fileds: ${fields.length}/${maxf}`);\n\t\t}\n\n\t\t// Parse Identifier\n\t\tconst id = fields.shift();\n\t\tif (!id || !idRegex.test(id)) {\n\t\t\tthrow new TypeError(`id must satisfy ${idRegex}`);\n\t\t}\n\n\t\tlet version: number | undefined;\n\t\t// Parse Version\n\t\tif (fields[0] && versionRegex.test(fields[0])) {\n\t\t\tconst versionMatch = fields.shift()?.match(versionRegex);\n\t\t\tversion = versionMatch ? parseInt(versionMatch[1], 10) : undefined;\n\t\t}\n\n\t\tlet hash: Uint8Array | undefined;\n\t\tlet salt: Uint8Array | undefined;\n\t\tif (fields[fields.length - 1] && b64Regex.test(fields[fields.length - 1])) {\n\t\t\tif (fields.length > 1 && b64Regex.test(fields[fields.length - 2])) {\n\t\t\t\t// Parse Hash\n\t\t\t\tconst hashStr = fields.pop();\n\t\t\t\tif (hashStr) hash = fromBase64(hashStr);\n\t\t\t\t// Parse Salt\n\t\t\t\tconst saltStr = fields.pop();\n\t\t\t\tif (saltStr !== undefined) salt = fromBase64(saltStr);\n\t\t\t} else {\n\t\t\t\t// Parse Salt\n\t\t\t\tconst saltStr = fields.pop();\n\t\t\t\tif (saltStr !== undefined) salt = fromBase64(saltStr);\n\t\t\t}\n\t\t}\n\n\t\t// Parse Parameters\n\t\tlet params: Record<string, string | number> | undefined;\n\t\tif (fields.length > 0) {\n\t\t\tconst parstr = fields.pop();\n\t\t\tif (parstr) {\n\t\t\t\tparams = keyValtoObj(parstr);\n\t\t\t\tif (!Object.keys(params).every((p) => nameRegex.test(p))) {\n\t\t\t\t\tthrow new TypeError(`params names must satisfy ${nameRegex}}`);\n\t\t\t\t}\n\n\t\t\t\tconst pv = Object.values(params);\n\t\t\t\tif (!pv.every((v) => valueRegex.test(String(v)))) {\n\t\t\t\t\tthrow new TypeError(`params values must satisfy ${valueRegex}`);\n\t\t\t\t}\n\n\t\t\t\t// Convert Decimal Strings into Numbers\n\t\t\t\tObject.keys(params).forEach((k) => {\n\t\t\t\t\tconst value = params?.[k];\n\t\t\t\t\tif (typeof value === 'string' && decimalRegex.test(value)) {\n\t\t\t\t\t\tparams![k] = parseInt(value, 10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (fields.length > 0) {\n\t\t\tthrow new TypeError(`pchstr contains unrecognized fileds: ${fields}`);\n\t\t}\n\n\t\t// Build the output object\n\t\tconst phcobj: DeserializeResult = { id };\n\t\tif (version !== undefined) phcobj.version = version;\n\t\tif (params) phcobj.params = params;\n\t\tif (salt) phcobj.salt = salt;\n\t\tif (hash) phcobj.hash = hash;\n\n\t\treturn phcobj;\n\t}\n}\n"],"names":["ArrayBuffers","PHC","idRegex","nameRegex","valueRegex","b64Regex","decimalRegex","versionRegex","fromBase64","toBase64","isBuffer","v","Uint8Array","objToKeyVal","obj","objectKeys","map","k","join","keyValtoObj","str","split","forEach","ps","pss","length","TypeError","key","shift","undefined","object","Object","keys","objectValues","values","serialize","opts","fields","id","test","push","version","Number","isInteger","params","pk","every","p","toString","value","pv","strpar","salt","hash","phcstr","deserialize","maxf","versionMatch","match","parseInt","hashStr","pop","saltStr","parstr","String","phcobj"],"mappings":"AAAA,SAASA,YAAY,QAAQ,eAAe;UAE3BC;IAChB,+DAA+D;IAE/D,MAAMC,UAAU;IAChB,MAAMC,YAAY;IAClB,MAAMC,aAAa;IACnB,MAAMC,WAAW;IACjB,MAAMC,eAAe;IACrB,MAAMC,eAAe;IAErB,MAAMC,aAAaR,aAAaQ,UAAU;IAC1C,MAAMC,WAAWT,aAAaS,QAAQ;IACtC,MAAMC,WAAW,CAACC;QACjB,OAAOA,aAAaC;IACrB;IAEA,SAASC,YAAYC,GAAwB;QAC5C,OAAOC,WAAWD,KAChBE,GAAG,CAAC,CAACC,IAAM;gBAACA;gBAAGH,GAAG,CAACG,EAAE;aAAC,CAACC,IAAI,CAAC,MAC5BA,IAAI,CAAC;IACR;IAEA,SAASC,YAAYC,GAAW;QAC/B,MAAMN,MAA8B,CAAC;QACrCM,IAAIC,KAAK,CAAC,KAAKC,OAAO,CAAC,CAACC;YACvB,MAAMC,MAAMD,GAAGF,KAAK,CAAC;YACrB,IAAIG,IAAIC,MAAM,GAAG,GAAG;gBACnB,MAAM,IAAIC,UAAU,CAAC,uCAAuC,CAAC;YAC9D;YAEA,MAAMC,MAAMH,IAAII,KAAK;YACrB,IAAID,QAAQE,WAAW;gBACtBf,GAAG,CAACa,IAAI,GAAGH,IAAIN,IAAI,CAAC;YACrB;QACD;QACA,OAAOJ;IACR;IAEA,SAASC,WAA6Be,MAAS;QAC9C,OAAOC,OAAOC,IAAI,CAACF;IACpB;IAEA,SAASG,aAA+BH,MAAS;QAChD,IAAI,OAAOC,OAAOG,MAAM,KAAK,YAAY,OAAOH,OAAOG,MAAM,CAACJ;QAC9D,OAAOf,WAAWe,QAAQd,GAAG,CAAC,CAACC,IAAMa,MAAM,CAACb,EAAE;IAC/C;IAeO,SAASkB,UAAUC,IAAsB;QAC/C,MAAMC,SAAmB;YAAC;SAAG;QAE7B,IAAI,OAAOD,SAAS,YAAYA,SAAS,MAAM;YAC9C,MAAM,IAAIV,UAAU;QACrB;QAEA,wBAAwB;QACxB,IAAI,OAAOU,KAAKE,EAAE,KAAK,UAAU;YAChC,MAAM,IAAIZ,UAAU;QACrB;QAEA,IAAI,CAACxB,QAAQqC,IAAI,CAACH,KAAKE,EAAE,GAAG;YAC3B,MAAM,IAAIZ,UAAU,CAAC,gBAAgB,EAAExB,SAAS;QACjD;QAEAmC,OAAOG,IAAI,CAACJ,KAAKE,EAAE;QAEnB,IAAI,OAAOF,KAAKK,OAAO,KAAK,aAAa;YACxC,IAAI,OAAOL,KAAKK,OAAO,KAAK,YAAYL,KAAKK,OAAO,GAAG,KAAK,CAACC,OAAOC,SAAS,CAACP,KAAKK,OAAO,GAAG;gBAC5F,MAAM,IAAIf,UAAU;YACrB;YAEAW,OAAOG,IAAI,CAAC,CAAC,EAAE,EAAEJ,KAAKK,OAAO,EAAE;QAChC;QAEA,wBAAwB;QACxB,IAAI,OAAOL,KAAKQ,MAAM,KAAK,aAAa;YACvC,IAAI,OAAOR,KAAKQ,MAAM,KAAK,YAAYR,KAAKQ,MAAM,KAAK,MAAM;gBAC5D,MAAM,IAAIlB,UAAU;YACrB;YAEA,MAAMmB,KAAK9B,WAAWqB,KAAKQ,MAAM;YACjC,IAAI,CAACC,GAAGC,KAAK,CAAC,CAACC,IAAM5C,UAAUoC,IAAI,CAACQ,EAAEC,QAAQ,MAAM;gBACnD,MAAM,IAAItB,UAAU,CAAC,0BAA0B,EAAEvB,WAAW;YAC7D;YAEA,6EAA6E;YAC7E0C,GAAGvB,OAAO,CAAC,CAACL;gBACX,MAAMgC,QAAQb,KAAKQ,MAAM,EAAE,CAAC3B,EAAE;gBAC9B,IAAI,OAAOgC,UAAU,UAAU;oBAC9Bb,KAAKQ,MAAM,AAAC,CAAC3B,EAAE,GAAGgC,MAAMD,QAAQ;gBACjC,OAAO,IAAIC,iBAAiBrC,YAAY;oBACvCwB,KAAKQ,MAAM,AAAC,CAAC3B,EAAE,GAAGR,SAASwC,OAAuB5B,KAAK,CAAC,IAAI,CAAC,EAAE;gBAChE;YACD;YACA,MAAM6B,KAAKjB,aAAaG,KAAKQ,MAAM;YACnC,IAAI,CAACM,GAAGJ,KAAK,CAAC,CAACnC,IAAM,OAAOA,MAAM,WAAW;gBAC5C,MAAM,IAAIe,UAAU;YACrB;YAEA,IAAI,CAACwB,GAAGJ,KAAK,CAAC,CAACnC,IAAMP,WAAWmC,IAAI,CAAC5B,KAAK;gBACzC,MAAM,IAAIe,UAAU,CAAC,2BAA2B,EAAEtB,YAAY;YAC/D;YAEA,MAAM+C,SAAStC,YAAYuB,KAAKQ,MAAM;YACtCP,OAAOG,IAAI,CAACW;QACb;QAEA,IAAI,OAAOf,KAAKgB,IAAI,KAAK,aAAa;YACrC,kBAAkB;YAClB,IAAI,CAAC1C,SAAS0B,KAAKgB,IAAI,GAAG;gBACzB,MAAM,IAAI1B,UAAU;YACrB;YAEAW,OAAOG,IAAI,CAAC/B,SAAS2B,KAAKgB,IAAI,EAAkB/B,KAAK,CAAC,IAAI,CAAC,EAAE;YAE7D,IAAI,OAAOe,KAAKiB,IAAI,KAAK,aAAa;gBACrC,kBAAkB;gBAClB,IAAI,CAAC3C,SAAS0B,KAAKiB,IAAI,GAAG;oBACzB,MAAM,IAAI3B,UAAU;gBACrB;gBAEAW,OAAOG,IAAI,CAAC/B,SAAS2B,KAAKiB,IAAI,EAAkBhC,KAAK,CAAC,IAAI,CAAC,EAAE;YAC9D;QACD;QAEA,kCAAkC;QAClC,MAAMiC,SAASjB,OAAOnB,IAAI,CAAC;QAE3B,OAAOoC;IACR;IAtFA;;;;EAIC,OACenB,YAAAA;IAgGT,SAASoB,YAAYD,MAAc;QACzC,IAAI,OAAOA,WAAW,YAAYA,WAAW,IAAI;YAChD,MAAM,IAAI5B,UAAU;QACrB;QAEA,IAAI4B,MAAM,CAAC,EAAE,KAAK,KAAK;YACtB,MAAM,IAAI5B,UAAU;QACrB;QAEA,MAAMW,SAASiB,OAAOjC,KAAK,CAAC;QAC5B,uBAAuB;QACvBgB,OAAOT,KAAK;QAEZ,eAAe;QACf,IAAI4B,OAAO;QACX,IAAI,CAACjD,aAAagC,IAAI,CAACF,MAAM,CAAC,EAAE,GAAGmB;QACnC,IAAInB,OAAOZ,MAAM,GAAG+B,MAAM;YACzB,MAAM,IAAI9B,UAAU,CAAC,iCAAiC,EAAEW,OAAOZ,MAAM,CAAC,CAAC,EAAE+B,MAAM;QAChF;QAEA,mBAAmB;QACnB,MAAMlB,KAAKD,OAAOT,KAAK;QACvB,IAAI,CAACU,MAAM,CAACpC,QAAQqC,IAAI,CAACD,KAAK;YAC7B,MAAM,IAAIZ,UAAU,CAAC,gBAAgB,EAAExB,SAAS;QACjD;QAEA,IAAIuC;QACJ,gBAAgB;QAChB,IAAIJ,MAAM,CAAC,EAAE,IAAI9B,aAAagC,IAAI,CAACF,MAAM,CAAC,EAAE,GAAG;YAC9C,MAAMoB,eAAepB,OAAOT,KAAK,IAAI8B,MAAMnD;YAC3CkC,UAAUgB,eAAeE,SAASF,YAAY,CAAC,EAAE,EAAE,MAAM5B;QAC1D;QAEA,IAAIwB;QACJ,IAAID;QACJ,IAAIf,MAAM,CAACA,OAAOZ,MAAM,GAAG,EAAE,IAAIpB,SAASkC,IAAI,CAACF,MAAM,CAACA,OAAOZ,MAAM,GAAG,EAAE,GAAG;YAC1E,IAAIY,OAAOZ,MAAM,GAAG,KAAKpB,SAASkC,IAAI,CAACF,MAAM,CAACA,OAAOZ,MAAM,GAAG,EAAE,GAAG;gBAClE,aAAa;gBACb,MAAMmC,UAAUvB,OAAOwB,GAAG;gBAC1B,IAAID,SAASP,OAAO7C,WAAWoD;gBAC/B,aAAa;gBACb,MAAME,UAAUzB,OAAOwB,GAAG;gBAC1B,IAAIC,YAAYjC,WAAWuB,OAAO5C,WAAWsD;YAC9C,OAAO;gBACN,aAAa;gBACb,MAAMA,UAAUzB,OAAOwB,GAAG;gBAC1B,IAAIC,YAAYjC,WAAWuB,OAAO5C,WAAWsD;YAC9C;QACD;QAEA,mBAAmB;QACnB,IAAIlB;QACJ,IAAIP,OAAOZ,MAAM,GAAG,GAAG;YACtB,MAAMsC,SAAS1B,OAAOwB,GAAG;YACzB,IAAIE,QAAQ;gBACXnB,SAASzB,YAAY4C;gBACrB,IAAI,CAAChC,OAAOC,IAAI,CAACY,QAAQE,KAAK,CAAC,CAACC,IAAM5C,UAAUoC,IAAI,CAACQ,KAAK;oBACzD,MAAM,IAAIrB,UAAU,CAAC,0BAA0B,EAAEvB,UAAU,CAAC,CAAC;gBAC9D;gBAEA,MAAM+C,KAAKnB,OAAOG,MAAM,CAACU;gBACzB,IAAI,CAACM,GAAGJ,KAAK,CAAC,CAACnC,IAAMP,WAAWmC,IAAI,CAACyB,OAAOrD,MAAM;oBACjD,MAAM,IAAIe,UAAU,CAAC,2BAA2B,EAAEtB,YAAY;gBAC/D;gBAEA,uCAAuC;gBACvC2B,OAAOC,IAAI,CAACY,QAAQtB,OAAO,CAAC,CAACL;oBAC5B,MAAMgC,QAAQL,QAAQ,CAAC3B,EAAE;oBACzB,IAAI,OAAOgC,UAAU,YAAY3C,aAAaiC,IAAI,CAACU,QAAQ;wBAC1DL,MAAO,CAAC3B,EAAE,GAAG0C,SAASV,OAAO;oBAC9B;gBACD;YACD;QACD;QAEA,IAAIZ,OAAOZ,MAAM,GAAG,GAAG;YACtB,MAAM,IAAIC,UAAU,CAAC,qCAAqC,EAAEW,QAAQ;QACrE;QAEA,0BAA0B;QAC1B,MAAM4B,SAA4B;YAAE3B;QAAG;QACvC,IAAIG,YAAYZ,WAAWoC,OAAOxB,OAAO,GAAGA;QAC5C,IAAIG,QAAQqB,OAAOrB,MAAM,GAAGA;QAC5B,IAAIQ,MAAMa,OAAOb,IAAI,GAAGA;QACxB,IAAIC,MAAMY,OAAOZ,IAAI,GAAGA;QAExB,OAAOY;IACR;IA5FA;;;;EAIC,OACeV,cAAAA;AAwFjB,GApPiBtD,QAAAA"}