cipher-kit 2.0.0 → 2.1.0

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 (40) hide show
  1. package/README.md +25 -27
  2. package/dist/{chunk-3UX5MZ2P.cjs → chunk-BHG5RSUV.cjs} +22 -20
  3. package/dist/chunk-BHG5RSUV.cjs.map +1 -0
  4. package/dist/{chunk-4MFF6V3R.js → chunk-CRTOKS3Q.js} +76 -41
  5. package/dist/chunk-CRTOKS3Q.js.map +1 -0
  6. package/dist/{chunk-N2EW2FDZ.cjs → chunk-HMTHK2IY.cjs} +183 -148
  7. package/dist/chunk-HMTHK2IY.cjs.map +1 -0
  8. package/dist/{chunk-ACFPMIXO.js → chunk-RAEBT46G.js} +75 -40
  9. package/dist/chunk-RAEBT46G.js.map +1 -0
  10. package/dist/{chunk-FKSYSPJR.js → chunk-RUTGDMVR.js} +21 -20
  11. package/dist/chunk-RUTGDMVR.js.map +1 -0
  12. package/dist/{chunk-CVCDAHDW.cjs → chunk-UVEMRK5F.cjs} +189 -154
  13. package/dist/chunk-UVEMRK5F.cjs.map +1 -0
  14. package/dist/{export-BMvZq46v.d.ts → export-5hmOiU0J.d.cts} +194 -20
  15. package/dist/{export-CQNsJFh_.d.cts → export-BF9wW56f.d.ts} +194 -20
  16. package/dist/{export-llM6c7Do.d.ts → export-DVERZibl.d.cts} +194 -20
  17. package/dist/{export-55tHE0Bw.d.cts → export-w8sBcKXw.d.ts} +194 -20
  18. package/dist/index.cjs +12 -12
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +3 -3
  21. package/dist/index.d.ts +3 -3
  22. package/dist/index.js +3 -3
  23. package/dist/index.js.map +1 -1
  24. package/dist/node.cjs +33 -33
  25. package/dist/node.d.cts +2 -2
  26. package/dist/node.d.ts +2 -2
  27. package/dist/node.js +2 -2
  28. package/dist/{validate-EHuJC5QQ.d.cts → validate-B3uHoP8n.d.cts} +26 -38
  29. package/dist/{validate-EHuJC5QQ.d.ts → validate-B3uHoP8n.d.ts} +26 -38
  30. package/dist/web-api.cjs +33 -33
  31. package/dist/web-api.d.cts +2 -2
  32. package/dist/web-api.d.ts +2 -2
  33. package/dist/web-api.js +2 -2
  34. package/package.json +6 -7
  35. package/dist/chunk-3UX5MZ2P.cjs.map +0 -1
  36. package/dist/chunk-4MFF6V3R.js.map +0 -1
  37. package/dist/chunk-ACFPMIXO.js.map +0 -1
  38. package/dist/chunk-CVCDAHDW.cjs.map +0 -1
  39. package/dist/chunk-FKSYSPJR.js.map +0 -1
  40. package/dist/chunk-N2EW2FDZ.cjs.map +0 -1
package/README.md CHANGED
@@ -41,20 +41,20 @@ bun add cipher-kit@latest
41
41
  ## Quick Start 🚀
42
42
 
43
43
  ```typescript
44
- // Node.js Quick Start
44
+ // Node.js
45
45
  import { createSecretKey, encrypt, decrypt } from "cipher-kit/node";
46
46
 
47
- const nodeSecretKey = createSecretKey("my-passphrase");
48
- const encrypted = encrypt("Hello World!", nodeSecretKey);
49
- const decrypted = decrypt(encrypted, nodeSecretKey);
47
+ const secretKey = createSecretKey("my-passphrase");
48
+ const encrypted = encrypt("Hello World!", secretKey);
49
+ const decrypted = decrypt(encrypted, secretKey);
50
50
  console.log(decrypted); // "Hello World!"
51
51
 
52
- // Web Quick Start
52
+ // Web - including Deno, Bun, Cloudflare Workers
53
53
  import { createSecretKey, encrypt, decrypt } from "cipher-kit/web-api";
54
54
 
55
- const webSecretKey = await createSecretKey("my-passphrase");
56
- const encrypted = await encrypt("Hello World!", webSecretKey);
57
- const decrypted = await decrypt(encrypted, webSecretKey);
55
+ const secretKey = await createSecretKey("my-passphrase");
56
+ const encrypted = await encrypt("Hello World!", secretKey);
57
+ const decrypted = await decrypt(encrypted, secretKey);
58
58
  console.log(decrypted); // "Hello World!"
59
59
  ```
60
60
 
@@ -129,6 +129,7 @@ Encryption is the process of converting readable plaintext into unreadable ciphe
129
129
  #### _Secret Key Creation_ 🔑
130
130
 
131
131
  Before encrypting or decrypting data, you need to create a secret key.
132
+ The key must be at least 8 characters long.
132
133
 
133
134
  Each key is tied to a specific platform (Web or Node.js) and cannot be used interchangeably.
134
135
 
@@ -188,7 +189,7 @@ The function accepts an optional `options` parameter to customize the output enc
188
189
  ```typescript
189
190
  interface EncryptOptions {
190
191
  // Output ciphertext encoding(default: "base64url")
191
- encoding?: "base64url" | "base64" | "hex";
192
+ outputEncoding?: "base64url" | "base64" | "hex";
192
193
  }
193
194
  ```
194
195
 
@@ -217,7 +218,7 @@ Make sure to use the same encoding that was used during encryption.
217
218
  ```typescript
218
219
  interface DecryptOptions {
219
220
  // Input ciphertext encoding (default: "base64url")
220
- encoding?: "base64url" | "base64" | "hex";
221
+ inputEncoding?: "base64url" | "base64" | "hex";
221
222
  }
222
223
  ```
223
224
 
@@ -275,7 +276,7 @@ interface HashOptions {
275
276
  digest?: "sha256" | "sha384" | "sha512";
276
277
 
277
278
  // Output encoding (default: "base64url").
278
- encoding?: "base64url" | "base64" | "hex";
279
+ outputEncoding?: "base64url" | "base64" | "hex";
279
280
  }
