Skip to content

Commit

Permalink
* add option for rule @typescript-eslint/restrict-template-expressions
Browse files Browse the repository at this point in the history
* fix `Parse errors in imported module '': parserPath or languageOptions.parser is required!`:  un-ts/eslint-plugin-import-x#85 (comment)
@ eslint.config.js

* re-plug eslint: pzmosquito/eslint-import-resolver-vite#12 (comment) @ package.json
* fix some violations of eslint rules
@ fe
  • Loading branch information
n0099 committed Jun 6, 2024
1 parent 07865ef commit c3fb25a
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 35 deletions.
36 changes: 22 additions & 14 deletions fe/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ const rules = [{ // as of eslint-plugin-unicorn@50.0.1
'@typescript-eslint/no-unsafe-enum-comparison': 'error',
'@typescript-eslint/no-unsafe-unary-minus': 'error',
'@typescript-eslint/parameter-properties': ['error', { prefer: 'parameter-property' }],
'@typescript-eslint/restrict-template-expressions': ['error', { allowNumber: true }],
},
}, { // as of eslint-plugin-vue@9.19.2
optout: {
Expand Down Expand Up @@ -520,20 +521,25 @@ const rules = [{ // as of eslint-plugin-unicorn@50.0.1
},
}];

import viteConfig from './vite.config.ts';
import pluginStylistic from '@stylistic/eslint-plugin';
import pluginImportX from 'eslint-plugin-import-x';
import pluginUnicorn from 'eslint-plugin-unicorn';
import * as typescriptESLintParserForExtraFiles from 'typescript-eslint-parser-for-extra-files';
import * as vueESLintParser from 'vue-eslint-parser';
// eslint-disable-next-line import-x/extensions
import vueESLintConfigTypescriptRecommendedExtends from '@vue/eslint-config-typescript/recommended.js';
import pluginVue from 'eslint-plugin-vue';
import { fixupConfigRules } from '@eslint/compat';
import { FlatCompat } from '@eslint/eslintrc';
import eslintJs from '@eslint/js';
import pluginStylistic from '@stylistic/eslint-plugin';
import stylisticMigrate from '@stylistic/eslint-plugin-migrate';
import pluginImportX from 'eslint-plugin-import-x';
import pluginUnicorn from 'eslint-plugin-unicorn';
// eslint-disable-next-line import-x/extensions
import { tsImport } from 'tsx/esm/api';
import * as typescriptESLintParserForExtraFiles from 'typescript-eslint-parser-for-extra-files';
import * as _ from 'lodash-es';

// https://github.com/pzmosquito/eslint-import-resolver-vite/issues/12#issuecomment-2151349705
const viteConfig = await tsImport('./vite.config.ts', import.meta.url);

// https://github.com/eslint/eslint/issues/18093
// https://github.com/eslint/eslint/issues/18391
const compat = new FlatCompat();
Expand All @@ -546,8 +552,11 @@ export default [
'plugin:@typescript-eslint/strict-type-checked',
'plugin:@typescript-eslint/stylistic-type-checked',
),
...compat.config(pluginImportX.configs.recommended), // https://github.com/un-ts/eslint-plugin-import-x/issues/29#issuecomment-2148843214
...compat.config(pluginImportX.configs.typescript),
{ // https://github.com/un-ts/eslint-plugin-import-x/pull/85#issuecomment-2153376351
plugins: { 'import-x': { rules: pluginImportX.rules } },
rules: pluginImportX.configs.recommended.rules,
}, // https://github.com/import-js/eslint-plugin-import/issues/2556#issuecomment-2119520339
pluginImportX.configs.typescript,
...fixupConfigRules(...compat.extends(
'plugin:@tanstack/eslint-plugin-query/recommended', // https://github.com/TanStack/query/pull/7253
)),
Expand All @@ -562,6 +571,12 @@ export default [
tsconfigRootDir: import.meta.dirname,
},
},
settings: {
'import-x/resolver': {
typescript: true,
vite: { viteConfig }, // https://github.com/pzmosquito/eslint-import-resolver-vite/issues/12#issuecomment-2148676875
},
},
plugins: { '@stylistic': pluginStylistic },

