@voltro/plugin-chat 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.
Files changed (50) hide show
  1. package/CHANGELOG.md +24492 -0
  2. package/LICENSE +61 -0
  3. package/README.md +516 -2
  4. package/SECURITY.md +56 -0
  5. package/THIRD-PARTY-NOTICES.md +16105 -0
  6. package/dist/admissions.entity.js +10 -0
  7. package/dist/channels.entity.js +19 -0
  8. package/dist/chat-app/events/chat.mentioned.event.ts +1 -0
  9. package/dist/chat-app/events/chat.messageChanged.event.ts +1 -0
  10. package/dist/chat-app/events/chat.typing.event.ts +1 -0
  11. package/dist/chat-app/schedules/chat.retention.cron.tsx +16 -0
  12. package/dist/chat-app/subscribers/chat.messages.subscribe.ts +4 -0
  13. package/dist/components.js +431 -0
  14. package/dist/contract.js +91 -0
  15. package/dist/errors.d.ts +13 -0
  16. package/dist/errors.js +20 -0
  17. package/dist/eventProducer.d.ts +18 -0
  18. package/dist/eventProducer.js +45 -0
  19. package/dist/events.d.ts +38 -0
  20. package/dist/events.js +35 -0
  21. package/dist/evidence.entity.js +24 -0
  22. package/dist/index.d.ts +623 -0
  23. package/dist/index.js +180 -0
  24. package/dist/inspect.js +37 -0
  25. package/dist/media.entity.js +14 -0
  26. package/dist/members.entity.js +21 -0
  27. package/dist/mentionDraft.js +20 -0
  28. package/dist/mentionNotifications.js +109 -0
  29. package/dist/messages.entity.js +27 -0
  30. package/dist/reportEvidence.js +15 -0
  31. package/dist/retention.entity.js +10 -0
  32. package/dist/rpc.d.ts +295 -0
  33. package/dist/rpc.js +266 -0
  34. package/dist/rpcRoutes.js +96 -0
  35. package/dist/server.d.ts +200 -0
  36. package/dist/server.js +6 -0
  37. package/dist/service.js +1411 -0
  38. package/dist/strategies.d.ts +148 -0
  39. package/dist/strategies.js +89 -0
  40. package/dist/testing.d.ts +139 -0
  41. package/dist/testing.js +110 -0
  42. package/dist/typing.js +87 -0
  43. package/dist/typingInvalidation.js +85 -0
  44. package/dist/typingLease.js +58 -0
  45. package/dist/typingPublisher.js +58 -0
  46. package/dist/useChatTypingPublisher.js +32 -0
  47. package/dist/useTyping.js +23 -0
  48. package/dist/web.d.ts +354 -0
  49. package/dist/web.js +18 -0
  50. package/package.json +98 -4
