diffninja 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.
- package/LICENSE +21 -0
- package/README.md +259 -0
- package/dist/calltree.d.ts +47 -0
- package/dist/calltree.js +296 -0
- package/dist/cli.d.ts +57 -0
- package/dist/cli.js +340 -0
- package/dist/diff.d.ts +7 -0
- package/dist/diff.js +114 -0
- package/dist/extract.d.ts +26 -0
- package/dist/extract.js +152 -0
- package/dist/git.d.ts +40 -0
- package/dist/git.js +288 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +8 -0
- package/dist/infer.d.ts +21 -0
- package/dist/infer.js +189 -0
- package/dist/languages/bash.d.ts +2 -0
- package/dist/languages/bash.js +208 -0
- package/dist/languages/c.d.ts +2 -0
- package/dist/languages/c.js +218 -0
- package/dist/languages/call-syntax.d.ts +125 -0
- package/dist/languages/call-syntax.js +997 -0
- package/dist/languages/cpp.d.ts +2 -0
- package/dist/languages/cpp.js +321 -0
- package/dist/languages/csharp.d.ts +2 -0
- package/dist/languages/csharp.js +324 -0
- package/dist/languages/elixir.d.ts +2 -0
- package/dist/languages/elixir.js +331 -0
- package/dist/languages/go.d.ts +2 -0
- package/dist/languages/go.js +299 -0
- package/dist/languages/grammars.d.ts +50 -0
- package/dist/languages/grammars.js +351 -0
- package/dist/languages/haskell.d.ts +2 -0
- package/dist/languages/haskell.js +250 -0
- package/dist/languages/java.d.ts +2 -0
- package/dist/languages/java.js +351 -0
- package/dist/languages/javascript.d.ts +4 -0
- package/dist/languages/javascript.js +648 -0
- package/dist/languages/kotlin.d.ts +2 -0
- package/dist/languages/kotlin.js +368 -0
- package/dist/languages/lua.d.ts +2 -0
- package/dist/languages/lua.js +212 -0
- package/dist/languages/ocaml.d.ts +2 -0
- package/dist/languages/ocaml.js +291 -0
- package/dist/languages/perl.d.ts +2 -0
- package/dist/languages/perl.js +418 -0
- package/dist/languages/php.d.ts +2 -0
- package/dist/languages/php.js +397 -0
- package/dist/languages/python.d.ts +2 -0
- package/dist/languages/python.js +376 -0
- package/dist/languages/registry.d.ts +7 -0
- package/dist/languages/registry.js +69 -0
- package/dist/languages/ruby.d.ts +2 -0
- package/dist/languages/ruby.js +391 -0
- package/dist/languages/rust.d.ts +2 -0
- package/dist/languages/rust.js +261 -0
- package/dist/languages/scala.d.ts +2 -0
- package/dist/languages/scala.js +307 -0
- package/dist/languages/solidity.d.ts +2 -0
- package/dist/languages/solidity.js +240 -0
- package/dist/languages/swift.d.ts +2 -0
- package/dist/languages/swift.js +268 -0
- package/dist/languages/types.d.ts +36 -0
- package/dist/languages/types.js +74 -0
- package/dist/languages/typescript-contracts.d.ts +57 -0
- package/dist/languages/typescript-contracts.js +528 -0
- package/dist/languages/typescript-dispatch.d.ts +68 -0
- package/dist/languages/typescript-dispatch.js +710 -0
- package/dist/languages/typescript.d.ts +4 -0
- package/dist/languages/typescript.js +722 -0
- package/dist/languages/zig.d.ts +2 -0
- package/dist/languages/zig.js +243 -0
- package/dist/loc.d.ts +17 -0
- package/dist/loc.js +34 -0
- package/dist/reach.d.ts +17 -0
- package/dist/reach.js +65 -0
- package/dist/render.d.ts +18 -0
- package/dist/render.js +83 -0
- package/dist/review/brand.d.ts +8 -0
- package/dist/review/brand.js +25 -0
- package/dist/review/call-context.d.ts +27 -0
- package/dist/review/call-context.js +446 -0
- package/dist/review/call-flow-html.d.ts +32 -0
- package/dist/review/call-flow-html.js +1870 -0
- package/dist/review/call-flow-nav.d.ts +151 -0
- package/dist/review/call-flow-nav.js +317 -0
- package/dist/review/call-flow.d.ts +47 -0
- package/dist/review/call-flow.js +229 -0
- package/dist/review/change-facts.d.ts +69 -0
- package/dist/review/change-facts.js +729 -0
- package/dist/review/cli.d.ts +2 -0
- package/dist/review/cli.js +50 -0
- package/dist/review/connected-analysis.d.ts +100 -0
- package/dist/review/connected-analysis.js +163 -0
- package/dist/review/connected-html.d.ts +17 -0
- package/dist/review/connected-html.js +2853 -0
- package/dist/review/connected.d.ts +23 -0
- package/dist/review/connected.js +141 -0
- package/dist/review/escape-html.d.ts +2 -0
- package/dist/review/escape-html.js +9 -0
- package/dist/review/evidence-html.d.ts +21 -0
- package/dist/review/evidence-html.js +521 -0
- package/dist/review/evidence-syntax.d.ts +132 -0
- package/dist/review/evidence-syntax.js +478 -0
- package/dist/review/evidence-types.d.ts +62 -0
- package/dist/review/evidence-types.js +1 -0
- package/dist/review/evidence.d.ts +31 -0
- package/dist/review/evidence.js +1603 -0
- package/dist/review/file-role.d.ts +9 -0
- package/dist/review/file-role.js +29 -0
- package/dist/review/github.d.ts +204 -0
- package/dist/review/github.js +1245 -0
- package/dist/review/history.d.ts +101 -0
- package/dist/review/history.js +412 -0
- package/dist/review/html.d.ts +34 -0
- package/dist/review/html.js +1104 -0
- package/dist/review/input.d.ts +10 -0
- package/dist/review/input.js +113 -0
- package/dist/review/intent.d.ts +4 -0
- package/dist/review/intent.js +75 -0
- package/dist/review/mcp-cli.d.ts +2 -0
- package/dist/review/mcp-cli.js +25 -0
- package/dist/review/mcp.d.ts +12 -0
- package/dist/review/mcp.js +414 -0
- package/dist/review/module-resolution.d.ts +2 -0
- package/dist/review/module-resolution.js +86 -0
- package/dist/review/palette.d.ts +7 -0
- package/dist/review/palette.js +104 -0
- package/dist/review/pipeline.d.ts +77 -0
- package/dist/review/pipeline.js +227 -0
- package/dist/review/pr-input.d.ts +19 -0
- package/dist/review/pr-input.js +130 -0
- package/dist/review/questions.d.ts +201 -0
- package/dist/review/questions.js +174 -0
- package/dist/review/reference-check.d.ts +7 -0
- package/dist/review/reference-check.js +733 -0
- package/dist/review/report-pages.d.ts +109 -0
- package/dist/review/report-pages.js +328 -0
- package/dist/review/service.d.ts +23 -0
- package/dist/review/service.js +198 -0
- package/dist/review/setup.d.ts +112 -0
- package/dist/review/setup.js +549 -0
- package/dist/review/source.d.ts +26 -0
- package/dist/review/source.js +276 -0
- package/dist/review/toml.d.ts +38 -0
- package/dist/review/toml.js +565 -0
- package/dist/review/types.d.ts +179 -0
- package/dist/review/types.js +1 -0
- package/dist/run.d.ts +49 -0
- package/dist/run.js +311 -0
- package/dist/types.d.ts +366 -0
- package/dist/types.js +83 -0
- package/package.json +88 -0
- package/scripts/ensure-native-grammar.mjs +188 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Definition source for report call-flow nodes, read from the snapshot the
|
|
3
|
+
* definition lived in. Nothing here is generated: a definition whose file or
|
|
4
|
+
* span cannot be read honestly yields no detail rather than an approximation,
|
|
5
|
+
* and the description is the definition's own attached comment or docstring,
|
|
6
|
+
* copied verbatim.
|
|
7
|
+
*
|
|
8
|
+
* The whole span `line`..`endLine` is carried: a trimmed preview would leave
|
|
9
|
+
* the rest of the function readable only online, which is exactly what an
|
|
10
|
+
* offline report cannot do. Only what git cannot confirm is withheld.
|
|
11
|
+
*/
|
|
12
|
+
import { readSnapshotFile } from "../git.js";
|
|
13
|
+
import { detectLanguage } from "../languages/registry.js";
|
|
14
|
+
const SLASH_COMMENTS = { line: ["//"], block: ["/*", "*/"] };
|
|
15
|
+
const COMMENT_SYNTAX = new Map(Object.entries({
|
|
16
|
+
bash: { line: ["#"] },
|
|
17
|
+
c: SLASH_COMMENTS,
|
|
18
|
+
cpp: SLASH_COMMENTS,
|
|
19
|
+
csharp: SLASH_COMMENTS,
|
|
20
|
+
elixir: { line: ["#"] },
|
|
21
|
+
go: SLASH_COMMENTS,
|
|
22
|
+
haskell: { line: ["--"], block: ["{-", "-}"] },
|
|
23
|
+
java: SLASH_COMMENTS,
|
|
24
|
+
javascript: SLASH_COMMENTS,
|
|
25
|
+
javascriptreact: SLASH_COMMENTS,
|
|
26
|
+
kotlin: SLASH_COMMENTS,
|
|
27
|
+
lua: { line: ["--"], block: ["--[[", "]]"] },
|
|
28
|
+
ocaml: { line: [], block: ["(*", "*)"] },
|
|
29
|
+
perl: { line: ["#"] },
|
|
30
|
+
php: SLASH_COMMENTS,
|
|
31
|
+
python: { line: ["#"] },
|
|
32
|
+
ruby: { line: ["#"] },
|
|
33
|
+
rust: SLASH_COMMENTS,
|
|
34
|
+
scala: SLASH_COMMENTS,
|
|
35
|
+
solidity: SLASH_COMMENTS,
|
|
36
|
+
swift: SLASH_COMMENTS,
|
|
37
|
+
typescript: SLASH_COMMENTS,
|
|
38
|
+
typescriptreact: SLASH_COMMENTS,
|
|
39
|
+
zig: SLASH_COMMENTS,
|
|
40
|
+
}));
|
|
41
|
+
/** Split snapshot text into lines without keeping a second copy of the file. */
|
|
42
|
+
function splitLines(text) {
|
|
43
|
+
return text.replace(/\r\n/g, "\n").split("\n");
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Definition source reader with one snapshot-file read per revision and path.
|
|
47
|
+
* The cache holds parsed lines, so a repeated call site of the same definition
|
|
48
|
+
* costs a slice rather than a `git show`.
|
|
49
|
+
*/
|
|
50
|
+
export function definitionReader(cwd) {
|
|
51
|
+
const files = new Map();
|
|
52
|
+
const linesOf = (snapshot, file) => {
|
|
53
|
+
const key = `${snapshot.kind}\0${snapshot.ref}\0${file}`;
|
|
54
|
+
const cached = files.get(key);
|
|
55
|
+
if (cached !== undefined)
|
|
56
|
+
return cached;
|
|
57
|
+
const text = readSnapshotFile(cwd, snapshot, file);
|
|
58
|
+
const lines = text === null ? null : splitLines(text);
|
|
59
|
+
files.set(key, lines);
|
|
60
|
+
return lines;
|
|
61
|
+
};
|
|
62
|
+
return (definition, snapshot) => {
|
|
63
|
+
const lines = linesOf(snapshot, definition.file);
|
|
64
|
+
if (!lines)
|
|
65
|
+
return {};
|
|
66
|
+
const line = definition.line;
|
|
67
|
+
const endLine = definition.endLine ?? line;
|
|
68
|
+
// A span the snapshot cannot cover means the definition is not at that
|
|
69
|
+
// place in this revision, so nothing about it can be stated.
|
|
70
|
+
if (line < 1 || endLine < line || endLine > lines.length)
|
|
71
|
+
return {};
|
|
72
|
+
const description = leadingDescription(definition.file, lines, line);
|
|
73
|
+
const source = {
|
|
74
|
+
file: definition.file,
|
|
75
|
+
line,
|
|
76
|
+
endLine,
|
|
77
|
+
ref: snapshot.ref.slice(0, 8),
|
|
78
|
+
text: lines.slice(line - 1, endLine).join("\n"),
|
|
79
|
+
};
|
|
80
|
+
return description === undefined ? { source } : { source, description };
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* First prose line of the definition's attached leading comment, or of its
|
|
85
|
+
* Python docstring. Decorators between comment and definition are stepped over.
|
|
86
|
+
*/
|
|
87
|
+
function leadingDescription(file, lines, line) {
|
|
88
|
+
const language = detectLanguage(file)?.id;
|
|
89
|
+
const syntax = language === undefined ? undefined : COMMENT_SYNTAX.get(language);
|
|
90
|
+
if (language === "python") {
|
|
91
|
+
const docstring = pythonDocstring(lines, line);
|
|
92
|
+
if (docstring !== undefined)
|
|
93
|
+
return docstring;
|
|
94
|
+
return commentProse(syntax, lines, decoratorAnchor(lines, line));
|
|
95
|
+
}
|
|
96
|
+
return commentProse(syntax, lines, line);
|
|
97
|
+
}
|
|
98
|
+
/** Top-most line of the decorator run directly above a Python definition. */
|
|
99
|
+
function decoratorAnchor(lines, line) {
|
|
100
|
+
let anchor = line;
|
|
101
|
+
for (let index = anchor - 2; index >= 0; index -= 1) {
|
|
102
|
+
if (!(lines[index] ?? "").trimStart().startsWith("@"))
|
|
103
|
+
break;
|
|
104
|
+
anchor = index + 1;
|
|
105
|
+
}
|
|
106
|
+
return anchor;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Prose of a comment block directly above `line`. A blank line breaks
|
|
110
|
+
* attachment, and a block comment whose opener is not found is dropped rather
|
|
111
|
+
* than attributed to the definition.
|
|
112
|
+
*/
|
|
113
|
+
function commentProse(syntax, lines, line) {
|
|
114
|
+
if (!syntax)
|
|
115
|
+
return undefined;
|
|
116
|
+
const above = (line - 2 >= 0 ? lines[line - 2] ?? "" : "").trim();
|
|
117
|
+
if (above === "")
|
|
118
|
+
return undefined;
|
|
119
|
+
const block = syntax.block;
|
|
120
|
+
const collected = [];
|
|
121
|
+
if (block && above.endsWith(block[1])) {
|
|
122
|
+
let opened = false;
|
|
123
|
+
for (let index = line - 2; index >= 0; index -= 1) {
|
|
124
|
+
const text = lines[index] ?? "";
|
|
125
|
+
collected.unshift(text);
|
|
126
|
+
if (text.includes(block[0])) {
|
|
127
|
+
opened = true;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (!opened)
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
else if (syntax.line.some((prefix) => above.startsWith(prefix))) {
|
|
135
|
+
for (let index = line - 2; index >= 0; index -= 1) {
|
|
136
|
+
const text = (lines[index] ?? "").trim();
|
|
137
|
+
if (!syntax.line.some((prefix) => text.startsWith(prefix)))
|
|
138
|
+
break;
|
|
139
|
+
collected.unshift(lines[index] ?? "");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
return firstProseLine(syntax, collected);
|
|
146
|
+
}
|
|
147
|
+
/** First line of a comment block that carries prose, with markers stripped. */
|
|
148
|
+
function firstProseLine(syntax, block) {
|
|
149
|
+
for (const raw of block) {
|
|
150
|
+
let text = raw.trim();
|
|
151
|
+
if (syntax.block) {
|
|
152
|
+
const [open, close] = syntax.block;
|
|
153
|
+
if (text.startsWith(open))
|
|
154
|
+
text = text.slice(open.length).trim();
|
|
155
|
+
if (text.endsWith(close))
|
|
156
|
+
text = text.slice(0, -close.length).trim();
|
|
157
|
+
}
|
|
158
|
+
for (const prefix of syntax.line) {
|
|
159
|
+
if (text.startsWith(prefix)) {
|
|
160
|
+
text = text.slice(prefix.length);
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (syntax.block && text.startsWith("*"))
|
|
165
|
+
text = text.slice(1);
|
|
166
|
+
text = text.trim();
|
|
167
|
+
// Separator lines (`---`, `***`) carry no prose.
|
|
168
|
+
if (text !== "" && !/^[*=~_+-]+$/.test(text))
|
|
169
|
+
return text;
|
|
170
|
+
}
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
/** Lines a Python signature may span before its colon is given up on. */
|
|
174
|
+
const PYTHON_SIGNATURE_MAX_LINES = 40;
|
|
175
|
+
/**
|
|
176
|
+
* One Python signature line: the bracket depth its code opens and the last
|
|
177
|
+
* non-space character of that code. Comment text and string contents are
|
|
178
|
+
* skipped, so a `#` or a bracket inside them cannot end the line or unbalance
|
|
179
|
+
* the count, and a comment can trail the colon it hides.
|
|
180
|
+
*/
|
|
181
|
+
function signatureLine(text) {
|
|
182
|
+
let last = "";
|
|
183
|
+
let delta = 0;
|
|
184
|
+
let quote = "";
|
|
185
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
186
|
+
const char = text[index];
|
|
187
|
+
if (quote !== "") {
|
|
188
|
+
if (char === "\\")
|
|
189
|
+
index += 1;
|
|
190
|
+
else if (char === quote)
|
|
191
|
+
quote = "";
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (char === "#")
|
|
195
|
+
break;
|
|
196
|
+
if (char !== " " && char !== "\t")
|
|
197
|
+
last = char;
|
|
198
|
+
if (char === '"' || char === "'")
|
|
199
|
+
quote = char;
|
|
200
|
+
else if (char === "(" || char === "[" || char === "{")
|
|
201
|
+
delta += 1;
|
|
202
|
+
else if (char === ")" || char === "]" || char === "}")
|
|
203
|
+
delta -= 1;
|
|
204
|
+
}
|
|
205
|
+
return { last, delta };
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Last line of a Python signature: the line whose code ends with `:` at bracket
|
|
209
|
+
* depth zero. A trailing comment cannot hide the colon and no line before it is
|
|
210
|
+
* skipped, so the search never walks on into the next definition and returns
|
|
211
|
+
* that one's docstring as this one's description.
|
|
212
|
+
*/
|
|
213
|
+
function signatureEnd(lines, line) {
|
|
214
|
+
let depth = 0;
|
|
215
|
+
const last = Math.min(line + PYTHON_SIGNATURE_MAX_LINES, lines.length);
|
|
216
|
+
for (let current = line; current <= last; current += 1) {
|
|
217
|
+
const { last: code, delta } = signatureLine(lines[current - 1] ?? "");
|
|
218
|
+
depth += delta;
|
|
219
|
+
if (depth > 0)
|
|
220
|
+
continue;
|
|
221
|
+
if (code === ":")
|
|
222
|
+
return current;
|
|
223
|
+
// Only an open bracket or an explicit continuation carries the signature to
|
|
224
|
+
// the next line; anything else is the body, so there is no signature here.
|
|
225
|
+
if (code !== "\\")
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
228
|
+
return undefined;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* First prose line of a Python docstring: the first string statement of the
|
|
232
|
+
* body. The signature is stepped over first, so a signature spanning several
|
|
233
|
+
* lines still finds its own docstring, and a body that opens with anything
|
|
234
|
+
* other than a string states no description.
|
|
235
|
+
*/
|
|
236
|
+
function pythonDocstring(lines, line) {
|
|
237
|
+
const body = signatureEnd(lines, line);
|
|
238
|
+
if (body === undefined)
|
|
239
|
+
return undefined;
|
|
240
|
+
for (let index = body; index < lines.length; index += 1) {
|
|
241
|
+
const text = (lines[index] ?? "").trim();
|
|
242
|
+
if (text === "" || text.startsWith("#"))
|
|
243
|
+
continue;
|
|
244
|
+
const open = /^(?:[rRuU]{0,2})("""|''')/.exec(text)?.[1];
|
|
245
|
+
if (!open)
|
|
246
|
+
return undefined;
|
|
247
|
+
const rest = text.slice(text.indexOf(open) + open.length);
|
|
248
|
+
const sameLine = rest.indexOf(open);
|
|
249
|
+
const opening = sameLine >= 0 ? rest.slice(0, sameLine) : rest;
|
|
250
|
+
// Prose on the opening line is the first line, the usual `"""Summary.`
|
|
251
|
+
// shape; only an opener standing alone moves the search below it.
|
|
252
|
+
if (opening.trim() !== "")
|
|
253
|
+
return proseOfDocstring([opening]);
|
|
254
|
+
const collected = [];
|
|
255
|
+
for (let next = index + 1; next < lines.length; next += 1) {
|
|
256
|
+
const raw = lines[next] ?? "";
|
|
257
|
+
const close = raw.indexOf(open);
|
|
258
|
+
if (close >= 0) {
|
|
259
|
+
collected.push(raw.slice(0, close));
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
collected.push(raw);
|
|
263
|
+
}
|
|
264
|
+
return proseOfDocstring(collected);
|
|
265
|
+
}
|
|
266
|
+
return undefined;
|
|
267
|
+
}
|
|
268
|
+
/** First non-empty line of docstring content, verbatim. */
|
|
269
|
+
function proseOfDocstring(lines) {
|
|
270
|
+
for (const raw of lines) {
|
|
271
|
+
const text = raw.trim();
|
|
272
|
+
if (text !== "")
|
|
273
|
+
return text;
|
|
274
|
+
}
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Byte-preserving TOML table edits for agent config files.
|
|
3
|
+
*
|
|
4
|
+
* The scanner walks the document statement by statement — skipping comments
|
|
5
|
+
* and every string form — so a table is addressed by its parsed key path
|
|
6
|
+
* rather than by matching text. Quoted keys, indented headers, and text that
|
|
7
|
+
* only looks like a header (inside a comment or a multiline string) therefore
|
|
8
|
+
* cannot misdirect an edit, and a table's whole subtree (nested tables and
|
|
9
|
+
* arrays of tables) is replaced or removed with it, wherever the document
|
|
10
|
+
* defines it: a header block, dotted keys, or an entry of an inline parent
|
|
11
|
+
* table. `smol-toml` parses the document before and after the edit: malformed
|
|
12
|
+
* input is reported instead of edited, and the result is only handed back when
|
|
13
|
+
* it parses and carries exactly the table the caller asked for.
|
|
14
|
+
*/
|
|
15
|
+
/** A rewritten document and whether it differs from the input. */
|
|
16
|
+
export interface TomlEdit {
|
|
17
|
+
text: string;
|
|
18
|
+
changed: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** Values this module writes: a string or an array of strings. */
|
|
21
|
+
export type TomlValue = string | string[];
|
|
22
|
+
/** Key/value pairs of one table, in the order they should be written. */
|
|
23
|
+
export type TomlTable = Record<string, TomlValue>;
|
|
24
|
+
/**
|
|
25
|
+
* Insert, replace, or extend the table at `target`, keeping every other byte
|
|
26
|
+
* of the document. A header-form table is replaced by a `[target]` block; a
|
|
27
|
+
* table defined with dotted or inline keys is rewritten in place as an inline
|
|
28
|
+
* table so the surrounding table body stays valid.
|
|
29
|
+
*/
|
|
30
|
+
export declare function upsertTomlTable(document: string, label: string, target: readonly string[], values: TomlTable): TomlEdit;
|
|
31
|
+
/**
|
|
32
|
+
* Remove the table at `target` and everything nested under it, wherever the
|
|
33
|
+
* document defines it: a `[target]` block with its subtree, dotted keys, or an
|
|
34
|
+
* entry of an inline parent table. Statements nested under `target` are
|
|
35
|
+
* removed even when unrelated tables sit between them. Every other byte of the
|
|
36
|
+
* document is kept.
|
|
37
|
+
*/
|
|
38
|
+
export declare function removeTomlTable(document: string, label: string, target: readonly string[]): TomlEdit;
|