@boundaries/elements 1.1.2 → 2.0.0-beta.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.
@@ -5,6 +5,49 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
5
5
  throw Error('Dynamic require of "' + x + '" is not supported');
6
6
  });
7
7
 
8
+ // src/Support/TypeGuards.ts
9
+ function isString(value) {
10
+ return typeof value === "string";
11
+ }
12
+ function isUndefined(value) {
13
+ return value === void 0;
14
+ }
15
+ function isNull(value) {
16
+ return value === null;
17
+ }
18
+ function isNullish(value) {
19
+ return isUndefined(value) || isNull(value);
20
+ }
21
+ function isBoolean(value) {
22
+ return typeof value === "boolean";
23
+ }
24
+ function isObject(value) {
25
+ return !isNullish(value) && !isBoolean(value) && !isArray(value) && typeof value === "object";
26
+ }
27
+ function isEmptyObject(obj) {
28
+ return isObject(obj) && Object.keys(obj).length === 0;
29
+ }
30
+ function isArray(value) {
31
+ return Array.isArray(value);
32
+ }
33
+ function isEmptyArray(arr) {
34
+ return arr.length === 0;
35
+ }
36
+ function isStringArray(value) {
37
+ return isArray(value) && value.every(isString);
38
+ }
39
+ function isObjectWithProperty(value, key) {
40
+ return isObject(value) && Object.hasOwn(value, key);
41
+ }
42
+ function isObjectWithAnyOfProperties(value, keys) {
43
+ return isObject(value) && keys.some((key) => key in value);
44
+ }
45
+
46
+ // src/Support/Paths.ts
47
+ function normalizePath(filePath) {
48
+ return filePath.replaceAll("\\", "/");
49
+ }
50
+
8
51
  // src/Config/Config.ts
