@gadgetinc/ggt 0.4.6 → 0.4.8
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 +1 -1
- package/bin/dev.js +2 -1
- package/bin/run.js +3 -1
- package/lib/__generated__/graphql.js.map +1 -1
- package/lib/commands/deploy.js +43 -49
- package/lib/commands/deploy.js.map +1 -1
- package/lib/commands/list.js +7 -11
- package/lib/commands/list.js.map +1 -1
- package/lib/commands/login.js +8 -12
- package/lib/commands/login.js.map +1 -1
- package/lib/commands/logout.js +3 -7
- package/lib/commands/logout.js.map +1 -1
- package/lib/commands/root.js +17 -43
- package/lib/commands/root.js.map +1 -1
- package/lib/commands/sync.js +10 -39
- package/lib/commands/sync.js.map +1 -1
- package/lib/commands/version.js +2 -6
- package/lib/commands/version.js.map +1 -1
- package/lib/commands/whoami.js +5 -9
- package/lib/commands/whoami.js.map +1 -1
- package/lib/ggt.js +40 -0
- package/lib/ggt.js.map +1 -0
- package/lib/services/app/app.js +8 -6
- package/lib/services/app/app.js.map +1 -1
- package/lib/services/app/edit/client.js +176 -0
- package/lib/services/app/edit/client.js.map +1 -0
- package/lib/services/app/edit/edit.js +155 -0
- package/lib/services/app/edit/edit.js.map +1 -0
- package/lib/services/app/edit/error.js +65 -0
- package/lib/services/app/edit/error.js.map +1 -0
- package/lib/services/app/edit/operation.js +87 -0
- package/lib/services/app/edit/operation.js.map +1 -0
- package/lib/services/command/arg.js +5 -5
- package/lib/services/command/arg.js.map +1 -1
- package/lib/services/command/command.js +23 -5
- package/lib/services/command/command.js.map +1 -1
- package/lib/services/command/context.js +123 -36
- package/lib/services/command/context.js.map +1 -1
- package/lib/services/filesync/changes.js +7 -9
- package/lib/services/filesync/changes.js.map +1 -1
- package/lib/services/filesync/conflicts.js +11 -9
- package/lib/services/filesync/conflicts.js.map +1 -1
- package/lib/services/filesync/directory.js +2 -2
- package/lib/services/filesync/directory.js.map +1 -1
- package/lib/services/filesync/filesync.js +187 -96
- package/lib/services/filesync/filesync.js.map +1 -1
- package/lib/services/filesync/hashes.js +18 -15
- package/lib/services/filesync/hashes.js.map +1 -1
- package/lib/services/http/auth.js +4 -4
- package/lib/services/http/auth.js.map +1 -1
- package/lib/services/http/http.js +54 -27
- package/lib/services/http/http.js.map +1 -1
- package/lib/services/output/log/logger.js +11 -6
- package/lib/services/output/log/logger.js.map +1 -1
- package/lib/services/output/log/printer.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/notify.js +3 -7
- package/lib/services/output/notify.js.map +1 -1
- package/lib/services/output/prompt.js +11 -11
- package/lib/services/output/prompt.js.map +1 -1
- package/lib/services/output/report.js +51 -67
- package/lib/services/output/report.js.map +1 -1
- package/lib/services/output/update.js +9 -10
- package/lib/services/output/update.js.map +1 -1
- package/lib/services/user/user.js +19 -25
- package/lib/services/user/user.js.map +1 -1
- package/lib/services/util/collection.js +1 -1
- package/lib/services/util/collection.js.map +1 -1
- package/lib/services/util/function.js +29 -11
- package/lib/services/util/function.js.map +1 -1
- package/lib/services/util/is.js +19 -1
- package/lib/services/util/is.js.map +1 -1
- package/lib/services/util/number.js +3 -3
- package/lib/services/util/number.js.map +1 -1
- package/lib/services/util/object.js +4 -4
- package/lib/services/util/object.js.map +1 -1
- package/lib/services/util/paths.js +4 -4
- package/lib/services/util/paths.js.map +1 -1
- package/lib/services/util/types.js +5 -0
- package/lib/services/util/types.js.map +1 -0
- package/npm-shrinkwrap.json +586 -418
- package/package.json +17 -15
- package/lib/main.js +0 -8
- package/lib/main.js.map +0 -1
- package/lib/services/app/edit-graphql.js +0 -389
- package/lib/services/app/edit-graphql.js.map +0 -1
package/lib/commands/root.js
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import arg from "arg";
|
|
2
|
-
import
|
|
3
|
-
import { AvailableCommands, importCommand, isAvailableCommand } from "../services/command/command.js";
|
|
4
|
-
import { Context } from "../services/command/context.js";
|
|
2
|
+
import { Commands, importCommand, isAvailableCommand } from "../services/command/command.js";
|
|
5
3
|
import { verbosityToLevel } from "../services/output/log/level.js";
|
|
6
|
-
import { createLogger } from "../services/output/log/logger.js";
|
|
7
4
|
import { reportErrorAndExit } from "../services/output/report.js";
|
|
8
5
|
import { sprint } from "../services/output/sprint.js";
|
|
9
6
|
import { warnIfUpdateAvailable } from "../services/output/update.js";
|
|
10
7
|
import { sortBySimilar } from "../services/util/collection.js";
|
|
11
8
|
import { isNil } from "../services/util/is.js";
|
|
12
|
-
const
|
|
13
|
-
name: "root"
|
|
14
|
-
});
|
|
15
|
-
export const rootUsage = ()=>sprint`
|
|
9
|
+
export const usage = ()=>sprint`
|
|
16
10
|
The command-line interface for Gadget
|
|
17
11
|
|
|
18
12
|
{bold USAGE}
|
|
@@ -33,7 +27,7 @@ export const rootUsage = ()=>sprint`
|
|
|
33
27
|
|
|
34
28
|
For more information on a specific command, use 'ggt [COMMAND] --help'
|
|
35
29
|
`;
|
|
36
|
-
export const
|
|
30
|
+
export const args = {
|
|
37
31
|
"--help": {
|
|
38
32
|
type: Boolean,
|
|
39
33
|
alias: "-h"
|
|
@@ -49,26 +43,28 @@ export const rootArgs = {
|
|
|
49
43
|
type: Boolean
|
|
50
44
|
}
|
|
51
45
|
};
|
|
52
|
-
export const command = async ()=>{
|
|
53
|
-
const ctx =
|
|
46
|
+
export const command = async (parent)=>{
|
|
47
|
+
const ctx = parent.child({
|
|
48
|
+
name: "root",
|
|
49
|
+
parse: args,
|
|
54
50
|
argv: process.argv.slice(2),
|
|
55
51
|
permissive: true
|
|
56
52
|
});
|
|
57
|
-
await warnIfUpdateAvailable();
|
|
58
53
|
if (ctx.args["--json"]) {
|
|
59
54
|
process.env["GGT_LOG_FORMAT"] = "json";
|
|
60
55
|
}
|
|
61
56
|
if (ctx.args["--verbose"]) {
|
|
62
57
|
process.env["GGT_LOG_LEVEL"] = verbosityToLevel(ctx.args["--verbose"]).toString();
|
|
63
58
|
}
|
|
59
|
+
await warnIfUpdateAvailable(ctx);
|
|
64
60
|
const cmd = ctx.args._.shift();
|
|
65
61
|
if (isNil(cmd)) {
|
|
66
|
-
log.println(
|
|
62
|
+
ctx.log.println(usage());
|
|
67
63
|
process.exit(0);
|
|
68
64
|
}
|
|
69
65
|
if (!isAvailableCommand(cmd)) {
|
|
70
|
-
const [closest] = sortBySimilar(cmd,
|
|
71
|
-
log.println`
|
|
66
|
+
const [closest] = sortBySimilar(cmd, Commands);
|
|
67
|
+
ctx.log.println`
|
|
72
68
|
Unknown command {yellow ${cmd}}
|
|
73
69
|
|
|
74
70
|
Did you mean {blueBright ${closest}}?
|
|
@@ -77,40 +73,18 @@ export const command = async ()=>{
|
|
|
77
73
|
`;
|
|
78
74
|
process.exit(1);
|
|
79
75
|
}
|
|
80
|
-
const
|
|
76
|
+
const subcommand = await importCommand(cmd);
|
|
81
77
|
if (ctx.args["--help"]) {
|
|
82
|
-
log.println(usage());
|
|
78
|
+
ctx.log.println(subcommand.usage());
|
|
83
79
|
process.exit(0);
|
|
84
80
|
}
|
|
85
81
|
try {
|
|
86
|
-
await command(ctx.
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
await subcommand.command(ctx.child({
|
|
83
|
+
name: cmd,
|
|
84
|
+
parse: subcommand.args
|
|
89
85
|
}));
|
|
90
86
|
} catch (error) {
|
|
91
|
-
await reportErrorAndExit(error);
|
|
92
|
-
}
|
|
93
|
-
for (const signal of [
|
|
94
|
-
"SIGINT",
|
|
95
|
-
"SIGTERM"
|
|
96
|
-
]){
|
|
97
|
-
process.once(signal, ()=>{
|
|
98
|
-
log.trace("received signal", {
|
|
99
|
-
signal
|
|
100
|
-
});
|
|
101
|
-
log.println` Stopping... {gray Press Ctrl+C again to force}`;
|
|
102
|
-
ctx.abort();
|
|
103
|
-
// when ggt is run via npx, and the user presses ctrl+c, npx
|
|
104
|
-
// sends sigint twice in quick succession. in order to prevent
|
|
105
|
-
// the second sigint from triggering the force exit listener,
|
|
106
|
-
// we wait a bit before registering it
|
|
107
|
-
setTimeout(()=>{
|
|
108
|
-
process.once(signal, ()=>{
|
|
109
|
-
log.println(" Exiting immediately");
|
|
110
|
-
process.exit(1);
|
|
111
|
-
});
|
|
112
|
-
}, ms("100ms")).unref();
|
|
113
|
-
});
|
|
87
|
+
await reportErrorAndExit(ctx, error);
|
|
114
88
|
}
|
|
115
89
|
};
|
|
116
90
|
|
package/lib/commands/root.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/root.ts"],"sourcesContent":["import arg from \"arg\";\nimport
|
|
1
|
+
{"version":3,"sources":["../../src/commands/root.ts"],"sourcesContent":["import arg from \"arg\";\nimport type { EmptyObject } from \"type-fest\";\nimport type { ArgsDefinition } from \"../services/command/arg.js\";\nimport { Commands, importCommand, isAvailableCommand, type Command, type Usage } from \"../services/command/command.js\";\nimport { verbosityToLevel } from \"../services/output/log/level.js\";\nimport { reportErrorAndExit } from \"../services/output/report.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { warnIfUpdateAvailable } from \"../services/output/update.js\";\nimport { sortBySimilar } from \"../services/util/collection.js\";\nimport { isNil } from \"../services/util/is.js\";\n\nexport const usage: Usage = () => sprint`\n The command-line interface for Gadget\n\n {bold USAGE}\n ggt [COMMAND]\n\n {bold COMMANDS}\n sync Sync your Gadget application's source code\n list List your apps\n login Log in to your account\n logout Log out of your account\n whoami Print the currently logged in account\n version Print the version of ggt\n\n {bold FLAGS}\n -h, --help Print command's usage\n -v, --verbose Print verbose output\n --json Print output as JSON\n\n For more information on a specific command, use 'ggt [COMMAND] --help'\n`;\n\nexport const args = {\n \"--help\": { type: Boolean, alias: \"-h\" },\n \"--verbose\": { type: arg.COUNT, alias: [\"-v\", \"--debug\"] },\n \"--json\": { type: Boolean },\n} satisfies ArgsDefinition;\n\nexport type RootArgs = typeof args;\n\nexport const command: Command<EmptyObject, EmptyObject> = async (parent): Promise<void> => {\n const ctx = parent.child({\n name: \"root\",\n parse: args,\n argv: process.argv.slice(2),\n permissive: true,\n });\n\n if (ctx.args[\"--json\"]) {\n process.env[\"GGT_LOG_FORMAT\"] = \"json\";\n }\n\n if (ctx.args[\"--verbose\"]) {\n process.env[\"GGT_LOG_LEVEL\"] = verbosityToLevel(ctx.args[\"--verbose\"]).toString();\n }\n\n await warnIfUpdateAvailable(ctx);\n\n const cmd = ctx.args._.shift();\n if (isNil(cmd)) {\n ctx.log.println(usage());\n process.exit(0);\n }\n\n if (!isAvailableCommand(cmd)) {\n const [closest] = sortBySimilar(cmd, Commands);\n ctx.log.println`\n Unknown command {yellow ${cmd}}\n\n Did you mean {blueBright ${closest}}?\n\n Run {gray ggt --help} for usage\n `;\n process.exit(1);\n }\n\n const subcommand = await importCommand(cmd);\n\n if (ctx.args[\"--help\"]) {\n ctx.log.println(subcommand.usage());\n process.exit(0);\n }\n\n try {\n await subcommand.command(ctx.child({ name: cmd, parse: subcommand.args }));\n } catch (error) {\n await reportErrorAndExit(ctx, error);\n }\n};\n"],"names":["arg","Commands","importCommand","isAvailableCommand","verbosityToLevel","reportErrorAndExit","sprint","warnIfUpdateAvailable","sortBySimilar","isNil","usage","args","type","Boolean","alias","COUNT","command","parent","ctx","child","name","parse","argv","process","slice","permissive","env","toString","cmd","_","shift","log","println","exit","closest","subcommand","error"],"mappings":"AAAA,OAAOA,SAAS,MAAM;AAGtB,SAASC,QAAQ,EAAEC,aAAa,EAAEC,kBAAkB,QAAkC,iCAAiC;AACvH,SAASC,gBAAgB,QAAQ,kCAAkC;AACnE,SAASC,kBAAkB,QAAQ,+BAA+B;AAClE,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,qBAAqB,QAAQ,+BAA+B;AACrE,SAASC,aAAa,QAAQ,iCAAiC;AAC/D,SAASC,KAAK,QAAQ,yBAAyB;AAE/C,OAAO,MAAMC,QAAe,IAAMJ,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;AAoBzC,CAAC,CAAC;AAEF,OAAO,MAAMK,OAAO;IAClB,UAAU;QAAEC,MAAMC;QAASC,OAAO;IAAK;IACvC,aAAa;QAAEF,MAAMZ,IAAIe,KAAK;QAAED,OAAO;YAAC;YAAM;SAAU;IAAC;IACzD,UAAU;QAAEF,MAAMC;IAAQ;AAC5B,EAA2B;AAI3B,OAAO,MAAMG,UAA6C,OAAOC;IAC/D,MAAMC,MAAMD,OAAOE,KAAK,CAAC;QACvBC,MAAM;QACNC,OAAOV;QACPW,MAAMC,QAAQD,IAAI,CAACE,KAAK,CAAC;QACzBC,YAAY;IACd;IAEA,IAAIP,IAAIP,IAAI,CAAC,SAAS,EAAE;QACtBY,QAAQG,GAAG,CAAC,iBAAiB,GAAG;IAClC;IAEA,IAAIR,IAAIP,IAAI,CAAC,YAAY,EAAE;QACzBY,QAAQG,GAAG,CAAC,gBAAgB,GAAGtB,iBAAiBc,IAAIP,IAAI,CAAC,YAAY,EAAEgB,QAAQ;IACjF;IAEA,MAAMpB,sBAAsBW;IAE5B,MAAMU,MAAMV,IAAIP,IAAI,CAACkB,CAAC,CAACC,KAAK;IAC5B,IAAIrB,MAAMmB,MAAM;QACdV,IAAIa,GAAG,CAACC,OAAO,CAACtB;QAChBa,QAAQU,IAAI,CAAC;IACf;IAEA,IAAI,CAAC9B,mBAAmByB,MAAM;QAC5B,MAAM,CAACM,QAAQ,GAAG1B,cAAcoB,KAAK3B;QACrCiB,IAAIa,GAAG,CAACC,OAAO,CAAC;8BACU,EAAEJ,IAAI;;+BAEL,EAAEM,QAAQ;;;IAGrC,CAAC;QACDX,QAAQU,IAAI,CAAC;IACf;IAEA,MAAME,aAAa,MAAMjC,cAAc0B;IAEvC,IAAIV,IAAIP,IAAI,CAAC,SAAS,EAAE;QACtBO,IAAIa,GAAG,CAACC,OAAO,CAACG,WAAWzB,KAAK;QAChCa,QAAQU,IAAI,CAAC;IACf;IAEA,IAAI;QACF,MAAME,WAAWnB,OAAO,CAACE,IAAIC,KAAK,CAAC;YAAEC,MAAMQ;YAAKP,OAAOc,WAAWxB,IAAI;QAAC;IACzE,EAAE,OAAOyB,OAAO;QACd,MAAM/B,mBAAmBa,KAAKkB;IAChC;AACF,EAAE"}
|
package/lib/commands/sync.js
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
import dayjs from "dayjs";
|
|
2
|
-
import { execa } from "execa";
|
|
3
2
|
import ms from "ms";
|
|
4
3
|
import path from "node:path";
|
|
5
4
|
import Watcher from "watcher";
|
|
6
5
|
import which from "which";
|
|
7
|
-
import { AppArg } from "../services/app/arg.js";
|
|
8
6
|
import { config } from "../services/config/config.js";
|
|
9
7
|
import { Changes } from "../services/filesync/changes.js";
|
|
10
8
|
import { YarnNotFoundError } from "../services/filesync/error.js";
|
|
11
|
-
import {
|
|
9
|
+
import { FileSync, FileSyncArgs } from "../services/filesync/filesync.js";
|
|
12
10
|
import { notify } from "../services/output/notify.js";
|
|
13
11
|
import { reportErrorAndExit } from "../services/output/report.js";
|
|
14
12
|
import { sprint } from "../services/output/sprint.js";
|
|
15
|
-
import { getUserOrLogin } from "../services/user/user.js";
|
|
16
13
|
import { debounce } from "../services/util/function.js";
|
|
17
14
|
import { isAbortError } from "../services/util/is.js";
|
|
18
15
|
export const usage = ()=>sprint`
|
|
@@ -86,13 +83,8 @@ export const usage = ()=>sprint`
|
|
|
86
83
|
Goodbye!
|
|
87
84
|
`;
|
|
88
85
|
export const args = {
|
|
89
|
-
|
|
90
|
-
type: AppArg,
|
|
91
|
-
alias: "-a"
|
|
92
|
-
},
|
|
93
|
-
"--force": Boolean,
|
|
86
|
+
...FileSyncArgs,
|
|
94
87
|
"--once": Boolean,
|
|
95
|
-
"--prefer": ConflictPreferenceArg,
|
|
96
88
|
"--file-push-delay": {
|
|
97
89
|
type: Number,
|
|
98
90
|
default: ms("100ms")
|
|
@@ -117,24 +109,17 @@ export const args = {
|
|
|
117
109
|
/**
|
|
118
110
|
* Runs the sync process until it is stopped or an error occurs.
|
|
119
111
|
*/ export const command = async (ctx)=>{
|
|
120
|
-
const filesync = await FileSync.init({
|
|
121
|
-
user: await getUserOrLogin(),
|
|
122
|
-
dir: ctx.args._[0],
|
|
123
|
-
app: ctx.args["--app"],
|
|
124
|
-
force: ctx.args["--force"]
|
|
125
|
-
});
|
|
126
|
-
await filesync.sync({
|
|
127
|
-
preference: ctx.args["--prefer"]
|
|
128
|
-
});
|
|
129
|
-
if (ctx.args["--once"]) {
|
|
130
|
-
ctx.log.println("Done!");
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
112
|
if (!which.sync("yarn", {
|
|
134
113
|
nothrow: true
|
|
135
114
|
})) {
|
|
136
115
|
throw new YarnNotFoundError();
|
|
137
116
|
}
|
|
117
|
+
const filesync = await FileSync.init(ctx);
|
|
118
|
+
await filesync.sync();
|
|
119
|
+
if (ctx.args["--once"]) {
|
|
120
|
+
ctx.log.println("Done!");
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
138
123
|
/**
|
|
139
124
|
* A list of filepaths that have changed because we (this ggt process)
|
|
140
125
|
* modified them. This is used to avoid reacting to filesystem events
|
|
@@ -168,20 +153,6 @@ export const args = {
|
|
|
168
153
|
dir = path.dirname(dir);
|
|
169
154
|
}
|
|
170
155
|
}
|
|
171
|
-
},
|
|
172
|
-
afterChanges: async ({ changes })=>{
|
|
173
|
-
if (changes.has("yarn.lock")) {
|
|
174
|
-
await execa("yarn", [
|
|
175
|
-
"install",
|
|
176
|
-
"--check-files"
|
|
177
|
-
], {
|
|
178
|
-
cwd: filesync.directory.path
|
|
179
|
-
}).catch((error)=>{
|
|
180
|
-
ctx.log.error("yarn install failed", {
|
|
181
|
-
error
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
156
|
}
|
|
186
157
|
});
|
|
187
158
|
/**
|
|
@@ -302,11 +273,11 @@ export const args = {
|
|
|
302
273
|
ctx.log.printlns("Goodbye!");
|
|
303
274
|
return;
|
|
304
275
|
}
|
|
305
|
-
notify({
|
|
276
|
+
notify(ctx, {
|
|
306
277
|
subtitle: "Uh oh!",
|
|
307
278
|
message: "An error occurred while syncing files"
|
|
308
279
|
});
|
|
309
|
-
await reportErrorAndExit(reason);
|
|
280
|
+
await reportErrorAndExit(ctx, reason);
|
|
310
281
|
});
|
|
311
282
|
};
|
|
312
283
|
|
package/lib/commands/sync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/sync.ts"],"sourcesContent":["import dayjs from \"dayjs\";\nimport { execa } from \"execa\";\nimport ms from \"ms\";\nimport path from \"node:path\";\nimport Watcher from \"watcher\";\nimport which from \"which\";\nimport { AppArg } from \"../services/app/arg.js\";\nimport type { ArgsSpec } from \"../services/command/arg.js\";\nimport type { Command, Usage } from \"../services/command/command.js\";\nimport { config } from \"../services/config/config.js\";\nimport { Changes } from \"../services/filesync/changes.js\";\nimport { YarnNotFoundError } from \"../services/filesync/error.js\";\nimport { ConflictPreferenceArg, FileSync } from \"../services/filesync/filesync.js\";\nimport { notify } from \"../services/output/notify.js\";\nimport { reportErrorAndExit } from \"../services/output/report.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { getUserOrLogin } from \"../services/user/user.js\";\nimport { debounce } from \"../services/util/function.js\";\nimport { isAbortError } from \"../services/util/is.js\";\n\nexport const usage: Usage = () => sprint`\n Sync your Gadget environment's source code with your local filesystem.\n\n {bold USAGE}\n ggt sync [DIRECTORY]\n\n {bold ARGUMENTS}\n DIRECTORY The directory to sync files to (default: \".\")\n\n {bold FLAGS}\n -a, --app=<name> The Gadget application to sync files to\n --prefer=<filesystem> Prefer \"local\" or \"gadget\" conflicting changes\n --once Sync once and exit\n --force Sync regardless of local filesystem state\n\n {bold DESCRIPTION}\n Sync allows you to synchronize your Gadget application's source\n code with your local filesystem.\n\n While ggt sync is running, local file changes are immediately\n reflected within Gadget, while files that are changed in Gadget are\n immediately saved to your local filesystem.\n\n Ideal for:\n • Local development with editors like VSCode\n • Storing source code in a Git repository like GitHub\n\n Sync looks for a \".ignore\" file to exclude certain files/directories\n from being synced. The format is identical to Git's.\n\n These files are always ignored:\n • .DS_Store\n • .gadget\n • .git\n • node_modules\n\n Note:\n • Sync only works with your development environment\n • Avoid deleting/moving all your files while sync is running\n • Gadget only supports Yarn v1 for dependency installation\n\n {bold EXAMPLE}\n $ ggt sync ~/gadget/example --app example\n\n App example\n Editor https://example.gadget.app/edit\n Playground https://example.gadget.app/api/graphql/playground\n Docs https://docs.gadget.dev/api/example\n\n Endpoints\n • https://example.gadget.app\n • https://example--development.gadget.app\n\n Watching for file changes... {gray Press Ctrl+C to stop}\n\n → Sent {gray 09:06:25 AM}\n {greenBright routes/GET-hello.js + created}\n\n → Sent {gray 09:06:49 AM}\n {blueBright routes/GET-hello.js ± updated}\n\n ← Received {gray 09:06:54 AM}\n {blueBright routes/GET-hello.js ± updated}\n\n ← Received {gray 09:06:56 AM}\n {redBright routes/GET-hello.js - deleted}\n ^C Stopping... {gray press Ctrl+C again to force}\n\n Goodbye!\n`;\n\nexport const args = {\n \"--app\": { type: AppArg, alias: \"-a\" },\n \"--force\": Boolean,\n \"--once\": Boolean,\n \"--prefer\": ConflictPreferenceArg,\n \"--file-push-delay\": { type: Number, default: ms(\"100ms\") },\n \"--file-watch-debounce\": { type: Number, default: ms(\"300ms\") },\n \"--file-watch-poll-interval\": { type: Number, default: ms(\"3s\") },\n \"--file-watch-poll-timeout\": { type: Number, default: ms(\"20s\") },\n \"--file-watch-rename-timeout\": { type: Number, default: ms(\"1.25s\") },\n} satisfies ArgsSpec;\n\n/**\n * Runs the sync process until it is stopped or an error occurs.\n */\nexport const command: Command<typeof args> = async (ctx) => {\n const filesync = await FileSync.init({\n user: await getUserOrLogin(),\n dir: ctx.args._[0],\n app: ctx.args[\"--app\"],\n force: ctx.args[\"--force\"],\n });\n\n await filesync.sync({ preference: ctx.args[\"--prefer\"] });\n\n if (ctx.args[\"--once\"]) {\n ctx.log.println(\"Done!\");\n return;\n }\n\n if (!which.sync(\"yarn\", { nothrow: true })) {\n throw new YarnNotFoundError();\n }\n\n /**\n * A list of filepaths that have changed because we (this ggt process)\n * modified them. This is used to avoid reacting to filesystem events\n * that we caused, which would cause an infinite loop.\n */\n const recentWritesToLocalFilesystem = new Map<string, number>();\n\n const clearRecentWritesInterval = setInterval(() => {\n for (const [path, timestamp] of recentWritesToLocalFilesystem) {\n if (dayjs().isAfter(timestamp + ms(\"5s\"))) {\n // this change should have been seen by now\n recentWritesToLocalFilesystem.delete(path);\n }\n }\n }, ms(\"1s\")).unref();\n\n /**\n * Subscribe to file changes on Gadget and apply them to the local\n * filesystem.\n */\n const unsubscribeFromGadgetChanges = filesync.subscribeToGadgetChanges({\n onError: (error) => ctx.abort(error),\n beforeChanges: ({ changed, deleted }) => {\n // add all the files and directories we're about to touch to\n // recentWritesToLocalFilesystem so that we don't send them back\n // to Gadget\n for (const filepath of [...changed, ...deleted]) {\n recentWritesToLocalFilesystem.set(filepath, Date.now());\n\n let dir = path.dirname(filepath);\n while (dir !== \".\") {\n recentWritesToLocalFilesystem.set(dir + \"/\", Date.now());\n dir = path.dirname(dir);\n }\n }\n },\n afterChanges: async ({ changes }) => {\n if (changes.has(\"yarn.lock\")) {\n await execa(\"yarn\", [\"install\", \"--check-files\"], { cwd: filesync.directory.path }).catch((error) => {\n ctx.log.error(\"yarn install failed\", { error });\n });\n }\n },\n });\n\n /**\n * A buffer of local file changes to send to Gadget.\n */\n const localChangesBuffer = new Changes();\n\n /**\n * A debounced function that sends the local file changes to Gadget.\n */\n const sendChangesToGadget = debounce(ctx.args[\"--file-push-delay\"], () => {\n const changes = new Changes(localChangesBuffer.entries());\n localChangesBuffer.clear();\n filesync.sendChangesToGadget({ changes }).catch((error) => ctx.abort(error));\n });\n\n ctx.log.debug(\"watching\", { path: filesync.directory.path });\n\n /**\n * Watches the local filesystem for changes.\n */\n const fileWatcher = new Watcher(\n filesync.directory.path,\n {\n // don't emit an event for every watched file on boot\n ignoreInitial: true,\n // don't emit changes to .gadget/ files because they're readonly (Gadget manages them)\n ignore: (path: string) => filesync.directory.relative(path).startsWith(\".gadget\") || filesync.directory.ignores(path),\n renameDetection: true,\n recursive: true,\n debounce: ctx.args[\"--file-watch-debounce\"],\n pollingInterval: ctx.args[\"--file-watch-poll-interval\"],\n pollingTimeout: ctx.args[\"--file-watch-poll-timeout\"],\n renameTimeout: ctx.args[\"--file-watch-rename-timeout\"],\n },\n (event: string, absolutePath: string, renamedPath: string) => {\n const filepath = event === \"rename\" || event === \"renameDir\" ? renamedPath : absolutePath;\n const isDirectory = event === \"renameDir\" || event === \"addDir\" || event === \"unlinkDir\";\n const normalizedPath = filesync.directory.normalize(filepath, isDirectory);\n\n ctx.log.trace(\"file event\", { event, isDirectory, path: normalizedPath });\n\n if (filepath === filesync.directory.absolute(\".ignore\")) {\n filesync.directory.loadIgnoreFile().catch((error) => ctx.abort(error));\n } else if (filesync.directory.ignores(filepath)) {\n return;\n }\n\n if (recentWritesToLocalFilesystem.delete(normalizedPath)) {\n ctx.log.trace(\"ignoring event because we caused it\", { event, path: normalizedPath });\n return;\n }\n\n switch (event) {\n case \"add\":\n case \"addDir\":\n localChangesBuffer.set(normalizedPath, { type: \"create\" });\n break;\n case \"rename\":\n case \"renameDir\": {\n const oldNormalizedPath = filesync.directory.normalize(absolutePath, isDirectory);\n localChangesBuffer.set(normalizedPath, { type: \"create\", oldPath: oldNormalizedPath });\n break;\n }\n case \"change\": {\n localChangesBuffer.set(normalizedPath, { type: \"update\" });\n break;\n }\n case \"unlink\":\n case \"unlinkDir\": {\n localChangesBuffer.set(normalizedPath, { type: \"delete\" });\n break;\n }\n }\n\n sendChangesToGadget();\n },\n ).once(\"error\", (error) => ctx.abort(error));\n\n ctx.log.printlns`\n ggt v${config.version}\n\n App ${filesync.app.slug}\n Editor https://${filesync.app.slug}.gadget.app/edit\n Playground https://${filesync.app.slug}.gadget.app/api/graphql/playground\n Docs https://docs.gadget.dev/api/${filesync.app.slug}\n\n Endpoints ${\n filesync.app.hasSplitEnvironments\n ? `\n • https://${filesync.app.primaryDomain}\n • https://${filesync.app.slug}--development.gadget.app`\n : `\n • https://${filesync.app.primaryDomain}`\n }\n\n Watching for file changes... {gray Press Ctrl+C to stop}\n `;\n\n ctx.onAbort(async (reason) => {\n ctx.log.info(\"stopping\", { reason });\n\n unsubscribeFromGadgetChanges();\n fileWatcher.close();\n clearInterval(clearRecentWritesInterval);\n sendChangesToGadget.flush();\n\n try {\n await filesync.idle();\n } catch (error) {\n ctx.log.error(\"error while waiting for idle\", { error });\n }\n\n if (isAbortError(reason)) {\n ctx.log.printlns(\"Goodbye!\");\n return;\n }\n\n notify({ subtitle: \"Uh oh!\", message: \"An error occurred while syncing files\" });\n await reportErrorAndExit(reason);\n });\n};\n"],"names":["dayjs","execa","ms","path","Watcher","which","AppArg","config","Changes","YarnNotFoundError","ConflictPreferenceArg","FileSync","notify","reportErrorAndExit","sprint","getUserOrLogin","debounce","isAbortError","usage","args","type","alias","Boolean","Number","default","command","ctx","filesync","init","user","dir","_","app","force","sync","preference","log","println","nothrow","recentWritesToLocalFilesystem","Map","clearRecentWritesInterval","setInterval","timestamp","isAfter","delete","unref","unsubscribeFromGadgetChanges","subscribeToGadgetChanges","onError","error","abort","beforeChanges","changed","deleted","filepath","set","Date","now","dirname","afterChanges","changes","has","cwd","directory","catch","localChangesBuffer","sendChangesToGadget","entries","clear","debug","fileWatcher","ignoreInitial","ignore","relative","startsWith","ignores","renameDetection","recursive","pollingInterval","pollingTimeout","renameTimeout","event","absolutePath","renamedPath","isDirectory","normalizedPath","normalize","trace","absolute","loadIgnoreFile","oldNormalizedPath","oldPath","once","printlns","version","slug","hasSplitEnvironments","primaryDomain","onAbort","reason","info","close","clearInterval","flush","idle","subtitle","message"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/sync.ts"],"sourcesContent":["import dayjs from \"dayjs\";\nimport ms from \"ms\";\nimport path from \"node:path\";\nimport Watcher from \"watcher\";\nimport which from \"which\";\nimport type { ArgsDefinition } from \"../services/command/arg.js\";\nimport type { Command, Usage } from \"../services/command/command.js\";\nimport { config } from \"../services/config/config.js\";\nimport { Changes } from \"../services/filesync/changes.js\";\nimport { YarnNotFoundError } from \"../services/filesync/error.js\";\nimport { FileSync, FileSyncArgs } from \"../services/filesync/filesync.js\";\nimport { notify } from \"../services/output/notify.js\";\nimport { reportErrorAndExit } from \"../services/output/report.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { debounce } from \"../services/util/function.js\";\nimport { isAbortError } from \"../services/util/is.js\";\n\nexport const usage: Usage = () => sprint`\n Sync your Gadget environment's source code with your local filesystem.\n\n {bold USAGE}\n ggt sync [DIRECTORY]\n\n {bold ARGUMENTS}\n DIRECTORY The directory to sync files to (default: \".\")\n\n {bold FLAGS}\n -a, --app=<name> The Gadget application to sync files to\n --prefer=<filesystem> Prefer \"local\" or \"gadget\" conflicting changes\n --once Sync once and exit\n --force Sync regardless of local filesystem state\n\n {bold DESCRIPTION}\n Sync allows you to synchronize your Gadget application's source\n code with your local filesystem.\n\n While ggt sync is running, local file changes are immediately\n reflected within Gadget, while files that are changed in Gadget are\n immediately saved to your local filesystem.\n\n Ideal for:\n • Local development with editors like VSCode\n • Storing source code in a Git repository like GitHub\n\n Sync looks for a \".ignore\" file to exclude certain files/directories\n from being synced. The format is identical to Git's.\n\n These files are always ignored:\n • .DS_Store\n • .gadget\n • .git\n • node_modules\n\n Note:\n • Sync only works with your development environment\n • Avoid deleting/moving all your files while sync is running\n • Gadget only supports Yarn v1 for dependency installation\n\n {bold EXAMPLE}\n $ ggt sync ~/gadget/example --app example\n\n App example\n Editor https://example.gadget.app/edit\n Playground https://example.gadget.app/api/graphql/playground\n Docs https://docs.gadget.dev/api/example\n\n Endpoints\n • https://example.gadget.app\n • https://example--development.gadget.app\n\n Watching for file changes... {gray Press Ctrl+C to stop}\n\n → Sent {gray 09:06:25 AM}\n {greenBright routes/GET-hello.js + created}\n\n → Sent {gray 09:06:49 AM}\n {blueBright routes/GET-hello.js ± updated}\n\n ← Received {gray 09:06:54 AM}\n {blueBright routes/GET-hello.js ± updated}\n\n ← Received {gray 09:06:56 AM}\n {redBright routes/GET-hello.js - deleted}\n ^C Stopping... {gray press Ctrl+C again to force}\n\n Goodbye!\n`;\n\nexport const args = {\n ...FileSyncArgs,\n \"--once\": Boolean,\n \"--file-push-delay\": { type: Number, default: ms(\"100ms\") },\n \"--file-watch-debounce\": { type: Number, default: ms(\"300ms\") },\n \"--file-watch-poll-interval\": { type: Number, default: ms(\"3s\") },\n \"--file-watch-poll-timeout\": { type: Number, default: ms(\"20s\") },\n \"--file-watch-rename-timeout\": { type: Number, default: ms(\"1.25s\") },\n} satisfies ArgsDefinition;\n\nexport type SyncArgs = typeof args;\n\n/**\n * Runs the sync process until it is stopped or an error occurs.\n */\nexport const command: Command<SyncArgs> = async (ctx) => {\n if (!which.sync(\"yarn\", { nothrow: true })) {\n throw new YarnNotFoundError();\n }\n\n const filesync = await FileSync.init(ctx);\n await filesync.sync();\n\n if (ctx.args[\"--once\"]) {\n ctx.log.println(\"Done!\");\n return;\n }\n\n /**\n * A list of filepaths that have changed because we (this ggt process)\n * modified them. This is used to avoid reacting to filesystem events\n * that we caused, which would cause an infinite loop.\n */\n const recentWritesToLocalFilesystem = new Map<string, number>();\n\n const clearRecentWritesInterval = setInterval(() => {\n for (const [path, timestamp] of recentWritesToLocalFilesystem) {\n if (dayjs().isAfter(timestamp + ms(\"5s\"))) {\n // this change should have been seen by now\n recentWritesToLocalFilesystem.delete(path);\n }\n }\n }, ms(\"1s\")).unref();\n\n /**\n * Subscribe to file changes on Gadget and apply them to the local\n * filesystem.\n */\n const unsubscribeFromGadgetChanges = filesync.subscribeToGadgetChanges({\n onError: (error) => ctx.abort(error),\n beforeChanges: ({ changed, deleted }) => {\n // add all the files and directories we're about to touch to\n // recentWritesToLocalFilesystem so that we don't send them back\n // to Gadget\n for (const filepath of [...changed, ...deleted]) {\n recentWritesToLocalFilesystem.set(filepath, Date.now());\n\n let dir = path.dirname(filepath);\n while (dir !== \".\") {\n recentWritesToLocalFilesystem.set(dir + \"/\", Date.now());\n dir = path.dirname(dir);\n }\n }\n },\n });\n\n /**\n * A buffer of local file changes to send to Gadget.\n */\n const localChangesBuffer = new Changes();\n\n /**\n * A debounced function that sends the local file changes to Gadget.\n */\n const sendChangesToGadget = debounce(ctx.args[\"--file-push-delay\"], () => {\n const changes = new Changes(localChangesBuffer.entries());\n localChangesBuffer.clear();\n filesync.sendChangesToGadget({ changes }).catch((error) => ctx.abort(error));\n });\n\n ctx.log.debug(\"watching\", { path: filesync.directory.path });\n\n /**\n * Watches the local filesystem for changes.\n */\n const fileWatcher = new Watcher(\n filesync.directory.path,\n {\n // don't emit an event for every watched file on boot\n ignoreInitial: true,\n // don't emit changes to .gadget/ files because they're readonly (Gadget manages them)\n ignore: (path: string) => filesync.directory.relative(path).startsWith(\".gadget\") || filesync.directory.ignores(path),\n renameDetection: true,\n recursive: true,\n debounce: ctx.args[\"--file-watch-debounce\"],\n pollingInterval: ctx.args[\"--file-watch-poll-interval\"],\n pollingTimeout: ctx.args[\"--file-watch-poll-timeout\"],\n renameTimeout: ctx.args[\"--file-watch-rename-timeout\"],\n },\n (event: string, absolutePath: string, renamedPath: string) => {\n const filepath = event === \"rename\" || event === \"renameDir\" ? renamedPath : absolutePath;\n const isDirectory = event === \"renameDir\" || event === \"addDir\" || event === \"unlinkDir\";\n const normalizedPath = filesync.directory.normalize(filepath, isDirectory);\n\n ctx.log.trace(\"file event\", { event, isDirectory, path: normalizedPath });\n\n if (filepath === filesync.directory.absolute(\".ignore\")) {\n filesync.directory.loadIgnoreFile().catch((error) => ctx.abort(error));\n } else if (filesync.directory.ignores(filepath)) {\n return;\n }\n\n if (recentWritesToLocalFilesystem.delete(normalizedPath)) {\n ctx.log.trace(\"ignoring event because we caused it\", { event, path: normalizedPath });\n return;\n }\n\n switch (event) {\n case \"add\":\n case \"addDir\":\n localChangesBuffer.set(normalizedPath, { type: \"create\" });\n break;\n case \"rename\":\n case \"renameDir\": {\n const oldNormalizedPath = filesync.directory.normalize(absolutePath, isDirectory);\n localChangesBuffer.set(normalizedPath, { type: \"create\", oldPath: oldNormalizedPath });\n break;\n }\n case \"change\": {\n localChangesBuffer.set(normalizedPath, { type: \"update\" });\n break;\n }\n case \"unlink\":\n case \"unlinkDir\": {\n localChangesBuffer.set(normalizedPath, { type: \"delete\" });\n break;\n }\n }\n\n sendChangesToGadget();\n },\n ).once(\"error\", (error) => ctx.abort(error));\n\n ctx.log.printlns`\n ggt v${config.version}\n\n App ${filesync.app.slug}\n Editor https://${filesync.app.slug}.gadget.app/edit\n Playground https://${filesync.app.slug}.gadget.app/api/graphql/playground\n Docs https://docs.gadget.dev/api/${filesync.app.slug}\n\n Endpoints ${\n filesync.app.hasSplitEnvironments\n ? `\n • https://${filesync.app.primaryDomain}\n • https://${filesync.app.slug}--development.gadget.app`\n : `\n • https://${filesync.app.primaryDomain}`\n }\n\n Watching for file changes... {gray Press Ctrl+C to stop}\n `;\n\n ctx.onAbort(async (reason) => {\n ctx.log.info(\"stopping\", { reason });\n\n unsubscribeFromGadgetChanges();\n fileWatcher.close();\n clearInterval(clearRecentWritesInterval);\n sendChangesToGadget.flush();\n\n try {\n await filesync.idle();\n } catch (error) {\n ctx.log.error(\"error while waiting for idle\", { error });\n }\n\n if (isAbortError(reason)) {\n ctx.log.printlns(\"Goodbye!\");\n return;\n }\n\n notify(ctx, { subtitle: \"Uh oh!\", message: \"An error occurred while syncing files\" });\n await reportErrorAndExit(ctx, reason);\n });\n};\n"],"names":["dayjs","ms","path","Watcher","which","config","Changes","YarnNotFoundError","FileSync","FileSyncArgs","notify","reportErrorAndExit","sprint","debounce","isAbortError","usage","args","Boolean","type","Number","default","command","ctx","sync","nothrow","filesync","init","log","println","recentWritesToLocalFilesystem","Map","clearRecentWritesInterval","setInterval","timestamp","isAfter","delete","unref","unsubscribeFromGadgetChanges","subscribeToGadgetChanges","onError","error","abort","beforeChanges","changed","deleted","filepath","set","Date","now","dir","dirname","localChangesBuffer","sendChangesToGadget","changes","entries","clear","catch","debug","directory","fileWatcher","ignoreInitial","ignore","relative","startsWith","ignores","renameDetection","recursive","pollingInterval","pollingTimeout","renameTimeout","event","absolutePath","renamedPath","isDirectory","normalizedPath","normalize","trace","absolute","loadIgnoreFile","oldNormalizedPath","oldPath","once","printlns","version","app","slug","hasSplitEnvironments","primaryDomain","onAbort","reason","info","close","clearInterval","flush","idle","subtitle","message"],"mappings":"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"}
|
package/lib/commands/version.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { config } from "../services/config/config.js";
|
|
2
|
-
import { createLogger } from "../services/output/log/logger.js";
|
|
3
2
|
import { sprint } from "../services/output/sprint.js";
|
|
4
|
-
const log = createLogger({
|
|
5
|
-
name: "version"
|
|
6
|
-
});
|
|
7
3
|
export const usage = ()=>sprint`
|
|
8
4
|
Print the version of ggt
|
|
9
5
|
|
|
@@ -14,8 +10,8 @@ export const usage = ()=>sprint`
|
|
|
14
10
|
$ ggt version
|
|
15
11
|
${config.version}
|
|
16
12
|
`;
|
|
17
|
-
export const command = ()=>{
|
|
18
|
-
log.println(config.version);
|
|
13
|
+
export const command = (ctx)=>{
|
|
14
|
+
ctx.log.println(config.version);
|
|
19
15
|
};
|
|
20
16
|
|
|
21
17
|
//# sourceMappingURL=version.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/version.ts"],"sourcesContent":["import type { Command, Usage } from \"../services/command/command.js\";\nimport { config } from \"../services/config/config.js\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/commands/version.ts"],"sourcesContent":["import type { Command, Usage } from \"../services/command/command.js\";\nimport { config } from \"../services/config/config.js\";\nimport { sprint } from \"../services/output/sprint.js\";\n\nexport const usage: Usage = () => sprint`\n Print the version of ggt\n\n {bold USAGE}\n ggt version\n\n {bold EXAMPLE}\n $ ggt version\n ${config.version}\n`;\n\nexport const command: Command = (ctx) => {\n ctx.log.println(config.version);\n};\n"],"names":["config","sprint","usage","version","command","ctx","log","println"],"mappings":"AACA,SAASA,MAAM,QAAQ,+BAA+B;AACtD,SAASC,MAAM,QAAQ,+BAA+B;AAEtD,OAAO,MAAMC,QAAe,IAAMD,MAAM,CAAC;;;;;;;;MAQnC,EAAED,OAAOG,OAAO,CAAC;AACvB,CAAC,CAAC;AAEF,OAAO,MAAMC,UAAmB,CAACC;IAC/BA,IAAIC,GAAG,CAACC,OAAO,CAACP,OAAOG,OAAO;AAChC,EAAE"}
|
package/lib/commands/whoami.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import { createLogger } from "../services/output/log/logger.js";
|
|
2
1
|
import { sprint } from "../services/output/sprint.js";
|
|
3
2
|
import { getUser } from "../services/user/user.js";
|
|
4
|
-
const log = createLogger({
|
|
5
|
-
name: "whoami"
|
|
6
|
-
});
|
|
7
3
|
export const usage = ()=>sprint`
|
|
8
4
|
Show the name and email address of the currently logged in user
|
|
9
5
|
|
|
@@ -14,16 +10,16 @@ export const usage = ()=>sprint`
|
|
|
14
10
|
$ ggt whoami
|
|
15
11
|
You are logged in as Jane Doe (jane@example.com)
|
|
16
12
|
`;
|
|
17
|
-
export const command = async ()=>{
|
|
18
|
-
const user = await getUser();
|
|
13
|
+
export const command = async (ctx)=>{
|
|
14
|
+
const user = await getUser(ctx);
|
|
19
15
|
if (!user) {
|
|
20
|
-
log.println`You are not logged in`;
|
|
16
|
+
ctx.log.println`You are not logged in`;
|
|
21
17
|
return;
|
|
22
18
|
}
|
|
23
19
|
if (user.name) {
|
|
24
|
-
log.println`You are logged in as ${user.name} {gray (${user.email})}`;
|
|
20
|
+
ctx.log.println`You are logged in as ${user.name} {gray (${user.email})}`;
|
|
25
21
|
} else {
|
|
26
|
-
log.println`You are logged in as ${user.email}`;
|
|
22
|
+
ctx.log.println`You are logged in as ${user.email}`;
|
|
27
23
|
}
|
|
28
24
|
};
|
|
29
25
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/whoami.ts"],"sourcesContent":["import type { Command, Usage } from \"../services/command/command.js\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/commands/whoami.ts"],"sourcesContent":["import type { Command, Usage } from \"../services/command/command.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { getUser } from \"../services/user/user.js\";\n\nexport const usage: Usage = () => sprint`\n Show the name and email address of the currently logged in user\n\n {bold USAGE}\n ggt whoami\n\n {bold EXAMPLE}\n $ ggt whoami\n You are logged in as Jane Doe (jane@example.com)\n`;\n\nexport const command: Command = async (ctx) => {\n const user = await getUser(ctx);\n if (!user) {\n ctx.log.println`You are not logged in`;\n return;\n }\n\n if (user.name) {\n ctx.log.println`You are logged in as ${user.name} {gray (${user.email})}`;\n } else {\n ctx.log.println`You are logged in as ${user.email}`;\n }\n};\n"],"names":["sprint","getUser","usage","command","ctx","user","log","println","name","email"],"mappings":"AACA,SAASA,MAAM,QAAQ,+BAA+B;AACtD,SAASC,OAAO,QAAQ,2BAA2B;AAEnD,OAAO,MAAMC,QAAe,IAAMF,MAAM,CAAC;;;;;;;;;AASzC,CAAC,CAAC;AAEF,OAAO,MAAMG,UAAmB,OAAOC;IACrC,MAAMC,OAAO,MAAMJ,QAAQG;IAC3B,IAAI,CAACC,MAAM;QACTD,IAAIE,GAAG,CAACC,OAAO,CAAC,qBAAqB,CAAC;QACtC;IACF;IAEA,IAAIF,KAAKG,IAAI,EAAE;QACbJ,IAAIE,GAAG,CAACC,OAAO,CAAC,qBAAqB,EAAEF,KAAKG,IAAI,CAAC,QAAQ,EAAEH,KAAKI,KAAK,CAAC,EAAE,CAAC;IAC3E,OAAO;QACLL,IAAIE,GAAG,CAACC,OAAO,CAAC,qBAAqB,EAAEF,KAAKI,KAAK,CAAC,CAAC;IACrD;AACF,EAAE"}
|
package/lib/ggt.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import ms from "ms";
|
|
2
|
+
import * as root from "./commands/root.js";
|
|
3
|
+
import { Context } from "./services/command/context.js";
|
|
4
|
+
import { installErrorHandlers, reportErrorAndExit } from "./services/output/report.js";
|
|
5
|
+
import { installJsonExtensions } from "./services/util/json.js";
|
|
6
|
+
export const ggt = async (ctx = Context.init({
|
|
7
|
+
name: "ggt"
|
|
8
|
+
}))=>{
|
|
9
|
+
installJsonExtensions();
|
|
10
|
+
installErrorHandlers(ctx);
|
|
11
|
+
try {
|
|
12
|
+
for (const signal of [
|
|
13
|
+
"SIGINT",
|
|
14
|
+
"SIGTERM"
|
|
15
|
+
]){
|
|
16
|
+
process.once(signal, ()=>{
|
|
17
|
+
ctx.log.trace("received signal", {
|
|
18
|
+
signal
|
|
19
|
+
});
|
|
20
|
+
ctx.log.println` Stopping... {gray Press Ctrl+C again to force}`;
|
|
21
|
+
ctx.abort();
|
|
22
|
+
// when ggt is run via npx, and the user presses ctrl+c, npx
|
|
23
|
+
// sends sigint twice in quick succession. in order to prevent
|
|
24
|
+
// the second sigint from triggering the force exit listener,
|
|
25
|
+
// we wait a bit before registering it
|
|
26
|
+
setTimeout(()=>{
|
|
27
|
+
process.once(signal, ()=>{
|
|
28
|
+
ctx.log.println(" Exiting immediately");
|
|
29
|
+
process.exit(1);
|
|
30
|
+
});
|
|
31
|
+
}, ms("100ms")).unref();
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
await root.command(ctx);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
await reportErrorAndExit(ctx, error);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=ggt.js.map
|
package/lib/ggt.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ggt.ts"],"sourcesContent":["import ms from \"ms\";\nimport * as root from \"./commands/root.js\";\nimport { Context } from \"./services/command/context.js\";\nimport { installErrorHandlers, reportErrorAndExit } from \"./services/output/report.js\";\nimport { installJsonExtensions } from \"./services/util/json.js\";\n\nexport const ggt = async (ctx = Context.init({ name: \"ggt\" })): Promise<void> => {\n installJsonExtensions();\n installErrorHandlers(ctx);\n\n try {\n for (const signal of [\"SIGINT\", \"SIGTERM\"] as const) {\n process.once(signal, () => {\n ctx.log.trace(\"received signal\", { signal });\n ctx.log.println` Stopping... {gray Press Ctrl+C again to force}`;\n ctx.abort();\n\n // when ggt is run via npx, and the user presses ctrl+c, npx\n // sends sigint twice in quick succession. in order to prevent\n // the second sigint from triggering the force exit listener,\n // we wait a bit before registering it\n setTimeout(() => {\n process.once(signal, () => {\n ctx.log.println(\" Exiting immediately\");\n process.exit(1);\n });\n }, ms(\"100ms\")).unref();\n });\n }\n\n await root.command(ctx);\n } catch (error) {\n await reportErrorAndExit(ctx, error);\n }\n};\n"],"names":["ms","root","Context","installErrorHandlers","reportErrorAndExit","installJsonExtensions","ggt","ctx","init","name","signal","process","once","log","trace","println","abort","setTimeout","exit","unref","command","error"],"mappings":"AAAA,OAAOA,QAAQ,KAAK;AACpB,YAAYC,UAAU,qBAAqB;AAC3C,SAASC,OAAO,QAAQ,gCAAgC;AACxD,SAASC,oBAAoB,EAAEC,kBAAkB,QAAQ,8BAA8B;AACvF,SAASC,qBAAqB,QAAQ,0BAA0B;AAEhE,OAAO,MAAMC,MAAM,OAAOC,MAAML,QAAQM,IAAI,CAAC;IAAEC,MAAM;AAAM,EAAE;IAC3DJ;IACAF,qBAAqBI;IAErB,IAAI;QACF,KAAK,MAAMG,UAAU;YAAC;YAAU;SAAU,CAAW;YACnDC,QAAQC,IAAI,CAACF,QAAQ;gBACnBH,IAAIM,GAAG,CAACC,KAAK,CAAC,mBAAmB;oBAAEJ;gBAAO;gBAC1CH,IAAIM,GAAG,CAACE,OAAO,CAAC,+CAA+C,CAAC;gBAChER,IAAIS,KAAK;gBAET,4DAA4D;gBAC5D,8DAA8D;gBAC9D,6DAA6D;gBAC7D,sCAAsC;gBACtCC,WAAW;oBACTN,QAAQC,IAAI,CAACF,QAAQ;wBACnBH,IAAIM,GAAG,CAACE,OAAO,CAAC;wBAChBJ,QAAQO,IAAI,CAAC;oBACf;gBACF,GAAGlB,GAAG,UAAUmB,KAAK;YACvB;QACF;QAEA,MAAMlB,KAAKmB,OAAO,CAACb;IACrB,EAAE,OAAOc,OAAO;QACd,MAAMjB,mBAAmBG,KAAKc;IAChC;AACF,EAAE"}
|
package/lib/services/app/app.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
1
2
|
import { z } from "zod";
|
|
2
3
|
import { config } from "../config/config.js";
|
|
3
4
|
import { loadCookie } from "../http/auth.js";
|
|
@@ -16,14 +17,18 @@ export const App = z.object({
|
|
|
16
17
|
* Retrieves a list of apps for the given user. If the user is not
|
|
17
18
|
* logged in, an empty array is returned instead.
|
|
18
19
|
*
|
|
19
|
-
* @param
|
|
20
|
+
* @param ctx - The current context.
|
|
20
21
|
* @returns A promise that resolves to an array of App objects.
|
|
21
|
-
*/ export const getApps = async (
|
|
22
|
+
*/ export const getApps = async (ctx)=>{
|
|
22
23
|
const cookie = loadCookie();
|
|
23
24
|
if (!cookie) {
|
|
24
25
|
return [];
|
|
25
26
|
}
|
|
27
|
+
assert(ctx.user, "must get user before getting apps");
|
|
26
28
|
const json = await http({
|
|
29
|
+
context: {
|
|
30
|
+
ctx
|
|
31
|
+
},
|
|
27
32
|
url: `https://${config.domains.services}/auth/api/apps`,
|
|
28
33
|
headers: {
|
|
29
34
|
cookie
|
|
@@ -31,10 +36,7 @@ export const App = z.object({
|
|
|
31
36
|
responseType: "json",
|
|
32
37
|
resolveBodyOnly: true
|
|
33
38
|
});
|
|
34
|
-
return z.array(App).parse(json)
|
|
35
|
-
...app,
|
|
36
|
-
user
|
|
37
|
-
}));
|
|
39
|
+
return z.array(App).parse(json);
|
|
38
40
|
};
|
|
39
41
|
|
|
40
42
|
//# sourceMappingURL=app.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/app/app.ts"],"sourcesContent":["import { z } from \"zod\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/services/app/app.ts"],"sourcesContent":["import assert from \"node:assert\";\nimport { z } from \"zod\";\nimport type { Context } from \"../command/context.js\";\nimport { config } from \"../config/config.js\";\nimport { loadCookie } from \"../http/auth.js\";\nimport { http } from \"../http/http.js\";\n\nexport const App = z.object({\n id: z.union([z.string(), z.number(), z.bigint()]),\n slug: z.string(),\n primaryDomain: z.string(),\n hasSplitEnvironments: z.boolean(),\n});\n\nexport type App = z.infer<typeof App>;\n\n/**\n * Retrieves a list of apps for the given user. If the user is not\n * logged in, an empty array is returned instead.\n *\n * @param ctx - The current context.\n * @returns A promise that resolves to an array of App objects.\n */\nexport const getApps = async (ctx: Context): Promise<App[]> => {\n const cookie = loadCookie();\n if (!cookie) {\n return [];\n }\n\n assert(ctx.user, \"must get user before getting apps\");\n\n const json = await http({\n context: { ctx },\n url: `https://${config.domains.services}/auth/api/apps`,\n headers: { cookie },\n responseType: \"json\",\n resolveBodyOnly: true,\n });\n\n return z.array(App).parse(json);\n};\n"],"names":["assert","z","config","loadCookie","http","App","object","id","union","string","number","bigint","slug","primaryDomain","hasSplitEnvironments","boolean","getApps","ctx","cookie","user","json","context","url","domains","services","headers","responseType","resolveBodyOnly","array","parse"],"mappings":"AAAA,OAAOA,YAAY,cAAc;AACjC,SAASC,CAAC,QAAQ,MAAM;AAExB,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,UAAU,QAAQ,kBAAkB;AAC7C,SAASC,IAAI,QAAQ,kBAAkB;AAEvC,OAAO,MAAMC,MAAMJ,EAAEK,MAAM,CAAC;IAC1BC,IAAIN,EAAEO,KAAK,CAAC;QAACP,EAAEQ,MAAM;QAAIR,EAAES,MAAM;QAAIT,EAAEU,MAAM;KAAG;IAChDC,MAAMX,EAAEQ,MAAM;IACdI,eAAeZ,EAAEQ,MAAM;IACvBK,sBAAsBb,EAAEc,OAAO;AACjC,GAAG;AAIH;;;;;;CAMC,GACD,OAAO,MAAMC,UAAU,OAAOC;IAC5B,MAAMC,SAASf;IACf,IAAI,CAACe,QAAQ;QACX,OAAO,EAAE;IACX;IAEAlB,OAAOiB,IAAIE,IAAI,EAAE;IAEjB,MAAMC,OAAO,MAAMhB,KAAK;QACtBiB,SAAS;YAAEJ;QAAI;QACfK,KAAK,CAAC,QAAQ,EAAEpB,OAAOqB,OAAO,CAACC,QAAQ,CAAC,cAAc,CAAC;QACvDC,SAAS;YAAEP;QAAO;QAClBQ,cAAc;QACdC,iBAAiB;IACnB;IAEA,OAAO1B,EAAE2B,KAAK,CAACvB,KAAKwB,KAAK,CAACT;AAC5B,EAAE"}
|