@nekoyasuii/config 0.1.5 → 0.1.7

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 (31) hide show
  1. package/dist/{chunk-fqcw0kzp.js → chunk-5vqtdgjy.js} +134 -10
  2. package/dist/{chunk-0xdbbpn5.js → chunk-cpyyjvfv.js} +2 -2
  3. package/dist/{chunk-08m6971b.js → chunk-k5zpegn9.js} +5 -5
  4. package/dist/{chunk-41590bpf.js → chunk-tvk9tq03.js} +2 -2
  5. package/dist/tools/oxfmt/index.js +3 -4
  6. package/dist/tools/oxlint/config/core/index.js +4 -5
  7. package/dist/tools/oxlint/config/index.d.ts +47 -45
  8. package/dist/tools/oxlint/config/index.js +11 -20
  9. package/dist/tools/oxlint/config/js-plugins/index.d.ts +270 -64
  10. package/dist/tools/oxlint/config/js-plugins/index.js +6 -7
  11. package/dist/tools/oxlint/config/react/index.js +3 -4
  12. package/dist/tools/oxlint/config/remix/index.js +0 -2
  13. package/dist/tools/oxlint/config/tanstack/index.js +0 -2
  14. package/dist/tools/oxlint/config/tanstack/js-plugins/index.d.ts +4 -4
  15. package/dist/tools/oxlint/config/tanstack/js-plugins/index.js +0 -2
  16. package/dist/tools/oxlint/config/{anti-slop/plugin.js → vendors/anti-slop.js} +717 -35
  17. package/dist/tools/oxlint/config/{no-comment-slop/plugin.d.ts → vendors/no-comment-slop.d.ts} +34 -0
  18. package/dist/tools/oxlint/config/{no-comment-slop/plugin.js → vendors/no-comment-slop.js} +72 -8
  19. package/dist/tools/oxlint/config/vendors/shadcn.d.ts +41 -0
  20. package/dist/tools/oxlint/config/vendors/shadcn.js +7159 -0
  21. package/dist/tools/oxlint/rules/index.js +7 -9
  22. package/dist/tools/shared/ignores.js +3 -4
  23. package/package.json +3 -13
  24. package/dist/chunk-5wgwscd0.js +0 -4
  25. package/dist/chunk-97s6xvc6.js +0 -32
  26. package/dist/chunk-c8jq73qx.js +0 -38
  27. package/dist/tools/oxlint/config/anti-slop/index.d.ts +0 -42
  28. package/dist/tools/oxlint/config/anti-slop/index.js +0 -7
  29. package/dist/tools/oxlint/config/no-comment-slop/index.d.ts +0 -19
  30. package/dist/tools/oxlint/config/no-comment-slop/index.js +0 -7
  31. /package/dist/tools/oxlint/config/{anti-slop/plugin.d.ts → vendors/anti-slop.d.ts} +0 -0
@@ -1,6 +1,4 @@
1
- import"../../../../chunk-5wgwscd0.js";
2
-
3
- // tools/oxlint/config/anti-slop/plugin.ts
1
+ // tools/oxlint/config/vendors/anti-slop.ts
4
2
  function defineRule(rule) {
5
3
  return rule;
6
4
  }
@@ -167,6 +165,191 @@ function createContextAndVisitor(rule, afterHooksState) {
167
165
  setupAfterHook
168
166
  };
169
167
  }
