@component-compass/cli 0.0.1 → 0.0.2

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 (71) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +8 -4
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/init.d.ts +3 -2
  5. package/dist/commands/init.js +50 -62
  6. package/dist/commands/init.js.map +1 -1
  7. package/dist/commands/scan.js +109 -82
  8. package/dist/commands/scan.js.map +1 -1
  9. package/dist/composition-rollup.d.ts +21 -0
  10. package/dist/composition-rollup.js +74 -0
  11. package/dist/composition-rollup.js.map +1 -0
  12. package/dist/config/loader.js +5 -3
  13. package/dist/config/loader.js.map +1 -1
  14. package/dist/config/schema.d.ts +1 -2
  15. package/dist/config/schema.js.map +1 -1
  16. package/dist/identity.d.ts +12 -0
  17. package/dist/identity.js +25 -0
  18. package/dist/identity.js.map +1 -1
  19. package/dist/manifest/barrel-parser.d.ts +20 -0
  20. package/dist/manifest/barrel-parser.js +101 -16
  21. package/dist/manifest/barrel-parser.js.map +1 -1
  22. package/dist/manifest/derived-manifest-stub.d.ts +9 -0
  23. package/dist/manifest/derived-manifest-stub.js +11 -0
  24. package/dist/manifest/derived-manifest-stub.js.map +1 -0
  25. package/dist/manifest/diagnostic-filter.d.ts +12 -0
  26. package/dist/manifest/diagnostic-filter.js +23 -0
  27. package/dist/manifest/diagnostic-filter.js.map +1 -0
  28. package/dist/manifest/lazy-resolver.d.ts +52 -0
  29. package/dist/manifest/lazy-resolver.js +405 -0
  30. package/dist/manifest/lazy-resolver.js.map +1 -0
  31. package/dist/occurrences.d.ts +17 -0
  32. package/dist/occurrences.js +73 -0
  33. package/dist/occurrences.js.map +1 -0
  34. package/dist/reporter/index.d.ts +26 -3
  35. package/dist/reporter/index.js +68 -5
  36. package/dist/reporter/index.js.map +1 -1
  37. package/dist/reporter/json.d.ts +6 -2
  38. package/dist/reporter/json.js +7 -3
  39. package/dist/reporter/json.js.map +1 -1
  40. package/dist/reporter/stdout.d.ts +2 -2
  41. package/dist/reporter/stdout.js +11 -23
  42. package/dist/reporter/stdout.js.map +1 -1
  43. package/dist/rollup.js +0 -1
  44. package/dist/rollup.js.map +1 -1
  45. package/dist/seeds.d.ts +40 -0
  46. package/dist/seeds.js +114 -0
  47. package/dist/seeds.js.map +1 -0
  48. package/dist/types.d.ts +0 -1
  49. package/package.json +9 -9
  50. package/schema/config.schema.json +2 -10
  51. package/dist/graph/builder.d.ts +0 -25
  52. package/dist/graph/builder.js +0 -176
  53. package/dist/graph/builder.js.map +0 -1
  54. package/dist/manifest/discovery.d.ts +0 -24
  55. package/dist/manifest/discovery.js +0 -194
  56. package/dist/manifest/discovery.js.map +0 -1
  57. package/dist/manifest/index.d.ts +0 -6
  58. package/dist/manifest/index.js +0 -98
  59. package/dist/manifest/index.js.map +0 -1
  60. package/dist/manifest/resolver.d.ts +0 -30
  61. package/dist/manifest/resolver.js +0 -136
  62. package/dist/manifest/resolver.js.map +0 -1
  63. package/dist/manifest/run-discovery.d.ts +0 -12
  64. package/dist/manifest/run-discovery.js +0 -46
  65. package/dist/manifest/run-discovery.js.map +0 -1
  66. package/dist/manifest/types.d.ts +0 -3
  67. package/dist/manifest/types.js +0 -2
  68. package/dist/manifest/types.js.map +0 -1
  69. package/dist/reporter/types.d.ts +0 -69
  70. package/dist/reporter/types.js +0 -2
  71. package/dist/reporter/types.js.map +0 -1
