@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,84 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import pluralize from "pluralize";
|
|
3
|
+
import { compact } from "../util/collection.js";
|
|
4
|
+
import { isGellyFile, isJavaScriptFile, isTypeScriptFile } from "../util/is.js";
|
|
5
|
+
import { println } from "./print.js";
|
|
6
|
+
import { sprint, sprintln } from "./sprint.js";
|
|
7
|
+
export const ProblemSeverity = Object.freeze({
|
|
8
|
+
Fatal: "Fatal",
|
|
9
|
+
Error: "Error",
|
|
10
|
+
Warning: "Warning",
|
|
11
|
+
Info: "Info"
|
|
12
|
+
});
|
|
13
|
+
export const sprintProblems = ({ problems: groupedProblems, showFileTypes, ...sprintOptions })=>{
|
|
14
|
+
let output = "";
|
|
15
|
+
for (const [name, problems] of Object.entries(groupedProblems)){
|
|
16
|
+
output += sprintln("");
|
|
17
|
+
output += sprintln`• {cyan ${name}} {redBright ${pluralize("problem", problems.length, true)}}`;
|
|
18
|
+
for (const problem of problems){
|
|
19
|
+
const [message, ...lines] = problem.message.split("\n");
|
|
20
|
+
output += sprint` {red ✖} `;
|
|
21
|
+
if (showFileTypes ?? problem.type === "SourceFile") {
|
|
22
|
+
output += sprint`${filetype(name)} `;
|
|
23
|
+
}
|
|
24
|
+
output += sprint(message);
|
|
25
|
+
for (const line of lines){
|
|
26
|
+
output += sprintln("");
|
|
27
|
+
output += sprint` ${line}`;
|
|
28
|
+
}
|
|
29
|
+
for (const label of problem.labels){
|
|
30
|
+
output += sprint` {dim ${label}}`;
|
|
31
|
+
}
|
|
32
|
+
output += sprintln("");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return sprintln(sprintOptions)(output);
|
|
36
|
+
};
|
|
37
|
+
export const printProblems = (options)=>{
|
|
38
|
+
println(sprintProblems(options));
|
|
39
|
+
};
|
|
40
|
+
export const filetype = (filename)=>{
|
|
41
|
+
switch(true){
|
|
42
|
+
case isJavaScriptFile(filename):
|
|
43
|
+
return chalk.yellowBright("JavaScript");
|
|
44
|
+
case isTypeScriptFile(filename):
|
|
45
|
+
return chalk.blue("TypeScript");
|
|
46
|
+
case isGellyFile(filename):
|
|
47
|
+
return chalk.magenta("Gelly");
|
|
48
|
+
default:
|
|
49
|
+
return chalk.gray("File");
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
export const publishIssuesToProblems = (issues)=>{
|
|
53
|
+
const problems = {};
|
|
54
|
+
for (const issue of issues){
|
|
55
|
+
const name = issue.node?.apiIdentifier ?? issue.node?.name ?? "Other";
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
57
|
+
problems[name] ??= [];
|
|
58
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
59
|
+
problems[name].push({
|
|
60
|
+
type: issue.node?.type ?? "Unknown",
|
|
61
|
+
severity: issue.severity,
|
|
62
|
+
message: issue.message,
|
|
63
|
+
labels: compact(issue.nodeLabels?.map((label)=>label?.identifier) ?? [])
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return problems;
|
|
67
|
+
};
|
|
68
|
+
export const filesyncProblemsToProblems = (filesyncProblems)=>{
|
|
69
|
+
const problems = {};
|
|
70
|
+
for (const filesyncProblem of filesyncProblems){
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
72
|
+
problems[filesyncProblem.path] ??= [];
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
74
|
+
problems[filesyncProblem.path].push({
|
|
75
|
+
type: filesyncProblem.type,
|
|
76
|
+
severity: filesyncProblem.level,
|
|
77
|
+
message: filesyncProblem.message,
|
|
78
|
+
labels: []
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return problems;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
//# sourceMappingURL=problems.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/output/problems.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport pluralize from \"pluralize\";\nimport type { Problem as FileSyncProblem, PublishIssue } from \"../../__generated__/graphql.js\";\nimport { compact } from \"../util/collection.js\";\nimport { isGellyFile, isJavaScriptFile, isTypeScriptFile } from \"../util/is.js\";\nimport { println } from \"./print.js\";\nimport { sprint, sprintln, type SprintOptions } from \"./sprint.js\";\n\nexport type Problems = Record<string, Problem[]>;\n\nexport type Problem = {\n type: string;\n severity: ProblemSeverity;\n message: string;\n labels: string[];\n};\n\nexport const ProblemSeverity = Object.freeze({\n Fatal: \"Fatal\",\n Error: \"Error\",\n Warning: \"Warning\",\n Info: \"Info\",\n});\n\nexport type ProblemSeverity = keyof typeof ProblemSeverity;\n\nexport type PrintProblemsOptions = SprintOptions & {\n /**\n * The problems to print.\n */\n problems: Problems;\n\n /**\n * Whether to show the file type in the output.\n *\n * @default problem.type === \"SourceFile\"\n */\n showFileTypes?: boolean;\n};\n\nexport const sprintProblems = ({ problems: groupedProblems, showFileTypes, ...sprintOptions }: PrintProblemsOptions): string => {\n let output = \"\";\n\n for (const [name, problems] of Object.entries(groupedProblems)) {\n output += sprintln(\"\");\n output += sprintln`• {cyan ${name}} {redBright ${pluralize(\"problem\", problems.length, true)}}`;\n for (const problem of problems) {\n const [message, ...lines] = problem.message.split(\"\\n\") as [string, ...string[]];\n\n output += sprint` {red ✖} `;\n if (showFileTypes ?? problem.type === \"SourceFile\") {\n output += sprint`${filetype(name)} `;\n }\n output += sprint(message);\n\n for (const line of lines) {\n output += sprintln(\"\");\n output += sprint` ${line}`;\n }\n\n for (const label of problem.labels) {\n output += sprint` {dim ${label}}`;\n }\n\n output += sprintln(\"\");\n }\n }\n\n return sprintln(sprintOptions)(output);\n};\n\nexport const printProblems = (options: PrintProblemsOptions): void => {\n println(sprintProblems(options));\n};\n\nexport const filetype = (filename: string): string => {\n switch (true) {\n case isJavaScriptFile(filename):\n return chalk.yellowBright(\"JavaScript\");\n case isTypeScriptFile(filename):\n return chalk.blue(\"TypeScript\");\n case isGellyFile(filename):\n return chalk.magenta(\"Gelly\");\n default:\n return chalk.gray(\"File\");\n }\n};\n\nexport const publishIssuesToProblems = (issues: PublishIssue[]): Problems => {\n const problems: Problems = {};\n for (const issue of issues) {\n const name = issue.node?.apiIdentifier ?? issue.node?.name ?? \"Other\";\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n problems[name] ??= [];\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n problems[name]!.push({\n type: issue.node?.type ?? \"Unknown\",\n severity: issue.severity as ProblemSeverity,\n message: issue.message,\n labels: compact(issue.nodeLabels?.map((label) => label?.identifier) ?? []),\n });\n }\n return problems;\n};\n\nexport const filesyncProblemsToProblems = (filesyncProblems: FileSyncProblem[]): Problems => {\n const problems: Problems = {};\n for (const filesyncProblem of filesyncProblems) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n problems[filesyncProblem.path] ??= [];\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n problems[filesyncProblem.path]!.push({\n type: filesyncProblem.type,\n severity: filesyncProblem.level as ProblemSeverity,\n message: filesyncProblem.message,\n labels: [],\n });\n }\n return problems;\n};\n"],"names":["chalk","pluralize","compact","isGellyFile","isJavaScriptFile","isTypeScriptFile","println","sprint","sprintln","ProblemSeverity","Object","freeze","Fatal","Error","Warning","Info","sprintProblems","problems","groupedProblems","showFileTypes","sprintOptions","output","name","entries","length","problem","message","lines","split","type","filetype","line","label","labels","printProblems","options","filename","yellowBright","blue","magenta","gray","publishIssuesToProblems","issues","issue","node","apiIdentifier","push","severity","nodeLabels","map","identifier","filesyncProblemsToProblems","filesyncProblems","filesyncProblem","path","level"],"mappings":"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"}
|
|
@@ -1,52 +1,185 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { _ as _define_property } from "@swc/helpers/_/_define_property";
|
|
2
|
+
import ansiEscapes from "ansi-escapes";
|
|
3
|
+
import assert from "node:assert";
|
|
4
|
+
import EventEmitter from "node:events";
|
|
5
|
+
import process from "node:process";
|
|
6
|
+
import readline from "node:readline";
|
|
7
|
+
import { output } from "./output.js";
|
|
2
8
|
/**
|
|
3
|
-
*
|
|
9
|
+
* Inspired by `prompts`:
|
|
10
|
+
* https://github.com/terkelg/prompts/blob/e0519913ec4fcc6746bb3d97d8cd0960c3f3ffde/lib/elements/prompt.js
|
|
4
11
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
* MIT License
|
|
13
|
+
*
|
|
14
|
+
* Copyright (c) 2018 Terkel Gjervig Nielsen
|
|
15
|
+
*
|
|
16
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
18
|
+
* in the Software without restriction, including without limitation the rights
|
|
19
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
20
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
21
|
+
* furnished to do so, subject to the following conditions:
|
|
22
|
+
*
|
|
23
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
24
|
+
* copies or substantial portions of the Software.
|
|
25
|
+
*
|
|
26
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
27
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
28
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
29
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
30
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
31
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
32
|
+
* SOFTWARE.
|
|
33
|
+
*/ export class Prompt extends EventEmitter {
|
|
34
|
+
_(_str, _key) {
|
|
35
|
+
// noop
|
|
36
|
+
}
|
|
37
|
+
onRender() {
|
|
38
|
+
// noop
|
|
39
|
+
}
|
|
40
|
+
fire() {
|
|
41
|
+
this.emit("state", {
|
|
42
|
+
value: this.value,
|
|
43
|
+
aborted: this.aborted,
|
|
44
|
+
exited: this.exited
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
bell() {
|
|
48
|
+
output.writeStdout(ansiEscapes.beep);
|
|
49
|
+
}
|
|
50
|
+
render() {
|
|
51
|
+
this.onRender();
|
|
52
|
+
if (this.firstRender) {
|
|
53
|
+
this.firstRender = false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
constructor(){
|
|
57
|
+
super();
|
|
58
|
+
// state
|
|
59
|
+
_define_property(this, "value", undefined);
|
|
60
|
+
_define_property(this, "firstRender", true);
|
|
61
|
+
_define_property(this, "done", false);
|
|
62
|
+
_define_property(this, "closed", false);
|
|
63
|
+
_define_property(this, "aborted", false);
|
|
64
|
+
_define_property(this, "exited", false);
|
|
65
|
+
// methods that rely on constructor closure
|
|
66
|
+
_define_property(this, "close", void 0);
|
|
67
|
+
assert(!Prompt.active, "only one prompt can be active at a time");
|
|
68
|
+
Prompt.active = true;
|
|
69
|
+
const rl = readline.createInterface({
|
|
70
|
+
input: process.stdin,
|
|
71
|
+
escapeCodeTimeout: 50
|
|
21
72
|
});
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
process.
|
|
73
|
+
readline.emitKeypressEvents(process.stdin, rl);
|
|
74
|
+
if (process.stdin.isTTY) {
|
|
75
|
+
process.stdin.setRawMode(true);
|
|
76
|
+
}
|
|
77
|
+
const isSelect = [
|
|
78
|
+
"SelectPrompt"
|
|
79
|
+
].includes(this.constructor.name);
|
|
80
|
+
const keypress = (str, key)=>{
|
|
81
|
+
const action = getPromptAction(key, isSelect);
|
|
82
|
+
if (action === false) {
|
|
83
|
+
this._(str, key);
|
|
84
|
+
} else if (action && typeof this[action] === "function") {
|
|
85
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
86
|
+
this[action](key);
|
|
87
|
+
} else {
|
|
88
|
+
this.bell();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
this.close = ()=>{
|
|
92
|
+
process.stdin.removeListener("keypress", keypress);
|
|
93
|
+
if (process.stdin.isTTY) {
|
|
94
|
+
process.stdin.setRawMode(false);
|
|
95
|
+
}
|
|
96
|
+
rl.close();
|
|
97
|
+
this.emit(this.aborted ? "abort" : this.exited ? "exit" : "submit", this.value);
|
|
98
|
+
this.closed = true;
|
|
99
|
+
Prompt.active = false;
|
|
100
|
+
};
|
|
101
|
+
process.stdin.on("keypress", keypress);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
_define_property(Prompt, "active", false);
|
|
105
|
+
const getPromptAction = (key, isSelect)=>{
|
|
106
|
+
if (key.meta && key.name !== "escape") {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (key.ctrl) {
|
|
110
|
+
switch(key.name){
|
|
111
|
+
case "a":
|
|
112
|
+
return "first";
|
|
113
|
+
case "c":
|
|
114
|
+
case "d":
|
|
115
|
+
return "abort";
|
|
116
|
+
case "e":
|
|
117
|
+
return "last";
|
|
118
|
+
case "g":
|
|
119
|
+
return "reset";
|
|
25
120
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
121
|
+
}
|
|
122
|
+
if (isSelect) {
|
|
123
|
+
if (key.name === "j") {
|
|
124
|
+
return "down";
|
|
125
|
+
}
|
|
126
|
+
if (key.name === "k") {
|
|
127
|
+
return "up";
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
switch(key.name){
|
|
131
|
+
case "return":
|
|
132
|
+
case "enter":
|
|
133
|
+
return "submit";
|
|
134
|
+
case "backspace":
|
|
135
|
+
return "delete";
|
|
136
|
+
case "delete":
|
|
137
|
+
return "deleteForward";
|
|
138
|
+
case "abort":
|
|
139
|
+
return "abort";
|
|
140
|
+
case "escape":
|
|
141
|
+
return "exit";
|
|
142
|
+
case "tab":
|
|
143
|
+
return "next";
|
|
144
|
+
case "pagedown":
|
|
145
|
+
return "nextPage";
|
|
146
|
+
case "pageup":
|
|
147
|
+
return "prevPage";
|
|
148
|
+
case "home":
|
|
149
|
+
return "home";
|
|
150
|
+
case "end":
|
|
151
|
+
return "end";
|
|
152
|
+
case "up":
|
|
153
|
+
return "up";
|
|
154
|
+
case "down":
|
|
155
|
+
return "down";
|
|
156
|
+
case "right":
|
|
157
|
+
return "right";
|
|
158
|
+
case "left":
|
|
159
|
+
return "left";
|
|
160
|
+
default:
|
|
161
|
+
return false;
|
|
29
162
|
}
|
|
30
163
|
};
|
|
31
164
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
165
|
+
* Determine what entries should be displayed on the screen, based on the
|
|
166
|
+
* currently selected index and the maximum visible. Used in list-based
|
|
167
|
+
* prompts like `select` and `multiselect`.
|
|
34
168
|
*
|
|
35
|
-
* @param
|
|
36
|
-
* @param
|
|
37
|
-
* @param
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
type: "confirm",
|
|
44
|
-
message
|
|
45
|
-
});
|
|
46
|
-
if (!response.value) {
|
|
47
|
-
// The user pressed Ctrl+C
|
|
48
|
-
process.exit(0);
|
|
169
|
+
* @param cursor - the currently selected entry
|
|
170
|
+
* @param total - the total entries available to display
|
|
171
|
+
* @param [maxVisible] - the number of entries that can be displayed
|
|
172
|
+
*/ export const entriesToDisplay = (cursor, total, maxVisible)=>{
|
|
173
|
+
maxVisible = maxVisible || total;
|
|
174
|
+
let startIndex = Math.min(total - maxVisible, cursor - Math.floor(maxVisible / 2));
|
|
175
|
+
if (startIndex < 0) {
|
|
176
|
+
startIndex = 0;
|
|
49
177
|
}
|
|
178
|
+
const endIndex = Math.min(startIndex + maxVisible, total);
|
|
179
|
+
return {
|
|
180
|
+
startIndex,
|
|
181
|
+
endIndex
|
|
182
|
+
};
|
|
50
183
|
};
|
|
51
184
|
|
|
52
185
|
//# sourceMappingURL=prompt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/output/prompt.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../../src/services/output/prompt.ts"],"sourcesContent":["import ansiEscapes from \"ansi-escapes\";\nimport assert from \"node:assert\";\nimport EventEmitter from \"node:events\";\nimport process from \"node:process\";\nimport readline from \"node:readline\";\nimport { output } from \"./output.js\";\n\n/**\n * Inspired by `prompts`:\n * https://github.com/terkelg/prompts/blob/e0519913ec4fcc6746bb3d97d8cd0960c3f3ffde/lib/elements/prompt.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 */\nexport class Prompt extends EventEmitter {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [action: string]: any; // (key: StdinKey) => void;\n\n static active = false;\n\n // state\n value: unknown = undefined;\n firstRender = true;\n done = false;\n closed = false;\n aborted = false;\n exited = false;\n\n // methods that rely on constructor closure\n close: () => void;\n\n constructor() {\n super();\n assert(!Prompt.active, \"only one prompt can be active at a time\");\n Prompt.active = true;\n\n const rl = readline.createInterface({ input: process.stdin, escapeCodeTimeout: 50 });\n readline.emitKeypressEvents(process.stdin, rl);\n\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n }\n\n const isSelect = [\"SelectPrompt\"].includes(this.constructor.name);\n const keypress = (str: string, key: StdinKey): void => {\n const action = getPromptAction(key, isSelect);\n if (action === false) {\n this._(str, key);\n } else if (action && typeof this[action] === \"function\") {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n this[action](key);\n } else {\n this.bell();\n }\n };\n\n this.close = () => {\n process.stdin.removeListener(\"keypress\", keypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n\n rl.close();\n this.emit(this.aborted ? \"abort\" : this.exited ? \"exit\" : \"submit\", this.value);\n this.closed = true;\n Prompt.active = false;\n };\n\n process.stdin.on(\"keypress\", keypress);\n }\n\n _(_str: string, _key: StdinKey): void {\n // noop\n }\n\n onRender(): void {\n // noop\n }\n\n fire(): void {\n this.emit(\"state\", {\n value: this.value,\n aborted: this.aborted,\n exited: this.exited,\n });\n }\n\n bell(): void {\n output.writeStdout(ansiEscapes.beep);\n }\n\n render(): void {\n this.onRender();\n if (this.firstRender) {\n this.firstRender = false;\n }\n }\n}\n\nexport type PromptAction =\n | \"abort\"\n | \"exit\"\n | \"submit\"\n | \"next\"\n | \"nextPage\"\n | \"prevPage\"\n | \"home\"\n | \"end\"\n | \"up\"\n | \"down\"\n | \"right\"\n | \"left\"\n | \"reset\"\n | \"delete\"\n | \"deleteForward\"\n | \"first\"\n | \"last\";\n\nexport type StdinKey = {\n name: string;\n ctrl: boolean;\n meta: boolean;\n};\n\nconst getPromptAction = (key: StdinKey, isSelect: boolean): PromptAction | false | undefined => {\n if (key.meta && key.name !== \"escape\") {\n return;\n }\n\n if (key.ctrl) {\n switch (key.name) {\n case \"a\":\n return \"first\";\n case \"c\":\n case \"d\":\n return \"abort\";\n case \"e\":\n return \"last\";\n case \"g\":\n return \"reset\";\n }\n }\n\n if (isSelect) {\n if (key.name === \"j\") {\n return \"down\";\n }\n if (key.name === \"k\") {\n return \"up\";\n }\n }\n\n switch (key.name) {\n case \"return\":\n case \"enter\":\n return \"submit\";\n case \"backspace\":\n return \"delete\";\n case \"delete\":\n return \"deleteForward\";\n case \"abort\":\n return \"abort\";\n case \"escape\":\n return \"exit\";\n case \"tab\":\n return \"next\";\n case \"pagedown\":\n return \"nextPage\";\n case \"pageup\":\n return \"prevPage\";\n case \"home\":\n return \"home\";\n case \"end\":\n return \"end\";\n case \"up\":\n return \"up\";\n case \"down\":\n return \"down\";\n case \"right\":\n return \"right\";\n case \"left\":\n return \"left\";\n default:\n return false;\n }\n};\n\n/**\n * Determine what entries should be displayed on the screen, based on the\n * currently selected index and the maximum visible. Used in list-based\n * prompts like `select` and `multiselect`.\n *\n * @param cursor - the currently selected entry\n * @param total - the total entries available to display\n * @param [maxVisible] - the number of entries that can be displayed\n */\nexport const entriesToDisplay = (cursor: number, total: number, maxVisible: number): { startIndex: number; endIndex: number } => {\n maxVisible = maxVisible || total;\n\n let startIndex = Math.min(total - maxVisible, cursor - Math.floor(maxVisible / 2));\n if (startIndex < 0) {\n startIndex = 0;\n }\n\n const endIndex = Math.min(startIndex + maxVisible, total);\n\n return { startIndex, endIndex };\n};\n"],"names":["ansiEscapes","assert","EventEmitter","process","readline","output","Prompt","_","_str","_key","onRender","fire","emit","value","aborted","exited","bell","writeStdout","beep","render","firstRender","constructor","undefined","done","closed","close","active","rl","createInterface","input","stdin","escapeCodeTimeout","emitKeypressEvents","isTTY","setRawMode","isSelect","includes","name","keypress","str","key","action","getPromptAction","removeListener","on","meta","ctrl","entriesToDisplay","cursor","total","maxVisible","startIndex","Math","min","floor","endIndex"],"mappings":"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"}
|
|
@@ -4,23 +4,32 @@ import cleanStack from "clean-stack";
|
|
|
4
4
|
import ms from "ms";
|
|
5
5
|
import { randomUUID } from "node:crypto";
|
|
6
6
|
import os from "node:os";
|
|
7
|
+
import terminalLink from "terminal-link";
|
|
7
8
|
import { config } from "../config/config.js";
|
|
8
9
|
import { env } from "../config/env.js";
|
|
9
|
-
import {
|
|
10
|
+
import { packageJson } from "../config/package-json.js";
|
|
11
|
+
import { isAbortError } from "../util/is.js";
|
|
10
12
|
import { serializeError } from "../util/object.js";
|
|
11
13
|
import { workspaceRoot } from "../util/paths.js";
|
|
12
|
-
import {
|
|
14
|
+
import { println } from "./print.js";
|
|
15
|
+
import { sprintln } from "./sprint.js";
|
|
13
16
|
export const reportErrorAndExit = async (ctx, cause)=>{
|
|
17
|
+
if (isAbortError(cause)) {
|
|
18
|
+
ctx.log.debug("aborting without reporting error", {
|
|
19
|
+
error: cause
|
|
20
|
+
});
|
|
21
|
+
return process.exit(1);
|
|
22
|
+
}
|
|
14
23
|
ctx.log.error("reporting error and exiting", {
|
|
15
24
|
error: cause
|
|
16
25
|
});
|
|
17
26
|
try {
|
|
18
|
-
const error =
|
|
19
|
-
|
|
27
|
+
const error = GGTError.from(cause);
|
|
28
|
+
error.print();
|
|
20
29
|
if (error.isBug === IsBug.NO) {
|
|
21
30
|
return undefined;
|
|
22
31
|
}
|
|
23
|
-
Sentry.
|
|
32
|
+
Sentry.captureException(error, {
|
|
24
33
|
event_id: error.id,
|
|
25
34
|
captureContext: {
|
|
26
35
|
user: ctx.user && {
|
|
@@ -35,7 +44,7 @@ export const reportErrorAndExit = async (ctx, cause)=>{
|
|
|
35
44
|
environment: env.value,
|
|
36
45
|
platform: config.platform,
|
|
37
46
|
shell: config.shell,
|
|
38
|
-
version:
|
|
47
|
+
version: packageJson.version
|
|
39
48
|
},
|
|
40
49
|
contexts: {
|
|
41
50
|
ctx: {
|
|
@@ -44,8 +53,8 @@ export const reportErrorAndExit = async (ctx, cause)=>{
|
|
|
44
53
|
},
|
|
45
54
|
cause: error.cause ? serializeError(error.cause) : undefined,
|
|
46
55
|
app: {
|
|
47
|
-
app_name:
|
|
48
|
-
app_version:
|
|
56
|
+
app_name: packageJson.name,
|
|
57
|
+
app_version: packageJson.version
|
|
49
58
|
},
|
|
50
59
|
device: {
|
|
51
60
|
name: os.hostname(),
|
|
@@ -68,8 +77,9 @@ export const installErrorHandlers = (ctx)=>{
|
|
|
68
77
|
ctx.log.debug("installing error handlers");
|
|
69
78
|
Sentry.init({
|
|
70
79
|
dsn: "https://0c26e0d8afd94e77a88ee1c3aa9e7065@o250689.ingest.sentry.io/6703266",
|
|
71
|
-
|
|
72
|
-
|
|
80
|
+
enabled: env.productionLike && ctx.args["--telemetry"],
|
|
81
|
+
release: packageJson.version,
|
|
82
|
+
environment: packageJson.version.includes("experimental") ? "experimental" : "production"
|
|
73
83
|
});
|
|
74
84
|
const handleError = (error)=>void reportErrorAndExit(ctx, error);
|
|
75
85
|
process.once("uncaughtException", handleError);
|
|
@@ -82,28 +92,48 @@ export const IsBug = Object.freeze({
|
|
|
82
92
|
});
|
|
83
93
|
/**
|
|
84
94
|
* Base class for all errors.
|
|
85
|
-
*/ export class
|
|
95
|
+
*/ export class GGTError extends Error {
|
|
86
96
|
/**
|
|
87
|
-
* Constructs a
|
|
97
|
+
* Constructs a GGTError from an unknown cause.
|
|
88
98
|
*
|
|
89
99
|
* @param cause - The cause of the error.
|
|
90
100
|
*/ static from(cause) {
|
|
91
|
-
if (cause instanceof
|
|
101
|
+
if (cause instanceof GGTError) {
|
|
92
102
|
return cause;
|
|
93
103
|
}
|
|
94
104
|
return new UnexpectedError(cause);
|
|
95
105
|
}
|
|
96
|
-
|
|
106
|
+
sprint() {
|
|
97
107
|
let rendered = this.render();
|
|
98
108
|
if (this.isBug !== IsBug.NO) {
|
|
99
|
-
rendered
|
|
100
|
-
|
|
109
|
+
// ensure the rendered message ends with a newline
|
|
110
|
+
rendered = sprintln(rendered);
|
|
111
|
+
const thisIsABug = this.isBug === IsBug.YES ? "This is a bug" : "If you think this is a bug";
|
|
112
|
+
const issueLink = `https://github.com/gadget-inc/ggt/issues/new?template=bug_report.yml&error-id=${this.id}`;
|
|
113
|
+
if (terminalLink.isSupported) {
|
|
114
|
+
rendered += sprintln({
|
|
115
|
+
ensureEmptyLineAbove: true
|
|
116
|
+
})`
|
|
117
|
+
${thisIsABug}, ${terminalLink("click here", issueLink)} to create an issue on GitHub.
|
|
118
|
+
`;
|
|
119
|
+
} else {
|
|
120
|
+
rendered += sprintln({
|
|
121
|
+
ensureEmptyLineAbove: true
|
|
122
|
+
})`
|
|
123
|
+
${thisIsABug}, use the link below to create an issue on GitHub.
|
|
101
124
|
|
|
102
|
-
|
|
125
|
+
${issueLink}
|
|
103
126
|
`;
|
|
127
|
+
}
|
|
104
128
|
}
|
|
105
129
|
return rendered;
|
|
106
130
|
}
|
|
131
|
+
print(options) {
|
|
132
|
+
println({
|
|
133
|
+
ensureEmptyLineAbove: true,
|
|
134
|
+
...options
|
|
135
|
+
})(this.sprint());
|
|
136
|
+
}
|
|
107
137
|
constructor(message){
|
|
108
138
|
super(message);
|
|
109
139
|
/**
|
|
@@ -128,11 +158,11 @@ export const IsBug = Object.freeze({
|
|
|
128
158
|
* If this error is thrown, we almost certainly have a bug, and should
|
|
129
159
|
* either fix it or add a more specific error so that we can provide
|
|
130
160
|
* more useful information.
|
|
131
|
-
*/ export class UnexpectedError extends
|
|
161
|
+
*/ export class UnexpectedError extends GGTError {
|
|
132
162
|
render() {
|
|
133
163
|
const serialized = serializeError(this.cause);
|
|
134
164
|
const body = serialized.stack || serialized.message || this.stack;
|
|
135
|
-
return this.message + "
|
|
165
|
+
return this.message + ".\n\n" + body;
|
|
136
166
|
}
|
|
137
167
|
constructor(cause){
|
|
138
168
|
super("An unexpected error occurred");
|
|
@@ -142,5 +172,19 @@ export const IsBug = Object.freeze({
|
|
|
142
172
|
this.isBug = IsBug.YES;
|
|
143
173
|
}
|
|
144
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* An error that is expected to happen sometimes.
|
|
177
|
+
*/ export class EdgeCaseError extends GGTError {
|
|
178
|
+
render() {
|
|
179
|
+
return this.message;
|
|
180
|
+
}
|
|
181
|
+
constructor(message, cause){
|
|
182
|
+
super(message);
|
|
183
|
+
_define_property(this, "cause", void 0);
|
|
184
|
+
_define_property(this, "isBug", void 0);
|
|
185
|
+
this.cause = cause;
|
|
186
|
+
this.isBug = IsBug.MAYBE;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
145
189
|
|
|
146
190
|
//# sourceMappingURL=report.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/output/report.ts"],"sourcesContent":["import * as Sentry from \"@sentry/node\";\nimport cleanStack from \"clean-stack\";\nimport ms from \"ms\";\nimport { randomUUID } from \"node:crypto\";\nimport os from \"node:os\";\nimport type { Context } from \"../command/context.js\";\nimport { config } from \"../config/config.js\";\nimport { env } from \"../config/env.js\";\nimport { parseBoolean } from \"../util/boolean.js\";\nimport { serializeError } from \"../util/object.js\";\nimport { workspaceRoot } from \"../util/paths.js\";\nimport { sprint } from \"./sprint.js\";\n\nexport const reportErrorAndExit = async (ctx: Context, cause: unknown): Promise<never> => {\n ctx.log.error(\"reporting error and exiting\", { error: cause });\n\n try {\n const error = CLIError.from(cause);\n ctx.log.println(error.toString());\n\n if (error.isBug === IsBug.NO) {\n return undefined as never;\n }\n\n Sentry.getCurrentHub().captureException(error, {\n event_id: error.id,\n captureContext: {\n user: ctx.user && {\n id: String(ctx.user.id),\n email: ctx.user.email,\n username: ctx.user.name ?? undefined,\n },\n tags: {\n application_id: ctx.app?.id,\n arch: config.arch,\n bug: error.isBug,\n environment: env.value,\n platform: config.platform,\n shell: config.shell,\n version: config.version,\n },\n contexts: {\n ctx: {\n argv: process.argv,\n args: ctx.args,\n },\n cause: error.cause ? serializeError(error.cause) : undefined,\n app: {\n app_name: config.name,\n app_version: config.version,\n },\n device: {\n name: os.hostname(),\n family: os.type(),\n arch: os.arch(),\n },\n runtime: {\n name: process.release.name,\n version: process.version,\n },\n },\n },\n });\n\n await Sentry.flush(ms(\"2s\"));\n } finally {\n process.exit(1);\n }\n};\n\nexport const installErrorHandlers = (ctx: Context): void => {\n ctx.log.debug(\"installing error handlers\");\n\n Sentry.init({\n dsn: \"https://0c26e0d8afd94e77a88ee1c3aa9e7065@o250689.ingest.sentry.io/6703266\",\n release: config.version,\n enabled: env.productionLike && parseBoolean(process.env[\"GGT_SENTRY_ENABLED\"] ?? \"true\"),\n });\n\n const handleError = (error: unknown) => void reportErrorAndExit(ctx, error);\n process.once(\"uncaughtException\", handleError);\n process.once(\"unhandledRejection\", handleError);\n};\n\nexport const IsBug = Object.freeze({\n YES: \"yes\",\n NO: \"no\",\n MAYBE: \"maybe\",\n});\n\nexport type IsBug = (typeof IsBug)[keyof typeof IsBug];\n\n/**\n * Base class for all errors.\n */\nexport abstract class CLIError extends Error {\n /**\n * The ID for this error.\n */\n id = env.testLike ? \"00000000-0000-0000-0000-000000000000\" : randomUUID();\n\n /**\n * The underlying *thing* that caused this error.\n */\n cause?: unknown;\n\n /**\n * Assume the stack trace exists.\n */\n override stack!: string;\n\n /**\n * Indicates whether this error is considered a bug or not.\n */\n abstract isBug: IsBug;\n\n constructor(message: string) {\n super(message);\n Error.captureStackTrace(this, this.constructor);\n this.stack = cleanStack(this.stack, { pretty: true, basePath: workspaceRoot });\n }\n\n /**\n * Constructs a CLIError from an unknown cause.\n *\n * @param cause - The cause of the error.\n */\n static from(cause: unknown): CLIError {\n if (cause instanceof CLIError) {\n return cause;\n }\n return new UnexpectedError(cause);\n }\n\n override toString(): string {\n let rendered = this.render();\n\n if (this.isBug !== IsBug.NO) {\n rendered +=\n \"\\n\\n\" +\n sprint`\n ${this.isBug === IsBug.YES ? \"This is a bug\" : \"If you think this is a bug\"}, please submit an issue using the link below.\n\n https://github.com/gadget-inc/ggt/issues/new?template=bug_report.yml&error-id=${this.id}\n `;\n }\n\n return rendered;\n }\n\n /**\n * Turns this error into a user-friendly message that explains what\n * went wrong and how to fix it. A good write up of what an error\n * should look like can be found here:\n * {@link https://clig.dev/#errors}\n */\n protected abstract render(): string;\n}\n\n/**\n * Our \"catch all\" error.\n *\n * If this error is thrown, we almost certainly have a bug, and should\n * either fix it or add a more specific error so that we can provide\n * more useful information.\n */\nexport class UnexpectedError extends CLIError {\n isBug = IsBug.YES;\n\n constructor(override cause: unknown) {\n super(\"An unexpected error occurred\");\n }\n\n protected render(): string {\n const serialized = serializeError(this.cause);\n const body = serialized.stack || serialized.message || this.stack;\n return this.message + \"\\n\\n\" + body;\n }\n}\n"],"names":["Sentry","cleanStack","ms","randomUUID","os","config","env","parseBoolean","serializeError","workspaceRoot","sprint","reportErrorAndExit","ctx","cause","log","error","CLIError","from","println","toString","isBug","IsBug","NO","undefined","getCurrentHub","captureException","event_id","id","captureContext","user","String","email","username","name","tags","application_id","app","arch","bug","environment","value","platform","shell","version","contexts","argv","process","args","app_name","app_version","device","hostname","family","type","runtime","release","flush","exit","installErrorHandlers","debug","init","dsn","enabled","productionLike","handleError","once","Object","freeze","YES","MAYBE","Error","UnexpectedError","rendered","render","constructor","message","testLike","stack","captureStackTrace","pretty","basePath","serialized","body"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/services/output/report.ts"],"sourcesContent":["import * as Sentry from \"@sentry/node\";\nimport cleanStack from \"clean-stack\";\nimport ms from \"ms\";\nimport { randomUUID } from \"node:crypto\";\nimport os from \"node:os\";\nimport terminalLink from \"terminal-link\";\nimport type { Context } from \"../command/context.js\";\nimport { config } from \"../config/config.js\";\nimport { env } from \"../config/env.js\";\nimport { packageJson } from \"../config/package-json.js\";\nimport { isAbortError } from \"../util/is.js\";\nimport { serializeError } from \"../util/object.js\";\nimport { workspaceRoot } from \"../util/paths.js\";\nimport { println } from \"./print.js\";\nimport { sprintln, type SprintOptions } from \"./sprint.js\";\n\nexport const reportErrorAndExit = async (ctx: Context, cause: unknown): Promise<never> => {\n if (isAbortError(cause)) {\n ctx.log.debug(\"aborting without reporting error\", { error: cause });\n return process.exit(1);\n }\n\n ctx.log.error(\"reporting error and exiting\", { error: cause });\n\n try {\n const error = GGTError.from(cause);\n error.print();\n\n if (error.isBug === IsBug.NO) {\n return undefined as never;\n }\n\n Sentry.captureException(error, {\n event_id: error.id,\n captureContext: {\n user: ctx.user && {\n id: String(ctx.user.id),\n email: ctx.user.email,\n username: ctx.user.name ?? undefined,\n },\n tags: {\n application_id: ctx.app?.id,\n arch: config.arch,\n bug: error.isBug,\n environment: env.value,\n platform: config.platform,\n shell: config.shell,\n version: packageJson.version,\n },\n contexts: {\n ctx: {\n argv: process.argv,\n args: ctx.args,\n },\n cause: error.cause ? serializeError(error.cause) : undefined,\n app: {\n app_name: packageJson.name,\n app_version: packageJson.version,\n },\n device: {\n name: os.hostname(),\n family: os.type(),\n arch: os.arch(),\n },\n runtime: {\n name: process.release.name,\n version: process.version,\n },\n },\n },\n });\n\n await Sentry.flush(ms(\"2s\"));\n } finally {\n process.exit(1);\n }\n};\n\nexport const installErrorHandlers = (ctx: Context): void => {\n ctx.log.debug(\"installing error handlers\");\n\n Sentry.init({\n dsn: \"https://0c26e0d8afd94e77a88ee1c3aa9e7065@o250689.ingest.sentry.io/6703266\",\n enabled: env.productionLike && ctx.args[\"--telemetry\"],\n release: packageJson.version,\n environment: packageJson.version.includes(\"experimental\") ? \"experimental\" : \"production\",\n });\n\n const handleError = (error: unknown) => void reportErrorAndExit(ctx, error);\n process.once(\"uncaughtException\", handleError);\n process.once(\"unhandledRejection\", handleError);\n};\n\nexport const IsBug = Object.freeze({\n YES: \"yes\",\n NO: \"no\",\n MAYBE: \"maybe\",\n});\n\nexport type IsBug = (typeof IsBug)[keyof typeof IsBug];\n\n/**\n * Base class for all errors.\n */\nexport abstract class GGTError extends Error {\n /**\n * The ID for this error.\n */\n id = env.testLike ? \"00000000-0000-0000-0000-000000000000\" : randomUUID();\n\n /**\n * The underlying *thing* that caused this error.\n */\n cause?: unknown;\n\n /**\n * Assume the stack trace exists.\n */\n override stack!: string;\n\n /**\n * Indicates whether this error is considered a bug or not.\n */\n abstract isBug: IsBug;\n\n constructor(message: string) {\n super(message);\n Error.captureStackTrace(this, this.constructor);\n this.stack = cleanStack(this.stack, { pretty: true, basePath: workspaceRoot });\n }\n\n /**\n * Constructs a GGTError from an unknown cause.\n *\n * @param cause - The cause of the error.\n */\n static from(cause: unknown): GGTError {\n if (cause instanceof GGTError) {\n return cause;\n }\n return new UnexpectedError(cause);\n }\n\n sprint(): string {\n let rendered = this.render();\n\n if (this.isBug !== IsBug.NO) {\n // ensure the rendered message ends with a newline\n rendered = sprintln(rendered);\n\n const thisIsABug = this.isBug === IsBug.YES ? \"This is a bug\" : \"If you think this is a bug\";\n const issueLink = `https://github.com/gadget-inc/ggt/issues/new?template=bug_report.yml&error-id=${this.id}`;\n\n if (terminalLink.isSupported) {\n rendered += sprintln({ ensureEmptyLineAbove: true })`\n ${thisIsABug}, ${terminalLink(\"click here\", issueLink)} to create an issue on GitHub.\n `;\n } else {\n rendered += sprintln({ ensureEmptyLineAbove: true })`\n ${thisIsABug}, use the link below to create an issue on GitHub.\n\n ${issueLink}\n `;\n }\n }\n\n return rendered;\n }\n\n print(options?: SprintOptions): void {\n println({ ensureEmptyLineAbove: true, ...options })(this.sprint());\n }\n\n /**\n * Turns this error into a user-friendly message that explains what\n * went wrong and how to fix it. A good write up of what an error\n * should look like can be found here:\n * {@link https://clig.dev/#errors}\n */\n protected abstract render(): string;\n}\n\n/**\n * Our \"catch all\" error.\n *\n * If this error is thrown, we almost certainly have a bug, and should\n * either fix it or add a more specific error so that we can provide\n * more useful information.\n */\nexport class UnexpectedError extends GGTError {\n isBug = IsBug.YES;\n\n constructor(override cause: unknown) {\n super(\"An unexpected error occurred\");\n }\n\n protected render(): string {\n const serialized = serializeError(this.cause);\n const body = serialized.stack || serialized.message || this.stack;\n return this.message + \".\\n\\n\" + body;\n }\n}\n\n/**\n * An error that is expected to happen sometimes.\n */\nexport class EdgeCaseError extends GGTError {\n isBug = IsBug.MAYBE;\n\n constructor(\n message: string,\n override cause?: unknown,\n ) {\n super(message);\n }\n\n protected render(): string {\n return this.message;\n }\n}\n"],"names":["Sentry","cleanStack","ms","randomUUID","os","terminalLink","config","env","packageJson","isAbortError","serializeError","workspaceRoot","println","sprintln","reportErrorAndExit","ctx","cause","log","debug","error","process","exit","GGTError","from","print","isBug","IsBug","NO","undefined","captureException","event_id","id","captureContext","user","String","email","username","name","tags","application_id","app","arch","bug","environment","value","platform","shell","version","contexts","argv","args","app_name","app_version","device","hostname","family","type","runtime","release","flush","installErrorHandlers","init","dsn","enabled","productionLike","includes","handleError","once","Object","freeze","YES","MAYBE","Error","UnexpectedError","sprint","rendered","render","thisIsABug","issueLink","isSupported","ensureEmptyLineAbove","options","constructor","message","testLike","stack","captureStackTrace","pretty","basePath","serialized","body","EdgeCaseError"],"mappings":"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"}
|