@frontmcp/utils 1.9.2 → 1.9.4

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.
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Class identity shared by every copy of a package loaded in one process.
3
+ *
4
+ * A process can hold two copies of a FrontMCP package: in an ES-module project `@frontmcp/sdk`'s ESM
5
+ * build loads `@frontmcp/observability` with `require()`, which resolves observability's CommonJS
6
+ * build, which in turn loads the CommonJS builds of the SDK and of its dependencies. Each copy has its
7
+ * own classes, so a plain `instanceof` in one copy does not recognise an instance made by the other:
8
+ * an error the client was answered with as a `PublicMcpError` was recorded as an internal error with
9
+ * a new id (#802).
10
+ *
11
+ * A branded class answers `instanceof` for its own instances as usual, and also for an instance of
12
+ * the class with the same brand from another copy. The brand is an own property of the class, so a
13
+ * subclass is recognised only through a brand of its own: an unbranded subclass keeps the plain
14
+ * check, and never matches a different subclass that happens to share a branded parent.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * export class GuardError extends Error {
19
+ * static override [Symbol.hasInstance](value: unknown): boolean {
20
+ * return isBrandedInstance(this, value);
21
+ * }
22
+ * }
23
+ * brandClass(GuardError, '@frontmcp/guard:GuardError');
24
+ * ```
25
+ */
26
+ /**
27
+ * Give `klass` a process-wide brand. The same class in another copy of its package carries the same
28
+ * brand, so each recognises the other's instances through {@link isBrandedInstance}. Namespace the
29
+ * brand with the package name (`'@frontmcp/sdk:McpError'`).
30
+ */
31
+ export declare function brandClass(klass: object, brand: string): void;
32
+ /**
33
+ * `value instanceof klass`, also true when `value` is an instance of the class that carries `klass`'s
34
+ * own brand in another copy of the package. Meant as the `static [Symbol.hasInstance]` of a branded
35
+ * class (subclasses inherit it, and match through their own brand or the plain check).
36
+ */
37
+ export declare function isBrandedInstance(klass: object, value: unknown): boolean;
@@ -0,0 +1 @@
1
+ export { brandClass, isBrandedInstance } from './class-brand';
@@ -11,6 +11,11 @@ import type { CryptoProvider } from './types';
11
11
  export declare const browserCrypto: CryptoProvider;
12
12
  /** Alias for conditional import resolution via `#crypto-provider`. */
13
13
  export { browserCrypto as cryptoProvider };
14
+ export declare function rsaVerify(): boolean;
15
+ export declare function rsaSignBase64Url(): string;
16
+ export declare function rsaVerifySync(): boolean;
17
+ export declare function pemToPublicJwk(): JsonWebKey;
18
+ export declare function generateRsaKeyPair(): never;
14
19
  export { isRsaPssAlg, jwtAlgToWebCryptoAlg } from './jwt-alg';
15
20
  /**
16
21
  * Verify an RSA signature using WebCrypto.
package/crypto/browser.js CHANGED
@@ -22,16 +22,21 @@ var browser_exports = {};
22
22
  __export(browser_exports, {
23
23
  browserCrypto: () => browserCrypto,
24
24
  cryptoProvider: () => browserCrypto,
25
+ generateRsaKeyPair: () => generateRsaKeyPair,
25
26
  isRsaPssAlg: () => isRsaPssAlg,
26
27
  jwtAlgToWebCryptoAlg: () => jwtAlgToWebCryptoAlg,
27
- rsaVerifyBrowser: () => rsaVerifyBrowser
28
+ pemToPublicJwk: () => pemToPublicJwk,
29
+ rsaSignBase64Url: () => rsaSignBase64Url,
30
+ rsaVerify: () => rsaVerify,
31
+ rsaVerifyBrowser: () => rsaVerifyBrowser,
32
+ rsaVerifySync: () => rsaVerifySync
28
33
  });
29
34
  module.exports = __toCommonJS(browser_exports);
30
- var import_sha2 = require("@noble/hashes/sha2.js");
31
- var import_hmac = require("@noble/hashes/hmac.js");
35
+ var import_aes = require("@noble/ciphers/aes.js");
32
36
  var import_hkdf = require("@noble/hashes/hkdf.js");
37
+ var import_hmac = require("@noble/hashes/hmac.js");
38
+ var import_sha2 = require("@noble/hashes/sha2.js");
33
39
  var import_utils = require("@noble/hashes/utils.js");
34
- var import_aes = require("@noble/ciphers/aes.js");
35
40
 
36
41
  // libs/utils/src/crypto/jwt-alg.ts
37
42
  function isRsaPssAlg(jwtAlg) {
@@ -119,6 +124,24 @@ var browserCrypto = {
119
124
  return constantTimeEqual(a, b);
120
125
  }
121
126
  };
127
+ function nodeOnly(name) {
128
+ throw new Error(`${name} is only available in Node.js runtimes`);
129
+ }
130
+ function rsaVerify() {
131
+ return nodeOnly("rsaVerify");
132
+ }
133
+ function rsaSignBase64Url() {
134
+ return nodeOnly("rsaSignBase64Url");
135
+ }
136
+ function rsaVerifySync() {
137
+ return nodeOnly("rsaVerifySync");
138
+ }
139
+ function pemToPublicJwk() {
140
+ return nodeOnly("pemToPublicJwk");
141
+ }
142
+ function generateRsaKeyPair() {
143
+ return nodeOnly("generateRsaKeyPair");
144
+ }
122
145
  async function rsaVerifyBrowser(jwtAlg, data, publicJwk, signature) {
123
146
  if (typeof globalThis.crypto?.subtle === "undefined") {
124
147
  throw new Error("WebCrypto API (crypto.subtle) is not available in this environment");
@@ -154,7 +177,12 @@ function getSaltLength(jwtAlg) {
154
177
  0 && (module.exports = {
155
178
  browserCrypto,
156
179
  cryptoProvider,
180
+ generateRsaKeyPair,
157
181
  isRsaPssAlg,
158
182
  jwtAlgToWebCryptoAlg,
159
- rsaVerifyBrowser
183
+ pemToPublicJwk,
184
+ rsaSignBase64Url,
185
+ rsaVerify,
186
+ rsaVerifyBrowser,
187
+ rsaVerifySync
160
188
  });
package/crypto/node.d.ts CHANGED
@@ -48,7 +48,7 @@ export declare function generateRsaKeyPair(modulusLength?: number, alg?: string)
48
48
  * For RSA-PSS (PS256/PS384/PS512), callers must pass appropriate padding/saltLength options.
49
49
  */
50
50
  export declare function rsaSign(algorithm: string, data: Buffer, privateKey: crypto.KeyObject, options?: Omit<crypto.SignKeyObjectInput, 'key'>): Buffer;
51
- export declare function rsaVerify(jwtAlg: string, data: Buffer, publicJwk: JsonWebKey, signature: Buffer): boolean;
51
+ export declare function rsaVerify(jwtAlg: string, data: Buffer | Uint8Array, publicJwk: JsonWebKey, signature: Buffer | Uint8Array): boolean;
52
52
  /**
53
53
  * Sign data with an RSA private JWK and return a base64url-encoded signature.
54
54
  *
@@ -2,11 +2,11 @@ var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuilt
2
2
  const require = __frontmcpModule ? __frontmcpModule.createRequire(import.meta.url || 'file:///') : undefined;
3
3
  // __frontmcpCreateRequire
4
4
  // libs/utils/src/crypto/browser.ts
5
- import { sha256 as sha256Hash } from "@noble/hashes/sha2.js";
6
- import { hmac } from "@noble/hashes/hmac.js";
5
+ import { gcm } from "@noble/ciphers/aes.js";
7
6
  import { hkdf } from "@noble/hashes/hkdf.js";
7
+ import { hmac } from "@noble/hashes/hmac.js";
8
+ import { sha256 as sha256Hash } from "@noble/hashes/sha2.js";
8
9
  import { randomBytes as nobleRandomBytes } from "@noble/hashes/utils.js";
9
- import { gcm } from "@noble/ciphers/aes.js";
10
10
 
11
11
  // libs/utils/src/crypto/jwt-alg.ts
12
12
  function isRsaPssAlg(jwtAlg) {
@@ -94,6 +94,24 @@ var browserCrypto = {
94
94
  return constantTimeEqual(a, b);
95
95
  }
96
96
  };
97
+ function nodeOnly(name) {
98
+ throw new Error(`${name} is only available in Node.js runtimes`);
99
+ }
100
+ function rsaVerify() {
101
+ return nodeOnly("rsaVerify");
102
+ }
103
+ function rsaSignBase64Url() {
104
+ return nodeOnly("rsaSignBase64Url");
105
+ }
106
+ function rsaVerifySync() {
107
+ return nodeOnly("rsaVerifySync");
108
+ }
109
+ function pemToPublicJwk() {
110
+ return nodeOnly("pemToPublicJwk");
111
+ }
112
+ function generateRsaKeyPair() {
113
+ return nodeOnly("generateRsaKeyPair");
114
+ }
97
115
  async function rsaVerifyBrowser(jwtAlg, data, publicJwk, signature) {
98
116
  if (typeof globalThis.crypto?.subtle === "undefined") {
99
117
  throw new Error("WebCrypto API (crypto.subtle) is not available in this environment");
@@ -128,7 +146,12 @@ function getSaltLength(jwtAlg) {
128
146
  export {
129
147
  browserCrypto,
130
148
  browserCrypto as cryptoProvider,
149
+ generateRsaKeyPair,
131
150
  isRsaPssAlg,
132
151
  jwtAlgToWebCryptoAlg,
133
- rsaVerifyBrowser
152
+ pemToPublicJwk,
153
+ rsaSignBase64Url,
154
+ rsaVerify,
155
+ rsaVerifyBrowser,
156
+ rsaVerifySync
134
157
  };