@kikiutils/eslint-config 9.3.1 → 10.0.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.
Files changed (61) hide show
  1. package/README.md +8 -0
  2. package/dist/{internals → _internals}/plugins.d.ts.map +1 -1
  3. package/dist/{internals → _internals}/plugins.js +1 -1
  4. package/dist/_internals/plugins.js.map +1 -0
  5. package/dist/_internals/rules/compact-iteration-layout.d.ts.map +1 -0
  6. package/dist/{internals → _internals}/rules/compact-iteration-layout.js +1 -1
  7. package/dist/_internals/rules/compact-iteration-layout.js.map +1 -0
  8. package/dist/_internals/rules/consistent-condition-layout.d.ts.map +1 -0
  9. package/dist/{internals → _internals}/rules/consistent-condition-layout.js +1 -1
  10. package/dist/_internals/rules/consistent-condition-layout.js.map +1 -0
  11. package/dist/_internals/rules/consistent-parameter-layout.d.ts.map +1 -0
  12. package/dist/_internals/rules/consistent-parameter-layout.js +137 -0
  13. package/dist/_internals/rules/consistent-parameter-layout.js.map +1 -0
  14. package/dist/_internals/rules/statement-padding.d.ts.map +1 -0
  15. package/dist/{internals → _internals}/rules/statement-padding.js +22 -12
  16. package/dist/_internals/rules/statement-padding.js.map +1 -0
  17. package/dist/_internals/type-aware.d.ts +3 -0
  18. package/dist/_internals/type-aware.d.ts.map +1 -0
  19. package/dist/_internals/type-aware.js +25 -0
  20. package/dist/_internals/type-aware.js.map +1 -0
  21. package/dist/_internals/utils.d.ts.map +1 -0
  22. package/dist/{internals → _internals}/utils.js +1 -1
  23. package/dist/_internals/utils.js.map +1 -0
  24. package/dist/base.d.ts.map +1 -1
  25. package/dist/base.js +44 -17
  26. package/dist/base.js.map +1 -1
  27. package/dist/style.js +1 -5
  28. package/dist/style.js.map +1 -1
  29. package/dist/vue.d.ts.map +1 -1
  30. package/dist/vue.js +8 -4
  31. package/dist/vue.js.map +1 -1
  32. package/package.json +19 -70
  33. package/src/_internals/rules/consistent-parameter-layout.ts +244 -0
  34. package/src/{internals → _internals}/rules/statement-padding.ts +33 -22
  35. package/src/_internals/type-aware.ts +28 -0
  36. package/src/base.ts +67 -24
  37. package/src/style.ts +1 -2
  38. package/src/vue.ts +11 -4
  39. package/dist/internals/plugins.js.map +0 -1
  40. package/dist/internals/rules/compact-iteration-layout.d.ts.map +0 -1
  41. package/dist/internals/rules/compact-iteration-layout.js.map +0 -1
  42. package/dist/internals/rules/consistent-condition-layout.d.ts.map +0 -1
  43. package/dist/internals/rules/consistent-condition-layout.js.map +0 -1
  44. package/dist/internals/rules/consistent-parameter-layout.d.ts.map +0 -1
  45. package/dist/internals/rules/consistent-parameter-layout.js +0 -90
  46. package/dist/internals/rules/consistent-parameter-layout.js.map +0 -1
  47. package/dist/internals/rules/statement-padding.d.ts.map +0 -1
  48. package/dist/internals/rules/statement-padding.js.map +0 -1
  49. package/dist/internals/utils.d.ts.map +0 -1
  50. package/dist/internals/utils.js.map +0 -1
  51. package/src/internals/rules/consistent-parameter-layout.ts +0 -163
  52. /package/dist/{internals → _internals}/plugins.d.ts +0 -0
  53. /package/dist/{internals → _internals}/rules/compact-iteration-layout.d.ts +0 -0
  54. /package/dist/{internals → _internals}/rules/consistent-condition-layout.d.ts +0 -0
  55. /package/dist/{internals → _internals}/rules/consistent-parameter-layout.d.ts +0 -0
  56. /package/dist/{internals → _internals}/rules/statement-padding.d.ts +0 -0
  57. /package/dist/{internals → _internals}/utils.d.ts +0 -0
  58. /package/src/{internals → _internals}/plugins.ts +0 -0
  59. /package/src/{internals → _internals}/rules/compact-iteration-layout.ts +0 -0
  60. /package/src/{internals → _internals}/rules/consistent-condition-layout.ts +0 -0
  61. /package/src/{internals → _internals}/utils.ts +0 -0
package/README.md CHANGED
@@ -26,6 +26,14 @@ You can also use `yarn`, `npm`, or `bun`.
26
26
 
27
27
  ## Usage
28
28
 
29
+ TypeScript and Vue configs enable type-aware checks using TypeScript's Project Service.
30
+ Linted files must belong to a discoverable `tsconfig.json`; project references are supported.
31
+ The default setup does not require an additional `typescript.tsconfigPath` option.
32
+ JavaScript files retain syntax-only linting.
33
+ TypeScript tool configs (`*.config.ts`, `*.config.mts`, `*.config.cts`) are excluded from type-aware checks.
34
+ Base configs keep linting Markdown itself, but exclude its code blocks from all lint rules.
35
+ Style configs format CSS and SCSS; indented Sass (`.sass`) is not supported.
36
+
29
37
  ## License
30
38
 
31
39
  [MIT License](./LICENSE)
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.d.ts","names":[],"sources":["../../src/internals/plugins.ts"],"mappings":"A,qBAKa"}
1
+ {"version":3,"file":"plugins.d.ts","names":[],"sources":["../../src/_internals/plugins.ts"],"mappings":"A,qBAKa"}
@@ -2,7 +2,7 @@ import { compactIterationLayout } from "./rules/compact-iteration-layout.js";
2
2
  import { consistentConditionLayout } from "./rules/consistent-condition-layout.js";
3
3
  import { consistentParameterLayout } from "./rules/consistent-parameter-layout.js";
4
4
  import { statementPadding } from "./rules/statement-padding.js";
