From 50b73778fe768241b02f3ef7b2782ee36cd26a36 Mon Sep 17 00:00:00 2001 From: Akos Foldesi Date: Sun, 26 Apr 2026 19:44:16 +0200 Subject: [PATCH] docs(0.2.0): document UnmatchedReason values + fix supported versions table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audit (2026-04-26) found three doc gaps that didn't track the 0.2.0 BREAKING change to UnmatchedReason semantics. No code changes. - src/types.ts — add JSDoc to UnmatchedReason and each union member describing what it means. The matchQuery JSDoc already covers the order-dependent "last failure" rule but the type itself was opaque in IDE hover. - README.md — extend the matchQuery API entry with a table of UnmatchedReason values + a 0.2.0 BREAKING note for callers upgrading from 0.1.x (where every failure collapsed to 'no_credential_found'). - SECURITY.md — Supported Versions table only listed 0.1.x. Replace with 0.2.x (current) + 0.1.x marked as superseded. Tests: 116/116 passing. dist/ DTS rebuilds with the new JSDoc. --- README.md | 16 ++++++++++++++++ SECURITY.md | 3 ++- src/types.ts | 16 ++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a2d3df..6bd8517 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,22 @@ Validates the shape of a DCQL query. Throws `DcqlValidationError` with a `code` Finds credentials that satisfy each query. Returns `{ satisfied, matches, unmatched }`. Never throws. +Each entry in `unmatched` carries an `UnmatchedReason`: + +| Reason | Meaning | +| --- | --- | +| `format_mismatch` | candidate's `format` did not equal the query's `format` | +| `vct_mismatch` | candidate's `vct` was not in the query's `meta.vct_values` (sd-jwt-vc only) | +| `doctype_mismatch` | candidate's `doctype` was not equal to the query's `meta.doctype_value` (mso_mdoc only) | +| `missing_claims` | candidate is missing one or more claim paths required by the query | +| `value_mismatch` | a required claim is present but its value is not in the query's `values:` filter | +| `trusted_authority_mismatch` | none of the candidate's `trusted_authority_ids` are in the query's `trusted_authorities` filter | +| `no_credential_found` | the candidate credentials list was empty for this query (reserved for the empty-input case only since 0.2.0) | + +When a query has multiple candidate credentials, `matchQuery` reports the LAST candidate's failure (DCQL does not specify candidate ordering — see the `matchQuery` JSDoc for details). + +> **0.2.0 BREAKING:** prior to 0.2.0 every failure collapsed to `'no_credential_found'`. Callers reading `unmatched[].reason` need to switch on the new specific values. + ### `buildSubmission(query: DcqlQuery, result: DcqlMatchResult): DcqlSubmission` Builds a spec-shaped `{ [queryId]: credentialId | credentialId[] }` map. Throws `DcqlMatchError` if the result is not satisfied. diff --git a/SECURITY.md b/SECURITY.md index 28932b5..c832b35 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,7 +4,8 @@ | Version | Supported | | ------- | --------- | -| 0.1.x | Yes | +| 0.2.x | Yes | +| 0.1.x | No (superseded by 0.2.0; 0.2.0 is BREAKING — see CHANGELOG) | Only the latest release receives security updates. diff --git a/src/types.ts b/src/types.ts index 64be354..735d8ea 100644 --- a/src/types.ts +++ b/src/types.ts @@ -47,13 +47,29 @@ export type DecodedCredential = { trusted_authority_ids?: string[]; }; +/** + * Reason a query did not match against the supplied credentials. + * + * Returned per-query in `DcqlMatchResult.unmatched[].reason`. When a query has + * multiple candidate credentials, `matchQuery` reports the LAST candidate's + * failure (DCQL does not specify candidate ordering — see `matchQuery` JSDoc). + * + * @see {@link matchQuery} + */ export type UnmatchedReason = + /** The candidate credentials list was empty for this query. */ | 'no_credential_found' + /** Candidate's `format` did not equal the query's `format`. */ | 'format_mismatch' + /** Candidate's `vct` was not in the query's `meta.vct_values` (sd-jwt-vc only). */ | 'vct_mismatch' + /** Candidate's `doctype` was not equal to the query's `meta.doctype_value` (mso_mdoc only). */ | 'doctype_mismatch' + /** Candidate is missing one or more claim paths required by the query. */ | 'missing_claims' + /** A required claim is present, but its value is not in the query's `values:` filter. */ | 'value_mismatch' + /** None of the candidate's `trusted_authority_ids` are in the query's `trusted_authorities` filter. */ | 'trusted_authority_mismatch'; export type DcqlMatchResult = {