/** * @typedef {Object} ExportJWKOptions * @property {string} [kid] * @property {'sig' | 'enc'} [use] * @property {string} [alg] * @property {string[]} [key_ops] */ /** * KeyObject → JWK. For asymmetric public / private keys and for `oct` * secret keys alike. Decorator fields override anything Node put in * `asymmetricKeyDetails`. * * @param {KeyObject} key * @param {ExportJWKOptions} [options] * @returns {Promise} */ declare function exportJWK(key: KeyObject, options?: ExportJWKOptions$1): Promise; /** * @typedef {'spki' | 'pkcs8'} PemExportFormat */ /** * KeyObject → PEM. Format defaults to SPKI for public keys and PKCS#8 * for private keys — the sensible choice unless a specific interop * target demands otherwise. * * @param {KeyObject} key * @param {PemExportFormat} [format] * @returns {Promise} */ declare function exportPEM(key: KeyObject, format?: PemExportFormat$1): Promise; /** * Strip every private / secret member from a JWK, returning a defensive * shallow copy that is safe to publish (e.g. via a JWKS endpoint). * * Convenience over hand-stripping — callers don't have to remember * which `kty` stores the secret material in which member. * * @param {object} jwk * @returns {object} */ declare function toPublic(jwk: object): object; type ExportJWKOptions$1 = { kid?: string | undefined; use?: "sig" | "enc" | undefined; alg?: string | undefined; key_ops?: string[] | undefined; }; type PemExportFormat$1 = "spki" | "pkcs8"; /** @typedef {import('node:crypto').KeyObject} KeyObject */ /** * @typedef {Object} ImportJWKOptions * @property {string} [alg] intended JOSE algorithm identifier — currently informational (Node ignores it in key import) */ /** * Convert a JWK into a `KeyObject`. JWKs with `d` (or `k` for `oct`) * yield a private / secret KeyObject; public JWKs yield a public one. * * @param {object} jwk * @param {ImportJWKOptions} [_options] * @returns {Promise} */ declare function importJWK(jwk: object, _options?: ImportJWKOptions$1): Promise; /** * @typedef {'spki' | 'pkcs8' | 'x509'} PemFormat */ /** * Import a PEM- or DER-encoded key. * * - `'spki'` → public key (SubjectPublicKeyInfo) * - `'pkcs8'` → private key (PrivateKeyInfo) * - `'x509'` → public key extracted from an X.509 certificate * * When `pemOrDer` is a `Buffer`, the input is treated as DER; strings * are PEM. * * @param {string | Buffer} pemOrDer * @param {PemFormat} [format='spki'] * @returns {Promise} */ declare function importPEM(pemOrDer: string | Buffer, format?: PemFormat$1): Promise; type KeyObject$1 = any; type ImportJWKOptions$1 = { /** * intended JOSE algorithm identifier — currently informational (Node ignores it in key import) */ alg?: string | undefined; }; type PemFormat$1 = "spki" | "pkcs8" | "x509"; /** * @typedef {Object} ValidateOptions * @property {boolean} [requirePrivate=false] reject public-only JWKs * @property {boolean} [requirePublic=false] reject secret-carrying JWKs */ /** * Assert that `jwk` conforms to the RFC 7517 shape and its per-kty * requirements. Returns the JWK unchanged when valid; throws * {@link JwkError} otherwise. * * @param {unknown} jwk * @param {ValidateOptions} [options] * @returns {object} the same JWK, narrowed to a validated shape */ declare function validate(jwk: unknown, options?: ValidateOptions$1): object; /** * Non-throwing variant. Returns `true` when the JWK passes * {@link validate}, `false` otherwise. Handy for JWKS filtering. * * @param {unknown} jwk * @param {ValidateOptions} [options] * @returns {boolean} */ declare function isValid(jwk: unknown, options?: ValidateOptions$1): boolean; type ValidateOptions$1 = { /** * reject public-only JWKs */ requirePrivate?: boolean | undefined; /** * reject secret-carrying JWKs */ requirePublic?: boolean | undefined; }; /** * Compute the JWK thumbprint per RFC 7638 §3, encoded as base64url. * * @param {object} jwk * @param {ThumbprintDigest} [digest='sha256'] * @returns {Promise} */ declare function thumbprint(jwk: object, digest?: ThumbprintDigest$1): Promise; /** * Compute the JWK Thumbprint URI per RFC 9278 §3: * `urn:ietf:params:oauth:jwk-thumbprint:sha-256:`. * * @param {object} jwk * @param {ThumbprintDigest} [digest='sha256'] * @returns {Promise} */ declare function thumbprintURI(jwk: object, digest?: ThumbprintDigest$1): Promise; /** * Semantic-equality check via thumbprint. Two JWKs match when their * required members (per kty) produce the same digest, regardless of * `kid` / `use` / `alg` decoration — even when one is the private form * and the other the public projection. * * @param {object} a * @param {object} b * @param {ThumbprintDigest} [digest='sha256'] * @returns {Promise} */ declare function matches(a: object, b: object, digest?: ThumbprintDigest$1): Promise; type ThumbprintDigest$1 = "sha256" | "sha384" | "sha512"; /** * @typedef {'EC' | 'RSA' | 'OKP' | 'oct'} Kty * @typedef {'P-256' | 'P-384' | 'P-521' | 'secp256k1'} EcCurve * @typedef {'Ed25519' | 'Ed448' | 'X25519' | 'X448'} OkpCurve */ /** * @typedef {Object} GenerateOptionsCommon * @property {string} [kid] * @property {'sig' | 'enc'} [use] * @property {string} [alg] * @property {string[]} [key_ops] */ /** * @typedef {GenerateOptionsCommon & { curve?: EcCurve }} GenerateOptionsEC * @typedef {GenerateOptionsCommon & { modulusLength?: number, publicExponent?: number }} GenerateOptionsRSA * @typedef {GenerateOptionsCommon & { curve?: OkpCurve }} GenerateOptionsOKP * @typedef {GenerateOptionsCommon & { bits?: number }} GenerateOptionsOct */ /** * @typedef {Object} GeneratedKeyPair * @property {object} publicJwk public projection (asymmetric); equals `privateJwk` for `oct` * @property {object} privateJwk private JWK (contains `d`, or `k` for `oct`) */ /** * Generate a JWK for the requested `kty`. * * @param {Kty} kty * @param {GenerateOptionsEC | GenerateOptionsRSA | GenerateOptionsOKP | GenerateOptionsOct} [options] * @returns {Promise} */ declare function generate(kty: Kty$1, options?: GenerateOptionsEC | GenerateOptionsRSA | GenerateOptionsOKP | GenerateOptionsOct): Promise; type Kty$1 = "EC" | "RSA" | "OKP" | "oct"; type EcCurve$1 = "P-256" | "P-384" | "P-521" | "secp256k1"; type OkpCurve$1 = "Ed25519" | "Ed448" | "X25519" | "X448"; type GenerateOptionsCommon = { kid?: string | undefined; use?: "sig" | "enc" | undefined; alg?: string | undefined; key_ops?: string[] | undefined; }; type GenerateOptionsEC = GenerateOptionsCommon & { curve?: EcCurve$1; }; type GenerateOptionsRSA = GenerateOptionsCommon & { modulusLength?: number; publicExponent?: number; }; type GenerateOptionsOKP = GenerateOptionsCommon & { curve?: OkpCurve$1; }; type GenerateOptionsOct = GenerateOptionsCommon & { bits?: number; }; type GeneratedKeyPair$1 = { /** * public projection (asymmetric); equals `privateJwk` for `oct` */ publicJwk: object; /** * private JWK (contains `d`, or `k` for `oct`) */ privateJwk: object; }; /** * Shared base error class — the single error structure behind every * `@exortek/*` package's `errors.js`. * * Every package keeps its own class identity with a one-liner subclass; * codes stay per-package frozen maps, status mapping is declared as a * static field: * * import { BaseError } from '@exortek/shared/errors'; * * export const ErrorCode = Object.freeze({ * INVALID_ARGUMENT: 'INVALID_ARGUMENT', * INVALID_TOKEN: 'INVALID_TOKEN', * }); * * export class JwtError extends BaseError { * static statuses = { INVALID_ARGUMENT: 400, INVALID_TOKEN: 401 }; * static defaultStatus = 500; * } * * Instances carry a stable machine-readable `code` (branch on this, * never on the message), an optional HTTP `status`, an optional * `details` object, and the standard `cause` chain. */ declare class BaseError extends Error { /** * Optional `code → HTTP status` map declared on the subclass. When * absent the instance carries no `status` at all — for HTTP-agnostic * packages like `@exortek/crypto`. * * @type {Record | undefined} */ static statuses: Record | undefined; /** * Fallback status for codes missing from `statuses`. * * @type {number} */ static defaultStatus: number; /** * @param {string} code Stable machine-readable code; branch on this. * @param {string} message Human-readable diagnostic. Free-form; may * change across versions. * @param {{ cause?: unknown, status?: number, details?: Record }} [options] */ constructor(code: string, message: string, options?: { cause?: unknown; status?: number; details?: Record; }); /** @type {string} */ code: string; /** @type {number | undefined} */ status: number | undefined; /** @type {Record | undefined} */ details: Record | undefined; } declare const ErrorCode: Readonly<{ INVALID_ARGUMENT: "INVALID_ARGUMENT"; UNSUPPORTED_KTY: "UNSUPPORTED_KTY"; UNSUPPORTED_CURVE: "UNSUPPORTED_CURVE"; UNSUPPORTED_ALGORITHM: "UNSUPPORTED_ALGORITHM"; INVALID_KEY: "INVALID_KEY"; INVALID_JWK: "INVALID_JWK"; INVALID_FORMAT: "INVALID_FORMAT"; MISSING_REQUIRED_MEMBER: "MISSING_REQUIRED_MEMBER"; KEY_OPS_CONFLICT: "KEY_OPS_CONFLICT"; }>; /** * Every recoverable failure raised by this package. Carries a stable * `code` (from {@link ErrorCode}) and a `status` — the HTTP response * status a middleware layer would use when translating the error. */ declare class JwkError extends BaseError { static statuses: { INVALID_ARGUMENT: number; UNSUPPORTED_KTY: number; UNSUPPORTED_CURVE: number; UNSUPPORTED_ALGORITHM: number; INVALID_FORMAT: number; MISSING_REQUIRED_MEMBER: number; KEY_OPS_CONFLICT: number; INVALID_KEY: number; INVALID_JWK: number; }; } /** * Bundled namespace matching the ARCHITECTURE example. * * `jwk.import` / `jwk.export` are property-access aliases for * {@link importJWK} / {@link _exportDispatch} — inside an object literal * the reserved-word restriction does not apply. */ declare const jwk: Readonly<{ generate: typeof generate; import: typeof importJWK; importPEM: typeof importPEM; export: typeof _exportDispatch; exportPEM: typeof exportPEM; toPublic: typeof toPublic; thumbprint: typeof thumbprint; thumbprintURI: typeof thumbprintURI; matches: typeof matches; validate: typeof validate; isValid: typeof isValid; }>; type Kty = Kty$1; type EcCurve = EcCurve$1; type OkpCurve = OkpCurve$1; type GeneratedKeyPair = GeneratedKeyPair$1; type ThumbprintDigest = ThumbprintDigest$1; type ValidateOptions = ValidateOptions$1; type ImportJWKOptions = ImportJWKOptions$1; type PemFormat = PemFormat$1; type ExportJWKOptions = ExportJWKOptions$1; type PemExportFormat = PemExportFormat$1; /** * `jwk.export(key, { format })` — bundled dispatcher used by the * namespace API. Named exports (`exportJWK`, `exportPEM`) remain * single-purpose; the namespace form matches the ARCHITECTURE.md example * where `format` selects the output shape. * * - `format: 'jwk'` (default) → {@link exportJWK}, options forwarded verbatim * - `format: 'pem'` → {@link exportPEM}, `pemType` selects SPKI vs PKCS#8 * * @param {import('node:crypto').KeyObject} key * @param {import('./export.js').ExportJWKOptions & { format?: 'jwk' | 'pem', pemType?: import('./export.js').PemExportFormat }} [options] * @returns {Promise} */ declare function _exportDispatch(key: any, options?: ExportJWKOptions$1 & { format?: "jwk" | "pem"; pemType?: PemExportFormat$1; }): Promise; export { ErrorCode, JwkError, exportJWK, exportPEM, generate, importJWK, importPEM, isValid, jwk, matches, thumbprint, thumbprintURI, toPublic, validate }; export type { EcCurve, ExportJWKOptions, GeneratedKeyPair, ImportJWKOptions, Kty, OkpCurve, PemExportFormat, PemFormat, ThumbprintDigest, ValidateOptions };