@learncard/react 2.12.6 → 2.12.8

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.
Files changed (102) hide show
  1. package/dist/cjs/{BoostGenericCard-eba2c7f3.js → BoostGenericCard-64c11fe1.js} +4 -4
  2. package/dist/cjs/BoostGenericCard-64c11fe1.js.map +1 -0
  3. package/dist/cjs/{CertificateDisplayCard-e66ebcfb.js → CertificateDisplayCard-b5e72ee5.js} +3 -3
  4. package/dist/cjs/{CertificateDisplayCard-e66ebcfb.js.map → CertificateDisplayCard-b5e72ee5.js.map} +1 -1
  5. package/dist/cjs/{MeritBadgeDisplayCard-10badbae.js → MeritBadgeDisplayCard-50423eeb.js} +3 -3
  6. package/dist/cjs/{MeritBadgeDisplayCard-10badbae.js.map → MeritBadgeDisplayCard-50423eeb.js.map} +1 -1
  7. package/dist/cjs/{MeritBadgeSkillsCount-8c2a6cab.js → MeritBadgeSkillsCount-f121a3db.js} +2 -2
  8. package/dist/cjs/{MeritBadgeSkillsCount-8c2a6cab.js.map → MeritBadgeSkillsCount-f121a3db.js.map} +1 -1
  9. package/dist/cjs/{SchoolIDCard-10796199.js → SchoolIDCard-2d3cbb2c.js} +3 -1184
  10. package/dist/cjs/SchoolIDCard-2d3cbb2c.js.map +1 -0
  11. package/dist/cjs/{VCCard-cc89948b.js → VCCard-72ec54b5.js} +3 -3
  12. package/dist/cjs/{VCCard-cc89948b.js.map → VCCard-72ec54b5.js.map} +1 -1
  13. package/dist/cjs/{VCDisplayBackFace-e4107c55.js → VCDisplayBackFace-c6204dda.js} +3 -3
  14. package/dist/cjs/{VCDisplayBackFace-e4107c55.js.map → VCDisplayBackFace-c6204dda.js.map} +1 -1
  15. package/dist/cjs/{VCDisplayCard-0b4e99c0.js → VCDisplayCard-e0fbeb3c.js} +3 -3
  16. package/dist/cjs/{VCDisplayCard-0b4e99c0.js.map → VCDisplayCard-e0fbeb3c.js.map} +1 -1
  17. package/dist/cjs/{VCDisplayCard2-5c7c0ff7.js → VCDisplayCard2-5d805202.js} +17 -7
  18. package/dist/cjs/VCDisplayCard2-5d805202.js.map +1 -0
  19. package/dist/cjs/{VCVerificationPill-ed387f6e.js → VCVerificationPill-90e6ab77.js} +2 -2
  20. package/dist/cjs/{VCVerificationPill-ed387f6e.js.map → VCVerificationPill-90e6ab77.js.map} +1 -1
  21. package/dist/cjs/{credential.helpers-9a9ad225.js → credential.helpers-0f0e8f00.js} +2 -2
  22. package/dist/cjs/{credential.helpers-9a9ad225.js.map → credential.helpers-0f0e8f00.js.map} +1 -1
  23. package/dist/cjs/index-47efbf5b.js +1186 -0
  24. package/dist/cjs/index-47efbf5b.js.map +1 -0
  25. package/dist/cjs/index.js +13 -12
  26. package/dist/cjs/index.js.map +1 -1
  27. package/dist/cjs/index14.js +13 -12
  28. package/dist/cjs/index14.js.map +1 -1
  29. package/dist/cjs/index22.js +4 -4
  30. package/dist/cjs/index31.js +2 -1
  31. package/dist/cjs/index31.js.map +1 -1
  32. package/dist/cjs/index39.js +10 -9
  33. package/dist/cjs/index39.js.map +1 -1
  34. package/dist/cjs/index4.js +3 -3
  35. package/dist/cjs/index40.js +4 -4
  36. package/dist/cjs/index41.js +5 -5
  37. package/dist/cjs/index42.js +6 -5
  38. package/dist/cjs/index42.js.map +1 -1
  39. package/dist/cjs/index43.js +1 -1
  40. package/dist/cjs/index46.js +2 -2
  41. package/dist/cjs/index7.js +3 -3
  42. package/dist/cjs/{types.esm-ba95174e.js → types.esm-9062360c.js} +800 -167
  43. package/dist/cjs/types.esm-9062360c.js.map +1 -0
  44. package/dist/esm/{BoostGenericCard-26502a81.js → BoostGenericCard-a2c5d561.js} +4 -4
  45. package/dist/esm/BoostGenericCard-a2c5d561.js.map +1 -0
  46. package/dist/esm/{CertificateDisplayCard-0de68029.js → CertificateDisplayCard-68d8d6ee.js} +3 -3
  47. package/dist/esm/{CertificateDisplayCard-0de68029.js.map → CertificateDisplayCard-68d8d6ee.js.map} +1 -1
  48. package/dist/esm/{MeritBadgeDisplayCard-e569e17f.js → MeritBadgeDisplayCard-7a32129d.js} +3 -3
  49. package/dist/esm/{MeritBadgeDisplayCard-e569e17f.js.map → MeritBadgeDisplayCard-7a32129d.js.map} +1 -1
  50. package/dist/esm/{MeritBadgeSkillsCount-d8d234a2.js → MeritBadgeSkillsCount-f0a53047.js} +2 -2
  51. package/dist/esm/{MeritBadgeSkillsCount-d8d234a2.js.map → MeritBadgeSkillsCount-f0a53047.js.map} +1 -1
  52. package/dist/esm/{SchoolIDCard-f82e40bc.js → SchoolIDCard-fbd1cf6c.js} +2 -1183
  53. package/dist/esm/SchoolIDCard-fbd1cf6c.js.map +1 -0
  54. package/dist/esm/{VCCard-6376f382.js → VCCard-a117cfd8.js} +3 -3
  55. package/dist/esm/{VCCard-6376f382.js.map → VCCard-a117cfd8.js.map} +1 -1
  56. package/dist/esm/{VCDisplayBackFace-2bf451a6.js → VCDisplayBackFace-2381affa.js} +3 -3
  57. package/dist/esm/{VCDisplayBackFace-2bf451a6.js.map → VCDisplayBackFace-2381affa.js.map} +1 -1
  58. package/dist/esm/{VCDisplayCard-ae88779a.js → VCDisplayCard-52e66021.js} +3 -3
  59. package/dist/esm/{VCDisplayCard-ae88779a.js.map → VCDisplayCard-52e66021.js.map} +1 -1
  60. package/dist/esm/{VCDisplayCard2-116d823d.js → VCDisplayCard2-b3b641a1.js} +17 -7
  61. package/dist/esm/VCDisplayCard2-b3b641a1.js.map +1 -0
  62. package/dist/esm/{VCVerificationPill-7cc43650.js → VCVerificationPill-680c4e23.js} +2 -2
  63. package/dist/esm/{VCVerificationPill-7cc43650.js.map → VCVerificationPill-680c4e23.js.map} +1 -1
  64. package/dist/esm/{credential.helpers-d71e692a.js → credential.helpers-43119589.js} +2 -2
  65. package/dist/esm/{credential.helpers-d71e692a.js.map → credential.helpers-43119589.js.map} +1 -1
  66. package/dist/esm/index-cbd2e9db.js +1184 -0
  67. package/dist/esm/index-cbd2e9db.js.map +1 -0
  68. package/dist/esm/index.js +13 -12
  69. package/dist/esm/index.js.map +1 -1
  70. package/dist/esm/index14.js +13 -12
  71. package/dist/esm/index14.js.map +1 -1
  72. package/dist/esm/index22.js +4 -4
  73. package/dist/esm/index31.js +2 -1
  74. package/dist/esm/index31.js.map +1 -1
  75. package/dist/esm/index39.js +10 -9
  76. package/dist/esm/index39.js.map +1 -1
  77. package/dist/esm/index4.js +3 -3
  78. package/dist/esm/index40.js +4 -4
  79. package/dist/esm/index41.js +5 -5
  80. package/dist/esm/index42.js +6 -5
  81. package/dist/esm/index42.js.map +1 -1
  82. package/dist/esm/index43.js +1 -1
  83. package/dist/esm/index46.js +2 -2
  84. package/dist/esm/index7.js +3 -3
  85. package/dist/esm/{types.esm-35d4f5e9.js → types.esm-b9cb7331.js} +800 -167
  86. package/dist/esm/types.esm-b9cb7331.js.map +1 -0
  87. package/dist/main.css +1 -1
  88. package/dist/main.js +1 -1
  89. package/package.json +4 -4
  90. package/src/assets/styles/main.css +10 -0
  91. package/src/components/BoostGenericCard/BoostGenericCard.stories.tsx +41 -1
  92. package/src/components/BoostGenericCard/BoostGenericCard.tsx +2 -2
  93. package/src/components/BoostGenericCard/__tests__/BoostGenericCard.a11y.test.tsx +25 -0
  94. package/src/components/VCDisplayCard2/VCIDDisplayFrontFace.tsx +8 -2
  95. package/dist/cjs/BoostGenericCard-eba2c7f3.js.map +0 -1
  96. package/dist/cjs/SchoolIDCard-10796199.js.map +0 -1
  97. package/dist/cjs/VCDisplayCard2-5c7c0ff7.js.map +0 -1
  98. package/dist/cjs/types.esm-ba95174e.js.map +0 -1
  99. package/dist/esm/BoostGenericCard-26502a81.js.map +0 -1
  100. package/dist/esm/SchoolIDCard-f82e40bc.js.map +0 -1
  101. package/dist/esm/VCDisplayCard2-116d823d.js.map +0 -1
  102. package/dist/esm/types.esm-35d4f5e9.js.map +0 -1