5
- // src/internals/plugins.ts
5
+ // src/_internals/plugins.ts
6
6
  const customPlugins = { rules: {
7
7
  "compact-iteration-layout": compactIterationLayout,
8
8
  "consistent-condition-layout": consistentConditionLayout,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugins.js","names":[],"sources":["../../src/_internals/plugins.ts"],"sourcesContent":["import { compactIterationLayout } from './rules/compact-iteration-layout';\nimport { consistentConditionLayout } from './rules/consistent-condition-layout';\nimport { consistentParameterLayout } from './rules/consistent-parameter-layout';\nimport { statementPadding } from './rules/statement-padding';\n\nexport const customPlugins = {\n rules: {\n 'compact-iteration-layout': compactIterationLayout,\n 'consistent-condition-layout': consistentConditionLayout,\n 'consistent-parameter-layout': consistentParameterLayout,\n 'statement-padding': statementPadding,\n },\n};\n"],"mappings":";;;;;AAKA,MAAa,gBAAgB,EACzB,OAAO;CACH,4BAA4B;CAC5B,+BAA+B;CAC/B,+BAA+B;CAC/B,qBAAqB;AACzB,EACJ"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compact-iteration-layout.d.ts","names":[],"sources":["../../../src/_internals/rules/compact-iteration-layout.ts"],"mappings":";qBAIa,wBAAwB,KAAK"}
@@ -1,4 +1,4 @@
1
- // src/internals/rules/compact-iteration-layout.ts
1
+ // src/_internals/rules/compact-iteration-layout.ts
2
2
  const compactIterationLayout = {
3
3
  create(context) {
4
4
  const { sourceCode } = context;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compact-iteration-layout.js","names":[],"sources":["../../../src/_internals/rules/compact-iteration-layout.ts"],"sourcesContent":["import type { Rule } from 'eslint';\n\ntype IterationNode = Extract<Rule.Node, { type: 'ForInStatement' | 'ForOfStatement' }>;\n\nexport const compactIterationLayout: Rule.RuleModule = {\n create(context) {\n const { sourceCode } = context;\n\n function checkParentheses(node: IterationNode): void {\n const openingParen = sourceCode.getFirstToken(node, (token) => token.value === '(')!;\n const closingParen = sourceCode.getTokenBefore(node.body)!;\n const next = sourceCode.getTokenAfter(openingParen)!;\n const previous = sourceCode.getTokenBefore(closingParen)!;\n const ranges: Array<[number, number]> = [];\n\n if (\n openingParen.loc.end.line !== next.loc.start.line\n && !sourceCode.commentsExistBetween(openingParen, next)\n ) {\n ranges.push([\n openingParen.range[1],\n next.range[0],\n ]);\n }\n\n if (\n previous.loc.end.line !== closingParen.loc.start.line\n && !sourceCode.commentsExistBetween(previous, closingParen)\n ) {\n ranges.push([\n previous.range[1],\n closingParen.range[0],\n ]);\n }\n\n if (ranges.length) {\n context.report({\n fix: (fixer) => ranges.map((range) => fixer.replaceTextRange(range, '')),\n messageId: 'compact',\n node,\n });\n }\n }\n\n return {\n ForInStatement: checkParentheses,\n ForOfStatement: checkParentheses,\n };\n },\n meta: {\n docs: { description: 'Keep for-in and for-of parentheses beside their header contents.' },\n fixable: 'whitespace',\n messages: { compact: 'Keep iteration parentheses on the same lines as their adjacent header contents.' },\n schema: [],\n type: 'layout',\n },\n};\n"],"mappings":";AAIA,MAAa,yBAA0C;CACnD,OAAO,SAAS;EACZ,MAAM,EAAE,eAAe;EAEvB,SAAS,iBAAiB,MAA2B;GACjD,MAAM,eAAe,WAAW,cAAc,OAAO,UAAU,MAAM,UAAU,GAAG;GAClF,MAAM,eAAe,WAAW,eAAe,KAAK,IAAI;GACxD,MAAM,OAAO,WAAW,cAAc,YAAY;GAClD,MAAM,WAAW,WAAW,eAAe,YAAY;GACvD,MAAM,SAAkC,CAAC;GAEzC,IACI,aAAa,IAAI,IAAI,SAAS,KAAK,IAAI,MAAM,QAC1C,CAAC,WAAW,qBAAqB,cAAc,IAAI,GAEtD,OAAO,KAAK,CACR,aAAa,MAAM,IACnB,KAAK,MAAM,EACf,CAAC;GAGL,IACI,SAAS,IAAI,IAAI,SAAS,aAAa,IAAI,MAAM,QAC9C,CAAC,WAAW,qBAAqB,UAAU,YAAY,GAE1D,OAAO,KAAK,CACR,SAAS,MAAM,IACf,aAAa,MAAM,EACvB,CAAC;GAGL,IAAI,OAAO,QACP,QAAQ,OAAO;IACX,MAAM,UAAU,OAAO,KAAK,UAAU,MAAM,iBAAiB,OAAO,EAAE,CAAC;IACvE,WAAW;IACX;GACJ,CAAC;EAET;EAEA,OAAO;GACH,gBAAgB;GAChB,gBAAgB;EACpB;CACJ;CACA,MAAM;EACF,MAAM,EAAE,aAAa,mEAAmE;EACxF,SAAS;EACT,UAAU,EAAE,SAAS,kFAAkF;EACvG,QAAQ,CAAC;EACT,MAAM;CACV;AACJ"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consistent-condition-layout.d.ts","names":[],"sources":["../../../src/_internals/rules/consistent-condition-layout.ts"],"mappings":";qBAUa,2BAA2B,KAAK"}
@@ -1,5 +1,5 @@
1
1
  import { defineScriptAndTemplateVisitors } from "../utils.js";
2
- // src/internals/rules/consistent-condition-layout.ts
2
+ // src/_internals/rules/consistent-condition-layout.ts
3
3
  const consistentConditionLayout = {
4
4
  create(context) {
5
5
  function createVisitor(tokenStore) {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consistent-condition-layout.js","names":[],"sources":["../../../src/_internals/rules/consistent-condition-layout.ts"],"sourcesContent":["import type {\n AST,\n Rule,\n} from 'eslint';\n\nimport type { TokenStore } from '../utils';\nimport { defineScriptAndTemplateVisitors } from '../utils';\n\ntype LogicalNode = Extract<Rule.Node, { type: 'LogicalExpression' }>;\n\nexport const consistentConditionLayout: Rule.RuleModule = {\n create(context) {\n function createVisitor(tokenStore: TokenStore): Rule.RuleListener {\n const checkedOpeningOffsets = new Set<number>();\n\n function collectOperators(node: LogicalNode['left'], operators: AST.Token[]): void {\n if (node.type !== 'LogicalExpression' || (node.operator !== '&&' && node.operator !== '||')) return;\n const operator = tokenStore.getTokensBetween(node.left, node.right)\n .find((token) => token.type === 'Punctuator' && token.value === node.operator)!;\n\n function collectChild(child: LogicalNode['left']): void {\n const before = tokenStore.getTokenBefore(child);\n const after = tokenStore.getTokenAfter(child);\n if (\n before?.value === '('\n && after?.value === ')'\n && before.range[0] >= node.range![0]\n && after.range[1] <= node.range![1]\n ) return;\n\n collectOperators(child, operators);\n }\n\n collectChild(node.left);\n operators.push(operator);\n collectChild(node.right);\n }\n\n function checkParentheses(node: LogicalNode['left']): void {\n let openingParen = tokenStore.getTokenBefore(node);\n let closingParen = tokenStore.getTokenAfter(node);\n let operators: AST.Token[] | undefined;\n const newlineOffsets: number[] = [];\n while (openingParen?.value === '(' && closingParen?.value === ')') {\n if (\n !checkedOpeningOffsets.has(openingParen.range[0])\n && openingParen.loc.start.line !== closingParen.loc.end.line\n ) {\n checkedOpeningOffsets.add(openingParen.range[0]);\n if (!operators) {\n operators = [];\n collectOperators(node, operators);\n }\n\n const next = tokenStore.getTokenAfter(openingParen)!;\n if (openingParen.loc.end.line === next.loc.start.line) {\n newlineOffsets.push(openingParen.range[1]);\n }\n\n for (const operator of operators) {\n if (tokenStore.getTokenBefore(operator)!.loc.end.line === operator.loc.start.line) {\n newlineOffsets.push(operator.range[0]);\n }\n }\n\n if (tokenStore.getTokenBefore(closingParen)!.loc.end.line === closingParen.loc.start.line) {\n newlineOffsets.push(closingParen.range[0]);\n }\n }\n\n openingParen = tokenStore.getTokenBefore(openingParen);\n closingParen = tokenStore.getTokenAfter(closingParen);\n // An outer pair contains one grouped item, not the inner logical chain.\n operators = [];\n }\n\n if (newlineOffsets.length) {\n context.report({\n fix: (fixer) => newlineOffsets.map((offset) => fixer.insertTextBeforeRange(\n [\n offset,\n offset,\n ],\n '\\n',\n )),\n messageId: 'newline',\n node,\n });\n }\n }\n\n return {\n BinaryExpression: (node) => {\n if (\n [\n '!=',\n '!==',\n '<',\n '<=',\n '==',\n '===',\n '>',\n '>=',\n 'in',\n 'instanceof',\n ].includes(node.operator)\n ) checkParentheses(node);\n },\n DoWhileStatement: (node) => checkParentheses(node.test),\n IfStatement: (node) => checkParentheses(node.test),\n LogicalExpression: (node) => {\n if (node.operator === '&&' || node.operator === '||') checkParentheses(node);\n },\n UnaryExpression: (node) => {\n if (node.operator === '!') checkParentheses(node);\n },\n WhileStatement: (node) => checkParentheses(node.test),\n };\n }\n\n return defineScriptAndTemplateVisitors(context.sourceCode, createVisitor);\n },\n meta: {\n docs: { description: 'Expand multiline parenthesized conditions one logical item per line.' },\n fixable: 'whitespace',\n messages: { newline: 'Put each logical item and both parentheses on separate lines in a multiline condition.' },\n schema: [],\n type: 'layout',\n },\n};\n"],"mappings":";;AAUA,MAAa,4BAA6C;CACtD,OAAO,SAAS;EACZ,SAAS,cAAc,YAA2C;GAC9D,MAAM,wCAAwB,IAAI,IAAY;GAE9C,SAAS,iBAAiB,MAA2B,WAA8B;IAC/E,IAAI,KAAK,SAAS,uBAAwB,KAAK,aAAa,QAAQ,KAAK,aAAa,MAAO;IAC7F,MAAM,WAAW,WAAW,iBAAiB,KAAK,MAAM,KAAK,KAAK,CAAC,CAC9D,MAAM,UAAU,MAAM,SAAS,gBAAgB,MAAM,UAAU,KAAK,QAAQ;IAEjF,SAAS,aAAa,OAAkC;KACpD,MAAM,SAAS,WAAW,eAAe,KAAK;KAC9C,MAAM,QAAQ,WAAW,cAAc,KAAK;KAC5C,IACI,QAAQ,UAAU,OACf,OAAO,UAAU,OACjB,OAAO,MAAM,MAAM,KAAK,MAAO,MAC/B,MAAM,MAAM,MAAM,KAAK,MAAO,IACnC;KAEF,iBAAiB,OAAO,SAAS;IACrC;IAEA,aAAa,KAAK,IAAI;IACtB,UAAU,KAAK,QAAQ;IACvB,aAAa,KAAK,KAAK;GAC3B;GAEA,SAAS,iBAAiB,MAAiC;IACvD,IAAI,eAAe,WAAW,eAAe,IAAI;IACjD,IAAI,eAAe,WAAW,cAAc,IAAI;IAChD,IAAI;IACJ,MAAM,iBAA2B,CAAC;IAClC,OAAO,cAAc,UAAU,OAAO,cAAc,UAAU,KAAK;KAC/D,IACI,CAAC,sBAAsB,IAAI,aAAa,MAAM,EAAE,KAC7C,aAAa,IAAI,MAAM,SAAS,aAAa,IAAI,IAAI,MAC1D;MACE,sBAAsB,IAAI,aAAa,MAAM,EAAE;MAC/C,IAAI,CAAC,WAAW;OACZ,YAAY,CAAC;OACb,iBAAiB,MAAM,SAAS;MACpC;MAEA,MAAM,OAAO,WAAW,cAAc,YAAY;MAClD,IAAI,aAAa,IAAI,IAAI,SAAS,KAAK,IAAI,MAAM,MAC7C,eAAe,KAAK,aAAa,MAAM,EAAE;MAG7C,KAAK,MAAM,YAAY,WACnB,IAAI,WAAW,eAAe,QAAQ,CAAC,CAAE,IAAI,IAAI,SAAS,SAAS,IAAI,MAAM,MACzE,eAAe,KAAK,SAAS,MAAM,EAAE;MAI7C,IAAI,WAAW,eAAe,YAAY,CAAC,CAAE,IAAI,IAAI,SAAS,aAAa,IAAI,MAAM,MACjF,eAAe,KAAK,aAAa,MAAM,EAAE;KAEjD;KAEA,eAAe,WAAW,eAAe,YAAY;KACrD,eAAe,WAAW,cAAc,YAAY;KAEpD,YAAY,CAAC;IACjB;IAEA,IAAI,eAAe,QACf,QAAQ,OAAO;KACX,MAAM,UAAU,eAAe,KAAK,WAAW,MAAM,sBACjD,CACI,QACA,MACJ,GACA,IACJ,CAAC;KACD,WAAW;KACX;IACJ,CAAC;GAET;GAEA,OAAO;IACH,mBAAmB,SAAS;KACxB,IACI;MACI;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;KACJ,CAAC,CAAC,SAAS,KAAK,QAAQ,GAC1B,iBAAiB,IAAI;IAC3B;IACA,mBAAmB,SAAS,iBAAiB,KAAK,IAAI;IACtD,cAAc,SAAS,iBAAiB,KAAK,IAAI;IACjD,oBAAoB,SAAS;KACzB,IAAI,KAAK,aAAa,QAAQ,KAAK,aAAa,MAAM,iBAAiB,IAAI;IAC/E;IACA,kBAAkB,SAAS;KACvB,IAAI,KAAK,aAAa,KAAK,iBAAiB,IAAI;IACpD;IACA,iBAAiB,SAAS,iBAAiB,KAAK,IAAI;GACxD;EACJ;EAEA,OAAO,gCAAgC,QAAQ,YAAY,aAAa;CAC5E;CACA,MAAM;EACF,MAAM,EAAE,aAAa,uEAAuE;EAC5F,SAAS;EACT,UAAU,EAAE,SAAS,yFAAyF;EAC9G,QAAQ,CAAC;EACT,MAAM;CACV;AACJ"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consistent-parameter-layout.d.ts","names":[],"sources":["../../../src/_internals/rules/consistent-parameter-layout.ts"],"mappings":";qBAgBa,2BAA2B,KAAK"}
@@ -0,0 +1,137 @@
1
+ import { defineScriptAndTemplateVisitors } from "../utils.js";
2
+ // src/_internals/rules/consistent-parameter-layout.ts
3
+ const consistentParameterLayout = {
4
+ create(context) {
5
+ const compactTestCalls = context.options[0]?.compactTestCalls === true;
6
+ function createVisitor(tokenStore, isTemplate) {
7
+ function checkTestCallLayout(node) {
8
+ const items = node.arguments;
9
+ if (!items.length) return;
10
+ const openingParen = tokenStore.getTokenAfter(node.typeArguments ?? node.callee, (token) => token.type === "Punctuator" && token.value === "(");
11
+ const closingParen = tokenStore.getLastToken(node);
12
+ const previous = tokenStore.getTokenBefore(closingParen);
13
+ const gaps = [[
14
+ openingParen,
15
+ tokenStore.getTokenAfter(openingParen),
16
+ ""
17
+ ], [
18
+ previous,
19
+ closingParen,
20
+ ""
21
+ ]];
22
+ for (let index = 1; index < items.length; index++) {
23
+ const comma = tokenStore.getTokensBetween(items[index - 1], items[index]).find((token) => token.type === "Punctuator" && token.value === ",");
24
+ gaps.push([
25
+ tokenStore.getTokenBefore(comma),
26
+ comma,
27
+ ""
28
+ ], [
29
+ comma,
30
+ tokenStore.getTokenAfter(comma),
31
+ " "
32
+ ]);
33
+ }
34
+ if (previous.value === ",") gaps.push([
35
+ tokenStore.getTokenBefore(previous),
36
+ previous,
37
+ ""
38
+ ]);
39
+ if (gaps.some(([left, right]) => tokenStore.commentsExistBetween(left, right))) return;
40
+ const multilineGaps = gaps.filter(([left, right]) => left.loc.end.line !== right.loc.start.line);
41
+ if (!multilineGaps.length) return;
42
+ context.report({
43
+ fix: (fixer) => multilineGaps.map(([left, right, text]) => fixer.replaceTextRange([left.range[1], right.range[0]], text)),
44
+ messageId: "compactTestCall",
45
+ node
46
+ });
47
+ }
48
+ function checkParameterLayout(node, items) {
49
+ const first = items[0];
50
+ if (!first) return;
51
+ const isSingleParameter = items.length === 1;
52
+ const firstType = first.type;
53
+ if (isSingleParameter && (firstType === "JSXElement" || firstType === "JSXFragment")) return;
54
+ let openingParen;
55
+ if (node.type === "CallExpression" || node.type === "NewExpression") openingParen = tokenStore.getTokenAfter(node.typeArguments ?? node.callee, (token) => token.type === "Punctuator" && token.value === "(");
56
+ else openingParen = tokenStore.getTokenBefore(first);
57
+ if (!openingParen || openingParen.value !== "(") return;
58
+ if (openingParen.range[0] < node.range[0]) return;
59
+ const closingParen = node.type === "CallExpression" || node.type === "NewExpression" ? tokenStore.getLastToken(node) : tokenStore.getTokenAfter(items.at(-1), (token) => token.value === ")");
60
+ const next = tokenStore.getTokenAfter(openingParen);
61
+ if (isSingleParameter) {
62
+ if (!closingParen || closingParen.value !== ")") return;
63
+ let previous = tokenStore.getTokenBefore(closingParen);
64
+ if (previous.value === ",") previous = tokenStore.getTokenBefore(previous);
65
+ if (tokenStore.commentsExistBetween(openingParen, next) || tokenStore.commentsExistBetween(previous, closingParen)) return;
66
+ const hasOpeningNewline = openingParen.loc.end.line !== next.loc.start.line;
67
+ if (hasOpeningNewline === (tokenStore.getTokenBefore(closingParen).loc.end.line !== closingParen.loc.start.line)) return;
68
+ context.report({
69
+ fix: (fixer) => hasOpeningNewline ? fixer.insertTextBefore(closingParen, "\n") : fixer.insertTextAfter(openingParen, "\n"),
70
+ messageId: "singleBoundary",
71
+ node
72
+ });
73
+ return;
74
+ }
75
+ if (!closingParen || openingParen.loc.start.line === closingParen.loc.end.line) return;
76
+ if (isTemplate) {
77
+ const newlineOffsets = [];
78
+ if (openingParen.loc.end.line === next.loc.start.line) newlineOffsets.push(openingParen.range[1]);
79
+ for (let index = 1; index < items.length; index++) {
80
+ const item = items[index];
81
+ const comma = tokenStore.getTokensBetween(items[index - 1], item).find((token) => token.value === ",");
82
+ if (comma && comma.loc.end.line === tokenStore.getTokenAfter(comma).loc.start.line) newlineOffsets.push(comma.range[1]);
83
+ }
84
+ if (closingParen.value === ")" && tokenStore.getTokenBefore(closingParen).loc.end.line === closingParen.loc.start.line) newlineOffsets.push(closingParen.range[0]);
85
+ if (newlineOffsets.length) context.report({
86
+ fix: (fixer) => newlineOffsets.map((offset) => fixer.insertTextBeforeRange([offset, offset], "\n")),
87
+ messageId: "newline",
88
+ node: first
89
+ });
90
+ return;
91
+ }
92
+ if (openingParen.loc.end.line !== next.loc.start.line) return;
93
+ context.report({
94
+ fix: (fixer) => fixer.insertTextAfter(openingParen, "\n"),
95
+ messageId: "newline",
96
+ node: first
97
+ });
98
+ }
99
+ return {
100
+ ArrowFunctionExpression: (node) => checkParameterLayout(node, node.params),
101
+ CallExpression: (node) => {
102
+ const { callee } = node;
103
+ if (compactTestCalls) {
104
+ const target = callee.type === "MemberExpression" && !callee.computed && callee.property.type === "Identifier" && callee.property.name === "concurrent" ? callee.object : callee;
105
+ if (target.type === "Identifier" && (target.name === "describe" || target.name === "it")) {
106
+ checkTestCallLayout(node);
107
+ return;
108
+ }
109
+ }
110
+ checkParameterLayout(node, node.arguments);
111
+ },
112
+ FunctionDeclaration: (node) => checkParameterLayout(node, node.params),
113
+ FunctionExpression: (node) => checkParameterLayout(node, node.params),
114
+ NewExpression: (node) => checkParameterLayout(node, node.arguments)
115
+ };
116
+ }
117
+ return defineScriptAndTemplateVisitors(context.sourceCode, createVisitor);
118
+ },
119
+ meta: {
120
+ docs: { description: "Keep parameter boundaries consistent, expand multiline lists, and compact test calls." },
121
+ fixable: "whitespace",
122
+ messages: {
123
+ compactTestCall: "Keep test-call arguments beside their parentheses and each other.",
124
+ newline: "Start a multiline parameter list on a new line.",
125
+ singleBoundary: "Use matching newline boundaries around a single parameter."
126
+ },
127
+ schema: [{
128
+ additionalProperties: false,
129
+ properties: { compactTestCalls: { type: "boolean" } },
130
+ type: "object"
131
+ }],
132
+ type: "layout"
133
+ }
134
+ };
135
+ export { consistentParameterLayout };
136
+
137
+ //# sourceMappingURL=consistent-parameter-layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consistent-parameter-layout.js","names":[],"sources":["../../../src/_internals/rules/consistent-parameter-layout.ts"],"sourcesContent":["import type {\n AST,\n Rule,\n} from 'eslint';\n\nimport type { TokenStore } from '../utils';\nimport { defineScriptAndTemplateVisitors } from '../utils';\n\ntype CallNode = Extract<Rule.Node, { type: 'CallExpression' | 'NewExpression' }> & { typeArguments?: Rule.Node };\ntype FunctionNode = Extract<\n Rule.Node,\n { type: 'ArrowFunctionExpression' | 'FunctionDeclaration' | 'FunctionExpression' }\n>;\n\ntype ListItem = CallNode['arguments'][number] | FunctionNode['params'][number];\n\nexport const consistentParameterLayout: Rule.RuleModule = {\n create(context) {\n const compactTestCalls = context.options[0]?.compactTestCalls === true;\n\n function createVisitor(tokenStore: TokenStore, isTemplate: boolean): Rule.RuleListener {\n function checkTestCallLayout(node: CallNode): void {\n const items = node.arguments;\n if (!items.length) return;\n const openingParen = tokenStore.getTokenAfter(\n node.typeArguments ?? node.callee,\n (token) => token.type === 'Punctuator' && token.value === '(',\n )!;\n\n const closingParen = tokenStore.getLastToken(node)!;\n const previous = tokenStore.getTokenBefore(closingParen)!;\n const gaps: Array<[AST.Token, AST.Token, string]> = [\n [\n openingParen,\n tokenStore.getTokenAfter(openingParen)!,\n '',\n ],\n [\n previous,\n closingParen,\n '',\n ],\n ];\n\n for (let index = 1; index < items.length; index++) {\n const comma = tokenStore.getTokensBetween(items[index - 1]!, items[index]!)\n .find((token) => token.type === 'Punctuator' && token.value === ',')!;\n\n gaps.push(\n [\n tokenStore.getTokenBefore(comma)!,\n comma,\n '',\n ],\n [\n comma,\n tokenStore.getTokenAfter(comma)!,\n ' ',\n ],\n );\n }\n\n if (previous.value === ',') {\n gaps.push([\n tokenStore.getTokenBefore(previous)!,\n previous,\n '',\n ]);\n }\n\n // Keep the whole list's layout when a boundary comment prevents safe compaction.\n if (gaps.some(([left, right]) => tokenStore.commentsExistBetween(left, right))) return;\n const multilineGaps = gaps.filter(([left, right]) => left.loc.end.line !== right.loc.start.line);\n if (!multilineGaps.length) return;\n\n context.report({\n fix: (fixer) => multilineGaps.map(([\n left,\n right,\n text,\n ]) => fixer.replaceTextRange(\n [\n left.range[1],\n right.range[0],\n ],\n text,\n )),\n messageId: 'compactTestCall',\n node,\n });\n }\n\n function checkParameterLayout(\n node: CallNode | FunctionNode,\n items: readonly ListItem[],\n ): void {\n const first = items[0];\n if (!first) return;\n const isSingleParameter = items.length === 1;\n\n // JSX argument layout belongs to the JSX formatting rules.\n const firstType: string = first.type;\n if (isSingleParameter && (firstType === 'JSXElement' || firstType === 'JSXFragment')) return;\n let openingParen;\n if (node.type === 'CallExpression' || node.type === 'NewExpression') {\n openingParen = tokenStore.getTokenAfter(\n node.typeArguments ?? node.callee,\n (token) => token.type === 'Punctuator' && token.value === '(',\n );\n } else {\n openingParen = tokenStore.getTokenBefore(first);\n }\n\n if (!openingParen || openingParen.value !== '(') return;\n // An unparenthesized arrow must not borrow its parent's delimiters.\n if (openingParen.range[0] < node.range![0]) return;\n const closingParen = node.type === 'CallExpression' || node.type === 'NewExpression'\n ? tokenStore.getLastToken(node)\n : tokenStore.getTokenAfter(items.at(-1)!, (token) => token.value === ')');\n\n const next = tokenStore.getTokenAfter(openingParen)!;\n\n if (isSingleParameter) {\n if (!closingParen || closingParen.value !== ')') return;\n let previous = tokenStore.getTokenBefore(closingParen)!;\n if (previous.value === ',') previous = tokenStore.getTokenBefore(previous)!;\n if (\n tokenStore.commentsExistBetween(openingParen, next)\n || tokenStore.commentsExistBetween(previous, closingParen)\n ) return;\n\n const hasOpeningNewline = openingParen.loc.end.line !== next.loc.start.line;\n const hasClosingNewline = tokenStore.getTokenBefore(closingParen)!.loc.end.line\n !== closingParen.loc.start.line;\n\n if (hasOpeningNewline === hasClosingNewline) return;\n\n context.report({\n fix: (fixer) => hasOpeningNewline\n ? fixer.insertTextBefore(closingParen, '\\n')\n : fixer.insertTextAfter(openingParen, '\\n'),\n messageId: 'singleBoundary',\n node,\n });\n\n return;\n }\n\n if (!closingParen || openingParen.loc.start.line === closingParen.loc.end.line) return;\n\n if (isTemplate) {\n // Script list formatters do not traverse Vue template expressions.\n const newlineOffsets: number[] = [];\n if (openingParen.loc.end.line === next.loc.start.line) newlineOffsets.push(openingParen.range[1]);\n for (let index = 1; index < items.length; index++) {\n const item = items[index]!;\n const comma = tokenStore.getTokensBetween(items[index - 1]!, item)\n .find((token) => token.value === ',');\n\n if (comma && comma.loc.end.line === tokenStore.getTokenAfter(comma)!.loc.start.line) {\n newlineOffsets.push(comma.range[1]);\n }\n }\n\n if (\n closingParen.value === ')'\n && tokenStore.getTokenBefore(closingParen)!.loc.end.line === closingParen.loc.start.line\n ) newlineOffsets.push(closingParen.range[0]);\n\n if (newlineOffsets.length) {\n context.report({\n fix: (fixer) => newlineOffsets.map((offset) => fixer.insertTextBeforeRange(\n [\n offset,\n offset,\n ],\n '\\n',\n )),\n messageId: 'newline',\n node: first,\n });\n }\n\n return;\n }\n\n if (openingParen.loc.end.line !== next.loc.start.line) return;\n\n context.report({\n fix: (fixer) => fixer.insertTextAfter(openingParen, '\\n'),\n messageId: 'newline',\n node: first,\n });\n }\n\n return {\n ArrowFunctionExpression: (node) => checkParameterLayout(node, node.params),\n CallExpression: (node) => {\n const { callee } = node;\n if (compactTestCalls) {\n const target = callee.type === 'MemberExpression'\n && !callee.computed\n && callee.property.type === 'Identifier'\n && callee.property.name === 'concurrent'\n ? callee.object\n : callee;\n\n if (\n target.type === 'Identifier'\n && (target.name === 'describe' || target.name === 'it')\n ) {\n checkTestCallLayout(node);\n return;\n }\n }\n\n checkParameterLayout(node, node.arguments);\n },\n FunctionDeclaration: (node) => checkParameterLayout(node, node.params),\n FunctionExpression: (node) => checkParameterLayout(node, node.params),\n NewExpression: (node) => checkParameterLayout(node, node.arguments),\n };\n }\n\n return defineScriptAndTemplateVisitors(context.sourceCode, createVisitor);\n },\n meta: {\n docs: { description: 'Keep parameter boundaries consistent, expand multiline lists, and compact test calls.' },\n fixable: 'whitespace',\n messages: {\n compactTestCall: 'Keep test-call arguments beside their parentheses and each other.',\n newline: 'Start a multiline parameter list on a new line.',\n singleBoundary: 'Use matching newline boundaries around a single parameter.',\n },\n schema: [\n {\n additionalProperties: false,\n properties: { compactTestCalls: { type: 'boolean' } },\n type: 'object',\n },\n ],\n type: 'layout',\n },\n};\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statement-padding.d.ts","names":[],"sources":["../../../src/_internals/rules/statement-padding.ts"],"mappings":";qBAIa,kBAAkB,KAAK"}
@@ -1,4 +1,4 @@
1
- // src/internals/rules/statement-padding.ts
1
+ // src/_internals/rules/statement-padding.ts
2
2
  const statementPadding = {
3
3
  create(context) {
4
4
  const { sourceCode } = context;
@@ -6,12 +6,11 @@ const statementPadding = {
6
6
  for (let index = 1; index < statements.length; index++) {
7
7
  const previous = statements[index - 1];
8
8
  const next = statements[index];
9
+ if ([previous, next].some((node) => node.type === "ImportDeclaration" || node.type === "ExportAllDeclaration" || node.type === "ExportNamedDeclaration" && node.source)) continue;
10
+ const previousFirstToken = sourceCode.getFirstToken(previous);
9
11
  const lastToken = sourceCode.getLastToken(previous);
10
12
  const firstToken = sourceCode.getFirstToken(next);
11
- const closingLine = sourceCode.lines[lastToken.loc.end.line - 1];
12
- const openingLine = sourceCode.lines[firstToken.loc.start.line - 1];
13
- const hasDifferentIndent = /^\s*/.exec(closingLine)[0] !== /^\s*/.exec(openingLine)[0];
14
- const hasStandaloneClosing = /^[)\]}]+;?$/.test(closingLine.slice(0, lastToken.loc.end.column).trim());
13
+ const isMultiline = previousFirstToken.loc.start.line !== lastToken.loc.end.line;
15
14
  const blockNode = previous.type === "ExportDefaultDeclaration" || previous.type === "ExportNamedDeclaration" ? previous.declaration : previous;
16
15
  const hasBlockClosing = lastToken.value === "}" && blockNode && [
17
16
  "BlockStatement",
@@ -27,13 +26,24 @@ const statementPadding = {
27
26
  "WhileStatement",
28
27
  "WithStatement"
29
28
  ].includes(blockNode.type);
30
- if (!hasDifferentIndent && !hasStandaloneClosing && !hasBlockClosing) continue;
31
- const comments = sourceCode.getCommentsBefore(next);
32
- if (sourceCode.lines.slice(lastToken.loc.end.line, firstToken.loc.start.line - 1).some((line, index) => !line.trim() && !comments.some((comment) => comment.loc.start.line <= lastToken.loc.end.line + index + 1 && comment.loc.end.line >= lastToken.loc.end.line + index + 1))) continue;
33
- const boundary = comments.find((comment) => comment.loc.start.line > lastToken.loc.end.line) ?? firstToken;
34
- const offset = boundary.loc.start.line > lastToken.loc.end.line ? boundary.range[0] - boundary.loc.start.column : boundary.range[0];
29
+ if (!isMultiline && !hasBlockClosing) continue;
30
+ let previousEnd = lastToken.range[1];
31
+ let previousEndLine = lastToken.loc.end.line;
32
+ let nextStart = firstToken.range[0];
33
+ let nextStartLine = firstToken.loc.start.line;
34
+ for (const comment of sourceCode.getCommentsBefore(next)) if (comment.loc.start.line === previousEndLine) {
35
+ previousEnd = comment.range[1];
36
+ previousEndLine = comment.loc.end.line;
37
+ } else {
38
+ nextStart = comment.range[0];
39
+ nextStartLine = comment.loc.start.line;
40
+ break;
41
+ }
42
+ if (nextStartLine > previousEndLine + 1) continue;
43
+ const linebreakIndex = sourceCode.text.slice(previousEnd, nextStart).indexOf("\n");
44
+ const offset = linebreakIndex === -1 ? nextStart : previousEnd + linebreakIndex + 1;
35
45
  context.report({
36
- fix: (fixer) => fixer.insertTextBeforeRange([offset, offset], boundary.loc.start.line === lastToken.loc.end.line ? "\n\n" : "\n"),
46
+ fix: (fixer) => fixer.insertTextBeforeRange([offset, offset], linebreakIndex === -1 ? "\n\n" : "\n"),
37
47
  messageId: "blankLine",
38
48
  node: next
39
49
  });
@@ -47,7 +57,7 @@ const statementPadding = {
47
57
  };
48
58
  },
49
59
  meta: {
50
- docs: { description: "Separate statements after closing lines, blocks, or indentation changes." },
60
+ docs: { description: "Separate complete multiline statements and block-ending statements with blank lines." },
51
61
  fixable: "whitespace",
52
62
  messages: { blankLine: "Add a blank line between these complete statements." },
53
63
  schema: [],
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statement-padding.js","names":[],"sources":["../../../src/_internals/rules/statement-padding.ts"],"sourcesContent":["import type { Rule } from 'eslint';\n\ntype StatementNode = Extract<Rule.Node, { type: 'Program' }>['body'][number];\n\nexport const statementPadding: Rule.RuleModule = {\n create(context) {\n const { sourceCode } = context;\n\n function checkStatements(statements: readonly StatementNode[]): void {\n for (let index = 1; index < statements.length; index++) {\n const previous = statements[index - 1]!;\n const next = statements[index]!;\n if (\n [\n previous,\n next,\n ].some((node) =>\n node.type === 'ImportDeclaration'\n || node.type === 'ExportAllDeclaration'\n || (node.type === 'ExportNamedDeclaration' && node.source))\n ) continue;\n\n const previousFirstToken = sourceCode.getFirstToken(previous)!;\n const lastToken = sourceCode.getLastToken(previous)!;\n const firstToken = sourceCode.getFirstToken(next)!;\n const isMultiline = previousFirstToken.loc.start.line !== lastToken.loc.end.line;\n const blockNode = previous.type === 'ExportDefaultDeclaration'\n || previous.type === 'ExportNamedDeclaration'\n ? previous.declaration\n : previous;\n\n const hasBlockClosing = lastToken.value === '}' && blockNode && [\n 'BlockStatement',\n 'ClassDeclaration',\n 'ForInStatement',\n 'ForOfStatement',\n 'ForStatement',\n 'FunctionDeclaration',\n 'IfStatement',\n 'LabeledStatement',\n 'SwitchStatement',\n 'TryStatement',\n 'WhileStatement',\n 'WithStatement',\n ].includes(blockNode.type);\n\n if (!isMultiline && !hasBlockClosing) continue;\n let previousEnd = lastToken.range[1];\n let previousEndLine = lastToken.loc.end.line;\n let nextStart = firstToken.range[0];\n let nextStartLine = firstToken.loc.start.line;\n\n // Include trailing comments in the previous boundary, not leading comments of the next statement.\n for (const comment of sourceCode.getCommentsBefore(next)) {\n if (comment.loc!.start.line === previousEndLine) {\n previousEnd = comment.range![1];\n previousEndLine = comment.loc!.end.line;\n } else {\n nextStart = comment.range![0];\n nextStartLine = comment.loc!.start.line;\n break;\n }\n }\n\n if (nextStartLine > previousEndLine + 1) continue;\n const linebreakIndex = sourceCode.text.slice(previousEnd, nextStart).indexOf('\\n');\n const offset = linebreakIndex === -1 ? nextStart : previousEnd + linebreakIndex + 1;\n\n context.report({\n fix: (fixer) => fixer.insertTextBeforeRange(\n [\n offset,\n offset,\n ],\n linebreakIndex === -1 ? '\\n\\n' : '\\n',\n ),\n messageId: 'blankLine',\n node: next,\n });\n }\n }\n\n return {\n BlockStatement: (node) => checkStatements(node.body),\n Program: (node) => checkStatements(node.body),\n StaticBlock: (node) => checkStatements(node.body),\n SwitchCase: (node) => checkStatements(node.consequent),\n };\n },\n meta: {\n docs: { description: 'Separate complete multiline statements and block-ending statements with blank lines.' },\n fixable: 'whitespace',\n messages: { blankLine: 'Add a blank line between these complete statements.' },\n schema: [],\n type: 'layout',\n },\n};\n"],"mappings":";AAIA,MAAa,mBAAoC;CAC7C,OAAO,SAAS;EACZ,MAAM,EAAE,eAAe;EAEvB,SAAS,gBAAgB,YAA4C;GACjE,KAAK,IAAI,QAAQ,GAAG,QAAQ,WAAW,QAAQ,SAAS;IACpD,MAAM,WAAW,WAAW,QAAQ;IACpC,MAAM,OAAO,WAAW;IACxB,IACI,CACI,UACA,IACJ,CAAC,CAAC,MAAM,SACJ,KAAK,SAAS,uBACX,KAAK,SAAS,0BACb,KAAK,SAAS,4BAA4B,KAAK,MAAO,GAChE;IAEF,MAAM,qBAAqB,WAAW,cAAc,QAAQ;IAC5D,MAAM,YAAY,WAAW,aAAa,QAAQ;IAClD,MAAM,aAAa,WAAW,cAAc,IAAI;IAChD,MAAM,cAAc,mBAAmB,IAAI,MAAM,SAAS,UAAU,IAAI,IAAI;IAC5E,MAAM,YAAY,SAAS,SAAS,8BAC/B,SAAS,SAAS,2BACjB,SAAS,cACT;IAEN,MAAM,kBAAkB,UAAU,UAAU,OAAO,aAAa;KAC5D;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;IACJ,CAAC,CAAC,SAAS,UAAU,IAAI;IAEzB,IAAI,CAAC,eAAe,CAAC,iBAAiB;IACtC,IAAI,cAAc,UAAU,MAAM;IAClC,IAAI,kBAAkB,UAAU,IAAI,IAAI;IACxC,IAAI,YAAY,WAAW,MAAM;IACjC,IAAI,gBAAgB,WAAW,IAAI,MAAM;IAGzC,KAAK,MAAM,WAAW,WAAW,kBAAkB,IAAI,GACnD,IAAI,QAAQ,IAAK,MAAM,SAAS,iBAAiB;KAC7C,cAAc,QAAQ,MAAO;KAC7B,kBAAkB,QAAQ,IAAK,IAAI;IACvC,OAAO;KACH,YAAY,QAAQ,MAAO;KAC3B,gBAAgB,QAAQ,IAAK,MAAM;KACnC;IACJ;IAGJ,IAAI,gBAAgB,kBAAkB,GAAG;IACzC,MAAM,iBAAiB,WAAW,KAAK,MAAM,aAAa,SAAS,CAAC,CAAC,QAAQ,IAAI;IACjF,MAAM,SAAS,mBAAmB,KAAK,YAAY,cAAc,iBAAiB;IAElF,QAAQ,OAAO;KACX,MAAM,UAAU,MAAM,sBAClB,CACI,QACA,MACJ,GACA,mBAAmB,KAAK,SAAS,IACrC;KACA,WAAW;KACX,MAAM;IACV,CAAC;GACL;EACJ;EAEA,OAAO;GACH,iBAAiB,SAAS,gBAAgB,KAAK,IAAI;GACnD,UAAU,SAAS,gBAAgB,KAAK,IAAI;GAC5C,cAAc,SAAS,gBAAgB,KAAK,IAAI;GAChD,aAAa,SAAS,gBAAgB,KAAK,UAAU;EACzD;CACJ;CACA,MAAM;EACF,MAAM,EAAE,aAAa,uFAAuF;EAC5G,SAAS;EACT,UAAU,EAAE,WAAW,sDAAsD;EAC7E,QAAQ,CAAC;EACT,MAAM;CACV;AACJ"}
@@ -0,0 +1,3 @@
1
+ import { TypedFlatConfigItem } from "@antfu/eslint-config";
2
+ export declare function createTypeAwareConfig(): TypedFlatConfigItem;
3
+ //# sourceMappingURL=type-aware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-aware.d.ts","names":[],"sources":["../../src/_internals/type-aware.ts"],"mappings":";wBAEgB,yBAAyB"}
@@ -0,0 +1,25 @@
1
+ // src/_internals/type-aware.ts
2
+ function createTypeAwareConfig() {
3
+ return {
4
+ languageOptions: { parserOptions: {
5
+ projectService: true,
6
+ tsconfigRootDir: process.cwd()
7
+ } },
8
+ rules: {
9
+ "require-await": "off",
10
+ "ts/await-thenable": "error",
11
+ "ts/no-base-to-string": "error",
12
+ "ts/no-floating-promises": "error",
13
+ "ts/no-for-in-array": "error",
14
+ "ts/no-misused-promises": "error",
15
+ "ts/no-misused-spread": "error",
16
+ "ts/no-unnecessary-type-assertion": "error",
17
+ "ts/require-await": "error",
18
+ "ts/return-await": "error",
19
+ "ts/switch-exhaustiveness-check": ["error", { considerDefaultExhaustiveForUnions: true }]
20
+ }
21
+ };
22
+ }
23
+ export { createTypeAwareConfig };
24
+
25
+ //# sourceMappingURL=type-aware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-aware.js","names":[],"sources":["../../src/_internals/type-aware.ts"],"sourcesContent":["import type { TypedFlatConfigItem } from '@antfu/eslint-config';\n\nexport function createTypeAwareConfig(): TypedFlatConfigItem {\n return {\n languageOptions: {\n parserOptions: {\n projectService: true,\n tsconfigRootDir: process.cwd(),\n },\n },\n rules: {\n 'require-await': 'off',\n 'ts/await-thenable': 'error',\n 'ts/no-base-to-string': 'error',\n 'ts/no-floating-promises': 'error',\n 'ts/no-for-in-array': 'error',\n 'ts/no-misused-promises': 'error',\n 'ts/no-misused-spread': 'error',\n 'ts/no-unnecessary-type-assertion': 'error',\n 'ts/require-await': 'error',\n 'ts/return-await': 'error',\n 'ts/switch-exhaustiveness-check': [\n 'error',\n { considerDefaultExhaustiveForUnions: true },\n ],\n },\n };\n}\n"],"mappings":";AAEA,SAAgB,wBAA6C;CACzD,OAAO;EACH,iBAAiB,EACb,eAAe;GACX,gBAAgB;GAChB,iBAAiB,QAAQ,IAAI;EACjC,EACJ;EACA,OAAO;GACH,iBAAiB;GACjB,qBAAqB;GACrB,wBAAwB;GACxB,2BAA2B;GAC3B,sBAAsB;GACtB,0BAA0B;GAC1B,wBAAwB;GACxB,oCAAoC;GACpC,oBAAoB;GACpB,mBAAmB;GACnB,kCAAkC,CAC9B,SACA,EAAE,oCAAoC,KAAK,CAC/C;EACJ;CACJ;AACJ"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","names":[],"sources":["../../src/_internals/utils.ts"],"mappings":";YAKY,aAAa,KACrB;wBAaY,gCACZ,YAAY,YACZ,gBAAgB,YAAY,YAAY,wBAAwB,KAAK,eACtE,KAAK"}
@@ -1,4 +1,4 @@
1
- // src/internals/utils.ts
1
+ // src/_internals/utils.ts
2
2
  function defineScriptAndTemplateVisitors(sourceCode, createVisitor) {
3
3
  const scriptVisitor = createVisitor(sourceCode, false);
4
4
  const parserServices = sourceCode.parserServices;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../src/_internals/utils.ts"],"sourcesContent":["import type {\n Rule,\n SourceCode,\n} from 'eslint';\n\nexport type TokenStore = Pick<\n SourceCode,\n 'commentsExistBetween' | 'getLastToken' | 'getTokenAfter' | 'getTokenBefore' | 'getTokensBetween'\n>;\n\ninterface TemplateParserServices {\n defineTemplateBodyVisitor?: (\n templateVisitor: Rule.RuleListener,\n scriptVisitor: Rule.RuleListener,\n ) => Rule.RuleListener;\n\n getTemplateBodyTokenStore?: () => TokenStore;\n}\n\nexport function defineScriptAndTemplateVisitors(\n sourceCode: SourceCode,\n createVisitor: (tokenStore: TokenStore, isTemplate: boolean) => Rule.RuleListener,\n): Rule.RuleListener {\n const scriptVisitor = createVisitor(sourceCode, false);\n const parserServices = sourceCode.parserServices as TemplateParserServices;\n if (!parserServices.defineTemplateBodyVisitor || !parserServices.getTemplateBodyTokenStore) return scriptVisitor;\n\n return parserServices.defineTemplateBodyVisitor(\n createVisitor(parserServices.getTemplateBodyTokenStore(), true),\n scriptVisitor,\n );\n}\n"],"mappings":";AAmBA,SAAgB,gCACZ,YACA,eACiB;CACjB,MAAM,gBAAgB,cAAc,YAAY,KAAK;CACrD,MAAM,iBAAiB,WAAW;CAClC,IAAI,CAAC,eAAe,6BAA6B,CAAC,eAAe,2BAA2B,OAAO;CAEnG,OAAO,eAAe,0BAClB,cAAc,eAAe,0BAA0B,GAAG,IAAI,GAC9D,aACJ;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","names":[],"sources":["../src/base.ts"],"mappings":";wBAgBgB,kBAAkB,+BAAuC;wBA+EzD,gBAAgB,+BAAuC"}
1
+ {"version":3,"file":"base.d.ts","names":[],"sources":["../src/base.ts"],"mappings":";wBAoCgB,kBAAkB,+BAAuC;wBAsGzD,gBAAgB,+BAAuC"}
package/dist/base.js CHANGED
@@ -1,18 +1,36 @@
1
- import { customPlugins } from "./internals/plugins.js";
1
+ import { customPlugins } from "./_internals/plugins.js";
2
+ import { createTypeAwareConfig } from "./_internals/type-aware.js";
3
+ import { GLOB_JS, GLOB_JSX, GLOB_TESTS, GLOB_TS, GLOB_TSX } from "@antfu/eslint-config";
2
4
  import promise from "eslint-plugin-promise";
3
5
  // src/base.ts
4
6
  const basePerfectionistSortOptions = {
5
7
  ignoreCase: false,
6
8
  type: "natural"
7
9
  };
10
+ const vscodeOrderSensitiveArrayProperties = [
11
+ "args",
12
+ "autoAttachSmartPattern",
13
+ "dependsOn",
14
+ "options",
15
+ "outFiles",
16
+ "problemMatcher",
17
+ "resolveSourceMapLocations",
18
+ "runtimeArgs",
19
+ "skipFiles"
20
+ ].join("|");
8
21
  function createBaseConfigs(environment = "node") {
9
22
  return [
10
23
  { rules: {
11
- "e18e/ban-dependencies": ["error", { allowed: ["axios", "rimraf"] }],
12
- "e18e/prefer-static-regex": ["off"]
24
+ "e18e/ban-dependencies": ["error", { allowed: ["axios"] }],
25
+ "e18e/prefer-static-regex": "off"
13
26
  } },
14
27
  {
15
- files: ["**/*.{cjs,js,mjs}"],
28
+ files: [
29
+ GLOB_JS,
30
+ GLOB_JSX,
31
+ GLOB_TS,
32
+ GLOB_TSX
33
+ ],
16
34
  plugins: {
17
35
  kikiutils: customPlugins,
18
36
  promise
@@ -23,18 +41,26 @@ function createBaseConfigs(environment = "node") {
23
41
  }
24
42
  },
25
43
  {
26
- files: ["**/*.{ts,tsx}"],
27
- plugins: {
28
- kikiutils: customPlugins,
29
- promise
30
- },
44
+ files: [GLOB_TS, GLOB_TSX],
31
45
  rules: {
32
- ...createBaseRules(environment),
33
- "node/prefer-global/process": ["error", "always"],
46
+ "ts/array-type": ["error", { default: "array-simple" }],
34
47
  "ts/consistent-generic-constructors": ["error", "constructor"],
35
48
  "ts/no-redeclare": "off"
36
49
  }
37
50
  },
51
+ {
52
+ ...createTypeAwareConfig(),
53
+ files: [GLOB_TS, GLOB_TSX],
54
+ ignores: ["**/*.config.?([cm])ts"]
55
+ },
56
+ {
57
+ files: GLOB_TESTS,
58
+ rules: {
59
+ "kikiutils/consistent-parameter-layout": ["error", { compactTestCalls: true }],
60
+ "test/valid-expect": "error",
61
+ "test/valid-expect-in-promise": "error"
62
+ }
63
+ },
38
64
  {
39
65
  files: ["**/.vscode/*.json"],
40
66
  rules: {
@@ -43,7 +69,7 @@ function createBaseConfigs(environment = "node") {
43
69
  natural: true,
44
70
  type: "asc"
45
71
  },
46
- pathPattern: "^.*$"
72
+ pathPattern: String.raw`^(?!.*(?:^|\.|\[")(?:${vscodeOrderSensitiveArrayProperties})(?:$|\.|\[|"\])).*`
47
73
  }],
48
74
  "jsonc/sort-keys": [
49
75
  "error",
@@ -54,7 +80,8 @@ function createBaseConfigs(environment = "node") {
54
80
  }
55
81
  ]
56
82
  }
57
- }
83
+ },
84
+ { ignores: ["**/*.md/**"] }
58
85
  ];
59
86
  }
60
87
  function createBaseRules(environment = "node") {
@@ -74,16 +101,15 @@ function createBaseRules(environment = "node") {
74
101
  "kikiutils/consistent-parameter-layout": "error",
75
102
  "kikiutils/statement-padding": "error",
76
103
  "max-classes-per-file": ["error", 1],
104
+ "no-constant-binary-expression": "error",
77
105
  "no-promise-executor-return": ["error", { allowVoid: true }],
106
+ "no-useless-assignment": "error",
78
107
  "perfectionist/sort-array-includes": ["error", basePerfectionistSortOptions],
79
108
  "perfectionist/sort-enums": ["error", {
80
109
  ...basePerfectionistSortOptions,
81
110
  sortByValue: "never"
82
111
  }],
83
- "perfectionist/sort-heritage-clauses": ["error", {
84
- ignoreCase: false,
85
- type: "natural"
86
- }],
112
+ "perfectionist/sort-heritage-clauses": ["error", basePerfectionistSortOptions],
87
113
  "perfectionist/sort-imports": ["error", {
88
114
  environment,
89
115
  groups: [
@@ -133,6 +159,7 @@ function createBaseRules(environment = "node") {
133
159
  }],
134
160
  "perfectionist/sort-union-types": ["error", basePerfectionistSortOptions],
135
161
  "perfectionist/sort-variable-declarations": ["error", basePerfectionistSortOptions],
162
+ "preserve-caught-error": "error",
136
163
  "promise/no-multiple-resolved": "error",
137
164
  "promise/no-return-in-finally": "error",
138
165
  "promise/no-return-wrap": "error",
package/dist/base.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","names":[],"sources":["../src/base.ts"],"sourcesContent":["import type {\n Rules,\n TypedFlatConfigItem,\n} from '@antfu/eslint-config';\n// @ts-expect-error No declare file.\nimport promise from 'eslint-plugin-promise';\n\nimport { customPlugins } from './internals/plugins';\n\n// Constants/Variables\nconst basePerfectionistSortOptions = {\n ignoreCase: false,\n type: 'natural',\n} as const;\n\n// Functions\nexport function createBaseConfigs(environment: 'bun' | 'node' = 'node'): TypedFlatConfigItem[] {\n return [\n // All files\n {\n rules: {\n 'e18e/ban-dependencies': [\n 'error',\n {\n allowed: [\n 'axios',\n 'rimraf',\n ],\n },\n ],\n 'e18e/prefer-static-regex': ['off'],\n },\n },\n // JavaScript\n {\n files: ['**/*.{cjs,js,mjs}'],\n plugins: {\n kikiutils: customPlugins,\n promise,\n },\n rules: {\n ...createBaseRules(environment),\n 'node/prefer-global/process': [\n 'error',\n 'always',\n ],\n },\n },\n // TypeScript\n {\n files: ['**/*.{ts,tsx}'],\n plugins: {\n kikiutils: customPlugins,\n promise,\n },\n rules: {\n ...createBaseRules(environment),\n 'node/prefer-global/process': [\n 'error',\n 'always',\n ],\n 'ts/consistent-generic-constructors': [\n 'error',\n 'constructor',\n ],\n 'ts/no-redeclare': 'off',\n },\n },\n // VsCode jsonc\n {\n files: ['**/.vscode/*.json'],\n rules: {\n 'jsonc/sort-array-values': [\n 'error',\n {\n order: {\n natural: true,\n type: 'asc',\n },\n pathPattern: '^.*$',\n },\n ],\n 'jsonc/sort-keys': [\n 'error',\n 'asc',\n {\n caseSensitive: true,\n natural: true,\n },\n ],\n },\n },\n ];\n}\n\nexport function createBaseRules(environment: 'bun' | 'node' = 'node'): Rules {\n return {\n 'antfu/consistent-list-newline': [\n 'error',\n {\n ArrayExpression: false,\n ArrayPattern: false,\n },\n ],\n 'antfu/curly': 'off',\n 'antfu/if-newline': 'off',\n 'antfu/no-top-level-await': 'off',\n 'antfu/reasonable-newline': 'off',\n 'arrow-body-style': [\n 'error',\n 'as-needed',\n ],\n 'curly': [\n 'error',\n 'multi-line',\n ],\n 'kikiutils/compact-iteration-layout': 'error',\n 'kikiutils/consistent-condition-layout': 'error',\n 'kikiutils/consistent-parameter-layout': 'error',\n 'kikiutils/statement-padding': 'error',\n 'max-classes-per-file': [\n 'error',\n 1,\n ],\n 'no-promise-executor-return': [\n 'error',\n { allowVoid: true },\n ],\n 'perfectionist/sort-array-includes': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-enums': [\n 'error',\n {\n ...basePerfectionistSortOptions,\n sortByValue: 'never',\n },\n ],\n 'perfectionist/sort-heritage-clauses': [\n 'error',\n {\n ignoreCase: false,\n type: 'natural',\n },\n ],\n 'perfectionist/sort-imports': [\n 'error',\n {\n environment,\n groups: [\n 'side-effect',\n 'side-effect-style',\n 'style',\n [\n 'value-builtin',\n 'type-builtin',\n ],\n [\n 'value-external',\n 'type-external',\n ],\n [\n 'value-internal',\n 'type-internal',\n ],\n [\n 'value-parent',\n 'type-parent',\n ],\n [\n 'value-sibling',\n 'type-sibling',\n ],\n [\n 'value-index',\n 'type-index',\n ],\n 'unknown',\n ],\n ignoreCase: false,\n internalPattern: [\n '^#.*',\n '^@/.*',\n '^~/.*',\n ],\n type: 'natural',\n },\n ],\n 'perfectionist/sort-interfaces': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-intersection-types': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-maps': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-modules': [\n 'error',\n {\n ...basePerfectionistSortOptions,\n groups: [\n 'declare-type',\n [\n 'export-type',\n 'type',\n ],\n 'declare-interface',\n [\n 'export-interface',\n 'interface',\n ],\n 'declare-enum',\n [\n 'enum',\n 'export-enum',\n ],\n 'declare-class',\n [\n 'class',\n 'export-class',\n ],\n 'declare-function',\n [\n 'export-function',\n 'function',\n ],\n ],\n },\n ],\n 'perfectionist/sort-object-types': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-objects': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-sets': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-switch-case': [\n 'error',\n {\n ignoreCase: false,\n type: 'natural',\n },\n ],\n 'perfectionist/sort-union-types': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-variable-declarations': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'promise/no-multiple-resolved': 'error',\n 'promise/no-return-in-finally': 'error',\n 'promise/no-return-wrap': 'error',\n 'require-await': 'error',\n 'style/array-bracket-newline': [\n 'error',\n { multiline: true },\n ],\n 'style/array-element-newline': [\n 'error',\n {\n ArrayExpression: {\n consistent: true,\n minItems: 2,\n },\n ArrayPattern: { minItems: 3 },\n },\n ],\n 'style/arrow-parens': [\n 'error',\n 'always',\n ],\n 'style/brace-style': [\n 'error',\n '1tbs',\n { allowSingleLine: false },\n ],\n 'style/function-call-spacing': [\n 'error',\n 'never',\n ],\n 'style/indent': [\n 'error',\n 4,\n ],\n 'style/max-len': [\n 'warn',\n {\n code: 120,\n comments: 120,\n },\n ],\n 'style/member-delimiter-style': [\n 'error',\n {\n multiline: {\n delimiter: 'semi',\n requireLast: true,\n },\n },\n ],\n 'style/no-extra-parens': [\n 'error',\n 'all',\n { nestedBinaryExpressions: false },\n ],\n 'style/no-extra-semi': 'error',\n 'style/object-curly-newline': [\n 'error',\n {\n ExportDeclaration: {\n minProperties: 2,\n multiline: true,\n },\n ImportDeclaration: {\n minProperties: 2,\n multiline: true,\n },\n ObjectExpression: {\n minProperties: 2,\n multiline: true,\n },\n ObjectPattern: {\n minProperties: 3,\n multiline: true,\n },\n },\n ],\n 'style/operator-linebreak': [\n 'error',\n 'before',\n { overrides: { '=': 'after' } },\n ],\n 'style/padding-line-between-statements': [\n 'error',\n {\n blankLine: 'always',\n next: [\n 'class',\n 'enum',\n 'function',\n ],\n prev: '*',\n },\n {\n blankLine: 'always',\n next: '*',\n prev: [\n 'class',\n 'function',\n ],\n },\n ],\n 'style/semi': [\n 'error',\n 'always',\n ],\n };\n}\n"],"mappings":";;;AAUA,MAAM,+BAA+B;CACjC,YAAY;CACZ,MAAM;AACV;AAGA,SAAgB,kBAAkB,cAA8B,QAA+B;CAC3F,OAAO;EAEH,EACI,OAAO;GACH,yBAAyB,CACrB,SACA,EACI,SAAS,CACL,SACA,QACJ,EACJ,CACJ;GACA,4BAA4B,CAAC,KAAK;EACtC,EACJ;EAEA;GACI,OAAO,CAAC,mBAAmB;GAC3B,SAAS;IACL,WAAW;IACX;GACJ;GACA,OAAO;IACH,GAAG,gBAAgB,WAAW;IAC9B,8BAA8B,CAC1B,SACA,QACJ;GACJ;EACJ;EAEA;GACI,OAAO,CAAC,eAAe;GACvB,SAAS;IACL,WAAW;IACX;GACJ;GACA,OAAO;IACH,GAAG,gBAAgB,WAAW;IAC9B,8BAA8B,CAC1B,SACA,QACJ;IACA,sCAAsC,CAClC,SACA,aACJ;IACA,mBAAmB;GACvB;EACJ;EAEA;GACI,OAAO,CAAC,mBAAmB;GAC3B,OAAO;IACH,2BAA2B,CACvB,SACA;KACI,OAAO;MACH,SAAS;MACT,MAAM;KACV;KACA,aAAa;IACjB,CACJ;IACA,mBAAmB;KACf;KACA;KACA;MACI,eAAe;MACf,SAAS;KACb;IACJ;GACJ;EACJ;CACJ;AACJ;AAEA,SAAgB,gBAAgB,cAA8B,QAAe;CACzE,OAAO;EACH,iCAAiC,CAC7B,SACA;GACI,iBAAiB;GACjB,cAAc;EAClB,CACJ;EACA,eAAe;EACf,oBAAoB;EACpB,4BAA4B;EAC5B,4BAA4B;EAC5B,oBAAoB,CAChB,SACA,WACJ;EACA,SAAS,CACL,SACA,YACJ;EACA,sCAAsC;EACtC,yCAAyC;EACzC,yCAAyC;EACzC,+BAA+B;EAC/B,wBAAwB,CACpB,SACA,CACJ;EACA,8BAA8B,CAC1B,SACA,EAAE,WAAW,KAAK,CACtB;EACA,qCAAqC,CACjC,SACA,4BACJ;EACA,4BAA4B,CACxB,SACA;GACI,GAAG;GACH,aAAa;EACjB,CACJ;EACA,uCAAuC,CACnC,SACA;GACI,YAAY;GACZ,MAAM;EACV,CACJ;EACA,8BAA8B,CAC1B,SACA;GACI;GACA,QAAQ;IACJ;IACA;IACA;IACA,CACI,iBACA,cACJ;IACA,CACI,kBACA,eACJ;IACA,CACI,kBACA,eACJ;IACA,CACI,gBACA,aACJ;IACA,CACI,iBACA,cACJ;IACA,CACI,eACA,YACJ;IACA;GACJ;GACA,YAAY;GACZ,iBAAiB;IACb;IACA;IACA;GACJ;GACA,MAAM;EACV,CACJ;EACA,iCAAiC,CAC7B,SACA,4BACJ;EACA,yCAAyC,CACrC,SACA,4BACJ;EACA,2BAA2B,CACvB,SACA,4BACJ;EACA,8BAA8B,CAC1B,SACA;GACI,GAAG;GACH,QAAQ;IACJ;IACA,CACI,eACA,MACJ;IACA;IACA,CACI,oBACA,WACJ;IACA;IACA,CACI,QACA,aACJ;IACA;IACA,CACI,SACA,cACJ;IACA;IACA,CACI,mBACA,UACJ;GACJ;EACJ,CACJ;EACA,mCAAmC,CAC/B,SACA,4BACJ;EACA,8BAA8B,CAC1B,SACA,4BACJ;EACA,2BAA2B,CACvB,SACA,4BACJ;EACA,kCAAkC,CAC9B,SACA;GACI,YAAY;GACZ,MAAM;EACV,CACJ;EACA,kCAAkC,CAC9B,SACA,4BACJ;EACA,4CAA4C,CACxC,SACA,4BACJ;EACA,gCAAgC;EAChC,gCAAgC;EAChC,0BAA0B;EAC1B,iBAAiB;EACjB,+BAA+B,CAC3B,SACA,EAAE,WAAW,KAAK,CACtB;EACA,+BAA+B,CAC3B,SACA;GACI,iBAAiB;IACb,YAAY;IACZ,UAAU;GACd;GACA,cAAc,EAAE,UAAU,EAAE;EAChC,CACJ;EACA,sBAAsB,CAClB,SACA,QACJ;EACA,qBAAqB;GACjB;GACA;GACA,EAAE,iBAAiB,MAAM;EAC7B;EACA,+BAA+B,CAC3B,SACA,OACJ;EACA,gBAAgB,CACZ,SACA,CACJ;EACA,iBAAiB,CACb,QACA;GACI,MAAM;GACN,UAAU;EACd,CACJ;EACA,gCAAgC,CAC5B,SACA,EACI,WAAW;GACP,WAAW;GACX,aAAa;EACjB,EACJ,CACJ;EACA,yBAAyB;GACrB;GACA;GACA,EAAE,yBAAyB,MAAM;EACrC;EACA,uBAAuB;EACvB,8BAA8B,CAC1B,SACA;GACI,mBAAmB;IACf,eAAe;IACf,WAAW;GACf;GACA,mBAAmB;IACf,eAAe;IACf,WAAW;GACf;GACA,kBAAkB;IACd,eAAe;IACf,WAAW;GACf;GACA,eAAe;IACX,eAAe;IACf,WAAW;GACf;EACJ,CACJ;EACA,4BAA4B;GACxB;GACA;GACA,EAAE,WAAW,EAAE,KAAK,QAAQ,EAAE;EAClC;EACA,yCAAyC;GACrC;GACA;IACI,WAAW;IACX,MAAM;KACF;KACA;KACA;IACJ;IACA,MAAM;GACV;GACA;IACI,WAAW;IACX,MAAM;IACN,MAAM,CACF,SACA,UACJ;GACJ;EACJ;EACA,cAAc,CACV,SACA,QACJ;CACJ;AACJ"}
1
+ {"version":3,"file":"base.js","names":[],"sources":["../src/base.ts"],"sourcesContent":["import type {\n Rules,\n TypedFlatConfigItem,\n} from '@antfu/eslint-config';\nimport {\n GLOB_JS,\n GLOB_JSX,\n GLOB_TESTS,\n GLOB_TS,\n GLOB_TSX,\n} from '@antfu/eslint-config';\n// @ts-expect-error No declare file.\nimport promise from 'eslint-plugin-promise';\n\nimport { customPlugins } from './_internals/plugins';\nimport { createTypeAwareConfig } from './_internals/type-aware';\n\n// Constants/Variables\nconst basePerfectionistSortOptions = {\n ignoreCase: false,\n type: 'natural',\n} as const;\n\nconst vscodeOrderSensitiveArrayProperties = [\n 'args',\n 'autoAttachSmartPattern',\n 'dependsOn',\n 'options',\n 'outFiles',\n 'problemMatcher',\n 'resolveSourceMapLocations',\n 'runtimeArgs',\n 'skipFiles',\n].join('|');\n\n// Functions\nexport function createBaseConfigs(environment: 'bun' | 'node' = 'node'): TypedFlatConfigItem[] {\n return [\n // All files\n {\n rules: {\n 'e18e/ban-dependencies': [\n 'error',\n { allowed: ['axios'] },\n ],\n 'e18e/prefer-static-regex': 'off',\n },\n },\n // JavaScript and TypeScript\n {\n files: [\n GLOB_JS,\n GLOB_JSX,\n GLOB_TS,\n GLOB_TSX,\n ],\n plugins: {\n kikiutils: customPlugins,\n promise,\n },\n rules: {\n ...createBaseRules(environment),\n 'node/prefer-global/process': [\n 'error',\n 'always',\n ],\n },\n },\n // TypeScript\n {\n files: [\n GLOB_TS,\n GLOB_TSX,\n ],\n rules: {\n 'ts/array-type': [\n 'error',\n { default: 'array-simple' },\n ],\n 'ts/consistent-generic-constructors': [\n 'error',\n 'constructor',\n ],\n 'ts/no-redeclare': 'off',\n },\n },\n // Type-aware TypeScript\n {\n ...createTypeAwareConfig(),\n files: [\n GLOB_TS,\n GLOB_TSX,\n ],\n ignores: ['**/*.config.?([cm])ts'],\n },\n // Tests\n {\n files: GLOB_TESTS,\n rules: {\n 'kikiutils/consistent-parameter-layout': [\n 'error',\n { compactTestCalls: true },\n ],\n 'test/valid-expect': 'error',\n 'test/valid-expect-in-promise': 'error',\n },\n },\n // VS Code JSONC\n {\n files: ['**/.vscode/*.json'],\n rules: {\n 'jsonc/sort-array-values': [\n 'error',\n {\n order: {\n natural: true,\n type: 'asc',\n },\n // Preserve ordered fields and any argument or option arrays nested inside them.\n // eslint-disable-next-line style/max-len\n pathPattern: String.raw`^(?!.*(?:^|\\.|\\[\")(?:${vscodeOrderSensitiveArrayProperties})(?:$|\\.|\\[|\"\\])).*`,\n },\n ],\n 'jsonc/sort-keys': [\n 'error',\n 'asc',\n {\n caseSensitive: true,\n natural: true,\n },\n ],\n },\n },\n // Ignore all extracted Markdown code blocks, but keep linting Markdown itself.\n { ignores: ['**/*.md/**'] },\n ];\n}\n\nexport function createBaseRules(environment: 'bun' | 'node' = 'node'): Rules {\n return {\n 'antfu/consistent-list-newline': [\n 'error',\n {\n ArrayExpression: false,\n ArrayPattern: false,\n },\n ],\n 'antfu/curly': 'off',\n 'antfu/if-newline': 'off',\n 'antfu/no-top-level-await': 'off',\n 'antfu/reasonable-newline': 'off',\n 'arrow-body-style': [\n 'error',\n 'as-needed',\n ],\n 'curly': [\n 'error',\n 'multi-line',\n ],\n 'kikiutils/compact-iteration-layout': 'error',\n 'kikiutils/consistent-condition-layout': 'error',\n 'kikiutils/consistent-parameter-layout': 'error',\n 'kikiutils/statement-padding': 'error',\n 'max-classes-per-file': [\n 'error',\n 1,\n ],\n 'no-constant-binary-expression': 'error',\n 'no-promise-executor-return': [\n 'error',\n { allowVoid: true },\n ],\n 'no-useless-assignment': 'error',\n 'perfectionist/sort-array-includes': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-enums': [\n 'error',\n {\n ...basePerfectionistSortOptions,\n sortByValue: 'never',\n },\n ],\n 'perfectionist/sort-heritage-clauses': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-imports': [\n 'error',\n {\n environment,\n groups: [\n 'side-effect',\n 'side-effect-style',\n 'style',\n [\n 'value-builtin',\n 'type-builtin',\n ],\n [\n 'value-external',\n 'type-external',\n ],\n [\n 'value-internal',\n 'type-internal',\n ],\n [\n 'value-parent',\n 'type-parent',\n ],\n [\n 'value-sibling',\n 'type-sibling',\n ],\n [\n 'value-index',\n 'type-index',\n ],\n 'unknown',\n ],\n ignoreCase: false,\n internalPattern: [\n '^#.*',\n '^@/.*',\n '^~/.*',\n ],\n type: 'natural',\n },\n ],\n 'perfectionist/sort-interfaces': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-intersection-types': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-maps': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-modules': [\n 'error',\n {\n ...basePerfectionistSortOptions,\n groups: [\n 'declare-type',\n [\n 'export-type',\n 'type',\n ],\n 'declare-interface',\n [\n 'export-interface',\n 'interface',\n ],\n 'declare-enum',\n [\n 'enum',\n 'export-enum',\n ],\n 'declare-class',\n [\n 'class',\n 'export-class',\n ],\n 'declare-function',\n [\n 'export-function',\n 'function',\n ],\n ],\n },\n ],\n 'perfectionist/sort-object-types': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-objects': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-sets': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-switch-case': [\n 'error',\n {\n ignoreCase: false,\n type: 'natural',\n },\n ],\n 'perfectionist/sort-union-types': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'perfectionist/sort-variable-declarations': [\n 'error',\n basePerfectionistSortOptions,\n ],\n 'preserve-caught-error': 'error',\n 'promise/no-multiple-resolved': 'error',\n 'promise/no-return-in-finally': 'error',\n 'promise/no-return-wrap': 'error',\n 'require-await': 'error',\n 'style/array-bracket-newline': [\n 'error',\n { multiline: true },\n ],\n 'style/array-element-newline': [\n 'error',\n {\n ArrayExpression: {\n consistent: true,\n minItems: 2,\n },\n ArrayPattern: { minItems: 3 },\n },\n ],\n 'style/arrow-parens': [\n 'error',\n 'always',\n ],\n 'style/brace-style': [\n 'error',\n '1tbs',\n { allowSingleLine: false },\n ],\n 'style/function-call-spacing': [\n 'error',\n 'never',\n ],\n 'style/indent': [\n 'error',\n 4,\n ],\n 'style/max-len': [\n 'warn',\n {\n code: 120,\n comments: 120,\n },\n ],\n 'style/member-delimiter-style': [\n 'error',\n {\n multiline: {\n delimiter: 'semi',\n requireLast: true,\n },\n },\n ],\n 'style/no-extra-parens': [\n 'error',\n 'all',\n { nestedBinaryExpressions: false },\n ],\n 'style/no-extra-semi': 'error',\n 'style/object-curly-newline': [\n 'error',\n {\n ExportDeclaration: {\n minProperties: 2,\n multiline: true,\n },\n ImportDeclaration: {\n minProperties: 2,\n multiline: true,\n },\n ObjectExpression: {\n minProperties: 2,\n multiline: true,\n },\n ObjectPattern: {\n minProperties: 3,\n multiline: true,\n },\n },\n ],\n 'style/operator-linebreak': [\n 'error',\n 'before',\n { overrides: { '=': 'after' } },\n ],\n 'style/padding-line-between-statements': [\n 'error',\n {\n blankLine: 'always',\n next: [\n 'class',\n 'enum',\n 'function',\n ],\n prev: '*',\n },\n {\n blankLine: 'always',\n next: '*',\n prev: [\n 'class',\n 'function',\n ],\n },\n ],\n 'style/semi': [\n 'error',\n 'always',\n ],\n };\n}\n"],"mappings":";;;;;AAkBA,MAAM,+BAA+B;CACjC,YAAY;CACZ,MAAM;AACV;AAEA,MAAM,sCAAsC;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACJ,CAAC,CAAC,KAAK,GAAG;AAGV,SAAgB,kBAAkB,cAA8B,QAA+B;CAC3F,OAAO;EAEH,EACI,OAAO;GACH,yBAAyB,CACrB,SACA,EAAE,SAAS,CAAC,OAAO,EAAE,CACzB;GACA,4BAA4B;EAChC,EACJ;EAEA;GACI,OAAO;IACH;IACA;IACA;IACA;GACJ;GACA,SAAS;IACL,WAAW;IACX;GACJ;GACA,OAAO;IACH,GAAG,gBAAgB,WAAW;IAC9B,8BAA8B,CAC1B,SACA,QACJ;GACJ;EACJ;EAEA;GACI,OAAO,CACH,SACA,QACJ;GACA,OAAO;IACH,iBAAiB,CACb,SACA,EAAE,SAAS,eAAe,CAC9B;IACA,sCAAsC,CAClC,SACA,aACJ;IACA,mBAAmB;GACvB;EACJ;EAEA;GACI,GAAG,sBAAsB;GACzB,OAAO,CACH,SACA,QACJ;GACA,SAAS,CAAC,uBAAuB;EACrC;EAEA;GACI,OAAO;GACP,OAAO;IACH,yCAAyC,CACrC,SACA,EAAE,kBAAkB,KAAK,CAC7B;IACA,qBAAqB;IACrB,gCAAgC;GACpC;EACJ;EAEA;GACI,OAAO,CAAC,mBAAmB;GAC3B,OAAO;IACH,2BAA2B,CACvB,SACA;KACI,OAAO;MACH,SAAS;MACT,MAAM;KACV;KAGA,aAAa,OAAO,GAAG,wBAAwB,oCAAoC;IACvF,CACJ;IACA,mBAAmB;KACf;KACA;KACA;MACI,eAAe;MACf,SAAS;KACb;IACJ;GACJ;EACJ;EAEA,EAAE,SAAS,CAAC,YAAY,EAAE;CAC9B;AACJ;AAEA,SAAgB,gBAAgB,cAA8B,QAAe;CACzE,OAAO;EACH,iCAAiC,CAC7B,SACA;GACI,iBAAiB;GACjB,cAAc;EAClB,CACJ;EACA,eAAe;EACf,oBAAoB;EACpB,4BAA4B;EAC5B,4BAA4B;EAC5B,oBAAoB,CAChB,SACA,WACJ;EACA,SAAS,CACL,SACA,YACJ;EACA,sCAAsC;EACtC,yCAAyC;EACzC,yCAAyC;EACzC,+BAA+B;EAC/B,wBAAwB,CACpB,SACA,CACJ;EACA,iCAAiC;EACjC,8BAA8B,CAC1B,SACA,EAAE,WAAW,KAAK,CACtB;EACA,yBAAyB;EACzB,qCAAqC,CACjC,SACA,4BACJ;EACA,4BAA4B,CACxB,SACA;GACI,GAAG;GACH,aAAa;EACjB,CACJ;EACA,uCAAuC,CACnC,SACA,4BACJ;EACA,8BAA8B,CAC1B,SACA;GACI;GACA,QAAQ;IACJ;IACA;IACA;IACA,CACI,iBACA,cACJ;IACA,CACI,kBACA,eACJ;IACA,CACI,kBACA,eACJ;IACA,CACI,gBACA,aACJ;IACA,CACI,iBACA,cACJ;IACA,CACI,eACA,YACJ;IACA;GACJ;GACA,YAAY;GACZ,iBAAiB;IACb;IACA;IACA;GACJ;GACA,MAAM;EACV,CACJ;EACA,iCAAiC,CAC7B,SACA,4BACJ;EACA,yCAAyC,CACrC,SACA,4BACJ;EACA,2BAA2B,CACvB,SACA,4BACJ;EACA,8BAA8B,CAC1B,SACA;GACI,GAAG;GACH,QAAQ;IACJ;IACA,CACI,eACA,MACJ;IACA;IACA,CACI,oBACA,WACJ;IACA;IACA,CACI,QACA,aACJ;IACA;IACA,CACI,SACA,cACJ;IACA;IACA,CACI,mBACA,UACJ;GACJ;EACJ,CACJ;EACA,mCAAmC,CAC/B,SACA,4BACJ;EACA,8BAA8B,CAC1B,SACA,4BACJ;EACA,2BAA2B,CACvB,SACA,4BACJ;EACA,kCAAkC,CAC9B,SACA;GACI,YAAY;GACZ,MAAM;EACV,CACJ;EACA,kCAAkC,CAC9B,SACA,4BACJ;EACA,4CAA4C,CACxC,SACA,4BACJ;EACA,yBAAyB;EACzB,gCAAgC;EAChC,gCAAgC;EAChC,0BAA0B;EAC1B,iBAAiB;EACjB,+BAA+B,CAC3B,SACA,EAAE,WAAW,KAAK,CACtB;EACA,+BAA+B,CAC3B,SACA;GACI,iBAAiB;IACb,YAAY;IACZ,UAAU;GACd;GACA,cAAc,EAAE,UAAU,EAAE;EAChC,CACJ;EACA,sBAAsB,CAClB,SACA,QACJ;EACA,qBAAqB;GACjB;GACA;GACA,EAAE,iBAAiB,MAAM;EAC7B;EACA,+BAA+B,CAC3B,SACA,OACJ;EACA,gBAAgB,CACZ,SACA,CACJ;EACA,iBAAiB,CACb,QACA;GACI,MAAM;GACN,UAAU;EACd,CACJ;EACA,gCAAgC,CAC5B,SACA,EACI,WAAW;GACP,WAAW;GACX,aAAa;EACjB,EACJ,CACJ;EACA,yBAAyB;GACrB;GACA;GACA,EAAE,yBAAyB,MAAM;EACrC;EACA,uBAAuB;EACvB,8BAA8B,CAC1B,SACA;GACI,mBAAmB;IACf,eAAe;IACf,WAAW;GACf;GACA,mBAAmB;IACf,eAAe;IACf,WAAW;GACf;GACA,kBAAkB;IACd,eAAe;IACf,WAAW;GACf;GACA,eAAe;IACX,eAAe;IACf,WAAW;GACf;EACJ,CACJ;EACA,4BAA4B;GACxB;GACA;GACA,EAAE,WAAW,EAAE,KAAK,QAAQ,EAAE;EAClC;EACA,yCAAyC;GACrC;GACA;IACI,WAAW;IACX,MAAM;KACF;KACA;KACA;IACJ;IACA,MAAM;GACV;GACA;IACI,WAAW;IACX,MAAM;IACN,MAAM,CACF,SACA,UACJ;GACJ;EACJ;EACA,cAAc,CACV,SACA,QACJ;CACJ;AACJ"}