Svelte 컴포넌트를 제외한 파일, 폴더 및 라우팅 경로의 이름을 kebab-case로 통일하고 import 경로에 실제 파일 확장자를 사용하도록 변경

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
staticandClaude Opus 5.5 committed 2026-10-12 07:41:28 +09:00
1 parent 225ad3515f
commit 306fcb2420
201 files changed
+550 -545

No files matched your search

+1 -1
View File
@@ -61,7 +61,7 @@ export default defineConfig(
"src/lib/ui/**": "^(#lib/(server|client|features)/|#trpc/)",
"src/lib/features/**": "^#lib/server/",
"src/service-worker/**":
"^(#lib/(?!shared/|client/storage/|client/cache/fileCache\\.js$)|#trpc/|#workers/)",
"^(#lib/(?!shared/|client/storage/|client/cache/file-cache\\.ts$)|#trpc/|#workers/)",
}),
{
files: ["**/*.svelte", "**/*.svelte.ts", "**/*.svelte.js"],
+1 -1
View File
@@ -1,5 +1,5 @@
import { defineConfig } from "kysely-ctl";
import { createDialect } from "./src/lib/server/db/dialect";
import { createDialect } from "./src/lib/server/db/dialect.ts";
// Empty values (e.g. `DATABASE_HOST=` in .env) are treated as unset, as in src/env.ts
const optional = (name: string) => process.env[name] || undefined;
+4 -4
View File
@@ -1,8 +1,8 @@
import type { ClientInit } from "@sveltejs/kit/hooks";
import { cleanupFileCaches } from "#lib/client/cache/index.js";
import { keyring } from "#lib/client/keys/index.js";
import { listenForServiceWorkerMessages } from "#lib/client/serviceWorker.js";
import { cleanupDanglingInfos } from "#lib/client/storage/indexedDB/index.js";
import { cleanupFileCaches } from "#lib/client/cache/index.ts";
import { keyring } from "#lib/client/keys/index.ts";
import { listenForServiceWorkerMessages } from "#lib/client/service-worker.ts";
import { cleanupDanglingInfos } from "#lib/client/storage/indexed-db/index.ts";
const requestPersistentStorage = async () => {
const isPersistent = await navigator.storage.persist();
+4 -4
View File
@@ -1,9 +1,9 @@
import { sequence, type ServerInit } from "@sveltejs/kit/hooks";
import schedule from "node-schedule";
import { ClientRepo, SessionRepo } from "#lib/server/db/index.js";
import { migrateDB } from "#lib/server/db/kysely.js";
import { authenticate, setAgentInfo } from "#lib/server/middlewares/index.js";
import { FileDeletionService, UploadService } from "#lib/server/services/index.js";
import { ClientRepo, SessionRepo } from "#lib/server/db/index.ts";
import { migrateDB } from "#lib/server/db/kysely.ts";
import { authenticate, setAgentInfo } from "#lib/server/middlewares/index.ts";
import { FileDeletionService, UploadService } from "#lib/server/services/index.ts";
export const init: ServerInit = async () => {
await migrateDB();
@@ -4,7 +4,7 @@ import {
getFileCacheIndexOf,
storeFileCacheIndex,
updateFileCacheRetrievedAt,
} from "#lib/client/storage/indexedDB/cacheIndex.js";
} from "#lib/client/storage/indexed-db/cache-index.ts";
import {
createWritable,
deleteDirectory,
@@ -14,8 +14,8 @@ import {
listDirectoryNames,
listFileNames,
moveFile,
} from "#lib/client/storage/opfs.js";
import { CHUNK_SIZE, getChunkCount } from "#lib/shared/format/index.js";
} from "#lib/client/storage/opfs.ts";
import { CHUNK_SIZE, getChunkCount } from "#lib/shared/format/index.ts";
// Caches the plaintext of files in chunks, so that partially loaded files (e.g. videos which were
// partially played) can also be cached. Chunk `i` starts at `i * CHUNK_SIZE` of the plaintext,
+2 -2
View File
@@ -1,2 +1,2 @@
export * from "./fileCache";
export * from "./thumbnailCache.svelte";
export * from "./file-cache.ts";
export * from "./thumbnail-cache.svelte.ts";
@@ -1,7 +1,7 @@
/* eslint-disable svelte/prefer-svelte-reactivity -- Lookup tables of reactive entries */
import { LRUCache } from "lru-cache";
import { deleteDirectory, deleteFile, readFile, writeFile } from "#lib/client/storage/opfs.js";
import { decryptChunk, encodeToBase64 } from "#lib/shared/crypto/index.js";
import { deleteDirectory, deleteFile, readFile, writeFile } from "#lib/client/storage/opfs.ts";
import { decryptChunk, encodeToBase64 } from "#lib/shared/crypto/index.ts";
export interface Thumbnail {
url?: string;
+2 -2
View File
@@ -1,5 +1,5 @@
import type { ComputeMessage, ResultMessage } from "#workers/hmac.js";
import HmacWorker from "#workers/hmac.js?worker";
import type { ComputeMessage, ResultMessage } from "#workers/hmac.ts";
import HmacWorker from "#workers/hmac.ts?worker";
// Computes HMAC of large blobs incrementally in a worker, which WebCrypto doesn't support
export const signMessageHmac = async (message: Blob, hmacSecret: CryptoKey) => {
+3 -3
View File
@@ -13,9 +13,9 @@ import {
makeRSAKeyNonextractable,
wrapHmacSecret,
wrapMasterKey,
} from "#lib/shared/crypto/index.js";
import { keyring } from "./keyring.svelte";
import { deserializeClientKeys } from "./serialization";
} from "#lib/shared/crypto/index.ts";
import { keyring } from "./keyring.svelte.ts";
import { deserializeClientKeys } from "./serialization.ts";
// Generates new client keys and keeps them in the keyring without persisting
export const generateClientKeys = async () => {
+5 -5
View File
@@ -1,5 +1,5 @@
export * from "./generation";
export * from "./keyring.svelte";
export * from "./serialization";
export * from "./sync";
export * from "./types";
export * from "./generation.ts";
export * from "./keyring.svelte.ts";
export * from "./serialization.ts";
export * from "./sync.ts";
export * from "./types.ts";
+2 -2
View File
@@ -5,8 +5,8 @@ import {
storeClientKey,
storeHmacSecrets,
storeMasterKeys,
} from "#lib/client/storage/indexedDB/index.js";
import type { ClientKeys, HmacSecret, MasterKey } from "./types";
} from "#lib/client/storage/indexed-db/index.ts";
import type { ClientKeys, HmacSecret, MasterKey } from "./types.ts";
const findLatestActive = <T extends { version: number; state: string }>(
entries: ReadonlyMap<number, T>,
+4 -4
View File
@@ -7,10 +7,10 @@ import {
unwrapHmacSecret,
unwrapMasterKey,
verifyMasterKeyWrapped,
} from "#lib/shared/crypto/index.js";
import { isTRPCClientError, trpc } from "#trpc/client.js";
import { keyring } from "./keyring.svelte";
import type { ClientKeys } from "./types";
} from "#lib/shared/crypto/index.ts";
import { isTRPCClientError, trpc } from "#trpc/client.ts";
import { keyring } from "./keyring.svelte.ts";
import type { ClientKeys } from "./types.ts";
// Synchronizes keys with the server
@@ -1,10 +1,10 @@
import { handleDownloadProgress } from "#lib/client/transfer/download.svelte.js";
import { handleDownloadProgress } from "#lib/client/transfer/download.svelte.ts";
import {
DECRYPTED_FILE_URL_PREFIX,
type FileMetadata,
type ServiceWorkerMessage,
type ServiceWorkerResponse,
} from "#lib/shared/serviceWorker.js";
} from "#lib/shared/service-worker.ts";
const PREPARE_TIMEOUT_MS = 5000;
@@ -0,0 +1,3 @@
export * from "./cache-index.ts";
export * from "./filesystem.ts";
export * from "./key-store.ts";
@@ -1,3 +0,0 @@
export * from "./cacheIndex";
export * from "./filesystem";
export * from "./keyStore";
@@ -1,10 +1,10 @@
import { sha256 } from "@noble/hashes/sha2.js";
import axios from "axios";
import pLimit from "p-limit";
import { encodeToBase64, encryptChunk } from "#lib/shared/crypto/index.js";
import { CHUNK_SIZE, getChunkCount, getEncryptedSize } from "#lib/shared/format/index.js";
import { BoundedQueue } from "#lib/utils/concurrency/index.js";
import { createSpeedMeter } from "#lib/utils/speedMeter.js";
import { encodeToBase64, encryptChunk } from "#lib/shared/crypto/index.ts";
import { CHUNK_SIZE, getChunkCount, getEncryptedSize } from "#lib/shared/format/index.ts";
import { BoundedQueue } from "#lib/utils/concurrency/index.ts";
import { createSpeedMeter } from "#lib/utils/speed-meter.ts";
interface UploadStats {
progress: number;
+2 -2
View File
@@ -1,5 +1,5 @@
import type { DownloadProgressMessage } from "#lib/shared/serviceWorker.js";
import { createSpeedMeter } from "#lib/utils/speedMeter.js";
import type { DownloadProgressMessage } from "#lib/shared/service-worker.ts";
import { createSpeedMeter } from "#lib/utils/speed-meter.ts";
// Files are downloaded and decrypted by the service worker, which reports the progress
+2 -2
View File
@@ -1,2 +1,2 @@
export * from "./download.svelte";
export * from "./upload.svelte";
export * from "./download.svelte.ts";
export * from "./upload.svelte.ts";
+10 -10
View File
@@ -1,24 +1,24 @@
import { limitFunction } from "p-limit";
import { signMessageHmac } from "#lib/client/crypto/hmac.js";
import { createUploadFileCache } from "#lib/client/cache/index.ts";
import { signMessageHmac } from "#lib/client/crypto/hmac.ts";
import {
ensureHmacSecrets,
keyring,
type HmacSecret,
type MasterKey,
} from "#lib/client/keys/index.js";
import { createUploadFileCache } from "#lib/client/cache/index.js";
import { readExifDateTime } from "#lib/client/media/exif.js";
import { generateThumbnail } from "#lib/client/media/thumbnail.js";
import { uploadBlob } from "#lib/client/transfer/chunkedUpload.js";
} from "#lib/client/keys/index.ts";
import { readExifDateTime } from "#lib/client/media/exif.ts";
import { generateThumbnail } from "#lib/client/media/thumbnail.ts";
import { uploadBlob } from "#lib/client/transfer/chunked-upload.ts";
import {
encodeToBase64,
generateDataKey,
wrapDataKey,
encryptString,
} from "#lib/shared/crypto/index.js";
import { getChunkCount } from "#lib/shared/format/index.js";
import { Scheduler } from "#lib/utils/index.js";
import { trpc } from "#trpc/client.js";
} from "#lib/shared/crypto/index.ts";
import { getChunkCount } from "#lib/shared/format/index.ts";
import { Scheduler } from "#lib/utils/index.ts";
import { trpc } from "#trpc/client.ts";
export interface FileUploadState {
id: string;
@@ -1,5 +1,5 @@
<script lang="ts">
import { ActionModal } from "#lib/ui/index.js";
import { ActionModal } from "#lib/ui/index.ts";
interface Props {
isOpen: boolean;
+1 -1
View File
@@ -1,4 +1,4 @@
import { trpc } from "#trpc/client.js";
import { trpc } from "#trpc/client.ts";
export const login = async (email: string, password: string) => {
await trpc.auth.login.mutate({ email, password });
+2 -2
View File
@@ -1,5 +1,5 @@
import { showToast } from "#lib/ui/index.js";
import { isTRPCClientError } from "#trpc/client.js";
import { showToast } from "#lib/ui/index.ts";
import { isTRPCClientError } from "#trpc/client.ts";
const getErrorMessage = (e: unknown, fallbackMessage: string) => {
if (isTRPCClientError(e)) {
+3 -3
View File
@@ -5,9 +5,9 @@ import {
setFileFavorite,
type LocalDirectoryInfo,
type SummarizedFileInfo,
} from "#lib/features/filesystem/index.js";
import { sortEntries } from "#lib/utils/index.js";
import { trpc } from "#trpc/client.js";
} from "#lib/features/filesystem/index.ts";
import { sortEntries } from "#lib/utils/index.ts";
import { trpc } from "#trpc/client.ts";
export type FavoriteEntry =
| { type: "directory"; name: string; details: LocalDirectoryInfo }
+7 -7
View File
@@ -1,15 +1,15 @@
import * as IndexedDB from "#lib/client/storage/indexedDB/index.js";
import { isTRPCClientError, trpc } from "#trpc/client.js";
import { FilesystemCache } from "./cache.svelte";
import { invalidateFile } from "./file";
import * as IndexedDB from "#lib/client/storage/indexed-db/index.ts";
import { isTRPCClientError, trpc } from "#trpc/client.ts";
import { FilesystemCache } from "./cache.svelte.ts";
import { invalidateFile } from "./file.ts";
import {
decryptCategoryMetadata,
decryptFileMetadata,
encryptName,
generateEntryKeys,
} from "./metadata";
import { useResource } from "./resource.svelte";
import type { CategoryInfo, DataKey, LocalCategoryInfo, MaybeCategoryInfo } from "./types";
} from "./metadata.ts";
import { useResource } from "./resource.svelte.ts";
import type { CategoryInfo, DataKey, LocalCategoryInfo, MaybeCategoryInfo } from "./types.ts";
const cache = new FilesystemCache<CategoryId, MaybeCategoryInfo>({
async fetchFromIndexedDB(id) {
@@ -1,5 +1,5 @@
<script module lang="ts">
import type { DataKey, SubCategoryInfo } from "#lib/features/filesystem/index.js";
import type { DataKey, SubCategoryInfo } from "#lib/features/filesystem/index.ts";
export interface SelectedCategory {
id: number;
@@ -11,8 +11,8 @@
<script lang="ts">
import type { Component } from "svelte";
import type { SvelteHTMLElements } from "svelte/elements";
import { ActionEntryButton, CategoryLabel } from "#lib/ui/index.js";
import { sortEntries } from "#lib/utils/index.js";
import { ActionEntryButton, CategoryLabel } from "#lib/ui/index.ts";
import { sortEntries } from "#lib/utils/index.ts";
interface Props {
categories: SubCategoryInfo[];
@@ -1,5 +1,5 @@
<script lang="ts">
import { TextInputModal } from "#lib/ui/index.js";
import { TextInputModal } from "#lib/ui/index.ts";
interface Props {
isOpen: boolean;
@@ -1,7 +1,7 @@
<script lang="ts">
import type { Component } from "svelte";
import type { SvelteHTMLElements } from "svelte/elements";
import { ActionEntryButton, DirectoryEntryLabel } from "#lib/ui/index.js";
import { ActionEntryButton, DirectoryEntryLabel } from "#lib/ui/index.ts";
interface Props {
action?: {
@@ -1,10 +1,10 @@
<script lang="ts">
import type { Component } from "svelte";
import type { ClassValue, SvelteHTMLElements } from "svelte/elements";
import { getFileThumbnail } from "#lib/client/cache/index.js";
import { ActionEntryButton, DirectoryEntryLabel } from "#lib/ui/index.js";
import { formatDateTime } from "#lib/utils/index.js";
import type { SummarizedFileInfo } from "../types";
import { getFileThumbnail } from "#lib/client/cache/index.ts";
import { ActionEntryButton, DirectoryEntryLabel } from "#lib/ui/index.ts";
import { formatDateTime } from "#lib/utils/index.ts";
import type { SummarizedFileInfo } from "../types.ts";
interface Props {
action?: {
@@ -1,6 +1,6 @@
<script lang="ts">
import { getFileThumbnail } from "#lib/client/cache/index.js";
import type { SummarizedFileInfo } from "#lib/features/filesystem/index.js";
import { getFileThumbnail } from "#lib/client/cache/index.ts";
import type { SummarizedFileInfo } from "#lib/features/filesystem/index.ts";
import IconFavorite from "~icons/material-symbols/favorite";
@@ -1,9 +1,9 @@
<script lang="ts">
import type { Component } from "svelte";
import type { ClassValue, SvelteHTMLElements } from "svelte/elements";
import { Categories, type SelectedCategory } from "#lib/features/filesystem/components/index.js";
import type { CategoryInfo } from "#lib/features/filesystem/index.js";
import { IconEntryButton } from "#lib/ui/index.js";
import { Categories, type SelectedCategory } from "#lib/features/filesystem/components/index.ts";
import type { CategoryInfo } from "#lib/features/filesystem/index.ts";
import { IconEntryButton } from "#lib/ui/index.ts";
import IconAddCircle from "~icons/material-symbols/add-circle";
+6 -6
View File
@@ -2,16 +2,16 @@ import {
deleteFileCache,
deleteFileThumbnailCache,
storeFileThumbnailCache,
} from "#lib/client/cache/index.js";
} from "#lib/client/cache/index.ts";
import {
getDecryptedFileUrl,
prepareFileDecryption,
saveDecryptedFile,
} from "#lib/client/serviceWorker.js";
import { getAllFileInfos } from "#lib/client/storage/indexedDB/index.js";
import { uploadBlob } from "#lib/client/transfer/chunkedUpload.js";
import { trpc } from "#trpc/client.js";
import type { DataKey } from "./types";
} from "#lib/client/service-worker.ts";
import { getAllFileInfos } from "#lib/client/storage/indexed-db/index.ts";
import { uploadBlob } from "#lib/client/transfer/chunked-upload.ts";
import { trpc } from "#trpc/client.ts";
import type { DataKey } from "./types.ts";
interface StreamableFile {
id: number;
+7 -7
View File
@@ -1,15 +1,15 @@
import { deleteFileCache, deleteFileThumbnailCache } from "#lib/client/cache/index.js";
import * as IndexedDB from "#lib/client/storage/indexedDB/index.js";
import { isTRPCClientError, trpc } from "#trpc/client.js";
import { FilesystemCache } from "./cache.svelte";
import { deleteFileCache, deleteFileThumbnailCache } from "#lib/client/cache/index.ts";
import * as IndexedDB from "#lib/client/storage/indexed-db/index.ts";
import { isTRPCClientError, trpc } from "#trpc/client.ts";
import { FilesystemCache } from "./cache.svelte.ts";
import {
decryptDirectoryMetadata,
decryptFileMetadata,
encryptName,
generateEntryKeys,
} from "./metadata";
import { useResource } from "./resource.svelte";
import type { DataKey, DirectoryInfo, MaybeDirectoryInfo } from "./types";
} from "./metadata.ts";
import { useResource } from "./resource.svelte.ts";
import type { DataKey, DirectoryInfo, MaybeDirectoryInfo } from "./types.ts";
const cache = new FilesystemCache<DirectoryId, MaybeDirectoryInfo>({
async fetchFromIndexedDB(id) {
+8 -8
View File
@@ -1,11 +1,11 @@
import { deleteFileCache, deleteFileThumbnailCache } from "#lib/client/cache/index.js";
import * as IndexedDB from "#lib/client/storage/indexedDB/index.js";
import { isTRPCClientError, trpc } from "#trpc/client.js";
import { FilesystemCache } from "./cache.svelte";
import { invalidateDirectory } from "./directory";
import { decryptCategoryMetadata, decryptFileMetadata, encryptName } from "./metadata";
import { useResource } from "./resource.svelte";
import type { DataKey, FileInfo, MaybeFileInfo } from "./types";
import { deleteFileCache, deleteFileThumbnailCache } from "#lib/client/cache/index.ts";
import * as IndexedDB from "#lib/client/storage/indexed-db/index.ts";
import { isTRPCClientError, trpc } from "#trpc/client.ts";
import { FilesystemCache } from "./cache.svelte.ts";
import { invalidateDirectory } from "./directory.ts";
import { decryptCategoryMetadata, decryptFileMetadata, encryptName } from "./metadata.ts";
import { useResource } from "./resource.svelte.ts";
import type { DataKey, FileInfo, MaybeFileInfo } from "./types.ts";
const cache = new FilesystemCache<number, MaybeFileInfo>({
async fetchFromIndexedDB(id) {
+6 -6
View File
@@ -1,6 +1,6 @@
export * from "./category";
export * from "./content";
export * from "./directory";
export * from "./file";
export * from "./types";
export * from "./upload";
export * from "./category.ts";
export * from "./content.ts";
export * from "./directory.ts";
export * from "./file.ts";
export * from "./types.ts";
export * from "./upload.ts";
+2 -2
View File
@@ -1,11 +1,11 @@
import { keyring } from "#lib/client/keys/index.js";
import { keyring } from "#lib/client/keys/index.ts";
import {
decryptString,
encryptString,
generateDataKey,
unwrapDataKey,
wrapDataKey,
} from "#lib/shared/crypto/index.js";
} from "#lib/shared/crypto/index.ts";
const unwrapEntryDataKey = async (metadata: { mekVersion: number; dek: string }) => {
const { dataKey } = await unwrapDataKey(
+3 -3
View File
@@ -1,6 +1,6 @@
import { storeFileThumbnailCache } from "#lib/client/cache/index.js";
import { uploadFile as doUploadFile } from "#lib/client/transfer/index.js";
import { invalidateDirectory } from "./directory";
import { storeFileThumbnailCache } from "#lib/client/cache/index.ts";
import { uploadFile as doUploadFile } from "#lib/client/transfer/index.ts";
import { invalidateDirectory } from "./directory.ts";
// Uploads the file and caches it with its thumbnail locally. Returns `false` if the upload is canceled.
export const uploadFile = async (
+2 -2
View File
@@ -4,8 +4,8 @@ import {
type FileInfo,
type LocalCategoryInfo,
type LocalDirectoryInfo,
} from "#lib/features/filesystem/index.js";
import { trpc } from "#trpc/client.js";
} from "#lib/features/filesystem/index.ts";
import { trpc } from "#trpc/client.ts";
export interface SearchFilter {
ancestorId: DirectoryId;
+4 -4
View File
@@ -1,7 +1,7 @@
import { ClientRepo, SessionRepo, IntegrityError } from "#lib/server/db/index.js";
import env from "#lib/server/config.js";
import { verifySessionId } from "#lib/server/crypto.js";
import { AppError } from "#lib/server/errors.js";
import { ClientRepo, SessionRepo, IntegrityError } from "#lib/server/db/index.ts";
import env from "#lib/server/config.ts";
import { verifySessionId } from "#lib/server/crypto.ts";
import { AppError } from "#lib/server/errors.ts";
export interface Session {
sessionId: string;
+1 -1
View File
@@ -1,4 +1,4 @@
import { AppError, type ErrorCode } from "#lib/server/errors.js";
import { AppError, type ErrorCode } from "#lib/server/errors.ts";
const errorCodes = {
// Category
+13 -13
View File
@@ -1,14 +1,14 @@
export * as CategoryRepo from "./repositories/category";
export * as ClientRepo from "./repositories/client";
export * as DirectoryRepo from "./repositories/directory";
export * as FileRepo from "./repositories/file";
export * as FileDeletionRepo from "./repositories/fileDeletion";
export * as HskRepo from "./repositories/hsk";
export * as MediaRepo from "./repositories/media";
export * as MekRepo from "./repositories/mek";
export * as SessionRepo from "./repositories/session";
export * as UploadRepo from "./repositories/upload";
export * as UserRepo from "./repositories/user";
export * as CategoryRepo from "./repositories/category.ts";
export * as ClientRepo from "./repositories/client.ts";
export * as DirectoryRepo from "./repositories/directory.ts";
export * as FileRepo from "./repositories/file.ts";
export * as FileDeletionRepo from "./repositories/file-deletion.ts";
export * as HskRepo from "./repositories/hsk.ts";
export * as MediaRepo from "./repositories/media.ts";
export * as MekRepo from "./repositories/mek.ts";
export * as SessionRepo from "./repositories/session.ts";
export * as UploadRepo from "./repositories/upload.ts";
export * as UserRepo from "./repositories/user.ts";
export * from "./error";
export { default as db } from "./kysely";
export * from "./error.ts";
export { default as db } from "./kysely.ts";
+4 -4
View File
@@ -1,9 +1,9 @@
import { Kysely } from "kysely";
import { Migrator } from "kysely/migration";
import env from "#lib/server/config.js";
import { createDialect } from "./dialect";
import migrations from "./migrations";
import type { Database } from "./schema";
import env from "#lib/server/config.ts";
import { createDialect } from "./dialect.ts";
import migrations from "./migrations/index.ts";
import type { Database } from "./schema/index.ts";
const db = new Kysely<Database>({ dialect: createDialect(env.database) });
+6 -6
View File
@@ -1,9 +1,9 @@
import * as Initial1737357000 from "./1737357000-Initial";
import * as AddFileCategory1737422340 from "./1737422340-AddFileCategory";
import * as AddThumbnail1738409340 from "./1738409340-AddThumbnail";
import * as AddChunkedUpload1768062380 from "./1768062380-AddChunkedUpload";
import * as AddFavorites1768643000 from "./1768643000-AddFavorites";
import * as AddFileDeletionQueue1791730000 from "./1791730000-AddFileDeletionQueue";
import * as Initial1737357000 from "./1737357000-Initial.ts";
import * as AddFileCategory1737422340 from "./1737422340-AddFileCategory.ts";
import * as AddThumbnail1738409340 from "./1738409340-AddThumbnail.ts";
import * as AddChunkedUpload1768062380 from "./1768062380-AddChunkedUpload.ts";
import * as AddFavorites1768643000 from "./1768643000-AddFavorites.ts";
import * as AddFileDeletionQueue1791730000 from "./1791730000-AddFileDeletionQueue.ts";
export default {
"1737357000-Initial": Initial1737357000,
+4 -4
View File
@@ -1,8 +1,8 @@
import type { Selectable } from "kysely";
import { IntegrityError } from "../error";
import db from "../kysely";
import type { CategoryTable, Ciphertext } from "../schema";
import { lockActiveMekVersion } from "./mek";
import { IntegrityError } from "../error.ts";
import db from "../kysely.ts";
import type { CategoryTable, Ciphertext } from "../schema/index.ts";
import { lockActiveMekVersion } from "./mek.ts";
export interface Category {
id: number;
+3 -3
View File
@@ -1,7 +1,7 @@
import pg from "pg";
import { IntegrityError } from "../error";
import db from "../kysely";
import type { UserClientState } from "../schema";
import { IntegrityError } from "../error.ts";
import db from "../kysely.ts";
import type { UserClientState } from "../schema/index.ts";
interface Client {
id: number;
+5 -5
View File
@@ -1,9 +1,9 @@
import type { Selectable } from "kysely";
import { IntegrityError } from "../error";
import db from "../kysely";
import type { Ciphertext, DirectoryTable } from "../schema";
import { enqueueFileDeletions } from "./fileDeletion";
import { lockActiveMekVersion } from "./mek";
import { IntegrityError } from "../error.ts";
import db from "../kysely.ts";
import type { Ciphertext, DirectoryTable } from "../schema/index.ts";
import { enqueueFileDeletions } from "./file-deletion.ts";
import { lockActiveMekVersion } from "./mek.ts";
export interface Directory {
id: number;
@@ -1,4 +1,4 @@
import db from "../kysely";
import db from "../kysely.ts";
export const enqueueFileDeletions = async (
trx: typeof db,
+5 -5
View File
@@ -1,11 +1,11 @@
import { sql, type Selectable } from "kysely";
import { jsonArrayFrom } from "kysely/helpers/postgres";
import pg from "pg";
import { IntegrityError } from "../error";
import db from "../kysely";
import type { Ciphertext, FileTable } from "../schema";
import { toCategory } from "./category";
import { enqueueFileDeletions } from "./fileDeletion";
import { IntegrityError } from "../error.ts";
import db from "../kysely.ts";
import type { Ciphertext, FileTable } from "../schema/index.ts";
import { toCategory } from "./category.ts";
import { enqueueFileDeletions } from "./file-deletion.ts";
export interface File {
id: number;
+3 -3
View File
@@ -1,7 +1,7 @@
import pg from "pg";
import { IntegrityError } from "../error";
import db from "../kysely";
import type { HskState } from "../schema";
import { IntegrityError } from "../error.ts";
import db from "../kysely.ts";
import type { HskState } from "../schema/index.ts";
interface Hsk {
userId: number;
+3 -3
View File
@@ -1,7 +1,7 @@
import type { NotNull } from "kysely";
import { IntegrityError } from "../error";
import db from "../kysely";
import { enqueueFileDeletions } from "./fileDeletion";
import { IntegrityError } from "../error.ts";
import db from "../kysely.ts";
import { enqueueFileDeletions } from "./file-deletion.ts";
interface Thumbnail {
id: number;
+3 -3
View File
@@ -1,7 +1,7 @@
import pg from "pg";
import { IntegrityError } from "../error";
import db from "../kysely";
import type { MekState } from "../schema";
import { IntegrityError } from "../error.ts";
import db from "../kysely.ts";
import type { MekState } from "../schema/index.ts";
interface Mek {
userId: number;
+3 -3
View File
@@ -1,7 +1,7 @@
import pg from "pg";
import env from "#lib/server/config.js";
import { IntegrityError } from "../error";
import db from "../kysely";
import env from "#lib/server/config.ts";
import { IntegrityError } from "../error.ts";
import db from "../kysely.ts";
export const createSession = async (
userId: number,
+7 -7
View File
@@ -1,11 +1,11 @@
import { sql, type Selectable } from "kysely";
import { IntegrityError } from "../error";
import db from "../kysely";
import type { Ciphertext, UploadSessionTable } from "../schema";
import { ensureDirectoryExists } from "./directory";
import { enqueueFileDeletions } from "./fileDeletion";
import { lockActiveHskVersion } from "./hsk";
import { lockActiveMekVersion } from "./mek";
import { IntegrityError } from "../error.ts";
import db from "../kysely.ts";
import type { Ciphertext, UploadSessionTable } from "../schema/index.ts";
import { ensureDirectoryExists } from "./directory.ts";
import { enqueueFileDeletions } from "./file-deletion.ts";
import { lockActiveHskVersion } from "./hsk.ts";
import { lockActiveMekVersion } from "./mek.ts";
interface BaseUploadSession {
id: string;
+1 -1
View File
@@ -1,4 +1,4 @@
import db from "../kysely";
import db from "../kysely.ts";
interface User {
id: number;
+1 -1
View File
@@ -1,5 +1,5 @@
import type { Generated } from "kysely";
import type { Ciphertext } from "./utils";
import type { Ciphertext } from "./utils.ts";
export interface CategoryTable {
id: Generated<number>;
+1 -1
View File
@@ -1,5 +1,5 @@
import type { ColumnType, Generated } from "kysely";
import type { Ciphertext } from "./utils";
import type { Ciphertext } from "./utils.ts";
export interface DirectoryTable {
id: Generated<number>;
+1 -1
View File
@@ -1,5 +1,5 @@
import type { ColumnType, Generated } from "kysely";
import type { Ciphertext } from "./utils";
import type { Ciphertext } from "./utils.ts";
export interface FileTable {
id: Generated<number>;
+12 -12
View File
@@ -1,15 +1,15 @@
export * from "./category";
export * from "./client";
export * from "./directory";
export * from "./file";
export * from "./fileDeletion";
export * from "./hsk";
export * from "./media";
export * from "./mek";
export * from "./session";
export * from "./upload";
export * from "./user";
export * from "./utils";
export * from "./category.ts";
export * from "./client.ts";
export * from "./directory.ts";
export * from "./file.ts";
export * from "./file-deletion.ts";
export * from "./hsk.ts";
export * from "./media.ts";
export * from "./mek.ts";
export * from "./session.ts";
export * from "./upload.ts";
export * from "./user.ts";
export * from "./utils.ts";
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface Database {}
+1 -1
View File
@@ -1,5 +1,5 @@
import type { Generated } from "kysely";
import type { Ciphertext } from "./utils";
import type { Ciphertext } from "./utils.ts";
export interface UploadSessionTable {
id: string;
+1 -1
View File
@@ -1,5 +1,5 @@
import { error, type RequestEvent } from "@sveltejs/kit";
import { AppError } from "#lib/server/errors.js";
import { AppError } from "#lib/server/errors.ts";
// Converts `AppError`s thrown by services into HTTP errors
export const handleAppErrors = <Event extends RequestEvent>(
+1 -1
View File
@@ -1,6 +1,6 @@
import { error, redirect } from "@sveltejs/kit";
import type { Handle } from "@sveltejs/kit/hooks";
import { cookieOptions, authenticate, AuthenticationError } from "#lib/server/auth.js";
import { cookieOptions, authenticate, AuthenticationError } from "#lib/server/auth.ts";
export const authenticateMiddleware: Handle = async ({ event, resolve }) => {
try {
+2 -2
View File
@@ -1,2 +1,2 @@
export { default as authenticate } from "./authenticate";
export { default as setAgentInfo } from "./setAgentInfo";
export { default as authenticate } from "./authenticate.ts";
export { default as setAgentInfo } from "./set-agent-info.ts";
+5 -5
View File
@@ -1,9 +1,9 @@
import argon2 from "argon2";
import { ClientRepo, IntegrityError, SessionRepo, UserRepo } from "#lib/server/db/index.js";
import env from "#lib/server/config.js";
import { issueSessionId } from "#lib/server/crypto.js";
import { AppError } from "#lib/server/errors.js";
import { createChallenge, verifyChallengeAnswer } from "./client";
import { ClientRepo, IntegrityError, SessionRepo, UserRepo } from "#lib/server/db/index.ts";
import env from "#lib/server/config.ts";
import { issueSessionId } from "#lib/server/crypto.ts";
import { AppError } from "#lib/server/errors.ts";
import { createChallenge, verifyChallengeAnswer } from "./client.ts";
const MIN_PASSWORD_LENGTH = 8;
+4 -4
View File
@@ -1,7 +1,7 @@
import { CategoryRepo, FileRepo } from "#lib/server/db/index.js";
import type { Ciphertext } from "#lib/server/db/schema/index.js";
import { AppError } from "#lib/server/errors.js";
import { ensureFreshDekVersion } from "./common";
import { CategoryRepo, FileRepo } from "#lib/server/db/index.ts";
import type { Ciphertext } from "#lib/server/db/schema/index.ts";
import { AppError } from "#lib/server/errors.ts";
import { ensureFreshDekVersion } from "./common.ts";
export const getCategory = async (userId: number, categoryId: CategoryId, recurse: boolean) => {
const category =
+4 -4
View File
@@ -1,7 +1,7 @@
import { ClientRepo } from "#lib/server/db/index.js";
import env from "#lib/server/config.js";
import { generateChallenge, verifyPubKey, verifySignature } from "#lib/server/crypto.js";
import { AppError } from "#lib/server/errors.js";
import { ClientRepo } from "#lib/server/db/index.ts";
import env from "#lib/server/config.ts";
import { generateChallenge, verifyPubKey, verifySignature } from "#lib/server/crypto.ts";
import { AppError } from "#lib/server/errors.ts";
const CHALLENGE_LENGTH = 32;
+1 -1
View File
@@ -1,4 +1,4 @@
import { AppError } from "#lib/server/errors.js";
import { AppError } from "#lib/server/errors.ts";
const DEK_VERSION_TOLERANCE = 60 * 1000; // 1 minute
+5 -5
View File
@@ -1,8 +1,8 @@
import { DirectoryRepo, FileRepo } from "#lib/server/db/index.js";
import type { Ciphertext } from "#lib/server/db/schema/index.js";
import { AppError } from "#lib/server/errors.js";
import { ensureFreshDekVersion } from "./common";
import { schedulePendingFileDeletions } from "./fileDeletion";
import { DirectoryRepo, FileRepo } from "#lib/server/db/index.ts";
import type { Ciphertext } from "#lib/server/db/schema/index.ts";
import { AppError } from "#lib/server/errors.ts";
import { ensureFreshDekVersion } from "./common.ts";
import { schedulePendingFileDeletions } from "./file-deletion.ts";
export const getDirectory = async (userId: number, directoryId: DirectoryId) => {
const directory =
@@ -1,5 +1,5 @@
import { FileDeletionRepo } from "#lib/server/db/index.js";
import { deleteFile } from "#lib/server/storage/index.js";
import { FileDeletionRepo } from "#lib/server/db/index.ts";
import { deleteFile } from "#lib/server/storage/index.ts";
const BATCH_SIZE = 100;
+6 -6
View File
@@ -1,9 +1,9 @@
import { FileRepo, MediaRepo } from "#lib/server/db/index.js";
import type { Ciphertext } from "#lib/server/db/schema/index.js";
import { AppError } from "#lib/server/errors.js";
import { createEncContentStream } from "#lib/server/storage/index.js";
import type { RangeRequest } from "#lib/shared/http.js";
import { schedulePendingFileDeletions } from "./fileDeletion";
import { FileRepo, MediaRepo } from "#lib/server/db/index.ts";
import type { Ciphertext } from "#lib/server/db/schema/index.ts";
import { AppError } from "#lib/server/errors.ts";
import { createEncContentStream } from "#lib/server/storage/index.ts";
import type { RangeRequest } from "#lib/shared/http.ts";
import { schedulePendingFileDeletions } from "./file-deletion.ts";
export const getFile = async (userId: number, fileId: number) => {
const file = await FileRepo.getFile(userId, fileId);
+10 -10
View File
@@ -1,10 +1,10 @@
export * as AuthService from "./auth";
export * as CategoryService from "./category";
export * as ClientService from "./client";
export * as DirectoryService from "./directory";
export * as FileService from "./file";
export * as FileDeletionService from "./fileDeletion";
export * as KeyService from "./key";
export * as SearchService from "./search";
export * as UploadService from "./upload";
export * as UserService from "./user";
export * as AuthService from "./auth.ts";
export * as CategoryService from "./category.ts";
export * as ClientService from "./client.ts";
export * as DirectoryService from "./directory.ts";
export * as FileService from "./file.ts";
export * as FileDeletionService from "./file-deletion.ts";
export * as KeyService from "./key.ts";
export * as SearchService from "./search.ts";
export * as UploadService from "./upload.ts";
export * as UserService from "./user.ts";
+3 -3
View File
@@ -1,6 +1,6 @@
import { ClientRepo, HskRepo, MekRepo } from "#lib/server/db/index.js";
import { verifySignature } from "#lib/server/crypto.js";
import { AppError } from "#lib/server/errors.js";
import { ClientRepo, HskRepo, MekRepo } from "#lib/server/db/index.ts";
import { verifySignature } from "#lib/server/crypto.ts";
import { AppError } from "#lib/server/errors.ts";
export const getClientMeks = async (userId: number, clientId: number) => {
return await MekRepo.getAllValidClientMeks(userId, clientId);
+1 -1
View File
@@ -1,4 +1,4 @@
import { DirectoryRepo, FileRepo } from "#lib/server/db/index.js";
import { DirectoryRepo, FileRepo } from "#lib/server/db/index.ts";
export const search = async (
userId: number,
+6 -6
View File
@@ -1,15 +1,15 @@
import type { Readable } from "stream";
import { db, FileRepo, MediaRepo, UploadRepo } from "#lib/server/db/index.js";
import type { Ciphertext } from "#lib/server/db/schema/index.js";
import { AppError } from "#lib/server/errors.js";
import { db, FileRepo, MediaRepo, UploadRepo } from "#lib/server/db/index.ts";
import type { Ciphertext } from "#lib/server/db/schema/index.ts";
import { AppError } from "#lib/server/errors.ts";
import {
deleteFile,
hashFile,
reserveFile,
writeChunkAtOffset,
} from "#lib/server/storage/index.js";
import { ensureFreshDekVersion } from "./common";
import { schedulePendingFileDeletions } from "./fileDeletion";
} from "#lib/server/storage/index.ts";
import { ensureFreshDekVersion } from "./common.ts";
import { schedulePendingFileDeletions } from "./file-deletion.ts";
const UPLOAD_EXPIRES = 24 * 3600 * 1000; // 24 hours
const THUMBNAIL_CHUNKS = 1; // Up to 4 MiB
+2 -2
View File
@@ -1,5 +1,5 @@
import { UserRepo } from "#lib/server/db/index.js";
import { AppError } from "#lib/server/errors.js";
import { UserRepo } from "#lib/server/db/index.ts";
import { AppError } from "#lib/server/errors.ts";
export const getUser = async (userId: number) => {
const user = await UserRepo.getUser(userId);
+2 -2
View File
@@ -1,7 +1,7 @@
import { open } from "fs/promises";
import type { Readable } from "stream";
import { AppError } from "#lib/server/errors.js";
import { ENCRYPTION_OVERHEAD, ENCRYPTED_CHUNK_SIZE } from "#lib/shared/format/index.js";
import { AppError } from "#lib/server/errors.ts";
import { ENCRYPTION_OVERHEAD, ENCRYPTED_CHUNK_SIZE } from "#lib/shared/format/index.ts";
const invalidChunkSize = () => new AppError("BAD_REQUEST", "Invalid chunk size");
+1 -1
View File
@@ -2,7 +2,7 @@ import { createHash, randomUUID } from "crypto";
import { createReadStream } from "fs";
import { mkdir, open, unlink } from "fs/promises";
import { dirname } from "path";
import env from "#lib/server/config.js";
import env from "#lib/server/config.ts";
const roots = {
library: () => env.libraryPath,
+3 -3
View File
@@ -1,3 +1,3 @@
export * from "./chunks";
export * from "./files";
export * from "./streams";
export * from "./chunks.ts";
export * from "./files.ts";
export * from "./streams.ts";
+2 -2
View File
@@ -1,8 +1,8 @@
import { createReadStream } from "fs";
import { stat } from "fs/promises";
import { Readable } from "stream";
import { AppError } from "#lib/server/errors.js";
import { resolveRange, type RangeRequest } from "#lib/shared/http.js";
import { AppError } from "#lib/server/errors.ts";
import { resolveRange, type RangeRequest } from "#lib/shared/http.ts";
export const createEncContentStream = async (
path: string,
+2 -2
View File
@@ -1,11 +1,11 @@
import { AES_GCM_IV_SIZE } from "#lib/shared/format/index.js";
import { AES_GCM_IV_SIZE } from "#lib/shared/format/index.ts";
import {
encodeString,
decodeString,
encodeToBase64,
decodeFromBase64,
concatenateBuffers,
} from "./encoding";
} from "./encoding.ts";
export const generateMasterKey = async () => {
return {
+4 -4
View File
@@ -1,4 +1,4 @@
export * from "./aes";
export * from "./encoding";
export * from "./rsa";
export * from "./sha";
export * from "./aes.ts";
export * from "./encoding.ts";
export * from "./rsa.ts";
export * from "./sha.ts";
+1 -1
View File
@@ -1,4 +1,4 @@
import { encodeString, encodeToBase64, decodeFromBase64 } from "./encoding";
import { encodeString, encodeToBase64, decodeFromBase64 } from "./encoding.ts";
export const generateEncryptionKeyPair = async () => {
const keyPair = await crypto.subtle.generateKey(
+2 -2
View File
@@ -1,2 +1,2 @@
export * from "./chunk";
export * from "./stream";
export * from "./chunk.ts";
export * from "./stream.ts";
+3 -3
View File
@@ -1,6 +1,6 @@
import { decryptChunk } from "#lib/shared/crypto/index.js";
import type { ByteRange } from "#lib/shared/http.js";
import { CHUNK_SIZE, ENCRYPTED_CHUNK_SIZE } from "./chunk";
import { decryptChunk } from "#lib/shared/crypto/index.ts";
import type { ByteRange } from "#lib/shared/http.ts";
import { CHUNK_SIZE, ENCRYPTED_CHUNK_SIZE } from "./chunk.ts";
// Accumulates stream pieces and takes them out in fixed sizes without copying them repeatedly
const createByteQueue = () => {
@@ -1,4 +1,4 @@
export const DECRYPTED_FILE_URL_PREFIX = "/_internal/decryptedFile/";
export const DECRYPTED_FILE_URL_PREFIX = "/_internal/decrypted-file/";
export interface FileMetadata {
isLegacy: boolean;
+1 -1
View File
@@ -1,7 +1,7 @@
<script lang="ts">
import type { Component } from "svelte";
import type { ClassValue, SvelteHTMLElements } from "svelte/elements";
import { AdaptiveDiv } from "#lib/ui/index.js";
import { AdaptiveDiv } from "#lib/ui/index.ts";
interface Props {
class: ClassValue;
+1 -1
View File
@@ -1,7 +1,7 @@
<script lang="ts">
import type { Component, Snippet } from "svelte";
import type { ClassValue, SvelteHTMLElements } from "svelte/elements";
import { EntryButton, IconLabel } from "#lib/ui/index.js";
import { EntryButton, IconLabel } from "#lib/ui/index.ts";
interface Props {
children: Snippet;
+2 -2
View File
@@ -20,9 +20,9 @@ export * from "./overlays/ActionModal.svelte";
export { default as ActionModal } from "./overlays/ActionModal.svelte";
export { default as BottomSheet } from "./overlays/BottomSheet.svelte";
export { default as Modal } from "./overlays/Modal.svelte";
export * from "./overlays/overlayGroup.svelte";
export * from "./overlays/overlay-group.svelte.ts";
export { default as RenameModal } from "./overlays/RenameModal.svelte";
export { default as TextInputModal } from "./overlays/TextInputModal.svelte";
export * from "./overlays/toast.svelte";
export * from "./overlays/toast.svelte.ts";
export { default as Toasts } from "./overlays/Toasts.svelte";
export { default as RowVirtualizer } from "./RowVirtualizer.svelte";
+1 -1
View File
@@ -1,6 +1,6 @@
<script lang="ts">
import type { ClassValue } from "svelte/elements";
import { IconLabel } from "#lib/ui/index.js";
import { IconLabel } from "#lib/ui/index.ts";
import IconCategory from "~icons/material-symbols/category";
+1 -1
View File
@@ -1,6 +1,6 @@
<script lang="ts">
import type { ClassValue } from "svelte/elements";
import { IconLabel } from "#lib/ui/index.js";
import { IconLabel } from "#lib/ui/index.ts";
import IconFolder from "~icons/material-symbols/folder";
import IconDriveFolderUpload from "~icons/material-symbols/drive-folder-upload";
+1 -1
View File
@@ -1,7 +1,7 @@
<script lang="ts">
import type { Component, Snippet } from "svelte";
import type { ClassValue, SvelteHTMLElements } from "svelte/elements";
import { TitleLabel } from "#lib/ui/index.js";
import { TitleLabel } from "#lib/ui/index.ts";
interface Props {
children?: Snippet;
+1 -1
View File
@@ -4,7 +4,7 @@
<script lang="ts">
import type { Snippet } from "svelte";
import { Button, Modal } from "#lib/ui/index.js";
import { Button, Modal } from "#lib/ui/index.ts";
interface Props {
cancelText?: string;
+1 -1
View File
@@ -2,7 +2,7 @@
import type { Snippet } from "svelte";
import type { ClassValue } from "svelte/elements";
import { fade, fly } from "svelte/transition";
import { AdaptiveDiv } from "#lib/ui/index.js";
import { AdaptiveDiv } from "#lib/ui/index.ts";
interface Props {
children: Snippet;
+1 -1
View File
@@ -2,7 +2,7 @@
import type { Snippet } from "svelte";
import type { ClassValue } from "svelte/elements";
import { fade } from "svelte/transition";
import { AdaptiveDiv } from "#lib/ui/index.js";
import { AdaptiveDiv } from "#lib/ui/index.ts";
interface Props {
children: Snippet;
+1 -1
View File
@@ -1,5 +1,5 @@
<script lang="ts">
import { TextInputModal } from "#lib/ui/index.js";
import { TextInputModal } from "#lib/ui/index.ts";
interface Props {
isOpen: boolean;
+1 -1
View File
@@ -1,5 +1,5 @@
<script lang="ts">
import { TextInput, ActionModal, type ConfirmHandler } from "#lib/ui/index.js";
import { TextInput, ActionModal, type ConfirmHandler } from "#lib/ui/index.ts";
interface Props {
defaultValue?: string;
+1 -1
View File
@@ -1,6 +1,6 @@
<script lang="ts">
import { fly } from "svelte/transition";
import { getToasts } from "./toast.svelte";
import { getToasts } from "./toast.svelte.ts";
</script>
<div class="pointer-events-none fixed inset-x-0 top-4 z-50 flex flex-col items-center gap-y-2 px-4">
Loaded 100 of 201 files, more files were not shown because too many files have changed in this diff. Show more