@@ -0,0 +1,405 @@
1
+ import { existsSync, readFileSync, statSync } from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import { dirname, join, resolve as pathResolve } from "node:path";
4
+ import { validateManifest, } from "@component-compass/plugin-core";
5
+ import { parseBarrelTopLevelDetailed } from "./barrel-parser.js";
6
+ import { extractDerivedManifest as extractDerivedManifestStub } from "./derived-manifest-stub.js";
7
+ /**
8
+ * Hard ceiling on re-export hops a single resolution may walk. Real chains
9
+ * top out around 10 hops (deep barrel piles); 32 is a pathological-input
10
+ * safety net. When this fires we emit a `chain-too-deep` diagnostic and
11
+ * treat the current file as terminal so the user sees a signal rather than
12
+ * a silent wrong-leaf attribution.
13
+ */
14
+ const MAX_REEXPORT_HOPS = 32;
15
+ export function createLazyResolver(opts) {
16
+ const { resolveImport } = opts;
17
+ const extractDerived = opts.extractDerivedManifest ?? extractDerivedManifestStub;
18
+ // (absoluteFilePath::exportName) → cached hit (or null for negative cache).
19
+ const hitCache = new Map();
20
+ // tagName → custom-element entry (populated as authored manifests load).
21
+ const byTag = new Map();
22
+ // Leaf packages whose authored manifest has been loaded.
23
+ const visitedLeafs = new Map();
24
+ const diagnostics = [];
25
+ function loadLeafManifest(leafPackage, leafDir) {
26
+ const cached = visitedLeafs.get(leafPackage);
27
+ if (cached)
28
+ return cached.components;
29
+ const cemPath = join(leafDir, "custom-elements.json");
30
+ const ccmPath = join(leafDir, "component-compass-manifest.json");
31
+ let components = [];
32
+ let manifestPath = null;
33
+ let manifestSource = null;
34
+ let pkgVersion;
35
+ try {
36
+ const raw = readFileSync(join(leafDir, "package.json"), "utf8");
37
+ const pkg = JSON.parse(raw);
38
+ pkgVersion = pkg.version;
39
+ }
40
+ catch {
41
+ // Best-effort; leave undefined.
42
+ }
43
+ if (existsSync(cemPath)) {
44
+ try {
45
+ const raw = readFileSync(cemPath, "utf8");
46
+ const cem = JSON.parse(raw);
47
+ components = absorbCemDeclarations(cem, leafPackage);
48
+ manifestPath = cemPath;
49
+ manifestSource = "cem";
50
+ }
51
+ catch {
52
+ // Treat malformed CEM as no manifest.
53
+ }
54
+ }
55
+ else if (existsSync(ccmPath)) {
56
+ try {
57
+ const raw = readFileSync(ccmPath, "utf8");
58
+ const parsed = JSON.parse(raw);
59
+ const v = validateManifest(parsed);
60
+ if (v.ok) {
61
+ components = absorbCcmComponents(v.data, leafPackage);
62
+ manifestPath = ccmPath;
63
+ manifestSource = v.data.source;
64
+ }
65
+ }
66
+ catch {
67
+ // Treat malformed CCM as no manifest.
68
+ }
69
+ }
70
+ if (!manifestPath || !manifestSource) {
71
+ // No authored manifest — try derived (Phase 4 hook).
72
+ const derived = extractDerived(leafDir);
73
+ if (derived) {
74
+ components = derived.components;
75
+ for (const c of components) {
76
+ if (c.kind === "custom-element")
77
+ byTag.set(c.tagName, c);
78
+ }
79
+ // `path: ""` filters this entry out of `snapshotManifestRefs()`. The
80
+ // resolver-internal `source` is `ManifestSource` ("cem" | "react" |
81
+ // "vue"); "react" is a placeholder here — the artifact-facing
82
+ // distinction between authored and derived is carried by
83
+ // `OutputManifest.source` (added in Task 8), not this internal field.
84
+ visitedLeafs.set(leafPackage, {
85
+ components,
86
+ manifestRef: { source: "react", package: leafPackage, path: "", version: pkgVersion ?? null },
87
+ });
88
+ return components;
89
+ }
90
+ visitedLeafs.set(leafPackage, {
91
+ components: [],
92
+ manifestRef: { source: "cem", package: leafPackage, path: "", version: pkgVersion ?? null },
93
+ });
94
+ return [];
95
+ }
96
+ // Index custom elements by tagName.
97
+ for (const c of components) {
98
+ if (c.kind === "custom-element")
99
+ byTag.set(c.tagName, c);
100
+ }
101
+ visitedLeafs.set(leafPackage, {
102
+ components,
103
+ manifestRef: {
104
+ source: manifestSource,
105
+ package: leafPackage,
106
+ path: manifestPath,
107
+ version: pkgVersion ?? null,
108
+ },
109
+ });
110
+ return components;
111
+ }
112
+ function findPackageRoot(absFile) {
113
+ let dir = dirname(absFile);
114
+ while (dir !== dirname(dir)) {
115
+ const pkgJson = join(dir, "package.json");
116
+ if (existsSync(pkgJson)) {
117
+ try {
118
+ const pkg = JSON.parse(readFileSync(pkgJson, "utf8"));
119
+ if (pkg.name)
120
+ return { name: pkg.name, dir };
121
+ }
122
+ catch {
123
+ // Continue walking if unreadable.
124
+ }
125
+ }
126
+ dir = dirname(dir);
127
+ }
128
+ return null;
129
+ }
130
+ function matchInLeaf(components, chainSpecifiers, exportName) {
131
+ // First pass: explicit imports.react[] match (strongest signal).
132
+ for (const c of components) {
133
+ if (c.kind === "custom-element") {
134
+ const imports = c.imports?.react ?? [];
135
+ for (const i of imports) {
136
+ if (i.export !== exportName)
137
+ continue;
138
+ // Match if any specifier in the chain equals i.specifier (or stripped form).
139
+ const stripped = i.specifier.replace(/\.(js|mjs|cjs)$/, "");
140
+ if (chainSpecifiers.some((s) => s === i.specifier || s === stripped))
141
+ return c;
142
+ }
143
+ }
144
+ else if (c.kind === "react-component" || c.kind === "vue-component") {
145
+ if (c.export === exportName)
146
+ return c;
147
+ }
148
+ }
149
+ // Second pass: className-equality fallback for CEMs that don't declare
150
+ // componentCompass.imports.react[]. Scoped to THIS leaf only — never
151
+ // iterates a global byTag map (the old heuristic's failure mode). Safe
152
+ // because the resolver has already traversed the chain to a specific
153
+ // leaf package; if that leaf's CEM declares a custom-element class with
154
+ // exactly this name, the consumer's import is the React wrapper for it.
155
+ for (const c of components) {
156
+ if (c.kind === "custom-element" && c.className === exportName)
157
+ return c;
158
+ }
159
+ return null;
160
+ }
161
+ function resolveLazyManifest(fromFile, specifier, exportName) {
162
+ const initialAbs = resolveImport(fromFile, specifier);
163
+ if (!initialAbs)
164
+ return null;
165
+ // Resolved file lives in the same package as the importer (e.g.
166
+ // `../components/Foo.vue` from a sibling file in the consumer repo).
167
+ // The lazy resolver's contract is "external packages are opaque tuples";
168
+ // local files belong to the local-detection pipeline. Return null so the
169
+ // parser falls back to classifyImportOrigin / localIndex. Different
170
+ // package names — whether resolved through node_modules or through a
171
+ // yarn workspace symlink — are external and continue normal resolution.
172
+ const fromPkg = findPackageRoot(fromFile);
173
+ const initialPkg = findPackageRoot(initialAbs);
174
+ if (fromPkg && initialPkg && fromPkg.name === initialPkg.name) {
175
+ return null;
176
+ }
177
+ const cacheKey = `${initialAbs}::${exportName}`;
178
+ if (hitCache.has(cacheKey))
179
+ return hitCache.get(cacheKey) ?? null;
180
+ const visited = new Set();
181
+ const chainSpecifiers = [specifier];
182
+ let currentAbs = initialAbs;
183
+ let currentExport = exportName;
184
+ // Walk the re-export chain. If we advance MAX_REEXPORT_HOPS times without
185
+ // the chain naturally terminating (i.e. the next file would also be a
186
+ // barrel carrying our export), surface `chain-too-deep` and treat the
187
+ // current file as terminal so a wrong-leaf attribution is never silent.
188
+ let hops = 0;
189
+ while (true) {
190
+ const visitKey = `${currentAbs}::${currentExport}`;
191
+ if (visited.has(visitKey)) {
192
+ const cyclePkg = findPackageRoot(currentAbs)?.name;
193
+ const entry = { code: "cycle-detected", file: currentAbs, exportName: currentExport };
194
+ if (cyclePkg !== undefined)
195
+ entry.packageName = cyclePkg;
196
+ diagnostics.push(entry);
197
+ hitCache.set(cacheKey, null);
198
+ return null;
199
+ }
200
+ visited.add(visitKey);
201
+ const source = safeReadFile(currentAbs);
202
+ if (source === null)
203
+ break;
204
+ const { reExports, unsupported } = parseBarrelTopLevelDetailed(source);
205
+ const unsupportedPkg = unsupported.length > 0 ? findPackageRoot(currentAbs)?.name : undefined;
206
+ for (const u of unsupported) {
207
+ const entry = { code: "barrel-unsupported-form", file: currentAbs, form: u.form };
208
+ if (u.line !== undefined)
209
+ entry.line = u.line;
210
+ if (unsupportedPkg !== undefined)
211
+ entry.packageName = unsupportedPkg;
212
+ diagnostics.push(entry);
213
+ }
214
+ if (reExports.length === 0)
215
+ break; // terminal
216
+ // Find the re-export that carries `currentExport`.
217
+ const next = pickReExportFor(reExports, currentExport);
218
+ if (!next)
219
+ break; // terminal — none of the re-exports carry this export
220
+ const nextAbs = resolveImport(currentAbs, next.from);
221
+ if (!nextAbs)
222
+ break; // unresolvable next hop → treat current as terminal
223
+ // We're about to advance. If we've already consumed our budget, bail
224
+ // out with a diagnostic instead. `currentAbs` stays on the last barrel
225
+ // we successfully read so package-root walk continues from there.
226
+ if (hops >= MAX_REEXPORT_HOPS) {
227
+ const deepPkg = findPackageRoot(currentAbs)?.name;
228
+ const entry = {
229
+ code: "chain-too-deep",
230
+ file: currentAbs,
231
+ exportName: currentExport,
232
+ depth: MAX_REEXPORT_HOPS,
233
+ };
234
+ if (deepPkg !== undefined)
235
+ entry.packageName = deepPkg;
236
+ diagnostics.push(entry);
237
+ break;
238
+ }
239
+ chainSpecifiers.push(next.from);
240
+ currentAbs = nextAbs;
241
+ currentExport = next.targetExport;
242
+ hops++;
243
+ }
244
+ // Walk up to the package root of currentAbs.
245
+ const pkg = findPackageRoot(currentAbs);
246
+ if (!pkg) {
247
+ hitCache.set(cacheKey, null);
248
+ return null;
249
+ }
250
+ const components = loadLeafManifest(pkg.name, pkg.dir);
251
+ const matched = matchInLeaf(components, chainSpecifiers, currentExport);
252
+ if (!matched && components.length === 0) {
253
+ // Untraceable + no manifest at all; surface diagnostic.
254
+ diagnostics.push({
255
+ code: "untraceable-barrel",
256
+ packageName: pkg.name,
257
+ resolvedFile: currentAbs,
258
+ });
259
+ }
260
+ const hit = { leafPackage: pkg.name, matched };
261
+ hitCache.set(cacheKey, hit);
262
+ return hit;
263
+ }
264
+ function lookupByTag(tagName) {
265
+ return byTag.get(tagName) ?? null;
266
+ }
267
+ function snapshotComponents() {
268
+ const out = [];
269
+ for (const v of visitedLeafs.values())
270
+ out.push(...v.components);
271
+ return out;
272
+ }
273
+ function snapshotManifestRefs() {
274
+ const out = [];
275
+ for (const v of visitedLeafs.values()) {
276
+ if (v.manifestRef.path)
277
+ out.push(v.manifestRef);
278
+ }
279
+ return out;
280
+ }
281
+ function warmRoots(packageNames) {
282
+ // Anchor at <repoRoot>/_ so Node's resolution walks up through
283
+ // <repoRoot>/node_modules and parents, mirroring resolve-import.ts.
284
+ const anchor = pathResolve(opts.repoRoot ?? process.cwd(), "_");
285
+ const requireFromRepo = createRequire(anchor);
286
+ for (const name of packageNames) {
287
+ if (visitedLeafs.has(name))
288
+ continue;
289
+ try {
290
+ const pkgJsonPath = requireFromRepo.resolve(`${name}/package.json`);
291
+ loadLeafManifest(name, dirname(pkgJsonPath));
292
+ }
293
+ catch {
294
+ // Package not installed or its package.json not exposed via exports —
295
+ // skip silently. Warm-up is best-effort; missing entries are fine.
296
+ }
297
+ }
298
+ }
299
+ return {
300
+ resolveLazyManifest,
301
+ lookupByTag,
302
+ snapshotComponents,
303
+ snapshotManifestRefs,
304
+ diagnostics: () => diagnostics,
305
+ warmRoots,
306
+ };
307
+ }
308
+ // ---------------------------------------------------------------------------
309
+ // Helpers
310
+ // ---------------------------------------------------------------------------
311
+ function safeReadFile(path) {
312
+ try {
313
+ if (!statSync(path).isFile())
314
+ return null;
315
+ return readFileSync(path, "utf8");
316
+ }
317
+ catch {
318
+ return null;
319
+ }
320
+ }
321
+ function pickReExportFor(reExports, exportName) {
322
+ // Named re-export carrying our export wins over star re-exports.
323
+ for (const re of reExports) {
324
+ if (re.kind === "named") {
325
+ const found = re.names.find((n) => n.exported === exportName);
326
+ if (found)
327
+ return { from: re.from, targetExport: found.local };
328
+ }
329
+ }
330
+ // Star re-export: any star may carry the export; resolver tries the first
331
+ // and its terminal will tell us whether the leaf has it. v1 picks the first
332
+ // star — multi-star ambiguity in the same file is rare and a `barrel-
333
+ // unsupported-form` diagnostic could be added in a patch if real cases
334
+ // surface.
335
+ for (const re of reExports) {
336
+ if (re.kind === "star")
337
+ return { from: re.from, targetExport: exportName };
338
+ }
339
+ return null;
340
+ }
341
+ function absorbCemDeclarations(cem, packageName) {
342
+ const out = [];
343
+ for (const mod of cem.modules ?? []) {
344
+ for (const decl of mod.declarations ?? []) {
345
+ const d = decl;
346
+ if (!d.customElement || !d.tagName || !d.name)
347
+ continue;
348
+ const props = [];
349
+ for (const mem of d.members ?? []) {
350
+ if (mem.kind !== "field" || mem.privacy === "private")
351
+ continue;
352
+ if (!mem.name)
353
+ continue;
354
+ const p = { name: mem.name };
355
+ if (mem.type?.text !== undefined)
356
+ p.type = mem.type.text;
357
+ if (mem.deprecated !== undefined)
358
+ p.deprecated = mem.deprecated;
359
+ props.push(p);
360
+ }
361
+ const events = [];
362
+ for (const e of d.events ?? []) {
363
+ if (!e.name)
364
+ continue;
365
+ const ev = { name: e.name };
366
+ if (e.deprecated !== undefined)
367
+ ev.deprecated = e.deprecated;
368
+ events.push(ev);
369
+ }
370
+ out.push({
371
+ kind: "custom-element",
372
+ tagName: d.tagName,
373
+ source: { type: "external", package: packageName },
374
+ deprecated: d.deprecated ?? false,
375
+ props,
376
+ events,
377
+ slots: (d.slots ?? []).map((s) => ({ name: s.name ?? "" })),
378
+ className: d.name,
379
+ imports: d.componentCompass?.imports ?? {},
380
+ });
381
+ }
382
+ }
383
+ return out;
384
+ }
385
+ function absorbCcmComponents(manifest, packageName) {
386
+ const out = [];
387
+ for (const c of manifest.components) {
388
+ if (c.kind === "custom-element")
389
+ continue;
390
+ if (c.kind !== "react-component" && c.kind !== "vue-component")
391
+ continue;
392
+ if (!c.export)
393
+ continue;
394
+ const externalSrc = { type: "external", package: packageName };
395
+ out.push({
396
+ kind: c.kind,
397
+ export: c.export,
398
+ source: externalSrc,
399
+ deprecated: c.deprecated ?? false,
400
+ props: (c.props ?? []).map((p) => ({ name: p.name })),
401
+ });
402
+ }
403
+ return out;
404
+ }
405
+ //# sourceMappingURL=lazy-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lazy-resolver.js","sourceRoot":"","sources":["../../src/manifest/lazy-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Project parser-emitted occurrences onto the artifact-shape OutputOccurrence
3
+ * stream, preserving the three-state attribute model:
4
+ * - literal value (when captureValues is true and source value was static),
5
+ * - { __dynamic: DynamicKind } marker (always, when source was non-literal),
6
+ * - null (when captureValues is false and source was static, OR when source
7
+ * value was literal null).
8
+ *
9
+ * Phase 2: also resolves parser-side `parentRef` (intra-ParseResult occurrence
10
+ * index) into artifact-side `parentOccurrenceId` + `parentComponentId` strings,
11
+ * and carries through `depth`. Parent resolution stays scoped to one
12
+ * ParseResult — cross-file composition is not tracked.
13
+ *
14
+ * Pure function; no I/O.
15
+ */
16
+ import { type OutputOccurrence, type ParseResult } from "@component-compass/plugin-core";
17
+ export declare function parseResultsToOccurrences(results: ParseResult[], captureValues: boolean): OutputOccurrence[];
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Project parser-emitted occurrences onto the artifact-shape OutputOccurrence
3
+ * stream, preserving the three-state attribute model:
4
+ * - literal value (when captureValues is true and source value was static),
5
+ * - { __dynamic: DynamicKind } marker (always, when source was non-literal),
6
+ * - null (when captureValues is false and source was static, OR when source
7
+ * value was literal null).
8
+ *
9
+ * Phase 2: also resolves parser-side `parentRef` (intra-ParseResult occurrence
10
+ * index) into artifact-side `parentOccurrenceId` + `parentComponentId` strings,
11
+ * and carries through `depth`. Parent resolution stays scoped to one
12
+ * ParseResult — cross-file composition is not tracked.
13
+ *
14
+ * Pure function; no I/O.
15
+ */
16
+ import { computeOccurrenceId, } from "@component-compass/plugin-core";
17
+ import { computeStableIdFromComponentId } from "./identity.js";
18
+ export function parseResultsToOccurrences(results, captureValues) {
19
+ const out = [];
20
+ for (const result of results) {
21
+ // First pass: compute (final componentId hash, occurrenceId) for every
22
+ // parser-emitted occurrence in THIS ParseResult. Indexes align with
23
+ // result.occurrences, so parentRef indices resolve correctly in pass two.
24
+ const computed = result.occurrences.map((occ) => {
25
+ const componentId = computeStableIdFromComponentId(occ.componentId);
26
+ const occurrenceId = computeOccurrenceId(componentId, occ.loc.file, occ.loc.line, occ.loc.column);
27
+ return { componentId, occurrenceId };
28
+ });
29
+ // Second pass: project to OutputOccurrence, resolving parentRef.
30
+ for (let i = 0; i < result.occurrences.length; i++) {
31
+ const occ = result.occurrences[i];
32
+ const meta = computed[i];
33
+ if (!occ || !meta)
34
+ continue;
35
+ const { componentId, occurrenceId } = meta;
36
+ const props = {};
37
+ for (const p of occ.props) {
38
+ if (p.isDynamic) {
39
+ // dynamicKind should always be set when isDynamic is true (per
40
+ // scan-types.ts), but defend against malformed parser output.
41
+ props[p.name] = { __dynamic: p.dynamicKind ?? "expr" };
42
+ }
43
+ else if (captureValues && p.literalValue !== undefined) {
44
+ props[p.name] = p.literalValue;
45
+ }
46
+ else {
47
+ props[p.name] = null;
48
+ }
49
+ }
50
+ const output = {
51
+ componentId,
52
+ filePath: occ.loc.file,
53
+ line: occ.loc.line,
54
+ column: occ.loc.column,
55
+ via: occ.via,
56
+ props,
57
+ occurrenceId,
58
+ };
59
+ if (occ.parentRef !== undefined) {
60
+ const parent = computed[occ.parentRef];
61
+ if (parent) {
62
+ output.parentOccurrenceId = parent.occurrenceId;
63
+ output.parentComponentId = parent.componentId;
64
+ }
65
+ }
66
+ if (occ.depth !== undefined)
67
+ output.depth = occ.depth;
68
+ out.push(output);
69
+ }
70
+ }
71
+ return out;
72
+ }
73
+ //# sourceMappingURL=occurrences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"occurrences.js","sourceRoot":"","sources":["../src/occurrences.ts"],"names":[],"mappings":"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"}
@@ -7,9 +7,32 @@
7
7
  *
