@gadgetinc/ggt 0.4.10 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +165 -93
- package/lib/__generated__/graphql.js +66 -1
- package/lib/__generated__/graphql.js.map +1 -1
- package/lib/commands/deploy.js +328 -230
- package/lib/commands/deploy.js.map +1 -1
- package/lib/commands/dev.js +445 -0
- package/lib/commands/dev.js.map +1 -0
- package/lib/commands/list.js +27 -19
- package/lib/commands/list.js.map +1 -1
- package/lib/commands/login.js +15 -11
- package/lib/commands/login.js.map +1 -1
- package/lib/commands/logout.js +5 -5
- package/lib/commands/logout.js.map +1 -1
- package/lib/commands/open.js +200 -0
- package/lib/commands/open.js.map +1 -0
- package/lib/commands/pull.js +128 -0
- package/lib/commands/pull.js.map +1 -0
- package/lib/commands/push.js +126 -0
- package/lib/commands/push.js.map +1 -0
- package/lib/commands/root.js +46 -28
- package/lib/commands/root.js.map +1 -1
- package/lib/commands/status.js +61 -0
- package/lib/commands/status.js.map +1 -0
- package/lib/commands/version.js +6 -6
- package/lib/commands/version.js.map +1 -1
- package/lib/commands/whoami.js +6 -6
- package/lib/commands/whoami.js.map +1 -1
- package/lib/ggt.js +33 -8
- package/lib/ggt.js.map +1 -1
- package/lib/main.js +5 -0
- package/lib/main.js.map +1 -0
- package/lib/services/app/api/api.js +191 -0
- package/lib/services/app/api/api.js.map +1 -0
- package/lib/services/app/api/operation.js +12 -0
- package/lib/services/app/api/operation.js.map +1 -0
- package/lib/services/app/app.js +44 -10
- package/lib/services/app/app.js.map +1 -1
- package/lib/services/app/{edit/client.js → client.js} +29 -19
- package/lib/services/app/client.js.map +1 -0
- package/lib/services/app/edit/edit.js +67 -31
- package/lib/services/app/edit/edit.js.map +1 -1
- package/lib/services/app/edit/operation.js +4 -3
- package/lib/services/app/edit/operation.js.map +1 -1
- package/lib/services/app/{edit/error.js → error.js} +6 -6
- package/lib/services/app/error.js.map +1 -0
- package/lib/services/command/arg.js +4 -4
- package/lib/services/command/arg.js.map +1 -1
- package/lib/services/command/command.js +9 -7
- package/lib/services/command/command.js.map +1 -1
- package/lib/services/command/context.js +82 -20
- package/lib/services/command/context.js.map +1 -1
- package/lib/services/config/config.js +4 -7
- package/lib/services/config/config.js.map +1 -1
- package/lib/services/config/env.js +1 -1
- package/lib/services/config/env.js.map +1 -1
- package/lib/services/filesync/changes.js +76 -37
- package/lib/services/filesync/changes.js.map +1 -1
- package/lib/services/filesync/conflicts.js +10 -9
- package/lib/services/filesync/conflicts.js.map +1 -1
- package/lib/services/filesync/directory.js +16 -1
- package/lib/services/filesync/directory.js.map +1 -1
- package/lib/services/filesync/error.js +96 -27
- package/lib/services/filesync/error.js.map +1 -1
- package/lib/services/filesync/filesync.js +448 -490
- package/lib/services/filesync/filesync.js.map +1 -1
- package/lib/services/filesync/hashes.js +8 -5
- package/lib/services/filesync/hashes.js.map +1 -1
- package/lib/services/filesync/strategy.js +59 -0
- package/lib/services/filesync/strategy.js.map +1 -0
- package/lib/services/filesync/sync-json.js +475 -0
- package/lib/services/filesync/sync-json.js.map +1 -0
- package/lib/services/http/auth.js +30 -1
- package/lib/services/http/auth.js.map +1 -1
- package/lib/services/http/http.js +5 -0
- package/lib/services/http/http.js.map +1 -1
- package/lib/services/output/confirm.js +149 -0
- package/lib/services/output/confirm.js.map +1 -0
- package/lib/services/output/footer.js +22 -0
- package/lib/services/output/footer.js.map +1 -0
- package/lib/services/output/log/format/pretty.js +2 -1
- package/lib/services/output/log/format/pretty.js.map +1 -1
- package/lib/services/output/log/logger.js +13 -5
- package/lib/services/output/log/logger.js.map +1 -1
- package/lib/services/output/log/structured.js +2 -2
- package/lib/services/output/log/structured.js.map +1 -1
- package/lib/services/output/output.js +197 -0
- package/lib/services/output/output.js.map +1 -0
- package/lib/services/output/print.js +31 -0
- package/lib/services/output/print.js.map +1 -0
- package/lib/services/output/problems.js +84 -0
- package/lib/services/output/problems.js.map +1 -0
- package/lib/services/output/prompt.js +173 -40
- package/lib/services/output/prompt.js.map +1 -1
- package/lib/services/output/report.js +63 -19
- package/lib/services/output/report.js.map +1 -1
- package/lib/services/output/select.js +198 -0
- package/lib/services/output/select.js.map +1 -0
- package/lib/services/output/spinner.js +141 -0
- package/lib/services/output/spinner.js.map +1 -0
- package/lib/services/output/sprint.js +38 -15
- package/lib/services/output/sprint.js.map +1 -1
- package/lib/services/output/symbols.js +23 -0
- package/lib/services/output/symbols.js.map +1 -0
- package/lib/services/output/table.js +98 -0
- package/lib/services/output/table.js.map +1 -0
- package/lib/services/output/timestamp.js +12 -0
- package/lib/services/output/timestamp.js.map +1 -0
- package/lib/services/output/update.js +29 -9
- package/lib/services/output/update.js.map +1 -1
- package/lib/services/user/session.js +4 -0
- package/lib/services/user/session.js.map +1 -1
- package/lib/services/user/user.js +15 -10
- package/lib/services/user/user.js.map +1 -1
- package/lib/services/util/assert.js +11 -0
- package/lib/services/util/assert.js.map +1 -0
- package/lib/services/util/boolean.js +2 -2
- package/lib/services/util/boolean.js.map +1 -1
- package/lib/services/util/function.js +45 -7
- package/lib/services/util/function.js.map +1 -1
- package/lib/services/util/is.js +23 -2
- package/lib/services/util/is.js.map +1 -1
- package/lib/services/util/json.js +16 -13
- package/lib/services/util/json.js.map +1 -1
- package/lib/services/util/object.js +2 -2
- package/lib/services/util/object.js.map +1 -1
- package/lib/services/util/promise.js +5 -2
- package/lib/services/util/promise.js.map +1 -1
- package/lib/services/util/types.js.map +1 -1
- package/npm-shrinkwrap.json +3415 -2973
- package/package.json +47 -40
- package/bin/dev.cmd +0 -3
- package/bin/dev.js +0 -14
- package/bin/run.cmd +0 -3
- package/bin/run.js +0 -5
- package/lib/commands/sync.js +0 -284
- package/lib/commands/sync.js.map +0 -1
- package/lib/services/app/edit/client.js.map +0 -1
- package/lib/services/app/edit/error.js.map +0 -1
- package/lib/services/output/log/printer.js +0 -120
- package/lib/services/output/log/printer.js.map +0 -1
- package/lib/services/output/stream.js +0 -54
- package/lib/services/output/stream.js.map +0 -1
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { _ as _define_property } from "@swc/helpers/_/_define_property";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import indentString from "indent-string";
|
|
4
|
+
import assert from "node:assert";
|
|
5
|
+
import process from "node:process";
|
|
6
|
+
import { isString } from "../util/is.js";
|
|
7
|
+
import { defaults } from "../util/object.js";
|
|
8
|
+
import { output } from "./output.js";
|
|
9
|
+
import { println } from "./print.js";
|
|
10
|
+
import { entriesToDisplay, Prompt } from "./prompt.js";
|
|
11
|
+
import { sprint, sprintln } from "./sprint.js";
|
|
12
|
+
import { symbol } from "./symbols.js";
|
|
13
|
+
// TODO: i regret this api... don't make it the same as println... just make it take ctx and options
|
|
14
|
+
export const select = (options)=>{
|
|
15
|
+
options = defaults(options, {
|
|
16
|
+
ensureEmptyLineAbove: true
|
|
17
|
+
});
|
|
18
|
+
return (template, ...values)=>{
|
|
19
|
+
let text = template;
|
|
20
|
+
if (!isString(text)) {
|
|
21
|
+
text = sprint(template, ...values);
|
|
22
|
+
}
|
|
23
|
+
if (!output.isInteractive) {
|
|
24
|
+
// TODO: log an error here
|
|
25
|
+
println(options)(text);
|
|
26
|
+
println({
|
|
27
|
+
ensureEmptyLineAbove: true
|
|
28
|
+
})`
|
|
29
|
+
Aborting because ggt is not running in an interactive terminal.
|
|
30
|
+
`;
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
return new Promise((resolve)=>{
|
|
34
|
+
const sel = new Select(text, {
|
|
35
|
+
formatChoice: (choice)=>choice,
|
|
36
|
+
formatSelection: (choice)=>choice,
|
|
37
|
+
...options
|
|
38
|
+
});
|
|
39
|
+
sel.on("submit", resolve);
|
|
40
|
+
sel.on("exit", ()=>process.exit(0));
|
|
41
|
+
sel.on("abort", ()=>process.exit(0));
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Inspired by `prompts`:
|
|
47
|
+
* https://github.com/terkelg/prompts/blob/e0519913ec4fcc6746bb3d97d8cd0960c3f3ffde/lib/elements/select.js
|
|
48
|
+
*
|
|
49
|
+
* MIT License
|
|
50
|
+
*
|
|
51
|
+
* Copyright (c) 2018 Terkel Gjervig Nielsen
|
|
52
|
+
*
|
|
53
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
54
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
55
|
+
* in the Software without restriction, including without limitation the rights
|
|
56
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
57
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
58
|
+
* furnished to do so, subject to the following conditions:
|
|
59
|
+
*
|
|
60
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
61
|
+
* copies or substantial portions of the Software.
|
|
62
|
+
*
|
|
63
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
64
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
65
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
66
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
67
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
68
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
69
|
+
* SOFTWARE.
|
|
70
|
+
*/ // TODO: implement autocomplete https://github.com/terkelg/prompts/blob/e0519913ec4fcc6746bb3d97d8cd0960c3f3ffde/lib/elements/autocomplete.js
|
|
71
|
+
class Select extends Prompt {
|
|
72
|
+
get selection() {
|
|
73
|
+
const choice = this.options.choices[this.cursor];
|
|
74
|
+
assert(choice, `choices[${this.cursor}] is not defined`);
|
|
75
|
+
return choice;
|
|
76
|
+
}
|
|
77
|
+
moveCursor(n) {
|
|
78
|
+
this.cursor = n;
|
|
79
|
+
this.fire();
|
|
80
|
+
}
|
|
81
|
+
reset() {
|
|
82
|
+
this.moveCursor(0);
|
|
83
|
+
this.fire();
|
|
84
|
+
this.render();
|
|
85
|
+
}
|
|
86
|
+
exit() {
|
|
87
|
+
this.abort();
|
|
88
|
+
}
|
|
89
|
+
abort() {
|
|
90
|
+
this.done = this.aborted = true;
|
|
91
|
+
this.fire();
|
|
92
|
+
this.render("Cancel (Ctrl+C)");
|
|
93
|
+
this.close();
|
|
94
|
+
}
|
|
95
|
+
submit() {
|
|
96
|
+
this.done = true;
|
|
97
|
+
this.aborted = false;
|
|
98
|
+
this.value = this.selection;
|
|
99
|
+
this.fire();
|
|
100
|
+
this.render();
|
|
101
|
+
this.close();
|
|
102
|
+
}
|
|
103
|
+
first() {
|
|
104
|
+
this.moveCursor(0);
|
|
105
|
+
this.render();
|
|
106
|
+
}
|
|
107
|
+
last() {
|
|
108
|
+
this.moveCursor(this.options.choices.length - 1);
|
|
109
|
+
this.render();
|
|
110
|
+
}
|
|
111
|
+
up() {
|
|
112
|
+
if (this.cursor === 0) {
|
|
113
|
+
this.moveCursor(this.options.choices.length - 1);
|
|
114
|
+
} else {
|
|
115
|
+
this.moveCursor(this.cursor - 1);
|
|
116
|
+
}
|
|
117
|
+
this.render();
|
|
118
|
+
}
|
|
119
|
+
down() {
|
|
120
|
+
if (this.cursor === this.options.choices.length - 1) {
|
|
121
|
+
this.moveCursor(0);
|
|
122
|
+
} else {
|
|
123
|
+
this.moveCursor(this.cursor + 1);
|
|
124
|
+
}
|
|
125
|
+
this.render();
|
|
126
|
+
}
|
|
127
|
+
next() {
|
|
128
|
+
this.moveCursor((this.cursor + 1) % this.options.choices.length);
|
|
129
|
+
this.render();
|
|
130
|
+
}
|
|
131
|
+
_(char, _key) {
|
|
132
|
+
if (char === " ") {
|
|
133
|
+
this.submit();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
render(selection) {
|
|
138
|
+
if (this.closed) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
super.render();
|
|
142
|
+
let question = this.text;
|
|
143
|
+
if (this.done) {
|
|
144
|
+
output.persistPrompt(sprintln`
|
|
145
|
+
${question.trimEnd()} ${this.options.formatChoice(selection ?? this.selection)}
|
|
146
|
+
`);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
question += ` ${chalk.gray("Use arrow keys to move")}\n\n`;
|
|
150
|
+
let choices = "";
|
|
151
|
+
const { startIndex, endIndex } = entriesToDisplay(this.cursor, this.options.choices.length, this.optionsPerPage);
|
|
152
|
+
for(let index = startIndex; index < endIndex; index++){
|
|
153
|
+
// determine whether to display "more choices" indicators
|
|
154
|
+
let prefix;
|
|
155
|
+
if (this.cursor === index) {
|
|
156
|
+
prefix = `${symbol.arrowRight} `;
|
|
157
|
+
} else if (index === startIndex && startIndex > 0) {
|
|
158
|
+
prefix = `${symbol.arrowUp} `;
|
|
159
|
+
} else if (index === endIndex - 1 && endIndex < this.options.choices.length) {
|
|
160
|
+
prefix = `${symbol.arrowDown} `;
|
|
161
|
+
} else {
|
|
162
|
+
prefix = " ";
|
|
163
|
+
}
|
|
164
|
+
const choice_ = this.options.choices[index];
|
|
165
|
+
assert(choice_, `choices[${index}] is not defined`);
|
|
166
|
+
let choice = this.options.formatChoice(choice_);
|
|
167
|
+
if (this.cursor === index) {
|
|
168
|
+
choice = chalk.blue.underline(choice);
|
|
169
|
+
}
|
|
170
|
+
choices += `${prefix}${choice}\n`;
|
|
171
|
+
}
|
|
172
|
+
if (this.options.indent) {
|
|
173
|
+
choices = indentString(choices, this.options.indent);
|
|
174
|
+
}
|
|
175
|
+
output.updatePrompt(question + choices);
|
|
176
|
+
}
|
|
177
|
+
constructor(text, options){
|
|
178
|
+
super();
|
|
179
|
+
_define_property(this, "text", void 0);
|
|
180
|
+
_define_property(this, "cursor", void 0);
|
|
181
|
+
_define_property(this, "optionsPerPage", void 0);
|
|
182
|
+
_define_property(this, "options", void 0);
|
|
183
|
+
this.text = text;
|
|
184
|
+
this.cursor = 0;
|
|
185
|
+
this.optionsPerPage = 10;
|
|
186
|
+
this.options = defaults(options, {
|
|
187
|
+
formatChoice: (choice)=>choice,
|
|
188
|
+
formatSelection: (choice)=>choice,
|
|
189
|
+
...options
|
|
190
|
+
});
|
|
191
|
+
if (this.options.ensureEmptyLineAbove) {
|
|
192
|
+
this.text = "\n" + this.text;
|
|
193
|
+
}
|
|
194
|
+
this.render();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
//# sourceMappingURL=select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/output/select.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport indentString from \"indent-string\";\nimport assert from \"node:assert\";\nimport process from \"node:process\";\nimport { isString } from \"../util/is.js\";\nimport { defaults } from \"../util/object.js\";\nimport { output } from \"./output.js\";\nimport { println } from \"./print.js\";\nimport { entriesToDisplay, Prompt, type StdinKey } from \"./prompt.js\";\nimport { sprint, sprintln, type SprintOptions } from \"./sprint.js\";\nimport { symbol } from \"./symbols.js\";\n\nexport type SelectOptions<Choice extends string> = SprintOptions & {\n choices: Choice[];\n formatChoice?: (choice: Choice) => string;\n formatSelection?: (choice: Choice) => string;\n};\n\nexport type select<Choice extends string> = (options: SelectOptions<Choice>) => selectWithChoices<Choice>;\n\nexport type selectWithChoices<Choice extends string> = {\n (str: string): Promise<Choice>;\n (template: TemplateStringsArray, ...values: unknown[]): Promise<Choice>;\n};\n\n// TODO: i regret this api... don't make it the same as println... just make it take ctx and options\nexport const select = <Choice extends string>(options: SelectOptions<Choice>): selectWithChoices<Choice> => {\n options = defaults(options, {\n ensureEmptyLineAbove: true,\n });\n\n return ((template: string | TemplateStringsArray, ...values: unknown[]): Promise<Choice> => {\n let text = template as string;\n if (!isString(text)) {\n text = sprint(template as TemplateStringsArray, ...values);\n }\n\n if (!output.isInteractive) {\n // TODO: log an error here\n println(options)(text);\n println({ ensureEmptyLineAbove: true })`\n Aborting because ggt is not running in an interactive terminal.\n `;\n process.exit(1);\n }\n\n return new Promise((resolve) => {\n const sel = new Select(text, {\n formatChoice: (choice) => choice,\n formatSelection: (choice) => choice,\n ...options,\n });\n sel.on(\"submit\", resolve);\n sel.on(\"exit\", () => process.exit(0));\n sel.on(\"abort\", () => process.exit(0));\n });\n }) as selectWithChoices<Choice>;\n};\n\n/**\n * Inspired by `prompts`:\n * https://github.com/terkelg/prompts/blob/e0519913ec4fcc6746bb3d97d8cd0960c3f3ffde/lib/elements/select.js\n *\n * MIT License\n *\n * Copyright (c) 2018 Terkel Gjervig Nielsen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n// TODO: implement autocomplete https://github.com/terkelg/prompts/blob/e0519913ec4fcc6746bb3d97d8cd0960c3f3ffde/lib/elements/autocomplete.js\nclass Select<Choice extends string> extends Prompt {\n cursor = 0;\n optionsPerPage = 10;\n options;\n\n constructor(\n readonly text: string,\n options: SelectOptions<Choice>,\n ) {\n super();\n\n this.options = defaults(options, {\n formatChoice: (choice) => choice,\n formatSelection: (choice) => choice,\n ...options,\n });\n\n if (this.options.ensureEmptyLineAbove) {\n this.text = \"\\n\" + this.text;\n }\n\n this.render();\n }\n\n get selection(): Choice {\n const choice = this.options.choices[this.cursor];\n assert(choice, `choices[${this.cursor}] is not defined`);\n return choice;\n }\n\n moveCursor(n: number): void {\n this.cursor = n;\n this.fire();\n }\n\n reset(): void {\n this.moveCursor(0);\n this.fire();\n this.render();\n }\n\n exit(): void {\n this.abort();\n }\n\n abort(): void {\n this.done = this.aborted = true;\n this.fire();\n this.render(\"Cancel (Ctrl+C)\" as Choice);\n this.close();\n }\n\n submit(): void {\n this.done = true;\n this.aborted = false;\n this.value = this.selection;\n this.fire();\n this.render();\n this.close();\n }\n\n first(): void {\n this.moveCursor(0);\n this.render();\n }\n\n last(): void {\n this.moveCursor(this.options.choices.length - 1);\n this.render();\n }\n\n up(): void {\n if (this.cursor === 0) {\n this.moveCursor(this.options.choices.length - 1);\n } else {\n this.moveCursor(this.cursor - 1);\n }\n this.render();\n }\n\n down(): void {\n if (this.cursor === this.options.choices.length - 1) {\n this.moveCursor(0);\n } else {\n this.moveCursor(this.cursor + 1);\n }\n this.render();\n }\n\n next(): void {\n this.moveCursor((this.cursor + 1) % this.options.choices.length);\n this.render();\n }\n\n override _(char: string, _key: StdinKey): void {\n if (char === \" \") {\n this.submit();\n return;\n }\n }\n\n override render(selection?: Choice): void {\n if (this.closed) {\n return;\n }\n\n super.render();\n\n let question = this.text;\n if (this.done) {\n output.persistPrompt(sprintln`\n ${question.trimEnd()} ${this.options.formatChoice(selection ?? this.selection)}\n `);\n return;\n }\n\n question += ` ${chalk.gray(\"Use arrow keys to move\")}\\n\\n`;\n\n let choices = \"\";\n const { startIndex, endIndex } = entriesToDisplay(this.cursor, this.options.choices.length, this.optionsPerPage);\n for (let index = startIndex; index < endIndex; index++) {\n // determine whether to display \"more choices\" indicators\n let prefix: string;\n if (this.cursor === index) {\n prefix = `${symbol.arrowRight} `;\n } else if (index === startIndex && startIndex > 0) {\n prefix = `${symbol.arrowUp} `;\n } else if (index === endIndex - 1 && endIndex < this.options.choices.length) {\n prefix = `${symbol.arrowDown} `;\n } else {\n prefix = \" \";\n }\n\n const choice_ = this.options.choices[index];\n assert(choice_, `choices[${index}] is not defined`);\n\n let choice = this.options.formatChoice(choice_);\n if (this.cursor === index) {\n choice = chalk.blue.underline(choice);\n }\n\n choices += `${prefix}${choice}\\n`;\n }\n\n if (this.options.indent) {\n choices = indentString(choices, this.options.indent);\n }\n\n output.updatePrompt(question + choices);\n }\n}\n"],"names":["chalk","indentString","assert","process","isString","defaults","output","println","entriesToDisplay","Prompt","sprint","sprintln","symbol","select","options","ensureEmptyLineAbove","template","values","text","isInteractive","exit","Promise","resolve","sel","Select","formatChoice","choice","formatSelection","on","selection","choices","cursor","moveCursor","n","fire","reset","render","abort","done","aborted","close","submit","value","first","last","length","up","down","next","_","char","_key","closed","question","persistPrompt","trimEnd","gray","startIndex","endIndex","optionsPerPage","index","prefix","arrowRight","arrowUp","arrowDown","choice_","blue","underline","indent","updatePrompt","constructor"],"mappings":"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"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import chalkTemplate from "chalk-template";
|
|
3
|
+
import cliSpinners from "cli-spinners";
|
|
4
|
+
import assert from "node:assert";
|
|
5
|
+
import os from "node:os";
|
|
6
|
+
import { dedent } from "ts-dedent";
|
|
7
|
+
import { isString } from "../util/is.js";
|
|
8
|
+
import { output } from "./output.js";
|
|
9
|
+
import { isSprintOptions, sprintln } from "./sprint.js";
|
|
10
|
+
import { symbol } from "./symbols.js";
|
|
11
|
+
export let activeSpinner;
|
|
12
|
+
export const createSpin = (options)=>{
|
|
13
|
+
return (optionsOrString, ...values)=>{
|
|
14
|
+
if (isSprintOptions(optionsOrString)) {
|
|
15
|
+
return createSpin({
|
|
16
|
+
...options,
|
|
17
|
+
...optionsOrString
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
assert(!activeSpinner, "a spinner is already active");
|
|
21
|
+
let str = optionsOrString;
|
|
22
|
+
if (!isString(str)) {
|
|
23
|
+
str = sprintln(str, ...values);
|
|
24
|
+
}
|
|
25
|
+
const { ensureNewLine = true, ensureEmptyLineAbove = false, kind = "dots", color = "white", successSymbol = chalk.green(symbol.tick), failSymbol = chalk.red(symbol.cross) } = options;
|
|
26
|
+
let frameIndex = 0;
|
|
27
|
+
const frames = cliSpinners[kind].frames;
|
|
28
|
+
const interval = cliSpinners[kind].interval;
|
|
29
|
+
let firstRender = true;
|
|
30
|
+
const render = ({ symbol, message, final: finalRender = false })=>{
|
|
31
|
+
// strip leading and trailing newlines so we can add them back in
|
|
32
|
+
// the right place
|
|
33
|
+
while(message.startsWith("\n")){
|
|
34
|
+
message = message.slice(1);
|
|
35
|
+
}
|
|
36
|
+
while(message.endsWith("\n")){
|
|
37
|
+
message = message.slice(0, -1);
|
|
38
|
+
}
|
|
39
|
+
// if no symbol is provided, use the next frame
|
|
40
|
+
if (symbol === undefined) {
|
|
41
|
+
frameIndex = ++frameIndex % frames.length;
|
|
42
|
+
symbol = chalk[color](frames[frameIndex]);
|
|
43
|
+
}
|
|
44
|
+
if (message) {
|
|
45
|
+
// we have a message to display
|
|
46
|
+
if (symbol) {
|
|
47
|
+
// add the spinner symbol to the first line of the message
|
|
48
|
+
const lines = message.split(/\r?\n/);
|
|
49
|
+
lines[0] = `${symbol} ${lines[0]}`;
|
|
50
|
+
message = lines.join(os.EOL);
|
|
51
|
+
}
|
|
52
|
+
if (ensureEmptyLineAbove && !message.startsWith("\n")) {
|
|
53
|
+
// add an empty line before the symbol
|
|
54
|
+
message = "\n" + message;
|
|
55
|
+
}
|
|
56
|
+
if (ensureNewLine && !message.endsWith("\n")) {
|
|
57
|
+
// add a newline after the message
|
|
58
|
+
message += "\n";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (finalRender) {
|
|
62
|
+
if (!output.isInteractive && ensureEmptyLineAbove) {
|
|
63
|
+
// we're in a non-interactive terminal, therefor
|
|
64
|
+
// ensureEmptyLineAbove only applies to the first render.
|
|
65
|
+
// strip it so that the final render of the spinner is right
|
|
66
|
+
// below the first render of the spinner
|
|
67
|
+
message = message.slice(1);
|
|
68
|
+
}
|
|
69
|
+
// this is the final render, so persist the spinner
|
|
70
|
+
output.persistSpinner(message);
|
|
71
|
+
activeSpinner = undefined;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// this is not the final render, so we need to update the spinner
|
|
75
|
+
if (output.isInteractive) {
|
|
76
|
+
// we're in an interactive terminal, so update the spinner
|
|
77
|
+
output.updateSpinner(message);
|
|
78
|
+
} else if (firstRender) {
|
|
79
|
+
// we're not in an interactive terminal, and this is the first
|
|
80
|
+
// render, so just write the first render to stdout
|
|
81
|
+
output.writeStdout(message);
|
|
82
|
+
firstRender = false;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
// render the first frame
|
|
86
|
+
render({
|
|
87
|
+
message: str
|
|
88
|
+
});
|
|
89
|
+
let spinnerInterval;
|
|
90
|
+
if (output.isInteractive) {
|
|
91
|
+
// we are in an interactive terminal, so keep rendering the spinner
|
|
92
|
+
spinnerInterval = setInterval(()=>render({
|
|
93
|
+
message: str
|
|
94
|
+
}), interval);
|
|
95
|
+
}
|
|
96
|
+
// setup the last render
|
|
97
|
+
const finalRender = (renderOptions)=>{
|
|
98
|
+
render({
|
|
99
|
+
...renderOptions,
|
|
100
|
+
final: true
|
|
101
|
+
});
|
|
102
|
+
clearInterval(spinnerInterval);
|
|
103
|
+
};
|
|
104
|
+
activeSpinner = {
|
|
105
|
+
text: str,
|
|
106
|
+
clear () {
|
|
107
|
+
this.text = "";
|
|
108
|
+
finalRender({
|
|
109
|
+
symbol: "",
|
|
110
|
+
message: ""
|
|
111
|
+
});
|
|
112
|
+
},
|
|
113
|
+
succeed (finalStr, ...values) {
|
|
114
|
+
finalStr ??= str;
|
|
115
|
+
if (!isString(finalStr)) {
|
|
116
|
+
finalStr = dedent(chalkTemplate(finalStr, ...values));
|
|
117
|
+
}
|
|
118
|
+
this.text = finalStr;
|
|
119
|
+
finalRender({
|
|
120
|
+
message: finalStr,
|
|
121
|
+
symbol: successSymbol
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
fail (finalStr, ...values) {
|
|
125
|
+
finalStr ??= str;
|
|
126
|
+
if (!isString(finalStr)) {
|
|
127
|
+
finalStr = dedent(chalkTemplate(finalStr, ...values));
|
|
128
|
+
}
|
|
129
|
+
this.text = finalStr;
|
|
130
|
+
finalRender({
|
|
131
|
+
message: finalStr,
|
|
132
|
+
symbol: failSymbol
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
return activeSpinner;
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
export const spin = createSpin({});
|
|
140
|
+
|
|
141
|
+
//# sourceMappingURL=spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/output/spinner.ts"],"sourcesContent":["import type { ColorName } from \"chalk\";\nimport chalk from \"chalk\";\nimport chalkTemplate from \"chalk-template\";\nimport type { SpinnerName } from \"cli-spinners\";\nimport cliSpinners from \"cli-spinners\";\nimport assert from \"node:assert\";\nimport os from \"node:os\";\nimport { dedent } from \"ts-dedent\";\nimport { isString } from \"../util/is.js\";\nimport { output } from \"./output.js\";\nimport { isSprintOptions, sprintln } from \"./sprint.js\";\nimport { symbol } from \"./symbols.js\";\n\nexport type SpinnerOptions = {\n /**\n * Whether to ensure a new line is after the text.\n *\n * @default false\n */\n ensureNewLine?: boolean;\n\n /**\n * Whether to ensure an empty line is above the spinner.\n *\n * @default false\n */\n ensureEmptyLineAbove?: boolean;\n\n /**\n * The name of the spinner to use.\n *\n * @default \"dots\"\n * @see https://github.com/sindresorhus/cli-spinners\n */\n kind?: SpinnerName;\n\n /**\n * The color of the spinner.\n *\n * @default \"cyan\"\n * @see https://github.com/chalk/chalk\n */\n color?: ColorName;\n\n /**\n * The symbol to display when the spinner succeeds.\n *\n * @default \"✔\"\n */\n successSymbol?: string;\n\n /**\n * The symbol to display when the spinner fails.\n *\n * @default \"✖\"\n */\n failSymbol?: string;\n};\n\nexport type spin = {\n (str: string): spinner;\n (template: TemplateStringsArray, ...values: unknown[]): spinner;\n (options: Omit<SpinnerOptions, \"str\">): spin;\n};\n\nexport type spinner = {\n text: string;\n clear: () => void;\n succeed: {\n (str?: string): void;\n (template: TemplateStringsArray, ...values: unknown[]): void;\n };\n fail: {\n (str?: string): void;\n (template: TemplateStringsArray, ...values: unknown[]): void;\n };\n};\n\nexport let activeSpinner: spinner | undefined;\n\nexport const createSpin = (options: SpinnerOptions): spin => {\n return ((optionsOrString: SpinnerOptions | string | TemplateStringsArray, ...values: unknown[]): spin | spinner => {\n if (isSprintOptions(optionsOrString)) {\n return createSpin({ ...options, ...optionsOrString });\n }\n\n assert(!activeSpinner, \"a spinner is already active\");\n\n let str = optionsOrString as string;\n if (!isString(str)) {\n str = sprintln(str, ...values);\n }\n\n const {\n ensureNewLine = true,\n ensureEmptyLineAbove = false,\n kind = \"dots\",\n color = \"white\",\n successSymbol = chalk.green(symbol.tick),\n failSymbol = chalk.red(symbol.cross),\n } = options;\n\n let frameIndex = 0;\n const frames = cliSpinners[kind].frames;\n const interval = cliSpinners[kind].interval;\n\n type RenderOptions = { symbol?: string; message: string; final?: boolean };\n let firstRender = true;\n\n const render = ({ symbol, message, final: finalRender = false }: RenderOptions): void => {\n // strip leading and trailing newlines so we can add them back in\n // the right place\n while (message.startsWith(\"\\n\")) {\n message = message.slice(1);\n }\n\n while (message.endsWith(\"\\n\")) {\n message = message.slice(0, -1);\n }\n\n // if no symbol is provided, use the next frame\n if (symbol === undefined) {\n frameIndex = ++frameIndex % frames.length;\n symbol = chalk[color](frames[frameIndex]);\n }\n\n if (message) {\n // we have a message to display\n if (symbol) {\n // add the spinner symbol to the first line of the message\n const lines = message.split(/\\r?\\n/);\n lines[0] = `${symbol} ${lines[0]}`;\n message = lines.join(os.EOL);\n }\n\n if (ensureEmptyLineAbove && !message.startsWith(\"\\n\")) {\n // add an empty line before the symbol\n message = \"\\n\" + message;\n }\n\n if (ensureNewLine && !message.endsWith(\"\\n\")) {\n // add a newline after the message\n message += \"\\n\";\n }\n }\n\n if (finalRender) {\n if (!output.isInteractive && ensureEmptyLineAbove) {\n // we're in a non-interactive terminal, therefor\n // ensureEmptyLineAbove only applies to the first render.\n // strip it so that the final render of the spinner is right\n // below the first render of the spinner\n message = message.slice(1);\n }\n\n // this is the final render, so persist the spinner\n output.persistSpinner(message);\n activeSpinner = undefined;\n return;\n }\n\n // this is not the final render, so we need to update the spinner\n if (output.isInteractive) {\n // we're in an interactive terminal, so update the spinner\n output.updateSpinner(message);\n } else if (firstRender) {\n // we're not in an interactive terminal, and this is the first\n // render, so just write the first render to stdout\n output.writeStdout(message);\n firstRender = false;\n }\n };\n\n // render the first frame\n render({ message: str });\n\n let spinnerInterval: NodeJS.Timeout | undefined;\n if (output.isInteractive) {\n // we are in an interactive terminal, so keep rendering the spinner\n spinnerInterval = setInterval(() => render({ message: str }), interval);\n }\n\n // setup the last render\n const finalRender = (renderOptions: Omit<RenderOptions, \"final\">): void => {\n render({ ...renderOptions, final: true });\n clearInterval(spinnerInterval);\n };\n\n activeSpinner = {\n text: str,\n clear(): void {\n this.text = \"\";\n finalRender({ symbol: \"\", message: \"\" });\n },\n succeed(finalStr?: string | TemplateStringsArray, ...values: unknown[]): void {\n finalStr ??= str;\n if (!isString(finalStr)) {\n finalStr = dedent(chalkTemplate(finalStr, ...values));\n }\n this.text = finalStr;\n finalRender({ message: finalStr, symbol: successSymbol });\n },\n fail(finalStr?: string | TemplateStringsArray, ...values: unknown[]): void {\n finalStr ??= str;\n if (!isString(finalStr)) {\n finalStr = dedent(chalkTemplate(finalStr, ...values));\n }\n this.text = finalStr;\n finalRender({ message: finalStr, symbol: failSymbol });\n },\n };\n\n return activeSpinner;\n }) as spin;\n};\n\nexport const spin = createSpin({});\n"],"names":["chalk","chalkTemplate","cliSpinners","assert","os","dedent","isString","output","isSprintOptions","sprintln","symbol","activeSpinner","createSpin","options","optionsOrString","values","str","ensureNewLine","ensureEmptyLineAbove","kind","color","successSymbol","green","tick","failSymbol","red","cross","frameIndex","frames","interval","firstRender","render","message","final","finalRender","startsWith","slice","endsWith","undefined","length","lines","split","join","EOL","isInteractive","persistSpinner","updateSpinner","writeStdout","spinnerInterval","setInterval","renderOptions","clearInterval","text","clear","succeed","finalStr","fail","spin"],"mappings":"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"}
|
|
@@ -1,21 +1,44 @@
|
|
|
1
|
+
import boxen from "boxen";
|
|
1
2
|
import chalkTemplate from "chalk-template";
|
|
3
|
+
import indentString from "indent-string";
|
|
2
4
|
import { dedent } from "ts-dedent";
|
|
3
|
-
import { isString } from "../util/is.js";
|
|
4
|
-
export const
|
|
5
|
-
|
|
6
|
-
if (!isString(content)) {
|
|
7
|
-
content = chalkTemplate(content, ...values);
|
|
8
|
-
}
|
|
9
|
-
return dedent(content);
|
|
5
|
+
import { isArray, isString } from "../util/is.js";
|
|
6
|
+
export const isSprintOptions = (value)=>{
|
|
7
|
+
return !isString(value) && !isArray(value);
|
|
10
8
|
};
|
|
11
|
-
|
|
12
|
-
return
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
const createSprint = (options)=>{
|
|
10
|
+
return (optionsOrString, ...values)=>{
|
|
11
|
+
if (isSprintOptions(optionsOrString)) {
|
|
12
|
+
return createSprint({
|
|
13
|
+
...options,
|
|
14
|
+
...optionsOrString
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
const { ensureNewLine = false, ensureEmptyLineAbove = false, indent = 0, boxen: boxenOptions } = options;
|
|
18
|
+
let str = optionsOrString;
|
|
19
|
+
if (!isString(str)) {
|
|
20
|
+
str = dedent(chalkTemplate(str, ...values));
|
|
21
|
+
}
|
|
22
|
+
if (ensureEmptyLineAbove && !str.startsWith("\n")) {
|
|
23
|
+
str = "\n" + str;
|
|
24
|
+
}
|
|
25
|
+
if (ensureNewLine && !str.endsWith("\n")) {
|
|
26
|
+
str += "\n";
|
|
27
|
+
}
|
|
28
|
+
if (boxenOptions) {
|
|
29
|
+
str = boxen(str, boxenOptions);
|
|
30
|
+
}
|
|
31
|
+
if (indent > 0) {
|
|
32
|
+
str = indentString(str, indent);
|
|
33
|
+
}
|
|
34
|
+
return str;
|
|
35
|
+
};
|
|
19
36
|
};
|
|
37
|
+
export const sprint = createSprint({
|
|
38
|
+
ensureNewLine: false
|
|
39
|
+
});
|
|
40
|
+
export const sprintln = createSprint({
|
|
41
|
+
ensureNewLine: true
|
|
42
|
+
});
|
|
20
43
|
|
|
21
44
|
//# sourceMappingURL=sprint.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/output/sprint.ts"],"sourcesContent":["import chalkTemplate from \"chalk-template\";\nimport { dedent } from \"ts-dedent\";\nimport { isString } from \"../util/is.js\";\n\nexport type
|
|
1
|
+
{"version":3,"sources":["../../../src/services/output/sprint.ts"],"sourcesContent":["import type { Options as BoxenOptions } from \"boxen\";\nimport boxen from \"boxen\";\nimport chalkTemplate from \"chalk-template\";\nimport indentString from \"indent-string\";\nimport { dedent } from \"ts-dedent\";\nimport { isArray, isString } from \"../util/is.js\";\n\nexport type SprintOptions = {\n /**\n * Whether to ensure a new line is after the content.\n *\n * @default true\n */\n ensureNewLine?: boolean;\n\n /**\n * Whether to ensure an empty line is above the content.\n *\n * @default false\n */\n ensureEmptyLineAbove?: boolean;\n\n /**\n * The number of spaces to indent the text.\n *\n * @default 0\n */\n indent?: number;\n\n /**\n * Whether to wrap the text in a box.\n *\n * @default undefined (no box)\n */\n boxen?: BoxenOptions;\n};\n\nexport type sprint = {\n (str: string): string;\n (template: TemplateStringsArray, ...values: unknown[]): string;\n (options: SprintOptions): sprint;\n};\n\nexport const isSprintOptions = <const T extends SprintOptions>(value: string | TemplateStringsArray | SprintOptions): value is T => {\n return !isString(value) && !isArray(value);\n};\n\nconst createSprint = (options: SprintOptions): sprint => {\n return ((optionsOrString: SprintOptions | string | TemplateStringsArray, ...values: unknown[]): sprint | string => {\n if (isSprintOptions(optionsOrString)) {\n return createSprint({ ...options, ...optionsOrString });\n }\n\n const { ensureNewLine = false, ensureEmptyLineAbove = false, indent = 0, boxen: boxenOptions } = options;\n\n let str = optionsOrString as string;\n if (!isString(str)) {\n str = dedent(chalkTemplate(str, ...values));\n }\n\n if (ensureEmptyLineAbove && !str.startsWith(\"\\n\")) {\n str = \"\\n\" + str;\n }\n\n if (ensureNewLine && !str.endsWith(\"\\n\")) {\n str += \"\\n\";\n }\n\n if (boxenOptions) {\n str = boxen(str, boxenOptions);\n }\n\n if (indent > 0) {\n str = indentString(str, indent);\n }\n\n return str;\n }) as sprint;\n};\n\nexport const sprint = createSprint({ ensureNewLine: false });\nexport const sprintln = createSprint({ ensureNewLine: true });\n"],"names":["boxen","chalkTemplate","indentString","dedent","isArray","isString","isSprintOptions","value","createSprint","options","optionsOrString","values","ensureNewLine","ensureEmptyLineAbove","indent","boxenOptions","str","startsWith","endsWith","sprint","sprintln"],"mappings":"AACA,OAAOA,WAAW,QAAQ;AAC1B,OAAOC,mBAAmB,iBAAiB;AAC3C,OAAOC,kBAAkB,gBAAgB;AACzC,SAASC,MAAM,QAAQ,YAAY;AACnC,SAASC,OAAO,EAAEC,QAAQ,QAAQ,gBAAgB;AAsClD,OAAO,MAAMC,kBAAkB,CAAgCC;IAC7D,OAAO,CAACF,SAASE,UAAU,CAACH,QAAQG;AACtC,EAAE;AAEF,MAAMC,eAAe,CAACC;IACpB,OAAQ,CAACC,iBAAgE,GAAGC;QAC1E,IAAIL,gBAAgBI,kBAAkB;YACpC,OAAOF,aAAa;gBAAE,GAAGC,OAAO;gBAAE,GAAGC,eAAe;YAAC;QACvD;QAEA,MAAM,EAAEE,gBAAgB,KAAK,EAAEC,uBAAuB,KAAK,EAAEC,SAAS,CAAC,EAAEd,OAAOe,YAAY,EAAE,GAAGN;QAEjG,IAAIO,MAAMN;QACV,IAAI,CAACL,SAASW,MAAM;YAClBA,MAAMb,OAAOF,cAAce,QAAQL;QACrC;QAEA,IAAIE,wBAAwB,CAACG,IAAIC,UAAU,CAAC,OAAO;YACjDD,MAAM,OAAOA;QACf;QAEA,IAAIJ,iBAAiB,CAACI,IAAIE,QAAQ,CAAC,OAAO;YACxCF,OAAO;QACT;QAEA,IAAID,cAAc;YAChBC,MAAMhB,MAAMgB,KAAKD;QACnB;QAEA,IAAID,SAAS,GAAG;YACdE,MAAMd,aAAac,KAAKF;QAC1B;QAEA,OAAOE;IACT;AACF;AAEA,OAAO,MAAMG,SAASX,aAAa;IAAEI,eAAe;AAAM,GAAG;AAC7D,OAAO,MAAMQ,WAAWZ,aAAa;IAAEI,eAAe;AAAK,GAAG"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// eslint-disable-next-line no-restricted-imports -- this is the only place we're allowed to import figures
|
|
2
|
+
import figures, { mainSymbols } from "figures";
|
|
3
|
+
import isUnicodeSupported from "is-unicode-supported";
|
|
4
|
+
import { config } from "../config/config.js";
|
|
5
|
+
import { env } from "../config/env.js";
|
|
6
|
+
// we always use main symbols in tests rather than figures so that our
|
|
7
|
+
// tests are consistent across platforms (particularly Windows)
|
|
8
|
+
export const symbol = {
|
|
9
|
+
...env.testLike ? mainSymbols : figures
|
|
10
|
+
};
|
|
11
|
+
if (isUnicodeSupported() && config.windowsOrWsl) {
|
|
12
|
+
// when unicode is supported and we're on windows or wsl, these
|
|
13
|
+
// symbols end up rendering over two cells while only taking up one,
|
|
14
|
+
// so we add an extra space to each of them to make them take up two
|
|
15
|
+
for (const name of [
|
|
16
|
+
"tick",
|
|
17
|
+
"cross"
|
|
18
|
+
]){
|
|
19
|
+
symbol[name] += " ";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=symbols.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/output/symbols.ts"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports -- this is the only place we're allowed to import figures\nimport figures, { mainSymbols } from \"figures\";\nimport isUnicodeSupported from \"is-unicode-supported\";\nimport { config } from \"../config/config.js\";\nimport { env } from \"../config/env.js\";\n\n// we always use main symbols in tests rather than figures so that our\n// tests are consistent across platforms (particularly Windows)\nexport const symbol = { ...(env.testLike ? mainSymbols : figures) };\n\nif (isUnicodeSupported() && config.windowsOrWsl) {\n // when unicode is supported and we're on windows or wsl, these\n // symbols end up rendering over two cells while only taking up one,\n // so we add an extra space to each of them to make them take up two\n for (const name of [\"tick\", \"cross\"] as const) {\n symbol[name] += \" \";\n }\n}\n"],"names":["figures","mainSymbols","isUnicodeSupported","config","env","symbol","testLike","windowsOrWsl","name"],"mappings":"AAAA,2GAA2G;AAC3G,OAAOA,WAAWC,WAAW,QAAQ,UAAU;AAC/C,OAAOC,wBAAwB,uBAAuB;AACtD,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,GAAG,QAAQ,mBAAmB;AAEvC,sEAAsE;AACtE,+DAA+D;AAC/D,OAAO,MAAMC,SAAS;IAAE,GAAID,IAAIE,QAAQ,GAAGL,cAAcD,OAAO;AAAE,EAAE;AAEpE,IAAIE,wBAAwBC,OAAOI,YAAY,EAAE;IAC/C,+DAA+D;IAC/D,oEAAoE;IACpE,oEAAoE;IACpE,KAAK,MAAMC,QAAQ;QAAC;QAAQ;KAAQ,CAAW;QAC7CH,MAAM,CAACG,KAAK,IAAI;IAClB;AACF"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import CliTable3 from "cli-table3";
|
|
2
|
+
import indentString from "indent-string";
|
|
3
|
+
import { dedent } from "ts-dedent";
|
|
4
|
+
import { println } from "./print.js";
|
|
5
|
+
import { sprintln } from "./sprint.js";
|
|
6
|
+
export const sprintTable = ({ title, headers, rows, footer, ensureEmptyLineAboveBody = false, ensureEmptyLineAboveFooter = false, borders: borderType = "none", colAligns = [], colWidths = [], indent, ...printOptions })=>{
|
|
7
|
+
const table = new CliTable3({
|
|
8
|
+
chars: borders[borderType],
|
|
9
|
+
colAligns,
|
|
10
|
+
colWidths,
|
|
11
|
+
head: headers,
|
|
12
|
+
style: {
|
|
13
|
+
head: [],
|
|
14
|
+
border: []
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
table.push(...rows);
|
|
18
|
+
let text = table.toString() + "\n";
|
|
19
|
+
if (borderType === "none") {
|
|
20
|
+
// remove the left padding
|
|
21
|
+
text = dedent(text).slice(1);
|
|
22
|
+
}
|
|
23
|
+
// remove the right padding
|
|
24
|
+
text = text.split("\n").map((line)=>line.trimEnd()).join("\n");
|
|
25
|
+
if (indent) {
|
|
26
|
+
text = indentString(text, indent);
|
|
27
|
+
}
|
|
28
|
+
if (title) {
|
|
29
|
+
text = sprintln(title) + sprintln({
|
|
30
|
+
ensureEmptyLineAbove: ensureEmptyLineAboveBody
|
|
31
|
+
})(text);
|
|
32
|
+
}
|
|
33
|
+
if (footer) {
|
|
34
|
+
text = sprintln(text) + sprintln({
|
|
35
|
+
ensureEmptyLineAbove: ensureEmptyLineAboveFooter
|
|
36
|
+
})(footer);
|
|
37
|
+
}
|
|
38
|
+
return sprintln(printOptions)(text);
|
|
39
|
+
};
|
|
40
|
+
export const printTable = (options)=>{
|
|
41
|
+
println(options)(sprintTable(options));
|
|
42
|
+
};
|
|
43
|
+
// prettier-ignore
|
|
44
|
+
const borders = {
|
|
45
|
+
none: {
|
|
46
|
+
"top-left": "",
|
|
47
|
+
top: "",
|
|
48
|
+
"top-mid": "",
|
|
49
|
+
"top-right": "",
|
|
50
|
+
"left-mid": "",
|
|
51
|
+
mid: "",
|
|
52
|
+
"mid-mid": "",
|
|
53
|
+
"right-mid": "",
|
|
54
|
+
left: "",
|
|
55
|
+
middle: "",
|
|
56
|
+
right: "",
|
|
57
|
+
"bottom-left": "",
|
|
58
|
+
bottom: "",
|
|
59
|
+
"bottom-mid": "",
|
|
60
|
+
"bottom-right": ""
|
|
61
|
+
},
|
|
62
|
+
thin: {
|
|
63
|
+
"top-left": "┌",
|
|
64
|
+
top: "─",
|
|
65
|
+
"top-mid": "┬",
|
|
66
|
+
"top-right": "┐",
|
|
67
|
+
"left-mid": "├",
|
|
68
|
+
mid: "─",
|
|
69
|
+
"mid-mid": "┼",
|
|
70
|
+
"right-mid": "┤",
|
|
71
|
+
left: "│",
|
|
72
|
+
middle: "│",
|
|
73
|
+
right: "│",
|
|
74
|
+
"bottom-left": "└",
|
|
75
|
+
bottom: "─",
|
|
76
|
+
"bottom-mid": "┴",
|
|
77
|
+
"bottom-right": "┘"
|
|
78
|
+
},
|
|
79
|
+
thick: {
|
|
80
|
+
"top-left": "╔",
|
|
81
|
+
top: "═",
|
|
82
|
+
"top-mid": "╤",
|
|
83
|
+
"top-right": "╗",
|
|
84
|
+
left: "║",
|
|
85
|
+
middle: "│",
|
|
86
|
+
right: "║",
|
|
87
|
+
"left-mid": "╟",
|
|
88
|
+
mid: "─",
|
|
89
|
+
"mid-mid": "┼",
|
|
90
|
+
"right-mid": "╢",
|
|
91
|
+
"bottom-left": "╚",
|
|
92
|
+
bottom: "═",
|
|
93
|
+
"bottom-mid": "╧",
|
|
94
|
+
"bottom-right": "╝"
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
//# sourceMappingURL=table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/output/table.ts"],"sourcesContent":["import CliTable3 from \"cli-table3\";\nimport indentString from \"indent-string\";\nimport { dedent } from \"ts-dedent\";\nimport { println, type PrintOptions } from \"./print.js\";\nimport { sprintln, type SprintOptions } from \"./sprint.js\";\n\nexport type SprintTableOptions = SprintOptions & {\n /**\n * The text to print above the table.\n */\n title?: string;\n\n /**\n * The headers of the table.\n */\n headers?: string[];\n\n /**\n * The rows of the table.\n */\n rows: string[][];\n\n /**\n * The text to print below the table.\n */\n footer?: string;\n\n /**\n * Whether to add an empty line above the body of the table.\n *\n * @default false\n */\n ensureEmptyLineAboveBody?: boolean;\n\n /**\n * Whether to add an empty line above the footer of the table.\n *\n * @default false\n */\n ensureEmptyLineAboveFooter?: boolean;\n\n /**\n * The type of borders to use.\n *\n * @default \"none\"\n */\n borders?: \"none\" | \"thin\" | \"thick\";\n\n /**\n * The alignment of the content in each column.\n *\n * @default [] (left-aligned)\n */\n colAligns?: (\"left\" | \"center\" | \"right\")[];\n\n /**\n * The width of each column.\n *\n * @default [] (auto-sized)\n */\n colWidths?: number[];\n};\n\nexport const sprintTable = ({\n title,\n headers,\n rows,\n footer,\n ensureEmptyLineAboveBody = false,\n ensureEmptyLineAboveFooter = false,\n borders: borderType = \"none\",\n colAligns = [],\n colWidths = [],\n indent,\n ...printOptions\n}: SprintTableOptions): string => {\n const table = new CliTable3({\n chars: borders[borderType],\n colAligns,\n colWidths,\n head: headers,\n style: { head: [], border: [] },\n });\n\n table.push(...rows);\n\n let text = table.toString() + \"\\n\";\n if (borderType === \"none\") {\n // remove the left padding\n text = dedent(text).slice(1);\n }\n\n // remove the right padding\n text = text\n .split(\"\\n\")\n .map((line) => line.trimEnd())\n .join(\"\\n\");\n\n if (indent) {\n text = indentString(text, indent);\n }\n\n if (title) {\n text = sprintln(title) + sprintln({ ensureEmptyLineAbove: ensureEmptyLineAboveBody })(text);\n }\n\n if (footer) {\n text = sprintln(text) + sprintln({ ensureEmptyLineAbove: ensureEmptyLineAboveFooter })(footer);\n }\n\n return sprintln(printOptions)(text);\n};\n\nexport type PrintTableOptions = PrintOptions & SprintTableOptions;\n\nexport const printTable = (options: PrintTableOptions): void => {\n println(options)(sprintTable(options));\n};\n\n// prettier-ignore\nconst borders = {\n none: {\n \"top-left\": \"\", top: \"\", \"top-mid\": \"\", \"top-right\": \"\",\n \"left-mid\": \"\", mid: \"\", \"mid-mid\": \"\", \"right-mid\": \"\",\n left: \"\", middle: \"\", right: \"\",\n \"bottom-left\": \"\", bottom: \"\", \"bottom-mid\": \"\", \"bottom-right\": \"\",\n },\n thin: {\n \"top-left\": \"┌\", top: \"─\", \"top-mid\": \"┬\", \"top-right\": \"┐\",\n \"left-mid\": \"├\", mid: \"─\", \"mid-mid\": \"┼\", \"right-mid\": \"┤\",\n left: \"│\", middle: \"│\", right: \"│\",\n \"bottom-left\": \"└\", bottom: \"─\", \"bottom-mid\": \"┴\", \"bottom-right\": \"┘\",\n },\n thick: {\n \"top-left\": \"╔\", top: \"═\", \"top-mid\": \"╤\", \"top-right\": \"╗\",\n left: \"║\", middle: \"│\", right: \"║\",\n \"left-mid\": \"╟\", mid: \"─\", \"mid-mid\": \"┼\", \"right-mid\": \"╢\",\n \"bottom-left\": \"╚\", bottom: \"═\", \"bottom-mid\": \"╧\", \"bottom-right\": \"╝\",\n },\n };\n"],"names":["CliTable3","indentString","dedent","println","sprintln","sprintTable","title","headers","rows","footer","ensureEmptyLineAboveBody","ensureEmptyLineAboveFooter","borders","borderType","colAligns","colWidths","indent","printOptions","table","chars","head","style","border","push","text","toString","slice","split","map","line","trimEnd","join","ensureEmptyLineAbove","printTable","options","none","top","mid","left","middle","right","bottom","thin","thick"],"mappings":"AAAA,OAAOA,eAAe,aAAa;AACnC,OAAOC,kBAAkB,gBAAgB;AACzC,SAASC,MAAM,QAAQ,YAAY;AACnC,SAASC,OAAO,QAA2B,aAAa;AACxD,SAASC,QAAQ,QAA4B,cAAc;AA2D3D,OAAO,MAAMC,cAAc,CAAC,EAC1BC,KAAK,EACLC,OAAO,EACPC,IAAI,EACJC,MAAM,EACNC,2BAA2B,KAAK,EAChCC,6BAA6B,KAAK,EAClCC,SAASC,aAAa,MAAM,EAC5BC,YAAY,EAAE,EACdC,YAAY,EAAE,EACdC,MAAM,EACN,GAAGC,cACgB;IACnB,MAAMC,QAAQ,IAAIlB,UAAU;QAC1BmB,OAAOP,OAAO,CAACC,WAAW;QAC1BC;QACAC;QACAK,MAAMb;QACNc,OAAO;YAAED,MAAM,EAAE;YAAEE,QAAQ,EAAE;QAAC;IAChC;IAEAJ,MAAMK,IAAI,IAAIf;IAEd,IAAIgB,OAAON,MAAMO,QAAQ,KAAK;IAC9B,IAAIZ,eAAe,QAAQ;QACzB,0BAA0B;QAC1BW,OAAOtB,OAAOsB,MAAME,KAAK,CAAC;IAC5B;IAEA,2BAA2B;IAC3BF,OAAOA,KACJG,KAAK,CAAC,MACNC,GAAG,CAAC,CAACC,OAASA,KAAKC,OAAO,IAC1BC,IAAI,CAAC;IAER,IAAIf,QAAQ;QACVQ,OAAOvB,aAAauB,MAAMR;IAC5B;IAEA,IAAIV,OAAO;QACTkB,OAAOpB,SAASE,SAASF,SAAS;YAAE4B,sBAAsBtB;QAAyB,GAAGc;IACxF;IAEA,IAAIf,QAAQ;QACVe,OAAOpB,SAASoB,QAAQpB,SAAS;YAAE4B,sBAAsBrB;QAA2B,GAAGF;IACzF;IAEA,OAAOL,SAASa,cAAcO;AAChC,EAAE;AAIF,OAAO,MAAMS,aAAa,CAACC;IACzB/B,QAAQ+B,SAAS7B,YAAY6B;AAC/B,EAAE;AAEF,kBAAkB;AAClB,MAAMtB,UAAU;IACZuB,MAAM;QACJ,YAAY;QAAIC,KAAK;QAAI,WAAW;QAAI,aAAa;QACrD,YAAY;QAAIC,KAAK;QAAI,WAAW;QAAI,aAAa;QACrDC,MAAM;QAAIC,QAAQ;QAAIC,OAAO;QAC7B,eAAe;QAAIC,QAAQ;QAAI,cAAc;QAAI,gBAAgB;IACnE;IACAC,MAAM;QACJ,YAAY;QAAKN,KAAK;QAAK,WAAW;QAAK,aAAa;QACxD,YAAY;QAAKC,KAAK;QAAK,WAAW;QAAK,aAAa;QACxDC,MAAM;QAAKC,QAAQ;QAAKC,OAAO;QAC/B,eAAe;QAAKC,QAAQ;QAAK,cAAc;QAAK,gBAAgB;IACtE;IACAE,OAAO;QACL,YAAY;QAAKP,KAAK;QAAK,WAAW;QAAK,aAAa;QACxDE,MAAM;QAAKC,QAAQ;QAAKC,OAAO;QAC/B,YAAY;QAAKH,KAAK;QAAK,WAAW;QAAK,aAAa;QACxD,eAAe;QAAKI,QAAQ;QAAK,cAAc;QAAK,gBAAgB;IACtE;AACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import dayjs from "dayjs";
|
|
3
|
+
import { env } from "../config/env.js";
|
|
4
|
+
import { parseBoolean } from "../util/boolean.js";
|
|
5
|
+
export const ts = ()=>{
|
|
6
|
+
if (!env.testLike && parseBoolean(process.env["CI"])) {
|
|
7
|
+
return new Date().toISOString();
|
|
8
|
+
}
|
|
9
|
+
return chalk.gray(dayjs().format("hh:mm:ss A"));
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=timestamp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/output/timestamp.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport dayjs from \"dayjs\";\nimport { env } from \"../config/env.js\";\nimport { parseBoolean } from \"../util/boolean.js\";\n\nexport const ts = (): string => {\n if (!env.testLike && parseBoolean(process.env[\"CI\"])) {\n return new Date().toISOString();\n }\n return chalk.gray(dayjs().format(\"hh:mm:ss A\"));\n};\n"],"names":["chalk","dayjs","env","parseBoolean","ts","testLike","process","Date","toISOString","gray","format"],"mappings":"AAAA,OAAOA,WAAW,QAAQ;AAC1B,OAAOC,WAAW,QAAQ;AAC1B,SAASC,GAAG,QAAQ,mBAAmB;AACvC,SAASC,YAAY,QAAQ,qBAAqB;AAElD,OAAO,MAAMC,KAAK;IAChB,IAAI,CAACF,IAAIG,QAAQ,IAAIF,aAAaG,QAAQJ,GAAG,CAAC,KAAK,GAAG;QACpD,OAAO,IAAIK,OAAOC,WAAW;IAC/B;IACA,OAAOR,MAAMS,IAAI,CAACR,QAAQS,MAAM,CAAC;AACnC,EAAE"}
|