@arken/node 1.5.1 → 1.5.2

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 (148) hide show
  1. package/db.ts +76 -1
  2. package/index.ts +351 -18
  3. package/package.json +3 -3
  4. package/tsconfig.json +33 -2
  5. package/util.ts +1 -0
  6. package/modules/area/area.models.ts +0 -15
  7. package/modules/area/area.router.ts +0 -74
  8. package/modules/area/area.schema.ts +0 -22
  9. package/modules/area/area.service.ts +0 -124
  10. package/modules/area/area.types.ts +0 -26
  11. package/modules/area/index.ts +0 -5
  12. package/modules/asset/asset.models.ts +0 -59
  13. package/modules/asset/asset.router.ts +0 -55
  14. package/modules/asset/asset.schema.ts +0 -27
  15. package/modules/asset/asset.service.ts +0 -85
  16. package/modules/asset/asset.types.ts +0 -22
  17. package/modules/asset/index.ts +0 -5
  18. package/modules/chain/chain.models.ts +0 -50
  19. package/modules/chain/chain.router.ts +0 -104
  20. package/modules/chain/chain.schema.ts +0 -52
  21. package/modules/chain/chain.service.ts +0 -167
  22. package/modules/chain/chain.types.ts +0 -24
  23. package/modules/chain/index.ts +0 -5
  24. package/modules/character/character.models.ts +0 -174
  25. package/modules/character/character.router.ts +0 -314
  26. package/modules/character/character.schema.ts +0 -147
  27. package/modules/character/character.service.ts +0 -876
  28. package/modules/character/character.types.ts +0 -64
  29. package/modules/character/index.ts +0 -5
  30. package/modules/chat/chat.models.ts +0 -43
  31. package/modules/chat/chat.router.ts +0 -67
  32. package/modules/chat/chat.schema.ts +0 -36
  33. package/modules/chat/chat.service.ts +0 -128
  34. package/modules/chat/chat.types.ts +0 -20
  35. package/modules/chat/index.ts +0 -5
  36. package/modules/collection/collection.models.ts +0 -76
  37. package/modules/collection/collection.router.ts +0 -91
  38. package/modules/collection/collection.schema.ts +0 -90
  39. package/modules/collection/collection.service.ts +0 -192
  40. package/modules/collection/collection.types.ts +0 -36
  41. package/modules/collection/index.ts +0 -5
  42. package/modules/core/core.models.ts +0 -1380
  43. package/modules/core/core.router.ts +0 -1781
  44. package/modules/core/core.schema.ts +0 -847
  45. package/modules/core/core.service.ts +0 -2824
  46. package/modules/core/core.types.ts +0 -340
  47. package/modules/core/index.ts +0 -5
  48. package/modules/core/mail/applyPatchesOrMail.ts +0 -568
  49. package/modules/core/mail/mailClaimablePatchesBatch.ts +0 -381
  50. package/modules/game/game.models.ts +0 -53
  51. package/modules/game/game.router.ts +0 -110
  52. package/modules/game/game.schema.ts +0 -23
  53. package/modules/game/game.service.ts +0 -143
  54. package/modules/game/game.types.ts +0 -28
  55. package/modules/game/index.ts +0 -5
  56. package/modules/interface/index.ts +0 -5
  57. package/modules/interface/interface.canonicalize.ts +0 -279
  58. package/modules/interface/interface.models.ts +0 -40
  59. package/modules/interface/interface.router.ts +0 -175
  60. package/modules/interface/interface.schema.ts +0 -59
  61. package/modules/interface/interface.service.ts +0 -356
  62. package/modules/interface/interface.types.ts +0 -25
  63. package/modules/item/index.ts +0 -5
  64. package/modules/item/item.models.ts +0 -124
  65. package/modules/item/item.router.ts +0 -103
  66. package/modules/item/item.schema.ts +0 -120
  67. package/modules/item/item.service.ts +0 -167
  68. package/modules/item/item.types.ts +0 -74
  69. package/modules/job/index.ts +0 -5
  70. package/modules/job/job.models.ts +0 -14
  71. package/modules/job/job.router.ts +0 -44
  72. package/modules/job/job.schema.ts +0 -9
  73. package/modules/job/job.service.ts +0 -243
  74. package/modules/job/job.types.ts +0 -23
  75. package/modules/market/index.ts +0 -5
  76. package/modules/market/market.models.ts +0 -113
  77. package/modules/market/market.router.ts +0 -73
  78. package/modules/market/market.schema.ts +0 -140
  79. package/modules/market/market.service.ts +0 -122
  80. package/modules/market/market.types.ts +0 -56
  81. package/modules/product/index.ts +0 -5
  82. package/modules/product/product.models.ts +0 -166
  83. package/modules/product/product.router.ts +0 -93
  84. package/modules/product/product.schema.ts +0 -149
  85. package/modules/product/product.service.ts +0 -160
  86. package/modules/product/product.types.ts +0 -33
  87. package/modules/profile/index.ts +0 -5
  88. package/modules/profile/profile.models.ts +0 -214
  89. package/modules/profile/profile.router.ts +0 -72
  90. package/modules/profile/profile.schema.ts +0 -156
  91. package/modules/profile/profile.service.ts +0 -149
  92. package/modules/profile/profile.types.ts +0 -22
  93. package/modules/raffle/index.ts +0 -5
  94. package/modules/raffle/raffle.models.ts +0 -44
  95. package/modules/raffle/raffle.router.ts +0 -90
  96. package/modules/raffle/raffle.schema.ts +0 -32
  97. package/modules/raffle/raffle.service.ts +0 -167
  98. package/modules/raffle/raffle.types.ts +0 -30
  99. package/modules/skill/index.ts +0 -5
  100. package/modules/skill/skill.models.ts +0 -16
  101. package/modules/skill/skill.router.ts +0 -201
  102. package/modules/skill/skill.schema.ts +0 -40
  103. package/modules/skill/skill.service.ts +0 -390
  104. package/modules/skill/skill.types.ts +0 -33
  105. package/modules/video/index.ts +0 -5
  106. package/modules/video/video.models.ts +0 -25
  107. package/modules/video/video.router.ts +0 -143
  108. package/modules/video/video.schema.ts +0 -46
  109. package/modules/video/video.service.ts +0 -274
  110. package/modules/video/video.types.ts +0 -33
  111. package/util/db/index.ts +0 -7
  112. package/util/db/isPostgresError.ts +0 -9
  113. package/util/db/isUniqueConstraintViolation.ts +0 -3
  114. package/util/db.ts +0 -62
  115. package/util/index.ts +0 -351
  116. /package/{util/api.ts → api.ts} +0 -0
  117. /package/{util/array.ts → array.ts} +0 -0
  118. /package/{util/browser.ts → browser.ts} +0 -0
  119. /package/{util/codebase.ts → codebase.ts} +0 -0
  120. /package/{util/config.ts → config.ts} +0 -0
  121. /package/{util/decoder.test.ts → decoder.test.ts} +0 -0
  122. /package/{util/decoder.ts → decoder.ts} +0 -0
  123. /package/{util/format.ts → format.ts} +0 -0
  124. /package/{util/guid.ts → guid.ts} +0 -0
  125. /package/{util/json.ts → json.ts} +0 -0
  126. /package/{util/log.ts → log.ts} +0 -0
  127. /package/{util/math.ts → math.ts} +0 -0
  128. /package/{util/merkle.ts → merkle.ts} +0 -0
  129. /package/{util/mongo.ts → mongo.ts} +0 -0
  130. /package/{util/number.ts → number.ts} +0 -0
  131. /package/{util/object.ts → object.ts} +0 -0
  132. /package/{util/otp.ts → otp.ts} +0 -0
  133. /package/{util/physics.ts → physics.ts} +0 -0
  134. /package/{util/process.ts → process.ts} +0 -0
  135. /package/{util/rpc.ts → rpc.ts} +0 -0
  136. /package/{util/seer.ts → seer.ts} +0 -0
  137. /package/{util/string.ts → string.ts} +0 -0
  138. /package/{util/text.ts → text.ts} +0 -0
  139. /package/{util/time → time}/date.ts +0 -0
  140. /package/{util/time → time}/fancyTimeFormat.ts +0 -0
  141. /package/{util/time → time}/index.ts +0 -0
  142. /package/{util/time → time}/now.ts +0 -0
  143. /package/{util/types → types}/mongo.d.ts +0 -0
  144. /package/{util/web3 → web3}/httpProvider.ts +0 -0
  145. /package/{util/web3.ts → web3.ts} +0 -0
  146. /package/{util/websocket.ts → websocket.ts} +0 -0
  147. /package/{util/zk.ts → zk.ts} +0 -0
  148. /package/{util/zod.ts → zod.ts} +0 -0
