@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.
Files changed (142) hide show
  1. package/README.md +165 -93
  2. package/lib/__generated__/graphql.js +66 -1
  3. package/lib/__generated__/graphql.js.map +1 -1
  4. package/lib/commands/deploy.js +329 -184
  5. package/lib/commands/deploy.js.map +1 -1
  6. package/lib/commands/dev.js +445 -0
  7. package/lib/commands/dev.js.map +1 -0
  8. package/lib/commands/list.js +27 -19
  9. package/lib/commands/list.js.map +1 -1
  10. package/lib/commands/login.js +15 -11
  11. package/lib/commands/login.js.map +1 -1
  12. package/lib/commands/logout.js +5 -5
  13. package/lib/commands/logout.js.map +1 -1
  14. package/lib/commands/open.js +200 -0
  15. package/lib/commands/open.js.map +1 -0
  16. package/lib/commands/pull.js +128 -0
  17. package/lib/commands/pull.js.map +1 -0
  18. package/lib/commands/push.js +126 -0
  19. package/lib/commands/push.js.map +1 -0
  20. package/lib/commands/root.js +46 -28
  21. package/lib/commands/root.js.map +1 -1
  22. package/lib/commands/status.js +61 -0
  23. package/lib/commands/status.js.map +1 -0
  24. package/lib/commands/version.js +6 -6
  25. package/lib/commands/version.js.map +1 -1
  26. package/lib/commands/whoami.js +6 -6
  27. package/lib/commands/whoami.js.map +1 -1
  28. package/lib/ggt.js +33 -8
  29. package/lib/ggt.js.map +1 -1
  30. package/lib/main.js +5 -0
  31. package/lib/main.js.map +1 -0
  32. package/lib/services/app/api/api.js +191 -0
  33. package/lib/services/app/api/api.js.map +1 -0
  34. package/lib/services/app/api/operation.js +12 -0
  35. package/lib/services/app/api/operation.js.map +1 -0
  36. package/lib/services/app/app.js +44 -10
  37. package/lib/services/app/app.js.map +1 -1
  38. package/lib/services/app/{edit/client.js → client.js} +29 -19
  39. package/lib/services/app/client.js.map +1 -0
  40. package/lib/services/app/edit/edit.js +67 -31
  41. package/lib/services/app/edit/edit.js.map +1 -1
  42. package/lib/services/app/edit/operation.js +19 -3
  43. package/lib/services/app/edit/operation.js.map +1 -1
  44. package/lib/services/app/{edit/error.js → error.js} +6 -6
  45. package/lib/services/app/error.js.map +1 -0
  46. package/lib/services/command/arg.js +4 -4
  47. package/lib/services/command/arg.js.map +1 -1
  48. package/lib/services/command/command.js +9 -7
  49. package/lib/services/command/command.js.map +1 -1
  50. package/lib/services/command/context.js +82 -20
  51. package/lib/services/command/context.js.map +1 -1
  52. package/lib/services/config/config.js +4 -7
  53. package/lib/services/config/config.js.map +1 -1
  54. package/lib/services/config/env.js +1 -1
  55. package/lib/services/config/env.js.map +1 -1
  56. package/lib/services/filesync/changes.js +76 -37
  57. package/lib/services/filesync/changes.js.map +1 -1
  58. package/lib/services/filesync/conflicts.js +10 -9
  59. package/lib/services/filesync/conflicts.js.map +1 -1
  60. package/lib/services/filesync/directory.js +16 -1
  61. package/lib/services/filesync/directory.js.map +1 -1
  62. package/lib/services/filesync/error.js +96 -27
  63. package/lib/services/filesync/error.js.map +1 -1
  64. package/lib/services/filesync/filesync.js +448 -472
  65. package/lib/services/filesync/filesync.js.map +1 -1
  66. package/lib/services/filesync/hashes.js +8 -5
  67. package/lib/services/filesync/hashes.js.map +1 -1
  68. package/lib/services/filesync/strategy.js +59 -0
  69. package/lib/services/filesync/strategy.js.map +1 -0
  70. package/lib/services/filesync/sync-json.js +475 -0
  71. package/lib/services/filesync/sync-json.js.map +1 -0
  72. package/lib/services/http/auth.js +30 -1
  73. package/lib/services/http/auth.js.map +1 -1
  74. package/lib/services/http/http.js +5 -0
  75. package/lib/services/http/http.js.map +1 -1
  76. package/lib/services/output/confirm.js +149 -0
  77. package/lib/services/output/confirm.js.map +1 -0
  78. package/lib/services/output/footer.js +22 -0
  79. package/lib/services/output/footer.js.map +1 -0
  80. package/lib/services/output/log/format/pretty.js +2 -1
  81. package/lib/services/output/log/format/pretty.js.map +1 -1
  82. package/lib/services/output/log/logger.js +13 -5
  83. package/lib/services/output/log/logger.js.map +1 -1
  84. package/lib/services/output/log/structured.js +2 -2
  85. package/lib/services/output/log/structured.js.map +1 -1
  86. package/lib/services/output/output.js +197 -0
  87. package/lib/services/output/output.js.map +1 -0
  88. package/lib/services/output/print.js +31 -0
  89. package/lib/services/output/print.js.map +1 -0
  90. package/lib/services/output/problems.js +84 -0
  91. package/lib/services/output/problems.js.map +1 -0
  92. package/lib/services/output/prompt.js +173 -40
  93. package/lib/services/output/prompt.js.map +1 -1
  94. package/lib/services/output/report.js +63 -19
  95. package/lib/services/output/report.js.map +1 -1
  96. package/lib/services/output/select.js +198 -0
  97. package/lib/services/output/select.js.map +1 -0
  98. package/lib/services/output/spinner.js +141 -0
  99. package/lib/services/output/spinner.js.map +1 -0
  100. package/lib/services/output/sprint.js +38 -15
  101. package/lib/services/output/sprint.js.map +1 -1
  102. package/lib/services/output/symbols.js +23 -0
  103. package/lib/services/output/symbols.js.map +1 -0
  104. package/lib/services/output/table.js +98 -0
  105. package/lib/services/output/table.js.map +1 -0
  106. package/lib/services/output/timestamp.js +12 -0
  107. package/lib/services/output/timestamp.js.map +1 -0
  108. package/lib/services/output/update.js +29 -9
  109. package/lib/services/output/update.js.map +1 -1
  110. package/lib/services/user/session.js +4 -0
  111. package/lib/services/user/session.js.map +1 -1
  112. package/lib/services/user/user.js +15 -10
  113. package/lib/services/user/user.js.map +1 -1
  114. package/lib/services/util/assert.js +11 -0
  115. package/lib/services/util/assert.js.map +1 -0
  116. package/lib/services/util/boolean.js +2 -2
  117. package/lib/services/util/boolean.js.map +1 -1
  118. package/lib/services/util/function.js +45 -7
  119. package/lib/services/util/function.js.map +1 -1
  120. package/lib/services/util/is.js +23 -2
  121. package/lib/services/util/is.js.map +1 -1
  122. package/lib/services/util/json.js +16 -13
  123. package/lib/services/util/json.js.map +1 -1
  124. package/lib/services/util/object.js +2 -2
  125. package/lib/services/util/object.js.map +1 -1
  126. package/lib/services/util/promise.js +5 -2
  127. package/lib/services/util/promise.js.map +1 -1
  128. package/lib/services/util/types.js.map +1 -1
  129. package/npm-shrinkwrap.json +3436 -2833
  130. package/package.json +47 -40
  131. package/bin/dev.cmd +0 -3
  132. package/bin/dev.js +0 -14
  133. package/bin/run.cmd +0 -3
  134. package/bin/run.js +0 -5
  135. package/lib/commands/sync.js +0 -284
  136. package/lib/commands/sync.js.map +0 -1
  137. package/lib/services/app/edit/client.js.map +0 -1
  138. package/lib/services/app/edit/error.js.map +0 -1
  139. package/lib/services/output/log/printer.js +0 -120
  140. package/lib/services/output/log/printer.js.map +0 -1
  141. package/lib/services/output/stream.js +0 -54
  142. package/lib/services/output/stream.js.map +0 -1
