@domino-sdk/relay 1.0.0-next.2 → 1.0.0-next.34
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.
- package/README.md +13 -1
- package/build.mjs +18 -1
- package/dist/activity-B8k9Sa_a.d.ts +9112 -0
- package/dist/authoring.d.ts +1355 -182
- package/dist/authoring.js +658 -225
- package/dist/automatic-outcomes-B1xrETxm.d.ts +758 -0
- package/dist/avatar.d.ts +29 -0
- package/dist/avatar.js +21 -0
- package/dist/browser-J7tUpXxy.d.ts +4154 -0
- package/dist/browser.d.ts +11 -4580
- package/dist/browser.js +8 -6
- package/dist/capability-error-DNMwKmlL.d.ts +458 -0
- package/dist/chunk-36HTX2BM.js +1223 -0
- package/dist/chunk-6QJ3LADK.js +112 -0
- package/dist/chunk-BGGKNIRP.js +171 -0
- package/dist/chunk-EYH5RDIE.js +496 -0
- package/dist/chunk-GQKYAQM6.js +84 -0
- package/dist/chunk-GUP7YRR4.js +42 -0
- package/dist/chunk-GZ6FJAXN.js +1659 -0
- package/dist/chunk-JON5SESL.js +2986 -0
- package/dist/chunk-MC6V6VMG.js +49 -0
- package/dist/chunk-NPGENI7K.js +37 -0
- package/dist/chunk-V7UKZLHA.js +35 -0
- package/dist/chunk-VFHHLN6A.js +284 -0
- package/dist/chunk-WJSSJ7AF.js +151 -0
- package/dist/{chunk-VH4OQ5VX.js → chunk-XFMSUPNS.js} +26 -5
- package/dist/{chunk-FDWRBMB3.js → chunk-ZVIRG24J.js} +150 -33
- package/dist/client-XiuFnug_.d.ts +4262 -0
- package/dist/groups-Ck-OxzjD.d.ts +2449 -0
- package/dist/identity-integration-GxAHdKR2.d.ts +58 -0
- package/dist/images-Dv-P5VBw.d.ts +234 -0
- package/dist/index.d.ts +15 -13115
- package/dist/index.js +30 -689
- package/dist/internal.d.ts +159 -0
- package/dist/internal.js +79 -0
- package/dist/offers-Cy-e4o5x.d.ts +431 -0
- package/dist/outcomes-kVB-Juzs.d.ts +4902 -0
- package/dist/pages-BBYD21IE.d.ts +359 -0
- package/dist/participant-rewards-3duLb8YJ.d.ts +668 -0
- package/dist/portal-proxy.js +26 -9
- package/dist/profiles-D2aFcOxu.d.ts +297 -0
- package/dist/react/index.d.ts +3378 -3318
- package/dist/react/index.js +1635 -783
- package/dist/request-error-DWduJCGV.d.ts +62 -0
- package/dist/schema-DfJzH2ci.d.ts +5644 -0
- package/dist/schema.d.ts +15 -3388
- package/dist/schema.js +790 -3
- package/dist/server/index.d.ts +81498 -0
- package/dist/server/index.js +2520 -0
- package/dist/streaks-CWyq8Px5.d.ts +71 -0
- package/dist/submission-input-BZkm6ohU.d.ts +290 -0
- package/dist/units-CwgsPB_r.d.ts +9 -0
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +1 -0
- package/dist/wallet-YssWxGg8.d.ts +228 -0
- package/package.json +24 -5
- package/dist/chunk-4KNTMNXA.js +0 -1847
- package/dist/chunk-B76BAJ25.js +0 -624
- package/dist/chunk-NKGJEYZM.js +0 -1833
- package/dist/chunk-ONDBQSMU.js +0 -373
- package/dist/submission-input-JDwq3EVK.d.ts +0 -4986
package/dist/authoring.js
CHANGED
|
@@ -1,55 +1,352 @@
|
|
|
1
1
|
import {
|
|
2
|
-
authoringKey,
|
|
3
|
-
defineEngagementReward,
|
|
4
|
-
defineLeaderboard,
|
|
5
|
-
defineReferral,
|
|
6
2
|
formatUnits,
|
|
7
3
|
parseUnits
|
|
8
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-V7UKZLHA.js";
|
|
5
|
+
import {
|
|
6
|
+
CapabilityError,
|
|
7
|
+
capabilityErrorCodes
|
|
8
|
+
} from "./chunk-MC6V6VMG.js";
|
|
9
|
+
import {
|
|
10
|
+
sourceDataSchema,
|
|
11
|
+
sourceRoles,
|
|
12
|
+
validateQuestShape
|
|
13
|
+
} from "./chunk-GQKYAQM6.js";
|
|
9
14
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
cosmosDenomSchema,
|
|
16
|
+
cosmosNetworkSchema,
|
|
17
|
+
defineOffer,
|
|
18
|
+
engagementDefinitionSchema,
|
|
19
|
+
engagementScoreInputSchema,
|
|
20
|
+
engagementScoreSchema,
|
|
21
|
+
isEvmChainId,
|
|
22
|
+
leaderboardAuthoringSchema,
|
|
23
|
+
pointLedgerDeclarationSchema,
|
|
24
|
+
referralAuthoringSchema
|
|
25
|
+
} from "./chunk-36HTX2BM.js";
|
|
26
|
+
import "./chunk-NPGENI7K.js";
|
|
12
27
|
import {
|
|
13
|
-
|
|
28
|
+
authoringKey,
|
|
29
|
+
balanceAtLeast,
|
|
14
30
|
budgetSchema,
|
|
15
|
-
|
|
31
|
+
completed,
|
|
32
|
+
contentMetricNameSchema,
|
|
16
33
|
contentPerformancePolicySchema,
|
|
17
34
|
contentPerformanceSnapshotSchema,
|
|
18
|
-
|
|
35
|
+
counterGoalSchema,
|
|
36
|
+
counterPolicySchema,
|
|
37
|
+
counterWindowSchema,
|
|
38
|
+
customSourceSchema,
|
|
19
39
|
decisionSchema,
|
|
20
40
|
defaultTriggerMode,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
41
|
+
defineCampaign,
|
|
42
|
+
defineGroup,
|
|
43
|
+
discordMessagesSourceSchema,
|
|
44
|
+
discordReactionsSourceSchema,
|
|
45
|
+
discordRewardSchema,
|
|
46
|
+
evaluatorIntegrationProviderSchema,
|
|
47
|
+
evaluatorProtocol,
|
|
48
|
+
identifier,
|
|
49
|
+
inGroup,
|
|
50
|
+
ledgerKey,
|
|
51
|
+
ledgerSettingSchema,
|
|
24
52
|
parseSettings,
|
|
25
|
-
perContent,
|
|
26
|
-
pointLedgers,
|
|
27
53
|
pointsRewardSchema,
|
|
28
54
|
questDescriptionSchema,
|
|
29
55
|
quizAnswersSchema,
|
|
56
|
+
quizContentSchema,
|
|
57
|
+
resourceHandle,
|
|
58
|
+
resourceSourceSchema,
|
|
30
59
|
rewardBundleSchema,
|
|
60
|
+
schemaCheckedReader,
|
|
31
61
|
settingFieldSchema,
|
|
32
|
-
|
|
62
|
+
settingInstant,
|
|
63
|
+
settingResourceId,
|
|
64
|
+
sourceContent,
|
|
33
65
|
sourceIdentities,
|
|
34
|
-
|
|
66
|
+
streakPolicySchema,
|
|
35
67
|
textOptionsSchema,
|
|
36
68
|
tierRewardSchema,
|
|
37
69
|
tieredRewardDefinitionSchema,
|
|
70
|
+
trackerDataIssue,
|
|
71
|
+
trackerDataSchema,
|
|
72
|
+
trackerDefinitionSchema,
|
|
38
73
|
trackerTriggerContextSchema,
|
|
39
74
|
trackerTriggerPolicySchema,
|
|
40
75
|
urlOptionsSchema,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
76
|
+
whereSchemaIssue,
|
|
77
|
+
whereSettings,
|
|
78
|
+
xSearchSourceSchema
|
|
79
|
+
} from "./chunk-JON5SESL.js";
|
|
44
80
|
|
|
45
|
-
// src/
|
|
81
|
+
// src/builders.ts
|
|
46
82
|
import { z } from "zod";
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
83
|
+
function defineLedger(input) {
|
|
84
|
+
return resourceHandle("ledger", pointLedgerDeclarationSchema.parse(input));
|
|
85
|
+
}
|
|
86
|
+
function defineEngagementReward(input) {
|
|
87
|
+
const { target, ledger, ...config } = input;
|
|
88
|
+
const definition = engagementDefinitionSchema.parse({
|
|
89
|
+
...config,
|
|
90
|
+
qualifiedBy: input.qualifiedBy.key,
|
|
91
|
+
balance: ledgerKey(ledger)
|
|
92
|
+
});
|
|
93
|
+
const selected = z.record(
|
|
94
|
+
z.enum(input.metrics),
|
|
95
|
+
engagementScoreSchema.shape.target
|
|
96
|
+
);
|
|
97
|
+
return {
|
|
98
|
+
key: definition.key,
|
|
99
|
+
describe: () => definition,
|
|
100
|
+
score(raw) {
|
|
101
|
+
const sample = engagementScoreInputSchema.parse(raw);
|
|
102
|
+
return engagementScoreSchema.parse({
|
|
103
|
+
target: target({ metrics: selected.parse(sample.metrics) }),
|
|
104
|
+
baseline: target({ metrics: selected.parse(sample.baseline) })
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
var streak = (options) => {
|
|
110
|
+
if ("timeZone" in options) {
|
|
111
|
+
throw new Error(
|
|
112
|
+
"streak() no longer takes a timeZone. Set the project timezone with calendar.timeZone in relay.json or in Console settings."
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
return streakPolicySchema.strict().parse({ kind: "streak", ...options });
|
|
116
|
+
};
|
|
117
|
+
var count = (count2) => counterGoalSchema.brand().parse({ kind: "count", count: count2 });
|
|
118
|
+
var calendar = (period, options = {}) => counterWindowSchema.brand().parse({ kind: "calendar", period, ...options });
|
|
119
|
+
var rolling = ({ days }) => counterWindowSchema.brand().parse({ kind: "rolling", durationMs: days * 864e5 });
|
|
120
|
+
var questCompleted = (quest) => ({
|
|
121
|
+
kind: "quest",
|
|
122
|
+
quest
|
|
123
|
+
});
|
|
124
|
+
function defineReferral(input) {
|
|
125
|
+
const { qualification, inviterGroup, milestones, bonuses, ...properties } = input;
|
|
126
|
+
const definition = referralAuthoringSchema.parse({
|
|
127
|
+
...properties,
|
|
128
|
+
qualification: qualification.kind === "quest" ? { kind: "quest", quest: qualification.quest.key } : qualification,
|
|
129
|
+
...inviterGroup ? { inviterGroup: identifier.parse(inviterGroup.key) } : {},
|
|
130
|
+
milestones: milestones?.map(({ key, ...rule }) => ({
|
|
131
|
+
...rule,
|
|
132
|
+
id: authoringKey({ key, ...rule })
|
|
133
|
+
})),
|
|
134
|
+
bonuses: bonuses?.map(({ key, ledger, quests, ...rule }) => ({
|
|
135
|
+
...rule,
|
|
136
|
+
id: authoringKey({ key, ...rule }),
|
|
137
|
+
balance: ledgerKey(ledger),
|
|
138
|
+
quests: quests?.map((quest) => quest.key)
|
|
139
|
+
}))
|
|
140
|
+
});
|
|
141
|
+
return resourceHandle("referral", definition);
|
|
142
|
+
}
|
|
143
|
+
function earned(options = {}) {
|
|
144
|
+
return { kind: "earned", ...options };
|
|
145
|
+
}
|
|
146
|
+
function defineLeaderboard(input) {
|
|
147
|
+
const { ledger, group, score, ...properties } = input;
|
|
148
|
+
const definition = leaderboardAuthoringSchema.parse({
|
|
149
|
+
...properties,
|
|
150
|
+
balance: ledgerKey(ledger),
|
|
151
|
+
...group ? { group: identifier.parse(group.key) } : {},
|
|
152
|
+
score: score?.kind === "earned" ? { ...score, quests: score.quests?.map((quest) => quest.key) } : score
|
|
153
|
+
});
|
|
154
|
+
return resourceHandle("leaderboard", definition);
|
|
155
|
+
}
|
|
156
|
+
var x = {
|
|
157
|
+
provider: "x",
|
|
158
|
+
/**
|
|
159
|
+
* Posts matching an X search. Each record's `data` is the provider's post payload. Its content
|
|
160
|
+
* is the post's normalized body (`XContentBody`), measured by the six X counters, so `content()`
|
|
161
|
+
* quests can use it.
|
|
162
|
+
*/
|
|
163
|
+
search: (input) => xSearchSourceSchema.parse({ kind: "x-search", ...input })
|
|
164
|
+
};
|
|
165
|
+
function customSource(namespace, options) {
|
|
166
|
+
const { data, content: content2, ...rest } = options ?? {};
|
|
167
|
+
if (content2 !== void 0) {
|
|
168
|
+
if (data !== void 0) {
|
|
169
|
+
throw new Error(
|
|
170
|
+
`customSource("${namespace}") takes data or content, not both: a content source's records carry { body, metrics }`
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
if (!isZodSchema(content2.body)) {
|
|
174
|
+
throw new Error(
|
|
175
|
+
`customSource("${namespace}") needs a content body schema: customSource(namespace, { content: { body: z.object({ ... }), metrics: ["likes"] } })`
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
const metrics = [...content2.metrics ?? []];
|
|
179
|
+
for (const metric of metrics) {
|
|
180
|
+
contentMetricNameSchema.parse(metric);
|
|
181
|
+
}
|
|
182
|
+
return customSourceSchema.parse({
|
|
183
|
+
kind: "custom",
|
|
184
|
+
namespace,
|
|
185
|
+
...rest,
|
|
186
|
+
data: trackerDataSchema(
|
|
187
|
+
z.object({
|
|
188
|
+
body: content2.body,
|
|
189
|
+
metrics: z.strictObject(
|
|
190
|
+
Object.fromEntries(
|
|
191
|
+
metrics.map((metric) => [
|
|
192
|
+
metric,
|
|
193
|
+
z.number().int().safe().nonnegative().optional()
|
|
194
|
+
])
|
|
195
|
+
)
|
|
196
|
+
).optional()
|
|
197
|
+
})
|
|
198
|
+
),
|
|
199
|
+
content: { metrics }
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
if (!isZodSchema(data)) {
|
|
203
|
+
throw new Error(
|
|
204
|
+
`customSource("${namespace}") needs a data schema: customSource(namespace, { data: z.object({ ... }) }) describes each record's data`
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
return customSourceSchema.parse({
|
|
208
|
+
kind: "custom",
|
|
209
|
+
namespace,
|
|
210
|
+
...rest,
|
|
211
|
+
data: trackerDataSchema(data)
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
function isZodSchema(value) {
|
|
215
|
+
return typeof value === "object" && value !== null && "_zod" in value;
|
|
216
|
+
}
|
|
217
|
+
function defineTracker(input) {
|
|
218
|
+
return resourceHandle(
|
|
219
|
+
"tracker",
|
|
220
|
+
trackerDefinitionSchema.parse(input)
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
function messages(options = {}) {
|
|
224
|
+
return discordMessagesSourceSchema.parse({
|
|
225
|
+
kind: "discord-messages",
|
|
226
|
+
...options.text ? { text: true } : {}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
function reactions() {
|
|
230
|
+
return discordReactionsSourceSchema.parse({ kind: "discord-reactions" });
|
|
231
|
+
}
|
|
232
|
+
var discord = {
|
|
50
233
|
provider: "discord",
|
|
51
|
-
|
|
52
|
-
|
|
234
|
+
grantRole: (roleId) => discordRewardSchema.parse({
|
|
235
|
+
kind: "integration",
|
|
236
|
+
provider: "discord",
|
|
237
|
+
action: "grant-role",
|
|
238
|
+
roleId
|
|
239
|
+
}),
|
|
240
|
+
messages,
|
|
241
|
+
reactions,
|
|
242
|
+
roles(options = {}) {
|
|
243
|
+
return resourceSourceSchema.parse({
|
|
244
|
+
provider: "discord",
|
|
245
|
+
resource: "role",
|
|
246
|
+
assignable: options.assignable ?? false
|
|
247
|
+
});
|
|
248
|
+
},
|
|
249
|
+
channels(options = {}) {
|
|
250
|
+
return resourceSourceSchema.parse({
|
|
251
|
+
provider: "discord",
|
|
252
|
+
resource: "channel",
|
|
253
|
+
types: options.types ?? ["text", "announcement"]
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
var pointLedgers = () => ({
|
|
258
|
+
provider: "domino",
|
|
259
|
+
resource: "point-ledger"
|
|
260
|
+
});
|
|
261
|
+
function setting(_kind, schema) {
|
|
262
|
+
return schema;
|
|
263
|
+
}
|
|
264
|
+
var settings = {
|
|
265
|
+
pointLedger(options) {
|
|
266
|
+
const field = {
|
|
267
|
+
...options,
|
|
268
|
+
kind: "point-ledger",
|
|
269
|
+
default: options.default ? identifier.parse(options.default.key) : ""
|
|
270
|
+
};
|
|
271
|
+
return setting(
|
|
272
|
+
"point-ledger",
|
|
273
|
+
ledgerSettingSchema.prefault(field.default).meta(field)
|
|
274
|
+
);
|
|
275
|
+
},
|
|
276
|
+
datetime(options) {
|
|
277
|
+
const field = {
|
|
278
|
+
...options,
|
|
279
|
+
kind: "datetime",
|
|
280
|
+
default: settingInstant.parse(options.default)
|
|
281
|
+
};
|
|
282
|
+
return setting(
|
|
283
|
+
"datetime",
|
|
284
|
+
settingInstant.default(field.default).meta(field)
|
|
285
|
+
);
|
|
286
|
+
},
|
|
287
|
+
resource(options) {
|
|
288
|
+
const field = {
|
|
289
|
+
...options,
|
|
290
|
+
source: resourceSourceSchema.parse(options.source),
|
|
291
|
+
kind: "resource",
|
|
292
|
+
default: settingResourceId.parse(options.default ?? "")
|
|
293
|
+
};
|
|
294
|
+
return setting(
|
|
295
|
+
"resource",
|
|
296
|
+
settingResourceId.default(field.default).meta(field)
|
|
297
|
+
);
|
|
298
|
+
},
|
|
299
|
+
quiz(options) {
|
|
300
|
+
const value = quizContentSchema.parse(options.default);
|
|
301
|
+
return setting(
|
|
302
|
+
"quiz",
|
|
303
|
+
quizContentSchema.default(value).meta({ ...options, default: value, kind: "quiz" })
|
|
304
|
+
);
|
|
305
|
+
},
|
|
306
|
+
text(options) {
|
|
307
|
+
const field = {
|
|
308
|
+
...options,
|
|
309
|
+
kind: "text",
|
|
310
|
+
minLength: options.minLength ?? 1,
|
|
311
|
+
maxLength: options.maxLength ?? 2e3,
|
|
312
|
+
multiline: options.multiline ?? false
|
|
313
|
+
};
|
|
314
|
+
return setting(
|
|
315
|
+
"text",
|
|
316
|
+
z.string().min(field.minLength).max(field.maxLength).default(field.default).meta(field)
|
|
317
|
+
);
|
|
318
|
+
},
|
|
319
|
+
integer(options) {
|
|
320
|
+
return setting(
|
|
321
|
+
"integer",
|
|
322
|
+
z.number().int().min(options.min).max(options.max).default(options.default).meta({ ...options, kind: "integer" })
|
|
323
|
+
);
|
|
324
|
+
},
|
|
325
|
+
boolean(options) {
|
|
326
|
+
return setting(
|
|
327
|
+
"boolean",
|
|
328
|
+
z.boolean().default(options.default).meta({ ...options, kind: "boolean" })
|
|
329
|
+
);
|
|
330
|
+
},
|
|
331
|
+
choice(options) {
|
|
332
|
+
return setting(
|
|
333
|
+
"choice",
|
|
334
|
+
z.enum(options.options).default(options.default).meta({ ...options, kind: "choice" })
|
|
335
|
+
);
|
|
336
|
+
},
|
|
337
|
+
/** A quest's settings: every field is built with one of the builders above. */
|
|
338
|
+
object(shape) {
|
|
339
|
+
return z.object(shape).strict();
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
// src/authoring.ts
|
|
344
|
+
import { z as z2 } from "zod";
|
|
345
|
+
import { z as z3 } from "zod";
|
|
346
|
+
var points = (ledger, amount) => pointsRewardSchema.parse({
|
|
347
|
+
kind: "points",
|
|
348
|
+
balance: ledgerKey(ledger),
|
|
349
|
+
amount
|
|
53
350
|
});
|
|
54
351
|
var evidence = {
|
|
55
352
|
text: (options = {}) => ({
|
|
@@ -78,60 +375,129 @@ function manual(options) {
|
|
|
78
375
|
...options?.actor ? { actor: options.actor } : {}
|
|
79
376
|
};
|
|
80
377
|
}
|
|
378
|
+
var triggerDataSchemas = /* @__PURE__ */ new WeakMap();
|
|
379
|
+
var triggerContentMetrics = /* @__PURE__ */ new WeakMap();
|
|
380
|
+
function trackerTrigger(input, constructor) {
|
|
381
|
+
const {
|
|
382
|
+
tracker,
|
|
383
|
+
beneficiary = "author",
|
|
384
|
+
on,
|
|
385
|
+
where,
|
|
386
|
+
enrollment,
|
|
387
|
+
since,
|
|
388
|
+
historical,
|
|
389
|
+
content: content2
|
|
390
|
+
} = input;
|
|
391
|
+
if (!tracker?.source) {
|
|
392
|
+
throw new Error(
|
|
393
|
+
constructor === "automatic" ? "automatic() takes no argument, or { tracker } with a tracker handle from defineTracker" : "content() takes { tracker } with a tracker handle from defineTracker"
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
const { source } = tracker;
|
|
397
|
+
if (!sourceIdentities(source)) {
|
|
398
|
+
throw new Error(
|
|
399
|
+
'Tracker triggers need attributable records: declare customSource(namespace, { identities: ["wallet"] }) or other identity kinds'
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
if (content2 && !sourceContent(source)) {
|
|
403
|
+
throw new Error(
|
|
404
|
+
`content() needs a tracker whose source has content: x.search(), or customSource(namespace, { content: { body, metrics } }). Tracker "${tracker.key}" has none; use automatic({ tracker }) instead.`
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
if (since === "enrollment" && enrollment !== "required") {
|
|
408
|
+
throw new Error(
|
|
409
|
+
`${constructor}() counts from enrollment only on a quest that requires it: add enrollment: "required"`
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
const roles = sourceRoles(source);
|
|
413
|
+
if (!roles.includes(beneficiary)) {
|
|
414
|
+
throw new Error(
|
|
415
|
+
source.kind === "custom" ? `Tracker "${tracker.key}" has no "${beneficiary}" account: declare it in customSource(namespace, { accounts: ["${beneficiary}"] })` : `Tracker "${tracker.key}" pays ${roles.map((role) => `"${role}"`).join(" or ")}, not "${beneficiary}"`
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
const policy = trackerTriggerPolicySchema.parse({
|
|
419
|
+
tracker: tracker.key,
|
|
420
|
+
source: source.kind,
|
|
421
|
+
// A content item is decided by its first observation; later observations run its stage.
|
|
422
|
+
on: content2 ? "new-record" : on ?? defaultTriggerMode(source.kind),
|
|
423
|
+
...where ? { where } : {},
|
|
424
|
+
beneficiary,
|
|
425
|
+
// Defaults are left out too: "none", "activation", and "staff" ("claim" on content).
|
|
426
|
+
...enrollment === "required" ? { enrollment } : {},
|
|
427
|
+
...since && since !== "activation" ? { since } : {},
|
|
428
|
+
...historical && historical !== (content2 ? "claim" : "staff") ? { historical } : {},
|
|
429
|
+
...content2 ? { content: content2 } : {}
|
|
430
|
+
});
|
|
431
|
+
const schema = sourceDataSchema(source);
|
|
432
|
+
const issue = schema ? whereSchemaIssue(schema, policy.where) : null;
|
|
433
|
+
if (issue) {
|
|
434
|
+
throw new Error(issue);
|
|
435
|
+
}
|
|
436
|
+
const trigger = { kind: "automatic", tracker: policy };
|
|
437
|
+
if (schema) {
|
|
438
|
+
triggerDataSchemas.set(trigger, schema);
|
|
439
|
+
}
|
|
440
|
+
const declared = sourceContent(source);
|
|
441
|
+
if (declared) {
|
|
442
|
+
triggerContentMetrics.set(trigger, declared.metrics);
|
|
443
|
+
}
|
|
444
|
+
return trigger;
|
|
445
|
+
}
|
|
81
446
|
function automatic(input) {
|
|
82
447
|
if (!input) {
|
|
83
448
|
return { kind: "automatic" };
|
|
84
449
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
if (!sourceIdentities(source)) {
|
|
94
|
-
throw new Error(
|
|
95
|
-
'Tracker triggers need attributable records: declare customSource(namespace, { identities: ["wallet"] }) or other identity kinds'
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
if (source.kind === "custom" && beneficiary !== "author" && !source.accounts?.includes(beneficiary)) {
|
|
99
|
-
throw new Error(
|
|
100
|
-
`Tracker "${tracker.key}" has no "${beneficiary}" account: declare it in customSource(namespace, { accounts: ["${beneficiary}"] })`
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
return {
|
|
104
|
-
kind: "automatic",
|
|
105
|
-
tracker: trackerTriggerPolicySchema.parse({
|
|
106
|
-
tracker: tracker.key,
|
|
107
|
-
source: source.kind,
|
|
108
|
-
// The source's default mode is left out, so default quests keep the policy shape
|
|
109
|
-
// earlier SDKs and servers read.
|
|
110
|
-
...on && on !== defaultTriggerMode(source.kind) ? { on } : {},
|
|
111
|
-
...where ? { where } : {},
|
|
112
|
-
beneficiary
|
|
113
|
-
})
|
|
114
|
-
};
|
|
450
|
+
return trackerTrigger(input, "automatic");
|
|
451
|
+
}
|
|
452
|
+
function content(input) {
|
|
453
|
+
if (input && typeof input === "object" && "source" in input && "key" in input && !("tracker" in input)) {
|
|
454
|
+
throw new Error(
|
|
455
|
+
"content() takes { tracker }: write content({ tracker: posts }) instead of content(posts)"
|
|
456
|
+
);
|
|
115
457
|
}
|
|
116
|
-
return {
|
|
458
|
+
return trackerTrigger({ ...input, content: true }, "content");
|
|
117
459
|
}
|
|
118
|
-
var budget = (definition) =>
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
460
|
+
var budget = (definition) => {
|
|
461
|
+
const { key: _, cost, ...properties } = definition;
|
|
462
|
+
return budgetSchema.parse({
|
|
463
|
+
...properties,
|
|
464
|
+
id: authoringKey(definition),
|
|
465
|
+
cost: typeof cost === "number" ? cost : { balance: ledgerKey(cost.ledger) }
|
|
466
|
+
});
|
|
467
|
+
};
|
|
468
|
+
var keyed = (key) => ({
|
|
469
|
+
kind: "keyed",
|
|
470
|
+
key
|
|
122
471
|
});
|
|
472
|
+
var progress = (definition) => {
|
|
473
|
+
const { distinct, ...policy } = definition;
|
|
474
|
+
return {
|
|
475
|
+
...counterPolicySchema.parse({
|
|
476
|
+
kind: "progress",
|
|
477
|
+
window: { kind: "lifetime" },
|
|
478
|
+
...policy
|
|
479
|
+
}),
|
|
480
|
+
distinct
|
|
481
|
+
};
|
|
482
|
+
};
|
|
123
483
|
var untracked = () => ({ kind: "untracked" });
|
|
124
484
|
var staffHandover = () => ({ kind: "staff-handover" });
|
|
485
|
+
var automaticFulfillment = () => ({ kind: "automatic" });
|
|
125
486
|
function defineTieredReward(input) {
|
|
126
|
-
const { key: _,
|
|
487
|
+
const { key: _, tiers, ...properties } = input;
|
|
127
488
|
const key = authoringKey(input);
|
|
128
|
-
const reward = tieredRewardDefinitionSchema.parse({
|
|
129
|
-
|
|
489
|
+
const reward = tieredRewardDefinitionSchema.parse({
|
|
490
|
+
id: key,
|
|
491
|
+
...properties,
|
|
492
|
+
tiers: tiers.map(({ key: key2, ...tier }) => ({
|
|
493
|
+
...tier,
|
|
494
|
+
id: authoringKey({ key: key2, ...tier })
|
|
495
|
+
}))
|
|
496
|
+
});
|
|
497
|
+
return resourceHandle("tiered-reward", {
|
|
130
498
|
key: reward.id,
|
|
131
|
-
/** @deprecated Authoring key alias. Use key. */
|
|
132
|
-
id: reward.id,
|
|
133
499
|
tier: (tier) => tierRewardSchema.parse({ kind: "tier", reward, tier })
|
|
134
|
-
};
|
|
500
|
+
});
|
|
135
501
|
}
|
|
136
502
|
var once = () => ({ kind: "once" });
|
|
137
503
|
function accept(options = {}) {
|
|
@@ -142,6 +508,11 @@ function review(options) {
|
|
|
142
508
|
}
|
|
143
509
|
var decision = {
|
|
144
510
|
accept,
|
|
511
|
+
defer: (options) => ({ kind: "defer", ...options }),
|
|
512
|
+
progress: (options) => ({
|
|
513
|
+
kind: "progress",
|
|
514
|
+
...options
|
|
515
|
+
}),
|
|
145
516
|
reject: (options) => ({
|
|
146
517
|
kind: "reject",
|
|
147
518
|
...options
|
|
@@ -152,7 +523,7 @@ var evaluators = {
|
|
|
152
523
|
quiz(answerKey, options = {}) {
|
|
153
524
|
const expected = quizAnswersSchema.parse(answerKey);
|
|
154
525
|
const questions = Object.keys(expected);
|
|
155
|
-
const minimum =
|
|
526
|
+
const minimum = z3.number().int().min(1).max(questions.length).parse(options.minimumCorrect ?? questions.length);
|
|
156
527
|
return async ({ input }) => {
|
|
157
528
|
const complete = Object.keys(input.answers).length === questions.length && questions.every((question) => Object.hasOwn(input.answers, question));
|
|
158
529
|
const correct = questions.filter(
|
|
@@ -175,206 +546,268 @@ var evaluators = {
|
|
|
175
546
|
};
|
|
176
547
|
}
|
|
177
548
|
};
|
|
178
|
-
function
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
if (definition.completion.kind === "streak" && (definition.trigger.kind !== "automatic" || !definition.trigger.observation)) {
|
|
195
|
-
throw new Error("Streaks require an automatic observation trigger");
|
|
196
|
-
}
|
|
197
|
-
const bareAutomatic = definition.trigger.kind === "automatic" && !definition.trigger.observation && !definition.trigger.content && !definition.trigger.tracker;
|
|
198
|
-
if (bareAutomatic && !definition.requires?.length) {
|
|
199
|
-
throw new Error(
|
|
200
|
-
"A bare automatic() quest needs at least one requires entry, such as requires: [completed(quest)]. Give it an observation, content or tracker trigger, or a prerequisite."
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
if (bareAutomatic && definition.completion.kind === "keyed") {
|
|
204
|
-
throw new Error(
|
|
205
|
-
"A bare automatic() quest cannot use keyed() completion. Give it an observation, content or tracker trigger, or use once()."
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
if (definition.trigger.kind === "manual" && definition.trigger.input !== "none" && !definition.evaluate) {
|
|
209
|
-
throw new Error("Evidence quests require an evaluator");
|
|
210
|
-
}
|
|
211
|
-
const fields = Object.fromEntries(
|
|
212
|
-
Object.entries(definition.settings.shape).map(([key2, schema]) => [
|
|
213
|
-
key2,
|
|
214
|
-
settingFieldSchema.parse(schema.meta())
|
|
215
|
-
])
|
|
216
|
-
);
|
|
217
|
-
const where = definition.trigger.kind === "automatic" ? definition.trigger.tracker?.where : void 0;
|
|
218
|
-
for (const bound of where && !("equals" in where) ? [where.gt, where.gte, where.lt, where.lte] : []) {
|
|
219
|
-
if (typeof bound === "object" && fields[bound.setting]?.kind !== "integer") {
|
|
549
|
+
function questBuilder(template) {
|
|
550
|
+
return function defineQuest2(definition) {
|
|
551
|
+
const key = authoringKey(definition);
|
|
552
|
+
const integrations = [
|
|
553
|
+
...new Set(
|
|
554
|
+
(definition.integrations ?? []).map(
|
|
555
|
+
(module) => evaluatorIntegrationProviderSchema.parse(module.provider)
|
|
556
|
+
)
|
|
557
|
+
)
|
|
558
|
+
];
|
|
559
|
+
const contentTrigger = definition.trigger.kind === "automatic" && definition.trigger.tracker?.content === true;
|
|
560
|
+
const trackerTrigger2 = definition.trigger.kind === "automatic" && definition.trigger.tracker !== void 0;
|
|
561
|
+
const completion = definition.completion;
|
|
562
|
+
if (contentTrigger && completion !== void 0) {
|
|
220
563
|
throw new Error(
|
|
221
|
-
|
|
564
|
+
"A content quest completes once per content item: remove its completion"
|
|
222
565
|
);
|
|
223
566
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
presentation: definition.presentation?.({ settings: settings2 }) ?? {},
|
|
236
|
-
fields,
|
|
237
|
-
values,
|
|
238
|
-
rewards,
|
|
239
|
-
humanReview: definition.review?.({ settings: settings2 })?.enabled ?? true,
|
|
240
|
-
trigger: definition.trigger,
|
|
241
|
-
...definition.performance ? {
|
|
242
|
-
performance: contentPerformancePolicySchema.parse({
|
|
567
|
+
if (!contentTrigger && completion === void 0) {
|
|
568
|
+
throw new Error(
|
|
569
|
+
"A quest needs a completion, such as once(), keyed(...), streak(...) or progress(...)"
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
validateQuestShape(
|
|
573
|
+
{
|
|
574
|
+
trigger: definition.trigger,
|
|
575
|
+
completion: completion ?? { kind: "keyed" },
|
|
576
|
+
requires: definition.requires ?? [],
|
|
577
|
+
performance: definition.performance ? contentPerformancePolicySchema.parse({
|
|
243
578
|
metrics: definition.performance.metrics,
|
|
244
579
|
maxAgeMs: definition.performance.maxAgeMs
|
|
245
|
-
})
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
describe,
|
|
271
|
-
async evaluate(ctx) {
|
|
272
|
-
const settings2 = definition.settings.parse(ctx.settings);
|
|
273
|
-
const tracker = trackerTrigger ? trackerTriggerContextSchema.parse(ctx.tracker) : null;
|
|
274
|
-
if (ctx.performance) {
|
|
275
|
-
if (!definition.performance) {
|
|
276
|
-
throw new Error("Quest has no performance evaluator");
|
|
580
|
+
}) : void 0
|
|
581
|
+
},
|
|
582
|
+
{ template }
|
|
583
|
+
);
|
|
584
|
+
if (definition.performance) {
|
|
585
|
+
const declared = triggerContentMetrics.get(definition.trigger) ?? [];
|
|
586
|
+
const unknown = definition.performance.metrics.filter(
|
|
587
|
+
(metric) => !declared.includes(metric)
|
|
588
|
+
);
|
|
589
|
+
if (unknown.length) {
|
|
590
|
+
throw new Error(
|
|
591
|
+
`The tracker's source does not measure ${unknown.join(", ")}`
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
if (definition.trigger.kind === "manual" && definition.trigger.input !== "none" && !definition.evaluate) {
|
|
596
|
+
throw new Error("Evidence quests require an evaluator");
|
|
597
|
+
}
|
|
598
|
+
const fields = Object.fromEntries(
|
|
599
|
+
Object.entries(definition.settings.shape).map(([key2, schema]) => {
|
|
600
|
+
const field = settingFieldSchema.safeParse(schema.meta());
|
|
601
|
+
if (!field.success) {
|
|
602
|
+
throw new Error(
|
|
603
|
+
`Setting "${key2}" is not a quest setting: build it with a settings builder, such as settings.integer({ label, default, min, max })`
|
|
604
|
+
);
|
|
277
605
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
606
|
+
return [key2, field.data];
|
|
607
|
+
})
|
|
608
|
+
);
|
|
609
|
+
for (const setting2 of whereSettings(
|
|
610
|
+
definition.trigger.kind === "automatic" ? definition.trigger.tracker?.where : void 0
|
|
611
|
+
)) {
|
|
612
|
+
if (fields[setting2]?.kind !== "integer") {
|
|
613
|
+
throw new Error(
|
|
614
|
+
`The tracker filter compares with setting "${setting2}", which is not an integer setting`
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
function describe(input) {
|
|
619
|
+
const settings2 = definition.settings.parse(input);
|
|
620
|
+
const values = parseSettings(fields, settings2);
|
|
621
|
+
const rewards = rewardBundleSchema.parse(
|
|
622
|
+
typeof definition.rewards === "function" ? definition.rewards({ settings: settings2 }) : definition.rewards
|
|
623
|
+
);
|
|
624
|
+
const required = [
|
|
625
|
+
...rewards.flatMap(
|
|
626
|
+
(reward) => reward.kind === "integration" ? [reward.provider] : []
|
|
627
|
+
),
|
|
628
|
+
...Object.values(fields).flatMap(
|
|
629
|
+
(field) => field.kind === "resource" && field.source.provider !== "domino" ? [field.source.provider] : []
|
|
630
|
+
)
|
|
631
|
+
];
|
|
632
|
+
for (const provider of required) {
|
|
633
|
+
if (!integrations.includes(provider)) {
|
|
634
|
+
throw new Error(`Declare the ${provider} integration on this quest`);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
return questDescriptionSchema.parse({
|
|
638
|
+
quest: key,
|
|
639
|
+
evaluatorProtocol,
|
|
640
|
+
title: typeof definition.title === "function" ? definition.title({ settings: settings2 }) : definition.title,
|
|
641
|
+
presentation: definition.presentation?.({ settings: settings2 }) ?? {},
|
|
642
|
+
fields,
|
|
643
|
+
values,
|
|
644
|
+
rewards,
|
|
645
|
+
humanReview: definition.review?.({ settings: settings2 })?.enabled ?? true,
|
|
646
|
+
trigger: definition.trigger,
|
|
647
|
+
...definition.performance ? {
|
|
648
|
+
performance: contentPerformancePolicySchema.parse({
|
|
649
|
+
metrics: definition.performance.metrics,
|
|
650
|
+
maxAgeMs: definition.performance.maxAgeMs
|
|
651
|
+
})
|
|
652
|
+
} : {},
|
|
653
|
+
integrations,
|
|
654
|
+
// A content quest's completion is keyed by its content item, with a key Relay owns.
|
|
655
|
+
completion: !completion ? { kind: "keyed" } : completion.kind === "progress" ? {
|
|
656
|
+
kind: completion.kind,
|
|
657
|
+
goal: completion.goal,
|
|
658
|
+
window: completion.window,
|
|
659
|
+
repeat: completion.repeat
|
|
660
|
+
} : completion.kind === "streak" ? completion : { kind: completion.kind },
|
|
661
|
+
visibility: definition.visibility ?? "visible",
|
|
662
|
+
profile: definition.profile ?? { visible: false },
|
|
663
|
+
budgets: definition.budgets ?? [],
|
|
664
|
+
requires: definition.requires ?? [],
|
|
665
|
+
...definition.campaign ? { campaign: definition.campaign } : {},
|
|
666
|
+
...definition.availability ? { availability: definition.availability } : {}
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
return resourceHandle("quest", {
|
|
670
|
+
protocol: evaluatorProtocol,
|
|
671
|
+
key,
|
|
672
|
+
describe,
|
|
673
|
+
async evaluate(ctx) {
|
|
674
|
+
const settings2 = definition.settings.parse(ctx.settings);
|
|
675
|
+
const pinned = trackerTrigger2 ? trackerTriggerContextSchema.parse(ctx.tracker) : null;
|
|
676
|
+
const schema = triggerDataSchemas.get(definition.trigger);
|
|
677
|
+
const dataIssue = pinned && schema ? trackerDataIssue(schema, pinned.record.data) : null;
|
|
678
|
+
if (dataIssue) {
|
|
679
|
+
return decisionSchema.parse({
|
|
680
|
+
kind: "reject",
|
|
681
|
+
reason: `The record's data does not match the data schema this quest was built with: ${dataIssue.path} ${dataIssue.reason}`
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
const tracker = pinned;
|
|
685
|
+
if (ctx.performance) {
|
|
686
|
+
if (!definition.performance) {
|
|
687
|
+
throw new Error("Quest has no performance evaluator");
|
|
688
|
+
}
|
|
689
|
+
const sample = contentPerformanceSnapshotSchema.parse(ctx.performance);
|
|
690
|
+
const metrics = z3.record(
|
|
691
|
+
z3.enum(definition.performance.metrics),
|
|
692
|
+
z3.number().int().safe().nonnegative()
|
|
693
|
+
).parse(sample.metrics);
|
|
694
|
+
const result2 = await definition.performance.evaluate({
|
|
695
|
+
settings: settings2,
|
|
696
|
+
member: ctx.member,
|
|
697
|
+
tracker,
|
|
698
|
+
metrics,
|
|
699
|
+
observedAt: sample.observedAt
|
|
700
|
+
});
|
|
701
|
+
if (!result2) {
|
|
702
|
+
throw new Error("Performance evaluator returned no decision");
|
|
703
|
+
}
|
|
704
|
+
if (result2.rewards !== void 0) {
|
|
705
|
+
throw new Error(
|
|
706
|
+
"A performance evaluator cannot select rewards. It gates the rewards content evaluation selected: return accept, review or reject with a reason only."
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
return decisionSchema.parse(
|
|
710
|
+
result2.kind === "accept" ? { kind: "accept", rewards: sample.rewards } : result2.kind === "review" && ctx.humanReview ? {
|
|
711
|
+
kind: "review",
|
|
712
|
+
reason: result2.reason,
|
|
713
|
+
rewards: sample.rewards
|
|
714
|
+
} : {
|
|
715
|
+
kind: "reject",
|
|
716
|
+
reason: result2.reason,
|
|
717
|
+
...result2.kind === "review" ? { requestedReview: true } : {}
|
|
718
|
+
}
|
|
719
|
+
);
|
|
720
|
+
}
|
|
721
|
+
const result = definition.evaluate ? await definition.evaluate({
|
|
284
722
|
settings: settings2,
|
|
285
723
|
member: ctx.member,
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
724
|
+
input: ctx.input,
|
|
725
|
+
tracker,
|
|
726
|
+
eligibleAt: ctx.eligibleAt,
|
|
727
|
+
calendar: ctx.calendar,
|
|
728
|
+
now: ctx.now,
|
|
729
|
+
review: ctx.review,
|
|
730
|
+
trackers: schemaCheckedReader(ctx.trackers),
|
|
731
|
+
wallet: ctx.wallet,
|
|
732
|
+
images: ctx.images,
|
|
733
|
+
// The declared module providers select these keys; unrelated host readers are omitted.
|
|
734
|
+
...Object.fromEntries(
|
|
735
|
+
integrations.map((provider) => [provider, ctx[provider]])
|
|
736
|
+
)
|
|
737
|
+
}) : decision.accept();
|
|
738
|
+
if (!result) {
|
|
739
|
+
throw new Error("Evaluator returned no decision");
|
|
292
740
|
}
|
|
293
|
-
if (
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
741
|
+
if (result.kind === "review" && !ctx.humanReview) {
|
|
742
|
+
return decisionSchema.parse({
|
|
743
|
+
kind: "reject",
|
|
744
|
+
reason: result.reason,
|
|
745
|
+
requestedReview: true
|
|
746
|
+
});
|
|
297
747
|
}
|
|
298
748
|
return decisionSchema.parse(
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
rewards:
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
rewards: sample.rewards
|
|
307
|
-
} : { kind: "reject", reason: result2.reason }
|
|
749
|
+
result.kind === "accept" || result.kind === "review" ? {
|
|
750
|
+
...result,
|
|
751
|
+
rewards: result.rewards ?? ctx.rewards,
|
|
752
|
+
...completion?.kind === "keyed" || completion?.kind === "progress" ? {
|
|
753
|
+
completionKey: completion.kind === "progress" ? completion.distinct({ ...ctx, tracker: pinned }) : result.completionKey ?? completion.key({ ...ctx, tracker: pinned })
|
|
754
|
+
} : {}
|
|
755
|
+
} : result
|
|
308
756
|
);
|
|
309
757
|
}
|
|
310
|
-
|
|
311
|
-
settings: settings2,
|
|
312
|
-
member: ctx.member,
|
|
313
|
-
input: ctx.input,
|
|
314
|
-
content: contentTrigger ? admittedContentSchema.parse(ctx.content) : null,
|
|
315
|
-
observation: ctx.observation ?? null,
|
|
316
|
-
tracker,
|
|
317
|
-
eligibleAt: ctx.eligibleAt,
|
|
318
|
-
review: ctx.review,
|
|
319
|
-
trackers: ctx.trackers,
|
|
320
|
-
wallet: ctx.wallet,
|
|
321
|
-
x: ctx.x,
|
|
322
|
-
images: ctx.images,
|
|
323
|
-
discord: ctx.discord
|
|
324
|
-
}) : decision.accept();
|
|
325
|
-
if (!result) {
|
|
326
|
-
throw new Error("Evaluator returned no decision");
|
|
327
|
-
}
|
|
328
|
-
if (result.kind === "review" && !ctx.humanReview) {
|
|
329
|
-
return decisionSchema.parse({ kind: "reject", reason: result.reason });
|
|
330
|
-
}
|
|
331
|
-
return decisionSchema.parse(
|
|
332
|
-
result.kind === "accept" || result.kind === "review" ? {
|
|
333
|
-
...result,
|
|
334
|
-
rewards: result.rewards ?? ctx.rewards,
|
|
335
|
-
...definition.completion.kind === "keyed" ? {
|
|
336
|
-
completionKey: definition.completion.key({
|
|
337
|
-
...ctx,
|
|
338
|
-
tracker
|
|
339
|
-
})
|
|
340
|
-
} : {}
|
|
341
|
-
} : result
|
|
342
|
-
);
|
|
343
|
-
}
|
|
758
|
+
});
|
|
344
759
|
};
|
|
345
760
|
}
|
|
346
|
-
var
|
|
761
|
+
var defineQuest = questBuilder(false);
|
|
762
|
+
var defineQuestType = questBuilder(true);
|
|
347
763
|
export {
|
|
764
|
+
CapabilityError,
|
|
348
765
|
automatic,
|
|
766
|
+
automaticFulfillment,
|
|
767
|
+
balanceAtLeast,
|
|
349
768
|
budget,
|
|
769
|
+
calendar,
|
|
770
|
+
capabilityErrorCodes,
|
|
350
771
|
completed,
|
|
351
772
|
content,
|
|
773
|
+
cosmosDenomSchema,
|
|
774
|
+
cosmosNetworkSchema,
|
|
775
|
+
count,
|
|
352
776
|
customSource,
|
|
353
777
|
decision,
|
|
778
|
+
defineCampaign,
|
|
354
779
|
defineEngagementReward,
|
|
780
|
+
defineGroup,
|
|
355
781
|
defineLeaderboard,
|
|
782
|
+
defineLedger,
|
|
783
|
+
defineOffer,
|
|
356
784
|
defineQuest,
|
|
357
785
|
defineQuestType,
|
|
358
786
|
defineReferral,
|
|
359
787
|
defineTieredReward,
|
|
360
788
|
defineTracker,
|
|
361
789
|
discord,
|
|
362
|
-
|
|
790
|
+
earned,
|
|
363
791
|
evaluators,
|
|
364
792
|
evidence,
|
|
365
793
|
formatUnits,
|
|
794
|
+
inGroup,
|
|
366
795
|
isEvmChainId,
|
|
367
796
|
keyed,
|
|
368
797
|
manual,
|
|
369
798
|
once,
|
|
370
799
|
parseUnits,
|
|
371
|
-
perContent,
|
|
372
800
|
pointLedgers,
|
|
373
801
|
points,
|
|
802
|
+
progress,
|
|
803
|
+
questCompleted,
|
|
804
|
+
rolling,
|
|
374
805
|
settings,
|
|
375
806
|
staffHandover,
|
|
376
807
|
streak,
|
|
808
|
+
trackerDataSchema,
|
|
377
809
|
trackerTriggerContextSchema,
|
|
378
810
|
untracked,
|
|
379
|
-
x
|
|
811
|
+
x,
|
|
812
|
+
z2 as z
|
|
380
813
|
};
|