@gbl-uzh/platform 0.2.10

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/dist/nexus.js ADDED
@@ -0,0 +1,2563 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
+
26
+ // src/nexus.ts
27
+ var nexus_exports = {};
28
+ __export(nexus_exports, {
29
+ DateScalar: () => DateScalar,
30
+ Event: () => Event,
31
+ Game: () => Game,
32
+ GameStatus: () => GameStatus2,
33
+ JsonScalar: () => JsonScalar,
34
+ LearningAnswerOption: () => LearningAnswerOption,
35
+ LearningElement: () => LearningElement,
36
+ LearningElementAttempt: () => LearningElementAttempt,
37
+ LearningElementState: () => LearningElementState,
38
+ Mutation: () => Mutation,
39
+ Period: () => Period,
40
+ PeriodFactsInput: () => PeriodFactsInput,
41
+ PeriodFactsSchema: () => PeriodFactsSchema,
42
+ PeriodSegment: () => PeriodSegment,
43
+ PeriodSegmentFactsInput: () => PeriodSegmentFactsInput,
44
+ PeriodSegmentFactsSchema: () => PeriodSegmentFactsSchema,
45
+ Player: () => Player,
46
+ PlayerAction: () => PlayerAction,
47
+ PlayerDecision: () => PlayerDecision,
48
+ PlayerDecisionType: () => PlayerDecisionType2,
49
+ PlayerLevel: () => PlayerLevel,
50
+ PlayerResult: () => PlayerResult,
51
+ PlayerResultType: () => PlayerResultType2,
52
+ PlayerState: () => PlayerState,
53
+ Query: () => Query,
54
+ Subscription: () => Subscription,
55
+ UserRole: () => UserRole3,
56
+ generateBaseMutations: () => generateBaseMutations,
57
+ generateBaseQueries: () => generateBaseQueries,
58
+ generateBaseSubscriptions: () => generateBaseSubscriptions
59
+ });
60
+ module.exports = __toCommonJS(nexus_exports);
61
+ var DB5 = __toESM(require("@prisma/client"));
62
+ var import_graphql_scalars = require("graphql-scalars");
63
+ var import_nexus11 = require("nexus");
64
+
65
+ // src/types/Game.ts
66
+ var DB4 = __toESM(require("@prisma/client"));
67
+ var import_nexus5 = require("nexus");
68
+
69
+ // src/types/LearningElement.ts
70
+ var import_nexus4 = require("nexus");
71
+
72
+ // src/types/Player.ts
73
+ var DB3 = __toESM(require("@prisma/client"));
74
+ var import_nexus3 = require("nexus");
75
+
76
+ // src/types/Achievement.ts
77
+ var DB = __toESM(require("@prisma/client"));
78
+ var import_nexus = require("nexus");
79
+ var AchievementFrequency2 = (0, import_nexus.enumType)({
80
+ name: "AchievementFrequency",
81
+ members: Object.values(DB.AchievementFrequency)
82
+ });
83
+ var Achievement = (0, import_nexus.objectType)({
84
+ name: "Achievement",
85
+ definition(t) {
86
+ t.nonNull.id("id");
87
+ t.nonNull.string("name");
88
+ t.nonNull.string("description");
89
+ t.string("image");
90
+ t.nonNull.field("when", {
91
+ type: AchievementFrequency2
92
+ });
93
+ t.field("reward", {
94
+ type: "JSONObject"
95
+ });
96
+ }
97
+ });
98
+ var AchievementInstance = (0, import_nexus.objectType)({
99
+ name: "AchievementInstance",
100
+ definition(t) {
101
+ t.nonNull.int("id");
102
+ t.nonNull.int("count");
103
+ t.nonNull.field("achievement", {
104
+ type: Achievement
105
+ });
106
+ }
107
+ });
108
+
109
+ // src/types/StoryElement.ts
110
+ var DB2 = __toESM(require("@prisma/client"));
111
+ var import_nexus2 = require("nexus");
112
+ var StoryElementType2 = (0, import_nexus2.enumType)({
113
+ name: "StoryElementType",
114
+ members: Object.values(DB2.StoryElementType)
115
+ });
116
+ var StoryElement = (0, import_nexus2.objectType)({
117
+ name: "StoryElement",
118
+ definition(t) {
119
+ t.nonNull.id("id");
120
+ t.nonNull.field("type", {
121
+ type: StoryElementType2
122
+ });
123
+ t.nonNull.string("title");
124
+ t.string("content");
125
+ t.string("contentRole");
126
+ t.field("reward", {
127
+ type: "JSONObject"
128
+ });
129
+ }
130
+ });
131
+
132
+ // src/types/Player.ts
133
+ var PlayerDecisionType2 = (0, import_nexus3.enumType)({
134
+ name: "PlayerDecisionType",
135
+ members: Object.values(DB3.PlayerDecisionType)
136
+ });
137
+ var PlayerResultType2 = (0, import_nexus3.enumType)({
138
+ name: "PlayerResultType",
139
+ members: Object.values(DB3.PlayerResultType)
140
+ });
141
+ var PlayerLevel = (0, import_nexus3.objectType)({
142
+ name: "PlayerLevel",
143
+ definition(t) {
144
+ t.nonNull.id("id");
145
+ t.nonNull.int("index");
146
+ t.nonNull.string("description");
147
+ t.nonNull.int("requiredXP");
148
+ }
149
+ });
150
+ var PlayerState = (0, import_nexus3.objectType)({
151
+ name: "PlayerState",
152
+ definition(t) {
153
+ t.field("playerResult", {
154
+ type: PlayerResult
155
+ });
156
+ t.field("currentGame", {
157
+ type: Game
158
+ });
159
+ t.list.field("previousResults", {
160
+ type: PlayerResult
161
+ });
162
+ t.list.field("transactions", {
163
+ type: PlayerAction
164
+ });
165
+ }
166
+ });
167
+ var Player = (0, import_nexus3.objectType)({
168
+ name: "Player",
169
+ definition(t) {
170
+ t.nonNull.id("id");
171
+ t.nonNull.boolean("isReady");
172
+ t.nonNull.string("name");
173
+ t.nonNull.string("avatar");
174
+ t.nonNull.string("location");
175
+ t.nonNull.string("color");
176
+ t.nonNull.string("token");
177
+ t.nonNull.boolean("tutorialCompleted");
178
+ t.nonNull.string("role");
179
+ t.nonNull.int("experience");
180
+ t.nonNull.int("experienceToNext");
181
+ t.nonNull.field("facts", {
182
+ type: "JSONObject"
183
+ });
184
+ t.nonNull.field("level", {
185
+ type: PlayerLevel
186
+ });
187
+ t.nonNull.int("levelIx");
188
+ t.nonNull.list.nonNull.string("achievementKeys");
189
+ t.nonNull.list.nonNull.string("achievementIds");
190
+ t.nonNull.list.nonNull.field("achievements", {
191
+ type: AchievementInstance
192
+ });
193
+ t.nonNull.list.nonNull.field("completedLearningElements", {
194
+ type: LearningElement
195
+ });
196
+ t.nonNull.list.nonNull.int("completedLearningElementIds");
197
+ t.nonNull.list.nonNull.field("visitedStoryElements", {
198
+ type: StoryElement
199
+ });
200
+ t.nonNull.list.nonNull.int("visitedStoryElementIds");
201
+ }
202
+ });
203
+ var PlayerResult = (0, import_nexus3.objectType)({
204
+ name: "PlayerResult",
205
+ definition(t) {
206
+ t.nonNull.id("id");
207
+ t.field("type", {
208
+ type: PlayerResultType2
209
+ });
210
+ t.field("facts", {
211
+ type: "JSONObject"
212
+ });
213
+ t.nonNull.field("player", {
214
+ type: Player
215
+ });
216
+ t.nonNull.field("period", {
217
+ type: Period
218
+ });
219
+ t.field("segment", {
220
+ type: PeriodSegment
221
+ });
222
+ }
223
+ });
224
+ var PlayerAction = (0, import_nexus3.objectType)({
225
+ name: "PlayerAction",
226
+ definition(t) {
227
+ t.nonNull.id("id");
228
+ t.nonNull.string("type");
229
+ t.field("facts", {
230
+ type: "JSONObject"
231
+ });
232
+ t.nonNull.field("player", {
233
+ type: Player
234
+ });
235
+ t.nonNull.field("period", {
236
+ type: Period
237
+ });
238
+ t.nonNull.int("periodIx");
239
+ t.field("segment", {
240
+ type: PeriodSegment
241
+ });
242
+ t.int("segmentIx");
243
+ }
244
+ });
245
+ var PlayerDecision = (0, import_nexus3.objectType)({
246
+ name: "PlayerDecision",
247
+ definition(t) {
248
+ t.nonNull.id("id");
249
+ t.nonNull.field("player", {
250
+ type: Player
251
+ });
252
+ t.nonNull.field("period", {
253
+ type: Period
254
+ });
255
+ t.nonNull.int("periodIx");
256
+ t.nonNull.field("type", {
257
+ type: PlayerDecisionType2
258
+ });
259
+ t.nonNull.field("facts", {
260
+ type: "JSONObject"
261
+ });
262
+ }
263
+ });
264
+
265
+ // src/types/LearningElement.ts
266
+ var LearningAnswerOption = (0, import_nexus4.objectType)({
267
+ name: "LearningAnswerOption",
268
+ definition(t) {
269
+ t.nonNull.id("id");
270
+ t.nonNull.string("content");
271
+ t.nonNull.boolean("correct");
272
+ }
273
+ });
274
+ var LearningElementState = (0, import_nexus4.objectType)({
275
+ name: "LearningElementState",
276
+ definition(t) {
277
+ t.id("id");
278
+ t.field("element", {
279
+ type: LearningElement
280
+ });
281
+ t.string("state");
282
+ t.string("solution");
283
+ }
284
+ });
285
+ var LearningElementAttempt = (0, import_nexus4.objectType)({
286
+ name: "LearningElementAttempt",
287
+ definition(t) {
288
+ t.id("id");
289
+ t.int("pointsAchieved");
290
+ t.int("pointsMax");
291
+ t.field("element", {
292
+ type: LearningElement
293
+ });
294
+ t.field("player", {
295
+ type: Player
296
+ });
297
+ }
298
+ });
299
+ var LearningElement = (0, import_nexus4.objectType)({
300
+ name: "LearningElement",
301
+ definition(t) {
302
+ t.nonNull.id("id");
303
+ t.nonNull.string("title");
304
+ t.nonNull.string("question");
305
+ t.field("reward", {
306
+ type: "JSONObject"
307
+ });
308
+ t.string("motivation");
309
+ t.nonNull.list.nonNull.field("options", {
310
+ type: LearningAnswerOption
311
+ });
312
+ t.string("feedback");
313
+ }
314
+ });
315
+
316
+ // src/types/Game.ts
317
+ var GameStatus2 = (0, import_nexus5.enumType)({
318
+ name: "GameStatus",
319
+ members: Object.values(DB4.GameStatus)
320
+ });
321
+ var Game = (0, import_nexus5.objectType)({
322
+ name: "Game",
323
+ definition(t) {
324
+ t.nonNull.id("id");
325
+ t.nonNull.field("status", {
326
+ type: GameStatus2
327
+ });
328
+ t.nonNull.string("name");
329
+ t.int("activePeriodIx");
330
+ t.field("activePeriod", {
331
+ type: Period
332
+ });
333
+ t.nonNull.list.nonNull.field("players", {
334
+ type: Player
335
+ });
336
+ t.nonNull.list.nonNull.field("periods", {
337
+ type: Period
338
+ });
339
+ t.nonNull.list.nonNull.field("segments", {
340
+ type: PeriodSegment
341
+ });
342
+ }
343
+ });
344
+ var Period = (0, import_nexus5.objectType)({
345
+ name: "Period",
346
+ definition(t) {
347
+ t.nonNull.id("id");
348
+ t.nonNull.int("index");
349
+ t.int("activeSegmentIx");
350
+ t.field("activeSegment", {
351
+ type: PeriodSegment
352
+ });
353
+ t.nonNull.list.nonNull.field("actions", {
354
+ type: PlayerAction
355
+ });
356
+ t.nonNull.list.nonNull.field("results", {
357
+ type: PlayerResult
358
+ });
359
+ t.nonNull.list.nonNull.field("segments", {
360
+ type: PeriodSegment
361
+ });
362
+ t.nonNull.field("facts", {
363
+ type: "JSONObject"
364
+ });
365
+ }
366
+ });
367
+ var PeriodSegment = (0, import_nexus5.objectType)({
368
+ name: "PeriodSegment",
369
+ definition(t) {
370
+ t.nonNull.id("id");
371
+ t.nonNull.int("index");
372
+ t.nonNull.int("periodIx");
373
+ t.nonNull.list.nonNull.field("actions", {
374
+ type: PlayerAction
375
+ });
376
+ t.nonNull.list.nonNull.field("results", {
377
+ type: PlayerResult
378
+ });
379
+ t.nonNull.list.nonNull.field("learningElements", {
380
+ type: LearningElement
381
+ });
382
+ t.nonNull.list.nonNull.field("storyElements", {
383
+ type: StoryElement
384
+ });
385
+ t.nonNull.field("facts", {
386
+ type: "JSONObject"
387
+ });
388
+ }
389
+ });
390
+
391
+ // src/types/Mutation.ts
392
+ var import_nexus7 = require("nexus");
393
+
394
+ // src/generated/ops.ts
395
+ var GameDataFragmentDoc = { "kind": "Document", "definitions": [{ "kind": "FragmentDefinition", "name": { "kind": "Name", "value": "GameData" }, "typeCondition": { "kind": "NamedType", "name": { "kind": "Name", "value": "Game" } }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "status" } }, { "kind": "Field", "name": { "kind": "Name", "value": "name" } }, { "kind": "Field", "name": { "kind": "Name", "value": "activePeriodIx" } }] } }] };
396
+ var LearningElementDataFragmentDoc = { "kind": "Document", "definitions": [{ "kind": "FragmentDefinition", "name": { "kind": "Name", "value": "LearningElementData" }, "typeCondition": { "kind": "NamedType", "name": { "kind": "Name", "value": "LearningElement" } }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "title" } }, { "kind": "Field", "name": { "kind": "Name", "value": "question" } }, { "kind": "Field", "name": { "kind": "Name", "value": "reward" } }, { "kind": "Field", "name": { "kind": "Name", "value": "motivation" } }, { "kind": "Field", "name": { "kind": "Name", "value": "feedback" } }] } }] };
397
+ var SegmentDataFragmentDoc = { "kind": "Document", "definitions": [{ "kind": "FragmentDefinition", "name": { "kind": "Name", "value": "SegmentData" }, "typeCondition": { "kind": "NamedType", "name": { "kind": "Name", "value": "PeriodSegment" } }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "index" } }, { "kind": "Field", "name": { "kind": "Name", "value": "facts" } }, { "kind": "Field", "name": { "kind": "Name", "value": "learningElements" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "storyElements" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }] } }] } }] };
398
+ var PeriodDataFragmentDoc = { "kind": "Document", "definitions": [{ "kind": "FragmentDefinition", "name": { "kind": "Name", "value": "PeriodData" }, "typeCondition": { "kind": "NamedType", "name": { "kind": "Name", "value": "Period" } }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "index" } }, { "kind": "Field", "name": { "kind": "Name", "value": "activeSegmentIx" } }, { "kind": "Field", "name": { "kind": "Name", "value": "facts" } }, { "kind": "Field", "name": { "kind": "Name", "value": "segments" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "SegmentData" } }] } }] } }, ...SegmentDataFragmentDoc.definitions] };
399
+ var PlayerActionDataFragmentDoc = { "kind": "Document", "definitions": [{ "kind": "FragmentDefinition", "name": { "kind": "Name", "value": "PlayerActionData" }, "typeCondition": { "kind": "NamedType", "name": { "kind": "Name", "value": "PlayerAction" } }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "periodIx" } }, { "kind": "Field", "name": { "kind": "Name", "value": "segmentIx" } }, { "kind": "Field", "name": { "kind": "Name", "value": "type" } }, { "kind": "Field", "name": { "kind": "Name", "value": "facts" } }] } }] };
400
+ var PlayerDataFragmentDoc = { "kind": "Document", "definitions": [{ "kind": "FragmentDefinition", "name": { "kind": "Name", "value": "PlayerData" }, "typeCondition": { "kind": "NamedType", "name": { "kind": "Name", "value": "Player" } }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "isReady" } }, { "kind": "Field", "name": { "kind": "Name", "value": "role" } }, { "kind": "Field", "name": { "kind": "Name", "value": "name" } }, { "kind": "Field", "name": { "kind": "Name", "value": "avatar" } }, { "kind": "Field", "name": { "kind": "Name", "value": "location" } }, { "kind": "Field", "name": { "kind": "Name", "value": "color" } }, { "kind": "Field", "name": { "kind": "Name", "value": "facts" } }, { "kind": "Field", "name": { "kind": "Name", "value": "experience" } }, { "kind": "Field", "name": { "kind": "Name", "value": "experienceToNext" } }, { "kind": "Field", "name": { "kind": "Name", "value": "achievementKeys" } }, { "kind": "Field", "name": { "kind": "Name", "value": "achievements" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "count" } }, { "kind": "Field", "name": { "kind": "Name", "value": "achievement" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "name" } }, { "kind": "Field", "name": { "kind": "Name", "value": "description" } }, { "kind": "Field", "name": { "kind": "Name", "value": "image" } }, { "kind": "Field", "name": { "kind": "Name", "value": "reward" } }] } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "level" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "index" } }] } }] } }] };
401
+ var ResultDataFragmentDoc = { "kind": "Document", "definitions": [{ "kind": "FragmentDefinition", "name": { "kind": "Name", "value": "ResultData" }, "typeCondition": { "kind": "NamedType", "name": { "kind": "Name", "value": "PlayerResult" } }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "type" } }, { "kind": "Field", "name": { "kind": "Name", "value": "facts" } }, { "kind": "Field", "name": { "kind": "Name", "value": "period" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "index" } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "segment" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "index" } }] } }] } }] };
402
+ var ActivateNextPeriodDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "mutation", "name": { "kind": "Name", "value": "ActivateNextPeriod" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "gameId" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "Int" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "activateNextPeriod" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "gameId" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "gameId" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "GameData" } }, { "kind": "Field", "name": { "kind": "Name", "value": "periods" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "PeriodData" } }] } }] } }] } }, ...GameDataFragmentDoc.definitions, ...PeriodDataFragmentDoc.definitions] };
403
+ var ActivateNextSegmentDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "mutation", "name": { "kind": "Name", "value": "ActivateNextSegment" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "gameId" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "Int" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "activateNextSegment" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "gameId" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "gameId" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "GameData" } }, { "kind": "Field", "name": { "kind": "Name", "value": "periods" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "PeriodData" } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "players" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "PlayerData" } }] } }] } }] } }, ...GameDataFragmentDoc.definitions, ...PeriodDataFragmentDoc.definitions, ...PlayerDataFragmentDoc.definitions] };
404
+ var AddGamePeriodDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "mutation", "name": { "kind": "Name", "value": "AddGamePeriod" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "gameId" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "Int" } } } }, { "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "facts" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "PeriodFactsInput" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "addGamePeriod" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "gameId" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "gameId" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "facts" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "facts" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "PeriodData" } }] } }] } }, ...PeriodDataFragmentDoc.definitions] };
405
+ var AddPeriodSegmentDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "mutation", "name": { "kind": "Name", "value": "AddPeriodSegment" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "gameId" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "Int" } } } }, { "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "periodIx" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "Int" } } } }, { "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "facts" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "PeriodSegmentFactsInput" } } } }, { "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "storyElements" } }, "type": { "kind": "ListType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } } }, { "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "learningElements" } }, "type": { "kind": "ListType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "addPeriodSegment" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "gameId" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "gameId" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "periodIx" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "periodIx" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "facts" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "facts" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "storyElements" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "storyElements" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "learningElements" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "learningElements" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "SegmentData" } }] } }] } }, ...SegmentDataFragmentDoc.definitions] };
406
+ var CreateGameDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "mutation", "name": { "kind": "Name", "value": "CreateGame" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "name" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } } }, { "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "playerCount" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "Int" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "createGame" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "name" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "name" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "playerCount" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "playerCount" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "GameData" } }] } }] } }, ...GameDataFragmentDoc.definitions] };
407
+ var LoginAsTeamDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "mutation", "name": { "kind": "Name", "value": "LoginAsTeam" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "token" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "loginAsTeam" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "token" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "token" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "PlayerData" } }] } }] } }, ...PlayerDataFragmentDoc.definitions] };
408
+ var PerformActionDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "mutation", "name": { "kind": "Name", "value": "PerformAction" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "type" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } } }, { "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "payload" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "performAction" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "type" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "type" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "payload" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "payload" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "ResultData" } }] } }] } }, ...ResultDataFragmentDoc.definitions] };
409
+ var UpdatePlayerDataDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "mutation", "name": { "kind": "Name", "value": "UpdatePlayerData" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "name" } }, "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } }, { "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "avatar" } }, "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } }, { "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "color" } }, "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } }, { "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "facts" } }, "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "updatePlayerData" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "name" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "name" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "avatar" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "avatar" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "color" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "color" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "facts" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "facts" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "PlayerData" } }] } }] } }, ...PlayerDataFragmentDoc.definitions] };
410
+ var GameDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "Game" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "id" } }, "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "Int" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "game" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "id" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "id" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "GameData" } }, { "kind": "Field", "name": { "kind": "Name", "value": "activePeriod" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "activeSegmentIx" } }, { "kind": "Field", "name": { "kind": "Name", "value": "segments" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }] } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "periods" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "PeriodData" } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "players" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "isReady" } }, { "kind": "Field", "name": { "kind": "Name", "value": "role" } }, { "kind": "Field", "name": { "kind": "Name", "value": "name" } }, { "kind": "Field", "name": { "kind": "Name", "value": "avatar" } }, { "kind": "Field", "name": { "kind": "Name", "value": "location" } }, { "kind": "Field", "name": { "kind": "Name", "value": "color" } }, { "kind": "Field", "name": { "kind": "Name", "value": "facts" } }, { "kind": "Field", "name": { "kind": "Name", "value": "experience" } }, { "kind": "Field", "name": { "kind": "Name", "value": "experienceToNext" } }, { "kind": "Field", "name": { "kind": "Name", "value": "token" } }] } }] } }] } }, ...GameDataFragmentDoc.definitions, ...PeriodDataFragmentDoc.definitions] };
411
+ var GamesDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "Games" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "games" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "GameData" } }] } }] } }, ...GameDataFragmentDoc.definitions] };
412
+ var LearningElementDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "LearningElement" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "id" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "ID" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "learningElement" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "id" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "id" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "element" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "LearningElementData" } }, { "kind": "Field", "name": { "kind": "Name", "value": "options" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "content" } }] } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "state" } }, { "kind": "Field", "name": { "kind": "Name", "value": "solution" } }] } }] } }, ...LearningElementDataFragmentDoc.definitions] };
413
+ var LearningElementsDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "LearningElements" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "learningElements" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "LearningElementData" } }] } }] } }, ...LearningElementDataFragmentDoc.definitions] };
414
+ var PastResultsDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "PastResults" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "result" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "currentGame" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "status" } }] } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "pastResults" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "ResultData" } }, { "kind": "Field", "name": { "kind": "Name", "value": "player" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "role" } }, { "kind": "Field", "name": { "kind": "Name", "value": "name" } }, { "kind": "Field", "name": { "kind": "Name", "value": "avatar" } }, { "kind": "Field", "name": { "kind": "Name", "value": "color" } }, { "kind": "Field", "name": { "kind": "Name", "value": "facts" } }, { "kind": "Field", "name": { "kind": "Name", "value": "experience" } }, { "kind": "Field", "name": { "kind": "Name", "value": "experienceToNext" } }, { "kind": "Field", "name": { "kind": "Name", "value": "level" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "index" } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "completedLearningElementIds" } }, { "kind": "Field", "name": { "kind": "Name", "value": "visitedStoryElementIds" } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "period" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "index" } }, { "kind": "Field", "name": { "kind": "Name", "value": "facts" } }] } }] } }] } }, ...ResultDataFragmentDoc.definitions] };
415
+ var ResultDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "Result" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "result" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "playerResult" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "ResultData" } }, { "kind": "Field", "name": { "kind": "Name", "value": "player" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "completedLearningElementIds" } }, { "kind": "Field", "name": { "kind": "Name", "value": "visitedStoryElementIds" } }] } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "previousResults" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "ResultData" } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "currentGame" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "status" } }, { "kind": "Field", "name": { "kind": "Name", "value": "periods" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "PeriodData" } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "activePeriod" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "PeriodData" } }, { "kind": "Field", "name": { "kind": "Name", "value": "activeSegment" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "index" } }, { "kind": "Field", "name": { "kind": "Name", "value": "facts" } }, { "kind": "Field", "name": { "kind": "Name", "value": "learningElements" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "title" } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "storyElements" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "type" } }, { "kind": "Field", "name": { "kind": "Name", "value": "title" } }, { "kind": "Field", "name": { "kind": "Name", "value": "content" } }, { "kind": "Field", "name": { "kind": "Name", "value": "contentRole" } }] } }] } }] } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "transactions" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "PlayerActionData" } }] } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "self" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "PlayerData" } }] } }] } }, ...ResultDataFragmentDoc.definitions, ...PeriodDataFragmentDoc.definitions, ...PlayerActionDataFragmentDoc.definitions, ...PlayerDataFragmentDoc.definitions] };
416
+ var ResultsDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "Results" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "results" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "ResultData" } }, { "kind": "Field", "name": { "kind": "Name", "value": "player" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "name" } }] } }] } }] } }, ...ResultDataFragmentDoc.definitions] };
417
+ var SelfDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "Self" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "self" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "FragmentSpread", "name": { "kind": "Name", "value": "PlayerData" } }] } }] } }, ...PlayerDataFragmentDoc.definitions] };
418
+
419
+ // src/services/AccountService.ts
420
+ var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
421
+ var import_node_assert = require("assert");
422
+ var import_nookies = require("nookies");
423
+ function createLoginToken({
424
+ sub,
425
+ role,
426
+ ...extra
427
+ }) {
428
+ (0, import_node_assert.strict)(typeof process.env.NEXTAUTH_SECRET === "string");
429
+ return import_jsonwebtoken.default.sign({ sub, role, ...extra }, process.env.NEXTAUTH_SECRET, {
430
+ expiresIn: "1 week"
431
+ });
432
+ }
433
+ async function loginAsTeam({ token }, ctx) {
434
+ const matchingPlayer = await ctx.prisma.player.findUnique({
435
+ where: { token },
436
+ include: {
437
+ level: true,
438
+ achievements: {
439
+ include: {
440
+ achievement: true
441
+ }
442
+ }
443
+ }
444
+ });
445
+ if (!matchingPlayer) {
446
+ throw new Error("INVALID_TOKEN");
447
+ }
448
+ try {
449
+ const jwt = createLoginToken({
450
+ gameId: matchingPlayer.gameId,
451
+ sub: matchingPlayer.id,
452
+ role: "PLAYER" /* PLAYER */,
453
+ token: matchingPlayer.token
454
+ });
455
+ (0, import_nookies.setCookie)(
456
+ ctx,
457
+ process.env.NODE_ENV === "production" ? "__Secure-next-auth.session-token" : "next-auth.session-token",
458
+ jwt,
459
+ {
460
+ path: "/",
461
+ maxAge: 60 * 60 * 24 * 7,
462
+ httpOnly: process.env.NODE_ENV === "production",
463
+ secure: process.env.NODE_ENV === "production"
464
+ }
465
+ );
466
+ } catch (err) {
467
+ console.error(err);
468
+ return null;
469
+ }
470
+ return matchingPlayer;
471
+ }
472
+
473
+ // ../../node_modules/nanoid/index.js
474
+ var import_crypto = __toESM(require("crypto"), 1);
475
+
476
+ // ../../node_modules/nanoid/url-alphabet/index.js
477
+ var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
478
+
479
+ // ../../node_modules/nanoid/index.js
480
+ var POOL_SIZE_MULTIPLIER = 128;
481
+ var pool;
482
+ var poolOffset;
483
+ var fillPool = (bytes) => {
484
+ if (!pool || pool.length < bytes) {
485
+ pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
486
+ import_crypto.default.randomFillSync(pool);
487
+ poolOffset = 0;
488
+ } else if (poolOffset + bytes > pool.length) {
489
+ import_crypto.default.randomFillSync(pool);
490
+ poolOffset = 0;
491
+ }
492
+ poolOffset += bytes;
493
+ };
494
+ var nanoid = (size = 21) => {
495
+ fillPool(size -= 0);
496
+ let id = "";
497
+ for (let i = poolOffset - size; i < poolOffset; i++) {
498
+ id += urlAlphabet[pool[i] & 63];
499
+ }
500
+ return id;
501
+ };
502
+
503
+ // src/services/GameService.ts
504
+ var import_ramda = require("ramda");
505
+ var yup = __toESM(require("yup"));
506
+
507
+ // src/lib/pubsub.ts
508
+ var import_graphql_yoga = require("graphql-yoga");
509
+ var pubSub = (0, import_graphql_yoga.createPubSub)();
510
+
511
+ // src/services/EventService.ts
512
+ async function receiveEvents({ events, ctx, prisma }) {
513
+ if (!Array.isArray(events))
514
+ return;
515
+ const definedEvents = await prisma.event.findMany({
516
+ include: {
517
+ achievements: true
518
+ }
519
+ });
520
+ const definedLevels = await prisma.playerLevel.findMany();
521
+ const promises = await Promise.all(
522
+ events.map(
523
+ async (event) => receiveEvent({ ...event, ctx }, definedEvents, definedLevels, prisma)
524
+ )
525
+ );
526
+ const results = prisma.$transaction(promises.flat());
527
+ return results;
528
+ }
529
+ function prepareAchievementData({
530
+ achievementId,
531
+ gameId,
532
+ periodIx,
533
+ playerId,
534
+ count
535
+ }) {
536
+ return {
537
+ count,
538
+ achievement: { connect: { id: achievementId } },
539
+ game: { connect: { id: gameId } },
540
+ period: { connect: { gameId_index: { gameId, index: periodIx } } },
541
+ player: { connect: { id: playerId } }
542
+ };
543
+ }
544
+ async function receiveEvent(event, definedEvents, definedLevels, prisma) {
545
+ var _a;
546
+ const matchingEvent = definedEvents.find((item) => item.id === event.type);
547
+ if (matchingEvent && ((_a = matchingEvent.achievements) == null ? void 0 : _a.length) > 0) {
548
+ const awardedAchievements = await matchingEvent.achievements.reduce(
549
+ async (acc, achievement) => {
550
+ var _a2;
551
+ if (achievement.when === "FIRST" /* First */ && event.ctx.achievements.includes(achievement.id)) {
552
+ return acc;
553
+ }
554
+ const existingInstance = await prisma.achievementInstance.findFirst({
555
+ where: {
556
+ achievement: {
557
+ id: achievement.id
558
+ },
559
+ player: {
560
+ id: event.ctx.args.playerId
561
+ }
562
+ }
563
+ });
564
+ let achievementInstance;
565
+ if (existingInstance) {
566
+ achievementInstance = await prisma.achievementInstance.update({
567
+ where: {
568
+ id: existingInstance.id
569
+ },
570
+ data: prepareAchievementData({
571
+ count: existingInstance.count + 1,
572
+ achievementId: achievement.id,
573
+ gameId: event.ctx.args.gameId,
574
+ periodIx: event.ctx.args.periodIx,
575
+ playerId: event.ctx.args.playerId
576
+ })
577
+ });
578
+ } else {
579
+ achievementInstance = await prisma.achievementInstance.create({
580
+ data: prepareAchievementData({
581
+ count: 1,
582
+ achievementId: achievement.id,
583
+ gameId: event.ctx.args.gameId,
584
+ periodIx: event.ctx.args.periodIx,
585
+ playerId: event.ctx.args.playerId
586
+ })
587
+ });
588
+ }
589
+ return {
590
+ achievements: [
591
+ ...acc.achievements,
592
+ {
593
+ achievement,
594
+ achievementInstance
595
+ }
596
+ ],
597
+ achievementKeys: [...acc.achievementKeys, achievement.id],
598
+ rewards: {
599
+ ...acc.rewards,
600
+ xp: (acc.rewards.xp ?? 0) + (((_a2 = achievement.reward) == null ? void 0 : _a2.xp) ?? 0)
601
+ }
602
+ };
603
+ },
604
+ {
605
+ achievements: [],
606
+ achievementKeys: [],
607
+ rewards: {}
608
+ }
609
+ );
610
+ const currentLevelPlus1 = definedLevels.find(
611
+ (level) => level.index === event.ctx.currentLevelIx + 1
612
+ );
613
+ const currentLevelPlus2 = definedLevels.find(
614
+ (level) => level.index === event.ctx.currentLevelIx + 2
615
+ );
616
+ if (awardedAchievements.achievements.length > 0) {
617
+ if (event.ctx.experience + awardedAchievements.rewards.xp >= currentLevelPlus1.requiredXP) {
618
+ publishUserNotification(
619
+ {
620
+ user: {
621
+ sub: event.ctx.args.playerId
622
+ }
623
+ },
624
+ [
625
+ {
626
+ type: "ACHIEVEMENT_RECEIVED" /* ACHIEVEMENT_RECEIVED */
627
+ }
628
+ ]
629
+ );
630
+ publishUserNotification(
631
+ {
632
+ user: {
633
+ sub: event.ctx.args.playerId
634
+ }
635
+ },
636
+ [
637
+ {
638
+ type: "LEVEL_UP" /* LEVEL_UP */
639
+ }
640
+ ]
641
+ );
642
+ return [
643
+ prisma.player.update({
644
+ where: {
645
+ id: event.ctx.args.playerId
646
+ },
647
+ data: {
648
+ experience: {
649
+ increment: awardedAchievements.rewards.xp
650
+ },
651
+ experienceToNext: currentLevelPlus2.requiredXP,
652
+ level: {
653
+ connect: {
654
+ index: currentLevelPlus1.index
655
+ }
656
+ },
657
+ achievementKeys: {
658
+ push: awardedAchievements.achievementKeys
659
+ }
660
+ }
661
+ })
662
+ ];
663
+ } else {
664
+ publishUserNotification(
665
+ {
666
+ user: {
667
+ sub: event.ctx.args.playerId
668
+ }
669
+ },
670
+ [
671
+ {
672
+ type: "ACHIEVEMENT_RECEIVED" /* ACHIEVEMENT_RECEIVED */
673
+ }
674
+ ]
675
+ );
676
+ return [
677
+ prisma.player.update({
678
+ where: {
679
+ id: event.ctx.args.playerId
680
+ },
681
+ data: {
682
+ experience: {
683
+ increment: awardedAchievements.rewards.xp
684
+ },
685
+ achievementKeys: {
686
+ push: awardedAchievements.achievementKeys
687
+ }
688
+ }
689
+ })
690
+ ];
691
+ }
692
+ }
693
+ return [];
694
+ }
695
+ return [];
696
+ }
697
+ function publishUserNotification(ctx, events) {
698
+ if (events && events.length > 0) {
699
+ pubSub.publish("user:events", ctx.user.sub, events);
700
+ }
701
+ }
702
+
703
+ // src/services/GameService.ts
704
+ async function createGame({ name, playerCount }, ctx, { roleAssigner }) {
705
+ return ctx.prisma.game.create({
706
+ data: {
707
+ name,
708
+ owner: {
709
+ connect: {
710
+ id: ctx.user.sub
711
+ }
712
+ },
713
+ players: {
714
+ create: (0, import_ramda.repeat)(0, playerCount).map((_, ix) => {
715
+ return {
716
+ facts: {},
717
+ token: nanoid(),
718
+ role: roleAssigner(ix),
719
+ level: {
720
+ connect: {
721
+ index: 0
722
+ }
723
+ }
724
+ };
725
+ })
726
+ }
727
+ },
728
+ include: {
729
+ players: true,
730
+ periods: true
731
+ }
732
+ });
733
+ }
734
+ async function addGamePeriod({ gameId, facts }, ctx, { schema, reducers }) {
735
+ var _a, _b, _c, _d;
736
+ const validatedFacts = schema.validateSync(facts);
737
+ const game = await ctx.prisma.game.findUnique({
738
+ where: {
739
+ id: gameId
740
+ },
741
+ include: {
742
+ periods: {
743
+ orderBy: {
744
+ index: "desc"
745
+ },
746
+ take: 1,
747
+ include: {
748
+ segments: {
749
+ orderBy: {
750
+ index: "desc"
751
+ },
752
+ take: 1
753
+ }
754
+ }
755
+ }
756
+ }
757
+ });
758
+ if (!game)
759
+ return null;
760
+ const index = ((_a = game.periods[0]) == null ? void 0 : _a.index) + 1 || 0;
761
+ const { result: initializedFacts } = reducers.Period.apply(validatedFacts, {
762
+ type: reducers.Period.ActionTypes.PERIOD_INITIALIZE,
763
+ payload: {
764
+ periodFacts: validatedFacts,
765
+ previousPeriodFacts: (_b = game.periods[0]) == null ? void 0 : _b.facts,
766
+ previousSegmentFacts: (_d = (_c = game.periods[0]) == null ? void 0 : _c.segments[0]) == null ? void 0 : _d.facts,
767
+ periodIx: index
768
+ }
769
+ });
770
+ return ctx.prisma.period.upsert({
771
+ where: {
772
+ gameId_index: {
773
+ gameId,
774
+ index
775
+ }
776
+ },
777
+ create: {
778
+ index,
779
+ facts: initializedFacts,
780
+ game: {
781
+ connect: {
782
+ id: gameId
783
+ }
784
+ },
785
+ previousPeriod: {
786
+ connect: index > 0 ? {
787
+ gameId_index: {
788
+ gameId,
789
+ index: index - 1
790
+ }
791
+ } : []
792
+ }
793
+ },
794
+ update: {
795
+ facts: initializedFacts
796
+ },
797
+ include: {
798
+ segments: {
799
+ include: {
800
+ learningElements: true,
801
+ storyElements: true
802
+ }
803
+ }
804
+ }
805
+ });
806
+ }
807
+ async function addPeriodSegment({
808
+ gameId,
809
+ periodIx,
810
+ facts,
811
+ learningElements,
812
+ storyElements
813
+ }, ctx, { schema, reducers }) {
814
+ var _a, _b;
815
+ const validatedFacts = schema.validateSync(facts);
816
+ const period = await ctx.prisma.period.findUnique({
817
+ where: {
818
+ gameId_index: {
819
+ gameId,
820
+ index: periodIx
821
+ }
822
+ },
823
+ include: {
824
+ segments: {
825
+ orderBy: {
826
+ index: "desc"
827
+ },
828
+ take: 1
829
+ }
830
+ }
831
+ });
832
+ if (!period)
833
+ return null;
834
+ const index = ((_a = period.segments[0]) == null ? void 0 : _a.index) + 1 || 0;
835
+ const { result: initializedFacts } = reducers.Segment.apply(validatedFacts, {
836
+ type: reducers.Segment.ActionTypes.SEGMENT_INITIALIZE,
837
+ payload: {
838
+ periodFacts: period.facts,
839
+ previousSegmentFacts: (_b = period.segments[0]) == null ? void 0 : _b.facts,
840
+ segmentIx: index,
841
+ segmentCount: 4,
842
+ periodIx
843
+ }
844
+ });
845
+ return ctx.prisma.periodSegment.upsert({
846
+ where: {
847
+ gameId_periodIx_index: {
848
+ gameId,
849
+ periodIx,
850
+ index
851
+ }
852
+ },
853
+ create: {
854
+ index,
855
+ facts: initializedFacts,
856
+ learningElements: {
857
+ connect: learningElements ? learningElements.map((item) => ({ id: item })) : []
858
+ },
859
+ storyElements: {
860
+ connect: storyElements ? storyElements.map((item) => ({ id: item })) : []
861
+ },
862
+ game: {
863
+ connect: {
864
+ id: gameId
865
+ }
866
+ },
867
+ periodIx,
868
+ period: {
869
+ connect: {
870
+ gameId_index: {
871
+ gameId,
872
+ index: periodIx
873
+ }
874
+ }
875
+ },
876
+ previousSegment: {
877
+ connect: index > 0 ? {
878
+ gameId_periodIx_index: {
879
+ gameId,
880
+ periodIx,
881
+ index: index - 1
882
+ }
883
+ } : []
884
+ }
885
+ },
886
+ update: {
887
+ facts: initializedFacts,
888
+ learningElements: {
889
+ connect: learningElements ? learningElements.map((item) => ({ id: item })) : []
890
+ },
891
+ storyElements: {
892
+ connect: storyElements ? storyElements.map((item) => ({ id: item })) : []
893
+ }
894
+ },
895
+ include: {
896
+ learningElements: true,
897
+ storyElements: true
898
+ }
899
+ });
900
+ }
901
+ async function activateNextPeriod({ gameId }, ctx, { reducers }) {
902
+ var _a, _b, _c, _d, _e;
903
+ const game = await ctx.prisma.game.findUnique({
904
+ where: {
905
+ id: gameId
906
+ },
907
+ include: {
908
+ players: true,
909
+ periods: true,
910
+ activePeriod: {
911
+ include: {
912
+ results: {
913
+ include: {
914
+ player: true
915
+ }
916
+ },
917
+ nextPeriod: true,
918
+ previousPeriod: {
919
+ include: {
920
+ results: {
921
+ include: {
922
+ player: true
923
+ }
924
+ }
925
+ }
926
+ },
927
+ activeSegment: {
928
+ include: {
929
+ results: {
930
+ include: {
931
+ player: true
932
+ }
933
+ }
934
+ }
935
+ },
936
+ decisions: {
937
+ include: {
938
+ player: true
939
+ }
940
+ }
941
+ }
942
+ }
943
+ }
944
+ });
945
+ if (!game)
946
+ return null;
947
+ const currentPeriodIx = game.activePeriodIx;
948
+ const currentSegmentIx = (_a = game.activePeriod) == null ? void 0 : _a.activeSegmentIx;
949
+ const nextPeriodIx = currentPeriodIx + 1;
950
+ switch (game.status) {
951
+ case "SCHEDULED" /* Scheduled */: {
952
+ const { results, extras } = computePeriodStartResults(
953
+ {
954
+ results: void 0,
955
+ players: game.players,
956
+ activePeriodIx: currentPeriodIx,
957
+ gameId: game.id,
958
+ periodFacts: (_b = game.periods) == null ? void 0 : _b[0].facts
959
+ },
960
+ ctx,
961
+ { reducers }
962
+ );
963
+ const result = await ctx.prisma.$transaction([
964
+ ctx.prisma.game.update({
965
+ where: {
966
+ id: gameId
967
+ },
968
+ data: {
969
+ status: "PREPARATION" /* Preparation */,
970
+ activePeriodIx: nextPeriodIx,
971
+ activePeriod: {
972
+ connect: {
973
+ gameId_index: {
974
+ gameId,
975
+ index: nextPeriodIx
976
+ }
977
+ }
978
+ }
979
+ }
980
+ }),
981
+ ctx.prisma.period.update({
982
+ where: {
983
+ gameId_index: {
984
+ gameId,
985
+ index: nextPeriodIx
986
+ }
987
+ },
988
+ data: {
989
+ results: {
990
+ create: results
991
+ }
992
+ }
993
+ }),
994
+ ...extras
995
+ ]);
996
+ return result;
997
+ }
998
+ case "RUNNING" /* Running */: {
999
+ if (!((_c = game.activePeriod) == null ? void 0 : _c.activeSegment) || !currentSegmentIx)
1000
+ return null;
1001
+ const { results, extras } = computeSegmentEndResults(game, ctx, {
1002
+ reducers
1003
+ });
1004
+ const { result: consolidatedFacts } = reducers.Period.apply(
1005
+ game.activePeriod.facts,
1006
+ {
1007
+ type: reducers.Period.ActionTypes.PERIOD_CONSOLIDATE,
1008
+ payload: {
1009
+ previousSegmentFacts: game.activePeriod.activeSegment.facts,
1010
+ periodIx: currentPeriodIx
1011
+ }
1012
+ }
1013
+ );
1014
+ const result = await ctx.prisma.$transaction([
1015
+ ctx.prisma.game.update({
1016
+ data: {
1017
+ status: "CONSOLIDATION" /* Consolidation */
1018
+ },
1019
+ where: {
1020
+ id: gameId
1021
+ }
1022
+ }),
1023
+ ctx.prisma.period.update({
1024
+ where: {
1025
+ gameId_index: {
1026
+ gameId,
1027
+ index: currentPeriodIx
1028
+ }
1029
+ },
1030
+ data: {
1031
+ facts: consolidatedFacts
1032
+ }
1033
+ }),
1034
+ ctx.prisma.periodSegment.update({
1035
+ where: {
1036
+ gameId_periodIx_index: {
1037
+ gameId,
1038
+ periodIx: currentPeriodIx,
1039
+ index: currentSegmentIx
1040
+ }
1041
+ },
1042
+ data: {
1043
+ results: {
1044
+ update: results
1045
+ }
1046
+ },
1047
+ include: {
1048
+ results: {
1049
+ include: {
1050
+ player: true
1051
+ }
1052
+ }
1053
+ }
1054
+ }),
1055
+ ...extras
1056
+ ]);
1057
+ return result;
1058
+ }
1059
+ case "CONSOLIDATION" /* Consolidation */: {
1060
+ if (!((_d = game.activePeriod) == null ? void 0 : _d.activeSegment))
1061
+ return null;
1062
+ const { results, extras, promises } = await computePeriodEndResults(
1063
+ {
1064
+ segmentResults: game.activePeriod.activeSegment.results,
1065
+ segmentFacts: game.activePeriod.activeSegment.facts,
1066
+ periodFacts: game.activePeriod.facts,
1067
+ periodDecisions: game.activePeriod.decisions,
1068
+ activePeriodIx: currentPeriodIx,
1069
+ gameId: game.id
1070
+ },
1071
+ ctx,
1072
+ { reducers }
1073
+ );
1074
+ await Promise.all(promises);
1075
+ const result = await ctx.prisma.$transaction([
1076
+ ctx.prisma.game.update({
1077
+ where: {
1078
+ id: gameId
1079
+ },
1080
+ data: {
1081
+ status: "RESULTS" /* Results */,
1082
+ activePeriodIx: nextPeriodIx,
1083
+ activePeriod: {
1084
+ connect: {
1085
+ gameId_index: {
1086
+ gameId,
1087
+ index: nextPeriodIx
1088
+ }
1089
+ }
1090
+ }
1091
+ }
1092
+ }),
1093
+ ctx.prisma.period.update({
1094
+ where: {
1095
+ gameId_index: {
1096
+ gameId,
1097
+ index: currentPeriodIx
1098
+ }
1099
+ },
1100
+ data: {
1101
+ results: {
1102
+ create: results
1103
+ }
1104
+ },
1105
+ include: {
1106
+ results: true
1107
+ }
1108
+ }),
1109
+ ...extras
1110
+ ]);
1111
+ return result;
1112
+ }
1113
+ case "RESULTS" /* Results */: {
1114
+ if (!((_e = game.activePeriod) == null ? void 0 : _e.nextPeriod)) {
1115
+ return null;
1116
+ }
1117
+ const { results, extras } = computePeriodStartResults(
1118
+ {
1119
+ results: game.activePeriod.previousPeriod[0].results,
1120
+ players: game.players,
1121
+ activePeriodIx: currentPeriodIx,
1122
+ gameId: game.id,
1123
+ periodFacts: game.activePeriod.facts
1124
+ },
1125
+ ctx,
1126
+ { reducers }
1127
+ );
1128
+ const result = await ctx.prisma.$transaction([
1129
+ ctx.prisma.game.update({
1130
+ where: {
1131
+ id: gameId
1132
+ },
1133
+ data: {
1134
+ status: "PREPARATION" /* Preparation */
1135
+ }
1136
+ }),
1137
+ ctx.prisma.period.update({
1138
+ where: {
1139
+ gameId_index: {
1140
+ gameId,
1141
+ index: currentPeriodIx
1142
+ }
1143
+ },
1144
+ data: {
1145
+ results: {
1146
+ create: results
1147
+ }
1148
+ }
1149
+ }),
1150
+ ...extras
1151
+ ]);
1152
+ return result;
1153
+ }
1154
+ default:
1155
+ return null;
1156
+ }
1157
+ }
1158
+ async function activateNextSegment({ gameId }, ctx, { reducers }) {
1159
+ var _a, _b;
1160
+ const game = await ctx.prisma.game.findUnique({
1161
+ where: {
1162
+ id: gameId
1163
+ },
1164
+ include: {
1165
+ players: true,
1166
+ periods: true,
1167
+ segments: true,
1168
+ activePeriod: {
1169
+ include: {
1170
+ results: {
1171
+ include: {
1172
+ player: true
1173
+ }
1174
+ },
1175
+ activeSegment: {
1176
+ include: {
1177
+ nextSegment: true,
1178
+ results: {
1179
+ include: {
1180
+ player: true
1181
+ }
1182
+ }
1183
+ }
1184
+ }
1185
+ }
1186
+ }
1187
+ }
1188
+ });
1189
+ if (!(game == null ? void 0 : game.activePeriod))
1190
+ return null;
1191
+ const currentPeriodIx = game.activePeriodIx;
1192
+ const currentSegmentIx = game.activePeriod.activeSegmentIx;
1193
+ const nextSegmentIx = currentSegmentIx + 1;
1194
+ switch (game.status) {
1195
+ case "PREPARATION" /* Preparation */:
1196
+ case "PAUSED" /* Paused */: {
1197
+ const { results, extras } = computeSegmentStartResults(game, ctx, {
1198
+ reducers
1199
+ });
1200
+ const result = await ctx.prisma.$transaction([
1201
+ ctx.prisma.game.update({
1202
+ where: {
1203
+ id: gameId
1204
+ },
1205
+ data: {
1206
+ status: "RUNNING" /* Running */
1207
+ }
1208
+ }),
1209
+ ctx.prisma.period.update({
1210
+ where: {
1211
+ gameId_index: {
1212
+ gameId,
1213
+ index: currentPeriodIx
1214
+ }
1215
+ },
1216
+ data: {
1217
+ activeSegmentIx: nextSegmentIx,
1218
+ activeSegment: {
1219
+ connect: {
1220
+ gameId_periodIx_index: {
1221
+ gameId,
1222
+ periodIx: currentPeriodIx,
1223
+ index: nextSegmentIx
1224
+ }
1225
+ }
1226
+ }
1227
+ }
1228
+ }),
1229
+ ctx.prisma.periodSegment.update({
1230
+ where: {
1231
+ gameId_periodIx_index: {
1232
+ gameId,
1233
+ periodIx: currentPeriodIx,
1234
+ index: nextSegmentIx
1235
+ }
1236
+ },
1237
+ data: {
1238
+ results: {
1239
+ create: results
1240
+ }
1241
+ }
1242
+ }),
1243
+ ...extras
1244
+ ]);
1245
+ try {
1246
+ await ctx.prisma.player.updateMany({
1247
+ where: {
1248
+ game: {
1249
+ id: gameId
1250
+ }
1251
+ },
1252
+ data: {
1253
+ isReady: false
1254
+ }
1255
+ });
1256
+ } catch (e) {
1257
+ console.error(e);
1258
+ }
1259
+ return result;
1260
+ }
1261
+ case "RUNNING" /* Running */: {
1262
+ if (!((_b = (_a = game.activePeriod) == null ? void 0 : _a.activeSegment) == null ? void 0 : _b.nextSegment)) {
1263
+ return null;
1264
+ }
1265
+ const { results, extras } = computeSegmentEndResults(game, ctx, {
1266
+ reducers
1267
+ });
1268
+ const result = await ctx.prisma.$transaction([
1269
+ ctx.prisma.game.update({
1270
+ where: { id: gameId },
1271
+ data: {
1272
+ status: "PAUSED" /* Paused */
1273
+ }
1274
+ }),
1275
+ ctx.prisma.periodSegment.update({
1276
+ where: {
1277
+ gameId_periodIx_index: {
1278
+ gameId,
1279
+ periodIx: currentPeriodIx,
1280
+ index: currentSegmentIx
1281
+ }
1282
+ },
1283
+ data: {
1284
+ results: {
1285
+ update: results
1286
+ }
1287
+ },
1288
+ include: {
1289
+ results: true
1290
+ }
1291
+ }),
1292
+ ...extras
1293
+ ]);
1294
+ return result;
1295
+ }
1296
+ default:
1297
+ return null;
1298
+ }
1299
+ }
1300
+ var PlayerFactsSchema = yup.object({
1301
+ location: yup.string().default("Zurich")
1302
+ });
1303
+ async function updatePlayerData({ name, avatar, color, facts }, ctx) {
1304
+ if ((0, import_ramda.none)(Boolean, [name, avatar, color, facts])) {
1305
+ return null;
1306
+ }
1307
+ let data = {};
1308
+ if (name) {
1309
+ data["name"] = name;
1310
+ }
1311
+ if (avatar) {
1312
+ data["avatar"] = avatar;
1313
+ }
1314
+ if (color) {
1315
+ data["color"] = color;
1316
+ }
1317
+ if (facts) {
1318
+ data["facts"] = PlayerFactsSchema.validateSync(facts, {
1319
+ stripUnknown: true
1320
+ });
1321
+ }
1322
+ const player = await ctx.prisma.player.update({
1323
+ where: {
1324
+ id: ctx.user.sub
1325
+ },
1326
+ data,
1327
+ include: {
1328
+ level: true,
1329
+ achievements: {
1330
+ include: {
1331
+ achievement: true
1332
+ }
1333
+ }
1334
+ }
1335
+ });
1336
+ return player;
1337
+ }
1338
+ async function getGames(args, ctx) {
1339
+ return ctx.prisma.game.findMany();
1340
+ }
1341
+ async function getGame(args, ctx) {
1342
+ const gameId = args.id ?? ctx.user.gameId;
1343
+ if (!gameId) {
1344
+ return null;
1345
+ }
1346
+ return ctx.prisma.game.findUnique({
1347
+ where: {
1348
+ id: args.id
1349
+ },
1350
+ include: {
1351
+ players: {
1352
+ include: {
1353
+ level: true,
1354
+ achievements: true
1355
+ }
1356
+ },
1357
+ periods: {
1358
+ orderBy: {
1359
+ index: "asc"
1360
+ },
1361
+ include: {
1362
+ segments: {
1363
+ orderBy: {
1364
+ index: "asc"
1365
+ },
1366
+ include: {
1367
+ learningElements: true,
1368
+ storyElements: true
1369
+ }
1370
+ }
1371
+ }
1372
+ },
1373
+ activePeriod: {
1374
+ include: {
1375
+ segments: true,
1376
+ activeSegment: true
1377
+ }
1378
+ }
1379
+ }
1380
+ });
1381
+ }
1382
+ async function getGameFromContext(ctx) {
1383
+ return ctx.prisma.game.findUnique({
1384
+ where: {
1385
+ id: ctx.user.gameId
1386
+ },
1387
+ include: {
1388
+ activePeriod: true
1389
+ }
1390
+ });
1391
+ }
1392
+ async function getLearningElements(args, ctx) {
1393
+ return ctx.prisma.learningElement.findMany({
1394
+ include: {
1395
+ options: true
1396
+ }
1397
+ });
1398
+ }
1399
+ function mapAction({ ctx, gameId, activePeriodIx, playerId }) {
1400
+ return (action) => ctx.prisma.playerAction.create({
1401
+ data: {
1402
+ type: action.type,
1403
+ facts: action.facts,
1404
+ game: {
1405
+ connect: { id: gameId }
1406
+ },
1407
+ player: {
1408
+ connect: { id: playerId }
1409
+ },
1410
+ periodIx: activePeriodIx,
1411
+ period: {
1412
+ connect: {
1413
+ gameId_index: {
1414
+ gameId,
1415
+ index: activePeriodIx
1416
+ }
1417
+ }
1418
+ },
1419
+ segmentIx: typeof action.segment === "number" ? action.segment : void 0,
1420
+ segment: typeof action.segment === "number" ? {
1421
+ connect: {
1422
+ gameId_periodIx_index: {
1423
+ gameId,
1424
+ periodIx: activePeriodIx,
1425
+ index: action.segment
1426
+ }
1427
+ }
1428
+ } : void 0
1429
+ }
1430
+ });
1431
+ }
1432
+ function computePeriodStartResults({ results, players, activePeriodIx, gameId, periodFacts }, ctx, { reducers }) {
1433
+ const currentPeriodIx = activePeriodIx;
1434
+ const nextPeriodIx = currentPeriodIx + 1;
1435
+ let extras = [];
1436
+ if (currentPeriodIx >= 0) {
1437
+ const result2 = results.filter((result3) => result3.type === "PERIOD_END" /* PeriodEnd */).map((result3, ix, allResults) => {
1438
+ const { result: facts, actions } = reducers.PeriodResult.apply(result3, {
1439
+ type: reducers.PeriodResult.ActionTypes.PERIOD_RESULTS_START,
1440
+ payload: {
1441
+ playerRole: result3.player.role ?? result3.player.connect.role,
1442
+ initialCash: periodFacts.initialCash
1443
+ }
1444
+ });
1445
+ const mapper = mapAction({
1446
+ ctx,
1447
+ gameId,
1448
+ activePeriodIx: currentPeriodIx,
1449
+ playerId: result3.player.id
1450
+ });
1451
+ if (actions && actions.length > 0) {
1452
+ extras = [...extras, ...actions.map(mapper)];
1453
+ }
1454
+ return {
1455
+ type: "PERIOD_START" /* PeriodStart */,
1456
+ periodIx: currentPeriodIx,
1457
+ facts,
1458
+ player: {
1459
+ connect: {
1460
+ id: result3.player.id ?? result3.player.connect.id
1461
+ }
1462
+ },
1463
+ game: {
1464
+ connect: {
1465
+ id: gameId
1466
+ }
1467
+ }
1468
+ };
1469
+ });
1470
+ return {
1471
+ results: result2,
1472
+ extras
1473
+ };
1474
+ }
1475
+ const result = players.map((player, ix, allPlayers) => {
1476
+ const { result: facts, actions } = reducers.PeriodResult.apply(
1477
+ {},
1478
+ {
1479
+ type: reducers.PeriodResult.ActionTypes.PERIOD_RESULTS_INITIALIZE,
1480
+ payload: {
1481
+ playerRole: player.role,
1482
+ initialCash: periodFacts.initialCash
1483
+ }
1484
+ }
1485
+ );
1486
+ const mapper = mapAction({
1487
+ ctx,
1488
+ gameId,
1489
+ activePeriodIx: nextPeriodIx,
1490
+ playerId: player.id
1491
+ });
1492
+ if (actions && actions.length > 0) {
1493
+ extras = [...extras, ...actions.map(mapper)];
1494
+ }
1495
+ return {
1496
+ type: "PERIOD_START" /* PeriodStart */,
1497
+ periodIx: nextPeriodIx,
1498
+ facts,
1499
+ player: {
1500
+ connect: {
1501
+ id: player.id
1502
+ }
1503
+ },
1504
+ game: {
1505
+ connect: {
1506
+ id: gameId
1507
+ }
1508
+ }
1509
+ };
1510
+ });
1511
+ return {
1512
+ results: result,
1513
+ extras
1514
+ };
1515
+ }
1516
+ async function computePeriodEndResults({
1517
+ segmentResults,
1518
+ periodFacts,
1519
+ periodDecisions,
1520
+ segmentFacts,
1521
+ activePeriodIx,
1522
+ gameId
1523
+ }, ctx, { reducers }) {
1524
+ let extras = [];
1525
+ let promises = [];
1526
+ const results = segmentResults.filter((result) => result.type === "SEGMENT_END" /* SegmentEnd */).map((result, ix, allResults) => {
1527
+ const consolidationDecisions = periodDecisions.find(
1528
+ (decision) => decision.playerId === result.playerId
1529
+ );
1530
+ const {
1531
+ result: facts,
1532
+ actions,
1533
+ events
1534
+ } = reducers.PeriodResult.apply(result.facts, {
1535
+ type: reducers.PeriodResult.ActionTypes.PERIOD_RESULTS_END,
1536
+ payload: {
1537
+ interestRate: periodFacts.interestRate,
1538
+ spotPrice: segmentFacts.spotPrice,
1539
+ futuresPrice: segmentFacts.futuresPrice,
1540
+ randomSeed: periodFacts.randomSeed,
1541
+ initialSpotPrice: periodFacts.initialSpotPrice,
1542
+ playerRole: result.player.role,
1543
+ playerLevel: result.player.levelIx + 1,
1544
+ playerExperience: result.player.experience,
1545
+ storageCostPerItem: periodFacts.storageCostPerItem,
1546
+ trendE: periodFacts.trendE,
1547
+ trendGap: periodFacts.trendGap,
1548
+ consolidationDecisions,
1549
+ cashInflowTotal: segmentFacts.cashInflowTotal,
1550
+ periodIx: activePeriodIx
1551
+ }
1552
+ });
1553
+ const mapper = mapAction({
1554
+ ctx,
1555
+ gameId,
1556
+ activePeriodIx,
1557
+ playerId: result.player.id
1558
+ });
1559
+ if (actions && actions.length > 0) {
1560
+ extras = [...extras, ...actions.map(mapper)];
1561
+ }
1562
+ promises = [
1563
+ ...promises,
1564
+ receiveEvents({
1565
+ events,
1566
+ ctx: {
1567
+ args: {
1568
+ playerId: result.player.id,
1569
+ periodIx: activePeriodIx,
1570
+ gameId
1571
+ },
1572
+ user: ctx.user,
1573
+ achievements: result.player.achievementKeys,
1574
+ experience: result.player.experience,
1575
+ currentLevelIx: result.player.levelIx
1576
+ },
1577
+ prisma: ctx.prisma
1578
+ })
1579
+ ];
1580
+ return {
1581
+ type: "PERIOD_END" /* PeriodEnd */,
1582
+ periodIx: activePeriodIx,
1583
+ facts,
1584
+ player: {
1585
+ connect: {
1586
+ id: result.playerId
1587
+ }
1588
+ },
1589
+ game: {
1590
+ connect: {
1591
+ id: gameId
1592
+ }
1593
+ }
1594
+ };
1595
+ });
1596
+ return {
1597
+ extras,
1598
+ results,
1599
+ promises
1600
+ };
1601
+ }
1602
+ function computeSegmentStartResults(game, ctx, { reducers }) {
1603
+ const currentSegmentIx = game.activePeriod.activeSegmentIx;
1604
+ const nextSegmentIx = currentSegmentIx + 1;
1605
+ let extras = [];
1606
+ if (currentSegmentIx >= 0) {
1607
+ const results2 = game.activePeriod.activeSegment.results.filter((result) => result.type === "SEGMENT_END" /* SegmentEnd */).reduce((acc, result, ix, allResults) => {
1608
+ const { result: facts, actions } = reducers.SegmentResult.apply(
1609
+ result.facts,
1610
+ {
1611
+ type: reducers.SegmentResult.ActionTypes.SEGMENT_RESULTS_START,
1612
+ payload: {
1613
+ playerRole: result.player.role,
1614
+ interestRate: game.activePeriod.facts.interestRate,
1615
+ futuresPriceNext: game.activePeriod.activeSegment.nextSegment.facts.futuresPrice,
1616
+ futuresPriceCurrent: game.activePeriod.activeSegment.facts.futuresPrice,
1617
+ spotPriceNext: game.activePeriod.activeSegment.nextSegment.facts.spotPrice,
1618
+ segmentIx: nextSegmentIx,
1619
+ cashInflow: game.activePeriod.activeSegment.nextSegment.facts.cashInflow
1620
+ }
1621
+ }
1622
+ );
1623
+ const mapper = mapAction({
1624
+ ctx,
1625
+ gameId: game.id,
1626
+ activePeriodIx: game.activePeriodIx,
1627
+ playerId: result.player.id
1628
+ });
1629
+ if (actions && actions.length > 0) {
1630
+ extras = [...extras, ...actions.map(mapper)];
1631
+ }
1632
+ const common = {
1633
+ facts,
1634
+ periodIx: game.activePeriodIx,
1635
+ segmentIx: nextSegmentIx,
1636
+ player: {
1637
+ connect: {
1638
+ id: result.playerId
1639
+ }
1640
+ },
1641
+ period: {
1642
+ connect: {
1643
+ id: game.activePeriodId
1644
+ }
1645
+ },
1646
+ game: {
1647
+ connect: {
1648
+ id: game.id
1649
+ }
1650
+ }
1651
+ };
1652
+ return [
1653
+ ...acc,
1654
+ {
1655
+ ...common,
1656
+ type: "SEGMENT_START" /* SegmentStart */
1657
+ },
1658
+ {
1659
+ ...common,
1660
+ type: "SEGMENT_END" /* SegmentEnd */
1661
+ }
1662
+ ];
1663
+ }, []);
1664
+ return {
1665
+ results: results2,
1666
+ extras
1667
+ };
1668
+ }
1669
+ const results = game.activePeriod.results.filter((result) => result.type === "PERIOD_START" /* PeriodStart */).reduce((acc, result, ix, allResults) => {
1670
+ const { result: facts } = reducers.SegmentResult.apply(result.facts, {
1671
+ type: reducers.SegmentResult.ActionTypes.SEGMENT_RESULTS_INITIALIZE,
1672
+ payload: {
1673
+ cashBalance: result.facts.cashBalance,
1674
+ storageAmount: result.facts.storageAmount,
1675
+ spotPrice: game.activePeriod.facts.initialSpotPrice,
1676
+ playerRole: result.player.role
1677
+ }
1678
+ });
1679
+ const common = {
1680
+ facts,
1681
+ periodIx: game.activePeriodIx,
1682
+ segmentIx: nextSegmentIx,
1683
+ player: {
1684
+ connect: {
1685
+ id: result.playerId
1686
+ }
1687
+ },
1688
+ period: {
1689
+ connect: {
1690
+ id: game.activePeriodId
1691
+ }
1692
+ },
1693
+ game: {
1694
+ connect: {
1695
+ id: game.id
1696
+ }
1697
+ }
1698
+ };
1699
+ return [
1700
+ ...acc,
1701
+ {
1702
+ ...common,
1703
+ type: "SEGMENT_START" /* SegmentStart */
1704
+ },
1705
+ {
1706
+ ...common,
1707
+ type: "SEGMENT_END" /* SegmentEnd */
1708
+ }
1709
+ ];
1710
+ }, []);
1711
+ return {
1712
+ results,
1713
+ extras
1714
+ };
1715
+ }
1716
+ function computeSegmentEndResults(game, ctx, { reducers }) {
1717
+ let extras = [];
1718
+ const results = game.activePeriod.activeSegment.results.filter((result) => result.type === "SEGMENT_END" /* SegmentEnd */).map((result, ix, allResults) => {
1719
+ const { result: facts, actions } = reducers.SegmentResult.apply(
1720
+ result.facts,
1721
+ {
1722
+ type: reducers.SegmentResult.ActionTypes.SEGMENT_RESULTS_END,
1723
+ payload: {
1724
+ storageCostPerItem: game.activePeriod.facts.storageCostPerItem,
1725
+ segmentIx: game.activePeriod.activeSegmentIx
1726
+ }
1727
+ }
1728
+ );
1729
+ const mapper = mapAction({
1730
+ ctx,
1731
+ gameId: game.id,
1732
+ activePeriodIx: game.activePeriodIx,
1733
+ playerId: result.player.id
1734
+ });
1735
+ if (actions && actions.length > 0) {
1736
+ extras = [...extras, ...actions.map(mapper)];
1737
+ }
1738
+ return {
1739
+ where: {
1740
+ periodIx_segmentIx_playerId_type: {
1741
+ periodIx: game.activePeriodIx,
1742
+ segmentIx: game.activePeriod.activeSegmentIx,
1743
+ playerId: result.playerId,
1744
+ type: "SEGMENT_END" /* SegmentEnd */
1745
+ }
1746
+ },
1747
+ data: {
1748
+ facts,
1749
+ game: {
1750
+ connect: {
1751
+ id: game.id
1752
+ }
1753
+ }
1754
+ }
1755
+ };
1756
+ });
1757
+ return {
1758
+ results,
1759
+ extras
1760
+ };
1761
+ }
1762
+
1763
+ // src/services/PlayService.ts
1764
+ async function performAction(args, ctx, { reducers }) {
1765
+ var _a;
1766
+ const periodIx_segmentIx_playerId_type = {
1767
+ periodIx: args.periodIx,
1768
+ segmentIx: args.segmentIx,
1769
+ playerId: args.playerId,
1770
+ type: "SEGMENT_END" /* SegmentEnd */
1771
+ };
1772
+ const previousResult = await ctx.prisma.playerResult.findUnique({
1773
+ where: {
1774
+ periodIx_segmentIx_playerId_type
1775
+ },
1776
+ include: {
1777
+ game: true,
1778
+ segment: true,
1779
+ period: true,
1780
+ player: true
1781
+ }
1782
+ });
1783
+ if (!previousResult)
1784
+ return null;
1785
+ if (previousResult.game.status !== "RUNNING" /* Running */) {
1786
+ throw new Error("ACTIONS_NOT_ALLOWED");
1787
+ }
1788
+ const { result, events, notifications, isDirty, extras } = reducers.Actions.apply(previousResult.facts, {
1789
+ type: args.actionType,
1790
+ payload: {
1791
+ playerArgs: args.facts,
1792
+ segmentFacts: (_a = previousResult.segment) == null ? void 0 : _a.facts,
1793
+ periodFacts: previousResult.period.facts
1794
+ }
1795
+ });
1796
+ publishUserNotification(ctx, notifications);
1797
+ await receiveEvents({
1798
+ events,
1799
+ ctx: {
1800
+ user: ctx.user,
1801
+ args,
1802
+ achievements: previousResult.player.achievementKeys,
1803
+ experience: previousResult.player.experience,
1804
+ currentLevelIx: previousResult.player.levelIx
1805
+ },
1806
+ prisma: ctx.prisma
1807
+ });
1808
+ if (!isDirty) {
1809
+ return previousResult;
1810
+ }
1811
+ const [updatedResult, _] = await ctx.prisma.$transaction([
1812
+ ctx.prisma.playerResult.update({
1813
+ where: {
1814
+ periodIx_segmentIx_playerId_type
1815
+ },
1816
+ data: {
1817
+ facts: result
1818
+ },
1819
+ include: {
1820
+ period: true
1821
+ }
1822
+ }),
1823
+ ctx.prisma.playerAction.create({
1824
+ data: {
1825
+ periodIx: args.periodIx,
1826
+ period: {
1827
+ connect: {
1828
+ gameId_index: {
1829
+ gameId: args.gameId,
1830
+ index: args.periodIx
1831
+ }
1832
+ }
1833
+ },
1834
+ segmentIx: args.segmentIx,
1835
+ segment: {
1836
+ connect: {
1837
+ gameId_periodIx_index: {
1838
+ gameId: args.gameId,
1839
+ periodIx: args.periodIx,
1840
+ index: args.segmentIx
1841
+ }
1842
+ }
1843
+ },
1844
+ game: {
1845
+ connect: {
1846
+ id: args.gameId
1847
+ }
1848
+ },
1849
+ player: {
1850
+ connect: {
1851
+ id: args.playerId
1852
+ }
1853
+ },
1854
+ type: args.actionType,
1855
+ facts: {
1856
+ ...args.facts,
1857
+ ...extras
1858
+ }
1859
+ }
1860
+ })
1861
+ ]);
1862
+ return updatedResult;
1863
+ }
1864
+ async function saveDecisions(args, ctx) {
1865
+ const game = await ctx.prisma.game.findUnique({
1866
+ where: {
1867
+ id: ctx.user.gameId
1868
+ },
1869
+ include: {
1870
+ activePeriod: {
1871
+ include: {
1872
+ activeSegment: true
1873
+ }
1874
+ }
1875
+ }
1876
+ });
1877
+ if (!(game == null ? void 0 : game.activePeriod))
1878
+ return null;
1879
+ if (args.decisionType !== game.status) {
1880
+ throw new Error("INVALID_DECISION");
1881
+ }
1882
+ const periodIx = game.activePeriod.index;
1883
+ const savedDecision = ctx.prisma.playerDecision.upsert({
1884
+ where: {
1885
+ playerId_periodIx_type: {
1886
+ periodIx,
1887
+ playerId: ctx.user.sub,
1888
+ type: args.decisionType
1889
+ }
1890
+ },
1891
+ create: {
1892
+ facts: args.facts,
1893
+ type: args.decisionType,
1894
+ periodIx,
1895
+ period: {
1896
+ connect: {
1897
+ gameId_index: {
1898
+ gameId: game.id,
1899
+ index: periodIx
1900
+ }
1901
+ }
1902
+ },
1903
+ game: {
1904
+ connect: {
1905
+ id: game.id
1906
+ }
1907
+ },
1908
+ player: {
1909
+ connect: {
1910
+ id: ctx.user.sub
1911
+ }
1912
+ }
1913
+ },
1914
+ update: {
1915
+ facts: args.facts
1916
+ }
1917
+ });
1918
+ return savedDecision;
1919
+ }
1920
+ async function getPlayerResult(args, ctx) {
1921
+ const currentGame = await ctx.prisma.game.findUnique({
1922
+ where: {
1923
+ id: args.gameId
1924
+ },
1925
+ include: {
1926
+ activePeriod: {
1927
+ include: {
1928
+ activeSegment: {
1929
+ include: {
1930
+ learningElements: true,
1931
+ storyElements: true
1932
+ }
1933
+ },
1934
+ segments: {
1935
+ include: {
1936
+ learningElements: true,
1937
+ storyElements: true
1938
+ }
1939
+ }
1940
+ }
1941
+ },
1942
+ periods: {
1943
+ include: {
1944
+ segments: {
1945
+ include: {
1946
+ learningElements: true,
1947
+ storyElements: true
1948
+ }
1949
+ }
1950
+ }
1951
+ }
1952
+ }
1953
+ });
1954
+ if (!(currentGame == null ? void 0 : currentGame.activePeriod))
1955
+ return null;
1956
+ const previousResults = ctx.prisma.playerResult.findMany({
1957
+ where: {
1958
+ playerId: args.playerId,
1959
+ periodIx: {
1960
+ lte: currentGame.activePeriod.index
1961
+ }
1962
+ },
1963
+ include: {
1964
+ period: true
1965
+ }
1966
+ });
1967
+ const playerResult = await ctx.prisma.playerResult.findUnique({
1968
+ where: {
1969
+ periodIx_segmentIx_playerId_type: {
1970
+ periodIx: currentGame.activePeriodIx,
1971
+ segmentIx: currentGame.activePeriod.activeSegmentIx,
1972
+ playerId: args.playerId,
1973
+ type: "SEGMENT_END" /* SegmentEnd */
1974
+ }
1975
+ },
1976
+ include: {
1977
+ period: true,
1978
+ player: {
1979
+ include: {
1980
+ completedLearningElements: true,
1981
+ visitedStoryElements: true
1982
+ }
1983
+ }
1984
+ }
1985
+ });
1986
+ const transactions = ctx.prisma.playerAction.findMany({
1987
+ where: {
1988
+ player: {
1989
+ id: args.playerId
1990
+ }
1991
+ }
1992
+ });
1993
+ return {
1994
+ currentGame,
1995
+ playerResult,
1996
+ previousResults,
1997
+ transactions
1998
+ };
1999
+ }
2000
+ async function getPlayerData(args, ctx) {
2001
+ return ctx.prisma.player.findUnique({
2002
+ where: {
2003
+ id: args.playerId
2004
+ },
2005
+ include: {
2006
+ level: true,
2007
+ achievements: {
2008
+ include: {
2009
+ achievement: true
2010
+ }
2011
+ }
2012
+ }
2013
+ });
2014
+ }
2015
+ async function getLearningElement(args, ctx) {
2016
+ const playerWithLearningElements = await ctx.prisma.player.findUnique({
2017
+ where: {
2018
+ id: ctx.user.sub
2019
+ },
2020
+ include: {
2021
+ completedLearningElements: {
2022
+ where: {
2023
+ id: args.id
2024
+ }
2025
+ }
2026
+ }
2027
+ });
2028
+ if (!playerWithLearningElements)
2029
+ return null;
2030
+ const elementSolved = playerWithLearningElements.completedLearningElements.length > 0;
2031
+ const element = await ctx.prisma.learningElement.findUnique({
2032
+ where: {
2033
+ id: args.id
2034
+ },
2035
+ include: {
2036
+ options: true
2037
+ }
2038
+ });
2039
+ if (!element)
2040
+ return null;
2041
+ return {
2042
+ id: args.id,
2043
+ element: {
2044
+ ...element,
2045
+ feedback: elementSolved ? element.feedback : null
2046
+ },
2047
+ state: elementSolved ? "SOLVED" /* SOLVED */ : "NEW" /* NEW */,
2048
+ solution: elementSolved ? JSON.stringify(
2049
+ element.options.flatMap((option, ix) => option.correct ? [ix] : [])
2050
+ ) : null
2051
+ };
2052
+ }
2053
+ async function attemptLearningElement(args, ctx) {
2054
+ const learningElement = await ctx.prisma.learningElement.findUnique({
2055
+ where: { id: args.elementId },
2056
+ include: { options: true }
2057
+ });
2058
+ if (!learningElement)
2059
+ return null;
2060
+ try {
2061
+ const selectedOptions = JSON.parse(args.selection);
2062
+ const pointsAchieved = learningElement.options.reduce((acc, option, ix) => {
2063
+ if (option.correct && selectedOptions.includes(ix)) {
2064
+ return acc + 1;
2065
+ }
2066
+ if (!option.correct && !selectedOptions.includes(ix)) {
2067
+ return acc + 1;
2068
+ }
2069
+ return acc;
2070
+ }, 0);
2071
+ const pointsMax = learningElement.options.length;
2072
+ let updatedPlayer;
2073
+ if (pointsAchieved === pointsMax) {
2074
+ updatedPlayer = await ctx.prisma.player.update({
2075
+ where: {
2076
+ id: ctx.user.sub
2077
+ },
2078
+ data: {
2079
+ completedLearningElements: {
2080
+ connect: {
2081
+ id: args.elementId
2082
+ }
2083
+ }
2084
+ },
2085
+ include: {
2086
+ game: {
2087
+ select: {
2088
+ activePeriodIx: true
2089
+ }
2090
+ }
2091
+ }
2092
+ });
2093
+ await receiveEvents({
2094
+ events: [
2095
+ {
2096
+ type: "LEARNING_ELEMENT_SOLVED" /* LEARNING_ELEMENT_SOLVED */,
2097
+ facts: {
2098
+ elementId: args.elementId
2099
+ }
2100
+ }
2101
+ ],
2102
+ ctx: {
2103
+ user: ctx.user,
2104
+ args: {
2105
+ gameId: ctx.user.gameId,
2106
+ periodIx: updatedPlayer.game.activePeriodIx,
2107
+ playerId: ctx.user.sub
2108
+ },
2109
+ achievements: updatedPlayer.achievementKeys,
2110
+ experience: updatedPlayer.experience,
2111
+ currentLevelIx: updatedPlayer.levelIx
2112
+ },
2113
+ prisma: ctx.prisma
2114
+ });
2115
+ } else {
2116
+ publishUserNotification(ctx, [
2117
+ {
2118
+ type: "LEARNING_ELEMENT_INCORRECT" /* LEARNING_ELEMENT_INCORRECT */
2119
+ }
2120
+ ]);
2121
+ }
2122
+ return {
2123
+ id: args.elementId,
2124
+ pointsAchieved,
2125
+ pointsMax,
2126
+ element: {
2127
+ id: args.elementId,
2128
+ feedback: learningElement.feedback
2129
+ },
2130
+ player: updatedPlayer
2131
+ };
2132
+ } catch (e) {
2133
+ console.warn(e);
2134
+ return null;
2135
+ }
2136
+ }
2137
+ async function markStoryElement(args, ctx) {
2138
+ const storyElement = await ctx.prisma.storyElement.findUnique({
2139
+ where: { id: args.elementId }
2140
+ });
2141
+ if (!storyElement)
2142
+ return null;
2143
+ return ctx.prisma.player.update({
2144
+ where: {
2145
+ id: ctx.user.sub
2146
+ },
2147
+ data: {
2148
+ visitedStoryElements: {
2149
+ connect: {
2150
+ id: args.elementId
2151
+ }
2152
+ }
2153
+ }
2154
+ });
2155
+ }
2156
+ async function getPlayerResults(args, ctx) {
2157
+ const playerResults = await ctx.prisma.playerResult.findMany({
2158
+ where: {
2159
+ gameId: ctx.user.gameId
2160
+ },
2161
+ include: {
2162
+ period: true,
2163
+ player: true,
2164
+ segment: true
2165
+ }
2166
+ });
2167
+ return playerResults;
2168
+ }
2169
+ async function getPastResults(args, ctx) {
2170
+ const currentGame = await ctx.prisma.game.findUnique({
2171
+ where: { id: ctx.user.gameId }
2172
+ });
2173
+ if (!currentGame)
2174
+ return null;
2175
+ const playerResults = await ctx.prisma.playerResult.findMany({
2176
+ where: {
2177
+ gameId: ctx.user.gameId,
2178
+ periodIx: {
2179
+ lt: currentGame.activePeriodIx
2180
+ },
2181
+ type: "PERIOD_END"
2182
+ },
2183
+ include: {
2184
+ period: true,
2185
+ player: true
2186
+ }
2187
+ });
2188
+ return playerResults;
2189
+ }
2190
+ async function updateReadyState(args, ctx) {
2191
+ return ctx.prisma.player.update({
2192
+ where: {
2193
+ id: ctx.user.sub
2194
+ },
2195
+ data: {
2196
+ isReady: args.isReady
2197
+ }
2198
+ });
2199
+ }
2200
+
2201
+ // src/types/Period.ts
2202
+ var import_nexus6 = require("nexus");
2203
+ var yup2 = __toESM(require("yup"));
2204
+ var PeriodFactsSchema = yup2.object({
2205
+ spotTradingEnabled: yup2.boolean().default(true),
2206
+ futuresTradingEnabled: yup2.boolean().default(false),
2207
+ optionsTradingEnabled: yup2.boolean().default(false),
2208
+ interestRate: yup2.number().default(0.01),
2209
+ convenienceYield: yup2.number().default(8e-3),
2210
+ storageCostPerItem: yup2.number().default(50),
2211
+ initialSpotPrice: yup2.number(),
2212
+ randomSeed: yup2.number(),
2213
+ trendE: yup2.number().default(5e-3),
2214
+ trendGap: yup2.number().default(0.02)
2215
+ });
2216
+ var PeriodFactsInput = (0, import_nexus6.inputObjectType)({
2217
+ name: "PeriodFactsInput",
2218
+ definition(t) {
2219
+ t.boolean("spotTradingEnabled");
2220
+ t.boolean("futuresTradingEnabled");
2221
+ t.boolean("optionsTradingEnabled");
2222
+ t.float("interestRate");
2223
+ t.float("convenienceYield");
2224
+ t.int("storageCostPerItem");
2225
+ t.int("initialSpotPrice");
2226
+ t.int("randomSeed");
2227
+ t.float("trendE");
2228
+ t.float("trendGap");
2229
+ }
2230
+ });
2231
+ var PeriodSegmentFactsSchema = yup2.object({
2232
+ trendE: yup2.number(),
2233
+ trendGap: yup2.number()
2234
+ });
2235
+ var PeriodSegmentFactsInput = (0, import_nexus6.inputObjectType)({
2236
+ name: "PeriodSegmentFactsInput",
2237
+ definition(t) {
2238
+ t.float("trendE");
2239
+ t.float("trendGap");
2240
+ }
2241
+ });
2242
+
2243
+ // src/types/Mutation.ts
2244
+ var defaultReducers = {};
2245
+ function generateBaseMutations({
2246
+ reducers = defaultReducers,
2247
+ roleAssigner = () => "UNSET"
2248
+ } = {}) {
2249
+ return (0, import_nexus7.objectType)({
2250
+ name: "Mutation",
2251
+ definition(t) {
2252
+ t.field("updateReadyState", {
2253
+ type: Player,
2254
+ args: {
2255
+ isReady: (0, import_nexus7.nonNull)((0, import_nexus7.booleanArg)())
2256
+ },
2257
+ async resolve(_, args, ctx) {
2258
+ return updateReadyState(args, ctx);
2259
+ }
2260
+ });
2261
+ t.nonNull.field("loginAsTeam", {
2262
+ type: Player,
2263
+ args: {
2264
+ token: (0, import_nexus7.nonNull)((0, import_nexus7.stringArg)())
2265
+ },
2266
+ async resolve(_, args, ctx) {
2267
+ return loginAsTeam(args, ctx);
2268
+ }
2269
+ });
2270
+ t.nonNull.field("createGame", {
2271
+ type: Game,
2272
+ args: {
2273
+ name: (0, import_nexus7.nonNull)((0, import_nexus7.stringArg)()),
2274
+ playerCount: (0, import_nexus7.nonNull)((0, import_nexus7.intArg)())
2275
+ },
2276
+ async resolve(_, args, ctx) {
2277
+ return createGame(args, ctx, {
2278
+ roleAssigner
2279
+ });
2280
+ }
2281
+ });
2282
+ t.nonNull.field("addGamePeriod", {
2283
+ type: Period,
2284
+ args: {
2285
+ gameId: (0, import_nexus7.nonNull)((0, import_nexus7.intArg)()),
2286
+ facts: (0, import_nexus7.arg)({
2287
+ type: (0, import_nexus7.nonNull)(PeriodFactsInput)
2288
+ })
2289
+ },
2290
+ async resolve(_, args, ctx) {
2291
+ return addGamePeriod(args, ctx, {
2292
+ schema: PeriodFactsSchema,
2293
+ reducers
2294
+ });
2295
+ }
2296
+ });
2297
+ t.nonNull.field("addPeriodSegment", {
2298
+ type: PeriodSegment,
2299
+ args: {
2300
+ gameId: (0, import_nexus7.nonNull)((0, import_nexus7.intArg)()),
2301
+ periodIx: (0, import_nexus7.nonNull)((0, import_nexus7.intArg)()),
2302
+ facts: (0, import_nexus7.arg)({
2303
+ type: (0, import_nexus7.nonNull)(PeriodSegmentFactsInput)
2304
+ }),
2305
+ storyElements: (0, import_nexus7.list)((0, import_nexus7.stringArg)()),
2306
+ learningElements: (0, import_nexus7.list)((0, import_nexus7.stringArg)())
2307
+ },
2308
+ async resolve(_, args, ctx) {
2309
+ return addPeriodSegment(args, ctx, {
2310
+ schema: PeriodSegmentFactsSchema,
2311
+ reducers
2312
+ });
2313
+ }
2314
+ });
2315
+ t.field("activateNextPeriod", {
2316
+ type: Game,
2317
+ args: {
2318
+ gameId: (0, import_nexus7.nonNull)((0, import_nexus7.intArg)())
2319
+ },
2320
+ async resolve(_, args, ctx) {
2321
+ const results = await activateNextPeriod(args, ctx, {
2322
+ reducers
2323
+ });
2324
+ if (!results)
2325
+ return;
2326
+ return results[0];
2327
+ }
2328
+ });
2329
+ t.field("activateNextSegment", {
2330
+ type: Game,
2331
+ args: {
2332
+ gameId: (0, import_nexus7.nonNull)((0, import_nexus7.intArg)())
2333
+ },
2334
+ async resolve(_, args, ctx) {
2335
+ const results = await activateNextSegment(args, ctx, {
2336
+ reducers
2337
+ });
2338
+ if (!results)
2339
+ return;
2340
+ return results[0];
2341
+ }
2342
+ });
2343
+ t.field("performAction", {
2344
+ type: PlayerResult,
2345
+ args: {
2346
+ type: (0, import_nexus7.nonNull)((0, import_nexus7.stringArg)()),
2347
+ payload: (0, import_nexus7.nonNull)((0, import_nexus7.stringArg)())
2348
+ },
2349
+ async resolve(_, args, ctx) {
2350
+ const currentGame = await getGameFromContext(ctx);
2351
+ if (!(currentGame == null ? void 0 : currentGame.activePeriod))
2352
+ return null;
2353
+ const facts = JSON.parse(args.payload);
2354
+ const result = await performAction(
2355
+ {
2356
+ gameId: currentGame.id,
2357
+ actionType: args.type,
2358
+ playerId: ctx.user.sub,
2359
+ periodIx: currentGame.activePeriodIx,
2360
+ segmentIx: currentGame.activePeriod.activeSegmentIx,
2361
+ facts
2362
+ },
2363
+ ctx,
2364
+ { reducers }
2365
+ );
2366
+ return result;
2367
+ }
2368
+ });
2369
+ t.field("attemptLearningElement", {
2370
+ type: LearningElementAttempt,
2371
+ args: {
2372
+ elementId: (0, import_nexus7.nonNull)((0, import_nexus7.idArg)()),
2373
+ selection: (0, import_nexus7.nonNull)((0, import_nexus7.stringArg)())
2374
+ },
2375
+ async resolve(_, args, ctx) {
2376
+ return attemptLearningElement(args, ctx);
2377
+ }
2378
+ });
2379
+ t.field("markStoryElement", {
2380
+ type: Player,
2381
+ args: {
2382
+ elementId: (0, import_nexus7.nonNull)((0, import_nexus7.idArg)())
2383
+ },
2384
+ async resolve(_, args, ctx) {
2385
+ return markStoryElement(args, ctx);
2386
+ }
2387
+ });
2388
+ t.field("updatePlayerData", {
2389
+ type: Player,
2390
+ args: {
2391
+ name: (0, import_nexus7.stringArg)(),
2392
+ avatar: (0, import_nexus7.stringArg)(),
2393
+ color: (0, import_nexus7.stringArg)(),
2394
+ facts: (0, import_nexus7.stringArg)()
2395
+ },
2396
+ async resolve(_, args, ctx) {
2397
+ const facts = args.facts ? JSON.parse(args.facts) : {};
2398
+ return updatePlayerData({ ...args, facts }, ctx);
2399
+ }
2400
+ });
2401
+ t.field("saveConsolidationDecision", {
2402
+ type: PlayerDecision,
2403
+ args: {
2404
+ payload: (0, import_nexus7.nonNull)((0, import_nexus7.stringArg)())
2405
+ },
2406
+ async resolve(_, args, ctx) {
2407
+ const facts = JSON.parse(args.payload);
2408
+ return saveDecisions(
2409
+ {
2410
+ decisionType: "CONSOLIDATION" /* Consolidation */,
2411
+ facts
2412
+ },
2413
+ ctx
2414
+ );
2415
+ }
2416
+ });
2417
+ }
2418
+ });
2419
+ }
2420
+ var Mutation = generateBaseMutations();
2421
+
2422
+ // src/types/Query.ts
2423
+ var import_nexus8 = require("nexus");
2424
+ function generateBaseQueries() {
2425
+ return (0, import_nexus8.objectType)({
2426
+ name: "Query",
2427
+ definition(t) {
2428
+ t.nonNull.list.field("games", {
2429
+ type: Game,
2430
+ async resolve(_, args, ctx) {
2431
+ return getGames(args, ctx);
2432
+ }
2433
+ });
2434
+ t.field("game", {
2435
+ type: Game,
2436
+ args: {
2437
+ id: (0, import_nexus8.intArg)()
2438
+ },
2439
+ async resolve(_, args, ctx) {
2440
+ return getGame(args, ctx);
2441
+ }
2442
+ });
2443
+ t.field("result", {
2444
+ type: PlayerState,
2445
+ async resolve(_, args, ctx) {
2446
+ return getPlayerResult(
2447
+ { gameId: ctx.user.gameId, playerId: ctx.user.sub },
2448
+ ctx
2449
+ );
2450
+ }
2451
+ });
2452
+ t.nonNull.field("self", {
2453
+ type: Player,
2454
+ async resolve(_, args, ctx) {
2455
+ return getPlayerData({ playerId: ctx.user.sub }, ctx);
2456
+ }
2457
+ });
2458
+ t.nonNull.list.field("learningElements", {
2459
+ type: LearningElement,
2460
+ async resolve(_, args, ctx) {
2461
+ return getLearningElements(args, ctx);
2462
+ }
2463
+ });
2464
+ t.field("learningElement", {
2465
+ type: LearningElementState,
2466
+ args: {
2467
+ id: (0, import_nexus8.nonNull)((0, import_nexus8.idArg)())
2468
+ },
2469
+ async resolve(_, args, ctx) {
2470
+ return getLearningElement(args, ctx);
2471
+ }
2472
+ });
2473
+ t.list.field("results", {
2474
+ type: PlayerResult,
2475
+ async resolve(_, args, ctx) {
2476
+ return getPlayerResults(args, ctx);
2477
+ }
2478
+ });
2479
+ t.list.field("pastResults", {
2480
+ type: PlayerResult,
2481
+ async resolve(_, args, ctx) {
2482
+ return getPastResults(args, ctx);
2483
+ }
2484
+ });
2485
+ }
2486
+ });
2487
+ }
2488
+ var Query = generateBaseQueries();
2489
+
2490
+ // src/types/Subscription.ts
2491
+ var import_nexus9 = require("nexus");
2492
+ function generateBaseSubscriptions() {
2493
+ return (0, import_nexus9.subscriptionType)({
2494
+ definition(t) {
2495
+ t.list.field("eventsGlobal", {
2496
+ type: Event,
2497
+ async subscribe(_, args, ctx) {
2498
+ return pubSub.subscribe("global:events");
2499
+ },
2500
+ async resolve(payload) {
2501
+ return payload;
2502
+ }
2503
+ });
2504
+ t.list.field("eventsUser", {
2505
+ type: Event,
2506
+ async subscribe(_, args, ctx) {
2507
+ return pubSub.subscribe("user:events", String(ctx.user.sub));
2508
+ },
2509
+ async resolve(payload) {
2510
+ return payload;
2511
+ }
2512
+ });
2513
+ }
2514
+ });
2515
+ }
2516
+ var Subscription = generateBaseSubscriptions();
2517
+
2518
+ // src/nexus.ts
2519
+ var JsonScalar = (0, import_nexus11.asNexusMethod)(import_graphql_scalars.JSONObjectResolver, "json");
2520
+ var DateScalar = (0, import_nexus11.asNexusMethod)(import_graphql_scalars.DateTimeResolver, "date");
2521
+ var UserRole3 = (0, import_nexus11.enumType)({
2522
+ name: "UserRole",
2523
+ members: Object.values(DB5.UserRole)
2524
+ });
2525
+ var Event = (0, import_nexus11.objectType)({
2526
+ name: "Event",
2527
+ definition(t) {
2528
+ t.string("type");
2529
+ }
2530
+ });
2531
+ // Annotate the CommonJS export names for ESM import in node:
2532
+ 0 && (module.exports = {
2533
+ DateScalar,
2534
+ Event,
2535
+ Game,
2536
+ GameStatus,
2537
+ JsonScalar,
2538
+ LearningAnswerOption,
2539
+ LearningElement,
2540
+ LearningElementAttempt,
2541
+ LearningElementState,
2542
+ Mutation,
2543
+ Period,
2544
+ PeriodFactsInput,
2545
+ PeriodFactsSchema,
2546
+ PeriodSegment,
2547
+ PeriodSegmentFactsInput,
2548
+ PeriodSegmentFactsSchema,
2549
+ Player,
2550
+ PlayerAction,
2551
+ PlayerDecision,
2552
+ PlayerDecisionType,
2553
+ PlayerLevel,
2554
+ PlayerResult,
2555
+ PlayerResultType,
2556
+ PlayerState,
2557
+ Query,
2558
+ Subscription,
2559
+ UserRole,
2560
+ generateBaseMutations,
2561
+ generateBaseQueries,
2562
+ generateBaseSubscriptions
2563
+ });