@gjsify/webcrypto 0.3.12 → 0.3.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/esm/util.js CHANGED
@@ -1,133 +1,127 @@
1
1
  import { DOMException } from "@gjsify/dom-exception";
2
+
3
+ //#region src/util.ts
4
+ /** Normalize algorithm identifier to {name: string, ...} form */
2
5
  function normalizeAlgorithm(algorithm) {
3
- if (typeof algorithm === "string") {
4
- return { name: algorithm };
5
- }
6
- if (!algorithm || typeof algorithm.name !== "string") {
7
- throw new TypeError("Algorithm must have a name property");
8
- }
9
- return algorithm;
6
+ if (typeof algorithm === "string") {
7
+ return { name: algorithm };
8
+ }
9
+ if (!algorithm || typeof algorithm.name !== "string") {
10
+ throw new TypeError("Algorithm must have a name property");
11
+ }
12
+ return algorithm;
10
13
  }
14
+ /** Map WebCrypto algorithm names to Node.js crypto names */
11
15
  const HASH_NAMES = {
12
- "SHA-1": "sha1",
13
- "SHA-256": "sha256",
14
- "SHA-384": "sha384",
15
- "SHA-512": "sha512"
16
+ "SHA-1": "sha1",
17
+ "SHA-256": "sha256",
18
+ "SHA-384": "sha384",
19
+ "SHA-512": "sha512"
16
20
  };
17
21
  function toNodeHashName(name) {
18
- const resolved = HASH_NAMES[name.toUpperCase()] || HASH_NAMES[name];
19
- if (!resolved) {
20
- throw new DOMException(`Unrecognized hash name: ${name}`, "NotSupportedError");
21
- }
22
- return resolved;
22
+ const resolved = HASH_NAMES[name.toUpperCase()] || HASH_NAMES[name];
23
+ if (!resolved) {
24
+ throw new DOMException(`Unrecognized hash name: ${name}`, "NotSupportedError");
25
+ }
26
+ return resolved;
23
27
  }
24
28
  function toWebCryptoHashName(name) {
25
- const upper = name.toUpperCase().replace(/[^A-Z0-9]/g, "");
26
- for (const [web, node] of Object.entries(HASH_NAMES)) {
27
- if (node === name || upper === web.replace("-", "")) return web;
28
- }
29
- throw new DOMException(`Unrecognized hash name: ${name}`, "NotSupportedError");
29
+ const upper = name.toUpperCase().replace(/[^A-Z0-9]/g, "");
30
+ for (const [web, node] of Object.entries(HASH_NAMES)) {
31
+ if (node === name || upper === web.replace("-", "")) return web;
32
+ }
33
+ throw new DOMException(`Unrecognized hash name: ${name}`, "NotSupportedError");
30
34
  }
35
+ /** Map WebCrypto curve names to Node.js crypto names */
31
36
  const CURVE_NAMES = {
32
- "P-256": "prime256v1",
33
- "P-384": "secp384r1",
34
- "P-521": "secp521r1"
37
+ "P-256": "prime256v1",
38
+ "P-384": "secp384r1",
39
+ "P-521": "secp521r1"
35
40
  };
36
41
  function toNodeCurveName(name) {
37
- const resolved = CURVE_NAMES[name];
38
- if (!resolved) {
39
- throw new DOMException(`Unrecognized curve name: ${name}`, "NotSupportedError");
40
- }
41
- return resolved;
42
+ const resolved = CURVE_NAMES[name];
43
+ if (!resolved) {
44
+ throw new DOMException(`Unrecognized curve name: ${name}`, "NotSupportedError");
45
+ }
46
+ return resolved;
42
47
  }
48
+ /** Get hash output size in bytes */
43
49
  function hashSize(hash) {
44
- switch (toNodeHashName(hash)) {
45
- case "sha1":
46
- return 20;
47
- case "sha256":
48
- return 32;
49
- case "sha384":
50
- return 48;
51
- case "sha512":
52
- return 64;
53
- default:
54
- throw new DOMException(`Unsupported hash: ${hash}`, "NotSupportedError");
55
- }
50
+ switch (toNodeHashName(hash)) {
51
+ case "sha1": return 20;
52
+ case "sha256": return 32;
53
+ case "sha384": return 48;
54
+ case "sha512": return 64;
55
+ default: throw new DOMException(`Unsupported hash: ${hash}`, "NotSupportedError");
56
+ }
56
57
  }
58
+ /** Validate key usages */
57
59
  function validateUsages(usages, allowed) {
58
- for (const usage of usages) {
59
- if (!allowed.includes(usage)) {
60
- throw new DOMException(`Invalid key usage: ${usage}`, "SyntaxError");
61
- }
62
- }
63
- if (usages.length === 0) {
64
- throw new DOMException("Key usages must not be empty", "SyntaxError");
65
- }
60
+ for (const usage of usages) {
61
+ if (!allowed.includes(usage)) {
62
+ throw new DOMException(`Invalid key usage: ${usage}`, "SyntaxError");
63
+ }
64
+ }
65
+ if (usages.length === 0) {
66
+ throw new DOMException("Key usages must not be empty", "SyntaxError");
67
+ }
66
68
  }
69
+ /** Check key has required usage */
67
70
  function checkUsage(key, required) {
68
- if (!key.usages.includes(required)) {
69
- throw new DOMException(
70
- `Key does not support the '${required}' usage`,
71
- "InvalidAccessError"
72
- );
73
- }
71
+ if (!key.usages.includes(required)) {
72
+ throw new DOMException(`Key does not support the '${required}' usage`, "InvalidAccessError");
73
+ }
74
74
  }
