@gadgetinc/ggt 0.2.4 → 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 -91
  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 +312 -678
  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 +15703 -25760
  57. package/package.json +53 -60
  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,68 +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
97
- - .DS_Store
119
+ .DS_Store
120
+ .gadget
121
+ .git
122
+ node_modules
98
123
 
99
124
  Note:
100
- - If you have separate development and production environments, ggt sync will only sync with your development environment
101
- - Gadget applications only support installing dependencies with Yarn 1 (https://classic.yarnpkg.com/lang/en/)
102
- - Since file changes are immediately reflected in Gadget, avoid the following while ggt sync is running:
103
- - Deleting all your files
104
- - 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
105
133
 
106
134
  EXAMPLES
107
135
  $ ggt sync --app my-app ~/gadget/my-app
@@ -112,8 +140,8 @@ EXAMPLES
112
140
  Docs https://docs.gadget.dev/api/my-app
113
141
 
114
142
  Endpoints
115
- - https://my-app.gadget.app
116
- - https://my-app--development.gadget.app
143
+ https://my-app.gadget.app
144
+ https://my-app--development.gadget.app
117
145
 
118
146
  Watching for file changes... Press Ctrl+C to stop
119
147
 
@@ -130,54 +158,28 @@ EXAMPLES
130
158
  Goodbye!
131
159
  ```
132
160
 
133
- _See code: [src/commands/sync.ts](https://github.com/gadget-inc/ggt/blob/v0.2.4/src/commands/sync.ts)_
134
-
135
- ### `ggt help [COMMAND]`
136
-
137
- Display help for ggt.
138
-
139
- ```
140
- USAGE
141
- $ ggt help [COMMAND]
142
-
143
- ARGUMENTS
144
- COMMAND The command to show help for.
145
- ```
146
-
147
- _See code: [src/commands/help.ts](https://github.com/gadget-inc/ggt/blob/v0.2.4/src/commands/help.ts)_
148
-
149
161
  ### `ggt list`
150
162
 
163
+ ```
151
164
  List the apps available to the currently logged in user.
152
165
 
153
- ```
154
166
  USAGE
155
167
  $ ggt list
156
168
 
157
- FLAGS
158
- -x, --extended show extra columns
159
- --columns=<value> only show provided columns (comma-separated)
160
- --csv output is csv format [alias: --output=csv]
161
- --filter=<value> filter property by partial string matching, ex: name=foo
162
- --no-header hide table header from output
163
- --no-truncate do not truncate output to fit screen
164
- --output=<option> output in a more machine friendly format
165
- <options: csv|json|yaml>
166
- --sort=<value> property to sort by (prepend '-' for descending)
167
-
168
- EXAMPLES
169
+ EXAMPLE
169
170
  $ ggt list
170
- $ ggt list --extended
171
- $ 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
172
176
  ```
173
177
 
174
- _See code: [src/commands/list.ts](https://github.com/gadget-inc/ggt/blob/v0.2.4/src/commands/list.ts)_
175
-
176
178
  ### `ggt login`
177
179
 
180
+ ```
178
181
  Log in to your account.
179
182
 
180
- ```
181
183
  USAGE
182
184
  $ ggt login
183
185
 
@@ -190,13 +192,11 @@ EXAMPLES
190
192
  Hello, Jane Doe (jane@example.com)
191
193
  ```
192
194
 
193
- _See code: [src/commands/login.ts](https://github.com/gadget-inc/ggt/blob/v0.2.4/src/commands/login.ts)_
194
-
195
195
  ### `ggt logout`
196
196
 
197
+ ```
197
198
  Log out of your account.
198
199
 
199
- ```
200
200
  USAGE
201
201
  $ ggt logout
202
202
 
@@ -205,13 +205,11 @@ EXAMPLES
205
205
  Goodbye
206
206
  ```
207
207
 
208
- _See code: [src/commands/logout.ts](https://github.com/gadget-inc/ggt/blob/v0.2.4/src/commands/logout.ts)_
209
-
210
208
  ### `ggt whoami`
211
209
 
210
+ ```
212
211
  Show the name and email address of the currently logged in user.
213
212
 
214
- ```
215
213
  USAGE
216
214
  $ ggt whoami
217
215
 
@@ -219,13 +217,3 @@ EXAMPLES
219
217
  $ ggt whoami
220
218
  You are logged in as Jane Doe (jane@example.com)
221
219
  ```
222
-
223
- _See code: [src/commands/whoami.ts](https://github.com/gadget-inc/ggt/blob/v0.2.4/src/commands/whoami.ts)_
224
-
225
- <!-- commandsstop -->
226
-
227
- ## Global Flags
228
-
229
- ### Debug
230
-
231
- 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