pasika 0.10.136 → 0.10.138
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 +2 -2
- package/dist/eslint/pasika/index.js +617 -366
- package/package.json +2 -1
|
@@ -5392,20 +5392,217 @@ var noArbitraryTailwindRule = {
|
|
|
5392
5392
|
import path40 from "path";
|
|
5393
5393
|
|
|
5394
5394
|
// eslint/project/jsx-class-reuse.ts
|
|
5395
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
5396
|
+
import ts9 from "typescript";
|
|
5397
|
+
|
|
5398
|
+
// eslint/project/shared-class-compositions.ts
|
|
5395
5399
|
import { readFileSync as readFileSync9 } from "fs";
|
|
5396
5400
|
import ts8 from "typescript";
|
|
5397
5401
|
var MIN_SHARED_CLASSES = 5;
|
|
5402
|
+
function moduleInfo(file, index, cache6) {
|
|
5403
|
+
if (cache6.has(file)) return cache6.get(file);
|
|
5404
|
+
try {
|
|
5405
|
+
const source = ts8.createSourceFile(
|
|
5406
|
+
file,
|
|
5407
|
+
readFileSync9(file, "utf8"),
|
|
5408
|
+
ts8.ScriptTarget.Latest,
|
|
5409
|
+
true,
|
|
5410
|
+
ts8.ScriptKind.TSX
|
|
5411
|
+
);
|
|
5412
|
+
const result = {
|
|
5413
|
+
source,
|
|
5414
|
+
values: /* @__PURE__ */ new Map(),
|
|
5415
|
+
imports: /* @__PURE__ */ new Map(),
|
|
5416
|
+
exports: /* @__PURE__ */ new Map(),
|
|
5417
|
+
reexports: [],
|
|
5418
|
+
stars: []
|
|
5419
|
+
};
|
|
5420
|
+
for (const statement of source.statements) {
|
|
5421
|
+
if (ts8.isVariableStatement(statement)) {
|
|
5422
|
+
const exported = (ts8.getModifiers(statement) ?? []).some((item) => item.kind === ts8.SyntaxKind.ExportKeyword);
|
|
5423
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
5424
|
+
if (!ts8.isIdentifier(declaration.name) || !declaration.initializer) continue;
|
|
5425
|
+
const name = declaration.name.text;
|
|
5426
|
+
result.values.set(name, declaration.initializer);
|
|
5427
|
+
if (exported) result.exports.set(name, name);
|
|
5428
|
+
}
|
|
5429
|
+
} else if (ts8.isImportDeclaration(statement) && ts8.isStringLiteral(statement.moduleSpecifier)) {
|
|
5430
|
+
const target = resolveSpecifier(file, statement.moduleSpecifier.text, index.sourceRoot);
|
|
5431
|
+
const named = statement.importClause?.namedBindings;
|
|
5432
|
+
if (!target || !named || !ts8.isNamedImports(named)) continue;
|
|
5433
|
+
for (const element of named.elements) {
|
|
5434
|
+
result.imports.set(element.name.text, {
|
|
5435
|
+
file: target,
|
|
5436
|
+
name: element.propertyName?.text ?? element.name.text
|
|
5437
|
+
});
|
|
5438
|
+
}
|
|
5439
|
+
} else if (ts8.isExportDeclaration(statement)) {
|
|
5440
|
+
const target = statement.moduleSpecifier && ts8.isStringLiteral(statement.moduleSpecifier) ? resolveSpecifier(file, statement.moduleSpecifier.text, index.sourceRoot) : void 0;
|
|
5441
|
+
if (statement.exportClause && ts8.isNamedExports(statement.exportClause)) {
|
|
5442
|
+
for (const element of statement.exportClause.elements) {
|
|
5443
|
+
const local = element.propertyName?.text ?? element.name.text;
|
|
5444
|
+
if (target) result.reexports.push({ file: target, name: local, exported: element.name.text });
|
|
5445
|
+
else result.exports.set(element.name.text, local);
|
|
5446
|
+
}
|
|
5447
|
+
} else if (target && !statement.exportClause) {
|
|
5448
|
+
result.stars.push(target);
|
|
5449
|
+
}
|
|
5450
|
+
}
|
|
5451
|
+
}
|
|
5452
|
+
cache6.set(file, result);
|
|
5453
|
+
return result;
|
|
5454
|
+
} catch {
|
|
5455
|
+
cache6.set(file, void 0);
|
|
5456
|
+
return void 0;
|
|
5457
|
+
}
|
|
5458
|
+
}
|
|
5459
|
+
function staticText(expression, info, visited) {
|
|
5460
|
+
if (ts8.isStringLiteral(expression) || ts8.isNoSubstitutionTemplateLiteral(expression)) return expression.text;
|
|
5461
|
+
if (ts8.isParenthesizedExpression(expression)) return staticText(expression.expression, info, visited);
|
|
5462
|
+
if (ts8.isIdentifier(expression)) {
|
|
5463
|
+
if (visited.has(expression.text)) return void 0;
|
|
5464
|
+
const value = info.values.get(expression.text);
|
|
5465
|
+
if (!value) return void 0;
|
|
5466
|
+
visited.add(expression.text);
|
|
5467
|
+
const result = staticText(value, info, visited);
|
|
5468
|
+
visited.delete(expression.text);
|
|
5469
|
+
return result;
|
|
5470
|
+
}
|
|
5471
|
+
if (ts8.isCallExpression(expression) && ts8.isIdentifier(expression.expression)) {
|
|
5472
|
+
if (expression.expression.text !== "cn" && expression.expression.text !== "clsx") return void 0;
|
|
5473
|
+
const parts = [];
|
|
5474
|
+
for (const argument of expression.arguments) {
|
|
5475
|
+
if (ts8.isSpreadElement(argument)) return void 0;
|
|
5476
|
+
const value = staticText(argument, info, visited);
|
|
5477
|
+
if (value === void 0) return void 0;
|
|
5478
|
+
parts.push(value);
|
|
5479
|
+
}
|
|
5480
|
+
return parts.join(" ");
|
|
5481
|
+
}
|
|
5482
|
+
return void 0;
|
|
5483
|
+
}
|
|
5484
|
+
function resolveExport(file, name, index, cache6, seen) {
|
|
5485
|
+
const key = `${file}\0${name}`;
|
|
5486
|
+
if (seen.has(key)) return void 0;
|
|
5487
|
+
seen.add(key);
|
|
5488
|
+
const info = moduleInfo(file, index, cache6);
|
|
5489
|
+
if (!info) return void 0;
|
|
5490
|
+
const localName = info.exports.get(name);
|
|
5491
|
+
if (localName) {
|
|
5492
|
+
const initializer = info.values.get(localName);
|
|
5493
|
+
const text = initializer ? staticText(initializer, info, /* @__PURE__ */ new Set([localName])) : void 0;
|
|
5494
|
+
if (text !== void 0) {
|
|
5495
|
+
const classes = [...new Set(text.split(/\s+/u).filter(Boolean))].sort();
|
|
5496
|
+
if (classes.length >= MIN_SHARED_CLASSES) return { origin: file, name: localName, classes };
|
|
5497
|
+
}
|
|
5498
|
+
const imported = info.imports.get(localName);
|
|
5499
|
+
if (imported) return resolveExport(imported.file, imported.name, index, cache6, seen);
|
|
5500
|
+
}
|
|
5501
|
+
for (const reexport of info.reexports) {
|
|
5502
|
+
if (reexport.exported !== name) continue;
|
|
5503
|
+
const target = resolveExport(reexport.file, reexport.name, index, cache6, seen);
|
|
5504
|
+
if (target) return target;
|
|
5505
|
+
}
|
|
5506
|
+
for (const target of info.stars) {
|
|
5507
|
+
const found = resolveExport(target, name, index, cache6, seen);
|
|
5508
|
+
if (found) return found;
|
|
5509
|
+
}
|
|
5510
|
+
return void 0;
|
|
5511
|
+
}
|
|
5512
|
+
function usagesInFile(file, index, cache6) {
|
|
5513
|
+
const info = moduleInfo(file, index, cache6);
|
|
5514
|
+
if (!info) return [];
|
|
5515
|
+
const result = [];
|
|
5516
|
+
const visit = (node) => {
|
|
5517
|
+
if (ts8.isJsxOpeningElement(node) || ts8.isJsxSelfClosingElement(node)) {
|
|
5518
|
+
const tag = node.tagName.getText(info.source);
|
|
5519
|
+
if (/^[a-z][a-z0-9-]*$/u.test(tag)) {
|
|
5520
|
+
const attribute = node.attributes.properties.find(
|
|
5521
|
+
(item) => ts8.isJsxAttribute(item) && ts8.isIdentifier(item.name) && item.name.text === "className"
|
|
5522
|
+
);
|
|
5523
|
+
if (attribute && ts8.isJsxAttribute(attribute) && attribute.initializer && ts8.isJsxExpression(attribute.initializer)) {
|
|
5524
|
+
const expression = attribute.initializer.expression;
|
|
5525
|
+
if (expression) {
|
|
5526
|
+
const identified = /* @__PURE__ */ new Set();
|
|
5527
|
+
const visitedLocals = /* @__PURE__ */ new Set();
|
|
5528
|
+
const collect = (part) => {
|
|
5529
|
+
if (ts8.isIdentifier(part)) {
|
|
5530
|
+
const imported = info.imports.get(part.text);
|
|
5531
|
+
const resolved = imported ? resolveExport(imported.file, imported.name, index, cache6, /* @__PURE__ */ new Set()) : void 0;
|
|
5532
|
+
if (resolved) {
|
|
5533
|
+
const symbol = `${resolved.origin}\0${resolved.name}`;
|
|
5534
|
+
if (!identified.has(symbol)) {
|
|
5535
|
+
identified.add(symbol);
|
|
5536
|
+
const location = info.source.getLineAndCharacterOfPosition(attribute.getStart(info.source));
|
|
5537
|
+
result.push({
|
|
5538
|
+
file,
|
|
5539
|
+
line: location.line + 1,
|
|
5540
|
+
column: location.character,
|
|
5541
|
+
tag,
|
|
5542
|
+
symbol,
|
|
5543
|
+
classes: resolved.classes
|
|
5544
|
+
});
|
|
5545
|
+
}
|
|
5546
|
+
} else if (!visitedLocals.has(part.text)) {
|
|
5547
|
+
const local = info.values.get(part.text);
|
|
5548
|
+
if (local) {
|
|
5549
|
+
visitedLocals.add(part.text);
|
|
5550
|
+
collect(local);
|
|
5551
|
+
visitedLocals.delete(part.text);
|
|
5552
|
+
}
|
|
5553
|
+
}
|
|
5554
|
+
return;
|
|
5555
|
+
}
|
|
5556
|
+
ts8.forEachChild(part, collect);
|
|
5557
|
+
};
|
|
5558
|
+
collect(expression);
|
|
5559
|
+
}
|
|
5560
|
+
}
|
|
5561
|
+
}
|
|
5562
|
+
}
|
|
5563
|
+
ts8.forEachChild(node, visit);
|
|
5564
|
+
};
|
|
5565
|
+
visit(info.source);
|
|
5566
|
+
return result;
|
|
5567
|
+
}
|
|
5568
|
+
function sharedClassReuses(index) {
|
|
5569
|
+
const cache6 = /* @__PURE__ */ new Map();
|
|
5570
|
+
const bySymbol = /* @__PURE__ */ new Map();
|
|
5571
|
+
for (const file of [...index.modules.keys()].sort()) {
|
|
5572
|
+
if (!/\.(?:tsx|jsx)$/u.test(file) || /\.(?:test|spec)\.(?:tsx|jsx)$/u.test(file)) continue;
|
|
5573
|
+
for (const occurrence of usagesInFile(file, index, cache6)) {
|
|
5574
|
+
const members = bySymbol.get(occurrence.symbol) ?? [];
|
|
5575
|
+
members.push(occurrence);
|
|
5576
|
+
bySymbol.set(occurrence.symbol, members);
|
|
5577
|
+
}
|
|
5578
|
+
}
|
|
5579
|
+
const matches = /* @__PURE__ */ new Map();
|
|
5580
|
+
for (const members of bySymbol.values()) {
|
|
5581
|
+
if (new Set(members.map((member) => member.file)).size < 2) continue;
|
|
5582
|
+
for (const occurrence of members.slice(1)) {
|
|
5583
|
+
const original = members.find((member) => member.file !== occurrence.file);
|
|
5584
|
+
if (!original) continue;
|
|
5585
|
+
const entries = matches.get(occurrence.file) ?? [];
|
|
5586
|
+
entries.push({ occurrence, original });
|
|
5587
|
+
matches.set(occurrence.file, entries);
|
|
5588
|
+
}
|
|
5589
|
+
}
|
|
5590
|
+
return matches;
|
|
5591
|
+
}
|
|
5592
|
+
|
|
5593
|
+
// eslint/project/jsx-class-reuse.ts
|
|
5594
|
+
var MIN_SHARED_CLASSES2 = 5;
|
|
5398
5595
|
var cache3 = /* @__PURE__ */ new WeakMap();
|
|
5399
5596
|
function staticClassText(expression) {
|
|
5400
|
-
if (
|
|
5597
|
+
if (ts9.isStringLiteral(expression) || ts9.isNoSubstitutionTemplateLiteral(expression)) {
|
|
5401
5598
|
return expression.text;
|
|
5402
5599
|
}
|
|
5403
|
-
if (
|
|
5404
|
-
if (!
|
|
5600
|
+
if (ts9.isParenthesizedExpression(expression)) return staticClassText(expression.expression);
|
|
5601
|
+
if (!ts9.isCallExpression(expression) || !ts9.isIdentifier(expression.expression)) return void 0;
|
|
5405
5602
|
if (expression.expression.text !== "cn") return void 0;
|
|
5406
5603
|
const chunks = [];
|
|
5407
5604
|
for (const arg of expression.arguments) {
|
|
5408
|
-
if (
|
|
5605
|
+
if (ts9.isSpreadElement(arg)) return void 0;
|
|
5409
5606
|
const text = staticClassText(arg);
|
|
5410
5607
|
if (text === void 0) return void 0;
|
|
5411
5608
|
chunks.push(text);
|
|
@@ -5413,26 +5610,26 @@ function staticClassText(expression) {
|
|
|
5413
5610
|
return chunks.join(" ");
|
|
5414
5611
|
}
|
|
5415
5612
|
function occurrencesInFile(file) {
|
|
5416
|
-
const source =
|
|
5613
|
+
const source = ts9.createSourceFile(file, readFileSync10(file, "utf8"), ts9.ScriptTarget.Latest, true, ts9.ScriptKind.TSX);
|
|
5417
5614
|
const result = [];
|
|
5418
5615
|
const visit = (node) => {
|
|
5419
|
-
if (
|
|
5616
|
+
if (ts9.isJsxOpeningElement(node) || ts9.isJsxSelfClosingElement(node)) {
|
|
5420
5617
|
const tag = node.tagName.getText(source);
|
|
5421
5618
|
if (/^[a-z][a-z0-9-]*$/.test(tag)) {
|
|
5422
5619
|
const attribute = node.attributes.properties.find(
|
|
5423
|
-
(item) =>
|
|
5620
|
+
(item) => ts9.isJsxAttribute(item) && ts9.isIdentifier(item.name) && item.name.text === "className"
|
|
5424
5621
|
);
|
|
5425
|
-
if (attribute &&
|
|
5622
|
+
if (attribute && ts9.isJsxAttribute(attribute)) {
|
|
5426
5623
|
const initializer = attribute.initializer;
|
|
5427
5624
|
let text;
|
|
5428
|
-
if (initializer &&
|
|
5625
|
+
if (initializer && ts9.isStringLiteral(initializer)) {
|
|
5429
5626
|
text = initializer.text;
|
|
5430
|
-
} else if (initializer &&
|
|
5627
|
+
} else if (initializer && ts9.isJsxExpression(initializer) && initializer.expression) {
|
|
5431
5628
|
text = staticClassText(initializer.expression);
|
|
5432
5629
|
}
|
|
5433
5630
|
if (text !== void 0) {
|
|
5434
5631
|
const classes = [...new Set(text.split(/\s+/).filter(Boolean))].sort();
|
|
5435
|
-
if (classes.length >=
|
|
5632
|
+
if (classes.length >= MIN_SHARED_CLASSES2) {
|
|
5436
5633
|
const location = source.getLineAndCharacterOfPosition(attribute.getStart(source));
|
|
5437
5634
|
result.push({
|
|
5438
5635
|
file,
|
|
@@ -5446,7 +5643,7 @@ function occurrencesInFile(file) {
|
|
|
5446
5643
|
}
|
|
5447
5644
|
}
|
|
5448
5645
|
}
|
|
5449
|
-
|
|
5646
|
+
ts9.forEachChild(node, visit);
|
|
5450
5647
|
};
|
|
5451
5648
|
visit(source);
|
|
5452
5649
|
return result;
|
|
@@ -5480,11 +5677,11 @@ function reuseIndex(index) {
|
|
|
5480
5677
|
matches.set(occurrence.file, entries);
|
|
5481
5678
|
}
|
|
5482
5679
|
}
|
|
5483
|
-
return { matches, groups };
|
|
5680
|
+
return { matches, groups, shared: sharedClassReuses(index) };
|
|
5484
5681
|
}
|
|
5485
5682
|
function getJsxReuseAnalysis(sourceRoot) {
|
|
5486
5683
|
const index = getProjectIndex(sourceRoot);
|
|
5487
|
-
if (!index) return { matches: /* @__PURE__ */ new Map(), groups: [] };
|
|
5684
|
+
if (!index) return { matches: /* @__PURE__ */ new Map(), groups: [], shared: /* @__PURE__ */ new Map() };
|
|
5488
5685
|
const existing = cache3.get(index);
|
|
5489
5686
|
if (existing) return existing;
|
|
5490
5687
|
const result = reuseIndex(index);
|
|
@@ -5494,6 +5691,9 @@ function getJsxReuseAnalysis(sourceRoot) {
|
|
|
5494
5691
|
function getJsxClassReuses(sourceRoot) {
|
|
5495
5692
|
return getJsxReuseAnalysis(sourceRoot).matches;
|
|
5496
5693
|
}
|
|
5694
|
+
function getSharedClassReuses(sourceRoot) {
|
|
5695
|
+
return getJsxReuseAnalysis(sourceRoot).shared;
|
|
5696
|
+
}
|
|
5497
5697
|
|
|
5498
5698
|
// eslint/rules/no-duplicate-jsx-classes.ts
|
|
5499
5699
|
var noDuplicateJsxClassesRule = {
|
|
@@ -5507,7 +5707,8 @@ var noDuplicateJsxClassesRule = {
|
|
|
5507
5707
|
if (!/\.(?:jsx|tsx)$/.test(file) || /\.(?:test|spec)\.(?:jsx|tsx)$/.test(file)) return {};
|
|
5508
5708
|
const root = sourceRootOf(context);
|
|
5509
5709
|
const matches = getJsxClassReuses(root).get(file) ?? [];
|
|
5510
|
-
|
|
5710
|
+
const shared = getSharedClassReuses(root).get(file) ?? [];
|
|
5711
|
+
if (matches.length === 0 && shared.length === 0) return {};
|
|
5511
5712
|
return {
|
|
5512
5713
|
Program(node) {
|
|
5513
5714
|
for (const { occurrence, original, commonClasses } of matches) {
|
|
@@ -5518,6 +5719,15 @@ var noDuplicateJsxClassesRule = {
|
|
|
5518
5719
|
message: `<${occurrence.tag}> repeats the same set of ${String(commonClasses.length)} classes as ${reference}:${String(original.line)}. Extract a shared component. See docs/next-tailwind-guide/rules/tailwind-class-reuse-rule.md`
|
|
5519
5720
|
});
|
|
5520
5721
|
}
|
|
5722
|
+
for (const { occurrence, original } of shared) {
|
|
5723
|
+
const reference = path40.relative(path40.dirname(root), original.file).split(path40.sep).join("/");
|
|
5724
|
+
const name = occurrence.symbol.split("\0")[1] ?? "class composition";
|
|
5725
|
+
context.report({
|
|
5726
|
+
node,
|
|
5727
|
+
loc: { line: occurrence.line, column: occurrence.column },
|
|
5728
|
+
message: `<${occurrence.tag}> reuses exported class composition "${name}" (${String(occurrence.classes.length)} classes) from ${reference}:${String(original.line)}. Extract a shared component. See docs/next-tailwind-guide/rules/tailwind-class-reuse-rule.md`
|
|
5729
|
+
});
|
|
5730
|
+
}
|
|
5521
5731
|
}
|
|
5522
5732
|
};
|
|
5523
5733
|
}
|
|
@@ -5527,9 +5737,9 @@ var noDuplicateJsxClassesRule = {
|
|
|
5527
5737
|
import path42 from "path";
|
|
5528
5738
|
|
|
5529
5739
|
// eslint/project/semantic-literals.ts
|
|
5530
|
-
import { readFileSync as
|
|
5740
|
+
import { readFileSync as readFileSync11 } from "fs";
|
|
5531
5741
|
import path41 from "path";
|
|
5532
|
-
import
|
|
5742
|
+
import ts10 from "typescript";
|
|
5533
5743
|
var excludedProperties = /* @__PURE__ */ new Set([
|
|
5534
5744
|
"label",
|
|
5535
5745
|
"title",
|
|
@@ -5576,24 +5786,24 @@ function featureOf(file, root) {
|
|
|
5576
5786
|
return `layer:${parts[0] ?? "src"}`;
|
|
5577
5787
|
}
|
|
5578
5788
|
function nameOf(property) {
|
|
5579
|
-
if (
|
|
5789
|
+
if (ts10.isIdentifier(property) || ts10.isStringLiteral(property)) return property.text;
|
|
5580
5790
|
return void 0;
|
|
5581
5791
|
}
|
|
5582
5792
|
function literalOf(node) {
|
|
5583
|
-
if (
|
|
5584
|
-
if (
|
|
5585
|
-
if (
|
|
5793
|
+
if (ts10.isStringLiteral(node)) return node.text;
|
|
5794
|
+
if (ts10.isNumericLiteral(node)) return Number(node.text.replaceAll("_", ""));
|
|
5795
|
+
if (ts10.isPrefixUnaryExpression(node) && node.operator === ts10.SyntaxKind.MinusToken && ts10.isNumericLiteral(node.operand)) {
|
|
5586
5796
|
return -Number(node.operand.text.replaceAll("_", ""));
|
|
5587
5797
|
}
|
|
5588
5798
|
return void 0;
|
|
5589
5799
|
}
|
|
5590
5800
|
function isLiteralRoot(node) {
|
|
5591
|
-
if (
|
|
5592
|
-
return (
|
|
5801
|
+
if (ts10.isPrefixUnaryExpression(node)) return literalOf(node) !== void 0;
|
|
5802
|
+
return (ts10.isStringLiteral(node) || ts10.isNumericLiteral(node)) && !(ts10.isPrefixUnaryExpression(node.parent) && node.parent.operand === node);
|
|
5593
5803
|
}
|
|
5594
5804
|
function invocation(node) {
|
|
5595
|
-
if (
|
|
5596
|
-
if (
|
|
5805
|
+
if (ts10.isIdentifier(node.expression)) return { method: node.expression.text };
|
|
5806
|
+
if (ts10.isPropertyAccessExpression(node.expression)) {
|
|
5597
5807
|
const receiver = node.expression.expression.getText();
|
|
5598
5808
|
if (!/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)?$/.test(receiver)) return void 0;
|
|
5599
5809
|
return { method: node.expression.name.text, receiver };
|
|
@@ -5601,7 +5811,7 @@ function invocation(node) {
|
|
|
5601
5811
|
return void 0;
|
|
5602
5812
|
}
|
|
5603
5813
|
function isPathname(node) {
|
|
5604
|
-
return
|
|
5814
|
+
return ts10.isPropertyAccessExpression(node) && node.name.text === "pathname";
|
|
5605
5815
|
}
|
|
5606
5816
|
function contextFor(node, value, file, root) {
|
|
5607
5817
|
if (typeof value === "number" && ignoredNumbers.has(value)) return void 0;
|
|
@@ -5610,7 +5820,7 @@ function contextFor(node, value, file, root) {
|
|
|
5610
5820
|
const scope = featureOf(file, root);
|
|
5611
5821
|
const isApiRoute = typeof value === "string" && value.startsWith("/api/") && !/[?&#\s]/.test(value);
|
|
5612
5822
|
const route = () => ({ role: "api-route", family: "api-route" });
|
|
5613
|
-
if (
|
|
5823
|
+
if (ts10.isPropertyAssignment(parent) && parent.initializer === node) {
|
|
5614
5824
|
const name = nameOf(parent.name);
|
|
5615
5825
|
if (!name) return void 0;
|
|
5616
5826
|
if (name === "path" && isApiRoute) return route();
|
|
@@ -5619,14 +5829,14 @@ function contextFor(node, value, file, root) {
|
|
|
5619
5829
|
if (isApiRoute && /route|path|endpoint/i.test(name)) return route();
|
|
5620
5830
|
return { role: `property:${name}:${scope}`, family: `property:${name}` };
|
|
5621
5831
|
}
|
|
5622
|
-
if (
|
|
5832
|
+
if (ts10.isVariableDeclaration(parent) && parent.initializer === node && ts10.isIdentifier(parent.name)) {
|
|
5623
5833
|
if (typeof value === "number") return void 0;
|
|
5624
5834
|
const name = parent.name.text;
|
|
5625
5835
|
if (excludedProperties.has(name) || !semanticVariableName.test(name)) return void 0;
|
|
5626
5836
|
if (isApiRoute && /route|path|endpoint/i.test(name)) return route();
|
|
5627
5837
|
return { role: `variable:${name}:${scope}`, family: `variable:${name}` };
|
|
5628
5838
|
}
|
|
5629
|
-
if (
|
|
5839
|
+
if (ts10.isCallExpression(parent)) {
|
|
5630
5840
|
const position = parent.arguments.findIndex((argument) => argument === node);
|
|
5631
5841
|
if (position < 0) return void 0;
|
|
5632
5842
|
const call = invocation(parent);
|
|
@@ -5645,29 +5855,29 @@ function contextFor(node, value, file, root) {
|
|
|
5645
5855
|
return { role: `column:${scope}`, family: "column" };
|
|
5646
5856
|
}
|
|
5647
5857
|
}
|
|
5648
|
-
if (isApiRoute &&
|
|
5858
|
+
if (isApiRoute && ts10.isBinaryExpression(parent) && (parent.operatorToken.kind === ts10.SyntaxKind.EqualsEqualsEqualsToken || parent.operatorToken.kind === ts10.SyntaxKind.ExclamationEqualsEqualsToken) && (parent.left === node && isPathname(parent.right) || parent.right === node && isPathname(parent.left))) {
|
|
5649
5859
|
return route();
|
|
5650
5860
|
}
|
|
5651
|
-
if (isApiRoute &&
|
|
5861
|
+
if (isApiRoute && ts10.isCallExpression(parent) && parent.arguments[0] === node && ts10.isPropertyAccessExpression(parent.expression) && parent.expression.name.text === "startsWith" && isPathname(parent.expression.expression)) {
|
|
5652
5862
|
return route();
|
|
5653
5863
|
}
|
|
5654
5864
|
return void 0;
|
|
5655
5865
|
}
|
|
5656
5866
|
function isExported2(node) {
|
|
5657
|
-
return
|
|
5867
|
+
return ts10.canHaveModifiers(node) && (ts10.getModifiers(node) ?? []).some((modifier) => modifier.kind === ts10.SyntaxKind.ExportKeyword);
|
|
5658
5868
|
}
|
|
5659
5869
|
function parse(file, root, output) {
|
|
5660
5870
|
if (!isProductionSource(file, root)) return;
|
|
5661
|
-
const source =
|
|
5871
|
+
const source = ts10.createSourceFile(
|
|
5662
5872
|
file,
|
|
5663
|
-
|
|
5664
|
-
|
|
5873
|
+
readFileSync11(file, "utf8"),
|
|
5874
|
+
ts10.ScriptTarget.Latest,
|
|
5665
5875
|
true,
|
|
5666
|
-
file.endsWith(".tsx") || file.endsWith(".jsx") ?
|
|
5876
|
+
file.endsWith(".tsx") || file.endsWith(".jsx") ? ts10.ScriptKind.TSX : ts10.ScriptKind.TS
|
|
5667
5877
|
);
|
|
5668
5878
|
const inConstants = path41.relative(root, file).split(path41.sep).includes("constants");
|
|
5669
5879
|
for (const statement of source.statements) {
|
|
5670
|
-
if (inConstants &&
|
|
5880
|
+
if (inConstants && ts10.isEnumDeclaration(statement) && isExported2(statement)) {
|
|
5671
5881
|
for (const member of statement.members) {
|
|
5672
5882
|
const value = member.initializer && literalOf(member.initializer);
|
|
5673
5883
|
const memberName10 = nameOf(member.name);
|
|
@@ -5681,9 +5891,9 @@ function parse(file, root, output) {
|
|
|
5681
5891
|
});
|
|
5682
5892
|
}
|
|
5683
5893
|
}
|
|
5684
|
-
if (inConstants &&
|
|
5894
|
+
if (inConstants && ts10.isVariableStatement(statement) && isExported2(statement)) {
|
|
5685
5895
|
for (const declaration of statement.declarationList.declarations) {
|
|
5686
|
-
if (!
|
|
5896
|
+
if (!ts10.isIdentifier(declaration.name) || !declaration.initializer) continue;
|
|
5687
5897
|
const value = literalOf(declaration.initializer);
|
|
5688
5898
|
if (value === void 0) continue;
|
|
5689
5899
|
output.canonicals.push({
|
|
@@ -5702,7 +5912,7 @@ function parse(file, root, output) {
|
|
|
5702
5912
|
const semantic = contextFor(node, value, file, root);
|
|
5703
5913
|
if (semantic) {
|
|
5704
5914
|
const declaration = node.parent;
|
|
5705
|
-
const isCanonicalDefinition = inConstants && (
|
|
5915
|
+
const isCanonicalDefinition = inConstants && (ts10.isVariableDeclaration(declaration) && ts10.isVariableStatement(declaration.parent.parent) && isExported2(declaration.parent.parent) || ts10.isEnumMember(declaration));
|
|
5706
5916
|
if ((!inConstants || semantic.family === "api-route") && !isCanonicalDefinition) {
|
|
5707
5917
|
const position = source.getLineAndCharacterOfPosition(node.getStart(source));
|
|
5708
5918
|
output.uses.push({
|
|
@@ -5717,7 +5927,7 @@ function parse(file, root, output) {
|
|
|
5717
5927
|
}
|
|
5718
5928
|
}
|
|
5719
5929
|
}
|
|
5720
|
-
|
|
5930
|
+
ts10.forEachChild(node, visit);
|
|
5721
5931
|
};
|
|
5722
5932
|
visit(source);
|
|
5723
5933
|
}
|
|
@@ -6010,7 +6220,7 @@ var noLiteralInlineStyleRule = {
|
|
|
6010
6220
|
};
|
|
6011
6221
|
|
|
6012
6222
|
// eslint/rules/no-mixed-concerns.ts
|
|
6013
|
-
import { readFileSync as
|
|
6223
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
6014
6224
|
import path43 from "path";
|
|
6015
6225
|
function isComponentSupportKind(kind) {
|
|
6016
6226
|
return kind === "constant" || kind === "type" || kind === "schema";
|
|
@@ -6134,7 +6344,7 @@ var noMixedConcernsRule = {
|
|
|
6134
6344
|
continue;
|
|
6135
6345
|
}
|
|
6136
6346
|
const target = typeof statement.source?.value === "string" ? resolveSpecifier(file, statement.source.value, sourceRoot) : void 0;
|
|
6137
|
-
const forwardedComponents = target?.endsWith(".tsx") ? parseComponentInfo(
|
|
6347
|
+
const forwardedComponents = target?.endsWith(".tsx") ? parseComponentInfo(readFileSync12(target, "utf8"), target).map((component) => component.name) : [];
|
|
6138
6348
|
for (const specifier of statement.specifiers) {
|
|
6139
6349
|
if (/^type\b/.test(context.sourceCode.getText(specifier))) continue;
|
|
6140
6350
|
if (specifier.local.type !== "Identifier") continue;
|
|
@@ -6172,7 +6382,7 @@ import path45 from "path";
|
|
|
6172
6382
|
|
|
6173
6383
|
// eslint/rules/contract-ownership.ts
|
|
6174
6384
|
import path44 from "path";
|
|
6175
|
-
import
|
|
6385
|
+
import ts11 from "typescript";
|
|
6176
6386
|
function isTsProgram(value) {
|
|
6177
6387
|
return typeof value === "object" && value !== null && "getTypeChecker" in value && typeof value.getTypeChecker === "function" && "getSourceFiles" in value && typeof value.getSourceFiles === "function";
|
|
6178
6388
|
}
|
|
@@ -6206,11 +6416,11 @@ function endpointOwnership(pathValue) {
|
|
|
6206
6416
|
return "unknown";
|
|
6207
6417
|
}
|
|
6208
6418
|
function resolvedSymbol(checker, symbol) {
|
|
6209
|
-
return symbol.flags ===
|
|
6419
|
+
return symbol.flags === ts11.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
6210
6420
|
}
|
|
6211
6421
|
function propertyName5(node) {
|
|
6212
6422
|
if (!node) return void 0;
|
|
6213
|
-
if (
|
|
6423
|
+
if (ts11.isIdentifier(node) || ts11.isStringLiteral(node) || ts11.isNumericLiteral(node)) return node.text;
|
|
6214
6424
|
return void 0;
|
|
6215
6425
|
}
|
|
6216
6426
|
var ContractOwnershipIndex = class {
|
|
@@ -6234,7 +6444,7 @@ var ContractOwnershipIndex = class {
|
|
|
6234
6444
|
}
|
|
6235
6445
|
if (declarations.length > 0) return this.endpointFromDeclarations(declarations);
|
|
6236
6446
|
let object;
|
|
6237
|
-
if (
|
|
6447
|
+
if (ts11.isPropertyAccessExpression(node) || ts11.isElementAccessExpression(node)) object = node.expression;
|
|
6238
6448
|
if (!object) return { kind: "missing", ownership: "unknown" };
|
|
6239
6449
|
const type = this.checker.getTypeAtLocation(object);
|
|
6240
6450
|
const typeDeclarations = this.typeDeclarations(type);
|
|
@@ -6242,7 +6452,7 @@ var ContractOwnershipIndex = class {
|
|
|
6242
6452
|
return this.endpointFromDeclarations(typeDeclarations);
|
|
6243
6453
|
}
|
|
6244
6454
|
sourceBinding(node, name) {
|
|
6245
|
-
if (!
|
|
6455
|
+
if (!ts11.isVariableDeclaration(node) || !node.initializer) {
|
|
6246
6456
|
return { kind: "missing", ownership: "unknown" };
|
|
6247
6457
|
}
|
|
6248
6458
|
const sourceType = this.checker.getTypeAtLocation(node.initializer);
|
|
@@ -6251,11 +6461,11 @@ var ContractOwnershipIndex = class {
|
|
|
6251
6461
|
return this.endpointFromDeclarations(declarations);
|
|
6252
6462
|
}
|
|
6253
6463
|
targetProperty(node, name) {
|
|
6254
|
-
if (!
|
|
6464
|
+
if (!ts11.isPropertyAssignment(node) && !ts11.isShorthandPropertyAssignment(node)) {
|
|
6255
6465
|
return { kind: "missing", ownership: "unknown" };
|
|
6256
6466
|
}
|
|
6257
6467
|
const object = node.parent;
|
|
6258
|
-
if (!
|
|
6468
|
+
if (!ts11.isObjectLiteralExpression(object)) return { kind: "missing", ownership: "unknown" };
|
|
6259
6469
|
const contextualType = this.checker.getContextualType(object);
|
|
6260
6470
|
if (!contextualType) return { kind: "missing", ownership: "unknown" };
|
|
6261
6471
|
const declarations = this.propertyDeclarations(contextualType, name);
|
|
@@ -6263,8 +6473,8 @@ var ContractOwnershipIndex = class {
|
|
|
6263
6473
|
return this.endpointFromDeclarations(declarations);
|
|
6264
6474
|
}
|
|
6265
6475
|
memberNameSymbol(node) {
|
|
6266
|
-
if (
|
|
6267
|
-
if (
|
|
6476
|
+
if (ts11.isPropertyAccessExpression(node)) return this.checker.getSymbolAtLocation(node.name);
|
|
6477
|
+
if (ts11.isElementAccessExpression(node)) return this.checker.getSymbolAtLocation(node.argumentExpression);
|
|
6268
6478
|
return void 0;
|
|
6269
6479
|
}
|
|
6270
6480
|
propertyDeclarations(type, name) {
|
|
@@ -6294,14 +6504,14 @@ var ContractOwnershipIndex = class {
|
|
|
6294
6504
|
if (declarations.some((declaration) => this.isDataContractField(declaration))) {
|
|
6295
6505
|
return { kind: "data-contract", ownership };
|
|
6296
6506
|
}
|
|
6297
|
-
if (declarations.some((declaration) =>
|
|
6507
|
+
if (declarations.some((declaration) => ts11.isPropertySignature(declaration) || ts11.isPropertyDeclaration(declaration))) {
|
|
6298
6508
|
return { kind: "typed-local", ownership };
|
|
6299
6509
|
}
|
|
6300
6510
|
return { kind: "non-contract", ownership };
|
|
6301
6511
|
}
|
|
6302
6512
|
isDataContractField(declaration) {
|
|
6303
6513
|
if (this.isZodSchemaField(declaration)) return true;
|
|
6304
|
-
if (!
|
|
6514
|
+
if (!ts11.isPropertySignature(declaration) && !ts11.isPropertyDeclaration(declaration)) return false;
|
|
6305
6515
|
const fileName = normalizePath(declaration.getSourceFile().fileName);
|
|
6306
6516
|
return /(?:^|\/)database(?:[-.]generated)?\.ts$/u.test(fileName);
|
|
6307
6517
|
}
|
|
@@ -6310,10 +6520,10 @@ var ContractOwnershipIndex = class {
|
|
|
6310
6520
|
return this.checker.getPropertyOfType(type, "_zod") !== void 0 && this.checker.getPropertyOfType(type, "parse") !== void 0 && this.checker.getPropertyOfType(type, "safeParse") !== void 0;
|
|
6311
6521
|
}
|
|
6312
6522
|
isZodSchemaField(declaration) {
|
|
6313
|
-
if (!
|
|
6523
|
+
if (!ts11.isPropertyAssignment(declaration)) return false;
|
|
6314
6524
|
let current = declaration.parent;
|
|
6315
|
-
while (!
|
|
6316
|
-
if (
|
|
6525
|
+
while (!ts11.isSourceFile(current)) {
|
|
6526
|
+
if (ts11.isVariableDeclaration(current) && ts11.isIdentifier(current.name) && current.name.text.endsWith("Schema")) {
|
|
6317
6527
|
return true;
|
|
6318
6528
|
}
|
|
6319
6529
|
current = current.parent;
|
|
@@ -6336,7 +6546,7 @@ var ContractOwnershipIndex = class {
|
|
|
6336
6546
|
}
|
|
6337
6547
|
schemaOwnership(declaration) {
|
|
6338
6548
|
let current = declaration;
|
|
6339
|
-
while (!
|
|
6549
|
+
while (!ts11.isSourceFile(current)) {
|
|
6340
6550
|
const ownership = this.schemaNodeOwnership.get(current);
|
|
6341
6551
|
if (ownership !== void 0) return ownership;
|
|
6342
6552
|
current = current.parent;
|
|
@@ -6347,29 +6557,29 @@ var ContractOwnershipIndex = class {
|
|
|
6347
6557
|
for (const sourceFile of this.program.getSourceFiles()) {
|
|
6348
6558
|
if (sourceFile.isDeclarationFile || !isWithin2(this.cwd, path44.resolve(sourceFile.fileName))) continue;
|
|
6349
6559
|
const visit = (node) => {
|
|
6350
|
-
if (
|
|
6351
|
-
|
|
6560
|
+
if (ts11.isCallExpression(node) && this.isDefineApiContractCall(node)) this.indexApiContractCall(node);
|
|
6561
|
+
ts11.forEachChild(node, visit);
|
|
6352
6562
|
};
|
|
6353
6563
|
visit(sourceFile);
|
|
6354
6564
|
}
|
|
6355
6565
|
}
|
|
6356
6566
|
isDefineApiContractCall(node) {
|
|
6357
|
-
if (
|
|
6358
|
-
return
|
|
6567
|
+
if (ts11.isIdentifier(node.expression)) return node.expression.text === "defineApiContract";
|
|
6568
|
+
return ts11.isPropertyAccessExpression(node.expression) && node.expression.name.text === "defineApiContract";
|
|
6359
6569
|
}
|
|
6360
6570
|
indexApiContractCall(node) {
|
|
6361
6571
|
const argument = node.arguments[0];
|
|
6362
|
-
if (!argument || !
|
|
6572
|
+
if (!argument || !ts11.isObjectLiteralExpression(argument)) return;
|
|
6363
6573
|
let pathExpression;
|
|
6364
6574
|
const schemaExpressions = [];
|
|
6365
6575
|
for (const property of argument.properties) {
|
|
6366
|
-
if (
|
|
6576
|
+
if (ts11.isPropertyAssignment(property)) {
|
|
6367
6577
|
const name = propertyName5(property.name);
|
|
6368
6578
|
if (name === "path") pathExpression = property.initializer;
|
|
6369
6579
|
if (name === "requestSchema" || name === "responseSchema") schemaExpressions.push(property.initializer);
|
|
6370
6580
|
continue;
|
|
6371
6581
|
}
|
|
6372
|
-
if (
|
|
6582
|
+
if (ts11.isShorthandPropertyAssignment(property)) {
|
|
6373
6583
|
const name = property.name.text;
|
|
6374
6584
|
if (name === "path") pathExpression = property.name;
|
|
6375
6585
|
if (name === "requestSchema" || name === "responseSchema") schemaExpressions.push(property.name);
|
|
@@ -6383,13 +6593,13 @@ var ContractOwnershipIndex = class {
|
|
|
6383
6593
|
}
|
|
6384
6594
|
staticString(node, seen) {
|
|
6385
6595
|
if (!node) return void 0;
|
|
6386
|
-
if (
|
|
6387
|
-
if (
|
|
6596
|
+
if (ts11.isStringLiteralLike(node)) return node.text;
|
|
6597
|
+
if (ts11.isIdentifier(node)) {
|
|
6388
6598
|
const symbol = this.checker.getSymbolAtLocation(node);
|
|
6389
6599
|
if (!symbol || seen.has(symbol)) return void 0;
|
|
6390
6600
|
seen.add(symbol);
|
|
6391
6601
|
for (const declaration of resolvedSymbol(this.checker, symbol).declarations ?? []) {
|
|
6392
|
-
if (
|
|
6602
|
+
if (ts11.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
6393
6603
|
const value = this.staticString(declaration.initializer, seen);
|
|
6394
6604
|
if (value !== void 0) return value;
|
|
6395
6605
|
}
|
|
@@ -6407,20 +6617,20 @@ var ContractOwnershipIndex = class {
|
|
|
6407
6617
|
this.followSchemaDeclaration(declaration, ownership, seen);
|
|
6408
6618
|
}
|
|
6409
6619
|
}
|
|
6410
|
-
|
|
6620
|
+
ts11.forEachChild(node, (child) => {
|
|
6411
6621
|
this.markSchemaExpression(child, ownership, seen);
|
|
6412
6622
|
});
|
|
6413
6623
|
}
|
|
6414
6624
|
schemaReferenceSymbol(node) {
|
|
6415
|
-
if (
|
|
6625
|
+
if (ts11.isIdentifier(node)) {
|
|
6416
6626
|
if (!node.text.endsWith("Schema")) return void 0;
|
|
6417
6627
|
return this.checker.getSymbolAtLocation(node);
|
|
6418
6628
|
}
|
|
6419
|
-
if (
|
|
6629
|
+
if (ts11.isPropertyAccessExpression(node)) {
|
|
6420
6630
|
if (!node.name.text.endsWith("Schema")) return void 0;
|
|
6421
6631
|
return this.checker.getSymbolAtLocation(node.name);
|
|
6422
6632
|
}
|
|
6423
|
-
if (
|
|
6633
|
+
if (ts11.isElementAccessExpression(node) && ts11.isStringLiteralLike(node.argumentExpression)) {
|
|
6424
6634
|
if (!node.argumentExpression.text.endsWith("Schema")) return void 0;
|
|
6425
6635
|
return this.checker.getSymbolAtLocation(node.argumentExpression);
|
|
6426
6636
|
}
|
|
@@ -6428,15 +6638,15 @@ var ContractOwnershipIndex = class {
|
|
|
6428
6638
|
}
|
|
6429
6639
|
followSchemaDeclaration(declaration, ownership, seen) {
|
|
6430
6640
|
this.setSchemaOwnership(declaration, ownership);
|
|
6431
|
-
if (
|
|
6641
|
+
if (ts11.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
6432
6642
|
this.markSchemaExpression(declaration.initializer, ownership, seen);
|
|
6433
6643
|
return;
|
|
6434
6644
|
}
|
|
6435
|
-
if (
|
|
6645
|
+
if (ts11.isPropertyAssignment(declaration)) {
|
|
6436
6646
|
this.markSchemaExpression(declaration.initializer, ownership, seen);
|
|
6437
6647
|
return;
|
|
6438
6648
|
}
|
|
6439
|
-
if (
|
|
6649
|
+
if (ts11.isShorthandPropertyAssignment(declaration)) {
|
|
6440
6650
|
const valueSymbol = this.checker.getShorthandAssignmentValueSymbol(declaration);
|
|
6441
6651
|
if (!valueSymbol || seen.has(valueSymbol)) return;
|
|
6442
6652
|
seen.add(valueSymbol);
|
|
@@ -6810,7 +7020,7 @@ function sourceRootOf3(context, filename) {
|
|
|
6810
7020
|
}
|
|
6811
7021
|
|
|
6812
7022
|
// eslint/rules/package-json/ci-checks.ts
|
|
6813
|
-
import { existsSync as existsSync6, readFileSync as
|
|
7023
|
+
import { existsSync as existsSync6, readFileSync as readFileSync13, readdirSync as readdirSync4 } from "fs";
|
|
6814
7024
|
import path47 from "path";
|
|
6815
7025
|
import { parse as parse2 } from "yaml";
|
|
6816
7026
|
function mapping(value) {
|
|
@@ -6869,7 +7079,7 @@ function readWorkflows(dir) {
|
|
|
6869
7079
|
const errors = [];
|
|
6870
7080
|
for (const file of readdirSync4(dir).filter((name) => /\.ya?ml$/i.test(name)).sort()) {
|
|
6871
7081
|
try {
|
|
6872
|
-
const parsed = parse2(
|
|
7082
|
+
const parsed = parse2(readFileSync13(path47.join(dir, file), "utf8"), { uniqueKeys: true });
|
|
6873
7083
|
const content = mapping(parsed);
|
|
6874
7084
|
if (!content) throw new Error("expected a YAML mapping");
|
|
6875
7085
|
workflows.push(content);
|
|
@@ -7153,7 +7363,7 @@ var nextjsStackRule = {
|
|
|
7153
7363
|
};
|
|
7154
7364
|
|
|
7155
7365
|
// eslint/rules/package-json/vitest-coverage.ts
|
|
7156
|
-
import { existsSync as existsSync7, readFileSync as
|
|
7366
|
+
import { existsSync as existsSync7, readFileSync as readFileSync14 } from "fs";
|
|
7157
7367
|
import path48 from "path";
|
|
7158
7368
|
function memberName6(member) {
|
|
7159
7369
|
return member.name.type === "String" ? member.name.value : member.name.name;
|
|
@@ -7232,7 +7442,7 @@ var vitestCoverageRule = {
|
|
|
7232
7442
|
});
|
|
7233
7443
|
return;
|
|
7234
7444
|
}
|
|
7235
|
-
const content =
|
|
7445
|
+
const content = readFileSync14(path48.join(context.cwd, configName), "utf8");
|
|
7236
7446
|
for (const metric of THRESHOLD_METRICS) {
|
|
7237
7447
|
if (!new RegExp(`\\b${metric}\\s*:\\s*[1-9]\\d*`).test(content)) {
|
|
7238
7448
|
context.report({ node, message: `${configName} must set a coverage threshold above zero for ${metric}.` });
|
|
@@ -7280,7 +7490,7 @@ var nextjsPackageJsonRules = {
|
|
|
7280
7490
|
|
|
7281
7491
|
// eslint/rules/prefer-enum.ts
|
|
7282
7492
|
import path49 from "path";
|
|
7283
|
-
import
|
|
7493
|
+
import ts12 from "typescript";
|
|
7284
7494
|
function isConstAssertion(node) {
|
|
7285
7495
|
const typeAnnotation = node.typeAnnotation;
|
|
7286
7496
|
return typeAnnotation?.type === "TSTypeReference" && typeAnnotation.typeName?.type === "Identifier" && typeAnnotation.typeName.name === "const";
|
|
@@ -7334,13 +7544,13 @@ function isLiteralTupleAssertion(node) {
|
|
|
7334
7544
|
return values.every((value) => value !== void 0) && new Set(values).size >= 2;
|
|
7335
7545
|
}
|
|
7336
7546
|
function isTsLiteralTupleDeclaration(declaration) {
|
|
7337
|
-
if (!
|
|
7547
|
+
if (!ts12.isVariableDeclaration(declaration) || !declaration.initializer) return false;
|
|
7338
7548
|
const init = declaration.initializer;
|
|
7339
|
-
if (!
|
|
7549
|
+
if (!ts12.isAsExpression(init) || !ts12.isTypeReferenceNode(init.type) || !ts12.isIdentifier(init.type.typeName) || init.type.typeName.text !== "const" || !ts12.isArrayLiteralExpression(init.expression) || init.expression.elements.length < 2) {
|
|
7340
7550
|
return false;
|
|
7341
7551
|
}
|
|
7342
7552
|
const values = init.expression.elements.map(
|
|
7343
|
-
(element) =>
|
|
7553
|
+
(element) => ts12.isStringLiteral(element) || ts12.isNumericLiteral(element) ? element.text : void 0
|
|
7344
7554
|
);
|
|
7345
7555
|
return values.every((value) => value !== void 0) && new Set(values).size >= 2;
|
|
7346
7556
|
}
|
|
@@ -7369,7 +7579,7 @@ var preferEnumRule = {
|
|
|
7369
7579
|
const checker = services.program.getTypeChecker();
|
|
7370
7580
|
const symbol = checker.getSymbolAtLocation(tsNode);
|
|
7371
7581
|
if (!symbol) return false;
|
|
7372
|
-
const original = symbol.flags ===
|
|
7582
|
+
const original = symbol.flags === ts12.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
7373
7583
|
return (original.declarations ?? []).some(isTsLiteralTupleDeclaration);
|
|
7374
7584
|
}
|
|
7375
7585
|
return {
|
|
@@ -7464,7 +7674,7 @@ var preferEnumRule = {
|
|
|
7464
7674
|
};
|
|
7465
7675
|
|
|
7466
7676
|
// eslint/rules/prefer-object-destructuring.ts
|
|
7467
|
-
import
|
|
7677
|
+
import ts13 from "typescript";
|
|
7468
7678
|
var DOC7 = "See docs/next-codebase-guide/rules/redundant-aliases-rule.md";
|
|
7469
7679
|
function hasTypeAnnotation(identifier) {
|
|
7470
7680
|
return "typeAnnotation" in identifier && identifier.typeAnnotation !== void 0;
|
|
@@ -7557,8 +7767,8 @@ function enumValueResolver(context) {
|
|
|
7557
7767
|
const checker = services.program.getTypeChecker();
|
|
7558
7768
|
const { esTreeNodeToTSNodeMap: nodeMap } = services;
|
|
7559
7769
|
const isEnumSymbol = (symbol) => {
|
|
7560
|
-
const resolved = symbol.flags ===
|
|
7561
|
-
return (resolved.declarations ?? []).some((declaration) =>
|
|
7770
|
+
const resolved = symbol.flags === ts13.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
7771
|
+
return (resolved.declarations ?? []).some((declaration) => ts13.isEnumDeclaration(declaration));
|
|
7562
7772
|
};
|
|
7563
7773
|
return (node) => {
|
|
7564
7774
|
const tsNode = nodeMap.get(node);
|
|
@@ -7574,18 +7784,18 @@ function detachableCallResolver(context) {
|
|
|
7574
7784
|
if (!services) return () => false;
|
|
7575
7785
|
const checker = services.program.getTypeChecker();
|
|
7576
7786
|
const { esTreeNodeToTSNodeMap: nodeMap } = services;
|
|
7577
|
-
const isUnboundFunctionType = (type) =>
|
|
7787
|
+
const isUnboundFunctionType = (type) => ts13.isFunctionTypeNode(type) && !type.parameters.some((parameter) => ts13.isIdentifier(parameter.name) && parameter.name.text === "this");
|
|
7578
7788
|
return (member) => {
|
|
7579
7789
|
const node = nodeMap.get(member);
|
|
7580
|
-
if (!node || !
|
|
7790
|
+
if (!node || !ts13.isPropertyAccessExpression(node)) return false;
|
|
7581
7791
|
const symbol = checker.getSymbolAtLocation(node.name);
|
|
7582
7792
|
const declarations = symbol?.declarations;
|
|
7583
7793
|
if (!declarations?.length) return false;
|
|
7584
7794
|
return declarations.every((declaration) => {
|
|
7585
|
-
if (
|
|
7586
|
-
return declaration.type !== void 0 && isUnboundFunctionType(declaration.type) ||
|
|
7795
|
+
if (ts13.isPropertySignature(declaration) || ts13.isPropertyDeclaration(declaration)) {
|
|
7796
|
+
return declaration.type !== void 0 && isUnboundFunctionType(declaration.type) || ts13.isPropertyDeclaration(declaration) && declaration.initializer !== void 0 && ts13.isArrowFunction(declaration.initializer);
|
|
7587
7797
|
}
|
|
7588
|
-
if (
|
|
7798
|
+
if (ts13.isPropertyAssignment(declaration)) return ts13.isArrowFunction(declaration.initializer);
|
|
7589
7799
|
return false;
|
|
7590
7800
|
});
|
|
7591
7801
|
};
|
|
@@ -8200,7 +8410,7 @@ import path53 from "path";
|
|
|
8200
8410
|
|
|
8201
8411
|
// eslint/rules/imported-enum-literals.ts
|
|
8202
8412
|
import path52 from "path";
|
|
8203
|
-
import
|
|
8413
|
+
import ts14 from "typescript";
|
|
8204
8414
|
var columnMethods2 = /* @__PURE__ */ new Set([
|
|
8205
8415
|
"eq",
|
|
8206
8416
|
"neq",
|
|
@@ -8217,7 +8427,7 @@ var columnMethods2 = /* @__PURE__ */ new Set([
|
|
|
8217
8427
|
"not"
|
|
8218
8428
|
]);
|
|
8219
8429
|
function memberName7(name) {
|
|
8220
|
-
if (
|
|
8430
|
+
if (ts14.isIdentifier(name) || ts14.isStringLiteral(name)) return name.text;
|
|
8221
8431
|
return void 0;
|
|
8222
8432
|
}
|
|
8223
8433
|
function isWithin3(root, file) {
|
|
@@ -8232,22 +8442,22 @@ function domainOf(name) {
|
|
|
8232
8442
|
function importedEnums(file, checker, sourceRoot, importedNames) {
|
|
8233
8443
|
const matches = /* @__PURE__ */ new Map();
|
|
8234
8444
|
for (const statement of file.statements) {
|
|
8235
|
-
if (!
|
|
8445
|
+
if (!ts14.isImportDeclaration(statement) || !statement.importClause?.namedBindings || !ts14.isNamedImports(statement.importClause.namedBindings)) {
|
|
8236
8446
|
continue;
|
|
8237
8447
|
}
|
|
8238
8448
|
for (const specifier of statement.importClause.namedBindings.elements) {
|
|
8239
8449
|
if (!importedNames.has(specifier.name.text)) continue;
|
|
8240
8450
|
const symbol = checker.getSymbolAtLocation(specifier.name);
|
|
8241
8451
|
if (!symbol) continue;
|
|
8242
|
-
const resolved = symbol.flags ===
|
|
8452
|
+
const resolved = symbol.flags === ts14.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
8243
8453
|
for (const declaration of resolved.declarations ?? []) {
|
|
8244
|
-
if (!
|
|
8454
|
+
if (!ts14.isEnumDeclaration(declaration)) continue;
|
|
8245
8455
|
const declarationFile = path52.resolve(declaration.getSourceFile().fileName);
|
|
8246
8456
|
if (!isWithin3(sourceRoot, declarationFile)) continue;
|
|
8247
8457
|
const domain = domainOf(declaration.name.text);
|
|
8248
8458
|
if (!domain) continue;
|
|
8249
8459
|
for (const member of declaration.members) {
|
|
8250
|
-
if (!member.initializer || !
|
|
8460
|
+
if (!member.initializer || !ts14.isStringLiteral(member.initializer)) continue;
|
|
8251
8461
|
const name = memberName7(member.name);
|
|
8252
8462
|
if (!name) continue;
|
|
8253
8463
|
const entries = matches.get(member.initializer.text) ?? [];
|
|
@@ -8264,19 +8474,19 @@ function importedEnums(file, checker, sourceRoot, importedNames) {
|
|
|
8264
8474
|
return matches;
|
|
8265
8475
|
}
|
|
8266
8476
|
function isPathname2(node) {
|
|
8267
|
-
return
|
|
8477
|
+
return ts14.isPropertyAccessExpression(node) && node.name.text === "pathname";
|
|
8268
8478
|
}
|
|
8269
8479
|
function domainForUse(node) {
|
|
8270
8480
|
const parent = node.parent;
|
|
8271
|
-
if (
|
|
8481
|
+
if (ts14.isPropertyAssignment(parent) && parent.initializer === node && memberName7(parent.name) === "path") {
|
|
8272
8482
|
return "route";
|
|
8273
8483
|
}
|
|
8274
|
-
if (
|
|
8484
|
+
if (ts14.isCallExpression(parent) && parent.arguments[0] === node && ts14.isPropertyAccessExpression(parent.expression)) {
|
|
8275
8485
|
const { expression, name } = parent.expression;
|
|
8276
8486
|
if (columnMethods2.has(name.text)) return "column";
|
|
8277
8487
|
if (name.text === "startsWith" && isPathname2(expression)) return "route";
|
|
8278
8488
|
}
|
|
8279
|
-
if (
|
|
8489
|
+
if (ts14.isBinaryExpression(parent) && (parent.operatorToken.kind === ts14.SyntaxKind.EqualsEqualsEqualsToken || parent.operatorToken.kind === ts14.SyntaxKind.ExclamationEqualsEqualsToken) && (parent.left === node && isPathname2(parent.right) || parent.right === node && isPathname2(parent.left))) {
|
|
8280
8490
|
return "route";
|
|
8281
8491
|
}
|
|
8282
8492
|
return void 0;
|
|
@@ -8298,7 +8508,7 @@ function importedEnumLiteralUses(context, root) {
|
|
|
8298
8508
|
if (matches.size === 0) return [];
|
|
8299
8509
|
const uses = [];
|
|
8300
8510
|
const visit = (node) => {
|
|
8301
|
-
if (
|
|
8511
|
+
if (ts14.isStringLiteral(node)) {
|
|
8302
8512
|
const domain = domainForUse(node);
|
|
8303
8513
|
const candidates = matches.get(node.text)?.filter((entry) => entry.domain === domain) ?? [];
|
|
8304
8514
|
if (candidates.length === 1) {
|
|
@@ -8315,7 +8525,7 @@ function importedEnumLiteralUses(context, root) {
|
|
|
8315
8525
|
}
|
|
8316
8526
|
}
|
|
8317
8527
|
}
|
|
8318
|
-
|
|
8528
|
+
ts14.forEachChild(node, visit);
|
|
8319
8529
|
};
|
|
8320
8530
|
visit(file);
|
|
8321
8531
|
return uses;
|
|
@@ -8812,7 +9022,7 @@ var rootSupportPlacementRule = {
|
|
|
8812
9022
|
|
|
8813
9023
|
// eslint/rules/route-handler-shape.ts
|
|
8814
9024
|
import path57 from "path";
|
|
8815
|
-
import
|
|
9025
|
+
import ts15 from "typescript";
|
|
8816
9026
|
|
|
8817
9027
|
// eslint/rules/route-single-use-delegation.ts
|
|
8818
9028
|
import path56 from "path";
|
|
@@ -8926,33 +9136,33 @@ function findHandler(node) {
|
|
|
8926
9136
|
return void 0;
|
|
8927
9137
|
}
|
|
8928
9138
|
function isLoop(node) {
|
|
8929
|
-
return
|
|
9139
|
+
return ts15.isForStatement(node) || ts15.isForOfStatement(node) || ts15.isForInStatement(node) || ts15.isWhileStatement(node) || ts15.isDoStatement(node);
|
|
8930
9140
|
}
|
|
8931
9141
|
function isFunctionBoundary(node) {
|
|
8932
|
-
return
|
|
9142
|
+
return ts15.isFunctionExpression(node) || ts15.isArrowFunction(node) || ts15.isFunctionDeclaration(node);
|
|
8933
9143
|
}
|
|
8934
9144
|
function analyzeHandlerBody(body, sourceText) {
|
|
8935
9145
|
const start = body.range?.[0] ?? 0;
|
|
8936
9146
|
const end = body.range?.[1] ?? sourceText.length;
|
|
8937
|
-
const sourceFile =
|
|
9147
|
+
const sourceFile = ts15.createSourceFile(
|
|
8938
9148
|
"route.ts",
|
|
8939
9149
|
sourceText.slice(start, end),
|
|
8940
|
-
|
|
9150
|
+
ts15.ScriptTarget.Latest,
|
|
8941
9151
|
true,
|
|
8942
|
-
|
|
9152
|
+
ts15.ScriptKind.TS
|
|
8943
9153
|
);
|
|
8944
9154
|
const kinds = /* @__PURE__ */ new Set();
|
|
8945
9155
|
const calledNames = /* @__PURE__ */ new Set();
|
|
8946
9156
|
const visit = (node) => {
|
|
8947
|
-
if (
|
|
9157
|
+
if (ts15.isTryStatement(node)) kinds.add("try");
|
|
8948
9158
|
if (isLoop(node)) kinds.add("loop");
|
|
8949
|
-
if (
|
|
8950
|
-
if (
|
|
9159
|
+
if (ts15.isIfStatement(node)) kinds.add("if");
|
|
9160
|
+
if (ts15.isCallExpression(node) && ts15.isPropertyAccessExpression(node.expression) && node.expression.name.text === "map") {
|
|
8951
9161
|
kinds.add("map");
|
|
8952
9162
|
}
|
|
8953
|
-
if (
|
|
9163
|
+
if (ts15.isCallExpression(node) && ts15.isIdentifier(node.expression)) calledNames.add(node.expression.text);
|
|
8954
9164
|
if (isFunctionBoundary(node)) return;
|
|
8955
|
-
|
|
9165
|
+
ts15.forEachChild(node, visit);
|
|
8956
9166
|
};
|
|
8957
9167
|
visit(sourceFile);
|
|
8958
9168
|
return { kinds, calledNames };
|
|
@@ -9121,38 +9331,38 @@ var schemaCasingRule = {
|
|
|
9121
9331
|
|
|
9122
9332
|
// eslint/rules/sole-state-owner.ts
|
|
9123
9333
|
import path59 from "path";
|
|
9124
|
-
import
|
|
9334
|
+
import ts16 from "typescript";
|
|
9125
9335
|
function findStateHooks(node) {
|
|
9126
9336
|
const hooks = [];
|
|
9127
9337
|
const visit = (child) => {
|
|
9128
|
-
if (
|
|
9129
|
-
if (
|
|
9338
|
+
if (ts16.isCallExpression(child) && ts16.isIdentifier(child.expression) && child.expression.text === "useState") {
|
|
9339
|
+
if (ts16.isVariableDeclaration(child.parent)) {
|
|
9130
9340
|
const { name } = child.parent;
|
|
9131
|
-
if (
|
|
9341
|
+
if (ts16.isArrayBindingPattern(name) && name.elements.length >= 2) {
|
|
9132
9342
|
const value = name.elements[0];
|
|
9133
9343
|
const updater = name.elements[1];
|
|
9134
|
-
if (value && updater &&
|
|
9344
|
+
if (value && updater && ts16.isBindingElement(value) && ts16.isBindingElement(updater)) {
|
|
9135
9345
|
const valueName = value.name;
|
|
9136
9346
|
const updaterName = updater.name;
|
|
9137
|
-
if (
|
|
9347
|
+
if (ts16.isIdentifier(valueName) && ts16.isIdentifier(updaterName)) {
|
|
9138
9348
|
hooks.push({ value: valueName.text, updater: updaterName.text });
|
|
9139
9349
|
}
|
|
9140
9350
|
}
|
|
9141
9351
|
}
|
|
9142
9352
|
}
|
|
9143
9353
|
}
|
|
9144
|
-
|
|
9354
|
+
ts16.forEachChild(child, visit);
|
|
9145
9355
|
};
|
|
9146
9356
|
visit(node);
|
|
9147
9357
|
return hooks;
|
|
9148
9358
|
}
|
|
9149
9359
|
function isHookUsage(node, hook) {
|
|
9150
|
-
if (
|
|
9360
|
+
if (ts16.isCallExpression(node) && ts16.isIdentifier(node.expression) && node.expression.text === hook.updater) {
|
|
9151
9361
|
return "updater";
|
|
9152
9362
|
}
|
|
9153
|
-
if (
|
|
9363
|
+
if (ts16.isIdentifier(node) && node.text === hook.value) {
|
|
9154
9364
|
const parent = node.parent;
|
|
9155
|
-
if (
|
|
9365
|
+
if (ts16.isBindingElement(parent) && parent.name === node || ts16.isVariableDeclaration(parent) && parent.name === node || ts16.isParameter(parent) && parent.name === node || ts16.isPropertyAccessExpression(parent) && parent.name === node || ts16.isPropertyAssignment(parent) && parent.name === node) {
|
|
9156
9366
|
return void 0;
|
|
9157
9367
|
}
|
|
9158
9368
|
return "value";
|
|
@@ -9162,61 +9372,61 @@ function isHookUsage(node, hook) {
|
|
|
9162
9372
|
function topLevelJsxChildren(initial) {
|
|
9163
9373
|
if (!initial) return void 0;
|
|
9164
9374
|
let expression = initial;
|
|
9165
|
-
while (
|
|
9166
|
-
if (
|
|
9375
|
+
while (ts16.isParenthesizedExpression(expression)) expression = expression.expression;
|
|
9376
|
+
if (ts16.isJsxFragment(expression)) {
|
|
9167
9377
|
const children = expression.children.filter(
|
|
9168
|
-
(c) => !
|
|
9378
|
+
(c) => !ts16.isJsxText(c) && !ts16.isJsxSpreadAttribute(c)
|
|
9169
9379
|
);
|
|
9170
9380
|
return { root: expression, children };
|
|
9171
9381
|
}
|
|
9172
|
-
if (
|
|
9382
|
+
if (ts16.isJsxElement(expression)) {
|
|
9173
9383
|
const children = expression.children.filter(
|
|
9174
|
-
(c) => !
|
|
9384
|
+
(c) => !ts16.isJsxText(c) && !ts16.isJsxSpreadAttribute(c)
|
|
9175
9385
|
);
|
|
9176
9386
|
return { root: expression, children };
|
|
9177
9387
|
}
|
|
9178
9388
|
return void 0;
|
|
9179
9389
|
}
|
|
9180
9390
|
function isSimpleDerivedExpression(node) {
|
|
9181
|
-
if (
|
|
9391
|
+
if (ts16.isNewExpression(node) || ts16.isAwaitExpression(node) || ts16.isYieldExpression(node) || ts16.isDeleteExpression(node) || ts16.isTaggedTemplateExpression(node) || ts16.isBlock(node)) {
|
|
9182
9392
|
return false;
|
|
9183
9393
|
}
|
|
9184
|
-
if (
|
|
9394
|
+
if (ts16.isCallExpression(node)) {
|
|
9185
9395
|
const callee = node.expression;
|
|
9186
|
-
if (!
|
|
9396
|
+
if (!ts16.isPropertyAccessExpression(callee) || !(/* @__PURE__ */ new Set(["filter", "map", "find", "findIndex", "some", "every", "slice", "includes"])).has(callee.name.text)) {
|
|
9187
9397
|
return false;
|
|
9188
9398
|
}
|
|
9189
9399
|
}
|
|
9190
|
-
if (
|
|
9191
|
-
if (
|
|
9400
|
+
if (ts16.isArrowFunction(node) && ts16.isBlock(node.body)) return false;
|
|
9401
|
+
if (ts16.isBinaryExpression(node)) {
|
|
9192
9402
|
const operator = node.operatorToken.kind;
|
|
9193
|
-
if (operator >=
|
|
9403
|
+
if (operator >= ts16.SyntaxKind.FirstAssignment && operator <= ts16.SyntaxKind.LastAssignment) return false;
|
|
9194
9404
|
}
|
|
9195
|
-
if ((
|
|
9405
|
+
if ((ts16.isPrefixUnaryExpression(node) || ts16.isPostfixUnaryExpression(node)) && (node.operator === ts16.SyntaxKind.PlusPlusToken || node.operator === ts16.SyntaxKind.MinusMinusToken)) {
|
|
9196
9406
|
return false;
|
|
9197
9407
|
}
|
|
9198
9408
|
let safe = true;
|
|
9199
|
-
|
|
9409
|
+
ts16.forEachChild(node, (child) => {
|
|
9200
9410
|
if (!isSimpleDerivedExpression(child)) safe = false;
|
|
9201
9411
|
});
|
|
9202
9412
|
return safe;
|
|
9203
9413
|
}
|
|
9204
9414
|
function isIdentifierRead(node, names) {
|
|
9205
|
-
if (!
|
|
9415
|
+
if (!ts16.isIdentifier(node) || !names.has(node.text)) return false;
|
|
9206
9416
|
const parent = node.parent;
|
|
9207
|
-
return !(
|
|
9417
|
+
return !(ts16.isBindingElement(parent) && parent.name === node || ts16.isVariableDeclaration(parent) && parent.name === node || ts16.isParameter(parent) && parent.name === node || ts16.isPropertyAccessExpression(parent) && parent.name === node || ts16.isPropertyAssignment(parent) && parent.name === node);
|
|
9208
9418
|
}
|
|
9209
9419
|
function containsNamedRead(node, names) {
|
|
9210
9420
|
if (isIdentifierRead(node, names)) return true;
|
|
9211
|
-
return
|
|
9421
|
+
return ts16.forEachChild(node, (child) => containsNamedRead(child, names)) ?? false;
|
|
9212
9422
|
}
|
|
9213
9423
|
function findDerivedState(body, hook) {
|
|
9214
9424
|
const names = /* @__PURE__ */ new Set([hook.value]);
|
|
9215
9425
|
const allowedInitializers = /* @__PURE__ */ new Set();
|
|
9216
9426
|
for (const statement of body.statements) {
|
|
9217
|
-
if (!
|
|
9427
|
+
if (!ts16.isVariableStatement(statement) || statement.declarationList.flags !== ts16.NodeFlags.Const) continue;
|
|
9218
9428
|
for (const declaration of statement.declarationList.declarations) {
|
|
9219
|
-
if (!
|
|
9429
|
+
if (!ts16.isIdentifier(declaration.name) || !declaration.initializer) continue;
|
|
9220
9430
|
if (!containsNamedRead(declaration.initializer, names)) continue;
|
|
9221
9431
|
if (!isSimpleDerivedExpression(declaration.initializer)) continue;
|
|
9222
9432
|
names.add(declaration.name.text);
|
|
@@ -9232,21 +9442,21 @@ function countUsesIn(child, hook, names) {
|
|
|
9232
9442
|
let count = 0;
|
|
9233
9443
|
const visit = (node) => {
|
|
9234
9444
|
if (isTrackedUse(node, hook, names)) count += 1;
|
|
9235
|
-
if (
|
|
9236
|
-
|
|
9445
|
+
if (ts16.isFunctionDeclaration(node) || ts16.isClassDeclaration(node)) return;
|
|
9446
|
+
ts16.forEachChild(node, visit);
|
|
9237
9447
|
};
|
|
9238
9448
|
visit(child);
|
|
9239
9449
|
return count;
|
|
9240
9450
|
}
|
|
9241
9451
|
function jsxChildren(node) {
|
|
9242
|
-
if (
|
|
9243
|
-
return [...node.children].filter((child) => !
|
|
9452
|
+
if (ts16.isJsxElement(node) || ts16.isJsxFragment(node)) {
|
|
9453
|
+
return [...node.children].filter((child) => !ts16.isJsxText(child));
|
|
9244
9454
|
}
|
|
9245
9455
|
return void 0;
|
|
9246
9456
|
}
|
|
9247
9457
|
function isDecorativeSeparator(node) {
|
|
9248
|
-
if (!
|
|
9249
|
-
const tagName2 =
|
|
9458
|
+
if (!ts16.isJsxSelfClosingElement(node) && !ts16.isJsxElement(node)) return false;
|
|
9459
|
+
const tagName2 = ts16.isJsxElement(node) ? node.openingElement.tagName : node.tagName;
|
|
9250
9460
|
return /(?:Divider|Separator)$/.test(tagName2.getText());
|
|
9251
9461
|
}
|
|
9252
9462
|
var soleStateOwnerRule = {
|
|
@@ -9283,18 +9493,18 @@ var soleStateOwnerRule = {
|
|
|
9283
9493
|
}
|
|
9284
9494
|
};
|
|
9285
9495
|
function analyzeSoleOwner(declaration, hook) {
|
|
9286
|
-
const body =
|
|
9287
|
-
if (!body || !
|
|
9496
|
+
const body = ts16.isFunctionDeclaration(declaration) ? declaration.body : void 0;
|
|
9497
|
+
if (!body || !ts16.isBlock(body)) return void 0;
|
|
9288
9498
|
const returns = [];
|
|
9289
9499
|
const visit = (node) => {
|
|
9290
|
-
if (node !== body && (
|
|
9291
|
-
if (
|
|
9292
|
-
|
|
9500
|
+
if (node !== body && (ts16.isFunctionLike(node) || ts16.isClassLike(node))) return;
|
|
9501
|
+
if (ts16.isReturnStatement(node)) returns.push(node);
|
|
9502
|
+
ts16.forEachChild(node, visit);
|
|
9293
9503
|
};
|
|
9294
9504
|
visit(body);
|
|
9295
9505
|
if (returns.length !== 1) return void 0;
|
|
9296
9506
|
const expression = returns[0]?.expression;
|
|
9297
|
-
if (!expression || !
|
|
9507
|
+
if (!expression || !ts16.isExpression(expression)) return void 0;
|
|
9298
9508
|
const root = topLevelJsxChildren(expression);
|
|
9299
9509
|
if (!root) return void 0;
|
|
9300
9510
|
const derived = findDerivedState(body, hook);
|
|
@@ -9305,7 +9515,7 @@ function analyzeSoleOwner(declaration, hook) {
|
|
|
9305
9515
|
const children = jsxChildren(node);
|
|
9306
9516
|
if (!children || children.length === 0) return void 0;
|
|
9307
9517
|
for (const child of children) {
|
|
9308
|
-
if (
|
|
9518
|
+
if (ts16.isJsxElement(child) || ts16.isJsxFragment(child)) {
|
|
9309
9519
|
const inner = analyzeSection(child);
|
|
9310
9520
|
if (inner) return inner;
|
|
9311
9521
|
}
|
|
@@ -9329,11 +9539,11 @@ function usesOutsideJsx(declaration, hook, derived, children) {
|
|
|
9329
9539
|
let outside = false;
|
|
9330
9540
|
const visit = (node) => {
|
|
9331
9541
|
if (outside) return;
|
|
9332
|
-
if (node !== declaration && (
|
|
9542
|
+
if (node !== declaration && (ts16.isFunctionDeclaration(node) || ts16.isClassDeclaration(node))) return;
|
|
9333
9543
|
if (isTrackedUse(node, hook, derived.names)) {
|
|
9334
9544
|
let current = node;
|
|
9335
9545
|
let allowed = false;
|
|
9336
|
-
while (!
|
|
9546
|
+
while (!ts16.isSourceFile(current)) {
|
|
9337
9547
|
if (children.includes(current) || derived.allowedInitializers.has(current)) {
|
|
9338
9548
|
allowed = true;
|
|
9339
9549
|
break;
|
|
@@ -9342,7 +9552,7 @@ function usesOutsideJsx(declaration, hook, derived, children) {
|
|
|
9342
9552
|
}
|
|
9343
9553
|
if (!allowed) outside = true;
|
|
9344
9554
|
}
|
|
9345
|
-
|
|
9555
|
+
ts16.forEachChild(node, visit);
|
|
9346
9556
|
};
|
|
9347
9557
|
visit(declaration);
|
|
9348
9558
|
return outside;
|
|
@@ -9766,7 +9976,7 @@ import path66 from "path";
|
|
|
9766
9976
|
import { parse as parse3, toPlainObject } from "@eslint/css-tree";
|
|
9767
9977
|
|
|
9768
9978
|
// eslint/rules/tailwind/source-files.ts
|
|
9769
|
-
import { readdirSync as readdirSync5, readFileSync as
|
|
9979
|
+
import { readdirSync as readdirSync5, readFileSync as readFileSync15, statSync as statSync3 } from "fs";
|
|
9770
9980
|
import path64 from "path";
|
|
9771
9981
|
var CSS_EXTENSIONS = [".css"];
|
|
9772
9982
|
var MODULE_EXTENSIONS4 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
|
|
@@ -9797,7 +10007,7 @@ function cachedTextReader() {
|
|
|
9797
10007
|
let text = texts.get(file);
|
|
9798
10008
|
if (text === void 0) {
|
|
9799
10009
|
try {
|
|
9800
|
-
text =
|
|
10010
|
+
text = readFileSync15(file, "utf8");
|
|
9801
10011
|
} catch {
|
|
9802
10012
|
text = "";
|
|
9803
10013
|
}
|
|
@@ -10219,12 +10429,80 @@ var customUtilityApplyRule = {
|
|
|
10219
10429
|
};
|
|
10220
10430
|
|
|
10221
10431
|
// eslint/rules/tailwind/feature-css-placement.ts
|
|
10222
|
-
import
|
|
10223
|
-
import path70 from "path";
|
|
10432
|
+
import path71 from "path";
|
|
10224
10433
|
|
|
10225
10434
|
// eslint/rules/tailwind/css-dependency-graph.ts
|
|
10226
|
-
import
|
|
10435
|
+
import path69 from "path";
|
|
10227
10436
|
import { generate, parse as parse4, walk } from "@eslint/css-tree";
|
|
10437
|
+
|
|
10438
|
+
// eslint/rules/tailwind/tailwind-theme-classes.ts
|
|
10439
|
+
import { spawnSync } from "child_process";
|
|
10440
|
+
import { existsSync as existsSync10 } from "fs";
|
|
10441
|
+
import path68 from "path";
|
|
10442
|
+
var WORKER = String.raw`
|
|
10443
|
+
import { readFileSync } from "node:fs";
|
|
10444
|
+
import { createRequire } from "node:module";
|
|
10445
|
+
import path from "node:path";
|
|
10446
|
+
import { pathToFileURL } from "node:url";
|
|
10447
|
+
|
|
10448
|
+
const { names, projectRoot, moduleUrl } = JSON.parse(readFileSync(0, "utf8"));
|
|
10449
|
+
let resolved;
|
|
10450
|
+
try {
|
|
10451
|
+
resolved = createRequire(path.join(projectRoot, "package.json")).resolve("@tailwindcss/node");
|
|
10452
|
+
} catch {
|
|
10453
|
+
resolved = createRequire(moduleUrl).resolve("@tailwindcss/node");
|
|
10454
|
+
}
|
|
10455
|
+
const { __unstable__loadDesignSystem } = await import(pathToFileURL(resolved).href);
|
|
10456
|
+
if (typeof __unstable__loadDesignSystem !== "function") {
|
|
10457
|
+
throw new Error("@tailwindcss/node design-system API is unavailable");
|
|
10458
|
+
}
|
|
10459
|
+
const css = "@theme inline {\n" + names.map((name, index) =>
|
|
10460
|
+
name + "-pasika-owner-" + index + ": 1px;"
|
|
10461
|
+
).join("\n") + "\n}";
|
|
10462
|
+
const designSystem = await __unstable__loadDesignSystem(css, { base: projectRoot });
|
|
10463
|
+
const available = designSystem.getClassList().map(([name]) => name);
|
|
10464
|
+
const result = names.map((_, index) => {
|
|
10465
|
+
const marker = "-pasika-owner-" + index;
|
|
10466
|
+
return available.filter((name) => name.endsWith(marker)).map((name) => name.slice(0, -marker.length));
|
|
10467
|
+
});
|
|
10468
|
+
process.stdout.write(JSON.stringify(result));
|
|
10469
|
+
`;
|
|
10470
|
+
var cache5 = /* @__PURE__ */ new Map();
|
|
10471
|
+
var TOKEN = /^--[a-z][a-z0-9-]*$/u;
|
|
10472
|
+
function isStringGroups(value) {
|
|
10473
|
+
return Array.isArray(value) && value.every((group) => Array.isArray(group) && group.every((item) => typeof item === "string"));
|
|
10474
|
+
}
|
|
10475
|
+
function themeClassesForTokens(names, sourceRoot) {
|
|
10476
|
+
const projectRoot = path68.dirname(sourceRoot);
|
|
10477
|
+
const unique = [...new Set(names)].filter((name) => TOKEN.test(name) && name !== "--spacing");
|
|
10478
|
+
const missing = unique.filter((name) => !cache5.has(`${projectRoot}\0${name}`));
|
|
10479
|
+
if (missing.length > 0) {
|
|
10480
|
+
const child = spawnSync(process.execPath, ["--input-type=module", "--eval", WORKER], {
|
|
10481
|
+
cwd: existsSync10(projectRoot) ? projectRoot : process.cwd(),
|
|
10482
|
+
input: JSON.stringify({ names: missing, projectRoot, moduleUrl: import.meta.url }),
|
|
10483
|
+
encoding: "utf8",
|
|
10484
|
+
timeout: 3e4,
|
|
10485
|
+
maxBuffer: 8 * 1024 * 1024,
|
|
10486
|
+
windowsHide: true
|
|
10487
|
+
});
|
|
10488
|
+
if (child.error || child.status !== 0) {
|
|
10489
|
+
const detail = child.error?.message ?? (child.stderr.trim() || "Tailwind could not resolve theme utilities");
|
|
10490
|
+
throw new Error(`Cannot resolve Tailwind theme classes: ${detail}`);
|
|
10491
|
+
}
|
|
10492
|
+
const result = JSON.parse(child.stdout);
|
|
10493
|
+
if (!isStringGroups(result) || result.length !== missing.length) {
|
|
10494
|
+
throw new Error("Unexpected Tailwind theme class resolver output");
|
|
10495
|
+
}
|
|
10496
|
+
for (const [index, name] of missing.entries()) {
|
|
10497
|
+
const classes = result[index];
|
|
10498
|
+
if (!classes) throw new Error("Missing Tailwind theme class result");
|
|
10499
|
+
cache5.set(`${projectRoot}\0${name}`, classes);
|
|
10500
|
+
}
|
|
10501
|
+
}
|
|
10502
|
+
return new Map(unique.map((name) => [name, cache5.get(`${projectRoot}\0${name}`) ?? []]));
|
|
10503
|
+
}
|
|
10504
|
+
|
|
10505
|
+
// eslint/rules/tailwind/css-dependency-graph.ts
|
|
10228
10506
|
function lineAt(text, offset) {
|
|
10229
10507
|
return text.slice(0, offset).split("\n").length;
|
|
10230
10508
|
}
|
|
@@ -10235,93 +10513,15 @@ function tokenLines(content, token) {
|
|
|
10235
10513
|
function pushSymbol(symbols, kind, name, file, line, value) {
|
|
10236
10514
|
if (name) symbols.push({ kind, name, file, line, ...value === void 0 ? {} : { value } });
|
|
10237
10515
|
}
|
|
10238
|
-
function themeClasses(name) {
|
|
10239
|
-
if (name.includes("--", 2)) return [];
|
|
10240
|
-
if (name.startsWith("--color-")) {
|
|
10241
|
-
const stem = name.slice("--color-".length);
|
|
10242
|
-
return [
|
|
10243
|
-
"bg",
|
|
10244
|
-
"text",
|
|
10245
|
-
"border",
|
|
10246
|
-
"ring",
|
|
10247
|
-
"fill",
|
|
10248
|
-
"stroke",
|
|
10249
|
-
"accent",
|
|
10250
|
-
"caret",
|
|
10251
|
-
"decoration",
|
|
10252
|
-
"outline",
|
|
10253
|
-
"divide",
|
|
10254
|
-
"from",
|
|
10255
|
-
"via",
|
|
10256
|
-
"to",
|
|
10257
|
-
"shadow",
|
|
10258
|
-
"ring-offset"
|
|
10259
|
-
].map((prefix) => `${prefix}-${stem}`);
|
|
10260
|
-
}
|
|
10261
|
-
if (name.startsWith("--background-image-")) return [`bg-${name.slice("--background-image-".length)}`];
|
|
10262
|
-
if (name.startsWith("--spacing-")) {
|
|
10263
|
-
const stem = name.slice("--spacing-".length);
|
|
10264
|
-
return [
|
|
10265
|
-
"p",
|
|
10266
|
-
"px",
|
|
10267
|
-
"py",
|
|
10268
|
-
"pt",
|
|
10269
|
-
"pr",
|
|
10270
|
-
"pb",
|
|
10271
|
-
"pl",
|
|
10272
|
-
"ps",
|
|
10273
|
-
"pe",
|
|
10274
|
-
"m",
|
|
10275
|
-
"mx",
|
|
10276
|
-
"my",
|
|
10277
|
-
"mt",
|
|
10278
|
-
"mr",
|
|
10279
|
-
"mb",
|
|
10280
|
-
"ml",
|
|
10281
|
-
"ms",
|
|
10282
|
-
"me",
|
|
10283
|
-
"w",
|
|
10284
|
-
"h",
|
|
10285
|
-
"size",
|
|
10286
|
-
"min-w",
|
|
10287
|
-
"min-h",
|
|
10288
|
-
"max-w",
|
|
10289
|
-
"max-h",
|
|
10290
|
-
"gap",
|
|
10291
|
-
"gap-x",
|
|
10292
|
-
"gap-y",
|
|
10293
|
-
"inset",
|
|
10294
|
-
"inset-x",
|
|
10295
|
-
"inset-y",
|
|
10296
|
-
"top",
|
|
10297
|
-
"right",
|
|
10298
|
-
"bottom",
|
|
10299
|
-
"left",
|
|
10300
|
-
"start",
|
|
10301
|
-
"end",
|
|
10302
|
-
"space-x",
|
|
10303
|
-
"space-y"
|
|
10304
|
-
].map((prefix) => `${prefix}-${stem}`);
|
|
10305
|
-
}
|
|
10306
|
-
if (name.startsWith("--aspect-")) return [`aspect-${name.slice("--aspect-".length)}`];
|
|
10307
|
-
if (name.startsWith("--leading-")) return [`leading-${name.slice("--leading-".length)}`];
|
|
10308
|
-
if (name.startsWith("--animate-")) return [`animate-${name.slice("--animate-".length)}`];
|
|
10309
|
-
if (name.startsWith("--inset-shadow-")) return [`inset-shadow-${name.slice("--inset-shadow-".length)}`];
|
|
10310
|
-
if (name.startsWith("--radius-")) return [`rounded-${name.slice("--radius-".length)}`];
|
|
10311
|
-
if (name.startsWith("--text-") || name.startsWith("--tracking-") || name.startsWith("--font-")) {
|
|
10312
|
-
return [name.slice(2)];
|
|
10313
|
-
}
|
|
10314
|
-
return [];
|
|
10315
|
-
}
|
|
10316
10516
|
function buildCssDependencyGraph(options) {
|
|
10317
10517
|
const definitions = [];
|
|
10318
10518
|
const references = [];
|
|
10319
10519
|
const imports = [];
|
|
10320
10520
|
for (const file of options.css) {
|
|
10321
|
-
const filename =
|
|
10521
|
+
const filename = path69.normalize(file.path);
|
|
10322
10522
|
for (const spec of importedSpecifiers(file.content)) {
|
|
10323
10523
|
const target = resolveSpecifier2(filename, spec, options.sourceRoot);
|
|
10324
|
-
if (target) imports.push({ from: filename, to:
|
|
10524
|
+
if (target) imports.push({ from: filename, to: path69.normalize(target) });
|
|
10325
10525
|
}
|
|
10326
10526
|
const ast = parse4(file.content, { positions: true, parseAtrulePrelude: false });
|
|
10327
10527
|
const atRuleStack = [];
|
|
@@ -10422,13 +10622,24 @@ function buildCssDependencyGraph(options) {
|
|
|
10422
10622
|
const utilities = new Set(definitions.filter((item) => item.kind === "utility").map((item) => item.name));
|
|
10423
10623
|
const selectors = new Set(definitions.filter((item) => item.kind === "selector").map((item) => item.name));
|
|
10424
10624
|
const keyframes = new Set(definitions.filter((item) => item.kind === "keyframes").map((item) => item.name));
|
|
10625
|
+
for (const token of definitions) {
|
|
10626
|
+
if (token.kind !== "theme-token" || !token.name.startsWith("--animate-") || !token.value) continue;
|
|
10627
|
+
for (const name of keyframes) {
|
|
10628
|
+
if (tokenLines(token.value, name).length === 0) continue;
|
|
10629
|
+
references.push({ kind: "keyframes", name, file: token.file, line: token.line, source: "css" });
|
|
10630
|
+
}
|
|
10631
|
+
}
|
|
10425
10632
|
const generatedClasses = /* @__PURE__ */ new Map();
|
|
10633
|
+
const themeNames = definitions.filter((symbol) => symbol.kind === "theme-token").map((symbol) => symbol.name);
|
|
10634
|
+
const classesByToken = themeClassesForTokens(themeNames, options.sourceRoot);
|
|
10426
10635
|
for (const symbol of definitions) {
|
|
10427
10636
|
if (symbol.kind !== "theme-token") continue;
|
|
10428
|
-
for (const className of
|
|
10637
|
+
for (const className of classesByToken.get(symbol.name) ?? []) {
|
|
10638
|
+
generatedClasses.set(className, symbol.name);
|
|
10639
|
+
}
|
|
10429
10640
|
}
|
|
10430
10641
|
for (const file of options.css) {
|
|
10431
|
-
const filename =
|
|
10642
|
+
const filename = path69.normalize(file.path);
|
|
10432
10643
|
const ast = parse4(file.content, { positions: true, parseAtrulePrelude: false });
|
|
10433
10644
|
walk(ast, {
|
|
10434
10645
|
enter(node) {
|
|
@@ -10481,7 +10692,7 @@ function buildCssDependencyGraph(options) {
|
|
|
10481
10692
|
});
|
|
10482
10693
|
}
|
|
10483
10694
|
for (const file of options.modules) {
|
|
10484
|
-
const filename =
|
|
10695
|
+
const filename = path69.normalize(file.path);
|
|
10485
10696
|
for (const [kind, names] of [
|
|
10486
10697
|
["utility", utilities],
|
|
10487
10698
|
["keyframes", keyframes],
|
|
@@ -10501,25 +10712,22 @@ function buildCssDependencyGraph(options) {
|
|
|
10501
10712
|
}
|
|
10502
10713
|
return { definitions, references, imports };
|
|
10503
10714
|
}
|
|
10504
|
-
function cssSymbolUsages(graph, kind, name) {
|
|
10505
|
-
return graph.references.filter((item) => item.kind === kind && item.name === name);
|
|
10506
|
-
}
|
|
10507
10715
|
|
|
10508
10716
|
// eslint/rules/tailwind/css-ownership.ts
|
|
10509
|
-
import
|
|
10717
|
+
import path70 from "path";
|
|
10510
10718
|
import { generate as generate2, parse as parse5, walk as walk2 } from "@eslint/css-tree";
|
|
10511
10719
|
var GLOBAL = "globals.css";
|
|
10512
10720
|
function symbolId(def) {
|
|
10513
10721
|
return [def.file, def.kind, def.name, def.line].join("|");
|
|
10514
10722
|
}
|
|
10515
10723
|
function consumerFeature(file, sourceRoot) {
|
|
10516
|
-
const parts =
|
|
10724
|
+
const parts = path70.relative(sourceRoot, file).split(path70.sep);
|
|
10517
10725
|
return parts[0] === "features" && parts.length > 2 ? parts[1] ?? GLOBAL : GLOBAL;
|
|
10518
10726
|
}
|
|
10519
10727
|
function contains(text, name) {
|
|
10520
10728
|
return new RegExp(`(?<![\\w-])${escapeRegExp(name)}(?![\\w-])`, "u").test(text);
|
|
10521
10729
|
}
|
|
10522
|
-
function dependencies(text, defs) {
|
|
10730
|
+
function dependencies(text, defs, classesByToken) {
|
|
10523
10731
|
const result = /* @__PURE__ */ new Set();
|
|
10524
10732
|
const variables = new Set([...text.matchAll(/var\(\s*(?<name>--[\w-]+)/gu)].map((m) => m.groups?.name));
|
|
10525
10733
|
const applied = [...text.matchAll(/@apply\s+(?<value>[^;}]+)/gu)].map((m) => m.groups?.value ?? "");
|
|
@@ -10530,7 +10738,7 @@ function dependencies(text, defs) {
|
|
|
10530
10738
|
(m) => (m.groups?.value ?? "").replaceAll("_", " ").toLowerCase()
|
|
10531
10739
|
);
|
|
10532
10740
|
for (const def of defs) {
|
|
10533
|
-
const match = (def.kind === "theme-token" || def.kind === "root-variable") && variables.has(def.name) || (def.kind === "utility" || def.kind === "selector") && applied.some((part) => contains(part, def.name)) || def.kind === "keyframes" && animations.some((part) => contains(part, def.name)) || def.kind === "font-face" && (families.some((part) => contains(part, def.name)) || new RegExp(`^\\s*["']?${escapeRegExp(def.name)}["']?\\s*(?:,|$)`, "iu").test(text)) || def.kind === "theme-token" && applied.some((part) =>
|
|
10741
|
+
const match = (def.kind === "theme-token" || def.kind === "root-variable") && variables.has(def.name) || (def.kind === "utility" || def.kind === "selector") && applied.some((part) => contains(part, def.name)) || def.kind === "keyframes" && animations.some((part) => contains(part, def.name)) || def.kind === "font-face" && (families.some((part) => contains(part, def.name)) || new RegExp(`^\\s*["']?${escapeRegExp(def.name)}["']?\\s*(?:,|$)`, "iu").test(text)) || def.kind === "theme-token" && applied.some((part) => (classesByToken.get(def.name) ?? []).some((name) => contains(part, name)));
|
|
10534
10742
|
if (match) result.add(symbolId(def));
|
|
10535
10743
|
}
|
|
10536
10744
|
return result;
|
|
@@ -10538,7 +10746,7 @@ function dependencies(text, defs) {
|
|
|
10538
10746
|
function bodiesOf(css2, defs) {
|
|
10539
10747
|
const bodies = /* @__PURE__ */ new Map();
|
|
10540
10748
|
for (const src of css2) {
|
|
10541
|
-
const file =
|
|
10749
|
+
const file = path70.normalize(src.path);
|
|
10542
10750
|
const ast = parse5(src.content, { positions: true, parseAtrulePrelude: false });
|
|
10543
10751
|
walk2(ast, {
|
|
10544
10752
|
enter(node) {
|
|
@@ -10566,6 +10774,10 @@ function bodiesOf(css2, defs) {
|
|
|
10566
10774
|
function inferCssOwners(options) {
|
|
10567
10775
|
const { graph, css: css2, modules, sourceRoot } = options;
|
|
10568
10776
|
const defs = graph.definitions;
|
|
10777
|
+
const classesByToken = themeClassesForTokens(
|
|
10778
|
+
defs.filter((def) => def.kind === "theme-token").map((def) => def.name),
|
|
10779
|
+
sourceRoot
|
|
10780
|
+
);
|
|
10569
10781
|
const owners = new Map(defs.map((def) => [symbolId(def), /* @__PURE__ */ new Set()]));
|
|
10570
10782
|
const counts = /* @__PURE__ */ new Map();
|
|
10571
10783
|
for (const def of defs) {
|
|
@@ -10598,7 +10810,7 @@ function inferCssOwners(options) {
|
|
|
10598
10810
|
}
|
|
10599
10811
|
const links = /* @__PURE__ */ new Map();
|
|
10600
10812
|
for (const [key, content] of bodiesOf(css2, defs)) {
|
|
10601
|
-
const targets = dependencies(content, defs);
|
|
10813
|
+
const targets = dependencies(content, defs, classesByToken);
|
|
10602
10814
|
const def = defs.find((candidate) => symbolId(candidate) === key);
|
|
10603
10815
|
if (def?.kind === "theme-token" && def.name.startsWith("--animate-")) {
|
|
10604
10816
|
for (const frame of defs) {
|
|
@@ -10611,7 +10823,7 @@ function inferCssOwners(options) {
|
|
|
10611
10823
|
links.set(key, targets);
|
|
10612
10824
|
}
|
|
10613
10825
|
for (const src of css2) {
|
|
10614
|
-
if (
|
|
10826
|
+
if (path70.basename(src.path) !== GLOBAL) continue;
|
|
10615
10827
|
const ast = parse5(src.content, { positions: true, parseAtrulePrelude: false });
|
|
10616
10828
|
if (ast.type !== "StyleSheet") continue;
|
|
10617
10829
|
for (const node of ast.children) {
|
|
@@ -10619,7 +10831,7 @@ function inferCssOwners(options) {
|
|
|
10619
10831
|
continue;
|
|
10620
10832
|
}
|
|
10621
10833
|
const body = src.content.slice(node.loc.start.offset, node.loc.end.offset);
|
|
10622
|
-
for (const key of dependencies(body, defs)) owners.get(key)?.add(GLOBAL);
|
|
10834
|
+
for (const key of dependencies(body, defs, classesByToken)) owners.get(key)?.add(GLOBAL);
|
|
10623
10835
|
}
|
|
10624
10836
|
}
|
|
10625
10837
|
let changed = true;
|
|
@@ -10652,9 +10864,8 @@ function inferCssOwners(options) {
|
|
|
10652
10864
|
}
|
|
10653
10865
|
|
|
10654
10866
|
// eslint/rules/tailwind/feature-css-placement.ts
|
|
10655
|
-
var STYLES_DIR =
|
|
10867
|
+
var STYLES_DIR = path71.join("app", "styles");
|
|
10656
10868
|
var GLOBALS = "globals.css";
|
|
10657
|
-
var FEATURE_CSS = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*\.css$/u;
|
|
10658
10869
|
var LABELS = {
|
|
10659
10870
|
utility: "utility",
|
|
10660
10871
|
"theme-token": "theme token",
|
|
@@ -10673,13 +10884,10 @@ var featureCssPlacementRule = {
|
|
|
10673
10884
|
},
|
|
10674
10885
|
create(context) {
|
|
10675
10886
|
const sourceRoot = sourceRootOf(context);
|
|
10676
|
-
const current =
|
|
10677
|
-
const relative =
|
|
10678
|
-
const styles =
|
|
10679
|
-
if (!relative.startsWith(`${STYLES_DIR}${
|
|
10680
|
-
const basename = path70.basename(current);
|
|
10681
|
-
const featureName = basename.slice(0, -".css".length);
|
|
10682
|
-
const isFeatureFile = path70.dirname(current) === styles && FEATURE_CSS.test(basename) && existsSync10(path70.join(sourceRoot, "features", featureName));
|
|
10887
|
+
const current = path71.normalize(path71.resolve(context.filename));
|
|
10888
|
+
const relative = path71.relative(sourceRoot, current);
|
|
10889
|
+
const styles = path71.join(sourceRoot, STYLES_DIR);
|
|
10890
|
+
if (!relative.startsWith(`${STYLES_DIR}${path71.sep}`)) return {};
|
|
10683
10891
|
const read = cachedTextReader();
|
|
10684
10892
|
const css2 = findFiles(sourceRoot, CSS_EXTENSIONS).map((file) => ({ path: file, content: read(file) }));
|
|
10685
10893
|
const modules = findFiles(sourceRoot, MODULE_EXTENSIONS4).map((file) => ({ path: file, content: read(file) }));
|
|
@@ -10692,10 +10900,7 @@ var featureCssPlacementRule = {
|
|
|
10692
10900
|
const owner = owners.get(symbolId(definition));
|
|
10693
10901
|
if (!owner) continue;
|
|
10694
10902
|
const expected = owner === GLOBALS ? GLOBALS : `${owner}.css`;
|
|
10695
|
-
if (
|
|
10696
|
-
continue;
|
|
10697
|
-
}
|
|
10698
|
-
if (basename === expected) continue;
|
|
10903
|
+
if (current === path71.join(styles, expected)) continue;
|
|
10699
10904
|
const kind = LABELS[definition.kind] ?? definition.kind;
|
|
10700
10905
|
context.report({
|
|
10701
10906
|
node,
|
|
@@ -10713,7 +10918,7 @@ var featureCssPlacementRule = {
|
|
|
10713
10918
|
|
|
10714
10919
|
// eslint/rules/tailwind/global-stylesheet.ts
|
|
10715
10920
|
import { existsSync as existsSync11 } from "fs";
|
|
10716
|
-
import
|
|
10921
|
+
import path72 from "path";
|
|
10717
10922
|
var MISSING_REGISTRATION = 'Global stylesheet must register Tailwind with @import "tailwindcss".';
|
|
10718
10923
|
var MISSING_ENTRYPOINT = "Project CSS must have a canonical global stylesheet at src/app/styles/globals.css.";
|
|
10719
10924
|
var globalStylesheetRule = {
|
|
@@ -10727,11 +10932,11 @@ var globalStylesheetRule = {
|
|
|
10727
10932
|
},
|
|
10728
10933
|
create(context) {
|
|
10729
10934
|
const sourceRoot = sourceRootOf(context);
|
|
10730
|
-
const entryPoint =
|
|
10731
|
-
const current =
|
|
10935
|
+
const entryPoint = path72.normalize(path72.join(sourceRoot, "app", "styles", "globals.css"));
|
|
10936
|
+
const current = path72.normalize(path72.resolve(context.filename));
|
|
10732
10937
|
const isEntryPoint = current === entryPoint;
|
|
10733
10938
|
const hasEntryPoint = existsSync11(entryPoint);
|
|
10734
|
-
const isFirstStylesheet = !hasEntryPoint && [current, ...findFiles(sourceRoot, CSS_EXTENSIONS).map((file) =>
|
|
10939
|
+
const isFirstStylesheet = !hasEntryPoint && [current, ...findFiles(sourceRoot, CSS_EXTENSIONS).map((file) => path72.normalize(file))].sort()[0] === current;
|
|
10735
10940
|
if (!isEntryPoint && !isFirstStylesheet) return {};
|
|
10736
10941
|
return {
|
|
10737
10942
|
"StyleSheet:exit"(node) {
|
|
@@ -10791,7 +10996,7 @@ var noUtilityAliasRule = {
|
|
|
10791
10996
|
};
|
|
10792
10997
|
|
|
10793
10998
|
// eslint/rules/tailwind/root-variables.ts
|
|
10794
|
-
import
|
|
10999
|
+
import path73 from "path";
|
|
10795
11000
|
import { parse as parse6, walk as walk3 } from "@eslint/css-tree";
|
|
10796
11001
|
|
|
10797
11002
|
// eslint/rules/tailwind/external-mapping.ts
|
|
@@ -10818,13 +11023,13 @@ var rootVariablesRule = {
|
|
|
10818
11023
|
},
|
|
10819
11024
|
create(context) {
|
|
10820
11025
|
const sourceRoot = sourceRootOf(context);
|
|
10821
|
-
const current =
|
|
11026
|
+
const current = path73.normalize(path73.resolve(context.filename));
|
|
10822
11027
|
const textOf = cachedTextReader();
|
|
10823
11028
|
const stylesheets = findFiles(sourceRoot, CSS_EXTENSIONS);
|
|
10824
11029
|
const graph = buildCssDependencyGraph({
|
|
10825
11030
|
sourceRoot,
|
|
10826
11031
|
css: [
|
|
10827
|
-
...stylesheets.filter((file) =>
|
|
11032
|
+
...stylesheets.filter((file) => path73.normalize(file) !== current).map((file) => ({ path: file, content: textOf(file) })),
|
|
10828
11033
|
{ path: current, content: context.sourceCode.text }
|
|
10829
11034
|
],
|
|
10830
11035
|
modules: [],
|
|
@@ -10853,8 +11058,8 @@ var rootVariablesRule = {
|
|
|
10853
11058
|
});
|
|
10854
11059
|
}
|
|
10855
11060
|
const mirroredTokens = /* @__PURE__ */ new Set();
|
|
10856
|
-
for (const file of [...stylesheets.filter((candidate) =>
|
|
10857
|
-
const source = (
|
|
11061
|
+
for (const file of [...stylesheets.filter((candidate) => path73.normalize(candidate) !== current), current]) {
|
|
11062
|
+
const source = (path73.normalize(file) === current ? context.sourceCode.text : textOf(file)).replace(
|
|
10858
11063
|
/\/\*[\s\S]*?\*\//gu,
|
|
10859
11064
|
" "
|
|
10860
11065
|
);
|
|
@@ -10874,8 +11079,8 @@ var rootVariablesRule = {
|
|
|
10874
11079
|
}
|
|
10875
11080
|
const authoredVariables = new Set(names);
|
|
10876
11081
|
const variantNames = /* @__PURE__ */ new Set();
|
|
10877
|
-
for (const file of [...stylesheets.filter((candidate) =>
|
|
10878
|
-
const css2 =
|
|
11082
|
+
for (const file of [...stylesheets.filter((candidate) => path73.normalize(candidate) !== current), current]) {
|
|
11083
|
+
const css2 = path73.normalize(file) === current ? context.sourceCode.text : textOf(file);
|
|
10879
11084
|
const tree = parse6(css2, { parseAtrulePrelude: false });
|
|
10880
11085
|
let variantDepth = 0;
|
|
10881
11086
|
walk3(tree, {
|
|
@@ -10984,7 +11189,7 @@ var rootVariablesRule = {
|
|
|
10984
11189
|
};
|
|
10985
11190
|
|
|
10986
11191
|
// eslint/rules/tailwind/stylesheet-ordering.ts
|
|
10987
|
-
import
|
|
11192
|
+
import path74 from "path";
|
|
10988
11193
|
import { generate as generate3 } from "@eslint/css-tree";
|
|
10989
11194
|
var SECTION_ORDER = [
|
|
10990
11195
|
"Tailwind import",
|
|
@@ -11031,8 +11236,8 @@ var stylesheetOrderingRule = {
|
|
|
11031
11236
|
},
|
|
11032
11237
|
create(context) {
|
|
11033
11238
|
const sourceRoot = sourceRootOf(context);
|
|
11034
|
-
const entryPoint =
|
|
11035
|
-
if (
|
|
11239
|
+
const entryPoint = path74.normalize(path74.join(sourceRoot, "app", "styles", "globals.css"));
|
|
11240
|
+
if (path74.normalize(path74.resolve(context.filename)) !== entryPoint) return {};
|
|
11036
11241
|
return {
|
|
11037
11242
|
"StyleSheet:exit"(node) {
|
|
11038
11243
|
const topLevel = [...node.children];
|
|
@@ -11104,7 +11309,7 @@ var stylesheetOrderingRule = {
|
|
|
11104
11309
|
};
|
|
11105
11310
|
|
|
11106
11311
|
// eslint/rules/tailwind/theme-mode.ts
|
|
11107
|
-
import
|
|
11312
|
+
import path75 from "path";
|
|
11108
11313
|
import { generate as generate4 } from "@eslint/css-tree";
|
|
11109
11314
|
var MODE_NAME = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
|
|
11110
11315
|
var MODE_REFERENCE = /(?:^|[^a-z0-9-])(?<name>[a-z][a-z0-9]*(?:-[a-z0-9]+)*):(?=[a-z[(])/gu;
|
|
@@ -11143,9 +11348,9 @@ var themeModeRule = {
|
|
|
11143
11348
|
},
|
|
11144
11349
|
create(context) {
|
|
11145
11350
|
const sourceRoot = sourceRootOf(context);
|
|
11146
|
-
const current =
|
|
11147
|
-
const globalFile =
|
|
11148
|
-
if (
|
|
11351
|
+
const current = path75.normalize(path75.resolve(context.filename));
|
|
11352
|
+
const globalFile = path75.normalize(path75.join(sourceRoot, "app", "styles", "globals.css"));
|
|
11353
|
+
if (path75.dirname(current) !== path75.dirname(globalFile)) return {};
|
|
11149
11354
|
const read = cachedTextReader();
|
|
11150
11355
|
return {
|
|
11151
11356
|
"StyleSheet:exit"(node) {
|
|
@@ -11226,7 +11431,7 @@ var themeModeRule = {
|
|
|
11226
11431
|
};
|
|
11227
11432
|
|
|
11228
11433
|
// eslint/rules/tailwind/theme-reset.ts
|
|
11229
|
-
import
|
|
11434
|
+
import path76 from "path";
|
|
11230
11435
|
import { generate as generate5 } from "@eslint/css-tree";
|
|
11231
11436
|
function isThemeReset(node) {
|
|
11232
11437
|
if (!node) return false;
|
|
@@ -11255,9 +11460,9 @@ var themeResetRule = {
|
|
|
11255
11460
|
},
|
|
11256
11461
|
create(context) {
|
|
11257
11462
|
const sourceRoot = sourceRootOf(context);
|
|
11258
|
-
const current =
|
|
11259
|
-
const entryPoint =
|
|
11260
|
-
if (
|
|
11463
|
+
const current = path76.normalize(path76.resolve(context.filename));
|
|
11464
|
+
const entryPoint = path76.normalize(path76.join(sourceRoot, "app", "styles", "globals.css"));
|
|
11465
|
+
if (path76.dirname(current) !== path76.dirname(entryPoint)) return {};
|
|
11261
11466
|
return {
|
|
11262
11467
|
"StyleSheet:exit"(node) {
|
|
11263
11468
|
const hasReset = hasThemeReset(node);
|
|
@@ -11282,7 +11487,7 @@ var themeResetRule = {
|
|
|
11282
11487
|
};
|
|
11283
11488
|
|
|
11284
11489
|
// eslint/rules/tailwind/unique-css-definition.ts
|
|
11285
|
-
import
|
|
11490
|
+
import path77 from "path";
|
|
11286
11491
|
function ownershipKey(symbol) {
|
|
11287
11492
|
if (symbol.kind === "selector") return void 0;
|
|
11288
11493
|
if (symbol.kind === "root-variable" && symbol.scope !== "default") return void 0;
|
|
@@ -11314,7 +11519,7 @@ var uniqueCssDefinitionRule = {
|
|
|
11314
11519
|
},
|
|
11315
11520
|
create(context) {
|
|
11316
11521
|
const sourceRoot = sourceRootOf(context);
|
|
11317
|
-
const current =
|
|
11522
|
+
const current = path77.normalize(path77.resolve(context.filename));
|
|
11318
11523
|
const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
|
|
11319
11524
|
if (cssFiles.length === 0) return {};
|
|
11320
11525
|
const textOf = cachedTextReader();
|
|
@@ -11322,7 +11527,7 @@ var uniqueCssDefinitionRule = {
|
|
|
11322
11527
|
sourceRoot,
|
|
11323
11528
|
css: cssFiles.map((file) => ({
|
|
11324
11529
|
path: file,
|
|
11325
|
-
content:
|
|
11530
|
+
content: path77.normalize(file) === current ? context.sourceCode.text : textOf(file)
|
|
11326
11531
|
})),
|
|
11327
11532
|
modules: [],
|
|
11328
11533
|
includeReferences: false
|
|
@@ -11344,7 +11549,7 @@ var uniqueCssDefinitionRule = {
|
|
|
11344
11549
|
if (!canonical) continue;
|
|
11345
11550
|
for (const symbol of definitions.slice(1)) {
|
|
11346
11551
|
if (symbol.file !== current) continue;
|
|
11347
|
-
const message = symbol.file === canonical.file ? `${symbolLabel(symbol)} "${symbol.name}" is defined more than once in this CSS file; define it only once.` : `${symbolLabel(symbol)} "${symbol.name}" is also defined in ${
|
|
11552
|
+
const message = symbol.file === canonical.file ? `${symbolLabel(symbol)} "${symbol.name}" is defined more than once in this CSS file; define it only once.` : `${symbolLabel(symbol)} "${symbol.name}" is also defined in ${path77.relative(sourceRoot, canonical.file)}; define it in only one CSS file.`;
|
|
11348
11553
|
context.report({
|
|
11349
11554
|
node,
|
|
11350
11555
|
loc: {
|
|
@@ -11361,7 +11566,7 @@ var uniqueCssDefinitionRule = {
|
|
|
11361
11566
|
};
|
|
11362
11567
|
|
|
11363
11568
|
// eslint/rules/tailwind/unique-css-token-value.ts
|
|
11364
|
-
import
|
|
11569
|
+
import path78 from "path";
|
|
11365
11570
|
|
|
11366
11571
|
// eslint/rules/tailwind/css-named-colors.ts
|
|
11367
11572
|
var CSS_NAMED_COLORS = {
|
|
@@ -11602,14 +11807,14 @@ var uniqueCssTokenValueRule = {
|
|
|
11602
11807
|
},
|
|
11603
11808
|
create(context) {
|
|
11604
11809
|
const sourceRoot = sourceRootOf(context);
|
|
11605
|
-
const current =
|
|
11810
|
+
const current = path78.normalize(path78.resolve(context.filename));
|
|
11606
11811
|
const textOf = cachedTextReader();
|
|
11607
11812
|
const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
|
|
11608
11813
|
const graph = buildCssDependencyGraph({
|
|
11609
11814
|
sourceRoot,
|
|
11610
11815
|
css: cssFiles.map((file) => ({
|
|
11611
11816
|
path: file,
|
|
11612
|
-
content:
|
|
11817
|
+
content: path78.normalize(file) === current ? context.sourceCode.text : textOf(file)
|
|
11613
11818
|
})),
|
|
11614
11819
|
modules: [],
|
|
11615
11820
|
includeReferences: false
|
|
@@ -11642,7 +11847,7 @@ var uniqueCssTokenValueRule = {
|
|
|
11642
11847
|
start: { line: definition.line, column: 1 },
|
|
11643
11848
|
end: { line: definition.line, column: 2 }
|
|
11644
11849
|
},
|
|
11645
|
-
message: `Token "${definition.name}" duplicates the value of "${original.name}" in ${
|
|
11850
|
+
message: `Token "${definition.name}" duplicates the value of "${original.name}" in ${path78.relative(
|
|
11646
11851
|
sourceRoot,
|
|
11647
11852
|
original.file
|
|
11648
11853
|
)}:${String(original.line)}; reuse one design token.`
|
|
@@ -11653,15 +11858,47 @@ var uniqueCssTokenValueRule = {
|
|
|
11653
11858
|
}
|
|
11654
11859
|
};
|
|
11655
11860
|
|
|
11656
|
-
// eslint/rules/tailwind/unused-
|
|
11861
|
+
// eslint/rules/tailwind/unused-css-definition.ts
|
|
11657
11862
|
import { statSync as statSync5 } from "fs";
|
|
11658
|
-
import
|
|
11659
|
-
|
|
11863
|
+
import path79 from "path";
|
|
11864
|
+
function isImplicitThemeToken(name) {
|
|
11865
|
+
return name === "--spacing" || name === "--radius" || name === "--font-sans" || name === "--font-mono" || name.startsWith("--breakpoint-") || name.startsWith("--default-");
|
|
11866
|
+
}
|
|
11867
|
+
function staticMention(content, name) {
|
|
11868
|
+
const pattern = new RegExp(`(?<![\\w-])${escapeRegExp(name)}(?![\\w-])`, "u");
|
|
11869
|
+
return pattern.test(content);
|
|
11870
|
+
}
|
|
11871
|
+
function isUnused(symbol, references, moduleContents) {
|
|
11872
|
+
if (symbol.kind === "utility") {
|
|
11873
|
+
return !references.some((reference) => reference.kind === "utility" && reference.name === symbol.name);
|
|
11874
|
+
}
|
|
11875
|
+
if (symbol.kind === "keyframes") {
|
|
11876
|
+
return !references.some((reference) => reference.kind === "keyframes" && reference.name === symbol.name);
|
|
11877
|
+
}
|
|
11878
|
+
if (symbol.kind !== "theme-token" || isImplicitThemeToken(symbol.name)) return false;
|
|
11879
|
+
if (references.some((reference) => reference.kind === "theme-class" && reference.token === symbol.name)) {
|
|
11880
|
+
return false;
|
|
11881
|
+
}
|
|
11882
|
+
if (references.some((reference) => reference.kind === "variable" && reference.name === symbol.name)) {
|
|
11883
|
+
return false;
|
|
11884
|
+
}
|
|
11885
|
+
return !moduleContents.some((content) => staticMention(content, symbol.name));
|
|
11886
|
+
}
|
|
11887
|
+
function unusedMessage(symbol) {
|
|
11888
|
+
if (symbol.kind === "utility") {
|
|
11889
|
+
return `Custom utility "${symbol.name}" is never referenced by project CSS or source.`;
|
|
11890
|
+
}
|
|
11891
|
+
if (symbol.kind === "keyframes") {
|
|
11892
|
+
return `@keyframes "${symbol.name}" is never referenced by project CSS or source.`;
|
|
11893
|
+
}
|
|
11894
|
+
return `Theme token "${symbol.name}" is never referenced by project CSS or source.`;
|
|
11895
|
+
}
|
|
11896
|
+
var unusedCssDefinitionRule = {
|
|
11660
11897
|
meta: {
|
|
11661
11898
|
schema: [],
|
|
11662
11899
|
type: "problem",
|
|
11663
11900
|
docs: {
|
|
11664
|
-
description: "
|
|
11901
|
+
description: "Report unused @utility, @keyframes and non-foundational @theme tokens across project CSS and modules."
|
|
11665
11902
|
}
|
|
11666
11903
|
},
|
|
11667
11904
|
create(context) {
|
|
@@ -11671,27 +11908,35 @@ var unusedUtilityRule = {
|
|
|
11671
11908
|
} catch {
|
|
11672
11909
|
return {};
|
|
11673
11910
|
}
|
|
11674
|
-
const current =
|
|
11911
|
+
const current = path79.normalize(path79.resolve(context.filename));
|
|
11675
11912
|
const textOf = cachedTextReader();
|
|
11676
11913
|
const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
|
|
11677
|
-
const
|
|
11914
|
+
const moduleContents = findFiles(sourceRoot, MODULE_EXTENSIONS4).map((file) => ({
|
|
11915
|
+
path: file,
|
|
11916
|
+
content: textOf(file)
|
|
11917
|
+
}));
|
|
11678
11918
|
const graph = buildCssDependencyGraph({
|
|
11679
11919
|
sourceRoot,
|
|
11680
11920
|
css: cssFiles.map((file) => ({
|
|
11681
11921
|
path: file,
|
|
11682
|
-
content:
|
|
11922
|
+
content: path79.normalize(file) === current ? context.sourceCode.text : textOf(file)
|
|
11683
11923
|
})),
|
|
11684
|
-
modules:
|
|
11924
|
+
modules: moduleContents
|
|
11685
11925
|
});
|
|
11926
|
+
const sourceTexts = moduleContents.map((module) => module.content);
|
|
11927
|
+
const unused = graph.definitions.filter(
|
|
11928
|
+
(symbol) => symbol.file === current && isUnused(symbol, graph.references, sourceTexts)
|
|
11929
|
+
);
|
|
11686
11930
|
return {
|
|
11687
11931
|
"StyleSheet:exit"(node) {
|
|
11688
|
-
for (const
|
|
11689
|
-
const name = preludeIdentifiers(utility)[0];
|
|
11690
|
-
if (!name) continue;
|
|
11691
|
-
if (cssSymbolUsages(graph, "utility", name).length > 0) continue;
|
|
11932
|
+
for (const symbol of unused) {
|
|
11692
11933
|
context.report({
|
|
11693
|
-
node
|
|
11694
|
-
|
|
11934
|
+
node,
|
|
11935
|
+
loc: {
|
|
11936
|
+
start: { line: symbol.line, column: 1 },
|
|
11937
|
+
end: { line: symbol.line, column: 2 }
|
|
11938
|
+
},
|
|
11939
|
+
message: unusedMessage(symbol)
|
|
11695
11940
|
});
|
|
11696
11941
|
}
|
|
11697
11942
|
}
|
|
@@ -11700,9 +11945,9 @@ var unusedUtilityRule = {
|
|
|
11700
11945
|
};
|
|
11701
11946
|
|
|
11702
11947
|
// eslint/rules/tailwind/utility-mapping.ts
|
|
11703
|
-
import { spawnSync } from "child_process";
|
|
11948
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
11704
11949
|
import { existsSync as existsSync12 } from "fs";
|
|
11705
|
-
import
|
|
11950
|
+
import path80 from "path";
|
|
11706
11951
|
function applyOperationCount(utility, textOf) {
|
|
11707
11952
|
let count = 0;
|
|
11708
11953
|
for (const apply of atrulesNamed(utility, "apply")) {
|
|
@@ -11823,7 +12068,7 @@ function themeSupportedGenerators(candidates, cwd) {
|
|
|
11823
12068
|
const cacheKey = (key) => `${cwd}\0${key}`;
|
|
11824
12069
|
const missing = [...unique].filter(([key]) => !generatorSupportCache.has(cacheKey(key)));
|
|
11825
12070
|
if (missing.length > 0) {
|
|
11826
|
-
const child =
|
|
12071
|
+
const child = spawnSync2(process.execPath, ["--input-type=module", "--eval", THEME_GENERATOR_WORKER], {
|
|
11827
12072
|
cwd,
|
|
11828
12073
|
input: JSON.stringify(missing.map(([, candidate]) => candidate)),
|
|
11829
12074
|
encoding: "utf8",
|
|
@@ -12057,13 +12302,13 @@ var utilityMappingRule = {
|
|
|
12057
12302
|
},
|
|
12058
12303
|
create(context) {
|
|
12059
12304
|
const sourceRoot = sourceRootOf(context);
|
|
12060
|
-
const current =
|
|
12305
|
+
const current = path80.normalize(path80.resolve(context.filename));
|
|
12061
12306
|
const textOf = cachedTextReader();
|
|
12062
12307
|
const graph = buildCssDependencyGraph({
|
|
12063
12308
|
sourceRoot,
|
|
12064
12309
|
css: findFiles(sourceRoot, CSS_EXTENSIONS).map((file) => ({
|
|
12065
12310
|
path: file,
|
|
12066
|
-
content:
|
|
12311
|
+
content: path80.normalize(file) === current ? context.sourceCode.text : textOf(file)
|
|
12067
12312
|
})),
|
|
12068
12313
|
modules: [],
|
|
12069
12314
|
includeReferences: false
|
|
@@ -12125,6 +12370,10 @@ var utilityMappingRule = {
|
|
|
12125
12370
|
themeDefinitions.set(child.property, definitions);
|
|
12126
12371
|
}
|
|
12127
12372
|
}
|
|
12373
|
+
const classesByToken = themeClassesForTokens(
|
|
12374
|
+
[...projectTokens.map((token) => token.name), ...themeDefinitions.keys()],
|
|
12375
|
+
sourceRoot
|
|
12376
|
+
);
|
|
12128
12377
|
for (const cssRule of node.children) {
|
|
12129
12378
|
if (cssRule.type !== "Rule") continue;
|
|
12130
12379
|
if (context.sourceCode.getText(cssRule.prelude).trim() !== ":root") continue;
|
|
@@ -12203,7 +12452,8 @@ var utilityMappingRule = {
|
|
|
12203
12452
|
continue;
|
|
12204
12453
|
}
|
|
12205
12454
|
const generatedClass = `${candidate.prefix}-${token.name.slice(namespacePrefix.length)}`;
|
|
12206
|
-
|
|
12455
|
+
const generatesClass = (classesByToken.get(token.name) ?? []).includes(generatedClass);
|
|
12456
|
+
if (candidate.namespace === "color" && !generatesClass) continue;
|
|
12207
12457
|
return generatedClass;
|
|
12208
12458
|
}
|
|
12209
12459
|
return void 0;
|
|
@@ -12211,8 +12461,8 @@ var utilityMappingRule = {
|
|
|
12211
12461
|
const generatorCandidates = utilities.map(
|
|
12212
12462
|
(utility) => themeCandidate(preludeIdentifiers(utility)[0] ?? "unknown", context.sourceCode.getText(utility))
|
|
12213
12463
|
).filter((candidate) => Boolean(candidate && requiresGeneratorProbe(candidate)));
|
|
12214
|
-
const physicalDir =
|
|
12215
|
-
const tailwindCwd =
|
|
12464
|
+
const physicalDir = path80.dirname(context.physicalFilename);
|
|
12465
|
+
const tailwindCwd = path80.isAbsolute(physicalDir) && existsSync12(physicalDir) ? physicalDir : context.cwd;
|
|
12216
12466
|
const themeGenerators = themeSupportedGenerators(generatorCandidates, tailwindCwd);
|
|
12217
12467
|
for (const utility of utilities) {
|
|
12218
12468
|
const name = preludeIdentifiers(utility)[0] ?? "unknown";
|
|
@@ -12284,7 +12534,7 @@ var utilityMappingRule = {
|
|
|
12284
12534
|
if (only.type === "Atrule" && only.name === "apply") {
|
|
12285
12535
|
const alias = /^@apply\s+(?<name>[a-z][a-z0-9-]*)\s*;?$/u.exec(declarationText)?.groups?.name;
|
|
12286
12536
|
if (alias && [...projectTokens.map((token) => token.name), ...themeDefinitions.keys()].some(
|
|
12287
|
-
(name) =>
|
|
12537
|
+
(name) => (classesByToken.get(name) ?? []).includes(alias)
|
|
12288
12538
|
)) {
|
|
12289
12539
|
context.report({
|
|
12290
12540
|
node: cssNode,
|
|
@@ -12320,9 +12570,9 @@ var utilityMappingRule = {
|
|
|
12320
12570
|
};
|
|
12321
12571
|
|
|
12322
12572
|
// eslint/rules/tailwind/utility-name-parity.ts
|
|
12323
|
-
import { spawnSync as
|
|
12573
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
12324
12574
|
import { existsSync as existsSync13 } from "fs";
|
|
12325
|
-
import
|
|
12575
|
+
import path81 from "path";
|
|
12326
12576
|
import { generate as generate6, parse as parse7, toPlainObject as toPlainObject2 } from "@eslint/css-tree";
|
|
12327
12577
|
function numericPart(value) {
|
|
12328
12578
|
const match = /^(?<negative>-?)(?<number>(?:\d+(?:\.\d+)?|\.\d+))(?<unit>%|px|rem|em|vw|vh|dvw|dvh|ch|fr|s|ms|deg|turn)?$/u.exec(
|
|
@@ -12387,7 +12637,7 @@ function compileApplies(applies, cwd) {
|
|
|
12387
12637
|
const key = `${cwd}\0${JSON.stringify(applies)}`;
|
|
12388
12638
|
const cached = compilerCache.get(key);
|
|
12389
12639
|
if (cached) return cached;
|
|
12390
|
-
const child =
|
|
12640
|
+
const child = spawnSync3(process.execPath, ["--input-type=module", "--eval", TAILWIND_WORKER], {
|
|
12391
12641
|
cwd,
|
|
12392
12642
|
input: JSON.stringify(applies),
|
|
12393
12643
|
encoding: "utf8",
|
|
@@ -12466,8 +12716,8 @@ var utilityNameParityRule = {
|
|
|
12466
12716
|
return apply ? [{ utility, name, apply }] : [];
|
|
12467
12717
|
});
|
|
12468
12718
|
if (candidates.length === 0) return;
|
|
12469
|
-
const physicalDir =
|
|
12470
|
-
const cwd =
|
|
12719
|
+
const physicalDir = path81.dirname(context.physicalFilename);
|
|
12720
|
+
const cwd = path81.isAbsolute(physicalDir) && existsSync13(physicalDir) ? physicalDir : context.cwd;
|
|
12471
12721
|
const compiled = compileApplies(
|
|
12472
12722
|
candidates.map((candidate) => candidate.apply),
|
|
12473
12723
|
cwd
|
|
@@ -12528,14 +12778,14 @@ var tailwindRules = {
|
|
|
12528
12778
|
"css-entry-point": cssEntryPointRule,
|
|
12529
12779
|
"feature-css-placement": featureCssPlacementRule,
|
|
12530
12780
|
"global-stylesheet": globalStylesheetRule,
|
|
12531
|
-
"unused-
|
|
12781
|
+
"unused-css-definition": unusedCssDefinitionRule,
|
|
12532
12782
|
"unique-css-definition": uniqueCssDefinitionRule,
|
|
12533
12783
|
"unique-css-token-value": uniqueCssTokenValueRule,
|
|
12534
12784
|
"no-utility-alias": noUtilityAliasRule
|
|
12535
12785
|
};
|
|
12536
12786
|
|
|
12537
12787
|
// eslint/rules/type-extraction.ts
|
|
12538
|
-
import
|
|
12788
|
+
import path82 from "path";
|
|
12539
12789
|
var typeExtractionRule = {
|
|
12540
12790
|
meta: {
|
|
12541
12791
|
schema: [],
|
|
@@ -12546,7 +12796,7 @@ var typeExtractionRule = {
|
|
|
12546
12796
|
},
|
|
12547
12797
|
create(context) {
|
|
12548
12798
|
const sourceRoot = sourceRootOf(context);
|
|
12549
|
-
const file =
|
|
12799
|
+
const file = path82.resolve(context.filename);
|
|
12550
12800
|
const segments = segmentsOf(file, sourceRoot);
|
|
12551
12801
|
if (segments.length === 0) return {};
|
|
12552
12802
|
const index = getProjectIndex(sourceRoot);
|
|
@@ -12685,9 +12935,9 @@ var uiStateRule = {
|
|
|
12685
12935
|
};
|
|
12686
12936
|
|
|
12687
12937
|
// eslint/rules/unknown-utility.ts
|
|
12688
|
-
import { existsSync as existsSync14, readdirSync as readdirSync6, readFileSync as
|
|
12938
|
+
import { existsSync as existsSync14, readdirSync as readdirSync6, readFileSync as readFileSync16, statSync as statSync6 } from "fs";
|
|
12689
12939
|
import { createRequire } from "module";
|
|
12690
|
-
import
|
|
12940
|
+
import path83 from "path";
|
|
12691
12941
|
var PREFIX_NAMESPACES = {
|
|
12692
12942
|
bg: ["color", "background-image"],
|
|
12693
12943
|
text: ["color", "text"],
|
|
@@ -12975,7 +13225,7 @@ function stylesheetFiles(dir) {
|
|
|
12975
13225
|
}
|
|
12976
13226
|
return entries.flatMap((entry) => {
|
|
12977
13227
|
if (entry.startsWith(".") || entry === "node_modules") return [];
|
|
12978
|
-
const entryPath =
|
|
13228
|
+
const entryPath = path83.join(dir, entry);
|
|
12979
13229
|
let stats;
|
|
12980
13230
|
try {
|
|
12981
13231
|
stats = statSync6(entryPath);
|
|
@@ -12983,7 +13233,7 @@ function stylesheetFiles(dir) {
|
|
|
12983
13233
|
return [];
|
|
12984
13234
|
}
|
|
12985
13235
|
if (stats.isDirectory()) return stylesheetFiles(entryPath);
|
|
12986
|
-
return
|
|
13236
|
+
return path83.extname(entry) === ".css" ? [entryPath] : [];
|
|
12987
13237
|
});
|
|
12988
13238
|
}
|
|
12989
13239
|
function packageNameOf(specifier) {
|
|
@@ -12994,24 +13244,24 @@ function packageNameOf(specifier) {
|
|
|
12994
13244
|
function resolvePackageStylesheet(fromFile, specifier) {
|
|
12995
13245
|
const packageName = packageNameOf(specifier);
|
|
12996
13246
|
if (!packageName || packageName === "tailwindcss") return void 0;
|
|
12997
|
-
let directory =
|
|
12998
|
-
while (directory !==
|
|
12999
|
-
const packageRoot =
|
|
13000
|
-
const manifestPath =
|
|
13247
|
+
let directory = path83.dirname(fromFile);
|
|
13248
|
+
while (directory !== path83.dirname(directory)) {
|
|
13249
|
+
const packageRoot = path83.join(directory, "node_modules", packageName);
|
|
13250
|
+
const manifestPath = path83.join(packageRoot, "package.json");
|
|
13001
13251
|
if (existsSync14(manifestPath)) {
|
|
13002
13252
|
try {
|
|
13003
|
-
const manifest =
|
|
13253
|
+
const manifest = readFileSync16(manifestPath, "utf8");
|
|
13004
13254
|
const stylesheet = /"style"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
|
|
13005
13255
|
const main = /"main"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
|
|
13006
13256
|
const target = stylesheet ?? main;
|
|
13007
13257
|
if (!target) return void 0;
|
|
13008
|
-
const resolved =
|
|
13258
|
+
const resolved = path83.resolve(packageRoot, target);
|
|
13009
13259
|
return existsSync14(resolved) ? resolved : void 0;
|
|
13010
13260
|
} catch {
|
|
13011
13261
|
return void 0;
|
|
13012
13262
|
}
|
|
13013
13263
|
}
|
|
13014
|
-
directory =
|
|
13264
|
+
directory = path83.dirname(directory);
|
|
13015
13265
|
}
|
|
13016
13266
|
return void 0;
|
|
13017
13267
|
}
|
|
@@ -13020,7 +13270,7 @@ function inventoryStylesheetFiles(projectFiles) {
|
|
|
13020
13270
|
for (const file of projectFiles) {
|
|
13021
13271
|
let css2;
|
|
13022
13272
|
try {
|
|
13023
|
-
css2 =
|
|
13273
|
+
css2 = readFileSync16(file, "utf8");
|
|
13024
13274
|
} catch {
|
|
13025
13275
|
continue;
|
|
13026
13276
|
}
|
|
@@ -13087,7 +13337,7 @@ function readInventory(files) {
|
|
|
13087
13337
|
for (const file of files) {
|
|
13088
13338
|
let css2;
|
|
13089
13339
|
try {
|
|
13090
|
-
css2 =
|
|
13340
|
+
css2 = readFileSync16(file, "utf8");
|
|
13091
13341
|
} catch {
|
|
13092
13342
|
continue;
|
|
13093
13343
|
}
|
|
@@ -13292,7 +13542,7 @@ var unknownUtilityRule = {
|
|
|
13292
13542
|
};
|
|
13293
13543
|
|
|
13294
13544
|
// eslint/rules/util-file-name.ts
|
|
13295
|
-
import
|
|
13545
|
+
import path84 from "path";
|
|
13296
13546
|
function toKebabCase2(value) {
|
|
13297
13547
|
return value.replace(/(?<lower>[a-z0-9])(?<upper>[A-Z])/g, "$<lower>-$<upper>").replace(/(?<first>[A-Z])(?<rest>[A-Z][a-z])/g, "$<first>-$<rest>").toLowerCase();
|
|
13298
13548
|
}
|
|
@@ -13305,7 +13555,7 @@ var utilFileNameRule = {
|
|
|
13305
13555
|
}
|
|
13306
13556
|
},
|
|
13307
13557
|
create(context) {
|
|
13308
|
-
const filename =
|
|
13558
|
+
const filename = path84.resolve(context.filename);
|
|
13309
13559
|
const segments = filename.replace(/\\/g, "/").split("/");
|
|
13310
13560
|
if (!segments.includes("utils")) return {};
|
|
13311
13561
|
let module;
|
|
@@ -13319,13 +13569,13 @@ var utilFileNameRule = {
|
|
|
13319
13569
|
const functionName = functions[0]?.name;
|
|
13320
13570
|
if (!functionName) return {};
|
|
13321
13571
|
const expected = toKebabCase2(functionName);
|
|
13322
|
-
const actual =
|
|
13572
|
+
const actual = path84.basename(filename, path84.extname(filename));
|
|
13323
13573
|
if (!expected || actual === expected) return {};
|
|
13324
13574
|
return {
|
|
13325
13575
|
Program(node) {
|
|
13326
13576
|
context.report({
|
|
13327
13577
|
node,
|
|
13328
|
-
message: `A utility file exporting ${functionName} must be named ${expected}.${
|
|
13578
|
+
message: `A utility file exporting ${functionName} must be named ${expected}.${path84.extname(filename).slice(1)}.`
|
|
13329
13579
|
});
|
|
13330
13580
|
}
|
|
13331
13581
|
};
|
|
@@ -13333,7 +13583,7 @@ var utilFileNameRule = {
|
|
|
13333
13583
|
};
|
|
13334
13584
|
|
|
13335
13585
|
// eslint/rules/value-extraction.ts
|
|
13336
|
-
import
|
|
13586
|
+
import path85 from "path";
|
|
13337
13587
|
var valueExtractionRule = {
|
|
13338
13588
|
meta: {
|
|
13339
13589
|
schema: [],
|
|
@@ -13344,7 +13594,7 @@ var valueExtractionRule = {
|
|
|
13344
13594
|
},
|
|
13345
13595
|
create(context) {
|
|
13346
13596
|
const sourceRoot = sourceRootOf(context);
|
|
13347
|
-
const file =
|
|
13597
|
+
const file = path85.resolve(context.filename);
|
|
13348
13598
|
const segments = segmentsOf(file, sourceRoot);
|
|
13349
13599
|
if (segments.length === 0 || segments[0] !== "app") return {};
|
|
13350
13600
|
const index = getProjectIndex(sourceRoot);
|
|
@@ -13365,8 +13615,8 @@ var valueExtractionRule = {
|
|
|
13365
13615
|
};
|
|
13366
13616
|
|
|
13367
13617
|
// eslint/rules/vulyk/tracked-docs.ts
|
|
13368
|
-
import { existsSync as existsSync15, readFileSync as
|
|
13369
|
-
import
|
|
13618
|
+
import { existsSync as existsSync15, readFileSync as readFileSync17 } from "fs";
|
|
13619
|
+
import path86 from "path";
|
|
13370
13620
|
var PASIKA_REPO = "Bredansky/pasika";
|
|
13371
13621
|
var BASE_REQUIRED_TRACKED_DOCS = [
|
|
13372
13622
|
{ name: "documentation-guide", path: "docs/documentation-guide" },
|
|
@@ -13399,8 +13649,8 @@ var trackedDocsRule = {
|
|
|
13399
13649
|
if (!context.filename.endsWith("package.json")) return;
|
|
13400
13650
|
const root = node.body;
|
|
13401
13651
|
if (root.type !== "Object") return;
|
|
13402
|
-
const projectRoot =
|
|
13403
|
-
const configPath =
|
|
13652
|
+
const projectRoot = path86.dirname(path86.resolve(context.filename));
|
|
13653
|
+
const configPath = path86.join(projectRoot, "vulyk.config.ts");
|
|
13404
13654
|
if (!existsSync15(configPath)) {
|
|
13405
13655
|
context.report({
|
|
13406
13656
|
node,
|
|
@@ -13408,7 +13658,7 @@ var trackedDocsRule = {
|
|
|
13408
13658
|
});
|
|
13409
13659
|
return;
|
|
13410
13660
|
}
|
|
13411
|
-
const config =
|
|
13661
|
+
const config = readFileSync17(configPath, "utf8");
|
|
13412
13662
|
if (!config.includes(PASIKA_REPO)) {
|
|
13413
13663
|
context.report({
|
|
13414
13664
|
node,
|
|
@@ -13425,7 +13675,7 @@ var trackedDocsRule = {
|
|
|
13425
13675
|
});
|
|
13426
13676
|
}
|
|
13427
13677
|
}
|
|
13428
|
-
const agentsPath =
|
|
13678
|
+
const agentsPath = path86.join(projectRoot, "AGENTS.md");
|
|
13429
13679
|
if (!existsSync15(agentsPath)) {
|
|
13430
13680
|
context.report({
|
|
13431
13681
|
node,
|
|
@@ -13525,7 +13775,7 @@ var withResponseHelperRule = {
|
|
|
13525
13775
|
|
|
13526
13776
|
// eslint/rules/zirka-baseline.ts
|
|
13527
13777
|
import fs7 from "fs";
|
|
13528
|
-
import
|
|
13778
|
+
import path87 from "path";
|
|
13529
13779
|
var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
|
|
13530
13780
|
var PRETTIER_CONFIGS = [
|
|
13531
13781
|
"prettier.config.mjs",
|
|
@@ -13544,10 +13794,10 @@ var zirkaBaselineRule = {
|
|
|
13544
13794
|
}
|
|
13545
13795
|
},
|
|
13546
13796
|
create(context) {
|
|
13547
|
-
const filename =
|
|
13548
|
-
const basename =
|
|
13797
|
+
const filename = path87.resolve(context.filename);
|
|
13798
|
+
const basename = path87.basename(filename);
|
|
13549
13799
|
if (!ESLINT_CONFIG.test(basename)) return {};
|
|
13550
|
-
const projectRoot =
|
|
13800
|
+
const projectRoot = path87.dirname(filename);
|
|
13551
13801
|
const report3 = (message) => {
|
|
13552
13802
|
context.report({
|
|
13553
13803
|
node: context.sourceCode.ast,
|
|
@@ -13562,7 +13812,7 @@ var zirkaBaselineRule = {
|
|
|
13562
13812
|
'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
|
|
13563
13813
|
);
|
|
13564
13814
|
}
|
|
13565
|
-
const tsconfigPath =
|
|
13815
|
+
const tsconfigPath = path87.join(projectRoot, "tsconfig.json");
|
|
13566
13816
|
if (!fs7.existsSync(tsconfigPath)) {
|
|
13567
13817
|
report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
|
|
13568
13818
|
} else {
|
|
@@ -13580,13 +13830,13 @@ var zirkaBaselineRule = {
|
|
|
13580
13830
|
report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
|
|
13581
13831
|
}
|
|
13582
13832
|
}
|
|
13583
|
-
const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(
|
|
13833
|
+
const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path87.join(projectRoot, name)));
|
|
13584
13834
|
if (!prettierConfigFile) {
|
|
13585
13835
|
report3(
|
|
13586
13836
|
"No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
|
|
13587
13837
|
);
|
|
13588
13838
|
} else {
|
|
13589
|
-
const content = fs7.readFileSync(
|
|
13839
|
+
const content = fs7.readFileSync(path87.join(projectRoot, prettierConfigFile), "utf8");
|
|
13590
13840
|
if (!content.includes("zirka")) {
|
|
13591
13841
|
report3(
|
|
13592
13842
|
"The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
|
|
@@ -13732,14 +13982,14 @@ var zodSchemaValidationRule = {
|
|
|
13732
13982
|
};
|
|
13733
13983
|
|
|
13734
13984
|
// eslint/ts-alignment.ts
|
|
13735
|
-
import { readFileSync as
|
|
13985
|
+
import { readFileSync as readFileSync18 } from "fs";
|
|
13736
13986
|
import { createRequire as createRequire2 } from "module";
|
|
13737
13987
|
import { join } from "path";
|
|
13738
13988
|
var ownRequire = createRequire2(import.meta.url);
|
|
13739
13989
|
var majorOf = (version) => Number(version.split(".")[0]);
|
|
13740
13990
|
function versionOf(packagePath) {
|
|
13741
13991
|
try {
|
|
13742
|
-
const parsed = JSON.parse(
|
|
13992
|
+
const parsed = JSON.parse(readFileSync18(packagePath, "utf8"));
|
|
13743
13993
|
if (typeof parsed !== "object" || parsed === null || !("version" in parsed)) return null;
|
|
13744
13994
|
return typeof parsed.version === "string" ? parsed.version : null;
|
|
13745
13995
|
} catch {
|
|
@@ -13936,6 +14186,7 @@ var tailwindImportGraph = {
|
|
|
13936
14186
|
languageOptions: { tolerant: true },
|
|
13937
14187
|
rules: {
|
|
13938
14188
|
"pasika/at-rule-spacing": "error",
|
|
14189
|
+
"pasika/unused-css-definition": "error",
|
|
13939
14190
|
"pasika/css-entry-point": "error",
|
|
13940
14191
|
"pasika/feature-css-placement": "error",
|
|
13941
14192
|
"pasika/unique-css-definition": "error",
|