@@ -1,27 +1,49 @@
1
1
  import assert from "node:assert";
2
2
  import { z } from "zod";
3
3
  import { config } from "../config/config.js";
4
- import { loadCookie } from "../http/auth.js";
4
+ import { loadAuthHeaders } from "../http/auth.js";
5
5
  import { http } from "../http/http.js";
6
- export const App = z.object({
6
+ import { Api } from "./api/api.js";
7
+ import { GADGET_META_MODELS_QUERY } from "./api/operation.js";
8
+ export const EnvironmentType = Object.freeze({
9
+ Development: "development",
10
+ Production: "production",
11
+ Test: "test"
12
+ });
13
+ export const Environment = z.object({
14
+ id: z.union([
15
+ z.string(),
16
+ z.number(),
17
+ z.bigint()
18
+ ]).transform((v)=>BigInt(v)),
19
+ name: z.string().transform((name)=>name.toLowerCase()),
20
+ type: z.nativeEnum(EnvironmentType)
21
+ });
22
+ export const Application = z.object({
7
23
  id: z.union([
8
24
  z.string(),
9
25
  z.number(),
10
26
  z.bigint()
11
- ]),
27
+ ]).transform((v)=>BigInt(v)),
12
28
  slug: z.string(),
13
29
  primaryDomain: z.string(),
14
- hasSplitEnvironments: z.boolean()
30
+ hasSplitEnvironments: z.boolean(),
31
+ multiEnvironmentEnabled: z.boolean(),
32
+ environments: z.array(Environment)
33
+ });
34
+ export const ModelApiIdentifier = z.object({
35
+ apiIdentifier: z.string()
15
36
  });
16
37
  /**
17
38
  * Retrieves a list of apps for the given user. If the user is not
18
39
  * logged in, an empty array is returned instead.
19
40
  *
20
41
  * @param ctx - The current context.
21
- * @returns A promise that resolves to an array of App objects.
22
- */ export const getApps = async (ctx)=>{
23
- const cookie = loadCookie();
24
- if (!cookie) {
42
+ * @returns A promise that resolves to an array of Application objects.
43
+ */ // TODO: cache this
44
+ export const getApps = async (ctx)=>{
45
+ const headers = loadAuthHeaders();
46
+ if (!headers) {
25
47
  return [];
26
48
  }
27
49
  assert(ctx.user, "must get user before getting apps");
@@ -31,12 +53,24 @@ export const App = z.object({
31
53
  },
32
54
  url: `https://${config.domains.services}/auth/api/apps`,
33
55
  headers: {
34
- cookie
56
+ ...headers
35
57
  },
36
58
  responseType: "json",
37
59
  resolveBodyOnly: true
38
60
  });
39
- return z.array(App).parse(json);
61
+ return z.array(Application).parse(json);
62
+ };
63
+ export const getModels = async (ctx)=>{
64
+ const headers = loadAuthHeaders();
65
+ if (!headers) {
66
+ return [];
67
+ }
68
+ assert(ctx.user, "must get user before getting models");
69
+ const api = new Api(ctx);
70
+ const { gadgetMeta } = await api.query({
71
+ query: GADGET_META_MODELS_QUERY
72
+ });
73
+ return gadgetMeta.models;
40
74
  };
41
75
 
42
76
  //# sourceMappingURL=app.js.map
@@ -1 +1 @@
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"}
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 { loadAuthHeaders } from \"../http/auth.js\";\nimport { http } from \"../http/http.js\";\nimport { Api } from \"./api/api.js\";\nimport { GADGET_META_MODELS_QUERY } from \"./api/operation.js\";\n\nexport const EnvironmentType = Object.freeze({\n Development: \"development\",\n Production: \"production\",\n Test: \"test\",\n});\n\nexport type EnvironmentType = keyof typeof EnvironmentType;\n\nexport const Environment = z.object({\n id: z.union([z.string(), z.number(), z.bigint()]).transform((v) => BigInt(v)),\n name: z.string().transform((name) => name.toLowerCase()),\n type: z.nativeEnum(EnvironmentType),\n});\n\nexport type Environment = z.infer<typeof Environment>;\n\nexport const Application = z.object({\n id: z.union([z.string(), z.number(), z.bigint()]).transform((v) => BigInt(v)),\n slug: z.string(),\n primaryDomain: z.string(),\n hasSplitEnvironments: z.boolean(),\n multiEnvironmentEnabled: z.boolean(),\n environments: z.array(Environment),\n});\n\nexport type Application = z.infer<typeof Application>;\n\nexport const ModelApiIdentifier = z.object({\n apiIdentifier: z.string(),\n});\n\nexport type ModelApiIdentifier = z.infer<typeof ModelApiIdentifier>;\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 Application objects.\n */\n// TODO: cache this\nexport const getApps = async (ctx: Context): Promise<Application[]> => {\n const headers = loadAuthHeaders();\n if (!headers) {\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: { ...headers },\n responseType: \"json\",\n resolveBodyOnly: true,\n });\n\n return z.array(Application).parse(json);\n};\n\nexport const getModels = async (ctx: Context): Promise<ModelApiIdentifier[] | []> => {\n const headers = loadAuthHeaders();\n if (!headers) {\n return [];\n }\n\n assert(ctx.user, \"must get user before getting models\");\n\n const api = new Api(ctx);\n const { gadgetMeta } = await api.query({ query: GADGET_META_MODELS_QUERY });\n return gadgetMeta.models;\n};\n"],"names":["assert","z","config","loadAuthHeaders","http","Api","GADGET_META_MODELS_QUERY","EnvironmentType","Object","freeze","Development","Production","Test","Environment","object","id","union","string","number","bigint","transform","v","BigInt","name","toLowerCase","type","nativeEnum","Application","slug","primaryDomain","hasSplitEnvironments","boolean","multiEnvironmentEnabled","environments","array","ModelApiIdentifier","apiIdentifier","getApps","ctx","headers","user","json","context","url","domains","services","responseType","resolveBodyOnly","parse","getModels","api","gadgetMeta","query","models"],"mappings":"AAAA,OAAOA,YAAY,cAAc;AACjC,SAASC,CAAC,QAAQ,MAAM;AAExB,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,eAAe,QAAQ,kBAAkB;AAClD,SAASC,IAAI,QAAQ,kBAAkB;AACvC,SAASC,GAAG,QAAQ,eAAe;AACnC,SAASC,wBAAwB,QAAQ,qBAAqB;AAE9D,OAAO,MAAMC,kBAAkBC,OAAOC,MAAM,CAAC;IAC3CC,aAAa;IACbC,YAAY;IACZC,MAAM;AACR,GAAG;AAIH,OAAO,MAAMC,cAAcZ,EAAEa,MAAM,CAAC;IAClCC,IAAId,EAAEe,KAAK,CAAC;QAACf,EAAEgB,MAAM;QAAIhB,EAAEiB,MAAM;QAAIjB,EAAEkB,MAAM;KAAG,EAAEC,SAAS,CAAC,CAACC,IAAMC,OAAOD;IAC1EE,MAAMtB,EAAEgB,MAAM,GAAGG,SAAS,CAAC,CAACG,OAASA,KAAKC,WAAW;IACrDC,MAAMxB,EAAEyB,UAAU,CAACnB;AACrB,GAAG;AAIH,OAAO,MAAMoB,cAAc1B,EAAEa,MAAM,CAAC;IAClCC,IAAId,EAAEe,KAAK,CAAC;QAACf,EAAEgB,MAAM;QAAIhB,EAAEiB,MAAM;QAAIjB,EAAEkB,MAAM;KAAG,EAAEC,SAAS,CAAC,CAACC,IAAMC,OAAOD;IAC1EO,MAAM3B,EAAEgB,MAAM;IACdY,eAAe5B,EAAEgB,MAAM;IACvBa,sBAAsB7B,EAAE8B,OAAO;IAC/BC,yBAAyB/B,EAAE8B,OAAO;IAClCE,cAAchC,EAAEiC,KAAK,CAACrB;AACxB,GAAG;AAIH,OAAO,MAAMsB,qBAAqBlC,EAAEa,MAAM,CAAC;IACzCsB,eAAenC,EAAEgB,MAAM;AACzB,GAAG;AAIH;;;;;;CAMC,GACD,mBAAmB;AACnB,OAAO,MAAMoB,UAAU,OAAOC;IAC5B,MAAMC,UAAUpC;IAChB,IAAI,CAACoC,SAAS;QACZ,OAAO,EAAE;IACX;IAEAvC,OAAOsC,IAAIE,IAAI,EAAE;IAEjB,MAAMC,OAAO,MAAMrC,KAAK;QACtBsC,SAAS;YAAEJ;QAAI;QACfK,KAAK,CAAC,QAAQ,EAAEzC,OAAO0C,OAAO,CAACC,QAAQ,CAAC,cAAc,CAAC;QACvDN,SAAS;YAAE,GAAGA,OAAO;QAAC;QACtBO,cAAc;QACdC,iBAAiB;IACnB;IAEA,OAAO9C,EAAEiC,KAAK,CAACP,aAAaqB,KAAK,CAACP;AACpC,EAAE;AAEF,OAAO,MAAMQ,YAAY,OAAOX;IAC9B,MAAMC,UAAUpC;IAChB,IAAI,CAACoC,SAAS;QACZ,OAAO,EAAE;IACX;IAEAvC,OAAOsC,IAAIE,IAAI,EAAE;IAEjB,MAAMU,MAAM,IAAI7C,IAAIiC;IACpB,MAAM,EAAEa,UAAU,EAAE,GAAG,MAAMD,IAAIE,KAAK,CAAC;QAAEA,OAAO9C;IAAyB;IACzE,OAAO6C,WAAWE,MAAM;AAC1B,EAAE"}
@@ -3,12 +3,12 @@ import { createClient } from "graphql-ws";
3
3
  import assert from "node:assert";
