chore: migrate eslint 9 (#7588)

#### What type of PR is this?

/area ui
/kind cleanup

#### What this PR does / why we need it:

Migrate to ESLint 9, use flat config file, and simplify ESLint configuration.

Now, linting for all packages will be managed by the configuration in the project root directory.

#### Does this PR introduce a user-facing change?

```release-note
None
```
pull/7589/head
Ryan Wang 2025-06-25 08:37:20 +08:00 committed by GitHub
parent 0addf79aec
commit 1826c7dcbb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
51 changed files with 633 additions and 422 deletions

View File

@ -1,25 +0,0 @@
/* eslint-env node */
require("@rushstack/eslint-patch/modern-module-resolution");
module.exports = {
root: true,
extends: [
"plugin:vue/vue3-recommended",
"eslint:recommended",
"@vue/eslint-config-typescript/recommended",
"@vue/eslint-config-prettier",
],
env: {
node: true,
"vue/setup-compiler-macros": true,
},
rules: {
"vue/multi-word-component-names": 0,
"@typescript-eslint/ban-ts-comment": 0,
"vue/no-v-html": 0,
},
ignorePatterns: ["!.storybook", "packages/api-client"],
parserOptions: {
ecmaVersion: "latest",
},
};

View File

@ -1,4 +1,4 @@
<script setup lang="tsx"> <script setup lang="ts">
import type { OwnerInfo } from "@halo-dev/api-client"; import type { OwnerInfo } from "@halo-dev/api-client";
import { VAvatar } from "@halo-dev/components"; import { VAvatar } from "@halo-dev/components";

View File

@ -118,7 +118,6 @@ export function convertCategoryTreeToCategory(
): Category { ): Category {
const childNames = categoryTree.children.map((child) => child.metadata.name); const childNames = categoryTree.children.map((child) => child.metadata.name);
// eslint-disable-next-line
const { children: _, ...categoryWithoutChildren } = categoryTree; const { children: _, ...categoryWithoutChildren } = categoryTree;
return { return {

View File

@ -96,7 +96,7 @@ async function handleChange(value: string) {
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: Q_KEY(extensionPointDefinitionName), queryKey: Q_KEY(extensionPointDefinitionName),
}); });
} catch (error) { } catch (_) {
Toast.error(t("core.common.toast.save_failed_and_retry")); Toast.error(t("core.common.toast.save_failed_and_retry"));
} finally { } finally {
isSubmitting.value = false; isSubmitting.value = false;

View File

@ -36,7 +36,9 @@ export function useUserFetch(options?: {
}; };
onMounted(() => { onMounted(() => {
fetchOnMounted && handleFetchUsers(); if (fetchOnMounted) {
handleFetchUsers();
}
}); });
return { return {

54
ui/eslint.config.ts Normal file
View File

@ -0,0 +1,54 @@
import pluginVitest from "@vitest/eslint-plugin";
import skipFormatting from "@vue/eslint-config-prettier/skip-formatting";
import {
defineConfigWithVueTs,
vueTsConfigs,
} from "@vue/eslint-config-typescript";
import pluginVue from "eslint-plugin-vue";
export default defineConfigWithVueTs(
{
name: "app/global-ignores",
ignores: ["**/dist/**", "**/node_modules/**", "packages/api-client/src/"],
},
pluginVue.configs["flat/recommended"],
vueTsConfigs.recommended,
{
name: "app/base",
files: ["**/*.{ts,mts,tsx,vue}"],
rules: {
"vue/multi-word-component-names": 0,
"@typescript-eslint/ban-ts-comment": 0,
"vue/no-v-html": 0,
"@typescript-eslint/no-unused-vars": [
"error",
{
args: "all",
argsIgnorePattern: "^_",
caughtErrors: "all",
caughtErrorsIgnorePattern: "^_",
destructuredArrayIgnorePattern: "^_",
varsIgnorePattern: "^_",
ignoreRestSiblings: true,
},
],
},
},
{
name: "app/config-files",
files: ["**/*.config.{js,cjs}"],
rules: {
"@typescript-eslint/no-require-imports": "off",
},
},
{
...pluginVitest.configs.recommended,
files: ["**/__tests__/*"],
},
skipFormatting
);

View File

@ -18,10 +18,9 @@
"test:unit:ui": "vitest --watch --ui", "test:unit:ui": "vitest --watch --ui",
"test:unit:coverage": "vitest run --coverage", "test:unit:coverage": "vitest run --coverage",
"typecheck": "vue-tsc --noEmit -p tsconfig.app.json --composite false && pnpm run typecheck:packages", "typecheck": "vue-tsc --noEmit -p tsconfig.app.json --composite false && pnpm run typecheck:packages",
"lint": "eslint \"./src\" \"./console-src\" \"./uc-src\" --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --ignore-path .gitignore --max-warnings=0 -f html -o build/lint-result/index.html && pnpm run lint:packages", "lint": "eslint . --max-warnings=0 -f html -o build/lint-result/index.html",
"prettier": "prettier --write \"./{src,uc-src,console-src}/**/*.{vue,js,jsx,ts,tsx,css,scss,json,yml,yaml,html}\" && pnpm run prettier:packages", "prettier": "prettier --write \"./{src,uc-src,console-src}/**/*.{vue,js,jsx,ts,tsx,css,scss,json,yml,yaml,html}\" && pnpm run prettier:packages",
"typecheck:packages": "pnpm --parallel --filter \"./packages/**\" run typecheck", "typecheck:packages": "pnpm --parallel --filter \"./packages/**\" run typecheck",
"lint:packages": "pnpm --parallel --filter \"./packages/**\" lint",
"prettier:packages": "pnpm --parallel --filter \"./packages/**\" prettier", "prettier:packages": "pnpm --parallel --filter \"./packages/**\" prettier",
"test:unit:packages": "pnpm --parallel --filter \"./packages/**\" run test:unit" "test:unit:packages": "pnpm --parallel --filter \"./packages/**\" run test:unit"
}, },
@ -29,7 +28,7 @@
"*.{vue,js,jsx,ts,tsx,css,scss,json,yml,yaml,html}": [ "*.{vue,js,jsx,ts,tsx,css,scss,json,yml,yaml,html}": [
"prettier --write" "prettier --write"
], ],
"*.{js,ts,vue,tsx,jsx}": [ "*.{ts,mts,tsx,vue}": [
"eslint --fix --max-warnings=0" "eslint --fix --max-warnings=0"
] ]
}, },
@ -113,7 +112,6 @@
"@iconify/json": "^2.2.343", "@iconify/json": "^2.2.343",
"@intlify/unplugin-vue-i18n": "^6.0.8", "@intlify/unplugin-vue-i18n": "^6.0.8",
"@number-flow/vue": "^0.4.8", "@number-flow/vue": "^0.4.8",
"@rushstack/eslint-patch": "^1.3.2",
"@tailwindcss/aspect-ratio": "^0.4.2", "@tailwindcss/aspect-ratio": "^0.4.2",
"@tailwindcss/container-queries": "^0.1.0", "@tailwindcss/container-queries": "^0.1.0",
"@tailwindcss/forms": "^0.5.7", "@tailwindcss/forms": "^0.5.7",
@ -126,17 +124,18 @@
"@types/randomstring": "^1.1.8", "@types/randomstring": "^1.1.8",
"@types/ua-parser-js": "^0.7.39", "@types/ua-parser-js": "^0.7.39",
"@typescript/native-preview": "7.0.0-dev.20250619.1", "@typescript/native-preview": "7.0.0-dev.20250619.1",
"@vitest/eslint-plugin": "^1.2.7",
"@vitejs/plugin-vue": "^6.0.0", "@vitejs/plugin-vue": "^6.0.0",
"@vitejs/plugin-vue-jsx": "^5.0.0", "@vitejs/plugin-vue-jsx": "^5.0.0",
"@vitest/ui": "^3.1.4", "@vitest/ui": "^3.1.4",
"@vue/compiler-sfc": "^3.5.16", "@vue/compiler-sfc": "^3.5.16",
"@vue/eslint-config-prettier": "^7.1.0", "@vue/eslint-config-prettier": "^10.2.0",
"@vue/eslint-config-typescript": "^11.0.3", "@vue/eslint-config-typescript": "^14.5.0",
"@vue/test-utils": "^2.4.6", "@vue/test-utils": "^2.4.6",
"@vue/tsconfig": "^0.5.1", "@vue/tsconfig": "^0.5.1",
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.14",
"c8": "^7.12.0", "c8": "^7.12.0",
"eslint": "^8.43.0", "eslint": "^9.22.0",
"eslint-plugin-vue": "^9.33.0", "eslint-plugin-vue": "^9.33.0",
"husky": "^8.0.3", "husky": "^8.0.3",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",

