@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 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/adapters/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAGL,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGvD,YAAY,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEjF,sGAAsG;AACtG,wBAAgB,cAAc,CAC5B,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,EAC1C,QAAQ,CAAC,EAAE,MAAM,GAChB,gBAAgB,EAAE,CAWpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,UAAU,EAAE,GACnB,aAAa,EAAE,CA6BjB;AAED,4HAA4H;AAC5H,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,UAAU,CAG7F;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,UAAU,EAAE,EACpB,MAAM,GAAE,kBAA8C,EACtD,iBAAiB,CAAC,EAAE,sBAAsB,GACzC,aAAa,EAAE,CAUjB"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { sha256Hex } from "@untangle-code/domain";
|
|
2
|
+
import { buildArtifactSkipLedger, defaultSkipLedgerReporter, } from "../coverage.js";
|
|
3
|
+
import { buildArtifactChunkId } from "../ids.js";
|
|
4
|
+
import { rangeForLines, sliceBytes, sliceLines } from "../text/line-index.js";
|
|
5
|
+
/** Builds one `ArtifactDocument` per file in `input.files` (spec.md §19.2: files AND directories). */
|
|
6
|
+
export function buildDocuments(input, type, language) {
|
|
7
|
+
return input.files.map((file) => {
|
|
8
|
+
const document = {
|
|
9
|
+
artifactName: input.config.name,
|
|
10
|
+
type,
|
|
11
|
+
path: file.path,
|
|
12
|
+
contentHash: file.contentHash,
|
|
13
|
+
content: file.content,
|
|
14
|
+
};
|
|
15
|
+
return language === undefined ? document : { ...document, language };
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Turns line-range drafts into fully-formed `ArtifactChunk`s: computes
|
|
20
|
+
* `range` (via `index`, or the draft's own `startByte`/`endByte` when
|
|
21
|
+
* given), byte-exact `content` (a slice of the SAME buffer `index` was
|
|
22
|
+
* built from — never a re-encoded copy, so content is always byte-identical
|
|
23
|
+
* to the source, spec.md §19.2), `contentHash`, and a deterministic
|
|
24
|
+
* `chunkId` (ordinal = position in `drafts`).
|
|
25
|
+
*/
|
|
26
|
+
export function buildChunks(document, index, drafts) {
|
|
27
|
+
return drafts.map((draft, ordinal) => {
|
|
28
|
+
const hasExactBytes = draft.startByte !== undefined && draft.endByte !== undefined;
|
|
29
|
+
const range = hasExactBytes
|
|
30
|
+
? {
|
|
31
|
+
startLine: draft.startLine,
|
|
32
|
+
endLine: draft.endLine,
|
|
33
|
+
startByte: draft.startByte,
|
|
34
|
+
endByte: draft.endByte,
|
|
35
|
+
}
|
|
36
|
+
: rangeForLines(index, draft.startLine, draft.endLine);
|
|
37
|
+
const content = hasExactBytes
|
|
38
|
+
? sliceBytes(index, draft.startByte, draft.endByte)
|
|
39
|
+
: sliceLines(index, draft.startLine, draft.endLine);
|
|
40
|
+
const chunk = {
|
|
41
|
+
chunkId: buildArtifactChunkId({
|
|
42
|
+
artifactName: document.artifactName,
|
|
43
|
+
documentPath: document.path,
|
|
44
|
+
kind: draft.kind,
|
|
45
|
+
ordinal,
|
|
46
|
+
}),
|
|
47
|
+
artifactName: document.artifactName,
|
|
48
|
+
kind: draft.kind,
|
|
49
|
+
range,
|
|
50
|
+
content,
|
|
51
|
+
contentHash: sha256Hex(content),
|
|
52
|
+
};
|
|
53
|
+
return draft.title === undefined ? chunk : { ...chunk, title: draft.title };
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/** A single chunk spanning the whole document, used for parse-error degrades and the text fallback's single-window case. */
|
|
57
|
+
export function wholeDocumentDraft(kind, index, title) {
|
|
58
|
+
const draft = { kind, startLine: 1, endLine: Math.max(index.lineCount, 1) };
|
|
59
|
+
return title === undefined ? draft : { ...draft, title };
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* `buildChunks`, plus BUILD_PLAN §12 E4: `buildArtifactSkipLedger()` must
|
|
63
|
+
* never be a "Bringschuld" (an obligation a caller has to remember) —
|
|
64
|
+
* every format adapter's `chunk()` calls this instead of `buildChunks`
|
|
65
|
+
* directly, so a loss becomes visible in the SAME call that produces
|
|
66
|
+
* chunks, with zero extra action from whoever calls `adapter.chunk()`.
|
|
67
|
+
*
|
|
68
|
+
* `checkPlausibility` (optional, WP-118) reicht die formatspezifische
|
|
69
|
+
* Plausibilitätsprüfung des Adapters an den Ledger durch: ein Fragment,
|
|
70
|
+
* das MITTEN DURCH ein Konstrukt geschnitten wurde, ist auch dann ein
|
|
71
|
+
* Befund, wenn die Byte-Abdeckung lückenlos ist. Siehe
|
|
72
|
+
* `coverage.ts::ChunkPlausibilityCheck` und `text/delimiter-balance.ts`.
|
|
73
|
+
*
|
|
74
|
+
* Only entries beyond plain `"whitespace_or_comment"` are reported —
|
|
75
|
+
* `"unclassified_content"` and `"semantic_loss"` are the two reasons that
|
|
76
|
+
* indicate a real problem (see coverage.ts's module doc); a benign gap
|
|
77
|
+
* between two well-formed sections is expected and stays silent here too,
|
|
78
|
+
* exactly as it does for a caller who inspects the ledger directly.
|
|
79
|
+
*
|
|
80
|
+
* `report` defaults to `defaultSkipLedgerReporter` (a single stderr line
|
|
81
|
+
* per finding) but every `create*Adapter()` factory accepts an
|
|
82
|
+
* `onSkipLedgerGap` override — inject a real structured logger, a test
|
|
83
|
+
* spy, or a no-op, without this package depending on any particular
|
|
84
|
+
* logging implementation.
|
|
85
|
+
*/
|
|
86
|
+
export function buildChunksReportingSkips(document, index, drafts, report = defaultSkipLedgerReporter, checkPlausibility) {
|
|
87
|
+
const chunks = buildChunks(document, index, drafts);
|
|
88
|
+
const options = checkPlausibility === undefined ? {} : { checkPlausibility };
|
|
89
|
+
const actionable = buildArtifactSkipLedger(document, chunks, options).filter((entry) => entry.reason !== "whitespace_or_comment");
|
|
90
|
+
if (actionable.length > 0) {
|
|
91
|
+
report(actionable, document);
|
|
92
|
+
}
|
|
93
|
+
return chunks;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/adapters/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL schema adapter (architecture.md §20: "Tabellen, Views, Indizes,
|
|
3
|
+
* Constraints als semantische Abschnitte").
|
|
4
|
+
*
|
|
5
|
+
* Splits the file into top-level statements (terminated by a `;` that is
|
|
6
|
+
* not inside a string literal, a quoted identifier, or a comment), then
|
|
7
|
+
* classifies each statement by its leading keywords. An unrecognized
|
|
8
|
+
* statement (e.g. `INSERT`, `GRANT`) still becomes a chunk — kind
|
|
9
|
+
* `"sql_statement"` — rather than being dropped; nothing in a schema file
|
|
10
|
+
* is silently skipped (rule 4 / BUILD_PLAN §12 E4).
|
|
11
|
+
*
|
|
12
|
+
* Statement boundaries are tracked as exact BYTE offsets, not just line
|
|
13
|
+
* numbers (WP-81 review finding): two statements can share one physical
|
|
14
|
+
* line (`CREATE TABLE a (id int); CREATE TABLE b (id int);`), and a
|
|
15
|
+
* line-only span can't tell them apart — either the second collapses into
|
|
16
|
+
* an empty/inverted range (a phantom chunk carrying no content) or its
|
|
17
|
+
* bytes get silently absorbed into the first statement's chunk, which
|
|
18
|
+
* still reports zero gap (byte coverage looks complete) even though the
|
|
19
|
+
* second statement's identity was lost. `splitStatements` below scans the
|
|
20
|
+
* document's own UTF-8 bytes once, so every statement — including a second
|
|
21
|
+
* one sharing its predecessor's line — gets its own precise, non-empty,
|
|
22
|
+
* non-overlapping byte range that `ChunkDraft.startByte`/`endByte`
|
|
23
|
+
* (`adapters/shared.ts`) carries straight through, instead of snapping to
|
|
24
|
+
* whole-line boundaries.
|
|
25
|
+
*
|
|
26
|
+
* The file's LAST statement is not required to end in `;` — a schema file
|
|
27
|
+
* missing its final terminator (a common paste/truncation mistake) still
|
|
28
|
+
* gets its own chunk for that trailing statement; nothing after the last
|
|
29
|
+
* real `;` is ever silently dropped.
|
|
30
|
+
*
|
|
31
|
+
* WP-118: Der Zerleger kannte lange nur die verdoppelte
|
|
32
|
+
* Anführungszeichen-Konvention (`''`) als Escape. Ein Literal mit `\'` und
|
|
33
|
+
* einem `;` darin — in Dumps alltäglich — zerriss deshalb EIN Statement in
|
|
34
|
+
* zwei syntaktisch kaputte Fragmente, und zwar bei NULL Ledger-Warnungen:
|
|
35
|
+
* die Byte-Abdeckung war lückenlos, die Fragmente weder leer noch
|
|
36
|
+
* überlappend. Zwei Änderungen beheben das:
|
|
37
|
+
*
|
|
38
|
+
* 1. Die Escape-Behandlung ist dialektbewusst ({@link SqlDialect}), mit
|
|
39
|
+
* einem benannten, begründeten Standardwert ({@link DEFAULT_SQL_DIALECT})
|
|
40
|
+
* statt einer Vermutung über die vorliegende Datei. Zusätzlich erkennt
|
|
41
|
+
* der Scanner `$tag$`-Literale, in denen ein `;` genauso alltäglich ist.
|
|
42
|
+
* 2. Wichtiger: `sqlPlausibilityCheck` prüft JEDES fertige Fragment auf
|
|
43
|
+
* offene Zeichenketten, offene Kommentare und unausgeglichene Klammern.
|
|
44
|
+
* Damit greift E4 auch dann, wenn nichts FEHLT, sondern etwas FALSCH
|
|
45
|
+
* GESCHNITTEN ist — unabhängig davon, ob der Dialekt richtig gewählt
|
|
46
|
+
* war. Eine falsche Dialektwahl ist danach sichtbar, nicht still.
|
|
47
|
+
*/
|
|
48
|
+
import type { ArtifactAdapter } from "@untangle-code/domain";
|
|
49
|
+
import type { SkipLedgerReporter } from "./shared.js";
|
|
50
|
+
/**
|
|
51
|
+
* Escape-Konvention für Zeichenketten-Literale. Die SQL-Dialekte
|
|
52
|
+
* WIDERSPRECHEN sich hier, und zwar unauflösbar:
|
|
53
|
+
*
|
|
54
|
+
* - `"doubled-quotes-only"` — Standard-SQL: das EINZIGE Escape in einem
|
|
55
|
+
* Literal ist das verdoppelte Anführungszeichen (`'it''s'`). Ein `\` ist
|
|
56
|
+
* ein ganz normales Zeichen; `'it\'` ist eine ABGESCHLOSSENE Zeichenkette
|
|
57
|
+
* mit einem Backslash am Ende.
|
|
58
|
+
* - `"backslash-escapes"` — die verbreitete Erweiterung: zusätzlich zum
|
|
59
|
+
* verdoppelten Anführungszeichen maskiert `\'` ein Anführungszeichen,
|
|
60
|
+
* `` ` `` klammert Bezeichner und `#` leitet einen Zeilenkommentar ein.
|
|
61
|
+
*
|
|
62
|
+
* Dieselbe Datei bedeutet also je nach Dialekt etwas anderes, und der
|
|
63
|
+
* Dialekt steht NICHT in der Datei. Deshalb wird hier nicht geraten: die
|
|
64
|
+
* Wahl ist eine explizite Option mit einem benannten Standardwert, und
|
|
65
|
+
* jedes Ergebnis, das unter der gewählten Konvention unsinnig aussieht,
|
|
66
|
+
* erzeugt einen sichtbaren Befund (siehe `sqlPlausibilityCheck`).
|
|
67
|
+
*/
|
|
68
|
+
export type SqlDialect = "backslash-escapes" | "doubled-quotes-only";
|
|
69
|
+
/**
|
|
70
|
+
* Standardwert: `"backslash-escapes"` — bewusst NICHT der Standard-SQL-Dialekt.
|
|
71
|
+
*
|
|
72
|
+
* Begründung (asymmetrische Fehlerkosten für einen ZERLEGER, nicht für
|
|
73
|
+
* einen Ausführer): dieser Adapter führt kein SQL aus, er schneidet nur
|
|
74
|
+
* Abschnitte. Der teure Fehler ist der Schnitt MITTEN durch ein Statement,
|
|
75
|
+
* denn er erzeugt zwei syntaktisch kaputte Chunks, die niemand mehr als
|
|
76
|
+
* ein Statement erkennt (WP-118). Der billige Fehler ist der zu späte
|
|
77
|
+
* Schnitt: zwei Statements landen in einem Chunk, der immer noch gültiges,
|
|
78
|
+
* vollständiges SQL enthält.
|
|
79
|
+
*
|
|
80
|
+
* - Nimmt man `\'` als Escape und die Datei war Standard-SQL, kann nur ein
|
|
81
|
+
* Literal betroffen sein, das unmittelbar vor seinem Schlusszeichen auf
|
|
82
|
+
* `\` endet (`'C:\'`) — selten, und das Ergebnis ist eine offene
|
|
83
|
+
* Zeichenkette, die die Plausibilitätsprüfung meldet.
|
|
84
|
+
* - Nimmt man `\'` NICHT als Escape und die Datei nutzt es, zerreißt jedes
|
|
85
|
+
* Literal mit `\'` und einem folgenden `;` ein Statement — genau der
|
|
86
|
+
* gemeldete Defekt, und in Dumps alltäglich.
|
|
87
|
+
*
|
|
88
|
+
* Wer Standard-SQL indexiert und die Backtick-/`#`-Erweiterungen
|
|
89
|
+
* ausschließen will, setzt `dialect: "doubled-quotes-only"`.
|
|
90
|
+
*/
|
|
91
|
+
export declare const DEFAULT_SQL_DIALECT: SqlDialect;
|
|
92
|
+
export interface SqlAdapterOptions {
|
|
93
|
+
/** Overrides how a real skip-ledger finding surfaces from `chunk()` (default: a stderr warning) — see `coverage.ts`'s `SkipLedgerReporter`. */
|
|
94
|
+
onSkipLedgerGap?: SkipLedgerReporter;
|
|
95
|
+
/**
|
|
96
|
+
* Escape-Konvention der Zeichenketten-Literale. Standard:
|
|
97
|
+
* {@link DEFAULT_SQL_DIALECT} (`"backslash-escapes"`) — die Begründung
|
|
98
|
+
* dieser Wahl steht dort. Der Dialekt wird NICHT aus dem Dateiinhalt
|
|
99
|
+
* erraten; er ist eine Entscheidung des Aufrufers.
|
|
100
|
+
*/
|
|
101
|
+
dialect?: SqlDialect;
|
|
102
|
+
}
|
|
103
|
+
export declare function createSqlAdapter(options?: SqlAdapterOptions): ArtifactAdapter;
|
|
104
|
+
//# sourceMappingURL=sql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../src/adapters/sql.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,OAAO,KAAK,EACV,eAAe,EAKhB,MAAM,uBAAuB,CAAC;AAW/B,OAAO,KAAK,EAAsC,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAK1F;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,UAAU,GAAG,mBAAmB,GAAG,qBAAqB,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,mBAAmB,EAAE,UAAgC,CAAC;AA2XnE,MAAM,WAAW,iBAAiB;IAChC,+IAA+I;IAC/I,eAAe,CAAC,EAAE,kBAAkB,CAAC;IACrC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,eAAe,CAoDjF"}
|
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
import { describeDelimiterImbalances, findDelimiterImbalances } from "../text/delimiter-balance.js";
|
|
2
|
+
import { buildLineIndex, lineNumberForByte, sliceBytes, } from "../text/line-index.js";
|
|
3
|
+
import { buildChunks, buildChunksReportingSkips, buildDocuments } from "./shared.js";
|
|
4
|
+
const SQL_EXTENSION = /\.sql$/i;
|
|
5
|
+
/**
|
|
6
|
+
* Standardwert: `"backslash-escapes"` — bewusst NICHT der Standard-SQL-Dialekt.
|
|
7
|
+
*
|
|
8
|
+
* Begründung (asymmetrische Fehlerkosten für einen ZERLEGER, nicht für
|
|
9
|
+
* einen Ausführer): dieser Adapter führt kein SQL aus, er schneidet nur
|
|
10
|
+
* Abschnitte. Der teure Fehler ist der Schnitt MITTEN durch ein Statement,
|
|
11
|
+
* denn er erzeugt zwei syntaktisch kaputte Chunks, die niemand mehr als
|
|
12
|
+
* ein Statement erkennt (WP-118). Der billige Fehler ist der zu späte
|
|
13
|
+
* Schnitt: zwei Statements landen in einem Chunk, der immer noch gültiges,
|
|
14
|
+
* vollständiges SQL enthält.
|
|
15
|
+
*
|
|
16
|
+
* - Nimmt man `\'` als Escape und die Datei war Standard-SQL, kann nur ein
|
|
17
|
+
* Literal betroffen sein, das unmittelbar vor seinem Schlusszeichen auf
|
|
18
|
+
* `\` endet (`'C:\'`) — selten, und das Ergebnis ist eine offene
|
|
19
|
+
* Zeichenkette, die die Plausibilitätsprüfung meldet.
|
|
20
|
+
* - Nimmt man `\'` NICHT als Escape und die Datei nutzt es, zerreißt jedes
|
|
21
|
+
* Literal mit `\'` und einem folgenden `;` ein Statement — genau der
|
|
22
|
+
* gemeldete Defekt, und in Dumps alltäglich.
|
|
23
|
+
*
|
|
24
|
+
* Wer Standard-SQL indexiert und die Backtick-/`#`-Erweiterungen
|
|
25
|
+
* ausschließen will, setzt `dialect: "doubled-quotes-only"`.
|
|
26
|
+
*/
|
|
27
|
+
export const DEFAULT_SQL_DIALECT = "backslash-escapes";
|
|
28
|
+
function isAsciiWhitespaceByte(byte) {
|
|
29
|
+
return (byte === 0x20 ||
|
|
30
|
+
byte === 0x09 ||
|
|
31
|
+
byte === 0x0a ||
|
|
32
|
+
byte === 0x0d ||
|
|
33
|
+
byte === 0x0b ||
|
|
34
|
+
byte === 0x0c);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* After a statement-terminating `;` (buffer offset `semicolonEnd`, already
|
|
38
|
+
* past the `;` itself), decides how far the just-CLOSED statement's span
|
|
39
|
+
* should extend: through the rest of this physical line — its trailing
|
|
40
|
+
* whitespace, an optional trailing `-- ...` line comment, and the newline
|
|
41
|
+
* itself — when nothing else remains before that newline. This matches how
|
|
42
|
+
* a statement "owns" the rest of its own terminator line in the common
|
|
43
|
+
* case, where a schema file has exactly one statement per line (the exact
|
|
44
|
+
* byte a hand-formatted schema's next statement starts on is then, as
|
|
45
|
+
* before, the first byte of the following line).
|
|
46
|
+
*
|
|
47
|
+
* When real content follows the `;` on the SAME line instead — a second
|
|
48
|
+
* statement sharing that line — this returns `semicolonEnd` UNCHANGED, so
|
|
49
|
+
* that content starts its own span right where it begins rather than being
|
|
50
|
+
* silently folded into the span that just closed (the WP-81 review's
|
|
51
|
+
* "two statements, one line" defect: `TABLE_RE`/`VIEW_RE`/etc. would only
|
|
52
|
+
* ever see the FIRST statement's text, and the second statement's own span
|
|
53
|
+
* would either come out empty or never exist at all).
|
|
54
|
+
*/
|
|
55
|
+
function extendPastTrailingLineNoise(buffer, semicolonEnd) {
|
|
56
|
+
let j = semicolonEnd;
|
|
57
|
+
for (;;) {
|
|
58
|
+
while (j < buffer.length && buffer[j] !== 0x0a && isAsciiWhitespaceByte(buffer[j])) {
|
|
59
|
+
j += 1;
|
|
60
|
+
}
|
|
61
|
+
if (j < buffer.length && buffer[j] === 0x2d && buffer[j + 1] === 0x2d) {
|
|
62
|
+
// "--": a trailing line comment on the terminator's own line is also
|
|
63
|
+
// benign noise, not a new statement — skip to (not past) its newline.
|
|
64
|
+
while (j < buffer.length && buffer[j] !== 0x0a) {
|
|
65
|
+
j += 1;
|
|
66
|
+
}
|
|
67
|
+
continue; // a comment could be followed by more whitespace before the newline
|
|
68
|
+
}
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
if (j >= buffer.length)
|
|
72
|
+
return buffer.length;
|
|
73
|
+
if (buffer[j] === 0x0a)
|
|
74
|
+
return j + 1;
|
|
75
|
+
return semicolonEnd; // real content follows on the same line: do not extend past the `;`
|
|
76
|
+
}
|
|
77
|
+
/** Byte-Konstanten des Scanners — alles Einzelbyte-ASCII, siehe `splitStatements`. */
|
|
78
|
+
const BYTE_NEWLINE = 0x0a;
|
|
79
|
+
const BYTE_HASH = 0x23;
|
|
80
|
+
const BYTE_DOLLAR = 0x24;
|
|
81
|
+
const BYTE_SINGLE_QUOTE = 0x27;
|
|
82
|
+
const BYTE_DOUBLE_QUOTE = 0x22;
|
|
83
|
+
const BYTE_BACKTICK = 0x60;
|
|
84
|
+
const BYTE_BACKSLASH = 0x5c;
|
|
85
|
+
const BYTE_STAR = 0x2a;
|
|
86
|
+
const BYTE_SLASH = 0x2f;
|
|
87
|
+
const BYTE_DASH = 0x2d;
|
|
88
|
+
const BYTE_SEMICOLON = 0x3b;
|
|
89
|
+
const BYTE_UNDERSCORE = 0x5f;
|
|
90
|
+
function isDigitByte(byte) {
|
|
91
|
+
return byte >= 0x30 && byte <= 0x39;
|
|
92
|
+
}
|
|
93
|
+
function isLetterByte(byte) {
|
|
94
|
+
return (byte >= 0x41 && byte <= 0x5a) || (byte >= 0x61 && byte <= 0x7a);
|
|
95
|
+
}
|
|
96
|
+
/** Zeichen, die in einem `$tag$`-Etikett vorkommen dürfen (ohne `$` selbst). */
|
|
97
|
+
function isTagByte(byte) {
|
|
98
|
+
return (byte !== undefined && (isLetterByte(byte) || isDigitByte(byte) || byte === BYTE_UNDERSCORE));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Länge eines `$tag$`-Öffners an Position `i` (0, wenn dort keiner steht).
|
|
102
|
+
*
|
|
103
|
+
* Ein Dollar-Literal (`$$ … $$`, `$body$ … $body$`) ist der übliche Weg,
|
|
104
|
+
* einen Funktionsrumpf einzubetten — und darin steht fast immer ein `;`.
|
|
105
|
+
* Ohne diese Erkennung zerreißt jeder Funktionsrumpf in Fragmente, also
|
|
106
|
+
* exakt derselbe Defekt wie bei den Backslash-Escapes, nur mit anderem
|
|
107
|
+
* Auslöser. Erkannt wird das dialektübergreifend: `$tag$` hat außerhalb
|
|
108
|
+
* einer Zeichenkette in keinem gängigen Dialekt eine andere Bedeutung, die
|
|
109
|
+
* einen Statement-Zerleger interessieren müsste.
|
|
110
|
+
*
|
|
111
|
+
* Ein vorangehendes Bezeichnerzeichen verhindert die Erkennung — sonst
|
|
112
|
+
* würde der Bezeichner `my$col$x` fälschlich ein Literal öffnen.
|
|
113
|
+
*/
|
|
114
|
+
function dollarQuoteLength(buffer, i) {
|
|
115
|
+
if (buffer[i] !== BYTE_DOLLAR)
|
|
116
|
+
return 0;
|
|
117
|
+
const previous = i > 0 ? buffer[i - 1] : undefined;
|
|
118
|
+
if (previous !== undefined && (isTagByte(previous) || previous === BYTE_DOLLAR))
|
|
119
|
+
return 0;
|
|
120
|
+
let j = i + 1;
|
|
121
|
+
const first = buffer[j];
|
|
122
|
+
if (first !== undefined && (isLetterByte(first) || first === BYTE_UNDERSCORE)) {
|
|
123
|
+
j += 1;
|
|
124
|
+
while (j < buffer.length && isTagByte(buffer[j]))
|
|
125
|
+
j += 1;
|
|
126
|
+
}
|
|
127
|
+
if (buffer[j] !== BYTE_DOLLAR)
|
|
128
|
+
return 0;
|
|
129
|
+
return j + 1 - i;
|
|
130
|
+
}
|
|
131
|
+
/** Ob an Position `i` genau das Etikett steht, das bei `tagStart` geöffnet wurde. */
|
|
132
|
+
function matchesDollarTag(buffer, i, tagStart, tagLength) {
|
|
133
|
+
if (i + tagLength > buffer.length)
|
|
134
|
+
return false;
|
|
135
|
+
for (let k = 0; k < tagLength; k += 1) {
|
|
136
|
+
if (buffer[i + k] !== buffer[tagStart + k])
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Splits `index`'s underlying document into top-level statement byte spans
|
|
143
|
+
* (terminated by `;` outside strings/comments — see the module doc for why
|
|
144
|
+
* this is byte-, not line-, precise). Scans the raw UTF-8 `Buffer` directly
|
|
145
|
+
* (never the decoded JS string): every byte this function compares against
|
|
146
|
+
* (`'`, `"`, `` ` ``, `$`, `#`, `;`, `-`, `/`, `*`, `\\`, ASCII whitespace) is
|
|
147
|
+
* single-byte ASCII, and any UTF-8 continuation/multibyte-lead byte is
|
|
148
|
+
* `>= 0x80` and never matches one of those comparisons — so scanning raw
|
|
149
|
+
* bytes instead of UTF-16 code units never misreads a multibyte character
|
|
150
|
+
* (e.g. inside a comment or string) as one of these ASCII control
|
|
151
|
+
* characters. Das gilt auch für das Überspringen des Zeichens nach einem
|
|
152
|
+
* `\\`: übersprungen wird ein einzelnes Byte, und die restlichen Bytes
|
|
153
|
+
* eines Mehrbyte-Zeichens sind `>= 0x80` und lösen selbst nichts aus.
|
|
154
|
+
*
|
|
155
|
+
* `dialect` entscheidet über die Escape-Konvention (siehe {@link SqlDialect}).
|
|
156
|
+
* Falsch geschnittene Ergebnisse bleiben trotzdem möglich — deshalb prüft
|
|
157
|
+
* `sqlPlausibilityCheck` jedes fertige Fragment nach (WP-118, E4).
|
|
158
|
+
*/
|
|
159
|
+
function splitStatements(index, dialect) {
|
|
160
|
+
const { buffer } = index;
|
|
161
|
+
const backslashEscapes = dialect === "backslash-escapes";
|
|
162
|
+
const backtickIdentifiers = backslashEscapes;
|
|
163
|
+
const hashLineComments = backslashEscapes;
|
|
164
|
+
const spans = [];
|
|
165
|
+
let statementStartByte = 0;
|
|
166
|
+
let statementHasContent = false;
|
|
167
|
+
/** Offenes Anführungszeichen (`'`, `"` oder `` ` ``), sonst `undefined`. */
|
|
168
|
+
let quoteByte;
|
|
169
|
+
/** Länge des offenen `$tag$`-Etiketts (0 = kein Dollar-Literal offen). */
|
|
170
|
+
let dollarTagLength = 0;
|
|
171
|
+
let dollarTagStart = 0;
|
|
172
|
+
let inLineComment = false;
|
|
173
|
+
let inBlockComment = false;
|
|
174
|
+
const flush = (endByteExclusive) => {
|
|
175
|
+
if (!statementHasContent)
|
|
176
|
+
return;
|
|
177
|
+
spans.push({
|
|
178
|
+
startByte: statementStartByte,
|
|
179
|
+
endByte: endByteExclusive,
|
|
180
|
+
startLine: lineNumberForByte(index, statementStartByte),
|
|
181
|
+
endLine: lineNumberForByte(index, endByteExclusive - 1),
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
for (let i = 0; i < buffer.length; i += 1) {
|
|
185
|
+
const c = buffer[i];
|
|
186
|
+
const next = buffer[i + 1];
|
|
187
|
+
if (inBlockComment) {
|
|
188
|
+
if (c === BYTE_STAR && next === BYTE_SLASH) {
|
|
189
|
+
inBlockComment = false;
|
|
190
|
+
i += 1;
|
|
191
|
+
}
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (inLineComment) {
|
|
195
|
+
if (c === BYTE_NEWLINE)
|
|
196
|
+
inLineComment = false;
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (dollarTagLength > 0) {
|
|
200
|
+
if (c === BYTE_DOLLAR && matchesDollarTag(buffer, i, dollarTagStart, dollarTagLength)) {
|
|
201
|
+
i += dollarTagLength - 1;
|
|
202
|
+
dollarTagLength = 0;
|
|
203
|
+
}
|
|
204
|
+
statementHasContent = true;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (quoteByte !== undefined) {
|
|
208
|
+
// Reihenfolge: erst Backslash (verschluckt AUCH ein direkt folgendes
|
|
209
|
+
// Anführungszeichen), dann das verdoppelte Anführungszeichen, dann
|
|
210
|
+
// das schließende. Innerhalb von `` ` `` ist `\` kein Escape — dort
|
|
211
|
+
// ist die Verdopplung die einzige Konvention.
|
|
212
|
+
if (backslashEscapes && quoteByte !== BYTE_BACKTICK && c === BYTE_BACKSLASH) {
|
|
213
|
+
i += 1;
|
|
214
|
+
}
|
|
215
|
+
else if (c === quoteByte && next === quoteByte) {
|
|
216
|
+
i += 1;
|
|
217
|
+
}
|
|
218
|
+
else if (c === quoteByte) {
|
|
219
|
+
quoteByte = undefined;
|
|
220
|
+
}
|
|
221
|
+
statementHasContent = true;
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
if (c === BYTE_DASH && next === BYTE_DASH) {
|
|
225
|
+
inLineComment = true;
|
|
226
|
+
i += 1;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (hashLineComments && c === BYTE_HASH) {
|
|
230
|
+
inLineComment = true;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (c === BYTE_SLASH && next === BYTE_STAR) {
|
|
234
|
+
inBlockComment = true;
|
|
235
|
+
i += 1;
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
const dollarLength = dollarQuoteLength(buffer, i);
|
|
239
|
+
if (dollarLength > 0) {
|
|
240
|
+
dollarTagStart = i;
|
|
241
|
+
dollarTagLength = dollarLength;
|
|
242
|
+
i += dollarLength - 1;
|
|
243
|
+
statementHasContent = true;
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
if (c === BYTE_SINGLE_QUOTE ||
|
|
247
|
+
c === BYTE_DOUBLE_QUOTE ||
|
|
248
|
+
(backtickIdentifiers && c === BYTE_BACKTICK)) {
|
|
249
|
+
quoteByte = c;
|
|
250
|
+
statementHasContent = true;
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
if (c === BYTE_SEMICOLON) {
|
|
254
|
+
const endByteExclusive = extendPastTrailingLineNoise(buffer, i + 1);
|
|
255
|
+
flush(endByteExclusive);
|
|
256
|
+
statementStartByte = endByteExclusive;
|
|
257
|
+
statementHasContent = false;
|
|
258
|
+
i = endByteExclusive - 1;
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
if (!isAsciiWhitespaceByte(c)) {
|
|
262
|
+
statementHasContent = true;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
// A final statement with no terminating `;` (the file's last statement
|
|
266
|
+
// missing its semicolon) still becomes its own span — never silently
|
|
267
|
+
// dropped (rule 4 / BUILD_PLAN §12 E4). Trailing whitespace-only content
|
|
268
|
+
// after the true last `;` reaches here with `statementHasContent` still
|
|
269
|
+
// `false` and correctly produces no extra span.
|
|
270
|
+
flush(buffer.length);
|
|
271
|
+
return spans;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Trennzeichen-Konventionen für die Plausibilitätsprüfung, abgeleitet aus
|
|
275
|
+
* demselben Dialekt wie die Zerlegung. Geprüft werden nur runde Klammern —
|
|
276
|
+
* eckige Klammern sind in manchen Dialekten Bezeichner-Klammern und in
|
|
277
|
+
* anderen Array-Syntax; sie zu prüfen brächte Fehlalarme statt Befunde.
|
|
278
|
+
*/
|
|
279
|
+
function sqlScanOptions(dialect) {
|
|
280
|
+
const backslashEscapes = dialect === "backslash-escapes";
|
|
281
|
+
const quotes = [
|
|
282
|
+
{ open: "'", close: "'", backslashEscapes, doubledEscapes: true, spansLines: true },
|
|
283
|
+
{ open: '"', close: '"', backslashEscapes, doubledEscapes: true, spansLines: true },
|
|
284
|
+
// Backtick-Bezeichner kennt der Zerleger nur im Backslash-Dialekt, der
|
|
285
|
+
// Prüfer dagegen IMMER — er darf misstrauischer sein als der Zerleger
|
|
286
|
+
// (siehe `text/delimiter-balance.ts`). Genau so wird die falsche
|
|
287
|
+
// Dialektwahl sichtbar: eine Datei mit `` `a;b` `` wird unter
|
|
288
|
+
// `"doubled-quotes-only"` falsch geschnitten, und beide Fragmente
|
|
289
|
+
// melden dann einen offenen Backtick, statt still zu bleiben. In
|
|
290
|
+
// Standard-SQL ist ein einzelner Backtick ohnehin ungültig, ein
|
|
291
|
+
// Fehlalarm also nicht möglich.
|
|
292
|
+
{ open: "`", close: "`", backslashEscapes: false, doubledEscapes: true, spansLines: true },
|
|
293
|
+
];
|
|
294
|
+
return {
|
|
295
|
+
quotes,
|
|
296
|
+
brackets: [{ open: "(", close: ")" }],
|
|
297
|
+
lineComments: backslashEscapes ? ["--", "#"] : ["--"],
|
|
298
|
+
blockComment: { open: "/*", close: "*/" },
|
|
299
|
+
dollarQuotedStrings: true,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Die eigentliche Antwort auf WP-118: ein Statement-Fragment mit offener
|
|
304
|
+
* Zeichenkette, offenem Kommentar oder unausgeglichenen Klammern ist ein
|
|
305
|
+
* Befund — auch dann, wenn die Byte-Abdeckung lückenlos ist, weil nichts
|
|
306
|
+
* FEHLT, sondern etwas FALSCH GESCHNITTEN wurde.
|
|
307
|
+
*/
|
|
308
|
+
function sqlPlausibilityCheck(dialect) {
|
|
309
|
+
const scanOptions = sqlScanOptions(dialect);
|
|
310
|
+
return (chunk) => {
|
|
311
|
+
const imbalances = findDelimiterImbalances(chunk.content, scanOptions);
|
|
312
|
+
return imbalances.length === 0 ? undefined : describeDelimiterImbalances(imbalances);
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
const TABLE_RE = /^\s*CREATE\s+(?:OR\s+REPLACE\s+)?(?:TEMP(?:ORARY)?\s+)?TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?["`[]?([\w.]+)["`\]]?/i;
|
|
316
|
+
const VIEW_RE = /^\s*CREATE\s+(?:OR\s+REPLACE\s+)?VIEW\s+(?:IF\s+NOT\s+EXISTS\s+)?["`[]?([\w.]+)["`\]]?/i;
|
|
317
|
+
const INDEX_RE = /^\s*CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?["`[]?([\w.]+)["`\]]?\s+ON\s+["`[]?([\w.]+)["`\]]?/i;
|
|
318
|
+
const ALTER_CONSTRAINT_RE = /^\s*ALTER\s+TABLE\s+["`[]?([\w.]+)["`\]]?\s+ADD\s+CONSTRAINT\s+["`[]?([\w.]+)["`\]]?/i;
|
|
319
|
+
/** Strips leading whitespace and leading `--`/`/* *\/` comments so classification regexes only ever see real SQL. */
|
|
320
|
+
function stripLeadingComments(text) {
|
|
321
|
+
let remaining = text;
|
|
322
|
+
for (;;) {
|
|
323
|
+
const trimmed = remaining.replace(/^\s+/, "");
|
|
324
|
+
if (trimmed.startsWith("--")) {
|
|
325
|
+
const newlineIndex = trimmed.indexOf("\n");
|
|
326
|
+
remaining = newlineIndex === -1 ? "" : trimmed.slice(newlineIndex + 1);
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
if (trimmed.startsWith("/*")) {
|
|
330
|
+
const closeIndex = trimmed.indexOf("*/");
|
|
331
|
+
remaining = closeIndex === -1 ? "" : trimmed.slice(closeIndex + 2);
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
return trimmed;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
function classify(rawStatementText) {
|
|
338
|
+
const statementText = stripLeadingComments(rawStatementText);
|
|
339
|
+
const table = TABLE_RE.exec(statementText);
|
|
340
|
+
if (table)
|
|
341
|
+
return { kind: "sql_table", title: table[1] };
|
|
342
|
+
const view = VIEW_RE.exec(statementText);
|
|
343
|
+
if (view)
|
|
344
|
+
return { kind: "sql_view", title: view[1] };
|
|
345
|
+
const index = INDEX_RE.exec(statementText);
|
|
346
|
+
if (index)
|
|
347
|
+
return { kind: "sql_index", title: `${index[1]} ON ${index[2]}` };
|
|
348
|
+
const constraint = ALTER_CONSTRAINT_RE.exec(statementText);
|
|
349
|
+
if (constraint)
|
|
350
|
+
return { kind: "sql_constraint", title: `${constraint[2]} ON ${constraint[1]}` };
|
|
351
|
+
const firstWord = /^\s*(\w+)/.exec(statementText)?.[1] ?? "statement";
|
|
352
|
+
return { kind: "sql_statement", title: firstWord.toUpperCase() };
|
|
353
|
+
}
|
|
354
|
+
function sqlDrafts(index, dialect) {
|
|
355
|
+
return splitStatements(index, dialect).map((span) => {
|
|
356
|
+
const text = sliceBytes(index, span.startByte, span.endByte);
|
|
357
|
+
const { kind, title } = classify(text);
|
|
358
|
+
return {
|
|
359
|
+
kind,
|
|
360
|
+
startLine: span.startLine,
|
|
361
|
+
endLine: span.endLine,
|
|
362
|
+
title,
|
|
363
|
+
startByte: span.startByte,
|
|
364
|
+
endByte: span.endByte,
|
|
365
|
+
};
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
/** Table name a chunk defines, when its kind is `"sql_table"` — used by `links()`. */
|
|
369
|
+
function tableNameOf(chunk) {
|
|
370
|
+
return chunk.kind === "sql_table" ? chunk.title : undefined;
|
|
371
|
+
}
|
|
372
|
+
/** `snake_case`/`kebab-case` table name → PascalCase-ish repository class name guess. */
|
|
373
|
+
function guessRepositoryName(tableName) {
|
|
374
|
+
const bareName = tableName.includes(".") ? tableName.split(".").at(-1) : tableName;
|
|
375
|
+
const pascal = bareName
|
|
376
|
+
.split(/[_-]+/)
|
|
377
|
+
.filter((part) => part.length > 0)
|
|
378
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
379
|
+
.join("");
|
|
380
|
+
return `${pascal}Repository`;
|
|
381
|
+
}
|
|
382
|
+
export function createSqlAdapter(options = {}) {
|
|
383
|
+
const dialect = options.dialect ?? DEFAULT_SQL_DIALECT;
|
|
384
|
+
const checkPlausibility = sqlPlausibilityCheck(dialect);
|
|
385
|
+
return {
|
|
386
|
+
supports(type, path) {
|
|
387
|
+
return type === "sql" || (type === "auto" && SQL_EXTENSION.test(path));
|
|
388
|
+
},
|
|
389
|
+
async read(input) {
|
|
390
|
+
return buildDocuments(input, "sql");
|
|
391
|
+
},
|
|
392
|
+
chunk(document) {
|
|
393
|
+
const index = buildLineIndex(document.content);
|
|
394
|
+
return buildChunksReportingSkips(document, index, sqlDrafts(index, dialect), options.onSkipLedgerGap, checkPlausibility);
|
|
395
|
+
},
|
|
396
|
+
/**
|
|
397
|
+
* Heuristic-only (architecture.md §20): guesses that table `orders`
|
|
398
|
+
* has a corresponding `OrdersRepository` code symbol, purely from a
|
|
399
|
+
* naming convention. `targetId` is deliberately left unset — this
|
|
400
|
+
* adapter has no code-symbol index to resolve against, only the
|
|
401
|
+
* repository-adapter graph-linking stage (a different WP) can turn
|
|
402
|
+
* `targetName` into a real `targetId`. Confidence is fixed and
|
|
403
|
+
* conservative: this guess is right often enough to be worth surfacing,
|
|
404
|
+
* wrong often enough that a caller MUST treat it as a hint, never a fact.
|
|
405
|
+
*/
|
|
406
|
+
links(document) {
|
|
407
|
+
const index = buildLineIndex(document.content);
|
|
408
|
+
const chunks = buildChunks(document, index, sqlDrafts(index, dialect));
|
|
409
|
+
const links = [];
|
|
410
|
+
for (const chunk of chunks) {
|
|
411
|
+
const tableName = tableNameOf(chunk);
|
|
412
|
+
if (tableName === undefined)
|
|
413
|
+
continue;
|
|
414
|
+
links.push({
|
|
415
|
+
fromChunkId: chunk.chunkId,
|
|
416
|
+
targetKind: "symbol",
|
|
417
|
+
targetName: guessRepositoryName(tableName),
|
|
418
|
+
heuristic: true,
|
|
419
|
+
confidence: 0.4,
|
|
420
|
+
note: `naming-convention guess: SQL table "${tableName}" → repository symbol, not a resolved reference`,
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
return links;
|
|
424
|
+
},
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
//# sourceMappingURL=sql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.js","sourceRoot":"","sources":["../../src/adapters/sql.ts"],"names":[],"mappings":"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"}
|