import eslintPluginJsonSchemaValidator from 'eslint-plugin-json-schema-validator'; import eslintPluginJsonc from 'eslint-plugin-jsonc'; import eslintPluginYml from 'eslint-plugin-yml'; import withNuxt from './.nuxt/eslint.config.mjs'; export default withNuxt( { name: 'pronouns-page/ignores', ignores: ['census', 'data', 'dist', 'keys', 'new', 'public', 'pnpm-lock.yaml'], }, { name: 'pronouns-page/typescript/type-info', files: ['*.ts', '*.vue'], rules: { '@typescript-eslint/await-thenable': 'error', '@typescript-eslint/adjacent-overload-signatures': 'warn', '@typescript-eslint/array-type': 'warn', '@typescript-eslint/consistent-indexed-object-style': 'warn', '@typescript-eslint/consistent-type-assertions': 'warn', '@typescript-eslint/consistent-type-definitions': 'warn', '@typescript-eslint/consistent-type-imports': 'warn', '@typescript-eslint/consistent-type-exports': 'warn', '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'warn', '@typescript-eslint/no-unnecessary-type-arguments': 'warn', '@typescript-eslint/no-unnecessary-type-assertion': 'warn', }, languageOptions: { parserOptions: { projectService: true, tsconfigRootDir: import.meta.dirname, }, }, }, { name: 'pronouns-page/typescript/definition', files: ['**/*.d.ts'], rules: { // var is needed for globalThis declaration 'no-var': 'off', }, }, eslintPluginJsonc.configs['flat/recommended-with-jsonc'], { name: 'pronouns-page/json', files: ['**/*.json'], rules: { 'jsonc/array-bracket-newline': ['warn', 'consistent'], 'jsonc/array-bracket-spacing': 'warn', 'jsonc/array-element-newline': ['warn', 'consistent'], 'jsonc/indent': 'warn', 'jsonc/key-spacing': 'warn', 'jsonc/no-irregular-whitespace': 'warn', 'jsonc/object-curly-newline': 'warn', 'jsonc/object-curly-spacing': ['warn', 'always'], 'jsonc/object-property-newline': ['warn', { allowAllPropertiesOnSameLine: true }], '@stylistic/max-len': 'off', }, }, { name: 'pronouns-page/tsconfig', files: ['tsconfig.json'], rules: { 'jsonc/no-comments': 'off', }, }, eslintPluginYml.configs['flat/standard'].map((config) => ({ ...config, files: ['**/*.suml', '**/*.yml'], })), { name: 'pronouns-page/suml', files: ['**/*.suml', '**/*.yml'], rules: { 'yml/flow-mapping-curly-spacing': ['warn', 'always'], 'yml/no-irregular-whitespace': 'off', 'yml/plain-scalar': 'off', 'yml/quotes': ['warn', { prefer: 'single' }], // these two rules do not work well with inline lists 'yml/block-sequence-hyphen-indicator-newline': 'off', 'yml/indent': 'off', '@stylistic/spaced-comment': 'off', }, }, eslintPluginJsonSchemaValidator.configs['flat/base'], // ! JSON Schema generation fails and causes ESLint to crash // { // name: 'pronouns-page/validation', // files: ['locale/**/*.suml'], // rules: { // 'json-schema-validator/no-invalid': ['error', { // schemas: [ // { // fileMatch: ['locale/*/config.suml'], // schema: 'locale/config.schema.json', // }, // { // fileMatch: ['locale/*/nouns/nounsData.suml'], // schema: 'locale/nounsData.schema.json', // }, // ], // }], // }, // }, ) .override('nuxt/javascript', { rules: { 'camelcase': ['warn', { properties: 'never' }], 'curly': 'warn', 'dot-notation': 'warn', 'eqeqeq': 'warn', 'no-constant-condition': 'warn', 'no-empty': 'warn', 'no-irregular-whitespace': 'warn', 'no-template-curly-in-string': 'warn', 'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrors: 'none', }], 'no-useless-escape': 'warn', 'no-useless-rename': 'warn', 'object-shorthand': 'warn', 'prefer-template': 'warn', }, }) .override('nuxt/typescript/rules', { rules: { 'prefer-const': 'warn', '@typescript-eslint/no-dynamic-delete': 'warn', '@typescript-eslint/no-empty-object-type': ['error', { allowInterfaces: 'with-single-extends' }], '@typescript-eslint/no-explicit-any': 'warn', '@typescript-eslint/no-extraneous-class': 'warn', '@typescript-eslint/no-this-alias': 'warn', '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrors: 'none', }], }, }) .override('nuxt/import/rules', { rules: { 'import/consistent-type-specifier-style': ['warn', 'prefer-top-level'], 'import/extensions': ['error', 'ignorePackages'], 'import/no-useless-path-segments': 'warn', 'import/order': ['warn', { 'newlines-between': 'always', 'alphabetize': { order: 'asc', orderImportKind: 'desc' }, }], }, }) .override('nuxt/stylistic', (config) => ({ ...config, rules: { ...Object.fromEntries(Object.entries(config.rules ?? {}).map(([ruleName, ruleEntry]) => { if (ruleEntry === undefined) { return [ruleName, undefined]; } return [ruleName, typeof ruleEntry === 'number' || typeof ruleEntry === 'string' ? 'warn' : ['warn', ...ruleEntry.slice(1)]]; })), '@stylistic/array-bracket-newline': ['warn', 'consistent'], '@stylistic/array-element-newline': ['warn', 'consistent'], '@stylistic/function-call-argument-newline': ['warn', 'consistent'], '@stylistic/function-call-spacing': 'warn', '@stylistic/function-paren-newline': ['warn', 'multiline-arguments'], '@stylistic/implicit-arrow-linebreak': 'warn', '@stylistic/linebreak-style': 'warn', '@stylistic/max-len': ['warn', { code: 120 }], '@stylistic/no-extra-semi': 'warn', '@stylistic/no-mixed-operators': ['warn', { groups: [['&&', '||']], }], '@stylistic/object-curly-newline': 'warn', '@stylistic/object-property-newline': ['warn', { allowAllPropertiesOnSameLine: true }], '@stylistic/one-var-declaration-per-line': 'warn', '@stylistic/operator-linebreak': 'warn', '@stylistic/switch-colon-spacing': 'warn', '@stylistic/generator-star-spacing': ['warn', { before: false, after: true, method: { before: false, after: false }, }], }, })) .override('nuxt/vue/rules', { rules: { 'vue/first-attribute-linebreak': ['warn', { singleline: 'beside' }], 'vue/html-button-has-type': 'error', 'vue/html-self-closing': ['warn', { html: { normal: 'never' } }], 'vue/max-attributes-per-line': ['warn', { singleline: 5 }], 'vue/multi-word-component-names': 'off', 'vue/no-mutating-props': 'warn', 'vue/require-v-for-key': 'warn', 'vue/singleline-html-element-content-newline': ['warn', { externalIgnores: ['T', 'nuxt-link'] }], 'vue/valid-template-root': 'warn', 'vue/valid-v-for': 'warn', 'vue/array-bracket-newline': ['warn', 'consistent'], 'vue/array-element-newline': ['warn', 'consistent'], 'vue/camelcase': ['warn', { properties: 'never' }], 'vue/dot-location': ['warn', 'property'], 'vue/dot-notation': 'warn', 'vue/eqeqeq': 'warn', 'vue/multiline-ternary': ['warn', 'always-multiline'], 'vue/no-empty-pattern': 'warn', 'vue/no-loss-of-precision': 'warn', 'vue/no-sparse-arrays': 'warn', 'vue/object-curly-newline': 'warn', 'vue/object-shorthand': 'warn', 'vue/operator-linebreak': 'warn', 'vue/prefer-use-template-ref': 'error', 'vue/prefer-template': 'warn', 'vue/require-macro-variable-name': 'error', 'vue/require-typed-ref': 'error', 'vue/space-infix-ops': 'warn', 'vue/space-unary-ops': 'warn', }, });