@@ -7406,6 +7406,7 @@ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7406
7406
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
7407
7407
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7408
7408
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
7409
+ var __pow = Math.pow;
7409
7410
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7410
7411
  var __spreadValues = (a, b) => {
7411
7412
  for (var prop in b || (b = {}))
@@ -8007,6 +8008,201 @@ var StringQuery = union([
8007
8008
  $or: BaseStringQuery.array()
8008
8009
  })
8009
8010
  ]);
8011
+ var LearnCardRefreshAuthorizationValidator = object({ type: literal("LearnCardDIDAuth") }).catchall(any());
8012
+ var ManagedCredentialRefreshServiceValidator = object({
8013
+ id: string().min(1),
8014
+ type: literal("LearnCardCredentialRefresh2026"),
8015
+ authorization: LearnCardRefreshAuthorizationValidator.optional()
8016
+ }).catchall(any());
8017
+ var StandardCredentialRefreshServiceValidator = object({
8018
+ id: string().min(1),
8019
+ type: literal("1EdTechCredentialRefresh")
8020
+ }).catchall(any());
8021
+ union([
8022
+ ManagedCredentialRefreshServiceValidator,
8023
+ StandardCredentialRefreshServiceValidator
8024
+ ]);
8025
+ object({
8026
+ holder: object({
8027
+ profileId: string().optional(),
8028
+ did: string().min(1)
8029
+ }),
8030
+ credentialId: string().min(1)
8031
+ });
8032
+ object({
8033
+ refreshId: string().min(1),
8034
+ refreshService: ManagedCredentialRefreshServiceValidator.extend({
8035
+ authorization: LearnCardRefreshAuthorizationValidator
8036
+ })
8037
+ });
8038
+ var ManagedCredentialRefreshReceiptValidator = object({
8039
+ refreshId: string().min(1),
8040
+ refreshService: ManagedCredentialRefreshServiceValidator,
8041
+ credentialId: string().min(1),
8042
+ issuerDid: string().min(1),
8043
+ holderDid: string().min(1),
8044
+ credentialStatus: CredentialStatusValidator.or(
8045
+ CredentialStatusValidator.array()
8046
+ ).optional()
8047
+ }).strip();
8048
+ var InboxCredentialRefreshReceiptValidator = ManagedCredentialRefreshReceiptValidator.omit(
8049
+ { holderDid: true }
8050
+ ).extend({ holderDid: string().min(1).optional() });
8051
+ var CredentialRefreshSigningModeValidator = _enum(["issuer-signed", "signing-authority"]);
8052
+ var PublishCredentialRefreshBaseFields = {
8053
+ refreshId: string().min(1),
8054
+ notifyHolder: boolean().optional(),
8055
+ updateSummary: string().optional(),
8056
+ idempotencyKey: string().optional()
8057
+ };
8058
+ object(__spreadProps(__spreadValues({}, PublishCredentialRefreshBaseFields), {
8059
+ mode: literal("issuer-signed"),
8060
+ signedCredential: VCValidator
8061
+ }));
8062
+ object(__spreadProps(__spreadValues({}, PublishCredentialRefreshBaseFields), {
8063
+ mode: literal("signing-authority"),
8064
+ credential: UnsignedVCValidator,
8065
+ signingAuthority: object({
8066
+ type: string().min(1)
8067
+ }).catchall(any())
8068
+ }));
8069
+ object(__spreadProps(__spreadValues({}, PublishCredentialRefreshBaseFields), {
8070
+ mode: CredentialRefreshSigningModeValidator,
8071
+ signedCredential: VCValidator.optional(),
8072
+ credential: UnsignedVCValidator.optional(),
8073
+ signingAuthority: object({
8074
+ type: string().min(1)
8075
+ }).catchall(any()).optional()
8076
+ })).superRefine((input, ctx) => {
8077
+ if (input.mode === "issuer-signed" && !input.signedCredential) {
8078
+ ctx.addIssue({
8079
+ code: "custom",
8080
+ path: ["signedCredential"],
8081
+ message: "signedCredential is required for issuer-signed publication"
8082
+ });
8083
+ }
8084
+ if (input.mode === "issuer-signed" && (input.credential !== void 0 || input.signingAuthority !== void 0)) {
8085
+ ctx.addIssue({
8086
+ code: "custom",
8087
+ path: ["mode"],
8088
+ message: "issuer-signed publication cannot include signing-authority fields"
8089
+ });
8090
+ }
8091
+ if (input.mode === "signing-authority") {
8092
+ if (input.signedCredential !== void 0) {
8093
+ ctx.addIssue({
8094
+ code: "custom",
8095
+ path: ["signedCredential"],
8096
+ message: "signing-authority publication cannot include signedCredential"
8097
+ });
8098
+ }
8099
+ if (!input.credential) {
8100
+ ctx.addIssue({
8101
+ code: "custom",
8102
+ path: ["credential"],
8103
+ message: "credential is required for signing-authority publication"
8104
+ });
8105
+ }
8106
+ if (!input.signingAuthority) {
8107
+ ctx.addIssue({
8108
+ code: "custom",
8109
+ path: ["signingAuthority"],
8110
+ message: "signingAuthority is required for signing-authority publication"
8111
+ });
8112
+ }
8113
+ }
8114
+ });
8115
+ var PublishCredentialRefreshNotificationValidator = _enum([
8116
+ "queued",
8117
+ "suppressed",
8118
+ "not-applicable",
8119
+ /** Publication succeeded, but the post-commit notification enqueue must be retried. */
8120
+ "delivery-failed"
8121
+ ]);
8122
+ object({
8123
+ refreshId: string().min(1),
8124
+ version: number().int().positive(),
8125
+ publishedAt: string().min(1),
8126
+ notification: PublishCredentialRefreshNotificationValidator
8127
+ });
8128
+ var CredentialRefreshVersionMetadataValidator = object({
8129
+ version: number().int().positive(),
8130
+ publishedAt: string().min(1),
8131
+ effectiveAt: string().optional(),
8132
+ etag: string().optional(),
8133
+ signingMode: CredentialRefreshSigningModeValidator.optional(),
8134
+ updateSummary: string().optional()
8135
+ });
8136
+ object({
8137
+ refreshId: string().min(1),
8138
+ cursor: string().optional(),
8139
+ limit: number().int().positive().optional()
8140
+ });
8141
+ object({
8142
+ records: CredentialRefreshVersionMetadataValidator.array(),
8143
+ hasMore: boolean(),
8144
+ cursor: string().optional()
8145
+ });
8146
+ object({
8147
+ challenge: string().min(1),
8148
+ expiresAt: string().min(1),
8149
+ domain: string().optional(),
8150
+ scheme: literal("LearnCardDIDAuth").optional()
8151
+ });
8152
+ var PublicCredentialRefreshEnvelopeValidator = object({
8153
+ format: literal("vc"),
8154
+ credential: VCValidator,
8155
+ etag: string().optional()
8156
+ });
8157
+ var JweCredentialRefreshEnvelopeValidator = object({
8158
+ format: literal("jwe"),
8159
+ jwe: JWEValidator,
8160
+ etag: string().optional(),
8161
+ /** Present on LearnCard-managed endpoints; optional for interoperable JWE services. */
8162
+ version: number().int().positive().optional()
8163
+ });
8164
+ discriminatedUnion("format", [
8165
+ PublicCredentialRefreshEnvelopeValidator,
8166
+ JweCredentialRefreshEnvelopeValidator
8167
+ ]);
8168
+ var CredentialRefreshFailureCodeValidator = _enum([
8169
+ "UNAVAILABLE",
8170
+ "TIMEOUT",
8171
+ "UNSUPPORTED_SERVICE",
8172
+ "UNAUTHORIZED",
8173
+ "MALFORMED_RESPONSE",
8174
+ "INVALID_PROOF",
8175
+ "ISSUER_MISMATCH",
8176
+ "ID_MISMATCH",
8177
+ "ROLLBACK",
8178
+ "REVOKED",
8179
+ "UNSAFE_ENDPOINT"
8180
+ ]);
8181
+ var CredentialRefreshUpdatedResultValidator = object({
8182
+ status: literal("updated"),
8183
+ credential: VCValidator,
8184
+ etag: string().optional(),
8185
+ managedVersion: number().int().positive().optional()
8186
+ });
8187
+ var CredentialRefreshUnchangedResultValidator = object({
8188
+ status: literal("unchanged"),
8189
+ checkedAt: string().min(1),
8190
+ etag: string().optional()
8191
+ });
8192
+ var CredentialRefreshUnsupportedResultValidator = object({
8193
+ status: literal("unsupported")
8194
+ });
8195
+ var CredentialRefreshFailedResultValidator = object({
8196
+ status: literal("failed"),
8197
+ code: CredentialRefreshFailureCodeValidator,
8198
+ retryable: boolean()
8199
+ });
8200
+ discriminatedUnion("status", [
8201
+ CredentialRefreshUpdatedResultValidator,
8202
+ CredentialRefreshUnchangedResultValidator,
8203
+ CredentialRefreshUnsupportedResultValidator,
8204
+ CredentialRefreshFailedResultValidator
8205
+ ]);
8010
8206
  var LCNProfileDisplayValidator = object({
8011
8207
  backgroundColor: string().optional(),
8012
8208
  backgroundImage: string().optional(),
@@ -8342,7 +8538,13 @@ var SendBoostInputValidator = object({
8342
8538
  "Options for email/phone recipients (Universal Inbox)"
8343
8539
  ),
8344
8540
  templateData: record(string(), unknown()).optional(),
8345
- integrationId: string().optional().describe("Integration ID for activity tracking")
8541
+ integrationId: string().optional().describe("Integration ID for activity tracking"),
8542
+ refresh: boolean().optional().describe(
8543
+ "Request managed credential refresh for this send. Profile/DID recipients use immediate issuance; email/phone recipients use deferred Universal Inbox signing and bind the holder at claim."
8544
+ ),
8545
+ idempotencyKey: string().min(1).max(200).optional().describe(
8546
+ "Caller-chosen key that makes a managed refresh send (refresh: true) safe to retry as a whole: retries with the same key reuse the same boost, refresh allocation and result. Reusing a key for a different request is rejected. With signedCredential, requires prior tRPC prepareRefreshableSend; direct REST callers omit the key and retry the exact signed credential and templateUri."
8547
+ )
8346
8548
  }).refine((data) => data.templateUri || data.template || data.signedCredential, {
8347
8549
  message: "Either templateUri, template, or signedCredential must be provided.",
8348
8550
  path: ["templateUri"]
@@ -8358,8 +8560,12 @@ var SendBoostInputValidator = object({
8358
8560
  message: "guardianEmail must differ from recipient (self-approval not allowed)",
8359
8561
  path: ["options", "guardianEmail"]
8360
8562
  }
8361
- );
8563
+ ).refine((data) => !data.idempotencyKey || data.refresh === true, {
8564
+ message: "idempotencyKey is only supported with refresh: true.",
8565
+ path: ["idempotencyKey"]
8566
+ });
8362
8567
  var SendInboxResponseValidator = object({
8568
+ refresh: InboxCredentialRefreshReceiptValidator.optional(),
8363
8569
  issuanceId: string(),
8364
8570
  status: _enum(["PENDING", "ISSUED", "EXPIRED", "DELIVERED", "CLAIMED"]),
8365
8571
  claimUrl: string().url().optional().describe("Present when suppressDelivery=true"),
@@ -8374,8 +8580,34 @@ var SendBoostResponseValidator = object({
8374
8580
  activityId: string().describe("Links to the activity lifecycle for this issuance"),
8375
8581
  inbox: SendInboxResponseValidator.optional().describe(
8376
8582
  "Present when sent via email/phone (Universal Inbox)"
8583
+ ),
8584
+ refresh: ManagedCredentialRefreshReceiptValidator.optional().describe(
8585
+ "Present when managed refresh was requested: issuance metadata the issuer keeps to publish future updates"
8377
8586
  )
8378
8587
  });
8588
+ object({
8589
+ recipient: string(),
8590
+ templateUri: string().optional(),
8591
+ template: SendBoostTemplateValidator.optional(),
8592
+ contractUri: string().optional(),
8593
+ templateData: record(string(), unknown()).optional(),
8594
+ integrationId: string().optional(),
8595
+ /** Credential ID to allocate for; generated server-side when omitted. */
8596
+ credentialId: string().min(1).optional(),
8597
+ idempotencyKey: string().min(1).max(200).optional()
8598
+ }).refine((data) => Boolean(data.templateUri) !== Boolean(data.template), {
8599
+ message: "Provide exactly one of templateUri or template."
8600
+ });
8601
+ object({
8602
+ boostUri: string(),
8603
+ credentialId: string(),
8604
+ refreshId: string(),
8605
+ refreshService: ManagedCredentialRefreshServiceValidator,
8606
+ /** The DID to use as credentialSubject.id (recipient DID, or the profile's did:web). */
8607
+ holderDid: string(),
8608
+ /** Present when this idempotencyKey already completed: return it without signing. */
8609
+ completed: SendBoostResponseValidator.optional()
8610
+ });
8379
8611
  discriminatedUnion("type", [SendBoostInputValidator]);
8380
8612
  discriminatedUnion("type", [SendBoostResponseValidator]);
8381
8613
  var ConsentFlowTermsStatusValidator = _enum(["live", "stale", "withdrawn"]);
@@ -8706,6 +8938,7 @@ object({
8706
8938
  }, "error")
8707
8939
  }),
8708
8940
  scope: string(),
8941
+ actAs: string().optional(),
8709
8942
  createdAt: datetime({ error: "createdAt must be a valid ISO 8601 datetime string" }),
8710
8943
  expiresAt: datetime({ error: "expiresAt must be a valid ISO 8601 datetime string" }).nullish().optional()
8711
8944
  });
