@owf/eudi-lote 0.3.2-alpha-20260713153517 → 0.3.2

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/dist/index.cjs CHANGED
@@ -1,29 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- //#region \0rolldown/runtime.js
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
- get: ((k) => from[k]).bind(null, key),
14
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
- });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
- value: mod,
21
- enumerable: true
22
- }) : target, mod));
23
- //#endregion
24
2
  let _owf_identity_common = require("@owf/identity-common");
25
3
  let zod = require("zod");
26
- zod = __toESM(zod);
27
4
  let _owf_crypto = require("@owf/crypto");
28
5
  //#region src/lote-exception.ts
29
6
  /**
@@ -432,6 +409,15 @@ function service() {
432
409
  //#endregion
433
410
  //#region src/profiles.ts
434
411
  const SIX_MONTHS_IN_MS = 4464 * 60 * 60 * 1e3;
412
+ const LOTE_TYPES = {
413
+ EUPIDProvidersList: "http://uri.etsi.org/19602/LoTEType/EUPIDProvidersList",
414
+ EUWalletProvidersList: "http://uri.etsi.org/19602/LoTEType/EUWalletProvidersList",
415
+ EUWRPACProvidersList: "http://uri.etsi.org/19602/LoTEType/EUWRPACProvidersList",
416
+ EUWRPRCProvidersList: "http://uri.etsi.org/19602/LoTEType/EUWRPRCProvidersList",
417
+ EUEAAProvidersList: "http://uri.etsi.org/19602/LoTEType/EUEAAProvidersList",
418
+ EUPubEAAProvidersList: "http://uri.etsi.org/19602/LoTEType/EUPubEAAProvidersList",
419
+ mDLProvidersList: "http://trust.ec.europa.eu/lists/mDL/mDLProvidersListType"
420
+ };
435
421
  const listAndSchemeInformationRefinement = ({ loTEType, loTEVersionIdentifier, statusDeterminationApproach, schemeTerritory, schemeTypeCommunityRulesUri, historicalInformationPeriod, requireNoHistoricalInformationPeriod, requireNoPointersToOtherLoTE }) => ({ LoTE }, ctx) => {
436
422
  const info = LoTE.ListAndSchemeInformation;
437
423
  const path = ["LoTE", "ListAndSchemeInformation"];
@@ -557,7 +543,7 @@ const trustedEntitiesListRefinement = ({ allowedServiceTypeIdentifiers, informat
557
543
  });
558
544
  };
559
545
  const EUPIDProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInformationRefinement({
560
- loTEType: "http://uri.etsi.org/19602/LoTEType/EUPIDProvidersList",
546
+ loTEType: LOTE_TYPES.EUPIDProvidersList,
561
547
  loTEVersionIdentifier: 1,
562
548
  statusDeterminationApproach: "http://uri.etsi.org/19602/PIDProvidersList/StatusDetn/EU",
563
549
  schemeTerritory: "EU",
@@ -568,7 +554,7 @@ const EUPIDProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInf
568
554
  informationUriPrefix: "http://uri.etsi.org/19602/ListOfTrustedEntities/PIDProvider/"
569
555
  }));
570
556
  const EUWalletProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInformationRefinement({
571
- loTEType: "http://uri.etsi.org/19602/LoTEType/EUWalletProvidersList",
557
+ loTEType: LOTE_TYPES.EUWalletProvidersList,
572
558
  loTEVersionIdentifier: 1,
573
559
  statusDeterminationApproach: "http://uri.etsi.org/19602/WalletProvidersList/StatusDetn/EU",
574
560
  schemeTerritory: "EU",
@@ -579,7 +565,7 @@ const EUWalletProvidersListSchema = LoTEDocumentSchema.superRefine(listAndScheme
579
565
  informationUriPrefix: "http://uri.etsi.org/19602/ListOfTrustedEntities/WalletProvider/"
580
566
  }));
581
567
  const EUWRPACProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInformationRefinement({
582
- loTEType: "http://uri.etsi.org/19602/LoTEType/EUWRPACProvidersList",
568
+ loTEType: LOTE_TYPES.EUWRPACProvidersList,
583
569
  loTEVersionIdentifier: 1,
584
570
  statusDeterminationApproach: "http://uri.etsi.org/19602/WRPACProvidersList/StatusDetn/EU",
585
571
  schemeTerritory: "EU",
@@ -590,7 +576,7 @@ const EUWRPACProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeI
590
576
  informationUriPrefix: "http://uri.etsi.org/19602/ListOfTrustedEntities/WRPACProvider/"
591
577
  }));
592
578
  const EUWRPRCProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInformationRefinement({
593
- loTEType: "http://uri.etsi.org/19602/LoTEType/EUWRPRCProvidersList",
579
+ loTEType: LOTE_TYPES.EUWRPRCProvidersList,
594
580
  loTEVersionIdentifier: 1,
595
581
  statusDeterminationApproach: "http://uri.etsi.org/19602/WRPRCrovidersList/StatusDetn/EU",
596
582
  schemeTerritory: "EU",
@@ -601,7 +587,7 @@ const EUWRPRCProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeI
601
587
  informationUriPrefix: "http://uri.etsi.org/19602/ListOfTrustedEntities/WRPRCProvider/"
602
588
  }));
603
589
  const EUEAAProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInformationRefinement({
604
- loTEType: "http://uri.etsi.org/19602/LoTEType/EUEAAProvidersList",
590
+ loTEType: LOTE_TYPES.EUEAAProvidersList,
605
591
  loTEVersionIdentifier: 1,
606
592
  statusDeterminationApproach: "http://uri.etsi.org/19602/EAAProvidersList/StatusDetn/EU\"",
607
593
  schemeTerritory: "EU",
@@ -612,7 +598,7 @@ const EUEAAProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInf
612
598
  informationUriPrefix: "http://uri.etsi.org/19602/ListOfTrustedEntities/EAAProvider/"
613
599
  }));
614
600
  const EUPubEAAProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInformationRefinement({
615
- loTEType: "http://uri.etsi.org/19602/LoTEType/EUPubEAAProvidersList",
601
+ loTEType: LOTE_TYPES.EUPubEAAProvidersList,
616
602
  loTEVersionIdentifier: 1,
617
603
  statusDeterminationApproach: "http://uri.etsi.org/19602/PubEAAProvidersList/StatusDetn/EU\"",
618
604
  schemeTerritory: "EU",
@@ -624,7 +610,7 @@ const EUPubEAAProvidersListSchema = LoTEDocumentSchema.superRefine(listAndScheme
624
610
  informationUriPrefix: "http://uri.etsi.org/19602/ListOfTrustedEntities/PubEAAProvider/"
625
611
  }));
626
612
  const mDLProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInformationRefinement({
627
- loTEType: "http://trust.ec.europa.eu/lists/mDL/mDLProvidersListType",
613
+ loTEType: LOTE_TYPES.mDLProvidersList,
628
614
  loTEVersionIdentifier: 1,
629
615
  statusDeterminationApproach: "http://trust.ec.europa.eu/lists/mDL/mDLProvidersListStatusDetn",
630
616
  schemeTerritory: "EU",
@@ -769,11 +755,6 @@ function removeTrustedEntity(lote, entityName) {
769
755
  //#endregion
770
756
  //#region src/validator.ts
771
757
  /**
772
- * LoTE Validator
773
- *
774
- * Runtime validation for ETSI TS 119 602 LoTE documents using Zod schemas.
775
- */
776
- /**
777
758
  * Validate a LoTE document against ETSI TS 119 602 schema
778
759
  *
779
760
  * @param loteDocument - The LoTE document to validate
@@ -824,15 +805,44 @@ let LoTEProfile = /* @__PURE__ */ function(LoTEProfile) {
824
805
  LoTEProfile["mDLProvidersList"] = "mDLProvidersList";
825
806
  return LoTEProfile;
826
807
  }({});
827
- const profileToSchemaMap = {
828
- ["EUPIDProvidersList"]: EUPIDProvidersListSchema,
829
- ["EUWalletProvidersList"]: EUWalletProvidersListSchema,
830
- ["EUWRPACProvidersList"]: EUWRPACProvidersListSchema,
831
- ["EUWRPRCProvidersList"]: EUWRPRCProvidersListSchema,
832
- ["EUEAAProvidersList"]: EUEAAProvidersListSchema,
833
- ["EUPubEAAProvidersList"]: EUPubEAAProvidersListSchema,
834
- ["mDLProvidersList"]: mDLProvidersListSchema
808
+ const profileConfig = {
809
+ ["EUPIDProvidersList"]: {
810
+ loTEType: LOTE_TYPES.EUPIDProvidersList,
811
+ schema: EUPIDProvidersListSchema
812
+ },
813
+ ["EUWalletProvidersList"]: {
814
+ loTEType: LOTE_TYPES.EUWalletProvidersList,
815
+ schema: EUWalletProvidersListSchema
816
+ },
817
+ ["EUWRPACProvidersList"]: {
818
+ loTEType: LOTE_TYPES.EUWRPACProvidersList,
819
+ schema: EUWRPACProvidersListSchema
820
+ },
821
+ ["EUWRPRCProvidersList"]: {
822
+ loTEType: LOTE_TYPES.EUWRPRCProvidersList,
823
+ schema: EUWRPRCProvidersListSchema
824
+ },
825
+ ["EUEAAProvidersList"]: {
826
+ loTEType: LOTE_TYPES.EUEAAProvidersList,
827
+ schema: EUEAAProvidersListSchema
828
+ },
829
+ ["EUPubEAAProvidersList"]: {
830
+ loTEType: LOTE_TYPES.EUPubEAAProvidersList,
831
+ schema: EUPubEAAProvidersListSchema
832
+ },
833
+ ["mDLProvidersList"]: {
834
+ loTEType: LOTE_TYPES.mDLProvidersList,
835
+ schema: mDLProvidersListSchema
836
+ }
835
837
  };
838
+ function getDocumentLoTEType(loteDocument) {
839
+ try {
840
+ const type = loteDocument?.LoTE?.ListAndSchemeInformation?.LoTEType;
841
+ return typeof type === "string" ? type : void 0;
842
+ } catch {
843
+ return;
844
+ }
845
+ }
836
846
  /**
837
847
  * Validate a LoTE document against one or more given profiles. Validation
838
848
  * succeeds if the document matches one of the specified profiles
@@ -843,26 +853,34 @@ const profileToSchemaMap = {
843
853
  */
844
854
  function validateLoTEProfile(loteDocument, profile) {
845
855
  const profiles = Array.isArray(profile) ? profile : [profile];
846
- const result = zod.default.union(profiles.map((p) => profileToSchemaMap[p])).safeParse(loteDocument);
847
- if (result.success) return {
848
- valid: true,
849
- errors: []
850
- };
856
+ const documentLoTEType = getDocumentLoTEType(loteDocument);
857
+ const matchedProfile = profiles.find((p) => profileConfig[p].loTEType === documentLoTEType);
858
+ if (matchedProfile) {
859
+ const result = profileConfig[matchedProfile].schema.safeParse(loteDocument);
860
+ if (result.success) return {
861
+ valid: true,
862
+ errors: []
863
+ };
864
+ return {
865
+ valid: false,
866
+ errors: [{
867
+ path: "LoTEType",
868
+ message: `Document does not match profile ${matchedProfile}`
869
+ }, ...result.error.issues.map((issue) => ({
870
+ path: issue.path.join("."),
871
+ message: `Profile ${matchedProfile}: ${issue.message}`
872
+ }))]
873
+ };
874
+ }
851
875
  return {
852
876
  valid: false,
853
877
  errors: [{
854
878
  path: "LoTEType",
855
879
  message: `Document does not match any of the specified profiles: ${profiles.join(", ")}`
856
- }, ...result.error.issues.flatMap((issue) => {
857
- if (issue.code === "invalid_union") return issue.errors.flatMap((branchIssues, index) => branchIssues.map((branchIssue) => ({
858
- path: branchIssue.path.join("."),
859
- message: `Profile ${profiles[index]}: ${branchIssue.message}`
860
- })));
861
- return [{
862
- path: issue.path.join("."),
863
- message: issue.message
864
- }];
865
- })]
880
+ }, ...profiles.map((p) => ({
881
+ path: "LoTE.ListAndSchemeInformation.LoTEType",
882
+ message: `Profile ${p}: LoTEType must be ${profileConfig[p].loTEType}`
883
+ }))]
866
884
  };
867
885
  }
