@untangle-code/context-artifacts 0.0.0-stage → 0.1.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 +661 -0
- package/NOTICE +90 -0
- package/README.md +247 -2
- package/THIRD_PARTY_LICENSES.md +24 -0
- package/dist/adapters/asyncapi.d.ts +20 -0
- package/dist/adapters/asyncapi.d.ts.map +1 -0
- package/dist/adapters/asyncapi.js +95 -0
- package/dist/adapters/asyncapi.js.map +1 -0
- package/dist/adapters/docker.d.ts +43 -0
- package/dist/adapters/docker.d.ts.map +1 -0
- package/dist/adapters/docker.js +97 -0
- package/dist/adapters/docker.js.map +1 -0
- package/dist/adapters/kubernetes.d.ts +22 -0
- package/dist/adapters/kubernetes.d.ts.map +1 -0
- package/dist/adapters/kubernetes.js +56 -0
- package/dist/adapters/kubernetes.js.map +1 -0
- package/dist/adapters/markdown.d.ts +35 -0
- package/dist/adapters/markdown.d.ts.map +1 -0
- package/dist/adapters/markdown.js +36 -0
- package/dist/adapters/markdown.js.map +1 -0
- package/dist/adapters/openapi.d.ts +21 -0
- package/dist/adapters/openapi.d.ts.map +1 -0
- package/dist/adapters/openapi.js +101 -0
- package/dist/adapters/openapi.js.map +1 -0
- package/dist/adapters/protobuf.d.ts +34 -0
- package/dist/adapters/protobuf.d.ts.map +1 -0
- package/dist/adapters/protobuf.js +221 -0
- package/dist/adapters/protobuf.js.map +1 -0
- package/dist/adapters/shared.d.ts +65 -0
- package/dist/adapters/shared.d.ts.map +1 -0
- package/dist/adapters/shared.js +95 -0
- package/dist/adapters/shared.js.map +1 -0
- package/dist/adapters/sql.d.ts +104 -0
- package/dist/adapters/sql.d.ts.map +1 -0
- package/dist/adapters/sql.js +427 -0
- package/dist/adapters/sql.js.map +1 -0
- package/dist/adapters/terraform.d.ts +40 -0
- package/dist/adapters/terraform.d.ts.map +1 -0
- package/dist/adapters/terraform.js +186 -0
- package/dist/adapters/terraform.js.map +1 -0
- package/dist/adapters/text.d.ts +24 -0
- package/dist/adapters/text.d.ts.map +1 -0
- package/dist/adapters/text.js +31 -0
- package/dist/adapters/text.js.map +1 -0
- package/dist/config-validation.d.ts +18 -0
- package/dist/config-validation.d.ts.map +1 -0
- package/dist/config-validation.js +30 -0
- package/dist/config-validation.js.map +1 -0
- package/dist/coverage.d.ts +114 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/coverage.js +0 -0
- package/dist/coverage.js.map +1 -0
- package/dist/ids.d.ts +12 -0
- package/dist/ids.d.ts.map +1 -0
- package/dist/ids.js +42 -0
- package/dist/ids.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/registry.d.ts +51 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +86 -0
- package/dist/registry.js.map +1 -0
- package/dist/staleness.d.ts +44 -0
- package/dist/staleness.d.ts.map +1 -0
- package/dist/staleness.js +35 -0
- package/dist/staleness.js.map +1 -0
- package/dist/text/delimiter-balance.d.ts +95 -0
- package/dist/text/delimiter-balance.d.ts.map +1 -0
- package/dist/text/delimiter-balance.js +209 -0
- package/dist/text/delimiter-balance.js.map +1 -0
- package/dist/text/line-index.d.ts +61 -0
- package/dist/text/line-index.d.ts.map +1 -0
- package/dist/text/line-index.js +75 -0
- package/dist/text/line-index.js.map +1 -0
- package/dist/text/yaml-lite.d.ts +73 -0
- package/dist/text/yaml-lite.d.ts.map +1 -0
- package/dist/text/yaml-lite.js +486 -0
- package/dist/text/yaml-lite.js.map +1 -0
- package/package.json +61 -3
- package/src/adapters/__golden__/adr-0001-sections.json +68 -0
- package/src/adapters/__golden__/app-compose-services.json +24 -0
- package/src/adapters/__golden__/app-image-stages.json +24 -0
- package/src/adapters/__golden__/infra-main-sections.json +46 -0
- package/src/adapters/__golden__/orders-events-operations.json +24 -0
- package/src/adapters/__golden__/orders-proto-sections.json +57 -0
- package/src/adapters/__golden__/orders-schema-statements.json +68 -0
- package/src/adapters/__golden__/users-api-operations.json +46 -0
- package/src/adapters/__golden__/web-manifests-resources.json +24 -0
- package/src/adapters/asyncapi.ts +147 -0
- package/src/adapters/docker.ts +170 -0
- package/src/adapters/kubernetes.ts +103 -0
- package/src/adapters/markdown.ts +88 -0
- package/src/adapters/openapi.ts +156 -0
- package/src/adapters/protobuf.ts +286 -0
- package/src/adapters/shared.ts +151 -0
- package/src/adapters/sql.ts +555 -0
- package/src/adapters/terraform.ts +261 -0
- package/src/adapters/text.ts +72 -0
- package/src/config-validation.ts +41 -0
- package/src/coverage.ts +336 -0
- package/src/ids.ts +57 -0
- package/src/index.ts +105 -0
- package/src/registry.ts +155 -0
- package/src/staleness.ts +69 -0
- package/src/text/delimiter-balance.ts +295 -0
- package/src/text/line-index.ts +108 -0
- package/src/text/yaml-lite.ts +565 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terraform/HCL adapter (architecture.md §20: "Ressourcen, Module,
|
|
3
|
+
* Variablen").
|
|
4
|
+
*
|
|
5
|
+
* Same brace-depth line scanning approach as the Protobuf adapter: a
|
|
6
|
+
* top-level `resource "type" "name" {`, `data "type" "name" {`, `module
|
|
7
|
+
* "name" {`, `variable "name" {`, `output "name" {`, `provider "name" {`,
|
|
8
|
+
* or `locals {` block runs to its matching `}`. Whitespace/comments
|
|
9
|
+
* between blocks are not chunked — `buildArtifactSkipLedger` surfaces
|
|
10
|
+
* those gaps with reason `"whitespace_or_comment"`, never silently.
|
|
11
|
+
*
|
|
12
|
+
* The brace counter skips `"..."` string literals, `#`/`//`/`/* *\/`
|
|
13
|
+
* comments and heredoc bodies (`<<EOT` … `EOT`, WP-118) (WP-81 review, same defect class as the Protobuf adapter's own
|
|
14
|
+
* fix: a `{`/`}` inside a multi-line `/* *\/` comment must never move the
|
|
15
|
+
* depth counter, or it desyncs permanently and "runs to EOF", silently
|
|
16
|
+
* swallowing every following top-level block). `scanLine` carries the
|
|
17
|
+
* open-block-comment state across lines through one continuous scan — the
|
|
18
|
+
* SAME scan that finds block boundaries, not a separate look-ahead with its
|
|
19
|
+
* own independent counter, so there is exactly one source of truth for "is
|
|
20
|
+
* this brace really code right now".
|
|
21
|
+
*
|
|
22
|
+
* KNOWN, UNFIXED gap in the same defect class (documented, not silent):
|
|
23
|
+
* `BLOCK_PATTERNS` match against a full physical LINE (`^\s*keyword...`), so
|
|
24
|
+
* two block openers sharing one physical line (`resource "a" "b" {} module
|
|
25
|
+
* "m" {}`) — valid but extremely unidiomatic HCL that `terraform fmt` would
|
|
26
|
+
* never produce — only detects the first; the second's bytes still land
|
|
27
|
+
* inside the first block's `content` (nothing is dropped from the document,
|
|
28
|
+
* only mis-titled), rather than getting its own chunk. Fixing this fully
|
|
29
|
+
* would need the same byte-precise, sub-line splitting the SQL adapter now
|
|
30
|
+
* uses for multiple statements per line; left as an open issue given how
|
|
31
|
+
* rare well-formed HCL makes this shape.
|
|
32
|
+
*/
|
|
33
|
+
import type { ArtifactAdapter } from "@untangle-code/domain";
|
|
34
|
+
import type { SkipLedgerReporter } from "./shared.js";
|
|
35
|
+
export interface TerraformAdapterOptions {
|
|
36
|
+
/** Overrides how a real skip-ledger finding surfaces from `chunk()` (default: a stderr warning) — see `coverage.ts`'s `SkipLedgerReporter`. */
|
|
37
|
+
onSkipLedgerGap?: SkipLedgerReporter;
|
|
38
|
+
}
|
|
39
|
+
export declare function createTerraformAdapter(options?: TerraformAdapterOptions): ArtifactAdapter;
|
|
40
|
+
//# sourceMappingURL=terraform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terraform.d.ts","sourceRoot":"","sources":["../../src/adapters/terraform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EACV,eAAe,EAKhB,MAAM,uBAAuB,CAAC;AAM/B,OAAO,KAAK,EAAsC,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAyL1F,MAAM,WAAW,uBAAuB;IACtC,+IAA+I;IAC/I,eAAe,CAAC,EAAE,kBAAkB,CAAC;CACtC;AAED,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,eAAe,CA0B7F"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { describeDelimiterImbalances, findDelimiterImbalances } from "../text/delimiter-balance.js";
|
|
2
|
+
import { buildLineIndex, splitLines } from "../text/line-index.js";
|
|
3
|
+
import { buildChunksReportingSkips, buildDocuments } from "./shared.js";
|
|
4
|
+
const TERRAFORM_EXTENSION = /\.(tf|tf\.json|hcl)$/i;
|
|
5
|
+
const BLOCK_PATTERNS = [
|
|
6
|
+
{
|
|
7
|
+
kind: "terraform_resource",
|
|
8
|
+
re: /^\s*resource\s+"([^"]+)"\s+"([^"]+)"\s*\{/,
|
|
9
|
+
title: (m) => `${m[1]}.${m[2]}`,
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
kind: "terraform_data",
|
|
13
|
+
re: /^\s*data\s+"([^"]+)"\s+"([^"]+)"\s*\{/,
|
|
14
|
+
title: (m) => `${m[1]}.${m[2]}`,
|
|
15
|
+
},
|
|
16
|
+
{ kind: "terraform_module", re: /^\s*module\s+"([^"]+)"\s*\{/, title: (m) => m[1] },
|
|
17
|
+
{ kind: "terraform_variable", re: /^\s*variable\s+"([^"]+)"\s*\{/, title: (m) => m[1] },
|
|
18
|
+
{ kind: "terraform_output", re: /^\s*output\s+"([^"]+)"\s*\{/, title: (m) => m[1] },
|
|
19
|
+
{ kind: "terraform_provider", re: /^\s*provider\s+"([^"]+)"\s*\{/, title: (m) => m[1] },
|
|
20
|
+
{ kind: "terraform_locals", re: /^\s*locals\s*\{/, title: () => "locals" },
|
|
21
|
+
];
|
|
22
|
+
/**
|
|
23
|
+
* Öffner eines Heredocs (`<<EOT` / `<<-EOT`); die Gruppe ist die Endmarke.
|
|
24
|
+
* Sticky, damit er an einer Position geprüft werden kann, ohne die Zeile zu
|
|
25
|
+
* kopieren.
|
|
26
|
+
*/
|
|
27
|
+
const HEREDOC_OPEN = /<<-?([A-Za-z_][A-Za-z0-9_]*)/y;
|
|
28
|
+
/**
|
|
29
|
+
* Net brace delta for one line, skipping `"..."` string literals and
|
|
30
|
+
* `#`/`//`/`/* *\/` comments. `state.inBlockComment` is mutated for a
|
|
31
|
+
* comment that is still open at the end of this line — the next call for
|
|
32
|
+
* the following line continues from exactly that state. String state is
|
|
33
|
+
* NOT carried across lines: an HCL double-quoted string cannot contain a
|
|
34
|
+
* literal newline (only `\n` escapes), so it is always fully open and
|
|
35
|
+
* closed within one physical line.
|
|
36
|
+
*/
|
|
37
|
+
function scanLine(line, state) {
|
|
38
|
+
// WP-118: Ein Heredoc ist ROHTEXT. Ein `{` in einem eingebetteten
|
|
39
|
+
// Shell-Skript (`user_data = <<-EOT ... EOT`) hat den Klammerzähler
|
|
40
|
+
// bisher dauerhaft verschoben — der laufende Block „lief bis Dateiende"
|
|
41
|
+
// und verschluckte jeden folgenden Top-Level-Block, bei lückenloser
|
|
42
|
+
// Byte-Abdeckung und damit ohne einen einzigen Ledger-Eintrag. Genau
|
|
43
|
+
// dieselbe Blindstelle wie die des SQL-Zerlegers, nur mit anderem
|
|
44
|
+
// Auslöser.
|
|
45
|
+
if (state.heredocTag !== undefined) {
|
|
46
|
+
if (line.trim() === state.heredocTag)
|
|
47
|
+
state.heredocTag = undefined;
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
let delta = 0;
|
|
51
|
+
let inDouble = false;
|
|
52
|
+
for (let i = 0; i < line.length; i += 1) {
|
|
53
|
+
const c = line[i];
|
|
54
|
+
const next = line[i + 1];
|
|
55
|
+
if (state.inBlockComment) {
|
|
56
|
+
if (c === "*" && next === "/") {
|
|
57
|
+
state.inBlockComment = false;
|
|
58
|
+
i += 1;
|
|
59
|
+
}
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (inDouble) {
|
|
63
|
+
if (c === '"' && line[i - 1] !== "\\")
|
|
64
|
+
inDouble = false;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (c === "#" || (c === "/" && next === "/"))
|
|
68
|
+
break; // line comment: rest of the line is never code
|
|
69
|
+
if (c === "/" && next === "*") {
|
|
70
|
+
state.inBlockComment = true;
|
|
71
|
+
i += 1;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (c === '"') {
|
|
75
|
+
inDouble = true;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (c === "<" && next === "<") {
|
|
79
|
+
HEREDOC_OPEN.lastIndex = i;
|
|
80
|
+
const heredoc = HEREDOC_OPEN.exec(line);
|
|
81
|
+
if (heredoc !== null) {
|
|
82
|
+
state.heredocTag = heredoc[1];
|
|
83
|
+
return delta; // alles hinter dem Öffner gehört zum Heredoc-Inhalt
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (c === "{")
|
|
87
|
+
delta += 1;
|
|
88
|
+
else if (c === "}")
|
|
89
|
+
delta -= 1;
|
|
90
|
+
}
|
|
91
|
+
return delta;
|
|
92
|
+
}
|
|
93
|
+
function terraformDrafts(lines) {
|
|
94
|
+
const drafts = [];
|
|
95
|
+
const state = { inBlockComment: false, heredocTag: undefined };
|
|
96
|
+
let depth = 0;
|
|
97
|
+
let pending;
|
|
98
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
99
|
+
const line = lines[i] ?? "";
|
|
100
|
+
if (depth === 0 &&
|
|
101
|
+
pending === undefined &&
|
|
102
|
+
!state.inBlockComment &&
|
|
103
|
+
state.heredocTag === undefined) {
|
|
104
|
+
for (const pattern of BLOCK_PATTERNS) {
|
|
105
|
+
const match = pattern.re.exec(line);
|
|
106
|
+
if (match) {
|
|
107
|
+
pending = { kind: pattern.kind, title: pattern.title(match), startLine: i + 1 };
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
depth += scanLine(line, state);
|
|
113
|
+
if (pending !== undefined && depth === 0) {
|
|
114
|
+
drafts.push({
|
|
115
|
+
kind: pending.kind,
|
|
116
|
+
startLine: pending.startLine,
|
|
117
|
+
endLine: i + 1,
|
|
118
|
+
title: pending.title,
|
|
119
|
+
});
|
|
120
|
+
pending = undefined;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (pending !== undefined) {
|
|
124
|
+
// Unterminated top-level block (malformed source, or a still-open
|
|
125
|
+
// block comment at EOF): degrade to "runs to EOF" rather than dropping
|
|
126
|
+
// it — never silently, see the module doc.
|
|
127
|
+
drafts.push({
|
|
128
|
+
kind: pending.kind,
|
|
129
|
+
startLine: pending.startLine,
|
|
130
|
+
endLine: Math.max(lines.length, pending.startLine),
|
|
131
|
+
title: pending.title,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
return drafts;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Trennzeichen-Konventionen für die Plausibilitätsprüfung (WP-118).
|
|
138
|
+
* Heredocs (`<<EOF` / `<<-EOF`) sind Rohtext: eingebettete Skripte
|
|
139
|
+
* enthalten regelmäßig unpaarige Klammern und Anführungszeichen, die kein
|
|
140
|
+
* Befund sind. Der Prüfer überliest sie deshalb vollständig — und meldet
|
|
141
|
+
* dafür ein Heredoc, dessen Endmarke im Fragment fehlt.
|
|
142
|
+
*/
|
|
143
|
+
const TERRAFORM_SCAN_OPTIONS = {
|
|
144
|
+
quotes: [
|
|
145
|
+
{ open: '"', close: '"', backslashEscapes: true, doubledEscapes: false, spansLines: false },
|
|
146
|
+
],
|
|
147
|
+
brackets: [
|
|
148
|
+
{ open: "{", close: "}" },
|
|
149
|
+
{ open: "(", close: ")" },
|
|
150
|
+
{ open: "[", close: "]" },
|
|
151
|
+
],
|
|
152
|
+
lineComments: ["#", "//"],
|
|
153
|
+
blockComment: { open: "/*", close: "*/" },
|
|
154
|
+
heredocs: "hcl",
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* WP-118 (dieselbe Blindstelle wie in `sql.ts`): ein unabgeschlossener
|
|
158
|
+
* Top-Level-Block wurde bisher still zu „läuft bis Dateiende" degradiert —
|
|
159
|
+
* lückenlose Byte-Abdeckung, kein leerer Chunk, also kein Ledger-Eintrag,
|
|
160
|
+
* obwohl der Klammerzähler nachweislich aus dem Tritt war. Dasselbe gilt
|
|
161
|
+
* für ein Heredoc, dessen `{` den Zähler verschoben hat (der Zähler dieses
|
|
162
|
+
* Adapters kennt Heredocs nicht). Beides ist jetzt ein sichtbarer Befund.
|
|
163
|
+
*/
|
|
164
|
+
const checkTerraformPlausibility = (chunk) => {
|
|
165
|
+
const imbalances = findDelimiterImbalances(chunk.content, TERRAFORM_SCAN_OPTIONS);
|
|
166
|
+
return imbalances.length === 0 ? undefined : describeDelimiterImbalances(imbalances);
|
|
167
|
+
};
|
|
168
|
+
export function createTerraformAdapter(options = {}) {
|
|
169
|
+
return {
|
|
170
|
+
supports(type, path) {
|
|
171
|
+
return type === "terraform" || (type === "auto" && TERRAFORM_EXTENSION.test(path));
|
|
172
|
+
},
|
|
173
|
+
async read(input) {
|
|
174
|
+
return buildDocuments(input, "terraform");
|
|
175
|
+
},
|
|
176
|
+
chunk(document) {
|
|
177
|
+
const { lines } = splitLines(document.content);
|
|
178
|
+
const index = buildLineIndex(document.content);
|
|
179
|
+
return buildChunksReportingSkips(document, index, terraformDrafts(lines), options.onSkipLedgerGap, checkTerraformPlausibility);
|
|
180
|
+
},
|
|
181
|
+
links() {
|
|
182
|
+
return [];
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=terraform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terraform.js","sourceRoot":"","sources":["../../src/adapters/terraform.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic text fallback adapter (spec.md §19.2 "sicherer Text-Fallback";
|
|
3
|
+
* architecture.md §22.2 "Parserfehler degradieren auf Textanalyse").
|
|
4
|
+
*
|
|
5
|
+
* `supports()` matches everything the registry hasn't already routed to a
|
|
6
|
+
* more specific adapter — it is always registered LAST, as the registry's
|
|
7
|
+
* catch-all, so no file is ever left unindexable just because its format
|
|
8
|
+
* has no dedicated adapter (rule 4 / E4: nothing is silently skipped, it
|
|
9
|
+
* is degraded to fixed-size line windows instead).
|
|
10
|
+
*
|
|
11
|
+
* Windows are contiguous and non-overlapping, covering the ENTIRE file —
|
|
12
|
+
* `buildArtifactSkipLedger` reports zero gaps for a text-fallback document,
|
|
13
|
+
* by construction.
|
|
14
|
+
*/
|
|
15
|
+
import type { ArtifactAdapter } from "@untangle-code/domain";
|
|
16
|
+
import type { SkipLedgerReporter } from "./shared.js";
|
|
17
|
+
/** Lines per window — generous enough to keep a chunk's content meaningfully self-contained, small enough to stay embeddable. */
|
|
18
|
+
export declare const TEXT_WINDOW_LINES = 200;
|
|
19
|
+
export interface TextFallbackAdapterOptions {
|
|
20
|
+
/** Overrides how a real skip-ledger finding surfaces from `chunk()` (default: a stderr warning) — see `coverage.ts`'s `SkipLedgerReporter`. Never actually fires here: windows are gapless by construction (see module doc). */
|
|
21
|
+
onSkipLedgerGap?: SkipLedgerReporter;
|
|
22
|
+
}
|
|
23
|
+
export declare function createTextFallbackAdapter(options?: TextFallbackAdapterOptions): ArtifactAdapter;
|
|
24
|
+
//# sourceMappingURL=text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/adapters/text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EACV,eAAe,EAKhB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,KAAK,EAAc,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGlE,iIAAiI;AACjI,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAYrC,MAAM,WAAW,0BAA0B;IACzC,gOAAgO;IAChO,eAAe,CAAC,EAAE,kBAAkB,CAAC;CACtC;AAED,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,0BAA+B,GACvC,eAAe,CAwBjB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { buildLineIndex } from "../text/line-index.js";
|
|
2
|
+
import { buildChunksReportingSkips, buildDocuments } from "./shared.js";
|
|
3
|
+
/** Lines per window — generous enough to keep a chunk's content meaningfully self-contained, small enough to stay embeddable. */
|
|
4
|
+
export const TEXT_WINDOW_LINES = 200;
|
|
5
|
+
function windowDrafts(lineCount) {
|
|
6
|
+
const total = Math.max(lineCount, 1);
|
|
7
|
+
const drafts = [];
|
|
8
|
+
for (let start = 1; start <= total; start += TEXT_WINDOW_LINES) {
|
|
9
|
+
const end = Math.min(start + TEXT_WINDOW_LINES - 1, total);
|
|
10
|
+
drafts.push({ kind: "text_window", startLine: start, endLine: end });
|
|
11
|
+
}
|
|
12
|
+
return drafts;
|
|
13
|
+
}
|
|
14
|
+
export function createTextFallbackAdapter(options = {}) {
|
|
15
|
+
return {
|
|
16
|
+
supports() {
|
|
17
|
+
return true; // catch-all; the registry only reaches this adapter once nothing else claimed the file.
|
|
18
|
+
},
|
|
19
|
+
async read(input) {
|
|
20
|
+
return buildDocuments(input, "text");
|
|
21
|
+
},
|
|
22
|
+
chunk(document) {
|
|
23
|
+
const index = buildLineIndex(document.content);
|
|
24
|
+
return buildChunksReportingSkips(document, index, windowDrafts(index.lineCount), options.onSkipLedgerGap);
|
|
25
|
+
},
|
|
26
|
+
links() {
|
|
27
|
+
return [];
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/adapters/text.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAExE,iIAAiI;AACjI,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAErC,SAAS,YAAY,CAAC,SAAiB;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACrC,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,KAAK,EAAE,KAAK,IAAI,iBAAiB,EAAE,CAAC;QAC/D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,iBAAiB,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;QAC3D,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAOD,MAAM,UAAU,yBAAyB,CACvC,UAAsC,EAAE;IAExC,OAAO;QACL,QAAQ;YACN,OAAO,IAAI,CAAC,CAAC,wFAAwF;QACvG,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,KAAoB;YAC7B,OAAO,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACvC,CAAC;QAED,KAAK,CAAC,QAA0B;YAC9B,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC/C,OAAO,yBAAyB,CAC9B,QAAQ,EACR,KAAK,EACL,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,EAC7B,OAAO,CAAC,eAAe,CACxB,CAAC;QACJ,CAAC;QAED,KAAK;YACH,OAAO,EAAE,CAAC;QACZ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-artifact configuration validation (spec.md §19.2: "Name MUSS
|
|
3
|
+
* projektweit eindeutig sein.").
|
|
4
|
+
*/
|
|
5
|
+
import type { ContextArtifactConfig } from "@untangle-code/domain";
|
|
6
|
+
/**
|
|
7
|
+
* Validates a whole project's `ContextArtifactConfig` list: every `name`
|
|
8
|
+
* must be non-empty and unique across the list (case-sensitive — two
|
|
9
|
+
* artifacts differing only by case are almost certainly a copy/paste bug,
|
|
10
|
+
* and case-insensitive uniqueness would silently reject that legitimate
|
|
11
|
+
* edge case too, so this stays deliberately literal).
|
|
12
|
+
*
|
|
13
|
+
* Throws `UntangleError("CONFIG_INVALID", …)` (rule 8) with every offending
|
|
14
|
+
* name listed in `context.duplicateNames`, not just the first one found, so
|
|
15
|
+
* a single fix-and-rerun cycle can catch everything at once.
|
|
16
|
+
*/
|
|
17
|
+
export declare function validateArtifactConfigs(configs: readonly ContextArtifactConfig[]): void;
|
|
18
|
+
//# sourceMappingURL=config-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-validation.d.ts","sourceRoot":"","sources":["../src/config-validation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAGnE;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,GAAG,IAAI,CAsBvF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { configInvalidError } from "@untangle-code/observability";
|
|
2
|
+
/**
|
|
3
|
+
* Validates a whole project's `ContextArtifactConfig` list: every `name`
|
|
4
|
+
* must be non-empty and unique across the list (case-sensitive — two
|
|
5
|
+
* artifacts differing only by case are almost certainly a copy/paste bug,
|
|
6
|
+
* and case-insensitive uniqueness would silently reject that legitimate
|
|
7
|
+
* edge case too, so this stays deliberately literal).
|
|
8
|
+
*
|
|
9
|
+
* Throws `UntangleError("CONFIG_INVALID", …)` (rule 8) with every offending
|
|
10
|
+
* name listed in `context.duplicateNames`, not just the first one found, so
|
|
11
|
+
* a single fix-and-rerun cycle can catch everything at once.
|
|
12
|
+
*/
|
|
13
|
+
export function validateArtifactConfigs(configs) {
|
|
14
|
+
const seen = new Map();
|
|
15
|
+
const emptyNameCount = configs.filter((config) => config.name.trim().length === 0).length;
|
|
16
|
+
if (emptyNameCount > 0) {
|
|
17
|
+
throw configInvalidError(`${emptyNameCount} context artifact config(s) have an empty "name" (spec.md §19.2 requires a project-wide unique name)`, { context: { emptyNameCount } });
|
|
18
|
+
}
|
|
19
|
+
for (const config of configs) {
|
|
20
|
+
seen.set(config.name, (seen.get(config.name) ?? 0) + 1);
|
|
21
|
+
}
|
|
22
|
+
const duplicateNames = [...seen.entries()]
|
|
23
|
+
.filter(([, count]) => count > 1)
|
|
24
|
+
.map(([name]) => name)
|
|
25
|
+
.sort();
|
|
26
|
+
if (duplicateNames.length > 0) {
|
|
27
|
+
throw configInvalidError(`context artifact name(s) are not project-wide unique (spec.md §19.2): ${duplicateNames.join(", ")}`, { context: { duplicateNames } });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=config-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-validation.js","sourceRoot":"","sources":["../src/config-validation.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElE;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAyC;IAC/E,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAC1F,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,kBAAkB,CACtB,GAAG,cAAc,sGAAsG,EACvH,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,EAAE,CAChC,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;SACvC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC;SAChC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC;SACrB,IAAI,EAAE,CAAC;IACV,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,kBAAkB,CACtB,yEAAyE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACpG,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,EAAE,CAChC,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skip ledger (docs/BUILD_PLAN.md §12 E4: "KEIN stilles Ueberspringen von
|
|
3
|
+
* Inhalt — Skip-Ledger mit Grund").
|
|
4
|
+
*
|
|
5
|
+
* `ArtifactChunk`/`ArtifactAdapter` (architecture.md §20, frozen in
|
|
6
|
+
* `@untangle-code/domain`) carry no ledger field of their own — chunk
|
|
7
|
+
* ranges are the only signal a caller has about what was turned into a
|
|
8
|
+
* searchable chunk. `buildArtifactSkipLedger()` is this package's answer to
|
|
9
|
+
* E4 within that contract: given a document and the chunks an adapter
|
|
10
|
+
* produced for it, it finds every byte range NOT covered by any chunk and
|
|
11
|
+
* returns it as a labeled entry, so a caller (indexer/CLI) can log or
|
|
12
|
+
* surface "artifact X, bytes N..M were not turned into a chunk, because
|
|
13
|
+
* Y" — visibly, with a reason, never silently.
|
|
14
|
+
*
|
|
15
|
+
* A gap is not automatically a defect: whitespace between two SQL
|
|
16
|
+
* statements, or a comment line between two Terraform blocks, is expected
|
|
17
|
+
* and labeled `"whitespace_or_comment"`. A gap that still contains
|
|
18
|
+
* non-trivial content is labeled `"unclassified_content"` — a signal that
|
|
19
|
+
* an adapter's section boundaries missed something real.
|
|
20
|
+
*
|
|
21
|
+
* Byte coverage alone is BLIND to one real defect class (found in review of
|
|
22
|
+
* WP-81): an adapter can produce chunks whose union of byte ranges looks
|
|
23
|
+
* complete while a real section's identity was still lost — e.g. two SQL
|
|
24
|
+
* statements sharing one physical line, where a broken span computation
|
|
25
|
+
* attributed BOTH statements' bytes to the first statement's chunk and then
|
|
26
|
+
* emitted a second, byte-EMPTY chunk for the one that lost its own range.
|
|
27
|
+
* That second chunk carries no gap (there are no uncovered bytes left to
|
|
28
|
+
* report) yet is definitive proof that the adapter detected a section
|
|
29
|
+
* boundary and then failed to capture anything for it — a section was
|
|
30
|
+
* found, not classified.
|
|
31
|
+
*
|
|
32
|
+
* This module cannot re-parse an arbitrary format to notice that kind of
|
|
33
|
+
* loss (coverage.ts is intentionally format-agnostic — it only ever sees
|
|
34
|
+
* `ArtifactChunk[]`, never an adapter's own grammar). What it CAN check,
|
|
35
|
+
* generically and with zero false positives, is the structural invariant
|
|
36
|
+
* every legitimate chunk must satisfy: a non-empty, non-inverted byte range
|
|
37
|
+
* (`range.endByte > range.startByte`), and — when two chunks claim the
|
|
38
|
+
* EXACT same byte range — agreement on what that range even is (same
|
|
39
|
+
* `kind`+`title`; protobuf's intentionally nested service/RPC overlap never
|
|
40
|
+
* trips this, since an RPC's range is a strict sub-range of its service's,
|
|
41
|
+
* never byte-identical to it). Either violation is reported as
|
|
42
|
+
* `"semantic_loss"`: content IS covered by some chunk, but a section the
|
|
43
|
+
* adapter itself tried to carve out was not actually captured or was
|
|
44
|
+
* captured twice with conflicting identities.
|
|
45
|
+
*
|
|
46
|
+
* WP-118 fand die dritte Blindstelle derselben Familie: nichts fehlt,
|
|
47
|
+
* nichts ist leer, nichts überlappt — aber ein Fragment ist MITTEN DURCH
|
|
48
|
+
* ein Konstrukt geschnitten (die SQL-Zerlegung zerriss ein Statement an
|
|
49
|
+
* einem Semikolon INNERHALB einer Zeichenkette). Das kann dieses Modul
|
|
50
|
+
* nicht selbst erkennen, weil ihm dafür die Konventionen des Formats
|
|
51
|
+
* fehlen. Es nimmt sie deshalb als Rückruf entgegen:
|
|
52
|
+
* `buildArtifactSkipLedger(document, chunks, { checkPlausibility })`
|
|
53
|
+
* meldet jedes so beanstandete Fragment als `"implausible_fragment"`.
|
|
54
|
+
* Die Adapter reichen ihre eigene Prüfung über
|
|
55
|
+
* `adapters/shared.ts::buildChunksReportingSkips` herein, damit auch das
|
|
56
|
+
* keine Bringschuld des Aufrufers wird (E4).
|
|
57
|
+
*/
|
|
58
|
+
import type { ArtifactChunk, ArtifactDocument, SourceRange } from "@untangle-code/domain";
|
|
59
|
+
export type ArtifactSkipReason = "whitespace_or_comment" | "unclassified_content" | "semantic_loss" | "implausible_fragment";
|
|
60
|
+
export interface ArtifactSkipLedgerEntry {
|
|
61
|
+
artifactName: string;
|
|
62
|
+
/** "/"-normalized document path. */
|
|
63
|
+
path: string;
|
|
64
|
+
range: SourceRange;
|
|
65
|
+
reason: ArtifactSkipReason;
|
|
66
|
+
/** First 200 chars of the skipped content, for a human reviewing the ledger. */
|
|
67
|
+
contentPreview: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Callback invoked with the actionable (non-`"whitespace_or_comment"`)
|
|
71
|
+
* entries of a document's skip ledger, from the NORMAL `chunk()` path (see
|
|
72
|
+
* `adapters/shared.ts`'s `buildChunksReportingSkips` — every built-in
|
|
73
|
+
* adapter's `chunk()` goes through it, so this fires without a caller ever
|
|
74
|
+
* having to call `buildArtifactSkipLedger` separately, BUILD_PLAN §12 E4).
|
|
75
|
+
*/
|
|
76
|
+
export type SkipLedgerReporter = (entries: readonly ArtifactSkipLedgerEntry[], document: ArtifactDocument) => void;
|
|
77
|
+
/**
|
|
78
|
+
* Default `SkipLedgerReporter`: one JSON-lines-shaped warning per entry on
|
|
79
|
+
* `stderr`. Deliberately dependency-free (no `@untangle-code/observability`
|
|
80
|
+
* `Logger` — that requires an injected `Clock` and isn't available to a
|
|
81
|
+
* bare `create*Adapter()` factory call) so a loss is visible out of the box;
|
|
82
|
+
* a caller with a real structured logger passes its own `onSkipLedgerGap`
|
|
83
|
+
* to any `create*Adapter()`/`createArtifactAdapterRegistry()` instead.
|
|
84
|
+
*/
|
|
85
|
+
export declare const defaultSkipLedgerReporter: SkipLedgerReporter;
|
|
86
|
+
/**
|
|
87
|
+
* Prüft EIN fertiges Fragment auf Sinnhaftigkeit und liefert bei einem
|
|
88
|
+
* Befund den Begründungstext, sonst `undefined` (WP-118).
|
|
89
|
+
*
|
|
90
|
+
* Byte-Abdeckung beantwortet nur „fehlt etwas?"; sie ist blind dafür, ob
|
|
91
|
+
* ein Fragment an einer sinnvollen Stelle endet. Genau diese zweite Frage
|
|
92
|
+
* kann `coverage.ts` nicht selbst beantworten — sie braucht die
|
|
93
|
+
* Konventionen des jeweiligen Formats. Der zuständige Adapter reicht sie
|
|
94
|
+
* deshalb als Funktion herein (`adapters/sql.ts`, `adapters/protobuf.ts`,
|
|
95
|
+
* `adapters/terraform.ts` nutzen dafür `text/delimiter-balance.ts`),
|
|
96
|
+
* während dieses Modul format-agnostisch bleibt.
|
|
97
|
+
*/
|
|
98
|
+
export type ChunkPlausibilityCheck = (chunk: ArtifactChunk) => string | undefined;
|
|
99
|
+
export interface ArtifactSkipLedgerOptions {
|
|
100
|
+
/** Siehe {@link ChunkPlausibilityCheck}. Ohne diese Option verhält sich der Ledger wie vor WP-118. */
|
|
101
|
+
readonly checkPlausibility?: ChunkPlausibilityCheck;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Finds every byte range of `document.content` not covered by any of
|
|
105
|
+
* `chunks`' ranges and returns one labeled ledger entry per gap.
|
|
106
|
+
*
|
|
107
|
+
* Overlapping/out-of-order chunk ranges (e.g. Protobuf's intentionally
|
|
108
|
+
* overlapping service/RPC chunks, see the protobuf adapter's
|
|
109
|
+
* "Entscheidungen" entry) are handled correctly: ranges are merged before
|
|
110
|
+
* gaps are computed, so an RPC chunk nested inside its service chunk never
|
|
111
|
+
* produces a spurious gap either side of it.
|
|
112
|
+
*/
|
|
113
|
+
export declare function buildArtifactSkipLedger(document: ArtifactDocument, chunks: readonly ArtifactChunk[], options?: ArtifactSkipLedgerOptions): ArtifactSkipLedgerEntry[];
|
|
114
|
+
//# sourceMappingURL=coverage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAI1F,MAAM,MAAM,kBAAkB,GAC5B,uBAAuB,GAAG,sBAAsB,GAAG,eAAe,GAAG,sBAAsB,CAAC;AAE9F,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,gFAAgF;IAChF,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAC/B,OAAO,EAAE,SAAS,uBAAuB,EAAE,EAC3C,QAAQ,EAAE,gBAAgB,KACvB,IAAI,CAAC;AAEV;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,EAAE,kBAcvC,CAAC;AAqBF;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,MAAM,GAAG,SAAS,CAAC;AAElF,MAAM,WAAW,yBAAyB;IACxC,sGAAsG;IACtG,QAAQ,CAAC,iBAAiB,CAAC,EAAE,sBAAsB,CAAC;CACrD;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,OAAO,GAAE,yBAA8B,GACtC,uBAAuB,EAAE,CAgD3B"}
|
package/dist/coverage.js
ADDED
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":"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"}
|
package/dist/ids.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ArtifactChunkIdInput {
|
|
2
|
+
artifactName: string;
|
|
3
|
+
/** "/"-normalized document path (as carried on `ArtifactDocument.path`). */
|
|
4
|
+
documentPath: string;
|
|
5
|
+
/** Semantic chunk kind, e.g. "sql_table", "markdown_section". */
|
|
6
|
+
kind: string;
|
|
7
|
+
/** 0-based position among this document's chunks, so equal-kind chunks never collide. */
|
|
8
|
+
ordinal: number;
|
|
9
|
+
}
|
|
10
|
+
/** Deterministic `ArtifactChunk.chunkId` (see module doc). */
|
|
11
|
+
export declare function buildArtifactChunkId(input: ArtifactChunkIdInput): string;
|
|
12
|
+
//# sourceMappingURL=ids.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,yFAAyF;IACzF,OAAO,EAAE,MAAM,CAAC;CACjB;AAWD,8DAA8D;AAC9D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAkBxE"}
|
package/dist/ids.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic `ArtifactChunk.chunkId` derivation.
|
|
3
|
+
*
|
|
4
|
+
* `packages/domain/src/identity.ts` defines one `buildXId` helper per ID
|
|
5
|
+
* kind from spec.md §5, but `ArtifactChunk` (architecture.md §20) is an
|
|
6
|
+
* Untangle-decision shape with no spec.md §5 identity formula of its own —
|
|
7
|
+
* domain deliberately leaves it to this package (see README
|
|
8
|
+
* "Entscheidungen"). This mirrors `buildChunkId`'s approach exactly: a
|
|
9
|
+
* `uuidv5` under the shared Untangle namespace, over a kind-tagged,
|
|
10
|
+
* unit-separator-joined component list, so a re-chunk of unchanged input
|
|
11
|
+
* reproduces the exact same id (stable across index runs) while chunk ids
|
|
12
|
+
* from different artifacts/documents/kinds can never collide.
|
|
13
|
+
*
|
|
14
|
+
* No `Date.now()`/`Math.random()` anywhere — pure function of its inputs
|
|
15
|
+
* (rule 5).
|
|
16
|
+
*/
|
|
17
|
+
import { ID_COMPONENT_SEPARATOR, uuidv5 } from "@untangle-code/domain";
|
|
18
|
+
function assertNonEmpty(value, label) {
|
|
19
|
+
if (value.length === 0) {
|
|
20
|
+
throw new Error(`buildArtifactChunkId: "${label}" must not be empty`);
|
|
21
|
+
}
|
|
22
|
+
if (value.includes(ID_COMPONENT_SEPARATOR)) {
|
|
23
|
+
throw new Error(`buildArtifactChunkId: "${label}" must not contain the U+001F separator`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Deterministic `ArtifactChunk.chunkId` (see module doc). */
|
|
27
|
+
export function buildArtifactChunkId(input) {
|
|
28
|
+
assertNonEmpty(input.artifactName, "artifactName");
|
|
29
|
+
assertNonEmpty(input.documentPath, "documentPath");
|
|
30
|
+
assertNonEmpty(input.kind, "kind");
|
|
31
|
+
if (!Number.isInteger(input.ordinal) || input.ordinal < 0) {
|
|
32
|
+
throw new Error(`buildArtifactChunkId: ordinal must be a non-negative integer, got ${input.ordinal}`);
|
|
33
|
+
}
|
|
34
|
+
return uuidv5([
|
|
35
|
+
"artifact_chunk",
|
|
36
|
+
input.artifactName,
|
|
37
|
+
input.documentPath,
|
|
38
|
+
input.kind,
|
|
39
|
+
String(input.ordinal),
|
|
40
|
+
].join(ID_COMPONENT_SEPARATOR));
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=ids.js.map
|
package/dist/ids.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAYvE,SAAS,cAAc,CAAC,KAAa,EAAE,KAAa;IAClD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,qBAAqB,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,yCAAyC,CAAC,CAAC;IAC5F,CAAC;AACH,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,oBAAoB,CAAC,KAA2B;IAC9D,cAAc,CAAC,KAAK,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IACnD,cAAc,CAAC,KAAK,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IACnD,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,qEAAqE,KAAK,CAAC,OAAO,EAAE,CACrF,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CACX;QACE,gBAAgB;QAChB,KAAK,CAAC,YAAY;QAClB,KAAK,CAAC,YAAY;QAClB,KAAK,CAAC,IAAI;QACV,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;KACtB,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAC/B,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @untangle-code/context-artifacts — the ONLY public export of this
|
|
3
|
+
* package.
|
|
4
|
+
*
|
|
5
|
+
* `createArtifactAdapterRegistry()` returns an `ArtifactAdapter`
|
|
6
|
+
* (`@untangle-code/domain` `ports.ts`, architecture.md §20) that dispatches
|
|
7
|
+
* to one of the built-in format adapters — Markdown/ADR, SQL schema,
|
|
8
|
+
* OpenAPI, AsyncAPI, Protobuf, Terraform/HCL, Kubernetes YAML, Docker/
|
|
9
|
+
* Compose — or the safe generic text fallback. Individual `create*Adapter()`
|
|
10
|
+
* factories are exported too, both for direct golden-testing (one per
|
|
11
|
+
* adapter, see each `src/adapters/*.test.ts`) and so a caller who only
|
|
12
|
+
* needs one format can skip the registry entirely.
|
|
13
|
+
*
|
|
14
|
+
* Also exported: cross-artifact config validation (`validateArtifactConfigs`,
|
|
15
|
+
* spec.md §19.2's project-wide unique name requirement), staleness
|
|
16
|
+
* snapshotting (`computeArtifactStalenessSnapshot`/`isArtifactStale`,
|
|
17
|
+
* spec.md §19.2's "config hash + content hash"), and the skip ledger
|
|
18
|
+
* (`buildArtifactSkipLedger`, BUILD_PLAN §12 E4) — see README.md
|
|
19
|
+
* "Entscheidungen" for why these last two exist as this package's own
|
|
20
|
+
* derived utilities rather than domain port additions.
|
|
21
|
+
*/
|
|
22
|
+
export type { ArtifactAdapterRegistry, ArtifactAdapterRegistryOptions } from "./registry.js";
|
|
23
|
+
export { createArtifactAdapterRegistry } from "./registry.js";
|
|
24
|
+
export type { MarkdownAdapterOptions } from "./adapters/markdown.js";
|
|
25
|
+
export { createMarkdownAdapter } from "./adapters/markdown.js";
|
|
26
|
+
export type { SqlAdapterOptions, SqlDialect } from "./adapters/sql.js";
|
|
27
|
+
export { createSqlAdapter, DEFAULT_SQL_DIALECT } from "./adapters/sql.js";
|
|
28
|
+
export type { OpenApiAdapterOptions } from "./adapters/openapi.js";
|
|
29
|
+
export { createOpenApiAdapter } from "./adapters/openapi.js";
|
|
30
|
+
export type { AsyncApiAdapterOptions } from "./adapters/asyncapi.js";
|
|
31
|
+
export { createAsyncApiAdapter } from "./adapters/asyncapi.js";
|
|
32
|
+
export type { ProtobufAdapterOptions } from "./adapters/protobuf.js";
|
|
33
|
+
export { createProtobufAdapter } from "./adapters/protobuf.js";
|
|
34
|
+
export type { TerraformAdapterOptions } from "./adapters/terraform.js";
|
|
35
|
+
export { createTerraformAdapter } from "./adapters/terraform.js";
|
|
36
|
+
export type { KubernetesAdapterOptions } from "./adapters/kubernetes.js";
|
|
37
|
+
export { createKubernetesAdapter } from "./adapters/kubernetes.js";
|
|
38
|
+
export type { DockerAdapterOptions } from "./adapters/docker.js";
|
|
39
|
+
export { createDockerAdapter } from "./adapters/docker.js";
|
|
40
|
+
export type { TextFallbackAdapterOptions } from "./adapters/text.js";
|
|
41
|
+
export { createTextFallbackAdapter, TEXT_WINDOW_LINES } from "./adapters/text.js";
|
|
42
|
+
export { validateArtifactConfigs } from "./config-validation.js";
|
|
43
|
+
export type { ArtifactStalenessSnapshot } from "./staleness.js";
|
|
44
|
+
export { computeArtifactConfigHash, computeArtifactContentHash, computeArtifactStalenessSnapshot, isArtifactStale, } from "./staleness.js";
|
|
45
|
+
export type { ArtifactSkipLedgerEntry, ArtifactSkipLedgerOptions, ArtifactSkipReason, ChunkPlausibilityCheck, SkipLedgerReporter, } from "./coverage.js";
|
|
46
|
+
export { buildArtifactSkipLedger, defaultSkipLedgerReporter } from "./coverage.js";
|
|
47
|
+
export { buildArtifactChunkId } from "./ids.js";
|
|
48
|
+
export type { ArtifactChunkIdInput } from "./ids.js";
|
|
49
|
+
export type { LineIndex } from "./text/line-index.js";
|
|
50
|
+
export { buildLineIndex, rangeForLines, sliceBytes, sliceLines, splitLines, } from "./text/line-index.js";
|
|
51
|
+
export type { BlockCommentRule, BracketRule, DelimiterImbalance, DelimiterImbalanceKind, DelimiterScanOptions, HeredocStyle, QuoteRule, } from "./text/delimiter-balance.js";
|
|
52
|
+
export { describeDelimiterImbalances, findDelimiterImbalances } from "./text/delimiter-balance.js";
|
|
53
|
+
export type { YamlDocumentSpan, YamlMapEntry, YamlNode, YamlScalarValue, } from "./text/yaml-lite.js";
|
|
54
|
+
export { YamlParseError, mapGet, parseYamlNode, scalarString, splitYamlDocuments, } from "./text/yaml-lite.js";
|
|
55
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,YAAY,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAC;AAC7F,OAAO,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AAE9D,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC1E,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,YAAY,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,YAAY,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAElF,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,YAAY,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,gCAAgC,EAChC,eAAe,GAChB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,uBAAuB,EACvB,yBAAyB,EACzB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAEnF,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,YAAY,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAKrD,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EACL,cAAc,EACd,aAAa,EACb,UAAU,EACV,UAAU,EACV,UAAU,GACX,MAAM,sBAAsB,CAAC;AAI9B,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,YAAY,EACZ,SAAS,GACV,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAInG,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,QAAQ,EACR,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,cAAc,EACd,MAAM,EACN,aAAa,EACb,YAAY,EACZ,kBAAkB,GACnB,MAAM,qBAAqB,CAAC"}
|