@gadgetinc/ggt 0.4.9 → 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 +329 -184
- 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 +19 -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 -472
- 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 +3436 -2833
- 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
package/lib/commands/root.js
CHANGED
|
@@ -1,36 +1,18 @@
|
|
|
1
1
|
import arg from "arg";
|
|
2
2
|
import { Commands, importCommand, isAvailableCommand } from "../services/command/command.js";
|
|
3
3
|
import { verbosityToLevel } from "../services/output/log/level.js";
|
|
4
|
+
import { println } from "../services/output/print.js";
|
|
4
5
|
import { reportErrorAndExit } from "../services/output/report.js";
|
|
5
6
|
import { sprint } from "../services/output/sprint.js";
|
|
6
7
|
import { warnIfUpdateAvailable } from "../services/output/update.js";
|
|
7
8
|
import { sortBySimilar } from "../services/util/collection.js";
|
|
8
9
|
import { isNil } from "../services/util/is.js";
|
|
9
|
-
export const usage = ()=>sprint`
|
|
10
|
-
The command-line interface for Gadget
|
|
11
|
-
|
|
12
|
-
{bold USAGE}
|
|
13
|
-
ggt [COMMAND]
|
|
14
|
-
|
|
15
|
-
{bold COMMANDS}
|
|
16
|
-
sync Sync your Gadget application's source code
|
|
17
|
-
list List your apps
|
|
18
|
-
login Log in to your account
|
|
19
|
-
logout Log out of your account
|
|
20
|
-
whoami Print the currently logged in account
|
|
21
|
-
version Print the version of ggt
|
|
22
|
-
|
|
23
|
-
{bold FLAGS}
|
|
24
|
-
-h, --help Print command's usage
|
|
25
|
-
-v, --verbose Print verbose output
|
|
26
|
-
--json Print output as JSON
|
|
27
|
-
|
|
28
|
-
For more information on a specific command, use 'ggt [COMMAND] --help'
|
|
29
|
-
`;
|
|
30
10
|
export const args = {
|
|
11
|
+
"-h": {
|
|
12
|
+
type: Boolean
|
|
13
|
+
},
|
|
31
14
|
"--help": {
|
|
32
|
-
type: Boolean
|
|
33
|
-
alias: "-h"
|
|
15
|
+
type: Boolean
|
|
34
16
|
},
|
|
35
17
|
"--verbose": {
|
|
36
18
|
type: arg.COUNT,
|
|
@@ -39,10 +21,41 @@ export const args = {
|
|
|
39
21
|
"--debug"
|
|
40
22
|
]
|
|
41
23
|
},
|
|
24
|
+
"--telemetry": {
|
|
25
|
+
type: Boolean
|
|
26
|
+
},
|
|
42
27
|
"--json": {
|
|
43
28
|
type: Boolean
|
|
44
29
|
}
|
|
45
30
|
};
|
|
31
|
+
export const usage = ()=>{
|
|
32
|
+
return sprint`
|
|
33
|
+
The command-line interface for Gadget.
|
|
34
|
+
|
|
35
|
+
{bold USAGE}
|
|
36
|
+
ggt [COMMAND]
|
|
37
|
+
|
|
38
|
+
{bold COMMANDS}
|
|
39
|
+
dev Start developing your application
|
|
40
|
+
deploy Deploy your environment to production
|
|
41
|
+
status Show your local and environment's file changes
|
|
42
|
+
push Push your local files to your environment
|
|
43
|
+
pull Pull your environment's files to your local computer
|
|
44
|
+
open Open a Gadget location in your browser
|
|
45
|
+
list List your available applications
|
|
46
|
+
login Log in to your account
|
|
47
|
+
logout Log out of your account
|
|
48
|
+
whoami Print the currently logged in account
|
|
49
|
+
version Print this version of ggt
|
|
50
|
+
|
|
51
|
+
{bold FLAGS}
|
|
52
|
+
-h, --help Print how to use a command
|
|
53
|
+
-v, --verbose Print more verbose output
|
|
54
|
+
--telemetry Enable telemetry
|
|
55
|
+
|
|
56
|
+
Run "ggt [COMMAND] -h" for more information about a specific command.
|
|
57
|
+
`;
|
|
58
|
+
};
|
|
46
59
|
export const command = async (parent)=>{
|
|
47
60
|
const ctx = parent.child({
|
|
48
61
|
name: "root",
|
|
@@ -57,14 +70,18 @@ export const command = async (parent)=>{
|
|
|
57
70
|
process.env["GGT_LOG_LEVEL"] = verbosityToLevel(ctx.args["--verbose"]).toString();
|
|
58
71
|
}
|
|
59
72
|
await warnIfUpdateAvailable(ctx);
|
|
60
|
-
|
|
73
|
+
let cmd = ctx.args._.shift();
|
|
61
74
|
if (isNil(cmd)) {
|
|
62
|
-
|
|
75
|
+
println(usage(ctx));
|
|
63
76
|
process.exit(0);
|
|
64
77
|
}
|
|
78
|
+
if (cmd === "sync") {
|
|
79
|
+
ctx.log.debug('renaming "sync" to "dev" for backwards compatibility');
|
|
80
|
+
cmd = "dev";
|
|
81
|
+
}
|
|
65
82
|
if (!isAvailableCommand(cmd)) {
|
|
66
83
|
const [closest] = sortBySimilar(cmd, Commands);
|
|
67
|
-
|
|
84
|
+
println`
|
|
68
85
|
Unknown command {yellow ${cmd}}
|
|
69
86
|
|
|
70
87
|
Did you mean {blueBright ${closest}}?
|
|
@@ -74,12 +91,13 @@ export const command = async (parent)=>{
|
|
|
74
91
|
process.exit(1);
|
|
75
92
|
}
|
|
76
93
|
const subcommand = await importCommand(cmd);
|
|
77
|
-
if (ctx.args["--help"]) {
|
|
78
|
-
|
|
94
|
+
if (ctx.args["-h"] ?? ctx.args["--help"]) {
|
|
95
|
+
println(subcommand.usage(ctx));
|
|
79
96
|
process.exit(0);
|
|
80
97
|
}
|
|
81
98
|
try {
|
|
82
99
|
await subcommand.command(ctx.child({
|
|
100
|
+
command: cmd,
|
|
83
101
|
name: cmd,
|
|
84
102
|
parse: subcommand.args
|
|
85
103
|
}));
|
package/lib/commands/root.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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
|
|
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 { println } from \"../services/output/print.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 type RootArgs = typeof args;\n\nexport const args = {\n \"-h\": { type: Boolean },\n \"--help\": { type: Boolean },\n \"--verbose\": { type: arg.COUNT, alias: [\"-v\", \"--debug\"] },\n \"--telemetry\": { type: Boolean },\n \"--json\": { type: Boolean },\n} satisfies ArgsDefinition;\n\nexport const usage: Usage = () => {\n return sprint`\n The command-line interface for Gadget.\n\n {bold USAGE}\n ggt [COMMAND]\n\n {bold COMMANDS}\n dev Start developing your application\n deploy Deploy your environment to production\n status Show your local and environment's file changes\n push Push your local files to your environment\n pull Pull your environment's files to your local computer\n open Open a Gadget location in your browser\n list List your available applications\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 this version of ggt\n\n {bold FLAGS}\n -h, --help Print how to use a command\n -v, --verbose Print more verbose output\n --telemetry Enable telemetry\n\n Run \"ggt [COMMAND] -h\" for more information about a specific command.\n `;\n};\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 let cmd = ctx.args._.shift();\n if (isNil(cmd)) {\n println(usage(ctx));\n process.exit(0);\n }\n\n if (cmd === \"sync\") {\n ctx.log.debug('renaming \"sync\" to \"dev\" for backwards compatibility');\n cmd = \"dev\";\n }\n\n if (!isAvailableCommand(cmd)) {\n const [closest] = sortBySimilar(cmd, Commands);\n 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[\"-h\"] ?? ctx.args[\"--help\"]) {\n println(subcommand.usage(ctx));\n process.exit(0);\n }\n\n try {\n await subcommand.command(ctx.child({ command: cmd, name: cmd, parse: subcommand.args }));\n } catch (error) {\n await reportErrorAndExit(ctx, error);\n }\n};\n"],"names":["arg","Commands","importCommand","isAvailableCommand","verbosityToLevel","println","reportErrorAndExit","sprint","warnIfUpdateAvailable","sortBySimilar","isNil","args","type","Boolean","COUNT","alias","usage","command","parent","ctx","child","name","parse","argv","process","slice","permissive","env","toString","cmd","_","shift","exit","log","debug","closest","subcommand","error"],"mappings":"AAAA,OAAOA,SAAS,MAAM;AAGtB,SAASC,QAAQ,EAAEC,aAAa,EAAEC,kBAAkB,QAAkC,iCAAiC;AACvH,SAASC,gBAAgB,QAAQ,kCAAkC;AACnE,SAASC,OAAO,QAAQ,8BAA8B;AACtD,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;AAI/C,OAAO,MAAMC,OAAO;IAClB,MAAM;QAAEC,MAAMC;IAAQ;IACtB,UAAU;QAAED,MAAMC;IAAQ;IAC1B,aAAa;QAAED,MAAMZ,IAAIc,KAAK;QAAEC,OAAO;YAAC;YAAM;SAAU;IAAC;IACzD,eAAe;QAAEH,MAAMC;IAAQ;IAC/B,UAAU;QAAED,MAAMC;IAAQ;AAC5B,EAA2B;AAE3B,OAAO,MAAMG,QAAe;IAC1B,OAAOT,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;EAyBd,CAAC;AACH,EAAE;AAEF,OAAO,MAAMU,UAA6C,OAAOC;IAC/D,MAAMC,MAAMD,OAAOE,KAAK,CAAC;QACvBC,MAAM;QACNC,OAAOX;QACPY,MAAMC,QAAQD,IAAI,CAACE,KAAK,CAAC;QACzBC,YAAY;IACd;IAEA,IAAIP,IAAIR,IAAI,CAAC,SAAS,EAAE;QACtBa,QAAQG,GAAG,CAAC,iBAAiB,GAAG;IAClC;IAEA,IAAIR,IAAIR,IAAI,CAAC,YAAY,EAAE;QACzBa,QAAQG,GAAG,CAAC,gBAAgB,GAAGvB,iBAAiBe,IAAIR,IAAI,CAAC,YAAY,EAAEiB,QAAQ;IACjF;IAEA,MAAMpB,sBAAsBW;IAE5B,IAAIU,MAAMV,IAAIR,IAAI,CAACmB,CAAC,CAACC,KAAK;IAC1B,IAAIrB,MAAMmB,MAAM;QACdxB,QAAQW,MAAMG;QACdK,QAAQQ,IAAI,CAAC;IACf;IAEA,IAAIH,QAAQ,QAAQ;QAClBV,IAAIc,GAAG,CAACC,KAAK,CAAC;QACdL,MAAM;IACR;IAEA,IAAI,CAAC1B,mBAAmB0B,MAAM;QAC5B,MAAM,CAACM,QAAQ,GAAG1B,cAAcoB,KAAK5B;QACrCI,OAAO,CAAC;8BACkB,EAAEwB,IAAI;;+BAEL,EAAEM,QAAQ;;;IAGrC,CAAC;QACDX,QAAQQ,IAAI,CAAC;IACf;IAEA,MAAMI,aAAa,MAAMlC,cAAc2B;IAEvC,IAAIV,IAAIR,IAAI,CAAC,KAAK,IAAIQ,IAAIR,IAAI,CAAC,SAAS,EAAE;QACxCN,QAAQ+B,WAAWpB,KAAK,CAACG;QACzBK,QAAQQ,IAAI,CAAC;IACf;IAEA,IAAI;QACF,MAAMI,WAAWnB,OAAO,CAACE,IAAIC,KAAK,CAAC;YAAEH,SAASY;YAAKR,MAAMQ;YAAKP,OAAOc,WAAWzB,IAAI;QAAC;IACvF,EAAE,OAAO0B,OAAO;QACd,MAAM/B,mBAAmBa,KAAKkB;IAChC;AACF,EAAE"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ArgError } from "../services/command/arg.js";
|
|
2
|
+
import { getConflicts, printConflicts } from "../services/filesync/conflicts.js";
|
|
3
|
+
import { UnknownDirectoryError } from "../services/filesync/error.js";
|
|
4
|
+
import { FileSync } from "../services/filesync/filesync.js";
|
|
5
|
+
import { SyncJson, SyncJsonArgs, loadSyncJsonDirectory } from "../services/filesync/sync-json.js";
|
|
6
|
+
import { sprint } from "../services/output/sprint.js";
|
|
7
|
+
export const args = SyncJsonArgs;
|
|
8
|
+
export const usage = ()=>{
|
|
9
|
+
return sprint`
|
|
10
|
+
Show file changes since your last dev, push, or pull.
|
|
11
|
+
|
|
12
|
+
{bold USAGE}
|
|
13
|
+
|
|
14
|
+
ggt status
|
|
15
|
+
|
|
16
|
+
{bold EXAMPLES}
|
|
17
|
+
|
|
18
|
+
$ ggt status
|
|
19
|
+
`;
|
|
20
|
+
};
|
|
21
|
+
export const command = async (ctx)=>{
|
|
22
|
+
if (ctx.args._.length > 0) {
|
|
23
|
+
throw new ArgError(sprint`
|
|
24
|
+
"ggt status" does not take any positional arguments.
|
|
25
|
+
|
|
26
|
+
If you are trying to see the status of a specific directory,
|
|
27
|
+
you must "cd" to that directory and then run "ggt status".
|
|
28
|
+
|
|
29
|
+
Run "ggt status -h" for more information.
|
|
30
|
+
`);
|
|
31
|
+
}
|
|
32
|
+
const directory = await loadSyncJsonDirectory(process.cwd());
|
|
33
|
+
const syncJson = await SyncJson.load(ctx, {
|
|
34
|
+
directory
|
|
35
|
+
});
|
|
36
|
+
if (!syncJson) {
|
|
37
|
+
throw new UnknownDirectoryError(ctx, {
|
|
38
|
+
directory
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
syncJson.print();
|
|
42
|
+
const filesync = new FileSync(syncJson);
|
|
43
|
+
const hashes = await filesync.hashes(ctx);
|
|
44
|
+
await filesync.print(ctx, {
|
|
45
|
+
hashes
|
|
46
|
+
});
|
|
47
|
+
const conflicts = getConflicts({
|
|
48
|
+
localChanges: hashes.localChanges,
|
|
49
|
+
environmentChanges: hashes.environmentChanges
|
|
50
|
+
});
|
|
51
|
+
if (conflicts.size > 0) {
|
|
52
|
+
ctx.log.debug("conflicts detected", {
|
|
53
|
+
conflicts
|
|
54
|
+
});
|
|
55
|
+
printConflicts({
|
|
56
|
+
conflicts
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/commands/status.ts"],"sourcesContent":["import { ArgError } from \"../services/command/arg.js\";\nimport type { Command, Usage } from \"../services/command/command.js\";\nimport { getConflicts, printConflicts } from \"../services/filesync/conflicts.js\";\nimport { UnknownDirectoryError } from \"../services/filesync/error.js\";\nimport { FileSync } from \"../services/filesync/filesync.js\";\nimport { SyncJson, SyncJsonArgs, loadSyncJsonDirectory } from \"../services/filesync/sync-json.js\";\nimport { sprint } from \"../services/output/sprint.js\";\n\nexport type StatusArgs = typeof args;\n\nexport const args = SyncJsonArgs;\n\nexport const usage: Usage = () => {\n return sprint`\n Show file changes since your last dev, push, or pull.\n\n {bold USAGE}\n\n ggt status\n\n {bold EXAMPLES}\n\n $ ggt status\n `;\n};\n\nexport const command: Command<StatusArgs> = async (ctx) => {\n if (ctx.args._.length > 0) {\n throw new ArgError(sprint`\n \"ggt status\" does not take any positional arguments.\n\n If you are trying to see the status of a specific directory,\n you must \"cd\" to that directory and then run \"ggt status\".\n\n Run \"ggt status -h\" for more information.\n `);\n }\n\n const directory = await loadSyncJsonDirectory(process.cwd());\n const syncJson = await SyncJson.load(ctx, { directory });\n if (!syncJson) {\n throw new UnknownDirectoryError(ctx, { directory });\n }\n\n syncJson.print();\n\n const filesync = new FileSync(syncJson);\n const hashes = await filesync.hashes(ctx);\n await filesync.print(ctx, { hashes });\n\n const conflicts = getConflicts({ localChanges: hashes.localChanges, environmentChanges: hashes.environmentChanges });\n if (conflicts.size > 0) {\n ctx.log.debug(\"conflicts detected\", { conflicts });\n printConflicts({ conflicts });\n }\n};\n"],"names":["ArgError","getConflicts","printConflicts","UnknownDirectoryError","FileSync","SyncJson","SyncJsonArgs","loadSyncJsonDirectory","sprint","args","usage","command","ctx","_","length","directory","process","cwd","syncJson","load","print","filesync","hashes","conflicts","localChanges","environmentChanges","size","log","debug"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,6BAA6B;AAEtD,SAASC,YAAY,EAAEC,cAAc,QAAQ,oCAAoC;AACjF,SAASC,qBAAqB,QAAQ,gCAAgC;AACtE,SAASC,QAAQ,QAAQ,mCAAmC;AAC5D,SAASC,QAAQ,EAAEC,YAAY,EAAEC,qBAAqB,QAAQ,oCAAoC;AAClG,SAASC,MAAM,QAAQ,+BAA+B;AAItD,OAAO,MAAMC,OAAOH,aAAa;AAEjC,OAAO,MAAMI,QAAe;IAC1B,OAAOF,MAAM,CAAC;;;;;;;;;;EAUd,CAAC;AACH,EAAE;AAEF,OAAO,MAAMG,UAA+B,OAAOC;IACjD,IAAIA,IAAIH,IAAI,CAACI,CAAC,CAACC,MAAM,GAAG,GAAG;QACzB,MAAM,IAAId,SAASQ,MAAM,CAAC;;;;;;;IAO1B,CAAC;IACH;IAEA,MAAMO,YAAY,MAAMR,sBAAsBS,QAAQC,GAAG;IACzD,MAAMC,WAAW,MAAMb,SAASc,IAAI,CAACP,KAAK;QAAEG;IAAU;IACtD,IAAI,CAACG,UAAU;QACb,MAAM,IAAIf,sBAAsBS,KAAK;YAAEG;QAAU;IACnD;IAEAG,SAASE,KAAK;IAEd,MAAMC,WAAW,IAAIjB,SAASc;IAC9B,MAAMI,SAAS,MAAMD,SAASC,MAAM,CAACV;IACrC,MAAMS,SAASD,KAAK,CAACR,KAAK;QAAEU;IAAO;IAEnC,MAAMC,YAAYtB,aAAa;QAAEuB,cAAcF,OAAOE,YAAY;QAAEC,oBAAoBH,OAAOG,kBAAkB;IAAC;IAClH,IAAIF,UAAUG,IAAI,GAAG,GAAG;QACtBd,IAAIe,GAAG,CAACC,KAAK,CAAC,sBAAsB;YAAEL;QAAU;QAChDrB,eAAe;YAAEqB;QAAU;IAC7B;AACF,EAAE"}
|
package/lib/commands/version.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { packageJson } from "../services/config/package-json.js";
|
|
2
|
+
import { println } from "../services/output/print.js";
|
|
2
3
|
import { sprint } from "../services/output/sprint.js";
|
|
3
4
|
export const usage = ()=>sprint`
|
|
4
|
-
Print
|
|
5
|
+
Print this version of ggt.
|
|
5
6
|
|
|
6
7
|
{bold USAGE}
|
|
7
8
|
ggt version
|
|
8
9
|
|
|
9
|
-
{bold
|
|
10
|
+
{bold EXAMPLES}
|
|
10
11
|
$ ggt version
|
|
11
|
-
${config.version}
|
|
12
12
|
`;
|
|
13
|
-
export const command = (
|
|
14
|
-
|
|
13
|
+
export const command = (_ctx)=>{
|
|
14
|
+
println(packageJson.version);
|
|
15
15
|
};
|
|
16
16
|
|
|
17
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 {
|
|
1
|
+
{"version":3,"sources":["../../src/commands/version.ts"],"sourcesContent":["import type { Command, Usage } from \"../services/command/command.js\";\nimport { packageJson } from \"../services/config/package-json.js\";\nimport { println } from \"../services/output/print.js\";\nimport { sprint } from \"../services/output/sprint.js\";\n\nexport const usage: Usage = () => sprint`\n Print this version of ggt.\n\n {bold USAGE}\n ggt version\n\n {bold EXAMPLES}\n $ ggt version\n`;\n\nexport const command: Command = (_ctx) => {\n println(packageJson.version);\n};\n"],"names":["packageJson","println","sprint","usage","command","_ctx","version"],"mappings":"AACA,SAASA,WAAW,QAAQ,qCAAqC;AACjE,SAASC,OAAO,QAAQ,8BAA8B;AACtD,SAASC,MAAM,QAAQ,+BAA+B;AAEtD,OAAO,MAAMC,QAAe,IAAMD,MAAM,CAAC;;;;;;;;AAQzC,CAAC,CAAC;AAEF,OAAO,MAAME,UAAmB,CAACC;IAC/BJ,QAAQD,YAAYM,OAAO;AAC7B,EAAE"}
|
package/lib/commands/whoami.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
+
import { println } from "../services/output/print.js";
|
|
1
2
|
import { sprint } from "../services/output/sprint.js";
|
|
2
3
|
import { getUser } from "../services/user/user.js";
|
|
3
4
|
export const usage = ()=>sprint`
|
|
4
|
-
Show the name and email address of the currently logged in user
|
|
5
|
+
Show the name and email address of the currently logged in user.
|
|
5
6
|
|
|
6
7
|
{bold USAGE}
|
|
7
8
|
ggt whoami
|
|
8
9
|
|
|
9
|
-
{bold
|
|
10
|
+
{bold EXAMPLES}
|
|
10
11
|
$ ggt whoami
|
|
11
|
-
You are logged in as Jane Doe (jane@example.com)
|
|
12
12
|
`;
|
|
13
13
|
export const command = async (ctx)=>{
|
|
14
14
|
const user = await getUser(ctx);
|
|
15
15
|
if (!user) {
|
|
16
|
-
|
|
16
|
+
println`You are not logged in`;
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
if (user.name) {
|
|
20
|
-
|
|
20
|
+
println`You are logged in as ${user.name} (${user.email})`;
|
|
21
21
|
} else {
|
|
22
|
-
|
|
22
|
+
println`You are logged in as ${user.email}`;
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
|
|
@@ -1 +1 @@
|
|
|
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
|
|
1
|
+
{"version":3,"sources":["../../src/commands/whoami.ts"],"sourcesContent":["import type { Command, Usage } from \"../services/command/command.js\";\nimport { println } from \"../services/output/print.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 EXAMPLES}\n $ ggt whoami\n`;\n\nexport const command: Command = async (ctx) => {\n const user = await getUser(ctx);\n if (!user) {\n println`You are not logged in`;\n return;\n }\n\n if (user.name) {\n println`You are logged in as ${user.name} (${user.email})`;\n } else {\n println`You are logged in as ${user.email}`;\n }\n};\n"],"names":["println","sprint","getUser","usage","command","ctx","user","name","email"],"mappings":"AACA,SAASA,OAAO,QAAQ,8BAA8B;AACtD,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,OAAO,QAAQ,2BAA2B;AAEnD,OAAO,MAAMC,QAAe,IAAMF,MAAM,CAAC;;;;;;;;AAQzC,CAAC,CAAC;AAEF,OAAO,MAAMG,UAAmB,OAAOC;IACrC,MAAMC,OAAO,MAAMJ,QAAQG;IAC3B,IAAI,CAACC,MAAM;QACTN,OAAO,CAAC,qBAAqB,CAAC;QAC9B;IACF;IAEA,IAAIM,KAAKC,IAAI,EAAE;QACbP,OAAO,CAAC,qBAAqB,EAAEM,KAAKC,IAAI,CAAC,EAAE,EAAED,KAAKE,KAAK,CAAC,CAAC,CAAC;IAC5D,OAAO;QACLR,OAAO,CAAC,qBAAqB,EAAEM,KAAKE,KAAK,CAAC,CAAC;IAC7C;AACF,EAAE"}
|
package/lib/ggt.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import ms from "ms";
|
|
2
2
|
import * as root from "./commands/root.js";
|
|
3
3
|
import { Context } from "./services/command/context.js";
|
|
4
|
+
import { output } from "./services/output/output.js";
|
|
5
|
+
import { println } from "./services/output/print.js";
|
|
4
6
|
import { installErrorHandlers, reportErrorAndExit } from "./services/output/report.js";
|
|
7
|
+
import { activeSpinner, spin } from "./services/output/spinner.js";
|
|
5
8
|
import { installJsonExtensions } from "./services/util/json.js";
|
|
6
9
|
export const ggt = async (ctx = Context.init({
|
|
7
10
|
name: "ggt"
|
|
@@ -9,26 +12,48 @@ export const ggt = async (ctx = Context.init({
|
|
|
9
12
|
installJsonExtensions();
|
|
10
13
|
installErrorHandlers(ctx);
|
|
11
14
|
try {
|
|
15
|
+
let stopping = false;
|
|
12
16
|
for (const signal of [
|
|
13
17
|
"SIGINT",
|
|
14
18
|
"SIGTERM"
|
|
15
19
|
]){
|
|
16
|
-
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
21
|
+
process.on(signal, async ()=>{
|
|
22
|
+
if (stopping) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
stopping = true;
|
|
17
26
|
ctx.log.trace("received signal", {
|
|
18
27
|
signal
|
|
19
28
|
});
|
|
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
29
|
setTimeout(()=>{
|
|
30
|
+
// when ggt is run with npx, and the user presses ctrl+c, ggt
|
|
31
|
+
// receives SIGINT twice in quick succession. in order to
|
|
32
|
+
// prevent the second SIGINT from triggering the force exit
|
|
33
|
+
// listener, we wait a bit in this setTimeout before adding it
|
|
27
34
|
process.once(signal, ()=>{
|
|
28
|
-
|
|
35
|
+
println(" Exiting immediately");
|
|
29
36
|
process.exit(1);
|
|
30
37
|
});
|
|
31
38
|
}, ms("100ms")).unref();
|
|
39
|
+
// ctrl+c was pressed, so we need to clear the line
|
|
40
|
+
output.writeStdout("\n");
|
|
41
|
+
// if there was any sticky text, it needs to be persisted now
|
|
42
|
+
activeSpinner?.clear();
|
|
43
|
+
output.persistFooter();
|
|
44
|
+
const spinner = spin({
|
|
45
|
+
successSymbol: "👋"
|
|
46
|
+
})`
|
|
47
|
+
Stopping {gray Press Ctrl+C again to force}
|
|
48
|
+
`;
|
|
49
|
+
try {
|
|
50
|
+
ctx.abort();
|
|
51
|
+
await ctx.done;
|
|
52
|
+
spinner.succeed("Goodbye!");
|
|
53
|
+
} catch (error) {
|
|
54
|
+
spinner.fail();
|
|
55
|
+
await reportErrorAndExit(ctx, error);
|
|
56
|
+
}
|
|
32
57
|
});
|
|
33
58
|
}
|
|
34
59
|
await root.command(ctx);
|
package/lib/ggt.js.map
CHANGED
|
@@ -1 +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.
|
|
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 { output } from \"./services/output/output.js\";\nimport { println } from \"./services/output/print.js\";\nimport { installErrorHandlers, reportErrorAndExit } from \"./services/output/report.js\";\nimport { activeSpinner, spin } from \"./services/output/spinner.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 let stopping = false;\n\n for (const signal of [\"SIGINT\", \"SIGTERM\"] as const) {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n process.on(signal, async () => {\n if (stopping) {\n return;\n }\n\n stopping = true;\n ctx.log.trace(\"received signal\", { signal });\n\n setTimeout(() => {\n // when ggt is run with npx, and the user presses ctrl+c, ggt\n // receives SIGINT twice in quick succession. in order to\n // prevent the second SIGINT from triggering the force exit\n // listener, we wait a bit in this setTimeout before adding it\n process.once(signal, () => {\n println(\" Exiting immediately\");\n process.exit(1);\n });\n }, ms(\"100ms\")).unref();\n\n // ctrl+c was pressed, so we need to clear the line\n output.writeStdout(\"\\n\");\n\n // if there was any sticky text, it needs to be persisted now\n activeSpinner?.clear();\n output.persistFooter();\n\n const spinner = spin({ successSymbol: \"👋\" })`\n Stopping {gray Press Ctrl+C again to force}\n `;\n\n try {\n ctx.abort();\n await ctx.done;\n spinner.succeed(\"Goodbye!\");\n } catch (error) {\n spinner.fail();\n await reportErrorAndExit(ctx, error);\n }\n });\n }\n\n await root.command(ctx);\n } catch (error) {\n await reportErrorAndExit(ctx, error);\n }\n};\n"],"names":["ms","root","Context","output","println","installErrorHandlers","reportErrorAndExit","activeSpinner","spin","installJsonExtensions","ggt","ctx","init","name","stopping","signal","process","on","log","trace","setTimeout","once","exit","unref","writeStdout","clear","persistFooter","spinner","successSymbol","abort","done","succeed","error","fail","command"],"mappings":"AAAA,OAAOA,QAAQ,KAAK;AACpB,YAAYC,UAAU,qBAAqB;AAC3C,SAASC,OAAO,QAAQ,gCAAgC;AACxD,SAASC,MAAM,QAAQ,8BAA8B;AACrD,SAASC,OAAO,QAAQ,6BAA6B;AACrD,SAASC,oBAAoB,EAAEC,kBAAkB,QAAQ,8BAA8B;AACvF,SAASC,aAAa,EAAEC,IAAI,QAAQ,+BAA+B;AACnE,SAASC,qBAAqB,QAAQ,0BAA0B;AAEhE,OAAO,MAAMC,MAAM,OAAOC,MAAMT,QAAQU,IAAI,CAAC;IAAEC,MAAM;AAAM,EAAE;IAC3DJ;IACAJ,qBAAqBM;IAErB,IAAI;QACF,IAAIG,WAAW;QAEf,KAAK,MAAMC,UAAU;YAAC;YAAU;SAAU,CAAW;YACnD,kEAAkE;YAClEC,QAAQC,EAAE,CAACF,QAAQ;gBACjB,IAAID,UAAU;oBACZ;gBACF;gBAEAA,WAAW;gBACXH,IAAIO,GAAG,CAACC,KAAK,CAAC,mBAAmB;oBAAEJ;gBAAO;gBAE1CK,WAAW;oBACT,6DAA6D;oBAC7D,yDAAyD;oBACzD,2DAA2D;oBAC3D,8DAA8D;oBAC9DJ,QAAQK,IAAI,CAACN,QAAQ;wBACnBX,QAAQ;wBACRY,QAAQM,IAAI,CAAC;oBACf;gBACF,GAAGtB,GAAG,UAAUuB,KAAK;gBAErB,mDAAmD;gBACnDpB,OAAOqB,WAAW,CAAC;gBAEnB,6DAA6D;gBAC7DjB,eAAekB;gBACftB,OAAOuB,aAAa;gBAEpB,MAAMC,UAAUnB,KAAK;oBAAEoB,eAAe;gBAAK,EAAE,CAAC;;QAE9C,CAAC;gBAED,IAAI;oBACFjB,IAAIkB,KAAK;oBACT,MAAMlB,IAAImB,IAAI;oBACdH,QAAQI,OAAO,CAAC;gBAClB,EAAE,OAAOC,OAAO;oBACdL,QAAQM,IAAI;oBACZ,MAAM3B,mBAAmBK,KAAKqB;gBAChC;YACF;QACF;QAEA,MAAM/B,KAAKiC,OAAO,CAACvB;IACrB,EAAE,OAAOqB,OAAO;QACd,MAAM1B,mBAAmBK,KAAKqB;IAChC;AACF,EAAE"}
|
package/lib/main.js
ADDED
package/lib/main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { ggt } from \"./ggt.js\";\n\nawait ggt();\n"],"names":["ggt"],"mappings":";AAEA,SAASA,GAAG,QAAQ,WAAW;AAE/B,MAAMA"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { _ as _class_private_field_get } from "@swc/helpers/_/_class_private_field_get";
|
|
2
|
+
import { _ as _class_private_field_init } from "@swc/helpers/_/_class_private_field_init";
|
|
3
|
+
import { _ as _class_private_field_set } from "@swc/helpers/_/_class_private_field_set";
|
|
4
|
+
import { _ as _define_property } from "@swc/helpers/_/_define_property";
|
|
5
|
+
import assert from "node:assert";
|
|
6
|
+
import { unthunk } from "../../util/function.js";
|
|
7
|
+
import { Client } from "../client.js";
|
|
8
|
+
import { ClientError } from "../error.js";
|
|
9
|
+
var /**
|
|
10
|
+
* The client used to make requests to Gadget's /api/graphql
|
|
11
|
+
* endpoint.
|
|
12
|
+
*/ _client = /*#__PURE__*/ new WeakMap();
|
|
13
|
+
export class Api {
|
|
14
|
+
/**
|
|
15
|
+
* Execute a GraphQL query.
|
|
16
|
+
*
|
|
17
|
+
* @param request - The query and variables to send to the server.
|
|
18
|
+
* @param request.query - The GraphQL query to execute.
|
|
19
|
+
* @param request.variables - The variables to send to the server.
|
|
20
|
+
* @param request.http - {@linkcode HttpOptions} to pass to http.
|
|
21
|
+
* @returns The data returned by the server.
|
|
22
|
+
*/ async query({ query, variables, ...options }) {
|
|
23
|
+
const name = query.match(/query (\w+)/)?.[1];
|
|
24
|
+
assert(name, "query name not found");
|
|
25
|
+
const ctx = this.ctx.child({
|
|
26
|
+
fields: {
|
|
27
|
+
edit: {
|
|
28
|
+
query: name
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
devFields: {
|
|
32
|
+
edit: {
|
|
33
|
+
query: name,
|
|
34
|
+
variables: unthunk(variables)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
ctx.log.info("executing graphql query");
|
|
39
|
+
const response = await _class_private_field_get(this, _client).execute(ctx, {
|
|
40
|
+
operation: query,
|
|
41
|
+
variables,
|
|
42
|
+
...options,
|
|
43
|
+
http: {
|
|
44
|
+
retry: {
|
|
45
|
+
// queries _should_ be idempotent, so automatically retry them
|
|
46
|
+
methods: [
|
|
47
|
+
"POST"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
...options.http
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
if (response.errors) {
|
|
54
|
+
throw new ClientError(query, response.errors);
|
|
55
|
+
}
|
|
56
|
+
if (!response.data) {
|
|
57
|
+
throw new ClientError(query, "Query response did not contain data");
|
|
58
|
+
}
|
|
59
|
+
return response.data;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Execute a GraphQL mutation.
|
|
63
|
+
*
|
|
64
|
+
* @param request - The query and variables to send to the server.
|
|
65
|
+
* @param request.mutation - The GraphQL mutation to execute.
|
|
66
|
+
* @param request.variables - The variables to send to the server.
|
|
67
|
+
* @param request.http - {@linkcode HttpOptions} to pass to http.
|
|
68
|
+
* @returns The data returned by the server.
|
|
69
|
+
*/ async mutate({ mutation, variables, ...options }) {
|
|
70
|
+
const name = mutation.match(/mutation (\w+)/)?.[1];
|
|
71
|
+
assert(name, "mutation name not found");
|
|
72
|
+
const ctx = this.ctx.child({
|
|
73
|
+
fields: {
|
|
74
|
+
edit: {
|
|
75
|
+
mutation: name
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
devFields: {
|
|
79
|
+
edit: {
|
|
80
|
+
mutation: name,
|
|
81
|
+
variables: unthunk(variables)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
ctx.log.info("executing graphql mutation");
|
|
86
|
+
const response = await _class_private_field_get(this, _client).execute(ctx, {
|
|
87
|
+
operation: mutation,
|
|
88
|
+
variables,
|
|
89
|
+
...options
|
|
90
|
+
});
|
|
91
|
+
if (response.errors) {
|
|
92
|
+
throw new ClientError(mutation, response.errors);
|
|
93
|
+
}
|
|
94
|
+
if (!response.data) {
|
|
95
|
+
throw new ClientError(mutation, "Mutation response did not contain data");
|
|
96
|
+
}
|
|
97
|
+
return response.data;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Subscribe to a GraphQL subscription.
|
|
101
|
+
*
|
|
102
|
+
* @param options - The query and variables to send to the server.
|
|
103
|
+
* @param options.subscription - The GraphQL subscription to subscribe to.
|
|
104
|
+
* @param options.variables - The variables to send to the server.
|
|
105
|
+
* @param options.onData - A callback that will be called when data is received from the server.
|
|
106
|
+
* @param options.onError - A callback that will be called when an error is received from the server.
|
|
107
|
+
* @param options.onComplete - A callback that will be called when the subscription ends.
|
|
108
|
+
* @returns A function to unsubscribe from the subscription.
|
|
109
|
+
*/ subscribe({ onData, ...options }) {
|
|
110
|
+
const name = options.subscription.match(/subscription (\w+)/)?.[1];
|
|
111
|
+
assert(name, "subscription name not found");
|
|
112
|
+
let ctx = this.ctx.child({
|
|
113
|
+
fields: {
|
|
114
|
+
edit: {
|
|
115
|
+
subscription: name
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
devFields: {
|
|
119
|
+
edit: {
|
|
120
|
+
subscription: name,
|
|
121
|
+
variables: unthunk(options.variables)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
const onResponse = async (response)=>{
|
|
126
|
+
if (response.errors) {
|
|
127
|
+
unsubscribe();
|
|
128
|
+
await options.onError(new ClientError(options.subscription, response.errors));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (!response.data) {
|
|
132
|
+
unsubscribe();
|
|
133
|
+
await options.onError(new ClientError(options.subscription, "Subscription response did not contain data"));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
await onData(response.data);
|
|
137
|
+
};
|
|
138
|
+
ctx.log.info("subscribing to graphql subscription");
|
|
139
|
+
let unsubscribe = _class_private_field_get(this, _client).subscribe(ctx, {
|
|
140
|
+
...options,
|
|
141
|
+
onResponse
|
|
142
|
+
});
|
|
143
|
+
return {
|
|
144
|
+
unsubscribe,
|
|
145
|
+
resubscribe: (variables)=>{
|
|
146
|
+
unsubscribe();
|
|
147
|
+
if (variables !== undefined) {
|
|
148
|
+
options.variables = variables;
|
|
149
|
+
}
|
|
150
|
+
ctx = this.ctx.child({
|
|
151
|
+
fields: {
|
|
152
|
+
edit: {
|
|
153
|
+
subscription: name
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
devFields: {
|
|
157
|
+
edit: {
|
|
158
|
+
subscription: name,
|
|
159
|
+
variables: unthunk(options.variables)
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
ctx.log.info("re-subscribing to graphql subscription");
|
|
164
|
+
unsubscribe = _class_private_field_get(this, _client).subscribe(ctx, {
|
|
165
|
+
...options,
|
|
166
|
+
onResponse
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Close the client.
|
|
173
|
+
*/ async dispose() {
|
|
174
|
+
await _class_private_field_get(this, _client).dispose();
|
|
175
|
+
}
|
|
176
|
+
constructor(ctx){
|
|
177
|
+
/**
|
|
178
|
+
* The {@linkcode Context} that was used to create this instance.
|
|
179
|
+
*/ _define_property(this, "ctx", void 0);
|
|
180
|
+
_class_private_field_init(this, _client, {
|
|
181
|
+
writable: true,
|
|
182
|
+
value: void 0
|
|
183
|
+
});
|
|
184
|
+
this.ctx = ctx.child({
|
|
185
|
+
name: "api"
|
|
186
|
+
});
|
|
187
|
+
_class_private_field_set(this, _client, new Client(this.ctx, "/api/graphql"));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/services/app/api/api.ts"],"sourcesContent":["import type { ExecutionResult } from \"graphql-ws\";\nimport assert from \"node:assert\";\nimport type { Promisable } from \"type-fest\";\nimport type { Context } from \"../../command/context.js\";\nimport type { HttpOptions } from \"../../http/http.js\";\nimport { unthunk, type Thunk } from \"../../util/function.js\";\nimport { Client } from \"../client.js\";\nimport type { GraphQLMutation, GraphQLQuery, GraphQLSubscription } from \"../edit/operation.js\";\nimport { ClientError } from \"../error.js\";\n\nexport class Api {\n /**\n * The {@linkcode Context} that was used to create this instance.\n */\n readonly ctx: Context;\n\n /**\n * The client used to make requests to Gadget's /api/graphql\n * endpoint.\n */\n #client: Client;\n\n constructor(ctx: Context) {\n this.ctx = ctx.child({ name: \"api\" });\n this.#client = new Client(this.ctx, \"/api/graphql\");\n }\n\n /**\n * Execute a GraphQL query.\n *\n * @param request - The query and variables to send to the server.\n * @param request.query - The GraphQL query to execute.\n * @param request.variables - The variables to send to the server.\n * @param request.http - {@linkcode HttpOptions} to pass to http.\n * @returns The data returned by the server.\n */\n async query<Query extends GraphQLQuery>({\n query,\n variables,\n ...options\n }: {\n query: Query;\n variables?: Thunk<Query[\"Variables\"]> | null;\n http?: HttpOptions;\n }): Promise<Query[\"Data\"]> {\n const name = query.match(/query (\\w+)/)?.[1];\n assert(name, \"query name not found\");\n\n const ctx = this.ctx.child({\n fields: { edit: { query: name } },\n devFields: { edit: { query: name, variables: unthunk(variables) } },\n });\n\n ctx.log.info(\"executing graphql query\");\n const response = await this.#client.execute(ctx, {\n operation: query,\n variables,\n ...options,\n http: {\n retry: {\n // queries _should_ be idempotent, so automatically retry them\n methods: [\"POST\"],\n },\n ...options.http,\n },\n });\n\n if (response.errors) {\n throw new ClientError(query, response.errors);\n }\n\n if (!response.data) {\n throw new ClientError(query, \"Query response did not contain data\");\n }\n\n return response.data;\n }\n\n /**\n * Execute a GraphQL mutation.\n *\n * @param request - The query and variables to send to the server.\n * @param request.mutation - The GraphQL mutation to execute.\n * @param request.variables - The variables to send to the server.\n * @param request.http - {@linkcode HttpOptions} to pass to http.\n * @returns The data returned by the server.\n */\n async mutate<Mutation extends GraphQLMutation>({\n mutation,\n variables,\n ...options\n }: {\n mutation: Mutation;\n variables?: Thunk<Mutation[\"Variables\"]> | null;\n http?: HttpOptions;\n }): Promise<Mutation[\"Data\"]> {\n const name = mutation.match(/mutation (\\w+)/)?.[1];\n assert(name, \"mutation name not found\");\n\n const ctx = this.ctx.child({\n fields: { edit: { mutation: name } },\n devFields: { edit: { mutation: name, variables: unthunk(variables) } },\n });\n\n ctx.log.info(\"executing graphql mutation\");\n const response = await this.#client.execute(ctx, { operation: mutation, variables, ...options });\n\n if (response.errors) {\n throw new ClientError(mutation, response.errors);\n }\n\n if (!response.data) {\n throw new ClientError(mutation, \"Mutation response did not contain data\");\n }\n\n return response.data;\n }\n\n /**\n * Subscribe to a GraphQL subscription.\n *\n * @param options - The query and variables to send to the server.\n * @param options.subscription - The GraphQL subscription to subscribe to.\n * @param options.variables - The variables to send to the server.\n * @param options.onData - A callback that will be called when data is received from the server.\n * @param options.onError - A callback that will be called when an error is received from the server.\n * @param options.onComplete - A callback that will be called when the subscription ends.\n * @returns A function to unsubscribe from the subscription.\n */\n subscribe<Subscription extends GraphQLSubscription>({\n onData,\n ...options\n }: {\n subscription: Subscription;\n variables?: Thunk<Subscription[\"Variables\"]> | null;\n onData: (data: Subscription[\"Data\"]) => Promisable<void>;\n onError: (error: ClientError) => Promisable<void>;\n onComplete?: () => Promisable<void>;\n }): EditSubscription<Subscription> {\n const name = options.subscription.match(/subscription (\\w+)/)?.[1];\n assert(name, \"subscription name not found\");\n\n let ctx = this.ctx.child({\n fields: { edit: { subscription: name } },\n devFields: { edit: { subscription: name, variables: unthunk(options.variables) } },\n });\n\n const onResponse = async (response: ExecutionResult<Subscription[\"Data\"], Subscription[\"Extensions\"]>): Promise<void> => {\n if (response.errors) {\n unsubscribe();\n await options.onError(new ClientError(options.subscription, response.errors));\n return;\n }\n\n if (!response.data) {\n unsubscribe();\n await options.onError(new ClientError(options.subscription, \"Subscription response did not contain data\"));\n return;\n }\n\n await onData(response.data);\n };\n\n ctx.log.info(\"subscribing to graphql subscription\");\n let unsubscribe = this.#client.subscribe(ctx, { ...options, onResponse });\n\n return {\n unsubscribe,\n resubscribe: (variables) => {\n unsubscribe();\n\n if (variables !== undefined) {\n options.variables = variables;\n }\n\n ctx = this.ctx.child({\n fields: { edit: { subscription: name } },\n devFields: { edit: { subscription: name, variables: unthunk(options.variables) } },\n });\n\n ctx.log.info(\"re-subscribing to graphql subscription\");\n unsubscribe = this.#client.subscribe(ctx, { ...options, onResponse });\n },\n };\n }\n\n /**\n * Close the client.\n */\n async dispose(): Promise<void> {\n await this.#client.dispose();\n }\n}\n\n/**\n * An object that can be used to unsubscribe and resubscribe to an\n * ongoing Edit GraphQL subscription.\n */\nexport type EditSubscription<Subscription extends GraphQLSubscription> = {\n /**\n * Unsubscribe from the subscription.\n */\n unsubscribe(): void;\n\n /**\n * Resubscribe to the subscription.\n */\n resubscribe(variables?: Thunk<Subscription[\"Variables\"]> | null): void;\n};\n"],"names":["assert","unthunk","Client","ClientError","Api","query","variables","options","name","match","ctx","child","fields","edit","devFields","log","info","response","client","execute","operation","http","retry","methods","errors","data","mutate","mutation","subscribe","onData","subscription","onResponse","unsubscribe","onError","resubscribe","undefined","dispose","constructor"],"mappings":";;;;AACA,OAAOA,YAAY,cAAc;AAIjC,SAASC,OAAO,QAAoB,yBAAyB;AAC7D,SAASC,MAAM,QAAQ,eAAe;AAEtC,SAASC,WAAW,QAAQ,cAAc;IAQxC;;;GAGC,GACD;AAVF,OAAO,MAAMC;IAiBX;;;;;;;;GAQC,GACD,MAAMC,MAAkC,EACtCA,KAAK,EACLC,SAAS,EACT,GAAGC,SAKJ,EAA0B;QACzB,MAAMC,OAAOH,MAAMI,KAAK,CAAC,gBAAgB,CAAC,EAAE;QAC5CT,OAAOQ,MAAM;QAEb,MAAME,MAAM,IAAI,CAACA,GAAG,CAACC,KAAK,CAAC;YACzBC,QAAQ;gBAAEC,MAAM;oBAAER,OAAOG;gBAAK;YAAE;YAChCM,WAAW;gBAAED,MAAM;oBAAER,OAAOG;oBAAMF,WAAWL,QAAQK;gBAAW;YAAE;QACpE;QAEAI,IAAIK,GAAG,CAACC,IAAI,CAAC;QACb,MAAMC,WAAW,MAAM,yBAAA,IAAI,EAAEC,SAAOC,OAAO,CAACT,KAAK;YAC/CU,WAAWf;YACXC;YACA,GAAGC,OAAO;YACVc,MAAM;gBACJC,OAAO;oBACL,8DAA8D;oBAC9DC,SAAS;wBAAC;qBAAO;gBACnB;gBACA,GAAGhB,QAAQc,IAAI;YACjB;QACF;QAEA,IAAIJ,SAASO,MAAM,EAAE;YACnB,MAAM,IAAIrB,YAAYE,OAAOY,SAASO,MAAM;QAC9C;QAEA,IAAI,CAACP,SAASQ,IAAI,EAAE;YAClB,MAAM,IAAItB,YAAYE,OAAO;QAC/B;QAEA,OAAOY,SAASQ,IAAI;IACtB;IAEA;;;;;;;;GAQC,GACD,MAAMC,OAAyC,EAC7CC,QAAQ,EACRrB,SAAS,EACT,GAAGC,SAKJ,EAA6B;QAC5B,MAAMC,OAAOmB,SAASlB,KAAK,CAAC,mBAAmB,CAAC,EAAE;QAClDT,OAAOQ,MAAM;QAEb,MAAME,MAAM,IAAI,CAACA,GAAG,CAACC,KAAK,CAAC;YACzBC,QAAQ;gBAAEC,MAAM;oBAAEc,UAAUnB;gBAAK;YAAE;YACnCM,WAAW;gBAAED,MAAM;oBAAEc,UAAUnB;oBAAMF,WAAWL,QAAQK;gBAAW;YAAE;QACvE;QAEAI,IAAIK,GAAG,CAACC,IAAI,CAAC;QACb,MAAMC,WAAW,MAAM,yBAAA,IAAI,EAAEC,SAAOC,OAAO,CAACT,KAAK;YAAEU,WAAWO;YAAUrB;YAAW,GAAGC,OAAO;QAAC;QAE9F,IAAIU,SAASO,MAAM,EAAE;YACnB,MAAM,IAAIrB,YAAYwB,UAAUV,SAASO,MAAM;QACjD;QAEA,IAAI,CAACP,SAASQ,IAAI,EAAE;YAClB,MAAM,IAAItB,YAAYwB,UAAU;QAClC;QAEA,OAAOV,SAASQ,IAAI;IACtB;IAEA;;;;;;;;;;GAUC,GACDG,UAAoD,EAClDC,MAAM,EACN,GAAGtB,SAOJ,EAAkC;QACjC,MAAMC,OAAOD,QAAQuB,YAAY,CAACrB,KAAK,CAAC,uBAAuB,CAAC,EAAE;QAClET,OAAOQ,MAAM;QAEb,IAAIE,MAAM,IAAI,CAACA,GAAG,CAACC,KAAK,CAAC;YACvBC,QAAQ;gBAAEC,MAAM;oBAAEiB,cAActB;gBAAK;YAAE;YACvCM,WAAW;gBAAED,MAAM;oBAAEiB,cAActB;oBAAMF,WAAWL,QAAQM,QAAQD,SAAS;gBAAE;YAAE;QACnF;QAEA,MAAMyB,aAAa,OAAOd;YACxB,IAAIA,SAASO,MAAM,EAAE;gBACnBQ;gBACA,MAAMzB,QAAQ0B,OAAO,CAAC,IAAI9B,YAAYI,QAAQuB,YAAY,EAAEb,SAASO,MAAM;gBAC3E;YACF;YAEA,IAAI,CAACP,SAASQ,IAAI,EAAE;gBAClBO;gBACA,MAAMzB,QAAQ0B,OAAO,CAAC,IAAI9B,YAAYI,QAAQuB,YAAY,EAAE;gBAC5D;YACF;YAEA,MAAMD,OAAOZ,SAASQ,IAAI;QAC5B;QAEAf,IAAIK,GAAG,CAACC,IAAI,CAAC;QACb,IAAIgB,cAAc,yBAAA,IAAI,EAAEd,SAAOU,SAAS,CAAClB,KAAK;YAAE,GAAGH,OAAO;YAAEwB;QAAW;QAEvE,OAAO;YACLC;YACAE,aAAa,CAAC5B;gBACZ0B;gBAEA,IAAI1B,cAAc6B,WAAW;oBAC3B5B,QAAQD,SAAS,GAAGA;gBACtB;gBAEAI,MAAM,IAAI,CAACA,GAAG,CAACC,KAAK,CAAC;oBACnBC,QAAQ;wBAAEC,MAAM;4BAAEiB,cAActB;wBAAK;oBAAE;oBACvCM,WAAW;wBAAED,MAAM;4BAAEiB,cAActB;4BAAMF,WAAWL,QAAQM,QAAQD,SAAS;wBAAE;oBAAE;gBACnF;gBAEAI,IAAIK,GAAG,CAACC,IAAI,CAAC;gBACbgB,cAAc,yBAAA,IAAI,EAAEd,SAAOU,SAAS,CAAClB,KAAK;oBAAE,GAAGH,OAAO;oBAAEwB;gBAAW;YACrE;QACF;IACF;IAEA;;GAEC,GACD,MAAMK,UAAyB;QAC7B,MAAM,yBAAA,IAAI,EAAElB,SAAOkB,OAAO;IAC5B;IAzKAC,YAAY3B,GAAY,CAAE;QAX1B;;GAEC,GACD,uBAASA,OAAT,KAAA;QAMA,gCAAA;;mBAAA,KAAA;;QAGE,IAAI,CAACA,GAAG,GAAGA,IAAIC,KAAK,CAAC;YAAEH,MAAM;QAAM;uCAC7BU,SAAS,IAAIhB,OAAO,IAAI,CAACQ,GAAG,EAAE;IACtC;AAuKF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/services/app/api/operation.ts"],"sourcesContent":["import type { GadgetMetaModelsQuery, GadgetMetaModelsQueryVariables } from \"../../../__generated__/graphql.js\";\nimport { sprint } from \"../../output/sprint.js\";\nimport type { GraphQLQuery } from \"../edit/operation.js\";\n\nexport const GADGET_META_MODELS_QUERY = sprint(/* GraphQL */ `\n query GadgetMetaModels {\n gadgetMeta {\n models {\n apiIdentifier\n }\n }\n }\n`) as GraphQLQuery<GadgetMetaModelsQuery, GadgetMetaModelsQueryVariables>;\n"],"names":["sprint","GADGET_META_MODELS_QUERY"],"mappings":"AACA,SAASA,MAAM,QAAQ,yBAAyB;AAGhD,OAAO,MAAMC,2BAA2BD,OAAO,WAAW,GAAG,CAAC;;;;;;;;AAQ9D,CAAC,EAAyE"}
|