168
+ function unwrapArrayExpression(node) {
169
+ while (node.type === "ParenthesizedExpression" || node.type === "ChainExpression" || node.type === "TSAsExpression" || node.type === "TSTypeAssertion" || node.type === "TSNonNullExpression" || node.type === "TSSatisfiesExpression") {
170
+ node = node.expression;
171
+ }
172
+ return node;
173
+ }
174
+ function resolveArrayBinding(sourceCode, node) {
175
+ node = unwrapArrayExpression(node);
176
+ if (node.type !== "Identifier")
177
+ return null;
178
+ let scope = sourceCode.getScope(node);
179
+ while (scope !== null) {
180
+ const variable = scope.set.get(node.name);
181
+ if (variable !== undefined)
182
+ return variable;
183
+ scope = scope.upper;
184
+ }
185
+ return null;
186
+ }
187
+ function arrayMethodTarget(node) {
188
+ node = unwrapArrayExpression(node);
189
+ if (node.type !== "MemberExpression")
190
+ return null;
191
+ const property = node.property;
192
+ if (!node.computed && property.type === "Identifier") {
193
+ return { name: property.name, object: node.object };
194
+ }
195
+ if (node.computed && property.type === "Literal" && typeof property.value === "string") {
196
+ return { name: property.value, object: node.object };
197
+ }
198
+ return null;
199
+ }
200
+ function isArrayAnnotation(type) {
201
+ if (type.type === "TSArrayType" || type.type === "TSTupleType")
202
+ return true;
203
+ if (type.type === "TSParenthesizedType")
204
+ return isArrayAnnotation(type.typeAnnotation);
205
+ if (type.type === "TSTypeOperator" && type.operator === "readonly") {
206
+ return isArrayAnnotation(type.typeAnnotation);
207
+ }
208
+ return type.type === "TSTypeReference" && type.typeName.type === "Identifier" && (type.typeName.name === "Array" || type.typeName.name === "ReadonlyArray");
209
+ }
210
+ function isKnownArrayExpression(sourceCode, node, visited = new Set) {
211
+ node = unwrapArrayExpression(node);
212
+ if (node.type === "ArrayExpression")
213
+ return true;
214
+ if (node.type === "CallExpression") {
215
+ const method = arrayMethodTarget(node.callee);
216
+ return method !== null && ["map", "filter", "flatMap", "slice", "concat", "toSorted", "toReversed", "toSpliced"].includes(method.name) && isKnownArrayExpression(sourceCode, method.object, visited);
217
+ }
218
+ if (node.type !== "Identifier")
219
+ return false;
220
+ const variable = resolveArrayBinding(sourceCode, node);
221
+ if (variable === null || visited.has(variable))
222
+ return false;
223
+ visited.add(variable);
224
+ if (variable.references.some((reference) => reference.isWrite() && !reference.init))
225
+ return false;
226
+ for (const identifier of variable.identifiers) {
227
+ const annotation = identifier.typeAnnotation?.typeAnnotation;
228
+ if (annotation !== undefined)
229
+ return isArrayAnnotation(annotation);
230
+ }
231
+ for (const definition of variable.defs) {
232
+ if (definition.type === "Variable" && definition.node.type === "VariableDeclarator" && definition.node.id.type === "Identifier" && definition.node.init !== null && definition.node.parent.type === "VariableDeclaration" && definition.node.parent.kind === "const") {
233
+ return isKnownArrayExpression(sourceCode, definition.node.init, visited);
234
+ }
235
+ }
236
+ return false;
237
+ }
238
+ var noArrayFilterMapRule = defineRule({
239
+ meta: {
240
+ type: "suggestion",
241
+ docs: { description: "Disallow adjacent array filter/map passes in favor of lazy iterator helpers or a single transformation." },
242
+ messages: {
243
+ arrayFilterMap: "Avoid consecutive array `{{first}}` and `{{second}}` passes. Prefer `.values().{{first}}(...).{{second}}(...).toArray()` where iterator helpers are supported, or a single `flatMap`/mutating reducer. Preserve callback ordering, indexes, and filtering semantics."
244
+ }
245
+ },
246
+ createOnce(context) {
247
+ return {
248
+ CallExpression(node) {
249
+ const outer = arrayMethodTarget(node.callee);
250
+ if (outer === null || outer.name !== "map" && outer.name !== "filter")
251
+ return;
252
+ const innerCall = unwrapArrayExpression(outer.object);
253
+ if (innerCall.type !== "CallExpression")
254
+ return;
255
+ const inner = arrayMethodTarget(innerCall.callee);
256
+ if (inner === null || inner.name !== (outer.name === "map" ? "filter" : "map"))
257
+ return;
258
+ if (!isKnownArrayExpression(context.sourceCode, inner.object))
259
+ return;
260
+ context.report({ node, messageId: "arrayFilterMap", data: { first: inner.name, second: outer.name } });
261
+ }
262
+ };
263
+ }
264
+ });
265
+ function enclosingReducer(node) {
266
+ let parent = node.parent;
267
+ while (parent !== null) {
268
+ if (parent.type === "FunctionDeclaration")
269
+ return null;
270
+ if (parent.type === "ArrowFunctionExpression" || parent.type === "FunctionExpression") {
271
+ const callback = parent;
272
+ let owner = callback.parent;
273
+ while (owner !== null && unwrapArrayExpression(owner) === callback)
274
+ owner = owner.parent;
275
+ if (owner?.type !== "CallExpression")
276
+ return null;
277
+ const method = arrayMethodTarget(owner.callee);
278
+ const firstArgument = owner.arguments[0];
279
+ if (method === null || method.name !== "reduce" && method.name !== "reduceRight" || owner.arguments.length > 2 || firstArgument === undefined || unwrapArrayExpression(firstArgument) !== callback)
280
+ return null;
281
+ const firstParameter = callback.params[0];
282
+ const accumulator = firstParameter?.type === "AssignmentPattern" ? firstParameter.left : firstParameter;
283
+ if (accumulator?.type !== "Identifier")
284
+ return null;
285
+ return { callback, accumulator, initialValue: owner.arguments[1] };
286
+ }
287
+ parent = parent.parent;
288
+ }
289
+ return null;
290
+ }
291
+ function referencesAccumulator(sourceCode, node, accumulator, visited = new Set) {
292
+ const variable = resolveArrayBinding(sourceCode, node);
293
+ if (variable === null || visited.has(variable))
294
+ return false;
295
+ if (variable === accumulator)
296
+ return true;
297
+ visited.add(variable);
298
+ if (variable.references.some((reference) => reference.isWrite() && !reference.init))
299
+ return false;
300
+ for (const definition of variable.defs) {
301
+ if (definition.type === "Variable" && definition.node.type === "VariableDeclarator" && definition.node.id.type === "Identifier" && definition.node.init !== null && definition.node.parent.type === "VariableDeclaration" && definition.node.parent.kind === "const") {
302
+ return referencesAccumulator(sourceCode, definition.node.init, accumulator, visited);
303
+ }
304
+ }
305
+ return false;
306
+ }
307
+ function isGlobalCopyOwner(sourceCode, node, name) {
308
+ node = unwrapArrayExpression(node);
309
+ if (node.type !== "Identifier" || node.name !== name)
310
+ return false;
311
+ const variable = resolveArrayBinding(sourceCode, node);
312
+ return variable === null || variable.defs.length === 0;
313
+ }
314
+ var noReduceAccumulatorCopyRule = defineRule({
315
+ meta: {
316
+ type: "problem",
317
+ docs: { description: "Disallow copying growing reducer accumulators with Object.assign, Array.from, or array copy methods." },
318
+ messages: {
319
+ accumulatorCopy: "Do not copy the reducer accumulator on every iteration; growing copies can cause quadratic work. Mutate a fresh, locally owned accumulator and return it, or use an iterator pipeline/flatMap."
320
+ }
321
+ },
322
+ createOnce(context) {
323
+ return {
324
+ CallExpression(node) {
325
+ const method = arrayMethodTarget(node.callee);
326
+ if (method === null)
327
+ return;
328
+ const reducer = enclosingReducer(node);
329
+ if (reducer === null)
330
+ return;
331
+ const accumulator = context.sourceCode.getDeclaredVariables(reducer.callback).find((variable) => variable.identifiers.some((identifier) => identifier.start === reducer.accumulator.start));
332
+ if (accumulator === undefined)
333
+ return;
334
+ const isAccumulator = (expression) => referencesAccumulator(context.sourceCode, expression, accumulator);
335
+ let copiesAccumulator = false;
336
+ if (method.name === "assign" && isGlobalCopyOwner(context.sourceCode, method.object, "Object")) {
337
+ const target = node.arguments[0];
338
+ copiesAccumulator = target !== undefined && unwrapArrayExpression(target).type === "ObjectExpression" && node.arguments.slice(1).some(isAccumulator);
339
+ } else if (method.name === "from" && isGlobalCopyOwner(context.sourceCode, method.object, "Array")) {
340
+ const source = node.arguments[0];
341
+ copiesAccumulator = source !== undefined && isAccumulator(source);
342
+ } else if (["concat", "slice", "toSpliced", "toSorted", "toReversed", "with"].includes(method.name)) {
343
+ const initialValue = reducer.initialValue;
344
+ const arrayAccumulator = initialValue !== undefined && isKnownArrayExpression(context.sourceCode, initialValue);
345
+ copiesAccumulator = arrayAccumulator && isAccumulator(method.object);
346
+ }
347
+ if (copiesAccumulator)
348
+ context.report({ node, messageId: "accumulatorCopy" });
349
+ }
350
+ };
351
+ }
352
+ });
170
353
  function isTypeAssertionExpression(node) {
171
354
  return node.type === "TSAsExpression" || node.type === "TSTypeAssertion";
172
355
  }
