@drmxrcy/tcg-shared 0.0.0-202602060544
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/package.json +30 -0
- package/src/auth/index.ts +4 -0
- package/src/auth/types.ts +46 -0
- package/src/index.ts +9 -0
- package/src/libs/logger.ts +51 -0
- package/src/object-hash.d.ts +30 -0
- package/src/types.ts +302 -0
- package/src/utils.ts +48 -0
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@drmxrcy/tcg-shared",
|
|
3
|
+
"version": "0.0.0-202602060544",
|
|
4
|
+
"private": false,
|
|
5
|
+
"main": "./src/index.ts",
|
|
6
|
+
"types": "./src/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"src/"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"typecheck": "tsc --noEmit",
|
|
12
|
+
"format": "bun x @biomejs/biome check --fix --max-diagnostics=none --diagnostic-level=error --linter-enabled=false ./src",
|
|
13
|
+
"lint": "bun x @biomejs/biome lint --write ./src",
|
|
14
|
+
"check-types": "tsc --noEmit",
|
|
15
|
+
"test": "echo 'No tests'"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"pino": "9.7.0",
|
|
19
|
+
"pino-pretty": "13.0.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@biomejs/biome": "2.3.11",
|
|
23
|
+
"@drmxrcy/tcg-typescript-config": "workspace:*"
|
|
24
|
+
},
|
|
25
|
+
"exports": {
|
|
26
|
+
".": "./src/index.ts",
|
|
27
|
+
"./types": "./src/types.ts",
|
|
28
|
+
"./auth": "./src/auth/index.ts"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared authentication types
|
|
3
|
+
*
|
|
4
|
+
* These types are used across the API, web app, and any other packages
|
|
5
|
+
* that need to work with Better Auth session data.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* User type from Better Auth session
|
|
10
|
+
*/
|
|
11
|
+
export interface AuthUser {
|
|
12
|
+
id: string;
|
|
13
|
+
email: string;
|
|
14
|
+
name: string;
|
|
15
|
+
image?: string | null;
|
|
16
|
+
username?: string | null;
|
|
17
|
+
displayUsername?: string | null;
|
|
18
|
+
emailVerified: boolean;
|
|
19
|
+
subscriptionTier: string;
|
|
20
|
+
subscriptionExpiresAt?: Date | null;
|
|
21
|
+
createdAt: Date;
|
|
22
|
+
updatedAt: Date;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Session type from Better Auth
|
|
27
|
+
*/
|
|
28
|
+
export interface AuthSession {
|
|
29
|
+
id: string;
|
|
30
|
+
userId: string;
|
|
31
|
+
token: string;
|
|
32
|
+
expiresAt: Date;
|
|
33
|
+
ipAddress?: string | null;
|
|
34
|
+
userAgent?: string | null;
|
|
35
|
+
createdAt: Date;
|
|
36
|
+
updatedAt: Date;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Session result type for server responses
|
|
41
|
+
* This matches the structure returned by auth.api.getSession()
|
|
42
|
+
*/
|
|
43
|
+
export interface SessionResult {
|
|
44
|
+
user: AuthUser | null;
|
|
45
|
+
session: AuthSession | null;
|
|
46
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import pino, { type Logger } from "pino";
|
|
2
|
+
|
|
3
|
+
const isDevelopment = process.env.NODE_ENV !== "production";
|
|
4
|
+
const isTest = process.env.NODE_ENV === "test";
|
|
5
|
+
|
|
6
|
+
// https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#logseverity
|
|
7
|
+
const _PinoLevelToSeverityLookup = {
|
|
8
|
+
trace: "TRACE",
|
|
9
|
+
debug: "DEBUG",
|
|
10
|
+
info: "INFO",
|
|
11
|
+
warn: "WARNING",
|
|
12
|
+
error: "ERROR",
|
|
13
|
+
fatal: "CRITICAL",
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
let internalLogger = pino({
|
|
17
|
+
level: process.env.LOG_LEVEL || isDevelopment ? "debug" : "info",
|
|
18
|
+
formatters: {
|
|
19
|
+
level: (label) => {
|
|
20
|
+
return { level: label.toUpperCase() };
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
timestamp: pino.stdTimeFunctions.isoTime,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// if (isDevelopment) {
|
|
27
|
+
// internalLogger = pino({
|
|
28
|
+
// transport: {
|
|
29
|
+
// target: "pino-pretty",
|
|
30
|
+
// options: {
|
|
31
|
+
// colorize: true,
|
|
32
|
+
// },
|
|
33
|
+
// },
|
|
34
|
+
// });
|
|
35
|
+
// }
|
|
36
|
+
|
|
37
|
+
if (isTest || isDevelopment) {
|
|
38
|
+
// @ts-expect-error TODO: find a better way to disable pino
|
|
39
|
+
internalLogger = {
|
|
40
|
+
trace: console.trace,
|
|
41
|
+
warn: console.log,
|
|
42
|
+
info: console.info,
|
|
43
|
+
debug: console.debug,
|
|
44
|
+
error: console.error,
|
|
45
|
+
silent: console.log,
|
|
46
|
+
fatal: console.error,
|
|
47
|
+
level: "debug",
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const logger: Logger = internalLogger;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declaration file for object-hash module
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
declare module "object-hash" {
|
|
6
|
+
interface ObjectHashOptions {
|
|
7
|
+
algorithm?: string;
|
|
8
|
+
encoding?: string;
|
|
9
|
+
excludeValues?: boolean;
|
|
10
|
+
ignoreUnknown?: boolean;
|
|
11
|
+
replacer?: (value: unknown) => unknown;
|
|
12
|
+
respectFunctionProperties?: boolean;
|
|
13
|
+
respectFunctionNames?: boolean;
|
|
14
|
+
respectType?: boolean;
|
|
15
|
+
unorderedArrays?: boolean;
|
|
16
|
+
unorderedObjects?: boolean;
|
|
17
|
+
unorderedSets?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface ObjectHash {
|
|
21
|
+
(obj: unknown, options?: ObjectHashOptions): string;
|
|
22
|
+
MD5(data: unknown): string;
|
|
23
|
+
keys(obj: object): string;
|
|
24
|
+
keysMD5(obj: object): string;
|
|
25
|
+
sha1(obj: unknown): string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const objectHash: ObjectHash;
|
|
29
|
+
export default objectHash;
|
|
30
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
export type Zones = "hand" | "play" | "discard" | "inkwell" | "deck";
|
|
2
|
+
|
|
3
|
+
export type MatchMove =
|
|
4
|
+
| ChangeGameModeMove
|
|
5
|
+
| AlterHandMove
|
|
6
|
+
| RequestMove
|
|
7
|
+
| GenerateOnDemandLayerMove
|
|
8
|
+
| ConcedeMatchMove
|
|
9
|
+
| ConcedeGameMove
|
|
10
|
+
| ShiftMove
|
|
11
|
+
| ResolveLayerMove
|
|
12
|
+
| SkipLayerMove
|
|
13
|
+
| AcceptOptionalLayerMove
|
|
14
|
+
| DrawCardMove
|
|
15
|
+
| RevealCardMove
|
|
16
|
+
| UpdateLoreMove
|
|
17
|
+
| ShuffleDeckMove
|
|
18
|
+
| ScryMove
|
|
19
|
+
| UndoMove
|
|
20
|
+
| UndoTurnMove
|
|
21
|
+
| UndoLastTurnMove
|
|
22
|
+
| ActivateAbilityMove
|
|
23
|
+
| UpdateCardDamageMove
|
|
24
|
+
| ChooseWhoGoesFirstMove
|
|
25
|
+
| QuestMove
|
|
26
|
+
| QuestWithAllMove
|
|
27
|
+
| TapCardMove
|
|
28
|
+
| MoveCardMove
|
|
29
|
+
| TutorCardMove
|
|
30
|
+
| SingTogetherMove
|
|
31
|
+
| SingMove
|
|
32
|
+
| PassTurnMove
|
|
33
|
+
| PutCardIntoInkwellMove
|
|
34
|
+
| EnterLocationMove
|
|
35
|
+
| MoveToLocationMove
|
|
36
|
+
| AnswerPlayerRequest
|
|
37
|
+
| CancelPlayerRequest
|
|
38
|
+
| ChallengeMove
|
|
39
|
+
| PlayerJoinedMove
|
|
40
|
+
| PlayerLeftMove
|
|
41
|
+
| PlayCardMove
|
|
42
|
+
| DropPlayerMove;
|
|
43
|
+
|
|
44
|
+
interface BaseMove {
|
|
45
|
+
type: MatchMove["type"];
|
|
46
|
+
number?: number;
|
|
47
|
+
id?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface AnswerPlayerRequest extends BaseMove {
|
|
51
|
+
type: "ANSWER_PLAYER_REQUEST";
|
|
52
|
+
accepted: boolean;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface PlayerJoinedMove extends BaseMove {
|
|
56
|
+
type: "PLAYER_JOINED";
|
|
57
|
+
playerId: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface PlayerLeftMove extends BaseMove {
|
|
61
|
+
type: "PLAYER_LEFT";
|
|
62
|
+
playerId: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface DropPlayerMove extends BaseMove {
|
|
66
|
+
type: "DROP_PLAYER";
|
|
67
|
+
playerId: string;
|
|
68
|
+
dropped?: boolean;
|
|
69
|
+
timeLeft?: number;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface CancelPlayerRequest extends BaseMove {
|
|
73
|
+
type: "CANCEL_PLAYER_REQUEST";
|
|
74
|
+
cancelled: boolean;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface ChangeGameModeMove extends BaseMove {
|
|
78
|
+
type: "CHANGE_GAME_MODE";
|
|
79
|
+
manual: boolean;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface UndoMoveBase extends BaseMove {
|
|
83
|
+
type: "UNDO";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface UndoMoveWithTurn extends UndoMoveBase {
|
|
87
|
+
turn: number;
|
|
88
|
+
move?: never;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface UndoMoveWithMove extends UndoMoveBase {
|
|
92
|
+
turn?: never;
|
|
93
|
+
move: number;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export type UndoMove = UndoMoveWithTurn | UndoMoveWithMove;
|
|
97
|
+
|
|
98
|
+
export interface UndoTurnMove extends BaseMove {
|
|
99
|
+
type: "UNDO_TURN";
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface UndoLastTurnMove extends BaseMove {
|
|
103
|
+
type: "UNDO_LAST_TURN";
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface ChooseWhoGoesFirstMove extends BaseMove {
|
|
107
|
+
type: "CHOOSE_FIRST_PLAYER";
|
|
108
|
+
player: string;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface AlterHandMove extends BaseMove {
|
|
112
|
+
type: "ALTER_HAND";
|
|
113
|
+
player: string;
|
|
114
|
+
cards: string[];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface RequestMove extends BaseMove {
|
|
118
|
+
type: "REQUEST";
|
|
119
|
+
payload:
|
|
120
|
+
| {
|
|
121
|
+
type: "ENABLE_CHAT";
|
|
122
|
+
mode: "free_text" | "predefined";
|
|
123
|
+
}
|
|
124
|
+
| {
|
|
125
|
+
type: "CONCEDE_GAME";
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface PassTurnMove extends BaseMove {
|
|
130
|
+
type: "PASS_TURN";
|
|
131
|
+
player: string;
|
|
132
|
+
forced?: boolean;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface ActivateAbilityMove extends BaseMove {
|
|
136
|
+
type: "ACTIVATE_ABILITY";
|
|
137
|
+
instanceId: string;
|
|
138
|
+
ability?: string;
|
|
139
|
+
costs?: string[];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface UpdateCardDamageMove extends BaseMove {
|
|
143
|
+
type: "UPDATE_CARD_DAMAGE";
|
|
144
|
+
instanceId: string;
|
|
145
|
+
damage: number;
|
|
146
|
+
operation: "add" | "remove" | "set";
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface QuestMove extends BaseMove {
|
|
150
|
+
type: "QUEST";
|
|
151
|
+
instanceId: string;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export interface QuestWithAllMove extends BaseMove {
|
|
155
|
+
type: "QUEST_WITH_ALL";
|
|
156
|
+
playerId: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface TapCardMove extends BaseMove {
|
|
160
|
+
type: "TAP_CARD";
|
|
161
|
+
instanceId: string;
|
|
162
|
+
exerted?: boolean;
|
|
163
|
+
toggle?: boolean;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface MoveCardMove extends BaseMove {
|
|
167
|
+
type: "MOVE_CARD";
|
|
168
|
+
instanceId: string;
|
|
169
|
+
to: Zones;
|
|
170
|
+
position: "first" | "last";
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export interface TutorCardMove extends BaseMove {
|
|
174
|
+
type: "TUTOR_CARD";
|
|
175
|
+
instanceId: string;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface RevealCardMove extends BaseMove {
|
|
179
|
+
type: "REVEAL_CARD";
|
|
180
|
+
instanceId: string;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export interface UpdateLoreMove extends BaseMove {
|
|
184
|
+
type: "UPDATE_LORE";
|
|
185
|
+
player: string;
|
|
186
|
+
lore: number;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export interface DrawCardMove extends BaseMove {
|
|
190
|
+
type: "DRAW_CARD";
|
|
191
|
+
player: string;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export interface ShuffleDeckMove extends BaseMove {
|
|
195
|
+
type: "SHUFFLE_DECK";
|
|
196
|
+
player: string;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export interface ConcedeMatchMove extends BaseMove {
|
|
200
|
+
type: "CONCEDE_MATCH";
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export interface ConcedeGameMove extends BaseMove {
|
|
204
|
+
type: "CONCEDE_GAME";
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export interface PutCardIntoInkwellMove extends BaseMove {
|
|
208
|
+
type: "PUT_CARD_INTO_INKWELL";
|
|
209
|
+
instanceId: string;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export interface SingTogetherMove extends BaseMove {
|
|
213
|
+
type: "SING_TOGETHER";
|
|
214
|
+
song: string;
|
|
215
|
+
singers: string[];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export interface SingMove extends BaseMove {
|
|
219
|
+
type: "SING";
|
|
220
|
+
song: string;
|
|
221
|
+
singer: string;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export interface EnterLocationMove extends BaseMove {
|
|
225
|
+
type: "ENTER_LOCATION";
|
|
226
|
+
character: string;
|
|
227
|
+
location: string;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export interface MoveToLocationMove extends BaseMove {
|
|
231
|
+
type: "MOVE_TO_LOCATION";
|
|
232
|
+
character: string;
|
|
233
|
+
location: string;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export interface ChallengeMove extends BaseMove {
|
|
237
|
+
type: "CHALLENGE";
|
|
238
|
+
attacker: string;
|
|
239
|
+
defender: string;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export interface ShiftMove extends BaseMove {
|
|
243
|
+
type: "SHIFT";
|
|
244
|
+
shifter: string;
|
|
245
|
+
shifted: string;
|
|
246
|
+
costs?: string[];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export interface ScryParams {
|
|
250
|
+
top?: string[];
|
|
251
|
+
bottom?: string[];
|
|
252
|
+
hand?: string[];
|
|
253
|
+
inkwell?: string[];
|
|
254
|
+
discard?: string[];
|
|
255
|
+
play?: string[];
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export interface ScryMove extends BaseMove, ScryParams {
|
|
259
|
+
type: "SCRY";
|
|
260
|
+
playerId: string;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export interface ResolverLayerParams {
|
|
264
|
+
layerId: string;
|
|
265
|
+
targets?: string[];
|
|
266
|
+
mode?: string;
|
|
267
|
+
nameACard?: string;
|
|
268
|
+
skip?: boolean;
|
|
269
|
+
scry?: ScryParams;
|
|
270
|
+
targetPlayer?: string;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export interface ResolveLayerMove extends BaseMove, ResolverLayerParams {
|
|
274
|
+
type: "RESOLVE_LAYER";
|
|
275
|
+
activePlayer: string;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export interface SkipLayerMove extends BaseMove {
|
|
279
|
+
type: "SKIP_LAYER";
|
|
280
|
+
layerId: string;
|
|
281
|
+
activePlayer: string;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export interface AcceptOptionalLayerMove extends BaseMove {
|
|
285
|
+
type: "ACCEPT_OPTIONAL_LAYER";
|
|
286
|
+
layerId: string;
|
|
287
|
+
activePlayer: string;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export interface PlayCardMove extends BaseMove {
|
|
291
|
+
type: "PLAY_CARD";
|
|
292
|
+
instanceId: string;
|
|
293
|
+
bodyguard?: boolean;
|
|
294
|
+
alternativeCosts?: string[];
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export interface GenerateOnDemandLayerMove extends BaseMove {
|
|
298
|
+
type: "GENERATE_ON_DEMAND_LAYER";
|
|
299
|
+
instanceId: string;
|
|
300
|
+
ability: Record<string, unknown>; // ActivatedAbility
|
|
301
|
+
costs?: string[];
|
|
302
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility types for handling null/undefined checks
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Ensures a value is non-null (useful for TypeScript strict null checks)
|
|
7
|
+
* @param value The value to check
|
|
8
|
+
* @throws Error if value is null or undefined
|
|
9
|
+
*/
|
|
10
|
+
export function assertNonNull<T>(
|
|
11
|
+
value: T | null | undefined,
|
|
12
|
+
message = "Value cannot be null or undefined",
|
|
13
|
+
): asserts value is T {
|
|
14
|
+
if (value === null || value === undefined) {
|
|
15
|
+
throw new Error(message);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Returns a default value if the input is null/undefined
|
|
21
|
+
* @param value The value to check
|
|
22
|
+
* @param defaultVal The default value to return if value is null/undefined
|
|
23
|
+
*/
|
|
24
|
+
export function withDefault<T>(value: T | null | undefined, defaultVal: T): T {
|
|
25
|
+
return value === null || value === undefined ? defaultVal : value;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Type guard to check if a value is not null or undefined
|
|
30
|
+
*/
|
|
31
|
+
export function isDefined<T>(value: T | null | undefined): value is T {
|
|
32
|
+
return value !== null && value !== undefined;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Type utility that removes null from a type
|
|
37
|
+
*/
|
|
38
|
+
export type NonNull<T> = T extends null ? never : T;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Type utility that removes undefined from a type
|
|
42
|
+
*/
|
|
43
|
+
export type NonUndefined<T> = T extends undefined ? never : T;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Type utility that ensures a type is not null or undefined
|
|
47
|
+
*/
|
|
48
|
+
export type NonNullable<T> = T extends null | undefined ? never : T;
|