@gadgetinc/ggt 0.4.6 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +1 -1
  2. package/bin/dev.js +2 -1
  3. package/bin/run.js +3 -1
  4. package/lib/__generated__/graphql.js.map +1 -1
  5. package/lib/commands/deploy.js +43 -49
  6. package/lib/commands/deploy.js.map +1 -1
  7. package/lib/commands/list.js +7 -11
  8. package/lib/commands/list.js.map +1 -1
  9. package/lib/commands/login.js +8 -12
  10. package/lib/commands/login.js.map +1 -1
  11. package/lib/commands/logout.js +3 -7
  12. package/lib/commands/logout.js.map +1 -1
  13. package/lib/commands/root.js +17 -43
  14. package/lib/commands/root.js.map +1 -1
  15. package/lib/commands/sync.js +10 -39
  16. package/lib/commands/sync.js.map +1 -1
  17. package/lib/commands/version.js +2 -6
  18. package/lib/commands/version.js.map +1 -1
  19. package/lib/commands/whoami.js +5 -9
  20. package/lib/commands/whoami.js.map +1 -1
  21. package/lib/ggt.js +40 -0
  22. package/lib/ggt.js.map +1 -0
  23. package/lib/services/app/app.js +8 -6
  24. package/lib/services/app/app.js.map +1 -1
  25. package/lib/services/app/edit/client.js +176 -0
  26. package/lib/services/app/edit/client.js.map +1 -0
  27. package/lib/services/app/edit/edit.js +155 -0
  28. package/lib/services/app/edit/edit.js.map +1 -0
  29. package/lib/services/app/edit/error.js +65 -0
  30. package/lib/services/app/edit/error.js.map +1 -0
  31. package/lib/services/app/edit/operation.js +87 -0
  32. package/lib/services/app/edit/operation.js.map +1 -0
  33. package/lib/services/command/arg.js +5 -5
  34. package/lib/services/command/arg.js.map +1 -1
  35. package/lib/services/command/command.js +23 -5
  36. package/lib/services/command/command.js.map +1 -1
  37. package/lib/services/command/context.js +123 -36
  38. package/lib/services/command/context.js.map +1 -1
  39. package/lib/services/filesync/changes.js +7 -9
  40. package/lib/services/filesync/changes.js.map +1 -1
  41. package/lib/services/filesync/conflicts.js +11 -9
  42. package/lib/services/filesync/conflicts.js.map +1 -1
  43. package/lib/services/filesync/directory.js +2 -2
  44. package/lib/services/filesync/directory.js.map +1 -1
  45. package/lib/services/filesync/filesync.js +187 -96
  46. package/lib/services/filesync/filesync.js.map +1 -1
  47. package/lib/services/filesync/hashes.js +18 -15
  48. package/lib/services/filesync/hashes.js.map +1 -1
  49. package/lib/services/http/auth.js +4 -4
  50. package/lib/services/http/auth.js.map +1 -1
  51. package/lib/services/http/http.js +54 -27
  52. package/lib/services/http/http.js.map +1 -1
  53. package/lib/services/output/log/logger.js +11 -6
  54. package/lib/services/output/log/logger.js.map +1 -1
  55. package/lib/services/output/log/printer.js.map +1 -1
  56. package/lib/services/output/log/structured.js +2 -2
  57. package/lib/services/output/log/structured.js.map +1 -1
  58. package/lib/services/output/notify.js +3 -7
  59. package/lib/services/output/notify.js.map +1 -1
  60. package/lib/services/output/prompt.js +11 -11
  61. package/lib/services/output/prompt.js.map +1 -1
  62. package/lib/services/output/report.js +51 -67
  63. package/lib/services/output/report.js.map +1 -1
  64. package/lib/services/output/update.js +9 -10
  65. package/lib/services/output/update.js.map +1 -1
  66. package/lib/services/user/user.js +19 -25
  67. package/lib/services/user/user.js.map +1 -1
  68. package/lib/services/util/collection.js +1 -1
  69. package/lib/services/util/collection.js.map +1 -1
  70. package/lib/services/util/function.js +29 -11
  71. package/lib/services/util/function.js.map +1 -1
  72. package/lib/services/util/is.js +19 -1
  73. package/lib/services/util/is.js.map +1 -1
  74. package/lib/services/util/number.js +3 -3
  75. package/lib/services/util/number.js.map +1 -1
  76. package/lib/services/util/object.js +4 -4
  77. package/lib/services/util/object.js.map +1 -1
  78. package/lib/services/util/paths.js +4 -4
  79. package/lib/services/util/paths.js.map +1 -1
  80. package/lib/services/util/types.js +5 -0
  81. package/lib/services/util/types.js.map +1 -0
  82. package/npm-shrinkwrap.json +586 -418
  83. package/package.json +17 -15
  84. package/lib/main.js +0 -8
  85. package/lib/main.js.map +0 -1
  86. package/lib/services/app/edit-graphql.js +0 -389
  87. package/lib/services/app/edit-graphql.js.map +0 -1
package/README.md CHANGED
@@ -226,5 +226,5 @@ USAGE
226
226
 
227
227
  EXAMPLE
228
228
  $ ggt version
