@domino-sdk/relay 1.0.0-next.8 → 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 +1135 -285
  4. package/dist/authoring.js +545 -269
  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 -2528
  9. package/dist/browser.js +8 -6
  10. package/dist/capability-error-DNMwKmlL.d.ts +458 -0
  11. package/dist/{chunk-V7EZUZ3Z.js → chunk-36HTX2BM.js} +389 -169
  12. package/dist/chunk-6QJ3LADK.js +112 -0
  13. package/dist/{chunk-77H7APVD.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-V5R2DMGY.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-QBOHLT7M.js → chunk-XFMSUPNS.js} +1 -1
  24. package/dist/{chunk-6A6K5RUD.js → chunk-ZVIRG24J.js} +145 -42
  25. package/dist/{client-CK4nwt7V.d.ts → client-XiuFnug_.d.ts} +2193 -562
  26. package/dist/{submission-input-C9qm9ixd.d.ts → groups-Ck-OxzjD.d.ts} +919 -1142
  27. package/dist/identity-integration-GxAHdKR2.d.ts +58 -0
  28. package/dist/{images--vZ9U0kr.d.ts → images-Dv-P5VBw.d.ts} +2 -2
  29. package/dist/index.d.ts +13 -9
  30. package/dist/index.js +17 -6
  31. package/dist/internal.d.ts +82 -43
  32. package/dist/internal.js +58 -90
  33. package/dist/offers-Cy-e4o5x.d.ts +431 -0
  34. package/dist/{pages-BzqJuI69.d.ts → outcomes-kVB-Juzs.d.ts} +2386 -1490
  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 +3122 -1011
  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 -4216
  44. package/dist/schema.js +322 -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-MRIURJE3.js +0 -257
  54. package/dist/chunk-VARGF4JS.js +0 -1733
  55. package/dist/chunk-ZWY3R6B3.js +0 -26
  56. package/dist/collection-BGneJ6Bk.d.ts +0 -114
  57. package/dist/integrations-C3Sp558f.d.ts +0 -1297
  58. package/dist/point-ledgers-iS00Z_v0.d.ts +0 -37
  59. package/dist/schema-pnuWqvGn.d.ts +0 -3396
