sh-ast 0.0.0 → 0.2.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 (81) hide show
  1. package/README.md +147 -0
  2. package/dist/analyze/ansi-c-escapes.d.ts +53 -0
  3. package/dist/analyze/ansi-c-escapes.d.ts.map +1 -0
  4. package/dist/analyze/ansi-c-escapes.js +255 -0
  5. package/dist/analyze/ansi-c-escapes.js.map +1 -0
  6. package/dist/analyze/decode-lit.d.ts +74 -0
  7. package/dist/analyze/decode-lit.d.ts.map +1 -0
  8. package/dist/analyze/decode-lit.js +114 -0
  9. package/dist/analyze/decode-lit.js.map +1 -0
  10. package/dist/analyze/enumerate-commands.d.ts +165 -0
  11. package/dist/analyze/enumerate-commands.d.ts.map +1 -0
  12. package/dist/analyze/enumerate-commands.js +396 -0
  13. package/dist/analyze/enumerate-commands.js.map +1 -0
  14. package/dist/analyze/index.d.ts +26 -0
  15. package/dist/analyze/index.d.ts.map +1 -0
  16. package/dist/analyze/index.js +30 -0
  17. package/dist/analyze/index.js.map +1 -0
  18. package/dist/analyze/node-helpers.d.ts +28 -0
  19. package/dist/analyze/node-helpers.d.ts.map +1 -0
  20. package/dist/analyze/node-helpers.js +37 -0
  21. package/dist/analyze/node-helpers.js.map +1 -0
  22. package/dist/analyze/resolve-argv0.d.ts +335 -0
  23. package/dist/analyze/resolve-argv0.d.ts.map +1 -0
  24. package/dist/analyze/resolve-argv0.js +510 -0
  25. package/dist/analyze/resolve-argv0.js.map +1 -0
  26. package/dist/analyze/resolve-word.d.ts +151 -0
  27. package/dist/analyze/resolve-word.d.ts.map +1 -0
  28. package/dist/analyze/resolve-word.js +207 -0
  29. package/dist/analyze/resolve-word.js.map +1 -0
  30. package/dist/analyze.d.ts +771 -0
  31. package/dist/deep-freeze.d.ts +14 -0
  32. package/dist/deep-freeze.d.ts.map +1 -0
  33. package/dist/deep-freeze.js +25 -0
  34. package/dist/deep-freeze.js.map +1 -0
  35. package/dist/errors.d.ts +180 -0
  36. package/dist/errors.d.ts.map +1 -0
  37. package/dist/errors.js +179 -0
  38. package/dist/errors.js.map +1 -0
  39. package/dist/index.d.ts +18 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +5 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/normalize.d.ts +52 -0
  44. package/dist/normalize.d.ts.map +1 -0
  45. package/dist/normalize.js +260 -0
  46. package/dist/normalize.js.map +1 -0
  47. package/dist/parse-depth-guard.d.ts +11 -0
  48. package/dist/parse-depth-guard.d.ts.map +1 -0
  49. package/dist/parse-depth-guard.js +633 -0
  50. package/dist/parse-depth-guard.js.map +1 -0
  51. package/dist/parse.d.ts +50 -0
  52. package/dist/parse.d.ts.map +1 -0
  53. package/dist/parse.js +125 -0
  54. package/dist/parse.js.map +1 -0
  55. package/dist/sh-ast.d.ts +1346 -0
  56. package/dist/types.d.ts +74 -0
  57. package/dist/types.d.ts.map +1 -0
  58. package/dist/types.js +2 -0
  59. package/dist/types.js.map +1 -0
  60. package/dist/visitor-keys.d.ts +21 -0
  61. package/dist/visitor-keys.d.ts.map +1 -0
  62. package/dist/visitor-keys.js +23 -0
  63. package/dist/visitor-keys.js.map +1 -0
  64. package/dist/walk.d.ts +18 -0
  65. package/dist/walk.d.ts.map +1 -0
  66. package/dist/walk.js +40 -0
  67. package/dist/walk.js.map +1 -0
  68. package/dist/wasm-instance.d.ts +13 -0
  69. package/dist/wasm-instance.d.ts.map +1 -0
  70. package/dist/wasm-instance.js +88 -0
  71. package/dist/wasm-instance.js.map +1 -0
  72. package/generated/child-type-schema.d.ts +14 -0
  73. package/generated/child-type-schema.js +188 -0
  74. package/generated/node-types.d.ts +958 -0
  75. package/generated/position-fields.d.ts +21 -0
  76. package/generated/position-fields.js +50 -0
  77. package/generated/visitor-keys.d.ts +11 -0
  78. package/generated/visitor-keys.js +50 -0
  79. package/package.json +93 -10
  80. package/shim/sh-ast.wasm +0 -0
  81. package/shim/wasm_exec.js +654 -0
