@effected/cli 0.25.0 → 0.26.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 (107) hide show
  1. package/README.md +5 -208
  2. package/bin/effected.js +7 -0
  3. package/commands/root.js +14 -0
  4. package/index.d.ts +19 -3942
  5. package/index.js +3 -26
  6. package/main.d.ts +28 -0
  7. package/main.js +46 -0
  8. package/package.json +17 -52
  9. package/tsdoc-metadata.json +1 -1
  10. package/version.js +11 -0
  11. package/Cancelled.js +0 -43
  12. package/CliAudience.js +0 -177
  13. package/CliColor.js +0 -59
  14. package/CliEnv.js +0 -101
  15. package/CliExit.js +0 -64
  16. package/CliFailure.js +0 -287
  17. package/CliFormat.js +0 -124
  18. package/CliInteractive.js +0 -94
  19. package/CliLinks.js +0 -153
  20. package/CliLog.js +0 -367
  21. package/CliLogger.js +0 -91
  22. package/CliMessage.js +0 -79
  23. package/CliPrompt.js +0 -110
  24. package/CliRuntime.js +0 -254
  25. package/CliTest.js +0 -206
  26. package/CliTheme.js +0 -142
  27. package/ConfigIssueRenderer.js +0 -63
  28. package/Doc.js +0 -548
  29. package/Fmt.js +0 -335
  30. package/GithubAnnotation.js +0 -39
  31. package/Glyphs.js +0 -82
  32. package/NotInteractive.js +0 -41
  33. package/Render.js +0 -280
  34. package/SchemaIssueRenderer.js +0 -47
  35. package/Status.js +0 -165
  36. package/TestTerminal.js +0 -101
  37. package/Token.js +0 -68
  38. package/internal/ExitRequested.js +0 -21
  39. package/internal/HelpRouting.js +0 -35
  40. package/internal/ansi.js +0 -229
  41. package/internal/autoFormat.js +0 -33
  42. package/internal/canPrompt.js +0 -14
  43. package/internal/counts.js +0 -83
  44. package/internal/diagnostics.js +0 -31
  45. package/internal/displayPath.js +0 -46
  46. package/internal/displayWidth.js +0 -42
  47. package/internal/failureTarget.js +0 -195
  48. package/internal/fallbackAnswer.js +0 -17
  49. package/internal/fileSink.js +0 -61
  50. package/internal/format.js +0 -175
  51. package/internal/inspect.js +0 -40
  52. package/internal/isExitCode.js +0 -11
  53. package/internal/layout.js +0 -249
  54. package/internal/linkScheme.js +0 -29
  55. package/internal/linkTarget.js +0 -49
  56. package/internal/logSafety.js +0 -45
  57. package/internal/renderAnsi.js +0 -51
  58. package/internal/renderDoc.js +0 -322
  59. package/internal/renderGithubLog.js +0 -59
  60. package/internal/renderMarkdown.js +0 -367
  61. package/internal/renderPlain.js +0 -49
  62. package/internal/scanAudience.js +0 -105
  63. package/internal/splitFrame.js +0 -55
  64. package/internal/terminalCapabilities.js +0 -23
  65. package/internal/wizardGate.js +0 -17
  66. package/testing.d.ts +0 -246
  67. package/testing.js +0 -4
  68. package/ui/CliUi.js +0 -507
  69. package/ui/CliUiDetached.js +0 -36
  70. package/ui/CliUiLive.js +0 -436
  71. package/ui/CliUiRouteStream.js +0 -72
  72. package/ui/Confirm.js +0 -244
  73. package/ui/DocView.js +0 -76
  74. package/ui/KeyHelp.js +0 -61
  75. package/ui/KeyTable.js +0 -198
  76. package/ui/MultiSelect.js +0 -259
  77. package/ui/Select.js +0 -229
  78. package/ui/Tabs.js +0 -201
  79. package/ui/TextInput.js +0 -289
  80. package/ui/Toggle.js +0 -31
  81. package/ui/UiKey.js +0 -48
  82. package/ui/UiProvider.js +0 -62
  83. package/ui/UiStreams.js +0 -17
  84. package/ui/UiTheme.js +0 -147
  85. package/ui/Viewport.js +0 -203
  86. package/ui/internal/ErrorBoundary.js +0 -29
  87. package/ui/internal/Holder.js +0 -73
  88. package/ui/internal/ScreenContext.js +0 -51
  89. package/ui/internal/UiProviders.js +0 -38
  90. package/ui/internal/ink.js +0 -121
  91. package/ui/internal/inkChalk.js +0 -47
  92. package/ui/internal/inkConsole.js +0 -150
  93. package/ui/internal/lazyView.js +0 -73
  94. package/ui/internal/lineRouter.js +0 -70
  95. package/ui/internal/lineText.js +0 -18
  96. package/ui/internal/mountPermit.js +0 -15
  97. package/ui/internal/processStreams.js +0 -18
  98. package/ui/internal/renderOptions.js +0 -12
  99. package/ui/testing/CliUiTest.js +0 -792
  100. package/ui/testing/fakeStreams.js +0 -104
  101. package/ui/testing/terminalModel.js +0 -67
  102. package/ui-testing-serializer.d.ts +0 -12
  103. package/ui-testing-serializer.js +0 -32
  104. package/ui-testing.d.ts +0 -558
  105. package/ui-testing.js +0 -3
  106. package/ui.d.ts +0 -1990
  107. package/ui.js +0 -17