280
281
  ```
281
282
 
@@ -309,19 +310,19 @@ To verify a password, the same hashing process is applied to the input password,
309
310
  // Node.js example
310
311
  import { hashPassword, verifyPassword } from "cipher-kit/node";
311
312
 
312
- const { hash, salt } = hashPassword("some-secure-password");
313
- console.log(`Hashed Password: ${hash}`);
313
+ const { result, salt } = hashPassword("some-secure-password");
314
+ console.log(`Hashed Password: ${result}`);
314
315
 
315
- const isMatch = verifyPassword("some-secure-password", hash, salt);
316
+ const isMatch = verifyPassword("some-secure-password", result, salt);
316
317
  console.log(`Password match: ${isMatch}`);
317
318
 
318
319
  // Web example
319
320
  import { hashPassword, verifyPassword } from "cipher-kit/web-api";
320
321
 
321
- const { hash, salt } = await hashPassword("some-secure-password");
322
- console.log(`Hashed Password: ${hash}`);
322
+ const { result, salt } = await hashPassword("some-secure-password");
323
+ console.log(`Hashed Password: ${result}`);
323
324
 
324
- const isMatch = await verifyPassword("some-secure-password", hash, salt);
325
+ const isMatch = await verifyPassword("some-secure-password", result, salt);
325
326
  console.log(`Password match: ${isMatch}`);
326
327
  ```
327
328
 
