@boundaries/elements 1.1.1 → 1.2.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.
@@ -80,6 +80,46 @@ __export(src_exports, {
80
80
  });
81
81
  module.exports = __toCommonJS(src_exports);
82
82
 
83
+ // src/Support/TypeGuards.ts
84
+ function isString(value) {
85
+ return typeof value === "string";
86
+ }
87
+ function isNullish(value) {
88
+ return value === null || value === void 0;
89
+ }
90
+ function isNull(value) {
91
+ return value === null;
92
+ }
93
+ function isBoolean(value) {
94
+ return typeof value === "boolean";
95
+ }
96
+ function isObject(value) {
97
+ return !isNullish(value) && !isBoolean(value) && !isArray(value) && typeof value === "object";
98
+ }
99
+ function isEmptyObject(obj) {
100
+ return isObject(obj) && Object.keys(obj).length === 0;
101
+ }
102
+ function isArray(value) {
103
+ return Array.isArray(value);
104
+ }
105
+ function isEmptyArray(arr) {
106
+ return arr.length === 0;
107
+ }
108
+ function isStringArray(value) {
109
+ return isArray(value) && value.every(isString);
110
+ }
111
+ function isObjectWithProperty(value, key) {
112
+ return isObject(value) && Object.hasOwn(value, key);
113
+ }
114
+ function isObjectWithAnyOfProperties(value, keys) {
115
+ return isObject(value) && keys.some((key) => key in value);
116
+ }
117
+
118
+ // src/Support/Paths.ts
119
+ function normalizePath(filePath) {
120
+ return filePath.replaceAll("\\", "/");
121
+ }
122
+
83
123
  // src/Config/Config.ts
