@gbl-uzh/platform 0.4.13 → 0.4.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/LICENSE.md +1 -1
  2. package/dist/index.d.ts +7 -1473
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +11 -2012
  5. package/dist/index.js.map +1 -0
  6. package/dist/lib/SSELink.d.ts +9 -0
  7. package/dist/lib/SSELink.d.ts.map +1 -0
  8. package/dist/lib/SSELink.js +24 -0
  9. package/dist/lib/SSELink.js.map +1 -0
  10. package/dist/lib/apollo.d.ts +3 -4
  11. package/dist/lib/apollo.d.ts.map +1 -0
  12. package/dist/lib/apollo.js +50 -108
  13. package/dist/lib/apollo.js.map +1 -0
  14. package/dist/lib/constants.d.ts +8 -0
  15. package/dist/lib/constants.d.ts.map +1 -0
  16. package/dist/lib/logger.d.ts +4 -0
  17. package/dist/lib/logger.d.ts.map +1 -0
  18. package/dist/lib/logger.js +11 -0
  19. package/dist/lib/logger.js.map +1 -0
  20. package/dist/lib/pubsub.d.ts +5 -0
  21. package/dist/lib/pubsub.d.ts.map +1 -0
  22. package/dist/lib/pubsub.js +6 -0
  23. package/dist/lib/pubsub.js.map +1 -0
  24. package/dist/lib/util.d.ts +12 -13
  25. package/dist/lib/util.d.ts.map +1 -0
  26. package/dist/lib/util.js +63 -105
  27. package/dist/lib/util.js.map +1 -0
  28. package/dist/nexus.d.ts +11 -42
  29. package/dist/nexus.d.ts.map +1 -0
  30. package/dist/nexus.js +22 -2605
  31. package/dist/nexus.js.map +1 -0
  32. package/dist/ops/FGameData.graphql +1 -0
  33. package/dist/ops/FPeriodData.graphql +1 -0
  34. package/dist/ops/FPlayerData.graphql +0 -4
  35. package/dist/ops/FSegmentData.graphql +1 -0
  36. package/dist/ops/FStoryElementData.graphql +7 -0
  37. package/dist/ops/MActivateNextSegment.graphql +0 -3
  38. package/dist/ops/MAddGamePeriod.graphql +2 -2
  39. package/dist/ops/MUpdatePlayerData.graphql +1 -3
  40. package/dist/ops/QGame.graphql +2 -3
  41. package/dist/ops/QPastResults.graphql +0 -3
  42. package/dist/ops/QResult.graphql +4 -5
  43. package/dist/ops/QSpecificResults.graphql +11 -0
  44. package/dist/ops/QStoryElements.graphql +7 -0
  45. package/dist/schema.prisma +11 -12
  46. package/dist/services/AccountService.d.ts +65 -0
  47. package/dist/services/AccountService.d.ts.map +1 -0
  48. package/dist/services/AccountService.js +70 -0
  49. package/dist/services/AccountService.js.map +1 -0
  50. package/dist/services/EventService.d.ts +13 -0
  51. package/dist/services/EventService.d.ts.map +1 -0
  52. package/dist/services/EventService.js +180 -0
  53. package/dist/services/EventService.js.map +1 -0
  54. package/dist/services/GameService.d.ts +670 -0
  55. package/dist/services/GameService.d.ts.map +1 -0
  56. package/dist/services/GameService.js +1191 -0
  57. package/dist/services/GameService.js.map +1 -0
  58. package/dist/services/PlayService.d.ts +630 -0
  59. package/dist/services/PlayService.d.ts.map +1 -0
  60. package/dist/services/PlayService.js +534 -0
  61. package/dist/services/PlayService.js.map +1 -0
  62. package/dist/tsconfig.tsbuildinfo +1 -0
  63. package/dist/types/Achievement.d.ts +4 -0
  64. package/dist/types/Achievement.d.ts.map +1 -0
  65. package/dist/types/Achievement.js +35 -0
  66. package/dist/types/Achievement.js.map +1 -0
  67. package/dist/types/Game.d.ts +5 -0
  68. package/dist/types/Game.d.ts.map +1 -0
  69. package/dist/types/Game.js +85 -0
  70. package/dist/types/Game.js.map +1 -0
  71. package/dist/types/LearningElement.d.ts +5 -0
  72. package/dist/types/LearningElement.d.ts.map +1 -0
  73. package/dist/types/LearningElement.js +55 -0
  74. package/dist/types/LearningElement.js.map +1 -0
  75. package/dist/types/Mutation.d.ts +10 -0
  76. package/dist/types/Mutation.d.ts.map +1 -0
  77. package/dist/types/Mutation.js +194 -0
  78. package/dist/types/Mutation.js.map +1 -0
  79. package/dist/types/Player.d.ts +9 -0
  80. package/dist/types/Player.d.ts.map +1 -0
  81. package/dist/types/Player.js +139 -0
  82. package/dist/types/Player.js.map +1 -0
  83. package/dist/types/Query.d.ts +3 -0
  84. package/dist/types/Query.d.ts.map +1 -0
  85. package/dist/types/Query.js +91 -0
  86. package/dist/types/Query.js.map +1 -0
  87. package/dist/types/StoryElement.d.ts +3 -0
  88. package/dist/types/StoryElement.d.ts.map +1 -0
  89. package/dist/types/StoryElement.js +27 -0
  90. package/dist/types/StoryElement.js.map +1 -0
  91. package/dist/types/Subscription.d.ts +3 -0
  92. package/dist/types/Subscription.d.ts.map +1 -0
  93. package/dist/types/Subscription.js +35 -0
  94. package/dist/types/Subscription.js.map +1 -0
  95. package/dist/types.d.ts +139 -0
  96. package/dist/types.d.ts.map +1 -0
  97. package/dist/types.js +26 -0
  98. package/dist/types.js.map +1 -0
  99. package/package.json +42 -38
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nexus.js","sources":["../src/nexus.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;AAIa,MAAA,UAAU,GAAG,aAAa,CAAC,kBAAkB,EAAE,MAAM;AACrD,MAAA,UAAU,GAAG,aAAa,CAAC,gBAAgB,EAAE,MAAM;AAEzD,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAC/B,IAAA,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC;AACpC,CAAA;AAEM,MAAM,KAAK,GAAG,UAAU,CAAC;AAC9B,IAAA,IAAI,EAAE,OAAO;AACb,IAAA,UAAU,CAAC,CAAC,EAAA;AACV,QAAA,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;KACjB;AACF,CAAA;;;;"}
@@ -4,4 +4,5 @@ fragment GameData on Game {
4
4
  status
5
5
  name
6
6
  activePeriodIx
7
+ activeSegmentIx
7
8
  }
