@gadgetinc/ggt 0.2.3 → 0.3.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 (70) hide show
  1. package/README.md +79 -90
  2. package/bin/dev.js +11 -19
  3. package/bin/run.js +1 -9
  4. package/lib/__generated__/graphql.js +2 -2
  5. package/lib/__generated__/graphql.js.map +1 -1
  6. package/lib/commands/index.js +9 -0
  7. package/lib/commands/index.js.map +1 -0
  8. package/lib/commands/list.js +34 -49
  9. package/lib/commands/list.js.map +1 -1
  10. package/lib/commands/login.js +74 -17
  11. package/lib/commands/login.js.map +1 -1
  12. package/lib/commands/logout.js +19 -23
  13. package/lib/commands/logout.js.map +1 -1
  14. package/lib/commands/root.js +85 -0
  15. package/lib/commands/root.js.map +1 -0
  16. package/lib/commands/sync.js +313 -677
  17. package/lib/commands/sync.js.map +1 -1
  18. package/lib/commands/whoami.js +23 -27
  19. package/lib/commands/whoami.js.map +1 -1
  20. package/lib/main.js +12 -0
  21. package/lib/main.js.map +1 -0
  22. package/lib/services/app.js +36 -0
  23. package/lib/services/app.js.map +1 -0
  24. package/lib/services/args.js +28 -0
  25. package/lib/services/args.js.map +1 -0
  26. package/lib/services/client.js +43 -76
  27. package/lib/services/client.js.map +1 -1
  28. package/lib/services/config.js +139 -0
  29. package/lib/services/config.js.map +1 -0
  30. package/lib/services/errors.js +64 -89
  31. package/lib/services/errors.js.map +1 -1
  32. package/lib/services/filesync.js +404 -0
  33. package/lib/services/filesync.js.map +1 -0
  34. package/lib/services/fs-utils.js +18 -91
  35. package/lib/services/fs-utils.js.map +1 -1
  36. package/lib/services/http.js +53 -0
  37. package/lib/services/http.js.map +1 -0
  38. package/lib/services/log.js +45 -0
  39. package/lib/services/log.js.map +1 -0
  40. package/lib/services/notify.js +30 -0
  41. package/lib/services/notify.js.map +1 -0
  42. package/lib/services/output.js +59 -0
  43. package/lib/services/output.js.map +1 -0
  44. package/lib/services/promise.js +8 -5
  45. package/lib/services/promise.js.map +1 -1
  46. package/lib/services/session.js +27 -0
  47. package/lib/services/session.js.map +1 -0
  48. package/lib/services/sleep.js +2 -5
  49. package/lib/services/sleep.js.map +1 -1
  50. package/lib/services/timeout.js +8 -0
  51. package/lib/services/timeout.js.map +1 -0
  52. package/lib/services/user.js +70 -0
  53. package/lib/services/user.js.map +1 -0
  54. package/lib/services/version.js +72 -0
  55. package/lib/services/version.js.map +1 -0
  56. package/npm-shrinkwrap.json +16947 -26644
  57. package/package.json +68 -75
  58. package/lib/commands/help.js +0 -28
  59. package/lib/commands/help.js.map +0 -1
  60. package/lib/index.js +0 -3
  61. package/lib/index.js.map +0 -1
  62. package/lib/services/base-command.js +0 -203
  63. package/lib/services/base-command.js.map +0 -1
  64. package/lib/services/context.js +0 -143
  65. package/lib/services/context.js.map +0 -1
  66. package/lib/services/flags.js +0 -57
  67. package/lib/services/flags.js.map +0 -1
  68. package/lib/services/help.js +0 -36
  69. package/lib/services/help.js.map +0 -1
  70. package/oclif.manifest.json +0 -244
package/README.md CHANGED
@@ -22,6 +22,18 @@
22
22
 
23
23
  </div>
24
24
 
