@akterjs/cli 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +47 -2
  3. package/dist/Argument-D81dqizB.mjs +57 -0
  4. package/dist/Array-B4kuTQeW.mjs +2323 -0
  5. package/dist/Boolean-kILIvmhE.mjs +26 -0
  6. package/dist/ChildProcess-BCIwxPGc.mjs +577 -0
  7. package/dist/CliError-Cf5xqkkj.mjs +633 -0
  8. package/dist/Command-Dzq9KM-h.mjs +5135 -0
  9. package/dist/Config-B6OND9WR.mjs +854 -0
  10. package/dist/Console-BKHUkH6a.mjs +141 -0
  11. package/dist/Data-CeCULr0-.mjs +251 -0
  12. package/dist/Digest-CBd3uv5B.mjs +348 -0
  13. package/dist/Duration-EH9Vy4U6.mjs +791 -0
  14. package/dist/Effect-CKFpqbmw.mjs +12911 -0
  15. package/dist/FileSystem-4pPcEb_i.mjs +1366 -0
  16. package/dist/HttpClientError-BUeMWx70.mjs +303 -0
  17. package/dist/HttpClientResponse-D5ZKICVV.mjs +855 -0
  18. package/dist/Match-CGPLZYrV.mjs +434 -0
  19. package/dist/MutableHashMap-f8nW8AJR.mjs +376 -0
  20. package/dist/MutableHashSet-_HI572Ya.mjs +155 -0
  21. package/dist/MutableRef-D4Qv592C.mjs +107 -0
  22. package/dist/Number-BvkRkfc-.mjs +137 -0
  23. package/dist/Option-DkxSnBhp.mjs +3967 -0
  24. package/dist/Order-C1JC991I.mjs +481 -0
  25. package/dist/Path-Djdv_eF5.mjs +130 -0
  26. package/dist/Queue-CO5UQ6os.mjs +1394 -0
  27. package/dist/Redacted-RkJrG5Me.mjs +160 -0
  28. package/dist/Ref-BIPOxJNH.mjs +267 -0
  29. package/dist/Runtime-BInIAwK3.mjs +297 -0
  30. package/dist/Schema-MiKt5K1v.mjs +10999 -0
  31. package/dist/SecureRandom-B_U4ysO3.mjs +279 -0
  32. package/dist/Semaphore-DOVJ4ZGS.mjs +177 -0
  33. package/dist/Stdio-KylmOBX_.mjs +74 -0
  34. package/dist/Stream-bK9QIETN.mjs +4012 -0
  35. package/dist/String-q5dcsVe4.mjs +351 -0
  36. package/dist/TerminalCapabilities-w_44MAca.mjs +1769 -0
  37. package/dist/WebCrypto-ZI_GNVlw.mjs +33 -0
  38. package/dist/actor-call.service-CGM_vD9u.mjs +1269 -0
  39. package/dist/actor-client.adapter-Coem7gF1.mjs +3691 -0
  40. package/dist/akter-program.config-C4cXx4Fr.mjs +7034 -0
  41. package/dist/akter.cli.mjs +5 -0
  42. package/dist/app-cli.config.mjs +49 -0
  43. package/dist/app-entry.pure.mjs +31 -0
  44. package/dist/archive/akter-archive.schema.mjs +65 -0
  45. package/dist/archive/akter-archive.service.mjs +309 -0
  46. package/dist/archive/archive-cli.config.mjs +45 -0
  47. package/dist/archive/archive-invalid.errors.mjs +5 -0
  48. package/dist/archive/archived-lineage.pure.mjs +13 -0
  49. package/dist/archive/tar.pure.mjs +291 -0
  50. package/dist/archive/zstd.adapter.mjs +46 -0
  51. package/dist/bench/bench-report.pure.mjs +120 -0
  52. package/dist/bench/bench-runner.pure.mjs +89 -0
  53. package/dist/bench/bench.service.mjs +301 -0
  54. package/dist/cli-runtime.layer-BqK2mmVL.mjs +1191 -0
  55. package/dist/cli-runtime.layer.mjs +1 -0
  56. package/dist/cloud-client.adapter-Cy1BjDbG.mjs +3186 -0
  57. package/dist/cloud-client.adapter-DOVMoYAj.mjs +304 -0
  58. package/dist/command/akter-commands.config.mjs +32 -0
  59. package/dist/command/akter-program.config.mjs +1 -0
  60. package/dist/credentials/credentials.service.mjs +226 -0
  61. package/dist/credentials/keychain.adapter.mjs +92 -0
  62. package/dist/credentials/login.config.mjs +251 -0
  63. package/dist/deploy/auth/api-attempt.service.mjs +30 -0
  64. package/dist/deploy/auth/token-refresh.errors.mjs +4 -0
  65. package/dist/deploy/build-bundle.adapter.mjs +133 -0
  66. package/dist/deploy/build-manifest.pure.mjs +44 -0
  67. package/dist/deploy/cloud-client.adapter.mjs +1 -0
  68. package/dist/deploy/cloud-url.pure.mjs +17 -0
  69. package/dist/deploy/deploy-failed.errors.mjs +17 -0
  70. package/dist/deploy/deploy.service.mjs +156 -0
  71. package/dist/deploy/request-failure.pure.mjs +87 -0
  72. package/dist/dev-runner.pure.mjs +30 -0
  73. package/dist/docs/doc-topics.pure.mjs +21 -0
  74. package/dist/docs/docs.config.mjs +1 -0
  75. package/dist/docs.config-_21Xi6HU.mjs +190 -0
  76. package/dist/export/actor-export.service.mjs +267 -0
  77. package/dist/export/export-failed.errors.mjs +4 -0
  78. package/dist/export/export-failure.pure.mjs +18 -0
  79. package/dist/export/ordered-lines.pure.mjs +43 -0
  80. package/dist/export/ranged-download.pure.mjs +66 -0
  81. package/dist/export/snapshot-download.pure.mjs +86 -0
  82. package/dist/history-runner.pure.mjs +186 -0
  83. package/dist/history-since.pure.mjs +17 -0
  84. package/dist/hosted-runtime.layer-Cx3IPsEd.mjs +16358 -0
  85. package/dist/local/environment-cli.config.mjs +90 -0
  86. package/dist/local/environment-runner.pure.mjs +75 -0
  87. package/dist/local/local-cli.config.mjs +159 -0
  88. package/dist/logs/log-follow.config.mjs +21 -0
  89. package/dist/logs/log-follow.service.mjs +87 -0
  90. package/dist/logs/log-lines.pure.mjs +44 -0
  91. package/dist/migrate-runner.pure.mjs +28 -0
  92. package/dist/operation-input.pure-CS9iUhqK.mjs +1383 -0
  93. package/dist/operation-registry.pure-DVC8EDgj.mjs +283 -0
  94. package/dist/registry/actor-call.service.mjs +1 -0
  95. package/dist/registry/actor-commands.config.mjs +127 -0
  96. package/dist/registry/actor-refusal.pure.mjs +34 -0
  97. package/dist/registry/approval.service.mjs +80 -0
  98. package/dist/registry/cloud-commands.config.mjs +151 -0
  99. package/dist/registry/cloud-served.pure.mjs +31 -0
  100. package/dist/registry/operation-call.service.mjs +262 -0
  101. package/dist/registry/operation-input.pure.mjs +1 -0
  102. package/dist/registry/operation-output.pure.mjs +91 -0
  103. package/dist/registry/served-command.config.mjs +57 -0
  104. package/dist/runner-exited.errors.mjs +10 -0
  105. package/dist/terminal/cli-exit.errors.mjs +38 -0
  106. package/dist/terminal/cli-failure.pure.mjs +31 -0
  107. package/dist/terminal/confirm.adapter.mjs +27 -0
  108. package/package.json +61 -3