@@ -1,104 +0,0 @@
1
- import { PassThrough, Writable } from "node:stream";
2
-
3
- // src/ui/testing/fakeStreams.ts
4
- /** The hide-cursor escape `cli-cursor` writes to a TTY stream as it arms the restore. */
5
- const HIDE_CURSOR = `${String.fromCharCode(27)}[?25l`;
6
- /** A cursor-show escape in a listener's source, as `restore-cursor` writes it (`'\u001B[?25h'`) or as the raw byte. */
7
- const CURSOR_SHOW = /\[\?25h/;
8
- /**
9
- * Disarm the real terminal's cursor restore that a fake TTY arms, so no byte of a run on the fakes reaches the
10
- * process's own streams (#983). The fake streams call it as the hide escape is written to them.
11
- *
12
- * @remarks
13
- * Ink's frame writer hides the cursor through `cli-cursor` on its first render, and `cli-cursor` does it only for a
14
- * stream that says it is a TTY, which the fakes do. Hiding it also arms `restore-cursor`, once per loaded copy of it
15
- * (once per test file where the runner isolates modules): a `signal-exit` hook (`alwaysLast`, so on the `afterexit`
16
- * event) that writes the cursor-show escape to the REAL `process.stderr` when the process exits or is signalled,
17
- * whatever stream Ink was given and whether or not stderr is a terminal. Nothing on the fakes hid the real cursor, so
18
- * that restore is only ever a stray byte in the test runner's output: this removes every `afterexit` listener that
19
- * writes a cursor-show escape, right after the copy that armed it wrote its hide escape. The emitter is `signal-exit` 3's process-wide one, the version `restore-cursor` 4
20
- * (the one Ink 8's `cli-cursor` takes) loads; without one there is nothing to disarm.
21
- *
22
- * The one read of `process` in the testing fakes, under the process-streams licence: it touches no stream.
23
- */
24
- const disarmCursorRestore = () => {
25
- const emitter = process.__signal_exit_emitter__;
26
- if (emitter === void 0) return;
27
- for (const listener of emitter.listeners("afterexit")) if (CURSOR_SHOW.test(String(listener))) emitter.removeListener("afterexit", listener);
28
- };
29
- const capture = (columns, rows, both, onWrite) => {
30
- const chunks = [];
31
- const stream = new Writable({ write(chunk, _encoding, callback) {
32
- const text = chunk.toString();
33
- if (text.includes(HIDE_CURSOR)) disarmCursorRestore();
34
- chunks.push(text);
35
- both.push(text);
36
- onWrite?.(text);
37
- callback();
38
- } });
39
- Object.assign(stream, {
40
- isTTY: true,
41
- columns,
42
- rows
43
- });
44
- return {
45
- stream,
46
- text: () => chunks.join("")
47
- };
48
- };
49
- /**
50
- * Make in-memory stdin, stdout and stderr that satisfy Ink's stream contract: TTYs with a size, a recorded
51
- * `setRawMode`, `ref` and `unref`, and captured writes.
52
- *
53
- * @remarks
54
- * The third file licensed to touch Node, testing only: Ink's stream
55
- * contract is Node's, so the fakes are `node:stream` streams rather than a hand-rolled emitter that would have to
56
- * reproduce `readable`, `read()`, `setEncoding` and the write-callback barrier Ink waits on at unmount.
57
- *
58
- * @internal
59
- */
60
- const makeFakeStreams = (options = {}) => {
61
- const columns = options.columns ?? 80;
62
- const rows = options.rows ?? 24;
63
- const rawModes = [];
64
- const stdin = new PassThrough();
65
- Object.assign(stdin, {
66
- isTTY: true,
67
- setRawMode: (mode) => {
68
- rawModes.push(mode);
69
- return stdin;
70
- },
71
- ref: () => stdin,
72
- unref: () => stdin
73
- });
74
- const both = [];
75
- const stdout = capture(columns, rows, both, options.onStdoutWrite);
76
- const stderr = capture(columns, rows, both);
77
- return {
78
- streams: {
79
- stdin,
80
- stdout: stdout.stream,
81
- stderr: stderr.stream
82
- },
83
- rawModes,
84
- stdout: stdout.text,
85
- stderr: stderr.text,
86
- written: () => both.join(""),
87
- input: (data) => {
88
- stdin.write(data);
89
- },
90
- resize: (nextColumns, nextRows) => {
91
- Object.assign(stdout.stream, {
92
- columns: nextColumns,
93
- rows: nextRows
94
- });
95
- Object.assign(stderr.stream, {
96
- columns: nextColumns,
97
- rows: nextRows
98
- });
99
- stdout.stream.emit("resize");
100
- }
101
- };
102
- };
103
-
104
- export { makeFakeStreams };
@@ -1,67 +0,0 @@
1
- // src/ui/testing/terminalModel.ts
2
- const ESC = String.fromCharCode(27);
3
- /**
4
- * A small terminal model for the production render path: what a terminal shows after `written`, as its non-empty
5
- * lines.
6
- *
7
- * @remarks
8
- * It applies printable text, line feeds, the erase and cursor moves Ink's log-update writes (erase line, cursor up,
9
- * down and forward, cursor to a column, cursor to the next line), and the clears of Ink's full-clear frame: `ESC[J`
10
- * erases from the cursor to the end of the screen, `ESC[2J` blanks the visible screen, `ESC[3J` drops the scrollback
11
- * above it, `ESC[H` homes the cursor to the screen's top left. The visible screen is the last
12
- * `rows` lines; with `rows` unknown, the whole buffer counts as the screen, so a clear takes everything. Every other
13
- * escape is ignored. It does not wrap a line wider than the terminal. Shared by `CliUiTest.live`'s transcript and the
14
- * kit's own production-path tests.
15
- *
16
- * @param written - every byte written to the terminal
17
- * @param rows - the terminal's height, which decides how much of the buffer a clear takes as the screen
18
- *
19
- * @internal
20
- */
21
- const screenAfter = (written, rows) => {
22
- const lines = [""];
23
- let row = 0;
24
- let column = 0;
25
- const screenTop = () => rows === void 0 ? 0 : Math.max(0, lines.length - rows);
26
- const sequence = new RegExp(`${ESC}\\[([0-9;?]*)([A-Za-z])|${ESC}\\][^\\u0007]*\\u0007|([\\s\\S])`, "g");
27
- for (const match of written.matchAll(sequence)) {
28
- const [, params, command, character] = match;
29
- if (character !== void 0) {
30
- if (character === "\n") {
31
- row++;
32
- column = 0;
33
- while (lines.length <= row) lines.push("");
34
- } else if (character === "\r") column = 0;
35
- else if (character >= " ") {
36
- const line = lines[row] ?? "";
37
- lines[row] = `${line.slice(0, column).padEnd(column)}${character}${line.slice(column + 1)}`;
38
- column++;
39
- }
40
- } else if (command === "K") lines[row] = "";
41
- else if (command === "A") row = Math.max(0, row - Number(params === "" ? 1 : params));
42
- else if (command === "B" || command === "E") {
43
- row += Number(params === "" ? 1 : params);
44
- if (command === "E") column = 0;
45
- while (lines.length <= row) lines.push("");
46
- } else if (command === "C") column += Number(params === "" ? 1 : params);
47
- else if (command === "G") column = Math.max(0, Number(params === "" ? 1 : params) - 1);
48
- else if (command === "J" && (params === "" || params === "0")) {
49
- lines[row] = (lines[row] ?? "").slice(0, column);
50
- for (let index = row + 1; index < lines.length; index++) lines[index] = "";
51
- } else if (command === "J" && params === "2") for (let index = screenTop(); index < lines.length; index++) lines[index] = "";
52
- else if (command === "J" && params === "3") {
53
- const top = screenTop();
54
- lines.splice(0, top);
55
- row = Math.max(0, row - top);
56
- if (lines.length === 0) lines.push("");
57
- } else if (command === "H") {
58
- const [line, col] = params === "" ? [1, 1] : params.split(";").map((part) => Number(part === "" ? 1 : part));
59
- row = screenTop() + (line ?? 1) - 1;
60
- column = (col ?? 1) - 1;
61
- while (lines.length <= row) lines.push("");
62
- }
63
- }
64
- return lines.map((line) => line.trimEnd()).filter((line) => line !== "");
65
- };
66
-
67
- export { screenAfter };
@@ -1,12 +0,0 @@
1
- /**
2
- * `CliUiTest.serializer`: it claims a string carrying escapes or token markup and prints it as token markup with each
3
- * line's trailing spaces trimmed. See `CliUiTest.serializer` for what it claims.
4
- *
5
- * @public
6
- */
7
- declare const serializer: {
8
- readonly test: (value: unknown) => boolean;
9
- readonly serialize: (value: unknown) => string;
10
- };
11
- export { serializer as default };
12
- //# sourceMappingURL=ui-testing-serializer.d.ts.map
@@ -1,32 +0,0 @@
1
- import { CliUiTest } from "./ui/testing/CliUiTest.js";
2
-
3
- // src/ui-testing-serializer.ts
4
- /**
5
- * `CliUiTest.serializer` as a module's default export, for Vitest's `snapshotSerializers` config.
6
- *
7
- * @remarks
8
- * Vitest's `test.snapshotSerializers` takes module paths whose default export is a serializer, so registering this
9
- * one needs no `expect.addSnapshotSerializer` call and no shim file of your own:
10
- *
11
- * ```ts
12
- * // vitest.config.ts
13
- * import { defineConfig } from "vitest/config"
14
- *
15
- * export default defineConfig({
16
- * test: { snapshotSerializers: ["@effected/cli/ui/testing/serializer"] },
17
- * })
18
- * ```
19
- *
20
- * A separate entrypoint so a program's runtime import graph never loads test code.
21
- *
22
- * @packageDocumentation
23
- */
24
- /**
25
- * `CliUiTest.serializer`: it claims a string carrying escapes or token markup and prints it as token markup with each
26
- * line's trailing spaces trimmed. See `CliUiTest.serializer` for what it claims.
27
- *
28
- * @public
29
- */
30
- const serializer = CliUiTest.serializer;
31
-
32
- export { serializer as default };