pasika 0.10.90 → 0.10.91
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 +103 -43
- package/package.json +1 -1
|
@@ -6200,6 +6200,7 @@ var nextjsPackageJsonRules = {
|
|
|
6200
6200
|
|
|
6201
6201
|
// eslint/rules/prefer-enum.ts
|
|
6202
6202
|
import path44 from "path";
|
|
6203
|
+
import ts8 from "typescript";
|
|
6203
6204
|
function isConstAssertion(node) {
|
|
6204
6205
|
const typeAnnotation = node.typeAnnotation;
|
|
6205
6206
|
return typeAnnotation?.type === "TSTypeReference" && typeAnnotation.typeName?.type === "Identifier" && typeAnnotation.typeName.name === "const";
|
|
@@ -6242,12 +6243,33 @@ function rawZodDiscriminantLiteral(schemaCall, discriminator) {
|
|
|
6242
6243
|
}
|
|
6243
6244
|
return void 0;
|
|
6244
6245
|
}
|
|
6246
|
+
function isLiteralTupleAssertion(node) {
|
|
6247
|
+
if (!isConstAssertion(node)) return false;
|
|
6248
|
+
const expression = node.expression;
|
|
6249
|
+
if (expression?.type !== "ArrayExpression" || expression.elements.length < 2) return false;
|
|
6250
|
+
const values = expression.elements.map((element) => {
|
|
6251
|
+
if (element?.type !== "Literal") return void 0;
|
|
6252
|
+
return typeof element.value === "string" || typeof element.value === "number" ? element.value : void 0;
|
|
6253
|
+
});
|
|
6254
|
+
return values.every((value) => value !== void 0) && new Set(values).size >= 2;
|
|
6255
|
+
}
|
|
6256
|
+
function isTsLiteralTupleDeclaration(declaration) {
|
|
6257
|
+
if (!ts8.isVariableDeclaration(declaration) || !declaration.initializer) return false;
|
|
6258
|
+
const init = declaration.initializer;
|
|
6259
|
+
if (!ts8.isAsExpression(init) || !ts8.isTypeReferenceNode(init.type) || !ts8.isIdentifier(init.type.typeName) || init.type.typeName.text !== "const" || !ts8.isArrayLiteralExpression(init.expression) || init.expression.elements.length < 2) {
|
|
6260
|
+
return false;
|
|
6261
|
+
}
|
|
6262
|
+
const values = init.expression.elements.map(
|
|
6263
|
+
(element) => ts8.isStringLiteral(element) || ts8.isNumericLiteral(element) ? element.text : void 0
|
|
6264
|
+
);
|
|
6265
|
+
return values.every((value) => value !== void 0) && new Set(values).size >= 2;
|
|
6266
|
+
}
|
|
6245
6267
|
var preferEnumRule = {
|
|
6246
6268
|
meta: {
|
|
6247
6269
|
schema: [],
|
|
6248
6270
|
type: "problem",
|
|
6249
6271
|
docs: {
|
|
6250
|
-
description: "Require fixed sets of named string/number values to be TypeScript enums, including Zod discriminated-union discriminator values."
|
|
6272
|
+
description: "Require fixed sets of named string/number values to be TypeScript enums, including named Zod enum tuples and discriminated-union discriminator values."
|
|
6251
6273
|
}
|
|
6252
6274
|
},
|
|
6253
6275
|
create(context) {
|
|
@@ -6255,20 +6277,54 @@ var preferEnumRule = {
|
|
|
6255
6277
|
const sourceRoot = sourceRootOf(context);
|
|
6256
6278
|
if (!filename.startsWith(sourceRoot + path44.sep)) return {};
|
|
6257
6279
|
const objectSchemas = /* @__PURE__ */ new Map();
|
|
6280
|
+
const literalTuples = /* @__PURE__ */ new Set();
|
|
6281
|
+
const enumTupleUses = [];
|
|
6258
6282
|
const discriminatedUnions = [];
|
|
6259
6283
|
const reportedDiscriminants = /* @__PURE__ */ new Set();
|
|
6284
|
+
const services = typedParserServices(context.sourceCode.parserServices);
|
|
6285
|
+
function isTupleDomain(name) {
|
|
6286
|
+
if (!services) return literalTuples.has(name.name);
|
|
6287
|
+
const tsNode = services.esTreeNodeToTSNodeMap.get(name);
|
|
6288
|
+
if (!tsNode) return false;
|
|
6289
|
+
const checker = services.program.getTypeChecker();
|
|
6290
|
+
const symbol = checker.getSymbolAtLocation(tsNode);
|
|
6291
|
+
if (!symbol) return false;
|
|
6292
|
+
const original = symbol.flags === ts8.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
6293
|
+
return (original.declarations ?? []).some(isTsLiteralTupleDeclaration);
|
|
6294
|
+
}
|
|
6260
6295
|
return {
|
|
6261
6296
|
VariableDeclarator(node) {
|
|
6262
6297
|
const { id, init } = node;
|
|
6263
|
-
if (id?.type !== "Identifier" ||
|
|
6264
|
-
|
|
6298
|
+
if (id?.type !== "Identifier" || !init) return;
|
|
6299
|
+
if (init.type === "CallExpression" && isZodCall(init, "object")) {
|
|
6300
|
+
objectSchemas.set(id.name, init);
|
|
6301
|
+
}
|
|
6265
6302
|
},
|
|
6266
6303
|
CallExpression(node) {
|
|
6267
6304
|
if (isZodCall(node, "discriminatedUnion")) {
|
|
6268
6305
|
discriminatedUnions.push(node);
|
|
6269
6306
|
}
|
|
6307
|
+
const argument = node.arguments?.[0];
|
|
6308
|
+
if (isZodCall(node, "enum") && argument?.type === "Identifier") {
|
|
6309
|
+
enumTupleUses.push({ name: argument, node });
|
|
6310
|
+
}
|
|
6311
|
+
},
|
|
6312
|
+
TSIndexedAccessType(node) {
|
|
6313
|
+
const { objectType, indexType } = node;
|
|
6314
|
+
if (objectType?.type === "TSTypeQuery" && objectType.exprName?.type === "Identifier" && indexType?.type === "TSNumberKeyword") {
|
|
6315
|
+
enumTupleUses.push({ name: objectType.exprName, node });
|
|
6316
|
+
}
|
|
6270
6317
|
},
|
|
6271
6318
|
"Program:exit"() {
|
|
6319
|
+
const reportedTuples = /* @__PURE__ */ new Set();
|
|
6320
|
+
for (const use of enumTupleUses) {
|
|
6321
|
+
if (reportedTuples.has(use.name.name) || !isTupleDomain(use.name)) continue;
|
|
6322
|
+
reportedTuples.add(use.name.name);
|
|
6323
|
+
context.report({
|
|
6324
|
+
node: use.node,
|
|
6325
|
+
message: "A const tuple used as a named enum domain must be replaced with a TypeScript enum. See docs/next-codebase-guide/rules/constants-rule.md"
|
|
6326
|
+
});
|
|
6327
|
+
}
|
|
6272
6328
|
for (const unionCall of discriminatedUnions) {
|
|
6273
6329
|
const [discriminatorArg, optionsArg] = unionCall.arguments ?? [];
|
|
6274
6330
|
if (discriminatorArg?.type !== "Literal" || typeof discriminatorArg.value !== "string" || optionsArg?.type !== "ArrayExpression") {
|
|
@@ -6295,6 +6351,10 @@ var preferEnumRule = {
|
|
|
6295
6351
|
},
|
|
6296
6352
|
TSAsExpression(node) {
|
|
6297
6353
|
if (!isConstAssertion(node)) return;
|
|
6354
|
+
if (isLiteralTupleAssertion(node) && node.parent?.type === "VariableDeclarator") {
|
|
6355
|
+
const { id } = node.parent;
|
|
6356
|
+
if (id.type === "Identifier") literalTuples.add(id.name);
|
|
6357
|
+
}
|
|
6298
6358
|
const expression = node.expression;
|
|
6299
6359
|
if (!expression || expression.type !== "ObjectExpression") return;
|
|
6300
6360
|
if (expression.properties.length === 0) return;
|
|
@@ -6324,7 +6384,7 @@ var preferEnumRule = {
|
|
|
6324
6384
|
};
|
|
6325
6385
|
|
|
6326
6386
|
// eslint/rules/prefer-object-destructuring.ts
|
|
6327
|
-
import
|
|
6387
|
+
import ts9 from "typescript";
|
|
6328
6388
|
var DOC5 = "See docs/next-codebase-guide/rules/redundant-aliases-rule.md";
|
|
6329
6389
|
function hasTypeAnnotation(identifier) {
|
|
6330
6390
|
return "typeAnnotation" in identifier && identifier.typeAnnotation !== void 0;
|
|
@@ -6413,8 +6473,8 @@ function enumValueResolver(context) {
|
|
|
6413
6473
|
const checker = services.program.getTypeChecker();
|
|
6414
6474
|
const { esTreeNodeToTSNodeMap: nodeMap } = services;
|
|
6415
6475
|
const isEnumSymbol = (symbol) => {
|
|
6416
|
-
const resolved = symbol.flags ===
|
|
6417
|
-
return (resolved.declarations ?? []).some((declaration) =>
|
|
6476
|
+
const resolved = symbol.flags === ts9.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
6477
|
+
return (resolved.declarations ?? []).some((declaration) => ts9.isEnumDeclaration(declaration));
|
|
6418
6478
|
};
|
|
6419
6479
|
return (node) => {
|
|
6420
6480
|
const tsNode = nodeMap.get(node);
|
|
@@ -7329,7 +7389,7 @@ var rootSupportPlacementRule = {
|
|
|
7329
7389
|
|
|
7330
7390
|
// eslint/rules/route-handler-shape.ts
|
|
7331
7391
|
import path49 from "path";
|
|
7332
|
-
import
|
|
7392
|
+
import ts10 from "typescript";
|
|
7333
7393
|
var HTTP_METHODS2 = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
7334
7394
|
var REQUIRED_BOUNDARY = "withResponse";
|
|
7335
7395
|
function isFunctionLike(node) {
|
|
@@ -7347,33 +7407,33 @@ function findHandler(node) {
|
|
|
7347
7407
|
return void 0;
|
|
7348
7408
|
}
|
|
7349
7409
|
function isLoop(node) {
|
|
7350
|
-
return
|
|
7410
|
+
return ts10.isForStatement(node) || ts10.isForOfStatement(node) || ts10.isForInStatement(node) || ts10.isWhileStatement(node) || ts10.isDoStatement(node);
|
|
7351
7411
|
}
|
|
7352
7412
|
function isFunctionBoundary(node) {
|
|
7353
|
-
return
|
|
7413
|
+
return ts10.isFunctionExpression(node) || ts10.isArrowFunction(node) || ts10.isFunctionDeclaration(node);
|
|
7354
7414
|
}
|
|
7355
7415
|
function analyzeHandlerBody(body, sourceText) {
|
|
7356
7416
|
const start = body.range?.[0] ?? 0;
|
|
7357
7417
|
const end = body.range?.[1] ?? sourceText.length;
|
|
7358
|
-
const sourceFile =
|
|
7418
|
+
const sourceFile = ts10.createSourceFile(
|
|
7359
7419
|
"route.ts",
|
|
7360
7420
|
sourceText.slice(start, end),
|
|
7361
|
-
|
|
7421
|
+
ts10.ScriptTarget.Latest,
|
|
7362
7422
|
true,
|
|
7363
|
-
|
|
7423
|
+
ts10.ScriptKind.TS
|
|
7364
7424
|
);
|
|
7365
7425
|
const kinds = /* @__PURE__ */ new Set();
|
|
7366
7426
|
const calledNames = /* @__PURE__ */ new Set();
|
|
7367
7427
|
const visit = (node) => {
|
|
7368
|
-
if (
|
|
7428
|
+
if (ts10.isTryStatement(node)) kinds.add("try");
|
|
7369
7429
|
if (isLoop(node)) kinds.add("loop");
|
|
7370
|
-
if (
|
|
7371
|
-
if (
|
|
7430
|
+
if (ts10.isIfStatement(node)) kinds.add("if");
|
|
7431
|
+
if (ts10.isCallExpression(node) && ts10.isPropertyAccessExpression(node.expression) && node.expression.name.text === "map") {
|
|
7372
7432
|
kinds.add("map");
|
|
7373
7433
|
}
|
|
7374
|
-
if (
|
|
7434
|
+
if (ts10.isCallExpression(node) && ts10.isIdentifier(node.expression)) calledNames.add(node.expression.text);
|
|
7375
7435
|
if (isFunctionBoundary(node)) return;
|
|
7376
|
-
|
|
7436
|
+
ts10.forEachChild(node, visit);
|
|
7377
7437
|
};
|
|
7378
7438
|
visit(sourceFile);
|
|
7379
7439
|
return { kinds, calledNames };
|
|
@@ -7535,38 +7595,38 @@ var schemaCasingRule = {
|
|
|
7535
7595
|
|
|
7536
7596
|
// eslint/rules/sole-state-owner.ts
|
|
7537
7597
|
import path51 from "path";
|
|
7538
|
-
import
|
|
7598
|
+
import ts11 from "typescript";
|
|
7539
7599
|
function findStateHooks(node) {
|
|
7540
7600
|
const hooks = [];
|
|
7541
7601
|
const visit = (child) => {
|
|
7542
|
-
if (
|
|
7543
|
-
if (
|
|
7602
|
+
if (ts11.isCallExpression(child) && ts11.isIdentifier(child.expression) && child.expression.text === "useState") {
|
|
7603
|
+
if (ts11.isVariableDeclaration(child.parent)) {
|
|
7544
7604
|
const { name } = child.parent;
|
|
7545
|
-
if (
|
|
7605
|
+
if (ts11.isArrayBindingPattern(name) && name.elements.length >= 2) {
|
|
7546
7606
|
const value = name.elements[0];
|
|
7547
7607
|
const updater = name.elements[1];
|
|
7548
|
-
if (value && updater &&
|
|
7608
|
+
if (value && updater && ts11.isBindingElement(value) && ts11.isBindingElement(updater)) {
|
|
7549
7609
|
const valueName = value.name;
|
|
7550
7610
|
const updaterName = updater.name;
|
|
7551
|
-
if (
|
|
7611
|
+
if (ts11.isIdentifier(valueName) && ts11.isIdentifier(updaterName)) {
|
|
7552
7612
|
hooks.push({ value: valueName.text, updater: updaterName.text });
|
|
7553
7613
|
}
|
|
7554
7614
|
}
|
|
7555
7615
|
}
|
|
7556
7616
|
}
|
|
7557
7617
|
}
|
|
7558
|
-
|
|
7618
|
+
ts11.forEachChild(child, visit);
|
|
7559
7619
|
};
|
|
7560
7620
|
visit(node);
|
|
7561
7621
|
return hooks;
|
|
7562
7622
|
}
|
|
7563
7623
|
function isHookUsage(node, hook) {
|
|
7564
|
-
if (
|
|
7624
|
+
if (ts11.isCallExpression(node) && ts11.isIdentifier(node.expression) && node.expression.text === hook.updater) {
|
|
7565
7625
|
return "updater";
|
|
7566
7626
|
}
|
|
7567
|
-
if (
|
|
7627
|
+
if (ts11.isIdentifier(node) && node.text === hook.value) {
|
|
7568
7628
|
const parent = node.parent;
|
|
7569
|
-
if (
|
|
7629
|
+
if (ts11.isBindingElement(parent) || ts11.isPropertyAccessExpression(parent) || ts11.isShorthandPropertyAssignment(parent)) {
|
|
7570
7630
|
return void 0;
|
|
7571
7631
|
}
|
|
7572
7632
|
return "value";
|
|
@@ -7576,16 +7636,16 @@ function isHookUsage(node, hook) {
|
|
|
7576
7636
|
function topLevelJsxChildren(initial) {
|
|
7577
7637
|
if (!initial) return void 0;
|
|
7578
7638
|
let expression = initial;
|
|
7579
|
-
while (
|
|
7580
|
-
if (
|
|
7639
|
+
while (ts11.isParenthesizedExpression(expression)) expression = expression.expression;
|
|
7640
|
+
if (ts11.isJsxFragment(expression)) {
|
|
7581
7641
|
const children = expression.children.filter(
|
|
7582
|
-
(c) => !
|
|
7642
|
+
(c) => !ts11.isJsxText(c) && !ts11.isJsxSpreadAttribute(c)
|
|
7583
7643
|
);
|
|
7584
7644
|
return { root: expression, children };
|
|
7585
7645
|
}
|
|
7586
|
-
if (
|
|
7646
|
+
if (ts11.isJsxElement(expression)) {
|
|
7587
7647
|
const children = expression.children.filter(
|
|
7588
|
-
(c) => !
|
|
7648
|
+
(c) => !ts11.isJsxText(c) && !ts11.isJsxSpreadAttribute(c)
|
|
7589
7649
|
);
|
|
7590
7650
|
return { root: expression, children };
|
|
7591
7651
|
}
|
|
@@ -7599,8 +7659,8 @@ function collectUsesIn(child, hook) {
|
|
|
7599
7659
|
positions.push(node);
|
|
7600
7660
|
count += 1;
|
|
7601
7661
|
}
|
|
7602
|
-
if (
|
|
7603
|
-
|
|
7662
|
+
if (ts11.isFunctionDeclaration(node) || ts11.isClassDeclaration(node)) return;
|
|
7663
|
+
ts11.forEachChild(node, visit);
|
|
7604
7664
|
};
|
|
7605
7665
|
visit(child);
|
|
7606
7666
|
return { positions, count };
|
|
@@ -7639,18 +7699,18 @@ var soleStateOwnerRule = {
|
|
|
7639
7699
|
}
|
|
7640
7700
|
};
|
|
7641
7701
|
function analyzeSoleOwner(declaration, hook) {
|
|
7642
|
-
const body =
|
|
7643
|
-
if (!body || !
|
|
7702
|
+
const body = ts11.isFunctionDeclaration(declaration) ? declaration.body : void 0;
|
|
7703
|
+
if (!body || !ts11.isBlock(body)) return void 0;
|
|
7644
7704
|
const returns = [];
|
|
7645
7705
|
const visit = (node) => {
|
|
7646
|
-
if (node !== body && (
|
|
7647
|
-
if (
|
|
7648
|
-
|
|
7706
|
+
if (node !== body && (ts11.isFunctionLike(node) || ts11.isClassLike(node))) return;
|
|
7707
|
+
if (ts11.isReturnStatement(node)) returns.push(node);
|
|
7708
|
+
ts11.forEachChild(node, visit);
|
|
7649
7709
|
};
|
|
7650
7710
|
visit(body);
|
|
7651
7711
|
if (returns.length !== 1) return void 0;
|
|
7652
7712
|
const single = returns[0];
|
|
7653
|
-
if (!single?.expression || !
|
|
7713
|
+
if (!single?.expression || !ts11.isExpression(single.expression)) return void 0;
|
|
7654
7714
|
const returnExpression = single.expression;
|
|
7655
7715
|
const root = topLevelJsxChildren(returnExpression);
|
|
7656
7716
|
if (!root || root.children.length === 0) return void 0;
|
|
@@ -7673,11 +7733,11 @@ function usesOutsideJsx(declaration, hook, children) {
|
|
|
7673
7733
|
let outside = false;
|
|
7674
7734
|
const visit = (node) => {
|
|
7675
7735
|
if (outside) return;
|
|
7676
|
-
if (node !== declaration && (
|
|
7736
|
+
if (node !== declaration && (ts11.isFunctionDeclaration(node) || ts11.isClassDeclaration(node))) return;
|
|
7677
7737
|
if (isHookUsage(node, hook)) {
|
|
7678
7738
|
let current = node;
|
|
7679
7739
|
let isInJsxChild = false;
|
|
7680
|
-
while (!
|
|
7740
|
+
while (!ts11.isSourceFile(current)) {
|
|
7681
7741
|
if (children.includes(current)) {
|
|
7682
7742
|
isInJsxChild = true;
|
|
7683
7743
|
break;
|
|
@@ -7686,7 +7746,7 @@ function usesOutsideJsx(declaration, hook, children) {
|
|
|
7686
7746
|
}
|
|
7687
7747
|
if (!isInJsxChild) outside = true;
|
|
7688
7748
|
}
|
|
7689
|
-
|
|
7749
|
+
ts11.forEachChild(node, visit);
|
|
7690
7750
|
};
|
|
7691
7751
|
visit(declaration);
|
|
7692
7752
|
return outside;
|