@@ -0,0 +1,112 @@
1
+ import {
2
+ isRequestError
3
+ } from "./chunk-NPGENI7K.js";
4
+
5
+ // src/request-lifetime.ts
6
+ var PARTICIPANT_TIMEOUT = 15e3;
7
+ var MANAGEMENT_TIMEOUT = 3e4;
8
+ var MAX_ATTEMPTS = 3;
9
+ var transientStatuses = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
10
+ function validTimeout(value) {
11
+ return typeof value === "number" && Number.isFinite(value) && value > 0;
12
+ }
13
+ function lifetime(timeout, caller) {
14
+ const deadline = new AbortController();
15
+ const expiresAt = Date.now() + timeout;
16
+ const timer = setTimeout(
17
+ () => deadline.abort(
18
+ new DOMException(`No answer within ${timeout} ms`, "TimeoutError")
19
+ ),
20
+ timeout
21
+ );
22
+ const signal = caller ? AbortSignal.any([caller, deadline.signal]) : deadline.signal;
23
+ return {
24
+ signal,
25
+ timeout,
26
+ ended: () => caller?.aborted ? "aborted" : deadline.signal.aborted ? "timeout" : void 0,
27
+ remaining: () => Math.max(0, expiresAt - Date.now()),
28
+ reason: () => caller?.aborted ? caller.reason : deadline.signal.reason,
29
+ end: () => clearTimeout(timer)
30
+ };
31
+ }
32
+ function retryAfter(headers, now = Date.now()) {
33
+ const value = headers.get("Retry-After")?.trim();
34
+ if (!value) {
35
+ return void 0;
36
+ }
37
+ if (/^\d+$/.test(value)) {
38
+ return Number(value) * 1e3;
39
+ }
40
+ const date = Date.parse(value);
41
+ return Number.isNaN(date) ? void 0 : Math.max(0, date - now);
42
+ }
43
+ function backoff(retry) {
44
+ return Math.round(250 * 4 ** (retry - 1) * (0.5 + Math.random() / 2));
45
+ }
46
+ function retryDelay(failure, context) {
47
+ const transient = failure.kind === "network" && (failure.status === void 0 || failure.status < 400) || (failure.kind === "http" || failure.kind === "network") && transientStatuses.has(failure.status ?? 0) && // Domino's rate limits run for minutes or hours: a 429 waits only when told how long.
48
+ (failure.status !== 429 || failure.retryAfter !== void 0);
49
+ if (!transient || !context.replaySafe || context.attempt >= MAX_ATTEMPTS) {
50
+ return void 0;
51
+ }
52
+ const wait = failure.retryAfter ?? backoff(context.attempt);
53
+ return wait < context.remaining ? wait : void 0;
54
+ }
55
+ function pause(ms, signal) {
56
+ return new Promise((resolve) => {
57
+ const done = () => {
58
+ clearTimeout(timer);
59
+ signal.removeEventListener("abort", done);
60
+ resolve();
61
+ };
62
+ const timer = setTimeout(done, ms);
63
+ signal.addEventListener("abort", done, { once: true });
64
+ });
65
+ }
66
+ async function retrying(life, rules, attempt) {
67
+ const describe = rules.describe ?? describeRequestError;
68
+ const uncertain = rules.uncertain ?? markUncertain;
69
+ let earlierUncertain = false;
70
+ for (let number = 1; ; number++) {
71
+ try {
72
+ return await attempt();
73
+ } catch (error) {
74
+ const failure = describe(error);
75
+ const wait = failure && !life.ended() ? retryDelay(failure, {
76
+ attempt: number,
77
+ replaySafe: rules.replaySafe,
78
+ remaining: life.remaining()
79
+ }) : void 0;
80
+ if (wait === void 0) {
81
+ throw earlierUncertain && !failure?.uncertain ? uncertain(error) : error;
82
+ }
83
+ earlierUncertain ||= failure?.uncertain ?? false;
84
+ await pause(wait, life.signal);
85
+ }
86
+ }
87
+ }
88
+ function describeRequestError(error) {
89
+ return isRequestError(error) ? {
90
+ kind: error.kind,
91
+ status: error.status,
92
+ uncertain: error.uncertain,
93
+ retryAfter: error.retryAfter
94
+ } : void 0;
95
+ }
96
+ function markUncertain(error) {
97
+ if (isRequestError(error)) {
98
+ const target = error;
99
+ target.uncertain = true;
100
+ target.recovery = error.operationId ? "replay" : "reconcile";
101
+ }
102
+ return error;
103
+ }
104
+
105
+ export {
106
+ PARTICIPANT_TIMEOUT,
107
+ MANAGEMENT_TIMEOUT,
108
+ validTimeout,
109
+ lifetime,
110
+ retryAfter,
111
+ retrying
112
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  identifier,
3
3
  xTweetSchema
4
- } from "./chunk-VARGF4JS.js";
4
+ } from "./chunk-JON5SESL.js";
5
5
 
6
6
  // src/x.ts
7
7
  import { z } from "zod";