@@ -0,0 +1,1769 @@
1
+ import { S as none, Tn as pipe, _ as isSome, bn as dual, f as getOrElse, qt as hasProperty, w as some, x as match } from "./Option-DkxSnBhp.mjs";
2
+ import { $t as suspend, A as ensuring, B as flatMap$1, Et as orDie, Gt as scoped, M as fail, Nt as raceFirst, W as fnUntraced, Xt as succeed$1, _t as match$1, aa as Service, at as isEffect, dt as map$1, en as sync, f as cached, ht as mapError, ia as Reference, va as Prototype } from "./Effect-CKFpqbmw.mjs";
3
+ import { L as reduce, M as match$2, d as findFirstIndex, f as findLast, j as map$2, o as empty, u as findFirst, w as isReadonlyArrayNonEmpty } from "./Array-B4kuTQeW.mjs";
4
+ import { p as Error$1, sn as tag } from "./Schema-MiKt5K1v.mjs";
5
+ import { a as taggedEnum } from "./Data-CeCULr0-.mjs";
6
+ import { i as round } from "./Number-BvkRkfc-.mjs";
7
+ import { g as take } from "./Queue-CO5UQ6os.mjs";
8
+ import { n as make$1 } from "./Redacted-RkJrG5Me.mjs";
9
+ // ../../node_modules/.pnpm/effect@4.1.2_patch_hash=0e61176203bb1256381ce1c5b488d7951983ce38ff698647d3f4617383abbf07/node_modules/effect/dist/Terminal.js
10
+ const TypeId$1 = "~effect/Terminal";
11
+ const QuitErrorTypeId = "~effect/Terminal/QuitError";
12
+ /**
13
+ * Represents an error that occurs when a user attempts to
14
+ * quit out of a `Terminal` prompt for input (usually by entering `ctrl`+`c`).
15
+ *
16
+ * **When to use**
17
+ *
18
+ * Use when implementing terminal input or prompts that need to signal
19
+ * user-requested cancellation through the typed error channel.
20
+ *
21
+ * @see {@link isQuitError} for checking unknown errors when handling terminal cancellation
22
+ *
23
+ * @stability unstable
24
+ * @category errors
25
+ * @since 4.0.0
26
+ */
27
+ var QuitError = class extends (/*#__PURE__*/ Error$1("QuitError")({ _tag: /*#__PURE__*/ tag("QuitError") })) {
28
+ /**
29
+ * Marks this value as a terminal quit error for runtime guards.
30
+ *
31
+ * @since 4.0.0
32
+ */
33
+ [QuitErrorTypeId] = QuitErrorTypeId;
34
+ };
35
+ /**
36
+ * Returns `true` if the provided value is a `Terminal.QuitError`.
37
+ *
38
+ * **When to use**
39
+ *
40
+ * Use to narrow unknown failures to `QuitError` when handling terminal input
41
+ * cancellation.
42
+ *
43
+ * **Details**
44
+ *
45
+ * Returns `true` when the value carries the `QuitError` runtime marker and
46
+ * narrows it to `QuitError`.
47
+ *
48
+ * @see {@link QuitError} for the error value produced when terminal input is quit
49
+ *
50
+ * @stability unstable
51
+ * @category guards
52
+ * @since 4.0.0
53
+ */
54
+ const isQuitError = (u) => hasProperty(u, QuitErrorTypeId);
55
+ /**
56
+ * Service tag for command-line input and output services.
57
+ *
58
+ * **When to use**
59
+ *
60
+ * Use to access or provide platform terminal capabilities such as reading
61
+ * input, writing output, and inspecting terminal dimensions.
62
+ *
63
+ * @stability unstable
64
+ * @category services
65
+ * @since 4.0.0
66
+ */
67
+ const Terminal = /*#__PURE__*/ Service("effect/Terminal");
68
+ /**
69
+ * Creates a `Terminal` service implementation.
70
+ *
71
+ * **When to use**
72
+ *
73
+ * Use to construct a custom `Terminal` service implementation from concrete
74
+ * terminal capabilities when writing a platform adapter, test implementation,
75
+ * or custom runtime service.
76
+ *
77
+ * **Details**
78
+ *
79
+ * The implementation object supplies `columns`, `rows`, `size`, `readInput`,
80
+ * `readLine`, and `display`; `make` attaches the `Terminal` service marker so
81
+ * the result can be provided through the `Terminal` context service.
82
+ *
83
+ * @stability unstable
84
+ * @category constructors
85
+ * @since 4.0.0
86
+ */
87
+ const make = (impl) => Terminal.of({
88
+ ...impl,
89
+ [TypeId$1]: TypeId$1
90
+ });
91
+ // ../../node_modules/.pnpm/effect@4.1.2_patch_hash=0e61176203bb1256381ce1c5b488d7951983ce38ff698647d3f4617383abbf07/node_modules/effect/dist/cli/internal/ansi.js
92
+ /**
93
+ * Internal ANSI escape sequence helpers used by the unstable CLI rendering
94
+ * implementation. This module centralizes the control codes for text styling,
95
+ * cursor movement, line erasing, and terminal notifications so renderers can
96
+ * compose terminal output without scattering raw escape sequences throughout
97
+ * the CLI internals.
98
+ *
99
+ * The helpers deliberately work with plain strings because terminal rendering
100
+ * is sensitive to ordering: style codes must be reset after annotated text,
101
+ * cursor operations must account for one-based terminal coordinates, and line
102
+ * clearing usually needs to preserve the cursor position expected by the next
103
+ * frame.
104
+ */
105
+ const ESC = "\x1B[";
106
+ const SEP = ";";
107
+ /**
108
+ * @internal
109
+ */
110
+ const reset = `${ESC}0m`;
111
+ /**
112
+ * @internal
113
+ */
114
+ const bold = `${ESC}1m`;
115
+ /**
116
+ * @internal
117
+ */
118
+ const italicized = `${ESC}3m`;
119
+ /**
120
+ * @internal
121
+ */
122
+ const underlined = `${ESC}4m`;
123
+ /**
124
+ * @internal
125
+ */
126
+ const strikethrough = `${ESC}9m`;
127
+ /**
128
+ * @internal
129
+ */
130
+ const cursorShow = `${ESC}?25h`;
131
+ /**
132
+ * @internal
133
+ */
134
+ const cursorHide = `${ESC}?25l`;
135
+ /**
136
+ * @internal
137
+ */
138
+ const eraseLine = `${ESC}2K`;
139
+ /**
140
+ * @internal
141
+ */
142
+ const red = `${ESC}31m`;
143
+ /**
144
+ * @internal
145
+ */
146
+ const green = `${ESC}32m`;
147
+ /**
148
+ * @internal
149
+ */
150
+ const magenta = `${ESC}35m`;
151
+ /**
152
+ * @internal
153
+ */
154
+ const white = `${ESC}37m`;
155
+ /**
156
+ * @internal
157
+ */
158
+ const blackBright = `${ESC}90m`;
159
+ /**
160
+ * @internal
161
+ */
162
+ const cyanBright = `${ESC}96m`;
163
+ /**
164
+ * Wraps `text` in the given styles followed by a reset. When `colors` is
165
+ * `false` the text is returned unchanged, so callers gate color and style
166
+ * escapes in one place while cursor and erase controls stay untouched.
167
+ *
168
+ * @internal
169
+ */
170
+ const annotate = (colors, text, ...styles) => {
171
+ if (!colors) return text;
172
+ return `${styles.flat().join("")}${text}${reset}`;
173
+ };
174
+ /**
175
+ * Detects whether CLI output should use color and style escapes: stdout must
176
+ * be a TTY and `NO_COLOR` must be unset or empty.
177
+ *
178
+ * @internal
179
+ */
180
+ const detectColors = () => {
181
+ const globalProcess = globalThis.process;
182
+ return typeof globalProcess === "object" && globalProcess !== null && typeof globalProcess.stdout === "object" && globalProcess.stdout !== null && globalProcess.stdout.isTTY === true && !globalProcess.env?.NO_COLOR;
183
+ };
184
+ const combine = (...styles) => styles;
185
+ /**
186
+ * @internal
187
+ */
188
+ const cursorTo = (column, row) => {
189
+ if (row === void 0) return `${ESC}${Math.max(column + 1, 0)}G`;
190
+ return `${ESC}${row + 1}${SEP}${Math.max(column + 1, 0)}H`;
191
+ };
192
+ /**
193
+ * @internal
194
+ */
195
+ const cursorDown = (lines = 1) => {
196
+ return `${ESC}${lines}B`;
197
+ };
198
+ /**
199
+ * @internal
200
+ */
201
+ const cursorMove = (column, row = 0) => {
202
+ let command = "";
203
+ if (row < 0) command += `${ESC}${-row}A`;
204
+ if (row > 0) command += `${ESC}${row}B`;
205
+ if (column > 0) command += `${ESC}${column}C`;
206
+ if (column < 0) command += `${ESC}${-column}D`;
207
+ return command;
208
+ };
209
+ /**
210
+ * @internal
211
+ */
212
+ const eraseLines = (rows) => {
213
+ let command = "";
214
+ for (let i = 0; i < rows; i++) command += `${ESC}2K` + (i < rows - 1 ? `${ESC}1A` : "");
215
+ if (rows > 0) command += `${ESC}G`;
216
+ return command;
217
+ };
218
+ // ../../node_modules/.pnpm/effect@4.1.2_patch_hash=0e61176203bb1256381ce1c5b488d7951983ce38ff698647d3f4617383abbf07/node_modules/effect/dist/cli/Prompt.js
219
+ /**
220
+ * Builds interactive terminal prompts for CLI applications.
221
+ *
222
+ * A `Prompt<A>` describes a small terminal UI that renders frames, reads
223
+ * keyboard input, validates responses, and eventually produces an `A`. Prompts
224
+ * can ask for simple values, selections, lists, files, hidden text, or custom
225
+ * interactions. This module includes prompt constructors, tools for combining
226
+ * and transforming prompt output, and support for running prompts through the
227
+ * `Terminal` service.
228
+ *
229
+ * @stability unstable
230
+ * @since 4.0.0
231
+ */
232
+ const TypeId = "~effect/cli/Prompt";
233
+ const defaultTheme = {
234
+ prefix: "?",
235
+ arrowUp: "↑",
236
+ arrowDown: "↓",
237
+ checkboxOn: "☒",
238
+ checkboxOff: "☐",
239
+ tick: "✔",
240
+ ellipsis: "…",
241
+ pointerSmall: "›",
242
+ pointer: "❯",
243
+ descriptionSeparator: "- ",
244
+ passwordMask: "*",
245
+ toggleSeparator: "/",
246
+ primaryColor: cyanBright,
247
+ mutedColor: blackBright,
248
+ successColor: green,
249
+ errorColor: red,
250
+ submittedColor: white
251
+ };
252
+ const windowsTheme = {
253
+ ...defaultTheme,
254
+ checkboxOn: "[*]",
255
+ checkboxOff: "[ ]",
256
+ tick: "√",
257
+ ellipsis: "...",
258
+ pointerSmall: "»",
259
+ pointer: ">"
260
+ };
261
+ /**
262
+ * Creates a prompt theme using the current platform defaults.
263
+ *
264
+ * **Details**
265
+ *
266
+ * Unless `colors` is provided, it is detected when the theme is created:
267
+ * colors are enabled when stdout is a TTY and `NO_COLOR` is unset or empty.
268
+ *
269
+ * @stability unstable
270
+ * @category constructors
271
+ * @since 4.0.0
272
+ */
273
+ const makeTheme = (options) => ({
274
+ ...process.platform === "win32" ? windowsTheme : defaultTheme,
275
+ ...options,
276
+ colors: options?.colors ?? detectColors()
277
+ });
278
+ /**
279
+ * Context reference for the theme used by built-in prompts.
280
+ *
281
+ * **Details**
282
+ *
283
+ * Provide this reference once to theme every prompt in an application. A
284
+ * prompt's `theme` option takes precedence over the context value. The
285
+ * command wizard also reads `colors` from this reference, so provide a theme
286
+ * with `colors: false` to disable wizard styling.
287
+ *
288
+ * The default value is created with `makeTheme` the first time it is read,
289
+ * so color detection runs once per process. Changes to `NO_COLOR` after the
290
+ * first prompt do not affect the default theme.
291
+ *
292
+ * @stability unstable
293
+ * @category services
294
+ * @since 4.0.0
295
+ */
296
+ const Theme = /*#__PURE__*/ Reference("effect/cli/Prompt/Theme", { defaultValue: makeTheme });
297
+ const getTheme = (options) => map$1(Theme, (theme) => ({
298
+ ...theme,
299
+ ...options.theme
300
+ }));
301
+ const annotateErrorLine = (theme, line) => annotate(theme.colors, line, combine(italicized, theme.errorColor));
302
+ const annotateSymbol = (theme, symbol, ...styles) => symbol.length === 0 ? "" : annotate(theme.colors, symbol, ...styles);
303
+ const separateSymbol = (symbol, text) => symbol.length === 0 ? text : symbol + " " + text;
304
+ const renderPagingPrefix = (theme, showArrowUp, showArrowDown) => {
305
+ const width = Math.max(theme.arrowUp.length, theme.arrowDown.length);
306
+ if (showArrowUp) return theme.arrowUp.padEnd(width);
307
+ if (showArrowDown) return theme.arrowDown.padEnd(width);
308
+ return " ".repeat(width);
309
+ };
310
+ /**
311
+ * Creates a confirmation prompt that asks the user to choose a boolean yes/no
312
+ * value.
313
+ *
314
+ * **When to use**
315
+ *
316
+ * Use to ask for a yes/no answer that can be submitted directly.
317
+ *
318
+ * **Details**
319
+ *
320
+ * `initial` defaults to `false`. Enter submits the current default, yes-style
321
+ * input submits `true`, no-style input submits `false`, and other input beeps.
322
+ *
323
+ * @see {@link Toggle} for an interactive switch-before-submit boolean prompt
324
+ *
325
+ * @stability unstable
326
+ * @category constructors
327
+ * @since 4.0.0
328
+ */
329
+ const Confirm = (options) => {
330
+ const opts = {
331
+ initial: false,
332
+ ...options,
333
+ label: {
334
+ confirm: "yes",
335
+ deny: "no",
336
+ ...options.label
337
+ },
338
+ placeholder: {
339
+ defaultConfirm: "(Y/n)",
340
+ defaultDeny: "(y/N)",
341
+ ...options.placeholder
342
+ }
343
+ };
344
+ const initialState = { value: opts.initial };
345
+ return Custom(initialState, {
346
+ render: handleConfirmRender(opts),
347
+ process: (input) => handleConfirmProcess(input, opts.initial),
348
+ clear: handleConfirmClear(opts)
349
+ });
350
+ };
351
+ /**
352
+ * Creates a custom `Prompt` from the specified initial state and handlers.
353
+ *
354
+ * **Details**
355
+ *
356
+ * The initial state can either be a pure value or an `Effect`. This is
357
+ * particularly useful when the initial state of the `Prompt` must be computed
358
+ * by performing an effectful computation, such as reading data from the file
359
+ * system. A `Prompt` runs as a render loop: `render` returns ANSI output for
360
+ * the current frame, the `Terminal` obtains user input, `process` returns the
361
+ * next prompt action, and `clear` returns ANSI output used to clear the previous
362
+ * frame.
363
+ *
364
+ * Optionally, an external `events` dequeue can be provided as the third
365
+ * argument. When present, the render loop will race user input against events
366
+ * from the dequeue, allowing background events to trigger re-renders without
367
+ * waiting for a keypress. When an event is received from the dequeue, the
368
+ * `receive` handler is called instead of `process`.
369
+ *
370
+ * @stability unstable
371
+ * @category constructors
372
+ * @since 4.0.0
373
+ */
374
+ const Custom = (initialState, ...args) => {
375
+ const [events, handlers] = args.length === 1 ? [void 0, args[0]] : [args[0], args[1]];
376
+ const op = Object.create(proto);
377
+ op._tag = "Loop";
378
+ op.initialState = initialState;
379
+ op.render = handlers.render;
380
+ op.process = handlers.process;
381
+ op.clear = handlers.clear;
382
+ op.events = events;
383
+ return op;
384
+ };
385
+ /**
386
+ * Creates a date prompt that lets the user edit a formatted date value and
387
+ * validates the final `Date` before submission.
388
+ *
389
+ * **Details**
390
+ *
391
+ * `initial` defaults to the current `Date`, `dateMask` defaults to
392
+ * `YYYY-MM-DD HH:mm:ss`, mask parsing creates editable date parts plus literal
393
+ * tokens, `locales` customizes month and weekday labels, and `validate` runs on
394
+ * submission.
395
+ *
396
+ * **Gotchas**
397
+ *
398
+ * A supplied `initial` `Date` is edited in place during prompt interaction.
399
+ * Date edits use JavaScript `Date` setters, so out-of-range typed values can
400
+ * normalize before validation. If the prompt is meant to be editable,
401
+ * `dateMask` should contain at least one editable date token.
402
+ *
403
+ * @stability unstable
404
+ * @category constructors
405
+ * @since 4.0.0
406
+ */
407
+ const Date = (options) => {
408
+ const opts = {
409
+ initial: new globalThis.Date(),
410
+ dateMask: "YYYY-MM-DD HH:mm:ss",
411
+ validate: succeed$1,
412
+ ...options,
413
+ locales: {
414
+ ...defaultLocales,
415
+ ...options.locales
416
+ }
417
+ };
418
+ const dateParts = makeDateParts(opts.dateMask, opts.initial, opts.locales);
419
+ const initialState = {
420
+ dateParts,
421
+ typed: "",
422
+ cursor: dateParts.findIndex((part) => !part.isToken()),
423
+ value: opts.initial,
424
+ error: none()
425
+ };
426
+ return Custom(initialState, {
427
+ render: handleDateRender(opts),
428
+ process: handleDateProcess(opts),
429
+ clear: handleDateClear(opts)
430
+ });
431
+ };
432
+ /**
433
+ * Composes prompts by using the output of this prompt to create the next prompt.
434
+ *
435
+ * @stability unstable
436
+ * @category combinators
437
+ * @since 4.0.0
438
+ */
439
+ const flatMap = /*#__PURE__*/ dual(2, (self, f) => {
440
+ const op = Object.create(proto);
441
+ op._tag = "OnSuccess";
442
+ op.prompt = self;
443
+ op.onSuccess = f;
444
+ return op;
445
+ });
446
+ /**
447
+ * Creates a floating-point number prompt.
448
+ *
449
+ * **Details**
450
+ *
451
+ * The prompt supports minimum and maximum bounds, keyboard step sizes, display
452
+ * precision, and additional validation before submission.
453
+ *
454
+ * @stability unstable
455
+ * @category constructors
456
+ * @since 4.0.0
457
+ */
458
+ const Number = (options) => {
459
+ const opts = {
460
+ default: 0,
461
+ min: globalThis.Number.NEGATIVE_INFINITY,
462
+ max: globalThis.Number.POSITIVE_INFINITY,
463
+ incrementBy: 1,
464
+ decrementBy: 1,
465
+ precision: 2,
466
+ validate: (n) => {
467
+ if (n < opts.min) return fail(`${n} must be greater than or equal to ${opts.min}`);
468
+ if (n > opts.max) return fail(`${n} must be less than or equal to ${opts.max}`);
469
+ return succeed$1(n);
470
+ },
471
+ ...options
472
+ };
473
+ const initialValue = options.default === void 0 ? "" : `${opts.default}`;
474
+ const initialState = {
475
+ cursor: initialValue.length,
476
+ value: initialValue,
477
+ error: none()
478
+ };
479
+ return Custom(initialState, {
480
+ render: handleRenderFloat(opts),
481
+ process: handleProcessFloat(opts),
482
+ clear: handleNumberClear(opts)
483
+ });
484
+ };
485
+ /**
486
+ * Creates an integer prompt.
487
+ *
488
+ * **Details**
489
+ *
490
+ * The prompt supports minimum and maximum bounds, keyboard step sizes, and
491
+ * additional validation before submission.
492
+ *
493
+ * @stability unstable
494
+ * @category constructors
495
+ * @since 4.0.0
496
+ */
497
+ const Int = (options) => {
498
+ const opts = {
499
+ default: 0,
500
+ min: globalThis.Number.NEGATIVE_INFINITY,
501
+ max: globalThis.Number.POSITIVE_INFINITY,
502
+ incrementBy: 1,
503
+ decrementBy: 1,
504
+ validate: (n) => {
505
+ if (n < opts.min) return fail(`${n} must be greater than or equal to ${opts.min}`);
506
+ if (n > opts.max) return fail(`${n} must be less than or equal to ${opts.max}`);
507
+ return succeed$1(n);
508
+ },
509
+ ...options
510
+ };
511
+ const initialValue = options.default === void 0 ? "" : `${opts.default}`;
512
+ const initialState = {
513
+ cursor: initialValue.length,
514
+ value: initialValue,
515
+ error: none()
516
+ };
517
+ return Custom(initialState, {
518
+ render: handleRenderInteger(opts),
519
+ process: handleProcessInteger(opts),
520
+ clear: handleNumberClear(opts)
521
+ });
522
+ };
523
+ /**
524
+ * Transforms the output value produced by a prompt.
525
+ *
526
+ * @stability unstable
527
+ * @category combinators
528
+ * @since 4.0.0
529
+ */
530
+ const map = /*#__PURE__*/ dual(2, (self, f) => flatMap(self, (a) => succeed(f(a))));
531
+ /**
532
+ * Creates a password prompt that masks typed input and returns the submitted
533
+ * value wrapped in `Redacted`.
534
+ *
535
+ * @stability unstable
536
+ * @category constructors
537
+ * @since 4.0.0
538
+ */
539
+ const Password = (options) => basePrompt(options, "password").pipe(map(make$1));
540
+ /**
541
+ * Runs a prompt by reading terminal input and rendering prompt frames until the
542
+ * prompt submits a value.
543
+ *
544
+ * **Gotchas**
545
+ *
546
+ * The returned effect may fail with `Terminal.QuitError` if terminal input ends
547
+ * or the prompt is quit.
548
+ *
549
+ * @stability unstable
550
+ * @category running
551
+ * @since 4.0.0
552
+ */
553
+ const run = /*#__PURE__*/ fnUntraced(function* (self) {
554
+ const terminal = yield* Terminal;
555
+ const input = yield* cached(terminal.readInput);
556
+ return yield* runWithInput(self, terminal, input);
557
+ }, /*#__PURE__*/ mapError(() => new QuitError({})), scoped);
558
+ const getSelectInitialIndex = (choices) => {
559
+ let initialIndex = 0;
560
+ let seenSelected = -1;
561
+ for (let i = 0; i < choices.length; i++) if (choices[i].selected === true) {
562
+ if (seenSelected !== -1) throw new Error("InvalidArgumentException: only a single choice can be selected by default for Prompt.Select");
563
+ seenSelected = i;
564
+ }
565
+ if (seenSelected !== -1) initialIndex = seenSelected;
566
+ return initialIndex;
567
+ };
568
+ /**
569
+ * Creates a prompt that lets the user select a single value from a list of
570
+ * choices.
571
+ *
572
+ * **Gotchas**
573
+ *
574
+ * At most one choice may be marked as selected by default.
575
+ *
576
+ * @stability unstable
577
+ * @category constructors
578
+ * @since 4.0.0
579
+ */
580
+ const Select = (options) => {
581
+ const opts = {
582
+ maxPerPage: 10,
583
+ ...options
584
+ };
585
+ const initialIndex = getSelectInitialIndex(opts.choices);
586
+ return Custom(initialIndex, {
587
+ render: handleSelectRender(opts),
588
+ process: handleSelectProcess(opts),
589
+ clear: handleSelectClear(opts)
590
+ });
591
+ };
592
+ /**
593
+ * Creates a `Prompt` which immediately succeeds with the specified value.
594
+ *
595
+ * **Details**
596
+ *
597
+ * This prompt does not attempt to obtain user input or render anything to the
598
+ * screen.
599
+ *
600
+ * @stability unstable
601
+ * @category constructors
602
+ * @since 4.0.0
603
+ */
604
+ const succeed = (value) => {
605
+ const op = Object.create(proto);
606
+ op._tag = "Succeed";
607
+ op.value = value;
608
+ return op;
609
+ };
610
+ /**
611
+ * Creates a text-entry prompt that echoes input and returns the submitted
612
+ * string after validation.
613
+ *
614
+ * @stability unstable
615
+ * @category constructors
616
+ * @since 4.0.0
617
+ */
618
+ const String = (options) => basePrompt(options, "text");
619
+ /**
620
+ * Creates a toggle prompt that lets the user switch between active and inactive
621
+ * states and returns the selected boolean value.
622
+ *
623
+ * @stability unstable
624
+ * @category constructors
625
+ * @since 4.0.0
626
+ */
627
+ const Toggle = (options) => {
628
+ const opts = {
629
+ initial: false,
630
+ active: "on",
631
+ inactive: "off",
632
+ ...options
633
+ };
634
+ return Custom(opts.initial, {
635
+ render: handleToggleRender(opts),
636
+ process: handleToggleProcess,
637
+ clear: () => handleToggleClear(opts)
638
+ });
639
+ };
640
+ const proto = {
641
+ .../*#__PURE__*/ Prototype({
642
+ label: "Prompt",
643
+ evaluate() {
644
+ return run(this);
645
+ }
646
+ }),
647
+ [TypeId]: { _Output: (_) => _ }
648
+ };
649
+ const runWithInput = (prompt, terminal, input) => suspend(() => {
650
+ const op = prompt;
651
+ switch (op._tag) {
652
+ case "Loop": return flatMap$1(input, (queue) => runLoop(op, terminal, queue));
653
+ case "OnSuccess": return flatMap$1(runWithInput(op.prompt, terminal, input), (a) => runWithInput(op.onSuccess(a), terminal, input));
654
+ case "Succeed": return succeed$1(op.value);
655
+ }
656
+ });
657
+ const runLoop = /*#__PURE__*/ fnUntraced(function* (loop, terminal, input) {
658
+ let state = isEffect(loop.initialState) ? yield* loop.initialState : loop.initialState;
659
+ let action = Action.NextFrame({ state });
660
+ let clear = "";
661
+ while (true) {
662
+ const msg = yield* loop.render(state, action);
663
+ yield* orDie(terminal.display(clear + msg));
664
+ clear = "";
665
+ if (loop.events) {
666
+ const takeInput = take(input).pipe(map$1((input) => ({
667
+ _tag: "Input",
668
+ input
669
+ })));
670
+ const result = yield* raceFirst(takeInput, take(loop.events).pipe(map$1((value) => ({
671
+ _tag: "Event",
672
+ value
673
+ }))));
674
+ action = yield* loop.process(result, state);
675
+ } else {
676
+ const result = yield* take(input);
677
+ action = yield* loop.process(result, state);
678
+ }
679
+ switch (action._tag) {
680
+ case "Beep": continue;
681
+ case "NextFrame":
682
+ clear = yield* loop.clear(state, action);
683
+ state = action.state;
684
+ continue;
685
+ case "Submit": {
686
+ clear = yield* loop.clear(state, action);
687
+ const msg = yield* loop.render(state, action);
688
+ yield* orDie(terminal.display(clear + msg));
689
+ return action.value;
690
+ }
691
+ }
692
+ }
693
+ }, (effect, _, terminal) => ensuring(effect, orDie(terminal.display(cursorShow))));
694
+ const Action = /*#__PURE__*/ taggedEnum();
695
+ /**
696
+ * Clears all lines taken up by the specified `text`.
697
+ */
698
+ const eraseText = (text, columns) => {
699
+ if (columns === 0) return eraseLine + cursorTo(0);
700
+ let rows = 0;
701
+ const lines = text.split(NEWLINE_REGEXP);
702
+ for (const line of lines) rows += 1 + Math.floor(Math.max(line.length - 1, 0) / columns);
703
+ return eraseLines(rows);
704
+ };
705
+ const lines = (prompt, columns) => {
706
+ const lines = prompt.split(NEWLINE_REGEXP);
707
+ return columns === 0 ? lines.length : pipe(map$2(lines, (line) => Math.ceil(line.length / columns)), reduce(0, (left, right) => left + right));
708
+ };
709
+ const clearOutputWithError = (outputText, columns, errorText) => {
710
+ if (errorText !== void 0 && errorText.length > 0) return cursorDown(lines(errorText, columns)) + eraseText(`\n${errorText}`, columns) + eraseText(outputText, columns);
711
+ return eraseText(outputText, columns);
712
+ };
713
+ const renderBeep = "\x07";
714
+ const NEWLINE_REGEXP = /\r?\n/;
715
+ const handleConfirmClear = (options) => {
716
+ return fnUntraced(function* (state, _) {
717
+ const columns = yield* (yield* Terminal).columns;
718
+ const figures = yield* getTheme(options);
719
+ const confirmMessage = state.value ? options.placeholder.defaultConfirm : options.placeholder.defaultDeny;
720
+ const promptText = renderPrompt(confirmMessage, options.message, figures.prefix, figures.pointerSmall, figures, { plain: true });
721
+ return eraseText(promptText, columns) + (eraseLine + "\x1B[G");
722
+ });
723
+ };
724
+ const renderConfirmNextFrame = /*#__PURE__*/ fnUntraced(function* (state, options) {
725
+ const figures = yield* getTheme(options);
726
+ const leadingSymbol = annotateSymbol(figures, figures.prefix, figures.primaryColor);
727
+ const trailingSymbol = annotateSymbol(figures, figures.pointerSmall, figures.mutedColor);
728
+ const confirmMessage = state.value ? options.placeholder.defaultConfirm : options.placeholder.defaultDeny;
729
+ const confirm = annotate(figures.colors, confirmMessage, figures.mutedColor);
730
+ const promptMsg = renderPrompt(confirm, options.message, leadingSymbol, trailingSymbol, figures);
731
+ return cursorHide + promptMsg;
732
+ });
733
+ const renderConfirmSubmission = /*#__PURE__*/ fnUntraced(function* (value, options) {
734
+ const figures = yield* getTheme(options);
735
+ const leadingSymbol = annotateSymbol(figures, figures.tick, figures.successColor);
736
+ const trailingSymbol = annotateSymbol(figures, figures.ellipsis, figures.mutedColor);
737
+ const confirmMessage = value ? options.label.confirm : options.label.deny;
738
+ return renderPrompt(confirmMessage, options.message, leadingSymbol, trailingSymbol, figures) + "\n";
739
+ });
740
+ const handleConfirmRender = (options) => {
741
+ return (_, action) => {
742
+ return Action.$match(action, {
743
+ Beep: () => succeed$1(renderBeep),
744
+ NextFrame: ({ state }) => renderConfirmNextFrame(state, options),
745
+ Submit: ({ value }) => renderConfirmSubmission(value, options)
746
+ });
747
+ };
748
+ };
749
+ const TRUE_VALUE_REGEXP = /^y|t$/;
750
+ const FALSE_VALUE_REGEXP = /^n|f$/;
751
+ const handleConfirmProcess = (input, defaultValue) => {
752
+ const value = getOrElse(input.input, () => "");
753
+ if (input.key.name === "enter" || input.key.name === "return") return succeed$1(Action.Submit({ value: defaultValue }));
754
+ if (TRUE_VALUE_REGEXP.test(value.toLowerCase())) return succeed$1(Action.Submit({ value: true }));
755
+ if (FALSE_VALUE_REGEXP.test(value.toLowerCase())) return succeed$1(Action.Submit({ value: false }));
756
+ return succeed$1(Action.Beep());
757
+ };
758
+ const handleDateClear = (options) => {
759
+ return fnUntraced(function* (state, _) {
760
+ const columns = yield* (yield* Terminal).columns;
761
+ const figures = yield* getTheme(options);
762
+ const resetCurrentLine = eraseLine + "\x1B[G";
763
+ const parts = reduce(state.dateParts, "", (doc, part) => doc + part.toString());
764
+ const promptText = renderPrompt(parts, options.message, figures.prefix, figures.pointerSmall, figures, { plain: true });
765
+ const errorText = isSome(state.error) ? match$2(state.error.value.split(NEWLINE_REGEXP), {
766
+ onEmpty: () => "",
767
+ onNonEmpty: (errorLines) => separateSymbol(figures.pointerSmall, errorLines.join("\n"))
768
+ }) : "";
769
+ return clearOutputWithError(promptText, columns, errorText) + resetCurrentLine;
770
+ });
771
+ };
772
+ const renderDateError = (state, pointer, theme) => {
773
+ if (isSome(state.error)) {
774
+ const errorLines = state.error.value.split(NEWLINE_REGEXP);
775
+ if (isReadonlyArrayNonEmpty(errorLines)) {
776
+ const prefix = annotateSymbol(theme, pointer, theme.errorColor);
777
+ const lines = map$2(errorLines, (str) => annotateErrorLine(theme, str));
778
+ return "\x1B[s\n" + separateSymbol(prefix, lines.join("\n")) + "\x1B[u";
779
+ }
780
+ }
781
+ return "";
782
+ };
783
+ const renderParts = (state, theme, submitted = false) => {
784
+ return reduce(state.dateParts, "", (doc, part, currentIndex) => {
785
+ const partDoc = part.toString();
786
+ if (currentIndex === state.cursor && !submitted) {
787
+ const annotation = combine(underlined, theme.primaryColor);
788
+ return doc + annotate(theme.colors, partDoc, annotation);
789
+ }
790
+ return doc + partDoc;
791
+ });
792
+ };
793
+ const renderDateNextFrame = /*#__PURE__*/ fnUntraced(function* (state, options) {
794
+ const figures = yield* getTheme(options);
795
+ const leadingSymbol = annotateSymbol(figures, figures.prefix, figures.primaryColor);
796
+ const trailingSymbol = annotateSymbol(figures, figures.pointerSmall, figures.mutedColor);
797
+ const parts = renderParts(state, figures);
798
+ const promptMsg = renderPrompt(parts, options.message, leadingSymbol, trailingSymbol, figures);
799
+ const errorMsg = renderDateError(state, figures.pointerSmall, figures);
800
+ return cursorHide + promptMsg + errorMsg;
801
+ });
802
+ const renderDateSubmission = /*#__PURE__*/ fnUntraced(function* (state, options) {
803
+ const figures = yield* getTheme(options);
804
+ const leadingSymbol = annotateSymbol(figures, figures.tick, figures.successColor);
805
+ const trailingSymbol = annotateSymbol(figures, figures.ellipsis, figures.mutedColor);
806
+ const parts = renderParts(state, figures, true);
807
+ return renderPrompt(parts, options.message, leadingSymbol, trailingSymbol, figures) + "\n";
808
+ });
809
+ const processUp = (state) => {
810
+ state.dateParts[state.cursor].increment();
811
+ return Action.NextFrame({ state: {
812
+ ...state,
813
+ typed: ""
814
+ } });
815
+ };
816
+ const processDown = (state) => {
817
+ state.dateParts[state.cursor].decrement();
818
+ return Action.NextFrame({ state: {
819
+ ...state,
820
+ typed: ""
821
+ } });
822
+ };
823
+ const processDateCursorLeft = (state) => {
824
+ const previous = state.dateParts[state.cursor].previousPart();
825
+ if (isSome(previous)) return Action.NextFrame({ state: {
826
+ ...state,
827
+ typed: "",
828
+ cursor: state.dateParts.indexOf(previous.value)
829
+ } });
830
+ return Action.Beep();
831
+ };
832
+ const processDateCursorRight = (state) => {
833
+ const next = state.dateParts[state.cursor].nextPart();
834
+ if (isSome(next)) return Action.NextFrame({ state: {
835
+ ...state,
836
+ typed: "",
837
+ cursor: state.dateParts.indexOf(next.value)
838
+ } });
839
+ return Action.Beep();
840
+ };
841
+ const processDateNext = (state) => {
842
+ const next = state.dateParts[state.cursor].nextPart();
843
+ const cursor = match(next, {
844
+ onNone: () => state.dateParts.findIndex((part) => !part.isToken()),
845
+ onSome: (next) => state.dateParts.indexOf(next)
846
+ });
847
+ return Action.NextFrame({ state: {
848
+ ...state,
849
+ typed: "",
850
+ cursor
851
+ } });
852
+ };
853
+ const defaultDateProcessor = (value, state) => {
854
+ if (/\d/.test(value)) {
855
+ const typed = state.typed + value;
856
+ state.dateParts[state.cursor].setValue(typed);
857
+ return Action.NextFrame({ state: {
858
+ ...state,
859
+ typed
860
+ } });
861
+ }
862
+ return Action.Beep();
863
+ };
864
+ const defaultLocales = {
865
+ months: [
866
+ "January",
867
+ "February",
868
+ "March",
869
+ "April",
870
+ "May",
871
+ "June",
872
+ "July",
873
+ "August",
874
+ "September",
875
+ "October",
876
+ "November",
877
+ "December"
878
+ ],
879
+ monthsShort: [
880
+ "Jan",
881
+ "Feb",
882
+ "Mar",
883
+ "Apr",
884
+ "May",
885
+ "Jun",
886
+ "Jul",
887
+ "Aug",
888
+ "Sep",
889
+ "Oct",
890
+ "Nov",
891
+ "Dec"
892
+ ],
893
+ weekdays: [
894
+ "Sunday",
895
+ "Monday",
896
+ "Tuesday",
897
+ "Wednesday",
898
+ "Thursday",
899
+ "Friday",
900
+ "Saturday"
901
+ ],
902
+ weekdaysShort: [
903
+ "Sun",
904
+ "Mon",
905
+ "Tue",
906
+ "Wed",
907
+ "Thu",
908
+ "Fri",
909
+ "Sat"
910
+ ]
911
+ };
912
+ const handleDateRender = (options) => {
913
+ return (state, action) => {
914
+ return Action.$match(action, {
915
+ Beep: () => succeed$1(renderBeep),
916
+ NextFrame: ({ state }) => renderDateNextFrame(state, options),
917
+ Submit: () => renderDateSubmission(state, options)
918
+ });
919
+ };
920
+ };
921
+ const handleDateProcess = (options) => {
922
+ return (input, state) => {
923
+ switch (input.key.name) {
924
+ case "left": return succeed$1(processDateCursorLeft(state));
925
+ case "right": return succeed$1(processDateCursorRight(state));
926
+ case "k":
927
+ case "up": return succeed$1(processUp(state));
928
+ case "j":
929
+ case "down": return succeed$1(processDown(state));
930
+ case "tab": return succeed$1(processDateNext(state));
931
+ case "enter":
932
+ case "return": return match$1(options.validate(state.value), {
933
+ onFailure: (error) => Action.NextFrame({ state: {
934
+ ...state,
935
+ error: some(error)
936
+ } }),
937
+ onSuccess: (value) => Action.Submit({ value })
938
+ });
939
+ default: return succeed$1(defaultDateProcessor(getOrElse(input.input, () => ""), state));
940
+ }
941
+ };
942
+ };
943
+ const DATE_PART_REGEXP = /\\(.)|"((?:\\["\\]|[^"])+)"|(D[Do]?|d{3,4}|d)|(M{1,4})|(YY(?:YY)?)|([aA])|([Hh]{1,2})|(m{1,2})|(s{1,2})|(S{1,4})|./g;
944
+ const regExpGroups = {
945
+ 1: ({ token, ...opts }) => new Token({
946
+ token: token.replace(/\\(.)/g, "$1"),
947
+ ...opts
948
+ }),
949
+ 2: (opts) => new Day(opts),
950
+ 3: (opts) => new Month(opts),
951
+ 4: (opts) => new Year(opts),
952
+ 5: (opts) => new Meridiem(opts),
953
+ 6: (opts) => new Hours(opts),
954
+ 7: (opts) => new Minutes(opts),
955
+ 8: (opts) => new Seconds(opts),
956
+ 9: (opts) => new Milliseconds(opts)
957
+ };
958
+ const makeDateParts = (dateMask, date, locales) => {
959
+ const parts = [];
960
+ let result = null;
961
+ while (result = DATE_PART_REGEXP.exec(dateMask)) {
962
+ const match = result.shift();
963
+ const index = result.findIndex((group) => group !== void 0);
964
+ if (index in regExpGroups) {
965
+ const token = result[index] || match;
966
+ parts.push(regExpGroups[index]({
967
+ token,
968
+ date,
969
+ parts,
970
+ locales
971
+ }));
972
+ } else parts.push(new Token({
973
+ token: result[index] || match,
974
+ date,
975
+ parts,
976
+ locales
977
+ }));
978
+ }
979
+ const orderedParts = parts.reduce((array, element) => {
980
+ const lastElement = array[array.length - 1];
981
+ if (element.isToken() && lastElement !== void 0 && lastElement.isToken()) lastElement.setValue(element.token);
982
+ else array.push(element);
983
+ return array;
984
+ }, empty());
985
+ parts.splice(0, parts.length, ...orderedParts);
986
+ return parts;
987
+ };
988
+ var DatePart = class {
989
+ token;
990
+ date;
991
+ parts;
992
+ locales;
993
+ constructor(params) {
994
+ this.token = params.token;
995
+ this.locales = params.locales;
996
+ this.date = params.date || new globalThis.Date();
997
+ this.parts = params.parts || [this];
998
+ }
999
+ /**
1000
+ * Returns `true` if this `DatePart` is a `Token`, `false` otherwise.
1001
+ */
1002
+ isToken() {
1003
+ return false;
1004
+ }
1005
+ /**
1006
+ * Retrieves the next date part in the list of parts.
1007
+ */
1008
+ nextPart() {
1009
+ const currentPartIndex = getOrElse(findFirstIndex(this.parts, (part) => part === this), () => 0);
1010
+ return findFirst(this.parts.slice(currentPartIndex + 1), (part) => !part.isToken());
1011
+ }
1012
+ /**
1013
+ * Retrieves the previous date part in the list of parts.
1014
+ */
1015
+ previousPart() {
1016
+ const currentPartIndex = findFirstIndex(this.parts, (part) => part === this);
1017
+ if (isSome(currentPartIndex)) return findLast(this.parts.slice(0, currentPartIndex.value), (part) => !part.isToken());
1018
+ return none();
1019
+ }
1020
+ toString() {
1021
+ return globalThis.String(this.date);
1022
+ }
1023
+ };
1024
+ var Token = class extends DatePart {
1025
+ increment() {}
1026
+ decrement() {}
1027
+ setValue(value) {
1028
+ this.token = this.token + value;
1029
+ }
1030
+ isToken() {
1031
+ return true;
1032
+ }
1033
+ toString() {
1034
+ return this.token;
1035
+ }
1036
+ };
1037
+ var Milliseconds = class extends DatePart {
1038
+ increment() {
1039
+ this.date.setMilliseconds(this.date.getMilliseconds() + 1);
1040
+ }
1041
+ decrement() {
1042
+ this.date.setMilliseconds(this.date.getMilliseconds() - 1);
1043
+ }
1044
+ setValue(value) {
1045
+ this.date.setMilliseconds(globalThis.Number.parseInt(value.slice(-this.token.length)));
1046
+ }
1047
+ toString() {
1048
+ return `${this.date.getMilliseconds()}`.padStart(4, "0").substring(0, this.token.length);
1049
+ }
1050
+ };
1051
+ var Seconds = class extends DatePart {
1052
+ increment() {
1053
+ this.date.setSeconds(this.date.getSeconds() + 1);
1054
+ }
1055
+ decrement() {
1056
+ this.date.setSeconds(this.date.getSeconds() - 1);
1057
+ }
1058
+ setValue(value) {
1059
+ this.date.setSeconds(globalThis.Number.parseInt(value.slice(-2)));
1060
+ }
1061
+ toString() {
1062
+ const seconds = `${this.date.getSeconds()}`;
1063
+ return this.token.length > 1 ? seconds.padStart(2, "0") : seconds;
1064
+ }
1065
+ };
1066
+ var Minutes = class extends DatePart {
1067
+ increment() {
1068
+ this.date.setMinutes(this.date.getMinutes() + 1);
1069
+ }
1070
+ decrement() {
1071
+ this.date.setMinutes(this.date.getMinutes() - 1);
1072
+ }
1073
+ setValue(value) {
1074
+ this.date.setMinutes(globalThis.Number.parseInt(value.slice(-2)));
1075
+ }
1076
+ toString() {
1077
+ const minutes = `${this.date.getMinutes()}`;
1078
+ return this.token.length > 1 ? minutes.padStart(2, "0") : minutes;
1079
+ }
1080
+ };
1081
+ var Hours = class extends DatePart {
1082
+ increment() {
1083
+ this.date.setHours(this.date.getHours() + 1);
1084
+ }
1085
+ decrement() {
1086
+ this.date.setHours(this.date.getHours() - 1);
1087
+ }
1088
+ setValue(value) {
1089
+ this.date.setHours(globalThis.Number.parseInt(value.slice(-2)));
1090
+ }
1091
+ toString() {
1092
+ const hours = /h/.test(this.token) ? this.date.getHours() % 12 || 12 : this.date.getHours();
1093
+ return this.token.length > 1 ? `${hours}`.padStart(2, "0") : `${hours}`;
1094
+ }
1095
+ };
1096
+ var Day = class extends DatePart {
1097
+ increment() {
1098
+ this.date.setDate(this.date.getDate() + 1);
1099
+ }
1100
+ decrement() {
1101
+ this.date.setDate(this.date.getDate() - 1);
1102
+ }
1103
+ setValue(value) {
1104
+ this.date.setDate(globalThis.Number.parseInt(value.slice(-2)));
1105
+ }
1106
+ toString() {
1107
+ const date = this.date.getDate();
1108
+ const day = this.date.getDay();
1109
+ switch (this.token) {
1110
+ case "DD": return `${date}`.padStart(2, "0");
1111
+ case "Do": return `${date}${this.ordinalIndicator(date)}`;
1112
+ case "d": return `${day + 1}`;
1113
+ case "ddd": return this.locales.weekdaysShort[day];
1114
+ case "dddd": return this.locales.weekdays[day];
1115
+ default: return `${date}`;
1116
+ }
1117
+ }
1118
+ ordinalIndicator(day) {
1119
+ if (day >= 11 && day <= 13) return "th";
1120
+ switch (day % 10) {
1121
+ case 1: return "st";
1122
+ case 2: return "nd";
1123
+ case 3: return "rd";
1124
+ default: return "th";
1125
+ }
1126
+ }
1127
+ };
1128
+ var Month = class extends DatePart {
1129
+ increment() {
1130
+ this.date.setMonth(this.date.getMonth() + 1);
1131
+ }
1132
+ decrement() {
1133
+ this.date.setMonth(this.date.getMonth() - 1);
1134
+ }
1135
+ setValue(value) {
1136
+ const month = globalThis.Number.parseInt(value.slice(-2)) - 1;
1137
+ this.date.setMonth(month < 0 ? 0 : month);
1138
+ }
1139
+ toString() {
1140
+ const month = this.date.getMonth();
1141
+ switch (this.token.length) {
1142
+ case 2: return `${month + 1}`.padStart(2, "0");
1143
+ case 3: return this.locales.monthsShort[month];
1144
+ case 4: return this.locales.months[month];
1145
+ default: return `${month + 1}`;
1146
+ }
1147
+ }
1148
+ };
1149
+ var Year = class extends DatePart {
1150
+ increment() {
1151
+ this.date.setFullYear(this.date.getFullYear() + 1);
1152
+ }
1153
+ decrement() {
1154
+ this.date.setFullYear(this.date.getFullYear() - 1);
1155
+ }
1156
+ setValue(value) {
1157
+ this.date.setFullYear(globalThis.Number.parseInt(value.slice(-4)));
1158
+ }
1159
+ toString() {
1160
+ const year = `${this.date.getFullYear()}`.padStart(4, "0");
1161
+ return this.token.length === 2 ? year.slice(-2) : year;
1162
+ }
1163
+ };
1164
+ var Meridiem = class extends DatePart {
1165
+ increment() {
1166
+ this.date.setHours((this.date.getHours() + 12) % 24);
1167
+ }
1168
+ decrement() {
1169
+ this.increment();
1170
+ }
1171
+ setValue(_value) {}
1172
+ toString() {
1173
+ const meridiem = this.date.getHours() >= 12 ? "pm" : "am";
1174
+ return /A/.test(this.token) ? meridiem.toUpperCase() : meridiem;
1175
+ }
1176
+ };
1177
+ const renderPrompt = (confirm, message, leadingSymbol, trailingSymbol, theme, options) => {
1178
+ const prefix = leadingSymbol.length === 0 ? "" : leadingSymbol + " ";
1179
+ const renderLine = (line) => {
1180
+ let output = prefix + line;
1181
+ if (trailingSymbol.length > 0) output += " " + trailingSymbol;
1182
+ if (confirm.length > 0) output += " " + confirm;
1183
+ else if (trailingSymbol.length > 0) output += " ";
1184
+ return output;
1185
+ };
1186
+ return match$2(message.split(NEWLINE_REGEXP), {
1187
+ onEmpty: () => renderLine(""),
1188
+ onNonEmpty: (promptLines) => {
1189
+ const lines = options?.plain === true ? promptLines : map$2(promptLines, (line) => annotate(theme.colors, line, bold));
1190
+ return renderLine(lines.join("\n"));
1191
+ }
1192
+ });
1193
+ };
1194
+ const renderChoiceDescription = (choice, isActive, theme, renderOptions) => {
1195
+ if (!choice.disabled && choice.description && isActive) {
1196
+ const text = theme.descriptionSeparator + choice.description;
1197
+ return renderOptions?.plain === true ? text : annotate(theme.colors, text, theme.mutedColor);
1198
+ }
1199
+ return "";
1200
+ };
1201
+ const handleNumberClear = (options) => {
1202
+ return fnUntraced(function* (state, _) {
1203
+ const columns = yield* (yield* Terminal).columns;
1204
+ const figures = yield* getTheme(options);
1205
+ const resetCurrentLine = eraseLine + "\x1B[G";
1206
+ const errorText = renderNumberError(state, figures.pointerSmall, figures, { plain: true });
1207
+ const promptText = renderNumberOutput(state, figures.prefix, figures.pointerSmall, options, figures, { plain: true });
1208
+ return clearOutputWithError(promptText, columns, errorText) + resetCurrentLine;
1209
+ });
1210
+ };
1211
+ const renderNumberInput = (state, submitted, theme, renderOptions) => {
1212
+ const value = state.value === "" ? "" : `${state.value}`;
1213
+ if (submitted || renderOptions?.plain === true) return value;
1214
+ const annotation = isSome(state.error) ? theme.errorColor : combine(underlined, theme.primaryColor);
1215
+ return annotate(theme.colors, value, annotation);
1216
+ };
1217
+ const renderNumberError = (state, pointer, theme, renderOptions) => {
1218
+ if (isSome(state.error)) return match$2(state.error.value.split(NEWLINE_REGEXP), {
1219
+ onEmpty: () => "",
1220
+ onNonEmpty: (errorLines) => {
1221
+ if (renderOptions?.plain === true) return separateSymbol(pointer, errorLines.join("\n"));
1222
+ const prefix = annotateSymbol(theme, pointer, theme.errorColor);
1223
+ const lines = map$2(errorLines, (str) => annotateErrorLine(theme, str));
1224
+ return "\x1B[s\n" + separateSymbol(prefix, lines.join("\n")) + "\x1B[u";
1225
+ }
1226
+ });
1227
+ return "";
1228
+ };
1229
+ const renderNumberOutput = (state, leadingSymbol, trailingSymbol, options, theme, renderOptions, submitted = false) => {
1230
+ const value = renderNumberInput(state, submitted, theme, renderOptions);
1231
+ return renderPrompt(value, options.message, leadingSymbol, trailingSymbol, theme, renderOptions);
1232
+ };
1233
+ const renderNumberNextFrame = /*#__PURE__*/ fnUntraced(function* (state, options) {
1234
+ const figures = yield* getTheme(options);
1235
+ const leadingSymbol = annotateSymbol(figures, figures.prefix, figures.primaryColor);
1236
+ const trailingSymbol = annotateSymbol(figures, figures.pointerSmall, figures.mutedColor);
1237
+ const errorMsg = renderNumberError(state, figures.pointerSmall, figures);
1238
+ return renderNumberOutput(state, leadingSymbol, trailingSymbol, options, figures) + errorMsg;
1239
+ });
1240
+ const renderNumberSubmission = /*#__PURE__*/ fnUntraced(function* (nextState, options) {
1241
+ const figures = yield* getTheme(options);
1242
+ const leadingSymbol = annotateSymbol(figures, figures.tick, figures.successColor);
1243
+ const trailingSymbol = annotateSymbol(figures, figures.ellipsis, figures.mutedColor);
1244
+ return renderNumberOutput(nextState, leadingSymbol, trailingSymbol, options, figures, void 0, true) + "\n";
1245
+ });
1246
+ const processNumberBackspace = (state) => {
1247
+ if (state.value.length <= 0) return succeed$1(Action.Beep());
1248
+ const value = state.value.slice(0, state.value.length - 1);
1249
+ return succeed$1(Action.NextFrame({ state: {
1250
+ ...state,
1251
+ value,
1252
+ error: none()
1253
+ } }));
1254
+ };
1255
+ const processNumberClear = (state) => succeed$1(Action.NextFrame({ state: {
1256
+ ...state,
1257
+ cursor: 0,
1258
+ value: "",
1259
+ error: none()
1260
+ } }));
1261
+ const defaultIntProcessor = (input, state) => {
1262
+ if (state.value.length === 0 && input === "-") return succeed$1(Action.NextFrame({ state: {
1263
+ ...state,
1264
+ value: "-",
1265
+ error: none()
1266
+ } }));
1267
+ const parsed = globalThis.Number.parseInt(state.value + input);
1268
+ if (globalThis.Number.isNaN(parsed)) return succeed$1(Action.Beep());
1269
+ else return succeed$1(Action.NextFrame({ state: {
1270
+ ...state,
1271
+ value: `${parsed}`,
1272
+ error: none()
1273
+ } }));
1274
+ };
1275
+ const defaultFloatProcessor = (input, state) => {
1276
+ if (input === "." && state.value.includes(".")) return succeed$1(Action.Beep());
1277
+ if (state.value.length === 0 && input === "-") return succeed$1(Action.NextFrame({ state: {
1278
+ ...state,
1279
+ value: "-",
1280
+ error: none()
1281
+ } }));
1282
+ const parsed = globalThis.Number.parseFloat(state.value + input);
1283
+ if (globalThis.Number.isNaN(parsed)) return succeed$1(Action.Beep());
1284
+ else return succeed$1(Action.NextFrame({ state: {
1285
+ ...state,
1286
+ value: input === "." ? `${parsed}.` : state.value.includes(".") && /^\d$/.test(input) ? state.value + input : `${parsed}`,
1287
+ error: none()
1288
+ } }));
1289
+ };
1290
+ const handleRenderInteger = (options) => {
1291
+ return (state, action) => {
1292
+ return Action.$match(action, {
1293
+ Beep: () => succeed$1(renderBeep),
1294
+ NextFrame: ({ state }) => renderNumberNextFrame(state, options),
1295
+ Submit: () => renderNumberSubmission(state, options)
1296
+ });
1297
+ };
1298
+ };
1299
+ const handleProcessInteger = (options) => {
1300
+ return (input, state) => {
1301
+ if (input.key.ctrl && input.key.name === "u") return processNumberClear(state);
1302
+ switch (input.key.name) {
1303
+ case "backspace": return processNumberBackspace(state);
1304
+ case "k":
1305
+ case "up": return succeed$1(Action.NextFrame({ state: {
1306
+ ...state,
1307
+ value: state.value === "" || state.value === "-" ? `${options.incrementBy}` : `${globalThis.Number.parseInt(state.value) + options.incrementBy}`,
1308
+ error: none()
1309
+ } }));
1310
+ case "j":
1311
+ case "down": return succeed$1(Action.NextFrame({ state: {
1312
+ ...state,
1313
+ value: state.value === "" || state.value === "-" ? `-${options.decrementBy}` : `${globalThis.Number.parseInt(state.value) - options.decrementBy}`,
1314
+ error: none()
1315
+ } }));
1316
+ case "enter":
1317
+ case "return": {
1318
+ const parsed = globalThis.Number.parseInt(state.value);
1319
+ if (globalThis.Number.isNaN(parsed)) return succeed$1(Action.NextFrame({ state: {
1320
+ ...state,
1321
+ error: some("Must provide an integer value")
1322
+ } }));
1323
+ else return match$1(options.validate(parsed), {
1324
+ onFailure: (error) => Action.NextFrame({ state: {
1325
+ ...state,
1326
+ error: some(error)
1327
+ } }),
1328
+ onSuccess: (value) => Action.Submit({ value })
1329
+ });
1330
+ }
1331
+ default: return defaultIntProcessor(getOrElse(input.input, () => ""), state);
1332
+ }
1333
+ };
1334
+ };
1335
+ const handleRenderFloat = (options) => {
1336
+ return (state, action) => {
1337
+ return Action.$match(action, {
1338
+ Beep: () => succeed$1(renderBeep),
1339
+ NextFrame: ({ state }) => renderNumberNextFrame(state, options),
1340
+ Submit: () => renderNumberSubmission(state, options)
1341
+ });
1342
+ };
1343
+ };
1344
+ const handleProcessFloat = (options) => {
1345
+ return (input, state) => {
1346
+ if (input.key.ctrl && input.key.name === "u") return processNumberClear(state);
1347
+ switch (input.key.name) {
1348
+ case "backspace": return processNumberBackspace(state);
1349
+ case "k":
1350
+ case "up": return succeed$1(Action.NextFrame({ state: {
1351
+ ...state,
1352
+ value: state.value === "" || state.value === "-" ? `${options.incrementBy}` : `${globalThis.Number.parseFloat(state.value) + options.incrementBy}`,
1353
+ error: none()
1354
+ } }));
1355
+ case "j":
1356
+ case "down": return succeed$1(Action.NextFrame({ state: {
1357
+ ...state,
1358
+ value: state.value === "" || state.value === "-" ? `-${options.decrementBy}` : `${globalThis.Number.parseFloat(state.value) - options.decrementBy}`,
1359
+ error: none()
1360
+ } }));
1361
+ case "enter":
1362
+ case "return": {
1363
+ const parsed = globalThis.Number.parseFloat(state.value);
1364
+ if (globalThis.Number.isNaN(parsed)) return succeed$1(Action.NextFrame({ state: {
1365
+ ...state,
1366
+ error: some("Must provide a floating point value")
1367
+ } }));
1368
+ else return flatMap$1(sync(() => round(parsed, options.precision)), (rounded) => match$1(options.validate(rounded), {
1369
+ onFailure: (error) => Action.NextFrame({ state: {
1370
+ ...state,
1371
+ error: some(error)
1372
+ } }),
1373
+ onSuccess: (value) => Action.Submit({ value })
1374
+ }));
1375
+ }
1376
+ default: return defaultFloatProcessor(getOrElse(input.input, () => ""), state);
1377
+ }
1378
+ };
1379
+ };
1380
+ const renderSelectOutput = (leadingSymbol, trailingSymbol, options, theme, renderOptions) => options.message === void 0 ? void 0 : renderPrompt("", options.message, leadingSymbol, trailingSymbol, theme, renderOptions);
1381
+ const withSelectHeader = (header, body) => header === void 0 ? body : header + "\n" + body;
1382
+ const renderChoicePrefix = (state, choices, toDisplay, currentIndex, figures, renderOptions) => {
1383
+ const prefix = renderPagingPrefix(figures, currentIndex === toDisplay.startIndex && toDisplay.startIndex > 0, currentIndex === toDisplay.endIndex - 1 && toDisplay.endIndex < choices.length);
1384
+ if (renderOptions?.plain === true) return state === currentIndex ? figures.pointer + prefix : prefix + " ".repeat(figures.pointer.length);
1385
+ if (choices[currentIndex].disabled) {
1386
+ const annotation = combine(bold, figures.mutedColor);
1387
+ return state === currentIndex ? annotateSymbol(figures, figures.pointer, annotation) + prefix : prefix + " ".repeat(figures.pointer.length);
1388
+ }
1389
+ return state === currentIndex ? annotateSymbol(figures, figures.pointer, figures.primaryColor) + prefix : prefix + " ".repeat(figures.pointer.length);
1390
+ };
1391
+ const renderChoiceTitle = (choice, isSelected, theme, renderOptions) => {
1392
+ if (renderOptions?.plain === true) return choice.title;
1393
+ const title = choice.title;
1394
+ if (isSelected) return choice.disabled ? annotate(theme.colors, title, combine(underlined, theme.mutedColor)) : annotate(theme.colors, title, combine(underlined, theme.primaryColor));
1395
+ return choice.disabled ? annotate(theme.colors, title, combine(strikethrough, theme.mutedColor)) : title;
1396
+ };
1397
+ const renderSelectChoices = (state, options, figures, renderOptions) => {
1398
+ const choices = options.choices;
1399
+ const toDisplay = entriesToDisplay(state, choices.length, options.maxPerPage);
1400
+ const documents = [];
1401
+ for (let index = toDisplay.startIndex; index < toDisplay.endIndex; index++) {
1402
+ const choice = choices[index];
1403
+ const isSelected = state === index;
1404
+ const prefix = renderChoicePrefix(state, choices, toDisplay, index, figures, renderOptions);
1405
+ const title = renderChoiceTitle(choice, isSelected, figures, renderOptions);
1406
+ const description = renderChoiceDescription(choice, isSelected, figures, renderOptions);
1407
+ documents.push(prefix + title + " " + description);
1408
+ }
1409
+ return documents.join("\n");
1410
+ };
1411
+ const renderSelectNextFrame = /*#__PURE__*/ fnUntraced(function* (state, options) {
1412
+ const figures = yield* getTheme(options);
1413
+ const choices = renderSelectChoices(state, options, figures);
1414
+ const leadingSymbol = annotateSymbol(figures, figures.prefix, figures.primaryColor);
1415
+ const trailingSymbol = annotateSymbol(figures, figures.pointerSmall, figures.mutedColor);
1416
+ const promptMsg = renderSelectOutput(leadingSymbol, trailingSymbol, options, figures);
1417
+ return cursorHide + withSelectHeader(promptMsg, choices);
1418
+ });
1419
+ const renderSelectSubmission = /*#__PURE__*/ fnUntraced(function* (state, options) {
1420
+ const figures = yield* getTheme(options);
1421
+ const selected = options.choices[state].title;
1422
+ const leadingSymbol = annotateSymbol(figures, figures.tick, figures.successColor);
1423
+ const trailingSymbol = annotateSymbol(figures, figures.ellipsis, figures.mutedColor);
1424
+ return (renderSelectOutput(leadingSymbol, trailingSymbol, options, figures) ?? leadingSymbol) + " " + annotate(figures.colors, selected, figures.submittedColor) + "\n";
1425
+ });
1426
+ const processSelectCursorUp = (state, choices) => {
1427
+ if (state === 0) return succeed$1(Action.NextFrame({ state: choices.length - 1 }));
1428
+ return succeed$1(Action.NextFrame({ state: state - 1 }));
1429
+ };
1430
+ const processSelectCursorDown = (state, choices) => {
1431
+ if (state === choices.length - 1) return succeed$1(Action.NextFrame({ state: 0 }));
1432
+ return succeed$1(Action.NextFrame({ state: state + 1 }));
1433
+ };
1434
+ const processSelectNext = (state, choices) => {
1435
+ return succeed$1(Action.NextFrame({ state: (state + 1) % choices.length }));
1436
+ };
1437
+ const handleSelectRender = (options) => {
1438
+ return (state, action) => {
1439
+ return Action.$match(action, {
1440
+ Beep: () => succeed$1(renderBeep),
1441
+ NextFrame: ({ state }) => renderSelectNextFrame(state, options),
1442
+ Submit: () => renderSelectSubmission(state, options)
1443
+ });
1444
+ };
1445
+ };
1446
+ const handleSelectClear = (options) => fnUntraced(function* (state, _) {
1447
+ const columns = yield* (yield* Terminal).columns;
1448
+ const figures = yield* getTheme(options);
1449
+ const clearPrompt = eraseLine + "\x1B[G";
1450
+ const promptText = renderSelectOutput(figures.prefix, figures.pointerSmall, options, figures, { plain: true });
1451
+ const choicesText = renderSelectChoices(state, options, figures, { plain: true });
1452
+ return eraseText(withSelectHeader(promptText, choicesText), columns) + clearPrompt;
1453
+ });
1454
+ const handleSelectProcess = (options) => {
1455
+ return (input, state) => {
1456
+ switch (input.key.name) {
1457
+ case "k":
1458
+ case "up": return processSelectCursorUp(state, options.choices);
1459
+ case "j":
1460
+ case "down": return processSelectCursorDown(state, options.choices);
1461
+ case "tab": return processSelectNext(state, options.choices);
1462
+ case "enter":
1463
+ case "return": {
1464
+ const selected = options.choices[state];
1465
+ if (selected.disabled) return succeed$1(Action.Beep());
1466
+ return succeed$1(Action.Submit({ value: selected.value }));
1467
+ }
1468
+ default: return succeed$1(Action.Beep());
1469
+ }
1470
+ };
1471
+ };
1472
+ const renderClearScreen = /*#__PURE__*/ fnUntraced(function* (state, options) {
1473
+ const columns = yield* (yield* Terminal).columns;
1474
+ const figures = yield* getTheme(options);
1475
+ const resetCurrentLine = eraseLine + "\x1B[G";
1476
+ const errorText = renderTextError(state, figures.pointerSmall, figures, { plain: true });
1477
+ return clearOutputWithError(renderTextOutput(state, figures.prefix, figures.pointerSmall, options, figures, { plain: true }), columns, errorText) + resetCurrentLine;
1478
+ });
1479
+ const renderTextInput = (nextState, options, theme, submitted, renderOptions) => {
1480
+ const text = nextState.value;
1481
+ if (renderOptions?.plain === true) switch (options.type) {
1482
+ case "hidden": return "";
1483
+ case "password": return theme.passwordMask.repeat(text.length);
1484
+ case "text": return text;
1485
+ }
1486
+ if (text.length === 0) return "";
1487
+ const annotation = isSome(nextState.error) ? theme.errorColor : submitted ? theme.submittedColor : combine(underlined, theme.primaryColor);
1488
+ switch (options.type) {
1489
+ case "hidden": return "";
1490
+ case "password": return annotateSymbol(theme, theme.passwordMask.repeat(text.length), annotation);
1491
+ case "text": return annotate(theme.colors, text, annotation);
1492
+ }
1493
+ };
1494
+ const renderTextError = (nextState, pointer, theme, renderOptions) => {
1495
+ if (isSome(nextState.error)) return match$2(nextState.error.value.split(NEWLINE_REGEXP), {
1496
+ onEmpty: () => "",
1497
+ onNonEmpty: (errorLines) => {
1498
+ if (renderOptions?.plain === true) return separateSymbol(pointer, errorLines.join("\n"));
1499
+ const prefix = annotateSymbol(theme, pointer, theme.errorColor);
1500
+ const lines = map$2(errorLines, (str) => annotateErrorLine(theme, str));
1501
+ return "\x1B[s\n" + separateSymbol(prefix, lines.join("\n")) + "\x1B[u";
1502
+ }
1503
+ });
1504
+ return "";
1505
+ };
1506
+ const renderTextOutput = (nextState, leadingSymbol, trailingSymbol, options, theme, renderOptions, submitted = false) => {
1507
+ const value = renderTextInput(nextState, options, theme, submitted, renderOptions);
1508
+ return renderPrompt(value, options.message, leadingSymbol, trailingSymbol, theme, renderOptions);
1509
+ };
1510
+ const renderTextNextFrame = /*#__PURE__*/ fnUntraced(function* (state, options) {
1511
+ const figures = yield* getTheme(options);
1512
+ const leadingSymbol = annotateSymbol(figures, figures.prefix, figures.primaryColor);
1513
+ const trailingSymbol = annotateSymbol(figures, figures.pointerSmall, figures.mutedColor);
1514
+ const promptMsg = renderTextOutput(state, leadingSymbol, trailingSymbol, options, figures);
1515
+ const errorMsg = renderTextError(state, figures.pointerSmall, figures);
1516
+ const cursorWidth = options.type === "password" ? figures.passwordMask.length : 1;
1517
+ const offset = (state.cursor - state.value.length) * cursorWidth;
1518
+ return promptMsg + errorMsg + cursorMove(offset);
1519
+ });
1520
+ const renderTextSubmission = /*#__PURE__*/ fnUntraced(function* (state, options) {
1521
+ const figures = yield* getTheme(options);
1522
+ const leadingSymbol = annotateSymbol(figures, figures.tick, figures.successColor);
1523
+ const trailingSymbol = annotateSymbol(figures, figures.ellipsis, figures.mutedColor);
1524
+ return renderTextOutput(state, leadingSymbol, trailingSymbol, options, figures, void 0, true) + "\n";
1525
+ });
1526
+ const processTextBackspace = (state) => {
1527
+ if (state.cursor <= 0) return succeed$1(Action.Beep());
1528
+ const beforeCursor = state.value.slice(0, state.cursor - 1);
1529
+ const afterCursor = state.value.slice(state.cursor);
1530
+ const cursor = state.cursor - 1;
1531
+ const value = `${beforeCursor}${afterCursor}`;
1532
+ return succeed$1(Action.NextFrame({ state: {
1533
+ ...state,
1534
+ cursor,
1535
+ value,
1536
+ error: none()
1537
+ } }));
1538
+ };
1539
+ const processTextClear = (state) => succeed$1(Action.NextFrame({ state: {
1540
+ ...state,
1541
+ cursor: 0,
1542
+ value: "",
1543
+ error: none()
1544
+ } }));
1545
+ const processTextCursorLeft = (state) => {
1546
+ if (state.cursor <= 0) return succeed$1(Action.Beep());
1547
+ const cursor = state.cursor - 1;
1548
+ return succeed$1(Action.NextFrame({ state: {
1549
+ ...state,
1550
+ cursor,
1551
+ error: none()
1552
+ } }));
1553
+ };
1554
+ const processTextCursorRight = (state) => {
1555
+ if (state.cursor >= state.value.length) return succeed$1(Action.Beep());
1556
+ const cursor = Math.min(state.cursor + 1, state.value.length);
1557
+ return succeed$1(Action.NextFrame({ state: {
1558
+ ...state,
1559
+ cursor,
1560
+ error: none()
1561
+ } }));
1562
+ };
1563
+ const processTextCursorStart = (state) => succeed$1(Action.NextFrame({ state: {
1564
+ ...state,
1565
+ cursor: 0,
1566
+ error: none()
1567
+ } }));
1568
+ const processTextCursorEnd = (state) => succeed$1(Action.NextFrame({ state: {
1569
+ ...state,
1570
+ cursor: state.value.length,
1571
+ error: none()
1572
+ } }));
1573
+ const processTab = (state, options) => {
1574
+ if (state.value === options.default) return succeed$1(Action.Beep());
1575
+ const value = state.value.length === 0 ? options.default : state.value;
1576
+ return succeed$1(Action.NextFrame({ state: {
1577
+ ...state,
1578
+ value,
1579
+ cursor: value.length,
1580
+ error: none()
1581
+ } }));
1582
+ };
1583
+ const defaultTextProcessor = (input, state) => {
1584
+ const value = `${state.value.slice(0, state.cursor)}${input}${state.value.slice(state.cursor)}`;
1585
+ const cursor = state.cursor + input.length;
1586
+ return succeed$1(Action.NextFrame({ state: {
1587
+ ...state,
1588
+ cursor,
1589
+ value,
1590
+ error: none()
1591
+ } }));
1592
+ };
1593
+ const handleTextRender = (options) => {
1594
+ return (state, action) => {
1595
+ return Action.$match(action, {
1596
+ Beep: () => succeed$1(renderBeep),
1597
+ NextFrame: ({ state }) => renderTextNextFrame(state, options),
1598
+ Submit: () => renderTextSubmission(state, options)
1599
+ });
1600
+ };
1601
+ };
1602
+ const handleTextProcess = (options) => {
1603
+ return (input, state) => {
1604
+ if (input.key.ctrl) switch (input.key.name) {
1605
+ case "u": return processTextClear(state);
1606
+ case "a": return processTextCursorStart(state);
1607
+ case "e": return processTextCursorEnd(state);
1608
+ default: return succeed$1(Action.Beep());
1609
+ }
1610
+ switch (input.key.name) {
1611
+ case "backspace": return processTextBackspace(state);
1612
+ case "left": return processTextCursorLeft(state);
1613
+ case "right": return processTextCursorRight(state);
1614
+ case "home": return processTextCursorStart(state);
1615
+ case "end": return processTextCursorEnd(state);
1616
+ case "enter":
1617
+ case "return": {
1618
+ const value = state.value;
1619
+ return match$1(options.validate(value), {
1620
+ onFailure: (error) => Action.NextFrame({ state: {
1621
+ ...state,
1622
+ value,
1623
+ error: some(error)
1624
+ } }),
1625
+ onSuccess: (value) => Action.Submit({ value })
1626
+ });
1627
+ }
1628
+ case "tab": return processTab(state, options);
1629
+ default: return defaultTextProcessor(getOrElse(input.input, () => ""), state);
1630
+ }
1631
+ };
1632
+ };
1633
+ const handleTextClear = (options) => {
1634
+ return (state, _) => {
1635
+ return renderClearScreen(state, options);
1636
+ };
1637
+ };
1638
+ const basePrompt = (options, type) => {
1639
+ const opts = {
1640
+ default: "",
1641
+ type,
1642
+ validate: succeed$1,
1643
+ ...options
1644
+ };
1645
+ const initialState = {
1646
+ cursor: opts.default.length,
1647
+ value: opts.default,
1648
+ error: none()
1649
+ };
1650
+ return Custom(initialState, {
1651
+ render: handleTextRender(opts),
1652
+ process: handleTextProcess(opts),
1653
+ clear: handleTextClear(opts)
1654
+ });
1655
+ };
1656
+ const handleToggleClear = /*#__PURE__*/ fnUntraced(function* (options) {
1657
+ const columns = yield* (yield* Terminal).columns;
1658
+ const figures = yield* getTheme(options);
1659
+ const clearPrompt = eraseLine + "\x1B[G";
1660
+ const toggleText = options.active + " " + separateSymbol(figures.toggleSeparator, options.inactive);
1661
+ const promptText = renderPrompt(toggleText, options.message, figures.prefix, figures.pointerSmall, figures, { plain: true });
1662
+ return eraseText(promptText, columns) + clearPrompt;
1663
+ });
1664
+ const renderToggle = (value, options, theme, submitted = false) => {
1665
+ const separator = annotateSymbol(theme, theme.toggleSeparator, theme.mutedColor);
1666
+ const selectedAnnotation = combine(underlined, submitted ? theme.submittedColor : theme.primaryColor);
1667
+ const inactive = value ? options.inactive : annotate(theme.colors, options.inactive, selectedAnnotation);
1668
+ return (value ? annotate(theme.colors, options.active, selectedAnnotation) : options.active) + " " + separateSymbol(separator, inactive);
1669
+ };
1670
+ const renderToggleNextFrame = /*#__PURE__*/ fnUntraced(function* (state, options) {
1671
+ const figures = yield* getTheme(options);
1672
+ const leadingSymbol = annotateSymbol(figures, figures.prefix, figures.primaryColor);
1673
+ const trailingSymbol = annotateSymbol(figures, figures.pointerSmall, figures.mutedColor);
1674
+ const toggle = renderToggle(state, options, figures);
1675
+ const promptMsg = renderPrompt(toggle, options.message, leadingSymbol, trailingSymbol, figures);
1676
+ return cursorHide + promptMsg;
1677
+ });
1678
+ const renderToggleSubmission = /*#__PURE__*/ fnUntraced(function* (value, options) {
1679
+ const figures = yield* getTheme(options);
1680
+ const leadingSymbol = annotateSymbol(figures, figures.tick, figures.successColor);
1681
+ const trailingSymbol = annotateSymbol(figures, figures.ellipsis, figures.mutedColor);
1682
+ const toggle = renderToggle(value, options, figures, true);
1683
+ return renderPrompt(toggle, options.message, leadingSymbol, trailingSymbol, figures) + "\n";
1684
+ });
1685
+ const activate = /*#__PURE__*/ succeed$1(/*#__PURE__*/ Action.NextFrame({ state: true }));
1686
+ const deactivate = /*#__PURE__*/ succeed$1(/*#__PURE__*/ Action.NextFrame({ state: false }));
1687
+ const handleToggleRender = (options) => {
1688
+ return (state, action) => {
1689
+ switch (action._tag) {
1690
+ case "Beep": return succeed$1(renderBeep);
1691
+ case "NextFrame": return renderToggleNextFrame(state, options);
1692
+ case "Submit": return renderToggleSubmission(state, options);
1693
+ }
1694
+ };
1695
+ };
1696
+ const handleToggleProcess = (input, state) => {
1697
+ switch (input.key.name) {
1698
+ case "0":
1699
+ case "j":
1700
+ case "delete":
1701
+ case "right":
1702
+ case "down": return deactivate;
1703
+ case "1":
1704
+ case "k":
1705
+ case "left":
1706
+ case "up": return activate;
1707
+ case " ":
1708
+ case "tab": return state ? deactivate : activate;
1709
+ case "enter":
1710
+ case "return": return succeed$1(Action.Submit({ value: state }));
1711
+ default: return succeed$1(Action.Beep());
1712
+ }
1713
+ };
1714
+ const entriesToDisplay = (cursor, total, maxVisible) => {
1715
+ const max = maxVisible === void 0 ? total : maxVisible;
1716
+ let startIndex = Math.min(total - max, cursor - Math.floor(max / 2));
1717
+ if (startIndex < 0) startIndex = 0;
1718
+ const endIndex = Math.min(startIndex + max, total);
1719
+ return {
1720
+ startIndex,
1721
+ endIndex
1722
+ };
1723
+ };
1724
+ // ../../node_modules/.pnpm/effect@4.1.2_patch_hash=0e61176203bb1256381ce1c5b488d7951983ce38ff698647d3f4617383abbf07/node_modules/effect/dist/cli/TerminalCapabilities.js
1725
+ /**
1726
+ * Reference to the terminal capabilities of the current process.
1727
+ *
1728
+ * **When to use**
1729
+ *
1730
+ * Use when application output should share the built-in help, version, and
1731
+ * error output's answer. Provide `layer` to detect through
1732
+ * `ConfigProvider` and `Stdio`, or provide a value to override detection.
1733
+ *
1734
+ * **Details**
1735
+ *
1736
+ * The default is detected from the current process the first time it is
1737
+ * read, so later changes to the environment do not affect it. Without a
1738
+ * `process` global, every flag is `false`.
1739
+ *
1740
+ * @stability unstable
1741
+ * @category services
1742
+ * @since 4.0.0
1743
+ */
1744
+ const TerminalCapabilities = /*#__PURE__*/ Reference("effect/cli/TerminalCapabilities", { defaultValue: () => fromProcess() });
1745
+ const isPresent = (value) => value !== void 0 && value.length > 0;
1746
+ const isForcingColor = (value) => isPresent(value) && value !== "0" && value.toLowerCase() !== "false";
1747
+ const detect = (input) => {
1748
+ if (input.term === "dumb") return {
1749
+ canColor: false,
1750
+ canAnimate: false,
1751
+ canPrompt: false
1752
+ };
1753
+ return {
1754
+ canColor: !isPresent(input.noColor) && (isForcingColor(input.forceColor) || input.stdoutIsTerminal),
1755
+ canAnimate: input.stdoutIsTerminal,
1756
+ canPrompt: input.stdinIsTerminal && input.stdoutIsTerminal
1757
+ };
1758
+ };
1759
+ const fromProcess = () => {
1760
+ const process = globalThis.process;
1761
+ return detect({
1762
+ noColor: process?.env?.NO_COLOR,
1763
+ forceColor: process?.env?.FORCE_COLOR,
1764
+ term: process?.env?.TERM,
1765
+ stdinIsTerminal: process?.stdin?.isTTY === true,
1766
+ stdoutIsTerminal: process?.stdout?.isTTY === true
1767
+ });
1768
+ };
1769
+ export { isQuitError as C, Terminal as S, green as _, Number as a, white as b, String as c, run as d, annotate as f, detectColors as g, cyanBright as h, Int as i, Theme as l, bold as m, Confirm as n, Password as o, blackBright as p, Date as r, Select as s, TerminalCapabilities as t, Toggle as u, magenta as v, make as w, QuitError as x, red as y };