@domino-sdk/relay 0.3.0 → 0.5.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.
@@ -1,10 +1,25 @@
1
+ import {
2
+ leaderboardArtifactSchema,
3
+ leaderboardDefinitionSchema,
4
+ leaderboardPageSchema,
5
+ leaderboardPreviewSchema,
6
+ leaderboardQuerySchema,
7
+ publishedReferralSchema,
8
+ referralAcceptSchema,
9
+ referralArtifactSchema,
10
+ referralDefinitionSchema,
11
+ referralHistorySchema,
12
+ referralSummarySchema
13
+ } from "./chunk-TXL43HL3.js";
1
14
  import {
2
15
  authScopeSchema,
3
16
  exchangeResultSchema,
4
17
  sessionSchema
5
- } from "./chunk-6IXQRMGW.js";
18
+ } from "./chunk-QWRSUSNB.js";
6
19
  import {
20
+ accountConnectionSchema,
7
21
  attemptSchema,
22
+ authProviderSchema,
8
23
  entitlementSchema,
9
24
  errorSchema,
10
25
  evidenceSchema,
@@ -24,7 +39,20 @@ import {
24
39
  settingsValuesSchema,
25
40
  snapshotSchema,
26
41
  templateSchema
27
- } from "./chunk-C2KOMNLG.js";
42
+ } from "./chunk-3IQ4KUKF.js";
43
+
44
+ // src/resource-id.ts
45
+ var alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
46
+ function resourceId(prefix) {
47
+ let suffix = "";
48
+ while (suffix.length < 22) {
49
+ for (const byte of crypto.getRandomValues(new Uint8Array(32))) {
50
+ if (byte < 248) suffix += alphabet[byte % 62];
51
+ if (suffix.length === 22) break;
52
+ }
53
+ }
54
+ return `${prefix}_${suffix}`;
55
+ }
28
56
 
29
57
  // src/catalog.ts
30
58
  import { z } from "zod";
@@ -327,6 +355,23 @@ function submissions(transport, configuredStore, namespace) {
327
355
  });
328
356
  }
