diff --git a/.gitignore b/.gitignore index 7553d92..938355a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ /.pnp .pnp.* .yarn/* +/.next !.yarn/patches !.yarn/plugins !.yarn/releases @@ -42,4 +43,7 @@ next-env.d.ts # Test app/test/ -app/api/test \ No newline at end of file +app/api/test + +# Idea +/.idea \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..aa6015f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ +# [v1.4.0](https://github.com/SolidLoop-studio/kkuko-utils/compare/v1.3.0...v1.4.0) - 2025-12-20 + +## fix +- ([b91fdd2](https://github.com/SolidLoop-studio/kkuko-utils/commit/b91fdd2)) - 릴리즈 nodejs 버전 업데이트 +- ([e603226](https://github.com/SolidLoop-studio/kkuko-utils/commit/e603226)) - 서비스 제공자 이름 변경, 코드 라이센스 변경 + +## feat +- ([768ef96](https://github.com/SolidLoop-studio/kkuko-utils/commit/768ef96)) - implement automated release workflow and update dependencies + diff --git a/app/AutoLogin.tsx b/app/AutoLogin.tsx index db9cfb3..8d30791 100644 --- a/app/AutoLogin.tsx +++ b/app/AutoLogin.tsx @@ -14,15 +14,15 @@ const AutoLogin = () => { if (!data || !data.session || error) return; - const { data: ddata, error: err } = await SCM.get().userById(data.session.user.id); + const { data: dbdata, error: err } = await SCM.get().userById(data.session.user.id); - if (err || !ddata) return; + if (err || !dbdata) return; dispatch( userAction.setInfo({ - username: ddata.nickname, - role: ddata.role ?? "guest", - uuid: ddata.id, + username: dbdata.nickname, + role: dbdata.role ?? "guest", + uuid: dbdata.id, }) ); } diff --git a/app/ErrorPage.tsx b/app/ErrorPage.tsx index 5a1054b..1ac6b1e 100644 --- a/app/ErrorPage.tsx +++ b/app/ErrorPage.tsx @@ -6,7 +6,7 @@ import type { ErrorMessage } from "./types/type"; import { useRouter } from "next/navigation"; const ErrorPage:React.FC<{e:ErrorMessage}> = ({e}) => { - const [errork,setError] = useState(null); + const [error,setError] = useState(null); const router = useRouter(); const goBack = () => { @@ -19,7 +19,7 @@ const ErrorPage:React.FC<{e:ErrorMessage}> = ({e}) => { return (
- {errork && setError(null)} /> } + {error && setError(null)} /> }
diff --git a/app/auth/page.tsx b/app/auth/page.tsx index 102b7fb..7055cf7 100644 --- a/app/auth/page.tsx +++ b/app/auth/page.tsx @@ -16,10 +16,10 @@ export async function generateMetadata() { }; } -const OAuthpage: React.FC = () => { +const OAuthPage: React.FC = () => { return ( ) } -export default OAuthpage; \ No newline at end of file +export default OAuthPage; \ No newline at end of file diff --git a/app/header.tsx b/app/header.tsx index b433cea..9a9678f 100644 --- a/app/header.tsx +++ b/app/header.tsx @@ -64,22 +64,33 @@ const Header = () => { setTheme(theme === 'dark' ? 'light' : 'dark'); } + type NavItem = { + href: string; + label: string; + match: (pathname: string) => boolean; + }; + + const navDefs: NavItem[] = [ + { href: "/word-combiner", label: "단어조합기", match: p => p === "/word-combiner" }, + { href: "/manager-tool", label: "단어장 관리 도구", match: p => p.includes("/manager-tool") }, + { href: "/words-docs", label: "단어장 공유", match: p => p.includes("/words-docs") }, + { href: "/word", label: "오픈DB", match: p => p === "/word" || p.includes("/word/") }, + { href: "/openapi", label: "오픈API", match: p => p=== "/openapi" || p.includes("/openapi") }, + ]; + + const activeIndex = navDefs.findIndex(item => item.match(pathname)); + const navItems = [ - { href: "/word-combiner", label: "단어조합기", isActive: pathname === "/word-combiner" }, - { href: "/manager-tool", label: "단어장 관리 도구", isActive: pathname.includes('manager-tool') }, - { href: "/words-docs", label: "단어장 공유", isActive: pathname.includes('words-docs') }, - { href: "/word", label: "오픈DB", isActive: pathname==='/word' || pathname.includes('/word/') }, - { - href: "/extra-features", - label: "기타 기능", - isActive: !(pathname === "/word-combiner") && - !(pathname.includes('manager-tool')) && - !(pathname.includes('words-docs')) && - !(pathname === "/") && - !(pathname.includes('admin')) && - !(pathname.includes('/word/')) && - pathname !=='/word' - } + ...navDefs.map((item, i) => ({ + href: item.href, + label: item.label, + isActive: i === activeIndex, + })), + { + href: "/extra-features", + label: "기타 기능", + isActive: activeIndex === -1, + }, ]; return ( diff --git a/app/lib/CombinationsManger.ts b/app/lib/CombinationsManger.ts index 3f0949f..a820158 100644 --- a/app/lib/CombinationsManger.ts +++ b/app/lib/CombinationsManger.ts @@ -145,7 +145,7 @@ class CombinationManager { } /** - * 단어 사전의 단어들의 글자 출현 횟수 countting 함수 (나중에 단어들의 점수로 활용됨) + * 단어 사전의 단어들의 글자 출현 횟수 counting 함수 (나중에 단어들의 점수로 활용됨) */ private countLetter() { this.letterCount = {}; // letterCount 초기화 @@ -158,7 +158,7 @@ class CombinationManager { } /** - * 사용가능한 음절들을 countting하는 함수(음절 문자열에서 replace하는것 보다 효율적일듯) + * 사용가능한 음절들을 counting하는 함수(음절 문자열에서 replace하는것 보다 효율적일듯) */ private countSyllable() { this.syllableCount = {}; @@ -190,7 +190,7 @@ class CombinationManager { * 남아 있는 음절들을 정렬하여 반환하는 함수 * @returns {string} 정렬된 음절 문자열 */ - public remainstr(): string { + public remainStr(): string { const result = []; for (const [syllable, count] of Object.entries(this.syllableCount)) { if (count > 0) { diff --git a/app/lib/supabase/ISupabaseClientManager.ts b/app/lib/supabase/ISupabaseClientManager.ts index 57f10cc..c6bedf2 100644 --- a/app/lib/supabase/ISupabaseClientManager.ts +++ b/app/lib/supabase/ISupabaseClientManager.ts @@ -58,7 +58,7 @@ export interface IGetManager{ docsWords({ name, duem, typez }: { name: string; duem: boolean; typez: "letter" | "theme";} | {name: number; duem: boolean; typez: "ect";}): Promise<{data: null, error: PostgrestError} | {data: {words: word[], waitWords: ({ word: string; request_type: "add" | "delete"; requested_by: string | null; })[]}, error: null}> allWaitWords(c?:"add" | "delete"): Promise>; wordsThemes(wordIds: number[]): Promise> - allWords({ includeAddReq, includeDeleteReq, includeInjung, includeNoInjung, onlyWordChain, lenf }: { includeAddReq?: boolean; includeDeleteReq?: boolean; includeInjung?: boolean; includeNoInjung?: boolean; onlyWordChain?: boolean; lenf?: boolean; }): Promise<{ data: { word: string; noin_canuse: boolean; k_canuse: boolean; status: "ok" | "add" | "delete"; }[]; error: null } | {data: null; error: PostgrestError; }> + allWords({ includeAddReq, includeDeleteReq, includeInjung, includeNoInjung, onlyWordChain, lenf }: { includeAddReq?: boolean; includeDeleteReq?: boolean; includeInjung?: boolean; includeNoInjung?: boolean; onlyWordChain?: boolean; lenf?: boolean; }): Promise<{ data: { word: string; noin_canuse: boolean; k_CanUse: boolean; status: "ok" | "add" | "delete"; }[]; error: null } | {data: null; error: PostgrestError; }> letterDocs(): Promise>; addWaitDocs(): Promise>; releaseNote(): Promise>; @@ -66,7 +66,7 @@ export interface IGetManager{ session(): Promise<{data: {session: Session}, error: null} | {data: { session: null}, error: AuthError} | { data: {session: null}, error: null}>; usersByNickname(userName: string): Promise>; usersLikeByNickname(q: string): Promise>; - userByNickname(nicknmae: string): Promise>; + userByNickname(nickname: string): Promise>; monthlyConRankByUserId(userId: string): Promise>; monthlyContributionsByUserId(userId: string): Promise> starredDocsById(userId: string): Promise>; @@ -85,7 +85,7 @@ export interface IGetManager{ firstWordCountByLetters(letter: string): Promise; lastWordCountByLetters(letter: string): Promise; wordsByQuery(query: string): Promise<{data: string[], error: null} | {data: null; error: PostgrestError}>; - logsByFillter({filterState, filterType, from, to}:{filterState?: "approved" | "rejected" | "pending" | "all", filterType: "delete" | "add" | "all", from: number, to: number}): Promise> + logsByFilter({filterState, filterType, from, to}:{filterState?: "approved" | "rejected" | "pending" | "all", filterType: "delete" | "add" | "all", from: number, to: number}): Promise> docsLogsByFilter({ docsName, logType, from, to }: { docsName?: string; logType: 'add' | 'delete' | 'all'; from: number; to: number; }): Promise>; notice(): Promise>; wordsThemesByWordId(wordIds: number[]): Promise>; diff --git a/app/lib/supabase/SupabaseClientManager.ts b/app/lib/supabase/SupabaseClientManager.ts index 5ed505c..61dcd69 100644 --- a/app/lib/supabase/SupabaseClientManager.ts +++ b/app/lib/supabase/SupabaseClientManager.ts @@ -590,7 +590,7 @@ class GetManager implements IGetManager { return result; } - public async logsByFillter({ filterState, filterType, from, to }: { filterState: 'approved' | 'rejected' | 'pending' | 'all'; filterType: 'delete' | 'add' | 'all'; from: number; to: number; }) { + public async logsByFilter({ filterState, filterType, from, to }: { filterState: 'approved' | 'rejected' | 'pending' | 'all'; filterType: 'delete' | 'add' | 'all'; from: number; to: number; }) { let query = this.supabase .from('logs') .select(` diff --git a/app/manager-tool/arrange/ArrangeHome.tsx b/app/manager-tool/arrange/ArrangeHome.tsx index 3ec7ef3..e0ea7bb 100644 --- a/app/manager-tool/arrange/ArrangeHome.tsx +++ b/app/manager-tool/arrange/ArrangeHome.tsx @@ -140,12 +140,12 @@ const FileSector = ({ fileContent, fileInputRef, handleFileUpload, file, lineCou }; -const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalView }: +const ToolSector = ({ fileContent, setFileContent, setLineCount, setErrorModalView }: { fileContent: string, setFileContent: React.Dispatch>, setLineCount: React.Dispatch>, - seterrorModalView: React.Dispatch> + setErrorModalView: React.Dispatch> } ) => { const [undoStack, setUndoStack] = useState([]); @@ -163,7 +163,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi setRedoStack([]); } catch (err) { if (err instanceof Error) { - seterrorModalView({ + setErrorModalView({ ErrName: err.name, ErrMessage: err.message, ErrStackRace: err.stack, @@ -171,7 +171,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi }); } else { - seterrorModalView({ + setErrorModalView({ ErrName: null, ErrMessage: null, ErrStackRace: err as string, @@ -192,7 +192,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi } } catch (err) { if (err instanceof Error) { - seterrorModalView({ + setErrorModalView({ ErrName: err.name, ErrMessage: err.message, ErrStackRace: err.stack, @@ -200,7 +200,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi }); } else { - seterrorModalView({ + setErrorModalView({ ErrName: null, ErrMessage: null, ErrStackRace: err as string, @@ -221,7 +221,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi } } catch (err) { if (err instanceof Error) { - seterrorModalView({ + setErrorModalView({ ErrName: err.name, ErrMessage: err.message, ErrStackRace: err.stack, @@ -229,7 +229,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi }); } else { - seterrorModalView({ + setErrorModalView({ ErrName: null, ErrMessage: null, ErrStackRace: err as string, @@ -249,7 +249,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi setLineCount(updatedContent.split("\n").length); } catch (err) { if (err instanceof Error) { - seterrorModalView({ + setErrorModalView({ ErrName: err.name, ErrMessage: err.message, ErrStackRace: err.stack, @@ -257,7 +257,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi }); } else { - seterrorModalView({ + setErrorModalView({ ErrName: null, ErrMessage: null, ErrStackRace: err as string, @@ -280,7 +280,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi setLineCount(updatedContent.split("\n").length); } catch (err) { if (err instanceof Error) { - seterrorModalView({ + setErrorModalView({ ErrName: err.name, ErrMessage: err.message, ErrStackRace: err.stack, @@ -288,7 +288,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi }); } else { - seterrorModalView({ + setErrorModalView({ ErrName: null, ErrMessage: null, ErrStackRace: err as string, @@ -312,7 +312,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi setRemoveWord(""); } catch (err) { if (err instanceof Error) { - seterrorModalView({ + setErrorModalView({ ErrName: err.name, ErrMessage: err.message, ErrStackRace: err.stack, @@ -320,7 +320,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi }); } else { - seterrorModalView({ + setErrorModalView({ ErrName: null, ErrMessage: null, ErrStackRace: err as string, @@ -342,7 +342,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi setReplaceValue(""); } catch (err) { if (err instanceof Error) { - seterrorModalView({ + setErrorModalView({ ErrName: err.name, ErrMessage: err.message, ErrStackRace: err.stack, @@ -350,7 +350,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi }); } else { - seterrorModalView({ + setErrorModalView({ ErrName: null, ErrMessage: null, ErrStackRace: err as string, @@ -377,7 +377,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi setLineCount(temp.length); } catch (err) { if (err instanceof Error) { - seterrorModalView({ + setErrorModalView({ ErrName: err.name, ErrMessage: err.message, ErrStackRace: err.stack, @@ -385,7 +385,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi }); } else { - seterrorModalView({ + setErrorModalView({ ErrName: null, ErrMessage: null, ErrStackRace: err as string, @@ -406,7 +406,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi console.log(updatedContent) } catch (err) { if (err instanceof Error) { - seterrorModalView({ + setErrorModalView({ ErrName: err.name, ErrMessage: err.message, ErrStackRace: err.stack, @@ -414,7 +414,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi }); } else { - seterrorModalView({ + setErrorModalView({ ErrName: null, ErrMessage: null, ErrStackRace: err as string, @@ -450,7 +450,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi setLineCount(updatedContent.split("\n").length); } catch (err) { if (err instanceof Error) { - seterrorModalView({ + setErrorModalView({ ErrName: err.name, ErrMessage: err.message, ErrStackRace: err.stack, @@ -458,7 +458,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi }); } else { - seterrorModalView({ + setErrorModalView({ ErrName: null, ErrMessage: null, ErrStackRace: err as string, @@ -495,14 +495,14 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi setPatternToDelete(""); } catch (err) { if (err instanceof Error) { - seterrorModalView({ + setErrorModalView({ ErrName: err.name, ErrMessage: err.message, ErrStackRace: err.stack, inputValue: `DeleteByPattern | ${fileContent}` }); } else { - seterrorModalView({ + setErrorModalView({ ErrName: null, ErrMessage: null, ErrStackRace: err as string, @@ -522,14 +522,14 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi setLineCount(updatedContent.length); } catch (err) { if (err instanceof Error) { - seterrorModalView({ + setErrorModalView({ ErrName: err.name, ErrMessage: err.message, ErrStackRace: err.stack, inputValue: `SortByLength | ${fileContent}` }); } else { - seterrorModalView({ + setErrorModalView({ ErrName: null, ErrMessage: null, ErrStackRace: err as string, @@ -560,7 +560,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi console.log(updatedContent) } catch (err) { if (err instanceof Error) { - seterrorModalView({ + setErrorModalView({ ErrName: err.name, ErrMessage: err.message, ErrStackRace: err.stack, @@ -568,7 +568,7 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi }); } else { - seterrorModalView({ + setErrorModalView({ ErrName: null, ErrMessage: null, ErrStackRace: err as string, @@ -639,14 +639,14 @@ const ToolSector = ({ fileContent, setFileContent, setLineCount, seterrorModalVi setLineCount(updatedContent.split("\n").length); } catch (err) { if (err instanceof Error) { - seterrorModalView({ + setErrorModalView({ ErrName: err.name, ErrMessage: err.message, ErrStackRace: err.stack, inputValue: `ConvertToLowercase | ${fileContent}` }); } else { - seterrorModalView({ + setErrorModalView({ ErrName: null, ErrMessage: null, ErrStackRace: err as string, @@ -1121,7 +1121,7 @@ const ArrangeHome = () => { fileContent={fileContent} setFileContent={setFileContent} setLineCount={setLineCount} - seterrorModalView={seterrorModalView} + setErrorModalView={seterrorModalView} /> diff --git a/app/manager-tool/arrange/HelpModal.tsx b/app/manager-tool/arrange/HelpModal.tsx index d60b5ed..8426dff 100644 --- a/app/manager-tool/arrange/HelpModal.tsx +++ b/app/manager-tool/arrange/HelpModal.tsx @@ -5,7 +5,7 @@ interface HelpModalprop { wantGo?: 1 | 2 | 3 | 4 | 5; } -const HelpModalB = ({ wantGo }: HelpModalprop) => { +const HelpModalB = ({ wantGo }: HelpModalProp) => { // 각 섹션에 대한 const sortRef1 = useRef(null); const sortRef2 = useRef(null); @@ -141,7 +141,7 @@ const HelpModalB = ({ wantGo }: HelpModalprop) => { ) } -export default function HelpModalC({ wantGo }: HelpModalprop) { +export default function HelpModalC({ wantGo }: HelpModalProp) { return ( diff --git a/app/openapi/page.tsx b/app/openapi/page.tsx new file mode 100644 index 0000000..7b5f438 --- /dev/null +++ b/app/openapi/page.tsx @@ -0,0 +1,83 @@ +import {AlignStartVertical, ChevronRight, DoorOpen} from "lucide-react"; +import Link from "next/link"; + +export async function generateMetadata() { + return { + title: "끄코 유틸리티 - 오픈API", + description: `끄코 유틸리티 - 오픈API 홈`, + openGraph: { + title: "끄코 유틸리티 - 오픈API", + description: "끄코 유틸리티 - 오픈API 홈", + type: "website", + url: "https://kkuko-utils.vercel.app/openapi", + siteName: "끄코 유틸리티", + locale: "ko_KR", + }, + }; +} + +const features = [ + { + title: "Word Search API", + description: "단어 검색 기능을 API에서 만나보세요.", + link: "/openapi/word", + icon: AlignStartVertical, + color: "from-indigo-400 to-yellow-600", + bgColor: "group-hover:bg-indigo-50 dark:group-hover:bg-indigo-950/20" + } +] + +export default function OpenAPIHomePage() { + return ( +
+ {/* 헤더 */} +
+
+
+ +

+ 오픈 API +

+
+

+ 끄코 유틸리티의 기능을 API에서 만나보세요. +

+
+ + {/* 기능 카드 그리드 */} +
+ {features.map((feature, idx) => { + const IconComponent = feature.icon; + + return ( + +
+
+
+ +
+ +
+ +

+ {feature.title} +

+ +

+ {feature.description} +

+ +
+ + 시작하기 → + +
+
+ + ); + })} +
+
+
+ ); +} \ No newline at end of file diff --git a/app/openapi/word/page.tsx b/app/openapi/word/page.tsx new file mode 100644 index 0000000..294be06 --- /dev/null +++ b/app/openapi/word/page.tsx @@ -0,0 +1,242 @@ +import { + AlertCircle, + Code, + List, + Search, + Settings, + Terminal, + Braces, + FileJson +} from "lucide-react"; + +export async function generateMetadata() { + return { + title: "끄코 유틸리티 - 오픈API 단어", + description: `끄코 유틸리티 - 오픈API 단어`, + openGraph: { + title: "끄코 유틸리티 - 오픈API 단어", + description: "끄코 유틸리티 - 오픈API 단어", + type: "website", + url: "https://kkuko-utils.vercel.app/openapi/word", + siteName: "끄코 유틸리티", + locale: "ko_KR", + }, + }; +} + +export default function OpenApiDocsPage() { + const commonParameters = [ + { name: "mode", type: "string", description: "게임 모드 (kor-start, kor-end, kung, hunmin, jaqi)", defaultValue: "kor-start" }, + { name: "q", type: "string", description: "검색어. 모드에 따라 시작자, 끝자, 또는 초성", defaultValue: "-" }, + { name: "limit", type: "number", description: "최대 검색 결과 수", defaultValue: "100" }, + { name: "sortBy", type: "string", description: "정렬 기준 (abc, length, attack)", defaultValue: "length" }, + ]; + + const advancedParameters = [ + { parameterName: "manner", type: "string", description: "단어 필터 (man, jen, eti)", defaultValue: "man" }, + { parameterName: "minLength", type: "number", description: "최소 글자 수", defaultValue: "2" }, + { parameterName: "maxLength", type: "number", description: "최대 글자 수", defaultValue: "100" }, + { parameterName: "duem", type: "boolean", description: "두음법칙 적용 여부", defaultValue: "true" }, + { parameterName: "mission", type: "string", description: "포함해야 할 특정 글자", defaultValue: '""' }, + { parameterName: "themeId", type: "number", description: "jaqi 모드 사용 시 필수 테마 Id", defaultValue: "-" }, + ]; + + return ( +
+
+
+
+ +

+ Open API +

+
+

+ 오픈 DB의 단어 검색 기능을 API에서 만나보세요. +

+
+ +
+
+
+ +
+

기본 정보

+
+
+ GET + + /api/words/search + +
+

+ 모드별 필터링 및 정렬 옵션을 적용하여 오픈DB의 단어 리스트를 반환합니다. +

+
+ +
+
+
+
+ +
+

쿼리 파라미터

+
+ +

+ 1. 필수 및 공통 옵션 +

+
+ + + + + + + + + + + {commonParameters.map((param, index) => ( + + + + + + + ))} + +
파라미터타입설명기본값
{param.name}{param.type}{param.description}{param.defaultValue}
+
+ +

+ 2. 세부 필터링 (Advanced) +

+
+ + + + + + + + + + + {advancedParameters.map((param, index) => ( + + + + + + + ))} + +
파라미터타입설명기본값
{param.parameterName}{param.type}{param.description}{param.defaultValue}
+
+
+
+ +
+
+
+
+ +
+

Response Body

+
+ +
+
+

Success (Array)

+
    +
  • + word: string + 검색된 단어의 명칭 +
  • +
  • + nextWordCount: number + 해당 단어 이후에 이어질 수 있는 단어의 개수 +
  • +
+
+
+
+ +
+
+ +

Example

+
+
+{`[
+  {
+    "word": "사과",
+    "nextWordCount": 15
+  },
+  {
+    "word": "해질녘",
+    "nextWordCount": 0
+  }
+]`}
+                        
+
+
+ +
+
+ +

API 사용 예제

+
+ +
+
+

A. 일반적인 끝말잇기 (시작 단어 찾기)

+
+ GET /api/words/search?mode=kor-start&q=가&manner=man&limit=50&sortBy=length +
+
+ +
+

B. 쿵쿵따 모드

+
+ GET /api/words/search?mode=kung&q=나 +
+
+ +
+

C. 훈민정음 (초성 퀴즈)

+
+ GET /api/words/search?mode=hunmin&q=ㄱㄴ +
+
+
+
+ +
+
+ +

Response Status Code

+
+
    +
  • + 200: + OK +
  • +
  • + 400: +
    + Bad Request +

    필수 파라미터 누락 또는 유효하지 않은 요청

    +
    +
  • +
  • + 500: + Internal Server Error +
  • +
+
+
+
+ ); +} \ No newline at end of file diff --git a/app/profile/ProfileHome.tsx b/app/profile/ProfileHome.tsx index 8eb50aa..d120611 100644 --- a/app/profile/ProfileHome.tsx +++ b/app/profile/ProfileHome.tsx @@ -51,7 +51,7 @@ export default function ProfileHomePage() { const [searchInput, setSearchInput] = useState(""); const [resultUsers, setResultUsers] = useState([]); const [isLoading, setIsLoading] = useState(false); - const [errorModalView, seterrorModalView] = useState(null); + const [errorModalView, setErrorModalView] = useState(null); const handleSearch = async () => { setIsLoading(true); @@ -60,7 +60,7 @@ export default function ProfileHomePage() { if (error){ setIsLoading(false); setResultUsers([]); - seterrorModalView({ + setErrorModalView({ ErrName: error.name, ErrMessage: error.message, ErrStackRace: error.code, @@ -210,7 +210,7 @@ export default function ProfileHomePage() { {errorModalView && ( seterrorModalView(null)} + onClose={() => setErrorModalView(null)} /> )} diff --git a/app/profile/[username]/ProfilePage.tsx b/app/profile/[username]/ProfilePage.tsx index 4f74a25..1327735 100644 --- a/app/profile/[username]/ProfilePage.tsx +++ b/app/profile/[username]/ProfilePage.tsx @@ -213,7 +213,7 @@ const ProfilePage = ({ userName }: { userName: string }) => { setMonthlyContributions(filledContributions); setLoading(null); - loadTabsData(getUserData.id); + await loadTabsData(getUserData.id); }; getData(); diff --git a/app/programs/[id]/ProgramDetailPage.tsx b/app/programs/[id]/ProgramDetailPage.tsx index 6431e44..879fc72 100644 --- a/app/programs/[id]/ProgramDetailPage.tsx +++ b/app/programs/[id]/ProgramDetailPage.tsx @@ -32,7 +32,7 @@ const programInfoFetcher = async (id: string): Promise<{data: {data: Program}, e } } -const ProgramRelaseFetcher = async (_: string, { arg }: { arg: { repo: string } }): Promise<{data: {latest: GitHubRelease, all: GitHubRelease[]}, error: null} | {data: null, error: FetchError}> => { +const ProgramReleaseFetcher = async (_: string, { arg }: { arg: { repo: string } }): Promise<{data: {latest: GitHubRelease, all: GitHubRelease[]}, error: null} | {data: null, error: FetchError}> => { try { const repo = arg.repo; const encodedRepo = encodeURIComponent(repo); @@ -69,7 +69,7 @@ export default function ProgramDetailPage() { const [error, setError] = useState(null); const [showAllReleases, setShowAllReleases] = useState(false); const {data: infoData, isLoading} = useSWR(`/api/programs/info?id=${programId}`, () => programInfoFetcher(programId), { dedupingInterval: 300_000, revalidateIfStale: false }); - const { trigger, data: mutateData, isMutating } = useSWRMutation(`/api/programs/releases?id=${programId}`, ProgramRelaseFetcher); + const { trigger, data: mutateData, isMutating } = useSWRMutation(`/api/programs/releases?id=${programId}`, ProgramReleaseFetcher); useEffect(()=>{ const updateFunc = async () => { @@ -79,7 +79,7 @@ export default function ProgramDetailPage() { } else if (infoData.data) { setProgram(infoData.data.data); setError(null); - trigger({repo: infoData.data.data.github_repo}); + await trigger({repo: infoData.data.data.github_repo}); } } } diff --git a/app/providers.tsx b/app/providers.tsx index 905a4e0..922b2c1 100644 --- a/app/providers.tsx +++ b/app/providers.tsx @@ -3,6 +3,7 @@ import { Provider } from "react-redux"; import { store } from "./store/store"; import { ThemeProvider } from 'next-themes' +import React from "react"; export function Providers({ children }: { children: React.ReactNode }) { return ( diff --git a/app/release-note/page.tsx b/app/release-note/page.tsx index fa59e0b..691d291 100644 --- a/app/release-note/page.tsx +++ b/app/release-note/page.tsx @@ -1,4 +1,5 @@ import ReleaseNote from "./ReleaseNote"; +import React from "react"; export async function generateMetadata() { return { diff --git a/app/word-combiner/WordCombinerClient.tsx b/app/word-combiner/WordCombinerClient.tsx index c98ea9f..c77117f 100644 --- a/app/word-combiner/WordCombinerClient.tsx +++ b/app/word-combiner/WordCombinerClient.tsx @@ -1,6 +1,6 @@ "use client" import React, { useState } from 'react'; -import type { SixCharString, FiveCharString, ErrorMessage } from '../types/type'; +import type { SixCharString, FiveCharString, ErrorMessage } from '@/types/type'; import CombinationManager from '../lib/CombinationsManger'; import ErrorModal from '../components/ErrModal'; import HelpModal from './WordCombinerHelpModal'; @@ -12,7 +12,7 @@ interface WordCombinerWithData { } export default function WordCombinerClient({ prop }: { prop: WordCombinerWithData }) { - const [nomalJOKAK, setNomalJOKAK] = useState(""); + const [normalJOKAK, setNormalJOKAK] = useState(""); const [highJOKAK, setHighJOKAK] = useState(""); const [rareJOKAK, setRareJOKAK] = useState(""); const [inputHtml, setInputHtml] = useState(""); @@ -31,7 +31,7 @@ export default function WordCombinerClient({ prop }: { prop: WordCombinerWithDat const parser = new DOMParser(); const doc = parser.parseFromString(htmlString, 'text/html'); - let nomal = ""; // 일반 + let normal = ""; // 일반 let high = ""; // 고급 let rare = ""; // 희귀 @@ -58,11 +58,11 @@ export default function WordCombinerClient({ prop }: { prop: WordCombinerWithDat rare += chName.repeat(tCount); } else if (charName.includes("글자 조각")) { const chName = charName.replace("글자 조각 - ", ""); - nomal += chName.repeat(tCount); + normal += chName.repeat(tCount); } }); setInputHtml(""); - setNomalJOKAK(nomal); + setNormalJOKAK(normal); setHighJOKAK(high); setRareJOKAK(rare); setActiveTab('normal'); @@ -89,12 +89,12 @@ export default function WordCombinerClient({ prop }: { prop: WordCombinerWithDat try { setLoading(true); setTimeout(() => { - const manger6 = new CombinationManager(nomalJOKAK.replace(/\s+/g, '').split('').sort().join(''), len6WordsData); + const manger6 = new CombinationManager(normalJOKAK.replace(/\s+/g, '').split('').sort().join(''), len6WordsData); setLen6Date(manger6.getBests()); - const manger5 = new CombinationManager(manger6.remainstr(), len5WordsData); + const manger5 = new CombinationManager(manger6.remainStr(), len5WordsData); setLen5Data(manger5.getBests()); setLoading(false); - setNomalJOKAK(manger5.remainstr()); + setNormalJOKAK(manger5.remainStr()); }, 1) } catch (err: unknown) { if (err instanceof Error) { @@ -123,10 +123,10 @@ export default function WordCombinerClient({ prop }: { prop: WordCombinerWithDat setTimeout(() => { const manger6 = new CombinationManager(highJOKAK.replace(/\s+/g, '').split('').sort().join(''), len6WordsData); setLen6Date(manger6.getBests()); - const manger5 = new CombinationManager(manger6.remainstr(), len5WordsData); + const manger5 = new CombinationManager(manger6.remainStr(), len5WordsData); setLen5Data(manger5.getBests()); setLoading(false); - setHighJOKAK(manger5.remainstr()); + setHighJOKAK(manger5.remainStr()); }, 1) } catch (err: unknown) { if (err instanceof Error) { @@ -155,10 +155,10 @@ export default function WordCombinerClient({ prop }: { prop: WordCombinerWithDat setTimeout(() => { const manger6 = new CombinationManager(rareJOKAK.replace(/\s+/g, '').split('').sort().join(''), len6WordsData); setLen6Date(manger6.getBests()); - const manger5 = new CombinationManager(manger6.remainstr(), len5WordsData); + const manger5 = new CombinationManager(manger6.remainStr(), len5WordsData); setLen5Data(manger5.getBests()); setLoading(false); - setRareJOKAK(manger5.remainstr()); + setRareJOKAK(manger5.remainStr()); }, 1) } catch (err: unknown) { if (err instanceof Error) { @@ -193,7 +193,7 @@ export default function WordCombinerClient({ prop }: { prop: WordCombinerWithDat const getCurrentValue = () => { switch(activeTab) { - case 'normal': return nomalJOKAK; + case 'normal': return normalJOKAK; case 'high': return highJOKAK; case 'rare': return rareJOKAK; case 'html': return inputHtml; @@ -203,11 +203,11 @@ export default function WordCombinerClient({ prop }: { prop: WordCombinerWithDat const getCurrentSetter = () => { switch(activeTab) { - case 'normal': return setNomalJOKAK; + case 'normal': return setNormalJOKAK; case 'high': return setHighJOKAK; case 'rare': return setRareJOKAK; case 'html': return setInputHtml; - default: return setNomalJOKAK; + default: return setNormalJOKAK; } }; @@ -309,7 +309,7 @@ export default function WordCombinerClient({ prop }: { prop: WordCombinerWithDat
일반 - {nomalJOKAK.length} + {normalJOKAK.length}
고급 diff --git a/app/word-combiner/WordCombinerHelpModal.tsx b/app/word-combiner/WordCombinerHelpModal.tsx index aa8ab86..ca14f8f 100644 --- a/app/word-combiner/WordCombinerHelpModal.tsx +++ b/app/word-combiner/WordCombinerHelpModal.tsx @@ -7,7 +7,7 @@ import { Play } from 'lucide-react'; const HelpModalA = ({ wantGo }: { wantGo?: 1 | 2 | 3; }) => { // 각 섹션에 대한 ref - const nomalHelp = useRef(null); + const normalHelp = useRef(null); const HTMLHelp = useRef(null); const chromeHTML = useRef(null); @@ -36,7 +36,7 @@ const HelpModalA = ({ wantGo }: { wantGo?: 1 | 2 | 3; }) => {
  • @@ -64,7 +64,7 @@ const HelpModalA = ({ wantGo }: { wantGo?: 1 | 2 | 3; }) => { {/* 기본 사용법 */}
    -

    +

    1 기본적인 사용법

    diff --git a/app/word-combiner/page.tsx b/app/word-combiner/page.tsx index 8d79f4e..e70e20e 100644 --- a/app/word-combiner/page.tsx +++ b/app/word-combiner/page.tsx @@ -1,4 +1,5 @@ import WordCombinerPage from "./WordCombinerPage"; +import React from "react"; export async function generateMetadata() { return { diff --git a/app/word/lib.ts b/app/word/lib.ts index fff60b2..0d174a3 100644 --- a/app/word/lib.ts +++ b/app/word/lib.ts @@ -1,6 +1,6 @@ "use client"; -import { SCM } from "../lib/supabaseClient"; +import { SCM } from "@/lib/supabaseClient"; export const fetcher = async () => { const { data, error } = await SCM.get().allThemes(); diff --git a/app/word/logs/LogsHome.tsx b/app/word/logs/LogsHome.tsx index f116c4c..f7e0f8d 100644 --- a/app/word/logs/LogsHome.tsx +++ b/app/word/logs/LogsHome.tsx @@ -97,7 +97,7 @@ export default function LogPage() { const from = (currentPage - 1) * itemsPerPage; const to = from + itemsPerPage - 1; - const { data: LogsData, error: LogsDataError, count } = await SCM.get().logsByFillter({ + const { data: LogsData, error: LogsDataError, count } = await SCM.get().logsByFilter({ filterState: currentFilterState, filterType: currentFilterType, from, to diff --git a/app/word/page.tsx b/app/word/page.tsx index 41ad728..4e1b2bb 100644 --- a/app/word/page.tsx +++ b/app/word/page.tsx @@ -1,15 +1,5 @@ import Link from "next/link"; -import { - Search, - Download, - Plus, - Upload, - FileText, - Clock, - ChevronRight, - Database, - BarChart3 -} from "lucide-react"; +import {BarChart3, ChevronRight, Clock, Database, Download, FileText, Plus, Search, Upload} from "lucide-react"; export async function generateMetadata() { return { diff --git a/app/word/search/components/SimpleSearchOptions.tsx b/app/word/search/components/SimpleSearchOptions.tsx index d71a94e..d7463e9 100644 --- a/app/word/search/components/SimpleSearchOptions.tsx +++ b/app/word/search/components/SimpleSearchOptions.tsx @@ -1,4 +1,5 @@ import { Search, Loader2 } from 'lucide-react'; +import React from "react"; interface SimpleSearchOptionsProps { simpleQuery: string; diff --git a/app/word/search/hooks/useWordSearch.ts b/app/word/search/hooks/useWordSearch.ts index ca7b3d1..bc8aca0 100644 --- a/app/word/search/hooks/useWordSearch.ts +++ b/app/word/search/hooks/useWordSearch.ts @@ -32,7 +32,7 @@ export const useWordSearch = () => { useEffect(() => { const modeParam = searchParams.get('mode'); const qParam = searchParams.get('q'); - + if (modeParam || qParam) { // mode 파라미터 처리 let targetMode: GameMode = 'kor-start'; @@ -43,26 +43,26 @@ export const useWordSearch = () => { } else if (modeParam === 'k') { targetMode = 'kung'; } - + setMode(targetMode); setSearchType('advanced'); - + // q 파라미터 처리 if (qParam) { setManner(''); // manner을 빈 문자열로 설정 - + if (targetMode === 'kor-start' || targetMode === 'kung') { setStartLetter(qParam); } else if (targetMode === 'kor-end') { setEndLetter(qParam); } - + // 쿵쿵따 모드인 경우 길이 설정 if (targetMode === 'kung') { setMinLength(3); setMaxLength(3); } - + // 자동 검색 트리거 setAutoSearchTriggered(true); } @@ -84,10 +84,10 @@ export const useWordSearch = () => { setLoading(true); setSearchPerformed(true); setResults([]); - + try { let query: advancedQueryType; - + if (mode === 'kor-start' || mode === 'kor-end') { if (mode === 'kor-start' && startLetter.trim() === '') return; if (mode === 'kor-end' && endLetter.trim() === '') return; @@ -160,10 +160,10 @@ export const useWordSearch = () => { setLoading(true); setSearchPerformed(true); setResults([]); - + try { if (simpleQuery.trim() === '') return; - + const { data, error } = await SCM.get().wordsByQuery(simpleQuery.trim()); if (error) { console.error('검색 오류:', error); @@ -199,4 +199,4 @@ export const useWordSearch = () => { handleSearch, handleSimpleSearch }; -}; +}; \ No newline at end of file diff --git a/app/words-docs/WordsDocsHome.tsx b/app/words-docs/WordsDocsHome.tsx index 14b466c..768982e 100644 --- a/app/words-docs/WordsDocsHome.tsx +++ b/app/words-docs/WordsDocsHome.tsx @@ -9,7 +9,7 @@ import { convertQwertyToHangul } from "es-hangul"; import { useSelector } from "react-redux"; import type { RootState } from "../store/store"; import LoginRequiredModal from "../components/LoginRequiredModal"; -import { SCM } from "../lib/supabaseClient"; +import { SCM } from "@/lib/supabaseClient"; import CompleteModal from "../components/CompleteModal"; interface Document { diff --git a/app/words-docs/WordsDocsHomePage.tsx b/app/words-docs/WordsDocsHomePage.tsx index ad3ebf3..31035c5 100644 --- a/app/words-docs/WordsDocsHomePage.tsx +++ b/app/words-docs/WordsDocsHomePage.tsx @@ -18,7 +18,7 @@ type DocsType = { export default function WordsDocsHomePage(){ const { loadingState, updateLoadingState } = useLoadingState(); const [errorMessage,setErrorMessage] = useState(null); - const [docsDatas, setDocsDatas] = useState(null); + const [docsData, setDocsData] = useState(null); // Data 자체가 복수형 useEffect(()=>{ const getData = async () => { @@ -36,7 +36,7 @@ export default function WordsDocsHomePage(){ id: `${id}`, name, maker: users?.nickname ?? "알수없음", last_update, is_manager: false, typez, created_at })); - setDocsDatas(docs); + setDocsData(docs); updateLoadingState(100, "완료"); } getData(); @@ -46,7 +46,7 @@ export default function WordsDocsHomePage(){ if (errorMessage) return - if (docsDatas) return + if (docsData) return return null } \ No newline at end of file diff --git a/app/words-docs/[id]/DocsDataHome.tsx b/app/words-docs/[id]/DocsDataHome.tsx index 99f6ea9..491a5f7 100644 --- a/app/words-docs/[id]/DocsDataHome.tsx +++ b/app/words-docs/[id]/DocsDataHome.tsx @@ -56,7 +56,7 @@ const DocsDataHome = ({ id, data, metaData, starCount }: DocsPageProp) => { const user = useSelector((state: RootState) => state.user); const [isUserStarreda, setIsUserStarreda] = useState(false); const [loginNeedModalOpen, setLoginNeedModalOpen] = useState(false); - const [errorModalView, seterrorModalView] = useState(null); + const [errorModalView, setErrorModalView] = useState(null); // 유저 즐겨찾기 상태 업데이트 useEffect(() => { @@ -227,7 +227,7 @@ const DocsDataHome = ({ id, data, metaData, starCount }: DocsPageProp) => { URL.revokeObjectURL(url); }; - const hadnleDocsStar = async () => { + const handleDocsStar = async () => { if (!user.uuid) { return setLoginNeedModalOpen(true); } @@ -243,7 +243,7 @@ const DocsDataHome = ({ id, data, metaData, starCount }: DocsPageProp) => { } const makeError = (error: PostgrestError) => { - seterrorModalView({ + setErrorModalView({ ErrName: error.name, ErrMessage: error.message, ErrStackRace: error.stack, @@ -321,7 +321,7 @@ const DocsDataHome = ({ id, data, metaData, starCount }: DocsPageProp) => { ? "bg-yellow-400 text-yellow-900 hover:bg-yellow-300" : "bg-white/20 text-white hover:bg-white/30 backdrop-blur-sm" }`} - onClick={hadnleDocsStar} + onClick={handleDocsStar} > { )} {errorModalView && ( seterrorModalView(null)} + onClose={() => setErrorModalView(null)} error={errorModalView} /> )} diff --git a/app/words-docs/[id]/DocsDataPage.tsx b/app/words-docs/[id]/DocsDataPage.tsx index 991aab5..10ec070 100644 --- a/app/words-docs/[id]/DocsDataPage.tsx +++ b/app/words-docs/[id]/DocsDataPage.tsx @@ -23,14 +23,14 @@ export default function DocsDataPage({id}:{id:number}){ const [errorMessage,setErrorMessage] = useState(null); const [wordsData,setWordsData] = useState<{words:wordsDataType[], metadata:{title:string, lastUpdate:string, typez: "letter" | "theme" | "ect"}, starCount: string[]} | null>(null); - const makeError = (erorr: PostgrestError) => { - setErrorMessage(`문서 정보 데이터 로드중 오류.\nErrorName: ${erorr.name ?? "알수없음"}\nError Message: ${erorr.message ?? "없음"}\nError code: ${erorr.code}`) + const makeError = (error: PostgrestError) => { + setErrorMessage(`문서 정보 데이터 로드중 오류.\nErrorName: ${error.name ?? "알수없음"}\nError Message: ${error.message ?? "없음"}\nError code: ${error.code}`) updateLoadingState(100,"ERR"); return; } useEffect(()=>{ - const getDatas = async () => { + const getData = async () => { updateLoadingState(10,"문서 정보 가져오는 중...") const {data: docsData, error: docsDataError} = await SCM.get().docsInfoByDocsId(id); if (docsDataError) return makeError(docsDataError); @@ -40,16 +40,16 @@ export default function DocsDataPage({id}:{id:number}){ if (docsData.typez === "letter"){ updateLoadingState(40, "문서에 들어간 단어 정보 가져오는 중..."); - const {data, error: LetterDatasError} = await SCM.get().docsWords({name: docsData.name, duem: docsData.duem, typez: "letter"}); - if (LetterDatasError) return makeError(LetterDatasError); - const {words: LetterDatas1, waitWords: LetterDatas2} = data; + const {data, error: LetterDataError} = await SCM.get().docsWords({name: docsData.name, duem: docsData.duem, typez: "letter"}); + if (LetterDataError) return makeError(LetterDataError); + const {words: LetterData1, waitWords: LetterData2} = data; await new Promise(resolve => setTimeout(resolve, 1)) updateLoadingState(70, "데이터를 가공중...") // 삭제 요청인 단어는 제외 - const wordsNotInB = LetterDatas1.filter(a => !LetterDatas2.some(b => b.word === a.word)).map((p)=>({word: p.word, status: "ok" as const, maker: undefined})); - const wordsData = [...wordsNotInB, ...LetterDatas2.filter(({word})=>word.length > 1).map(({word,requested_by,request_type})=>({word, status: request_type, maker:requested_by}))] + const wordsNotInB = LetterData1.filter(a => !LetterData2.some(b => b.word === a.word)).map((p)=>({word: p.word, status: "ok" as const, maker: undefined})); + const wordsData = [...wordsNotInB, ...LetterData2.filter(({word})=>word.length > 1).map(({word,requested_by,request_type})=>({word, status: request_type, maker:requested_by}))] const p = {title: docsData.name, lastUpdate: docsData.last_update, typez:docsData.typez} setWordsData({words: wordsData, metadata: p, starCount:docsStarData.map(({user_id})=>user_id)}); await SCM.update().docView(docsData.id); @@ -99,7 +99,7 @@ export default function DocsDataPage({id}:{id:number}){ return; } } - getDatas(); + getData(); },[]) if (isNotFound) return ; diff --git a/app/words-docs/[id]/Table.tsx b/app/words-docs/[id]/Table.tsx index f114c98..34ccccc 100644 --- a/app/words-docs/[id]/Table.tsx +++ b/app/words-docs/[id]/Table.tsx @@ -194,7 +194,7 @@ const Table = ({ CancelDeleteRequest, RequestDelete, DeleteByAdmin, - } = useWorkFunc({ makeError, setIsProcessing, user, CompleWork, isProcessing }); + } = useWorkFunc({ makeError, setIsProcessing, user, CompWork: CompleWork, isProcessing }); return (
    diff --git a/app/words-docs/[id]/TableWorkFunc.tsx b/app/words-docs/[id]/TableWorkFunc.tsx index a8671de..36a3a3c 100644 --- a/app/words-docs/[id]/TableWorkFunc.tsx +++ b/app/words-docs/[id]/TableWorkFunc.tsx @@ -2,7 +2,7 @@ import { SCM } from '@/app/lib/supabaseClient'; import type { PostgrestError } from "@supabase/supabase-js"; import { isNoin } from "@/app/lib/lib"; import type { RootState } from '@/app/store/store'; -import { useCallback } from 'react'; +import React, { useCallback } from 'react'; interface DocsLogData { readonly word: string; @@ -19,22 +19,22 @@ interface WordLogData { readonly state: "approved" | "rejected"; } -type DocsLogDatas = DocsLogData[]; -type WordLogDatas = WordLogData[]; +type DocsLogArrayOfData = DocsLogData[]; +type WordLogArrayOfData = WordLogData[]; -export const useWorkFunc = ({ makeError, setIsProcessing, user, isProcessing, CompleWork }: { +export const useWorkFunc = ({ makeError, setIsProcessing, user, isProcessing, CompWork }: { makeError: (error: PostgrestError) => void, setIsProcessing: React.Dispatch>, user: RootState['user'], - CompleWork: () => void, + CompWork: () => void, isProcessing: boolean }) => { - const WriteDocsLog = useCallback(async (logsData: DocsLogDatas) => { + const WriteDocsLog = useCallback(async (logsData: DocsLogArrayOfData) => { const { error: insertDocsLogDataError } = await SCM.add().docsLog(logsData); if (insertDocsLogDataError) { throw insertDocsLogDataError } }, []); - const WriteWordLog = useCallback(async (logsData: WordLogDatas) => { + const WriteWordLog = useCallback(async (logsData: WordLogArrayOfData) => { const { error: insertWordLogDataError } = await SCM.add().wordLog(logsData); if (insertWordLogDataError) { throw insertWordLogDataError } }, []); @@ -123,7 +123,7 @@ export const useWorkFunc = ({ makeError, setIsProcessing, user, isProcessing, Co if (deleteWaitWordDataError) return makeError(deleteWaitWordDataError); setIsProcessing(false); - CompleWork(); + CompWork(); } catch (error) { makeError(error as PostgrestError); setIsProcessing(false); @@ -155,7 +155,7 @@ export const useWorkFunc = ({ makeError, setIsProcessing, user, isProcessing, Co await WriteWordLog([insertWordLogData]); setIsProcessing(false); - CompleWork(); + CompWork(); return; }, []); @@ -233,7 +233,7 @@ export const useWorkFunc = ({ makeError, setIsProcessing, user, isProcessing, Co setIsProcessing(false); - CompleWork(); + CompWork(); return; }, []); @@ -262,7 +262,7 @@ export const useWorkFunc = ({ makeError, setIsProcessing, user, isProcessing, Co await WriteWordLog([insertWordLogData]); setIsProcessing(false); - CompleWork(); + CompWork(); return; }, []); @@ -281,7 +281,7 @@ export const useWorkFunc = ({ makeError, setIsProcessing, user, isProcessing, Co if (deleteWaitWordDataError) { return makeError(deleteWaitWordDataError); } setIsProcessing(false); - CompleWork(); + CompWork(); return; }, []); @@ -300,7 +300,7 @@ export const useWorkFunc = ({ makeError, setIsProcessing, user, isProcessing, Co if (deleteWaitWordDataError) { return makeError(deleteWaitWordDataError); } setIsProcessing(false); - CompleWork(); + CompWork(); return; }, []); @@ -374,7 +374,7 @@ export const useWorkFunc = ({ makeError, setIsProcessing, user, isProcessing, Co } setIsProcessing(false); - CompleWork(); + CompWork(); return; }, []); @@ -405,7 +405,7 @@ export const useWorkFunc = ({ makeError, setIsProcessing, user, isProcessing, Co if (!insertWaitWordDataA) return; setIsProcessing(false); - CompleWork(); + CompWork(); return; }, []); diff --git a/app/words-docs/[id]/logs/DocsLogPage.tsx b/app/words-docs/[id]/logs/DocsLogPage.tsx index 4bb5152..4a5163e 100644 --- a/app/words-docs/[id]/logs/DocsLogPage.tsx +++ b/app/words-docs/[id]/logs/DocsLogPage.tsx @@ -18,10 +18,10 @@ type log = { export default function DocsLogPage({id}:{id: number}){ const [isNotFound,setIsNotFound] = useState(false); const [errorMessage,setErrorMessage] = useState(null); - const [logsData, setLogsDatas] = useState<{logs:log[], docsName: string}|null>(null); + const [logsData, setLogsData] = useState<{logs:log[], docsName: string}|null>(null); const { loadingState, updateLoadingState } = useLoadingState(); - const hanldeError = (error: PostgrestError) => { + const handleError = (error: PostgrestError) => { setErrorMessage(`문서 정보 데이터 로드중 오류.\nErrorName: ${error.name ?? "알수없음"}\nError Message: ${error.message ?? "없음"}\nError code: ${error.code}`); updateLoadingState(100,"ERR"); } @@ -32,12 +32,12 @@ export default function DocsLogPage({id}:{id: number}){ // 문서 정보 가져오기 const {data: docsData, error: docsDataError} = await SCM.get().docsInfoByDocsId(id); if (docsData === null) return setIsNotFound(true); - if (docsDataError){ return hanldeError(docsDataError); } + if (docsDataError){ return handleError(docsDataError); } updateLoadingState(40,"로그 가져오는 중..."); // 문서 로그 가져오기 const {data: logData, error: logDataError} = await SCM.get().docsLogs(id); - if (logDataError){ return hanldeError(logDataError); } + if (logDataError){ return handleError(logDataError); } updateLoadingState(90,"데이터 가공중..."); const logsData = logData?.map((log) => ({ @@ -48,7 +48,7 @@ export default function DocsLogPage({id}:{id: number}){ type: log.type, })); - setLogsDatas({logs:logsData ?? [], docsName: docsData?.name}); + setLogsData({logs:logsData ?? [], docsName: docsData?.name}); updateLoadingState(100,"완료!"); } getData() diff --git a/app/words-docs/[id]/page.tsx b/app/words-docs/[id]/page.tsx index 305653b..9075a9c 100644 --- a/app/words-docs/[id]/page.tsx +++ b/app/words-docs/[id]/page.tsx @@ -21,8 +21,7 @@ const DocsDataHomePage = async ({ params }: { params: Promise<{ id: string }> }) const {id} = await params; const nid = Number(id) - if (isNaN(nid)) return - return + return isNaN(nid) ? : } diff --git a/package-lock.json b/package-lock.json index 862d211..655d443 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "kkuko-utils", - "version": "1.3.0", + "version": "1.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "kkuko-utils", - "version": "1.3.0", + "version": "1.4.0", "dependencies": { "@codemirror/lang-javascript": "^6.2.3", "@codemirror/language": "^6.11.0", @@ -49,7 +49,7 @@ "howler": "^2.2.4", "idb": "^8.0.3", "lucide-react": "^0.474.0", - "next": "^15.1.0", + "next": "^15.5.9", "next-themes": "^0.4.6", "react": "^19.0.0", "react-dom": "^19.0.0", @@ -2826,9 +2826,10 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.6.0.tgz", - "integrity": "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", + "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", + "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" @@ -3096,18 +3097,20 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "license": "MIT", "optional": true, "engines": { "node": ">=18" } }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.4.tgz", - "integrity": "sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", "cpu": [ "arm64" ], + "license": "Apache-2.0", "optional": true, "os": [ "darwin" @@ -3119,16 +3122,17 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.3" + "@img/sharp-libvips-darwin-arm64": "1.2.4" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.4.tgz", - "integrity": "sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", "cpu": [ "x64" ], + "license": "Apache-2.0", "optional": true, "os": [ "darwin" @@ -3140,16 +3144,17 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.3" + "@img/sharp-libvips-darwin-x64": "1.2.4" } }, "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.3.tgz", - "integrity": "sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", "cpu": [ "arm64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "darwin" @@ -3159,12 +3164,13 @@ } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.3.tgz", - "integrity": "sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", "cpu": [ "x64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "darwin" @@ -3174,12 +3180,13 @@ } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.3.tgz", - "integrity": "sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", "cpu": [ "arm" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -3189,12 +3196,13 @@ } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.3.tgz", - "integrity": "sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", "cpu": [ "arm64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -3204,12 +3212,29 @@ } }, "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.3.tgz", - "integrity": "sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", "cpu": [ "ppc64" ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -3219,12 +3244,13 @@ } }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.3.tgz", - "integrity": "sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", "cpu": [ "s390x" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -3234,12 +3260,13 @@ } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.3.tgz", - "integrity": "sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", "cpu": [ "x64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -3249,12 +3276,13 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.3.tgz", - "integrity": "sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", "cpu": [ "arm64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -3264,12 +3292,13 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.3.tgz", - "integrity": "sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", "cpu": [ "x64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" @@ -3279,12 +3308,13 @@ } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.34.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.4.tgz", - "integrity": "sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", "cpu": [ "arm" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -3296,16 +3326,17 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.3" + "@img/sharp-libvips-linux-arm": "1.2.4" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.4.tgz", - "integrity": "sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", "cpu": [ "arm64" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -3317,16 +3348,39 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.3" + "@img/sharp-libvips-linux-arm64": "1.2.4" } }, "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.4.tgz", - "integrity": "sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", "cpu": [ "ppc64" ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -3338,16 +3392,17 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.3" + "@img/sharp-libvips-linux-riscv64": "1.2.4" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.4.tgz", - "integrity": "sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", "cpu": [ "s390x" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -3359,16 +3414,17 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.3" + "@img/sharp-libvips-linux-s390x": "1.2.4" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.34.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.4.tgz", - "integrity": "sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", "cpu": [ "x64" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -3380,16 +3436,17 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.3" + "@img/sharp-libvips-linux-x64": "1.2.4" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.4.tgz", - "integrity": "sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", "cpu": [ "arm64" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -3401,16 +3458,17 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.3" + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.4.tgz", - "integrity": "sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", "cpu": [ "x64" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -3422,19 +3480,20 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.3" + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.34.4", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.4.tgz", - "integrity": "sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", "cpu": [ "wasm32" ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { - "@emnapi/runtime": "^1.5.0" + "@emnapi/runtime": "^1.7.0" }, "engines": { "node": "^18.17.0 || ^20.3.0 || >=21.0.0" @@ -3444,12 +3503,13 @@ } }, "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.4.tgz", - "integrity": "sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", "cpu": [ "arm64" ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ "win32" @@ -3462,12 +3522,13 @@ } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.4.tgz", - "integrity": "sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", "cpu": [ "ia32" ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ "win32" @@ -3480,12 +3541,13 @@ } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.34.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.4.tgz", - "integrity": "sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", "cpu": [ "x64" ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ "win32" @@ -9426,6 +9488,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", "optional": true, "engines": { "node": ">=8" @@ -15816,15 +15879,16 @@ } }, "node_modules/sharp": { - "version": "0.34.4", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.4.tgz", - "integrity": "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", "hasInstallScript": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "@img/colour": "^1.0.0", - "detect-libc": "^2.1.0", - "semver": "^7.7.2" + "detect-libc": "^2.1.2", + "semver": "^7.7.3" }, "engines": { "node": "^18.17.0 || ^20.3.0 || >=21.0.0" @@ -15833,28 +15897,30 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.4", - "@img/sharp-darwin-x64": "0.34.4", - "@img/sharp-libvips-darwin-arm64": "1.2.3", - "@img/sharp-libvips-darwin-x64": "1.2.3", - "@img/sharp-libvips-linux-arm": "1.2.3", - "@img/sharp-libvips-linux-arm64": "1.2.3", - "@img/sharp-libvips-linux-ppc64": "1.2.3", - "@img/sharp-libvips-linux-s390x": "1.2.3", - "@img/sharp-libvips-linux-x64": "1.2.3", - "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", - "@img/sharp-libvips-linuxmusl-x64": "1.2.3", - "@img/sharp-linux-arm": "0.34.4", - "@img/sharp-linux-arm64": "0.34.4", - "@img/sharp-linux-ppc64": "0.34.4", - "@img/sharp-linux-s390x": "0.34.4", - "@img/sharp-linux-x64": "0.34.4", - "@img/sharp-linuxmusl-arm64": "0.34.4", - "@img/sharp-linuxmusl-x64": "0.34.4", - "@img/sharp-wasm32": "0.34.4", - "@img/sharp-win32-arm64": "0.34.4", - "@img/sharp-win32-ia32": "0.34.4", - "@img/sharp-win32-x64": "0.34.4" + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" } }, "node_modules/shebang-command": { diff --git a/package.json b/package.json index e6c62c9..661b535 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kkuko-utils", - "version": "1.3.0", + "version": "1.4.0", "private": true, "scripts": { "dev": "next dev --turbopack", @@ -57,7 +57,7 @@ "howler": "^2.2.4", "idb": "^8.0.3", "lucide-react": "^0.474.0", - "next": "^15.1.0", + "next": "^15.5.9", "next-themes": "^0.4.6", "react": "^19.0.0", "react-dom": "^19.0.0",