8
8
  * It does no IO; downstream JSON / stdout reporters consume the result.
9
9
  */
10
- import type { ManifestComponent, OutputManifest, OutputOccurrence, ScanEnvelope, ScanOutput } from "@component-compass/plugin-core";
10
+ import type { ManifestComponent, ManifestRef, OutputManifest, OutputOccurrence, ScanEnvelope, ScanOutput, ScanStats } from "@component-compass/plugin-core";
11
11
  import { type ComponentSeed } from "../rollup.js";
12
- export declare function buildScanOutput(envelope: ScanEnvelope, seeds: ComponentSeed[], occurrences: OutputOccurrence[]): ScanOutput;
12
+ export type PartialScanStats = Pick<ScanStats, "filesScanned" | "filesWithUsage" | "scanDurationMs">;
13
+ /**
14
+ * Builds the two-grain `ScanOutput` from the per-component seeds and the
15
+ * flat occurrence stream. When `packageScopes` is non-empty the emitter
16
+ * applies a final filter: components whose `identity.packageName` matches
17
+ * no scope pattern are dropped, along with every occurrence pointing at
18
+ * them. Local components always pass — `packageScopes` only constrains
19
+ * the external/ds lanes. An empty `packageScopes` array short-circuits
20
+ * the filter (visibility-first: emit everything).
21
+ *
22
+ * Pipeline order: rollup → composition → scope filter.
23
+ *
24
+ * Composition runs BEFORE the scope filter so cross-component parent
25
+ * counts are computed against the full occurrence graph. The scope
26
+ * filter then drops out-of-scope components, their occurrences, and —
27
+ * by transitive consequence — their composition rollup. Running
28
+ * composition AFTER the filter would let a child's `parentComponentId`
29
+ * point at a dropped component, leaving a dangling reference in the
30
+ * artifact.
31
+ *
32
+ * The filter runs AFTER rollup so the per-component stats already reflect
33
+ * the data the consumer will see in the artifact.
34
+ */
35
+ export declare function buildScanOutput(envelope: ScanEnvelope, manifests: ManifestRef[], partialStats: PartialScanStats, seeds: ComponentSeed[], occurrences: OutputOccurrence[], packageScopes: string[]): ScanOutput;
13
36
  /**
14
37
  * Pure converter: project a rich `ManifestComponent` (plugin-core domain
15
38
  * model) onto the artifact-shape `OutputManifest` consumed by the JSON
@@ -21,4 +44,4 @@ export declare function buildScanOutput(envelope: ScanEnvelope, seeds: Component
21
44
  * Returns `null` when no manifest entry was matched for the component, so
22
45
  * downstream `OutputComponent.manifest` can be set directly.
23
46
  */