229
- 0.4.6
229
+ 0.4.8
230
230
  ```
package/bin/dev.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node --loader @swc-node/register/esm --no-warnings
2
2
 
3
3
  import process from "node:process";
4
+ import { ggt } from "../src/ggt.js";
4
5
  import { workspacePath } from "../src/services/util/paths.js";
5
6
 
6
7
  process.env["NODE_ENV"] ??= "development";
@@ -10,4 +11,4 @@ process.env["GGT_CONFIG_DIR"] ??= workspacePath("tmp/config");
10
11
  process.env["GGT_CACHE_DIR"] ??= workspacePath("tmp/cache");
11
12
  process.env["GGT_DATA_DIR"] ??= workspacePath("tmp/data");
12
13
 
13
- await import("../src/main.js");
14
+ await ggt();
package/bin/run.js CHANGED
@@ -1,3 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import "../lib/main.js";
3
+ import { ggt } from "../lib/ggt.js";
4
+
5
+ await ggt();
@@ -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; 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 AddApplicationTagResult = {\n __typename?: 'AddApplicationTagResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type AddUserTagResult = {\n __typename?: 'AddUserTagResult';\n reason?: Maybe<Scalars['String']['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 FileSyncComparisonHashes = {\n __typename?: 'FileSyncComparisonHashes';\n filesVersionHashes: FileSyncHashes;\n latestFilesVersionHashes: FileSyncHashes;\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 FileSyncFile = {\n __typename?: 'FileSyncFile';\n content: Scalars['String']['output'];\n encoding: FileSyncEncoding;\n mode: Scalars['Float']['output'];\n path: Scalars['String']['output'];\n};\n\nexport type FileSyncFiles = {\n __typename?: 'FileSyncFiles';\n files: Array<FileSyncFile>;\n filesVersion: Scalars['String']['output'];\n};\n\nexport type FileSyncHashes = {\n __typename?: 'FileSyncHashes';\n filesVersion: Scalars['String']['output'];\n hashes: Scalars['JSON']['output'];\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 MigrateAacResult = {\n __typename?: 'MigrateAACResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type MigrateEnvironmentsResult = {\n __typename?: 'MigrateEnvironmentsResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type Mutation = {\n __typename?: 'Mutation';\n addApplicationTag?: Maybe<AddApplicationTagResult>;\n addUserTag?: Maybe<AddUserTagResult>;\n changeAppDomain?: Maybe<ChangeAppDomainResult>;\n convergePackages: Scalars['Boolean']['output'];\n deleteApp?: Maybe<DeleteAppStatusResult>;\n enableFrontend?: Maybe<EnableFrontendResult>;\n migrateAAC?: Maybe<MigrateAacResult>;\n migrateEnvironments?: Maybe<MigrateEnvironmentsResult>;\n patchEnvironmentTree?: Maybe<EnvironmentPatchResult>;\n publish?: Maybe<EnvironmentPublishResult>;\n publishFileSyncEvents: PublishFileSyncEventsResult;\n refreshScopes?: Maybe<RefreshScopesResult>;\n registerWebhooks?: Maybe<RegisterWebhooksResult>;\n /** @deprecated use team */\n removeContributor?: Maybe<RemoveContributorResult>;\n /** @deprecated app invitations are no longer supported */\n sendAppInvitation?: Maybe<SendAppInvitationResult>;\n setClientCurrentPath: EnvironmentPatchResult;\n setFrameworkVersion: SetFrameworkVersionResult;\n syncToWebflow: Scalars['Boolean']['output'];\n uninstallShop?: Maybe<UninstallShopResult>;\n unregisterWebhooks?: Maybe<UnregisterWebhooksResult>;\n uploadFiles: UploadFilesResult;\n uploadTemplateAsset: UploadTemplateAssetResult;\n};\n\n\nexport type MutationAddApplicationTagArgs = {\n tag: Scalars['String']['input'];\n};\n\n\nexport type MutationAddUserTagArgs = {\n replaceMatches?: InputMaybe<Array<Scalars['String']['input']>>;\n tag: Scalars['String']['input'];\n};\n\n\nexport type MutationChangeAppDomainArgs = {\n newSubdomain: Scalars['String']['input'];\n onlyValidate?: InputMaybe<Scalars['Boolean']['input']>;\n};\n\n\nexport type MutationDeleteAppArgs = {\n onlyProduction?: 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 MutationSetClientCurrentPathArgs = {\n clientID: EnvironmentTreeClientId;\n currentPath: Scalars['String']['input'];\n};\n\n\nexport type MutationSetFrameworkVersionArgs = {\n constraint: Scalars['String']['input'];\n};\n\n\nexport type MutationUninstallShopArgs = {\n shopId: Scalars['String']['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\n\nexport type MutationUploadTemplateAssetArgs = {\n file: Scalars['Upload']['input'];\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 PublishIssue = {\n __typename?: 'PublishIssue';\n message: Scalars['String']['output'];\n node?: Maybe<PublishIssueNode>;\n severity: Scalars['String']['output'];\n};\n\nexport type PublishIssueNode = {\n __typename?: 'PublishIssueNode';\n fieldType?: Maybe<Scalars['String']['output']>;\n key: Scalars['String']['output'];\n name?: Maybe<Scalars['String']['output']>;\n parentApiIdentifier?: Maybe<Scalars['String']['output']>;\n parentKey?: Maybe<Scalars['String']['output']>;\n type: Scalars['String']['output'];\n};\n\nexport type PublishStatusState = {\n __typename?: 'PublishStatusState';\n issues: Array<PublishIssue>;\n progress: Scalars['String']['output'];\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 fileSyncComparisonHashes: FileSyncComparisonHashes;\n fileSyncFiles: FileSyncFiles;\n fileSyncHashes: FileSyncHashes;\n identifySupportConversation?: Maybe<IdentifySupportConversationResult>;\n /** @deprecated use team */\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 QueryFileSyncComparisonHashesArgs = {\n filesVersion: Scalars['String']['input'];\n};\n\n\nexport type QueryFileSyncFilesArgs = {\n encoding?: InputMaybe<FileSyncEncoding>;\n filesVersion?: InputMaybe<Scalars['String']['input']>;\n paths: Array<Scalars['String']['input']>;\n};\n\n\nexport type QueryFileSyncHashesArgs = {\n filesVersion?: InputMaybe<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 environmentStatus?: InputMaybe<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 SetFrameworkVersionResult = {\n __typename?: 'SetFrameworkVersionResult';\n installDependenciesOperationKey?: Maybe<Scalars['String']['output']>;\n};\n\nexport type Subscription = {\n __typename?: 'Subscription';\n environmentTreePathPatches?: Maybe<EnvironmentSubscriptionResult>;\n logsSearch: LogSearchResult;\n publishStatus?: Maybe<PublishStatusState>;\n remoteFileSyncEvents: RemoteFileSyncEvents;\n reportClientPresence?: Maybe<Scalars['Boolean']['output']>;\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 SubscriptionPublishStatusArgs = {\n force?: InputMaybe<Scalars['Boolean']['input']>;\n localFilesVersion: Scalars['String']['input'];\n};\n\n\nexport type SubscriptionRemoteFileSyncEventsArgs = {\n encoding?: InputMaybe<FileSyncEncoding>;\n localFilesVersion: Scalars['String']['input'];\n};\n\n\nexport type SubscriptionReportClientPresenceArgs = {\n clientID: EnvironmentTreeClientId;\n};\n\nexport type TeamEntitlements = {\n __typename?: 'TeamEntitlements';\n openAICredits?: Maybe<Scalars['Boolean']['output']>;\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 canPublish: Scalars['Boolean']['output'];\n costPerApplication?: Maybe<Scalars['String']['output']>;\n costPerSeat?: Maybe<Scalars['String']['output']>;\n includedApplications?: Maybe<Scalars['Int']['output']>;\n includedApplicationsRemaining?: Maybe<Scalars['Int']['output']>;\n maxApplications?: Maybe<Scalars['Int']['output']>;\n teamEntitlements: TeamEntitlements;\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 UninstallShopResult = {\n __typename?: 'UninstallShopResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['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 UploadTemplateAssetResult = {\n __typename?: 'UploadTemplateAssetResult';\n success: Scalars['Boolean']['output'];\n url?: Maybe<Scalars['String']['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\nexport type FileSyncFilesQueryVariables = Exact<{\n paths: Array<Scalars['String']['input']> | Scalars['String']['input'];\n filesVersion?: InputMaybe<Scalars['String']['input']>;\n encoding?: InputMaybe<FileSyncEncoding>;\n}>;\n\n\nexport type FileSyncFilesQuery = { __typename?: 'Query', fileSyncFiles: { __typename?: 'FileSyncFiles', filesVersion: string, files: Array<{ __typename?: 'FileSyncFile', path: string, mode: number, content: string, encoding: FileSyncEncoding }> } };\n\nexport type FileSyncHashesQueryVariables = Exact<{\n filesVersion?: InputMaybe<Scalars['String']['input']>;\n}>;\n\n\nexport type FileSyncHashesQuery = { __typename?: 'Query', fileSyncHashes: { __typename?: 'FileSyncHashes', filesVersion: string, hashes: { [key: string]: any } } };\n\nexport type FileSyncComparisonHashesQueryVariables = Exact<{\n filesVersion: Scalars['String']['input'];\n}>;\n\n\nexport type FileSyncComparisonHashesQuery = { __typename?: 'Query', fileSyncComparisonHashes: { __typename?: 'FileSyncComparisonHashes', filesVersionHashes: { __typename?: 'FileSyncHashes', filesVersion: string, hashes: { [key: string]: any } }, latestFilesVersionHashes: { __typename?: 'FileSyncHashes', filesVersion: string, hashes: { [key: string]: any } } } };\n\nexport type PublishStatusSubscriptionVariables = Exact<{\n localFilesVersion: Scalars['String']['input'];\n force?: InputMaybe<Scalars['Boolean']['input']>;\n}>;\n\n\nexport type PublishStatusSubscription = { __typename?: 'Subscription', publishStatus?: { __typename?: 'PublishStatusState', remoteFilesVersion: string, progress: string, issues: Array<{ __typename?: 'PublishIssue', severity: string, message: string, node?: { __typename?: 'PublishIssueNode', type: string, key: string, name?: string | null, fieldType?: string | null, parentKey?: string | null, parentApiIdentifier?: string | null } | null }> } | null };\n"],"names":["FileSyncEncoding"],"mappings":"AAAA;;;;;;CAMC;UAyHWA;;;GAAAA,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; 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 AddApplicationTagResult = {\n __typename?: 'AddApplicationTagResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type AddUserTagResult = {\n __typename?: 'AddUserTagResult';\n reason?: Maybe<Scalars['String']['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 FileSyncComparisonHashes = {\n __typename?: 'FileSyncComparisonHashes';\n filesVersionHashes: FileSyncHashes;\n latestFilesVersionHashes: FileSyncHashes;\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 FileSyncFile = {\n __typename?: 'FileSyncFile';\n content: Scalars['String']['output'];\n encoding: FileSyncEncoding;\n mode: Scalars['Float']['output'];\n path: Scalars['String']['output'];\n};\n\nexport type FileSyncFiles = {\n __typename?: 'FileSyncFiles';\n files: Array<FileSyncFile>;\n filesVersion: Scalars['String']['output'];\n};\n\nexport type FileSyncHashes = {\n __typename?: 'FileSyncHashes';\n filesVersion: Scalars['String']['output'];\n hashes: Scalars['JSON']['output'];\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 MigrateAacResult = {\n __typename?: 'MigrateAACResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type MigrateEnvironmentsResult = {\n __typename?: 'MigrateEnvironmentsResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type Mutation = {\n __typename?: 'Mutation';\n addApplicationTag?: Maybe<AddApplicationTagResult>;\n addUserTag?: Maybe<AddUserTagResult>;\n changeAppDomain?: Maybe<ChangeAppDomainResult>;\n convergePackages: Scalars['Boolean']['output'];\n deleteApp?: Maybe<DeleteAppStatusResult>;\n enableFrontend?: Maybe<EnableFrontendResult>;\n migrateAAC?: Maybe<MigrateAacResult>;\n migrateEnvironments?: Maybe<MigrateEnvironmentsResult>;\n patchEnvironmentTree?: Maybe<EnvironmentPatchResult>;\n publish?: Maybe<EnvironmentPublishResult>;\n publishFileSyncEvents: PublishFileSyncEventsResult;\n refreshScopes?: Maybe<RefreshScopesResult>;\n registerWebhooks?: Maybe<RegisterWebhooksResult>;\n /** @deprecated use team */\n removeContributor?: Maybe<RemoveContributorResult>;\n /** @deprecated app invitations are no longer supported */\n sendAppInvitation?: Maybe<SendAppInvitationResult>;\n setClientCurrentPath: EnvironmentPatchResult;\n setFrameworkVersion: SetFrameworkVersionResult;\n syncToWebflow: Scalars['Boolean']['output'];\n uninstallShop?: Maybe<UninstallShopResult>;\n unregisterWebhooks?: Maybe<UnregisterWebhooksResult>;\n uploadFiles: UploadFilesResult;\n uploadTemplateAsset: UploadTemplateAssetResult;\n};\n\n\nexport type MutationAddApplicationTagArgs = {\n tag: Scalars['String']['input'];\n};\n\n\nexport type MutationAddUserTagArgs = {\n replaceMatches?: InputMaybe<Array<Scalars['String']['input']>>;\n tag: Scalars['String']['input'];\n};\n\n\nexport type MutationChangeAppDomainArgs = {\n newSubdomain: Scalars['String']['input'];\n onlyValidate?: InputMaybe<Scalars['Boolean']['input']>;\n};\n\n\nexport type MutationDeleteAppArgs = {\n onlyProduction?: 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 MutationSetClientCurrentPathArgs = {\n clientID: EnvironmentTreeClientId;\n currentPath: Scalars['String']['input'];\n};\n\n\nexport type MutationSetFrameworkVersionArgs = {\n constraint: Scalars['String']['input'];\n};\n\n\nexport type MutationUninstallShopArgs = {\n shopId: Scalars['String']['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\n\nexport type MutationUploadTemplateAssetArgs = {\n file: Scalars['Upload']['input'];\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 PublishIssue = {\n __typename?: 'PublishIssue';\n message: Scalars['String']['output'];\n node?: Maybe<PublishIssueNode>;\n severity: Scalars['String']['output'];\n};\n\nexport type PublishIssueNode = {\n __typename?: 'PublishIssueNode';\n apiIdentifier?: Maybe<Scalars['String']['output']>;\n fieldType?: Maybe<Scalars['String']['output']>;\n key: Scalars['String']['output'];\n name?: Maybe<Scalars['String']['output']>;\n parentApiIdentifier?: Maybe<Scalars['String']['output']>;\n parentKey?: Maybe<Scalars['String']['output']>;\n type: Scalars['String']['output'];\n};\n\nexport type PublishStatusState = {\n __typename?: 'PublishStatusState';\n issues: Array<PublishIssue>;\n progress: Scalars['String']['output'];\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 fileSyncComparisonHashes: FileSyncComparisonHashes;\n fileSyncFiles: FileSyncFiles;\n fileSyncHashes: FileSyncHashes;\n identifySupportConversation?: Maybe<IdentifySupportConversationResult>;\n /** @deprecated use team */\n listContributors: Array<ContributorResult>;\n logsSearch: LogSearchResult;\n publishIssues: Array<PublishIssue>;\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 QueryFileSyncComparisonHashesArgs = {\n filesVersion: Scalars['String']['input'];\n};\n\n\nexport type QueryFileSyncFilesArgs = {\n encoding?: InputMaybe<FileSyncEncoding>;\n filesVersion?: InputMaybe<Scalars['String']['input']>;\n paths: Array<Scalars['String']['input']>;\n};\n\n\nexport type QueryFileSyncHashesArgs = {\n filesVersion?: InputMaybe<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 environmentStatus?: InputMaybe<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 SetFrameworkVersionResult = {\n __typename?: 'SetFrameworkVersionResult';\n installDependenciesOperationKey?: Maybe<Scalars['String']['output']>;\n};\n\nexport type Subscription = {\n __typename?: 'Subscription';\n environmentTreePathPatches?: Maybe<EnvironmentSubscriptionResult>;\n logsSearch: LogSearchResult;\n publishStatus?: Maybe<PublishStatusState>;\n remoteFileSyncEvents: RemoteFileSyncEvents;\n reportClientPresence?: Maybe<Scalars['Boolean']['output']>;\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 SubscriptionPublishStatusArgs = {\n force?: InputMaybe<Scalars['Boolean']['input']>;\n localFilesVersion: Scalars['String']['input'];\n};\n\n\nexport type SubscriptionRemoteFileSyncEventsArgs = {\n encoding?: InputMaybe<FileSyncEncoding>;\n localFilesVersion: Scalars['String']['input'];\n};\n\n\nexport type SubscriptionReportClientPresenceArgs = {\n clientID: EnvironmentTreeClientId;\n};\n\nexport type TeamEntitlements = {\n __typename?: 'TeamEntitlements';\n openAICredits?: Maybe<Scalars['Boolean']['output']>;\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 canPublish: Scalars['Boolean']['output'];\n costPerApplication?: Maybe<Scalars['String']['output']>;\n costPerSeat?: Maybe<Scalars['String']['output']>;\n includedApplications?: Maybe<Scalars['Int']['output']>;\n includedApplicationsRemaining?: Maybe<Scalars['Int']['output']>;\n maxApplications?: Maybe<Scalars['Int']['output']>;\n teamEntitlements: TeamEntitlements;\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 UninstallShopResult = {\n __typename?: 'UninstallShopResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['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 UploadTemplateAssetResult = {\n __typename?: 'UploadTemplateAssetResult';\n success: Scalars['Boolean']['output'];\n url?: Maybe<Scalars['String']['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\nexport type FileSyncFilesQueryVariables = Exact<{\n paths: Array<Scalars['String']['input']> | Scalars['String']['input'];\n filesVersion?: InputMaybe<Scalars['String']['input']>;\n encoding?: InputMaybe<FileSyncEncoding>;\n}>;\n\n\nexport type FileSyncFilesQuery = { __typename?: 'Query', fileSyncFiles: { __typename?: 'FileSyncFiles', filesVersion: string, files: Array<{ __typename?: 'FileSyncFile', path: string, mode: number, content: string, encoding: FileSyncEncoding }> } };\n\nexport type FileSyncHashesQueryVariables = Exact<{\n filesVersion?: InputMaybe<Scalars['String']['input']>;\n}>;\n\n\nexport type FileSyncHashesQuery = { __typename?: 'Query', fileSyncHashes: { __typename?: 'FileSyncHashes', filesVersion: string, hashes: { [key: string]: any } } };\n\nexport type FileSyncComparisonHashesQueryVariables = Exact<{\n filesVersion: Scalars['String']['input'];\n}>;\n\n\nexport type FileSyncComparisonHashesQuery = { __typename?: 'Query', fileSyncComparisonHashes: { __typename?: 'FileSyncComparisonHashes', filesVersionHashes: { __typename?: 'FileSyncHashes', filesVersion: string, hashes: { [key: string]: any } }, latestFilesVersionHashes: { __typename?: 'FileSyncHashes', filesVersion: string, hashes: { [key: string]: any } } } };\n\nexport type PublishStatusSubscriptionVariables = Exact<{\n localFilesVersion: Scalars['String']['input'];\n force?: InputMaybe<Scalars['Boolean']['input']>;\n}>;\n\n\nexport type PublishStatusSubscription = { __typename?: 'Subscription', publishStatus?: { __typename?: 'PublishStatusState', remoteFilesVersion: string, progress: string, issues: Array<{ __typename?: 'PublishIssue', severity: string, message: string, node?: { __typename?: 'PublishIssueNode', type: string, key: string, apiIdentifier?: string | null, name?: string | null, fieldType?: string | null, parentKey?: string | null, parentApiIdentifier?: string | null } | null }> } | null };\n"],"names":["FileSyncEncoding"],"mappings":"AAAA;;;;;;CAMC;UAyHWA;;;GAAAA,qBAAAA"}
@@ -1,11 +1,9 @@
1
1
  import chalk from "chalk";
2
2
  import ora from "ora";
3
- import { AppArg } from "../services/app/arg.js";
4
- import { REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION } from "../services/app/edit-graphql.js";
5
- import { FileSync } from "../services/filesync/filesync.js";
3
+ import { REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION } from "../services/app/edit/operation.js";
4
+ import { FileSync, FileSyncArgs } from "../services/filesync/filesync.js";
6
5
  import { select } from "../services/output/prompt.js";
7
6
  import { sprint } from "../services/output/sprint.js";
8
- import { getUserOrLogin } from "../services/user/user.js";
9
7
  import { isCloseEvent, isGraphQLErrors } from "../services/util/is.js";
10
8
  export const usage = ()=>sprint`
