@morriconeluca/eslint-plugin-faf 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "@morriconeluca/eslint-plugin-faf",
4
- version: "0.6.0",
4
+ version: "0.6.1",
5
5
  description: "An ESLint plugin for FAF projects.",
6
6
  repository: {
7
7
  type: "git",
@@ -79,12 +79,12 @@ var package_default = {
79
79
  "@stryker-mutator/core": "^10.1.1",
80
80
  "@stryker-mutator/vitest-runner": "^10.1.1",
81
81
  "@types/node": "^25.9.3",
82
- "@typescript-eslint/utils": "^8.24.1",
82
+ "@typescript-eslint/utils": "^8.72.2",
83
83
  "@vitest/coverage-v8": "^4.1.12",
84
84
  "dependency-cruiser": "^17.4.3",
85
85
  eslint: "^10.14.0",
86
86
  "eslint-import-resolver-typescript": "^4.4.5",
87
- "eslint-plugin-import-x": "^4.16.2",
87
+ "eslint-plugin-import-x": "^4.18.1",
88
88
  "eslint-plugin-jsdoc": "^65.4.2",
89
89
  "eslint-plugin-perfectionist": "^5.9.0",
90
90
  "eslint-plugin-sonarjs": "^4.2.2",
@@ -96,9 +96,14 @@ var package_default = {
96
96
  publint: "^0.3.25",
97
97
  tsup: "^8.3.6",
98
98
  typescript: "^6.0.3",
99
- "typescript-eslint": "^8.61.0",
99
+ "typescript-eslint": "^8.72.2",
100
100
  vitest: "^4.1.9"
101
101
  },
102
+ overrides: {
103
+ esbuild: "^0.28.2",
104
+ minimatch: "^11.0.5",
105
+ qs: "^6.17.1"
106
+ },
102
107
  "lint-staged": {
103
108
  "*": "prettier --write --ignore-unknown",
104
109
  "src/**/*.ts": "eslint --fix"
@@ -140,12 +145,15 @@ var REFERENCE_D_08 = "D-08";
140
145
  var REFERENCE_D_09 = "D-09";
141
146
  var REFERENCE_D_14 = "D-14";
142
147
  var REFERENCE_FAF_4 = "FAF \xA74";
148
+ var REFERENCE_FAF_4_6_3_1 = "FAF \xA74, \xA76.3.1";
143
149
  var REFERENCE_FAF_4_6_3_5_6_6 = "FAF \xA74, \xA76.3.5, \xA76.6";
144
150
  var REFERENCE_FAF_4_6_7 = "FAF \xA74, \xA76.7";
145
151
  var REFERENCE_FAF_5 = "FAF \xA75";
146
152
  var REFERENCE_FAF_6 = "FAF \xA76";
147
153
  var REFERENCE_FAF_6_1_1 = "FAF \xA76.1.1";
148
154
  var REFERENCE_FAF_6_1_3 = "FAF \xA76.1.3";
155
+ var REFERENCE_FAF_6_2 = "FAF \xA76.2";
156
+ var REFERENCE_FAF_6_2_1 = "FAF \xA76.2.1";
149
157
  var REFERENCE_FAF_6_2_2 = "FAF \xA76.2.2";
150
158
  var REFERENCE_FAF_6_3_1 = "FAF \xA76.3.1";
151
159
  var REFERENCE_FAF_6_3_2_MULTIPLE = "FAF \xA76.3.2, \xA76.4.1, \xA76.5.1, \xA76.6.1";
@@ -442,8 +450,8 @@ var OUTCOME_CATALOG = {
442
450
  "configuration/invalid-file-name": {
443
451
  family: "configuration",
444
452
  form: "element",
445
- normativeReference: REFERENCE_FAF_4,
446
- predicate: "must adhere to kebab-case grammar"
453
+ normativeReference: REFERENCE_D_05,
454
+ predicate: "must be a direct child file name without path separators"
447
455
  },
448
456
  "configuration/invalid-foreign-pattern": {
449
457
  family: "configuration",
@@ -454,8 +462,8 @@ var OUTCOME_CATALOG = {
454
462
  "configuration/invalid-implicit-extension": {
455
463
  family: "configuration",
456
464
  form: "element",
457
- normativeReference: REFERENCE_FAF_6_3_1,
458
- predicate: "must start with a dot and contain only lowercase letters"
465
+ normativeReference: REFERENCE_FAF_4_6_3_1,
466
+ predicate: "must be a dot-prefixed asset extension reserved to non-script files"
459
467
  },
460
468
  "configuration/invalid-literal-path": {
461
469
  family: "configuration",
@@ -532,7 +540,7 @@ var OUTCOME_CATALOG = {
532
540
  "configuration/nested-root-fragment-not-direct-child": {
533
541
  family: "configuration",
534
542
  form: "element",
535
- normativeReference: REFERENCE_FAF_6_2_2,
543
+ normativeReference: REFERENCE_FAF_6_2,
536
544
  predicate: "must be a direct child directory of the root fragment"
537
545
  },
538
546
  "configuration/non-existent-path": {
@@ -610,7 +618,7 @@ var OUTCOME_CATALOG = {
610
618
  "configuration/root-node-not-direct-child": {
611
619
  family: "configuration",
612
620
  form: "element",
613
- normativeReference: REFERENCE_FAF_6_2_2,
621
+ normativeReference: REFERENCE_FAF_6_2_1,
614
622
  predicate: "must be a direct child root node of the root fragment"
615
623
  },
616
624
  "configuration/scope-mismatch": {
@@ -646,13 +654,13 @@ var OUTCOME_CATALOG = {
646
654
  "configuration/undeclared-sub-root-fragment": {
647
655
  family: "configuration",
648
656
  form: "element",
649
- normativeReference: REFERENCE_FAF_6_2_2,
657
+ normativeReference: REFERENCE_FAF_6_2,
650
658
  predicate: "must be declared in subRootFragments"
651
659
  },
652
660
  "configuration/unenumerated-root-file": {
653
661
  family: "configuration",
654
662
  form: "element",
655
- normativeReference: REFERENCE_FAF_6_2_2,
663
+ normativeReference: REFERENCE_FAF_6_2_1,
656
664
  predicate: "must be either enumerated as a Root Node or designated as a Foreign Node"
657
665
  },
658
666
  "configuration/unknown-property": {
@@ -1613,7 +1621,7 @@ function resolveSpecifiers(baseDirectory, aliases) {
1613
1621
  const tsconfigCandidate = nodePath10.join(resolvedBase, "tsconfig.json");
1614
1622
  const hasTsconfig = nodeFs10.existsSync(tsconfigCandidate);
1615
1623
  const tsconfig = hasTsconfig ? { configFile: tsconfigCandidate, references: "auto" } : void 0;
1616
- const resolver = new ResolverFactory({
1624
+ const resolverOptions = {
1617
1625
  builtinModules: true,
1618
1626
  conditionNames: ["import", "require", "node", "types", "style", "default"],
1619
1627
  extensionAlias: {
@@ -1634,9 +1642,13 @@ function resolveSpecifiers(baseDirectory, aliases) {
1634
1642
  ".json",
1635
1643
  ".css"
1636
1644
  ],
1637
- importsFields: [["imports"]],
1645
+ importsFields: [["imports"]]
1646
+ };
1647
+ const resolver = new ResolverFactory({
1648
+ ...resolverOptions,
1638
1649
  tsconfig
1639
1650
  });
1651
+ const noTsconfigResolver = hasTsconfig ? new ResolverFactory(resolverOptions) : null;
1640
1652
  const resolutionCache = /* @__PURE__ */ new Map();
1641
1653
  const toCanonicalPath = (filePath) => {
1642
1654
  try {
@@ -1645,17 +1657,58 @@ function resolveSpecifiers(baseDirectory, aliases) {
1645
1657
  return filePath;
1646
1658
  }
1647
1659
  };
1660
+ const isCandidateForDiscordanceCheck = (cleanSpecifier, aliasUsed, hasUsedRelativeFallback, isBuiltin, resolvedPath) => {
1661
+ const isContextEligible = hasTsconfig && aliasUsed === null && !hasUsedRelativeFallback;
1662
+ const isBare = !cleanSpecifier.startsWith(".") && !cleanSpecifier.startsWith("/");
1663
+ const isLocal = !isBuiltin && resolvedPath !== void 0;
1664
+ const isOutsideNodeModules = resolvedPath !== void 0 && !toPosixPath(resolvedPath).includes(NODE_MODULES_MARKER);
1665
+ return isContextEligible && isBare && isLocal && isOutsideNodeModules;
1666
+ };
1667
+ const resolveWithoutTsconfig = (directory, specifier) => {
1668
+ if (noTsconfigResolver === null) {
1669
+ return null;
1670
+ }
1671
+ try {
1672
+ const result = noTsconfigResolver.sync(directory, specifier);
1673
+ if (result.path === void 0) {
1674
+ return null;
1675
+ }
1676
+ const cleanPath = result.path.split("?", 1)[0] ?? result.path;
1677
+ return toCanonicalPath(cleanPath);
1678
+ } catch {
1679
+ return null;
1680
+ }
1681
+ };
1682
+ const resolveWithFallback = (directory, specifier, canFallbackToBare) => {
1683
+ let result = resolver.sync(directory, specifier);
1684
+ if (canFallbackToBare && result.path === void 0 && specifier.startsWith("./")) {
1685
+ result = resolver.sync(directory, specifier.slice(2));
1686
+ return { hasUsedFallback: true, result };
1687
+ }
1688
+ return { hasUsedFallback: false, result };
1689
+ };
1690
+ const acquireCanonicalResult = (rawResult) => {
1691
+ if (rawResult.path === void 0) {
1692
+ return rawResult;
1693
+ }
1694
+ const cleanPath = rawResult.path.split("?", 1)[0] ?? rawResult.path;
1695
+ return {
1696
+ ...rawResult,
1697
+ path: toCanonicalPath(cleanPath)
1698
+ };
1699
+ };
1648
1700
  const resolveSingle = (directory, specifier, canFallbackToBare) => {
1649
1701
  const cleanSpecifier = specifier.split("?", 1)[0] ?? specifier;
1650
1702
  const matchedAlias = matchPathAlias(cleanSpecifier, aliases);
1651
1703
  const aliasUsed = matchedAlias?.alias.prefix ?? null;
1652
1704
  const aliasAlternatives = matchedAlias?.targets ?? [];
1653
- let resolveResult;
1705
+ let fallbackOutcome;
1654
1706
  try {
1655
- resolveResult = resolver.sync(directory, specifier);
1656
- if (canFallbackToBare && resolveResult.path === void 0 && specifier.startsWith("./")) {
1657
- resolveResult = resolver.sync(directory, specifier.slice(2));
1658
- }
1707
+ fallbackOutcome = resolveWithFallback(
1708
+ directory,
1709
+ specifier,
1710
+ canFallbackToBare
1711
+ );
1659
1712
  } catch (error) {
1660
1713
  assertInvariant(error instanceof Error, "Expected resolver error");
1661
1714
  return {
@@ -1667,13 +1720,28 @@ function resolveSpecifiers(baseDirectory, aliases) {
1667
1720
  }
1668
1721
  };
1669
1722
  }
1670
- let acquiredResolveResult = resolveResult;
1671
- if (resolveResult.path !== void 0) {
1672
- const cleanResolvedPath = resolveResult.path.split("?", 1)[0] ?? resolveResult.path;
1673
- acquiredResolveResult = {
1674
- ...resolveResult,
1675
- path: toCanonicalPath(cleanResolvedPath)
1676
- };
1723
+ const acquiredResolveResult = acquireCanonicalResult(
1724
+ fallbackOutcome.result
1725
+ );
1726
+ const isCandidate = isCandidateForDiscordanceCheck(
1727
+ cleanSpecifier,
1728
+ aliasUsed,
1729
+ fallbackOutcome.hasUsedFallback,
1730
+ acquiredResolveResult.builtin !== void 0,
1731
+ acquiredResolveResult.path
1732
+ );
1733
+ if (isCandidate) {
1734
+ const nonTsconfigPath = resolveWithoutTsconfig(directory, specifier);
1735
+ if (nonTsconfigPath === null || nonTsconfigPath !== acquiredResolveResult.path) {
1736
+ return {
1737
+ aliasAlternatives,
1738
+ aliasUsed,
1739
+ target: {
1740
+ reason: DISCORDANCE_REASON,
1741
+ type: "unresolved"
1742
+ }
1743
+ };
1744
+ }
1677
1745
  }
1678
1746
  const target = classifyResolutionTarget({
1679
1747
  aliasAlternatives,
@@ -2069,6 +2137,13 @@ function extractDefaultExport(statement, rootSymbols, importedBindings, locator)
2069
2137
  };
2070
2138
  }
2071
2139
 
2140
+ // src/_rules/conformity/_stores/session/_services/verify-project/_adapters/collect-modules/_utils/produce-module-record-by-extension/_utils/extract-script-module-record/_utils/extract-module-exports/_utils/extract-named-specifiers-exports/_utils/extract-local-specifiers/_utils/is-local-type-export/is-local-type-export.util.ts
2141
+ function isLocalTypeExport(isExplicitlyTypeOnly, binding, localName, rootSymbols) {
2142
+ return isExplicitlyTypeOnly && binding !== void 0 && !binding.isTypeOnly && rootSymbols.some(
2143
+ (symbol) => symbol.name === localName && symbol.space === "type"
2144
+ );
2145
+ }
2146
+
2072
2147
  // src/_rules/conformity/_stores/session/_services/verify-project/_adapters/collect-modules/_utils/produce-module-record-by-extension/_utils/extract-script-module-record/_utils/extract-module-exports/_utils/extract-named-specifiers-exports/_utils/extract-local-specifiers/extract-local-specifiers.util.ts
2073
2148
  function extractLocalSpecifiers(statement, rootSymbols, importedBindings, locator, exports) {
2074
2149
  const isDeclarationTypeOnly = statement.exportKind === "type";
@@ -2077,8 +2152,9 @@ function extractLocalSpecifiers(statement, rootSymbols, importedBindings, locato
2077
2152
  const localName = getExportedName(specifier.local);
2078
2153
  const position = locator(specifier.start);
2079
2154
  const binding = importedBindings.get(localName);
2080
- if (binding === void 0) {
2081
- const isTypeOnly = isDeclarationTypeOnly || specifier.exportKind === "type" || isAllTypeSpace(localName, rootSymbols);
2155
+ const isExplicitlyTypeOnly = isDeclarationTypeOnly || specifier.exportKind === "type";
2156
+ if (binding === void 0 || isLocalTypeExport(isExplicitlyTypeOnly, binding, localName, rootSymbols)) {
2157
+ const isTypeOnly = isExplicitlyTypeOnly || isAllTypeSpace(localName, rootSymbols);
2082
2158
  exports.push({
2083
2159
  exportedName,
2084
2160
  isTypeOnly,
@@ -2086,7 +2162,7 @@ function extractLocalSpecifiers(statement, rootSymbols, importedBindings, locato
2086
2162
  position
2087
2163
  });
2088
2164
  } else {
2089
- const isTypeOnly = isDeclarationTypeOnly || specifier.exportKind === "type" || binding.isTypeOnly;
2165
+ const isTypeOnly = isExplicitlyTypeOnly || binding.isTypeOnly;
2090
2166
  const origin = binding.isNamespace ? { specifier: binding.specifier, type: NAMESPACE_ORIGIN } : {
2091
2167
  importedName: binding.importedName,
2092
2168
  specifier: binding.specifier,
@@ -2585,64 +2661,67 @@ var BINDING_PATTERN_TYPES = /* @__PURE__ */ new Set([
2585
2661
  "ObjectPattern",
2586
2662
  "RestElement"
2587
2663
  ]);
2664
+ var EXPORTS_NAME = "exports";
2588
2665
  var FUNCTION_AST_TYPES = /* @__PURE__ */ new Set([
2589
2666
  "ArrowFunctionExpression",
2590
2667
  "FunctionDeclaration",
2591
2668
  "FunctionExpression"
2592
2669
  ]);
2670
+ var MODULE_NAME = "module";
2593
2671
  var REQUIRE_NAME = "require";
2672
+ var UNSUPPORTED_COMMONJS_MESSAGE = "CommonJS export assignment (module.exports / exports) is unsupported";
2594
2673
  var UNSUPPORTED_REQUIRE_MESSAGE = "Unsupported non-literal require call";
2595
2674
 
2596
2675
  // src/_rules/conformity/_stores/session/_services/verify-project/_adapters/collect-modules/_utils/produce-module-record-by-extension/_utils/extract-script-module-record/_utils/extract-traversal-entries/_utils/traverse-ast/_utils/does-node-declare-require/_does-node-declare-require@shared/_utils/_primitives/does-pattern-bind-require/does-pattern-bind-require.util.ts
2597
- function doesPatternBindRequire(pattern) {
2676
+ function doesPatternBindRequire(pattern, name = REQUIRE_NAME) {
2598
2677
  let current = pattern;
2599
2678
  while (current.type === "AssignmentPattern" || current.type === "RestElement") {
2600
2679
  current = current.type === "AssignmentPattern" ? current.left : current.argument;
2601
2680
  }
2602
2681
  if (current.type === "Identifier") {
2603
- return current.name === REQUIRE_NAME;
2682
+ return current.name === name;
2604
2683
  }
2605
2684
  if (current.type === "ArrayPattern") {
2606
2685
  return current.elements.some(
2607
- (element) => element !== null && doesPatternBindRequire(element)
2686
+ (element) => element !== null && doesPatternBindRequire(element, name)
2608
2687
  );
2609
2688
  }
2610
2689
  return current.properties.some((property) => {
2611
2690
  const next = property.type === "Property" ? property.value : property.argument;
2612
- return doesPatternBindRequire(next);
2691
+ return doesPatternBindRequire(next, name);
2613
2692
  });
2614
2693
  }
2615
2694
 
2616
2695
  // src/_rules/conformity/_stores/session/_services/verify-project/_adapters/collect-modules/_utils/produce-module-record-by-extension/_utils/extract-script-module-record/_utils/extract-traversal-entries/_utils/traverse-ast/_utils/does-node-declare-require/_does-node-declare-require@shared/_utils/_compounds/does-statement-declare-require/_utils/does-target-declare-require/does-target-declare-require.util.ts
2617
- function doesTargetDeclareRequire(statement) {
2696
+ function doesTargetDeclareRequire(statement, name = REQUIRE_NAME) {
2618
2697
  if (statement.type === "TSModuleDeclaration") {
2619
- return "name" in statement.id && statement.id.name === REQUIRE_NAME;
2698
+ return "name" in statement.id && statement.id.name === name;
2620
2699
  }
2621
2700
  if (statement.type === "ClassDeclaration" || statement.type === "FunctionDeclaration" || statement.type === "TSEnumDeclaration") {
2622
- return statement.id?.name === REQUIRE_NAME;
2701
+ return statement.id?.name === name;
2623
2702
  }
2624
2703
  return false;
2625
2704
  }
2626
2705
 
2627
2706
  // src/_rules/conformity/_stores/session/_services/verify-project/_adapters/collect-modules/_utils/produce-module-record-by-extension/_utils/extract-script-module-record/_utils/extract-traversal-entries/_utils/traverse-ast/_utils/does-node-declare-require/_does-node-declare-require@shared/_utils/_compounds/does-statement-declare-require/does-statement-declare-require.util.ts
2628
- function doesStatementDeclareRequire(statement) {
2707
+ function doesStatementDeclareRequire(statement, name = REQUIRE_NAME) {
2629
2708
  if (statement.type === "ExportNamedDeclaration") {
2630
- return statement.declaration !== null && doesStatementDeclareRequire(statement.declaration);
2709
+ return statement.declaration !== null && doesStatementDeclareRequire(statement.declaration, name);
2631
2710
  }
2632
2711
  if (statement.type === "VariableDeclaration") {
2633
2712
  return statement.declarations.some(
2634
- (declarator) => doesPatternBindRequire(declarator.id)
2713
+ (declarator) => doesPatternBindRequire(declarator.id, name)
2635
2714
  );
2636
2715
  }
2637
2716
  if (statement.type === "ImportDeclaration") {
2638
2717
  return statement.specifiers.some(
2639
- (specifier) => specifier.local.name === REQUIRE_NAME
2718
+ (specifier) => specifier.local.name === name
2640
2719
  );
2641
2720
  }
2642
2721
  if (statement.type === "TSImportEqualsDeclaration") {
2643
- return statement.id.name === REQUIRE_NAME;
2722
+ return statement.id.name === name;
2644
2723
  }
2645
- return doesTargetDeclareRequire(statement);
2724
+ return doesTargetDeclareRequire(statement, name);
2646
2725
  }
2647
2726
 
2648
2727
  // src/_rules/conformity/_stores/session/_services/verify-project/_adapters/collect-modules/_utils/produce-module-record-by-extension/_utils/extract-script-module-record/_utils/extract-traversal-entries/_utils/traverse-ast/_traverse-ast@shared/_utils/is-ast-node/is-ast-node.util.ts
@@ -2662,14 +2741,14 @@ function isStatement(value) {
2662
2741
  }
2663
2742
 
2664
2743
  // src/_rules/conformity/_stores/session/_services/verify-project/_adapters/collect-modules/_utils/produce-module-record-by-extension/_utils/extract-script-module-record/_utils/extract-traversal-entries/_utils/traverse-ast/_utils/does-node-declare-require/_utils/does-function-declare-require/does-function-declare-require.util.ts
2665
- function doesFunctionDeclareRequire(node) {
2744
+ function doesFunctionDeclareRequire(node, name = REQUIRE_NAME) {
2666
2745
  const id = node["id"];
2667
- if (isAstNode(id) && id["name"] === REQUIRE_NAME) {
2746
+ if (isAstNode(id) && id["name"] === name) {
2668
2747
  return true;
2669
2748
  }
2670
2749
  const parameters = node["params"];
2671
2750
  if (Array.isArray(parameters) && parameters.some(
2672
- (parameter) => isBindingPattern(parameter) && doesPatternBindRequire(parameter)
2751
+ (parameter) => isBindingPattern(parameter) && doesPatternBindRequire(parameter, name)
2673
2752
  )) {
2674
2753
  return true;
2675
2754
  }
@@ -2677,24 +2756,24 @@ function doesFunctionDeclareRequire(node) {
2677
2756
  if (isAstNode(body)) {
2678
2757
  const inner = body["body"];
2679
2758
  if (Array.isArray(inner)) {
2680
- return inner.filter(isStatement).some((statement) => doesStatementDeclareRequire(statement));
2759
+ return inner.filter(isStatement).some((statement) => doesStatementDeclareRequire(statement, name));
2681
2760
  }
2682
2761
  }
2683
2762
  return false;
2684
2763
  }
2685
2764
 
2686
2765
  // src/_rules/conformity/_stores/session/_services/verify-project/_adapters/collect-modules/_utils/produce-module-record-by-extension/_utils/extract-script-module-record/_utils/extract-traversal-entries/_utils/traverse-ast/_utils/does-node-declare-require/does-node-declare-require.util.ts
2687
- function doesNodeDeclareRequire(node) {
2766
+ function doesNodeDeclareRequire(node, name = REQUIRE_NAME) {
2688
2767
  if (node.type === "Program" || node.type === "BlockStatement") {
2689
2768
  const body = node["body"];
2690
- return Array.isArray(body) && body.filter(isStatement).some((statement) => doesStatementDeclareRequire(statement));
2769
+ return Array.isArray(body) && body.filter(isStatement).some((statement) => doesStatementDeclareRequire(statement, name));
2691
2770
  }
2692
2771
  if (FUNCTION_AST_TYPES.has(node.type)) {
2693
- return doesFunctionDeclareRequire(node);
2772
+ return doesFunctionDeclareRequire(node, name);
2694
2773
  }
2695
2774
  if (node.type === "CatchClause") {
2696
2775
  const parameter = node["param"];
2697
- return isBindingPattern(parameter) && doesPatternBindRequire(parameter);
2776
+ return isBindingPattern(parameter) && doesPatternBindRequire(parameter, name);
2698
2777
  }
2699
2778
  return false;
2700
2779
  }
@@ -2791,20 +2870,69 @@ function handleTsImportType(importType, locator, inlineImports) {
2791
2870
  });
2792
2871
  }
2793
2872
 
2873
+ // src/_rules/conformity/_stores/session/_services/verify-project/_adapters/collect-modules/_utils/produce-module-record-by-extension/_utils/extract-script-module-record/_utils/extract-traversal-entries/_utils/traverse-ast/_utils/handle-specific-node/_utils/handle-unsupported-syntax/_utils/is-commonjs-export-assignment/_utils/is-exports-property/is-exports-property.util.ts
2874
+ function isExportsProperty(node) {
2875
+ const property = node["property"];
2876
+ if (!isAstNode(property)) {
2877
+ return false;
2878
+ }
2879
+ if (node["computed"] === true) {
2880
+ return extractStaticSpecifier(property) === EXPORTS_NAME;
2881
+ }
2882
+ return property.type === "Identifier" && property["name"] === EXPORTS_NAME;
2883
+ }
2884
+
2885
+ // src/_rules/conformity/_stores/session/_services/verify-project/_adapters/collect-modules/_utils/produce-module-record-by-extension/_utils/extract-script-module-record/_utils/extract-traversal-entries/_utils/traverse-ast/_utils/handle-specific-node/_utils/handle-unsupported-syntax/_utils/is-commonjs-export-assignment/is-commonjs-export-assignment.util.ts
2886
+ function isCommonJsExportAssignment(left, isModuleShadowed, isExportsShadowed) {
2887
+ if (left.type !== "MemberExpression") {
2888
+ return false;
2889
+ }
2890
+ let current = left;
2891
+ let innermostOnModule = null;
2892
+ while (current.type === "MemberExpression") {
2893
+ const object = current["object"];
2894
+ if (!isAstNode(object)) {
2895
+ return false;
2896
+ }
2897
+ if (object.type === "Identifier") {
2898
+ if (object["name"] === EXPORTS_NAME) {
2899
+ return !isExportsShadowed;
2900
+ }
2901
+ if (object["name"] === MODULE_NAME) {
2902
+ innermostOnModule = current;
2903
+ }
2904
+ }
2905
+ current = object;
2906
+ }
2907
+ return innermostOnModule !== null && !isModuleShadowed && isExportsProperty(innermostOnModule);
2908
+ }
2909
+
2794
2910
  // src/_rules/conformity/_stores/session/_services/verify-project/_adapters/collect-modules/_utils/produce-module-record-by-extension/_utils/extract-script-module-record/_utils/extract-traversal-entries/_utils/traverse-ast/_utils/handle-specific-node/_utils/handle-unsupported-syntax/handle-unsupported-syntax.util.ts
2795
- function handleUnsupportedSyntax(node, locator, unsupportedSyntaxes) {
2796
- if (node.type !== "TSExportAssignment") {
2911
+ function handleUnsupportedSyntax(node, isModuleShadowed, isExportsShadowed, locator, unsupportedSyntaxes) {
2912
+ if (node.type === "TSExportAssignment") {
2913
+ const start2 = typeof node["start"] === "number" ? node["start"] : 0;
2914
+ unsupportedSyntaxes.push({
2915
+ description: "TypeScript export assignment (export =) is unsupported",
2916
+ position: locator(start2)
2917
+ });
2918
+ return;
2919
+ }
2920
+ if (node.type !== "AssignmentExpression") {
2921
+ return;
2922
+ }
2923
+ const left = node["left"];
2924
+ if (!isAstNode(left) || !isCommonJsExportAssignment(left, isModuleShadowed, isExportsShadowed)) {
2797
2925
  return;
2798
2926
  }
2799
2927
  const start = typeof node["start"] === "number" ? node["start"] : 0;
2800
2928
  unsupportedSyntaxes.push({
2801
- description: "TypeScript export assignment (export =) is unsupported",
2929
+ description: UNSUPPORTED_COMMONJS_MESSAGE,
2802
2930
  position: locator(start)
2803
2931
  });
2804
2932
  }
2805
2933
 
2806
2934
  // src/_rules/conformity/_stores/session/_services/verify-project/_adapters/collect-modules/_utils/produce-module-record-by-extension/_utils/extract-script-module-record/_utils/extract-traversal-entries/_utils/traverse-ast/_utils/handle-specific-node/handle-specific-node.util.ts
2807
- function handleSpecificNode(node, isRequireShadowed, locator, inlineImports, unsupportedSyntaxes) {
2935
+ function handleSpecificNode(node, isRequireShadowed, isModuleShadowed, isExportsShadowed, locator, inlineImports, unsupportedSyntaxes) {
2808
2936
  if (node.type === "CallExpression") {
2809
2937
  const callee = node["callee"];
2810
2938
  if (!isRequireShadowed && isAstNode(callee) && callee.type === "Identifier" && callee["name"] === REQUIRE_NAME) {
@@ -2820,7 +2948,13 @@ function handleSpecificNode(node, isRequireShadowed, locator, inlineImports, uns
2820
2948
  handleTsImportType(node, locator, inlineImports);
2821
2949
  return;
2822
2950
  }
2823
- handleUnsupportedSyntax(node, locator, unsupportedSyntaxes);
2951
+ handleUnsupportedSyntax(
2952
+ node,
2953
+ isModuleShadowed,
2954
+ isExportsShadowed,
2955
+ locator,
2956
+ unsupportedSyntaxes
2957
+ );
2824
2958
  }
2825
2959
 
2826
2960
  // src/_rules/conformity/_stores/session/_services/verify-project/_adapters/collect-modules/_utils/produce-module-record-by-extension/_utils/extract-script-module-record/_utils/extract-traversal-entries/_utils/traverse-ast/_utils/visit-children/visit-children.util.ts
@@ -2834,12 +2968,16 @@ function visitChildren(node, visitor) {
2834
2968
  }
2835
2969
 
2836
2970
  // src/_rules/conformity/_stores/session/_services/verify-project/_adapters/collect-modules/_utils/produce-module-record-by-extension/_utils/extract-script-module-record/_utils/extract-traversal-entries/_utils/traverse-ast/traverse-ast.util.ts
2837
- function traverseAst(node, isRequireShadowed, locator, inlineImports, unsupportedSyntaxes) {
2971
+ function traverseAst(node, isRequireShadowed, isModuleShadowed, isExportsShadowed, locator, inlineImports, unsupportedSyntaxes) {
2838
2972
  const astNode = { ...node, type: node.type };
2839
- const isNextShadowed = isRequireShadowed || doesNodeDeclareRequire(astNode);
2973
+ const isNextRequireShadowed = isRequireShadowed || doesNodeDeclareRequire(astNode, REQUIRE_NAME);
2974
+ const isNextModuleShadowed = isModuleShadowed || doesNodeDeclareRequire(astNode, MODULE_NAME);
2975
+ const isNextExportsShadowed = isExportsShadowed || doesNodeDeclareRequire(astNode, EXPORTS_NAME);
2840
2976
  handleSpecificNode(
2841
2977
  astNode,
2842
- isNextShadowed,
2978
+ isNextRequireShadowed,
2979
+ isNextModuleShadowed,
2980
+ isNextExportsShadowed,
2843
2981
  locator,
2844
2982
  inlineImports,
2845
2983
  unsupportedSyntaxes
@@ -2847,7 +2985,9 @@ function traverseAst(node, isRequireShadowed, locator, inlineImports, unsupporte
2847
2985
  visitChildren(astNode, (child) => {
2848
2986
  traverseAst(
2849
2987
  child,
2850
- isNextShadowed,
2988
+ isNextRequireShadowed,
2989
+ isNextModuleShadowed,
2990
+ isNextExportsShadowed,
2851
2991
  locator,
2852
2992
  inlineImports,
2853
2993
  unsupportedSyntaxes
@@ -2859,7 +2999,15 @@ function traverseAst(node, isRequireShadowed, locator, inlineImports, unsupporte
2859
2999
  function extractTraversalEntries(program, locator) {
2860
3000
  const inlineImports = [];
2861
3001
  const unsupportedSyntaxes = [];
2862
- traverseAst(program, false, locator, inlineImports, unsupportedSyntaxes);
3002
+ traverseAst(
3003
+ program,
3004
+ false,
3005
+ false,
3006
+ false,
3007
+ locator,
3008
+ inlineImports,
3009
+ unsupportedSyntaxes
3010
+ );
2863
3011
  return {
2864
3012
  inlineImports,
2865
3013
  unsupportedSyntaxes
@@ -6000,21 +6148,28 @@ function isViolatingDomainName(classification, inventory, trees) {
6000
6148
  // src/_rules/conformity/_stores/session/_services/verify-project/_norms/nomenclature/_utils/is-violating-unit-name/_utils/is-violating-path-fragment-name/is-violating-path-fragment-name.util.ts
6001
6149
  function isViolatingPathFragmentName(name, lookupPath, mimeticStructures) {
6002
6150
  const isKebab = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(name);
6003
- const matched = mimeticStructures.find(
6004
- (structure) => structure.paths.some(
6151
+ const matchingCandidates = mimeticStructures.flatMap(
6152
+ (structure) => structure.paths.filter(
6005
6153
  (prefix) => lookupPath === prefix || lookupPath.startsWith(`${prefix}/`)
6006
- )
6154
+ ).map((prefix) => ({
6155
+ prefixLength: prefix.length,
6156
+ structure
6157
+ }))
6007
6158
  );
6159
+ matchingCandidates.sort(
6160
+ (left, right) => right.prefixLength - left.prefixLength
6161
+ );
6162
+ const matched = matchingCandidates[0]?.structure;
6008
6163
  const actions = matched?.actions ?? [];
6009
6164
  if (actions.length === 0) {
6010
6165
  return !isKebab;
6011
6166
  }
6012
6167
  const matchingActions = actions.filter(
6013
- (action) => name.startsWith(`${action}-`)
6168
+ (action) => name === action || name.startsWith(`${action}-`)
6014
6169
  );
6015
6170
  matchingActions.sort((left, right) => right.length - left.length);
6016
6171
  const longestAction = matchingActions[0];
6017
- if (longestAction === void 0) {
6172
+ if (longestAction === void 0 || name === longestAction) {
6018
6173
  return true;
6019
6174
  }
6020
6175
  const target = name.slice(longestAction.length + 1);
@@ -7332,42 +7487,105 @@ function readPackageJson(input) {
7332
7487
  // src/_rules/conformity/_stores/session/_services/verify-project/_services/prepare-project/_adapters/include-external-targets/include-external-targets.adapter.ts
7333
7488
  import nodeFs12 from "fs";
7334
7489
  import nodePath12 from "path";
7335
- function includeExternalTargets(inventory, config, baseDirectory) {
7490
+ function includeExternalTargets(inventory, config, baseDirectory, origins) {
7491
+ const skippedDirectoryNames = /* @__PURE__ */ new Set([
7492
+ "build",
7493
+ "coverage",
7494
+ "dist",
7495
+ "node_modules",
7496
+ "out",
7497
+ "reports",
7498
+ "tmp"
7499
+ ]);
7336
7500
  const items = [...inventory.items];
7337
7501
  const pathToId = new Map(inventory.pathToId);
7338
7502
  const realPathToId = new Map(inventory.realPathToId);
7503
+ const resolveTargetKind = (target) => {
7504
+ const normalized = toPosixPath(target);
7505
+ if (pathToId.has(normalized)) {
7506
+ return null;
7507
+ }
7508
+ const absolute = nodePath12.resolve(baseDirectory, normalized);
7509
+ const stats = nodeFs12.statSync(absolute, { throwIfNoEntry: false });
7510
+ if (stats?.isDirectory() === true) {
7511
+ return { absolute, kind: "directory", normalized };
7512
+ }
7513
+ if (stats?.isFile() === true) {
7514
+ return { absolute, kind: "file", normalized };
7515
+ }
7516
+ return null;
7517
+ };
7518
+ const declaredOriginList = origins ?? config.faf.locals.flatMap((local) => [
7519
+ ...local.rootLayers ?? [],
7520
+ ...local.rootFragments?.map((rootFragment) => rootFragment.path) ?? []
7521
+ ]);
7522
+ const declaredOrigins = new Set(
7523
+ declaredOriginList.map((origin) => toPosixPath(origin))
7524
+ );
7525
+ const collectExternalCandidates = () => {
7526
+ if (declaredOrigins.has(".") || !nodeFs12.existsSync(baseDirectory)) {
7527
+ return [];
7528
+ }
7529
+ const readDirectory = (directory) => {
7530
+ try {
7531
+ return nodeFs12.readdirSync(directory, {
7532
+ withFileTypes: true
7533
+ });
7534
+ } catch {
7535
+ return [];
7536
+ }
7537
+ };
7538
+ const candidates = [];
7539
+ const directoryQueue = [baseDirectory];
7540
+ const processDirent2 = (dirent, currentDirectory) => {
7541
+ if (dirent.name.startsWith(".") || dirent.isSymbolicLink()) {
7542
+ return;
7543
+ }
7544
+ const fullPath = nodePath12.join(currentDirectory, dirent.name);
7545
+ const relativePath = toPosixPath(
7546
+ nodePath12.relative(baseDirectory, fullPath)
7547
+ );
7548
+ if (dirent.isDirectory() && !skippedDirectoryNames.has(dirent.name) && !declaredOrigins.has(relativePath)) {
7549
+ directoryQueue.push(fullPath);
7550
+ }
7551
+ if (relativePath !== "fafconfig.ts" && dirent.isFile() && LINTABLE_EXTENSIONS.some((extension) => dirent.name.endsWith(extension))) {
7552
+ candidates.push(relativePath);
7553
+ }
7554
+ };
7555
+ for (const currentDirectory of directoryQueue) {
7556
+ for (const dirent of readDirectory(currentDirectory)) {
7557
+ processDirent2(dirent, currentDirectory);
7558
+ }
7559
+ }
7560
+ candidates.sort(compareOrdinal);
7561
+ return candidates;
7562
+ };
7339
7563
  const sections = [
7340
7564
  config.faf.common?.externalDependencies,
7341
7565
  ...config.faf.locals.map((local) => local.externalDependencies)
7342
7566
  ];
7343
- const targets = sections.flatMap((section) => section ?? []).flatMap((edge) => edge.to);
7344
- const dirents = nodeFs12.existsSync(baseDirectory) ? nodeFs12.readdirSync(baseDirectory, { withFileTypes: true }) : [];
7345
- for (const dirent of dirents) {
7346
- const isRootCandidate = dirent.isFile() && dirent.name !== "fafconfig.ts" && LINTABLE_EXTENSIONS.some((extension) => dirent.name.endsWith(extension));
7347
- if (isRootCandidate) {
7348
- targets.push(dirent.name);
7349
- }
7350
- }
7567
+ const targets = [
7568
+ ...sections.flatMap((section) => section ?? []).flatMap((edge) => edge.to),
7569
+ ...Object.values(config.faf.common?.aliases ?? {}),
7570
+ ...collectExternalCandidates()
7571
+ ];
7351
7572
  for (const target of targets) {
7352
- const normalized = toPosixPath(target);
7353
- const absolute = nodePath12.resolve(baseDirectory, normalized);
7354
- const stats = nodeFs12.statSync(absolute, { throwIfNoEntry: false });
7355
- const isRegularFile = stats?.isFile() === true;
7356
- if (!isRegularFile || pathToId.has(normalized)) {
7573
+ const resolved = resolveTargetKind(target);
7574
+ if (resolved === null) {
7357
7575
  continue;
7358
7576
  }
7359
7577
  const id = items.length;
7360
- const isSymlink = nodeFs12.lstatSync(absolute).isSymbolicLink();
7578
+ const isSymlink = nodeFs12.lstatSync(resolved.absolute).isSymbolicLink();
7361
7579
  const item = {
7362
7580
  depth: 0,
7363
7581
  id,
7364
7582
  isSymlink,
7365
- kind: "file",
7583
+ kind: resolved.kind,
7366
7584
  parentId: null,
7367
- path: normalized,
7585
+ path: resolved.normalized,
7368
7586
  preorderEnd: id,
7369
7587
  preorderStart: id,
7370
- realPath: nodeFs12.realpathSync(absolute),
7588
+ realPath: nodeFs12.realpathSync(resolved.absolute),
7371
7589
  treeOrigin: null
7372
7590
  };
7373
7591
  items.push(item);
@@ -8745,6 +8963,9 @@ function isLiteralConfigPath(path5) {
8745
8963
  if (path5 === ".") {
8746
8964
  return true;
8747
8965
  }
8966
+ if (path5.includes("\\")) {
8967
+ return false;
8968
+ }
8748
8969
  const segments = path5.split("/");
8749
8970
  return segments.every(
8750
8971
  (segment) => !INVALID_CONFIG_PATH_SEGMENTS.has(segment)
@@ -9228,7 +9449,7 @@ var aliasesSchema = z6.record(
9228
9449
  path: [key]
9229
9450
  });
9230
9451
  }
9231
- if (value.length > 0 && !formFields.isLiteralPath(value)) {
9452
+ if (value.includes("*") || value.length > 0 && !formFields.isLiteralPath(value)) {
9232
9453
  context.addIssue({
9233
9454
  code: "custom",
9234
9455
  message: formFields.fixed(CONSTRAINT_INVALID_LITERAL_PATH),
@@ -10004,6 +10225,9 @@ var CONSTRAINT_INVALID_IMPLICIT_EXT = "configuration/invalid-implicit-extension"
10004
10225
  var FORBIDDEN_CODE_EXTENSIONS = /* @__PURE__ */ new Set([
10005
10226
  ".cjs",
10006
10227
  ".cts",
10228
+ ".d.cts",
10229
+ ".d.mts",
10230
+ ".d.ts",
10007
10231
  ".js",
10008
10232
  ".jsx",
10009
10233
  ".mjs",
@@ -10496,6 +10720,36 @@ var validateConfigFormat = /* @__PURE__ */ (() => {
10496
10720
  };
10497
10721
  })();
10498
10722
 
10723
+ // src/_rules/conformity/_stores/session/_services/verify-project/_services/prepare-project/_utils/validate-config-references/_utils/validate-alias-references/validate-alias-references.util.ts
10724
+ function validateAliasReferences(config, context) {
10725
+ const outcomes = [];
10726
+ const entries = Object.entries(config.faf.common?.aliases ?? {});
10727
+ for (const [key, basePath] of entries) {
10728
+ const id = context.inventory.pathToId.get(basePath);
10729
+ if (id === void 0) {
10730
+ outcomes.push(
10731
+ createOutcome("configuration/non-existent-path", {
10732
+ detail: `Alias base "${basePath}" does not exist under configuration base "${context.baseDirectory}".`,
10733
+ element: basePath,
10734
+ propertyPath: `faf.common.aliases.${key}`
10735
+ })
10736
+ );
10737
+ continue;
10738
+ }
10739
+ const item = context.inventory.items[id];
10740
+ if (item === void 0 || item.kind !== "directory") {
10741
+ outcomes.push(
10742
+ createOutcome("configuration/expected-directory", {
10743
+ detail: `Alias base "${basePath}" must be a directory.`,
10744
+ element: basePath,
10745
+ propertyPath: `faf.common.aliases.${key}`
10746
+ })
10747
+ );
10748
+ }
10749
+ }
10750
+ return outcomes;
10751
+ }
10752
+
10499
10753
  // src/_rules/conformity/_stores/session/_services/verify-project/_services/prepare-project/_utils/validate-config-references/_validate-config-references@shared/_utils/reject-directory-in-scope/_utils/reject-directory-scope/reject-directory-scope.util.ts
10500
10754
  function rejectDirectoryScope(check, item, _family) {
10501
10755
  if (item.treeOrigin === null) {
@@ -11529,7 +11783,8 @@ function validateConfigReferences(config, declarations, inventory) {
11529
11783
  ...validateRootReferences(config, context),
11530
11784
  ...validateForeignReferences(config, context),
11531
11785
  ...validateStructuralReferences(config, context),
11532
- ...validateFrontierReferences(config, context)
11786
+ ...validateFrontierReferences(config, context),
11787
+ ...validateAliasReferences(config, context)
11533
11788
  ]);
11534
11789
  }
11535
11790
 
@@ -11596,7 +11851,11 @@ function prepareProject(configPath) {
11596
11851
  declarations.outcomes
11597
11852
  );
11598
11853
  }
11599
- const origins = declarations.value.trees.map((tree) => tree.originPath);
11854
+ const effectiveDeclarations = {
11855
+ ...declarations.value,
11856
+ aliases: aliases.value
11857
+ };
11858
+ const origins = effectiveDeclarations.trees.map((tree) => tree.originPath);
11600
11859
  const entries = listEntries(loaded.value.configDirectory, origins);
11601
11860
  if (!entries.ok) {
11602
11861
  return blocked(
@@ -11610,11 +11869,12 @@ function prepareProject(configPath) {
11610
11869
  const inventory = includeExternalTargets(
11611
11870
  built.inventory,
11612
11871
  formatted.value,
11613
- loaded.value.configDirectory
11872
+ loaded.value.configDirectory,
11873
+ origins
11614
11874
  );
11615
11875
  const references = validateConfigReferences(
11616
11876
  formatted.value,
11617
- declarations.value,
11877
+ effectiveDeclarations,
11618
11878
  inventory
11619
11879
  );
11620
11880
  if (references.length > 0) {
@@ -11629,7 +11889,7 @@ function prepareProject(configPath) {
11629
11889
  aliases: aliases.value,
11630
11890
  baseDirectory: loaded.value.configDirectory,
11631
11891
  configPath: loaded.value.configPath,
11632
- declarations: declarations.value,
11892
+ declarations: effectiveDeclarations,
11633
11893
  inventory,
11634
11894
  inventoryOutcomes: built.outcomes,
11635
11895
  kind: "ready",