@@ -8777,6 +9010,8 @@ object({
8777
9010
  sessionJwt: string()
8778
9011
  });
8779
9012
  var InboxCredentialValidator = object({
9013
+ refresh: InboxCredentialRefreshReceiptValidator.optional(),
9014
+ refreshId: string().optional(),
8780
9015
  id: string(),
8781
9016
  credential: string().optional(),
8782
9017
  isSigned: boolean(),
@@ -8820,7 +9055,7 @@ var IssueInboxSigningAuthorityValidator = object({
8820
9055
  endpoint: string().url(),
8821
9056
  name: string()
8822
9057
  });
8823
- object({
9058
+ var IssueInboxCredentialValidator = object({
8824
9059
  // === CORE DATA (Required) ===
8825
9060
  // WHAT is being sent and WHO is it for?
8826
9061
  recipient: ContactMethodQueryValidator.describe("The recipient of the credential"),
@@ -8831,12 +9066,19 @@ object({
8831
9066
  templateUri: string().optional().describe(
8832
9067
  "URI of a boost template to use for issuance. The boost credential will be resolved and used. Mutually exclusive with credential field."
8833
9068
  ),
9069
+ refresh: boolean().optional().describe(
9070
+ "Allocate managed refresh before signing. Requires unsigned content and a registered signing authority; binds the holder on claim."
9071
+ ),
9072
+ idempotencyKey: string().min(1).max(200).optional(),
8834
9073
  // === OPTIONAL FEATURES ===
8835
9074
  // Add major, distinct features at the top level.
8836
9075
  //consentRequest: ConsentRequestValidator.optional(),
8837
9076
  // === PROCESS CONFIGURATION (Optional) ===
8838
9077
  // HOW should this issuance be handled?
8839
9078
  configuration: object({
9079
+ guardianEmail: string().email().optional().describe(
9080
+ "Require approval from this guardian before the recipient can claim. Must differ from the recipient email."
9081
+ ),
8840
9082
  signingAuthority: IssueInboxSigningAuthorityValidator.optional().describe(
8841
9083
  "The signing authority to use for the credential. If not provided, the users default signing authority will be used if the credential is not signed."
8842
9084
  ),
@@ -8890,17 +9132,133 @@ object({
8890
9132
  }).optional().describe(
8891
9133
  "Configuration for the credential issuance. If not provided, the default configuration will be used."
8892
9134
  )
9135
+ }).refine((data) => !data.idempotencyKey || data.refresh === true, {
9136
+ message: "idempotencyKey requires refresh: true."
8893
9137
  }).refine((data) => data.credential || data.templateUri, {
8894
9138
  message: "Either credential or templateUri must be provided.",
8895
9139
  path: ["credential"]
8896
- });
8897
- object({
9140
+ }).refine(
9141
+ (data) => {
9142
+ var _a2;
9143
+ return !((_a2 = data.configuration) == null ? void 0 : _a2.guardianEmail) || data.recipient.type !== "email" || data.configuration.guardianEmail.toLowerCase() !== data.recipient.value.toLowerCase();
9144
+ },
9145
+ {
9146
+ message: "guardianEmail must differ from recipient (self-approval not allowed)",
9147
+ path: ["configuration", "guardianEmail"]
9148
+ }
9149
+ );
9150
+ var IssueInboxCredentialResponseValidator = object({
9151
+ refresh: InboxCredentialRefreshReceiptValidator.optional(),
8898
9152
  issuanceId: string(),
8899
9153
  status: LCNInboxStatusEnumValidator,
8900
9154
  recipient: ContactMethodQueryValidator,
8901
9155
  claimUrl: string().url().optional(),
8902
9156
  recipientDid: string().optional()
8903
9157
  });
9158
+ var InboxBatchConfigurationValidator = IssueInboxCredentialValidator.shape.configuration.unwrap().extend({
9159
+ refresh: IssueInboxCredentialValidator.shape.refresh.describe(
9160
+ "Enable managed refresh by default. An item configuration.refresh overrides this value, including false."
9161
+ ),
9162
+ delivery: IssueInboxCredentialValidator.shape.configuration.unwrap().shape.delivery.unwrap().extend({ suppress: boolean().optional() }).optional()
9163
+ });
9164
+ var InboxBatchItemConfigurationValidator = InboxBatchConfigurationValidator.extend({
9165
+ guardianEmail: InboxBatchConfigurationValidator.shape.guardianEmail.nullable().describe(
9166
+ "Require guardian approval, or set null to clear a batch-level guardianEmail for this item."
9167
+ )
9168
+ });
9169
+ var IssueInboxCredentialBatchItemValidator = object(__spreadProps(__spreadValues({}, IssueInboxCredentialValidator.shape), {
9170
+ configuration: InboxBatchItemConfigurationValidator.optional(),
9171
+ idempotencyKey: string().max(256).optional()
9172
+ })).refine((data) => data.credential || data.templateUri, {
9173
+ message: "Either credential or templateUri must be provided.",
9174
+ path: ["credential"]
9175
+ }).describe(
9176
+ "One issuance: provide credential or templateUri. Invalid input is rejected at submission with its item index."
9177
+ );
9178
+ object({
9179
+ requestId: string().min(1).max(256).optional(),
9180
+ items: array(IssueInboxCredentialBatchItemValidator).min(1).max(100),
9181
+ configuration: InboxBatchConfigurationValidator.optional()
9182
+ }).superRefine((batch, ctx) => {
9183
+ batch.items.forEach((item, index) => {
9184
+ var _a2, _b;
9185
+ const itemGuardian = (_a2 = item.configuration) == null ? void 0 : _a2.guardianEmail;
9186
+ const guardian = itemGuardian === null ? void 0 : itemGuardian != null ? itemGuardian : (_b = batch.configuration) == null ? void 0 : _b.guardianEmail;
9187
+ if (guardian && item.recipient.type === "email" && guardian.toLowerCase() === item.recipient.value.toLowerCase()) {
9188
+ ctx.addIssue({
9189
+ code: "custom",
9190
+ path: ["items", index, "configuration", "guardianEmail"],
9191
+ message: "guardianEmail must differ from recipient (self-approval not allowed)"
9192
+ });
9193
+ }
9194
+ });
9195
+ });
9196
+ var InboxBatchErrorReasonValidator = _enum([
9197
+ "DUPLICATE_KEY",
9198
+ "IDEMPOTENCY_MISMATCH",
9199
+ "IN_PROGRESS",
9200
+ "UNCONFIRMED"
9201
+ ]);
9202
+ var IssueInboxCredentialBatchItemResultValidator = discriminatedUnion("success", [
9203
+ IssueInboxCredentialResponseValidator.extend({
9204
+ success: literal(true),
9205
+ index: number().int().nonnegative(),
9206
+ deduplicated: boolean().optional(),
9207
+ guardianStatus: GuardianStatusValidator.optional(),
9208
+ idempotencyKey: string().optional()
9209
+ }),
9210
+ object({
9211
+ success: literal(false),
9212
+ index: number().int().nonnegative(),
9213
+ idempotencyKey: string().optional(),
9214
+ recipient: ContactMethodQueryValidator.optional(),
9215
+ error: object({
9216
+ code: string(),
9217
+ message: string(),
9218
+ reason: InboxBatchErrorReasonValidator.optional()
9219
+ }),
9220
+ issuanceId: string().optional().describe(
9221
+ "Present when issuance completed but replay storage could not be confirmed. Reconcile this issuance; do not issue again with a new key."
9222
+ ),
9223
+ claimUrl: string().url().optional().describe(
9224
+ "Claim URL of the completed issuance, if available, when replay storage could not be confirmed."
9225
+ )
9226
+ })
9227
+ ]);
9228
+ var IssueInboxCredentialBatchResponseValidator = object({
9229
+ results: array(IssueInboxCredentialBatchItemResultValidator),
9230
+ summary: object({
9231
+ total: number(),
9232
+ succeeded: number(),
9233
+ failed: number(),
9234
+ deduplicated: number()
9235
+ })
9236
+ });
9237
+ object({
9238
+ batchId: string(),
9239
+ status: _enum(["QUEUED", "PROCESSING", "COMPLETED", "NEEDS_RECONCILIATION"]),
9240
+ createdAt: string()
9241
+ });
9242
+ object({
9243
+ batchId: string(),
9244
+ createdAt: string(),
9245
+ done: boolean().describe(
9246
+ "True when no queued or processing items remain, including unconfirmed outcomes."
9247
+ ),
9248
+ status: _enum(["QUEUED", "PROCESSING", "COMPLETED", "NEEDS_RECONCILIATION"]),
9249
+ items: array(
9250
+ object({
9251
+ index: number().int().nonnegative(),
9252
+ state: _enum(["QUEUED", "PROCESSING", "COMPLETED", "NEEDS_RECONCILIATION"]),
9253
+ result: IssueInboxCredentialBatchItemResultValidator.optional()
9254
+ })
9255
+ ),
9256
+ summary: IssueInboxCredentialBatchResponseValidator.shape.summary.extend({
9257
+ completed: number(),
9258
+ pending: number(),
9259
+ unconfirmed: number()
9260
+ })
9261
+ });
8904
9262
  var CredentialNameRefValidator = object({ name: string() }).passthrough();
8905
9263
  object({
8906
9264
  credential: VCValidator.or(VPValidator).or(UnsignedVCValidator).or(CredentialNameRefValidator).describe("The credential to issue, or a { name } reference to resolve a boost template."),
@@ -9386,6 +9744,7 @@ var CredentialActivityValidator = object({
9386
9744
  eventType: CredentialActivityEventTypeValidator,
9387
9745
  timestamp: string(),
9388
9746
  actorProfileId: string().optional(),
9747
+ onBehalfOf: string().optional(),
9389
9748
  recipientType: CredentialActivityRecipientTypeValidator,
9390
9749
  recipientIdentifier: string(),
9391
9750
  boostUri: string().optional(),
@@ -9426,6 +9785,12 @@ object({
9426
9785
  this.name = "AuthSessionError";
9427
9786
  }
9428
9787
  }, __name(_a, "AuthSessionError"), _a);
9788
+ object({
9789
+ state: _enum(["none", "enabled", "locked", "stale"]),
9790
+ enabled: boolean(),
9791
+ attemptsRemaining: number().int().nonnegative(),
9792
+ salt: string().optional()
9793
+ });
9429
9794
  var BITSTRING_STATUS_PURPOSES = ["revocation", "suspension"];
9430
9795
  var BitstringStatusPurposeValidator = _enum(BITSTRING_STATUS_PURPOSES);
9431
9796
  var BitstringStatusListEntryValidator = object({
@@ -9534,188 +9899,456 @@ object({
9534
9899
  version: number().default(1),
9535
9900
  messages: array(inAppMessageValidator).default([])
9536
9901
  }).passthrough();
9537
- var LearnCardRefreshAuthorizationValidator = object({ type: literal("LearnCardDIDAuth") }).catchall(any());
9538
- var ManagedCredentialRefreshServiceValidator = object({
9539
- id: string().min(1),
9540
- type: literal("LearnCardCredentialRefresh2026"),
9541
- authorization: LearnCardRefreshAuthorizationValidator.optional()
9542
- }).catchall(any());
9543
- var StandardCredentialRefreshServiceValidator = object({
9544
- id: string().min(1),
9545
- type: literal("1EdTechCredentialRefresh")
9546
- }).catchall(any());
9547
- union([
9548
- ManagedCredentialRefreshServiceValidator,
9549
- StandardCredentialRefreshServiceValidator
9550
- ]);
9551
- object({
9552
- holder: object({
9553
- profileId: string().optional(),
9554
- did: string().min(1)
9555
- }),
9556
- credentialId: string().min(1)
9557
- });
9558
- object({
9559
- refreshId: string().min(1),
9560
- refreshService: ManagedCredentialRefreshServiceValidator.extend({
9561
- authorization: LearnCardRefreshAuthorizationValidator
9562
- })
9563
- });
9564
- var CredentialRefreshSigningModeValidator = _enum(["issuer-signed", "signing-authority"]);
9565
- var PublishCredentialRefreshBaseFields = {
9566
- refreshId: string().min(1),
9567
- notifyHolder: boolean().optional(),
9568
- updateSummary: string().optional(),
9569
- idempotencyKey: string().optional()
9570
- };
9571
- object(__spreadProps(__spreadValues({}, PublishCredentialRefreshBaseFields), {
9572
- mode: literal("issuer-signed"),
9573
- signedCredential: VCValidator
9574
- }));
9575
- object(__spreadProps(__spreadValues({}, PublishCredentialRefreshBaseFields), {
9576
- mode: literal("signing-authority"),
9577
- credential: UnsignedVCValidator,
9578
- signingAuthority: object({
9579
- type: string().min(1)
9580
- }).catchall(any())
9581
- }));
9582
- object(__spreadProps(__spreadValues({}, PublishCredentialRefreshBaseFields), {
9583
- mode: CredentialRefreshSigningModeValidator,
9584
- signedCredential: VCValidator.optional(),
9585
- credential: UnsignedVCValidator.optional(),
9586
- signingAuthority: object({
9587
- type: string().min(1)
9588
- }).catchall(any()).optional()
9589
- })).superRefine((input, ctx) => {
9590
- if (input.mode === "issuer-signed" && !input.signedCredential) {
9591
- ctx.addIssue({
9592
- code: "custom",
9593
- path: ["signedCredential"],
9594
- message: "signedCredential is required for issuer-signed publication"
9595
- });
9902
+ var SHARE_LINK_ID_BYTES = 16;
9903
+ var SHARE_CONTENT_KEY_BYTES = 32;
9904
+ var SHARE_IV_BYTES = 12;
9905
+ var SHARE_TAG_BYTES = 16;
9906
+ var MAX_SHARE_CIPHERTEXT_BYTES = 512 * 1024;
9907
+ var MAX_SHARE_RECOVERY_JWE_BYTES = 64 * 1024;
9908
+ var MAX_SELECTED_CREDENTIALS = 50;
9909
+ var MAX_ENDORSEMENTS = 200;
9910
+ var MAX_VP_MEMBERS = MAX_SELECTED_CREDENTIALS + MAX_ENDORSEMENTS;
9911
+ var MAX_SHARE_SOURCE_URI_CHARS = 2048;
9912
+ var SHARE_LINK_PROTOCOL = "lc-share/v1";
9913
+ var SHARE_RECOVERY_PROTOCOL = "lc-share-recovery/v1";
9914
+ var BASE64URL_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
9915
+ var BASE64URL_LOOKUP = (() => {
9916
+ const table = new Int16Array(128).fill(-1);
9917
+ for (let index = 0; index < BASE64URL_ALPHABET.length; index += 1) {
9918
+ table[BASE64URL_ALPHABET.charCodeAt(index)] = index;
9596
9919
  }
9597
- if (input.mode === "issuer-signed" && (input.credential !== void 0 || input.signingAuthority !== void 0)) {
9920
+ return table;
9921
+ })();
9922
+ var encodeBase64Url = /* @__PURE__ */ __name((bytes) => {
9923
+ let output = "";
9924
+ for (let index = 0; index < bytes.length; index += 3) {
9925
+ const first = bytes[index];
9926
+ const second = bytes[index + 1];
9927
+ const third = bytes[index + 2];
9928
+ output += BASE64URL_ALPHABET[first >> 2];
9929
+ output += BASE64URL_ALPHABET[(first & 3) << 4 | (second != null ? second : 0) >> 4];
9930
+ if (second === void 0) break;
9931
+ output += BASE64URL_ALPHABET[(second & 15) << 2 | (third != null ? third : 0) >> 6];
9932
+ if (third === void 0) break;
9933
+ output += BASE64URL_ALPHABET[third & 63];
9934
+ }
9935
+ return output;
9936
+ }, "encodeBase64Url");
9937
+ var decodeBase64Url = /* @__PURE__ */ __name((value) => {
9938
+ if (typeof value !== "string") return null;
9939
+ const output = new Uint8Array(Math.floor(value.length * 6 / 8));
9940
+ let bits = 0;
9941
+ let bitCount = 0;
9942
+ let outputIndex = 0;
9943
+ for (let index = 0; index < value.length; index += 1) {
9944
+ const code = value.charCodeAt(index);
9945
+ const digit = code < 128 ? BASE64URL_LOOKUP[code] : -1;
9946
+ if (digit < 0) return null;
9947
+ bits = bits << 6 | digit;
9948
+ bitCount += 6;
9949
+ if (bitCount >= 8) {
9950
+ bitCount -= 8;
9951
+ output[outputIndex] = bits >> bitCount & 255;
9952
+ outputIndex += 1;
9953
+ }
9954
+ }
9955
+ return output;
9956
+ }, "decodeBase64Url");
9957
+ var isCanonicalBase64Url = /* @__PURE__ */ __name((value, expectedBytes) => {
9958
+ if (typeof value !== "string") return false;
9959
+ if (expectedBytes !== void 0 && value.length !== Math.ceil(expectedBytes * 4 / 3))
9960
+ return false;
9961
+ const decoded = decodeBase64Url(value);
9962
+ if (decoded === null) return false;
9963
+ if (expectedBytes !== void 0 && decoded.length !== expectedBytes) return false;
9964
+ return encodeBase64Url(decoded) === value;
9965
+ }, "isCanonicalBase64Url");
9966
+ var utf8ByteLength = /* @__PURE__ */ __name((value) => new TextEncoder().encode(value).length, "utf8ByteLength");
9967
+ var canonicalBase64Url = /* @__PURE__ */ __name((bytes) => string().refine((value) => isCanonicalBase64Url(value, bytes), {
9968
+ message: `must be canonical base64url for exactly ${bytes} bytes`
9969
+ }), "canonicalBase64Url");
9970
+ var ShareLinkIdValidator = canonicalBase64Url(SHARE_LINK_ID_BYTES);
9971
+ var ShareContentKeyValidator = canonicalBase64Url(SHARE_CONTENT_KEY_BYTES);
9972
+ var ShareIvValidator = canonicalBase64Url(SHARE_IV_BYTES);
9973
+ var ShareCiphertextValidator = string().refine(
9974
+ (value) => {
9975
+ if (value.length > Math.ceil(MAX_SHARE_CIPHERTEXT_BYTES * 4 / 3)) return false;
9976
+ const decoded = decodeBase64Url(value);
9977
+ if (decoded === null) return false;
9978
+ if (encodeBase64Url(decoded) !== value) return false;
9979
+ return decoded.length >= SHARE_TAG_BYTES && decoded.length <= MAX_SHARE_CIPHERTEXT_BYTES;
9980
+ },
9981
+ {
9982
+ message: `must be canonical base64url decoding to ${SHARE_TAG_BYTES}..${MAX_SHARE_CIPHERTEXT_BYTES} bytes`
9983
+ }
9984
+ );
9985
+ var ShareEnvelopeValidator = object({
9986
+ v: literal(1),
9987
+ alg: literal("A256GCM"),
9988
+ iv: ShareIvValidator,
9989
+ ct: ShareCiphertextValidator
9990
+ }).strict();
9991
+ var safeVersion = number().int().min(1).max(__pow(2, 31) - 1);
9992
+ var safeCredentialIndex = number().int().min(0).max(MAX_VP_MEMBERS - 1);
9993
+ var ShareSelectionEntryValidator = object({ credentialIndex: safeCredentialIndex }).strict();
9994
+ var ShareEndorsementEntryValidator = object({ credentialIndex: safeCredentialIndex, targetCredentialIndex: safeCredentialIndex }).strict();
9995
+ var ShareSharerValidator = object({
9996
+ profileId: string().min(1).max(128),
9997
+ displayName: string().min(1).max(120),
9998
+ avatar: string().max(2048).optional()
9999
+ }).strict();
10000
+ var presentationShape = VPValidator.extend({
10001
+ verifiableCredential: VCValidator.array().min(1).max(MAX_VP_MEMBERS)
10002
+ });
10003
+ var hasBoundedPresentation = /* @__PURE__ */ __name((value) => {
10004
+ let credentialCount = 0;
10005
+ const ancestors = /* @__PURE__ */ new Set();
10006
+ const visit = /* @__PURE__ */ __name((node, depth) => {
10007
+ if (node === null || typeof node !== "object") return true;
10008
+ if (depth > 32 || ancestors.has(node)) return false;
10009
+ ancestors.add(node);
10010
+ try {
10011
+ for (const [key, child] of Object.entries(node)) {
10012
+ if (key === "verifiableCredential") {
10013
+ credentialCount += Array.isArray(child) ? child.length : 1;
10014
+ if (credentialCount > MAX_VP_MEMBERS) return false;
10015
+ }
10016
+ if (!visit(child, depth + 1)) return false;
10017
+ }
10018
+ return true;
10019
+ } finally {
10020
+ ancestors.delete(node);
10021
+ }
10022
+ }, "visit");
10023
+ return visit(value, 0);
10024
+ }, "hasBoundedPresentation");
10025
+ var ShareManifestPresentationValidator = custom(
10026
+ (value) => hasBoundedPresentation(value) && presentationShape.safeParse(value).success,
10027
+ { message: "invalid share presentation" }
10028
+ );
10029
+ var SharePayloadValidatorShape = object({
10030
+ protocol: literal(SHARE_LINK_PROTOCOL),
10031
+ shareId: ShareLinkIdValidator,
10032
+ contentVersion: safeVersion,
10033
+ createdAt: datetime(),
10034
+ sharer: ShareSharerValidator,
10035
+ presentation: ShareManifestPresentationValidator,
10036
+ selection: ShareSelectionEntryValidator.array().min(1).max(MAX_SELECTED_CREDENTIALS),
10037
+ endorsements: ShareEndorsementEntryValidator.array().max(MAX_ENDORSEMENTS).default([])
10038
+ }).strict();
10039
+ var classificationFailure = /* @__PURE__ */ __name((code, message, path = []) => ({ ok: false, code, message, path }), "classificationFailure");
10040
+ var readSignedClaimId = /* @__PURE__ */ __name((member) => {
10041
+ var _a2, _b;
10042
+ if (member === null || typeof member !== "object") return void 0;
10043
+ const record = member;
10044
+ const claim = (_a2 = record.credentialSubject) != null ? _a2 : record.endorsement;
10045
+ if (claim === null || typeof claim !== "object") return void 0;
10046
+ const claimRecord = claim;
10047
+ const nested = claimRecord.endorsement;
10048
+ const nestedId = nested !== null && typeof nested === "object" ? nested.id : void 0;
10049
+ return (_b = claimRecord.id) != null ? _b : nestedId;
10050
+ }, "readSignedClaimId");
10051
+ var classifyShareManifest = /* @__PURE__ */ __name((payload) => {
10052
+ var _a2, _b;
10053
+ const members = (_a2 = payload.presentation) == null ? void 0 : _a2.verifiableCredential;
10054
+ if (!Array.isArray(members) || members.length === 0) {
10055
+ return classificationFailure("NO_PRESENTATION_MEMBERS", "presentation has no credentials");
10056
+ }
10057
+ if (members.length > MAX_VP_MEMBERS) {
10058
+ return classificationFailure(
10059
+ "TOO_MANY_VP_MEMBERS",
10060
+ `presentation has ${members.length} members, over the ${MAX_VP_MEMBERS} bound`
10061
+ );
10062
+ }
10063
+ const selection = payload.selection;
10064
+ const endorsements = (_b = payload.endorsements) != null ? _b : [];
10065
+ if (!Array.isArray(selection) || selection.length < 1 || selection.length > MAX_SELECTED_CREDENTIALS) {
10066
+ return classificationFailure("BAD_SELECTION", "selection must contain 1..50 entries");
10067
+ }
10068
+ if (!Array.isArray(endorsements) || endorsements.length > MAX_ENDORSEMENTS) {
10069
+ return classificationFailure(
10070
+ "BAD_ENDORSEMENTS",
10071
+ "endorsements must contain at most 200 entries"
10072
+ );
10073
+ }
10074
+ const selectedIndices = [];
10075
+ const selected = /* @__PURE__ */ new Set();
10076
+ for (let index = 0; index < selection.length; index += 1) {
10077
+ const entry = selection[index];
10078
+ const credentialIndex = entry == null ? void 0 : entry.credentialIndex;
10079
+ if (!Number.isSafeInteger(credentialIndex) || credentialIndex < 0 || credentialIndex >= members.length) {
10080
+ return classificationFailure(
10081
+ "SELECTION_INDEX_OUT_OF_BOUNDS",
10082
+ `selection[${index}].credentialIndex is out of bounds`,
10083
+ ["selection", index, "credentialIndex"]
10084
+ );
10085
+ }
10086
+ if (selected.has(credentialIndex)) {
10087
+ return classificationFailure(
10088
+ "SELECTION_INDEX_DUPLICATE",
10089
+ `selection[${index}].credentialIndex is duplicated`,
10090
+ ["selection", index, "credentialIndex"]
10091
+ );
10092
+ }
10093
+ selected.add(credentialIndex);
10094
+ selectedIndices.push(credentialIndex);
10095
+ }
10096
+ const classified = new Set(selected);
10097
+ const endorsementIndices = [];
10098
+ for (let index = 0; index < endorsements.length; index += 1) {
10099
+ const entry = endorsements[index];
10100
+ const credentialIndex = entry == null ? void 0 : entry.credentialIndex;
10101
+ const targetIndex = entry == null ? void 0 : entry.targetCredentialIndex;
10102
+ if (!Number.isSafeInteger(credentialIndex) || credentialIndex < 0 || credentialIndex >= members.length) {
10103
+ return classificationFailure(
10104
+ "ENDORSEMENT_INDEX_OUT_OF_BOUNDS",
10105
+ `endorsements[${index}].credentialIndex is out of bounds`,
10106
+ ["endorsements", index, "credentialIndex"]
10107
+ );
10108
+ }
10109
+ if (classified.has(credentialIndex)) {
10110
+ return classificationFailure(
10111
+ "VP_MEMBER_CLASSIFIED_TWICE",
10112
+ `endorsements[${index}].credentialIndex was already classified`,
10113
+ ["endorsements", index, "credentialIndex"]
10114
+ );
10115
+ }
10116
+ if (!selected.has(targetIndex)) {
10117
+ return classificationFailure(
10118
+ "ENDORSEMENT_TARGET_NOT_SELECTED",
10119
+ `endorsements[${index}].targetCredentialIndex must reference a selected credential`,
10120
+ ["endorsements", index, "targetCredentialIndex"]
10121
+ );
10122
+ }
10123
+ const referenced = readSignedClaimId(members[credentialIndex]);
10124
+ const target = members[targetIndex];
10125
+ const targetId = target !== null && typeof target === "object" ? target.id : void 0;
10126
+ if (typeof referenced !== "string" || typeof targetId !== "string" || referenced !== targetId) {
10127
+ return classificationFailure(
10128
+ "ENDORSEMENT_TARGET_UNBOUND",
10129
+ `endorsements[${index}] claim does not reference the target credential id`,
10130
+ ["endorsements", index]
10131
+ );
10132
+ }
10133
+ classified.add(credentialIndex);
10134
+ endorsementIndices.push(credentialIndex);
10135
+ }
10136
+ if (classified.size !== members.length) {
10137
+ return classificationFailure(
10138
+ "UNCLASSIFIED_VP_MEMBER",
10139
+ "every presentation member must be classified exactly once",
10140
+ ["presentation", "verifiableCredential"]
10141
+ );
10142
+ }
10143
+ return {
10144
+ ok: true,
10145
+ classification: { selectedIndices, endorsementIndices, memberCount: members.length }
10146
+ };
10147
+ }, "classifyShareManifest");
10148
+ SharePayloadValidatorShape.superRefine((payload, ctx) => {
10149
+ const result = classifyShareManifest(payload);
10150
+ if (!result.ok) {
9598
10151
  ctx.addIssue({
9599
10152
  code: "custom",
9600
- path: ["mode"],
9601
- message: "issuer-signed publication cannot include signing-authority fields"
10153
+ message: result.message,
10154
+ path: result.path,
10155
+ params: { shareLinkCode: result.code }
9602
10156
  });
9603
10157
  }
9604
- if (input.mode === "signing-authority") {
9605
- if (input.signedCredential !== void 0) {
9606
- ctx.addIssue({
9607
- code: "custom",
9608
- path: ["signedCredential"],
9609
- message: "signing-authority publication cannot include signedCredential"
9610
- });
9611
- }
9612
- if (!input.credential) {
10158
+ });
10159
+ var ShareRecoverySelectionValidator = object({
10160
+ ref: string().min(1).max(MAX_SHARE_SOURCE_URI_CHARS),
10161
+ order: number().int().min(0).max(MAX_SELECTED_CREDENTIALS - 1)
10162
+ }).strict();
10163
+ var ShareRecoveryEndorsementValidator = object({ targetRef: string().min(1).max(MAX_SHARE_SOURCE_URI_CHARS) }).strict();
10164
+ object({
10165
+ protocol: literal(SHARE_RECOVERY_PROTOCOL),
10166
+ shareId: ShareLinkIdValidator,
10167
+ ownerProfileId: string().min(1).max(128),
10168
+ createdAt: datetime(),
10169
+ latest: object({ contentVersion: safeVersion, key: ShareContentKeyValidator }).strict(),
10170
+ selection: ShareRecoverySelectionValidator.array().min(1).max(MAX_SELECTED_CREDENTIALS),
10171
+ endorsements: ShareRecoveryEndorsementValidator.array().max(MAX_ENDORSEMENTS).default([])
10172
+ }).strict().superRefine((recovery, ctx) => {
10173
+ const orders = /* @__PURE__ */ new Set();
10174
+ recovery.selection.forEach((entry, index) => {
10175
+ if (entry.order >= recovery.selection.length) {
9613
10176
  ctx.addIssue({
9614
10177
  code: "custom",
9615
- path: ["credential"],
9616
- message: "credential is required for signing-authority publication"
10178
+ message: "order must be within the selection bounds",
10179
+ path: ["selection", index, "order"]
9617
10180
  });
9618
10181
  }
9619
- if (!input.signingAuthority) {
10182
+ if (orders.has(entry.order)) {
9620
10183
  ctx.addIssue({
9621
10184
  code: "custom",
9622
- path: ["signingAuthority"],
9623
- message: "signingAuthority is required for signing-authority publication"
10185
+ message: "order must be unique within the selection",
10186
+ path: ["selection", index, "order"]
9624
10187
  });
9625
10188
  }
9626
- }
9627
- });
9628
- var PublishCredentialRefreshNotificationValidator = _enum([
9629
- "queued",
9630
- "suppressed",
9631
- "not-applicable",
9632
- /** Publication succeeded, but the post-commit notification enqueue must be retried. */
9633
- "delivery-failed"
9634
- ]);
9635
- object({
9636
- refreshId: string().min(1),
9637
- version: number().int().positive(),
9638
- publishedAt: string().min(1),
9639
- notification: PublishCredentialRefreshNotificationValidator
9640
- });
9641
- var CredentialRefreshVersionMetadataValidator = object({
9642
- version: number().int().positive(),
9643
- publishedAt: string().min(1),
9644
- effectiveAt: string().optional(),
9645
- etag: string().optional(),
9646
- signingMode: CredentialRefreshSigningModeValidator.optional(),
9647
- updateSummary: string().optional()
10189
+ orders.add(entry.order);
10190
+ });
9648
10191
  });
9649
- object({
9650
- refreshId: string().min(1),
9651
- cursor: string().optional(),
9652
- limit: number().int().positive().optional()
10192
+ var ShareOwnerRecoveryValidator = JWEValidator.refine(
10193
+ (value) => utf8ByteLength(JSON.stringify(value)) <= MAX_SHARE_RECOVERY_JWE_BYTES,
10194
+ { message: `serialized recovery JWE must be at most ${MAX_SHARE_RECOVERY_JWE_BYTES} bytes` }
10195
+ );
10196
+ var ShareLinkStatusValidator = _enum(["pending", "active", "stopped"]);
10197
+ var ShareContentStateValidator = _enum(["staging", "finalized", "content_missing"]);
10198
+ var ShareLinkValidator = object({
10199
+ id: ShareLinkIdValidator,
10200
+ title: string().min(1).max(120),
10201
+ note: string().max(500).optional(),
10202
+ selectedCount: number().int().min(1).max(MAX_SELECTED_CREDENTIALS),
10203
+ version: safeVersion,
10204
+ contentVersion: safeVersion,
10205
+ status: ShareLinkStatusValidator,
10206
+ contentState: ShareContentStateValidator,
10207
+ createdAt: datetime(),
10208
+ updatedAt: datetime(),
10209
+ expiresAt: datetime().nullable(),
10210
+ stoppedAt: datetime().nullable(),
10211
+ lastViewedAt: datetime().nullable(),
10212
+ viewCount: number().int().min(0).optional(),
10213
+ passcodeProtected: boolean(),
10214
+ notifyOnView: boolean(),
10215
+ minorPolicy: object({
10216
+ isMinor: boolean().nullable(),
10217
+ policyResolved: boolean(),
10218
+ defaultExpiryDays: union([literal(30), literal(365)]),
10219
+ viewCountingEnabled: boolean()
10220
+ }),
10221
+ /**
10222
+ * Guarded application/API URL for the content. Optional because owner APIs in
10223
+ * D1 have no public resolve/content endpoint yet; it must never be a
10224
+ * LearnCloud object URL or carry a fabricated decryption key.
10225
+ */
10226
+ contentUrl: string().optional()
9653
10227
  });
10228
+ var clientRequestId = string().uuid();
9654
10229
  object({
9655
- records: CredentialRefreshVersionMetadataValidator.array(),
9656
- hasMore: boolean(),
9657
- cursor: string().optional()
9658
- });
10230
+ id: ShareLinkIdValidator,
10231
+ clientRequestId,
10232
+ title: string().min(1).max(120),
10233
+ note: string().max(500).optional(),
10234
+ expiresAt: datetime().nullable().optional(),
10235
+ passcode: string().min(8).max(64).optional(),
10236
+ notifyOnView: boolean().default(false),
10237
+ selectedCount: number().int().min(1).max(MAX_SELECTED_CREDENTIALS),
10238
+ contentVersion: literal(1),
10239
+ envelope: ShareEnvelopeValidator,
10240
+ ownerEncryptedRecovery: ShareOwnerRecoveryValidator
10241
+ }).strict();
9659
10242
  object({
9660
- challenge: string().min(1),
9661
- expiresAt: string().min(1),
9662
- domain: string().optional(),
9663
- scheme: literal("LearnCardDIDAuth").optional()
9664
- });
9665
- var PublicCredentialRefreshEnvelopeValidator = object({
9666
- format: literal("vc"),
9667
- credential: VCValidator,
9668
- etag: string().optional()
9669
- });
9670
- var JweCredentialRefreshEnvelopeValidator = object({
9671
- format: literal("jwe"),
9672
- jwe: JWEValidator,
9673
- etag: string().optional(),
9674
- /** Present on LearnCard-managed endpoints; optional for interoperable JWE services. */
9675
- version: number().int().positive().optional()
10243
+ id: ShareLinkIdValidator,
10244
+ expectedVersion: safeVersion,
10245
+ clientRequestId,
10246
+ title: string().min(1).max(120).optional(),
10247
+ note: string().max(500).nullable().optional(),
10248
+ expiresAt: datetime().nullable().optional(),
10249
+ /** Omitted preserves the current passcode, null removes it, and a string replaces it. */
10250
+ passcode: string().min(8).max(64).nullable().optional(),
10251
+ notifyOnView: boolean().optional(),
10252
+ contentVersion: safeVersion.optional(),
10253
+ selectedCount: number().int().min(1).max(MAX_SELECTED_CREDENTIALS).optional(),
10254
+ envelope: ShareEnvelopeValidator.optional(),
10255
+ ownerEncryptedRecovery: ShareOwnerRecoveryValidator.optional()
10256
+ }).strict().superRefine((value, ctx) => {
10257
+ const provided = [
10258
+ value.contentVersion,
10259
+ value.selectedCount,
10260
+ value.envelope,
10261
+ value.ownerEncryptedRecovery
10262
+ ].filter((field) => field !== void 0).length;
10263
+ if (provided !== 0 && provided !== 4) {
10264
+ ctx.addIssue({
10265
+ code: "custom",
10266
+ message: "content replacement requires contentVersion, selectedCount, envelope and ownerEncryptedRecovery together"
10267
+ });
10268
+ }
9676
10269
  });
9677
- discriminatedUnion("format", [
9678
- PublicCredentialRefreshEnvelopeValidator,
9679
- JweCredentialRefreshEnvelopeValidator
9680
- ]);
9681
- var CredentialRefreshFailureCodeValidator = _enum([
9682
- "UNAVAILABLE",
9683
- "TIMEOUT",
9684
- "UNSUPPORTED_SERVICE",
9685
- "UNAUTHORIZED",
9686
- "MALFORMED_RESPONSE",
9687
- "INVALID_PROOF",
9688
- "ISSUER_MISMATCH",
9689
- "ID_MISMATCH",
9690
- "ROLLBACK",
9691
- "REVOKED",
9692
- "UNSAFE_ENDPOINT"
10270
+ object({ id: ShareLinkIdValidator }).strict();
10271
+ object({ id: ShareLinkIdValidator, operationId: string().uuid() }).strict();
10272
+ discriminatedUnion("status", [
10273
+ object({ status: literal("completed"), share: ShareLinkValidator }).strict(),
10274
+ object({
10275
+ status: literal("pending"),
10276
+ id: ShareLinkIdValidator,
10277
+ operationId: string().uuid()
10278
+ }).strict()
9693
10279
  ]);
9694
- var CredentialRefreshUpdatedResultValidator = object({
9695
- status: literal("updated"),
9696
- credential: VCValidator,
9697
- etag: string().optional(),
9698
- managedVersion: number().int().positive().optional()
9699
- });
9700
- var CredentialRefreshUnchangedResultValidator = object({
9701
- status: literal("unchanged"),
9702
- checkedAt: string().min(1),
9703
- etag: string().optional()
9704
- });
9705
- var CredentialRefreshUnsupportedResultValidator = object({
9706
- status: literal("unsupported")
9707
- });
9708
- var CredentialRefreshFailedResultValidator = object({
9709
- status: literal("failed"),
9710
- code: CredentialRefreshFailureCodeValidator,
9711
- retryable: boolean()
9712
- });
9713
10280
  discriminatedUnion("status", [
9714
- CredentialRefreshUpdatedResultValidator,
9715
- CredentialRefreshUnchangedResultValidator,
9716
- CredentialRefreshUnsupportedResultValidator,
9717
- CredentialRefreshFailedResultValidator
10281
+ object({ status: literal("found"), share: ShareLinkValidator }).strict(),
10282
+ object({
10283
+ status: literal("pending"),
10284
+ id: ShareLinkIdValidator,
10285
+ operationId: string().uuid()
10286
+ }).strict(),
10287
+ object({ status: literal("not_found"), id: ShareLinkIdValidator }).strict()
9718
10288
  ]);
10289
+ object({ recovery: ShareOwnerRecoveryValidator }).strict();
10290
+ object({
10291
+ id: ShareLinkIdValidator,
10292
+ contentVersion: safeVersion,
10293
+ envelope: ShareEnvelopeValidator
10294
+ }).strict();
10295
+ object({
10296
+ id: ShareLinkIdValidator,
10297
+ /** Sent only in a POST body; it must never be placed in a share URL. */
10298
+ passcode: string().min(4).max(64).optional()
10299
+ }).strict();
10300
+ discriminatedUnion("state", [
10301
+ object({
10302
+ state: literal("passcode_required"),
10303
+ id: ShareLinkIdValidator
10304
+ }).strict(),
10305
+ object({ state: literal("try_later"), id: ShareLinkIdValidator }).strict(),
10306
+ object({
10307
+ state: literal("active"),
10308
+ id: ShareLinkIdValidator,
10309
+ title: string().max(120),
10310
+ note: string().max(500).optional(),
10311
+ selectedCount: number().int().min(1).max(MAX_SELECTED_CREDENTIALS),
10312
+ contentVersion: safeVersion,
10313
+ contentUrl: string(),
10314
+ sharer: object({
10315
+ displayName: string().max(120),
10316
+ avatar: string().max(2048).optional()
10317
+ }),
10318
+ createdAt: datetime(),
10319
+ updatedAt: datetime(),
10320
+ expiresAt: datetime().nullable()
10321
+ }).strict(),
10322
+ object({
10323
+ state: literal("expired"),
10324
+ id: ShareLinkIdValidator,
10325
+ expiresAt: datetime()
10326
+ }).strict(),
10327
+ object({
10328
+ state: literal("stopped"),
10329
+ id: ShareLinkIdValidator,
10330
+ stoppedAt: datetime()
10331
+ }).strict(),
10332
+ object({ state: literal("not_found"), id: ShareLinkIdValidator }).strict()
10333
+ ]);
10334
+ object({
10335
+ limit: number().int().min(1).max(50).default(25),
10336
+ cursor: string().max(512).optional()
10337
+ }).strict();
10338
+ PaginationResponseValidator.extend({
10339
+ records: ShareLinkValidator.array()
10340
+ });
10341
+ object({
10342
+ receipt: string().min(22).max(128).regex(/^[A-Za-z0-9_-]+$/)
10343
+ }).strict();
10344
+ object({ ok: literal(true) }).strict();
10345
+ object({
10346
+ id: ShareLinkIdValidator,
10347
+ contentVersion: safeVersion,
10348
+ envelope: ShareEnvelopeValidator,
10349
+ contentUrl: string(),
10350
+ receipt: string().min(22).max(128).regex(/^[A-Za-z0-9_-]+$/)
10351
+ }).strict();
9719
10352
 
9720
10353
  export { VerificationStatusEnum as V };
9721
- //# sourceMappingURL=types.esm-35d4f5e9.js.map
10354
+ //# sourceMappingURL=types.esm-b9cb7331.js.map