@nielspeter/eess-ts 0.7.0 → 0.9.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 (72) hide show
  1. package/dist/builders/cross-layer-builder.d.ts.map +1 -1
  2. package/dist/builders/cross-layer-builder.js +6 -8
  3. package/dist/builders/cross-layer-builder.js.map +1 -1
  4. package/dist/builders/slice-rule-builder.d.ts.map +1 -1
  5. package/dist/builders/slice-rule-builder.js +7 -1
  6. package/dist/builders/slice-rule-builder.js.map +1 -1
  7. package/dist/conditions/dependency.d.ts.map +1 -1
  8. package/dist/conditions/dependency.js +5 -6
  9. package/dist/conditions/dependency.js.map +1 -1
  10. package/dist/conditions/function.d.ts.map +1 -1
  11. package/dist/conditions/function.js +22 -8
  12. package/dist/conditions/function.js.map +1 -1
  13. package/dist/conditions/reverse-dependency.d.ts.map +1 -1
  14. package/dist/conditions/reverse-dependency.js +16 -14
  15. package/dist/conditions/reverse-dependency.js.map +1 -1
  16. package/dist/conditions/structural.d.ts.map +1 -1
  17. package/dist/conditions/structural.js +28 -11
  18. package/dist/conditions/structural.js.map +1 -1
  19. package/dist/core/disk-set.d.ts.map +1 -1
  20. package/dist/core/disk-set.js +37 -2
  21. package/dist/core/disk-set.js.map +1 -1
  22. package/dist/core/glob-evaluator.d.ts.map +1 -1
  23. package/dist/core/glob-evaluator.js +5 -1
  24. package/dist/core/glob-evaluator.js.map +1 -1
  25. package/dist/core/import-candidates.d.ts +43 -0
  26. package/dist/core/import-candidates.d.ts.map +1 -1
  27. package/dist/core/import-candidates.js +46 -0
  28. package/dist/core/import-candidates.js.map +1 -1
  29. package/dist/core/path-universe.d.ts.map +1 -1
  30. package/dist/core/path-universe.js +10 -0
  31. package/dist/core/path-universe.js.map +1 -1
  32. package/dist/core/project-relative.d.ts +165 -42
  33. package/dist/core/project-relative.d.ts.map +1 -1
  34. package/dist/core/project-relative.js +355 -2
  35. package/dist/core/project-relative.js.map +1 -1
  36. package/dist/index.d.ts +1 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +1 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/models/slice.d.ts.map +1 -1
  41. package/dist/models/slice.js +20 -16
  42. package/dist/models/slice.js.map +1 -1
  43. package/dist/predicates/identity.d.ts +4 -1
  44. package/dist/predicates/identity.d.ts.map +1 -1
  45. package/dist/predicates/identity.js +39 -38
  46. package/dist/predicates/identity.js.map +1 -1
  47. package/dist/predicates/module.d.ts.map +1 -1
  48. package/dist/predicates/module.js +3 -4
  49. package/dist/predicates/module.js.map +1 -1
  50. package/dist/presets/agent-guardrails.d.ts.map +1 -1
  51. package/dist/presets/agent-guardrails.js +65 -14
  52. package/dist/presets/agent-guardrails.js.map +1 -1
  53. package/dist/presets/boundaries.js +58 -16
  54. package/dist/presets/boundaries.js.map +1 -1
  55. package/dist/presets/recommended.d.ts +21 -6
  56. package/dist/presets/recommended.d.ts.map +1 -1
  57. package/dist/presets/recommended.js.map +1 -1
  58. package/dist/rules/errors.d.ts +17 -0
  59. package/dist/rules/errors.d.ts.map +1 -1
  60. package/dist/rules/errors.js +21 -0
  61. package/dist/rules/errors.js.map +1 -1
  62. package/dist/smells/duplicate-bodies.d.ts +1 -1
  63. package/dist/smells/duplicate-bodies.d.ts.map +1 -1
  64. package/dist/smells/duplicate-bodies.js +12 -11
  65. package/dist/smells/duplicate-bodies.js.map +1 -1
  66. package/dist/smells/sibling-files.d.ts.map +1 -1
  67. package/dist/smells/sibling-files.js +16 -7
  68. package/dist/smells/sibling-files.js.map +1 -1
  69. package/dist/smells/smell-builder.d.ts.map +1 -1
  70. package/dist/smells/smell-builder.js +15 -1
  71. package/dist/smells/smell-builder.js.map +1 -1
  72. package/package.json +2 -2
@@ -2,6 +2,7 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import picomatch from 'picomatch';
4
4
  import { discoverIdentityRoot } from '@nielspeter/eess/internal';
