diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..b93d4b6 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,7 @@ +node_modules +dist +.yarn +.devcontainer +.github +.next +.vscode \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 4972523..762a7a9 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,5 +1,13 @@ { - "extends": ["next", "next/core-web-vitals", "plugin:prettier/recommended"], + "root": true, + "extends": [ + "next", + "next/core-web-vitals", + "plugin:prettier/recommended", + "plugin:@typescript-eslint/recommended" + ], + "plugins": ["unused-imports", "@typescript-eslint"], + "parser": "@typescript-eslint/parser", "rules": { "linebreak-style": ["error", "unix"], "quotes": [ @@ -28,6 +36,14 @@ "react/style-prop-object": "warn", "@next/next/no-img-element": "off", "jsx-a11y/alt-text": "off", - "react/display-name": "off" + "react/display-name": "off", + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "off", + "unused-imports/no-unused-imports": "error", + "unused-imports/no-unused-vars": [ + "error", + { "vars": "all", "varsIgnorePattern": "^_", "args": "after-used", "argsIgnorePattern": "^_" } + ], + "@typescript-eslint/ban-ts-comment": "off" } } diff --git a/package.json b/package.json index 819c08c..5da7df6 100644 --- a/package.json +++ b/package.json @@ -81,15 +81,18 @@ "@types/qrcode": "^1.5.0", "@types/react": "^18.0.28", "@types/sharp": "^0.31.1", + "@typescript-eslint/eslint-plugin": "^5.56.0", + "@typescript-eslint/parser": "^5.56.0", "cross-env": "^7.0.3", - "eslint": "^8.35.0", + "eslint": "^8.36.0", "eslint-config-next": "^13.2.1", "eslint-config-prettier": "^8.6.0", "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-unused-imports": "^2.0.0", "npm-run-all": "^4.1.5", "prettier": "^2.8.4", "tsup": "^6.6.3", - "typescript": "^4.9.5" + "typescript": "^5.0.2" }, "repository": { "type": "git", diff --git a/src/components/File/FileModal.tsx b/src/components/File/FileModal.tsx index 738ef15..2f2ff98 100644 --- a/src/components/File/FileModal.tsx +++ b/src/components/File/FileModal.tsx @@ -22,7 +22,6 @@ import { IconFile, IconFileDownload, IconFolderMinus, - IconFolderOff, IconFolderPlus, IconFolderX, IconHash, @@ -31,10 +30,9 @@ import { IconPhotoCancel, IconPhotoMinus, IconPhotoStar, - IconStarFilled, } from '@tabler/icons-react'; -import useFetch from 'hooks/useFetch'; -import { useFileDelete, useFileFavorite } from 'lib/queries/files'; +import useFetch, { ApiError } from 'hooks/useFetch'; +import { useFileDelete, useFileFavorite, UserFilesResponse } from 'lib/queries/files'; import { useFolders } from 'lib/queries/folders'; import { bytesToHuman } from 'lib/utils/bytes'; import { relativeTime } from 'lib/utils/client'; @@ -54,7 +52,7 @@ export default function FileModal({ }: { open: boolean; setOpen: (open: boolean) => void; - file: any; + file: UserFilesResponse; loading: boolean; refresh: () => void; reducedActions?: boolean; @@ -79,7 +77,7 @@ export default function FileModal({ }); }, - onError: (res: any) => { + onError: (res: ApiError) => { showNotification({ title: 'Failed to delete file', message: res.error, @@ -123,7 +121,7 @@ export default function FileModal({ }); }, - onError: (res: any) => { + onError: (res: { error: string }) => { showNotification({ title: 'Failed to favorite file', message: res.error, diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index f2ca434..175ab54 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -48,6 +48,7 @@ import useFetch from 'hooks/useFetch'; import { useVersion } from 'lib/queries/version'; import { userSelector } from 'lib/recoil/user'; import { capitalize } from 'lib/utils/client'; +import { UserExtended } from 'middleware/withZipline'; import Link from 'next/link'; import { useRouter } from 'next/router'; import { useState } from 'react'; @@ -60,7 +61,7 @@ export type NavbarItems = { text: string; link?: string; children?: NavbarItems[]; - if?: (user: any, props: any) => boolean; + if?: (user: UserExtended, props: unknown) => boolean; }; const items: NavbarItems[] = [ @@ -120,7 +121,7 @@ const items: NavbarItems[] = [ icon: , text: 'Invites', link: '/dashboard/invites', - if: (_, props) => props.invites, + if: (_, props: { invites: boolean }) => props.invites, }, ], }, @@ -290,9 +291,9 @@ export default function Layout({ children, props }) { {external_links.length - ? external_links.map(({ label, link }, i) => ( + ? external_links.map(({ label, link }, i: number) => (
- {/* @ts-ignore */} - {expireText(new Date(invite.expiresAt))} + {expireText(invite.expiresAt.toString())}
diff --git a/src/components/pages/Manage/Flameshot.tsx b/src/components/pages/Manage/Flameshot.tsx index ec9c52e..79c678e 100644 --- a/src/components/pages/Manage/Flameshot.tsx +++ b/src/components/pages/Manage/Flameshot.tsx @@ -1,6 +1,5 @@ -import { Anchor, Code } from '@mantine/core'; +import { Code } from '@mantine/core'; import AnchorNext from 'components/AnchorNext'; -import Link from 'next/link'; import { GeneratorModal } from './GeneratorModal'; export default function Flameshot({ user, open, setOpen }) { diff --git a/src/components/pages/Manage/GeneratorModal.tsx b/src/components/pages/Manage/GeneratorModal.tsx index 8a2e520..3135b73 100644 --- a/src/components/pages/Manage/GeneratorModal.tsx +++ b/src/components/pages/Manage/GeneratorModal.tsx @@ -1,5 +1,4 @@ import { - Anchor, Box, Button, Checkbox, @@ -18,7 +17,6 @@ import { useForm } from '@mantine/form'; import { IconFileDownload, IconWorld } from '@tabler/icons-react'; import AnchorNext from 'components/AnchorNext'; import MutedText from 'components/MutedText'; -import Link from 'next/link'; import { useReducer, useState } from 'react'; const DEFAULT_OD_DESC = 'Override the default domain(s). Type in a URL, e.g https://example.com'; diff --git a/src/components/pages/Manage/ShareX.tsx b/src/components/pages/Manage/ShareX.tsx index 52ea404..7bc21e4 100644 --- a/src/components/pages/Manage/ShareX.tsx +++ b/src/components/pages/Manage/ShareX.tsx @@ -1,4 +1,3 @@ -import { useReducer, useState } from 'react'; import { GeneratorModal } from './GeneratorModal'; export default function ShareX({ user, open, setOpen }) { diff --git a/src/components/pages/Stats/Graphs.tsx b/src/components/pages/Stats/Graphs.tsx index 1887663..9147159 100644 --- a/src/components/pages/Stats/Graphs.tsx +++ b/src/components/pages/Stats/Graphs.tsx @@ -2,7 +2,7 @@ import { Box, Card, Grid, LoadingOverlay, Title, useMantineTheme } from '@mantin import { useStats } from 'lib/queries/stats'; import { bytesToHuman } from 'lib/utils/bytes'; -import { useEffect, useMemo, useState } from 'react'; +import { useMemo } from 'react'; import { CartesianGrid, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts'; diff --git a/src/components/pages/Stats/Types.tsx b/src/components/pages/Stats/Types.tsx index 5e67a41..d4602fd 100644 --- a/src/components/pages/Stats/Types.tsx +++ b/src/components/pages/Stats/Types.tsx @@ -3,7 +3,7 @@ import { Box, Card, Center, Grid, LoadingOverlay, Title, useMantineTheme } from import { SmallTable } from 'components/SmallTable'; import { useStats } from 'lib/queries/stats'; import { colorHash } from 'lib/utils/client'; -import { useEffect, useMemo, useState } from 'react'; +import { useMemo } from 'react'; import { Pie, PieChart, ResponsiveContainer, Tooltip } from 'recharts'; diff --git a/src/components/pages/Upload/useUploadOptions.tsx b/src/components/pages/Upload/useUploadOptions.tsx index ba98297..2256f54 100644 --- a/src/components/pages/Upload/useUploadOptions.tsx +++ b/src/components/pages/Upload/useUploadOptions.tsx @@ -11,7 +11,7 @@ import { Title, } from '@mantine/core'; import { IconAlarm, IconEye, IconFileInfo, IconKey, IconPhotoDown, IconWorld } from '@tabler/icons-react'; -import React, { Dispatch, SetStateAction, useReducer, useState } from 'react'; +import React, { Dispatch, ReactNode, SetStateAction, useReducer, useState } from 'react'; export type UploadOptionsState = { expires: string; @@ -37,7 +37,11 @@ export function OptionsModal({ opened: boolean; setOpened: Dispatch>; state: UploadOptionsState; - setState: Dispatch>; + setState: Dispatch< + SetStateAction<{ + [key in keyof UploadOptionsState]?: UploadOptionsState[key]; + }> + >; reset: () => void; }) { const [odState, setODState] = useReducer((state, newState) => ({ ...state, ...newState }), { @@ -79,7 +83,7 @@ export function OptionsModal({ label='Max Views' description='The maximum number of times this file can be viewed. Leave blank for unlimited views.' value={state.maxViews} - onChange={(e) => setState({ maxViews: e })} + onChange={(e) => setState({ maxViews: e === '' ? undefined : e })} min={0} icon={} /> @@ -206,7 +210,11 @@ export function OptionsModal({ ); } -export default function useUploadOptions(): [UploadOptionsState, Dispatch>, any] { +export default function useUploadOptions(): [ + UploadOptionsState, + Dispatch>, + ReactNode +] { const [state, setState] = useReducer((state, newState) => ({ ...state, ...newState }), { expires: 'never', password: '', diff --git a/src/components/pages/Urls/URLCard.tsx b/src/components/pages/Urls/URLCard.tsx index cbee745..ce8efe3 100644 --- a/src/components/pages/Urls/URLCard.tsx +++ b/src/components/pages/Urls/URLCard.tsx @@ -1,9 +1,9 @@ -import { ActionIcon, Anchor, Card, Group, Stack, Title, Tooltip } from '@mantine/core'; +import { ActionIcon, Card, Group, Stack, Title, Tooltip } from '@mantine/core'; import { IconClipboardCopy, IconExternalLink, IconTrash } from '@tabler/icons-react'; +import AnchorNext from 'components/AnchorNext'; import MutedText from 'components/MutedText'; import { URLResponse } from 'lib/queries/url'; import { relativeTime } from 'lib/utils/client'; -import Link from 'next/link'; export default function URLCard({ url, diff --git a/src/components/pages/Urls/index.tsx b/src/components/pages/Urls/index.tsx index c971010..94696bf 100644 --- a/src/components/pages/Urls/index.tsx +++ b/src/components/pages/Urls/index.tsx @@ -1,6 +1,5 @@ import { ActionIcon, - Anchor, Button, Card, Center, @@ -28,11 +27,11 @@ import { } from '@tabler/icons-react'; import AnchorNext from 'components/AnchorNext'; import MutedText from 'components/MutedText'; +import { ApiError } from 'hooks/useFetch'; import { useURLDelete, useURLs } from 'lib/queries/url'; import { listViewUrlsSelector } from 'lib/recoil/settings'; import { userSelector } from 'lib/recoil/user'; import { DataTable, DataTableSortStatus } from 'mantine-datatable'; -import Link from 'next/link'; import { useEffect, useState } from 'react'; import { useRecoilState, useRecoilValue } from 'recoil'; import URLCard from './URLCard'; @@ -196,7 +195,7 @@ export default function Urls() { }); }, - onError: (url: any) => { + onError: (url: ApiError) => { showNotification({ title: 'Failed to delete URL', message: url.error, diff --git a/src/components/render/Markdown.tsx b/src/components/render/Markdown.tsx index 9e184c5..ef2a9e2 100644 --- a/src/components/render/Markdown.tsx +++ b/src/components/render/Markdown.tsx @@ -2,24 +2,24 @@ import { Code } from '@mantine/core'; import { Prism } from '@mantine/prism'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; +import { Language } from 'prism-react-renderer'; export default function Markdown({ code, ...props }) { return ( + {String(children).replace(/\n$/, '')} ) : ( {children} ); }, - img({ node, ...props }) { + img(props) { return ; }, }} diff --git a/src/lib/config.ts b/src/lib/config.ts index fe3fc6d..f1edbac 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -7,5 +7,6 @@ if (!global.config) global.config = validateConfig(readConfig()); export default global.config as Config; declare global { + // eslint-disable-next-line no-var var config: Config; } diff --git a/src/lib/config/readConfig.ts b/src/lib/config/readConfig.ts index 64b941e..459d304 100644 --- a/src/lib/config/readConfig.ts +++ b/src/lib/config/readConfig.ts @@ -7,11 +7,11 @@ import { humanToBytes } from 'utils/bytes'; export type ValueType = 'string' | 'number' | 'boolean' | 'array' | 'json-array' | 'human-to-byte' | 'path'; -function isObject(value: any): value is Record { +function isObject(value: unknown): value is Record { return typeof value === 'object' && value !== null; } -function set(object: Record, property: string, value: any) { +function set(object: Record | unknown, property: string, value: unknown) { const parts = property.split('.'); for (let i = 0; i < parts.length; ++i) { @@ -176,14 +176,14 @@ export default function readConfig() { const value = process.env[map.env]; if (value) { - let parsed: any; + let parsed: unknown; switch (map.type) { case 'array': parsed = value.split(','); break; case 'number': parsed = Number(value); - if (isNaN(parsed)) { + if (isNaN(parsed as number)) { parsed = undefined; logger.debug(`Failed to parse number ${map.env}=${value}`); } @@ -205,7 +205,8 @@ export default function readConfig() { break; case 'path': parsed = resolve(value); - if (!existsSync(parsed)) logger.debug(`Unable to find ${map.env}=${value} (path does not exist)`); + if (!existsSync(parsed as string)) + logger.debug(`Unable to find ${map.env}=${value} (path does not exist)`); break; default: parsed = value; diff --git a/src/lib/datasource.ts b/src/lib/datasource.ts index 38e29dd..8f621a2 100644 --- a/src/lib/datasource.ts +++ b/src/lib/datasource.ts @@ -26,5 +26,6 @@ if (!global.datasource) { export default global.datasource as Datasource; declare global { + // eslint-disable-next-line no-var var datasource: Datasource; } diff --git a/src/lib/datasources/Local.ts b/src/lib/datasources/Local.ts index e69578b..c1aadb6 100644 --- a/src/lib/datasources/Local.ts +++ b/src/lib/datasources/Local.ts @@ -4,7 +4,7 @@ import { join } from 'path'; import { Datasource } from '.'; export class Local extends Datasource { - public name: string = 'local'; + public name = 'local'; public constructor(public path: string) { super(); diff --git a/src/lib/datasources/S3.ts b/src/lib/datasources/S3.ts index 9e0797d..011b5e0 100644 --- a/src/lib/datasources/S3.ts +++ b/src/lib/datasources/S3.ts @@ -4,7 +4,7 @@ import { ConfigS3Datasource } from 'lib/config/Config'; import { Client } from 'minio'; export class S3 extends Datasource { - public name: string = 'S3'; + public name = 'S3'; public s3: Client; public constructor(public config: ConfigS3Datasource) { @@ -41,7 +41,7 @@ export class S3 extends Datasource { } public get(file: string): Promise { - return new Promise((res, rej) => { + return new Promise((res) => { this.s3.getObject(this.config.bucket, file, (err, stream) => { if (err) res(null); else res(stream); diff --git a/src/lib/datasources/Supabase.ts b/src/lib/datasources/Supabase.ts index c157026..981351a 100644 --- a/src/lib/datasources/Supabase.ts +++ b/src/lib/datasources/Supabase.ts @@ -5,7 +5,7 @@ import Logger from 'lib/logger'; import { Readable } from 'stream'; export class Supabase extends Datasource { - public name: string = 'Supabase'; + public name = 'Supabase'; public logger: Logger = Logger.get('datasource::supabase'); public constructor(public config: ConfigSupabaseDatasource) { @@ -81,11 +81,12 @@ export class Supabase extends Datasource { }, }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any return Readable.fromWeb(r.body as any); } public size(file: string): Promise { - return new Promise(async (res, rej) => { + return new Promise(async (res) => { fetch(`${this.config.url}/storage/v1/object/list/${this.config.bucket}`, { method: 'POST', headers: { @@ -114,7 +115,7 @@ export class Supabase extends Datasource { } public async fullSize(): Promise { - return new Promise((res, rej) => { + return new Promise((res) => { fetch(`${this.config.url}/storage/v1/object/list/${this.config.bucket}`, { method: 'POST', headers: { diff --git a/src/lib/hooks/useFetch.ts b/src/lib/hooks/useFetch.ts index 97b1430..a879b60 100644 --- a/src/lib/hooks/useFetch.ts +++ b/src/lib/hooks/useFetch.ts @@ -1,7 +1,13 @@ +export type ApiError = { + error: string; + code: number; + [key: string]: unknown; +}; + export default async function useFetch( url: string, method: 'GET' | 'POST' | 'PATCH' | 'DELETE' = 'GET', - body: Record = null + body: ApiError | Record = null ) { const headers = {}; if (body) headers['content-type'] = 'application/json'; diff --git a/src/lib/logger.ts b/src/lib/logger.ts index 43ea9d9..07de26d 100644 --- a/src/lib/logger.ts +++ b/src/lib/logger.ts @@ -21,10 +21,11 @@ export default class Logger { return (process.env.LOGGER_FILTERS ?? '').split(',').filter((x) => x !== ''); } - static get(klass: any) { + // eslint-disable-next-line @typescript-eslint/ban-types + static get(klass: Function | string) { if (typeof klass !== 'function') if (typeof klass !== 'string') throw new Error('not string/function'); - const name = klass.name ?? klass; + const name = typeof klass === 'string' ? klass : klass.name; return new Logger(name); } @@ -44,7 +45,7 @@ export default class Logger { return filters.includes(this.name); } - info(...args: any[]): this { + info(...args: unknown[]): this { if (!this.show()) return this; process.stdout.write(this.formatMessage(LoggerLevel.INFO, this.name, args.join(' '))); @@ -52,17 +53,21 @@ export default class Logger { return this; } - error(...args: any[]): this { + error(...args: unknown[]): this { if (!this.show()) return this; process.stdout.write( - this.formatMessage(LoggerLevel.ERROR, this.name, args.map((error) => error.stack ?? error).join(' ')) + this.formatMessage( + LoggerLevel.ERROR, + this.name, + args.map((error) => (typeof error === 'string' ? error : (error as Error).stack)).join(' ') + ) ); return this; } - debug(...args: any[]): this { + debug(...args: unknown[]): this { if (!process.env.DEBUG) return this; if (!this.show()) return this; diff --git a/src/lib/middleware/withOAuth.ts b/src/lib/middleware/withOAuth.ts index 209a2b1..cb26433 100644 --- a/src/lib/middleware/withOAuth.ts +++ b/src/lib/middleware/withOAuth.ts @@ -143,7 +143,7 @@ export const withOAuth = logger.debug(`attempting to refresh ${provider} account for ${user.username}`); await prisma.oAuth.update({ where: { - id: userOauth!.id, + id: userOauth?.id, }, data: { token: oauth_resp.access_token, @@ -160,7 +160,7 @@ export const withOAuth = } else if ((existingOauth && existingOauth.fallback) || existingOauth) { await prisma.oAuth.update({ where: { - id: existingOauth!.id, + id: existingOauth?.id, }, data: { token: oauth_resp.access_token, diff --git a/src/lib/middleware/withZipline.ts b/src/lib/middleware/withZipline.ts index a12303f..826aef1 100644 --- a/src/lib/middleware/withZipline.ts +++ b/src/lib/middleware/withZipline.ts @@ -47,12 +47,12 @@ export type NextApiResExtra = | 'notFound' | 'error'; export type NextApiResExtraObj = { - [key in NextApiResExtra]: (message: any, extra?: Record) => void; + [key in NextApiResExtra]: (message: string | number, extra?: Record) => void; }; export type NextApiRes = NextApiResponse & NextApiResExtraObj & { - json: (json: Record, status?: number) => void; + json: (json: Record, status?: number) => void; setCookie: (name: string, value: unknown, options: CookieSerializeOptions) => void; setUserCookie: (id: number) => void; }; @@ -80,7 +80,7 @@ export const withZipline = if (req.method === 'OPTIONS') return res.status(204).end(); // Used when the client sends wrong information, etc. - res.badRequest = (message: string, extra: Record = {}) => { + res.badRequest = (message: string, extra: Record = {}) => { res.json( { error: message, @@ -92,7 +92,7 @@ export const withZipline = }; // If the user is not logged in - res.unauthorized = (message: string, extra: Record = {}) => { + res.unauthorized = (message: string, extra: Record = {}) => { res.json( { error: message, @@ -104,7 +104,7 @@ export const withZipline = }; // If the user is logged in but doesn't have permission to do something - res.forbidden = (message: string, extra: Record = {}) => { + res.forbidden = (message: string, extra: Record = {}) => { res.json( { error: message, @@ -115,7 +115,7 @@ export const withZipline = ); }; - res.notFound = (message: string, extra: Record = {}) => { + res.notFound = (message: string, extra: Record = {}) => { res.json( { error: message, @@ -126,7 +126,7 @@ export const withZipline = ); }; - res.ratelimited = (message: number, extra: Record = {}) => { + res.ratelimited = (message: number, extra: Record = {}) => { const retry = Math.floor(message / 1000); res.setHeader('X-Ratelimit-Remaining', retry); @@ -140,7 +140,7 @@ export const withZipline = ); }; - res.json = (json: any, status: number = 200) => { + res.json = (json: unknown, status = 200) => { res.setHeader('Content-Type', 'application/json'); res.status(status); res.end(JSON.stringify(json)); diff --git a/src/lib/prisma.ts b/src/lib/prisma.ts index 162590e..ed13334 100644 --- a/src/lib/prisma.ts +++ b/src/lib/prisma.ts @@ -7,5 +7,6 @@ if (!global.prisma) { export default global.prisma as PrismaClient; declare global { + // eslint-disable-next-line no-var var prisma: PrismaClient; } diff --git a/src/lib/queries/files.ts b/src/lib/queries/files.ts index 097b28c..47cbfdb 100644 --- a/src/lib/queries/files.ts +++ b/src/lib/queries/files.ts @@ -10,6 +10,9 @@ export type UserFilesResponse = { favorite: boolean; url: string; size: number; + maxViews: number; + views: number; + folderId?: number; }; export const useFiles = (query: { [key: string]: string } = {}) => { @@ -30,7 +33,7 @@ export const useFiles = (query: { [key: string]: string } = {}) => { ); }); }; -export const usePaginatedFiles = (page?: number, filter: string = 'media', favorite = null) => { +export const usePaginatedFiles = (page?: number, filter = 'media', favorite = null) => { const queryBuilder = new URLSearchParams({ page: Number(page || '1').toString(), filter, diff --git a/src/lib/queries/folders.ts b/src/lib/queries/folders.ts index 986bbb3..f73b342 100644 --- a/src/lib/queries/folders.ts +++ b/src/lib/queries/folders.ts @@ -1,4 +1,4 @@ -import { useMutation, useQuery } from '@tanstack/react-query'; +import { useQuery } from '@tanstack/react-query'; import queryClient from './client'; import { UserFilesResponse } from './files'; @@ -29,7 +29,7 @@ export const useFolders = (query: { [key: string]: string } = {}) => { }); }; -export const useFolder = (id: string, withFiles: boolean = false) => { +export const useFolder = (id: string, withFiles = false) => { return useQuery(['folder', id], async () => { return fetch('/api/user/folders/' + id + (withFiles ? '?files=true' : '')) .then((res) => res.json() as Promise) diff --git a/src/lib/queries/stats.ts b/src/lib/queries/stats.ts index bb75dbe..aa1347c 100644 --- a/src/lib/queries/stats.ts +++ b/src/lib/queries/stats.ts @@ -10,7 +10,7 @@ export type Stats = { id: number; data: { count: number; - count_by_user: any[]; + count_by_user: unknown[]; count_users: number; size: string; size_num: number; diff --git a/src/lib/spotlight.tsx b/src/lib/spotlight.tsx index dcc00f1..88e816e 100644 --- a/src/lib/spotlight.tsx +++ b/src/lib/spotlight.tsx @@ -15,6 +15,7 @@ import { IconUser, } from '@tabler/icons-react'; import { NextRouter } from 'next/router'; +import { ReactNode } from 'react'; import { useRecoilValue } from 'recoil'; import { userSelector } from './recoil/user'; @@ -35,7 +36,7 @@ export const createSpotlightActions = (router: NextRouter): SpotlightAction[] => title: string, description: string, link: string, - icon: any + icon: ReactNode ): SpotlightAction => { return actionDo(group, title, description, icon, () => linkTo(link)); }; @@ -44,7 +45,7 @@ export const createSpotlightActions = (router: NextRouter): SpotlightAction[] => group: string, title: string, description: string, - icon: any, + icon: ReactNode, action: () => void ): SpotlightAction => { return { diff --git a/src/lib/util.ts b/src/lib/util.ts index c4c4fc0..aad8548 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -120,6 +120,6 @@ export async function getBase64URLFromURL(url: string) { return `data:${res.headers.get('content-type')};base64,${base64}`; } -export function notNull(a: any, b: any) { +export function notNull(a: unknown, b: unknown) { return a !== null && b !== null; } diff --git a/src/lib/utils/client.ts b/src/lib/utils/client.ts index 04f11db..0ba7e76 100644 --- a/src/lib/utils/client.ts +++ b/src/lib/utils/client.ts @@ -5,7 +5,7 @@ import ms, { StringValue } from 'ms'; dayjs.extend(duration); dayjs.extend(dayjsRelativeTime); -export function jsonUserReplacer(key: string, value: any) { +export function jsonUserReplacer(key: string, value: unknown) { if (key === 'avatar') return 'data:image/*;base64,***'; return value; @@ -137,7 +137,7 @@ export function colorHash(str: string) { let color = '#'; for (let i = 0; i < 3; i++) { - let value = (hash >> (i * 8)) & 0xff; + const value = (hash >> (i * 8)) & 0xff; color += ('00' + value.toString(16)).substr(-2); } diff --git a/src/lib/utils/parser.ts b/src/lib/utils/parser.ts index be0661c..b9b8957 100644 --- a/src/lib/utils/parser.ts +++ b/src/lib/utils/parser.ts @@ -61,7 +61,7 @@ export function parseString(str: string, value: ParseValue) { return str; } -function modifier(mod: string, value: any): string { +function modifier(mod: string, value: unknown): string { mod = mod.toLowerCase(); if (value instanceof Date) { diff --git a/src/pages/_error.tsx b/src/pages/_error.tsx index d714f33..3db5e7a 100644 --- a/src/pages/_error.tsx +++ b/src/pages/_error.tsx @@ -3,7 +3,7 @@ import MutedText from 'components/MutedText'; import Head from 'next/head'; import Link from 'next/link'; -export default function Error({ statusCode, oauthError }) { +export default function Error({ statusCode }) { return ( <> diff --git a/src/pages/api/admin/clear.ts b/src/pages/api/admin/clear.ts index 3c3b677..d1d58d8 100644 --- a/src/pages/api/admin/clear.ts +++ b/src/pages/api/admin/clear.ts @@ -1,4 +1,3 @@ -import datasource from 'lib/datasource'; import Logger from 'lib/logger'; import prisma from 'lib/prisma'; import { NextApiReq, NextApiRes, UserExtended, withZipline } from 'middleware/withZipline'; diff --git a/src/pages/api/stats.ts b/src/pages/api/stats.ts index c15f78a..4ba5fdd 100644 --- a/src/pages/api/stats.ts +++ b/src/pages/api/stats.ts @@ -19,7 +19,7 @@ async function handler(req: NextApiReq, res: NextApiRes, user: UserExtended) { return res.json(stats_data); } else { - let amount = typeof req.query.amount === 'string' ? Number(req.query.amount) : 2; + const amount = typeof req.query.amount === 'string' ? Number(req.query.amount) : 2; if (isNaN(amount)) return res.badRequest('invalid amount'); // get stats per day @@ -38,7 +38,7 @@ async function handler(req: NextApiReq, res: NextApiRes, user: UserExtended) { if (!config.website.show_files_per_user) { stats = stats.map((stat) => { - (stat.data as any).count_by_user = []; + (stat.data as Record).count_by_user = []; return stat; }); } diff --git a/src/pages/api/upload.ts b/src/pages/api/upload.ts index 704a0a0..ecde82c 100644 --- a/src/pages/api/upload.ts +++ b/src/pages/api/upload.ts @@ -1,6 +1,4 @@ import { InvisibleFile } from '@prisma/client'; -import { randomUUID } from 'crypto'; -import dayjs from 'dayjs'; import { readdir, readFile, unlink, writeFile } from 'fs/promises'; import zconfig from 'lib/config'; import datasource from 'lib/datasource'; @@ -9,7 +7,7 @@ import formatFileName, { NameFormat, NameFormats } from 'lib/format'; import Logger from 'lib/logger'; import { NextApiReq, NextApiRes, withZipline } from 'lib/middleware/withZipline'; import prisma from 'lib/prisma'; -import { createInvisImage, hashPassword, randomChars } from 'lib/util'; +import { createInvisImage, hashPassword } from 'lib/util'; import { parseExpiry } from 'lib/utils/client'; import { removeGPSData } from 'lib/utils/exif'; import multer from 'multer'; @@ -32,7 +30,7 @@ async function handler(req: NextApiReq, res: NextApiRes) { if (!user) return res.forbidden('authorization incorrect'); await new Promise((resolve, reject) => { - uploader.array('file')(req as any, res as any, (result: unknown) => { + uploader.array('file')(req as never, res as never, (result: unknown) => { if (result instanceof Error) reject(result.message); resolve(result); }); @@ -127,7 +125,7 @@ async function handler(req: NextApiReq, res: NextApiRes) { const ext = filename.split('.').length === 1 ? '' : filename.split('.').pop(); if (zconfig.uploader.disabled_extensions.includes(ext)) return res.error('disabled extension recieved: ' + ext); - let fileName = await formatFileName(format, filename); + const fileName = await formatFileName(format, filename); let password = null; if (req.headers.password) { diff --git a/src/pages/api/user/[id].ts b/src/pages/api/user/[id].ts index 25dfb8e..af929a0 100644 --- a/src/pages/api/user/[id].ts +++ b/src/pages/api/user/[id].ts @@ -21,7 +21,7 @@ async function handler(req: NextApiReq, res: NextApiRes, user: UserExtended) { if (req.method === 'DELETE') { if (target.id === user.id) return res.badRequest("you can't delete your own account"); if (target.administrator && !user.superAdmin) return res.forbidden('cannot delete administrator'); - let promises = []; + const promises = []; promises.push( prisma.user.delete({ diff --git a/src/pages/api/user/export.ts b/src/pages/api/user/export.ts index cee763d..1e794dc 100644 --- a/src/pages/api/user/export.ts +++ b/src/pages/api/user/export.ts @@ -34,7 +34,7 @@ async function handler(req: NextApiReq, res: NextApiRes, user: UserExtended) { }; const backpressureThreshold = 65536; - let backpressure = []; + const backpressure = []; let backpressureBytes = 0; const push = stream.push; stream.push = (dat, final) => { diff --git a/src/pages/api/user/paged.ts b/src/pages/api/user/paged.ts index e418ab9..0210257 100644 --- a/src/pages/api/user/paged.ts +++ b/src/pages/api/user/paged.ts @@ -48,7 +48,7 @@ async function handler(req: NextApiReq, res: NextApiRes, user: UserExtended) { if (!page) return res.badRequest('no page'); if (isNaN(Number(page))) return res.badRequest('page is not a number'); - let files: { + const files: { favorite: boolean; createdAt: Date; id: number; diff --git a/src/pages/api/user/urls.ts b/src/pages/api/user/urls.ts index 201516a..33aa931 100644 --- a/src/pages/api/user/urls.ts +++ b/src/pages/api/user/urls.ts @@ -18,7 +18,7 @@ async function handler(req: NextApiReq, res: NextApiRes, user: UserExtended) { return res.json(url); } else { - let urls = await prisma.url.findMany({ + const urls = await prisma.url.findMany({ where: { userId: user.id, }, diff --git a/src/pages/auth/login.tsx b/src/pages/auth/login.tsx index af1b96f..a697ab4 100644 --- a/src/pages/auth/login.tsx +++ b/src/pages/auth/login.tsx @@ -21,7 +21,6 @@ import Link from 'next/link'; import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; export { getServerSideProps } from 'middleware/getServerSideProps'; -import AnchorNext from 'components/AnchorNext'; export default function Login({ title, user_registration, oauth_registration, oauth_providers: unparsed }) { const router = useRouter(); diff --git a/src/pages/view/[id].tsx b/src/pages/view/[id].tsx index 9f11b91..06eb2c8 100644 --- a/src/pages/view/[id].tsx +++ b/src/pages/view/[id].tsx @@ -259,6 +259,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => { }, }; } + // @ts-ignore if (file.password) file.password = true; diff --git a/src/scripts/clear-zero-byte.ts b/src/scripts/clear-zero-byte.ts index 2ac7d4d..3286b43 100644 --- a/src/scripts/clear-zero-byte.ts +++ b/src/scripts/clear-zero-byte.ts @@ -1,9 +1,6 @@ import { PrismaClient } from '@prisma/client'; -import { readdir, readFile } from 'fs/promises'; -import { join } from 'path'; import config from 'lib/config'; import datasource from 'lib/datasource'; -import { guess } from 'lib/mimes'; import { migrations } from 'server/util'; async function main() { diff --git a/src/server/plugins/next.ts b/src/server/plugins/next.ts index a837c15..e8f4306 100644 --- a/src/server/plugins/next.ts +++ b/src/server/plugins/next.ts @@ -15,7 +15,7 @@ async function nextPlugin(fastify: FastifyInstance, options: NextServerOptions) return nextServer.prepare(); - function route(path, opts: any = { method: 'GET' }) { + function route(path, opts: { method: string | string[] } = { method: 'GET' }) { if (typeof opts.method === 'string') this[opts.method.toLowerCase()](path, opts, handler); else if (Array.isArray(opts.method)) { for (const method of opts.method) this[method.toLowerCase()](path, opts, handler); diff --git a/yarn.lock b/yarn.lock index b90009c..7fbb101 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1430,27 +1430,45 @@ __metadata: languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.0.0": - version: 2.0.0 - resolution: "@eslint/eslintrc@npm:2.0.0" +"@eslint-community/eslint-utils@npm:^4.2.0": + version: 4.3.0 + resolution: "@eslint-community/eslint-utils@npm:4.3.0" + dependencies: + eslint-visitor-keys: ^3.3.0 + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: f487760a692f0f1fef76e248ad72976919576ba57edc2b1b1dc1d182553bae6b5bf7b078e654da85d04f0af8a485d20bd26280002768f4fbcd2e330078340cb0 + languageName: node + linkType: hard + +"@eslint-community/regexpp@npm:^4.4.0": + version: 4.4.0 + resolution: "@eslint-community/regexpp@npm:4.4.0" + checksum: 2d127af0c752b80e8a782eacfe996a86925d21de92da3ffc6f9e615e701145e44a62e26bdd88bfac2cd76779c39ba8d9875a91046ec5e7e5f23cb647c247ea6a + languageName: node + linkType: hard + +"@eslint/eslintrc@npm:^2.0.1": + version: 2.0.1 + resolution: "@eslint/eslintrc@npm:2.0.1" dependencies: ajv: ^6.12.4 debug: ^4.3.2 - espree: ^9.4.0 + espree: ^9.5.0 globals: ^13.19.0 ignore: ^5.2.0 import-fresh: ^3.2.1 js-yaml: ^4.1.0 minimatch: ^3.1.2 strip-json-comments: ^3.1.1 - checksum: 31119c8ca06723d80384f18f5c78e0530d8e6306ad36379868650131a8b10dd7cffd7aff79a5deb3a2e9933660823052623d268532bae9538ded53d5b19a69a6 + checksum: 56b9192a687a450db53a7b883daf9f0f447c43b3510189cf88808a7a2467c2a302a42a50f184cc6d5a9faf3d1df890a2ef0fd0d60b751f32a3e9dfea717c6b48 languageName: node linkType: hard -"@eslint/js@npm:8.35.0": - version: 8.35.0 - resolution: "@eslint/js@npm:8.35.0" - checksum: 6687ceff659a6d617e37823f809dc9c4b096535961a81acead27d26b1a51a4cf608a5e59d831ddd57f24f6f8bb99340a4a0e19f9c99b390fbb4b275f51ed5f5e +"@eslint/js@npm:8.36.0": + version: 8.36.0 + resolution: "@eslint/js@npm:8.36.0" + checksum: b7d6b84b823c8c7784be390741196617565527b1f7c0977fde9455bfb57fd88f81c074a03dd878757d2c33fa29f24291e9ecbc1425710f067917324b55e1bf3a languageName: node linkType: hard @@ -2625,6 +2643,13 @@ __metadata: languageName: node linkType: hard +"@types/json-schema@npm:^7.0.9": + version: 7.0.11 + resolution: "@types/json-schema@npm:7.0.11" + checksum: 527bddfe62db9012fccd7627794bd4c71beb77601861055d87e3ee464f2217c85fca7a4b56ae677478367bbd248dbde13553312b7d4dbc702a2f2bbf60c4018d + languageName: node + linkType: hard + "@types/json5@npm:^0.0.29": version: 0.0.29 resolution: "@types/json5@npm:0.0.29" @@ -2777,6 +2802,13 @@ __metadata: languageName: node linkType: hard +"@types/semver@npm:^7.3.12": + version: 7.3.13 + resolution: "@types/semver@npm:7.3.13" + checksum: 00c0724d54757c2f4bc60b5032fe91cda6410e48689633d5f35ece8a0a66445e3e57fa1d6e07eb780f792e82ac542948ec4d0b76eb3484297b79bd18b8cf1cb0 + languageName: node + linkType: hard + "@types/serve-static@npm:*": version: 1.15.0 resolution: "@types/serve-static@npm:1.15.0" @@ -2820,6 +2852,30 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/eslint-plugin@npm:^5.56.0": + version: 5.56.0 + resolution: "@typescript-eslint/eslint-plugin@npm:5.56.0" + dependencies: + "@eslint-community/regexpp": ^4.4.0 + "@typescript-eslint/scope-manager": 5.56.0 + "@typescript-eslint/type-utils": 5.56.0 + "@typescript-eslint/utils": 5.56.0 + debug: ^4.3.4 + grapheme-splitter: ^1.0.4 + ignore: ^5.2.0 + natural-compare-lite: ^1.4.0 + semver: ^7.3.7 + tsutils: ^3.21.0 + peerDependencies: + "@typescript-eslint/parser": ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 2eed4a4ed8279950ad553252e8623e947ffdee39b0d677a13f6e4e2d863ea1cbc5d683ff189e55d0de6fd5a25afd72d3c3a9ab7ae417d5405a21ead907e1b154 + languageName: node + linkType: hard + "@typescript-eslint/parser@npm:^5.42.0": version: 5.46.0 resolution: "@typescript-eslint/parser@npm:5.46.0" @@ -2837,6 +2893,23 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/parser@npm:^5.56.0": + version: 5.56.0 + resolution: "@typescript-eslint/parser@npm:5.56.0" + dependencies: + "@typescript-eslint/scope-manager": 5.56.0 + "@typescript-eslint/types": 5.56.0 + "@typescript-eslint/typescript-estree": 5.56.0 + debug: ^4.3.4 + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: eb25490290bd5e22f9c42603dedc0d2d8ee845553e3cf48ea377bd5dc22440d3463f8b84be637b6a2b37cd9ea56b21e4e43007a0a69998948d9c8965c03fe1aa + languageName: node + linkType: hard + "@typescript-eslint/scope-manager@npm:5.46.0": version: 5.46.0 resolution: "@typescript-eslint/scope-manager@npm:5.46.0" @@ -2847,6 +2920,33 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:5.56.0": + version: 5.56.0 + resolution: "@typescript-eslint/scope-manager@npm:5.56.0" + dependencies: + "@typescript-eslint/types": 5.56.0 + "@typescript-eslint/visitor-keys": 5.56.0 + checksum: bacac255ee52148cee6622be2811c0d7e25419058b89f1a11f4c1303faef4535a0a1237549f9556ec1d7a297c640ce4357183a1a8465d72e1393b7d8fb43874b + languageName: node + linkType: hard + +"@typescript-eslint/type-utils@npm:5.56.0": + version: 5.56.0 + resolution: "@typescript-eslint/type-utils@npm:5.56.0" + dependencies: + "@typescript-eslint/typescript-estree": 5.56.0 + "@typescript-eslint/utils": 5.56.0 + debug: ^4.3.4 + tsutils: ^3.21.0 + peerDependencies: + eslint: "*" + peerDependenciesMeta: + typescript: + optional: true + checksum: 3dd1fcfadad18790b900a3d90f6617904adb6b0e2bd1e1edb6ebf239e1399865ca9098647405385feb4252d8b2b4577883e6fd3ef8d00bdd521d6070972d486b + languageName: node + linkType: hard + "@typescript-eslint/types@npm:5.46.0": version: 5.46.0 resolution: "@typescript-eslint/types@npm:5.46.0" @@ -2854,6 +2954,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:5.56.0": + version: 5.56.0 + resolution: "@typescript-eslint/types@npm:5.56.0" + checksum: 82ca11553bbb1bbfcaf7e7760b03c0d898940238dc002552c21af3e58f7d482c64c3c6cf0666521aff2a1e7b4b58bb6e4d9a00b1e4998a16b5039f5d288d003a + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:5.46.0": version: 5.46.0 resolution: "@typescript-eslint/typescript-estree@npm:5.46.0" @@ -2872,6 +2979,42 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:5.56.0": + version: 5.56.0 + resolution: "@typescript-eslint/typescript-estree@npm:5.56.0" + dependencies: + "@typescript-eslint/types": 5.56.0 + "@typescript-eslint/visitor-keys": 5.56.0 + debug: ^4.3.4 + globby: ^11.1.0 + is-glob: ^4.0.3 + semver: ^7.3.7 + tsutils: ^3.21.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: ec3e85201786aa9adddba7cb834a9f330a7f55c729ee9ccf847dbdc2f7437b760f3774152ccad6d0aa48d13fd78df766c880e3a7ca42e01a20aba0e1a1ed61c5 + languageName: node + linkType: hard + +"@typescript-eslint/utils@npm:5.56.0": + version: 5.56.0 + resolution: "@typescript-eslint/utils@npm:5.56.0" + dependencies: + "@eslint-community/eslint-utils": ^4.2.0 + "@types/json-schema": ^7.0.9 + "@types/semver": ^7.3.12 + "@typescript-eslint/scope-manager": 5.56.0 + "@typescript-eslint/types": 5.56.0 + "@typescript-eslint/typescript-estree": 5.56.0 + eslint-scope: ^5.1.1 + semver: ^7.3.7 + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + checksum: 413e8d4bf7023ee5ba4f695b62e796a1f94930bb92fe5aa0cee58f63b9837116c23f618825a9c671f610e50f5630188b6059b4ed6b05a2a3336f01d8e977becb + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:5.46.0": version: 5.46.0 resolution: "@typescript-eslint/visitor-keys@npm:5.46.0" @@ -2882,6 +3025,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:5.56.0": + version: 5.56.0 + resolution: "@typescript-eslint/visitor-keys@npm:5.56.0" + dependencies: + "@typescript-eslint/types": 5.56.0 + eslint-visitor-keys: ^3.3.0 + checksum: 568fda40134e153d7befb59b55698f7919ba780d2d3431d8745feabf2e0fbb8aa7a02173b3c467dd20a0f6594e5248a1f82bb25d6c37827716d77452e86cad29 + languageName: node + linkType: hard + "@zxing/text-encoding@npm:0.9.0": version: 0.9.0 resolution: "@zxing/text-encoding@npm:0.9.0" @@ -5052,6 +5205,38 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-unused-imports@npm:^2.0.0": + version: 2.0.0 + resolution: "eslint-plugin-unused-imports@npm:2.0.0" + dependencies: + eslint-rule-composer: ^0.3.0 + peerDependencies: + "@typescript-eslint/eslint-plugin": ^5.0.0 + eslint: ^8.0.0 + peerDependenciesMeta: + "@typescript-eslint/eslint-plugin": + optional: true + checksum: 8aa1e03e75da2a62a354065e0cb8fe370118c6f8d9720a32fe8c1da937de6adb81a4fed7d0d391d115ac9453b49029fb19f970d180a2cf3dba451fd4c20f0dc4 + languageName: node + linkType: hard + +"eslint-rule-composer@npm:^0.3.0": + version: 0.3.0 + resolution: "eslint-rule-composer@npm:0.3.0" + checksum: c2f57cded8d1c8f82483e0ce28861214347e24fd79fd4144667974cd334d718f4ba05080aaef2399e3bbe36f7d6632865110227e6b176ed6daa2d676df9281b1 + languageName: node + linkType: hard + +"eslint-scope@npm:^5.1.1": + version: 5.1.1 + resolution: "eslint-scope@npm:5.1.1" + dependencies: + esrecurse: ^4.3.0 + estraverse: ^4.1.1 + checksum: 47e4b6a3f0cc29c7feedee6c67b225a2da7e155802c6ea13bbef4ac6b9e10c66cd2dcb987867ef176292bf4e64eccc680a49e35e9e9c669f4a02bac17e86abdb + languageName: node + linkType: hard + "eslint-scope@npm:^7.1.1": version: 7.1.1 resolution: "eslint-scope@npm:7.1.1" @@ -5062,24 +5247,6 @@ __metadata: languageName: node linkType: hard -"eslint-utils@npm:^3.0.0": - version: 3.0.0 - resolution: "eslint-utils@npm:3.0.0" - dependencies: - eslint-visitor-keys: ^2.0.0 - peerDependencies: - eslint: ">=5" - checksum: 0668fe02f5adab2e5a367eee5089f4c39033af20499df88fe4e6aba2015c20720404d8c3d6349b6f716b08fdf91b9da4e5d5481f265049278099c4c836ccb619 - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^2.0.0": - version: 2.1.0 - resolution: "eslint-visitor-keys@npm:2.1.0" - checksum: e3081d7dd2611a35f0388bbdc2f5da60b3a3c5b8b6e928daffff7391146b434d691577aa95064c8b7faad0b8a680266bcda0a42439c18c717b80e6718d7e267d - languageName: node - linkType: hard - "eslint-visitor-keys@npm:^3.3.0": version: 3.3.0 resolution: "eslint-visitor-keys@npm:3.3.0" @@ -5087,12 +5254,14 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^8.35.0": - version: 8.35.0 - resolution: "eslint@npm:8.35.0" +"eslint@npm:^8.36.0": + version: 8.36.0 + resolution: "eslint@npm:8.36.0" dependencies: - "@eslint/eslintrc": ^2.0.0 - "@eslint/js": 8.35.0 + "@eslint-community/eslint-utils": ^4.2.0 + "@eslint-community/regexpp": ^4.4.0 + "@eslint/eslintrc": ^2.0.1 + "@eslint/js": 8.36.0 "@humanwhocodes/config-array": ^0.11.8 "@humanwhocodes/module-importer": ^1.0.1 "@nodelib/fs.walk": ^1.2.8 @@ -5103,9 +5272,8 @@ __metadata: doctrine: ^3.0.0 escape-string-regexp: ^4.0.0 eslint-scope: ^7.1.1 - eslint-utils: ^3.0.0 eslint-visitor-keys: ^3.3.0 - espree: ^9.4.0 + espree: ^9.5.0 esquery: ^1.4.2 esutils: ^2.0.2 fast-deep-equal: ^3.1.3 @@ -5127,24 +5295,23 @@ __metadata: minimatch: ^3.1.2 natural-compare: ^1.4.0 optionator: ^0.9.1 - regexpp: ^3.2.0 strip-ansi: ^6.0.1 strip-json-comments: ^3.1.0 text-table: ^0.2.0 bin: eslint: bin/eslint.js - checksum: 6212173691d90b1bc94dd3d640e1f210374b30c3905fc0a15e501cf71c6ca52aa3d80ea7a9a245adaaed26d6019169e01fb6881b3f2885b188d37069c749308c + checksum: e9a961fc3b3de5cff5a1cb2c92eeffaa7e155a715489e30b3e1e76f186bd1255e0481e09564f2094733c0b1dbd3453499fb72ae7c043c83156e11e6d965b2304 languageName: node linkType: hard -"espree@npm:^9.4.0": - version: 9.4.1 - resolution: "espree@npm:9.4.1" +"espree@npm:^9.5.0": + version: 9.5.0 + resolution: "espree@npm:9.5.0" dependencies: acorn: ^8.8.0 acorn-jsx: ^5.3.2 eslint-visitor-keys: ^3.3.0 - checksum: 4d266b0cf81c7dfe69e542c7df0f246e78d29f5b04dda36e514eb4c7af117ee6cfbd3280e560571ed82ff6c9c3f0003c05b82583fc7a94006db7497c4fe4270e + checksum: a7f110aefb6407e0d3237aa635ab3cea87106ae63748dd23c67031afccc640d04c4209fca2daf16e2233c82efb505faead0fb84097478fd9cc6e8f8dd80bf99d languageName: node linkType: hard @@ -5166,6 +5333,13 @@ __metadata: languageName: node linkType: hard +"estraverse@npm:^4.1.1": + version: 4.3.0 + resolution: "estraverse@npm:4.3.0" + checksum: a6299491f9940bb246124a8d44b7b7a413a8336f5436f9837aaa9330209bd9ee8af7e91a654a3545aee9c54b3308e78ee360cef1d777d37cfef77d2fa33b5827 + languageName: node + linkType: hard + "estraverse@npm:^5.1.0, estraverse@npm:^5.2.0, estraverse@npm:^5.3.0": version: 5.3.0 resolution: "estraverse@npm:5.3.0" @@ -8141,6 +8315,13 @@ __metadata: languageName: node linkType: hard +"natural-compare-lite@npm:^1.4.0": + version: 1.4.0 + resolution: "natural-compare-lite@npm:1.4.0" + checksum: 5222ac3986a2b78dd6069ac62cbb52a7bf8ffc90d972ab76dfe7b01892485d229530ed20d0c62e79a6b363a663b273db3bde195a1358ce9e5f779d4453887225 + languageName: node + linkType: hard + "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -9680,13 +9861,6 @@ __metadata: languageName: node linkType: hard -"regexpp@npm:^3.2.0": - version: 3.2.0 - resolution: "regexpp@npm:3.2.0" - checksum: a78dc5c7158ad9ddcfe01aa9144f46e192ddbfa7b263895a70a5c6c73edd9ce85faf7c0430e59ac38839e1734e275b9c3de5c57ee3ab6edc0e0b1bdebefccef8 - languageName: node - linkType: hard - "remark-gfm@npm:^3.0.1": version: 3.0.1 resolution: "remark-gfm@npm:3.0.1" @@ -11070,23 +11244,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^4.9.5": - version: 4.9.5 - resolution: "typescript@npm:4.9.5" +"typescript@npm:^5.0.2": + version: 5.0.2 + resolution: "typescript@npm:5.0.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: ee000bc26848147ad423b581bd250075662a354d84f0e06eb76d3b892328d8d4440b7487b5a83e851b12b255f55d71835b008a66cbf8f255a11e4400159237db + checksum: bef1dcd166acfc6934b2ec4d72f93edb8961a5fab36b8dd2aaf6f4f4cd5c0210f2e0850aef4724f3b4913d5aef203a94a28ded731b370880c8bcff7e4ff91fc1 languageName: node linkType: hard -"typescript@patch:typescript@^4.9.5#~builtin": - version: 4.9.5 - resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=ad5954" +"typescript@patch:typescript@^5.0.2#~builtin": + version: 5.0.2 + resolution: "typescript@patch:typescript@npm%3A5.0.2#~builtin::version=5.0.2&hash=ad5954" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 8f6260acc86b56bfdda6004bc53f32ea548f543e8baef7071c8e34d29d292f3e375c8416556c8de10b24deef6933cd1c16a8233dc84a3dd43a13a13265d0faab + checksum: bdbf3d0aac0d6cf010fbe0536753dc19f278eb4aba88140dcd25487dfe1c56ca8b33abc0dcd42078790a939b08ebc4046f3e9bb961d77d3d2c3cfa9829da4d53 languageName: node linkType: hard @@ -11713,16 +11887,19 @@ __metadata: "@types/qrcode": ^1.5.0 "@types/react": ^18.0.28 "@types/sharp": ^0.31.1 + "@typescript-eslint/eslint-plugin": ^5.56.0 + "@typescript-eslint/parser": ^5.56.0 argon2: ^0.30.3 cookie: ^0.5.0 cross-env: ^7.0.3 dayjs: ^1.11.7 dotenv: ^16.0.3 dotenv-expand: ^10.0.0 - eslint: ^8.35.0 + eslint: ^8.36.0 eslint-config-next: ^13.2.1 eslint-config-prettier: ^8.6.0 eslint-plugin-prettier: ^4.2.1 + eslint-plugin-unused-imports: ^2.0.0 exiftool-vendored: ^21.2.0 fastify: ^4.13.0 fastify-plugin: ^4.5.0 @@ -11748,7 +11925,7 @@ __metadata: remark-gfm: ^3.0.1 sharp: ^0.31.3 tsup: ^6.6.3 - typescript: ^4.9.5 + typescript: ^5.0.2 languageName: unknown linkType: soft