75
75
  const B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
76
76
  const B64_LOOKUP = new Uint8Array(128);
77
77
  for (let i = 0; i < B64_CHARS.length; i++) B64_LOOKUP[B64_CHARS.charCodeAt(i)] = i;
78
78
  function bytesToBase64(bytes) {
79
- let result = "";
80
- const len = bytes.length;
81
- for (let i = 0; i < len; i += 3) {
82
- const b0 = bytes[i];
83
- const b1 = i + 1 < len ? bytes[i + 1] : 0;
84
- const b2 = i + 2 < len ? bytes[i + 2] : 0;
85
- result += B64_CHARS[b0 >> 2 & 63];
86
- result += B64_CHARS[(b0 << 4 | b1 >> 4) & 63];
87
- result += i + 1 < len ? B64_CHARS[(b1 << 2 | b2 >> 6) & 63] : "=";
88
- result += i + 2 < len ? B64_CHARS[b2 & 63] : "=";
89
- }
90
- return result;
79
+ let result = "";
80
+ const len = bytes.length;
81
+ for (let i = 0; i < len; i += 3) {
82
+ const b0 = bytes[i];
83
+ const b1 = i + 1 < len ? bytes[i + 1] : 0;
84
+ const b2 = i + 2 < len ? bytes[i + 2] : 0;
85
+ result += B64_CHARS[b0 >> 2 & 63];
86
+ result += B64_CHARS[(b0 << 4 | b1 >> 4) & 63];
87
+ result += i + 1 < len ? B64_CHARS[(b1 << 2 | b2 >> 6) & 63] : "=";
88
+ result += i + 2 < len ? B64_CHARS[b2 & 63] : "=";
89
+ }
90
+ return result;
91
91
  }
92
92
  function base64ToBytes(str) {
93
- let s = str;
94
- while (s.endsWith("=")) s = s.slice(0, -1);
95
- const out = [];
96
- let bits = 0;
97
- let val = 0;
98
- for (let i = 0; i < s.length; i++) {
99
- val = val << 6 | B64_LOOKUP[s.charCodeAt(i)];
100
- bits += 6;
101
- if (bits >= 8) {
102
- bits -= 8;
103
- out.push(val >> bits & 255);
104
- }
105
- }
106
- return new Uint8Array(out);
93
+ let s = str;
94
+ while (s.endsWith("=")) s = s.slice(0, -1);
95
+ const out = [];
96
+ let bits = 0;
97
+ let val = 0;
98
+ for (let i = 0; i < s.length; i++) {
99
+ val = val << 6 | B64_LOOKUP[s.charCodeAt(i)];
100
+ bits += 6;
101
+ if (bits >= 8) {
102
+ bits -= 8;
103
+ out.push(val >> bits & 255);
104
+ }
105
+ }
106
+ return new Uint8Array(out);
107
107
  }
108
+ /** Base64url encode */
108
109
  function base64urlEncode(data) {
109
- return bytesToBase64(data).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
110
+ return bytesToBase64(data).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
110
111
  }
112
+ /** Base64url decode */
111
113
  function base64urlDecode(str) {
112
- let s = str.replace(/-/g, "+").replace(/_/g, "/");
113
- while (s.length % 4) s += "=";
114
- return base64ToBytes(s);
114
+ let s = str.replace(/-/g, "+").replace(/_/g, "/");
115
+ while (s.length % 4) s += "=";
116
+ return base64ToBytes(s);
115
117
  }
118
+ /** Convert ArrayBuffer or view to Uint8Array */
116
119
  function toUint8Array(data) {
117
- if (data instanceof Uint8Array) return data;
118
- if (data instanceof ArrayBuffer) return new Uint8Array(data);
119
- if (ArrayBuffer.isView(data)) return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
120
- throw new TypeError("Expected BufferSource");
120
+ if (data instanceof Uint8Array) return data;
121
+ if (data instanceof ArrayBuffer) return new Uint8Array(data);
122
+ if (ArrayBuffer.isView(data)) return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
123
+ throw new TypeError("Expected BufferSource");
121
124
  }
122
- export {
123
- base64urlDecode,
124
- base64urlEncode,
125
- checkUsage,
126
- hashSize,
127
- normalizeAlgorithm,
128
- toNodeCurveName,
129
- toNodeHashName,
130
- toUint8Array,
131
- toWebCryptoHashName,
132
- validateUsages
133
- };
125
+
126
+ //#endregion
127
+ export { base64urlDecode, base64urlEncode, checkUsage, hashSize, normalizeAlgorithm, toNodeCurveName, toNodeHashName, toUint8Array, toWebCryptoHashName, validateUsages };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/webcrypto",
3
- "version": "0.3.12",
3
+ "version": "0.3.14",
4
4
  "description": "W3C WebCrypto API (SubtleCrypto) for GJS using @gjsify/crypto primitives",
5
5
  "type": "module",
6
6
  "module": "lib/esm/index.js",
@@ -41,11 +41,11 @@
41
41
  "crypto"
42
42
  ],
43
43
  "dependencies": {
44
- "@gjsify/dom-exception": "^0.3.12"
44
+ "@gjsify/dom-exception": "^0.3.14"
45
45
  },
46
46
  "devDependencies": {
47
- "@gjsify/cli": "^0.3.12",
48
- "@gjsify/unit": "^0.3.12",
47
+ "@gjsify/cli": "^0.3.14",
48
+ "@gjsify/unit": "^0.3.14",
49
49
  "@types/node": "^25.6.0",
50
50
  "typescript": "^6.0.3"
51
51
  }