@@ -333,7 +334,7 @@ interface HashPasswordOptions {
333
334
  digest?: "sha256" | "sha384" | "sha512";
334
335
 
335
336
  // Encoding format for the output hash (default: "base64url").
336
- encoding?: "base64url" | "base64" | "hex";
337
+ outputEncoding?: "base64url" | "base64" | "hex";
337
338
 
338
339
  // Length of the salt in bytes (default: 16 bytes, min: 8 bytes).
339
340
  saltLength?: number;
@@ -350,7 +351,7 @@ interface VerifyPasswordOptions {
350
351
  digest?: "sha256" | "sha384" | "sha512";
351
352
 
352
353
  // Encoding format used during the original hashing (default: `'base64url'`).
353
- encoding?: "base64url" | "base64" | "hex";
354
+ inputEncoding?: "base64url" | "base64" | "hex";
354
355
 
355
356
  // Number of iterations used during the original hashing (default: `320000`).
356
357
  iterations?: number;
@@ -404,10 +405,10 @@ Regular expressions (regex) are sequences of characters that form search pattern
404
405
  Before decrypting, you can validate the format (decryption functions already validate internally).
405
406
 
406
407
  ```typescript
407
- import { ENCRYPTED_REGEX, matchPattern } from "cipher-kit"; // works in both "cipher-kit/web-api" and "cipher-kit/node"
408
+ import { ENCRYPTED_REGEX, matchEncryptedPattern } from "cipher-kit"; // works in both "cipher-kit/web-api" and "cipher-kit/node"
408
409
 
409
410
  function isEncryptedFormat(message: string): boolean {
410
- return matchPattern(message, "general"); // or "node" or "web"
411
+ return matchEncryptedPattern(message, "general"); // or "node" or "web"
411
412
  }
412
413
 
413
414
  // or
@@ -419,18 +420,15 @@ function isEncryptedFormat(message: string): boolean {
419
420
 
420
421
  ## Contributions 🤝
421
422
 
422
- Want to contribute or suggest a feature?
423
+ Want to contribute or suggest a feature or improvement?
423
424
 
424
425
  - Open an issue or feature request
425
426
  - Submit a PR to improve the packages or add new ones
426
427
  - Star ⭐ the repo if you like what you see
427
428
 
428
- ## License 📜
429
-
430
- This project is licensed under the [MIT License](https://opensource.org/licenses/MIT).
431
-
432
429
  <div align="center">
433
430
  <br/>
434
431
  <div style="font-size: 14px; font-weight:bold;"> ⚒️ Crafted carefully by <a href="https://github.com/WolfieLeader" target="_blank" rel="nofollow">WolfieLeader</a></div>
435
- <div style="font-size: 12px; font-style: italic;">Thank you!</div>
432
+ <p style="font-size: 12px; font-style: italic;">This project is licensed under the <a href="https://opensource.org/licenses/MIT" target="_blank" rel="nofollow">MIT License</a>.</p>
433
+ <div style="font-size: 12px; font-style: italic; font-weight: 600;">Thank you!</div>
436
434
  </div>
@@ -30,22 +30,22 @@ var ENCRYPTION_ALGORITHMS = Object.freeze({
30
30
  function $isStr(x, min = 1) {
31
31
  return x !== null && x !== void 0 && typeof x === "string" && x.trim().length >= min;
32
32
  }
33
- function $isObj(x) {
33
+ function $isPlainObj(x) {
34
34
  if (typeof x !== "object" || x === null || x === void 0) return false;
35
35
  const proto = Object.getPrototypeOf(x);
36
36
  return proto === Object.prototype || proto === null;
37
37
  }
38
- function $isLooseObj(x) {
38
+ function $isObj(x) {
39
39
  return typeof x === "object" && x !== null && x !== void 0;
40
40
  }
41
41
  var expectedKeys = /* @__PURE__ */ new Set(["platform", "digest", "algorithm", "key"]);
42
42
  function $isSecretKey(x, platform) {
43
- if (!$isLooseObj(x) || platform !== "node" && platform !== "web" || x.platform !== platform) return null;
43
+ if (!$isObj(x) || platform !== "node" && platform !== "web" || x.platform !== platform) return null;
44
44
  const keys = Object.keys(x);
45
45
  if (keys.length !== expectedKeys.size) return null;
46
46
  for (const key of keys) if (!expectedKeys.has(key)) return null;
47
47
  for (const key of expectedKeys) if (!Object.hasOwn(x, key)) return null;
48
- if (typeof x.digest !== "string" || !(x.digest in DIGEST_ALGORITHMS) || typeof x.algorithm !== "string" || !(x.algorithm in ENCRYPTION_ALGORITHMS) || !$isLooseObj(x.key) || x.key.type !== "secret") {
48
+ if (typeof x.digest !== "string" || !(x.digest in DIGEST_ALGORITHMS) || typeof x.algorithm !== "string" || !(x.algorithm in ENCRYPTION_ALGORITHMS) || !$isObj(x.key) || x.key.type !== "secret") {
49
49
  return null;
50
50
  }
51
51
  const algorithm = ENCRYPTION_ALGORITHMS[x.algorithm];
@@ -55,7 +55,7 @@ function $isSecretKey(x, platform) {
55
55
  }
56
56
  return Object.freeze({ ...x, injected: algorithm });
57
57
  }
58
- if (!$isLooseObj(x.key.algorithm) || x.key.algorithm.name !== algorithm.web || typeof x.key.algorithm.length === "number" && x.key.algorithm.length !== algorithm.keyBytes * 8 || typeof x.key.extractable !== "boolean" || !Array.isArray(x.key.usages) || x.key.usages.length !== 2 || !(x.key.usages.includes("encrypt") && x.key.usages.includes("decrypt"))) {
58
+ if (!$isObj(x.key.algorithm) || x.key.algorithm.name !== algorithm.web || typeof x.key.algorithm.length === "number" && x.key.algorithm.length !== algorithm.keyBytes * 8 || typeof x.key.extractable !== "boolean" || !Array.isArray(x.key.usages) || x.key.usages.length !== 2 || !(x.key.usages.includes("encrypt") && x.key.usages.includes("decrypt"))) {
59
59
  return null;
60
60
  }
61
61
  return Object.freeze({ ...x, injected: algorithm });
@@ -65,7 +65,7 @@ var ENCRYPTED_REGEX = Object.freeze({
65
65
  web: /^([^.]+)\.([^.]+)\.$/,
66
66
  general: /^([^.]+)\.([^.]+)(?:\.([^.]+))?\.$/
67
67
  });
68
- function matchPattern(data, format) {
68
+ function matchEncryptedPattern(data, format) {
69
69
  if (typeof data !== "string") return false;
70
70
  if (!(format in ENCRYPTED_REGEX)) throw new Error(`Unknown format: ${format}`);
71
71
  return ENCRYPTED_REGEX[format].test(data);
@@ -73,7 +73,7 @@ function matchPattern(data, format) {
73
73
 
74
74
  // src/helpers/error.ts
75
75
  function $ok(result) {
76
- if ($isObj(result)) return { success: true, ...result };
76
+ if ($isPlainObj(result)) return { success: true, ...result };
77
77
  return { success: true, result };
78
78
  }
79
79
  function $err(err) {
@@ -101,30 +101,31 @@ function title(platform, title2) {
101
101
  // src/helpers/object.ts
102
102
  function $stringifyObj(obj) {
103
103
  try {
104
- if (!$isObj(obj)) return $err({ msg: "Invalid object", desc: "Input is not a plain object" });
104
+ if (!$isPlainObj(obj)) return $err({ msg: "Invalid object", desc: "Input is not a plain object" });
105
105
  return $ok(JSON.stringify(obj));
106
106
  } catch (error) {
107
107
  return $err({ msg: "Utility: Stringify error", desc: $fmtError(error) });
108
108
  }
109
109
  }
110
- function tryStringifyObj(obj) {
111
- return $stringifyObj(obj);
112
- }
113
- function stringifyObj(obj) {
114
- const { result, error } = $stringifyObj(obj);
115
- if (error) throw new Error($fmtResultErr(error));
116
- return result;
117
- }
118
110
  function $parseToObj(str) {
119
111
  try {
120
112
  if (!$isStr(str)) return $err({ msg: "Utility: Invalid input", desc: "Input is not a valid string" });
121
113
  const obj = JSON.parse(str);
122
- if (!$isObj(obj)) return $err({ msg: "Utility: Invalid object format", desc: "Parsed data is not a plain object" });
114
+ if (!$isPlainObj(obj))
115
+ return $err({ msg: "Utility: Invalid object format", desc: "Parsed data is not a plain object" });
123
116
  return $ok({ result: obj });
124
117
  } catch (error) {
125
118
  return $err({ msg: "Utility: Invalid format", desc: $fmtError(error) });
126
119
  }
127
120
  }
121
+ function tryStringifyObj(obj) {
122
+ return $stringifyObj(obj);
123
+ }
124
+ function stringifyObj(obj) {
125
+ const { result, error } = $stringifyObj(obj);
126
+ if (error) throw new Error($fmtResultErr(error));
127
+ return result;
128
+ }
128
129
  function tryParseToObj(str) {
129
130
  return $parseToObj(str);
130
131
  }
@@ -137,6 +138,7 @@ function parseToObj(str) {
137
138
  exports.$err = $err;
138
139
  exports.$fmtError = $fmtError;
139
140
  exports.$fmtResultErr = $fmtResultErr;
141
+ exports.$isPlainObj = $isPlainObj;
140
142
  exports.$isSecretKey = $isSecretKey;
141
143
  exports.$isStr = $isStr;
142
144
  exports.$ok = $ok;
@@ -148,11 +150,11 @@ exports.ENCODING = ENCODING;
148
150
  exports.ENCRYPTED_REGEX = ENCRYPTED_REGEX;
149
151
  exports.ENCRYPTION_ALGORITHMS = ENCRYPTION_ALGORITHMS;
150
152
  exports.__export = __export;
151
- exports.matchPattern = matchPattern;
153
+ exports.matchEncryptedPattern = matchEncryptedPattern;
152
154
  exports.parseToObj = parseToObj;
153
155
  exports.stringifyObj = stringifyObj;
154
156
  exports.title = title;
155
157
  exports.tryParseToObj = tryParseToObj;
156
158
  exports.tryStringifyObj = tryStringifyObj;
157
- //# sourceMappingURL=chunk-3UX5MZ2P.cjs.map
158
- //# sourceMappingURL=chunk-3UX5MZ2P.cjs.map
159
+ //# sourceMappingURL=chunk-BHG5RSUV.cjs.map
160
+ //# sourceMappingURL=chunk-BHG5RSUV.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/helpers/consts.ts","../src/helpers/validate.ts","../src/helpers/error.ts","../src/helpers/object.ts"],"names":["nodeCrypto","title"],"mappings":"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","file":"chunk-BHG5RSUV.cjs","sourcesContent":["export const ENCODING = Object.freeze([\"base64\", \"base64url\", \"hex\", \"utf8\", \"latin1\"] as const);\r\n\r\nexport const CIPHER_ENCODING = Object.freeze([\"base64\", \"base64url\", \"hex\"] as const);\r\n\r\nexport const DIGEST_ALGORITHMS = Object.freeze({\r\n sha256: { node: \"sha256\", web: \"SHA-256\" },\r\n sha384: { node: \"sha384\", web: \"SHA-384\" },\r\n sha512: { node: \"sha512\", web: \"SHA-512\" },\r\n} as const);\r\n\r\nexport const ENCRYPTION_ALGORITHMS = Object.freeze({\r\n aes256gcm: { keyBytes: 32, ivLength: 12, node: \"aes-256-gcm\", web: \"AES-GCM\" },\r\n aes192gcm: { keyBytes: 24, ivLength: 12, node: \"aes-192-gcm\", web: \"AES-GCM\" },\r\n aes128gcm: { keyBytes: 16, ivLength: 12, node: \"aes-128-gcm\", web: \"AES-GCM\" },\r\n} as const);\r\n","import nodeCrypto from \"node:crypto\";\r\nimport type { SecretKey } from \"~/helpers/types\";\r\nimport { DIGEST_ALGORITHMS, ENCRYPTION_ALGORITHMS } from \"./consts\";\r\n\r\nexport function $isStr(x: unknown, min = 1): x is string {\r\n return x !== null && x !== undefined && typeof x === \"string\" && x.trim().length >= min;\r\n}\r\n\r\nexport function $isPlainObj<T extends object = Record<string, unknown>>(x: unknown): x is T {\r\n if (typeof x !== \"object\" || x === null || x === undefined) return false;\r\n const proto = Object.getPrototypeOf(x);\r\n return proto === Object.prototype || proto === null;\r\n}\r\n\r\nexport function $isObj(x: unknown): x is Record<string, unknown> {\r\n return typeof x === \"object\" && x !== null && x !== undefined;\r\n}\r\n\r\ntype InjectedSecretKey<Platform extends \"web\" | \"node\"> = SecretKey<Platform> & {\r\n readonly injected: (typeof ENCRYPTION_ALGORITHMS)[keyof typeof ENCRYPTION_ALGORITHMS];\r\n};\r\n\r\nconst expectedKeys = new Set([\"platform\", \"digest\", \"algorithm\", \"key\"]);\r\n\r\nexport function $isSecretKey<Platform extends \"node\" | \"web\">(\r\n x: unknown,\r\n platform: Platform,\r\n): InjectedSecretKey<Platform> | null {\r\n if (!$isObj(x) || (platform !== \"node\" && platform !== \"web\") || x.platform !== platform) return null;\r\n\r\n const keys = Object.keys(x);\r\n if (keys.length !== expectedKeys.size) return null;\r\n for (const key of keys) if (!expectedKeys.has(key)) return null;\r\n for (const key of expectedKeys) if (!Object.hasOwn(x, key)) return null;\r\n\r\n if (\r\n typeof x.digest !== \"string\" ||\r\n !(x.digest in DIGEST_ALGORITHMS) ||\r\n typeof x.algorithm !== \"string\" ||\r\n !(x.algorithm in ENCRYPTION_ALGORITHMS) ||\r\n !$isObj(x.key) ||\r\n x.key.type !== \"secret\"\r\n ) {\r\n return null;\r\n }\r\n\r\n const algorithm = ENCRYPTION_ALGORITHMS[x.algorithm as keyof typeof ENCRYPTION_ALGORITHMS];\r\n\r\n if (platform === \"node\") {\r\n if (\r\n !(x.key instanceof nodeCrypto.KeyObject) ||\r\n (typeof x.key.symmetricKeySize === \"number\" && x.key.symmetricKeySize !== algorithm.keyBytes)\r\n ) {\r\n return null;\r\n }\r\n return Object.freeze({ ...x, injected: algorithm }) as InjectedSecretKey<Platform>;\r\n }\r\n\r\n if (\r\n !$isObj(x.key.algorithm) ||\r\n x.key.algorithm.name !== algorithm.web ||\r\n (typeof x.key.algorithm.length === \"number\" && x.key.algorithm.length !== algorithm.keyBytes * 8) ||\r\n typeof x.key.extractable !== \"boolean\" ||\r\n !Array.isArray(x.key.usages) ||\r\n x.key.usages.length !== 2 ||\r\n !(x.key.usages.includes(\"encrypt\") && x.key.usages.includes(\"decrypt\"))\r\n ) {\r\n return null;\r\n }\r\n return Object.freeze({ ...x, injected: algorithm }) as InjectedSecretKey<Platform>;\r\n}\r\n\r\n/**\r\n * Regular expressions for encrypted data patterns.\r\n *\r\n * - **node**: `\"iv.cipher.tag.\"` (three dot-separated parts plus a trailing dot)\r\n * - **web**: `\"iv.cipherWithTag.\"` (two parts plus a trailing dot)\r\n * - **general**: accepts both shapes (2 or 3 parts) with a trailing dot\r\n *\r\n * Each part is any non-empty string without dots.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * You have a secret code you want to check. Before you check it,\r\n * you make sure it looks how a secret code should look.\r\n */\r\nexport const ENCRYPTED_REGEX = Object.freeze({\r\n node: /^([^.]+)\\.([^.]+)\\.([^.]+)\\.$/,\r\n web: /^([^.]+)\\.([^.]+)\\.$/,\r\n general: /^([^.]+)\\.([^.]+)(?:\\.([^.]+))?\\.$/,\r\n});\r\n\r\n/**\r\n * Checks if a string matches an expected encrypted payload shape.\r\n *\r\n * - **node**: `\"iv.cipher.tag.\"` (three dot-separated parts plus a trailing dot)\r\n * - **web**: `\"iv.cipherWithTag.\"` (two parts plus a trailing dot)\r\n * - **general**: accepts both shapes (2 or 3 parts) with a trailing dot\r\n *\r\n * Each part is any non-empty string without dots.\r\n *\r\n * This validates only the **shape**, not whether content is valid base64/hex, etc.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * You have a secret code you want to check. Before you check it,\r\n * you make sure it looks how a secret code should look.\r\n *\r\n * @param data - The string to test.\r\n * @param format - Which layout to check: `'node'`, `'web'`, or `'general'`.\r\n * @returns `true` if the string matches the pattern; otherwise `false`.\r\n * @throws {Error} If an unknown `format` is provided.\r\n *\r\n * @example\r\n * ```ts\r\n * matchEncryptedPattern(\"abc.def.ghi.\", \"node\"); // true\r\n * matchEncryptedPattern(\"abc.def.\", \"web\"); // true\r\n * matchEncryptedPattern(\"abc.def.\", \"node\"); // false\r\n * matchEncryptedPattern(\"abc.def.ghi.\", \"general\"); // true\r\n * ```\r\n */\r\nexport function matchEncryptedPattern(data: string, format: \"general\" | \"node\" | \"web\"): boolean {\r\n if (typeof data !== \"string\") return false;\r\n if (!(format in ENCRYPTED_REGEX)) throw new Error(`Unknown format: ${format}`);\r\n return ENCRYPTED_REGEX[format].test(data);\r\n}\r\n","import { $isPlainObj } from \"./validate\";\r\n\r\n/**\r\n * Standardized error object for the `Result` type.\r\n * Always has a brief `message` and a more detailed `description`.\r\n */\r\nexport interface ResultErr {\r\n readonly message: string;\r\n readonly description: string;\r\n}\r\n\r\n/**\r\n * Discriminated union for functions that can succeed or fail.\r\n *\r\n * - On **success**:\r\n * - If `T` is an object - properties of `T` are **spread** into the result\r\n * along with `success: true`.\r\n * - Otherwise - `{ success: true, result: T }`.\r\n * - On **failure**: `{ success: false, error: E }`.\r\n *\r\n * @example\r\n * ```ts\r\n * // Primitive result\r\n * function getNum(): Result<number> {\r\n * return $ok(42);\r\n * }\r\n * const r1 = getNum();\r\n * if (r1.success) console.log(r1.result); // 42\r\n *\r\n * // Object result (spread)\r\n * function getObject(): Result<{ name: string; age: number }> {\r\n * return $ok({ name: 'Alice', age: 30 });\r\n * }\r\n * const r2 = getObject();\r\n * if (r2.success) console.log(r2.name, r2.age); // 'Alice' 30\r\n * ```\r\n */\r\nexport type Result<T, E = ResultErr> = T extends object\r\n ?\r\n | ({ readonly [K in keyof T]: T[K] } & { readonly success: true; readonly error?: undefined })\r\n | ({ readonly [K in keyof T]?: undefined } & { readonly success: false; readonly error: E })\r\n :\r\n | { readonly success: true; readonly result: T; readonly error?: undefined }\r\n | { readonly success: false; readonly error: E; readonly result?: undefined };\r\n\r\nexport function $ok<T>(result?: T): Result<T> {\r\n if ($isPlainObj(result)) return { success: true, ...(result as T & object) } as Result<T>;\r\n return { success: true, result } as Result<T>;\r\n}\r\n\r\nexport function $err(err: { msg: string; desc: string }): Result<never, ResultErr>;\r\nexport function $err(err: ResultErr): Result<never, ResultErr>;\r\nexport function $err(err: { msg: string; desc: string } | ResultErr): Result<never, ResultErr> {\r\n return {\r\n success: false,\r\n error: {\r\n message: \"msg\" in err ? err.msg : err.message,\r\n description: \"desc\" in err ? err.desc : err.description,\r\n },\r\n } as Result<never, ResultErr>;\r\n}\r\n\r\nexport function $fmtError(error: unknown): string {\r\n if (typeof error === \"string\") return error;\r\n if (error instanceof Error) return error.message;\r\n return String(error);\r\n}\r\n\r\nexport function $fmtResultErr(err: ResultErr | undefined): string {\r\n if (!err) return \"Unknown error\";\r\n return `${err.message} - ${err.description}`;\r\n}\r\n\r\nexport function title(platform: \"web\" | \"node\", title: string): string {\r\n return `${platform === \"web\" ? \"Crypto Web API\" : \"Crypto NodeJS API\"} - ${title}`;\r\n}\r\n","import { $err, $fmtError, $fmtResultErr, $ok, type Result } from \"./error\";\r\nimport { $isPlainObj, $isStr } from \"./validate\";\r\n\r\nexport function $stringifyObj<T extends object = Record<string, unknown>>(obj: T): Result<string> {\r\n try {\r\n if (!$isPlainObj(obj)) return $err({ msg: \"Invalid object\", desc: \"Input is not a plain object\" });\r\n return $ok(JSON.stringify(obj));\r\n } catch (error) {\r\n return $err({ msg: \"Utility: Stringify error\", desc: $fmtError(error) });\r\n }\r\n}\r\n\r\nexport function $parseToObj<T extends object = Record<string, unknown>>(str: string): Result<{ result: T }> {\r\n try {\r\n if (!$isStr(str)) return $err({ msg: \"Utility: Invalid input\", desc: \"Input is not a valid string\" });\r\n const obj = JSON.parse(str);\r\n\r\n if (!$isPlainObj(obj))\r\n return $err({ msg: \"Utility: Invalid object format\", desc: \"Parsed data is not a plain object\" });\r\n return $ok({ result: obj as T });\r\n } catch (error) {\r\n return $err({ msg: \"Utility: Invalid format\", desc: $fmtError(error) });\r\n }\r\n}\r\n\r\n/**\r\n * Safely serializes a plain object to JSON without throwing.\r\n *\r\n * Wraps `JSON.stringify` and returns a `Result` containing the JSON string or an error.\r\n * Only plain objects (POJOs) are accepted. Class instances, Maps, Sets, etc. are rejected.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * You have a box of toys (your object) and take a photo of it (a JSON string)\r\n * so you can send it to a friend.\r\n *\r\n * @template T - Plain object type to serialize.\r\n * @param obj - The object to stringify (must be a plain object).\r\n * @returns A `Result` with the JSON string on success, or an error.\r\n *\r\n * @example\r\n * ```ts\r\n * const { result, error, success } = tryStringifyObj({ a: 1 });\r\n *\r\n * if (success) console.log(result); // \"{\\\"a\\\":1}\"\r\n * else console.error(error); // { message: \"...\", description: \"...\" }\r\n * ```\r\n */\r\nexport function tryStringifyObj<T extends object = Record<string, unknown>>(obj: T): Result<string> {\r\n return $stringifyObj(obj);\r\n}\r\n\r\n/**\r\n * Serializes a plain object to JSON (throwing).\r\n *\r\n * Wraps `JSON.stringify` and returns the result or throws an error.\r\n * Only plain objects (POJOs) are accepted. Class instances, Maps, Sets, etc. are rejected.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * You have a box of toys (your object) and take a photo of it (a JSON string)\r\n * so you can send it to a friend.\r\n *\r\n * @template T - Plain object type to serialize.\r\n * @param obj - The object to stringify (must be a plain object).\r\n * @returns JSON string representation of the object.\r\n * @throws {Error} If `obj` is not a plain object or serialization fails.\r\n *\r\n * @example\r\n * ```ts\r\n * const json = stringifyObj({ a: 1 }); // \"{\\\"a\\\":1}\"\r\n * ```\r\n */\r\nexport function stringifyObj<T extends object = Record<string, unknown>>(obj: T): string {\r\n const { result, error } = $stringifyObj(obj);\r\n if (error) throw new Error($fmtResultErr(error));\r\n return result;\r\n}\r\n\r\n/**\r\n * Safely parses a JSON string to a plain object (non-throwing).\r\n *\r\n * Wraps `JSON.parse` and returns a `Result` containing the parsed object, or an error.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * You rebuild your toy box (an object) from a photo you took (a JSON string).\r\n *\r\n * @template T - The expected object type.\r\n * @param str - The JSON string to parse.\r\n * @returns A `Result` with the parsed object on success, or an error.\r\n *\r\n * @example\r\n * ```ts\r\n * const {result, error, success} = tryParseToObj<{ a: number }>('{\"a\":1}');\r\n *\r\n * if (success) console.log(result); // { a: 1 }\r\n * else console.error(error) // { message: \"...\", description: \"...\" }\r\n * ```\r\n */\r\nexport function tryParseToObj<T extends object = Record<string, unknown>>(str: string): Result<{ result: T }> {\r\n return $parseToObj<T>(str);\r\n}\r\n\r\n/**\r\n * Parses a JSON string to a plain object (throwing).\r\n *\r\n * Wraps `JSON.parse` and returns the parsed object, or throws on failure.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * You rebuild your toy box (an object) from a photo you took (a JSON string).\r\n *\r\n * @template T - The expected object type.\r\n * @param str - The JSON string to parse.\r\n * @returns The parsed plain object.\r\n * @throws {Error} If the string can’t be parsed or doesn’t represent a plain object.\r\n *\r\n * @example\r\n * ```ts\r\n * const obj = parseToObj<{ a: number }>('{\"a\":1}'); // obj.a === 1\r\n * ```\r\n */\r\nexport function parseToObj<T extends object = Record<string, unknown>>(str: string): T {\r\n const { result, error } = $parseToObj<T>(str);\r\n if (error) throw new Error($fmtResultErr(error));\r\n return result;\r\n}\r\n"]}
@@ -1,4 +1,4 @@
1
- import { __export, $isSecretKey, $fmtResultErr, $ok, $err, $fmtError, title, $isStr, ENCRYPTION_ALGORITHMS, DIGEST_ALGORITHMS, CIPHER_ENCODING, matchPattern, $stringifyObj, $parseToObj, ENCODING } from './chunk-FKSYSPJR.js';
1
+ import { __export, $isSecretKey, $fmtResultErr, $ok, $err, $fmtError, title, $isStr, $isPlainObj, ENCRYPTION_ALGORITHMS, DIGEST_ALGORITHMS, CIPHER_ENCODING, matchEncryptedPattern, $stringifyObj, $parseToObj, ENCODING } from './chunk-RUTGDMVR.js';
2
2
 