11
9
  Deploy your Gadget application's development source code to production.
@@ -22,20 +20,20 @@ export const usage = ()=>sprint`
22
20
 
23
21
  {bold DESCRIPTION}
24
22
  Deploy allows you to deploy your current Gadget application in development to production.
25
-
26
- It detects if local files are up to date with remote and if the Gadget application
27
- is in a deployable state. If there are any issues, it will display them and ask if
28
- you would like to deploy anyways.
29
-
23
+
24
+ It detects if local files are up to date with remote and if the Gadget application
25
+ is in a deployable state. If there are any issues, it will display them and ask if
26
+ you would like to deploy anyways.
27
+
30
28
  Note:
31
29
  • If local files are not up to date or have not recently been synced with remote ones,
32
- you will be prompted to run a one-time sync to ensure the files remain consistent with
33
- what is on the remote.
30
+ you will be prompted to run a one-time sync to ensure the files remain consistent with
31
+ what is on the remote.
34
32
  • You may wish to keep ggt sync running in the background before trying to run ggt deploy
35
-
36
- {bold EXAMPLE}
33
+
34
+ {bold EXAMPLE}
37
35
  $ ggt deploy ~/gadget/example --app example
38
-
36
+
39
37
  App example
40
38
  Editor https://example.gadget.app/edit
41
39
  Playground https://example.gadget.app/api/graphql/playground
@@ -44,28 +42,24 @@ export const usage = ()=>sprint`
44
42
  Endpoints
45
43
  • https://example.gadget.app
46
44
  • https://example--development.gadget.app
47
-
48
-
45
+
46
+
49
47
  Building frontend assets ...
50
48
  ✔ DONE
51
-
49
+
52
50
  Setting up database ...
53
51
  ✔ DONE
54
-
52
+
55
53
  Copying development ...
56
54
  ✔ DONE
57
-
55
+
58
56
  Restarting app ...
59
57
  ✔ DONE
60
-
58
+
61
59
  Deploy completed. Good bye!
62
60
  `;
63
61
  export const args = {
64
- "--app": {
65
- type: AppArg,
66
- alias: "-a"
67
- },
68
- "--force": Boolean
62
+ ...FileSyncArgs
69
63
  };
70
64
  export var Action;
71
65
  (function(Action) {
@@ -110,21 +104,21 @@ var AppDeploymentSteps;
110
104
  const spinner = ora();
111
105
  let prevProgress = AppDeploymentStepsToAppDeployState("NOT_STARTED");
112
106
  let action;
113
- const filesync = await FileSync.init({
114
- user: await getUserOrLogin(),
115
- dir: ctx.args._[0],
116
- app: ctx.args["--app"]
117
- });
118
- const log = filesync.log.extend("deploy");
107
+ // deploy --force != sync --force
108
+ const filesync = await FileSync.init(ctx.child({
109
+ overwrite: {
110
+ "--force": false
111
+ }
112
+ }));
119
113
  if (firstRun) {
120
- log.printlns`App: ${filesync.app.slug}`;
114
+ ctx.log.printlns`App: ${filesync.app.slug}`;
121
115
  }
122
116
  const { inSync } = await filesync.hashes();
123
117
  if (!inSync) {
124
- log.printlns`
125
- Local files have diverged from remote. Run a sync once to converge your files or keep {italic ggt sync} running in the background.
126
- `;
127
- action = await select({
118
+ ctx.log.printlns`
119
+ Local files have diverged from remote. Run a sync once to converge your files or keep {italic ggt sync} running in the background.
120
+ `;
121
+ action = await select(ctx, {
128
122
  message: "How would you like to proceed?",
129
123
  choices: [
130
124
  "Cancel (Ctrl+C)",
@@ -144,8 +138,8 @@ var AppDeploymentSteps;
144
138
  }
145
139
  }
146
140
  // subscribes to the graphql subscription that will listen and send back the server contract status
147
- const unsubscribe = filesync.editGraphQL.subscribe({
148
- query: REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION,
141
+ const unsubscribe = filesync.edit.subscribe({
142
+ subscription: REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION,
149
143
  variables: ()=>({
150
144
  localFilesVersion: String(filesync.filesVersion),
151
145
  force: ctx.args["--force"]
@@ -153,16 +147,16 @@ var AppDeploymentSteps;
153
147
  onError: (error)=>{
154
148
  if (isCloseEvent(error.cause)) {
155
149
  spinner.fail("Failed");
156
- log.printlns(error.message);
150
+ ctx.log.printlns(error.message);
157
151
  } else if (isGraphQLErrors(error.cause)) {
158
152
  const message = error.cause[0]?.message;
159
153
  if (message && message.includes("GGT_PAYMENT_REQUIRED")) {
160
- log.println("Production environment limit reached. Upgrade your plan to deploy");
154
+ ctx.log.println("Production environment limit reached. Upgrade your plan to deploy");
161
155
  } else {
162
- log.println(`${message}`);
156
+ ctx.log.println(`${message}`);
163
157
  }
164
158
  }
165
- log.error("failed to deploy", {
159
+ ctx.log.error("failed to deploy", {
166
160
  error
167
161
  });
168
162
  unsubscribe();
@@ -172,20 +166,20 @@ var AppDeploymentSteps;
172
166
  const { progress, issues } = publishStatus ?? {};
173
167
  const hasIssues = issues?.length;
174
168
  if (firstRun && hasIssues) {
175
- log.printlns`{underline Issues detected}`;
169
+ ctx.log.printlns`{underline Issues detected}`;
176
170
  for (const issue of issues){
177
171
  const message = issue.message.replace(/"/g, "");
178
172
  const nodeType = issue.node?.type;
179
- const nodeName = issue.node?.name;
173
+ const nodeName = issue.node?.apiIdentifier ?? issue.node?.name;
180
174
  const nodeParent = issue.node?.parentApiIdentifier;
181
- log.printlns(`
182
- • ${message}
175
+ ctx.log.printlns(`
176
+ • ${message}
183
177
  ${nodeType ? `${nodeType}: ${chalk.cyan(nodeName)}` : ""} ${nodeParent ? `ParentResource: ${chalk.cyan(nodeParent)}` : ""}
184
178
  `.trim());
