@knapsack/source-conflicts-adapter 4.89.11 → 4.89.12--canary.7237.e7e94a1.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.
- package/README.md +110 -66
- package/dist/analyzer.d.ts +12 -20
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +41 -25
- package/dist/analyzer.js.map +1 -1
- package/dist/analyzer.vitest.js +31 -2
- package/dist/analyzer.vitest.js.map +1 -1
- package/dist/detect.d.ts +3 -3
- package/dist/detect.js +14 -14
- package/dist/detect.js.map +1 -1
- package/dist/detect.vitest.js +16 -16
- package/dist/detect.vitest.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/json/jsonConflicts.d.ts +5 -7
- package/dist/json/jsonConflicts.d.ts.map +1 -1
- package/dist/json/jsonConflicts.js +22 -61
- package/dist/json/jsonConflicts.js.map +1 -1
- package/dist/json/jsonConflicts.vitest.js +13 -44
- package/dist/json/jsonConflicts.vitest.js.map +1 -1
- package/dist/mdx/mdxConflicts.d.ts +19 -20
- package/dist/mdx/mdxConflicts.d.ts.map +1 -1
- package/dist/mdx/mdxConflicts.js +106 -120
- package/dist/mdx/mdxConflicts.js.map +1 -1
- package/dist/mdx/mdxConflicts.vitest.js +295 -10
- package/dist/mdx/mdxConflicts.vitest.js.map +1 -1
- package/dist/mdx/tableMdx.d.ts +5 -0
- package/dist/mdx/tableMdx.d.ts.map +1 -1
- package/dist/mdx/tableMdx.js +10 -0
- package/dist/mdx/tableMdx.js.map +1 -1
- package/dist/multiSourceCompare.d.ts +2 -3
- package/dist/multiSourceCompare.d.ts.map +1 -1
- package/dist/multiSourceCompare.js +2 -3
- package/dist/multiSourceCompare.js.map +1 -1
- package/dist/multiSourceCompare.vitest.js +4 -4
- package/dist/multiSourceCompare.vitest.js.map +1 -1
- package/dist/parser.js +1 -1
- package/dist/transformer.d.ts.map +1 -1
- package/dist/transformer.js +0 -7
- package/dist/transformer.js.map +1 -1
- package/dist/types.d.ts +83 -12
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/entityKey.d.ts +11 -0
- package/dist/utils/entityKey.d.ts.map +1 -0
- package/dist/utils/entityKey.js +31 -0
- package/dist/utils/entityKey.js.map +1 -0
- package/dist/utils/entityKey.vitest.d.ts +2 -0
- package/dist/utils/entityKey.vitest.d.ts.map +1 -0
- package/dist/utils/entityKey.vitest.js +41 -0
- package/dist/utils/entityKey.vitest.js.map +1 -0
- package/dist/utils/fingerprint.d.ts +12 -0
- package/dist/utils/fingerprint.d.ts.map +1 -0
- package/dist/utils/fingerprint.js +17 -0
- package/dist/utils/fingerprint.js.map +1 -0
- package/example/demo-output.json +953 -0
- package/example/run-demo.mjs +21 -0
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ When the same entity (e.g. `button.react.mdx` or `global.tokens.json`) is contri
|
|
|
13
13
|
3. **Detects** conflicts by comparing content across sources:
|
|
14
14
|
- **MDX/MD**: parses into anchored sections, applies a chain of canonicalization rules
|
|
15
15
|
- **JSON (W3C Design Token)**: flattens token leaves (`$value`) to anchors, compares by exact hash
|
|
16
|
-
4. **Reports** per-anchor verdicts: `
|
|
16
|
+
4. **Reports** per-anchor verdicts: `DIFFERENT` or `MISSING` (only conflicting anchors are included — `ALL_SAME` anchors are filtered out)
|
|
17
17
|
|
|
18
18
|
### Entity file layout
|
|
19
19
|
|
|
@@ -39,27 +39,25 @@ This package lives in the monorepo at `libs/ingest-pipeline/adapters/source-conf
|
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
42
|
-
## Quick start —
|
|
42
|
+
## Quick start — `run()`
|
|
43
43
|
|
|
44
|
-
The fastest way to detect conflicts without running the full pipeline is via
|
|
44
|
+
The fastest way to detect conflicts without running the full pipeline is via `run()`:
|
|
45
45
|
|
|
46
46
|
```typescript
|
|
47
|
-
import
|
|
48
|
-
import * as path from 'node:path';
|
|
49
|
-
import { analyze } from '@knapsack/source-conflicts-adapter';
|
|
47
|
+
import { run } from '@knapsack/source-conflicts-adapter';
|
|
50
48
|
import { createLogger } from '@knapsack/utils';
|
|
51
49
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
const report = await run({
|
|
51
|
+
entitiesRootAbs: '/absolute/path/to/entities',
|
|
52
|
+
outputPath: '/absolute/path/to/output.json', // optional
|
|
53
|
+
logger: createLogger('source-conflicts'),
|
|
54
|
+
});
|
|
57
55
|
|
|
58
|
-
|
|
59
|
-
console.log(`
|
|
56
|
+
console.log(`Entities: ${report.summary.entityCount}`);
|
|
57
|
+
console.log(`Conflicts: ${report.summary.totalConflicts}`);
|
|
60
58
|
```
|
|
61
59
|
|
|
62
|
-
|
|
60
|
+
`run()` scans the entities directory, detects all conflicts, and returns a `ConflictReport`. When `outputPath` is provided, the report is also written as JSON.
|
|
63
61
|
|
|
64
62
|
---
|
|
65
63
|
|
|
@@ -108,9 +106,35 @@ const result = await sourceConflictsAdapter.analyzer!.analyze(config, {
|
|
|
108
106
|
|
|
109
107
|
---
|
|
110
108
|
|
|
111
|
-
## Result
|
|
109
|
+
## Result shapes
|
|
112
110
|
|
|
113
|
-
### `
|
|
111
|
+
### `ConflictReport` (from `run()`)
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
type ConflictReport = {
|
|
115
|
+
generatedAt: string;
|
|
116
|
+
entitiesRootAbs: string;
|
|
117
|
+
entities: ConflictReportEntity[];
|
|
118
|
+
summary: {
|
|
119
|
+
entityCount: number;
|
|
120
|
+
totalConflicts: number;
|
|
121
|
+
differentCount: number;
|
|
122
|
+
missingCount: number;
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
type ConflictReportEntity = {
|
|
127
|
+
entityKey: string;
|
|
128
|
+
entityType: EntityKind;
|
|
129
|
+
entityRelPath: string;
|
|
130
|
+
/** Source key URIs of all sources involved in this entity. */
|
|
131
|
+
sources: string[];
|
|
132
|
+
/** DIFFERENT and MISSING anchors only. */
|
|
133
|
+
conflicts: AnchorDiffView[];
|
|
134
|
+
};
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### `SourceConflictsAnalysisResult` (from `analyze()`)
|
|
114
138
|
|
|
115
139
|
```typescript
|
|
116
140
|
type SourceConflictsAnalysisResult = {
|
|
@@ -125,24 +149,63 @@ type SourceConflictsAnalysisResult = {
|
|
|
125
149
|
|
|
126
150
|
```typescript
|
|
127
151
|
type ConflictGroupResult = {
|
|
128
|
-
group: ConflictGroup;
|
|
129
|
-
bundle: ConflictBundle;
|
|
130
|
-
|
|
131
|
-
compareSourceKeys: string[]; // frontmatter URIs of compare sources (up to MAX_COMPARE_SOURCES)
|
|
132
|
-
verdicts: AnchorVerdictView[]; // per-anchor verdict derived from bundle for this baseline/compare
|
|
152
|
+
group: ConflictGroup; // entityType, relPath, artifacts[]
|
|
153
|
+
bundle: ConflictBundle; // source-agnostic per-anchor snapshot (serializable — store in DB)
|
|
154
|
+
anchors: AnchorDiffView[]; // DIFFERENT and MISSING anchors only
|
|
133
155
|
};
|
|
134
156
|
```
|
|
135
157
|
|
|
136
|
-
`bundle` is a fully-serializable JSON snapshot — no functions, no circular refs.
|
|
158
|
+
`bundle` is a fully-serializable JSON snapshot — no functions, no circular refs.
|
|
159
|
+
|
|
160
|
+
### `AnchorDiffView`
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
type AnchorDiffView = {
|
|
164
|
+
readonly anchor: string;
|
|
165
|
+
readonly verdict: 'DIFFERENT' | 'MISSING';
|
|
166
|
+
/**
|
|
167
|
+
* One entry per distinct canonical form — sources that share the same hash are grouped.
|
|
168
|
+
* Present when verdict is DIFFERENT or MISSING (and at least one source has a value).
|
|
169
|
+
*/
|
|
170
|
+
readonly variants?: AnchorVariant[];
|
|
171
|
+
/**
|
|
172
|
+
* All pairwise unified diffs (n*(n-1)/2 pairs).
|
|
173
|
+
* Present when verdict is DIFFERENT and text values are available.
|
|
174
|
+
*/
|
|
175
|
+
readonly diffs?: AnchorPairDiff[];
|
|
176
|
+
/**
|
|
177
|
+
* Source key URIs of sources that have no definition for this anchor.
|
|
178
|
+
* Present when verdict is MISSING.
|
|
179
|
+
*/
|
|
180
|
+
readonly missingSourceKeys?: string[];
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
type AnchorVariant = {
|
|
184
|
+
/** Source key URIs that share this canonical form. */
|
|
185
|
+
readonly sourceKeys: string[];
|
|
186
|
+
/** Canonical text (may be truncated by PreviewBounds). */
|
|
187
|
+
readonly text: string;
|
|
188
|
+
/** Language hint for syntax highlighting. Present for code fence anchors. */
|
|
189
|
+
readonly lang?: string;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
type AnchorPairDiff = {
|
|
193
|
+
readonly fromSourceKeys: string[];
|
|
194
|
+
readonly toSourceKeys: string[];
|
|
195
|
+
/** Unified diff string (GNU patch format). */
|
|
196
|
+
readonly unifiedDiff: string;
|
|
197
|
+
};
|
|
198
|
+
```
|
|
137
199
|
|
|
138
200
|
### `ConflictItemRecord` (inside `ConflictBundle.items`)
|
|
139
201
|
|
|
140
202
|
```typescript
|
|
141
203
|
type ConflictItemRecord = {
|
|
142
204
|
fingerprint: string;
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
205
|
+
/** Filename-parsed source type (e.g. "KNAPSACK"). Used internally for matching. */
|
|
206
|
+
sourceType: SourceType;
|
|
207
|
+
/** URI, e.g. "knapsack://patterns/button". The authoritative source identifier. */
|
|
208
|
+
sourceKey: string;
|
|
146
209
|
frontmatterSchemaVersion: number;
|
|
147
210
|
frontmatter: Record<string, unknown>; // MDX: YAML frontmatter; JSON: $extensions.pcif contents
|
|
148
211
|
};
|
|
@@ -150,61 +213,38 @@ type ConflictItemRecord = {
|
|
|
150
213
|
|
|
151
214
|
### Verdicts
|
|
152
215
|
|
|
153
|
-
| Value | Meaning
|
|
154
|
-
| ----------- |
|
|
155
|
-
| `
|
|
156
|
-
| `
|
|
157
|
-
| `MISSING` | At least one source does not contain this anchor |
|
|
158
|
-
|
|
159
|
-
---
|
|
216
|
+
| Value | Meaning |
|
|
217
|
+
| ----------- | ----------------------------------------------------------------- |
|
|
218
|
+
| `DIFFERENT` | At least one source has different content for this anchor |
|
|
219
|
+
| `MISSING` | At least one source does not contain this anchor |
|
|
160
220
|
|
|
161
|
-
|
|
221
|
+
`ALL_SAME` anchors (where all sources agree) are excluded from `anchors` / `conflicts` output.
|
|
162
222
|
|
|
163
|
-
|
|
223
|
+
---
|
|
164
224
|
|
|
165
|
-
|
|
225
|
+
## Bundle-first pattern
|
|
166
226
|
|
|
167
|
-
|
|
168
|
-
2. **Load** the bundle from storage when serving a request.
|
|
169
|
-
3. **Call** `computeVerdictsForBaselineCompare` with the caller-specified baseline/compare source URIs.
|
|
227
|
+
`ConflictBundle` is the stable stored artifact. `computeDiffsForAllSources` is a pure function that derives diffs from any stored bundle with no I/O or re-parsing.
|
|
170
228
|
|
|
171
229
|
```typescript
|
|
172
230
|
import {
|
|
173
|
-
|
|
231
|
+
computeDiffsForAllSources,
|
|
174
232
|
getAvailableSourceKeysFromBundle,
|
|
175
233
|
} from '@knapsack/source-conflicts-adapter';
|
|
176
234
|
import type { ConflictBundle } from '@knapsack/source-conflicts-adapter';
|
|
177
235
|
|
|
178
|
-
// Load stored bundle from DB (JSON column → parse → use directly
|
|
236
|
+
// Load stored bundle from DB (JSON column → parse → use directly)
|
|
179
237
|
const bundle: ConflictBundle = JSON.parse(row.bundleJson);
|
|
180
238
|
|
|
181
|
-
// Discover which source URIs are available
|
|
239
|
+
// Discover which source URIs are available
|
|
182
240
|
const available = getAvailableSourceKeysFromBundle(bundle);
|
|
183
241
|
// e.g. ["knapsack://patterns/button", "storybook://components/button"]
|
|
184
242
|
|
|
185
|
-
// Derive
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
'knapsack://patterns/button', // baseline URI
|
|
189
|
-
['storybook://components/button'], // compare URIs
|
|
190
|
-
);
|
|
191
|
-
|
|
192
|
-
// Swap baseline without re-detecting — just call again
|
|
193
|
-
const swappedVerdicts = computeVerdictsForBaselineCompare(
|
|
194
|
-
bundle,
|
|
195
|
-
'storybook://components/button',
|
|
196
|
-
['knapsack://patterns/button'],
|
|
197
|
-
);
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### `getAvailableSourceKeysFromBundle`
|
|
201
|
-
|
|
202
|
-
```typescript
|
|
203
|
-
function getAvailableSourceKeysFromBundle(bundle: ConflictBundle): string[];
|
|
243
|
+
// Derive diffs across all sources — instant, no I/O
|
|
244
|
+
const anchors = computeDiffsForAllSources(bundle);
|
|
245
|
+
// Returns only DIFFERENT and MISSING anchors
|
|
204
246
|
```
|
|
205
247
|
|
|
206
|
-
Returns the frontmatter source URI (`sourceKey`) for every item in the bundle. Any of these can be passed as `baselineSourceKey` to `computeVerdictsForBaselineCompare` without re-running detection. Sources in `bundle.excludedSourceKeys` (if any, when `MAX_COMPARE_SOURCES` is exceeded) are **not** in the bundle and cannot be used as baseline without a full re-detect.
|
|
207
|
-
|
|
208
248
|
---
|
|
209
249
|
|
|
210
250
|
## Comparison rules
|
|
@@ -256,19 +296,21 @@ src/
|
|
|
256
296
|
├── index.ts # Adapter export + public API re-exports
|
|
257
297
|
├── types.ts # Shared types: SourceConflictsConfig, ArtifactRef, ConflictGroup,
|
|
258
298
|
│ # ConflictBundle, ConflictRecord, ConflictItemRecord,
|
|
259
|
-
│ # AgnosticDefinition, AnchorDefinitionsRecord,
|
|
260
|
-
│ #
|
|
299
|
+
│ # AgnosticDefinition, AnchorDefinitionsRecord,
|
|
300
|
+
│ # AnchorDiffView, AnchorVariant, AnchorPairDiff,
|
|
301
|
+
│ # ConflictReport, ConflictReportEntity, VERDICT, Rule,
|
|
302
|
+
│ # CanonicalizeContext, PreviewBounds
|
|
261
303
|
├── validator.ts # validateConfig / validateFull
|
|
262
304
|
├── parser.ts # parse() — indexes entities, writes manifest
|
|
263
305
|
├── transformer.ts # transform() — runs detection, writes verdict bundles
|
|
264
|
-
├── analyzer.ts # analyze() — in-process detection, returns typed result
|
|
306
|
+
├── analyzer.ts # analyze() / run() — in-process detection, returns typed result
|
|
265
307
|
├── detect.ts # indexEntitiesDir / findConflictGroups (filesystem)
|
|
266
308
|
├── parse.ts # parseEntityKind / parseSourceType (filename parsing)
|
|
267
309
|
├── multiSourceCompare.ts # compareAnchorMultiSource (rule engine)
|
|
268
310
|
├── compare/
|
|
269
311
|
│ └── preview.ts # Preview/truncation helpers
|
|
270
312
|
├── mdx/
|
|
271
|
-
│ ├── mdxConflicts.ts # detectMdxConflictBundle /
|
|
313
|
+
│ ├── mdxConflicts.ts # detectMdxConflictBundle / computeDiffsForAllSources
|
|
272
314
|
│ ├── mdxRules.ts # Built-in canonicalization rules
|
|
273
315
|
│ ├── tableMdx.ts # Table parsing / canonicalization
|
|
274
316
|
│ └── sharedProcessor.ts # Shared remark processor
|
|
@@ -276,6 +318,8 @@ src/
|
|
|
276
318
|
│ └── jsonConflicts.ts # detectJsonConflictBundle / flattenTokenAnchors / extractJsonSourceKey
|
|
277
319
|
└── utils/
|
|
278
320
|
├── canonicalCache.ts # In-memory canonical result cache (sha256)
|
|
321
|
+
├── entityKey.ts # parseGroupKey — shared entity key parsing for MDX and JSON
|
|
322
|
+
├── fingerprint.ts # computeFingerprintV1 — entity-level fingerprint
|
|
279
323
|
└── frontmatter.ts # Frontmatter parsing helpers
|
|
280
324
|
```
|
|
281
325
|
|
package/dist/analyzer.d.ts
CHANGED
|
@@ -1,29 +1,21 @@
|
|
|
1
1
|
import type { Logger } from '@knapsack/adapter-core';
|
|
2
|
-
import type { SourceConflictsConfig } from './types.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
bundle: ConflictBundle;
|
|
8
|
-
/** Frontmatter sourceKey URI of the baseline source (e.g. "knapsack://patterns/button"). */
|
|
9
|
-
baselineSourceKey: string;
|
|
10
|
-
/** Frontmatter sourceKey URIs of the compare sources. */
|
|
11
|
-
compareSourceKeys: string[];
|
|
12
|
-
verdicts: AnchorVerdictView[];
|
|
13
|
-
};
|
|
14
|
-
export type SourceConflictsAnalysisResult = {
|
|
15
|
-
groupResults: ConflictGroupResult[];
|
|
16
|
-
/** Groups that were skipped (non-MDX or not enough sources). */
|
|
17
|
-
skippedGroupKeys: string[];
|
|
2
|
+
import type { SourceConflictsConfig, ConflictBundle, SourceConflictsAnalysisResult, ConflictReport } from './types.js';
|
|
3
|
+
export type RunOptions = SourceConflictsConfig & {
|
|
4
|
+
readonly logger: Logger;
|
|
5
|
+
/** When provided, the report JSON is written to this path. */
|
|
6
|
+
readonly outputPath?: string;
|
|
18
7
|
};
|
|
19
8
|
export declare function analyze(config: SourceConflictsConfig, deps: Pick<{
|
|
20
9
|
logger: Logger;
|
|
21
10
|
}, 'logger'>): Promise<SourceConflictsAnalysisResult>;
|
|
22
11
|
/**
|
|
23
|
-
* Returns the source keys present in a stored bundle.
|
|
24
|
-
*
|
|
25
|
-
* `computeVerdictsForBaselineCompare` without re-running detection.
|
|
26
|
-
* Sources in `bundle.excludedSourceKeys` are NOT available.
|
|
12
|
+
* Returns the source keys of all sources present in a stored bundle.
|
|
13
|
+
* Useful for inspecting which sources contributed to a previously detected conflict.
|
|
27
14
|
*/
|
|
28
15
|
export declare function getAvailableSourceKeysFromBundle(bundle: ConflictBundle): string[];
|
|
16
|
+
/**
|
|
17
|
+
* Scan an entities directory, detect all conflicts, and return a structured report.
|
|
18
|
+
* Optionally writes the report as JSON to outputPath.
|
|
19
|
+
*/
|
|
20
|
+
export declare function run(options: RunOptions): Promise<ConflictReport>;
|
|
29
21
|
//# sourceMappingURL=analyzer.d.ts.map
|
package/dist/analyzer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EACV,qBAAqB,EACrB,cAAc,EAEd,6BAA6B,EAC7B,cAAc,EAEf,MAAM,YAAY,CAAC;AAQpB,MAAM,MAAM,UAAU,GAAG,qBAAqB,GAAG;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,8DAA8D;IAC9D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,wBAAsB,OAAO,CAC3B,MAAM,EAAE,qBAAqB,EAC7B,IAAI,EAAE,IAAI,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,QAAQ,CAAC,GACvC,OAAO,CAAC,6BAA6B,CAAC,CAiDxC;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,cAAc,GACrB,MAAM,EAAE,CAEV;AAED;;;GAGG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CAkCtE"}
|
package/dist/analyzer.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
1
2
|
import { indexEntitiesDir, findConflictGroups } from './detect.js';
|
|
2
|
-
import { detectMdxConflictBundle,
|
|
3
|
+
import { detectMdxConflictBundle, computeDiffsForAllSources, } from './mdx/mdxConflicts.js';
|
|
3
4
|
import { detectJsonConflictBundle } from './json/jsonConflicts.js';
|
|
4
5
|
export async function analyze(config, deps) {
|
|
5
6
|
const { logger } = deps;
|
|
@@ -14,20 +15,15 @@ export async function analyze(config, deps) {
|
|
|
14
15
|
skippedGroupKeys.push(group.key);
|
|
15
16
|
continue;
|
|
16
17
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (sources.length < 1 + MIN_COMPARE_SOURCES) {
|
|
18
|
+
// Require at least 2 distinct source types. No upper limit — all sources are compared equally.
|
|
19
|
+
const uniqueSources = new Set(group.artifacts.map((a) => a.sourceType));
|
|
20
|
+
if (uniqueSources.size < 2) {
|
|
21
21
|
skippedGroupKeys.push(group.key);
|
|
22
22
|
continue;
|
|
23
23
|
}
|
|
24
|
-
const baselineSourceKey = sources[0];
|
|
25
|
-
const compareSourceKeys = sources.slice(1, 1 + MAX_COMPARE_SOURCES);
|
|
26
24
|
const detectArgs = {
|
|
27
25
|
groupKey: group.key,
|
|
28
26
|
artifacts: group.artifacts,
|
|
29
|
-
baselineSourceKey,
|
|
30
|
-
compareSourceKeys,
|
|
31
27
|
siteId: config.siteId,
|
|
32
28
|
userId: config.userId,
|
|
33
29
|
configId: config.configId,
|
|
@@ -40,28 +36,48 @@ export async function analyze(config, deps) {
|
|
|
40
36
|
skippedGroupKeys.push(group.key);
|
|
41
37
|
continue;
|
|
42
38
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const baselineUri = getUri(baselineSourceKey);
|
|
46
|
-
const compareUris = compareSourceKeys.map(getUri);
|
|
47
|
-
const verdicts = computeVerdictsForBaselineCompare(bundle, baselineUri, compareUris);
|
|
48
|
-
groupResults.push({
|
|
49
|
-
group,
|
|
50
|
-
bundle,
|
|
51
|
-
baselineSourceKey: baselineUri,
|
|
52
|
-
compareSourceKeys: compareUris,
|
|
53
|
-
verdicts,
|
|
54
|
-
});
|
|
39
|
+
const anchors = computeDiffsForAllSources(bundle);
|
|
40
|
+
groupResults.push({ group, bundle, anchors });
|
|
55
41
|
}
|
|
56
42
|
return { groupResults, skippedGroupKeys };
|
|
57
43
|
}
|
|
58
44
|
/**
|
|
59
|
-
* Returns the source keys present in a stored bundle.
|
|
60
|
-
*
|
|
61
|
-
* `computeVerdictsForBaselineCompare` without re-running detection.
|
|
62
|
-
* Sources in `bundle.excludedSourceKeys` are NOT available.
|
|
45
|
+
* Returns the source keys of all sources present in a stored bundle.
|
|
46
|
+
* Useful for inspecting which sources contributed to a previously detected conflict.
|
|
63
47
|
*/
|
|
64
48
|
export function getAvailableSourceKeysFromBundle(bundle) {
|
|
65
49
|
return bundle.items.map((item) => item.sourceKey);
|
|
66
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Scan an entities directory, detect all conflicts, and return a structured report.
|
|
53
|
+
* Optionally writes the report as JSON to outputPath.
|
|
54
|
+
*/
|
|
55
|
+
export async function run(options) {
|
|
56
|
+
const { logger, outputPath, ...config } = options;
|
|
57
|
+
const { groupResults } = await analyze(config, { logger });
|
|
58
|
+
const entities = groupResults.map(({ group, bundle, anchors }) => ({
|
|
59
|
+
entityKey: group.key,
|
|
60
|
+
entityType: group.entityType,
|
|
61
|
+
entityRelPath: group.relPath,
|
|
62
|
+
sources: bundle.items.map((i) => i.sourceKey).sort(),
|
|
63
|
+
conflicts: anchors,
|
|
64
|
+
}));
|
|
65
|
+
const allConflicts = entities.flatMap((e) => e.conflicts);
|
|
66
|
+
const report = {
|
|
67
|
+
generatedAt: new Date().toISOString(),
|
|
68
|
+
entitiesRootAbs: config.entitiesRootAbs,
|
|
69
|
+
entities,
|
|
70
|
+
summary: {
|
|
71
|
+
conflictingEntityCount: entities.length,
|
|
72
|
+
totalConflicts: allConflicts.length,
|
|
73
|
+
differentCount: allConflicts.filter((c) => c.verdict === 'DIFFERENT')
|
|
74
|
+
.length,
|
|
75
|
+
missingCount: allConflicts.filter((c) => c.verdict === 'MISSING').length,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
if (outputPath) {
|
|
79
|
+
await fs.writeFile(outputPath, JSON.stringify(report, null, 2), 'utf8');
|
|
80
|
+
}
|
|
81
|
+
return report;
|
|
82
|
+
}
|
|
67
83
|
//# sourceMappingURL=analyzer.js.map
|
package/dist/analyzer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
|
package/dist/analyzer.vitest.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { getAvailableSourceKeysFromBundle } from './analyzer.js';
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import { getAvailableSourceKeysFromBundle, run } from './analyzer.js';
|
|
3
|
+
vi.mock('./detect.js', () => ({
|
|
4
|
+
indexEntitiesDir: vi.fn().mockResolvedValue([]),
|
|
5
|
+
findConflictGroups: vi.fn().mockReturnValue([]),
|
|
6
|
+
}));
|
|
3
7
|
function makeBundle(items) {
|
|
4
8
|
return {
|
|
5
9
|
conflict: {
|
|
@@ -14,6 +18,31 @@ function makeBundle(items) {
|
|
|
14
18
|
anchorDefinitions: [],
|
|
15
19
|
};
|
|
16
20
|
}
|
|
21
|
+
const silentLogger = {
|
|
22
|
+
debug: () => { },
|
|
23
|
+
info: () => { },
|
|
24
|
+
warn: () => { },
|
|
25
|
+
error: () => { },
|
|
26
|
+
};
|
|
27
|
+
describe('run() summary', () => {
|
|
28
|
+
it('returns zero counts when there are no conflicting groups', async () => {
|
|
29
|
+
const report = await run({
|
|
30
|
+
entitiesRootAbs: '/fake/entities',
|
|
31
|
+
logger: silentLogger,
|
|
32
|
+
});
|
|
33
|
+
expect(report.summary.conflictingEntityCount).toBe(0);
|
|
34
|
+
expect(report.summary.totalConflicts).toBe(0);
|
|
35
|
+
expect(report.summary.differentCount).toBe(0);
|
|
36
|
+
expect(report.summary.missingCount).toBe(0);
|
|
37
|
+
});
|
|
38
|
+
it('totalConflicts equals differentCount + missingCount', async () => {
|
|
39
|
+
const report = await run({
|
|
40
|
+
entitiesRootAbs: '/fake/entities',
|
|
41
|
+
logger: silentLogger,
|
|
42
|
+
});
|
|
43
|
+
expect(report.summary.totalConflicts).toBe(report.summary.differentCount + report.summary.missingCount);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
17
46
|
describe('getAvailableSourceKeysFromBundle', () => {
|
|
18
47
|
it('returns URI sourceKeys for all items in the bundle', () => {
|
|
19
48
|
const bundle = makeBundle([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.vitest.js","sourceRoot":"","sources":["../src/analyzer.vitest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"analyzer.vitest.js","sourceRoot":"","sources":["../src/analyzer.vitest.ts"],"names":[],"mappings":"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"}
|
package/dist/detect.d.ts
CHANGED
|
@@ -2,10 +2,10 @@ import type { Logger } from '@knapsack/adapter-core';
|
|
|
2
2
|
import type { ArtifactRef, ConflictGroup } from './types.js';
|
|
3
3
|
export type { ArtifactRef, ConflictGroup } from './types.js';
|
|
4
4
|
/**
|
|
5
|
-
* Index filesystem artifacts by (
|
|
5
|
+
* Index filesystem artifacts by (entityType + canonical relPath).
|
|
6
6
|
*
|
|
7
|
-
* Expected layout: entities/<
|
|
8
|
-
* Same entity = same
|
|
7
|
+
* Expected layout: entities/<entityType>/<base>.<sourceType>-<hash>.<ext>
|
|
8
|
+
* Same entity = same entityType + same base name (e.g. button.react.mdx or button.react.md);
|
|
9
9
|
* sourceType and hash are read from the filename.
|
|
10
10
|
*/
|
|
11
11
|
export declare function indexEntitiesDir(entitiesRootAbs: string, logger: Logger): Promise<Map<string, ArtifactRef[]>>;
|
package/dist/detect.js
CHANGED
|
@@ -32,18 +32,18 @@ function parseArtifactFilename(filename) {
|
|
|
32
32
|
const hash = sourceTypeHash.slice(dashIdx + 1);
|
|
33
33
|
if (!rawSourceType || !hash)
|
|
34
34
|
return null;
|
|
35
|
-
const
|
|
36
|
-
if (!
|
|
35
|
+
const sourceType = parseSourceType(rawSourceType);
|
|
36
|
+
if (!sourceType)
|
|
37
37
|
return null;
|
|
38
38
|
const base = parts.join('.');
|
|
39
39
|
const relPath = `${base}.${ext}`;
|
|
40
|
-
return { relPath,
|
|
40
|
+
return { relPath, sourceType, hash };
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
|
-
* Index filesystem artifacts by (
|
|
43
|
+
* Index filesystem artifacts by (entityType + canonical relPath).
|
|
44
44
|
*
|
|
45
|
-
* Expected layout: entities/<
|
|
46
|
-
* Same entity = same
|
|
45
|
+
* Expected layout: entities/<entityType>/<base>.<sourceType>-<hash>.<ext>
|
|
46
|
+
* Same entity = same entityType + same base name (e.g. button.react.mdx or button.react.md);
|
|
47
47
|
* sourceType and hash are read from the filename.
|
|
48
48
|
*/
|
|
49
49
|
export async function indexEntitiesDir(entitiesRootAbs, logger) {
|
|
@@ -54,8 +54,8 @@ export async function indexEntitiesDir(entitiesRootAbs, logger) {
|
|
|
54
54
|
for (const etEnt of entityTypeDirs) {
|
|
55
55
|
if (!etEnt.isDirectory())
|
|
56
56
|
continue;
|
|
57
|
-
const
|
|
58
|
-
if (!
|
|
57
|
+
const entityType = parseEntityKind(etEnt.name);
|
|
58
|
+
if (!entityType)
|
|
59
59
|
continue;
|
|
60
60
|
const etDir = path.join(entitiesRootAbs, etEnt.name);
|
|
61
61
|
const files = await walkFiles(etDir);
|
|
@@ -64,10 +64,10 @@ export async function indexEntitiesDir(entitiesRootAbs, logger) {
|
|
|
64
64
|
const parsed = parseArtifactFilename(filename);
|
|
65
65
|
if (!parsed)
|
|
66
66
|
continue;
|
|
67
|
-
const key = `${
|
|
67
|
+
const key = `${entityType}::${parsed.relPath}`;
|
|
68
68
|
const ref = {
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
sourceType: parsed.sourceType,
|
|
70
|
+
entityType,
|
|
71
71
|
relPath: parsed.relPath,
|
|
72
72
|
absPath,
|
|
73
73
|
};
|
|
@@ -88,9 +88,9 @@ export function findConflictGroups(index, logger) {
|
|
|
88
88
|
for (const [key, artifacts] of index.entries()) {
|
|
89
89
|
if (artifacts.length < 2)
|
|
90
90
|
continue;
|
|
91
|
-
// all same
|
|
92
|
-
const {
|
|
93
|
-
conflicts.push({ key,
|
|
91
|
+
// all same entityType/relPath by construction
|
|
92
|
+
const { entityType, relPath } = artifacts[0];
|
|
93
|
+
conflicts.push({ key, entityType, relPath, artifacts });
|
|
94
94
|
}
|
|
95
95
|
conflicts.sort((a, b) => a.key.localeCompare(b.key)); // stable order for deterministic output
|
|
96
96
|
logger.info('Conflict groups', {
|
package/dist/detect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAK9D,KAAK,UAAU,SAAS,CAAC,GAAW;IAClC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/D,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;YACtB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;aAAM,IAAI,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;YACxB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAWD;;;GAGG;AACH,SAAS,qBAAqB,CAC5B,QAAgB;IAEhB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;IACxB,MAAM,cAAc,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;IACnC,IAAI,CAAC,GAAG,IAAI,CAAC,cAAc,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1E,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,aAAa,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IAC/C,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"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"}
|