@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.
Files changed (142) hide show
  1. package/README.md +165 -93
  2. package/lib/__generated__/graphql.js +66 -1
  3. package/lib/__generated__/graphql.js.map +1 -1
  4. package/lib/commands/deploy.js +328 -230
  5. package/lib/commands/deploy.js.map +1 -1
  6. package/lib/commands/dev.js +445 -0
  7. package/lib/commands/dev.js.map +1 -0
  8. package/lib/commands/list.js +27 -19
  9. package/lib/commands/list.js.map +1 -1
  10. package/lib/commands/login.js +15 -11
  11. package/lib/commands/login.js.map +1 -1
  12. package/lib/commands/logout.js +5 -5
  13. package/lib/commands/logout.js.map +1 -1
  14. package/lib/commands/open.js +200 -0
  15. package/lib/commands/open.js.map +1 -0
  16. package/lib/commands/pull.js +128 -0
  17. package/lib/commands/pull.js.map +1 -0
  18. package/lib/commands/push.js +126 -0
  19. package/lib/commands/push.js.map +1 -0
  20. package/lib/commands/root.js +46 -28
  21. package/lib/commands/root.js.map +1 -1
  22. package/lib/commands/status.js +61 -0
  23. package/lib/commands/status.js.map +1 -0
  24. package/lib/commands/version.js +6 -6
  25. package/lib/commands/version.js.map +1 -1
  26. package/lib/commands/whoami.js +6 -6
  27. package/lib/commands/whoami.js.map +1 -1
  28. package/lib/ggt.js +33 -8
  29. package/lib/ggt.js.map +1 -1
  30. package/lib/main.js +5 -0
  31. package/lib/main.js.map +1 -0
  32. package/lib/services/app/api/api.js +191 -0
  33. package/lib/services/app/api/api.js.map +1 -0
  34. package/lib/services/app/api/operation.js +12 -0
  35. package/lib/services/app/api/operation.js.map +1 -0
  36. package/lib/services/app/app.js +44 -10
  37. package/lib/services/app/app.js.map +1 -1
  38. package/lib/services/app/{edit/client.js → client.js} +29 -19
  39. package/lib/services/app/client.js.map +1 -0
  40. package/lib/services/app/edit/edit.js +67 -31
  41. package/lib/services/app/edit/edit.js.map +1 -1
  42. package/lib/services/app/edit/operation.js +4 -3
  43. package/lib/services/app/edit/operation.js.map +1 -1
  44. package/lib/services/app/{edit/error.js → error.js} +6 -6
  45. package/lib/services/app/error.js.map +1 -0
  46. package/lib/services/command/arg.js +4 -4
  47. package/lib/services/command/arg.js.map +1 -1
  48. package/lib/services/command/command.js +9 -7
  49. package/lib/services/command/command.js.map +1 -1
  50. package/lib/services/command/context.js +82 -20
  51. package/lib/services/command/context.js.map +1 -1
  52. package/lib/services/config/config.js +4 -7
  53. package/lib/services/config/config.js.map +1 -1
  54. package/lib/services/config/env.js +1 -1
  55. package/lib/services/config/env.js.map +1 -1
  56. package/lib/services/filesync/changes.js +76 -37
  57. package/lib/services/filesync/changes.js.map +1 -1
  58. package/lib/services/filesync/conflicts.js +10 -9
  59. package/lib/services/filesync/conflicts.js.map +1 -1
  60. package/lib/services/filesync/directory.js +16 -1
  61. package/lib/services/filesync/directory.js.map +1 -1
  62. package/lib/services/filesync/error.js +96 -27
  63. package/lib/services/filesync/error.js.map +1 -1
  64. package/lib/services/filesync/filesync.js +448 -490
  65. package/lib/services/filesync/filesync.js.map +1 -1
  66. package/lib/services/filesync/hashes.js +8 -5
  67. package/lib/services/filesync/hashes.js.map +1 -1
  68. package/lib/services/filesync/strategy.js +59 -0
  69. package/lib/services/filesync/strategy.js.map +1 -0
  70. package/lib/services/filesync/sync-json.js +475 -0
  71. package/lib/services/filesync/sync-json.js.map +1 -0
  72. package/lib/services/http/auth.js +30 -1
  73. package/lib/services/http/auth.js.map +1 -1
  74. package/lib/services/http/http.js +5 -0
  75. package/lib/services/http/http.js.map +1 -1
  76. package/lib/services/output/confirm.js +149 -0
  77. package/lib/services/output/confirm.js.map +1 -0
  78. package/lib/services/output/footer.js +22 -0
  79. package/lib/services/output/footer.js.map +1 -0
  80. package/lib/services/output/log/format/pretty.js +2 -1
  81. package/lib/services/output/log/format/pretty.js.map +1 -1
  82. package/lib/services/output/log/logger.js +13 -5
  83. package/lib/services/output/log/logger.js.map +1 -1
  84. package/lib/services/output/log/structured.js +2 -2
  85. package/lib/services/output/log/structured.js.map +1 -1
  86. package/lib/services/output/output.js +197 -0
  87. package/lib/services/output/output.js.map +1 -0
  88. package/lib/services/output/print.js +31 -0
  89. package/lib/services/output/print.js.map +1 -0
  90. package/lib/services/output/problems.js +84 -0
  91. package/lib/services/output/problems.js.map +1 -0
  92. package/lib/services/output/prompt.js +173 -40
  93. package/lib/services/output/prompt.js.map +1 -1
  94. package/lib/services/output/report.js +63 -19
  95. package/lib/services/output/report.js.map +1 -1
  96. package/lib/services/output/select.js +198 -0
  97. package/lib/services/output/select.js.map +1 -0
  98. package/lib/services/output/spinner.js +141 -0
  99. package/lib/services/output/spinner.js.map +1 -0
  100. package/lib/services/output/sprint.js +38 -15
  101. package/lib/services/output/sprint.js.map +1 -1
  102. package/lib/services/output/symbols.js +23 -0
  103. package/lib/services/output/symbols.js.map +1 -0
  104. package/lib/services/output/table.js +98 -0
  105. package/lib/services/output/table.js.map +1 -0
  106. package/lib/services/output/timestamp.js +12 -0
  107. package/lib/services/output/timestamp.js.map +1 -0
  108. package/lib/services/output/update.js +29 -9
  109. package/lib/services/output/update.js.map +1 -1
  110. package/lib/services/user/session.js +4 -0
  111. package/lib/services/user/session.js.map +1 -1
  112. package/lib/services/user/user.js +15 -10
  113. package/lib/services/user/user.js.map +1 -1
  114. package/lib/services/util/assert.js +11 -0
  115. package/lib/services/util/assert.js.map +1 -0
  116. package/lib/services/util/boolean.js +2 -2
  117. package/lib/services/util/boolean.js.map +1 -1
  118. package/lib/services/util/function.js +45 -7
  119. package/lib/services/util/function.js.map +1 -1
  120. package/lib/services/util/is.js +23 -2
  121. package/lib/services/util/is.js.map +1 -1
  122. package/lib/services/util/json.js +16 -13
  123. package/lib/services/util/json.js.map +1 -1
  124. package/lib/services/util/object.js +2 -2
  125. package/lib/services/util/object.js.map +1 -1
  126. package/lib/services/util/promise.js +5 -2
  127. package/lib/services/util/promise.js.map +1 -1
  128. package/lib/services/util/types.js.map +1 -1
  129. package/npm-shrinkwrap.json +3415 -2973
  130. package/package.json +47 -40
  131. package/bin/dev.cmd +0 -3
  132. package/bin/dev.js +0 -14
  133. package/bin/run.cmd +0 -3
  134. package/bin/run.js +0 -5
  135. package/lib/commands/sync.js +0 -284
  136. package/lib/commands/sync.js.map +0 -1
  137. package/lib/services/app/edit/client.js.map +0 -1
  138. package/lib/services/app/edit/error.js.map +0 -1
  139. package/lib/services/output/log/printer.js +0 -120
  140. package/lib/services/output/log/printer.js.map +0 -1
  141. package/lib/services/output/stream.js +0 -54
  142. 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 sprint = (template, ...values)=>{
5
- let content = template;
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
- export const sprintln = (template, ...values)=>{
12
- return sprint(template, ...values) + "\n";
13
- };
14
- export const sprintln2 = (template, ...values)=>{
15
- return sprintln(template, ...values) + "\n";
16
- };
17
- export const sprintlns = (template, ...values)=>{
18
- return "\n" + sprintln(template, ...values);
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 Sprint = (template: TemplateStringsArray | string, ...values: unknown[]) => string;\n\nexport const sprint: Sprint = (template, ...values) => {\n let content = template;\n if (!isString(content)) {\n content = chalkTemplate(content, ...values);\n }\n return dedent(content);\n};\n\nexport const sprintln: Sprint = (template, ...values) => {\n return sprint(template, ...values) + \"\\n\";\n};\n\nexport const sprintln2: Sprint = (template, ...values) => {\n return sprintln(template, ...values) + \"\\n\";\n};\n\nexport const sprintlns: Sprint = (template, ...values) => {\n return \"\\n\" + sprintln(template, ...values);\n};\n"],"names":["chalkTemplate","dedent","isString","sprint","template","values","content","sprintln","sprintln2","sprintlns"],"mappings":"AAAA,OAAOA,mBAAmB,iBAAiB;AAC3C,SAASC,MAAM,QAAQ,YAAY;AACnC,SAASC,QAAQ,QAAQ,gBAAgB;AAIzC,OAAO,MAAMC,SAAiB,CAACC,UAAU,GAAGC;IAC1C,IAAIC,UAAUF;IACd,IAAI,CAACF,SAASI,UAAU;QACtBA,UAAUN,cAAcM,YAAYD;IACtC;IACA,OAAOJ,OAAOK;AAChB,EAAE;AAEF,OAAO,MAAMC,WAAmB,CAACH,UAAU,GAAGC;IAC5C,OAAOF,OAAOC,aAAaC,UAAU;AACvC,EAAE;AAEF,OAAO,MAAMG,YAAoB,CAACJ,UAAU,GAAGC;IAC7C,OAAOE,SAASH,aAAaC,UAAU;AACzC,EAAE;AAEF,OAAO,MAAMI,YAAoB,CAACL,UAAU,GAAGC;IAC7C,OAAO,OAAOE,SAASH,aAAaC;AACtC,EAAE"}
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"}