@gr4vy/sdk 1.10.17 → 2.0.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.
package/jsr.json CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  {
4
4
  "name": "@gr4vy/sdk",
5
- "version": "1.10.17",
5
+ "version": "2.0.0",
6
6
  "exports": {
7
7
  ".": "./src/index.ts",
8
8
  "./models/errors": "./src/models/errors/index.ts",
package/lib/config.d.ts CHANGED
@@ -44,8 +44,8 @@ export declare function serverURLFromOptions(options: SDKOptions): URL | null;
44
44
  export declare const SDK_METADATA: {
45
45
  readonly language: "typescript";
46
46
  readonly openapiDocVersion: "1.0.0";
47
- readonly sdkVersion: "1.10.17";
48
- readonly genVersion: "2.856.1";
49
- readonly userAgent: "speakeasy-sdk/typescript 1.10.17 2.856.1 1.0.0 @gr4vy/sdk";
47
+ readonly sdkVersion: "2.0.0";
48
+ readonly genVersion: "2.858.2";
49
+ readonly userAgent: "speakeasy-sdk/typescript 2.0.0 2.858.2 1.0.0 @gr4vy/sdk";
50
50
  };
51
51
  //# sourceMappingURL=config.d.ts.map
package/lib/config.js CHANGED
@@ -37,8 +37,8 @@ function serverURLFromOptions(options) {
37
37
  exports.SDK_METADATA = {
38
38
  language: "typescript",
39
39
  openapiDocVersion: "1.0.0",
40
- sdkVersion: "1.10.17",
41
- genVersion: "2.856.1",
42
- userAgent: "speakeasy-sdk/typescript 1.10.17 2.856.1 1.0.0 @gr4vy/sdk",
40
+ sdkVersion: "2.0.0",
41
+ genVersion: "2.858.2",
42
+ userAgent: "speakeasy-sdk/typescript 2.0.0 2.858.2 1.0.0 @gr4vy/sdk",
43
43
  };
44
44
  //# sourceMappingURL=config.js.map
package/lib/config.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/lib/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAkDH,oDAsBC;AAnED,qCAA8C;AAEjC,QAAA,aAAa,GAAG,SAAS,CAAC;AAC1B,QAAA,gBAAgB,GAAG,YAAY,CAAC;AAC7C;;GAEG;AACU,QAAA,UAAU,GAAG;IACxB,CAAC,qBAAa,CAAC,EAAE,oCAAoC;IACrD,CAAC,wBAAgB,CAAC,EAAE,4BAA4B;CACxC,CAAC;AAmCX,SAAgB,oBAAoB,CAAC,OAAmB;IACtD,IAAI,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAElC,MAAM,YAAY,GAA2B;QAC3C,SAAS,EAAE;YACT,IAAI,EAAE,OAAO,CAAC,EAAE,IAAI,SAAS;SAC9B;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,OAAO,CAAC,EAAE,IAAI,SAAS;SAC9B;KACF,CAAC;IAEF,IAAI,MAAM,GAAW,EAAE,CAAC;IAExB,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,qBAAa,CAAC;QAC/C,SAAS,GAAG,kBAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACtC,CAAC;IAED,MAAM,CAAC,GAAG,IAAA,mBAAU,EAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;IACxC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAEY,QAAA,YAAY,GAAG;IAC1B,QAAQ,EAAE,YAAY;IACtB,iBAAiB,EAAE,OAAO;IAC1B,UAAU,EAAE,SAAS;IACrB,UAAU,EAAE,SAAS;IACrB,SAAS,EAAE,2DAA2D;CAC9D,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/lib/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAkDH,oDAsBC;AAnED,qCAA8C;AAEjC,QAAA,aAAa,GAAG,SAAS,CAAC;AAC1B,QAAA,gBAAgB,GAAG,YAAY,CAAC;AAC7C;;GAEG;AACU,QAAA,UAAU,GAAG;IACxB,CAAC,qBAAa,CAAC,EAAE,oCAAoC;IACrD,CAAC,wBAAgB,CAAC,EAAE,4BAA4B;CACxC,CAAC;AAmCX,SAAgB,oBAAoB,CAAC,OAAmB;IACtD,IAAI,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAElC,MAAM,YAAY,GAA2B;QAC3C,SAAS,EAAE;YACT,IAAI,EAAE,OAAO,CAAC,EAAE,IAAI,SAAS;SAC9B;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,OAAO,CAAC,EAAE,IAAI,SAAS;SAC9B;KACF,CAAC;IAEF,IAAI,MAAM,GAAW,EAAE,CAAC;IAExB,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,qBAAa,CAAC;QAC/C,SAAS,GAAG,kBAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACtC,CAAC;IAED,MAAM,CAAC,GAAG,IAAA,mBAAU,EAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;IACxC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAEY,QAAA,YAAY,GAAG;IAC1B,QAAQ,EAAE,YAAY;IACtB,iBAAiB,EAAE,OAAO;IAC1B,UAAU,EAAE,OAAO;IACnB,UAAU,EAAE,SAAS;IACrB,SAAS,EAAE,yDAAyD;CAC5D,CAAC"}
package/lib/helpers.d.ts CHANGED
@@ -1,12 +1,29 @@
1
1
  /**
2
- * Attempts to detect the JS runtime and its version based on available globals.
2
+ * Best-effort runtime identification used for SDK metadata/user-agent strings.
3
+ *
4
+ * The function prefers browser-style detection via `navigator.userAgent` and
5
+ * falls back to Node.js `process.version` when available.
6
+ *
7
+ * @returns A runtime identifier string, or `"<unknown-runtime>"` when not detectable.
3
8
  */
4
9
  export declare function getRuntime(): string;
5
10
  /**
6
- * Calculate the Key ID
11
+ * Derives JWT `kid` from a private key using an RFC 7638 JWK thumbprint.
12
+ *
13
+ * Expected key format:
14
+ * - PKCS#8 PEM-encoded private key
15
+ * - EC P-521 curve (matches ES512 signing)
16
+ *
17
+ * Steps:
18
+ * 1. Decode PEM to PKCS#8 DER bytes.
19
+ * 2. Import key through Web Crypto.
20
+ * 3. Export as JWK and validate required fields.
21
+ * 4. Hash the canonical RFC 7638 thumbprint input with SHA-256.
22
+ * 5. Return base64url encoded digest.
23
+ *
24
+ * @param privateKey PEM-encoded PKCS#8 EC private key.
25
+ * @returns The base64url-encoded JWK thumbprint used as JWT `kid`.
26
+ * @throws If key parsing/import/export/validation/digest fails.
7
27
  */
8
28
  export declare function getKeyId(privateKey: string): Promise<string>;
9
- export declare function stripUndefined<T extends {}>(obj: T): {
10
- [K in keyof T]?: Exclude<T[K], undefined>;
11
- };
12
29
  //# sourceMappingURL=helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/lib/helpers.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,wBAAgB,UAAU,WAsBzB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAalE;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,EAAE,EACzC,GAAG,EAAE,CAAC,GACL;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC;CAAE,CAa/C"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/lib/helpers.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,wBAAgB,UAAU,WAsBzB;AAyDD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkElE"}
package/lib/helpers.js CHANGED
@@ -1,15 +1,15 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.getRuntime = getRuntime;
7
4
  exports.getKeyId = getKeyId;
8
- exports.stripUndefined = stripUndefined;
9
- const keyto_1 = __importDefault(require("@trust/keyto"));
10
- const jwk_thumbprint_1 = require("jwk-thumbprint");
5
+ const base64_1 = require("./base64");
11
6
  /**
12
- * Attempts to detect the JS runtime and its version based on available globals.
7
+ * Best-effort runtime identification used for SDK metadata/user-agent strings.
8
+ *
9
+ * The function prefers browser-style detection via `navigator.userAgent` and
10
+ * falls back to Node.js `process.version` when available.
11
+ *
12
+ * @returns A runtime identifier string, or `"<unknown-runtime>"` when not detectable.
13
13
  */
14
14
  function getRuntime() {
15
15
  if (typeof navigator !== "undefined" &&
@@ -28,26 +28,115 @@ function getRuntime() {
28
28
  }
29
29
  return "<unknown-runtime>";
30
30
  }
31
+ let cachedWebCrypto;
31
32
  /**
32
- * Calculate the Key ID
33
+ * Resolves a Web Crypto implementation across supported runtimes.
34
+ *
35
+ * Resolution order:
36
+ * 1. `globalThis.crypto` when already exposed by the runtime.
37
+ * 2. Node.js fallback via `node:crypto`.webcrypto (important for some Node 18 setups).
38
+ *
39
+ * @returns A Web Crypto compatible `Crypto` object with `subtle` APIs.
40
+ * @throws If no Web Crypto implementation is available.
33
41
  */
34
- async function getKeyId(privateKey) {
35
- const jwk = keyto_1.default.from(privateKey, "pem").toJwk("private");
36
- const keyid = (0, jwk_thumbprint_1.jwkThumbprintByEncoding)(stripUndefined(jwk), "SHA-256", "base64url");
37
- if (keyid == null) {
38
- throw new Error("Failed to generate jwk thumbprint");
42
+ async function resolveWebCrypto() {
43
+ // Browsers, Bun, Deno, and many Node setups expose crypto globally.
44
+ if (globalThis.crypto?.subtle != null) {
45
+ return globalThis.crypto;
46
+ }
47
+ // Reuse the resolved Node fallback to avoid repeated dynamic imports.
48
+ if (cachedWebCrypto != null) {
49
+ return cachedWebCrypto;
39
50
  }
40
- return keyid;
51
+ const gt = globalThis;
52
+ const isNodeRuntime = typeof gt === "object" &&
53
+ gt != null &&
54
+ "process" in gt &&
55
+ typeof gt.process === "object" &&
56
+ gt.process != null &&
57
+ "versions" in gt.process &&
58
+ typeof gt.process.versions === "object" &&
59
+ gt.process.versions != null &&
60
+ "node" in gt.process.versions;
61
+ // Avoid attempting to resolve `node:crypto` in non-Node runtimes.
62
+ if (isNodeRuntime) {
63
+ try {
64
+ // Keep the specifier non-literal to avoid eager bundler resolution.
65
+ const nodeCryptoSpecifier = `node${":"}crypto`;
66
+ const nodeCrypto = await import(nodeCryptoSpecifier);
67
+ if (nodeCrypto.webcrypto?.subtle != null) {
68
+ cachedWebCrypto = nodeCrypto.webcrypto;
69
+ return cachedWebCrypto;
70
+ }
71
+ }
72
+ catch {
73
+ // Intentionally ignored. We'll throw a descriptive error below.
74
+ }
75
+ }
76
+ throw new Error("Web Crypto API is unavailable. Expected globalThis.crypto.subtle or Node's crypto.webcrypto.");
41
77
  }
42
- function stripUndefined(obj) {
43
- const newObj = {};
44
- const target = newObj;
45
- for (const entry of Object.entries(obj)) {
46
- const [key, value] = entry;
47
- if (typeof value !== "undefined") {
48
- target[key] = value;
78
+ /**
79
+ * Derives JWT `kid` from a private key using an RFC 7638 JWK thumbprint.
80
+ *
81
+ * Expected key format:
82
+ * - PKCS#8 PEM-encoded private key
83
+ * - EC P-521 curve (matches ES512 signing)
84
+ *
85
+ * Steps:
86
+ * 1. Decode PEM to PKCS#8 DER bytes.
87
+ * 2. Import key through Web Crypto.
88
+ * 3. Export as JWK and validate required fields.
89
+ * 4. Hash the canonical RFC 7638 thumbprint input with SHA-256.
90
+ * 5. Return base64url encoded digest.
91
+ *
92
+ * @param privateKey PEM-encoded PKCS#8 EC private key.
93
+ * @returns The base64url-encoded JWK thumbprint used as JWT `kid`.
94
+ * @throws If key parsing/import/export/validation/digest fails.
95
+ */
96
+ async function getKeyId(privateKey) {
97
+ try {
98
+ const runtimeCrypto = await resolveWebCrypto();
99
+ // Parse PEM to DER binary
100
+ const pemBody = privateKey
101
+ .replace(/-----BEGIN PRIVATE KEY-----/, "")
102
+ .replace(/-----END PRIVATE KEY-----/, "")
103
+ .replace(/\s/g, "");
104
+ const der = (0, base64_1.bytesFromBase64)(pemBody);
105
+ // Import as extractable CryptoKey (ES512 = P-521)
106
+ const key = await runtimeCrypto.subtle.importKey("pkcs8", der, { name: "ECDSA", namedCurve: "P-521" }, true, ["sign"]);
107
+ // Export as JWK and validate fields required to build an RFC 7638 thumbprint.
108
+ const jwk = await runtimeCrypto.subtle.exportKey("jwk", key);
109
+ const requiredFields = ["kty", "crv", "x", "y"];
110
+ const invalidFields = requiredFields.filter((field) => {
111
+ const value = jwk[field];
112
+ return typeof value !== "string" || value.length === 0;
113
+ });
114
+ if (invalidFields.length > 0) {
115
+ throw new Error(`Exported JWK is missing required string field(s): ${invalidFields.join(", ")}`);
116
+ }
117
+ if (jwk.kty !== "EC" || jwk.crv !== "P-521") {
118
+ throw new Error("Imported key is not an EC P-521 private key");
49
119
  }
120
+ // RFC 7638 canonical member set for EC keys: crv, kty, x, y.
121
+ const input = JSON.stringify({
122
+ crv: jwk.crv,
123
+ kty: jwk.kty,
124
+ x: jwk.x,
125
+ y: jwk.y,
126
+ });
127
+ const hash = await runtimeCrypto.subtle.digest("SHA-256", new TextEncoder().encode(input));
128
+ // Base64url encode
129
+ return btoa(String.fromCharCode(...new Uint8Array(hash)))
130
+ .replace(/\+/g, "-")
131
+ .replace(/\//g, "_")
132
+ .replace(/=+$/, "");
133
+ }
134
+ catch (error) {
135
+ const reason = error instanceof Error && error.message
136
+ ? ` Reason: ${error.message}`
137
+ : "";
138
+ throw new Error("Failed to derive JWT key ID from private key. Expected a PKCS#8 PEM-encoded EC private key on curve P-521 (ES512)." +
139
+ reason);
50
140
  }
51
- return newObj;
52
141
  }
53
142
  //# sourceMappingURL=helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/lib/helpers.ts"],"names":[],"mappings":";;;;;AAMA,gCAsBC;AAKD,4BAaC;AAED,wCAeC;AA/DD,yDAAiC;AACjC,mDAAyD;AAEzD;;GAEG;AACH,SAAgB,UAAU;IACxB,IACE,OAAO,SAAS,KAAK,WAAW;QAChC,OAAO,SAAS,CAAC,SAAS,KAAK,QAAQ,EACvC,CAAC;QACD,OAAO,SAAS,CAAC,SAAS,CAAC;IAC7B,CAAC;IAED,MAAM,EAAE,GAAY,UAAU,CAAC;IAC/B,IACE,OAAO,EAAE,KAAK,QAAQ;QACtB,EAAE,IAAI,IAAI;QACV,SAAS,IAAI,EAAE;QACf,OAAO,EAAE,CAAC,OAAO,KAAK,QAAQ;QAC9B,EAAE,CAAC,OAAO,IAAI,IAAI;QAClB,SAAS,IAAI,EAAE,CAAC,OAAO;QACvB,OAAO,EAAE,CAAC,OAAO,CAAC,OAAO,KAAK,QAAQ,EACtC,CAAC;QACD,OAAO,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACzC,CAAC;IAED,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,QAAQ,CAAC,UAAkB;IAC/C,MAAM,GAAG,GAAG,eAAK,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAE3D,MAAM,KAAK,GAAG,IAAA,wCAAuB,EACnC,cAAc,CAAC,GAAG,CAAC,EACnB,SAAS,EACT,WAAW,CACZ,CAAC;IACF,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAgB,cAAc,CAC5B,GAAM;IAEN,MAAM,MAAM,GAAkD,EAAE,CAAC;IACjE,MAAM,MAAM,GAA4B,MAAM,CAAC;IAE/C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC;QAE3B,IAAI,OAAO,KAAK,KAAK,WAAW,EAAE,CAAC;YACjC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/lib/helpers.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gr4vy/sdk",
3
- "version": "1.10.17",
3
+ "version": "2.0.0",
4
4
  "author": "Gr4vy",
5
5
  "main": "./index.js",
6
6
  "sideEffects": false,
@@ -19,7 +19,6 @@
19
19
  "devDependencies": {
20
20
  "@eslint/js": "^9.26.0",
21
21
  "@types/jsonwebtoken": "^9.0.10",
22
- "@types/trust__keyto": "^1.0.4",
23
22
  "@types/uuid": "^11.0.0",
24
23
  "eslint": "^9.26.0",
25
24
  "globals": "^15.14.0",
@@ -29,9 +28,7 @@
29
28
  "vitest": "^4.0.3"
30
29
  },
31
30
  "dependencies": {
32
- "@trust/keyto": "^1.0.1",
33
31
  "jsonwebtoken": "^9.0.3",
34
- "jwk-thumbprint": "^0.1.4",
35
32
  "snakecase-keys": "^6.0.0",
36
33
  "uuid": "^11.1.0",
37
34
  "zod": "^3.25.0 || ^4.0.0"
package/src/lib/config.ts CHANGED
@@ -77,7 +77,7 @@ export function serverURLFromOptions(options: SDKOptions): URL | null {
77
77
  export const SDK_METADATA = {
78
78
  language: "typescript",
79
79
  openapiDocVersion: "1.0.0",
80
- sdkVersion: "1.10.17",
81
- genVersion: "2.856.1",
82
- userAgent: "speakeasy-sdk/typescript 1.10.17 2.856.1 1.0.0 @gr4vy/sdk",
80
+ sdkVersion: "2.0.0",
81
+ genVersion: "2.858.2",
82
+ userAgent: "speakeasy-sdk/typescript 2.0.0 2.858.2 1.0.0 @gr4vy/sdk",
83
83
  } as const;
@@ -1,8 +1,12 @@
1
- import keyto from "@trust/keyto";
2
- import { jwkThumbprintByEncoding } from "jwk-thumbprint";
1
+ import { bytesFromBase64 } from "./base64";
3
2
 
4
3
  /**
5
- * Attempts to detect the JS runtime and its version based on available globals.
4
+ * Best-effort runtime identification used for SDK metadata/user-agent strings.
5
+ *
6
+ * The function prefers browser-style detection via `navigator.userAgent` and
7
+ * falls back to Node.js `process.version` when available.
8
+ *
9
+ * @returns A runtime identifier string, or `"<unknown-runtime>"` when not detectable.
6
10
  */
7
11
  export function getRuntime() {
8
12
  if (
@@ -28,37 +32,143 @@ export function getRuntime() {
28
32
  return "<unknown-runtime>";
29
33
  }
30
34
 
35
+ let cachedWebCrypto: Crypto | undefined;
36
+
31
37
  /**
32
- * Calculate the Key ID
38
+ * Resolves a Web Crypto implementation across supported runtimes.
39
+ *
40
+ * Resolution order:
41
+ * 1. `globalThis.crypto` when already exposed by the runtime.
42
+ * 2. Node.js fallback via `node:crypto`.webcrypto (important for some Node 18 setups).
43
+ *
44
+ * @returns A Web Crypto compatible `Crypto` object with `subtle` APIs.
45
+ * @throws If no Web Crypto implementation is available.
33
46
  */
34
- export async function getKeyId(privateKey: string): Promise<string> {
35
- const jwk = keyto.from(privateKey, "pem").toJwk("private");
47
+ async function resolveWebCrypto(): Promise<Crypto> {
48
+ // Browsers, Bun, Deno, and many Node setups expose crypto globally.
49
+ if (globalThis.crypto?.subtle != null) {
50
+ return globalThis.crypto;
51
+ }
36
52
 
37
- const keyid = jwkThumbprintByEncoding(
38
- stripUndefined(jwk),
39
- "SHA-256",
40
- "base64url"
41
- );
42
- if (keyid == null) {
43
- throw new Error("Failed to generate jwk thumbprint");
53
+ // Reuse the resolved Node fallback to avoid repeated dynamic imports.
54
+ if (cachedWebCrypto != null) {
55
+ return cachedWebCrypto;
56
+ }
57
+
58
+ const gt: unknown = globalThis;
59
+ const isNodeRuntime =
60
+ typeof gt === "object" &&
61
+ gt != null &&
62
+ "process" in gt &&
63
+ typeof gt.process === "object" &&
64
+ gt.process != null &&
65
+ "versions" in gt.process &&
66
+ typeof gt.process.versions === "object" &&
67
+ gt.process.versions != null &&
68
+ "node" in gt.process.versions;
69
+
70
+ // Avoid attempting to resolve `node:crypto` in non-Node runtimes.
71
+ if (isNodeRuntime) {
72
+ try {
73
+ // Keep the specifier non-literal to avoid eager bundler resolution.
74
+ const nodeCryptoSpecifier = `node${":"}crypto`;
75
+ const nodeCrypto = await import(nodeCryptoSpecifier);
76
+ if (nodeCrypto.webcrypto?.subtle != null) {
77
+ cachedWebCrypto = nodeCrypto.webcrypto as unknown as Crypto;
78
+ return cachedWebCrypto;
79
+ }
80
+ } catch {
81
+ // Intentionally ignored. We'll throw a descriptive error below.
82
+ }
44
83
  }
45
84
 
46
- return keyid;
85
+ throw new Error(
86
+ "Web Crypto API is unavailable. Expected globalThis.crypto.subtle or Node's crypto.webcrypto."
87
+ );
47
88
  }
48
89
 
49
- export function stripUndefined<T extends {}>(
50
- obj: T
51
- ): { [K in keyof T]?: Exclude<T[K], undefined> } {
52
- const newObj: { [K in keyof T]?: Exclude<T[K], undefined> } = {};
53
- const target: Record<string, unknown> = newObj;
90
+ /**
91
+ * Derives JWT `kid` from a private key using an RFC 7638 JWK thumbprint.
92
+ *
93
+ * Expected key format:
94
+ * - PKCS#8 PEM-encoded private key
95
+ * - EC P-521 curve (matches ES512 signing)
96
+ *
97
+ * Steps:
98
+ * 1. Decode PEM to PKCS#8 DER bytes.
99
+ * 2. Import key through Web Crypto.
100
+ * 3. Export as JWK and validate required fields.
101
+ * 4. Hash the canonical RFC 7638 thumbprint input with SHA-256.
102
+ * 5. Return base64url encoded digest.
103
+ *
104
+ * @param privateKey PEM-encoded PKCS#8 EC private key.
105
+ * @returns The base64url-encoded JWK thumbprint used as JWT `kid`.
106
+ * @throws If key parsing/import/export/validation/digest fails.
107
+ */
108
+ export async function getKeyId(privateKey: string): Promise<string> {
109
+ try {
110
+ const runtimeCrypto = await resolveWebCrypto();
111
+
112
+ // Parse PEM to DER binary
113
+ const pemBody = privateKey
114
+ .replace(/-----BEGIN PRIVATE KEY-----/, "")
115
+ .replace(/-----END PRIVATE KEY-----/, "")
116
+ .replace(/\s/g, "");
117
+ const der = bytesFromBase64(pemBody);
54
118
 
55
- for (const entry of Object.entries(obj)) {
56
- const [key, value] = entry;
119
+ // Import as extractable CryptoKey (ES512 = P-521)
120
+ const key = await runtimeCrypto.subtle.importKey(
121
+ "pkcs8",
122
+ der,
123
+ { name: "ECDSA", namedCurve: "P-521" },
124
+ true,
125
+ ["sign"]
126
+ );
57
127
 
58
- if (typeof value !== "undefined") {
59
- target[key] = value;
128
+ // Export as JWK and validate fields required to build an RFC 7638 thumbprint.
129
+ const jwk = await runtimeCrypto.subtle.exportKey("jwk", key);
130
+ const requiredFields = ["kty", "crv", "x", "y"] as const;
131
+ const invalidFields = requiredFields.filter((field) => {
132
+ const value = jwk[field];
133
+ return typeof value !== "string" || value.length === 0;
134
+ });
135
+ if (invalidFields.length > 0) {
136
+ throw new Error(
137
+ `Exported JWK is missing required string field(s): ${invalidFields.join(
138
+ ", "
139
+ )}`
140
+ );
60
141
  }
61
- }
62
142
 
63
- return newObj;
143
+ if (jwk.kty !== "EC" || jwk.crv !== "P-521") {
144
+ throw new Error("Imported key is not an EC P-521 private key");
145
+ }
146
+
147
+ // RFC 7638 canonical member set for EC keys: crv, kty, x, y.
148
+ const input = JSON.stringify({
149
+ crv: jwk.crv,
150
+ kty: jwk.kty,
151
+ x: jwk.x,
152
+ y: jwk.y,
153
+ });
154
+ const hash = await runtimeCrypto.subtle.digest(
155
+ "SHA-256",
156
+ new TextEncoder().encode(input)
157
+ );
158
+
159
+ // Base64url encode
160
+ return btoa(String.fromCharCode(...new Uint8Array(hash)))
161
+ .replace(/\+/g, "-")
162
+ .replace(/\//g, "_")
163
+ .replace(/=+$/, "");
164
+ } catch (error) {
165
+ const reason =
166
+ error instanceof Error && error.message
167
+ ? ` Reason: ${error.message}`
168
+ : "";
169
+ throw new Error(
170
+ "Failed to derive JWT key ID from private key. Expected a PKCS#8 PEM-encoded EC private key on curve P-521 (ES512)." +
171
+ reason
172
+ );
173
+ }
64
174
  }