@@ -0,0 +1,496 @@
1
+ import {
2
+ pointLedgerReferenceSchema
3
+ } from "./chunk-36HTX2BM.js";
4
+ import {
5
+ authoringIdentityShape,
6
+ entitlementSchema,
7
+ identifier,
8
+ memberProgressSchema,
9
+ pageCursorSchema,
10
+ pickupAvailabilitySchema,
11
+ pickupSelectionSchema,
12
+ prerequisiteSchema,
13
+ publishedReleaseSchema,
14
+ reviewModeSchema,
15
+ settingsValuesSchema,
16
+ storedQuestDescriptionSchema,
17
+ storedReviewModeSchema,
18
+ tieredRewardReferenceSchema
19
+ } from "./chunk-JON5SESL.js";
20
+
21
+ // src/participant-activity.ts
22
+ import { z } from "zod";
23
+ var base = { id: z.string(), at: z.number() };
24
+ var attempt = {
25
+ ...base,
26
+ quest: z.string(),
27
+ attempt: z.string(),
28
+ completion: z.string().nullable()
29
+ };
30
+ var kinds = [
31
+ "attempt.accepted",
32
+ "attempt.rejected",
33
+ "attempt.review",
34
+ "points.awarded",
35
+ "entitlement.granted",
36
+ "entitlement.collected",
37
+ "delivery.updated",
38
+ "referral.qualified"
39
+ ];
40
+ var knownRelayEventSchema = z.discriminatedUnion("kind", [
41
+ z.object({ ...attempt, kind: z.literal("attempt.accepted") }),
42
+ z.object({ ...attempt, kind: z.literal("attempt.rejected") }),
43
+ z.object({ ...attempt, kind: z.literal("attempt.review") }),
44
+ z.object({
45
+ ...base,
46
+ kind: z.literal("points.awarded"),
47
+ entry: z.string(),
48
+ ledger: z.string(),
49
+ amount: z.number(),
50
+ quest: z.string().nullable(),
51
+ completion: z.string().nullable()
52
+ }),
53
+ z.object({
54
+ ...base,
55
+ kind: z.literal("entitlement.granted"),
56
+ entitlement: z.string(),
57
+ tier: z.string(),
58
+ status: z.string()
59
+ }),
60
+ z.object({
61
+ ...base,
62
+ kind: z.literal("entitlement.collected"),
63
+ entitlement: z.string()
64
+ }),
65
+ z.object({
66
+ ...base,
67
+ kind: z.literal("delivery.updated"),
68
+ delivery: z.string(),
69
+ quest: z.string(),
70
+ completion: z.string(),
71
+ status: z.string()
72
+ }),
73
+ z.object({
74
+ ...base,
75
+ kind: z.literal("referral.qualified"),
76
+ program: z.string()
77
+ })
78
+ ]);
79
+ var relayEventSchema = z.union([
80
+ knownRelayEventSchema,
81
+ z.object({
82
+ ...base,
83
+ kind: z.string().refine((kind) => !kinds.includes(kind))
84
+ }).catchall(z.json()).transform(({ kind, ...event }) => ({
85
+ ...event,
86
+ kind: "unknown",
87
+ reportedKind: kind
88
+ }))
89
+ ]);
90
+ var participantActivityQuerySchema = z.object({
91
+ cursor: pageCursorSchema.optional(),
92
+ limit: z.number().int().min(1).max(100).default(50)
93
+ }).strict();
94
+ var participantActivitySchema = z.object({
95
+ member: z.string(),
96
+ items: z.array(relayEventSchema),
97
+ nextCursor: pageCursorSchema
98
+ });
99
+
100
+ // src/catalog.ts
101
+ import { z as z2 } from "zod";
102
+ var interactionSchema = z2.enum([
103
+ "photo",
104
+ "text",
105
+ "url",
106
+ "quiz",
107
+ "claim",
108
+ "staff",
109
+ "automatic"
110
+ ]);
111
+ function questInteraction(trigger) {
112
+ return trigger.kind === "automatic" ? "automatic" : trigger.actor === "staff" ? "staff" : trigger.input === "none" ? "claim" : trigger.input;
113
+ }
114
+ var questTypeVersionSchema = z2.object({
115
+ archivedAt: z2.number().int().nonnegative().nullable().optional(),
116
+ key: identifier.optional(),
117
+ id: identifier,
118
+ version: identifier,
119
+ code: z2.string(),
120
+ definition: storedQuestDescriptionSchema,
121
+ provider: storedReviewModeSchema,
122
+ createdAt: z2.number()
123
+ });
124
+ var collectionSlotSchema = z2.object({
125
+ archivedAt: z2.number().int().nonnegative().nullable().optional(),
126
+ id: identifier,
127
+ key: identifier.optional(),
128
+ title: z2.string().trim().min(1).max(120)
129
+ }).strict();
130
+ var collectionSlotDeclarationSchema = collectionSlotSchema.omit({ id: true, archivedAt: true }).extend(authoringIdentityShape).strict();
131
+ var questCollectionSchema = collectionSlotSchema.extend({
132
+ quests: z2.array(identifier).max(100).refine(
133
+ (v) => new Set(v).size === v.length,
134
+ "A collection can contain a quest only once"
135
+ )
136
+ });
137
+ var questInstanceSchema = z2.object({
138
+ id: identifier,
139
+ title: z2.string().trim().min(1).max(120),
140
+ typeVersion: identifier,
141
+ settings: settingsValuesSchema,
142
+ requires: z2.array(prerequisiteSchema).max(30),
143
+ status: z2.enum(["active", "paused", "archived"])
144
+ }).strict();
145
+ var questDraftChangesSchema = z2.object({
146
+ quests: z2.array(
147
+ questInstanceSchema.extend({ expectedRelease: identifier.nullable() })
148
+ ).max(50),
149
+ collections: z2.array(questCollectionSchema.omit({ archivedAt: true })).max(50)
150
+ }).strict();
151
+ var draftBase = z2.object({
152
+ id: identifier,
153
+ revision: z2.number().int().positive(),
154
+ baseRevision: z2.number().int().nonnegative(),
155
+ changes: questDraftChangesSchema
156
+ });
157
+ var questDraftSchema = z2.discriminatedUnion("status", [
158
+ draftBase.extend({ status: z2.literal("draft") }),
159
+ draftBase.extend({
160
+ status: z2.literal("published"),
161
+ releaseIds: z2.array(identifier)
162
+ })
163
+ ]);
164
+ var questCatalogSchema = z2.object({
165
+ revision: z2.number().int().nonnegative(),
166
+ types: z2.array(questTypeVersionSchema),
167
+ collections: z2.array(questCollectionSchema),
168
+ quests: z2.array(questInstanceSchema),
169
+ drafts: z2.array(questDraftSchema),
170
+ releases: z2.array(publishedReleaseSchema).default([]),
171
+ supportedInteractions: z2.array(interactionSchema)
172
+ });
173
+ var catalogDeploymentSchema = z2.object({
174
+ expectedRevision: z2.number().int().nonnegative(),
175
+ types: z2.array(
176
+ z2.object({
177
+ code: z2.string().min(1).max(1e6),
178
+ provider: reviewModeSchema
179
+ })
180
+ ).max(50).default([]),
181
+ collections: z2.array(collectionSlotDeclarationSchema).max(50).default([]),
182
+ supportedInteractions: z2.array(interactionSchema).min(1).optional()
183
+ }).strict();
184
+ var catalogDeploymentPreviewSchema = z2.object({
185
+ revision: z2.number().int().nonnegative(),
186
+ types: z2.array(questTypeVersionSchema),
187
+ collections: z2.array(collectionSlotSchema),
188
+ supportedInteractions: z2.array(interactionSchema)
189
+ });
190
+ var saveQuestDraftSchema = z2.object({
191
+ id: identifier.optional(),
192
+ actionId: identifier,
193
+ expectedRevision: z2.number().int().nonnegative(),
194
+ baseRevision: z2.number().int().nonnegative(),
195
+ changes: questDraftChangesSchema
196
+ }).strict();
197
+ var publishQuestDraftSchema = z2.object({ id: identifier, expectedRevision: z2.number().int().positive() }).strict();
198
+ var questRewardViewSchema = z2.discriminatedUnion("kind", [
199
+ z2.object({
200
+ kind: z2.literal("points"),
201
+ label: z2.string(),
202
+ amount: z2.number().int().nonnegative(),
203
+ ledger: pointLedgerReferenceSchema
204
+ }),
205
+ z2.object({
206
+ kind: z2.literal("tier"),
207
+ label: z2.string(),
208
+ reward: tieredRewardReferenceSchema.extend({ title: z2.string() }),
209
+ tier: identifier
210
+ }),
211
+ z2.object({ kind: z2.literal("integration"), label: z2.string() })
212
+ ]);
213
+ var questViewSchema = memberProgressSchema.shape.quests.element.extend(
214
+ {
215
+ release: identifier,
216
+ interaction: interactionSchema,
217
+ lifecycle: z2.enum(["active", "paused", "archived"]),
218
+ rewards: z2.array(questRewardViewSchema)
219
+ }
220
+ );
221
+ var collectionViewSchema = z2.object({
222
+ key: identifier.optional(),
223
+ id: identifier,
224
+ title: z2.string(),
225
+ quests: z2.array(questViewSchema)
226
+ });
227
+ var questExperienceSchema = z2.object({
228
+ entitlements: z2.array(entitlementSchema).default([]),
229
+ member: identifier,
230
+ quests: z2.array(questViewSchema),
231
+ collections: z2.array(collectionViewSchema)
232
+ });
233
+ var questPublicationPreviewSchema = z2.object({
234
+ draft: questDraftSchema,
235
+ releases: z2.array(publishedReleaseSchema),
236
+ affectedCollections: z2.array(questCollectionSchema)
237
+ });
238
+ var allocateQuestSchema = z2.object({ actionId: identifier }).strict();
239
+ var allocatedQuestSchema = z2.object({ id: identifier });
240
+
241
+ // src/collection.ts
242
+ import { z as z3 } from "zod";
243
+ var collectionCodeSchema = z3.string().regex(/^relay:collect:[a-f0-9]{64}$/);
244
+ var collectionPassSchema = z3.object({
245
+ code: collectionCodeSchema,
246
+ expiresAt: z3.number(),
247
+ entitlement: identifier
248
+ });
249
+ var collectionResolveSchema = z3.object({ code: collectionCodeSchema }).strict();
250
+ var collectionBeginSchema = collectionResolveSchema.extend({
251
+ actionId: identifier,
252
+ revision: z3.number().int().positive(),
253
+ selection: pickupSelectionSchema.optional()
254
+ });
255
+ var collectionPreviewSchema = z3.object({
256
+ entitlement: entitlementSchema,
257
+ inventory: pickupAvailabilitySchema,
258
+ expiresAt: z3.number()
259
+ });
260
+
261
+ // src/outcomes.ts
262
+ import { z as z4 } from "zod";
263
+ var timestamp = z4.number().int().safe().nonnegative();
264
+ var questEnrollmentInputSchema = z4.strictObject({
265
+ actionId: identifier,
266
+ /** Quest key or ID. */
267
+ quest: identifier
268
+ });
269
+ var memberEnrollmentInputSchema = questEnrollmentInputSchema.extend({
270
+ member: identifier
271
+ });
272
+ var questEnrollmentSchema = z4.object({
273
+ /** Stable quest ID. */
274
+ quest: identifier,
275
+ member: identifier,
276
+ enrolledAt: timestamp
277
+ });
278
+ var questClaimInputSchema = z4.strictObject({
279
+ actionId: identifier,
280
+ /** Quest key or ID. */
281
+ quest: identifier,
282
+ /** The outcome's tracker, as `QuestOutcome.tracker` names it. */
283
+ tracker: identifier,
284
+ record: z4.string().min(1).max(256),
285
+ observedAt: timestamp
286
+ });
287
+ var QuestOutcomeState = {
288
+ Admitted: "admitted",
289
+ Skipped: "skipped"
290
+ };
291
+ var questOutcomeSchema = z4.object({
292
+ /** Prerequisite transition identity; absent on older tracker responses. */
293
+ automatic: identifier.optional(),
294
+ /** Stable quest ID. */
295
+ quest: identifier,
296
+ /** Stable tracker ID of the record decided. */
297
+ tracker: identifier.nullable(),
298
+ /** The record's ID in its tracker. */
299
+ record: z4.string().nullable(),
300
+ /** Which observation of the record was decided. */
301
+ observedAt: timestamp.nullable(),
302
+ state: z4.enum(["admitted", "skipped"]),
303
+ /**
304
+ * Why it was skipped, one of `trackerSkipCodes` or a code a newer Relay sends; null when
305
+ * admitted. Show an unknown code by its `reason`.
306
+ */
307
+ code: z4.string().nullable(),
308
+ /** Why it was skipped, for people; null when admitted. */
309
+ reason: z4.string().nullable(),
310
+ /** The admitted attempt. */
311
+ attempt: identifier.nullable(),
312
+ /** The member can claim it with `relay.quests.claim()`. */
313
+ claimable: z4.boolean(),
314
+ createdAt: timestamp,
315
+ updatedAt: timestamp
316
+ });
317
+ var questOutcomeQuerySchema = z4.strictObject({
318
+ /** Quest key or ID. */
319
+ quest: identifier.optional(),
320
+ state: z4.enum(["admitted", "skipped"]).optional(),
321
+ /** Only skips with this code, such as `historical`. */
322
+ code: z4.string().min(1).max(100).optional(),
323
+ cursor: pageCursorSchema.optional()
324
+ });
325
+ var questOutcomePageSchema = z4.object({
326
+ items: z4.array(questOutcomeSchema),
327
+ nextCursor: pageCursorSchema.nullable()
328
+ });
329
+
330
+ // src/participant-rewards.ts
331
+ import { z as z5 } from "zod";
332
+ var participantEntitlementsSchema = z5.object({
333
+ items: z5.array(entitlementSchema)
334
+ });
335
+ var base2 = {
336
+ id: z5.string(),
337
+ status: z5.string(),
338
+ at: z5.number().nullable(),
339
+ quest: z5.string().nullable(),
340
+ completion: z5.string().nullable()
341
+ };
342
+ var known = z5.discriminatedUnion("kind", [
343
+ z5.object({
344
+ ...base2,
345
+ kind: z5.literal("points"),
346
+ ledger: pointLedgerReferenceSchema,
347
+ amount: z5.number(),
348
+ reversed: z5.number()
349
+ }).catchall(z5.json()),
350
+ z5.object({
351
+ ...base2,
352
+ kind: z5.literal("tier"),
353
+ entitlement: entitlementSchema
354
+ }).catchall(z5.json().transform((value) => value)),
355
+ z5.object({
356
+ ...base2,
357
+ kind: z5.literal("integration"),
358
+ provider: z5.string(),
359
+ action: z5.string(),
360
+ roleId: z5.string().optional(),
361
+ deliveredAt: z5.number().nullable(),
362
+ revokedAt: z5.number().nullable(),
363
+ reconciliation: z5.object({ status: z5.string(), ownership: z5.string(), at: z5.number() }).catchall(z5.json()).nullable()
364
+ }).catchall(z5.json().optional())
365
+ ]);
366
+ var participantDeliverySchema = z5.union([
367
+ known,
368
+ z5.object({
369
+ ...base2,
370
+ kind: z5.string().refine((kind) => !["points", "tier", "integration"].includes(kind))
371
+ }).catchall(z5.json()).transform(({ kind, ...item }) => ({
372
+ ...item,
373
+ kind: "unknown",
374
+ reportedKind: kind
375
+ }))
376
+ ]);
377
+ var participantDeliveriesSchema = z5.object({
378
+ items: z5.array(participantDeliverySchema)
379
+ });
380
+
381
+ // src/reward-deliveries.ts
382
+ import { z as z6 } from "zod";
383
+ var RewardDeliveryAction = {
384
+ /** Delivers a quest's Discord role reward. */
385
+ GrantRole: "grant-role"
386
+ };
387
+ var rewardDeliveryActionSchema = z6.string().min(1).max(64);
388
+ var roleReconciliationSchema = z6.object({
389
+ status: z6.enum(["pending", "granted", "removed", "preserved", "failed"]),
390
+ ownership: z6.enum(["unclaimed", "relay", "external"]),
391
+ at: z6.number(),
392
+ reason: z6.string().nullable()
393
+ });
394
+ var knownRewardDeliverySchema = z6.object({
395
+ id: z6.string(),
396
+ quest: z6.string(),
397
+ completion: z6.string(),
398
+ member: z6.string(),
399
+ provider: z6.literal("discord"),
400
+ /** `RewardDeliveryAction`, such as `grant-role`. */
401
+ action: rewardDeliveryActionSchema,
402
+ roleId: z6.string(),
403
+ /**
404
+ * `failed` is terminal: Discord rejected the grant permanently (unknown role,
405
+ * member left the server, missing permissions) or retries ran out after about
406
+ * a day. An operator can retry it once the cause is fixed, unless revokedAt is set.
407
+ * Revoke stops pending grants; a late success records deliveredAt but leaves status failed.
408
+ */
409
+ status: z6.enum(["pending", "delivered", "failed"]),
410
+ /** Provider attempts in the current round; an operator retry starts a new round at zero. */
411
+ attempts: z6.number().int(),
412
+ /** While pending with a `lastError`, when the next attempt is scheduled. */
413
+ nextAt: z6.number(),
414
+ lastError: z6.string().nullable(),
415
+ createdAt: z6.number(),
416
+ deliveredAt: z6.number().nullable(),
417
+ /** First dispatch attempt, retained across retries. Legacy rows use creation time when dispatch timing is unknown. */
418
+ dispatchedAt: z6.number().nullable().optional(),
419
+ /** Completion revocation stops retries, including deliveries that had already failed. */
420
+ revokedAt: z6.number().nullable().optional(),
421
+ /** Current reconciliation of the pinned Discord membership; original delivery and revoke history stay intact. */
422
+ reconciliation: roleReconciliationSchema.nullable().optional()
423
+ });
424
+ var futureRewardDeliverySchema = knownRewardDeliverySchema.extend({
425
+ provider: z6.string(),
426
+ status: z6.string(),
427
+ roleId: z6.string().optional(),
428
+ reconciliation: z6.object({
429
+ status: z6.string(),
430
+ ownership: z6.string(),
431
+ at: z6.number(),
432
+ reason: z6.string().nullable()
433
+ }).catchall(z6.json()).nullable().optional()
434
+ }).catchall(z6.json().optional()).refine(
435
+ (delivery) => delivery.provider !== "discord" || !["pending", "delivered", "failed"].includes(delivery.status) || delivery.reconciliation && (!["pending", "granted", "removed", "preserved", "failed"].includes(
436
+ delivery.reconciliation.status
437
+ ) || !["unclaimed", "relay", "external"].includes(
438
+ delivery.reconciliation.ownership
439
+ ))
440
+ );
441
+ var rewardDeliverySchema = z6.union([
442
+ knownRewardDeliverySchema.catchall(z6.json().optional()),
443
+ futureRewardDeliverySchema
444
+ ]);
445
+ var rewardDeliveriesSchema = z6.object({
446
+ deliveries: z6.array(rewardDeliverySchema)
447
+ });
448
+
449
+ export {
450
+ knownRelayEventSchema,
451
+ relayEventSchema,
452
+ participantActivityQuerySchema,
453
+ participantActivitySchema,
454
+ interactionSchema,
455
+ questInteraction,
456
+ questTypeVersionSchema,
457
+ collectionSlotSchema,
458
+ collectionSlotDeclarationSchema,
459
+ questCollectionSchema,
460
+ questInstanceSchema,
461
+ questDraftChangesSchema,
462
+ questDraftSchema,
463
+ questCatalogSchema,
464
+ catalogDeploymentSchema,
465
+ catalogDeploymentPreviewSchema,
466
+ saveQuestDraftSchema,
467
+ publishQuestDraftSchema,
468
+ questRewardViewSchema,
469
+ questViewSchema,
470
+ collectionViewSchema,
471
+ questExperienceSchema,
472
+ questPublicationPreviewSchema,
473
+ allocateQuestSchema,
474
+ allocatedQuestSchema,
475
+ collectionCodeSchema,
476
+ collectionPassSchema,
477
+ collectionResolveSchema,
478
+ collectionBeginSchema,
479
+ collectionPreviewSchema,
480
+ questEnrollmentInputSchema,
481
+ memberEnrollmentInputSchema,
482
+ questEnrollmentSchema,
483
+ questClaimInputSchema,
484
+ QuestOutcomeState,
485
+ questOutcomeSchema,
486
+ questOutcomeQuerySchema,
487
+ questOutcomePageSchema,
488
+ participantEntitlementsSchema,
489
+ participantDeliverySchema,
490
+ participantDeliveriesSchema,
491
+ RewardDeliveryAction,
492
+ roleReconciliationSchema,
493
+ knownRewardDeliverySchema,
494
+ rewardDeliverySchema,
495
+ rewardDeliveriesSchema
496
+ };
@@ -0,0 +1,84 @@
1
+ import {
2
+ discordMessageDataSchema,
3
+ discordMessageTextDataSchema,
4
+ discordReactionDataSchema,
5
+ isKnownTrackerSource,
6
+ trackerDataSchema,
7
+ xAccountRoles
8
+ } from "./chunk-JON5SESL.js";
9
+
10
+ // src/quest-shape.ts
11
+ function validateQuestShape(description, options = {}) {
12
+ const { trigger, completion, requires, performance } = description;
13
+ const tracker = trigger.kind === "automatic" ? trigger.tracker : void 0;
14
+ const content = tracker?.content === true;
15
+ if (performance && !content) {
16
+ throw new Error("Performance requires a content quest");
17
+ }
18
+ if (content) {
19
+ if (completion.kind !== "keyed") {
20
+ throw new Error("Content quests complete once per content item");
21
+ }
22
+ if (tracker.beneficiary !== "author" || tracker.on !== "new-record") {
23
+ throw new Error(
24
+ "A content quest pays each content item's author and fires on its first observation"
25
+ );
26
+ }
27
+ }
28
+ if (trigger.kind === "automatic" && !tracker) {
29
+ if (!options.template && requires.length === 0) {
30
+ throw new Error("Automatic quests need at least one prerequisite");
31
+ }
32
+ if (completion.kind !== "once") {
33
+ throw new Error("Prerequisite-only automatic quests complete once");
34
+ }
35
+ }
36
+ }
37
+
38
+ // src/tracker-sources.ts
39
+ var discordMessageRoles = ["author"];
40
+ var discordReactionRoles = ["author", "messageAuthor"];
41
+ function sourceRoles(source) {
42
+ if (!isKnownTrackerSource(source)) {
43
+ return [];
44
+ }
45
+ switch (source.kind) {
46
+ case "x-search":
47
+ return xAccountRoles;
48
+ case "discord-messages":
49
+ return discordMessageRoles;
50
+ case "discord-reactions":
51
+ return discordReactionRoles;
52
+ case "custom":
53
+ return ["author", ...source.accounts ?? []];
54
+ }
55
+ }
56
+ var discordSchemas = /* @__PURE__ */ new Map();
57
+ function discordDataSchema(source) {
58
+ const key = source.kind === "discord-messages" && source.text ? "messages-text" : source.kind;
59
+ let schema = discordSchemas.get(key);
60
+ if (!schema) {
61
+ schema = trackerDataSchema(
62
+ key === "messages-text" ? discordMessageTextDataSchema : key === "discord-messages" ? discordMessageDataSchema : discordReactionDataSchema
63
+ );
64
+ discordSchemas.set(key, schema);
65
+ }
66
+ return schema;
67
+ }
68
+ function sourceDataSchema(source) {
69
+ switch (source.kind) {
70
+ case "x-search":
71
+ return void 0;
72
+ case "discord-messages":
73
+ case "discord-reactions":
74
+ return discordDataSchema(source);
75
+ case "custom":
76
+ return source.data;
77
+ }
78
+ }
79
+
80
+ export {
81
+ validateQuestShape,
82
+ sourceRoles,
83
+ sourceDataSchema
84
+ };