@@ -0,0 +1,1346 @@
1
+ /**
2
+ * Options accepted by {@link parseSync}.
3
+ *
4
+ * @public
5
+ */
6
+ export declare interface ParseOptions {
7
+ /**
8
+ * The shell dialect to parse against.
9
+ * @defaultValue `"bash"`
10
+ */
11
+ readonly dialect?: ShellDialect;
12
+ /**
13
+ * Filename used only to annotate error messages and positions; the source
14
+ * is never read from disk.
15
+ * @defaultValue `"input.sh"`
16
+ */
17
+ readonly filename?: string;
18
+ }
19
+
20
+ /**
21
+ * Synchronously parses shell source into a normalized AST.
22
+ *
23
+ * The first call instantiates the WASM shim synchronously (Node-only); the
24
+ * instance is reused across subsequent calls, so repeated calls do not
25
+ * re-instantiate (see design/ARCHITECTURE.md).
26
+ *
27
+ * Throws {@link ShParseError} on a shell syntax error, carrying the position
28
+ * mvdan/sh reported: `.line` is 1-based exactly as mvdan/sh reports it;
29
+ * `.column` is converted to UTF-16 code units so it agrees with
30
+ * {@link ShNode.loc}'s columns (mvdan/sh itself reports `column` as a byte
31
+ * count — see {@link ShParseErrorInfo.column}). That unconverted, raw
32
+ * position appears only inside `.message`, which is mvdan/sh's own
33
+ * formatted string, verbatim. Throws {@link ShInvalidDialectError} when
34
+ * {@link ParseOptions.dialect} is not a supported dialect. Throws
35
+ * {@link ShInternalError} for failures that should never happen given
36
+ * a correctly-behaving shim (malformed envelope, unexpected root node
37
+ * type, shim contract violations). Throws {@link ShParseMaxDepthError} if
38
+ * `text`'s conservatively estimated structural nesting depth exceeds the
39
+ * limit this bridge accepts — checked, and thrown, *before* `text` is ever
40
+ * handed to the WASM shim, since mvdan/sh's own parser has no recovery path
41
+ * for exhausting its stack on pathological nesting (see that error's doc
42
+ * comment and `parse-depth-guard.ts`).
43
+ *
44
+ * @public
45
+ */
46
+ export declare function parseSync(text: string, options?: ParseOptions): ShFile;
47
+
48
+ /**
49
+ * A 1-based line/column position. Columns are UTF-16 code units, matching
50
+ * JavaScript string indexing (see {@link ShNode.range}).
51
+ *
52
+ * @public
53
+ */
54
+ export declare interface Position {
55
+ readonly line: number;
56
+ readonly column: number;
57
+ }
58
+
59
+ /**
60
+ * Thrown by `sh-ast/analyze`'s `resolveArgv0` when a caller-supplied
61
+ * `options.transparentWrappers` array contains a malformed `WrapperSpec`
62
+ * entry — e.g. a non-array or empty `names`, or a flag field that isn't an
63
+ * array of strings. Fails closed with a clear, specific message at the
64
+ * point the malformed table is supplied, rather than letting the bad shape
65
+ * reach flag-matching logic and surface as a confusing native `TypeError`
66
+ * (or, worse, a silently wrong match) far from its actual cause.
67
+ *
68
+ * @public
69
+ */
70
+ export declare class ShAnalyzeInvalidWrapperSpecError extends ShAstError {
71
+ readonly code = "SH_AST_ANALYZE_INVALID_WRAPPER_SPEC";
72
+ constructor(message: string);
73
+ }
74
+
75
+ /**
76
+ * Thrown by `sh-ast/analyze`'s `enumerateCommands` when a tree's genuinely
77
+ * nested structure — subshells within subshells, chained command/process
78
+ * substitutions, deeply nested `if`/`case`/loop/function/`time`/`{ }`
79
+ * bodies, deeply chained `elif` — exceeds its defensive recursion-depth
80
+ * guard. **Not** thrown for a long *linear* chain (`|`/`|&`/`&&`/`||` of
81
+ * any realistic length): `enumerateCommands` traverses those iteratively,
82
+ * so chain length alone never grows this guard's depth counter — only
83
+ * genuine tree nesting does.
84
+ *
85
+ * `enumerateCommands` deliberately fails closed here rather than returning
86
+ * a truncated, partial result: a partial `CommandSite[]` silently omits
87
+ * real command sites, which is a false negative for a permission-hook-style
88
+ * consumer that treats "command not found in the enumeration" as "nothing
89
+ * to worry about" — an explicit, documented throw is safer than a silent
90
+ * under-report. Gate-style consumers should treat this error as `deny`,
91
+ * not fall back to "no commands found, so allow".
92
+ *
93
+ * @public
94
+ */
95
+ export declare class ShAnalyzeMaxDepthError extends ShAstError {
96
+ readonly code = "SH_AST_ANALYZE_MAX_DEPTH";
97
+ /** The maximum nesting depth `enumerateCommands` supports; the same value every time (not caller-configurable). */
98
+ readonly maxDepth: number;
99
+ constructor(maxDepth: number);
100
+ }
101
+
102
+ /**
103
+ * The union of every normalized node type this bridge can produce.
104
+ *
105
+ * @public
106
+ */
107
+ declare type ShAnyNode =
108
+ | ShArithmCmdNode
109
+ | ShArithmExpNode
110
+ | ShArrayElemNode
111
+ | ShArrayExprNode
112
+ | ShAssignNode
113
+ | ShBinaryArithmNode
114
+ | ShBinaryCmdNode
115
+ | ShBinaryTestNode
116
+ | ShBlockNode
117
+ | ShBraceExpNode
118
+ | ShCStyleLoopNode
119
+ | ShCallExprNode
120
+ | ShCaseClauseNode
121
+ | ShCaseItemNode
122
+ | ShCmdSubstNode
123
+ | ShCommentNode
124
+ | ShCoprocClauseNode
125
+ | ShDblQuotedNode
126
+ | ShDeclClauseNode
127
+ | ShExpansionNode
128
+ | ShExtGlobNode
129
+ | ShFileNode
130
+ | ShFlagsArithmNode
131
+ | ShForClauseNode
132
+ | ShFuncDeclNode
133
+ | ShIfClauseNode
134
+ | ShLetClauseNode
135
+ | ShLitNode
136
+ | ShParamExpNode
137
+ | ShParenArithmNode
138
+ | ShParenTestNode
139
+ | ShProcSubstNode
140
+ | ShRedirectNode
141
+ | ShReplaceNode
142
+ | ShSglQuotedNode
143
+ | ShSliceNode
144
+ | ShStmtNode
145
+ | ShSubshellNode
146
+ | ShTestClauseNode
147
+ | ShTestDeclNode
148
+ | ShTimeClauseNode
149
+ | ShUnaryArithmNode
150
+ | ShUnaryTestNode
151
+ | ShWhileClauseNode
152
+ | ShWordNode
153
+ | ShWordIterNode;
154
+
155
+ /**
156
+ * mvdan/sh's `syntax.ArithmCmd`, normalized.
157
+ *
158
+ * @public
159
+ */
160
+ declare interface ShArithmCmdNode {
161
+ readonly type: 'ArithmCmd';
162
+ readonly range: readonly [number, number];
163
+ readonly loc: {
164
+ readonly start: { readonly line: number; readonly column: number };
165
+ readonly end: { readonly line: number; readonly column: number };
166
+ };
167
+ [field: string]: unknown;
168
+ readonly x?: ShArithmExprNode;
169
+ }
170
+
171
+ /**
172
+ * mvdan/sh's `syntax.ArithmExp`, normalized.
173
+ *
174
+ * @public
175
+ */
176
+ declare interface ShArithmExpNode {
177
+ readonly type: 'ArithmExp';
178
+ readonly range: readonly [number, number];
179
+ readonly loc: {
180
+ readonly start: { readonly line: number; readonly column: number };
181
+ readonly end: { readonly line: number; readonly column: number };
182
+ };
183
+ [field: string]: unknown;
184
+ readonly x?: ShArithmExprNode;
185
+ }
186
+
187
+ /**
188
+ * The union of concrete node types mvdan/sh's `syntax.ArithmExpr` interface can
189
+ * hold.
190
+ *
191
+ * @public
192
+ */
193
+ declare type ShArithmExprNode =
194
+ ShBinaryArithmNode | ShFlagsArithmNode | ShParenArithmNode | ShUnaryArithmNode | ShWordNode;
195
+
196
+ /**
197
+ * mvdan/sh's `syntax.ArrayElem`, normalized.
198
+ *
199
+ * @public
200
+ */
201
+ declare interface ShArrayElemNode {
202
+ readonly type: 'ArrayElem';
203
+ readonly range: readonly [number, number];
204
+ readonly loc: {
205
+ readonly start: { readonly line: number; readonly column: number };
206
+ readonly end: { readonly line: number; readonly column: number };
207
+ };
208
+ [field: string]: unknown;
209
+ readonly comments: readonly ShCommentNode[];
210
+ readonly index?: ShArithmExprNode;
211
+ readonly value?: ShWordNode;
212
+ }
213
+
214
+ /**
215
+ * mvdan/sh's `syntax.ArrayExpr`, normalized.
216
+ *
217
+ * @public
218
+ */
219
+ declare interface ShArrayExprNode {
220
+ readonly type: 'ArrayExpr';
221
+ readonly range: readonly [number, number];
222
+ readonly loc: {
223
+ readonly start: { readonly line: number; readonly column: number };
224
+ readonly end: { readonly line: number; readonly column: number };
225
+ };
226
+ [field: string]: unknown;
227
+ readonly elems: readonly ShArrayElemNode[];
228
+ readonly last: readonly ShCommentNode[];
229
+ }
230
+
231
+ /**
232
+ * mvdan/sh's `syntax.Assign`, normalized.
233
+ *
234
+ * @public
235
+ */
236
+ declare interface ShAssignNode {
237
+ readonly type: 'Assign';
238
+ readonly range: readonly [number, number];
239
+ readonly loc: {
240
+ readonly start: { readonly line: number; readonly column: number };
241
+ readonly end: { readonly line: number; readonly column: number };
242
+ };
243
+ [field: string]: unknown;
244
+ readonly array?: ShArrayExprNode;
245
+ readonly index?: ShArithmExprNode;
246
+ readonly name?: ShLitNode;
247
+ readonly value?: ShWordNode;
248
+ }
249
+
250
+ /**
251
+ * Common base class for every error this package throws — originally just
252
+ * {@link sh-ast#parseSync | parseSync}'s errors, now also the
253
+ * `sh-ast/analyze` layer's (see {@link ShAnalyzeMaxDepthError},
254
+ * {@link ShAnalyzeInvalidWrapperSpecError}). Provides a stable, documented
255
+ * `code` discriminator (e.g. `"SH_AST_PARSE_ERROR"`) alongside the usual
256
+ * `instanceof` narrowing, so consumers can branch on failure kind
257
+ * programmatically without parsing `.message` strings. Never thrown directly
258
+ * — only via its concrete subclasses
259
+ * ({@link sh-ast#ShParseError | ShParseError},
260
+ * {@link sh-ast#ShInvalidDialectError | ShInvalidDialectError},
261
+ * {@link sh-ast#ShInternalError | ShInternalError},
262
+ * {@link ShAnalyzeMaxDepthError},
263
+ * {@link sh-ast#ShParseMaxDepthError | ShParseMaxDepthError},
264
+ * {@link ShAnalyzeInvalidWrapperSpecError}).
265
+ *
266
+ * Re-exported from `sh-ast/analyze` as well as the root `sh-ast` entry
267
+ * point (see #23) — every subclass thrown by `sh-ast/analyze`'s own
268
+ * functions extends this, so a consumer of that subpath alone can
269
+ * `catch`/reference the base without also importing from root.
270
+ *
271
+ * @public
272
+ */
273
+ export declare abstract class ShAstError extends Error {
274
+ /**
275
+ * Stable, machine-readable discriminator for this error kind. Distinct
276
+ * per subclass and will not change once published.
277
+ */
278
+ abstract readonly code: string;
279
+ }
280
+
281
+ /**
282
+ * mvdan/sh's `syntax.BinaryArithm`, normalized.
283
+ *
284
+ * @public
285
+ */
286
+ declare interface ShBinaryArithmNode {
287
+ readonly type: 'BinaryArithm';
288
+ readonly range: readonly [number, number];
289
+ readonly loc: {
290
+ readonly start: { readonly line: number; readonly column: number };
291
+ readonly end: { readonly line: number; readonly column: number };
292
+ };
293
+ [field: string]: unknown;
294
+ readonly x?: ShArithmExprNode;
295
+ readonly y?: ShArithmExprNode;
296
+ }
297
+
298
+ /**
299
+ * mvdan/sh's `syntax.BinaryCmd`, normalized.
300
+ *
301
+ * @public
302
+ */
303
+ declare interface ShBinaryCmdNode {
304
+ readonly type: 'BinaryCmd';
305
+ readonly range: readonly [number, number];
306
+ readonly loc: {
307
+ readonly start: { readonly line: number; readonly column: number };
308
+ readonly end: { readonly line: number; readonly column: number };
309
+ };
310
+ [field: string]: unknown;
311
+ readonly x?: ShStmtNode;
312
+ readonly y?: ShStmtNode;
313
+ }
314
+
315
+ /**
316
+ * mvdan/sh's `syntax.BinaryTest`, normalized.
317
+ *
318
+ * @public
319
+ */
320
+ declare interface ShBinaryTestNode {
321
+ readonly type: 'BinaryTest';
322
+ readonly range: readonly [number, number];
323
+ readonly loc: {
324
+ readonly start: { readonly line: number; readonly column: number };
325
+ readonly end: { readonly line: number; readonly column: number };
326
+ };
327
+ [field: string]: unknown;
328
+ readonly x?: ShTestExprNode;
329
+ readonly y?: ShTestExprNode;
330
+ }
331
+
332
+ /**
333
+ * mvdan/sh's `syntax.Block`, normalized.
334
+ *
335
+ * @public
336
+ */
337
+ declare interface ShBlockNode {
338
+ readonly type: 'Block';
339
+ readonly range: readonly [number, number];
340
+ readonly loc: {
341
+ readonly start: { readonly line: number; readonly column: number };
342
+ readonly end: { readonly line: number; readonly column: number };
343
+ };
344
+ [field: string]: unknown;
345
+ readonly last: readonly ShCommentNode[];
346
+ readonly stmts: readonly ShStmtNode[];
347
+ }
348
+
349
+ /**
350
+ * mvdan/sh's `syntax.BraceExp`, normalized.
351
+ *
352
+ * @public
353
+ */
354
+ declare interface ShBraceExpNode {
355
+ readonly type: 'BraceExp';
356
+ readonly range: readonly [number, number];
357
+ readonly loc: {
358
+ readonly start: { readonly line: number; readonly column: number };
359
+ readonly end: { readonly line: number; readonly column: number };
360
+ };
361
+ [field: string]: unknown;
362
+ readonly elems: readonly ShWordNode[];
363
+ }
364
+
365
+ /**
366
+ * mvdan/sh's `syntax.CallExpr`, normalized.
367
+ *
368
+ * @public
369
+ */
370
+ declare interface ShCallExprNode {
371
+ readonly type: 'CallExpr';
372
+ readonly range: readonly [number, number];
373
+ readonly loc: {
374
+ readonly start: { readonly line: number; readonly column: number };
375
+ readonly end: { readonly line: number; readonly column: number };
376
+ };
377
+ [field: string]: unknown;
378
+ readonly args: readonly ShWordNode[];
379
+ readonly assigns: readonly ShAssignNode[];
380
+ }
381
+
382
+ /**
383
+ * mvdan/sh's `syntax.CaseClause`, normalized.
384
+ *
385
+ * @public
386
+ */
387
+ declare interface ShCaseClauseNode {
388
+ readonly type: 'CaseClause';
389
+ readonly range: readonly [number, number];
390
+ readonly loc: {
391
+ readonly start: { readonly line: number; readonly column: number };
392
+ readonly end: { readonly line: number; readonly column: number };
393
+ };
394
+ [field: string]: unknown;
395
+ readonly items: readonly ShCaseItemNode[];
396
+ readonly last: readonly ShCommentNode[];
397
+ readonly word?: ShWordNode;
398
+ }
399
+
400
+ /**
401
+ * mvdan/sh's `syntax.CaseItem`, normalized.
402
+ *
403
+ * @public
404
+ */
405
+ declare interface ShCaseItemNode {
406
+ readonly type: 'CaseItem';
407
+ readonly range: readonly [number, number];
408
+ readonly loc: {
409
+ readonly start: { readonly line: number; readonly column: number };
410
+ readonly end: { readonly line: number; readonly column: number };
411
+ };
412
+ [field: string]: unknown;
413
+ readonly comments: readonly ShCommentNode[];
414
+ readonly last: readonly ShCommentNode[];
415
+ readonly patterns: readonly ShWordNode[];
416
+ readonly stmts: readonly ShStmtNode[];
417
+ }
418
+
419
+ /**
420
+ * mvdan/sh's `syntax.CmdSubst`, normalized.
421
+ *
422
+ * @public
423
+ */
424
+ declare interface ShCmdSubstNode {
425
+ readonly type: 'CmdSubst';
426
+ readonly range: readonly [number, number];
427
+ readonly loc: {
428
+ readonly start: { readonly line: number; readonly column: number };
429
+ readonly end: { readonly line: number; readonly column: number };
430
+ };
431
+ [field: string]: unknown;
432
+ readonly last: readonly ShCommentNode[];
433
+ readonly stmts: readonly ShStmtNode[];
434
+ }
435
+
436
+ /**
437
+ * The union of concrete node types mvdan/sh's `syntax.Command` interface can
438
+ * hold.
439
+ *
440
+ * @public
441
+ */
442
+ declare type ShCommandNode =
443
+ | ShArithmCmdNode
444
+ | ShBinaryCmdNode
445
+ | ShBlockNode
446
+ | ShCallExprNode
447
+ | ShCaseClauseNode
448
+ | ShCoprocClauseNode
449
+ | ShDeclClauseNode
450
+ | ShForClauseNode
451
+ | ShFuncDeclNode
452
+ | ShIfClauseNode
453
+ | ShLetClauseNode
454
+ | ShSubshellNode
455
+ | ShTestClauseNode
456
+ | ShTestDeclNode
457
+ | ShTimeClauseNode
458
+ | ShWhileClauseNode;
459
+
460
+ /**
461
+ * mvdan/sh's `syntax.Comment`, normalized.
462
+ *
463
+ * @public
464
+ */
465
+ declare interface ShCommentNode {
466
+ readonly type: 'Comment';
467
+ readonly range: readonly [number, number];
468
+ readonly loc: {
469
+ readonly start: { readonly line: number; readonly column: number };
470
+ readonly end: { readonly line: number; readonly column: number };
471
+ };
472
+ [field: string]: unknown;
473
+ }
474
+
475
+ /**
476
+ * mvdan/sh's `syntax.CoprocClause`, normalized.
477
+ *
478
+ * @public
479
+ */
480
+ declare interface ShCoprocClauseNode {
481
+ readonly type: 'CoprocClause';
482
+ readonly range: readonly [number, number];
483
+ readonly loc: {
484
+ readonly start: { readonly line: number; readonly column: number };
485
+ readonly end: { readonly line: number; readonly column: number };
486
+ };
487
+ [field: string]: unknown;
488
+ readonly name?: ShWordNode;
489
+ readonly stmt?: ShStmtNode;
490
+ }
491
+
492
+ /**
493
+ * mvdan/sh's `syntax.CStyleLoop`, normalized.
494
+ *
495
+ * @public
496
+ */
497
+ declare interface ShCStyleLoopNode {
498
+ readonly type: 'CStyleLoop';
499
+ readonly range: readonly [number, number];
500
+ readonly loc: {
501
+ readonly start: { readonly line: number; readonly column: number };
502
+ readonly end: { readonly line: number; readonly column: number };
503
+ };
504
+ [field: string]: unknown;
505
+ readonly cond?: ShArithmExprNode;
506
+ readonly init?: ShArithmExprNode;
507
+ readonly post?: ShArithmExprNode;
508
+ }
509
+
510
+ /**
511
+ * mvdan/sh's `syntax.DblQuoted`, normalized.
512
+ *
513
+ * @public
514
+ */
515
+ declare interface ShDblQuotedNode {
516
+ readonly type: 'DblQuoted';
517
+ readonly range: readonly [number, number];
518
+ readonly loc: {
519
+ readonly start: { readonly line: number; readonly column: number };
520
+ readonly end: { readonly line: number; readonly column: number };
521
+ };
522
+ [field: string]: unknown;
523
+ readonly parts: readonly ShWordPartNode[];
524
+ }
525
+
526
+ /**
527
+ * mvdan/sh's `syntax.DeclClause`, normalized.
528
+ *
529
+ * @public
530
+ */
531
+ declare interface ShDeclClauseNode {
532
+ readonly type: 'DeclClause';
533
+ readonly range: readonly [number, number];
534
+ readonly loc: {
535
+ readonly start: { readonly line: number; readonly column: number };
536
+ readonly end: { readonly line: number; readonly column: number };
537
+ };
538
+ [field: string]: unknown;
539
+ readonly args: readonly ShAssignNode[];
540
+ readonly variant?: ShLitNode;
541
+ }
542
+
543
+ /**
544
+ * Shell dialect (mvdan/sh `LangVariant`) to parse against. Mapped to
545
+ * `LangVariant` by string name via `LangVariant.Set()` — never by numeric
546
+ * value, since the bit-flag encoding of `LangVariant` is not a stable
547
+ * contract across mvdan/sh versions. See design/ARCHITECTURE.md, "Parse
548
+ * errors and dialects".
549
+ *
550
+ * @public
551
+ */
552
+ export declare type ShellDialect = 'bash' | 'posix' | 'mksh' | 'bats' | 'zsh';
553
+
554
+ /**
555
+ * mvdan/sh's `syntax.Expansion`, normalized.
556
+ *
557
+ * @public
558
+ */
559
+ declare interface ShExpansionNode {
560
+ readonly type: 'Expansion';
561
+ readonly range: readonly [number, number];
562
+ readonly loc: {
563
+ readonly start: { readonly line: number; readonly column: number };
564
+ readonly end: { readonly line: number; readonly column: number };
565
+ };
566
+ [field: string]: unknown;
567
+ readonly word?: ShWordNode;
568
+ }
569
+
570
+ /**
571
+ * mvdan/sh's `syntax.ExtGlob`, normalized.
572
+ *
573
+ * @public
574
+ */
575
+ declare interface ShExtGlobNode {
576
+ readonly type: 'ExtGlob';
577
+ readonly range: readonly [number, number];
578
+ readonly loc: {
579
+ readonly start: { readonly line: number; readonly column: number };
580
+ readonly end: { readonly line: number; readonly column: number };
581
+ };
582
+ [field: string]: unknown;
583
+ readonly pattern?: ShLitNode;
584
+ }
585
+
586
+ /**
587
+ * The root node of a parsed shell script.
588
+ *
589
+ * @public
590
+ */
591
+ export declare interface ShFile extends ShNode {
592
+ readonly type: 'File';
593
+ readonly stmts: readonly ShNode[];
594
+ }
595
+
596
+ /**
597
+ * mvdan/sh's `syntax.File`, normalized.
598
+ *
599
+ * @public
600
+ */
601
+ declare interface ShFileNode {
602
+ readonly type: 'File';
603
+ readonly range: readonly [number, number];
604
+ readonly loc: {
605
+ readonly start: { readonly line: number; readonly column: number };
606
+ readonly end: { readonly line: number; readonly column: number };
607
+ };
608
+ [field: string]: unknown;
609
+ readonly last: readonly ShCommentNode[];
610
+ readonly stmts: readonly ShStmtNode[];
611
+ }
612
+
613
+ /**
614
+ * mvdan/sh's `syntax.FlagsArithm`, normalized.
615
+ *
616
+ * @public
617
+ */
618
+ declare interface ShFlagsArithmNode {
619
+ readonly type: 'FlagsArithm';
620
+ readonly range: readonly [number, number];
621
+ readonly loc: {
622
+ readonly start: { readonly line: number; readonly column: number };
623
+ readonly end: { readonly line: number; readonly column: number };
624
+ };
625
+ [field: string]: unknown;
626
+ readonly flags?: ShLitNode;
627
+ readonly x?: ShArithmExprNode;
628
+ }
629
+
630
+ /**
631
+ * mvdan/sh's `syntax.ForClause`, normalized.
632
+ *
633
+ * @public
634
+ */
635
+ declare interface ShForClauseNode {
636
+ readonly type: 'ForClause';
637
+ readonly range: readonly [number, number];
638
+ readonly loc: {
639
+ readonly start: { readonly line: number; readonly column: number };
640
+ readonly end: { readonly line: number; readonly column: number };
641
+ };
642
+ [field: string]: unknown;
643
+ readonly do: readonly ShStmtNode[];
644
+ readonly dolast: readonly ShCommentNode[];
645
+ readonly loop?: ShLoopNode;
646
+ }
647
+
648
+ /**
649
+ * mvdan/sh's `syntax.FuncDecl`, normalized.
650
+ *
651
+ * @public
652
+ */
653
+ declare interface ShFuncDeclNode {
654
+ readonly type: 'FuncDecl';
655
+ readonly range: readonly [number, number];
656
+ readonly loc: {
657
+ readonly start: { readonly line: number; readonly column: number };
658
+ readonly end: { readonly line: number; readonly column: number };
659
+ };
660
+ [field: string]: unknown;
661
+ readonly body?: ShStmtNode;
662
+ readonly name?: ShLitNode;
663
+ readonly names: readonly ShLitNode[];
664
+ }
665
+
666
+ /**
667
+ * mvdan/sh's `syntax.IfClause`, normalized.
668
+ *
669
+ * @public
670
+ */
671
+ declare interface ShIfClauseNode {
672
+ readonly type: 'IfClause';
673
+ readonly range: readonly [number, number];
674
+ readonly loc: {
675
+ readonly start: { readonly line: number; readonly column: number };
676
+ readonly end: { readonly line: number; readonly column: number };
677
+ };
678
+ [field: string]: unknown;
679
+ readonly cond: readonly ShStmtNode[];
680
+ readonly condlast: readonly ShCommentNode[];
681
+ readonly else?: ShIfClauseNode;
682
+ readonly last: readonly ShCommentNode[];
683
+ readonly then: readonly ShStmtNode[];
684
+ readonly thenlast: readonly ShCommentNode[];
685
+ }
686
+
687
+ /**
688
+ * Thrown by {@link parseSync} for failures that should never happen given a
689
+ * correctly-behaving WASM shim: a malformed result envelope, an unexpected
690
+ * root node type, or any other shim contract violation. Distinct from
691
+ * {@link ShInvalidDialectError} and {@link ShParseError}, both of which
692
+ * indicate a foreseeable, actionable user mistake rather than an internal
693
+ * defect.
694
+ *
695
+ * @public
696
+ */
697
+ export declare class ShInternalError extends ShAstError {
698
+ readonly code = "SH_AST_INTERNAL";
699
+ constructor(message: string);
700
+ }
701
+
702
+ /**
703
+ * Thrown by {@link parseSync} when {@link ParseOptions.dialect} is not one
704
+ * of the supported {@link ShellDialect} values. Carries the rejected value
705
+ * as `.dialect`; `.message` lists the supported dialects. A foreseeable,
706
+ * actionable user mistake — never an instance of {@link ShParseError}.
707
+ *
708
+ * @public
709
+ */
710
+ export declare class ShInvalidDialectError extends ShAstError {
711
+ readonly code = "SH_AST_INVALID_DIALECT";
712
+ /** The rejected dialect value, exactly as passed to {@link parseSync}. */
713
+ readonly dialect: string;
714
+ constructor(dialect: string, supportedDialects: readonly ShellDialect[]);
715
+ }
716
+
717
+ /**
718
+ * mvdan/sh's `syntax.LetClause`, normalized.
719
+ *
720
+ * @public
721
+ */
722
+ declare interface ShLetClauseNode {
723
+ readonly type: 'LetClause';
724
+ readonly range: readonly [number, number];
725
+ readonly loc: {
726
+ readonly start: { readonly line: number; readonly column: number };
727
+ readonly end: { readonly line: number; readonly column: number };
728
+ };
729
+ [field: string]: unknown;
730
+ readonly exprs: readonly ShArithmExprNode[];
731
+ }
732
+
733
+ /**
734
+ * mvdan/sh's `syntax.Lit`, normalized.
735
+ *
736
+ * @public
737
+ */
738
+ declare interface ShLitNode {
739
+ readonly type: 'Lit';
740
+ readonly range: readonly [number, number];
741
+ readonly loc: {
742
+ readonly start: { readonly line: number; readonly column: number };
743
+ readonly end: { readonly line: number; readonly column: number };
744
+ };
745
+ [field: string]: unknown;
746
+ }
747
+
748
+ /**
749
+ * The union of concrete node types mvdan/sh's `syntax.Loop` interface can
750
+ * hold.
751
+ *
752
+ * @public
753
+ */
754
+ declare type ShLoopNode = ShCStyleLoopNode | ShWordIterNode;
755
+
756
+ /**
757
+ * A normalized AST node produced by {@link sh-ast#parseSync | parseSync}.
758
+ *
759
+ * `range` and `loc` are expressed in UTF-16 code units, so
760
+ * `code.slice(node.range[0], node.range[1])` reproduces the node's exact
761
+ * source text — even though mvdan/sh itself reports byte offsets and
762
+ * byte-counting columns internally (see design/ARCHITECTURE.md's
763
+ * "Serialization contract"). Every other field copied over from mvdan/sh's
764
+ * typedjson tree keeps its original value but with the field name
765
+ * lowercased (`Stmts` becomes `stmts`, `CondLast` becomes `condlast`, etc.).
766
+ *
767
+ * Also re-exported from `sh-ast/analyze` (see #23) — the subpath's public
768
+ * surface consumes and exposes `ShNode`, so a consumer can reference the type
769
+ * without also importing from the root `sh-ast` entry point.
770
+ *
771
+ * @public
772
+ */
773
+ export declare interface ShNode {
774
+ readonly type: string;
775
+ readonly range: readonly [number, number];
776
+ readonly loc: {
777
+ readonly start: Position;
778
+ readonly end: Position;
779
+ };
780
+ [field: string]: unknown;
781
+ }
782
+
783
+ export declare namespace ShNodes {
784
+ export {
785
+ ShArithmCmdNode,
786
+ ShArithmExpNode,
787
+ ShArrayElemNode,
788
+ ShArrayExprNode,
789
+ ShAssignNode,
790
+ ShBinaryArithmNode,
791
+ ShBinaryCmdNode,
792
+ ShBinaryTestNode,
793
+ ShBlockNode,
794
+ ShBraceExpNode,
795
+ ShCStyleLoopNode,
796
+ ShCallExprNode,
797
+ ShCaseClauseNode,
798
+ ShCaseItemNode,
799
+ ShCmdSubstNode,
800
+ ShCommentNode,
801
+ ShCoprocClauseNode,
802
+ ShDblQuotedNode,
803
+ ShDeclClauseNode,
804
+ ShExpansionNode,
805
+ ShExtGlobNode,
806
+ ShFileNode,
807
+ ShFlagsArithmNode,
808
+ ShForClauseNode,
809
+ ShFuncDeclNode,
810
+ ShIfClauseNode,
811
+ ShLetClauseNode,
812
+ ShLitNode,
813
+ ShParamExpNode,
814
+ ShParenArithmNode,
815
+ ShParenTestNode,
816
+ ShProcSubstNode,
817
+ ShRedirectNode,
818
+ ShReplaceNode,
819
+ ShSglQuotedNode,
820
+ ShSliceNode,
821
+ ShStmtNode,
822
+ ShSubshellNode,
823
+ ShTestClauseNode,
824
+ ShTestDeclNode,
825
+ ShTimeClauseNode,
826
+ ShUnaryArithmNode,
827
+ ShUnaryTestNode,
828
+ ShWhileClauseNode,
829
+ ShWordNode,
830
+ ShWordIterNode,
831
+ ShArithmExprNode,
832
+ ShCommandNode,
833
+ ShLoopNode,
834
+ ShTestExprNode,
835
+ ShWordPartNode,
836
+ ShAnyNode,
837
+ ShNodeTypeName
838
+ }
839
+ }
840
+
841
+ /**
842
+ * Every normalized node `type` string this bridge can produce.
843
+ *
844
+ * @public
845
+ */
846
+ declare type ShNodeTypeName =
847
+ | 'ArithmCmd'
848
+ | 'ArithmExp'
849
+ | 'ArrayElem'
850
+ | 'ArrayExpr'
851
+ | 'Assign'
852
+ | 'BinaryArithm'
853
+ | 'BinaryCmd'
854
+ | 'BinaryTest'
855
+ | 'Block'
856
+ | 'BraceExp'
857
+ | 'CStyleLoop'
858
+ | 'CallExpr'
859
+ | 'CaseClause'
860
+ | 'CaseItem'
861
+ | 'CmdSubst'
862
+ | 'Comment'
863
+ | 'CoprocClause'
864
+ | 'DblQuoted'
865
+ | 'DeclClause'
866
+ | 'Expansion'
867
+ | 'ExtGlob'
868
+ | 'File'
869
+ | 'FlagsArithm'
870
+ | 'ForClause'
871
+ | 'FuncDecl'
872
+ | 'IfClause'
873
+ | 'LetClause'
874
+ | 'Lit'
875
+ | 'ParamExp'
876
+ | 'ParenArithm'
877
+ | 'ParenTest'
878
+ | 'ProcSubst'
879
+ | 'Redirect'
880
+ | 'Replace'
881
+ | 'SglQuoted'
882
+ | 'Slice'
883
+ | 'Stmt'
884
+ | 'Subshell'
885
+ | 'TestClause'
886
+ | 'TestDecl'
887
+ | 'TimeClause'
888
+ | 'UnaryArithm'
889
+ | 'UnaryTest'
890
+ | 'WhileClause'
891
+ | 'Word'
892
+ | 'WordIter';
893
+
894
+ /**
895
+ * mvdan/sh's `syntax.ParamExp`, normalized.
896
+ *
897
+ * @public
898
+ */
899
+ declare interface ShParamExpNode {
900
+ readonly type: 'ParamExp';
901
+ readonly range: readonly [number, number];
902
+ readonly loc: {
903
+ readonly start: { readonly line: number; readonly column: number };
904
+ readonly end: { readonly line: number; readonly column: number };
905
+ };
906
+ [field: string]: unknown;
907
+ readonly exp?: ShExpansionNode;
908
+ readonly flags?: ShLitNode;
909
+ readonly index?: ShArithmExprNode;
910
+ readonly modifiers: readonly ShLitNode[];
911
+ readonly nestedparam?: ShWordPartNode;
912
+ readonly param?: ShLitNode;
913
+ readonly repl?: ShReplaceNode;
914
+ readonly slice?: ShSliceNode;
915
+ }
916
+
917
+ /**
918
+ * mvdan/sh's `syntax.ParenArithm`, normalized.
919
+ *
920
+ * @public
921
+ */
922
+ declare interface ShParenArithmNode {
923
+ readonly type: 'ParenArithm';
924
+ readonly range: readonly [number, number];
925
+ readonly loc: {
926
+ readonly start: { readonly line: number; readonly column: number };
927
+ readonly end: { readonly line: number; readonly column: number };
928
+ };
929
+ [field: string]: unknown;
930
+ readonly x?: ShArithmExprNode;
931
+ }
932
+
933
+ /**
934
+ * mvdan/sh's `syntax.ParenTest`, normalized.
935
+ *
936
+ * @public
937
+ */
938
+ declare interface ShParenTestNode {
939
+ readonly type: 'ParenTest';
940
+ readonly range: readonly [number, number];
941
+ readonly loc: {
942
+ readonly start: { readonly line: number; readonly column: number };
943
+ readonly end: { readonly line: number; readonly column: number };
944
+ };
945
+ [field: string]: unknown;
946
+ readonly x?: ShTestExprNode;
947
+ }
948
+
949
+ /**
950
+ * Thrown by {@link parseSync} when shell source fails to parse. Carries the
951
+ * real position mvdan/sh reported — never 1:1 placeholders: `.line` is
952
+ * 1-based exactly as mvdan/sh reports it, and `.column` is converted to
953
+ * UTF-16 code units so it agrees with {@link ShNode.loc}'s columns (mvdan/sh
954
+ * itself reports `column` as a byte count on the source line — see
955
+ * {@link ShParseErrorInfo.column}). The unconverted, raw byte-column
956
+ * position appears only inside `.message`, mvdan/sh's own formatted string,
957
+ * verbatim.
958
+ *
959
+ * @public
960
+ */
961
+ export declare class ShParseError extends ShAstError {
962
+ readonly code = "SH_AST_PARSE_ERROR";
963
+ readonly line: number;
964
+ readonly column: number;
965
+ readonly filename: string;
966
+ constructor(message: string, info: ShParseErrorInfo);
967
+ }
968
+
969
+ /**
970
+ * Position info attached to a {@link ShParseError}.
971
+ *
972
+ * @public
973
+ */
974
+ export declare interface ShParseErrorInfo {
975
+ /** 1-based line number, exactly as reported by mvdan/sh. */
976
+ line: number;
977
+ /**
978
+ * 1-based column number, in **UTF-16 code units** — converted from
979
+ * mvdan/sh's own byte-counting column so it agrees with
980
+ * {@link ShNode.loc}'s columns (mvdan/sh reports `column` as a byte count
981
+ * on the source line, not a UTF-16 code unit count; see
982
+ * design/ARCHITECTURE.md's "Byte→UTF-16 conversion"). For ASCII-only
983
+ * source text this is numerically identical to mvdan/sh's own column.
984
+ */
985
+ column: number;
986
+ /** The filename used for the parse (see {@link ParseOptions.filename}). */
987
+ filename: string;
988
+ }
989
+
990
+ /**
991
+ * Thrown by {@link parseSync} when `text`'s conservatively estimated
992
+ * structural nesting depth (subshells, command/process substitutions,
993
+ * `if`/`case`/loop/function bodies, `{ }` blocks, backtick or `$(...)`
994
+ * command substitution, `$((...))` arithmetic — see
995
+ * `parse-depth-guard.ts`'s module doc for the exact heuristic) exceeds the
996
+ * limit `parseSync` accepts. Thrown *before* `text` is ever handed to the
997
+ * WASM shim: mvdan/sh's own recursive-descent parser has no recovery path
998
+ * for exhausting its call stack on pathologically deep input (a stack
999
+ * overflow deep inside the shared WASM instance is not a normal, catchable
1000
+ * JS error the way a parse syntax error is), so this bridge estimates the
1001
+ * risk up front and fails closed with a typed error instead of ever making
1002
+ * that call — the shared WASM instance is therefore never put at risk of
1003
+ * wedging on this class of input; a `parseSync` call right after catching
1004
+ * this error works exactly as it would if this input had never been
1005
+ * attempted.
1006
+ *
1007
+ * Like {@link ShAnalyzeMaxDepthError}, this is pathological-input
1008
+ * protection, not a normal-usage ceiling: a legitimately deep (but
1009
+ * realistic) script parses fine. The estimate can *over*-count relative to
1010
+ * mvdan/sh's real grammar (rejecting some legitimate-but-unusually-deep
1011
+ * input) but is designed to never *under*-count relative to it — see
1012
+ * `parse-depth-guard.ts` for the documented false-positive sources this
1013
+ * trades off against ever letting a genuinely crash-inducing input
1014
+ * through.
1015
+ *
1016
+ * @public
1017
+ */
1018
+ export declare class ShParseMaxDepthError extends ShAstError {
1019
+ readonly code = "SH_AST_PARSE_MAX_DEPTH";
1020
+ /** The maximum structural nesting depth `parseSync` accepts; the same value every time (not caller-configurable). */
1021
+ readonly maxDepth: number;
1022
+ /**
1023
+ * The conservatively estimated nesting depth that tripped the guard.
1024
+ * Not necessarily `text`'s "true" nesting depth under a real parse — see
1025
+ * {@link ShParseMaxDepthError}'s doc comment — only ever `> maxDepth`.
1026
+ */
1027
+ readonly estimatedDepth: number;
1028
+ constructor(maxDepth: number, estimatedDepth: number);
1029
+ }
1030
+
1031
+ /**
1032
+ * mvdan/sh's `syntax.ProcSubst`, normalized.
1033
+ *
1034
+ * @public
1035
+ */
1036
+ declare interface ShProcSubstNode {
1037
+ readonly type: 'ProcSubst';
1038
+ readonly range: readonly [number, number];
1039
+ readonly loc: {
1040
+ readonly start: { readonly line: number; readonly column: number };
1041
+ readonly end: { readonly line: number; readonly column: number };
1042
+ };
1043
+ [field: string]: unknown;
1044
+ readonly last: readonly ShCommentNode[];
1045
+ readonly stmts: readonly ShStmtNode[];
1046
+ }
1047
+
1048
+ /**
1049
+ * mvdan/sh's `syntax.Redirect`, normalized.
1050
+ *
1051
+ * @public
1052
+ */
1053
+ declare interface ShRedirectNode {
1054
+ readonly type: 'Redirect';
1055
+ readonly range: readonly [number, number];
1056
+ readonly loc: {
1057
+ readonly start: { readonly line: number; readonly column: number };
1058
+ readonly end: { readonly line: number; readonly column: number };
1059
+ };
1060
+ [field: string]: unknown;
1061
+ readonly hdoc?: ShWordNode;
1062
+ readonly n?: ShLitNode;
1063
+ readonly word?: ShWordNode;
1064
+ }
1065
+
1066
+ /**
1067
+ * mvdan/sh's `syntax.Replace`, normalized.
1068
+ *
1069
+ * @public
1070
+ */
1071
+ declare interface ShReplaceNode {
1072
+ readonly type: 'Replace';
1073
+ readonly range: readonly [number, number];
1074
+ readonly loc: {
1075
+ readonly start: { readonly line: number; readonly column: number };
1076
+ readonly end: { readonly line: number; readonly column: number };
1077
+ };
1078
+ [field: string]: unknown;
1079
+ readonly orig?: ShWordNode;
1080
+ readonly with?: ShWordNode;
1081
+ }
1082
+
1083
+ /**
1084
+ * mvdan/sh's `syntax.SglQuoted`, normalized.
1085
+ *
1086
+ * @public
1087
+ */
1088
+ declare interface ShSglQuotedNode {
1089
+ readonly type: 'SglQuoted';
1090
+ readonly range: readonly [number, number];
1091
+ readonly loc: {
1092
+ readonly start: { readonly line: number; readonly column: number };
1093
+ readonly end: { readonly line: number; readonly column: number };
1094
+ };
1095
+ [field: string]: unknown;
1096
+ }
1097
+
1098
+ /**
1099
+ * mvdan/sh's `syntax.Slice`, normalized.
1100
+ *
1101
+ * @public
1102
+ */
1103
+ declare interface ShSliceNode {
1104
+ readonly type: 'Slice';
1105
+ readonly range: readonly [number, number];
1106
+ readonly loc: {
1107
+ readonly start: { readonly line: number; readonly column: number };
1108
+ readonly end: { readonly line: number; readonly column: number };
1109
+ };
1110
+ [field: string]: unknown;
1111
+ readonly length?: ShArithmExprNode;
1112
+ readonly offset?: ShArithmExprNode;
1113
+ }
1114
+
1115
+ /**
1116
+ * mvdan/sh's `syntax.Stmt`, normalized.
1117
+ *
1118
+ * @public
1119
+ */
1120
+ declare interface ShStmtNode {
1121
+ readonly type: 'Stmt';
1122
+ readonly range: readonly [number, number];
1123
+ readonly loc: {
1124
+ readonly start: { readonly line: number; readonly column: number };
1125
+ readonly end: { readonly line: number; readonly column: number };
1126
+ };
1127
+ [field: string]: unknown;
1128
+ readonly cmd?: ShCommandNode;
1129
+ readonly comments: readonly ShCommentNode[];
1130
+ readonly redirs: readonly ShRedirectNode[];
1131
+ }
1132
+
1133
+ /**
1134
+ * mvdan/sh's `syntax.Subshell`, normalized.
1135
+ *
1136
+ * @public
1137
+ */
1138
+ declare interface ShSubshellNode {
1139
+ readonly type: 'Subshell';
1140
+ readonly range: readonly [number, number];
1141
+ readonly loc: {
1142
+ readonly start: { readonly line: number; readonly column: number };
1143
+ readonly end: { readonly line: number; readonly column: number };
1144
+ };
1145
+ [field: string]: unknown;
1146
+ readonly last: readonly ShCommentNode[];
1147
+ readonly stmts: readonly ShStmtNode[];
1148
+ }
1149
+
1150
+ /**
1151
+ * mvdan/sh's `syntax.TestClause`, normalized.
1152
+ *
1153
+ * @public
1154
+ */
1155
+ declare interface ShTestClauseNode {
1156
+ readonly type: 'TestClause';
1157
+ readonly range: readonly [number, number];
1158
+ readonly loc: {
1159
+ readonly start: { readonly line: number; readonly column: number };
1160
+ readonly end: { readonly line: number; readonly column: number };
1161
+ };
1162
+ [field: string]: unknown;
1163
+ readonly x?: ShTestExprNode;
1164
+ }
1165
+
1166
+ /**
1167
+ * mvdan/sh's `syntax.TestDecl`, normalized.
1168
+ *
1169
+ * @public
1170
+ */
1171
+ declare interface ShTestDeclNode {
1172
+ readonly type: 'TestDecl';
1173
+ readonly range: readonly [number, number];
1174
+ readonly loc: {
1175
+ readonly start: { readonly line: number; readonly column: number };
1176
+ readonly end: { readonly line: number; readonly column: number };
1177
+ };
1178
+ [field: string]: unknown;
1179
+ readonly body?: ShStmtNode;
1180
+ readonly description?: ShWordNode;
1181
+ }
1182
+
1183
+ /**
1184
+ * The union of concrete node types mvdan/sh's `syntax.TestExpr` interface can
1185
+ * hold.
1186
+ *
1187
+ * @public
1188
+ */
1189
+ declare type ShTestExprNode = ShBinaryTestNode | ShParenTestNode | ShUnaryTestNode | ShWordNode;
1190
+
1191
+ /**
1192
+ * mvdan/sh's `syntax.TimeClause`, normalized.
1193
+ *
1194
+ * @public
1195
+ */
1196
+ declare interface ShTimeClauseNode {
1197
+ readonly type: 'TimeClause';
1198
+ readonly range: readonly [number, number];
1199
+ readonly loc: {
1200
+ readonly start: { readonly line: number; readonly column: number };
1201
+ readonly end: { readonly line: number; readonly column: number };
1202
+ };
1203
+ [field: string]: unknown;
1204
+ readonly stmt?: ShStmtNode;
1205
+ }
1206
+
1207
+ /**
1208
+ * mvdan/sh's `syntax.UnaryArithm`, normalized.
1209
+ *
1210
+ * @public
1211
+ */
1212
+ declare interface ShUnaryArithmNode {
1213
+ readonly type: 'UnaryArithm';
1214
+ readonly range: readonly [number, number];
1215
+ readonly loc: {
1216
+ readonly start: { readonly line: number; readonly column: number };
1217
+ readonly end: { readonly line: number; readonly column: number };
1218
+ };
1219
+ [field: string]: unknown;
1220
+ readonly x?: ShArithmExprNode;
1221
+ }
1222
+
1223
+ /**
1224
+ * mvdan/sh's `syntax.UnaryTest`, normalized.
1225
+ *
1226
+ * @public
1227
+ */
1228
+ declare interface ShUnaryTestNode {
1229
+ readonly type: 'UnaryTest';
1230
+ readonly range: readonly [number, number];
1231
+ readonly loc: {
1232
+ readonly start: { readonly line: number; readonly column: number };
1233
+ readonly end: { readonly line: number; readonly column: number };
1234
+ };
1235
+ [field: string]: unknown;
1236
+ readonly x?: ShTestExprNode;
1237
+ }
1238
+
1239
+ /**
1240
+ * mvdan/sh's `syntax.WhileClause`, normalized.
1241
+ *
1242
+ * @public
1243
+ */
1244
+ declare interface ShWhileClauseNode {
1245
+ readonly type: 'WhileClause';
1246
+ readonly range: readonly [number, number];
1247
+ readonly loc: {
1248
+ readonly start: { readonly line: number; readonly column: number };
1249
+ readonly end: { readonly line: number; readonly column: number };
1250
+ };
1251
+ [field: string]: unknown;
1252
+ readonly cond: readonly ShStmtNode[];
1253
+ readonly condlast: readonly ShCommentNode[];
1254
+ readonly do: readonly ShStmtNode[];
1255
+ readonly dolast: readonly ShCommentNode[];
1256
+ }
1257
+
1258
+ /**
1259
+ * mvdan/sh's `syntax.WordIter`, normalized.
1260
+ *
1261
+ * @public
1262
+ */
1263
+ declare interface ShWordIterNode {
1264
+ readonly type: 'WordIter';
1265
+ readonly range: readonly [number, number];
1266
+ readonly loc: {
1267
+ readonly start: { readonly line: number; readonly column: number };
1268
+ readonly end: { readonly line: number; readonly column: number };
1269
+ };
1270
+ [field: string]: unknown;
1271
+ readonly items: readonly ShWordNode[];
1272
+ readonly name?: ShLitNode;
1273
+ }
1274
+
1275
+ /**
1276
+ * mvdan/sh's `syntax.Word`, normalized.
1277
+ *
1278
+ * @public
1279
+ */
1280
+ declare interface ShWordNode {
1281
+ readonly type: 'Word';
1282
+ readonly range: readonly [number, number];
1283
+ readonly loc: {
1284
+ readonly start: { readonly line: number; readonly column: number };
1285
+ readonly end: { readonly line: number; readonly column: number };
1286
+ };
1287
+ [field: string]: unknown;
1288
+ readonly parts: readonly ShWordPartNode[];
1289
+ }
1290
+
1291
+ /**
1292
+ * The union of concrete node types mvdan/sh's `syntax.WordPart` interface can
1293
+ * hold.
1294
+ *
1295
+ * @public
1296
+ */
1297
+ declare type ShWordPartNode =
1298
+ | ShArithmExpNode
1299
+ | ShBraceExpNode
1300
+ | ShCmdSubstNode
1301
+ | ShDblQuotedNode
1302
+ | ShExtGlobNode
1303
+ | ShLitNode
1304
+ | ShParamExpNode
1305
+ | ShProcSubstNode
1306
+ | ShSglQuotedNode;
1307
+
1308
+ /**
1309
+ * Maps each normalized node `type` to the field names (lowercased, matching
1310
+ * the normalized node shape produced by `normalize`) whose values hold child
1311
+ * nodes.
1312
+ *
1313
+ * Generated from mvdan/sh's `syntax` package struct definitions by
1314
+ * `tools/gen-visitor-keys` (see design/ARCHITECTURE.md, "The schema table is
1315
+ * generated, not hand-written") — this module only re-exports the generated
1316
+ * table under the public name, frozen. {@link walk} does not depend on this
1317
+ * table for correctness — it discovers children structurally — so any gap
1318
+ * here (there shouldn't be one; the kitchen-sink golden test guards it)
1319
+ * affects only external consumers that choose to traverse via this table.
1320
+ *
1321
+ * Frozen (including each per-type field-name array) so immutability of this
1322
+ * shared, module-scoped table is a contract, not just a convention any
1323
+ * importer happens to honor.
1324
+ *
1325
+ * @public
1326
+ */
1327
+ export declare const visitorKeys: Readonly<Record<string, readonly string[]>>;
1328
+
1329
+ /**
1330
+ * Visits every node in a normalized tree, pre-order (parent before
1331
+ * children), starting at `node`.
1332
+ *
1333
+ * Children are discovered structurally: any field on a visited node whose
1334
+ * value is itself a normalized node (or an array of normalized nodes) is
1335
+ * treated as a child. This is deliberately not driven off {@link
1336
+ * visitorKeys} — the spike's hand-written visitor-keys table missed
1337
+ * `DeclClause.Variant` (see design/ARCHITECTURE.md) and silently
1338
+ * under-walked the tree, and `visitorKeys` remains hand-maintained pending a
1339
+ * schema generator (tracked separately). Walking structurally means this
1340
+ * function's completeness never depends on that table's accuracy.
1341
+ *
1342
+ * @public
1343
+ */
1344
+ export declare function walk(node: ShNode, visit: (node: ShNode, parent: ShNode | null) => void): void;
1345
+
1346
+ export { }