Felipe97/llama-cpp-compiled
01.2k
1// For more info, see https://github.com/storybookjs/eslint-plugin-storybook#configuration-flat-config-format2import svelteConfig from './svelte.config.js';3import { includeIgnoreFile } from '@eslint/compat';4import js from '@eslint/js';5import prettier from 'eslint-config-prettier';6import perfectionist from 'eslint-plugin-perfectionist';7import simpleImportSort from 'eslint-plugin-simple-import-sort';8import storybook from 'eslint-plugin-storybook';9import svelte from 'eslint-plugin-svelte';10import globals from 'globals';11import { fileURLToPath } from 'node:url';12import ts from 'typescript-eslint';13 14const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url));15// Require a blank line between sibling element-like nodes in a Svelte template16// (elements, components, and the {#if} / {#each} / {#await} / {#snippet} /17// {@render} blocks) that sit on separate lines at the same nesting level.18// Whitespace between siblings is a whitespace-only SvelteText node; when it19// holds a single newline (no blank line) the fix adds one, keeping the20// indentation of the second sibling. Real text content (e.g. `foo\n\nbar`)21// is left alone.22const ELEMENT_LIKE_TYPES = new Set([23 'SvelteAwaitBlock',24 'SvelteComponent',25 'SvelteEachBlock',26 'SvelteElement',27 'SvelteIfBlock',28 'SvelteKeyBlock',29 'SvelteRenderTag',30 'SvelteSelf',31 'SvelteSnippetBlock'32]);33const paddingLineBetweenElements = {34 create(context) {35 // Check one list of template children. Each children array holds the36 // element-like nodes plus the whitespace/comment text between them.37 function checkChildren(children) {38 if (!Array.isArray(children)) return;39 40 let lastElement = null;41 let lastWhitespace = null;42 43 for (const child of children) {44 if (child.type === 'SvelteText' && /^\s*$/.test(child.value)) {45 lastWhitespace = child;46 47 continue;48 }49 50 if (!ELEMENT_LIKE_TYPES.has(child.type)) continue;51 52 if (53 lastElement &&54 lastWhitespace &&55 child.loc.start.line - lastElement.loc.end.line === 156 ) {57 const textNode = lastWhitespace;58 59 context.report({60 fix(fixer) {61 // Add a second newline so the two siblings are separated by a62 // blank line, keeping the trailing indentation.63 return fixer.replaceText(textNode, textNode.value.replace(/\n/, '\n\n'));64 },65 message: 'Expected a blank line between sibling elements.',66 node: child67 });68 }69 70 lastElement = child;71 lastWhitespace = null;72 }73 }74 75 return {76 SvelteAwaitBlock(node) {77 checkChildren(node.children);78 checkChildren(node.then?.children);79 checkChildren(node.else?.children);80 },81 SvelteComponent(node) {82 checkChildren(node.children);83 },84 SvelteEachBlock(node) {85 checkChildren(node.children);86 checkChildren(node.else?.children);87 },88 SvelteElement(node) {89 checkChildren(node.children);90 },91 SvelteFragment(node) {92 checkChildren(node.children);93 },94 SvelteIfBlock(node) {95 checkChildren(node.children);96 checkChildren(node.else?.children);97 },98 SvelteKeyBlock(node) {99 checkChildren(node.children);100 },101 SvelteProgram(node) {102 checkChildren(node.children);103 },104 SvelteSnippetBlock(node) {105 checkChildren(node.children);106 }107 };108 },109 meta: {110 docs: { description: 'Require a blank line between sibling elements in a Svelte template.' },111 fixable: 'whitespace',112 schema: [],113 type: 'layout'114 }115};116// Require a blank line between consecutive class accessors (get/set). The core117// `padding-line-between-statements` rule only handles statements, not class118// members, so this is enforced with a small custom rule.119const blankLineBetweenAccessors = {120 create(context) {121 return {122 MethodDefinition(node) {123 if (node.kind !== 'get' && node.kind !== 'set') return;124 125 const body = node.parent;126 127 if (!body || body.type !== 'ClassBody') return;128 129 const index = body.body.indexOf(node);130 131 if (index <= 0) return;132 133 const prev = body.body[index - 1];134 135 if (prev.type !== 'MethodDefinition' || (prev.kind !== 'get' && prev.kind !== 'set'))136 return;137 138 if (node.loc.start.line - prev.loc.end.line <= 1) {139 context.report({140 fix(fixer) {141 // Insert after the previous accessor's closing brace so the blank142 // line keeps the current accessor's indentation.143 return fixer.insertTextAfter(prev, '\n');144 },145 message: 'Expected a blank line between class accessors (get/set).',146 node147 });148 }149 }150 };151 },152 meta: {153 docs: { description: 'Require a blank line between consecutive class accessors (get/set).' },154 fixable: 'whitespace',155 schema: [],156 type: 'layout'157 }158};159 160export default ts.config(161 includeIgnoreFile(gitignorePath),162 js.configs.recommended,163 ...ts.configs.recommended,164 ...svelte.configs.recommended,165 prettier,166 ...svelte.configs.prettier,167 {168 languageOptions: { globals: { ...globals.browser, ...globals.node } },169 plugins: {170 local: {171 rules: {172 'blank-line-between-accessors': blankLineBetweenAccessors,173 'padding-line-between-elements': paddingLineBetweenElements174 }175 },176 perfectionist,177 'simple-import-sort': simpleImportSort178 },179 rules: {180 // Snippet bodies often ignore one or more of the parent's params181 // (e.g. `{#snippet children(_meta, ctx)}` when only ctx is read).182 '@typescript-eslint/no-unused-vars': [183 'error',184 { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }185 ],186 187 // Enforce empty line at end of file188 'eol-last': 'error',189 // Enforce a blank line between consecutive get/set accessors190 'local/blank-line-between-accessors': 'error',191 // Require a blank line between sibling elements in a Svelte template192 'local/padding-line-between-elements': 'error',193 // typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects.194 // see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors195 'no-undef': 'off',196 197 'padding-line-between-statements': [198 'error',199 // Blank line between function/class declarations.200 { blankLine: 'always', next: ['function', 'class'], prev: ['function', 'class'] },201 // Blank line around if blocks (if/else and else if stay one statement).202 { blankLine: 'always', next: '*', prev: 'if' },203 { blankLine: 'always', next: 'if', prev: '*' },204 // Blank line after the last declaration in a group. Because the 'never'205 // rules below are scoped per declaration kind, a const group and a let206 // group get separated by a blank line, while same-kind declarations stay207 // together.208 { blankLine: 'always', next: '*', prev: ['const', 'let', 'var'] },209 // No blank line between consecutive declarations of the same kind (kept210 // last so each takes precedence over the always rule above for matching211 // declaration pairs).212 { blankLine: 'never', next: 'const', prev: 'const' },213 { blankLine: 'never', next: 'let', prev: 'let' },214 { blankLine: 'never', next: 'var', prev: 'var' },215 // Blank line before a statement that follows another statement in the block216 // (works for return/throw/break/continue). A blank line for a terminal217 // statement that opens a block body can't be enforced here: Prettier removes218 // the leading blank line of a block, so the two formatters would fight.219 { blankLine: 'always', next: ['return', 'throw', 'break', 'continue'], prev: '*' }220 ],221 222 // Class member order: public fields -> private fields -> constructor -> getters223 // -> setters -> public methods -> private methods, alphabetical within each.224 // Svelte $derived fields must stay in dependency order (forward references are225 // rejected), so the two stores that rely on that are exempted below.226 'perfectionist/sort-classes': [227 'error',228 {229 customGroups: [230 { groupName: 'public-field', modifiers: ['public'], selector: 'property' },231 { groupName: 'private-field', modifiers: ['private'], selector: 'property' },232 { groupName: 'get-method', selector: 'get-method' },233 { groupName: 'set-method', selector: 'set-method' },234 { groupName: 'public-method', modifiers: ['public'], selector: 'method' },235 { groupName: 'private-method', modifiers: ['private'], selector: 'method' }236 ],237 groups: [238 'public-field',239 'private-field',240 'constructor',241 'get-method',242 'set-method',243 'public-method',244 'private-method',245 'unknown'246 ],247 type: 'natural',248 // Keep members in dependency order (Svelte rejects forward references in249 // $derived fields), while still sorting the rest alphabetically.250 useExperimentalDependencyDetection: true251 }252 ],253 254 // Alphabetical order for enum members255 'perfectionist/sort-enums': ['error', { type: 'natural' }],256 257 'perfectionist/sort-objects': ['error', { type: 'natural' }],258 259 // Alphabetical order for variable declarations and object keys260 'perfectionist/sort-variable-declarations': ['error', { type: 'natural' }],261 262 // Sort imports alphabetically by module path, and sort named members within263 // each statement. A single catch-all group keeps the list flat (no blank-line264 // grouping); Prettier normalizes comma spacing afterwards.265 'simple-import-sort/imports': ['error', { groups: [['.*']] }],266 'svelte/no-at-html-tags': 'off',267 // This app uses hash-based routing (#/) where resolve() from $app/paths does not apply268 'svelte/no-navigation-without-resolve': 'off',269 270 // Sort HTML attributes alphabetically in the markup. The Svelte directives271 // (bind:/use:/animate:/style:/in:/out:/transition:/class:) sort first,272 // alphabetically among themselves, then all remaining attributes sort273 // alphabetically. The rule keeps spread attributes in place and does not cross274 // them. `this` stays first on <svelte:element> because Prettier forces it there275 // - reordering it alphabetically would fight the formatter.276 'svelte/sort-attributes': [277 'error',278 {279 order: [280 'this',281 {282 match: [283 '/^bind:/u',284 '/^use:/u',285 '/^animate:/u',286 '/^style:/u',287 '/^in:/u',288 '/^out:/u',289 '/^transition:/u',290 '/^class:/u'291 ],292 sort: 'alphabetical'293 },294 {295 match: [296 '!/^bind:/u',297 '!/^use:/u',298 '!/^animate:/u',299 '!/^style:/u',300 '!/^in:/u',301 '!/^out:/u',302 '!/^transition:/u',303 '!/^class:/u'304 ],305 sort: 'alphabetical'306 }307 ]308 }309 ]310 }311 },312 {313 files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],314 languageOptions: {315 parserOptions: {316 extraFileExtensions: ['.svelte'],317 parser: ts.parser,318 projectService: true,319 svelteConfig320 }321 }322 },323 {324 // Exclude generated build output and Storybook files from ESLint325 ignores: [326 'dist/**',327 'build/**',328 '.svelte-kit/**',329 'test-results/**',330 '.storybook/**/*',331 'src/lib/services/sandbox-worker.js',332 'src/lib/vendors/**'333 ]334 },335 storybook.configs['flat/recommended']336);337 