4
4
  import PQueue from "p-queue";
5
5
  import WebSocket from "ws";
6
- import { config } from "../../config/config.js";
7
- import { loadCookie } from "../../http/auth.js";
8
- import { http } from "../../http/http.js";
9
- import { noop, unthunk } from "../../util/function.js";
10
- import { isObject } from "../../util/is.js";
11
- import { EditError } from "./error.js";
6
+ import { config } from "../config/config.js";
7
+ import { loadAuthHeaders } from "../http/auth.js";
8
+ import { http } from "../http/http.js";
9
+ import { noop, unthunk } from "../util/function.js";
10
+ import { isObject } from "../util/is.js";
11
+ import { ClientError } from "./error.js";
12
12
  var ConnectionStatus;
13
13
  (function(ConnectionStatus) {
14
14
  ConnectionStatus[ConnectionStatus["CONNECTED"] = 0] = "CONNECTED";
@@ -17,7 +17,7 @@ var ConnectionStatus;
17
17
  })(ConnectionStatus || (ConnectionStatus = {}));
18
18
  /**
19
19
  * Client is a GraphQL client connected to a Gadget application's
20
- * /edit/api/graphql endpoint.
20
+ * given endpoint.
21
21
  */ export class Client {
22
22
  /**
23
23
  * Subscribe to a GraphQL subscription.
@@ -38,7 +38,7 @@ var ConnectionStatus;
38
38
  const queue = new PQueue({
39
39
  concurrency: 1
40
40
  });
41
- const onError = (error)=>optionsOnError(new EditError(subscription, error));
41
+ const onError = (error)=>optionsOnError(new ClientError(subscription, error));
42
42
  const unsubscribe = this._graphqlWsClient.subscribe(request, {
43
43
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
44
44
  next: (response)=>queue.add(()=>onResponse(response)).catch(onError),
@@ -56,10 +56,13 @@ var ConnectionStatus;
56
56
  * Execute a GraphQL query or mutation.
57
57
  */ async execute(ctx, request) {
58
58
  assert(ctx.app, "missing app when executing GraphQL query");
59
- const cookie = loadCookie();
60
- assert(cookie, "missing cookie when executing GraphQL request");
59
+ assert(ctx.env, "missing env when executing GraphQL query");
60
+ const headers = loadAuthHeaders();
61
+ assert(headers, "missing headers when executing GraphQL request");
61
62
  let subdomain = ctx.app.slug;
62
- if (ctx.app.hasSplitEnvironments) {
63
+ if (ctx.app.multiEnvironmentEnabled) {
64
+ subdomain += `--${ctx.env.name}`;
65
+ } else if (ctx.app.hasSplitEnvironments) {
63
66
  subdomain += "--development";
64
67
  }
65
68
  try {
@@ -68,9 +71,10 @@ var ConnectionStatus;
68
71
  ctx
69
72
  },
70
73
  method: "POST",
71
- url: `https://${subdomain}.${config.domains.app}/edit/api/graphql`,
74
+ url: `https://${subdomain}.${config.domains.app}${this.endpoint}`,
72
75
  headers: {
73
- cookie
76
+ ...headers,
77
+ "x-gadget-environment": ctx.env.name
74
78
  },
75
79
  json: {
76
80
  query: request.operation,
@@ -89,7 +93,7 @@ var ConnectionStatus;
89
93
  }
90
94
  return json;
91
95
  } catch (error) {
92
- throw new EditError(request.operation, error);
96
+ throw new ClientError(request.operation, error);
93
97
  }
94
98
  }
95
99
  /**
@@ -97,15 +101,18 @@ var ConnectionStatus;
97
101
  */ async dispose() {
98
102
  await this._graphqlWsClient.dispose();
99
103
  }
100
- constructor(ctx){
104
+ constructor(ctx, endpoint){
101
105
  // assume the client is going to connect
102
106
  _define_property(this, "status", 0);
103
107
  _define_property(this, "ctx", void 0);
108
+ _define_property(this, "endpoint", void 0);
104
109
  _define_property(this, "_graphqlWsClient", void 0);
105
110
  this.ctx = ctx.child({
106
111
  name: "client"
107
112
  });
108
- assert(ctx.app, "missing app when creating edit client");
113
+ assert(ctx.app, "app must be set on Client context");
114
+ assert(ctx.env, "env must be set on Client context");
115
+ this.endpoint = endpoint;
109
116
  let subdomain = ctx.app.slug;
110
117
  if (ctx.app.hasSplitEnvironments) {
111
118
  subdomain += "--development";
@@ -113,18 +120,21 @@ var ConnectionStatus;
113
120
  this._graphqlWsClient = createClient({
114
121
  url: `wss://${subdomain}.${config.domains.app}/edit/api/graphql-ws`,
115
122
  shouldRetry: ()=>true,
123
+ connectionParams: {
124
+ environment: ctx.env.name
125
+ },
116
126
  webSocketImpl: class extends WebSocket {
117
127
  constructor(address, protocols, wsOptions){
118
128
  // this cookie should be available since we were given an app which requires a cookie to load
119
- const cookie = loadCookie();
120
- assert(cookie, "missing cookie when connecting to GraphQL API");
129
+ const headers = loadAuthHeaders();
130
+ assert(headers, "missing headers when connecting to GraphQL API");
121
131
  super(address, protocols, {
122
132
  signal: ctx.signal,
123
133
  ...wsOptions,
124
134
  headers: {
125
135
  ...wsOptions?.headers,
126
136
  "user-agent": config.versionFull,
127
- cookie
137
+ ...headers
128
138
  }
129
139
  });
130
140
  }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/services/app/client.ts"],"sourcesContent":["import type { ExecutionResult } from \"graphql-ws\";\nimport { createClient } from \"graphql-ws\";\nimport assert from \"node:assert\";\nimport type { ClientRequestArgs } from \"node:http\";\nimport PQueue from \"p-queue\";\nimport type { Promisable } from \"type-fest\";\nimport WebSocket from \"ws\";\nimport type { Context } from \"../command/context.js\";\nimport { config } from \"../config/config.js\";\nimport { loadAuthHeaders } from \"../http/auth.js\";\nimport { http, type HttpOptions } from \"../http/http.js\";\nimport { noop, unthunk, type Thunk } from \"../util/function.js\";\nimport { isObject } from \"../util/is.js\";\nimport type { GraphQLMutation, GraphQLQuery, GraphQLSubscription } from \"./edit/operation.js\";\nimport { ClientError } from \"./error.js\";\n\nenum ConnectionStatus {\n CONNECTED,\n DISCONNECTED,\n RECONNECTING,\n}\n\n/**\n * Client is a GraphQL client connected to a Gadget application's\n * given endpoint.\n */\nexport class Client {\n // assume the client is going to connect\n status = ConnectionStatus.CONNECTED;\n\n readonly ctx: Context;\n\n readonly endpoint: string;\n\n private _graphqlWsClient: ReturnType<typeof createClient>;\n\n constructor(ctx: Context, endpoint: string) {\n this.ctx = ctx.child({ name: \"client\" });\n assert(ctx.app, \"app must be set on Client context\");\n assert(ctx.env, \"env must be set on Client context\");\n\n this.endpoint = endpoint;\n\n let subdomain = ctx.app.slug;\n if (ctx.app.hasSplitEnvironments) {\n subdomain += \"--development\";\n }\n\n this._graphqlWsClient = createClient({\n url: `wss://${subdomain}.${config.domains.app}/edit/api/graphql-ws`,\n shouldRetry: () => true,\n connectionParams: {\n environment: ctx.env.name,\n },\n webSocketImpl: class extends WebSocket {\n constructor(address: string | URL, protocols?: string | string[], wsOptions?: WebSocket.ClientOptions | ClientRequestArgs) {\n // this cookie should be available since we were given an app which requires a cookie to load\n const headers = loadAuthHeaders();\n\n assert(headers, \"missing headers when connecting to GraphQL API\");\n\n super(address, protocols, {\n signal: ctx.signal,\n ...wsOptions,\n headers: {\n ...wsOptions?.headers,\n \"user-agent\": config.versionFull,\n ...headers,\n },\n });\n }\n },\n on: {\n connecting: () => {\n switch (this.status) {\n case ConnectionStatus.DISCONNECTED:\n this.status = ConnectionStatus.RECONNECTING;\n this.ctx.log.info(\"reconnecting\");\n break;\n case ConnectionStatus.RECONNECTING:\n this.ctx.log.info(\"retrying\");\n break;\n default:\n this.ctx.log.debug(\"connecting\");\n break;\n }\n },\n connected: () => {\n if (this.status === ConnectionStatus.RECONNECTING) {\n this.ctx.log.info(\"reconnected\");\n } else {\n this.ctx.log.debug(\"connected\");\n }\n\n // let the other on connected listeners see what status we're in\n setImmediate(() => (this.status = ConnectionStatus.CONNECTED));\n },\n closed: () => {\n this.status = ConnectionStatus.DISCONNECTED;\n this.ctx.log.debug(\"disconnected\");\n },\n error: (error) => {\n if (this.status === ConnectionStatus.RECONNECTING) {\n this.ctx.log.error(\"failed to reconnect\", { error });\n } else {\n this.ctx.log.error(\"connection error\", { error });\n }\n },\n },\n });\n }\n\n /**\n * Subscribe to a GraphQL subscription.\n */\n subscribe<Subscription extends GraphQLSubscription>(\n ctx: Context,\n {\n subscription,\n variables,\n onResponse,\n onError: optionsOnError,\n onComplete = noop,\n }: {\n subscription: Subscription;\n variables?: Thunk<Subscription[\"Variables\"]> | null;\n onResponse: (response: ExecutionResult<Subscription[\"Data\"], Subscription[\"Extensions\"]>) => Promisable<void>;\n onError: (error: ClientError) => Promisable<void>;\n onComplete?: () => Promisable<void>;\n },\n ): () => void {\n let request = { query: subscription, variables: unthunk(variables) };\n\n const removeConnectedListener = this._graphqlWsClient.on(\"connected\", () => {\n if (this.status === ConnectionStatus.RECONNECTING) {\n request = { query: subscription, variables: unthunk(variables) };\n ctx.log.info(\"re-subscribing to graphql subscription\");\n }\n });\n\n const queue = new PQueue({ concurrency: 1 });\n const onError = (error: unknown): Promisable<void> => optionsOnError(new ClientError(subscription, error));\n\n const unsubscribe = this._graphqlWsClient.subscribe<Subscription[\"Data\"], Subscription[\"Extensions\"]>(request, {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n next: (response) => queue.add(() => onResponse(response)).catch(onError),\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n error: (error) => queue.add(() => onError(error)),\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n complete: () => queue.add(() => onComplete()).catch(onError),\n });\n\n return () => {\n removeConnectedListener();\n unsubscribe();\n };\n }\n\n /**\n * Execute a GraphQL query or mutation.\n */\n async execute<Operation extends GraphQLQuery | GraphQLMutation>(\n ctx: Context,\n request: {\n operation: Operation;\n variables?: Thunk<Operation[\"Variables\"]> | null;\n http?: HttpOptions;\n },\n ): Promise<ExecutionResult<Operation[\"Data\"], Operation[\"Extensions\"]>> {\n assert(ctx.app, \"missing app when executing GraphQL query\");\n assert(ctx.env, \"missing env when executing GraphQL query\");\n\n const headers = loadAuthHeaders();\n assert(headers, \"missing headers when executing GraphQL request\");\n\n let subdomain = ctx.app.slug;\n if (ctx.app.multiEnvironmentEnabled) {\n subdomain += `--${ctx.env.name}`;\n } else if (ctx.app.hasSplitEnvironments) {\n subdomain += \"--development\";\n }\n\n try {\n const json = await http({\n context: { ctx },\n method: \"POST\",\n url: `https://${subdomain}.${config.domains.app}${this.endpoint}`,\n headers: { ...headers, \"x-gadget-environment\": ctx.env.name },\n json: { query: request.operation, variables: unthunk(request.variables) },\n responseType: \"json\",\n resolveBodyOnly: true,\n throwHttpErrors: false,\n ...request.http,\n });\n\n if (!isObject(json) || (!(\"data\" in json) && !(\"errors\" in json))) {\n ctx.log.error(\"received invalid graphql response\", { error: json });\n throw json;\n }\n\n return json as Operation[\"Response\"];\n } catch (error) {\n throw new ClientError(request.operation, error);\n }\n }\n\n /**\n * Close the connection to the server.\n */\n async dispose(): Promise<void> {\n await this._graphqlWsClient.dispose();\n }\n}\n"],"names":["createClient","assert","PQueue","WebSocket","config","loadAuthHeaders","http","noop","unthunk","isObject","ClientError","ConnectionStatus","Client","subscribe","ctx","subscription","variables","onResponse","onError","optionsOnError","onComplete","request","query","removeConnectedListener","_graphqlWsClient","on","status","log","info","queue","concurrency","error","unsubscribe","next","response","add","catch","complete","execute","app","env","headers","subdomain","slug","multiEnvironmentEnabled","name","hasSplitEnvironments","json","context","method","url","domains","endpoint","operation","responseType","resolveBodyOnly","throwHttpErrors","dispose","constructor","child","shouldRetry","connectionParams","environment","webSocketImpl","address","protocols","wsOptions","signal","versionFull","connecting","debug","connected","setImmediate","closed"],"mappings":"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"}
@@ -2,10 +2,14 @@ import { _ as _class_private_field_get } from "@swc/helpers/_/_class_private_fie
2
2
  import { _ as _class_private_field_init } from "@swc/helpers/_/_class_private_field_init";
3
3
  import { _ as _class_private_field_set } from "@swc/helpers/_/_class_private_field_set";
4
4
  import { _ as _define_property } from "@swc/helpers/_/_define_property";
5
+ import assert from "node:assert";
5
6
  import { unthunk } from "../../util/function.js";
6
- import { Client } from "./client.js";
7
- import { EditError } from "./error.js";
8
- var _client = /*#__PURE__*/ new WeakMap();
7
+ import { Client } from "../client.js";
8
+ import { ClientError } from "../error.js";
9
+ var /**
10
+ * The client used to make requests to Gadget's /edit/api/graphql
11
+ * endpoint.
12
+ */ _client = /*#__PURE__*/ new WeakMap();
9
13
  export class Edit {
10
14
  /**
11
15
  * Execute a GraphQL query.
@@ -16,7 +20,8 @@ export class Edit {
16
20
  * @param request.http - {@linkcode HttpOptions} to pass to http.
17
21
  * @returns The data returned by the server.
18
22
  */ async query({ query, variables, ...options }) {
19
- const name = query.split(/ |\(/, 2)[1];
23
+ const name = query.match(/query (\w+)/)?.[1];
24
+ assert(name, "query name not found");
20
25
  const ctx = this.ctx.child({
21
26
  fields: {
22
27
  edit: {
@@ -46,10 +51,10 @@ export class Edit {
46
51
  }
47
52
  });
48
53
  if (response.errors) {
49
- throw new EditError(query, response.errors);
54
+ throw new ClientError(query, response.errors);
50
55
  }
51
56
  if (!response.data) {
52
- throw new EditError(query, "Query response did not contain data");
57
+ throw new ClientError(query, "Query response did not contain data");
53
58
  }
54
59
  return response.data;
55
60
  }
@@ -57,12 +62,13 @@ export class Edit {
57
62
  * Execute a GraphQL mutation.
58
63
  *
59
64
  * @param request - The query and variables to send to the server.
60
- * @param request.mutation - The GraphQL query to execute.
65
+ * @param request.mutation - The GraphQL mutation to execute.
61
66
  * @param request.variables - The variables to send to the server.
62
67
  * @param request.http - {@linkcode HttpOptions} to pass to http.
63
68
  * @returns The data returned by the server.
64
69
  */ async mutate({ mutation, variables, ...options }) {
65
- const name = mutation.split(/ |\(/, 2)[1];
70
+ const name = mutation.match(/mutation (\w+)/)?.[1];
71
+ assert(name, "mutation name not found");
66
72
  const ctx = this.ctx.child({
67
73
  fields: {
68
74
  edit: {
@@ -83,10 +89,10 @@ export class Edit {
83
89
  ...options
84
90
  });
85
91
  if (response.errors) {
86
- throw new EditError(mutation, response.errors);
92
+ throw new ClientError(mutation, response.errors);
87
93
  }
88
94
  if (!response.data) {
89
- throw new EditError(mutation, "Mutation response did not contain data");
95
+ throw new ClientError(mutation, "Mutation response did not contain data");
90
96
  }
91
97
  return response.data;
92
98
  }
@@ -96,13 +102,14 @@ export class Edit {
96
102
  * @param options - The query and variables to send to the server.
97
103
  * @param options.subscription - The GraphQL subscription to subscribe to.
98
104
  * @param options.variables - The variables to send to the server.
99
- * @param options.onData - A callback that will be called with the data returned by the server.
100
- * @param options.onError - A callback that will be called with any errors returned by the server.
101
- * @param options.onComplete - A callback that will be called when the subscription is complete.
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.
102
108
  * @returns A function to unsubscribe from the subscription.
103
109
  */ subscribe({ onData, ...options }) {
104
- const name = options.subscription.split(/ |\(/, 2)[1];
105
- const ctx = this.ctx.child({
110
+ const name = options.subscription.match(/subscription (\w+)/)?.[1];
111
+ assert(name, "subscription name not found");
112
+ let ctx = this.ctx.child({
106
113
  fields: {
107
114
  edit: {
108
115
  subscription: name
@@ -115,24 +122,51 @@ export class Edit {
115
122
  }
116
123
  }
117
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
+ };
118
138
  ctx.log.info("subscribing to graphql subscription");
119
- const unsubscribe = _class_private_field_get(this, _client).subscribe(ctx, {
139
+ let unsubscribe = _class_private_field_get(this, _client).subscribe(ctx, {
120
140
  ...options,
121
- onResponse: async (response)=>{
122
- if (response.errors) {
123
- unsubscribe();
124
- await options.onError(new EditError(options.subscription, response.errors));
125
- return;
126
- }
127
- if (!response.data) {
128
- unsubscribe();
129
- await options.onError(new EditError(options.subscription, "Subscription response did not contain data"));
130
- return;
141
+ onResponse
142
+ });
143
+ return {
144
+ unsubscribe,
145
+ resubscribe: (variables)=>{
146
+ unsubscribe();
147
+ if (variables !== undefined) {
148
+ options.variables = variables;
131
149
  }
132
- await onData(response.data);
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
+ });
133
168
  }
134
- });
135
- return unsubscribe;
169
+ };
136
170
  }
137
171
  /**
138
172
  * Close the client.
@@ -140,7 +174,9 @@ export class Edit {
140
174
  await _class_private_field_get(this, _client).dispose();
141
175
  }
142
176
  constructor(ctx){
143
- _define_property(this, "ctx", void 0);
177
+ /**
178
+ * The {@linkcode Context} that was used to create this instance.
179
+ */ _define_property(this, "ctx", void 0);
144
180
  _class_private_field_init(this, _client, {
145
181
  writable: true,
146
182
  value: void 0
@@ -148,7 +184,7 @@ export class Edit {
148
184
  this.ctx = ctx.child({
149
185
  name: "edit"
150
186
  });
151
- _class_private_field_set(this, _client, new Client(this.ctx));
187
+ _class_private_field_set(this, _client, new Client(this.ctx, "/edit/api/graphql"));
152
188
  }
153
189
  }
154
190
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/services/app/edit/edit.ts"],"sourcesContent":["import 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 { EditError } from \"./error.js\";\nimport type { GraphQLMutation, GraphQLQuery, GraphQLSubscription } from \"./operation.js\";\n\nexport class Edit {\n readonly ctx: Context;\n #client: Client;\n\n constructor(ctx: Context) {\n this.ctx = ctx.child({ name: \"edit\" });\n this.#client = new Client(this.ctx);\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.split(/ |\\(/, 2)[1];\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 EditError(query, response.errors);\n }\n\n if (!response.data) {\n throw new EditError(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 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 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.split(/ |\\(/, 2)[1];\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 EditError(mutation, response.errors);\n }\n\n if (!response.data) {\n throw new EditError(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 with the data returned by the server.\n * @param options.onError - A callback that will be called with any errors returned by the server.\n * @param options.onComplete - A callback that will be called when the subscription is complete.\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: EditError) => Promisable<void>;\n onComplete?: () => Promisable<void>;\n }): () => void {\n const name = options.subscription.split(/ |\\(/, 2)[1];\n const ctx = this.ctx.child({\n fields: { edit: { subscription: name } },\n devFields: { edit: { subscription: name, variables: unthunk(options.variables) } },\n });\n\n ctx.log.info(\"subscribing to graphql subscription\");\n const unsubscribe = this.#client.subscribe(ctx, {\n ...options,\n onResponse: async (response) => {\n if (response.errors) {\n unsubscribe();\n await options.onError(new EditError(options.subscription, response.errors));\n return;\n }\n\n if (!response.data) {\n unsubscribe();\n await options.onError(new EditError(options.subscription, \"Subscription response did not contain data\"));\n return;\n }\n\n await onData(response.data);\n },\n });\n\n return unsubscribe;\n }\n\n /**\n * Close the client.\n */\n async dispose(): Promise<void> {\n await this.#client.dispose();\n }\n}\n"],"names":["unthunk","Client","EditError","Edit","query","variables","options","name","split","ctx","child","fields","edit","devFields","log","info","response","client","execute","operation","http","retry","methods","errors","data","mutate","mutation","subscribe","onData","subscription","unsubscribe","onResponse","onError","dispose","constructor"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/services/app/edit/edit.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 { ClientError } from \"../error.js\";\nimport type { GraphQLMutation, GraphQLQuery, GraphQLSubscription } from \"./operation.js\";\n\nexport class Edit {\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 /edit/api/graphql\n * endpoint.\n */\n #client: Client;\n\n constructor(ctx: Context) {\n this.ctx = ctx.child({ name: \"edit\" });\n this.#client = new Client(this.ctx, \"/edit/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","Edit","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":"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"}
@@ -24,6 +24,12 @@ export const PUBLISH_FILE_SYNC_EVENTS_MUTATION = sprint(/* GraphQL */ `
24
24
  mutation PublishFileSyncEvents($input: PublishFileSyncEventsInput!) {
25
25
  publishFileSyncEvents(input: $input) {
26
26
  remoteFilesVersion
27
+ problems {
28
+ level
29
+ message
30
+ path
31
+ type
32
+ }
27
33
  }
28
34
  }
29
35
  `);
@@ -62,9 +68,10 @@ export const FILE_SYNC_COMPARISON_HASHES_QUERY = sprint(/* GraphQL */ `
62
68
  }
63
69
  }
64
70
  `);
65
- export const REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION = sprint(/* GraphQL */ `
66
- subscription publishStatus($localFilesVersion: String!, $force: Boolean) {
67
- publishStatus(localFilesVersion: $localFilesVersion, force: $force) {
71
+ export const PUBLISH_STATUS_SUBSCRIPTION = sprint(/* GraphQL */ `
72
+ subscription PublishStatus($localFilesVersion: String!, $force: Boolean, $allowCharges: Boolean) {
73
+ publishStatus(localFilesVersion: $localFilesVersion, force: $force, allowCharges: $allowCharges) {
74
+ publishStarted
68
75
  remoteFilesVersion
69
76
  progress
70
77
  issues {
@@ -79,6 +86,15 @@ export const REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION = sprint(/* GraphQL */ `
79
86
  parentKey
80
87
  parentApiIdentifier
81
88
  }
89
+ nodeLabels {
90
+ type
91
+ identifier
92
+ }
93
+ }
94
+ status {
95
+ code
96
+ message
97
+ output
82
98
  }
83
99
  }
84
100
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/services/app/edit/operation.ts"],"sourcesContent":["import type { ExecutionResult } from \"graphql-ws\";\nimport type { JsonObject } from \"type-fest\";\nimport type {\n FileSyncComparisonHashesQuery,\n FileSyncComparisonHashesQueryVariables,\n FileSyncFilesQuery,\n FileSyncFilesQueryVariables,\n FileSyncHashesQuery,\n FileSyncHashesQueryVariables,\n PublishFileSyncEventsMutation,\n PublishFileSyncEventsMutationVariables,\n PublishStatusSubscription,\n PublishStatusSubscriptionVariables,\n RemoteFileSyncEventsSubscription,\n RemoteFileSyncEventsSubscriptionVariables,\n RemoteFilesVersionQuery,\n RemoteFilesVersionQueryVariables,\n} from \"../../../__generated__/graphql.js\";\nimport { sprint } from \"../../output/sprint.js\";\n\n/**\n * A GraphQL query with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLQuery<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"query\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\n/**\n * A GraphQL mutation with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLMutation<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"mutation\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\n/**\n * A GraphQL subscription with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLSubscription<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"subscription\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\nexport const REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION = sprint(/* GraphQL */ `\n subscription RemoteFileSyncEvents($localFilesVersion: String!) {\n remoteFileSyncEvents(localFilesVersion: $localFilesVersion, encoding: base64) {\n remoteFilesVersion\n changed {\n path\n mode\n content\n encoding\n }\n deleted {\n path\n }\n }\n }\n`) as GraphQLSubscription<RemoteFileSyncEventsSubscription, RemoteFileSyncEventsSubscriptionVariables>;\n\nexport type REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION = typeof REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION;\n\nexport const REMOTE_FILES_VERSION_QUERY = sprint(/* GraphQL */ `\n query RemoteFilesVersion {\n remoteFilesVersion\n }\n`) as GraphQLQuery<RemoteFilesVersionQuery, RemoteFilesVersionQueryVariables>;\n\nexport type REMOTE_FILES_VERSION_QUERY = typeof REMOTE_FILES_VERSION_QUERY;\n\nexport const PUBLISH_FILE_SYNC_EVENTS_MUTATION = sprint(/* GraphQL */ `\n mutation PublishFileSyncEvents($input: PublishFileSyncEventsInput!) {\n publishFileSyncEvents(input: $input) {\n remoteFilesVersion\n }\n }\n`) as GraphQLMutation<PublishFileSyncEventsMutation, PublishFileSyncEventsMutationVariables>;\n\nexport type PUBLISH_FILE_SYNC_EVENTS_MUTATION = typeof PUBLISH_FILE_SYNC_EVENTS_MUTATION;\n\nexport const FILE_SYNC_FILES_QUERY = sprint(/* GraphQL */ `\n query FileSyncFiles($paths: [String!]!, $filesVersion: String, $encoding: FileSyncEncoding) {\n fileSyncFiles(paths: $paths, filesVersion: $filesVersion, encoding: $encoding) {\n filesVersion\n files {\n path\n mode\n content\n encoding\n }\n }\n }\n`) as GraphQLQuery<FileSyncFilesQuery, FileSyncFilesQueryVariables>;\n\nexport type FILE_SYNC_FILES_QUERY = typeof FILE_SYNC_FILES_QUERY;\n\nexport const FILE_SYNC_HASHES_QUERY = sprint(/* GraphQL */ `\n query FileSyncHashes($filesVersion: String) {\n fileSyncHashes(filesVersion: $filesVersion) {\n filesVersion\n hashes\n }\n }\n`) as GraphQLQuery<FileSyncHashesQuery, FileSyncHashesQueryVariables>;\n\nexport type FILE_SYNC_HASHES_QUERY = typeof FILE_SYNC_HASHES_QUERY;\n\nexport const FILE_SYNC_COMPARISON_HASHES_QUERY = sprint(/* GraphQL */ `\n query FileSyncComparisonHashes($filesVersion: String!) {\n fileSyncComparisonHashes(filesVersion: $filesVersion) {\n filesVersionHashes {\n filesVersion\n hashes\n }\n latestFilesVersionHashes {\n filesVersion\n hashes\n }\n }\n }\n`) as GraphQLQuery<FileSyncComparisonHashesQuery, FileSyncComparisonHashesQueryVariables>;\n\nexport type FILE_SYNC_COMPARISON_HASHES_QUERY = typeof FILE_SYNC_COMPARISON_HASHES_QUERY;\n\nexport const REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION = sprint(/* GraphQL */ `\n subscription publishStatus($localFilesVersion: String!, $force: Boolean) {\n publishStatus(localFilesVersion: $localFilesVersion, force: $force) {\n remoteFilesVersion\n progress\n issues {\n severity\n message\n node {\n type\n key\n apiIdentifier\n name\n fieldType\n parentKey\n parentApiIdentifier\n }\n }\n }\n }\n`) as GraphQLSubscription<PublishStatusSubscription, PublishStatusSubscriptionVariables>;\n\nexport type REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION = typeof REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION;\n"],"names":["sprint","REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION","REMOTE_FILES_VERSION_QUERY","PUBLISH_FILE_SYNC_EVENTS_MUTATION","FILE_SYNC_FILES_QUERY","FILE_SYNC_HASHES_QUERY","FILE_SYNC_COMPARISON_HASHES_QUERY","REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION"],"mappings":"AAkBA,SAASA,MAAM,QAAQ,yBAAyB;AAwDhD,OAAO,MAAMC,uCAAuCD,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;;;;AAe1E,CAAC,EAAsG;AAIvG,OAAO,MAAME,6BAA6BF,OAAO,WAAW,GAAG,CAAC;;;;AAIhE,CAAC,EAA6E;AAI9E,OAAO,MAAMG,oCAAoCH,OAAO,WAAW,GAAG,CAAC;;;;;;AAMvE,CAAC,EAA4F;AAI7F,OAAO,MAAMI,wBAAwBJ,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;AAY3D,CAAC,EAAmE;AAIpE,OAAO,MAAMK,yBAAyBL,OAAO,WAAW,GAAG,CAAC;;;;;;;AAO5D,CAAC,EAAqE;AAItE,OAAO,MAAMM,oCAAoCN,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;;AAavE,CAAC,EAAyF;AAI1F,OAAO,MAAMO,6CAA6CP,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;AAoBhF,CAAC,EAAwF"}
1
+ {"version":3,"sources":["../../../../src/services/app/edit/operation.ts"],"sourcesContent":["import type { ExecutionResult } from \"graphql-ws\";\nimport type { JsonObject } from \"type-fest\";\nimport type {\n FileSyncComparisonHashesQuery,\n FileSyncComparisonHashesQueryVariables,\n FileSyncFilesQuery,\n FileSyncFilesQueryVariables,\n FileSyncHashesQuery,\n FileSyncHashesQueryVariables,\n PublishFileSyncEventsMutation,\n PublishFileSyncEventsMutationVariables,\n PublishStatusSubscription,\n PublishStatusSubscriptionVariables,\n RemoteFileSyncEventsSubscription,\n RemoteFileSyncEventsSubscriptionVariables,\n RemoteFilesVersionQuery,\n RemoteFilesVersionQueryVariables,\n} from \"../../../__generated__/graphql.js\";\nimport { sprint } from \"../../output/sprint.js\";\n\n/**\n * A GraphQL query with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLQuery<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"query\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\n/**\n * A GraphQL mutation with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLMutation<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"mutation\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\n/**\n * A GraphQL subscription with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLSubscription<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"subscription\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\nexport const REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION = sprint(/* GraphQL */ `\n subscription RemoteFileSyncEvents($localFilesVersion: String!) {\n remoteFileSyncEvents(localFilesVersion: $localFilesVersion, encoding: base64) {\n remoteFilesVersion\n changed {\n path\n mode\n content\n encoding\n }\n deleted {\n path\n }\n }\n }\n`) as GraphQLSubscription<RemoteFileSyncEventsSubscription, RemoteFileSyncEventsSubscriptionVariables>;\n\nexport type REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION = typeof REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION;\n\nexport const REMOTE_FILES_VERSION_QUERY = sprint(/* GraphQL */ `\n query RemoteFilesVersion {\n remoteFilesVersion\n }\n`) as GraphQLQuery<RemoteFilesVersionQuery, RemoteFilesVersionQueryVariables>;\n\nexport type REMOTE_FILES_VERSION_QUERY = typeof REMOTE_FILES_VERSION_QUERY;\n\nexport const PUBLISH_FILE_SYNC_EVENTS_MUTATION = sprint(/* GraphQL */ `\n mutation PublishFileSyncEvents($input: PublishFileSyncEventsInput!) {\n publishFileSyncEvents(input: $input) {\n remoteFilesVersion\n problems {\n level\n message\n path\n type\n }\n }\n }\n`) as GraphQLMutation<PublishFileSyncEventsMutation, PublishFileSyncEventsMutationVariables>;\n\nexport type PUBLISH_FILE_SYNC_EVENTS_MUTATION = typeof PUBLISH_FILE_SYNC_EVENTS_MUTATION;\n\nexport const FILE_SYNC_FILES_QUERY = sprint(/* GraphQL */ `\n query FileSyncFiles($paths: [String!]!, $filesVersion: String, $encoding: FileSyncEncoding) {\n fileSyncFiles(paths: $paths, filesVersion: $filesVersion, encoding: $encoding) {\n filesVersion\n files {\n path\n mode\n content\n encoding\n }\n }\n }\n`) as GraphQLQuery<FileSyncFilesQuery, FileSyncFilesQueryVariables>;\n\nexport type FILE_SYNC_FILES_QUERY = typeof FILE_SYNC_FILES_QUERY;\n\nexport const FILE_SYNC_HASHES_QUERY = sprint(/* GraphQL */ `\n query FileSyncHashes($filesVersion: String) {\n fileSyncHashes(filesVersion: $filesVersion) {\n filesVersion\n hashes\n }\n }\n`) as GraphQLQuery<FileSyncHashesQuery, FileSyncHashesQueryVariables>;\n\nexport type FILE_SYNC_HASHES_QUERY = typeof FILE_SYNC_HASHES_QUERY;\n\nexport const FILE_SYNC_COMPARISON_HASHES_QUERY = sprint(/* GraphQL */ `\n query FileSyncComparisonHashes($filesVersion: String!) {\n fileSyncComparisonHashes(filesVersion: $filesVersion) {\n filesVersionHashes {\n filesVersion\n hashes\n }\n latestFilesVersionHashes {\n filesVersion\n hashes\n }\n }\n }\n`) as GraphQLQuery<FileSyncComparisonHashesQuery, FileSyncComparisonHashesQueryVariables>;\n\nexport type FILE_SYNC_COMPARISON_HASHES_QUERY = typeof FILE_SYNC_COMPARISON_HASHES_QUERY;\n\nexport const PUBLISH_STATUS_SUBSCRIPTION = sprint(/* GraphQL */ `\n subscription PublishStatus($localFilesVersion: String!, $force: Boolean, $allowCharges: Boolean) {\n publishStatus(localFilesVersion: $localFilesVersion, force: $force, allowCharges: $allowCharges) {\n publishStarted\n remoteFilesVersion\n progress\n issues {\n severity\n message\n node {\n type\n key\n apiIdentifier\n name\n fieldType\n parentKey\n parentApiIdentifier\n }\n nodeLabels {\n type\n identifier\n }\n }\n status {\n code\n message\n output\n }\n }\n }\n`) as GraphQLSubscription<PublishStatusSubscription, PublishStatusSubscriptionVariables>;\n\nexport type PUBLISH_STATUS_SUBSCRIPTION = typeof PUBLISH_STATUS_SUBSCRIPTION;\n"],"names":["sprint","REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION","REMOTE_FILES_VERSION_QUERY","PUBLISH_FILE_SYNC_EVENTS_MUTATION","FILE_SYNC_FILES_QUERY","FILE_SYNC_HASHES_QUERY","FILE_SYNC_COMPARISON_HASHES_QUERY","PUBLISH_STATUS_SUBSCRIPTION"],"mappings":"AAkBA,SAASA,MAAM,QAAQ,yBAAyB;AAwDhD,OAAO,MAAMC,uCAAuCD,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;;;;AAe1E,CAAC,EAAsG;AAIvG,OAAO,MAAME,6BAA6BF,OAAO,WAAW,GAAG,CAAC;;;;AAIhE,CAAC,EAA6E;AAI9E,OAAO,MAAMG,oCAAoCH,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;AAYvE,CAAC,EAA4F;AAI7F,OAAO,MAAMI,wBAAwBJ,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;AAY3D,CAAC,EAAmE;AAIpE,OAAO,MAAMK,yBAAyBL,OAAO,WAAW,GAAG,CAAC;;;;;;;AAO5D,CAAC,EAAqE;AAItE,OAAO,MAAMM,oCAAoCN,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;;AAavE,CAAC,EAAyF;AAI1F,OAAO,MAAMO,8BAA8BP,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BjE,CAAC,EAAwF"}
@@ -1,12 +1,12 @@
1
1
  import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
2
  import assert from "node:assert";
3
3
  import pluralize from "pluralize";
4
- import { CLIError, IsBug } from "../../output/report.js";
5
- import { sprint } from "../../output/sprint.js";
6
- import { uniq } from "../../util/collection.js";
7
- import { isCloseEvent, isError, isErrorEvent, isGraphQLErrors, isString } from "../../util/is.js";
8
- import { serializeError } from "../../util/object.js";
9
- export class EditError extends CLIError {
4
+ import { GGTError, IsBug } from "../output/report.js";
5
+ import { sprint } from "../output/sprint.js";
6
+ import { uniq } from "../util/collection.js";
7
+ import { isCloseEvent, isError, isErrorEvent, isGraphQLErrors, isString } from "../util/is.js";
8
+ import { serializeError } from "../util/object.js";
9
+ export class ClientError extends GGTError {
10
10
  render() {
11
11
  let body = "";
12
12
  switch(true){
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/services/app/error.ts"],"sourcesContent":["import type { GraphQLError } from \"graphql\";\nimport assert from \"node:assert\";\nimport pluralize from \"pluralize\";\nimport type { CloseEvent, ErrorEvent } from \"ws\";\nimport { GGTError, IsBug } from \"../output/report.js\";\nimport { sprint } from \"../output/sprint.js\";\nimport { uniq } from \"../util/collection.js\";\nimport { isCloseEvent, isError, isErrorEvent, isGraphQLErrors, isString } from \"../util/is.js\";\nimport { serializeError } from \"../util/object.js\";\nimport type { GraphQLMutation, GraphQLQuery, GraphQLSubscription } from \"./edit/operation.js\";\n\nexport class ClientError extends GGTError {\n isBug = IsBug.MAYBE;\n\n override cause: string | Error | readonly GraphQLError[] | CloseEvent | ErrorEvent;\n\n constructor(\n readonly request: GraphQLQuery | GraphQLMutation | GraphQLSubscription,\n cause: unknown,\n ) {\n super(\"An error occurred while communicating with Gadget\");\n\n // ErrorEvent and CloseEvent aren't serializable, so we reconstruct\n // them into an object. We discard the `target` property because\n // it's large and not that useful\n if (isErrorEvent(cause)) {\n this.cause = {\n type: cause.type,\n message: cause.message,\n error: serializeError(cause.error),\n } as ErrorEvent;\n } else if (isCloseEvent(cause)) {\n this.cause = {\n type: cause.type,\n code: cause.code,\n reason: cause.reason,\n wasClean: cause.wasClean,\n } as CloseEvent;\n } else {\n assert(\n isString(cause) || isError(cause) || isGraphQLErrors(cause),\n \"cause must be a string, Error, GraphQLError[], CloseEvent, or ErrorEvent\",\n );\n this.cause = cause;\n }\n }\n\n override render(): string {\n let body = \"\";\n\n switch (true) {\n case isGraphQLErrors(this.cause): {\n const errors = uniq(this.cause.map((x) => x.message));\n body = sprint`\n Gadget responded with the following ${pluralize(\"error\", errors.length, false)}:\n\n • ${errors.join(\"\\n • \")}\n `;\n break;\n }\n case isCloseEvent(this.cause):\n body = \"The connection to Gadget closed unexpectedly.\";\n break;\n case isErrorEvent(this.cause) || isError(this.cause):\n body = this.cause.message;\n break;\n default:\n body = this.cause;\n break;\n }\n\n return this.message + \"\\n\\n\" + body;\n }\n}\n"],"names":["assert","pluralize","GGTError","IsBug","sprint","uniq","isCloseEvent","isError","isErrorEvent","isGraphQLErrors","isString","serializeError","ClientError","render","body","cause","errors","map","x","message","length","join","constructor","request","isBug","MAYBE","type","error","code","reason","wasClean"],"mappings":";AACA,OAAOA,YAAY,cAAc;AACjC,OAAOC,eAAe,YAAY;AAElC,SAASC,QAAQ,EAAEC,KAAK,QAAQ,sBAAsB;AACtD,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,IAAI,QAAQ,wBAAwB;AAC7C,SAASC,YAAY,EAAEC,OAAO,EAAEC,YAAY,EAAEC,eAAe,EAAEC,QAAQ,QAAQ,gBAAgB;AAC/F,SAASC,cAAc,QAAQ,oBAAoB;AAGnD,OAAO,MAAMC,oBAAoBV;IAoCtBW,SAAiB;QACxB,IAAIC,OAAO;QAEX,OAAQ;YACN,KAAKL,gBAAgB,IAAI,CAACM,KAAK;gBAAG;oBAChC,MAAMC,SAASX,KAAK,IAAI,CAACU,KAAK,CAACE,GAAG,CAAC,CAACC,IAAMA,EAAEC,OAAO;oBACnDL,OAAOV,MAAM,CAAC;8CACwB,EAAEH,UAAU,SAASe,OAAOI,MAAM,EAAE,OAAO;;cAE3E,EAAEJ,OAAOK,IAAI,CAAC,oBAAoB;QACxC,CAAC;oBACD;gBACF;YACA,KAAKf,aAAa,IAAI,CAACS,KAAK;gBAC1BD,OAAO;gBACP;YACF,KAAKN,aAAa,IAAI,CAACO,KAAK,KAAKR,QAAQ,IAAI,CAACQ,KAAK;gBACjDD,OAAO,IAAI,CAACC,KAAK,CAACI,OAAO;gBACzB;YACF;gBACEL,OAAO,IAAI,CAACC,KAAK;gBACjB;QACJ;QAEA,OAAO,IAAI,CAACI,OAAO,GAAG,SAASL;IACjC;IAxDAQ,YACE,AAASC,OAA6D,EACtER,KAAc,CACd;QACA,KAAK,CAAC;;QARRS,uBAAAA,SAAAA,KAAAA;QAEA,uBAAST,SAAT,KAAA;aAGWQ,UAAAA;aALXC,QAAQrB,MAAMsB,KAAK;QAUjB,mEAAmE;QACnE,gEAAgE;QAChE,iCAAiC;QACjC,IAAIjB,aAAaO,QAAQ;YACvB,IAAI,CAACA,KAAK,GAAG;gBACXW,MAAMX,MAAMW,IAAI;gBAChBP,SAASJ,MAAMI,OAAO;gBACtBQ,OAAOhB,eAAeI,MAAMY,KAAK;YACnC;QACF,OAAO,IAAIrB,aAAaS,QAAQ;YAC9B,IAAI,CAACA,KAAK,GAAG;gBACXW,MAAMX,MAAMW,IAAI;gBAChBE,MAAMb,MAAMa,IAAI;gBAChBC,QAAQd,MAAMc,MAAM;gBACpBC,UAAUf,MAAMe,QAAQ;YAC1B;QACF,OAAO;YACL9B,OACEU,SAASK,UAAUR,QAAQQ,UAAUN,gBAAgBM,QACrD;YAEF,IAAI,CAACA,KAAK,GAAGA;QACf;IACF;AA4BF"}
@@ -1,6 +1,6 @@
1
1
  import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
2
  import arg from "arg";
3
- import { CLIError, IsBug, UnexpectedError } from "../output/report.js";
3
+ import { GGTError, IsBug, UnexpectedError } from "../output/report.js";
4
4
  import { isNil } from "../util/is.js";
5
5
  export const parseArgs = (args, options)=>{
6
6
  const spec = {};
@@ -30,17 +30,17 @@ export const parseArgs = (args, options)=>{
30
30
  return parsed;
31
31
  } catch (error) {
32
32
  if (error instanceof arg.ArgError) {
33
- // convert arg.ArgError to CLIError
33
+ // convert arg.ArgError to GGTError
34
34
  // eslint-disable-next-line no-ex-assign
35
35
  error = new ArgError(error.message);
36
36
  }
37
- if (error instanceof CLIError) {
37
+ if (error instanceof GGTError) {
38
38
  throw error;
39
39
  }
40
40
  throw new UnexpectedError(error);
41
41
  }
42
42
  };
43
- export class ArgError extends CLIError {
43
+ export class ArgError extends GGTError {
44
44
  render() {
45
45
  return this.message;
46
46
  }