1
1
import { error } from '@sveltejs/kit' ;
2
2
3
3
import type { WorkBook } from '$lib/types/workbook' ;
4
+
4
5
import * as userCrud from '$lib/services/users' ;
5
6
import * as workBookCrud from '$lib/services/workbooks' ;
7
+
8
+ import { isValidUrlSlug } from '$lib/utils/url' ;
6
9
import { BAD_REQUEST , NOT_FOUND } from '$lib/constants/http-response-status-codes' ;
7
10
8
11
// See:
@@ -11,25 +14,71 @@ import { BAD_REQUEST, NOT_FOUND } from '$lib/constants/http-response-status-code
11
14
export async function getWorkbookWithAuthor (
12
15
slug : string ,
13
16
) : Promise < { workBook : WorkBook ; isExistingAuthor : boolean } > {
14
- const id = parseInt ( slug ) ;
17
+ const workBookId = parseWorkBookId ( slug ) ;
18
+ const workBookUrlSlug = parseWorkBookUrlSlug ( slug ) ;
15
19
16
- if ( Number . isNaN ( id ) ) {
20
+ if ( workBookId === null && workBookUrlSlug === null ) {
17
21
error ( BAD_REQUEST , '不正な問題集idです。' ) ;
18
22
}
19
23
20
- const workBook = await workBookCrud . getWorkBook ( id ) ;
24
+ let workBook : WorkBook | null = null ;
25
+
26
+ if ( workBookId ) {
27
+ workBook = await workBookCrud . getWorkBook ( workBookId ) ;
28
+ } else if ( workBookUrlSlug ) {
29
+ workBook = await workBookCrud . getWorkBookByUrlSlug ( workBookUrlSlug ) ;
30
+ }
21
31
22
- if ( ! workBook ) {
23
- error ( NOT_FOUND , `問題集id: ${ id } は見つかりませんでした。` ) ;
32
+ if ( workBook === null ) {
33
+ error ( NOT_FOUND , `問題集id: ${ slug } は見つかりませんでした。` ) ;
24
34
}
25
35
26
- // ユーザが問題集を作成したあとに、アカウントが削除されていないかを確認
36
+ // Validate if the author of the workbook exists after the workbook has been created.
27
37
const workbookAuthor = await userCrud . getUserById ( workBook . authorId ) ;
28
38
const isExistingAuthor = workbookAuthor ? true : false ;
29
39
30
40
return { workBook : workBook , isExistingAuthor : isExistingAuthor } ;
31
41
}
32
42
43
+ /**
44
+ * Finds a workbook ID from a given slug string.
45
+ *
46
+ * This function first attempts to parse the slug as a direct workbook ID.
47
+ * If that fails, it tries to parse it as a workbook URL slug and looks up
48
+ * the corresponding workbook in the database.
49
+ *
50
+ * @param slug - The slug string to search for, can be either a numeric ID or URL slug
51
+ * @returns A Promise that resolves to the workbook ID if found, or null if not found
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * // Using numeric ID
56
+ * const id1 = await findWorkBookIdFrom("123");
57
+ *
58
+ * // Using URL slug
59
+ * const id2 = await findWorkBookIdFrom("union-find");
60
+ * ```
61
+ */
62
+ export async function findWorkBookIdFrom ( slug : string ) : Promise < number | null > {
63
+ const workBookId = parseWorkBookId ( slug ) ;
64
+
65
+ if ( workBookId !== null ) {
66
+ return workBookId ;
67
+ }
68
+
69
+ const workBookUrlSlug = parseWorkBookUrlSlug ( slug ) ;
70
+
71
+ if ( workBookUrlSlug !== null ) {
72
+ const workBook = await workBookCrud . getWorkBookByUrlSlug ( slug ) ;
73
+
74
+ if ( workBook !== null && workBook . id !== null ) {
75
+ return workBook . id ;
76
+ }
77
+ }
78
+
79
+ return null ;
80
+ }
81
+
33
82
export function parseWorkBookId ( slug : string ) : number | null {
34
83
const isOnlyDigits = ( id : string ) => / ^ \d + $ / . test ( id ) ;
35
84
const id = Number ( slug ) ;
@@ -42,3 +91,7 @@ export function parseWorkBookId(slug: string): number | null {
42
91
43
92
return id ;
44
93
}
94
+
95
+ export function parseWorkBookUrlSlug ( slug : string ) : string | null {
96
+ return isValidUrlSlug ( slug ) ? slug : null ;
97
+ }
0 commit comments