Skip to content

Commit 7f95e95

Browse files
committed
✨ Add utils for url slug in workbook (#2020)
1 parent c2784a9 commit 7f95e95

File tree

1 file changed

+59
-6
lines changed

1 file changed

+59
-6
lines changed

src/lib/utils/workbook.ts

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { error } from '@sveltejs/kit';
22

33
import type { WorkBook } from '$lib/types/workbook';
4+
45
import * as userCrud from '$lib/services/users';
56
import * as workBookCrud from '$lib/services/workbooks';
7+
8+
import { isValidUrlSlug } from '$lib/utils/url';
69
import { 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
1114
export 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+
3382
export 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

Comments
 (0)