@vestcards/server-types 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apps/server/src/app.d.ts +155 -4
- package/dist/apps/server/src/config/env.d.ts +2 -2
- package/dist/apps/server/src/libs/mappers.d.ts +5 -0
- package/dist/apps/server/src/modules/auth/index.d.ts +2 -2
- package/dist/apps/server/src/modules/auth/lib.d.ts +69 -16
- package/dist/apps/server/src/modules/auth/utils.d.ts +1 -0
- package/dist/apps/server/src/modules/card/index.d.ts +92 -3
- package/dist/apps/server/src/modules/card/model.d.ts +17 -0
- package/dist/apps/server/src/modules/card/service.d.ts +8 -1
- package/dist/apps/server/src/modules/deck/index.d.ts +2 -2
- package/dist/apps/server/src/modules/library/index.d.ts +2 -2
- package/dist/apps/server/src/modules/study/index.d.ts +2 -2
- package/dist/apps/server/src/modules/study/service.d.ts +3 -3
- package/dist/apps/server/src/modules/topic/index.d.ts +2 -2
- package/dist/apps/server/src/modules/user/errors.d.ts +3 -0
- package/dist/apps/server/src/modules/user/index.d.ts +65 -3
- package/dist/apps/server/src/modules/user/model.d.ts +6 -0
- package/dist/apps/server/src/modules/user/service.d.ts +4 -0
- package/dist/apps/server/src/tests/helpers/fixtures.d.ts +1 -0
- package/dist/apps/server/src/utils/api.d.ts +1 -1
- package/dist/apps/server/src/utils/select.d.ts +17 -0
- package/dist/packages/db-core/src/schema/auth.d.ts +60 -0
- package/dist/packages/db-core/src/schema/deck.d.ts +17 -0
- package/dist/packages/db-core/src/schema/index.d.ts +1 -0
- package/dist/packages/email-core/src/templates/deleteAccountRequest.d.ts +8 -0
- package/dist/packages/email-core/src/templates/footer.d.ts +1 -1
- package/dist/packages/email-core/src/templates/index.d.ts +2 -0
- package/dist/packages/shared/src/spaced-repetition/config.d.ts +5 -0
- package/dist/packages/shared/src/spaced-repetition/fsrs.d.ts +13 -0
- package/dist/packages/shared/src/spaced-repetition/index.d.ts +4 -0
- package/dist/packages/shared/src/spaced-repetition/session-manager.d.ts +25 -0
- package/dist/packages/shared/src/spaced-repetition/utils.d.ts +26 -0
- package/dist/packages/shared/src/theme/tokens/border.d.ts +1 -1
- package/dist/packages/shared/src/types/deck.d.ts +11 -1
- package/dist/packages/shared/src/types/permissions.d.ts +4 -0
- package/package.json +1 -1
- package/dist/apps/server/src/modules/study/lib/fsrs.d.ts +0 -12
- /package/dist/apps/server/src/modules/study/{lib/constants.d.ts → constants.d.ts} +0 -0
|
@@ -65,7 +65,7 @@ declare const app: Elysia<"", {
|
|
|
65
65
|
route: string;
|
|
66
66
|
request: Request;
|
|
67
67
|
store: {};
|
|
68
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
68
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
69
69
|
readonly 100: "Continue";
|
|
70
70
|
readonly 101: "Switching Protocols";
|
|
71
71
|
readonly 102: "Processing";
|
|
@@ -239,7 +239,7 @@ declare const app: Elysia<"", {
|
|
|
239
239
|
route: string;
|
|
240
240
|
request: Request;
|
|
241
241
|
store: {};
|
|
242
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
242
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
243
243
|
readonly 100: "Continue";
|
|
244
244
|
readonly 101: "Switching Protocols";
|
|
245
245
|
readonly 102: "Processing";
|
|
@@ -450,11 +450,11 @@ declare const app: Elysia<"", {
|
|
|
450
450
|
headers: {};
|
|
451
451
|
response: {
|
|
452
452
|
200: {
|
|
453
|
+
status: "not-reviewed" | "card-updated" | "demand-rejected" | "card-removed";
|
|
453
454
|
type: string;
|
|
454
455
|
createdAt: Date;
|
|
455
456
|
updatedAt: Date;
|
|
456
457
|
userId: string;
|
|
457
|
-
status: "not-reviewed" | "card-updated" | "demand-rejected" | "card-removed";
|
|
458
458
|
cardId: string;
|
|
459
459
|
content: string;
|
|
460
460
|
} | null;
|
|
@@ -503,6 +503,95 @@ declare const app: Elysia<"", {
|
|
|
503
503
|
};
|
|
504
504
|
};
|
|
505
505
|
};
|
|
506
|
+
} & {
|
|
507
|
+
v1: {
|
|
508
|
+
card: {
|
|
509
|
+
suspend: {
|
|
510
|
+
post: {
|
|
511
|
+
body: {
|
|
512
|
+
cardId: string;
|
|
513
|
+
};
|
|
514
|
+
params: {};
|
|
515
|
+
query: {};
|
|
516
|
+
headers: {};
|
|
517
|
+
response: {
|
|
518
|
+
200: {
|
|
519
|
+
success: boolean;
|
|
520
|
+
};
|
|
521
|
+
422: {
|
|
522
|
+
type: "validation";
|
|
523
|
+
on: string;
|
|
524
|
+
summary?: string;
|
|
525
|
+
message?: string;
|
|
526
|
+
found?: unknown;
|
|
527
|
+
property?: string;
|
|
528
|
+
expected?: string;
|
|
529
|
+
};
|
|
530
|
+
};
|
|
531
|
+
};
|
|
532
|
+
};
|
|
533
|
+
};
|
|
534
|
+
};
|
|
535
|
+
} & {
|
|
536
|
+
v1: {
|
|
537
|
+
card: {
|
|
538
|
+
suspend: {
|
|
539
|
+
delete: {
|
|
540
|
+
body: {};
|
|
541
|
+
params: {};
|
|
542
|
+
query: {
|
|
543
|
+
cardId: string;
|
|
544
|
+
};
|
|
545
|
+
headers: {};
|
|
546
|
+
response: {
|
|
547
|
+
200: {
|
|
548
|
+
success: boolean;
|
|
549
|
+
};
|
|
550
|
+
422: {
|
|
551
|
+
type: "validation";
|
|
552
|
+
on: string;
|
|
553
|
+
summary?: string;
|
|
554
|
+
message?: string;
|
|
555
|
+
found?: unknown;
|
|
556
|
+
property?: string;
|
|
557
|
+
expected?: string;
|
|
558
|
+
};
|
|
559
|
+
};
|
|
560
|
+
};
|
|
561
|
+
};
|
|
562
|
+
};
|
|
563
|
+
};
|
|
564
|
+
} & {
|
|
565
|
+
v1: {
|
|
566
|
+
card: {
|
|
567
|
+
"user-state": {
|
|
568
|
+
get: {
|
|
569
|
+
body: {};
|
|
570
|
+
params: {};
|
|
571
|
+
query: {
|
|
572
|
+
deckId: string;
|
|
573
|
+
};
|
|
574
|
+
headers: {};
|
|
575
|
+
response: {
|
|
576
|
+
200: {
|
|
577
|
+
cardId: string;
|
|
578
|
+
suspended: boolean;
|
|
579
|
+
toReview: boolean;
|
|
580
|
+
}[];
|
|
581
|
+
422: {
|
|
582
|
+
type: "validation";
|
|
583
|
+
on: string;
|
|
584
|
+
summary?: string;
|
|
585
|
+
message?: string;
|
|
586
|
+
found?: unknown;
|
|
587
|
+
property?: string;
|
|
588
|
+
expected?: string;
|
|
589
|
+
};
|
|
590
|
+
};
|
|
591
|
+
};
|
|
592
|
+
};
|
|
593
|
+
};
|
|
594
|
+
};
|
|
506
595
|
} & {
|
|
507
596
|
v1: {
|
|
508
597
|
decks: {
|
|
@@ -1165,6 +1254,68 @@ declare const app: Elysia<"", {
|
|
|
1165
1254
|
};
|
|
1166
1255
|
};
|
|
1167
1256
|
};
|
|
1257
|
+
} & {
|
|
1258
|
+
v1: {
|
|
1259
|
+
user: {
|
|
1260
|
+
account: {
|
|
1261
|
+
"delete-request": {
|
|
1262
|
+
post: {
|
|
1263
|
+
body: {
|
|
1264
|
+
email: string;
|
|
1265
|
+
};
|
|
1266
|
+
params: {};
|
|
1267
|
+
query: {};
|
|
1268
|
+
headers: {};
|
|
1269
|
+
response: {
|
|
1270
|
+
200: {
|
|
1271
|
+
success: boolean;
|
|
1272
|
+
};
|
|
1273
|
+
422: {
|
|
1274
|
+
type: "validation";
|
|
1275
|
+
on: string;
|
|
1276
|
+
summary?: string;
|
|
1277
|
+
message?: string;
|
|
1278
|
+
found?: unknown;
|
|
1279
|
+
property?: string;
|
|
1280
|
+
expected?: string;
|
|
1281
|
+
};
|
|
1282
|
+
};
|
|
1283
|
+
};
|
|
1284
|
+
};
|
|
1285
|
+
};
|
|
1286
|
+
};
|
|
1287
|
+
};
|
|
1288
|
+
} & {
|
|
1289
|
+
v1: {
|
|
1290
|
+
user: {
|
|
1291
|
+
account: {
|
|
1292
|
+
"confirm-delete": {
|
|
1293
|
+
post: {
|
|
1294
|
+
body: {
|
|
1295
|
+
token: string;
|
|
1296
|
+
};
|
|
1297
|
+
params: {};
|
|
1298
|
+
query: {};
|
|
1299
|
+
headers: {};
|
|
1300
|
+
response: {
|
|
1301
|
+
200: {
|
|
1302
|
+
success: boolean;
|
|
1303
|
+
};
|
|
1304
|
+
422: {
|
|
1305
|
+
type: "validation";
|
|
1306
|
+
on: string;
|
|
1307
|
+
summary?: string;
|
|
1308
|
+
message?: string;
|
|
1309
|
+
found?: unknown;
|
|
1310
|
+
property?: string;
|
|
1311
|
+
expected?: string;
|
|
1312
|
+
};
|
|
1313
|
+
};
|
|
1314
|
+
};
|
|
1315
|
+
};
|
|
1316
|
+
};
|
|
1317
|
+
};
|
|
1318
|
+
};
|
|
1168
1319
|
} & {
|
|
1169
1320
|
v1: {
|
|
1170
1321
|
user: {
|
|
@@ -1190,8 +1341,8 @@ declare const app: Elysia<"", {
|
|
|
1190
1341
|
"complete-profile": {
|
|
1191
1342
|
post: {
|
|
1192
1343
|
body: {
|
|
1193
|
-
dayTimeReminder?: string | undefined;
|
|
1194
1344
|
university?: number | undefined;
|
|
1345
|
+
dayTimeReminder?: string | undefined;
|
|
1195
1346
|
course?: number | undefined;
|
|
1196
1347
|
goal: string;
|
|
1197
1348
|
hoursStudied: string;
|
|
@@ -2,8 +2,8 @@ export declare const config: {
|
|
|
2
2
|
databaseUrl: string;
|
|
3
3
|
baseUrl: string;
|
|
4
4
|
webAppUrl: string;
|
|
5
|
-
redisUrl: string
|
|
6
|
-
redisToken: string
|
|
5
|
+
redisUrl: string;
|
|
6
|
+
redisToken: string;
|
|
7
7
|
betterAuthSecret: string;
|
|
8
8
|
googleClientId: string;
|
|
9
9
|
googleClientSecret: string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CardReview, NewCardReview, NewReviewLog } from '@vestcards/db-core';
|
|
2
|
+
import type { ICardReview, IReviewLog } from '@vestcards/shared';
|
|
3
|
+
export declare function cardReviewToICardReview(row: CardReview): ICardReview;
|
|
4
|
+
export declare function iCardReviewToNewCardReview(card: ICardReview): NewCardReview;
|
|
5
|
+
export declare function iReviewLogToNewReviewLog(log: IReviewLog): NewReviewLog;
|
|
@@ -41,7 +41,7 @@ export declare const authModule: Elysia<"/v1", {
|
|
|
41
41
|
route: string;
|
|
42
42
|
request: Request;
|
|
43
43
|
store: {};
|
|
44
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
44
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
45
45
|
readonly 100: "Continue";
|
|
46
46
|
readonly 101: "Switching Protocols";
|
|
47
47
|
readonly 102: "Processing";
|
|
@@ -215,7 +215,7 @@ export declare const authModule: Elysia<"/v1", {
|
|
|
215
215
|
route: string;
|
|
216
216
|
request: Request;
|
|
217
217
|
store: {};
|
|
218
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
218
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
219
219
|
readonly 100: "Continue";
|
|
220
220
|
readonly 101: "Switching Protocols";
|
|
221
221
|
readonly 102: "Processing";
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { UserRole } from '@vestcards/shared';
|
|
2
2
|
import { type BetterAuthOptions } from 'better-auth';
|
|
3
3
|
export declare const auth: import("better-auth").Auth<{
|
|
4
|
-
plugins:
|
|
4
|
+
plugins: ({
|
|
5
5
|
id: "open-api";
|
|
6
|
+
version: string;
|
|
6
7
|
endpoints: {
|
|
7
8
|
generateOpenAPISchema: import("better-call").StrictEndpoint<"/open-api/generate-schema", {
|
|
8
9
|
method: "GET";
|
|
@@ -52,8 +53,9 @@ export declare const auth: import("better-auth").Auth<{
|
|
|
52
53
|
}, Response>;
|
|
53
54
|
};
|
|
54
55
|
options: NoInfer<import("better-auth/plugins").OpenAPIOptions>;
|
|
55
|
-
}
|
|
56
|
+
} | {
|
|
56
57
|
id: "expo";
|
|
58
|
+
version: string;
|
|
57
59
|
init: (ctx: import("better-auth").AuthContext) => {
|
|
58
60
|
options: {
|
|
59
61
|
trustedOrigins: string[];
|
|
@@ -71,10 +73,10 @@ export declare const auth: import("better-auth").Auth<{
|
|
|
71
73
|
endpoints: {
|
|
72
74
|
expoAuthorizationProxy: import("better-call").StrictEndpoint<"/expo-authorization-proxy", {
|
|
73
75
|
method: "GET";
|
|
74
|
-
query: import("
|
|
75
|
-
authorizationURL: import("
|
|
76
|
-
oauthState: import("
|
|
77
|
-
}, import("
|
|
76
|
+
query: import("zod").ZodObject<{
|
|
77
|
+
authorizationURL: import("zod").ZodString;
|
|
78
|
+
oauthState: import("zod").ZodOptional<import("zod").ZodString>;
|
|
79
|
+
}, import("zod/v4/core").$strip>;
|
|
78
80
|
metadata: {
|
|
79
81
|
readonly scope: "server";
|
|
80
82
|
};
|
|
@@ -94,8 +96,27 @@ export declare const auth: import("better-auth").Auth<{
|
|
|
94
96
|
}>;
|
|
95
97
|
};
|
|
96
98
|
options: import("@better-auth/expo").ExpoOptions | undefined;
|
|
97
|
-
}
|
|
99
|
+
} | {
|
|
100
|
+
id: "bearer";
|
|
101
|
+
version: string;
|
|
102
|
+
hooks: {
|
|
103
|
+
before: {
|
|
104
|
+
matcher(context: import("better-auth").HookEndpointContext): boolean;
|
|
105
|
+
handler: (inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
|
|
106
|
+
context: {
|
|
107
|
+
headers: Headers;
|
|
108
|
+
};
|
|
109
|
+
} | undefined>;
|
|
110
|
+
}[];
|
|
111
|
+
after: {
|
|
112
|
+
matcher(context: import("better-auth").HookEndpointContext): true;
|
|
113
|
+
handler: (inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<void>;
|
|
114
|
+
}[];
|
|
115
|
+
};
|
|
116
|
+
options: import("better-auth/plugins").BearerOptions | undefined;
|
|
117
|
+
} | {
|
|
98
118
|
id: "custom-session";
|
|
119
|
+
version: string;
|
|
99
120
|
hooks: {
|
|
100
121
|
after: {
|
|
101
122
|
matcher: (ctx: import("better-auth").HookEndpointContext) => boolean;
|
|
@@ -130,10 +151,10 @@ export declare const auth: import("better-auth").Auth<{
|
|
|
130
151
|
endpoints: {
|
|
131
152
|
getSession: import("better-call").StrictEndpoint<"/get-session", {
|
|
132
153
|
method: "GET";
|
|
133
|
-
query: import("
|
|
134
|
-
disableCookieCache: import("
|
|
135
|
-
disableRefresh: import("
|
|
136
|
-
}, import("
|
|
154
|
+
query: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
155
|
+
disableCookieCache: import("zod").ZodOptional<import("zod").ZodUnion<[import("zod").ZodBoolean, import("zod").ZodPipe<import("zod").ZodString, import("zod").ZodTransform<boolean, string>>]>>;
|
|
156
|
+
disableRefresh: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
157
|
+
}, import("zod/v4/core").$strip>>;
|
|
137
158
|
metadata: {
|
|
138
159
|
CUSTOM_SESSION: boolean;
|
|
139
160
|
openapi: {
|
|
@@ -213,15 +234,15 @@ export declare const auth: import("better-auth").Auth<{
|
|
|
213
234
|
};
|
|
214
235
|
};
|
|
215
236
|
options: import("better-auth/plugins").CustomSessionPluginOptions | undefined;
|
|
216
|
-
}];
|
|
237
|
+
})[];
|
|
217
238
|
baseURL: string;
|
|
218
239
|
basePath: string;
|
|
219
240
|
database: (options: BetterAuthOptions) => import("better-auth").DBAdapter<BetterAuthOptions>;
|
|
220
241
|
secondaryStorage: import("better-auth").SecondaryStorage | undefined;
|
|
221
242
|
emailAndPassword: {
|
|
222
243
|
enabled: true;
|
|
223
|
-
autoSignIn:
|
|
224
|
-
requireEmailVerification:
|
|
244
|
+
autoSignIn: true;
|
|
245
|
+
requireEmailVerification: false;
|
|
225
246
|
minPasswordLength: number;
|
|
226
247
|
maxPasswordLength: number;
|
|
227
248
|
password: {
|
|
@@ -268,6 +289,10 @@ export declare const auth: import("better-auth").Auth<{
|
|
|
268
289
|
google: {
|
|
269
290
|
clientId: string;
|
|
270
291
|
clientSecret: string;
|
|
292
|
+
mapProfileToUser: (profile: import("better-auth").GoogleProfile) => {
|
|
293
|
+
name: string;
|
|
294
|
+
surname: string;
|
|
295
|
+
};
|
|
271
296
|
};
|
|
272
297
|
apple: {
|
|
273
298
|
clientId: string;
|
|
@@ -318,16 +343,41 @@ export declare const auth: import("better-auth").Auth<{
|
|
|
318
343
|
}>;
|
|
319
344
|
};
|
|
320
345
|
};
|
|
346
|
+
session: {
|
|
347
|
+
create: {
|
|
348
|
+
before: (session: {
|
|
349
|
+
id: string;
|
|
350
|
+
createdAt: Date;
|
|
351
|
+
updatedAt: Date;
|
|
352
|
+
userId: string;
|
|
353
|
+
expiresAt: Date;
|
|
354
|
+
token: string;
|
|
355
|
+
ipAddress?: string | null | undefined;
|
|
356
|
+
userAgent?: string | null | undefined;
|
|
357
|
+
} & Record<string, unknown>) => Promise<{
|
|
358
|
+
data: {
|
|
359
|
+
id: string;
|
|
360
|
+
createdAt: Date;
|
|
361
|
+
updatedAt: Date;
|
|
362
|
+
userId: string;
|
|
363
|
+
expiresAt: Date;
|
|
364
|
+
token: string;
|
|
365
|
+
ipAddress?: string | null | undefined;
|
|
366
|
+
userAgent?: string | null | undefined;
|
|
367
|
+
} & Record<string, unknown>;
|
|
368
|
+
}>;
|
|
369
|
+
};
|
|
370
|
+
};
|
|
321
371
|
};
|
|
322
372
|
logger: {
|
|
323
|
-
log(level: "
|
|
373
|
+
log(level: "error" | "warn" | "info" | "debug", message: string, ...args: any[]): void;
|
|
324
374
|
};
|
|
325
375
|
advanced: {
|
|
326
376
|
useSecureCookies: boolean;
|
|
327
377
|
disableOriginCheck: true;
|
|
328
378
|
cookiePrefix: string;
|
|
329
379
|
defaultCookieAttributes: {
|
|
330
|
-
sameSite: "
|
|
380
|
+
sameSite: "lax" | "none";
|
|
331
381
|
secure: boolean;
|
|
332
382
|
};
|
|
333
383
|
database: {
|
|
@@ -335,5 +385,8 @@ export declare const auth: import("better-auth").Auth<{
|
|
|
335
385
|
};
|
|
336
386
|
};
|
|
337
387
|
trustedOrigins: string[];
|
|
388
|
+
hooks: {
|
|
389
|
+
before: (inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<void>;
|
|
390
|
+
};
|
|
338
391
|
}>;
|
|
339
392
|
export type Auth = typeof auth;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BetterAuthOptions } from 'better-auth';
|
|
2
|
+
export declare function assertCredentialAccount(userId: string): Promise<void>;
|
|
2
3
|
type SendVerificationEmail = NonNullable<BetterAuthOptions['emailVerification']>['sendVerificationEmail'];
|
|
3
4
|
export declare const sendVerificationEmail: SendVerificationEmail;
|
|
4
5
|
type SendResetPassword = NonNullable<BetterAuthOptions['emailAndPassword']>['sendResetPassword'];
|
|
@@ -42,7 +42,7 @@ export declare const cardModule: Elysia<"/v1/card", {
|
|
|
42
42
|
route: string;
|
|
43
43
|
request: Request;
|
|
44
44
|
store: {};
|
|
45
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
45
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
46
46
|
readonly 100: "Continue";
|
|
47
47
|
readonly 101: "Switching Protocols";
|
|
48
48
|
readonly 102: "Processing";
|
|
@@ -216,7 +216,7 @@ export declare const cardModule: Elysia<"/v1/card", {
|
|
|
216
216
|
route: string;
|
|
217
217
|
request: Request;
|
|
218
218
|
store: {};
|
|
219
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
219
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
220
220
|
readonly 100: "Continue";
|
|
221
221
|
readonly 101: "Switching Protocols";
|
|
222
222
|
readonly 102: "Processing";
|
|
@@ -392,11 +392,11 @@ export declare const cardModule: Elysia<"/v1/card", {
|
|
|
392
392
|
headers: {};
|
|
393
393
|
response: {
|
|
394
394
|
200: {
|
|
395
|
+
status: "not-reviewed" | "card-updated" | "demand-rejected" | "card-removed";
|
|
395
396
|
type: string;
|
|
396
397
|
createdAt: Date;
|
|
397
398
|
updatedAt: Date;
|
|
398
399
|
userId: string;
|
|
399
|
-
status: "not-reviewed" | "card-updated" | "demand-rejected" | "card-removed";
|
|
400
400
|
cardId: string;
|
|
401
401
|
content: string;
|
|
402
402
|
} | null;
|
|
@@ -445,6 +445,95 @@ export declare const cardModule: Elysia<"/v1/card", {
|
|
|
445
445
|
};
|
|
446
446
|
};
|
|
447
447
|
};
|
|
448
|
+
} & {
|
|
449
|
+
v1: {
|
|
450
|
+
card: {
|
|
451
|
+
suspend: {
|
|
452
|
+
post: {
|
|
453
|
+
body: {
|
|
454
|
+
cardId: string;
|
|
455
|
+
};
|
|
456
|
+
params: {};
|
|
457
|
+
query: {};
|
|
458
|
+
headers: {};
|
|
459
|
+
response: {
|
|
460
|
+
200: {
|
|
461
|
+
success: boolean;
|
|
462
|
+
};
|
|
463
|
+
422: {
|
|
464
|
+
type: "validation";
|
|
465
|
+
on: string;
|
|
466
|
+
summary?: string;
|
|
467
|
+
message?: string;
|
|
468
|
+
found?: unknown;
|
|
469
|
+
property?: string;
|
|
470
|
+
expected?: string;
|
|
471
|
+
};
|
|
472
|
+
};
|
|
473
|
+
};
|
|
474
|
+
};
|
|
475
|
+
};
|
|
476
|
+
};
|
|
477
|
+
} & {
|
|
478
|
+
v1: {
|
|
479
|
+
card: {
|
|
480
|
+
suspend: {
|
|
481
|
+
delete: {
|
|
482
|
+
body: {};
|
|
483
|
+
params: {};
|
|
484
|
+
query: {
|
|
485
|
+
cardId: string;
|
|
486
|
+
};
|
|
487
|
+
headers: {};
|
|
488
|
+
response: {
|
|
489
|
+
200: {
|
|
490
|
+
success: boolean;
|
|
491
|
+
};
|
|
492
|
+
422: {
|
|
493
|
+
type: "validation";
|
|
494
|
+
on: string;
|
|
495
|
+
summary?: string;
|
|
496
|
+
message?: string;
|
|
497
|
+
found?: unknown;
|
|
498
|
+
property?: string;
|
|
499
|
+
expected?: string;
|
|
500
|
+
};
|
|
501
|
+
};
|
|
502
|
+
};
|
|
503
|
+
};
|
|
504
|
+
};
|
|
505
|
+
};
|
|
506
|
+
} & {
|
|
507
|
+
v1: {
|
|
508
|
+
card: {
|
|
509
|
+
"user-state": {
|
|
510
|
+
get: {
|
|
511
|
+
body: {};
|
|
512
|
+
params: {};
|
|
513
|
+
query: {
|
|
514
|
+
deckId: string;
|
|
515
|
+
};
|
|
516
|
+
headers: {};
|
|
517
|
+
response: {
|
|
518
|
+
200: {
|
|
519
|
+
cardId: string;
|
|
520
|
+
suspended: boolean;
|
|
521
|
+
toReview: boolean;
|
|
522
|
+
}[];
|
|
523
|
+
422: {
|
|
524
|
+
type: "validation";
|
|
525
|
+
on: string;
|
|
526
|
+
summary?: string;
|
|
527
|
+
message?: string;
|
|
528
|
+
found?: unknown;
|
|
529
|
+
property?: string;
|
|
530
|
+
expected?: string;
|
|
531
|
+
};
|
|
532
|
+
};
|
|
533
|
+
};
|
|
534
|
+
};
|
|
535
|
+
};
|
|
536
|
+
};
|
|
448
537
|
}, {
|
|
449
538
|
derive: {};
|
|
450
539
|
resolve: {};
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export declare namespace CardModel {
|
|
2
|
+
/**
|
|
3
|
+
* Whether a card counts as "to review" in the deck view.
|
|
4
|
+
* Uses end-of-day cutoff to match StudyService.getReviewCards behaviour.
|
|
5
|
+
*/
|
|
6
|
+
function isCardToReview(state: string, suspended: boolean, due: Date | null, now?: Date): boolean;
|
|
2
7
|
const reportBody: import("@sinclair/typebox").TObject<{
|
|
3
8
|
cardId: import("@sinclair/typebox").TString;
|
|
4
9
|
content: import("@sinclair/typebox").TString;
|
|
@@ -9,4 +14,16 @@ export declare namespace CardModel {
|
|
|
9
14
|
cardId: import("@sinclair/typebox").TString;
|
|
10
15
|
}>;
|
|
11
16
|
type ReportQuery = typeof reportQuery.static;
|
|
17
|
+
const suspendBody: import("@sinclair/typebox").TObject<{
|
|
18
|
+
cardId: import("@sinclair/typebox").TString;
|
|
19
|
+
}>;
|
|
20
|
+
type SuspendBody = typeof suspendBody.static;
|
|
21
|
+
const suspendQuery: import("@sinclair/typebox").TObject<{
|
|
22
|
+
cardId: import("@sinclair/typebox").TString;
|
|
23
|
+
}>;
|
|
24
|
+
type SuspendQuery = typeof suspendQuery.static;
|
|
25
|
+
const userStateQuery: import("@sinclair/typebox").TObject<{
|
|
26
|
+
deckId: import("@sinclair/typebox").TString;
|
|
27
|
+
}>;
|
|
28
|
+
type UserStateQuery = typeof userStateQuery.static;
|
|
12
29
|
}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { CardDemand } from '@vestcards/db-core';
|
|
2
|
-
import
|
|
2
|
+
import { CardModel } from './model';
|
|
3
3
|
export declare abstract class CardService {
|
|
4
4
|
static getReport(userId: string, cardId: string): Promise<CardDemand | null>;
|
|
5
|
+
static suspendCard(userId: string, cardId: string): Promise<boolean>;
|
|
6
|
+
static unsuspendCard(userId: string, cardId: string): Promise<boolean>;
|
|
7
|
+
static getUserState(userId: string, deckId: string): Promise<{
|
|
8
|
+
cardId: string;
|
|
9
|
+
suspended: boolean;
|
|
10
|
+
toReview: boolean;
|
|
11
|
+
}[]>;
|
|
5
12
|
static reportCard(userId: string, body: CardModel.ReportBody): Promise<void>;
|
|
6
13
|
}
|
|
@@ -42,7 +42,7 @@ export declare const deckModule: Elysia<"/v1/decks", {
|
|
|
42
42
|
route: string;
|
|
43
43
|
request: Request;
|
|
44
44
|
store: {};
|
|
45
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
45
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
46
46
|
readonly 100: "Continue";
|
|
47
47
|
readonly 101: "Switching Protocols";
|
|
48
48
|
readonly 102: "Processing";
|
|
@@ -216,7 +216,7 @@ export declare const deckModule: Elysia<"/v1/decks", {
|
|
|
216
216
|
route: string;
|
|
217
217
|
request: Request;
|
|
218
218
|
store: {};
|
|
219
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
219
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
220
220
|
readonly 100: "Continue";
|
|
221
221
|
readonly 101: "Switching Protocols";
|
|
222
222
|
readonly 102: "Processing";
|
|
@@ -42,7 +42,7 @@ export declare const libraryModule: Elysia<"/v1/library", {
|
|
|
42
42
|
route: string;
|
|
43
43
|
request: Request;
|
|
44
44
|
store: {};
|
|
45
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
45
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
46
46
|
readonly 100: "Continue";
|
|
47
47
|
readonly 101: "Switching Protocols";
|
|
48
48
|
readonly 102: "Processing";
|
|
@@ -216,7 +216,7 @@ export declare const libraryModule: Elysia<"/v1/library", {
|
|
|
216
216
|
route: string;
|
|
217
217
|
request: Request;
|
|
218
218
|
store: {};
|
|
219
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
219
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
220
220
|
readonly 100: "Continue";
|
|
221
221
|
readonly 101: "Switching Protocols";
|
|
222
222
|
readonly 102: "Processing";
|
|
@@ -42,7 +42,7 @@ export declare const studyModule: Elysia<"/v1/study", {
|
|
|
42
42
|
route: string;
|
|
43
43
|
request: Request;
|
|
44
44
|
store: {};
|
|
45
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
45
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
46
46
|
readonly 100: "Continue";
|
|
47
47
|
readonly 101: "Switching Protocols";
|
|
48
48
|
readonly 102: "Processing";
|
|
@@ -216,7 +216,7 @@ export declare const studyModule: Elysia<"/v1/study", {
|
|
|
216
216
|
route: string;
|
|
217
217
|
request: Request;
|
|
218
218
|
store: {};
|
|
219
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
219
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
220
220
|
readonly 100: "Continue";
|
|
221
221
|
readonly 101: "Switching Protocols";
|
|
222
222
|
readonly 102: "Processing";
|
|
@@ -9,11 +9,11 @@ export declare abstract class StudyService {
|
|
|
9
9
|
static getReviewCards(userId: string, type: StudyType, id?: string, maxToFetch?: number): Promise<import("@vestcards/shared").ISessionCard[]>;
|
|
10
10
|
static getNewCards(userId: string, allocatedNewForToday: number, type: StudyType, id?: string): Promise<import("@vestcards/shared").ISessionCard[]>;
|
|
11
11
|
static getUserDeckStudy(userId: string, deckId: string): Promise<{
|
|
12
|
-
suspended: boolean;
|
|
13
12
|
id: string;
|
|
14
|
-
createdAt: Date;
|
|
15
|
-
userId: string;
|
|
16
13
|
deckId: string;
|
|
14
|
+
userId: string;
|
|
15
|
+
suspended: boolean;
|
|
16
|
+
createdAt: Date;
|
|
17
17
|
}>;
|
|
18
18
|
static getCardReview(userId: string, cardId: string): Promise<CardReview>;
|
|
19
19
|
static gradeCard(userId: string, input: StudyModel.GradeCardBody): Promise<void>;
|
|
@@ -42,7 +42,7 @@ export declare const topicModule: Elysia<"/v1/topics", {
|
|
|
42
42
|
route: string;
|
|
43
43
|
request: Request;
|
|
44
44
|
store: {};
|
|
45
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
45
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
46
46
|
readonly 100: "Continue";
|
|
47
47
|
readonly 101: "Switching Protocols";
|
|
48
48
|
readonly 102: "Processing";
|
|
@@ -216,7 +216,7 @@ export declare const topicModule: Elysia<"/v1/topics", {
|
|
|
216
216
|
route: string;
|
|
217
217
|
request: Request;
|
|
218
218
|
store: {};
|
|
219
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
219
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
220
220
|
readonly 100: "Continue";
|
|
221
221
|
readonly 101: "Switching Protocols";
|
|
222
222
|
readonly 102: "Processing";
|
|
@@ -42,7 +42,7 @@ export declare const userModule: Elysia<"/v1/user", {
|
|
|
42
42
|
route: string;
|
|
43
43
|
request: Request;
|
|
44
44
|
store: {};
|
|
45
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
45
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
46
46
|
readonly 100: "Continue";
|
|
47
47
|
readonly 101: "Switching Protocols";
|
|
48
48
|
readonly 102: "Processing";
|
|
@@ -216,7 +216,7 @@ export declare const userModule: Elysia<"/v1/user", {
|
|
|
216
216
|
route: string;
|
|
217
217
|
request: Request;
|
|
218
218
|
store: {};
|
|
219
|
-
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends
|
|
219
|
+
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 400 | 401 | 403 | 404 | 409 | 429 | 500 | 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 402 | 405 | 406 | 407 | 408 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 431 | 451 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
220
220
|
readonly 100: "Continue";
|
|
221
221
|
readonly 101: "Switching Protocols";
|
|
222
222
|
readonly 102: "Processing";
|
|
@@ -457,6 +457,68 @@ export declare const userModule: Elysia<"/v1/user", {
|
|
|
457
457
|
};
|
|
458
458
|
};
|
|
459
459
|
};
|
|
460
|
+
} & {
|
|
461
|
+
v1: {
|
|
462
|
+
user: {
|
|
463
|
+
account: {
|
|
464
|
+
"delete-request": {
|
|
465
|
+
post: {
|
|
466
|
+
body: {
|
|
467
|
+
email: string;
|
|
468
|
+
};
|
|
469
|
+
params: {};
|
|
470
|
+
query: {};
|
|
471
|
+
headers: {};
|
|
472
|
+
response: {
|
|
473
|
+
200: {
|
|
474
|
+
success: boolean;
|
|
475
|
+
};
|
|
476
|
+
422: {
|
|
477
|
+
type: "validation";
|
|
478
|
+
on: string;
|
|
479
|
+
summary?: string;
|
|
480
|
+
message?: string;
|
|
481
|
+
found?: unknown;
|
|
482
|
+
property?: string;
|
|
483
|
+
expected?: string;
|
|
484
|
+
};
|
|
485
|
+
};
|
|
486
|
+
};
|
|
487
|
+
};
|
|
488
|
+
};
|
|
489
|
+
};
|
|
490
|
+
};
|
|
491
|
+
} & {
|
|
492
|
+
v1: {
|
|
493
|
+
user: {
|
|
494
|
+
account: {
|
|
495
|
+
"confirm-delete": {
|
|
496
|
+
post: {
|
|
497
|
+
body: {
|
|
498
|
+
token: string;
|
|
499
|
+
};
|
|
500
|
+
params: {};
|
|
501
|
+
query: {};
|
|
502
|
+
headers: {};
|
|
503
|
+
response: {
|
|
504
|
+
200: {
|
|
505
|
+
success: boolean;
|
|
506
|
+
};
|
|
507
|
+
422: {
|
|
508
|
+
type: "validation";
|
|
509
|
+
on: string;
|
|
510
|
+
summary?: string;
|
|
511
|
+
message?: string;
|
|
512
|
+
found?: unknown;
|
|
513
|
+
property?: string;
|
|
514
|
+
expected?: string;
|
|
515
|
+
};
|
|
516
|
+
};
|
|
517
|
+
};
|
|
518
|
+
};
|
|
519
|
+
};
|
|
520
|
+
};
|
|
521
|
+
};
|
|
460
522
|
} & {
|
|
461
523
|
v1: {
|
|
462
524
|
user: {
|
|
@@ -482,8 +544,8 @@ export declare const userModule: Elysia<"/v1/user", {
|
|
|
482
544
|
"complete-profile": {
|
|
483
545
|
post: {
|
|
484
546
|
body: {
|
|
485
|
-
dayTimeReminder?: string | undefined;
|
|
486
547
|
university?: number | undefined;
|
|
548
|
+
dayTimeReminder?: string | undefined;
|
|
487
549
|
course?: number | undefined;
|
|
488
550
|
goal: string;
|
|
489
551
|
hoursStudied: string;
|
|
@@ -15,6 +15,12 @@ export declare namespace TopicModel {
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
export declare namespace UserModel {
|
|
18
|
+
const deleteRequestBody: import("@sinclair/typebox").TObject<{
|
|
19
|
+
email: import("@sinclair/typebox").TString;
|
|
20
|
+
}>;
|
|
21
|
+
const confirmDeleteBody: import("@sinclair/typebox").TObject<{
|
|
22
|
+
token: import("@sinclair/typebox").TString;
|
|
23
|
+
}>;
|
|
18
24
|
const updateSettingsBody: import("@sinclair/typebox").TObject<{
|
|
19
25
|
learnDailyLimit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
20
26
|
university: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TInteger, import("@sinclair/typebox").TNull]>>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MembershipStatus } from '@vestcards/shared';
|
|
2
2
|
export declare abstract class UserService {
|
|
3
|
+
private static getUserById;
|
|
3
4
|
static getLearnDailyLimit(userId: string): Promise<number>;
|
|
4
5
|
static getProfile(userId: string): Promise<{
|
|
5
6
|
id: string;
|
|
@@ -23,7 +24,10 @@ export declare abstract class UserService {
|
|
|
23
24
|
course?: number;
|
|
24
25
|
dayTimeReminder?: string;
|
|
25
26
|
}): Promise<void>;
|
|
27
|
+
private static sendDeletionEmail;
|
|
26
28
|
static deleteAccount(userId: string): Promise<void>;
|
|
29
|
+
static requestDeletion(email: string): Promise<void>;
|
|
30
|
+
static confirmDeletion(token: string): Promise<void>;
|
|
27
31
|
static getMembership(userId: string): Promise<{
|
|
28
32
|
status: MembershipStatus;
|
|
29
33
|
expiresAt: Date | null;
|
|
@@ -27,5 +27,5 @@ export declare const paginateResults: <T, TOtherData = {}>(data: T[], { size, to
|
|
|
27
27
|
size: number;
|
|
28
28
|
total: number;
|
|
29
29
|
}, aggregatedData?: TOtherData) => Paginated<T, TOtherData>;
|
|
30
|
-
export { paginationModel, searchModel, sortModel };
|
|
31
30
|
export type { Paginated, Pagination, Search, Sort };
|
|
31
|
+
export { paginationModel, searchModel, sortModel };
|
|
@@ -331,6 +331,23 @@ export declare const sessionCardSelect: {
|
|
|
331
331
|
identity: undefined;
|
|
332
332
|
generated: undefined;
|
|
333
333
|
}, {}, {}>;
|
|
334
|
+
suspended: import("drizzle-orm/pg-core").PgColumn<{
|
|
335
|
+
name: "suspended";
|
|
336
|
+
tableName: "card_review";
|
|
337
|
+
dataType: "boolean";
|
|
338
|
+
columnType: "PgBoolean";
|
|
339
|
+
data: boolean;
|
|
340
|
+
driverParam: boolean;
|
|
341
|
+
notNull: true;
|
|
342
|
+
hasDefault: true;
|
|
343
|
+
isPrimaryKey: false;
|
|
344
|
+
isAutoincrement: false;
|
|
345
|
+
hasRuntimeDefault: false;
|
|
346
|
+
enumValues: undefined;
|
|
347
|
+
baseColumn: never;
|
|
348
|
+
identity: undefined;
|
|
349
|
+
generated: undefined;
|
|
350
|
+
}, {}, {}>;
|
|
334
351
|
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
335
352
|
name: "created_at";
|
|
336
353
|
tableName: "card_review";
|
|
@@ -336,6 +336,66 @@ export declare const session: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
|
336
336
|
identity: undefined;
|
|
337
337
|
generated: undefined;
|
|
338
338
|
}, {}, {}>;
|
|
339
|
+
entitlements: import("drizzle-orm/pg-core").PgColumn<{
|
|
340
|
+
name: "entitlements";
|
|
341
|
+
tableName: "session";
|
|
342
|
+
dataType: "array";
|
|
343
|
+
columnType: "PgArray";
|
|
344
|
+
data: string[];
|
|
345
|
+
driverParam: string | string[];
|
|
346
|
+
notNull: true;
|
|
347
|
+
hasDefault: true;
|
|
348
|
+
isPrimaryKey: false;
|
|
349
|
+
isAutoincrement: false;
|
|
350
|
+
hasRuntimeDefault: false;
|
|
351
|
+
enumValues: [string, ...string[]];
|
|
352
|
+
baseColumn: import("drizzle-orm").Column<{
|
|
353
|
+
name: "entitlements";
|
|
354
|
+
tableName: "session";
|
|
355
|
+
dataType: "string";
|
|
356
|
+
columnType: "PgText";
|
|
357
|
+
data: string;
|
|
358
|
+
driverParam: string;
|
|
359
|
+
notNull: false;
|
|
360
|
+
hasDefault: false;
|
|
361
|
+
isPrimaryKey: false;
|
|
362
|
+
isAutoincrement: false;
|
|
363
|
+
hasRuntimeDefault: false;
|
|
364
|
+
enumValues: [string, ...string[]];
|
|
365
|
+
baseColumn: never;
|
|
366
|
+
identity: undefined;
|
|
367
|
+
generated: undefined;
|
|
368
|
+
}, {}, {}>;
|
|
369
|
+
identity: undefined;
|
|
370
|
+
generated: undefined;
|
|
371
|
+
}, {}, {
|
|
372
|
+
baseBuilder: import("drizzle-orm/pg-core").PgColumnBuilder<{
|
|
373
|
+
name: "entitlements";
|
|
374
|
+
dataType: "string";
|
|
375
|
+
columnType: "PgText";
|
|
376
|
+
data: string;
|
|
377
|
+
enumValues: [string, ...string[]];
|
|
378
|
+
driverParam: string;
|
|
379
|
+
}, {}, {}, import("drizzle-orm").ColumnBuilderExtraConfig>;
|
|
380
|
+
size: undefined;
|
|
381
|
+
}>;
|
|
382
|
+
completedProfile: import("drizzle-orm/pg-core").PgColumn<{
|
|
383
|
+
name: "completed_profile";
|
|
384
|
+
tableName: "session";
|
|
385
|
+
dataType: "boolean";
|
|
386
|
+
columnType: "PgBoolean";
|
|
387
|
+
data: boolean;
|
|
388
|
+
driverParam: boolean;
|
|
389
|
+
notNull: true;
|
|
390
|
+
hasDefault: true;
|
|
391
|
+
isPrimaryKey: false;
|
|
392
|
+
isAutoincrement: false;
|
|
393
|
+
hasRuntimeDefault: false;
|
|
394
|
+
enumValues: undefined;
|
|
395
|
+
baseColumn: never;
|
|
396
|
+
identity: undefined;
|
|
397
|
+
generated: undefined;
|
|
398
|
+
}, {}, {}>;
|
|
339
399
|
};
|
|
340
400
|
dialect: "pg";
|
|
341
401
|
}>;
|
|
@@ -920,6 +920,23 @@ export declare const cardReviews: import("drizzle-orm/pg-core").PgTableWithColum
|
|
|
920
920
|
identity: undefined;
|
|
921
921
|
generated: undefined;
|
|
922
922
|
}, {}, {}>;
|
|
923
|
+
suspended: import("drizzle-orm/pg-core").PgColumn<{
|
|
924
|
+
name: "suspended";
|
|
925
|
+
tableName: "card_review";
|
|
926
|
+
dataType: "boolean";
|
|
927
|
+
columnType: "PgBoolean";
|
|
928
|
+
data: boolean;
|
|
929
|
+
driverParam: boolean;
|
|
930
|
+
notNull: true;
|
|
931
|
+
hasDefault: true;
|
|
932
|
+
isPrimaryKey: false;
|
|
933
|
+
isAutoincrement: false;
|
|
934
|
+
hasRuntimeDefault: false;
|
|
935
|
+
enumValues: undefined;
|
|
936
|
+
baseColumn: never;
|
|
937
|
+
identity: undefined;
|
|
938
|
+
generated: undefined;
|
|
939
|
+
}, {}, {}>;
|
|
923
940
|
userDeckStudyId: import("drizzle-orm/pg-core").PgColumn<{
|
|
924
941
|
name: "user_deck_study_id";
|
|
925
942
|
tableName: "card_review";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const EMAILFooter
|
|
1
|
+
export declare const EMAILFooter: string;
|
|
@@ -2,6 +2,7 @@ import { type EmailAccountDeletionValues } from './accountDeletion';
|
|
|
2
2
|
import { type EmailAdminPurchaseAlertValues } from './adminPurchaseAlert';
|
|
3
3
|
import { type EmailCardDemandValues } from './cardDemand';
|
|
4
4
|
import { type EmailCardDemandActionValues } from './cardDemandAction';
|
|
5
|
+
import { type EmailDeleteAccountRequestValues } from './deleteAccountRequest';
|
|
5
6
|
import { type EmailConfirmAccountValues } from './emailVerification';
|
|
6
7
|
import { type EmailForgotPasswordValues } from './forgotPassword';
|
|
7
8
|
import { type EmailPurchaseConfirmationValues } from './purchaseConfirmation';
|
|
@@ -19,6 +20,7 @@ export interface EmailTemplateFunctions {
|
|
|
19
20
|
PurchaseConfirmation: (data: EmailPurchaseConfirmationValues) => EmailTemplateType;
|
|
20
21
|
AdminPurchaseAlert: (data: EmailAdminPurchaseAlertValues) => EmailTemplateType;
|
|
21
22
|
AccountDeletion: (data: EmailAccountDeletionValues) => EmailTemplateType;
|
|
23
|
+
DeleteAccountRequest: (data: EmailDeleteAccountRequestValues) => EmailTemplateType;
|
|
22
24
|
CardDemand: (data: EmailCardDemandValues) => EmailTemplateType;
|
|
23
25
|
CardDemandAction: (data: EmailCardDemandActionValues) => EmailTemplateType;
|
|
24
26
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Card as FSRSCard } from 'ts-fsrs';
|
|
2
|
+
import { type ReviewRating } from '../types/fsrs';
|
|
3
|
+
import type { ICardReview, IReviewLog } from '../types/study';
|
|
4
|
+
export declare const gradeCard: (card: ICardReview, rating: ReviewRating, durationInSeconds: number) => {
|
|
5
|
+
nextCard: ICardReview;
|
|
6
|
+
reviewLog: IReviewLog;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Give a {@link ICardReview}, returns the review {@link Date} for each {@link ReviewRating}.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getReviewDateForEachRating(card: ICardReview): Record<ReviewRating, Date>;
|
|
12
|
+
export declare function mergeFsrsCard(fsrsCard: FSRSCard, card: ICardReview): ICardReview;
|
|
13
|
+
export declare function newCardReview(userDeckStudyId: string, cardId: string): ICardReview;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ReviewRating } from '../types/fsrs';
|
|
2
|
+
import type { ISessionCard, ISessionData } from '../types/study';
|
|
3
|
+
export declare const RECENTLY_REVIEWED_SET_SIZE = 5;
|
|
4
|
+
export declare const defaultSessionData: ISessionData;
|
|
5
|
+
export interface SessionProgress {
|
|
6
|
+
reviewsCompleted: number;
|
|
7
|
+
correctGrades: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Encapsulates the stateful logic shared across platforms for a flashcard study session:
|
|
11
|
+
* - Recently-reviewed set (prevents immediate card repetition)
|
|
12
|
+
* - Progress counters (total reviews, correct grades)
|
|
13
|
+
* - Next card selection (delegates to getNextCardFromSession)
|
|
14
|
+
*
|
|
15
|
+
* Usage: hold an instance in a ref (React/RN), call nextCard() on each render
|
|
16
|
+
* and onRate() whenever the user grades a card.
|
|
17
|
+
*/
|
|
18
|
+
export declare class FlashcardSessionManager {
|
|
19
|
+
private recentlyReviewed;
|
|
20
|
+
private _reviewsCompleted;
|
|
21
|
+
private _correctGrades;
|
|
22
|
+
getProgress(): SessionProgress;
|
|
23
|
+
nextCard(data: ISessionData): ISessionCard | undefined;
|
|
24
|
+
onRate(cardId: string, rating: ReviewRating): SessionProgress;
|
|
25
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ReviewRating } from '../types/fsrs';
|
|
2
|
+
import type { ISessionCard, ISessionData } from '../types/study';
|
|
3
|
+
export declare function getNextCardFromSession(data: ISessionData, recentlyReviewed?: Set<string>): ISessionCard | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* Remove a card from session data without grading it (e.g. suspend + skip).
|
|
6
|
+
* Properly decrements the matching stats bucket and total.
|
|
7
|
+
*/
|
|
8
|
+
export declare function skipCardFromSessionData(data: ISessionData, cardId: string): ISessionData;
|
|
9
|
+
/**
|
|
10
|
+
* Computes the next session data after grading a card.
|
|
11
|
+
*
|
|
12
|
+
* Simulates the card grading and if the next review is within ~10 minutes,
|
|
13
|
+
* keeps the card in the session and updates the respective counter.
|
|
14
|
+
*
|
|
15
|
+
* If the card's state is `New`, then the card exists in `newCards`.
|
|
16
|
+
* If the card is any other state, then the card exists in `reviewCards`.
|
|
17
|
+
*
|
|
18
|
+
* @param grade The grade given to the card
|
|
19
|
+
* @param data The current session data
|
|
20
|
+
* @param cardId The id of the card that was graded
|
|
21
|
+
*/
|
|
22
|
+
export declare function removeCardFromSessionData(grade: ReviewRating, data: ISessionData, cardId: string): ISessionData;
|
|
23
|
+
/**
|
|
24
|
+
* Gets the card from the session data.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getSessionCard(sessionData: ISessionData, cardId: string): ISessionCard | undefined;
|
|
@@ -41,7 +41,7 @@ export interface IDeck {
|
|
|
41
41
|
subject: Subject;
|
|
42
42
|
topic?: string;
|
|
43
43
|
topicIcon?: string | null;
|
|
44
|
-
|
|
44
|
+
ownerInfo?: IOwnerInfo;
|
|
45
45
|
}
|
|
46
46
|
export interface IDeckDetail extends IDeck {
|
|
47
47
|
subject: Subject;
|
|
@@ -50,3 +50,13 @@ export interface IDeckDetail extends IDeck {
|
|
|
50
50
|
ownerInfo: IOwnerInfo;
|
|
51
51
|
cards: ICard[];
|
|
52
52
|
}
|
|
53
|
+
export interface ICardUserState {
|
|
54
|
+
cardId: string;
|
|
55
|
+
suspended: boolean;
|
|
56
|
+
toReview: boolean;
|
|
57
|
+
}
|
|
58
|
+
export interface ICardMedia {
|
|
59
|
+
id: string;
|
|
60
|
+
side: 'front' | 'back';
|
|
61
|
+
url: string;
|
|
62
|
+
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Entitlement, UserRole } from './user';
|
|
2
2
|
export declare const PERMISSIONS: {
|
|
3
|
+
readonly APP: {
|
|
4
|
+
readonly ACCESS: "app:access";
|
|
5
|
+
};
|
|
3
6
|
readonly DECK: {
|
|
4
7
|
readonly CREATE_OWN: "deck:create:own";
|
|
5
8
|
readonly CREATE_PUBLIC: "deck:create:public";
|
|
@@ -64,6 +67,7 @@ export type Permission = ValueOf<{
|
|
|
64
67
|
[K in keyof typeof PERMISSIONS]: ValueOf<(typeof PERMISSIONS)[K]>;
|
|
65
68
|
}>;
|
|
66
69
|
export declare const Permission: {
|
|
70
|
+
readonly APP_ACCESS: "app:access";
|
|
67
71
|
readonly DECK_CREATE_OWN: "deck:create:own";
|
|
68
72
|
readonly DECK_CREATE_PUBLIC: "deck:create:public";
|
|
69
73
|
readonly DECK_READ_OWN: "deck:read:own";
|
package/package.json
CHANGED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { type CardReview, type NewCardReview, type NewReviewLog, type Rating } from '@vestcards/db-core';
|
|
2
|
-
import { type Card as FSRSCard } from 'ts-fsrs';
|
|
3
|
-
export declare const gradeCard: (card: CardReview, schemaRating: Rating, durationInSeconds: number) => {
|
|
4
|
-
nextCard: CardReview;
|
|
5
|
-
reviewLog: NewReviewLog;
|
|
6
|
-
};
|
|
7
|
-
/**
|
|
8
|
-
* Give a {@link Card}, returns the review {@link Date} for each {@link Rating}.
|
|
9
|
-
*/
|
|
10
|
-
export declare function getReviewDateForEachRating(card: CardReview | NewCardReview): Record<Rating, Date>;
|
|
11
|
-
export declare function mergeFsrsCard(fsrsCard: FSRSCard, card: CardReview): CardReview;
|
|
12
|
-
export declare function newCardReview(userDeckStudyId: string, cardId: string): NewCardReview;
|
|
File without changes
|