185
179
  }
186
180
  if (!ctx.args["--force"]) {
187
181
  unsubscribe();
188
- action = await select({
182
+ action = await select(ctx, {
189
183
  message: "Detected some issues with your app. How would you like to proceed?",
190
184
  choices: [
191
185
  "Cancel (Ctrl+C)",
@@ -209,7 +203,7 @@ var AppDeploymentSteps;
209
203
  } else {
210
204
  if (progress === "COMPLETED") {
211
205
  spinner.succeed("DONE");
212
- log.printlns("Deploy completed. Good bye!");
206
+ ctx.log.printlns("Deploy completed. Good bye!");
213
207
  unsubscribe();
214
208
  return;
215
209
  }
@@ -219,7 +213,7 @@ var AppDeploymentSteps;
219
213
  spinner.succeed("DONE");
220
214
  }
221
215
  prevProgress = currentProgress;
222
- log.printlns(`${currentProgress} ...`);
216
+ ctx.log.printlns(`${currentProgress} ...`);
223
217
  spinner.start("Working ...");
224
218
  }
225
219
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/deploy.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { AppArg } from \"../services/app/arg.js\";\nimport { REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION } from \"../services/app/edit-graphql.js\";\nimport type { ArgsSpec } from \"../services/command/arg.js\";\nimport { type Command, type Usage } from \"../services/command/command.js\";\nimport { FileSync } from \"../services/filesync/filesync.js\";\nimport { select } from \"../services/output/prompt.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { getUserOrLogin } from \"../services/user/user.js\";\nimport { isCloseEvent, isGraphQLErrors } from \"../services/util/is.js\";\n\nexport const usage: Usage = () => sprint`\n Deploy your Gadget application's development source code to production.\n\n {bold USAGE}\n ggt deploy [DIRECTORY] [--app=<name>]\n\n {bold ARGUMENTS}\n DIRECTORY The directory to sync files to and deploy (default: \".\")\n\n {bold FLAGS}\n -a, --app=<name> The Gadget application to deploy\n --force Deploy the Gadget application regardless of any issues it may have\n\n {bold DESCRIPTION}\n Deploy allows you to deploy your current Gadget application in development to production.\n \n It detects if local files are up to date with remote and if the Gadget application \n is in a deployable state. If there are any issues, it will display them and ask if \n you would like to deploy anyways. \n \n Note:\n • If local files are not up to date or have not recently been synced with remote ones,\n you will be prompted to run a one-time sync to ensure the files remain consistent with \n what is on the remote. \n • You may wish to keep ggt sync running in the background before trying to run ggt deploy\n \n {bold EXAMPLE} \n $ ggt deploy ~/gadget/example --app example\n \n App example\n Editor https://example.gadget.app/edit\n Playground https://example.gadget.app/api/graphql/playground\n Docs https://docs.gadget.dev/api/example\n\n Endpoints\n • https://example.gadget.app\n • https://example--development.gadget.app\n \n \n Building frontend assets ...\n ✔ DONE\n \n Setting up database ...\n ✔ DONE\n \n Copying development ...\n ✔ DONE\n \n Restarting app ...\n ✔ DONE\n \n Deploy completed. Good bye!\n`;\n\nexport const args = {\n \"--app\": {\n type: AppArg,\n alias: \"-a\",\n },\n \"--force\": Boolean,\n} satisfies ArgsSpec;\n\nexport enum Action {\n DEPLOY_ANYWAYS = \"Deploy anyways\",\n SYNC_ONCE = \"Sync once\",\n CANCEL = \"Cancel (Ctrl+C)\",\n}\n\nconst AppDeploymentStepsToAppDeployState = (step: string | undefined): string => {\n switch (step) {\n case \"NOT_STARTED\":\n return \"Deploy not started\";\n case \"STARTING\":\n case \"BUILDING_ASSETS\":\n case \"UPLOADING_ASSETS\":\n return \"Building frontend assets\";\n case \"CONVERGING_STORAGE\":\n return \"Setting up database\";\n case \"PUBLISHING_TREE\":\n return \"Copying development\";\n case \"RELOADING_SANDBOX\":\n return \"Restarting app\";\n case \"COMPLETED\":\n return \"Deploy completed\";\n default:\n return \"Unknown step\";\n }\n};\n\nenum AppDeploymentSteps {\n NOT_STARTED = \"NOT_STARTED\",\n STARTING = \"STARTING\",\n BUILDING_ASSETS = \"BUILDING_ASSETS\",\n UPLOADING_ASSETS = \"UPLOADING_ASSETS\",\n CONVERGING_STORAGE = \"CONVERGING_STORAGE\",\n PUBLISHING_TREE = \"PUBLISHING_TREE\",\n RELOADING_SANDBOX = \"RELOADING_SANDBOX\",\n COMPLETED = \"COMPLETED\",\n}\n\n/**\n * Runs the deploy process.\n */\n\nexport const command = (async (ctx, firstRun = true) => {\n const spinner = ora();\n let prevProgress: string | undefined = AppDeploymentStepsToAppDeployState(\"NOT_STARTED\");\n let action: Action;\n\n const filesync = await FileSync.init({\n user: await getUserOrLogin(),\n dir: ctx.args._[0],\n app: ctx.args[\"--app\"],\n });\n\n const log = filesync.log.extend(\"deploy\");\n\n if (firstRun) {\n log.printlns`App: ${filesync.app.slug}`;\n }\n\n const { inSync } = await filesync.hashes();\n if (!inSync) {\n log.printlns`\n Local files have diverged from remote. Run a sync once to converge your files or keep {italic ggt sync} running in the background.\n `;\n\n action = await select({\n message: \"How would you like to proceed?\",\n choices: [Action.CANCEL, Action.SYNC_ONCE],\n });\n\n switch (action) {\n case Action.SYNC_ONCE: {\n await filesync.sync();\n\n break;\n }\n case Action.CANCEL: {\n process.exit(0);\n }\n }\n }\n\n // subscribes to the graphql subscription that will listen and send back the server contract status\n const unsubscribe = filesync.editGraphQL.subscribe({\n query: REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION,\n variables: () => ({ localFilesVersion: String(filesync.filesVersion), force: ctx.args[\"--force\"] }),\n onError: (error) => {\n if (isCloseEvent(error.cause)) {\n spinner.fail(\"Failed\");\n log.printlns(error.message);\n } else if (isGraphQLErrors(error.cause)) {\n const message = error.cause[0]?.message;\n if (message && message.includes(\"GGT_PAYMENT_REQUIRED\")) {\n log.println(\"Production environment limit reached. Upgrade your plan to deploy\");\n } else {\n log.println(`${message}`);\n }\n }\n log.error(\"failed to deploy\", { error });\n unsubscribe();\n return;\n },\n onData: async ({ publishStatus }): Promise<void> => {\n const { progress, issues } = publishStatus ?? {};\n\n const hasIssues = issues?.length;\n\n if (firstRun && hasIssues) {\n log.printlns`{underline Issues detected}`;\n\n for (const issue of issues) {\n const message = issue.message.replace(/\"/g, \"\");\n const nodeType = issue.node?.type;\n const nodeName = issue.node?.name;\n const nodeParent = issue.node?.parentApiIdentifier;\n\n log.printlns(\n `\n • ${message} \n ${nodeType ? `${nodeType}: ${chalk.cyan(nodeName)}` : \"\"} ${\n nodeParent ? `ParentResource: ${chalk.cyan(nodeParent)}` : \"\"\n }\n `.trim(),\n );\n }\n\n if (!ctx.args[\"--force\"]) {\n unsubscribe();\n\n action = await select({\n message: \"Detected some issues with your app. How would you like to proceed?\",\n choices: [Action.CANCEL, Action.DEPLOY_ANYWAYS],\n });\n\n switch (action) {\n case Action.DEPLOY_ANYWAYS: {\n ctx.args[\"--force\"] = true;\n await command(ctx, false);\n break;\n }\n case Action.CANCEL: {\n process.exit(0);\n }\n }\n }\n\n firstRun = false;\n } else {\n if (progress === AppDeploymentSteps.COMPLETED) {\n spinner.succeed(\"DONE\");\n log.printlns(\"Deploy completed. Good bye!\");\n unsubscribe();\n return;\n }\n\n const currentProgress = AppDeploymentStepsToAppDeployState(progress);\n\n if (progress && currentProgress !== prevProgress) {\n if ((progress as AppDeploymentSteps) !== AppDeploymentSteps.STARTING) {\n spinner.succeed(\"DONE\");\n }\n\n prevProgress = currentProgress;\n log.printlns(`${currentProgress} ...`);\n spinner.start(\"Working ...\");\n }\n }\n },\n });\n}) satisfies Command<typeof args>;\n"],"names":["chalk","ora","AppArg","REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION","FileSync","select","sprint","getUserOrLogin","isCloseEvent","isGraphQLErrors","usage","args","type","alias","Boolean","Action","AppDeploymentStepsToAppDeployState","step","AppDeploymentSteps","command","ctx","firstRun","spinner","prevProgress","action","filesync","init","user","dir","_","app","log","extend","printlns","slug","inSync","hashes","message","choices","sync","process","exit","unsubscribe","editGraphQL","subscribe","query","variables","localFilesVersion","String","filesVersion","force","onError","error","cause","fail","includes","println","onData","publishStatus","progress","issues","hasIssues","length","issue","replace","nodeType","node","nodeName","name","nodeParent","parentApiIdentifier","cyan","trim","succeed","currentProgress","start"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/commands/deploy.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION } from \"../services/app/edit/operation.js\";\nimport type { ArgsDefinition } from \"../services/command/arg.js\";\nimport { type Command, type Usage } from \"../services/command/command.js\";\nimport { FileSync, FileSyncArgs } from \"../services/filesync/filesync.js\";\nimport { select } from \"../services/output/prompt.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { isCloseEvent, isGraphQLErrors } from \"../services/util/is.js\";\n\nexport const usage: Usage = () => sprint`\n Deploy your Gadget application's development source code to production.\n\n {bold USAGE}\n ggt deploy [DIRECTORY] [--app=<name>]\n\n {bold ARGUMENTS}\n DIRECTORY The directory to sync files to and deploy (default: \".\")\n\n {bold FLAGS}\n -a, --app=<name> The Gadget application to deploy\n --force Deploy the Gadget application regardless of any issues it may have\n\n {bold DESCRIPTION}\n Deploy allows you to deploy your current Gadget application in development to production.\n\n It detects if local files are up to date with remote and if the Gadget application\n is in a deployable state. If there are any issues, it will display them and ask if\n you would like to deploy anyways.\n\n Note:\n • If local files are not up to date or have not recently been synced with remote ones,\n you will be prompted to run a one-time sync to ensure the files remain consistent with\n what is on the remote.\n • You may wish to keep ggt sync running in the background before trying to run ggt deploy\n\n {bold EXAMPLE}\n $ ggt deploy ~/gadget/example --app example\n\n App example\n Editor https://example.gadget.app/edit\n Playground https://example.gadget.app/api/graphql/playground\n Docs https://docs.gadget.dev/api/example\n\n Endpoints\n • https://example.gadget.app\n • https://example--development.gadget.app\n\n\n Building frontend assets ...\n ✔ DONE\n\n Setting up database ...\n ✔ DONE\n\n Copying development ...\n ✔ DONE\n\n Restarting app ...\n ✔ DONE\n\n Deploy completed. Good bye!\n`;\n\nexport const args = {\n ...FileSyncArgs,\n} satisfies ArgsDefinition;\n\nexport enum Action {\n DEPLOY_ANYWAYS = \"Deploy anyways\",\n SYNC_ONCE = \"Sync once\",\n CANCEL = \"Cancel (Ctrl+C)\",\n}\n\nconst AppDeploymentStepsToAppDeployState = (step: string | undefined): string => {\n switch (step) {\n case \"NOT_STARTED\":\n return \"Deploy not started\";\n case \"STARTING\":\n case \"BUILDING_ASSETS\":\n case \"UPLOADING_ASSETS\":\n return \"Building frontend assets\";\n case \"CONVERGING_STORAGE\":\n return \"Setting up database\";\n case \"PUBLISHING_TREE\":\n return \"Copying development\";\n case \"RELOADING_SANDBOX\":\n return \"Restarting app\";\n case \"COMPLETED\":\n return \"Deploy completed\";\n default:\n return \"Unknown step\";\n }\n};\n\nenum AppDeploymentSteps {\n NOT_STARTED = \"NOT_STARTED\",\n STARTING = \"STARTING\",\n BUILDING_ASSETS = \"BUILDING_ASSETS\",\n UPLOADING_ASSETS = \"UPLOADING_ASSETS\",\n CONVERGING_STORAGE = \"CONVERGING_STORAGE\",\n PUBLISHING_TREE = \"PUBLISHING_TREE\",\n RELOADING_SANDBOX = \"RELOADING_SANDBOX\",\n COMPLETED = \"COMPLETED\",\n}\n\n/**\n * Runs the deploy process.\n */\nexport const command = (async (ctx, firstRun = true) => {\n const spinner = ora();\n let prevProgress: string | undefined = AppDeploymentStepsToAppDeployState(\"NOT_STARTED\");\n let action: Action;\n\n // deploy --force != sync --force\n const filesync = await FileSync.init(ctx.child({ overwrite: { \"--force\": false } }));\n\n if (firstRun) {\n ctx.log.printlns`App: ${filesync.app.slug}`;\n }\n\n const { inSync } = await filesync.hashes();\n if (!inSync) {\n ctx.log.printlns`\n Local files have diverged from remote. Run a sync once to converge your files or keep {italic ggt sync} running in the background.\n `;\n\n action = await select(ctx, {\n message: \"How would you like to proceed?\",\n choices: [Action.CANCEL, Action.SYNC_ONCE],\n });\n\n switch (action) {\n case Action.SYNC_ONCE: {\n await filesync.sync();\n\n break;\n }\n case Action.CANCEL: {\n process.exit(0);\n }\n }\n }\n\n // subscribes to the graphql subscription that will listen and send back the server contract status\n const unsubscribe = filesync.edit.subscribe({\n subscription: REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION,\n variables: () => ({ localFilesVersion: String(filesync.filesVersion), force: ctx.args[\"--force\"] }),\n onError: (error) => {\n if (isCloseEvent(error.cause)) {\n spinner.fail(\"Failed\");\n ctx.log.printlns(error.message);\n } else if (isGraphQLErrors(error.cause)) {\n const message = error.cause[0]?.message;\n if (message && message.includes(\"GGT_PAYMENT_REQUIRED\")) {\n ctx.log.println(\"Production environment limit reached. Upgrade your plan to deploy\");\n } else {\n ctx.log.println(`${message}`);\n }\n }\n ctx.log.error(\"failed to deploy\", { error });\n unsubscribe();\n return;\n },\n onData: async ({ publishStatus }): Promise<void> => {\n const { progress, issues } = publishStatus ?? {};\n\n const hasIssues = issues?.length;\n\n if (firstRun && hasIssues) {\n ctx.log.printlns`{underline Issues detected}`;\n\n for (const issue of issues) {\n const message = issue.message.replace(/\"/g, \"\");\n const nodeType = issue.node?.type;\n const nodeName = issue.node?.apiIdentifier ?? issue.node?.name;\n const nodeParent = issue.node?.parentApiIdentifier;\n\n ctx.log.printlns(\n `\n • ${message}\n ${nodeType ? `${nodeType}: ${chalk.cyan(nodeName)}` : \"\"} ${\n nodeParent ? `ParentResource: ${chalk.cyan(nodeParent)}` : \"\"\n }\n `.trim(),\n );\n }\n\n if (!ctx.args[\"--force\"]) {\n unsubscribe();\n\n action = await select(ctx, {\n message: \"Detected some issues with your app. How would you like to proceed?\",\n choices: [Action.CANCEL, Action.DEPLOY_ANYWAYS],\n });\n\n switch (action) {\n case Action.DEPLOY_ANYWAYS: {\n ctx.args[\"--force\"] = true;\n await command(ctx, false);\n break;\n }\n case Action.CANCEL: {\n process.exit(0);\n }\n }\n }\n\n firstRun = false;\n } else {\n if (progress === AppDeploymentSteps.COMPLETED) {\n spinner.succeed(\"DONE\");\n ctx.log.printlns(\"Deploy completed. Good bye!\");\n unsubscribe();\n return;\n }\n\n const currentProgress = AppDeploymentStepsToAppDeployState(progress);\n\n if (progress && currentProgress !== prevProgress) {\n if ((progress as AppDeploymentSteps) !== AppDeploymentSteps.STARTING) {\n spinner.succeed(\"DONE\");\n }\n\n prevProgress = currentProgress;\n ctx.log.printlns(`${currentProgress} ...`);\n spinner.start(\"Working ...\");\n }\n }\n },\n });\n}) satisfies Command<typeof args>;\n"],"names":["chalk","ora","REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION","FileSync","FileSyncArgs","select","sprint","isCloseEvent","isGraphQLErrors","usage","args","Action","AppDeploymentStepsToAppDeployState","step","AppDeploymentSteps","command","ctx","firstRun","spinner","prevProgress","action","filesync","init","child","overwrite","log","printlns","app","slug","inSync","hashes","message","choices","sync","process","exit","unsubscribe","edit","subscribe","subscription","variables","localFilesVersion","String","filesVersion","force","onError","error","cause","fail","includes","println","onData","publishStatus","progress","issues","hasIssues","length","issue","replace","nodeType","node","type","nodeName","apiIdentifier","name","nodeParent","parentApiIdentifier","cyan","trim","succeed","currentProgress","start"],"mappings":"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"}
@@ -1,10 +1,6 @@
1
1
  import { getApps } from "../services/app/app.js";
2
- import { createLogger } from "../services/output/log/logger.js";
3
2
  import { sprint } from "../services/output/sprint.js";
4
3
  import { getUserOrLogin } from "../services/user/user.js";
5
- const log = createLogger({
6
- name: "list"
7
- });
8
4
  export const usage = ()=>sprint`
9
5
  List the apps available to the currently logged in user.
10
6
 
@@ -19,11 +15,11 @@ export const usage = ()=>sprint`
19
15
  example example.gadget.app
20
16
  test test.gadget.app
21
17
  `;
22
- export const command = async ()=>{
23
- const user = await getUserOrLogin();
24
- const apps = await getApps(user);
18
+ export const command = async (ctx)=>{
19
+ await getUserOrLogin(ctx);
20
+ const apps = await getApps(ctx);
25
21
  if (apps.length === 0) {
26
- log.println`
22
+ ctx.log.println`
27
23
  It doesn't look like you have any applications.
28
24
 
29
25
  Visit https://gadget.new to create one!
@@ -36,10 +32,10 @@ export const command = async ()=>{
36
32
  longestSlug = Math.max(longestSlug, app.slug.length);
37
33
  longestDomain = Math.max(longestDomain, app.primaryDomain.length);
38
34
  }
39
- log.println`{bold Slug}${" ".repeat(longestSlug - 4)} {bold Domain}`;
40
- log.println`${"─".repeat(Math.max(longestSlug, 4))} ${"─".repeat(Math.max(longestDomain, 6))}`;
35
+ ctx.log.println`{bold Slug}${" ".repeat(longestSlug - 4)} {bold Domain}`;
36
+ ctx.log.println`${"─".repeat(Math.max(longestSlug, 4))} ${"─".repeat(Math.max(longestDomain, 6))}`;
41
37
  for (const app of apps.sort((a, b)=>a.slug.localeCompare(b.slug))){
42
- log.println`${app.slug}${" ".repeat(longestSlug - app.slug.length)} ${app.primaryDomain}`;
38
+ ctx.log.println`${app.slug}${" ".repeat(longestSlug - app.slug.length)} ${app.primaryDomain}`;
43
39
  }
44
40
  };
45
41
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/list.ts"],"sourcesContent":["import { getApps } from \"../services/app/app.js\";\nimport type { Command, Usage } from \"../services/command/command.js\";\nimport { createLogger } from \"../services/output/log/logger.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { getUserOrLogin } from \"../services/user/user.js\";\n\nconst log = createLogger({ name: \"list\" });\n\nexport const usage: 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 $ 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 command: Command = async () => {\n const user = await getUserOrLogin();\n\n const apps = await getApps(user);\n if (apps.length === 0) {\n log.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 let longestSlug = 0;\n let longestDomain = 0;\n\n for (const app of apps) {\n longestSlug = Math.max(longestSlug, app.slug.length);\n longestDomain = Math.max(longestDomain, app.primaryDomain.length);\n }\n\n log.println`{bold Slug}${\" \".repeat(longestSlug - 4)} {bold Domain}`;\n log.println`${\"─\".repeat(Math.max(longestSlug, 4))} ${\"─\".repeat(Math.max(longestDomain, 6))}`;\n for (const app of apps.sort((a, b) => a.slug.localeCompare(b.slug))) {\n log.println`${app.slug}${\" \".repeat(longestSlug - app.slug.length)} ${app.primaryDomain}`;\n }\n};\n"],"names":["getApps","createLogger","sprint","getUserOrLogin","log","name","usage","command","user","apps","length","println","longestSlug","longestDomain","app","Math","max","slug","primaryDomain","repeat","sort","a","b","localeCompare"],"mappings":"AAAA,SAASA,OAAO,QAAQ,yBAAyB;AAEjD,SAASC,YAAY,QAAQ,mCAAmC;AAChE,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,cAAc,QAAQ,2BAA2B;AAE1D,MAAMC,MAAMH,aAAa;IAAEI,MAAM;AAAO;AAExC,OAAO,MAAMC,QAAe,IAAMJ,MAAM,CAAC;;;;;;;;;;;;;AAazC,CAAC,CAAC;AAEF,OAAO,MAAMK,UAAmB;IAC9B,MAAMC,OAAO,MAAML;IAEnB,MAAMM,OAAO,MAAMT,QAAQQ;IAC3B,IAAIC,KAAKC,MAAM,KAAK,GAAG;QACrBN,IAAIO,OAAO,CAAC;;;;IAIZ,CAAC;QACD;IACF;IAEA,IAAIC,cAAc;IAClB,IAAIC,gBAAgB;IAEpB,KAAK,MAAMC,OAAOL,KAAM;QACtBG,cAAcG,KAAKC,GAAG,CAACJ,aAAaE,IAAIG,IAAI,CAACP,MAAM;QACnDG,gBAAgBE,KAAKC,GAAG,CAACH,eAAeC,IAAII,aAAa,CAACR,MAAM;IAClE;IAEAN,IAAIO,OAAO,CAAC,WAAW,EAAE,IAAIQ,MAAM,CAACP,cAAc,GAAG,cAAc,CAAC;IACpER,IAAIO,OAAO,CAAC,EAAE,IAAIQ,MAAM,CAACJ,KAAKC,GAAG,CAACJ,aAAa,IAAI,CAAC,EAAE,IAAIO,MAAM,CAACJ,KAAKC,GAAG,CAACH,eAAe,IAAI,CAAC;IAC9F,KAAK,MAAMC,OAAOL,KAAKW,IAAI,CAAC,CAACC,GAAGC,IAAMD,EAAEJ,IAAI,CAACM,aAAa,CAACD,EAAEL,IAAI,GAAI;QACnEb,IAAIO,OAAO,CAAC,EAAEG,IAAIG,IAAI,CAAC,EAAE,IAAIE,MAAM,CAACP,cAAcE,IAAIG,IAAI,CAACP,MAAM,EAAE,CAAC,EAAEI,IAAII,aAAa,CAAC,CAAC;IAC3F;AACF,EAAE"}
1
+ {"version":3,"sources":["../../src/commands/list.ts"],"sourcesContent":["import { getApps } from \"../services/app/app.js\";\nimport type { Command, Usage } from \"../services/command/command.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { getUserOrLogin } from \"../services/user/user.js\";\n\nexport const usage: 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 $ 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 command: Command = async (ctx) => {\n await getUserOrLogin(ctx);\n\n const apps = await getApps(ctx);\n if (apps.length === 0) {\n ctx.log.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 let longestSlug = 0;\n let longestDomain = 0;\n\n for (const app of apps) {\n longestSlug = Math.max(longestSlug, app.slug.length);\n longestDomain = Math.max(longestDomain, app.primaryDomain.length);\n }\n\n ctx.log.println`{bold Slug}${\" \".repeat(longestSlug - 4)} {bold Domain}`;\n ctx.log.println`${\"─\".repeat(Math.max(longestSlug, 4))} ${\"─\".repeat(Math.max(longestDomain, 6))}`;\n for (const app of apps.sort((a, b) => a.slug.localeCompare(b.slug))) {\n ctx.log.println`${app.slug}${\" \".repeat(longestSlug - app.slug.length)} ${app.primaryDomain}`;\n }\n};\n"],"names":["getApps","sprint","getUserOrLogin","usage","command","ctx","apps","length","log","println","longestSlug","longestDomain","app","Math","max","slug","primaryDomain","repeat","sort","a","b","localeCompare"],"mappings":"AAAA,SAASA,OAAO,QAAQ,yBAAyB;AAEjD,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,cAAc,QAAQ,2BAA2B;AAE1D,OAAO,MAAMC,QAAe,IAAMF,MAAM,CAAC;;;;;;;;;;;;;AAazC,CAAC,CAAC;AAEF,OAAO,MAAMG,UAAmB,OAAOC;IACrC,MAAMH,eAAeG;IAErB,MAAMC,OAAO,MAAMN,QAAQK;IAC3B,IAAIC,KAAKC,MAAM,KAAK,GAAG;QACrBF,IAAIG,GAAG,CAACC,OAAO,CAAC;;;;IAIhB,CAAC;QACD;IACF;IAEA,IAAIC,cAAc;IAClB,IAAIC,gBAAgB;IAEpB,KAAK,MAAMC,OAAON,KAAM;QACtBI,cAAcG,KAAKC,GAAG,CAACJ,aAAaE,IAAIG,IAAI,CAACR,MAAM;QACnDI,gBAAgBE,KAAKC,GAAG,CAACH,eAAeC,IAAII,aAAa,CAACT,MAAM;IAClE;IAEAF,IAAIG,GAAG,CAACC,OAAO,CAAC,WAAW,EAAE,IAAIQ,MAAM,CAACP,cAAc,GAAG,cAAc,CAAC;IACxEL,IAAIG,GAAG,CAACC,OAAO,CAAC,EAAE,IAAIQ,MAAM,CAACJ,KAAKC,GAAG,CAACJ,aAAa,IAAI,CAAC,EAAE,IAAIO,MAAM,CAACJ,KAAKC,GAAG,CAACH,eAAe,IAAI,CAAC;IAClG,KAAK,MAAMC,OAAON,KAAKY,IAAI,CAAC,CAACC,GAAGC,IAAMD,EAAEJ,IAAI,CAACM,aAAa,CAACD,EAAEL,IAAI,GAAI;QACnEV,IAAIG,GAAG,CAACC,OAAO,CAAC,EAAEG,IAAIG,IAAI,CAAC,EAAE,IAAIE,MAAM,CAACP,cAAcE,IAAIG,IAAI,CAACR,MAAM,EAAE,CAAC,EAAEK,IAAII,aAAa,CAAC,CAAC;IAC/F;AACF,EAAE"}
@@ -3,13 +3,9 @@ import assert from "node:assert";
3
3
  import http from "node:http";
