import pluginVue from 'eslint-plugin-vue'; import vueTsEslintConfig from '@vue/eslint-config-typescript'; import eslintConfigPrettier from 'eslint-config-prettier'; export default [ { name: 'app/files-to-lint', files: ['**/*.{ts,mts,tsx,vue}'], }, { name: 'app/files-to-ignore', ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**', '**/.vite/**', '**/.ponder/**', '**/node_modules/**'], }, ...pluginVue.configs['flat/essential'], ...vueTsEslintConfig(), { name: 'arch/landing-import-restrictions', rules: { 'no-restricted-imports': [ 'error', { patterns: [ { group: ['**/web-app/**', '@harb/web-app/*'], message: 'Landing component imports from web-app. Landing must not depend on web-app. Move shared code to kraiken-lib or a shared/ package. See docs/ARCHITECTURE.md.', }, ], paths: [ { name: 'viem', importNames: ['createPublicClient', 'publicActions'], message: 'Landing component imports a direct RPC client from viem. Landing must not make direct RPC calls from the browser — this will kill any node under load. Use Ponder GraphQL at /api/graphql instead. See docs/UX-DECISIONS.md.', }, { name: '@wagmi/vue', importNames: ['usePublicClient'], message: 'Landing component imports usePublicClient from @wagmi/vue. Landing must not make direct RPC calls from the browser — this will kill any node under load. Use Ponder GraphQL at /api/graphql instead. See docs/UX-DECISIONS.md.', }, { name: 'axios', message: 'Landing component imports axios. Landing must not use axios — it increases bundle size for no benefit. Use native fetch() with the /api/graphql proxy instead.', }, ], }, ], }, }, { name: 'arch/graphql-no-interpolation', rules: { 'no-restricted-syntax': [ 'error', { selector: "Property[key.name='query'] > TemplateLiteral[expressions.length>0], Property[key.name='mutation'] > TemplateLiteral[expressions.length>0]", message: 'String interpolation used in a GraphQL query or mutation string. GraphQL queries must not use string interpolation — it bypasses type-checking and is unsafe. Use the `variables` parameter in the fetch body instead. Example: `variables: { holder: address }`. See PR #191 for the pattern.', }, ], }, }, { name: 'app/custom-rules', rules: { // TypeScript rules '@typescript-eslint/no-unused-vars': [ 'error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_', }, ], '@typescript-eslint/no-explicit-any': 'error', // Vue rules 'vue/multi-word-component-names': 'error', 'vue/no-unused-vars': 'error', 'vue/component-name-in-template-casing': ['error', 'PascalCase'], 'vue/require-default-prop': 'error', 'vue/require-prop-types': 'error', 'vue/html-indent': ['error', 2], 'vue/max-attributes-per-line': 'off', // Prettier handles this 'vue/singleline-html-element-content-newline': 'off', // Prettier handles this // General rules 'no-console': 'error', 'max-len': ['error', { code: 140, ignoreUrls: true, ignoreStrings: true, ignoreTemplateLiterals: true }], indent: ['error', 2, { SwitchCase: 1 }], // Disable complexity rules complexity: 'off', 'max-depth': 'off', 'max-nested-callbacks': 'off', 'max-lines': 'off', 'max-lines-per-function': 'off', 'max-params': 'off', 'max-statements': 'off', }, }, eslintConfigPrettier, ];