@taiga-ui/eslint-plugin-experience-next 0.396.0 → 0.398.0

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.
Files changed (2) hide show
  1. package/index.esm.js +110 -63
  2. package/package.json +4 -4
package/index.esm.js CHANGED
@@ -1665,14 +1665,113 @@ const rule$4 = createRule$7({
1665
1665
  });
1666
1666
 
1667
1667
  const createRule$6 = ESLintUtils.RuleCreator((name) => name);
1668
+ const resolveCacheByOptions = new WeakMap();
1669
+ const nearestFileUpCache = new Map();
1670
+ const markerCache = new Map();
1671
+ const indexFileCache = new Map();
1672
+ const indexExportsCache = new Map();
1668
1673
  var noDeepImportsToIndexedPackages = createRule$6({
1669
1674
  create(context) {
1670
1675
  const parserServices = ESLintUtils.getParserServices(context);
1671
1676
  const program = parserServices.program;
1672
- const compilerHost = ts.createCompilerHost(program.getCompilerOptions(), true);
1673
- function resolveTypescriptModule(moduleSpecifier) {
1674
- const resolved = ts.resolveModuleName(moduleSpecifier, context.filename, program.getCompilerOptions(), compilerHost);
1675
- return resolved.resolvedModule?.resolvedFileName ?? null;
1677
+ const compilerOptions = program.getCompilerOptions();
1678
+ const compilerHost = ts.createCompilerHost(compilerOptions, true);
1679
+ const containingDir = path.dirname(context.filename);
1680
+ function resolveTypescriptModuleCached(moduleSpecifier) {
1681
+ let cache = resolveCacheByOptions.get(compilerOptions);
1682
+ if (!cache) {
1683
+ cache = new Map();
1684
+ resolveCacheByOptions.set(compilerOptions, cache);
1685
+ }
1686
+ const key = `${containingDir}\0${moduleSpecifier}`;
1687
+ if (cache.has(key)) {
1688
+ return cache.get(key);
1689
+ }
1690
+ const resolved = ts.resolveModuleName(moduleSpecifier, context.filename, compilerOptions, compilerHost);
1691
+ const file = resolved.resolvedModule?.resolvedFileName ?? null;
1692
+ cache.set(key, file);
1693
+ return file;
1694
+ }
1695
+ function findNearestFileUpwardsCached(startDirectory, fileName) {
1696
+ const key = `${startDirectory}\0${fileName}`;
1697
+ if (nearestFileUpCache.has(key)) {
1698
+ return nearestFileUpCache.get(key);
1699
+ }
1700
+ let currentDirectory = startDirectory;
1701
+ while (currentDirectory.length > 0) {
1702
+ const candidatePath = path.join(currentDirectory, fileName);
1703
+ if (fs.existsSync(candidatePath)) {
1704
+ nearestFileUpCache.set(key, candidatePath);
1705
+ return candidatePath;
1706
+ }
1707
+ const parentDirectory = path.dirname(currentDirectory);
1708
+ if (parentDirectory === currentDirectory) {
1709
+ break;
1710
+ }
1711
+ currentDirectory = parentDirectory;
1712
+ }
1713
+ nearestFileUpCache.set(key, null);
1714
+ return null;
1715
+ }
1716
+ function pickPackageMarkerFileCached(resolvedRootFilePath) {
1717
+ if (markerCache.has(resolvedRootFilePath)) {
1718
+ return markerCache.get(resolvedRootFilePath);
1719
+ }
1720
+ const resolvedRootDirectory = path.dirname(resolvedRootFilePath);
1721
+ const nearestNgPackageJson = findNearestFileUpwardsCached(resolvedRootDirectory, 'ng-package.json');
1722
+ const nearestPackageJson = findNearestFileUpwardsCached(resolvedRootDirectory, 'package.json');
1723
+ const marker = nearestNgPackageJson ?? nearestPackageJson ?? null;
1724
+ markerCache.set(resolvedRootFilePath, marker);
1725
+ return marker;
1726
+ }
1727
+ function pickIndexFileInDirectoryCached(packageDirectory) {
1728
+ if (indexFileCache.has(packageDirectory)) {
1729
+ return indexFileCache.get(packageDirectory);
1730
+ }
1731
+ const indexTypescriptPath = path.join(packageDirectory, 'index.ts');
1732
+ const indexTypesDeclarationPath = path.join(packageDirectory, 'index.d.ts');
1733
+ let indexFilePath = null;
1734
+ if (fs.existsSync(indexTypescriptPath)) {
1735
+ indexFilePath = indexTypescriptPath;
1736
+ }
1737
+ else if (fs.existsSync(indexTypesDeclarationPath)) {
1738
+ indexFilePath = indexTypesDeclarationPath;
1739
+ }
1740
+ indexFileCache.set(packageDirectory, indexFilePath);
1741
+ return indexFilePath;
1742
+ }
1743
+ function getIndexReExportSpecifiersSet(indexFilePath) {
1744
+ let stat;
1745
+ try {
1746
+ stat = fs.statSync(indexFilePath);
1747
+ }
1748
+ catch {
1749
+ return new Set();
1750
+ }
1751
+ const cached = indexExportsCache.get(indexFilePath);
1752
+ if (cached?.mtimeMs === stat.mtimeMs) {
1753
+ return cached.set;
1754
+ }
1755
+ const fileText = fs.readFileSync(indexFilePath, 'utf8');
1756
+ const sourceFile = ts.createSourceFile(indexFilePath, fileText, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
1757
+ const set = new Set();
1758
+ sourceFile.forEachChild((astNode) => {
1759
+ if (!ts.isExportDeclaration(astNode)) {
1760
+ return;
1761
+ }
1762
+ const ms = astNode.moduleSpecifier;
1763
+ if (ms && ts.isStringLiteral(ms)) {
1764
+ set.add(normalizeModuleSpecifier(stripKnownExtensions(ms.text)));
1765
+ }
1766
+ });
1767
+ indexExportsCache.set(indexFilePath, { mtimeMs: stat.mtimeMs, set });
1768
+ return set;
1769
+ }
1770
+ function indexExportsSubpathCached(indexFilePath, subpath) {
1771
+ const set = getIndexReExportSpecifiersSet(indexFilePath);
1772
+ const expectedSpecifier = normalizeModuleSpecifier(stripKnownExtensions(`./${subpath}`));
1773
+ const expectedIndexSpecifier = normalizeModuleSpecifier(stripKnownExtensions(`./${subpath}/index`));
1774
+ return set.has(expectedSpecifier) || set.has(expectedIndexSpecifier);
1676
1775
  }
1677
1776
  return {
1678
1777
  ImportDeclaration(node) {
@@ -1680,6 +1779,9 @@ var noDeepImportsToIndexedPackages = createRule$6({
1680
1779
  if (typeof importSpecifier !== 'string') {
1681
1780
  return;
1682
1781
  }
1782
+ if (!importSpecifier.includes('/')) {
1783
+ return;
1784
+ }
1683
1785
  if (!isExternalModuleSpecifier(importSpecifier)) {
1684
1786
  return;
1685
1787
  }
@@ -1688,20 +1790,20 @@ var noDeepImportsToIndexedPackages = createRule$6({
1688
1790
  if (!importSubpath) {
1689
1791
  return;
1690
1792
  }
1691
- const resolvedRootModuleFilePath = resolveTypescriptModule(packageRootSpecifier);
1793
+ const resolvedRootModuleFilePath = resolveTypescriptModuleCached(packageRootSpecifier);
1692
1794
  if (!resolvedRootModuleFilePath) {
1693
1795
  return;
1694
1796
  }
1695
- const packageMarkerFilePath = pickPackageMarkerFile(resolvedRootModuleFilePath);
1797
+ const packageMarkerFilePath = pickPackageMarkerFileCached(resolvedRootModuleFilePath);
1696
1798
  if (!packageMarkerFilePath) {
1697
1799
  return;
1698
1800
  }
1699
1801
  const packageDirectory = path.dirname(packageMarkerFilePath);
1700
- const indexFilePath = pickIndexFileInDirectory(packageDirectory);
1802
+ const indexFilePath = pickIndexFileInDirectoryCached(packageDirectory);
1701
1803
  if (!indexFilePath) {
1702
1804
  return;
1703
1805
  }
1704
- const hasMatchingReExport = indexExportsSubpath(indexFilePath, importSubpath);
1806
+ const hasMatchingReExport = indexExportsSubpathCached(indexFilePath, importSubpath);
1705
1807
  if (!hasMatchingReExport) {
1706
1808
  return;
1707
1809
  }
@@ -1735,23 +1837,6 @@ function isExternalModuleSpecifier(moduleSpecifier) {
1735
1837
  }
1736
1838
  return !path.isAbsolute(moduleSpecifier);
1737
1839
  }
1738
- function pickPackageMarkerFile(resolvedRootFilePath) {
1739
- const resolvedRootDirectory = path.dirname(resolvedRootFilePath);
1740
- const nearestNgPackageJson = findNearestFileUpwards(resolvedRootDirectory, 'ng-package.json');
1741
- const nearestPackageJson = findNearestFileUpwards(resolvedRootDirectory, 'package.json');
1742
- return nearestNgPackageJson ?? nearestPackageJson ?? null;
1743
- }
1744
- function pickIndexFileInDirectory(packageDirectory) {
1745
- const indexTypescriptPath = path.join(packageDirectory, 'index.ts');
1746
- const indexTypesDeclarationPath = path.join(packageDirectory, 'index.d.ts');
1747
- if (fs.existsSync(indexTypescriptPath)) {
1748
- return indexTypescriptPath;
1749
- }
1750
- if (fs.existsSync(indexTypesDeclarationPath)) {
1751
- return indexTypesDeclarationPath;
1752
- }
1753
- return null;
1754
- }
1755
1840
  function isScopedPackage(importSpecifier) {
1756
1841
  return importSpecifier.startsWith('@');
1757
1842
  }
@@ -1774,50 +1859,12 @@ function getSubpath(importSpecifier, packageRootSpecifier) {
1774
1859
  }
1775
1860
  return importSpecifier.slice(packageRootSpecifier.length + 1);
1776
1861
  }
1777
- function findNearestFileUpwards(startDirectory, fileName) {
1778
- let currentDirectory = startDirectory;
1779
- while (currentDirectory.length > 0) {
1780
- const candidatePath = path.join(currentDirectory, fileName);
1781
- if (fs.existsSync(candidatePath)) {
1782
- return candidatePath;
1783
- }
1784
- const parentDirectory = path.dirname(currentDirectory);
1785
- if (parentDirectory === currentDirectory) {
1786
- break;
1787
- }
1788
- currentDirectory = parentDirectory;
1789
- }
1790
- return null;
1791
- }
1792
1862
  function normalizeModuleSpecifier(moduleSpecifier) {
1793
1863
  return moduleSpecifier.replaceAll('\\', '/');
1794
1864
  }
1795
1865
  function stripKnownExtensions(filePathOrSpecifier) {
1796
1866
  return filePathOrSpecifier.replace(/\.(d\.ts|ts|tsx|js|jsx|mjs|cjs)$/, '');
1797
1867
  }
1798
- function indexExportsSubpath(indexFilePath, subpath) {
1799
- const fileText = fs.readFileSync(indexFilePath, 'utf8');
1800
- const sourceFile = ts.createSourceFile(indexFilePath, fileText, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
1801
- const expectedSpecifier = normalizeModuleSpecifier(stripKnownExtensions(`./${subpath}`));
1802
- const expectedIndexSpecifier = normalizeModuleSpecifier(stripKnownExtensions(`./${subpath}/index`));
1803
- let isReExportFound = false;
1804
- sourceFile.forEachChild((astNode) => {
1805
- if (isReExportFound) {
1806
- return;
1807
- }
1808
- if (ts.isExportDeclaration(astNode)) {
1809
- const moduleSpecifierNode = astNode.moduleSpecifier;
1810
- if (moduleSpecifierNode && ts.isStringLiteral(moduleSpecifierNode)) {
1811
- const exportedSpecifier = normalizeModuleSpecifier(stripKnownExtensions(moduleSpecifierNode.text));
1812
- if (exportedSpecifier === expectedSpecifier ||
1813
- exportedSpecifier === expectedIndexSpecifier) {
1814
- isReExportFound = true;
1815
- }
1816
- }
1817
- }
1818
- });
1819
- return isReExportFound;
1820
- }
1821
1868
 
1822
1869
  const MESSAGE_ID$2 = 'no-href-with-router-link';
1823
1870
  const ERROR_MESSAGE$1 = 'Do not use href and routerLink attributes together on the same element';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taiga-ui/eslint-plugin-experience-next",
3
- "version": "0.396.0",
3
+ "version": "0.398.0",
4
4
  "description": "An ESLint plugin to enforce a consistent code styles across taiga-ui projects",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -20,15 +20,15 @@
20
20
  "angular-eslint": "^20.7.0",
21
21
  "eslint": "^9.39.2",
22
22
  "eslint-config-prettier": "^10.1.7",
23
- "eslint-plugin-compat": "^6.0.2",
23
+ "eslint-plugin-compat": "^6.1.0",
24
24
  "eslint-plugin-de-morgan": "^2.0.0",
25
25
  "eslint-plugin-decorator-position": "^6.0.0",
26
26
  "eslint-plugin-file-progress": "^3.0.2",
27
27
  "eslint-plugin-import": "^2.32.0",
28
28
  "eslint-plugin-jest": "^29.12.1",
29
- "eslint-plugin-package-json": "^0.88.1",
29
+ "eslint-plugin-package-json": "^0.88.2",
30
30
  "eslint-plugin-perfectionist": "^5.4.0",
31
- "eslint-plugin-playwright": "^2.5.0",
31
+ "eslint-plugin-playwright": "^2.5.1",
32
32
  "eslint-plugin-prettier": "^5.5.5",
33
33
  "eslint-plugin-promise": "^7.2.1",
34
34
  "eslint-plugin-simple-import-sort": "^12.1.1",