pasika 0.10.58 → 0.10.60

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.
@@ -259,6 +259,7 @@ declare const pasikaPlugin: {
259
259
  "locale-placement": eslint.Rule.RuleModule;
260
260
  "sole-state-owner": eslint.Rule.RuleModule;
261
261
  "locale-key-shape": eslint.Rule.RuleModule;
262
+ "repeated-numeric-value": eslint.Rule.RuleModule;
262
263
  "repeated-structure": eslint.Rule.RuleModule;
263
264
  };
264
265
  };
@@ -38,8 +38,8 @@ function memberPropertyName(node) {
38
38
  }
39
39
  return void 0;
40
40
  }
41
- function importedContractMember(expression, propertyName3, imports) {
42
- if (expression?.type !== "MemberExpression" || memberPropertyName(expression) !== propertyName3 || expression.object.type !== "Identifier" || !imports.has(expression.object.name)) {
41
+ function importedContractMember(expression, propertyName4, imports) {
42
+ if (expression?.type !== "MemberExpression" || memberPropertyName(expression) !== propertyName4 || expression.object.type !== "Identifier" || !imports.has(expression.object.name)) {
43
43
  return void 0;
44
44
  }
45
45
  return expression.object.name;
@@ -282,6 +282,25 @@ var isSchemaName = (name) => /(?:[Ss]chema|ApiContract)$/.test(name);
282
282
  function lineOf(sourceFile, node) {
283
283
  return sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;
284
284
  }
285
+ function numericLiteralValue(node) {
286
+ if (!node) return void 0;
287
+ if (ts.isNumericLiteral(node)) return Number(node.text.replaceAll("_", ""));
288
+ if (ts.isPrefixUnaryExpression(node) && node.operator === ts.SyntaxKind.MinusToken && ts.isNumericLiteral(node.operand)) {
289
+ return -Number(node.operand.text.replaceAll("_", ""));
290
+ }
291
+ return void 0;
292
+ }
293
+ function semanticName(name) {
294
+ const parts = name.replace(/(?<lower>[a-z0-9])(?<upper>[A-Z])/g, "$<lower> $<upper>").replace(/[_-]+/g, " ").toLowerCase().split(/\s+/).filter(Boolean);
295
+ const last = parts.at(-1);
296
+ if (last === "width" || last === "height" || last === "fps") return last;
297
+ if (parts.includes("duration")) return "duration";
298
+ return parts.join(" ");
299
+ }
300
+ function propertyName(node) {
301
+ if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node)) return node.text;
302
+ return void 0;
303
+ }
285
304
  function returnsJsx(node) {
286
305
  let found = false;
287
306
  const visit = (child) => {
@@ -317,6 +336,31 @@ function parseModule(file) {
317
336
  const imports = [];
318
337
  const reexports = [];
319
338
  const exports = [];
339
+ const namedNumericLiterals = [];
340
+ const addNamedNumericLiteral = (name, value, node) => {
341
+ namedNumericLiterals.push({
342
+ name,
343
+ semanticName: semanticName(name),
344
+ value,
345
+ line: lineOf(sourceFile, node)
346
+ });
347
+ };
348
+ const collectNamedNumericLiterals = (node) => {
349
+ if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)) {
350
+ const value = numericLiteralValue(node.initializer);
351
+ if (value !== void 0) addNamedNumericLiteral(node.name.text, value, node.initializer ?? node);
352
+ } else if (ts.isPropertyAssignment(node)) {
353
+ const name = propertyName(node.name);
354
+ const value = numericLiteralValue(node.initializer);
355
+ if (name && value !== void 0) addNamedNumericLiteral(name, value, node.initializer);
356
+ } else if (ts.isJsxAttribute(node) && ts.isIdentifier(node.name) && node.initializer && ts.isJsxExpression(node.initializer)) {
357
+ const expression = node.initializer.expression;
358
+ const value = expression ? numericLiteralValue(expression) : void 0;
359
+ if (value !== void 0 && expression) addNamedNumericLiteral(node.name.text, value, expression);
360
+ }
361
+ ts.forEachChild(node, collectNamedNumericLiterals);
362
+ };
363
+ collectNamedNumericLiterals(sourceFile);
320
364
  const addImport = (specifierNode, names, node) => {
321
365
  if (!ts.isStringLiteral(specifierNode)) return;
322
366
  imports.push({ specifier: specifierNode.text, names, line: lineOf(sourceFile, node) });
@@ -398,7 +442,7 @@ function parseModule(file) {
398
442
  });
399
443
  }
400
444
  }
401
- return { file: path3.resolve(file), imports, reexports, exports };
445
+ return { file: path3.resolve(file), imports, reexports, exports, namedNumericLiterals };
402
446
  }
403
447
 
404
448
  // eslint/rules/project-root.ts
@@ -4864,7 +4908,7 @@ function isStaticValue(value) {
4864
4908
  }
4865
4909
  return false;
4866
4910
  }