25
+ ## Table of Contents
26
+
27
+ - [Intro](#intro)
28
+ - [Quick Start](#quick-start)
29
+ - [Usage](#usage)
30
+ - [Commands](#commands)
31
+ - [`ggt sync`](#ggt-sync)
32
+ - [`ggt list`](#ggt-list)
33
+ - [`ggt login`](#ggt-login)
34
+ - [`ggt logout`](#ggt-logout)
35
+ - [`ggt whoami`](#ggt-whoami)
36
+
25
37
  ## Intro
26
38
 
27
39
  `ggt` is the command line interface for the Gadget platform, providing additional functionality for working with your Gadget applications using your existing tools on your machine. `ggt` isn't required for building end-to-end Gadget apps but supports syncing files locally (and more soon) for your preferred coding experience.
@@ -40,67 +52,84 @@ With this running in the background, your local `~/gadget/my-app` folder will be
40
52
 
41
53
  ```sh-session
42
54
  $ npm install -g @gadgetinc/ggt
43
- $ ggt COMMAND
44
- running command...
45
- $ ggt --version
46
- @gadgetinc/ggt/0.0.0 darwin-arm64 node-v18.0.0
47
- $ ggt help [COMMAND]
48
- USAGE
49
- $ ggt COMMAND
50
- ...
51
- ```
55
+ $ ggt
56
+ The command-line interface for Gadget
52
57
 
53
- ## Commands
58
+ VERSION
59
+ ggt/0.3.0 linux-x64 node-v16.20.2
54
60
 
55
- <!-- commands -->
61
+ USAGE
62
+ $ ggt [COMMAND]
56
63
 
57
- - [`ggt sync [DIRECTORY] [--app <name>]`](#ggt-sync-directory---app-name)
58
- - [`ggt help [COMMAND]`](#ggt-help-command)
59
- - [`ggt list`](#ggt-list)
60
- - [`ggt login`](#ggt-login)
61
- - [`ggt logout`](#ggt-logout)
62
- - [`ggt whoami`](#ggt-whoami)
64
+ FLAGS
65
+ -h, --help Print command's usage
66
+ -v, --version Print version
67
+ --debug Print debug output
68
+
69
+ COMMANDS
70
+ sync Sync your Gadget application's source code to and
71
+ from your local filesystem.
72
+ list List your apps.
73
+ login Log in to your account.
74
+ logout Log out of your account.
75
+ whoami Print the currently logged in account.
76
+ ```
63
77
 
64
- ### `ggt sync [DIRECTORY] [--app <name>]`
78
+ ## Commands
65
79
 
66
- Sync your Gadget application's source code to and from your local filesystem.
80
+ ### `ggt sync`
67
81
 
68
82
  ```
83
+ Sync your Gadget application's source code to and from
84
+ your local filesystem.
85
+
69
86
  USAGE
70
87
  $ ggt sync [DIRECTORY] [--app <name>]
71
88
 
72
89
  ARGUMENTS
73
- DIRECTORY [default: .] The directory to sync files to. If the directory doesn't exist, it will be created.
90
+ DIRECTORY [default: .] The directory to sync files to.
91
+
92
+ If the directory doesn't exist, it will be created.
74
93
 
75
94
  FLAGS
76
95
  -a, --app=<name> The Gadget application to sync files to.
77
- --force Whether to sync even if we can't determine the state of your local files relative to your remote
78
- ones.
96
+
97
+ --force Whether to sync even if we can't determine
98
+ the state of your local files relative to
99
+ your remote ones.
79
100
 
80
101
  DESCRIPTION
81
- Sync provides the ability to sync your Gadget application's source code to and from your local
82
- filesystem. While ggt sync is running, local file changes are immediately reflected within
83
- Gadget, while files that are changed remotely are immediately saved to your local filesystem.
102
+ Sync provides the ability to sync your Gadget application's source
103
+ code to and from your local filesystem.
104
+
105
+ While ggt sync is running, local file changes are immediately
106
+ reflected within Gadget, while files that are changed remotely are
107
+ immediately saved to your local filesystem.
84
108
 
85
109
  Use cases for this include:
86
- - Developing locally with your own editor like VSCode (https://code.visualstudio.com/)
87
- - Storing your source code in a Git repository like GitHub (https://github.com/)
110
+ Developing locally with your own editor like VSCode
111
+ Storing your source code in a Git repository like GitHub
88
112
 
89
- Sync includes the concept of a .ignore file. This file may contain a list of files and
90
- directories that won't be received or sent to Gadget when syncing. The format of this file is
91
- identical to the one used by Git (https://git-scm.com/docs/gitignore).
113
+ Sync includes the concept of a .ignore file. This file may
114
+ contain a list of files and directories that won't be received or
115
+ sent to Gadget when syncing. The format of this file is identical
116
+ to the one used by Git (https://git-scm.com/docs/gitignore).
92
117
 
93
118
  The following files and directories are always ignored:
94
- - .gadget
95
- - .git
96
- - node_modules
119
+ .DS_Store
120
+ .gadget
121
+ .git
122
+ • node_modules
97
123
 
98
124
  Note:
99
- - If you have separate development and production environments, ggt sync will only sync with your development environment
100
- - Gadget applications only support installing dependencies with Yarn 1 (https://classic.yarnpkg.com/lang/en/)
101
- - Since file changes are immediately reflected in Gadget, avoid the following while ggt sync is running:
102
- - Deleting all your files
103
- - Moving all your files to a different directory
125
+ If you have separate development and production environments,
126
+ ggt sync will only sync with your development environment
127
+ Gadget applications only support installing dependencies
128
+ with Yarn 1 (https://classic.yarnpkg.com/lang/en/)
129
+ Since file changes are immediately reflected in Gadget,
130
+ avoid the following while ggt sync is running:
131
+ • Deleting all your files
132
+ • Moving all your files to a different directory
104
133
 
105
134
  EXAMPLES
106
135
  $ ggt sync --app my-app ~/gadget/my-app
@@ -111,8 +140,8 @@ EXAMPLES
111
140
  Docs https://docs.gadget.dev/api/my-app
112
141
 
113
142
  Endpoints
114
- - https://my-app.gadget.app
115
- - https://my-app--development.gadget.app
143
+ https://my-app.gadget.app
144
+ https://my-app--development.gadget.app
116
145
 
117
146
  Watching for file changes... Press Ctrl+C to stop
118
147
 
@@ -129,54 +158,28 @@ EXAMPLES
129
158
  Goodbye!
130
159
  ```
131
160
 
132
- _See code: [src/commands/sync.ts](https://github.com/gadget-inc/ggt/blob/v0.2.3/src/commands/sync.ts)_
133
-
134
- ### `ggt help [COMMAND]`
135
-
136
- Display help for ggt.
137
-
138
- ```
139
- USAGE
140
- $ ggt help [COMMAND]
141
-
142
- ARGUMENTS
143
- COMMAND The command to show help for.
144
- ```
145
-
146
- _See code: [src/commands/help.ts](https://github.com/gadget-inc/ggt/blob/v0.2.3/src/commands/help.ts)_
147
-
148
161
  ### `ggt list`
149
162
 
163
+ ```
150
164
  List the apps available to the currently logged in user.
151
165
 
152
- ```
153
166
  USAGE
154
167
  $ ggt list
155
168
 
156
- FLAGS
157
- -x, --extended show extra columns
158
- --columns=<value> only show provided columns (comma-separated)
159
- --csv output is csv format [alias: --output=csv]
160
- --filter=<value> filter property by partial string matching, ex: name=foo
161
- --no-header hide table header from output
162
- --no-truncate do not truncate output to fit screen
163
- --output=<option> output in a more machine friendly format
164
- <options: csv|json|yaml>
165
- --sort=<value> property to sort by (prepend '-' for descending)
166
-
167
- EXAMPLES
169
+ EXAMPLE
168
170
  $ ggt list
169
- $ ggt list --extended
170
- $ ggt list --sort=slug
171
+ Slug Domain
172
+ ─────── ──────────────────
173
+ my-app my-app.gadget.app
174
+ example example.gadget.app
175
+ test test.gadget.app
171
176
  ```
172
177
 
173
- _See code: [src/commands/list.ts](https://github.com/gadget-inc/ggt/blob/v0.2.3/src/commands/list.ts)_
174
-
175
178
  ### `ggt login`
176
179
 
180
+ ```
177
181
  Log in to your account.
178
182
 
179
- ```
180
183
  USAGE
181
184
  $ ggt login
182
185
 
@@ -189,13 +192,11 @@ EXAMPLES
189
192
  Hello, Jane Doe (jane@example.com)
190
193
  ```
191
194
 
192
- _See code: [src/commands/login.ts](https://github.com/gadget-inc/ggt/blob/v0.2.3/src/commands/login.ts)_
193
-
194
195
  ### `ggt logout`
195
196
 
197
+ ```
196
198
  Log out of your account.
197
199
 
198
- ```
199
200
  USAGE
200
201
  $ ggt logout
201
202
 
@@ -204,13 +205,11 @@ EXAMPLES
204
205
  Goodbye
205
206
  ```
206
207
 
207
- _See code: [src/commands/logout.ts](https://github.com/gadget-inc/ggt/blob/v0.2.3/src/commands/logout.ts)_
208
-
209
208
  ### `ggt whoami`
210
209
 
210
+ ```
211
211
  Show the name and email address of the currently logged in user.
212
212
 
213
- ```
214
213
  USAGE
215
214
  $ ggt whoami
216
215
 
@@ -218,13 +217,3 @@ EXAMPLES
218
217
  $ ggt whoami
219
218
  You are logged in as Jane Doe (jane@example.com)
220
219
  ```
221
-
222
- _See code: [src/commands/whoami.ts](https://github.com/gadget-inc/ggt/blob/v0.2.3/src/commands/whoami.ts)_
223
-
224
- <!-- commandsstop -->
225
-
226
- ## Global Flags
227
-
228
- ### Debug
229
-
230
- The `--debug` flag, shorthand `-D`, enables verbose output for debugging purposes.
package/bin/dev.js CHANGED
@@ -1,24 +1,16 @@
1
- #!/usr/bin/env node --loader ts-node/esm --no-warnings
1
+ #!/usr/bin/env node --loader @swc-node/register/esm --no-warnings
2
2
 
3
- import oclif from "@oclif/core";
4
- import path from "node:path";
3
+ import { dirname, join } from "node:path";
5
4
  import process from "node:process";
6
- import url from "node:url";
5
+ import { fileURLToPath } from "node:url";
7
6
 
8
- process.env["NODE_ENV"] = "development";
9
- process.env["GGT_ENV"] ??= "development";
10
-
11
- const workspaceRoot = path.join(path.dirname(url.fileURLToPath(import.meta.url)), "..");
7
+ const workspaceRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
12
8
 
13
- // store files in the project's tmp directory
14
- // https://github.com/oclif/core/blob/503e263f1c224fb2b2e28538975e4d5e0a5d2028/src/config/config.ts#L155
15
- process.env["GGT_CONFIG_DIR"] = path.join(workspaceRoot, "tmp", "config");
16
- process.env["GGT_CACHE_DIR"] = path.join(workspaceRoot, "tmp", "cache");
17
- process.env["GGT_DATA_DIR"] = path.join(workspaceRoot, "tmp", "data");
18
-
19
- process.on("unhandledRejection", oclif.Errors.handle);
9
+ process.env["NODE_ENV"] ??= "development";
10
+ process.env["GGT_ENV"] ??= "development";
11
+ process.env["GGT_SENTRY_ENABLED"] ??= "false";
12
+ process.env["GGT_CONFIG_DIR"] ??= join(workspaceRoot, "tmp/config");
13
+ process.env["GGT_CACHE_DIR"] ??= join(workspaceRoot, "tmp/cache");
14
+ process.env["GGT_DATA_DIR"] ??= join(workspaceRoot, "tmp/data");
20
15
 
21
- oclif
22
- .run(process.argv.slice(2), import.meta.url)
23
- .then(() => oclif.flush())
24
- .catch(oclif.Errors.handle);
16
+ await import("../src/main.js");
package/bin/run.js CHANGED
@@ -1,11 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import oclif from "@oclif/core";
4
- import process from "node:process";
5
-
6
- process.on("unhandledRejection", oclif.Errors.handle);
7
-
8
- oclif
9
- .run(process.argv.slice(2), import.meta.url)
10
- .then(() => oclif.flush())
11
- .catch(oclif.Errors.handle);
3
+ import "../lib/main.js";
@@ -6,8 +6,8 @@
6
6
  * ======================================================
7
7
  */ export var FileSyncEncoding;
8
8
  (function(FileSyncEncoding) {
9
- FileSyncEncoding["Base64"] = 'base64';
10
- FileSyncEncoding["Utf8"] = 'utf8';
9
+ FileSyncEncoding["Base64"] = "base64";
10
+ FileSyncEncoding["Utf8"] = "utf8";
11
11
  })(FileSyncEncoding || (FileSyncEncoding = {}));
12
12
 
13
13
  //# sourceMappingURL=graphql.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/__generated__/graphql.ts"],"sourcesContent":["/**\n * ======================================================\n * THIS IS A GENERATED FILE! DO NOT EDIT IT MANUALLY!\n *\n * You can regenerate it by running `npm run generate-graphql`.\n * ======================================================\n */\n\nexport type Maybe<T> = T | null;\nexport type InputMaybe<T> = Maybe<T>;\nexport type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };\nexport type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };\nexport type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };\nexport type MakeEmpty<T extends { [key: string]: unknown }, K extends keyof T> = { [_ in K]?: never };\nexport type Incremental<T> = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };\n/** All built-in and custom scalars, mapped to their actual values */\nexport type Scalars = {\n ID: { input: string | number; output: string; }\n String: { input: string; output: string; }\n Boolean: { input: boolean; output: boolean; }\n Int: { input: number; output: number; }\n Float: { input: number; output: number; }\n /** A date string, such as 2007-12-03, compliant with the `full-date` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. */\n Date: { input: any; output: any; }\n /** A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. */\n DateTime: { input: any; output: any; }\n JSON: { input: { [key: string]: any }; output: { [key: string]: any }; }\n /** The `Upload` scalar type represents a file upload. */\n Upload: { input: any; output: any; }\n};\n\nexport type ApiUpgradeConvergePlanResult = {\n __typename?: 'APIUpgradeConvergePlanResult';\n items: Array<Scalars['JSON']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type ChangeAppDomainResult = {\n __typename?: 'ChangeAppDomainResult';\n onlyValidate?: Maybe<Scalars['Boolean']['output']>;\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type ContributorResult = {\n __typename?: 'ContributorResult';\n email: Scalars['String']['output'];\n isOwner: Scalars['Boolean']['output'];\n isPending: Scalars['Boolean']['output'];\n};\n\nexport type DeleteAppStatusResult = {\n __typename?: 'DeleteAppStatusResult';\n isNotCreator?: Maybe<Scalars['Boolean']['output']>;\n isNotOwner?: Maybe<Scalars['Boolean']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnableFrontendResult = {\n __typename?: 'EnableFrontendResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnvironmentPatchResult = {\n __typename?: 'EnvironmentPatchResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnvironmentPublishResult = {\n __typename?: 'EnvironmentPublishResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnvironmentSubscriptionResult = {\n __typename?: 'EnvironmentSubscriptionResult';\n patches: Array<Scalars['JSON']['output']>;\n};\n\nexport type EnvironmentTreeClientId = {\n clientType: Scalars['String']['input'];\n id: Scalars['String']['input'];\n};\n\nexport type FileSyncChangedEvent = {\n __typename?: 'FileSyncChangedEvent';\n content: Scalars['String']['output'];\n encoding: FileSyncEncoding;\n mode: Scalars['Float']['output'];\n path: Scalars['String']['output'];\n};\n\nexport type FileSyncChangedEventInput = {\n content: Scalars['String']['input'];\n encoding?: InputMaybe<FileSyncEncoding>;\n mode: Scalars['Float']['input'];\n oldPath?: InputMaybe<Scalars['String']['input']>;\n path: Scalars['String']['input'];\n};\n\nexport type FileSyncDeletedEvent = {\n __typename?: 'FileSyncDeletedEvent';\n path: Scalars['String']['output'];\n};\n\nexport type FileSyncDeletedEventInput = {\n path: Scalars['String']['input'];\n};\n\nexport enum FileSyncEncoding {\n Base64 = 'base64',\n Utf8 = 'utf8'\n}\n\nexport type GadgetRole = {\n __typename?: 'GadgetRole';\n key: Scalars['String']['output'];\n name: Scalars['String']['output'];\n order: Scalars['Int']['output'];\n selectable: Scalars['Boolean']['output'];\n};\n\nexport type IdentifySupportConversationResult = {\n __typename?: 'IdentifySupportConversationResult';\n identificationEmail: Scalars['String']['output'];\n identificationToken: Scalars['String']['output'];\n};\n\nexport type LogSearchResult = {\n __typename?: 'LogSearchResult';\n data: Scalars['JSON']['output'];\n status: Scalars['String']['output'];\n};\n\nexport type MigrateEnvironmentsResult = {\n __typename?: 'MigrateEnvironmentsResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type Mutation = {\n __typename?: 'Mutation';\n changeAppDomain?: Maybe<ChangeAppDomainResult>;\n deleteApp?: Maybe<DeleteAppStatusResult>;\n enableFrontend?: Maybe<EnableFrontendResult>;\n migrateEnvironments?: Maybe<MigrateEnvironmentsResult>;\n patchEnvironmentTree?: Maybe<EnvironmentPatchResult>;\n publish?: Maybe<EnvironmentPublishResult>;\n publishFileSyncEvents: PublishFileSyncEventsResult;\n refreshScopes?: Maybe<RefreshScopesResult>;\n registerWebhooks?: Maybe<RegisterWebhooksResult>;\n removeContributor?: Maybe<RemoveContributorResult>;\n sendAppInvitation?: Maybe<SendAppInvitationResult>;\n unregisterWebhooks?: Maybe<UnregisterWebhooksResult>;\n uploadFiles: UploadFilesResult;\n};\n\n\nexport type MutationChangeAppDomainArgs = {\n newSubdomain: Scalars['String']['input'];\n onlyValidate?: InputMaybe<Scalars['Boolean']['input']>;\n};\n\n\nexport type MutationEnableFrontendArgs = {\n hasShopifyConnection: Scalars['Boolean']['input'];\n};\n\n\nexport type MutationMigrateEnvironmentsArgs = {\n existingToProduction: Scalars['Boolean']['input'];\n};\n\n\nexport type MutationPatchEnvironmentTreeArgs = {\n clientID: EnvironmentTreeClientId;\n patches: Array<Scalars['JSON']['input']>;\n};\n\n\nexport type MutationPublishFileSyncEventsArgs = {\n input: PublishFileSyncEventsInput;\n};\n\n\nexport type MutationRefreshScopesArgs = {\n appConfigKey: Scalars['String']['input'];\n connectionKey: Scalars['String']['input'];\n shopId: Scalars['String']['input'];\n};\n\n\nexport type MutationRegisterWebhooksArgs = {\n connectionKey: Scalars['String']['input'];\n keepExtraTopics?: InputMaybe<Scalars['Boolean']['input']>;\n modelKeys?: InputMaybe<Array<Scalars['String']['input']>>;\n shopIds: Array<Scalars['String']['input']>;\n};\n\n\nexport type MutationRemoveContributorArgs = {\n email: Scalars['String']['input'];\n isInvitation: Scalars['Boolean']['input'];\n};\n\n\nexport type MutationSendAppInvitationArgs = {\n email?: InputMaybe<Scalars['String']['input']>;\n emails?: InputMaybe<Array<Scalars['String']['input']>>;\n resend?: InputMaybe<Scalars['Boolean']['input']>;\n};\n\n\nexport type MutationUnregisterWebhooksArgs = {\n apiKeys?: InputMaybe<Array<Scalars['String']['input']>>;\n connectionKey: Scalars['String']['input'];\n modelKeys?: InputMaybe<Array<Scalars['String']['input']>>;\n};\n\n\nexport type MutationUploadFilesArgs = {\n files: Array<UploadFile>;\n};\n\nexport type PublishFileSyncEventsInput = {\n changed: Array<FileSyncChangedEventInput>;\n deleted: Array<FileSyncDeletedEventInput>;\n expectedRemoteFilesVersion: Scalars['String']['input'];\n};\n\nexport type PublishFileSyncEventsResult = {\n __typename?: 'PublishFileSyncEventsResult';\n remoteFilesVersion: Scalars['String']['output'];\n};\n\nexport type Query = {\n __typename?: 'Query';\n apiUpgradeConvergePlan?: Maybe<ApiUpgradeConvergePlanResult>;\n currentUser: User;\n environmentTreeChildKeys: Array<Scalars['String']['output']>;\n environmentTreePath?: Maybe<Scalars['JSON']['output']>;\n identifySupportConversation?: Maybe<IdentifySupportConversationResult>;\n listContributors: Array<ContributorResult>;\n logsSearch: LogSearchResult;\n remoteFilesVersion: Scalars['String']['output'];\n roles: Array<GadgetRole>;\n runTestSupportFunction?: Maybe<Scalars['JSON']['output']>;\n team: TeamResult;\n typesManifest: TypesManifest;\n};\n\n\nexport type QueryApiUpgradeConvergePlanArgs = {\n currentVersion: Scalars['String']['input'];\n targetVersion: Scalars['String']['input'];\n};\n\n\nexport type QueryEnvironmentTreeChildKeysArgs = {\n path: Scalars['String']['input'];\n};\n\n\nexport type QueryEnvironmentTreePathArgs = {\n hydrateChildrenGlobs?: InputMaybe<Array<Scalars['String']['input']>>;\n path: Scalars['String']['input'];\n};\n\n\nexport type QueryLogsSearchArgs = {\n direction?: InputMaybe<Scalars['String']['input']>;\n end?: InputMaybe<Scalars['DateTime']['input']>;\n limit?: InputMaybe<Scalars['Int']['input']>;\n query: Scalars['String']['input'];\n start?: InputMaybe<Scalars['DateTime']['input']>;\n step?: InputMaybe<Scalars['Int']['input']>;\n};\n\n\nexport type QueryTypesManifestArgs = {\n dependenciesHash: Scalars['String']['input'];\n};\n\nexport type RefreshScopesResult = {\n __typename?: 'RefreshScopesResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type RegisterWebhooksResult = {\n __typename?: 'RegisterWebhooksResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type RemoteFileSyncEvents = {\n __typename?: 'RemoteFileSyncEvents';\n changed: Array<FileSyncChangedEvent>;\n deleted: Array<FileSyncDeletedEvent>;\n remoteFilesVersion: Scalars['String']['output'];\n};\n\nexport type RemoveContributorResult = {\n __typename?: 'RemoveContributorResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type SendAppInvitationResult = {\n __typename?: 'SendAppInvitationResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type Subscription = {\n __typename?: 'Subscription';\n editorActive?: Maybe<Scalars['Boolean']['output']>;\n environmentTreePathPatches?: Maybe<EnvironmentSubscriptionResult>;\n logsSearch: LogSearchResult;\n remoteFileSyncEvents: RemoteFileSyncEvents;\n typesManifestStream: TypesManifest;\n};\n\n\nexport type SubscriptionEnvironmentTreePathPatchesArgs = {\n clientID: EnvironmentTreeClientId;\n path: Scalars['String']['input'];\n};\n\n\nexport type SubscriptionLogsSearchArgs = {\n limit?: InputMaybe<Scalars['Int']['input']>;\n query: Scalars['String']['input'];\n start?: InputMaybe<Scalars['DateTime']['input']>;\n};\n\n\nexport type SubscriptionRemoteFileSyncEventsArgs = {\n encoding?: InputMaybe<FileSyncEncoding>;\n localFilesVersion: Scalars['String']['input'];\n};\n\nexport type TeamMember = {\n __typename?: 'TeamMember';\n contributesToApp: Scalars['Boolean']['output'];\n email: Scalars['String']['output'];\n};\n\nexport type TeamResult = {\n __typename?: 'TeamResult';\n availableSeats?: Maybe<Scalars['Int']['output']>;\n costPerSeat?: Maybe<Scalars['String']['output']>;\n teamMembers: Array<TeamMember>;\n};\n\nexport type TypeManifestEntry = {\n __typename?: 'TypeManifestEntry';\n declaration: Scalars['String']['output'];\n path: Scalars['String']['output'];\n};\n\nexport type TypesManifest = {\n __typename?: 'TypesManifest';\n cdn: Array<Scalars['String']['output']>;\n dependenciesHash: Scalars['String']['output'];\n entries: Array<TypeManifestEntry>;\n environmentVersion: Scalars['Int']['output'];\n};\n\nexport type UnregisterWebhooksResult = {\n __typename?: 'UnregisterWebhooksResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type UploadFile = {\n file: Scalars['Upload']['input'];\n path: Scalars['String']['input'];\n};\n\nexport type UploadFilesResult = {\n __typename?: 'UploadFilesResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type User = {\n __typename?: 'User';\n email: Scalars['String']['output'];\n name?: Maybe<Scalars['String']['output']>;\n};\n\nexport type RemoteFileSyncEventsSubscriptionVariables = Exact<{\n localFilesVersion: Scalars['String']['input'];\n}>;\n\n\nexport type RemoteFileSyncEventsSubscription = { __typename?: 'Subscription', remoteFileSyncEvents: { __typename?: 'RemoteFileSyncEvents', remoteFilesVersion: string, changed: Array<{ __typename?: 'FileSyncChangedEvent', path: string, mode: number, content: string, encoding: FileSyncEncoding }>, deleted: Array<{ __typename?: 'FileSyncDeletedEvent', path: string }> } };\n\nexport type RemoteFilesVersionQueryVariables = Exact<{ [key: string]: never; }>;\n\n\nexport type RemoteFilesVersionQuery = { __typename?: 'Query', remoteFilesVersion: string };\n\nexport type PublishFileSyncEventsMutationVariables = Exact<{\n input: PublishFileSyncEventsInput;\n}>;\n\n\nexport type PublishFileSyncEventsMutation = { __typename?: 'Mutation', publishFileSyncEvents: { __typename?: 'PublishFileSyncEventsResult', remoteFilesVersion: string } };\n"],"names":["FileSyncEncoding","Base64","Utf8"],"mappings":"AAAA;;;;;;CAMC,cAuGM;UAAKA,gBAAgB;IAAhBA,iBACVC,YAAS;IADCD,iBAEVE,UAAO;GAFGF,qBAAAA"}
1
+ {"version":3,"sources":["../../src/__generated__/graphql.ts"],"sourcesContent":["/**\n * ======================================================\n * THIS IS A GENERATED FILE! DO NOT EDIT IT MANUALLY!\n *\n * You can regenerate it by running `npm run generate-graphql`.\n * ======================================================\n */\n\nexport type Maybe<T> = T | null;\nexport type InputMaybe<T> = Maybe<T>;\nexport type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };\nexport type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };\nexport type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };\nexport type MakeEmpty<T extends { [key: string]: unknown }, K extends keyof T> = { [_ in K]?: never };\nexport type Incremental<T> = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };\n/** All built-in and custom scalars, mapped to their actual values */\nexport type Scalars = {\n ID: { input: string | number; output: string; }\n String: { input: string; output: string; }\n Boolean: { input: boolean; output: boolean; }\n Int: { input: number; output: number; }\n Float: { input: number; output: number; }\n /** A date string, such as 2007-12-03, compliant with the `full-date` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. */\n Date: { input: any; output: any; }\n /** A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. */\n DateTime: { input: any; output: any; }\n JSON: { input: { [key: string]: any }; output: { [key: string]: any }; }\n /** The `Upload` scalar type represents a file upload. */\n Upload: { input: any; output: any; }\n};\n\nexport type ApiUpgradeConvergePlanResult = {\n __typename?: 'APIUpgradeConvergePlanResult';\n items: Array<Scalars['JSON']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type ChangeAppDomainResult = {\n __typename?: 'ChangeAppDomainResult';\n onlyValidate?: Maybe<Scalars['Boolean']['output']>;\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type ContributorResult = {\n __typename?: 'ContributorResult';\n email: Scalars['String']['output'];\n isOwner: Scalars['Boolean']['output'];\n isPending: Scalars['Boolean']['output'];\n};\n\nexport type DeleteAppStatusResult = {\n __typename?: 'DeleteAppStatusResult';\n isNotCreator?: Maybe<Scalars['Boolean']['output']>;\n isNotOwner?: Maybe<Scalars['Boolean']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnableFrontendResult = {\n __typename?: 'EnableFrontendResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnvironmentPatchResult = {\n __typename?: 'EnvironmentPatchResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnvironmentPublishResult = {\n __typename?: 'EnvironmentPublishResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnvironmentSubscriptionResult = {\n __typename?: 'EnvironmentSubscriptionResult';\n patches: Array<Scalars['JSON']['output']>;\n};\n\nexport type EnvironmentTreeClientId = {\n clientType: Scalars['String']['input'];\n id: Scalars['String']['input'];\n};\n\nexport type FileSyncChangedEvent = {\n __typename?: 'FileSyncChangedEvent';\n content: Scalars['String']['output'];\n encoding: FileSyncEncoding;\n mode: Scalars['Float']['output'];\n path: Scalars['String']['output'];\n};\n\nexport type FileSyncChangedEventInput = {\n content: Scalars['String']['input'];\n encoding?: InputMaybe<FileSyncEncoding>;\n mode: Scalars['Float']['input'];\n oldPath?: InputMaybe<Scalars['String']['input']>;\n path: Scalars['String']['input'];\n};\n\nexport type FileSyncDeletedEvent = {\n __typename?: 'FileSyncDeletedEvent';\n path: Scalars['String']['output'];\n};\n\nexport type FileSyncDeletedEventInput = {\n path: Scalars['String']['input'];\n};\n\nexport enum FileSyncEncoding {\n Base64 = 'base64',\n Utf8 = 'utf8'\n}\n\nexport type GadgetRole = {\n __typename?: 'GadgetRole';\n key: Scalars['String']['output'];\n name: Scalars['String']['output'];\n order: Scalars['Int']['output'];\n selectable: Scalars['Boolean']['output'];\n};\n\nexport type IdentifySupportConversationResult = {\n __typename?: 'IdentifySupportConversationResult';\n identificationEmail: Scalars['String']['output'];\n identificationToken: Scalars['String']['output'];\n};\n\nexport type LogSearchResult = {\n __typename?: 'LogSearchResult';\n data: Scalars['JSON']['output'];\n status: Scalars['String']['output'];\n};\n\nexport type MigrateEnvironmentsResult = {\n __typename?: 'MigrateEnvironmentsResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type Mutation = {\n __typename?: 'Mutation';\n changeAppDomain?: Maybe<ChangeAppDomainResult>;\n deleteApp?: Maybe<DeleteAppStatusResult>;\n enableFrontend?: Maybe<EnableFrontendResult>;\n migrateEnvironments?: Maybe<MigrateEnvironmentsResult>;\n patchEnvironmentTree?: Maybe<EnvironmentPatchResult>;\n publish?: Maybe<EnvironmentPublishResult>;\n publishFileSyncEvents: PublishFileSyncEventsResult;\n refreshScopes?: Maybe<RefreshScopesResult>;\n registerWebhooks?: Maybe<RegisterWebhooksResult>;\n removeContributor?: Maybe<RemoveContributorResult>;\n sendAppInvitation?: Maybe<SendAppInvitationResult>;\n unregisterWebhooks?: Maybe<UnregisterWebhooksResult>;\n uploadFiles: UploadFilesResult;\n};\n\n\nexport type MutationChangeAppDomainArgs = {\n newSubdomain: Scalars['String']['input'];\n onlyValidate?: InputMaybe<Scalars['Boolean']['input']>;\n};\n\n\nexport type MutationEnableFrontendArgs = {\n hasShopifyConnection: Scalars['Boolean']['input'];\n};\n\n\nexport type MutationMigrateEnvironmentsArgs = {\n existingToProduction: Scalars['Boolean']['input'];\n};\n\n\nexport type MutationPatchEnvironmentTreeArgs = {\n clientID: EnvironmentTreeClientId;\n patches: Array<Scalars['JSON']['input']>;\n};\n\n\nexport type MutationPublishFileSyncEventsArgs = {\n input: PublishFileSyncEventsInput;\n};\n\n\nexport type MutationRefreshScopesArgs = {\n appConfigKey: Scalars['String']['input'];\n connectionKey: Scalars['String']['input'];\n shopId: Scalars['String']['input'];\n};\n\n\nexport type MutationRegisterWebhooksArgs = {\n connectionKey: Scalars['String']['input'];\n keepExtraTopics?: InputMaybe<Scalars['Boolean']['input']>;\n modelKeys?: InputMaybe<Array<Scalars['String']['input']>>;\n shopIds: Array<Scalars['String']['input']>;\n};\n\n\nexport type MutationRemoveContributorArgs = {\n email: Scalars['String']['input'];\n isInvitation: Scalars['Boolean']['input'];\n};\n\n\nexport type MutationSendAppInvitationArgs = {\n email?: InputMaybe<Scalars['String']['input']>;\n emails?: InputMaybe<Array<Scalars['String']['input']>>;\n resend?: InputMaybe<Scalars['Boolean']['input']>;\n};\n\n\nexport type MutationUnregisterWebhooksArgs = {\n apiKeys?: InputMaybe<Array<Scalars['String']['input']>>;\n connectionKey: Scalars['String']['input'];\n modelKeys?: InputMaybe<Array<Scalars['String']['input']>>;\n};\n\n\nexport type MutationUploadFilesArgs = {\n files: Array<UploadFile>;\n};\n\nexport type PublishFileSyncEventsInput = {\n changed: Array<FileSyncChangedEventInput>;\n deleted: Array<FileSyncDeletedEventInput>;\n expectedRemoteFilesVersion: Scalars['String']['input'];\n};\n\nexport type PublishFileSyncEventsResult = {\n __typename?: 'PublishFileSyncEventsResult';\n remoteFilesVersion: Scalars['String']['output'];\n};\n\nexport type Query = {\n __typename?: 'Query';\n apiUpgradeConvergePlan?: Maybe<ApiUpgradeConvergePlanResult>;\n currentUser: User;\n environmentTreeChildKeys: Array<Scalars['String']['output']>;\n environmentTreePath?: Maybe<Scalars['JSON']['output']>;\n identifySupportConversation?: Maybe<IdentifySupportConversationResult>;\n listContributors: Array<ContributorResult>;\n logsSearch: LogSearchResult;\n remoteFilesVersion: Scalars['String']['output'];\n roles: Array<GadgetRole>;\n runTestSupportFunction?: Maybe<Scalars['JSON']['output']>;\n team: TeamResult;\n typesManifest: TypesManifest;\n};\n\n\nexport type QueryApiUpgradeConvergePlanArgs = {\n currentVersion: Scalars['String']['input'];\n targetVersion: Scalars['String']['input'];\n};\n\n\nexport type QueryEnvironmentTreeChildKeysArgs = {\n path: Scalars['String']['input'];\n};\n\n\nexport type QueryEnvironmentTreePathArgs = {\n hydrateChildrenGlobs?: InputMaybe<Array<Scalars['String']['input']>>;\n path: Scalars['String']['input'];\n};\n\n\nexport type QueryLogsSearchArgs = {\n direction?: InputMaybe<Scalars['String']['input']>;\n end?: InputMaybe<Scalars['DateTime']['input']>;\n limit?: InputMaybe<Scalars['Int']['input']>;\n query: Scalars['String']['input'];\n start?: InputMaybe<Scalars['DateTime']['input']>;\n step?: InputMaybe<Scalars['Int']['input']>;\n};\n\n\nexport type QueryTypesManifestArgs = {\n dependenciesHash: Scalars['String']['input'];\n};\n\nexport type RefreshScopesResult = {\n __typename?: 'RefreshScopesResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type RegisterWebhooksResult = {\n __typename?: 'RegisterWebhooksResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type RemoteFileSyncEvents = {\n __typename?: 'RemoteFileSyncEvents';\n changed: Array<FileSyncChangedEvent>;\n deleted: Array<FileSyncDeletedEvent>;\n remoteFilesVersion: Scalars['String']['output'];\n};\n\nexport type RemoveContributorResult = {\n __typename?: 'RemoveContributorResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type SendAppInvitationResult = {\n __typename?: 'SendAppInvitationResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type Subscription = {\n __typename?: 'Subscription';\n editorActive?: Maybe<Scalars['Boolean']['output']>;\n environmentTreePathPatches?: Maybe<EnvironmentSubscriptionResult>;\n logsSearch: LogSearchResult;\n remoteFileSyncEvents: RemoteFileSyncEvents;\n typesManifestStream: TypesManifest;\n};\n\n\nexport type SubscriptionEnvironmentTreePathPatchesArgs = {\n clientID: EnvironmentTreeClientId;\n path: Scalars['String']['input'];\n};\n\n\nexport type SubscriptionLogsSearchArgs = {\n limit?: InputMaybe<Scalars['Int']['input']>;\n query: Scalars['String']['input'];\n start?: InputMaybe<Scalars['DateTime']['input']>;\n};\n\n\nexport type SubscriptionRemoteFileSyncEventsArgs = {\n encoding?: InputMaybe<FileSyncEncoding>;\n localFilesVersion: Scalars['String']['input'];\n};\n\nexport type TeamMember = {\n __typename?: 'TeamMember';\n contributesToApp: Scalars['Boolean']['output'];\n email: Scalars['String']['output'];\n};\n\nexport type TeamResult = {\n __typename?: 'TeamResult';\n availableSeats?: Maybe<Scalars['Int']['output']>;\n costPerSeat?: Maybe<Scalars['String']['output']>;\n teamMembers: Array<TeamMember>;\n};\n\nexport type TypeManifestEntry = {\n __typename?: 'TypeManifestEntry';\n declaration: Scalars['String']['output'];\n path: Scalars['String']['output'];\n};\n\nexport type TypesManifest = {\n __typename?: 'TypesManifest';\n cdn: Array<Scalars['String']['output']>;\n dependenciesHash: Scalars['String']['output'];\n entries: Array<TypeManifestEntry>;\n environmentVersion: Scalars['Int']['output'];\n};\n\nexport type UnregisterWebhooksResult = {\n __typename?: 'UnregisterWebhooksResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type UploadFile = {\n file: Scalars['Upload']['input'];\n path: Scalars['String']['input'];\n};\n\nexport type UploadFilesResult = {\n __typename?: 'UploadFilesResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type User = {\n __typename?: 'User';\n email: Scalars['String']['output'];\n name?: Maybe<Scalars['String']['output']>;\n};\n\nexport type RemoteFileSyncEventsSubscriptionVariables = Exact<{\n localFilesVersion: Scalars['String']['input'];\n}>;\n\n\nexport type RemoteFileSyncEventsSubscription = { __typename?: 'Subscription', remoteFileSyncEvents: { __typename?: 'RemoteFileSyncEvents', remoteFilesVersion: string, changed: Array<{ __typename?: 'FileSyncChangedEvent', path: string, mode: number, content: string, encoding: FileSyncEncoding }>, deleted: Array<{ __typename?: 'FileSyncDeletedEvent', path: string }> } };\n\nexport type RemoteFilesVersionQueryVariables = Exact<{ [key: string]: never; }>;\n\n\nexport type RemoteFilesVersionQuery = { __typename?: 'Query', remoteFilesVersion: string };\n\nexport type PublishFileSyncEventsMutationVariables = Exact<{\n input: PublishFileSyncEventsInput;\n}>;\n\n\nexport type PublishFileSyncEventsMutation = { __typename?: 'Mutation', publishFileSyncEvents: { __typename?: 'PublishFileSyncEventsResult', remoteFilesVersion: string } };\n"],"names":["FileSyncEncoding"],"mappings":"AAAA;;;;;;CAMC;UAuGWA;;;GAAAA,qBAAAA"}
@@ -0,0 +1,9 @@
1
+ export const availableCommands = [
2
+ "sync",
3
+ "list",
4
+ "login",
5
+ "logout",
6
+ "whoami"
7
+ ];
8
+
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/commands/index.ts"],"sourcesContent":["import type { RootArgs } from \"./root.js\";\n\nexport interface Command {\n usage: string;\n init?: (rootArgs: RootArgs) => void | Promise<void>;\n run: (rootArgs: RootArgs) => void | Promise<void>;\n}\n\nexport const availableCommands = [\"sync\", \"list\", \"login\", \"logout\", \"whoami\"] as const;\n"],"names":["availableCommands"],"mappings":"AAQA,OAAO,MAAMA,oBAAoB;IAAC;IAAQ;IAAQ;IAAS;IAAU;CAAS,CAAU"}
@@ -1,54 +1,39 @@
1
- import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
- import { ux } from "@oclif/core";
3
- import chalkTemplate from "chalk-template";
4
- import { dedent } from "ts-dedent";
5
- import { BaseCommand } from "../services/base-command.js";
6
- import { context } from "../services/context.js";
7
- class List extends BaseCommand {
8
- async run() {
9
- const { flags } = await this.parse(List);
10
- const apps = await context.getAvailableApps();
11
- if (!apps.length) {
12
- this.log(dedent`
13
- It doesn't look like you have any applications.
1
+ import _ from "lodash";
2
+ import { getApps } from "../services/app.js";
3
+ import { println, sprint } from "../services/output.js";
4
+ import { getUserOrLogin } from "../services/user.js";
5
+ export const usage = sprint`
6
+ List the apps available to the currently logged in user.
14
7
 
15
- Visit https://gadget.new to create one!
16
- `);
17
- return;
18
- }
19
- ux.table(apps, {
20
- id: {
21
- header: "ID",
22
- extended: true
23
- },
24
- slug: {
25
- header: "Slug"
26
- },
27
- primaryDomain: {
28
- header: "Domain"
29
- }
30
- }, {
31
- printLine: this.log.bind(this),
32
- ...flags
33
- });
8
+ {bold USAGE}
9
+ $ ggt list
10
+
11
+ {bold EXAMPLE}
12
+ {gray $ ggt list}
13
+ Slug Domain
14
+ ─────── ──────────────────
15
+ my-app my-app.gadget.app
16
+ example example.gadget.app
17
+ test test.gadget.app
18
+ `;
19
+ export const run = async ()=>{
20
+ const user = await getUserOrLogin();
21
+ const apps = await getApps(user);
22
+ if (!apps.length) {
23
+ println`
24
+ It doesn't look like you have any applications.
25
+
26
+ Visit https://gadget.new to create one!
27
+ `;
28
+ return;
34
29
  }
35
- constructor(...args){
36
- super(...args);
37
- _define_property(this, "requireUser", true);
30
+ const longestSlug = _.maxBy(apps, "slug.length")?.slug.length ?? 0;
31
+ const longestDomain = _.maxBy(apps, "primaryDomain.length")?.primaryDomain.length ?? 0;
32
+ println`{bold Slug}${_.repeat(" ", longestSlug - 4)} {bold Domain}`;
33
+ println`${_.repeat("─", Math.max(longestSlug, 4))} ${_.repeat("─", Math.max(longestDomain, 6))}`;
34
+ for (const app of _.sortBy(apps, "slug")){
35
+ println`${app.slug}${_.repeat(" ", longestSlug - app.slug.length)} ${app.primaryDomain}`;
38
36
  }
39
- }
40
- _define_property(List, "summary", "List the apps available to the currently logged in user.");
41
- _define_property(List, "usage", "list");
42
- _define_property(List, "examples", [
43
- dedent(chalkTemplate`
44
- {gray $ ggt list}
45
- {gray $ ggt list --extended}
46
- {gray $ ggt list --sort=slug}
47
- `)
48
- ]);
49
- _define_property(List, "flags", {
50
- ...ux.table.flags()
51
- });
52
- export { List as default };
37
+ };
53
38
 
54
39
  //# sourceMappingURL=list.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/list.ts"],"sourcesContent":["import { ux } from \"@oclif/core\";\nimport chalkTemplate from \"chalk-template\";\nimport { dedent } from \"ts-dedent\";\nimport { BaseCommand } from \"../services/base-command.js\";\nimport type { App } from \"../services/context.js\";\nimport { context } from \"../services/context.js\";\n\nexport default class List extends BaseCommand<typeof List> {\n static override summary = \"List the apps available to the currently logged in user.\";\n\n static override usage = \"list\";\n\n static override examples = [\n dedent(chalkTemplate`\n {gray $ ggt list}\n {gray $ ggt list --extended}\n {gray $ ggt list --sort=slug}\n `),\n ];\n\n static override flags = {\n ...ux.table.flags(),\n };\n\n override requireUser = true;\n\n async run(): Promise<void> {\n const { flags } = await this.parse(List);\n\n const apps = await context.getAvailableApps();\n if (!apps.length) {\n this.log(dedent`\n It doesn't look like you have any applications.\n\n Visit https://gadget.new to create one!\n `);\n return;\n }\n\n ux.table<App & Record<string, never>>(\n apps as unknown as (App & Record<string, never>)[],\n {\n id: {\n header: \"ID\",\n extended: true,\n },\n slug: {\n header: \"Slug\",\n },\n primaryDomain: {\n header: \"Domain\",\n },\n },\n {\n printLine: this.log.bind(this),\n ...flags, // parsed flags\n },\n );\n }\n}\n"],"names":["ux","chalkTemplate","dedent","BaseCommand","context","List","run","flags","parse","apps","getAvailableApps","length","log","table","id","header","extended","slug","primaryDomain","printLine","bind","requireUser","summary","usage","examples"],"mappings":";AAAA,SAASA,EAAE,QAAQ,cAAc;AACjC,OAAOC,mBAAmB,iBAAiB;AAC3C,SAASC,MAAM,QAAQ,YAAY;AACnC,SAASC,WAAW,QAAQ,8BAA8B;AAE1D,SAASC,OAAO,QAAQ,yBAAyB;AAElC,MAAMC,aAAaF;IAmBhC,MAAMG,MAAqB;QACzB,MAAM,EAAEC,KAAK,EAAE,GAAG,MAAM,IAAI,CAACC,KAAK,CAACH;QAEnC,MAAMI,OAAO,MAAML,QAAQM,gBAAgB;QAC3C,IAAI,CAACD,KAAKE,MAAM,EAAE;YAChB,IAAI,CAACC,GAAG,CAACV,MAAM,CAAC;;;;MAIhB,CAAC;YACD;QACF;QAEAF,GAAGa,KAAK,CACNJ,MACA;YACEK,IAAI;gBACFC,QAAQ;gBACRC,UAAU;YACZ;YACAC,MAAM;gBACJF,QAAQ;YACV;YACAG,eAAe;gBACbH,QAAQ;YACV;QACF,GACA;YACEI,WAAW,IAAI,CAACP,GAAG,CAACQ,IAAI,CAAC,IAAI;YAC7B,GAAGb,KAAK;QACV;IAEJ;;;QAlCA,uBAASc,eAAc;;AAmCzB;AAnDE,iBADmBhB,MACHiB,WAAU;AAE1B,iBAHmBjB,MAGHkB,SAAQ;AAExB,iBALmBlB,MAKHmB,YAAW;IACzBtB,OAAOD,aAAa,CAAC;;;;IAIrB,CAAC;CACF;AAED,iBAbmBI,MAaHE,SAAQ;IACtB,GAAGP,GAAGa,KAAK,CAACN,KAAK,EAAE;AACrB;AAfF,SAAqBF,kBAoDpB"}
1
+ {"version":3,"sources":["../../src/commands/list.ts"],"sourcesContent":["import _ from \"lodash\";\nimport { getApps } from \"../services/app.js\";\nimport { println, sprint } from \"../services/output.js\";\nimport { getUserOrLogin } from \"../services/user.js\";\n\nexport const usage = sprint`\n List the apps available to the currently logged in user.\n\n {bold USAGE}\n $ ggt list\n\n {bold EXAMPLE}\n {gray $ ggt list}\n Slug Domain\n ─────── ──────────────────\n my-app my-app.gadget.app\n example example.gadget.app\n test test.gadget.app\n`;\n\nexport const run = async () => {\n const user = await getUserOrLogin();\n\n const apps = await getApps(user);\n if (!apps.length) {\n println`\n It doesn't look like you have any applications.\n\n Visit https://gadget.new to create one!\n `;\n return;\n }\n\n const longestSlug = _.maxBy(apps, \"slug.length\")?.slug.length ?? 0;\n const longestDomain = _.maxBy(apps, \"primaryDomain.length\")?.primaryDomain.length ?? 0;\n\n println`{bold Slug}${_.repeat(\" \", longestSlug - 4)} {bold Domain}`;\n println`${_.repeat(\"─\", Math.max(longestSlug, 4))} ${_.repeat(\"─\", Math.max(longestDomain, 6))}`;\n for (const app of _.sortBy(apps, \"slug\")) {\n println`${app.slug}${_.repeat(\" \", longestSlug - app.slug.length)} ${app.primaryDomain}`;\n }\n};\n"],"names":["_","getApps","println","sprint","getUserOrLogin","usage","run","user","apps","length","longestSlug","maxBy","slug","longestDomain","primaryDomain","repeat","Math","max","app","sortBy"],"mappings":"AAAA,OAAOA,OAAO,SAAS;AACvB,SAASC,OAAO,QAAQ,qBAAqB;AAC7C,SAASC,OAAO,EAAEC,MAAM,QAAQ,wBAAwB;AACxD,SAASC,cAAc,QAAQ,sBAAsB;AAErD,OAAO,MAAMC,QAAQF,MAAM,CAAC;;;;;;;;;;;;;AAa5B,CAAC,CAAC;AAEF,OAAO,MAAMG,MAAM;IACjB,MAAMC,OAAO,MAAMH;IAEnB,MAAMI,OAAO,MAAMP,QAAQM;IAC3B,IAAI,CAACC,KAAKC,MAAM,EAAE;QAChBP,OAAO,CAAC;;;;IAIR,CAAC;QACD;IACF;IAEA,MAAMQ,cAAcV,EAAEW,KAAK,CAACH,MAAM,gBAAgBI,KAAKH,UAAU;IACjE,MAAMI,gBAAgBb,EAAEW,KAAK,CAACH,MAAM,yBAAyBM,cAAcL,UAAU;IAErFP,OAAO,CAAC,WAAW,EAAEF,EAAEe,MAAM,CAAC,KAAKL,cAAc,GAAG,cAAc,CAAC;IACnER,OAAO,CAAC,EAAEF,EAAEe,MAAM,CAAC,KAAKC,KAAKC,GAAG,CAACP,aAAa,IAAI,CAAC,EAAEV,EAAEe,MAAM,CAAC,KAAKC,KAAKC,GAAG,CAACJ,eAAe,IAAI,CAAC;IAChG,KAAK,MAAMK,OAAOlB,EAAEmB,MAAM,CAACX,MAAM,QAAS;QACxCN,OAAO,CAAC,EAAEgB,IAAIN,IAAI,CAAC,EAAEZ,EAAEe,MAAM,CAAC,KAAKL,cAAcQ,IAAIN,IAAI,CAACH,MAAM,EAAE,CAAC,EAAES,IAAIJ,aAAa,CAAC,CAAC;IAC1F;AACF,EAAE"}
@@ -1,24 +1,81 @@
1
- import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
- import chalkTemplate from "chalk-template";
3
- import { dedent } from "ts-dedent";
4
- import { BaseCommand } from "../services/base-command.js";
5
- class Login extends BaseCommand {
6
- async run() {
7
- await this.login();
8
- }
9
- }
10
- _define_property(Login, "summary", "Log in to your account.");
11
- _define_property(Login, "usage", "login");
12
- _define_property(Login, "examples", [
13
- dedent(chalkTemplate`
1
+ import getPort from "get-port";
2
+ import assert from "node:assert";
3
+ import http from "node:http";
4
+ import open from "open";
5
+ import { config } from "../services/config.js";
6
+ import { createLogger } from "../services/log.js";
7
+ import { println, sprint } from "../services/output.js";
8
+ import { writeSession } from "../services/session.js";
9
+ import { getUser } from "../services/user.js";
10
+ export const usage = sprint`
11
+ Log in to your account.
12
+
13
+ {bold USAGE}
14
+ $ ggt login
15
+
16
+ {bold EXAMPLES}
14
17
  {gray $ ggt login}
15
18
  We've opened Gadget's login page using your default browser.
16
19
 
17
20
  Please log in and then return to this terminal.
18
21
 
19
- Hello, Jane Doe {gray (jane@example.com)}
20
- `)
21
- ]);
22
- export { Login as default };
22
+ Hello, Jane Doe (jane@example.com)
23
+ `;
24
+ const log = createLogger("login");
25
+ export const run = async ()=>{
26
+ let server;
27
+ try {
28
+ const port = await getPort();
29
+ const receiveSession = new Promise((resolve, reject)=>{
30
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
31
+ server = http.createServer(async (req, res)=>{
32
+ const landingPage = new URL(`https://${config.domains.services}/auth/cli`);
33
+ try {
34
+ assert(req.url, "missing url");
35
+ const session = new URL(req.url, `http://localhost:${port}`).searchParams.get("session");
36
+ assert(session, "missing session");
37
+ writeSession(session);
38
+ const user = await getUser();
39
+ assert(user, "missing user after successful login");
40
+ if (user.name) {
41
+ println`Hello, ${user.name} {gray (${user.email})}`;
42
+ } else {
43
+ println`Hello, ${user.email}`;
44
+ }
45
+ println();
46
+ landingPage.searchParams.set("success", "true");
47
+ resolve();
48
+ } catch (error) {
49
+ writeSession(undefined);
50
+ landingPage.searchParams.set("success", "false");
51
+ reject(error);
52
+ } finally{
53
+ res.writeHead(303, {
54
+ Location: landingPage.toString()
55
+ });
56
+ res.end();
57
+ }
58
+ });
59
+ log.info("starting login server", {
60
+ port
61
+ });
62
+ server.listen(port);
63
+ });
64
+ // open the login page in the user's default browser have it
65
+ // redirect to the cli callback route. The cli callback route will
66
+ // send the session to the server we just started.
67
+ const url = new URL(`https://${config.domains.services}/auth/login`);
68
+ url.searchParams.set("returnTo", `https://${config.domains.services}/auth/cli/callback?port=${port}`);
69
+ await open(url.toString());
70
+ println`
71
+ We've opened Gadget's login page using your default browser.
72
+
73
+ Please log in and then return to this terminal.\n
74
+ `;
75
+ await receiveSession;
76
+ } finally{
77
+ server?.close();
78
+ }
79
+ };
23
80
 
24
81
  //# sourceMappingURL=login.js.map