5
+ import { readsRootRelativePath, rootFromTsConfigPath } from './project-relative.js';
5
6
  /**
6
7
  * Directories never worth walking.
7
8
  *
@@ -190,15 +191,49 @@ function build(project, budgetLimit) {
190
191
  // Exactly the confidently-wrong cause ADR-009 rule 2 forbids.
191
192
  const everything = [...everyFile, ...dirs];
192
193
  const typeScript = new Set(files);
194
+ // TWO prefixes, not one. The walk starts at `discoverIdentityRoot(...)` — the
195
+ // `.git`/workspace root — while every rule-facing matcher names its second
196
+ // view from `rootOf(sourceFile)`, the **tsconfig's** directory. In a monorepo
197
+ // package those differ, and using the walk root alone left this producer
198
+ // answering `absent` for a `'src/**'` the runtime matcher selects: the same
199
+ // two-derivations-disagree failure bug 0339 is about, surviving in the one
200
+ // place that states a fact about the filesystem. Reported in review, and the
201
+ // pinning test below now carries a fixture where the two roots differ.
202
+ //
203
+ // The absolute candidate is what stays in `matched`: `holdsTypeScript` and
204
+ // `typeScript` are keyed by absolute path, and a second spelling in the set
205
+ // would be a second key for one directory.
206
+ const prefixes = [root, rootFromTsConfigPath(project.tsConfigPath)]
207
+ .filter((r) => r !== undefined)
208
+ .map((r) => (r === '/' ? '/' : `${r.replaceAll('\\', '/')}/`));
209
+ const namedFromARoot = (candidate) => prefixes
210
+ .filter((prefix) => candidate.startsWith(prefix))
211
+ .map((prefix) => candidate.slice(prefix.length));
193
212
  return {
194
213
  classify(glob) {
195
214
  const isMatch = picomatch(glob);
215
+ // Both views of each path, as every rule-facing matcher does since bug
216
+ // 0339 — and here it is a claim about the FILESYSTEM, which makes getting
217
+ // it wrong worse than a missed match. Under a project path holding a
218
+ // dot-segment, picomatch's default `dot: false` stops `**` crossing it, so
219
+ // a `'**\/src/**'` whose directory exists and is merely excluded by the
220
+ // tsconfig was classified `absent` — and `absent`'s advice says no such
221
+ // path was found and a segment must be misspelled. Confidently wrong about
222
+ // a fact, which is the one thing this producer exists not to be.
223
+ const readsRootRelative = readsRootRelativePath(glob);
224
+ const hits = (candidate) => {
225
+ if (isMatch(candidate))
226
+ return true;
227
+ if (!readsRootRelative)
228
+ return false;
229
+ return namedFromARoot(candidate).some((named) => isMatch(named));
230
+ };
196
231
  // Never `everything.some(isMatch)` — picomatch reads the array index as
197
232
  // its second argument and returns a truthy object from index 1 onwards.
198
- const matched = everything.filter((candidate) => isMatch(candidate));
233
+ const matched = everything.filter((candidate) => hits(candidate));
199
234
  if (matched.length === 0) {
200
235
  // Not seen is not the same as not there.
201
- return pruned.some((dir) => isMatch(dir) || glob.includes(dir.slice(root.length + 1)))
236
+ return pruned.some((dir) => hits(dir) || glob.includes(dir.slice(root.length + 1)))
202
237
  ? 'not-determined'
203
238
  : 'absent';
204
239
  }
@@ -1 +1 @@
1
- {"version":3,"file":"disk-set.js","sourceRoot":"","sources":["../../src/core/disk-set.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"disk-set.js","sourceRoot":"","sources":["../../src/core/disk-set.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,SAAS,MAAM,WAAW,CAAA;AAEjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAEnF;;;;;;;;GAQG;AACH,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC;IACpB,cAAc;IACd,MAAM;IACN,MAAM;IACN,OAAO;IACP,KAAK;IACL,UAAU;IACV,OAAO;IACP,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,OAAO;IACP,QAAQ;CACT,CAAC,CAAA;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,YAAY,GAAG,MAAM,CAAA;AAE3B,4EAA4E;AAC5E,0EAA0E;AAC1E,6EAA6E;AAC7E,0EAA0E;AAC1E,kBAAkB;AAClB,MAAM,OAAO,GAAG,eAAe,CAAA;AA+B/B,MAAM,KAAK,GAAG,IAAI,OAAO,EAAwB,CAAA;AAEjD;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,OAAoB;IAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACjC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAA;IACzB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;IAC1C,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IACzB,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,4JAA4J;AAC5J,MAAM,UAAU,YAAY,CAAC,OAAoB,EAAE,WAAW,GAAG,YAAY;IAC3E,OAAO,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;AACpC,CAAC;AAED,SAAS,KAAK,CAAC,OAAoB,EAAE,WAAmB;IACtD,6EAA6E;IAC7E,wEAAwE;IACxE,uEAAuE;IACvE,0EAA0E;IAC1E,6EAA6E;IAC7E,uEAAuE;IACvE,6EAA6E;IAC7E,8EAA8E;IAC9E,kEAAkE;IAClE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC;QAAE,OAAO,YAAY,CAAA;IAC/D,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAA;IACrE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,YAAY,CAAA;IAE7C,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,sFAAsF;IACtF,MAAM,SAAS,GAAa,EAAE,CAAA;IAC9B,MAAM,IAAI,GAAa,EAAE,CAAA;IACzB;;;;;;;;OAQG;IACH,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,IAAI,MAAM,GAAG,WAAW,CAAA;IACxB,IAAI,SAAS,GAAG,KAAK,CAAA;IAErB,MAAM,IAAI,GAAG,CAAC,GAAW,EAAQ,EAAE;QACjC,IAAI,SAAS;YAAE,OAAM;QACrB,IAAI,OAAoB,CAAA;QACxB,IAAI,CAAC;YACH,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;QACxD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,GAAG,CAAA,CAAC,uDAAuD;YAChE,OAAM;QACR,CAAC;QACD,MAAM,IAAI,OAAO,CAAC,MAAM,CAAA;QACxB,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACf,SAAS,GAAG,IAAI,CAAA;YAChB,OAAM;QACR,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;YAC7D,0DAA0D;YAC1D,EAAE;YACF,8JAA8J;YAC9J,gEAAgE;YAChE,mEAAmE;YACnE,wEAAwE;YACxE,uEAAuE;YACvE,oEAAoE;YACpE,sEAAsE;YACtE,gCAAgC;YAChC,EAAE;YACF,qEAAqE;YACrE,qDAAqD;YACrD,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACjB,SAAQ;YACV,CAAC;YACD,uEAAuE;YACvE,qEAAqE;YACrE,uCAAuC;YACvC,EAAE;YACF,yEAAyE;YACzE,0EAA0E;YAC1E,0EAA0E;YAC1E,0EAA0E;YAC1E,cAAc;YACd,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACf,IAAI,CAAC,IAAI,CAAC,CAAA;YACZ,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACpB,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;oBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAChD,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IACD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAA;IAChC,IAAI,SAAS;QAAE,OAAO,YAAY,CAAA;IAElC,yEAAyE;IACzE,yEAAyE;IACzE,6EAA6E;IAC7E,qEAAqE;IACrE,6EAA6E;IAC7E,YAAY;IACZ,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAA;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAC5B,OAAO,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACjC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACxB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAChC,IAAI,MAAM,KAAK,GAAG;gBAAE,MAAK;YACzB,GAAG,GAAG,MAAM,CAAA;QACd,CAAC;IACH,CAAC;IAED,qEAAqE;IACrE,4EAA4E;IAC5E,wEAAwE;IACxE,oEAAoE;IACpE,0EAA0E;IAC1E,8DAA8D;IAC9D,MAAM,UAAU,GAAG,CAAC,GAAG,SAAS,EAAE,GAAG,IAAI,CAAC,CAAA;IAC1C,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAA;IACjC,8EAA8E;IAC9E,2EAA2E;IAC3E,8EAA8E;IAC9E,yEAAyE;IACzE,4EAA4E;IAC5E,2EAA2E;IAC3E,6EAA6E;IAC7E,uEAAuE;IACvE,EAAE;IACF,2EAA2E;IAC3E,4EAA4E;IAC5E,2CAA2C;IAC3C,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,oBAAoB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;SAChE,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;SAC3C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;IAChE,MAAM,cAAc,GAAG,CAAC,SAAiB,EAAY,EAAE,CACrD,QAAQ;SACL,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;SAChD,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IACpD,OAAO;QACL,QAAQ,CAAC,IAAY;YACnB,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;YAC/B,uEAAuE;YACvE,0EAA0E;YAC1E,qEAAqE;YACrE,2EAA2E;YAC3E,wEAAwE;YACxE,wEAAwE;YACxE,2EAA2E;YAC3E,iEAAiE;YACjE,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAA;YACrD,MAAM,IAAI,GAAG,CAAC,SAAiB,EAAW,EAAE;gBAC1C,IAAI,OAAO,CAAC,SAAS,CAAC;oBAAE,OAAO,IAAI,CAAA;gBACnC,IAAI,CAAC,iBAAiB;oBAAE,OAAO,KAAK,CAAA;gBACpC,OAAO,cAAc,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;YAClE,CAAC,CAAA;YACD,wEAAwE;YACxE,wEAAwE;YACxE,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA;YACjE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,yCAAyC;gBACzC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;oBACjF,CAAC,CAAC,gBAAgB;oBAClB,CAAC,CAAC,QAAQ,CAAA;YACd,CAAC;YACD,mEAAmE;YACnE,yEAAyE;YACzE,uEAAuE;YACvE,8CAA8C;YAC9C,OAAO,OAAO,CAAC,IAAI,CACjB,CAAC,SAAS,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAC3E;gBACC,CAAC,CAAC,kBAAkB;gBACpB,CAAC,CAAC,eAAe,CAAA;QACrB,CAAC;KACF,CAAA;AACH,CAAC;AAED,MAAM,YAAY,GAAY;IAC5B,QAAQ,EAAE,GAAG,EAAE,CAAC,gBAAgB;CACjC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"glob-evaluator.d.ts","sourceRoot":"","sources":["../../src/core/glob-evaluator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAY,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAItD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAQ9E;AAQD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAS1E;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAUtD"}
1
+ {"version":3,"file":"glob-evaluator.d.ts","sourceRoot":"","sources":["../../src/core/glob-evaluator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAY,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAKtD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAQ9E;AAQD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAY1E;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAUtD"}
@@ -1,5 +1,6 @@
1
1
  import picomatch from 'picomatch';
2
2
  import { isGlobNode, isOpaqueGlob } from '@nielspeter/eess/internal';
3
+ import { readsRepoRelativePath } from './project-relative.js';
3
4
  import { viewsFor } from '@nielspeter/eess/internal';
4
5
  import { syntacticFault } from './glob-diagnosis.js';
5
6
  /**
@@ -62,7 +63,10 @@ function isDeadChild(child, universe) {
62
63
  export function isDeadSite(site, universe) {
63
64
  if ((site.polarity ?? 'positive') === 'negative')
64
65
  return false;
65
- const views = viewsFor(universe, site.kind);
66
+ // Which views the MATCHER gives this glob, not every view the universe holds. A view the
67
+ // matcher does not read makes an unsatisfiable glob look live, and an unreported dead selector
68
+ // is a rule that certifies nothing while passing — see `viewsFor`'s own note.
69
+ const views = viewsFor(universe, site.kind, readsRepoRelativePath(site.glob));
66
70
  if (views.length === 0)
67
71
  return false;
68
72
  if (syntacticFault(site.glob, site.kind, site.base) !== undefined)
@@ -1 +1 @@
1
- {"version":3,"file":"glob-evaluator.js","sourceRoot":"","sources":["../../src/core/glob-evaluator.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,WAAW,CAAA;AAEjC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAEpE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,cAAc,CAAC,IAAc,EAAE,QAAsB;IACnE,OAAO,IAAI,CAAC,EAAE,KAAK,KAAK;QACtB,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC7D,CAAC,CAAC,qEAAqE;YACrE,kEAAkE;YAClE,uEAAuE;YACvE,6DAA6D;YAC7D,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAA;AAC9F,CAAC;AAED,SAAS,WAAW,CAAC,KAAoC,EAAE,QAAsB;IAC/E,IAAI,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IAC7D,IAAI,YAAY,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACrC,OAAO,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;AACpC,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,UAAU,CAAC,IAAc,EAAE,QAAsB;IAC/D,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC,KAAK,UAAU;QAAE,OAAO,KAAK,CAAA;IAC9D,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACpC,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IAC9E,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACpC,sEAAsE;IACtE,oEAAoE;IACpE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;AAC5E,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,WAAW,CAAC,IAAc;IACxC,MAAM,KAAK,GAAe,EAAE,CAAA;IAC5B,MAAM,IAAI,GAAG,CAAC,OAAiB,EAAQ,EAAE;QACvC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrC,IAAI,UAAU,CAAC,KAAK,CAAC;gBAAE,IAAI,CAAC,KAAK,CAAC,CAAA;iBAC7B,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAClD,CAAC;IACH,CAAC,CAAA;IACD,IAAI,CAAC,IAAI,CAAC,CAAA;IACV,OAAO,KAAK,CAAA;AACd,CAAC"}
1
+ {"version":3,"file":"glob-evaluator.js","sourceRoot":"","sources":["../../src/core/glob-evaluator.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,WAAW,CAAA;AAEjC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAEpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,cAAc,CAAC,IAAc,EAAE,QAAsB;IACnE,OAAO,IAAI,CAAC,EAAE,KAAK,KAAK;QACtB,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC7D,CAAC,CAAC,qEAAqE;YACrE,kEAAkE;YAClE,uEAAuE;YACvE,6DAA6D;YAC7D,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAA;AAC9F,CAAC;AAED,SAAS,WAAW,CAAC,KAAoC,EAAE,QAAsB;IAC/E,IAAI,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IAC7D,IAAI,YAAY,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACrC,OAAO,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;AACpC,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,UAAU,CAAC,IAAc,EAAE,QAAsB;IAC/D,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC,KAAK,UAAU;QAAE,OAAO,KAAK,CAAA;IAC9D,yFAAyF;IACzF,+FAA+F;IAC/F,8EAA8E;IAC9E,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC7E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACpC,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IAC9E,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACpC,sEAAsE;IACtE,oEAAoE;IACpE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;AAC5E,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,WAAW,CAAC,IAAc;IACxC,MAAM,KAAK,GAAe,EAAE,CAAA;IAC5B,MAAM,IAAI,GAAG,CAAC,OAAiB,EAAQ,EAAE;QACvC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrC,IAAI,UAAU,CAAC,KAAK,CAAC;gBAAE,IAAI,CAAC,KAAK,CAAC,CAAA;iBAC7B,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAClD,CAAC;IACH,CAAC,CAAA;IACD,IAAI,CAAC,IAAI,CAAC,CAAA;IACV,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -48,6 +48,49 @@ export declare function importCandidates(decl: ImportDeclaration): ImportCandida
48
48
  * from an edge on the other.
49
49
  */
