@orkestrel/terminal 0.0.12 → 0.0.14
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/README.md +3 -7
- package/dist/src/core/index.cjs +408 -258
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +544 -297
- package/dist/src/core/index.d.ts +544 -297
- package/dist/src/core/index.js +393 -241
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +187 -201
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +129 -143
- package/dist/src/server/index.d.ts +129 -143
- package/dist/src/server/index.js +176 -185
- package/dist/src/server/index.js.map +1 -1
- package/package.json +23 -19
|
@@ -6,22 +6,20 @@ import { FormInterface } from '@orkestrel/form';
|
|
|
6
6
|
import { FormValues } from '@orkestrel/form';
|
|
7
7
|
import { PromptTheme } from '@orkestrel/terminal';
|
|
8
8
|
import { PromptThemeOptions } from '@orkestrel/terminal';
|
|
9
|
+
import { StreamTargetInterface } from '@orkestrel/console/server';
|
|
9
10
|
import { StylerInterface } from '@orkestrel/console';
|
|
10
11
|
import { TerminalInterface } from '@orkestrel/terminal';
|
|
11
12
|
import { TextField } from '@orkestrel/form';
|
|
12
13
|
|
|
13
|
-
/** A carriage return (`\r`, U+000D) — returns the cursor to column 0 so a redraw starts at the line's left edge. */
|
|
14
|
-
export declare const CARRIAGE_RETURN: string;
|
|
15
|
-
|
|
16
14
|
/**
|
|
17
|
-
*
|
|
15
|
+
* Erases from the cursor down to the end of the screen (`ESC[J`) — wipes the WHOLE previous (possibly
|
|
18
16
|
* multi-line `select` / `checkbox`) view in one write before the new view is rendered, so a redraw
|
|
19
17
|
* never leaves orphaned rows below.
|
|
20
18
|
*/
|
|
21
19
|
export declare const CLEAR_DOWN: string;
|
|
22
20
|
|
|
23
21
|
/**
|
|
24
|
-
*
|
|
22
|
+
* Holds the format cue appended to a field's label for each control the walk reads as a line of text —
|
|
25
23
|
* the terminal has no date picker, no color well, and no file chooser, so the accepted shape is
|
|
26
24
|
* stated instead. A control with no entry needs none: `text` and `editor` accept any line,
|
|
27
25
|
* `password` masks one, and `confirm`, `select`, and `checkbox` are answered by key rather than by
|
|
@@ -30,7 +28,7 @@ export declare const CLEAR_DOWN: string;
|
|
|
30
28
|
export declare const CONTROL_HINTS: Readonly<Partial<Record<FieldControl, string>>>;
|
|
31
29
|
|
|
32
30
|
/**
|
|
33
|
-
*
|
|
31
|
+
* Creates the interactive terminal form driver — the local-keyboard arm of the terminal trio, beside
|
|
34
32
|
* the core headless `createPrompt` broker and the SSE `createPromptClient` bridge. Where the broker
|
|
35
33
|
* PARKS a live form until somebody elsewhere answers it, a `Terminal` answers one HERE: it walks the
|
|
36
34
|
* form's fields in schema order, drives each control's pure reducer over raw-mode stdin, binds every
|
|
@@ -43,7 +41,7 @@ export declare const CONTROL_HINTS: Readonly<Partial<Record<FieldControl, string
|
|
|
43
41
|
* @remarks
|
|
44
42
|
* - **The form is the unit.** `ask` takes the caller's live form and returns its settled values. The
|
|
45
43
|
* returned promise is that form's own `answer`, so a caller holding the form can await either one.
|
|
46
|
-
* - **Every control renders.**
|
|
44
|
+
* - **Every control renders.** The line-read controls are read as a line of text with their format cue,
|
|
47
45
|
* `password` masks, `confirm` takes a key, `editor` takes a block, `select` and `checkbox` drive a
|
|
48
46
|
* list, and an open `select` accepts a value its list does not offer.
|
|
49
47
|
* - **The form decides.** A blank answer binds as absence, the form evaluates, and a refusal
|
|
@@ -74,71 +72,45 @@ export declare const CONTROL_HINTS: Readonly<Partial<Record<FieldControl, string
|
|
|
74
72
|
*/
|
|
75
73
|
export declare function createTerminal(options?: TerminalOptions): TerminalInterface;
|
|
76
74
|
|
|
77
|
-
/** The Control Sequence Introducer (`ESC[`) — the prefix of every cursor / erase sequence. */
|
|
78
|
-
export declare const CSI: string;
|
|
79
|
-
|
|
80
75
|
/**
|
|
81
|
-
*
|
|
76
|
+
* Holds the cursor-UP sequence TEMPLATE (`ESC[{count}A`) — {@link import('./helpers.js').renderCursorUp}
|
|
82
77
|
* interpolates the `{count}` placeholder with the number of lines to climb. Kept as a template so
|
|
83
78
|
* the count stays out of the constant.
|
|
84
79
|
*/
|
|
85
80
|
export declare const CSI_UP: string;
|
|
86
81
|
|
|
87
82
|
/**
|
|
88
|
-
*
|
|
83
|
+
* Hides the cursor (`ESC[?25l`) — written before the driver starts redrawing a prompt so the cursor
|
|
89
84
|
* does not flicker across the view during an in-place re-render; paired with {@link CURSOR_SHOW}.
|
|
90
85
|
*/
|
|
91
86
|
export declare const CURSOR_HIDE: string;
|
|
92
87
|
|
|
93
|
-
/**
|
|
88
|
+
/** Shows the cursor (`ESC[?25h`) — restores the cursor after a prompt resolves / cancels (the {@link CURSOR_HIDE} pair). */
|
|
94
89
|
export declare const CURSOR_SHOW: string;
|
|
95
90
|
|
|
96
|
-
/**
|
|
97
|
-
* The choices a `select` or `checkbox` field SHOWS but refuses — the complement of
|
|
98
|
-
* {@link enabledChoices}, rendered by {@link unavailableLine} above the list so a reader sees why a
|
|
99
|
-
* declared choice is missing from it.
|
|
100
|
-
*
|
|
101
|
-
* @param choices - The field's declared choices
|
|
102
|
-
* @returns The refused choices, in declared order
|
|
103
|
-
*/
|
|
104
|
-
export declare function disabledChoices(choices: readonly FieldChoice[]): readonly FieldChoice[];
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* The choices a `select` or `checkbox` field actually OFFERS — the form refuses a disabled choice's
|
|
108
|
-
* value at every door, including a fill, so the walk never puts one in front of the cursor. Pair
|
|
109
|
-
* with {@link disabledChoices} to tell the reader what was withheld.
|
|
110
|
-
*
|
|
111
|
-
* @param choices - The field's declared choices
|
|
112
|
-
* @returns The choices the walk offers, in declared order
|
|
113
|
-
*/
|
|
114
|
-
export declare function enabledChoices(choices: readonly FieldChoice[]): readonly FieldChoice[];
|
|
115
|
-
|
|
116
|
-
/** The Escape byte (ESC, U+001B) — the lead byte of every CSI cursor-control sequence below. */
|
|
117
|
-
export declare const ESCAPE: string;
|
|
118
|
-
|
|
119
|
-
/** The comma-separated multi-select hint the non-TTY `checkbox` fallback shows (the user types one or more numbers). */
|
|
91
|
+
/** Holds the comma-separated multi-select hint the non-TTY `checkbox` fallback shows (the user types one or more numbers). */
|
|
120
92
|
export declare const FALLBACK_CHECKBOX_HINT = "Enter numbers separated by commas";
|
|
121
93
|
|
|
122
|
-
/**
|
|
94
|
+
/** Holds the hint the non-TTY `confirm` fallback shows — a piped stream sends a whole line, so the answer is typed rather than pressed. */
|
|
123
95
|
export declare const FALLBACK_CONFIRM_HINT = "(y/n)";
|
|
124
96
|
|
|
125
|
-
/**
|
|
97
|
+
/** Holds the hint the non-TTY `editor` fallback shows — a piped stream has no ctrl-d, so end of input finishes the block. */
|
|
126
98
|
export declare const FALLBACK_EDITOR_HINT = "(end of input finishes)";
|
|
127
99
|
|
|
128
100
|
/**
|
|
129
|
-
*
|
|
101
|
+
* Holds the numbered-list prompt the non-TTY {@link import('./Terminal.js').Terminal} `select` fallback
|
|
130
102
|
* appends — a piped (non-terminal) stream cannot navigate with arrow keys, so the choices are
|
|
131
103
|
* printed numbered and the user types one number on a single readline line.
|
|
132
104
|
*/
|
|
133
105
|
export declare const FALLBACK_SELECT_HINT = "Enter a number";
|
|
134
106
|
|
|
135
107
|
/**
|
|
136
|
-
*
|
|
137
|
-
* takes — `text` itself, and the
|
|
108
|
+
* Projects any field the walk reads as a LINE OF TEXT into the {@link TextField} the text reducer
|
|
109
|
+
* takes — `text` itself, and the controls a terminal has no widget for: `number`, `date`,
|
|
138
110
|
* `time`, `datetime`, `color`, and one `file` entry. The label carries that control's format cue
|
|
139
111
|
* from {@link CONTROL_HINTS}, and a declared `default` becomes the line a bare return submits. The
|
|
140
112
|
* projection carries no rule, because the AUTHORITATIVE form still evaluates the answer this line
|
|
141
|
-
* binds; it exists only so one reducer
|
|
113
|
+
* binds; it exists only so one reducer covers every one of them.
|
|
142
114
|
*
|
|
143
115
|
* @param field - The field being read
|
|
144
116
|
* @returns The text field the reducer renders for it
|
|
@@ -151,14 +123,31 @@ export declare const FALLBACK_SELECT_HINT = "Enter a number";
|
|
|
151
123
|
*/
|
|
152
124
|
export declare function fieldToText(field: FormField): TextField;
|
|
153
125
|
|
|
154
|
-
/**
|
|
126
|
+
/** Holds the instruction a `file` field with `multiple` shows before its entries — one path per line, and a blank line ends the list. */
|
|
155
127
|
export declare const FILE_HINT = "One path per line, blank to finish";
|
|
156
128
|
|
|
157
|
-
/**
|
|
158
|
-
|
|
129
|
+
/**
|
|
130
|
+
* Returns the choices a `select` or `checkbox` field SHOWS but refuses — the complement of
|
|
131
|
+
* {@link filterEnabled}, rendered by {@link renderUnavailableLine} above the list so a reader sees
|
|
132
|
+
* why a declared choice is missing from it.
|
|
133
|
+
*
|
|
134
|
+
* @param choices - The field's declared choices
|
|
135
|
+
* @returns The refused choices, in declared order
|
|
136
|
+
*/
|
|
137
|
+
export declare function filterDisabled(choices: readonly FieldChoice[]): readonly FieldChoice[];
|
|
159
138
|
|
|
160
139
|
/**
|
|
161
|
-
*
|
|
140
|
+
* Returns the choices a `select` or `checkbox` field actually OFFERS — the form refuses a disabled
|
|
141
|
+
* choice's value at every door, including a fill, so the walk never puts one in front of the
|
|
142
|
+
* cursor. Pair with {@link filterDisabled} to tell the reader what was withheld.
|
|
143
|
+
*
|
|
144
|
+
* @param choices - The field's declared choices
|
|
145
|
+
* @returns The choices the walk offers, in declared order
|
|
146
|
+
*/
|
|
147
|
+
export declare function filterEnabled(choices: readonly FieldChoice[]): readonly FieldChoice[];
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Represents the minimal input-stream shape the driver reads — exactly the slice of a Node `tty.ReadStream` /
|
|
162
151
|
* `process.stdin` it touches, and no more. A {@link TerminalOptions} `input` is narrowed to this
|
|
163
152
|
* through {@link import('./helpers.js').isInputStream}, never an assertion, so a test drives a whole
|
|
164
153
|
* form with a hand-built fake stream that emits scripted key chunks, never touches the real
|
|
@@ -167,7 +156,7 @@ export declare function groupHeader(styler: StylerInterface, theme: PromptTheme,
|
|
|
167
156
|
* @remarks
|
|
168
157
|
* - `on(event, listener)` / `off(event, listener)` — subscribe / unsubscribe a `'data'` chunk
|
|
169
158
|
* listener (the irreducible event seam; a `Buffer`, string, or `Uint8Array` chunk arrives). The
|
|
170
|
-
*
|
|
159
|
+
* required methods.
|
|
171
160
|
* - `setRawMode(mode)` — switch the TTY in and out of raw mode (each keypress delivered
|
|
172
161
|
* immediately, no line buffering, no echo). Present on a real `tty.ReadStream`; ABSENT on a
|
|
173
162
|
* piped, non-TTY stream, and its absence (or `isTTY !== true`) selects the
|
|
@@ -186,8 +175,8 @@ export declare interface InputStreamInterface {
|
|
|
186
175
|
}
|
|
187
176
|
|
|
188
177
|
/**
|
|
189
|
-
*
|
|
190
|
-
* `'data'` subscription methods. A total type guard
|
|
178
|
+
* Checks whether `value` is a usable {@link InputStreamInterface} — a record with callable `on` / `off`
|
|
179
|
+
* `'data'` subscription methods. A total type guard: it NEVER throws and returns `false`
|
|
191
180
|
* for anything off-shape, so it narrows the one unavoidable input boundary (the real `process.stdin`,
|
|
192
181
|
* or a fake TTY a test injects) to the exact slice the driver reads — no `as`.
|
|
193
182
|
*
|
|
@@ -198,23 +187,12 @@ export declare interface InputStreamInterface {
|
|
|
198
187
|
* fallback rather than raw mode.
|
|
199
188
|
*
|
|
200
189
|
* @param value - Any value crossing the boundary (a process stream, an injected fake, `unknown`)
|
|
201
|
-
* @returns
|
|
190
|
+
* @returns True if `value` has callable `on` and `off`; false otherwise
|
|
202
191
|
*/
|
|
203
192
|
export declare function isInputStream(value: unknown): value is InputStreamInterface;
|
|
204
193
|
|
|
205
194
|
/**
|
|
206
|
-
*
|
|
207
|
-
* total type guard (AGENTS §14): it NEVER throws and returns `false` for anything off-shape, so it
|
|
208
|
-
* narrows the output boundary (the real `process.stdout`, or a recording fake a test injects) to the
|
|
209
|
-
* one method the driver writes through — no `as`.
|
|
210
|
-
*
|
|
211
|
-
* @param value - Any value crossing the boundary (a process stream, an injected fake, `unknown`)
|
|
212
|
-
* @returns `true` when `value` has a callable `write`
|
|
213
|
-
*/
|
|
214
|
-
export declare function isOutputStream(value: unknown): value is OutputStreamInterface;
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Whether `value` is a Node {@link NodeJS.ReadableStream} — a total structural guard (AGENTS §14)
|
|
195
|
+
* Checks whether `value` is a Node {@link NodeJS.ReadableStream} — a total structural guard
|
|
218
196
|
* checking for the callable `read` / `pipe` / `on` that `node:readline`'s `createInterface` requires
|
|
219
197
|
* as its `input`. The non-TTY fallback narrows the resolved input stream through this before handing
|
|
220
198
|
* it to readline (never an `as`), so a real piped `process.stdin` (or a `PassThrough` a test injects)
|
|
@@ -222,15 +200,12 @@ export declare function isOutputStream(value: unknown): value is OutputStreamInt
|
|
|
222
200
|
* isn't a full readable.
|
|
223
201
|
*
|
|
224
202
|
* @param value - The resolved input stream (or any value crossing the boundary)
|
|
225
|
-
* @returns
|
|
203
|
+
* @returns True if `value` has the readable methods readline needs; false otherwise
|
|
226
204
|
*/
|
|
227
205
|
export declare function isReadable(value: unknown): value is NodeJS.ReadableStream;
|
|
228
206
|
|
|
229
|
-
/** A line feed (`\n`, U+000A) — the line terminator the driver writes after the final committed prompt view. */
|
|
230
|
-
export declare const LINE_FEED: string;
|
|
231
|
-
|
|
232
207
|
/**
|
|
233
|
-
*
|
|
208
|
+
* Counts the terminal LINES a rendered prompt `view` occupies — one more than its newline count
|
|
234
209
|
* (a view with no newline is a single line; N newlines span N+1 lines). The basis of the in-place
|
|
235
210
|
* re-render: the driver records the line count of the view it just wrote so the next redraw knows how
|
|
236
211
|
* far up to move the cursor before overwriting. Total; an empty string is one (empty) line.
|
|
@@ -240,24 +215,38 @@ export declare const LINE_FEED: string;
|
|
|
240
215
|
*/
|
|
241
216
|
export declare function lineCount(view: string): number;
|
|
242
217
|
|
|
243
|
-
/**
|
|
218
|
+
/** Holds the mark on a locked field's line — the walk renders its value and moves on, because the form refuses an edit there. */
|
|
244
219
|
export declare const LOCKED_MARK = "(locked)";
|
|
245
220
|
|
|
246
221
|
/**
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
222
|
+
* Returns the full reposition-and-clear prefix to write BEFORE re-rendering a prompt view in place — given
|
|
223
|
+
* the line count of the PREVIOUS view, it moves the cursor up over those lines, returns it to column
|
|
224
|
+
* 0, and erases everything from there to the end of the screen, so the next view is drawn on a clean
|
|
225
|
+
* region (no orphaned rows from a taller previous view). Pure; the driver writes this immediately
|
|
226
|
+
* followed by the new view.
|
|
250
227
|
*
|
|
251
|
-
* @
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
228
|
+
* @remarks
|
|
229
|
+
* For the FIRST render `previousLines` is `1` (the cursor sits on the line the prompt opened on) so
|
|
230
|
+
* the prefix is just a carriage return + clear-down — the prompt draws from the current line. For a
|
|
231
|
+
* subsequent render it climbs `previousLines - 1` lines (the cursor is on the LAST line of the prior
|
|
232
|
+
* view) before clearing. Keeping the math here (not in the driver) makes the re-render unit-testable
|
|
233
|
+
* without a real terminal.
|
|
234
|
+
*
|
|
235
|
+
* @param previousLines - The line count of the view currently on screen (from {@link lineCount})
|
|
236
|
+
* @returns The control-sequence prefix to write before the new view
|
|
256
237
|
*/
|
|
257
|
-
export declare function
|
|
238
|
+
export declare function redrawPrefix(previousLines: number): string;
|
|
258
239
|
|
|
259
240
|
/**
|
|
260
|
-
*
|
|
241
|
+
* States what a field is told when the walk read an answer the control cannot hold — a word typed into a
|
|
242
|
+
* `number`, an off-list value typed into an open `select` whose choice is refused. The value binds
|
|
243
|
+
* as absence and this message is invalidated onto the field, so the walk re-asks it with the reason
|
|
244
|
+
* on screen.
|
|
245
|
+
*/
|
|
246
|
+
export declare const REFUSAL_MESSAGE = "Enter a value this field accepts";
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Returns the cursor-UP control sequence that moves the cursor up `count` lines (`ESC[{count}A`) — or the
|
|
261
250
|
* empty string when `count` is zero or negative (no movement needed, and `ESC[0A` is a wasted write).
|
|
262
251
|
* The pure step the in-place re-render uses to climb back over the previous view before clearing it.
|
|
263
252
|
* Total.
|
|
@@ -265,86 +254,84 @@ export declare function lockedLine(styler: StylerInterface, theme: PromptTheme,
|
|
|
265
254
|
* @param count - How many lines to move the cursor up
|
|
266
255
|
* @returns The `ESC[{count}A` sequence, or `''` when `count <= 0`
|
|
267
256
|
*/
|
|
268
|
-
export declare function
|
|
257
|
+
export declare function renderCursorUp(count: number): string;
|
|
269
258
|
|
|
270
259
|
/**
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
* choice, with no trailing newline.
|
|
260
|
+
* Renders the section header the walk writes when it enters a new field group, painted by the
|
|
261
|
+
* `message` role.
|
|
274
262
|
*
|
|
275
263
|
* @param styler - The console styler that renders each role
|
|
276
264
|
* @param theme - The resolved prompt theme
|
|
277
|
-
* @param
|
|
278
|
-
* @returns The rendered
|
|
265
|
+
* @param label - The group's declared label, falling back to its own name
|
|
266
|
+
* @returns The rendered section header
|
|
279
267
|
*/
|
|
280
|
-
export declare function
|
|
268
|
+
export declare function renderGroupHeader(styler: StylerInterface, theme: PromptTheme, label: string): string;
|
|
281
269
|
|
|
282
270
|
/**
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
* the walk renders and asserts the rendered content with the ANSI stripped.
|
|
271
|
+
* Renders the read-only line a LOCKED field shows — its label, the {@link LOCKED_MARK}, and the
|
|
272
|
+
* answer the form already holds. The walk writes this instead of a prompt, because the field is still
|
|
273
|
+
* validated and still submitted but must not be edited here.
|
|
287
274
|
*
|
|
288
|
-
* @
|
|
289
|
-
*
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
* it; the styler already decided color.
|
|
275
|
+
* @param styler - The console styler that renders each role
|
|
276
|
+
* @param theme - The resolved prompt theme
|
|
277
|
+
* @param label - The field's label
|
|
278
|
+
* @param value - The held answer, from {@link valueToText}
|
|
279
|
+
* @returns The rendered line, with no trailing space when there is nothing to show
|
|
294
280
|
*/
|
|
295
|
-
export declare
|
|
296
|
-
write(text: string): boolean | void;
|
|
297
|
-
readonly isTTY?: boolean;
|
|
298
|
-
}
|
|
281
|
+
export declare function renderLockedLine(styler: StylerInterface, theme: PromptTheme, label: string, value: string): string;
|
|
299
282
|
|
|
300
283
|
/**
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
* `node:readline` line-input fallback (a piped / non-terminal stream cannot enter raw mode). Total —
|
|
305
|
-
* never throws.
|
|
284
|
+
* Renders the numbered choice list the non-TTY fallback prints — a piped stream cannot navigate
|
|
285
|
+
* with arrow keys, so each offered choice is printed with the number the reader types back. One
|
|
286
|
+
* line per choice, with no trailing newline.
|
|
306
287
|
*
|
|
307
|
-
* @param
|
|
308
|
-
* @
|
|
288
|
+
* @param styler - The console styler that renders each role
|
|
289
|
+
* @param theme - The resolved prompt theme
|
|
290
|
+
* @param choices - The choices the walk offers, from {@link filterEnabled}
|
|
291
|
+
* @returns The rendered list
|
|
309
292
|
*/
|
|
310
|
-
export declare function
|
|
293
|
+
export declare function renderNumberedList(styler: StylerInterface, theme: PromptTheme, choices: readonly FieldChoice[]): string;
|
|
311
294
|
|
|
312
295
|
/**
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
* 0, and erases everything from there to the end of the screen, so the next view is drawn on a clean
|
|
316
|
-
* region (no orphaned rows from a taller previous view). Pure; the driver writes this immediately
|
|
317
|
-
* followed by the new view.
|
|
296
|
+
* Renders the line listing an OPEN select's offered values above its text prompt — a suggestion
|
|
297
|
+
* list, because an open select admits an answer the list does not offer.
|
|
318
298
|
*
|
|
319
|
-
* @
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
* view) before clearing. Keeping the math here (not in the driver) makes the re-render unit-testable
|
|
324
|
-
* without a real terminal.
|
|
325
|
-
*
|
|
326
|
-
* @param previousLines - The line count of the view currently on screen (from {@link lineCount})
|
|
327
|
-
* @returns The control-sequence prefix to write before the new view
|
|
299
|
+
* @param styler - The console styler that renders each role
|
|
300
|
+
* @param theme - The resolved prompt theme
|
|
301
|
+
* @param choices - The choices the open select offers, from {@link filterEnabled}
|
|
302
|
+
* @returns The rendered suggestion line
|
|
328
303
|
*/
|
|
329
|
-
export declare function
|
|
304
|
+
export declare function renderSuggestionLine(styler: StylerInterface, theme: PromptTheme, choices: readonly FieldChoice[]): string;
|
|
330
305
|
|
|
331
306
|
/**
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
307
|
+
* Renders the line naming the choices a field shows but refuses, written above the list the walk
|
|
308
|
+
* drives.
|
|
309
|
+
*
|
|
310
|
+
* @param styler - The console styler that renders each role
|
|
311
|
+
* @param theme - The resolved prompt theme
|
|
312
|
+
* @param choices - The refused choices, from {@link filterDisabled}
|
|
313
|
+
* @returns The rendered unavailable line
|
|
336
314
|
*/
|
|
337
|
-
export declare
|
|
315
|
+
export declare function renderUnavailableLine(styler: StylerInterface, theme: PromptTheme, choices: readonly FieldChoice[]): string;
|
|
338
316
|
|
|
339
|
-
/**
|
|
317
|
+
/** Holds the lead on the line listing an open `select`'s offered values, which a typed answer may ignore. */
|
|
340
318
|
export declare const SUGGESTION_LEAD = "Suggestions";
|
|
341
319
|
|
|
342
|
-
/**
|
|
343
|
-
|
|
320
|
+
/**
|
|
321
|
+
* Checks whether an input stream can be driven in RAW mode — it both reports `isTTY === true` AND
|
|
322
|
+
* exposes a callable `setRawMode`. The {@link import('./Terminal.js').Terminal} probes this to choose its path:
|
|
323
|
+
* `true` ⇒ the interactive raw-mode prompts (arrow-key navigation, live re-render); `false` ⇒ the
|
|
324
|
+
* `node:readline` line-input fallback (a piped / non-terminal stream cannot enter raw mode). Total —
|
|
325
|
+
* never throws.
|
|
326
|
+
*
|
|
327
|
+
* @param input - The resolved {@link InputStreamInterface}
|
|
328
|
+
* @returns True if the stream is a TTY with `setRawMode`; false otherwise
|
|
329
|
+
*/
|
|
330
|
+
export declare function supportsRawMode(input: InputStreamInterface): boolean;
|
|
344
331
|
|
|
345
332
|
/**
|
|
346
|
-
*
|
|
347
|
-
*
|
|
333
|
+
* Implements {@link TerminalInterface} for a human at this machine's keyboard — the interactive form
|
|
334
|
+
* DRIVER, and the only impure part of the terminal stack. {@link ask} walks one
|
|
348
335
|
* form's fields in schema order, feeds raw-mode stdin bytes through `parseKey` into the matching
|
|
349
336
|
* pure reducer, renders each returned view in place, and binds every answer through the form's own
|
|
350
337
|
* `fill`. It owns no form logic: the schema, the rules, the values, and the settlement all belong to
|
|
@@ -353,7 +340,7 @@ export declare function suggestionLine(styler: StylerInterface, theme: PromptThe
|
|
|
353
340
|
* @remarks
|
|
354
341
|
* See {@link TerminalInterface} for the driving contract. The walk itself:
|
|
355
342
|
*
|
|
356
|
-
* - **
|
|
343
|
+
* - **Controls and reducers.** `text`, `number`, `date`, `time`, `datetime`, `color`, and
|
|
357
344
|
* each `file` entry are read as one line of text through {@link fieldToText}, which appends that
|
|
358
345
|
* control's format cue to the label. `password`, `confirm`, `editor`, `select`, and `checkbox`
|
|
359
346
|
* each drive their own reducer. An open `select` is a suggestion list plus a typed line, because
|
|
@@ -382,7 +369,7 @@ export declare class Terminal implements TerminalInterface {
|
|
|
382
369
|
}
|
|
383
370
|
|
|
384
371
|
/**
|
|
385
|
-
*
|
|
372
|
+
* Configures {@link import('./factories.js').createTerminal} — every member optional, so a bare
|
|
386
373
|
* `createTerminal()` walks a form over the real `process.stdin` / `process.stdout` with the default
|
|
387
374
|
* theme.
|
|
388
375
|
*
|
|
@@ -392,8 +379,10 @@ export declare class Terminal implements TerminalInterface {
|
|
|
392
379
|
* {@link import('./helpers.js').isInputStream}, so a test injects a fake TTY that emits scripted
|
|
393
380
|
* `'data'` chunks. A stream that is not a TTY falls back to `node:readline` line input.
|
|
394
381
|
* - `output` — the stream each view is rendered to; defaults to `process.stdout`. Any
|
|
395
|
-
* {@link
|
|
396
|
-
* {@link import('
|
|
382
|
+
* {@link import('@orkestrel/console/server').StreamTargetInterface}-shaped stream is accepted,
|
|
383
|
+
* resolved through {@link import('@orkestrel/console/server').isStreamTarget}, so a test records
|
|
384
|
+
* the rendered output. That is the console module's own boundary shape, so one target drives a
|
|
385
|
+
* console sink and this driver alike.
|
|
397
386
|
* - `theme` — the glyphs and role styles every rendered line is painted with, merged over
|
|
398
387
|
* {@link import('@src/core').DEFAULT_PROMPT_THEME} leaf by leaf by
|
|
399
388
|
* {@link import('@src/core').createPromptTheme}. Supplying one icon or one role leaves every
|
|
@@ -401,18 +390,15 @@ export declare class Terminal implements TerminalInterface {
|
|
|
401
390
|
*/
|
|
402
391
|
export declare interface TerminalOptions {
|
|
403
392
|
readonly input?: InputStreamInterface;
|
|
404
|
-
readonly output?:
|
|
393
|
+
readonly output?: StreamTargetInterface;
|
|
405
394
|
readonly theme?: PromptThemeOptions;
|
|
406
395
|
}
|
|
407
396
|
|
|
408
|
-
/**
|
|
397
|
+
/** Holds the lead on the line listing the choices a `select` or `checkbox` shows but refuses, so a reader sees why one is missing from the list below. */
|
|
409
398
|
export declare const UNAVAILABLE_LEAD = "Unavailable";
|
|
410
399
|
|
|
411
|
-
/** The line naming the choices a field shows but refuses, written above the list the walk drives. */
|
|
412
|
-
export declare function unavailableLine(styler: StylerInterface, theme: PromptTheme, choices: readonly FieldChoice[]): string;
|
|
413
|
-
|
|
414
400
|
/**
|
|
415
|
-
*
|
|
401
|
+
* Projects one held answer into the text a read-only line shows — a scalar as itself, a boolean as
|
|
416
402
|
* `yes` / `no` (the word the confirm reducer commits), and a list joined by commas. Absence renders
|
|
417
403
|
* as nothing, because a locked field nobody has answered has nothing to show.
|
|
418
404
|
*
|