24
- export declare function manifestComponentToOutput(m: ManifestComponent | undefined): OutputManifest | null;
47
+ export declare function manifestComponentToOutput(m: ManifestComponent | undefined, source: "authored" | "derived"): OutputManifest | null;
@@ -7,14 +7,77 @@
7
7
  *
8
8
  * It does no IO; downstream JSON / stdout reporters consume the result.
9
9
  */
10
+ import picomatch from "picomatch";
11
+ import { applyCompositionRollup } from "../composition-rollup.js";
10
12
  import { rollupOccurrencesToComponents } from "../rollup.js";
11
- export function buildScanOutput(envelope, seeds, occurrences) {
13
+ /**
14
+ * Builds the two-grain `ScanOutput` from the per-component seeds and the
15
+ * flat occurrence stream. When `packageScopes` is non-empty the emitter
16
+ * applies a final filter: components whose `identity.packageName` matches
17
+ * no scope pattern are dropped, along with every occurrence pointing at
18
+ * them. Local components always pass — `packageScopes` only constrains
19
+ * the external/ds lanes. An empty `packageScopes` array short-circuits
20
+ * the filter (visibility-first: emit everything).
21
+ *
22
+ * Pipeline order: rollup → composition → scope filter.
23
+ *
24
+ * Composition runs BEFORE the scope filter so cross-component parent
25
+ * counts are computed against the full occurrence graph. The scope
26
+ * filter then drops out-of-scope components, their occurrences, and —
27
+ * by transitive consequence — their composition rollup. Running
28
+ * composition AFTER the filter would let a child's `parentComponentId`
29
+ * point at a dropped component, leaving a dangling reference in the
30
+ * artifact.
31
+ *
32
+ * The filter runs AFTER rollup so the per-component stats already reflect
33
+ * the data the consumer will see in the artifact.
34
+ */
35
+ export function buildScanOutput(envelope, manifests, partialStats, seeds, occurrences, packageScopes) {
36
+ const rolled = rollupOccurrencesToComponents(occurrences, seeds);
37
+ const withComposition = applyCompositionRollup(rolled, occurrences);
38
+ const filtered = applyScopeFilter(withComposition, occurrences, packageScopes);
39
+ const stats = {
40
+ ...partialStats,
41
+ componentsDetected: filtered.components.length,
42
+ totalOccurrences: filtered.occurrences.length,
43
+ };
12
44
  return {
13
45
  envelope,
14
- components: rollupOccurrencesToComponents(occurrences, seeds),
15
- occurrences,
46
+ manifests,
47
+ stats,
48
+ components: filtered.components,
49
+ occurrences: filtered.occurrences,
16
50
  };
17
51
  }
52
+ /**
53
+ * Drops components whose `identity.packageName` matches none of the scope
54
+ * patterns and every occurrence pointing at a dropped component. Local
55
+ * components always pass (their `identity.scope === "local"` and they
56
+ * have no `packageName` to match).
57
+ *
58
+ * Empty `packageScopes` is the explicit "no filter" signal — the function
59
+ * returns the inputs untouched (visibility-first emit).
60
+ */
61
+ function applyScopeFilter(components, occurrences, packageScopes) {
62
+ if (packageScopes.length === 0)
63
+ return { components, occurrences };
64
+ const matchers = packageScopes.map((p) => picomatch(p));
65
+ const allowedIds = new Set();
66
+ const allowedComponents = components.filter((c) => {
67
+ if (c.identity.scope === "local") {
68
+ allowedIds.add(c.id);
69
+ return true;
70
+ }
71
+ const pkg = c.identity.packageName ?? "";
72
+ if (matchers.some((m) => m(pkg))) {
73
+ allowedIds.add(c.id);
74
+ return true;
75
+ }
76
+ return false;
77
+ });
78
+ const allowedOccurrences = occurrences.filter((o) => allowedIds.has(o.componentId));
79
+ return { components: allowedComponents, occurrences: allowedOccurrences };
80
+ }
18
81
  /**
19
82
  * Pure converter: project a rich `ManifestComponent` (plugin-core domain
20
83
  * model) onto the artifact-shape `OutputManifest` consumed by the JSON
@@ -26,7 +89,7 @@ export function buildScanOutput(envelope, seeds, occurrences) {
26
89
  * Returns `null` when no manifest entry was matched for the component, so
27
90
  * downstream `OutputComponent.manifest` can be set directly.
28
91
  */
29
- export function manifestComponentToOutput(m) {
92
+ export function manifestComponentToOutput(m, source) {
30
93
  if (!m)
31
94
  return null;
32
95
  const props = {};
@@ -34,7 +97,7 @@ export function manifestComponentToOutput(m) {
34
97
  if (p.default !== undefined)
35
98
  props[p.name] = { default: p.default };
36
99
  }
37
- const out = { props };
100
+ const out = { source, props };
38
101
  if (m.lifecycle !== undefined)
39
102
  out.lifecycle = m.lifecycle;
40
103
  return out;