diff --git a/e2e/community-feed.spec.ts b/e2e/community-feed.spec.ts index e1cbf79862..dcba37ec85 100644 --- a/e2e/community-feed.spec.ts +++ b/e2e/community-feed.spec.ts @@ -12,7 +12,7 @@ test("load community posts", async ({ page }) => { await expect(page).toHaveTitle("Voyager for Lemmy"); - await expect(page.getByText(posts[0].post.name)).toBeVisible(); + await expect(page.getByText(posts[0]!.post.name)).toBeVisible(); }); test("navigate to post on click", async ({ page }) => { @@ -22,7 +22,7 @@ test("navigate to post on click", async ({ page }) => { await page.goto("/"); - await page.getByText(posts[0].post.name).click(); + await page.getByText(posts[0]!.post.name).click(); await expect(page).toHaveURL( "/posts/lemmy.world/c/community_1@test.lemmy/comments/999", diff --git a/eslint.config.js b/eslint.config.js index d39577eb99..b31c206bd8 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -10,6 +10,7 @@ import vitestPlugin from "eslint-plugin-vitest"; import tseslint from "typescript-eslint"; import compilerOptions from "./compilerOptions.js"; +import packageJson from "./package.json" with { type: "json" }; export default tseslint.config( eslint.configs.recommended, @@ -119,7 +120,9 @@ export default tseslint.config( newlinesBetween: "always", ignoreCase: false, type: "natural", - internalPattern: ["#/**"], + internalPattern: Object.keys(packageJson.imports).map((i) => + i.endsWith("*") ? `${i}*` : i, + ), sortSideEffects: true, groups: [ "builtin", diff --git a/package.json b/package.json index 577ddeb26d..e4dd30e2f9 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,9 @@ "upgrade:react": "pnpm i --save react@experimental react-dom@experimental babel-plugin-react-compiler@experimental eslint-plugin-react-compiler@experimental eslint-plugin-react-hooks@experimental", "release": "./scripts/release.sh" }, + "imports": { + "#/*": "./src/*" + }, "pnpm": { "overrides": { "@ionic/core": "npm:voyager-ionic-core@8.4.0" diff --git a/src/features/media/gallery/GalleryProvider.tsx b/src/features/media/gallery/GalleryProvider.tsx index b54792d04e..0b53fd4a6e 100644 --- a/src/features/media/gallery/GalleryProvider.tsx +++ b/src/features/media/gallery/GalleryProvider.tsx @@ -1,8 +1,7 @@ import { StatusBar } from "@capacitor/status-bar"; import { compact, noop } from "es-toolkit"; import { PostView } from "lemmy-js-client"; -import type { PreparedPhotoSwipeOptions } from "photoswipe"; -import type ZoomLevel from "photoswipe/dist/types/slide/zoom-level"; +import type { PreparedPhotoSwipeOptions, ZoomLevelOption } from "photoswipe"; import PhotoSwipeLightbox from "photoswipe/lightbox"; import "photoswipe/style.css"; import React, { @@ -40,7 +39,7 @@ interface IGalleryContext { } export const GalleryContext = createContext({ - // eslint-disable-next-line no-empty-function -- https://github.com/toss/es-toolkit/issues/636 + // eslint-disable-next-line no-empty-function open: async () => {}, close: noop, }); @@ -159,7 +158,11 @@ export default function GalleryProvider({ children }: React.PropsWithChildren) { }, }); - let zoomLevel: ZoomLevel; + // ZoomLevel is not directly exported from photoswipe + let zoomLevel: Parameters< + Extract unknown> + >[0]; + let currZoomLevel = 0; instance.on("zoomLevelsUpdate", (e) => { diff --git a/src/features/shared/markdown/components/spoiler/spoilerSlice.ts b/src/features/shared/markdown/components/spoiler/spoilerSlice.ts index 2b2dc4b432..2572d51666 100644 --- a/src/features/shared/markdown/components/spoiler/spoilerSlice.ts +++ b/src/features/shared/markdown/components/spoiler/spoilerSlice.ts @@ -1,5 +1,5 @@ import { PayloadAction, createSlice } from "@reduxjs/toolkit"; -import type { Element } from "react-markdown/lib"; +import type { ExtraProps } from "react-markdown"; interface NetworkState { byId: Record; @@ -33,7 +33,7 @@ export default spoilerSlice.reducer; export function getSpoilerId( markdownItemId: string, - node: Element | undefined, + node: NonNullable | undefined, ) { return `${markdownItemId}__${node?.position?.start.offset ?? 0}`; } diff --git a/src/services/db.ts b/src/services/db.ts index 3860d4aebf..8419dac939 100644 --- a/src/services/db.ts +++ b/src/services/db.ts @@ -9,9 +9,9 @@ import { PostSortType, } from "lemmy-js-client"; -import { COMMENT_SORTS } from "#/features/comment/CommentSort"; -import { ALL_POST_SORTS } from "#/features/feed/PostSort"; -import { arrayOfAll } from "#/helpers/array"; +import { COMMENT_SORTS } from "#/features/comment/CommentSort.js"; +import { ALL_POST_SORTS } from "#/features/feed/PostSort.js"; +import { arrayOfAll } from "#/helpers/array.js"; export interface IPostMetadata { post_id: number; diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index df90938216..eddd8b10a3 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -1,5 +1,6 @@ /// /// +/// /** * Version from package.json diff --git a/tsconfig.json b/tsconfig.json index d2f8918db3..9231d7b54d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,25 +1,28 @@ { "compilerOptions": { - "target": "ESNext", - "useDefineForClassFields": true, - "lib": ["DOM", "DOM.Iterable", "ESNext"], - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": false, - "allowSyntheticDefaultImports": true, + "target": "esnext", + + "module": "esnext", + "moduleResolution": "bundler", + "strict": true, - "forceConsistentCasingInFileNames": true, - "module": "ESNext", - "moduleResolution": "Node", - "resolveJsonModule": true, - "isolatedModules": true, "noEmit": true, - "jsx": "react-jsx", - "types": ["vite-plugin-svgr/client"], + "skipLibCheck": true, + "isolatedModules": true, + "allowJs": false, + + "forceConsistentCasingInFileNames": true, + "useDefineForClassFields": true, "noUncheckedIndexedAccess": true, + + "jsx": "react-jsx", + "paths": { + // duplicate of package.json[imports] + // typescript doesn't support this same syntax in package.json with + // module resolution set to bundler, despite it working fine in esbuild/vite... + // https://github.com/microsoft/TypeScript/issues/55337 (╯°□°)╯︵ ┻━┻ "#/*": ["./src/*"] } - }, - "include": ["src"] + } } diff --git a/vite.config.ts b/vite.config.ts index 8fcbe5e4ef..1fc0fd6d17 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,12 +1,14 @@ import legacy from "@vitejs/plugin-legacy"; import react from "@vitejs/plugin-react"; import wyw from "@wyw-in-js/vite"; +import { omitBy } from "es-toolkit"; import { ManifestOptions, VitePWA } from "vite-plugin-pwa"; import svgr from "vite-plugin-svgr"; -import tsconfigPaths from "vite-tsconfig-paths"; import { defineConfig } from "vitest/config"; -import compilerOptions from "./compilerOptions"; +// @ts-expect-error -- Waiting for stable typescript eslint config +// https://eslint.org/docs/latest/use/configure/configuration-files#typescript-configuration-files +import compilerOptions from "./compilerOptions.js"; import manifest from "./manifest.json"; const IGNORED_ROLLUP_WARNINGS = [ @@ -21,7 +23,6 @@ const IGNORED_ROLLUP_WARNINGS = [ // https://vitejs.dev/config/ export default defineConfig({ plugins: [ - tsconfigPaths(), react({ babel: { plugins: [["babel-plugin-react-compiler", compilerOptions]], @@ -87,12 +88,16 @@ export default defineConfig({ }, }, }, - define: { - APP_VERSION: JSON.stringify(process.env.npm_package_version), - APP_BUILD: process.env.APP_BUILD && JSON.stringify(process.env.APP_BUILD), - APP_GIT_REF: JSON.stringify(process.env.APP_GIT_REF), - BUILD_FOSS_ONLY: !!process.env.BUILD_FOSS_ONLY, - }, + // vite panics on empty strings + define: omitBy( + { + APP_VERSION: JSON.stringify(process.env.npm_package_version), + APP_BUILD: process.env.APP_BUILD && JSON.stringify(process.env.APP_BUILD), + APP_GIT_REF: JSON.stringify(process.env.APP_GIT_REF), + BUILD_FOSS_ONLY: !!process.env.BUILD_FOSS_ONLY, + }, + (v) => !v, + ), test: { exclude: ["**/e2e/**", "**/node_modules/**"], globals: true,