@domino-sdk/relay 0.5.0 → 0.7.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.
@@ -0,0 +1,831 @@
1
+ // src/identifier.ts
2
+ import { z } from "zod";
3
+ var identifier = z.string().min(1).max(100).regex(/^[a-zA-Z0-9_-]+$/);
4
+
5
+ // src/observations.ts
6
+ import { z as z2 } from "zod";
7
+ var name = z2.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,199}$/);
8
+ var observationInputSchema = z2.object({
9
+ id: name,
10
+ source: name,
11
+ type: name,
12
+ member: identifier,
13
+ actor: z2.object({ provider: identifier, subject: z2.string().min(1).max(200) }).strict().optional(),
14
+ occurredAt: z2.number().int().nonnegative().max(864e13),
15
+ data: z2.record(z2.string(), z2.json())
16
+ }).strict().refine(
17
+ (value) => JSON.stringify(value.data).length <= 32768,
18
+ "Observation data exceeds 32 KB"
19
+ );
20
+ var observationSchema = observationInputSchema.safeExtend({
21
+ receivedAt: z2.number().int().nonnegative()
22
+ });
23
+ var observationTriggerSchema = z2.object({ source: name, type: name }).strict();
24
+ var completionPolicySchema = z2.discriminatedUnion("kind", [
25
+ z2.object({ kind: z2.literal("once") }).strict(),
26
+ z2.object({ kind: z2.literal("keyed") }).strict()
27
+ ]);
28
+ var completionKeySchema = z2.string().min(1).max(500);
29
+ var budgetSchema = z2.object({
30
+ id: name,
31
+ scope: z2.enum(["member", "project"]),
32
+ period: z2.enum(["lifetime", "day"]),
33
+ limit: z2.number().int().positive().max(Number.MAX_SAFE_INTEGER),
34
+ cost: z2.union([
35
+ z2.number().int().positive().max(Number.MAX_SAFE_INTEGER),
36
+ z2.object({ balance: name }).strict()
37
+ ])
38
+ }).strict();
39
+ var observationReceiptSchema = z2.object({
40
+ id: name,
41
+ source: name,
42
+ attempts: z2.array(z2.string()),
43
+ receivedAt: z2.number()
44
+ });
45
+ var discordReactionSchema = z2.object({
46
+ guildId: z2.string(),
47
+ channelId: z2.string(),
48
+ messageId: z2.string(),
49
+ userId: z2.string(),
50
+ messageAuthorId: z2.string().nullable().default(null),
51
+ actorRoles: z2.array(z2.string()).default([]),
52
+ emoji: z2.object({ id: z2.string().nullable(), name: z2.string() }),
53
+ messagePublishedAt: z2.number()
54
+ }).strict();
55
+ var discordMessageSchema = z2.object({
56
+ guildId: z2.string(),
57
+ channelId: z2.string(),
58
+ messageId: z2.string(),
59
+ userId: z2.string(),
60
+ content: z2.string().nullable(),
61
+ replyTo: z2.string().nullable(),
62
+ publishedAt: z2.number()
63
+ }).strict();
64
+
65
+ // src/integrations.ts
66
+ import { z as z3 } from "zod";
67
+ var integrationProviderSchema = z3.enum(["discord"]);
68
+ var discordServerSchema = z3.object({
69
+ id: z3.string().regex(/^[0-9]{1,20}$/),
70
+ name: z3.string().min(1),
71
+ icon: z3.string().nullable()
72
+ });
73
+ var projectIntegrationSchema = z3.object({
74
+ provider: integrationProviderSchema,
75
+ configured: z3.boolean(),
76
+ status: z3.enum(["disconnected", "ready", "attention"]),
77
+ revision: z3.number().int().nonnegative(),
78
+ server: discordServerSchema.nullable(),
79
+ issue: z3.string().nullable(),
80
+ connectedAt: z3.number().default(0)
81
+ });
82
+
83
+ // src/accounts.ts
84
+ import { z as z4 } from "zod";
85
+ var authProviderSchema = z4.enum(["google", "apple", "x", "discord"]);
86
+ var accountConnectionSchema = z4.object({
87
+ provider: authProviderSchema,
88
+ configured: z4.boolean(),
89
+ status: z4.enum(["disconnected", "connected", "reconnect"]),
90
+ subject: z4.string().nullable(),
91
+ revision: z4.number().int().nonnegative()
92
+ });
93
+ var discordMemberInputSchema = z4.object({}).strict();
94
+ var discordMessageInputSchema = z4.object({
95
+ channelId: z4.string().regex(/^[0-9]{1,20}$/),
96
+ messageId: z4.string().regex(/^[0-9]{1,20}$/)
97
+ }).strict();
98
+ var discordMemberSchema = z4.object({
99
+ userId: z4.string().regex(/^[0-9]{1,20}$/).nullable().default(null),
100
+ nickname: z4.string().nullable().default(null),
101
+ displayName: z4.string().nullable().default(null),
102
+ boostingSince: z4.string().datetime({ offset: true }).nullable().default(null),
103
+ roles: z4.array(z4.string().regex(/^[0-9]{1,20}$/)),
104
+ joinedAt: z4.string().datetime({ offset: true }).nullable(),
105
+ pending: z4.boolean()
106
+ });
107
+
108
+ // src/quiz.ts
109
+ import { z as z5 } from "zod";
110
+ var quizId = z5.string().regex(/^[a-zA-Z0-9_-]+$/).max(100);
111
+ var quizChoiceSchema = z5.object({ id: quizId, label: z5.string().trim().min(1).max(500) }).strict();
112
+ var quizQuestionSchema = z5.object({
113
+ id: quizId,
114
+ prompt: z5.string().trim().min(1).max(1e3),
115
+ choices: z5.array(quizChoiceSchema).min(2).max(8).refine(
116
+ (choices) => new Set(choices.map((choice) => choice.id)).size === choices.length,
117
+ "Choice IDs must be unique"
118
+ )
119
+ }).strict();
120
+ var quizQuestionsSchema = z5.array(quizQuestionSchema).min(1).max(20).refine(
121
+ (questions) => new Set(questions.map((question) => question.id)).size === questions.length,
122
+ "Question IDs must be unique"
123
+ );
124
+ var quizContentSchema = z5.array(
125
+ quizQuestionSchema.extend({ correct: quizId }).refine(
126
+ (question) => question.choices.some((choice) => choice.id === question.correct),
127
+ "Choose a correct answer from the available choices"
128
+ )
129
+ ).min(1).max(20).refine(
130
+ (questions) => new Set(questions.map((question) => question.id)).size === questions.length,
131
+ "Question IDs must be unique"
132
+ );
133
+
134
+ // src/schema.ts
135
+ import { z as z8 } from "zod";
136
+
137
+ // src/settings.ts
138
+ import { z as z7 } from "zod";
139
+
140
+ // src/resources.ts
141
+ import { z as z6 } from "zod";
142
+ var channelSourceSchema = z6.object({
143
+ provider: z6.literal("discord"),
144
+ resource: z6.literal("channel"),
145
+ types: z6.array(z6.enum(["text", "announcement"])).min(1)
146
+ }).strict();
147
+ var resourceSourceSchema = z6.union([
148
+ channelSourceSchema,
149
+ z6.object({
150
+ provider: z6.literal("discord"),
151
+ resource: z6.literal("role"),
152
+ assignable: z6.boolean().default(false)
153
+ }).strict()
154
+ ]);
155
+ var resourceRequestSchema = z6.object({
156
+ source: resourceSourceSchema,
157
+ query: z6.string().max(100).optional(),
158
+ cursor: z6.string().regex(/^\d{1,6}$/).optional(),
159
+ ids: z6.array(z6.string().min(1).max(100)).max(50).optional()
160
+ }).strict();
161
+ var resourceOptionsSchema = z6.object({
162
+ revision: z6.number().int(),
163
+ options: z6.array(
164
+ z6.object({
165
+ id: z6.string(),
166
+ label: z6.string(),
167
+ description: z6.string().optional(),
168
+ group: z6.string().optional(),
169
+ disabledReason: z6.string().optional()
170
+ })
171
+ ),
172
+ cursor: z6.string().nullable()
173
+ });
174
+ var discord = {
175
+ roles(options = {}) {
176
+ return resourceSourceSchema.parse({
177
+ provider: "discord",
178
+ resource: "role",
179
+ assignable: options.assignable ?? false
180
+ });
181
+ },
182
+ channels(options = {}) {
183
+ return resourceSourceSchema.parse({
184
+ provider: "discord",
185
+ resource: "channel",
186
+ types: options.types ?? ["text", "announcement"]
187
+ });
188
+ }
189
+ };
190
+
191
+ // src/settings.ts
192
+ var instant = z7.iso.datetime({ offset: true }).transform((value) => new Date(value).toISOString());
193
+ var resourceId = z7.union([z7.literal(""), z7.string().regex(/^\S{1,200}$/)]);
194
+ var base = { label: z7.string().min(1), description: z7.string().optional() };
195
+ var settingFieldSchema = z7.discriminatedUnion("kind", [
196
+ z7.object({ ...base, kind: z7.literal("point-ledger"), default: identifier }).strict(),
197
+ z7.object({ ...base, kind: z7.literal("datetime"), default: instant }).strict(),
198
+ z7.object({
199
+ ...base,
200
+ kind: z7.literal("resource"),
201
+ default: resourceId,
202
+ source: resourceSourceSchema
203
+ }).strict(),
204
+ z7.object({ ...base, kind: z7.literal("quiz"), default: quizContentSchema }).strict(),
205
+ z7.object({
206
+ ...base,
207
+ kind: z7.literal("text"),
208
+ default: z7.string(),
209
+ minLength: z7.number().int().nonnegative(),
210
+ maxLength: z7.number().int().positive(),
211
+ multiline: z7.boolean()
212
+ }).strict(),
213
+ z7.object({
214
+ ...base,
215
+ kind: z7.literal("integer"),
216
+ default: z7.number().int(),
217
+ min: z7.number().int(),
218
+ max: z7.number().int()
219
+ }).strict(),
220
+ z7.object({ ...base, kind: z7.literal("boolean"), default: z7.boolean() }).strict(),
221
+ z7.object({
222
+ ...base,
223
+ kind: z7.literal("choice"),
224
+ default: z7.string(),
225
+ options: z7.array(z7.string().min(1)).min(1)
226
+ }).strict()
227
+ ]);
228
+ var settingsFieldsSchema = z7.record(
229
+ z7.string().regex(/^[a-zA-Z][a-zA-Z0-9_]*$/),
230
+ settingFieldSchema
231
+ );
232
+ var settingsValuesSchema = z7.record(
233
+ z7.string(),
234
+ z7.union([z7.string(), z7.number().finite(), z7.boolean(), quizContentSchema])
235
+ );
236
+ var settings = {
237
+ pointLedger(options) {
238
+ const field = {
239
+ ...options,
240
+ kind: "point-ledger",
241
+ default: identifier.parse(options.default)
242
+ };
243
+ return identifier.default(field.default).meta(field);
244
+ },
245
+ datetime(options) {
246
+ const field = {
247
+ ...options,
248
+ kind: "datetime",
249
+ default: instant.parse(options.default)
250
+ };
251
+ return instant.default(field.default).meta(field);
252
+ },
253
+ resource(options) {
254
+ const field = {
255
+ ...options,
256
+ source: resourceSourceSchema.parse(options.source),
257
+ kind: "resource",
258
+ default: resourceId.parse(options.default ?? "")
259
+ };
260
+ return resourceId.default(field.default).meta(field);
261
+ },
262
+ quiz(options) {
263
+ const value = quizContentSchema.parse(options.default);
264
+ return quizContentSchema.default(value).meta({ ...options, default: value, kind: "quiz" });
265
+ },
266
+ text(options) {
267
+ const field = {
268
+ ...options,
269
+ kind: "text",
270
+ minLength: options.minLength ?? 1,
271
+ maxLength: options.maxLength ?? 2e3,
272
+ multiline: options.multiline ?? false
273
+ };
274
+ return z7.string().min(field.minLength).max(field.maxLength).default(field.default).meta(field);
275
+ },
276
+ integer(options) {
277
+ return z7.number().int().min(options.min).max(options.max).default(options.default).meta({ ...options, kind: "integer" });
278
+ },
279
+ boolean(options) {
280
+ return z7.boolean().default(options.default).meta({ ...options, kind: "boolean" });
281
+ },
282
+ choice(options) {
283
+ return z7.enum(options.options).default(options.default).meta({ ...options, kind: "choice" });
284
+ },
285
+ object(shape) {
286
+ return z7.object(shape).strict();
287
+ }
288
+ };
289
+ function parseSettings(fields, input) {
290
+ const shape = {};
291
+ for (const [key, field] of Object.entries(fields)) {
292
+ switch (field.kind) {
293
+ case "point-ledger":
294
+ shape[key] = identifier.default(field.default);
295
+ break;
296
+ case "datetime":
297
+ shape[key] = instant.default(field.default);
298
+ break;
299
+ case "resource":
300
+ shape[key] = resourceId.default(field.default);
301
+ break;
302
+ case "quiz":
303
+ shape[key] = quizContentSchema.default(field.default);
304
+ break;
305
+ case "text":
306
+ shape[key] = z7.string().min(field.minLength).max(field.maxLength).default(field.default);
307
+ break;
308
+ case "integer":
309
+ shape[key] = z7.number().int().min(field.min).max(field.max).default(field.default);
310
+ break;
311
+ case "boolean":
312
+ shape[key] = z7.boolean().default(field.default);
313
+ break;
314
+ case "choice":
315
+ shape[key] = z7.enum(field.options).default(field.default);
316
+ break;
317
+ }
318
+ }
319
+ return settingsValuesSchema.parse(z7.object(shape).strict().parse(input));
320
+ }
321
+ function missingResourceSettings(fields, values) {
322
+ return Object.entries(fields).filter(([key, field]) => field.kind === "resource" && !values[key]).map(([key]) => key);
323
+ }
324
+ function compatibleSettingKinds(previous, next) {
325
+ return previous.kind === next.kind || previous.kind === "text" && (next.kind === "resource" || next.kind === "datetime" || next.kind === "point-ledger");
326
+ }
327
+
328
+ // src/schema.ts
329
+ var pointsRewardSchema = z8.object({
330
+ kind: z8.literal("points").default("points"),
331
+ balance: identifier,
332
+ amount: z8.number().int().min(0).max(1e4)
333
+ }).strict();
334
+ var tieredRewardDefinitionSchema = z8.object({
335
+ id: identifier,
336
+ title: z8.string().min(1).max(120),
337
+ tiers: z8.array(
338
+ z8.object({ id: identifier, title: z8.string().min(1).max(120) }).strict()
339
+ ).min(1).max(20).refine(
340
+ (tiers) => new Set(tiers.map((t) => t.id)).size === tiers.length,
341
+ "Tier IDs must be unique"
342
+ ),
343
+ inventory: z8.object({ kind: z8.literal("untracked") }).strict(),
344
+ fulfillment: z8.object({ kind: z8.literal("staff-handover") }).strict()
345
+ }).strict();
346
+ var tierRewardSchema = z8.object({
347
+ kind: z8.literal("tier"),
348
+ reward: tieredRewardDefinitionSchema,
349
+ tier: identifier
350
+ }).strict().refine(
351
+ (value) => value.reward.tiers.some((t) => t.id === value.tier),
352
+ "Unknown reward tier"
353
+ );
354
+ var integrationRewardSchema = z8.object({
355
+ kind: z8.literal("integration"),
356
+ provider: z8.literal("discord"),
357
+ action: z8.literal("grant-role"),
358
+ roleId: z8.string().regex(/^[0-9]{1,20}$/)
359
+ }).strict();
360
+ var rewardSchema = z8.union([
361
+ pointsRewardSchema,
362
+ tierRewardSchema,
363
+ integrationRewardSchema
364
+ ]);
365
+ function rewardKey(reward) {
366
+ if (reward.kind === "integration")
367
+ return `integration:${reward.provider}:${reward.action}:${reward.roleId}`;
368
+ return reward.kind === "points" ? "points:" + reward.balance : "tier:" + reward.reward.id;
369
+ }
370
+ var triggerSchema = z8.union([
371
+ z8.object({
372
+ kind: z8.literal("manual"),
373
+ input: z8.enum(["photo", "quiz", "none"]),
374
+ actor: z8.enum(["member", "staff"]).optional()
375
+ }).strict(),
376
+ z8.object({
377
+ kind: z8.literal("automatic"),
378
+ observation: observationTriggerSchema.optional()
379
+ }).strict()
380
+ ]);
381
+ var prerequisiteSchema = z8.object({ quest: identifier, scope: z8.literal("ever") }).strict();
382
+ var photoResultSchema = z8.object({
383
+ kind: z8.enum(["pass", "fail", "unclear"]),
384
+ reason: z8.string().min(1).max(2e3)
385
+ }).strict();
386
+ var decisionSchema = z8.discriminatedUnion("kind", [
387
+ z8.object({
388
+ kind: z8.literal("accept"),
389
+ rewards: z8.array(rewardSchema).max(10),
390
+ completionKey: completionKeySchema.optional()
391
+ }).strict(),
392
+ z8.object({ kind: z8.literal("reject"), reason: z8.string().min(1).max(2e3) }).strict(),
393
+ z8.object({
394
+ kind: z8.literal("review"),
395
+ reason: z8.string().min(1).max(2e3),
396
+ rewards: z8.array(rewardSchema).max(10).optional(),
397
+ completionKey: completionKeySchema.optional()
398
+ }).strict()
399
+ ]);
400
+ var reviewModeSchema = z8.enum([
401
+ "fixture-pass",
402
+ "fixture-fail",
403
+ "fixture-unclear",
404
+ "fixture-error",
405
+ "workers-ai"
406
+ ]);
407
+ var rewardBundleSchema = z8.array(rewardSchema).max(10).refine(
408
+ (rewards) => new Set(rewards.map(rewardKey)).size === rewards.length,
409
+ "Use one entry per balance or shared reward"
410
+ );
411
+ var mediaUrlSchema = z8.string().max(2e3).refine((value) => {
412
+ if (/^\/(?!\/)[^\\\s]*$/.test(value)) return true;
413
+ try {
414
+ return new URL(value).protocol === "https:";
415
+ } catch {
416
+ return false;
417
+ }
418
+ }, "Use an HTTPS URL or a same-site path beginning with /");
419
+ var questPresentationSchema = z8.object({
420
+ quiz: quizQuestionsSchema.optional(),
421
+ instructions: z8.string().max(4e3).optional(),
422
+ video: z8.object({
423
+ url: mediaUrlSchema,
424
+ poster: mediaUrlSchema.optional(),
425
+ captions: z8.object({
426
+ url: mediaUrlSchema,
427
+ language: z8.string().min(2).max(20),
428
+ label: z8.string().min(1).max(80)
429
+ }).strict().optional()
430
+ }).strict().optional()
431
+ }).strict();
432
+ var questDescriptionSchema = z8.object({
433
+ quest: identifier,
434
+ runtimeVersion: z8.union([z8.literal(1), z8.literal(2)]).default(1),
435
+ title: z8.string().min(1).max(120),
436
+ presentation: questPresentationSchema.default({}),
437
+ integrations: z8.array(integrationProviderSchema).max(10).default([]),
438
+ fields: settingsFieldsSchema,
439
+ values: settingsValuesSchema,
440
+ rewards: rewardBundleSchema,
441
+ humanReview: z8.boolean(),
442
+ trigger: triggerSchema,
443
+ requires: z8.array(prerequisiteSchema).max(30).default([]),
444
+ completion: completionPolicySchema,
445
+ visibility: z8.enum(["visible", "hidden"]).default("visible"),
446
+ budgets: z8.array(budgetSchema).max(20).default([])
447
+ }).strict();
448
+ var artifactSchema = z8.object({ code: z8.string().min(1).max(1e6) }).strict();
449
+ var releaseSchema = artifactSchema.extend({
450
+ settings: settingsValuesSchema,
451
+ provider: reviewModeSchema,
452
+ expectedRelease: identifier.nullable().optional(),
453
+ settingRenames: z8.record(z8.string(), z8.string()).optional()
454
+ }).strict();
455
+ var batchReleaseSchema = z8.object({ releases: z8.array(releaseSchema).min(1).max(50) }).strict();
456
+ var questSettingsInputSchema = z8.object({
457
+ quest: identifier,
458
+ expectedRelease: identifier,
459
+ set: settingsValuesSchema,
460
+ reset: z8.array(z8.string())
461
+ }).strict();
462
+ var storedReleaseSchema = questDescriptionSchema.extend({
463
+ code: z8.string(),
464
+ provider: reviewModeSchema,
465
+ id: identifier,
466
+ createdAt: z8.number(),
467
+ legacy: z8.boolean().default(false),
468
+ origin: z8.object({ typeVersion: identifier }).strict().optional(),
469
+ lifecycle: z8.enum(["active", "paused", "archived"]).default("active"),
470
+ configuration: z8.object({
471
+ defaults: settingsValuesSchema,
472
+ overrides: settingsValuesSchema,
473
+ preserved: z8.array(z8.string())
474
+ }).strict().optional()
475
+ });
476
+ var legacyReleaseSchema = z8.object({
477
+ quest: identifier,
478
+ title: z8.string(),
479
+ criteria: z8.string(),
480
+ humanReview: z8.boolean(),
481
+ rewards: rewardBundleSchema,
482
+ code: z8.string(),
483
+ provider: reviewModeSchema,
484
+ id: identifier,
485
+ createdAt: z8.number()
486
+ }).transform((r) => {
487
+ const { criteria, ...stored } = r;
488
+ return storedReleaseSchema.parse({
489
+ ...stored,
490
+ fields: {},
491
+ values: { criteria, humanReview: r.humanReview },
492
+ trigger: { kind: "manual", input: "photo" },
493
+ completion: { kind: "once" },
494
+ legacy: true
495
+ });
496
+ });
497
+ var publishedReleaseSchema = z8.union([
498
+ storedReleaseSchema,
499
+ legacyReleaseSchema
500
+ ]);
501
+ var templateSchema = z8.object({
502
+ code: z8.string(),
503
+ definition: questDescriptionSchema
504
+ });
505
+ var quizAnswersSchema = z8.record(identifier, identifier).refine(
506
+ (answers) => Object.keys(answers).length > 0 && Object.keys(answers).length <= 50,
507
+ "Provide between 1 and 50 answers"
508
+ ).transform(
509
+ (answers) => Object.fromEntries(
510
+ Object.entries(answers).sort(([a], [b]) => a.localeCompare(b))
511
+ )
512
+ );
513
+ var quizEvidenceSchema = z8.object({
514
+ kind: z8.literal("quiz"),
515
+ release: identifier.optional(),
516
+ answers: quizAnswersSchema
517
+ }).strict();
518
+ var submitSchema = z8.object({
519
+ actionId: identifier,
520
+ quest: identifier,
521
+ member: identifier,
522
+ evidence: identifier.optional(),
523
+ input: quizEvidenceSchema.optional(),
524
+ release: identifier.optional(),
525
+ faultAfterReview: z8.boolean().optional()
526
+ }).strict();
527
+ var attemptSchema = z8.object({
528
+ id: identifier,
529
+ release: identifier,
530
+ quest: identifier,
531
+ member: identifier,
532
+ evidence: identifier.nullable(),
533
+ input: quizEvidenceSchema.optional(),
534
+ status: z8.enum([
535
+ "queued",
536
+ "evaluating",
537
+ "accepted",
538
+ "rejected",
539
+ "needs-review",
540
+ "failed"
541
+ ]),
542
+ reason: z8.string().nullable(),
543
+ retries: z8.number(),
544
+ generation: z8.number(),
545
+ completion: z8.string().nullable(),
546
+ reviewRewards: rewardBundleSchema.nullable().default(null),
547
+ createdAt: z8.number()
548
+ });
549
+ var eventSchema = z8.object({
550
+ id: z8.number(),
551
+ attempt: z8.string().nullable(),
552
+ kind: z8.string(),
553
+ detail: z8.string(),
554
+ actor: z8.string().nullable().default(null),
555
+ at: z8.number()
556
+ });
557
+ var pickupSelectionSchema = z8.object({
558
+ item: identifier,
559
+ revision: z8.number().int().nonnegative()
560
+ }).strict();
561
+ var pickupAllocationSchema = z8.object({
562
+ item: identifier,
563
+ label: z8.string().min(1).max(80)
564
+ }).strict();
565
+ var pickupPolicySchema = z8.discriminatedUnion("kind", [
566
+ z8.object({ kind: z8.literal("untracked") }).strict(),
567
+ z8.object({
568
+ kind: z8.literal("at-pickup"),
569
+ tiers: z8.array(
570
+ z8.object({
571
+ tier: identifier,
572
+ variants: z8.array(pickupAllocationSchema).min(1).max(100)
573
+ }).strict()
574
+ ).min(1).max(100)
575
+ }).strict()
576
+ ]);
577
+ var pickupCatalogSchema = z8.object({
578
+ reward: tieredRewardDefinitionSchema,
579
+ revision: z8.number().int().nonnegative(),
580
+ policy: pickupPolicySchema
581
+ });
582
+ var pickupAvailabilitySchema = z8.discriminatedUnion("kind", [
583
+ z8.object({ kind: z8.literal("untracked") }).strict(),
584
+ z8.object({
585
+ kind: z8.literal("at-pickup"),
586
+ revision: z8.number().int().nonnegative(),
587
+ variants: z8.array(
588
+ pickupAllocationSchema.extend({
589
+ available: z8.number().int().nonnegative()
590
+ })
591
+ )
592
+ }).strict()
593
+ ]);
594
+ var configurePickupSchema = z8.object({
595
+ reward: identifier,
596
+ revision: z8.number().int().nonnegative(),
597
+ actionId: identifier,
598
+ policy: pickupPolicySchema
599
+ }).strict();
600
+ var entitlementBase = {
601
+ id: identifier,
602
+ member: identifier,
603
+ reward: tieredRewardDefinitionSchema,
604
+ earnedTier: identifier,
605
+ tier: identifier,
606
+ revision: z8.number().int().positive()
607
+ };
608
+ var entitlementSchema = z8.discriminatedUnion("status", [
609
+ z8.object({ ...entitlementBase, status: z8.literal("available") }).strict(),
610
+ z8.object({
611
+ ...entitlementBase,
612
+ status: z8.literal("handing-over"),
613
+ handover: identifier,
614
+ startedAt: z8.number(),
615
+ allocation: pickupAllocationSchema.optional()
616
+ }).strict(),
617
+ z8.object({
618
+ ...entitlementBase,
619
+ status: z8.literal("collected"),
620
+ handover: identifier,
621
+ startedAt: z8.number(),
622
+ allocation: pickupAllocationSchema.optional(),
623
+ collectedAt: z8.number()
624
+ }).strict()
625
+ ]);
626
+ var beginHandoverSchema = z8.object({
627
+ actionId: identifier,
628
+ revision: z8.number().int().positive(),
629
+ selection: pickupSelectionSchema.optional()
630
+ }).strict();
631
+ var confirmHandoverSchema = z8.object({ actionId: identifier, handover: identifier }).strict();
632
+ var completionRecordSchema = z8.object({
633
+ key: z8.string().default("once"),
634
+ id: identifier,
635
+ quest: identifier,
636
+ member: identifier
637
+ });
638
+ var questAvailabilitySchema = z8.discriminatedUnion("kind", [
639
+ z8.object({
640
+ kind: z8.literal("available"),
641
+ input: z8.enum(["photo", "quiz", "none"])
642
+ }).strict(),
643
+ z8.object({ kind: z8.literal("completed") }).strict(),
644
+ z8.object({
645
+ kind: z8.literal("locked"),
646
+ missing: z8.array(z8.object({ quest: identifier, title: z8.string() })).min(1)
647
+ }).strict(),
648
+ z8.object({ kind: z8.literal("staff-required") }).strict(),
649
+ z8.object({
650
+ kind: z8.literal("automatic"),
651
+ observation: observationTriggerSchema.optional()
652
+ }).strict(),
653
+ z8.object({ kind: z8.literal("checking"), attempt: identifier }).strict(),
654
+ z8.object({ kind: z8.literal("needs-review"), attempt: identifier }).strict(),
655
+ z8.object({ kind: z8.literal("retryable"), attempt: identifier }).strict()
656
+ ]);
657
+ var memberProgressSchema = z8.object({
658
+ member: identifier,
659
+ quests: z8.array(
660
+ z8.object({
661
+ quest: identifier,
662
+ release: identifier.optional(),
663
+ title: z8.string(),
664
+ presentation: questPresentationSchema.default({}),
665
+ connections: z8.array(authProviderSchema).default([]),
666
+ trigger: triggerSchema,
667
+ availability: questAvailabilitySchema,
668
+ completed: z8.boolean(),
669
+ completion: completionPolicySchema.default({ kind: "once" }),
670
+ completionCount: z8.number().int().nonnegative().default(0),
671
+ visibility: z8.enum(["visible", "hidden"]).default("visible"),
672
+ missing: z8.array(z8.object({ quest: identifier, title: z8.string() })),
673
+ attempt: attemptSchema.nullable()
674
+ })
675
+ ),
676
+ entitlements: z8.array(entitlementSchema)
677
+ });
678
+ var snapshotSchema = z8.object({
679
+ releases: z8.array(publishedReleaseSchema),
680
+ completions: z8.array(completionRecordSchema),
681
+ entitlements: z8.array(entitlementSchema),
682
+ attempts: z8.array(attemptSchema),
683
+ balances: z8.array(
684
+ z8.object({
685
+ member: z8.string(),
686
+ balance: z8.string(),
687
+ earned: z8.number(),
688
+ held: z8.number(),
689
+ available: z8.number()
690
+ })
691
+ ),
692
+ events: z8.array(eventSchema)
693
+ });
694
+ var evidenceSchema = z8.object({
695
+ id: identifier,
696
+ member: identifier,
697
+ type: z8.enum(["image/jpeg", "image/png"]),
698
+ size: z8.number()
699
+ });
700
+ var errorSchema = z8.object({
701
+ error: z8.string(),
702
+ code: z8.enum(["stale-quiz", "quest-updated"]).optional(),
703
+ missing: z8.array(z8.object({ quest: identifier, title: z8.string() })).optional()
704
+ });
705
+ var staffDecisionSchema = z8.object({
706
+ actionId: identifier,
707
+ generation: z8.number().int().nonnegative(),
708
+ decision: z8.enum(["accept", "reject"]),
709
+ reason: z8.string().trim().min(1).max(2e3)
710
+ }).strict();
711
+ var stockSchema = z8.object({ item: identifier, quantity: z8.number().int().min(0).max(1e4) }).strict();
712
+ var reservationSchema = z8.object({
713
+ actionId: identifier,
714
+ member: identifier,
715
+ item: identifier,
716
+ balance: identifier,
717
+ price: z8.number().int().positive().max(1e4)
718
+ }).strict();
719
+ var pageOptions = {
720
+ limit: z8.number().int().min(1).max(100).default(25),
721
+ cursor: z8.string().min(1).max(4096).optional()
722
+ };
723
+ var reviewListSchema = z8.object({
724
+ ...pageOptions,
725
+ member: identifier.optional(),
726
+ quest: identifier.optional()
727
+ }).strict();
728
+ var memberListSchema = z8.object({
729
+ ...pageOptions,
730
+ prefix: identifier.optional()
731
+ }).strict();
732
+ var reviewItemSchema = z8.object({
733
+ attempt: attemptSchema,
734
+ title: z8.string(),
735
+ checks: z8.array(
736
+ z8.object({ criteria: z8.string(), result: photoResultSchema })
737
+ )
738
+ });
739
+ var reviewPageSchema = z8.object({
740
+ items: z8.array(reviewItemSchema).max(100),
741
+ nextCursor: z8.string().nullable()
742
+ });
743
+ var memberPageSchema = z8.object({
744
+ items: z8.array(z8.object({ member: identifier })).max(100),
745
+ nextCursor: z8.string().nullable()
746
+ });
747
+
748
+ export {
749
+ identifier,
750
+ observationInputSchema,
751
+ observationSchema,
752
+ observationTriggerSchema,
753
+ completionPolicySchema,
754
+ completionKeySchema,
755
+ budgetSchema,
756
+ observationReceiptSchema,
757
+ discordReactionSchema,
758
+ discordMessageSchema,
759
+ integrationProviderSchema,
760
+ discordServerSchema,
761
+ projectIntegrationSchema,
762
+ authProviderSchema,
763
+ accountConnectionSchema,
764
+ discordMemberInputSchema,
765
+ discordMessageInputSchema,
766
+ discordMemberSchema,
767
+ quizChoiceSchema,
768
+ quizQuestionSchema,
769
+ quizQuestionsSchema,
770
+ quizContentSchema,
771
+ resourceSourceSchema,
772
+ resourceRequestSchema,
773
+ resourceOptionsSchema,
774
+ discord,
775
+ settingFieldSchema,
776
+ settingsFieldsSchema,
777
+ settingsValuesSchema,
778
+ settings,
779
+ parseSettings,
780
+ missingResourceSettings,
781
+ compatibleSettingKinds,
782
+ pointsRewardSchema,
783
+ tieredRewardDefinitionSchema,
784
+ tierRewardSchema,
785
+ integrationRewardSchema,
786
+ rewardSchema,
787
+ rewardKey,
788
+ triggerSchema,
789
+ prerequisiteSchema,
790
+ photoResultSchema,
791
+ decisionSchema,
792
+ reviewModeSchema,
793
+ rewardBundleSchema,
794
+ mediaUrlSchema,
795
+ questPresentationSchema,
796
+ questDescriptionSchema,
797
+ artifactSchema,
798
+ releaseSchema,
799
+ batchReleaseSchema,
800
+ questSettingsInputSchema,
801
+ publishedReleaseSchema,
802
+ templateSchema,
803
+ quizAnswersSchema,
804
+ quizEvidenceSchema,
805
+ submitSchema,
806
+ attemptSchema,
807
+ eventSchema,
808
+ pickupSelectionSchema,
809
+ pickupAllocationSchema,
810
+ pickupPolicySchema,
811
+ pickupCatalogSchema,
812
+ pickupAvailabilitySchema,
813
+ configurePickupSchema,
814
+ entitlementSchema,
815
+ beginHandoverSchema,
816
+ confirmHandoverSchema,
817
+ completionRecordSchema,
818
+ questAvailabilitySchema,
819
+ memberProgressSchema,
820
+ snapshotSchema,
821
+ evidenceSchema,
822
+ errorSchema,
823
+ staffDecisionSchema,
824
+ stockSchema,
825
+ reservationSchema,
826
+ reviewListSchema,
827
+ memberListSchema,
828
+ reviewItemSchema,
829
+ reviewPageSchema,
830
+ memberPageSchema
831
+ };