50
50
  export declare function candidatesFor(specifier: string, resolvedPath: string | undefined, projectRoot?: string): ImportCandidates;
51
+ /**
52
+ * The matcher an import glob is matched with — `dot: true`, deliberately.
53
+ *
54
+ * ## Why this differs from a project-source glob (bug 0349)
55
+ *
56
+ * picomatch's default `dot: false` stops `**` crossing a path segment that begins
57
+ * with `.`. Under pnpm a package resolves to
58
+ * `node_modules/.pnpm/knex@3/node_modules/knex/…` and under Yarn's cache to
59
+ * `.yarn/cache/knex-npm-3/…`, so `notImportFrom('**\/node_modules/knex/**')` — the
60
+ * spelling for "this package, however it is imported" — matched nothing and
61
+ * reported a **pass**. No dot-directory checkout is involved; the dot segment is
62
+ * the package manager's own layout, inside an ordinary tree.
63
+ *
64
+ * [Bug 0339](../../../../work/bugs/fixed/0339-globs-match-nothing-when-the-project-sits-under-a-dot-directory.md)
65
+ * weighed `{ dot: true }` for path globs generally and **rejected** it, because it
66
+ * would change matching inside the project: `'**\/*.ts'` would begin matching
67
+ * `.nuxt/` or `.next/` content. That rejection stands and is not touched here.
68
+ *
69
+ * **It does not transfer to an import target, for a reason and a measurement.**
70
+ *
71
+ * The reason: an adopter authors their project's paths, so crossing `.storybook/`
72
+ * changes which of *their* files a rule reads — their decision to make. They do
73
+ * not author `node_modules`' layout. A dot segment there is the resolver's
74
+ * implementation detail, and refusing to cross it means the glob cannot name the
75
+ * package it is about.
76
+ *
77
+ * The measurement, which is the stronger half. Today the SAME rule gives different
78
+ * verdicts for the same dependency depending only on how `node_modules` was laid
79
+ * out — `onlyImportFrom('**\/shared/**')` against a dependency's internal
80
+ * `shared/` directory **allows** it under a hoisted npm tree and **reports** it
81
+ * under pnpm. So the current behaviour is not safely strict, it is inconsistent by
82
+ * package manager, which is the same defect 0339 is named for: a verdict that
83
+ * depends on where things sit on disk rather than on the code. `dot: true` makes
84
+ * every layout agree, on what the majority layout already does.
85
+ *
86
+ * **The consequence to state plainly:** an allowlist widens under pnpm and Yarn to
87
+ * match what it always did under npm. A sloppy allowlist glob was always this
88
+ * permissive; those layouts were accidentally hiding it.
89
+ *
90
+ * One definition rather than six call sites, because six copies of a matching rule
91
+ * is how this area has repeatedly drifted.
92
+ */
93
+ export declare function importTargetMatcher(glob: string): picomatch.Matcher;
51
94
  /**
52
95
  * The first candidate matching any matcher, or `undefined` if none do.
53
96
  *
@@ -1 +1 @@
1
- {"version":3,"file":"import-candidates.d.ts","sourceRoot":"","sources":["../../src/core/import-candidates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AACtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAEjD;;;;GAIG;AACH,KAAK,gBAAgB,GAAG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,CAAC,CAAA;AAE3E;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,gBAAgB,CAK1E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,WAAW,CAAC,EAAE,MAAM,GACnB,gBAAgB,CAsBlB;AASD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,gBAAgB,EAC5B,QAAQ,EAAE,SAAS,SAAS,CAAC,OAAO,EAAE,GACrC,MAAM,GAAG,SAAS,CAIpB"}
1
+ {"version":3,"file":"import-candidates.d.ts","sourceRoot":"","sources":["../../src/core/import-candidates.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AACtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAEjD;;;;GAIG;AACH,KAAK,gBAAgB,GAAG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,CAAC,CAAA;AAE3E;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,gBAAgB,CAK1E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,WAAW,CAAC,EAAE,MAAM,GACnB,gBAAgB,CAsBlB;AASD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,OAAO,CAEnE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,gBAAgB,EAC5B,QAAQ,EAAE,SAAS,SAAS,CAAC,OAAO,EAAE,GACrC,MAAM,GAAG,SAAS,CAIpB"}
@@ -1,3 +1,4 @@
1
+ import picomatchFactory from 'picomatch';
1
2
  /**
2
3
  * Every string a glob may legitimately be matched against for one import.
3
4
  *
@@ -74,6 +75,51 @@ function relativeTo(root, absolutePath) {
74
75
  const prefix = root === '/' ? '/' : `${root}/`;
75
76
  return absolutePath.startsWith(prefix) ? absolutePath.slice(prefix.length) : undefined;
76
77
  }
78
+ /**
79
+ * The matcher an import glob is matched with — `dot: true`, deliberately.
80
+ *
81
+ * ## Why this differs from a project-source glob (bug 0349)
82
+ *
83
+ * picomatch's default `dot: false` stops `**` crossing a path segment that begins
84
+ * with `.`. Under pnpm a package resolves to
85
+ * `node_modules/.pnpm/knex@3/node_modules/knex/…` and under Yarn's cache to
86
+ * `.yarn/cache/knex-npm-3/…`, so `notImportFrom('**\/node_modules/knex/**')` — the
87
+ * spelling for "this package, however it is imported" — matched nothing and
88
+ * reported a **pass**. No dot-directory checkout is involved; the dot segment is
89
+ * the package manager's own layout, inside an ordinary tree.
90
+ *
91
+ * [Bug 0339](../../../../work/bugs/fixed/0339-globs-match-nothing-when-the-project-sits-under-a-dot-directory.md)
92
+ * weighed `{ dot: true }` for path globs generally and **rejected** it, because it
93
+ * would change matching inside the project: `'**\/*.ts'` would begin matching
94
+ * `.nuxt/` or `.next/` content. That rejection stands and is not touched here.
95
+ *
96
+ * **It does not transfer to an import target, for a reason and a measurement.**
97
+ *
98
+ * The reason: an adopter authors their project's paths, so crossing `.storybook/`
99
+ * changes which of *their* files a rule reads — their decision to make. They do
100
+ * not author `node_modules`' layout. A dot segment there is the resolver's
101
+ * implementation detail, and refusing to cross it means the glob cannot name the
102
+ * package it is about.
103
+ *
104
+ * The measurement, which is the stronger half. Today the SAME rule gives different
105
+ * verdicts for the same dependency depending only on how `node_modules` was laid
106
+ * out — `onlyImportFrom('**\/shared/**')` against a dependency's internal
107
+ * `shared/` directory **allows** it under a hoisted npm tree and **reports** it
108
+ * under pnpm. So the current behaviour is not safely strict, it is inconsistent by
109
+ * package manager, which is the same defect 0339 is named for: a verdict that
110
+ * depends on where things sit on disk rather than on the code. `dot: true` makes
111
+ * every layout agree, on what the majority layout already does.
112
+ *
113
+ * **The consequence to state plainly:** an allowlist widens under pnpm and Yarn to
114
+ * match what it always did under npm. A sloppy allowlist glob was always this
115
+ * permissive; those layouts were accidentally hiding it.
116
+ *
117
+ * One definition rather than six call sites, because six copies of a matching rule
118
+ * is how this area has repeatedly drifted.
119
+ */
120
+ export function importTargetMatcher(glob) {
121
+ return picomatchFactory(glob, { dot: true });
122
+ }
77
123
  /**
78
124
  * The first candidate matching any matcher, or `undefined` if none do.
79
125
  *
@@ -1 +1 @@
1
- {"version":3,"file":"import-candidates.js","sourceRoot":"","sources":["../../src/core/import-candidates.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,4JAA4J;AAC5J,MAAM,UAAU,gBAAgB,CAAC,IAAuB;IACtD,OAAO,aAAa,CAClB,IAAI,CAAC,uBAAuB,EAAE,EAC9B,IAAI,CAAC,4BAA4B,EAAE,EAAE,WAAW,EAAE,CACnD,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa,CAC3B,SAAiB,EACjB,YAAgC,EAChC,WAAoB;IAEpB,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO,CAAC,SAAS,CAAC,CAAA;IAClD,MAAM,UAAU,GAAa,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IAC9E,0EAA0E;IAC1E,EAAE;IACF,oEAAoE;IACpE,uDAAuD;IACvD,4EAA4E;IAC5E,2DAA2D;IAC3D,8EAA8E;IAC9E,2EAA2E;IAC3E,8CAA8C;IAC9C,EAAE;IACF,2EAA2E;IAC3E,2EAA2E;IAC3E,+DAA+D;IAC/D,EAAE;IACF,6EAA6E;IAC7E,2EAA2E;IAC3E,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA;IACtD,IAAI,QAAQ,KAAK,SAAS;QAAE,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACrD,OAAO,CAAC,YAAY,EAAE,GAAG,UAAU,CAAC,CAAA;AACtC,CAAC;AAED,sFAAsF;AACtF,SAAS,UAAU,CAAC,IAAwB,EAAE,YAAoB;IAChE,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACxC,MAAM,MAAM,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAA;IAC9C,OAAO,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACxF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,UAA4B,EAC5B,QAAsC;IAEtC,4EAA4E;IAC5E,+DAA+D;IAC/D,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;AACvF,CAAC;AAED,wEAAwE;AACxE,SAAS,mBAAmB,CAAC,SAAiB;IAC5C,OAAO,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;AAC/D,CAAC"}
1
+ {"version":3,"file":"import-candidates.js","sourceRoot":"","sources":["../../src/core/import-candidates.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,MAAM,WAAW,CAAA;AAWxC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,4JAA4J;AAC5J,MAAM,UAAU,gBAAgB,CAAC,IAAuB;IACtD,OAAO,aAAa,CAClB,IAAI,CAAC,uBAAuB,EAAE,EAC9B,IAAI,CAAC,4BAA4B,EAAE,EAAE,WAAW,EAAE,CACnD,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa,CAC3B,SAAiB,EACjB,YAAgC,EAChC,WAAoB;IAEpB,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO,CAAC,SAAS,CAAC,CAAA;IAClD,MAAM,UAAU,GAAa,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IAC9E,0EAA0E;IAC1E,EAAE;IACF,oEAAoE;IACpE,uDAAuD;IACvD,4EAA4E;IAC5E,2DAA2D;IAC3D,8EAA8E;IAC9E,2EAA2E;IAC3E,8CAA8C;IAC9C,EAAE;IACF,2EAA2E;IAC3E,2EAA2E;IAC3E,+DAA+D;IAC/D,EAAE;IACF,6EAA6E;IAC7E,2EAA2E;IAC3E,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA;IACtD,IAAI,QAAQ,KAAK,SAAS;QAAE,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACrD,OAAO,CAAC,YAAY,EAAE,GAAG,UAAU,CAAC,CAAA;AACtC,CAAC;AAED,sFAAsF;AACtF,SAAS,UAAU,CAAC,IAAwB,EAAE,YAAoB;IAChE,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACxC,MAAM,MAAM,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAA;IAC9C,OAAO,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACxF,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,gBAAgB,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAA;AAC9C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,UAA4B,EAC5B,QAAsC;IAEtC,4EAA4E;IAC5E,+DAA+D;IAC/D,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;AACvF,CAAC;AAED,wEAAwE;AACxE,SAAS,mBAAmB,CAAC,SAAiB;IAC5C,OAAO,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;AAC/D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"path-universe.d.ts","sourceRoot":"","sources":["../../src/core/path-universe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD;;;;;;;;;;GAUG;AACH,YAAY,EAAE,YAAY,EAAE,CAAA;AAI5B;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,YAAY,CAiB/D"}
1
+ {"version":3,"file":"path-universe.d.ts","sourceRoot":"","sources":["../../src/core/path-universe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD;;;;;;;;;;GAUG;AACH,YAAY,EAAE,YAAY,EAAE,CAAA;AAI5B;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,YAAY,CA4B/D"}
@@ -1,3 +1,4 @@
1
+ import { repoRootOf } from './project-relative.js';
1
2
  const cache = new WeakMap();
2
3
  /**
3
4
  * The project's path universe, computed once per project.
@@ -14,11 +15,20 @@ export function pathUniverse(project) {
14
15
  ...new Set(filePaths.map((filePath) => filePath.substring(0, filePath.lastIndexOf('/')))),
15
16
  ];
16
17
  const root = tsconfigDir(project.tsConfigPath);
18
+ // The SAME derivation the runtime matcher uses, from the same function — not a
19
+ // second walk. `viewsFor`'s union decides whether a glob is reported dead, so a
20
+ // view the matcher has and the universe lacks reports a working rule as
21
+ // enforcing nothing, and a view the universe has and the matcher lacks reports
22
+ // nothing at all about a rule that silently selects zero. Bug 0348 is the
23
+ // second shape; bug 0339's own docstring records the first.
24
+ const repoRoot = repoRootOf(project.tsConfigPath);
17
25
  const universe = {
18
26
  filePaths,
19
27
  parentDirs,
20
28
  tsconfigRelativeFilePaths: filePaths.map((filePath) => relativeTo(root, filePath)),
21
29
  tsconfigRelativeParentDirs: parentDirs.map((dir) => relativeTo(root, dir)),
30
+ repoRelativeFilePaths: repoRoot === undefined ? [] : filePaths.map((p) => relativeTo(repoRoot, p)),
31
+ repoRelativeParentDirs: repoRoot === undefined ? [] : parentDirs.map((d) => relativeTo(repoRoot, d)),
22
32
  };
23
33
  cache.set(project, universe);
24
34
  return universe;
@@ -1 +1 @@
1
- {"version":3,"file":"path-universe.js","sourceRoot":"","sources":["../../src/core/path-universe.ts"],"names":[],"mappings":"AAgBA,MAAM,KAAK,GAAG,IAAI,OAAO,EAA6B,CAAA;AAEtD;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,OAAoB;IAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACjC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAA;IAEzB,MAAM,SAAS,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAA;IACxF,MAAM,UAAU,GAAG;QACjB,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;KAC1F,CAAA;IACD,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IAC9C,MAAM,QAAQ,GAAiB;QAC7B,SAAS;QACT,UAAU;QACV,yBAAyB,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAClF,0BAA0B,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;KAC3E,CAAA;IACD,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IAC5B,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,6FAA6F;AAC7F,SAAS,WAAW,CAAC,YAAoB;IACvC,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACrD,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;IAC7C,OAAO,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;AAC/D,CAAC;AAED;;;;;;GAMG;AACH,SAAS,UAAU,CAAC,IAAY,EAAE,QAAgB;IAChD,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAA;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAA;IACrD,OAAO,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC/E,CAAC"}
1
+ {"version":3,"file":"path-universe.js","sourceRoot":"","sources":["../../src/core/path-universe.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAgBlD,MAAM,KAAK,GAAG,IAAI,OAAO,EAA6B,CAAA;AAEtD;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,OAAoB;IAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACjC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAA;IAEzB,MAAM,SAAS,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAA;IACxF,MAAM,UAAU,GAAG;QACjB,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;KAC1F,CAAA;IACD,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IAC9C,+EAA+E;IAC/E,gFAAgF;IAChF,wEAAwE;IACxE,+EAA+E;IAC/E,0EAA0E;IAC1E,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IACjD,MAAM,QAAQ,GAAiB;QAC7B,SAAS;QACT,UAAU;QACV,yBAAyB,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAClF,0BAA0B,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC1E,qBAAqB,EACnB,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC7E,sBAAsB,EACpB,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;KAC/E,CAAA;IACD,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IAC5B,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,6FAA6F;AAC7F,SAAS,WAAW,CAAC,YAAoB;IACvC,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACrD,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;IAC7C,OAAO,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;AAC/D,CAAC;AAED;;;;;;GAMG;AACH,SAAS,UAAU,CAAC,IAAY,EAAE,QAAgB;IAChD,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAA;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAA;IACrD,OAAO,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC/E,CAAC"}
@@ -1,45 +1,4 @@
1
- /**
2
- * Make a project-relative glob work, instead of failing loudly — plan 0067 C.
3
- *
4
- * Globs are matched against **absolute** file paths, so `'src/domain/**'`
5
- * matches nothing. That is the single commonest real mistake with this library:
6
- * it is the shape 0.18.1 was released for, and as of **0.34.0** it is a hard
7
- * build failure telling the author to prefix `'**\/'`.
8
- *
9
- * Prefixing works but says something different. `'**\/src/domain/**'` matches a
10
- * `src/domain` **anywhere** — including `vendor/thing/src/domain`, and
11
- * including a second `src/` nested inside a monorepo package. What the author
12
- * meant was the one at the project root. 0067 called normalization "the root
13
- * cause" fix for that reason, and 0069 sequenced it directly after R3b.
14
- *
15
- * So an unanchored glob is matched against the path **relative to the
16
- * tsconfig's directory**, in addition to the absolute path. Both spellings keep
17
- * working and they mean different things:
18
- *
19
- * | glob | matches |
20
- * | --------------------- | ------------------------------------------- |
21
- * | `'src/domain/**'` | that folder **at the project root** |
22
- * | `'**\/src/domain/**'` | a `src/domain` **anywhere** in the project |
23
- * | `'/abs/src/domain/**'`| exactly that absolute path |
24
- *
25
- * ## Why the root comes from the element, not from the builder
26
- *
27
- * A predicate is constructed two ways that must not diverge:
28
- * `.that().resideInFolder(g)`, where the builder knows the project, and
29
- * `.that().satisfy(resideInFolder(g))`, where nothing does.
30
- * `tests/core/glob-declaration.test.ts` exists to assert the two spellings
31
- * agree, and threading the root through only the first would break that.
32
- *
33
- * Every `Located` element can reach its own `SourceFile`, and ts-morph carries
34
- * the tsconfig it was loaded from on the project's compiler options. So the
35
- * root is derived where the match happens, from the element itself, and both
36
- * spellings get it for free.
37
- *
38
- * `configFilePath` is `undefined` for a project built in memory or without a
39
- * tsconfig. That is a genuine "no root known" and normalization is skipped —
40
- * the glob keeps its absolute-only meaning rather than being matched against
41
- * something invented.
42
- */
1
+ import picomatch from 'picomatch';
43
2
  import type { Project as TsMorphProject, SourceFile } from 'ts-morph';