9
52
  var Config = class {
10
53
  /** The ignore paths */
@@ -15,6 +58,10 @@ var Config = class {
15
58
  _legacyTemplates;
16
59
  /** Whether the cache is enabled */
17
60
  _cache;
61
+ /** Configuration for categorizing dependencies as external or local */
62
+ _flagAsExternal;
63
+ /** Root path of the project */
64
+ _rootPath;
18
65
  /**
19
66
  * Creates a new Config instance
20
67
  * @param options Configuration options
@@ -24,6 +71,18 @@ var Config = class {
24
71
  this._includePaths = options?.includePaths;
25
72
  this._legacyTemplates = options?.legacyTemplates ?? true;
26
73
  this._cache = options?.cache ?? true;
74
+ this._flagAsExternal = {
75
+ unresolvableAlias: options?.flagAsExternal?.unresolvableAlias ?? true,
76
+ inNodeModules: options?.flagAsExternal?.inNodeModules ?? true,
77
+ outsideRootPath: options?.flagAsExternal?.outsideRootPath ?? false,
78
+ customSourcePatterns: options?.flagAsExternal?.customSourcePatterns ?? []
79
+ };
80
+ if (options?.rootPath) {
81
+ const normalizedRoot = normalizePath(options.rootPath);
82
+ this._rootPath = normalizedRoot.endsWith("/") ? normalizedRoot : `${normalizedRoot}/`;
83
+ } else {
84
+ this._rootPath = void 0;
85
+ }
27
86
  }
28
87
  /**
29
88
  * The normalized configuration options
@@ -33,7 +92,9 @@ var Config = class {
33
92
  ignorePaths: this._ignorePaths,
34
93
  includePaths: this._includePaths,
35
94
  legacyTemplates: this._legacyTemplates,
36
- cache: this._cache
95
+ cache: this._cache,
96
+ flagAsExternal: this._flagAsExternal,
97
+ rootPath: this._rootPath
37
98
  };
38
99
  }
39
100
  /**
@@ -43,7 +104,9 @@ var Config = class {
43
104
  return {
44
105
  ignorePaths: this._ignorePaths,
45
106
  includePaths: this._includePaths,
46
- cache: this._cache
107
+ cache: this._cache,
108
+ flagAsExternal: this._flagAsExternal,
109
+ rootPath: this._rootPath
47
110
  };
48
111
  }
49
112
  /**
@@ -64,137 +127,8 @@ var Config = class {
64
127
 
65
128
  // src/Matcher/BaseElementsMatcher.ts
66
129
  import Handlebars from "handlebars";
67
-
68
- // src/Support/TypeGuards.ts
69
- function isString(value) {
70
- return typeof value === "string";
71
- }
72
- function isNullish(value) {
73
- return value === null || value === void 0;
74
- }
75
- function isNull(value) {
76
- return value === null;
77
- }
78
- function isBoolean(value) {
79
- return typeof value === "boolean";
80
- }
81
- function isObject(value) {
82
- return !isNullish(value) && !isBoolean(value) && !isArray(value) && typeof value === "object";
83
- }
84
- function isEmptyObject(obj) {
85
- return isObject(obj) && Object.keys(obj).length === 0;
86
- }
87
- function isArray(value) {
88
- return Array.isArray(value);
89
- }
90
- function isEmptyArray(arr) {
91
- return arr.length === 0;
92
- }
93
- function isStringArray(value) {
94
- return isArray(value) && value.every(isString);
95
- }
96
- function isObjectWithProperty(value, key) {
97
- return isObject(value) && Object.hasOwn(value, key);
98
- }
99
- function isObjectWithAnyOfProperties(value, keys) {
100
- return isObject(value) && keys.some((key) => key in value);
101
- }
102
-
103
- // src/Matcher/MatcherHelpers.ts
104
- function isCapturedValuesSelector(value) {
105
- if (!isObject(value) || isArray(value)) {
106
- return false;
107
- }
108
- return Object.values(value).every(
109
- (pattern) => isString(pattern) || isStringArray(pattern)
110
- );
111
- }
112
- function isSimpleElementSelectorByType(value) {
113
- return isString(value);
114
- }
115
- function isBaseElementSelectorData(value) {
116
- return isObjectWithAnyOfProperties(value, [
117
- "path",
118
- "elementPath",
119
- "internalPath",
120
- "type",
121
- "category",
122
- "captured",
123
- "origin",
124
- "source",
125
- "baseSource",
126
- "isIgnored",
127
- "isUnknown"
128
- ]);
129
- }
130
- function isElementSelectorData(value) {
131
- return isBaseElementSelectorData(value) || isObjectWithAnyOfProperties(value, [
132
- "relationship",
133
- "kind",
134
- "specifiers",
135
- "nodeKind"
136
- ]);
137
- }
138
- function isElementSelectorWithLegacyOptions(value) {
139
- return isArray(value) && (value.length === 2 && isSimpleElementSelectorByType(value[0]) && // NOTE: Arrays of length 2 with captured values selector as second element having a key "type" or "category" will be treated as legacy options instead of two different selectors. We have to live with this limitation for now.
140
- isCapturedValuesSelector(value[1]) || // NOTE: Backwards compatibility: Allow arrays of length 1 with simple element selector. Some users might defined arrays without options.
141
- value.length === 1 && isSimpleElementSelectorByType(value[0]));
142
- }
143
- function isElementSelector(value) {
144
- return isSimpleElementSelectorByType(value) || isElementSelectorData(value) || isElementSelectorWithLegacyOptions(value);
145
- }
146
- function isElementsSelector(value) {
147
- return isElementSelector(value) || isArray(value) && !isEmptyArray(value) && value.every(isElementSelector);
148
- }
149
- function isDependencySelector(value) {
150
- return isObjectWithAnyOfProperties(value, ["from", "to"]);
151
- }
152
- function isExternalLibrarySelectorOptionsWithPath(value) {
153
- return isObjectWithProperty(value, "path") && (isString(value.path) || isStringArray(value.path));
154
- }
155
- function isExternalLibrarySelectorOptionsWithSpecifiers(value) {
156
- return isObjectWithProperty(value, "specifiers") && isStringArray(value.specifiers);
157
- }
158
- function isExternalLibrarySelectorOptions(value) {
159
- return isExternalLibrarySelectorOptionsWithPath(value) || isExternalLibrarySelectorOptionsWithSpecifiers(value);
160
- }
161
- function isExternalLibrarySelectorWithOptions(value) {
162
- return isArray(value) && value.length === 2 && isSimpleElementSelectorByType(value[0]) && isExternalLibrarySelectorOptions(value[1]);
163
- }
164
- function isExternalLibrarySelector(value) {
165
- return isSimpleElementSelectorByType(value) || isExternalLibrarySelectorWithOptions(value);
166
- }
167
- function isExternalLibrariesSelector(value) {
168
- return isExternalLibrarySelector(value) || isArray(value) && !isEmptyArray(value) && value.every(isExternalLibrarySelector);
169
- }
170
-
171
- // src/Matcher/BaseElementsMatcher.ts
172
- var HANDLEBARS_TEMPLATE_REGEX = /{{\s*[^}\s]+(?:\s+[^}\s]+)*\s*}}/;
173
130
  var LEGACY_TEMPLATE_REGEX = /\$\{([^}]+)\}/g;
174
- function normalizeSelector(selector) {
175
- if (isSimpleElementSelectorByType(selector)) {
176
- return { type: selector };
177
- }
178
- if (isElementSelectorData(selector)) {
179
- return { ...selector };
180
- }
181
- if (isElementSelectorWithLegacyOptions(selector)) {
182
- return {
183
- type: selector[0],
184
- captured: selector[1] ? { ...selector[1] } : void 0
185
- };
186
- }
187
- throw new Error("Invalid element selector");
188
- }
189
- function normalizeElementsSelector(elementsSelector) {
190
- if (isArray(elementsSelector)) {
191
- if (isElementSelectorWithLegacyOptions(elementsSelector)) {
192
- return [normalizeSelector(elementsSelector)];
193
- }
194
- return elementsSelector.map((sel) => normalizeSelector(sel));
195
- }
196
- return [normalizeSelector(elementsSelector)];
197
- }
131
+ var HANDLEBARS_TEMPLATE_REGEX = /{{\s*[^{}\s][^{}]*}}/;
198
132
  var BaseElementsMatcher = class {
199
133
  /**
200
134
  * Option to use legacy templates with ${} syntax.
@@ -219,6 +153,9 @@ var BaseElementsMatcher = class {
219
153
  * @returns The converted template.
220
154
  */
221
155
  _getBackwardsCompatibleTemplate(template) {
156
+ if (!template) {
157
+ return template;
158
+ }
222
159
  return template.replaceAll(LEGACY_TEMPLATE_REGEX, "{{ $1 }}");
223
160
  }
224
161
  /**
@@ -227,6 +164,9 @@ var BaseElementsMatcher = class {
227
164
  * @returns True if the template contains Handlebars syntax, false otherwise.
228
165
  */
229
166
  _isHandlebarsTemplate(template) {
167
+ if (!template) {
168
+ return false;
169
+ }
230
170
  return HANDLEBARS_TEMPLATE_REGEX.test(template);
231
171
  }
232
172
  /**
@@ -258,6 +198,14 @@ var BaseElementsMatcher = class {
258
198
  }
259
199
  return this._getRenderedTemplate(template, templateData);
260
200
  }
201
+ /**
202
+ * Cleans a micromatch pattern by removing falsy values from arrays.
203
+ * @param pattern The micromatch pattern(s) to clean.
204
+ * @returns The cleaned pattern. If an array is provided, falsy entries are removed and the resulting array may be empty. If null is provided, null is returned unchanged.
205
+ */
206
+ cleanMicromatchPattern(pattern) {
207
+ return isArray(pattern) ? pattern.filter(Boolean) : pattern;
208
+ }
261
209
  /**
262
210
  * Returns whether the given value matches the micromatch pattern, converting non-string values to strings.
263
211
  * Optimized version with caching for better performance.
@@ -266,9 +214,18 @@ var BaseElementsMatcher = class {
266
214
  * @returns Whether the value matches the pattern.
267
215
  */
268
216
  isMicromatchMatch(value, pattern) {
217
+ if (isNull(pattern)) {
218
+ return isNull(value);
219
+ }
220
+ if (isNull(value)) {
221
+ return isArray(pattern) && pattern.some(isNull);
222
+ }
223
+ const patternToCheck = this.cleanMicromatchPattern(pattern);
224
+ if (!patternToCheck?.length) {
225
+ return false;
226
+ }
269
227
  const elementValueToCheck = !value || !isString(value) ? String(value) : value;
270
- const selectorValueToCheck = isArray(pattern) ? pattern.filter(Boolean) : pattern;
271
- return this.micromatch.isMatch(elementValueToCheck, selectorValueToCheck);
228
+ return this.micromatch.isMatch(elementValueToCheck, patternToCheck);
272
229
  }
273
230
  /**
274
231
  * Returns whether the given value matches the micromatch pattern after rendering it as a template.
@@ -278,18 +235,17 @@ var BaseElementsMatcher = class {
278
235
  * @returns Whether the value matches the rendered pattern.
279
236
  */
280
237
  isTemplateMicromatchMatch(pattern, templateData, value) {
281
- if (isNullish(value)) {
238
+ if (isUndefined(value)) {
282
239
  return false;
283
240
  }
284
241
  const patternRendered = this.getRenderedTemplates(pattern, templateData);
285
- if (!patternRendered) {
242
+ if (!isNull(patternRendered) && !patternRendered) {
286
243
  return false;
287
244
  }
288
- const filteredPattern = isArray(patternRendered) ? patternRendered.filter(Boolean) : patternRendered;
289
245
  if (isArray(value)) {
290
- return value.some((val) => this.isMicromatchMatch(val, filteredPattern));
246
+ return value.some((val) => this.isMicromatchMatch(val, patternRendered));
291
247
  }
292
- return this.isMicromatchMatch(value, filteredPattern);
248
+ return this.isMicromatchMatch(value, patternRendered);
293
249
  }
294
250
  /**
295
251
  * Whether the given element key matches the selector key as booleans.
@@ -333,20 +289,113 @@ var BaseElementsMatcher = class {
333
289
  if (!(selectorKey in selector)) {
334
290
  return true;
335
291
  }
336
- if (!selectorValue) {
337
- return false;
338
- }
339
- if (!isObjectWithProperty(element, elementKey)) {
292
+ if (isUndefined(selectorValue) || !isObjectWithProperty(element, String(elementKey))) {
340
293
  return false;
341
294
  }
295
+ const elementValue = element[String(elementKey)];
342
296
  return this.isTemplateMicromatchMatch(
343
297
  selectorValue,
344
298
  templateData,
345
- element[elementKey]
299
+ elementValue
346
300
  );
347
301
  }
348
302
  };
349
303
 
304
+ // src/Matcher/MatcherHelpers.ts
305
+ function isCapturedValuesObjectSelector(value) {
306
+ if (!isObject(value) || isArray(value)) {
307
+ return false;
308
+ }
309
+ return Object.values(value).every(
310
+ (pattern) => isString(pattern) || isStringArray(pattern)
311
+ );
312
+ }
313
+ function isCapturedValuesSelector(value) {
314
+ if (isArray(value)) {
315
+ return value.every((item) => isCapturedValuesObjectSelector(item));
316
+ }
317
+ return isCapturedValuesObjectSelector(value);
318
+ }
319
+ function isSimpleElementSelectorByType(value) {
320
+ return isString(value);
321
+ }
322
+ function isBaseElementSelectorData(value) {
323
+ return isObjectWithAnyOfProperties(value, [
324
+ "path",
325
+ "elementPath",
326
+ "internalPath",
327
+ "type",
328
+ "category",
329
+ "captured",
330
+ "parent",
331
+ "origin",
332
+ "source",
333
+ "module",
334
+ "isIgnored",
335
+ "isUnknown"
336
+ ]);
337
+ }
338
+ function isElementSelectorData(value) {
339
+ return isBaseElementSelectorData(value);
340
+ }
341
+ function isElementSelectorWithLegacyOptions(value) {
342
+ return isArray(value) && (value.length === 2 && isSimpleElementSelectorByType(value[0]) && // NOTE: Arrays of length 2 with captured values selector as second element having a key "type" or "category" will be treated as legacy options instead of two different selectors. We have to live with this limitation for now.
343
+ isCapturedValuesSelector(value[1]) || // NOTE: Backwards compatibility: Allow arrays of length 1 with simple element selector. Some users might defined arrays without options.
344
+ value.length === 1 && isSimpleElementSelectorByType(value[0]));
345
+ }
346
+ function isElementSelector(value) {
347
+ return isSimpleElementSelectorByType(value) || isElementSelectorData(value) || isElementSelectorWithLegacyOptions(value);
348
+ }
349
+ function isElementsSelector(value) {
350
+ return isElementSelector(value) || isArray(value) && !isEmptyArray(value) && value.every(isElementSelector);
351
+ }
352
+ function normalizeElementSelector(selector) {
353
+ if (isSimpleElementSelectorByType(selector)) {
354
+ return { type: selector };
355
+ }
356
+ if (isElementSelectorData(selector)) {
357
+ return { ...selector };
358
+ }
359
+ if (isElementSelectorWithLegacyOptions(selector)) {
360
+ return {
361
+ type: selector[0],
362
+ captured: selector[1] ? { ...selector[1] } : void 0
363
+ };
364
+ }
365
+ throw new Error("Invalid element selector");
366
+ }
367
+ function normalizeElementsSelector(elementsSelector) {
368
+ if (isArray(elementsSelector)) {
369
+ if (isElementSelectorWithLegacyOptions(elementsSelector)) {
370
+ return [normalizeElementSelector(elementsSelector)];
371
+ }
372
+ return elementsSelector.map((sel) => normalizeElementSelector(sel));
373
+ }
374
+ return [normalizeElementSelector(elementsSelector)];
375
+ }
376
+ function isDependencySelector(value) {
377
+ if (!isObjectWithAnyOfProperties(value, ["from", "to", "dependency"])) {
378
+ return false;
379
+ }
380
+ const fromIsValid = !isObjectWithProperty(value, "from") || isElementsSelector(value.from);
381
+ const toIsValid = !isObjectWithProperty(value, "to") || isElementsSelector(value.to);
382
+ const dependencyIsValid = !isObjectWithProperty(value, "dependency") || isDependencyDataSelector(value.dependency);
383
+ return fromIsValid && toIsValid && dependencyIsValid;
384
+ }
385
+ function isDependencyDataSelectorData(value) {
386
+ return isObjectWithAnyOfProperties(value, [
387
+ "kind",
388
+ "relationship",
389
+ "specifiers",
390
+ "nodeKind",
391
+ "source",
392
+ "module"
393
+ ]);
394
+ }
395
+ function isDependencyDataSelector(value) {
396
+ return isDependencyDataSelectorData(value) || isArray(value) && !isEmptyArray(value) && value.every(isDependencyDataSelectorData);
397
+ }
398
+
350
399
  // src/Matcher/DependenciesMatcher.ts
351
400
  var DependenciesMatcher = class extends BaseElementsMatcher {
352
401
  /**
@@ -369,68 +418,20 @@ var DependenciesMatcher = class extends BaseElementsMatcher {
369
418
  * @param selector The dependency selector to normalize.
370
419
  * @returns The normalized dependency selector.
371
420
  */
372
- _normalizeDependencySelector(selector, dependencySelectorsGlobals) {
421
+ _normalizeDependencySelector(selector) {
373
422
  if (!isDependencySelector(selector)) {
374
423
  throw new Error("Invalid dependency selector");
375
424
  }
376
- let normalizedDependencySelectors = selector.to ? normalizeElementsSelector(selector.to) : null;
377
- if (normalizedDependencySelectors) {
378
- normalizedDependencySelectors = normalizedDependencySelectors.map(
379
- (depSelector) => {
380
- return {
381
- ...dependencySelectorsGlobals,
382
- ...depSelector
383
- };
384
- }
385
- );
425
+ let normalizedDependencySelectors = null;
426
+ if (selector.dependency && isDependencyDataSelector(selector.dependency)) {
427
+ normalizedDependencySelectors = isArray(selector.dependency) ? selector.dependency : [selector.dependency];
386
428
  }
387
429
  return {
388
430
  from: selector.from ? normalizeElementsSelector(selector.from) : null,
389
- to: normalizedDependencySelectors
431
+ to: selector.to ? normalizeElementsSelector(selector.to) : null,
432
+ dependency: normalizedDependencySelectors
390
433
  };
391
434
  }
392
- /**
393
- * Converts a DependencyElementSelectorData to a BaseElementSelectorData, by removing dependency-specific properties.
394
- * @param selector The dependency element selector data.
395
- * @returns The base element selector data.
396
- */
397
- _convertDependencyElementSelectorDataToBaseElementSelectorData(selector) {
398
- const baseSelector = {};
399
- if (selector.type) {
400
- baseSelector.type = selector.type;
401
- }
402
- if (selector.category) {
403
- baseSelector.category = selector.category;
404
- }
405
- if (selector.path) {
406
- baseSelector.path = selector.path;
407
- }
408
- if (selector.elementPath) {
409
- baseSelector.elementPath = selector.elementPath;
410
- }
411
- if (selector.internalPath) {
412
- baseSelector.internalPath = selector.internalPath;
413
- }
414
- if (selector.captured) {
415
- baseSelector.captured = selector.captured;
416
- }
417
- if (selector.origin) {
418
- baseSelector.origin = selector.origin;
419
- }
420
- if (selector.baseSource) {
421
- baseSelector.baseSource = selector.baseSource;
422
- }
423
- if (selector.source) {
424
- baseSelector.source = selector.source;
425
- }
426
- if (!isNullish(selector.isIgnored)) {
427
- baseSelector.isIgnored = selector.isIgnored;
428
- }
429
- if (!isNullish(selector.isUnknown)) {
430
- baseSelector.isUnknown = selector.isUnknown;
431
- }
432
- return baseSelector;
433
- }
434
435
  /**
435
436
  * Returns the selectors matching result for the given dependency.
436
437
  * @param dependency The dependency description.
@@ -438,56 +439,37 @@ var DependenciesMatcher = class extends BaseElementsMatcher {
438
439
  * @param extraTemplateData The extra template data for selector values.
439
440
  * @returns The selectors matching result for the given dependency.
440
441
  */
441
- _getSelectorMatching(dependency, selector, templateData) {
442
- const getFromSelectorMatching = () => {
443
- for (const fromSelectorData of selector.from) {
444
- const fromMatch = this._elementsMatcher.isElementMatch(
445
- dependency.from,
446
- fromSelectorData,
447
- {
448
- extraTemplateData: templateData
449
- }
450
- );
451
- const dependencyPropertiesMatch = this._dependencyFromPropertiesMatch(
442
+ _getSelectorsMatching(dependency, selector, templateData) {
443
+ const getDependencyMetadataSelectorMatching = () => {
444
+ for (const dependencySelectorData of selector.dependency) {
445
+ const dependencyPropertiesMatch = this._dependencyPropertiesMatch(
452
446
  dependency,
453
- [fromSelectorData],
447
+ dependencySelectorData,
454
448
  templateData
455
449
  );
456
- if (fromMatch && dependencyPropertiesMatch) {
457
- return fromSelectorData;
450
+ if (dependencyPropertiesMatch) {
451
+ return dependencySelectorData;
458
452
  }
459
453
  }
460
454
  return null;
461
455
  };
462
- const getToSelectorMatching = () => {
463
- for (const toSelectorData of selector.to) {
464
- const toMatch = isBaseElementSelectorData(toSelectorData) ? this._elementsMatcher.isElementMatch(
465
- dependency.to,
466
- this._convertDependencyElementSelectorDataToBaseElementSelectorData(
467
- toSelectorData
468
- ),
469
- {
470
- extraTemplateData: templateData
471
- }
472
- ) : true;
473
- const dependencyPropertiesMatch = this._dependencyToPropertiesMatch(
474
- dependency,
475
- [toSelectorData],
476
- templateData
477
- );
478
- if (toMatch && dependencyPropertiesMatch) {
479
- return toSelectorData;
480
- }
456
+ const fromSelectorMatching = selector.from ? this._elementsMatcher.getSelectorMatching(
457
+ dependency.from,
458
+ selector.from,
459
+ {
460
+ extraTemplateData: templateData
481
461
  }
482
- return null;
483
- };
484
- const fromSelectorMatching = selector.from ? getFromSelectorMatching() : null;
485
- const toSelectorMatching = selector.to ? getToSelectorMatching() : null;
462
+ ) : null;
463
+ const toSelectorMatching = selector.to ? this._elementsMatcher.getSelectorMatching(dependency.to, selector.to, {
464
+ extraTemplateData: templateData
465
+ }) : null;
466
+ const dependencyMetadataSelectorMatching = selector.dependency ? getDependencyMetadataSelectorMatching() : null;
486
467
  return {
487
468
  from: fromSelectorMatching,
488
469
  to: toSelectorMatching,
470
+ dependency: dependencyMetadataSelectorMatching,
489
471
  isMatch: Boolean(
490
- (selector.from ? fromSelectorMatching : true) && (selector.to ? toSelectorMatching : true)
472
+ (selector.from ? fromSelectorMatching : true) && (selector.to ? toSelectorMatching : true) && (selector.dependency ? dependencyMetadataSelectorMatching : true)
491
473
  )
492
474
  };
493
475
  }
@@ -497,12 +479,29 @@ var DependenciesMatcher = class extends BaseElementsMatcher {
497
479
  * @param selector The data of an element selector.
498
480
  * @returns Whether the dependency relationship matches the selector.
499
481
  */
500
- _relationshipMatches(selector, relationship, templateData) {
501
- if (!selector.relationship) {
482
+ _relationshipFromMatches(selector, relationship, templateData) {
483
+ if (!selector.relationship?.from) {
502
484
  return true;
503
485
  }
504
486
  return this.isTemplateMicromatchMatch(
505
- selector.relationship,
487
+ selector.relationship.from,
488
+ templateData,
489
+ relationship
490
+ );
491
+ }
492
+ /**
493
+ * Determines if the dependency origin relationship matches the selector.
494
+ * @param selector The dependency selector data.
495
+ * @param relationship The relationship from origin element to target element.
496
+ * @param templateData The template data for rendering selector values.
497
+ * @returns Whether the dependency origin relationship matches.
498
+ */
499
+ _relationshipToMatches(selector, relationship, templateData) {
500
+ if (!selector.relationship?.to) {
501
+ return true;
502
+ }
503
+ return this.isTemplateMicromatchMatch(
504
+ selector.relationship.to,
506
505
  templateData,
507
506
  relationship
508
507
  );
@@ -555,75 +554,85 @@ var DependenciesMatcher = class extends BaseElementsMatcher {
555
554
  );
556
555
  }
557
556
  /**
558
- * Determines if the dependency description matches the selector for 'from'.
557
+ * Determines if the dependency description matches the selector for 'to'.
559
558
  * @param dependency The dependency description.
560
- * @param fromSelector The selector for 'from' elements.
559
+ * @param toSelector The selector for 'to' elements.
561
560
  * @param templateData The template data for rendering selector values
562
- * @returns Whether the dependency properties match the selector for 'from'.
563
- */
564
- _dependencyFromPropertiesMatch(dependency, fromSelector, templateData) {
565
- return fromSelector.some(
566
- (selectorData) => this._relationshipMatches(
567
- selectorData,
568
- dependency.dependency.relationship.from,
569
- templateData
570
- )
561
+ * @returns Whether the dependency properties match the selector for 'to'.
562
+ */
563
+ _sourceMatches(selector, source, templateData) {
564
+ if (!selector.source) {
565
+ return true;
566
+ }
567
+ return this.isTemplateMicromatchMatch(
568
+ selector.source,
569
+ templateData,
570
+ source
571
571
  );
572
572
  }
573
573
  /**
574
- * Determines if the dependency description matches the selector for 'to'.
574
+ * Determines if the selector matches the module
575
+ * @param selector The dependency selector data
576
+ * @param module The module to check
577
+ * @param templateData The template data for rendering selector values
578
+ * @returns Whether the selector matches the module
579
+ */
580
+ _moduleMatches(selector, dependencyModule, templateData) {
581
+ if (!selector.module) {
582
+ return true;
583
+ }
584
+ return this.isTemplateMicromatchMatch(
585
+ selector.module,
586
+ templateData,
587
+ dependencyModule
588
+ );
589
+ }
590
+ /**
591
+ * Determines if the dependency description matches the selector for dependency metadata.
575
592
  * @param dependency The dependency description.
576
- * @param toSelector The selector for 'to' elements.
593
+ * @param selectorData The selector for dependency metadata.
577
594
  * @param templateData The template data for rendering selector values
578
- * @returns Whether the dependency properties match the selector for 'to'.
595
+ * @returns Whether the dependency properties match the selector.
579
596
  */
580
- _dependencyToPropertiesMatch(dependency, toSelector, templateData) {
597
+ _dependencyPropertiesMatch(dependency, selectorData, templateData) {
581
598
  const dependencyInfo = dependency.dependency;
599
+ const relationshipFrom = dependencyInfo.relationship.from;
582
600
  const relationshipTo = dependencyInfo.relationship.to;
583
601
  const kind = dependencyInfo.kind;
584
602
  const nodeKind = dependencyInfo.nodeKind;
585
603
  const specifiers = dependencyInfo.specifiers;
586
- for (const selectorData of toSelector) {
587
- if (this._kindMatches(selectorData, kind, templateData) && this._nodeKindMatches(selectorData, nodeKind, templateData) && this._relationshipMatches(selectorData, relationshipTo, templateData) && this._specifierMatches(selectorData, specifiers, templateData)) {
588
- return true;
589
- }
590
- }
591
- return false;
604
+ const source = dependencyInfo.source;
605
+ const dependencyModule = dependencyInfo.module;
606
+ return this._kindMatches(selectorData, kind, templateData) && this._nodeKindMatches(selectorData, nodeKind, templateData) && this._sourceMatches(selectorData, source, templateData) && this._moduleMatches(selectorData, dependencyModule, templateData) && this._relationshipFromMatches(
607
+ selectorData,
608
+ relationshipFrom,
609
+ templateData
610
+ ) && this._relationshipToMatches(selectorData, relationshipTo, templateData) && this._specifierMatches(selectorData, specifiers, templateData);
592
611
  }
593
612
  /**
594
613
  * Returns the selectors matching result for the given dependency.
595
614
  * @param dependency The dependency to check.
596
615
  * @param selector The selector to check against.
597
- * @param options Extra options for matching, such as templates data, globals for dependency selectors, etc.
616
+ * @param options Extra options for matching, such as templates data, etc.
598
617
  * @returns The matching result for the dependency against the selector.
599
618
  */
600
- getSelectorsMatching(dependency, selector, {
601
- extraTemplateData = {},
602
- dependencySelectorsGlobals = {}
603
- } = {}) {
604
- const normalizedSelector = this._normalizeDependencySelector(
605
- selector,
606
- dependencySelectorsGlobals
607
- );
619
+ getSelectorsMatching(dependency, selector, { extraTemplateData = {} } = {}) {
620
+ const normalizedSelector = this._normalizeDependencySelector(selector);
608
621
  const fromExtraData = extraTemplateData.from || {};
609
622
  const toExtraData = extraTemplateData.to || {};
610
623
  const templateData = {
611
624
  ...extraTemplateData,
612
625
  from: {
613
626
  ...dependency.from,
614
- relationship: dependency.dependency.relationship.from,
615
627
  ...fromExtraData
616
628
  },
617
629
  to: {
618
630
  ...dependency.to,
619
- relationship: dependency.dependency.relationship.to,
620
- kind: dependency.dependency.kind,
621
- nodeKind: dependency.dependency.nodeKind,
622
- specifiers: dependency.dependency.specifiers,
623
631
  ...toExtraData
624
- }
632
+ },
633
+ dependency: dependency.dependency
625
634
  };
626
- const result = this._getSelectorMatching(
635
+ const result = this._getSelectorsMatching(
627
636
  dependency,
628
637
  normalizedSelector,
629
638
  templateData
@@ -634,7 +643,7 @@ var DependenciesMatcher = class extends BaseElementsMatcher {
634
643
  * Returns whether the given dependency matches the selector.
635
644
  * @param dependency The dependency to check.
636
645
  * @param selector The selector to check against.
637
- * @param options Extra options for matching, such as templates data, globals for dependency selectors, etc.
646
+ * @param options Extra options for matching, such as templates data, etc.
638
647
  * @returns Whether the dependency matches the selector properties.
639
648
  */
640
649
  isDependencyMatch(dependency, selector, options) {
@@ -649,8 +658,6 @@ var DependenciesMatcher = class extends BaseElementsMatcher {
649
658
 
650
659
  // src/Matcher/ElementsMatcher.ts
651
660
  var ElementsMatcher = class extends BaseElementsMatcher {
652
- /** Whether the cache is enabled or not */
653
- _cacheIsEnabled;
654
661
  /**
655
662
  * Creates a new ElementsSelectorMatcher.
656
663
  * @param config Configuration options for the matcher.
@@ -763,41 +770,36 @@ var ElementsMatcher = class extends BaseElementsMatcher {
763
770
  });
764
771
  }
765
772
  /**
766
- * Whether the given element baseSource matches the selector baseSource
767
- * @param element The element to check.
768
- * @param selector The selector to check against.
769
- * @param templateData The data to use for replace in selector value
770
- * @returns Whether the element baseSource matches the selector baseSource.
771
- */
772
- _isBaseSourceMatch(element, selector, templateData) {
773
- return this.isElementKeyMicromatchMatch({
774
- element,
775
- selector,
776
- elementKey: "baseSource",
777
- selectorKey: "baseSource",
778
- selectorValue: selector.baseSource,
779
- templateData
780
- });
781
- }
782
- /**
783
- * Whether the given element source matches the selector source
784
- * @param element The element to check.
785
- * @param selector The selector to check against.
786
- * @param templateData The data to use for replace in selector value
787
- * @returns Whether the element source matches the selector source.
773
+ * Checks if a single captured values object matches the element.
774
+ * @param capturedValues The captured values to check.
775
+ * @param capturedSelector The captured values selector object to check against
776
+ * @param templateData The data to use for replace in selector values
777
+ * @returns True if all captured values in the selector match those in the element, false otherwise.
788
778
  */
789
- _isSourceMatch(element, selector, templateData) {
790
- return this.isElementKeyMicromatchMatch({
791
- element,
792
- selector,
793
- elementKey: "source",
794
- selectorKey: "source",
795
- selectorValue: selector.source,
796
- templateData
797
- });
779
+ _checkCapturedValuesObject(capturedValues, capturedSelector, templateData) {
780
+ if (!capturedValues) {
781
+ return false;
782
+ }
783
+ for (const [key, pattern] of Object.entries(capturedSelector)) {
784
+ const elementValue = capturedValues[key];
785
+ if (!elementValue) {
786
+ return false;
787
+ }
788
+ const renderedPattern = this.getRenderedTemplates(pattern, templateData);
789
+ const filteredPattern = this.cleanMicromatchPattern(renderedPattern);
790
+ if (!filteredPattern) {
791
+ return false;
792
+ }
793
+ const isMatch = this.micromatch.isMatch(elementValue, filteredPattern);
794
+ if (!isMatch) {
795
+ return false;
796
+ }
797
+ }
798
+ return true;
798
799
  }
799
800
  /**
800
801
  * Determines if the captured values of the element match those in the selector.
802
+ * When the selector is an array, the element matches if it matches any of the array elements (OR logic).
801
803
  * @param element The element to check.
802
804
  * @param selector The selector to check against
803
805
  * @param templateData The data to use for replace in selector values
@@ -807,23 +809,98 @@ var ElementsMatcher = class extends BaseElementsMatcher {
807
809
  if (!selector.captured || isEmptyObject(selector.captured)) {
808
810
  return true;
809
811
  }
810
- if (!element.captured) {
811
- return false;
812
- }
813
- for (const [key, pattern] of Object.entries(selector.captured)) {
814
- const elementValue = element.captured?.[key];
815
- if (!elementValue) {
812
+ if (isArray(selector.captured)) {
813
+ if (selector.captured.length === 0) {
816
814
  return false;
817
815
  }
818
- const renderedPattern = this.getRenderedTemplates(pattern, templateData);
819
- if (!renderedPattern) {
820
- return false;
821
- }
822
- const filteredPattern = isArray(renderedPattern) ? renderedPattern.filter(Boolean) : renderedPattern;
823
- const isMatch = this.micromatch.isMatch(elementValue, filteredPattern);
824
- if (!isMatch) {
816
+ return selector.captured.some(
817
+ (capturedSelector) => this._checkCapturedValuesObject(
818
+ element.captured,
819
+ capturedSelector,
820
+ templateData
821
+ )
822
+ );
823
+ }
824
+ return this._checkCapturedValuesObject(
825
+ element.captured,
826
+ selector.captured,
827
+ templateData
828
+ );
829
+ }
830
+ /**
831
+ * Determines if the parent captured values match the selector.
832
+ * @param parentSelector The parent selector to match.
833
+ * @param parentCaptured The captured values from first parent.
834
+ * @param templateData The data to use for replace in selector values
835
+ * @returns True if the captured values match, false otherwise.
836
+ */
837
+ _isParentCapturedValuesMatch(parentSelector, parentCaptured, templateData) {
838
+ if (!parentSelector.captured || isEmptyObject(parentSelector.captured)) {
839
+ return true;
840
+ }
841
+ if (isArray(parentSelector.captured)) {
842
+ if (parentSelector.captured.length === 0) {
825
843
  return false;
826
844
  }
845
+ return parentSelector.captured.some(
846
+ (capturedSelector) => this._checkCapturedValuesObject(
847
+ parentCaptured,
848
+ capturedSelector,
849
+ templateData
850
+ )
851
+ );
852
+ }
853
+ return this._checkCapturedValuesObject(
854
+ parentCaptured,
855
+ parentSelector.captured,
856
+ templateData
857
+ );
858
+ }
859
+ /**
860
+ * Whether the given element first parent matches the selector parent.
861
+ * @param element The element to check.
862
+ * @param selector The selector to check against.
863
+ * @param templateData The data to use for replace in selector values
864
+ * @returns Whether the first parent matches the selector parent.
865
+ */
866
+ _isParentMatch(element, selector, templateData) {
867
+ if (isUndefined(selector.parent)) {
868
+ return true;
869
+ }
870
+ if (isNull(selector.parent)) {
871
+ return !element.parents || element.parents.length === 0;
872
+ }
873
+ const firstParent = element.parents?.[0];
874
+ if (!firstParent) {
875
+ return false;
876
+ }
877
+ if (!isUndefined(selector.parent.type) && !this.isTemplateMicromatchMatch(
878
+ selector.parent.type,
879
+ templateData,
880
+ firstParent.type
881
+ )) {
882
+ return false;
883
+ }
884
+ if (!isUndefined(selector.parent.category) && !this.isTemplateMicromatchMatch(
885
+ selector.parent.category,
886
+ templateData,
887
+ firstParent.category
888
+ )) {
889
+ return false;
890
+ }
891
+ if (!isUndefined(selector.parent.elementPath) && !this.isTemplateMicromatchMatch(
892
+ selector.parent.elementPath,
893
+ templateData,
894
+ firstParent.elementPath
895
+ )) {
896
+ return false;
897
+ }
898
+ if (!this._isParentCapturedValuesMatch(
899
+ selector.parent,
900
+ firstParent.captured,
901
+ templateData
902
+ )) {
903
+ return false;
827
904
  }
828
905
  return true;
829
906
  }
@@ -868,7 +945,7 @@ var ElementsMatcher = class extends BaseElementsMatcher {
868
945
  ...extraTemplateData
869
946
  };
870
947
  for (const selectorData of selectorsData) {
871
- if (!this._isTypeMatch(element, selectorData, templateData) || !this._isCategoryMatch(element, selectorData, templateData) || !this._isOriginMatch(element, selectorData, templateData) || !this._isIgnoredMatch(element, selectorData) || !this._isUnknownMatch(element, selectorData) || !this._isPathMatch(element, selectorData, templateData) || !this._isElementPathMatch(element, selectorData, templateData) || !this._isInternalPathMatch(element, selectorData, templateData) || !this._isSourceMatch(element, selectorData, templateData) || !this._isBaseSourceMatch(element, selectorData, templateData) || !this._isCapturedValuesMatch(element, selectorData, templateData)) {
948
+ if (!this._isTypeMatch(element, selectorData, templateData) || !this._isCategoryMatch(element, selectorData, templateData) || !this._isOriginMatch(element, selectorData, templateData) || !this._isIgnoredMatch(element, selectorData) || !this._isUnknownMatch(element, selectorData) || !this._isPathMatch(element, selectorData, templateData) || !this._isElementPathMatch(element, selectorData, templateData) || !this._isInternalPathMatch(element, selectorData, templateData) || !this._isCapturedValuesMatch(element, selectorData, templateData) || !this._isParentMatch(element, selectorData, templateData)) {
872
949
  continue;
873
950
  }
874
951
  return selectorData;
@@ -880,7 +957,7 @@ var ElementsMatcher = class extends BaseElementsMatcher {
880
957
  * It omits checks in keys applying only to dependency between elements, such as relationship.
881
958
  * @param element The element to check.
882
959
  * @param selector The selector to check against.
883
- * @param options Extra options for matching, such as templates data, globals for dependency selectors, etc.
960
+ * @param options Extra options for matching, such as templates data, etc.
884
961
  * @returns The selector matching result for the given element, or null if none matches.
885
962
  */
886
963
  getSelectorMatching(element, selector, { extraTemplateData = {} } = {}) {
@@ -892,7 +969,7 @@ var ElementsMatcher = class extends BaseElementsMatcher {
892
969
  * It omits checks in keys applying only to dependency between elements, such as relationship.
893
970
  * @param element The element to check.
894
971
  * @param selector The selector to check against.
895
- * @param options Extra options for matching, such as templates data, globals for dependency selectors, etc.
972
+ * @param options Extra options for matching, such as templates data, etc.
896
973
  * @returns Whether the element matches the selector properties applying to elements.
897
974
  */
898
975
  isElementMatch(element, selector, options) {
@@ -959,20 +1036,17 @@ function isUnknownLocalElement(value) {
959
1036
  function isKnownLocalElement(value) {
960
1037
  return isLocalElement(value) && value.isUnknown === false;
961
1038
  }
962
- function isDependencyElementDescription(value) {
963
- return isBaseElement(value) && isObjectWithProperty(value, "source") && isString(value.source);
964
- }
965
- function isElementDescription(value) {
966
- return isIgnoredElement(value) || isUnknownLocalElement(value) || isKnownLocalElement(value) || isDependencyElementDescription(value);
967
- }
968
1039
  function isLocalDependencyElement(value) {
969
- return isDependencyElementDescription(value) && isLocalElement(value);
1040
+ return isLocalElement(value) && value.isIgnored === false;
970
1041
  }
971
1042
  function isExternalDependencyElement(value) {
972
- return isDependencyElementDescription(value) && value.origin === ELEMENT_ORIGINS_MAP.EXTERNAL && isObjectWithProperty(value, "baseSource") && isString(value.baseSource);
1043
+ return isBaseElement(value) && value.origin === ELEMENT_ORIGINS_MAP.EXTERNAL;
973
1044
  }
974
1045
  function isCoreDependencyElement(value) {
975
- return isDependencyElementDescription(value) && value.origin === ELEMENT_ORIGINS_MAP.CORE && isObjectWithProperty(value, "baseSource") && isString(value.baseSource);
1046
+ return isBaseElement(value) && value.origin === ELEMENT_ORIGINS_MAP.CORE;
1047
+ }
1048
+ function isElementDescription(value) {
1049
+ return isIgnoredElement(value) || isUnknownLocalElement(value) || isKnownLocalElement(value) || isExternalDependencyElement(value) || isCoreDependencyElement(value);
976
1050
  }
977
1051
 
978
1052
  // src/Descriptor/DependenciesDescriptor.types.ts
@@ -1029,7 +1103,7 @@ function isDependencyRelationshipDescription(value) {
1029
1103
  return isObjectWithProperty(value, "to") && (isNull(value.to) || isDependencyRelationship(value.to)) && isObjectWithProperty(value, "from") && (isNull(value.from) || isDependencyRelationship(value.from));
1030
1104
  }
1031
1105
  function isElementsDependencyInfo(value) {
1032
- return isObjectWithProperty(value, "kind") && isDependencyKind(value.kind) && isObjectWithProperty(value, "relationship") && isDependencyRelationshipDescription(value.relationship) && isObjectWithProperty(value, "nodeKind") && (isNull(value.nodeKind) || isString(value.nodeKind));
1106
+ return isObjectWithProperty(value, "source") && isString(value.source) && isObjectWithProperty(value, "module") && (isNullish(value.module) || isString(value.module)) && isObjectWithProperty(value, "kind") && isDependencyKind(value.kind) && isObjectWithProperty(value, "relationship") && isDependencyRelationshipDescription(value.relationship) && isObjectWithProperty(value, "nodeKind") && (isNull(value.nodeKind) || isString(value.nodeKind)) && isObjectWithProperty(value, "specifiers") && (isNull(value.specifiers) || isStringArray(value.specifiers));
1033
1107
  }
1034
1108
  function isDependencyDescription(value) {
1035
1109
  return isObjectWithProperty(value, "to") && isElementDescription(value.to) && isObjectWithProperty(value, "from") && isElementDescription(value.from) && isObjectWithProperty(value, "dependency") && isElementsDependencyInfo(value.dependency);
@@ -1367,17 +1441,20 @@ var DependenciesDescriptor = class {
1367
1441
  return this._dependenciesCache.get(cacheKey);
1368
1442
  }
1369
1443
  const fromElement = this._elementsDescriptor.describeElement(from);
1370
- const toElement = this._elementsDescriptor.describeDependencyElement(
1371
- source,
1372
- to
1373
- );
1444
+ const toElement = this._elementsDescriptor.describeElement(to, source);
1445
+ const { module: dependencyModule, ...toElementDescription } = toElement;
1374
1446
  const result = {
1375
1447
  from: fromElement,
1376
- to: toElement,
1448
+ to: toElementDescription,
1377
1449
  dependency: {
1450
+ source,
1451
+ module: dependencyModule || null,
1378
1452
  kind,
1379
1453
  nodeKind: nodeKind || null,
1380
- relationship: this._dependencyRelationships(fromElement, toElement),
1454
+ relationship: this._dependencyRelationships(
1455
+ fromElement,
1456
+ toElementDescription
1457
+ ),
1381
1458
  specifiers: specifiers || null
1382
1459
  }
1383
1460
  };
@@ -1392,8 +1469,6 @@ var UNKNOWN_ELEMENT = {
1392
1469
  path: null,
1393
1470
  elementPath: null,
1394
1471
  internalPath: null,
1395
- source: null,
1396
- baseSource: null,
1397
1472
  parents: null,
1398
1473
  type: null,
1399
1474
  category: null,
@@ -1495,8 +1570,8 @@ var ElementsDescriptor = class {
1495
1570
  */
1496
1571
  _dependencySourceIsCoreModule(dependencySource, baseDependencySource) {
1497
1572
  if (this._mod) {
1498
- const baseSourceWithoutPrefix = baseDependencySource.startsWith("node:") ? baseDependencySource.slice(5) : baseDependencySource;
1499
- return this._mod.builtinModules.includes(baseSourceWithoutPrefix);
1573
+ const moduleWithoutPrefix = baseDependencySource.startsWith("node:") ? baseDependencySource.slice(5) : baseDependencySource;
1574
+ return this._mod.builtinModules.includes(moduleWithoutPrefix);
1500
1575
  }
1501
1576
  return isCoreModule(dependencySource);
1502
1577
  }
@@ -1521,7 +1596,7 @@ var ElementsDescriptor = class {
1521
1596
  * @param dependencySource The source of the dependency to check.
1522
1597
  * @returns The base source of the external module. (e.g., for "@scope/package/submodule", it returns "@scope/package")
1523
1598
  */
1524
- _getExternalOrCoreModuleBaseSource(dependencySource) {
1599
+ _getExternalOrCoreModuleModule(dependencySource) {
1525
1600
  if (this._dependencySourceIsScoped(dependencySource)) {
1526
1601
  const [scope, packageName] = dependencySource.split("/");
1527
1602
  return `${scope}/${packageName}`;
@@ -1530,17 +1605,72 @@ var ElementsDescriptor = class {
1530
1605
  return pkg;
1531
1606
  }
1532
1607
  /**
1533
- * Determines if an element is external based on its file path and dependency source.
1534
- * Files inside "node_modules" are considered external.
1535
- * If the dependency source is not provided, only the file path is considered.
1536
- * If the dependency source is provided, it must not be a local path (i.e, it should start by "./", "../", or "/").
1537
- * @param filePath
1538
- * @param dependencySource
1539
- * @returns
1608
+ * Determines if a file path is outside the configured root path.
1609
+ * @param filePath The file path to check.
1610
+ * @returns True if the file path is outside the root path, false otherwise.
1611
+ */
1612
+ _isOutsideRootPath(filePath) {
1613
+ if (!this._config.rootPath) {
1614
+ return false;
1615
+ }
1616
+ return !filePath.startsWith(this._config.rootPath);
1617
+ }
1618
+ /**
1619
+ * Converts an absolute file path to a relative path if rootPath is configured.
1620
+ * If rootPath is not configured, returns the path as-is (maintains backward compatibility).
1621
+ * @param filePath The file path to convert (can be absolute or relative)
1622
+ * @returns The relative path if rootPath is configured and path is absolute, otherwise the original path
1540
1623
  */
1541
- _isExternalDependency(filePath, dependencySource) {
1542
- 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?
1543
- (!dependencySource || this._dependencySourceIsExternalOrScoped(dependencySource));
1624
+ _toRelativePath(filePath) {
1625
+ if (!this._config.rootPath || this._isOutsideRootPath(filePath)) {
1626
+ return filePath;
1627
+ }
1628
+ return filePath.replace(this._config.rootPath, "");
1629
+ }
1630
+ /**
1631
+ * Checks if a source string matches any of the provided patterns using micromatch.
1632
+ * @param patterns - Array of micromatch patterns
1633
+ * @param source - The source string to match against patterns
1634
+ * @returns True if the source matches any pattern, false otherwise
1635
+ */
1636
+ _matchesAnyPattern(patterns, source) {
1637
+ if (!source || patterns.length === 0) {
1638
+ return false;
1639
+ }
1640
+ return this._micromatch.isMatch(source, patterns);
1641
+ }
1642
+ /**
1643
+ * Determines if an element is external based on its file path and dependency source.
1644
+ * Uses the flagAsExternal configuration to evaluate multiple conditions with OR logic:
1645
+ * - unresolvableAlias: Files whose path cannot be resolved (filePath is null)
1646
+ * - inNodeModules: Non-relative paths that include "node_modules"
1647
+ * - outsideRootPath: Resolved path is outside the configured root path (only if rootPath is configured)
1648
+ * - customSourcePatterns: Source matches any of the configured patterns
1649
+ * @param filePath The resolved file path (null if unresolved). Can be absolute if rootPath is configured, or relative if rootPath is not configured.
1650
+ * @param isOutsideRootPath Whether the file path is outside the configured root path.
1651
+ * @param dependencySource The import/export source string
1652
+ * @returns True if any of the configured conditions is met, false otherwise
1653
+ */
1654
+ _isExternalDependency(filePath, isOutsideRootPath, dependencySource) {
1655
+ const {
1656
+ unresolvableAlias,
1657
+ inNodeModules,
1658
+ outsideRootPath,
1659
+ customSourcePatterns
1660
+ } = this._config.flagAsExternal;
1661
+ if (outsideRootPath && isOutsideRootPath) {
1662
+ return true;
1663
+ }
1664
+ if (inNodeModules && filePath?.includes("node_modules")) {
1665
+ return true;
1666
+ }
1667
+ if (unresolvableAlias && !filePath && dependencySource && this._dependencySourceIsExternalOrScoped(dependencySource)) {
1668
+ return true;
1669
+ }
1670
+ if (this._matchesAnyPattern(customSourcePatterns, dependencySource)) {
1671
+ return true;
1672
+ }
1673
+ return false;
1544
1674
  }
1545
1675
  /**
1546
1676
  * Determines if a given path is included based on the configuration.
@@ -1608,6 +1738,16 @@ var ElementsDescriptor = class {
1608
1738
  }
1609
1739
  return `${[...allPathSegments].reverse().join("/").split(result)[0]}${result}`;
1610
1740
  }
1741
+ /**
1742
+ * Determines if an element descriptor matches the given parameters in the provided path.
1743
+ * @param options The options for matching the descriptor.
1744
+ * @param options.elementDescriptor The element descriptor to match.
1745
+ * @param options.filePath The file path to match against the descriptor.
1746
+ * @param options.currentPathSegments The current path segments leading to the element.
1747
+ * @param options.lastPathSegmentMatching The last path segment that was matched.
1748
+ * @param options.alreadyMatched Whether the element matched previously.
1749
+ * @returns The result of the match, including whether it matched.
1750
+ */
1611
1751
  _fileDescriptorMatch({
1612
1752
  elementDescriptor,
1613
1753
  filePath,
@@ -1762,11 +1902,12 @@ var ElementsDescriptor = class {
1762
1902
  /**
1763
1903
  * Returns an external or core dependency element given its dependency source and file path.
1764
1904
  * @param dependencySource The source of the dependency.
1765
- * @param filePath The resolved file path of the dependency, if known.
1905
+ * @param isOutsideRootPath Whether the file path is outside the configured root path.
1906
+ * @param filePath The resolved file path of the dependency, if known. Can be absolute if rootPath is configured.
1766
1907
  * @returns The external or core dependency element, or null if it is a local dependency.
1767
1908
  */
1768
- _getExternalOrCoreDependencyElement(dependencySource, filePath) {
1769
- const baseDependencySource = this._getExternalOrCoreModuleBaseSource(dependencySource);
1909
+ _getExternalOrCoreDependencyElement(dependencySource, isOutsideRootPath, filePath) {
1910
+ const baseDependencySource = this._getExternalOrCoreModuleModule(dependencySource);
1770
1911
  const isCore = this._dependencySourceIsCoreModule(
1771
1912
  dependencySource,
1772
1913
  baseDependencySource
@@ -1774,23 +1915,22 @@ var ElementsDescriptor = class {
1774
1915
  if (isCore) {
1775
1916
  const coreElement = {
1776
1917
  ...UNKNOWN_ELEMENT,
1777
- source: dependencySource,
1778
- baseSource: baseDependencySource,
1918
+ module: baseDependencySource,
1779
1919
  origin: ELEMENT_ORIGINS_MAP.CORE
1780
1920
  };
1781
1921
  return coreElement;
1782
1922
  }
1783
1923
  const isExternal = this._isExternalDependency(
1784
1924
  filePath || null,
1925
+ isOutsideRootPath,
1785
1926
  dependencySource
1786
1927
  );
1787
1928
  if (isExternal) {
1788
1929
  const externalElement = {
1789
1930
  ...UNKNOWN_ELEMENT,
1790
1931
  path: filePath || null,
1791
- internalPath: dependencySource.replace(baseDependencySource, ""),
1792
- source: dependencySource,
1793
- baseSource: baseDependencySource,
1932
+ internalPath: dependencySource.replace(baseDependencySource, "") || null,
1933
+ module: baseDependencySource,
1794
1934
  origin: ELEMENT_ORIGINS_MAP.EXTERNAL
1795
1935
  };
1796
1936
  return externalElement;
@@ -1802,34 +1942,23 @@ var ElementsDescriptor = class {
1802
1942
  if (this._descriptionsCache.has(cacheKey)) {
1803
1943
  return this._descriptionsCache.get(cacheKey);
1804
1944
  }
1805
- const externalOrCoreDependencyElement = dependencySource ? this._getExternalOrCoreDependencyElement(dependencySource, filePath) : null;
1945
+ const normalizedFilePath = filePath ? normalizePath(filePath) : filePath;
1946
+ const isOutsideRootPath = normalizedFilePath ? this._isOutsideRootPath(normalizedFilePath) : false;
1947
+ const relativePath = normalizedFilePath && this._config.rootPath ? this._toRelativePath(normalizedFilePath) : normalizedFilePath;
1948
+ const externalOrCoreDependencyElement = dependencySource ? this._getExternalOrCoreDependencyElement(
1949
+ dependencySource,
1950
+ isOutsideRootPath,
1951
+ relativePath
1952
+ ) : null;
1806
1953
  if (externalOrCoreDependencyElement) {
1807
1954
  this._descriptionsCache.set(cacheKey, externalOrCoreDependencyElement);
1808
1955
  return externalOrCoreDependencyElement;
1809
1956
  }
1810
- const fileDescription = this._describeFile(filePath);
1811
- const elementResult = dependencySource ? {
1812
- ...fileDescription,
1813
- source: dependencySource
1814
- } : fileDescription;
1815
- this._descriptionsCache.set(cacheKey, elementResult);
1816
- return elementResult;
1957
+ const fileDescription = this._describeFile(relativePath);
1958
+ this._descriptionsCache.set(cacheKey, fileDescription);
1959
+ return fileDescription;
1817
1960
  }
1818
- /**
1819
- * Describes an element given its file path.
1820
- * @param filePath The path of the file to describe.
1821
- * @returns The description of the element.
1822
- */
1823
- describeElement(filePath) {
1824
- return this._describeElement(filePath);
1825
- }
1826
- /**
1827
- * Describes a dependency element given its dependency source and file path.
1828
- * @param dependencySource The source of the dependency.
1829
- * @param filePath The path of the file being the dependency, if known.
1830
- * @returns The description of the dependency element.
1831
- */
1832
- describeDependencyElement(dependencySource, filePath) {
1961
+ describeElement(filePath, dependencySource) {
1833
1962
  return this._describeElement(filePath, dependencySource);
1834
1963
  }
1835
1964
  };
@@ -1889,18 +2018,6 @@ var Descriptors = class {
1889
2018
  describeElement(filePath) {
1890
2019
  return this._elementsDescriptor.describeElement(filePath);
1891
2020
  }
1892
- /**
1893
- * Describes a dependency element given its dependency source and file path.
1894
- * @param dependencySource The source of the dependency.
1895
- * @param filePath The path of the file being the dependency, if known.
1896
- * @returns The description of the dependency element.
1897
- */
1898
- describeDependencyElement(dependencySource, filePath) {
1899
- return this._elementsDescriptor.describeDependencyElement(
1900
- dependencySource,
1901
- filePath
1902
- );
1903
- }
1904
2021
  /**
1905
2022
  * Describes elements in a dependency relationship, and provides additional information about the dependency itself.
1906
2023
  * @param options The options for describing the elements and the dependency details.
@@ -1929,6 +2046,22 @@ var Matcher = class {
1929
2046
  this._elementsMatcher = elementsMatcher;
1930
2047
  this._dependenciesMatcher = dependenciesMatcher;
1931
2048
  }
2049
+ /**
2050
+ * Describes an element given its file path.
2051
+ * @param filePath The path of the file to describe.
2052
+ * @returns The description of the element.
2053
+ */
2054
+ describeElement(filePath) {
2055
+ return this._descriptors.describeElement(filePath);
2056
+ }
2057
+ /**
2058
+ * Describes elements in a dependency relationship, and provides additional information about the dependency itself.
2059
+ * @param options The options for describing the elements and the dependency details.
2060
+ * @returns The description of the dependency between the elements.
2061
+ */
2062
+ describeDependency(options) {
2063
+ return this._descriptors.describeDependency(options);
2064
+ }
1932
2065
  /**
1933
2066
  * Determines if an element matches a given selector.
1934
2067
  * @param filePath The file path of the element
@@ -1936,7 +2069,7 @@ var Matcher = class {
1936
2069
  * @param options Extra matcher options
1937
2070
  * @returns True if the element matches the selector, false otherwise
1938
2071
  */
1939
- _isElementMatch(filePath, selector, options) {
2072
+ isElementMatch(filePath, selector, options) {
1940
2073
  const description = this._descriptors.describeElement(filePath);
1941
2074
  return this._elementsMatcher.isElementMatch(description, selector, options);
1942
2075
  }
@@ -1947,7 +2080,7 @@ var Matcher = class {
1947
2080
  * @param options Extra matcher options
1948
2081
  * @returns True if the dependency matches the selector, false otherwise
1949
2082
  */
1950
- _isDependencyMatch(dependencyData, selector, options) {
2083
+ isDependencyMatch(dependencyData, selector, options) {
1951
2084
  const description = this._descriptors.describeDependency(dependencyData);
1952
2085
  return this._dependenciesMatcher.isDependencyMatch(
1953
2086
  description,
@@ -1955,20 +2088,6 @@ var Matcher = class {
1955
2088
  options
1956
2089
  );
1957
2090
  }
1958
- isMatch(descriptorOptions, selector, options) {
1959
- if (isString(descriptorOptions)) {
1960
- return this._isElementMatch(
1961
- descriptorOptions,
1962
- selector,
1963
- options
1964
- );
1965
- }
1966
- return this._isDependencyMatch(
1967
- descriptorOptions,
1968
- selector,
1969
- options
1970
- );
1971
- }
1972
2091
  /**
1973
2092
  * Determines the selector matching for an element.
1974
2093
  * @param filePath The file path of the element
@@ -1976,7 +2095,7 @@ var Matcher = class {
1976
2095
  * @param options Extra options for matching
1977
2096
  * @returns The matching selector data or null if no match is found
1978
2097
  */
1979
- _getElementSelectorMatching(filePath, selector, options) {
2098
+ getElementSelectorMatching(filePath, selector, options) {
1980
2099
  const description = this._descriptors.describeElement(filePath);
1981
2100
  return this._elementsMatcher.getSelectorMatching(
1982
2101
  description,
@@ -1991,7 +2110,7 @@ var Matcher = class {
1991
2110
  * @param options Extra options for matching
1992
2111
  * @returns The matching dependency result or null if no match is found
1993
2112
  */
1994
- _getDependencySelectorMatching(dependencyData, selector, options) {
2113
+ getDependencySelectorMatching(dependencyData, selector, options) {
1995
2114
  const description = this._descriptors.describeDependency(dependencyData);
1996
2115
  return this._dependenciesMatcher.getSelectorsMatching(
1997
2116
  description,
@@ -1999,66 +2118,44 @@ var Matcher = class {
1999
2118
  options
2000
2119
  );
2001
2120
  }
2002
- getSelectorMatching(descriptorOptions, selector, options) {
2003
- if (isString(descriptorOptions)) {
2004
- return this._getElementSelectorMatching(
2005
- descriptorOptions,
2121
+ /**
2122
+ * Returns the selectors matching result for the given element or dependency description.
2123
+ * @param description The element or dependency description to check.
2124
+ * @param selector The selector to check against.
2125
+ * @param options Extra options for matching, such as templates data, etc.
2126
+ * @returns The selectors matching result for the given description, and whether it matches or not.
2127
+ */
2128
+ getDependencySelectorMatchingDescription(description, selector, options) {
2129
+ if (isDependencySelector(selector) && isDependencyDescription(description)) {
2130
+ return this._dependenciesMatcher.getSelectorsMatching(
2131
+ description,
2006
2132
  selector,
2007
2133
  options
2008
2134
  );
2009
2135
  }
2010
- return this._getDependencySelectorMatching(
2011
- descriptorOptions,
2012
- selector,
2013
- options
2136
+ throw new Error(
2137
+ "Invalid arguments: Please provide a valid description and selector"
2014
2138
  );
2015
2139
  }
2016
- getSelectorMatchingDescription(description, selector, options) {
2140
+ /**
2141
+ * Returns the first element selector matching result for the given element description.
2142
+ * @param description The element description to check.
2143
+ * @param selector The selector to check against.
2144
+ * @param options Extra options for matching, such as templates data, etc.
2145
+ * @returns The first matching selector result for the given description, or null if no match is found.
2146
+ */
2147
+ getElementSelectorMatchingDescription(description, selector, options) {
2017
2148
  if (isElementsSelector(selector) && isElementDescription(description)) {
2018
2149
  return this._elementsMatcher.getSelectorMatching(
2019
2150
  description,
2020
2151
  selector,
2021
2152
  options
2022
2153
  );
2023
- } else if (isDependencySelector(selector) && isDependencyDescription(description)) {
2024
- return this._dependenciesMatcher.getSelectorsMatching(
2025
- description,
2026
- selector,
2027
- options
2028
- );
2029
2154
  }
2030
2155
  throw new Error(
2031
2156
  "Invalid arguments: Please provide a valid description and selector"
2032
2157
  );
2033
2158
  }
2034
- /**
2035
- * Describes an element given its file path.
2036
- * @param filePath The path of the file to describe.
2037
- * @returns The description of the element.
2038
- */
2039
- describeElement(filePath) {
2040
- return this._descriptors.describeElement(filePath);
2041
- }
2042
- /**
2043
- * Describes a dependency element given its dependency source and file path.
2044
- * @param dependencySource The source of the dependency.
2045
- * @param filePath The path of the file being the dependency, if known.
2046
- * @returns The description of the dependency element.
2047
- */
2048
- describeDependencyElement(dependencySource, filePath) {
2049
- return this._descriptors.describeDependencyElement(
2050
- dependencySource,
2051
- filePath
2052
- );
2053
- }
2054
- /**
2055
- * Describes elements in a dependency relationship, and provides additional information about the dependency itself.
2056
- * @param options The options for describing the elements and the dependency details.
2057
- * @returns The description of the dependency between the elements.
2058
- */
2059
- describeDependency(options) {
2060
- return this._descriptors.describeDependency(options);
2061
- }
2062
2159
  /**
2063
2160
  * Clears all caches.
2064
2161
  */
@@ -2214,7 +2311,7 @@ var MatchersCache = class extends CacheManager {
2214
2311
  config,
2215
2312
  elementDescriptors
2216
2313
  }) {
2217
- const configHash = `${config.legacyTemplates}|${config.includePaths}|${config.ignorePaths}|${config.cache}`;
2314
+ 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(",")}`;
2218
2315
  const elementDescriptorsHash = elementDescriptors.map(
2219
2316
  (descriptor) => `${descriptor.type}|${descriptor.category}|${descriptor.pattern}|${descriptor.basePattern}|${descriptor.mode}|${descriptor.capture}|${descriptor.baseCapture}`
2220
2317
  ).join(",");
@@ -2354,8 +2451,9 @@ export {
2354
2451
  isBaseElementSelectorData,
2355
2452
  isCapturedValuesSelector,
2356
2453
  isCoreDependencyElement,
2454
+ isDependencyDataSelector,
2455
+ isDependencyDataSelectorData,
2357
2456
  isDependencyDescription,
2358
- isDependencyElementDescription,
2359
2457
  isDependencyKind,
2360
2458
  isDependencyRelationship,
2361
2459
  isDependencyRelationshipDescription,
@@ -2372,12 +2470,6 @@ export {
2372
2470
  isElementsDependencyInfo,
2373
2471
  isElementsSelector,
2374
2472
  isExternalDependencyElement,
2375
- isExternalLibrariesSelector,
2376
- isExternalLibrarySelector,
2377
- isExternalLibrarySelectorOptions,
2378
- isExternalLibrarySelectorOptionsWithPath,
2379
- isExternalLibrarySelectorOptionsWithSpecifiers,
2380
- isExternalLibrarySelectorWithOptions,
2381
2473
  isIgnoredElement,
2382
2474
  isInternalDependency,
2383
2475
  isKnownLocalElement,
@@ -2385,6 +2477,7 @@ export {
2385
2477
  isLocalElement,
2386
2478
  isSimpleElementSelectorByType,
2387
2479
  isUnknownLocalElement,
2480
+ normalizeElementSelector,
2388
2481
  normalizeElementsSelector
2389
2482
  };
2390
2483
  //# sourceMappingURL=index.browser.mjs.map