@mitre/hdf-diff 3.0.1 → 3.1.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +55 -0
- package/README.md +49 -17
- package/dist/index.d.ts +622 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2037 -18
- package/dist/index.js.map +1 -1
- package/package.json +19 -19
- package/dist/diff.d.ts +0 -49
- package/dist/diff.d.ts.map +0 -1
- package/dist/diff.js +0 -791
- package/dist/diff.js.map +0 -1
- package/dist/exit-codes.d.ts +0 -42
- package/dist/exit-codes.d.ts.map +0 -1
- package/dist/exit-codes.js +0 -74
- package/dist/exit-codes.js.map +0 -1
- package/dist/matching/cci-match.d.ts +0 -14
- package/dist/matching/cci-match.d.ts.map +0 -1
- package/dist/matching/cci-match.js +0 -102
- package/dist/matching/cci-match.js.map +0 -1
- package/dist/matching/exact-id.d.ts +0 -9
- package/dist/matching/exact-id.d.ts.map +0 -1
- package/dist/matching/exact-id.js +0 -88
- package/dist/matching/exact-id.js.map +0 -1
- package/dist/matching/fuzzy-match.d.ts +0 -26
- package/dist/matching/fuzzy-match.d.ts.map +0 -1
- package/dist/matching/fuzzy-match.js +0 -145
- package/dist/matching/fuzzy-match.js.map +0 -1
- package/dist/matching/index.d.ts +0 -36
- package/dist/matching/index.d.ts.map +0 -1
- package/dist/matching/index.js +0 -71
- package/dist/matching/index.js.map +0 -1
- package/dist/matching/mapped-id.d.ts +0 -13
- package/dist/matching/mapped-id.d.ts.map +0 -1
- package/dist/matching/mapped-id.js +0 -101
- package/dist/matching/mapped-id.js.map +0 -1
- package/dist/matching/types.d.ts +0 -34
- package/dist/matching/types.d.ts.map +0 -1
- package/dist/matching/types.js +0 -2
- package/dist/matching/types.js.map +0 -1
- package/dist/normalize.d.ts +0 -20
- package/dist/normalize.d.ts.map +0 -1
- package/dist/normalize.js +0 -120
- package/dist/normalize.js.map +0 -1
- package/dist/renderers/csv.d.ts +0 -15
- package/dist/renderers/csv.d.ts.map +0 -1
- package/dist/renderers/csv.js +0 -77
- package/dist/renderers/csv.js.map +0 -1
- package/dist/renderers/filter.d.ts +0 -11
- package/dist/renderers/filter.d.ts.map +0 -1
- package/dist/renderers/filter.js +0 -29
- package/dist/renderers/filter.js.map +0 -1
- package/dist/renderers/index.d.ts +0 -17
- package/dist/renderers/index.d.ts.map +0 -1
- package/dist/renderers/index.js +0 -29
- package/dist/renderers/index.js.map +0 -1
- package/dist/renderers/json.d.ts +0 -13
- package/dist/renderers/json.d.ts.map +0 -1
- package/dist/renderers/json.js +0 -41
- package/dist/renderers/json.js.map +0 -1
- package/dist/renderers/markdown.d.ts +0 -13
- package/dist/renderers/markdown.d.ts.map +0 -1
- package/dist/renderers/markdown.js +0 -133
- package/dist/renderers/markdown.js.map +0 -1
- package/dist/renderers/terminal.d.ts +0 -14
- package/dist/renderers/terminal.d.ts.map +0 -1
- package/dist/renderers/terminal.js +0 -173
- package/dist/renderers/terminal.js.map +0 -1
- package/dist/renderers/types.d.ts +0 -12
- package/dist/renderers/types.d.ts.map +0 -1
- package/dist/renderers/types.js +0 -2
- package/dist/renderers/types.js.map +0 -1
- package/dist/sbom.d.ts +0 -42
- package/dist/sbom.d.ts.map +0 -1
- package/dist/sbom.js +0 -203
- package/dist/sbom.js.map +0 -1
- package/dist/status.d.ts +0 -27
- package/dist/status.d.ts.map +0 -1
- package/dist/status.js +0 -137
- package/dist/status.js.map +0 -1
- package/dist/summary.d.ts +0 -6
- package/dist/summary.d.ts.map +0 -1
- package/dist/summary.js +0 -47
- package/dist/summary.js.map +0 -1
- package/dist/types.d.ts +0 -208
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/validate.d.ts +0 -20
- package/dist/validate.d.ts.map +0 -1
- package/dist/validate.js +0 -19
- package/dist/validate.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/matching/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAiB,MAAM,YAAY,CAAC;AAO7D,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEzF;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAqBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAClC,OAAO,CAAC,EAAE,YAAY,GACrB,WAAW,CAmCb"}
|
package/dist/matching/index.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { createExactIdStrategy } from './exact-id.js';
|
|
2
|
-
import { createMappedIdStrategy } from './mapped-id.js';
|
|
3
|
-
import { createCciMatchStrategy } from './cci-match.js';
|
|
4
|
-
import { createFuzzyTitleStrategy } from './fuzzy-match.js';
|
|
5
|
-
export { createExactIdStrategy } from './exact-id.js';
|
|
6
|
-
export { createMappedIdStrategy } from './mapped-id.js';
|
|
7
|
-
export { createCciMatchStrategy } from './cci-match.js';
|
|
8
|
-
export { createFuzzyTitleStrategy, tokenize, jaccardSimilarity } from './fuzzy-match.js';
|
|
9
|
-
/**
|
|
10
|
-
* Create a strategy instance by name, using the provided options for
|
|
11
|
-
* strategies that require configuration.
|
|
12
|
-
*/
|
|
13
|
-
function createStrategy(name, options) {
|
|
14
|
-
switch (name) {
|
|
15
|
-
case 'exactId':
|
|
16
|
-
return createExactIdStrategy();
|
|
17
|
-
case 'mappedId':
|
|
18
|
-
return createMappedIdStrategy(options.mappingTable ?? {});
|
|
19
|
-
case 'cciMatch':
|
|
20
|
-
return createCciMatchStrategy();
|
|
21
|
-
case 'fuzzyTitle':
|
|
22
|
-
return createFuzzyTitleStrategy(options.minConfidence);
|
|
23
|
-
default:
|
|
24
|
-
throw new Error(`Unknown matching strategy: '${name}'`);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Match requirements between two evaluations using a primary strategy
|
|
29
|
-
* and optional fallback strategies.
|
|
30
|
-
*
|
|
31
|
-
* The registry applies strategies in order:
|
|
32
|
-
* 1. Primary strategy matches what it can
|
|
33
|
-
* 2. Unmatched requirements pass to the next fallback strategy
|
|
34
|
-
* 3. Process continues until all strategies are exhausted or all
|
|
35
|
-
* requirements are matched
|
|
36
|
-
*
|
|
37
|
-
* @param oldReqs Requirements from the old evaluation
|
|
38
|
-
* @param newReqs Requirements from the new evaluation
|
|
39
|
-
* @param options Matching configuration
|
|
40
|
-
* @returns Combined match result from all strategies
|
|
41
|
-
*/
|
|
42
|
-
export function matchRequirements(oldReqs, newReqs, options) {
|
|
43
|
-
const opts = options ?? {};
|
|
44
|
-
const primaryName = opts.strategy ?? 'exactId';
|
|
45
|
-
const fallbackNames = opts.fallbackStrategies ?? [];
|
|
46
|
-
// Build all strategy instances once up front (also validates names —
|
|
47
|
-
// createStrategy throws for unknown strategy names).
|
|
48
|
-
const allNames = [primaryName, ...fallbackNames];
|
|
49
|
-
const strategies = allNames.map((name) => createStrategy(name, opts));
|
|
50
|
-
// Accumulate all matched pairs
|
|
51
|
-
const allMatched = [];
|
|
52
|
-
// Start with all requirements unmatched
|
|
53
|
-
let currentUnmatchedOld = oldReqs;
|
|
54
|
-
let currentUnmatchedNew = newReqs;
|
|
55
|
-
// Apply strategies in order
|
|
56
|
-
for (const strategy of strategies) {
|
|
57
|
-
if (currentUnmatchedOld.length === 0 || currentUnmatchedNew.length === 0) {
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
60
|
-
const result = strategy.match(currentUnmatchedOld, currentUnmatchedNew);
|
|
61
|
-
allMatched.push(...result.matched);
|
|
62
|
-
currentUnmatchedOld = result.unmatchedOld;
|
|
63
|
-
currentUnmatchedNew = result.unmatchedNew;
|
|
64
|
-
}
|
|
65
|
-
return {
|
|
66
|
-
matched: allMatched,
|
|
67
|
-
unmatchedOld: currentUnmatchedOld,
|
|
68
|
-
unmatchedNew: currentUnmatchedNew,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/matching/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAI5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAgBzF;;;GAGG;AACH,SAAS,cAAc,CAAC,IAAY,EAAE,OAAqB;IACzD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,SAAS;YACZ,OAAO,qBAAqB,EAAE,CAAC;QACjC,KAAK,UAAU;YACb,OAAO,sBAAsB,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,UAAU;YACb,OAAO,sBAAsB,EAAE,CAAC;QAClC,KAAK,YAAY;YACf,OAAO,wBAAwB,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACzD;YACE,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,GAAG,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAkC,EAClC,OAAkC,EAClC,OAAsB;IAEtB,MAAM,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC;IAC3B,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC;IAC/C,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,IAAI,EAAE,CAAC;IAEpD,qEAAqE;IACrE,qDAAqD;IACrD,MAAM,QAAQ,GAAG,CAAC,WAAW,EAAE,GAAG,aAAa,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAEtE,+BAA+B;IAC/B,MAAM,UAAU,GAA2B,EAAE,CAAC;IAE9C,wCAAwC;IACxC,IAAI,mBAAmB,GAAG,OAAO,CAAC;IAClC,IAAI,mBAAmB,GAAG,OAAO,CAAC;IAElC,4BAA4B;IAC5B,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;QAClC,IAAI,mBAAmB,CAAC,MAAM,KAAK,CAAC,IAAI,mBAAmB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzE,MAAM;QACR,CAAC;QAED,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAC;QAExE,UAAU,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QACnC,mBAAmB,GAAG,MAAM,CAAC,YAAY,CAAC;QAC1C,mBAAmB,GAAG,MAAM,CAAC,YAAY,CAAC;IAC5C,CAAC;IAED,OAAO;QACL,OAAO,EAAE,UAAU;QACnB,YAAY,EAAE,mBAAmB;QACjC,YAAY,EAAE,mBAAmB;KAClC,CAAC;AACJ,CAAC"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { MatchStrategy } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Create a mapped ID matching strategy.
|
|
4
|
-
*
|
|
5
|
-
* Translates old requirement IDs using a mapping table before matching.
|
|
6
|
-
* Only matches requirements whose old ID appears in the mapping table and
|
|
7
|
-
* whose mapped new ID exists in the new requirements.
|
|
8
|
-
*
|
|
9
|
-
* Confidence is 0.95 for mapped matches (slightly less than exact ID
|
|
10
|
-
* because the match depends on the accuracy of the mapping table).
|
|
11
|
-
*/
|
|
12
|
-
export declare function createMappedIdStrategy(mapping: Record<string, string>): MatchStrategy;
|
|
13
|
-
//# sourceMappingURL=mapped-id.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mapped-id.d.ts","sourceRoot":"","sources":["../../src/matching/mapped-id.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,YAAY,CAAC;AAE7D;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,aAAa,CA8FrF"}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Create a mapped ID matching strategy.
|
|
3
|
-
*
|
|
4
|
-
* Translates old requirement IDs using a mapping table before matching.
|
|
5
|
-
* Only matches requirements whose old ID appears in the mapping table and
|
|
6
|
-
* whose mapped new ID exists in the new requirements.
|
|
7
|
-
*
|
|
8
|
-
* Confidence is 0.95 for mapped matches (slightly less than exact ID
|
|
9
|
-
* because the match depends on the accuracy of the mapping table).
|
|
10
|
-
*/
|
|
11
|
-
export function createMappedIdStrategy(mapping) {
|
|
12
|
-
return {
|
|
13
|
-
name: 'mappedId',
|
|
14
|
-
match(oldReqs, newReqs) {
|
|
15
|
-
const result = {
|
|
16
|
-
matched: [],
|
|
17
|
-
unmatchedOld: [],
|
|
18
|
-
unmatchedNew: [],
|
|
19
|
-
};
|
|
20
|
-
// Build a map of new requirements by id, detecting duplicates.
|
|
21
|
-
// When multiple requirements share the same ID, the ID is ambiguous
|
|
22
|
-
// and cannot be used for matching — all duplicates go to unmatchedNew.
|
|
23
|
-
const newById = new Map();
|
|
24
|
-
const duplicateNewIds = new Set();
|
|
25
|
-
for (const req of newReqs) {
|
|
26
|
-
const id = req['id'];
|
|
27
|
-
if (typeof id === 'string') {
|
|
28
|
-
if (newById.has(id)) {
|
|
29
|
-
duplicateNewIds.add(id);
|
|
30
|
-
newById.delete(id);
|
|
31
|
-
}
|
|
32
|
-
else if (!duplicateNewIds.has(id)) {
|
|
33
|
-
newById.set(id, req);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
// Build a map of old requirements by id, detecting duplicates.
|
|
38
|
-
const oldById = new Map();
|
|
39
|
-
const duplicateOldIds = new Set();
|
|
40
|
-
for (const req of oldReqs) {
|
|
41
|
-
const id = req['id'];
|
|
42
|
-
if (typeof id === 'string') {
|
|
43
|
-
if (oldById.has(id)) {
|
|
44
|
-
duplicateOldIds.add(id);
|
|
45
|
-
oldById.delete(id);
|
|
46
|
-
}
|
|
47
|
-
else if (!duplicateOldIds.has(id)) {
|
|
48
|
-
oldById.set(id, req);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
// Track which new reqs have been matched
|
|
53
|
-
const matchedNewIds = new Set();
|
|
54
|
-
// Try to match old requirements using the mapping table (skip duplicate old IDs)
|
|
55
|
-
for (const oldReq of oldReqs) {
|
|
56
|
-
const oldId = oldReq['id'];
|
|
57
|
-
if (typeof oldId !== 'string' || duplicateOldIds.has(oldId)) {
|
|
58
|
-
result.unmatchedOld.push(oldReq);
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
const mappedNewId = mapping[oldId];
|
|
62
|
-
if (mappedNewId === undefined) {
|
|
63
|
-
result.unmatchedOld.push(oldReq);
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
// Skip if the mapped new ID is a duplicate
|
|
67
|
-
if (duplicateNewIds.has(mappedNewId)) {
|
|
68
|
-
result.unmatchedOld.push(oldReq);
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
const newReq = newById.get(mappedNewId);
|
|
72
|
-
if (newReq && !matchedNewIds.has(mappedNewId)) {
|
|
73
|
-
result.matched.push({
|
|
74
|
-
oldReq,
|
|
75
|
-
newReq,
|
|
76
|
-
strategy: 'mappedId',
|
|
77
|
-
confidence: 0.95,
|
|
78
|
-
});
|
|
79
|
-
matchedNewIds.add(mappedNewId);
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
result.unmatchedOld.push(oldReq);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
// Collect unmatched new requirements (including all duplicates)
|
|
86
|
-
for (const req of newReqs) {
|
|
87
|
-
const id = req['id'];
|
|
88
|
-
if (typeof id === 'string') {
|
|
89
|
-
if (duplicateNewIds.has(id) || !matchedNewIds.has(id)) {
|
|
90
|
-
result.unmatchedNew.push(req);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
result.unmatchedNew.push(req);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
return result;
|
|
98
|
-
},
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
//# sourceMappingURL=mapped-id.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mapped-id.js","sourceRoot":"","sources":["../../src/matching/mapped-id.ts"],"names":[],"mappings":"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"}
|
package/dist/matching/types.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Result of matching requirements between two evaluations.
|
|
3
|
-
*/
|
|
4
|
-
export interface MatchResult {
|
|
5
|
-
/** Paired requirements with their match metadata */
|
|
6
|
-
matched: MatchPair[];
|
|
7
|
-
/** Requirements only in the old evaluation (unmatched) */
|
|
8
|
-
unmatchedOld: Record<string, unknown>[];
|
|
9
|
-
/** Requirements only in the new evaluation (unmatched) */
|
|
10
|
-
unmatchedNew: Record<string, unknown>[];
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* A single matched pair of requirements.
|
|
14
|
-
*/
|
|
15
|
-
export interface MatchPair {
|
|
16
|
-
/** The requirement from the old evaluation */
|
|
17
|
-
oldReq: Record<string, unknown>;
|
|
18
|
-
/** The requirement from the new evaluation */
|
|
19
|
-
newReq: Record<string, unknown>;
|
|
20
|
-
/** Name of the strategy that produced this match */
|
|
21
|
-
strategy: string;
|
|
22
|
-
/** Confidence score for the match (0.0 - 1.0) */
|
|
23
|
-
confidence: number;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* A pluggable strategy for matching requirements between evaluations.
|
|
27
|
-
*/
|
|
28
|
-
export interface MatchStrategy {
|
|
29
|
-
/** Unique name for this strategy */
|
|
30
|
-
name: string;
|
|
31
|
-
/** Match old requirements against new requirements */
|
|
32
|
-
match(oldReqs: Record<string, unknown>[], newReqs: Record<string, unknown>[]): MatchResult;
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/matching/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,oDAAoD;IACpD,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACxC,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,WAAW,CAAC;CAC5F"}
|
package/dist/matching/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/matching/types.ts"],"names":[],"mappings":""}
|
package/dist/normalize.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Normalize InSpec exec-json v1 format to HDF v2 structure for diffing.
|
|
3
|
-
*
|
|
4
|
-
* V1 uses: profiles[].controls[].results[].code_desc, source_location, start_time
|
|
5
|
-
* V2 uses: baselines[].requirements[].results[].codeDesc, sourceLocation, startTime
|
|
6
|
-
*
|
|
7
|
-
* This module detects v1 documents and converts them in-memory to v2 shape
|
|
8
|
-
* so the diff engine only needs to handle one format.
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* Detect whether a document is v1 (InSpec exec-json) format.
|
|
12
|
-
* V1 has `profiles` at the top level; v2 has `baselines`.
|
|
13
|
-
*/
|
|
14
|
-
export declare function isV1Format(doc: Record<string, unknown>): boolean;
|
|
15
|
-
/**
|
|
16
|
-
* Normalize a document to v2-like structure. If already v2, returns as-is.
|
|
17
|
-
* If v1, converts profiles→baselines, controls→requirements, and snake_case→camelCase.
|
|
18
|
-
*/
|
|
19
|
-
export declare function normalizeToV2(doc: Record<string, unknown>): Record<string, unknown>;
|
|
20
|
-
//# sourceMappingURL=normalize.d.ts.map
|
package/dist/normalize.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAwCH;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAEhE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgBnF"}
|
package/dist/normalize.js
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Normalize InSpec exec-json v1 format to HDF v2 structure for diffing.
|
|
3
|
-
*
|
|
4
|
-
* V1 uses: profiles[].controls[].results[].code_desc, source_location, start_time
|
|
5
|
-
* V2 uses: baselines[].requirements[].results[].codeDesc, sourceLocation, startTime
|
|
6
|
-
*
|
|
7
|
-
* This module detects v1 documents and converts them in-memory to v2 shape
|
|
8
|
-
* so the diff engine only needs to handle one format.
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* Detect whether a document is v1 (InSpec exec-json) format.
|
|
12
|
-
* V1 has `profiles` at the top level; v2 has `baselines`.
|
|
13
|
-
*/
|
|
14
|
-
export function isV1Format(doc) {
|
|
15
|
-
return Array.isArray(doc['profiles']) && !Array.isArray(doc['baselines']);
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Normalize a document to v2-like structure. If already v2, returns as-is.
|
|
19
|
-
* If v1, converts profiles→baselines, controls→requirements, and snake_case→camelCase.
|
|
20
|
-
*/
|
|
21
|
-
export function normalizeToV2(doc) {
|
|
22
|
-
if (!isV1Format(doc)) {
|
|
23
|
-
return doc;
|
|
24
|
-
}
|
|
25
|
-
const profiles = doc['profiles'];
|
|
26
|
-
const baselines = profiles.map(normalizeProfile);
|
|
27
|
-
// Preserve timestamp from statistics if available
|
|
28
|
-
const statistics = doc['statistics'];
|
|
29
|
-
return {
|
|
30
|
-
baselines,
|
|
31
|
-
statistics,
|
|
32
|
-
timestamp: doc['timestamp'],
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
function normalizeProfile(profile) {
|
|
36
|
-
const controls = profile.controls ?? [];
|
|
37
|
-
const requirements = controls.map(normalizeControl);
|
|
38
|
-
return {
|
|
39
|
-
name: profile.name,
|
|
40
|
-
title: profile.title,
|
|
41
|
-
version: profile.version,
|
|
42
|
-
checksum: profile.sha256 ? { algorithm: 'sha256', value: profile.sha256 } : undefined,
|
|
43
|
-
groups: profile.groups ?? [],
|
|
44
|
-
supports: profile.supports ?? [],
|
|
45
|
-
inputs: profile.attributes ?? [],
|
|
46
|
-
requirements,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
function normalizeControl(control) {
|
|
50
|
-
const v1Results = control.results ?? [];
|
|
51
|
-
const results = v1Results.map(normalizeResult);
|
|
52
|
-
return {
|
|
53
|
-
id: control.id,
|
|
54
|
-
title: control.title,
|
|
55
|
-
descriptions: control.desc
|
|
56
|
-
? [{ label: 'default', data: control.desc }]
|
|
57
|
-
: [],
|
|
58
|
-
impact: control.impact,
|
|
59
|
-
tags: control.tags ?? {},
|
|
60
|
-
refs: control.refs ?? [],
|
|
61
|
-
code: control.code,
|
|
62
|
-
sourceLocation: control.source_location ?? control.sourceLocation,
|
|
63
|
-
results,
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Map InSpec v1 result status values to HDF v2 Result_Status enum values.
|
|
68
|
-
*
|
|
69
|
-
* InSpec v1 uses: "passed", "failed", "skipped", "error"
|
|
70
|
-
* HDF v2 uses: "passed", "failed", "notApplicable", "notReviewed", "error"
|
|
71
|
-
*
|
|
72
|
-
* "skipped" in InSpec means the test was not executed (typically because a
|
|
73
|
-
* `describe.one_of` condition was not met, or `only_if` excluded it).
|
|
74
|
-
* This maps to "notReviewed" in HDF v2 — the requirement was not assessed.
|
|
75
|
-
*/
|
|
76
|
-
function normalizeResultStatus(v1Status) {
|
|
77
|
-
switch (v1Status) {
|
|
78
|
-
case 'skipped':
|
|
79
|
-
return 'notReviewed';
|
|
80
|
-
default:
|
|
81
|
-
return v1Status;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Normalize a timestamp string to RFC 3339 / ISO 8601 date-time format.
|
|
86
|
-
*
|
|
87
|
-
* InSpec v1 uses formats like "2017-09-22 14:12:15 -0400" which are not valid
|
|
88
|
-
* RFC 3339. This function attempts to parse and re-format such timestamps.
|
|
89
|
-
* If parsing fails, the original string is returned as-is.
|
|
90
|
-
*/
|
|
91
|
-
function normalizeTimestamp(timestamp) {
|
|
92
|
-
// Already valid ISO 8601 (contains 'T')
|
|
93
|
-
if (timestamp.includes('T')) {
|
|
94
|
-
return timestamp;
|
|
95
|
-
}
|
|
96
|
-
// Try to parse InSpec format: "YYYY-MM-DD HH:MM:SS +HHMM"
|
|
97
|
-
const parsed = new Date(timestamp);
|
|
98
|
-
if (!isNaN(parsed.getTime())) {
|
|
99
|
-
return parsed.toISOString();
|
|
100
|
-
}
|
|
101
|
-
return timestamp;
|
|
102
|
-
}
|
|
103
|
-
function normalizeResult(result) {
|
|
104
|
-
const rawStartTime = result.start_time ?? result.startTime ?? '';
|
|
105
|
-
const normalized = {
|
|
106
|
-
status: normalizeResultStatus(result.status),
|
|
107
|
-
codeDesc: result.code_desc ?? result.codeDesc ?? '',
|
|
108
|
-
startTime: rawStartTime ? normalizeTimestamp(rawStartTime) : rawStartTime,
|
|
109
|
-
};
|
|
110
|
-
// Only include optional fields when they have values
|
|
111
|
-
const runTime = result.run_time ?? result.runTime;
|
|
112
|
-
if (runTime !== undefined) {
|
|
113
|
-
normalized['runTime'] = runTime;
|
|
114
|
-
}
|
|
115
|
-
if (result.message !== undefined) {
|
|
116
|
-
normalized['message'] = result.message;
|
|
117
|
-
}
|
|
118
|
-
return normalized;
|
|
119
|
-
}
|
|
120
|
-
//# sourceMappingURL=normalize.js.map
|
package/dist/normalize.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"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"}
|
package/dist/renderers/csv.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { HdfComparison } from '../types.js';
|
|
2
|
-
import type { RenderOptions } from './types.js';
|
|
3
|
-
/**
|
|
4
|
-
* Render an HdfComparison as a CSV string.
|
|
5
|
-
*
|
|
6
|
-
* One row per requirement. Columns:
|
|
7
|
-
* - ID, Title, State, Old Status, New Status, Impact (Old), Impact (New), Change Reasons
|
|
8
|
-
*
|
|
9
|
-
* When `detail: 'full'`, an additional Field Changes column is included.
|
|
10
|
-
*
|
|
11
|
-
* Header row is always included. Standard CSV escaping (RFC 4180).
|
|
12
|
-
* Default detail level: `'control'`.
|
|
13
|
-
*/
|
|
14
|
-
export declare function renderCsv(comparison: HdfComparison, options?: RenderOptions): string;
|
|
15
|
-
//# sourceMappingURL=csv.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"csv.d.ts","sourceRoot":"","sources":["../../src/renderers/csv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA+BhD;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CACvB,UAAU,EAAE,aAAa,EACzB,OAAO,CAAC,EAAE,aAAa,GACtB,MAAM,CAyCR"}
|
package/dist/renderers/csv.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { filterRequirements } from './filter.js';
|
|
2
|
-
/**
|
|
3
|
-
* Escape a value for CSV output.
|
|
4
|
-
*
|
|
5
|
-
* Per RFC 4180:
|
|
6
|
-
* - Fields containing commas, double quotes, or newlines are enclosed in double quotes.
|
|
7
|
-
* - Double quotes within a field are escaped by doubling them.
|
|
8
|
-
*/
|
|
9
|
-
function escapeCsvField(value) {
|
|
10
|
-
if (value.includes(',') || value.includes('"') || value.includes('\n') || value.includes('\r')) {
|
|
11
|
-
return `"${value.replace(/"/g, '""')}"`;
|
|
12
|
-
}
|
|
13
|
-
return value;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Format field changes as a human-readable string.
|
|
17
|
-
*/
|
|
18
|
-
function formatFieldChanges(req) {
|
|
19
|
-
if (req.fieldChanges.length === 0)
|
|
20
|
-
return '';
|
|
21
|
-
return req.fieldChanges
|
|
22
|
-
.map((fc) => {
|
|
23
|
-
if (fc.op === 'add')
|
|
24
|
-
return `+${fc.path}: ${JSON.stringify(fc.newValue)}`;
|
|
25
|
-
if (fc.op === 'remove')
|
|
26
|
-
return `-${fc.path}: ${JSON.stringify(fc.oldValue)}`;
|
|
27
|
-
return `${fc.path}: ${JSON.stringify(fc.oldValue)} -> ${JSON.stringify(fc.newValue)}`;
|
|
28
|
-
})
|
|
29
|
-
.join('; ');
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Render an HdfComparison as a CSV string.
|
|
33
|
-
*
|
|
34
|
-
* One row per requirement. Columns:
|
|
35
|
-
* - ID, Title, State, Old Status, New Status, Impact (Old), Impact (New), Change Reasons
|
|
36
|
-
*
|
|
37
|
-
* When `detail: 'full'`, an additional Field Changes column is included.
|
|
38
|
-
*
|
|
39
|
-
* Header row is always included. Standard CSV escaping (RFC 4180).
|
|
40
|
-
* Default detail level: `'control'`.
|
|
41
|
-
*/
|
|
42
|
-
export function renderCsv(comparison, options) {
|
|
43
|
-
const detail = options?.detail ?? 'control';
|
|
44
|
-
const filtered = filterRequirements(comparison.requirementDiffs, options);
|
|
45
|
-
const headers = [
|
|
46
|
-
'ID',
|
|
47
|
-
'Title',
|
|
48
|
-
'State',
|
|
49
|
-
'Old Status',
|
|
50
|
-
'New Status',
|
|
51
|
-
'Impact (Old)',
|
|
52
|
-
'Impact (New)',
|
|
53
|
-
'Change Reasons',
|
|
54
|
-
];
|
|
55
|
-
if (detail === 'full') {
|
|
56
|
-
headers.push('Field Changes');
|
|
57
|
-
}
|
|
58
|
-
const lines = [headers.join(',')];
|
|
59
|
-
for (const req of filtered) {
|
|
60
|
-
const row = [
|
|
61
|
-
escapeCsvField(req.id),
|
|
62
|
-
escapeCsvField(req.title ?? ''),
|
|
63
|
-
escapeCsvField(req.state),
|
|
64
|
-
escapeCsvField(req.oldEffectiveStatus ?? ''),
|
|
65
|
-
escapeCsvField(req.newEffectiveStatus ?? ''),
|
|
66
|
-
escapeCsvField(req.oldImpact !== undefined ? String(req.oldImpact) : ''),
|
|
67
|
-
escapeCsvField(req.newImpact !== undefined ? String(req.newImpact) : ''),
|
|
68
|
-
escapeCsvField(req.changeReasons.join(', ')),
|
|
69
|
-
];
|
|
70
|
-
if (detail === 'full') {
|
|
71
|
-
row.push(escapeCsvField(formatFieldChanges(req)));
|
|
72
|
-
}
|
|
73
|
-
lines.push(row.join(','));
|
|
74
|
-
}
|
|
75
|
-
return lines.join('\n');
|
|
76
|
-
}
|
|
77
|
-
//# sourceMappingURL=csv.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"csv.js","sourceRoot":"","sources":["../../src/renderers/csv.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { RequirementDiff } from '../types.js';
|
|
2
|
-
import type { RenderOptions } from './types.js';
|
|
3
|
-
/**
|
|
4
|
-
* Filter requirement diffs based on render options.
|
|
5
|
-
*
|
|
6
|
-
* Supports filtering by:
|
|
7
|
-
* - `filterStates`: Only include requirements matching the given states
|
|
8
|
-
* - `filterSeverity`: Only include requirements matching the given severity tag
|
|
9
|
-
*/
|
|
10
|
-
export declare function filterRequirements(diffs: RequirementDiff[], options?: RenderOptions): RequirementDiff[];
|
|
11
|
-
//# sourceMappingURL=filter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../src/renderers/filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EAAE,EACxB,OAAO,CAAC,EAAE,aAAa,GACtB,eAAe,EAAE,CAyBnB"}
|
package/dist/renderers/filter.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Filter requirement diffs based on render options.
|
|
3
|
-
*
|
|
4
|
-
* Supports filtering by:
|
|
5
|
-
* - `filterStates`: Only include requirements matching the given states
|
|
6
|
-
* - `filterSeverity`: Only include requirements matching the given severity tag
|
|
7
|
-
*/
|
|
8
|
-
export function filterRequirements(diffs, options) {
|
|
9
|
-
let filtered = diffs;
|
|
10
|
-
if (options?.filterStates && options.filterStates.length > 0) {
|
|
11
|
-
const states = new Set(options.filterStates);
|
|
12
|
-
filtered = filtered.filter((r) => states.has(r.state));
|
|
13
|
-
}
|
|
14
|
-
if (options?.filterSeverity) {
|
|
15
|
-
const severity = options.filterSeverity.toLowerCase();
|
|
16
|
-
filtered = filtered.filter((r) => {
|
|
17
|
-
const before = r.before;
|
|
18
|
-
const after = r.after;
|
|
19
|
-
const tags = after?.['tags'] ??
|
|
20
|
-
before?.['tags'];
|
|
21
|
-
if (!tags)
|
|
22
|
-
return false;
|
|
23
|
-
return (typeof tags['severity'] === 'string' &&
|
|
24
|
-
tags['severity'].toLowerCase() === severity);
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
return filtered;
|
|
28
|
-
}
|
|
29
|
-
//# sourceMappingURL=filter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../src/renderers/filter.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAwB,EACxB,OAAuB;IAEvB,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,IAAI,OAAO,EAAE,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7D,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC7C,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,OAAO,EAAE,cAAc,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC;QACtD,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YAC/B,MAAM,MAAM,GAAG,CAAC,CAAC,MAAwC,CAAC;YAC1D,MAAM,KAAK,GAAG,CAAC,CAAC,KAAuC,CAAC;YACxD,MAAM,IAAI,GACP,KAAK,EAAE,CAAC,MAAM,CAAyC;gBACvD,MAAM,EAAE,CAAC,MAAM,CAAyC,CAAC;YAC5D,IAAI,CAAC,IAAI;gBAAE,OAAO,KAAK,CAAC;YACxB,OAAO,CACL,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,QAAQ;gBACpC,IAAI,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,KAAK,QAAQ,CAC5C,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export { renderJson } from './json.js';
|
|
2
|
-
export { renderMarkdown } from './markdown.js';
|
|
3
|
-
export { renderTerminal } from './terminal.js';
|
|
4
|
-
export { renderCsv } from './csv.js';
|
|
5
|
-
export type { DetailLevel, RenderOptions } from './types.js';
|
|
6
|
-
import type { HdfComparison } from '../types.js';
|
|
7
|
-
import type { RenderOptions } from './types.js';
|
|
8
|
-
/**
|
|
9
|
-
* Convenience function to render a comparison in any supported format.
|
|
10
|
-
*
|
|
11
|
-
* @param comparison - The HdfComparison document to render
|
|
12
|
-
* @param format - Output format: 'json', 'markdown', 'terminal', or 'csv'
|
|
13
|
-
* @param options - Rendering options (detail level, filters, color)
|
|
14
|
-
* @returns The rendered string
|
|
15
|
-
*/
|
|
16
|
-
export declare function render(comparison: HdfComparison, format: 'json' | 'markdown' | 'terminal' | 'csv', options?: RenderOptions): string;
|
|
17
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/renderers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhD;;;;;;;GAOG;AACH,wBAAgB,MAAM,CACpB,UAAU,EAAE,aAAa,EACzB,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,KAAK,EAChD,OAAO,CAAC,EAAE,aAAa,GACtB,MAAM,CAWR"}
|
package/dist/renderers/index.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export { renderJson } from './json.js';
|
|
2
|
-
export { renderMarkdown } from './markdown.js';
|
|
3
|
-
export { renderTerminal } from './terminal.js';
|
|
4
|
-
export { renderCsv } from './csv.js';
|
|
5
|
-
import { renderJson } from './json.js';
|
|
6
|
-
import { renderMarkdown } from './markdown.js';
|
|
7
|
-
import { renderTerminal } from './terminal.js';
|
|
8
|
-
import { renderCsv } from './csv.js';
|
|
9
|
-
/**
|
|
10
|
-
* Convenience function to render a comparison in any supported format.
|
|
11
|
-
*
|
|
12
|
-
* @param comparison - The HdfComparison document to render
|
|
13
|
-
* @param format - Output format: 'json', 'markdown', 'terminal', or 'csv'
|
|
14
|
-
* @param options - Rendering options (detail level, filters, color)
|
|
15
|
-
* @returns The rendered string
|
|
16
|
-
*/
|
|
17
|
-
export function render(comparison, format, options) {
|
|
18
|
-
switch (format) {
|
|
19
|
-
case 'json':
|
|
20
|
-
return renderJson(comparison, options);
|
|
21
|
-
case 'markdown':
|
|
22
|
-
return renderMarkdown(comparison, options);
|
|
23
|
-
case 'terminal':
|
|
24
|
-
return renderTerminal(comparison, options);
|
|
25
|
-
case 'csv':
|
|
26
|
-
return renderCsv(comparison, options);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/renderers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAKrC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC;;;;;;;GAOG;AACH,MAAM,UAAU,MAAM,CACpB,UAAyB,EACzB,MAAgD,EAChD,OAAuB;IAEvB,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM;YACT,OAAO,UAAU,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACzC,KAAK,UAAU;YACb,OAAO,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC7C,KAAK,UAAU;YACb,OAAO,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC7C,KAAK,KAAK;YACR,OAAO,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC"}
|
package/dist/renderers/json.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { HdfComparison } from '../types.js';
|
|
2
|
-
import type { RenderOptions } from './types.js';
|
|
3
|
-
/**
|
|
4
|
-
* Render an HdfComparison as a JSON string.
|
|
5
|
-
*
|
|
6
|
-
* - `detail: 'summary'` -- only `{ formatVersion, comparisonMode, summary }`
|
|
7
|
-
* - `detail: 'control'` -- full document but `before`/`after` stripped from requirementDiffs
|
|
8
|
-
* - `detail: 'full'` -- `JSON.stringify(comparison, null, 2)` (the complete document)
|
|
9
|
-
*
|
|
10
|
-
* Default detail level: `'control'`.
|
|
11
|
-
*/
|
|
12
|
-
export declare function renderJson(comparison: HdfComparison, options?: RenderOptions): string;
|
|
13
|
-
//# sourceMappingURL=json.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/renderers/json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAehD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,aAAa,EACzB,OAAO,CAAC,EAAE,aAAa,GACtB,MAAM,CA0CR"}
|