44
3
  /**
45
4
  * Whether a glob can already match an absolute path, so the `**\/` hint would
@@ -95,4 +54,168 @@ export declare function rootOf(sourceFile: SourceFile, fallbackTsConfigPath?: st
95
54
  * `path-universe.ts` documents avoiding for the same reason.
96
55
  */
97
56
  export declare function relativeToRoot(sourceFile: SourceFile, absolutePath: string, fallbackTsConfigPath?: string): string | undefined;
57
+ /**
58
+ * The identity root for a project, from the path of its tsconfig.
59
+ *
60
+ * For the materializer in `path-universe.ts`, which holds the `ArchProject` and
61
+ * no `SourceFile`. It must agree with `matchesPath`'s view or the diagnosis and
62
+ * the runtime disagree about one glob — so both derive it here.
63
+ */
64
+ export declare function repoRootOf(tsConfigPath: string): string | undefined;
65
+ /**
66
+ * `absolutePath` named from the identity root — the `.git`/workspace root above
67
+ * the tsconfig — or `undefined` when there is no such root or the path sits
68
+ * outside it.
69
+ *
70
+ * This is the view a monorepo's own addressing needs: `'**\/apps/api/src/**'`
71
+ * names segments BETWEEN the repository root and the tsconfig directory, so the
72
+ * tsconfig-relative view has stripped off the very thing it names.
73
+ */
74
+ export declare function relativeToRepoRoot(sourceFile: SourceFile, absolutePath: string, fallbackTsConfigPath?: string): string | undefined;
75
+ /**
76
+ * Is this glob matched against the path named from the identity root, as well as
77
+ * the two views above?
78
+ *
79
+ * ## Globstar-led only, and that is the whole ruling — bug 0348
80
+ *
81
+ * `'**\/x'` says **anywhere**. The only reason it fails to match a file under a
82
+ * checkout like `~/.worktrees/repo` is picomatch's default `dot: false` applied
83
+ * to a prefix the author does not own — where the repository happens to sit on
84
+ * this machine. Naming the path from the repository root removes exactly that
85
+ * prefix and nothing else, so the glob gets to mean what it says. It is the same
86
+ * authorship argument [bug 0349](../../../../work/bugs/fixed/0349-a-path-shaped-dependency-ban-passes-silently-under-pnpm-and-yarn.md)
87
+ * makes for a package manager's layout: a verdict must not be decided by where
88
+ * things sit on disk.
89
+ *
90
+ * A **project-relative** glob (`'src/**'`) is deliberately excluded, and this is
91
+ * the exclusion that keeps the fix from being a widening. That spelling MEANS
92
+ * "relative to the project root", and `core/project-relative.ts`'s first job is
93
+ * that the project root is the tsconfig's directory. Offering it an identity-root
94
+ * view would make one spelling name two different directories in a monorepo —
95
+ * `packages/api/src/` and the repository's own `src/` — which is a second meaning
96
+ * for one glob with no bug behind it. Pinned by `a-glob-above-the-tsconfig-root.test.ts`
97
+ * · `it('CONTROL: a glob relative to the package root keeps meaning the package root')`.
98
+ *
99
+ * Project-relative globs need nothing here anyway: their second view is already
100
+ * free of the checkout path, which is why bug 0339 fixed them and left this.
101
+ *
102
+ * ## Why this adds no matches except the broken ones
103
+ *
104
+ * The identity-relative path is a SUFFIX of the absolute path. For a glob led by
105
+ * `'**\/'`, if it matches the suffix it also matches the whole — unless some
106
+ * segment of the stripped prefix begins with `.`, which is precisely the defect.
107
+ * So under a checkout with no dot-segment the third view selects nothing the
108
+ * first did not. Measured rather than argued: `it('adds no match under a
109
+ * checkout with no dot-segment')` compares every file in a fixture with the view
110
+ * on and off.
111
+ */
112
+ export declare function readsRepoRelativePath(glob: string): boolean;
113
+ /**
114
+ * Is this glob matched against the path named from the project root, as well as
115
+ * the absolute path?
116
+ *
117
+ * ## The case that was missing — bug 0339
118
+ *
119
+ * This used to be `isProjectRelative` alone, so `'**\/src/**'` — the one
120
+ * spelling `FAULT_ADVICE` tells the author to write — was the one spelling that
121
+ * never got the second view. picomatch's default `dot: false` stops `**`
122
+ * crossing a segment that begins with `.`, and these globs are matched against
123
+ * an ABSOLUTE path, so a checkout under `~/.tool/worktrees/app` (a worktree
124
+ * manager's layout, a cache directory, some CI workspaces) selected **nothing**
125
+ * for every rule. Measured on 0.7.0 over one fixture copied to two paths:
126
+ * `resideInFile('**\/src/**')` examined 0 subjects under a dot-segment and 1
127
+ * beside it, and ADR-010's guard then reported correct rules as enforcing
128
+ * nothing — with a remedy that says to widen the selector or declare it empty.
129
+ *
130
+ * It was also the last disagreement with the DIAGNOSIS: `viewsFor` takes
131
+ * satisfiability against the **union** of the absolute and tsconfig-relative
132
+ * views, unconditionally. So a `'**\/src/**'` under a dot-directory was live to
133
+ * `isDeadSite` and dead at runtime — two derivations disagreeing about one glob,
134
+ * which is the failure this file spends most of its guards on.
135
+ *
136
+ * ## Why this is not simply "every glob"
137
+ *
138
+ * Removing the gate outright was tried, and this repository's own controls
139
+ * refused it — both exclusions `isProjectRelative` makes are load-bearing, and
140
+ * neither is about anchoring:
141
+ *
142
+ * - a `./` segment stays excluded, because `syntacticFault` reports
143
+ * `dot-segment` for it. picomatch matches `'./src/domain/**'` against
144
+ * `src/domain`, so offering the view reinstates exactly the split verdict
145
+ * `isProjectRelative`'s own comment records: 3 subjects selected AND a dead
146
+ * selector reported, in one run. `../` is excluded alongside it and is a
147
+ * DIFFERENT fault — `syntacticFault`'s dot-segment test is `/(?:^|\/)\.\//`,
148
+ * which `'../src/**'` does not match, so it is reported `unanchored` instead.
149
+ * The exclusion is right either way (nothing above the root has a second view,
150
+ * so no match is forged); it is the fault name that differs, and this comment
151
+ * claimed one rule for two shapes.
152
+ * - `'*\/x/**'` stays excluded, because it is the last reachable `unanchored`
153
+ * fault for a path glob. Normalizing it made the anchor advice and the whole
154
+ * `ANCHOR_ADVICE` grouping unreachable — measured as seven failures in
155
+ * `tests/builders/slice-rule-builder.test.ts`, whose subject is that each
156
+ * remedy is TRUE.
157
+ *
158
+ * `'/abs/x'` and a drive-absolute `'C:/x'` are excluded too, and there it makes
159
+ * no behavioural difference — neither can match a relative path — but the
160
+ * declaration stays honest about what is tried.
161
+ *
162
+ * So the rule is: the root-relative view is offered to a glob that names a
163
+ * location relative to the root, and to one that says "anywhere". Both readings
164
+ * are location-independent, which is the property the bug was about.
165
+ */
166
+ export declare function readsRootRelativePath(glob: string): boolean;
167
+ /**
168
+ * A compiled path glob: the matcher, and whether it reads the root-relative
169
+ * view.
170
+ *
171
+ * Both together, because the decision is a function of the glob and the sites
172
+ * that match several globs at once would otherwise carry a parallel array of
173
+ * booleans. Deciding it once per glob rather than once per path also keeps
174
+ * `picomatch()` and `readsRootRelativePath()` off the per-element path.
175
+ */
176
+ export interface PathGlobMatcher {
177
+ readonly glob: string;
178
+ readonly isMatch: picomatch.Matcher;
179
+ readonly readsRootRelative: boolean;
180
+ readonly readsRepoRelative: boolean;
181
+ }
182
+ /** Compile one path glob. */
183
+ export declare function pathGlobMatcher(glob: string): PathGlobMatcher;
184
+ /** Compile several path globs, in order. */
185
+ export declare function pathGlobMatchers(globs: readonly string[]): PathGlobMatcher[];
186
+ /**
187
+ * Does this glob match this path — absolutely, or named from the project root?
188
+ *
189
+ * The one place a path glob meets a path **where a `SourceFile` is in hand**.
190
+ * `disk-set.ts` reimplements the decision inline over walked disk paths, which
191
+ * have no `SourceFile` and are named from a root of their own — that copy is
192
+ * deliberate and is marked as such there, so this is not "the only place" and
193
+ * saying so would leave the next reader trusting a claim with a second copy
194
+ * behind it.
195
+ *
196
+ * Every site that matched a file path against a glob had its own copy of this
197
+ * three-line decision and they disagreed. Over the ten that carry a sabotage row
198
+ * in bug 0339, measured at 0.7.0: **three** offered the second view only for a
199
+ * project-relative glob (`predicates/identity.ts`, `cross-layer-builder.ts`,
200
+ * `slice.ts`'s `resolveByDefinition`), **one** offered it always
201
+ * (`duplicate-bodies.ts`), and **six** never offered it at all. Bug 0339 was in
202
+ * the last group's shape and bug 0036 in the first's.
203
+ * `conditions/reverse-dependency.ts` also offered it always and needed no
204
+ * change, so it has no row.
205
+ *
206
+ * `undefined` from `relativeToRoot` (no root known, or a file above the root) is
207
+ * a genuine "there is no second view" and yields the absolute answer rather than
208
+ * an invented one.
209
+ */
210
+ export declare function matchesPath(matcher: PathGlobMatcher, sourceFile: SourceFile, absolutePath: string, fallbackTsConfigPath?: string): boolean;
211
+ /**
212
+ * Does ANY of these globs match this path?
213
+ *
214
+ * Never `matchers.some(isMatch)` at a call site: picomatch takes the array index
215
+ * as its second argument and returns a truthy object from index 1 onwards, so
216
+ * the shorthand reports a match for every path in a list of two or more. Four
217
+ * files in `src/` carry a comment warning about it; this is the version that
218
+ * cannot be written the other way.
219
+ */
220
+ export declare function anyMatchesPath(matchers: readonly PathGlobMatcher[], sourceFile: SourceFile, absolutePath: string, fallbackTsConfigPath?: string): boolean;
98
221
  //# sourceMappingURL=project-relative.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"project-relative.d.ts","sourceRoot":"","sources":["../../src/core/project-relative.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,KAAK,EAAE,OAAO,IAAI,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAErE;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAgCvD;AA+BD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,EAAE,cAAc,EAC9B,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B,IAAI,CAKN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAY7E;AAOD,wBAAgB,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,oBAAoB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAqChG;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,MAAM,EACpB,oBAAoB,CAAC,EAAE,MAAM,GAC5B,MAAM,GAAG,SAAS,CAKpB"}