4
4
  import open from "open";
5
5
  import { config } from "../services/config/config.js";
6
- import { createLogger } from "../services/output/log/logger.js";
7
6
  import { sprint } from "../services/output/sprint.js";
8
7
  import { writeSession } from "../services/user/session.js";
9
8
  import { getUser } from "../services/user/user.js";
10
- const log = createLogger({
11
- name: "login"
12
- });
13
9
  export const usage = ()=>sprint`
14
10
  Log in to your account.
15
11
 
@@ -24,7 +20,7 @@ export const usage = ()=>sprint`
24
20
 
25
21
  Hello, Jane Doe (jane@example.com)
26
22
  `;
27
- export const login = async ()=>{
23
+ export const login = async (ctx)=>{
28
24
  let server;
29
25
  try {
30
26
  const port = await getPort();
@@ -37,12 +33,12 @@ export const login = async ()=>{
37
33
  const session = new URL(req.url, `http://localhost:${port}`).searchParams.get("session");
38
34
  assert(session, "missing session");
39
35
  writeSession(session);
40
- const user = await getUser();
36
+ const user = await getUser(ctx);
41
37
  assert(user, "missing user after successful login");
42
38
  if (user.name) {
43
- log.printlns`Hello, ${user.name} {gray (${user.email})}`;
39
+ ctx.log.printlns`Hello, ${user.name} {gray (${user.email})}`;
44
40
  } else {
45
- log.printlns`Hello, ${user.email}`;
41
+ ctx.log.printlns`Hello, ${user.email}`;
46
42
  }
