pasika 0.10.95 → 0.10.96

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.
@@ -444,8 +444,8 @@ function parseModule(file) {
444
444
  }
445
445
  continue;
446
446
  }
447
- const isExported2 = ts.canHaveModifiers(statement) ? (ts.getModifiers(statement) ?? []).some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword) : false;
448
- if (!isExported2) continue;
447
+ const isExported3 = ts.canHaveModifiers(statement) ? (ts.getModifiers(statement) ?? []).some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword) : false;
448
+ if (!isExported3) continue;
449
449
  if (ts.isFunctionDeclaration(statement) && statement.name) {
450
450
  const name = statement.name.text;
451
451
  exports.push({
@@ -3261,19 +3261,34 @@ var enumPlacementRule = {
3261
3261
  schema: [],
3262
3262
  type: "problem",
3263
3263
  docs: {
3264
- description: "Require TypeScript enum declarations to live in constants/ folders."
3264
+ description: "Keep file-local enums local, place shared enums in constants/, and avoid one-member enums."
3265
3265
  }
3266
3266
  },
3267
3267
  create(context) {
3268
3268
  const filename = path25.resolve(context.filename);
3269
3269
  const sourceRoot = sourceRootOf(context);
3270
3270
  if (!filename.startsWith(sourceRoot + path25.sep)) return {};
3271
- if (path25.basename(path25.dirname(filename)) === "constants") return {};
3271
+ const inConstantsFolder = path25.basename(path25.dirname(filename)) === "constants";
3272
+ const index = getProjectIndex(sourceRoot);
3272
3273
  return {
3273
3274
  TSEnumDeclaration(node) {
3275
+ const enumBody = "body" in node ? node.body : void 0;
3276
+ const members = enumBody && typeof enumBody === "object" && "members" in enumBody ? enumBody.members : void 0;
3277
+ const enumId = "id" in node ? node.id : void 0;
3278
+ const enumName = enumId && typeof enumId === "object" && "name" in enumId ? enumId.name : void 0;
3279
+ if (!Array.isArray(members) || typeof enumName !== "string") return;
3280
+ if (members.length === 1) {
3281
+ context.report({
3282
+ node,
3283
+ message: "A single named string or number value must be a const, not a one-member enum. See docs/next-codebase-guide/rules/constants-rule.md"
3284
+ });
3285
+ return;
3286
+ }
3287
+ const shared = (index?.symbolConsumers.get(symbolKey(filename, enumName))?.size ?? 0) > 0;
3288
+ if (inConstantsFolder || !shared) return;
3274
3289
  context.report({
3275
3290
  node,
3276
- message: "A TypeScript enum must live in a constants/ folder because it creates runtime values as well as a type. See docs/next-codebase-guide/rules/constants-rule.md"
3291
+ message: "An enum imported by another file must live in a constants/ folder at its CCF; keep file-local enums beside their consumers. See docs/next-codebase-guide/rules/constants-rule.md"
3277
3292
  });
3278
3293
  }
3279
3294
  };
@@ -4614,10 +4629,10 @@ function localePlacement(text) {
4614
4629
  const sourceFile = ts6.createSourceFile("locales.ts", text, ts6.ScriptTarget.Latest, true, ts6.ScriptKind.TS);
4615
4630
  for (const statement of sourceFile.statements) {
4616
4631
  if (!ts6.isVariableStatement(statement)) continue;
4617
- const isExported2 = (ts6.getModifiers(statement) ?? []).some(
4632
+ const isExported3 = (ts6.getModifiers(statement) ?? []).some(
4618
4633
  (modifier) => modifier.kind === ts6.SyntaxKind.ExportKeyword
4619
4634
  );
4620
- if (!isExported2) continue;
4635
+ if (!isExported3) continue;
4621
4636
  for (const declaration of statement.declarationList.declarations) {
4622
4637
  if (!ts6.isIdentifier(declaration.name) || declaration.name.text !== "locales") continue;
4623
4638
  if (!declaration.initializer || !ts6.isObjectLiteralExpression(declaration.initializer)) continue;
@@ -6361,7 +6376,7 @@ var preferEnumRule = {
6361
6376
  }
6362
6377
  for (const unionCall of discriminatedUnions) {
6363
6378
  const [discriminatorArg, optionsArg] = unionCall.arguments ?? [];
6364
- if (discriminatorArg?.type !== "Literal" || typeof discriminatorArg.value !== "string" || optionsArg?.type !== "ArrayExpression") {
6379
+ if (discriminatorArg?.type !== "Literal" || typeof discriminatorArg.value !== "string" || optionsArg?.type !== "ArrayExpression" || optionsArg.elements.length < 2) {
6365
6380
  continue;
6366
6381
  }
6367
6382
  for (const option of optionsArg.elements) {
@@ -6391,7 +6406,7 @@ var preferEnumRule = {
6391
6406
  }
6392
6407
  const expression = node.expression;
6393
6408
  if (!expression || expression.type !== "ObjectExpression") return;
6394
- if (expression.properties.length === 0) return;
6409
+ if (expression.properties.length < 2) return;
6395
6410
  if (!expression.properties.every(isEnumConvertibleProperty)) return;
6396
6411
  context.report({
6397
6412
  node,
@@ -7109,7 +7124,7 @@ var repeatedNumericValueRule = {
7109
7124
  schema: [],
7110
7125
  type: "problem",
7111
7126
  docs: {
7112
- description: "Require repeated named numeric values across production files to use one extracted constant or enum."
7127
+ description: "Require repeated named numeric values across production files to use one shared constant."
7113
7128
  }
7114
7129
  },
7115
7130
  create(context) {
@@ -7144,7 +7159,467 @@ var repeatedNumericValueRule = {
7144
7159
  context.report({
7145
7160
  node,
7146
7161
  loc: { line: literal.line, column: 0 },
7147
- 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`
7162
+ message: `The numeric value ${String(literal.value)} is repeated for the "${literal.semanticName}" semantic slot in ${String(files.size)} production files. Extract one constant at their CCF and import it instead. See docs/next-codebase-guide/rules/constants-rule.md`
7163
+ });
7164
+ }
7165
+ }
7166
+ };
7167
+ }
7168
+ };
7169
+
7170
+ // eslint/rules/repeated-semantic-literal.ts
7171
+ import path49 from "path";
7172
+
7173
+ // eslint/project/semantic-literals.ts
7174
+ import { readFileSync as readFileSync10 } from "fs";
7175
+ import path47 from "path";
7176
+ import ts10 from "typescript";
7177
+ var excludedProperties = /* @__PURE__ */ new Set([
7178
+ "label",
7179
+ "title",
7180
+ "description",
7181
+ "message",
7182
+ "text",
7183
+ "placeholder",
7184
+ "className",
7185
+ "content",
7186
+ "alt",
7187
+ "src",
7188
+ "href",
7189
+ "url",
7190
+ "html",
7191
+ "ariaLabel",
7192
+ "testId"
7193
+ ]);
7194
+ var semanticProperties = /* @__PURE__ */ new Set(["status", "phase", "event", "eventName", "action", "storageKey", "endpoint"]);
7195
+ var semanticVariableName = /route|path|key|status|event|timeout|delay|token|column|endpoint|limit|duration/i;
7196
+ var columnMethods = /* @__PURE__ */ new Set([
7197
+ "eq",
7198
+ "neq",
7199
+ "gt",
7200
+ "gte",
7201
+ "lt",
7202
+ "lte",
7203
+ "like",
7204
+ "ilike",
7205
+ "is",
7206
+ "in",
7207
+ "order",
7208
+ "filter",
7209
+ "not"
7210
+ ]);
7211
+ var eventMethods = /* @__PURE__ */ new Set(["emit", "on", "off", "once", "addListener", "removeListener"]);
7212
+ var ignoredNumbers = /* @__PURE__ */ new Set([-1, 0, 1]);
7213
+ function isProductionSource(file, root) {
7214
+ const parts = path47.relative(root, file).split(path47.sep);
7215
+ return !(/\.(?:test|spec|mock)\.[^.]+$/.test(path47.basename(file)) || parts.some((part) => part === "__tests__" || part === "__mocks__" || part === "mocks"));
7216
+ }
7217
+ function featureOf(file, root) {
7218
+ const parts = path47.relative(root, file).split(path47.sep);
7219
+ if (parts[0] === "features" && parts[1]) return `feature:${parts[1]}`;
7220
+ return `layer:${parts[0] ?? "src"}`;
7221
+ }
7222
+ function nameOf(property) {
7223
+ if (ts10.isIdentifier(property) || ts10.isStringLiteral(property)) return property.text;
7224
+ return void 0;
7225
+ }
7226
+ function literalOf(node) {
7227
+ if (ts10.isStringLiteral(node)) return node.text;
7228
+ if (ts10.isNumericLiteral(node)) return Number(node.text.replaceAll("_", ""));
7229
+ if (ts10.isPrefixUnaryExpression(node) && node.operator === ts10.SyntaxKind.MinusToken && ts10.isNumericLiteral(node.operand)) {
7230
+ return -Number(node.operand.text.replaceAll("_", ""));
7231
+ }
7232
+ return void 0;
7233
+ }
7234
+ function isLiteralRoot(node) {
7235
+ if (ts10.isPrefixUnaryExpression(node)) return literalOf(node) !== void 0;
7236
+ return (ts10.isStringLiteral(node) || ts10.isNumericLiteral(node)) && !(ts10.isPrefixUnaryExpression(node.parent) && node.parent.operand === node);
7237
+ }
7238
+ function invocation(node) {
7239
+ if (ts10.isIdentifier(node.expression)) return { method: node.expression.text };
7240
+ if (ts10.isPropertyAccessExpression(node.expression)) {
7241
+ const receiver = node.expression.expression.getText();
7242
+ if (!/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)?$/.test(receiver)) return void 0;
7243
+ return { method: node.expression.name.text, receiver };
7244
+ }
7245
+ return void 0;
7246
+ }
7247
+ function isPathname(node) {
7248
+ return ts10.isPropertyAccessExpression(node) && node.name.text === "pathname";
7249
+ }
7250
+ function contextFor(node, value, file, root) {
7251
+ if (typeof value === "number" && ignoredNumbers.has(value)) return void 0;
7252
+ if (typeof value === "string" && (value.length < 3 || /\s/.test(value))) return void 0;
7253
+ const parent = node.parent;
7254
+ const scope = featureOf(file, root);
7255
+ const isApiRoute = typeof value === "string" && value.startsWith("/api/") && !/[?&#\s]/.test(value);
7256
+ const route = () => ({ role: "api-route", family: "api-route" });
7257
+ if (ts10.isPropertyAssignment(parent) && parent.initializer === node) {
7258
+ const name = nameOf(parent.name);
7259
+ if (!name) return void 0;
7260
+ if (name === "path" && isApiRoute) return route();
7261
+ if (!semanticProperties.has(name)) return void 0;
7262
+ if (typeof value === "number") return void 0;
7263
+ if (isApiRoute && /route|path|endpoint/i.test(name)) return route();
7264
+ return { role: `property:${name}:${scope}`, family: `property:${name}` };
7265
+ }
7266
+ if (ts10.isVariableDeclaration(parent) && parent.initializer === node && ts10.isIdentifier(parent.name)) {
7267
+ if (typeof value === "number") return void 0;
7268
+ const name = parent.name.text;
7269
+ if (excludedProperties.has(name) || !semanticVariableName.test(name)) return void 0;
7270
+ if (isApiRoute && /route|path|endpoint/i.test(name)) return route();
7271
+ return { role: `variable:${name}:${scope}`, family: `variable:${name}` };
7272
+ }
7273
+ if (ts10.isCallExpression(parent)) {
7274
+ const position = parent.arguments.findIndex((argument) => argument === node);
7275
+ if (position < 0) return void 0;
7276
+ const call = invocation(parent);
7277
+ if (!call) return void 0;
7278
+ if (isApiRoute && position === 0 && (call.method === "fetch" || call.method === "zodFetch")) return route();
7279
+ if (typeof value === "number" && position === 1 && (call.method === "setTimeout" || call.method === "setInterval")) {
7280
+ return { role: `timer:${call.method}:${scope}`, family: "timer" };
7281
+ }
7282
+ if (typeof value === "string" && position === 0 && call.receiver && (call.receiver === "localStorage" || call.receiver === "sessionStorage") && ["getItem", "setItem", "removeItem"].includes(call.method)) {
7283
+ return { role: `storage:${call.receiver}`, family: "storage" };
7284
+ }
7285
+ if (typeof value === "string" && position === 0 && call.receiver && eventMethods.has(call.method) && /(?:event|bus|socket|emitter)/i.test(call.receiver)) {
7286
+ return { role: `event:${call.receiver}`, family: "event" };
7287
+ }
7288
+ if (typeof value === "string" && position === 0 && call.receiver && columnMethods.has(call.method) && value.length > 3 && /^[a-z][a-z0-9_]*$/.test(value)) {
7289
+ return { role: `column:${scope}`, family: "column" };
7290
+ }
7291
+ }
7292
+ 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))) {
7293
+ return route();
7294
+ }
7295
+ if (isApiRoute && ts10.isCallExpression(parent) && parent.arguments[0] === node && ts10.isPropertyAccessExpression(parent.expression) && parent.expression.name.text === "startsWith" && isPathname(parent.expression.expression)) {
7296
+ return route();
7297
+ }
7298
+ return void 0;
7299
+ }
7300
+ function isExported2(node) {
7301
+ return ts10.canHaveModifiers(node) && (ts10.getModifiers(node) ?? []).some((modifier) => modifier.kind === ts10.SyntaxKind.ExportKeyword);
7302
+ }
7303
+ function parse(file, root, output) {
7304
+ if (!isProductionSource(file, root)) return;
7305
+ const source = ts10.createSourceFile(
7306
+ file,
7307
+ readFileSync10(file, "utf8"),
7308
+ ts10.ScriptTarget.Latest,
7309
+ true,
7310
+ file.endsWith(".tsx") || file.endsWith(".jsx") ? ts10.ScriptKind.TSX : ts10.ScriptKind.TS
7311
+ );
7312
+ const inConstants = path47.relative(root, file).split(path47.sep).includes("constants");
7313
+ for (const statement of source.statements) {
7314
+ if (inConstants && ts10.isEnumDeclaration(statement) && isExported2(statement)) {
7315
+ for (const member of statement.members) {
7316
+ const value = member.initializer && literalOf(member.initializer);
7317
+ const memberName9 = nameOf(member.name);
7318
+ if (value === void 0 || !memberName9) continue;
7319
+ output.canonicals.push({
7320
+ file,
7321
+ name: memberName9,
7322
+ owner: statement.name.text,
7323
+ kind: typeof value === "string" ? "string" : "number",
7324
+ value
7325
+ });
7326
+ }
7327
+ }
7328
+ if (inConstants && ts10.isVariableStatement(statement) && isExported2(statement)) {
7329
+ for (const declaration of statement.declarationList.declarations) {
7330
+ if (!ts10.isIdentifier(declaration.name) || !declaration.initializer) continue;
7331
+ const value = literalOf(declaration.initializer);
7332
+ if (value === void 0) continue;
7333
+ output.canonicals.push({
7334
+ file,
7335
+ name: declaration.name.text,
7336
+ kind: typeof value === "string" ? "string" : "number",
7337
+ value
7338
+ });
7339
+ }
7340
+ }
7341
+ }
7342
+ const visit = (node) => {
7343
+ if (isLiteralRoot(node)) {
7344
+ const value = literalOf(node);
7345
+ if (value !== void 0) {
7346
+ const semantic = contextFor(node, value, file, root);
7347
+ if (semantic) {
7348
+ const declaration = node.parent;
7349
+ const isCanonicalDefinition = inConstants && (ts10.isVariableDeclaration(declaration) && ts10.isVariableStatement(declaration.parent.parent) && isExported2(declaration.parent.parent) || ts10.isEnumMember(declaration));
7350
+ if ((!inConstants || semantic.family === "api-route") && !isCanonicalDefinition) {
7351
+ const position = source.getLineAndCharacterOfPosition(node.getStart(source));
7352
+ output.uses.push({
7353
+ file,
7354
+ kind: typeof value === "string" ? "string" : "number",
7355
+ value,
7356
+ line: position.line + 1,
7357
+ column: position.character,
7358
+ ...semantic
7359
+ });
7360
+ }
7361
+ }
7362
+ }
7363
+ }
7364
+ ts10.forEachChild(node, visit);
7365
+ };
7366
+ visit(source);
7367
+ }
7368
+ var cache3 = /* @__PURE__ */ new WeakMap();
7369
+ function getSemanticLiteralIndex(index) {
7370
+ const previous = cache3.get(index);
7371
+ if (previous) return previous;
7372
+ const result = { uses: [], canonicals: [] };
7373
+ for (const file of index.modules.keys()) {
7374
+ try {
7375
+ parse(file, index.sourceRoot, result);
7376
+ } catch {
7377
+ }
7378
+ }
7379
+ cache3.set(index, result);
7380
+ return result;
7381
+ }
7382
+
7383
+ // eslint/rules/imported-enum-literals.ts
7384
+ import path48 from "path";
7385
+ import ts11 from "typescript";
7386
+ var columnMethods2 = /* @__PURE__ */ new Set([
7387
+ "eq",
7388
+ "neq",
7389
+ "gt",
7390
+ "gte",
7391
+ "lt",
7392
+ "lte",
7393
+ "like",
7394
+ "ilike",
7395
+ "is",
7396
+ "in",
7397
+ "order",
7398
+ "filter",
7399
+ "not"
7400
+ ]);
7401
+ function memberName6(name) {
7402
+ if (ts11.isIdentifier(name) || ts11.isStringLiteral(name)) return name.text;
7403
+ return void 0;
7404
+ }
7405
+ function isWithin3(root, file) {
7406
+ const relative = path48.relative(root, file);
7407
+ return relative === "" || !relative.startsWith("..") && !path48.isAbsolute(relative);
7408
+ }
7409
+ function domainOf(name) {
7410
+ if (name.endsWith("ColumnEnum")) return "column";
7411
+ if (name.endsWith("Route") || name.endsWith("RouteEnum")) return "route";
7412
+ return void 0;
7413
+ }
7414
+ function importedEnums(file, checker, sourceRoot, importedNames) {
7415
+ const matches = /* @__PURE__ */ new Map();
7416
+ for (const statement of file.statements) {
7417
+ if (!ts11.isImportDeclaration(statement) || !statement.importClause?.namedBindings || !ts11.isNamedImports(statement.importClause.namedBindings)) {
7418
+ continue;
7419
+ }
7420
+ for (const specifier of statement.importClause.namedBindings.elements) {
7421
+ if (!importedNames.has(specifier.name.text)) continue;
7422
+ const symbol = checker.getSymbolAtLocation(specifier.name);
7423
+ if (!symbol) continue;
7424
+ const resolved = symbol.flags === ts11.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
7425
+ for (const declaration of resolved.declarations ?? []) {
7426
+ if (!ts11.isEnumDeclaration(declaration)) continue;
7427
+ const declarationFile = path48.resolve(declaration.getSourceFile().fileName);
7428
+ if (!isWithin3(sourceRoot, declarationFile)) continue;
7429
+ const domain = domainOf(declaration.name.text);
7430
+ if (!domain) continue;
7431
+ for (const member of declaration.members) {
7432
+ if (!member.initializer || !ts11.isStringLiteral(member.initializer)) continue;
7433
+ const name = memberName6(member.name);
7434
+ if (!name) continue;
7435
+ const entries = matches.get(member.initializer.text) ?? [];
7436
+ entries.push({
7437
+ reference: `${specifier.name.text}.${name}`,
7438
+ domain,
7439
+ sourceFile: declarationFile
7440
+ });
7441
+ matches.set(member.initializer.text, entries);
7442
+ }
7443
+ }
7444
+ }
7445
+ }
7446
+ return matches;
7447
+ }
7448
+ function isPathname2(node) {
7449
+ return ts11.isPropertyAccessExpression(node) && node.name.text === "pathname";
7450
+ }
7451
+ function domainForUse(node) {
7452
+ const parent = node.parent;
7453
+ if (ts11.isPropertyAssignment(parent) && parent.initializer === node && memberName6(parent.name) === "path") {
7454
+ return "route";
7455
+ }
7456
+ if (ts11.isCallExpression(parent) && parent.arguments[0] === node && ts11.isPropertyAccessExpression(parent.expression)) {
7457
+ const { expression, name } = parent.expression;
7458
+ if (columnMethods2.has(name.text)) return "column";
7459
+ if (name.text === "startsWith" && isPathname2(expression)) return "route";
7460
+ }
7461
+ if (ts11.isBinaryExpression(parent) && (parent.operatorToken.kind === ts11.SyntaxKind.EqualsEqualsEqualsToken || parent.operatorToken.kind === ts11.SyntaxKind.ExclamationEqualsEqualsToken) && (parent.left === node && isPathname2(parent.right) || parent.right === node && isPathname2(parent.left))) {
7462
+ return "route";
7463
+ }
7464
+ return void 0;
7465
+ }
7466
+ function importedEnumLiteralUses(context, root) {
7467
+ const filename = path48.resolve(context.filename);
7468
+ if (!isWithin3(root, filename)) return [];
7469
+ const services = typedParserServices(context.sourceCode.parserServices);
7470
+ if (!services) return [];
7471
+ const file = services.program.getSourceFile(filename);
7472
+ if (file?.text !== context.sourceCode.text) return [];
7473
+ const importedNames = /* @__PURE__ */ new Set();
7474
+ for (const statement of context.sourceCode.ast.body) {
7475
+ if (statement.type !== "ImportDeclaration") continue;
7476
+ for (const specifier of statement.specifiers) importedNames.add(specifier.local.name);
7477
+ }
7478
+ if (importedNames.size === 0) return [];
7479
+ const matches = importedEnums(file, services.program.getTypeChecker(), root, importedNames);
7480
+ if (matches.size === 0) return [];
7481
+ const uses = [];
7482
+ const visit = (node) => {
7483
+ if (ts11.isStringLiteral(node)) {
7484
+ const domain = domainForUse(node);
7485
+ const candidates = matches.get(node.text)?.filter((entry) => entry.domain === domain) ?? [];
7486
+ if (candidates.length === 1) {
7487
+ const match = candidates[0];
7488
+ if (match) {
7489
+ const position = file.getLineAndCharacterOfPosition(node.getStart(file));
7490
+ uses.push({
7491
+ reference: match.reference,
7492
+ sourceFile: match.sourceFile,
7493
+ value: node.text,
7494
+ line: position.line + 1,
7495
+ column: position.character
7496
+ });
7497
+ }
7498
+ }
7499
+ }
7500
+ ts11.forEachChild(node, visit);
7501
+ };
7502
+ visit(file);
7503
+ return uses;
7504
+ }
7505
+
7506
+ // eslint/rules/repeated-semantic-literal.ts
7507
+ var DOC6 = "See docs/next-codebase-guide/rules/constants-rule.md";
7508
+ function canonicalMatches(use, canonical, sourceRoot) {
7509
+ if (use.kind !== canonical.kind || use.value !== canonical.value) return false;
7510
+ const name = canonical.owner ?? canonical.name;
7511
+ if (use.family === "api-route") return /route|path|endpoint/i.test(name);
7512
+ if (use.family === "column") return /column/i.test(name);
7513
+ if (use.family === "timer") return /timeout|delay|interval/i.test(name);
7514
+ if (use.family === "storage") return /key|storage/i.test(name);
7515
+ if (use.family === "event") return /event/i.test(name);
7516
+ if (use.family.startsWith("property:") || use.family.startsWith("variable:")) {
7517
+ const semanticName2 = use.family.split(":")[1];
7518
+ if (!semanticName2 || !name.toLowerCase().includes(semanticName2.toLowerCase())) return false;
7519
+ const location = featureOf(canonical.file, sourceRoot);
7520
+ return location === featureOf(use.file, sourceRoot) || path49.relative(sourceRoot, canonical.file).split(path49.sep)[0] === "constants";
7521
+ }
7522
+ return false;
7523
+ }
7524
+ function formatValue(use) {
7525
+ return typeof use.value === "string" ? JSON.stringify(use.value) : String(use.value);
7526
+ }
7527
+ function canonicalName(canonical) {
7528
+ return canonical.owner ? `${canonical.owner}.${canonical.name}` : canonical.name;
7529
+ }
7530
+ function messageFor(use, matches, duplicateRouteDomains, existingRouteEnum, root) {
7531
+ const count = new Set(matches.map((match) => match.file)).size;
7532
+ const kind = use.kind === "string" ? "string" : "numeric";
7533
+ if (use.family === "api-route" && existingRouteEnum?.owner) {
7534
+ const location = path49.relative(root, existingRouteEnum.file).replaceAll(path49.sep, "/");
7535
+ return `The route ${formatValue(use)} repeats; add a member to existing ${existingRouteEnum.owner} in src/${location} and reuse it. ${DOC6}`;
7536
+ }
7537
+ if (count === 1) {
7538
+ return `The ${kind} literal ${formatValue(use)} repeats in the same semantic role in this file. Extract a file-local const. ${DOC6}`;
7539
+ }
7540
+ const placement = use.family === "api-route" && duplicateRouteDomains.has(use.role) ? "a shared enum for this closed route domain" : "one shared const";
7541
+ return `The ${kind} literal ${formatValue(use)} repeats in ${String(count)} production files for the same semantic role. Extract ${placement} at the consumers' CCF and import it. ${DOC6}`;
7542
+ }
7543
+ var repeatedSemanticLiteralRule = {
7544
+ meta: {
7545
+ schema: [],
7546
+ type: "problem",
7547
+ docs: {
7548
+ description: "Reuse canonical string/number values or extract semantically repeated literals at their CCF."
7549
+ }
7550
+ },
7551
+ create(context) {
7552
+ const root = sourceRootOf(context);
7553
+ const file = path49.resolve(context.filename);
7554
+ if (!isProductionSource(file, root)) return {};
7555
+ const project = getProjectIndex(root);
7556
+ if (!project?.modules.has(file)) return {};
7557
+ const index = getSemanticLiteralIndex(project);
7558
+ const current = index.uses.filter((entry) => entry.file === file);
7559
+ const imported = importedEnumLiteralUses(context, root);
7560
+ if (current.length === 0 && imported.length === 0) return {};
7561
+ const groups = /* @__PURE__ */ new Map();
7562
+ for (const use of index.uses) {
7563
+ const key = `${use.kind}\0${String(use.value)}\0${use.role}`;
7564
+ const group = groups.get(key) ?? [];
7565
+ group.push(use);
7566
+ groups.set(key, group);
7567
+ }
7568
+ const duplicatedApiRoutes = /* @__PURE__ */ new Set();
7569
+ const routeValues = /* @__PURE__ */ new Map();
7570
+ for (const group of groups.values()) {
7571
+ const first = group[0];
7572
+ if (group.length < 2 || first?.family !== "api-route") continue;
7573
+ const values = routeValues.get(first.role) ?? /* @__PURE__ */ new Set();
7574
+ values.add(String(first.value));
7575
+ routeValues.set(first.role, values);
7576
+ }
7577
+ for (const [role, values] of routeValues) {
7578
+ if (values.size >= 2) duplicatedApiRoutes.add(role);
7579
+ }
7580
+ const routeDomains = /* @__PURE__ */ new Map();
7581
+ for (const canonical of index.canonicals) {
7582
+ if (canonical.owner && /^ApiRoute(?:Enum)?$/.test(canonical.owner)) {
7583
+ routeDomains.set(`${canonical.file}:${canonical.owner}`, canonical);
7584
+ }
7585
+ }
7586
+ const existingRouteEnum = routeDomains.size === 1 ? [...routeDomains.values()][0] : void 0;
7587
+ const recognized = new Set(imported.map((use) => `${String(use.line)}:${String(use.column)}`));
7588
+ return {
7589
+ Program(node) {
7590
+ for (const use of imported) {
7591
+ const relative = path49.relative(root, use.sourceFile).replaceAll(path49.sep, "/");
7592
+ context.report({
7593
+ node,
7594
+ loc: { line: use.line, column: use.column },
7595
+ message: `Reuse ${use.reference} from src/${relative} instead of raw ${JSON.stringify(use.value)}. ${DOC6}`
7596
+ });
7597
+ }
7598
+ for (const use of current) {
7599
+ if (recognized.has(`${String(use.line)}:${String(use.column)}`)) continue;
7600
+ const candidates = index.canonicals.filter(
7601
+ (canonical) => canonicalMatches(use, canonical, root) && canonical.file !== file
7602
+ );
7603
+ if (candidates.length === 1) {
7604
+ const canonical = candidates[0];
7605
+ if (!canonical) continue;
7606
+ const relative = path49.relative(root, canonical.file).replaceAll(path49.sep, "/");
7607
+ context.report({
7608
+ node,
7609
+ loc: { line: use.line, column: use.column },
7610
+ message: `Reuse ${canonicalName(canonical)} from src/${relative} instead of raw ${formatValue(use)}. ${DOC6}`
7611
+ });
7612
+ continue;
7613
+ }
7614
+ if (candidates.length > 1) continue;
7615
+ const key = `${use.kind}\0${String(use.value)}\0${use.role}`;
7616
+ const peers = groups.get(key) ?? [];
7617
+ if (peers.length < 2) continue;
7618
+ if (use.kind === "number" && !use.family.startsWith("timer")) continue;
7619
+ context.report({
7620
+ node,
7621
+ loc: { line: use.line, column: use.column },
7622
+ message: messageFor(use, peers, duplicatedApiRoutes, existingRouteEnum, root)
7148
7623
  });
7149
7624
  }
7150
7625
  }
@@ -7334,7 +7809,7 @@ var repeatedStructureRule = {
7334
7809
 
7335
7810
  // eslint/rules/require-barrel-star-exports.ts
7336
7811
  import fs5 from "fs";
7337
- import path47 from "path";
7812
+ import path50 from "path";
7338
7813
  var SUPPORT_FOLDERS3 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
7339
7814
  var INDEX_NAMES = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
7340
7815
  var MODULE_EXTENSIONS3 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
@@ -7342,9 +7817,9 @@ function resolveSiblingModule(indexFile, specifier) {
7342
7817
  if (!specifier.startsWith("./")) return void 0;
7343
7818
  const relative = specifier.slice(2);
7344
7819
  if (!relative || relative.includes("/")) return void 0;
7345
- const directory = path47.dirname(indexFile);
7346
- const direct = path47.resolve(directory, relative);
7347
- const candidates = path47.extname(direct) ? [direct] : MODULE_EXTENSIONS3.map((extension) => `${direct}${extension}`);
7820
+ const directory = path50.dirname(indexFile);
7821
+ const direct = path50.resolve(directory, relative);
7822
+ const candidates = path50.extname(direct) ? [direct] : MODULE_EXTENSIONS3.map((extension) => `${direct}${extension}`);
7348
7823
  return candidates.find((candidate) => fs5.existsSync(candidate) && fs5.statSync(candidate).isFile());
7349
7824
  }
7350
7825
  var requireBarrelStarExportsRule = {
@@ -7357,9 +7832,9 @@ var requireBarrelStarExportsRule = {
7357
7832
  fixable: "code"
7358
7833
  },
7359
7834
  create(context) {
7360
- const filename = path47.resolve(context.filename);
7361
- if (!INDEX_NAMES.has(path47.basename(filename))) return {};
7362
- if (!SUPPORT_FOLDERS3.has(path47.basename(path47.dirname(filename)))) return {};
7835
+ const filename = path50.resolve(context.filename);
7836
+ if (!INDEX_NAMES.has(path50.basename(filename))) return {};
7837
+ if (!SUPPORT_FOLDERS3.has(path50.basename(path50.dirname(filename)))) return {};
7363
7838
  return {
7364
7839
  ExportNamedDeclaration(node) {
7365
7840
  const sourceNode = node.source;
@@ -7412,7 +7887,7 @@ var requireBarrelStarExportsRule = {
7412
7887
  };
7413
7888
 
7414
7889
  // eslint/rules/root-support-placement.ts
7415
- import path48 from "path";
7890
+ import path51 from "path";
7416
7891
  function isSupportFolder(value) {
7417
7892
  return value === "utils" || value === "types" || value === "schemas" || value === "constants";
7418
7893
  }
@@ -7445,7 +7920,7 @@ var rootSupportPlacementRule = {
7445
7920
  },
7446
7921
  create(context) {
7447
7922
  const sourceRoot = sourceRootOf(context);
7448
- const file = path48.resolve(context.filename);
7923
+ const file = path51.resolve(context.filename);
7449
7924
  const segments = segmentsOf(file, sourceRoot);
7450
7925
  const folderSegments = folderSegmentsOf(file, sourceRoot);
7451
7926
  const supportFolder = folderSegments[folderSegments.length - 1];
@@ -7491,8 +7966,8 @@ var rootSupportPlacementRule = {
7491
7966
  };
7492
7967
 
7493
7968
  // eslint/rules/route-handler-shape.ts
7494
- import path49 from "path";
7495
- import ts10 from "typescript";
7969
+ import path52 from "path";
7970
+ import ts12 from "typescript";
7496
7971
  var HTTP_METHODS2 = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
7497
7972
  var REQUIRED_BOUNDARY = "withResponse";
7498
7973
  function isFunctionLike(node) {
@@ -7510,33 +7985,33 @@ function findHandler(node) {
7510
7985
  return void 0;
7511
7986
  }
7512
7987
  function isLoop(node) {
7513
- return ts10.isForStatement(node) || ts10.isForOfStatement(node) || ts10.isForInStatement(node) || ts10.isWhileStatement(node) || ts10.isDoStatement(node);
7988
+ return ts12.isForStatement(node) || ts12.isForOfStatement(node) || ts12.isForInStatement(node) || ts12.isWhileStatement(node) || ts12.isDoStatement(node);
7514
7989
  }
7515
7990
  function isFunctionBoundary(node) {
7516
- return ts10.isFunctionExpression(node) || ts10.isArrowFunction(node) || ts10.isFunctionDeclaration(node);
7991
+ return ts12.isFunctionExpression(node) || ts12.isArrowFunction(node) || ts12.isFunctionDeclaration(node);
7517
7992
  }
7518
7993
  function analyzeHandlerBody(body, sourceText) {
7519
7994
  const start = body.range?.[0] ?? 0;
7520
7995
  const end = body.range?.[1] ?? sourceText.length;
7521
- const sourceFile = ts10.createSourceFile(
7996
+ const sourceFile = ts12.createSourceFile(
7522
7997
  "route.ts",
7523
7998
  sourceText.slice(start, end),
7524
- ts10.ScriptTarget.Latest,
7999
+ ts12.ScriptTarget.Latest,
7525
8000
  true,
7526
- ts10.ScriptKind.TS
8001
+ ts12.ScriptKind.TS
7527
8002
  );
7528
8003
  const kinds = /* @__PURE__ */ new Set();
7529
8004
  const calledNames = /* @__PURE__ */ new Set();
7530
8005
  const visit = (node) => {
7531
- if (ts10.isTryStatement(node)) kinds.add("try");
8006
+ if (ts12.isTryStatement(node)) kinds.add("try");
7532
8007
  if (isLoop(node)) kinds.add("loop");
7533
- if (ts10.isIfStatement(node)) kinds.add("if");
7534
- if (ts10.isCallExpression(node) && ts10.isPropertyAccessExpression(node.expression) && node.expression.name.text === "map") {
8008
+ if (ts12.isIfStatement(node)) kinds.add("if");
8009
+ if (ts12.isCallExpression(node) && ts12.isPropertyAccessExpression(node.expression) && node.expression.name.text === "map") {
7535
8010
  kinds.add("map");
7536
8011
  }
7537
- if (ts10.isCallExpression(node) && ts10.isIdentifier(node.expression)) calledNames.add(node.expression.text);
8012
+ if (ts12.isCallExpression(node) && ts12.isIdentifier(node.expression)) calledNames.add(node.expression.text);
7538
8013
  if (isFunctionBoundary(node)) return;
7539
- ts10.forEachChild(node, visit);
8014
+ ts12.forEachChild(node, visit);
7540
8015
  };
7541
8016
  visit(sourceFile);
7542
8017
  return { kinds, calledNames };
@@ -7576,7 +8051,7 @@ var routeHandlerShapeRule = {
7576
8051
  }
7577
8052
  },
7578
8053
  create(context) {
7579
- if (path49.basename(context.filename) !== "route.ts") return {};
8054
+ if (path52.basename(context.filename) !== "route.ts") return {};
7580
8055
  const sourceText = context.sourceCode.text;
7581
8056
  function reportUnwrapped(node, name) {
7582
8057
  context.report({
@@ -7635,7 +8110,7 @@ var routeHandlerShapeRule = {
7635
8110
  };
7636
8111
 
7637
8112
  // eslint/rules/schema-casing.ts
7638
- import path50 from "path";
8113
+ import path53 from "path";
7639
8114
  function isCamelCase(name) {
7640
8115
  return /^[a-z][a-zA-Z0-9]*$/.test(name);
7641
8116
  }
@@ -7663,9 +8138,9 @@ var schemaCasingRule = {
7663
8138
  }
7664
8139
  },
7665
8140
  create(context) {
7666
- const filename = path50.resolve(context.filename);
8141
+ const filename = path53.resolve(context.filename);
7667
8142
  const sourceRoot = sourceRootOf(context);
7668
- if (!filename.startsWith(sourceRoot + path50.sep)) return {};
8143
+ if (!filename.startsWith(sourceRoot + path53.sep)) return {};
7669
8144
  let zodLocalName;
7670
8145
  return {
7671
8146
  ImportDeclaration(node) {
@@ -7697,39 +8172,39 @@ var schemaCasingRule = {
7697
8172
  };
7698
8173
 
7699
8174
  // eslint/rules/sole-state-owner.ts
7700
- import path51 from "path";
7701
- import ts11 from "typescript";
8175
+ import path54 from "path";
8176
+ import ts13 from "typescript";
7702
8177
  function findStateHooks(node) {
7703
8178
  const hooks = [];
7704
8179
  const visit = (child) => {
7705
- if (ts11.isCallExpression(child) && ts11.isIdentifier(child.expression) && child.expression.text === "useState") {
7706
- if (ts11.isVariableDeclaration(child.parent)) {
8180
+ if (ts13.isCallExpression(child) && ts13.isIdentifier(child.expression) && child.expression.text === "useState") {
8181
+ if (ts13.isVariableDeclaration(child.parent)) {
7707
8182
  const { name } = child.parent;
7708
- if (ts11.isArrayBindingPattern(name) && name.elements.length >= 2) {
8183
+ if (ts13.isArrayBindingPattern(name) && name.elements.length >= 2) {
7709
8184
  const value = name.elements[0];
7710
8185
  const updater = name.elements[1];
7711
- if (value && updater && ts11.isBindingElement(value) && ts11.isBindingElement(updater)) {
8186
+ if (value && updater && ts13.isBindingElement(value) && ts13.isBindingElement(updater)) {
7712
8187
  const valueName = value.name;
7713
8188
  const updaterName = updater.name;
7714
- if (ts11.isIdentifier(valueName) && ts11.isIdentifier(updaterName)) {
8189
+ if (ts13.isIdentifier(valueName) && ts13.isIdentifier(updaterName)) {
7715
8190
  hooks.push({ value: valueName.text, updater: updaterName.text });
7716
8191
  }
7717
8192
  }
7718
8193
  }
7719
8194
  }
7720
8195
  }
7721
- ts11.forEachChild(child, visit);
8196
+ ts13.forEachChild(child, visit);
7722
8197
  };
7723
8198
  visit(node);
7724
8199
  return hooks;
7725
8200
  }
7726
8201
  function isHookUsage(node, hook) {
7727
- if (ts11.isCallExpression(node) && ts11.isIdentifier(node.expression) && node.expression.text === hook.updater) {
8202
+ if (ts13.isCallExpression(node) && ts13.isIdentifier(node.expression) && node.expression.text === hook.updater) {
7728
8203
  return "updater";
7729
8204
  }
7730
- if (ts11.isIdentifier(node) && node.text === hook.value) {
8205
+ if (ts13.isIdentifier(node) && node.text === hook.value) {
7731
8206
  const parent = node.parent;
7732
- if (ts11.isBindingElement(parent) || ts11.isPropertyAccessExpression(parent) || ts11.isShorthandPropertyAssignment(parent)) {
8207
+ if (ts13.isBindingElement(parent) || ts13.isPropertyAccessExpression(parent) || ts13.isShorthandPropertyAssignment(parent)) {
7733
8208
  return void 0;
7734
8209
  }
7735
8210
  return "value";
@@ -7739,16 +8214,16 @@ function isHookUsage(node, hook) {
7739
8214
  function topLevelJsxChildren(initial) {
7740
8215
  if (!initial) return void 0;
7741
8216
  let expression = initial;
7742
- while (ts11.isParenthesizedExpression(expression)) expression = expression.expression;
7743
- if (ts11.isJsxFragment(expression)) {
8217
+ while (ts13.isParenthesizedExpression(expression)) expression = expression.expression;
8218
+ if (ts13.isJsxFragment(expression)) {
7744
8219
  const children = expression.children.filter(
7745
- (c) => !ts11.isJsxText(c) && !ts11.isJsxSpreadAttribute(c)
8220
+ (c) => !ts13.isJsxText(c) && !ts13.isJsxSpreadAttribute(c)
7746
8221
  );
7747
8222
  return { root: expression, children };
7748
8223
  }
7749
- if (ts11.isJsxElement(expression)) {
8224
+ if (ts13.isJsxElement(expression)) {
7750
8225
  const children = expression.children.filter(
7751
- (c) => !ts11.isJsxText(c) && !ts11.isJsxSpreadAttribute(c)
8226
+ (c) => !ts13.isJsxText(c) && !ts13.isJsxSpreadAttribute(c)
7752
8227
  );
7753
8228
  return { root: expression, children };
7754
8229
  }
@@ -7762,8 +8237,8 @@ function collectUsesIn(child, hook) {
7762
8237
  positions.push(node);
7763
8238
  count += 1;
7764
8239
  }
7765
- if (ts11.isFunctionDeclaration(node) || ts11.isClassDeclaration(node)) return;
7766
- ts11.forEachChild(node, visit);
8240
+ if (ts13.isFunctionDeclaration(node) || ts13.isClassDeclaration(node)) return;
8241
+ ts13.forEachChild(node, visit);
7767
8242
  };
7768
8243
  visit(child);
7769
8244
  return { positions, count };
@@ -7777,7 +8252,7 @@ var soleStateOwnerRule = {
7777
8252
  }
7778
8253
  },
7779
8254
  create(context) {
7780
- const filename = path51.resolve(context.filename);
8255
+ const filename = path54.resolve(context.filename);
7781
8256
  if (!filename.endsWith(".tsx") && !filename.endsWith(".jsx")) return {};
7782
8257
  const text = context.sourceCode.text;
7783
8258
  const components = parseComponentInfo(text, filename);
@@ -7802,18 +8277,18 @@ var soleStateOwnerRule = {
7802
8277
  }
7803
8278
  };
7804
8279
  function analyzeSoleOwner(declaration, hook) {
7805
- const body = ts11.isFunctionDeclaration(declaration) ? declaration.body : void 0;
7806
- if (!body || !ts11.isBlock(body)) return void 0;
8280
+ const body = ts13.isFunctionDeclaration(declaration) ? declaration.body : void 0;
8281
+ if (!body || !ts13.isBlock(body)) return void 0;
7807
8282
  const returns = [];
7808
8283
  const visit = (node) => {
7809
- if (node !== body && (ts11.isFunctionLike(node) || ts11.isClassLike(node))) return;
7810
- if (ts11.isReturnStatement(node)) returns.push(node);
7811
- ts11.forEachChild(node, visit);
8284
+ if (node !== body && (ts13.isFunctionLike(node) || ts13.isClassLike(node))) return;
8285
+ if (ts13.isReturnStatement(node)) returns.push(node);
8286
+ ts13.forEachChild(node, visit);
7812
8287
  };
7813
8288
  visit(body);
7814
8289
  if (returns.length !== 1) return void 0;
7815
8290
  const single = returns[0];
7816
- if (!single?.expression || !ts11.isExpression(single.expression)) return void 0;
8291
+ if (!single?.expression || !ts13.isExpression(single.expression)) return void 0;
7817
8292
  const returnExpression = single.expression;
7818
8293
  const root = topLevelJsxChildren(returnExpression);
7819
8294
  if (!root || root.children.length === 0) return void 0;
@@ -7836,11 +8311,11 @@ function usesOutsideJsx(declaration, hook, children) {
7836
8311
  let outside = false;
7837
8312
  const visit = (node) => {
7838
8313
  if (outside) return;
7839
- if (node !== declaration && (ts11.isFunctionDeclaration(node) || ts11.isClassDeclaration(node))) return;
8314
+ if (node !== declaration && (ts13.isFunctionDeclaration(node) || ts13.isClassDeclaration(node))) return;
7840
8315
  if (isHookUsage(node, hook)) {
7841
8316
  let current = node;
7842
8317
  let isInJsxChild = false;
7843
- while (!ts11.isSourceFile(current)) {
8318
+ while (!ts13.isSourceFile(current)) {
7844
8319
  if (children.includes(current)) {
7845
8320
  isInJsxChild = true;
7846
8321
  break;
@@ -7849,14 +8324,14 @@ function usesOutsideJsx(declaration, hook, children) {
7849
8324
  }
7850
8325
  if (!isInJsxChild) outside = true;
7851
8326
  }
7852
- ts11.forEachChild(node, visit);
8327
+ ts13.forEachChild(node, visit);
7853
8328
  };
7854
8329
  visit(declaration);
7855
8330
  return outside;
7856
8331
  }
7857
8332
 
7858
8333
  // eslint/rules/source-under-src.ts
7859
- import path52 from "path";
8334
+ import path55 from "path";
7860
8335
  var NON_SOURCE_ROOT_DIRS = /* @__PURE__ */ new Set([
7861
8336
  ".agents",
7862
8337
  ".cache",
@@ -7897,14 +8372,14 @@ var sourceUnderSrcRule = {
7897
8372
  }
7898
8373
  },
7899
8374
  create(context) {
7900
- const filename = path52.resolve(context.filename);
8375
+ const filename = path55.resolve(context.filename);
7901
8376
  if (!MODULE_EXTENSION.test(filename)) return {};
7902
- const relative = path52.relative(context.cwd, filename).replace(/\\/g, "/");
8377
+ const relative = path55.relative(context.cwd, filename).replace(/\\/g, "/");
7903
8378
  if (relative === "src" || relative.startsWith("src/")) return {};
7904
8379
  const topLevel = relative.split("/")[0] ?? "";
7905
8380
  if (NON_SOURCE_ROOT_DIRS.has(topLevel)) return {};
7906
8381
  if (!relative.includes("/")) {
7907
- const basename = path52.basename(filename);
8382
+ const basename = path55.basename(filename);
7908
8383
  if (CONFIG_FILE.test(basename) || DECLARATION_FILE.test(basename) || basename.startsWith(".")) return {};
7909
8384
  }
7910
8385
  return {
@@ -7920,7 +8395,7 @@ var sourceUnderSrcRule = {
7920
8395
  };
7921
8396
 
7922
8397
  // eslint/rules/stay-flat.ts
7923
- import path53 from "path";
8398
+ import path56 from "path";
7924
8399
  var stayFlatRule = {
7925
8400
  meta: {
7926
8401
  schema: [],
@@ -7931,7 +8406,7 @@ var stayFlatRule = {
7931
8406
  },
7932
8407
  create(context) {
7933
8408
  const sourceRoot = sourceRootOf(context);
7934
- const file = path53.resolve(context.filename);
8409
+ const file = path56.resolve(context.filename);
7935
8410
  const segments = segmentsOf(file, sourceRoot);
7936
8411
  if (segments.length !== 3 || segments[0] !== "features") return {};
7937
8412
  const index = getProjectIndex(sourceRoot);
@@ -7971,7 +8446,7 @@ var stayFlatRule = {
7971
8446
  };
7972
8447
 
7973
8448
  // eslint/rules/support-file-placement.ts
7974
- import path54 from "path";
8449
+ import path57 from "path";
7975
8450
  var CONFIG_OWNED_FOLDERS = /* @__PURE__ */ new Set(["types", "constants"]);
7976
8451
  var EXPORT_KIND_BY_SUPPORT_FOLDER = /* @__PURE__ */ new Map([
7977
8452
  ["constants", "constant"],
@@ -7996,7 +8471,7 @@ var supportFilePlacementRule = {
7996
8471
  },
7997
8472
  create(context) {
7998
8473
  const sourceRoot = sourceRootOf(context);
7999
- const supportFile = path54.resolve(context.filename);
8474
+ const supportFile = path57.resolve(context.filename);
8000
8475
  const currentFolder = folderSegmentsOf(supportFile, sourceRoot);
8001
8476
  const supportFolder = currentFolder[currentFolder.length - 1];
8002
8477
  if (supportFolder === void 0 || !SUPPORT_FOLDERS.has(supportFolder)) return {};
@@ -8050,7 +8525,7 @@ var supportFilePlacementRule = {
8050
8525
 
8051
8526
  // eslint/rules/support-folder-shape.ts
8052
8527
  import fs6 from "fs";
8053
- import path55 from "path";
8528
+ import path58 from "path";
8054
8529
  var SUPPORT_FOLDERS4 = /* @__PURE__ */ new Set(["constants", "types", "schemas"]);
8055
8530
  var INDEX_NAMES2 = /* @__PURE__ */ new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
8056
8531
  var supportFolderShapeRule = {
@@ -8062,12 +8537,12 @@ var supportFolderShapeRule = {
8062
8537
  }
8063
8538
  },
8064
8539
  create(context) {
8065
- const filename = path55.resolve(context.filename);
8066
- const baseName = path55.basename(filename);
8540
+ const filename = path58.resolve(context.filename);
8541
+ const baseName = path58.basename(filename);
8067
8542
  if (!INDEX_NAMES2.has(baseName)) return {};
8068
- const folder = path55.basename(path55.dirname(filename));
8543
+ const folder = path58.basename(path58.dirname(filename));
8069
8544
  if (!SUPPORT_FOLDERS4.has(folder)) return {};
8070
- const directory = path55.dirname(filename);
8545
+ const directory = path58.dirname(filename);
8071
8546
  let entries;
8072
8547
  try {
8073
8548
  entries = fs6.readdirSync(directory);
@@ -8085,7 +8560,7 @@ var supportFolderShapeRule = {
8085
8560
  for (const match of source.matchAll(exportPattern)) {
8086
8561
  hasAnyReExport = true;
8087
8562
  const specifier = match.groups?.specifier;
8088
- if (specifier?.startsWith(".")) exportedFiles.add(path55.basename(specifier));
8563
+ if (specifier?.startsWith(".")) exportedFiles.add(path58.basename(specifier));
8089
8564
  }
8090
8565
  const guide = `docs/next-codebase-guide/rules/${folder === "constants" ? "constants" : "types-and-schemas"}-rule.md`;
8091
8566
  if (siblingModules.length === 0) {
@@ -8264,11 +8739,11 @@ var baseLayerPairRule = {
8264
8739
 
8265
8740
  // eslint/rules/tailwind/css-entry-point.ts
8266
8741
  import { statSync as statSync4 } from "fs";
8267
- import path58 from "path";
8742
+ import path61 from "path";
8268
8743
 
8269
8744
  // eslint/rules/tailwind/source-files.ts
8270
- import { readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
8271
- import path56 from "path";
8745
+ import { readdirSync as readdirSync3, readFileSync as readFileSync11, statSync as statSync3 } from "fs";
8746
+ import path59 from "path";
8272
8747
  var CSS_EXTENSIONS = [".css"];
8273
8748
  var MODULE_EXTENSIONS4 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
8274
8749
  var SOURCE_EXTENSIONS = [...MODULE_EXTENSIONS4, ...CSS_EXTENSIONS];
@@ -8281,7 +8756,7 @@ function findFiles(dir, extensions) {
8281
8756
  }
8282
8757
  return entries.flatMap((entry) => {
8283
8758
  if (entry.startsWith(".") || entry === "node_modules") return [];
8284
- const entryPath = path56.join(dir, entry);
8759
+ const entryPath = path59.join(dir, entry);
8285
8760
  let stats;
8286
8761
  try {
8287
8762
  stats = statSync3(entryPath);
@@ -8289,7 +8764,7 @@ function findFiles(dir, extensions) {
8289
8764
  return [];
8290
8765
  }
8291
8766
  if (stats.isDirectory()) return findFiles(entryPath, extensions);
8292
- return extensions.includes(path56.extname(entry)) ? [entryPath] : [];
8767
+ return extensions.includes(path59.extname(entry)) ? [entryPath] : [];
8293
8768
  });
8294
8769
  }
8295
8770
  function cachedTextReader() {
@@ -8298,7 +8773,7 @@ function cachedTextReader() {
8298
8773
  let text = texts.get(file);
8299
8774
  if (text === void 0) {
8300
8775
  try {
8301
- text = readFileSync10(file, "utf8");
8776
+ text = readFileSync11(file, "utf8");
8302
8777
  } catch {
8303
8778
  text = "";
8304
8779
  }
@@ -8312,7 +8787,7 @@ function escapeRegExp(text) {
8312
8787
  }
8313
8788
 
8314
8789
  // eslint/rules/tailwind/stylesheet-graph.ts
8315
- import path57 from "path";
8790
+ import path60 from "path";
8316
8791
  function registersTailwind(text) {
8317
8792
  return /@import\s+(?:url\(\s*)?["']tailwindcss["']\s*\)?/i.test(text);
8318
8793
  }
@@ -8326,25 +8801,25 @@ function moduleImports(text, fileName) {
8326
8801
  return new RegExp(`(?:import|require)\\s*\\(?\\s*["'][^"']*${escaped}["']`, "i").test(text);
8327
8802
  }
8328
8803
  function resolveSpecifier2(fromFile, spec, sourceRoot) {
8329
- if (spec.startsWith("/")) return path57.resolve(spec);
8330
- if (spec.startsWith("./") || spec.startsWith("../")) return path57.resolve(path57.dirname(fromFile), spec);
8331
- if (spec.startsWith("@/")) return path57.resolve(sourceRoot, spec.slice(2));
8804
+ if (spec.startsWith("/")) return path60.resolve(spec);
8805
+ if (spec.startsWith("./") || spec.startsWith("../")) return path60.resolve(path60.dirname(fromFile), spec);
8806
+ if (spec.startsWith("@/")) return path60.resolve(sourceRoot, spec.slice(2));
8332
8807
  return void 0;
8333
8808
  }
8334
8809
  function buildStylesheetGraph(options) {
8335
8810
  const { cssFiles, sourceRoot, textOf } = options;
8336
- const cssSet = new Set(cssFiles.map((file) => path57.normalize(file)));
8811
+ const cssSet = new Set(cssFiles.map((file) => path60.normalize(file)));
8337
8812
  const globals = cssFiles.filter((file) => registersTailwind(textOf(file)));
8338
8813
  const reachable = /* @__PURE__ */ new Set();
8339
8814
  const queue = [...globals];
8340
- for (const global of globals) reachable.add(path57.normalize(global));
8815
+ for (const global of globals) reachable.add(path60.normalize(global));
8341
8816
  while (queue.length > 0) {
8342
8817
  const from = queue.shift();
8343
8818
  if (!from) continue;
8344
8819
  for (const spec of importedSpecifiers(textOf(from))) {
8345
8820
  const target = resolveSpecifier2(from, spec, sourceRoot);
8346
8821
  if (!target) continue;
8347
- const normalized = path57.normalize(target);
8822
+ const normalized = path60.normalize(target);
8348
8823
  if (cssSet.has(normalized) && !reachable.has(normalized)) {
8349
8824
  reachable.add(normalized);
8350
8825
  queue.push(normalized);
@@ -8356,7 +8831,7 @@ function buildStylesheetGraph(options) {
8356
8831
  for (const spec of importedSpecifiers(textOf(global))) {
8357
8832
  const target = resolveSpecifier2(global, spec, sourceRoot);
8358
8833
  if (!target) continue;
8359
- const normalized = path57.normalize(target);
8834
+ const normalized = path60.normalize(target);
8360
8835
  if (cssSet.has(normalized)) directChildren.add(normalized);
8361
8836
  }
8362
8837
  }
@@ -8364,8 +8839,8 @@ function buildStylesheetGraph(options) {
8364
8839
  }
8365
8840
 
8366
8841
  // eslint/rules/tailwind/css-entry-point.ts
8367
- var APP_STYLES_DIR = path58.join("app", "styles");
8368
- var GLOBAL_STYLESHEET_PATH = path58.join(APP_STYLES_DIR, "globals.css");
8842
+ var APP_STYLES_DIR = path61.join("app", "styles");
8843
+ var GLOBAL_STYLESHEET_PATH = path61.join(APP_STYLES_DIR, "globals.css");
8369
8844
  var cssEntryPointRule = {
8370
8845
  meta: {
8371
8846
  schema: [],
@@ -8391,8 +8866,8 @@ var cssEntryPointRule = {
8391
8866
  return {
8392
8867
  "StyleSheet:exit"(node) {
8393
8868
  if (globals.length === 0) return;
8394
- const current = path58.normalize(path58.resolve(context.filename));
8395
- const relative = path58.relative(sourceRoot, current);
8869
+ const current = path61.normalize(path61.resolve(context.filename));
8870
+ const relative = path61.relative(sourceRoot, current);
8396
8871
  if (globals.includes(current)) {
8397
8872
  if (globals.length > 1) {
8398
8873
  context.report({
@@ -8408,7 +8883,7 @@ var cssEntryPointRule = {
8408
8883
  });
8409
8884
  return;
8410
8885
  }
8411
- const basename = path58.basename(current);
8886
+ const basename = path61.basename(current);
8412
8887
  const importCount = moduleFiles.filter((modulePath) => moduleImports(textOf(modulePath), basename)).length;
8413
8888
  if (importCount !== 1) {
8414
8889
  context.report({
@@ -8418,7 +8893,7 @@ var cssEntryPointRule = {
8418
8893
  }
8419
8894
  return;
8420
8895
  }
8421
- const isInAppStyles = relative === APP_STYLES_DIR || relative.startsWith(`${APP_STYLES_DIR}${path58.sep}`);
8896
+ const isInAppStyles = relative === APP_STYLES_DIR || relative.startsWith(`${APP_STYLES_DIR}${path61.sep}`);
8422
8897
  if (!isInAppStyles) {
8423
8898
  context.report({
8424
8899
  node,
@@ -8907,7 +9382,7 @@ var tailwindRules = {
8907
9382
  };
8908
9383
 
8909
9384
  // eslint/rules/type-extraction.ts
8910
- import path59 from "path";
9385
+ import path62 from "path";
8911
9386
  var typeExtractionRule = {
8912
9387
  meta: {
8913
9388
  schema: [],
@@ -8918,7 +9393,7 @@ var typeExtractionRule = {
8918
9393
  },
8919
9394
  create(context) {
8920
9395
  const sourceRoot = sourceRootOf(context);
8921
- const file = path59.resolve(context.filename);
9396
+ const file = path62.resolve(context.filename);
8922
9397
  const segments = segmentsOf(file, sourceRoot);
8923
9398
  if (segments.length === 0) return {};
8924
9399
  const index = getProjectIndex(sourceRoot);
@@ -9057,9 +9532,9 @@ var uiStateRule = {
9057
9532
  };
9058
9533
 
9059
9534
  // eslint/rules/unknown-utility.ts
9060
- import { existsSync as existsSync6, readdirSync as readdirSync4, readFileSync as readFileSync11, statSync as statSync6 } from "fs";
9535
+ import { existsSync as existsSync6, readdirSync as readdirSync4, readFileSync as readFileSync12, statSync as statSync6 } from "fs";
9061
9536
  import { createRequire } from "module";
9062
- import path60 from "path";
9537
+ import path63 from "path";
9063
9538
  var PREFIX_NAMESPACES = {
9064
9539
  bg: ["color"],
9065
9540
  text: ["color", "text"],
@@ -9299,7 +9774,7 @@ function stylesheetFiles(dir) {
9299
9774
  }
9300
9775
  return entries.flatMap((entry) => {
9301
9776
  if (entry.startsWith(".") || entry === "node_modules") return [];
9302
- const entryPath = path60.join(dir, entry);
9777
+ const entryPath = path63.join(dir, entry);
9303
9778
  let stats;
9304
9779
  try {
9305
9780
  stats = statSync6(entryPath);
@@ -9307,7 +9782,7 @@ function stylesheetFiles(dir) {
9307
9782
  return [];
9308
9783
  }
9309
9784
  if (stats.isDirectory()) return stylesheetFiles(entryPath);
9310
- return path60.extname(entry) === ".css" ? [entryPath] : [];
9785
+ return path63.extname(entry) === ".css" ? [entryPath] : [];
9311
9786
  });
9312
9787
  }
9313
9788
  function packageNameOf(specifier) {
@@ -9318,24 +9793,24 @@ function packageNameOf(specifier) {
9318
9793
  function resolvePackageStylesheet(fromFile, specifier) {
9319
9794
  const packageName = packageNameOf(specifier);
9320
9795
  if (!packageName || packageName === "tailwindcss") return void 0;
9321
- let directory = path60.dirname(fromFile);
9322
- while (directory !== path60.dirname(directory)) {
9323
- const packageRoot = path60.join(directory, "node_modules", packageName);
9324
- const manifestPath = path60.join(packageRoot, "package.json");
9796
+ let directory = path63.dirname(fromFile);
9797
+ while (directory !== path63.dirname(directory)) {
9798
+ const packageRoot = path63.join(directory, "node_modules", packageName);
9799
+ const manifestPath = path63.join(packageRoot, "package.json");
9325
9800
  if (existsSync6(manifestPath)) {
9326
9801
  try {
9327
- const manifest = readFileSync11(manifestPath, "utf8");
9802
+ const manifest = readFileSync12(manifestPath, "utf8");
9328
9803
  const stylesheet = /"style"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
9329
9804
  const main = /"main"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
9330
9805
  const target = stylesheet ?? main;
9331
9806
  if (!target) return void 0;
9332
- const resolved = path60.resolve(packageRoot, target);
9807
+ const resolved = path63.resolve(packageRoot, target);
9333
9808
  return existsSync6(resolved) ? resolved : void 0;
9334
9809
  } catch {
9335
9810
  return void 0;
9336
9811
  }
9337
9812
  }
9338
- directory = path60.dirname(directory);
9813
+ directory = path63.dirname(directory);
9339
9814
  }
9340
9815
  return void 0;
9341
9816
  }
@@ -9344,7 +9819,7 @@ function inventoryStylesheetFiles(projectFiles) {
9344
9819
  for (const file of projectFiles) {
9345
9820
  let css2;
9346
9821
  try {
9347
- css2 = readFileSync11(file, "utf8");
9822
+ css2 = readFileSync12(file, "utf8");
9348
9823
  } catch {
9349
9824
  continue;
9350
9825
  }
@@ -9410,7 +9885,7 @@ function readInventory(files) {
9410
9885
  for (const file of files) {
9411
9886
  let css2;
9412
9887
  try {
9413
- css2 = readFileSync11(file, "utf8");
9888
+ css2 = readFileSync12(file, "utf8");
9414
9889
  } catch {
9415
9890
  continue;
9416
9891
  }
@@ -9586,7 +10061,7 @@ var unknownUtilityRule = {
9586
10061
  };
9587
10062
 
9588
10063
  // eslint/rules/util-file-name.ts
9589
- import path61 from "path";
10064
+ import path64 from "path";
9590
10065
  function toKebabCase2(value) {
9591
10066
  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();
9592
10067
  }
@@ -9599,7 +10074,7 @@ var utilFileNameRule = {
9599
10074
  }
9600
10075
  },
9601
10076
  create(context) {
9602
- const filename = path61.resolve(context.filename);
10077
+ const filename = path64.resolve(context.filename);
9603
10078
  const segments = filename.replace(/\\/g, "/").split("/");
9604
10079
  if (!segments.includes("utils")) return {};
9605
10080
  let module;
@@ -9613,13 +10088,13 @@ var utilFileNameRule = {
9613
10088
  const functionName = functions[0]?.name;
9614
10089
  if (!functionName) return {};
9615
10090
  const expected = toKebabCase2(functionName);
9616
- const actual = path61.basename(filename, path61.extname(filename));
10091
+ const actual = path64.basename(filename, path64.extname(filename));
9617
10092
  if (!expected || actual === expected) return {};
9618
10093
  return {
9619
10094
  Program(node) {
9620
10095
  context.report({
9621
10096
  node,
9622
- message: `A utility file exporting ${functionName} must be named ${expected}.${path61.extname(filename).slice(1)}.`
10097
+ message: `A utility file exporting ${functionName} must be named ${expected}.${path64.extname(filename).slice(1)}.`
9623
10098
  });
9624
10099
  }
9625
10100
  };
@@ -9627,7 +10102,7 @@ var utilFileNameRule = {
9627
10102
  };
9628
10103
 
9629
10104
  // eslint/rules/value-extraction.ts
9630
- import path62 from "path";
10105
+ import path65 from "path";
9631
10106
  var valueExtractionRule = {
9632
10107
  meta: {
9633
10108
  schema: [],
@@ -9638,7 +10113,7 @@ var valueExtractionRule = {
9638
10113
  },
9639
10114
  create(context) {
9640
10115
  const sourceRoot = sourceRootOf(context);
9641
- const file = path62.resolve(context.filename);
10116
+ const file = path65.resolve(context.filename);
9642
10117
  const segments = segmentsOf(file, sourceRoot);
9643
10118
  if (segments.length === 0 || segments[0] !== "app") return {};
9644
10119
  const index = getProjectIndex(sourceRoot);
@@ -9659,8 +10134,8 @@ var valueExtractionRule = {
9659
10134
  };
9660
10135
 
9661
10136
  // eslint/rules/vulyk/tracked-docs.ts
9662
- import { existsSync as existsSync7, readFileSync as readFileSync12 } from "fs";
9663
- import path63 from "path";
10137
+ import { existsSync as existsSync7, readFileSync as readFileSync13 } from "fs";
10138
+ import path66 from "path";
9664
10139
  var PASIKA_REPO = "Bredansky/pasika";
9665
10140
  var BASE_REQUIRED_TRACKED_DOCS = [
9666
10141
  { name: "documentation-guide", path: "docs/documentation-guide" },
@@ -9671,13 +10146,13 @@ var NEXTJS_REQUIRED_TRACKED_DOCS = [
9671
10146
  { name: "next-codebase-guide", path: "docs/next-codebase-guide" },
9672
10147
  { name: "next-tailwind-guide", path: "docs/next-tailwind-guide" }
9673
10148
  ];
9674
- function memberName6(member) {
10149
+ function memberName7(member) {
9675
10150
  return member.name.type === "String" ? member.name.value : member.name.name;
9676
10151
  }
9677
10152
  function hasDependency(root, name) {
9678
- const section = root.members.find((member) => memberName6(member) === "dependencies");
10153
+ const section = root.members.find((member) => memberName7(member) === "dependencies");
9679
10154
  if (section?.value.type !== "Object") return false;
9680
- return section.value.members.some((member) => memberName6(member) === name);
10155
+ return section.value.members.some((member) => memberName7(member) === name);
9681
10156
  }
9682
10157
  var trackedDocsRule = {
9683
10158
  meta: {
@@ -9693,8 +10168,8 @@ var trackedDocsRule = {
9693
10168
  if (!context.filename.endsWith("package.json")) return;
9694
10169
  const root = node.body;
9695
10170
  if (root.type !== "Object") return;
9696
- const projectRoot = path63.dirname(path63.resolve(context.filename));
9697
- const configPath = path63.join(projectRoot, "vulyk.config.ts");
10171
+ const projectRoot = path66.dirname(path66.resolve(context.filename));
10172
+ const configPath = path66.join(projectRoot, "vulyk.config.ts");
9698
10173
  if (!existsSync7(configPath)) {
9699
10174
  context.report({
9700
10175
  node,
@@ -9702,7 +10177,7 @@ var trackedDocsRule = {
9702
10177
  });
9703
10178
  return;
9704
10179
  }
9705
- const config = readFileSync12(configPath, "utf8");
10180
+ const config = readFileSync13(configPath, "utf8");
9706
10181
  if (!config.includes(PASIKA_REPO)) {
9707
10182
  context.report({
9708
10183
  node,
@@ -9719,7 +10194,7 @@ var trackedDocsRule = {
9719
10194
  });
9720
10195
  }
9721
10196
  }
9722
- const agentsPath = path63.join(projectRoot, "AGENTS.md");
10197
+ const agentsPath = path66.join(projectRoot, "AGENTS.md");
9723
10198
  if (!existsSync7(agentsPath)) {
9724
10199
  context.report({
9725
10200
  node,
@@ -9732,14 +10207,14 @@ var trackedDocsRule = {
9732
10207
  };
9733
10208
 
9734
10209
  // eslint/rules/vulyk/vulyk-dependency.ts
9735
- function memberName7(member) {
10210
+ function memberName8(member) {
9736
10211
  return member.name.type === "String" ? member.name.value : member.name.name;
9737
10212
  }
9738
10213
  function dependency(root, sectionName) {
9739
10214
  if (root.type !== "Object") return void 0;
9740
- const section = root.members.find((member) => memberName7(member) === sectionName);
10215
+ const section = root.members.find((member) => memberName8(member) === sectionName);
9741
10216
  if (section?.value.type !== "Object") return void 0;
9742
- return section.value.members.find((member) => memberName7(member) === "vulyk");
10217
+ return section.value.members.find((member) => memberName8(member) === "vulyk");
9743
10218
  }
9744
10219
  var vulykDependencyRule = {
9745
10220
  meta: {
@@ -9780,9 +10255,9 @@ var vulykRules = {
9780
10255
  // eslint/rules/with-response-helper.ts
9781
10256
  var HELPER3 = "withResponse";
9782
10257
  var ENTRY3 = "pasika/with-response";
9783
- var DOC6 = "docs/pasika-adoption-guide/rules/with-response-helper-rule.md";
9784
- var DECLARED3 = `A repository must not declare its own ${HELPER3}; import it from ${ENTRY3}. See ${DOC6}`;
9785
- var IMPORTED3 = `${HELPER3} must be imported from ${ENTRY3}. See ${DOC6}`;
10258
+ var DOC7 = "docs/pasika-adoption-guide/rules/with-response-helper-rule.md";
10259
+ var DECLARED3 = `A repository must not declare its own ${HELPER3}; import it from ${ENTRY3}. See ${DOC7}`;
10260
+ var IMPORTED3 = `${HELPER3} must be imported from ${ENTRY3}. See ${DOC7}`;
9786
10261
  function isNamed3(node, name) {
9787
10262
  return node?.type === "Identifier" && node.name === name;
9788
10263
  }
@@ -9819,7 +10294,7 @@ var withResponseHelperRule = {
9819
10294
 
9820
10295
  // eslint/rules/zirka-baseline.ts
9821
10296
  import fs7 from "fs";
9822
- import path64 from "path";
10297
+ import path67 from "path";
9823
10298
  var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
9824
10299
  var PRETTIER_CONFIGS = [
9825
10300
  "prettier.config.mjs",
@@ -9838,10 +10313,10 @@ var zirkaBaselineRule = {
9838
10313
  }
9839
10314
  },
9840
10315
  create(context) {
9841
- const filename = path64.resolve(context.filename);
9842
- const basename = path64.basename(filename);
10316
+ const filename = path67.resolve(context.filename);
10317
+ const basename = path67.basename(filename);
9843
10318
  if (!ESLINT_CONFIG.test(basename)) return {};
9844
- const projectRoot = path64.dirname(filename);
10319
+ const projectRoot = path67.dirname(filename);
9845
10320
  const report3 = (message) => {
9846
10321
  context.report({
9847
10322
  node: context.sourceCode.ast,
@@ -9856,7 +10331,7 @@ var zirkaBaselineRule = {
9856
10331
  'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
9857
10332
  );
9858
10333
  }
9859
- const tsconfigPath = path64.join(projectRoot, "tsconfig.json");
10334
+ const tsconfigPath = path67.join(projectRoot, "tsconfig.json");
9860
10335
  if (!fs7.existsSync(tsconfigPath)) {
9861
10336
  report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
9862
10337
  } else {
@@ -9874,13 +10349,13 @@ var zirkaBaselineRule = {
9874
10349
  report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
9875
10350
  }
9876
10351
  }
9877
- const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path64.join(projectRoot, name)));
10352
+ const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path67.join(projectRoot, name)));
9878
10353
  if (!prettierConfigFile) {
9879
10354
  report3(
9880
10355
  "No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
9881
10356
  );
9882
10357
  } else {
9883
- const content = fs7.readFileSync(path64.join(projectRoot, prettierConfigFile), "utf8");
10358
+ const content = fs7.readFileSync(path67.join(projectRoot, prettierConfigFile), "utf8");
9884
10359
  if (!content.includes("zirka")) {
9885
10360
  report3(
9886
10361
  "The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
@@ -9903,10 +10378,10 @@ function referencesZirka(sourceCode) {
9903
10378
  // eslint/rules/zod-fetch-helper.ts
9904
10379
  var HELPER4 = "zodFetch";
9905
10380
  var ENTRY4 = "pasika/zod-fetch";
9906
- var DOC7 = "docs/pasika-adoption-guide/rules/zod-fetch-helper-rule.md";
9907
- var FETCHED = `fetch must not be called; make the request through ${HELPER4} from ${ENTRY4}. See ${DOC7}`;
9908
- var DECLARED4 = `A file must not declare its own ${HELPER4}; import it from ${ENTRY4}. See ${DOC7}`;
9909
- var IMPORTED4 = `${HELPER4} must be imported from ${ENTRY4}. See ${DOC7}`;
10381
+ var DOC8 = "docs/pasika-adoption-guide/rules/zod-fetch-helper-rule.md";
10382
+ var FETCHED = `fetch must not be called; make the request through ${HELPER4} from ${ENTRY4}. See ${DOC8}`;
10383
+ var DECLARED4 = `A file must not declare its own ${HELPER4}; import it from ${ENTRY4}. See ${DOC8}`;
10384
+ var IMPORTED4 = `${HELPER4} must be imported from ${ENTRY4}. See ${DOC8}`;
9910
10385
  var GLOBAL_OBJECTS = /* @__PURE__ */ new Set(["globalThis", "window", "self", "global"]);
9911
10386
  var TEST_FILE2 = /(?:^|[\\/])(?:__tests__|tests)[\\/]|[.](?:test|spec)[.][cm]?[jt]sx?$/;
9912
10387
  function isNamed4(node, name) {
@@ -10026,14 +10501,14 @@ var zodSchemaValidationRule = {
10026
10501
  };
10027
10502
 
10028
10503
  // eslint/ts-alignment.ts
10029
- import { readFileSync as readFileSync13 } from "fs";
10504
+ import { readFileSync as readFileSync14 } from "fs";
10030
10505
  import { createRequire as createRequire2 } from "module";
10031
10506
  import { join } from "path";
10032
10507
  var ownRequire = createRequire2(import.meta.url);
10033
10508
  var majorOf = (version) => Number(version.split(".")[0]);
10034
10509
  function versionOf(packagePath) {
10035
10510
  try {
10036
- const parsed = JSON.parse(readFileSync13(packagePath, "utf8"));
10511
+ const parsed = JSON.parse(readFileSync14(packagePath, "utf8"));
10037
10512
  if (typeof parsed !== "object" || parsed === null || !("version" in parsed)) return null;
10038
10513
  return typeof parsed.version === "string" ? parsed.version : null;
10039
10514
  } catch {
@@ -10093,6 +10568,7 @@ var pasikaNextjsAppRules = {
10093
10568
  "value-extraction": valueExtractionRule,
10094
10569
  "constant-casing": constantCasingRule,
10095
10570
  "prefer-enum": preferEnumRule,
10571
+ "repeated-semantic-literal": repeatedSemanticLiteralRule,
10096
10572
  "prefer-object-destructuring": preferObjectDestructuringRule,
10097
10573
  "enum-placement": enumPlacementRule,
10098
10574
  "type-extraction": typeExtractionRule,