@@ -11,4 +11,5 @@ fragment PeriodData on Period {
11
11
  segments {
12
12
  ...SegmentData
13
13
  }
14
+ segmentCount
14
15
  }
@@ -6,10 +6,6 @@ fragment PlayerData on Player {
6
6
  role
7
7
 
8
8
  name
9
- avatar
10
- location
11
- color
12
-
13
9
  facts
14
10
 
15
11
  experience
@@ -4,6 +4,7 @@ fragment SegmentData on PeriodSegment {
4
4
  index
5
5
 
6
6
  countdownExpiresAt
7
+ countdownDurationMs
7
8
 
8
9
  facts
9
10
 
@@ -0,0 +1,7 @@
1
+ fragment StoryElementData on StoryElement {
2
+ id
3
+ type
4
+ title
5
+ content
6
+ contentRole
7
+ }
@@ -28,9 +28,6 @@ mutation ActivateNextSegment($gameId: Int!) {
28
28
  role
29
29
 
30
30
  name
31
- avatar
32
- location
33
- color
34
31
 
35
32
  facts
36
33
 
@@ -1,7 +1,7 @@
1
1
  #import "./FPeriodData.graphql"
2
2
 
3
- mutation AddGamePeriod($gameId: Int!, $facts: PeriodFactsInput!) {
4
- addGamePeriod(gameId: $gameId, facts: $facts) {
3
+ mutation AddGamePeriod($gameId: Int!, $facts: PeriodFactsInput!, $segmentCount: Int!) {
4
+ addGamePeriod(gameId: $gameId, facts: $facts, segmentCount: $segmentCount) {
5
5
  ...PeriodData
6
6
  }
7
7
  }
@@ -2,11 +2,9 @@
2
2
 
3
3
  mutation UpdatePlayerData(
4
4
  $name: String
5
- $avatar: String
6
- $color: String
7
5
  $facts: String
8
6
  ) {
9
- updatePlayerData(name: $name, avatar: $avatar, color: $color, facts: $facts) {
7
+ updatePlayerData(name: $name, facts: $facts) {
10
8
  ...PlayerData
11
9
  }
12
10
  }
@@ -11,7 +11,9 @@ query Game($id: Int) {
11
11
  activeSegment {
12
12
  id
13
13
  countdownExpiresAt
14
+ countdownDurationMs
14
15
  }
16
+ segmentCount
15
17
  segments {
16
18
  id
17
19
  }
@@ -28,9 +30,6 @@ query Game($id: Int) {
28
30
 
29
31
  number
30
32
  name
31
- avatar
32
- location
33
- color
34
33
 
35
34
  facts
36
35
 
@@ -15,9 +15,6 @@ query PastResults {
15
15
  role
16
16
 
17
17
  name
18
- avatar
19
- location
20
- color
21
18
 
22
19
  facts
23
20
 
@@ -1,5 +1,6 @@
1
1
  #import "./FResultData.graphql"
2
2
  #import "./FPeriodData.graphql"
3
+ #import "./FStoryElementData.graphql"
3
4
  #import "./FPlayerData.graphql"
4
5
  #import "./FPlayerActionData.graphql"
5
6
 
@@ -21,6 +22,7 @@ query Result {
21
22
  status
22
23
  periods {
23
24
  ...PeriodData
25
+ segmentCount
24
26
  }
25
27
  activePeriod {
26
28
  ...PeriodData
@@ -29,16 +31,13 @@ query Result {
29
31
  index
30
32
  facts
31
33
  countdownExpiresAt
34
+ countdownDurationMs
32
35
  learningElements {
33
36
  id
34
37
  title
35
38
  }
36
39
  storyElements {
37
- id
38
- type
39
- title
40
- content
41
- contentRole
40
+ ...StoryElementData
42
41
  }
43
42
  }
44
43
  }
@@ -0,0 +1,11 @@
1
+ #import "./FResultData.graphql"
2
+
3
+ query SpecificResults($gameId: Int!, $type: String!) {
4
+ specificResults(gameId: $gameId, type: $type) {
5
+ ...ResultData
6
+ player {
7
+ id
8
+ name
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,7 @@
1
+ #import "./FStoryElementData.graphql"
2
+
3
+ query StoryElements {
4
+ storyElements {
5
+ ...StoryElementData
6
+ }
7
+ }
@@ -98,7 +98,7 @@ model Game {
98
98
 
99
99
  activePeriodIx Int @default(-1)
100
100
  activePeriodId Int?
101
- activePeriod Period? @relation("activePeriod", fields: [activePeriodId], references: [id], onUpdate: NoAction, onDelete: NoAction)
101
+ activePeriod Period? @relation("activePeriod", fields: [activePeriodId], references: [id], onUpdate: NoAction, onDelete: Cascade)
102
102
 
103
103
  segments PeriodSegment[]
104
104
 
@@ -119,10 +119,11 @@ model Period {
119
119
  facts Json
120
120
 
121
121
  segments PeriodSegment[]
122
+ segmentCount Int
122
123
 
123
124
  activeSegmentIx Int @default(-1)
124
125
  activeSegmentId Int?
125
- activeSegment PeriodSegment? @relation("activeSegment", fields: [activeSegmentId], references: [id], onUpdate: NoAction, onDelete: NoAction)
126
+ activeSegment PeriodSegment? @relation("activeSegment", fields: [activeSegmentId], references: [id], onUpdate: NoAction, onDelete: Cascade)
126
127
 
127
128
  decisions PlayerDecision[]
128
129
  results PlayerResult[]
@@ -134,7 +135,7 @@ model Period {
134
135
  nextPeriod Period? @relation("periodSequence", fields: [nextPeriodId], references: [id], onUpdate: NoAction, onDelete: NoAction)
135
136
 
136
137
  gameId Int
137
- game Game @relation(fields: [gameId], references: [id])
138
+ game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
138
139
 
139
140
  Game Game[] @relation("activePeriod")
140
141
 
@@ -152,6 +153,7 @@ model PeriodSegment {
152
153
  facts Json
153
154
 
154
155
  countdownExpiresAt DateTime?
156
+ countdownDurationMs Int?
155
157
 
156
158
  actions PlayerAction[]
157
159
  results PlayerResult[]
@@ -159,14 +161,14 @@ model PeriodSegment {
159
161
  learningElements LearningElement[]
160
162
  storyElements StoryElement[]
161
163
 
162
- period Period @relation(fields: [periodId], references: [id])
164
+ period Period @relation(fields: [periodId], references: [id], onDelete: Cascade)
163
165
  periodId Int
164
166
  periodIx Int
165
167
 
166
168
  Period Period[] @relation("activeSegment")
167
169
 
168
170
  gameId Int
169
- game Game @relation(fields: [gameId], references: [id])
171
+ game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
170
172
 
171
173
  previousSegment PeriodSegment[] @relation("segmentSequence")
172
174
  nextSegmentId Int?
@@ -183,9 +185,6 @@ model Player {
183
185
 
184
186
  number Int @default(-1)
185
187
  name String @default("Anonymous")
186
- avatar String @default("")
187
- location String @default("")
188
- color String @default("White")
189
188
  isReady Boolean @default(false)
190
189
 
191
190
  experience Int @default(0)
@@ -215,7 +214,7 @@ model Player {
215
214
  visitedStoryElementIds String[]
216
215
 
217
216
  gameId Int
218
- game Game @relation(fields: [gameId], references: [id])
217
+ game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
219
218
 
220
219
  createdAt DateTime @default(now())
221
220
  updatedAt DateTime @updatedAt
@@ -259,14 +258,14 @@ model PlayerResult {
259
258
  facts Json
260
259
 
261
260
  playerId String @db.Uuid
262
- player Player @relation(fields: [playerId], references: [id])
261
+ player Player @relation(fields: [playerId], references: [id], onDelete: Cascade)
263
262
 
264
263
  gameId Int
265
- game Game @relation(fields: [gameId], references: [id])
264
+ game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
266
265
 
267
266
  periodId Int
268
267
  periodIx Int
269
- period Period @relation(fields: [periodId], references: [id])
268
+ period Period @relation(fields: [periodId], references: [id], onDelete: Cascade)
270
269
 
271
270
  segmentId Int?
272
271
  segmentIx Int?
@@ -0,0 +1,65 @@
1
+ import type { PrismaClient } from '@prisma/client';
2
+ import { CtxWithPrisma, UserRole } from '../types.js';
3
+ interface CreateLoginTokenArgs {
4
+ sub: string;
5
+ role: UserRole;
6
+ token?: string;
7
+ gameId?: number;
8
+ }
9
+ export declare function createLoginToken({ sub, role, ...extra }: CreateLoginTokenArgs): string;
10
+ interface LoginAsTeamArgs {
11
+ token: string;
12
+ }
13
+ export declare function loginAsTeam({ token }: LoginAsTeamArgs, ctx: CtxWithPrisma<PrismaClient>): Promise<({
14
+ level: {
15
+ id: number;
16
+ index: number;
17
+ description: string;
18
+ image: string;
19
+ requiredXP: number;
20
+ };
21
+ achievements: ({
22
+ achievement: {
23
+ id: string;
24
+ name: string;
25
+ createdAt: Date;
26
+ updatedAt: Date;
27
+ description: string;
28
+ image: string | null;
29
+ reward: import("@prisma/client/runtime/library").JsonValue | null;
30
+ when: import("@prisma/client").$Enums.AchievementFrequency;
31
+ onEventId: string;
32
+ };
33
+ } & {
34
+ gameId: number;
35
+ id: number;
36
+ createdAt: Date;
37
+ updatedAt: Date;
38
+ count: number;
39
+ achievementId: string;
40
+ playerId: string;
41
+ periodId: number;
42
+ })[];
43
+ } & {
44
+ number: number;
45
+ role: string | null;
46
+ token: string;
47
+ gameId: number;
48
+ id: string;
49
+ name: string;
50
+ isReady: boolean;
51
+ experience: number;
52
+ experienceToNext: number;
53
+ levelIx: number;
54
+ tutorialCompleted: boolean;
55
+ facts: import("@prisma/client/runtime/library").JsonValue;
56
+ achievementKeys: string[];
57
+ achievementIds: string[];
58
+ completedLearningElementIds: string[];
59
+ visitedStoryElementIds: string[];
60
+ createdAt: Date;
61
+ updatedAt: Date;
62
+ }) | null>;
63
+ export declare function logoutAsTeam(ctx: CtxWithPrisma<PrismaClient>): Promise<boolean>;
64
+ export {};
65
+ //# sourceMappingURL=AccountService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AccountService.d.ts","sourceRoot":"","sources":["../../src/services/AccountService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAGlD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAErD,UAAU,oBAAoB;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,QAAQ,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,oBAAoB,UAQtB;AAED,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wBAAsB,WAAW,CAC/B,EAAE,KAAK,EAAE,EAAE,eAAe,EAC1B,GAAG,EAAE,aAAa,CAAC,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA2CjC;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,aAAa,CAAC,YAAY,CAAC,oBAqBlE"}
@@ -0,0 +1,70 @@
1
+ import JWT from 'jsonwebtoken';
2
+ import { setCookie, destroyCookie } from 'nookies';
3
+ import { UserRole } from '../types.js';
4
+
5
+ function createLoginToken({ sub, role, ...extra }) {
6
+ if (!process.env.NEXTAUTH_SECRET) {
7
+ throw new Error('NEXTAUTH_SECRET is not set');
8
+ }
9
+ return JWT.sign({ sub, role, ...extra }, process.env.NEXTAUTH_SECRET, {
10
+ expiresIn: '1 week',
11
+ });
12
+ }
13
+ async function loginAsTeam({ token }, ctx) {
14
+ const matchingPlayer = await ctx.prisma.player.findUnique({
15
+ where: { token },
16
+ include: {
17
+ level: true,
18
+ achievements: {
19
+ include: {
20
+ achievement: true,
21
+ },
22
+ },
23
+ },
24
+ });
25
+ if (!matchingPlayer) {
26
+ throw new Error('INVALID_TOKEN');
27
+ }
28
+ try {
29
+ const jwt = createLoginToken({
30
+ gameId: matchingPlayer.gameId,
31
+ sub: matchingPlayer.id,
32
+ role: UserRole.PLAYER,
33
+ token: matchingPlayer.token,
34
+ });
35
+ const cookieName = process.env.NODE_ENV === 'production'
36
+ ? '__Secure-next-auth.session-token'
37
+ : 'next-auth.session-token';
38
+ setCookie(ctx, cookieName, jwt, {
39
+ path: '/',
40
+ maxAge: 60 * 60 * 24 * 7,
41
+ httpOnly: process.env.NODE_ENV === 'production',
42
+ secure: process.env.NODE_ENV === 'production',
43
+ });
44
+ }
45
+ catch (err) {
46
+ console.error(err);
47
+ return null;
48
+ }
49
+ return matchingPlayer;
50
+ }
51
+ async function logoutAsTeam(ctx) {
52
+ if (!ctx.user?.sub)
53
+ return false;
54
+ const matchingPlayer = await ctx.prisma.player.findUnique({
55
+ where: {
56
+ id: ctx.user.sub,
57
+ },
58
+ });
59
+ if (matchingPlayer) {
60
+ const cookieName = process.env.NODE_ENV === 'production'
61
+ ? '__Secure-next-auth.session-token'
62
+ : 'next-auth.session-token';
63
+ destroyCookie(ctx, cookieName);
64
+ return true;
65
+ }
66
+ return false;
67
+ }
68
+
69
+ export { createLoginToken, loginAsTeam, logoutAsTeam };
70
+ //# sourceMappingURL=AccountService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AccountService.js","sources":["../../src/services/AccountService.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAYM,SAAU,gBAAgB,CAAC,EAC/B,GAAG,EACH,IAAI,EACJ,GAAG,KAAK,EACa,EAAA;AACrB,IAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE;AAChC,QAAA,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC;;AAG/C,IAAA,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE;AACpE,QAAA,SAAS,EAAE,QAAQ;AACpB,KAAA,CAAC;AACJ;AAMO,eAAe,WAAW,CAC/B,EAAE,KAAK,EAAmB,EAC1B,GAAgC,EAAA;IAEhC,MAAM,cAAc,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;QACxD,KAAK,EAAE,EAAE,KAAK,EAAE;AAChB,QAAA,OAAO,EAAE;AACP,YAAA,KAAK,EAAE,IAAI;AACX,YAAA,YAAY,EAAE;AACZ,gBAAA,OAAO,EAAE;AACP,oBAAA,WAAW,EAAE,IAAI;AAClB,iBAAA;AACF,aAAA;AACF,SAAA;AACF,KAAA,CAAC;IAEF,IAAI,CAAC,cAAc,EAAE;AACnB,QAAA,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC;;AAGlC,IAAA,IAAI;QACF,MAAM,GAAG,GAAG,gBAAgB,CAAC;YAC3B,MAAM,EAAE,cAAc,CAAC,MAAM;YAC7B,GAAG,EAAE,cAAc,CAAC,EAAE;YACtB,IAAI,EAAE,QAAQ,CAAC,MAAM;YACrB,KAAK,EAAE,cAAc,CAAC,KAAK;AAC5B,SAAA,CAAC;QAEF,MAAM,UAAU,GACd,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK;AACvB,cAAE;cACA,yBAAyB;AAE/B,QAAA,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE;AAC9B,YAAA,IAAI,EAAE,GAAG;AACT,YAAA,MAAM,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;AACxB,YAAA,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;AAC/C,YAAA,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;AAC9C,SAAA,CAAC;;IACF,OAAO,GAAG,EAAE;AACZ,QAAA,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC;AAClB,QAAA,OAAO,IAAI;;AAGb,IAAA,OAAO,cAAc;AACvB;AAEO,eAAe,YAAY,CAAC,GAAgC,EAAA;AACjE,IAAA,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG;AAAE,QAAA,OAAO,KAAK;IAEhC,MAAM,cAAc,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;AACxD,QAAA,KAAK,EAAE;AACL,YAAA,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG;AACjB,SAAA;AACF,KAAA,CAAC;IAEF,IAAI,cAAc,EAAE;QAClB,MAAM,UAAU,GACd,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK;AACvB,cAAE;cACA,yBAAyB;AAE/B,QAAA,aAAa,CAAC,GAAG,EAAE,UAAU,CAAC;AAE9B,QAAA,OAAO,IAAI;;AAGb,IAAA,OAAO,KAAK;AACd;;;;"}
@@ -0,0 +1,13 @@
1
+ export declare function receiveEvents({ events, ctx, prisma }: {
2
+ events: any;
3
+ ctx: any;
4
+ prisma: any;
5
+ }): Promise<any>;
6
+ export declare function receiveEvent(event: any, definedEvents: any, definedLevels: any, prisma: any): Promise<any[]>;
7
+ export declare function publishGlobalNotification(event: any): void;
8
+ export declare function publishUserNotification(ctx: {
9
+ user: {
10
+ sub: string;
11
+ };
12
+ }, events?: any): void;
13
+ //# sourceMappingURL=EventService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventService.d.ts","sourceRoot":"","sources":["../../src/services/EventService.ts"],"names":[],"mappings":"AAIA,wBAAsB,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE;;;;CAAA,gBAoB1D;AAkBD,wBAAsB,YAAY,CAChC,KAAK,KAAA,EACL,aAAa,KAAA,EACb,aAAa,KAAA,EACb,MAAM,KAAA,kBA0KP;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,GAAG,QAGnD;AAED,wBAAgB,uBAAuB,CACrC,GAAG,EAAE;IAAE,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAC9B,MAAM,CAAC,EAAE,GAAG,QAMb"}
@@ -0,0 +1,180 @@
1
+ import * as DB from '@prisma/client';
2
+ import { pubSub } from '../lib/pubsub.js';
3
+ import { BaseUserNotificationType } from '../types.js';
4
+
5
+ async function receiveEvents({ events, ctx, prisma }) {
6
+ if (!Array.isArray(events))
7
+ return;
8
+ const definedEvents = await prisma.event.findMany({
9
+ include: {
10
+ achievements: true,
11
+ },
12
+ });
13
+ const definedLevels = await prisma.playerLevel.findMany();
14
+ const promises = await Promise.all(events.map(async (event) => receiveEvent({ ...event, ctx }, definedEvents, definedLevels, prisma)));
15
+ const results = prisma.$transaction(promises.flat());
16
+ return results;
17
+ }
18
+ function prepareAchievementData({ achievementId, gameId, periodIx, playerId, count, }) {
19
+ return {
20
+ count,
21
+ achievement: { connect: { id: achievementId } },
22
+ game: { connect: { id: gameId } },
23
+ period: { connect: { gameId_index: { gameId, index: periodIx } } },
24
+ player: { connect: { id: playerId } },
25
+ };
26
+ }
27
+ async function receiveEvent(event, definedEvents, definedLevels, prisma) {
28
+ const matchingEvent = definedEvents.find((item) => item.id === event.type);
29
+ // console.warn(event, matchingEvent)
30
+ // if there is a matching event and it awards achievements, process each
31
+ if (matchingEvent && matchingEvent.achievements?.length > 0) {
32
+ const awardedAchievements = await matchingEvent.achievements.reduce(async (acc, achievement) => {
33
+ if (achievement.when === DB.AchievementFrequency.FIRST &&
34
+ event.ctx.achievements.includes(achievement.id)) {
35
+ return acc;
36
+ }
37
+ const existingInstance = await prisma.achievementInstance.findFirst({
38
+ where: {
39
+ achievement: {
40
+ id: achievement.id,
41
+ },
42
+ player: {
43
+ id: event.ctx.args.playerId,
44
+ },
45
+ },
46
+ });
47
+ let achievementInstance;
48
+ if (existingInstance) {
49
+ achievementInstance = await prisma.achievementInstance.update({
50
+ where: {
51
+ id: existingInstance.id,
52
+ },
53
+ data: prepareAchievementData({
54
+ count: existingInstance.count + 1,
55
+ achievementId: achievement.id,
56
+ gameId: event.ctx.args.gameId,
57
+ periodIx: event.ctx.args.periodIx,
58
+ playerId: event.ctx.args.playerId,
59
+ }),
60
+ });
61
+ }
62
+ else {
63
+ achievementInstance = await prisma.achievementInstance.create({
64
+ data: prepareAchievementData({
65
+ count: 1,
66
+ achievementId: achievement.id,
67
+ gameId: event.ctx.args.gameId,
68
+ periodIx: event.ctx.args.periodIx,
69
+ playerId: event.ctx.args.playerId,
70
+ }),
71
+ });
72
+ }
73
+ return {
74
+ achievements: [
75
+ ...acc.achievements,
76
+ {
77
+ achievement,
78
+ achievementInstance,
79
+ },
80
+ ],
81
+ achievementKeys: [...acc.achievementKeys, achievement.id],
82
+ rewards: {
83
+ ...acc.rewards,
84
+ xp: (acc.rewards.xp ?? 0) + (achievement.reward?.xp ?? 0),
85
+ },
86
+ };
87
+ }, {
88
+ achievements: [],
89
+ achievementKeys: [],
90
+ rewards: {},
91
+ });
92
+ const currentLevelPlus1 = definedLevels.find((level) => level.index === event.ctx.currentLevelIx + 1);
93
+ const currentLevelPlus2 = definedLevels.find((level) => level.index === event.ctx.currentLevelIx + 2);
94
+ if (awardedAchievements.achievements.length > 0) {
95
+ if (event.ctx.experience + awardedAchievements.rewards.xp >=
96
+ currentLevelPlus1.requiredXP) {
97
+ publishUserNotification({
98
+ user: {
99
+ sub: event.ctx.args.playerId,
100
+ },
101
+ }, [
102
+ {
103
+ type: BaseUserNotificationType.ACHIEVEMENT_RECEIVED,
104
+ },
105
+ ]);
106
+ publishUserNotification({
107
+ user: {
108
+ sub: event.ctx.args.playerId,
109
+ },
110
+ }, [
111
+ {
112
+ type: BaseUserNotificationType.LEVEL_UP,
113
+ },
114
+ ]);
115
+ return [
116
+ prisma.player.update({
117
+ where: {
118
+ id: event.ctx.args.playerId,
119
+ },
120
+ data: {
121
+ experience: {
122
+ increment: awardedAchievements.rewards.xp,
123
+ },
124
+ experienceToNext: currentLevelPlus2.requiredXP,
125
+ level: {
126
+ connect: {
127
+ index: currentLevelPlus1.index,
128
+ },
129
+ },
130
+ achievementKeys: {
131
+ push: awardedAchievements.achievementKeys,
132
+ },
133
+ },
134
+ }),
135
+ ];
136
+ }
137
+ else {
138
+ publishUserNotification({
139
+ user: {
140
+ sub: event.ctx.args.playerId,
141
+ },
142
+ }, [
143
+ {
144
+ type: BaseUserNotificationType.ACHIEVEMENT_RECEIVED,
145
+ },
146
+ ]);
147
+ return [
148
+ prisma.player.update({
149
+ where: {
150
+ id: event.ctx.args.playerId,
151
+ },
152
+ data: {
153
+ experience: {
154
+ increment: awardedAchievements.rewards.xp,
155
+ },
156
+ achievementKeys: {
157
+ push: awardedAchievements.achievementKeys,
158
+ },
159
+ },
160
+ }),
161
+ ];
162
+ }
163
+ }
164
+ return [];
165
+ }
166
+ return [];
167
+ }
168
+ function publishGlobalNotification(event) {
169
+ // console.log(event)
170
+ pubSub.publish('global:events', event);
171
+ }
172
+ function publishUserNotification(ctx, events) {
173
+ if (events && events.length > 0) {
174
+ // console.log(events)
175
+ pubSub.publish('user:events', ctx.user.sub, events);
176
+ }
177
+ }
178
+
179
+ export { publishGlobalNotification, publishUserNotification, receiveEvent, receiveEvents };
180
+ //# sourceMappingURL=EventService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventService.js","sources":["../../src/services/EventService.ts"],"sourcesContent":[null],"names":["UserNotificationType"],"mappings":"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"}