@domino-sdk/relay 1.0.0-next.9 → 1.1.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.
- package/README.md +1 -1
- package/dist/activity-B8k9Sa_a.d.ts +9112 -0
- package/dist/authoring.d.ts +1053 -259
- package/dist/authoring.js +478 -277
- package/dist/automatic-outcomes-B1xrETxm.d.ts +758 -0
- package/dist/avatar.d.ts +2 -2
- package/dist/browser-J7tUpXxy.d.ts +4154 -0
- package/dist/browser.d.ts +11 -2613
- package/dist/browser.js +8 -6
- package/dist/{integrations-Ba5TtqTv.d.ts → capability-error-DNMwKmlL.d.ts} +124 -76
- package/dist/{chunk-PHU5VDLR.js → chunk-36HTX2BM.js} +389 -169
- package/dist/chunk-6QJ3LADK.js +112 -0
- package/dist/{chunk-4LBUTHD6.js → chunk-BGGKNIRP.js} +1 -1
- package/dist/chunk-EYH5RDIE.js +496 -0
- package/dist/chunk-GQKYAQM6.js +84 -0
- package/dist/chunk-GUP7YRR4.js +42 -0
- package/dist/{chunk-X2F2RAR3.js → chunk-GZ6FJAXN.js} +380 -128
- package/dist/chunk-JON5SESL.js +2986 -0
- package/dist/chunk-MC6V6VMG.js +49 -0
- package/dist/chunk-NPGENI7K.js +37 -0
- package/dist/chunk-VFHHLN6A.js +284 -0
- package/dist/chunk-WJSSJ7AF.js +151 -0
- package/dist/{chunk-7Q4BGGT6.js → chunk-XFMSUPNS.js} +1 -1
- package/dist/{chunk-P6FK43GG.js → chunk-ZVIRG24J.js} +145 -42
- package/dist/{client-CT4-S5vc.d.ts → client-XiuFnug_.d.ts} +2161 -615
- package/dist/{submission-input-0OOGaq8c.d.ts → groups-Ck-OxzjD.d.ts} +916 -1139
- package/dist/identity-integration-GxAHdKR2.d.ts +58 -0
- package/dist/images-Dv-P5VBw.d.ts +234 -0
- package/dist/index.d.ts +13 -9
- package/dist/index.js +17 -6
- package/dist/internal.d.ts +82 -44
- package/dist/internal.js +43 -89
- package/dist/offers-Cy-e4o5x.d.ts +431 -0
- package/dist/{pages-D3titw5B.d.ts → outcomes-kVB-Juzs.d.ts} +2157 -1448
- package/dist/pages-BBYD21IE.d.ts +359 -0
- package/dist/participant-rewards-3duLb8YJ.d.ts +668 -0
- package/dist/portal-proxy.js +22 -4
- package/dist/{profiles-DDMFBRKe.d.ts → profiles-D2aFcOxu.d.ts} +15 -15
- package/dist/react/index.d.ts +3038 -1029
- package/dist/react/index.js +1627 -779
- package/dist/request-error-DWduJCGV.d.ts +62 -0
- package/dist/schema-DfJzH2ci.d.ts +5644 -0
- package/dist/schema.d.ts +15 -4168
- package/dist/schema.js +310 -81
- package/dist/server/index.d.ts +81722 -0
- package/dist/server/index.js +2569 -0
- package/dist/{streaks-CwGReWGt.d.ts → streaks-CWyq8Px5.d.ts} +2 -4
- package/dist/submission-input-BZkm6ohU.d.ts +290 -0
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +1 -0
- package/dist/{wallet-BGOfFkG9.d.ts → wallet-YssWxGg8.d.ts} +35 -38
- package/package.json +8 -2
- package/dist/chunk-QR7ZA2BJ.js +0 -257
- package/dist/chunk-YYD4QUBO.js +0 -2348
- package/dist/chunk-ZWY3R6B3.js +0 -26
- package/dist/collection-BGneJ6Bk.d.ts +0 -114
- package/dist/images-BTgk6OmC.d.ts +0 -1564
- package/dist/point-ledgers-iS00Z_v0.d.ts +0 -37
- package/dist/schema-Di3aLSiK.d.ts +0 -3532
package/dist/authoring.d.ts
CHANGED
|
@@ -1,56 +1,34 @@
|
|
|
1
|
+
import { cB as xContentBodySchema, I as IdentityKind, aM as customSourceSchema, at as WithRecordData, as as WithContent, ar as WithAccountRoles, cG as QuestHandle, cH as LedgerReference, cI as GroupHandle, cF as ResourceHandle, ad as TrackerSource, c1 as trackerDefinitionSchema, U as Tracker, $ as TrackerData, H as SourceRoles, cJ as LedgerHandle, cD as xSearchSourceSchema, av as XTweet, au as XContentMetric, aj as TrackerTriggerPolicy, ap as Where, r as MemberIdentity, ah as TrackerTriggerContext, ab as TrackerReader, L as TextReviewInput, J as TextResult, P as PhotoResult, n as Decision, by as rewardSchema, ai as TrackerTriggerMode, F as RoleOf, aq as WhereSetting, k as ContentBody, l as ContentMetricName, cw as triggerSchema, d as QuestPresentation, e as QuestProfile, f as QuizEvidence, N as TieredRewardDefinition } from './schema-DfJzH2ci.js';
|
|
2
|
+
export { cK as LedgerSetting, a1 as TrackerDataSchema, a6 as TrackerPage, aa as TrackerReadQuery, cL as trackerDataSchema, cn as trackerTriggerContextSchema } from './schema-DfJzH2ci.js';
|
|
1
3
|
import { z } from 'zod';
|
|
2
4
|
export { z } from 'zod';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import { d as
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
import { E as EngagementBudget, a4 as leaderboardDefinitionSchema, aQ as AuthoringIdentity, au as pointLedgerDeclarationSchema, aJ as referralAuthoringSchema, C as CampaignDefinition, A as AvailabilityWindow } from './groups-Ck-OxzjD.js';
|
|
6
|
+
export { G as defineCampaign, H as defineGroup } from './groups-Ck-OxzjD.js';
|
|
7
|
+
import { u as discordMessagesSourceSchema, e as DiscordMessageData, f as DiscordMessageTextData, w as discordReactionsSourceSchema, g as DiscordReactionData, h as DiscordReader, P as Prerequisite, T as TextEvidence, U as UrlEvidence, b as TextOptions, c as UrlOptions } from './submission-input-BZkm6ohU.js';
|
|
8
|
+
export { k as balanceAtLeast, m as completed, B as inGroup } from './submission-input-BZkm6ohU.js';
|
|
9
|
+
import { Q as QuizContent, a as StreakPolicy } from './streaks-CWyq8Px5.js';
|
|
10
|
+
import { d as ResourceSource, S as Setting, b as IntegrationModule, i as XReader, B as Budget, I as IntegerSettings } from './capability-error-DNMwKmlL.js';
|
|
11
|
+
export { L as CapabilityError, C as CapabilityErrorCode, k as capabilityErrorCodes } from './capability-error-DNMwKmlL.js';
|
|
12
|
+
import { e as ImageReader } from './images-Dv-P5VBw.js';
|
|
13
|
+
export { e as defineOffer } from './offers-Cy-e4o5x.js';
|
|
14
|
+
import { l as WalletReader } from './wallet-YssWxGg8.js';
|
|
15
|
+
export { h as CosmosDenom, a as CosmosNetwork, E as EvmChainId, j as WalletBalance, k as WalletBalanceQuery, p as cosmosDenomSchema, q as cosmosNetworkSchema, t as isEvmChainId } from './wallet-YssWxGg8.js';
|
|
11
16
|
export { f as formatUnits, p as parseUnits } from './units-CwgsPB_r.js';
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
18
|
+
declare function defineLedger(input: z.input<typeof pointLedgerDeclarationSchema>): {
|
|
19
|
+
name: string;
|
|
20
|
+
description: string;
|
|
15
21
|
key: string;
|
|
16
|
-
|
|
17
|
-
} | {
|
|
18
|
-
key?: never; /** @deprecated Use key. */
|
|
19
|
-
id: string;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/** Discover posts automatically; historical release remains an explicit policy. */
|
|
23
|
-
declare function content(tracker: TrackerDefinition, policy?: Partial<Pick<ContentPolicy, "enrollment" | "posts" | "historical">>): {
|
|
24
|
-
kind: "automatic";
|
|
25
|
-
content: {
|
|
26
|
-
tracker: string;
|
|
27
|
-
window: {
|
|
28
|
-
start: number;
|
|
29
|
-
end?: number | undefined;
|
|
30
|
-
};
|
|
31
|
-
enrollment: "required" | "none";
|
|
32
|
-
posts: "after-enrollment" | "since-start";
|
|
33
|
-
historical: "staff" | "automatic" | "claim";
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
declare function perContent(): {
|
|
37
|
-
kind: "keyed";
|
|
38
|
-
perContent: true;
|
|
39
|
-
key: (ctx: {
|
|
40
|
-
content?: AdmittedContent | null;
|
|
41
|
-
}) => string;
|
|
42
|
-
};
|
|
22
|
+
} & ResourceHandle<"ledger">;
|
|
43
23
|
/** One independent cumulative formula; management changes capture a new scoring boundary. */
|
|
44
|
-
declare function defineEngagementReward<const M extends readonly [
|
|
24
|
+
declare function defineEngagementReward<const M extends readonly [string, ...string[]]>(input: {
|
|
45
25
|
key: string;
|
|
46
|
-
qualifiedBy:
|
|
47
|
-
|
|
48
|
-
};
|
|
49
|
-
balance: string;
|
|
26
|
+
qualifiedBy: QuestHandle;
|
|
27
|
+
ledger: LedgerReference;
|
|
50
28
|
metrics: M;
|
|
51
29
|
baseline: "historical";
|
|
52
30
|
maxAgeMs?: number;
|
|
53
|
-
|
|
31
|
+
budgets?: EngagementBudget[];
|
|
54
32
|
target: (input: {
|
|
55
33
|
metrics: Record<M[number], number>;
|
|
56
34
|
}) => number;
|
|
@@ -60,14 +38,14 @@ declare function defineEngagementReward<const M extends readonly [ContentMetric,
|
|
|
60
38
|
key: string;
|
|
61
39
|
qualifiedBy: string;
|
|
62
40
|
balance: string;
|
|
63
|
-
metrics:
|
|
41
|
+
metrics: string[];
|
|
64
42
|
baseline: "historical";
|
|
65
43
|
maxAgeMs: number;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
};
|
|
44
|
+
budgets: {
|
|
45
|
+
scope: "member" | "project";
|
|
46
|
+
period: "lifetime" | "day" | "week" | "month";
|
|
47
|
+
limit: number;
|
|
48
|
+
}[];
|
|
71
49
|
};
|
|
72
50
|
score(raw: unknown): {
|
|
73
51
|
target: number;
|
|
@@ -75,15 +53,68 @@ declare function defineEngagementReward<const M extends readonly [ContentMetric,
|
|
|
75
53
|
};
|
|
76
54
|
};
|
|
77
55
|
/**
|
|
78
|
-
* One milestone per quest, after `days` consecutive
|
|
79
|
-
* Multiple accepted attempts occupy one day. The day comes from the attempt's trusted
|
|
80
|
-
* time: a tracker record's
|
|
56
|
+
* One milestone per quest, after `days` consecutive project calendar days with an accepted
|
|
57
|
+
* attempt. Multiple accepted attempts occupy one day. The day comes from the attempt's trusted
|
|
58
|
+
* occurrence time: a tracker record's `occurredAt` for `automatic({ tracker })`, and the
|
|
81
59
|
* submission's admission time for `manual()`, so a manual streak counts the days a member
|
|
82
|
-
* submitted.
|
|
60
|
+
* submitted. Days begin at midnight in the project timezone (`calendar.timeZone` in relay.json, or
|
|
61
|
+
* Console settings). Not available on content quests or prerequisite-only `automatic()`.
|
|
83
62
|
*/
|
|
84
|
-
declare const streak: (options:
|
|
85
|
-
|
|
86
|
-
|
|
63
|
+
declare const streak: (options: {
|
|
64
|
+
days: number;
|
|
65
|
+
}) => StreakPolicy;
|
|
66
|
+
/** The number of distinct qualifying actions in one counter achievement. */
|
|
67
|
+
declare const count: (count: number) => {
|
|
68
|
+
kind: "count";
|
|
69
|
+
count: number;
|
|
70
|
+
} & z.core.$brand<"counter-goal">;
|
|
71
|
+
/** A counter window in the shared project calendar, with a bounded lateness allowance. */
|
|
72
|
+
declare const calendar: (period: "day" | "week" | "month", options?: {
|
|
73
|
+
latenessMs?: number;
|
|
74
|
+
}) => ({
|
|
75
|
+
kind: "lifetime";
|
|
76
|
+
} & z.core.$brand<"counter-window">) | ({
|
|
77
|
+
kind: "calendar";
|
|
78
|
+
period: "day" | "week" | "month";
|
|
79
|
+
latenessMs: number;
|
|
80
|
+
} & z.core.$brand<"counter-window">) | ({
|
|
81
|
+
kind: "rolling";
|
|
82
|
+
durationMs: number;
|
|
83
|
+
} & z.core.$brand<"counter-window">);
|
|
84
|
+
/** A trailing elapsed-time window, independent of timezone and calendar boundaries. */
|
|
85
|
+
declare const rolling: ({ days }: {
|
|
86
|
+
days: number;
|
|
87
|
+
}) => ({
|
|
88
|
+
kind: "lifetime";
|
|
89
|
+
} & z.core.$brand<"counter-window">) | ({
|
|
90
|
+
kind: "calendar";
|
|
91
|
+
period: "day" | "week" | "month";
|
|
92
|
+
latenessMs: number;
|
|
93
|
+
} & z.core.$brand<"counter-window">) | ({
|
|
94
|
+
kind: "rolling";
|
|
95
|
+
durationMs: number;
|
|
96
|
+
} & z.core.$brand<"counter-window">);
|
|
97
|
+
declare const questCompleted: (quest: QuestHandle) => {
|
|
98
|
+
kind: "quest";
|
|
99
|
+
quest: QuestHandle;
|
|
100
|
+
};
|
|
101
|
+
type ReferralInput = z.input<typeof referralAuthoringSchema>;
|
|
102
|
+
type ReferralBonus = NonNullable<ReferralInput["bonuses"]>[number];
|
|
103
|
+
type ReferralMilestone = NonNullable<ReferralInput["milestones"]>[number];
|
|
104
|
+
declare function defineReferral(input: Omit<ReferralInput, "qualification" | "inviterGroup" | "milestones" | "bonuses"> & {
|
|
105
|
+
qualification: {
|
|
106
|
+
kind: "signup" | "external";
|
|
107
|
+
} | ReturnType<typeof questCompleted>;
|
|
108
|
+
inviterGroup?: GroupHandle;
|
|
109
|
+
milestones?: (Omit<ReferralMilestone, "id"> & {
|
|
110
|
+
key: string;
|
|
111
|
+
})[];
|
|
112
|
+
bonuses?: (Omit<ReferralBonus, "id" | "balance" | "quests"> & {
|
|
113
|
+
key: string;
|
|
114
|
+
ledger: LedgerReference;
|
|
115
|
+
quests?: QuestHandle[];
|
|
116
|
+
})[];
|
|
117
|
+
}): {
|
|
87
118
|
title: string;
|
|
88
119
|
rewards: {
|
|
89
120
|
inviter: ({
|
|
@@ -100,6 +131,8 @@ declare function defineReferral(input: Omit<z.input<typeof referralAuthoringSche
|
|
|
100
131
|
};
|
|
101
132
|
fulfillment: {
|
|
102
133
|
kind: "staff-handover";
|
|
134
|
+
} | {
|
|
135
|
+
kind: "automatic";
|
|
103
136
|
};
|
|
104
137
|
};
|
|
105
138
|
tier: string;
|
|
@@ -122,6 +155,8 @@ declare function defineReferral(input: Omit<z.input<typeof referralAuthoringSche
|
|
|
122
155
|
};
|
|
123
156
|
fulfillment: {
|
|
124
157
|
kind: "staff-handover";
|
|
158
|
+
} | {
|
|
159
|
+
kind: "automatic";
|
|
125
160
|
};
|
|
126
161
|
};
|
|
127
162
|
tier: string;
|
|
@@ -140,7 +175,6 @@ declare function defineReferral(input: Omit<z.input<typeof referralAuthoringSche
|
|
|
140
175
|
kind: "external";
|
|
141
176
|
};
|
|
142
177
|
enabled: boolean;
|
|
143
|
-
inviterGroup?: string | undefined;
|
|
144
178
|
milestones: {
|
|
145
179
|
id: string;
|
|
146
180
|
count: number;
|
|
@@ -158,6 +192,8 @@ declare function defineReferral(input: Omit<z.input<typeof referralAuthoringSche
|
|
|
158
192
|
};
|
|
159
193
|
fulfillment: {
|
|
160
194
|
kind: "staff-handover";
|
|
195
|
+
} | {
|
|
196
|
+
kind: "automatic";
|
|
161
197
|
};
|
|
162
198
|
};
|
|
163
199
|
tier: string;
|
|
@@ -177,12 +213,41 @@ declare function defineReferral(input: Omit<z.input<typeof referralAuthoringSche
|
|
|
177
213
|
maxPoints?: number | undefined;
|
|
178
214
|
}[];
|
|
179
215
|
key: string;
|
|
216
|
+
inviterGroup?: string | undefined;
|
|
217
|
+
} & ResourceHandle<"referral">;
|
|
218
|
+
type LeaderboardInput = z.input<typeof leaderboardDefinitionSchema>;
|
|
219
|
+
type EarnedScore = Extract<NonNullable<LeaderboardInput["score"]>, {
|
|
220
|
+
kind: "earned";
|
|
221
|
+
}>;
|
|
222
|
+
declare function earned(options?: Omit<EarnedScore, "kind" | "quests"> & {
|
|
223
|
+
quests?: QuestHandle[];
|
|
224
|
+
}): {
|
|
225
|
+
window?: {
|
|
226
|
+
kind: "fixed";
|
|
227
|
+
start: number;
|
|
228
|
+
end: number;
|
|
229
|
+
} | {
|
|
230
|
+
kind: "all-time";
|
|
231
|
+
} | {
|
|
232
|
+
kind: "rolling";
|
|
233
|
+
days: number;
|
|
234
|
+
} | {
|
|
235
|
+
kind: "calendar";
|
|
236
|
+
period: "day" | "week" | "month";
|
|
237
|
+
} | undefined;
|
|
238
|
+
quests?: QuestHandle[];
|
|
239
|
+
kind: "earned";
|
|
180
240
|
};
|
|
181
|
-
declare function defineLeaderboard(input: Omit<
|
|
182
|
-
|
|
183
|
-
|
|
241
|
+
declare function defineLeaderboard(input: Omit<LeaderboardInput, "key" | "id" | "balance" | "group" | "score"> & AuthoringIdentity & {
|
|
242
|
+
ledger: LedgerReference;
|
|
243
|
+
group?: GroupHandle;
|
|
244
|
+
score?: Exclude<LeaderboardInput["score"], {
|
|
245
|
+
kind: "earned";
|
|
246
|
+
}> | ReturnType<typeof earned>;
|
|
247
|
+
}): {
|
|
184
248
|
title: string;
|
|
185
|
-
|
|
249
|
+
balance: string;
|
|
250
|
+
access: "participants" | "public";
|
|
186
251
|
score: {
|
|
187
252
|
kind: "balance";
|
|
188
253
|
} | {
|
|
@@ -198,7 +263,6 @@ declare function defineLeaderboard(input: Omit<z.input<typeof leaderboardAuthori
|
|
|
198
263
|
} | {
|
|
199
264
|
kind: "calendar";
|
|
200
265
|
period: "day" | "week" | "month";
|
|
201
|
-
timeZone: string;
|
|
202
266
|
};
|
|
203
267
|
kind: "earned";
|
|
204
268
|
quests?: string[] | undefined;
|
|
@@ -216,17 +280,54 @@ declare function defineLeaderboard(input: Omit<z.input<typeof leaderboardAuthori
|
|
|
216
280
|
} | {
|
|
217
281
|
kind: "calendar";
|
|
218
282
|
period: "day" | "week" | "month";
|
|
219
|
-
timeZone: string;
|
|
220
283
|
};
|
|
221
284
|
};
|
|
222
|
-
access: "participants" | "public";
|
|
223
285
|
key: string;
|
|
224
|
-
|
|
286
|
+
settle?: {
|
|
287
|
+
at: "window-end";
|
|
288
|
+
ties: "shared" | "earliest";
|
|
289
|
+
prizes: {
|
|
290
|
+
ranks: [number, number];
|
|
291
|
+
rewards: ({
|
|
292
|
+
kind: "tier";
|
|
293
|
+
reward: {
|
|
294
|
+
id: string;
|
|
295
|
+
title: string;
|
|
296
|
+
tiers: {
|
|
297
|
+
id: string;
|
|
298
|
+
title: string;
|
|
299
|
+
}[];
|
|
300
|
+
inventory: {
|
|
301
|
+
kind: "untracked";
|
|
302
|
+
};
|
|
303
|
+
fulfillment: {
|
|
304
|
+
kind: "staff-handover";
|
|
305
|
+
} | {
|
|
306
|
+
kind: "automatic";
|
|
307
|
+
};
|
|
308
|
+
};
|
|
309
|
+
tier: string;
|
|
310
|
+
} | {
|
|
311
|
+
kind: "points";
|
|
312
|
+
balance: string;
|
|
313
|
+
amount: number;
|
|
314
|
+
})[];
|
|
315
|
+
}[];
|
|
316
|
+
} | undefined;
|
|
317
|
+
group?: string | undefined;
|
|
318
|
+
} & ResourceHandle<"leaderboard">;
|
|
319
|
+
/** An X post's body as content quests read it in `ctx.tracker.content.body`. */
|
|
320
|
+
type XContentBody = z.infer<typeof xContentBodySchema>;
|
|
225
321
|
declare const x: {
|
|
226
|
-
|
|
322
|
+
provider: "x";
|
|
323
|
+
/**
|
|
324
|
+
* Posts matching an X search. Each record's `data` is the provider's post payload. Its content
|
|
325
|
+
* is the post's normalized body (`XContentBody`), measured by the six X counters, so `content()`
|
|
326
|
+
* quests can use it.
|
|
327
|
+
*/
|
|
227
328
|
search: (input: {
|
|
228
329
|
query: string;
|
|
229
|
-
}) => z.output<typeof xSearchSourceSchema> & WithRecordData<XTweet>;
|
|
330
|
+
}) => z.output<typeof xSearchSourceSchema> & WithRecordData<XTweet> & WithContent<XContentBody, XContentMetric>;
|
|
230
331
|
};
|
|
231
332
|
/**
|
|
232
333
|
* Records your own code sends with `trackers.ingest`. `data` is a zod object schema that every
|
|
@@ -237,18 +338,75 @@ declare const x: {
|
|
|
237
338
|
* trigger from the tracker. A record states each account's `kind` unless the source names exactly
|
|
238
339
|
* one.
|
|
239
340
|
*/
|
|
240
|
-
|
|
341
|
+
/** What a content source's records carry in `data`: the body, and the metrics each sample measures. */
|
|
342
|
+
type ContentData<B, M extends string> = {
|
|
343
|
+
body: B;
|
|
344
|
+
metrics?: Partial<Record<M, number>>;
|
|
345
|
+
};
|
|
346
|
+
/**
|
|
347
|
+
* Content your own code collects, such as posts from another platform: each record's `data` is
|
|
348
|
+
* `{ body, metrics? }`, where `body` matches the `body` schema and `metrics` holds the declared
|
|
349
|
+
* counters a sample measured (a counter a sample leaves out is unknown, never zero). The record's
|
|
350
|
+
* `author` is the creator, `occurredAt` the publication time, and its ID the content item. Quests
|
|
351
|
+
* use the tracker with `content()`, and a performance stage or engagement reward reads the
|
|
352
|
+
* declared metrics.
|
|
353
|
+
*/
|
|
354
|
+
declare function customSource<B extends z.ZodObject, const M extends readonly string[] = [], const A extends readonly string[] = []>(namespace: string, options: {
|
|
355
|
+
identities?: IdentityKind[];
|
|
356
|
+
accounts?: A;
|
|
357
|
+
content: {
|
|
358
|
+
body: B;
|
|
359
|
+
metrics?: M;
|
|
360
|
+
};
|
|
361
|
+
}): z.output<typeof customSourceSchema> & WithRecordData<ContentData<z.input<B>, M[number]>> & WithContent<z.input<B>, M[number]> & WithAccountRoles<"author" | A[number]>;
|
|
362
|
+
declare function customSource<S extends z.ZodObject, const A extends readonly string[] = []>(namespace: string, options: {
|
|
241
363
|
identities?: IdentityKind[];
|
|
242
|
-
accounts?:
|
|
364
|
+
accounts?: A;
|
|
243
365
|
data: S;
|
|
244
|
-
}): z.output<typeof customSourceSchema> & WithRecordData<z.input<S
|
|
366
|
+
}): z.output<typeof customSourceSchema> & WithRecordData<z.input<S>> & WithAccountRoles<"author" | A[number]>;
|
|
367
|
+
/** The content marker of a source, carried by the tracker built from it. */
|
|
368
|
+
type ContentOf<S> = S extends WithContent<infer B, infer M> ? WithContent<B, M> : unknown;
|
|
245
369
|
declare function defineTracker<S extends TrackerSource>(input: Omit<z.input<typeof trackerDefinitionSchema>, "source"> & {
|
|
246
370
|
source: S;
|
|
247
|
-
}): Tracker<TrackerData<S>>;
|
|
371
|
+
}): Tracker<TrackerData<S>> & ContentOf<S> & WithAccountRoles<SourceRoles<S>>;
|
|
248
372
|
type ChannelTypes = Extract<ResourceSource, {
|
|
249
373
|
resource: "channel";
|
|
250
374
|
}>["types"];
|
|
375
|
+
type DiscordMessagesSource = z.output<typeof discordMessagesSourceSchema>;
|
|
376
|
+
/**
|
|
377
|
+
* Messages members post in the project's Discord server. The Discord gateway writes one record per
|
|
378
|
+
* message, keyed by the message ID: its `author` is the poster's Discord account, `occurredAt` is
|
|
379
|
+
* when the message arrived, and `data` holds the channel, the replied-to message and the post time.
|
|
380
|
+
* A record is stored only when its author has linked that Discord account in the project, and its
|
|
381
|
+
* text only with `text: true`. Edits update stored text. Deleting a message, or publishing this
|
|
382
|
+
* tracker without `text: true`, removes retained text.
|
|
383
|
+
*/
|
|
384
|
+
declare function messages(options?: {
|
|
385
|
+
text?: false;
|
|
386
|
+
}): DiscordMessagesSource & WithRecordData<DiscordMessageData>;
|
|
387
|
+
declare function messages(options: {
|
|
388
|
+
text: true;
|
|
389
|
+
}): DiscordMessagesSource & WithRecordData<DiscordMessageTextData>;
|
|
390
|
+
/**
|
|
391
|
+
* Reactions members add in the project's Discord server. The Discord gateway writes one record per
|
|
392
|
+
* reaction, keyed by message, reactor and emoji: its `author` is the reactor's Discord account and
|
|
393
|
+
* its `messageAuthor` account the message's author, when Discord names it. `occurredAt` is when
|
|
394
|
+
* the reaction arrived. A record is stored only when the reactor or the message author has linked
|
|
395
|
+
* that Discord account in the project. Pay the message author with
|
|
396
|
+
* `automatic({ tracker, beneficiary: "messageAuthor" })`; reactions to one's own message are
|
|
397
|
+
* skipped.
|
|
398
|
+
*/
|
|
399
|
+
declare function reactions(): z.output<typeof discordReactionsSourceSchema> & WithRecordData<DiscordReactionData>;
|
|
251
400
|
declare const discord: {
|
|
401
|
+
provider: "discord";
|
|
402
|
+
grantRole: (roleId: string) => {
|
|
403
|
+
kind: "integration";
|
|
404
|
+
provider: "discord";
|
|
405
|
+
action: "grant-role";
|
|
406
|
+
roleId: string;
|
|
407
|
+
};
|
|
408
|
+
messages: typeof messages;
|
|
409
|
+
reactions: typeof reactions;
|
|
252
410
|
roles(options?: {
|
|
253
411
|
assignable?: boolean;
|
|
254
412
|
}): ResourceSource;
|
|
@@ -263,8 +421,8 @@ type Label = {
|
|
|
263
421
|
};
|
|
264
422
|
declare const settings: {
|
|
265
423
|
pointLedger(options: Label & {
|
|
266
|
-
default
|
|
267
|
-
}): Setting<"point-ledger", z.
|
|
424
|
+
default?: LedgerHandle;
|
|
425
|
+
}): Setting<"point-ledger", z.ZodPrefault<z.core.$ZodBranded<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>, "ledger-reference", "out">>>;
|
|
268
426
|
datetime(options: Label & {
|
|
269
427
|
default: string;
|
|
270
428
|
}): Setting<"datetime", z.ZodDefault<z.ZodPipe<z.ZodISODateTime, z.ZodTransform<string, string>>>>;
|
|
@@ -306,17 +464,11 @@ declare const settings: {
|
|
|
306
464
|
};
|
|
307
465
|
|
|
308
466
|
type Reward = z.infer<typeof rewardSchema>;
|
|
309
|
-
declare const points: (
|
|
467
|
+
declare const points: (ledger: LedgerReference, amount: number) => {
|
|
310
468
|
kind: "points";
|
|
311
469
|
balance: string;
|
|
312
470
|
amount: number;
|
|
313
471
|
};
|
|
314
|
-
declare const discordRole: (roleId: string) => {
|
|
315
|
-
kind: "integration";
|
|
316
|
-
provider: "discord";
|
|
317
|
-
action: "grant-role";
|
|
318
|
-
roleId: string;
|
|
319
|
-
};
|
|
320
472
|
|
|
321
473
|
declare const evidence: {
|
|
322
474
|
text: (options?: TextOptions) => {
|
|
@@ -360,14 +512,38 @@ declare function manual(options: {
|
|
|
360
512
|
input: "none";
|
|
361
513
|
actor: "staff";
|
|
362
514
|
};
|
|
515
|
+
/**
|
|
516
|
+
* Which members' activity a tracker trigger counts, and from when. With `enrollment: "required"`,
|
|
517
|
+
* a member's activity counts only once they enroll (`relay.quests.enroll`, or
|
|
518
|
+
* `management.quests.enroll` from a server), and `since` can also be `"enrollment"`.
|
|
519
|
+
*/
|
|
520
|
+
type TriggerAdmission = {
|
|
521
|
+
/** `"none"` (the default): every member who has joined the project. */
|
|
522
|
+
enrollment?: "none";
|
|
523
|
+
/**
|
|
524
|
+
* The earliest activity counted: `"activation"` (the default), records since the quest was
|
|
525
|
+
* published; `"window"`, every record in the tracker's window.
|
|
526
|
+
*/
|
|
527
|
+
since?: "activation" | "window";
|
|
528
|
+
} | {
|
|
529
|
+
/** Members enroll in the quest before their activity counts. */
|
|
530
|
+
enrollment: "required";
|
|
531
|
+
/**
|
|
532
|
+
* The earliest activity counted: `"activation"` (the default), `"window"`, or
|
|
533
|
+
* `"enrollment"`, records since the member enrolled. With `"activation"` or `"window"`, a
|
|
534
|
+
* record from before the member enrolled is historical.
|
|
535
|
+
*/
|
|
536
|
+
since?: "activation" | "window" | "enrollment";
|
|
537
|
+
};
|
|
363
538
|
/** A tracker trigger: which observations of which tracker run the quest, and for whom. */
|
|
364
|
-
type TrackerTriggerInput<T extends Tracker = Tracker, W extends Where<TrackerData<T>> | undefined = Where<TrackerData<T>> | undefined> = {
|
|
539
|
+
type TrackerTriggerInput<T extends Tracker = Tracker, W extends Where<TrackerData<T>> | undefined = Where<TrackerData<T>> | undefined> = TriggerAdmission & {
|
|
365
540
|
/** The tracker handle `defineTracker` returns. */
|
|
366
541
|
tracker: T;
|
|
367
542
|
/**
|
|
368
543
|
* Which observations fire. `"new-record"`: each record's first observation (the default for X
|
|
369
|
-
* trackers, where it means each newly collected post
|
|
370
|
-
* that becomes its record's current one (the default for
|
|
544
|
+
* and Discord trackers, where it means each newly collected post, message or reaction).
|
|
545
|
+
* `"new-observation"`: each observation that becomes its record's current one (the default for
|
|
546
|
+
* custom trackers). `"data-changed"`: a
|
|
371
547
|
* new record, or a current observation whose `data` differs from the previous one.
|
|
372
548
|
*/
|
|
373
549
|
on?: TrackerTriggerMode;
|
|
@@ -380,53 +556,107 @@ type TrackerTriggerInput<T extends Tracker = Tracker, W extends Where<TrackerDat
|
|
|
380
556
|
where?: W;
|
|
381
557
|
/**
|
|
382
558
|
* The record account whose member the quest pays: `"author"` (the default), `"inReplyTo"` on
|
|
383
|
-
* an X tracker, or a named account a custom
|
|
384
|
-
* account is the record's author account or
|
|
559
|
+
* an X tracker, `"messageAuthor"` on a Discord reactions tracker, or a named account a custom
|
|
560
|
+
* source declares in `accounts`. Skipped when that account is the record's author account or
|
|
561
|
+
* belongs to the author's member, such as a reaction to one's own message.
|
|
562
|
+
*/
|
|
563
|
+
beneficiary?: RoleOf<T>;
|
|
564
|
+
/**
|
|
565
|
+
* Who releases historical activity: a record that occurred before the member linked the
|
|
566
|
+
* account it pays (an unknown link time counts as before), or before they enrolled. `"staff"`
|
|
567
|
+
* (the default): only a reviewer's retry. `"claim"`: also the member, with
|
|
568
|
+
* `relay.quests.claim`. `"automatic"`: Relay admits it, including when the member links the
|
|
569
|
+
* account or enrolls later. Accounts of kind `member` are never historical.
|
|
385
570
|
*/
|
|
386
|
-
|
|
571
|
+
historical?: "staff" | "claim" | "automatic";
|
|
387
572
|
};
|
|
388
573
|
/** Type-only markers a tracker trigger carries into `defineQuest`. They never exist at runtime. */
|
|
389
574
|
declare const triggerData: unique symbol;
|
|
390
575
|
declare const triggerSettings: unique symbol;
|
|
576
|
+
declare const triggerBody: unique symbol;
|
|
577
|
+
declare const triggerMetrics: unique symbol;
|
|
391
578
|
/**
|
|
392
579
|
* A tracker trigger whose records carry `data` of type `D` and whose filter compares with the
|
|
393
|
-
* settings `S`.
|
|
394
|
-
* settings.
|
|
580
|
+
* settings `S`. On a content source, its content body has type `B` and its metrics are `M`.
|
|
581
|
+
* `defineQuest` types `ctx.tracker` from `D` and `B` and checks `S` against its integer settings.
|
|
395
582
|
*/
|
|
396
|
-
type TrackerTrigger<D = unknown, S extends string = never> = {
|
|
583
|
+
type TrackerTrigger<D = unknown, S extends string = never, B = never, M extends string = never> = {
|
|
397
584
|
kind: "automatic";
|
|
398
585
|
tracker: TrackerTriggerPolicy;
|
|
399
586
|
readonly [triggerData]?: D;
|
|
400
587
|
readonly [triggerSettings]?: S;
|
|
588
|
+
readonly [triggerBody]?: B;
|
|
589
|
+
readonly [triggerMetrics]?: M;
|
|
590
|
+
};
|
|
591
|
+
/**
|
|
592
|
+
* A content quest's trigger: a tracker trigger on a content source with the content stage. It
|
|
593
|
+
* completes once per content item, so its quest takes no `completion`.
|
|
594
|
+
*/
|
|
595
|
+
type ContentTrigger<D = unknown, S extends string = never, B = unknown, M extends string = string> = TrackerTrigger<D, S, B, M> & {
|
|
596
|
+
tracker: TrackerTriggerPolicy & {
|
|
597
|
+
content: true;
|
|
598
|
+
};
|
|
401
599
|
};
|
|
402
|
-
type TriggerData<G> = G extends
|
|
600
|
+
type TriggerData<G> = G extends {
|
|
601
|
+
readonly [triggerData]?: infer D;
|
|
602
|
+
} ? unknown extends D ? unknown : Exclude<D, undefined> : unknown;
|
|
403
603
|
type TriggerSettings<G> = G extends {
|
|
404
604
|
readonly [triggerSettings]?: infer S;
|
|
405
605
|
} ? unknown extends S ? never : Exclude<S, undefined> : never;
|
|
606
|
+
type TriggerBody<G> = G extends {
|
|
607
|
+
readonly [triggerBody]?: infer B;
|
|
608
|
+
} ? Exclude<B, undefined> : never;
|
|
609
|
+
/** The metric names a content trigger's source measures. */
|
|
610
|
+
type TriggerMetrics<G> = G extends {
|
|
611
|
+
readonly [triggerMetrics]?: infer M;
|
|
612
|
+
} ? Exclude<M, undefined> : never;
|
|
613
|
+
/** A trigger that runs a content stage. */
|
|
614
|
+
type IsContent<G> = G extends {
|
|
615
|
+
tracker: {
|
|
616
|
+
content: true;
|
|
617
|
+
};
|
|
618
|
+
} ? true : false;
|
|
619
|
+
/** A tracker's content body type, or never when its source declares no content. */
|
|
620
|
+
type BodyOf<T> = T extends WithContent<unknown, string> ? ContentBody<T> : never;
|
|
406
621
|
/**
|
|
407
|
-
* An automatic quest. With no argument it runs once its prerequisites are complete; with
|
|
408
|
-
*
|
|
409
|
-
*
|
|
622
|
+
* An automatic quest. With no argument it runs once its prerequisites are complete; with a tracker
|
|
623
|
+
* it runs for each observation its firing mode and filter admit, for the member Relay attributes
|
|
624
|
+
* the beneficiary account to.
|
|
410
625
|
*/
|
|
411
626
|
declare function automatic(): {
|
|
412
627
|
kind: "automatic";
|
|
413
628
|
};
|
|
414
|
-
declare function automatic(
|
|
415
|
-
|
|
416
|
-
|
|
629
|
+
declare function automatic<T extends Tracker, const W extends Where<TrackerData<T>> | undefined = undefined>(input: TrackerTriggerInput<T, W>): TrackerTrigger<TrackerData<T>, WhereSetting<W>, BodyOf<T>>;
|
|
630
|
+
/** A content quest's trigger: which content items of which tracker it takes, and from whom. */
|
|
631
|
+
type ContentTriggerInput<T extends Tracker = Tracker, W extends Where<TrackerData<T>> | undefined = Where<TrackerData<T>> | undefined> = TriggerAdmission & {
|
|
632
|
+
/** A tracker handle from `defineTracker` whose source has content. */
|
|
633
|
+
tracker: T;
|
|
634
|
+
/** Take only content items whose first observation's `data` matches. */
|
|
635
|
+
where?: W;
|
|
636
|
+
/**
|
|
637
|
+
* Who releases historical content: posts from before the creator linked the account or
|
|
638
|
+
* enrolled. `"claim"` (the default): the creator claims it with `relay.quests.claim`. `"staff"`:
|
|
639
|
+
* only a reviewer's retry. `"automatic"`: Relay takes it.
|
|
640
|
+
*/
|
|
641
|
+
historical?: "staff" | "claim" | "automatic";
|
|
417
642
|
};
|
|
418
|
-
|
|
643
|
+
/**
|
|
644
|
+
* A content quest: each content item a tracker collects, such as an X post or a custom source's
|
|
645
|
+
* record, becomes one attempt for its author's member, decided once on its first observation and
|
|
646
|
+
* evaluated again when its body changes. Completes once per content item: the quest takes no
|
|
647
|
+
* `completion`. With `performance`, a later observation's metrics gate the rewards.
|
|
648
|
+
*/
|
|
649
|
+
declare function content<T extends Tracker & WithContent<unknown, string>, const W extends Where<TrackerData<T>> | undefined = undefined>(input: ContentTriggerInput<T, W>): ContentTrigger<TrackerData<T>, WhereSetting<W>, ContentBody<T>, ContentMetricName<T>>;
|
|
419
650
|
/**
|
|
420
651
|
* What a trigger `G` supplies under key `K`: `Present` when the trigger has it, null when it cannot,
|
|
421
652
|
* and `Present | null` when `G` is not known.
|
|
422
653
|
*/
|
|
423
654
|
type Supplied<G, K extends string, Present, Base> = unknown extends G ? Base | null : G extends unknown ? K extends keyof G ? [G[K]] extends [object] ? Present : Base | null : null : never;
|
|
424
|
-
/**
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
type ContextObservation<G> = Supplied<G, "observation", Observation, Observation>;
|
|
655
|
+
/**
|
|
656
|
+
* `ctx.tracker` for a trigger: non-null and typed for a tracker trigger, null for others. On a
|
|
657
|
+
* content source, `content.body` has the source's body type.
|
|
658
|
+
*/
|
|
659
|
+
type ContextTracker<G> = Supplied<G, "tracker", TrackerTriggerContext<TriggerData<G>, TriggerBody<G>>, TrackerTriggerContext>;
|
|
430
660
|
/**
|
|
431
661
|
* What a `keyed()` completion key reads. TypeScript cannot carry the trigger into a completion
|
|
432
662
|
* built inline, so `tracker` stays nullable here; the evaluator's `ctx.tracker` is typed.
|
|
@@ -435,18 +665,23 @@ type KeyedContext = {
|
|
|
435
665
|
member: {
|
|
436
666
|
id: string;
|
|
437
667
|
};
|
|
438
|
-
content?: AdmittedContent | null;
|
|
439
|
-
observation: Observation | null;
|
|
440
668
|
/** The pinned tracker observation of a tracker-triggered quest; null for other triggers. */
|
|
441
669
|
tracker: TrackerTriggerContext | null;
|
|
442
670
|
eligibleAt: number;
|
|
671
|
+
/** The evaluation run's pinned project calendar. */
|
|
672
|
+
calendar: EvaluationCalendar;
|
|
443
673
|
/** The attempt's evaluation time; see {@link EvaluationContext.now}. */
|
|
444
674
|
now: number;
|
|
445
675
|
};
|
|
446
|
-
declare const budget: (definition: Budget
|
|
676
|
+
declare const budget: (definition: Omit<Budget, "id" | "cost"> & {
|
|
677
|
+
key: string;
|
|
678
|
+
cost: number | {
|
|
679
|
+
ledger: LedgerReference;
|
|
680
|
+
};
|
|
681
|
+
}) => {
|
|
447
682
|
id: string;
|
|
448
683
|
scope: "member" | "project";
|
|
449
|
-
period: "lifetime" | "day" | "week";
|
|
684
|
+
period: "lifetime" | "day" | "week" | "month";
|
|
450
685
|
limit: number;
|
|
451
686
|
cost: number | {
|
|
452
687
|
balance: string;
|
|
@@ -456,8 +691,30 @@ declare const keyed: (key: (ctx: KeyedContext) => string) => {
|
|
|
456
691
|
kind: "keyed";
|
|
457
692
|
key: (ctx: KeyedContext) => string;
|
|
458
693
|
};
|
|
459
|
-
|
|
460
|
-
|
|
694
|
+
/** Accepted evidence contributes once under its distinct key; Relay commits progress with rewards. */
|
|
695
|
+
declare const progress: (definition: {
|
|
696
|
+
distinct: (ctx: KeyedContext) => string;
|
|
697
|
+
goal: ReturnType<typeof count>;
|
|
698
|
+
window?: ReturnType<typeof calendar>;
|
|
699
|
+
repeat?: "once" | "repeat";
|
|
700
|
+
}) => {
|
|
701
|
+
distinct: (ctx: KeyedContext) => string;
|
|
702
|
+
kind: "progress";
|
|
703
|
+
goal: {
|
|
704
|
+
kind: "count";
|
|
705
|
+
count: number;
|
|
706
|
+
};
|
|
707
|
+
window: {
|
|
708
|
+
kind: "lifetime";
|
|
709
|
+
} | {
|
|
710
|
+
kind: "calendar";
|
|
711
|
+
period: "day" | "week" | "month";
|
|
712
|
+
latenessMs: number;
|
|
713
|
+
} | {
|
|
714
|
+
kind: "rolling";
|
|
715
|
+
durationMs: number;
|
|
716
|
+
};
|
|
717
|
+
repeat: "repeat" | "once";
|
|
461
718
|
};
|
|
462
719
|
declare const untracked: () => {
|
|
463
720
|
kind: "untracked";
|
|
@@ -465,11 +722,17 @@ declare const untracked: () => {
|
|
|
465
722
|
declare const staffHandover: () => {
|
|
466
723
|
kind: "staff-handover";
|
|
467
724
|
};
|
|
468
|
-
declare
|
|
725
|
+
declare const automaticFulfillment: () => {
|
|
726
|
+
kind: "automatic";
|
|
727
|
+
};
|
|
728
|
+
declare function defineTieredReward<const T extends readonly {
|
|
469
729
|
key: string;
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
730
|
+
title: string;
|
|
731
|
+
}[]>(input: Omit<TieredRewardDefinition, "id" | "tiers"> & AuthoringIdentity & {
|
|
732
|
+
tiers: T;
|
|
733
|
+
}): {
|
|
734
|
+
key: string;
|
|
735
|
+
tier: (tier: T[number]["key"]) => {
|
|
473
736
|
kind: "tier";
|
|
474
737
|
reward: {
|
|
475
738
|
id: string;
|
|
@@ -483,25 +746,23 @@ declare function defineTieredReward(input: Omit<TieredRewardDefinition, "id"> &
|
|
|
483
746
|
};
|
|
484
747
|
fulfillment: {
|
|
485
748
|
kind: "staff-handover";
|
|
749
|
+
} | {
|
|
750
|
+
kind: "automatic";
|
|
486
751
|
};
|
|
487
752
|
};
|
|
488
753
|
tier: string;
|
|
489
754
|
};
|
|
490
|
-
}
|
|
755
|
+
} & ResourceHandle<"tiered-reward">;
|
|
491
756
|
declare const once: () => {
|
|
492
757
|
kind: "once";
|
|
493
758
|
};
|
|
494
|
-
type Outcome = {
|
|
759
|
+
type Outcome = (Omit<Extract<Decision, {
|
|
495
760
|
kind: "accept";
|
|
761
|
+
}>, "rewards"> & {
|
|
496
762
|
rewards?: Reward[];
|
|
497
|
-
} | {
|
|
498
|
-
kind: "
|
|
499
|
-
|
|
500
|
-
rewards?: Reward[];
|
|
501
|
-
} | {
|
|
502
|
-
kind: "reject";
|
|
503
|
-
reason: string;
|
|
504
|
-
};
|
|
763
|
+
}) | Exclude<Decision, {
|
|
764
|
+
kind: "accept";
|
|
765
|
+
}>;
|
|
505
766
|
/**
|
|
506
767
|
* A performance evaluator's answer. It gates the rewards content evaluation already selected, so
|
|
507
768
|
* it carries none: a `rewards` value fails the evaluation.
|
|
@@ -520,9 +781,11 @@ type PerformanceOutcome = {
|
|
|
520
781
|
declare function accept(): {
|
|
521
782
|
kind: "accept";
|
|
522
783
|
};
|
|
523
|
-
declare function accept(options: {
|
|
524
|
-
|
|
525
|
-
}): Outcome
|
|
784
|
+
declare function accept(options: Omit<Extract<Outcome, {
|
|
785
|
+
kind: "accept";
|
|
786
|
+
}>, "kind">): Extract<Outcome, {
|
|
787
|
+
kind: "accept";
|
|
788
|
+
}>;
|
|
526
789
|
declare function review(options: {
|
|
527
790
|
reason: string;
|
|
528
791
|
rewards?: undefined;
|
|
@@ -530,12 +793,23 @@ declare function review(options: {
|
|
|
530
793
|
kind: "review";
|
|
531
794
|
reason: string;
|
|
532
795
|
};
|
|
533
|
-
declare function review(options: {
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
796
|
+
declare function review(options: Omit<Extract<Outcome, {
|
|
797
|
+
kind: "review";
|
|
798
|
+
}>, "kind">): Extract<Outcome, {
|
|
799
|
+
kind: "review";
|
|
800
|
+
}>;
|
|
537
801
|
declare const decision: {
|
|
538
802
|
accept: typeof accept;
|
|
803
|
+
defer: (options: Omit<Extract<Decision, {
|
|
804
|
+
kind: "defer";
|
|
805
|
+
}>, "kind">) => Extract<Decision, {
|
|
806
|
+
kind: "defer";
|
|
807
|
+
}>;
|
|
808
|
+
progress: (options: Omit<Extract<Decision, {
|
|
809
|
+
kind: "progress";
|
|
810
|
+
}>, "kind">) => Extract<Decision, {
|
|
811
|
+
kind: "progress";
|
|
812
|
+
}>;
|
|
539
813
|
reject: (options: {
|
|
540
814
|
reason: string;
|
|
541
815
|
}) => {
|
|
@@ -544,42 +818,70 @@ declare const decision: {
|
|
|
544
818
|
};
|
|
545
819
|
review: typeof review;
|
|
546
820
|
};
|
|
821
|
+
/** The member an attempt evaluates. */
|
|
822
|
+
type EvaluationMember = {
|
|
823
|
+
id: string;
|
|
824
|
+
/**
|
|
825
|
+
* The member's selected X and Discord accounts and their `app:<name>` identities in this
|
|
826
|
+
* project, pinned once per evaluation run at the first call: later links and unlinks do not change
|
|
827
|
+
* this evaluation. Null when the member has none. `ctx.wallet.list()` reads wallets.
|
|
828
|
+
*/
|
|
829
|
+
identities(): Promise<MemberIdentity[] | null>;
|
|
830
|
+
};
|
|
831
|
+
/** One project-calendar day, with epoch-millisecond bounds. */
|
|
832
|
+
type EvaluationCalendarDay = {
|
|
833
|
+
/** The stable completion-key form, such as `2026-10-01@Europe/Budapest`. */
|
|
834
|
+
key: string;
|
|
835
|
+
/** The local ISO date in `timeZone`. */
|
|
836
|
+
date: string;
|
|
837
|
+
timeZone: string;
|
|
838
|
+
/** Inclusive epoch-millisecond boundary. */
|
|
839
|
+
start: number;
|
|
840
|
+
/** Exclusive epoch-millisecond boundary. */
|
|
841
|
+
end: number;
|
|
842
|
+
};
|
|
843
|
+
/** The project calendar pinned for one evaluation run. */
|
|
844
|
+
type EvaluationCalendar = {
|
|
845
|
+
/** The day containing `at`, or the activity's `eligibleAt` when omitted. */
|
|
846
|
+
day(at?: number): EvaluationCalendarDay;
|
|
847
|
+
};
|
|
547
848
|
/**
|
|
548
|
-
* What an evaluator reads. `G` is the quest's trigger: `tracker
|
|
549
|
-
*
|
|
849
|
+
* What an evaluator reads. `G` is the quest's trigger: `tracker` and `content` are non-null for
|
|
850
|
+
* the trigger that supplies them and null otherwise. `G` defaults to `any`, which
|
|
550
851
|
* leaves them nullable and lets a shared evaluator, such as `evaluators.photo()`, fit every quest.
|
|
551
852
|
*/
|
|
853
|
+
type IntegrationReaders<D extends readonly IntegrationModule[]> = Pick<{
|
|
854
|
+
x: XReader;
|
|
855
|
+
discord: DiscordReader;
|
|
856
|
+
}, D[number]["provider"]>;
|
|
552
857
|
type EvaluationContext<T, I = {
|
|
553
858
|
photo: string;
|
|
554
|
-
}, G = any> = {
|
|
859
|
+
}, G = any, D extends readonly IntegrationModule[] = readonly IntegrationModule[]> = {
|
|
555
860
|
settings: T;
|
|
556
|
-
member:
|
|
557
|
-
id: string;
|
|
558
|
-
};
|
|
861
|
+
member: EvaluationMember;
|
|
559
862
|
input: I;
|
|
560
|
-
/** The admitted post of a content quest. */
|
|
561
|
-
content: ContextContent<G>;
|
|
562
|
-
/** The observation of an observation-triggered quest. */
|
|
563
|
-
observation: ContextObservation<G>;
|
|
564
863
|
/**
|
|
565
864
|
* The tracker observation that admitted this attempt, and the member and verified account it
|
|
566
865
|
* was attributed to. Present for a tracker trigger, with `record.data` of the tracker's type.
|
|
866
|
+
* On a content source, `content` holds the body revision being evaluated, with the source's
|
|
867
|
+
* body type.
|
|
567
868
|
*/
|
|
568
869
|
tracker: ContextTracker<G>;
|
|
569
870
|
/**
|
|
570
|
-
* When the activity happened, in epoch milliseconds: the
|
|
571
|
-
*
|
|
871
|
+
* When the activity happened, in epoch milliseconds: the tracker record's occurrence time, else
|
|
872
|
+
* when the attempt was admitted. Budgets and daily keys use it.
|
|
572
873
|
*/
|
|
573
874
|
eligibleAt: number;
|
|
875
|
+
/** The project calendar pinned when this evaluation run started. */
|
|
876
|
+
calendar: EvaluationCalendar;
|
|
574
877
|
/**
|
|
575
|
-
* The
|
|
576
|
-
*
|
|
878
|
+
* The current evaluation run's start time in epoch milliseconds.
|
|
879
|
+
* Retries and replays of that run receive the same value; a scheduled defer starts a fresh run, and the sandbox freezes
|
|
577
880
|
* `Date.now()` and `new Date()` at it. Use `eligibleAt` for when the activity
|
|
578
881
|
* happened.
|
|
579
882
|
*/
|
|
580
883
|
now: number;
|
|
581
884
|
trackers: TrackerReader;
|
|
582
|
-
x: XReader;
|
|
583
885
|
images: ImageReader;
|
|
584
886
|
review: {
|
|
585
887
|
text(options: TextReviewInput): Promise<TextResult>;
|
|
@@ -588,31 +890,11 @@ type EvaluationContext<T, I = {
|
|
|
588
890
|
criteria: string;
|
|
589
891
|
}): Promise<PhotoResult>;
|
|
590
892
|
};
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
message(input: {
|
|
594
|
-
channelId: string;
|
|
595
|
-
messageId: string;
|
|
596
|
-
}): Promise<DiscordMessage | null>;
|
|
597
|
-
};
|
|
598
|
-
wallet: {
|
|
599
|
-
/** The member's newest linked Solana wallet. */
|
|
600
|
-
connection(): Promise<WalletConnection | null>;
|
|
601
|
-
/** SOL held by the newest linked Solana wallet. */
|
|
602
|
-
solanaBalance(): Promise<SolanaBalance | null>;
|
|
603
|
-
/** Every wallet the member has linked to this project, pinned once per attempt. */
|
|
604
|
-
list(): Promise<LinkedWallet[]>;
|
|
605
|
-
/**
|
|
606
|
-
* The native or token balance of the member's pinned linked wallets on one chain: all wallets of
|
|
607
|
-
* that family, or `address` (which must be one of them). No wallets gives `total: "0"` and
|
|
608
|
-
* `wallets: []`. Provider failures throw; they never read as a zero balance.
|
|
609
|
-
*/
|
|
610
|
-
balance(query: WalletBalanceQuery): Promise<WalletBalance>;
|
|
611
|
-
};
|
|
612
|
-
};
|
|
893
|
+
wallet: WalletReader;
|
|
894
|
+
} & IntegrationReaders<D>;
|
|
613
895
|
type Evaluator<T, I = {
|
|
614
896
|
photo: string;
|
|
615
|
-
}, G = any> = (ctx: EvaluationContext<T, I, G>) => Promise<Outcome>;
|
|
897
|
+
}, G = any, D extends readonly IntegrationModule[] = readonly []> = (ctx: EvaluationContext<T, I, G, D>) => Promise<Outcome>;
|
|
616
898
|
declare const evaluators: {
|
|
617
899
|
quiz(answerKey: QuizEvidence["answers"], options?: {
|
|
618
900
|
minimumCorrect?: number;
|
|
@@ -645,21 +927,50 @@ type IntegerSettingBounds<G, T> = [
|
|
|
645
927
|
] extends [never] ? unknown : {
|
|
646
928
|
readonly "The tracker filter compares with settings that are not integer settings of this quest": Exclude<TriggerSettings<G>, IntegerSettings<T>>;
|
|
647
929
|
};
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
930
|
+
/** How a quest completes: a content quest once per content item, so it takes no `completion`. */
|
|
931
|
+
type CompletionFor<G> = IsContent<G> extends true ? {
|
|
932
|
+
/** A content quest completes once per content item; it takes no completion. */
|
|
933
|
+
completion?: never;
|
|
934
|
+
} : G extends {
|
|
935
|
+
kind: "automatic";
|
|
936
|
+
tracker?: never;
|
|
937
|
+
} ? {
|
|
938
|
+
completion: ReturnType<typeof once>;
|
|
939
|
+
} : {
|
|
940
|
+
completion: ReturnType<typeof once> | ReturnType<typeof keyed> | StreakPolicy | ReturnType<typeof progress>;
|
|
941
|
+
};
|
|
942
|
+
/** What a content quest's performance stage reads: the declared metrics it chose, fresh. */
|
|
943
|
+
type PerformanceContext<S, G, M extends string> = {
|
|
944
|
+
settings: S;
|
|
945
|
+
member: {
|
|
946
|
+
id: string;
|
|
947
|
+
};
|
|
948
|
+
/** The content item's pinned observation, attribution and body revision. */
|
|
949
|
+
tracker: ContextTracker<G>;
|
|
950
|
+
/** The chosen metrics of one complete, fresh sample. */
|
|
951
|
+
metrics: Record<M, number>;
|
|
952
|
+
/** When the sample was observed. */
|
|
953
|
+
observedAt: number;
|
|
954
|
+
};
|
|
955
|
+
/** A concrete quest: prerequisite-only automatic triggers need at least one prerequisite. */
|
|
956
|
+
declare const defineQuest: <T extends Record<string, Setting>, const G extends Trigger, const D extends readonly IntegrationModule[] = readonly [], const M extends readonly [string, ...string[]] = readonly [string, ...string[]]>(definition: AuthoringIdentity & CompletionFor<G> & (G extends {
|
|
957
|
+
kind: "automatic";
|
|
958
|
+
tracker?: never;
|
|
959
|
+
} ? {
|
|
960
|
+
requires: readonly [Prerequisite, ...Prerequisite[]];
|
|
961
|
+
} : unknown) & {
|
|
652
962
|
title: string | ((ctx: {
|
|
653
|
-
settings: z.
|
|
963
|
+
settings: z.core.$InferObjectOutput<T, {}>;
|
|
654
964
|
}) => string);
|
|
655
|
-
settings: z.ZodObject<T>;
|
|
656
|
-
presentation?: (ctx: {
|
|
657
|
-
settings: z.
|
|
658
|
-
}) => QuestPresentation;
|
|
965
|
+
settings: z.ZodObject<T, z.core.$strip>;
|
|
966
|
+
presentation?: ((ctx: {
|
|
967
|
+
settings: z.core.$InferObjectOutput<T, {}>;
|
|
968
|
+
}) => QuestPresentation) | undefined;
|
|
659
969
|
trigger: G & NoInfer<IntegerSettingBounds<G, T>>;
|
|
660
|
-
integrations?:
|
|
661
|
-
requires?:
|
|
662
|
-
|
|
970
|
+
integrations?: D | undefined;
|
|
971
|
+
requires?: readonly Prerequisite[];
|
|
972
|
+
campaign?: CampaignDefinition;
|
|
973
|
+
availability?: AvailabilityWindow;
|
|
663
974
|
visibility?: "visible" | "hidden";
|
|
664
975
|
/**
|
|
665
976
|
* `{ visible: true }` lists the quest's completions on participant profiles
|
|
@@ -673,37 +984,59 @@ declare function defineQuest<T extends Record<string, Setting>, const G extends
|
|
|
673
984
|
* review reason, and the attempt records `requestedReview: true`; Console shows "Would have
|
|
674
985
|
* gone to review; human review is off".
|
|
675
986
|
*/
|
|
676
|
-
review?: (ctx: {
|
|
677
|
-
settings: z.
|
|
987
|
+
review?: ((ctx: {
|
|
988
|
+
settings: z.core.$InferObjectOutput<T, {}>;
|
|
678
989
|
}) => {
|
|
679
990
|
enabled: boolean;
|
|
680
|
-
};
|
|
681
|
-
rewards:
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
} ? {
|
|
688
|
-
metrics: M;
|
|
689
|
-
maxAgeMs?: number;
|
|
690
|
-
evaluate: (ctx: {
|
|
691
|
-
settings: z.output<z.ZodObject<T>>;
|
|
692
|
-
member: {
|
|
991
|
+
}) | undefined;
|
|
992
|
+
rewards: ({
|
|
993
|
+
kind: "tier";
|
|
994
|
+
reward: {
|
|
995
|
+
id: string;
|
|
996
|
+
title: string;
|
|
997
|
+
tiers: {
|
|
693
998
|
id: string;
|
|
999
|
+
title: string;
|
|
1000
|
+
}[];
|
|
1001
|
+
inventory: {
|
|
1002
|
+
kind: "untracked";
|
|
694
1003
|
};
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
}
|
|
1004
|
+
fulfillment: {
|
|
1005
|
+
kind: "staff-handover";
|
|
1006
|
+
} | {
|
|
1007
|
+
kind: "automatic";
|
|
1008
|
+
};
|
|
1009
|
+
};
|
|
1010
|
+
tier: string;
|
|
1011
|
+
} | {
|
|
1012
|
+
kind: "integration";
|
|
1013
|
+
provider: "discord";
|
|
1014
|
+
action: "grant-role";
|
|
1015
|
+
roleId: string;
|
|
1016
|
+
} | {
|
|
1017
|
+
kind: "points";
|
|
1018
|
+
balance: string;
|
|
1019
|
+
amount: number;
|
|
1020
|
+
})[] | ((ctx: {
|
|
1021
|
+
settings: z.core.$InferObjectOutput<T, {}>;
|
|
1022
|
+
}) => Reward[]);
|
|
1023
|
+
evaluate?: Evaluator<z.core.$InferObjectOutput<T, {}>, QuestInput<G>, NoInfer<G>, NoInfer<D>> | undefined;
|
|
1024
|
+
/**
|
|
1025
|
+
* A content quest's performance stage: once content evaluation accepts an item, each later
|
|
1026
|
+
* complete and fresh sample of `metrics` (a subset of the tracker's declared metrics) gates the
|
|
1027
|
+
* rewards it selected.
|
|
1028
|
+
*/
|
|
1029
|
+
performance?: (IsContent<G> extends true ? {
|
|
1030
|
+
metrics: M & readonly TriggerMetrics<G>[];
|
|
1031
|
+
maxAgeMs?: number;
|
|
1032
|
+
evaluate: (ctx: PerformanceContext<z.core.$InferObjectOutput<T, {}>, G, M[number]>) => PerformanceOutcome | Promise<PerformanceOutcome>;
|
|
1033
|
+
} : never) | undefined;
|
|
1034
|
+
}) => {
|
|
1035
|
+
protocol: number;
|
|
701
1036
|
key: string;
|
|
702
|
-
/** @deprecated Authoring key alias. Use key. */
|
|
703
|
-
id: string;
|
|
704
1037
|
describe: (input: unknown) => {
|
|
705
1038
|
quest: string;
|
|
706
|
-
|
|
1039
|
+
evaluatorProtocol: 2;
|
|
707
1040
|
title: string;
|
|
708
1041
|
presentation: {
|
|
709
1042
|
quiz?: {
|
|
@@ -725,7 +1058,7 @@ declare function defineQuest<T extends Record<string, Setting>, const G extends
|
|
|
725
1058
|
} | undefined;
|
|
726
1059
|
} | undefined;
|
|
727
1060
|
};
|
|
728
|
-
integrations: "discord"[];
|
|
1061
|
+
integrations: ("discord" | "x")[];
|
|
729
1062
|
fields: Record<string, {
|
|
730
1063
|
kind: "point-ledger";
|
|
731
1064
|
default: string;
|
|
@@ -740,9 +1073,6 @@ declare function defineQuest<T extends Record<string, Setting>, const G extends
|
|
|
740
1073
|
kind: "resource";
|
|
741
1074
|
default: string;
|
|
742
1075
|
source: {
|
|
743
|
-
provider: "domino";
|
|
744
|
-
resource: "point-ledger";
|
|
745
|
-
} | {
|
|
746
1076
|
provider: "discord";
|
|
747
1077
|
resource: "channel";
|
|
748
1078
|
types: ("text" | "announcement")[];
|
|
@@ -750,6 +1080,9 @@ declare function defineQuest<T extends Record<string, Setting>, const G extends
|
|
|
750
1080
|
provider: "discord";
|
|
751
1081
|
resource: "role";
|
|
752
1082
|
assignable: boolean;
|
|
1083
|
+
} | {
|
|
1084
|
+
provider: "domino";
|
|
1085
|
+
resource: "point-ledger";
|
|
753
1086
|
};
|
|
754
1087
|
label: string;
|
|
755
1088
|
description?: string | undefined;
|
|
@@ -816,41 +1149,50 @@ declare function defineQuest<T extends Record<string, Setting>, const G extends
|
|
|
816
1149
|
};
|
|
817
1150
|
fulfillment: {
|
|
818
1151
|
kind: "staff-handover";
|
|
1152
|
+
} | {
|
|
1153
|
+
kind: "automatic";
|
|
819
1154
|
};
|
|
820
1155
|
};
|
|
821
1156
|
tier: string;
|
|
822
|
-
} | {
|
|
823
|
-
kind: "points";
|
|
824
|
-
balance: string;
|
|
825
|
-
amount: number;
|
|
826
1157
|
} | {
|
|
827
1158
|
kind: "integration";
|
|
828
1159
|
provider: "discord";
|
|
829
1160
|
action: "grant-role";
|
|
830
1161
|
roleId: string;
|
|
1162
|
+
} | {
|
|
1163
|
+
kind: "points";
|
|
1164
|
+
balance: string;
|
|
1165
|
+
amount: number;
|
|
831
1166
|
})[];
|
|
832
1167
|
humanReview: boolean;
|
|
833
1168
|
trigger: {
|
|
1169
|
+
kind: "manual";
|
|
1170
|
+
input: "text";
|
|
1171
|
+
constraints: {
|
|
1172
|
+
required: boolean;
|
|
1173
|
+
minLength: number;
|
|
1174
|
+
maxLength: number;
|
|
1175
|
+
};
|
|
1176
|
+
actor?: "staff" | "member" | undefined;
|
|
1177
|
+
} | {
|
|
1178
|
+
kind: "manual";
|
|
1179
|
+
input: "url";
|
|
1180
|
+
constraints: {
|
|
1181
|
+
required: boolean;
|
|
1182
|
+
allowedHosts?: string[] | undefined;
|
|
1183
|
+
};
|
|
1184
|
+
actor?: "staff" | "member" | undefined;
|
|
1185
|
+
} | {
|
|
1186
|
+
kind: "manual";
|
|
1187
|
+
input: "none" | "quiz" | "photo";
|
|
1188
|
+
actor?: "staff" | "member" | undefined;
|
|
1189
|
+
} | {
|
|
834
1190
|
kind: "automatic";
|
|
835
|
-
observation?: {
|
|
836
|
-
source: string;
|
|
837
|
-
type: string;
|
|
838
|
-
} | undefined;
|
|
839
|
-
content?: {
|
|
840
|
-
tracker: string;
|
|
841
|
-
window: {
|
|
842
|
-
start: number;
|
|
843
|
-
end?: number | undefined;
|
|
844
|
-
};
|
|
845
|
-
enrollment: "required" | "none";
|
|
846
|
-
posts: "after-enrollment" | "since-start";
|
|
847
|
-
historical: "staff" | "automatic" | "claim";
|
|
848
|
-
} | undefined;
|
|
849
1191
|
tracker?: {
|
|
850
1192
|
tracker: string;
|
|
851
|
-
source:
|
|
1193
|
+
source: string;
|
|
1194
|
+
on: "new-record" | "new-observation" | "data-changed";
|
|
852
1195
|
beneficiary: string;
|
|
853
|
-
on?: "new-record" | "new-observation" | "data-changed" | undefined;
|
|
854
1196
|
where?: {
|
|
855
1197
|
path: string;
|
|
856
1198
|
gt?: number | {
|
|
@@ -886,67 +1228,519 @@ declare function defineQuest<T extends Record<string, Setting>, const G extends
|
|
|
886
1228
|
path: string;
|
|
887
1229
|
equals: string | number | boolean;
|
|
888
1230
|
})[] | undefined;
|
|
1231
|
+
enrollment?: "none" | "required" | undefined;
|
|
1232
|
+
since?: "activation" | "window" | "enrollment" | undefined;
|
|
1233
|
+
historical?: "staff" | "claim" | "automatic" | undefined;
|
|
1234
|
+
content?: true | undefined;
|
|
889
1235
|
} | undefined;
|
|
1236
|
+
};
|
|
1237
|
+
requires: ({
|
|
1238
|
+
kind: "completion";
|
|
1239
|
+
quest: string;
|
|
1240
|
+
scope: "ever";
|
|
890
1241
|
} | {
|
|
891
|
-
kind: "
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
minLength: number;
|
|
896
|
-
maxLength: number;
|
|
897
|
-
};
|
|
898
|
-
actor?: "staff" | "member" | undefined;
|
|
1242
|
+
kind: "completion";
|
|
1243
|
+
quest: string;
|
|
1244
|
+
scope: "period";
|
|
1245
|
+
period: "day" | "week" | "month";
|
|
899
1246
|
} | {
|
|
900
|
-
kind: "
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
required: boolean;
|
|
904
|
-
allowedHosts?: string[] | undefined;
|
|
905
|
-
};
|
|
906
|
-
actor?: "staff" | "member" | undefined;
|
|
1247
|
+
kind: "balance";
|
|
1248
|
+
balance: string;
|
|
1249
|
+
minimum: number;
|
|
907
1250
|
} | {
|
|
908
|
-
kind: "
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
};
|
|
912
|
-
requires: {
|
|
913
|
-
quest: string;
|
|
914
|
-
}[];
|
|
1251
|
+
kind: "group";
|
|
1252
|
+
group: string;
|
|
1253
|
+
title: string;
|
|
1254
|
+
})[];
|
|
915
1255
|
completion: {
|
|
1256
|
+
kind: "progress";
|
|
1257
|
+
goal: {
|
|
1258
|
+
kind: "count";
|
|
1259
|
+
count: number;
|
|
1260
|
+
};
|
|
1261
|
+
window: {
|
|
1262
|
+
kind: "lifetime";
|
|
1263
|
+
} | {
|
|
1264
|
+
kind: "calendar";
|
|
1265
|
+
period: "day" | "week" | "month";
|
|
1266
|
+
latenessMs: number;
|
|
1267
|
+
} | {
|
|
1268
|
+
kind: "rolling";
|
|
1269
|
+
durationMs: number;
|
|
1270
|
+
};
|
|
1271
|
+
repeat: "repeat" | "once";
|
|
1272
|
+
} | {
|
|
916
1273
|
kind: "streak";
|
|
917
1274
|
days: number;
|
|
918
|
-
timeZone: string;
|
|
919
1275
|
} | {
|
|
920
1276
|
kind: "once";
|
|
921
1277
|
} | {
|
|
922
1278
|
kind: "keyed";
|
|
923
1279
|
};
|
|
924
1280
|
visibility: "visible" | "hidden";
|
|
1281
|
+
profile: {
|
|
1282
|
+
visible: boolean;
|
|
1283
|
+
};
|
|
925
1284
|
budgets: {
|
|
926
1285
|
id: string;
|
|
927
1286
|
scope: "member" | "project";
|
|
928
|
-
period: "lifetime" | "day" | "week";
|
|
1287
|
+
period: "lifetime" | "day" | "week" | "month";
|
|
929
1288
|
limit: number;
|
|
930
1289
|
cost: number | {
|
|
931
1290
|
balance: string;
|
|
932
1291
|
};
|
|
933
1292
|
}[];
|
|
934
1293
|
performance?: {
|
|
935
|
-
metrics:
|
|
1294
|
+
metrics: string[];
|
|
936
1295
|
maxAgeMs: number;
|
|
937
1296
|
} | undefined;
|
|
938
|
-
|
|
939
|
-
|
|
1297
|
+
campaign?: {
|
|
1298
|
+
key: string;
|
|
1299
|
+
title: string;
|
|
1300
|
+
enrollment: "none" | "required";
|
|
1301
|
+
window?: {
|
|
1302
|
+
from: number;
|
|
1303
|
+
until: number;
|
|
1304
|
+
} | undefined;
|
|
1305
|
+
} | undefined;
|
|
1306
|
+
availability?: {
|
|
1307
|
+
from: number;
|
|
1308
|
+
until: number;
|
|
940
1309
|
} | undefined;
|
|
941
1310
|
};
|
|
942
|
-
evaluate(ctx:
|
|
1311
|
+
evaluate(ctx: {
|
|
1312
|
+
settings: unknown;
|
|
1313
|
+
member: EvaluationMember;
|
|
1314
|
+
input: QuestInput<G>;
|
|
1315
|
+
/**
|
|
1316
|
+
* The tracker observation that admitted this attempt, and the member and verified account it
|
|
1317
|
+
* was attributed to. Present for a tracker trigger, with `record.data` of the tracker's type.
|
|
1318
|
+
* On a content source, `content` holds the body revision being evaluated, with the source's
|
|
1319
|
+
* body type.
|
|
1320
|
+
*/
|
|
1321
|
+
tracker: TrackerTriggerContext | null;
|
|
1322
|
+
/**
|
|
1323
|
+
* When the activity happened, in epoch milliseconds: the tracker record's occurrence time, else
|
|
1324
|
+
* when the attempt was admitted. Budgets and daily keys use it.
|
|
1325
|
+
*/
|
|
1326
|
+
eligibleAt: number;
|
|
1327
|
+
/** The project calendar pinned when this evaluation run started. */
|
|
1328
|
+
calendar: EvaluationCalendar;
|
|
1329
|
+
/**
|
|
1330
|
+
* The current evaluation run's start time in epoch milliseconds.
|
|
1331
|
+
* Retries and replays of that run receive the same value; a scheduled defer starts a fresh run, and the sandbox freezes
|
|
1332
|
+
* `Date.now()` and `new Date()` at it. Use `eligibleAt` for when the activity
|
|
1333
|
+
* happened.
|
|
1334
|
+
*/
|
|
1335
|
+
now: number;
|
|
1336
|
+
trackers: TrackerReader;
|
|
1337
|
+
images: ImageReader;
|
|
1338
|
+
review: {
|
|
1339
|
+
text(options: TextReviewInput): Promise<TextResult>;
|
|
1340
|
+
photo(options: {
|
|
1341
|
+
image: string;
|
|
1342
|
+
criteria: string;
|
|
1343
|
+
}): Promise<PhotoResult>;
|
|
1344
|
+
};
|
|
1345
|
+
wallet: WalletReader;
|
|
1346
|
+
} & IntegrationReaders<readonly IntegrationModule[]> & {
|
|
943
1347
|
rewards: Reward[];
|
|
944
1348
|
humanReview: boolean;
|
|
945
1349
|
performance?: unknown;
|
|
946
1350
|
}): Promise<Decision>;
|
|
947
|
-
}
|
|
1351
|
+
} & ResourceHandle<"quest">;
|
|
948
1352
|
/** Publish this artifact as a reusable type. Its key names the type;
|
|
949
1353
|
* Console instances receive independent quest identities and pinned versions. */
|
|
950
|
-
declare const defineQuestType:
|
|
1354
|
+
declare const defineQuestType: <T extends Record<string, Setting>, const G extends Trigger, const D extends readonly IntegrationModule[] = readonly [], const M extends readonly [string, ...string[]] = readonly [string, ...string[]]>(definition: AuthoringIdentity & CompletionFor<G> & {
|
|
1355
|
+
title: string | ((ctx: {
|
|
1356
|
+
settings: z.core.$InferObjectOutput<T, {}>;
|
|
1357
|
+
}) => string);
|
|
1358
|
+
settings: z.ZodObject<T, z.core.$strip>;
|
|
1359
|
+
presentation?: ((ctx: {
|
|
1360
|
+
settings: z.core.$InferObjectOutput<T, {}>;
|
|
1361
|
+
}) => QuestPresentation) | undefined;
|
|
1362
|
+
trigger: G & NoInfer<IntegerSettingBounds<G, T>>;
|
|
1363
|
+
integrations?: D | undefined;
|
|
1364
|
+
requires?: readonly Prerequisite[];
|
|
1365
|
+
campaign?: CampaignDefinition;
|
|
1366
|
+
availability?: AvailabilityWindow;
|
|
1367
|
+
visibility?: "visible" | "hidden";
|
|
1368
|
+
/**
|
|
1369
|
+
* `{ visible: true }` lists the quest's completions on participant profiles
|
|
1370
|
+
* (`relay.profiles.completions`). Hidden by default.
|
|
1371
|
+
*/
|
|
1372
|
+
profile?: QuestProfile;
|
|
1373
|
+
budgets?: Budget[];
|
|
1374
|
+
/**
|
|
1375
|
+
* Whether staff can review this quest's attempts. Human review is on unless this returns
|
|
1376
|
+
* `{ enabled: false }`. With it off, `decision.review(...)` becomes a reject that keeps the
|
|
1377
|
+
* review reason, and the attempt records `requestedReview: true`; Console shows "Would have
|
|
1378
|
+
* gone to review; human review is off".
|
|
1379
|
+
*/
|
|
1380
|
+
review?: ((ctx: {
|
|
1381
|
+
settings: z.core.$InferObjectOutput<T, {}>;
|
|
1382
|
+
}) => {
|
|
1383
|
+
enabled: boolean;
|
|
1384
|
+
}) | undefined;
|
|
1385
|
+
rewards: ({
|
|
1386
|
+
kind: "tier";
|
|
1387
|
+
reward: {
|
|
1388
|
+
id: string;
|
|
1389
|
+
title: string;
|
|
1390
|
+
tiers: {
|
|
1391
|
+
id: string;
|
|
1392
|
+
title: string;
|
|
1393
|
+
}[];
|
|
1394
|
+
inventory: {
|
|
1395
|
+
kind: "untracked";
|
|
1396
|
+
};
|
|
1397
|
+
fulfillment: {
|
|
1398
|
+
kind: "staff-handover";
|
|
1399
|
+
} | {
|
|
1400
|
+
kind: "automatic";
|
|
1401
|
+
};
|
|
1402
|
+
};
|
|
1403
|
+
tier: string;
|
|
1404
|
+
} | {
|
|
1405
|
+
kind: "integration";
|
|
1406
|
+
provider: "discord";
|
|
1407
|
+
action: "grant-role";
|
|
1408
|
+
roleId: string;
|
|
1409
|
+
} | {
|
|
1410
|
+
kind: "points";
|
|
1411
|
+
balance: string;
|
|
1412
|
+
amount: number;
|
|
1413
|
+
})[] | ((ctx: {
|
|
1414
|
+
settings: z.core.$InferObjectOutput<T, {}>;
|
|
1415
|
+
}) => Reward[]);
|
|
1416
|
+
evaluate?: Evaluator<z.core.$InferObjectOutput<T, {}>, QuestInput<G>, NoInfer<G>, NoInfer<D>> | undefined;
|
|
1417
|
+
/**
|
|
1418
|
+
* A content quest's performance stage: once content evaluation accepts an item, each later
|
|
1419
|
+
* complete and fresh sample of `metrics` (a subset of the tracker's declared metrics) gates the
|
|
1420
|
+
* rewards it selected.
|
|
1421
|
+
*/
|
|
1422
|
+
performance?: (IsContent<G> extends true ? {
|
|
1423
|
+
metrics: M & readonly TriggerMetrics<G>[];
|
|
1424
|
+
maxAgeMs?: number;
|
|
1425
|
+
evaluate: (ctx: PerformanceContext<z.core.$InferObjectOutput<T, {}>, G, M[number]>) => PerformanceOutcome | Promise<PerformanceOutcome>;
|
|
1426
|
+
} : never) | undefined;
|
|
1427
|
+
}) => {
|
|
1428
|
+
protocol: number;
|
|
1429
|
+
key: string;
|
|
1430
|
+
describe: (input: unknown) => {
|
|
1431
|
+
quest: string;
|
|
1432
|
+
evaluatorProtocol: 2;
|
|
1433
|
+
title: string;
|
|
1434
|
+
presentation: {
|
|
1435
|
+
quiz?: {
|
|
1436
|
+
id: string;
|
|
1437
|
+
prompt: string;
|
|
1438
|
+
choices: {
|
|
1439
|
+
id: string;
|
|
1440
|
+
label: string;
|
|
1441
|
+
}[];
|
|
1442
|
+
}[] | undefined;
|
|
1443
|
+
instructions?: string | undefined;
|
|
1444
|
+
video?: {
|
|
1445
|
+
url: string;
|
|
1446
|
+
poster?: string | undefined;
|
|
1447
|
+
captions?: {
|
|
1448
|
+
url: string;
|
|
1449
|
+
language: string;
|
|
1450
|
+
label: string;
|
|
1451
|
+
} | undefined;
|
|
1452
|
+
} | undefined;
|
|
1453
|
+
};
|
|
1454
|
+
integrations: ("discord" | "x")[];
|
|
1455
|
+
fields: Record<string, {
|
|
1456
|
+
kind: "point-ledger";
|
|
1457
|
+
default: string;
|
|
1458
|
+
label: string;
|
|
1459
|
+
description?: string | undefined;
|
|
1460
|
+
} | {
|
|
1461
|
+
kind: "datetime";
|
|
1462
|
+
default: string;
|
|
1463
|
+
label: string;
|
|
1464
|
+
description?: string | undefined;
|
|
1465
|
+
} | {
|
|
1466
|
+
kind: "resource";
|
|
1467
|
+
default: string;
|
|
1468
|
+
source: {
|
|
1469
|
+
provider: "discord";
|
|
1470
|
+
resource: "channel";
|
|
1471
|
+
types: ("text" | "announcement")[];
|
|
1472
|
+
} | {
|
|
1473
|
+
provider: "discord";
|
|
1474
|
+
resource: "role";
|
|
1475
|
+
assignable: boolean;
|
|
1476
|
+
} | {
|
|
1477
|
+
provider: "domino";
|
|
1478
|
+
resource: "point-ledger";
|
|
1479
|
+
};
|
|
1480
|
+
label: string;
|
|
1481
|
+
description?: string | undefined;
|
|
1482
|
+
} | {
|
|
1483
|
+
kind: "quiz";
|
|
1484
|
+
default: {
|
|
1485
|
+
id: string;
|
|
1486
|
+
prompt: string;
|
|
1487
|
+
choices: {
|
|
1488
|
+
id: string;
|
|
1489
|
+
label: string;
|
|
1490
|
+
}[];
|
|
1491
|
+
correct: string;
|
|
1492
|
+
}[];
|
|
1493
|
+
label: string;
|
|
1494
|
+
description?: string | undefined;
|
|
1495
|
+
} | {
|
|
1496
|
+
kind: "text";
|
|
1497
|
+
default: string;
|
|
1498
|
+
minLength: number;
|
|
1499
|
+
maxLength: number;
|
|
1500
|
+
multiline: boolean;
|
|
1501
|
+
label: string;
|
|
1502
|
+
description?: string | undefined;
|
|
1503
|
+
} | {
|
|
1504
|
+
kind: "integer";
|
|
1505
|
+
default: number;
|
|
1506
|
+
min: number;
|
|
1507
|
+
max: number;
|
|
1508
|
+
label: string;
|
|
1509
|
+
description?: string | undefined;
|
|
1510
|
+
} | {
|
|
1511
|
+
kind: "boolean";
|
|
1512
|
+
default: boolean;
|
|
1513
|
+
label: string;
|
|
1514
|
+
description?: string | undefined;
|
|
1515
|
+
} | {
|
|
1516
|
+
kind: "choice";
|
|
1517
|
+
default: string;
|
|
1518
|
+
options: string[];
|
|
1519
|
+
label: string;
|
|
1520
|
+
description?: string | undefined;
|
|
1521
|
+
}>;
|
|
1522
|
+
values: Record<string, string | number | boolean | {
|
|
1523
|
+
id: string;
|
|
1524
|
+
prompt: string;
|
|
1525
|
+
choices: {
|
|
1526
|
+
id: string;
|
|
1527
|
+
label: string;
|
|
1528
|
+
}[];
|
|
1529
|
+
correct: string;
|
|
1530
|
+
}[]>;
|
|
1531
|
+
rewards: ({
|
|
1532
|
+
kind: "tier";
|
|
1533
|
+
reward: {
|
|
1534
|
+
id: string;
|
|
1535
|
+
title: string;
|
|
1536
|
+
tiers: {
|
|
1537
|
+
id: string;
|
|
1538
|
+
title: string;
|
|
1539
|
+
}[];
|
|
1540
|
+
inventory: {
|
|
1541
|
+
kind: "untracked";
|
|
1542
|
+
};
|
|
1543
|
+
fulfillment: {
|
|
1544
|
+
kind: "staff-handover";
|
|
1545
|
+
} | {
|
|
1546
|
+
kind: "automatic";
|
|
1547
|
+
};
|
|
1548
|
+
};
|
|
1549
|
+
tier: string;
|
|
1550
|
+
} | {
|
|
1551
|
+
kind: "integration";
|
|
1552
|
+
provider: "discord";
|
|
1553
|
+
action: "grant-role";
|
|
1554
|
+
roleId: string;
|
|
1555
|
+
} | {
|
|
1556
|
+
kind: "points";
|
|
1557
|
+
balance: string;
|
|
1558
|
+
amount: number;
|
|
1559
|
+
})[];
|
|
1560
|
+
humanReview: boolean;
|
|
1561
|
+
trigger: {
|
|
1562
|
+
kind: "manual";
|
|
1563
|
+
input: "text";
|
|
1564
|
+
constraints: {
|
|
1565
|
+
required: boolean;
|
|
1566
|
+
minLength: number;
|
|
1567
|
+
maxLength: number;
|
|
1568
|
+
};
|
|
1569
|
+
actor?: "staff" | "member" | undefined;
|
|
1570
|
+
} | {
|
|
1571
|
+
kind: "manual";
|
|
1572
|
+
input: "url";
|
|
1573
|
+
constraints: {
|
|
1574
|
+
required: boolean;
|
|
1575
|
+
allowedHosts?: string[] | undefined;
|
|
1576
|
+
};
|
|
1577
|
+
actor?: "staff" | "member" | undefined;
|
|
1578
|
+
} | {
|
|
1579
|
+
kind: "manual";
|
|
1580
|
+
input: "none" | "quiz" | "photo";
|
|
1581
|
+
actor?: "staff" | "member" | undefined;
|
|
1582
|
+
} | {
|
|
1583
|
+
kind: "automatic";
|
|
1584
|
+
tracker?: {
|
|
1585
|
+
tracker: string;
|
|
1586
|
+
source: string;
|
|
1587
|
+
on: "new-record" | "new-observation" | "data-changed";
|
|
1588
|
+
beneficiary: string;
|
|
1589
|
+
where?: {
|
|
1590
|
+
path: string;
|
|
1591
|
+
gt?: number | {
|
|
1592
|
+
setting: string;
|
|
1593
|
+
} | undefined;
|
|
1594
|
+
gte?: number | {
|
|
1595
|
+
setting: string;
|
|
1596
|
+
} | undefined;
|
|
1597
|
+
lt?: number | {
|
|
1598
|
+
setting: string;
|
|
1599
|
+
} | undefined;
|
|
1600
|
+
lte?: number | {
|
|
1601
|
+
setting: string;
|
|
1602
|
+
} | undefined;
|
|
1603
|
+
} | {
|
|
1604
|
+
path: string;
|
|
1605
|
+
equals: string | number | boolean;
|
|
1606
|
+
} | ({
|
|
1607
|
+
path: string;
|
|
1608
|
+
gt?: number | {
|
|
1609
|
+
setting: string;
|
|
1610
|
+
} | undefined;
|
|
1611
|
+
gte?: number | {
|
|
1612
|
+
setting: string;
|
|
1613
|
+
} | undefined;
|
|
1614
|
+
lt?: number | {
|
|
1615
|
+
setting: string;
|
|
1616
|
+
} | undefined;
|
|
1617
|
+
lte?: number | {
|
|
1618
|
+
setting: string;
|
|
1619
|
+
} | undefined;
|
|
1620
|
+
} | {
|
|
1621
|
+
path: string;
|
|
1622
|
+
equals: string | number | boolean;
|
|
1623
|
+
})[] | undefined;
|
|
1624
|
+
enrollment?: "none" | "required" | undefined;
|
|
1625
|
+
since?: "activation" | "window" | "enrollment" | undefined;
|
|
1626
|
+
historical?: "staff" | "claim" | "automatic" | undefined;
|
|
1627
|
+
content?: true | undefined;
|
|
1628
|
+
} | undefined;
|
|
1629
|
+
};
|
|
1630
|
+
requires: ({
|
|
1631
|
+
kind: "completion";
|
|
1632
|
+
quest: string;
|
|
1633
|
+
scope: "ever";
|
|
1634
|
+
} | {
|
|
1635
|
+
kind: "completion";
|
|
1636
|
+
quest: string;
|
|
1637
|
+
scope: "period";
|
|
1638
|
+
period: "day" | "week" | "month";
|
|
1639
|
+
} | {
|
|
1640
|
+
kind: "balance";
|
|
1641
|
+
balance: string;
|
|
1642
|
+
minimum: number;
|
|
1643
|
+
} | {
|
|
1644
|
+
kind: "group";
|
|
1645
|
+
group: string;
|
|
1646
|
+
title: string;
|
|
1647
|
+
})[];
|
|
1648
|
+
completion: {
|
|
1649
|
+
kind: "progress";
|
|
1650
|
+
goal: {
|
|
1651
|
+
kind: "count";
|
|
1652
|
+
count: number;
|
|
1653
|
+
};
|
|
1654
|
+
window: {
|
|
1655
|
+
kind: "lifetime";
|
|
1656
|
+
} | {
|
|
1657
|
+
kind: "calendar";
|
|
1658
|
+
period: "day" | "week" | "month";
|
|
1659
|
+
latenessMs: number;
|
|
1660
|
+
} | {
|
|
1661
|
+
kind: "rolling";
|
|
1662
|
+
durationMs: number;
|
|
1663
|
+
};
|
|
1664
|
+
repeat: "repeat" | "once";
|
|
1665
|
+
} | {
|
|
1666
|
+
kind: "streak";
|
|
1667
|
+
days: number;
|
|
1668
|
+
} | {
|
|
1669
|
+
kind: "once";
|
|
1670
|
+
} | {
|
|
1671
|
+
kind: "keyed";
|
|
1672
|
+
};
|
|
1673
|
+
visibility: "visible" | "hidden";
|
|
1674
|
+
profile: {
|
|
1675
|
+
visible: boolean;
|
|
1676
|
+
};
|
|
1677
|
+
budgets: {
|
|
1678
|
+
id: string;
|
|
1679
|
+
scope: "member" | "project";
|
|
1680
|
+
period: "lifetime" | "day" | "week" | "month";
|
|
1681
|
+
limit: number;
|
|
1682
|
+
cost: number | {
|
|
1683
|
+
balance: string;
|
|
1684
|
+
};
|
|
1685
|
+
}[];
|
|
1686
|
+
performance?: {
|
|
1687
|
+
metrics: string[];
|
|
1688
|
+
maxAgeMs: number;
|
|
1689
|
+
} | undefined;
|
|
1690
|
+
campaign?: {
|
|
1691
|
+
key: string;
|
|
1692
|
+
title: string;
|
|
1693
|
+
enrollment: "none" | "required";
|
|
1694
|
+
window?: {
|
|
1695
|
+
from: number;
|
|
1696
|
+
until: number;
|
|
1697
|
+
} | undefined;
|
|
1698
|
+
} | undefined;
|
|
1699
|
+
availability?: {
|
|
1700
|
+
from: number;
|
|
1701
|
+
until: number;
|
|
1702
|
+
} | undefined;
|
|
1703
|
+
};
|
|
1704
|
+
evaluate(ctx: {
|
|
1705
|
+
settings: unknown;
|
|
1706
|
+
member: EvaluationMember;
|
|
1707
|
+
input: QuestInput<G>;
|
|
1708
|
+
/**
|
|
1709
|
+
* The tracker observation that admitted this attempt, and the member and verified account it
|
|
1710
|
+
* was attributed to. Present for a tracker trigger, with `record.data` of the tracker's type.
|
|
1711
|
+
* On a content source, `content` holds the body revision being evaluated, with the source's
|
|
1712
|
+
* body type.
|
|
1713
|
+
*/
|
|
1714
|
+
tracker: TrackerTriggerContext | null;
|
|
1715
|
+
/**
|
|
1716
|
+
* When the activity happened, in epoch milliseconds: the tracker record's occurrence time, else
|
|
1717
|
+
* when the attempt was admitted. Budgets and daily keys use it.
|
|
1718
|
+
*/
|
|
1719
|
+
eligibleAt: number;
|
|
1720
|
+
/** The project calendar pinned when this evaluation run started. */
|
|
1721
|
+
calendar: EvaluationCalendar;
|
|
1722
|
+
/**
|
|
1723
|
+
* The current evaluation run's start time in epoch milliseconds.
|
|
1724
|
+
* Retries and replays of that run receive the same value; a scheduled defer starts a fresh run, and the sandbox freezes
|
|
1725
|
+
* `Date.now()` and `new Date()` at it. Use `eligibleAt` for when the activity
|
|
1726
|
+
* happened.
|
|
1727
|
+
*/
|
|
1728
|
+
now: number;
|
|
1729
|
+
trackers: TrackerReader;
|
|
1730
|
+
images: ImageReader;
|
|
1731
|
+
review: {
|
|
1732
|
+
text(options: TextReviewInput): Promise<TextResult>;
|
|
1733
|
+
photo(options: {
|
|
1734
|
+
image: string;
|
|
1735
|
+
criteria: string;
|
|
1736
|
+
}): Promise<PhotoResult>;
|
|
1737
|
+
};
|
|
1738
|
+
wallet: WalletReader;
|
|
1739
|
+
} & IntegrationReaders<readonly IntegrationModule[]> & {
|
|
1740
|
+
rewards: Reward[];
|
|
1741
|
+
humanReview: boolean;
|
|
1742
|
+
performance?: unknown;
|
|
1743
|
+
}): Promise<Decision>;
|
|
1744
|
+
} & ResourceHandle<"quest">;
|
|
951
1745
|
|
|
952
|
-
export { type EvaluationContext, ImageReader, type KeyedContext, type PerformanceOutcome, Setting, Tracker, TrackerData, TrackerReader, type TrackerTrigger, TrackerTriggerContext, type TrackerTriggerInput,
|
|
1746
|
+
export { ContentBody, type ContentData, ContentMetricName, type ContentTrigger, type ContentTriggerInput, DiscordMessageData, DiscordMessageTextData, DiscordReactionData, DiscordReader, type EvaluationCalendar, type EvaluationCalendarDay, type EvaluationContext, type EvaluationMember, GroupHandle, IdentityKind, ImageReader, IntegrationModule, type KeyedContext, LedgerHandle, LedgerReference, MemberIdentity, type Outcome, type PerformanceContext, type PerformanceOutcome, QuestHandle, RoleOf, Setting, Tracker, TrackerData, TrackerReader, type TrackerTrigger, TrackerTriggerContext, type TrackerTriggerInput, type TriggerAdmission, WalletReader, Where, type XContentBody, XReader, automatic, automaticFulfillment, budget, calendar, content, count, customSource, decision, defineEngagementReward, defineLeaderboard, defineLedger, defineQuest, defineQuestType, defineReferral, defineTieredReward, defineTracker, discord, earned, evaluators, evidence, keyed, manual, once, pointLedgers, points, progress, questCompleted, rolling, settings, staffHandover, streak, untracked, x };
|