4867
- function propertyName(property) {
4911
+ function propertyName2(property) {
4868
4912
  if (!property.computed && property.key.type === "Identifier") return property.key.name;
4869
4913
  if (property.key.type === "Literal" && typeof property.key.value === "string") return property.key.value;
4870
4914
  return void 0;
@@ -4872,7 +4916,7 @@ function propertyName(property) {
4872
4916
  function findStaticDeclaration(expression) {
4873
4917
  for (const property of expression.properties) {
4874
4918
  if (property.type !== "Property" || property.kind !== "init") continue;
4875
- const name = propertyName(property);
4919
+ const name = propertyName2(property);
4876
4920
  if (!name) continue;
4877
4921
  if (isStaticValue(property.value)) return name;
4878
4922
  }
@@ -4976,12 +5020,19 @@ function aliasMessage(alias, source) {
4976
5020
  const sourceName = source ?? "the original symbol";
4977
5021
  return `"${aliasName}" only renames "${sourceName}". Use "${sourceName}" directly or rename the original symbol and its consumers. ${DOC4}`;
4978
5022
  }
5023
+ function objectPropertyMessage(propertyName4, source, identifierValue) {
5024
+ if (!identifierValue) {
5025
+ return `"${propertyName4}" maps "${source}" inline. Bind it as "${propertyName4}" before this object and use property shorthand. ${DOC4}`;
5026
+ }
5027
+ if (source === propertyName4) return `Use property shorthand for "${propertyName4}". ${DOC4}`;
5028
+ return `"${propertyName4}" maps the local "${source}" inline. Rename the producer to "${propertyName4}" and use property shorthand. ${DOC4}`;
5029
+ }
4979
5030
  var noRedundantAliasRule = {
4980
5031
  meta: {
4981
5032
  schema: [],
4982
5033
  type: "problem",
4983
5034
  docs: {
4984
- description: "Disallow declarations that only give an existing symbol a second name."
5035
+ description: "Disallow redundant aliases and inline identifier/member-expression object mappings."
4985
5036
  }
4986
5037
  },
4987
5038
  create(context) {
@@ -4998,6 +5049,17 @@ var noRedundantAliasRule = {
4998
5049
  message: aliasMessage(node.id.name, node.init.name)
4999
5050
  });
5000
5051
  },
5052
+ Property(node) {
5053
+ if (node.parent.type !== "ObjectExpression" || node.computed || node.key.type !== "Identifier") return;
5054
+ if (node.value.type !== "Identifier" && node.value.type !== "MemberExpression") return;
5055
+ const propertyName4 = node.key.name;
5056
+ const source = context.sourceCode.getText(node.value);
5057
+ if (node.value.type === "Identifier" && node.shorthand) return;
5058
+ context.report({
5059
+ node,
5060
+ message: objectPropertyMessage(propertyName4, source, node.value.type === "Identifier")
5061
+ });
5062
+ },
5001
5063
  TSTypeAliasDeclaration(node) {
5002
5064
  if (node.typeParameters) return;
5003
5065
  const annotation = node.typeAnnotation;
@@ -5447,7 +5509,7 @@ function isZodCall(node, method) {
5447
5509
  const { callee } = node;
5448
5510
  return callee?.type === "MemberExpression" && !callee.computed && callee.object.type === "Identifier" && callee.object.name === "z" && callee.property.type === "Identifier" && callee.property.name === method;
5449
5511
  }
5450
- function propertyName2(property) {
5512
+ function propertyName3(property) {
5451
5513
  if (property.computed) return void 0;
5452
5514
  if (property.key.type === "Identifier") return property.key.name;
5453
5515
  if (property.key.type === "Literal" && typeof property.key.value === "string") return property.key.value;
@@ -5458,7 +5520,7 @@ function rawZodDiscriminantLiteral(schemaCall, discriminator) {
5458
5520
  const shape = schemaCall.arguments[0];
5459
5521
  if (shape?.type !== "ObjectExpression") return void 0;
5460
5522
  for (const property of shape.properties) {
5461
- if (property.type !== "Property" || propertyName2(property) !== discriminator) continue;
5523
+ if (property.type !== "Property" || propertyName3(property) !== discriminator) continue;
5462
5524
  if (property.value.type !== "CallExpression" || !isZodCall(property.value, "literal")) return void 0;
5463
5525
  const literal = property.value.arguments[0];
5464
5526
  if (literal?.type === "Literal" && (typeof literal.value === "string" || typeof literal.value === "number")) {
@@ -5679,6 +5741,70 @@ var pureFunctionExtractRule = {
5679
5741
  }
5680
5742
  };
5681
5743
 
5744
+ // eslint/rules/repeated-numeric-value.ts
5745
+ import path44 from "path";
5746
+ var ignoredValues = /* @__PURE__ */ new Set([-1, 0, 1]);
5747
+ function isNonProductionFile(file, sourceRoot) {
5748
+ const relative = path44.relative(sourceRoot, file);
5749
+ const segments = relative.split(path44.sep);
5750
+ const basename = path44.basename(file);
5751
+ return /\.(?:test|spec|mock)\.[^.]+$/.test(basename) || segments.some((segment) => segment === "__tests__" || segment === "__mocks__" || segment === "mocks");
5752
+ }
5753
+ function isCanonicalConstantFile(file, sourceRoot) {
5754
+ const segments = path44.relative(sourceRoot, file).split(path44.sep);
5755
+ return segments.includes("constants") || segments[0] === "config";
5756
+ }
5757
+ function groupKey(literal) {
5758
+ return `${literal.semanticName}\0${String(literal.value)}`;
5759
+ }
5760
+ var repeatedNumericValueRule = {
5761
+ meta: {
5762
+ schema: [],
5763
+ type: "problem",
5764
+ docs: {
5765
+ description: "Require repeated named numeric values across production files to use one extracted constant or enum."
5766
+ }
5767
+ },
5768
+ create(context) {
5769
+ const sourceRoot = sourceRootOf(context);
5770
+ const file = path44.resolve(context.filename);
5771
+ if (isNonProductionFile(file, sourceRoot) || isCanonicalConstantFile(file, sourceRoot)) return {};
5772
+ const index = getProjectIndex(sourceRoot);
5773
+ if (!index) return {};
5774
+ const currentModule = index.modules.get(file);
5775
+ if (!currentModule) return {};
5776
+ const filesByGroup = /* @__PURE__ */ new Map();
5777
+ for (const [moduleFile, parsedModule] of index.modules) {
5778
+ if (isNonProductionFile(moduleFile, sourceRoot)) continue;
5779
+ for (const literal of parsedModule.namedNumericLiterals) {
5780
+ if (ignoredValues.has(literal.value)) continue;
5781
+ const key = groupKey(literal);
5782
+ const files = filesByGroup.get(key) ?? /* @__PURE__ */ new Set();
5783
+ files.add(moduleFile);
5784
+ filesByGroup.set(key, files);
5785
+ }
5786
+ }
5787
+ return {
5788
+ Program(node) {
5789
+ const reported = /* @__PURE__ */ new Set();
5790
+ for (const literal of currentModule.namedNumericLiterals) {
5791
+ if (ignoredValues.has(literal.value)) continue;
5792
+ const key = groupKey(literal);
5793
+ if (reported.has(key)) continue;
5794
+ const files = filesByGroup.get(key);
5795
+ if (!files || files.size < 2) continue;
5796
+ reported.add(key);
5797
+ context.report({
5798
+ node,
5799
+ loc: { line: literal.line, column: 0 },
5800
+ message: `The numeric value ${String(literal.value)} is repeated for the "${literal.semanticName}" semantic slot in ${String(files.size)} production files. Extract one constant or enum at their CCF and import it instead. See docs/next-codebase-guide/rules/constants-rule.md`
5801
+ });
5802
+ }
5803
+ }
5804
+ };
5805
+ }
5806
+ };
5807
+
5682
5808
  // eslint/rules/repeated-structure.ts
5683
5809
  function nodeKind(node) {
5684
5810
  return node.type;
@@ -5861,7 +5987,7 @@ var repeatedStructureRule = {
5861
5987
 
5862
5988
  // eslint/rules/require-barrel-star-exports.ts
5863
5989
  import fs5 from "fs";
5864
- import path44 from "path";
5990
+ import path45 from "path";
5865
5991
  var SUPPORT_FOLDERS3 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
5866
5992
  var INDEX_NAMES = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
5867
5993
  var MODULE_EXTENSIONS3 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
@@ -5869,9 +5995,9 @@ function resolveSiblingModule(indexFile, specifier) {
5869
5995
  if (!specifier.startsWith("./")) return void 0;
5870
5996
  const relative = specifier.slice(2);
5871
5997
  if (!relative || relative.includes("/")) return void 0;
5872
- const directory = path44.dirname(indexFile);
5873
- const direct = path44.resolve(directory, relative);
5874
- const candidates = path44.extname(direct) ? [direct] : MODULE_EXTENSIONS3.map((extension) => `${direct}${extension}`);
5998
+ const directory = path45.dirname(indexFile);
5999
+ const direct = path45.resolve(directory, relative);
6000
+ const candidates = path45.extname(direct) ? [direct] : MODULE_EXTENSIONS3.map((extension) => `${direct}${extension}`);
5875
6001
  return candidates.find((candidate) => fs5.existsSync(candidate) && fs5.statSync(candidate).isFile());
5876
6002
  }
5877
6003
  var requireBarrelStarExportsRule = {
@@ -5884,9 +6010,9 @@ var requireBarrelStarExportsRule = {
5884
6010
  fixable: "code"
5885
6011
  },
5886
6012
  create(context) {
5887
- const filename = path44.resolve(context.filename);
5888
- if (!INDEX_NAMES.has(path44.basename(filename))) return {};
5889
- if (!SUPPORT_FOLDERS3.has(path44.basename(path44.dirname(filename)))) return {};
6013
+ const filename = path45.resolve(context.filename);
6014
+ if (!INDEX_NAMES.has(path45.basename(filename))) return {};
6015
+ if (!SUPPORT_FOLDERS3.has(path45.basename(path45.dirname(filename)))) return {};
5890
6016
  return {
5891
6017
  ExportNamedDeclaration(node) {
5892
6018
  const sourceNode = node.source;
@@ -5939,7 +6065,7 @@ var requireBarrelStarExportsRule = {
5939
6065
  };
5940
6066
 
5941
6067
  // eslint/rules/root-support-placement.ts
5942
- import path45 from "path";
6068
+ import path46 from "path";
5943
6069
  function isSupportFolder(value) {
5944
6070
  return value === "utils" || value === "types" || value === "schemas" || value === "constants";
5945
6071
  }
@@ -5972,7 +6098,7 @@ var rootSupportPlacementRule = {
5972
6098
  },
5973
6099
  create(context) {
5974
6100
  const sourceRoot = sourceRootOf(context);
5975
- const file = path45.resolve(context.filename);
6101
+ const file = path46.resolve(context.filename);
5976
6102
  const segments = segmentsOf(file, sourceRoot);
5977
6103
  const folderSegments = folderSegmentsOf(file, sourceRoot);
5978
6104
  const supportFolder = folderSegments[folderSegments.length - 1];
@@ -6012,7 +6138,7 @@ var rootSupportPlacementRule = {
6012
6138
  };
6013
6139
 
6014
6140
  // eslint/rules/route-handler-shape.ts
6015
- import path46 from "path";
6141
+ import path47 from "path";
6016
6142
  import ts7 from "typescript";
6017
6143
  var HTTP_METHODS2 = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
6018
6144
  var REQUIRED_BOUNDARY = "withResponse";
@@ -6097,7 +6223,7 @@ var routeHandlerShapeRule = {
6097
6223
  }
6098
6224
  },
6099
6225
  create(context) {
6100
- if (path46.basename(context.filename) !== "route.ts") return {};
6226
+ if (path47.basename(context.filename) !== "route.ts") return {};
6101
6227
  const sourceText = context.sourceCode.text;
6102
6228
  function reportUnwrapped(node, name) {
6103
6229
  context.report({
@@ -6156,7 +6282,7 @@ var routeHandlerShapeRule = {
6156
6282
  };
6157
6283
 
6158
6284
  // eslint/rules/schema-casing.ts
6159
- import path47 from "path";
6285
+ import path48 from "path";
6160
6286
  function isCamelCase(name) {
6161
6287
  return /^[a-z][a-zA-Z0-9]*$/.test(name);
6162
6288
  }
@@ -6184,9 +6310,9 @@ var schemaCasingRule = {
6184
6310
  }
6185
6311
  },
6186
6312
  create(context) {
6187
- const filename = path47.resolve(context.filename);
6313
+ const filename = path48.resolve(context.filename);
6188
6314
  const sourceRoot = sourceRootOf(context);
6189
- if (!filename.startsWith(sourceRoot + path47.sep)) return {};
6315
+ if (!filename.startsWith(sourceRoot + path48.sep)) return {};
6190
6316
  let zodLocalName;
6191
6317
  return {
6192
6318
  ImportDeclaration(node) {
@@ -6218,7 +6344,7 @@ var schemaCasingRule = {
6218
6344
  };
6219
6345
 
6220
6346
  // eslint/rules/sole-state-owner.ts
6221
- import path48 from "path";
6347
+ import path49 from "path";
6222
6348
  import ts8 from "typescript";
6223
6349
  function findStateHooks(node) {
6224
6350
  const hooks = [];
@@ -6298,7 +6424,7 @@ var soleStateOwnerRule = {
6298
6424
  }
6299
6425
  },
6300
6426
  create(context) {
6301
- const filename = path48.resolve(context.filename);
6427
+ const filename = path49.resolve(context.filename);
6302
6428
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
6303
6429
  const text = context.sourceCode.text;
6304
6430
  const components = parseComponentInfo(text, filename);
@@ -6377,7 +6503,7 @@ function usesOutsideJsx(declaration, hook, children) {
6377
6503
  }
6378
6504
 
6379
6505
  // eslint/rules/source-under-src.ts
6380
- import path49 from "path";
6506
+ import path50 from "path";
6381
6507
  var NON_SOURCE_ROOT_DIRS = /* @__PURE__ */ new Set([
6382
6508
  ".agents",
6383
6509
  ".cache",
@@ -6418,14 +6544,14 @@ var sourceUnderSrcRule = {
6418
6544
  }
6419
6545
  },
6420
6546
  create(context) {
6421
- const filename = path49.resolve(context.filename);
6547
+ const filename = path50.resolve(context.filename);
6422
6548
  if (!MODULE_EXTENSION.test(filename)) return {};
6423
- const relative = path49.relative(context.cwd, filename).replace(/\\/g, "/");
6549
+ const relative = path50.relative(context.cwd, filename).replace(/\\/g, "/");
6424
6550
  if (relative === "src" || relative.startsWith("src/")) return {};
6425
6551
  const topLevel = relative.split("/")[0] ?? "";
6426
6552
  if (NON_SOURCE_ROOT_DIRS.has(topLevel)) return {};
6427
6553
  if (!relative.includes("/")) {
6428
- const basename = path49.basename(filename);
6554
+ const basename = path50.basename(filename);
6429
6555
  if (CONFIG_FILE.test(basename) || DECLARATION_FILE.test(basename) || basename.startsWith(".")) return {};
6430
6556
  }
6431
6557
  return {
@@ -6441,7 +6567,7 @@ var sourceUnderSrcRule = {
6441
6567
  };
6442
6568
 
6443
6569
  // eslint/rules/stay-flat.ts
6444
- import path50 from "path";
6570
+ import path51 from "path";
6445
6571
  var stayFlatRule = {
6446
6572
  meta: {
6447
6573
  schema: [],
@@ -6452,7 +6578,7 @@ var stayFlatRule = {
6452
6578
  },
6453
6579
  create(context) {
6454
6580
  const sourceRoot = sourceRootOf(context);
6455
- const file = path50.resolve(context.filename);
6581
+ const file = path51.resolve(context.filename);
6456
6582
  const segments = segmentsOf(file, sourceRoot);
6457
6583
  if (segments.length !== 3 || segments[0] !== "features") return {};
6458
6584
  const index = getProjectIndex(sourceRoot);
@@ -6492,7 +6618,7 @@ var stayFlatRule = {
6492
6618
  };
6493
6619
 
6494
6620
  // eslint/rules/support-file-placement.ts
6495
- import path51 from "path";
6621
+ import path52 from "path";
6496
6622
  var CONFIG_OWNED_FOLDERS = /* @__PURE__ */ new Set(["types", "constants"]);
6497
6623
  var EXPORT_KIND_BY_SUPPORT_FOLDER = /* @__PURE__ */ new Map([
6498
6624
  ["constants", "constant"],
@@ -6517,7 +6643,7 @@ var supportFilePlacementRule = {
6517
6643
  },
6518
6644
  create(context) {
6519
6645
  const sourceRoot = sourceRootOf(context);
6520
- const supportFile = path51.resolve(context.filename);
6646
+ const supportFile = path52.resolve(context.filename);
6521
6647
  const currentFolder = folderSegmentsOf(supportFile, sourceRoot);
6522
6648
  const supportFolder = currentFolder[currentFolder.length - 1];
6523
6649
  if (supportFolder === void 0 || !SUPPORT_FOLDERS.has(supportFolder)) return {};
@@ -6571,7 +6697,7 @@ var supportFilePlacementRule = {
6571
6697
 
6572
6698
  // eslint/rules/support-folder-shape.ts
6573
6699
  import fs6 from "fs";
6574
- import path52 from "path";
6700
+ import path53 from "path";
6575
6701
  var SUPPORT_FOLDERS4 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
6576
6702
  var INDEX_NAMES2 = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
6577
6703
  var supportFolderShapeRule = {
@@ -6583,12 +6709,12 @@ var supportFolderShapeRule = {
6583
6709
  }
6584
6710
  },
6585
6711
  create(context) {
6586
- const filename = path52.resolve(context.filename);
6587
- const baseName = path52.basename(filename);
6712
+ const filename = path53.resolve(context.filename);
6713
+ const baseName = path53.basename(filename);
6588
6714
  if (!INDEX_NAMES2.has(baseName)) return {};
6589
- const folder = path52.basename(path52.dirname(filename));
6715
+ const folder = path53.basename(path53.dirname(filename));
6590
6716
  if (!SUPPORT_FOLDERS4.has(folder)) return {};
6591
- const directory = path52.dirname(filename);
6717
+ const directory = path53.dirname(filename);
6592
6718
  let entries;
6593
6719
  try {
6594
6720
  entries = fs6.readdirSync(directory);
@@ -6606,7 +6732,7 @@ var supportFolderShapeRule = {
6606
6732
  for (const match of source.matchAll(exportPattern)) {
6607
6733
  hasAnyReExport = true;
6608
6734
  const specifier = match.groups?.specifier;
6609
- if (specifier?.startsWith(".")) exportedFiles.add(path52.basename(specifier));
6735
+ if (specifier?.startsWith(".")) exportedFiles.add(path53.basename(specifier));
6610
6736
  }
6611
6737
  const guide = `docs/next-codebase-guide/rules/${folder === "constants" ? "constants" : "types-and-schemas"}-rule.md`;
6612
6738
  if (siblingModules.length === 0) {
@@ -6785,11 +6911,11 @@ var baseLayerPairRule = {
6785
6911
 
6786
6912
  // eslint/rules/tailwind/css-entry-point.ts
6787
6913
  import { statSync as statSync4 } from "fs";
6788
- import path55 from "path";
6914
+ import path56 from "path";
6789
6915
 
6790
6916
  // eslint/rules/tailwind/source-files.ts
6791
6917
  import { readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync3 } from "fs";
6792
- import path53 from "path";
6918
+ import path54 from "path";
6793
6919
  var CSS_EXTENSIONS = [".css"];
6794
6920
  var MODULE_EXTENSIONS4 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
6795
6921
  var SOURCE_EXTENSIONS = [...MODULE_EXTENSIONS4, ...CSS_EXTENSIONS];
@@ -6802,7 +6928,7 @@ function findFiles(dir, extensions) {
6802
6928
  }
6803
6929
  return entries.flatMap((entry) => {
6804
6930
  if (entry.startsWith(".") || entry === "node_modules") return [];
6805
- const entryPath = path53.join(dir, entry);
6931
+ const entryPath = path54.join(dir, entry);
6806
6932
  let stats;
6807
6933
  try {
6808
6934
  stats = statSync3(entryPath);
@@ -6810,7 +6936,7 @@ function findFiles(dir, extensions) {
6810
6936
  return [];
6811
6937
  }
6812
6938
  if (stats.isDirectory()) return findFiles(entryPath, extensions);
6813
- return extensions.includes(path53.extname(entry)) ? [entryPath] : [];
6939
+ return extensions.includes(path54.extname(entry)) ? [entryPath] : [];
6814
6940
  });
6815
6941
  }
6816
6942
  function cachedTextReader() {
@@ -6833,7 +6959,7 @@ function escapeRegExp(text) {
6833
6959
  }
6834
6960
 
6835
6961
  // eslint/rules/tailwind/stylesheet-graph.ts
6836
- import path54 from "path";
6962
+ import path55 from "path";
6837
6963
  function registersTailwind(text) {
6838
6964
  return /@import\s+(?:url\(\s*)?["']tailwindcss["']\s*\)?/i.test(text);
6839
6965
  }
@@ -6847,25 +6973,25 @@ function moduleImports(text, fileName) {
6847
6973
  return new RegExp(`(?:import|require)\\s*\\(?\\s*["'][^"']*${escaped}["']`, "i").test(text);
6848
6974
  }
6849
6975
  function resolveSpecifier2(fromFile, spec, sourceRoot) {
6850
- if (spec.startsWith("/")) return path54.resolve(spec);
6851
- if (spec.startsWith("./") || spec.startsWith("../")) return path54.resolve(path54.dirname(fromFile), spec);
6852
- if (spec.startsWith("@/")) return path54.resolve(sourceRoot, spec.slice(2));
6976
+ if (spec.startsWith("/")) return path55.resolve(spec);
6977
+ if (spec.startsWith("./") || spec.startsWith("../")) return path55.resolve(path55.dirname(fromFile), spec);
6978
+ if (spec.startsWith("@/")) return path55.resolve(sourceRoot, spec.slice(2));
6853
6979
  return void 0;
6854
6980
  }
6855
6981
  function buildStylesheetGraph(options) {
6856
6982
  const { cssFiles, sourceRoot, textOf } = options;
6857
- const cssSet = new Set(cssFiles.map((file) => path54.normalize(file)));
6983
+ const cssSet = new Set(cssFiles.map((file) => path55.normalize(file)));
6858
6984
  const globals = cssFiles.filter((file) => registersTailwind(textOf(file)));
6859
6985
  const reachable = /* @__PURE__ */ new Set();
6860
6986
  const queue = [...globals];
6861
- for (const global of globals) reachable.add(path54.normalize(global));
6987
+ for (const global of globals) reachable.add(path55.normalize(global));
6862
6988
  while (queue.length > 0) {
6863
6989
  const from = queue.shift();
6864
6990
  if (!from) continue;
6865
6991
  for (const spec of importedSpecifiers(textOf(from))) {
6866
6992
  const target = resolveSpecifier2(from, spec, sourceRoot);
6867
6993
  if (!target) continue;
6868
- const normalized = path54.normalize(target);
6994
+ const normalized = path55.normalize(target);
6869
6995
  if (cssSet.has(normalized) && !reachable.has(normalized)) {
6870
6996
  reachable.add(normalized);
6871
6997
  queue.push(normalized);
@@ -6877,7 +7003,7 @@ function buildStylesheetGraph(options) {
6877
7003
  for (const spec of importedSpecifiers(textOf(global))) {
6878
7004
  const target = resolveSpecifier2(global, spec, sourceRoot);
6879
7005
  if (!target) continue;
6880
- const normalized = path54.normalize(target);
7006
+ const normalized = path55.normalize(target);
6881
7007
  if (cssSet.has(normalized)) directChildren.add(normalized);
6882
7008
  }
6883
7009
  }
@@ -6885,8 +7011,8 @@ function buildStylesheetGraph(options) {
6885
7011
  }
6886
7012
 
6887
7013
  // eslint/rules/tailwind/css-entry-point.ts
6888
- var APP_STYLES_DIR = path55.join("app", "styles");
6889
- var GLOBAL_STYLESHEET_PATH = path55.join(APP_STYLES_DIR, "globals.css");
7014
+ var APP_STYLES_DIR = path56.join("app", "styles");
7015
+ var GLOBAL_STYLESHEET_PATH = path56.join(APP_STYLES_DIR, "globals.css");
6890
7016
  var cssEntryPointRule = {
6891
7017
  meta: {
6892
7018
  schema: [],
@@ -6912,8 +7038,8 @@ var cssEntryPointRule = {
6912
7038
  return {
6913
7039
  "StyleSheet:exit"(node) {
6914
7040
  if (globals.length === 0) return;
6915
- const current = path55.normalize(path55.resolve(context.filename));
6916
- const relative = path55.relative(sourceRoot, current);
7041
+ const current = path56.normalize(path56.resolve(context.filename));
7042
+ const relative = path56.relative(sourceRoot, current);
6917
7043
  if (globals.includes(current)) {
6918
7044
  if (globals.length > 1) {
6919
7045
  context.report({
@@ -6929,7 +7055,7 @@ var cssEntryPointRule = {
6929
7055
  });
6930
7056
  return;
6931
7057
  }
6932
- const basename = path55.basename(current);
7058
+ const basename = path56.basename(current);
6933
7059
  const importCount = moduleFiles.filter((modulePath) => moduleImports(textOf(modulePath), basename)).length;
6934
7060
  if (importCount !== 1) {
6935
7061
  context.report({
@@ -6939,7 +7065,7 @@ var cssEntryPointRule = {
6939
7065
  }
6940
7066
  return;
6941
7067
  }
6942
- const isInAppStyles = relative === APP_STYLES_DIR || relative.startsWith(`${APP_STYLES_DIR}${path55.sep}`);
7068
+ const isInAppStyles = relative === APP_STYLES_DIR || relative.startsWith(`${APP_STYLES_DIR}${path56.sep}`);
6943
7069
  if (!isInAppStyles) {
6944
7070
  context.report({
6945
7071
  node,
@@ -7428,7 +7554,7 @@ var tailwindRules = {
7428
7554
  };
7429
7555
 
7430
7556
  // eslint/rules/type-extraction.ts
7431
- import path56 from "path";
7557
+ import path57 from "path";
7432
7558
  var typeExtractionRule = {
7433
7559
  meta: {
7434
7560
  schema: [],
@@ -7439,7 +7565,7 @@ var typeExtractionRule = {
7439
7565
  },
7440
7566
  create(context) {
7441
7567
  const sourceRoot = sourceRootOf(context);
7442
- const file = path56.resolve(context.filename);
7568
+ const file = path57.resolve(context.filename);
7443
7569
  const segments = segmentsOf(file, sourceRoot);
7444
7570
  if (segments.length === 0) return {};
7445
7571
  const index = getProjectIndex(sourceRoot);
@@ -7574,7 +7700,7 @@ var uiStateRule = {
7574
7700
  // eslint/rules/unknown-utility.ts
7575
7701
  import { existsSync as existsSync6, readdirSync as readdirSync4, readFileSync as readFileSync10, statSync as statSync6 } from "fs";
7576
7702
  import { createRequire } from "module";
7577
- import path57 from "path";
7703
+ import path58 from "path";
7578
7704
  var PREFIX_NAMESPACES = {
7579
7705
  bg: ["color"],
7580
7706
  text: ["color", "text"],
@@ -7814,7 +7940,7 @@ function stylesheetFiles(dir) {
7814
7940
  }
7815
7941
  return entries.flatMap((entry) => {
7816
7942
  if (entry.startsWith(".") || entry === "node_modules") return [];
7817
- const entryPath = path57.join(dir, entry);
7943
+ const entryPath = path58.join(dir, entry);
7818
7944
  let stats;
7819
7945
  try {
7820
7946
  stats = statSync6(entryPath);
@@ -7822,7 +7948,7 @@ function stylesheetFiles(dir) {
7822
7948
  return [];
7823
7949
  }
7824
7950
  if (stats.isDirectory()) return stylesheetFiles(entryPath);
7825
- return path57.extname(entry) === ".css" ? [entryPath] : [];
7951
+ return path58.extname(entry) === ".css" ? [entryPath] : [];
7826
7952
  });
7827
7953
  }
7828
7954
  function packageNameOf(specifier) {
@@ -7833,10 +7959,10 @@ function packageNameOf(specifier) {
7833
7959
  function resolvePackageStylesheet(fromFile, specifier) {
7834
7960
  const packageName = packageNameOf(specifier);
7835
7961
  if (!packageName || packageName === "tailwindcss") return void 0;
7836
- let directory = path57.dirname(fromFile);
7837
- while (directory !== path57.dirname(directory)) {
7838
- const packageRoot = path57.join(directory, "node_modules", packageName);
7839
- const manifestPath = path57.join(packageRoot, "package.json");
7962
+ let directory = path58.dirname(fromFile);
7963
+ while (directory !== path58.dirname(directory)) {
7964
+ const packageRoot = path58.join(directory, "node_modules", packageName);
7965
+ const manifestPath = path58.join(packageRoot, "package.json");
7840
7966
  if (existsSync6(manifestPath)) {
7841
7967
  try {
7842
7968
  const manifest = readFileSync10(manifestPath, "utf8");
@@ -7844,13 +7970,13 @@ function resolvePackageStylesheet(fromFile, specifier) {
7844
7970
  const main = /"main"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
7845
7971
  const target = stylesheet ?? main;
7846
7972
  if (!target) return void 0;
7847
- const resolved = path57.resolve(packageRoot, target);
7973
+ const resolved = path58.resolve(packageRoot, target);
7848
7974
  return existsSync6(resolved) ? resolved : void 0;
7849
7975
  } catch {
7850
7976
  return void 0;
7851
7977
  }
7852
7978
  }
7853
- directory = path57.dirname(directory);
7979
+ directory = path58.dirname(directory);
7854
7980
  }
7855
7981
  return void 0;
7856
7982
  }
@@ -8101,7 +8227,7 @@ var unknownUtilityRule = {
8101
8227
  };
8102
8228
 
8103
8229
  // eslint/rules/util-file-name.ts
8104
- import path58 from "path";
8230
+ import path59 from "path";
8105
8231
  function toKebabCase2(value) {
8106
8232
  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();
8107
8233
  }
@@ -8114,7 +8240,7 @@ var utilFileNameRule = {
8114
8240
  }
8115
8241
  },
8116
8242
  create(context) {
8117
- const filename = path58.resolve(context.filename);
8243
+ const filename = path59.resolve(context.filename);
8118
8244
  const segments = filename.replace(/\\/g, "/").split("/");
8119
8245
  if (!segments.includes("utils")) return {};
8120
8246
  let module;
@@ -8128,13 +8254,13 @@ var utilFileNameRule = {
8128
8254
  const functionName = functions[0]?.name;
8129
8255
  if (!functionName) return {};
8130
8256
  const expected = toKebabCase2(functionName);
8131
- const actual = path58.basename(filename, path58.extname(filename));
8257
+ const actual = path59.basename(filename, path59.extname(filename));
8132
8258
  if (!expected || actual === expected) return {};
8133
8259
  return {
8134
8260
  Program(node) {
8135
8261
  context.report({
8136
8262
  node,
8137
- message: `A utility file exporting ${functionName} must be named ${expected}.${path58.extname(filename).slice(1)}.`
8263
+ message: `A utility file exporting ${functionName} must be named ${expected}.${path59.extname(filename).slice(1)}.`
8138
8264
  });
8139
8265
  }
8140
8266
  };
@@ -8142,7 +8268,7 @@ var utilFileNameRule = {
8142
8268
  };
8143
8269
 
8144
8270
  // eslint/rules/value-extraction.ts
8145
- import path59 from "path";
8271
+ import path60 from "path";
8146
8272
  var valueExtractionRule = {
8147
8273
  meta: {
8148
8274
  schema: [],
@@ -8153,7 +8279,7 @@ var valueExtractionRule = {
8153
8279
  },
8154
8280
  create(context) {
8155
8281
  const sourceRoot = sourceRootOf(context);
8156
- const file = path59.resolve(context.filename);
8282
+ const file = path60.resolve(context.filename);
8157
8283
  const segments = segmentsOf(file, sourceRoot);
8158
8284
  if (segments.length === 0 || segments[0] !== "app") return {};
8159
8285
  const index = getProjectIndex(sourceRoot);
@@ -8175,7 +8301,7 @@ var valueExtractionRule = {
8175
8301
 
8176
8302
  // eslint/rules/vulyk/tracked-docs.ts
8177
8303
  import { existsSync as existsSync7, readFileSync as readFileSync11 } from "fs";
8178
- import path60 from "path";
8304
+ import path61 from "path";
8179
8305
  var PASIKA_REPO = "Bredansky/pasika";
8180
8306
  var BASE_REQUIRED_TRACKED_DOCS = [
8181
8307
  { name: "documentation-guide", path: "docs/documentation-guide" },
@@ -8208,8 +8334,8 @@ var trackedDocsRule = {
8208
8334
  if (!context.filename.endsWith("package.json")) return;
8209
8335
  const root = node.body;
8210
8336
  if (root.type !== "Object") return;
8211
- const projectRoot = path60.dirname(path60.resolve(context.filename));
8212
- const configPath = path60.join(projectRoot, "vulyk.config.ts");
8337
+ const projectRoot = path61.dirname(path61.resolve(context.filename));
8338
+ const configPath = path61.join(projectRoot, "vulyk.config.ts");
8213
8339
  if (!existsSync7(configPath)) {
8214
8340
  context.report({
8215
8341
  node,
@@ -8234,7 +8360,7 @@ var trackedDocsRule = {
8234
8360
  });
8235
8361
  }
8236
8362
  }
8237
- const agentsPath = path60.join(projectRoot, "AGENTS.md");
8363
+ const agentsPath = path61.join(projectRoot, "AGENTS.md");
8238
8364
  if (!existsSync7(agentsPath)) {
8239
8365
  context.report({
8240
8366
  node,
@@ -8334,7 +8460,7 @@ var withResponseHelperRule = {
8334
8460
 
8335
8461
  // eslint/rules/zirka-baseline.ts
8336
8462
  import fs7 from "fs";
8337
- import path61 from "path";
8463
+ import path62 from "path";
8338
8464
  var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
8339
8465
  var PRETTIER_CONFIGS = [
8340
8466
  "prettier.config.mjs",
@@ -8353,10 +8479,10 @@ var zirkaBaselineRule = {
8353
8479
  }
8354
8480
  },
8355
8481
  create(context) {
8356
- const filename = path61.resolve(context.filename);
8357
- const basename = path61.basename(filename);
8482
+ const filename = path62.resolve(context.filename);
8483
+ const basename = path62.basename(filename);
8358
8484
  if (!ESLINT_CONFIG.test(basename)) return {};
8359
- const projectRoot = path61.dirname(filename);
8485
+ const projectRoot = path62.dirname(filename);
8360
8486
  const report3 = (message) => {
8361
8487
  context.report({
8362
8488
  node: context.sourceCode.ast,
@@ -8371,7 +8497,7 @@ var zirkaBaselineRule = {
8371
8497
  'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
8372
8498
  );
8373
8499
  }
8374
- const tsconfigPath = path61.join(projectRoot, "tsconfig.json");
8500
+ const tsconfigPath = path62.join(projectRoot, "tsconfig.json");
8375
8501
  if (!fs7.existsSync(tsconfigPath)) {
8376
8502
  report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
8377
8503
  } else {
@@ -8389,13 +8515,13 @@ var zirkaBaselineRule = {
8389
8515
  report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
8390
8516
  }
8391
8517
  }
8392
- const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path61.join(projectRoot, name)));
8518
+ const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path62.join(projectRoot, name)));
8393
8519
  if (!prettierConfigFile) {
8394
8520
  report3(
8395
8521
  "No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
8396
8522
  );
8397
8523
  } else {
8398
- const content = fs7.readFileSync(path61.join(projectRoot, prettierConfigFile), "utf8");
8524
+ const content = fs7.readFileSync(path62.join(projectRoot, prettierConfigFile), "utf8");
8399
8525
  if (!content.includes("zirka")) {
8400
8526
  report3(
8401
8527
  "The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
@@ -8647,6 +8773,7 @@ var pasikaNextjsAppRules = {
8647
8773
  "locale-placement": localePlacementRule,
8648
8774
  "sole-state-owner": soleStateOwnerRule,
8649
8775
  "locale-key-shape": localeKeyShapeRule,
8776
+ "repeated-numeric-value": repeatedNumericValueRule,
8650
8777
  "repeated-structure": repeatedStructureRule
8651
8778
  };
8652
8779
  var pasikaPlugin = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.58",
3
+ "version": "0.10.60",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",