chore: clear the mechanical lint and type findings

Dead imports and locals removed, each blocks keyed, `any` narrowed to unknown.
Two context setters kept their calls and lost only the unused binding; the
settings redirect no longer awaits a parent whose data it discards. A leading
underscore now marks a binding that only holds a position.
This commit is contained in:
2026-08-17 17:55:21 -04:00
parent 428168c07a
commit 3a29294f96
36 changed files with 76 additions and 91 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ import { BACKEND_API_URL } from '$lib/server/config';
import { invalid, redirect } from '@sveltejs/kit';
export const login = form(loginSchema, async (data, issue) => {
const { cookies, locals } = getRequestEvent();
const { cookies } = getRequestEvent();
// Create URL-encoded form data
const formData = new URLSearchParams();
+1 -1
View File
@@ -25,6 +25,6 @@ export const createLibrary = form(libraryCreateSchema, async (data) => {
return await response.json();
});
export const deleteLibrary = query('unchecked', async (data) => {
export const deleteLibrary = query('unchecked', async (_data) => {
throw new Error('Not implemented');
});
@@ -3,8 +3,6 @@
import { Checkbox } from '$lib/components/ui/checkbox/index.js';
import { Button } from '$lib/components/ui/button/index.js';
import * as Dialog from '$lib/components/ui/dialog/index.js';
import { getBookSelectionState } from '$lib/state/bookSelection.svelte';
import { getBookOperationsState } from '$lib/state/bookOperations.svelte';
let {
open = $bindable(),
@@ -16,9 +14,6 @@
deleteFn: (deleteFiles: boolean) => void | Promise<void>;
} = $props();
const selectedState = getBookSelectionState();
const bookOps = getBookOperationsState();
let deleteFiles = $state(false);
</script>
@@ -39,7 +39,7 @@
<Field.Field>
<Field.Label for="name">Device name</Field.Label>
<Input {...createDevice.fields.name.as('text')} placeholder="e.g. Kindle Paperwhite" />
{#each createDevice.fields.name.issues() ?? [] as issue}
{#each createDevice.fields.name.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -128,7 +128,7 @@
<Field.Field class="col-span-full">
<Field.Label for="title">Title</Field.Label>
<Input {...updateBookMetadata.fields.title.as('text')} />
{#each updateBookMetadata.fields.title.issues() ?? [] as issue}
{#each updateBookMetadata.fields.title.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -136,7 +136,7 @@
<Field.Field>
<Field.Label for="subtitle">Subtitle</Field.Label>
<Input {...updateBookMetadata.fields.subtitle.as('text')} />
{#each updateBookMetadata.fields.subtitle.issues() ?? [] as issue}
{#each updateBookMetadata.fields.subtitle.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -144,7 +144,7 @@
<Field.Field>
<Field.Label for="edition">Edition</Field.Label>
<Input {...updateBookMetadata.fields.edition.as('number')} />
{#each updateBookMetadata.fields.edition.issues() ?? [] as issue}
{#each updateBookMetadata.fields.edition.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -152,7 +152,7 @@
<Field.Field>
<Field.Label for="series">Series</Field.Label>
<Input {...updateBookMetadata.fields.series.as('text')} />
{#each updateBookMetadata.fields.series.issues() ?? [] as issue}
{#each updateBookMetadata.fields.series.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -161,7 +161,7 @@
<Field.Field>
<Field.Label for="series_position">No.</Field.Label>
<Input {...updateBookMetadata.fields.series_position.as('text')} />
{#each updateBookMetadata.fields.series_position.issues() ?? [] as issue}
{#each updateBookMetadata.fields.series_position.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -169,7 +169,7 @@
<Field.Field>
<Field.Label for="language">Language</Field.Label>
<Input {...updateBookMetadata.fields.language.as('text')} />
{#each updateBookMetadata.fields.language.issues() ?? [] as issue}
{#each updateBookMetadata.fields.language.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -185,10 +185,10 @@
placeholder="Add an author"
class="min-h-10 p-2 text-sm"
/>
{#each authors as author}
{#each authors as author, i (i)}
<input class="hidden" {...updateBookMetadata.fields.authors.as('checkbox', author)} />
{/each}
{#each updateBookMetadata.fields.authors.issues() ?? [] as issue}
{#each updateBookMetadata.fields.authors.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -201,10 +201,10 @@
placeholder="Add a tag"
class="min-h-10 p-2 text-sm"
/>
{#each tags as tag}
{#each tags as tag, i (i)}
<input class="hidden" {...updateBookMetadata.fields.tags.as('checkbox', tag)} />
{/each}
{#each updateBookMetadata.fields.tags.issues() ?? [] as issue}
{#each updateBookMetadata.fields.tags.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -214,7 +214,7 @@
<Field.Field>
<Field.Label for="publisher">Publisher</Field.Label>
<Input {...updateBookMetadata.fields.publisher.as('text')} />
{#each updateBookMetadata.fields.publisher.issues() ?? [] as issue}
{#each updateBookMetadata.fields.publisher.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -223,7 +223,7 @@
<Field.Field>
<Field.Label for="published_date">Published</Field.Label>
<Input {...updateBookMetadata.fields.published_date.as('date')} />
{#each updateBookMetadata.fields.published_date.issues() ?? [] as issue}
{#each updateBookMetadata.fields.published_date.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -231,7 +231,7 @@
<Field.Field>
<Field.Label for="pages">Pages</Field.Label>
<Input {...updateBookMetadata.fields.pages.as('number')} />
{#each updateBookMetadata.fields.pages.issues() ?? [] as issue}
{#each updateBookMetadata.fields.pages.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -240,7 +240,7 @@
<Field.Field class="col-span-full">
<Field.Label for="identifiers">Identifiers</Field.Label>
<div class="flex flex-col gap-2">
{#each identifierKeys as _, idx}
{#each identifierKeys as _, idx (idx)}
<div class="grid grid-cols-[1fr_1.6fr_auto] gap-2">
<Input bind:value={identifierKeys[idx]} placeholder="ISBN, DOI…" />
<Input bind:value={identifierValues[idx]} placeholder="Value" />
@@ -271,7 +271,7 @@
<Field.Field class="col-span-full">
<Field.Label for="description" class="sr-only">Description</Field.Label>
<Textarea {...updateBookMetadata.fields.description.as('text')} rows={6} />
{#each updateBookMetadata.fields.description.issues() ?? [] as issue}
{#each updateBookMetadata.fields.description.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -56,7 +56,7 @@
<Field.Field>
<Field.Label for="name">Library name</Field.Label>
<Input {...createLibrary.fields.name.as('text')} />
{#each createLibrary.fields.name.issues() ?? [] as issue}
{#each createLibrary.fields.name.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -73,7 +73,7 @@
<Field.Field>
<Field.Label for="description">Description</Field.Label>
<Textarea {...createLibrary.fields.description.as('text')} />
{#each createLibrary.fields.description.issues() ?? [] as issue}
{#each createLibrary.fields.description.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -82,7 +82,7 @@
<Field.Field>
<Field.Label for="root_path">Root Path</Field.Label>
<Input {...createLibrary.fields.root_path.as('text')} />
{#each createLibrary.fields.root_path.issues() ?? [] as issue}
{#each createLibrary.fields.root_path.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
<Field.Description class="text-xs">
@@ -94,7 +94,7 @@
<Field.Field>
<Field.Label for="path_template">Path Template</Field.Label>
<Input {...createLibrary.fields.path_template.as('text')} />
{#each createLibrary.fields.path_template.issues() ?? [] as issue}
{#each createLibrary.fields.path_template.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
<Field.Description class="text-xs">
@@ -21,7 +21,7 @@
<Field.Field>
<Field.Label for="email">Email</Field.Label>
<Input {...login.fields.email.as('email')} />
{#each login.fields.email.issues() ?? [] as issue}
{#each login.fields.email.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -30,7 +30,7 @@
<Field.Field>
<Field.Label for="password">Password</Field.Label>
<Input {...login.fields.password.as('password')} />
{#each login.fields.password.issues() ?? [] as issue}
{#each login.fields.password.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -47,7 +47,7 @@
<Field.Field>
<Field.Label for="email">Email</Field.Label>
<Input {...signup.fields.email.as('email')} />
{#each signup.fields.email.issues() ?? [] as issue}
{#each signup.fields.email.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -56,7 +56,7 @@
<Field.Field>
<Field.Label for="password">Password</Field.Label>
<Input {...signup.fields.password.as('password')} />
{#each signup.fields.password.issues() ?? [] as issue}
{#each signup.fields.password.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -65,7 +65,7 @@
<Field.Field>
<Field.Label for="confirmPassword">Confirm Password</Field.Label>
<Input {...signup.fields.confirmPassword.as('password')} />
{#each signup.fields.confirmPassword.issues() ?? [] as issue}
{#each signup.fields.confirmPassword.issues() ?? [] as issue, i (i)}
<Field.Error>{issue.message}</Field.Error>
{/each}
</Field.Field>
@@ -3,7 +3,7 @@
import * as Sidebar from '$lib/components/ui/sidebar/index.js';
import { useSidebar } from '$lib/components/ui/sidebar/index.js';
import { Badge } from '$lib/components/ui/badge/index.js';
import { getLibraryState, LibraryState } from '$lib/state/library.svelte';
import { getLibraryState } from '$lib/state/library.svelte';
import { LIBRARY_ICONS } from '$lib/components/ui/icon-picker/index.js';
import ChevronsUpDownIcon from '@lucide/svelte/icons/chevrons-up-down';
import PlusIcon from '@lucide/svelte/icons/plus';
@@ -53,9 +53,9 @@
}
}
function handleClick(e: any) {
function handleClick(e: Event & { currentTarget: HTMLElement }) {
open = true;
e.target.blur();
e.currentTarget.blur();
}
</script>
@@ -93,7 +93,7 @@
</div>
{:else}
<Command.List class="max-h-[600px]">
{#if searchResult?.items.length > 0}
{#if (searchResult?.items?.length ?? 0) > 0}
<Command.Group heading="Books">
{#each searchResult?.items as book (book.id)}
<Command.Item
@@ -121,7 +121,7 @@
{#if book.authors.length > 0}
<span class="line-clamp-1 w-full text-sm text-muted-foreground">
by
{#each book.authors as author}
{#each book.authors as author (author.id)}
<a
href="{resolve('/(root)/(library)/library/[libraryId]/view', {
libraryId: String(libraryState.activeLibrary!.id)
@@ -132,7 +132,7 @@
</span>
{/if}
<div class="mt-1 ml-[-1.5] flex">
{#each book.tags as tag}
{#each book.tags as tag (tag.id)}
<Badge class="scale-75">{tag.name}</Badge>
{/each}
</div>
@@ -4,7 +4,6 @@
import type { Book } from '$lib/schema';
import BookThumbnail from './book-thumbnail.svelte';
import { goto } from '$app/navigation';
import { getBookSelectionState } from '$lib/state/bookSelection.svelte';
import { getBookOperationsState } from '$lib/state/bookOperations.svelte';
import { getLibraryState } from '$lib/state/library.svelte';
@@ -1,8 +1,10 @@
<script>
let { src, fallback = '/images/default_cover.jpg', class: className = '' } = $props();
async function handleError(e) {
e.target.src = fallback;
/** @param {Event} e */
function handleError(e) {
const img = /** @type {HTMLImageElement} */ (e.currentTarget);
img.src = fallback;
}
</script>
@@ -2,7 +2,6 @@
import { resolve } from '$app/paths';
import * as Table from '$lib/components/ui/table/index';
import * as DropdownMenu from '$lib/components/ui/dropdown-menu/index';
import * as Tooltip from '$lib/components/ui/tooltip/index';
import { Checkbox } from '$lib/components/ui/checkbox/index';
import { Badge } from '$lib/components/ui/badge/index';
import { buttonVariants } from '$lib/components/ui/button/index.js';
@@ -2,12 +2,11 @@
import { resolve } from '$app/paths';
import BookImage from './book-image.svelte';
import GeneratedCover from './generated-cover.svelte';
import { Progress } from '$lib/components/ui/progress/index';
import { getLibraryState } from '$lib/state/library.svelte';
import { getBookSelectionState } from '$lib/state/bookSelection.svelte';
import type { Book } from '$lib/schema';
let { book, class: className = '', ...rest }: { book: Book; class?: string } = $props();
let { book, class: className = '' }: { book: Book; class?: string } = $props();
const selectionState = getBookSelectionState();
const libraryState = getLibraryState();
@@ -78,7 +77,7 @@
<!-- Authors list -->
<p class="line-clamp-1 w-full text-xs text-muted-foreground">
{#each book.authors as author}
{#each book.authors as author (author.id)}
<a
href="{resolve('/(root)/(library)/library/[libraryId]/view', {
libraryId: String(libraryState.activeLibrary?.id ?? '')
@@ -30,7 +30,7 @@
<Collapsible.Content class="h-full max-h-128 overflow-y-auto">
<Sidebar.GroupContent>
<Sidebar.Menu>
{#each filter.items as item, index (item.id)}
{#each filter.items as item (item.id)}
<Sidebar.MenuItem
onclick={() => bookCollection.toggleFilter(filter.value, item.id.toString())}
>
@@ -25,7 +25,7 @@
</DropdownMenu.Trigger>
<DropdownMenu.Content class="w-40">
<DropdownMenu.Group>
{#each bookCollection.sortOptions as sortProp}
{#each bookCollection.sortOptions as sortProp (sortProp.value)}
<DropdownMenu.Item
onSelect={() => bookCollection.updateSort(sortProp.value)}
class={bookCollection.orderBy === sortProp.value ? 'bg-muted' : ''}
-2
View File
@@ -4,8 +4,6 @@ const emailSchema = z
.email('Please enter a valid email address')
.max(255, 'Email address cannot exceed 255 characters');
const usernameSchema = z.string().min(1, 'Email is required');
const basePasswordSchema = z.string().min(1, 'Password is required');
const strongPasswordSchema = z.string().min(8, 'Password must be at least 8 characters');
+1 -3
View File
@@ -1,7 +1,5 @@
import { z } from 'zod';
import type { components } from './openapi/schema';
import { commonQuerySchema, stringArrayCoerce, stringCoerce } from './common';
import { commonQuerySchema, stringArrayCoerce } from './common';
export type Author = components['schemas']['AuthorRead'];
+1 -1
View File
@@ -67,7 +67,7 @@ const identifiersSchema = z
.transform((str, ctx) => {
try {
return JSON.parse(str);
} catch (e) {
} catch {
ctx.addIssue({
code: 'custom',
message: 'Must be a valid JSON string'
-2
View File
@@ -1,5 +1,3 @@
import { z } from 'zod';
import type { components } from './openapi/schema';
import { commonQuerySchema, stringArrayCoerce } from './common';
-2
View File
@@ -1,5 +1,3 @@
import { z } from 'zod';
import type { components } from './openapi/schema';
import { commonQuerySchema, stringArrayCoerce } from './common';
+3 -3
View File
@@ -21,7 +21,7 @@ export class ApiClient {
return this.request(endpoint);
}
async post(endpoint: string, data: any): Promise<Response> {
async post(endpoint: string, data: unknown): Promise<Response> {
return this.request(endpoint, {
method: 'POST',
headers: {
@@ -48,7 +48,7 @@ export class ApiClient {
});
}
async put(endpoint: string, data: any): Promise<Response> {
async put(endpoint: string, data: unknown): Promise<Response> {
return this.request(endpoint, {
method: 'PUT',
headers: {
@@ -71,7 +71,7 @@ export class ApiClient {
});
}
async patch(endpoint: string, data: any): Promise<Response> {
async patch(endpoint: string, data: unknown): Promise<Response> {
return this.request(endpoint, {
method: 'PATCH',
headers: {
@@ -1,5 +1,5 @@
import { getContext, setContext } from 'svelte';
import { goto, pushState, replaceState } from '$app/navigation';
import { goto, replaceState } from '$app/navigation';
import type { Book, DynamicFilterData, FilterOption, PaginatedResponse } from '$lib/schema';
import { page } from '$app/state';
import { BookOperationsState } from './bookOperations.svelte';
@@ -16,7 +16,7 @@ export class BookOperationsState {
// Delete dialog related state
deleteDialogOpen = $state(false);
deleteDialogTitle = $state('Delete books?');
deleteFn = $state((deleteFiles: boolean) => {});
deleteFn = $state((_deleteFiles: boolean) => {});
// Edit dialog related state
editDialogOpen = $state(false);
+4 -4
View File
@@ -1,4 +1,4 @@
import { goto, invalidate } from '$app/navigation';
import { invalidate } from '$app/navigation';
import { addBooksToShelf, createBookshelf, listBookshelves, removeBooksFromShelf } from '$lib/api';
import type { Book, Bookshelf } from '$lib/schema';
import { getContext, setContext } from 'svelte';
@@ -22,7 +22,7 @@ export class BookshelfState {
async fetchBookshelves(libraryId: string) {
try {
let paginatedBookshelves = await listBookshelves({
const paginatedBookshelves = await listBookshelves({
libraries: [libraryId]
});
@@ -34,7 +34,7 @@ export class BookshelfState {
async addBookshelf(name: string, libraryId?: string | number, booksToAdd?: string[] | number[]) {
try {
let bookshelf = await createBookshelf({
const bookshelf = await createBookshelf({
title: name,
library_id: libraryId,
book_ids: booksToAdd
@@ -133,7 +133,7 @@ export class BookshelfState {
decrementBy++;
}
});
return { ...shelf, total: shelf.total - decrementBy };
return { ...shelf, total: (shelf.total ?? 0) - decrementBy };
}
return shelf;
});
+1 -1
View File
@@ -1,6 +1,6 @@
import { resolve } from '$app/paths';
import { browser } from '$app/environment';
import { goto, invalidate } from '$app/navigation';
import { goto } from '$app/navigation';
import { page } from '$app/state';
import { deleteLibrary } from '$lib/api';
import type { Library } from '$lib/schema';