@@ -1,381 +0,0 @@
1
- // packages/node/modules/core/mail/mailClaimablePatchesBatch.ts
2
- //
3
- import type { RouterContext } from '../core.types';
4
- import type { EntityPatch } from '../../../types';
5
-
6
- type MailKind = 'mail' | 'dm' | 'group' | 'support' | 'system';
7
-
8
- export type MailPatchMessagePayload = {
9
- kind: 'patch-grant';
10
- source: string;
11
- title?: string;
12
- body?: string;
13
- patches: EntityPatch[];
14
- ui?: {
15
- rewards?: Array<{ type: 'item' | 'token' | 'reward'; id: string; quantity?: number; meta?: any }>;
16
- effects?: Array<{ type: 'stat' | 'flag' | 'effect'; key?: string; delta?: number; value?: any; label?: string }>;
17
- };
18
- };
19
-
20
- export type MailClaimableBatchParams = {
21
- ctx: RouterContext;
22
-
23
- /** If omitted, helper streams all profiles */
24
- profileIds?: string[];
25
-
26
- /** Streaming mode: process all profiles using _id cursor */
27
- streamAllProfiles?: boolean;
28
-
29
- kind?: MailKind; // default 'mail'
30
- source: string;
31
-
32
- title: string;
33
- body: string;
34
-
35
- /**
36
- * Same dedupeKey across all conversations is OK because uniqueness is enforced by:
37
- * (conversationId, claim.dedupeKey)
38
- */
39
- dedupeKey: string;
40
-
41
- /**
42
- * IMPORTANT: These patches should be claimable. Your applyPatchesWithInventoryViaMail
43
- * uses `patch.claimable` to decide mail vs immediate. For broadcast we ALWAYS mail.
44
- */
45
- claimablePatches: EntityPatch[];
46
-
47
- payloadUi?: MailPatchMessagePayload['ui'];
48
-
49
- batchSize?: number; // default 1000
50
-
51
- conversationKey: string; // ✅ REQUIRED
52
- conversationTitle?: string; // optional: used on new convo creation
53
- conversationCategory?: string; // optional
54
- conversationImportance?: number; // optional
55
- };
56
-
57
- export type MailClaimableBatchResult = {
58
- processedProfiles: number;
59
- conversationsFound: number;
60
- conversationsCreated: number;
61
-
62
- messagesExisting: number;
63
- messagesCreated: number;
64
- };
65
-
66
- function chunk<T>(arr: T[], size: number): T[][] {
67
- const out: T[][] = [];
68
- for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));
69
- return out;
70
- }
71
-
72
- function toObjectId(mongoose: any, id: string) {
73
- // Works whether id already is ObjectId-like or string
74
- try {
75
- return new mongoose.Types.ObjectId(id);
76
- } catch {
77
- return id;
78
- }
79
- }
80
-
81
- /**
82
- * Bulk-mail claimable patches to many profiles.
83
- *
84
- * Design assumptions:
85
- * - 1 mailbox per profile per kind (kind='mail' for inbox)
86
- * - Conversation can be found by:
87
- * - kind + profileId (back-compat) OR
88
- * - kind + participants.profileId (new)
89
- * - Dedupe per conversation by claim.dedupeKey
90
- */
91
- export async function mailClaimablePatchesBatch(params: MailClaimableBatchParams): Promise<MailClaimableBatchResult> {
92
- const {
93
- ctx,
94
- kind = 'mail',
95
- source,
96
- title,
97
- body,
98
- dedupeKey,
99
- claimablePatches,
100
- payloadUi,
101
- batchSize = 1000,
102
- conversationKey,
103
- } = params;
104
-
105
- const mongoose = (ctx.app as any).db?.mongoose ?? (ctx.app as any).mongoose;
106
- const Profile = (ctx.app as any).model.Profile;
107
- const Conversation = (ctx.app as any).model.Conversation;
108
- const ConversationMessage = (ctx.app as any).model.ConversationMessage;
109
-
110
- if (!Profile || !Conversation || !ConversationMessage) {
111
- throw new Error('mailClaimablePatchesBatch: missing required models (Profile/Conversation/ConversationMessage)');
112
- }
113
-
114
- const payload: MailPatchMessagePayload = {
115
- kind: 'patch-grant',
116
- source,
117
- title,
118
- body,
119
- patches: claimablePatches,
120
- ui: payloadUi,
121
- };
122
-
123
- const preview = `${title} — ${body}`.slice(0, 140);
124
- const now = new Date();
125
-
126
- let processedProfiles = 0;
127
- let conversationsFound = 0;
128
- let conversationsCreated = 0;
129
- let messagesExisting = 0;
130
- let messagesCreated = 0;
131
-
132
- // ----------------------------
133
- // Resolve profile id batches
134
- // ----------------------------
135
- const explicitIds = Array.isArray(params.profileIds) ? params.profileIds.filter(Boolean) : [];
136
-
137
- // If caller gave explicit profileIds, just run those (chunked).
138
- if (explicitIds.length > 0) {
139
- for (const batch of chunk(explicitIds, batchSize)) {
140
- const r = await processProfileIdBatch(batch, ctx);
141
- processedProfiles += r.processedProfiles;
142
- conversationsFound += r.conversationsFound;
143
- conversationsCreated += r.conversationsCreated;
144
- messagesExisting += r.messagesExisting;
145
- messagesCreated += r.messagesCreated;
146
- }
147
-
148
- return { processedProfiles, conversationsFound, conversationsCreated, messagesExisting, messagesCreated };
149
- }
150
-
151
- // Otherwise stream all profiles if requested; default true if neither profileIds nor streamAllProfiles specified.
152
- const streamAll = params.streamAllProfiles ?? true;
153
- if (!streamAll) {
154
- return {
155
- processedProfiles: 0,
156
- conversationsFound: 0,
157
- conversationsCreated: 0,
158
- messagesExisting: 0,
159
- messagesCreated: 0,
160
- };
161
- }
162
-
163
- // Stream profiles by _id cursor to avoid loading everything.
164
- let lastId: any = null;
165
-
166
- // eslint-disable-next-line no-constant-condition
167
- while (true) {
168
- const q: any = lastId ? { _id: { $gt: lastId } } : {};
169
- const docs = await Profile.find(q).select({ _id: 1 }).sort({ _id: 1 }).limit(batchSize).lean().exec();
170
-
171
- if (!docs || docs.length === 0) break;
172
-
173
- const batchIds = docs.map((d: any) => String(d._id));
174
- lastId = docs[docs.length - 1]._id;
175
-
176
- const r = await processProfileIdBatch(batchIds, ctx);
177
- processedProfiles += r.processedProfiles;
178
- conversationsFound += r.conversationsFound;
179
- conversationsCreated += r.conversationsCreated;
180
- messagesExisting += r.messagesExisting;
181
- messagesCreated += r.messagesCreated;
182
- }
183
-
184
- return { processedProfiles, conversationsFound, conversationsCreated, messagesExisting, messagesCreated };
185
-
186
- // ============================================================
187
- // Batch worker: takes string profile ids
188
- // ============================================================
189
- async function processProfileIdBatch(profileIds: string[], ctx: any): Promise<MailClaimableBatchResult> {
190
- const profileObjectIds = profileIds.map((id) => toObjectId(mongoose, id));
191
-
192
- // 1) Find existing inbox conversations for these profiles (both back-compat + participants)
193
- const existingConvos = await ctx.app.model.Conversation.find({
194
- kind,
195
- key: conversationKey, // ✅ NEW
196
- $or: [{ profileId: { $in: profileObjectIds } }, { 'participants.profileId': { $in: profileObjectIds } }],
197
- })
198
- .select({ _id: 1, profileId: 1, participants: 1 })
199
- .lean()
200
- .exec();
201
-
202
- const convoByProfileId = new Map<string, any>();
203
-
204
- for (const c of existingConvos || []) {
205
- // Prefer participant mapping when available
206
- const participants = Array.isArray((c as any).participants) ? (c as any).participants : [];
207
- for (const p of participants) {
208
- if (p?.profileId) convoByProfileId.set(String(p.profileId), c);
209
- }
210
- if ((c as any).profileId) convoByProfileId.set(String((c as any).profileId), c);
211
- }
212
-
213
- const foundCount = convoByProfileId.size;
214
-
215
- // 2) Create missing conversations
216
- const missingProfileIds = profileIds.filter((pid) => !convoByProfileId.has(String(pid)));
217
-
218
- // 2) Create missing conversations (UPSERT)
219
- if (missingProfileIds.length > 0) {
220
- const ops = missingProfileIds.map((pid) => {
221
- const pidObj = toObjectId(mongoose, pid);
222
- return {
223
- updateOne: {
224
- filter: {
225
- applicationId: toObjectId(mongoose, (ctx.app as any).filters.applicationId),
226
- kind,
227
- key: conversationKey,
228
- profileId: pidObj,
229
- status: { $ne: 'Archived' },
230
- },
231
- update: {
232
- $setOnInsert: {
233
- applicationId: toObjectId(mongoose, (ctx.app as any).filters.applicationId),
234
- kind,
235
- key: conversationKey,
236
- profileId: pidObj,
237
- participants: [
238
- {
239
- profileId: pidObj,
240
- role: 'user',
241
- lastReadAt: new Date(0),
242
- unreadCount: 0,
243
- isMuted: false,
244
- isPinned: false,
245
- isArchived: false,
246
- isDeleted: false,
247
- },
248
- ],
249
- isLocked: true,
250
- allowUserSend: false,
251
- name: 'System',
252
- category: 'system',
253
- importance: 0,
254
- lastMessageDate: null,
255
- lastMessagePreview: '',
256
- messageCount: 0,
257
- messages: [],
258
- status: 'Active',
259
- },
260
- },
261
- upsert: true,
262
- },
263
- };
264
- });
265
-
266
- // bulkWrite exists on your wrapper (you already call it later)
267
- const res = await ctx.app.model.Conversation.bulkWrite(ops, { ordered: false });
268
-
269
- // 🔴 REQUIRED: re-read conversations to get _id for newly upserted docs
270
- const convosForBatch = await ctx.app.model.Conversation.find({
271
- kind,
272
- key: conversationKey,
273
- $or: [{ profileId: { $in: profileObjectIds } }, { 'participants.profileId': { $in: profileObjectIds } }],
274
- })
275
- .select({ _id: 1, profileId: 1, participants: 1 })
276
- .lean()
277
- .exec();
278
-
279
- // rebuild convoByProfileId with fresh _id values
280
- convoByProfileId.clear();
281
- for (const c of convosForBatch || []) {
282
- const participants = Array.isArray(c.participants) ? c.participants : [];
283
- for (const p of participants) {
284
- if (p?.profileId) convoByProfileId.set(String(p.profileId), c);
285
- }
286
- if (c.profileId) convoByProfileId.set(String(c.profileId), c);
287
- }
288
-
289
- // Depending on wrapper, it may return { upsertedCount } or { nUpserted }
290
- conversationsCreated += Number((res as any)?.upsertedCount ?? (res as any)?.nUpserted ?? 0);
291
- }
292
-
293
- // 3) Now we have conversation ids for (almost) everyone in the batch
294
- const convoIds = profileIds.map((pid) => convoByProfileId.get(String(pid))?._id).filter(Boolean);
295
-
296
- // If something is still missing, skip those profiles (should be extremely rare)
297
- const convoIdSet = new Set(convoIds.map((id: any) => String(id)));
298
- const uniqueConvoIds = Array.from(convoIdSet).map((id) => toObjectId(mongoose, id));
299
-
300
- // 4) Dedupe: find existing messages with this dedupeKey for these conversations
301
- const existingMsgs = await ctx.app.model.ConversationMessage.find({
302
- conversationId: { $in: uniqueConvoIds },
303
- 'claim.dedupeKey': dedupeKey,
304
- })
305
- .select({ _id: 1, conversationId: 1 })
306
- .lean()
307
- .exec();
308
-
309
- const hasMsgForConvo = new Set<string>((existingMsgs || []).map((m: any) => String(m.conversationId)));
310
- const existingMsgCount = hasMsgForConvo.size;
311
-
312
- // 5) Build inserts for conversations missing the message
313
- const msgsToInsert = uniqueConvoIds
314
- .filter((cid: any) => !hasMsgForConvo.has(String(cid)))
315
- .map((conversationId: any) => ({
316
- conversationId,
317
- role: 'system',
318
- type: 'reward',
319
- content: body ?? '',
320
- payload,
321
- claim: {
322
- isClaimable: true,
323
- claimedDate: null,
324
- claimedByProfileId: null,
325
- dedupeKey,
326
- attachments: [],
327
- revokedDate: null,
328
- revokeReason: null,
329
- },
330
- }));
331
-
332
- let insertedMsgs: any[] = [];
333
- if (msgsToInsert.length > 0) {
334
- try {
335
- insertedMsgs = await ctx.app.model.ConversationMessage.insertMany(msgsToInsert, { ordered: false });
336
- } catch (e: any) {
337
- console.log('error inserting conversation messages', e);
338
- // If some duplicate insert races happened, we ignore and continue.
339
- // console.warn('ConversationMessage.insertMany partial failure', e?.message);
340
- }
341
- }
342
-
343
- // 6) Update conversations listing fields for those where we inserted a message
344
- if (insertedMsgs.length > 0) {
345
- const convoUpdates = insertedMsgs.map((m: any) => ({
346
- updateOne: {
347
- filter: { _id: m.conversationId },
348
- update: {
349
- $set: {
350
- lastMessageDate: now,
351
- lastMessagePreview: preview,
352
- },
353
- $inc: {
354
- messageCount: 1,
355
- // Increment unread count for the user participant if present
356
- 'participants.$[p].unreadCount': 1,
357
- },
358
- // Back-compat array; you said you’re keeping it for now.
359
- $push: { messages: m._id },
360
- },
361
- arrayFilters: [{ 'p.role': 'user' }],
362
- },
363
- }));
364
-
365
- try {
366
- await ctx.app.model.Conversation.bulkWrite(convoUpdates, { ordered: false });
367
- } catch (e: any) {
368
- console.log('error bulk updating conversations', e);
369
- // ignore
370
- }
371
- }
372
-
373
- return {
374
- processedProfiles: profileIds.length,
375
- conversationsFound: foundCount,
376
- conversationsCreated: 0, // tracked at outer scope; keep per-batch minimal
377
- messagesExisting: existingMsgCount,
378
- messagesCreated: insertedMsgs.length,
379
- };
380
- }
381
- }
@@ -1,53 +0,0 @@
1
- import * as mongo from '../../util/mongo';
2
- import type * as Types from './game.types';
3
-
4
- const { addTagVirtuals, addApplicationVirtual } = mongo;
5
-
6
- export const Game = mongo.createModel<Types.GameDocument>(
7
- 'Game',
8
- {
9
- productId: { type: mongo.Schema.Types.ObjectId, ref: 'Product', required: true },
10
- statId: { type: mongo.Schema.Types.ObjectId, ref: 'GameStat' },
11
- },
12
- {
13
- extend: 'EntityFields',
14
- indexes: [{ applicationId: 1, name: 1, unique: true }],
15
- virtuals: [
16
- ...addTagVirtuals('Application'),
17
- { name: 'stat' },
18
- { name: 'stats', ref: 'GameStat', localField: '_id', foreignField: 'gameId' },
19
- { name: 'rounds', ref: 'GameRound', localField: '_id', foreignField: 'gameId' },
20
- // {
21
- // name: 'latestStat',
22
- // ref: 'GameStat',
23
- // localField: '_id',
24
- // foreignField: 'gameId',
25
- // options: { sort: { createdAt: -1 }, limit: 1 },
26
- // },
27
- ],
28
- }
29
- );
30
-
31
- export const GameStat = mongo.createModel<Types.GameStatDocument>(
32
- 'GameStat',
33
- {
34
- gameId: { type: mongo.Schema.Types.ObjectId, ref: 'Game', required: true },
35
- },
36
- {
37
- extend: 'EntityFields',
38
- virtuals: [...addTagVirtuals('Application'), { name: 'game' }],
39
- }
40
- );
41
-
42
- export const GameRound = mongo.createModel<Types.GameRoundDocument>(
43
- 'GameRound',
44
- {
45
- gameId: { type: mongo.Schema.Types.ObjectId, ref: 'Game', required: true },
46
- },
47
- {
48
- extend: 'EntityFields',
49
- virtuals: [...addTagVirtuals('Application'), { name: 'game' }],
50
- }
51
- );
52
-
53
- export const Era = mongo.createModel<Types.EraDocument>('Era', {});
@@ -1,110 +0,0 @@
1
- import { z as zod } from 'zod';
2
- import { initTRPC } from '@trpc/server';
3
- import { customErrorFormatter, hasRole } from '../../util/rpc';
4
- import type { RouterContext } from '../../types';
5
- import { Era, Game, GameStat } from './game.schema';
6
- import { Query, getQueryInput, inferRouterOutputs, inferRouterInputs } from '../../schema';
7
-
8
- export const z = zod;
9
- export const t = initTRPC.context<RouterContext>().create();
10
- export const router = t.router;
11
- export const procedure = t.procedure;
12
-
13
- export const createRouter = () =>
14
- router({
15
- getGame: procedure
16
- .use(hasRole('guest', t))
17
- .use(customErrorFormatter(t))
18
- .input(getQueryInput(Game))
19
- .output(Game)
20
- .query(({ input, ctx }) => (ctx.app.service.Game.getGame as any)(input, ctx)),
21
-
22
- getGames: procedure
23
- .use(hasRole('guest', t))
24
- .use(customErrorFormatter(t))
25
- .input(getQueryInput(Game))
26
- .output(z.array(Game))
27
- .query(({ input, ctx }) => (ctx.app.service.Game.getGames as any)(input, ctx)),
28
-
29
- createGame: procedure
30
- .use(hasRole('guest', t))
31
- .use(customErrorFormatter(t))
32
- .input(getQueryInput(Game))
33
- .output(Game.pick({ id: true }))
34
- .query(({ input, ctx }) => (ctx.app.service.Game.createGame as any)(input, ctx)),
35
-
36
- updateGame: procedure
37
- .use(hasRole('guest', t))
38
- .use(customErrorFormatter(t))
39
- .input(getQueryInput(Game))
40
- .output(Game.pick({ id: true }))
41
- .query(({ input, ctx }) => (ctx.app.service.Game.updateGame as any)(input, ctx)),
42
-
43
- getGameStat: procedure
44
- .use(hasRole('guest', t))
45
- .use(customErrorFormatter(t))
46
- .input(getQueryInput(GameStat))
47
- .output(GameStat)
48
- .query(({ input, ctx }) => (ctx.app.service.Game.getGameStat as any)(input, ctx)),
49
-
50
- getGameStats: procedure
51
- .use(hasRole('guest', t))
52
- .use(customErrorFormatter(t))
53
- .input(getQueryInput(GameStat))
54
- .output(z.array(GameStat))
55
- .query(({ input, ctx }) => (ctx.app.service.Game.getGameStats as any)(input, ctx)),
56
-
57
- createGameStat: procedure
58
- .use(hasRole('guest', t))
59
- .use(customErrorFormatter(t))
60
- .input(getQueryInput(GameStat))
61
- .output(GameStat.pick({ id: true }))
62
- .query(({ input, ctx }) => (ctx.app.service.Game.createGameStat as any)(input, ctx)),
63
-
64
- updateGameStat: procedure
65
- .use(hasRole('guest', t))
66
- .use(customErrorFormatter(t))
67
- .input(getQueryInput(GameStat))
68
- .output(GameStat.pick({ id: true }))
69
- .query(({ input, ctx }) => (ctx.app.service.Game.updateGame as any)(input, ctx)),
70
-
71
- // Era Procedures
72
- getEra: procedure
73
- .use(hasRole('guest', t))
74
- .use(customErrorFormatter(t))
75
- .input(getQueryInput(Era))
76
- .output(Era)
77
- .query(({ input, ctx }) => (ctx.app.service.Game.getEra as any)(input, ctx)),
78
-
79
- getEras: procedure
80
- .use(hasRole('guest', t))
81
- .use(customErrorFormatter(t))
82
- .input(getQueryInput(Era))
83
- .output(z.array(Era))
84
- .query(({ input, ctx }) => (ctx.app.service.Game.getEras as any)(input, ctx)),
85
-
86
- createEra: procedure
87
- .use(hasRole('admin', t))
88
- .use(customErrorFormatter(t))
89
- .input(getQueryInput(Era))
90
- .output(Era.pick({ id: true }))
91
- .mutation(({ input, ctx }) => (ctx.app.service.Game.createEra as any)(input, ctx)),
92
-
93
- updateEra: procedure
94
- .use(hasRole('admin', t))
95
- .use(customErrorFormatter(t))
96
- .input(getQueryInput(Era))
97
- .output(Era.pick({ id: true }))
98
- .mutation(({ input, ctx }) => (ctx.app.service.Game.updateEra as any)(input, ctx)),
99
-
100
- deleteEra: procedure
101
- .use(hasRole('admin', t))
102
- .use(customErrorFormatter(t))
103
- .input(getQueryInput(Era))
104
- .output(Era.pick({ id: true }))
105
- .mutation(({ input, ctx }) => (ctx.app.service.Game.deleteEra as any)(input, ctx)),
106
- });
107
-
108
- export type Router = ReturnType<typeof createRouter>;
109
- export type RouterInput = inferRouterInputs<Router>;
110
- export type RouterOutput = inferRouterOutputs<Router>;
@@ -1,23 +0,0 @@
1
- import { z, ObjectId, Entity } from '../../schema';
2
-
3
- export const GameStat = Entity.merge(
4
- z.object({
5
- gameId: ObjectId,
6
- })
7
- );
8
-
9
- export const Game = Entity.merge(
10
- z.object({
11
- productId: ObjectId,
12
- statId: ObjectId.optional(),
13
- stat: GameStat.nullable().optional(),
14
- })
15
- );
16
-
17
- export const GameRound = Entity.merge(
18
- z.object({
19
- gameId: ObjectId,
20
- })
21
- );
22
-
23
- export const Era = Entity.merge(z.object({}));