@learncard/credential-library 1.0.17 → 2.0.1
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/README.md +58 -3
- package/dist/__tests__/sd-jwt-vc.test.d.ts +2 -0
- package/dist/__tests__/sd-jwt-vc.test.d.ts.map +1 -0
- package/dist/credential-library.cjs.development.js +8951 -272
- package/dist/credential-library.cjs.development.js.map +3 -3
- package/dist/credential-library.cjs.production.min.js +1 -1
- package/dist/credential-library.cjs.production.min.js.map +4 -4
- package/dist/credential-library.esm.js +8951 -272
- package/dist/credential-library.esm.js.map +3 -3
- package/dist/fixtures/clr/demo-isd-diploma-assessments.d.ts +3 -0
- package/dist/fixtures/clr/demo-isd-diploma-assessments.d.ts.map +1 -0
- package/dist/fixtures/index.d.ts +5 -3
- package/dist/fixtures/index.d.ts.map +1 -1
- package/dist/fixtures/sd-jwt-vc/course-completion.d.ts +3 -0
- package/dist/fixtures/sd-jwt-vc/course-completion.d.ts.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/materialize-sd-jwt-vc.d.ts +21 -0
- package/dist/materialize-sd-jwt-vc.d.ts.map +1 -0
- package/dist/prepare.d.ts +2 -2
- package/dist/prepare.d.ts.map +1 -1
- package/dist/registry.d.ts +11 -9
- package/dist/registry.d.ts.map +1 -1
- package/dist/types.d.ts +31 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -4
- package/src/__tests__/issuance.test.ts +5 -2
- package/src/__tests__/registry.test.ts +195 -7
- package/src/__tests__/sd-jwt-vc.test.ts +220 -0
- package/src/fixtures/clr/demo-isd-diploma-assessments.ts +9183 -0
- package/src/fixtures/index.ts +12 -2
- package/src/fixtures/sd-jwt-vc/course-completion.ts +27 -0
- package/src/index.ts +17 -0
- package/src/materialize-sd-jwt-vc.ts +159 -0
- package/src/prepare.ts +9 -2
- package/src/registry.ts +88 -27
- package/src/types.ts +51 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo-isd-diploma-assessments.d.ts","sourceRoot":"","sources":["../../../src/fixtures/clr/demo-isd-diploma-assessments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,eAAO,MAAM,4BAA4B,EAAE,iBA49R1C,CAAC"}
|
package/dist/fixtures/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LibraryFixture } from '../types';
|
|
2
2
|
import { vcV1Basic } from './vc-v1/basic';
|
|
3
3
|
import { vcV1WithStatus } from './vc-v1/with-status';
|
|
4
4
|
import { vcV2Basic } from './vc-v2/basic';
|
|
@@ -38,6 +38,8 @@ import { vcV2LicenseCredential } from './vc-v2/license-credential';
|
|
|
38
38
|
import { clrGreatPlainsFull } from './clr/great-plains-full';
|
|
39
39
|
import { clrWestbridgeFull } from './clr/westbridge-full';
|
|
40
40
|
import { clrCompetencyAligned } from './clr/competency-aligned';
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
import { clrDemoIsdDiplomaAssessments } from './clr/demo-isd-diploma-assessments';
|
|
42
|
+
import { sdJwtVcCourseCompletion } from './sd-jwt-vc/course-completion';
|
|
43
|
+
export declare const ALL_FIXTURES: LibraryFixture[];
|
|
44
|
+
export { vcV1Basic, vcV1WithStatus, vcV2Basic, vcV2WithEvidence, vcV2MultipleSubjects, vcV2RenderMethodExample, obv3MinimalBadge, obv3FullBadge, obv3WithAlignment, obv3WithEndorsement, obv3PlugfestJff2, clrMinimal, clrMultiAchievement, boostBasic, boostId, boostWithSkills, invalidMissingContext, invalidEmptyType, invalidMissingIssuer, clrNdStudentTranscript, obv3OneedtechFull, obv3ProfessionalCert, obv3MicroCredential, obv3CourseCompletion, obv3StandaloneFullCourse, obv3K12Diploma, obv3EndorsementCredential, clrUniversityTranscript, boostCommunityAward, boostDelegate, vcV1AlumniCredential, vcV2EmploymentCredential, vcV2EducationDegree, vcV2DigitalId, vcV2MembershipCredential, vcV2LicenseCredential, clrGreatPlainsFull, clrWestbridgeFull, clrCompetencyAligned, clrDemoIsdDiplomaAssessments, sdJwtVcCourseCompletion, };
|
|
43
45
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fixtures/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fixtures/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"course-completion.d.ts","sourceRoot":"","sources":["../../../src/fixtures/sd-jwt-vc/course-completion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,eAAO,MAAM,uBAAuB,EAAE,cAwBrC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
export type { CredentialSpec, CredentialProfile, CredentialFeature, FixtureSource, FixtureValidity, CredentialFixture, FixtureFilter, InvalidCredential, } from './types';
|
|
2
|
-
export { CREDENTIAL_SPECS, CREDENTIAL_PROFILES, CREDENTIAL_FEATURES, FIXTURE_SOURCES, FIXTURE_VALIDITIES, } from './types';
|
|
1
|
+
export type { CredentialSpec, CredentialProfile, CredentialFeature, FixtureKind, FixtureSource, FixtureValidity, BaseCredentialFixture, CredentialFixture, SdJwtVcTemplate, SdJwtVcFixture, LibraryFixture, FixtureFilter, InvalidCredential, } from './types';
|
|
2
|
+
export { CREDENTIAL_SPECS, CREDENTIAL_PROFILES, CREDENTIAL_FEATURES, FIXTURE_KINDS, FIXTURE_SOURCES, FIXTURE_VALIDITIES, isCredentialFixture, isSdJwtVcFixture, } from './types';
|
|
3
3
|
export { registerFixture, registerFixtures, resetRegistry, getAllFixtures, getFixture, findFixture, getFixtures, getUnsignedFixtures, getSignedFixtures, getValidFixtures, getInvalidFixtures, getStats, } from './registry';
|
|
4
4
|
export type { RegistryStats } from './registry';
|
|
5
5
|
export { prepareFixture, prepareFixtureById } from './prepare';
|
|
6
6
|
export type { PrepareOptions } from './prepare';
|
|
7
|
+
export { materializeSdJwtVcFixture } from './materialize-sd-jwt-vc';
|
|
8
|
+
export type { SdJwtVcSigner, MaterializeSdJwtVcOptions, MaterializedSdJwtVcFixture, } from './materialize-sd-jwt-vc';
|
|
7
9
|
export * from './fixtures';
|
|
8
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACR,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,iBAAiB,GACpB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACH,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACR,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,cAAc,EACd,aAAa,EACb,iBAAiB,GACpB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACH,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,GACnB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACH,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,UAAU,EACV,WAAW,EACX,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,QAAQ,GACX,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/D,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGhD,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEpE,YAAY,EACR,aAAa,EACb,yBAAyB,EACzB,0BAA0B,GAC7B,MAAM,yBAAyB,CAAC;AAGjC,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { StoredCredentialEnvelope } from '@learncard/types';
|
|
2
|
+
import type { SdJwtVcFixture } from './types';
|
|
3
|
+
export type SdJwtVcSigner = (signingInput: string) => Promise<string>;
|
|
4
|
+
export interface MaterializeSdJwtVcOptions {
|
|
5
|
+
issuerDid: string;
|
|
6
|
+
issuerKid: string;
|
|
7
|
+
issuerSigner: SdJwtVcSigner;
|
|
8
|
+
holderPublicJwk: Record<string, unknown>;
|
|
9
|
+
issuedAt?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface MaterializedSdJwtVcFixture {
|
|
12
|
+
compact: string;
|
|
13
|
+
envelope: StoredCredentialEnvelope;
|
|
14
|
+
vct: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Materializes an SD-JWT VC fixture with a caller-supplied issuer signer and holder key.
|
|
18
|
+
* The returned compact credential is canonical `dc+sd-jwt` and never includes a KB-JWT.
|
|
19
|
+
*/
|
|
20
|
+
export declare const materializeSdJwtVcFixture: (fixture: SdJwtVcFixture, options: MaterializeSdJwtVcOptions) => Promise<MaterializedSdJwtVcFixture>;
|
|
21
|
+
//# sourceMappingURL=materialize-sd-jwt-vc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"materialize-sd-jwt-vc.d.ts","sourceRoot":"","sources":["../src/materialize-sd-jwt-vc.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAEjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,aAAa,GAAG,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEtE,MAAM,WAAW,yBAAyB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,aAAa,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,0BAA0B;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,wBAAwB,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC;CACf;AAsFD;;;GAGG;AACH,eAAO,MAAM,yBAAyB,GAClC,SAAS,cAAc,EACvB,SAAS,yBAAyB,KACnC,OAAO,CAAC,0BAA0B,CA6CpC,CAAC"}
|
package/dist/prepare.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { UnsignedVC } from '@learncard/types';
|
|
2
|
-
import type
|
|
2
|
+
import { type LibraryFixture } from './types';
|
|
3
3
|
export interface PrepareOptions {
|
|
4
4
|
/** Issuer DID — e.g. from wallet.id.did() */
|
|
5
5
|
issuerDid: string;
|
|
@@ -30,7 +30,7 @@ export interface PrepareOptions {
|
|
|
30
30
|
* await wallet.store.LearnCloud.uploadEncrypted(signed);
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
33
|
-
export declare const prepareFixture: (fixture:
|
|
33
|
+
export declare const prepareFixture: (fixture: LibraryFixture, options: PrepareOptions) => UnsignedVC;
|
|
34
34
|
/**
|
|
35
35
|
* Shorthand that combines getFixture + prepareFixture.
|
|
36
36
|
*
|
package/dist/prepare.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepare.d.ts","sourceRoot":"","sources":["../src/prepare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"prepare.d.ts","sourceRoot":"","sources":["../src/prepare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAOhE,MAAM,WAAW,cAAc;IAC3B,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAElB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAkGD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,cAAc,GAAI,SAAS,cAAc,EAAE,SAAS,cAAc,KAAG,UAyDjF,CAAC;AAMF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,GAAI,WAAW,MAAM,EAAE,SAAS,cAAc,KAAG,UAC9B,CAAC"}
|
package/dist/registry.d.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import type { UnsignedVC, VC } from '@learncard/types';
|
|
2
|
-
import type
|
|
3
|
-
export declare const registerFixture:
|
|
4
|
-
export declare const registerFixtures: (batch:
|
|
2
|
+
import { type CredentialFixture, type FixtureFilter, type LibraryFixture, type SdJwtVcFixture } from './types';
|
|
3
|
+
export declare const registerFixture: (fixture: LibraryFixture) => void;
|
|
4
|
+
export declare const registerFixtures: (batch: LibraryFixture[]) => void;
|
|
5
5
|
export declare const resetRegistry: () => void;
|
|
6
|
-
export declare const getAllFixtures: () => readonly
|
|
7
|
-
|
|
8
|
-
export declare
|
|
9
|
-
export declare
|
|
6
|
+
export declare const getAllFixtures: () => readonly LibraryFixture[];
|
|
7
|
+
type FixtureForId<Id extends string> = Id extends `sd-jwt-vc/${string}` ? SdJwtVcFixture : string extends Id ? LibraryFixture : CredentialFixture;
|
|
8
|
+
export declare function getFixture<Id extends string>(id: Id): FixtureForId<Id>;
|
|
9
|
+
export declare function findFixture<Id extends string>(id: Id): FixtureForId<Id> | undefined;
|
|
10
|
+
export declare const getFixtures: (filter: FixtureFilter) => LibraryFixture[];
|
|
10
11
|
export declare const getUnsignedFixtures: (filter?: FixtureFilter) => CredentialFixture<UnsignedVC>[];
|
|
11
12
|
export declare const getSignedFixtures: (filter?: FixtureFilter) => CredentialFixture<VC>[];
|
|
12
|
-
export declare const getValidFixtures: (filter?: FixtureFilter) =>
|
|
13
|
-
export declare const getInvalidFixtures: (filter?: FixtureFilter) =>
|
|
13
|
+
export declare const getValidFixtures: (filter?: FixtureFilter) => LibraryFixture[];
|
|
14
|
+
export declare const getInvalidFixtures: (filter?: FixtureFilter) => LibraryFixture[];
|
|
14
15
|
export interface RegistryStats {
|
|
15
16
|
total: number;
|
|
16
17
|
bySpec: Record<string, number>;
|
|
@@ -20,4 +21,5 @@ export interface RegistryStats {
|
|
|
20
21
|
unsigned: number;
|
|
21
22
|
}
|
|
22
23
|
export declare const getStats: () => RegistryStats;
|
|
24
|
+
export {};
|
|
23
25
|
//# sourceMappingURL=registry.d.ts.map
|
package/dist/registry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAGH,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAElB,KAAK,cAAc,EACnB,KAAK,cAAc,EACtB,MAAM,SAAS,CAAC;AA+EjB,eAAO,MAAM,eAAe,GAAI,SAAS,cAAc,KAAG,IAEzD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,OAAO,cAAc,EAAE,KAAG,IAI1D,CAAC;AAMF,eAAO,MAAM,aAAa,QAAO,IAIhC,CAAC;AAsEF,eAAO,MAAM,cAAc,QAAO,SAAS,cAAc,EAIxD,CAAC;AAEF,KAAK,YAAY,CAAC,EAAE,SAAS,MAAM,IAAI,EAAE,SAAS,aAAa,MAAM,EAAE,GACjE,cAAc,GACd,MAAM,SAAS,EAAE,GACjB,cAAc,GACd,iBAAiB,CAAC;AAExB,wBAAgB,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;AAexE,wBAAgB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,YAAY,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;AAOrF,eAAO,MAAM,WAAW,GAAI,QAAQ,aAAa,KAAG,cAAc,EAIjE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,SAAS,aAAa,KAAG,iBAAiB,CAAC,UAAU,CAAC,EAGlD,CAAC;AAEzC,eAAO,MAAM,iBAAiB,GAAI,SAAS,aAAa,KAAG,iBAAiB,CAAC,EAAE,CAAC,EACmB,CAAC;AAEpG,eAAO,MAAM,gBAAgB,GAAI,SAAS,aAAa,KAAG,cAAc,EACvB,CAAC;AAElD,eAAO,MAAM,kBAAkB,GAAI,SAAS,aAAa,KAAG,cAAc,EACT,CAAC;AAMlE,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,QAAQ,QAAO,aAyB3B,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
2
|
import type { UnsignedVC, VC } from '@learncard/types';
|
|
3
|
-
export declare const CREDENTIAL_SPECS: readonly ["vc-v1", "vc-v2", "obv3", "clr-v2", "europass", "custom"];
|
|
3
|
+
export declare const CREDENTIAL_SPECS: readonly ["vc-v1", "vc-v2", "obv3", "clr-v2", "europass", "sd-jwt-vc", "custom"];
|
|
4
4
|
export type CredentialSpec = (typeof CREDENTIAL_SPECS)[number];
|
|
5
5
|
export declare const CREDENTIAL_PROFILES: readonly ["badge", "diploma", "certificate", "id", "membership", "license", "micro-credential", "course", "degree", "boost", "boost-id", "delegate", "endorsement", "learner-record", "generic"];
|
|
6
6
|
export type CredentialProfile = (typeof CREDENTIAL_PROFILES)[number];
|
|
7
|
-
export declare const CREDENTIAL_FEATURES: readonly ["evidence", "alignment", "endorsement", "expiration", "status", "multiple-subjects", "multiple-proofs", "refresh-service", "terms-of-use", "credential-schema", "image", "results", "source", "skills", "display", "attachments", "associations", "nested-credentials"];
|
|
7
|
+
export declare const CREDENTIAL_FEATURES: readonly ["evidence", "alignment", "endorsement", "expiration", "status", "multiple-subjects", "multiple-proofs", "refresh-service", "terms-of-use", "credential-schema", "image", "results", "source", "skills", "display", "attachments", "associations", "nested-credentials", "selective-disclosure", "holder-binding"];
|
|
8
8
|
export type CredentialFeature = (typeof CREDENTIAL_FEATURES)[number];
|
|
9
9
|
export declare const FIXTURE_SOURCES: readonly ["spec-example", "plugfest", "real-world", "synthetic"];
|
|
10
10
|
export type FixtureSource = (typeof FIXTURE_SOURCES)[number];
|
|
11
11
|
export declare const FIXTURE_VALIDITIES: readonly ["valid", "invalid", "tampered"];
|
|
12
12
|
export type FixtureValidity = (typeof FIXTURE_VALIDITIES)[number];
|
|
13
|
+
export declare const FIXTURE_KINDS: readonly ["w3c-vc", "sd-jwt-vc"];
|
|
14
|
+
export type FixtureKind = (typeof FIXTURE_KINDS)[number];
|
|
13
15
|
export type InvalidCredential = Record<string, unknown>;
|
|
14
|
-
export interface
|
|
16
|
+
export interface BaseCredentialFixture {
|
|
15
17
|
/** Unique fixture ID, e.g. 'obv3/minimal-badge' */
|
|
16
18
|
id: string;
|
|
17
19
|
/** Human-readable name */
|
|
@@ -30,14 +32,38 @@ export interface CredentialFixture<T extends UnsignedVC | VC = UnsignedVC> {
|
|
|
30
32
|
signed: boolean;
|
|
31
33
|
/** Whether this fixture is intentionally valid, invalid, or tampered */
|
|
32
34
|
validity: FixtureValidity;
|
|
35
|
+
/** Additional free-form tags for ad-hoc filtering */
|
|
36
|
+
tags?: string[];
|
|
37
|
+
}
|
|
38
|
+
export interface CredentialFixture<T extends UnsignedVC | VC = UnsignedVC> extends BaseCredentialFixture {
|
|
39
|
+
/** Omitted for backwards compatibility; W3C VC is the default fixture kind */
|
|
40
|
+
kind?: 'w3c-vc';
|
|
41
|
+
/** SD-JWT VC uses a separate template fixture variant */
|
|
42
|
+
spec: Exclude<CredentialSpec, 'sd-jwt-vc'>;
|
|
33
43
|
/** The actual credential JSON */
|
|
34
44
|
credential: T;
|
|
35
45
|
/** Zod validator this credential should pass (if valid) or fail (if invalid) */
|
|
36
46
|
validator?: z.ZodType;
|
|
37
|
-
/** Additional free-form tags for ad-hoc filtering */
|
|
38
|
-
tags?: string[];
|
|
39
47
|
}
|
|
48
|
+
export interface SdJwtVcTemplate {
|
|
49
|
+
format: 'dc+sd-jwt';
|
|
50
|
+
vct: string;
|
|
51
|
+
claims: Record<string, unknown>;
|
|
52
|
+
selectivelyDisclosable: string[];
|
|
53
|
+
}
|
|
54
|
+
export interface SdJwtVcFixture extends BaseCredentialFixture {
|
|
55
|
+
kind: 'sd-jwt-vc';
|
|
56
|
+
id: `sd-jwt-vc/${string}`;
|
|
57
|
+
spec: 'sd-jwt-vc';
|
|
58
|
+
signed: false;
|
|
59
|
+
template: SdJwtVcTemplate;
|
|
60
|
+
}
|
|
61
|
+
export type LibraryFixture = CredentialFixture | SdJwtVcFixture;
|
|
62
|
+
export declare const isSdJwtVcFixture: (fixture: LibraryFixture) => fixture is SdJwtVcFixture;
|
|
63
|
+
export declare const isCredentialFixture: (fixture: LibraryFixture) => fixture is CredentialFixture;
|
|
40
64
|
export interface FixtureFilter {
|
|
65
|
+
/** Match any of the given fixture kinds (omitted W3C kind is treated as w3c-vc) */
|
|
66
|
+
kind?: FixtureKind | FixtureKind[];
|
|
41
67
|
/** Match any of the given specs */
|
|
42
68
|
spec?: CredentialSpec | CredentialSpec[];
|
|
43
69
|
/** Match any of the given profiles */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAMvD,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@learncard/credential-library",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Comprehensive library of Verifiable Credential fixtures for testing, development, and regression prevention across the VC ecosystem",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/credential-library.esm.js",
|
|
@@ -26,16 +26,19 @@
|
|
|
26
26
|
"url": "https://github.com/learningeconomy/LearnCard/issues"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@learncard/didkit-plugin": "1.9.
|
|
30
|
-
"@learncard/init": "2.4.
|
|
29
|
+
"@learncard/didkit-plugin": "1.9.13",
|
|
30
|
+
"@learncard/init": "2.4.14",
|
|
31
31
|
"@types/node": "^17.0.38",
|
|
32
32
|
"esbuild": "^0.27.1",
|
|
33
|
+
"jose": "^5.9.6",
|
|
33
34
|
"shx": "^0.3.4",
|
|
34
35
|
"typescript": "5.6.2",
|
|
35
36
|
"vitest": "4.1.10"
|
|
36
37
|
},
|
|
37
38
|
"dependencies": {
|
|
38
|
-
"@learncard/
|
|
39
|
+
"@learncard/sd-jwt-vc-plugin": "0.2.11",
|
|
40
|
+
"@learncard/types": "5.18.3",
|
|
41
|
+
"@sd-jwt/sd-jwt-vc": "^0.19.0",
|
|
39
42
|
"zod": "4.1.13"
|
|
40
43
|
},
|
|
41
44
|
"types": "./dist/index.d.ts",
|
|
@@ -4,7 +4,7 @@ import { describe, it, expect, beforeAll } from 'vitest';
|
|
|
4
4
|
|
|
5
5
|
import { initLearnCard } from '@learncard/init';
|
|
6
6
|
|
|
7
|
-
import { getAllFixtures, getFixture, prepareFixture } from '../index';
|
|
7
|
+
import { getAllFixtures, getFixture, isCredentialFixture, prepareFixture } from '../index';
|
|
8
8
|
|
|
9
9
|
import type { CredentialFixture } from '../types';
|
|
10
10
|
|
|
@@ -31,7 +31,10 @@ beforeAll(async () => {
|
|
|
31
31
|
|
|
32
32
|
describe('Credential issuance', () => {
|
|
33
33
|
const validFixtures = (): CredentialFixture[] =>
|
|
34
|
-
getAllFixtures().filter(
|
|
34
|
+
getAllFixtures().filter(
|
|
35
|
+
(fixture): fixture is CredentialFixture =>
|
|
36
|
+
fixture.validity === 'valid' && isCredentialFixture(fixture)
|
|
37
|
+
);
|
|
35
38
|
|
|
36
39
|
describe('issueCredential succeeds for all valid fixtures', () => {
|
|
37
40
|
it.each(validFixtures().map(f => [f.id, f] as const))(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll } from 'vitest';
|
|
1
|
+
import { describe, it, expect, expectTypeOf, beforeAll } from 'vitest';
|
|
2
2
|
import { UnsignedVCValidator } from '@learncard/types';
|
|
3
3
|
|
|
4
4
|
import {
|
|
@@ -10,7 +10,10 @@ import {
|
|
|
10
10
|
getValidFixtures,
|
|
11
11
|
getInvalidFixtures,
|
|
12
12
|
getStats,
|
|
13
|
+
isCredentialFixture,
|
|
14
|
+
isSdJwtVcFixture,
|
|
13
15
|
resetRegistry,
|
|
16
|
+
registerFixture,
|
|
14
17
|
registerFixtures,
|
|
15
18
|
prepareFixture,
|
|
16
19
|
prepareFixtureById,
|
|
@@ -18,13 +21,32 @@ import {
|
|
|
18
21
|
|
|
19
22
|
import { ALL_FIXTURES } from '../fixtures';
|
|
20
23
|
|
|
21
|
-
import type { CredentialFixture } from '../types';
|
|
24
|
+
import type { CredentialFixture, LibraryFixture, SdJwtVcFixture } from '../types';
|
|
25
|
+
|
|
26
|
+
const sdJwtFixture: SdJwtVcFixture = {
|
|
27
|
+
kind: 'sd-jwt-vc',
|
|
28
|
+
id: 'sd-jwt-vc/test-course',
|
|
29
|
+
name: 'Test Course',
|
|
30
|
+
description: 'Registry-only SD-JWT VC fixture',
|
|
31
|
+
spec: 'sd-jwt-vc',
|
|
32
|
+
profile: 'course',
|
|
33
|
+
features: ['selective-disclosure', 'holder-binding'],
|
|
34
|
+
source: 'synthetic',
|
|
35
|
+
signed: false,
|
|
36
|
+
validity: 'valid',
|
|
37
|
+
template: {
|
|
38
|
+
format: 'dc+sd-jwt',
|
|
39
|
+
vct: 'https://example.com/vct/test-course',
|
|
40
|
+
claims: { course_name: 'Test Course' },
|
|
41
|
+
selectivelyDisclosable: ['course_name'],
|
|
42
|
+
},
|
|
43
|
+
};
|
|
22
44
|
|
|
23
45
|
// ---------------------------------------------------------------------------
|
|
24
46
|
// Ensure fixtures are loaded
|
|
25
47
|
// ---------------------------------------------------------------------------
|
|
26
48
|
|
|
27
|
-
let fixtures: readonly
|
|
49
|
+
let fixtures: readonly LibraryFixture[];
|
|
28
50
|
|
|
29
51
|
beforeAll(() => {
|
|
30
52
|
fixtures = getAllFixtures();
|
|
@@ -56,7 +78,11 @@ describe('Registry integrity', () => {
|
|
|
56
78
|
expect(f.source).toBeTruthy();
|
|
57
79
|
expect(typeof f.signed).toBe('boolean');
|
|
58
80
|
expect(f.validity).toBeTruthy();
|
|
59
|
-
|
|
81
|
+
if (isCredentialFixture(f)) {
|
|
82
|
+
expect(f.credential).toBeTruthy();
|
|
83
|
+
} else {
|
|
84
|
+
expect(f.template).toBeTruthy();
|
|
85
|
+
}
|
|
60
86
|
}
|
|
61
87
|
});
|
|
62
88
|
});
|
|
@@ -67,7 +93,11 @@ describe('Registry integrity', () => {
|
|
|
67
93
|
|
|
68
94
|
describe('Fixture validation', () => {
|
|
69
95
|
describe('Valid fixtures pass their declared validator', () => {
|
|
70
|
-
const validFixtures = () =>
|
|
96
|
+
const validFixtures = () =>
|
|
97
|
+
getAllFixtures().filter(
|
|
98
|
+
(fixture): fixture is CredentialFixture =>
|
|
99
|
+
fixture.validity === 'valid' && isCredentialFixture(fixture)
|
|
100
|
+
);
|
|
71
101
|
|
|
72
102
|
it.each(validFixtures().map(f => [f.id, f] as const))('%s', (_id, fixture) => {
|
|
73
103
|
if (!fixture.validator) return;
|
|
@@ -79,7 +109,11 @@ describe('Fixture validation', () => {
|
|
|
79
109
|
});
|
|
80
110
|
|
|
81
111
|
describe('Valid fixtures also pass base UnsignedVC validator', () => {
|
|
82
|
-
const validFixtures = () =>
|
|
112
|
+
const validFixtures = () =>
|
|
113
|
+
getAllFixtures().filter(
|
|
114
|
+
(fixture): fixture is CredentialFixture =>
|
|
115
|
+
fixture.validity === 'valid' && isCredentialFixture(fixture)
|
|
116
|
+
);
|
|
83
117
|
|
|
84
118
|
it.each(validFixtures().map(f => [f.id, f] as const))('%s', (_id, fixture) => {
|
|
85
119
|
const result = UnsignedVCValidator.safeParse(fixture.credential);
|
|
@@ -90,7 +124,11 @@ describe('Fixture validation', () => {
|
|
|
90
124
|
|
|
91
125
|
describe('Invalid fixtures fail their declared validator', () => {
|
|
92
126
|
const invalidFixtures = () =>
|
|
93
|
-
getAllFixtures().filter(
|
|
127
|
+
getAllFixtures().filter(
|
|
128
|
+
(fixture): fixture is CredentialFixture =>
|
|
129
|
+
(fixture.validity === 'invalid' || fixture.validity === 'tampered') &&
|
|
130
|
+
isCredentialFixture(fixture)
|
|
131
|
+
);
|
|
94
132
|
|
|
95
133
|
it.each(invalidFixtures().map(f => [f.id, f] as const))('%s', (_id, fixture) => {
|
|
96
134
|
if (!fixture.validator) return;
|
|
@@ -114,6 +152,21 @@ describe('Query API', () => {
|
|
|
114
152
|
expect(fixture.spec).toBe('vc-v2');
|
|
115
153
|
});
|
|
116
154
|
|
|
155
|
+
it('registers the production Course Completion SD-JWT VC fixture', () => {
|
|
156
|
+
const fixture = getFixture('sd-jwt-vc/course-completion');
|
|
157
|
+
|
|
158
|
+
expect(isSdJwtVcFixture(fixture)).toBe(true);
|
|
159
|
+
if (!isSdJwtVcFixture(fixture)) throw new Error('Expected SD-JWT VC fixture');
|
|
160
|
+
|
|
161
|
+
expect(fixture.template.format).toBe('dc+sd-jwt');
|
|
162
|
+
expect(fixture.template.vct).toBe(
|
|
163
|
+
'https://credentials.learncard.com/vct/course-completion'
|
|
164
|
+
);
|
|
165
|
+
expect(getFixtures({ spec: 'sd-jwt-vc' }).map(item => item.id)).toContain(fixture.id);
|
|
166
|
+
expect(getFixtures({ kind: 'sd-jwt-vc' }).map(item => item.id)).toContain(fixture.id);
|
|
167
|
+
expect(getUnsignedFixtures().map(item => item.id)).not.toContain(fixture.id);
|
|
168
|
+
});
|
|
169
|
+
|
|
117
170
|
it('getFixture throws for unknown ID', () => {
|
|
118
171
|
expect(() => getFixture('nonexistent/fixture')).toThrow('not found');
|
|
119
172
|
});
|
|
@@ -122,6 +175,13 @@ describe('Query API', () => {
|
|
|
122
175
|
expect(findFixture('nonexistent/fixture')).toBeUndefined();
|
|
123
176
|
});
|
|
124
177
|
|
|
178
|
+
it('types runtime string fixture lookups as the heterogeneous library union', () => {
|
|
179
|
+
const runtimeId: string = 'sd-jwt-vc/course-completion';
|
|
180
|
+
|
|
181
|
+
expectTypeOf(getFixture(runtimeId)).toEqualTypeOf<LibraryFixture>();
|
|
182
|
+
expectTypeOf(findFixture(runtimeId)).toEqualTypeOf<LibraryFixture | undefined>();
|
|
183
|
+
});
|
|
184
|
+
|
|
125
185
|
it('filters by spec', () => {
|
|
126
186
|
const obv3 = getFixtures({ spec: 'obv3' });
|
|
127
187
|
|
|
@@ -195,6 +255,134 @@ describe('Query API', () => {
|
|
|
195
255
|
expect(unsigned.every(f => f.signed === false)).toBe(true);
|
|
196
256
|
});
|
|
197
257
|
|
|
258
|
+
it('narrows SD-JWT fixtures and keeps W3C helpers narrow', () => {
|
|
259
|
+
expect(isSdJwtVcFixture(sdJwtFixture)).toBe(true);
|
|
260
|
+
expect(isCredentialFixture(getFixture('vc-v2/basic'))).toBe(true);
|
|
261
|
+
expect(getUnsignedFixtures().every(isCredentialFixture)).toBe(true);
|
|
262
|
+
expect(() =>
|
|
263
|
+
prepareFixture(sdJwtFixture, { issuerDid: 'did:key:z6MkTestIssuer123' })
|
|
264
|
+
).toThrow('materializeSdJwtVcFixture');
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it('stores SD-JWT fixtures separately from W3C fixtures', () => {
|
|
268
|
+
resetRegistry();
|
|
269
|
+
|
|
270
|
+
try {
|
|
271
|
+
registerFixtures([...ALL_FIXTURES, sdJwtFixture]);
|
|
272
|
+
|
|
273
|
+
const sdJwtFixtures = getFixtures({ kind: 'sd-jwt-vc' });
|
|
274
|
+
expect(sdJwtFixtures).toContainEqual(sdJwtFixture);
|
|
275
|
+
expect(sdJwtFixtures.map(fixture => fixture.id)).toContain(
|
|
276
|
+
'sd-jwt-vc/course-completion'
|
|
277
|
+
);
|
|
278
|
+
const w3cFixtures = getFixtures({ kind: 'w3c-vc' });
|
|
279
|
+
expect(w3cFixtures).toHaveLength(ALL_FIXTURES.filter(isCredentialFixture).length);
|
|
280
|
+
expect(w3cFixtures.every(isCredentialFixture)).toBe(true);
|
|
281
|
+
expect(getFixture('sd-jwt-vc/test-course').template).toEqual(sdJwtFixture.template);
|
|
282
|
+
expect(getUnsignedFixtures().every(isCredentialFixture)).toBe(true);
|
|
283
|
+
expect(getUnsignedFixtures().some(fixture => fixture.id === sdJwtFixture.id)).toBe(
|
|
284
|
+
false
|
|
285
|
+
);
|
|
286
|
+
} finally {
|
|
287
|
+
resetRegistry();
|
|
288
|
+
getAllFixtures();
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
it('rejects SD-JWT fixtures outside the required ID prefix', () => {
|
|
293
|
+
resetRegistry();
|
|
294
|
+
|
|
295
|
+
try {
|
|
296
|
+
expect(() =>
|
|
297
|
+
registerFixture({
|
|
298
|
+
...sdJwtFixture,
|
|
299
|
+
id: 'custom/course',
|
|
300
|
+
} as unknown as LibraryFixture)
|
|
301
|
+
).toThrow('must start with "sd-jwt-vc/"');
|
|
302
|
+
} finally {
|
|
303
|
+
resetRegistry();
|
|
304
|
+
getAllFixtures();
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
it('rejects W3C fixtures inside the reserved SD-JWT ID prefix', () => {
|
|
309
|
+
const w3cFixture = ALL_FIXTURES.find(isCredentialFixture);
|
|
310
|
+
if (!w3cFixture) throw new Error('Expected at least one W3C fixture');
|
|
311
|
+
|
|
312
|
+
resetRegistry();
|
|
313
|
+
|
|
314
|
+
try {
|
|
315
|
+
expect(() =>
|
|
316
|
+
registerFixture({
|
|
317
|
+
...w3cFixture,
|
|
318
|
+
id: 'sd-jwt-vc/not-an-sd-jwt-template',
|
|
319
|
+
} as LibraryFixture)
|
|
320
|
+
).toThrow('reserved for SD-JWT VC fixtures');
|
|
321
|
+
} finally {
|
|
322
|
+
resetRegistry();
|
|
323
|
+
getAllFixtures();
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
it('rejects SD-JWT fixtures whose kind and spec disagree', () => {
|
|
328
|
+
resetRegistry();
|
|
329
|
+
|
|
330
|
+
try {
|
|
331
|
+
expect(() =>
|
|
332
|
+
registerFixture({
|
|
333
|
+
...sdJwtFixture,
|
|
334
|
+
spec: 'vc-v2',
|
|
335
|
+
} as unknown as LibraryFixture)
|
|
336
|
+
).toThrow('must use spec "sd-jwt-vc"');
|
|
337
|
+
} finally {
|
|
338
|
+
resetRegistry();
|
|
339
|
+
getAllFixtures();
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it('rejects unrecognized fixture kinds at registration', () => {
|
|
344
|
+
const w3cFixture = ALL_FIXTURES.find(isCredentialFixture);
|
|
345
|
+
if (!w3cFixture) throw new Error('Expected at least one W3C fixture');
|
|
346
|
+
|
|
347
|
+
resetRegistry();
|
|
348
|
+
|
|
349
|
+
try {
|
|
350
|
+
expect(() =>
|
|
351
|
+
registerFixture({
|
|
352
|
+
...w3cFixture,
|
|
353
|
+
kind: 'unknown-fixture-kind',
|
|
354
|
+
} as unknown as LibraryFixture)
|
|
355
|
+
).toThrow('Unsupported fixture kind "unknown-fixture-kind"');
|
|
356
|
+
} finally {
|
|
357
|
+
resetRegistry();
|
|
358
|
+
getAllFixtures();
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it.each([undefined, 'w3c-vc'] as const)(
|
|
363
|
+
'rejects W3C fixtures with kind %s and the SD-JWT spec',
|
|
364
|
+
kind => {
|
|
365
|
+
const w3cFixture = ALL_FIXTURES.find(isCredentialFixture);
|
|
366
|
+
if (!w3cFixture) throw new Error('Expected at least one W3C fixture');
|
|
367
|
+
|
|
368
|
+
resetRegistry();
|
|
369
|
+
|
|
370
|
+
try {
|
|
371
|
+
expect(() =>
|
|
372
|
+
registerFixture({
|
|
373
|
+
...w3cFixture,
|
|
374
|
+
kind,
|
|
375
|
+
id: 'custom/not-an-sd-jwt-template',
|
|
376
|
+
spec: 'sd-jwt-vc',
|
|
377
|
+
} as unknown as LibraryFixture)
|
|
378
|
+
).toThrow('W3C VC fixtures cannot use spec "sd-jwt-vc"');
|
|
379
|
+
} finally {
|
|
380
|
+
resetRegistry();
|
|
381
|
+
getAllFixtures();
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
);
|
|
385
|
+
|
|
198
386
|
it('combined filters work together', () => {
|
|
199
387
|
const results = getFixtures({
|
|
200
388
|
spec: 'obv3',
|