868
886
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["IdentityException","z","parseCertificate","z"],"sources":["../src/lote-exception.ts","../src/schemas.ts","../src/builders.ts","../src/profiles.ts","../src/signer.ts","../src/validator.ts"],"sourcesContent":["import { IdentityException } from '@owf/identity-common'\n\n/**\n * LoTEException is a custom error class for LoTE-related exceptions.\n */\nexport class LoTEException extends IdentityException {\n constructor(message: string, details?: unknown) {\n super(message, details)\n Object.setPrototypeOf(this, LoTEException.prototype)\n this.name = 'LoTEException'\n }\n}\n","/**\n * LoTE Zod Schemas\n *\n * Zod schemas for ETSI TS 119 602 (LoTE - List of Trusted Entities) format.\n * Types are derived from these schemas via z.infer<>.\n *\n * @see https://www.etsi.org/deliver/etsi_ts/119600_119699/119602/01.01.01_60/ts_119602v010101p.pdf\n */\n\nimport { z } from 'zod'\n\n// ============================================================================\n// Localized Value Schemas\n// ============================================================================\n\nexport const LocalizedStringSchema = z.object({\n lang: z.string().min(1),\n value: z.string().min(1),\n})\n\nexport const LocalizedURISchema = z.object({\n lang: z.string().min(1),\n uriValue: z.url(),\n})\n\n// ============================================================================\n// Address Schemas\n// ============================================================================\n\nexport const PostalAddressSchema = z.object({\n lang: z.string().min(1),\n StreetAddress: z.string(),\n Locality: z.string(),\n StateOrProvince: z.string().optional(),\n PostalCode: z.string(),\n Country: z.string().length(2),\n})\n\nexport const SchemeOperatorAddressSchema = z.object({\n SchemeOperatorPostalAddress: z.array(PostalAddressSchema),\n SchemeOperatorElectronicAddress: z.array(LocalizedURISchema),\n})\n\nexport const TrustedEntityAddressSchema = z.object({\n TEPostalAddress: z.array(PostalAddressSchema),\n TEElectronicAddress: z.array(LocalizedURISchema),\n})\n\n// ============================================================================\n// Digital Identity Schemas\n// ============================================================================\n\nexport const PkiObjectSchema = z.object({\n encoding: z.string().optional(),\n specRef: z.string().optional(),\n val: z.string().min(1),\n})\n\nexport const X509CertificateRefSchema = PkiObjectSchema.extend({\n encoding: z.literal('urn:ietf:params:tls-cert-type:x509').optional(),\n specRef: z.literal('RFC5280').optional(),\n})\n\nexport const JWKPublicKeySchema = z.looseObject({\n kty: z.enum(['RSA', 'EC', 'OKP']),\n kid: z.string().optional(),\n use: z.enum(['sig', 'enc']).optional(),\n alg: z.string().optional(),\n})\n\nexport const ServiceDigitalIdentitySchema = z\n .object({\n X509Certificates: z.array(X509CertificateRefSchema).optional(),\n X509SubjectNames: z.array(z.string()).optional(),\n PublicKeyValues: z.array(JWKPublicKeySchema).optional(),\n X509SKIs: z.array(z.string()).optional(),\n OtherIds: z.array(z.string()).optional(),\n })\n .refine(\n (id) =>\n (id.X509Certificates && id.X509Certificates.length > 0) ||\n (id.X509SubjectNames && id.X509SubjectNames.length > 0) ||\n (id.PublicKeyValues && id.PublicKeyValues.length > 0) ||\n (id.X509SKIs && id.X509SKIs.length > 0) ||\n (id.OtherIds && id.OtherIds.length > 0),\n { message: 'At least one digital identity type must be provided' }\n )\n\n// ============================================================================\n// Service Schemas\n// ============================================================================\n\nexport const ServiceSupplyPointSchema = z.object({\n ServiceType: z.string(),\n uriValue: z.url(),\n})\n\nexport const ServiceInformationSchema = z.object({\n ServiceName: z.array(LocalizedStringSchema).min(1),\n ServiceDigitalIdentity: ServiceDigitalIdentitySchema,\n ServiceTypeIdentifier: z.url().optional(),\n ServiceStatus: z.url().optional(),\n StatusStartingTime: z.iso.datetime().optional(),\n SchemeServiceDefinitionURI: z.array(LocalizedURISchema).optional(),\n ServiceSupplyPoints: z.array(ServiceSupplyPointSchema).optional(),\n ServiceDefinitionURI: z.array(LocalizedURISchema).optional(),\n ServiceInformationExtensions: z.array(z.unknown()).optional(),\n})\n\nexport const ServiceHistoryInstanceSchema = z.object({\n ServiceName: z.array(LocalizedStringSchema).min(1),\n ServiceDigitalIdentity: ServiceDigitalIdentitySchema,\n ServiceStatus: z.url(),\n StatusStartingTime: z.iso.datetime(),\n ServiceTypeIdentifier: z.url().optional(),\n ServiceInformationExtensions: z.array(z.unknown()).optional(),\n})\n\nexport const TrustedEntityServiceSchema = z.object({\n ServiceInformation: ServiceInformationSchema,\n ServiceHistory: z.array(ServiceHistoryInstanceSchema).optional(),\n})\n\n// ============================================================================\n// Trusted Entity Schemas\n// ============================================================================\n\nexport const TrustedEntityInformationSchema = z.object({\n TEName: z.array(LocalizedStringSchema).min(1),\n TETradeName: z.array(LocalizedStringSchema).optional(),\n TEAddress: TrustedEntityAddressSchema,\n TEInformationURI: z.array(LocalizedURISchema).optional(),\n TEInformationExtensions: z.array(z.unknown()).optional(),\n})\n\nexport const TrustedEntitySchema = z.object({\n TrustedEntityInformation: TrustedEntityInformationSchema,\n TrustedEntityServices: z.array(TrustedEntityServiceSchema).min(1),\n})\n\n// ============================================================================\n// List and Scheme Information Schemas\n// ============================================================================\n\nexport const PolicyOrLegalNoticeSchema = z.object({\n LoTEPolicy: LocalizedURISchema.optional(),\n LoTELegalNotice: LocalizedStringSchema.optional(),\n})\n\nexport const LoTEQualifierSchema = z.object({\n LoTEType: z.url(),\n SchemeOperatorName: z.array(LocalizedStringSchema).min(1),\n SchemeTypeCommunityRules: z.array(LocalizedURISchema).optional(),\n SchemeTerritory: z.string().length(2).optional(),\n MimeType: z.string().min(1),\n})\n\nexport const OtherLoTEPointerSchema = z.object({\n LoTELocation: z.url(),\n ServiceDigitalIdentities: z.array(ServiceDigitalIdentitySchema).min(1),\n LoTEQualifiers: z.array(LoTEQualifierSchema).min(1),\n})\n\nexport const ListAndSchemeInformationSchema = z.object({\n LoTEVersionIdentifier: z.number().int(),\n LoTESequenceNumber: z.number().int(),\n LoTEType: z.url().optional(),\n SchemeOperatorName: z.array(LocalizedStringSchema).min(1),\n SchemeOperatorAddress: SchemeOperatorAddressSchema.optional(),\n SchemeName: z.array(LocalizedStringSchema).optional(),\n SchemeInformationURI: z.array(LocalizedURISchema).optional(),\n StatusDeterminationApproach: z.url().optional(),\n SchemeTypeCommunityRules: z.array(LocalizedURISchema).optional(),\n SchemeTerritory: z.string().length(2).optional(),\n PolicyOrLegalNotice: z.array(PolicyOrLegalNoticeSchema).optional(),\n HistoricalInformationPeriod: z.number().optional(),\n PointersToOtherLoTE: z.array(OtherLoTEPointerSchema).optional(),\n ListIssueDateTime: z.iso.datetime(),\n NextUpdate: z.iso.datetime(),\n DistributionPoints: z.array(z.url()).optional(),\n SchemeExtensions: z.array(z.unknown()).optional(),\n})\n\n// ============================================================================\n// LoTE Root Schemas\n// ============================================================================\n\nexport const LoTESchema = z.object({\n ListAndSchemeInformation: ListAndSchemeInformationSchema,\n TrustedEntitiesList: z.array(TrustedEntitySchema),\n})\n\nexport const LoTEDocumentSchema = z.object({\n LoTE: LoTESchema,\n})\n","import { LoTEException } from './lote-exception'\nimport { TrustedEntitySchema, TrustedEntityServiceSchema } from './schemas'\nimport type {\n JWKPublicKey,\n PostalAddress,\n ServiceHistoryInstance,\n ServiceInformation,\n TrustedEntity,\n TrustedEntityInformation,\n TrustedEntityService,\n} from './types'\n\n/**\n * Builder for creating TrustedEntity objects with a fluent API\n */\nexport class TrustedEntityBuilder {\n private info: Partial<TrustedEntityInformation> = {}\n private services: TrustedEntityService[] = []\n\n /**\n * Set the entity name\n */\n name(value: string, lang = 'en'): this {\n this.info.TEName = this.info.TEName ?? []\n this.info.TEName.push({ lang, value })\n return this\n }\n\n /**\n * Set the trade name\n */\n tradeName(value: string, lang = 'en'): this {\n this.info.TETradeName = this.info.TETradeName ?? []\n this.info.TETradeName.push({ lang, value })\n return this\n }\n\n /**\n * Set the postal address\n */\n postalAddress(address: Omit<PostalAddress, 'lang'>, lang = 'en'): this {\n this.info.TEAddress = this.info.TEAddress ?? {\n TEPostalAddress: [],\n TEElectronicAddress: [],\n }\n this.info.TEAddress.TEPostalAddress.push({ ...address, lang })\n return this\n }\n\n /**\n * Add an electronic address (email)\n */\n email(email: string, lang = 'en'): this {\n this.info.TEAddress = this.info.TEAddress ?? {\n TEPostalAddress: [],\n TEElectronicAddress: [],\n }\n this.info.TEAddress.TEElectronicAddress.push({\n lang,\n uriValue: email.startsWith('mailto:') ? email : `mailto:${email}`,\n })\n return this\n }\n\n /**\n * Add an information URI\n */\n infoUri(uri: string, lang = 'en'): this {\n this.info.TEInformationURI = this.info.TEInformationURI ?? []\n this.info.TEInformationURI.push({ lang, uriValue: uri })\n return this\n }\n\n /**\n * Add a website URL as an electronic address\n */\n website(url: string, lang = 'en'): this {\n this.info.TEAddress = this.info.TEAddress ?? {\n TEPostalAddress: [],\n TEElectronicAddress: [],\n }\n this.info.TEAddress.TEElectronicAddress.push({\n lang,\n uriValue: url.startsWith('http') ? url : `https://${url}`,\n })\n return this\n }\n\n /**\n * Add custom extensions\n */\n addExtension(extension: unknown): this {\n this.info.TEInformationExtensions = this.info.TEInformationExtensions ?? []\n this.info.TEInformationExtensions.push(extension)\n return this\n }\n\n /**\n * Add a service to the entity\n */\n addService(service: TrustedEntityService): this {\n this.services.push(service)\n return this\n }\n\n /**\n * Build the TrustedEntity object\n */\n build(): TrustedEntity {\n const result = TrustedEntitySchema.safeParse({\n TrustedEntityInformation: this.info,\n TrustedEntityServices: this.services,\n })\n\n if (!result.success) {\n const messages = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('\\n')\n throw new LoTEException(`Invalid TrustedEntity:\\n${messages}`)\n }\n\n return result.data\n }\n}\n\n/**\n * Builder for creating TrustedEntityService objects\n */\nexport class ServiceBuilder {\n private info: Partial<ServiceInformation> = {}\n private history: ServiceHistoryInstance[] = []\n\n /**\n * Set the service name\n */\n name(value: string, lang = 'en'): this {\n this.info.ServiceName = this.info.ServiceName ?? []\n this.info.ServiceName.push({ lang, value })\n return this\n }\n\n /**\n * Set the service type identifier\n */\n type(typeUri: string): this {\n this.info.ServiceTypeIdentifier = typeUri\n return this\n }\n\n /**\n * Set the service status\n */\n status(statusUri: string, startingTime?: Date): this {\n this.info.ServiceStatus = statusUri\n this.info.StatusStartingTime = startingTime?.toISOString() ?? new Date().toISOString()\n return this\n }\n\n /**\n * Add an X.509 certificate to the digital identity\n */\n addCertificate(certBase64: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.X509Certificates = this.info.ServiceDigitalIdentity.X509Certificates ?? []\n this.info.ServiceDigitalIdentity.X509Certificates.push({\n encoding: 'urn:ietf:params:tls-cert-type:x509',\n specRef: 'RFC5280',\n val: certBase64,\n })\n return this\n }\n\n /**\n * Add an X.509 subject name (DN format) to the digital identity\n */\n addX509SubjectName(subjectName: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.X509SubjectNames = this.info.ServiceDigitalIdentity.X509SubjectNames ?? []\n this.info.ServiceDigitalIdentity.X509SubjectNames.push(subjectName)\n return this\n }\n\n /**\n * Add an X.509 Subject Key Identifier (base64-encoded) to the digital identity\n */\n addX509SKI(ski: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.X509SKIs = this.info.ServiceDigitalIdentity.X509SKIs ?? []\n this.info.ServiceDigitalIdentity.X509SKIs.push(ski)\n return this\n }\n\n /**\n * Add another identifier to the digital identity\n */\n addOtherId(id: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.OtherIds = this.info.ServiceDigitalIdentity.OtherIds ?? []\n this.info.ServiceDigitalIdentity.OtherIds.push(id)\n return this\n }\n\n /**\n * Add a public key (JWK) to the digital identity\n */\n addPublicKey(jwk: JWKPublicKey): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.PublicKeyValues = this.info.ServiceDigitalIdentity.PublicKeyValues ?? []\n this.info.ServiceDigitalIdentity.PublicKeyValues.push(jwk)\n return this\n }\n\n /**\n * Add a service endpoint\n */\n addEndpoint(type: string, uri: string): this {\n this.info.ServiceSupplyPoints = this.info.ServiceSupplyPoints ?? []\n this.info.ServiceSupplyPoints.push({ ServiceType: type, uriValue: uri })\n return this\n }\n\n /**\n * Add a service definition URI\n */\n addDefinitionUri(uri: string, lang = 'en'): this {\n this.info.ServiceDefinitionURI = this.info.ServiceDefinitionURI ?? []\n this.info.ServiceDefinitionURI.push({ lang, uriValue: uri })\n return this\n }\n\n /**\n * Add custom service information extensions\n */\n addExtension(extension: unknown): this {\n this.info.ServiceInformationExtensions = this.info.ServiceInformationExtensions ?? []\n this.info.ServiceInformationExtensions.push(extension)\n return this\n }\n\n /**\n * Add a historical service instance\n */\n addHistoryEntry(historyInstance: ServiceHistoryInstance): this {\n this.history.push(historyInstance)\n return this\n }\n\n /**\n * Build the TrustedEntityService object\n */\n build(): TrustedEntityService {\n const data: Record<string, unknown> = {\n ServiceInformation: this.info,\n }\n\n if (this.history.length > 0) {\n data.ServiceHistory = this.history\n }\n\n const result = TrustedEntityServiceSchema.safeParse(data)\n\n if (!result.success) {\n const messages = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('\\n')\n throw new LoTEException(`Invalid TrustedEntityService:\\n${messages}`)\n }\n\n return result.data\n }\n}\n\n/**\n * Create a new TrustedEntityBuilder\n */\nexport function trustedEntity(): TrustedEntityBuilder {\n return new TrustedEntityBuilder()\n}\n\n/**\n * Create a new ServiceBuilder\n */\nexport function service(): ServiceBuilder {\n return new ServiceBuilder()\n}\n","/**\n * LoTE Profiles\n *\n * @see https://www.etsi.org/deliver/etsi_ts/119600_119699/119602/01.01.01_60/ts_119602v010101p.pdf\n * @see https://acceptance.eidas.ec.europa.eu/efda/wallet/lists-of-trusted-entities/mdl-providers\n */\n\nimport type z from 'zod'\nimport { LoTEDocumentSchema } from './schemas'\nimport type { LoTEDocument } from './types'\n\nconst SIX_MONTHS_IN_MS = 6 * 31 * 24 * 60 * 60 * 1000\n\ntype ListAndSchemeInformationRefinementOptions = {\n loTEType: string\n loTEVersionIdentifier: number\n statusDeterminationApproach: string\n schemeTerritory: string\n schemeTypeCommunityRulesUri: string\n historicalInformationPeriod?: number\n requireNoHistoricalInformationPeriod?: boolean\n requireNoPointersToOtherLoTE?: boolean\n}\n\nconst listAndSchemeInformationRefinement =\n ({\n loTEType,\n loTEVersionIdentifier,\n statusDeterminationApproach,\n schemeTerritory,\n schemeTypeCommunityRulesUri,\n historicalInformationPeriod,\n requireNoHistoricalInformationPeriod,\n requireNoPointersToOtherLoTE,\n }: ListAndSchemeInformationRefinementOptions) =>\n ({ LoTE }: LoTEDocument, ctx: z.RefinementCtx<LoTEDocument>) => {\n const info = LoTE.ListAndSchemeInformation\n const path = ['LoTE', 'ListAndSchemeInformation']\n\n if (info.LoTEType !== loTEType) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [loTEType],\n message: `LoTEType must be ${loTEType}`,\n path: [...path, 'LoTEType'],\n })\n }\n\n if (info.LoTEVersionIdentifier !== loTEVersionIdentifier) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [loTEVersionIdentifier],\n message: `LoTEVersionIdentifier must be ${loTEVersionIdentifier}`,\n path: [...path, 'LoTEVersionIdentifier'],\n })\n }\n\n if (info.StatusDeterminationApproach !== statusDeterminationApproach) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [statusDeterminationApproach],\n message: `StatusDeterminationApproach must be ${statusDeterminationApproach}`,\n path: [...path, 'StatusDeterminationApproach'],\n })\n }\n\n if (info.SchemeTerritory !== schemeTerritory) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [schemeTerritory],\n message: `SchemeTerritory must be ${schemeTerritory}`,\n path: [...path, 'SchemeTerritory'],\n })\n }\n\n if (\n !info.SchemeTypeCommunityRules ||\n info.SchemeTypeCommunityRules.length !== 1 ||\n info.SchemeTypeCommunityRules[0].uriValue !== schemeTypeCommunityRulesUri\n ) {\n ctx.addIssue({\n code: 'custom',\n message: `SchemeTypeCommunityRules must contain a single element with uriValue of ${schemeTypeCommunityRulesUri}`,\n path: [...path, 'SchemeTypeCommunityRules'],\n })\n }\n\n if (requireNoHistoricalInformationPeriod && typeof info.HistoricalInformationPeriod !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'HistoricalInformationPeriod must not be present',\n path: [...path, 'HistoricalInformationPeriod'],\n })\n }\n\n if (historicalInformationPeriod !== undefined && info.HistoricalInformationPeriod !== historicalInformationPeriod) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [historicalInformationPeriod],\n message: `HistoricalInformationPeriod must be ${historicalInformationPeriod}`,\n path: [...path, 'HistoricalInformationPeriod'],\n })\n }\n\n if (requireNoPointersToOtherLoTE && typeof info.PointersToOtherLoTE !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'PointersToOtherLoTE must not be present',\n path: [...path, 'PointersToOtherLoTE'],\n })\n }\n\n const listIssueDateTime = new Date(info.ListIssueDateTime).getTime()\n const nextUpdate = new Date(info.NextUpdate).getTime()\n\n if (nextUpdate - listIssueDateTime > SIX_MONTHS_IN_MS) {\n ctx.addIssue({\n code: 'custom',\n message: 'NextUpdate must be within 6 months of ListIssueDateTime',\n path: [...path, 'NextUpdate'],\n })\n }\n }\n\ntype TrustedEntitiesListRefinementOptions = {\n allowedServiceTypeIdentifiers: string[]\n informationUriPrefix?: string\n}\n\nconst trustedEntitiesListRefinement =\n ({ allowedServiceTypeIdentifiers, informationUriPrefix }: TrustedEntitiesListRefinementOptions) =>\n ({ LoTE }: LoTEDocument, ctx: z.RefinementCtx<LoTEDocument>) => {\n LoTE.TrustedEntitiesList.forEach((entity, index) => {\n const trustedEntityPath = ['LoTE', 'TrustedEntitiesList', index.toString()]\n\n if (informationUriPrefix) {\n const uri = entity.TrustedEntityInformation.TEInformationURI?.find(({ uriValue }) =>\n uriValue.startsWith(informationUriPrefix)\n )\n\n if (!uri) {\n ctx.addIssue({\n code: 'custom',\n message: `Each TrustedEntityInformation.TEInformationURI must contain at least one URI starting with ${informationUriPrefix}`,\n path: [...trustedEntityPath, 'TrustedEntityInformation', 'TEInformationURI'],\n })\n } else {\n const rest = uri.uriValue.substring(informationUriPrefix.length)\n if (rest.length !== 2) {\n ctx.addIssue({\n code: 'custom',\n message: `URI starting with ${informationUriPrefix} must be followed by a 2-letter country code`,\n path: [...trustedEntityPath, 'TrustedEntityInformation', 'TEInformationURI'],\n })\n }\n }\n }\n\n entity.TrustedEntityServices.forEach((service, serviceIndex) => {\n const entityServicePath = [...trustedEntityPath, 'TrustedEntityServices', serviceIndex.toString()]\n\n if (typeof service.ServiceInformation.ServiceStatus !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'ServiceStatus must not be present',\n path: [...entityServicePath, 'ServiceInformation', 'ServiceStatus'],\n })\n }\n\n if (typeof service.ServiceInformation.StatusStartingTime !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'StatusStartingTime must not be present',\n path: [...entityServicePath, 'ServiceInformation', 'StatusStartingTime'],\n })\n }\n\n if (\n !service.ServiceInformation.ServiceTypeIdentifier ||\n !allowedServiceTypeIdentifiers.includes(service.ServiceInformation.ServiceTypeIdentifier)\n ) {\n ctx.addIssue({\n code: 'invalid_value',\n message: `ServiceTypeIdentifier must be one of the following: ${allowedServiceTypeIdentifiers.join(', ')}`,\n path: [...entityServicePath, 'ServiceInformation', 'ServiceTypeIdentifier'],\n values: allowedServiceTypeIdentifiers,\n })\n }\n })\n })\n }\n\n// ETSI TS 119 602 D\nexport const EUPIDProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: 'http://uri.etsi.org/19602/LoTEType/EUPIDProvidersList',\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/PIDProvidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/PIDProviders/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/PID/Issuance',\n 'http://uri.etsi.org/19602/SvcType/PID/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/PIDProvider/',\n })\n)\n\n// ETSI TS 119 602 E\nexport const EUWalletProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: 'http://uri.etsi.org/19602/LoTEType/EUWalletProvidersList',\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/WalletProvidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/WalletProvidersList/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/WalletSolution/Issuance',\n 'http://uri.etsi.org/19602/SvcType/WalletSolution/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/WalletProvider/',\n })\n)\n\n// ETSI TS 119 602 F\nexport const EUWRPACProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: 'http://uri.etsi.org/19602/LoTEType/EUWRPACProvidersList',\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/WRPACProvidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/WRPACProvidersList/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/WRPAC/Issuance',\n 'http://uri.etsi.org/19602/SvcType/WRPAC/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/WRPACProvider/',\n })\n)\n\n// ETSI TS 119 602 G\nexport const EUWRPRCProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: 'http://uri.etsi.org/19602/LoTEType/EUWRPRCProvidersList',\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/WRPRCrovidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/WRPRCProvidersList/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/WRPRC/Issuance',\n 'http://uri.etsi.org/19602/SvcType/WRPRC/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/WRPRCProvider/',\n })\n)\n\nexport const EUEAAProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: 'http://uri.etsi.org/19602/LoTEType/EUEAAProvidersList',\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/EAAProvidersList/StatusDetn/EU\"',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/EAAProvidersList/schemerules/EU',\n requireNoPointersToOtherLoTE: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/EAA/Issuance',\n 'http://uri.etsi.org/19602/SvcType/EAA/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/EAAProvider/',\n })\n)\n\n// ETSI TS 119 602 H\nexport const EUPubEAAProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: 'http://uri.etsi.org/19602/LoTEType/EUPubEAAProvidersList',\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/PubEAAProvidersList/StatusDetn/EU\"',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/PubEAAProvidersList/schemerules/EU',\n requireNoPointersToOtherLoTE: true,\n historicalInformationPeriod: 65535,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/PubEAA/Issuance',\n 'http://uri.etsi.org/19602/SvcType/PubEAA/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/PubEAAProvider/',\n })\n)\n\n// mDL Providers List\nexport const mDLProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: 'http://trust.ec.europa.eu/lists/mDL/mDLProvidersListType',\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://trust.ec.europa.eu/lists/mDL/mDLProvidersListStatusDetn',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://trust.ec.europa.eu/lists/mDL/schemerules',\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://trust.ec.europa.eu/lists/mDL/SvcType/Issuance',\n 'http://trust.ec.europa.eu/lists/mDL/SvcType/Revocation',\n ],\n })\n)\n","import { parseCertificate } from '@owf/crypto'\nimport { base64urlEncode } from '@owf/identity-common'\nimport type { ListAndSchemeInformation, LoTE, LoTEDocument, SignedLoTE, SignOptions, TrustedEntity } from './types'\n\n/**\n * Sign a LoTE document\n *\n * @param options - Signing options including LoTE document, key ID, and signer function\n * @returns The signed LoTE document as a JWS\n *\n * @example Using a local key via @owf/crypto:\n * ```typescript\n * import { ES256 } from '@owf/crypto';\n * import { signLoTE } from '@owf/eudi-lote';\n *\n * const { privateKey } = await ES256.generateKeyPair();\n * const signer = await ES256.getSigner(privateKey);\n * const signed = await signLoTE({\n * lote: myLoTE,\n * keyId: 'lote-signer-2025',\n * signer,\n * });\n * ```\n *\n * @example Using an external KMS:\n * ```typescript\n * const signed = await signLoTE({\n * lote: myLoTE,\n * keyId: 'lote-signer-2025',\n * signer: async (data) => myKms.sign('ES256', data),\n * });\n * ```\n */\nexport async function signLoTE(options: SignOptions): Promise<SignedLoTE> {\n const { lote, keyId, algorithm = 'ES256', certificates, signer } = options\n\n const header: Record<string, unknown> = {\n alg: algorithm,\n typ: 'trustlist+jwt',\n kid: keyId,\n }\n\n if (certificates && certificates.length > 0) {\n header.x5c = certificates.map(parseCertificate)\n }\n\n const encodedHeader = base64urlEncode(JSON.stringify(header))\n const encodedPayload = base64urlEncode(JSON.stringify(lote))\n const signingInput = `${encodedHeader}.${encodedPayload}`\n\n const signature = await signer(signingInput)\n const jws = `${signingInput}.${signature}`\n\n return {\n jws,\n header: {\n alg: algorithm,\n typ: 'trustlist+jwt',\n kid: keyId,\n x5c: header.x5c as string[] | undefined,\n },\n payload: lote,\n }\n}\n\n/**\n * Create a new LoTE document with required structure\n * Per ETSI TS 119 602, only SchemeOperatorName, ListIssueDateTime and NextUpdate are required\n * Default NextUpdate is 6 months per ETSI TS 119 602 maximum validity\n */\nexport function createLoTE(\n schemeInfo: Partial<ListAndSchemeInformation> & Pick<ListAndSchemeInformation, 'SchemeOperatorName'>,\n entities: TrustedEntity[] = []\n): LoTEDocument {\n const now = new Date()\n const sixMonthsLater = new Date(now)\n sixMonthsLater.setMonth(sixMonthsLater.getMonth() + 6)\n\n const lote: LoTE = {\n ListAndSchemeInformation: {\n LoTEVersionIdentifier: schemeInfo.LoTEVersionIdentifier ?? 1,\n LoTESequenceNumber: schemeInfo.LoTESequenceNumber ?? 1,\n LoTEType: schemeInfo.LoTEType,\n SchemeOperatorName: schemeInfo.SchemeOperatorName,\n SchemeOperatorAddress: schemeInfo.SchemeOperatorAddress,\n SchemeName: schemeInfo.SchemeName,\n SchemeInformationURI: schemeInfo.SchemeInformationURI,\n StatusDeterminationApproach: schemeInfo.StatusDeterminationApproach,\n SchemeTypeCommunityRules: schemeInfo.SchemeTypeCommunityRules,\n SchemeTerritory: schemeInfo.SchemeTerritory,\n PolicyOrLegalNotice: schemeInfo.PolicyOrLegalNotice,\n HistoricalInformationPeriod: schemeInfo.HistoricalInformationPeriod,\n PointersToOtherLoTE: schemeInfo.PointersToOtherLoTE,\n ListIssueDateTime: schemeInfo.ListIssueDateTime ?? now.toISOString(),\n NextUpdate: schemeInfo.NextUpdate ?? sixMonthsLater.toISOString(),\n DistributionPoints: schemeInfo.DistributionPoints,\n SchemeExtensions: schemeInfo.SchemeExtensions,\n },\n TrustedEntitiesList: entities,\n }\n\n return { LoTE: lote }\n}\n\n/**\n * Options for updating a LoTE version\n */\nexport interface UpdateLoTEVersionOptions {\n /**\n * The issue date/time for the new version.\n * Useful when generating a LoTE in advance before publication.\n * Defaults to the current time.\n */\n listIssueDateTime?: Date | string\n /**\n * The next update date/time.\n * Per ETSI TS 119 602, maximum validity is 6 months.\n * Defaults to 6 months from listIssueDateTime.\n */\n nextUpdate?: Date | string\n}\n\n/**\n * Increment the sequence number and update timestamps for a new version\n *\n * @param lote - The LoTE document to update\n * @param options - Optional settings for listIssueDateTime and nextUpdate\n * @returns A new LoTE document with incremented sequence number and updated timestamps\n *\n * @example Update with defaults (now + 6 months):\n * ```typescript\n * const updated = updateLoTEVersion(lote);\n * ```\n *\n * @example Schedule for future publication:\n * ```typescript\n * const updated = updateLoTEVersion(lote, {\n * listIssueDateTime: new Date('2025-01-01'),\n * nextUpdate: new Date('2025-06-01'),\n * });\n * ```\n */\nexport function updateLoTEVersion(lote: LoTEDocument, options: UpdateLoTEVersionOptions = {}): LoTEDocument {\n const issueDate = options.listIssueDateTime\n ? typeof options.listIssueDateTime === 'string'\n ? new Date(options.listIssueDateTime)\n : options.listIssueDateTime\n : new Date()\n\n const defaultNextUpdate = new Date(issueDate)\n defaultNextUpdate.setMonth(defaultNextUpdate.getMonth() + 6)\n\n const nextUpdateDate = options.nextUpdate\n ? typeof options.nextUpdate === 'string'\n ? options.nextUpdate\n : options.nextUpdate.toISOString()\n : defaultNextUpdate.toISOString()\n\n return {\n LoTE: {\n ...lote.LoTE,\n ListAndSchemeInformation: {\n ...lote.LoTE.ListAndSchemeInformation,\n LoTESequenceNumber: lote.LoTE.ListAndSchemeInformation.LoTESequenceNumber + 1,\n ListIssueDateTime: issueDate.toISOString(),\n NextUpdate: nextUpdateDate,\n },\n },\n }\n}\n\n/**\n * Add a trusted entity to a LoTE document\n */\nexport function addTrustedEntity(lote: LoTEDocument, entity: TrustedEntity): LoTEDocument {\n return {\n LoTE: {\n ...lote.LoTE,\n TrustedEntitiesList: [...lote.LoTE.TrustedEntitiesList, entity],\n },\n }\n}\n\n/**\n * Remove a trusted entity from a LoTE document by name\n */\nexport function removeTrustedEntity(lote: LoTEDocument, entityName: string): LoTEDocument {\n return {\n LoTE: {\n ...lote.LoTE,\n TrustedEntitiesList: lote.LoTE.TrustedEntitiesList.filter(\n (e) => !e.TrustedEntityInformation.TEName.some((n) => n.value === entityName)\n ),\n },\n }\n}\n","/**\n * LoTE Validator\n *\n * Runtime validation for ETSI TS 119 602 LoTE documents using Zod schemas.\n */\n\nimport z from 'zod'\nimport { LoTEException } from './lote-exception'\nimport {\n EUEAAProvidersListSchema,\n EUPIDProvidersListSchema,\n EUPubEAAProvidersListSchema,\n EUWalletProvidersListSchema,\n EUWRPACProvidersListSchema,\n EUWRPRCProvidersListSchema,\n mDLProvidersListSchema,\n} from './profiles'\nimport { LoTEDocumentSchema } from './schemas'\nimport type { LoTEDocument } from './types'\n\n/**\n * Validation error detail\n */\nexport interface ValidationError {\n /** Path to the invalid field */\n path: string\n /** Error message */\n message: string\n}\n\n/**\n * Validation result\n */\nexport interface ValidationResult {\n /** Whether the LoTE document is valid */\n valid: boolean\n /** List of validation errors (if invalid) */\n errors: ValidationError[]\n}\n\n/**\n * Validate a LoTE document against ETSI TS 119 602 schema\n *\n * @param loteDocument - The LoTE document to validate\n * @returns Validation result with errors if invalid\n *\n * @example\n * ```typescript\n * const result = validateLoTE(myLoTE);\n * if (!result.valid) {\n * console.error('Validation errors:', result.errors);\n * }\n * ```\n */\nexport function validateLoTE(loteDocument: unknown): ValidationResult {\n const result = LoTEDocumentSchema.safeParse(loteDocument)\n\n if (result.success) {\n return { valid: true, errors: [] }\n }\n\n const errors: ValidationError[] = result.error.issues.map((issue) => ({\n path: issue.path.join('.'),\n message: issue.message,\n }))\n\n return { valid: false, errors }\n}\n\n/**\n * Assert that a LoTE document is valid, throwing if not\n *\n * @param loteDocument - The LoTE document to validate\n * @throws Error if validation fails\n */\nexport function assertValidLoTE(loteDocument: unknown): asserts loteDocument is LoTEDocument {\n const result = validateLoTE(loteDocument)\n if (!result.valid) {\n const errorMessages = result.errors.map((e) => `${e.path}: ${e.message}`).join('\\n')\n throw new LoTEException(`Invalid LoTE document:\\n${errorMessages}`)\n }\n}\n\n/**\n * Supported LoTE profiles for validation\n */\nexport enum LoTEProfile {\n EUPIDProvidersList = 'EUPIDProvidersList',\n EUWalletProvidersList = 'EUWalletProvidersList',\n EUWRPACProvidersList = 'EUWRPACProvidersList',\n EUWRPRCProvidersList = 'EUWRPRCProvidersList',\n EUEAAProvidersList = 'EUEAAProvidersList',\n EUPubEAAProvidersList = 'EUPubEAAProvidersList',\n mDLProvidersList = 'mDLProvidersList',\n}\n\nconst profileToSchemaMap: Record<LoTEProfile, z.ZodType> = {\n [LoTEProfile.EUPIDProvidersList]: EUPIDProvidersListSchema,\n [LoTEProfile.EUWalletProvidersList]: EUWalletProvidersListSchema,\n [LoTEProfile.EUWRPACProvidersList]: EUWRPACProvidersListSchema,\n [LoTEProfile.EUWRPRCProvidersList]: EUWRPRCProvidersListSchema,\n [LoTEProfile.EUEAAProvidersList]: EUEAAProvidersListSchema,\n [LoTEProfile.EUPubEAAProvidersList]: EUPubEAAProvidersListSchema,\n [LoTEProfile.mDLProvidersList]: mDLProvidersListSchema,\n}\n\n/**\n * Validate a LoTE document against one or more given profiles. Validation\n * succeeds if the document matches one of the specified profiles\n *\n * @param loteDocument - The LoTE document to validate\n * @param profile - The profile(s) to validate against\n * @returns Validation result with errors if invalid\n */\nexport function validateLoTEProfile(loteDocument: unknown, profile: LoTEProfile | LoTEProfile[]): ValidationResult {\n const profiles = Array.isArray(profile) ? profile : [profile]\n const schema = z.union(profiles.map((p) => profileToSchemaMap[p]))\n const result = schema.safeParse(loteDocument)\n\n if (result.success) {\n return { valid: true, errors: [] }\n }\n\n return {\n valid: false,\n errors: [\n {\n path: 'LoTEType',\n message: `Document does not match any of the specified profiles: ${profiles.join(', ')}`,\n },\n ...result.error.issues.flatMap((issue) => {\n if (issue.code === 'invalid_union') {\n // `issue.errors` holds one array of issues per union branch, in the same order as `profiles`\n return issue.errors.flatMap((branchIssues, index) =>\n branchIssues.map((branchIssue) => ({\n path: branchIssue.path.join('.'),\n message: `Profile ${profiles[index]}: ${branchIssue.message}`,\n }))\n )\n }\n\n return [{ path: issue.path.join('.'), message: issue.message }]\n }),\n ],\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["IdentityException","z","parseCertificate"],"sources":["../src/lote-exception.ts","../src/schemas.ts","../src/builders.ts","../src/profiles.ts","../src/signer.ts","../src/validator.ts"],"sourcesContent":["import { IdentityException } from '@owf/identity-common'\n\n/**\n * LoTEException is a custom error class for LoTE-related exceptions.\n */\nexport class LoTEException extends IdentityException {\n constructor(message: string, details?: unknown) {\n super(message, details)\n Object.setPrototypeOf(this, LoTEException.prototype)\n this.name = 'LoTEException'\n }\n}\n","/**\n * LoTE Zod Schemas\n *\n * Zod schemas for ETSI TS 119 602 (LoTE - List of Trusted Entities) format.\n * Types are derived from these schemas via z.infer<>.\n *\n * @see https://www.etsi.org/deliver/etsi_ts/119600_119699/119602/01.01.01_60/ts_119602v010101p.pdf\n */\n\nimport { z } from 'zod'\n\n// ============================================================================\n// Localized Value Schemas\n// ============================================================================\n\nexport const LocalizedStringSchema = z.object({\n lang: z.string().min(1),\n value: z.string().min(1),\n})\n\nexport const LocalizedURISchema = z.object({\n lang: z.string().min(1),\n uriValue: z.url(),\n})\n\n// ============================================================================\n// Address Schemas\n// ============================================================================\n\nexport const PostalAddressSchema = z.object({\n lang: z.string().min(1),\n StreetAddress: z.string(),\n Locality: z.string(),\n StateOrProvince: z.string().optional(),\n PostalCode: z.string(),\n Country: z.string().length(2),\n})\n\nexport const SchemeOperatorAddressSchema = z.object({\n SchemeOperatorPostalAddress: z.array(PostalAddressSchema),\n SchemeOperatorElectronicAddress: z.array(LocalizedURISchema),\n})\n\nexport const TrustedEntityAddressSchema = z.object({\n TEPostalAddress: z.array(PostalAddressSchema),\n TEElectronicAddress: z.array(LocalizedURISchema),\n})\n\n// ============================================================================\n// Digital Identity Schemas\n// ============================================================================\n\nexport const PkiObjectSchema = z.object({\n encoding: z.string().optional(),\n specRef: z.string().optional(),\n val: z.string().min(1),\n})\n\nexport const X509CertificateRefSchema = PkiObjectSchema.extend({\n encoding: z.literal('urn:ietf:params:tls-cert-type:x509').optional(),\n specRef: z.literal('RFC5280').optional(),\n})\n\nexport const JWKPublicKeySchema = z.looseObject({\n kty: z.enum(['RSA', 'EC', 'OKP']),\n kid: z.string().optional(),\n use: z.enum(['sig', 'enc']).optional(),\n alg: z.string().optional(),\n})\n\nexport const ServiceDigitalIdentitySchema = z\n .object({\n X509Certificates: z.array(X509CertificateRefSchema).optional(),\n X509SubjectNames: z.array(z.string()).optional(),\n PublicKeyValues: z.array(JWKPublicKeySchema).optional(),\n X509SKIs: z.array(z.string()).optional(),\n OtherIds: z.array(z.string()).optional(),\n })\n .refine(\n (id) =>\n (id.X509Certificates && id.X509Certificates.length > 0) ||\n (id.X509SubjectNames && id.X509SubjectNames.length > 0) ||\n (id.PublicKeyValues && id.PublicKeyValues.length > 0) ||\n (id.X509SKIs && id.X509SKIs.length > 0) ||\n (id.OtherIds && id.OtherIds.length > 0),\n { message: 'At least one digital identity type must be provided' }\n )\n\n// ============================================================================\n// Service Schemas\n// ============================================================================\n\nexport const ServiceSupplyPointSchema = z.object({\n ServiceType: z.string(),\n uriValue: z.url(),\n})\n\nexport const ServiceInformationSchema = z.object({\n ServiceName: z.array(LocalizedStringSchema).min(1),\n ServiceDigitalIdentity: ServiceDigitalIdentitySchema,\n ServiceTypeIdentifier: z.url().optional(),\n ServiceStatus: z.url().optional(),\n StatusStartingTime: z.iso.datetime().optional(),\n SchemeServiceDefinitionURI: z.array(LocalizedURISchema).optional(),\n ServiceSupplyPoints: z.array(ServiceSupplyPointSchema).optional(),\n ServiceDefinitionURI: z.array(LocalizedURISchema).optional(),\n ServiceInformationExtensions: z.array(z.unknown()).optional(),\n})\n\nexport const ServiceHistoryInstanceSchema = z.object({\n ServiceName: z.array(LocalizedStringSchema).min(1),\n ServiceDigitalIdentity: ServiceDigitalIdentitySchema,\n ServiceStatus: z.url(),\n StatusStartingTime: z.iso.datetime(),\n ServiceTypeIdentifier: z.url().optional(),\n ServiceInformationExtensions: z.array(z.unknown()).optional(),\n})\n\nexport const TrustedEntityServiceSchema = z.object({\n ServiceInformation: ServiceInformationSchema,\n ServiceHistory: z.array(ServiceHistoryInstanceSchema).optional(),\n})\n\n// ============================================================================\n// Trusted Entity Schemas\n// ============================================================================\n\nexport const TrustedEntityInformationSchema = z.object({\n TEName: z.array(LocalizedStringSchema).min(1),\n TETradeName: z.array(LocalizedStringSchema).optional(),\n TEAddress: TrustedEntityAddressSchema,\n TEInformationURI: z.array(LocalizedURISchema).optional(),\n TEInformationExtensions: z.array(z.unknown()).optional(),\n})\n\nexport const TrustedEntitySchema = z.object({\n TrustedEntityInformation: TrustedEntityInformationSchema,\n TrustedEntityServices: z.array(TrustedEntityServiceSchema).min(1),\n})\n\n// ============================================================================\n// List and Scheme Information Schemas\n// ============================================================================\n\nexport const PolicyOrLegalNoticeSchema = z.object({\n LoTEPolicy: LocalizedURISchema.optional(),\n LoTELegalNotice: LocalizedStringSchema.optional(),\n})\n\nexport const LoTEQualifierSchema = z.object({\n LoTEType: z.url(),\n SchemeOperatorName: z.array(LocalizedStringSchema).min(1),\n SchemeTypeCommunityRules: z.array(LocalizedURISchema).optional(),\n SchemeTerritory: z.string().length(2).optional(),\n MimeType: z.string().min(1),\n})\n\nexport const OtherLoTEPointerSchema = z.object({\n LoTELocation: z.url(),\n ServiceDigitalIdentities: z.array(ServiceDigitalIdentitySchema).min(1),\n LoTEQualifiers: z.array(LoTEQualifierSchema).min(1),\n})\n\nexport const ListAndSchemeInformationSchema = z.object({\n LoTEVersionIdentifier: z.number().int(),\n LoTESequenceNumber: z.number().int(),\n LoTEType: z.url().optional(),\n SchemeOperatorName: z.array(LocalizedStringSchema).min(1),\n SchemeOperatorAddress: SchemeOperatorAddressSchema.optional(),\n SchemeName: z.array(LocalizedStringSchema).optional(),\n SchemeInformationURI: z.array(LocalizedURISchema).optional(),\n StatusDeterminationApproach: z.url().optional(),\n SchemeTypeCommunityRules: z.array(LocalizedURISchema).optional(),\n SchemeTerritory: z.string().length(2).optional(),\n PolicyOrLegalNotice: z.array(PolicyOrLegalNoticeSchema).optional(),\n HistoricalInformationPeriod: z.number().optional(),\n PointersToOtherLoTE: z.array(OtherLoTEPointerSchema).optional(),\n ListIssueDateTime: z.iso.datetime(),\n NextUpdate: z.iso.datetime(),\n DistributionPoints: z.array(z.url()).optional(),\n SchemeExtensions: z.array(z.unknown()).optional(),\n})\n\n// ============================================================================\n// LoTE Root Schemas\n// ============================================================================\n\nexport const LoTESchema = z.object({\n ListAndSchemeInformation: ListAndSchemeInformationSchema,\n TrustedEntitiesList: z.array(TrustedEntitySchema),\n})\n\nexport const LoTEDocumentSchema = z.object({\n LoTE: LoTESchema,\n})\n","import { LoTEException } from './lote-exception'\nimport { TrustedEntitySchema, TrustedEntityServiceSchema } from './schemas'\nimport type {\n JWKPublicKey,\n PostalAddress,\n ServiceHistoryInstance,\n ServiceInformation,\n TrustedEntity,\n TrustedEntityInformation,\n TrustedEntityService,\n} from './types'\n\n/**\n * Builder for creating TrustedEntity objects with a fluent API\n */\nexport class TrustedEntityBuilder {\n private info: Partial<TrustedEntityInformation> = {}\n private services: TrustedEntityService[] = []\n\n /**\n * Set the entity name\n */\n name(value: string, lang = 'en'): this {\n this.info.TEName = this.info.TEName ?? []\n this.info.TEName.push({ lang, value })\n return this\n }\n\n /**\n * Set the trade name\n */\n tradeName(value: string, lang = 'en'): this {\n this.info.TETradeName = this.info.TETradeName ?? []\n this.info.TETradeName.push({ lang, value })\n return this\n }\n\n /**\n * Set the postal address\n */\n postalAddress(address: Omit<PostalAddress, 'lang'>, lang = 'en'): this {\n this.info.TEAddress = this.info.TEAddress ?? {\n TEPostalAddress: [],\n TEElectronicAddress: [],\n }\n this.info.TEAddress.TEPostalAddress.push({ ...address, lang })\n return this\n }\n\n /**\n * Add an electronic address (email)\n */\n email(email: string, lang = 'en'): this {\n this.info.TEAddress = this.info.TEAddress ?? {\n TEPostalAddress: [],\n TEElectronicAddress: [],\n }\n this.info.TEAddress.TEElectronicAddress.push({\n lang,\n uriValue: email.startsWith('mailto:') ? email : `mailto:${email}`,\n })\n return this\n }\n\n /**\n * Add an information URI\n */\n infoUri(uri: string, lang = 'en'): this {\n this.info.TEInformationURI = this.info.TEInformationURI ?? []\n this.info.TEInformationURI.push({ lang, uriValue: uri })\n return this\n }\n\n /**\n * Add a website URL as an electronic address\n */\n website(url: string, lang = 'en'): this {\n this.info.TEAddress = this.info.TEAddress ?? {\n TEPostalAddress: [],\n TEElectronicAddress: [],\n }\n this.info.TEAddress.TEElectronicAddress.push({\n lang,\n uriValue: url.startsWith('http') ? url : `https://${url}`,\n })\n return this\n }\n\n /**\n * Add custom extensions\n */\n addExtension(extension: unknown): this {\n this.info.TEInformationExtensions = this.info.TEInformationExtensions ?? []\n this.info.TEInformationExtensions.push(extension)\n return this\n }\n\n /**\n * Add a service to the entity\n */\n addService(service: TrustedEntityService): this {\n this.services.push(service)\n return this\n }\n\n /**\n * Build the TrustedEntity object\n */\n build(): TrustedEntity {\n const result = TrustedEntitySchema.safeParse({\n TrustedEntityInformation: this.info,\n TrustedEntityServices: this.services,\n })\n\n if (!result.success) {\n const messages = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('\\n')\n throw new LoTEException(`Invalid TrustedEntity:\\n${messages}`)\n }\n\n return result.data\n }\n}\n\n/**\n * Builder for creating TrustedEntityService objects\n */\nexport class ServiceBuilder {\n private info: Partial<ServiceInformation> = {}\n private history: ServiceHistoryInstance[] = []\n\n /**\n * Set the service name\n */\n name(value: string, lang = 'en'): this {\n this.info.ServiceName = this.info.ServiceName ?? []\n this.info.ServiceName.push({ lang, value })\n return this\n }\n\n /**\n * Set the service type identifier\n */\n type(typeUri: string): this {\n this.info.ServiceTypeIdentifier = typeUri\n return this\n }\n\n /**\n * Set the service status\n */\n status(statusUri: string, startingTime?: Date): this {\n this.info.ServiceStatus = statusUri\n this.info.StatusStartingTime = startingTime?.toISOString() ?? new Date().toISOString()\n return this\n }\n\n /**\n * Add an X.509 certificate to the digital identity\n */\n addCertificate(certBase64: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.X509Certificates = this.info.ServiceDigitalIdentity.X509Certificates ?? []\n this.info.ServiceDigitalIdentity.X509Certificates.push({\n encoding: 'urn:ietf:params:tls-cert-type:x509',\n specRef: 'RFC5280',\n val: certBase64,\n })\n return this\n }\n\n /**\n * Add an X.509 subject name (DN format) to the digital identity\n */\n addX509SubjectName(subjectName: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.X509SubjectNames = this.info.ServiceDigitalIdentity.X509SubjectNames ?? []\n this.info.ServiceDigitalIdentity.X509SubjectNames.push(subjectName)\n return this\n }\n\n /**\n * Add an X.509 Subject Key Identifier (base64-encoded) to the digital identity\n */\n addX509SKI(ski: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.X509SKIs = this.info.ServiceDigitalIdentity.X509SKIs ?? []\n this.info.ServiceDigitalIdentity.X509SKIs.push(ski)\n return this\n }\n\n /**\n * Add another identifier to the digital identity\n */\n addOtherId(id: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.OtherIds = this.info.ServiceDigitalIdentity.OtherIds ?? []\n this.info.ServiceDigitalIdentity.OtherIds.push(id)\n return this\n }\n\n /**\n * Add a public key (JWK) to the digital identity\n */\n addPublicKey(jwk: JWKPublicKey): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.PublicKeyValues = this.info.ServiceDigitalIdentity.PublicKeyValues ?? []\n this.info.ServiceDigitalIdentity.PublicKeyValues.push(jwk)\n return this\n }\n\n /**\n * Add a service endpoint\n */\n addEndpoint(type: string, uri: string): this {\n this.info.ServiceSupplyPoints = this.info.ServiceSupplyPoints ?? []\n this.info.ServiceSupplyPoints.push({ ServiceType: type, uriValue: uri })\n return this\n }\n\n /**\n * Add a service definition URI\n */\n addDefinitionUri(uri: string, lang = 'en'): this {\n this.info.ServiceDefinitionURI = this.info.ServiceDefinitionURI ?? []\n this.info.ServiceDefinitionURI.push({ lang, uriValue: uri })\n return this\n }\n\n /**\n * Add custom service information extensions\n */\n addExtension(extension: unknown): this {\n this.info.ServiceInformationExtensions = this.info.ServiceInformationExtensions ?? []\n this.info.ServiceInformationExtensions.push(extension)\n return this\n }\n\n /**\n * Add a historical service instance\n */\n addHistoryEntry(historyInstance: ServiceHistoryInstance): this {\n this.history.push(historyInstance)\n return this\n }\n\n /**\n * Build the TrustedEntityService object\n */\n build(): TrustedEntityService {\n const data: Record<string, unknown> = {\n ServiceInformation: this.info,\n }\n\n if (this.history.length > 0) {\n data.ServiceHistory = this.history\n }\n\n const result = TrustedEntityServiceSchema.safeParse(data)\n\n if (!result.success) {\n const messages = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('\\n')\n throw new LoTEException(`Invalid TrustedEntityService:\\n${messages}`)\n }\n\n return result.data\n }\n}\n\n/**\n * Create a new TrustedEntityBuilder\n */\nexport function trustedEntity(): TrustedEntityBuilder {\n return new TrustedEntityBuilder()\n}\n\n/**\n * Create a new ServiceBuilder\n */\nexport function service(): ServiceBuilder {\n return new ServiceBuilder()\n}\n","/**\n * LoTE Profiles\n *\n * @see https://www.etsi.org/deliver/etsi_ts/119600_119699/119602/01.01.01_60/ts_119602v010101p.pdf\n * @see https://acceptance.eidas.ec.europa.eu/efda/wallet/lists-of-trusted-entities/mdl-providers\n */\n\nimport type z from 'zod'\nimport { LoTEDocumentSchema } from './schemas'\nimport type { LoTEDocument } from './types'\n\nconst SIX_MONTHS_IN_MS = 6 * 31 * 24 * 60 * 60 * 1000\n\nexport const LOTE_TYPES = {\n EUPIDProvidersList: 'http://uri.etsi.org/19602/LoTEType/EUPIDProvidersList',\n EUWalletProvidersList: 'http://uri.etsi.org/19602/LoTEType/EUWalletProvidersList',\n EUWRPACProvidersList: 'http://uri.etsi.org/19602/LoTEType/EUWRPACProvidersList',\n EUWRPRCProvidersList: 'http://uri.etsi.org/19602/LoTEType/EUWRPRCProvidersList',\n EUEAAProvidersList: 'http://uri.etsi.org/19602/LoTEType/EUEAAProvidersList',\n EUPubEAAProvidersList: 'http://uri.etsi.org/19602/LoTEType/EUPubEAAProvidersList',\n mDLProvidersList: 'http://trust.ec.europa.eu/lists/mDL/mDLProvidersListType',\n} as const\n\ntype ListAndSchemeInformationRefinementOptions = {\n loTEType: string\n loTEVersionIdentifier: number\n statusDeterminationApproach: string\n schemeTerritory: string\n schemeTypeCommunityRulesUri: string\n historicalInformationPeriod?: number\n requireNoHistoricalInformationPeriod?: boolean\n requireNoPointersToOtherLoTE?: boolean\n}\n\nconst listAndSchemeInformationRefinement =\n ({\n loTEType,\n loTEVersionIdentifier,\n statusDeterminationApproach,\n schemeTerritory,\n schemeTypeCommunityRulesUri,\n historicalInformationPeriod,\n requireNoHistoricalInformationPeriod,\n requireNoPointersToOtherLoTE,\n }: ListAndSchemeInformationRefinementOptions) =>\n ({ LoTE }: LoTEDocument, ctx: z.RefinementCtx<LoTEDocument>) => {\n const info = LoTE.ListAndSchemeInformation\n const path = ['LoTE', 'ListAndSchemeInformation']\n\n if (info.LoTEType !== loTEType) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [loTEType],\n message: `LoTEType must be ${loTEType}`,\n path: [...path, 'LoTEType'],\n })\n }\n\n if (info.LoTEVersionIdentifier !== loTEVersionIdentifier) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [loTEVersionIdentifier],\n message: `LoTEVersionIdentifier must be ${loTEVersionIdentifier}`,\n path: [...path, 'LoTEVersionIdentifier'],\n })\n }\n\n if (info.StatusDeterminationApproach !== statusDeterminationApproach) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [statusDeterminationApproach],\n message: `StatusDeterminationApproach must be ${statusDeterminationApproach}`,\n path: [...path, 'StatusDeterminationApproach'],\n })\n }\n\n if (info.SchemeTerritory !== schemeTerritory) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [schemeTerritory],\n message: `SchemeTerritory must be ${schemeTerritory}`,\n path: [...path, 'SchemeTerritory'],\n })\n }\n\n if (\n !info.SchemeTypeCommunityRules ||\n info.SchemeTypeCommunityRules.length !== 1 ||\n info.SchemeTypeCommunityRules[0].uriValue !== schemeTypeCommunityRulesUri\n ) {\n ctx.addIssue({\n code: 'custom',\n message: `SchemeTypeCommunityRules must contain a single element with uriValue of ${schemeTypeCommunityRulesUri}`,\n path: [...path, 'SchemeTypeCommunityRules'],\n })\n }\n\n if (requireNoHistoricalInformationPeriod && typeof info.HistoricalInformationPeriod !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'HistoricalInformationPeriod must not be present',\n path: [...path, 'HistoricalInformationPeriod'],\n })\n }\n\n if (historicalInformationPeriod !== undefined && info.HistoricalInformationPeriod !== historicalInformationPeriod) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [historicalInformationPeriod],\n message: `HistoricalInformationPeriod must be ${historicalInformationPeriod}`,\n path: [...path, 'HistoricalInformationPeriod'],\n })\n }\n\n if (requireNoPointersToOtherLoTE && typeof info.PointersToOtherLoTE !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'PointersToOtherLoTE must not be present',\n path: [...path, 'PointersToOtherLoTE'],\n })\n }\n\n const listIssueDateTime = new Date(info.ListIssueDateTime).getTime()\n const nextUpdate = new Date(info.NextUpdate).getTime()\n\n if (nextUpdate - listIssueDateTime > SIX_MONTHS_IN_MS) {\n ctx.addIssue({\n code: 'custom',\n message: 'NextUpdate must be within 6 months of ListIssueDateTime',\n path: [...path, 'NextUpdate'],\n })\n }\n }\n\ntype TrustedEntitiesListRefinementOptions = {\n allowedServiceTypeIdentifiers: string[]\n informationUriPrefix?: string\n}\n\nconst trustedEntitiesListRefinement =\n ({ allowedServiceTypeIdentifiers, informationUriPrefix }: TrustedEntitiesListRefinementOptions) =>\n ({ LoTE }: LoTEDocument, ctx: z.RefinementCtx<LoTEDocument>) => {\n LoTE.TrustedEntitiesList.forEach((entity, index) => {\n const trustedEntityPath = ['LoTE', 'TrustedEntitiesList', index.toString()]\n\n if (informationUriPrefix) {\n const uri = entity.TrustedEntityInformation.TEInformationURI?.find(({ uriValue }) =>\n uriValue.startsWith(informationUriPrefix)\n )\n\n if (!uri) {\n ctx.addIssue({\n code: 'custom',\n message: `Each TrustedEntityInformation.TEInformationURI must contain at least one URI starting with ${informationUriPrefix}`,\n path: [...trustedEntityPath, 'TrustedEntityInformation', 'TEInformationURI'],\n })\n } else {\n const rest = uri.uriValue.substring(informationUriPrefix.length)\n if (rest.length !== 2) {\n ctx.addIssue({\n code: 'custom',\n message: `URI starting with ${informationUriPrefix} must be followed by a 2-letter country code`,\n path: [...trustedEntityPath, 'TrustedEntityInformation', 'TEInformationURI'],\n })\n }\n }\n }\n\n entity.TrustedEntityServices.forEach((service, serviceIndex) => {\n const entityServicePath = [...trustedEntityPath, 'TrustedEntityServices', serviceIndex.toString()]\n\n if (typeof service.ServiceInformation.ServiceStatus !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'ServiceStatus must not be present',\n path: [...entityServicePath, 'ServiceInformation', 'ServiceStatus'],\n })\n }\n\n if (typeof service.ServiceInformation.StatusStartingTime !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'StatusStartingTime must not be present',\n path: [...entityServicePath, 'ServiceInformation', 'StatusStartingTime'],\n })\n }\n\n if (\n !service.ServiceInformation.ServiceTypeIdentifier ||\n !allowedServiceTypeIdentifiers.includes(service.ServiceInformation.ServiceTypeIdentifier)\n ) {\n ctx.addIssue({\n code: 'invalid_value',\n message: `ServiceTypeIdentifier must be one of the following: ${allowedServiceTypeIdentifiers.join(', ')}`,\n path: [...entityServicePath, 'ServiceInformation', 'ServiceTypeIdentifier'],\n values: allowedServiceTypeIdentifiers,\n })\n }\n })\n })\n }\n\n// ETSI TS 119 602 D\nexport const EUPIDProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: LOTE_TYPES.EUPIDProvidersList,\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/PIDProvidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/PIDProviders/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/PID/Issuance',\n 'http://uri.etsi.org/19602/SvcType/PID/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/PIDProvider/',\n })\n)\n\n// ETSI TS 119 602 E\nexport const EUWalletProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: LOTE_TYPES.EUWalletProvidersList,\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/WalletProvidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/WalletProvidersList/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/WalletSolution/Issuance',\n 'http://uri.etsi.org/19602/SvcType/WalletSolution/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/WalletProvider/',\n })\n)\n\n// ETSI TS 119 602 F\nexport const EUWRPACProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: LOTE_TYPES.EUWRPACProvidersList,\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/WRPACProvidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/WRPACProvidersList/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/WRPAC/Issuance',\n 'http://uri.etsi.org/19602/SvcType/WRPAC/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/WRPACProvider/',\n })\n)\n\n// ETSI TS 119 602 G\nexport const EUWRPRCProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: LOTE_TYPES.EUWRPRCProvidersList,\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/WRPRCrovidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/WRPRCProvidersList/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/WRPRC/Issuance',\n 'http://uri.etsi.org/19602/SvcType/WRPRC/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/WRPRCProvider/',\n })\n)\n\nexport const EUEAAProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: LOTE_TYPES.EUEAAProvidersList,\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/EAAProvidersList/StatusDetn/EU\"',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/EAAProvidersList/schemerules/EU',\n requireNoPointersToOtherLoTE: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/EAA/Issuance',\n 'http://uri.etsi.org/19602/SvcType/EAA/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/EAAProvider/',\n })\n)\n\n// ETSI TS 119 602 H\nexport const EUPubEAAProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: LOTE_TYPES.EUPubEAAProvidersList,\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/PubEAAProvidersList/StatusDetn/EU\"',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/PubEAAProvidersList/schemerules/EU',\n requireNoPointersToOtherLoTE: true,\n historicalInformationPeriod: 65535,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/PubEAA/Issuance',\n 'http://uri.etsi.org/19602/SvcType/PubEAA/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/PubEAAProvider/',\n })\n)\n\n// mDL Providers List\nexport const mDLProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: LOTE_TYPES.mDLProvidersList,\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://trust.ec.europa.eu/lists/mDL/mDLProvidersListStatusDetn',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://trust.ec.europa.eu/lists/mDL/schemerules',\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://trust.ec.europa.eu/lists/mDL/SvcType/Issuance',\n 'http://trust.ec.europa.eu/lists/mDL/SvcType/Revocation',\n ],\n })\n)\n","import { parseCertificate } from '@owf/crypto'\nimport { base64urlEncode } from '@owf/identity-common'\nimport type { ListAndSchemeInformation, LoTE, LoTEDocument, SignedLoTE, SignOptions, TrustedEntity } from './types'\n\n/**\n * Sign a LoTE document\n *\n * @param options - Signing options including LoTE document, key ID, and signer function\n * @returns The signed LoTE document as a JWS\n *\n * @example Using a local key via @owf/crypto:\n * ```typescript\n * import { ES256 } from '@owf/crypto';\n * import { signLoTE } from '@owf/eudi-lote';\n *\n * const { privateKey } = await ES256.generateKeyPair();\n * const signer = await ES256.getSigner(privateKey);\n * const signed = await signLoTE({\n * lote: myLoTE,\n * keyId: 'lote-signer-2025',\n * signer,\n * });\n * ```\n *\n * @example Using an external KMS:\n * ```typescript\n * const signed = await signLoTE({\n * lote: myLoTE,\n * keyId: 'lote-signer-2025',\n * signer: async (data) => myKms.sign('ES256', data),\n * });\n * ```\n */\nexport async function signLoTE(options: SignOptions): Promise<SignedLoTE> {\n const { lote, keyId, algorithm = 'ES256', certificates, signer } = options\n\n const header: Record<string, unknown> = {\n alg: algorithm,\n typ: 'trustlist+jwt',\n kid: keyId,\n }\n\n if (certificates && certificates.length > 0) {\n header.x5c = certificates.map(parseCertificate)\n }\n\n const encodedHeader = base64urlEncode(JSON.stringify(header))\n const encodedPayload = base64urlEncode(JSON.stringify(lote))\n const signingInput = `${encodedHeader}.${encodedPayload}`\n\n const signature = await signer(signingInput)\n const jws = `${signingInput}.${signature}`\n\n return {\n jws,\n header: {\n alg: algorithm,\n typ: 'trustlist+jwt',\n kid: keyId,\n x5c: header.x5c as string[] | undefined,\n },\n payload: lote,\n }\n}\n\n/**\n * Create a new LoTE document with required structure\n * Per ETSI TS 119 602, only SchemeOperatorName, ListIssueDateTime and NextUpdate are required\n * Default NextUpdate is 6 months per ETSI TS 119 602 maximum validity\n */\nexport function createLoTE(\n schemeInfo: Partial<ListAndSchemeInformation> & Pick<ListAndSchemeInformation, 'SchemeOperatorName'>,\n entities: TrustedEntity[] = []\n): LoTEDocument {\n const now = new Date()\n const sixMonthsLater = new Date(now)\n sixMonthsLater.setMonth(sixMonthsLater.getMonth() + 6)\n\n const lote: LoTE = {\n ListAndSchemeInformation: {\n LoTEVersionIdentifier: schemeInfo.LoTEVersionIdentifier ?? 1,\n LoTESequenceNumber: schemeInfo.LoTESequenceNumber ?? 1,\n LoTEType: schemeInfo.LoTEType,\n SchemeOperatorName: schemeInfo.SchemeOperatorName,\n SchemeOperatorAddress: schemeInfo.SchemeOperatorAddress,\n SchemeName: schemeInfo.SchemeName,\n SchemeInformationURI: schemeInfo.SchemeInformationURI,\n StatusDeterminationApproach: schemeInfo.StatusDeterminationApproach,\n SchemeTypeCommunityRules: schemeInfo.SchemeTypeCommunityRules,\n SchemeTerritory: schemeInfo.SchemeTerritory,\n PolicyOrLegalNotice: schemeInfo.PolicyOrLegalNotice,\n HistoricalInformationPeriod: schemeInfo.HistoricalInformationPeriod,\n PointersToOtherLoTE: schemeInfo.PointersToOtherLoTE,\n ListIssueDateTime: schemeInfo.ListIssueDateTime ?? now.toISOString(),\n NextUpdate: schemeInfo.NextUpdate ?? sixMonthsLater.toISOString(),\n DistributionPoints: schemeInfo.DistributionPoints,\n SchemeExtensions: schemeInfo.SchemeExtensions,\n },\n TrustedEntitiesList: entities,\n }\n\n return { LoTE: lote }\n}\n\n/**\n * Options for updating a LoTE version\n */\nexport interface UpdateLoTEVersionOptions {\n /**\n * The issue date/time for the new version.\n * Useful when generating a LoTE in advance before publication.\n * Defaults to the current time.\n */\n listIssueDateTime?: Date | string\n /**\n * The next update date/time.\n * Per ETSI TS 119 602, maximum validity is 6 months.\n * Defaults to 6 months from listIssueDateTime.\n */\n nextUpdate?: Date | string\n}\n\n/**\n * Increment the sequence number and update timestamps for a new version\n *\n * @param lote - The LoTE document to update\n * @param options - Optional settings for listIssueDateTime and nextUpdate\n * @returns A new LoTE document with incremented sequence number and updated timestamps\n *\n * @example Update with defaults (now + 6 months):\n * ```typescript\n * const updated = updateLoTEVersion(lote);\n * ```\n *\n * @example Schedule for future publication:\n * ```typescript\n * const updated = updateLoTEVersion(lote, {\n * listIssueDateTime: new Date('2025-01-01'),\n * nextUpdate: new Date('2025-06-01'),\n * });\n * ```\n */\nexport function updateLoTEVersion(lote: LoTEDocument, options: UpdateLoTEVersionOptions = {}): LoTEDocument {\n const issueDate = options.listIssueDateTime\n ? typeof options.listIssueDateTime === 'string'\n ? new Date(options.listIssueDateTime)\n : options.listIssueDateTime\n : new Date()\n\n const defaultNextUpdate = new Date(issueDate)\n defaultNextUpdate.setMonth(defaultNextUpdate.getMonth() + 6)\n\n const nextUpdateDate = options.nextUpdate\n ? typeof options.nextUpdate === 'string'\n ? options.nextUpdate\n : options.nextUpdate.toISOString()\n : defaultNextUpdate.toISOString()\n\n return {\n LoTE: {\n ...lote.LoTE,\n ListAndSchemeInformation: {\n ...lote.LoTE.ListAndSchemeInformation,\n LoTESequenceNumber: lote.LoTE.ListAndSchemeInformation.LoTESequenceNumber + 1,\n ListIssueDateTime: issueDate.toISOString(),\n NextUpdate: nextUpdateDate,\n },\n },\n }\n}\n\n/**\n * Add a trusted entity to a LoTE document\n */\nexport function addTrustedEntity(lote: LoTEDocument, entity: TrustedEntity): LoTEDocument {\n return {\n LoTE: {\n ...lote.LoTE,\n TrustedEntitiesList: [...lote.LoTE.TrustedEntitiesList, entity],\n },\n }\n}\n\n/**\n * Remove a trusted entity from a LoTE document by name\n */\nexport function removeTrustedEntity(lote: LoTEDocument, entityName: string): LoTEDocument {\n return {\n LoTE: {\n ...lote.LoTE,\n TrustedEntitiesList: lote.LoTE.TrustedEntitiesList.filter(\n (e) => !e.TrustedEntityInformation.TEName.some((n) => n.value === entityName)\n ),\n },\n }\n}\n","/**\n * LoTE Validator\n *\n * Runtime validation for ETSI TS 119 602 LoTE documents using Zod schemas.\n */\n\nimport type z from 'zod'\nimport { LoTEException } from './lote-exception'\nimport {\n EUEAAProvidersListSchema,\n EUPIDProvidersListSchema,\n EUPubEAAProvidersListSchema,\n EUWalletProvidersListSchema,\n EUWRPACProvidersListSchema,\n EUWRPRCProvidersListSchema,\n LOTE_TYPES,\n mDLProvidersListSchema,\n} from './profiles'\nimport { LoTEDocumentSchema } from './schemas'\nimport type { LoTEDocument } from './types'\n\n/**\n * Validation error detail\n */\nexport interface ValidationError {\n /** Path to the invalid field */\n path: string\n /** Error message */\n message: string\n}\n\n/**\n * Validation result\n */\nexport interface ValidationResult {\n /** Whether the LoTE document is valid */\n valid: boolean\n /** List of validation errors (if invalid) */\n errors: ValidationError[]\n}\n\n/**\n * Validate a LoTE document against ETSI TS 119 602 schema\n *\n * @param loteDocument - The LoTE document to validate\n * @returns Validation result with errors if invalid\n *\n * @example\n * ```typescript\n * const result = validateLoTE(myLoTE);\n * if (!result.valid) {\n * console.error('Validation errors:', result.errors);\n * }\n * ```\n */\nexport function validateLoTE(loteDocument: unknown): ValidationResult {\n const result = LoTEDocumentSchema.safeParse(loteDocument)\n\n if (result.success) {\n return { valid: true, errors: [] }\n }\n\n const errors: ValidationError[] = result.error.issues.map((issue) => ({\n path: issue.path.join('.'),\n message: issue.message,\n }))\n\n return { valid: false, errors }\n}\n\n/**\n * Assert that a LoTE document is valid, throwing if not\n *\n * @param loteDocument - The LoTE document to validate\n * @throws Error if validation fails\n */\nexport function assertValidLoTE(loteDocument: unknown): asserts loteDocument is LoTEDocument {\n const result = validateLoTE(loteDocument)\n if (!result.valid) {\n const errorMessages = result.errors.map((e) => `${e.path}: ${e.message}`).join('\\n')\n throw new LoTEException(`Invalid LoTE document:\\n${errorMessages}`)\n }\n}\n\n/**\n * Supported LoTE profiles for validation\n */\nexport enum LoTEProfile {\n EUPIDProvidersList = 'EUPIDProvidersList',\n EUWalletProvidersList = 'EUWalletProvidersList',\n EUWRPACProvidersList = 'EUWRPACProvidersList',\n EUWRPRCProvidersList = 'EUWRPRCProvidersList',\n EUEAAProvidersList = 'EUEAAProvidersList',\n EUPubEAAProvidersList = 'EUPubEAAProvidersList',\n mDLProvidersList = 'mDLProvidersList',\n}\n\nconst profileConfig: Record<LoTEProfile, { loTEType: string; schema: z.ZodType }> = {\n [LoTEProfile.EUPIDProvidersList]: { loTEType: LOTE_TYPES.EUPIDProvidersList, schema: EUPIDProvidersListSchema },\n [LoTEProfile.EUWalletProvidersList]: {\n loTEType: LOTE_TYPES.EUWalletProvidersList,\n schema: EUWalletProvidersListSchema,\n },\n [LoTEProfile.EUWRPACProvidersList]: { loTEType: LOTE_TYPES.EUWRPACProvidersList, schema: EUWRPACProvidersListSchema },\n [LoTEProfile.EUWRPRCProvidersList]: { loTEType: LOTE_TYPES.EUWRPRCProvidersList, schema: EUWRPRCProvidersListSchema },\n [LoTEProfile.EUEAAProvidersList]: { loTEType: LOTE_TYPES.EUEAAProvidersList, schema: EUEAAProvidersListSchema },\n [LoTEProfile.EUPubEAAProvidersList]: {\n loTEType: LOTE_TYPES.EUPubEAAProvidersList,\n schema: EUPubEAAProvidersListSchema,\n },\n [LoTEProfile.mDLProvidersList]: { loTEType: LOTE_TYPES.mDLProvidersList, schema: mDLProvidersListSchema },\n}\n\nfunction getDocumentLoTEType(loteDocument: unknown): string | undefined {\n try {\n const type = (loteDocument as { LoTE?: { ListAndSchemeInformation?: { LoTEType?: unknown } } } | null | undefined)\n ?.LoTE?.ListAndSchemeInformation?.LoTEType\n return typeof type === 'string' ? type : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Validate a LoTE document against one or more given profiles. Validation\n * succeeds if the document matches one of the specified profiles\n *\n * @param loteDocument - The LoTE document to validate\n * @param profile - The profile(s) to validate against\n * @returns Validation result with errors if invalid\n */\nexport function validateLoTEProfile(loteDocument: unknown, profile: LoTEProfile | LoTEProfile[]): ValidationResult {\n const profiles = Array.isArray(profile) ? profile : [profile]\n const documentLoTEType = getDocumentLoTEType(loteDocument)\n\n // LoTEType is unique per profile, so at most one requested profile can match.\n const matchedProfile = profiles.find((p) => profileConfig[p].loTEType === documentLoTEType)\n\n if (matchedProfile) {\n const result = profileConfig[matchedProfile].schema.safeParse(loteDocument)\n\n if (result.success) {\n return { valid: true, errors: [] }\n }\n\n return {\n valid: false,\n errors: [\n { path: 'LoTEType', message: `Document does not match profile ${matchedProfile}` },\n ...result.error.issues.map((issue) => ({\n path: issue.path.join('.'),\n message: `Profile ${matchedProfile}: ${issue.message}`,\n })),\n ],\n }\n }\n\n // No requested profile matches the document's LoTEType.\n return {\n valid: false,\n errors: [\n {\n path: 'LoTEType',\n message: `Document does not match any of the specified profiles: ${profiles.join(', ')}`,\n },\n ...profiles.map((p) => ({\n path: 'LoTE.ListAndSchemeInformation.LoTEType',\n message: `Profile ${p}: LoTEType must be ${profileConfig[p].loTEType}`,\n })),\n ],\n }\n}\n"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { IdentityException, base64urlEncode } from "@owf/identity-common";
2
- import z, { z as z$1 } from "zod";
2
+ import { z as z$1 } from "zod";
3
3
  import { parseCertificate } from "@owf/crypto";
4
4
  //#region src/lote-exception.ts
5
5
  /**
@@ -408,6 +408,15 @@ function service() {
408
408
  //#endregion
409
409
  //#region src/profiles.ts
410
410
  const SIX_MONTHS_IN_MS = 4464 * 60 * 60 * 1e3;
411
+ const LOTE_TYPES = {
412
+ EUPIDProvidersList: "http://uri.etsi.org/19602/LoTEType/EUPIDProvidersList",
413
+ EUWalletProvidersList: "http://uri.etsi.org/19602/LoTEType/EUWalletProvidersList",
414
+ EUWRPACProvidersList: "http://uri.etsi.org/19602/LoTEType/EUWRPACProvidersList",
415
+ EUWRPRCProvidersList: "http://uri.etsi.org/19602/LoTEType/EUWRPRCProvidersList",
416
+ EUEAAProvidersList: "http://uri.etsi.org/19602/LoTEType/EUEAAProvidersList",
417
+ EUPubEAAProvidersList: "http://uri.etsi.org/19602/LoTEType/EUPubEAAProvidersList",
418
+ mDLProvidersList: "http://trust.ec.europa.eu/lists/mDL/mDLProvidersListType"
419
+ };
411
420
  const listAndSchemeInformationRefinement = ({ loTEType, loTEVersionIdentifier, statusDeterminationApproach, schemeTerritory, schemeTypeCommunityRulesUri, historicalInformationPeriod, requireNoHistoricalInformationPeriod, requireNoPointersToOtherLoTE }) => ({ LoTE }, ctx) => {
412
421
  const info = LoTE.ListAndSchemeInformation;
413
422
  const path = ["LoTE", "ListAndSchemeInformation"];
@@ -533,7 +542,7 @@ const trustedEntitiesListRefinement = ({ allowedServiceTypeIdentifiers, informat
533
542
  });
534
543
  };
535
544
  const EUPIDProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInformationRefinement({
536
- loTEType: "http://uri.etsi.org/19602/LoTEType/EUPIDProvidersList",
545
+ loTEType: LOTE_TYPES.EUPIDProvidersList,
537
546
  loTEVersionIdentifier: 1,
538
547
  statusDeterminationApproach: "http://uri.etsi.org/19602/PIDProvidersList/StatusDetn/EU",
539
548
  schemeTerritory: "EU",
@@ -544,7 +553,7 @@ const EUPIDProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInf
544
553
  informationUriPrefix: "http://uri.etsi.org/19602/ListOfTrustedEntities/PIDProvider/"
545
554
  }));
546
555
  const EUWalletProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInformationRefinement({
547
- loTEType: "http://uri.etsi.org/19602/LoTEType/EUWalletProvidersList",
556
+ loTEType: LOTE_TYPES.EUWalletProvidersList,
548
557
  loTEVersionIdentifier: 1,
549
558
  statusDeterminationApproach: "http://uri.etsi.org/19602/WalletProvidersList/StatusDetn/EU",
550
559
  schemeTerritory: "EU",
@@ -555,7 +564,7 @@ const EUWalletProvidersListSchema = LoTEDocumentSchema.superRefine(listAndScheme
555
564
  informationUriPrefix: "http://uri.etsi.org/19602/ListOfTrustedEntities/WalletProvider/"
556
565
  }));
557
566
  const EUWRPACProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInformationRefinement({
558
- loTEType: "http://uri.etsi.org/19602/LoTEType/EUWRPACProvidersList",
567
+ loTEType: LOTE_TYPES.EUWRPACProvidersList,
559
568
  loTEVersionIdentifier: 1,
560
569
  statusDeterminationApproach: "http://uri.etsi.org/19602/WRPACProvidersList/StatusDetn/EU",
561
570
  schemeTerritory: "EU",
@@ -566,7 +575,7 @@ const EUWRPACProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeI
566
575
  informationUriPrefix: "http://uri.etsi.org/19602/ListOfTrustedEntities/WRPACProvider/"
567
576
  }));
568
577
  const EUWRPRCProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInformationRefinement({
569
- loTEType: "http://uri.etsi.org/19602/LoTEType/EUWRPRCProvidersList",
578
+ loTEType: LOTE_TYPES.EUWRPRCProvidersList,
570
579
  loTEVersionIdentifier: 1,
571
580
  statusDeterminationApproach: "http://uri.etsi.org/19602/WRPRCrovidersList/StatusDetn/EU",
572
581
  schemeTerritory: "EU",
@@ -577,7 +586,7 @@ const EUWRPRCProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeI
577
586
  informationUriPrefix: "http://uri.etsi.org/19602/ListOfTrustedEntities/WRPRCProvider/"
578
587
  }));
579
588
  const EUEAAProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInformationRefinement({
580
- loTEType: "http://uri.etsi.org/19602/LoTEType/EUEAAProvidersList",
589
+ loTEType: LOTE_TYPES.EUEAAProvidersList,
581
590
  loTEVersionIdentifier: 1,
582
591
  statusDeterminationApproach: "http://uri.etsi.org/19602/EAAProvidersList/StatusDetn/EU\"",
583
592
  schemeTerritory: "EU",
@@ -588,7 +597,7 @@ const EUEAAProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInf
588
597
  informationUriPrefix: "http://uri.etsi.org/19602/ListOfTrustedEntities/EAAProvider/"
589
598
  }));
590
599
  const EUPubEAAProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInformationRefinement({
591
- loTEType: "http://uri.etsi.org/19602/LoTEType/EUPubEAAProvidersList",
600
+ loTEType: LOTE_TYPES.EUPubEAAProvidersList,
592
601
  loTEVersionIdentifier: 1,
593
602
  statusDeterminationApproach: "http://uri.etsi.org/19602/PubEAAProvidersList/StatusDetn/EU\"",
594
603
  schemeTerritory: "EU",
@@ -600,7 +609,7 @@ const EUPubEAAProvidersListSchema = LoTEDocumentSchema.superRefine(listAndScheme
600
609
  informationUriPrefix: "http://uri.etsi.org/19602/ListOfTrustedEntities/PubEAAProvider/"
601
610
  }));
602
611
  const mDLProvidersListSchema = LoTEDocumentSchema.superRefine(listAndSchemeInformationRefinement({
603
- loTEType: "http://trust.ec.europa.eu/lists/mDL/mDLProvidersListType",
612
+ loTEType: LOTE_TYPES.mDLProvidersList,
604
613
  loTEVersionIdentifier: 1,
605
614
  statusDeterminationApproach: "http://trust.ec.europa.eu/lists/mDL/mDLProvidersListStatusDetn",
606
615
  schemeTerritory: "EU",
@@ -745,11 +754,6 @@ function removeTrustedEntity(lote, entityName) {
745
754
  //#endregion
746
755
  //#region src/validator.ts
747
756
  /**
748
- * LoTE Validator
749
- *
750
- * Runtime validation for ETSI TS 119 602 LoTE documents using Zod schemas.
751
- */
752
- /**
753
757
  * Validate a LoTE document against ETSI TS 119 602 schema
754
758
  *
755
759
  * @param loteDocument - The LoTE document to validate
@@ -800,15 +804,44 @@ let LoTEProfile = /* @__PURE__ */ function(LoTEProfile) {
800
804
  LoTEProfile["mDLProvidersList"] = "mDLProvidersList";
801
805
  return LoTEProfile;
802
806
  }({});
803
- const profileToSchemaMap = {
804
- ["EUPIDProvidersList"]: EUPIDProvidersListSchema,
805
- ["EUWalletProvidersList"]: EUWalletProvidersListSchema,
806
- ["EUWRPACProvidersList"]: EUWRPACProvidersListSchema,
807
- ["EUWRPRCProvidersList"]: EUWRPRCProvidersListSchema,
808
- ["EUEAAProvidersList"]: EUEAAProvidersListSchema,
809
- ["EUPubEAAProvidersList"]: EUPubEAAProvidersListSchema,
810
- ["mDLProvidersList"]: mDLProvidersListSchema
807
+ const profileConfig = {
808
+ ["EUPIDProvidersList"]: {
809
+ loTEType: LOTE_TYPES.EUPIDProvidersList,
810
+ schema: EUPIDProvidersListSchema
811
+ },
812
+ ["EUWalletProvidersList"]: {
813
+ loTEType: LOTE_TYPES.EUWalletProvidersList,
814
+ schema: EUWalletProvidersListSchema
815
+ },
816
+ ["EUWRPACProvidersList"]: {
817
+ loTEType: LOTE_TYPES.EUWRPACProvidersList,
818
+ schema: EUWRPACProvidersListSchema
819
+ },
820
+ ["EUWRPRCProvidersList"]: {
821
+ loTEType: LOTE_TYPES.EUWRPRCProvidersList,
822
+ schema: EUWRPRCProvidersListSchema
823
+ },
824
+ ["EUEAAProvidersList"]: {
825
+ loTEType: LOTE_TYPES.EUEAAProvidersList,
826
+ schema: EUEAAProvidersListSchema
827
+ },
828
+ ["EUPubEAAProvidersList"]: {
829
+ loTEType: LOTE_TYPES.EUPubEAAProvidersList,
830
+ schema: EUPubEAAProvidersListSchema
831
+ },
832
+ ["mDLProvidersList"]: {
833
+ loTEType: LOTE_TYPES.mDLProvidersList,
834
+ schema: mDLProvidersListSchema
835
+ }
811
836
  };
837
+ function getDocumentLoTEType(loteDocument) {
838
+ try {
839
+ const type = loteDocument?.LoTE?.ListAndSchemeInformation?.LoTEType;
840
+ return typeof type === "string" ? type : void 0;
841
+ } catch {
842
+ return;
843
+ }
844
+ }
812
845
  /**
813
846
  * Validate a LoTE document against one or more given profiles. Validation
814
847
  * succeeds if the document matches one of the specified profiles
@@ -819,26 +852,34 @@ const profileToSchemaMap = {
819
852
  */
820
853
  function validateLoTEProfile(loteDocument, profile) {
821
854
  const profiles = Array.isArray(profile) ? profile : [profile];
822
- const result = z.union(profiles.map((p) => profileToSchemaMap[p])).safeParse(loteDocument);
823
- if (result.success) return {
824
- valid: true,
825
- errors: []
826
- };
855
+ const documentLoTEType = getDocumentLoTEType(loteDocument);
856
+ const matchedProfile = profiles.find((p) => profileConfig[p].loTEType === documentLoTEType);
857
+ if (matchedProfile) {
858
+ const result = profileConfig[matchedProfile].schema.safeParse(loteDocument);
859
+ if (result.success) return {
860
+ valid: true,
861
+ errors: []
862
+ };
863
+ return {
864
+ valid: false,
865
+ errors: [{
866
+ path: "LoTEType",
867
+ message: `Document does not match profile ${matchedProfile}`
868
+ }, ...result.error.issues.map((issue) => ({
869
+ path: issue.path.join("."),
870
+ message: `Profile ${matchedProfile}: ${issue.message}`
871
+ }))]
872
+ };
873
+ }
827
874
  return {
828
875
  valid: false,
829
876
  errors: [{
830
877
  path: "LoTEType",
831
878
  message: `Document does not match any of the specified profiles: ${profiles.join(", ")}`
832
- }, ...result.error.issues.flatMap((issue) => {
833
- if (issue.code === "invalid_union") return issue.errors.flatMap((branchIssues, index) => branchIssues.map((branchIssue) => ({
834
- path: branchIssue.path.join("."),
835
- message: `Profile ${profiles[index]}: ${branchIssue.message}`
836
- })));
837
- return [{
838
- path: issue.path.join("."),
839
- message: issue.message
840
- }];
841
- })]
879
+ }, ...profiles.map((p) => ({
880
+ path: "LoTE.ListAndSchemeInformation.LoTEType",
881
+ message: `Profile ${p}: LoTEType must be ${profileConfig[p].loTEType}`
882
+ }))]
842
883
  };
843
884
  }
