@gaia-react/lint 1.5.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/configs/base.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAS,MAAM,EAAC,MAAM,QAAQ,CAAC;AAyT3C,eAAO,MAAM,SAAS,GAAI,WAAW,MAAM,KAAG,MAAM,CAAC,MAAM,EAS1D,CAAC"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/configs/base.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAS,MAAM,EAAC,MAAM,QAAQ,CAAC;AAoV3C,eAAO,MAAM,SAAS,GAAI,WAAW,MAAM,KAAG,MAAM,CAAC,MAAM,EAU1D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"guardrails.d.ts","sourceRoot":"","sources":["../../src/configs/guardrails.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAuMnC,eAAO,MAAM,eAAe,GAAI,WAAW,MAAM,KAAG,MAAM,CAAC,MAAM,EAOhE,CAAC"}
1
+ {"version":3,"file":"guardrails.d.ts","sourceRoot":"","sources":["../../src/configs/guardrails.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAsNnC,eAAO,MAAM,eAAe,GAAI,WAAW,MAAM,KAAG,MAAM,CAAC,MAAM,EAOhE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../src/configs/playwright.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAEnC;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAarC,CAAC"}
1
+ {"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../src/configs/playwright.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAEnC;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAgBrC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"style-hygiene.d.ts","sourceRoot":"","sources":["../../src/configs/style-hygiene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAsQnC,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,KAAG,MAAM,CAAC,MAAM,EAMlE,CAAC"}
1
+ {"version":3,"file":"style-hygiene.d.ts","sourceRoot":"","sources":["../../src/configs/style-hygiene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AA2QnC,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,KAAG,MAAM,CAAC,MAAM,EAMlE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/configs/testing.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAEnC;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAkElC,CAAC"}
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/configs/testing.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAEnC;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAmIlC,CAAC"}
package/dist/index.js CHANGED
@@ -270,30 +270,43 @@ var preferArrowFunctionsConfig = [
270
270
  }
271
271
  },
272
272
  {
273
- // `prefer-arrow-functions` has a hardcoded exemption for named
274
- // default-exported declarations (`guard.js:hasNameAndIsExportedAsDefaultExport`),
275
- // so `export default function Foo() {}` slips through. This selector closes
276
- // that gap. Convert to `const Foo = () => {}; export default Foo;` instead.
277
- // `.d.ts` is ignored because ambient `export default function …(): T;`
278
- // declarations have no body to convert.
273
+ files: ["**/*.d.ts"],
274
+ name: "ts-definition-files/prefer-arrow-off",
275
+ rules: {
276
+ "prefer-arrow-functions/prefer-arrow-functions": "off"
277
+ }
278
+ }
279
+ ];
280
+ var restrictedSyntaxConfig = [
281
+ {
279
282
  ignores: ["**/*.d.ts"],
280
- name: "prefer-arrow/no-default-exported-function",
283
+ name: "gaia/no-restricted-syntax",
281
284
  rules: {
282
285
  "no-restricted-syntax": [
283
286
  "error",
284
287
  {
288
+ // `prefer-arrow-functions` has a hardcoded exemption for named
289
+ // default-exported declarations
290
+ // (`guard.js:hasNameAndIsExportedAsDefaultExport`), so
291
+ // `export default function Foo() {}` slips through. This selector
292
+ // closes that gap.
285
293
  message: "Use `const Name = () => {}; export default Name;` instead. The prefer-arrow-functions plugin exempts named default-exported declarations upstream.",
286
294
  selector: "ExportDefaultDeclaration > FunctionDeclaration"
295
+ },
296
+ {
297
+ // GAIA never renders `null`. `cond ? <JSX/> : null` is the
298
+ // numeric-0-safe `&&` guard written the long way. Both JSX-null
299
+ // ternary selectors only match a JSXElement/JSXFragment branch, so
300
+ // they are inert outside `.tsx`/`.jsx`.
301
+ message: "Do not render `null` from a ternary. Use a boolean-guarded `&&`: `cond && <JSX/>` (coerce a numeric/falsy guard with `!!cond`).",
302
+ selector: "ConditionalExpression[alternate.raw='null']:matches([consequent.type='JSXElement'], [consequent.type='JSXFragment'])"
303
+ },
304
+ {
305
+ message: "Do not render `null` from a ternary. Invert the condition and use `&&`: `!cond && <JSX/>`.",
306
+ selector: "ConditionalExpression[consequent.raw='null']:matches([alternate.type='JSXElement'], [alternate.type='JSXFragment'])"
287
307
  }
288
308
  ]
289
309
  }
290
- },
291
- {
292
- files: ["**/*.d.ts"],
293
- name: "ts-definition-files/prefer-arrow-off",
294
- rules: {
295
- "prefer-arrow-functions/prefer-arrow-functions": "off"
296
- }
297
310
  }
298
311
  ];
299
312
  var lodashUnderscoreConfig = [
@@ -315,6 +328,7 @@ var buildBase = (sourceDir) => [
315
328
  ...buildImportXConfig(sourceDir),
316
329
  ...eslintCommentsConfig,
317
330
  ...preferArrowFunctionsConfig,
331
+ ...restrictedSyntaxConfig,
318
332
  ...lodashUnderscoreConfig
319
333
  ];
320
334
 
@@ -504,6 +518,7 @@ var noSwitchConfig = [
504
518
  ];
505
519
  var buildNoRestrictedPathsConfig = (sourceDir) => {
506
520
  const dir = (layer) => `./${sourceDir}/${layer}`;
521
+ const dataEndpoints = ["actions+", "resources+"];
507
522
  return [
508
523
  {
509
524
  files: [`${sourceDir}/**/!(*.test|*.stories).ts?(x)`],
@@ -514,18 +529,21 @@ var buildNoRestrictedPathsConfig = (sourceDir) => {
514
529
  {
515
530
  zones: [
516
531
  {
532
+ except: dataEndpoints,
517
533
  from: [dir("routes")],
518
- message: "Pages may only be imported by routes; a page must not import a route (import direction is routes -> pages -> components).",
534
+ message: "Pages may only be imported by routes; a page must not import a route (import direction is routes -> pages -> components). Typed `resources+`/`actions+` data endpoints are exempt.",
519
535
  target: dir("pages")
520
536
  },
521
537
  {
538
+ except: dataEndpoints,
522
539
  from: [dir("routes"), dir("pages")],
523
- message: "Reusable components must not depend on page- or route-level code (import direction is routes -> pages -> components).",
540
+ message: "Reusable components must not depend on page- or route-level code (import direction is routes -> pages -> components). Typed `resources+`/`actions+` data endpoints are exempt.",
524
541
  target: dir("components")
525
542
  },
526
543
  {
544
+ except: dataEndpoints,
527
545
  from: [dir("routes"), dir("pages"), dir("components")],
528
- message: "Hooks and state sit below the UI tree; they must not import components, pages, or routes.",
546
+ message: "Hooks and state sit below the UI tree; they must not import components, pages, or routes. Typed `resources+`/`actions+` data endpoints are exempt.",
529
547
  target: [dir("hooks"), dir("state")]
530
548
  },
531
549
  {
@@ -640,8 +658,11 @@ var playwright = [
640
658
  files: [".playwright/**/*.ts?(x)"],
641
659
  rules: {
642
660
  ...playwrightPlugin.configs["flat/recommended"].rules,
661
+ // Every test must assert something. `assertFunctionPatterns` lets custom
662
+ // `expect*()` helpers count as the assertion. Error, never warn: a test
663
+ // that asserts nothing is a false green.
643
664
  "playwright/expect-expect": [
644
- "warn",
665
+ "error",
645
666
  { assertFunctionPatterns: ["^expect[A-Z]"] }
646
667
  ]
647
668
  }
@@ -868,6 +889,11 @@ var unicornConfig = [
868
889
  "unicorn/no-useless-undefined": "off",
869
890
  "unicorn/prefer-export-from": "off",
870
891
  "unicorn/prefer-global-this": "off",
892
+ // `Array#includes` returns a plain boolean, not a type predicate, so it
893
+ // cannot narrow a union the way an `===` comparison chain does. In a typed
894
+ // codebase the chain is the type-safe idiom; forcing `.includes()` discards
895
+ // the narrowing and the value's refined type along with it.
896
+ "unicorn/prefer-includes-over-repeated-comparisons": "off",
871
897
  "unicorn/prefer-set-has": "off",
872
898
  "unicorn/prefer-switch": "off",
873
899
  "unicorn/prefer-ternary": "off",
@@ -1066,11 +1092,74 @@ var testing = [
1066
1092
  // rewrite to test.todo('...') so the gap is explicit. Contradicts
1067
1093
  // `warn-todo`, which stays off. Auto-fixable.
1068
1094
  "vitest/prefer-todo": "error",
1095
+ // Honesty (D-8 / SPEC-006 Rule 3, the cheap-win stand-in for
1096
+ // `gaia-test-honesty/no-call-through-only`). A bare
1097
+ // `toHaveBeenCalled()`/`toBeCalled()` proves the function ran but
1098
+ // asserts nothing about how (arguments) or how many (count) — a
1099
+ // call-through that re-proves the framework, not the behavior.
1100
+ //
1101
+ // SCOPE NOTE: `prefer-called-with` is BROADER than spec Rule 3. The spec
1102
+ // rule fires only when a bare `toHaveBeenCalled()` is the SOLE assertion
1103
+ // in a test; `prefer-called-with` fires on EVERY bare
1104
+ // `toHaveBeenCalled()`/`toBeCalled()` (it exempts only the `.not` form).
1105
+ // So this stands in for Rule 3 rather than matching it exactly.
1106
+ "vitest/prefer-called-with": "error",
1069
1107
  // A bare .toThrow() passes on ANY throw, masking the wrong error;
1070
1108
  // require an asserted message or matcher.
1071
1109
  "vitest/require-to-throw-message": "error"
1072
1110
  }
1073
1111
  },
1112
+ {
1113
+ // Honesty (D-8 / SPEC-006 Rule 4, the cheap-win stand-in for
1114
+ // `gaia-test-honesty/no-server-import-from-consumer`). A consumer test,
1115
+ // story, or harness file must not import a server-only (`*.server`) or
1116
+ // internal (`/internals/`) module: those are private surface, and
1117
+ // reaching into them couples the test to implementation the public
1118
+ // interface is meant to hide.
1119
+ //
1120
+ // Same testing glob as the `vitest` block above. The `*.server.test.*`
1121
+ // exemption is the point of Rule 4: a dedicated server-side test IS the
1122
+ // right place to import a `.server` module (mirrors the real
1123
+ // `app/utils/tests/http.server.test.ts` importing `../http.server`).
1124
+ //
1125
+ // Implemented with the core `no-restricted-imports` rule (config only, no
1126
+ // custom plugin) rather than a dedicated AST rule. Chosen over
1127
+ // `import-x/no-restricted-paths` because Rule 4 keys off the import
1128
+ // SPECIFIER shape (`*.server`, `/internals/`) plus a per-file filename
1129
+ // exemption, not the directory `from`/`target` zones that
1130
+ // `no-restricted-paths` models.
1131
+ //
1132
+ // LIMITATION vs the would-be custom rule: `no-restricted-imports` covers
1133
+ // static `import` / `export ... from` only, NOT dynamic
1134
+ // `import('./x.server')`. The dynamic case is intentionally out of scope
1135
+ // for this cheap-win form; the advisory worthiness audit backstops it.
1136
+ //
1137
+ // ERROR severity, per spec (Rule 4 is an error rule).
1138
+ files: [
1139
+ "**/*.test.ts?(x)",
1140
+ "**/*.stories.ts?(x)",
1141
+ "test/**/*.ts?(x)"
1142
+ ],
1143
+ ignores: ["**/*.server.test.*"],
1144
+ name: "gaia-test-honesty/no-server-import-from-consumer",
1145
+ rules: {
1146
+ "no-restricted-imports": [
1147
+ "error",
1148
+ {
1149
+ patterns: [
1150
+ {
1151
+ group: ["**/*.server"],
1152
+ message: "Do not import a server-only ('*.server') module from a consumer test. Server-only modules are private surface: reach them through the public interface, or from a dedicated *.server.test.* file (which is exempt from this rule)."
1153
+ },
1154
+ {
1155
+ group: ["**/internals/**", "**/internals"],
1156
+ message: "Do not import an internal ('/internals/') module from a consumer test. Internal modules are private surface: importing them couples the test to implementation the public interface is meant to hide. Reach the behavior through the public interface instead."
1157
+ }
1158
+ ]
1159
+ }
1160
+ ]
1161
+ }
1162
+ },
1074
1163
  {
1075
1164
  ...testingLibrary.configs["flat/react"],
1076
1165
  files: ["**/*.test.ts?(x)"],
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/configs/base.ts","../src/configs/better-tailwind.ts","../src/configs/guardrails.ts","../src/plugins/no-enum.ts","../src/plugins/no-jsx-iife.ts","../src/plugins/no-switch.ts","../src/configs/ignores.ts","../src/configs/playwright.ts","../src/configs/prettier.ts","../src/configs/react.ts","../src/configs/storybook.ts","../src/configs/style-hygiene.ts","../src/configs/testing.ts","../src/index.ts"],"sourcesContent":["import eslintComments from '@eslint-community/eslint-plugin-eslint-comments';\nimport js from '@eslint/js';\nimport {configs, plugins, rules} from 'eslint-config-airbnb-extended';\nimport preferArrowFunctions from 'eslint-plugin-prefer-arrow-functions';\nimport lodashUnderscore from 'eslint-plugin-you-dont-need-lodash-underscore';\nimport type {ESLint, Linter} from 'eslint';\n\nconst jsConfig: Linter.Config[] = [\n // ESLint recommended config\n {\n name: 'js/config',\n ...js.configs.recommended,\n },\n // Stylistic plugin\n plugins.stylistic,\n // Import X plugin\n plugins.importX,\n // Airbnb base recommended config\n ...configs.base.recommended,\n // Strict import rules\n rules.base.importsStrict,\n];\n\nconst jsCustomConfig: Linter.Config[] = [\n {\n name: 'js-custom',\n rules: {\n 'consistent-return': 'off',\n curly: ['error', 'all'],\n 'max-params': 'error',\n 'no-param-reassign': 'off', // handled by sonarjs\n 'no-undef': 'off',\n 'no-unused-vars': 'off', // handled by sonarjs\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'test-files/all',\n rules: {\n 'guard-for-in': 'off',\n 'max-params': 'off',\n 'no-await-in-loop': 'off',\n 'no-plusplus': 'off',\n 'no-restricted-syntax': 'off',\n },\n },\n {\n files: ['.playwright/**/*.ts?(x)'],\n name: 'playwright/all',\n rules: {\n 'no-await-in-loop': 'off',\n 'no-restricted-syntax': 'off',\n },\n },\n];\n\nconst typescriptConfig: Linter.Config[] = [\n // TypeScript ESLint plugin\n plugins.typescriptEslint,\n // Airbnb base TypeScript config\n ...configs.base.typescript,\n // Strict TypeScript rules\n rules.typescript.typescriptEslintStrict,\n rules.typescript.stylistic,\n // Airbnb React TypeScript config\n ...configs.react.typescript,\n {\n files: ['./*.ts'],\n name: 'root-ts-files',\n rules: {\n 'global-require': 'off',\n 'no-void': 'off',\n },\n },\n {\n files: ['**/*.ts?(x)'],\n name: 'no-void',\n rules: {\n 'no-void': ['error', {allowAsStatement: true}],\n },\n },\n];\n\nconst buildTsEslintConfig = (sourceDir: string): Linter.Config[] => [\n {\n files: ['**/*.ts?(x)'],\n name: 'typescript/config',\n rules: {\n '@typescript-eslint/array-type': ['error', {default: 'array'}],\n '@typescript-eslint/ban-ts-comment': [\n 'error',\n {\n minimumDescriptionLength: 10,\n 'ts-check': false,\n 'ts-expect-error': 'allow-with-description',\n 'ts-ignore': true,\n 'ts-nocheck': true,\n },\n ],\n '@typescript-eslint/consistent-type-definitions': ['error', 'type'],\n '@typescript-eslint/consistent-type-imports': 'error',\n '@typescript-eslint/explicit-module-boundary-types': 'off',\n '@typescript-eslint/method-signature-style': 'error',\n '@typescript-eslint/no-confusing-void-expression': [\n 'error',\n {ignoreArrowShorthand: true},\n ],\n '@typescript-eslint/no-floating-promises': [\n 'error',\n {ignoreIIFE: true, ignoreVoid: true},\n ],\n '@typescript-eslint/no-misused-promises': [\n 'error',\n {checksVoidReturn: false},\n ],\n '@typescript-eslint/no-non-null-assertion': 'off',\n '@typescript-eslint/no-throw-literal': 'off',\n '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',\n '@typescript-eslint/no-unnecessary-condition': 'error',\n '@typescript-eslint/no-unnecessary-type-parameters': 'off',\n '@typescript-eslint/no-unsafe-assignment': 'error',\n '@typescript-eslint/no-unsafe-return': 'error',\n '@typescript-eslint/only-throw-error': 'off',\n '@typescript-eslint/prefer-nullish-coalescing': 'error',\n '@typescript-eslint/prefer-promise-reject-errors': 'off',\n '@typescript-eslint/restrict-template-expressions': [\n 'error',\n {allowBoolean: true, allowNumber: true},\n ],\n '@typescript-eslint/return-await': 'off',\n '@typescript-eslint/unbound-method': 'off',\n },\n },\n {\n files: [\n `${sourceDir}/hooks/**/*`,\n `${sourceDir}/routes/**/*`,\n `${sourceDir}/sessions.server/**/*`,\n ],\n name: 'typescript/only-throw-error',\n rules: {\n '@typescript-eslint/only-throw-error': 'off',\n },\n },\n {\n files: [\n `${sourceDir}/utils/**`,\n `${sourceDir}/services/**`,\n `${sourceDir}/hooks/**`,\n ],\n name: 'typescript/explicit-return-types',\n rules: {\n '@typescript-eslint/explicit-module-boundary-types': 'error',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'typescript/test-files',\n rules: {\n '@typescript-eslint/no-explicit-any': 'off',\n '@typescript-eslint/no-unsafe-assignment': 'off',\n '@typescript-eslint/no-unsafe-member-access': 'off',\n },\n },\n {\n files: ['test/**/*.ts?(x)'],\n name: 'typescript/test-config',\n rules: {\n '@typescript-eslint/no-var-requires': 'off',\n 'no-plusplus': 'off',\n },\n },\n {\n files: ['**/*.d.ts'],\n name: 'typescript/type-definitions',\n rules: {\n '@typescript-eslint/consistent-type-definitions': 'off',\n '@typescript-eslint/method-signature-style': 'error',\n '@typescript-eslint/no-unused-vars': 'off',\n },\n },\n];\n\nconst buildImportXConfig = (sourceDir: string): Linter.Config[] => [\n {\n name: 'import-x-all-files',\n rules: {\n 'import-x/consistent-type-specifier-style': ['error', 'prefer-top-level'],\n 'import-x/extensions': 'off',\n 'import-x/no-anonymous-default-export': [\n 'error',\n {\n allowArray: true,\n allowLiteral: true,\n allowObject: true,\n },\n ],\n 'import-x/no-namespace': 'off',\n 'import-x/no-rename-default': 'off',\n 'import-x/no-useless-path-segments': 'off',\n 'import-x/order': 'off',\n 'import-x/prefer-default-export': 'off',\n },\n },\n {\n files: ['./*.ts'],\n name: 'import-x/root-ts-files',\n rules: {\n 'import-x/no-extraneous-dependencies': 'off',\n 'import-x/no-unresolved': 'error',\n 'import-x/prefer-default-export': 'off',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'import-x/test-files',\n rules: {\n 'import-x/extensions': 'off',\n 'import-x/no-extraneous-dependencies': 'off',\n },\n },\n {\n files: [`${sourceDir}/**/!(*.test|*.stories).ts?(x)`],\n name: 'import-x/app-test-files',\n rules: {\n 'import-x/no-unresolved': 'error',\n },\n },\n {\n files: [`${sourceDir}/**/hooks/*.ts?(x)`],\n name: 'import-x/hooks',\n rules: {\n 'import-x/no-default-export': 'error',\n },\n },\n {\n files: ['test/**/*.ts?(x)'],\n name: 'import-x/test-config-files',\n rules: {\n 'import-x/no-extraneous-dependencies': 'off',\n 'import-x/prefer-default-export': 'off',\n },\n },\n {\n files: ['.storybook/**/*.ts?(x)', '.playwright/**/*.ts?(x)'],\n name: 'import-x/storybook-playwright',\n rules: {\n 'import-x/no-extraneous-dependencies': 'off',\n 'import-x/no-unresolved': 'off',\n },\n },\n];\n\nconst eslintCommentsConfig: Linter.Config[] = [\n {\n name: 'eslint-comments',\n plugins: {\n 'eslint-comments': eslintComments,\n },\n rules: {\n 'eslint-comments/disable-enable-pair': 'off',\n 'eslint-comments/no-unused-disable': 'error',\n },\n },\n];\n\nconst preferArrowFunctionsConfig: Linter.Config[] = [\n {\n name: 'prefer-arrow',\n plugins: {\n 'prefer-arrow-functions': preferArrowFunctions as unknown as ESLint.Plugin,\n },\n rules: {\n 'prefer-arrow-functions/prefer-arrow-functions': 'error',\n },\n },\n {\n // `prefer-arrow-functions` has a hardcoded exemption for named\n // default-exported declarations (`guard.js:hasNameAndIsExportedAsDefaultExport`),\n // so `export default function Foo() {}` slips through. This selector closes\n // that gap. Convert to `const Foo = () => {}; export default Foo;` instead.\n // `.d.ts` is ignored because ambient `export default function …(): T;`\n // declarations have no body to convert.\n ignores: ['**/*.d.ts'],\n name: 'prefer-arrow/no-default-exported-function',\n rules: {\n 'no-restricted-syntax': [\n 'error',\n {\n message:\n 'Use `const Name = () => {}; export default Name;` instead. The prefer-arrow-functions plugin exempts named default-exported declarations upstream.',\n selector: 'ExportDefaultDeclaration > FunctionDeclaration',\n },\n ],\n },\n },\n {\n files: ['**/*.d.ts'],\n name: 'ts-definition-files/prefer-arrow-off',\n rules: {\n 'prefer-arrow-functions/prefer-arrow-functions': 'off',\n },\n },\n];\n\nconst lodashUnderscoreConfig: Linter.Config[] = [\n {\n name: 'you-dont-need-lodash-underscore',\n plugins: {\n 'you-dont-need-lodash-underscore':\n lodashUnderscore as unknown as ESLint.Plugin,\n },\n rules: {\n ...(lodashUnderscore.configs.compatible.rules as Linter.RulesRecord),\n },\n },\n];\n\nexport const buildBase = (sourceDir: string): Linter.Config[] => [\n ...jsConfig,\n ...jsCustomConfig,\n ...typescriptConfig,\n ...buildTsEslintConfig(sourceDir),\n ...buildImportXConfig(sourceDir),\n ...eslintCommentsConfig,\n ...preferArrowFunctionsConfig,\n ...lodashUnderscoreConfig,\n];\n","import betterTailwindPlugin from 'eslint-plugin-better-tailwindcss';\nimport type {Linter} from 'eslint';\n\nexport type GaiaLintBetterTailwindOptions = {\n /** Path to the Tailwind entry CSS file (e.g. './app/styles/tailwind.css'). */\n entryPoint: string;\n /** Class names to ignore in `better-tailwindcss/no-unknown-classes`. */\n ignore?: string[];\n};\n\n/**\n * Better-Tailwind flat-config factory.\n *\n * Ports `betterTailwindConfig` from GAIA's `eslint.config.mjs`. The\n * `entryPoint` (consumer's Tailwind CSS entry) and `ignore` list are\n * project-specific, so this is shipped as a factory rather than a static\n * array.\n */\nexport const betterTailwind = (\n opts: GaiaLintBetterTailwindOptions,\n): Linter.Config[] => [\n {\n name: 'better-tailwindcss',\n plugins: {\n 'better-tailwindcss': betterTailwindPlugin,\n },\n rules: {\n 'better-tailwindcss/enforce-canonical-classes': 'error',\n 'better-tailwindcss/enforce-consistent-important-position': 'error',\n 'better-tailwindcss/enforce-consistent-variable-syntax': 'error',\n 'better-tailwindcss/enforce-shorthand-classes': 'error',\n 'better-tailwindcss/no-conflicting-classes': 'error',\n 'better-tailwindcss/no-deprecated-classes': 'error',\n 'better-tailwindcss/no-unknown-classes': [\n 'error',\n {ignore: opts.ignore ?? []},\n ],\n },\n settings: {\n 'better-tailwindcss': {\n detectComponentClasses: true,\n entryPoint: opts.entryPoint,\n },\n },\n },\n];\n","import type {Linter} from 'eslint';\nimport noRelativeImportPaths from 'eslint-plugin-no-relative-import-paths';\nimport sonarjs from 'eslint-plugin-sonarjs';\nimport noEnumPlugin from '../plugins/no-enum.js';\nimport noJsxIifePlugin from '../plugins/no-jsx-iife.js';\nimport noSwitchPlugin from '../plugins/no-switch.js';\n\nconst buildSonarConfig = (sourceDir: string): Linter.Config[] => [\n sonarjs.configs!.recommended as Linter.Config,\n {\n name: 'sonarjs',\n rules: {\n 'sonarjs/cognitive-complexity': 'error',\n 'sonarjs/fixme-tag': 'off',\n 'sonarjs/no-commented-code': 'off',\n 'sonarjs/no-nested-conditional': 'off',\n 'sonarjs/no-nested-functions': 'off',\n 'sonarjs/no-selector-parameter': 'off',\n 'sonarjs/regex-complexity': 'off',\n 'sonarjs/todo-tag': 'off',\n },\n },\n {\n files: ['**/*.tsx', '**/hooks/*.ts?(x)'],\n name: 'sonarjs/react-files',\n rules: {\n 'sonarjs/cognitive-complexity': 'off',\n 'sonarjs/function-return-type': 'off',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'sonarjs/test-files',\n rules: {\n 'sonarjs/no-duplicate-string': 'off',\n 'sonarjs/no-identical-functions': 'off',\n },\n },\n {\n files: [`${sourceDir}/languages/**/*.ts`, 'eslint.config.mjs'],\n name: 'sonarjs/credential-checks',\n rules: {\n 'sonarjs/no-hardcoded-credentials': 'off',\n 'sonarjs/no-hardcoded-passwords': 'off',\n },\n },\n];\n\nconst noEnumConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)'],\n name: 'no-enum',\n plugins: {'no-enum': noEnumPlugin},\n rules: {\n 'no-enum/no-enum': 'error',\n },\n },\n];\n\nconst noJsxIifeConfig: Linter.Config[] = [\n {\n files: ['**/*.tsx', '**/*.jsx'],\n name: 'no-jsx-iife',\n plugins: {'no-jsx-iife': noJsxIifePlugin},\n rules: {'no-jsx-iife/no-jsx-iife': 'error'},\n },\n];\n\nconst noSwitchConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)', '**/*.js?(x)'],\n name: 'no-switch',\n plugins: {'no-switch': noSwitchPlugin},\n rules: {'no-switch/no-switch': 'error'},\n },\n];\n\n/**\n * Architecture-boundary enforcement for GAIA's canonical `app/` layout.\n *\n * Imports may only flow from a higher layer to a lower one:\n *\n * routes -> pages -> components -> { hooks, state } -> services -> utils -> types\n *\n * `types/` is a pure leaf importable by everyone. Each zone names a lower\n * layer as `target` and the higher layers it must not import as `from`, so a\n * lower-importing-higher edge (the wrong direction) is reported. `routes`\n * appears in every `from` set, which encodes \"nothing may import a route\".\n *\n * Zone `target`/`from` paths resolve against `process.cwd()` (the consuming\n * project's root where eslint runs), not this package's location in\n * node_modules, so `./${sourceDir}/...` correctly points at the consumer's\n * source tree. `import-x@4.16.2` accepts `from`/`target` as string arrays,\n * which collapses the higher->lower pairs into one zone per target layer.\n *\n * `app/middleware`, `app/sessions.server`, `app/assets`, `app/languages`, and\n * `app/styles` are intentionally left unconstrained (server/asset dirs).\n */\nconst buildNoRestrictedPathsConfig = (\n sourceDir: string,\n): Linter.Config[] => {\n const dir = (layer: string): string => `./${sourceDir}/${layer}`;\n\n return [\n {\n files: [`${sourceDir}/**/!(*.test|*.stories).ts?(x)`],\n name: 'import-x/architecture-boundaries',\n rules: {\n 'import-x/no-restricted-paths': [\n 'error',\n {\n zones: [\n {\n from: [dir('routes')],\n message:\n 'Pages may only be imported by routes; a page must not import a route (import direction is routes -> pages -> components).',\n target: dir('pages'),\n },\n {\n from: [dir('routes'), dir('pages')],\n message:\n 'Reusable components must not depend on page- or route-level code (import direction is routes -> pages -> components).',\n target: dir('components'),\n },\n {\n from: [dir('routes'), dir('pages'), dir('components')],\n message:\n 'Hooks and state sit below the UI tree; they must not import components, pages, or routes.',\n target: [dir('hooks'), dir('state')],\n },\n {\n from: [\n dir('routes'),\n dir('pages'),\n dir('components'),\n dir('hooks'),\n dir('state'),\n ],\n message:\n 'The service/data layer sits below the UI and orchestration layers; it must not import components, pages, routes, hooks, or state.',\n target: dir('services'),\n },\n {\n from: [\n dir('routes'),\n dir('pages'),\n dir('components'),\n dir('hooks'),\n dir('state'),\n dir('services'),\n ],\n message:\n 'Utils are near-leaves; they may import only types and other utils.',\n target: dir('utils'),\n },\n {\n from: [\n dir('routes'),\n dir('pages'),\n dir('components'),\n dir('hooks'),\n dir('state'),\n dir('services'),\n dir('utils'),\n ],\n message:\n 'Types are a pure leaf; they must not import any other app layer.',\n target: dir('types'),\n },\n ],\n },\n ],\n },\n },\n ];\n};\n\nconst buildNoRelativeImportPathsConfig = (\n sourceDir: string,\n): Linter.Config[] => [\n {\n name: 'no-relative-import-paths',\n plugins: {\n 'no-relative-import-paths': noRelativeImportPaths,\n },\n rules: {\n 'no-relative-import-paths/no-relative-import-paths': [\n 'error',\n {\n allowedDepth: 2,\n allowSameFolder: true,\n prefix: '~',\n rootDir: sourceDir,\n },\n ],\n },\n },\n];\n\nexport const buildGuardrails = (sourceDir: string): Linter.Config[] => [\n ...buildSonarConfig(sourceDir),\n ...noEnumConfig,\n ...noJsxIifeConfig,\n ...noSwitchConfig,\n ...buildNoRestrictedPathsConfig(sourceDir),\n ...buildNoRelativeImportPathsConfig(sourceDir),\n];\n","import type {ESLint, Rule} from 'eslint';\n\nconst noEnumRule: Rule.RuleModule = {\n create: (context) => ({\n TSEnumDeclaration: (node: Rule.Node) => {\n context.report({messageId: 'noEnum', node});\n },\n }),\n meta: {\n docs: {description: 'Disallow TypeScript enums'},\n messages: {\n noEnum:\n 'Do not use TypeScript enums. Use an object with `as const` instead.',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-enum',\n version: '0.1.0',\n },\n rules: {\n 'no-enum': noEnumRule,\n },\n};\n\nexport default plugin;\n","import type {ESLint, Rule} from 'eslint';\n\nconst noJsxIifeRule: Rule.RuleModule = {\n create: (context) => ({\n 'JSXExpressionContainer > CallExpression > ArrowFunctionExpression.callee':\n (node: Rule.Node) => {\n context.report({messageId: 'noJsxIife', node});\n },\n 'JSXExpressionContainer > CallExpression > FunctionExpression.callee': (\n node: Rule.Node,\n ) => {\n context.report({messageId: 'noJsxIife', node});\n },\n }),\n meta: {\n docs: {description: 'Disallow IIFEs in JSX expressions'},\n messages: {\n noJsxIife:\n 'Do not use IIFEs in JSX. Use a computed variable before the return or extract a component instead.',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-jsx-iife',\n version: '0.1.0',\n },\n rules: {\n 'no-jsx-iife': noJsxIifeRule,\n },\n};\n\nexport default plugin;\n","import type {ESLint, Rule} from 'eslint';\n\nconst noSwitchRule: Rule.RuleModule = {\n create: (context) => ({\n SwitchStatement: (node: Rule.Node) => {\n context.report({messageId: 'noSwitch', node});\n },\n }),\n meta: {\n docs: {description: 'Disallow switch statements'},\n messages: {\n noSwitch:\n 'Do not use switch statements. Use an object map or if/else instead.',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-switch',\n version: '0.1.0',\n },\n rules: {\n 'no-switch': noSwitchRule,\n },\n};\n\nexport default plugin;\n","import {includeIgnoreFile} from '@eslint/config-helpers';\nimport type {Linter} from 'eslint';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport type GaiaLintIgnoresOptions = {\n /**\n * Path to a `.gitignore` file to merge in. Resolved from `process.cwd()`\n * if relative. Pass `false` to skip the gitignore merge entirely.\n *\n * If the resolved path does not exist, the merge is silently skipped —\n * projects without a `.gitignore` don't need to opt out explicitly.\n *\n * @default '.gitignore'\n */\n gitignore?: string | false;\n /** Extra ignore globs to merge with GAIA defaults. */\n extra?: string[];\n};\n\n/**\n * GAIA's default ignore globs — matches the static `ignored-files` block in\n * GAIA's `eslint.config.mjs`. Consumer's `extra` ignores get concatenated\n * onto this list.\n */\nconst defaultIgnores = [\n '.storybook',\n '.playwright',\n '/.react-router/**',\n '.claude/**/*.js',\n '.claude/**/*.cjs',\n 'scripts',\n 'public/**',\n '**/*.css',\n '**/*.svg',\n '**/*.md',\n];\n\n/**\n * Ignores flat-config factory.\n *\n * Ports the `includeIgnoreFile(gitignorePath)` + static `ignored-files`\n * block from GAIA's `eslint.config.mjs`. The `gitignore` path must be\n * resolved at the consumer's cwd (config-load time), not at gaia-lint's\n * install location, so this is shipped as a factory.\n */\nexport const ignores = (opts?: GaiaLintIgnoresOptions): Linter.Config[] => {\n const out: Linter.Config[] = [];\n\n const gitignore = opts?.gitignore ?? '.gitignore';\n if (gitignore !== false) {\n const resolved = path.isAbsolute(gitignore)\n ? gitignore\n : path.resolve(process.cwd(), gitignore);\n if (fs.existsSync(resolved)) {\n out.push(includeIgnoreFile(resolved) as Linter.Config);\n }\n }\n\n out.push({\n ignores: [...defaultIgnores, ...(opts?.extra ?? [])],\n name: 'ignored-files',\n });\n\n return out;\n};\n","import playwrightPlugin from 'eslint-plugin-playwright';\nimport type {Linter} from 'eslint';\n\n/**\n * Playwright flat-config block.\n *\n * Ports `playwrightConfig` from GAIA's `eslint.config.mjs` — scopes\n * `eslint-plugin-playwright`'s `flat/recommended` config to `.playwright/`\n * test files (GAIA's e2e directory convention).\n */\nexport const playwright: Linter.Config[] = [\n {\n name: 'playwright',\n ...(playwrightPlugin.configs['flat/recommended'] as Linter.Config),\n files: ['.playwright/**/*.ts?(x)'],\n rules: {\n ...playwrightPlugin.configs['flat/recommended'].rules,\n 'playwright/expect-expect': [\n 'warn',\n {assertFunctionPatterns: ['^expect[A-Z]']},\n ],\n },\n },\n];\n","import {rules as prettierConfigRules} from 'eslint-config-prettier';\nimport prettierPlugin from 'eslint-plugin-prettier';\nimport type {Linter} from 'eslint';\n\n/**\n * Prettier flat-config block.\n *\n * Ports `prettierConfig` from GAIA's `eslint.config.mjs`. Layers\n * `eslint-config-prettier`'s rule disablers, then re-enables a few\n * `@stylistic/*` rules GAIA wants to keep (padding lines, single quotes),\n * and finally turns on the `prettier/prettier` rule itself.\n */\nexport const prettier: Linter.Config[] = [\n {\n name: 'prettier/plugin/config',\n plugins: {prettier: prettierPlugin},\n },\n {\n name: 'prettier/config',\n rules: {\n ...prettierConfigRules,\n '@stylistic/padding-line-between-statements': [\n 'error',\n {\n blankLine: 'always',\n next: ['block-like', 'export', 'return', 'throw'],\n prev: '*',\n },\n ],\n '@stylistic/quotes': [\n 'error',\n 'single',\n {\n allowTemplateLiterals: 'avoidEscape',\n avoidEscape: true,\n },\n ],\n '@stylistic/spaced-comment': 'off',\n 'prettier/prettier': ['error', {endOfLine: 'auto'}],\n },\n },\n];\n","import {configs, plugins} from 'eslint-config-airbnb-extended';\nimport type {Linter} from 'eslint';\n\n/**\n * React flat-config block.\n *\n * Ports `reactConfig` + `reactCustomConfig` from GAIA's `eslint.config.mjs`.\n * Pulls React, React Hooks, and JSX A11y plugins plus Airbnb's recommended\n * React config, then layers GAIA's project-wide React rule overrides.\n *\n * The `react-router/routes` override targets `**\\/routes/**\\/*.tsx` — a GAIA\n * convention that's harmless for consumers without that folder structure\n * (the override only fires when files match).\n */\nexport const react: Linter.Config[] = [\n // React plugin\n plugins.react,\n // React hooks plugin\n plugins.reactHooks,\n // React JSX A11y plugin\n plugins.reactA11y,\n // Airbnb React recommended config\n ...configs.react.recommended,\n {\n name: 'react-custom',\n rules: {\n 'jsx-a11y/control-has-associated-label': 'off',\n 'jsx-a11y/no-autofocus': 'off',\n 'react/boolean-prop-naming': [\n 'error',\n {\n propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],\n rule: '^((can|has|hide|is|show)[A-Z]([A-Za-z0-9]?)+|(checked|disabled|hide|required|show))',\n },\n ],\n 'react/function-component-definition': 'off',\n 'react/jsx-boolean-value': ['error', 'always'],\n 'react/jsx-curly-brace-presence': 'error',\n 'react/jsx-filename-extension': 'off',\n 'react/jsx-fragments': 'error',\n // off by default because it doesn't handle props onXyz function names correctly\n // turn this on from time to time to check for misnamed handlers elsewhere\n 'react/jsx-handler-names': ['off', {checkLocalVariables: true}],\n 'react/jsx-newline': ['error', {prevent: true}],\n 'react/jsx-no-useless-fragment': ['error', {allowExpressions: true}],\n 'react/no-children-prop': 'off',\n 'react/no-danger': 'off',\n 'react/prop-types': 'off',\n 'react/react-in-jsx-scope': 'off',\n 'react/require-default-props': 'off',\n },\n },\n {\n files: ['**/routes/**/*.tsx'],\n name: 'react-router/routes',\n rules: {\n 'no-empty-pattern': 'off',\n 'react/display-name': 'off',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'react/test-files',\n rules: {\n 'react/jsx-props-no-spreading': 'off',\n },\n },\n];\n","import storybookPlugin from 'eslint-plugin-storybook';\nimport type {Linter} from 'eslint';\n\n/**\n * Storybook flat-config block.\n *\n * Ports `storybookConfig` from GAIA's `eslint.config.mjs` — applies the\n * official `flat/recommended` config from `eslint-plugin-storybook`.\n */\nexport const storybook: Linter.Config[] = [\n ...(storybookPlugin.configs['flat/recommended'] as Linter.Config[]),\n];\n","import type {Linter} from 'eslint';\nimport canonical from 'eslint-plugin-canonical';\nimport checkFile from 'eslint-plugin-check-file';\nimport perfectionist from 'eslint-plugin-perfectionist';\nimport unicorn from 'eslint-plugin-unicorn';\nimport unusedImports from 'eslint-plugin-unused-imports';\n\nconst buildCanonicalConfig = (sourceDir: string): Linter.Config[] => [\n canonical.configs['flat/recommended'] as Linter.Config,\n {\n name: 'canonical',\n rules: {\n 'canonical/destructuring-property-newline': 'off',\n 'canonical/filename-match-exported': 'error',\n 'canonical/id-match': 'off',\n 'canonical/import-specifier-newline': 'off',\n },\n },\n {\n files: ['**/*.tsx', '**/hooks/*.ts?(x)'],\n name: 'canonical/sort-react-dependencies',\n rules: {\n 'canonical/sort-react-dependencies': 'error',\n },\n },\n {\n files: [\n `${sourceDir}/root.tsx`,\n `${sourceDir}/entry.server.tsx`,\n `${sourceDir}/**/tests/*`,\n 'test/**/*.ts?(x)',\n '**/*.stories.tsx',\n '**/routes/**/*.tsx',\n '**/hooks/*.ts?(x)',\n '.storybook/**/*.ts?(x)',\n '.playwright/**/*.ts?(x)',\n ],\n name: 'canonical/filename-match-exported-disabled',\n rules: {\n 'canonical/filename-match-exported': 'off',\n },\n },\n];\n\nconst perfectionistConfig: Linter.Config[] = [\n perfectionist.configs['recommended-natural'] as Linter.Config,\n {\n name: 'perfectionist',\n rules: {\n 'perfectionist/sort-imports': [\n 'error',\n {\n customGroups: [\n {\n elementNamePattern: '^react$',\n groupName: 'react-type',\n selector: 'type',\n },\n {\n elementNamePattern: '^react$',\n groupName: 'react',\n },\n {\n elementNamePattern: '^react-.+',\n groupName: 'react-other-type',\n selector: 'type',\n },\n {\n elementNamePattern: '^react-.+',\n groupName: 'react-other',\n },\n ],\n groups: [\n 'react-type',\n 'react',\n 'react-other-type',\n 'react-other',\n ['type-external', 'external'],\n ['type-builtin', 'builtin'],\n ['type-internal', 'internal'],\n ['type-parent', 'parent'],\n ['type-sibling', 'sibling'],\n ['type-index', 'index'],\n 'unknown',\n 'style',\n 'side-effect',\n 'side-effect-style',\n ],\n newlinesBetween: 0,\n type: 'natural',\n },\n ],\n 'perfectionist/sort-jsx-props': [\n 'error',\n {\n customGroups: [\n {\n elementNamePattern: ['^key$', '^ref$'],\n groupName: 'reserved',\n },\n ],\n groups: ['reserved'],\n type: 'natural',\n },\n ],\n },\n },\n];\n\nconst unicornConfig: Linter.Config[] = [\n unicorn.configs.recommended as Linter.Config,\n {\n name: 'unicorn',\n rules: {\n 'unicorn/consistent-destructuring': 'error',\n 'unicorn/consistent-template-literal-escape': 'off',\n 'unicorn/filename-case': 'off',\n 'unicorn/new-for-builtins': 'off',\n 'unicorn/no-array-callback-reference': 'off',\n 'unicorn/no-array-for-each': 'off',\n 'unicorn/no-array-reduce': 'off',\n 'unicorn/no-nested-ternary': 'off',\n 'unicorn/no-null': 'off',\n 'unicorn/no-useless-undefined': 'off',\n 'unicorn/prefer-export-from': 'off',\n 'unicorn/prefer-global-this': 'off',\n 'unicorn/prefer-set-has': 'off',\n 'unicorn/prefer-switch': 'off',\n 'unicorn/prefer-ternary': 'off',\n 'unicorn/prevent-abbreviations': [\n 'error',\n {\n ignore: [\n 'acc',\n 'ctx',\n 'e2e',\n 'env',\n 'obj',\n 'prev',\n 'req',\n 'res',\n /args/i,\n /fn/i,\n /param/i,\n /params/i,\n /props/i,\n /ref/i,\n /src/i,\n /utils/i,\n ],\n },\n ],\n 'unicorn/text-encoding-identifier-case': 'off',\n },\n },\n {\n files: ['./*.ts'],\n name: 'unicorn/root-ts-files',\n rules: {\n 'unicorn/prefer-module': 'off',\n 'unicorn/prevent-abbreviations': 'off',\n },\n },\n];\n\nconst unusedImportsConfig: Linter.Config[] = [\n {\n name: 'unused-imports',\n plugins: {\n 'unused-imports': unusedImports,\n },\n rules: {\n '@typescript-eslint/no-unused-vars': 'off',\n 'no-unused-vars': 'off',\n 'sonarjs/no-unused-vars': 'off',\n 'sonarjs/unused-import': 'off',\n 'unused-imports/no-unused-imports': 'error',\n 'unused-imports/no-unused-vars': [\n 'error',\n {\n args: 'after-used',\n argsIgnorePattern: '^_',\n ignoreRestSiblings: true,\n vars: 'all',\n varsIgnorePattern: '^_',\n },\n ],\n },\n },\n {\n files: ['**/*.d.ts'],\n name: 'unused-imports/ts-definition-files',\n rules: {\n 'unused-imports/no-unused-vars': 'off',\n },\n },\n];\n\nconst buildCheckFileConfig = (sourceDir: string): Linter.Config[] => [\n {\n plugins: {\n 'check-file': checkFile,\n },\n },\n {\n files: [`${sourceDir}/**/*`],\n name: 'check-file',\n rules: {\n 'check-file/filename-naming-convention': [\n 'error',\n {\n // React hook files must be camelCase (to match the hook name)\n '**/hooks/*.{ts,tsx}': 'CAMEL_CASE',\n [`${sourceDir}/state/*.tsx`]: 'KEBAB_CASE',\n // React component files must be named index.tsx\n [`${sourceDir}/{components,pages}/**/!(assets|hooks|state|tests|utils)/*.tsx`]:\n 'index+()',\n // Generally, non-component files must be named kebab-case\n [`${sourceDir}/{components,pages}/**/!(hooks)/*.ts`]: 'KEBAB_CASE',\n // Non-component files inside specific components folders must be kebab-case\n [`${sourceDir}/{components,pages}/**/(assets|state|tests|utils)/*.{ts,tsx}`]:\n 'KEBAB_CASE',\n 'test/**/*.ts?(x)': 'KEBAB_CASE',\n },\n {\n ignoreMiddleExtensions: true,\n },\n ],\n 'check-file/folder-match-with-fex': [\n 'error',\n {\n // require stories and test files to be inside tests folders\n '*.(stories|test).{ts,tsx}': `${sourceDir}/**/tests/`,\n },\n ],\n 'check-file/folder-naming-convention': [\n 'error',\n {\n // enforce PascalCase component folders, and allow assets, hooks, tests, and utils subfolders\n [`${sourceDir}/components/**/`]:\n '(assets|hooks|state|tests|utils|[A-Z][a-zA-Z0-9]*)',\n },\n ],\n },\n },\n {\n files: ['test/**/*.*'],\n name: 'check-file/test-files',\n rules: {\n 'check-file/filename-naming-convention': [\n 'error',\n {\n 'test/**/*.ts?(x)': 'KEBAB_CASE',\n },\n {\n ignoreMiddleExtensions: true,\n },\n ],\n },\n },\n];\n\nexport const buildStyleHygiene = (sourceDir: string): Linter.Config[] => [\n ...buildCanonicalConfig(sourceDir),\n ...perfectionistConfig,\n ...unicornConfig,\n ...unusedImportsConfig,\n ...buildCheckFileConfig(sourceDir),\n];\n","import vitest from '@vitest/eslint-plugin';\nimport jestDom from 'eslint-plugin-jest-dom';\nimport testingLibrary from 'eslint-plugin-testing-library';\nimport type {Linter} from 'eslint';\n\n/**\n * Testing flat-config block.\n *\n * Ports `testHarnessConfig` + `testingLibraryConfig` from GAIA's\n * `eslint.config.mjs`. Wires up Vitest, jest-dom, and Testing Library\n * recommended rules across test/story/test-harness files.\n */\nexport const testing: Linter.Config[] = [\n {\n files: [\n '**/*.test.ts?(x)',\n '**/*.stories.ts?(x)',\n 'test/**/*.ts?(x)',\n ],\n name: 'vitest',\n plugins: {\n 'jest-dom': jestDom,\n vitest,\n },\n rules: {\n ...jestDom.configs['flat/recommended'].rules,\n ...vitest.configs.recommended.rules,\n 'import-x/no-useless-path-segments': [\n 'error',\n {noUselessIndex: true},\n ],\n 'vitest/expect-expect': [\n 'error',\n {assertFunctionNames: ['expect', 'expect*']},\n ],\n // Baseline bump: `recommended` ships no-disabled-tests at `warn`.\n // .skip is the single biggest gaming vector for a RED-verification\n // gate (it makes a failing test stop failing), so GAIA forbids it\n // outright. Park work with test.todo or an inline eslint-disable, not\n // a silent .skip.\n 'vitest/no-disabled-tests': 'error',\n // --- Hardening beyond the `recommended` preset ---------------------\n // Rule names and options verified against @vitest/eslint-plugin\n // v1.6.19. GAIA policy: every lint rule is `error`, never `warn`.\n //\n // Consistency: GAIA uses test() exclusively (120 vs 0 it() across the\n // gaia codebase). In 1.6.19 the `fn` option cascades to the\n // within-describe keyword, so this also governs test()/it() nested in\n // describe blocks. Auto-fixable.\n 'vitest/consistent-test-it': ['error', {fn: 'test'}],\n // Consistency: GAIA uses the `vi` mock API (37 vs 0 `vitest.` across the\n // gaia codebase). Auto-fixable.\n 'vitest/consistent-vitest-vi': ['error', {fn: 'vi'}],\n // RED-gate: a branch in a test body can assert nothing on one path.\n // Enable ONLY this one; `no-conditional-tests` is a byte-identical\n // duplicate in 1.6.19 and would double-report.\n 'vitest/no-conditional-in-test': 'error',\n // RED-gate: fdescribe/fit/xdescribe/xit bypass the active\n // no-focused-tests / no-disabled-tests rules; forbid the prefix\n // spellings so the focus/skip net stays airtight. Auto-fixable.\n 'vitest/no-test-prefixes': 'error',\n // RED-gate: a returned value/promise can resolve after the test\n // \"passes\", swallowing assertions and faking GREEN.\n 'vitest/no-test-return-statement': 'error',\n // RED-gate: empty test('...') stubs pass green and read as coverage;\n // rewrite to test.todo('...') so the gap is explicit. Contradicts\n // `warn-todo`, which stays off. Auto-fixable.\n 'vitest/prefer-todo': 'error',\n // A bare .toThrow() passes on ANY throw, masking the wrong error;\n // require an asserted message or matcher.\n 'vitest/require-to-throw-message': 'error',\n },\n },\n {\n ...testingLibrary.configs['flat/react'],\n files: ['**/*.test.ts?(x)'],\n name: 'testing-library',\n },\n];\n","import type {Linter} from 'eslint';\nimport {buildBase} from './configs/base.js';\nimport {\n betterTailwind,\n type GaiaLintBetterTailwindOptions,\n} from './configs/better-tailwind.js';\nimport {buildGuardrails} from './configs/guardrails.js';\nimport {ignores, type GaiaLintIgnoresOptions} from './configs/ignores.js';\nimport {playwright} from './configs/playwright.js';\nimport {prettier} from './configs/prettier.js';\nimport {react} from './configs/react.js';\nimport {storybook} from './configs/storybook.js';\nimport {buildStyleHygiene} from './configs/style-hygiene.js';\nimport {testing} from './configs/testing.js';\n\nexport type {GaiaLintBetterTailwindOptions, GaiaLintIgnoresOptions};\n\nexport type GaiaLintOptions = {\n /**\n * Application source directory (relative to project root). Used to scope\n * file-path-based rules — filename conventions, hook-folder scoping,\n * `no-relative-import-paths` root, etc.\n *\n * @default 'app'\n */\n sourceDir?: string;\n};\n\n/**\n * Dual-shape `ignores` accessor. Spread it directly for the default\n * configuration (`...lint.ignores`) or call it to override\n * (`...lint.ignores({extra: ['coverage/**']})`).\n */\nexport type GaiaLintIgnores = ((\n opts?: GaiaLintIgnoresOptions,\n) => Linter.Config[]) &\n Iterable<Linter.Config>;\n\nexport type GaiaLintBundle = {\n base: Linter.Config[];\n betterTailwind: (opts: GaiaLintBetterTailwindOptions) => Linter.Config[];\n guardrails: Linter.Config[];\n ignores: GaiaLintIgnores;\n playwright: Linter.Config[];\n prettier: Linter.Config[];\n react: Linter.Config[];\n storybook: Linter.Config[];\n styleHygiene: Linter.Config[];\n testing: Linter.Config[];\n};\n\nconst buildIgnoresAccessor = (): GaiaLintIgnores => {\n const defaults = ignores();\n const accessor = ((opts?: GaiaLintIgnoresOptions) => ignores(opts)) as\n | ((opts?: GaiaLintIgnoresOptions) => Linter.Config[]) &\n Iterable<Linter.Config> & {[Symbol.iterator]?: () => Iterator<Linter.Config>};\n accessor[Symbol.iterator] = () => defaults[Symbol.iterator]();\n return accessor as GaiaLintIgnores;\n};\n\n/**\n * GAIA lint configuration factory.\n *\n * Call once at the top of your `eslint.config.mjs` to bind a `sourceDir`,\n * then spread the returned configs into `defineConfig`. Defaults to GAIA's\n * `'app'` layout; pass `{sourceDir: 'src'}` (or any other value) for\n * projects that store source elsewhere.\n *\n * @example\n * const lint = gaiaLint(); // GAIA / app/\n * const lint = gaiaLint({sourceDir: 'src'}); // src/\n */\nconst gaiaLint = (opts?: GaiaLintOptions): GaiaLintBundle => {\n const sourceDir = opts?.sourceDir ?? 'app';\n return {\n base: buildBase(sourceDir),\n betterTailwind,\n guardrails: buildGuardrails(sourceDir),\n ignores: buildIgnoresAccessor(),\n playwright,\n prettier,\n react,\n storybook,\n styleHygiene: buildStyleHygiene(sourceDir),\n testing,\n };\n};\n\nexport default gaiaLint;\n"],"mappings":"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","names":["plugin","plugin","configs","plugins"]}
1
+ {"version":3,"sources":["../src/configs/base.ts","../src/configs/better-tailwind.ts","../src/configs/guardrails.ts","../src/plugins/no-enum.ts","../src/plugins/no-jsx-iife.ts","../src/plugins/no-switch.ts","../src/configs/ignores.ts","../src/configs/playwright.ts","../src/configs/prettier.ts","../src/configs/react.ts","../src/configs/storybook.ts","../src/configs/style-hygiene.ts","../src/configs/testing.ts","../src/index.ts"],"sourcesContent":["import eslintComments from '@eslint-community/eslint-plugin-eslint-comments';\nimport js from '@eslint/js';\nimport {configs, plugins, rules} from 'eslint-config-airbnb-extended';\nimport preferArrowFunctions from 'eslint-plugin-prefer-arrow-functions';\nimport lodashUnderscore from 'eslint-plugin-you-dont-need-lodash-underscore';\nimport type {ESLint, Linter} from 'eslint';\n\nconst jsConfig: Linter.Config[] = [\n // ESLint recommended config\n {\n name: 'js/config',\n ...js.configs.recommended,\n },\n // Stylistic plugin\n plugins.stylistic,\n // Import X plugin\n plugins.importX,\n // Airbnb base recommended config\n ...configs.base.recommended,\n // Strict import rules\n rules.base.importsStrict,\n];\n\nconst jsCustomConfig: Linter.Config[] = [\n {\n name: 'js-custom',\n rules: {\n 'consistent-return': 'off',\n curly: ['error', 'all'],\n 'max-params': 'error',\n 'no-param-reassign': 'off', // handled by sonarjs\n 'no-undef': 'off',\n 'no-unused-vars': 'off', // handled by sonarjs\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'test-files/all',\n rules: {\n 'guard-for-in': 'off',\n 'max-params': 'off',\n 'no-await-in-loop': 'off',\n 'no-plusplus': 'off',\n 'no-restricted-syntax': 'off',\n },\n },\n {\n files: ['.playwright/**/*.ts?(x)'],\n name: 'playwright/all',\n rules: {\n 'no-await-in-loop': 'off',\n 'no-restricted-syntax': 'off',\n },\n },\n];\n\nconst typescriptConfig: Linter.Config[] = [\n // TypeScript ESLint plugin\n plugins.typescriptEslint,\n // Airbnb base TypeScript config\n ...configs.base.typescript,\n // Strict TypeScript rules\n rules.typescript.typescriptEslintStrict,\n rules.typescript.stylistic,\n // Airbnb React TypeScript config\n ...configs.react.typescript,\n {\n files: ['./*.ts'],\n name: 'root-ts-files',\n rules: {\n 'global-require': 'off',\n 'no-void': 'off',\n },\n },\n {\n files: ['**/*.ts?(x)'],\n name: 'no-void',\n rules: {\n 'no-void': ['error', {allowAsStatement: true}],\n },\n },\n];\n\nconst buildTsEslintConfig = (sourceDir: string): Linter.Config[] => [\n {\n files: ['**/*.ts?(x)'],\n name: 'typescript/config',\n rules: {\n '@typescript-eslint/array-type': ['error', {default: 'array'}],\n '@typescript-eslint/ban-ts-comment': [\n 'error',\n {\n minimumDescriptionLength: 10,\n 'ts-check': false,\n 'ts-expect-error': 'allow-with-description',\n 'ts-ignore': true,\n 'ts-nocheck': true,\n },\n ],\n '@typescript-eslint/consistent-type-definitions': ['error', 'type'],\n '@typescript-eslint/consistent-type-imports': 'error',\n '@typescript-eslint/explicit-module-boundary-types': 'off',\n '@typescript-eslint/method-signature-style': 'error',\n '@typescript-eslint/no-confusing-void-expression': [\n 'error',\n {ignoreArrowShorthand: true},\n ],\n '@typescript-eslint/no-floating-promises': [\n 'error',\n {ignoreIIFE: true, ignoreVoid: true},\n ],\n '@typescript-eslint/no-misused-promises': [\n 'error',\n {checksVoidReturn: false},\n ],\n '@typescript-eslint/no-non-null-assertion': 'off',\n '@typescript-eslint/no-throw-literal': 'off',\n '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',\n '@typescript-eslint/no-unnecessary-condition': 'error',\n '@typescript-eslint/no-unnecessary-type-parameters': 'off',\n '@typescript-eslint/no-unsafe-assignment': 'error',\n '@typescript-eslint/no-unsafe-return': 'error',\n '@typescript-eslint/only-throw-error': 'off',\n '@typescript-eslint/prefer-nullish-coalescing': 'error',\n '@typescript-eslint/prefer-promise-reject-errors': 'off',\n '@typescript-eslint/restrict-template-expressions': [\n 'error',\n {allowBoolean: true, allowNumber: true},\n ],\n '@typescript-eslint/return-await': 'off',\n '@typescript-eslint/unbound-method': 'off',\n },\n },\n {\n files: [\n `${sourceDir}/hooks/**/*`,\n `${sourceDir}/routes/**/*`,\n `${sourceDir}/sessions.server/**/*`,\n ],\n name: 'typescript/only-throw-error',\n rules: {\n '@typescript-eslint/only-throw-error': 'off',\n },\n },\n {\n files: [\n `${sourceDir}/utils/**`,\n `${sourceDir}/services/**`,\n `${sourceDir}/hooks/**`,\n ],\n name: 'typescript/explicit-return-types',\n rules: {\n '@typescript-eslint/explicit-module-boundary-types': 'error',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'typescript/test-files',\n rules: {\n '@typescript-eslint/no-explicit-any': 'off',\n '@typescript-eslint/no-unsafe-assignment': 'off',\n '@typescript-eslint/no-unsafe-member-access': 'off',\n },\n },\n {\n files: ['test/**/*.ts?(x)'],\n name: 'typescript/test-config',\n rules: {\n '@typescript-eslint/no-var-requires': 'off',\n 'no-plusplus': 'off',\n },\n },\n {\n files: ['**/*.d.ts'],\n name: 'typescript/type-definitions',\n rules: {\n '@typescript-eslint/consistent-type-definitions': 'off',\n '@typescript-eslint/method-signature-style': 'error',\n '@typescript-eslint/no-unused-vars': 'off',\n },\n },\n];\n\nconst buildImportXConfig = (sourceDir: string): Linter.Config[] => [\n {\n name: 'import-x-all-files',\n rules: {\n 'import-x/consistent-type-specifier-style': ['error', 'prefer-top-level'],\n 'import-x/extensions': 'off',\n 'import-x/no-anonymous-default-export': [\n 'error',\n {\n allowArray: true,\n allowLiteral: true,\n allowObject: true,\n },\n ],\n 'import-x/no-namespace': 'off',\n 'import-x/no-rename-default': 'off',\n 'import-x/no-useless-path-segments': 'off',\n 'import-x/order': 'off',\n 'import-x/prefer-default-export': 'off',\n },\n },\n {\n files: ['./*.ts'],\n name: 'import-x/root-ts-files',\n rules: {\n 'import-x/no-extraneous-dependencies': 'off',\n 'import-x/no-unresolved': 'error',\n 'import-x/prefer-default-export': 'off',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'import-x/test-files',\n rules: {\n 'import-x/extensions': 'off',\n 'import-x/no-extraneous-dependencies': 'off',\n },\n },\n {\n files: [`${sourceDir}/**/!(*.test|*.stories).ts?(x)`],\n name: 'import-x/app-test-files',\n rules: {\n 'import-x/no-unresolved': 'error',\n },\n },\n {\n files: [`${sourceDir}/**/hooks/*.ts?(x)`],\n name: 'import-x/hooks',\n rules: {\n 'import-x/no-default-export': 'error',\n },\n },\n {\n files: ['test/**/*.ts?(x)'],\n name: 'import-x/test-config-files',\n rules: {\n 'import-x/no-extraneous-dependencies': 'off',\n 'import-x/prefer-default-export': 'off',\n },\n },\n {\n files: ['.storybook/**/*.ts?(x)', '.playwright/**/*.ts?(x)'],\n name: 'import-x/storybook-playwright',\n rules: {\n 'import-x/no-extraneous-dependencies': 'off',\n 'import-x/no-unresolved': 'off',\n },\n },\n];\n\nconst eslintCommentsConfig: Linter.Config[] = [\n {\n name: 'eslint-comments',\n plugins: {\n 'eslint-comments': eslintComments,\n },\n rules: {\n 'eslint-comments/disable-enable-pair': 'off',\n 'eslint-comments/no-unused-disable': 'error',\n },\n },\n];\n\nconst preferArrowFunctionsConfig: Linter.Config[] = [\n {\n name: 'prefer-arrow',\n plugins: {\n 'prefer-arrow-functions': preferArrowFunctions as unknown as ESLint.Plugin,\n },\n rules: {\n 'prefer-arrow-functions/prefer-arrow-functions': 'error',\n },\n },\n {\n files: ['**/*.d.ts'],\n name: 'ts-definition-files/prefer-arrow-off',\n rules: {\n 'prefer-arrow-functions/prefer-arrow-functions': 'off',\n },\n },\n];\n\n/**\n * All `no-restricted-syntax` selectors live in one config object. ESLint flat\n * config merges this rule key by replacement (last match wins), not\n * concatenation, so a second block matching the same files would silently\n * clobber these selectors. Each selector carries its own message.\n *\n * `.d.ts` is ignored: ambient `export default function …(): T;` declarations\n * have no body to convert, and type-definition files contain no render code.\n */\nconst restrictedSyntaxConfig: Linter.Config[] = [\n {\n ignores: ['**/*.d.ts'],\n name: 'gaia/no-restricted-syntax',\n rules: {\n 'no-restricted-syntax': [\n 'error',\n {\n // `prefer-arrow-functions` has a hardcoded exemption for named\n // default-exported declarations\n // (`guard.js:hasNameAndIsExportedAsDefaultExport`), so\n // `export default function Foo() {}` slips through. This selector\n // closes that gap.\n message:\n 'Use `const Name = () => {}; export default Name;` instead. The prefer-arrow-functions plugin exempts named default-exported declarations upstream.',\n selector: 'ExportDefaultDeclaration > FunctionDeclaration',\n },\n {\n // GAIA never renders `null`. `cond ? <JSX/> : null` is the\n // numeric-0-safe `&&` guard written the long way. Both JSX-null\n // ternary selectors only match a JSXElement/JSXFragment branch, so\n // they are inert outside `.tsx`/`.jsx`.\n message:\n 'Do not render `null` from a ternary. Use a boolean-guarded `&&`: `cond && <JSX/>` (coerce a numeric/falsy guard with `!!cond`).',\n selector:\n \"ConditionalExpression[alternate.raw='null']:matches([consequent.type='JSXElement'], [consequent.type='JSXFragment'])\",\n },\n {\n message:\n 'Do not render `null` from a ternary. Invert the condition and use `&&`: `!cond && <JSX/>`.',\n selector:\n \"ConditionalExpression[consequent.raw='null']:matches([alternate.type='JSXElement'], [alternate.type='JSXFragment'])\",\n },\n ],\n },\n },\n];\n\nconst lodashUnderscoreConfig: Linter.Config[] = [\n {\n name: 'you-dont-need-lodash-underscore',\n plugins: {\n 'you-dont-need-lodash-underscore':\n lodashUnderscore as unknown as ESLint.Plugin,\n },\n rules: {\n ...(lodashUnderscore.configs.compatible.rules as Linter.RulesRecord),\n },\n },\n];\n\nexport const buildBase = (sourceDir: string): Linter.Config[] => [\n ...jsConfig,\n ...jsCustomConfig,\n ...typescriptConfig,\n ...buildTsEslintConfig(sourceDir),\n ...buildImportXConfig(sourceDir),\n ...eslintCommentsConfig,\n ...preferArrowFunctionsConfig,\n ...restrictedSyntaxConfig,\n ...lodashUnderscoreConfig,\n];\n","import betterTailwindPlugin from 'eslint-plugin-better-tailwindcss';\nimport type {Linter} from 'eslint';\n\nexport type GaiaLintBetterTailwindOptions = {\n /** Path to the Tailwind entry CSS file (e.g. './app/styles/tailwind.css'). */\n entryPoint: string;\n /** Class names to ignore in `better-tailwindcss/no-unknown-classes`. */\n ignore?: string[];\n};\n\n/**\n * Better-Tailwind flat-config factory.\n *\n * Ports `betterTailwindConfig` from GAIA's `eslint.config.mjs`. The\n * `entryPoint` (consumer's Tailwind CSS entry) and `ignore` list are\n * project-specific, so this is shipped as a factory rather than a static\n * array.\n */\nexport const betterTailwind = (\n opts: GaiaLintBetterTailwindOptions,\n): Linter.Config[] => [\n {\n name: 'better-tailwindcss',\n plugins: {\n 'better-tailwindcss': betterTailwindPlugin,\n },\n rules: {\n 'better-tailwindcss/enforce-canonical-classes': 'error',\n 'better-tailwindcss/enforce-consistent-important-position': 'error',\n 'better-tailwindcss/enforce-consistent-variable-syntax': 'error',\n 'better-tailwindcss/enforce-shorthand-classes': 'error',\n 'better-tailwindcss/no-conflicting-classes': 'error',\n 'better-tailwindcss/no-deprecated-classes': 'error',\n 'better-tailwindcss/no-unknown-classes': [\n 'error',\n {ignore: opts.ignore ?? []},\n ],\n },\n settings: {\n 'better-tailwindcss': {\n detectComponentClasses: true,\n entryPoint: opts.entryPoint,\n },\n },\n },\n];\n","import type {Linter} from 'eslint';\nimport noRelativeImportPaths from 'eslint-plugin-no-relative-import-paths';\nimport sonarjs from 'eslint-plugin-sonarjs';\nimport noEnumPlugin from '../plugins/no-enum.js';\nimport noJsxIifePlugin from '../plugins/no-jsx-iife.js';\nimport noSwitchPlugin from '../plugins/no-switch.js';\n\nconst buildSonarConfig = (sourceDir: string): Linter.Config[] => [\n sonarjs.configs!.recommended as Linter.Config,\n {\n name: 'sonarjs',\n rules: {\n 'sonarjs/cognitive-complexity': 'error',\n 'sonarjs/fixme-tag': 'off',\n 'sonarjs/no-commented-code': 'off',\n 'sonarjs/no-nested-conditional': 'off',\n 'sonarjs/no-nested-functions': 'off',\n 'sonarjs/no-selector-parameter': 'off',\n 'sonarjs/regex-complexity': 'off',\n 'sonarjs/todo-tag': 'off',\n },\n },\n {\n files: ['**/*.tsx', '**/hooks/*.ts?(x)'],\n name: 'sonarjs/react-files',\n rules: {\n 'sonarjs/cognitive-complexity': 'off',\n 'sonarjs/function-return-type': 'off',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'sonarjs/test-files',\n rules: {\n 'sonarjs/no-duplicate-string': 'off',\n 'sonarjs/no-identical-functions': 'off',\n },\n },\n {\n files: [`${sourceDir}/languages/**/*.ts`, 'eslint.config.mjs'],\n name: 'sonarjs/credential-checks',\n rules: {\n 'sonarjs/no-hardcoded-credentials': 'off',\n 'sonarjs/no-hardcoded-passwords': 'off',\n },\n },\n];\n\nconst noEnumConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)'],\n name: 'no-enum',\n plugins: {'no-enum': noEnumPlugin},\n rules: {\n 'no-enum/no-enum': 'error',\n },\n },\n];\n\nconst noJsxIifeConfig: Linter.Config[] = [\n {\n files: ['**/*.tsx', '**/*.jsx'],\n name: 'no-jsx-iife',\n plugins: {'no-jsx-iife': noJsxIifePlugin},\n rules: {'no-jsx-iife/no-jsx-iife': 'error'},\n },\n];\n\nconst noSwitchConfig: Linter.Config[] = [\n {\n files: ['**/*.ts?(x)', '**/*.js?(x)'],\n name: 'no-switch',\n plugins: {'no-switch': noSwitchPlugin},\n rules: {'no-switch/no-switch': 'error'},\n },\n];\n\n/**\n * Architecture-boundary enforcement for GAIA's canonical `app/` layout.\n *\n * Imports may only flow from a higher layer to a lower one:\n *\n * routes -> pages -> components -> { hooks, state } -> services -> utils -> types\n *\n * `types/` is a pure leaf importable by everyone. Each zone names a lower\n * layer as `target` and the higher layers it must not import as `from`, so a\n * lower-importing-higher edge (the wrong direction) is reported. `routes`\n * appears in every `from` set, which encodes \"nothing may import a route\".\n *\n * Zone `target`/`from` paths resolve against `process.cwd()` (the consuming\n * project's root where eslint runs), not this package's location in\n * node_modules, so `./${sourceDir}/...` correctly points at the consumer's\n * source tree. `import-x@4.16.2` accepts `from`/`target` as string arrays,\n * which collapses the higher->lower pairs into one zone per target layer.\n *\n * `app/middleware`, `app/sessions.server`, `app/assets`, `app/languages`, and\n * `app/styles` are intentionally left unconstrained (server/asset dirs).\n *\n * The UI layers (pages, components, hooks/state) are exempted from the boundary\n * when importing `routes/resources+` and `routes/actions+`. These are no-UI,\n * typed data endpoints the UI is explicitly meant to consume (e.g.\n * `useFetcher<typeof action>`). `import-x/no-restricted-paths` cannot\n * distinguish a type-only import, so without this carve-out it flags a\n * component's `import type {action}` from a typed endpoint. `except` resolves\n * relative to each zone's `from`; only `routes` contains `actions+`/`resources+`\n * subfolders, so the exemption is scoped to route imports of those endpoints and\n * does not leak to the lower layers. The services, utils, and types zones get no\n * exemption, so the carve-out stays within the UI layer.\n */\nconst buildNoRestrictedPathsConfig = (\n sourceDir: string,\n): Linter.Config[] => {\n const dir = (layer: string): string => `./${sourceDir}/${layer}`;\n const dataEndpoints = ['actions+', 'resources+'];\n\n return [\n {\n files: [`${sourceDir}/**/!(*.test|*.stories).ts?(x)`],\n name: 'import-x/architecture-boundaries',\n rules: {\n 'import-x/no-restricted-paths': [\n 'error',\n {\n zones: [\n {\n except: dataEndpoints,\n from: [dir('routes')],\n message:\n 'Pages may only be imported by routes; a page must not import a route (import direction is routes -> pages -> components). Typed `resources+`/`actions+` data endpoints are exempt.',\n target: dir('pages'),\n },\n {\n except: dataEndpoints,\n from: [dir('routes'), dir('pages')],\n message:\n 'Reusable components must not depend on page- or route-level code (import direction is routes -> pages -> components). Typed `resources+`/`actions+` data endpoints are exempt.',\n target: dir('components'),\n },\n {\n except: dataEndpoints,\n from: [dir('routes'), dir('pages'), dir('components')],\n message:\n 'Hooks and state sit below the UI tree; they must not import components, pages, or routes. Typed `resources+`/`actions+` data endpoints are exempt.',\n target: [dir('hooks'), dir('state')],\n },\n {\n from: [\n dir('routes'),\n dir('pages'),\n dir('components'),\n dir('hooks'),\n dir('state'),\n ],\n message:\n 'The service/data layer sits below the UI and orchestration layers; it must not import components, pages, routes, hooks, or state.',\n target: dir('services'),\n },\n {\n from: [\n dir('routes'),\n dir('pages'),\n dir('components'),\n dir('hooks'),\n dir('state'),\n dir('services'),\n ],\n message:\n 'Utils are near-leaves; they may import only types and other utils.',\n target: dir('utils'),\n },\n {\n from: [\n dir('routes'),\n dir('pages'),\n dir('components'),\n dir('hooks'),\n dir('state'),\n dir('services'),\n dir('utils'),\n ],\n message:\n 'Types are a pure leaf; they must not import any other app layer.',\n target: dir('types'),\n },\n ],\n },\n ],\n },\n },\n ];\n};\n\nconst buildNoRelativeImportPathsConfig = (\n sourceDir: string,\n): Linter.Config[] => [\n {\n name: 'no-relative-import-paths',\n plugins: {\n 'no-relative-import-paths': noRelativeImportPaths,\n },\n rules: {\n 'no-relative-import-paths/no-relative-import-paths': [\n 'error',\n {\n allowedDepth: 2,\n allowSameFolder: true,\n prefix: '~',\n rootDir: sourceDir,\n },\n ],\n },\n },\n];\n\nexport const buildGuardrails = (sourceDir: string): Linter.Config[] => [\n ...buildSonarConfig(sourceDir),\n ...noEnumConfig,\n ...noJsxIifeConfig,\n ...noSwitchConfig,\n ...buildNoRestrictedPathsConfig(sourceDir),\n ...buildNoRelativeImportPathsConfig(sourceDir),\n];\n","import type {ESLint, Rule} from 'eslint';\n\nconst noEnumRule: Rule.RuleModule = {\n create: (context) => ({\n TSEnumDeclaration: (node: Rule.Node) => {\n context.report({messageId: 'noEnum', node});\n },\n }),\n meta: {\n docs: {description: 'Disallow TypeScript enums'},\n messages: {\n noEnum:\n 'Do not use TypeScript enums. Use an object with `as const` instead.',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-enum',\n version: '0.1.0',\n },\n rules: {\n 'no-enum': noEnumRule,\n },\n};\n\nexport default plugin;\n","import type {ESLint, Rule} from 'eslint';\n\nconst noJsxIifeRule: Rule.RuleModule = {\n create: (context) => ({\n 'JSXExpressionContainer > CallExpression > ArrowFunctionExpression.callee':\n (node: Rule.Node) => {\n context.report({messageId: 'noJsxIife', node});\n },\n 'JSXExpressionContainer > CallExpression > FunctionExpression.callee': (\n node: Rule.Node,\n ) => {\n context.report({messageId: 'noJsxIife', node});\n },\n }),\n meta: {\n docs: {description: 'Disallow IIFEs in JSX expressions'},\n messages: {\n noJsxIife:\n 'Do not use IIFEs in JSX. Use a computed variable before the return or extract a component instead.',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-jsx-iife',\n version: '0.1.0',\n },\n rules: {\n 'no-jsx-iife': noJsxIifeRule,\n },\n};\n\nexport default plugin;\n","import type {ESLint, Rule} from 'eslint';\n\nconst noSwitchRule: Rule.RuleModule = {\n create: (context) => ({\n SwitchStatement: (node: Rule.Node) => {\n context.report({messageId: 'noSwitch', node});\n },\n }),\n meta: {\n docs: {description: 'Disallow switch statements'},\n messages: {\n noSwitch:\n 'Do not use switch statements. Use an object map or if/else instead.',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nconst plugin: ESLint.Plugin = {\n meta: {\n name: 'no-switch',\n version: '0.1.0',\n },\n rules: {\n 'no-switch': noSwitchRule,\n },\n};\n\nexport default plugin;\n","import {includeIgnoreFile} from '@eslint/config-helpers';\nimport type {Linter} from 'eslint';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport type GaiaLintIgnoresOptions = {\n /**\n * Path to a `.gitignore` file to merge in. Resolved from `process.cwd()`\n * if relative. Pass `false` to skip the gitignore merge entirely.\n *\n * If the resolved path does not exist, the merge is silently skipped —\n * projects without a `.gitignore` don't need to opt out explicitly.\n *\n * @default '.gitignore'\n */\n gitignore?: string | false;\n /** Extra ignore globs to merge with GAIA defaults. */\n extra?: string[];\n};\n\n/**\n * GAIA's default ignore globs — matches the static `ignored-files` block in\n * GAIA's `eslint.config.mjs`. Consumer's `extra` ignores get concatenated\n * onto this list.\n */\nconst defaultIgnores = [\n '.storybook',\n '.playwright',\n '/.react-router/**',\n '.claude/**/*.js',\n '.claude/**/*.cjs',\n 'scripts',\n 'public/**',\n '**/*.css',\n '**/*.svg',\n '**/*.md',\n];\n\n/**\n * Ignores flat-config factory.\n *\n * Ports the `includeIgnoreFile(gitignorePath)` + static `ignored-files`\n * block from GAIA's `eslint.config.mjs`. The `gitignore` path must be\n * resolved at the consumer's cwd (config-load time), not at gaia-lint's\n * install location, so this is shipped as a factory.\n */\nexport const ignores = (opts?: GaiaLintIgnoresOptions): Linter.Config[] => {\n const out: Linter.Config[] = [];\n\n const gitignore = opts?.gitignore ?? '.gitignore';\n if (gitignore !== false) {\n const resolved = path.isAbsolute(gitignore)\n ? gitignore\n : path.resolve(process.cwd(), gitignore);\n if (fs.existsSync(resolved)) {\n out.push(includeIgnoreFile(resolved) as Linter.Config);\n }\n }\n\n out.push({\n ignores: [...defaultIgnores, ...(opts?.extra ?? [])],\n name: 'ignored-files',\n });\n\n return out;\n};\n","import playwrightPlugin from 'eslint-plugin-playwright';\nimport type {Linter} from 'eslint';\n\n/**\n * Playwright flat-config block.\n *\n * Ports `playwrightConfig` from GAIA's `eslint.config.mjs` — scopes\n * `eslint-plugin-playwright`'s `flat/recommended` config to `.playwright/`\n * test files (GAIA's e2e directory convention).\n */\nexport const playwright: Linter.Config[] = [\n {\n name: 'playwright',\n ...(playwrightPlugin.configs['flat/recommended'] as Linter.Config),\n files: ['.playwright/**/*.ts?(x)'],\n rules: {\n ...playwrightPlugin.configs['flat/recommended'].rules,\n // Every test must assert something. `assertFunctionPatterns` lets custom\n // `expect*()` helpers count as the assertion. Error, never warn: a test\n // that asserts nothing is a false green.\n 'playwright/expect-expect': [\n 'error',\n {assertFunctionPatterns: ['^expect[A-Z]']},\n ],\n },\n },\n];\n","import {rules as prettierConfigRules} from 'eslint-config-prettier';\nimport prettierPlugin from 'eslint-plugin-prettier';\nimport type {Linter} from 'eslint';\n\n/**\n * Prettier flat-config block.\n *\n * Ports `prettierConfig` from GAIA's `eslint.config.mjs`. Layers\n * `eslint-config-prettier`'s rule disablers, then re-enables a few\n * `@stylistic/*` rules GAIA wants to keep (padding lines, single quotes),\n * and finally turns on the `prettier/prettier` rule itself.\n */\nexport const prettier: Linter.Config[] = [\n {\n name: 'prettier/plugin/config',\n plugins: {prettier: prettierPlugin},\n },\n {\n name: 'prettier/config',\n rules: {\n ...prettierConfigRules,\n '@stylistic/padding-line-between-statements': [\n 'error',\n {\n blankLine: 'always',\n next: ['block-like', 'export', 'return', 'throw'],\n prev: '*',\n },\n ],\n '@stylistic/quotes': [\n 'error',\n 'single',\n {\n allowTemplateLiterals: 'avoidEscape',\n avoidEscape: true,\n },\n ],\n '@stylistic/spaced-comment': 'off',\n 'prettier/prettier': ['error', {endOfLine: 'auto'}],\n },\n },\n];\n","import {configs, plugins} from 'eslint-config-airbnb-extended';\nimport type {Linter} from 'eslint';\n\n/**\n * React flat-config block.\n *\n * Ports `reactConfig` + `reactCustomConfig` from GAIA's `eslint.config.mjs`.\n * Pulls React, React Hooks, and JSX A11y plugins plus Airbnb's recommended\n * React config, then layers GAIA's project-wide React rule overrides.\n *\n * The `react-router/routes` override targets `**\\/routes/**\\/*.tsx` — a GAIA\n * convention that's harmless for consumers without that folder structure\n * (the override only fires when files match).\n */\nexport const react: Linter.Config[] = [\n // React plugin\n plugins.react,\n // React hooks plugin\n plugins.reactHooks,\n // React JSX A11y plugin\n plugins.reactA11y,\n // Airbnb React recommended config\n ...configs.react.recommended,\n {\n name: 'react-custom',\n rules: {\n 'jsx-a11y/control-has-associated-label': 'off',\n 'jsx-a11y/no-autofocus': 'off',\n 'react/boolean-prop-naming': [\n 'error',\n {\n propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],\n rule: '^((can|has|hide|is|show)[A-Z]([A-Za-z0-9]?)+|(checked|disabled|hide|required|show))',\n },\n ],\n 'react/function-component-definition': 'off',\n 'react/jsx-boolean-value': ['error', 'always'],\n 'react/jsx-curly-brace-presence': 'error',\n 'react/jsx-filename-extension': 'off',\n 'react/jsx-fragments': 'error',\n // off by default because it doesn't handle props onXyz function names correctly\n // turn this on from time to time to check for misnamed handlers elsewhere\n 'react/jsx-handler-names': ['off', {checkLocalVariables: true}],\n 'react/jsx-newline': ['error', {prevent: true}],\n 'react/jsx-no-useless-fragment': ['error', {allowExpressions: true}],\n 'react/no-children-prop': 'off',\n 'react/no-danger': 'off',\n 'react/prop-types': 'off',\n 'react/react-in-jsx-scope': 'off',\n 'react/require-default-props': 'off',\n },\n },\n {\n files: ['**/routes/**/*.tsx'],\n name: 'react-router/routes',\n rules: {\n 'no-empty-pattern': 'off',\n 'react/display-name': 'off',\n },\n },\n {\n files: ['**/*.test.ts?(x)', '**/*.stories.ts?(x)'],\n name: 'react/test-files',\n rules: {\n 'react/jsx-props-no-spreading': 'off',\n },\n },\n];\n","import storybookPlugin from 'eslint-plugin-storybook';\nimport type {Linter} from 'eslint';\n\n/**\n * Storybook flat-config block.\n *\n * Ports `storybookConfig` from GAIA's `eslint.config.mjs` — applies the\n * official `flat/recommended` config from `eslint-plugin-storybook`.\n */\nexport const storybook: Linter.Config[] = [\n ...(storybookPlugin.configs['flat/recommended'] as Linter.Config[]),\n];\n","import type {Linter} from 'eslint';\nimport canonical from 'eslint-plugin-canonical';\nimport checkFile from 'eslint-plugin-check-file';\nimport perfectionist from 'eslint-plugin-perfectionist';\nimport unicorn from 'eslint-plugin-unicorn';\nimport unusedImports from 'eslint-plugin-unused-imports';\n\nconst buildCanonicalConfig = (sourceDir: string): Linter.Config[] => [\n canonical.configs['flat/recommended'] as Linter.Config,\n {\n name: 'canonical',\n rules: {\n 'canonical/destructuring-property-newline': 'off',\n 'canonical/filename-match-exported': 'error',\n 'canonical/id-match': 'off',\n 'canonical/import-specifier-newline': 'off',\n },\n },\n {\n files: ['**/*.tsx', '**/hooks/*.ts?(x)'],\n name: 'canonical/sort-react-dependencies',\n rules: {\n 'canonical/sort-react-dependencies': 'error',\n },\n },\n {\n files: [\n `${sourceDir}/root.tsx`,\n `${sourceDir}/entry.server.tsx`,\n `${sourceDir}/**/tests/*`,\n 'test/**/*.ts?(x)',\n '**/*.stories.tsx',\n '**/routes/**/*.tsx',\n '**/hooks/*.ts?(x)',\n '.storybook/**/*.ts?(x)',\n '.playwright/**/*.ts?(x)',\n ],\n name: 'canonical/filename-match-exported-disabled',\n rules: {\n 'canonical/filename-match-exported': 'off',\n },\n },\n];\n\nconst perfectionistConfig: Linter.Config[] = [\n perfectionist.configs['recommended-natural'] as Linter.Config,\n {\n name: 'perfectionist',\n rules: {\n 'perfectionist/sort-imports': [\n 'error',\n {\n customGroups: [\n {\n elementNamePattern: '^react$',\n groupName: 'react-type',\n selector: 'type',\n },\n {\n elementNamePattern: '^react$',\n groupName: 'react',\n },\n {\n elementNamePattern: '^react-.+',\n groupName: 'react-other-type',\n selector: 'type',\n },\n {\n elementNamePattern: '^react-.+',\n groupName: 'react-other',\n },\n ],\n groups: [\n 'react-type',\n 'react',\n 'react-other-type',\n 'react-other',\n ['type-external', 'external'],\n ['type-builtin', 'builtin'],\n ['type-internal', 'internal'],\n ['type-parent', 'parent'],\n ['type-sibling', 'sibling'],\n ['type-index', 'index'],\n 'unknown',\n 'style',\n 'side-effect',\n 'side-effect-style',\n ],\n newlinesBetween: 0,\n type: 'natural',\n },\n ],\n 'perfectionist/sort-jsx-props': [\n 'error',\n {\n customGroups: [\n {\n elementNamePattern: ['^key$', '^ref$'],\n groupName: 'reserved',\n },\n ],\n groups: ['reserved'],\n type: 'natural',\n },\n ],\n },\n },\n];\n\nconst unicornConfig: Linter.Config[] = [\n unicorn.configs.recommended as Linter.Config,\n {\n name: 'unicorn',\n rules: {\n 'unicorn/consistent-destructuring': 'error',\n 'unicorn/consistent-template-literal-escape': 'off',\n 'unicorn/filename-case': 'off',\n 'unicorn/new-for-builtins': 'off',\n 'unicorn/no-array-callback-reference': 'off',\n 'unicorn/no-array-for-each': 'off',\n 'unicorn/no-array-reduce': 'off',\n 'unicorn/no-nested-ternary': 'off',\n 'unicorn/no-null': 'off',\n 'unicorn/no-useless-undefined': 'off',\n 'unicorn/prefer-export-from': 'off',\n 'unicorn/prefer-global-this': 'off',\n // `Array#includes` returns a plain boolean, not a type predicate, so it\n // cannot narrow a union the way an `===` comparison chain does. In a typed\n // codebase the chain is the type-safe idiom; forcing `.includes()` discards\n // the narrowing and the value's refined type along with it.\n 'unicorn/prefer-includes-over-repeated-comparisons': 'off',\n 'unicorn/prefer-set-has': 'off',\n 'unicorn/prefer-switch': 'off',\n 'unicorn/prefer-ternary': 'off',\n 'unicorn/prevent-abbreviations': [\n 'error',\n {\n ignore: [\n 'acc',\n 'ctx',\n 'e2e',\n 'env',\n 'obj',\n 'prev',\n 'req',\n 'res',\n /args/i,\n /fn/i,\n /param/i,\n /params/i,\n /props/i,\n /ref/i,\n /src/i,\n /utils/i,\n ],\n },\n ],\n 'unicorn/text-encoding-identifier-case': 'off',\n },\n },\n {\n files: ['./*.ts'],\n name: 'unicorn/root-ts-files',\n rules: {\n 'unicorn/prefer-module': 'off',\n 'unicorn/prevent-abbreviations': 'off',\n },\n },\n];\n\nconst unusedImportsConfig: Linter.Config[] = [\n {\n name: 'unused-imports',\n plugins: {\n 'unused-imports': unusedImports,\n },\n rules: {\n '@typescript-eslint/no-unused-vars': 'off',\n 'no-unused-vars': 'off',\n 'sonarjs/no-unused-vars': 'off',\n 'sonarjs/unused-import': 'off',\n 'unused-imports/no-unused-imports': 'error',\n 'unused-imports/no-unused-vars': [\n 'error',\n {\n args: 'after-used',\n argsIgnorePattern: '^_',\n ignoreRestSiblings: true,\n vars: 'all',\n varsIgnorePattern: '^_',\n },\n ],\n },\n },\n {\n files: ['**/*.d.ts'],\n name: 'unused-imports/ts-definition-files',\n rules: {\n 'unused-imports/no-unused-vars': 'off',\n },\n },\n];\n\nconst buildCheckFileConfig = (sourceDir: string): Linter.Config[] => [\n {\n plugins: {\n 'check-file': checkFile,\n },\n },\n {\n files: [`${sourceDir}/**/*`],\n name: 'check-file',\n rules: {\n 'check-file/filename-naming-convention': [\n 'error',\n {\n // React hook files must be camelCase (to match the hook name)\n '**/hooks/*.{ts,tsx}': 'CAMEL_CASE',\n [`${sourceDir}/state/*.tsx`]: 'KEBAB_CASE',\n // React component files must be named index.tsx\n [`${sourceDir}/{components,pages}/**/!(assets|hooks|state|tests|utils)/*.tsx`]:\n 'index+()',\n // Generally, non-component files must be named kebab-case\n [`${sourceDir}/{components,pages}/**/!(hooks)/*.ts`]: 'KEBAB_CASE',\n // Non-component files inside specific components folders must be kebab-case\n [`${sourceDir}/{components,pages}/**/(assets|state|tests|utils)/*.{ts,tsx}`]:\n 'KEBAB_CASE',\n 'test/**/*.ts?(x)': 'KEBAB_CASE',\n },\n {\n ignoreMiddleExtensions: true,\n },\n ],\n 'check-file/folder-match-with-fex': [\n 'error',\n {\n // require stories and test files to be inside tests folders\n '*.(stories|test).{ts,tsx}': `${sourceDir}/**/tests/`,\n },\n ],\n 'check-file/folder-naming-convention': [\n 'error',\n {\n // enforce PascalCase component folders, and allow assets, hooks, tests, and utils subfolders\n [`${sourceDir}/components/**/`]:\n '(assets|hooks|state|tests|utils|[A-Z][a-zA-Z0-9]*)',\n },\n ],\n },\n },\n {\n files: ['test/**/*.*'],\n name: 'check-file/test-files',\n rules: {\n 'check-file/filename-naming-convention': [\n 'error',\n {\n 'test/**/*.ts?(x)': 'KEBAB_CASE',\n },\n {\n ignoreMiddleExtensions: true,\n },\n ],\n },\n },\n];\n\nexport const buildStyleHygiene = (sourceDir: string): Linter.Config[] => [\n ...buildCanonicalConfig(sourceDir),\n ...perfectionistConfig,\n ...unicornConfig,\n ...unusedImportsConfig,\n ...buildCheckFileConfig(sourceDir),\n];\n","import vitest from '@vitest/eslint-plugin';\nimport jestDom from 'eslint-plugin-jest-dom';\nimport testingLibrary from 'eslint-plugin-testing-library';\nimport type {Linter} from 'eslint';\n\n/**\n * Testing flat-config block.\n *\n * Ports `testHarnessConfig` + `testingLibraryConfig` from GAIA's\n * `eslint.config.mjs`. Wires up Vitest, jest-dom, and Testing Library\n * recommended rules across test/story/test-harness files.\n */\nexport const testing: Linter.Config[] = [\n {\n files: [\n '**/*.test.ts?(x)',\n '**/*.stories.ts?(x)',\n 'test/**/*.ts?(x)',\n ],\n name: 'vitest',\n plugins: {\n 'jest-dom': jestDom,\n vitest,\n },\n rules: {\n ...jestDom.configs['flat/recommended'].rules,\n ...vitest.configs.recommended.rules,\n 'import-x/no-useless-path-segments': [\n 'error',\n {noUselessIndex: true},\n ],\n 'vitest/expect-expect': [\n 'error',\n {assertFunctionNames: ['expect', 'expect*']},\n ],\n // Baseline bump: `recommended` ships no-disabled-tests at `warn`.\n // .skip is the single biggest gaming vector for a RED-verification\n // gate (it makes a failing test stop failing), so GAIA forbids it\n // outright. Park work with test.todo or an inline eslint-disable, not\n // a silent .skip.\n 'vitest/no-disabled-tests': 'error',\n // --- Hardening beyond the `recommended` preset ---------------------\n // Rule names and options verified against @vitest/eslint-plugin\n // v1.6.19. GAIA policy: every lint rule is `error`, never `warn`.\n //\n // Consistency: GAIA uses test() exclusively (120 vs 0 it() across the\n // gaia codebase). In 1.6.19 the `fn` option cascades to the\n // within-describe keyword, so this also governs test()/it() nested in\n // describe blocks. Auto-fixable.\n 'vitest/consistent-test-it': ['error', {fn: 'test'}],\n // Consistency: GAIA uses the `vi` mock API (37 vs 0 `vitest.` across the\n // gaia codebase). Auto-fixable.\n 'vitest/consistent-vitest-vi': ['error', {fn: 'vi'}],\n // RED-gate: a branch in a test body can assert nothing on one path.\n // Enable ONLY this one; `no-conditional-tests` is a byte-identical\n // duplicate in 1.6.19 and would double-report.\n 'vitest/no-conditional-in-test': 'error',\n // RED-gate: fdescribe/fit/xdescribe/xit bypass the active\n // no-focused-tests / no-disabled-tests rules; forbid the prefix\n // spellings so the focus/skip net stays airtight. Auto-fixable.\n 'vitest/no-test-prefixes': 'error',\n // RED-gate: a returned value/promise can resolve after the test\n // \"passes\", swallowing assertions and faking GREEN.\n 'vitest/no-test-return-statement': 'error',\n // RED-gate: empty test('...') stubs pass green and read as coverage;\n // rewrite to test.todo('...') so the gap is explicit. Contradicts\n // `warn-todo`, which stays off. Auto-fixable.\n 'vitest/prefer-todo': 'error',\n // Honesty (D-8 / SPEC-006 Rule 3, the cheap-win stand-in for\n // `gaia-test-honesty/no-call-through-only`). A bare\n // `toHaveBeenCalled()`/`toBeCalled()` proves the function ran but\n // asserts nothing about how (arguments) or how many (count) — a\n // call-through that re-proves the framework, not the behavior.\n //\n // SCOPE NOTE: `prefer-called-with` is BROADER than spec Rule 3. The spec\n // rule fires only when a bare `toHaveBeenCalled()` is the SOLE assertion\n // in a test; `prefer-called-with` fires on EVERY bare\n // `toHaveBeenCalled()`/`toBeCalled()` (it exempts only the `.not` form).\n // So this stands in for Rule 3 rather than matching it exactly.\n 'vitest/prefer-called-with': 'error',\n // A bare .toThrow() passes on ANY throw, masking the wrong error;\n // require an asserted message or matcher.\n 'vitest/require-to-throw-message': 'error',\n },\n },\n {\n // Honesty (D-8 / SPEC-006 Rule 4, the cheap-win stand-in for\n // `gaia-test-honesty/no-server-import-from-consumer`). A consumer test,\n // story, or harness file must not import a server-only (`*.server`) or\n // internal (`/internals/`) module: those are private surface, and\n // reaching into them couples the test to implementation the public\n // interface is meant to hide.\n //\n // Same testing glob as the `vitest` block above. The `*.server.test.*`\n // exemption is the point of Rule 4: a dedicated server-side test IS the\n // right place to import a `.server` module (mirrors the real\n // `app/utils/tests/http.server.test.ts` importing `../http.server`).\n //\n // Implemented with the core `no-restricted-imports` rule (config only, no\n // custom plugin) rather than a dedicated AST rule. Chosen over\n // `import-x/no-restricted-paths` because Rule 4 keys off the import\n // SPECIFIER shape (`*.server`, `/internals/`) plus a per-file filename\n // exemption, not the directory `from`/`target` zones that\n // `no-restricted-paths` models.\n //\n // LIMITATION vs the would-be custom rule: `no-restricted-imports` covers\n // static `import` / `export ... from` only, NOT dynamic\n // `import('./x.server')`. The dynamic case is intentionally out of scope\n // for this cheap-win form; the advisory worthiness audit backstops it.\n //\n // ERROR severity, per spec (Rule 4 is an error rule).\n files: [\n '**/*.test.ts?(x)',\n '**/*.stories.ts?(x)',\n 'test/**/*.ts?(x)',\n ],\n ignores: ['**/*.server.test.*'],\n name: 'gaia-test-honesty/no-server-import-from-consumer',\n rules: {\n 'no-restricted-imports': [\n 'error',\n {\n patterns: [\n {\n group: ['**/*.server'],\n message:\n \"Do not import a server-only ('*.server') module from a consumer test. Server-only modules are private surface: reach them through the public interface, or from a dedicated *.server.test.* file (which is exempt from this rule).\",\n },\n {\n group: ['**/internals/**', '**/internals'],\n message:\n \"Do not import an internal ('/internals/') module from a consumer test. Internal modules are private surface: importing them couples the test to implementation the public interface is meant to hide. Reach the behavior through the public interface instead.\",\n },\n ],\n },\n ],\n },\n },\n {\n ...testingLibrary.configs['flat/react'],\n files: ['**/*.test.ts?(x)'],\n name: 'testing-library',\n },\n];\n","import type {Linter} from 'eslint';\nimport {buildBase} from './configs/base.js';\nimport {\n betterTailwind,\n type GaiaLintBetterTailwindOptions,\n} from './configs/better-tailwind.js';\nimport {buildGuardrails} from './configs/guardrails.js';\nimport {ignores, type GaiaLintIgnoresOptions} from './configs/ignores.js';\nimport {playwright} from './configs/playwright.js';\nimport {prettier} from './configs/prettier.js';\nimport {react} from './configs/react.js';\nimport {storybook} from './configs/storybook.js';\nimport {buildStyleHygiene} from './configs/style-hygiene.js';\nimport {testing} from './configs/testing.js';\n\nexport type {GaiaLintBetterTailwindOptions, GaiaLintIgnoresOptions};\n\nexport type GaiaLintOptions = {\n /**\n * Application source directory (relative to project root). Used to scope\n * file-path-based rules — filename conventions, hook-folder scoping,\n * `no-relative-import-paths` root, etc.\n *\n * @default 'app'\n */\n sourceDir?: string;\n};\n\n/**\n * Dual-shape `ignores` accessor. Spread it directly for the default\n * configuration (`...lint.ignores`) or call it to override\n * (`...lint.ignores({extra: ['coverage/**']})`).\n */\nexport type GaiaLintIgnores = ((\n opts?: GaiaLintIgnoresOptions,\n) => Linter.Config[]) &\n Iterable<Linter.Config>;\n\nexport type GaiaLintBundle = {\n base: Linter.Config[];\n betterTailwind: (opts: GaiaLintBetterTailwindOptions) => Linter.Config[];\n guardrails: Linter.Config[];\n ignores: GaiaLintIgnores;\n playwright: Linter.Config[];\n prettier: Linter.Config[];\n react: Linter.Config[];\n storybook: Linter.Config[];\n styleHygiene: Linter.Config[];\n testing: Linter.Config[];\n};\n\nconst buildIgnoresAccessor = (): GaiaLintIgnores => {\n const defaults = ignores();\n const accessor = ((opts?: GaiaLintIgnoresOptions) => ignores(opts)) as\n | ((opts?: GaiaLintIgnoresOptions) => Linter.Config[]) &\n Iterable<Linter.Config> & {[Symbol.iterator]?: () => Iterator<Linter.Config>};\n accessor[Symbol.iterator] = () => defaults[Symbol.iterator]();\n return accessor as GaiaLintIgnores;\n};\n\n/**\n * GAIA lint configuration factory.\n *\n * Call once at the top of your `eslint.config.mjs` to bind a `sourceDir`,\n * then spread the returned configs into `defineConfig`. Defaults to GAIA's\n * `'app'` layout; pass `{sourceDir: 'src'}` (or any other value) for\n * projects that store source elsewhere.\n *\n * @example\n * const lint = gaiaLint(); // GAIA / app/\n * const lint = gaiaLint({sourceDir: 'src'}); // src/\n */\nconst gaiaLint = (opts?: GaiaLintOptions): GaiaLintBundle => {\n const sourceDir = opts?.sourceDir ?? 'app';\n return {\n base: buildBase(sourceDir),\n betterTailwind,\n guardrails: buildGuardrails(sourceDir),\n ignores: buildIgnoresAccessor(),\n playwright,\n prettier,\n react,\n storybook,\n styleHygiene: buildStyleHygiene(sourceDir),\n testing,\n };\n};\n\nexport default gaiaLint;\n"],"mappings":";AAAA,OAAO,oBAAoB;AAC3B,OAAO,QAAQ;AACf,SAAQ,SAAS,SAAS,aAAY;AACtC,OAAO,0BAA0B;AACjC,OAAO,sBAAsB;AAG7B,IAAM,WAA4B;AAAA;AAAA,EAEhC;AAAA,IACE,MAAM;AAAA,IACN,GAAG,GAAG,QAAQ;AAAA,EAChB;AAAA;AAAA,EAEA,QAAQ;AAAA;AAAA,EAER,QAAQ;AAAA;AAAA,EAER,GAAG,QAAQ,KAAK;AAAA;AAAA,EAEhB,MAAM,KAAK;AACb;AAEA,IAAM,iBAAkC;AAAA,EACtC;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,MACL,qBAAqB;AAAA,MACrB,OAAO,CAAC,SAAS,KAAK;AAAA,MACtB,cAAc;AAAA,MACd,qBAAqB;AAAA;AAAA,MACrB,YAAY;AAAA,MACZ,kBAAkB;AAAA;AAAA,IACpB;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,oBAAoB,qBAAqB;AAAA,IACjD,MAAM;AAAA,IACN,OAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,oBAAoB;AAAA,MACpB,eAAe;AAAA,MACf,wBAAwB;AAAA,IAC1B;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,yBAAyB;AAAA,IACjC,MAAM;AAAA,IACN,OAAO;AAAA,MACL,oBAAoB;AAAA,MACpB,wBAAwB;AAAA,IAC1B;AAAA,EACF;AACF;AAEA,IAAM,mBAAoC;AAAA;AAAA,EAExC,QAAQ;AAAA;AAAA,EAER,GAAG,QAAQ,KAAK;AAAA;AAAA,EAEhB,MAAM,WAAW;AAAA,EACjB,MAAM,WAAW;AAAA;AAAA,EAEjB,GAAG,QAAQ,MAAM;AAAA,EACjB;AAAA,IACE,OAAO,CAAC,QAAQ;AAAA,IAChB,MAAM;AAAA,IACN,OAAO;AAAA,MACL,kBAAkB;AAAA,MAClB,WAAW;AAAA,IACb;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,aAAa;AAAA,IACrB,MAAM;AAAA,IACN,OAAO;AAAA,MACL,WAAW,CAAC,SAAS,EAAC,kBAAkB,KAAI,CAAC;AAAA,IAC/C;AAAA,EACF;AACF;AAEA,IAAM,sBAAsB,CAAC,cAAuC;AAAA,EAClE;AAAA,IACE,OAAO,CAAC,aAAa;AAAA,IACrB,MAAM;AAAA,IACN,OAAO;AAAA,MACL,iCAAiC,CAAC,SAAS,EAAC,SAAS,QAAO,CAAC;AAAA,MAC7D,qCAAqC;AAAA,QACnC;AAAA,QACA;AAAA,UACE,0BAA0B;AAAA,UAC1B,YAAY;AAAA,UACZ,mBAAmB;AAAA,UACnB,aAAa;AAAA,UACb,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA,kDAAkD,CAAC,SAAS,MAAM;AAAA,MAClE,8CAA8C;AAAA,MAC9C,qDAAqD;AAAA,MACrD,6CAA6C;AAAA,MAC7C,mDAAmD;AAAA,QACjD;AAAA,QACA,EAAC,sBAAsB,KAAI;AAAA,MAC7B;AAAA,MACA,2CAA2C;AAAA,QACzC;AAAA,QACA,EAAC,YAAY,MAAM,YAAY,KAAI;AAAA,MACrC;AAAA,MACA,0CAA0C;AAAA,QACxC;AAAA,QACA,EAAC,kBAAkB,MAAK;AAAA,MAC1B;AAAA,MACA,4CAA4C;AAAA,MAC5C,uCAAuC;AAAA,MACvC,6DAA6D;AAAA,MAC7D,+CAA+C;AAAA,MAC/C,qDAAqD;AAAA,MACrD,2CAA2C;AAAA,MAC3C,uCAAuC;AAAA,MACvC,uCAAuC;AAAA,MACvC,gDAAgD;AAAA,MAChD,mDAAmD;AAAA,MACnD,oDAAoD;AAAA,QAClD;AAAA,QACA,EAAC,cAAc,MAAM,aAAa,KAAI;AAAA,MACxC;AAAA,MACA,mCAAmC;AAAA,MACnC,qCAAqC;AAAA,IACvC;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,MACL,GAAG,SAAS;AAAA,MACZ,GAAG,SAAS;AAAA,MACZ,GAAG,SAAS;AAAA,IACd;AAAA,IACA,MAAM;AAAA,IACN,OAAO;AAAA,MACL,uCAAuC;AAAA,IACzC;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,MACL,GAAG,SAAS;AAAA,MACZ,GAAG,SAAS;AAAA,MACZ,GAAG,SAAS;AAAA,IACd;AAAA,IACA,MAAM;AAAA,IACN,OAAO;AAAA,MACL,qDAAqD;AAAA,IACvD;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,oBAAoB,qBAAqB;AAAA,IACjD,MAAM;AAAA,IACN,OAAO;AAAA,MACL,sCAAsC;AAAA,MACtC,2CAA2C;AAAA,MAC3C,8CAA8C;AAAA,IAChD;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,kBAAkB;AAAA,IAC1B,MAAM;AAAA,IACN,OAAO;AAAA,MACL,sCAAsC;AAAA,MACtC,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,WAAW;AAAA,IACnB,MAAM;AAAA,IACN,OAAO;AAAA,MACL,kDAAkD;AAAA,MAClD,6CAA6C;AAAA,MAC7C,qCAAqC;AAAA,IACvC;AAAA,EACF;AACF;AAEA,IAAM,qBAAqB,CAAC,cAAuC;AAAA,EACjE;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,MACL,4CAA4C,CAAC,SAAS,kBAAkB;AAAA,MACxE,uBAAuB;AAAA,MACvB,wCAAwC;AAAA,QACtC;AAAA,QACA;AAAA,UACE,YAAY;AAAA,UACZ,cAAc;AAAA,UACd,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,yBAAyB;AAAA,MACzB,8BAA8B;AAAA,MAC9B,qCAAqC;AAAA,MACrC,kBAAkB;AAAA,MAClB,kCAAkC;AAAA,IACpC;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,QAAQ;AAAA,IAChB,MAAM;AAAA,IACN,OAAO;AAAA,MACL,uCAAuC;AAAA,MACvC,0BAA0B;AAAA,MAC1B,kCAAkC;AAAA,IACpC;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,oBAAoB,qBAAqB;AAAA,IACjD,MAAM;AAAA,IACN,OAAO;AAAA,MACL,uBAAuB;AAAA,MACvB,uCAAuC;AAAA,IACzC;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,GAAG,SAAS,gCAAgC;AAAA,IACpD,MAAM;AAAA,IACN,OAAO;AAAA,MACL,0BAA0B;AAAA,IAC5B;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,GAAG,SAAS,oBAAoB;AAAA,IACxC,MAAM;AAAA,IACN,OAAO;AAAA,MACL,8BAA8B;AAAA,IAChC;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,kBAAkB;AAAA,IAC1B,MAAM;AAAA,IACN,OAAO;AAAA,MACL,uCAAuC;AAAA,MACvC,kCAAkC;AAAA,IACpC;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,0BAA0B,yBAAyB;AAAA,IAC3D,MAAM;AAAA,IACN,OAAO;AAAA,MACL,uCAAuC;AAAA,MACvC,0BAA0B;AAAA,IAC5B;AAAA,EACF;AACF;AAEA,IAAM,uBAAwC;AAAA,EAC5C;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,MACP,mBAAmB;AAAA,IACrB;AAAA,IACA,OAAO;AAAA,MACL,uCAAuC;AAAA,MACvC,qCAAqC;AAAA,IACvC;AAAA,EACF;AACF;AAEA,IAAM,6BAA8C;AAAA,EAClD;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,MACP,0BAA0B;AAAA,IAC5B;AAAA,IACA,OAAO;AAAA,MACL,iDAAiD;AAAA,IACnD;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,WAAW;AAAA,IACnB,MAAM;AAAA,IACN,OAAO;AAAA,MACL,iDAAiD;AAAA,IACnD;AAAA,EACF;AACF;AAWA,IAAM,yBAA0C;AAAA,EAC9C;AAAA,IACE,SAAS,CAAC,WAAW;AAAA,IACrB,MAAM;AAAA,IACN,OAAO;AAAA,MACL,wBAAwB;AAAA,QACtB;AAAA,QACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAME,SACE;AAAA,UACF,UAAU;AAAA,QACZ;AAAA,QACA;AAAA;AAAA;AAAA;AAAA;AAAA,UAKE,SACE;AAAA,UACF,UACE;AAAA,QACJ;AAAA,QACA;AAAA,UACE,SACE;AAAA,UACF,UACE;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,yBAA0C;AAAA,EAC9C;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,MACP,mCACE;AAAA,IACJ;AAAA,IACA,OAAO;AAAA,MACL,GAAI,iBAAiB,QAAQ,WAAW;AAAA,IAC1C;AAAA,EACF;AACF;AAEO,IAAM,YAAY,CAAC,cAAuC;AAAA,EAC/D,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG,oBAAoB,SAAS;AAAA,EAChC,GAAG,mBAAmB,SAAS;AAAA,EAC/B,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;;;ACnWA,OAAO,0BAA0B;AAkB1B,IAAM,iBAAiB,CAC5B,SACoB;AAAA,EACpB;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,MACP,sBAAsB;AAAA,IACxB;AAAA,IACA,OAAO;AAAA,MACL,gDAAgD;AAAA,MAChD,4DAA4D;AAAA,MAC5D,yDAAyD;AAAA,MACzD,gDAAgD;AAAA,MAChD,6CAA6C;AAAA,MAC7C,4CAA4C;AAAA,MAC5C,yCAAyC;AAAA,QACvC;AAAA,QACA,EAAC,QAAQ,KAAK,UAAU,CAAC,EAAC;AAAA,MAC5B;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,sBAAsB;AAAA,QACpB,wBAAwB;AAAA,QACxB,YAAY,KAAK;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AACF;;;AC5CA,OAAO,2BAA2B;AAClC,OAAO,aAAa;;;ACApB,IAAM,aAA8B;AAAA,EAClC,QAAQ,CAAC,aAAa;AAAA,IACpB,mBAAmB,CAAC,SAAoB;AACtC,cAAQ,OAAO,EAAC,WAAW,UAAU,KAAI,CAAC;AAAA,IAC5C;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,MAAM,EAAC,aAAa,4BAA2B;AAAA,IAC/C,UAAU;AAAA,MACR,QACE;AAAA,IACJ;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,MAAM;AAAA,EACR;AACF;AAEA,IAAM,SAAwB;AAAA,EAC5B,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA,OAAO;AAAA,IACL,WAAW;AAAA,EACb;AACF;AAEA,IAAO,kBAAQ;;;AC3Bf,IAAM,gBAAiC;AAAA,EACrC,QAAQ,CAAC,aAAa;AAAA,IACpB,4EACE,CAAC,SAAoB;AACnB,cAAQ,OAAO,EAAC,WAAW,aAAa,KAAI,CAAC;AAAA,IAC/C;AAAA,IACF,uEAAuE,CACrE,SACG;AACH,cAAQ,OAAO,EAAC,WAAW,aAAa,KAAI,CAAC;AAAA,IAC/C;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,MAAM,EAAC,aAAa,oCAAmC;AAAA,IACvD,UAAU;AAAA,MACR,WACE;AAAA,IACJ;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,MAAM;AAAA,EACR;AACF;AAEA,IAAMA,UAAwB;AAAA,EAC5B,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA,OAAO;AAAA,IACL,eAAe;AAAA,EACjB;AACF;AAEA,IAAO,sBAAQA;;;ACjCf,IAAM,eAAgC;AAAA,EACpC,QAAQ,CAAC,aAAa;AAAA,IACpB,iBAAiB,CAAC,SAAoB;AACpC,cAAQ,OAAO,EAAC,WAAW,YAAY,KAAI,CAAC;AAAA,IAC9C;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,MAAM,EAAC,aAAa,6BAA4B;AAAA,IAChD,UAAU;AAAA,MACR,UACE;AAAA,IACJ;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,MAAM;AAAA,EACR;AACF;AAEA,IAAMC,UAAwB;AAAA,EAC5B,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA,OAAO;AAAA,IACL,aAAa;AAAA,EACf;AACF;AAEA,IAAO,oBAAQA;;;AHtBf,IAAM,mBAAmB,CAAC,cAAuC;AAAA,EAC/D,QAAQ,QAAS;AAAA,EACjB;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,MACL,gCAAgC;AAAA,MAChC,qBAAqB;AAAA,MACrB,6BAA6B;AAAA,MAC7B,iCAAiC;AAAA,MACjC,+BAA+B;AAAA,MAC/B,iCAAiC;AAAA,MACjC,4BAA4B;AAAA,MAC5B,oBAAoB;AAAA,IACtB;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,YAAY,mBAAmB;AAAA,IACvC,MAAM;AAAA,IACN,OAAO;AAAA,MACL,gCAAgC;AAAA,MAChC,gCAAgC;AAAA,IAClC;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,oBAAoB,qBAAqB;AAAA,IACjD,MAAM;AAAA,IACN,OAAO;AAAA,MACL,+BAA+B;AAAA,MAC/B,kCAAkC;AAAA,IACpC;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,GAAG,SAAS,sBAAsB,mBAAmB;AAAA,IAC7D,MAAM;AAAA,IACN,OAAO;AAAA,MACL,oCAAoC;AAAA,MACpC,kCAAkC;AAAA,IACpC;AAAA,EACF;AACF;AAEA,IAAM,eAAgC;AAAA,EACpC;AAAA,IACE,OAAO,CAAC,aAAa;AAAA,IACrB,MAAM;AAAA,IACN,SAAS,EAAC,WAAW,gBAAY;AAAA,IACjC,OAAO;AAAA,MACL,mBAAmB;AAAA,IACrB;AAAA,EACF;AACF;AAEA,IAAM,kBAAmC;AAAA,EACvC;AAAA,IACE,OAAO,CAAC,YAAY,UAAU;AAAA,IAC9B,MAAM;AAAA,IACN,SAAS,EAAC,eAAe,oBAAe;AAAA,IACxC,OAAO,EAAC,2BAA2B,QAAO;AAAA,EAC5C;AACF;AAEA,IAAM,iBAAkC;AAAA,EACtC;AAAA,IACE,OAAO,CAAC,eAAe,aAAa;AAAA,IACpC,MAAM;AAAA,IACN,SAAS,EAAC,aAAa,kBAAc;AAAA,IACrC,OAAO,EAAC,uBAAuB,QAAO;AAAA,EACxC;AACF;AAkCA,IAAM,+BAA+B,CACnC,cACoB;AACpB,QAAM,MAAM,CAAC,UAA0B,KAAK,SAAS,IAAI,KAAK;AAC9D,QAAM,gBAAgB,CAAC,YAAY,YAAY;AAE/C,SAAO;AAAA,IACL;AAAA,MACE,OAAO,CAAC,GAAG,SAAS,gCAAgC;AAAA,MACpD,MAAM;AAAA,MACN,OAAO;AAAA,QACL,gCAAgC;AAAA,UAC9B;AAAA,UACA;AAAA,YACE,OAAO;AAAA,cACL;AAAA,gBACE,QAAQ;AAAA,gBACR,MAAM,CAAC,IAAI,QAAQ,CAAC;AAAA,gBACpB,SACE;AAAA,gBACF,QAAQ,IAAI,OAAO;AAAA,cACrB;AAAA,cACA;AAAA,gBACE,QAAQ;AAAA,gBACR,MAAM,CAAC,IAAI,QAAQ,GAAG,IAAI,OAAO,CAAC;AAAA,gBAClC,SACE;AAAA,gBACF,QAAQ,IAAI,YAAY;AAAA,cAC1B;AAAA,cACA;AAAA,gBACE,QAAQ;AAAA,gBACR,MAAM,CAAC,IAAI,QAAQ,GAAG,IAAI,OAAO,GAAG,IAAI,YAAY,CAAC;AAAA,gBACrD,SACE;AAAA,gBACF,QAAQ,CAAC,IAAI,OAAO,GAAG,IAAI,OAAO,CAAC;AAAA,cACrC;AAAA,cACA;AAAA,gBACE,MAAM;AAAA,kBACJ,IAAI,QAAQ;AAAA,kBACZ,IAAI,OAAO;AAAA,kBACX,IAAI,YAAY;AAAA,kBAChB,IAAI,OAAO;AAAA,kBACX,IAAI,OAAO;AAAA,gBACb;AAAA,gBACA,SACE;AAAA,gBACF,QAAQ,IAAI,UAAU;AAAA,cACxB;AAAA,cACA;AAAA,gBACE,MAAM;AAAA,kBACJ,IAAI,QAAQ;AAAA,kBACZ,IAAI,OAAO;AAAA,kBACX,IAAI,YAAY;AAAA,kBAChB,IAAI,OAAO;AAAA,kBACX,IAAI,OAAO;AAAA,kBACX,IAAI,UAAU;AAAA,gBAChB;AAAA,gBACA,SACE;AAAA,gBACF,QAAQ,IAAI,OAAO;AAAA,cACrB;AAAA,cACA;AAAA,gBACE,MAAM;AAAA,kBACJ,IAAI,QAAQ;AAAA,kBACZ,IAAI,OAAO;AAAA,kBACX,IAAI,YAAY;AAAA,kBAChB,IAAI,OAAO;AAAA,kBACX,IAAI,OAAO;AAAA,kBACX,IAAI,UAAU;AAAA,kBACd,IAAI,OAAO;AAAA,gBACb;AAAA,gBACA,SACE;AAAA,gBACF,QAAQ,IAAI,OAAO;AAAA,cACrB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,mCAAmC,CACvC,cACoB;AAAA,EACpB;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,MACP,4BAA4B;AAAA,IAC9B;AAAA,IACA,OAAO;AAAA,MACL,qDAAqD;AAAA,QACnD;AAAA,QACA;AAAA,UACE,cAAc;AAAA,UACd,iBAAiB;AAAA,UACjB,QAAQ;AAAA,UACR,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,kBAAkB,CAAC,cAAuC;AAAA,EACrE,GAAG,iBAAiB,SAAS;AAAA,EAC7B,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG,6BAA6B,SAAS;AAAA,EACzC,GAAG,iCAAiC,SAAS;AAC/C;;;AI7NA,SAAQ,yBAAwB;AAEhC,OAAO,QAAQ;AACf,OAAO,UAAU;AAsBjB,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAUO,IAAM,UAAU,CAAC,SAAmD;AACzE,QAAM,MAAuB,CAAC;AAE9B,QAAM,YAAY,MAAM,aAAa;AACrC,MAAI,cAAc,OAAO;AACvB,UAAM,WAAW,KAAK,WAAW,SAAS,IACtC,YACA,KAAK,QAAQ,QAAQ,IAAI,GAAG,SAAS;AACzC,QAAI,GAAG,WAAW,QAAQ,GAAG;AAC3B,UAAI,KAAK,kBAAkB,QAAQ,CAAkB;AAAA,IACvD;AAAA,EACF;AAEA,MAAI,KAAK;AAAA,IACP,SAAS,CAAC,GAAG,gBAAgB,GAAI,MAAM,SAAS,CAAC,CAAE;AAAA,IACnD,MAAM;AAAA,EACR,CAAC;AAED,SAAO;AACT;;;ACjEA,OAAO,sBAAsB;AAUtB,IAAM,aAA8B;AAAA,EACzC;AAAA,IACE,MAAM;AAAA,IACN,GAAI,iBAAiB,QAAQ,kBAAkB;AAAA,IAC/C,OAAO,CAAC,yBAAyB;AAAA,IACjC,OAAO;AAAA,MACL,GAAG,iBAAiB,QAAQ,kBAAkB,EAAE;AAAA;AAAA;AAAA;AAAA,MAIhD,4BAA4B;AAAA,QAC1B;AAAA,QACA,EAAC,wBAAwB,CAAC,cAAc,EAAC;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AACF;;;AC1BA,SAAQ,SAAS,2BAA0B;AAC3C,OAAO,oBAAoB;AAWpB,IAAM,WAA4B;AAAA,EACvC;AAAA,IACE,MAAM;AAAA,IACN,SAAS,EAAC,UAAU,eAAc;AAAA,EACpC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,MACL,GAAG;AAAA,MACH,8CAA8C;AAAA,QAC5C;AAAA,QACA;AAAA,UACE,WAAW;AAAA,UACX,MAAM,CAAC,cAAc,UAAU,UAAU,OAAO;AAAA,UAChD,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,qBAAqB;AAAA,QACnB;AAAA,QACA;AAAA,QACA;AAAA,UACE,uBAAuB;AAAA,UACvB,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,6BAA6B;AAAA,MAC7B,qBAAqB,CAAC,SAAS,EAAC,WAAW,OAAM,CAAC;AAAA,IACpD;AAAA,EACF;AACF;;;ACzCA,SAAQ,WAAAC,UAAS,WAAAC,gBAAc;AAcxB,IAAM,QAAyB;AAAA;AAAA,EAEpCA,SAAQ;AAAA;AAAA,EAERA,SAAQ;AAAA;AAAA,EAERA,SAAQ;AAAA;AAAA,EAER,GAAGD,SAAQ,MAAM;AAAA,EACjB;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,MACL,yCAAyC;AAAA,MACzC,yBAAyB;AAAA,MACzB,6BAA6B;AAAA,QAC3B;AAAA,QACA;AAAA,UACE,eAAe,CAAC,QAAQ,4BAA4B;AAAA,UACpD,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,uCAAuC;AAAA,MACvC,2BAA2B,CAAC,SAAS,QAAQ;AAAA,MAC7C,kCAAkC;AAAA,MAClC,gCAAgC;AAAA,MAChC,uBAAuB;AAAA;AAAA;AAAA,MAGvB,2BAA2B,CAAC,OAAO,EAAC,qBAAqB,KAAI,CAAC;AAAA,MAC9D,qBAAqB,CAAC,SAAS,EAAC,SAAS,KAAI,CAAC;AAAA,MAC9C,iCAAiC,CAAC,SAAS,EAAC,kBAAkB,KAAI,CAAC;AAAA,MACnE,0BAA0B;AAAA,MAC1B,mBAAmB;AAAA,MACnB,oBAAoB;AAAA,MACpB,4BAA4B;AAAA,MAC5B,+BAA+B;AAAA,IACjC;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,oBAAoB;AAAA,IAC5B,MAAM;AAAA,IACN,OAAO;AAAA,MACL,oBAAoB;AAAA,MACpB,sBAAsB;AAAA,IACxB;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,oBAAoB,qBAAqB;AAAA,IACjD,MAAM;AAAA,IACN,OAAO;AAAA,MACL,gCAAgC;AAAA,IAClC;AAAA,EACF;AACF;;;ACnEA,OAAO,qBAAqB;AASrB,IAAM,YAA6B;AAAA,EACxC,GAAI,gBAAgB,QAAQ,kBAAkB;AAChD;;;ACVA,OAAO,eAAe;AACtB,OAAO,eAAe;AACtB,OAAO,mBAAmB;AAC1B,OAAO,aAAa;AACpB,OAAO,mBAAmB;AAE1B,IAAM,uBAAuB,CAAC,cAAuC;AAAA,EACnE,UAAU,QAAQ,kBAAkB;AAAA,EACpC;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,MACL,4CAA4C;AAAA,MAC5C,qCAAqC;AAAA,MACrC,sBAAsB;AAAA,MACtB,sCAAsC;AAAA,IACxC;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,YAAY,mBAAmB;AAAA,IACvC,MAAM;AAAA,IACN,OAAO;AAAA,MACL,qCAAqC;AAAA,IACvC;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,MACL,GAAG,SAAS;AAAA,MACZ,GAAG,SAAS;AAAA,MACZ,GAAG,SAAS;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,MAAM;AAAA,IACN,OAAO;AAAA,MACL,qCAAqC;AAAA,IACvC;AAAA,EACF;AACF;AAEA,IAAM,sBAAuC;AAAA,EAC3C,cAAc,QAAQ,qBAAqB;AAAA,EAC3C;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,MACL,8BAA8B;AAAA,QAC5B;AAAA,QACA;AAAA,UACE,cAAc;AAAA,YACZ;AAAA,cACE,oBAAoB;AAAA,cACpB,WAAW;AAAA,cACX,UAAU;AAAA,YACZ;AAAA,YACA;AAAA,cACE,oBAAoB;AAAA,cACpB,WAAW;AAAA,YACb;AAAA,YACA;AAAA,cACE,oBAAoB;AAAA,cACpB,WAAW;AAAA,cACX,UAAU;AAAA,YACZ;AAAA,YACA;AAAA,cACE,oBAAoB;AAAA,cACpB,WAAW;AAAA,YACb;AAAA,UACF;AAAA,UACA,QAAQ;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,CAAC,iBAAiB,UAAU;AAAA,YAC5B,CAAC,gBAAgB,SAAS;AAAA,YAC1B,CAAC,iBAAiB,UAAU;AAAA,YAC5B,CAAC,eAAe,QAAQ;AAAA,YACxB,CAAC,gBAAgB,SAAS;AAAA,YAC1B,CAAC,cAAc,OAAO;AAAA,YACtB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA,iBAAiB;AAAA,UACjB,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,gCAAgC;AAAA,QAC9B;AAAA,QACA;AAAA,UACE,cAAc;AAAA,YACZ;AAAA,cACE,oBAAoB,CAAC,SAAS,OAAO;AAAA,cACrC,WAAW;AAAA,YACb;AAAA,UACF;AAAA,UACA,QAAQ,CAAC,UAAU;AAAA,UACnB,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,gBAAiC;AAAA,EACrC,QAAQ,QAAQ;AAAA,EAChB;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,MACL,oCAAoC;AAAA,MACpC,8CAA8C;AAAA,MAC9C,yBAAyB;AAAA,MACzB,4BAA4B;AAAA,MAC5B,uCAAuC;AAAA,MACvC,6BAA6B;AAAA,MAC7B,2BAA2B;AAAA,MAC3B,6BAA6B;AAAA,MAC7B,mBAAmB;AAAA,MACnB,gCAAgC;AAAA,MAChC,8BAA8B;AAAA,MAC9B,8BAA8B;AAAA;AAAA;AAAA;AAAA;AAAA,MAK9B,qDAAqD;AAAA,MACrD,0BAA0B;AAAA,MAC1B,yBAAyB;AAAA,MACzB,0BAA0B;AAAA,MAC1B,iCAAiC;AAAA,QAC/B;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MACA,yCAAyC;AAAA,IAC3C;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,QAAQ;AAAA,IAChB,MAAM;AAAA,IACN,OAAO;AAAA,MACL,yBAAyB;AAAA,MACzB,iCAAiC;AAAA,IACnC;AAAA,EACF;AACF;AAEA,IAAM,sBAAuC;AAAA,EAC3C;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,MACP,kBAAkB;AAAA,IACpB;AAAA,IACA,OAAO;AAAA,MACL,qCAAqC;AAAA,MACrC,kBAAkB;AAAA,MAClB,0BAA0B;AAAA,MAC1B,yBAAyB;AAAA,MACzB,oCAAoC;AAAA,MACpC,iCAAiC;AAAA,QAC/B;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,mBAAmB;AAAA,UACnB,oBAAoB;AAAA,UACpB,MAAM;AAAA,UACN,mBAAmB;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,WAAW;AAAA,IACnB,MAAM;AAAA,IACN,OAAO;AAAA,MACL,iCAAiC;AAAA,IACnC;AAAA,EACF;AACF;AAEA,IAAM,uBAAuB,CAAC,cAAuC;AAAA,EACnE;AAAA,IACE,SAAS;AAAA,MACP,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,GAAG,SAAS,OAAO;AAAA,IAC3B,MAAM;AAAA,IACN,OAAO;AAAA,MACL,yCAAyC;AAAA,QACvC;AAAA,QACA;AAAA;AAAA,UAEE,uBAAuB;AAAA,UACvB,CAAC,GAAG,SAAS,cAAc,GAAG;AAAA;AAAA,UAE9B,CAAC,GAAG,SAAS,gEAAgE,GAC3E;AAAA;AAAA,UAEF,CAAC,GAAG,SAAS,sCAAsC,GAAG;AAAA;AAAA,UAEtD,CAAC,GAAG,SAAS,8DAA8D,GACzE;AAAA,UACF,oBAAoB;AAAA,QACtB;AAAA,QACA;AAAA,UACE,wBAAwB;AAAA,QAC1B;AAAA,MACF;AAAA,MACA,oCAAoC;AAAA,QAClC;AAAA,QACA;AAAA;AAAA,UAEE,6BAA6B,GAAG,SAAS;AAAA,QAC3C;AAAA,MACF;AAAA,MACA,uCAAuC;AAAA,QACrC;AAAA,QACA;AAAA;AAAA,UAEE,CAAC,GAAG,SAAS,iBAAiB,GAC5B;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO,CAAC,aAAa;AAAA,IACrB,MAAM;AAAA,IACN,OAAO;AAAA,MACL,yCAAyC;AAAA,QACvC;AAAA,QACA;AAAA,UACE,oBAAoB;AAAA,QACtB;AAAA,QACA;AAAA,UACE,wBAAwB;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,oBAAoB,CAAC,cAAuC;AAAA,EACvE,GAAG,qBAAqB,SAAS;AAAA,EACjC,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG,qBAAqB,SAAS;AACnC;;;ACjRA,OAAO,YAAY;AACnB,OAAO,aAAa;AACpB,OAAO,oBAAoB;AAUpB,IAAM,UAA2B;AAAA,EACtC;AAAA,IACE,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,MAAM;AAAA,IACN,SAAS;AAAA,MACP,YAAY;AAAA,MACZ;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL,GAAG,QAAQ,QAAQ,kBAAkB,EAAE;AAAA,MACvC,GAAG,OAAO,QAAQ,YAAY;AAAA,MAC9B,qCAAqC;AAAA,QACnC;AAAA,QACA,EAAC,gBAAgB,KAAI;AAAA,MACvB;AAAA,MACA,wBAAwB;AAAA,QACtB;AAAA,QACA,EAAC,qBAAqB,CAAC,UAAU,SAAS,EAAC;AAAA,MAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,4BAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAS5B,6BAA6B,CAAC,SAAS,EAAC,IAAI,OAAM,CAAC;AAAA;AAAA;AAAA,MAGnD,+BAA+B,CAAC,SAAS,EAAC,IAAI,KAAI,CAAC;AAAA;AAAA;AAAA;AAAA,MAInD,iCAAiC;AAAA;AAAA;AAAA;AAAA,MAIjC,2BAA2B;AAAA;AAAA;AAAA,MAG3B,mCAAmC;AAAA;AAAA;AAAA;AAAA,MAInC,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAYtB,6BAA6B;AAAA;AAAA;AAAA,MAG7B,mCAAmC;AAAA,IACrC;AAAA,EACF;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA0BE,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS,CAAC,oBAAoB;AAAA,IAC9B,MAAM;AAAA,IACN,OAAO;AAAA,MACL,yBAAyB;AAAA,QACvB;AAAA,QACA;AAAA,UACE,UAAU;AAAA,YACR;AAAA,cACE,OAAO,CAAC,aAAa;AAAA,cACrB,SACE;AAAA,YACJ;AAAA,YACA;AAAA,cACE,OAAO,CAAC,mBAAmB,cAAc;AAAA,cACzC,SACE;AAAA,YACJ;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,GAAG,eAAe,QAAQ,YAAY;AAAA,IACtC,OAAO,CAAC,kBAAkB;AAAA,IAC1B,MAAM;AAAA,EACR;AACF;;;AC5FA,IAAM,uBAAuB,MAAuB;AAClD,QAAM,WAAW,QAAQ;AACzB,QAAM,YAAY,CAAC,SAAkC,QAAQ,IAAI;AAGjE,WAAS,OAAO,QAAQ,IAAI,MAAM,SAAS,OAAO,QAAQ,EAAE;AAC5D,SAAO;AACT;AAcA,IAAM,WAAW,CAAC,SAA2C;AAC3D,QAAM,YAAY,MAAM,aAAa;AACrC,SAAO;AAAA,IACL,MAAM,UAAU,SAAS;AAAA,IACzB;AAAA,IACA,YAAY,gBAAgB,SAAS;AAAA,IACrC,SAAS,qBAAqB;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,kBAAkB,SAAS;AAAA,IACzC;AAAA,EACF;AACF;AAEA,IAAO,gBAAQ;","names":["plugin","plugin","configs","plugins"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gaia-react/lint",
3
- "version": "1.5.1",
3
+ "version": "1.7.0",
4
4
  "description": "GAIA's opinionated lint configuration.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -45,22 +45,22 @@
45
45
  "@eslint-community/eslint-plugin-eslint-comments": "4.7.2",
46
46
  "@eslint/config-helpers": "0.6.0",
47
47
  "@eslint/js": "9.39.4",
48
- "@vitest/eslint-plugin": "1.6.19",
48
+ "@vitest/eslint-plugin": "1.6.20",
49
49
  "eslint-config-airbnb-extended": "3.1.0",
50
50
  "eslint-config-prettier": "10.1.8",
51
- "eslint-plugin-better-tailwindcss": "4.5.0",
51
+ "eslint-plugin-better-tailwindcss": "4.6.0",
52
52
  "eslint-plugin-canonical": "5.1.3",
53
53
  "eslint-plugin-check-file": "3.3.1",
54
54
  "eslint-plugin-jest-dom": "5.5.0",
55
55
  "eslint-plugin-no-relative-import-paths": "1.6.1",
56
- "eslint-plugin-perfectionist": "5.9.0",
56
+ "eslint-plugin-perfectionist": "5.9.1",
57
57
  "eslint-plugin-playwright": "2.10.4",
58
58
  "eslint-plugin-prefer-arrow-functions": "3.9.1",
59
59
  "eslint-plugin-prettier": "5.5.6",
60
60
  "eslint-plugin-sonarjs": "4.0.3",
61
- "eslint-plugin-storybook": "10.4.2",
61
+ "eslint-plugin-storybook": "10.4.6",
62
62
  "eslint-plugin-testing-library": "7.16.2",
63
- "eslint-plugin-unicorn": "64.0.0",
63
+ "eslint-plugin-unicorn": "65.0.1",
64
64
  "eslint-plugin-unused-imports": "4.4.1",
65
65
  "eslint-plugin-you-dont-need-lodash-underscore": "6.14.0",
66
66
  "prettier-plugin-tailwindcss": "0.8.0",
@@ -72,11 +72,11 @@
72
72
  "devDependencies": {
73
73
  "@changesets/changelog-github": "^0.7.0",
74
74
  "@changesets/cli": "^2.31.0",
75
- "@types/node": "^25.9.1",
75
+ "@types/node": "^25.9.3",
76
76
  "eslint": "^9.39.0",
77
77
  "tsup": "^8.0.0",
78
78
  "typescript": "^6.0.0",
79
- "typescript-eslint": "^8.60.0"
79
+ "typescript-eslint": "^8.61.1"
80
80
  },
81
81
  "author": "Steven Sacks <stevensacks@gmail.com>",
82
82
  "license": "MIT",