1
+ {"version":3,"file":"project-relative.d.ts","sourceRoot":"","sources":["../../src/core/project-relative.ts"],"names":[],"mappings":"AAqDA,OAAO,SAAS,MAAM,WAAW,CAAA;AAEjC,OAAO,KAAK,EAAE,OAAO,IAAI,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAErE;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AA4BD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAgCvD;AA+BD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,EAAE,cAAc,EAC9B,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B,IAAI,CAKN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAY7E;AAOD,wBAAgB,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,oBAAoB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAqChG;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,MAAM,EACpB,oBAAoB,CAAC,EAAE,MAAM,GAC5B,MAAM,GAAG,SAAS,CAKpB;AAwCD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEnE;AAED;;;;;;;;GAQG;AAEH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,MAAM,EACpB,oBAAoB,CAAC,EAAE,MAAM,GAC5B,MAAM,GAAG,SAAS,CAKpB;AAqCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAY3D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAG3D;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAA;IACnC,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAA;IACnC,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAA;CACpC;AAED,6BAA6B;AAC7B,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAO7D;AAED,4CAA4C;AAC5C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,eAAe,EAAE,CAE5E;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,eAAe,EACxB,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,MAAM,EACpB,oBAAoB,CAAC,EAAE,MAAM,GAC5B,OAAO,CAeT;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,eAAe,EAAE,EACpC,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,MAAM,EACpB,oBAAoB,CAAC,EAAE,MAAM,GAC5B,OAAO,CAIT"}