844
885
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["z"],"sources":["../src/lote-exception.ts","../src/schemas.ts","../src/builders.ts","../src/profiles.ts","../src/signer.ts","../src/validator.ts"],"sourcesContent":["import { IdentityException } from '@owf/identity-common'\n\n/**\n * LoTEException is a custom error class for LoTE-related exceptions.\n */\nexport class LoTEException extends IdentityException {\n constructor(message: string, details?: unknown) {\n super(message, details)\n Object.setPrototypeOf(this, LoTEException.prototype)\n this.name = 'LoTEException'\n }\n}\n","/**\n * LoTE Zod Schemas\n *\n * Zod schemas for ETSI TS 119 602 (LoTE - List of Trusted Entities) format.\n * Types are derived from these schemas via z.infer<>.\n *\n * @see https://www.etsi.org/deliver/etsi_ts/119600_119699/119602/01.01.01_60/ts_119602v010101p.pdf\n */\n\nimport { z } from 'zod'\n\n// ============================================================================\n// Localized Value Schemas\n// ============================================================================\n\nexport const LocalizedStringSchema = z.object({\n lang: z.string().min(1),\n value: z.string().min(1),\n})\n\nexport const LocalizedURISchema = z.object({\n lang: z.string().min(1),\n uriValue: z.url(),\n})\n\n// ============================================================================\n// Address Schemas\n// ============================================================================\n\nexport const PostalAddressSchema = z.object({\n lang: z.string().min(1),\n StreetAddress: z.string(),\n Locality: z.string(),\n StateOrProvince: z.string().optional(),\n PostalCode: z.string(),\n Country: z.string().length(2),\n})\n\nexport const SchemeOperatorAddressSchema = z.object({\n SchemeOperatorPostalAddress: z.array(PostalAddressSchema),\n SchemeOperatorElectronicAddress: z.array(LocalizedURISchema),\n})\n\nexport const TrustedEntityAddressSchema = z.object({\n TEPostalAddress: z.array(PostalAddressSchema),\n TEElectronicAddress: z.array(LocalizedURISchema),\n})\n\n// ============================================================================\n// Digital Identity Schemas\n// ============================================================================\n\nexport const PkiObjectSchema = z.object({\n encoding: z.string().optional(),\n specRef: z.string().optional(),\n val: z.string().min(1),\n})\n\nexport const X509CertificateRefSchema = PkiObjectSchema.extend({\n encoding: z.literal('urn:ietf:params:tls-cert-type:x509').optional(),\n specRef: z.literal('RFC5280').optional(),\n})\n\nexport const JWKPublicKeySchema = z.looseObject({\n kty: z.enum(['RSA', 'EC', 'OKP']),\n kid: z.string().optional(),\n use: z.enum(['sig', 'enc']).optional(),\n alg: z.string().optional(),\n})\n\nexport const ServiceDigitalIdentitySchema = z\n .object({\n X509Certificates: z.array(X509CertificateRefSchema).optional(),\n X509SubjectNames: z.array(z.string()).optional(),\n PublicKeyValues: z.array(JWKPublicKeySchema).optional(),\n X509SKIs: z.array(z.string()).optional(),\n OtherIds: z.array(z.string()).optional(),\n })\n .refine(\n (id) =>\n (id.X509Certificates && id.X509Certificates.length > 0) ||\n (id.X509SubjectNames && id.X509SubjectNames.length > 0) ||\n (id.PublicKeyValues && id.PublicKeyValues.length > 0) ||\n (id.X509SKIs && id.X509SKIs.length > 0) ||\n (id.OtherIds && id.OtherIds.length > 0),\n { message: 'At least one digital identity type must be provided' }\n )\n\n// ============================================================================\n// Service Schemas\n// ============================================================================\n\nexport const ServiceSupplyPointSchema = z.object({\n ServiceType: z.string(),\n uriValue: z.url(),\n})\n\nexport const ServiceInformationSchema = z.object({\n ServiceName: z.array(LocalizedStringSchema).min(1),\n ServiceDigitalIdentity: ServiceDigitalIdentitySchema,\n ServiceTypeIdentifier: z.url().optional(),\n ServiceStatus: z.url().optional(),\n StatusStartingTime: z.iso.datetime().optional(),\n SchemeServiceDefinitionURI: z.array(LocalizedURISchema).optional(),\n ServiceSupplyPoints: z.array(ServiceSupplyPointSchema).optional(),\n ServiceDefinitionURI: z.array(LocalizedURISchema).optional(),\n ServiceInformationExtensions: z.array(z.unknown()).optional(),\n})\n\nexport const ServiceHistoryInstanceSchema = z.object({\n ServiceName: z.array(LocalizedStringSchema).min(1),\n ServiceDigitalIdentity: ServiceDigitalIdentitySchema,\n ServiceStatus: z.url(),\n StatusStartingTime: z.iso.datetime(),\n ServiceTypeIdentifier: z.url().optional(),\n ServiceInformationExtensions: z.array(z.unknown()).optional(),\n})\n\nexport const TrustedEntityServiceSchema = z.object({\n ServiceInformation: ServiceInformationSchema,\n ServiceHistory: z.array(ServiceHistoryInstanceSchema).optional(),\n})\n\n// ============================================================================\n// Trusted Entity Schemas\n// ============================================================================\n\nexport const TrustedEntityInformationSchema = z.object({\n TEName: z.array(LocalizedStringSchema).min(1),\n TETradeName: z.array(LocalizedStringSchema).optional(),\n TEAddress: TrustedEntityAddressSchema,\n TEInformationURI: z.array(LocalizedURISchema).optional(),\n TEInformationExtensions: z.array(z.unknown()).optional(),\n})\n\nexport const TrustedEntitySchema = z.object({\n TrustedEntityInformation: TrustedEntityInformationSchema,\n TrustedEntityServices: z.array(TrustedEntityServiceSchema).min(1),\n})\n\n// ============================================================================\n// List and Scheme Information Schemas\n// ============================================================================\n\nexport const PolicyOrLegalNoticeSchema = z.object({\n LoTEPolicy: LocalizedURISchema.optional(),\n LoTELegalNotice: LocalizedStringSchema.optional(),\n})\n\nexport const LoTEQualifierSchema = z.object({\n LoTEType: z.url(),\n SchemeOperatorName: z.array(LocalizedStringSchema).min(1),\n SchemeTypeCommunityRules: z.array(LocalizedURISchema).optional(),\n SchemeTerritory: z.string().length(2).optional(),\n MimeType: z.string().min(1),\n})\n\nexport const OtherLoTEPointerSchema = z.object({\n LoTELocation: z.url(),\n ServiceDigitalIdentities: z.array(ServiceDigitalIdentitySchema).min(1),\n LoTEQualifiers: z.array(LoTEQualifierSchema).min(1),\n})\n\nexport const ListAndSchemeInformationSchema = z.object({\n LoTEVersionIdentifier: z.number().int(),\n LoTESequenceNumber: z.number().int(),\n LoTEType: z.url().optional(),\n SchemeOperatorName: z.array(LocalizedStringSchema).min(1),\n SchemeOperatorAddress: SchemeOperatorAddressSchema.optional(),\n SchemeName: z.array(LocalizedStringSchema).optional(),\n SchemeInformationURI: z.array(LocalizedURISchema).optional(),\n StatusDeterminationApproach: z.url().optional(),\n SchemeTypeCommunityRules: z.array(LocalizedURISchema).optional(),\n SchemeTerritory: z.string().length(2).optional(),\n PolicyOrLegalNotice: z.array(PolicyOrLegalNoticeSchema).optional(),\n HistoricalInformationPeriod: z.number().optional(),\n PointersToOtherLoTE: z.array(OtherLoTEPointerSchema).optional(),\n ListIssueDateTime: z.iso.datetime(),\n NextUpdate: z.iso.datetime(),\n DistributionPoints: z.array(z.url()).optional(),\n SchemeExtensions: z.array(z.unknown()).optional(),\n})\n\n// ============================================================================\n// LoTE Root Schemas\n// ============================================================================\n\nexport const LoTESchema = z.object({\n ListAndSchemeInformation: ListAndSchemeInformationSchema,\n TrustedEntitiesList: z.array(TrustedEntitySchema),\n})\n\nexport const LoTEDocumentSchema = z.object({\n LoTE: LoTESchema,\n})\n","import { LoTEException } from './lote-exception'\nimport { TrustedEntitySchema, TrustedEntityServiceSchema } from './schemas'\nimport type {\n JWKPublicKey,\n PostalAddress,\n ServiceHistoryInstance,\n ServiceInformation,\n TrustedEntity,\n TrustedEntityInformation,\n TrustedEntityService,\n} from './types'\n\n/**\n * Builder for creating TrustedEntity objects with a fluent API\n */\nexport class TrustedEntityBuilder {\n private info: Partial<TrustedEntityInformation> = {}\n private services: TrustedEntityService[] = []\n\n /**\n * Set the entity name\n */\n name(value: string, lang = 'en'): this {\n this.info.TEName = this.info.TEName ?? []\n this.info.TEName.push({ lang, value })\n return this\n }\n\n /**\n * Set the trade name\n */\n tradeName(value: string, lang = 'en'): this {\n this.info.TETradeName = this.info.TETradeName ?? []\n this.info.TETradeName.push({ lang, value })\n return this\n }\n\n /**\n * Set the postal address\n */\n postalAddress(address: Omit<PostalAddress, 'lang'>, lang = 'en'): this {\n this.info.TEAddress = this.info.TEAddress ?? {\n TEPostalAddress: [],\n TEElectronicAddress: [],\n }\n this.info.TEAddress.TEPostalAddress.push({ ...address, lang })\n return this\n }\n\n /**\n * Add an electronic address (email)\n */\n email(email: string, lang = 'en'): this {\n this.info.TEAddress = this.info.TEAddress ?? {\n TEPostalAddress: [],\n TEElectronicAddress: [],\n }\n this.info.TEAddress.TEElectronicAddress.push({\n lang,\n uriValue: email.startsWith('mailto:') ? email : `mailto:${email}`,\n })\n return this\n }\n\n /**\n * Add an information URI\n */\n infoUri(uri: string, lang = 'en'): this {\n this.info.TEInformationURI = this.info.TEInformationURI ?? []\n this.info.TEInformationURI.push({ lang, uriValue: uri })\n return this\n }\n\n /**\n * Add a website URL as an electronic address\n */\n website(url: string, lang = 'en'): this {\n this.info.TEAddress = this.info.TEAddress ?? {\n TEPostalAddress: [],\n TEElectronicAddress: [],\n }\n this.info.TEAddress.TEElectronicAddress.push({\n lang,\n uriValue: url.startsWith('http') ? url : `https://${url}`,\n })\n return this\n }\n\n /**\n * Add custom extensions\n */\n addExtension(extension: unknown): this {\n this.info.TEInformationExtensions = this.info.TEInformationExtensions ?? []\n this.info.TEInformationExtensions.push(extension)\n return this\n }\n\n /**\n * Add a service to the entity\n */\n addService(service: TrustedEntityService): this {\n this.services.push(service)\n return this\n }\n\n /**\n * Build the TrustedEntity object\n */\n build(): TrustedEntity {\n const result = TrustedEntitySchema.safeParse({\n TrustedEntityInformation: this.info,\n TrustedEntityServices: this.services,\n })\n\n if (!result.success) {\n const messages = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('\\n')\n throw new LoTEException(`Invalid TrustedEntity:\\n${messages}`)\n }\n\n return result.data\n }\n}\n\n/**\n * Builder for creating TrustedEntityService objects\n */\nexport class ServiceBuilder {\n private info: Partial<ServiceInformation> = {}\n private history: ServiceHistoryInstance[] = []\n\n /**\n * Set the service name\n */\n name(value: string, lang = 'en'): this {\n this.info.ServiceName = this.info.ServiceName ?? []\n this.info.ServiceName.push({ lang, value })\n return this\n }\n\n /**\n * Set the service type identifier\n */\n type(typeUri: string): this {\n this.info.ServiceTypeIdentifier = typeUri\n return this\n }\n\n /**\n * Set the service status\n */\n status(statusUri: string, startingTime?: Date): this {\n this.info.ServiceStatus = statusUri\n this.info.StatusStartingTime = startingTime?.toISOString() ?? new Date().toISOString()\n return this\n }\n\n /**\n * Add an X.509 certificate to the digital identity\n */\n addCertificate(certBase64: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.X509Certificates = this.info.ServiceDigitalIdentity.X509Certificates ?? []\n this.info.ServiceDigitalIdentity.X509Certificates.push({\n encoding: 'urn:ietf:params:tls-cert-type:x509',\n specRef: 'RFC5280',\n val: certBase64,\n })\n return this\n }\n\n /**\n * Add an X.509 subject name (DN format) to the digital identity\n */\n addX509SubjectName(subjectName: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.X509SubjectNames = this.info.ServiceDigitalIdentity.X509SubjectNames ?? []\n this.info.ServiceDigitalIdentity.X509SubjectNames.push(subjectName)\n return this\n }\n\n /**\n * Add an X.509 Subject Key Identifier (base64-encoded) to the digital identity\n */\n addX509SKI(ski: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.X509SKIs = this.info.ServiceDigitalIdentity.X509SKIs ?? []\n this.info.ServiceDigitalIdentity.X509SKIs.push(ski)\n return this\n }\n\n /**\n * Add another identifier to the digital identity\n */\n addOtherId(id: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.OtherIds = this.info.ServiceDigitalIdentity.OtherIds ?? []\n this.info.ServiceDigitalIdentity.OtherIds.push(id)\n return this\n }\n\n /**\n * Add a public key (JWK) to the digital identity\n */\n addPublicKey(jwk: JWKPublicKey): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.PublicKeyValues = this.info.ServiceDigitalIdentity.PublicKeyValues ?? []\n this.info.ServiceDigitalIdentity.PublicKeyValues.push(jwk)\n return this\n }\n\n /**\n * Add a service endpoint\n */\n addEndpoint(type: string, uri: string): this {\n this.info.ServiceSupplyPoints = this.info.ServiceSupplyPoints ?? []\n this.info.ServiceSupplyPoints.push({ ServiceType: type, uriValue: uri })\n return this\n }\n\n /**\n * Add a service definition URI\n */\n addDefinitionUri(uri: string, lang = 'en'): this {\n this.info.ServiceDefinitionURI = this.info.ServiceDefinitionURI ?? []\n this.info.ServiceDefinitionURI.push({ lang, uriValue: uri })\n return this\n }\n\n /**\n * Add custom service information extensions\n */\n addExtension(extension: unknown): this {\n this.info.ServiceInformationExtensions = this.info.ServiceInformationExtensions ?? []\n this.info.ServiceInformationExtensions.push(extension)\n return this\n }\n\n /**\n * Add a historical service instance\n */\n addHistoryEntry(historyInstance: ServiceHistoryInstance): this {\n this.history.push(historyInstance)\n return this\n }\n\n /**\n * Build the TrustedEntityService object\n */\n build(): TrustedEntityService {\n const data: Record<string, unknown> = {\n ServiceInformation: this.info,\n }\n\n if (this.history.length > 0) {\n data.ServiceHistory = this.history\n }\n\n const result = TrustedEntityServiceSchema.safeParse(data)\n\n if (!result.success) {\n const messages = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('\\n')\n throw new LoTEException(`Invalid TrustedEntityService:\\n${messages}`)\n }\n\n return result.data\n }\n}\n\n/**\n * Create a new TrustedEntityBuilder\n */\nexport function trustedEntity(): TrustedEntityBuilder {\n return new TrustedEntityBuilder()\n}\n\n/**\n * Create a new ServiceBuilder\n */\nexport function service(): ServiceBuilder {\n return new ServiceBuilder()\n}\n","/**\n * LoTE Profiles\n *\n * @see https://www.etsi.org/deliver/etsi_ts/119600_119699/119602/01.01.01_60/ts_119602v010101p.pdf\n * @see https://acceptance.eidas.ec.europa.eu/efda/wallet/lists-of-trusted-entities/mdl-providers\n */\n\nimport type z from 'zod'\nimport { LoTEDocumentSchema } from './schemas'\nimport type { LoTEDocument } from './types'\n\nconst SIX_MONTHS_IN_MS = 6 * 31 * 24 * 60 * 60 * 1000\n\ntype ListAndSchemeInformationRefinementOptions = {\n loTEType: string\n loTEVersionIdentifier: number\n statusDeterminationApproach: string\n schemeTerritory: string\n schemeTypeCommunityRulesUri: string\n historicalInformationPeriod?: number\n requireNoHistoricalInformationPeriod?: boolean\n requireNoPointersToOtherLoTE?: boolean\n}\n\nconst listAndSchemeInformationRefinement =\n ({\n loTEType,\n loTEVersionIdentifier,\n statusDeterminationApproach,\n schemeTerritory,\n schemeTypeCommunityRulesUri,\n historicalInformationPeriod,\n requireNoHistoricalInformationPeriod,\n requireNoPointersToOtherLoTE,\n }: ListAndSchemeInformationRefinementOptions) =>\n ({ LoTE }: LoTEDocument, ctx: z.RefinementCtx<LoTEDocument>) => {\n const info = LoTE.ListAndSchemeInformation\n const path = ['LoTE', 'ListAndSchemeInformation']\n\n if (info.LoTEType !== loTEType) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [loTEType],\n message: `LoTEType must be ${loTEType}`,\n path: [...path, 'LoTEType'],\n })\n }\n\n if (info.LoTEVersionIdentifier !== loTEVersionIdentifier) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [loTEVersionIdentifier],\n message: `LoTEVersionIdentifier must be ${loTEVersionIdentifier}`,\n path: [...path, 'LoTEVersionIdentifier'],\n })\n }\n\n if (info.StatusDeterminationApproach !== statusDeterminationApproach) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [statusDeterminationApproach],\n message: `StatusDeterminationApproach must be ${statusDeterminationApproach}`,\n path: [...path, 'StatusDeterminationApproach'],\n })\n }\n\n if (info.SchemeTerritory !== schemeTerritory) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [schemeTerritory],\n message: `SchemeTerritory must be ${schemeTerritory}`,\n path: [...path, 'SchemeTerritory'],\n })\n }\n\n if (\n !info.SchemeTypeCommunityRules ||\n info.SchemeTypeCommunityRules.length !== 1 ||\n info.SchemeTypeCommunityRules[0].uriValue !== schemeTypeCommunityRulesUri\n ) {\n ctx.addIssue({\n code: 'custom',\n message: `SchemeTypeCommunityRules must contain a single element with uriValue of ${schemeTypeCommunityRulesUri}`,\n path: [...path, 'SchemeTypeCommunityRules'],\n })\n }\n\n if (requireNoHistoricalInformationPeriod && typeof info.HistoricalInformationPeriod !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'HistoricalInformationPeriod must not be present',\n path: [...path, 'HistoricalInformationPeriod'],\n })\n }\n\n if (historicalInformationPeriod !== undefined && info.HistoricalInformationPeriod !== historicalInformationPeriod) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [historicalInformationPeriod],\n message: `HistoricalInformationPeriod must be ${historicalInformationPeriod}`,\n path: [...path, 'HistoricalInformationPeriod'],\n })\n }\n\n if (requireNoPointersToOtherLoTE && typeof info.PointersToOtherLoTE !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'PointersToOtherLoTE must not be present',\n path: [...path, 'PointersToOtherLoTE'],\n })\n }\n\n const listIssueDateTime = new Date(info.ListIssueDateTime).getTime()\n const nextUpdate = new Date(info.NextUpdate).getTime()\n\n if (nextUpdate - listIssueDateTime > SIX_MONTHS_IN_MS) {\n ctx.addIssue({\n code: 'custom',\n message: 'NextUpdate must be within 6 months of ListIssueDateTime',\n path: [...path, 'NextUpdate'],\n })\n }\n }\n\ntype TrustedEntitiesListRefinementOptions = {\n allowedServiceTypeIdentifiers: string[]\n informationUriPrefix?: string\n}\n\nconst trustedEntitiesListRefinement =\n ({ allowedServiceTypeIdentifiers, informationUriPrefix }: TrustedEntitiesListRefinementOptions) =>\n ({ LoTE }: LoTEDocument, ctx: z.RefinementCtx<LoTEDocument>) => {\n LoTE.TrustedEntitiesList.forEach((entity, index) => {\n const trustedEntityPath = ['LoTE', 'TrustedEntitiesList', index.toString()]\n\n if (informationUriPrefix) {\n const uri = entity.TrustedEntityInformation.TEInformationURI?.find(({ uriValue }) =>\n uriValue.startsWith(informationUriPrefix)\n )\n\n if (!uri) {\n ctx.addIssue({\n code: 'custom',\n message: `Each TrustedEntityInformation.TEInformationURI must contain at least one URI starting with ${informationUriPrefix}`,\n path: [...trustedEntityPath, 'TrustedEntityInformation', 'TEInformationURI'],\n })\n } else {\n const rest = uri.uriValue.substring(informationUriPrefix.length)\n if (rest.length !== 2) {\n ctx.addIssue({\n code: 'custom',\n message: `URI starting with ${informationUriPrefix} must be followed by a 2-letter country code`,\n path: [...trustedEntityPath, 'TrustedEntityInformation', 'TEInformationURI'],\n })\n }\n }\n }\n\n entity.TrustedEntityServices.forEach((service, serviceIndex) => {\n const entityServicePath = [...trustedEntityPath, 'TrustedEntityServices', serviceIndex.toString()]\n\n if (typeof service.ServiceInformation.ServiceStatus !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'ServiceStatus must not be present',\n path: [...entityServicePath, 'ServiceInformation', 'ServiceStatus'],\n })\n }\n\n if (typeof service.ServiceInformation.StatusStartingTime !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'StatusStartingTime must not be present',\n path: [...entityServicePath, 'ServiceInformation', 'StatusStartingTime'],\n })\n }\n\n if (\n !service.ServiceInformation.ServiceTypeIdentifier ||\n !allowedServiceTypeIdentifiers.includes(service.ServiceInformation.ServiceTypeIdentifier)\n ) {\n ctx.addIssue({\n code: 'invalid_value',\n message: `ServiceTypeIdentifier must be one of the following: ${allowedServiceTypeIdentifiers.join(', ')}`,\n path: [...entityServicePath, 'ServiceInformation', 'ServiceTypeIdentifier'],\n values: allowedServiceTypeIdentifiers,\n })\n }\n })\n })\n }\n\n// ETSI TS 119 602 D\nexport const EUPIDProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: 'http://uri.etsi.org/19602/LoTEType/EUPIDProvidersList',\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/PIDProvidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/PIDProviders/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/PID/Issuance',\n 'http://uri.etsi.org/19602/SvcType/PID/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/PIDProvider/',\n })\n)\n\n// ETSI TS 119 602 E\nexport const EUWalletProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: 'http://uri.etsi.org/19602/LoTEType/EUWalletProvidersList',\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/WalletProvidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/WalletProvidersList/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/WalletSolution/Issuance',\n 'http://uri.etsi.org/19602/SvcType/WalletSolution/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/WalletProvider/',\n })\n)\n\n// ETSI TS 119 602 F\nexport const EUWRPACProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: 'http://uri.etsi.org/19602/LoTEType/EUWRPACProvidersList',\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/WRPACProvidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/WRPACProvidersList/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/WRPAC/Issuance',\n 'http://uri.etsi.org/19602/SvcType/WRPAC/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/WRPACProvider/',\n })\n)\n\n// ETSI TS 119 602 G\nexport const EUWRPRCProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: 'http://uri.etsi.org/19602/LoTEType/EUWRPRCProvidersList',\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/WRPRCrovidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/WRPRCProvidersList/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/WRPRC/Issuance',\n 'http://uri.etsi.org/19602/SvcType/WRPRC/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/WRPRCProvider/',\n })\n)\n\nexport const EUEAAProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: 'http://uri.etsi.org/19602/LoTEType/EUEAAProvidersList',\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/EAAProvidersList/StatusDetn/EU\"',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/EAAProvidersList/schemerules/EU',\n requireNoPointersToOtherLoTE: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/EAA/Issuance',\n 'http://uri.etsi.org/19602/SvcType/EAA/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/EAAProvider/',\n })\n)\n\n// ETSI TS 119 602 H\nexport const EUPubEAAProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: 'http://uri.etsi.org/19602/LoTEType/EUPubEAAProvidersList',\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/PubEAAProvidersList/StatusDetn/EU\"',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/PubEAAProvidersList/schemerules/EU',\n requireNoPointersToOtherLoTE: true,\n historicalInformationPeriod: 65535,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/PubEAA/Issuance',\n 'http://uri.etsi.org/19602/SvcType/PubEAA/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/PubEAAProvider/',\n })\n)\n\n// mDL Providers List\nexport const mDLProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: 'http://trust.ec.europa.eu/lists/mDL/mDLProvidersListType',\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://trust.ec.europa.eu/lists/mDL/mDLProvidersListStatusDetn',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://trust.ec.europa.eu/lists/mDL/schemerules',\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://trust.ec.europa.eu/lists/mDL/SvcType/Issuance',\n 'http://trust.ec.europa.eu/lists/mDL/SvcType/Revocation',\n ],\n })\n)\n","import { parseCertificate } from '@owf/crypto'\nimport { base64urlEncode } from '@owf/identity-common'\nimport type { ListAndSchemeInformation, LoTE, LoTEDocument, SignedLoTE, SignOptions, TrustedEntity } from './types'\n\n/**\n * Sign a LoTE document\n *\n * @param options - Signing options including LoTE document, key ID, and signer function\n * @returns The signed LoTE document as a JWS\n *\n * @example Using a local key via @owf/crypto:\n * ```typescript\n * import { ES256 } from '@owf/crypto';\n * import { signLoTE } from '@owf/eudi-lote';\n *\n * const { privateKey } = await ES256.generateKeyPair();\n * const signer = await ES256.getSigner(privateKey);\n * const signed = await signLoTE({\n * lote: myLoTE,\n * keyId: 'lote-signer-2025',\n * signer,\n * });\n * ```\n *\n * @example Using an external KMS:\n * ```typescript\n * const signed = await signLoTE({\n * lote: myLoTE,\n * keyId: 'lote-signer-2025',\n * signer: async (data) => myKms.sign('ES256', data),\n * });\n * ```\n */\nexport async function signLoTE(options: SignOptions): Promise<SignedLoTE> {\n const { lote, keyId, algorithm = 'ES256', certificates, signer } = options\n\n const header: Record<string, unknown> = {\n alg: algorithm,\n typ: 'trustlist+jwt',\n kid: keyId,\n }\n\n if (certificates && certificates.length > 0) {\n header.x5c = certificates.map(parseCertificate)\n }\n\n const encodedHeader = base64urlEncode(JSON.stringify(header))\n const encodedPayload = base64urlEncode(JSON.stringify(lote))\n const signingInput = `${encodedHeader}.${encodedPayload}`\n\n const signature = await signer(signingInput)\n const jws = `${signingInput}.${signature}`\n\n return {\n jws,\n header: {\n alg: algorithm,\n typ: 'trustlist+jwt',\n kid: keyId,\n x5c: header.x5c as string[] | undefined,\n },\n payload: lote,\n }\n}\n\n/**\n * Create a new LoTE document with required structure\n * Per ETSI TS 119 602, only SchemeOperatorName, ListIssueDateTime and NextUpdate are required\n * Default NextUpdate is 6 months per ETSI TS 119 602 maximum validity\n */\nexport function createLoTE(\n schemeInfo: Partial<ListAndSchemeInformation> & Pick<ListAndSchemeInformation, 'SchemeOperatorName'>,\n entities: TrustedEntity[] = []\n): LoTEDocument {\n const now = new Date()\n const sixMonthsLater = new Date(now)\n sixMonthsLater.setMonth(sixMonthsLater.getMonth() + 6)\n\n const lote: LoTE = {\n ListAndSchemeInformation: {\n LoTEVersionIdentifier: schemeInfo.LoTEVersionIdentifier ?? 1,\n LoTESequenceNumber: schemeInfo.LoTESequenceNumber ?? 1,\n LoTEType: schemeInfo.LoTEType,\n SchemeOperatorName: schemeInfo.SchemeOperatorName,\n SchemeOperatorAddress: schemeInfo.SchemeOperatorAddress,\n SchemeName: schemeInfo.SchemeName,\n SchemeInformationURI: schemeInfo.SchemeInformationURI,\n StatusDeterminationApproach: schemeInfo.StatusDeterminationApproach,\n SchemeTypeCommunityRules: schemeInfo.SchemeTypeCommunityRules,\n SchemeTerritory: schemeInfo.SchemeTerritory,\n PolicyOrLegalNotice: schemeInfo.PolicyOrLegalNotice,\n HistoricalInformationPeriod: schemeInfo.HistoricalInformationPeriod,\n PointersToOtherLoTE: schemeInfo.PointersToOtherLoTE,\n ListIssueDateTime: schemeInfo.ListIssueDateTime ?? now.toISOString(),\n NextUpdate: schemeInfo.NextUpdate ?? sixMonthsLater.toISOString(),\n DistributionPoints: schemeInfo.DistributionPoints,\n SchemeExtensions: schemeInfo.SchemeExtensions,\n },\n TrustedEntitiesList: entities,\n }\n\n return { LoTE: lote }\n}\n\n/**\n * Options for updating a LoTE version\n */\nexport interface UpdateLoTEVersionOptions {\n /**\n * The issue date/time for the new version.\n * Useful when generating a LoTE in advance before publication.\n * Defaults to the current time.\n */\n listIssueDateTime?: Date | string\n /**\n * The next update date/time.\n * Per ETSI TS 119 602, maximum validity is 6 months.\n * Defaults to 6 months from listIssueDateTime.\n */\n nextUpdate?: Date | string\n}\n\n/**\n * Increment the sequence number and update timestamps for a new version\n *\n * @param lote - The LoTE document to update\n * @param options - Optional settings for listIssueDateTime and nextUpdate\n * @returns A new LoTE document with incremented sequence number and updated timestamps\n *\n * @example Update with defaults (now + 6 months):\n * ```typescript\n * const updated = updateLoTEVersion(lote);\n * ```\n *\n * @example Schedule for future publication:\n * ```typescript\n * const updated = updateLoTEVersion(lote, {\n * listIssueDateTime: new Date('2025-01-01'),\n * nextUpdate: new Date('2025-06-01'),\n * });\n * ```\n */\nexport function updateLoTEVersion(lote: LoTEDocument, options: UpdateLoTEVersionOptions = {}): LoTEDocument {\n const issueDate = options.listIssueDateTime\n ? typeof options.listIssueDateTime === 'string'\n ? new Date(options.listIssueDateTime)\n : options.listIssueDateTime\n : new Date()\n\n const defaultNextUpdate = new Date(issueDate)\n defaultNextUpdate.setMonth(defaultNextUpdate.getMonth() + 6)\n\n const nextUpdateDate = options.nextUpdate\n ? typeof options.nextUpdate === 'string'\n ? options.nextUpdate\n : options.nextUpdate.toISOString()\n : defaultNextUpdate.toISOString()\n\n return {\n LoTE: {\n ...lote.LoTE,\n ListAndSchemeInformation: {\n ...lote.LoTE.ListAndSchemeInformation,\n LoTESequenceNumber: lote.LoTE.ListAndSchemeInformation.LoTESequenceNumber + 1,\n ListIssueDateTime: issueDate.toISOString(),\n NextUpdate: nextUpdateDate,\n },\n },\n }\n}\n\n/**\n * Add a trusted entity to a LoTE document\n */\nexport function addTrustedEntity(lote: LoTEDocument, entity: TrustedEntity): LoTEDocument {\n return {\n LoTE: {\n ...lote.LoTE,\n TrustedEntitiesList: [...lote.LoTE.TrustedEntitiesList, entity],\n },\n }\n}\n\n/**\n * Remove a trusted entity from a LoTE document by name\n */\nexport function removeTrustedEntity(lote: LoTEDocument, entityName: string): LoTEDocument {\n return {\n LoTE: {\n ...lote.LoTE,\n TrustedEntitiesList: lote.LoTE.TrustedEntitiesList.filter(\n (e) => !e.TrustedEntityInformation.TEName.some((n) => n.value === entityName)\n ),\n },\n }\n}\n","/**\n * LoTE Validator\n *\n * Runtime validation for ETSI TS 119 602 LoTE documents using Zod schemas.\n */\n\nimport z from 'zod'\nimport { LoTEException } from './lote-exception'\nimport {\n EUEAAProvidersListSchema,\n EUPIDProvidersListSchema,\n EUPubEAAProvidersListSchema,\n EUWalletProvidersListSchema,\n EUWRPACProvidersListSchema,\n EUWRPRCProvidersListSchema,\n mDLProvidersListSchema,\n} from './profiles'\nimport { LoTEDocumentSchema } from './schemas'\nimport type { LoTEDocument } from './types'\n\n/**\n * Validation error detail\n */\nexport interface ValidationError {\n /** Path to the invalid field */\n path: string\n /** Error message */\n message: string\n}\n\n/**\n * Validation result\n */\nexport interface ValidationResult {\n /** Whether the LoTE document is valid */\n valid: boolean\n /** List of validation errors (if invalid) */\n errors: ValidationError[]\n}\n\n/**\n * Validate a LoTE document against ETSI TS 119 602 schema\n *\n * @param loteDocument - The LoTE document to validate\n * @returns Validation result with errors if invalid\n *\n * @example\n * ```typescript\n * const result = validateLoTE(myLoTE);\n * if (!result.valid) {\n * console.error('Validation errors:', result.errors);\n * }\n * ```\n */\nexport function validateLoTE(loteDocument: unknown): ValidationResult {\n const result = LoTEDocumentSchema.safeParse(loteDocument)\n\n if (result.success) {\n return { valid: true, errors: [] }\n }\n\n const errors: ValidationError[] = result.error.issues.map((issue) => ({\n path: issue.path.join('.'),\n message: issue.message,\n }))\n\n return { valid: false, errors }\n}\n\n/**\n * Assert that a LoTE document is valid, throwing if not\n *\n * @param loteDocument - The LoTE document to validate\n * @throws Error if validation fails\n */\nexport function assertValidLoTE(loteDocument: unknown): asserts loteDocument is LoTEDocument {\n const result = validateLoTE(loteDocument)\n if (!result.valid) {\n const errorMessages = result.errors.map((e) => `${e.path}: ${e.message}`).join('\\n')\n throw new LoTEException(`Invalid LoTE document:\\n${errorMessages}`)\n }\n}\n\n/**\n * Supported LoTE profiles for validation\n */\nexport enum LoTEProfile {\n EUPIDProvidersList = 'EUPIDProvidersList',\n EUWalletProvidersList = 'EUWalletProvidersList',\n EUWRPACProvidersList = 'EUWRPACProvidersList',\n EUWRPRCProvidersList = 'EUWRPRCProvidersList',\n EUEAAProvidersList = 'EUEAAProvidersList',\n EUPubEAAProvidersList = 'EUPubEAAProvidersList',\n mDLProvidersList = 'mDLProvidersList',\n}\n\nconst profileToSchemaMap: Record<LoTEProfile, z.ZodType> = {\n [LoTEProfile.EUPIDProvidersList]: EUPIDProvidersListSchema,\n [LoTEProfile.EUWalletProvidersList]: EUWalletProvidersListSchema,\n [LoTEProfile.EUWRPACProvidersList]: EUWRPACProvidersListSchema,\n [LoTEProfile.EUWRPRCProvidersList]: EUWRPRCProvidersListSchema,\n [LoTEProfile.EUEAAProvidersList]: EUEAAProvidersListSchema,\n [LoTEProfile.EUPubEAAProvidersList]: EUPubEAAProvidersListSchema,\n [LoTEProfile.mDLProvidersList]: mDLProvidersListSchema,\n}\n\n/**\n * Validate a LoTE document against one or more given profiles. Validation\n * succeeds if the document matches one of the specified profiles\n *\n * @param loteDocument - The LoTE document to validate\n * @param profile - The profile(s) to validate against\n * @returns Validation result with errors if invalid\n */\nexport function validateLoTEProfile(loteDocument: unknown, profile: LoTEProfile | LoTEProfile[]): ValidationResult {\n const profiles = Array.isArray(profile) ? profile : [profile]\n const schema = z.union(profiles.map((p) => profileToSchemaMap[p]))\n const result = schema.safeParse(loteDocument)\n\n if (result.success) {\n return { valid: true, errors: [] }\n }\n\n return {\n valid: false,\n errors: [\n {\n path: 'LoTEType',\n message: `Document does not match any of the specified profiles: ${profiles.join(', ')}`,\n },\n ...result.error.issues.flatMap((issue) => {\n if (issue.code === 'invalid_union') {\n // `issue.errors` holds one array of issues per union branch, in the same order as `profiles`\n return issue.errors.flatMap((branchIssues, index) =>\n branchIssues.map((branchIssue) => ({\n path: branchIssue.path.join('.'),\n message: `Profile ${profiles[index]}: ${branchIssue.message}`,\n }))\n )\n }\n\n return [{ path: issue.path.join('.'), message: issue.message }]\n }),\n ],\n }\n}\n"],"mappings":";;;;;;;AAKA,IAAa,gBAAb,MAAa,sBAAsB,kBAAkB;CACnD,YAAY,SAAiB,SAAmB;EAC9C,MAAM,SAAS,OAAO;EACtB,OAAO,eAAe,MAAM,cAAc,SAAS;EACnD,KAAK,OAAO;CACd;AACF;;;;;;;;;;;ACIA,MAAa,wBAAwBA,IAAE,OAAO;CAC5C,MAAMA,IAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACtB,OAAOA,IAAE,OAAO,CAAC,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,MAAa,qBAAqBA,IAAE,OAAO;CACzC,MAAMA,IAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACtB,UAAUA,IAAE,IAAI;AAClB,CAAC;AAMD,MAAa,sBAAsBA,IAAE,OAAO;CAC1C,MAAMA,IAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACtB,eAAeA,IAAE,OAAO;CACxB,UAAUA,IAAE,OAAO;CACnB,iBAAiBA,IAAE,OAAO,CAAC,CAAC,SAAS;CACrC,YAAYA,IAAE,OAAO;CACrB,SAASA,IAAE,OAAO,CAAC,CAAC,OAAO,CAAC;AAC9B,CAAC;AAED,MAAa,8BAA8BA,IAAE,OAAO;CAClD,6BAA6BA,IAAE,MAAM,mBAAmB;CACxD,iCAAiCA,IAAE,MAAM,kBAAkB;AAC7D,CAAC;AAED,MAAa,6BAA6BA,IAAE,OAAO;CACjD,iBAAiBA,IAAE,MAAM,mBAAmB;CAC5C,qBAAqBA,IAAE,MAAM,kBAAkB;AACjD,CAAC;AAMD,MAAa,kBAAkBA,IAAE,OAAO;CACtC,UAAUA,IAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,SAASA,IAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,KAAKA,IAAE,OAAO,CAAC,CAAC,IAAI,CAAC;AACvB,CAAC;AAED,MAAa,2BAA2B,gBAAgB,OAAO;CAC7D,UAAUA,IAAE,QAAQ,oCAAoC,CAAC,CAAC,SAAS;CACnE,SAASA,IAAE,QAAQ,SAAS,CAAC,CAAC,SAAS;AACzC,CAAC;AAED,MAAa,qBAAqBA,IAAE,YAAY;CAC9C,KAAKA,IAAE,KAAK;EAAC;EAAO;EAAM;CAAK,CAAC;CAChC,KAAKA,IAAE,OAAO,CAAC,CAAC,SAAS;CACzB,KAAKA,IAAE,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,SAAS;CACrC,KAAKA,IAAE,OAAO,CAAC,CAAC,SAAS;AAC3B,CAAC;AAED,MAAa,+BAA+BA,IACzC,OAAO;CACN,kBAAkBA,IAAE,MAAM,wBAAwB,CAAC,CAAC,SAAS;CAC7D,kBAAkBA,IAAE,MAAMA,IAAE,OAAO,CAAC,CAAC,CAAC,SAAS;CAC/C,iBAAiBA,IAAE,MAAM,kBAAkB,CAAC,CAAC,SAAS;CACtD,UAAUA,IAAE,MAAMA,IAAE,OAAO,CAAC,CAAC,CAAC,SAAS;CACvC,UAAUA,IAAE,MAAMA,IAAE,OAAO,CAAC,CAAC,CAAC,SAAS;AACzC,CAAC,CAAC,CACD,QACE,OACE,GAAG,oBAAoB,GAAG,iBAAiB,SAAS,KACpD,GAAG,oBAAoB,GAAG,iBAAiB,SAAS,KACpD,GAAG,mBAAmB,GAAG,gBAAgB,SAAS,KAClD,GAAG,YAAY,GAAG,SAAS,SAAS,KACpC,GAAG,YAAY,GAAG,SAAS,SAAS,GACvC,EAAE,SAAS,sDAAsD,CACnE;AAMF,MAAa,2BAA2BA,IAAE,OAAO;CAC/C,aAAaA,IAAE,OAAO;CACtB,UAAUA,IAAE,IAAI;AAClB,CAAC;AAED,MAAa,2BAA2BA,IAAE,OAAO;CAC/C,aAAaA,IAAE,MAAM,qBAAqB,CAAC,CAAC,IAAI,CAAC;CACjD,wBAAwB;CACxB,uBAAuBA,IAAE,IAAI,CAAC,CAAC,SAAS;CACxC,eAAeA,IAAE,IAAI,CAAC,CAAC,SAAS;CAChC,oBAAoBA,IAAE,IAAI,SAAS,CAAC,CAAC,SAAS;CAC9C,4BAA4BA,IAAE,MAAM,kBAAkB,CAAC,CAAC,SAAS;CACjE,qBAAqBA,IAAE,MAAM,wBAAwB,CAAC,CAAC,SAAS;CAChE,sBAAsBA,IAAE,MAAM,kBAAkB,CAAC,CAAC,SAAS;CAC3D,8BAA8BA,IAAE,MAAMA,IAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;AAC9D,CAAC;AAED,MAAa,+BAA+BA,IAAE,OAAO;CACnD,aAAaA,IAAE,MAAM,qBAAqB,CAAC,CAAC,IAAI,CAAC;CACjD,wBAAwB;CACxB,eAAeA,IAAE,IAAI;CACrB,oBAAoBA,IAAE,IAAI,SAAS;CACnC,uBAAuBA,IAAE,IAAI,CAAC,CAAC,SAAS;CACxC,8BAA8BA,IAAE,MAAMA,IAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;AAC9D,CAAC;AAED,MAAa,6BAA6BA,IAAE,OAAO;CACjD,oBAAoB;CACpB,gBAAgBA,IAAE,MAAM,4BAA4B,CAAC,CAAC,SAAS;AACjE,CAAC;AAMD,MAAa,iCAAiCA,IAAE,OAAO;CACrD,QAAQA,IAAE,MAAM,qBAAqB,CAAC,CAAC,IAAI,CAAC;CAC5C,aAAaA,IAAE,MAAM,qBAAqB,CAAC,CAAC,SAAS;CACrD,WAAW;CACX,kBAAkBA,IAAE,MAAM,kBAAkB,CAAC,CAAC,SAAS;CACvD,yBAAyBA,IAAE,MAAMA,IAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;AACzD,CAAC;AAED,MAAa,sBAAsBA,IAAE,OAAO;CAC1C,0BAA0B;CAC1B,uBAAuBA,IAAE,MAAM,0BAA0B,CAAC,CAAC,IAAI,CAAC;AAClE,CAAC;AAMD,MAAa,4BAA4BA,IAAE,OAAO;CAChD,YAAY,mBAAmB,SAAS;CACxC,iBAAiB,sBAAsB,SAAS;AAClD,CAAC;AAED,MAAa,sBAAsBA,IAAE,OAAO;CAC1C,UAAUA,IAAE,IAAI;CAChB,oBAAoBA,IAAE,MAAM,qBAAqB,CAAC,CAAC,IAAI,CAAC;CACxD,0BAA0BA,IAAE,MAAM,kBAAkB,CAAC,CAAC,SAAS;CAC/D,iBAAiBA,IAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;CAC/C,UAAUA,IAAE,OAAO,CAAC,CAAC,IAAI,CAAC;AAC5B,CAAC;AAED,MAAa,yBAAyBA,IAAE,OAAO;CAC7C,cAAcA,IAAE,IAAI;CACpB,0BAA0BA,IAAE,MAAM,4BAA4B,CAAC,CAAC,IAAI,CAAC;CACrE,gBAAgBA,IAAE,MAAM,mBAAmB,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC;AAED,MAAa,iCAAiCA,IAAE,OAAO;CACrD,uBAAuBA,IAAE,OAAO,CAAC,CAAC,IAAI;CACtC,oBAAoBA,IAAE,OAAO,CAAC,CAAC,IAAI;CACnC,UAAUA,IAAE,IAAI,CAAC,CAAC,SAAS;CAC3B,oBAAoBA,IAAE,MAAM,qBAAqB,CAAC,CAAC,IAAI,CAAC;CACxD,uBAAuB,4BAA4B,SAAS;CAC5D,YAAYA,IAAE,MAAM,qBAAqB,CAAC,CAAC,SAAS;CACpD,sBAAsBA,IAAE,MAAM,kBAAkB,CAAC,CAAC,SAAS;CAC3D,6BAA6BA,IAAE,IAAI,CAAC,CAAC,SAAS;CAC9C,0BAA0BA,IAAE,MAAM,kBAAkB,CAAC,CAAC,SAAS;CAC/D,iBAAiBA,IAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;CAC/C,qBAAqBA,IAAE,MAAM,yBAAyB,CAAC,CAAC,SAAS;CACjE,6BAA6BA,IAAE,OAAO,CAAC,CAAC,SAAS;CACjD,qBAAqBA,IAAE,MAAM,sBAAsB,CAAC,CAAC,SAAS;CAC9D,mBAAmBA,IAAE,IAAI,SAAS;CAClC,YAAYA,IAAE,IAAI,SAAS;CAC3B,oBAAoBA,IAAE,MAAMA,IAAE,IAAI,CAAC,CAAC,CAAC,SAAS;CAC9C,kBAAkBA,IAAE,MAAMA,IAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;AAClD,CAAC;AAMD,MAAa,aAAaA,IAAE,OAAO;CACjC,0BAA0B;CAC1B,qBAAqBA,IAAE,MAAM,mBAAmB;AAClD,CAAC;AAED,MAAa,qBAAqBA,IAAE,OAAO,EACzC,MAAM,WACR,CAAC;;;;;;ACnLD,IAAa,uBAAb,MAAkC;;cACkB,CAAC;kBACR,CAAC;;;;;CAK5C,KAAK,OAAe,OAAO,MAAY;EACrC,KAAK,KAAK,SAAS,KAAK,KAAK,UAAU,CAAC;EACxC,KAAK,KAAK,OAAO,KAAK;GAAE;GAAM;EAAM,CAAC;EACrC,OAAO;CACT;;;;CAKA,UAAU,OAAe,OAAO,MAAY;EAC1C,KAAK,KAAK,cAAc,KAAK,KAAK,eAAe,CAAC;EAClD,KAAK,KAAK,YAAY,KAAK;GAAE;GAAM;EAAM,CAAC;EAC1C,OAAO;CACT;;;;CAKA,cAAc,SAAsC,OAAO,MAAY;EACrE,KAAK,KAAK,YAAY,KAAK,KAAK,aAAa;GAC3C,iBAAiB,CAAC;GAClB,qBAAqB,CAAC;EACxB;EACA,KAAK,KAAK,UAAU,gBAAgB,KAAK;GAAE,GAAG;GAAS;EAAK,CAAC;EAC7D,OAAO;CACT;;;;CAKA,MAAM,OAAe,OAAO,MAAY;EACtC,KAAK,KAAK,YAAY,KAAK,KAAK,aAAa;GAC3C,iBAAiB,CAAC;GAClB,qBAAqB,CAAC;EACxB;EACA,KAAK,KAAK,UAAU,oBAAoB,KAAK;GAC3C;GACA,UAAU,MAAM,WAAW,SAAS,IAAI,QAAQ,UAAU;EAC5D,CAAC;EACD,OAAO;CACT;;;;CAKA,QAAQ,KAAa,OAAO,MAAY;EACtC,KAAK,KAAK,mBAAmB,KAAK,KAAK,oBAAoB,CAAC;EAC5D,KAAK,KAAK,iBAAiB,KAAK;GAAE;GAAM,UAAU;EAAI,CAAC;EACvD,OAAO;CACT;;;;CAKA,QAAQ,KAAa,OAAO,MAAY;EACtC,KAAK,KAAK,YAAY,KAAK,KAAK,aAAa;GAC3C,iBAAiB,CAAC;GAClB,qBAAqB,CAAC;EACxB;EACA,KAAK,KAAK,UAAU,oBAAoB,KAAK;GAC3C;GACA,UAAU,IAAI,WAAW,MAAM,IAAI,MAAM,WAAW;EACtD,CAAC;EACD,OAAO;CACT;;;;CAKA,aAAa,WAA0B;EACrC,KAAK,KAAK,0BAA0B,KAAK,KAAK,2BAA2B,CAAC;EAC1E,KAAK,KAAK,wBAAwB,KAAK,SAAS;EAChD,OAAO;CACT;;;;CAKA,WAAW,SAAqC;EAC9C,KAAK,SAAS,KAAK,OAAO;EAC1B,OAAO;CACT;;;;CAKA,QAAuB;EACrB,MAAM,SAAS,oBAAoB,UAAU;GAC3C,0BAA0B,KAAK;GAC/B,uBAAuB,KAAK;EAC9B,CAAC;EAED,IAAI,CAAC,OAAO,SAEV,MAAM,IAAI,cAAc,2BADP,OAAO,MAAM,OAAO,KAAK,MAAM,GAAG,EAAE,KAAK,KAAK,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,KAAK,IAChC,GAAG;EAG/D,OAAO,OAAO;CAChB;AACF;;;;AAKA,IAAa,iBAAb,MAA4B;;cACkB,CAAC;iBACD,CAAC;;;;;CAK7C,KAAK,OAAe,OAAO,MAAY;EACrC,KAAK,KAAK,cAAc,KAAK,KAAK,eAAe,CAAC;EAClD,KAAK,KAAK,YAAY,KAAK;GAAE;GAAM;EAAM,CAAC;EAC1C,OAAO;CACT;;;;CAKA,KAAK,SAAuB;EAC1B,KAAK,KAAK,wBAAwB;EAClC,OAAO;CACT;;;;CAKA,OAAO,WAAmB,cAA2B;EACnD,KAAK,KAAK,gBAAgB;EAC1B,KAAK,KAAK,qBAAqB,cAAc,YAAY,sBAAK,IAAI,KAAK,EAAA,CAAE,YAAY;EACrF,OAAO;CACT;;;;CAKA,eAAe,YAA0B;EACvC,KAAK,KAAK,yBAAyB,KAAK,KAAK,0BAA0B,CAAC;EACxE,KAAK,KAAK,uBAAuB,mBAAmB,KAAK,KAAK,uBAAuB,oBAAoB,CAAC;EAC1G,KAAK,KAAK,uBAAuB,iBAAiB,KAAK;GACrD,UAAU;GACV,SAAS;GACT,KAAK;EACP,CAAC;EACD,OAAO;CACT;;;;CAKA,mBAAmB,aAA2B;EAC5C,KAAK,KAAK,yBAAyB,KAAK,KAAK,0BAA0B,CAAC;EACxE,KAAK,KAAK,uBAAuB,mBAAmB,KAAK,KAAK,uBAAuB,oBAAoB,CAAC;EAC1G,KAAK,KAAK,uBAAuB,iBAAiB,KAAK,WAAW;EAClE,OAAO;CACT;;;;CAKA,WAAW,KAAmB;EAC5B,KAAK,KAAK,yBAAyB,KAAK,KAAK,0BAA0B,CAAC;EACxE,KAAK,KAAK,uBAAuB,WAAW,KAAK,KAAK,uBAAuB,YAAY,CAAC;EAC1F,KAAK,KAAK,uBAAuB,SAAS,KAAK,GAAG;EAClD,OAAO;CACT;;;;CAKA,WAAW,IAAkB;EAC3B,KAAK,KAAK,yBAAyB,KAAK,KAAK,0BAA0B,CAAC;EACxE,KAAK,KAAK,uBAAuB,WAAW,KAAK,KAAK,uBAAuB,YAAY,CAAC;EAC1F,KAAK,KAAK,uBAAuB,SAAS,KAAK,EAAE;EACjD,OAAO;CACT;;;;CAKA,aAAa,KAAyB;EACpC,KAAK,KAAK,yBAAyB,KAAK,KAAK,0BAA0B,CAAC;EACxE,KAAK,KAAK,uBAAuB,kBAAkB,KAAK,KAAK,uBAAuB,mBAAmB,CAAC;EACxG,KAAK,KAAK,uBAAuB,gBAAgB,KAAK,GAAG;EACzD,OAAO;CACT;;;;CAKA,YAAY,MAAc,KAAmB;EAC3C,KAAK,KAAK,sBAAsB,KAAK,KAAK,uBAAuB,CAAC;EAClE,KAAK,KAAK,oBAAoB,KAAK;GAAE,aAAa;GAAM,UAAU;EAAI,CAAC;EACvE,OAAO;CACT;;;;CAKA,iBAAiB,KAAa,OAAO,MAAY;EAC/C,KAAK,KAAK,uBAAuB,KAAK,KAAK,wBAAwB,CAAC;EACpE,KAAK,KAAK,qBAAqB,KAAK;GAAE;GAAM,UAAU;EAAI,CAAC;EAC3D,OAAO;CACT;;;;CAKA,aAAa,WAA0B;EACrC,KAAK,KAAK,+BAA+B,KAAK,KAAK,gCAAgC,CAAC;EACpF,KAAK,KAAK,6BAA6B,KAAK,SAAS;EACrD,OAAO;CACT;;;;CAKA,gBAAgB,iBAA+C;EAC7D,KAAK,QAAQ,KAAK,eAAe;EACjC,OAAO;CACT;;;;CAKA,QAA8B;EAC5B,MAAM,OAAgC,EACpC,oBAAoB,KAAK,KAC3B;EAEA,IAAI,KAAK,QAAQ,SAAS,GACxB,KAAK,iBAAiB,KAAK;EAG7B,MAAM,SAAS,2BAA2B,UAAU,IAAI;EAExD,IAAI,CAAC,OAAO,SAEV,MAAM,IAAI,cAAc,kCADP,OAAO,MAAM,OAAO,KAAK,MAAM,GAAG,EAAE,KAAK,KAAK,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,KAAK,IACzB,GAAG;EAGtE,OAAO,OAAO;CAChB;AACF;;;;AAKA,SAAgB,gBAAsC;CACpD,OAAO,IAAI,qBAAqB;AAClC;;;;AAKA,SAAgB,UAA0B;CACxC,OAAO,IAAI,eAAe;AAC5B;;;AC7QA,MAAM,mBAAmB,OAAc,KAAK,KAAK;AAajD,MAAM,sCACH,EACC,UACA,uBACA,6BACA,iBACA,6BACA,6BACA,sCACA,oCAED,EAAE,QAAsB,QAAuC;CAC9D,MAAM,OAAO,KAAK;CAClB,MAAM,OAAO,CAAC,QAAQ,0BAA0B;CAEhD,IAAI,KAAK,aAAa,UACpB,IAAI,SAAS;EACX,MAAM;EACN,QAAQ,CAAC,QAAQ;EACjB,SAAS,oBAAoB;EAC7B,MAAM,CAAC,GAAG,MAAM,UAAU;CAC5B,CAAC;CAGH,IAAI,KAAK,0BAA0B,uBACjC,IAAI,SAAS;EACX,MAAM;EACN,QAAQ,CAAC,qBAAqB;EAC9B,SAAS,iCAAiC;EAC1C,MAAM,CAAC,GAAG,MAAM,uBAAuB;CACzC,CAAC;CAGH,IAAI,KAAK,gCAAgC,6BACvC,IAAI,SAAS;EACX,MAAM;EACN,QAAQ,CAAC,2BAA2B;EACpC,SAAS,uCAAuC;EAChD,MAAM,CAAC,GAAG,MAAM,6BAA6B;CAC/C,CAAC;CAGH,IAAI,KAAK,oBAAoB,iBAC3B,IAAI,SAAS;EACX,MAAM;EACN,QAAQ,CAAC,eAAe;EACxB,SAAS,2BAA2B;EACpC,MAAM,CAAC,GAAG,MAAM,iBAAiB;CACnC,CAAC;CAGH,IACE,CAAC,KAAK,4BACN,KAAK,yBAAyB,WAAW,KACzC,KAAK,yBAAyB,EAAE,CAAC,aAAa,6BAE9C,IAAI,SAAS;EACX,MAAM;EACN,SAAS,2EAA2E;EACpF,MAAM,CAAC,GAAG,MAAM,0BAA0B;CAC5C,CAAC;CAGH,IAAI,wCAAwC,OAAO,KAAK,gCAAgC,aACtF,IAAI,SAAS;EACX,MAAM;EACN,UAAU;EACV,SAAS;EACT,MAAM,CAAC,GAAG,MAAM,6BAA6B;CAC/C,CAAC;CAGH,IAAI,gCAAgC,KAAA,KAAa,KAAK,gCAAgC,6BACpF,IAAI,SAAS;EACX,MAAM;EACN,QAAQ,CAAC,2BAA2B;EACpC,SAAS,uCAAuC;EAChD,MAAM,CAAC,GAAG,MAAM,6BAA6B;CAC/C,CAAC;CAGH,IAAI,gCAAgC,OAAO,KAAK,wBAAwB,aACtE,IAAI,SAAS;EACX,MAAM;EACN,UAAU;EACV,SAAS;EACT,MAAM,CAAC,GAAG,MAAM,qBAAqB;CACvC,CAAC;CAGH,MAAM,oBAAoB,IAAI,KAAK,KAAK,iBAAiB,CAAC,CAAC,QAAQ;CAGnE,IAFmB,IAAI,KAAK,KAAK,UAAU,CAAC,CAAC,QAEhC,IAAI,oBAAoB,kBACnC,IAAI,SAAS;EACX,MAAM;EACN,SAAS;EACT,MAAM,CAAC,GAAG,MAAM,YAAY;CAC9B,CAAC;AAEL;AAOF,MAAM,iCACH,EAAE,+BAA+B,4BACjC,EAAE,QAAsB,QAAuC;CAC9D,KAAK,oBAAoB,SAAS,QAAQ,UAAU;EAClD,MAAM,oBAAoB;GAAC;GAAQ;GAAuB,MAAM,SAAS;EAAC;EAE1E,IAAI,sBAAsB;GACxB,MAAM,MAAM,OAAO,yBAAyB,kBAAkB,MAAM,EAAE,eACpE,SAAS,WAAW,oBAAoB,CAC1C;GAEA,IAAI,CAAC,KACH,IAAI,SAAS;IACX,MAAM;IACN,SAAS,8FAA8F;IACvG,MAAM;KAAC,GAAG;KAAmB;KAA4B;IAAkB;GAC7E,CAAC;QAGD,IADa,IAAI,SAAS,UAAU,qBAAqB,MAClD,CAAC,CAAC,WAAW,GAClB,IAAI,SAAS;IACX,MAAM;IACN,SAAS,qBAAqB,qBAAqB;IACnD,MAAM;KAAC,GAAG;KAAmB;KAA4B;IAAkB;GAC7E,CAAC;EAGP;EAEA,OAAO,sBAAsB,SAAS,SAAS,iBAAiB;GAC9D,MAAM,oBAAoB;IAAC,GAAG;IAAmB;IAAyB,aAAa,SAAS;GAAC;GAEjG,IAAI,OAAO,QAAQ,mBAAmB,kBAAkB,aACtD,IAAI,SAAS;IACX,MAAM;IACN,UAAU;IACV,SAAS;IACT,MAAM;KAAC,GAAG;KAAmB;KAAsB;IAAe;GACpE,CAAC;GAGH,IAAI,OAAO,QAAQ,mBAAmB,uBAAuB,aAC3D,IAAI,SAAS;IACX,MAAM;IACN,UAAU;IACV,SAAS;IACT,MAAM;KAAC,GAAG;KAAmB;KAAsB;IAAoB;GACzE,CAAC;GAGH,IACE,CAAC,QAAQ,mBAAmB,yBAC5B,CAAC,8BAA8B,SAAS,QAAQ,mBAAmB,qBAAqB,GAExF,IAAI,SAAS;IACX,MAAM;IACN,SAAS,uDAAuD,8BAA8B,KAAK,IAAI;IACvG,MAAM;KAAC,GAAG;KAAmB;KAAsB;IAAuB;IAC1E,QAAQ;GACV,CAAC;EAEL,CAAC;CACH,CAAC;AACH;AAGF,MAAa,2BAA2B,mBAAmB,YACzD,mCAAmC;CACjC,UAAU;CACV,uBAAuB;CACvB,6BAA6B;CAC7B,iBAAiB;CACjB,6BAA6B;CAC7B,sCAAsC;AACxC,CAAC,CACH,CAAC,CAAC,YACA,8BAA8B;CAC5B,+BAA+B,CAC7B,kDACA,kDACF;CACA,sBAAsB;AACxB,CAAC,CACH;AAGA,MAAa,8BAA8B,mBAAmB,YAC5D,mCAAmC;CACjC,UAAU;CACV,uBAAuB;CACvB,6BAA6B;CAC7B,iBAAiB;CACjB,6BAA6B;CAC7B,sCAAsC;AACxC,CAAC,CACH,CAAC,CAAC,YACA,8BAA8B;CAC5B,+BAA+B,CAC7B,6DACA,6DACF;CACA,sBAAsB;AACxB,CAAC,CACH;AAGA,MAAa,6BAA6B,mBAAmB,YAC3D,mCAAmC;CACjC,UAAU;CACV,uBAAuB;CACvB,6BAA6B;CAC7B,iBAAiB;CACjB,6BAA6B;CAC7B,sCAAsC;AACxC,CAAC,CACH,CAAC,CAAC,YACA,8BAA8B;CAC5B,+BAA+B,CAC7B,oDACA,oDACF;CACA,sBAAsB;AACxB,CAAC,CACH;AAGA,MAAa,6BAA6B,mBAAmB,YAC3D,mCAAmC;CACjC,UAAU;CACV,uBAAuB;CACvB,6BAA6B;CAC7B,iBAAiB;CACjB,6BAA6B;CAC7B,sCAAsC;AACxC,CAAC,CACH,CAAC,CAAC,YACA,8BAA8B;CAC5B,+BAA+B,CAC7B,oDACA,oDACF;CACA,sBAAsB;AACxB,CAAC,CACH;AAEA,MAAa,2BAA2B,mBAAmB,YACzD,mCAAmC;CACjC,UAAU;CACV,uBAAuB;CACvB,6BAA6B;CAC7B,iBAAiB;CACjB,6BAA6B;CAC7B,8BAA8B;AAChC,CAAC,CACH,CAAC,CAAC,YACA,8BAA8B;CAC5B,+BAA+B,CAC7B,kDACA,kDACF;CACA,sBAAsB;AACxB,CAAC,CACH;AAGA,MAAa,8BAA8B,mBAAmB,YAC5D,mCAAmC;CACjC,UAAU;CACV,uBAAuB;CACvB,6BAA6B;CAC7B,iBAAiB;CACjB,6BAA6B;CAC7B,8BAA8B;CAC9B,6BAA6B;AAC/B,CAAC,CACH,CAAC,CAAC,YACA,8BAA8B;CAC5B,+BAA+B,CAC7B,qDACA,qDACF;CACA,sBAAsB;AACxB,CAAC,CACH;AAGA,MAAa,yBAAyB,mBAAmB,YACvD,mCAAmC;CACjC,UAAU;CACV,uBAAuB;CACvB,6BAA6B;CAC7B,iBAAiB;CACjB,6BAA6B;AAC/B,CAAC,CACH,CAAC,CAAC,YACA,8BAA8B,EAC5B,+BAA+B,CAC7B,wDACA,wDACF,EACF,CAAC,CACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3SA,eAAsB,SAAS,SAA2C;CACxE,MAAM,EAAE,MAAM,OAAO,YAAY,SAAS,cAAc,WAAW;CAEnE,MAAM,SAAkC;EACtC,KAAK;EACL,KAAK;EACL,KAAK;CACP;CAEA,IAAI,gBAAgB,aAAa,SAAS,GACxC,OAAO,MAAM,aAAa,IAAI,gBAAgB;CAKhD,MAAM,eAAe,GAFC,gBAAgB,KAAK,UAAU,MAAM,CAEvB,EAAE,GADf,gBAAgB,KAAK,UAAU,IAAI,CACJ;CAKtD,OAAO;EACL,KAAA,GAHa,aAAa,GAAG,MADP,OAAO,YAAY;EAKzC,QAAQ;GACN,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK,OAAO;EACd;EACA,SAAS;CACX;AACF;;;;;;AAOA,SAAgB,WACd,YACA,WAA4B,CAAC,GACf;CACd,MAAM,sBAAM,IAAI,KAAK;CACrB,MAAM,iBAAiB,IAAI,KAAK,GAAG;CACnC,eAAe,SAAS,eAAe,SAAS,IAAI,CAAC;CAyBrD,OAAO,EAAE,MAAM;EAtBb,0BAA0B;GACxB,uBAAuB,WAAW,yBAAyB;GAC3D,oBAAoB,WAAW,sBAAsB;GACrD,UAAU,WAAW;GACrB,oBAAoB,WAAW;GAC/B,uBAAuB,WAAW;GAClC,YAAY,WAAW;GACvB,sBAAsB,WAAW;GACjC,6BAA6B,WAAW;GACxC,0BAA0B,WAAW;GACrC,iBAAiB,WAAW;GAC5B,qBAAqB,WAAW;GAChC,6BAA6B,WAAW;GACxC,qBAAqB,WAAW;GAChC,mBAAmB,WAAW,qBAAqB,IAAI,YAAY;GACnE,YAAY,WAAW,cAAc,eAAe,YAAY;GAChE,oBAAoB,WAAW;GAC/B,kBAAkB,WAAW;EAC/B;EACA,qBAAqB;CAGL,EAAE;AACtB;;;;;;;;;;;;;;;;;;;;;AAwCA,SAAgB,kBAAkB,MAAoB,UAAoC,CAAC,GAAiB;CAC1G,MAAM,YAAY,QAAQ,oBACtB,OAAO,QAAQ,sBAAsB,WACnC,IAAI,KAAK,QAAQ,iBAAiB,IAClC,QAAQ,oCACV,IAAI,KAAK;CAEb,MAAM,oBAAoB,IAAI,KAAK,SAAS;CAC5C,kBAAkB,SAAS,kBAAkB,SAAS,IAAI,CAAC;CAE3D,MAAM,iBAAiB,QAAQ,aAC3B,OAAO,QAAQ,eAAe,WAC5B,QAAQ,aACR,QAAQ,WAAW,YAAY,IACjC,kBAAkB,YAAY;CAElC,OAAO,EACL,MAAM;EACJ,GAAG,KAAK;EACR,0BAA0B;GACxB,GAAG,KAAK,KAAK;GACb,oBAAoB,KAAK,KAAK,yBAAyB,qBAAqB;GAC5E,mBAAmB,UAAU,YAAY;GACzC,YAAY;EACd;CACF,EACF;AACF;;;;AAKA,SAAgB,iBAAiB,MAAoB,QAAqC;CACxF,OAAO,EACL,MAAM;EACJ,GAAG,KAAK;EACR,qBAAqB,CAAC,GAAG,KAAK,KAAK,qBAAqB,MAAM;CAChE,EACF;AACF;;;;AAKA,SAAgB,oBAAoB,MAAoB,YAAkC;CACxF,OAAO,EACL,MAAM;EACJ,GAAG,KAAK;EACR,qBAAqB,KAAK,KAAK,oBAAoB,QAChD,MAAM,CAAC,EAAE,yBAAyB,OAAO,MAAM,MAAM,EAAE,UAAU,UAAU,CAC9E;CACF,EACF;AACF;;;;;;;;;;;;;;;;;;;;;;AC7IA,SAAgB,aAAa,cAAyC;CACpE,MAAM,SAAS,mBAAmB,UAAU,YAAY;CAExD,IAAI,OAAO,SACT,OAAO;EAAE,OAAO;EAAM,QAAQ,CAAC;CAAE;CAQnC,OAAO;EAAE,OAAO;EAAO,QALW,OAAO,MAAM,OAAO,KAAK,WAAW;GACpE,MAAM,MAAM,KAAK,KAAK,GAAG;GACzB,SAAS,MAAM;EACjB,EAE4B;CAAE;AAChC;;;;;;;AAQA,SAAgB,gBAAgB,cAA6D;CAC3F,MAAM,SAAS,aAAa,YAAY;CACxC,IAAI,CAAC,OAAO,OAEV,MAAM,IAAI,cAAc,2BADF,OAAO,OAAO,KAAK,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,SAAS,CAAC,CAAC,KAAK,IAChB,GAAG;AAEtE;;;;AAKA,IAAY,cAAL,yBAAA,aAAA;CACL,YAAA,wBAAA;CACA,YAAA,2BAAA;CACA,YAAA,0BAAA;CACA,YAAA,0BAAA;CACA,YAAA,wBAAA;CACA,YAAA,2BAAA;CACA,YAAA,sBAAA;;AACF,EAAA,CAAA,CAAA;AAEA,MAAM,qBAAqD;yBACvB;4BACG;2BACD;2BACA;yBACF;4BACG;uBACL;AAClC;;;;;;;;;AAUA,SAAgB,oBAAoB,cAAuB,SAAwD;CACjH,MAAM,WAAW,MAAM,QAAQ,OAAO,IAAI,UAAU,CAAC,OAAO;CAE5D,MAAM,SADS,EAAE,MAAM,SAAS,KAAK,MAAM,mBAAmB,EAAE,CAC5C,CAAC,CAAC,UAAU,YAAY;CAE5C,IAAI,OAAO,SACT,OAAO;EAAE,OAAO;EAAM,QAAQ,CAAC;CAAE;CAGnC,OAAO;EACL,OAAO;EACP,QAAQ,CACN;GACE,MAAM;GACN,SAAS,0DAA0D,SAAS,KAAK,IAAI;EACvF,GACA,GAAG,OAAO,MAAM,OAAO,SAAS,UAAU;GACxC,IAAI,MAAM,SAAS,iBAEjB,OAAO,MAAM,OAAO,SAAS,cAAc,UACzC,aAAa,KAAK,iBAAiB;IACjC,MAAM,YAAY,KAAK,KAAK,GAAG;IAC/B,SAAS,WAAW,SAAS,OAAO,IAAI,YAAY;GACtD,EAAE,CACJ;GAGF,OAAO,CAAC;IAAE,MAAM,MAAM,KAAK,KAAK,GAAG;IAAG,SAAS,MAAM;GAAQ,CAAC;EAChE,CAAC,CACH;CACF;AACF"}
1
+ {"version":3,"file":"index.mjs","names":["z"],"sources":["../src/lote-exception.ts","../src/schemas.ts","../src/builders.ts","../src/profiles.ts","../src/signer.ts","../src/validator.ts"],"sourcesContent":["import { IdentityException } from '@owf/identity-common'\n\n/**\n * LoTEException is a custom error class for LoTE-related exceptions.\n */\nexport class LoTEException extends IdentityException {\n constructor(message: string, details?: unknown) {\n super(message, details)\n Object.setPrototypeOf(this, LoTEException.prototype)\n this.name = 'LoTEException'\n }\n}\n","/**\n * LoTE Zod Schemas\n *\n * Zod schemas for ETSI TS 119 602 (LoTE - List of Trusted Entities) format.\n * Types are derived from these schemas via z.infer<>.\n *\n * @see https://www.etsi.org/deliver/etsi_ts/119600_119699/119602/01.01.01_60/ts_119602v010101p.pdf\n */\n\nimport { z } from 'zod'\n\n// ============================================================================\n// Localized Value Schemas\n// ============================================================================\n\nexport const LocalizedStringSchema = z.object({\n lang: z.string().min(1),\n value: z.string().min(1),\n})\n\nexport const LocalizedURISchema = z.object({\n lang: z.string().min(1),\n uriValue: z.url(),\n})\n\n// ============================================================================\n// Address Schemas\n// ============================================================================\n\nexport const PostalAddressSchema = z.object({\n lang: z.string().min(1),\n StreetAddress: z.string(),\n Locality: z.string(),\n StateOrProvince: z.string().optional(),\n PostalCode: z.string(),\n Country: z.string().length(2),\n})\n\nexport const SchemeOperatorAddressSchema = z.object({\n SchemeOperatorPostalAddress: z.array(PostalAddressSchema),\n SchemeOperatorElectronicAddress: z.array(LocalizedURISchema),\n})\n\nexport const TrustedEntityAddressSchema = z.object({\n TEPostalAddress: z.array(PostalAddressSchema),\n TEElectronicAddress: z.array(LocalizedURISchema),\n})\n\n// ============================================================================\n// Digital Identity Schemas\n// ============================================================================\n\nexport const PkiObjectSchema = z.object({\n encoding: z.string().optional(),\n specRef: z.string().optional(),\n val: z.string().min(1),\n})\n\nexport const X509CertificateRefSchema = PkiObjectSchema.extend({\n encoding: z.literal('urn:ietf:params:tls-cert-type:x509').optional(),\n specRef: z.literal('RFC5280').optional(),\n})\n\nexport const JWKPublicKeySchema = z.looseObject({\n kty: z.enum(['RSA', 'EC', 'OKP']),\n kid: z.string().optional(),\n use: z.enum(['sig', 'enc']).optional(),\n alg: z.string().optional(),\n})\n\nexport const ServiceDigitalIdentitySchema = z\n .object({\n X509Certificates: z.array(X509CertificateRefSchema).optional(),\n X509SubjectNames: z.array(z.string()).optional(),\n PublicKeyValues: z.array(JWKPublicKeySchema).optional(),\n X509SKIs: z.array(z.string()).optional(),\n OtherIds: z.array(z.string()).optional(),\n })\n .refine(\n (id) =>\n (id.X509Certificates && id.X509Certificates.length > 0) ||\n (id.X509SubjectNames && id.X509SubjectNames.length > 0) ||\n (id.PublicKeyValues && id.PublicKeyValues.length > 0) ||\n (id.X509SKIs && id.X509SKIs.length > 0) ||\n (id.OtherIds && id.OtherIds.length > 0),\n { message: 'At least one digital identity type must be provided' }\n )\n\n// ============================================================================\n// Service Schemas\n// ============================================================================\n\nexport const ServiceSupplyPointSchema = z.object({\n ServiceType: z.string(),\n uriValue: z.url(),\n})\n\nexport const ServiceInformationSchema = z.object({\n ServiceName: z.array(LocalizedStringSchema).min(1),\n ServiceDigitalIdentity: ServiceDigitalIdentitySchema,\n ServiceTypeIdentifier: z.url().optional(),\n ServiceStatus: z.url().optional(),\n StatusStartingTime: z.iso.datetime().optional(),\n SchemeServiceDefinitionURI: z.array(LocalizedURISchema).optional(),\n ServiceSupplyPoints: z.array(ServiceSupplyPointSchema).optional(),\n ServiceDefinitionURI: z.array(LocalizedURISchema).optional(),\n ServiceInformationExtensions: z.array(z.unknown()).optional(),\n})\n\nexport const ServiceHistoryInstanceSchema = z.object({\n ServiceName: z.array(LocalizedStringSchema).min(1),\n ServiceDigitalIdentity: ServiceDigitalIdentitySchema,\n ServiceStatus: z.url(),\n StatusStartingTime: z.iso.datetime(),\n ServiceTypeIdentifier: z.url().optional(),\n ServiceInformationExtensions: z.array(z.unknown()).optional(),\n})\n\nexport const TrustedEntityServiceSchema = z.object({\n ServiceInformation: ServiceInformationSchema,\n ServiceHistory: z.array(ServiceHistoryInstanceSchema).optional(),\n})\n\n// ============================================================================\n// Trusted Entity Schemas\n// ============================================================================\n\nexport const TrustedEntityInformationSchema = z.object({\n TEName: z.array(LocalizedStringSchema).min(1),\n TETradeName: z.array(LocalizedStringSchema).optional(),\n TEAddress: TrustedEntityAddressSchema,\n TEInformationURI: z.array(LocalizedURISchema).optional(),\n TEInformationExtensions: z.array(z.unknown()).optional(),\n})\n\nexport const TrustedEntitySchema = z.object({\n TrustedEntityInformation: TrustedEntityInformationSchema,\n TrustedEntityServices: z.array(TrustedEntityServiceSchema).min(1),\n})\n\n// ============================================================================\n// List and Scheme Information Schemas\n// ============================================================================\n\nexport const PolicyOrLegalNoticeSchema = z.object({\n LoTEPolicy: LocalizedURISchema.optional(),\n LoTELegalNotice: LocalizedStringSchema.optional(),\n})\n\nexport const LoTEQualifierSchema = z.object({\n LoTEType: z.url(),\n SchemeOperatorName: z.array(LocalizedStringSchema).min(1),\n SchemeTypeCommunityRules: z.array(LocalizedURISchema).optional(),\n SchemeTerritory: z.string().length(2).optional(),\n MimeType: z.string().min(1),\n})\n\nexport const OtherLoTEPointerSchema = z.object({\n LoTELocation: z.url(),\n ServiceDigitalIdentities: z.array(ServiceDigitalIdentitySchema).min(1),\n LoTEQualifiers: z.array(LoTEQualifierSchema).min(1),\n})\n\nexport const ListAndSchemeInformationSchema = z.object({\n LoTEVersionIdentifier: z.number().int(),\n LoTESequenceNumber: z.number().int(),\n LoTEType: z.url().optional(),\n SchemeOperatorName: z.array(LocalizedStringSchema).min(1),\n SchemeOperatorAddress: SchemeOperatorAddressSchema.optional(),\n SchemeName: z.array(LocalizedStringSchema).optional(),\n SchemeInformationURI: z.array(LocalizedURISchema).optional(),\n StatusDeterminationApproach: z.url().optional(),\n SchemeTypeCommunityRules: z.array(LocalizedURISchema).optional(),\n SchemeTerritory: z.string().length(2).optional(),\n PolicyOrLegalNotice: z.array(PolicyOrLegalNoticeSchema).optional(),\n HistoricalInformationPeriod: z.number().optional(),\n PointersToOtherLoTE: z.array(OtherLoTEPointerSchema).optional(),\n ListIssueDateTime: z.iso.datetime(),\n NextUpdate: z.iso.datetime(),\n DistributionPoints: z.array(z.url()).optional(),\n SchemeExtensions: z.array(z.unknown()).optional(),\n})\n\n// ============================================================================\n// LoTE Root Schemas\n// ============================================================================\n\nexport const LoTESchema = z.object({\n ListAndSchemeInformation: ListAndSchemeInformationSchema,\n TrustedEntitiesList: z.array(TrustedEntitySchema),\n})\n\nexport const LoTEDocumentSchema = z.object({\n LoTE: LoTESchema,\n})\n","import { LoTEException } from './lote-exception'\nimport { TrustedEntitySchema, TrustedEntityServiceSchema } from './schemas'\nimport type {\n JWKPublicKey,\n PostalAddress,\n ServiceHistoryInstance,\n ServiceInformation,\n TrustedEntity,\n TrustedEntityInformation,\n TrustedEntityService,\n} from './types'\n\n/**\n * Builder for creating TrustedEntity objects with a fluent API\n */\nexport class TrustedEntityBuilder {\n private info: Partial<TrustedEntityInformation> = {}\n private services: TrustedEntityService[] = []\n\n /**\n * Set the entity name\n */\n name(value: string, lang = 'en'): this {\n this.info.TEName = this.info.TEName ?? []\n this.info.TEName.push({ lang, value })\n return this\n }\n\n /**\n * Set the trade name\n */\n tradeName(value: string, lang = 'en'): this {\n this.info.TETradeName = this.info.TETradeName ?? []\n this.info.TETradeName.push({ lang, value })\n return this\n }\n\n /**\n * Set the postal address\n */\n postalAddress(address: Omit<PostalAddress, 'lang'>, lang = 'en'): this {\n this.info.TEAddress = this.info.TEAddress ?? {\n TEPostalAddress: [],\n TEElectronicAddress: [],\n }\n this.info.TEAddress.TEPostalAddress.push({ ...address, lang })\n return this\n }\n\n /**\n * Add an electronic address (email)\n */\n email(email: string, lang = 'en'): this {\n this.info.TEAddress = this.info.TEAddress ?? {\n TEPostalAddress: [],\n TEElectronicAddress: [],\n }\n this.info.TEAddress.TEElectronicAddress.push({\n lang,\n uriValue: email.startsWith('mailto:') ? email : `mailto:${email}`,\n })\n return this\n }\n\n /**\n * Add an information URI\n */\n infoUri(uri: string, lang = 'en'): this {\n this.info.TEInformationURI = this.info.TEInformationURI ?? []\n this.info.TEInformationURI.push({ lang, uriValue: uri })\n return this\n }\n\n /**\n * Add a website URL as an electronic address\n */\n website(url: string, lang = 'en'): this {\n this.info.TEAddress = this.info.TEAddress ?? {\n TEPostalAddress: [],\n TEElectronicAddress: [],\n }\n this.info.TEAddress.TEElectronicAddress.push({\n lang,\n uriValue: url.startsWith('http') ? url : `https://${url}`,\n })\n return this\n }\n\n /**\n * Add custom extensions\n */\n addExtension(extension: unknown): this {\n this.info.TEInformationExtensions = this.info.TEInformationExtensions ?? []\n this.info.TEInformationExtensions.push(extension)\n return this\n }\n\n /**\n * Add a service to the entity\n */\n addService(service: TrustedEntityService): this {\n this.services.push(service)\n return this\n }\n\n /**\n * Build the TrustedEntity object\n */\n build(): TrustedEntity {\n const result = TrustedEntitySchema.safeParse({\n TrustedEntityInformation: this.info,\n TrustedEntityServices: this.services,\n })\n\n if (!result.success) {\n const messages = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('\\n')\n throw new LoTEException(`Invalid TrustedEntity:\\n${messages}`)\n }\n\n return result.data\n }\n}\n\n/**\n * Builder for creating TrustedEntityService objects\n */\nexport class ServiceBuilder {\n private info: Partial<ServiceInformation> = {}\n private history: ServiceHistoryInstance[] = []\n\n /**\n * Set the service name\n */\n name(value: string, lang = 'en'): this {\n this.info.ServiceName = this.info.ServiceName ?? []\n this.info.ServiceName.push({ lang, value })\n return this\n }\n\n /**\n * Set the service type identifier\n */\n type(typeUri: string): this {\n this.info.ServiceTypeIdentifier = typeUri\n return this\n }\n\n /**\n * Set the service status\n */\n status(statusUri: string, startingTime?: Date): this {\n this.info.ServiceStatus = statusUri\n this.info.StatusStartingTime = startingTime?.toISOString() ?? new Date().toISOString()\n return this\n }\n\n /**\n * Add an X.509 certificate to the digital identity\n */\n addCertificate(certBase64: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.X509Certificates = this.info.ServiceDigitalIdentity.X509Certificates ?? []\n this.info.ServiceDigitalIdentity.X509Certificates.push({\n encoding: 'urn:ietf:params:tls-cert-type:x509',\n specRef: 'RFC5280',\n val: certBase64,\n })\n return this\n }\n\n /**\n * Add an X.509 subject name (DN format) to the digital identity\n */\n addX509SubjectName(subjectName: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.X509SubjectNames = this.info.ServiceDigitalIdentity.X509SubjectNames ?? []\n this.info.ServiceDigitalIdentity.X509SubjectNames.push(subjectName)\n return this\n }\n\n /**\n * Add an X.509 Subject Key Identifier (base64-encoded) to the digital identity\n */\n addX509SKI(ski: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.X509SKIs = this.info.ServiceDigitalIdentity.X509SKIs ?? []\n this.info.ServiceDigitalIdentity.X509SKIs.push(ski)\n return this\n }\n\n /**\n * Add another identifier to the digital identity\n */\n addOtherId(id: string): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.OtherIds = this.info.ServiceDigitalIdentity.OtherIds ?? []\n this.info.ServiceDigitalIdentity.OtherIds.push(id)\n return this\n }\n\n /**\n * Add a public key (JWK) to the digital identity\n */\n addPublicKey(jwk: JWKPublicKey): this {\n this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {}\n this.info.ServiceDigitalIdentity.PublicKeyValues = this.info.ServiceDigitalIdentity.PublicKeyValues ?? []\n this.info.ServiceDigitalIdentity.PublicKeyValues.push(jwk)\n return this\n }\n\n /**\n * Add a service endpoint\n */\n addEndpoint(type: string, uri: string): this {\n this.info.ServiceSupplyPoints = this.info.ServiceSupplyPoints ?? []\n this.info.ServiceSupplyPoints.push({ ServiceType: type, uriValue: uri })\n return this\n }\n\n /**\n * Add a service definition URI\n */\n addDefinitionUri(uri: string, lang = 'en'): this {\n this.info.ServiceDefinitionURI = this.info.ServiceDefinitionURI ?? []\n this.info.ServiceDefinitionURI.push({ lang, uriValue: uri })\n return this\n }\n\n /**\n * Add custom service information extensions\n */\n addExtension(extension: unknown): this {\n this.info.ServiceInformationExtensions = this.info.ServiceInformationExtensions ?? []\n this.info.ServiceInformationExtensions.push(extension)\n return this\n }\n\n /**\n * Add a historical service instance\n */\n addHistoryEntry(historyInstance: ServiceHistoryInstance): this {\n this.history.push(historyInstance)\n return this\n }\n\n /**\n * Build the TrustedEntityService object\n */\n build(): TrustedEntityService {\n const data: Record<string, unknown> = {\n ServiceInformation: this.info,\n }\n\n if (this.history.length > 0) {\n data.ServiceHistory = this.history\n }\n\n const result = TrustedEntityServiceSchema.safeParse(data)\n\n if (!result.success) {\n const messages = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('\\n')\n throw new LoTEException(`Invalid TrustedEntityService:\\n${messages}`)\n }\n\n return result.data\n }\n}\n\n/**\n * Create a new TrustedEntityBuilder\n */\nexport function trustedEntity(): TrustedEntityBuilder {\n return new TrustedEntityBuilder()\n}\n\n/**\n * Create a new ServiceBuilder\n */\nexport function service(): ServiceBuilder {\n return new ServiceBuilder()\n}\n","/**\n * LoTE Profiles\n *\n * @see https://www.etsi.org/deliver/etsi_ts/119600_119699/119602/01.01.01_60/ts_119602v010101p.pdf\n * @see https://acceptance.eidas.ec.europa.eu/efda/wallet/lists-of-trusted-entities/mdl-providers\n */\n\nimport type z from 'zod'\nimport { LoTEDocumentSchema } from './schemas'\nimport type { LoTEDocument } from './types'\n\nconst SIX_MONTHS_IN_MS = 6 * 31 * 24 * 60 * 60 * 1000\n\nexport const LOTE_TYPES = {\n EUPIDProvidersList: 'http://uri.etsi.org/19602/LoTEType/EUPIDProvidersList',\n EUWalletProvidersList: 'http://uri.etsi.org/19602/LoTEType/EUWalletProvidersList',\n EUWRPACProvidersList: 'http://uri.etsi.org/19602/LoTEType/EUWRPACProvidersList',\n EUWRPRCProvidersList: 'http://uri.etsi.org/19602/LoTEType/EUWRPRCProvidersList',\n EUEAAProvidersList: 'http://uri.etsi.org/19602/LoTEType/EUEAAProvidersList',\n EUPubEAAProvidersList: 'http://uri.etsi.org/19602/LoTEType/EUPubEAAProvidersList',\n mDLProvidersList: 'http://trust.ec.europa.eu/lists/mDL/mDLProvidersListType',\n} as const\n\ntype ListAndSchemeInformationRefinementOptions = {\n loTEType: string\n loTEVersionIdentifier: number\n statusDeterminationApproach: string\n schemeTerritory: string\n schemeTypeCommunityRulesUri: string\n historicalInformationPeriod?: number\n requireNoHistoricalInformationPeriod?: boolean\n requireNoPointersToOtherLoTE?: boolean\n}\n\nconst listAndSchemeInformationRefinement =\n ({\n loTEType,\n loTEVersionIdentifier,\n statusDeterminationApproach,\n schemeTerritory,\n schemeTypeCommunityRulesUri,\n historicalInformationPeriod,\n requireNoHistoricalInformationPeriod,\n requireNoPointersToOtherLoTE,\n }: ListAndSchemeInformationRefinementOptions) =>\n ({ LoTE }: LoTEDocument, ctx: z.RefinementCtx<LoTEDocument>) => {\n const info = LoTE.ListAndSchemeInformation\n const path = ['LoTE', 'ListAndSchemeInformation']\n\n if (info.LoTEType !== loTEType) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [loTEType],\n message: `LoTEType must be ${loTEType}`,\n path: [...path, 'LoTEType'],\n })\n }\n\n if (info.LoTEVersionIdentifier !== loTEVersionIdentifier) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [loTEVersionIdentifier],\n message: `LoTEVersionIdentifier must be ${loTEVersionIdentifier}`,\n path: [...path, 'LoTEVersionIdentifier'],\n })\n }\n\n if (info.StatusDeterminationApproach !== statusDeterminationApproach) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [statusDeterminationApproach],\n message: `StatusDeterminationApproach must be ${statusDeterminationApproach}`,\n path: [...path, 'StatusDeterminationApproach'],\n })\n }\n\n if (info.SchemeTerritory !== schemeTerritory) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [schemeTerritory],\n message: `SchemeTerritory must be ${schemeTerritory}`,\n path: [...path, 'SchemeTerritory'],\n })\n }\n\n if (\n !info.SchemeTypeCommunityRules ||\n info.SchemeTypeCommunityRules.length !== 1 ||\n info.SchemeTypeCommunityRules[0].uriValue !== schemeTypeCommunityRulesUri\n ) {\n ctx.addIssue({\n code: 'custom',\n message: `SchemeTypeCommunityRules must contain a single element with uriValue of ${schemeTypeCommunityRulesUri}`,\n path: [...path, 'SchemeTypeCommunityRules'],\n })\n }\n\n if (requireNoHistoricalInformationPeriod && typeof info.HistoricalInformationPeriod !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'HistoricalInformationPeriod must not be present',\n path: [...path, 'HistoricalInformationPeriod'],\n })\n }\n\n if (historicalInformationPeriod !== undefined && info.HistoricalInformationPeriod !== historicalInformationPeriod) {\n ctx.addIssue({\n code: 'invalid_value',\n values: [historicalInformationPeriod],\n message: `HistoricalInformationPeriod must be ${historicalInformationPeriod}`,\n path: [...path, 'HistoricalInformationPeriod'],\n })\n }\n\n if (requireNoPointersToOtherLoTE && typeof info.PointersToOtherLoTE !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'PointersToOtherLoTE must not be present',\n path: [...path, 'PointersToOtherLoTE'],\n })\n }\n\n const listIssueDateTime = new Date(info.ListIssueDateTime).getTime()\n const nextUpdate = new Date(info.NextUpdate).getTime()\n\n if (nextUpdate - listIssueDateTime > SIX_MONTHS_IN_MS) {\n ctx.addIssue({\n code: 'custom',\n message: 'NextUpdate must be within 6 months of ListIssueDateTime',\n path: [...path, 'NextUpdate'],\n })\n }\n }\n\ntype TrustedEntitiesListRefinementOptions = {\n allowedServiceTypeIdentifiers: string[]\n informationUriPrefix?: string\n}\n\nconst trustedEntitiesListRefinement =\n ({ allowedServiceTypeIdentifiers, informationUriPrefix }: TrustedEntitiesListRefinementOptions) =>\n ({ LoTE }: LoTEDocument, ctx: z.RefinementCtx<LoTEDocument>) => {\n LoTE.TrustedEntitiesList.forEach((entity, index) => {\n const trustedEntityPath = ['LoTE', 'TrustedEntitiesList', index.toString()]\n\n if (informationUriPrefix) {\n const uri = entity.TrustedEntityInformation.TEInformationURI?.find(({ uriValue }) =>\n uriValue.startsWith(informationUriPrefix)\n )\n\n if (!uri) {\n ctx.addIssue({\n code: 'custom',\n message: `Each TrustedEntityInformation.TEInformationURI must contain at least one URI starting with ${informationUriPrefix}`,\n path: [...trustedEntityPath, 'TrustedEntityInformation', 'TEInformationURI'],\n })\n } else {\n const rest = uri.uriValue.substring(informationUriPrefix.length)\n if (rest.length !== 2) {\n ctx.addIssue({\n code: 'custom',\n message: `URI starting with ${informationUriPrefix} must be followed by a 2-letter country code`,\n path: [...trustedEntityPath, 'TrustedEntityInformation', 'TEInformationURI'],\n })\n }\n }\n }\n\n entity.TrustedEntityServices.forEach((service, serviceIndex) => {\n const entityServicePath = [...trustedEntityPath, 'TrustedEntityServices', serviceIndex.toString()]\n\n if (typeof service.ServiceInformation.ServiceStatus !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'ServiceStatus must not be present',\n path: [...entityServicePath, 'ServiceInformation', 'ServiceStatus'],\n })\n }\n\n if (typeof service.ServiceInformation.StatusStartingTime !== 'undefined') {\n ctx.addIssue({\n code: 'invalid_type',\n expected: 'undefined',\n message: 'StatusStartingTime must not be present',\n path: [...entityServicePath, 'ServiceInformation', 'StatusStartingTime'],\n })\n }\n\n if (\n !service.ServiceInformation.ServiceTypeIdentifier ||\n !allowedServiceTypeIdentifiers.includes(service.ServiceInformation.ServiceTypeIdentifier)\n ) {\n ctx.addIssue({\n code: 'invalid_value',\n message: `ServiceTypeIdentifier must be one of the following: ${allowedServiceTypeIdentifiers.join(', ')}`,\n path: [...entityServicePath, 'ServiceInformation', 'ServiceTypeIdentifier'],\n values: allowedServiceTypeIdentifiers,\n })\n }\n })\n })\n }\n\n// ETSI TS 119 602 D\nexport const EUPIDProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: LOTE_TYPES.EUPIDProvidersList,\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/PIDProvidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/PIDProviders/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/PID/Issuance',\n 'http://uri.etsi.org/19602/SvcType/PID/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/PIDProvider/',\n })\n)\n\n// ETSI TS 119 602 E\nexport const EUWalletProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: LOTE_TYPES.EUWalletProvidersList,\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/WalletProvidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/WalletProvidersList/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/WalletSolution/Issuance',\n 'http://uri.etsi.org/19602/SvcType/WalletSolution/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/WalletProvider/',\n })\n)\n\n// ETSI TS 119 602 F\nexport const EUWRPACProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: LOTE_TYPES.EUWRPACProvidersList,\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/WRPACProvidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/WRPACProvidersList/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/WRPAC/Issuance',\n 'http://uri.etsi.org/19602/SvcType/WRPAC/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/WRPACProvider/',\n })\n)\n\n// ETSI TS 119 602 G\nexport const EUWRPRCProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: LOTE_TYPES.EUWRPRCProvidersList,\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/WRPRCrovidersList/StatusDetn/EU',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/WRPRCProvidersList/schemerules/EU',\n requireNoHistoricalInformationPeriod: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/WRPRC/Issuance',\n 'http://uri.etsi.org/19602/SvcType/WRPRC/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/WRPRCProvider/',\n })\n)\n\nexport const EUEAAProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: LOTE_TYPES.EUEAAProvidersList,\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/EAAProvidersList/StatusDetn/EU\"',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/EAAProvidersList/schemerules/EU',\n requireNoPointersToOtherLoTE: true,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/EAA/Issuance',\n 'http://uri.etsi.org/19602/SvcType/EAA/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/EAAProvider/',\n })\n)\n\n// ETSI TS 119 602 H\nexport const EUPubEAAProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: LOTE_TYPES.EUPubEAAProvidersList,\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://uri.etsi.org/19602/PubEAAProvidersList/StatusDetn/EU\"',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://uri.etsi.org/19602/PubEAAProvidersList/schemerules/EU',\n requireNoPointersToOtherLoTE: true,\n historicalInformationPeriod: 65535,\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://uri.etsi.org/19602/SvcType/PubEAA/Issuance',\n 'http://uri.etsi.org/19602/SvcType/PubEAA/Revocation',\n ],\n informationUriPrefix: 'http://uri.etsi.org/19602/ListOfTrustedEntities/PubEAAProvider/',\n })\n)\n\n// mDL Providers List\nexport const mDLProvidersListSchema = LoTEDocumentSchema.superRefine(\n listAndSchemeInformationRefinement({\n loTEType: LOTE_TYPES.mDLProvidersList,\n loTEVersionIdentifier: 1,\n statusDeterminationApproach: 'http://trust.ec.europa.eu/lists/mDL/mDLProvidersListStatusDetn',\n schemeTerritory: 'EU',\n schemeTypeCommunityRulesUri: 'http://trust.ec.europa.eu/lists/mDL/schemerules',\n })\n).superRefine(\n trustedEntitiesListRefinement({\n allowedServiceTypeIdentifiers: [\n 'http://trust.ec.europa.eu/lists/mDL/SvcType/Issuance',\n 'http://trust.ec.europa.eu/lists/mDL/SvcType/Revocation',\n ],\n })\n)\n","import { parseCertificate } from '@owf/crypto'\nimport { base64urlEncode } from '@owf/identity-common'\nimport type { ListAndSchemeInformation, LoTE, LoTEDocument, SignedLoTE, SignOptions, TrustedEntity } from './types'\n\n/**\n * Sign a LoTE document\n *\n * @param options - Signing options including LoTE document, key ID, and signer function\n * @returns The signed LoTE document as a JWS\n *\n * @example Using a local key via @owf/crypto:\n * ```typescript\n * import { ES256 } from '@owf/crypto';\n * import { signLoTE } from '@owf/eudi-lote';\n *\n * const { privateKey } = await ES256.generateKeyPair();\n * const signer = await ES256.getSigner(privateKey);\n * const signed = await signLoTE({\n * lote: myLoTE,\n * keyId: 'lote-signer-2025',\n * signer,\n * });\n * ```\n *\n * @example Using an external KMS:\n * ```typescript\n * const signed = await signLoTE({\n * lote: myLoTE,\n * keyId: 'lote-signer-2025',\n * signer: async (data) => myKms.sign('ES256', data),\n * });\n * ```\n */\nexport async function signLoTE(options: SignOptions): Promise<SignedLoTE> {\n const { lote, keyId, algorithm = 'ES256', certificates, signer } = options\n\n const header: Record<string, unknown> = {\n alg: algorithm,\n typ: 'trustlist+jwt',\n kid: keyId,\n }\n\n if (certificates && certificates.length > 0) {\n header.x5c = certificates.map(parseCertificate)\n }\n\n const encodedHeader = base64urlEncode(JSON.stringify(header))\n const encodedPayload = base64urlEncode(JSON.stringify(lote))\n const signingInput = `${encodedHeader}.${encodedPayload}`\n\n const signature = await signer(signingInput)\n const jws = `${signingInput}.${signature}`\n\n return {\n jws,\n header: {\n alg: algorithm,\n typ: 'trustlist+jwt',\n kid: keyId,\n x5c: header.x5c as string[] | undefined,\n },\n payload: lote,\n }\n}\n\n/**\n * Create a new LoTE document with required structure\n * Per ETSI TS 119 602, only SchemeOperatorName, ListIssueDateTime and NextUpdate are required\n * Default NextUpdate is 6 months per ETSI TS 119 602 maximum validity\n */\nexport function createLoTE(\n schemeInfo: Partial<ListAndSchemeInformation> & Pick<ListAndSchemeInformation, 'SchemeOperatorName'>,\n entities: TrustedEntity[] = []\n): LoTEDocument {\n const now = new Date()\n const sixMonthsLater = new Date(now)\n sixMonthsLater.setMonth(sixMonthsLater.getMonth() + 6)\n\n const lote: LoTE = {\n ListAndSchemeInformation: {\n LoTEVersionIdentifier: schemeInfo.LoTEVersionIdentifier ?? 1,\n LoTESequenceNumber: schemeInfo.LoTESequenceNumber ?? 1,\n LoTEType: schemeInfo.LoTEType,\n SchemeOperatorName: schemeInfo.SchemeOperatorName,\n SchemeOperatorAddress: schemeInfo.SchemeOperatorAddress,\n SchemeName: schemeInfo.SchemeName,\n SchemeInformationURI: schemeInfo.SchemeInformationURI,\n StatusDeterminationApproach: schemeInfo.StatusDeterminationApproach,\n SchemeTypeCommunityRules: schemeInfo.SchemeTypeCommunityRules,\n SchemeTerritory: schemeInfo.SchemeTerritory,\n PolicyOrLegalNotice: schemeInfo.PolicyOrLegalNotice,\n HistoricalInformationPeriod: schemeInfo.HistoricalInformationPeriod,\n PointersToOtherLoTE: schemeInfo.PointersToOtherLoTE,\n ListIssueDateTime: schemeInfo.ListIssueDateTime ?? now.toISOString(),\n NextUpdate: schemeInfo.NextUpdate ?? sixMonthsLater.toISOString(),\n DistributionPoints: schemeInfo.DistributionPoints,\n SchemeExtensions: schemeInfo.SchemeExtensions,\n },\n TrustedEntitiesList: entities,\n }\n\n return { LoTE: lote }\n}\n\n/**\n * Options for updating a LoTE version\n */\nexport interface UpdateLoTEVersionOptions {\n /**\n * The issue date/time for the new version.\n * Useful when generating a LoTE in advance before publication.\n * Defaults to the current time.\n */\n listIssueDateTime?: Date | string\n /**\n * The next update date/time.\n * Per ETSI TS 119 602, maximum validity is 6 months.\n * Defaults to 6 months from listIssueDateTime.\n */\n nextUpdate?: Date | string\n}\n\n/**\n * Increment the sequence number and update timestamps for a new version\n *\n * @param lote - The LoTE document to update\n * @param options - Optional settings for listIssueDateTime and nextUpdate\n * @returns A new LoTE document with incremented sequence number and updated timestamps\n *\n * @example Update with defaults (now + 6 months):\n * ```typescript\n * const updated = updateLoTEVersion(lote);\n * ```\n *\n * @example Schedule for future publication:\n * ```typescript\n * const updated = updateLoTEVersion(lote, {\n * listIssueDateTime: new Date('2025-01-01'),\n * nextUpdate: new Date('2025-06-01'),\n * });\n * ```\n */\nexport function updateLoTEVersion(lote: LoTEDocument, options: UpdateLoTEVersionOptions = {}): LoTEDocument {\n const issueDate = options.listIssueDateTime\n ? typeof options.listIssueDateTime === 'string'\n ? new Date(options.listIssueDateTime)\n : options.listIssueDateTime\n : new Date()\n\n const defaultNextUpdate = new Date(issueDate)\n defaultNextUpdate.setMonth(defaultNextUpdate.getMonth() + 6)\n\n const nextUpdateDate = options.nextUpdate\n ? typeof options.nextUpdate === 'string'\n ? options.nextUpdate\n : options.nextUpdate.toISOString()\n : defaultNextUpdate.toISOString()\n\n return {\n LoTE: {\n ...lote.LoTE,\n ListAndSchemeInformation: {\n ...lote.LoTE.ListAndSchemeInformation,\n LoTESequenceNumber: lote.LoTE.ListAndSchemeInformation.LoTESequenceNumber + 1,\n ListIssueDateTime: issueDate.toISOString(),\n NextUpdate: nextUpdateDate,\n },\n },\n }\n}\n\n/**\n * Add a trusted entity to a LoTE document\n */\nexport function addTrustedEntity(lote: LoTEDocument, entity: TrustedEntity): LoTEDocument {\n return {\n LoTE: {\n ...lote.LoTE,\n TrustedEntitiesList: [...lote.LoTE.TrustedEntitiesList, entity],\n },\n }\n}\n\n/**\n * Remove a trusted entity from a LoTE document by name\n */\nexport function removeTrustedEntity(lote: LoTEDocument, entityName: string): LoTEDocument {\n return {\n LoTE: {\n ...lote.LoTE,\n TrustedEntitiesList: lote.LoTE.TrustedEntitiesList.filter(\n (e) => !e.TrustedEntityInformation.TEName.some((n) => n.value === entityName)\n ),\n },\n }\n}\n","/**\n * LoTE Validator\n *\n * Runtime validation for ETSI TS 119 602 LoTE documents using Zod schemas.\n */\n\nimport type z from 'zod'\nimport { LoTEException } from './lote-exception'\nimport {\n EUEAAProvidersListSchema,\n EUPIDProvidersListSchema,\n EUPubEAAProvidersListSchema,\n EUWalletProvidersListSchema,\n EUWRPACProvidersListSchema,\n EUWRPRCProvidersListSchema,\n LOTE_TYPES,\n mDLProvidersListSchema,\n} from './profiles'\nimport { LoTEDocumentSchema } from './schemas'\nimport type { LoTEDocument } from './types'\n\n/**\n * Validation error detail\n */\nexport interface ValidationError {\n /** Path to the invalid field */\n path: string\n /** Error message */\n message: string\n}\n\n/**\n * Validation result\n */\nexport interface ValidationResult {\n /** Whether the LoTE document is valid */\n valid: boolean\n /** List of validation errors (if invalid) */\n errors: ValidationError[]\n}\n\n/**\n * Validate a LoTE document against ETSI TS 119 602 schema\n *\n * @param loteDocument - The LoTE document to validate\n * @returns Validation result with errors if invalid\n *\n * @example\n * ```typescript\n * const result = validateLoTE(myLoTE);\n * if (!result.valid) {\n * console.error('Validation errors:', result.errors);\n * }\n * ```\n */\nexport function validateLoTE(loteDocument: unknown): ValidationResult {\n const result = LoTEDocumentSchema.safeParse(loteDocument)\n\n if (result.success) {\n return { valid: true, errors: [] }\n }\n\n const errors: ValidationError[] = result.error.issues.map((issue) => ({\n path: issue.path.join('.'),\n message: issue.message,\n }))\n\n return { valid: false, errors }\n}\n\n/**\n * Assert that a LoTE document is valid, throwing if not\n *\n * @param loteDocument - The LoTE document to validate\n * @throws Error if validation fails\n */\nexport function assertValidLoTE(loteDocument: unknown): asserts loteDocument is LoTEDocument {\n const result = validateLoTE(loteDocument)\n if (!result.valid) {\n const errorMessages = result.errors.map((e) => `${e.path}: ${e.message}`).join('\\n')\n throw new LoTEException(`Invalid LoTE document:\\n${errorMessages}`)\n }\n}\n\n/**\n * Supported LoTE profiles for validation\n */\nexport enum LoTEProfile {\n EUPIDProvidersList = 'EUPIDProvidersList',\n EUWalletProvidersList = 'EUWalletProvidersList',\n EUWRPACProvidersList = 'EUWRPACProvidersList',\n EUWRPRCProvidersList = 'EUWRPRCProvidersList',\n EUEAAProvidersList = 'EUEAAProvidersList',\n EUPubEAAProvidersList = 'EUPubEAAProvidersList',\n mDLProvidersList = 'mDLProvidersList',\n}\n\nconst profileConfig: Record<LoTEProfile, { loTEType: string; schema: z.ZodType }> = {\n [LoTEProfile.EUPIDProvidersList]: { loTEType: LOTE_TYPES.EUPIDProvidersList, schema: EUPIDProvidersListSchema },\n [LoTEProfile.EUWalletProvidersList]: {\n loTEType: LOTE_TYPES.EUWalletProvidersList,\n schema: EUWalletProvidersListSchema,\n },\n [LoTEProfile.EUWRPACProvidersList]: { loTEType: LOTE_TYPES.EUWRPACProvidersList, schema: EUWRPACProvidersListSchema },\n [LoTEProfile.EUWRPRCProvidersList]: { loTEType: LOTE_TYPES.EUWRPRCProvidersList, schema: EUWRPRCProvidersListSchema },\n [LoTEProfile.EUEAAProvidersList]: { loTEType: LOTE_TYPES.EUEAAProvidersList, schema: EUEAAProvidersListSchema },\n [LoTEProfile.EUPubEAAProvidersList]: {\n loTEType: LOTE_TYPES.EUPubEAAProvidersList,\n schema: EUPubEAAProvidersListSchema,\n },\n [LoTEProfile.mDLProvidersList]: { loTEType: LOTE_TYPES.mDLProvidersList, schema: mDLProvidersListSchema },\n}\n\nfunction getDocumentLoTEType(loteDocument: unknown): string | undefined {\n try {\n const type = (loteDocument as { LoTE?: { ListAndSchemeInformation?: { LoTEType?: unknown } } } | null | undefined)\n ?.LoTE?.ListAndSchemeInformation?.LoTEType\n return typeof type === 'string' ? type : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Validate a LoTE document against one or more given profiles. Validation\n * succeeds if the document matches one of the specified profiles\n *\n * @param loteDocument - The LoTE document to validate\n * @param profile - The profile(s) to validate against\n * @returns Validation result with errors if invalid\n */\nexport function validateLoTEProfile(loteDocument: unknown, profile: LoTEProfile | LoTEProfile[]): ValidationResult {\n const profiles = Array.isArray(profile) ? profile : [profile]\n const documentLoTEType = getDocumentLoTEType(loteDocument)\n\n // LoTEType is unique per profile, so at most one requested profile can match.\n const matchedProfile = profiles.find((p) => profileConfig[p].loTEType === documentLoTEType)\n\n if (matchedProfile) {\n const result = profileConfig[matchedProfile].schema.safeParse(loteDocument)\n\n if (result.success) {\n return { valid: true, errors: [] }\n }\n\n return {\n valid: false,\n errors: [\n { path: 'LoTEType', message: `Document does not match profile ${matchedProfile}` },\n ...result.error.issues.map((issue) => ({\n path: issue.path.join('.'),\n message: `Profile ${matchedProfile}: ${issue.message}`,\n })),\n ],\n }\n }\n\n // No requested profile matches the document's LoTEType.\n return {\n valid: false,\n errors: [\n {\n path: 'LoTEType',\n message: `Document does not match any of the specified profiles: ${profiles.join(', ')}`,\n },\n ...profiles.map((p) => ({\n path: 'LoTE.ListAndSchemeInformation.LoTEType',\n message: `Profile ${p}: LoTEType must be ${profileConfig[p].loTEType}`,\n })),\n ],\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owf/eudi-lote",
3
- "version": "0.3.2-alpha-20260713153517",
3
+ "version": "0.3.2",
4
4
  "description": "SDK for creating, signing, and validating Lists of Trusted Entities (LoTE) per ETSI TS 119 602",
5
5
  "files": [
6
6
  "dist"
@@ -39,8 +39,8 @@
39
39
  ],
40
40
  "dependencies": {
41
41
  "zod": "^4.4.3",
42
- "@owf/crypto": "0.3.2-alpha-20260713153517",
43
- "@owf/identity-common": "0.3.2-alpha-20260713153517"
42
+ "@owf/crypto": "0.3.2",
43
+ "@owf/identity-common": "0.3.2"
44
44
  },
45
45
  "devDependencies": {
46
46
  "vitest": "^4.1.10"