View File

@ -1,2 +0,0 @@
dist/*
node_modules/*

View File

@ -1,3 +0,0 @@
module.exports = {
extends: ["../../.eslintrc.cjs"],
};

View File

@ -1 +0,0 @@
.storybook

View File

@ -1,3 +0,0 @@
module.exports = {
extends: ["../../.eslintrc.cjs", "plugin:storybook/recommended"],
};

View File

@ -1,4 +1,3 @@
/* eslint-disable storybook/no-uninstalled-addons */
import type { StorybookConfig } from "@storybook/vue3-vite"; import type { StorybookConfig } from "@storybook/vue3-vite";
const config: StorybookConfig = { const config: StorybookConfig = {

View File

@ -18,7 +18,6 @@
"test:unit:ui": "vitest --watch --ui", "test:unit:ui": "vitest --watch --ui",
"test:unit:coverage": "vitest run --coverage", "test:unit:coverage": "vitest run --coverage",
"typecheck": "vue-tsc --noEmit -p tsconfig.app.json --composite false", "typecheck": "vue-tsc --noEmit -p tsconfig.app.json --composite false",
"lint": "eslint ./src --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts",
"prettier": "prettier --write './src/**/*.{vue,js,jsx,ts,tsx,css,scss,json,yml,yaml,html}'", "prettier": "prettier --write './src/**/*.{vue,js,jsx,ts,tsx,css,scss,json,yml,yaml,html}'",
"storybook": "storybook dev -p 6006", "storybook": "storybook dev -p 6006",
"build-storybook": "storybook build" "build-storybook": "storybook build"
@ -52,7 +51,6 @@
"@storybook/testing-library": "^0.0.14-next.2", "@storybook/testing-library": "^0.0.14-next.2",
"@storybook/vue3": "^7.6.3", "@storybook/vue3": "^7.6.3",
"@storybook/vue3-vite": "^7.6.3", "@storybook/vue3-vite": "^7.6.3",
"eslint-plugin-storybook": "^0.6.15",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"storybook": "^7.6.3" "storybook": "^7.6.3"

View File

@ -43,7 +43,7 @@ const loadImage = async (isInit: boolean) => {
reject(err); reject(err);
}; };
}); });
} catch (e) { } catch (_) {
error.value = true; error.value = true;
} finally { } finally {
isLoading.value = false; isLoading.value = false;

View File

@ -52,10 +52,13 @@ const dialog: DialogEntry = (userProps: DialogProps) => {
props props
); );
hostContainer.firstElementChild && if (hostContainer.firstElementChild) {
container.appendChild(hostContainer.firstElementChild); container.appendChild(hostContainer.firstElementChild);
}
vnode.component?.props && (vnode.component.props.visible = true); if (vnode.component?.props) {
vnode.component.props.visible = true;
}
if (vnode?.props) { if (vnode?.props) {
vnode.props.onClose = () => { vnode.props.onClose = () => {

View File

@ -1,6 +0,0 @@
module.exports = {
extends: ["../../.eslintrc.cjs"],
rules: {
"@typescript-eslint/no-explicit-any": "off",
},
};

View File

@ -31,7 +31,6 @@
"scripts": { "scripts": {
"build": "vite build --config ./vite.lib.config.ts", "build": "vite build --config ./vite.lib.config.ts",
"dev": "vite", "dev": "vite",
"lint": "eslint ./src --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts",
"prettier": "prettier --write './src/**/*.{vue,js,jsx,ts,tsx,css,scss,json,yml,yaml,html}'", "prettier": "prettier --write './src/**/*.{vue,js,jsx,ts,tsx,css,scss,json,yml,yaml,html}'",
"release": "release-it", "release": "release-it",
"test:unit:coverage": "vitest run --environment jsdom --coverage", "test:unit:coverage": "vitest run --environment jsdom --coverage",

View File

@ -8,6 +8,7 @@ export interface Option {
value: string; value: string;
} }
const props = defineProps<{ const props = defineProps<{
// eslint-disable-next-line @typescript-eslint/no-explicit-any
container?: any; container?: any;
containerClass?: string; containerClass?: string;
options: Option[]; options: Option[];

View File

@ -41,7 +41,7 @@ const updateIndent = (tr: Transaction, type: IndentType): Transaction => {
return tr; return tr;
} }
const { from, to } = selection; const { from, to } = selection;
doc.nodesBetween(from, to, (node, pos) => { doc.nodesBetween(from, to, (_node, pos) => {
if (from - to == 0 && type === "indent") { if (from - to == 0 && type === "indent") {
tr.insertText(" ", from, to); tr.insertText(" ", from, to);
return false; return false;
@ -111,6 +111,7 @@ export interface CodeBlockOptions {
* @default {} * @default {}
* @example { class: 'foo' } * @example { class: 'foo' }
*/ */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
HTMLAttributes: Record<string, any>; HTMLAttributes: Record<string, any>;
/** /**

View File

@ -66,6 +66,7 @@ const getColumnsNodeTypes = (
type ColOperateType = "addBefore" | "addAfter" | "delete"; type ColOperateType = "addBefore" | "addAfter" | "delete";
const addOrDeleteCol = ( const addOrDeleteCol = (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
dispatch: any, dispatch: any,
state: EditorState, state: EditorState,
type: ColOperateType type: ColOperateType
@ -103,6 +104,7 @@ const addOrDeleteCol = (
colsJSON.attrs.cols = colsJSON.content.length; colsJSON.attrs.cols = colsJSON.content.length;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
colsJSON.content.forEach((colJSON: any, index: number) => { colsJSON.content.forEach((colJSON: any, index: number) => {
colJSON.attrs.index = index; colJSON.attrs.index = index;
}); });
@ -110,7 +112,7 @@ const addOrDeleteCol = (
const nextCols = PMNode.fromJSON(state.schema, colsJSON); const nextCols = PMNode.fromJSON(state.schema, colsJSON);
let nextSelectPos = maybeColumns.pos; let nextSelectPos = maybeColumns.pos;
nextCols.content.forEach((col, pos, index) => { nextCols.content.forEach((col, _pos, index) => {
if (index < nextIndex) { if (index < nextIndex) {
nextSelectPos += col.nodeSize; nextSelectPos += col.nodeSize;
} }
@ -130,6 +132,7 @@ const addOrDeleteCol = (
}; };
type GotoColType = "before" | "after"; type GotoColType = "before" | "after";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const gotoCol = (state: EditorState, dispatch: any, type: GotoColType) => { const gotoCol = (state: EditorState, dispatch: any, type: GotoColType) => {
const maybeColumns = findParentNode( const maybeColumns = findParentNode(
(node) => node.type.name === Columns.name (node) => node.type.name === Columns.name
@ -151,7 +154,7 @@ const gotoCol = (state: EditorState, dispatch: any, type: GotoColType) => {
} }
let nextSelectPos = maybeColumns.pos; let nextSelectPos = maybeColumns.pos;
cols.content.forEach((col, pos, index) => { cols.content.forEach((col, _pos, index) => {
if (index < nextIndex) { if (index < nextIndex) {
nextSelectPos += col.nodeSize; nextSelectPos += col.nodeSize;
} }

View File

@ -47,6 +47,7 @@ export default Extension.create({
let popup: Instance[]; let popup: Instance[];
return { return {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onStart: (props: Record<string, any>) => { onStart: (props: Record<string, any>) => {
component = new VueRenderer(CommandsView, { component = new VueRenderer(CommandsView, {
props, props,
@ -68,6 +69,7 @@ export default Extension.create({
}); });
}, },
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onUpdate(props: Record<string, any>) { onUpdate(props: Record<string, any>) {
component.updateProps(props); component.updateProps(props);
@ -80,6 +82,7 @@ export default Extension.create({
}); });
}, },
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onKeyDown(props: Record<string, any>) { onKeyDown(props: Record<string, any>) {
if (props.event.key === "Escape") { if (props.event.key === "Escape") {
popup[0].hide(); popup[0].hide();

View File

@ -33,6 +33,7 @@ let draggableHandleDom: HTMLElement | null = null;
let currEditorView: EditorView; let currEditorView: EditorView;
let activeNode: ActiveNode | null = null; let activeNode: ActiveNode | null = null;
let activeSelection: NodeSelection | null = null; let activeSelection: NodeSelection | null = null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let mouseleaveTimer: any; let mouseleaveTimer: any;
let dragging = false; let dragging = false;
let hoverOrClickDragItem = false; let hoverOrClickDragItem = false;
@ -161,6 +162,7 @@ const handleDragStartEvent = (event: DragEvent) => {
event.dataTransfer.clearData(); event.dataTransfer.clearData();
event.dataTransfer.setData("text/html", dom.innerHTML); event.dataTransfer.setData("text/html", dom.innerHTML);
event.dataTransfer.setData("text/plain", text); event.dataTransfer.setData("text/plain", text);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
event.dataTransfer.setDragImage(activeNode?.el as any, 0, 0); event.dataTransfer.setDragImage(activeNode?.el as any, 0, 0);
currEditorView.dragging = { currEditorView.dragging = {
@ -289,6 +291,7 @@ const getDraggableItem = ({
editor: Editor; editor: Editor;
view: EditorView; view: EditorView;
dom: HTMLElement; dom: HTMLElement;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
event?: any; event?: any;
depth?: number; depth?: number;
}): DraggableItemType | boolean | undefined => { }): DraggableItemType | boolean | undefined => {

View File

@ -16,9 +16,11 @@ declare module "@/tiptap" {
export interface FormatBrushStore { export interface FormatBrushStore {
formatBrush: boolean; formatBrush: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
formatBrushMarks: any[]; formatBrushMarks: any[];
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const formatBrush = Extension.create<any, FormatBrushStore>({ const formatBrush = Extension.create<any, FormatBrushStore>({
name: "formatBrush", name: "formatBrush",

View File

@ -30,6 +30,7 @@ class GapCursorSelection extends Selection {
return other instanceof GapCursorSelection && other.head == this.head; return other instanceof GapCursorSelection && other.head == this.head;
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
toJSON(): any { toJSON(): any {
return { type: "node-gap-cursor", pos: this.head }; return { type: "node-gap-cursor", pos: this.head };
} }
@ -38,6 +39,7 @@ class GapCursorSelection extends Selection {
return this.start; return this.start;
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static fromJSON(doc: PMNode, json: any): GapCursorSelection { static fromJSON(doc: PMNode, json: any): GapCursorSelection {
if (typeof json.pos != "number") { if (typeof json.pos != "number") {
throw new RangeError("Invalid input for GapCursorSelection.fromJSON"); throw new RangeError("Invalid input for GapCursorSelection.fromJSON");
@ -144,6 +146,7 @@ class GapCursorSelection extends Selection {
} }
GapCursorSelection.prototype.visible = false; GapCursorSelection.prototype.visible = false;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(GapCursorSelection as any).findFrom = GapCursorSelection.findGapCursorFrom; (GapCursorSelection as any).findFrom = GapCursorSelection.findGapCursorFrom;
Selection.jsonID("node-gap-cursor", GapCursorSelection); Selection.jsonID("node-gap-cursor", GapCursorSelection);

View File

@ -282,6 +282,7 @@ export function arrow(axis: "vert" | "horiz", dir: number): Command {
export const arrowGapCursor = ( export const arrowGapCursor = (
dir: number, dir: number,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
dirStr: any, dirStr: any,
state: EditorState, state: EditorState,
view?: EditorView view?: EditorView

View File

@ -282,7 +282,7 @@ const Blockquote = TiptapHeading.extend<ExtensionOptions & HeadingOptions>({
return [ return [
new Plugin({ new Plugin({
key: new PluginKey("generate-heading-id"), key: new PluginKey("generate-heading-id"),
appendTransaction: (transactions, oldState, newState) => { appendTransaction: (transactions, _oldState, newState) => {
const isChangeHeading = transactions.some((transaction) => { const isChangeHeading = transactions.some((transaction) => {
const composition = this.editor.view.composing; const composition = this.editor.view.composing;
if (beforeComposition !== undefined && !composition) { if (beforeComposition !== undefined && !composition) {

View File

@ -24,6 +24,7 @@ type IndentOptions = {
minIndentLevel: number; minIndentLevel: number;
maxIndentLevel: number; maxIndentLevel: number;
defaultIndentLevel: number; defaultIndentLevel: number;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
HTMLAttributes: Record<string, any>; HTMLAttributes: Record<string, any>;
firstLineIndent: boolean; firstLineIndent: boolean;
}; };

View File

@ -45,6 +45,7 @@ class RangeSelection extends Selection {
return new RangeBookmark(this.anchor, this.head); return new RangeBookmark(this.anchor, this.head);
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
toJSON(): any { toJSON(): any {
return { type: "range", anchor: this.anchor, head: this.head }; return { type: "range", anchor: this.anchor, head: this.head };
} }
@ -125,6 +126,7 @@ class RangeSelection extends Selection {
return new RangeSelection(doc.resolve(anchor), doc.resolve(head)); return new RangeSelection(doc.resolve(anchor), doc.resolve(head));
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static fromJSON(doc: Node, json: any) { static fromJSON(doc: Node, json: any) {
if (typeof json.anchor != "number" || typeof json.head != "number") { if (typeof json.anchor != "number" || typeof json.head != "number") {
throw new RangeError("Invalid input for RangeSelection.fromJSON"); throw new RangeError("Invalid input for RangeSelection.fromJSON");

View File

@ -58,6 +58,7 @@ const findPreviousSearchResult = () => {
props.editor.commands.findPrevious(); props.editor.commands.findPrevious();
}; };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const updateSearchReplace = (value: any) => { const updateSearchReplace = (value: any) => {
const { editor, pluginKey } = props; const { editor, pluginKey } = props;
if (!editor || !pluginKey) { if (!editor || !pluginKey) {

View File

@ -345,7 +345,7 @@ export class SearchAndReplacePluginState {
*/ */
getFullText(doc: PMNode): TextNodesWithPosition[] { getFullText(doc: PMNode): TextNodesWithPosition[] {
const textNodesWithPosition: TextNodesWithPosition[] = []; const textNodesWithPosition: TextNodesWithPosition[] = [];
doc.descendants((node, pos, parent, index) => { doc.descendants((node, pos, _parent, index) => {
if (node.isText) { if (node.isText) {
textNodesWithPosition.push({ textNodesWithPosition.push({
text: `${node.text}`, text: `${node.text}`,

View File

@ -42,6 +42,7 @@ declare module "@/tiptap" {
} }
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const instance = h<any>(SearchAndReplaceVue); const instance = h<any>(SearchAndReplaceVue);
function isShowSearch() { function isShowSearch() {
const searchAndReplaceInstance = instance.component; const searchAndReplaceInstance = instance.component;
@ -95,6 +96,7 @@ const SearchAndReplace = Extension.create<ExtensionOptions>({
dispatch, dispatch,
}: { }: {
state: EditorState; state: EditorState;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
dispatch: ((args?: any) => any) | undefined; dispatch: ((args?: any) => any) | undefined;
}) => { }) => {
const searchAndReplaceState = const searchAndReplaceState =
@ -130,6 +132,7 @@ const SearchAndReplace = Extension.create<ExtensionOptions>({
dispatch, dispatch,
}: { }: {
state: EditorState; state: EditorState;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
dispatch: ((args?: any) => any) | undefined; dispatch: ((args?: any) => any) | undefined;
}) => { }) => {
const searchAndReplaceState = const searchAndReplaceState =
@ -161,6 +164,7 @@ const SearchAndReplace = Extension.create<ExtensionOptions>({
dispatch, dispatch,
}: { }: {
state: EditorState; state: EditorState;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
dispatch: ((args?: any) => any) | undefined; dispatch: ((args?: any) => any) | undefined;
}) => { }) => {
if (dispatch) { if (dispatch) {
@ -187,6 +191,7 @@ const SearchAndReplace = Extension.create<ExtensionOptions>({
dispatch, dispatch,
}: { }: {
state: EditorState; state: EditorState;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
dispatch: ((args?: any) => any) | undefined; dispatch: ((args?: any) => any) | undefined;
}) => { }) => {
if (dispatch) { if (dispatch) {
@ -212,6 +217,7 @@ const SearchAndReplace = Extension.create<ExtensionOptions>({
dispatch, dispatch,
}: { }: {
state: EditorState; state: EditorState;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
dispatch: ((args?: any) => any) | undefined; dispatch: ((args?: any) => any) | undefined;
}) => { }) => {
const searchAndReplaceState = const searchAndReplaceState =
@ -240,6 +246,7 @@ const SearchAndReplace = Extension.create<ExtensionOptions>({
dispatch, dispatch,
}: { }: {
state: EditorState; state: EditorState;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
dispatch: ((args?: any) => any) | undefined; dispatch: ((args?: any) => any) | undefined;
}) => { }) => {
const searchAndReplaceState = const searchAndReplaceState =

View File

@ -54,6 +54,7 @@ function updateColumns(
table: HTMLElement, table: HTMLElement,
cellMinWidth: number, cellMinWidth: number,
overrideCol?: number, overrideCol?: number,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
overrideValue?: any overrideValue?: any
) { ) {
let totalWidth = 0; let totalWidth = 0;

View File

@ -19,6 +19,7 @@ import {
} from "./util"; } from "./util";
export interface TableCellOptions { export interface TableCellOptions {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
HTMLAttributes: Record<string, any>; HTMLAttributes: Record<string, any>;
} }

View File

@ -13,6 +13,7 @@ import MdiPlus from "~icons/mdi/plus";
import { getCellsInRow, isColumnSelected, selectColumn } from "./util"; import { getCellsInRow, isColumnSelected, selectColumn } from "./util";
export interface TableCellOptions { export interface TableCellOptions {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
HTMLAttributes: Record<string, any>; HTMLAttributes: Record<string, any>;
} }

View File

@ -150,6 +150,7 @@ export const findTable = (selection: Selection) => {
| undefined; | undefined;
}; };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const isRectSelected = (rect: any) => (selection: CellSelection) => { export const isRectSelected = (rect: any) => (selection: CellSelection) => {
const map = TableMap.get(selection.$anchorCell.node(-1)); const map = TableMap.get(selection.$anchorCell.node(-1));
const start = selection.$anchorCell.start(-1); const start = selection.$anchorCell.start(-1);
@ -170,10 +171,12 @@ export const isRectSelected = (rect: any) => (selection: CellSelection) => {
return true; return true;
}; };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const isCellSelection = (selection: any) => { export const isCellSelection = (selection: any) => {
return selection instanceof CellSelection; return selection instanceof CellSelection;
}; };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const isColumnSelected = (columnIndex: number) => (selection: any) => { export const isColumnSelected = (columnIndex: number) => (selection: any) => {
if (isCellSelection(selection)) { if (isCellSelection(selection)) {
const map = TableMap.get(selection.$anchorCell.node(-1)); const map = TableMap.get(selection.$anchorCell.node(-1));
@ -199,6 +202,7 @@ export const isColumnSelected = (columnIndex: number) => (selection: any) => {
return false; return false;
}; };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const isRowSelected = (rowIndex: number) => (selection: any) => { export const isRowSelected = (rowIndex: number) => (selection: any) => {
if (isCellSelection(selection)) { if (isCellSelection(selection)) {
const map = TableMap.get(selection.$anchorCell.node(-1)); const map = TableMap.get(selection.$anchorCell.node(-1));
@ -223,6 +227,7 @@ export const isRowSelected = (rowIndex: number) => (selection: any) => {
return false; return false;
}; };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const isTableSelected = (selection: any) => { export const isTableSelected = (selection: any) => {
if (isCellSelection(selection)) { if (isCellSelection(selection)) {
const map = TableMap.get(selection.$anchorCell.node(-1)); const map = TableMap.get(selection.$anchorCell.node(-1));

View File

@ -6,6 +6,7 @@ import { Extension } from "@/tiptap/vue-3";
* @param {Array | object} args.types possible types * @param {Array | object} args.types possible types
* @param {object} args.node node to check * @param {object} args.node node to check
*/ */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function nodeEqualsType({ types, node }: { types: any; node: any }) { function nodeEqualsType({ types, node }: { types: any; node: any }) {
return ( return (
(Array.isArray(types) && types.includes(node.type)) || node.type === types (Array.isArray(types) && types.includes(node.type)) || node.type === types

View File

@ -3,9 +3,9 @@
// see https://github.com/ueberdosis/tiptap/pull/5160 // see https://github.com/ueberdosis/tiptap/pull/5160
const ATTR_WHITESPACE = const ATTR_WHITESPACE =
/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g; // eslint-disable-line no-control-regex /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
const IS_ALLOWED_URI = const IS_ALLOWED_URI =
/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i; // eslint-disable-line no-useless-escape /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i;
export function isAllowedUri(uri: string | undefined) { export function isAllowedUri(uri: string | undefined) {
return !uri || uri.replace(ATTR_WHITESPACE, "").match(IS_ALLOWED_URI); return !uri || uri.replace(ATTR_WHITESPACE, "").match(IS_ALLOWED_URI);

View File

@ -1,3 +0,0 @@
module.exports = {
extends: ["../../.eslintrc.cjs"],
};

View File

@ -30,7 +30,6 @@
"scripts": { "scripts": {
"build": "tsdown", "build": "tsdown",
"dev": "tsdown --watch", "dev": "tsdown --watch",
"lint": "eslint ./src --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts",
"prettier": "prettier --write './src/**/*.{vue,js,jsx,ts,tsx,css,scss,json,yml,yaml,html}'", "prettier": "prettier --write './src/**/*.{vue,js,jsx,ts,tsx,css,scss,json,yml,yaml,html}'",
"typecheck": "tsc --noEmit -p tsconfig.app.json --composite false" "typecheck": "tsc --noEmit -p tsconfig.app.json --composite false"
}, },

View File

@ -1,2 +0,0 @@
dist/*
node_modules/*

View File

@ -1,3 +0,0 @@
module.exports = {
extends: ["../../.eslintrc.cjs"],
};

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@ onMounted(async () => {
isLoading.value = true; isLoading.value = true;
try { try {
await loadImage(); await loadImage();
} catch (e) { } catch (_) {
error.value = true; error.value = true;
} finally { } finally {
isLoading.value = false; isLoading.value = false;

View File

@ -89,7 +89,7 @@ const uppy = computed(() => {
return new Error(message); return new Error(message);
} }
} }
} catch (e) { } catch (_) {
const responseBody = response as XMLHttpRequest; const responseBody = response as XMLHttpRequest;
const { status, statusText } = responseBody; const { status, statusText } = responseBody;
const defaultMessage = [status, statusText].join(": "); const defaultMessage = [status, statusText].join(": ");

View File

@ -32,7 +32,7 @@ onMounted(async () => {
isLoading.value = true; isLoading.value = true;
try { try {
await loadVideo(); await loadVideo();
} catch (e) { } catch (_) {
error.value = true; error.value = true;
} finally { } finally {
isLoading.value = false; isLoading.value = false;

View File

@ -93,7 +93,9 @@ export function useContentCache(
(c: ContentCache) => c.name === "" (c: ContentCache) => c.name === ""
); );
} }
index > -1 && content_caches.value.splice(index, 1); if (index > -1) {
content_caches.value.splice(index, 1);
}
}; };
return { return {

View File

@ -59,20 +59,23 @@ function listFeature(node: FormKitNode) {
const fns = node.context.fns; const fns = node.context.fns;
fns.createShift = (index: number, offset: number) => () => { fns.createShift = (index: number, offset: number) => () => {
const value = node._value as unknown[]; const value = node._value as unknown[];
value.splice(index + offset, 0, value.splice(index, 1)[0]), value.splice(index + offset, 0, value.splice(index, 1)[0]);
node.input(value, false); node.input(value, false);
}; };
fns.createInsert = (index: number) => () => { fns.createInsert = (index: number) => () => {
const value = node._value as unknown[]; const value = node._value as unknown[];
value.splice(index + 1, 0, fn(node)), node.input(value, false); value.splice(index + 1, 0, fn(node));
node.input(value, false);
}; };
fns.createAppend = () => () => { fns.createAppend = () => () => {
const value = node._value as unknown[]; const value = node._value as unknown[];
value.push(fn(node)), node.input(value, false); value.push(fn(node));
node.input(value, false);
}; };
fns.createRemover = (index: number) => () => { fns.createRemover = (index: number) => () => {
const value = node._value as unknown[]; const value = node._value as unknown[];
value.splice(index, 1), node.input(value, false); value.splice(index, 1);
node.input(value, false);
}; };
} }
} }

View File

@ -9,7 +9,7 @@ export const repeats = function (node: FormKitNode) {
type FnType = (index: number) => object; type FnType = (index: number) => object;
function createValue(num: number, fn: FnType) { function createValue(num: number, fn: FnType) {
return new Array(num).fill("").map((value, index) => fn(index)); return new Array(num).fill("").map((_, index) => fn(index));
} }
function repeaterFeature(node: FormKitNode) { function repeaterFeature(node: FormKitNode) {
@ -50,20 +50,23 @@ function repeaterFeature(node: FormKitNode) {
const fns = node.context.fns; const fns = node.context.fns;
fns.createShift = (index: number, offset: number) => () => { fns.createShift = (index: number, offset: number) => () => {
const value = node._value as unknown[]; const value = node._value as unknown[];
value.splice(index + offset, 0, value.splice(index, 1)[0]), value.splice(index + offset, 0, value.splice(index, 1)[0]);
node.input(value, false); node.input(value, false);
}; };
fns.createInsert = (index: number) => () => { fns.createInsert = (index: number) => () => {
const value = node._value as unknown[]; const value = node._value as unknown[];
value.splice(index + 1, 0, {}), node.input(value, false); value.splice(index + 1, 0, {});
node.input(value, false);
}; };
fns.createAppend = () => () => { fns.createAppend = () => () => {
const value = node._value as unknown[]; const value = node._value as unknown[];
value.push({}), node.input(value, false); value.push({});
node.input(value, false);
}; };
fns.createRemover = (index: number) => () => { fns.createRemover = (index: number) => () => {
const value = node._value as unknown[]; const value = node._value as unknown[];
value.splice(index, 1), node.input(value, false); value.splice(index, 1);
node.input(value, false);
}; };
} }
} }

View File

@ -34,7 +34,9 @@ export function useUserFetch(options?: {
}; };
onMounted(() => { onMounted(() => {
fetchOnMounted && handleFetchUsers(); if (fetchOnMounted) {
handleFetchUsers();
}
}); });
return { return {

View File

@ -4,7 +4,7 @@ import type { Router } from "vue-router";
const whiteList = ["ResetPassword"]; const whiteList = ["ResetPassword"];
export function setupAuthCheckGuard(router: Router) { export function setupAuthCheckGuard(router: Router) {
router.beforeEach((to, from, next) => { router.beforeEach((to, _from, next) => {
if (whiteList.includes(to.name as string)) { if (whiteList.includes(to.name as string)) {
next(); next();
return; return;

View File

@ -3,7 +3,7 @@ import { hasPermission } from "@/utils/permission";
import type { Router } from "vue-router"; import type { Router } from "vue-router";
export function setupPermissionGuard(router: Router) { export function setupPermissionGuard(router: Router) {
router.beforeEach((to, from, next) => { router.beforeEach((to, _from, next) => {
const roleStore = useRoleStore(); const roleStore = useRoleStore();
const { uiPermissions } = roleStore.permissions; const { uiPermissions } = roleStore.permissions;
const { meta } = to; const { meta } = to;