@voltro/plugin-leaderboards 0.0.0-stage → 0.88.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/CHANGELOG.md +24492 -0
- package/LICENSE +61 -0
- package/README.md +1087 -2
- package/SECURITY.md +56 -0
- package/THIRD-PARTY-NOTICES.md +5603 -0
- package/dist/administration.js +4 -0
- package/dist/bracketAdmission.js +293 -0
- package/dist/bracketAdmissionPolicy.js +21 -0
- package/dist/bracketInstallation.js +132 -0
- package/dist/bracketMatchPorts.js +4 -0
- package/dist/bracketMatches.js +545 -0
- package/dist/brackets.d.ts +149 -0
- package/dist/brackets.js +378 -0
- package/dist/bucketStore.js +92 -0
- package/dist/buckets.js +8 -0
- package/dist/errors.d.ts +13 -0
- package/dist/errors.js +16 -0
- package/dist/glicko2.js +71 -0
- package/dist/index.d.ts +1208 -0
- package/dist/index.js +15 -0
- package/dist/inspect.js +83 -0
- package/dist/json.js +38 -0
- package/dist/leaderboard.d.ts +49 -0
- package/dist/leaderboard.js +56 -0
- package/dist/leagueSchedule.js +39 -0
- package/dist/leagues.js +30 -0
- package/dist/openskill.js +73 -0
- package/dist/plugin.js +337 -0
- package/dist/portLifetime.js +66 -0
- package/dist/ports.d.ts +294 -0
- package/dist/ports.js +6 -0
- package/dist/rankQuery.js +23 -0
- package/dist/ranking.d.ts +42 -0
- package/dist/ranking.js +70 -0
- package/dist/rating.d.ts +103 -0
- package/dist/rating.js +49 -0
- package/dist/ratingPools.js +133 -0
- package/dist/ratingStore.js +333 -0
- package/dist/ratingStrategies.js +107 -0
- package/dist/records.d.ts +116 -0
- package/dist/records.js +87 -0
- package/dist/rpc.d.ts +321 -0
- package/dist/rpc.js +305 -0
- package/dist/score.d.ts +13 -0
- package/dist/score.js +26 -0
- package/dist/server.d.ts +1477 -0
- package/dist/server.js +17 -0
- package/dist/service.js +948 -0
- package/dist/subjectFences.js +43 -0
- package/dist/tables.entity.js +187 -0
- package/dist/testing.d.ts +872 -0
- package/dist/testing.js +367 -0
- package/dist/tournament-app/tournament.advance.workflow.server.tsx +3 -0
- package/dist/tournament-app/tournament.advance.workflow.tsx +12 -0
- package/dist/tournament-app/tournament.stage.workflow.server.tsx +3 -0
- package/dist/tournament-app/tournament.stage.workflow.tsx +10 -0
- package/dist/tournamentInstallation.js +167 -0
- package/dist/tournamentPrizes.js +33 -0
- package/dist/tournamentStage.js +150 -0
- package/dist/tournamentStagePorts.js +4 -0
- package/dist/tournamentWorkflow.js +100 -0
- package/dist/tournamentWorkflowSchemas.js +53 -0
- package/dist/tournaments.d.ts +32 -0
- package/dist/tournaments.js +20 -0
- package/dist/web.d.ts +175 -0
- package/dist/web.js +16 -0
- package/package.json +113 -4
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { LeaderboardError as e, leaderboardError as t } from "./errors.js";
|
|
2
|
+
import { canonicalLeaderboardJson as n, captureLeaderboardJson as r } from "./json.js";
|
|
3
|
+
import { defineBracketAdmission as i } from "./bracketAdmissionPolicy.js";
|
|
4
|
+
import { makeLeaderboardSubjectFences as a } from "./subjectFences.js";
|
|
5
|
+
import { BracketAdmissionPort as o } from "./ports.js";
|
|
6
|
+
import { Effect as s, Layer as c, Schema as l } from "effect";
|
|
7
|
+
import { Subject as u } from "@voltro/protocol";
|
|
8
|
+
import { createHash as d } from "node:crypto";
|
|
9
|
+
import { and as f, eq as p, id as m, json as h, table as g, text as _, timestamp as v } from "@voltro/database";
|
|
10
|
+
// src/bracketAdmission.ts
|
|
11
|
+
var y = "_voltro_tournament_admissions", b = g(y, {
|
|
12
|
+
id: m({ prefix: "tadm" }),
|
|
13
|
+
tenantId: _().maxLength(120).externalId().sensitive("pii"),
|
|
14
|
+
tournamentId: _().maxLength(120).serverOnly(),
|
|
15
|
+
state: h().sensitive("pii"),
|
|
16
|
+
createdAt: v(),
|
|
17
|
+
updatedAt: v()
|
|
18
|
+
}).unique("byBracketAdmission", ["tenantId", "tournamentId"]).index(["tenantId"]), x = (e) => typeof e == "string" && e.length > 0 && e.length <= 120 && e.trim() === e && e.isWellFormed() && !/[\u0000-\u001f\u007f]/.test(e) ? e : S("invalid_input");
|
|
19
|
+
function S(e) {
|
|
20
|
+
throw t(e);
|
|
21
|
+
}
|
|
22
|
+
var C = (e) => Number.isSafeInteger(e) && e >= 0 && e <= 864e13 ? e : S("invalid_input"), w = (e) => {
|
|
23
|
+
let t = r(e, 1024);
|
|
24
|
+
return t && Object.keys(t).length === 2 && Object.hasOwn(t, "tenantId") && Object.hasOwn(t, "tournamentId") || S("invalid_input"), Object.freeze({
|
|
25
|
+
tenantId: x(t.tenantId),
|
|
26
|
+
tournamentId: x(t.tournamentId)
|
|
27
|
+
});
|
|
28
|
+
}, T = l.Struct({
|
|
29
|
+
ownerId: l.String,
|
|
30
|
+
joinedAt: l.Int,
|
|
31
|
+
checkedInAt: l.NullOr(l.Int)
|
|
32
|
+
}), E = l.Struct({
|
|
33
|
+
version: l.Literal(1),
|
|
34
|
+
definition: l.Struct({
|
|
35
|
+
registrationOpensAt: l.Int,
|
|
36
|
+
registrationClosesAt: l.Int,
|
|
37
|
+
checkInOpensAt: l.Int,
|
|
38
|
+
checkInClosesAt: l.Int,
|
|
39
|
+
maxEntries: l.Int
|
|
40
|
+
}),
|
|
41
|
+
phase: l.Literals([
|
|
42
|
+
"open",
|
|
43
|
+
"sealed",
|
|
44
|
+
"erasing",
|
|
45
|
+
"cancelled"
|
|
46
|
+
]),
|
|
47
|
+
entries: l.Array(T),
|
|
48
|
+
eraseRequest: l.NullOr(l.String),
|
|
49
|
+
eraseTarget: l.NullOr(l.String)
|
|
50
|
+
}), D = (e, t) => {
|
|
51
|
+
(e.tenantId !== t.tenantId || e.tournamentId !== t.tournamentId) && S("unavailable");
|
|
52
|
+
let n = l.decodeUnknownSync(E)(r(e.state, 65536), { onExcessProperty: "error" });
|
|
53
|
+
i(n.definition), (n.entries.length > n.definition.maxEntries || new Set(n.entries.map((e) => e.ownerId)).size !== n.entries.length) && S("unavailable");
|
|
54
|
+
for (let e of n.entries) x(e.ownerId), C(e.joinedAt), (e.joinedAt < n.definition.registrationOpensAt || e.joinedAt >= n.definition.registrationClosesAt) && S("unavailable"), e.checkedInAt !== null && (C(e.checkedInAt) < n.definition.checkInOpensAt || e.checkedInAt >= n.definition.checkInClosesAt) && S("unavailable");
|
|
55
|
+
n.eraseRequest !== null && x(n.eraseRequest), (n.eraseRequest === null != (n.eraseTarget === null) || n.eraseTarget !== null && !/^[a-f0-9]{64}$/.test(n.eraseTarget) || n.phase === "erasing" && n.eraseRequest === null || ["open", "sealed"].includes(n.phase) && n.eraseRequest !== null) && S("unavailable");
|
|
56
|
+
for (let t of ["createdAt", "updatedAt"]) e[t] instanceof Date && Number.isFinite(e[t].getTime()) || S("unavailable");
|
|
57
|
+
return n;
|
|
58
|
+
}, O = async (e, t, n = !1) => {
|
|
59
|
+
let r = await e.query({
|
|
60
|
+
table: y,
|
|
61
|
+
predicate: f(p("tenantId", t.tenantId), p("tournamentId", t.tournamentId)),
|
|
62
|
+
order: [],
|
|
63
|
+
take: 2,
|
|
64
|
+
skip: void 0,
|
|
65
|
+
projection: void 0,
|
|
66
|
+
...n ? { lock: "update" } : {}
|
|
67
|
+
});
|
|
68
|
+
return r.length !== 1 && S(r.length ? "unavailable" : "not_found"), {
|
|
69
|
+
row: r[0],
|
|
70
|
+
state: D(r[0], t)
|
|
71
|
+
};
|
|
72
|
+
}, k = (n, r) => {
|
|
73
|
+
let i;
|
|
74
|
+
try {
|
|
75
|
+
i = w(r);
|
|
76
|
+
} catch (n) {
|
|
77
|
+
return s.fail(n instanceof e ? n : t("invalid_input"));
|
|
78
|
+
}
|
|
79
|
+
return s.tryPromise({
|
|
80
|
+
try: async () => {
|
|
81
|
+
let { state: e } = await O(n, i);
|
|
82
|
+
return Object.freeze({
|
|
83
|
+
phase: e.phase,
|
|
84
|
+
definition: Object.freeze({ ...e.definition })
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
catch: (n) => n instanceof e ? n : t("unavailable")
|
|
88
|
+
}).pipe(s.uninterruptible);
|
|
89
|
+
}, A = (e) => {
|
|
90
|
+
let t = r(e, 2048);
|
|
91
|
+
return t && !Object.keys(t).some((e) => !["requestId", "target"].includes(e)) && t.target && !Object.keys(t.target).some((e) => ![
|
|
92
|
+
"tenantId",
|
|
93
|
+
"subjectId",
|
|
94
|
+
"kind"
|
|
95
|
+
].includes(e)) && ["user", "guest"].includes(t.target.kind) || S("invalid_input"), Object.freeze({
|
|
96
|
+
requestId: x(t.requestId),
|
|
97
|
+
target: Object.freeze({
|
|
98
|
+
tenantId: x(t.target.tenantId),
|
|
99
|
+
subjectId: x(t.target.subjectId),
|
|
100
|
+
kind: t.target.kind
|
|
101
|
+
})
|
|
102
|
+
});
|
|
103
|
+
}, j = (e) => {
|
|
104
|
+
(!e || typeof e != "object" || Object.getPrototypeOf(e) !== Object.prototype || Object.getOwnPropertySymbols(e).length) && S("invalid_input");
|
|
105
|
+
let t = Object.getOwnPropertyDescriptors(e);
|
|
106
|
+
Object.entries(t).some(([e, t]) => ![
|
|
107
|
+
"epochNow",
|
|
108
|
+
"maxTenantTournaments",
|
|
109
|
+
"authorize",
|
|
110
|
+
"withdrawSubject",
|
|
111
|
+
"withdrawTournament",
|
|
112
|
+
"authorizeExport"
|
|
113
|
+
].includes(e) || !t.enumerable || !("value" in t)) && S("invalid_input");
|
|
114
|
+
let n = e.maxTenantTournaments ?? 1024;
|
|
115
|
+
return (typeof e.epochNow != "function" || !Number.isSafeInteger(n) || n < 1 || n > 4096 || [
|
|
116
|
+
"authorize",
|
|
117
|
+
"withdrawSubject",
|
|
118
|
+
"withdrawTournament",
|
|
119
|
+
"authorizeExport"
|
|
120
|
+
].some((t) => typeof Reflect.get(e, t) != "function")) && S("invalid_input"), Object.freeze({
|
|
121
|
+
epochNow: e.epochNow.bind(e),
|
|
122
|
+
maxTenantTournaments: n,
|
|
123
|
+
authorize: e.authorize.bind(e),
|
|
124
|
+
withdrawSubject: e.withdrawSubject.bind(e),
|
|
125
|
+
withdrawTournament: e.withdrawTournament.bind(e),
|
|
126
|
+
authorizeExport: e.authorizeExport.bind(e)
|
|
127
|
+
});
|
|
128
|
+
}, M = (o, c) => {
|
|
129
|
+
let f = j(c), m = f.epochNow, h = f.maxTenantTournaments, { authorize: g, withdrawSubject: _, withdrawTournament: v, authorizeExport: b } = f, { seedSubject: T, subjectFence: E, eraseSubjectFence: k } = a(o), M = (n) => {
|
|
130
|
+
try {
|
|
131
|
+
return n();
|
|
132
|
+
} catch (n) {
|
|
133
|
+
return s.fail(n instanceof e ? n : t("invalid_input"));
|
|
134
|
+
}
|
|
135
|
+
}, N = (n) => s.tryPromise({
|
|
136
|
+
try: n,
|
|
137
|
+
catch: (n) => n instanceof e ? n : t("unavailable")
|
|
138
|
+
}).pipe(s.uninterruptible), P = O, F = async (e, t, n) => {
|
|
139
|
+
r(n, 65536), await e.update("_voltro_tournament_admissions", String(t.id), {
|
|
140
|
+
state: n,
|
|
141
|
+
updatedAt: new Date(C(m()))
|
|
142
|
+
}) || S("unavailable");
|
|
143
|
+
}, I = (e, t) => ((e.type !== "user" || e.tenantId !== t.tenantId || e.id === null) && S("forbidden"), x(e.id)), L = (e) => {
|
|
144
|
+
e.type !== "system" && e.type !== "service" && S("forbidden");
|
|
145
|
+
}, R = (e, t) => Object.freeze({
|
|
146
|
+
phase: e.phase,
|
|
147
|
+
entries: e.entries.length,
|
|
148
|
+
checkedIn: e.entries.filter((e) => e.checkedInAt !== null).length,
|
|
149
|
+
own: e.entries.some((e) => e.ownerId === t) ? Object.freeze({ ...e.entries.find((e) => e.ownerId === t) }) : null
|
|
150
|
+
}), z = async (e) => {
|
|
151
|
+
let t = await o.query({
|
|
152
|
+
table: y,
|
|
153
|
+
predicate: p("tenantId", e),
|
|
154
|
+
order: [],
|
|
155
|
+
take: h + 1,
|
|
156
|
+
skip: void 0,
|
|
157
|
+
projection: void 0
|
|
158
|
+
});
|
|
159
|
+
t.length > h && S("limit_exceeded");
|
|
160
|
+
let n = t.map((t) => {
|
|
161
|
+
let n = w({
|
|
162
|
+
tenantId: e,
|
|
163
|
+
tournamentId: x(t.tournamentId)
|
|
164
|
+
});
|
|
165
|
+
return {
|
|
166
|
+
scope: n,
|
|
167
|
+
state: D(t, n)
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
return new Set(n.map((e) => e.scope.tournamentId)).size !== n.length && S("unavailable"), n.sort((e, t) => e.scope.tournamentId < t.scope.tournamentId ? -1 : +(e.scope.tournamentId > t.scope.tournamentId));
|
|
171
|
+
};
|
|
172
|
+
return Object.freeze({
|
|
173
|
+
create: (e, t, r) => M(() => {
|
|
174
|
+
let a = w(t), c = l.decodeUnknownSync(l.toType(u))(structuredClone(e)), d = i(r);
|
|
175
|
+
return L(c), g(c, a, "create").pipe(s.flatMap(() => N(async () => {
|
|
176
|
+
let e = C(m());
|
|
177
|
+
await o.insertIgnore(y, {
|
|
178
|
+
...a,
|
|
179
|
+
state: {
|
|
180
|
+
version: 1,
|
|
181
|
+
definition: d,
|
|
182
|
+
phase: "open",
|
|
183
|
+
entries: [],
|
|
184
|
+
eraseRequest: null,
|
|
185
|
+
eraseTarget: null
|
|
186
|
+
},
|
|
187
|
+
createdAt: new Date(e),
|
|
188
|
+
updatedAt: new Date(e)
|
|
189
|
+
}, { conflictColumns: ["tenantId", "tournamentId"] });
|
|
190
|
+
let { state: t } = await P(o, a);
|
|
191
|
+
n(t.definition) !== n(d) && S("conflict");
|
|
192
|
+
})));
|
|
193
|
+
}),
|
|
194
|
+
register: (e, t) => M(() => {
|
|
195
|
+
let n = w(t), r = l.decodeUnknownSync(l.toType(u))(structuredClone(e)), i = I(r, n);
|
|
196
|
+
return g(r, n, "register").pipe(s.flatMap(() => N(() => T(n.tenantId, i))), s.flatMap(() => N(() => o.transactional(async (e) => {
|
|
197
|
+
await E(e, n.tenantId, i);
|
|
198
|
+
let { row: t, state: r } = await P(e, n, !0), a = C(m());
|
|
199
|
+
if (r.phase !== "open" && S("conflict"), r.entries.some((e) => e.ownerId === i)) return R(r, i);
|
|
200
|
+
(a < r.definition.registrationOpensAt || a >= r.definition.registrationClosesAt) && S("conflict"), r.entries.length >= r.definition.maxEntries && S("limit_exceeded");
|
|
201
|
+
let o = {
|
|
202
|
+
...r,
|
|
203
|
+
entries: [...r.entries, {
|
|
204
|
+
ownerId: i,
|
|
205
|
+
joinedAt: a,
|
|
206
|
+
checkedInAt: null
|
|
207
|
+
}]
|
|
208
|
+
};
|
|
209
|
+
return await F(e, t, o), R(o, i);
|
|
210
|
+
}))));
|
|
211
|
+
}),
|
|
212
|
+
checkIn: (e, t) => M(() => {
|
|
213
|
+
let n = w(t), r = l.decodeUnknownSync(l.toType(u))(structuredClone(e)), i = I(r, n);
|
|
214
|
+
return g(r, n, "checkIn").pipe(s.flatMap(() => N(() => T(n.tenantId, i))), s.flatMap(() => N(() => o.transactional(async (e) => {
|
|
215
|
+
await E(e, n.tenantId, i);
|
|
216
|
+
let { row: t, state: r } = await P(e, n, !0), a = C(m()), o = r.entries.find((e) => e.ownerId === i);
|
|
217
|
+
if (r.phase === "open" && o || S("conflict"), o.checkedInAt !== null) return R(r, i);
|
|
218
|
+
(a < r.definition.checkInOpensAt || a >= r.definition.checkInClosesAt) && S("conflict");
|
|
219
|
+
let s = {
|
|
220
|
+
...r,
|
|
221
|
+
entries: r.entries.map((e) => e.ownerId === i ? {
|
|
222
|
+
...e,
|
|
223
|
+
checkedInAt: a
|
|
224
|
+
} : e)
|
|
225
|
+
};
|
|
226
|
+
return await F(e, t, s), R(s, i);
|
|
227
|
+
}))));
|
|
228
|
+
}),
|
|
229
|
+
status: (e, t) => M(() => {
|
|
230
|
+
let n = w(t), r = l.decodeUnknownSync(l.toType(u))(structuredClone(e)), i = I(r, n);
|
|
231
|
+
return g(r, n, "status").pipe(s.flatMap(() => N(async () => R((await P(o, n)).state, i))));
|
|
232
|
+
}),
|
|
233
|
+
entrants: (e, t) => M(() => {
|
|
234
|
+
let n = w(t), r = l.decodeUnknownSync(l.toType(u))(structuredClone(e));
|
|
235
|
+
return L(r), g(r, n, "entrants").pipe(s.flatMap(() => N(async () => {
|
|
236
|
+
let e = (await P(o, n)).state;
|
|
237
|
+
return Object.freeze({
|
|
238
|
+
phase: e.phase,
|
|
239
|
+
entries: Object.freeze(e.entries.map((e) => Object.freeze({ ...e })))
|
|
240
|
+
});
|
|
241
|
+
})));
|
|
242
|
+
}),
|
|
243
|
+
seal: (e, t) => M(() => {
|
|
244
|
+
let r = w(t), i = l.decodeUnknownSync(l.toType(u))(structuredClone(e));
|
|
245
|
+
return L(i), g(i, r, "seal").pipe(s.flatMap(() => N(() => P(o, r))), s.flatMap((e) => N(() => o.transactional(async (t) => {
|
|
246
|
+
let i = e.state.entries.map((e) => e.ownerId).sort();
|
|
247
|
+
for (let e of i) await E(t, r.tenantId, e);
|
|
248
|
+
let { row: a, state: o } = await P(t, r, !0);
|
|
249
|
+
return n(o.entries.map((e) => e.ownerId).sort()) !== n(i) && S("conflict"), (!["open", "sealed"].includes(o.phase) || C(m()) < o.definition.checkInClosesAt) && S("conflict"), o.phase === "open" && await F(t, a, {
|
|
250
|
+
...o,
|
|
251
|
+
phase: "sealed"
|
|
252
|
+
}), Object.freeze({
|
|
253
|
+
checkedIn: Object.freeze(o.entries.filter((e) => e.checkedInAt !== null).map((e) => e.ownerId)),
|
|
254
|
+
noShows: Object.freeze(o.entries.filter((e) => e.checkedInAt === null).map((e) => e.ownerId))
|
|
255
|
+
});
|
|
256
|
+
}))));
|
|
257
|
+
}),
|
|
258
|
+
exportSubject: (e) => M(() => {
|
|
259
|
+
let t = A(e);
|
|
260
|
+
return b(t).pipe(s.flatMap(() => N(async () => (await z(t.target.tenantId)).flatMap(({ scope: e, state: n }) => {
|
|
261
|
+
let r = n.entries.find((e) => e.ownerId === t.target.subjectId);
|
|
262
|
+
return r ? [{
|
|
263
|
+
tournamentId: e.tournamentId,
|
|
264
|
+
phase: n.phase,
|
|
265
|
+
...r
|
|
266
|
+
}] : [];
|
|
267
|
+
}))));
|
|
268
|
+
}),
|
|
269
|
+
eraseSubject: (e) => M(() => {
|
|
270
|
+
let t = A(e), r = d("sha256").update(n(t.target)).digest("hex");
|
|
271
|
+
return _(t).pipe(s.flatMap(() => N(() => k(t.target.tenantId, t.target.subjectId))), s.flatMap(() => N(() => z(t.target.tenantId))), s.flatMap((e) => s.forEach(e.filter((e) => e.state.entries.some((e) => e.ownerId === t.target.subjectId) || e.state.eraseTarget === r && e.state.eraseRequest === t.requestId), ({ scope: e }) => N(() => o.transactional(async (n) => {
|
|
272
|
+
let { row: i, state: a } = await P(n, e, !0), o = a.entries.some((e) => e.ownerId === t.target.subjectId);
|
|
273
|
+
return !o && a.phase === "cancelled" && a.eraseRequest === t.requestId && a.eraseTarget === r || (o || S("unavailable"), a.phase === "erasing" && (a.eraseRequest !== t.requestId || a.eraseTarget !== r) && S("conflict"), await F(n, i, {
|
|
274
|
+
...a,
|
|
275
|
+
phase: "erasing",
|
|
276
|
+
eraseRequest: t.requestId,
|
|
277
|
+
eraseTarget: r
|
|
278
|
+
}), !1);
|
|
279
|
+
})).pipe(s.flatMap((n) => n ? s.void : v(e, t).pipe(s.flatMap(() => N(() => o.transactional(async (n) => {
|
|
280
|
+
let { row: i, state: a } = await P(n, e, !0);
|
|
281
|
+
(a.phase !== "erasing" || a.eraseRequest !== t.requestId || a.eraseTarget !== r) && S("conflict"), await F(n, i, {
|
|
282
|
+
...a,
|
|
283
|
+
phase: "cancelled",
|
|
284
|
+
entries: a.entries.filter((e) => e.ownerId !== t.target.subjectId)
|
|
285
|
+
});
|
|
286
|
+
})))))), {
|
|
287
|
+
concurrency: 1,
|
|
288
|
+
discard: !0
|
|
289
|
+
})));
|
|
290
|
+
})
|
|
291
|
+
});
|
|
292
|
+
}, N = (e, t) => c.succeed(o, M(e, t));
|
|
293
|
+
export { y as BRACKET_ADMISSIONS_TABLE, N as bracketAdmissionLayer, b as bracketAdmissionsTable, M as dataStoreBracketAdmissions, k as readBracketAdmissionWindow, j as resolveBracketAdmissionOptions };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { leaderboardError as e } from "./errors.js";
|
|
2
|
+
import { captureLeaderboardJson as t } from "./json.js";
|
|
3
|
+
import { Schema as n } from "effect";
|
|
4
|
+
// src/bracketAdmissionPolicy.ts
|
|
5
|
+
var r = n.Struct({
|
|
6
|
+
registrationOpensAt: n.Int,
|
|
7
|
+
registrationClosesAt: n.Int,
|
|
8
|
+
checkInOpensAt: n.Int,
|
|
9
|
+
checkInClosesAt: n.Int,
|
|
10
|
+
maxEntries: n.Int
|
|
11
|
+
}), i = (i) => {
|
|
12
|
+
let a;
|
|
13
|
+
try {
|
|
14
|
+
a = n.decodeUnknownSync(r)(t(i, 1024), { onExcessProperty: "error" });
|
|
15
|
+
} catch {
|
|
16
|
+
throw e("invalid_input");
|
|
17
|
+
}
|
|
18
|
+
if (a.registrationOpensAt < 0 || a.registrationClosesAt <= a.registrationOpensAt || a.checkInOpensAt < a.registrationClosesAt || a.checkInClosesAt <= a.checkInOpensAt || a.checkInClosesAt > 864e13 || a.maxEntries < 2 || a.maxEntries > 256) throw e("invalid_input");
|
|
19
|
+
return Object.freeze(a);
|
|
20
|
+
};
|
|
21
|
+
export { i as defineBracketAdmission };
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { LeaderboardError as e, leaderboardError as t } from "./errors.js";
|
|
2
|
+
import { captureLeaderboardJson as n } from "./json.js";
|
|
3
|
+
import { defineBracketAdmission as r } from "./bracketAdmissionPolicy.js";
|
|
4
|
+
import { dataStoreBracketAdmissions as i, resolveBracketAdmissionOptions as a } from "./bracketAdmission.js";
|
|
5
|
+
import { Effect as o, Schema as s } from "effect";
|
|
6
|
+
import { Subject as c } from "@voltro/protocol";
|
|
7
|
+
// src/bracketInstallation.ts
|
|
8
|
+
var l = [
|
|
9
|
+
"create",
|
|
10
|
+
"register",
|
|
11
|
+
"checkIn",
|
|
12
|
+
"status",
|
|
13
|
+
"seal",
|
|
14
|
+
"entrants",
|
|
15
|
+
"exportSubject",
|
|
16
|
+
"eraseSubject"
|
|
17
|
+
];
|
|
18
|
+
function u() {
|
|
19
|
+
throw t("invalid_input");
|
|
20
|
+
}
|
|
21
|
+
var d = (e) => {
|
|
22
|
+
e && typeof e == "object" || u();
|
|
23
|
+
for (let t of l) {
|
|
24
|
+
let n = Object.getOwnPropertyDescriptor(e, t);
|
|
25
|
+
n && "value" in n && typeof n.value == "function" || u();
|
|
26
|
+
}
|
|
27
|
+
return Object.freeze({
|
|
28
|
+
create: e.create.bind(e),
|
|
29
|
+
register: e.register.bind(e),
|
|
30
|
+
checkIn: e.checkIn.bind(e),
|
|
31
|
+
status: e.status.bind(e),
|
|
32
|
+
seal: e.seal.bind(e),
|
|
33
|
+
entrants: e.entrants.bind(e),
|
|
34
|
+
exportSubject: e.exportSubject.bind(e),
|
|
35
|
+
eraseSubject: e.eraseSubject.bind(e)
|
|
36
|
+
});
|
|
37
|
+
}, f = (l) => {
|
|
38
|
+
let f, p, m = null, h = Object.freeze([]);
|
|
39
|
+
if (l !== void 0) {
|
|
40
|
+
(!l || Object.getPrototypeOf(l) !== Object.prototype || Object.getOwnPropertySymbols(l).length) && u();
|
|
41
|
+
let e = Object.getOwnPropertyDescriptors(l);
|
|
42
|
+
Object.values(e).some((e) => !e.enumerable || !("value" in e)) && u(), l.backend === "sql" && Object.keys(e).length === 2 && Object.hasOwn(e, "options") ? (f = a(l.options), h = Object.freeze(["_voltro_tournament_admissions"]), m = Object.freeze({
|
|
43
|
+
backend: "sql",
|
|
44
|
+
version: "voltro:bracket-admission:1",
|
|
45
|
+
maxTenantTournaments: f.maxTenantTournaments
|
|
46
|
+
})) : l.backend === "custom" && Object.keys(e).length === 4 && Object.hasOwn(e, "version") && Object.hasOwn(e, "service") && Object.hasOwn(e, "sources") ? ((typeof l.version != "string" || !/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,119}$/.test(l.version) || l.version.startsWith("voltro:")) && u(), p = d(l.service), h = n(l.sources, 4096), (!Array.isArray(h) || h.length < 1 || h.length > 32 || new Set(h).size !== h.length || h.some((e) => typeof e != "string" || !/^[a-zA-Z_][a-zA-Z0-9_]{0,119}$/.test(e))) && u(), m = Object.freeze({
|
|
47
|
+
backend: "custom",
|
|
48
|
+
version: l.version,
|
|
49
|
+
maxTenantTournaments: null
|
|
50
|
+
})) : u();
|
|
51
|
+
}
|
|
52
|
+
let g, _ = !1, v = 0, y = /* @__PURE__ */ new Set(), b = () => {
|
|
53
|
+
if (v--, v === 0) for (let e of [...y]) e();
|
|
54
|
+
}, x = (n) => {
|
|
55
|
+
let r;
|
|
56
|
+
try {
|
|
57
|
+
r = n();
|
|
58
|
+
} catch (n) {
|
|
59
|
+
return o.fail(n instanceof e ? n : t("invalid_input"));
|
|
60
|
+
}
|
|
61
|
+
return o.acquireUseRelease(o.suspend(() => g === void 0 || _ ? o.fail(t("unavailable")) : (v++, o.succeed(g))), (e) => o.suspend(() => r(e)), () => o.sync(b)).pipe(o.uninterruptible);
|
|
62
|
+
}, S = (e) => s.decodeUnknownSync(s.toType(c))(structuredClone(e)), C = (e) => s.decodeUnknownSync(s.Struct({
|
|
63
|
+
requestId: s.NonEmptyString,
|
|
64
|
+
target: s.Struct({
|
|
65
|
+
subjectId: s.NonEmptyString,
|
|
66
|
+
tenantId: s.NullOr(s.NonEmptyString),
|
|
67
|
+
kind: s.Literals(["user", "guest"])
|
|
68
|
+
})
|
|
69
|
+
}))(n(e, 2048), { onExcessProperty: "error" }), w = Object.freeze({
|
|
70
|
+
create: (e, t, i) => x(() => {
|
|
71
|
+
let a = S(e), o = n(t, 1024), s = r(i);
|
|
72
|
+
return (e) => e.create(a, o, s);
|
|
73
|
+
}),
|
|
74
|
+
register: (e, t) => x(() => {
|
|
75
|
+
let r = S(e), i = n(t, 1024);
|
|
76
|
+
return (e) => e.register(r, i);
|
|
77
|
+
}),
|
|
78
|
+
checkIn: (e, t) => x(() => {
|
|
79
|
+
let r = S(e), i = n(t, 1024);
|
|
80
|
+
return (e) => e.checkIn(r, i);
|
|
81
|
+
}),
|
|
82
|
+
status: (e, t) => x(() => {
|
|
83
|
+
let r = S(e), i = n(t, 1024);
|
|
84
|
+
return (e) => e.status(r, i);
|
|
85
|
+
}),
|
|
86
|
+
seal: (e, t) => x(() => {
|
|
87
|
+
let r = S(e), i = n(t, 1024);
|
|
88
|
+
return (e) => e.seal(r, i);
|
|
89
|
+
}),
|
|
90
|
+
entrants: (e, t) => x(() => {
|
|
91
|
+
let r = S(e), i = n(t, 1024);
|
|
92
|
+
return (e) => e.entrants(r, i);
|
|
93
|
+
}),
|
|
94
|
+
exportSubject: (e) => x(() => {
|
|
95
|
+
let t = C(e);
|
|
96
|
+
return (e) => e.exportSubject(t);
|
|
97
|
+
}),
|
|
98
|
+
eraseSubject: (e) => x(() => {
|
|
99
|
+
let t = C(e);
|
|
100
|
+
return (e) => e.eraseSubject(t);
|
|
101
|
+
})
|
|
102
|
+
});
|
|
103
|
+
return Object.freeze({
|
|
104
|
+
configuration: m,
|
|
105
|
+
sources: h,
|
|
106
|
+
service: w,
|
|
107
|
+
isBound: () => g !== void 0 && !_,
|
|
108
|
+
boundService: () => _ ? void 0 : g,
|
|
109
|
+
bind: (e) => {
|
|
110
|
+
if (_) throw t("unavailable");
|
|
111
|
+
g = f === void 0 ? p : i(e, f);
|
|
112
|
+
},
|
|
113
|
+
close: () => {
|
|
114
|
+
_ = !0, g = void 0;
|
|
115
|
+
},
|
|
116
|
+
deactivate: () => o.sync(() => {
|
|
117
|
+
_ = !0, g = void 0;
|
|
118
|
+
}).pipe(o.flatMap(() => o.callback((e) => {
|
|
119
|
+
if (v === 0) {
|
|
120
|
+
e(o.void);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
let t = () => {
|
|
124
|
+
y.delete(t), e(o.void);
|
|
125
|
+
};
|
|
126
|
+
return y.add(t), o.sync(() => {
|
|
127
|
+
y.delete(t);
|
|
128
|
+
});
|
|
129
|
+
})))
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
export { f as makeBracketAdmissionInstallation };
|