@domino-sdk/relay 1.0.0-next.9 → 1.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.
Files changed (59) hide show
  1. package/README.md +1 -1
  2. package/dist/activity-DeKJsRry.d.ts +9112 -0
  3. package/dist/authoring.d.ts +1027 -233
  4. package/dist/authoring.js +478 -277
  5. package/dist/automatic-outcomes-B1xrETxm.d.ts +758 -0
  6. package/dist/avatar.d.ts +2 -2
  7. package/dist/browser-DFe7sWSN.d.ts +4154 -0
  8. package/dist/browser.d.ts +11 -2613
  9. package/dist/browser.js +8 -6
  10. package/dist/{integrations-Ba5TtqTv.d.ts → capability-error-DNMwKmlL.d.ts} +124 -76
  11. package/dist/{chunk-PHU5VDLR.js → chunk-36HTX2BM.js} +389 -169
  12. package/dist/chunk-6QJ3LADK.js +112 -0
  13. package/dist/{chunk-4LBUTHD6.js → chunk-BGGKNIRP.js} +1 -1
  14. package/dist/chunk-EYH5RDIE.js +496 -0
  15. package/dist/chunk-GQKYAQM6.js +84 -0
  16. package/dist/chunk-GUP7YRR4.js +42 -0
  17. package/dist/{chunk-X2F2RAR3.js → chunk-GZ6FJAXN.js} +380 -128
  18. package/dist/chunk-JON5SESL.js +2986 -0
  19. package/dist/chunk-MC6V6VMG.js +49 -0
  20. package/dist/chunk-NPGENI7K.js +37 -0
  21. package/dist/chunk-VFHHLN6A.js +284 -0
  22. package/dist/chunk-WJSSJ7AF.js +151 -0
  23. package/dist/{chunk-7Q4BGGT6.js → chunk-XFMSUPNS.js} +1 -1
  24. package/dist/{chunk-P6FK43GG.js → chunk-ZVIRG24J.js} +145 -42
  25. package/dist/{client-CT4-S5vc.d.ts → client-XiuFnug_.d.ts} +2161 -615
  26. package/dist/{submission-input-0OOGaq8c.d.ts → groups-Ck-OxzjD.d.ts} +916 -1139
  27. package/dist/identity-integration-GxAHdKR2.d.ts +58 -0
  28. package/dist/images-Dv-P5VBw.d.ts +234 -0
  29. package/dist/index.d.ts +13 -9
  30. package/dist/index.js +17 -6
  31. package/dist/internal.d.ts +82 -44
  32. package/dist/internal.js +43 -89
  33. package/dist/offers-Cy-e4o5x.d.ts +431 -0
  34. package/dist/{pages-D3titw5B.d.ts → outcomes-kVB-Juzs.d.ts} +2157 -1448
  35. package/dist/pages-BBYD21IE.d.ts +359 -0
  36. package/dist/participant-rewards-3duLb8YJ.d.ts +668 -0
  37. package/dist/portal-proxy.js +22 -4
  38. package/dist/{profiles-DDMFBRKe.d.ts → profiles-D2aFcOxu.d.ts} +15 -15
  39. package/dist/react/index.d.ts +3038 -1029
  40. package/dist/react/index.js +1627 -779
  41. package/dist/request-error-DWduJCGV.d.ts +62 -0
  42. package/dist/schema-DfJzH2ci.d.ts +5644 -0
  43. package/dist/schema.d.ts +15 -4168
  44. package/dist/schema.js +310 -81
  45. package/dist/server/index.d.ts +81498 -0
  46. package/dist/server/index.js +2520 -0
  47. package/dist/{streaks-CwGReWGt.d.ts → streaks-CWyq8Px5.d.ts} +2 -4
  48. package/dist/submission-input-BZkm6ohU.d.ts +290 -0
  49. package/dist/vite.d.ts +1 -1
  50. package/dist/vite.js +1 -0
  51. package/dist/{wallet-BGOfFkG9.d.ts → wallet-YssWxGg8.d.ts} +35 -38
  52. package/package.json +8 -2
  53. package/dist/chunk-QR7ZA2BJ.js +0 -257
  54. package/dist/chunk-YYD4QUBO.js +0 -2348
  55. package/dist/chunk-ZWY3R6B3.js +0 -26
  56. package/dist/collection-BGneJ6Bk.d.ts +0 -114
  57. package/dist/images-BTgk6OmC.d.ts +0 -1564
  58. package/dist/point-ledgers-iS00Z_v0.d.ts +0 -37
  59. package/dist/schema-Di3aLSiK.d.ts +0 -3532
@@ -1,59 +1,104 @@
1
1
  import {
2
+ RequestError,
3
+ isRequestError
4
+ } from "./chunk-NPGENI7K.js";
5
+ import {
6
+ authoringIdentityShape,
7
+ calendarPeriodSchema,
2
8
  contentMetricSchema,
3
9
  contentMetricsSchema,
4
10
  identifier,
5
11
  pageCursorSchema,
6
12
  pointsRewardSchema,
13
+ refuseWindowTimeZone,
14
+ resourceHandle,
15
+ rewardKey,
7
16
  tierRewardSchema
8
- } from "./chunk-YYD4QUBO.js";
17
+ } from "./chunk-JON5SESL.js";
9
18
 
10
- // src/authoring-identity.ts
19
+ // src/point-ledgers.ts
11
20
  import { z } from "zod";
