@sdd-method/sdd-cli 0.10.0 → 0.11.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/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/catalogue/aggregate.d.ts +39 -0
- package/dist/lib/catalogue/aggregate.d.ts.map +1 -0
- package/dist/lib/catalogue/aggregate.js +344 -0
- package/dist/lib/catalogue/aggregate.js.map +1 -0
- package/dist/lib/catalogue/aggregation-manifest-loader.d.ts +25 -0
- package/dist/lib/catalogue/aggregation-manifest-loader.d.ts.map +1 -0
- package/dist/lib/catalogue/aggregation-manifest-loader.js +111 -0
- package/dist/lib/catalogue/aggregation-manifest-loader.js.map +1 -0
- package/dist/lib/catalogue/build.d.ts +42 -0
- package/dist/lib/catalogue/build.d.ts.map +1 -0
- package/dist/lib/catalogue/build.js +373 -0
- package/dist/lib/catalogue/build.js.map +1 -0
- package/dist/lib/catalogue/builders/adr-supersedes.d.ts +14 -0
- package/dist/lib/catalogue/builders/adr-supersedes.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/adr-supersedes.js +62 -0
- package/dist/lib/catalogue/builders/adr-supersedes.js.map +1 -0
- package/dist/lib/catalogue/builders/adrs.d.ts +27 -0
- package/dist/lib/catalogue/builders/adrs.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/adrs.js +191 -0
- package/dist/lib/catalogue/builders/adrs.js.map +1 -0
- package/dist/lib/catalogue/builders/c4-containers.d.ts +16 -0
- package/dist/lib/catalogue/builders/c4-containers.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/c4-containers.js +169 -0
- package/dist/lib/catalogue/builders/c4-containers.js.map +1 -0
- package/dist/lib/catalogue/builders/c4-systems.d.ts +10 -0
- package/dist/lib/catalogue/builders/c4-systems.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/c4-systems.js +99 -0
- package/dist/lib/catalogue/builders/c4-systems.js.map +1 -0
- package/dist/lib/catalogue/builders/capabilities.d.ts +11 -0
- package/dist/lib/catalogue/builders/capabilities.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/capabilities.js +173 -0
- package/dist/lib/catalogue/builders/capabilities.js.map +1 -0
- package/dist/lib/catalogue/builders/capability-edges.d.ts +27 -0
- package/dist/lib/catalogue/builders/capability-edges.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/capability-edges.js +166 -0
- package/dist/lib/catalogue/builders/capability-edges.js.map +1 -0
- package/dist/lib/catalogue/builders/contracts.d.ts +15 -0
- package/dist/lib/catalogue/builders/contracts.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/contracts.js +153 -0
- package/dist/lib/catalogue/builders/contracts.js.map +1 -0
- package/dist/lib/catalogue/builders/domains.d.ts +10 -0
- package/dist/lib/catalogue/builders/domains.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/domains.js +93 -0
- package/dist/lib/catalogue/builders/domains.js.map +1 -0
- package/dist/lib/catalogue/builders/event-edges.d.ts +20 -0
- package/dist/lib/catalogue/builders/event-edges.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/event-edges.js +112 -0
- package/dist/lib/catalogue/builders/event-edges.js.map +1 -0
- package/dist/lib/catalogue/builders/events.d.ts +26 -0
- package/dist/lib/catalogue/builders/events.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/events.js +99 -0
- package/dist/lib/catalogue/builders/events.js.map +1 -0
- package/dist/lib/catalogue/builders/feature-groups.d.ts +10 -0
- package/dist/lib/catalogue/builders/feature-groups.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/feature-groups.js +118 -0
- package/dist/lib/catalogue/builders/feature-groups.js.map +1 -0
- package/dist/lib/catalogue/builders/features.d.ts +35 -0
- package/dist/lib/catalogue/builders/features.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/features.js +206 -0
- package/dist/lib/catalogue/builders/features.js.map +1 -0
- package/dist/lib/catalogue/builders/glossary-xref.d.ts +11 -0
- package/dist/lib/catalogue/builders/glossary-xref.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/glossary-xref.js +107 -0
- package/dist/lib/catalogue/builders/glossary-xref.js.map +1 -0
- package/dist/lib/catalogue/builders/glossary.d.ts +14 -0
- package/dist/lib/catalogue/builders/glossary.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/glossary.js +150 -0
- package/dist/lib/catalogue/builders/glossary.js.map +1 -0
- package/dist/lib/catalogue/builders/index.d.ts +57 -0
- package/dist/lib/catalogue/builders/index.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/index.js +33 -0
- package/dist/lib/catalogue/builders/index.js.map +1 -0
- package/dist/lib/catalogue/builders/integrations.d.ts +12 -0
- package/dist/lib/catalogue/builders/integrations.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/integrations.js +85 -0
- package/dist/lib/catalogue/builders/integrations.js.map +1 -0
- package/dist/lib/catalogue/builders/persona-journey-edges.d.ts +26 -0
- package/dist/lib/catalogue/builders/persona-journey-edges.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/persona-journey-edges.js +133 -0
- package/dist/lib/catalogue/builders/persona-journey-edges.js.map +1 -0
- package/dist/lib/catalogue/builders/personas.d.ts +22 -0
- package/dist/lib/catalogue/builders/personas.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/personas.js +150 -0
- package/dist/lib/catalogue/builders/personas.js.map +1 -0
- package/dist/lib/catalogue/builders/product-edges.d.ts +15 -0
- package/dist/lib/catalogue/builders/product-edges.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/product-edges.js +97 -0
- package/dist/lib/catalogue/builders/product-edges.js.map +1 -0
- package/dist/lib/catalogue/builders/products.d.ts +26 -0
- package/dist/lib/catalogue/builders/products.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/products.js +57 -0
- package/dist/lib/catalogue/builders/products.js.map +1 -0
- package/dist/lib/catalogue/builders/repo-edges.d.ts +18 -0
- package/dist/lib/catalogue/builders/repo-edges.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/repo-edges.js +113 -0
- package/dist/lib/catalogue/builders/repo-edges.js.map +1 -0
- package/dist/lib/catalogue/builders/repositories.d.ts +78 -0
- package/dist/lib/catalogue/builders/repositories.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/repositories.js +204 -0
- package/dist/lib/catalogue/builders/repositories.js.map +1 -0
- package/dist/lib/catalogue/builders/service-contract.d.ts +11 -0
- package/dist/lib/catalogue/builders/service-contract.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/service-contract.js +53 -0
- package/dist/lib/catalogue/builders/service-contract.js.map +1 -0
- package/dist/lib/catalogue/builders/services.d.ts +15 -0
- package/dist/lib/catalogue/builders/services.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/services.js +40 -0
- package/dist/lib/catalogue/builders/services.js.map +1 -0
- package/dist/lib/catalogue/builders/user-journeys.d.ts +24 -0
- package/dist/lib/catalogue/builders/user-journeys.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/user-journeys.js +253 -0
- package/dist/lib/catalogue/builders/user-journeys.js.map +1 -0
- package/dist/lib/catalogue/canonical-schema.yaml +624 -0
- package/dist/lib/catalogue/cli-version.d.ts +10 -0
- package/dist/lib/catalogue/cli-version.d.ts.map +1 -0
- package/dist/lib/catalogue/cli-version.js +10 -0
- package/dist/lib/catalogue/cli-version.js.map +1 -0
- package/dist/lib/catalogue/csv-reader.d.ts +7 -0
- package/dist/lib/catalogue/csv-reader.d.ts.map +1 -0
- package/dist/lib/catalogue/csv-reader.js +97 -0
- package/dist/lib/catalogue/csv-reader.js.map +1 -0
- package/dist/lib/catalogue/csv-writer.d.ts +29 -0
- package/dist/lib/catalogue/csv-writer.d.ts.map +1 -0
- package/dist/lib/catalogue/csv-writer.js +55 -0
- package/dist/lib/catalogue/csv-writer.js.map +1 -0
- package/dist/lib/catalogue/findings.d.ts +27 -0
- package/dist/lib/catalogue/findings.d.ts.map +1 -0
- package/dist/lib/catalogue/findings.js +34 -0
- package/dist/lib/catalogue/findings.js.map +1 -0
- package/dist/lib/catalogue/fk-validator.d.ts +44 -0
- package/dist/lib/catalogue/fk-validator.d.ts.map +1 -0
- package/dist/lib/catalogue/fk-validator.js +90 -0
- package/dist/lib/catalogue/fk-validator.js.map +1 -0
- package/dist/lib/catalogue/index.d.ts +27 -0
- package/dist/lib/catalogue/index.d.ts.map +1 -0
- package/dist/lib/catalogue/index.js +18 -0
- package/dist/lib/catalogue/index.js.map +1 -0
- package/dist/lib/catalogue/manifest-loader.d.ts +47 -0
- package/dist/lib/catalogue/manifest-loader.d.ts.map +1 -0
- package/dist/lib/catalogue/manifest-loader.js +161 -0
- package/dist/lib/catalogue/manifest-loader.js.map +1 -0
- package/dist/lib/catalogue/schema-compat.d.ts +47 -0
- package/dist/lib/catalogue/schema-compat.d.ts.map +1 -0
- package/dist/lib/catalogue/schema-compat.js +52 -0
- package/dist/lib/catalogue/schema-compat.js.map +1 -0
- package/dist/lib/catalogue/schema-loader.d.ts +58 -0
- package/dist/lib/catalogue/schema-loader.d.ts.map +1 -0
- package/dist/lib/catalogue/schema-loader.js +86 -0
- package/dist/lib/catalogue/schema-loader.js.map +1 -0
- package/dist/lib/catalogue/traceability-loader.d.ts +56 -0
- package/dist/lib/catalogue/traceability-loader.d.ts.map +1 -0
- package/dist/lib/catalogue/traceability-loader.js +217 -0
- package/dist/lib/catalogue/traceability-loader.js.map +1 -0
- package/dist/lib/catalogue/validate.d.ts +16 -0
- package/dist/lib/catalogue/validate.d.ts.map +1 -0
- package/dist/lib/catalogue/validate.js +137 -0
- package/dist/lib/catalogue/validate.js.map +1 -0
- package/dist/lib/catalogue/version.d.ts +3 -0
- package/dist/lib/catalogue/version.d.ts.map +1 -0
- package/dist/lib/catalogue/version.js +18 -0
- package/dist/lib/catalogue/version.js.map +1 -0
- package/dist/lib/mcp/build-info.d.ts +1 -1
- package/dist/lib/mcp/build-info.js +1 -1
- package/dist/verbs/catalogue.d.ts +3 -0
- package/dist/verbs/catalogue.d.ts.map +1 -0
- package/dist/verbs/catalogue.js +60 -0
- package/dist/verbs/catalogue.js.map +1 -0
- package/package.json +3 -3
- package/scripts/copy-yaml-assets.mjs +38 -0
- package/scripts/sync-canonical-schema.sh +39 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface ParsedCsv {
|
|
2
|
+
readonly columns: readonly string[];
|
|
3
|
+
readonly rows: readonly Record<string, string>[];
|
|
4
|
+
}
|
|
5
|
+
export declare function readCatalogueCsv(path: string): Promise<ParsedCsv>;
|
|
6
|
+
export declare function parseCatalogueCsv(text: string): ParsedCsv;
|
|
7
|
+
//# sourceMappingURL=csv-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv-reader.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/csv-reader.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;CAClD;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAGvE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAezD"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// CSV reader for catalogue files.
|
|
2
|
+
//
|
|
3
|
+
// RFC-4180-aware: handles `"` quoting (including doubled `""` for literal
|
|
4
|
+
// quotes), commas inside quoted cells, and CR/LF/CRLF line breaks. We
|
|
5
|
+
// don't try to be a general CSV library — the canonical writer's output
|
|
6
|
+
// is the input shape we support, plus tolerance for byte-identical
|
|
7
|
+
// catalogues authored by other conforming aggregator implementations.
|
|
8
|
+
//
|
|
9
|
+
// Headers come from the file's first line; column order is preserved
|
|
10
|
+
// for traceability but row access is by column name.
|
|
11
|
+
import { readFile } from "node:fs/promises";
|
|
12
|
+
export async function readCatalogueCsv(path) {
|
|
13
|
+
const text = await readFile(path, "utf-8");
|
|
14
|
+
return parseCatalogueCsv(text);
|
|
15
|
+
}
|
|
16
|
+
export function parseCatalogueCsv(text) {
|
|
17
|
+
const records = parseRecords(text);
|
|
18
|
+
if (records.length === 0)
|
|
19
|
+
return { columns: [], rows: [] };
|
|
20
|
+
const columns = records[0] ?? [];
|
|
21
|
+
const rows = [];
|
|
22
|
+
for (let r = 1; r < records.length; r++) {
|
|
23
|
+
const record = records[r] ?? [];
|
|
24
|
+
if (record.length === 1 && record[0] === "")
|
|
25
|
+
continue; // empty trailing line
|
|
26
|
+
const row = {};
|
|
27
|
+
for (let c = 0; c < columns.length; c++) {
|
|
28
|
+
row[columns[c] ?? ""] = record[c] ?? "";
|
|
29
|
+
}
|
|
30
|
+
rows.push(row);
|
|
31
|
+
}
|
|
32
|
+
return { columns, rows };
|
|
33
|
+
}
|
|
34
|
+
function parseRecords(text) {
|
|
35
|
+
const records = [];
|
|
36
|
+
let current = [];
|
|
37
|
+
let cell = "";
|
|
38
|
+
let i = 0;
|
|
39
|
+
let inQuotes = false;
|
|
40
|
+
while (i < text.length) {
|
|
41
|
+
const ch = text[i] ?? "";
|
|
42
|
+
if (inQuotes) {
|
|
43
|
+
if (ch === '"') {
|
|
44
|
+
if (text[i + 1] === '"') {
|
|
45
|
+
// Escaped double-quote inside a quoted cell.
|
|
46
|
+
cell += '"';
|
|
47
|
+
i += 2;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
inQuotes = false;
|
|
51
|
+
i++;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
cell += ch;
|
|
55
|
+
i++;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (ch === '"') {
|
|
59
|
+
inQuotes = true;
|
|
60
|
+
i++;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (ch === ",") {
|
|
64
|
+
current.push(cell);
|
|
65
|
+
cell = "";
|
|
66
|
+
i++;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (ch === "\r") {
|
|
70
|
+
if (text[i + 1] === "\n")
|
|
71
|
+
i++;
|
|
72
|
+
current.push(cell);
|
|
73
|
+
records.push(current);
|
|
74
|
+
current = [];
|
|
75
|
+
cell = "";
|
|
76
|
+
i++;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (ch === "\n") {
|
|
80
|
+
current.push(cell);
|
|
81
|
+
records.push(current);
|
|
82
|
+
current = [];
|
|
83
|
+
cell = "";
|
|
84
|
+
i++;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
cell += ch;
|
|
88
|
+
i++;
|
|
89
|
+
}
|
|
90
|
+
// Trailing cell + record.
|
|
91
|
+
if (cell !== "" || current.length > 0) {
|
|
92
|
+
current.push(cell);
|
|
93
|
+
records.push(current);
|
|
94
|
+
}
|
|
95
|
+
return records;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=csv-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv-reader.js","sourceRoot":"","sources":["../../../src/lib/catalogue/csv-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic CSV writer for catalogues.
|
|
3
|
+
*
|
|
4
|
+
* Emits headers + sorted rows per ADR 0134 builder contract:
|
|
5
|
+
* - column order matches the canonical schema exactly,
|
|
6
|
+
* - rows sorted by primary-key value,
|
|
7
|
+
* - cells with embedded comma/quote/newline are RFC-4180 quoted,
|
|
8
|
+
* - empty trailing newline (POSIX convention).
|
|
9
|
+
*
|
|
10
|
+
* Headers-only emission is supported — pass an empty rows array to write
|
|
11
|
+
* a CSV that downstream consumers can rely on the file existence of.
|
|
12
|
+
*/
|
|
13
|
+
import type { CatalogueDef } from "./schema-loader.js";
|
|
14
|
+
/** A row is a map from column name to cell value. Missing keys become empty cells. */
|
|
15
|
+
export type CatalogueRow = Readonly<Record<string, string | number | boolean | null | undefined>>;
|
|
16
|
+
export interface WriteCatalogueOptions {
|
|
17
|
+
/** Absolute path to the output directory (typically `<sdd-root>/catalogues/`). */
|
|
18
|
+
readonly outDir: string;
|
|
19
|
+
/** Catalogue definition driving column order + primary key. */
|
|
20
|
+
readonly catalogue: CatalogueDef;
|
|
21
|
+
/** Rows to emit. Empty array ⇒ headers-only file. */
|
|
22
|
+
readonly rows: readonly CatalogueRow[];
|
|
23
|
+
}
|
|
24
|
+
export declare function writeCatalogue(opts: WriteCatalogueOptions): Promise<{
|
|
25
|
+
rowCount: number;
|
|
26
|
+
path: string;
|
|
27
|
+
}>;
|
|
28
|
+
export declare function renderCatalogueCsv(catalogue: CatalogueDef, rows: readonly CatalogueRow[]): string;
|
|
29
|
+
//# sourceMappingURL=csv-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv-writer.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/csv-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,sFAAsF;AACtF,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC;AAElG,MAAM,WAAW,qBAAqB;IACpC,kFAAkF;IAClF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,SAAS,YAAY,EAAE,CAAC;CACxC;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAO7G;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,SAAS,YAAY,EAAE,GAC5B,MAAM,CAcR"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic CSV writer for catalogues.
|
|
3
|
+
*
|
|
4
|
+
* Emits headers + sorted rows per ADR 0134 builder contract:
|
|
5
|
+
* - column order matches the canonical schema exactly,
|
|
6
|
+
* - rows sorted by primary-key value,
|
|
7
|
+
* - cells with embedded comma/quote/newline are RFC-4180 quoted,
|
|
8
|
+
* - empty trailing newline (POSIX convention).
|
|
9
|
+
*
|
|
10
|
+
* Headers-only emission is supported — pass an empty rows array to write
|
|
11
|
+
* a CSV that downstream consumers can rely on the file existence of.
|
|
12
|
+
*/
|
|
13
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
14
|
+
import { dirname, join } from "node:path";
|
|
15
|
+
export async function writeCatalogue(opts) {
|
|
16
|
+
await mkdir(opts.outDir, { recursive: true });
|
|
17
|
+
const filePath = join(opts.outDir, `${opts.catalogue.name}.csv`);
|
|
18
|
+
const text = renderCatalogueCsv(opts.catalogue, opts.rows);
|
|
19
|
+
await mkdir(dirname(filePath), { recursive: true });
|
|
20
|
+
await writeFile(filePath, text, "utf-8");
|
|
21
|
+
return { rowCount: opts.rows.length, path: filePath };
|
|
22
|
+
}
|
|
23
|
+
export function renderCatalogueCsv(catalogue, rows) {
|
|
24
|
+
const columns = catalogue.columns.map((c) => c.name);
|
|
25
|
+
const lines = [];
|
|
26
|
+
lines.push(columns.map(escapeCell).join(","));
|
|
27
|
+
const sorted = [...rows].sort((a, b) => compareCell(a[catalogue.primaryKey], b[catalogue.primaryKey]));
|
|
28
|
+
for (const row of sorted) {
|
|
29
|
+
const cells = columns.map((col) => escapeCell(formatCell(row[col])));
|
|
30
|
+
lines.push(cells.join(","));
|
|
31
|
+
}
|
|
32
|
+
// Trailing newline per POSIX convention.
|
|
33
|
+
return `${lines.join("\n")}\n`;
|
|
34
|
+
}
|
|
35
|
+
function formatCell(value) {
|
|
36
|
+
if (value === null || value === undefined)
|
|
37
|
+
return "";
|
|
38
|
+
if (typeof value === "boolean")
|
|
39
|
+
return value ? "true" : "false";
|
|
40
|
+
return String(value);
|
|
41
|
+
}
|
|
42
|
+
function escapeCell(value) {
|
|
43
|
+
if (value === "")
|
|
44
|
+
return "";
|
|
45
|
+
if (/[",\n\r]/.test(value)) {
|
|
46
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
47
|
+
}
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
function compareCell(a, b) {
|
|
51
|
+
const sa = a === undefined || a === null ? "" : String(a);
|
|
52
|
+
const sb = b === undefined || b === null ? "" : String(b);
|
|
53
|
+
return sa < sb ? -1 : sa > sb ? 1 : 0;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=csv-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv-writer.js","sourceRoot":"","sources":["../../../src/lib/catalogue/csv-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Findings collector for the canonical builder per ADR 0134 / builder-spec
|
|
3
|
+
* §"Emit findings as it parses".
|
|
4
|
+
*
|
|
5
|
+
* Findings are human-readable AND machine-parseable. Format per finding:
|
|
6
|
+
* [finding] {category}: {one-line summary}
|
|
7
|
+
*
|
|
8
|
+
* Categories are an open set; the canonical catalogue is in the builder
|
|
9
|
+
* spec. This module hardcodes the well-known ones for type safety; new
|
|
10
|
+
* categories may be passed as freeform strings if they emerge.
|
|
11
|
+
*/
|
|
12
|
+
export type FindingCategory = "divergence" | "coverage" | "orphan" | "convention" | "inferred" | "external";
|
|
13
|
+
export interface Finding {
|
|
14
|
+
readonly category: FindingCategory | string;
|
|
15
|
+
readonly summary: string;
|
|
16
|
+
}
|
|
17
|
+
export declare class FindingsLog {
|
|
18
|
+
private readonly findings;
|
|
19
|
+
add(category: FindingCategory | string, summary: string): void;
|
|
20
|
+
/** Returns a copy of recorded findings, in insertion order. */
|
|
21
|
+
all(): readonly Finding[];
|
|
22
|
+
/** Count findings, optionally filtered to a single category. */
|
|
23
|
+
count(category?: FindingCategory | string): number;
|
|
24
|
+
/** Render every finding as a stdout line. */
|
|
25
|
+
render(): string;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=findings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findings.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/findings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,eAAe,GACvB,YAAY,GACZ,UAAU,GACV,QAAQ,GACR,YAAY,GACZ,UAAU,GACV,UAAU,CAAC;AAEf,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAE1C,GAAG,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAI9D,+DAA+D;IAC/D,GAAG,IAAI,SAAS,OAAO,EAAE;IAIzB,gEAAgE;IAChE,KAAK,CAAC,QAAQ,CAAC,EAAE,eAAe,GAAG,MAAM,GAAG,MAAM;IAKlD,6CAA6C;IAC7C,MAAM,IAAI,MAAM;CAKjB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Findings collector for the canonical builder per ADR 0134 / builder-spec
|
|
3
|
+
* §"Emit findings as it parses".
|
|
4
|
+
*
|
|
5
|
+
* Findings are human-readable AND machine-parseable. Format per finding:
|
|
6
|
+
* [finding] {category}: {one-line summary}
|
|
7
|
+
*
|
|
8
|
+
* Categories are an open set; the canonical catalogue is in the builder
|
|
9
|
+
* spec. This module hardcodes the well-known ones for type safety; new
|
|
10
|
+
* categories may be passed as freeform strings if they emerge.
|
|
11
|
+
*/
|
|
12
|
+
export class FindingsLog {
|
|
13
|
+
findings = [];
|
|
14
|
+
add(category, summary) {
|
|
15
|
+
this.findings.push({ category, summary });
|
|
16
|
+
}
|
|
17
|
+
/** Returns a copy of recorded findings, in insertion order. */
|
|
18
|
+
all() {
|
|
19
|
+
return [...this.findings];
|
|
20
|
+
}
|
|
21
|
+
/** Count findings, optionally filtered to a single category. */
|
|
22
|
+
count(category) {
|
|
23
|
+
if (category === undefined)
|
|
24
|
+
return this.findings.length;
|
|
25
|
+
return this.findings.filter((f) => f.category === category).length;
|
|
26
|
+
}
|
|
27
|
+
/** Render every finding as a stdout line. */
|
|
28
|
+
render() {
|
|
29
|
+
return this.findings
|
|
30
|
+
.map((f) => `[finding] ${f.category}: ${f.summary}`)
|
|
31
|
+
.join("\n");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=findings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findings.js","sourceRoot":"","sources":["../../../src/lib/catalogue/findings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAeH,MAAM,OAAO,WAAW;IACL,QAAQ,GAAc,EAAE,CAAC;IAE1C,GAAG,CAAC,QAAkC,EAAE,OAAe;QACrD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,+DAA+D;IAC/D,GAAG;QACD,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IAED,gEAAgE;IAChE,KAAK,CAAC,QAAmC;QACvC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QACxD,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;IACrE,CAAC;IAED,6CAA6C;IAC7C,MAAM;QACJ,OAAO,IAAI,CAAC,QAAQ;aACjB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;aACnD,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FK validator per ADR 0134 builder-spec §"Run internal FK validation
|
|
3
|
+
* before exiting" + §"External FK handling".
|
|
4
|
+
*
|
|
5
|
+
* For each catalogue's foreign keys:
|
|
6
|
+
* - Internal FKs (external=false): every non-empty value MUST resolve
|
|
7
|
+
* to a primary-key in the referenced catalogue's emitted rows. Missing
|
|
8
|
+
* resolution is a hard failure.
|
|
9
|
+
* - External FKs (external=true): every non-empty value is logged as a
|
|
10
|
+
* `[finding] external` line and skipped from validation. The aggregator
|
|
11
|
+
* resolves these post-merge per ADR 0134 §4.5.
|
|
12
|
+
*
|
|
13
|
+
* Returns a structured result; the caller decides exit code + reporting.
|
|
14
|
+
*/
|
|
15
|
+
import type { CanonicalSchema } from "./schema-loader.js";
|
|
16
|
+
import type { CatalogueRow } from "./csv-writer.js";
|
|
17
|
+
import type { FindingsLog } from "./findings.js";
|
|
18
|
+
export interface FkValidationResult {
|
|
19
|
+
readonly internalPass: boolean;
|
|
20
|
+
readonly internalFailures: readonly FkFailure[];
|
|
21
|
+
readonly externalFindings: number;
|
|
22
|
+
}
|
|
23
|
+
export interface FkFailure {
|
|
24
|
+
readonly catalogue: string;
|
|
25
|
+
readonly column: string;
|
|
26
|
+
readonly referencingRow: string;
|
|
27
|
+
readonly value: string;
|
|
28
|
+
readonly target: string;
|
|
29
|
+
}
|
|
30
|
+
export interface FkValidationOptions {
|
|
31
|
+
/**
|
|
32
|
+
* When true, treat FKs declared `external: true` as if they were
|
|
33
|
+
* internal — validate them against own rows and fail on dangling
|
|
34
|
+
* references. Used by the aggregator after merge per ADR 0134 §4.5.
|
|
35
|
+
* Defaults to false.
|
|
36
|
+
*/
|
|
37
|
+
readonly treatExternalAsInternal?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build an in-memory map of every catalogue's primary-key set, then walk
|
|
41
|
+
* every row's FK columns and check resolution.
|
|
42
|
+
*/
|
|
43
|
+
export declare function validateForeignKeys(schema: CanonicalSchema, rowsByCatalogue: ReadonlyMap<string, readonly CatalogueRow[]>, findings: FindingsLog, options?: FkValidationOptions): FkValidationResult;
|
|
44
|
+
//# sourceMappingURL=fk-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fk-validator.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/fk-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,SAAS,SAAS,EAAE,CAAC;IAChD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;CAC5C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,EACvB,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC,EAC7D,QAAQ,EAAE,WAAW,EACrB,OAAO,GAAE,mBAAwB,GAChC,kBAAkB,CAoFpB"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FK validator per ADR 0134 builder-spec §"Run internal FK validation
|
|
3
|
+
* before exiting" + §"External FK handling".
|
|
4
|
+
*
|
|
5
|
+
* For each catalogue's foreign keys:
|
|
6
|
+
* - Internal FKs (external=false): every non-empty value MUST resolve
|
|
7
|
+
* to a primary-key in the referenced catalogue's emitted rows. Missing
|
|
8
|
+
* resolution is a hard failure.
|
|
9
|
+
* - External FKs (external=true): every non-empty value is logged as a
|
|
10
|
+
* `[finding] external` line and skipped from validation. The aggregator
|
|
11
|
+
* resolves these post-merge per ADR 0134 §4.5.
|
|
12
|
+
*
|
|
13
|
+
* Returns a structured result; the caller decides exit code + reporting.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Build an in-memory map of every catalogue's primary-key set, then walk
|
|
17
|
+
* every row's FK columns and check resolution.
|
|
18
|
+
*/
|
|
19
|
+
export function validateForeignKeys(schema, rowsByCatalogue, findings, options = {}) {
|
|
20
|
+
// Index primary keys per catalogue.
|
|
21
|
+
const pkIndex = new Map();
|
|
22
|
+
for (const cat of schema.catalogues) {
|
|
23
|
+
const rows = rowsByCatalogue.get(cat.name) ?? [];
|
|
24
|
+
const pks = new Set();
|
|
25
|
+
for (const row of rows) {
|
|
26
|
+
const pk = row[cat.primaryKey];
|
|
27
|
+
if (pk !== undefined && pk !== null && pk !== "") {
|
|
28
|
+
pks.add(String(pk));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
pkIndex.set(cat.name, pks);
|
|
32
|
+
}
|
|
33
|
+
const failures = [];
|
|
34
|
+
let externalCount = 0;
|
|
35
|
+
for (const cat of schema.catalogues) {
|
|
36
|
+
const rows = rowsByCatalogue.get(cat.name) ?? [];
|
|
37
|
+
for (const fk of cat.foreignKeys) {
|
|
38
|
+
const [targetCat, targetCol] = fk.references.split(".");
|
|
39
|
+
if (!targetCat || !targetCol) {
|
|
40
|
+
throw new Error(`malformed FK reference "${fk.references}" on ${cat.name}.${fk.column}`);
|
|
41
|
+
}
|
|
42
|
+
const targetPks = pkIndex.get(targetCat);
|
|
43
|
+
if (!targetPks) {
|
|
44
|
+
throw new Error(`FK ${cat.name}.${fk.column} references unknown catalogue "${targetCat}"`);
|
|
45
|
+
}
|
|
46
|
+
for (const row of rows) {
|
|
47
|
+
const raw = row[fk.column];
|
|
48
|
+
if (raw === undefined || raw === null || raw === "") {
|
|
49
|
+
if (!fk.nullable && !fk.external) {
|
|
50
|
+
// Required FK with no value — internal violation regardless of external flag.
|
|
51
|
+
failures.push({
|
|
52
|
+
catalogue: cat.name,
|
|
53
|
+
column: fk.column,
|
|
54
|
+
referencingRow: String(row[cat.primaryKey] ?? ""),
|
|
55
|
+
value: "",
|
|
56
|
+
target: fk.references,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const value = String(raw);
|
|
62
|
+
const resolved = targetPks.has(value);
|
|
63
|
+
if (fk.external && !options.treatExternalAsInternal) {
|
|
64
|
+
if (!resolved) {
|
|
65
|
+
// Per spec: optimistically resolve against own rows; only log when unresolved.
|
|
66
|
+
externalCount++;
|
|
67
|
+
findings.add("external", `${cat.name}.${fk.column} → ${fk.references}=${value} ` +
|
|
68
|
+
`(referencing row pk=${row[cat.primaryKey] ?? "?"}; resolves at aggregation)`);
|
|
69
|
+
}
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (!resolved) {
|
|
73
|
+
failures.push({
|
|
74
|
+
catalogue: cat.name,
|
|
75
|
+
column: fk.column,
|
|
76
|
+
referencingRow: String(row[cat.primaryKey] ?? ""),
|
|
77
|
+
value,
|
|
78
|
+
target: fk.references,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
internalPass: failures.length === 0,
|
|
86
|
+
internalFailures: failures,
|
|
87
|
+
externalFindings: externalCount,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=fk-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fk-validator.js","sourceRoot":"","sources":["../../../src/lib/catalogue/fk-validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-exports for the catalogue builder library.
|
|
3
|
+
*
|
|
4
|
+
* Per ADR 0134 §4.6 the canonical builder is a sdd-cli subcommand; this
|
|
5
|
+
* module is its entry point. The verb file at src/verbs/catalogue.ts
|
|
6
|
+
* imports `runCatalogueBuild` from here.
|
|
7
|
+
*/
|
|
8
|
+
export { runCatalogueBuild } from "./build.js";
|
|
9
|
+
export type { BuildInputs, BuildResult } from "./build.js";
|
|
10
|
+
export { runCatalogueAggregate } from "./aggregate.js";
|
|
11
|
+
export type { AggregateInputs, AggregateResult } from "./aggregate.js";
|
|
12
|
+
export { runCatalogueValidate } from "./validate.js";
|
|
13
|
+
export type { ValidateInputs, ValidateResult } from "./validate.js";
|
|
14
|
+
export { runCatalogueVersion } from "./version.js";
|
|
15
|
+
export { SCHEMA_COMPAT, formatSchemaVersionMismatch } from "./schema-compat.js";
|
|
16
|
+
export type { SchemaName } from "./schema-compat.js";
|
|
17
|
+
export { loadCanonicalSchema, VENDORED_SCHEMA_PATH, findCatalogue, runtimeServiceTypes, } from "./schema-loader.js";
|
|
18
|
+
export type { CanonicalSchema, CatalogueDef, ColumnDef, ForeignKeyDef, EnumDef, EnumValueDef, } from "./schema-loader.js";
|
|
19
|
+
export { loadSddManifest, isInRange, MANIFEST_REL_PATH, PROFILES, CATEGORIES, } from "./manifest-loader.js";
|
|
20
|
+
export type { SddManifest, Profile, Category } from "./manifest-loader.js";
|
|
21
|
+
export { renderCatalogueCsv, writeCatalogue } from "./csv-writer.js";
|
|
22
|
+
export type { CatalogueRow } from "./csv-writer.js";
|
|
23
|
+
export { validateForeignKeys } from "./fk-validator.js";
|
|
24
|
+
export type { FkValidationResult, FkFailure } from "./fk-validator.js";
|
|
25
|
+
export { FindingsLog } from "./findings.js";
|
|
26
|
+
export type { Finding, FindingCategory } from "./findings.js";
|
|
27
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAChF,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,eAAe,EACf,YAAY,EACZ,SAAS,EACT,aAAa,EACb,OAAO,EACP,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,UAAU,GACX,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACrE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-exports for the catalogue builder library.
|
|
3
|
+
*
|
|
4
|
+
* Per ADR 0134 §4.6 the canonical builder is a sdd-cli subcommand; this
|
|
5
|
+
* module is its entry point. The verb file at src/verbs/catalogue.ts
|
|
6
|
+
* imports `runCatalogueBuild` from here.
|
|
7
|
+
*/
|
|
8
|
+
export { runCatalogueBuild } from "./build.js";
|
|
9
|
+
export { runCatalogueAggregate } from "./aggregate.js";
|
|
10
|
+
export { runCatalogueValidate } from "./validate.js";
|
|
11
|
+
export { runCatalogueVersion } from "./version.js";
|
|
12
|
+
export { SCHEMA_COMPAT, formatSchemaVersionMismatch } from "./schema-compat.js";
|
|
13
|
+
export { loadCanonicalSchema, VENDORED_SCHEMA_PATH, findCatalogue, runtimeServiceTypes, } from "./schema-loader.js";
|
|
14
|
+
export { loadSddManifest, isInRange, MANIFEST_REL_PATH, PROFILES, CATEGORIES, } from "./manifest-loader.js";
|
|
15
|
+
export { renderCatalogueCsv, writeCatalogue } from "./csv-writer.js";
|
|
16
|
+
export { validateForeignKeys } from "./fk-validator.js";
|
|
17
|
+
export { FindingsLog } from "./findings.js";
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/catalogue/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEhF,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAS5B,OAAO,EACL,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAErE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loader for the per-SDD `.sdd/sdd-manifest.yaml` per the schema at
|
|
3
|
+
* docs/method/methods/sdd-manifest-schema.yaml in sdd-method.
|
|
4
|
+
*
|
|
5
|
+
* Validates schema_version against SCHEMA_COMPAT and the
|
|
6
|
+
* profile↔category invariant from product-category-taxonomy.md.
|
|
7
|
+
*/
|
|
8
|
+
export declare const MANIFEST_REL_PATH = ".sdd/sdd-manifest.yaml";
|
|
9
|
+
export declare const PROFILES: readonly ["platform-profile", "application-product", "integration-product", "support-repo"];
|
|
10
|
+
export type Profile = (typeof PROFILES)[number];
|
|
11
|
+
export declare const CATEGORIES: readonly ["platform-root", "platform-subsystem", "application-product", "integration-provider", "integration-umbrella", "support-repo"];
|
|
12
|
+
export type Category = (typeof CATEGORIES)[number];
|
|
13
|
+
export interface SddManifest {
|
|
14
|
+
readonly schemaVersion: string;
|
|
15
|
+
readonly sddId: string;
|
|
16
|
+
readonly profile: Profile;
|
|
17
|
+
readonly category: Category;
|
|
18
|
+
readonly domainId?: string;
|
|
19
|
+
readonly ecosystemRoot?: string;
|
|
20
|
+
readonly aggregationManifestPath?: string;
|
|
21
|
+
readonly description?: string;
|
|
22
|
+
/** Absolute path the manifest was read from (for error messages). */
|
|
23
|
+
readonly sourcePath: string;
|
|
24
|
+
}
|
|
25
|
+
export interface LoadManifestOptions {
|
|
26
|
+
/** sdd-cli version, used in compat-mismatch error formatting. */
|
|
27
|
+
readonly cliVersion: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Read and validate the `.sdd/sdd-manifest.yaml` at the given SDD repo root.
|
|
31
|
+
*
|
|
32
|
+
* Throws on:
|
|
33
|
+
* - file missing
|
|
34
|
+
* - YAML parse error
|
|
35
|
+
* - shape violation (missing fields, bad enum value, bad slug pattern)
|
|
36
|
+
* - profile↔category invariant violation
|
|
37
|
+
* - schema_version outside SCHEMA_COMPAT.sdd_manifest range
|
|
38
|
+
*/
|
|
39
|
+
export declare function loadSddManifest(sddPath: string, options: LoadManifestOptions): Promise<SddManifest>;
|
|
40
|
+
/**
|
|
41
|
+
* Caret-prefixed semver range check. Accepts X in `^1.2.3` if X.major === 1
|
|
42
|
+
* and X >= 1.2.3.
|
|
43
|
+
*
|
|
44
|
+
* Restricted to the `^X.Y.Z` shape — that's the only form SCHEMA_COMPAT uses.
|
|
45
|
+
*/
|
|
46
|
+
export declare function isInRange(version: string, range: string): boolean;
|
|
47
|
+
//# sourceMappingURL=manifest-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/manifest-loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAE1D,eAAO,MAAM,QAAQ,6FAKX,CAAC;AACX,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhD,eAAO,MAAM,UAAU,yIAOb,CAAC;AACX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAyBnD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,qEAAqE;IACrE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,iEAAiE;IACjE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,WAAW,CAAC,CA2EtB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAejE"}
|