84
124
  var Config = class {
85
125
  /** The ignore paths */
@@ -90,6 +130,10 @@ var Config = class {
90
130
  _legacyTemplates;
91
131
  /** Whether the cache is enabled */
92
132
  _cache;
133
+ /** Configuration for categorizing dependencies as external or local */
134
+ _flagAsExternal;
135
+ /** Root path of the project */
136
+ _rootPath;
93
137
  /**
94
138
  * Creates a new Config instance
95
139
  * @param options Configuration options
@@ -99,6 +143,18 @@ var Config = class {
99
143
  this._includePaths = options?.includePaths;
100
144
  this._legacyTemplates = options?.legacyTemplates ?? true;
101
145
  this._cache = options?.cache ?? true;
146
+ this._flagAsExternal = {
147
+ unresolvableAlias: options?.flagAsExternal?.unresolvableAlias ?? true,
148
+ inNodeModules: options?.flagAsExternal?.inNodeModules ?? true,
149
+ outsideRootPath: options?.flagAsExternal?.outsideRootPath ?? false,
150
+ customSourcePatterns: options?.flagAsExternal?.customSourcePatterns ?? []
151
+ };
152
+ if (options?.rootPath) {
153
+ const normalizedRoot = normalizePath(options.rootPath);
154
+ this._rootPath = normalizedRoot.endsWith("/") ? normalizedRoot : `${normalizedRoot}/`;
155
+ } else {
156
+ this._rootPath = void 0;
157
+ }
102
158
  }
103
159
  /**
104
160
  * The normalized configuration options
@@ -108,7 +164,9 @@ var Config = class {
108
164
  ignorePaths: this._ignorePaths,
109
165
  includePaths: this._includePaths,
110
166
  legacyTemplates: this._legacyTemplates,
111
- cache: this._cache
167
+ cache: this._cache,
168
+ flagAsExternal: this._flagAsExternal,
169
+ rootPath: this._rootPath
112
170
  };
113
171
  }
114
172
  /**
@@ -118,7 +176,9 @@ var Config = class {
118
176
  return {
119
177
  ignorePaths: this._ignorePaths,
120
178
  includePaths: this._includePaths,
121
- cache: this._cache
179
+ cache: this._cache,
180
+ flagAsExternal: this._flagAsExternal,
181
+ rootPath: this._rootPath
122
182
  };
123
183
  }
124
184
  /**
@@ -140,41 +200,6 @@ var Config = class {
140
200
  // src/Matcher/BaseElementsMatcher.ts
141
201
  var import_handlebars = __toESM(require("handlebars"));
142
202
 
143
- // src/Support/TypeGuards.ts
144
- function isString(value) {
145
- return typeof value === "string";
146
- }
147
- function isNullish(value) {
148
- return value === null || value === void 0;
149
- }
150
- function isNull(value) {
151
- return value === null;
152
- }
153
- function isBoolean(value) {
154
- return typeof value === "boolean";
155
- }
156
- function isObject(value) {
157
- return !isNullish(value) && !isBoolean(value) && !isArray(value) && typeof value === "object";
158
- }
159
- function isEmptyObject(obj) {
160
- return isObject(obj) && Object.keys(obj).length === 0;
161
- }
162
- function isArray(value) {
163
- return Array.isArray(value);
164
- }
165
- function isEmptyArray(arr) {
166
- return arr.length === 0;
167
- }
168
- function isStringArray(value) {
169
- return isArray(value) && value.every(isString);
170
- }
171
- function isObjectWithProperty(value, key) {
172
- return isObject(value) && Object.hasOwn(value, key);
173
- }
174
- function isObjectWithAnyOfProperties(value, keys) {
175
- return isObject(value) && keys.some((key) => key in value);
176
- }
177
-
178
203
  // src/Matcher/MatcherHelpers.ts
179
204
  function isCapturedValuesSelector(value) {
180
205
  if (!isObject(value) || isArray(value)) {
@@ -244,7 +269,7 @@ function isExternalLibrariesSelector(value) {
244
269
  }
245
270
 
246
271
  // src/Matcher/BaseElementsMatcher.ts
247
- var HANDLEBARS_TEMPLATE_REGEX = /{{\s*[^}]+\s*}}/;
272
+ var HANDLEBARS_TEMPLATE_REGEX = /{{\s*[^}\s]+(?:\s+[^}\s]+)*\s*}}/;
248
273
  var LEGACY_TEMPLATE_REGEX = /\$\{([^}]+)\}/g;
249
274
  function normalizeSelector(selector) {
250
275
  if (isSimpleElementSelectorByType(selector)) {
@@ -1605,17 +1630,72 @@ var ElementsDescriptor = class {
1605
1630
  return pkg;
1606
1631
  }
1607
1632
  /**
1608
- * Determines if an element is external based on its file path and dependency source.
1609
- * Files inside "node_modules" are considered external.
1610
- * If the dependency source is not provided, only the file path is considered.
1611
- * If the dependency source is provided, it must not be a local path (i.e, it should start by "./", "../", or "/").
1612
- * @param filePath
1613
- * @param dependencySource
1614
- * @returns
1633
+ * Determines if a file path is outside the configured root path.
1634
+ * @param filePath The file path to check.
1635
+ * @returns True if the file path is outside the root path, false otherwise.
1636
+ */
1637
+ _isOutsideRootPath(filePath) {
1638
+ if (!this._config.rootPath) {
1639
+ return false;
1640
+ }
1641
+ return !filePath.startsWith(this._config.rootPath);
1642
+ }
1643
+ /**
1644
+ * Converts an absolute file path to a relative path if rootPath is configured.
1645
+ * If rootPath is not configured, returns the path as-is (maintains backward compatibility).
1646
+ * @param filePath The file path to convert (can be absolute or relative)
1647
+ * @returns The relative path if rootPath is configured and path is absolute, otherwise the original path
1648
+ */
1649
+ _toRelativePath(filePath) {
1650
+ if (!this._config.rootPath || this._isOutsideRootPath(filePath)) {
1651
+ return filePath;
1652
+ }
1653
+ return filePath.replace(this._config.rootPath, "");
1654
+ }
1655
+ /**
1656
+ * Checks if a source string matches any of the provided patterns using micromatch.
1657
+ * @param patterns - Array of micromatch patterns
1658
+ * @param source - The source string to match against patterns
1659
+ * @returns True if the source matches any pattern, false otherwise
1615
1660
  */
1616
- _isExternalDependency(filePath, dependencySource) {
1617
- return (!filePath || filePath.includes("node_modules")) && // Not having a source, and being in node_modules only could happen if user is analyzing a file directly from there, not as a dependency. Should this be considered external then?
1618
- (!dependencySource || this._dependencySourceIsExternalOrScoped(dependencySource));
1661
+ _matchesAnyPattern(patterns, source) {
1662
+ if (!source || patterns.length === 0) {
1663
+ return false;
1664
+ }
1665
+ return this._micromatch.isMatch(source, patterns);
1666
+ }
1667
+ /**
1668
+ * Determines if an element is external based on its file path and dependency source.
1669
+ * Uses the flagAsExternal configuration to evaluate multiple conditions with OR logic:
1670
+ * - unresolvableAlias: Files whose path cannot be resolved (filePath is null)
1671
+ * - inNodeModules: Non-relative paths that include "node_modules"
1672
+ * - outsideRootPath: Resolved path is outside the configured root path (only if rootPath is configured)
1673
+ * - customSourcePatterns: Source matches any of the configured patterns
1674
+ * @param filePath The resolved file path (null if unresolved). Can be absolute if rootPath is configured, or relative if rootPath is not configured.
1675
+ * @param isOutsideRootPath Whether the file path is outside the configured root path.
1676
+ * @param dependencySource The import/export source string
1677
+ * @returns True if any of the configured conditions is met, false otherwise
1678
+ */
1679
+ _isExternalDependency(filePath, isOutsideRootPath, dependencySource) {
1680
+ const {
1681
+ unresolvableAlias,
1682
+ inNodeModules,
1683
+ outsideRootPath,
1684
+ customSourcePatterns
1685
+ } = this._config.flagAsExternal;
1686
+ if (outsideRootPath && isOutsideRootPath) {
1687
+ return true;
1688
+ }
1689
+ if (inNodeModules && filePath?.includes("node_modules")) {
1690
+ return true;
1691
+ }
1692
+ if (unresolvableAlias && !filePath && dependencySource && this._dependencySourceIsExternalOrScoped(dependencySource)) {
1693
+ return true;
1694
+ }
1695
+ if (this._matchesAnyPattern(customSourcePatterns, dependencySource)) {
1696
+ return true;
1697
+ }
1698
+ return false;
1619
1699
  }
1620
1700
  /**
1621
1701
  * Determines if a given path is included based on the configuration.
@@ -1683,6 +1763,16 @@ var ElementsDescriptor = class {
1683
1763
  }
1684
1764
  return `${[...allPathSegments].reverse().join("/").split(result)[0]}${result}`;
1685
1765
  }
1766
+ /**
1767
+ * Determines if an element descriptor matches the given parameters in the provided path.
1768
+ * @param options The options for matching the descriptor.
1769
+ * @param options.elementDescriptor The element descriptor to match.
1770
+ * @param options.filePath The file path to match against the descriptor.
1771
+ * @param options.currentPathSegments The current path segments leading to the element.
1772
+ * @param options.lastPathSegmentMatching The last path segment that was matched.
1773
+ * @param options.alreadyMatched Whether the element matched previously.
1774
+ * @returns The result of the match, including whether it matched.
1775
+ */
1686
1776
  _fileDescriptorMatch({
1687
1777
  elementDescriptor,
1688
1778
  filePath,
@@ -1837,10 +1927,11 @@ var ElementsDescriptor = class {
1837
1927
  /**
1838
1928
  * Returns an external or core dependency element given its dependency source and file path.
1839
1929
  * @param dependencySource The source of the dependency.
1840
- * @param filePath The resolved file path of the dependency, if known.
1930
+ * @param isOutsideRootPath Whether the file path is outside the configured root path.
1931
+ * @param filePath The resolved file path of the dependency, if known. Can be absolute if rootPath is configured.
1841
1932
  * @returns The external or core dependency element, or null if it is a local dependency.
1842
1933
  */
1843
- _getExternalOrCoreDependencyElement(dependencySource, filePath) {
1934
+ _getExternalOrCoreDependencyElement(dependencySource, isOutsideRootPath, filePath) {
1844
1935
  const baseDependencySource = this._getExternalOrCoreModuleBaseSource(dependencySource);
1845
1936
  const isCore = this._dependencySourceIsCoreModule(
1846
1937
  dependencySource,
@@ -1857,6 +1948,7 @@ var ElementsDescriptor = class {
1857
1948
  }
1858
1949
  const isExternal = this._isExternalDependency(
1859
1950
  filePath || null,
1951
+ isOutsideRootPath,
1860
1952
  dependencySource
1861
1953
  );
1862
1954
  if (isExternal) {
@@ -1877,12 +1969,19 @@ var ElementsDescriptor = class {
1877
1969
  if (this._descriptionsCache.has(cacheKey)) {
1878
1970
  return this._descriptionsCache.get(cacheKey);
1879
1971
  }
1880
- const externalOrCoreDependencyElement = dependencySource ? this._getExternalOrCoreDependencyElement(dependencySource, filePath) : null;
1972
+ const normalizedFilePath = filePath ? normalizePath(filePath) : filePath;
1973
+ const isOutsideRootPath = normalizedFilePath ? this._isOutsideRootPath(normalizedFilePath) : false;
1974
+ const relativePath = normalizedFilePath && this._config.rootPath ? this._toRelativePath(normalizedFilePath) : normalizedFilePath;
1975
+ const externalOrCoreDependencyElement = dependencySource ? this._getExternalOrCoreDependencyElement(
1976
+ dependencySource,
1977
+ isOutsideRootPath,
1978
+ relativePath
1979
+ ) : null;
1881
1980
  if (externalOrCoreDependencyElement) {
1882
1981
  this._descriptionsCache.set(cacheKey, externalOrCoreDependencyElement);
1883
1982
  return externalOrCoreDependencyElement;
1884
1983
  }
1885
- const fileDescription = this._describeFile(filePath);
1984
+ const fileDescription = this._describeFile(relativePath);
1886
1985
  const elementResult = dependencySource ? {
1887
1986
  ...fileDescription,
1888
1987
  source: dependencySource
@@ -1892,7 +1991,7 @@ var ElementsDescriptor = class {
1892
1991
  }
1893
1992
  /**
1894
1993
  * Describes an element given its file path.
1895
- * @param filePath The path of the file to describe.
1994
+ * @param filePath The path of the file to describe. Can be absolute if rootPath is configured, or relative if not.
1896
1995
  * @returns The description of the element.
1897
1996
  */
1898
1997
  describeElement(filePath) {
@@ -1901,7 +2000,7 @@ var ElementsDescriptor = class {
1901
2000
  /**
1902
2001
  * Describes a dependency element given its dependency source and file path.
1903
2002
  * @param dependencySource The source of the dependency.
1904
- * @param filePath The path of the file being the dependency, if known.
2003
+ * @param filePath The path of the file being the dependency, if known. Can be absolute if rootPath is configured, or relative if not.
1905
2004
  * @returns The description of the dependency element.
1906
2005
  */
1907
2006
  describeDependencyElement(dependencySource, filePath) {
@@ -2289,7 +2388,7 @@ var MatchersCache = class extends CacheManager {
2289
2388
  config,
2290
2389
  elementDescriptors
2291
2390
  }) {
2292
- const configHash = `${config.legacyTemplates}|${config.includePaths}|${config.ignorePaths}|${config.cache}`;
2391
+ const configHash = `${config.legacyTemplates}|${config.includePaths}|${config.ignorePaths}|${config.cache}|${config.rootPath}|${config.flagAsExternal.inNodeModules}|${config.flagAsExternal.unresolvableAlias}|${config.flagAsExternal.outsideRootPath}|${config.flagAsExternal.customSourcePatterns.join(",")}`;
2293
2392
  const elementDescriptorsHash = elementDescriptors.map(
2294
2393
  (descriptor) => `${descriptor.type}|${descriptor.category}|${descriptor.pattern}|${descriptor.basePattern}|${descriptor.mode}|${descriptor.capture}|${descriptor.baseCapture}`
2295
2394
  ).join(",");