329
357
  const handle = {
358
+ async discard() {
359
+ return store.exclusive(key, async () => {
360
+ await currentSession();
361
+ const record = await read();
362
+ if (!record) return;
363
+ if (record.stage !== "submitted")
364
+ throw new Error(
365
+ "Resume the unfinished submission before starting over."
366
+ );
367
+ const attempt = await claim(record);
368
+ if (attempt.status !== "failed" && attempt.status !== "rejected")
369
+ throw new Error(
370
+ "Only a failed or rejected submission can be discarded."
371
+ );
372
+ await store.write(key, null);
373
+ });
374
+ },
330
375
  async status() {
331
376
  await currentSession();
332
377
  const record = await read();
@@ -447,6 +492,7 @@ function questActions(submission, latest) {
447
492
  kind: "status",
448
493
  view,
449
494
  status: handle.status,
495
+ discard: handle.discard,
450
496
  resume: () => run(handle.resume)
451
497
  };
452
498
  }
@@ -461,6 +507,7 @@ function questActions(submission, latest) {
461
507
  kind: "photo",
462
508
  view,
463
509
  status: handle.status,
510
+ discard: handle.discard,
464
511
  resume: () => run(handle.resume),
465
512
  submit: (file) => run(() => handle.submit(file))
466
513
  };
@@ -475,6 +522,7 @@ function questActions(submission, latest) {
475
522
  kind: "quiz",
476
523
  view,
477
524
  status: handle.status,
525
+ discard: handle.discard,
478
526
  resume: () => run(handle.resume),
479
527
  submit: (answers) => run(() => handle.submit(answers, { release: view.release }))
480
528
  };
@@ -489,6 +537,7 @@ function questActions(submission, latest) {
489
537
  kind: "claim",
490
538
  view,
491
539
  status: handle.status,
540
+ discard: handle.discard,
492
541
  resume: () => run(handle.resume),
493
542
  submit: () => run(handle.submit)
494
543
  };
@@ -643,11 +692,13 @@ function questConfiguration(release) {
643
692
 
644
693
  // src/deployments.ts
645
694
  import { z as z5 } from "zod";
646
- var projectDeploymentSchema = catalogDeploymentSchema.omit({ expectedRevision: true }).extend({
647
- releases: z5.array(releaseSchema).max(50).default([])
648
- }).refine(
649
- (value) => value.releases.length > 0 || value.types.length > 0 || value.collections.length > 0 || value.supportedInteractions !== void 0,
650
- "No resources configured. Add quests, questTypes, collections, or supportedInteractions to relay.json."
695
+ var projectCatalogArtifactSchema = catalogDeploymentSchema.omit({ expectedRevision: true }).extend({
696
+ referrals: z5.array(referralArtifactSchema).max(50).default([]),
697
+ leaderboards: z5.array(leaderboardArtifactSchema).max(50).default([])
698
+ });
699
+ var projectDeploymentSchema = projectCatalogArtifactSchema.extend({ releases: z5.array(releaseSchema).max(50).default([]) }).refine(
700
+ (value) => value.releases.length > 0 || value.leaderboards.length > 0 || value.referrals.length > 0 || value.types.length > 0 || value.collections.length > 0 || value.supportedInteractions !== void 0,
701
+ "No resources configured. Add quests, questTypes, leaderboards, collections, or supportedInteractions to relay.json."
651
702
  );
652
703
  var deploymentPreviewSchema = z5.object({
653
704
  id: identifier,
@@ -655,7 +706,9 @@ var deploymentPreviewSchema = z5.object({
655
706
  releases: z5.array(publishedReleaseSchema),
656
707
  types: z5.array(questTypeVersionSchema),
657
708
  collections: z5.array(questCollectionSchema),
658
- supportedInteractions: z5.array(interactionSchema)
709
+ supportedInteractions: z5.array(interactionSchema),
710
+ referrals: z5.array(publishedReferralSchema).default([]),
711
+ leaderboards: z5.array(leaderboardPreviewSchema).default([])
659
712
  });
660
713
  var publishDeploymentSchema = z5.object({ id: identifier }).strict();
661
714
  var deploymentResultSchema = deploymentPreviewSchema.extend({
@@ -796,6 +849,28 @@ function createRelayClient(options) {
796
849
  return quest;
797
850
  }
798
851
  return {
852
+ referrals: {
853
+ list: () => request("/v1/referrals", z7.array(referralDefinitionSchema)),
854
+ summary: () => request("/v1/referrals/me", referralSummarySchema),
855
+ history: (before) => request(
856
+ query("/v1/referrals/history", { before }),
857
+ referralHistorySchema
858
+ ),
859
+ accept: (input) => request("/v1/referrals/accept", z7.object({ ok: z7.literal(true) }), {
860
+ method: "POST",
861
+ body: JSON.stringify(referralAcceptSchema.parse(input))
862
+ })
863
+ },
864
+ leaderboards: {
865
+ list: () => request("/v1/leaderboards", z7.array(leaderboardDefinitionSchema)),
866
+ standings: (board, options2 = {}) => {
867
+ const parsed = leaderboardQuerySchema.parse(options2);
868
+ return request(
869
+ query(`/v1/leaderboards/${identifier.parse(board)}`, parsed),
870
+ leaderboardPageSchema
871
+ );
872
+ }
873
+ },
799
874
  quests: {
800
875
  get: getQuest,
801
876
  retry: async (view) => {
@@ -866,7 +941,7 @@ function createRelayClient(options) {
866
941
  z7.object({
867
942
  providers: z7.array(
868
943
  z7.object({
869
- provider: z7.enum(["google", "apple", "x", "discord"]),
944
+ provider: authProviderSchema,
870
945
  configured: z7.boolean()
871
946
  })
872
947
  ),
@@ -891,6 +966,12 @@ function createRelayClient(options) {
891
966
  json({ challenge, code })
892
967
  )
893
968
  ),
969
+ accounts: () => request("/v1/auth/accounts", z7.array(accountConnectionSchema)),
970
+ disconnect: (provider) => request(
971
+ "/v1/auth/accounts/disconnect",
972
+ z7.object({ ok: z7.boolean() }),
973
+ json({ provider })
974
+ ),
894
975
  connections: () => request(
895
976
  "/v1/auth/connections",
896
977
  z7.array(
@@ -902,9 +983,6 @@ function createRelayClient(options) {
902
983
  )
903
984
  ),
904
985
  session: () => request("/v1/auth/session", sessionSchema.nullable()),
905
- demoSignIn: (code) => changeSession(
906
- () => request("/v1/auth/demo", sessionSchema, json({ code }))
907
- ),
908
986
  signOut: () => changeSession(
909
987
  () => request("/v1/auth/logout", z7.object({ ok: z7.boolean() }), json({}))
910
988
  ),
@@ -1015,6 +1093,7 @@ function createRelayClient(options) {
1015
1093
  }
1016
1094
 
1017
1095
  export {
1096
+ resourceId,
1018
1097
  interactionSchema,
1019
1098
  questInteraction,
1020
1099
  questTypeVersionSchema,
@@ -1048,6 +1127,7 @@ export {
1048
1127
  collectionBeginSchema,
1049
1128
  collectionPreviewSchema,
1050
1129
  questConfiguration,
1130
+ projectCatalogArtifactSchema,
1051
1131
  projectDeploymentSchema,
1052
1132
  deploymentPreviewSchema,
1053
1133
  publishDeploymentSchema,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  identifier
3
- } from "./chunk-C2KOMNLG.js";
3
+ } from "./chunk-3IQ4KUKF.js";
4
4
 
5
5
  // src/auth.ts
6
6
  import { z } from "zod";
@@ -0,0 +1,335 @@
1
+ import {
2
+ identifier,
3
+ rewardSchema
4
+ } from "./chunk-3IQ4KUKF.js";
5
+
6
+ // src/referrals.ts
7
+ import { z } from "zod";
8
+ var amount = z.number().int().safe().nonnegative();
9
+ var reason = z.string().trim().min(1).max(1e3);
10
+ var referralDefinitionSchema = z.object({
11
+ id: identifier,
12
+ title: z.string().trim().min(1).max(120),
13
+ enabled: z.boolean().default(true),
14
+ qualification: z.discriminatedUnion("kind", [
15
+ z.object({ kind: z.literal("signup") }).strict(),
16
+ z.object({ kind: z.literal("quest"), quest: identifier }).strict(),
17
+ z.object({ kind: z.literal("external") }).strict()
18
+ ]),
19
+ inviterGroup: identifier.optional(),
20
+ rewards: z.object({
21
+ inviter: z.array(rewardSchema).max(10).default([]),
22
+ invitee: z.array(rewardSchema).max(10).default([])
23
+ }).strict().default({ inviter: [], invitee: [] }),
24
+ milestones: z.array(
25
+ z.object({
26
+ id: identifier,
27
+ count: amount.min(1),
28
+ rewards: z.array(rewardSchema).min(1).max(10)
29
+ }).strict()
30
+ ).max(30).default([]),
31
+ bonuses: z.array(
32
+ z.object({
33
+ id: identifier,
34
+ balance: identifier,
35
+ basisPoints: amount.min(1).max(1e4),
36
+ quests: z.array(identifier).min(1).max(100).optional(),
37
+ external: z.boolean().default(false),
38
+ durationDays: amount.min(1).max(36500).optional(),
39
+ maxPoints: amount.min(1).optional()
40
+ }).strict()
41
+ ).max(20).default([])
42
+ }).strict().superRefine((value, ctx) => {
43
+ for (const entries of [value.milestones, value.bonuses])
44
+ if (new Set(entries.map((e) => e.id)).size !== entries.length)
45
+ ctx.addIssue({ code: "custom", message: "Rule IDs must be unique" });
46
+ });
47
+ function defineReferral(input) {
48
+ return referralDefinitionSchema.parse(input);
49
+ }
50
+ var referralArtifactSchema = z.union([
51
+ referralDefinitionSchema,
52
+ z.object({ code: z.string().min(1).max(2e6) }).strict()
53
+ ]);
54
+ var publishedReferralSchema = z.object({
55
+ version: identifier,
56
+ definition: referralDefinitionSchema,
57
+ publishedAt: amount,
58
+ actor: z.string().nullable()
59
+ });
60
+ var referralAcceptSchema = z.object({ actionId: identifier, code: identifier }).strict();
61
+ var referralControlSchema = z.discriminatedUnion("kind", [
62
+ z.object({
63
+ kind: z.literal("suspend"),
64
+ actionId: identifier,
65
+ member: identifier,
66
+ suspended: z.boolean(),
67
+ reason
68
+ }).strict(),
69
+ z.object({
70
+ kind: z.literal("qualify"),
71
+ actionId: identifier,
72
+ member: identifier,
73
+ program: identifier,
74
+ qualified: z.boolean(),
75
+ reason
76
+ }).strict(),
77
+ z.object({
78
+ kind: z.literal("resolve-reward"),
79
+ actionId: identifier,
80
+ entitlement: identifier,
81
+ reason
82
+ }).strict()
83
+ ]);
84
+ var referralRelationshipSchema = z.object({
85
+ member: identifier,
86
+ inviter: identifier,
87
+ acceptedAt: amount,
88
+ suspended: z.boolean()
89
+ });
90
+ var referralAccountSchema = z.object({
91
+ id: identifier,
92
+ program: identifier,
93
+ kind: z.enum(["bonus", "fixed", "milestone"]),
94
+ balance: identifier,
95
+ earned: amount,
96
+ settled: amount,
97
+ outstanding: amount
98
+ });
99
+ var referralSummarySchema = z.object({
100
+ code: identifier,
101
+ attributed: amount,
102
+ programs: z.array(
103
+ z.object({
104
+ definition: referralDefinitionSchema,
105
+ qualified: amount,
106
+ milestones: z.array(
107
+ z.object({ id: identifier, count: amount, reached: z.boolean() })
108
+ )
109
+ })
110
+ ),
111
+ accounts: z.array(referralAccountSchema)
112
+ });
113
+ var referralHistorySchema = z.object({
114
+ items: z.array(
115
+ z.object({
116
+ id: amount,
117
+ program: identifier,
118
+ balance: identifier,
119
+ amount: z.number().int().safe(),
120
+ at: amount,
121
+ reason: z.string()
122
+ })
123
+ ),
124
+ next: amount.nullable()
125
+ });
126
+ var referralManagementSchema = z.object({
127
+ relationships: z.array(referralRelationshipSchema),
128
+ qualifications: z.array(
129
+ z.object({
130
+ member: identifier,
131
+ program: identifier,
132
+ qualified: z.boolean(),
133
+ qualifiedAt: amount
134
+ })
135
+ ),
136
+ accounts: z.array(
137
+ referralAccountSchema.extend({ member: identifier, invitee: z.string() })
138
+ ),
139
+ reviews: z.array(
140
+ z.object({
141
+ entitlement: identifier,
142
+ member: identifier,
143
+ program: identifier,
144
+ reason: z.string()
145
+ })
146
+ ),
147
+ next: amount.nullable()
148
+ });
149
+
150
+ // src/leaderboards.ts
151
+ import { z as z2 } from "zod";
152
+ var integer = z2.number().int().safe();
153
+ var timestamp = integer.nonnegative().max(864e13);
154
+ var leaderboardWindowSchema = z2.discriminatedUnion("kind", [
155
+ z2.object({ kind: z2.literal("all-time") }).strict(),
156
+ z2.object({ kind: z2.literal("fixed"), start: timestamp, end: timestamp }).strict().refine((w) => w.end > w.start, "Window end must follow its start"),
157
+ z2.object({ kind: z2.literal("rolling"), days: integer.min(1).max(3660) }).strict(),
158
+ z2.object({
159
+ kind: z2.literal("calendar"),
160
+ period: z2.enum(["day", "week", "month"]),
161
+ timeZone: z2.string().min(1).max(100).refine((zone) => {
162
+ try {
163
+ new Intl.DateTimeFormat("en", { timeZone: zone });
164
+ return true;
165
+ } catch {
166
+ return false;
167
+ }
168
+ }, "Use an IANA timezone")
169
+ }).strict()
170
+ ]);
171
+ var periodScore = {
172
+ window: leaderboardWindowSchema.default({ kind: "all-time" }),
173
+ quests: z2.array(identifier).min(1).max(100).optional()
174
+ };
175
+ var leaderboardDefinitionSchema = z2.object({
176
+ id: identifier,
177
+ title: z2.string().trim().min(1).max(120),
178
+ balance: identifier,
179
+ score: z2.discriminatedUnion("kind", [
180
+ z2.object({ kind: z2.literal("balance") }).strict(),
181
+ z2.object({ kind: z2.literal("earned"), ...periodScore }).strict(),
182
+ z2.object({
183
+ kind: z2.literal("net"),
184
+ window: leaderboardWindowSchema.default({ kind: "all-time" })
185
+ }).strict()
186
+ ]).default({ kind: "balance" }),
187
+ access: z2.enum(["participants", "public"]).default("participants"),
188
+ group: identifier.optional()
189
+ }).strict();
190
+ function defineLeaderboard(input) {
191
+ return leaderboardDefinitionSchema.parse(input);
192
+ }
193
+ var leaderboardArtifactSchema = z2.union([
194
+ leaderboardDefinitionSchema,
195
+ z2.object({ code: z2.string().min(1).max(2e6) }).strict()
196
+ ]);
197
+ var publishedLeaderboardSchema = z2.object({
198
+ version: identifier,
199
+ definition: leaderboardDefinitionSchema,
200
+ publishedAt: timestamp,
201
+ actor: z2.string().nullable()
202
+ });
203
+ var leaderboardQuerySchema = z2.object({
204
+ limit: z2.coerce.number().int().min(1).max(100).default(25),
205
+ cursor: z2.string().max(4096).optional()
206
+ }).strict();
207
+ var leaderboardRowSchema = z2.object({
208
+ participant: identifier,
209
+ member: identifier.optional(),
210
+ name: z2.string(),
211
+ score: integer,
212
+ rank: integer.positive()
213
+ });
214
+ var leaderboardPageSchema = z2.object({
215
+ leaderboard: identifier,
216
+ title: z2.string(),
217
+ version: identifier,
218
+ calculation: z2.enum(["balance", "earned", "net"]),
219
+ period: z2.object({ start: timestamp.nullable(), end: timestamp.nullable() }),
220
+ calculatedAt: timestamp,
221
+ lastEntryAt: timestamp.nullable(),
222
+ total: integer.nonnegative(),
223
+ items: z2.array(leaderboardRowSchema),
224
+ me: leaderboardRowSchema.nullable(),
225
+ nearby: z2.array(leaderboardRowSchema),
226
+ nextCursor: z2.string().nullable()
227
+ });
228
+ var leaderboardPreviewSchema = z2.object({
229
+ published: publishedLeaderboardSchema,
230
+ before: leaderboardPageSchema.nullable(),
231
+ after: leaderboardPageSchema
232
+ });
233
+ var mutationBase = {
234
+ actionId: identifier,
235
+ member: identifier,
236
+ balance: identifier,
237
+ reason: z2.string().trim().min(1).max(1e3)
238
+ };
239
+ var datedMutation = { ...mutationBase, effectiveAt: timestamp.optional() };
240
+ var pointsMutationSchema = z2.discriminatedUnion("kind", [
241
+ z2.object({
242
+ ...datedMutation,
243
+ kind: z2.literal("award"),
244
+ referralEligible: z2.boolean().optional(),
245
+ amount: integer.positive()
246
+ }).strict(),
247
+ z2.object({
248
+ ...datedMutation,
249
+ kind: z2.literal("spend"),
250
+ amount: integer.positive()
251
+ }).strict(),
252
+ z2.object({
253
+ ...datedMutation,
254
+ kind: z2.literal("adjust"),
255
+ amount: integer.refine((n) => n !== 0)
256
+ }).strict(),
257
+ z2.object({
258
+ ...datedMutation,
259
+ kind: z2.literal("set"),
260
+ total: integer.nonnegative(),
261
+ expectedTotal: integer.nonnegative(),
262
+ classification: z2.enum(["earned", "spend"])
263
+ }).strict(),
264
+ z2.object({
265
+ ...mutationBase,
266
+ kind: z2.literal("reverse"),
267
+ entry: identifier,
268
+ amount: integer.positive()
269
+ }).strict()
270
+ ]);
271
+ var pointsEntrySchema = z2.object({
272
+ id: identifier,
273
+ completion: z2.string().nullable(),
274
+ member: identifier,
275
+ balance: identifier,
276
+ amount: integer,
277
+ kind: z2.enum(["award", "spend", "adjust", "reverse"]),
278
+ effectiveAt: timestamp,
279
+ receivedAt: timestamp,
280
+ quest: identifier.nullable(),
281
+ original: identifier.nullable(),
282
+ reason: z2.string(),
283
+ actor: z2.string().nullable()
284
+ });
285
+ var pointsResultSchema = z2.object({
286
+ entry: pointsEntrySchema,
287
+ total: integer.nonnegative()
288
+ });
289
+ var pointsAccountSchema = z2.object({
290
+ member: identifier,
291
+ balance: identifier,
292
+ total: integer.nonnegative(),
293
+ held: integer.nonnegative()
294
+ });
295
+ var leaderboardExclusionSchema = z2.object({
296
+ actionId: identifier,
297
+ member: identifier,
298
+ excluded: z2.boolean(),
299
+ reason: z2.string().trim().min(1).max(1e3)
300
+ }).strict();
301
+ var leaderboardGroupSchema = z2.object({
302
+ actionId: identifier,
303
+ member: identifier,
304
+ included: z2.boolean(),
305
+ reason: z2.string().trim().min(1).max(1e3)
306
+ }).strict();
307
+
308
+ export {
309
+ referralDefinitionSchema,
310
+ defineReferral,
311
+ referralArtifactSchema,
312
+ publishedReferralSchema,
313
+ referralAcceptSchema,
314
+ referralControlSchema,
315
+ referralRelationshipSchema,
316
+ referralAccountSchema,
317
+ referralSummarySchema,
318
+ referralHistorySchema,
319
+ referralManagementSchema,
320
+ leaderboardWindowSchema,
321
+ leaderboardDefinitionSchema,
322
+ defineLeaderboard,
323
+ leaderboardArtifactSchema,
324
+ publishedLeaderboardSchema,
325
+ leaderboardQuerySchema,
326
+ leaderboardRowSchema,
327
+ leaderboardPageSchema,
328
+ leaderboardPreviewSchema,
329
+ pointsMutationSchema,
330
+ pointsEntrySchema,
331
+ pointsResultSchema,
332
+ pointsAccountSchema,
333
+ leaderboardExclusionSchema,
334
+ leaderboardGroupSchema
335
+ };