@owf/eudi-lote 0.0.0

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.mjs ADDED
@@ -0,0 +1,573 @@
1
+ import { IdentityException, base64urlEncode } from "@owf/identity-common";
2
+ import { z } from "zod";
3
+ import { parseCertificate } from "@owf/crypto";
4
+ //#region src/lote-exception.ts
5
+ /**
6
+ * LoTEException is a custom error class for LoTE-related exceptions.
7
+ */
8
+ var LoTEException = class LoTEException extends IdentityException {
9
+ constructor(message, details) {
10
+ super(message, details);
11
+ Object.setPrototypeOf(this, LoTEException.prototype);
12
+ this.name = "LoTEException";
13
+ }
14
+ };
15
+ //#endregion
16
+ //#region src/schemas.ts
17
+ /**
18
+ * LoTE Zod Schemas
19
+ *
20
+ * Zod schemas for ETSI TS 119 602 (LoTE - List of Trusted Entities) format.
21
+ * Types are derived from these schemas via z.infer<>.
22
+ *
23
+ * @see https://www.etsi.org/deliver/etsi_ts/119600_119699/119602/01.01.01_60/ts_119602v010101p.pdf
24
+ */
25
+ const LocalizedStringSchema = z.object({
26
+ lang: z.string().min(1),
27
+ value: z.string().min(1)
28
+ });
29
+ const LocalizedURISchema = z.object({
30
+ lang: z.string().min(1),
31
+ uriValue: z.string().url()
32
+ });
33
+ const PostalAddressSchema = z.object({
34
+ lang: z.string().min(1),
35
+ StreetAddress: z.string(),
36
+ Locality: z.string(),
37
+ StateOrProvince: z.string().optional(),
38
+ PostalCode: z.string(),
39
+ Country: z.string().length(2)
40
+ });
41
+ const SchemeOperatorAddressSchema = z.object({
42
+ SchemeOperatorPostalAddress: z.array(PostalAddressSchema),
43
+ SchemeOperatorElectronicAddress: z.array(LocalizedURISchema)
44
+ });
45
+ const TrustedEntityAddressSchema = z.object({
46
+ TEPostalAddress: z.array(PostalAddressSchema),
47
+ TEElectronicAddress: z.array(LocalizedURISchema)
48
+ });
49
+ const PkiObjectSchema = z.object({
50
+ encoding: z.string().optional(),
51
+ specRef: z.string().optional(),
52
+ val: z.string().min(1)
53
+ });
54
+ const X509CertificateRefSchema = PkiObjectSchema.extend({
55
+ encoding: z.literal("urn:ietf:params:tls-cert-type:x509").optional(),
56
+ specRef: z.literal("RFC5280").optional()
57
+ });
58
+ const JWKPublicKeySchema = z.object({
59
+ kty: z.enum([
60
+ "RSA",
61
+ "EC",
62
+ "OKP"
63
+ ]),
64
+ kid: z.string().optional(),
65
+ use: z.enum(["sig", "enc"]).optional(),
66
+ alg: z.string().optional()
67
+ }).passthrough();
68
+ const ServiceDigitalIdentitySchema = z.object({
69
+ X509Certificates: z.array(X509CertificateRefSchema).optional(),
70
+ X509SubjectNames: z.array(z.string()).optional(),
71
+ PublicKeyValues: z.array(JWKPublicKeySchema).optional(),
72
+ X509SKIs: z.array(z.string()).optional(),
73
+ OtherIds: z.array(z.string()).optional()
74
+ }).refine((id) => id.X509Certificates && id.X509Certificates.length > 0 || id.X509SubjectNames && id.X509SubjectNames.length > 0 || id.PublicKeyValues && id.PublicKeyValues.length > 0 || id.X509SKIs && id.X509SKIs.length > 0 || id.OtherIds && id.OtherIds.length > 0, { message: "At least one digital identity type must be provided" });
75
+ const ServiceSupplyPointSchema = z.object({
76
+ ServiceType: z.string(),
77
+ uriValue: z.string()
78
+ });
79
+ const ServiceInformationSchema = z.object({
80
+ ServiceName: z.array(LocalizedStringSchema).min(1),
81
+ ServiceDigitalIdentity: ServiceDigitalIdentitySchema,
82
+ ServiceTypeIdentifier: z.string().url().optional(),
83
+ ServiceStatus: z.string().url().optional(),
84
+ StatusStartingTime: z.string().datetime().optional(),
85
+ SchemeServiceDefinitionURI: z.array(LocalizedURISchema).optional(),
86
+ ServiceSupplyPoints: z.array(ServiceSupplyPointSchema).optional(),
87
+ ServiceDefinitionURI: z.array(LocalizedURISchema).optional(),
88
+ ServiceInformationExtensions: z.array(z.unknown()).optional()
89
+ });
90
+ const ServiceHistoryInstanceSchema = z.object({
91
+ ServiceName: z.array(LocalizedStringSchema).min(1),
92
+ ServiceDigitalIdentity: ServiceDigitalIdentitySchema,
93
+ ServiceStatus: z.string().url(),
94
+ StatusStartingTime: z.string().datetime(),
95
+ ServiceTypeIdentifier: z.string().url().optional(),
96
+ ServiceInformationExtensions: z.array(z.unknown()).optional()
97
+ });
98
+ const TrustedEntityServiceSchema = z.object({
99
+ ServiceInformation: ServiceInformationSchema,
100
+ ServiceHistory: z.array(ServiceHistoryInstanceSchema).optional()
101
+ });
102
+ const TrustedEntityInformationSchema = z.object({
103
+ TEName: z.array(LocalizedStringSchema).min(1),
104
+ TETradeName: z.array(LocalizedStringSchema).optional(),
105
+ TEAddress: TrustedEntityAddressSchema,
106
+ TEInformationURI: z.array(LocalizedURISchema).optional(),
107
+ TEInformationExtensions: z.array(z.unknown()).optional()
108
+ });
109
+ const TrustedEntitySchema = z.object({
110
+ TrustedEntityInformation: TrustedEntityInformationSchema,
111
+ TrustedEntityServices: z.array(TrustedEntityServiceSchema).min(1)
112
+ });
113
+ const PolicyOrLegalNoticeSchema = z.object({
114
+ LoTEPolicy: LocalizedURISchema.optional(),
115
+ LoTELegalNotice: LocalizedStringSchema.optional()
116
+ });
117
+ const LoTEQualifierSchema = z.object({
118
+ LoTEType: z.string().url(),
119
+ SchemeOperatorName: z.array(LocalizedStringSchema).min(1),
120
+ SchemeTypeCommunityRules: z.array(LocalizedURISchema).optional(),
121
+ SchemeTerritory: z.string().length(2).optional(),
122
+ MimeType: z.string().min(1)
123
+ });
124
+ const OtherLoTEPointerSchema = z.object({
125
+ LoTELocation: z.string().url(),
126
+ ServiceDigitalIdentities: z.array(ServiceDigitalIdentitySchema).min(1),
127
+ LoTEQualifiers: z.array(LoTEQualifierSchema).min(1)
128
+ });
129
+ const ListAndSchemeInformationSchema = z.object({
130
+ LoTEVersionIdentifier: z.number().int(),
131
+ LoTESequenceNumber: z.number().int(),
132
+ LoTEType: z.string().url().optional(),
133
+ SchemeOperatorName: z.array(LocalizedStringSchema).min(1),
134
+ SchemeOperatorAddress: SchemeOperatorAddressSchema.optional(),
135
+ SchemeName: z.array(LocalizedStringSchema).optional(),
136
+ SchemeInformationURI: z.array(LocalizedURISchema).optional(),
137
+ StatusDeterminationApproach: z.string().url().optional(),
138
+ SchemeTypeCommunityRules: z.array(LocalizedURISchema).optional(),
139
+ SchemeTerritory: z.string().length(2).optional(),
140
+ PolicyOrLegalNotice: z.array(PolicyOrLegalNoticeSchema).optional(),
141
+ HistoricalInformationPeriod: z.number().optional(),
142
+ PointersToOtherLoTE: z.array(OtherLoTEPointerSchema).optional(),
143
+ ListIssueDateTime: z.string().datetime(),
144
+ NextUpdate: z.string().datetime(),
145
+ DistributionPoints: z.array(z.string()).optional(),
146
+ SchemeExtensions: z.array(z.unknown()).optional()
147
+ });
148
+ const LoTESchema = z.object({
149
+ ListAndSchemeInformation: ListAndSchemeInformationSchema,
150
+ TrustedEntitiesList: z.array(TrustedEntitySchema)
151
+ });
152
+ const LoTEDocumentSchema = z.object({ LoTE: LoTESchema });
153
+ //#endregion
154
+ //#region src/builders.ts
155
+ /**
156
+ * Builder for creating TrustedEntity objects with a fluent API
157
+ */
158
+ var TrustedEntityBuilder = class {
159
+ constructor() {
160
+ this.info = {};
161
+ this.services = [];
162
+ }
163
+ /**
164
+ * Set the entity name
165
+ */
166
+ name(value, lang = "en") {
167
+ this.info.TEName = this.info.TEName ?? [];
168
+ this.info.TEName.push({
169
+ lang,
170
+ value
171
+ });
172
+ return this;
173
+ }
174
+ /**
175
+ * Set the trade name
176
+ */
177
+ tradeName(value, lang = "en") {
178
+ this.info.TETradeName = this.info.TETradeName ?? [];
179
+ this.info.TETradeName.push({
180
+ lang,
181
+ value
182
+ });
183
+ return this;
184
+ }
185
+ /**
186
+ * Set the postal address
187
+ */
188
+ postalAddress(address, lang = "en") {
189
+ this.info.TEAddress = this.info.TEAddress ?? {
190
+ TEPostalAddress: [],
191
+ TEElectronicAddress: []
192
+ };
193
+ this.info.TEAddress.TEPostalAddress.push({
194
+ ...address,
195
+ lang
196
+ });
197
+ return this;
198
+ }
199
+ /**
200
+ * Add an electronic address (email)
201
+ */
202
+ email(email, lang = "en") {
203
+ this.info.TEAddress = this.info.TEAddress ?? {
204
+ TEPostalAddress: [],
205
+ TEElectronicAddress: []
206
+ };
207
+ this.info.TEAddress.TEElectronicAddress.push({
208
+ lang,
209
+ uriValue: email.startsWith("mailto:") ? email : `mailto:${email}`
210
+ });
211
+ return this;
212
+ }
213
+ /**
214
+ * Add an information URI
215
+ */
216
+ infoUri(uri, lang = "en") {
217
+ this.info.TEInformationURI = this.info.TEInformationURI ?? [];
218
+ this.info.TEInformationURI.push({
219
+ lang,
220
+ uriValue: uri
221
+ });
222
+ return this;
223
+ }
224
+ /**
225
+ * Add a website URL as an electronic address
226
+ */
227
+ website(url, lang = "en") {
228
+ this.info.TEAddress = this.info.TEAddress ?? {
229
+ TEPostalAddress: [],
230
+ TEElectronicAddress: []
231
+ };
232
+ this.info.TEAddress.TEElectronicAddress.push({
233
+ lang,
234
+ uriValue: url.startsWith("http") ? url : `https://${url}`
235
+ });
236
+ return this;
237
+ }
238
+ /**
239
+ * Add custom extensions
240
+ */
241
+ addExtension(extension) {
242
+ this.info.TEInformationExtensions = this.info.TEInformationExtensions ?? [];
243
+ this.info.TEInformationExtensions.push(extension);
244
+ return this;
245
+ }
246
+ /**
247
+ * Add a service to the entity
248
+ */
249
+ addService(service) {
250
+ this.services.push(service);
251
+ return this;
252
+ }
253
+ /**
254
+ * Build the TrustedEntity object
255
+ */
256
+ build() {
257
+ const result = TrustedEntitySchema.safeParse({
258
+ TrustedEntityInformation: this.info,
259
+ TrustedEntityServices: this.services
260
+ });
261
+ if (!result.success) throw new LoTEException(`Invalid TrustedEntity:\n${result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("\n")}`);
262
+ return result.data;
263
+ }
264
+ };
265
+ /**
266
+ * Builder for creating TrustedEntityService objects
267
+ */
268
+ var ServiceBuilder = class {
269
+ constructor() {
270
+ this.info = {};
271
+ this.history = [];
272
+ }
273
+ /**
274
+ * Set the service name
275
+ */
276
+ name(value, lang = "en") {
277
+ this.info.ServiceName = this.info.ServiceName ?? [];
278
+ this.info.ServiceName.push({
279
+ lang,
280
+ value
281
+ });
282
+ return this;
283
+ }
284
+ /**
285
+ * Set the service type identifier
286
+ */
287
+ type(typeUri) {
288
+ this.info.ServiceTypeIdentifier = typeUri;
289
+ return this;
290
+ }
291
+ /**
292
+ * Set the service status
293
+ */
294
+ status(statusUri, startingTime) {
295
+ this.info.ServiceStatus = statusUri;
296
+ this.info.StatusStartingTime = startingTime?.toISOString() ?? (/* @__PURE__ */ new Date()).toISOString();
297
+ return this;
298
+ }
299
+ /**
300
+ * Add an X.509 certificate to the digital identity
301
+ */
302
+ addCertificate(certBase64) {
303
+ this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {};
304
+ this.info.ServiceDigitalIdentity.X509Certificates = this.info.ServiceDigitalIdentity.X509Certificates ?? [];
305
+ this.info.ServiceDigitalIdentity.X509Certificates.push({
306
+ encoding: "urn:ietf:params:tls-cert-type:x509",
307
+ specRef: "RFC5280",
308
+ val: certBase64
309
+ });
310
+ return this;
311
+ }
312
+ /**
313
+ * Add an X.509 subject name (DN format) to the digital identity
314
+ */
315
+ addX509SubjectName(subjectName) {
316
+ this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {};
317
+ this.info.ServiceDigitalIdentity.X509SubjectNames = this.info.ServiceDigitalIdentity.X509SubjectNames ?? [];
318
+ this.info.ServiceDigitalIdentity.X509SubjectNames.push(subjectName);
319
+ return this;
320
+ }
321
+ /**
322
+ * Add an X.509 Subject Key Identifier (base64-encoded) to the digital identity
323
+ */
324
+ addX509SKI(ski) {
325
+ this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {};
326
+ this.info.ServiceDigitalIdentity.X509SKIs = this.info.ServiceDigitalIdentity.X509SKIs ?? [];
327
+ this.info.ServiceDigitalIdentity.X509SKIs.push(ski);
328
+ return this;
329
+ }
330
+ /**
331
+ * Add another identifier to the digital identity
332
+ */
333
+ addOtherId(id) {
334
+ this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {};
335
+ this.info.ServiceDigitalIdentity.OtherIds = this.info.ServiceDigitalIdentity.OtherIds ?? [];
336
+ this.info.ServiceDigitalIdentity.OtherIds.push(id);
337
+ return this;
338
+ }
339
+ /**
340
+ * Add a public key (JWK) to the digital identity
341
+ */
342
+ addPublicKey(jwk) {
343
+ this.info.ServiceDigitalIdentity = this.info.ServiceDigitalIdentity ?? {};
344
+ this.info.ServiceDigitalIdentity.PublicKeyValues = this.info.ServiceDigitalIdentity.PublicKeyValues ?? [];
345
+ this.info.ServiceDigitalIdentity.PublicKeyValues.push(jwk);
346
+ return this;
347
+ }
348
+ /**
349
+ * Add a service endpoint
350
+ */
351
+ addEndpoint(type, uri) {
352
+ this.info.ServiceSupplyPoints = this.info.ServiceSupplyPoints ?? [];
353
+ this.info.ServiceSupplyPoints.push({
354
+ ServiceType: type,
355
+ uriValue: uri
356
+ });
357
+ return this;
358
+ }
359
+ /**
360
+ * Add a service definition URI
361
+ */
362
+ addDefinitionUri(uri, lang = "en") {
363
+ this.info.ServiceDefinitionURI = this.info.ServiceDefinitionURI ?? [];
364
+ this.info.ServiceDefinitionURI.push({
365
+ lang,
366
+ uriValue: uri
367
+ });
368
+ return this;
369
+ }
370
+ /**
371
+ * Add custom service information extensions
372
+ */
373
+ addExtension(extension) {
374
+ this.info.ServiceInformationExtensions = this.info.ServiceInformationExtensions ?? [];
375
+ this.info.ServiceInformationExtensions.push(extension);
376
+ return this;
377
+ }
378
+ /**
379
+ * Add a historical service instance
380
+ */
381
+ addHistoryEntry(historyInstance) {
382
+ this.history.push(historyInstance);
383
+ return this;
384
+ }
385
+ /**
386
+ * Build the TrustedEntityService object
387
+ */
388
+ build() {
389
+ const data = { ServiceInformation: this.info };
390
+ if (this.history.length > 0) data.ServiceHistory = this.history;
391
+ const result = TrustedEntityServiceSchema.safeParse(data);
392
+ if (!result.success) throw new LoTEException(`Invalid TrustedEntityService:\n${result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("\n")}`);
393
+ return result.data;
394
+ }
395
+ };
396
+ /**
397
+ * Create a new TrustedEntityBuilder
398
+ */
399
+ function trustedEntity() {
400
+ return new TrustedEntityBuilder();
401
+ }
402
+ /**
403
+ * Create a new ServiceBuilder
404
+ */
405
+ function service() {
406
+ return new ServiceBuilder();
407
+ }
408
+ //#endregion
409
+ //#region src/signer.ts
410
+ /**
411
+ * Sign a LoTE document
412
+ *
413
+ * @param options - Signing options including LoTE document, key ID, and signer function
414
+ * @returns The signed LoTE document as a JWS
415
+ *
416
+ * @example Using a local key via @owf/crypto:
417
+ * ```typescript
418
+ * import { ES256 } from '@owf/crypto';
419
+ * import { signLoTE } from '@owf/eudi-lote';
420
+ *
421
+ * const { privateKey } = await ES256.generateKeyPair();
422
+ * const signer = await ES256.getSigner(privateKey);
423
+ * const signed = await signLoTE({
424
+ * lote: myLoTE,
425
+ * keyId: 'lote-signer-2025',
426
+ * signer,
427
+ * });
428
+ * ```
429
+ *
430
+ * @example Using an external KMS:
431
+ * ```typescript
432
+ * const signed = await signLoTE({
433
+ * lote: myLoTE,
434
+ * keyId: 'lote-signer-2025',
435
+ * signer: async (data) => myKms.sign('ES256', data),
436
+ * });
437
+ * ```
438
+ */
439
+ async function signLoTE(options) {
440
+ const { lote, keyId, algorithm = "ES256", certificates, signer } = options;
441
+ const header = {
442
+ alg: algorithm,
443
+ typ: "trustlist+jwt",
444
+ kid: keyId
445
+ };
446
+ if (certificates && certificates.length > 0) header.x5c = certificates.map(parseCertificate);
447
+ const signingInput = `${base64urlEncode(JSON.stringify(header))}.${base64urlEncode(JSON.stringify(lote))}`;
448
+ return {
449
+ jws: `${signingInput}.${await signer(signingInput)}`,
450
+ header: {
451
+ alg: algorithm,
452
+ typ: "trustlist+jwt",
453
+ kid: keyId,
454
+ x5c: header.x5c
455
+ },
456
+ payload: lote
457
+ };
458
+ }
459
+ /**
460
+ * Create a new LoTE document with required structure
461
+ * Per ETSI TS 119 602, only SchemeOperatorName, ListIssueDateTime and NextUpdate are required
462
+ */
463
+ function createLoTE(schemeInfo, entities = []) {
464
+ const now = /* @__PURE__ */ new Date();
465
+ const nextYear = new Date(now);
466
+ nextYear.setFullYear(nextYear.getFullYear() + 1);
467
+ return { LoTE: {
468
+ ListAndSchemeInformation: {
469
+ LoTEVersionIdentifier: schemeInfo.LoTEVersionIdentifier ?? 1,
470
+ LoTESequenceNumber: schemeInfo.LoTESequenceNumber ?? 1,
471
+ LoTEType: schemeInfo.LoTEType,
472
+ SchemeOperatorName: schemeInfo.SchemeOperatorName,
473
+ SchemeOperatorAddress: schemeInfo.SchemeOperatorAddress,
474
+ SchemeName: schemeInfo.SchemeName,
475
+ SchemeInformationURI: schemeInfo.SchemeInformationURI,
476
+ StatusDeterminationApproach: schemeInfo.StatusDeterminationApproach,
477
+ SchemeTypeCommunityRules: schemeInfo.SchemeTypeCommunityRules,
478
+ SchemeTerritory: schemeInfo.SchemeTerritory,
479
+ PolicyOrLegalNotice: schemeInfo.PolicyOrLegalNotice,
480
+ HistoricalInformationPeriod: schemeInfo.HistoricalInformationPeriod,
481
+ PointersToOtherLoTE: schemeInfo.PointersToOtherLoTE,
482
+ ListIssueDateTime: schemeInfo.ListIssueDateTime ?? now.toISOString(),
483
+ NextUpdate: schemeInfo.NextUpdate ?? nextYear.toISOString(),
484
+ DistributionPoints: schemeInfo.DistributionPoints,
485
+ SchemeExtensions: schemeInfo.SchemeExtensions
486
+ },
487
+ TrustedEntitiesList: entities
488
+ } };
489
+ }
490
+ /**
491
+ * Increment the sequence number and update timestamps for a new version
492
+ */
493
+ function updateLoTEVersion(lote) {
494
+ const now = /* @__PURE__ */ new Date();
495
+ const nextYear = new Date(now);
496
+ nextYear.setFullYear(nextYear.getFullYear() + 1);
497
+ return { LoTE: {
498
+ ...lote.LoTE,
499
+ ListAndSchemeInformation: {
500
+ ...lote.LoTE.ListAndSchemeInformation,
501
+ LoTESequenceNumber: lote.LoTE.ListAndSchemeInformation.LoTESequenceNumber + 1,
502
+ ListIssueDateTime: now.toISOString(),
503
+ NextUpdate: nextYear.toISOString()
504
+ }
505
+ } };
506
+ }
507
+ /**
508
+ * Add a trusted entity to a LoTE document
509
+ */
510
+ function addTrustedEntity(lote, entity) {
511
+ return { LoTE: {
512
+ ...lote.LoTE,
513
+ TrustedEntitiesList: [...lote.LoTE.TrustedEntitiesList, entity]
514
+ } };
515
+ }
516
+ /**
517
+ * Remove a trusted entity from a LoTE document by name
518
+ */
519
+ function removeTrustedEntity(lote, entityName) {
520
+ return { LoTE: {
521
+ ...lote.LoTE,
522
+ TrustedEntitiesList: lote.LoTE.TrustedEntitiesList.filter((e) => !e.TrustedEntityInformation.TEName.some((n) => n.value === entityName))
523
+ } };
524
+ }
525
+ //#endregion
526
+ //#region src/validator.ts
527
+ /**
528
+ * LoTE Validator
529
+ *
530
+ * Runtime validation for ETSI TS 119 602 LoTE documents using Zod schemas.
531
+ */
532
+ /**
533
+ * Validate a LoTE document against ETSI TS 119 602 schema
534
+ *
535
+ * @param loteDocument - The LoTE document to validate
536
+ * @returns Validation result with errors if invalid
537
+ *
538
+ * @example
539
+ * ```typescript
540
+ * const result = validateLoTE(myLoTE);
541
+ * if (!result.valid) {
542
+ * console.error('Validation errors:', result.errors);
543
+ * }
544
+ * ```
545
+ */
546
+ function validateLoTE(loteDocument) {
547
+ const result = LoTEDocumentSchema.safeParse(loteDocument);
548
+ if (result.success) return {
549
+ valid: true,
550
+ errors: []
551
+ };
552
+ return {
553
+ valid: false,
554
+ errors: result.error.issues.map((issue) => ({
555
+ path: issue.path.join("."),
556
+ message: issue.message
557
+ }))
558
+ };
559
+ }
560
+ /**
561
+ * Assert that a LoTE document is valid, throwing if not
562
+ *
563
+ * @param loteDocument - The LoTE document to validate
564
+ * @throws Error if validation fails
565
+ */
566
+ function assertValidLoTE(loteDocument) {
567
+ const result = validateLoTE(loteDocument);
568
+ if (!result.valid) throw new LoTEException(`Invalid LoTE document:\n${result.errors.map((e) => `${e.path}: ${e.message}`).join("\n")}`);
569
+ }
570
+ //#endregion
571
+ export { JWKPublicKeySchema, ListAndSchemeInformationSchema, LoTEDocumentSchema, LoTEException, LoTEQualifierSchema, LoTESchema, LocalizedStringSchema, LocalizedURISchema, OtherLoTEPointerSchema, PkiObjectSchema, PolicyOrLegalNoticeSchema, PostalAddressSchema, SchemeOperatorAddressSchema, ServiceBuilder, ServiceDigitalIdentitySchema, ServiceHistoryInstanceSchema, ServiceInformationSchema, ServiceSupplyPointSchema, TrustedEntityAddressSchema, TrustedEntityBuilder, TrustedEntityInformationSchema, TrustedEntitySchema, TrustedEntityServiceSchema, X509CertificateRefSchema, addTrustedEntity, assertValidLoTE, createLoTE, removeTrustedEntity, service, signLoTE, trustedEntity, updateLoTEVersion, validateLoTE };
572
+
573
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/lote-exception.ts","../src/schemas.ts","../src/builders.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.string().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\n .object({\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 .passthrough()\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.string(),\n})\n\nexport const ServiceInformationSchema = z.object({\n ServiceName: z.array(LocalizedStringSchema).min(1),\n ServiceDigitalIdentity: ServiceDigitalIdentitySchema,\n ServiceTypeIdentifier: z.string().url().optional(),\n ServiceStatus: z.string().url().optional(),\n StatusStartingTime: z.string().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.string().url(),\n StatusStartingTime: z.string().datetime(),\n ServiceTypeIdentifier: z.string().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.string().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.string().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.string().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.string().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.string().datetime(),\n NextUpdate: z.string().datetime(),\n DistributionPoints: z.array(z.string()).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","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 */\nexport function createLoTE(\n schemeInfo: Partial<ListAndSchemeInformation> & Pick<ListAndSchemeInformation, 'SchemeOperatorName'>,\n entities: TrustedEntity[] = []\n): LoTEDocument {\n const now = new Date()\n const nextYear = new Date(now)\n nextYear.setFullYear(nextYear.getFullYear() + 1)\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 ?? nextYear.toISOString(),\n DistributionPoints: schemeInfo.DistributionPoints,\n SchemeExtensions: schemeInfo.SchemeExtensions,\n },\n TrustedEntitiesList: entities,\n }\n\n return { LoTE: lote }\n}\n\n/**\n * Increment the sequence number and update timestamps for a new version\n */\nexport function updateLoTEVersion(lote: LoTEDocument): LoTEDocument {\n const now = new Date()\n const nextYear = new Date(now)\n nextYear.setFullYear(nextYear.getFullYear() + 1)\n\n return {\n LoTE: {\n ...lote.LoTE,\n ListAndSchemeInformation: {\n ...lote.LoTE.ListAndSchemeInformation,\n LoTESequenceNumber: lote.LoTE.ListAndSchemeInformation.LoTESequenceNumber + 1,\n ListIssueDateTime: now.toISOString(),\n NextUpdate: nextYear.toISOString(),\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 { LoTEException } from './lote-exception'\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"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@owf/eudi-lote",
3
+ "version": "0.0.0",
4
+ "description": "SDK for creating, signing, and validating Lists of Trusted Entities (LoTE) per ETSI TS 119 602",
5
+ "files": [
6
+ "dist"
7
+ ],
8
+ "license": "Apache-2.0",
9
+ "exports": "./src/index.ts",
10
+ "homepage": "https://github.com/openwallet-foundation-labs/identity-common-ts/tree/main/packages/eudi-lote",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/openwallet-foundation-labs/identity-common-ts",
14
+ "directory": "packages/eudi-lote"
15
+ },
16
+ "publishConfig": {
17
+ "module": "./dist/index.mjs",
18
+ "types": "./dist/index.d.mts",
19
+ "exports": {
20
+ ".": "./dist/index.mjs",
21
+ "./package.json": "./package.json"
22
+ }
23
+ },
24
+ "keywords": [
25
+ "lote",
26
+ "list-of-trusted-entities",
27
+ "etsi",
28
+ "etsi-ts-119-602",
29
+ "eudi",
30
+ "wallet",
31
+ "x509",
32
+ "jwt"
33
+ ],
34
+ "scripts": {
35
+ "build": "tsdown src/index.ts --format esm --dts --sourcemap"
36
+ },
37
+ "dependencies": {
38
+ "@owf/crypto": "workspace:*",
39
+ "@owf/identity-common": "workspace:*",
40
+ "zod": "^4.3.6"
41
+ }
42
+ }