11import { error } from '@sveltejs/kit' ;
22
33import type { WorkBook } from '$lib/types/workbook' ;
4+
45import * as userCrud from '$lib/services/users' ;
56import * as workBookCrud from '$lib/services/workbooks' ;
7+
8+ import { isValidUrlSlug } from '$lib/utils/url' ;
69import { BAD_REQUEST , NOT_FOUND } from '$lib/constants/http-response-status-codes' ;
710
811// See:
@@ -11,25 +14,71 @@ import { BAD_REQUEST, NOT_FOUND } from '$lib/constants/http-response-status-code
1114export async function getWorkbookWithAuthor (
1215 slug : string ,
1316) : Promise < { workBook : WorkBook ; isExistingAuthor : boolean } > {
14- const id = parseInt ( slug ) ;
17+ const workBookId = parseWorkBookId ( slug ) ;
18+ const workBookUrlSlug = parseWorkBookUrlSlug ( slug ) ;
1519
16- if ( Number . isNaN ( id ) ) {
20+ if ( workBookId === null && workBookUrlSlug === null ) {
1721 error ( BAD_REQUEST , '不正な問題集idです。' ) ;
1822 }
1923
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+ }
2131
22- if ( ! workBook ) {
23- error ( NOT_FOUND , `問題集id: ${ id } は見つかりませんでした。` ) ;
32+ if ( workBook === null ) {
33+ error ( NOT_FOUND , `問題集id: ${ slug } は見つかりませんでした。` ) ;
2434 }
2535
26- // ユーザが問題集を作成したあとに、アカウントが削除されていないかを確認
36+ // Validate if the author of the workbook exists after the workbook has been created.
2737 const workbookAuthor = await userCrud . getUserById ( workBook . authorId ) ;
2838 const isExistingAuthor = workbookAuthor ? true : false ;
2939
3040 return { workBook : workBook , isExistingAuthor : isExistingAuthor } ;
3141}
3242
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+
3382export function parseWorkBookId ( slug : string ) : number | null {
3483 const isOnlyDigits = ( id : string ) => / ^ \d + $ / . test ( id ) ;
3584 const id = Number ( slug ) ;
@@ -42,3 +91,7 @@ export function parseWorkBookId(slug: string): number | null {
4291
4392 return id ;
4493}
94+
95+ export function parseWorkBookUrlSlug ( slug : string ) : string | null {
96+ return isValidUrlSlug ( slug ) ? slug : null ;
97+ }
0 commit comments