// https://stackoverflow.com/questions/30221286/how-to-convert-an-array-of-objects-to-an-object-in-lodash/36692117#36692117
Expand All @@ -576,7 +591,6 @@ export default [
{
files: ['**/*.ts'],
languageOptions: { parser: typescriptESLintParserForExtraFiles },
settings: { 'import-x/resolver': { typescript: true } },
},
{
files: ['**/*.vue'],
Expand All @@ -588,12 +602,6 @@ export default [
tsconfigRootDir: import.meta.dirname,
},
},
settings: {
'import-x/resolver': {
typescript: true,
vite: { viteConfig }, // https://github.com/pzmosquito/eslint-import-resolver-vite/issues/12#issuecomment-2148676875
},
},
},
{
files: ['eslint.config.js'],
Expand Down
10 changes: 2 additions & 8 deletions fe/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"preview": "vite preview",
"eslint": "tsx .yarn/unplugged/eslint-npm-*/node_modules/eslint/bin/eslint.js"
"preview": "vite preview"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.5.2",
Expand Down Expand Up @@ -81,10 +80,5 @@
"not ie 11",
"not dead"
],
"packageManager": "yarn@4.2.2",
"dependenciesMeta": {
"eslint@9.4.0": {
"unplugged": true
}
}
"packageManager": "yarn@4.2.2"
}
11 changes: 6 additions & 5 deletions fe/src/components/Post/queryForm/useQueryForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as _ from 'lodash-es';
export interface UnknownParam { name: string, value: unknown, subParam: ObjUnknown & { not?: boolean } }
export interface NamelessUnknownParam { value?: unknown, subParam?: ObjUnknown }
export type ParamPreprocessorOrWatcher = (p: UnknownParam) => void;
export default <
const useQueryForm = <
UniqueParams extends Record<string, UnknownParam> = Record<string, UnknownParam>,
Params extends Record<string, UnknownParam> = Record<string, UnknownParam>
>(
Expand All @@ -29,7 +29,7 @@ export default <
const fillParamDefaultValue = <T extends Param | UniqueParam>
(param: Partial<UnknownParam> & { name: string }, resetToDefault = false): T => {
// prevent defaultsDeep mutate origin paramsDefaultValue
const defaultParam = _.cloneDeep(deps.paramsDefaultValue[param.name]);
const defaultParam = structuredClone(deps.paramsDefaultValue[param.name]);
if (defaultParam === undefined)
throw new Error(`Param ${param.name} not found in paramsDefaultValue`);
defaultParam.subParam ??= {};
Expand All @@ -39,7 +39,7 @@ export default <
if (resetToDefault)
return _.defaultsDeep(defaultParam, param) as T;

return _.defaultsDeep(_.cloneDeep(param), defaultParam) as T;
return _.defaultsDeep(structuredClone(param), defaultParam) as T;
};
const addParam = (name: string) => {
params.value.push(fillParamDefaultValue({ name }));
Expand All @@ -57,14 +57,14 @@ export default <
params.value.splice(paramIndex, 1);
};
const clearParamDefaultValue = <T extends UnknownParam>(param: UnknownParam): Partial<T | UnknownParam> | null => {
const defaultParam = _.cloneDeep(deps.paramsDefaultValue[param.name]);
const defaultParam = structuredClone(deps.paramsDefaultValue[param.name]);
if (defaultParam === undefined)
throw new Error(`Param ${param.name} not found in paramsDefaultValue`);

/** remove subParam.not: false, which previously added by {@link fillParamDefaultValue()} */
if (defaultParam.subParam !== undefined)
defaultParam.subParam.not ??= false;
const newParam: Partial<UnknownParam> = _.cloneDeep(param); // prevent mutating origin param
const newParam: Partial<UnknownParam> = structuredClone(param); // prevent mutating origin param
/** number will consider as empty in {@link _.isEmpty()} */
// to prevent this we use complex short circuit evaluate expression
if (!(_.isNumber(newParam.value) || !_.isEmpty(newParam.value))
Expand Down Expand Up @@ -223,3 +223,4 @@ export default <
generateParamRoute
};
};
export default useQueryForm;
2 changes: 1 addition & 1 deletion fe/src/components/Post/renderers/list/RendererList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export type ThreadWithGroupedSubReplies<AdditionalSubReply extends SubReply = ne
Thread & { replies: Array<Reply & { subReplies: Array<AdditionalSubReply | SubReply[]> }> };
const posts = computed(() => {
// https://github.com/microsoft/TypeScript/issues/33591
const newPosts = _.cloneDeep(props.initialPosts) as
const newPosts = structuredClone(props.initialPosts) as
Modify<ApiPosts['response'], { threads: Array<ThreadWithGroupedSubReplies<SubReply>> }>;
newPosts.threads = newPosts.threads.map(thread => {
thread.replies = thread.replies.map(reply => {
Expand Down
4 changes: 2 additions & 2 deletions fe/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import App from '@/App.vue';
import router from '@/router';
import '@/styles/style.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import { VueQueryPlugin } from '@tanstack/vue-query';
import { createHead } from '@unhead/vue';
import 'bootstrap';

Check failure on line 8 in fe/src/main.ts

View workflow job for this annotation

GitHub Actions / eslint

`bootstrap` import should occur before import of `vue`
import 'bootstrap/dist/css/bootstrap.min.css';
import 'noty/lib/noty.css';
import 'noty/lib/themes/mint.css';
import nprogress from 'nprogress';
Expand All @@ -15,7 +15,7 @@ import 'nprogress/nprogress.css';
nprogress.configure({ trickleSpeed: 200 });

if (import.meta.env.DEV) {
// @ts-expect-error no .d.ts
// @ts-expect-error too small to write a .d.ts for it
await import('@/stats');
await import('@/checkCSS');
}
Expand Down
5 changes: 4 additions & 1 deletion fe/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ const lazyLoadRouteView = async (lazyComponent: Promise<Component>) => {
routeLazyComponent.isLoading = true;

return lazyComponent
.catch((e: Error) => { notyShow('error', `${e.name}<br />${e.message}`) })
.catch((e: unknown) => {
if (e instanceof Error)
notyShow('error', `${e.name}<br />${e.message}`);
})
.finally(() => { routeLazyComponent.isLoading = false });
};

Expand Down
2 changes: 1 addition & 1 deletion fe/src/views/BilibiliVote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ const loadCharts = {
});
// clone last timeline option then transform it to official votes count option
const originalTimelineOptions = _.cloneDeep(options.at(-1));
const originalTimelineOptions = structuredClone(options.at(-1));
if (originalTimelineOptions === undefined || !_.isArray(originalTimelineOptions.series))
return;
_.remove(originalTimelineOptions.series, { id: 'totalVotesValidation' });
Expand Down
3 changes: 0 additions & 3 deletions fe/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5685,9 +5685,6 @@ __metadata:
vue-eslint-parser: "npm:^9.4.3"
vue-router: "npm:^4.3.2"
vue-tsc: "npm:^2.0.19"
dependenciesMeta:
eslint@9.4.0:
unplugged: true
languageName: unknown
linkType: soft

Expand Down

0 comments on commit c3fb25a

Please sign in to comment.