pasika 0.10.107 → 0.10.109
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.js +142 -38
- package/package.json +1 -1
|
@@ -9143,7 +9143,7 @@ function isHookUsage(node, hook) {
|
|
|
9143
9143
|
}
|
|
9144
9144
|
if (ts15.isIdentifier(node) && node.text === hook.value) {
|
|
9145
9145
|
const parent = node.parent;
|
|
9146
|
-
if (ts15.isBindingElement(parent) || ts15.isPropertyAccessExpression(parent) || ts15.
|
|
9146
|
+
if (ts15.isBindingElement(parent) && parent.name === node || ts15.isVariableDeclaration(parent) && parent.name === node || ts15.isParameter(parent) && parent.name === node || ts15.isPropertyAccessExpression(parent) && parent.name === node || ts15.isPropertyAssignment(parent) && parent.name === node) {
|
|
9147
9147
|
return void 0;
|
|
9148
9148
|
}
|
|
9149
9149
|
return "value";
|
|
@@ -9168,19 +9168,77 @@ function topLevelJsxChildren(initial) {
|
|
|
9168
9168
|
}
|
|
9169
9169
|
return void 0;
|
|
9170
9170
|
}
|
|
9171
|
-
function
|
|
9172
|
-
|
|
9171
|
+
function isSimpleDerivedExpression(node) {
|
|
9172
|
+
if (ts15.isNewExpression(node) || ts15.isAwaitExpression(node) || ts15.isYieldExpression(node) || ts15.isDeleteExpression(node) || ts15.isTaggedTemplateExpression(node) || ts15.isBlock(node)) {
|
|
9173
|
+
return false;
|
|
9174
|
+
}
|
|
9175
|
+
if (ts15.isCallExpression(node)) {
|
|
9176
|
+
const callee = node.expression;
|
|
9177
|
+
if (!ts15.isPropertyAccessExpression(callee) || !(/* @__PURE__ */ new Set(["filter", "map", "find", "findIndex", "some", "every", "slice", "includes"])).has(callee.name.text)) {
|
|
9178
|
+
return false;
|
|
9179
|
+
}
|
|
9180
|
+
}
|
|
9181
|
+
if (ts15.isArrowFunction(node) && ts15.isBlock(node.body)) return false;
|
|
9182
|
+
if (ts15.isBinaryExpression(node)) {
|
|
9183
|
+
const operator = node.operatorToken.kind;
|
|
9184
|
+
if (operator >= ts15.SyntaxKind.FirstAssignment && operator <= ts15.SyntaxKind.LastAssignment) return false;
|
|
9185
|
+
}
|
|
9186
|
+
if ((ts15.isPrefixUnaryExpression(node) || ts15.isPostfixUnaryExpression(node)) && (node.operator === ts15.SyntaxKind.PlusPlusToken || node.operator === ts15.SyntaxKind.MinusMinusToken)) {
|
|
9187
|
+
return false;
|
|
9188
|
+
}
|
|
9189
|
+
let safe = true;
|
|
9190
|
+
ts15.forEachChild(node, (child) => {
|
|
9191
|
+
if (!isSimpleDerivedExpression(child)) safe = false;
|
|
9192
|
+
});
|
|
9193
|
+
return safe;
|
|
9194
|
+
}
|
|
9195
|
+
function isIdentifierRead(node, names) {
|
|
9196
|
+
if (!ts15.isIdentifier(node) || !names.has(node.text)) return false;
|
|
9197
|
+
const parent = node.parent;
|
|
9198
|
+
return !(ts15.isBindingElement(parent) && parent.name === node || ts15.isVariableDeclaration(parent) && parent.name === node || ts15.isParameter(parent) && parent.name === node || ts15.isPropertyAccessExpression(parent) && parent.name === node || ts15.isPropertyAssignment(parent) && parent.name === node);
|
|
9199
|
+
}
|
|
9200
|
+
function containsNamedRead(node, names) {
|
|
9201
|
+
if (isIdentifierRead(node, names)) return true;
|
|
9202
|
+
return ts15.forEachChild(node, (child) => containsNamedRead(child, names)) ?? false;
|
|
9203
|
+
}
|
|
9204
|
+
function findDerivedState(body, hook) {
|
|
9205
|
+
const names = /* @__PURE__ */ new Set([hook.value]);
|
|
9206
|
+
const allowedInitializers = /* @__PURE__ */ new Set();
|
|
9207
|
+
for (const statement of body.statements) {
|
|
9208
|
+
if (!ts15.isVariableStatement(statement) || statement.declarationList.flags !== ts15.NodeFlags.Const) continue;
|
|
9209
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
9210
|
+
if (!ts15.isIdentifier(declaration.name) || !declaration.initializer) continue;
|
|
9211
|
+
if (!containsNamedRead(declaration.initializer, names)) continue;
|
|
9212
|
+
if (!isSimpleDerivedExpression(declaration.initializer)) continue;
|
|
9213
|
+
names.add(declaration.name.text);
|
|
9214
|
+
allowedInitializers.add(declaration.initializer);
|
|
9215
|
+
}
|
|
9216
|
+
}
|
|
9217
|
+
return { names, allowedInitializers };
|
|
9218
|
+
}
|
|
9219
|
+
function isTrackedUse(node, hook, names) {
|
|
9220
|
+
return isHookUsage(node, hook) !== void 0 || isIdentifierRead(node, names);
|
|
9221
|
+
}
|
|
9222
|
+
function countUsesIn(child, hook, names) {
|
|
9173
9223
|
let count = 0;
|
|
9174
9224
|
const visit = (node) => {
|
|
9175
|
-
if (
|
|
9176
|
-
positions.push(node);
|
|
9177
|
-
count += 1;
|
|
9178
|
-
}
|
|
9225
|
+
if (isTrackedUse(node, hook, names)) count += 1;
|
|
9179
9226
|
if (ts15.isFunctionDeclaration(node) || ts15.isClassDeclaration(node)) return;
|
|
9180
9227
|
ts15.forEachChild(node, visit);
|
|
9181
9228
|
};
|
|
9182
9229
|
visit(child);
|
|
9183
|
-
return
|
|
9230
|
+
return count;
|
|
9231
|
+
}
|
|
9232
|
+
function jsxChildren(node) {
|
|
9233
|
+
if (ts15.isJsxElement(node) || ts15.isJsxFragment(node)) {
|
|
9234
|
+
return [...node.children].filter((child) => !ts15.isJsxText(child));
|
|
9235
|
+
}
|
|
9236
|
+
return void 0;
|
|
9237
|
+
}
|
|
9238
|
+
function isDecorativeSeparator(node) {
|
|
9239
|
+
if (!ts15.isJsxSelfClosingElement(node) && !ts15.isJsxElement(node)) return false;
|
|
9240
|
+
const tagName2 = ts15.isJsxElement(node) ? node.openingElement.tagName : node.tagName;
|
|
9241
|
+
return /(?:Divider|Separator)$/.test(tagName2.getText());
|
|
9184
9242
|
}
|
|
9185
9243
|
var soleStateOwnerRule = {
|
|
9186
9244
|
meta: {
|
|
@@ -9226,42 +9284,54 @@ function analyzeSoleOwner(declaration, hook) {
|
|
|
9226
9284
|
};
|
|
9227
9285
|
visit(body);
|
|
9228
9286
|
if (returns.length !== 1) return void 0;
|
|
9229
|
-
const
|
|
9230
|
-
if (!
|
|
9231
|
-
const
|
|
9232
|
-
|
|
9233
|
-
|
|
9234
|
-
|
|
9235
|
-
const
|
|
9236
|
-
|
|
9237
|
-
|
|
9238
|
-
|
|
9239
|
-
|
|
9240
|
-
|
|
9241
|
-
|
|
9242
|
-
|
|
9243
|
-
|
|
9244
|
-
|
|
9245
|
-
|
|
9246
|
-
|
|
9247
|
-
|
|
9248
|
-
|
|
9249
|
-
|
|
9287
|
+
const expression = returns[0]?.expression;
|
|
9288
|
+
if (!expression || !ts15.isExpression(expression)) return void 0;
|
|
9289
|
+
const root = topLevelJsxChildren(expression);
|
|
9290
|
+
if (!root) return void 0;
|
|
9291
|
+
const derived = findDerivedState(body, hook);
|
|
9292
|
+
if (usesOutsideJsx(declaration, hook, derived, root.children)) return void 0;
|
|
9293
|
+
const totalUses = countUsesIn(root.root, hook, derived.names);
|
|
9294
|
+
if (totalUses === 0) return void 0;
|
|
9295
|
+
const analyzeSection = (node) => {
|
|
9296
|
+
const children = jsxChildren(node);
|
|
9297
|
+
if (!children || children.length === 0) return void 0;
|
|
9298
|
+
for (const child of children) {
|
|
9299
|
+
if (ts15.isJsxElement(child) || ts15.isJsxFragment(child)) {
|
|
9300
|
+
const inner = analyzeSection(child);
|
|
9301
|
+
if (inner) return inner;
|
|
9302
|
+
}
|
|
9303
|
+
}
|
|
9304
|
+
const counts = children.map((child) => countUsesIn(child, hook, derived.names));
|
|
9305
|
+
if (counts.reduce((sum, count) => sum + count, 0) !== totalUses) return void 0;
|
|
9306
|
+
const firstUsed = counts.findIndex((count) => count > 0);
|
|
9307
|
+
const lastUsed = counts.map((count) => count > 0).lastIndexOf(true);
|
|
9308
|
+
if (firstUsed === -1 || lastUsed === -1) return void 0;
|
|
9309
|
+
for (let index = firstUsed; index <= lastUsed; index += 1) {
|
|
9310
|
+
const child = children[index];
|
|
9311
|
+
if ((counts[index] ?? 0) === 0 && (child === void 0 || !isDecorativeSeparator(child))) return void 0;
|
|
9312
|
+
}
|
|
9313
|
+
const hasOutside = firstUsed > 0 || lastUsed < children.length - 1;
|
|
9314
|
+
if (!hasOutside) return void 0;
|
|
9315
|
+
return { run: lastUsed - firstUsed + 1, totalTopLevel: children.length };
|
|
9316
|
+
};
|
|
9317
|
+
return analyzeSection(root.root);
|
|
9318
|
+
}
|
|
9319
|
+
function usesOutsideJsx(declaration, hook, derived, children) {
|
|
9250
9320
|
let outside = false;
|
|
9251
9321
|
const visit = (node) => {
|
|
9252
9322
|
if (outside) return;
|
|
9253
9323
|
if (node !== declaration && (ts15.isFunctionDeclaration(node) || ts15.isClassDeclaration(node))) return;
|
|
9254
|
-
if (
|
|
9324
|
+
if (isTrackedUse(node, hook, derived.names)) {
|
|
9255
9325
|
let current = node;
|
|
9256
|
-
let
|
|
9326
|
+
let allowed = false;
|
|
9257
9327
|
while (!ts15.isSourceFile(current)) {
|
|
9258
|
-
if (children.includes(current)) {
|
|
9259
|
-
|
|
9328
|
+
if (children.includes(current) || derived.allowedInitializers.has(current)) {
|
|
9329
|
+
allowed = true;
|
|
9260
9330
|
break;
|
|
9261
9331
|
}
|
|
9262
9332
|
current = current.parent;
|
|
9263
9333
|
}
|
|
9264
|
-
if (!
|
|
9334
|
+
if (!allowed) outside = true;
|
|
9265
9335
|
}
|
|
9266
9336
|
ts15.forEachChild(node, visit);
|
|
9267
9337
|
};
|
|
@@ -9868,6 +9938,20 @@ var BOUNDARY_PROPERTY_WORDS = /* @__PURE__ */ new Set(["border", "outline", "rin
|
|
|
9868
9938
|
function violatesBoundaryColorRole(token) {
|
|
9869
9939
|
return !token.endsWith("-edge") && token.split("-").some((word) => BOUNDARY_PROPERTY_WORDS.has(word));
|
|
9870
9940
|
}
|
|
9941
|
+
var BACKGROUND_COLOR_UTILITIES = /* @__PURE__ */ new Set(["bg", "from", "via", "to"]);
|
|
9942
|
+
var TEXT_COLOR_UTILITIES = /* @__PURE__ */ new Set(["text"]);
|
|
9943
|
+
var BOUNDARY_COLOR_UTILITIES = /* @__PURE__ */ new Set(["border", "divide", "outline", "ring", "stroke"]);
|
|
9944
|
+
function incompatibleColorUtilityRole(prefix, token) {
|
|
9945
|
+
let role;
|
|
9946
|
+
if (token.endsWith("-canvas")) role = "canvas";
|
|
9947
|
+
else if (token.endsWith("-ink")) role = "ink";
|
|
9948
|
+
else if (token.endsWith("-edge")) role = "edge";
|
|
9949
|
+
if (!role) return void 0;
|
|
9950
|
+
if (BACKGROUND_COLOR_UTILITIES.has(prefix)) return role === "canvas" ? void 0 : role;
|
|
9951
|
+
if (TEXT_COLOR_UTILITIES.has(prefix)) return role === "ink" ? void 0 : role;
|
|
9952
|
+
if (BOUNDARY_COLOR_UTILITIES.has(prefix)) return role === "edge" ? void 0 : role;
|
|
9953
|
+
return void 0;
|
|
9954
|
+
}
|
|
9871
9955
|
|
|
9872
9956
|
// eslint/rules/tailwind/css-variable-naming.ts
|
|
9873
9957
|
var EDGE_PROPERTY_WORDS = /* @__PURE__ */ new Set(["border", "outline", "ring", "stroke"]);
|
|
@@ -10884,17 +10968,23 @@ function isColorToken(token, inventory) {
|
|
|
10884
10968
|
if (hyphen === -1) return false;
|
|
10885
10969
|
return DEFAULT_PALETTE_FAMILIES.has(token.slice(0, hyphen)) && DEFAULT_PALETTE_SHADES.has(token.slice(hyphen + 1));
|
|
10886
10970
|
}
|
|
10887
|
-
function
|
|
10888
|
-
if (className.includes("[") || className.includes("(")) return
|
|
10971
|
+
function definedThemeColorClass(className, inventory) {
|
|
10972
|
+
if (className.includes("[") || className.includes("(")) return void 0;
|
|
10889
10973
|
const utility = (className.replace(/!+$/, "").split(":").pop() ?? "").split("/")[0] ?? "";
|
|
10890
10974
|
const compound = Object.keys(PREFIX_NAMESPACES).find(
|
|
10891
10975
|
(prefix2) => prefix2.includes("-") && utility.startsWith(`${prefix2}-`)
|
|
10892
10976
|
);
|
|
10893
10977
|
const dash = utility.indexOf("-");
|
|
10894
|
-
if (dash === -1) return
|
|
10978
|
+
if (dash === -1) return void 0;
|
|
10895
10979
|
const prefix = compound ?? utility.slice(0, dash);
|
|
10896
10980
|
const token = utility.slice(prefix.length + 1);
|
|
10897
|
-
|
|
10981
|
+
if (!(PREFIX_NAMESPACES[prefix]?.includes("color") ?? false)) return void 0;
|
|
10982
|
+
if (!(inventory.themeTokens.get("color")?.has(token) ?? false)) return void 0;
|
|
10983
|
+
return { prefix, token };
|
|
10984
|
+
}
|
|
10985
|
+
function isInvalidBoundaryColorClass(className, inventory) {
|
|
10986
|
+
const themeColor = definedThemeColorClass(className, inventory);
|
|
10987
|
+
return themeColor !== void 0 && violatesBoundaryColorRole(themeColor.token);
|
|
10898
10988
|
}
|
|
10899
10989
|
function isKnown(className, inventory) {
|
|
10900
10990
|
if (className.includes("[") || className.includes("(")) return true;
|
|
@@ -10963,6 +11053,20 @@ var unknownUtilityRule = {
|
|
|
10963
11053
|
});
|
|
10964
11054
|
continue;
|
|
10965
11055
|
}
|
|
11056
|
+
const themeColor = definedThemeColorClass(candidate, inventory);
|
|
11057
|
+
const incompatibleRole = themeColor ? incompatibleColorUtilityRole(themeColor.prefix, themeColor.token) : void 0;
|
|
11058
|
+
if (incompatibleRole) {
|
|
11059
|
+
const expected = {
|
|
11060
|
+
canvas: "bg-<role>-canvas",
|
|
11061
|
+
ink: "text-<role>-ink",
|
|
11062
|
+
edge: "border-<role>-edge"
|
|
11063
|
+
}[incompatibleRole];
|
|
11064
|
+
context.report({
|
|
11065
|
+
node,
|
|
11066
|
+
message: `Utility class "${candidate}" applies a -${incompatibleRole} color token to an incompatible property; use ${expected} for that role or define a token for the intended property.`
|
|
11067
|
+
});
|
|
11068
|
+
continue;
|
|
11069
|
+
}
|
|
10966
11070
|
if (isKnown(candidate, inventory)) continue;
|
|
10967
11071
|
const plainBase = candidate.replace(/!+$/, "").split(":").pop() ?? "";
|
|
10968
11072
|
if (inventory.plainClasses.has(plainBase)) {
|