@@ -0,0 +1,1411 @@
1
+ import { ChatError as e, chatError as t } from "./errors.js";
2
+ import { chatAdmissionsTable as n } from "./admissions.entity.js";
3
+ import { chatEvidenceTable as r } from "./evidence.entity.js";
4
+ import { CHAT_MAX_MESSAGE_VERSION as i } from "./contract.js";
5
+ import { chatMediaTable as a } from "./media.entity.js";
6
+ import { chatRetentionTable as o } from "./retention.entity.js";
7
+ import { createChatTyping as s } from "./typing.js";
8
+ import { chatChannelsTable as c } from "./channels.entity.js";
9
+ import { chatMembersTable as l } from "./members.entity.js";
10
+ import { chatMessagesTable as u } from "./messages.entity.js";
11
+ import { Effect as d, Result as f } from "effect";
12
+ import { and as p, eq as m, gt as h, gte as g, inSet as _, jsonField as v, lt as y, lte as b, or as x, queryFor as S } from "@voltro/database";
13
+ import { StorageService as C } from "@voltro/plugin-storage";
14
+ import { createHash as w, randomUUID as ee } from "node:crypto";
15
+ import { SanctionsPort as te } from "@voltro/plugin-sanctions/port";
16
+ import { PlayersPort as ne } from "@voltro/plugin-players/port";
17
+ import { GuildMembershipPort as T } from "@voltro/plugin-guilds/port";
18
+ import { PartyMembershipPort as re } from "@voltro/plugin-matchmaking/port";
19
+ import { SocialBlockPort as ie } from "@voltro/plugin-social/port";
20
+ // src/service.ts
21
+ var E = (e) => w("sha256").update(JSON.stringify(e)).digest("hex"), D = (n) => n instanceof e ? n : t("unavailable"), O = (e) => d.tryPromise({
22
+ try: e,
23
+ catch: D
24
+ }), k = (e) => d.try({
25
+ try: e,
26
+ catch: D
27
+ }), A = (e) => {
28
+ if (typeof e != "string" || !e.trim() || e.length > 256 || e.includes("\0") || e === "~") throw t("invalid_input");
29
+ }, j = (e) => {
30
+ if (e.type !== "user") throw t("identity_required");
31
+ return A(e.id), A(e.tenantId), e;
32
+ }, M = (e) => {
33
+ let n = e instanceof Date ? e.getTime() : typeof e == "string" ? Date.parse(e) : NaN;
34
+ if (!Number.isSafeInteger(n) || n < 0) throw t("unavailable");
35
+ return n;
36
+ }, N = (e) => e === null ? null : M(e), P = (e, n) => {
37
+ let r = e[n];
38
+ if (typeof r != "string") throw t("unavailable");
39
+ return r;
40
+ }, F = (e) => e === !0 || e === 1, I = (e) => ({
41
+ id: P(e, "id"),
42
+ kind: e.kind,
43
+ refId: P(e, "refId"),
44
+ name: P(e, "name"),
45
+ slowModeMs: Number(e.slowModeMs),
46
+ retentionMs: e.retentionMs === null ? null : Number(e.retentionMs),
47
+ maxMembers: Number(e.maxMembers),
48
+ frozen: F(e.frozen),
49
+ createdAt: M(e.createdAt),
50
+ metadata: e.metadata
51
+ }), L = (e) => ({
52
+ id: P(e, "id"),
53
+ channelId: P(e, "channelId"),
54
+ subjectId: P(e, "subjectId"),
55
+ role: e.role,
56
+ mutedUntil: N(e.mutedUntil),
57
+ lastReadAt: M(e.lastReadAt),
58
+ lastReadId: e.lastReadId === null ? null : P(e, "lastReadId"),
59
+ notify: F(e.notify),
60
+ metadata: e.metadata
61
+ }), R = (e, t = !1) => ({
62
+ id: P(e, "id"),
63
+ channelId: P(e, "channelId"),
64
+ authorId: e.authorId,
65
+ kind: e.kind,
66
+ body: e.deletedAt !== null && !t ? "" : P(e, "body"),
67
+ payload: e.deletedAt !== null && !t ? {} : e.payload,
68
+ replyToId: e.replyToId,
69
+ editedAt: N(e.editedAt),
70
+ deletedAt: N(e.deletedAt),
71
+ flagged: F(e.flagged),
72
+ createdAt: M(e.createdAt),
73
+ version: Number(e.version),
74
+ metadata: e.metadata
75
+ }), z = (w, z, ae) => {
76
+ let B = () => {
77
+ let e = z.now();
78
+ if (!Number.isSafeInteger(e) || e < 0 || e > 864e13) throw t("unavailable");
79
+ return e;
80
+ }, oe = (e) => {
81
+ if (typeof e != "string" || !e.trim() || [...e].length > z.maxBodyLength || /[\u0000-\u0008\u000b\u000c\u000e-\u001f]/u.test(e)) throw t("invalid_input");
82
+ return e;
83
+ }, V = (e, t, n) => "cmem_" + E([
84
+ e,
85
+ t,
86
+ n
87
+ ]).slice(0, 56), H = async (e, n, r, i = !1) => {
88
+ A(r);
89
+ let a = S(c).where(m("id", r)).limit(1), o = (await e.query((i ? a.forUpdate() : a).descriptor))[0];
90
+ if (!o || o.tenantId !== n) throw t("not_found");
91
+ return o;
92
+ }, U = async (e, n, r, i) => {
93
+ let a = (await e.query(S(l).where(m("id", V(n, r, i))).limit(1).descriptor))[0];
94
+ if (!a || a.tenantId !== n || a.channelId !== r || a.subjectId !== i) throw t("forbidden");
95
+ return a;
96
+ }, W = async (e, n, r) => {
97
+ A(r);
98
+ let i = (await e.query(S(u).where(m("id", r)).limit(1).descriptor))[0];
99
+ if (!i || i.tenantId !== n) throw t("not_found");
100
+ return i;
101
+ }, G = (e, t) => "cadm_" + E([e, t]).slice(0, 56), se = async (e, t) => {
102
+ A(e);
103
+ for (let r of [...new Set(t)].sort()) A(r), await w.insertIgnore(n.tableName, {
104
+ id: G(e, r),
105
+ tenantId: e,
106
+ subjectId: r,
107
+ admission: 0,
108
+ erased: !1
109
+ }, { conflictColumns: ["id"] });
110
+ }, ce = async (e, r, i, a = !1) => {
111
+ for (let o of i) {
112
+ let i = (await e.query(S(n).where(m("id", G(r, o))).limit(1).descriptor))[0];
113
+ if (i) {
114
+ if (i.tenantId !== r || !F(i.erased) && i.subjectId !== o) throw t("unavailable");
115
+ if (F(i.erased) && !a) throw t("identity_required");
116
+ }
117
+ }
118
+ }, le = async (e, r, i) => {
119
+ let a = [...new Set(i)].sort((e, t) => G(r, e) < G(r, t) ? -1 : 1);
120
+ for (let i of a) if (await e.updateMany(n.tableName, { admission: 0 }, { where: m("id", G(r, i)) }) !== 1) throw t("unavailable");
121
+ return a;
122
+ }, ue = async (e, t, n, r = !1) => ce(e, t, await le(e, t, n), r), K = async (e, n, r, i = []) => (i.length && await se(e, i), w.transactional(async (a) => {
123
+ let o = i.length ? await le(a, e, i) : [];
124
+ if (await a.updateMany(c.tableName, { admission: 0 }, { where: m("id", n) }) !== 1) throw t("not_found");
125
+ return await ce(a, e, o), r(a, await H(a, e, n, !0));
126
+ })), q = async (e, n, r) => {
127
+ if (!e || n.id === r) return !1;
128
+ try {
129
+ return await d.runPromise(e.isBlocked(n, r));
130
+ } catch {
131
+ throw t("unavailable");
132
+ }
133
+ }, J = d.serviceOption(ie).pipe(d.map((e) => e._tag === "Some" ? e.value : void 0)), de = d.serviceOption(C).pipe(d.map((e) => e._tag === "Some" ? e.value : void 0)), Y = d.all([d.serviceOption(T), d.serviceOption(re)]).pipe(d.map(([e, t]) => ({
134
+ ...e._tag === "Some" ? { guild: e.value } : {},
135
+ ...t._tag === "Some" ? { party: t.value } : {}
136
+ }))), fe = (e, t) => t.kind === "guild" ? e.guild : t.kind === "party" ? e.party : void 0, X = async (e, n, r, i) => {
137
+ let a = fe(e, r);
138
+ if (!a) return;
139
+ let o;
140
+ try {
141
+ o = await d.runPromise(a.isMember({
142
+ type: "user",
143
+ id: i,
144
+ tenantId: n
145
+ }, P(r, "refId")));
146
+ } catch {
147
+ throw t("unavailable");
148
+ }
149
+ if (o !== !0) throw t("forbidden");
150
+ }, pe = async (t, n, r, i) => {
151
+ try {
152
+ return await X(t, n, r, i), !0;
153
+ } catch (t) {
154
+ if (t instanceof e && t.code === "forbidden") return !1;
155
+ throw t;
156
+ }
157
+ }, Z = async (e) => {
158
+ try {
159
+ return {
160
+ ok: !0,
161
+ value: await e()
162
+ };
163
+ } catch (e) {
164
+ return {
165
+ ok: !1,
166
+ error: e
167
+ };
168
+ }
169
+ }, Q = (e) => {
170
+ if (!e) throw t("unavailable");
171
+ if (!e.ok) throw e.error;
172
+ return e.value;
173
+ }, me = (e, t) => "cmed_" + E([e, t]).slice(0, 56), he = (e) => E(e.mediaId === void 0 ? [e.body, e.replyToId ?? null] : [
174
+ e.body,
175
+ e.replyToId ?? null,
176
+ e.mediaId
177
+ ]), ge = (e, n) => d.gen(function* () {
178
+ let r = yield* de;
179
+ if (!r) return yield* d.fail(t("forbidden"));
180
+ let i = yield* d.suspend(() => r.head(n, { tenantId: e.tenantId })).pipe(d.mapError(() => t("unavailable")), d.catchDefect(() => d.fail(t("unavailable"))));
181
+ if (i === null) return yield* d.fail(t("not_found"));
182
+ let a = yield* k(() => {
183
+ if (i.id !== n || i.tenantId !== e.tenantId || i.ownerId !== e.id || (i.derivedFrom ?? null) !== null || i.passwordHash !== null) throw t("forbidden");
184
+ let r = (e) => {
185
+ if (e == null) return null;
186
+ if (!Number.isSafeInteger(e) || e < 0) throw t("unavailable");
187
+ return e;
188
+ };
189
+ if (typeof i.contentType != "string" || !Number.isSafeInteger(i.size) || i.size < 0) throw t("unavailable");
190
+ return {
191
+ id: i.id,
192
+ contentType: i.contentType,
193
+ size: i.size,
194
+ width: r(i.width),
195
+ height: r(i.height)
196
+ };
197
+ }), o = yield* d.suspend(() => z.strategies.moderateMedia({
198
+ subject: e,
199
+ ref: a,
200
+ contentTypes: z.mediaContentTypes,
201
+ maxBytes: z.maxMediaBytes
202
+ })).pipe(d.catchDefect(() => d.fail(t("unavailable"))));
203
+ return o.allowed === !0 ? typeof o.flagged == "boolean" ? {
204
+ media: a,
205
+ flagged: o.flagged
206
+ } : yield* d.fail(t("unavailable")) : yield* d.fail(t("content_rejected"));
207
+ }), _e = (e, n) => d.gen(function* () {
208
+ let r = yield* d.serviceOption(te);
209
+ if (r._tag !== "None" && (yield* d.suspend(() => r.value.check(e, "chat", { channelId: n })).pipe(d.mapError(() => t("unavailable")), d.catchDefect(() => d.fail(t("unavailable"))))).allowed !== !0) return yield* d.fail(t("sanctioned"));
210
+ }), ve = (e) => d.suspend(() => z.strategies.moderate({
211
+ body: e,
212
+ denyWords: z.denyWords,
213
+ action: z.moderationAction
214
+ })).pipe(d.flatMap((e) => e.allowed === !0 ? k(() => {
215
+ if (oe(e.body), typeof e.flagged != "boolean") throw t("unavailable");
216
+ return e;
217
+ }) : d.fail(t("content_rejected"))), d.catchDefect(() => d.fail(t("unavailable")))), $ = (e) => {
218
+ let n = z.strategies.retention(I(e));
219
+ if (n !== null && (!Number.isSafeInteger(n) || n < 1 || n > 31536e7)) throw t("unavailable");
220
+ return n;
221
+ }, ye = s({
222
+ store: w,
223
+ now: B,
224
+ options: z,
225
+ limiter: ae,
226
+ social: J,
227
+ sanctioned: _e,
228
+ readAccess: (t, n, r) => Y.pipe(d.flatMap((i) => O(async () => {
229
+ let a = j(t), o = await w.transactional(async (t) => {
230
+ let i = await H(t, a.tenantId, n), o = await U(t, a.tenantId, n, a.id), s = null;
231
+ if (r !== void 0) {
232
+ A(r);
233
+ try {
234
+ s = L(await U(t, a.tenantId, n, r));
235
+ } catch (t) {
236
+ if (!(t instanceof e) || t.code !== "forbidden") throw t;
237
+ }
238
+ }
239
+ return {
240
+ current: i,
241
+ own: o,
242
+ peer: s
243
+ };
244
+ });
245
+ await X(i, a.tenantId, o.current, a.id);
246
+ let s = o.peer !== null && r !== void 0 && !await pe(i, a.tenantId, o.current, r) ? null : o.peer;
247
+ return {
248
+ channel: I(o.current),
249
+ member: L(o.own),
250
+ peer: s
251
+ };
252
+ })))
253
+ }), be = {
254
+ prepareTyping: ye.prepare,
255
+ mentionCandidates: (e, n) => {
256
+ let r, i;
257
+ try {
258
+ r = structuredClone(j(e)), i = structuredClone(n), A(i.channelId), i.after !== void 0 && A(i.after);
259
+ } catch (e) {
260
+ return d.fail(D(e));
261
+ }
262
+ return d.gen(function* () {
263
+ let e = j(r), n = yield* Y, a = yield* O(async () => {
264
+ let r = await H(w, e.tenantId, i.channelId);
265
+ await U(w, e.tenantId, i.channelId, e.id), await X(n, e.tenantId, r, e.id);
266
+ let a = await w.query(S(l).where(p(m("tenantId", e.tenantId), m("channelId", i.channelId), ...i.after === void 0 ? [] : [h("id", i.after)])).orderBy("id", "asc").limit(129).descriptor);
267
+ if (a.some((t) => t.tenantId !== e.tenantId || t.channelId !== i.channelId)) throw t("unavailable");
268
+ return a;
269
+ }), o = a.slice(0, 128);
270
+ return {
271
+ authors: yield* be.authors(e, {
272
+ channelId: i.channelId,
273
+ subjectIds: o.map((e) => P(e, "subjectId"))
274
+ }),
275
+ after: a.length > 128 ? P(o[o.length - 1], "id") : null
276
+ };
277
+ }).pipe(d.catchDefect(() => d.fail(t("unavailable"))));
278
+ },
279
+ authors: (n, r) => {
280
+ let i, a, o;
281
+ try {
282
+ if (i = structuredClone(j(n)), a = r.channelId, A(a), !Array.isArray(r.subjectIds) || r.subjectIds.length > 128 || (o = [...r.subjectIds], o.forEach(A), new Set(o).size !== o.length)) throw t("invalid_input");
283
+ } catch (e) {
284
+ return d.fail(D(e));
285
+ }
286
+ return d.gen(function* () {
287
+ let n = j(i), r = yield* J, s = yield* d.serviceOption(ne), c = yield* Y, l = async (t) => {
288
+ let i = await H(w, n.tenantId, a);
289
+ await U(w, n.tenantId, a, n.id), await X(c, n.tenantId, i, n.id);
290
+ try {
291
+ await U(w, n.tenantId, a, t);
292
+ } catch (t) {
293
+ if (t instanceof e && t.code === "forbidden") return !1;
294
+ throw t;
295
+ }
296
+ return await pe(c, n.tenantId, i, t) ? !await q(r, n, t) : !1;
297
+ };
298
+ if (yield* O(async () => {
299
+ let e = await H(w, n.tenantId, a);
300
+ await U(w, n.tenantId, a, n.id), await X(c, n.tenantId, e, n.id);
301
+ }), s._tag === "None") return [];
302
+ let u = [];
303
+ for (let e of o) {
304
+ if (!(yield* O(() => l(e)))) continue;
305
+ let r = yield* d.suspend(() => s.value.resolveMember(n, e)).pipe(d.mapError(() => t("unavailable")), d.catchDefect(() => d.fail(t("unavailable"))));
306
+ r !== null && (yield* k(() => {
307
+ if (typeof r.displayName != "string" || !r.displayName.trim() || r.displayName.length > 256 || r.avatar !== null && (typeof r.avatar != "string" || r.avatar.length > 2048)) throw t("unavailable");
308
+ }), (yield* O(() => l(e))) && u.push({
309
+ subjectId: e,
310
+ displayName: r.displayName,
311
+ avatar: r.avatar
312
+ }));
313
+ }
314
+ let f = [];
315
+ for (let e of u) (yield* O(() => l(e.subjectId))) && f.push(e);
316
+ return yield* O(async () => {
317
+ await H(w, n.tenantId, a), await U(w, n.tenantId, a, n.id);
318
+ }), f;
319
+ });
320
+ },
321
+ dm: (e, n) => d.gen(function* () {
322
+ let r = yield* k(() => {
323
+ let r = j(e);
324
+ if (A(n), r.id === n) throw t("invalid_input");
325
+ return r;
326
+ }), i = yield* J;
327
+ if (!i) return yield* d.fail(t("forbidden"));
328
+ if (!(yield* i.canMessage(r, n).pipe(d.mapError(() => t("unavailable"))))) return yield* d.fail(t("blocked"));
329
+ let a = [r.id, n].sort();
330
+ return yield* De({
331
+ type: "serviceAccount",
332
+ id: "chat:dm",
333
+ tenantId: r.tenantId,
334
+ scopes: ["chat:channels:write"]
335
+ }, {
336
+ tenantId: r.tenantId,
337
+ kind: "dm",
338
+ refId: E([r.tenantId, a]),
339
+ name: "",
340
+ maxMembers: 2,
341
+ members: a.map((e) => ({
342
+ subjectId: e,
343
+ role: "member"
344
+ }))
345
+ });
346
+ }),
347
+ send: (e, n) => d.gen(function* () {
348
+ let r = yield* k(() => {
349
+ let t = j(e);
350
+ return A(n.channelId), A(n.requestId), (n.mediaId === void 0 || n.body !== "") && oe(n.body), n.mediaId !== void 0 && A(n.mediaId), t;
351
+ }), i = yield* O(async () => {
352
+ let e = "cmsg_" + E([
353
+ r.tenantId,
354
+ n.channelId,
355
+ r.id,
356
+ n.requestId
357
+ ]).slice(0, 56), i = (await w.query(S(u).where(m("id", e)).limit(1).descriptor))[0];
358
+ if (!i) return null;
359
+ if (await U(w, r.tenantId, n.channelId, r.id), i.tenantId !== r.tenantId || i.channelId !== n.channelId || i.authorId !== r.id || i.requestKey !== he(n)) throw t("conflict");
360
+ return R(i);
361
+ });
362
+ if (i !== null) return i;
363
+ let o = yield* J, s = yield* O(() => H(w, r.tenantId, n.channelId));
364
+ yield* O(() => U(w, r.tenantId, n.channelId, r.id));
365
+ let c = n.body === "" ? {
366
+ body: "",
367
+ flagged: !1
368
+ } : yield* ve(n.body), f = n.body === "" ? [] : yield* d.suspend(() => z.strategies.mentionResolver({
369
+ body: c.body,
370
+ subject: r,
371
+ maxMentions: z.maxMentions
372
+ })).pipe(d.catchDefect(() => d.fail(t("unavailable"))));
373
+ yield* k(() => {
374
+ if (f.length > z.maxMentions || new Set(f).size !== f.length) throw t("invalid_input");
375
+ f.forEach(A);
376
+ });
377
+ let p = yield* k(() => {
378
+ let e = z.strategies.rateLimit({
379
+ channel: I(s),
380
+ perChannel: z.perChannelRate,
381
+ global: z.globalRate
382
+ });
383
+ if (![e.perChannel, e.global].every((e) => Number.isSafeInteger(e) && e > 0 && e <= 1e4)) throw t("unavailable");
384
+ return e;
385
+ });
386
+ for (let [e, i] of [[E([
387
+ r.tenantId,
388
+ r.id,
389
+ n.channelId
390
+ ]), p.perChannel], [E([r.tenantId, r.id]), p.global]]) {
391
+ let n = yield* ae.consume("chat:send:" + e, {
392
+ limit: i,
393
+ windowMs: 1e3,
394
+ algorithm: "fixed-window",
395
+ burst: i
396
+ }, B()).pipe(d.catchDefect(() => d.fail(t("unavailable"))));
397
+ if (n.failOpenReason !== void 0) return yield* d.fail(t("unavailable"));
398
+ if (!n.allowed) return yield* d.fail(t("rate_limited"));
399
+ }
400
+ yield* _e(r, n.channelId);
401
+ let h = yield* Y, g = n.mediaId === void 0 ? null : yield* ge(r, n.mediaId), _ = yield* O(async () => {
402
+ let e = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), a = async (e) => {
403
+ i.has(e) || i.set(e, await Z(() => q(o, r, e)));
404
+ };
405
+ e.set(r.id, await Z(() => X(h, r.tenantId, s, r.id)));
406
+ let c, u;
407
+ if (s.kind === "dm" && o) {
408
+ let e = (await w.query(S(l).where(m("channelId", n.channelId)).limit(3).descriptor)).find((e) => e.tenantId === r.tenantId && e.subjectId !== r.id);
409
+ if (e) {
410
+ let n = P(e, "subjectId");
411
+ c = n, await a(n), u = await Z(async () => {
412
+ try {
413
+ return await d.runPromise(o.canMessage(r, n));
414
+ } catch {
415
+ throw t("unavailable");
416
+ }
417
+ });
418
+ }
419
+ }
420
+ if (n.replyToId !== void 0) {
421
+ let e = await Z(() => W(w, r.tenantId, n.replyToId));
422
+ e.ok && e.value.authorId !== null && await a(P(e.value, "authorId"));
423
+ }
424
+ for (let t of f) e.set(t, await Z(() => X(h, r.tenantId, s, t))), await a(t);
425
+ return {
426
+ roster: e,
427
+ block: i,
428
+ recipientId: c,
429
+ canMessage: u
430
+ };
431
+ });
432
+ return yield* O(() => K(r.tenantId, n.channelId, async (e, i) => {
433
+ let s = await U(e, r.tenantId, n.channelId, r.id), d = B();
434
+ Q(_.roster.get(r.id));
435
+ let p = "cmsg_" + E([
436
+ r.tenantId,
437
+ n.channelId,
438
+ r.id,
439
+ n.requestId
440
+ ]).slice(0, 56), h = (await e.query(S(u).where(m("id", p)).limit(1).descriptor))[0];
441
+ if (h) {
442
+ if (h.tenantId !== r.tenantId || h.channelId !== n.channelId || h.authorId !== r.id || h.requestKey !== he(n)) throw t("conflict");
443
+ return R(h);
444
+ }
445
+ if (F(i.frozen)) throw t("frozen");
446
+ if (s.mutedUntil !== null && M(s.mutedUntil) > d) throw t("muted");
447
+ if (s.lastSentAt !== null && d - M(s.lastSentAt) < Number(i.slowModeMs)) throw t("slow_mode");
448
+ if (i.kind === "dm") {
449
+ let i = await e.query(S(l).where(m("channelId", n.channelId)).limit(3).descriptor);
450
+ if (i.length !== 2 || i.some((e) => e.tenantId !== r.tenantId)) throw t("unavailable");
451
+ let a = i.find((e) => e.subjectId !== r.id);
452
+ if (!a || !o) throw t("forbidden");
453
+ let s = P(a, "subjectId");
454
+ if (s !== _.recipientId) throw t("unavailable");
455
+ if (Q(_.block.get(s))) throw t("blocked");
456
+ if (!Q(_.canMessage)) throw t("forbidden");
457
+ }
458
+ if (n.replyToId !== void 0) {
459
+ let i = await W(e, r.tenantId, n.replyToId);
460
+ if (i.channelId !== n.channelId || i.deletedAt !== null || i.authorId !== null && Q(_.block.get(P(i, "authorId")))) throw t("forbidden");
461
+ }
462
+ for (let i of f) if (await U(e, r.tenantId, n.channelId, i), Q(_.roster.get(i)), Q(_.block.get(i))) throw t("blocked");
463
+ let v = await e.insert(u.tableName, {
464
+ id: p,
465
+ tenantId: r.tenantId,
466
+ channelId: n.channelId,
467
+ authorId: r.id,
468
+ requestKey: he(n),
469
+ kind: g ? "media" : "text",
470
+ body: c.body,
471
+ originalBody: c.body,
472
+ payload: g ? {
473
+ mentions: [...f],
474
+ media: g.media
475
+ } : { mentions: [...f] },
476
+ replyToId: n.replyToId ?? null,
477
+ editedAt: null,
478
+ deletedAt: null,
479
+ flagged: c.flagged || g?.flagged === !0,
480
+ createdAt: new Date(d),
481
+ version: 0,
482
+ metadata: {}
483
+ });
484
+ return g && await e.insert(a.tableName, {
485
+ id: me(r.tenantId, p),
486
+ tenantId: r.tenantId,
487
+ channelId: n.channelId,
488
+ messageId: p,
489
+ storageId: g.media.id,
490
+ ownerId: r.id,
491
+ state: "active",
492
+ createdAt: new Date(d)
493
+ }), await e.update(l.tableName, V(r.tenantId, n.channelId, r.id), { lastSentAt: new Date(d) }), R(v);
494
+ }));
495
+ }),
496
+ edit: (e, n) => d.gen(function* () {
497
+ let r = yield* k(() => {
498
+ let r = j(e);
499
+ if (oe(n.body), !Number.isSafeInteger(n.baseVersion) || n.baseVersion < 0 || n.baseVersion >= 2147483647) throw t("invalid_input");
500
+ return r;
501
+ }), i = yield* ve(n.body), a = yield* J, o = yield* O(() => W(w, r.tenantId, n.messageId));
502
+ return yield* _e(r, P(o, "channelId")), yield* O(async () => {
503
+ let e = /* @__PURE__ */ new Map();
504
+ for (let t of await w.query(S(l).where(m("channelId", P(o, "channelId"))).limit(3).descriptor)) {
505
+ let n = P(t, "subjectId");
506
+ n !== r.id && e.set(n, await Z(() => q(a, r, n)));
507
+ }
508
+ return K(r.tenantId, P(o, "channelId"), async (a, o) => {
509
+ let s = await U(a, r.tenantId, P(o, "id"), r.id), c = await W(a, r.tenantId, n.messageId);
510
+ if (c.authorId !== r.id || c.deletedAt !== null) throw t("forbidden");
511
+ if (F(o.frozen)) throw t("frozen");
512
+ if (s.mutedUntil !== null && M(s.mutedUntil) > B()) throw t("muted");
513
+ if (o.kind === "dm") {
514
+ let n = await a.query(S(l).where(m("channelId", o.id)).limit(3).descriptor);
515
+ for (let i of n) if (i.subjectId !== r.id && Q(e.get(P(i, "subjectId")))) throw t("blocked");
516
+ }
517
+ if (c.version !== n.baseVersion) throw t("conflict");
518
+ let d = await a.update(u.tableName, n.messageId, {
519
+ body: i.body,
520
+ flagged: i.flagged,
521
+ payload: c.kind === "media" && typeof c.payload == "object" && c.payload !== null ? { media: c.payload.media } : {},
522
+ editedAt: new Date(B()),
523
+ version: n.baseVersion + 1
524
+ });
525
+ if (!d) throw t("unavailable");
526
+ return R(d);
527
+ });
528
+ });
529
+ }),
530
+ remove: (e, n) => O(async () => {
531
+ let r = j(e);
532
+ if (!Number.isSafeInteger(n.baseVersion) || n.baseVersion < 0 || n.baseVersion >= 2147483647) throw t("invalid_input");
533
+ let i = await W(w, r.tenantId, n.messageId);
534
+ return K(r.tenantId, P(i, "channelId"), async (e, i) => {
535
+ let a = await U(e, r.tenantId, P(i, "id"), r.id), o = await W(e, r.tenantId, n.messageId);
536
+ if (o.authorId !== r.id && a.role !== "mod" && a.role !== "owner") throw t("forbidden");
537
+ if (o.deletedAt !== null) return R(o);
538
+ if (o.version !== n.baseVersion) throw t("conflict");
539
+ let s = await e.update(u.tableName, n.messageId, {
540
+ deletedAt: new Date(B()),
541
+ version: n.baseVersion + 1
542
+ });
543
+ if (!s) throw t("unavailable");
544
+ return R(s);
545
+ });
546
+ }),
547
+ messages: (e, n) => d.gen(function* () {
548
+ let r = yield* k(() => j(e)), i = yield* J, a = yield* Y;
549
+ return yield* O(async () => {
550
+ let e = await H(w, r.tenantId, n.channelId);
551
+ await U(w, r.tenantId, n.channelId, r.id), await X(a, r.tenantId, e, r.id);
552
+ let o = n.before;
553
+ if (o !== void 0 && (A(o.id), !Number.isSafeInteger(o.at) || o.at < 0 || o.at > B())) throw t("invalid_input");
554
+ let s = $(e), c = p(m("tenantId", r.tenantId), m("channelId", n.channelId), ...s === null ? [] : [g("createdAt", new Date(Math.max(0, B() - s)))], ...o === void 0 ? [] : [x(y("createdAt", new Date(o.at)), p(m("createdAt", new Date(o.at)), y("id", o.id)))]), l = await w.query(S(u).where(c).orderBy("createdAt", "desc").orderBy("id", "desc").limit(z.pageSize).descriptor), d = [];
555
+ for (let e of l) {
556
+ if (e.tenantId !== r.tenantId || e.channelId !== n.channelId) throw t("unavailable");
557
+ e.authorId !== null && await q(i, r, P(e, "authorId")) || d.push(R(e));
558
+ }
559
+ let f = l.at(-1);
560
+ return {
561
+ messages: d,
562
+ before: l.length === z.pageSize && f ? {
563
+ at: M(f.createdAt),
564
+ id: P(f, "id")
565
+ } : null
566
+ };
567
+ });
568
+ }),
569
+ channel: (e, t) => d.gen(function* () {
570
+ let n = yield* k(() => j(e)), r = yield* Y;
571
+ return yield* O(async () => {
572
+ let e = await H(w, n.tenantId, t);
573
+ return await U(w, n.tenantId, t, n.id), await X(r, n.tenantId, e, n.id), I(e);
574
+ });
575
+ }),
576
+ membership: (e, t) => d.gen(function* () {
577
+ let n = yield* k(() => j(e)), r = yield* Y;
578
+ return yield* O(async () => {
579
+ let e = await w.transactional(async (e) => ({
580
+ row: await H(e, n.tenantId, t),
581
+ own: L(await U(e, n.tenantId, t, n.id))
582
+ }));
583
+ return await X(r, n.tenantId, e.row, n.id), e.own;
584
+ });
585
+ }),
586
+ channels: (e) => d.gen(function* () {
587
+ let n = yield* k(() => j(e)), r = yield* Y;
588
+ return yield* O(async () => {
589
+ let e = await w.query(S(l).where(p(m("tenantId", n.tenantId), m("subjectId", n.id))).orderBy("id", "asc").limit(z.maxChannelsPerSubject + 1).descriptor);
590
+ if (e.length > z.maxChannelsPerSubject) throw t("unavailable");
591
+ let i = [];
592
+ for (let a of e) {
593
+ if (a.tenantId !== n.tenantId || a.subjectId !== n.id) throw t("unavailable");
594
+ let e = await H(w, n.tenantId, P(a, "channelId"));
595
+ await pe(r, n.tenantId, e, n.id) && i.push(I(e));
596
+ }
597
+ return i;
598
+ });
599
+ }),
600
+ unread: (e) => d.gen(function* () {
601
+ let n = yield* k(() => j(e)), r = yield* J, i = yield* Y;
602
+ return yield* O(async () => {
603
+ let e = await w.transactional(async (e) => {
604
+ let r = await e.query(S(l).where(p(m("tenantId", n.tenantId), m("subjectId", n.id))).orderBy("id", "asc").limit(z.maxChannelsPerSubject + 1).descriptor);
605
+ if (r.length > z.maxChannelsPerSubject) throw t("unavailable");
606
+ let i = [];
607
+ for (let a of r) {
608
+ if (a.tenantId !== n.tenantId || a.subjectId !== n.id) throw t("unavailable");
609
+ let r = P(a, "channelId"), o = await H(e, n.tenantId, r), s = $(o), c = M(a.lastReadAt), l = a.lastReadId === null ? g("createdAt", new Date(c)) : x(h("createdAt", new Date(c)), p(m("createdAt", new Date(c)), h("id", P(a, "lastReadId")))), d = await e.query(S(u).where(p(m("tenantId", n.tenantId), m("channelId", r), l, ...s === null ? [] : [g("createdAt", new Date(Math.max(0, B() - s)))])).orderBy("createdAt", "asc").orderBy("id", "asc").limit(z.maxExportRows + 1).descriptor);
610
+ for (let e of d.slice(0, z.maxExportRows)) if (e.tenantId !== n.tenantId || e.channelId !== r) throw t("unavailable");
611
+ i.push({
612
+ channelId: r,
613
+ c: o,
614
+ candidates: d
615
+ });
616
+ }
617
+ return i;
618
+ }), a = [];
619
+ for (let { channelId: t, c: o, candidates: s } of e) {
620
+ if (!await pe(i, n.tenantId, o, n.id)) continue;
621
+ let e = 0;
622
+ for (let t of s.slice(0, z.maxExportRows)) t.deletedAt !== null || t.authorId === n.id || t.authorId !== null && await q(r, n, P(t, "authorId")) || e++;
623
+ a.push({
624
+ channelId: t,
625
+ count: e,
626
+ truncated: s.length > z.maxExportRows
627
+ });
628
+ }
629
+ return a;
630
+ });
631
+ }),
632
+ original: (e, n) => O(() => w.transactional(async (r) => {
633
+ let i = j(e), a = await W(r, i.tenantId, n), o = await U(r, i.tenantId, P(a, "channelId"), i.id);
634
+ if (await H(r, i.tenantId, P(a, "channelId")), o.role !== "owner" && o.role !== "mod") throw t("forbidden");
635
+ return {
636
+ message: R(a, !0),
637
+ originalBody: P(a, "originalBody")
638
+ };
639
+ })),
640
+ mediaUrl: (e, n) => d.gen(function* () {
641
+ let r = yield* k(() => j(e)), i = yield* J, o = yield* de, s = yield* Y, c = yield* O(async () => {
642
+ let e = await W(w, r.tenantId, n), o = P(e, "channelId"), c = await H(w, r.tenantId, o), l = await U(w, r.tenantId, o, r.id);
643
+ if (e.kind !== "media" || (await X(s, r.tenantId, c, r.id), e.deletedAt !== null && l.role !== "mod" && l.role !== "owner")) throw t("not_found");
644
+ let u = $(c);
645
+ if (u !== null && M(e.createdAt) < B() - u) throw t("not_found");
646
+ if (e.authorId !== null && await q(i, r, P(e, "authorId"))) throw t("forbidden");
647
+ let d = (await w.query(S(a).where(m("id", me(r.tenantId, n))).limit(1).descriptor))[0];
648
+ if (!d || d.state !== "active") throw t("not_found");
649
+ if (d.tenantId !== r.tenantId || d.messageId !== n || d.channelId !== o) throw t("unavailable");
650
+ return P(d, "storageId");
651
+ });
652
+ if (!o) return yield* d.fail(t("unavailable"));
653
+ let l = yield* k(B), u = yield* d.suspend(() => o.head(c, { tenantId: r.tenantId })).pipe(d.mapError(() => t("unavailable")), d.catchDefect(() => d.fail(t("unavailable"))));
654
+ return u === null || u.tenantId !== r.tenantId ? yield* d.fail(t("not_found")) : {
655
+ url: yield* d.suspend(() => o.getUrl(c, {
656
+ tenantId: r.tenantId,
657
+ expiresInSec: z.mediaUrlTtlSec
658
+ })).pipe(d.mapError(() => t("unavailable")), d.catchDefect(() => d.fail(t("unavailable")))),
659
+ expiresAt: l + z.mediaUrlTtlSec * 1e3
660
+ };
661
+ }),
662
+ markRead: (e, n, r) => O(async () => {
663
+ let i = j(e);
664
+ return K(i.tenantId, n, async (e) => {
665
+ let a = await U(e, i.tenantId, n, i.id), o = await W(e, i.tenantId, r);
666
+ if (o.channelId !== n) throw t("forbidden");
667
+ let s = M(a.lastReadAt), c = M(o.createdAt), u = P(o, "id");
668
+ if (c < s || c === s && a.lastReadId !== null && u <= P(a, "lastReadId")) return L(a);
669
+ let d = await e.update(l.tableName, P(a, "id"), {
670
+ lastReadAt: new Date(c),
671
+ lastReadId: u
672
+ });
673
+ if (!d) throw t("unavailable");
674
+ return L(d);
675
+ });
676
+ }),
677
+ moderateMember: (e, n) => O(async () => {
678
+ let r = j(e);
679
+ return K(r.tenantId, n.channelId, async (e) => {
680
+ let i = await U(e, r.tenantId, n.channelId, r.id), a = await U(e, r.tenantId, n.channelId, n.subjectId);
681
+ if (i.role !== "owner" && (i.role !== "mod" || a.role !== "member")) throw t("forbidden");
682
+ if (a.role === "owner" || n.mutedUntil !== null && (!Number.isSafeInteger(n.mutedUntil) || n.mutedUntil < B() || n.mutedUntil > B() + 31536e6)) throw t("invalid_input");
683
+ let o = await e.update(l.tableName, P(a, "id"), { mutedUntil: n.mutedUntil === null ? null : new Date(n.mutedUntil) });
684
+ if (!o) throw t("unavailable");
685
+ return L(o);
686
+ });
687
+ }),
688
+ configure: (e, n) => O(async () => {
689
+ let r = j(e);
690
+ return K(r.tenantId, n.channelId, async (e, i) => {
691
+ let a = await U(e, r.tenantId, n.channelId, r.id);
692
+ if (a.role !== "mod" && a.role !== "owner") throw t("forbidden");
693
+ if (n.slowModeMs !== void 0 && (!Number.isSafeInteger(n.slowModeMs) || n.slowModeMs < 0 || n.slowModeMs > 864e5) || n.frozen !== void 0 && typeof n.frozen != "boolean") throw t("invalid_input");
694
+ let o = await e.update(c.tableName, P(i, "id"), {
695
+ slowModeMs: n.slowModeMs ?? i.slowModeMs,
696
+ frozen: n.frozen ?? F(i.frozen)
697
+ });
698
+ if (!o) throw t("unavailable");
699
+ return I(o);
700
+ });
701
+ }),
702
+ join: (e, n) => d.gen(function* () {
703
+ let r = yield* k(() => {
704
+ let t = j(e);
705
+ return A(n), t;
706
+ });
707
+ yield* _e(r, n);
708
+ let i = yield* Y, a = yield* O(async () => {
709
+ let e = await Z(() => H(w, r.tenantId, n));
710
+ return e.ok ? Z(() => X(i, r.tenantId, e.value, r.id)) : void 0;
711
+ });
712
+ return yield* O(() => K(r.tenantId, n, async (e, o) => {
713
+ if (o.kind !== "global" && fe(i, o) === void 0) throw t("forbidden");
714
+ if (Q(a), F(o.frozen)) throw t("frozen");
715
+ let s = V(r.tenantId, n, r.id), c = (await e.query(S(l).where(m("id", s)).limit(1).forUpdate().descriptor))[0];
716
+ if (c) {
717
+ if (c.tenantId !== r.tenantId || c.channelId !== n || c.subjectId !== r.id) throw t("unavailable");
718
+ return L(c);
719
+ }
720
+ let u = await e.query(S(l).where(p(m("tenantId", r.tenantId), m("channelId", n))).limit(Number(o.maxMembers) + 1).forUpdate().descriptor);
721
+ if (u.some((e) => e.tenantId !== r.tenantId || e.channelId !== n)) throw t("unavailable");
722
+ if (u.length >= Number(o.maxMembers)) throw t("member_limit");
723
+ return L(await e.insert(l.tableName, {
724
+ id: s,
725
+ tenantId: r.tenantId,
726
+ channelId: n,
727
+ subjectId: r.id,
728
+ role: "member",
729
+ mutedUntil: null,
730
+ lastReadAt: /* @__PURE__ */ new Date(0),
731
+ lastReadId: null,
732
+ lastSentAt: null,
733
+ notify: !0,
734
+ metadata: {}
735
+ }));
736
+ }, [r.id]));
737
+ }),
738
+ leave: (e, n) => O(async () => {
739
+ let r = j(e);
740
+ return K(r.tenantId, n, async (e, i) => {
741
+ if (i.kind === "dm") throw t("forbidden");
742
+ let a = (await e.query(S(l).where(m("id", V(r.tenantId, n, r.id))).limit(1).descriptor))[0];
743
+ if (a) {
744
+ if (a.tenantId !== r.tenantId || a.channelId !== n || a.subjectId !== r.id) throw t("unavailable");
745
+ if (a.role === "owner") throw t("forbidden");
746
+ await e.delete(l.tableName, P(a, "id"));
747
+ }
748
+ });
749
+ }),
750
+ transferOwnership: (e, n, r) => O(async () => {
751
+ let i = j(e);
752
+ return A(r), K(i.tenantId, n, async (e, a) => {
753
+ if (a.kind === "dm") throw t("forbidden");
754
+ let o = await U(e, i.tenantId, n, i.id);
755
+ if (o.role !== "owner") throw t("forbidden");
756
+ if (r === i.id) return;
757
+ let s = await U(e, i.tenantId, n, r), c = await e.query(S(l).where(p(m("tenantId", i.tenantId), m("channelId", n), m("role", "owner"))).limit(2).descriptor);
758
+ if (c.length !== 1 || c[0]?.subjectId !== i.id) throw t("conflict");
759
+ if (s.mutedUntil !== null && M(s.mutedUntil) > B()) throw t("muted");
760
+ await e.update(l.tableName, P(o, "id"), { role: "member" }), await e.update(l.tableName, P(s, "id"), { role: "owner" });
761
+ });
762
+ })
763
+ }, xe = (e, n, r) => {
764
+ if (A(n), e.type !== "system" && !(e.type === "serviceAccount" && e.tenantId === n && e.scopes?.includes(r))) throw t("identity_required");
765
+ }, Se = (e, n) => {
766
+ let i, a;
767
+ try {
768
+ if (i = structuredClone(j(e)), a = structuredClone(n), A(a.channelId), A(a.messageId), A(a.targetId), i.id === a.targetId) throw t("invalid_input");
769
+ } catch (e) {
770
+ return d.fail(D(e));
771
+ }
772
+ return O(() => {
773
+ let e = j(i);
774
+ return K(e.tenantId, a.channelId, async (n, i) => {
775
+ await U(n, e.tenantId, a.channelId, e.id);
776
+ let o = await W(n, e.tenantId, a.messageId), s = B(), c = $(i);
777
+ if (o.channelId !== a.channelId || o.authorId !== a.targetId || c !== null && M(o.createdAt) < s - c) throw t("forbidden");
778
+ let l = M(o.createdAt), d = p(m("tenantId", e.tenantId), m("channelId", a.channelId), ...c === null ? [] : [g("createdAt", new Date(Math.max(0, s - c)))]), f = await n.query(S(u).where(p(d, x(y("createdAt", new Date(l)), p(m("createdAt", new Date(l)), y("id", a.messageId))))).orderBy("createdAt", "desc").orderBy("id", "desc").limit(20).select("id", "tenantId", "channelId", "authorId", "kind", "body", "originalBody", "version", "createdAt", "editedAt", "deletedAt").descriptor), _ = await n.query(S(u).where(p(d, x(h("createdAt", new Date(l)), p(m("createdAt", new Date(l)), h("id", a.messageId))))).orderBy("createdAt", "asc").orderBy("id", "asc").limit(20).select("id", "tenantId", "channelId", "authorId", "kind", "body", "originalBody", "version", "createdAt", "editedAt", "deletedAt").descriptor), v = [
779
+ ...[...f].reverse(),
780
+ o,
781
+ ..._
782
+ ];
783
+ if (v.some((t) => t.tenantId !== e.tenantId || t.channelId !== a.channelId || !Number.isSafeInteger(t.version) || Number(t.version) < 0)) throw t("unavailable");
784
+ let b = await W(n, e.tenantId, a.messageId);
785
+ if (b.version !== o.version || b.authorId !== a.targetId) throw t("conflict");
786
+ let C = s + z.evidenceRetentionMs;
787
+ if (!Number.isSafeInteger(C) || C > 864e13) throw t("unavailable");
788
+ let w = [];
789
+ for (let i of v) {
790
+ let o = null;
791
+ if (i.authorId !== null) {
792
+ let c = P(i, "id"), l = P(i, "authorId"), u = await n.query(S(r).where(p(m("tenantId", e.tenantId), m("channelId", a.channelId), m("messageId", c), m("messageVersion", i.version), h("expiresAt", new Date(s)))).orderBy("id", "asc").limit(2).descriptor);
793
+ if (u.length > 1 || u.some((t) => t.tenantId !== e.tenantId || t.channelId !== a.channelId || t.messageId !== c || t.messageVersion !== i.version)) throw t("unavailable");
794
+ let d = u[0];
795
+ if (d) {
796
+ if (d.erasedAt === null && (d.authorId !== l || d.body !== i.body || d.originalBody !== i.originalBody)) throw t("unavailable");
797
+ o = P(d, "id");
798
+ } else o = "cevi_" + ee().replaceAll("-", ""), await n.insert(r.tableName, {
799
+ id: o,
800
+ tenantId: e.tenantId,
801
+ channelId: a.channelId,
802
+ messageId: c,
803
+ messageVersion: i.version,
804
+ kind: P(i, "kind"),
805
+ authorId: l,
806
+ body: P(i, "body"),
807
+ originalBody: P(i, "originalBody"),
808
+ messageCreatedAt: i.createdAt,
809
+ messageEditedAt: i.editedAt,
810
+ messageDeletedAt: i.deletedAt,
811
+ capturedAt: new Date(s),
812
+ expiresAt: new Date(C),
813
+ erasedAt: null
814
+ });
815
+ }
816
+ w.push({
817
+ evidenceId: o,
818
+ messageId: P(i, "id"),
819
+ version: Number(i.version),
820
+ createdAt: M(i.createdAt),
821
+ deletedAt: N(i.deletedAt)
822
+ });
823
+ }
824
+ return {
825
+ kind: "chat.context",
826
+ channelId: a.channelId,
827
+ anchorMessageId: a.messageId,
828
+ observedAt: s,
829
+ messages: w
830
+ };
831
+ });
832
+ });
833
+ }, Ce = (e, n) => {
834
+ let i, a;
835
+ try {
836
+ if (i = structuredClone(e), a = structuredClone(n), A(a.tenantId), i.type !== "system" && (i.type !== "user" && i.type !== "serviceAccount" || i.tenantId !== a.tenantId || !i.scopes?.includes("sanctions:manage") && !i.scopes?.includes("admin:full"))) throw t("forbidden");
837
+ if (!Array.isArray(a.evidenceIds) || a.evidenceIds.length > 41 || new Set(a.evidenceIds).size !== a.evidenceIds.length) throw t("invalid_input");
838
+ a.evidenceIds.forEach(A);
839
+ } catch (e) {
840
+ return d.fail(D(e));
841
+ }
842
+ return O(async () => {
843
+ if (!a.evidenceIds.length) return [];
844
+ let e = await w.query(S(r).where(p(m("tenantId", a.tenantId), _("id", a.evidenceIds))).limit(42).descriptor);
845
+ if (e.length > 41 || e.some((e) => e.tenantId !== a.tenantId || !a.evidenceIds.includes(P(e, "id")))) throw t("unavailable");
846
+ return e.filter((e) => M(e.expiresAt) > B()).map((e) => ({
847
+ id: P(e, "id"),
848
+ channelId: P(e, "channelId"),
849
+ messageId: P(e, "messageId"),
850
+ messageVersion: Number(e.messageVersion),
851
+ kind: P(e, "kind"),
852
+ authorId: e.erasedAt === null ? P(e, "authorId") : null,
853
+ body: e.erasedAt === null ? P(e, "body") : null,
854
+ originalBody: e.erasedAt === null ? P(e, "originalBody") : null,
855
+ createdAt: M(e.messageCreatedAt),
856
+ editedAt: N(e.messageEditedAt),
857
+ deletedAt: N(e.messageDeletedAt),
858
+ capturedAt: M(e.capturedAt),
859
+ expiresAt: M(e.expiresAt),
860
+ erasedAt: N(e.erasedAt)
861
+ }));
862
+ });
863
+ }, we = (e) => {
864
+ let n;
865
+ try {
866
+ let r = structuredClone(e);
867
+ if (r.type === "system") n = null;
868
+ else if (r.type === "serviceAccount" && r.scopes?.includes("chat:retention:write")) A(r.tenantId), n = r.tenantId;
869
+ else throw t("identity_required");
870
+ } catch (e) {
871
+ return d.fail(D(e));
872
+ }
873
+ return O(async () => {
874
+ let e = "cret_" + E(["chat.retention", n]).slice(0, 56), i = S(o).where(m("id", e)).limit(1).descriptor;
875
+ if (!(await w.query(i))[0]) try {
876
+ await w.insert(o.tableName, {
877
+ id: e,
878
+ tenantId: n,
879
+ afterChannelId: null,
880
+ admission: 0,
881
+ updatedAt: new Date(B())
882
+ });
883
+ } catch (e) {
884
+ let t = (await w.query(i))[0];
885
+ if (!t || t.tenantId !== n) throw e;
886
+ }
887
+ return w.transactional(async (s) => {
888
+ if (await s.updateMany(o.tableName, { admission: 0 }, { where: m("id", e) }) !== 1) throw t("unavailable");
889
+ let l = (await s.query(i))[0];
890
+ if (!l || l.tenantId !== n || l.afterChannelId !== null && typeof l.afterChannelId != "string") throw t("unavailable");
891
+ let d = await s.query(S(c).where(p(h("id", ""), ...n === null ? [] : [m("tenantId", n)], ...l.afterChannelId === null ? [] : [h("id", l.afterChannelId)])).orderBy("id", "asc").limit(2).select("id", "tenantId").descriptor);
892
+ if (d.some((e) => typeof e.tenantId != "string" || n !== null && e.tenantId !== n)) throw t("unavailable");
893
+ let f = d[0];
894
+ if (!f) return await s.update(o.tableName, e, {
895
+ afterChannelId: null,
896
+ updatedAt: new Date(B())
897
+ }), {
898
+ deleted: 0,
899
+ evidenceDeleted: 0,
900
+ channelId: null,
901
+ remainingInChannel: !1,
902
+ evidenceRemainingInChannel: !1,
903
+ cycleComplete: !0
904
+ };
905
+ let g = P(f, "id"), v = P(f, "tenantId");
906
+ if (A(v), await s.updateMany(c.tableName, { admission: 0 }, { where: m("id", g) }) !== 1) throw t("unavailable");
907
+ let x = await H(s, v, g), C = $(x), w = 0, ee = !1;
908
+ if (C !== null) {
909
+ let e = new Date(Math.max(0, B() - C)), n = await s.query(S(u).where(p(m("tenantId", v), m("channelId", g), y("createdAt", e))).orderBy("createdAt", "asc").orderBy("id", "asc").limit(201).select("id", "tenantId", "channelId").descriptor);
910
+ if (n.some((e) => e.tenantId !== v || e.channelId !== g || typeof e.id != "string")) throw t("unavailable");
911
+ ee = n.length > 200;
912
+ let r = n.slice(0, 200);
913
+ if (r.length && (w = await s.deleteMany(u.tableName, { where: p(m("tenantId", v), m("channelId", g), y("createdAt", e), _("id", r.map((e) => P(e, "id")))) })), !Number.isSafeInteger(w) || w < 0 || w > r.length) throw t("unavailable");
914
+ r.length && await s.updateMany(a.tableName, {
915
+ state: "deleting",
916
+ ownerId: null
917
+ }, { where: p(m("tenantId", v), m("channelId", g), _("messageId", r.map((e) => P(e, "id")))) });
918
+ }
919
+ let te = await s.query(S(r).where(p(m("tenantId", v), m("channelId", g), b("expiresAt", new Date(B())))).orderBy("expiresAt", "asc").orderBy("id", "asc").limit(201).select("id", "tenantId", "channelId").descriptor);
920
+ if (te.some((e) => e.tenantId !== v || e.channelId !== g || typeof e.id != "string")) throw t("unavailable");
921
+ let ne = te.slice(0, 200), T = ne.length ? await s.deleteMany(r.tableName, { where: p(m("tenantId", v), m("channelId", g), b("expiresAt", new Date(B())), _("id", ne.map((e) => P(e, "id")))) }) : 0;
922
+ if (!Number.isSafeInteger(T) || T < 0 || T > ne.length) throw t("unavailable");
923
+ let re = d.length < 2;
924
+ return await s.update(o.tableName, e, {
925
+ afterChannelId: re ? null : g,
926
+ updatedAt: new Date(B())
927
+ }), {
928
+ deleted: w,
929
+ evidenceDeleted: T,
930
+ channelId: g,
931
+ remainingInChannel: ee,
932
+ evidenceRemainingInChannel: te.length > 200,
933
+ cycleComplete: re
934
+ };
935
+ });
936
+ });
937
+ }, Te = (e) => {
938
+ let n;
939
+ try {
940
+ let r = structuredClone(e);
941
+ if (r.type === "system") n = null;
942
+ else if (r.type === "serviceAccount" && r.scopes?.includes("chat:retention:write")) A(r.tenantId), n = r.tenantId;
943
+ else throw t("identity_required");
944
+ } catch (e) {
945
+ return d.fail(D(e));
946
+ }
947
+ let r = n;
948
+ return d.gen(function* () {
949
+ let e = yield* de, n = yield* O(() => w.query(S(a).where(p(m("state", "deleting"), ...r === null ? [] : [m("tenantId", r)])).orderBy("id", "asc").limit(51).descriptor));
950
+ if (n.some((e) => e.state !== "deleting" || typeof e.tenantId != "string" || r !== null && e.tenantId !== r)) return yield* d.fail(t("unavailable"));
951
+ let i = n.slice(0, 50);
952
+ if (i.length > 0 && !e) return yield* d.fail(t("unavailable"));
953
+ let o = 0, s = 0;
954
+ for (let n of i) {
955
+ let r = P(n, "tenantId"), i = P(n, "storageId");
956
+ if ((yield* O(() => w.query(S(a).where(p(m("tenantId", r), m("storageId", i), m("state", "active"))).limit(1).descriptor))).length === 0) {
957
+ let n = yield* d.result(d.suspend(() => e.delete(i, { tenantId: r })).pipe(d.catchDefect(() => d.fail(t("unavailable")))));
958
+ if (f.isFailure(n) && !("status" in n.failure && n.failure.status === 404)) {
959
+ s++;
960
+ continue;
961
+ }
962
+ }
963
+ yield* O(() => w.delete(a.tableName, P(n, "id"))), o++;
964
+ }
965
+ return {
966
+ removed: o,
967
+ failed: s,
968
+ remaining: n.length > 50
969
+ };
970
+ });
971
+ }, Ee = (t, n) => {
972
+ let r, i;
973
+ try {
974
+ r = structuredClone(t), i = structuredClone(n), xe(r, i.tenantId, "chat:notifications:send"), A(i.channelId), A(i.messageId), A(i.recipientId);
975
+ } catch (e) {
976
+ return d.fail(D(e));
977
+ }
978
+ return d.gen(function* () {
979
+ let t = yield* J;
980
+ return yield* O(async () => {
981
+ try {
982
+ let e = await H(w, i.tenantId, i.channelId), n = await W(w, i.tenantId, i.messageId);
983
+ if (n.channelId !== i.channelId || n.deletedAt !== null || typeof n.authorId != "string" || n.authorId === i.recipientId) return !1;
984
+ let r = $(e);
985
+ if (r !== null && M(n.createdAt) < B() - r) return !1;
986
+ let a = n.payload, o = a && typeof a == "object" && !Array.isArray(a) ? a.mentions : void 0;
987
+ if (!Array.isArray(o) || o.length > z.maxMentions || !o.includes(i.recipientId) || !F((await U(w, i.tenantId, i.channelId, i.recipientId)).notify)) return !1;
988
+ await U(w, i.tenantId, i.channelId, n.authorId);
989
+ let s = {
990
+ type: "user",
991
+ id: i.recipientId,
992
+ tenantId: i.tenantId
993
+ };
994
+ if (await q(t, s, n.authorId)) return !1;
995
+ let c = await W(w, i.tenantId, i.messageId);
996
+ if (c.version !== n.version || c.deletedAt !== null || c.authorId !== n.authorId) return !1;
997
+ await U(w, i.tenantId, i.channelId, n.authorId);
998
+ let l = $(await H(w, i.tenantId, i.channelId));
999
+ return l !== null && M(c.createdAt) < B() - l ? !1 : F((await U(w, i.tenantId, i.channelId, i.recipientId)).notify);
1000
+ } catch (t) {
1001
+ if (t instanceof e && (t.code === "not_found" || t.code === "forbidden")) return !1;
1002
+ throw t;
1003
+ }
1004
+ });
1005
+ });
1006
+ }, De = (n, r) => {
1007
+ let i, a;
1008
+ try {
1009
+ i = structuredClone(n), a = structuredClone(r);
1010
+ } catch {
1011
+ return d.fail(t("invalid_input"));
1012
+ }
1013
+ return O(async () => {
1014
+ if (i.type !== "system" && !(i.type === "serviceAccount" && i.tenantId === a.tenantId && i.scopes?.includes("chat:channels:write"))) throw t("identity_required");
1015
+ if (A(a.tenantId), A(a.refId), typeof a.name != "string" || a.name.length > 256 || a.name.includes("\0") || a.kind !== "dm" && !a.name.trim() || ![
1016
+ "global",
1017
+ "lobby",
1018
+ "party",
1019
+ "guild",
1020
+ "match",
1021
+ "dm",
1022
+ "custom"
1023
+ ].includes(a.kind) || a.members.length === 0 && ![
1024
+ "global",
1025
+ "guild",
1026
+ "party"
1027
+ ].includes(a.kind) || a.members.length > (a.maxMembers ?? z.maxMembers) || !Number.isSafeInteger(a.maxMembers ?? z.maxMembers) || (a.maxMembers ?? z.maxMembers) < 1 || (a.maxMembers ?? z.maxMembers) > z.maxMembers || a.kind === "dm" && a.members.length !== 2 || new Set(a.members.map((e) => e.subjectId)).size !== a.members.length) throw t("invalid_input");
1028
+ a.members.forEach((e) => {
1029
+ if (A(e.subjectId), ![
1030
+ "owner",
1031
+ "mod",
1032
+ "member"
1033
+ ].includes(e.role)) throw t("invalid_input");
1034
+ });
1035
+ let n = a.slowModeMs ?? 0, r = a.retentionMs === void 0 ? z.retentionMs : a.retentionMs;
1036
+ if (!Number.isSafeInteger(n) || n < 0 || n > 864e5 || r !== null && (!Number.isSafeInteger(r) || r < 1 || r > 31536e7)) throw t("invalid_input");
1037
+ let o = "cchan_" + E([
1038
+ a.tenantId,
1039
+ a.kind,
1040
+ a.refId
1041
+ ]).slice(0, 56), s = E([
1042
+ a.tenantId,
1043
+ a.kind,
1044
+ a.refId,
1045
+ a.name,
1046
+ [...a.members].sort((e, t) => e.subjectId < t.subjectId ? -1 : +(e.subjectId > t.subjectId)),
1047
+ n,
1048
+ r,
1049
+ a.maxMembers ?? z.maxMembers
1050
+ ]), u = a.members.map((e) => e.subjectId);
1051
+ await se(a.tenantId, u);
1052
+ try {
1053
+ return await w.transactional(async (e) => {
1054
+ await ue(e, a.tenantId, u);
1055
+ let t = B(), i = await e.insert(c.tableName, {
1056
+ id: o,
1057
+ tenantId: a.tenantId,
1058
+ kind: a.kind,
1059
+ refId: a.refId,
1060
+ name: a.name,
1061
+ slowModeMs: n,
1062
+ retentionMs: r,
1063
+ maxMembers: a.maxMembers ?? z.maxMembers,
1064
+ frozen: !1,
1065
+ createdAt: new Date(t),
1066
+ admission: 0,
1067
+ creationKey: s,
1068
+ metadata: {}
1069
+ });
1070
+ for (let t of a.members) await e.insert(l.tableName, {
1071
+ id: V(a.tenantId, o, t.subjectId),
1072
+ tenantId: a.tenantId,
1073
+ channelId: o,
1074
+ subjectId: t.subjectId,
1075
+ role: t.role,
1076
+ mutedUntil: null,
1077
+ lastReadAt: /* @__PURE__ */ new Date(0),
1078
+ lastReadId: null,
1079
+ lastSentAt: null,
1080
+ notify: !0,
1081
+ metadata: {}
1082
+ });
1083
+ return I(i);
1084
+ });
1085
+ } catch (n) {
1086
+ if (n instanceof e) throw n;
1087
+ await ce(w, a.tenantId, u);
1088
+ let r = (await w.query(S(c).where(m("id", o)).limit(1).descriptor))[0];
1089
+ if (!r) throw n;
1090
+ if (r.tenantId !== a.tenantId || r.kind !== a.kind || r.refId !== a.refId || r.creationKey !== s) throw t("conflict");
1091
+ return I(r);
1092
+ }
1093
+ });
1094
+ }, Oe = (e, n) => {
1095
+ let r, i;
1096
+ try {
1097
+ r = structuredClone(n), i = structuredClone(e);
1098
+ } catch {
1099
+ return d.fail(t("invalid_input"));
1100
+ }
1101
+ return O(async () => {
1102
+ if (xe(i, r.tenantId, "chat:members:write"), A(r.subjectId), r.role !== "member" && r.role !== "mod") throw t("invalid_input");
1103
+ return K(r.tenantId, r.channelId, async (e, n) => {
1104
+ if (n.kind === "dm" || n.kind === "match") throw t("forbidden");
1105
+ if (F(n.frozen)) throw t("frozen");
1106
+ let i = V(r.tenantId, r.channelId, r.subjectId), a = (await e.query(S(l).where(m("id", i)).limit(1).forUpdate().descriptor))[0];
1107
+ if (a) {
1108
+ if (a.tenantId !== r.tenantId || a.channelId !== r.channelId || a.subjectId !== r.subjectId) throw t("unavailable");
1109
+ if (a.role !== r.role) throw t("conflict");
1110
+ return L(a);
1111
+ }
1112
+ let o = await e.query(S(l).where(p(m("tenantId", r.tenantId), m("channelId", r.channelId))).limit(Number(n.maxMembers) + 1).forUpdate().descriptor);
1113
+ if (o.some((e) => e.tenantId !== r.tenantId || e.channelId !== r.channelId)) throw t("unavailable");
1114
+ if (o.length >= Number(n.maxMembers)) throw t("member_limit");
1115
+ return L(await e.insert(l.tableName, {
1116
+ id: i,
1117
+ tenantId: r.tenantId,
1118
+ channelId: r.channelId,
1119
+ subjectId: r.subjectId,
1120
+ role: r.role,
1121
+ mutedUntil: null,
1122
+ lastReadAt: /* @__PURE__ */ new Date(0),
1123
+ lastReadId: null,
1124
+ lastSentAt: null,
1125
+ notify: !0,
1126
+ metadata: {}
1127
+ }));
1128
+ }, [r.subjectId]);
1129
+ });
1130
+ }, ke = (e, n) => {
1131
+ let r, i;
1132
+ try {
1133
+ r = structuredClone(n), i = structuredClone(e);
1134
+ } catch {
1135
+ return d.fail(t("invalid_input"));
1136
+ }
1137
+ return O(async () => (xe(i, r.tenantId, "chat:members:write"), A(r.subjectId), K(r.tenantId, r.channelId, async (e, n) => {
1138
+ if (n.kind === "dm") throw t("forbidden");
1139
+ let i = (await e.query(S(l).where(m("id", V(r.tenantId, r.channelId, r.subjectId))).limit(1).descriptor))[0];
1140
+ if (i) {
1141
+ if (i.tenantId !== r.tenantId || i.channelId !== r.channelId || i.subjectId !== r.subjectId) throw t("unavailable");
1142
+ if (i.role === "owner") throw t("forbidden");
1143
+ await e.delete(l.tableName, P(i, "id"));
1144
+ }
1145
+ })));
1146
+ }, Ae = (n, r) => {
1147
+ let i, a;
1148
+ try {
1149
+ if (i = structuredClone(n), a = structuredClone(r), xe(i, a.tenantId, "chat:archive:write"), A(a.matchId), typeof a.name != "string" || !a.name.trim() || a.name.length > 256 || a.name.includes("\0") || !Array.isArray(a.members) || a.members.length < 1 || a.members.length > z.maxMembers || !Array.isArray(a.messages) || a.messages.length > z.maxExportRows) throw t("invalid_input");
1150
+ let e = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Set();
1151
+ for (let n of a.members) {
1152
+ if (A(n.subjectId), e.has(n.subjectId) || ![
1153
+ "member",
1154
+ "mod",
1155
+ "owner"
1156
+ ].includes(n.role)) throw t("invalid_input");
1157
+ e.add(n.subjectId);
1158
+ }
1159
+ let s = B();
1160
+ for (let n of a.messages) {
1161
+ if (A(n.id), A(n.authorId), oe(n.body), o.has(n.id) || !e.has(n.authorId) || !Number.isSafeInteger(n.at) || n.at < 0 || n.at > s) throw t("invalid_input");
1162
+ o.add(n.id);
1163
+ }
1164
+ if (a.retentionMs !== void 0 && a.retentionMs !== null && (!Number.isSafeInteger(a.retentionMs) || a.retentionMs < 1 || a.retentionMs > 31536e7)) throw t("invalid_input");
1165
+ } catch (e) {
1166
+ return d.fail(D(e));
1167
+ }
1168
+ let o = a;
1169
+ return d.gen(function* () {
1170
+ let n = o.tenantId, r = "cchan_" + E([
1171
+ n,
1172
+ "match",
1173
+ o.matchId
1174
+ ]).slice(0, 56), i = o.retentionMs === void 0 ? z.retentionMs : o.retentionMs, a = o.members.map((e) => ({
1175
+ subjectId: e.subjectId,
1176
+ role: e.role
1177
+ })).sort((e, t) => e.subjectId < t.subjectId ? -1 : +(e.subjectId > t.subjectId)), s = o.messages.map((e) => ({
1178
+ id: e.id,
1179
+ authorId: e.authorId,
1180
+ body: e.body,
1181
+ at: e.at
1182
+ })).sort((e, t) => e.id < t.id ? -1 : +(e.id > t.id)), d = E([
1183
+ "chat:archive:1",
1184
+ n,
1185
+ o.matchId,
1186
+ o.name,
1187
+ a,
1188
+ s,
1189
+ i
1190
+ ]), f = async () => {
1191
+ await ce(w, n, a.map((e) => e.subjectId));
1192
+ let e = (await w.query(S(c).where(m("id", r)).limit(1).descriptor))[0];
1193
+ if (!e) return null;
1194
+ if (e.tenantId !== n || e.kind !== "match" || e.refId !== o.matchId || e.creationKey !== d) throw t("conflict");
1195
+ for (let e of s) {
1196
+ let i = "cmsg_" + E([
1197
+ n,
1198
+ r,
1199
+ "archive",
1200
+ e.id
1201
+ ]).slice(0, 56), a = (await w.query(S(u).where(m("id", i)).limit(1).descriptor))[0];
1202
+ if (!a || a.tenantId !== n || a.channelId !== r || a.authorId !== e.authorId || a.requestKey !== E([d, e.id])) throw t("conflict");
1203
+ }
1204
+ return I(e);
1205
+ }, p = yield* O(f);
1206
+ if (p !== null) return p;
1207
+ let h = [];
1208
+ for (let e of s) h.push(yield* ve(e.body));
1209
+ return yield* O(async () => {
1210
+ let t = s.map((e, t) => ({
1211
+ entry: e,
1212
+ moderated: h[t]
1213
+ }));
1214
+ await se(n, a.map((e) => e.subjectId));
1215
+ try {
1216
+ return await w.transactional(async (e) => {
1217
+ await ue(e, n, a.map((e) => e.subjectId));
1218
+ let s = await e.insert(c.tableName, {
1219
+ id: r,
1220
+ tenantId: n,
1221
+ kind: "match",
1222
+ refId: o.matchId,
1223
+ name: o.name,
1224
+ slowModeMs: 0,
1225
+ retentionMs: i,
1226
+ maxMembers: a.length,
1227
+ frozen: !0,
1228
+ createdAt: new Date(B()),
1229
+ admission: 0,
1230
+ creationKey: d,
1231
+ metadata: {}
1232
+ });
1233
+ for (let t of a) await e.insert(l.tableName, {
1234
+ id: V(n, r, t.subjectId),
1235
+ tenantId: n,
1236
+ channelId: r,
1237
+ subjectId: t.subjectId,
1238
+ role: t.role,
1239
+ mutedUntil: null,
1240
+ lastReadAt: /* @__PURE__ */ new Date(0),
1241
+ lastReadId: null,
1242
+ lastSentAt: null,
1243
+ notify: !0,
1244
+ metadata: {}
1245
+ });
1246
+ for (let { entry: i, moderated: a } of t) await e.insert(u.tableName, {
1247
+ id: "cmsg_" + E([
1248
+ n,
1249
+ r,
1250
+ "archive",
1251
+ i.id
1252
+ ]).slice(0, 56),
1253
+ tenantId: n,
1254
+ channelId: r,
1255
+ authorId: i.authorId,
1256
+ requestKey: E([d, i.id]),
1257
+ kind: "text",
1258
+ body: a.body,
1259
+ originalBody: a.body,
1260
+ payload: {},
1261
+ replyToId: null,
1262
+ editedAt: null,
1263
+ deletedAt: null,
1264
+ flagged: a.flagged,
1265
+ createdAt: new Date(i.at),
1266
+ version: 0,
1267
+ metadata: {}
1268
+ });
1269
+ return I(s);
1270
+ });
1271
+ } catch (t) {
1272
+ if (t instanceof e) throw t;
1273
+ let n = await f();
1274
+ if (n === null) throw t;
1275
+ return n;
1276
+ }
1277
+ });
1278
+ });
1279
+ }, je = async (e, i) => {
1280
+ if (i.tenantId === null) throw t("identity_required");
1281
+ A(i.tenantId), A(i.subjectId);
1282
+ let o = await e.query(S(l).where(p(m("tenantId", i.tenantId), m("subjectId", i.subjectId))).orderBy("id", "asc").limit(z.maxExportRows + 1).descriptor), s = await e.query(S(u).where(p(m("tenantId", i.tenantId), m("authorId", i.subjectId))).orderBy("id", "asc").limit(z.maxExportRows + 1).descriptor), c = await e.query(S(r).where(p(m("tenantId", i.tenantId), m("authorId", i.subjectId))).orderBy("id", "asc").limit(z.maxExportRows + 1).descriptor), d = await e.query(S(a).where(p(m("tenantId", i.tenantId), m("ownerId", i.subjectId))).orderBy("id", "asc").limit(z.maxExportRows + 1).descriptor), f = /* @__PURE__ */ new Map();
1283
+ for (let t = 0; t < 100; t += 20) for (let n of await e.query(S(u).where(p(m("tenantId", i.tenantId), x(...Array.from({ length: 20 }, (e, n) => v("payload", "mentions", t + n).eq(i.subjectId))))).orderBy("id", "asc").limit(z.maxExportRows + 1).descriptor)) f.set(P(n, "id"), n);
1284
+ let h = [...f.values()].sort((e, t) => P(e, "id") < P(t, "id") ? -1 : 1);
1285
+ if (h.length > z.maxExportRows || h.some((e) => e.tenantId !== i.tenantId)) throw t("export_limit");
1286
+ let g = h.filter((e) => e.authorId !== i.subjectId && e.payload && typeof e.payload == "object" && Array.isArray(e.payload.mentions) && e.payload.mentions.includes(i.subjectId)), _ = (await e.query(S(n).where(m("id", G(i.tenantId, i.subjectId))).limit(1).descriptor))[0] ?? null;
1287
+ if (_ && (_.tenantId !== i.tenantId || !F(_.erased) && _.subjectId !== i.subjectId)) throw t("unavailable");
1288
+ let y = _ === null ? 0 : 1;
1289
+ if (o.length + s.length + c.length + g.length + d.length + y > z.maxExportRows) throw t("export_limit");
1290
+ if (o.some((e) => e.tenantId !== i.tenantId || e.subjectId !== i.subjectId) || s.some((e) => e.tenantId !== i.tenantId || e.authorId !== i.subjectId) || c.some((e) => e.tenantId !== i.tenantId || e.authorId !== i.subjectId) || d.some((e) => e.tenantId !== i.tenantId || e.ownerId !== i.subjectId)) throw t("unavailable");
1291
+ let b = new Set(o.filter((e) => e.role === "owner").map((e) => P(e, "channelId"))), C = [];
1292
+ for (let t of b) C.push(await H(e, i.tenantId, t));
1293
+ if (o.length + s.length + c.length + g.length + d.length + C.length + y > z.maxExportRows) throw t("export_limit");
1294
+ return {
1295
+ memberships: o,
1296
+ authored: s,
1297
+ ownedChannels: C,
1298
+ evidence: c,
1299
+ mentioned: g,
1300
+ media: d,
1301
+ admission: _
1302
+ };
1303
+ };
1304
+ return {
1305
+ service: be,
1306
+ typingPolicy: ye.policy,
1307
+ disposeTyping: ye.close,
1308
+ readReportEvidence: Ce,
1309
+ collectReportContext: Se,
1310
+ prune: we,
1311
+ sweepMedia: Te,
1312
+ canNotifyMention: Ee,
1313
+ createChannel: De,
1314
+ addMember: Oe,
1315
+ removeMember: ke,
1316
+ archiveMatch: Ae,
1317
+ exportSubject: (e) => O(() => w.transactional(async (t) => {
1318
+ let n = await je(t, e);
1319
+ return JSON.parse(JSON.stringify({
1320
+ memberships: n.memberships,
1321
+ messages: n.authored,
1322
+ evidence: n.evidence,
1323
+ media: n.media,
1324
+ admission: n.admission === null ? null : (({ admission: e, ...t }) => t)(n.admission),
1325
+ channels: n.ownedChannels.map(({ admission: e, ...t }) => t)
1326
+ }));
1327
+ })),
1328
+ eraseSubject: (e) => {
1329
+ let o;
1330
+ try {
1331
+ o = structuredClone(e);
1332
+ } catch {
1333
+ return d.fail(t("invalid_input"));
1334
+ }
1335
+ return O(async () => {
1336
+ if (o.tenantId === null) throw t("identity_required");
1337
+ A(o.subjectId), A(o.tenantId), await se(o.tenantId, [o.subjectId]);
1338
+ let e = Symbol("chat-erasure-channel-set-changed"), s = (e) => [.../* @__PURE__ */ new Set([
1339
+ ...e.memberships.map((e) => P(e, "channelId")),
1340
+ ...e.authored.map((e) => P(e, "channelId")),
1341
+ ...e.evidence.map((e) => P(e, "channelId")),
1342
+ ...e.mentioned.map((e) => P(e, "channelId")),
1343
+ ...e.media.map((e) => P(e, "channelId")),
1344
+ ...e.ownedChannels.map((e) => P(e, "id"))
1345
+ ])].sort();
1346
+ for (let d = 0; d < 4; d++) {
1347
+ let d = s(await je(w, o));
1348
+ try {
1349
+ await w.transactional(async (f) => {
1350
+ await le(f, o.tenantId, [o.subjectId]);
1351
+ let p = [];
1352
+ for (let e of d) {
1353
+ let n = await f.updateMany(c.tableName, { admission: 0 }, { where: m("id", e) });
1354
+ if (n > 1) throw t("unavailable");
1355
+ n === 1 && p.push(e);
1356
+ }
1357
+ await ce(f, o.tenantId, [o.subjectId], !0);
1358
+ for (let e of p) await H(f, o.tenantId, e);
1359
+ let h = await je(f, o);
1360
+ if (s(h).some((e) => !d.includes(e))) throw e;
1361
+ for (let e of h.authored) await f.update(u.tableName, P(e, "id"), {
1362
+ authorId: null,
1363
+ requestKey: "",
1364
+ body: "",
1365
+ originalBody: "",
1366
+ payload: {},
1367
+ metadata: {},
1368
+ deletedAt: new Date(B()),
1369
+ version: Math.min(Number(e.version) + 1, i)
1370
+ });
1371
+ for (let e of h.evidence) await f.update(r.tableName, P(e, "id"), {
1372
+ authorId: null,
1373
+ body: "",
1374
+ originalBody: "",
1375
+ erasedAt: new Date(B())
1376
+ });
1377
+ for (let e of h.mentioned) {
1378
+ let t = e.payload;
1379
+ await f.update(u.tableName, P(e, "id"), {
1380
+ payload: {
1381
+ ...t,
1382
+ mentions: t.mentions.filter((e) => e !== o.subjectId)
1383
+ },
1384
+ version: Math.min(Number(e.version) + 1, i)
1385
+ });
1386
+ }
1387
+ for (let e of h.media) await f.update(a.tableName, P(e, "id"), {
1388
+ ownerId: null,
1389
+ state: "deleting"
1390
+ });
1391
+ for (let e of h.memberships) await f.delete(l.tableName, P(e, "id"));
1392
+ for (let e of h.ownedChannels) await f.update(c.tableName, P(e, "id"), {
1393
+ metadata: {},
1394
+ name: ""
1395
+ });
1396
+ await f.update(n.tableName, G(o.tenantId, o.subjectId), {
1397
+ subjectId: null,
1398
+ erased: !0
1399
+ });
1400
+ });
1401
+ return;
1402
+ } catch (t) {
1403
+ if (t !== e) throw t;
1404
+ }
1405
+ }
1406
+ throw t("unavailable");
1407
+ });
1408
+ }
1409
+ };
1410
+ };
1411
+ export { z as dataStoreChat };