pasika 0.10.47 → 0.10.49
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.
- package/dist/eslint/pasika/index.d.ts +1 -0
- package/dist/eslint/pasika/index.js +189 -51
- package/package.json +1 -1
|
@@ -192,6 +192,7 @@ declare const pasikaPlugin: {
|
|
|
192
192
|
"glossary-term-linking": _eslint_markdown.MarkdownRuleDefinition;
|
|
193
193
|
"guide-mentions-documents": _eslint_markdown.MarkdownRuleDefinition;
|
|
194
194
|
"guide-section-shape": _eslint_markdown.MarkdownRuleDefinition;
|
|
195
|
+
"file-length": eslint.Rule.RuleModule;
|
|
195
196
|
"filename-case": eslint.Rule.RuleModule;
|
|
196
197
|
"import-boundaries": eslint.Rule.RuleModule;
|
|
197
198
|
"import-spacing": eslint.Rule.RuleModule;
|
|
@@ -2925,6 +2925,31 @@ var enforceCvaVariantPropsRule = {
|
|
|
2925
2925
|
}
|
|
2926
2926
|
};
|
|
2927
2927
|
|
|
2928
|
+
// eslint/rules/file-length.ts
|
|
2929
|
+
var MAX_SOURCE_FILE_LINES = 300;
|
|
2930
|
+
var fileLengthRule = {
|
|
2931
|
+
meta: {
|
|
2932
|
+
schema: [],
|
|
2933
|
+
type: "problem",
|
|
2934
|
+
docs: {
|
|
2935
|
+
description: "Require application source files to stay at or below 300 lines."
|
|
2936
|
+
}
|
|
2937
|
+
},
|
|
2938
|
+
create(context) {
|
|
2939
|
+
return {
|
|
2940
|
+
Program(node) {
|
|
2941
|
+
const lineCount = context.sourceCode.lines.length;
|
|
2942
|
+
if (lineCount <= MAX_SOURCE_FILE_LINES) return;
|
|
2943
|
+
context.report({
|
|
2944
|
+
node,
|
|
2945
|
+
loc: { line: 1, column: 0 },
|
|
2946
|
+
message: `Source file has ${String(lineCount)} lines; split it so no source file exceeds ${String(MAX_SOURCE_FILE_LINES)} lines. See docs/next-codebase-guide/rules/application-structure-rule.md`
|
|
2947
|
+
});
|
|
2948
|
+
}
|
|
2949
|
+
};
|
|
2950
|
+
}
|
|
2951
|
+
};
|
|
2952
|
+
|
|
2928
2953
|
// eslint/rules/filename-case.ts
|
|
2929
2954
|
import path24 from "path";
|
|
2930
2955
|
var NEXT_ROUTING_FILES2 = /* @__PURE__ */ new Set([
|
|
@@ -3087,6 +3112,10 @@ function sideEffectCategoryOf(node) {
|
|
|
3087
3112
|
}
|
|
3088
3113
|
return void 0;
|
|
3089
3114
|
}
|
|
3115
|
+
function score(hookNames, sideEffectCategories) {
|
|
3116
|
+
const hookDiversityPoint = hookNames.size >= 2 ? 1 : 0;
|
|
3117
|
+
return hookDiversityPoint + sideEffectCategories.size;
|
|
3118
|
+
}
|
|
3090
3119
|
function computeExtractionScore(body, sourceText) {
|
|
3091
3120
|
const start = body.range?.[0] ?? 0;
|
|
3092
3121
|
const end = body.range?.[1] ?? sourceText.length;
|
|
@@ -3107,15 +3136,44 @@ function computeExtractionScore(body, sourceText) {
|
|
|
3107
3136
|
ts3.forEachChild(node, visit);
|
|
3108
3137
|
};
|
|
3109
3138
|
visit(sourceFile);
|
|
3110
|
-
|
|
3111
|
-
|
|
3139
|
+
return score(hookNames, sideEffectCategories);
|
|
3140
|
+
}
|
|
3141
|
+
function componentBody(component) {
|
|
3142
|
+
const { declaration } = component;
|
|
3143
|
+
if (ts3.isFunctionDeclaration(declaration)) return declaration.body;
|
|
3144
|
+
const initializer = declaration.initializer;
|
|
3145
|
+
if (!initializer || !ts3.isArrowFunction(initializer) && !ts3.isFunctionExpression(initializer)) return void 0;
|
|
3146
|
+
return ts3.isBlock(initializer.body) ? initializer.body : void 0;
|
|
3147
|
+
}
|
|
3148
|
+
function computeInlineComponentExtractionScore(component) {
|
|
3149
|
+
const body = componentBody(component);
|
|
3150
|
+
if (!body) return 0;
|
|
3151
|
+
const hookNames = /* @__PURE__ */ new Set();
|
|
3152
|
+
const sideEffectCategories = /* @__PURE__ */ new Set();
|
|
3153
|
+
const collectSideEffects = (node) => {
|
|
3154
|
+
const sideEffect = sideEffectCategoryOf(node);
|
|
3155
|
+
if (sideEffect) sideEffectCategories.add(sideEffect);
|
|
3156
|
+
ts3.forEachChild(node, collectSideEffects);
|
|
3157
|
+
};
|
|
3158
|
+
const visit = (node) => {
|
|
3159
|
+
if (node !== body && ts3.isFunctionLike(node)) return;
|
|
3160
|
+
const hookName = calledHookName(node);
|
|
3161
|
+
if (hookName && ts3.isCallExpression(node)) {
|
|
3162
|
+
hookNames.add(hookName);
|
|
3163
|
+
for (const argument of node.arguments) collectSideEffects(argument);
|
|
3164
|
+
return;
|
|
3165
|
+
}
|
|
3166
|
+
ts3.forEachChild(node, visit);
|
|
3167
|
+
};
|
|
3168
|
+
visit(body);
|
|
3169
|
+
return score(hookNames, sideEffectCategories);
|
|
3112
3170
|
}
|
|
3113
3171
|
var hookComplexityRule = {
|
|
3114
3172
|
meta: {
|
|
3115
3173
|
schema: [],
|
|
3116
3174
|
type: "problem",
|
|
3117
3175
|
docs: {
|
|
3118
|
-
description: "Require extraction of complex single-consumer
|
|
3176
|
+
description: "Require extraction of complex inline or single-consumer hook logic and inline of simple hooks."
|
|
3119
3177
|
}
|
|
3120
3178
|
},
|
|
3121
3179
|
create(context) {
|
|
@@ -3132,18 +3190,32 @@ var hookComplexityRule = {
|
|
|
3132
3190
|
if (!name || !isHookName2(name) || !body) return;
|
|
3133
3191
|
hooks.push({ node, name, body, exported });
|
|
3134
3192
|
}
|
|
3193
|
+
function reportInlineComponentHooks() {
|
|
3194
|
+
if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return;
|
|
3195
|
+
const components = parseComponentInfo(sourceText, filename, { includeNonExported: true });
|
|
3196
|
+
for (const component of components) {
|
|
3197
|
+
const extractionScore = computeInlineComponentExtractionScore(component);
|
|
3198
|
+
if (extractionScore < 2) continue;
|
|
3199
|
+
const sourceFile = component.declaration.getSourceFile();
|
|
3200
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(component.declaration.getStart(sourceFile));
|
|
3201
|
+
context.report({
|
|
3202
|
+
loc: { line: line + 1, column: 0 },
|
|
3203
|
+
message: `Component "${component.name}" has inline hook logic with an extraction score of ${String(extractionScore)}; extract that logic to a custom hook in a hooks/ folder. See docs/next-codebase-guide/rules/hook-extraction-rule.md`
|
|
3204
|
+
});
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3135
3207
|
function reportHooks() {
|
|
3136
3208
|
const parentFolder = segments.length >= 2 ? segments[segments.length - 2] : void 0;
|
|
3137
3209
|
const inSupportFolder = parentFolder === "hooks";
|
|
3138
3210
|
for (const { node, name, body, exported } of hooks) {
|
|
3139
|
-
const
|
|
3211
|
+
const extractionScore = computeExtractionScore(body, sourceText);
|
|
3140
3212
|
const hasLocalConsumer = localHookCalls.has(name);
|
|
3141
3213
|
const externalConsumerCount = exported ? index?.symbolConsumers.get(symbolKey(filename, name))?.size ?? 0 : 0;
|
|
3142
|
-
if (
|
|
3214
|
+
if (extractionScore >= 2) {
|
|
3143
3215
|
if (!inSupportFolder && (exported || hasLocalConsumer)) {
|
|
3144
3216
|
context.report({
|
|
3145
3217
|
node,
|
|
3146
|
-
message: `Hook "${name}" has an extraction score of ${String(
|
|
3218
|
+
message: `Hook "${name}" has an extraction score of ${String(extractionScore)} and must be extracted to a hooks/ folder. See docs/next-codebase-guide/rules/hook-extraction-rule.md`
|
|
3147
3219
|
});
|
|
3148
3220
|
}
|
|
3149
3221
|
continue;
|
|
@@ -3189,6 +3261,7 @@ var hookComplexityRule = {
|
|
|
3189
3261
|
},
|
|
3190
3262
|
"Program:exit"() {
|
|
3191
3263
|
reportHooks();
|
|
3264
|
+
reportInlineComponentHooks();
|
|
3192
3265
|
}
|
|
3193
3266
|
};
|
|
3194
3267
|
}
|
|
@@ -3363,14 +3436,6 @@ var httpErrorUsageRule = {
|
|
|
3363
3436
|
// eslint/rules/husky/husky-hook.ts
|
|
3364
3437
|
import { existsSync as existsSync4, readFileSync as readFileSync6 } from "fs";
|
|
3365
3438
|
import path28 from "path";
|
|
3366
|
-
var VITEST_CONFIG_NAMES = [
|
|
3367
|
-
"vitest.config.ts",
|
|
3368
|
-
"vitest.config.mts",
|
|
3369
|
-
"vitest.config.cts",
|
|
3370
|
-
"vitest.config.js",
|
|
3371
|
-
"vitest.config.mjs",
|
|
3372
|
-
"vitest.config.cjs"
|
|
3373
|
-
];
|
|
3374
3439
|
function memberName(member) {
|
|
3375
3440
|
return member.name.type === "String" ? member.name.value : member.name.name;
|
|
3376
3441
|
}
|
|
@@ -3379,7 +3444,7 @@ var huskyHookRule = {
|
|
|
3379
3444
|
schema: [],
|
|
3380
3445
|
type: "problem",
|
|
3381
3446
|
docs: {
|
|
3382
|
-
description: "Require a pre-commit hook that runs lint-staged, typecheck, coverage
|
|
3447
|
+
description: "Require a pre-commit hook that runs lint-staged, typecheck, coverage, suppression pruning, and the libyear drift check."
|
|
3383
3448
|
}
|
|
3384
3449
|
},
|
|
3385
3450
|
create(context) {
|
|
@@ -3412,17 +3477,6 @@ var huskyHookRule = {
|
|
|
3412
3477
|
}
|
|
3413
3478
|
requireNamedScript("typecheck");
|
|
3414
3479
|
requireNamedScript("test:unit:coverage");
|
|
3415
|
-
const vitestConfigName = VITEST_CONFIG_NAMES.find((name) => existsSync4(path28.join(context.cwd, name)));
|
|
3416
|
-
if (vitestConfigName !== void 0) {
|
|
3417
|
-
const coverageIndex = content.indexOf("npm run test:unit:coverage");
|
|
3418
|
-
const localAddIndex = content.indexOf(`git add ${vitestConfigName}`);
|
|
3419
|
-
if (localAddIndex <= coverageIndex) {
|
|
3420
|
-
context.report({
|
|
3421
|
-
node,
|
|
3422
|
-
message: `.husky/pre-commit must stage an auto-updated ${vitestConfigName} after coverage.`
|
|
3423
|
-
});
|
|
3424
|
-
}
|
|
3425
|
-
}
|
|
3426
3480
|
if (!content.includes("libyear --limit-major-individual=1")) {
|
|
3427
3481
|
context.report({ node, message: ".husky/pre-commit must run npx libyear --limit-major-individual=1." });
|
|
3428
3482
|
}
|
|
@@ -4705,19 +4759,15 @@ var DOC3 = "See docs/next-codebase-guide/rules/redundant-aliases-rule.md";
|
|
|
4705
4759
|
var VALUE_SENTINELS = /* @__PURE__ */ new Set(["undefined", "NaN", "Infinity"]);
|
|
4706
4760
|
var HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
4707
4761
|
function entityNameText(name) {
|
|
4708
|
-
if (!name) return void 0;
|
|
4709
4762
|
if (name.type === "Identifier") return name.name;
|
|
4710
4763
|
if (name.type === "TSQualifiedName") {
|
|
4711
4764
|
const left = entityNameText(name.left);
|
|
4712
|
-
const right = name.right
|
|
4765
|
+
const right = name.right.name;
|
|
4713
4766
|
return left && right ? `${left}.${right}` : void 0;
|
|
4714
4767
|
}
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
return object && property ? `${object}.${property}` : void 0;
|
|
4719
|
-
}
|
|
4720
|
-
return void 0;
|
|
4768
|
+
const object = entityNameText(name.object);
|
|
4769
|
+
const property = name.property.name;
|
|
4770
|
+
return object && property ? `${object}.${property}` : void 0;
|
|
4721
4771
|
}
|
|
4722
4772
|
function aliasMessage(alias, source) {
|
|
4723
4773
|
const aliasName = alias ?? "This declaration";
|
|
@@ -4757,16 +4807,31 @@ var noRedundantAliasRule = {
|
|
|
4757
4807
|
message: aliasMessage(node.id?.name, source)
|
|
4758
4808
|
});
|
|
4759
4809
|
},
|
|
4810
|
+
ExportNamedDeclaration(node) {
|
|
4811
|
+
for (const specifier of node.specifiers) {
|
|
4812
|
+
if (specifier.local.type !== "Identifier" || specifier.exported.type !== "Identifier") continue;
|
|
4813
|
+
const source = specifier.local.name;
|
|
4814
|
+
const alias = specifier.exported.name;
|
|
4815
|
+
if (source === alias) continue;
|
|
4816
|
+
const frameworkRouteAlias = path37.basename(context.filename) === "route.ts" && HTTP_METHODS.has(alias);
|
|
4817
|
+
if (frameworkRouteAlias) continue;
|
|
4818
|
+
context.report({
|
|
4819
|
+
node: specifier,
|
|
4820
|
+
message: aliasMessage(alias, source)
|
|
4821
|
+
});
|
|
4822
|
+
}
|
|
4823
|
+
},
|
|
4760
4824
|
TSInterfaceDeclaration(node) {
|
|
4761
4825
|
if (node.typeParameters || node.body?.body?.length !== 0 || node.extends?.length !== 1) return;
|
|
4762
|
-
const heritage
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4826
|
+
for (const heritage of node.extends) {
|
|
4827
|
+
if (heritage.typeArguments) return;
|
|
4828
|
+
const source = entityNameText(heritage.expression);
|
|
4829
|
+
if (!source) return;
|
|
4830
|
+
context.report({
|
|
4831
|
+
node,
|
|
4832
|
+
message: aliasMessage(node.id?.name, source)
|
|
4833
|
+
});
|
|
4834
|
+
}
|
|
4770
4835
|
}
|
|
4771
4836
|
};
|
|
4772
4837
|
}
|
|
@@ -5046,7 +5111,7 @@ function stringValues2(value) {
|
|
|
5046
5111
|
if (value.type !== "Array") return [];
|
|
5047
5112
|
return value.elements.flatMap((element) => element.value.type === "String" ? [element.value.value] : []);
|
|
5048
5113
|
}
|
|
5049
|
-
var
|
|
5114
|
+
var VITEST_CONFIG_NAMES = [
|
|
5050
5115
|
"vitest.config.ts",
|
|
5051
5116
|
"vitest.config.mts",
|
|
5052
5117
|
"vitest.config.cts",
|
|
@@ -5103,7 +5168,7 @@ var vitestCoverageRule = {
|
|
|
5103
5168
|
message: 'package.json must declare a "test:unit:coverage" script that runs Vitest with coverage.'
|
|
5104
5169
|
});
|
|
5105
5170
|
}
|
|
5106
|
-
const configName =
|
|
5171
|
+
const configName = VITEST_CONFIG_NAMES.find((name) => existsSync5(path39.join(context.cwd, name)));
|
|
5107
5172
|
if (!configName) {
|
|
5108
5173
|
context.report({
|
|
5109
5174
|
node,
|
|
@@ -5316,6 +5381,27 @@ function hasHookUsage(body) {
|
|
|
5316
5381
|
}
|
|
5317
5382
|
return false;
|
|
5318
5383
|
}
|
|
5384
|
+
function enclosingComponentFunction(node) {
|
|
5385
|
+
let current = node.parent;
|
|
5386
|
+
while (current) {
|
|
5387
|
+
if (current.type === "FunctionDeclaration") {
|
|
5388
|
+
const name = current.id.name;
|
|
5389
|
+
return name && isComponentLikeName(name) ? current : void 0;
|
|
5390
|
+
}
|
|
5391
|
+
if (current.type === "ArrowFunctionExpression" || current.type === "FunctionExpression") {
|
|
5392
|
+
const declarator = current.parent;
|
|
5393
|
+
if (declarator.type !== "VariableDeclarator" || declarator.id.type !== "Identifier") return void 0;
|
|
5394
|
+
return isComponentLikeName(declarator.id.name) ? current : void 0;
|
|
5395
|
+
}
|
|
5396
|
+
current = current.parent;
|
|
5397
|
+
}
|
|
5398
|
+
return void 0;
|
|
5399
|
+
}
|
|
5400
|
+
function capturesComponentLocal(context, helper, component) {
|
|
5401
|
+
const helperScope = context.sourceCode.getScope(helper);
|
|
5402
|
+
const componentScope = context.sourceCode.getScope(component);
|
|
5403
|
+
return helperScope.through.some((reference) => reference.resolved?.scope === componentScope);
|
|
5404
|
+
}
|
|
5319
5405
|
var pureFunctionExtractRule = {
|
|
5320
5406
|
meta: {
|
|
5321
5407
|
schema: [],
|
|
@@ -5345,25 +5431,27 @@ var pureFunctionExtractRule = {
|
|
|
5345
5431
|
}
|
|
5346
5432
|
return {
|
|
5347
5433
|
FunctionDeclaration(node) {
|
|
5348
|
-
const exported = node.parent?.type === "ExportNamedDeclaration";
|
|
5349
|
-
const moduleLevel = exported || node.parent?.type === "Program";
|
|
5350
|
-
if (!moduleLevel) return;
|
|
5351
5434
|
const name = node.id?.name;
|
|
5352
5435
|
if (!name) return;
|
|
5353
5436
|
if (isRouteFile && ROUTE_HANDLER_EXPORT_NAMES.has(name)) return;
|
|
5354
5437
|
if (isComponentLikeName(name) || isHookName3(name)) return;
|
|
5355
5438
|
if (isHookSupportFile && node.async) return;
|
|
5356
5439
|
if (!node.body || hasHookUsage(node.body)) return;
|
|
5440
|
+
const exported = node.parent?.type === "ExportNamedDeclaration";
|
|
5441
|
+
const moduleLevel = exported || node.parent?.type === "Program";
|
|
5442
|
+
if (moduleLevel) {
|
|
5443
|
+
report3(node, name);
|
|
5444
|
+
return;
|
|
5445
|
+
}
|
|
5446
|
+
if (!isComponentFile) return;
|
|
5447
|
+
const component = enclosingComponentFunction(node);
|
|
5448
|
+
if (!component || capturesComponentLocal(context, node, component)) return;
|
|
5357
5449
|
report3(node, name);
|
|
5358
5450
|
},
|
|
5359
5451
|
VariableDeclarator(node) {
|
|
5360
5452
|
if (node.id.type !== "Identifier") return;
|
|
5361
5453
|
const name = node.id.name;
|
|
5362
5454
|
if (!name) return;
|
|
5363
|
-
const container = node.parent.parent;
|
|
5364
|
-
const exported = container?.type === "ExportNamedDeclaration";
|
|
5365
|
-
const moduleLevel = exported || container?.type === "Program";
|
|
5366
|
-
if (!moduleLevel) return;
|
|
5367
5455
|
if (isRouteFile && ROUTE_HANDLER_EXPORT_NAMES.has(name)) return;
|
|
5368
5456
|
if (isComponentLikeName(name) || isHookName3(name)) return;
|
|
5369
5457
|
const init = node.init;
|
|
@@ -5372,6 +5460,16 @@ var pureFunctionExtractRule = {
|
|
|
5372
5460
|
}
|
|
5373
5461
|
if (isHookSupportFile && init.async) return;
|
|
5374
5462
|
if (init.body.type === "BlockStatement" && hasHookUsage(init.body)) return;
|
|
5463
|
+
const container = node.parent.parent;
|
|
5464
|
+
const exported = container?.type === "ExportNamedDeclaration";
|
|
5465
|
+
const moduleLevel = exported || container?.type === "Program";
|
|
5466
|
+
if (moduleLevel) {
|
|
5467
|
+
report3(node, name);
|
|
5468
|
+
return;
|
|
5469
|
+
}
|
|
5470
|
+
if (!isComponentFile) return;
|
|
5471
|
+
const component = enclosingComponentFunction(node);
|
|
5472
|
+
if (!component || capturesComponentLocal(context, init, component)) return;
|
|
5375
5473
|
report3(node, name);
|
|
5376
5474
|
}
|
|
5377
5475
|
};
|
|
@@ -5451,6 +5549,26 @@ function structuralChildren(node) {
|
|
|
5451
5549
|
(child) => isJsxNode(child) || isJsxExpressionContainer(child)
|
|
5452
5550
|
);
|
|
5453
5551
|
}
|
|
5552
|
+
function branchRootSignature(node) {
|
|
5553
|
+
const children = blockChildren(node);
|
|
5554
|
+
if (children.length < 2) return void 0;
|
|
5555
|
+
return children.map((child) => {
|
|
5556
|
+
const opening = nodeKind(child) === "JSXFragment" ? "<>" : child.openingElement?.name.name ?? "<>";
|
|
5557
|
+
const attributes = (child.openingElement?.attributes ?? []).filter((attribute) => attribute.type === "JSXAttribute").map((attribute) => attribute.name?.name ?? "").sort().join(",");
|
|
5558
|
+
return `${opening}[${attributes}]`;
|
|
5559
|
+
}).join("/");
|
|
5560
|
+
}
|
|
5561
|
+
function isConditionalAssignmentRoot(node) {
|
|
5562
|
+
let current = node;
|
|
5563
|
+
let parent = current.parent;
|
|
5564
|
+
while (parent) {
|
|
5565
|
+
const parentType = parent.type;
|
|
5566
|
+
if (parentType !== "ParenthesizedExpression") break;
|
|
5567
|
+
current = parent;
|
|
5568
|
+
parent = current.parent;
|
|
5569
|
+
}
|
|
5570
|
+
return parent?.type === "AssignmentExpression" || parent?.type === "ConditionalExpression";
|
|
5571
|
+
}
|
|
5454
5572
|
var repeatedStructureRule = {
|
|
5455
5573
|
meta: {
|
|
5456
5574
|
schema: [],
|
|
@@ -5461,18 +5579,37 @@ var repeatedStructureRule = {
|
|
|
5461
5579
|
},
|
|
5462
5580
|
create(context) {
|
|
5463
5581
|
if (!context.filename.endsWith(".tsx") && !context.filename.endsWith(".jsx")) return {};
|
|
5582
|
+
const conditionalAssignmentBlocks = /* @__PURE__ */ new Map();
|
|
5464
5583
|
return {
|
|
5465
5584
|
JSXElement(node) {
|
|
5466
5585
|
checkChildren(node);
|
|
5586
|
+
collectConditionalAssignmentBlock(node);
|
|
5467
5587
|
},
|
|
5468
5588
|
JSXFragment(node) {
|
|
5469
5589
|
checkChildren(node);
|
|
5590
|
+
collectConditionalAssignmentBlock(node);
|
|
5591
|
+
},
|
|
5592
|
+
"Program:exit"() {
|
|
5593
|
+
for (const group of conditionalAssignmentBlocks.values()) {
|
|
5594
|
+
if (group.length < 2) continue;
|
|
5595
|
+
const first = group[0];
|
|
5596
|
+
if (!first) continue;
|
|
5597
|
+
reportRepeatedStructure(first, group.length);
|
|
5598
|
+
}
|
|
5470
5599
|
}
|
|
5471
5600
|
};
|
|
5472
5601
|
function checkChildren(node) {
|
|
5473
5602
|
checkSubstantialBlocks(node);
|
|
5474
5603
|
checkSmallElementExpressionPairs(node);
|
|
5475
5604
|
}
|
|
5605
|
+
function collectConditionalAssignmentBlock(node) {
|
|
5606
|
+
if (!isConditionalAssignmentRoot(node) || !isSubstantial(node)) return;
|
|
5607
|
+
const sig = branchRootSignature(node);
|
|
5608
|
+
if (!sig) return;
|
|
5609
|
+
const group = conditionalAssignmentBlocks.get(sig) ?? [];
|
|
5610
|
+
group.push(node);
|
|
5611
|
+
conditionalAssignmentBlocks.set(sig, group);
|
|
5612
|
+
}
|
|
5476
5613
|
function checkSubstantialBlocks(node) {
|
|
5477
5614
|
const children = blockChildren(node);
|
|
5478
5615
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -8163,6 +8300,7 @@ function assertTypescriptAlignment() {
|
|
|
8163
8300
|
// eslint/index.ts
|
|
8164
8301
|
var pasikaNextjsAppRules = {
|
|
8165
8302
|
// Framework-agnostic TypeScript rules.
|
|
8303
|
+
"file-length": fileLengthRule,
|
|
8166
8304
|
"filename-case": filenameCaseRule,
|
|
8167
8305
|
"import-boundaries": importBoundariesRule,
|
|
8168
8306
|
"import-spacing": importSpacingRule,
|