@@ -655,9 +838,9 @@ function classifyWideningTarget(type, environment) {
655
838
  if (alias === null)
656
839
  return null;
657
840
  if ((alias.typeParameters?.params.length ?? 0) > 0) {
658
- const substitutions2 = aliasSubstitution(alias, unwrapped, new Map);
659
- const resolved2 = substitutions2 === null ? null : classifyAliasBroadTarget(alias.typeAnnotation, environment, substitutions2, new Set([name]));
660
- return resolved2?.kind === "open dictionary" ? { kind: "generic container" } : null;
841
+ const substitutions = aliasSubstitution(alias, unwrapped, new Map);
842
+ const resolved = substitutions === null ? null : classifyAliasBroadTarget(alias.typeAnnotation, environment, substitutions, new Set([name]));
843
+ return resolved?.kind === "open dictionary" ? { kind: "generic container" } : null;
661
844
  }
662
845
  const substitutions = aliasSubstitution(alias, unwrapped, new Map);
663
846
  if (substitutions === null)
@@ -778,13 +961,6 @@ function functionParameterBindingName(parameter, sourceCode) {
778
961
  const annotationStart = parameter.typeAnnotation?.start;
779
962
  return annotationStart === undefined ? sourceText : sourceText.slice(0, annotationStart - parameter.start).trimEnd();
780
963
  }
781
- function unwrapExpression(expression) {
782
- let current = expression;
783
- while (current.type === "ParenthesizedExpression" || current.type === "TSAsExpression" || current.type === "TSSatisfiesExpression" || current.type === "TSTypeAssertion" || current.type === "TSNonNullExpression") {
784
- current = current.expression;
785
- }
786
- return current;
787
- }
788
964
  function resolveVariable(sourceCode, identifier) {
789
965
  let scope = sourceCode.getScope(identifier);
790
966
  while (scope !== null) {
@@ -795,6 +971,13 @@ function resolveVariable(sourceCode, identifier) {
795
971
  }
796
972
  return null;
797
973
  }
974
+ function unwrapExpression(expression) {
975
+ let current = expression;
976
+ while (current.type === "ParenthesizedExpression" || current.type === "TSAsExpression" || current.type === "TSSatisfiesExpression" || current.type === "TSTypeAssertion" || current.type === "TSNonNullExpression") {
977
+ current = current.expression;
978
+ }
979
+ return current;
980
+ }
798
981
  function variableDeclarator(variable) {
799
982
  if (variable.defs.length !== 1)
800
983
  return null;
@@ -1059,16 +1242,6 @@ var noKnownValueWideningRule = defineRule({
1059
1242
  }
1060
1243
  });
1061
1244
  var moduleMockMethods = new Set(["doMock", "mock", "unstable_mockModule"]);
1062
- function resolveVariable2(sourceCode, identifier) {
1063
- let scope = sourceCode.getScope(identifier);
1064
- while (scope !== null) {
1065
- const variable = scope.set.get(identifier.name);
1066
- if (variable !== undefined)
1067
- return variable;
1068
- scope = scope.upper;
1069
- }
1070
- return null;
1071
- }
1072
1245
  function importedName(node) {
1073
1246
  if (node.type !== "ImportSpecifier")
1074
1247
  return null;
@@ -1080,7 +1253,7 @@ function isTestFrameworkObject(sourceCode, expression) {
1080
1253
  if ((expression.name === "vi" || expression.name === "jest") && sourceCode.isGlobalReference(expression)) {
1081
1254
  return true;
1082
1255
  }
1083
- const variable = resolveVariable2(sourceCode, expression);
1256
+ const variable = resolveVariable(sourceCode, expression);
1084
1257
  if (variable === null || variable.defs.length === 0) {
1085
1258
  return expression.name === "vi" || expression.name === "jest";
1086
1259
  }
@@ -1175,22 +1348,12 @@ var noObjectParametersRule = defineRule({
1175
1348
  };
1176
1349
  }
1177
1350
  });
1178
- function resolveVariable3(sourceCode, identifier) {
1179
- let scope = sourceCode.getScope(identifier);
1180
- while (scope !== null) {
1181
- const variable = scope.set.get(identifier.name);
1182
- if (variable !== undefined)
1183
- return variable;
1184
- scope = scope.upper;
1185
- }
1186
- return null;
1187
- }
1188
1351
  function isGlobalReflect(sourceCode, expression) {
1189
1352
  if (expression.type !== "Identifier" || expression.name !== "Reflect")
1190
1353
  return false;
1191
1354
  if (sourceCode.isGlobalReference(expression))
1192
1355
  return true;
1193
- const variable = resolveVariable3(sourceCode, expression);
1356
+ const variable = resolveVariable(sourceCode, expression);
1194
1357
  return variable === null || variable.defs.length === 0;
1195
1358
  }
1196
1359
  function isGlobalReflectMethodCall(sourceCode, callee, methodName) {
@@ -1828,6 +1991,522 @@ var noWidenThenAssertRule = defineRule({
1828
1991
  };
1829
1992
  }
1830
1993
  });
1994
+ var LINEBREAKS = new Set([`\r
1995
+ `, "\r", `
1996
+ `, "\u2028", "\u2029"]);
1997
+ var isClosingBraceToken = (token) => token.type === "Punctuator" && token.value === "}";
1998
+ var isSemicolonToken = (token) => token.type === "Punctuator" && token.value === ";";
1999
+ var isNotSemicolonToken = (token) => !isSemicolonToken(token);
2000
+ var isTokenOnSameLine = (left, right) => left.loc.end.line === right.loc.start.line;
2001
+ var isFunction = (node) => node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
2002
+ var isSingleLine = (node) => node.loc.start.line === node.loc.end.line;
2003
+ var skipChainExpression = (node) => node.type === "ChainExpression" ? node.expression : node;
2004
+ var isTopLevelExpressionStatement = (node) => node.type === "ExpressionStatement" && (node.parent.type === "Program" || node.parent.type === "BlockStatement" && isFunction(node.parent.parent));
2005
+ function isParenthesized(node, sourceCode) {
2006
+ const before = sourceCode.getTokenBefore(node);
2007
+ const after = sourceCode.getTokenAfter(node);
2008
+ return before?.value === "(" && after?.value === ")";
2009
+ }
2010
+ var CJS_EXPORT = /^(?:module\s*\.\s*)?exports(?:\s*\.|\s*\[|$)/u;
2011
+ var CJS_IMPORT = /^require\(/u;
2012
+ var LT = `[${Array.from(LINEBREAKS).join("")}]`;
2013
+ var PADDING_LINE_SEQUENCE = new RegExp(String.raw`^(\s*?${LT})\s*${LT}(\s*;?)$`, "u");
2014
+ function isSelectorOption(option) {
2015
+ return typeof option === "object" && !Array.isArray(option);
2016
+ }
2017
+ function newKeywordTester(type, keyword) {
2018
+ return {
2019
+ test(node, sourceCode) {
2020
+ const isSameKeyword = sourceCode.getFirstToken(node)?.value === keyword;
2021
+ const isSameType = Array.isArray(type) ? type.includes(node.type) : type === node.type;
2022
+ return isSameKeyword && isSameType;
2023
+ }
2024
+ };
2025
+ }
2026
+ function newNodeTypeTester(type) {
2027
+ return {
2028
+ test: (node) => node.type === type
2029
+ };
2030
+ }
2031
+ function isIIFEStatement(node) {
2032
+ if (node.type === "ExpressionStatement") {
2033
+ let expression = skipChainExpression(node.expression);
2034
+ if (expression.type === "UnaryExpression")
2035
+ expression = skipChainExpression(expression.argument);
2036
+ if (expression.type === "CallExpression") {
2037
+ let node = expression.callee;
2038
+ while (node.type === "SequenceExpression") {
2039
+ const lastExpression = node.expressions.at(-1);
2040
+ if (lastExpression === undefined)
2041
+ throw new Error("Padding rule invariant: sequence expression is empty");
2042
+ node = lastExpression;
2043
+ }
2044
+ return isFunction(node);
2045
+ }
2046
+ }
2047
+ return false;
2048
+ }
2049
+ function isCJSRequire(node) {
2050
+ if (node.type === "VariableDeclaration") {
2051
+ const declaration = node.declarations[0];
2052
+ if (declaration?.init) {
2053
+ let call = declaration?.init;
2054
+ while (call.type === "MemberExpression")
2055
+ call = call.object;
2056
+ if (call.type === "CallExpression" && call.callee.type === "Identifier") {
2057
+ return call.callee.name === "require";
2058
+ }
2059
+ }
2060
+ }
2061
+ return false;
2062
+ }
2063
+ function isBlockLikeStatement(node, sourceCode) {
2064
+ if (node.type === "DoWhileStatement" && node.body.type === "BlockStatement") {
2065
+ return true;
2066
+ }
2067
+ if (isIIFEStatement(node))
2068
+ return true;
2069
+ const lastToken = sourceCode.getLastToken(node, isNotSemicolonToken);
2070
+ const belongingNode = lastToken && isClosingBraceToken(lastToken) ? sourceCode.getNodeByRangeIndex(lastToken.range[0]) : null;
2071
+ return !!belongingNode && (belongingNode.type === "BlockStatement" || belongingNode.type === "SwitchStatement");
2072
+ }
2073
+ function isDirective(node, sourceCode) {
2074
+ return isTopLevelExpressionStatement(node) && node.expression.type === "Literal" && typeof node.expression.value === "string" && !isParenthesized(node.expression, sourceCode);
2075
+ }
2076
+ function isDirectivePrologue(node, sourceCode) {
2077
+ if (isDirective(node, sourceCode) && node.parent && "body" in node.parent && Array.isArray(node.parent.body)) {
2078
+ for (const sibling of node.parent.body) {
2079
+ if (sibling === node)
2080
+ break;
2081
+ if (!isDirective(sibling, sourceCode))
2082
+ return false;
2083
+ }
2084
+ return true;
2085
+ }
2086
+ return false;
2087
+ }
2088
+ function isCJSExport(node) {
2089
+ if (node.type === "ExpressionStatement") {
2090
+ const expression = node.expression;
2091
+ if (expression.type === "AssignmentExpression") {
2092
+ let left = expression.left;
2093
+ if (left.type === "MemberExpression") {
2094
+ while (left.object.type === "MemberExpression")
2095
+ left = left.object;
2096
+ return left.object.type === "Identifier" && (left.object.name === "exports" || left.object.name === "module" && left.property.type === "Identifier" && left.property.name === "exports");
2097
+ }
2098
+ }
2099
+ }
2100
+ return false;
2101
+ }
2102
+ function isExpression(node, sourceCode) {
2103
+ return node.type === "ExpressionStatement" && !isDirectivePrologue(node, sourceCode);
2104
+ }
2105
+ function getActualLastToken(node, sourceCode) {
2106
+ const semiToken = sourceCode.getLastToken(node);
2107
+ const prevToken = sourceCode.getTokenBefore(semiToken);
2108
+ const nextToken = sourceCode.getTokenAfter(semiToken);
2109
+ const isSemicolonLessStyle = prevToken && nextToken && prevToken.range[0] >= node.range[0] && isSemicolonToken(semiToken) && !isTokenOnSameLine(prevToken, semiToken) && isTokenOnSameLine(semiToken, nextToken);
2110
+ return isSemicolonLessStyle ? prevToken : semiToken;
2111
+ }
2112
+ function replacerToRemovePaddingLines(_, trailingSpaces, indentSpaces) {
2113
+ return trailingSpaces + indentSpaces;
2114
+ }
2115
+ function getReportLoc(node, sourceCode) {
2116
+ if (isSingleLine(node))
2117
+ return node.loc;
2118
+ const line = node.loc.start.line;
2119
+ const sourceLine = sourceCode.lines[line - 1];
2120
+ if (sourceLine === undefined)
2121
+ throw new Error("Padding rule invariant: statement source line is missing");
2122
+ return {
2123
+ start: node.loc.start,
2124
+ end: {
2125
+ line,
2126
+ column: sourceLine.length
2127
+ }
2128
+ };
2129
+ }
2130
+ function verifyForAny() {}
2131
+ function verifyForNever(context, _, nextNode, paddingLines) {
2132
+ if (paddingLines.length === 0)
2133
+ return;
2134
+ context.report({
2135
+ node: nextNode,
2136
+ messageId: "unexpectedBlankLine",
2137
+ loc: getReportLoc(nextNode, context.sourceCode),
2138
+ fix(fixer) {
2139
+ if (paddingLines.length >= 2)
2140
+ return null;
2141
+ const paddingPair = paddingLines[0];
2142
+ if (paddingPair === undefined)
2143
+ throw new Error("Padding rule invariant: reported padding pair is missing");
2144
+ const [prevToken, nextToken] = paddingPair;
2145
+ const start = prevToken.range[1];
2146
+ const end = nextToken.range[0];
2147
+ const text = context.sourceCode.text.slice(start, end).replace(PADDING_LINE_SEQUENCE, replacerToRemovePaddingLines);
2148
+ return fixer.replaceTextRange([start, end], text);
2149
+ }
2150
+ });
2151
+ }
2152
+ function verifyForAlways(context, prevNode, nextNode, paddingLines) {
2153
+ if (paddingLines.length > 0)
2154
+ return;
2155
+ context.report({
2156
+ node: nextNode,
2157
+ messageId: "expectedBlankLine",
2158
+ loc: getReportLoc(nextNode, context.sourceCode),
2159
+ fix(fixer) {
2160
+ const sourceCode = context.sourceCode;
2161
+ let prevToken = getActualLastToken(prevNode, sourceCode);
2162
+ const nextToken = sourceCode.getFirstTokenBetween(prevToken, nextNode, {
2163
+ includeComments: true,
2164
+ filter(token) {
2165
+ if (isTokenOnSameLine(prevToken, token)) {
2166
+ prevToken = token;
2167
+ return false;
2168
+ }
2169
+ return true;
2170
+ }
2171
+ }) || nextNode;
2172
+ const insertText = isTokenOnSameLine(prevToken, nextToken) ? `
2173
+
2174
+ ` : `
2175
+ `;
2176
+ return fixer.insertTextAfter(prevToken, insertText);
2177
+ }
2178
+ });
2179
+ }
2180
+ var PaddingTypes = {
2181
+ any: { verify: verifyForAny },
2182
+ never: { verify: verifyForNever },
2183
+ always: { verify: verifyForAlways }
2184
+ };
2185
+ var MaybeMultilineStatementType = {
2186
+ "block-like": { test: isBlockLikeStatement },
2187
+ expression: { test: isExpression },
2188
+ return: newKeywordTester("ReturnStatement", "return"),
2189
+ export: newKeywordTester([
2190
+ "ExportAllDeclaration",
2191
+ "ExportDefaultDeclaration",
2192
+ "ExportNamedDeclaration"
2193
+ ], "export"),
2194
+ var: newKeywordTester("VariableDeclaration", "var"),
2195
+ let: newKeywordTester("VariableDeclaration", "let"),
2196
+ const: newKeywordTester("VariableDeclaration", "const"),
2197
+ using: {
2198
+ test: (node) => node.type === "VariableDeclaration" && (node.kind === "using" || node.kind === "await using")
2199
+ },
2200
+ type: newKeywordTester("TSTypeAliasDeclaration", "type")
2201
+ };
2202
+ var StatementTypes = {
2203
+ "*": { test: () => true },
2204
+ exports: { test: isCJSExport },
2205
+ require: { test: isCJSRequire },
2206
+ directive: { test: isDirectivePrologue },
2207
+ iife: { test: isIIFEStatement },
2208
+ block: newNodeTypeTester("BlockStatement"),
2209
+ empty: newNodeTypeTester("EmptyStatement"),
2210
+ function: newNodeTypeTester("FunctionDeclaration"),
2211
+ "ts-method": newNodeTypeTester("TSMethodSignature"),
2212
+ break: newKeywordTester("BreakStatement", "break"),
2213
+ case: newKeywordTester("SwitchCase", "case"),
2214
+ class: newKeywordTester("ClassDeclaration", "class"),
2215
+ continue: newKeywordTester("ContinueStatement", "continue"),
2216
+ debugger: newKeywordTester("DebuggerStatement", "debugger"),
2217
+ default: newKeywordTester(["SwitchCase", "ExportDefaultDeclaration"], "default"),
2218
+ do: newKeywordTester("DoWhileStatement", "do"),
2219
+ for: newKeywordTester([
2220
+ "ForStatement",
2221
+ "ForInStatement",
2222
+ "ForOfStatement"
2223
+ ], "for"),
2224
+ if: newKeywordTester("IfStatement", "if"),
2225
+ import: newKeywordTester("ImportDeclaration", "import"),
2226
+ switch: newKeywordTester("SwitchStatement", "switch"),
2227
+ throw: newKeywordTester("ThrowStatement", "throw"),
2228
+ try: newKeywordTester("TryStatement", "try"),
2229
+ while: newKeywordTester(["WhileStatement", "DoWhileStatement"], "while"),
2230
+ with: newKeywordTester("WithStatement", "with"),
2231
+ "cjs-export": {
2232
+ test: (node, sourceCode) => node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" && CJS_EXPORT.test(sourceCode.getText(node.expression.left))
2233
+ },
2234
+ "cjs-import": {
2235
+ test: (node, sourceCode) => node.type === "VariableDeclaration" && node.declarations.length > 0 && node.declarations[0]?.init != null && CJS_IMPORT.test(sourceCode.getText(node.declarations[0].init))
2236
+ },
2237
+ enum: newKeywordTester("TSEnumDeclaration", "enum"),
2238
+ interface: newKeywordTester("TSInterfaceDeclaration", "interface"),
2239
+ "function-overload": newNodeTypeTester("TSDeclareFunction"),
2240
+ ...Object.fromEntries(Object.entries(MaybeMultilineStatementType).flatMap(([key, value]) => [
2241
+ [key, value],
2242
+ [
2243
+ `singleline-${key}`,
2244
+ {
2245
+ ...value,
2246
+ test: (node, sourceCode) => value.test(node, sourceCode) && isSingleLine(node)
2247
+ }
2248
+ ],
2249
+ [
2250
+ `multiline-${key}`,
2251
+ {
2252
+ ...value,
2253
+ test: (node, sourceCode) => value.test(node, sourceCode) && !isSingleLine(node)
2254
+ }
2255
+ ]
2256
+ ]))
2257
+ };
2258
+ function createPaddingLineRule(options) {
2259
+ return {
2260
+ meta: {
2261
+ type: "layout",
2262
+ docs: {
2263
+ description: "Require or disallow padding lines between statements"
2264
+ },
2265
+ fixable: "whitespace",
2266
+ hasSuggestions: false,
2267
+ schema: {
2268
+ $defs: {
2269
+ paddingType: {
2270
+ type: "string",
2271
+ enum: Object.keys(PaddingTypes)
2272
+ },
2273
+ statementType: {
2274
+ type: "string",
2275
+ enum: Object.keys(StatementTypes)
2276
+ },
2277
+ selectorOption: {
2278
+ type: "object",
2279
+ properties: {
2280
+ selector: {
2281
+ type: "string"
2282
+ },
2283
+ lineMode: {
2284
+ type: "string",
2285
+ enum: ["any", "singleline", "multiline"]
2286
+ }
2287
+ },
2288
+ required: ["selector"],
2289
+ additionalProperties: false
2290
+ },
2291
+ statementMatcher: {
2292
+ anyOf: [
2293
+ { $ref: "#/$defs/statementType" },
2294
+ { $ref: "#/$defs/selectorOption" }
2295
+ ]
2296
+ },
2297
+ statementOption: {
2298
+ anyOf: [
2299
+ { $ref: "#/$defs/statementMatcher" },
2300
+ {
2301
+ type: "array",
2302
+ items: { $ref: "#/$defs/statementMatcher" },
2303
+ minItems: 1,
2304
+ uniqueItems: true,
2305
+ additionalItems: false
2306
+ }
2307
+ ]
2308
+ }
2309
+ },
2310
+ type: "array",
2311
+ additionalItems: false,
2312
+ items: {
2313
+ type: "object",
2314
+ properties: {
2315
+ blankLine: { $ref: "#/$defs/paddingType" },
2316
+ prev: { $ref: "#/$defs/statementOption" },
2317
+ next: { $ref: "#/$defs/statementOption" }
2318
+ },
2319
+ additionalProperties: false,
2320
+ required: ["blankLine", "prev", "next"]
2321
+ }
2322
+ },
2323
+ messages: {
2324
+ unexpectedBlankLine: "Unexpected blank line before this statement.",
2325
+ expectedBlankLine: "Expected blank line before this statement."
2326
+ }
2327
+ },
2328
+ create(context) {
2329
+ const sourceCode = context.sourceCode;
2330
+ const selectorMatchedNodes = new Map;
2331
+ const pendingPairs = [];
2332
+ function collectSelectorOption(option) {
2333
+ if (Array.isArray(option)) {
2334
+ for (const item of option)
2335
+ collectSelectorOption(item);
2336
+ return;
2337
+ }
2338
+ if (!isSelectorOption(option))
2339
+ return;
2340
+ selectorMatchedNodes.set(option.selector, new Set);
2341
+ }
2342
+ for (const configure of options) {
2343
+ collectSelectorOption(configure.prev);
2344
+ collectSelectorOption(configure.next);
2345
+ }
2346
+ let scopeInfo = null;
2347
+ function enterScope() {
2348
+ scopeInfo = {
2349
+ upper: scopeInfo,
2350
+ prevNode: null
2351
+ };
2352
+ }
2353
+ function exitScope() {
2354
+ if (scopeInfo)
2355
+ scopeInfo = scopeInfo.upper;
2356
+ }
2357
+ function match(node, type) {
2358
+ let innerStatementNode = node;
2359
+ while (innerStatementNode.type === "LabeledStatement")
2360
+ innerStatementNode = innerStatementNode.body;
2361
+ if (Array.isArray(type))
2362
+ return type.some(match.bind(null, innerStatementNode));
2363
+ if (isSelectorOption(type)) {
2364
+ const matchedNodes = selectorMatchedNodes.get(type.selector);
2365
+ if (!matchedNodes?.has(innerStatementNode))
2366
+ return false;
2367
+ const lineMode = type.lineMode;
2368
+ if (lineMode === "singleline")
2369
+ return isSingleLine(innerStatementNode);
2370
+ else if (lineMode === "multiline")
2371
+ return !isSingleLine(innerStatementNode);
2372
+ return true;
2373
+ } else {
2374
+ const statementType = StatementTypes[type];
2375
+ if (statementType === undefined)
2376
+ throw new Error(`Padding rule invariant: unsupported statement type ${type}`);
2377
+ return statementType.test(innerStatementNode, sourceCode);
2378
+ }
2379
+ }
2380
+ function getPaddingType(prevNode, nextNode) {
2381
+ for (let i = options.length - 1;i >= 0; --i) {
2382
+ const configure = options[i];
2383
+ if (configure === undefined)
2384
+ throw new Error("Padding rule invariant: configuration entry is missing");
2385
+ if (match(prevNode, configure.prev) && match(nextNode, configure.next)) {
2386
+ return PaddingTypes[configure.blankLine];
2387
+ }
2388
+ }
2389
+ return PaddingTypes.any;
2390
+ }
2391
+ function getPaddingLineSequences(prevNode, nextNode) {
2392
+ const pairs = [];
2393
+ let prevToken = getActualLastToken(prevNode, sourceCode);
2394
+ if (nextNode.loc.start.line - prevToken.loc.end.line >= 2) {
2395
+ do {
2396
+ const token = sourceCode.getTokenAfter(prevToken, {
2397
+ includeComments: true
2398
+ });
2399
+ if (token.loc.start.line - prevToken.loc.end.line >= 2)
2400
+ pairs.push([prevToken, token]);
2401
+ prevToken = token;
2402
+ } while (prevToken.range[0] < nextNode.range[0]);
2403
+ }
2404
+ return pairs;
2405
+ }
2406
+ function verify(node) {
2407
+ if (!node.parent || ![
2408
+ "BlockStatement",
2409
+ "Program",
2410
+ "StaticBlock",
2411
+ "SwitchCase",
2412
+ "SwitchStatement",
2413
+ "TSInterfaceBody",
2414
+ "TSModuleBlock",
2415
+ "TSTypeLiteral"
2416
+ ].includes(node.parent.type)) {
2417
+ return;
2418
+ }
2419
+ const prevNode = scopeInfo.prevNode;
2420
+ if (prevNode)
2421
+ pendingPairs.push({ prevNode, nextNode: node });
2422
+ scopeInfo.prevNode = node;
2423
+ }
2424
+ function verifyPendingPairs() {
2425
+ for (const { prevNode, nextNode } of pendingPairs) {
2426
+ const type = getPaddingType(prevNode, nextNode);
2427
+ const paddingLines = getPaddingLineSequences(prevNode, nextNode);
2428
+ type.verify(context, prevNode, nextNode, paddingLines);
2429
+ }
2430
+ }
2431
+ function verifyThenEnterScope(node) {
2432
+ verify(node);
2433
+ enterScope();
2434
+ }
2435
+ const selectorMatchListeners = Object.fromEntries(Array.from(selectorMatchedNodes.keys(), (selector) => [
2436
+ selector,
2437
+ (node) => {
2438
+ selectorMatchedNodes.get(selector)?.add(node);
2439
+ }
2440
+ ]));
2441
+ return {
2442
+ Program: enterScope,
2443
+ "Program:exit": () => {
2444
+ verifyPendingPairs();
2445
+ exitScope();
2446
+ },
2447
+ BlockStatement: enterScope,
2448
+ "BlockStatement:exit": exitScope,
2449
+ SwitchStatement: enterScope,
2450
+ "SwitchStatement:exit": exitScope,
2451
+ SwitchCase: verifyThenEnterScope,
2452
+ "SwitchCase:exit": exitScope,
2453
+ StaticBlock: enterScope,
2454
+ "StaticBlock:exit": exitScope,
2455
+ TSInterfaceBody: enterScope,
2456
+ "TSInterfaceBody:exit": exitScope,
2457
+ TSModuleBlock: enterScope,
2458
+ "TSModuleBlock:exit": exitScope,
2459
+ TSTypeLiteral: enterScope,
2460
+ "TSTypeLiteral:exit": exitScope,
2461
+ TSDeclareFunction: verifyThenEnterScope,
2462
+ "TSDeclareFunction:exit": exitScope,
2463
+ TSMethodSignature: verifyThenEnterScope,
2464
+ "TSMethodSignature:exit": exitScope,
2465
+ ":statement": verify,
2466
+ ...selectorMatchListeners
2467
+ };
2468
+ }
2469
+ };
2470
+ }
2471
+ var paddingRule = createPaddingLineRule([
2472
+ { blankLine: "always", prev: "import", next: "*" },
2473
+ { blankLine: "always", prev: "*", next: { selector: "Program > :not(ImportDeclaration)" } },
2474
+ { blankLine: "always", prev: { selector: "Program > :not(ImportDeclaration)" }, next: "*" },
2475
+ { blankLine: "always", prev: "*", next: ["function", "class", "interface", "type"] },
2476
+ { blankLine: "always", prev: ["function", "class", "interface", "type"], next: "*" },
2477
+ {
2478
+ blankLine: "always",
2479
+ prev: "*",
2480
+ next: ["multiline-const", "multiline-let", "multiline-var", "multiline-using"]
2481
+ },
2482
+ {
2483
+ blankLine: "always",
2484
+ prev: ["multiline-const", "multiline-let", "multiline-var", "multiline-using"],
2485
+ next: "*"
2486
+ },
2487
+ { blankLine: "always", prev: "*", next: ["return", "if", "switch", "try", "for", "while", "do"] },
2488
+ { blankLine: "always", prev: "block-like", next: "*" },
2489
+ { blankLine: "any", prev: "import", next: "import" },
2490
+ {
2491
+ blankLine: "any",
2492
+ prev: {
2493
+ selector: ':matches(TSDeclareFunction, ExportNamedDeclaration[declaration.type="TSDeclareFunction"])'
2494
+ },
2495
+ next: {
2496
+ selector: ':matches(TSDeclareFunction, FunctionDeclaration, ExportNamedDeclaration[declaration.type="TSDeclareFunction"], ExportNamedDeclaration[declaration.type="FunctionDeclaration"])'
2497
+ }
2498
+ }
2499
+ ]);
2500
+ var requireReadableSpacingRule = {
2501
+ ...paddingRule,
2502
+ meta: {
2503
+ ...paddingRule.meta,
2504
+ docs: {
2505
+ description: "Require readable spacing between declarations and logical statement groups."
2506
+ },
2507
+ schema: []
2508
+ }
2509
+ };
1831
2510
  var DEFAULT_SAFETY_MARKERS = ["SAFETY"];
1832
2511
  var commentOwnerKinds = new Set([
1833
2512
  "ExpressionStatement",
@@ -1921,6 +2600,8 @@ var requireSafetyCommentForTypeAssertionRule = defineRule({
1921
2600
  var antiSlopPlugin = eslintCompatPlugin({
1922
2601
  meta: { name: "anti-slop" },
1923
2602
  rules: {
2603
+ "no-array-filter-map": noArrayFilterMapRule,
2604
+ "no-reduce-accumulator-copy": noReduceAccumulatorCopyRule,
1924
2605
  "no-chained-type-assertions": noChainedTypeAssertionsRule,
1925
2606
  "no-conditional-empty-object-spread": noConditionalEmptyObjectSpreadRule,
1926
2607
  "no-known-value-widening": noKnownValueWideningRule,
@@ -1935,6 +2616,7 @@ var antiSlopPlugin = eslintCompatPlugin({
1935
2616
  "no-unknown-returns": noUnknownReturnsRule,
1936
2617
  "no-unknown-type-aliases": noUnknownTypeAliasesRule,
1937
2618
  "no-widen-then-assert": noWidenThenAssertRule,
2619
+ "require-readable-spacing": requireReadableSpacingRule,
1938
2620
  "require-safety-comment-for-type-assertion": requireSafetyCommentForTypeAssertionRule
1939
2621
  }
1940
2622
  });