12
- var authoringIdentityShape = {
13
- key: identifier.optional(),
14
- id: identifier.optional()
21
+ var pointLedgerPropertiesSchema = z.object({
22
+ name: z.string().trim().min(1).max(120),
23
+ description: z.string().trim().max(1e3).default("")
24
+ }).strict();
25
+ var createPointLedgerSchema = pointLedgerPropertiesSchema.extend({ actionId: identifier, key: identifier.optional() }).strict();
26
+ var pointLedgerSchema = pointLedgerPropertiesSchema.extend({
27
+ id: identifier
28
+ });
29
+ var managedPointLedgerSchema = pointLedgerSchema.extend({
30
+ archivedAt: z.number().int().nonnegative().nullable()
31
+ });
32
+ var pointLedgerDeclarationSchema = pointLedgerPropertiesSchema.extend({ key: identifier }).strict();
33
+ var pointLedgerArtifactSchema = z.union([
34
+ pointLedgerDeclarationSchema,
35
+ z.object({ code: z.string().min(1).max(2e6) }).strict()
36
+ ]);
37
+ var pointLedgerReferenceSchema = z.object({
38
+ id: identifier,
39
+ key: identifier.nullable(),
40
+ name: z.string()
41
+ });
42
+ var points = z.number().int().safe();
43
+ var pointBalanceSchema = z.object({
44
+ ledger: pointLedgerReferenceSchema,
45
+ balance: points,
46
+ available: points
47
+ });
48
+ var pointBalancesSchema = z.object({
49
+ items: z.array(pointBalanceSchema)
50
+ });
51
+ var PointEntryKind = {
52
+ /** Points a quest completion, an engagement settlement or an operator awarded. */
53
+ Award: "award",
54
+ /** Points the member spent. */
55
+ Spend: "spend",
56
+ /** A correction in either direction, by an operator or a referral payout. */
57
+ Adjust: "adjust",
58
+ /** Undoes part or all of an award or a positive adjustment (`reverses`). */
59
+ Reverse: "reverse"
15
60
  };
16
- function validateAuthoringIdentity(value, ctx) {
17
- if (!value.key && !value.id) {
18
- ctx.addIssue({
19
- code: "custom",
20
- path: ["key"],
21
- message: "Provide an authoring key. Legacy id is also accepted."
22
- });
23
- }
24
- if (value.key && value.id && value.key !== value.id) {
25
- ctx.addIssue({
26
- code: "custom",
27
- path: ["key"],
28
- message: "id and key must match. Keep the existing authoring name to preserve identity."
29
- });
30
- }
31
- }
32
- function normalizeAuthoringIdentity(value) {
33
- const { id, key, ...properties } = value;
34
- return { ...properties, key: identifier.parse(key ?? id) };
35
- }
36
- var identitySchema = z.object(authoringIdentityShape).superRefine(validateAuthoringIdentity).transform(normalizeAuthoringIdentity);
37
- var authoringKey = (input) => identitySchema.parse(input).key;
61
+ var pointEntryKindSchema = z.string().min(1).max(64);
62
+ var pointEntrySchema = z.object({
63
+ id: identifier,
64
+ amount: points,
65
+ kind: pointEntryKindSchema,
66
+ /** When the entry took effect, in epoch milliseconds. A reversal keeps its source's. */
67
+ at: points.nonnegative(),
68
+ quest: identifier.nullable(),
69
+ reverses: identifier.nullable()
70
+ });
71
+ var pointHistoryQuerySchema = z.strictObject({
72
+ ledger: identifier,
73
+ cursor: pageCursorSchema.optional()
74
+ });
75
+ var pointHistoryPageSchema = z.object({
76
+ items: z.array(pointEntrySchema),
77
+ nextCursor: pageCursorSchema.nullable()
78
+ });
38
79
 
39
80
  // src/engagement.ts
40
81
  import { z as z2 } from "zod";
41
82
  var amount = z2.number().int().safe().nonnegative();
83
+ var engagementBudgetSchema = z2.strictObject({
84
+ scope: z2.enum(["member", "project"]),
85
+ period: calendarPeriodSchema,
86
+ limit: amount
87
+ });
42
88
  var engagementDefinitionSchema = z2.strictObject({
43
89
  key: identifier,
44
90
  qualifiedBy: identifier,
45
91
  balance: identifier,
46
- metrics: z2.array(contentMetricSchema).min(1).max(6).refine(
92
+ metrics: z2.array(contentMetricSchema).min(1).max(10).refine(
47
93
  (metrics) => new Set(metrics).size === metrics.length,
48
94
  "Metrics must be unique"
49
95
  ),
50
96
  baseline: z2.literal("historical"),
51
97
  maxAgeMs: z2.number().int().positive().max(864e5).default(36e5),
52
- budget: z2.strictObject({
53
- projectDaily: amount.optional(),
54
- memberDaily: amount.optional(),
55
- projectLifetime: amount.optional()
56
- }).default({})
98
+ budgets: z2.array(engagementBudgetSchema).max(8).default([]).refine(
99
+ (budgets) => new Set(budgets.map((b) => b.scope + ":" + b.period)).size === budgets.length,
100
+ "Give each scope and period one budget"
101
+ )
57
102
  });
58
103
  var engagementScoreInputSchema = z2.strictObject({
59
104
  metrics: contentMetricsSchema,
@@ -174,32 +219,6 @@ var engagementDeploymentEntrySchema = z2.discriminatedUnion("kind", [
174
219
  })
175
220
  ]);
176
221
 
177
- // src/request-error.ts
178
- var requestErrorBrand = /* @__PURE__ */ Symbol.for("@domino-sdk/relay.RequestError");
179
- function isRequestError(value) {
180
- return typeof value === "object" && value !== null && value[requestErrorBrand] === true;
181
- }
182
- var RequestError = class extends Error {
183
- name = "RequestError";
184
- [requestErrorBrand] = true;
185
- kind;
186
- uncertain;
187
- status;
188
- code;
189
- operationId;
190
- /** `replay` when there is an `operationId`, else `reconcile`; only when `uncertain`. */
191
- recovery;
192
- constructor(message, details) {
193
- super(message, details.cause === void 0 ? {} : { cause: details.cause });
194
- this.kind = details.kind;
195
- this.uncertain = details.uncertain ?? false;
196
- this.status = details.status;
197
- this.code = details.code;
198
- this.operationId = details.operationId;
199
- this.recovery = this.uncertain ? details.operationId ? "replay" : "reconcile" : void 0;
200
- }
201
- };
202
-
203
222
  // src/errors.ts
204
223
  import { z as z3 } from "zod";
205
224
  var RelayErrorCode = {
@@ -221,18 +240,45 @@ var RelayErrorCode = {
221
240
  NotFound: "not-found",
222
241
  /** The quest has no failed attempt the member can retry. */
223
242
  RetryUnavailable: "retry-unavailable",
224
- /** Durable submission storage is missing, blocked or unreadable. */
243
+ /**
244
+ * Durable submission storage is missing, blocked or unreadable. Nothing was lost: call the
245
+ * handle's `status()` or `resume()` again once storage is available.
246
+ */
225
247
  SubmissionStorage: "submission-storage",
248
+ /** Browser storage is full, so submission progress was not saved. Free space, then resume. */
249
+ SubmissionStorageQuota: "submission-storage-quota",
226
250
  /** The saved submission is in a state that does not allow this action. */
227
251
  SubmissionConflict: "submission-conflict",
228
252
  /** The quest changed since the member saw it; review it before submitting again. */
229
253
  QuestUpdated: "quest-updated",
254
+ /** Wait for the deferred attempt before submitting another action. */
255
+ AttemptPending: "attempt-pending",
230
256
  /** The quiz changed since the member answered it. */
231
257
  StaleQuiz: "stale-quiz",
232
258
  /** Relay refused the submitted evidence. */
233
259
  InvalidSubmission: "invalid-submission",
234
260
  /** A page cursor Relay cannot read; start again from the first page. */
235
261
  InvalidCursor: "invalid-cursor",
262
+ /** No point ledger in the project has the key or ID the call named. */
263
+ PointLedgerNotFound: "point-ledger-not-found",
264
+ /** The member has not joined this project, so it holds no points here. */
265
+ NotJoined: "not-joined",
266
+ /** The quest or campaign is not open at this time. */
267
+ OutsideWindow: "outside-window",
268
+ /** The signed-in member must enroll in the campaign first. */
269
+ EnrollmentRequired: "enrollment-required",
270
+ /** The quest's current reward budget has no remaining capacity. */
271
+ BudgetExhausted: "budget-exhausted",
272
+ /** No published offer has the key or ID the call named. */
273
+ OfferNotFound: "offer-not-found",
274
+ /** The operator paused this offer. */
275
+ OfferPaused: "offer-paused",
276
+ /** This member has already used the offer's allowed number of redemptions. */
277
+ OfferLimitReached: "offer-limit-reached",
278
+ /** No declared units remain. */
279
+ OfferOutOfStock: "offer-out-of-stock",
280
+ /** The participant's available point balance is below the offer price. */
281
+ InsufficientPoints: "insufficient-points",
236
282
  /** A wallet signer failed or the member refused to sign; `cause` is the wallet's own error. */
237
283
  WalletSigner: "wallet-signer"
238
284
  };
@@ -243,13 +289,22 @@ function isRelayError(value) {
243
289
  var RelayError = class extends RequestError {
244
290
  name = "RelayError";
245
291
  [relayErrorBrand] = true;
246
- /** Prerequisite quests the member has not completed, when Relay refused for that reason. */
292
+ /** Prerequisites the member does not currently meet, when Relay refused for that reason. */
247
293
  missing;
248
294
  constructor(message, details) {
249
295
  super(message, details);
250
296
  this.missing = details.missing ?? [];
251
297
  }
252
298
  };
299
+ function asRelayError(cause, fallback = "Request failed") {
300
+ if (isRelayError(cause)) {
301
+ return cause;
302
+ }
303
+ return new RelayError(
304
+ cause instanceof Error && cause.message ? cause.message : fallback,
305
+ { kind: "client", cause }
306
+ );
307
+ }
253
308
  function clientError(message, code, details = {}) {
254
309
  return new RelayError(message, { ...details, kind: "client", code });
255
310
  }
@@ -409,45 +464,94 @@ var leaderboardWindowSchema = z5.discriminatedUnion("kind", [
409
464
  z5.object({ kind: z5.literal("all-time") }).strict(),
410
465
  z5.object({ kind: z5.literal("fixed"), start: timestamp, end: timestamp }).strict().refine((w) => w.end > w.start, "Window end must follow its start"),
411
466
  z5.object({ kind: z5.literal("rolling"), days: integer.min(1).max(3660) }).strict(),
467
+ // Not strict: boards published while a calendar window named its own `timeZone` keep reading,
468
+ // and the field drops on parse. The authoring schema refuses it.
412
469
  z5.object({
413
470
  kind: z5.literal("calendar"),
414
- period: z5.enum(["day", "week", "month"]),
415
- timeZone: z5.string().min(1).max(100).refine((zone) => {
416
- try {
417
- new Intl.DateTimeFormat("en", { timeZone: zone });
418
- return true;
419
- } catch {
420
- return false;
421
- }
422
- }, "Use an IANA timezone")
423
- }).strict()
471
+ /** The current day, week (ISO, starting on Monday) or month of the project calendar. */
472
+ period: calendarPeriodSchema.exclude(["lifetime"])
473
+ })
424
474
  ]);
425
475
  var periodScore = {
426
476
  window: leaderboardWindowSchema.default({ kind: "all-time" }),
427
477
  quests: z5.array(identifier).min(1).max(100).optional()
428
478
  };
429
- var leaderboardDefinitionSchema = z5.object({
479
+ var scoreSchema = z5.discriminatedUnion("kind", [
480
+ z5.object({ kind: z5.literal("balance") }).strict(),
481
+ z5.object({ kind: z5.literal("earned"), ...periodScore }).strict(),
482
+ z5.object({
483
+ kind: z5.literal("net"),
484
+ window: leaderboardWindowSchema.default({ kind: "all-time" })
485
+ }).strict()
486
+ ]).default({ kind: "balance" });
487
+ var leaderboardPrizeRewardSchema = z5.union([
488
+ pointsRewardSchema,
489
+ tierRewardSchema
490
+ ]);
491
+ var leaderboardPrizeSchema = z5.object({
492
+ ranks: z5.tuple([integer.positive(), integer.positive()]).refine(([first, last]) => last >= first, {
493
+ message: "Prize rank range must end at or after it starts"
494
+ }),
495
+ rewards: z5.array(leaderboardPrizeRewardSchema).min(1).max(20)
496
+ }).strict();
497
+ var leaderboardSettlementPolicySchema = z5.object({
498
+ at: z5.literal("window-end"),
499
+ ties: z5.enum(["shared", "earliest"]),
500
+ prizes: z5.array(leaderboardPrizeSchema).min(1).max(50)
501
+ }).strict().superRefine((policy, context) => {
502
+ for (const [index, prize] of policy.prizes.entries()) {
503
+ const keys = prize.rewards.map(rewardKey);
504
+ if (new Set(keys).size !== keys.length) {
505
+ context.addIssue({
506
+ code: "custom",
507
+ message: "A prize may grant each point ledger or tiered reward only once",
508
+ path: ["prizes", index, "rewards"]
509
+ });
510
+ }
511
+ }
512
+ for (let index = 1; index < policy.prizes.length; index++) {
513
+ const previous = policy.prizes[index - 1];
514
+ const current = policy.prizes[index];
515
+ if (current.ranks[0] <= previous.ranks[1]) {
516
+ context.addIssue({
517
+ code: "custom",
518
+ message: "Prize rank ranges must be ordered and must not overlap",
519
+ path: ["prizes", index, "ranks"]
520
+ });
521
+ }
522
+ }
523
+ });
524
+ var leaderboardDefinitionObject = z5.object({
430
525
  id: identifier,
431
526
  key: identifier.optional(),
432
527
  title: z5.string().trim().min(1).max(120),
433
528
  balance: identifier,
434
- score: z5.discriminatedUnion("kind", [
435
- z5.object({ kind: z5.literal("balance") }).strict(),
436
- z5.object({ kind: z5.literal("earned"), ...periodScore }).strict(),
437
- z5.object({
438
- kind: z5.literal("net"),
439
- window: leaderboardWindowSchema.default({ kind: "all-time" })
440
- }).strict()
441
- ]).default({ kind: "balance" }),
529
+ score: scoreSchema,
442
530
  access: z5.enum(["participants", "public"]).default("participants"),
443
- group: identifier.optional()
531
+ group: identifier.optional(),
532
+ settle: leaderboardSettlementPolicySchema.optional()
444
533
  }).strict();
445
- var leaderboardAuthoringSchema = leaderboardDefinitionSchema.omit({ id: true }).extend(authoringIdentityShape).strict().superRefine(validateAuthoringIdentity).transform(normalizeAuthoringIdentity);
534
+ var validateSettlementWindow = (definition, context) => {
535
+ if (definition.settle && (definition.score.kind === "balance" || !["fixed", "calendar"].includes(definition.score.window.kind))) {
536
+ context.addIssue({
537
+ code: "custom",
538
+ message: "Leaderboard prizes require an earned or net score with a fixed or calendar window",
539
+ path: ["settle"]
540
+ });
541
+ }
542
+ };
543
+ var leaderboardDefinitionSchema = leaderboardDefinitionObject.superRefine(validateSettlementWindow);
544
+ var leaderboardAuthoringSchema = leaderboardDefinitionObject.omit({ id: true }).extend({
545
+ ...authoringIdentityShape,
546
+ score: z5.preprocess(refuseWindowTimeZone, scoreSchema),
547
+ group: identifier.optional()
548
+ }).strict().superRefine(validateSettlementWindow);
446
549
  var leaderboardArtifactSchema = z5.union([
447
550
  leaderboardAuthoringSchema,
448
551
  z5.object({ code: z5.string().min(1).max(2e6) }).strict()
449
552
  ]);
450
553
  var publishedLeaderboardSchema = z5.object({
554
+ archivedAt: z5.number().int().nonnegative().nullable().optional(),
451
555
  version: identifier,
452
556
  definition: leaderboardDefinitionSchema,
453
557
  publishedAt: timestamp,
@@ -465,11 +569,8 @@ var leaderboardRowSchema = z5.object({
465
569
  name: z5.string(),
466
570
  score: integer,
467
571
  rank: integer.positive(),
468
- /**
469
- * The member's profile, where the project shows profiles to this viewer and the member has not
470
- * hidden theirs. Older servers omit it.
471
- */
472
- profile: profileSummarySchema.nullable().default(null)
572
+ /** The member's profile, where visible to this viewer and not hidden by the member. */
573
+ profile: profileSummarySchema.nullable()
473
574
  });
474
575
  var leaderboardPageSchema = z5.object({
475
576
  leaderboard: identifier,
@@ -574,6 +675,41 @@ var leaderboardGroupSchema = z5.object({
574
675
  included: z5.boolean(),
575
676
  reason: z5.string().trim().min(1).max(1e3)
576
677
  }).strict();
678
+ var leaderboardSettlementStatusSchema = z5.enum(["pending", "approved"]);
679
+ var leaderboardSettlementSummarySchema = z5.object({
680
+ id: identifier,
681
+ leaderboard: identifier,
682
+ version: identifier,
683
+ title: z5.string(),
684
+ period: z5.object({ start: timestamp, end: timestamp }),
685
+ ties: z5.enum(["shared", "earliest"]),
686
+ status: leaderboardSettlementStatusSchema,
687
+ total: integer.nonnegative(),
688
+ winners: integer.nonnegative(),
689
+ createdAt: timestamp,
690
+ approvedAt: timestamp.nullable(),
691
+ approvedBy: z5.string().nullable(),
692
+ approvalReason: z5.string().nullable()
693
+ });
694
+ var leaderboardSettlementRowSchema = z5.object({
695
+ member: identifier,
696
+ score: integer,
697
+ rank: integer.positive(),
698
+ position: integer.positive(),
699
+ scoredAt: timestamp,
700
+ prizes: z5.array(integer.nonnegative()),
701
+ completion: identifier.nullable(),
702
+ revokedAt: timestamp.nullable()
703
+ });
704
+ var leaderboardSettlementSchema = leaderboardSettlementSummarySchema.extend({
705
+ prizes: z5.array(leaderboardPrizeSchema),
706
+ excluded: z5.array(identifier),
707
+ rows: z5.array(leaderboardSettlementRowSchema)
708
+ });
709
+ var leaderboardSettlementApprovalSchema = z5.object({
710
+ actionId: identifier,
711
+ reason: z5.string().trim().min(1).max(500)
712
+ }).strict();
577
713
 
578
714
  // src/referrals.ts
579
715
  import { z as z6 } from "zod";
@@ -620,18 +756,22 @@ var referralDefinitionSchema = z6.object({
620
756
  }
621
757
  }
622
758
  });
623
- var referralAuthoringSchema = z6.object(referralDefinitionSchema.shape).omit({ id: true }).extend(authoringIdentityShape).strict().superRefine(validateAuthoringIdentity).superRefine((value, ctx) => {
759
+ var referralAuthoringSchema = z6.object(referralDefinitionSchema.shape).omit({ id: true }).extend({
760
+ ...authoringIdentityShape,
761
+ inviterGroup: identifier.optional()
762
+ }).strict().superRefine((value, ctx) => {
624
763
  for (const entries of [value.milestones, value.bonuses]) {
625
764
  if (new Set(entries.map((entry) => entry.id)).size !== entries.length) {
626
765
  ctx.addIssue({ code: "custom", message: "Rule keys must be unique" });
627
766
  }
628
767
  }
629
- }).transform(normalizeAuthoringIdentity);
768
+ });
630
769
  var referralArtifactSchema = z6.union([
631
770
  referralAuthoringSchema,
632
771
  z6.object({ code: z6.string().min(1).max(2e6) }).strict()
633
772
  ]);
634
773
  var publishedReferralSchema = z6.object({
774
+ archivedAt: z6.number().int().nonnegative().nullable().optional(),
635
775
  version: identifier,
636
776
  definition: referralDefinitionSchema,
637
777
  publishedAt: amount2,
@@ -727,41 +867,96 @@ var referralManagementSchema = z6.object({
727
867
  next: amount2.nullable()
728
868
  });
729
869
 
730
- // src/wallet.ts
870
+ // src/offers.ts
731
871
  import { z as z7 } from "zod";
732
- var solanaAddressSchema = z7.string().min(32).max(44).regex(/^[1-9A-HJ-NP-Za-km-z]+$/);
733
- var walletConnectionSchema = z7.object({
734
- chain: z7.literal("solana"),
735
- address: solanaAddressSchema,
736
- verifiedAt: z7.number().int().nonnegative(),
737
- revision: z7.number().int().positive()
738
- }).strict();
739
- var walletChallengeInputSchema = z7.object({
740
- chain: z7.literal("solana"),
741
- address: solanaAddressSchema
872
+ var quantity = z7.number().int().safe().nonnegative();
873
+ var offerPriceSchema = pointsRewardSchema.extend({
874
+ amount: z7.number().int().positive().max(1e4)
875
+ });
876
+ var offerLimitSchema = z7.object({ perMember: z7.number().int().positive().max(1e4) }).strict();
877
+ var offerDefinitionSchema = z7.object({
878
+ id: identifier,
879
+ key: identifier.optional(),
880
+ title: z7.string().trim().min(1).max(120),
881
+ price: offerPriceSchema,
882
+ reward: tierRewardSchema,
883
+ stock: quantity.max(1e6),
884
+ limit: offerLimitSchema.default({ perMember: 1 }),
885
+ enabled: z7.boolean().default(true)
742
886
  }).strict();
743
- var walletChallengeSchema = walletChallengeInputSchema.extend({
744
- id: z7.string().uuid(),
745
- message: z7.string(),
746
- expiresAt: z7.number()
747
- });
748
- var walletProofSchema = z7.object({
749
- challenge: z7.string().uuid(),
750
- signature: z7.string().min(64).max(88).regex(/^[1-9A-HJ-NP-Za-km-z]+$/)
887
+ var offerAuthoringSchema = offerDefinitionSchema.omit({ id: true, title: true, enabled: true }).extend({
888
+ ...authoringIdentityShape,
889
+ title: z7.string().trim().min(1).max(120).optional()
890
+ }).strict().transform((offer) => ({
891
+ ...offer,
892
+ title: offer.title ?? offer.reward.reward.title,
893
+ enabled: true
894
+ }));
895
+ var offerArtifactSchema = z7.union([
896
+ offerAuthoringSchema,
897
+ z7.object({ code: z7.string().min(1).max(2e6) }).strict()
898
+ ]);
899
+ var offerAvailabilitySchema = z7.discriminatedUnion("kind", [
900
+ z7.object({ kind: z7.literal("available"), remaining: quantity }).strict(),
901
+ z7.object({ kind: z7.literal("out-of-stock") }).strict(),
902
+ z7.object({ kind: z7.literal("limit-reached") }).strict(),
903
+ z7.object({ kind: z7.literal("paused") }).strict()
904
+ ]);
905
+ var offerSchema = offerDefinitionSchema.extend({
906
+ revision: z7.number().int().positive(),
907
+ available: quantity,
908
+ redeemed: quantity,
909
+ availability: offerAvailabilitySchema
910
+ });
911
+ var redeemOfferSchema = z7.object({ actionId: identifier }).strict();
912
+ var redemptionBase = {
913
+ id: identifier,
914
+ offer: identifier,
915
+ member: identifier,
916
+ reservation: identifier,
917
+ price: offerPriceSchema,
918
+ reward: tierRewardSchema,
919
+ entitlement: identifier,
920
+ revision: z7.number().int().positive(),
921
+ redeemedAt: z7.number().int().safe().nonnegative()
922
+ };
923
+ var redemptionSchema = z7.discriminatedUnion("status", [
924
+ z7.object({ ...redemptionBase, status: z7.literal("fulfilled") }).strict(),
925
+ z7.object({
926
+ ...redemptionBase,
927
+ status: z7.literal("canceled"),
928
+ canceledAt: z7.number().int().safe().nonnegative(),
929
+ reason: z7.string().min(1).max(500)
930
+ }).strict()
931
+ ]);
932
+ var offerControlSchema = z7.object({
933
+ actionId: identifier,
934
+ revision: z7.number().int().positive(),
935
+ enabled: z7.boolean(),
936
+ reason: z7.string().trim().min(1).max(500)
751
937
  }).strict();
752
- var solanaBalanceSchema = z7.object({
753
- address: solanaAddressSchema,
754
- network: z7.literal("mainnet-beta"),
755
- lamports: z7.string().regex(/^(0|[1-9][0-9]*)$/),
756
- slot: z7.number().int().nonnegative().safe(),
757
- observedAt: z7.number().int().nonnegative()
938
+ var redemptionCancellationSchema = z7.object({
939
+ actionId: identifier,
940
+ revision: z7.number().int().positive(),
941
+ reason: z7.string().trim().min(1).max(500)
758
942
  }).strict();
759
- var walletChainSchema = z7.enum(["solana", "eip155", "cosmos"]);
943
+ function defineOffer(input) {
944
+ return resourceHandle("offer", offerAuthoringSchema.parse(input));
945
+ }
946
+
947
+ // src/wallet.ts
948
+ import { z as z8 } from "zod";
949
+ var solanaAddressSchema = z8.string().min(32).max(44).regex(/^[1-9A-HJ-NP-Za-km-z]+$/);
950
+ var walletChainSchema = z8.enum(["solana", "eip155", "cosmos"]);
760
951
  var cosmosNetworkPattern = /^cosmos:[-_a-zA-Z0-9]{1,32}$/;
761
- var cosmosNetworkSchema = z7.custom(
952
+ var cosmosNetworkSchema = z8.custom(
762
953
  (value) => typeof value === "string" && cosmosNetworkPattern.test(value),
763
954
  "Use a Cosmos network: cosmos:<chain ID>"
764
955
  );
956
+ var cosmosDenomSchema = z8.string().regex(
957
+ /^[a-zA-Z][a-zA-Z0-9/:._-]{2,127}$/,
958
+ "Use a Cosmos bank denomination such as uatom or uosmo"
959
+ );
765
960
  function cosmosChain(chain) {
766
961
  if (typeof chain === "string" && !chain.startsWith("cosmos:")) {
767
962
  throw new Error('Use a Cosmos network such as "cosmos:cosmoshub-4"');
@@ -784,51 +979,51 @@ function cosmosChain(chain) {
784
979
  return { ...value, network };
785
980
  }
786
981
  var solanaMainnet = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
787
- var evmAddressSchema = z7.string().regex(/^0x[0-9a-fA-F]{40}$/);
788
- var cosmosAddressSchema = z7.string().min(8).max(90).regex(
982
+ var evmAddressSchema = z8.string().regex(/^0x[0-9a-fA-F]{40}$/);
983
+ var cosmosAddressSchema = z8.string().min(8).max(90).regex(
789
984
  /^(?:[a-z][a-z0-9]{0,82}1[02-9ac-hj-np-z]{38,}|[A-Z][A-Z0-9]{0,82}1[02-9AC-HJ-NP-Z]{38,})$/
790
985
  );
791
- var walletAddressInputSchema = z7.discriminatedUnion("chain", [
792
- z7.object({ chain: z7.literal("solana"), address: solanaAddressSchema }).strict(),
793
- z7.object({
794
- chain: z7.literal("eip155"),
986
+ var walletAddressInputSchema = z8.discriminatedUnion("chain", [
987
+ z8.object({ chain: z8.literal("solana"), address: solanaAddressSchema }).strict(),
988
+ z8.object({
989
+ chain: z8.literal("eip155"),
795
990
  address: evmAddressSchema,
796
991
  /** Shown in the sign-in message's Chain ID line only: links are chain-agnostic. Defaults to 1. */
797
- chainId: z7.number().int().positive().safe().optional()
992
+ chainId: z8.number().int().positive().safe().optional()
798
993
  }).strict(),
799
- z7.object({
800
- chain: z7.literal("cosmos"),
994
+ z8.object({
995
+ chain: z8.literal("cosmos"),
801
996
  network: cosmosNetworkSchema,
802
997
  address: cosmosAddressSchema
803
998
  }).strict()
804
999
  ]);
805
- var walletMessageChallengeSchema = z7.object({
806
- id: z7.string().min(1).max(200),
807
- purpose: z7.enum(["link", "sign-in"]),
1000
+ var walletMessageChallengeSchema = z8.object({
1001
+ id: z8.string().min(1).max(200),
1002
+ purpose: z8.enum(["link", "sign-in"]),
808
1003
  chain: walletChainSchema,
809
1004
  network: cosmosNetworkSchema.nullable(),
810
1005
  /** Canonical (base58, EIP-55 or lowercase bech32). The signer must sign with this address. */
811
- address: z7.string(),
812
- message: z7.string().max(4096),
813
- expiresAt: z7.number().int()
1006
+ address: z8.string(),
1007
+ message: z8.string().max(4096),
1008
+ expiresAt: z8.number().int()
814
1009
  });
815
- var walletSignatureSchema = z7.object({
816
- challenge: z7.string().min(1).max(200),
1010
+ var walletSignatureSchema = z8.object({
1011
+ challenge: z8.string().min(1).max(200),
817
1012
  /** solana: base58, 64 bytes · eip155: 0x and 130 hex digits (65 bytes) · cosmos: base64, 64 bytes (r‖s) */
818
- signature: z7.string().min(1).max(256),
1013
+ signature: z8.string().min(1).max(256),
819
1014
  /** cosmos only: the base64 33-byte compressed secp256k1 key from signArbitrary's pub_key.value */
820
- publicKey: z7.string().max(128).optional()
1015
+ publicKey: z8.string().max(128).optional()
821
1016
  }).strict();
822
- var linkedWalletSchema = z7.object({
1017
+ var linkedWalletSchema = z8.object({
823
1018
  chain: walletChainSchema,
824
1019
  network: cosmosNetworkSchema.nullable(),
825
- address: z7.string(),
826
- verifiedAt: z7.number().int().nonnegative(),
827
- revision: z7.number().int().positive(),
1020
+ address: z8.string(),
1021
+ verifiedAt: z8.number().int().nonnegative(),
1022
+ revision: z8.number().int().positive(),
828
1023
  /** True when this wallet can sign in: it was first used through wallet sign-in. Linking never enables sign-in. */
829
- signIn: z7.boolean()
1024
+ signIn: z8.boolean()
830
1025
  });
831
- var walletUnlinkInputSchema = z7.object({ chain: walletChainSchema, address: z7.string().min(1).max(100) }).strict();
1026
+ var walletUnlinkInputSchema = z8.object({ chain: walletChainSchema, address: z8.string().min(1).max(100) }).strict();
832
1027
  async function walletAddressInput(signer) {
833
1028
  const address = await signer.address();
834
1029
  switch (signer.chain) {
@@ -852,10 +1047,10 @@ async function walletAddressInput(signer) {
852
1047
  }
853
1048
  var WALLETS_PER_CHAIN = 5;
854
1049
  var walletSignInFamilies = ["solana", "eip155", "cosmos"];
855
- var walletSignInNetworkSchema = z7.union([z7.enum(walletSignInFamilies), z7.string().regex(cosmosNetworkPattern)]).transform(
856
- (value) => value.startsWith("cosmos:") ? "cosmos" : value
857
- );
858
- var walletSignInNetworksSchema = z7.array(walletSignInNetworkSchema).transform(
1050
+ var walletSignInNetworkSchema = z8.enum(walletSignInFamilies);
1051
+ var walletSignInNetworksSchema = z8.array(walletSignInNetworkSchema).max(walletSignInFamilies.length).refine((values) => new Set(values).size === values.length, {
1052
+ message: "Duplicate wallet family"
1053
+ }).transform(
859
1054
  (values) => walletSignInFamilies.filter((family) => values.includes(family))
860
1055
  );
861
1056
  function walletSignInNetwork(wallet) {
@@ -878,31 +1073,41 @@ function caip10(wallet, network) {
878
1073
  function isEvmChainId(value) {
879
1074
  return /^eip155:[1-9][0-9]{0,15}$/.test(value);
880
1075
  }
881
- var evmChainIdSchema = z7.custom(
1076
+ var evmChainIdSchema = z8.custom(
882
1077
  (value) => typeof value === "string" && isEvmChainId(value),
883
1078
  'Use an EVM chain ID such as "eip155:8453"'
884
1079
  );
885
- var units = z7.string().regex(/^(0|[1-9][0-9]*)$/);
886
- var walletBalanceSchema = z7.object({
887
- /** Canonical CAIP-2 ID: `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` or `eip155:<chain ID>`. */
888
- chain: z7.string(),
889
- /** The canonical mint (base58) or EIP-55 contract address; null for the native coin. */
890
- token: z7.string().nullable(),
891
- /** Null only for an ERC-20 contract without `decimals()`. */
892
- decimals: z7.number().int().min(0).max(255).nullable(),
1080
+ var units = z8.string().regex(/^(0|[1-9][0-9]*)$/);
1081
+ var walletBalanceSchema = z8.object({
1082
+ /** Canonical CAIP-2 ID for Solana, EVM or a supported Cosmos SDK chain. */
1083
+ chain: z8.string(),
1084
+ /** The canonical mint, EIP-55 contract or Cosmos bank denom; null for a native coin. */
1085
+ token: z8.string().nullable(),
1086
+ /** Null when token metadata does not report decimals. */
1087
+ decimals: z8.number().int().min(0).max(255).nullable(),
893
1088
  /** The sum over `wallets`. */
894
1089
  total: units,
895
- wallets: z7.array(z7.object({ address: z7.string(), amount: units }).strict()),
896
- /** Solana: the lowest slot the reads saw. EVM: the latest block when the read started (approximate). */
897
- at: z7.object({ kind: z7.enum(["slot", "block"]), number: units }).strict(),
898
- observedAt: z7.number().int().nonnegative()
1090
+ wallets: z8.array(z8.object({ address: z8.string(), amount: units }).strict()),
1091
+ /** Solana: lowest slot. EVM: approximate latest block. Cosmos: the fixed queried block. */
1092
+ at: z8.object({ kind: z8.enum(["slot", "block"]), number: units }).strict(),
1093
+ observedAt: z8.number().int().nonnegative()
899
1094
  }).strict();
900
1095
 
901
1096
  export {
902
- authoringIdentityShape,
903
- validateAuthoringIdentity,
904
- normalizeAuthoringIdentity,
905
- authoringKey,
1097
+ pointLedgerPropertiesSchema,
1098
+ createPointLedgerSchema,
1099
+ pointLedgerSchema,
1100
+ managedPointLedgerSchema,
1101
+ pointLedgerDeclarationSchema,
1102
+ pointLedgerArtifactSchema,
1103
+ pointLedgerReferenceSchema,
1104
+ pointBalanceSchema,
1105
+ pointBalancesSchema,
1106
+ PointEntryKind,
1107
+ pointEntrySchema,
1108
+ pointHistoryQuerySchema,
1109
+ pointHistoryPageSchema,
1110
+ engagementBudgetSchema,
906
1111
  engagementDefinitionSchema,
907
1112
  engagementScoreInputSchema,
908
1113
  engagementScoreSchema,
@@ -919,11 +1124,10 @@ export {
919
1124
  engagementBoundaryPageSchema,
920
1125
  engagementArtifactSchema,
921
1126
  engagementDeploymentEntrySchema,
922
- isRequestError,
923
- RequestError,
924
1127
  RelayErrorCode,
925
1128
  isRelayError,
926
1129
  RelayError,
1130
+ asRelayError,
927
1131
  clientError,
928
1132
  parseInput,
929
1133
  profileVisibilitySchema,
@@ -947,6 +1151,9 @@ export {
947
1151
  AVATAR_UPLOAD_LIMIT,
948
1152
  avatarUploadTypes,
949
1153
  leaderboardWindowSchema,
1154
+ leaderboardPrizeRewardSchema,
1155
+ leaderboardPrizeSchema,
1156
+ leaderboardSettlementPolicySchema,
950
1157
  leaderboardDefinitionSchema,
951
1158
  leaderboardAuthoringSchema,
952
1159
  leaderboardArtifactSchema,
@@ -962,6 +1169,11 @@ export {
962
1169
  pointsAccountSchema,
963
1170
  leaderboardExclusionSchema,
964
1171
  leaderboardGroupSchema,
1172
+ leaderboardSettlementStatusSchema,
1173
+ leaderboardSettlementSummarySchema,
1174
+ leaderboardSettlementRowSchema,
1175
+ leaderboardSettlementSchema,
1176
+ leaderboardSettlementApprovalSchema,
965
1177
  referralDefinitionSchema,
966
1178
  referralAuthoringSchema,
967
1179
  referralArtifactSchema,
@@ -973,14 +1185,22 @@ export {
973
1185
  referralSummarySchema,
974
1186
  referralHistorySchema,
975
1187
  referralManagementSchema,
1188
+ offerPriceSchema,
1189
+ offerLimitSchema,
1190
+ offerDefinitionSchema,
1191
+ offerAuthoringSchema,
1192
+ offerArtifactSchema,
1193
+ offerAvailabilitySchema,
1194
+ offerSchema,
1195
+ redeemOfferSchema,
1196
+ redemptionSchema,
1197
+ offerControlSchema,
1198
+ redemptionCancellationSchema,
1199
+ defineOffer,
976
1200
  solanaAddressSchema,
977
- walletConnectionSchema,
978
- walletChallengeInputSchema,
979
- walletChallengeSchema,
980
- walletProofSchema,
981
- solanaBalanceSchema,
982
1201
  walletChainSchema,
983
1202
  cosmosNetworkSchema,
1203
+ cosmosDenomSchema,
984
1204
  cosmosChain,
985
1205
  solanaMainnet,
986
1206
  evmAddressSchema,