47
43
  landingPage.searchParams.set("success", "true");
48
44
  resolve();
@@ -57,7 +53,7 @@ export const login = async ()=>{
57
53
  res.end();
58
54
  }
59
55
  });
60
- log.info("starting login server", {
56
+ ctx.log.info("starting login server", {
61
57
  port
62
58
  });
63
59
  server.listen(port);
@@ -69,16 +65,16 @@ export const login = async ()=>{
69
65
  url.searchParams.set("returnTo", `https://${config.domains.services}/auth/cli/callback?port=${port}`);
70
66
  try {
71
67
  await open(url.toString());
72
- log.printlns`
68
+ ctx.log.printlns`
73
69
  We've opened Gadget's login page using your default browser.
74
70
 
75
71
  Please log in and then return to this terminal.
76
72
  `;
77
73
  } catch (error) {
78
- log.error("failed to open browser", {
74
+ ctx.log.error("failed to open browser", {
79
75
  error
80
76
  });
81
- log.printlns`
77
+ ctx.log.printlns`
82
78
  Please open the following URL in your browser and log in:
83
79
 
84
80
  {gray ${url.toString()}}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/login.ts"],"sourcesContent":["import getPort from \"get-port\";\nimport assert from \"node:assert\";\nimport http, { type Server } from \"node:http\";\nimport open from \"open\";\nimport type { Command, Usage } from \"../services/command/command.js\";\nimport { config } from \"../services/config/config.js\";\nimport { createLogger } from \"../services/output/log/logger.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { writeSession } from \"../services/user/session.js\";\nimport { getUser } from \"../services/user/user.js\";\n\nconst log = createLogger({ name: \"login\" });\n\nexport const usage: Usage = () => sprint`\n Log in to your account.\n\n {bold USAGE}\n ggt login\n\n {bold EXAMPLE}\n $ ggt login\n We've opened Gadget's login page using your default browser.\n\n Please log in and then return to this terminal.\n\n Hello, Jane Doe (jane@example.com)\n`;\n\nexport const login = async (): Promise<void> => {\n let server: Server | undefined;\n\n try {\n const port = await getPort();\n const receiveSession = new Promise<void>((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n server = http.createServer(async (req, res) => {\n const landingPage = new URL(`https://${config.domains.services}/auth/cli`);\n\n try {\n assert(req.url, \"missing url\");\n const session = new URL(req.url, `http://localhost:${port}`).searchParams.get(\"session\");\n assert(session, \"missing session\");\n\n writeSession(session);\n\n const user = await getUser();\n assert(user, \"missing user after successful login\");\n\n if (user.name) {\n log.printlns`Hello, ${user.name} {gray (${user.email})}`;\n } else {\n log.printlns`Hello, ${user.email}`;\n }\n\n landingPage.searchParams.set(\"success\", \"true\");\n resolve();\n } catch (error) {\n writeSession(undefined);\n landingPage.searchParams.set(\"success\", \"false\");\n reject(error);\n } finally {\n res.writeHead(303, { Location: landingPage.toString() });\n res.end();\n }\n });\n\n log.info(\"starting login server\", { port });\n server.listen(port);\n });\n\n // open the login page in the user's default browser have it\n // redirect to the cli callback route. The cli callback route will\n // send the session to the server we just started.\n const url = new URL(`https://${config.domains.services}/auth/login`);\n url.searchParams.set(\"returnTo\", `https://${config.domains.services}/auth/cli/callback?port=${port}`);\n\n try {\n await open(url.toString());\n log.printlns`\n We've opened Gadget's login page using your default browser.\n\n Please log in and then return to this terminal.\n `;\n } catch (error) {\n log.error(\"failed to open browser\", { error });\n log.printlns`\n Please open the following URL in your browser and log in:\n\n {gray ${url.toString()}}\n\n Once logged in, return to this terminal.\n `;\n }\n\n await receiveSession;\n } finally {\n server?.close();\n }\n};\n\nexport const command: Command = login;\n"],"names":["getPort","assert","http","open","config","createLogger","sprint","writeSession","getUser","log","name","usage","login","server","port","receiveSession","Promise","resolve","reject","createServer","req","res","landingPage","URL","domains","services","url","session","searchParams","get","user","printlns","email","set","error","undefined","writeHead","Location","toString","end","info","listen","close","command"],"mappings":"AAAA,OAAOA,aAAa,WAAW;AAC/B,OAAOC,YAAY,cAAc;AACjC,OAAOC,UAA2B,YAAY;AAC9C,OAAOC,UAAU,OAAO;AAExB,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,YAAY,QAAQ,mCAAmC;AAChE,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,YAAY,QAAQ,8BAA8B;AAC3D,SAASC,OAAO,QAAQ,2BAA2B;AAEnD,MAAMC,MAAMJ,aAAa;IAAEK,MAAM;AAAQ;AAEzC,OAAO,MAAMC,QAAe,IAAML,MAAM,CAAC;;;;;;;;;;;;;AAazC,CAAC,CAAC;AAEF,OAAO,MAAMM,QAAQ;IACnB,IAAIC;IAEJ,IAAI;QACF,MAAMC,OAAO,MAAMd;QACnB,MAAMe,iBAAiB,IAAIC,QAAc,CAACC,SAASC;YACjD,kEAAkE;YAClEL,SAASX,KAAKiB,YAAY,CAAC,OAAOC,KAAKC;gBACrC,MAAMC,cAAc,IAAIC,IAAI,CAAC,QAAQ,EAAEnB,OAAOoB,OAAO,CAACC,QAAQ,CAAC,SAAS,CAAC;gBAEzE,IAAI;oBACFxB,OAAOmB,IAAIM,GAAG,EAAE;oBAChB,MAAMC,UAAU,IAAIJ,IAAIH,IAAIM,GAAG,EAAE,CAAC,iBAAiB,EAAEZ,KAAK,CAAC,EAAEc,YAAY,CAACC,GAAG,CAAC;oBAC9E5B,OAAO0B,SAAS;oBAEhBpB,aAAaoB;oBAEb,MAAMG,OAAO,MAAMtB;oBACnBP,OAAO6B,MAAM;oBAEb,IAAIA,KAAKpB,IAAI,EAAE;wBACbD,IAAIsB,QAAQ,CAAC,OAAO,EAAED,KAAKpB,IAAI,CAAC,QAAQ,EAAEoB,KAAKE,KAAK,CAAC,EAAE,CAAC;oBAC1D,OAAO;wBACLvB,IAAIsB,QAAQ,CAAC,OAAO,EAAED,KAAKE,KAAK,CAAC,CAAC;oBACpC;oBAEAV,YAAYM,YAAY,CAACK,GAAG,CAAC,WAAW;oBACxChB;gBACF,EAAE,OAAOiB,OAAO;oBACd3B,aAAa4B;oBACbb,YAAYM,YAAY,CAACK,GAAG,CAAC,WAAW;oBACxCf,OAAOgB;gBACT,SAAU;oBACRb,IAAIe,SAAS,CAAC,KAAK;wBAAEC,UAAUf,YAAYgB,QAAQ;oBAAG;oBACtDjB,IAAIkB,GAAG;gBACT;YACF;YAEA9B,IAAI+B,IAAI,CAAC,yBAAyB;gBAAE1B;YAAK;YACzCD,OAAO4B,MAAM,CAAC3B;QAChB;QAEA,4DAA4D;QAC5D,kEAAkE;QAClE,kDAAkD;QAClD,MAAMY,MAAM,IAAIH,IAAI,CAAC,QAAQ,EAAEnB,OAAOoB,OAAO,CAACC,QAAQ,CAAC,WAAW,CAAC;QACnEC,IAAIE,YAAY,CAACK,GAAG,CAAC,YAAY,CAAC,QAAQ,EAAE7B,OAAOoB,OAAO,CAACC,QAAQ,CAAC,wBAAwB,EAAEX,KAAK,CAAC;QAEpG,IAAI;YACF,MAAMX,KAAKuB,IAAIY,QAAQ;YACvB7B,IAAIsB,QAAQ,CAAC;;;;IAIf,CAAC;QACD,EAAE,OAAOG,OAAO;YACdzB,IAAIyB,KAAK,CAAC,0BAA0B;gBAAEA;YAAM;YAC5CzB,IAAIsB,QAAQ,CAAC;;;gBAGH,EAAEL,IAAIY,QAAQ,GAAG;;;MAG3B,CAAC;QACH;QAEA,MAAMvB;IACR,SAAU;QACRF,QAAQ6B;IACV;AACF,EAAE;AAEF,OAAO,MAAMC,UAAmB/B,MAAM"}
1
+ {"version":3,"sources":["../../src/commands/login.ts"],"sourcesContent":["import getPort from \"get-port\";\nimport assert from \"node:assert\";\nimport http, { type Server } from \"node:http\";\nimport open from \"open\";\nimport type { Command, Usage } from \"../services/command/command.js\";\nimport { config } from \"../services/config/config.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { writeSession } from \"../services/user/session.js\";\nimport { getUser } from \"../services/user/user.js\";\n\nexport const usage: Usage = () => sprint`\n Log in to your account.\n\n {bold USAGE}\n ggt login\n\n {bold EXAMPLE}\n $ ggt login\n We've opened Gadget's login page using your default browser.\n\n Please log in and then return to this terminal.\n\n Hello, Jane Doe (jane@example.com)\n`;\n\nexport const login: Command = async (ctx): Promise<void> => {\n let server: Server | undefined;\n\n try {\n const port = await getPort();\n const receiveSession = new Promise<void>((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n server = http.createServer(async (req, res) => {\n const landingPage = new URL(`https://${config.domains.services}/auth/cli`);\n\n try {\n assert(req.url, \"missing url\");\n const session = new URL(req.url, `http://localhost:${port}`).searchParams.get(\"session\");\n assert(session, \"missing session\");\n\n writeSession(session);\n\n const user = await getUser(ctx);\n assert(user, \"missing user after successful login\");\n\n if (user.name) {\n ctx.log.printlns`Hello, ${user.name} {gray (${user.email})}`;\n } else {\n ctx.log.printlns`Hello, ${user.email}`;\n }\n\n landingPage.searchParams.set(\"success\", \"true\");\n resolve();\n } catch (error) {\n writeSession(undefined);\n landingPage.searchParams.set(\"success\", \"false\");\n reject(error);\n } finally {\n res.writeHead(303, { Location: landingPage.toString() });\n res.end();\n }\n });\n\n ctx.log.info(\"starting login server\", { port });\n server.listen(port);\n });\n\n // open the login page in the user's default browser have it\n // redirect to the cli callback route. The cli callback route will\n // send the session to the server we just started.\n const url = new URL(`https://${config.domains.services}/auth/login`);\n url.searchParams.set(\"returnTo\", `https://${config.domains.services}/auth/cli/callback?port=${port}`);\n\n try {\n await open(url.toString());\n ctx.log.printlns`\n We've opened Gadget's login page using your default browser.\n\n Please log in and then return to this terminal.\n `;\n } catch (error) {\n ctx.log.error(\"failed to open browser\", { error });\n ctx.log.printlns`\n Please open the following URL in your browser and log in:\n\n {gray ${url.toString()}}\n\n Once logged in, return to this terminal.\n `;\n }\n\n await receiveSession;\n } finally {\n server?.close();\n }\n};\n\nexport const command = login;\n"],"names":["getPort","assert","http","open","config","sprint","writeSession","getUser","usage","login","ctx","server","port","receiveSession","Promise","resolve","reject","createServer","req","res","landingPage","URL","domains","services","url","session","searchParams","get","user","name","log","printlns","email","set","error","undefined","writeHead","Location","toString","end","info","listen","close","command"],"mappings":"AAAA,OAAOA,aAAa,WAAW;AAC/B,OAAOC,YAAY,cAAc;AACjC,OAAOC,UAA2B,YAAY;AAC9C,OAAOC,UAAU,OAAO;AAExB,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,YAAY,QAAQ,8BAA8B;AAC3D,SAASC,OAAO,QAAQ,2BAA2B;AAEnD,OAAO,MAAMC,QAAe,IAAMH,MAAM,CAAC;;;;;;;;;;;;;AAazC,CAAC,CAAC;AAEF,OAAO,MAAMI,QAAiB,OAAOC;IACnC,IAAIC;IAEJ,IAAI;QACF,MAAMC,OAAO,MAAMZ;QACnB,MAAMa,iBAAiB,IAAIC,QAAc,CAACC,SAASC;YACjD,kEAAkE;YAClEL,SAAST,KAAKe,YAAY,CAAC,OAAOC,KAAKC;gBACrC,MAAMC,cAAc,IAAIC,IAAI,CAAC,QAAQ,EAAEjB,OAAOkB,OAAO,CAACC,QAAQ,CAAC,SAAS,CAAC;gBAEzE,IAAI;oBACFtB,OAAOiB,IAAIM,GAAG,EAAE;oBAChB,MAAMC,UAAU,IAAIJ,IAAIH,IAAIM,GAAG,EAAE,CAAC,iBAAiB,EAAEZ,KAAK,CAAC,EAAEc,YAAY,CAACC,GAAG,CAAC;oBAC9E1B,OAAOwB,SAAS;oBAEhBnB,aAAamB;oBAEb,MAAMG,OAAO,MAAMrB,QAAQG;oBAC3BT,OAAO2B,MAAM;oBAEb,IAAIA,KAAKC,IAAI,EAAE;wBACbnB,IAAIoB,GAAG,CAACC,QAAQ,CAAC,OAAO,EAAEH,KAAKC,IAAI,CAAC,QAAQ,EAAED,KAAKI,KAAK,CAAC,EAAE,CAAC;oBAC9D,OAAO;wBACLtB,IAAIoB,GAAG,CAACC,QAAQ,CAAC,OAAO,EAAEH,KAAKI,KAAK,CAAC,CAAC;oBACxC;oBAEAZ,YAAYM,YAAY,CAACO,GAAG,CAAC,WAAW;oBACxClB;gBACF,EAAE,OAAOmB,OAAO;oBACd5B,aAAa6B;oBACbf,YAAYM,YAAY,CAACO,GAAG,CAAC,WAAW;oBACxCjB,OAAOkB;gBACT,SAAU;oBACRf,IAAIiB,SAAS,CAAC,KAAK;wBAAEC,UAAUjB,YAAYkB,QAAQ;oBAAG;oBACtDnB,IAAIoB,GAAG;gBACT;YACF;YAEA7B,IAAIoB,GAAG,CAACU,IAAI,CAAC,yBAAyB;gBAAE5B;YAAK;YAC7CD,OAAO8B,MAAM,CAAC7B;QAChB;QAEA,4DAA4D;QAC5D,kEAAkE;QAClE,kDAAkD;QAClD,MAAMY,MAAM,IAAIH,IAAI,CAAC,QAAQ,EAAEjB,OAAOkB,OAAO,CAACC,QAAQ,CAAC,WAAW,CAAC;QACnEC,IAAIE,YAAY,CAACO,GAAG,CAAC,YAAY,CAAC,QAAQ,EAAE7B,OAAOkB,OAAO,CAACC,QAAQ,CAAC,wBAAwB,EAAEX,KAAK,CAAC;QAEpG,IAAI;YACF,MAAMT,KAAKqB,IAAIc,QAAQ;YACvB5B,IAAIoB,GAAG,CAACC,QAAQ,CAAC;;;;IAInB,CAAC;QACD,EAAE,OAAOG,OAAO;YACdxB,IAAIoB,GAAG,CAACI,KAAK,CAAC,0BAA0B;gBAAEA;YAAM;YAChDxB,IAAIoB,GAAG,CAACC,QAAQ,CAAC;;;gBAGP,EAAEP,IAAIc,QAAQ,GAAG;;;MAG3B,CAAC;QACH;QAEA,MAAMzB;IACR,SAAU;QACRF,QAAQ+B;IACV;AACF,EAAE;AAEF,OAAO,MAAMC,UAAUlC,MAAM"}
@@ -1,9 +1,5 @@
1
- import { createLogger } from "../services/output/log/logger.js";
2
1
  import { sprint } from "../services/output/sprint.js";
3
2
  import { readSession, writeSession } from "../services/user/session.js";
4
- const log = createLogger({
5
- name: "logout"
6
- });
7
3
  export const usage = ()=>sprint`
8
4
  Log out of your account.
9
5
 
@@ -14,13 +10,13 @@ export const usage = ()=>sprint`
14
10
  $ ggt logout
15
11
  Goodbye
16
12
  `;
17
- export const command = ()=>{
13
+ export const command = (ctx)=>{
18
14
  const token = readSession();
19
15
  if (token) {
20
16
  writeSession(undefined);
21
- log.println("Goodbye");
17
+ ctx.log.println("Goodbye");
22
18
  } else {
23
- log.println("You are not logged in");
19
+ ctx.log.println("You are not logged in");
24
20
  }
25
21
  };
26
22
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/logout.ts"],"sourcesContent":["import type { Command, Usage } from \"../services/command/command.js\";\nimport { createLogger } from \"../services/output/log/logger.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { readSession, writeSession } from \"../services/user/session.js\";\n\nconst log = createLogger({ name: \"logout\" });\n\nexport const usage: Usage = () => sprint`\n Log out of your account.\n\n {bold USAGE}\n ggt logout\n\n {bold EXAMPLE}\n $ ggt logout\n Goodbye\n`;\n\nexport const command: Command = () => {\n const token = readSession();\n if (token) {\n writeSession(undefined);\n log.println(\"Goodbye\");\n } else {\n log.println(\"You are not logged in\");\n }\n};\n"],"names":["createLogger","sprint","readSession","writeSession","log","name","usage","command","token","undefined","println"],"mappings":"AACA,SAASA,YAAY,QAAQ,mCAAmC;AAChE,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,WAAW,EAAEC,YAAY,QAAQ,8BAA8B;AAExE,MAAMC,MAAMJ,aAAa;IAAEK,MAAM;AAAS;AAE1C,OAAO,MAAMC,QAAe,IAAML,MAAM,CAAC;;;;;;;;;AASzC,CAAC,CAAC;AAEF,OAAO,MAAMM,UAAmB;IAC9B,MAAMC,QAAQN;IACd,IAAIM,OAAO;QACTL,aAAaM;QACbL,IAAIM,OAAO,CAAC;IACd,OAAO;QACLN,IAAIM,OAAO,CAAC;IACd;AACF,EAAE"}
1
+ {"version":3,"sources":["../../src/commands/logout.ts"],"sourcesContent":["import type { Command, Usage } from \"../services/command/command.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { readSession, writeSession } from \"../services/user/session.js\";\n\nexport const usage: Usage = () => sprint`\n Log out of your account.\n\n {bold USAGE}\n ggt logout\n\n {bold EXAMPLE}\n $ ggt logout\n Goodbye\n`;\n\nexport const command: Command = (ctx) => {\n const token = readSession();\n if (token) {\n writeSession(undefined);\n ctx.log.println(\"Goodbye\");\n } else {\n ctx.log.println(\"You are not logged in\");\n }\n};\n"],"names":["sprint","readSession","writeSession","usage","command","ctx","token","undefined","log","println"],"mappings":"AACA,SAASA,MAAM,QAAQ,+BAA+B;AACtD,SAASC,WAAW,EAAEC,YAAY,QAAQ,8BAA8B;AAExE,OAAO,MAAMC,QAAe,IAAMH,MAAM,CAAC;;;;;;;;;AASzC,CAAC,CAAC;AAEF,OAAO,MAAMI,UAAmB,CAACC;IAC/B,MAAMC,QAAQL;IACd,IAAIK,OAAO;QACTJ,aAAaK;QACbF,IAAIG,GAAG,CAACC,OAAO,CAAC;IAClB,OAAO;QACLJ,IAAIG,GAAG,CAACC,OAAO,CAAC;IAClB;AACF,EAAE"}