3
3
  // src/web/kit.ts
4
4
  var kit_exports = {};
@@ -161,9 +161,18 @@ function $generateUuid() {
161
161
  return $err({ msg: `${title("web", "UUID Generation")}: Failed to generate UUID`, desc: $fmtError(error) });
162
162
  }
163
163
  }
164
- async function $createSecretKey(secret, options = {}) {
165
- if (!$isStr(secret)) {
166
- return $err({ msg: `${title("web", "Key Generation")}: Empty Secret`, desc: "Secret must be a non-empty string" });
164
+ async function $createSecretKey(secret, options) {
165
+ if (!$isStr(secret, 8)) {
166
+ return $err({
167
+ msg: `${title("web", "Key Generation")}: Empty Secret`,
168
+ desc: "Secret must be a non-empty string with at least 8 characters"
169
+ });
170
+ }
171
+ if (!$isPlainObj(options)) {
172
+ return $err({
173
+ msg: `${title("web", "Key Generation")}: Invalid options`,
174
+ desc: "Options must be an object"
175
+ });
167
176
  }
168
177
  const algorithm = options.algorithm ?? "aes256gcm";
169
178
  if (!(algorithm in ENCRYPTION_ALGORITHMS)) {
@@ -225,17 +234,23 @@ async function $createSecretKey(secret, options = {}) {
225
234
  });
226
235
  }
227
236
  }
228
- async function $encrypt(data, secretKey, options = {}) {
237
+ async function $encrypt(data, secretKey, options) {
229
238
  if (!$isStr(data)) {
230
239
  return $err({
231
240
  msg: `${title("web", "Encryption")}: Empty data for encryption`,
232
241
  desc: "Data must be a non-empty string"
233
242
  });
234
243
  }
235
- const encoding = options.encoding ?? "base64url";
236
- if (!CIPHER_ENCODING.includes(encoding)) {
244
+ if (!$isPlainObj(options)) {
237
245
  return $err({
238
- msg: `${title("web", "Encryption")}: Unsupported output encoding: ${encoding}`,
246
+ msg: `${title("web", "Encryption")}: Invalid options`,
247
+ desc: "Options must be an object"
248
+ });
249
+ }
250
+ const outputEncoding = options.outputEncoding ?? "base64url";
251
+ if (!CIPHER_ENCODING.includes(outputEncoding)) {
252
+ return $err({
253
+ msg: `${title("web", "Encryption")}: Unsupported output encoding: ${outputEncoding}`,
239
254
  desc: "Use base64, base64url, or hex"
240
255
  });
241
256
  }
@@ -255,8 +270,8 @@ async function $encrypt(data, secretKey, options = {}) {
255
270
  injectedKey.key,
256
271
  result
257
272
  );
258
- const ivStr = $convertBytesToStr(iv, encoding);
259
- const cipherStr = $convertBytesToStr(cipherWithTag, encoding);
273
+ const ivStr = $convertBytesToStr(iv, outputEncoding);
274
+ const cipherStr = $convertBytesToStr(cipherWithTag, outputEncoding);
260
275
  if (ivStr.error || cipherStr.error) {
261
276
  return $err({
262
277
  msg: `${title("web", "Encryption")}: Failed to convert IV or encrypted data`,
@@ -268,17 +283,23 @@ async function $encrypt(data, secretKey, options = {}) {
268
283
  return $err({ msg: `${title("web", "Encryption")}: Failed to encrypt data`, desc: $fmtError(error2) });
269
284
  }
270
285
  }
271
- async function $decrypt(encrypted, secretKey, options = {}) {
272
- if (matchPattern(encrypted, "web") === false) {
286
+ async function $decrypt(encrypted, secretKey, options) {
287
+ if (!matchEncryptedPattern(encrypted, "web")) {
273
288
  return $err({
274
289
  msg: `${title("web", "Decryption")}: Invalid encrypted data format`,
275
290
  desc: 'Encrypted data must be in the format "iv.cipherWithTag."'
276
291
  });
277
292
  }
278
- const encoding = options.encoding ?? "base64url";
279
- if (!CIPHER_ENCODING.includes(encoding)) {
293
+ if (!$isPlainObj(options)) {
280
294
  return $err({
281
- msg: `${title("web", "Decryption")}: Unsupported input encoding: ${encoding}`,
295
+ msg: `${title("web", "Decryption")}: Invalid options`,
296
+ desc: "Options must be an object"
297
+ });
298
+ }
299
+ const inputEncoding = options.inputEncoding ?? "base64url";
300
+ if (!CIPHER_ENCODING.includes(inputEncoding)) {
301
+ return $err({
302
+ msg: `${title("web", "Decryption")}: Unsupported input encoding: ${inputEncoding}`,
282
303
  desc: "Use base64, base64url, or hex"
283
304
  });
284
305
  }
@@ -296,8 +317,8 @@ async function $decrypt(encrypted, secretKey, options = {}) {
296
317
  desc: "Expected a Web SecretKey"
297
318
  });
298
319
  }
299
- const ivBytes = $convertStrToBytes(iv, encoding);
300
- const cipherWithTagBytes = $convertStrToBytes(encryptedWithTag, encoding);
320
+ const ivBytes = $convertStrToBytes(iv, inputEncoding);
321
+ const cipherWithTagBytes = $convertStrToBytes(encryptedWithTag, inputEncoding);
301
322
  if (ivBytes.error || cipherWithTagBytes.error) {
302
323
  return $err({
303
324
  msg: `${title("web", "Decryption")}: Failed to convert IV or encrypted data`,
@@ -315,24 +336,30 @@ async function $decrypt(encrypted, secretKey, options = {}) {
315
336
  return $err({ msg: `${title("web", "Decryption")}: Failed to decrypt data`, desc: $fmtError(error) });
316
337
  }
317
338
  }
318
- async function $encryptObj(data, secretKey, options = {}) {
339
+ async function $encryptObj(data, secretKey, options) {
319
340
  const { result, error } = $stringifyObj(data);
320
341
  if (error) return $err(error);
321
342
  return await $encrypt(result, secretKey, options);
322
343
  }
323
- async function $decryptObj(encrypted, secretKey, options = {}) {
344
+ async function $decryptObj(encrypted, secretKey, options) {
324
345
  const { result, error } = await $decrypt(encrypted, secretKey, options);
325
346
  if (error) return $err(error);
326
347
  return $parseToObj(result);
327
348
  }
328
- async function $hash(data, options = {}) {
349
+ async function $hash(data, options) {
329
350
  if (!$isStr(data)) {
330
351
  return $err({ msg: `${title("web", "Hashing")}: Empty data for hashing`, desc: "Data must be a non-empty string" });
331
352
  }
332
- const encoding = options.encoding ?? "base64url";
333
- if (!CIPHER_ENCODING.includes(encoding)) {
353
+ if (!$isPlainObj(options)) {
334
354
  return $err({
335
- msg: `${title("web", "Hashing")}: Unsupported output encoding: ${encoding}`,
355
+ msg: `${title("web", "Hashing")}: Invalid options`,
356
+ desc: "Options must be an object"
357
+ });
358
+ }
359
+ const outputEncoding = options.outputEncoding ?? "base64url";
360
+ if (!CIPHER_ENCODING.includes(outputEncoding)) {
361
+ return $err({
362
+ msg: `${title("web", "Hashing")}: Unsupported output encoding: ${outputEncoding}`,
336
363
  desc: "Use base64, base64url, or hex"
337
364
  });
338
365
  }
@@ -348,18 +375,24 @@ async function $hash(data, options = {}) {
348
375
  if (error) return $err(error);
349
376
  try {
350
377
  const hashed = await crypto.subtle.digest(digestAlgo.web, result);
351
- return $convertBytesToStr(hashed, encoding);
378
+ return $convertBytesToStr(hashed, outputEncoding);
352
379
  } catch (error2) {
353
380
  return $err({ msg: `${title("web", "Hashing")}: Failed to hash data`, desc: $fmtError(error2) });
354
381
  }
355
382
  }
356
- async function $hashPassword(password, options = {}) {
383
+ async function $hashPassword(password, options) {
357
384
  if (!$isStr(password)) {
358
385
  return $err({
359
386
  msg: `${title("web", "Password Hashing")}: Empty password`,
360
387
  desc: "Password must be a non-empty string"
361
388
  });
362
389
  }
390
+ if (!$isPlainObj(options)) {
391
+ return $err({
392
+ msg: `${title("web", "Password Hashing")}: Invalid options`,
393
+ desc: "Options must be an object"
394
+ });
395
+ }
363
396
  const digest = options.digest ?? "sha512";
364
397
  if (!(digest in DIGEST_ALGORITHMS)) {
365
398
  return $err({
@@ -368,10 +401,10 @@ async function $hashPassword(password, options = {}) {
368
401
  });
369
402
  }
370
403
  const digestAlgo = DIGEST_ALGORITHMS[digest];
371
- const encoding = options.encoding ?? "base64url";
372
- if (!CIPHER_ENCODING.includes(encoding)) {
404
+ const outputEncoding = options.outputEncoding ?? "base64url";
405
+ if (!CIPHER_ENCODING.includes(outputEncoding)) {
373
406
  return $err({
374
- msg: `${title("web", "Password Hashing")}: Unsupported output encoding: ${encoding}`,
407
+ msg: `${title("web", "Password Hashing")}: Unsupported output encoding: ${outputEncoding}`,
375
408
  desc: "Use base64, base64url, or hex"
376
409
  });
377
410
  }
@@ -410,29 +443,31 @@ async function $hashPassword(password, options = {}) {
410
443
  baseKey,
411
444
  keyLength * 8
412
445
  );
413
- const saltStr = $convertBytesToStr(salt, encoding);
446
+ const saltStr = $convertBytesToStr(salt, outputEncoding);
414
447
  if (saltStr.error) return $err(saltStr.error);
415
- const hashedPasswordStr = $convertBytesToStr(bits, encoding);
448
+ const hashedPasswordStr = $convertBytesToStr(bits, outputEncoding);
416
449
  if (hashedPasswordStr.error) return $err(hashedPasswordStr.error);
417
- return $ok({ hash: hashedPasswordStr.result, salt: saltStr.result });
450
+ return $ok({ result: hashedPasswordStr.result, salt: saltStr.result });
418
451
  } catch (error) {
419
452
  return $err({ msg: `${title("web", "Password Hashing")}: Failed to hash password`, desc: $fmtError(error) });
420
453
  }
421
454
  }
422
- async function $verifyPassword(password, hashedPassword, salt, options = {}) {
423
- if (!$isStr(password) || !$isStr(hashedPassword) || !$isStr(salt)) return false;
455
+ async function $verifyPassword(password, hashedPassword, salt, options) {
456
+ if (!$isStr(password) || !$isStr(hashedPassword) || !$isStr(salt) || !$isPlainObj(options)) {
457
+ return false;
458
+ }
424
459
  const digest = options.digest ?? "sha512";
425
460
  if (!(digest in DIGEST_ALGORITHMS)) return false;
426
461
  const digestAlgo = DIGEST_ALGORITHMS[digest];
427
- const encoding = options.encoding ?? "base64url";
428
- if (!CIPHER_ENCODING.includes(encoding)) return false;
462
+ const inputEncoding = options.inputEncoding ?? "base64url";
463
+ if (!CIPHER_ENCODING.includes(inputEncoding)) return false;
429
464
  const iterations = options.iterations ?? 32e4;
430
465
  if (typeof iterations !== "number" || iterations < 1e3) return false;
431
466
  const keyLength = options.keyLength ?? 64;
432
467
  if (typeof keyLength !== "number" || keyLength < 16) return false;
433
- const saltBytes = $convertStrToBytes(salt, encoding);
468
+ const saltBytes = $convertStrToBytes(salt, inputEncoding);
434
469
  if (saltBytes.error) return false;
435
- const hashedPasswordBytes = $convertStrToBytes(hashedPassword, encoding);
470
+ const hashedPasswordBytes = $convertStrToBytes(hashedPassword, inputEncoding);
436
471
  if (hashedPasswordBytes.error) return false;
437
472
  try {
438
473
  const baseKey = await crypto.subtle.importKey(
@@ -530,9 +565,9 @@ async function tryHashPassword(password, options = {}) {
530
565
  return await $hashPassword(password, options);
531
566
  }
532
567
  async function hashPassword(password, options = {}) {
533
- const { hash: hash2, salt, error } = await $hashPassword(password, options);
568
+ const { result, salt, error } = await $hashPassword(password, options);
534
569
  if (error) throw new Error($fmtResultErr(error));
535
- return { hash: hash2, salt };
570
+ return { result, salt };
536
571
  }
537
572
  async function verifyPassword(password, hashedPassword, salt, options = {}) {
538
573
  return await $verifyPassword(password, hashedPassword, salt, options);
@@ -563,5 +598,5 @@ function convertEncoding(data, from, to) {
563
598
  }
564
599
 
565
600
  export { convertBytesToStr, convertEncoding, convertStrToBytes, createSecretKey, decrypt, decryptObj, encrypt, encryptObj, generateUuid, hash, hashPassword, isWebSecretKey, kit_exports, tryConvertBytesToStr, tryConvertEncoding, tryConvertStrToBytes, tryCreateSecretKey, tryDecrypt, tryDecryptObj, tryEncrypt, tryEncryptObj, tryGenerateUuid, tryHash, tryHashPassword, verifyPassword };
566
- //# sourceMappingURL=chunk-4MFF6V3R.js.map
567
- //# sourceMappingURL=chunk-4MFF6V3R.js.map
601
+ //# sourceMappingURL=chunk-CRTOKS3Q.js.map
602
+ //# sourceMappingURL=chunk-CRTOKS3Q.js.map