diff --git a/.oxlintrc.json b/.oxlintrc.json index dd4578e07..4e16c139b 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -24,6 +24,17 @@ "error", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" } ], - "@typescript-eslint/no-explicit-any": "warn" + "@typescript-eslint/no-explicit-any": "warn", + "no-restricted-imports": [ + "error", + { + "patterns": [ + { + "regex": "^\\$lib(/|$)", + "message": "SvelteKit 3 removes $lib. Use #lib with an explicit extension (e.g. #lib/types/task.js)." + } + ] + } + ] } } diff --git a/docs/guides/agent-rules/prisma-db.md b/docs/guides/agent-rules/prisma-db.md index 1a0b3891f..a405e9e82 100644 --- a/docs/guides/agent-rules/prisma-db.md +++ b/docs/guides/agent-rules/prisma-db.md @@ -21,7 +21,7 @@ paths: ## Server-Only Code -- Import the DB client (`$lib/server/database`) only in `src/lib/server/**` and in server-only services under `src/lib/services/**` and `src/features/**/services/**` +- Import the DB client (`#lib/server/database.js`) only in `src/lib/server/**` and in server-only services under `src/lib/services/**` and `src/features/**/services/**` - Never import server-only code in client components ## Service Layer diff --git a/docs/guides/agent-rules/server-cache.md b/docs/guides/agent-rules/server-cache.md index f52599379..b8231faf2 100644 --- a/docs/guides/agent-rules/server-cache.md +++ b/docs/guides/agent-rules/server-cache.md @@ -78,7 +78,7 @@ Services call `getCached*()` with a `fetchFn` that performs the DB query. The se ```typescript // In service file -import { getCachedTasksMap } from '$lib/server/tasks/cache'; +import { getCachedTasksMap } from '#lib/server/tasks/cache.js'; export async function getTasksByTaskId(): Promise> { return getCachedTasksMap(async () => { @@ -91,7 +91,7 @@ export async function getTasksByTaskId(): Promise> { Mock cache in service tests to bypass caching: ```typescript -vi.mock('$lib/server/tasks/cache', () => ({ +vi.mock('#lib/server/tasks/cache.js', () => ({ getCachedTasksMap: (fetchFn: () => Promise) => fetchFn(), invalidateTaskCaches: vi.fn(), })); diff --git a/docs/guides/agent-rules/testing-e2e.md b/docs/guides/agent-rules/testing-e2e.md index f61df69eb..1c38e55ae 100644 --- a/docs/guides/agent-rules/testing-e2e.md +++ b/docs/guides/agent-rules/testing-e2e.md @@ -10,7 +10,7 @@ paths: ## Setup - File extension: **must** be `.spec.ts` (`.test.ts` not detected by `playwright.config.ts`) -- No path aliases (`$lib`, `$features` not resolved outside SvelteKit). Use type-only imports for types: +- No path aliases or subpath imports (`$features` is resolved only by Vite; `#lib/*.js` resolves to `src/lib/*.js`, but the Playwright runner does not map it to the `.ts` source). Use type-only imports for types: ```typescript // Bad: runtime import fails in E2E diff --git a/docs/guides/agent-rules/testing.md b/docs/guides/agent-rules/testing.md index f26d0f821..6d3e8f446 100644 --- a/docs/guides/agent-rules/testing.md +++ b/docs/guides/agent-rules/testing.md @@ -70,7 +70,7 @@ test.each([TaskGrade.PENDING, TaskGrade.Q11, TaskGrade.Q10, TaskGrade.D6])( ### Service Layer (Prisma) -Mock with `vi.mock('$lib/server/database', ...)`. Use helpers: +Mock with `vi.mock('#lib/server/database.js', ...)`. Use helpers: ```typescript const mockFindUnique = (data) => db.task.findUnique.mockResolvedValue(data); @@ -95,7 +95,7 @@ afterAll(() => disposeDomainCaches()); beforeEach(() => invalidateDomainCaches()); // Bypass caching in service tests: -vi.mock('$lib/server/tasks/cache', () => ({ +vi.mock('#lib/server/tasks/cache.js', () => ({ getCachedTasksMap: (fetchFn: () => Promise) => fetchFn(), invalidateTaskCaches: vi.fn(), })); diff --git a/docs/guides/architecture.md b/docs/guides/architecture.md index eb652fa4f..9f35fb9b5 100644 --- a/docs/guides/architecture.md +++ b/docs/guides/architecture.md @@ -75,7 +75,7 @@ feature 内は技術的な役割で分ける。必要なディレクトリだけ - `utils/`: 副作用のない関数。テストを隣接配置する。 - `stores/`: Svelte Runes を使う `.svelte.ts`。 -`features/{feature}/server/` は `$lib/server/` と違い、SvelteKit が client import を自動では禁止しない。規約と推移的な server-only dependency により client から分離する。複数 feature で使うサーバコードは `src/lib/server/` へ移す。 +`features/{feature}/server/` は `src/lib/server/` と違い、SvelteKit が client import を自動では禁止しない。規約と推移的な server-only dependency により client から分離する。複数 feature で使うサーバコードは `src/lib/server/` へ移す。 ### 3. src/lib @@ -139,12 +139,15 @@ include: [ ]; ``` -### 6. path alias +### 6. path alias と subpath imports -`svelte.config.js` で `$lib` と `$features` を定義している。 +`src/lib` は `package.json#imports` の `#lib/*` で参照する。SvelteKit 3 で組み込みの `$lib` が削除されるため `$lib` は使わず、oxlint と ESLint の `no-restricted-imports` で禁止している。 +`#lib` には明示的な拡張子が必要で、TS モジュールは `.js`、コンポーネントは `.svelte`、runes モジュール(`.svelte.ts`)は `.svelte.js` と書く。`vi.mock` の specifier も同じ形にする。 +lint が検出するのは import・export 宣言(`import type`・`export … from` を含む)と `.ts` の動的 `import()` で、`vi.mock('$lib/...')` と `.svelte` 内の動的 `import()` は検出しない。import の specifier をまとめて変えたときは、`rg -n '\$lib' src e2e prisma` で残りが無いことも確かめる。 +`$features` は `svelte.config.js` の alias で定義している。 ```typescript -import { formatDate } from '$lib/utils/format'; +import { formatDate } from '#lib/utils/format.js'; import WorkBookForm from '$features/workbooks/components/shared/WorkBookForm.svelte'; import type { PageServerLoad } from './$types'; ``` diff --git a/eslint.config.mjs b/eslint.config.mjs index 4adef090a..cd19da504 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -80,6 +80,19 @@ export default [ 'svelte/no-useless-mustaches': 'warn', 'svelte/prefer-writable-derived': 'warn', // New in 3.6.0 - prefer $derived over $state+$effect 'svelte/valid-prop-names-in-kit-pages': 'warn', // Allow props other than data/errors in pages + // Kit 2 still resolves $lib, so new imports would only break on Kit 3; oxlint covers JS/TS files + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + regex: '^\\$lib(/|$)', + message: + 'SvelteKit 3 removes $lib. Use #lib with an explicit extension (e.g. #lib/types/task.js).', + }, + ], + }, + ], 'no-unused-vars': 'off', // Use TypeScript version instead 'no-undef': 'off', // TypeScript handles this }, diff --git a/package.json b/package.json index 0c796a087..d16d1b94c 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,9 @@ "zod": "4.6.7" }, "type": "module", + "imports": { + "#lib/*": "./src/lib/*" + }, "dependencies": { "@dnd-kit/helpers": "0.5.1", "@dnd-kit/svelte": "0.5.1", diff --git a/src/features/account/components/delete/AccountDeletionForm.svelte b/src/features/account/components/delete/AccountDeletionForm.svelte index c41ea0deb..8cccb6398 100644 --- a/src/features/account/components/delete/AccountDeletionForm.svelte +++ b/src/features/account/components/delete/AccountDeletionForm.svelte @@ -2,9 +2,9 @@ import { Input, Button, Alert, Checkbox, Modal } from 'flowbite-svelte'; import Info from '@lucide/svelte/icons/info'; - import ContainerWrapper from '$lib/components/ContainerWrapper.svelte'; - import FormWrapper from '$lib/components/FormWrapper.svelte'; - import LabelWrapper from '$lib/components/LabelWrapper.svelte'; + import ContainerWrapper from '#lib/components/ContainerWrapper.svelte'; + import FormWrapper from '#lib/components/FormWrapper.svelte'; + import LabelWrapper from '#lib/components/LabelWrapper.svelte'; import WarningMessageOnDeletingAccount from './WarningMessageOnDeletingAccount.svelte'; interface Props { diff --git a/src/features/account/components/settings/AtCoderVerificationForm.svelte b/src/features/account/components/settings/AtCoderVerificationForm.svelte index 506cb4b28..047d8aafd 100644 --- a/src/features/account/components/settings/AtCoderVerificationForm.svelte +++ b/src/features/account/components/settings/AtCoderVerificationForm.svelte @@ -3,10 +3,10 @@ import { Label, Input, P, Clipboard } from 'flowbite-svelte'; import ClipboardCopy from '@lucide/svelte/icons/clipboard-copy'; import Check from '@lucide/svelte/icons/check'; - import ContainerWrapper from '$lib/components/ContainerWrapper.svelte'; - import FormWrapper from '$lib/components/FormWrapper.svelte'; - import LabelWrapper from '$lib/components/LabelWrapper.svelte'; - import SubmissionButton from '$lib/components/SubmissionButton.svelte'; + import ContainerWrapper from '#lib/components/ContainerWrapper.svelte'; + import FormWrapper from '#lib/components/FormWrapper.svelte'; + import LabelWrapper from '#lib/components/LabelWrapper.svelte'; + import SubmissionButton from '#lib/components/SubmissionButton.svelte'; interface Props { username: string; diff --git a/src/features/account/services/atcoder_verification.test.ts b/src/features/account/services/atcoder_verification.test.ts index a758a7b34..16fa2b32b 100644 --- a/src/features/account/services/atcoder_verification.test.ts +++ b/src/features/account/services/atcoder_verification.test.ts @@ -1,6 +1,6 @@ import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest'; -vi.mock('$lib/server/database', () => ({ +vi.mock('#lib/server/database.js', () => ({ default: { user: { findUniqueOrThrow: vi.fn(), @@ -13,13 +13,13 @@ vi.mock('$lib/server/database', () => ({ }, })); -vi.mock('$lib/utils/hash', () => ({ +vi.mock('#lib/utils/hash.js', () => ({ sha256: vi.fn().mockResolvedValue('mocked-hash'), })); import { Roles, type AtCoderAccount } from '@prisma/client'; -import prisma from '$lib/server/database'; +import prisma from '#lib/server/database.js'; import { generate, validate, reset } from './atcoder_verification'; // --------------------------------------------------------------------------- diff --git a/src/features/account/services/atcoder_verification.ts b/src/features/account/services/atcoder_verification.ts index 2fa856076..37878bc65 100644 --- a/src/features/account/services/atcoder_verification.ts +++ b/src/features/account/services/atcoder_verification.ts @@ -1,5 +1,5 @@ -import { default as db } from '$lib/server/database'; -import { sha256 } from '$lib/utils/hash'; +import { default as db } from '#lib/server/database.js'; +import { sha256 } from '#lib/utils/hash.js'; const EXTERNAL_API_TIMEOUT_MS = 5000; diff --git a/src/features/auth/server/session.test.ts b/src/features/auth/server/session.test.ts index f67ae1211..cfcc1ce5b 100644 --- a/src/features/auth/server/session.test.ts +++ b/src/features/auth/server/session.test.ts @@ -2,7 +2,7 @@ import { describe, test, expect, beforeEach, afterEach, vi } from 'vitest'; import { Prisma, Roles } from '@prisma/client'; -vi.mock('$lib/server/database', () => ({ +vi.mock('#lib/server/database.js', () => ({ default: { session: { create: vi.fn(), @@ -13,7 +13,7 @@ vi.mock('$lib/server/database', () => ({ }, })); -import db from '$lib/server/database'; +import db from '#lib/server/database.js'; import { createSession, validateSession, invalidateSession, SESSION_COOKIE_NAME } from './session'; const mockDb = db as unknown as { diff --git a/src/features/auth/server/session.ts b/src/features/auth/server/session.ts index 00eeb952f..a687c29af 100644 --- a/src/features/auth/server/session.ts +++ b/src/features/auth/server/session.ts @@ -1,7 +1,7 @@ import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; import type { Roles } from '@prisma/client'; -import client from '$lib/server/database'; +import client from '#lib/server/database.js'; import { generateRandomString } from './random'; // lucia v2 defaults: active 24h, idle +14d diff --git a/src/features/auth/services/admin_access.test.ts b/src/features/auth/services/admin_access.test.ts index c10a26b88..b6667ca06 100644 --- a/src/features/auth/services/admin_access.test.ts +++ b/src/features/auth/services/admin_access.test.ts @@ -19,12 +19,12 @@ vi.mock('@sveltejs/kit', () => { return { redirect: vi.fn(redirectImpl), error: vi.fn(errorImpl) }; }); -vi.mock('$lib/services/users', () => ({ +vi.mock('#lib/services/users.js', () => ({ getUser: vi.fn(), })); -import * as userService from '$lib/services/users'; -import { Roles } from '$lib/types/user'; +import * as userService from '#lib/services/users.js'; +import { Roles } from '#lib/types/user.js'; import { validateAdminAccess, validateAdminAccessForApi } from './admin_access'; const createMockLocalsWithSession = (username = 'admin-user') => diff --git a/src/features/auth/services/admin_access.ts b/src/features/auth/services/admin_access.ts index 7850b6d22..64bce1258 100644 --- a/src/features/auth/services/admin_access.ts +++ b/src/features/auth/services/admin_access.ts @@ -1,15 +1,15 @@ import { redirect, error } from '@sveltejs/kit'; -import * as userService from '$lib/services/users'; +import * as userService from '#lib/services/users.js'; -import { Roles } from '$lib/types/user'; +import { Roles } from '#lib/types/user.js'; -import { isAdmin } from '$lib/utils/authorship'; +import { isAdmin } from '#lib/utils/authorship.js'; import { TEMPORARY_REDIRECT, UNAUTHORIZED, FORBIDDEN, -} from '$lib/constants/http-response-status-codes'; +} from '#lib/constants/http-response-status-codes.js'; import { buildLoginPath } from '../utils/login'; diff --git a/src/features/auth/services/credentials.test.ts b/src/features/auth/services/credentials.test.ts index 4988afa96..7b84c47d0 100644 --- a/src/features/auth/services/credentials.test.ts +++ b/src/features/auth/services/credentials.test.ts @@ -2,7 +2,7 @@ import { describe, test, expect, vi } from 'vitest'; import { Prisma } from '@prisma/client'; -vi.mock('$lib/server/database', () => ({ +vi.mock('#lib/server/database.js', () => ({ default: { $transaction: vi.fn(), user: { @@ -20,7 +20,7 @@ vi.mock('../server/password', () => ({ verifyPassword: vi.fn(), })); -import db from '$lib/server/database'; +import db from '#lib/server/database.js'; import { hashPassword, verifyPassword } from '../server/password'; import { registerUser, authenticateUser } from './credentials'; diff --git a/src/features/auth/services/credentials.ts b/src/features/auth/services/credentials.ts index 4d1022e1c..b1eb6dc5f 100644 --- a/src/features/auth/services/credentials.ts +++ b/src/features/auth/services/credentials.ts @@ -1,6 +1,6 @@ import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; -import client from '$lib/server/database'; +import client from '#lib/server/database.js'; import { hashPassword, verifyPassword } from '../server/password'; import { generateRandomString } from '../server/random'; diff --git a/src/features/auth/services/session_guards.ts b/src/features/auth/services/session_guards.ts index 4eb97bf92..9a1be260f 100644 --- a/src/features/auth/services/session_guards.ts +++ b/src/features/auth/services/session_guards.ts @@ -1,6 +1,6 @@ import { redirect } from '@sveltejs/kit'; -import { TEMPORARY_REDIRECT } from '$lib/constants/http-response-status-codes'; +import { TEMPORARY_REDIRECT } from '#lib/constants/http-response-status-codes.js'; import { buildLoginPath } from '../utils/login'; diff --git a/src/features/auth/utils/login.ts b/src/features/auth/utils/login.ts index 192840e32..d29d273ef 100644 --- a/src/features/auth/utils/login.ts +++ b/src/features/auth/utils/login.ts @@ -1,4 +1,4 @@ -import { LOGIN_PAGE } from '$lib/constants/navbar-links'; +import { LOGIN_PAGE } from '#lib/constants/navbar-links.js'; /** * Builds the login path with an optional redirect parameter. diff --git a/src/features/auth/utils/signup.ts b/src/features/auth/utils/signup.ts index 2f83dc5ae..6a8bcb1a1 100644 --- a/src/features/auth/utils/signup.ts +++ b/src/features/auth/utils/signup.ts @@ -1,4 +1,4 @@ -import { SIGNUP_PAGE } from '$lib/constants/navbar-links'; +import { SIGNUP_PAGE } from '#lib/constants/navbar-links.js'; /** * Builds the signup path with an optional redirect parameter. diff --git a/src/features/tasks/components/contest-table/TaskTable.svelte b/src/features/tasks/components/contest-table/TaskTable.svelte index a89ee2ed4..ab635fa87 100644 --- a/src/features/tasks/components/contest-table/TaskTable.svelte +++ b/src/features/tasks/components/contest-table/TaskTable.svelte @@ -13,13 +13,13 @@ TableHeadCell, } from 'flowbite-svelte'; - import type { TaskResults, TaskResult } from '$lib/types/task'; + import type { TaskResults, TaskResult } from '#lib/types/task.js'; import type { ContestTableProvider, ContestTableDisplayConfig, ContestTableMetaData, } from '$features/tasks/types/contest-table/contest_table_provider'; - import type { ContestTaskPairKey } from '$lib/types/contest_task_pair'; + import type { ContestTaskPairKey } from '#lib/types/contest_task_pair.js'; import type { VoteStatisticsMap } from '$features/votes/types/vote_result'; import TaskTableBodyCell from './TaskTableBodyCell.svelte'; @@ -31,11 +31,11 @@ type ContestTableProviderGroups, } from '$features/tasks/utils/contest-table/contest_table_provider'; - import { useLocalStorage } from '$lib/stores/local_storage_helper.svelte'; + import { useLocalStorage } from '#lib/stores/local_storage_helper.svelte.js'; - import { getBackgroundColorFrom } from '$lib/services/submission_status'; - import { areAllTasksAccepted } from '$lib/utils/task'; - import { createContestTaskPairKey } from '$lib/utils/contest_task_pair'; + import { getBackgroundColorFrom } from '#lib/services/submission_status.js'; + import { areAllTasksAccepted } from '#lib/utils/task.js'; + import { createContestTaskPairKey } from '#lib/utils/contest_task_pair.js'; import { getBodyRowClasses } from './_utils/contest_table_layout'; interface Props { diff --git a/src/features/tasks/components/contest-table/TaskTableBodyCell.svelte b/src/features/tasks/components/contest-table/TaskTableBodyCell.svelte index 568b21330..47197ed3d 100644 --- a/src/features/tasks/components/contest-table/TaskTableBodyCell.svelte +++ b/src/features/tasks/components/contest-table/TaskTableBodyCell.svelte @@ -1,12 +1,12 @@ // 2. formに use:preventEnterKey を追加 diff --git a/src/lib/actions/update_task_result.ts b/src/lib/actions/update_task_result.ts index 26a7a8d2e..a9838801f 100644 --- a/src/lib/actions/update_task_result.ts +++ b/src/lib/actions/update_task_result.ts @@ -1,7 +1,7 @@ import { fail } from '@sveltejs/kit'; -import * as crud from '$lib/services/task_results'; -import { BAD_REQUEST, UNAUTHORIZED } from '$lib/constants/http-response-status-codes'; +import * as crud from '#lib/services/task_results.js'; +import { BAD_REQUEST, UNAUTHORIZED } from '#lib/constants/http-response-status-codes.js'; // HACK: clickを1回実行するとactionsが2回実行されてしまう。原因と修正方法が分かっていない状態。 export const updateTaskResult = async ( diff --git a/src/lib/clients/aizu_online_judge/clients.test.ts b/src/lib/clients/aizu_online_judge/clients.test.ts index 0c1039688..201522c5d 100644 --- a/src/lib/clients/aizu_online_judge/clients.test.ts +++ b/src/lib/clients/aizu_online_judge/clients.test.ts @@ -1,18 +1,18 @@ import { describe, test, expect, beforeEach, afterEach, vi } from 'vitest'; import nock from 'nock'; -vi.mock('$lib/utils/time', () => ({ +vi.mock('#lib/utils/time.js', () => ({ delay: vi.fn().mockResolvedValue(undefined), })); -import { HttpRequestClient } from '$lib/clients/http_client'; -import { ContestTaskCache } from '$lib/clients/cache_strategy'; -import { Cache } from '$lib/clients/cache'; +import { HttpRequestClient } from '#lib/clients/http_client.js'; +import { ContestTaskCache } from '#lib/clients/cache_strategy.js'; +import { Cache } from '#lib/clients/cache.js'; import { AojCoursesApiClient, AojChallengesApiClient } from './clients'; -import type { ContestsForImport } from '$lib/contests/types/contest'; -import type { TasksForImport } from '$lib/types/task'; +import type { ContestsForImport } from '#lib/contests/types/contest.js'; +import type { TasksForImport } from '#lib/types/task.js'; import type { AOJCourseAPI, AOJChallengeContestAPI, AOJTaskAPIs } from './types'; import { loadMockData } from '../fixtures/helpers'; diff --git a/src/lib/clients/aizu_online_judge/clients.ts b/src/lib/clients/aizu_online_judge/clients.ts index 9af340fdd..0dacee80f 100644 --- a/src/lib/clients/aizu_online_judge/clients.ts +++ b/src/lib/clients/aizu_online_judge/clients.ts @@ -1,9 +1,12 @@ -import { HttpRequestClient } from '$lib/clients/http_client'; -import { ContestTaskCache } from '$lib/clients/cache_strategy'; -import { getCachedOrFetchContests, getCachedOrFetchTasks } from '$lib/clients/contest_task_fetcher'; +import { HttpRequestClient } from '#lib/clients/http_client.js'; +import { ContestTaskCache } from '#lib/clients/cache_strategy.js'; +import { + getCachedOrFetchContests, + getCachedOrFetchTasks, +} from '#lib/clients/contest_task_fetcher.js'; -import type { ContestsForImport } from '$lib/contests/types/contest'; -import type { TasksForImport } from '$lib/types/task'; +import type { ContestsForImport } from '#lib/contests/types/contest.js'; +import type { TasksForImport } from '#lib/types/task.js'; import type { AOJCourseAPI, diff --git a/src/lib/clients/aizu_online_judge/utils.ts b/src/lib/clients/aizu_online_judge/utils.ts index cb22863f7..5406393d9 100644 --- a/src/lib/clients/aizu_online_judge/utils.ts +++ b/src/lib/clients/aizu_online_judge/utils.ts @@ -1,4 +1,4 @@ -import type { ContestForImport } from '$lib/contests/types/contest'; +import type { ContestForImport } from '#lib/contests/types/contest.js'; import { PENDING } from './types'; import type { AOJTaskAPI } from './types'; diff --git a/src/lib/clients/atcoder/atcoder_problems.test.ts b/src/lib/clients/atcoder/atcoder_problems.test.ts index 9b78df8be..f33079ef6 100644 --- a/src/lib/clients/atcoder/atcoder_problems.test.ts +++ b/src/lib/clients/atcoder/atcoder_problems.test.ts @@ -1,14 +1,14 @@ import { describe, test, expect, beforeAll, beforeEach, afterEach, vi } from 'vitest'; import nock from 'nock'; -vi.mock('$lib/utils/time', () => ({ +vi.mock('#lib/utils/time.js', () => ({ delay: vi.fn().mockResolvedValue(undefined), })); -import type { ContestsForImport } from '$lib/contests/types/contest'; -import type { TasksForImport } from '$lib/types/task'; +import type { ContestsForImport } from '#lib/contests/types/contest.js'; +import type { TasksForImport } from '#lib/types/task.js'; -import { AtCoderProblemsApiClient } from '$lib/clients/atcoder/atcoder_problems'; +import { AtCoderProblemsApiClient } from '#lib/clients/atcoder/atcoder_problems.js'; import { loadMockData } from '../fixtures/helpers'; diff --git a/src/lib/clients/atcoder/atcoder_problems.ts b/src/lib/clients/atcoder/atcoder_problems.ts index 653509a57..2b0211093 100644 --- a/src/lib/clients/atcoder/atcoder_problems.ts +++ b/src/lib/clients/atcoder/atcoder_problems.ts @@ -1,9 +1,9 @@ -import { HttpRequestClient } from '$lib/clients/http_client'; +import { HttpRequestClient } from '#lib/clients/http_client.js'; -import type { ContestsForImport } from '$lib/contests/types/contest'; -import type { TasksForImport } from '$lib/types/task'; +import type { ContestsForImport } from '#lib/contests/types/contest.js'; +import type { TasksForImport } from '#lib/types/task.js'; -import { ATCODER_PROBLEMS_API_BASE_URL } from '$lib/constants/urls'; +import { ATCODER_PROBLEMS_API_BASE_URL } from '#lib/constants/urls.js'; /** * The `AtCoderProblemsApiClient` class provides methods to interact with the AtCoder Problems API. diff --git a/src/lib/clients/cache.test.ts b/src/lib/clients/cache.test.ts index cd0334c81..9d3138d90 100644 --- a/src/lib/clients/cache.test.ts +++ b/src/lib/clients/cache.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest'; -import { Cache } from '$lib/clients/cache'; +import { Cache } from '#lib/clients/cache.js'; describe('Cache', () => { // Mock time functions diff --git a/src/lib/clients/cache_strategy.ts b/src/lib/clients/cache_strategy.ts index 3b9657536..2a32cd3c7 100644 --- a/src/lib/clients/cache_strategy.ts +++ b/src/lib/clients/cache_strategy.ts @@ -1,7 +1,7 @@ -import { Cache } from '$lib/clients/cache'; +import { Cache } from '#lib/clients/cache.js'; -import type { ContestsForImport } from '$lib/contests/types/contest'; -import type { TasksForImport } from '$lib/types/task'; +import type { ContestsForImport } from '#lib/contests/types/contest.js'; +import type { TasksForImport } from '#lib/types/task.js'; export class ContestTaskCache { constructor( diff --git a/src/lib/clients/contest_task_fetcher.ts b/src/lib/clients/contest_task_fetcher.ts index 1310d669c..097d04be7 100644 --- a/src/lib/clients/contest_task_fetcher.ts +++ b/src/lib/clients/contest_task_fetcher.ts @@ -1,7 +1,7 @@ -import type { HttpRequestClient } from '$lib/clients/http_client'; -import type { ContestTaskCache } from '$lib/clients/cache_strategy'; -import type { ContestsForImport } from '$lib/contests/types/contest'; -import type { TasksForImport } from '$lib/types/task'; +import type { HttpRequestClient } from '#lib/clients/http_client.js'; +import type { ContestTaskCache } from '#lib/clients/cache_strategy.js'; +import type { ContestsForImport } from '#lib/contests/types/contest.js'; +import type { TasksForImport } from '#lib/types/task.js'; type FetchContestsConfig = { cacheKey: string; diff --git a/src/lib/clients/fixtures/record_requests.ts b/src/lib/clients/fixtures/record_requests.ts index 25195b053..e45b32022 100644 --- a/src/lib/clients/fixtures/record_requests.ts +++ b/src/lib/clients/fixtures/record_requests.ts @@ -1,16 +1,16 @@ import path from 'path'; import fs from 'fs'; -import { AtCoderProblemsApiClient } from '$lib/clients/atcoder/atcoder_problems'; -import { HttpRequestClient } from '$lib/clients/http_client'; +import { AtCoderProblemsApiClient } from '#lib/clients/atcoder/atcoder_problems.js'; +import { HttpRequestClient } from '#lib/clients/http_client.js'; import type { AOJCourseAPI, AOJTaskAPIs, AOJChallengeContestAPI, -} from '$lib/clients/aizu_online_judge/types'; +} from '#lib/clients/aizu_online_judge/types.js'; -import { AOJ_API_BASE_URL } from '$lib/constants/urls'; +import { AOJ_API_BASE_URL } from '#lib/constants/urls.js'; // Run the main function if you add a contest site. // Usage: diff --git a/src/lib/clients/http_client.ts b/src/lib/clients/http_client.ts index a01d7bdd0..3617e6d6d 100644 --- a/src/lib/clients/http_client.ts +++ b/src/lib/clients/http_client.ts @@ -1,6 +1,6 @@ -import type { ContestsForImport } from '$lib/contests/types/contest'; -import type { TasksForImport } from '$lib/types/task'; -import { delay } from '$lib/utils/time'; +import type { ContestsForImport } from '#lib/contests/types/contest.js'; +import type { TasksForImport } from '#lib/types/task.js'; +import { delay } from '#lib/utils/time.js'; /** * Client interface for interacting with tasks and contests API endpoints. diff --git a/src/lib/clients/index.ts b/src/lib/clients/index.ts index 5b9c229d2..3bf06520b 100644 --- a/src/lib/clients/index.ts +++ b/src/lib/clients/index.ts @@ -1,18 +1,18 @@ -import { HttpRequestClient } from '$lib/clients/http_client'; -import { ContestTaskCache } from '$lib/clients/cache_strategy'; -import { Cache } from '$lib/clients/cache'; +import { HttpRequestClient } from '#lib/clients/http_client.js'; +import { ContestTaskCache } from '#lib/clients/cache_strategy.js'; +import { Cache } from '#lib/clients/cache.js'; -import { AtCoderProblemsApiClient } from '$lib/clients/atcoder/atcoder_problems'; +import { AtCoderProblemsApiClient } from '#lib/clients/atcoder/atcoder_problems.js'; import { AojCoursesApiClient, AojChallengesApiClient, -} from '$lib/clients/aizu_online_judge/clients'; +} from '#lib/clients/aizu_online_judge/clients.js'; -import type { ContestsForImport } from '$lib/contests/types/contest'; -import type { TasksForImport } from '$lib/types/task'; -import type { ChallengeParams } from '$lib/clients/aizu_online_judge/types'; +import type { ContestsForImport } from '#lib/contests/types/contest.js'; +import type { TasksForImport } from '#lib/types/task.js'; +import type { ChallengeParams } from '#lib/clients/aizu_online_judge/types.js'; -import { AOJ_API_BASE_URL } from '$lib/constants/urls'; +import { AOJ_API_BASE_URL } from '#lib/constants/urls.js'; // Supported contest data sources for task import. export type ContestTaskImportSource = diff --git a/src/lib/components/AuthForm.svelte b/src/lib/components/AuthForm.svelte index b06d72562..2e280efe8 100644 --- a/src/lib/components/AuthForm.svelte +++ b/src/lib/components/AuthForm.svelte @@ -10,15 +10,15 @@ import Eye from '@lucide/svelte/icons/eye'; import EyeOff from '@lucide/svelte/icons/eye-off'; - import MessageHelperWrapper from '$lib/components/MessageHelperWrapper.svelte'; + import MessageHelperWrapper from '#lib/components/MessageHelperWrapper.svelte'; import { GUEST_USER_NAME, GUEST_USER_PASSWORD, // GUEST_USER_PASSWORD_FOR_LOCAL, LOGIN_LABEL, - } from '$lib/constants/forms'; - import { HOME_PAGE, FORGOT_PASSWORD_PAGE, LOGIN_PAGE } from '$lib/constants/navbar-links'; + } from '#lib/constants/forms.js'; + import { HOME_PAGE, FORGOT_PASSWORD_PAGE, LOGIN_PAGE } from '#lib/constants/navbar-links.js'; interface Props { // FIXME: 構造体に相当するものを利用した方が拡張・修正がしやすくなるかもしれせまん diff --git a/src/lib/components/Footer.svelte b/src/lib/components/Footer.svelte index 28f652d06..94d6a5d2b 100644 --- a/src/lib/components/Footer.svelte +++ b/src/lib/components/Footer.svelte @@ -1,7 +1,7 @@ diff --git a/src/lib/components/GradeLabel.svelte b/src/lib/components/GradeLabel.svelte index 04a6f3f5c..029aebefe 100644 --- a/src/lib/components/GradeLabel.svelte +++ b/src/lib/components/GradeLabel.svelte @@ -1,11 +1,11 @@ diff --git a/src/routes/problems/+page.server.ts b/src/routes/problems/+page.server.ts index 1551d2b35..676487dc0 100644 --- a/src/routes/problems/+page.server.ts +++ b/src/routes/problems/+page.server.ts @@ -2,13 +2,13 @@ import { fail, type Actions } from '@sveltejs/kit'; import { superValidate } from 'sveltekit-superforms'; import { zod4 } from 'sveltekit-superforms/adapters'; -import * as task_crud from '$lib/services/task_results'; +import * as task_crud from '#lib/services/task_results.js'; import { getVoteGradeStatistics } from '$features/votes/services/vote_statistics'; -import type { TaskResults } from '$lib/types/task'; -import { updateTaskResult } from '$lib/actions/update_task_result'; +import type { TaskResults } from '#lib/types/task.js'; +import { updateTaskResult } from '#lib/actions/update_task_result.js'; import { voteAbsoluteGrade } from '@/features/votes/actions/vote_actions'; import { voteAbsoluteGradeSchema } from '$features/votes/zod/schema'; -import { BAD_REQUEST } from '$lib/constants/http-response-status-codes'; +import { BAD_REQUEST } from '#lib/constants/http-response-status-codes.js'; // 一覧表ページは、ログインしていなくても閲覧できるようにする export async function load({ locals, url }) { diff --git a/src/routes/problems/+page.svelte b/src/routes/problems/+page.svelte index ca943f540..4b47b96b6 100644 --- a/src/routes/problems/+page.svelte +++ b/src/routes/problems/+page.svelte @@ -1,20 +1,20 @@