Files
Filip Skokan a0b786baca ci: add type and package checks
Build every nested declaration and type-check the emitted entry points
across supported module-resolution and library configurations.

Validate type regressions, documented subpaths, package metadata, type
resolution, and generated docs in CI. Expand dist cache inputs.

Signed-off-by: Filip Skokan <[email protected]>
2026-07-29 18:50:54 +02:00

108 lines
3.0 KiB
TypeScript

import type QUnit from 'qunit'
import * as env from './env.js'
import { KEYS } from './fixtures.js'
import type * as jose from '../src/index.js'
export default (
QUnit: QUnit,
lib: typeof jose,
keys: Pick<typeof jose, 'exportJWK' | 'generateKeyPair' | 'generateSecret' | 'importJWK'>,
) => {
const { module, test } = QUnit
module('jwk.ts')
type Vector = [string, jose.JWK]
const algorithms: Vector[] = [
['ECDH-ES', KEYS.P256.jwk],
['ECDH-ES', KEYS.P384.jwk],
['ECDH-ES', KEYS.P521.jwk],
['ECDH-ES', KEYS.X25519.jwk],
['Ed25519', KEYS.Ed25519.jwk],
['EdDSA', KEYS.Ed25519.jwk],
['ES256', KEYS.P256.jwk],
['ES384', KEYS.P384.jwk],
['ES512', KEYS.P521.jwk],
['PS256', KEYS.RSA.jwk],
['PS384', KEYS.RSA.jwk],
['PS512', KEYS.RSA.jwk],
['RS256', KEYS.RSA.jwk],
['RS384', KEYS.RSA.jwk],
['RS512', KEYS.RSA.jwk],
['RSA-OAEP-256', KEYS.RSA.jwk],
['RSA-OAEP-384', KEYS.RSA.jwk],
['RSA-OAEP-512', KEYS.RSA.jwk],
['RSA-OAEP', KEYS.RSA.jwk],
['ML-DSA-44', KEYS['ML-DSA-44'].jwk],
['ML-DSA-65', KEYS['ML-DSA-65'].jwk],
['ML-DSA-87', KEYS['ML-DSA-87'].jwk],
]
function publicJwk(jwk: jose.JWK) {
const { d, p, q, dp, dq, qi, k, priv, ...result } = jwk
return result
}
for (const vector of algorithms.slice()) {
algorithms.push([vector[0], publicJwk(vector[1])])
}
function title(alg: string, jwk: jose.JWK, supported = true) {
let result = ''
if (!supported) {
result = '[not supported] '
}
result += `${alg} `
if (alg === 'EdDSA' || alg === 'ECDH-ES') {
result += `${jwk.crv} `
}
result += jwk.d || jwk.priv ? 'Private' : 'Public'
result += ' JWK Import'
return result
}
for (const vector of algorithms) {
const [alg, jwk] = vector
const execute = async (t: typeof QUnit.assert) => {
const key = await lib.importJWK({ ...jwk, ext: true } as jose.JWK, alg)
const exported = await lib.exportJWK(key)
t.deepEqual(Object.keys(exported).sort(), Object.keys(jwk).sort(), 'unexpected JWK members')
for (const prop of [...new Set([...Object.keys(jwk), ...Object.keys(exported)])]) {
t.strictEqual(
exported[prop as keyof jose.JWK],
jwk[prop as keyof jose.JWK],
`${prop} mismatch`,
)
}
if (env.isNode && lib.importJWK !== keys.importJWK) {
const nCrypto = globalThis.process.getBuiltinModule('node:crypto')
t.deepEqual(
await lib.exportJWK(
nCrypto[jwk.d || jwk.priv ? 'createPrivateKey' : 'createPublicKey']({
format: 'jwk',
key: jwk,
}),
),
exported,
)
}
t.ok(1)
}
const op = `${jwk.d || jwk.priv ? 'private' : 'public'} jwk import`
if (env.supported(alg, op) && env.supported(jwk.crv, op)) {
test(title(alg, jwk), execute)
} else {
test(title(alg, jwk, false), async (t) => {
await t.rejects(execute(t))
})
}
}
}