@untangle-code/context-artifacts 0.0.0-stage → 0.1.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.
Files changed (109) hide show
  1. package/LICENSE +661 -0
  2. package/NOTICE +90 -0
  3. package/README.md +247 -2
  4. package/THIRD_PARTY_LICENSES.md +24 -0
  5. package/dist/adapters/asyncapi.d.ts +20 -0
  6. package/dist/adapters/asyncapi.d.ts.map +1 -0
  7. package/dist/adapters/asyncapi.js +95 -0
  8. package/dist/adapters/asyncapi.js.map +1 -0
  9. package/dist/adapters/docker.d.ts +43 -0
  10. package/dist/adapters/docker.d.ts.map +1 -0
  11. package/dist/adapters/docker.js +97 -0
  12. package/dist/adapters/docker.js.map +1 -0
  13. package/dist/adapters/kubernetes.d.ts +22 -0
  14. package/dist/adapters/kubernetes.d.ts.map +1 -0
  15. package/dist/adapters/kubernetes.js +56 -0
  16. package/dist/adapters/kubernetes.js.map +1 -0
  17. package/dist/adapters/markdown.d.ts +35 -0
  18. package/dist/adapters/markdown.d.ts.map +1 -0
  19. package/dist/adapters/markdown.js +36 -0
  20. package/dist/adapters/markdown.js.map +1 -0
  21. package/dist/adapters/openapi.d.ts +21 -0
  22. package/dist/adapters/openapi.d.ts.map +1 -0
  23. package/dist/adapters/openapi.js +101 -0
  24. package/dist/adapters/openapi.js.map +1 -0
  25. package/dist/adapters/protobuf.d.ts +34 -0
  26. package/dist/adapters/protobuf.d.ts.map +1 -0
  27. package/dist/adapters/protobuf.js +221 -0
  28. package/dist/adapters/protobuf.js.map +1 -0
  29. package/dist/adapters/shared.d.ts +65 -0
  30. package/dist/adapters/shared.d.ts.map +1 -0
  31. package/dist/adapters/shared.js +95 -0
  32. package/dist/adapters/shared.js.map +1 -0
  33. package/dist/adapters/sql.d.ts +104 -0
  34. package/dist/adapters/sql.d.ts.map +1 -0
  35. package/dist/adapters/sql.js +427 -0
  36. package/dist/adapters/sql.js.map +1 -0
  37. package/dist/adapters/terraform.d.ts +40 -0
  38. package/dist/adapters/terraform.d.ts.map +1 -0
  39. package/dist/adapters/terraform.js +186 -0
  40. package/dist/adapters/terraform.js.map +1 -0
  41. package/dist/adapters/text.d.ts +24 -0
  42. package/dist/adapters/text.d.ts.map +1 -0
  43. package/dist/adapters/text.js +31 -0
  44. package/dist/adapters/text.js.map +1 -0
  45. package/dist/config-validation.d.ts +18 -0
  46. package/dist/config-validation.d.ts.map +1 -0
  47. package/dist/config-validation.js +30 -0
  48. package/dist/config-validation.js.map +1 -0
  49. package/dist/coverage.d.ts +114 -0
  50. package/dist/coverage.d.ts.map +1 -0
  51. package/dist/coverage.js +0 -0
  52. package/dist/coverage.js.map +1 -0
  53. package/dist/ids.d.ts +12 -0
  54. package/dist/ids.d.ts.map +1 -0
  55. package/dist/ids.js +42 -0
  56. package/dist/ids.js.map +1 -0
  57. package/dist/index.d.ts +55 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +18 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/registry.d.ts +51 -0
  62. package/dist/registry.d.ts.map +1 -0
  63. package/dist/registry.js +86 -0
  64. package/dist/registry.js.map +1 -0
  65. package/dist/staleness.d.ts +44 -0
  66. package/dist/staleness.d.ts.map +1 -0
  67. package/dist/staleness.js +35 -0
  68. package/dist/staleness.js.map +1 -0
  69. package/dist/text/delimiter-balance.d.ts +95 -0
  70. package/dist/text/delimiter-balance.d.ts.map +1 -0
  71. package/dist/text/delimiter-balance.js +209 -0
  72. package/dist/text/delimiter-balance.js.map +1 -0
  73. package/dist/text/line-index.d.ts +61 -0
  74. package/dist/text/line-index.d.ts.map +1 -0
  75. package/dist/text/line-index.js +75 -0
  76. package/dist/text/line-index.js.map +1 -0
  77. package/dist/text/yaml-lite.d.ts +73 -0
  78. package/dist/text/yaml-lite.d.ts.map +1 -0
  79. package/dist/text/yaml-lite.js +486 -0
  80. package/dist/text/yaml-lite.js.map +1 -0
  81. package/package.json +61 -3
  82. package/src/adapters/__golden__/adr-0001-sections.json +68 -0
  83. package/src/adapters/__golden__/app-compose-services.json +24 -0
  84. package/src/adapters/__golden__/app-image-stages.json +24 -0
  85. package/src/adapters/__golden__/infra-main-sections.json +46 -0
  86. package/src/adapters/__golden__/orders-events-operations.json +24 -0
  87. package/src/adapters/__golden__/orders-proto-sections.json +57 -0
  88. package/src/adapters/__golden__/orders-schema-statements.json +68 -0
  89. package/src/adapters/__golden__/users-api-operations.json +46 -0
  90. package/src/adapters/__golden__/web-manifests-resources.json +24 -0
  91. package/src/adapters/asyncapi.ts +147 -0
  92. package/src/adapters/docker.ts +170 -0
  93. package/src/adapters/kubernetes.ts +103 -0
  94. package/src/adapters/markdown.ts +88 -0
  95. package/src/adapters/openapi.ts +156 -0
  96. package/src/adapters/protobuf.ts +286 -0
  97. package/src/adapters/shared.ts +151 -0
  98. package/src/adapters/sql.ts +555 -0
  99. package/src/adapters/terraform.ts +261 -0
  100. package/src/adapters/text.ts +72 -0
  101. package/src/config-validation.ts +41 -0
  102. package/src/coverage.ts +336 -0
  103. package/src/ids.ts +57 -0
  104. package/src/index.ts +105 -0
  105. package/src/registry.ts +155 -0
  106. package/src/staleness.ts +69 -0
  107. package/src/text/delimiter-balance.ts +295 -0
  108. package/src/text/line-index.ts +108 -0
  109. package/src/text/yaml-lite.ts +565 -0
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Helpers shared by every concrete format adapter in `src/adapters/`.
3
+ */
4
+ import type {
5
+ ArtifactChunk,
6
+ ArtifactDocument,
7
+ ArtifactInput,
8
+ ContextArtifactType,
9
+ } from "@untangle-code/domain";
10
+ import { sha256Hex } from "@untangle-code/domain";
11
+
12
+ import {
13
+ buildArtifactSkipLedger,
14
+ defaultSkipLedgerReporter,
15
+ type ChunkPlausibilityCheck,
16
+ type SkipLedgerReporter,
17
+ } from "../coverage.js";
18
+ import { buildArtifactChunkId } from "../ids.js";
19
+ import type { LineIndex } from "../text/line-index.js";
20
+ import { rangeForLines, sliceBytes, sliceLines } from "../text/line-index.js";
21
+
22
+ export type { ChunkPlausibilityCheck, SkipLedgerReporter } from "../coverage.js";
23
+
24
+ /** Builds one `ArtifactDocument` per file in `input.files` (spec.md §19.2: files AND directories). */
25
+ export function buildDocuments(
26
+ input: ArtifactInput,
27
+ type: Exclude<ContextArtifactType, "auto">,
28
+ language?: string,
29
+ ): ArtifactDocument[] {
30
+ return input.files.map((file) => {
31
+ const document: ArtifactDocument = {
32
+ artifactName: input.config.name,
33
+ type,
34
+ path: file.path,
35
+ contentHash: file.contentHash,
36
+ content: file.content,
37
+ };
38
+ return language === undefined ? document : { ...document, language };
39
+ });
40
+ }
41
+
42
+ export interface ChunkDraft {
43
+ kind: string;
44
+ startLine: number;
45
+ endLine: number;
46
+ title?: string;
47
+ /**
48
+ * Optional exact byte range, used instead of `rangeForLines(index,
49
+ * startLine, endLine)` when a draft's true boundary does not land on a
50
+ * whole-line boundary — e.g. two SQL statements sharing one physical
51
+ * line, each needing its own non-overlapping byte span within that one
52
+ * line. `startLine`/`endLine` are still required (and still used for the
53
+ * chunk's `range.startLine`/`endLine`) so every draft has a human-facing
54
+ * line reference even when its bytes are sub-line-precise. Omitted by
55
+ * every adapter that only ever splits on whole lines (the common case).
56
+ */
57
+ startByte?: number;
58
+ endByte?: number;
59
+ }
60
+
61
+ /**
62
+ * Turns line-range drafts into fully-formed `ArtifactChunk`s: computes
63
+ * `range` (via `index`, or the draft's own `startByte`/`endByte` when
64
+ * given), byte-exact `content` (a slice of the SAME buffer `index` was
65
+ * built from — never a re-encoded copy, so content is always byte-identical
66
+ * to the source, spec.md §19.2), `contentHash`, and a deterministic
67
+ * `chunkId` (ordinal = position in `drafts`).
68
+ */
69
+ export function buildChunks(
70
+ document: ArtifactDocument,
71
+ index: LineIndex,
72
+ drafts: ChunkDraft[],
73
+ ): ArtifactChunk[] {
74
+ return drafts.map((draft, ordinal) => {
75
+ const hasExactBytes = draft.startByte !== undefined && draft.endByte !== undefined;
76
+ const range = hasExactBytes
77
+ ? {
78
+ startLine: draft.startLine,
79
+ endLine: draft.endLine,
80
+ startByte: draft.startByte!,
81
+ endByte: draft.endByte!,
82
+ }
83
+ : rangeForLines(index, draft.startLine, draft.endLine);
84
+ const content = hasExactBytes
85
+ ? sliceBytes(index, draft.startByte!, draft.endByte!)
86
+ : sliceLines(index, draft.startLine, draft.endLine);
87
+ const chunk: ArtifactChunk = {
88
+ chunkId: buildArtifactChunkId({
89
+ artifactName: document.artifactName,
90
+ documentPath: document.path,
91
+ kind: draft.kind,
92
+ ordinal,
93
+ }),
94
+ artifactName: document.artifactName,
95
+ kind: draft.kind,
96
+ range,
97
+ content,
98
+ contentHash: sha256Hex(content),
99
+ };
100
+ return draft.title === undefined ? chunk : { ...chunk, title: draft.title };
101
+ });
102
+ }
103
+
104
+ /** A single chunk spanning the whole document, used for parse-error degrades and the text fallback's single-window case. */
105
+ export function wholeDocumentDraft(kind: string, index: LineIndex, title?: string): ChunkDraft {
106
+ const draft: ChunkDraft = { kind, startLine: 1, endLine: Math.max(index.lineCount, 1) };
107
+ return title === undefined ? draft : { ...draft, title };
108
+ }
109
+
110
+ /**
111
+ * `buildChunks`, plus BUILD_PLAN §12 E4: `buildArtifactSkipLedger()` must
112
+ * never be a "Bringschuld" (an obligation a caller has to remember) —
113
+ * every format adapter's `chunk()` calls this instead of `buildChunks`
114
+ * directly, so a loss becomes visible in the SAME call that produces
115
+ * chunks, with zero extra action from whoever calls `adapter.chunk()`.
116
+ *
117
+ * `checkPlausibility` (optional, WP-118) reicht die formatspezifische
118
+ * Plausibilitätsprüfung des Adapters an den Ledger durch: ein Fragment,
119
+ * das MITTEN DURCH ein Konstrukt geschnitten wurde, ist auch dann ein
120
+ * Befund, wenn die Byte-Abdeckung lückenlos ist. Siehe
121
+ * `coverage.ts::ChunkPlausibilityCheck` und `text/delimiter-balance.ts`.
122
+ *
123
+ * Only entries beyond plain `"whitespace_or_comment"` are reported —
124
+ * `"unclassified_content"` and `"semantic_loss"` are the two reasons that
125
+ * indicate a real problem (see coverage.ts's module doc); a benign gap
126
+ * between two well-formed sections is expected and stays silent here too,
127
+ * exactly as it does for a caller who inspects the ledger directly.
128
+ *
129
+ * `report` defaults to `defaultSkipLedgerReporter` (a single stderr line
130
+ * per finding) but every `create*Adapter()` factory accepts an
131
+ * `onSkipLedgerGap` override — inject a real structured logger, a test
132
+ * spy, or a no-op, without this package depending on any particular
133
+ * logging implementation.
134
+ */
135
+ export function buildChunksReportingSkips(
136
+ document: ArtifactDocument,
137
+ index: LineIndex,
138
+ drafts: ChunkDraft[],
139
+ report: SkipLedgerReporter = defaultSkipLedgerReporter,
140
+ checkPlausibility?: ChunkPlausibilityCheck,
141
+ ): ArtifactChunk[] {
142
+ const chunks = buildChunks(document, index, drafts);
143
+ const options = checkPlausibility === undefined ? {} : { checkPlausibility };
144
+ const actionable = buildArtifactSkipLedger(document, chunks, options).filter(
145
+ (entry) => entry.reason !== "whitespace_or_comment",
146
+ );
147
+ if (actionable.length > 0) {
148
+ report(actionable, document);
149
+ }
150
+ return chunks;
151
+ }