@gadgetinc/ggt 0.4.8 → 0.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/lib/__generated__/graphql.js.map +1 -1
- package/lib/commands/deploy.js +61 -14
- package/lib/commands/deploy.js.map +1 -1
- package/lib/commands/sync.js +2 -2
- package/lib/commands/sync.js.map +1 -1
- package/lib/services/app/edit/operation.js +15 -0
- package/lib/services/app/edit/operation.js.map +1 -1
- package/lib/services/filesync/filesync.js +23 -3
- package/lib/services/filesync/filesync.js.map +1 -1
- package/lib/services/http/http.js +40 -0
- package/lib/services/http/http.js.map +1 -1
- package/npm-shrinkwrap.json +427 -266
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ With this running in the background, your local `~/gadget/my-app` folder will be
|
|
|
52
52
|
## Usage
|
|
53
53
|
|
|
54
54
|
```sh-session
|
|
55
|
-
$ npm install -g
|
|
55
|
+
$ npm install -g ggt
|
|
56
56
|
$ ggt
|
|
57
57
|
The command-line interface for Gadget
|
|
58
58
|
|
|
@@ -226,5 +226,5 @@ USAGE
|
|
|
226
226
|
|
|
227
227
|
EXAMPLE
|
|
228
228
|
$ ggt version
|
|
229
|
-
0.4.
|
|
229
|
+
0.4.10
|
|
230
230
|
```
|
|
@@ -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 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
|
+
{"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 Problem = {\n __typename?: 'Problem';\n level: Scalars['String']['output'];\n message: Scalars['String']['output'];\n path: Scalars['String']['output'];\n type: Scalars['String']['output'];\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 problems: Array<Problem>;\n remoteFilesVersion: Scalars['String']['output'];\n};\n\nexport type PublishIssue = {\n __typename?: 'PublishIssue';\n message: Scalars['String']['output'];\n node?: Maybe<PublishIssueNode>;\n nodeLabels?: Maybe<Array<Maybe<PublishIssueNodeLabel>>>;\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 PublishIssueNodeLabel = {\n __typename?: 'PublishIssueNodeLabel';\n identifier?: Maybe<Scalars['String']['output']>;\n type?: Maybe<Scalars['String']['output']>;\n};\n\nexport type PublishStatus = {\n __typename?: 'PublishStatus';\n code?: Maybe<Scalars['String']['output']>;\n message?: Maybe<Scalars['String']['output']>;\n output?: Maybe<Scalars['String']['output']>;\n};\n\nexport type PublishStatusState = {\n __typename?: 'PublishStatusState';\n issues: Array<PublishIssue>;\n progress: Scalars['String']['output'];\n publishStarted: Scalars['Boolean']['output'];\n remoteFilesVersion: Scalars['String']['output'];\n status?: Maybe<PublishStatus>;\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, problems: Array<{ __typename?: 'Problem', level: string, message: string, path: string, type: 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, nodeLabels?: Array<{ __typename?: 'PublishIssueNodeLabel', type?: string | null, identifier?: string | null } | null> | null }>, status?: { __typename?: 'PublishStatus', code?: string | null, message?: string | null, output?: string | null } | null } | null };\n"],"names":["FileSyncEncoding"],"mappings":"AAAA;;;;;;CAMC;UAyHWA;;;GAAAA,qBAAAA"}
|
package/lib/commands/deploy.js
CHANGED
|
@@ -98,6 +98,27 @@ var AppDeploymentSteps;
|
|
|
98
98
|
AppDeploymentSteps["RELOADING_SANDBOX"] = "RELOADING_SANDBOX";
|
|
99
99
|
AppDeploymentSteps["COMPLETED"] = "COMPLETED";
|
|
100
100
|
})(AppDeploymentSteps || (AppDeploymentSteps = {}));
|
|
101
|
+
const groupByProperty = (items, property)=>{
|
|
102
|
+
const grouped = {};
|
|
103
|
+
const defaultOtherIssues = "Other Issues";
|
|
104
|
+
for (const item of items){
|
|
105
|
+
if (item.node) {
|
|
106
|
+
const value = item.node[property];
|
|
107
|
+
if (value && !grouped[value]) {
|
|
108
|
+
grouped[value] = [];
|
|
109
|
+
grouped[value]?.push(item);
|
|
110
|
+
} else if (value && grouped[value]) {
|
|
111
|
+
grouped[value]?.push(item);
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
if (!grouped[defaultOtherIssues]) {
|
|
115
|
+
grouped[defaultOtherIssues] = [];
|
|
116
|
+
}
|
|
117
|
+
grouped[defaultOtherIssues].push(item);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return grouped;
|
|
121
|
+
};
|
|
101
122
|
/**
|
|
102
123
|
* Runs the deploy process.
|
|
103
124
|
*/ export const command = async (ctx, firstRun = true)=>{
|
|
@@ -163,20 +184,32 @@ var AppDeploymentSteps;
|
|
|
163
184
|
return;
|
|
164
185
|
},
|
|
165
186
|
onData: async ({ publishStatus })=>{
|
|
166
|
-
const { progress, issues } = publishStatus ?? {};
|
|
187
|
+
const { progress, issues, status } = publishStatus ?? {};
|
|
167
188
|
const hasIssues = issues?.length;
|
|
168
189
|
if (firstRun && hasIssues) {
|
|
169
190
|
ctx.log.printlns`{underline Issues detected}`;
|
|
170
|
-
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
191
|
+
const printIssues = (groupedIssues)=>{
|
|
192
|
+
for (const [name, nodeArray] of Object.entries(groupedIssues)){
|
|
193
|
+
ctx.log.println(`\n\n • ${chalk.cyan(name)} ${chalk.redBright(nodeArray.length === 1 ? `${nodeArray.length} issue` : `${nodeArray.length} issues`)}${nodeArray.map((e)=>{
|
|
194
|
+
if (!e.node) {
|
|
195
|
+
return `\n\t ${chalk.red("✖")} ${e.message}`;
|
|
196
|
+
}
|
|
197
|
+
return `\n\t ${chalk.red("✖")} ${titleFormatter(e)}: ${e.nodeLabels?.map((label)=>`${chalk.bgWhite.black(label.type.toLowerCase())} ${chalk.white.bold(label.identifier)}`).join("")}`;
|
|
198
|
+
}).join("")}`);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
const titleFormatter = (e)=>{
|
|
202
|
+
if (e.node?.type === "SourceFile") {
|
|
203
|
+
return `${chalk.magentaBright("Typescript")} ${e.message.replace(/[.,]+$/, "")}`;
|
|
204
|
+
}
|
|
205
|
+
return e.message.replace(/[.,]+$/, "");
|
|
206
|
+
};
|
|
207
|
+
const issuesWithNoNode = issues.filter((item)=>item.node?.apiIdentifier);
|
|
208
|
+
const groupedByApiIdentifier = groupByProperty(issuesWithNoNode, "apiIdentifier");
|
|
209
|
+
printIssues(groupedByApiIdentifier);
|
|
210
|
+
const remainingItems = issues.filter((item)=>!item.node?.apiIdentifier);
|
|
211
|
+
const groupedByName = groupByProperty(remainingItems, "name");
|
|
212
|
+
printIssues(groupedByName);
|
|
180
213
|
if (!ctx.args["--force"]) {
|
|
181
214
|
unsubscribe();
|
|
182
215
|
action = await select(ctx, {
|
|
@@ -201,10 +234,24 @@ var AppDeploymentSteps;
|
|
|
201
234
|
}
|
|
202
235
|
firstRun = false;
|
|
203
236
|
} else {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
237
|
+
const publishStatus = status ? status : undefined;
|
|
238
|
+
const handleCompletion = (message, color)=>{
|
|
239
|
+
spinner.stopAndPersist({
|
|
240
|
+
symbol: color === "red" ? chalk.red("✖") : chalk.greenBright("✔"),
|
|
241
|
+
text: color === "red" ? "Failed" : "DONE"
|
|
242
|
+
});
|
|
243
|
+
ctx.log.printlns(color === "red" ? chalk.red(message) : chalk.green(message));
|
|
244
|
+
if (publishStatus?.output) {
|
|
245
|
+
ctx.log.printlns(`Cmd/Ctrl + Click: \u001b]8;;${publishStatus.output}\u0007View Logs\u001b]8;;\u0007`);
|
|
246
|
+
}
|
|
207
247
|
unsubscribe();
|
|
248
|
+
};
|
|
249
|
+
if (publishStatus && "code" in publishStatus && publishStatus.code === "Errored") {
|
|
250
|
+
handleCompletion(publishStatus.message, "red");
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
if (progress === "COMPLETED") {
|
|
254
|
+
handleCompletion("Deploy completed. Good bye!", "green");
|
|
208
255
|
return;
|
|
209
256
|
}
|
|
210
257
|
const currentProgress = AppDeploymentStepsToAppDeployState(progress);
|
|
@@ -1 +1 @@
|
|
|
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
|
+
{"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\ntype Node = {\n [key: string]: string | undefined;\n type: string;\n key: string;\n apiIdentifier?: string;\n name?: string;\n fieldType?: string;\n parentKey?: string;\n parentApiIdentifier?: string;\n};\n\ntype NodeLabel = {\n type: string;\n identifier: string;\n};\n\ntype NodeIssue = {\n severity: string;\n message: string;\n node?: Node;\n nodeLabels?: NodeLabel[];\n};\n\ntype PublishStatus = {\n code?: string;\n message?: string;\n output?: string;\n};\n\ntype GroupedIssues = Record<string, NodeIssue[]>;\n\nconst groupByProperty = (items: NodeIssue[], property: string): GroupedIssues => {\n const grouped: GroupedIssues = {};\n const defaultOtherIssues = \"Other Issues\";\n\n for (const item of items) {\n if (item.node) {\n const value = item.node[property];\n\n if (value && !grouped[value]) {\n grouped[value] = [];\n grouped[value]?.push(item);\n } else if (value && grouped[value]) {\n grouped[value]?.push(item);\n }\n } else {\n if (!grouped[defaultOtherIssues]) {\n grouped[defaultOtherIssues] = [];\n }\n grouped[defaultOtherIssues].push(item);\n }\n }\n\n return grouped;\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, status } = publishStatus ?? {};\n\n const hasIssues = issues?.length;\n\n if (firstRun && hasIssues) {\n ctx.log.printlns`{underline Issues detected}`;\n\n const printIssues = (groupedIssues: GroupedIssues): void => {\n for (const [name, nodeArray] of Object.entries(groupedIssues)) {\n ctx.log.println(\n `\\n\\n • ${chalk.cyan(name)} ${chalk.redBright(\n nodeArray.length === 1 ? `${nodeArray.length} issue` : `${nodeArray.length} issues`,\n )}${nodeArray\n .map((e) => {\n if (!e.node) {\n return `\\n\\t ${chalk.red(\"✖\")} ${e.message}`;\n }\n\n return `\\n\\t ${chalk.red(\"✖\")} ${titleFormatter(e)}: ${e.nodeLabels\n ?.map((label: NodeLabel) => `${chalk.bgWhite.black(label.type.toLowerCase())} ${chalk.white.bold(label.identifier)}`)\n .join(\"\")}`;\n })\n .join(\"\")}`,\n );\n }\n };\n\n const titleFormatter = (e: NodeIssue): string => {\n if (e.node?.type === \"SourceFile\") {\n return `${chalk.magentaBright(\"Typescript\")} ${e.message.replace(/[.,]+$/, \"\")}`;\n }\n return e.message.replace(/[.,]+$/, \"\");\n };\n\n const issuesWithNoNode = issues.filter((item) => item.node?.apiIdentifier) as NodeIssue[];\n const groupedByApiIdentifier = groupByProperty(issuesWithNoNode, \"apiIdentifier\");\n printIssues(groupedByApiIdentifier);\n\n const remainingItems = issues.filter((item) => !item.node?.apiIdentifier) as NodeIssue[];\n const groupedByName = groupByProperty(remainingItems, \"name\");\n printIssues(groupedByName);\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 const publishStatus = status ? (status as PublishStatus) : undefined;\n\n const handleCompletion = (message: string | null | undefined, color: string): void => {\n spinner.stopAndPersist({\n symbol: color === \"red\" ? chalk.red(\"✖\") : chalk.greenBright(\"✔\"),\n text: color === \"red\" ? \"Failed\" : \"DONE\",\n });\n\n ctx.log.printlns(color === \"red\" ? chalk.red(message) : chalk.green(message));\n if (publishStatus?.output) {\n ctx.log.printlns(`Cmd/Ctrl + Click: \\u001b]8;;${publishStatus.output}\\u0007View Logs\\u001b]8;;\\u0007`);\n }\n unsubscribe();\n };\n\n if (publishStatus && \"code\" in publishStatus && publishStatus.code === \"Errored\") {\n handleCompletion(publishStatus.message, \"red\");\n return;\n }\n\n if (progress === AppDeploymentSteps.COMPLETED) {\n handleCompletion(\"Deploy completed. Good bye!\", \"green\");\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","groupByProperty","items","property","grouped","defaultOtherIssues","item","node","value","push","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","status","hasIssues","length","printIssues","groupedIssues","name","nodeArray","Object","entries","cyan","redBright","map","e","red","titleFormatter","nodeLabels","label","bgWhite","black","type","toLowerCase","white","bold","identifier","join","magentaBright","replace","issuesWithNoNode","filter","apiIdentifier","groupedByApiIdentifier","remainingItems","groupedByName","undefined","handleCompletion","color","stopAndPersist","symbol","greenBright","text","green","output","code","currentProgress","succeed","start"],"mappings":"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"}
|
package/lib/commands/sync.js
CHANGED
|
@@ -243,8 +243,8 @@ export const args = {
|
|
|
243
243
|
ggt v${config.version}
|
|
244
244
|
|
|
245
245
|
App ${filesync.app.slug}
|
|
246
|
-
Editor https://${filesync.app.
|
|
247
|
-
Playground https://${filesync.app.
|
|
246
|
+
Editor https://${filesync.app.primaryDomain}/edit
|
|
247
|
+
Playground https://${filesync.app.primaryDomain}/api/graphql/playground
|
|
248
248
|
Docs https://docs.gadget.dev/api/${filesync.app.slug}
|
|
249
249
|
|
|
250
250
|
Endpoints ${filesync.app.hasSplitEnvironments ? `
|
package/lib/commands/sync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/sync.ts"],"sourcesContent":["import dayjs from \"dayjs\";\nimport ms from \"ms\";\nimport path from \"node:path\";\nimport Watcher from \"watcher\";\nimport which from \"which\";\nimport type { ArgsDefinition } from \"../services/command/arg.js\";\nimport type { Command, Usage } from \"../services/command/command.js\";\nimport { config } from \"../services/config/config.js\";\nimport { Changes } from \"../services/filesync/changes.js\";\nimport { YarnNotFoundError } from \"../services/filesync/error.js\";\nimport { FileSync, FileSyncArgs } from \"../services/filesync/filesync.js\";\nimport { notify } from \"../services/output/notify.js\";\nimport { reportErrorAndExit } from \"../services/output/report.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { debounce } from \"../services/util/function.js\";\nimport { isAbortError } from \"../services/util/is.js\";\n\nexport const usage: Usage = () => sprint`\n Sync your Gadget environment's source code with your local filesystem.\n\n {bold USAGE}\n ggt sync [DIRECTORY]\n\n {bold ARGUMENTS}\n DIRECTORY The directory to sync files to (default: \".\")\n\n {bold FLAGS}\n -a, --app=<name> The Gadget application to sync files to\n --prefer=<filesystem> Prefer \"local\" or \"gadget\" conflicting changes\n --once Sync once and exit\n --force Sync regardless of local filesystem state\n\n {bold DESCRIPTION}\n Sync allows you to synchronize your Gadget application's source\n code with your local filesystem.\n\n While ggt sync is running, local file changes are immediately\n reflected within Gadget, while files that are changed in Gadget are\n immediately saved to your local filesystem.\n\n Ideal for:\n • Local development with editors like VSCode\n • Storing source code in a Git repository like GitHub\n\n Sync looks for a \".ignore\" file to exclude certain files/directories\n from being synced. The format is identical to Git's.\n\n These files are always ignored:\n • .DS_Store\n • .gadget\n • .git\n • node_modules\n\n Note:\n • Sync only works with your development environment\n • Avoid deleting/moving all your files while sync is running\n • Gadget only supports Yarn v1 for dependency installation\n\n {bold EXAMPLE}\n $ ggt sync ~/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 Watching for file changes... {gray Press Ctrl+C to stop}\n\n → Sent {gray 09:06:25 AM}\n {greenBright routes/GET-hello.js + created}\n\n → Sent {gray 09:06:49 AM}\n {blueBright routes/GET-hello.js ± updated}\n\n ← Received {gray 09:06:54 AM}\n {blueBright routes/GET-hello.js ± updated}\n\n ← Received {gray 09:06:56 AM}\n {redBright routes/GET-hello.js - deleted}\n ^C Stopping... {gray press Ctrl+C again to force}\n\n Goodbye!\n`;\n\nexport const args = {\n ...FileSyncArgs,\n \"--once\": Boolean,\n \"--file-push-delay\": { type: Number, default: ms(\"100ms\") },\n \"--file-watch-debounce\": { type: Number, default: ms(\"300ms\") },\n \"--file-watch-poll-interval\": { type: Number, default: ms(\"3s\") },\n \"--file-watch-poll-timeout\": { type: Number, default: ms(\"20s\") },\n \"--file-watch-rename-timeout\": { type: Number, default: ms(\"1.25s\") },\n} satisfies ArgsDefinition;\n\nexport type SyncArgs = typeof args;\n\n/**\n * Runs the sync process until it is stopped or an error occurs.\n */\nexport const command: Command<SyncArgs> = async (ctx) => {\n if (!which.sync(\"yarn\", { nothrow: true })) {\n throw new YarnNotFoundError();\n }\n\n const filesync = await FileSync.init(ctx);\n await filesync.sync();\n\n if (ctx.args[\"--once\"]) {\n ctx.log.println(\"Done!\");\n return;\n }\n\n /**\n * A list of filepaths that have changed because we (this ggt process)\n * modified them. This is used to avoid reacting to filesystem events\n * that we caused, which would cause an infinite loop.\n */\n const recentWritesToLocalFilesystem = new Map<string, number>();\n\n const clearRecentWritesInterval = setInterval(() => {\n for (const [path, timestamp] of recentWritesToLocalFilesystem) {\n if (dayjs().isAfter(timestamp + ms(\"5s\"))) {\n // this change should have been seen by now\n recentWritesToLocalFilesystem.delete(path);\n }\n }\n }, ms(\"1s\")).unref();\n\n /**\n * Subscribe to file changes on Gadget and apply them to the local\n * filesystem.\n */\n const unsubscribeFromGadgetChanges = filesync.subscribeToGadgetChanges({\n onError: (error) => ctx.abort(error),\n beforeChanges: ({ changed, deleted }) => {\n // add all the files and directories we're about to touch to\n // recentWritesToLocalFilesystem so that we don't send them back\n // to Gadget\n for (const filepath of [...changed, ...deleted]) {\n recentWritesToLocalFilesystem.set(filepath, Date.now());\n\n let dir = path.dirname(filepath);\n while (dir !== \".\") {\n recentWritesToLocalFilesystem.set(dir + \"/\", Date.now());\n dir = path.dirname(dir);\n }\n }\n },\n });\n\n /**\n * A buffer of local file changes to send to Gadget.\n */\n const localChangesBuffer = new Changes();\n\n /**\n * A debounced function that sends the local file changes to Gadget.\n */\n const sendChangesToGadget = debounce(ctx.args[\"--file-push-delay\"], () => {\n const changes = new Changes(localChangesBuffer.entries());\n localChangesBuffer.clear();\n filesync.sendChangesToGadget({ changes }).catch((error) => ctx.abort(error));\n });\n\n ctx.log.debug(\"watching\", { path: filesync.directory.path });\n\n /**\n * Watches the local filesystem for changes.\n */\n const fileWatcher = new Watcher(\n filesync.directory.path,\n {\n // don't emit an event for every watched file on boot\n ignoreInitial: true,\n // don't emit changes to .gadget/ files because they're readonly (Gadget manages them)\n ignore: (path: string) => filesync.directory.relative(path).startsWith(\".gadget\") || filesync.directory.ignores(path),\n renameDetection: true,\n recursive: true,\n debounce: ctx.args[\"--file-watch-debounce\"],\n pollingInterval: ctx.args[\"--file-watch-poll-interval\"],\n pollingTimeout: ctx.args[\"--file-watch-poll-timeout\"],\n renameTimeout: ctx.args[\"--file-watch-rename-timeout\"],\n },\n (event: string, absolutePath: string, renamedPath: string) => {\n const filepath = event === \"rename\" || event === \"renameDir\" ? renamedPath : absolutePath;\n const isDirectory = event === \"renameDir\" || event === \"addDir\" || event === \"unlinkDir\";\n const normalizedPath = filesync.directory.normalize(filepath, isDirectory);\n\n ctx.log.trace(\"file event\", { event, isDirectory, path: normalizedPath });\n\n if (filepath === filesync.directory.absolute(\".ignore\")) {\n filesync.directory.loadIgnoreFile().catch((error) => ctx.abort(error));\n } else if (filesync.directory.ignores(filepath)) {\n return;\n }\n\n if (recentWritesToLocalFilesystem.delete(normalizedPath)) {\n ctx.log.trace(\"ignoring event because we caused it\", { event, path: normalizedPath });\n return;\n }\n\n switch (event) {\n case \"add\":\n case \"addDir\":\n localChangesBuffer.set(normalizedPath, { type: \"create\" });\n break;\n case \"rename\":\n case \"renameDir\": {\n const oldNormalizedPath = filesync.directory.normalize(absolutePath, isDirectory);\n localChangesBuffer.set(normalizedPath, { type: \"create\", oldPath: oldNormalizedPath });\n break;\n }\n case \"change\": {\n localChangesBuffer.set(normalizedPath, { type: \"update\" });\n break;\n }\n case \"unlink\":\n case \"unlinkDir\": {\n localChangesBuffer.set(normalizedPath, { type: \"delete\" });\n break;\n }\n }\n\n sendChangesToGadget();\n },\n ).once(\"error\", (error) => ctx.abort(error));\n\n ctx.log.printlns`\n ggt v${config.version}\n\n App ${filesync.app.slug}\n Editor https://${filesync.app.slug}.gadget.app/edit\n Playground https://${filesync.app.slug}.gadget.app/api/graphql/playground\n Docs https://docs.gadget.dev/api/${filesync.app.slug}\n\n Endpoints ${\n filesync.app.hasSplitEnvironments\n ? `\n • https://${filesync.app.primaryDomain}\n • https://${filesync.app.slug}--development.gadget.app`\n : `\n • https://${filesync.app.primaryDomain}`\n }\n\n Watching for file changes... {gray Press Ctrl+C to stop}\n `;\n\n ctx.onAbort(async (reason) => {\n ctx.log.info(\"stopping\", { reason });\n\n unsubscribeFromGadgetChanges();\n fileWatcher.close();\n clearInterval(clearRecentWritesInterval);\n sendChangesToGadget.flush();\n\n try {\n await filesync.idle();\n } catch (error) {\n ctx.log.error(\"error while waiting for idle\", { error });\n }\n\n if (isAbortError(reason)) {\n ctx.log.printlns(\"Goodbye!\");\n return;\n }\n\n notify(ctx, { subtitle: \"Uh oh!\", message: \"An error occurred while syncing files\" });\n await reportErrorAndExit(ctx, reason);\n });\n};\n"],"names":["dayjs","ms","path","Watcher","which","config","Changes","YarnNotFoundError","FileSync","FileSyncArgs","notify","reportErrorAndExit","sprint","debounce","isAbortError","usage","args","Boolean","type","Number","default","command","ctx","sync","nothrow","filesync","init","log","println","recentWritesToLocalFilesystem","Map","clearRecentWritesInterval","setInterval","timestamp","isAfter","delete","unref","unsubscribeFromGadgetChanges","subscribeToGadgetChanges","onError","error","abort","beforeChanges","changed","deleted","filepath","set","Date","now","dir","dirname","localChangesBuffer","sendChangesToGadget","changes","entries","clear","catch","debug","directory","fileWatcher","ignoreInitial","ignore","relative","startsWith","ignores","renameDetection","recursive","pollingInterval","pollingTimeout","renameTimeout","event","absolutePath","renamedPath","isDirectory","normalizedPath","normalize","trace","absolute","loadIgnoreFile","oldNormalizedPath","oldPath","once","printlns","version","app","slug","hasSplitEnvironments","primaryDomain","onAbort","reason","info","close","clearInterval","flush","idle","subtitle","message"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/sync.ts"],"sourcesContent":["import dayjs from \"dayjs\";\nimport ms from \"ms\";\nimport path from \"node:path\";\nimport Watcher from \"watcher\";\nimport which from \"which\";\nimport type { ArgsDefinition } from \"../services/command/arg.js\";\nimport type { Command, Usage } from \"../services/command/command.js\";\nimport { config } from \"../services/config/config.js\";\nimport { Changes } from \"../services/filesync/changes.js\";\nimport { YarnNotFoundError } from \"../services/filesync/error.js\";\nimport { FileSync, FileSyncArgs } from \"../services/filesync/filesync.js\";\nimport { notify } from \"../services/output/notify.js\";\nimport { reportErrorAndExit } from \"../services/output/report.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { debounce } from \"../services/util/function.js\";\nimport { isAbortError } from \"../services/util/is.js\";\n\nexport const usage: Usage = () => sprint`\n Sync your Gadget environment's source code with your local filesystem.\n\n {bold USAGE}\n ggt sync [DIRECTORY]\n\n {bold ARGUMENTS}\n DIRECTORY The directory to sync files to (default: \".\")\n\n {bold FLAGS}\n -a, --app=<name> The Gadget application to sync files to\n --prefer=<filesystem> Prefer \"local\" or \"gadget\" conflicting changes\n --once Sync once and exit\n --force Sync regardless of local filesystem state\n\n {bold DESCRIPTION}\n Sync allows you to synchronize your Gadget application's source\n code with your local filesystem.\n\n While ggt sync is running, local file changes are immediately\n reflected within Gadget, while files that are changed in Gadget are\n immediately saved to your local filesystem.\n\n Ideal for:\n • Local development with editors like VSCode\n • Storing source code in a Git repository like GitHub\n\n Sync looks for a \".ignore\" file to exclude certain files/directories\n from being synced. The format is identical to Git's.\n\n These files are always ignored:\n • .DS_Store\n • .gadget\n • .git\n • node_modules\n\n Note:\n • Sync only works with your development environment\n • Avoid deleting/moving all your files while sync is running\n • Gadget only supports Yarn v1 for dependency installation\n\n {bold EXAMPLE}\n $ ggt sync ~/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 Watching for file changes... {gray Press Ctrl+C to stop}\n\n → Sent {gray 09:06:25 AM}\n {greenBright routes/GET-hello.js + created}\n\n → Sent {gray 09:06:49 AM}\n {blueBright routes/GET-hello.js ± updated}\n\n ← Received {gray 09:06:54 AM}\n {blueBright routes/GET-hello.js ± updated}\n\n ← Received {gray 09:06:56 AM}\n {redBright routes/GET-hello.js - deleted}\n ^C Stopping... {gray press Ctrl+C again to force}\n\n Goodbye!\n`;\n\nexport const args = {\n ...FileSyncArgs,\n \"--once\": Boolean,\n \"--file-push-delay\": { type: Number, default: ms(\"100ms\") },\n \"--file-watch-debounce\": { type: Number, default: ms(\"300ms\") },\n \"--file-watch-poll-interval\": { type: Number, default: ms(\"3s\") },\n \"--file-watch-poll-timeout\": { type: Number, default: ms(\"20s\") },\n \"--file-watch-rename-timeout\": { type: Number, default: ms(\"1.25s\") },\n} satisfies ArgsDefinition;\n\nexport type SyncArgs = typeof args;\n\n/**\n * Runs the sync process until it is stopped or an error occurs.\n */\nexport const command: Command<SyncArgs> = async (ctx) => {\n if (!which.sync(\"yarn\", { nothrow: true })) {\n throw new YarnNotFoundError();\n }\n\n const filesync = await FileSync.init(ctx);\n await filesync.sync();\n\n if (ctx.args[\"--once\"]) {\n ctx.log.println(\"Done!\");\n return;\n }\n\n /**\n * A list of filepaths that have changed because we (this ggt process)\n * modified them. This is used to avoid reacting to filesystem events\n * that we caused, which would cause an infinite loop.\n */\n const recentWritesToLocalFilesystem = new Map<string, number>();\n\n const clearRecentWritesInterval = setInterval(() => {\n for (const [path, timestamp] of recentWritesToLocalFilesystem) {\n if (dayjs().isAfter(timestamp + ms(\"5s\"))) {\n // this change should have been seen by now\n recentWritesToLocalFilesystem.delete(path);\n }\n }\n }, ms(\"1s\")).unref();\n\n /**\n * Subscribe to file changes on Gadget and apply them to the local\n * filesystem.\n */\n const unsubscribeFromGadgetChanges = filesync.subscribeToGadgetChanges({\n onError: (error) => ctx.abort(error),\n beforeChanges: ({ changed, deleted }) => {\n // add all the files and directories we're about to touch to\n // recentWritesToLocalFilesystem so that we don't send them back\n // to Gadget\n for (const filepath of [...changed, ...deleted]) {\n recentWritesToLocalFilesystem.set(filepath, Date.now());\n\n let dir = path.dirname(filepath);\n while (dir !== \".\") {\n recentWritesToLocalFilesystem.set(dir + \"/\", Date.now());\n dir = path.dirname(dir);\n }\n }\n },\n });\n\n /**\n * A buffer of local file changes to send to Gadget.\n */\n const localChangesBuffer = new Changes();\n\n /**\n * A debounced function that sends the local file changes to Gadget.\n */\n const sendChangesToGadget = debounce(ctx.args[\"--file-push-delay\"], () => {\n const changes = new Changes(localChangesBuffer.entries());\n localChangesBuffer.clear();\n filesync.sendChangesToGadget({ changes }).catch((error) => ctx.abort(error));\n });\n\n ctx.log.debug(\"watching\", { path: filesync.directory.path });\n\n /**\n * Watches the local filesystem for changes.\n */\n const fileWatcher = new Watcher(\n filesync.directory.path,\n {\n // don't emit an event for every watched file on boot\n ignoreInitial: true,\n // don't emit changes to .gadget/ files because they're readonly (Gadget manages them)\n ignore: (path: string) => filesync.directory.relative(path).startsWith(\".gadget\") || filesync.directory.ignores(path),\n renameDetection: true,\n recursive: true,\n debounce: ctx.args[\"--file-watch-debounce\"],\n pollingInterval: ctx.args[\"--file-watch-poll-interval\"],\n pollingTimeout: ctx.args[\"--file-watch-poll-timeout\"],\n renameTimeout: ctx.args[\"--file-watch-rename-timeout\"],\n },\n (event: string, absolutePath: string, renamedPath: string) => {\n const filepath = event === \"rename\" || event === \"renameDir\" ? renamedPath : absolutePath;\n const isDirectory = event === \"renameDir\" || event === \"addDir\" || event === \"unlinkDir\";\n const normalizedPath = filesync.directory.normalize(filepath, isDirectory);\n\n ctx.log.trace(\"file event\", { event, isDirectory, path: normalizedPath });\n\n if (filepath === filesync.directory.absolute(\".ignore\")) {\n filesync.directory.loadIgnoreFile().catch((error) => ctx.abort(error));\n } else if (filesync.directory.ignores(filepath)) {\n return;\n }\n\n if (recentWritesToLocalFilesystem.delete(normalizedPath)) {\n ctx.log.trace(\"ignoring event because we caused it\", { event, path: normalizedPath });\n return;\n }\n\n switch (event) {\n case \"add\":\n case \"addDir\":\n localChangesBuffer.set(normalizedPath, { type: \"create\" });\n break;\n case \"rename\":\n case \"renameDir\": {\n const oldNormalizedPath = filesync.directory.normalize(absolutePath, isDirectory);\n localChangesBuffer.set(normalizedPath, { type: \"create\", oldPath: oldNormalizedPath });\n break;\n }\n case \"change\": {\n localChangesBuffer.set(normalizedPath, { type: \"update\" });\n break;\n }\n case \"unlink\":\n case \"unlinkDir\": {\n localChangesBuffer.set(normalizedPath, { type: \"delete\" });\n break;\n }\n }\n\n sendChangesToGadget();\n },\n ).once(\"error\", (error) => ctx.abort(error));\n\n ctx.log.printlns`\n ggt v${config.version}\n\n App ${filesync.app.slug}\n Editor https://${filesync.app.primaryDomain}/edit\n Playground https://${filesync.app.primaryDomain}/api/graphql/playground\n Docs https://docs.gadget.dev/api/${filesync.app.slug}\n\n Endpoints ${\n filesync.app.hasSplitEnvironments\n ? `\n • https://${filesync.app.primaryDomain}\n • https://${filesync.app.slug}--development.gadget.app`\n : `\n • https://${filesync.app.primaryDomain}`\n }\n\n Watching for file changes... {gray Press Ctrl+C to stop}\n `;\n\n ctx.onAbort(async (reason) => {\n ctx.log.info(\"stopping\", { reason });\n\n unsubscribeFromGadgetChanges();\n fileWatcher.close();\n clearInterval(clearRecentWritesInterval);\n sendChangesToGadget.flush();\n\n try {\n await filesync.idle();\n } catch (error) {\n ctx.log.error(\"error while waiting for idle\", { error });\n }\n\n if (isAbortError(reason)) {\n ctx.log.printlns(\"Goodbye!\");\n return;\n }\n\n notify(ctx, { subtitle: \"Uh oh!\", message: \"An error occurred while syncing files\" });\n await reportErrorAndExit(ctx, reason);\n });\n};\n"],"names":["dayjs","ms","path","Watcher","which","config","Changes","YarnNotFoundError","FileSync","FileSyncArgs","notify","reportErrorAndExit","sprint","debounce","isAbortError","usage","args","Boolean","type","Number","default","command","ctx","sync","nothrow","filesync","init","log","println","recentWritesToLocalFilesystem","Map","clearRecentWritesInterval","setInterval","timestamp","isAfter","delete","unref","unsubscribeFromGadgetChanges","subscribeToGadgetChanges","onError","error","abort","beforeChanges","changed","deleted","filepath","set","Date","now","dir","dirname","localChangesBuffer","sendChangesToGadget","changes","entries","clear","catch","debug","directory","fileWatcher","ignoreInitial","ignore","relative","startsWith","ignores","renameDetection","recursive","pollingInterval","pollingTimeout","renameTimeout","event","absolutePath","renamedPath","isDirectory","normalizedPath","normalize","trace","absolute","loadIgnoreFile","oldNormalizedPath","oldPath","once","printlns","version","app","slug","primaryDomain","hasSplitEnvironments","onAbort","reason","info","close","clearInterval","flush","idle","subtitle","message"],"mappings":"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"}
|
|
@@ -24,6 +24,12 @@ export const PUBLISH_FILE_SYNC_EVENTS_MUTATION = sprint(/* GraphQL */ `
|
|
|
24
24
|
mutation PublishFileSyncEvents($input: PublishFileSyncEventsInput!) {
|
|
25
25
|
publishFileSyncEvents(input: $input) {
|
|
26
26
|
remoteFilesVersion
|
|
27
|
+
problems {
|
|
28
|
+
level
|
|
29
|
+
message
|
|
30
|
+
path
|
|
31
|
+
type
|
|
32
|
+
}
|
|
27
33
|
}
|
|
28
34
|
}
|
|
29
35
|
`);
|
|
@@ -79,6 +85,15 @@ export const REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION = sprint(/* GraphQL */ `
|
|
|
79
85
|
parentKey
|
|
80
86
|
parentApiIdentifier
|
|
81
87
|
}
|
|
88
|
+
nodeLabels {
|
|
89
|
+
type
|
|
90
|
+
identifier
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
status {
|
|
94
|
+
code
|
|
95
|
+
message
|
|
96
|
+
output
|
|
82
97
|
}
|
|
83
98
|
}
|
|
84
99
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/services/app/edit/operation.ts"],"sourcesContent":["import type { ExecutionResult } from \"graphql-ws\";\nimport type { JsonObject } from \"type-fest\";\nimport type {\n FileSyncComparisonHashesQuery,\n FileSyncComparisonHashesQueryVariables,\n FileSyncFilesQuery,\n FileSyncFilesQueryVariables,\n FileSyncHashesQuery,\n FileSyncHashesQueryVariables,\n PublishFileSyncEventsMutation,\n PublishFileSyncEventsMutationVariables,\n PublishStatusSubscription,\n PublishStatusSubscriptionVariables,\n RemoteFileSyncEventsSubscription,\n RemoteFileSyncEventsSubscriptionVariables,\n RemoteFilesVersionQuery,\n RemoteFilesVersionQueryVariables,\n} from \"../../../__generated__/graphql.js\";\nimport { sprint } from \"../../output/sprint.js\";\n\n/**\n * A GraphQL query with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLQuery<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"query\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\n/**\n * A GraphQL mutation with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLMutation<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"mutation\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\n/**\n * A GraphQL subscription with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLSubscription<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"subscription\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\nexport const REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION = sprint(/* GraphQL */ `\n subscription RemoteFileSyncEvents($localFilesVersion: String!) {\n remoteFileSyncEvents(localFilesVersion: $localFilesVersion, encoding: base64) {\n remoteFilesVersion\n changed {\n path\n mode\n content\n encoding\n }\n deleted {\n path\n }\n }\n }\n`) as GraphQLSubscription<RemoteFileSyncEventsSubscription, RemoteFileSyncEventsSubscriptionVariables>;\n\nexport type REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION = typeof REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION;\n\nexport const REMOTE_FILES_VERSION_QUERY = sprint(/* GraphQL */ `\n query RemoteFilesVersion {\n remoteFilesVersion\n }\n`) as GraphQLQuery<RemoteFilesVersionQuery, RemoteFilesVersionQueryVariables>;\n\nexport type REMOTE_FILES_VERSION_QUERY = typeof REMOTE_FILES_VERSION_QUERY;\n\nexport const PUBLISH_FILE_SYNC_EVENTS_MUTATION = sprint(/* GraphQL */ `\n mutation PublishFileSyncEvents($input: PublishFileSyncEventsInput!) {\n publishFileSyncEvents(input: $input) {\n remoteFilesVersion\n }\n }\n`) as GraphQLMutation<PublishFileSyncEventsMutation, PublishFileSyncEventsMutationVariables>;\n\nexport type PUBLISH_FILE_SYNC_EVENTS_MUTATION = typeof PUBLISH_FILE_SYNC_EVENTS_MUTATION;\n\nexport const FILE_SYNC_FILES_QUERY = sprint(/* GraphQL */ `\n query FileSyncFiles($paths: [String!]!, $filesVersion: String, $encoding: FileSyncEncoding) {\n fileSyncFiles(paths: $paths, filesVersion: $filesVersion, encoding: $encoding) {\n filesVersion\n files {\n path\n mode\n content\n encoding\n }\n }\n }\n`) as GraphQLQuery<FileSyncFilesQuery, FileSyncFilesQueryVariables>;\n\nexport type FILE_SYNC_FILES_QUERY = typeof FILE_SYNC_FILES_QUERY;\n\nexport const FILE_SYNC_HASHES_QUERY = sprint(/* GraphQL */ `\n query FileSyncHashes($filesVersion: String) {\n fileSyncHashes(filesVersion: $filesVersion) {\n filesVersion\n hashes\n }\n }\n`) as GraphQLQuery<FileSyncHashesQuery, FileSyncHashesQueryVariables>;\n\nexport type FILE_SYNC_HASHES_QUERY = typeof FILE_SYNC_HASHES_QUERY;\n\nexport const FILE_SYNC_COMPARISON_HASHES_QUERY = sprint(/* GraphQL */ `\n query FileSyncComparisonHashes($filesVersion: String!) {\n fileSyncComparisonHashes(filesVersion: $filesVersion) {\n filesVersionHashes {\n filesVersion\n hashes\n }\n latestFilesVersionHashes {\n filesVersion\n hashes\n }\n }\n }\n`) as GraphQLQuery<FileSyncComparisonHashesQuery, FileSyncComparisonHashesQueryVariables>;\n\nexport type FILE_SYNC_COMPARISON_HASHES_QUERY = typeof FILE_SYNC_COMPARISON_HASHES_QUERY;\n\nexport const REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION = sprint(/* GraphQL */ `\n subscription publishStatus($localFilesVersion: String!, $force: Boolean) {\n publishStatus(localFilesVersion: $localFilesVersion, force: $force) {\n remoteFilesVersion\n progress\n issues {\n severity\n message\n node {\n type\n key\n apiIdentifier\n name\n fieldType\n parentKey\n parentApiIdentifier\n }\n }\n }\n }\n`) as GraphQLSubscription<PublishStatusSubscription, PublishStatusSubscriptionVariables>;\n\nexport type REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION = typeof REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION;\n"],"names":["sprint","REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION","REMOTE_FILES_VERSION_QUERY","PUBLISH_FILE_SYNC_EVENTS_MUTATION","FILE_SYNC_FILES_QUERY","FILE_SYNC_HASHES_QUERY","FILE_SYNC_COMPARISON_HASHES_QUERY","REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION"],"mappings":"AAkBA,SAASA,MAAM,QAAQ,yBAAyB;AAwDhD,OAAO,MAAMC,uCAAuCD,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;;;;AAe1E,CAAC,EAAsG;AAIvG,OAAO,MAAME,6BAA6BF,OAAO,WAAW,GAAG,CAAC;;;;AAIhE,CAAC,EAA6E;AAI9E,OAAO,MAAMG,oCAAoCH,OAAO,WAAW,GAAG,CAAC
|
|
1
|
+
{"version":3,"sources":["../../../../src/services/app/edit/operation.ts"],"sourcesContent":["import type { ExecutionResult } from \"graphql-ws\";\nimport type { JsonObject } from \"type-fest\";\nimport type {\n FileSyncComparisonHashesQuery,\n FileSyncComparisonHashesQueryVariables,\n FileSyncFilesQuery,\n FileSyncFilesQueryVariables,\n FileSyncHashesQuery,\n FileSyncHashesQueryVariables,\n PublishFileSyncEventsMutation,\n PublishFileSyncEventsMutationVariables,\n PublishStatusSubscription,\n PublishStatusSubscriptionVariables,\n RemoteFileSyncEventsSubscription,\n RemoteFileSyncEventsSubscriptionVariables,\n RemoteFilesVersionQuery,\n RemoteFilesVersionQueryVariables,\n} from \"../../../__generated__/graphql.js\";\nimport { sprint } from \"../../output/sprint.js\";\n\n/**\n * A GraphQL query with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLQuery<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"query\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\n/**\n * A GraphQL mutation with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLMutation<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"mutation\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\n/**\n * A GraphQL subscription with its associated types.\n *\n * At runtime, this is just a string.\n */\nexport type GraphQLSubscription<\n Data extends JsonObject = JsonObject,\n Variables extends JsonObject = JsonObject,\n Extensions extends JsonObject = JsonObject,\n Response extends ExecutionResult<Data, Extensions> = ExecutionResult<Data, Extensions>,\n> = string & {\n type: \"subscription\";\n Data: Data;\n Variables: Variables;\n Extensions: Extensions;\n Response: Response;\n};\n\nexport const REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION = sprint(/* GraphQL */ `\n subscription RemoteFileSyncEvents($localFilesVersion: String!) {\n remoteFileSyncEvents(localFilesVersion: $localFilesVersion, encoding: base64) {\n remoteFilesVersion\n changed {\n path\n mode\n content\n encoding\n }\n deleted {\n path\n }\n }\n }\n`) as GraphQLSubscription<RemoteFileSyncEventsSubscription, RemoteFileSyncEventsSubscriptionVariables>;\n\nexport type REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION = typeof REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION;\n\nexport const REMOTE_FILES_VERSION_QUERY = sprint(/* GraphQL */ `\n query RemoteFilesVersion {\n remoteFilesVersion\n }\n`) as GraphQLQuery<RemoteFilesVersionQuery, RemoteFilesVersionQueryVariables>;\n\nexport type REMOTE_FILES_VERSION_QUERY = typeof REMOTE_FILES_VERSION_QUERY;\n\nexport const PUBLISH_FILE_SYNC_EVENTS_MUTATION = sprint(/* GraphQL */ `\n mutation PublishFileSyncEvents($input: PublishFileSyncEventsInput!) {\n publishFileSyncEvents(input: $input) {\n remoteFilesVersion\n problems {\n level\n message\n path\n type\n }\n }\n }\n`) as GraphQLMutation<PublishFileSyncEventsMutation, PublishFileSyncEventsMutationVariables>;\n\nexport type PUBLISH_FILE_SYNC_EVENTS_MUTATION = typeof PUBLISH_FILE_SYNC_EVENTS_MUTATION;\n\nexport const FILE_SYNC_FILES_QUERY = sprint(/* GraphQL */ `\n query FileSyncFiles($paths: [String!]!, $filesVersion: String, $encoding: FileSyncEncoding) {\n fileSyncFiles(paths: $paths, filesVersion: $filesVersion, encoding: $encoding) {\n filesVersion\n files {\n path\n mode\n content\n encoding\n }\n }\n }\n`) as GraphQLQuery<FileSyncFilesQuery, FileSyncFilesQueryVariables>;\n\nexport type FILE_SYNC_FILES_QUERY = typeof FILE_SYNC_FILES_QUERY;\n\nexport const FILE_SYNC_HASHES_QUERY = sprint(/* GraphQL */ `\n query FileSyncHashes($filesVersion: String) {\n fileSyncHashes(filesVersion: $filesVersion) {\n filesVersion\n hashes\n }\n }\n`) as GraphQLQuery<FileSyncHashesQuery, FileSyncHashesQueryVariables>;\n\nexport type FILE_SYNC_HASHES_QUERY = typeof FILE_SYNC_HASHES_QUERY;\n\nexport const FILE_SYNC_COMPARISON_HASHES_QUERY = sprint(/* GraphQL */ `\n query FileSyncComparisonHashes($filesVersion: String!) {\n fileSyncComparisonHashes(filesVersion: $filesVersion) {\n filesVersionHashes {\n filesVersion\n hashes\n }\n latestFilesVersionHashes {\n filesVersion\n hashes\n }\n }\n }\n`) as GraphQLQuery<FileSyncComparisonHashesQuery, FileSyncComparisonHashesQueryVariables>;\n\nexport type FILE_SYNC_COMPARISON_HASHES_QUERY = typeof FILE_SYNC_COMPARISON_HASHES_QUERY;\n\nexport const REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION = sprint(/* GraphQL */ `\n subscription publishStatus($localFilesVersion: String!, $force: Boolean) {\n publishStatus(localFilesVersion: $localFilesVersion, force: $force) {\n remoteFilesVersion\n progress\n issues {\n severity\n message\n node {\n type\n key\n apiIdentifier\n name\n fieldType\n parentKey\n parentApiIdentifier\n }\n nodeLabels {\n type\n identifier\n }\n }\n status {\n code\n message\n output\n }\n }\n }\n`) as GraphQLSubscription<PublishStatusSubscription, PublishStatusSubscriptionVariables>;\n\nexport type REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION = typeof REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION;\n"],"names":["sprint","REMOTE_FILE_SYNC_EVENTS_SUBSCRIPTION","REMOTE_FILES_VERSION_QUERY","PUBLISH_FILE_SYNC_EVENTS_MUTATION","FILE_SYNC_FILES_QUERY","FILE_SYNC_HASHES_QUERY","FILE_SYNC_COMPARISON_HASHES_QUERY","REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION"],"mappings":"AAkBA,SAASA,MAAM,QAAQ,yBAAyB;AAwDhD,OAAO,MAAMC,uCAAuCD,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;;;;AAe1E,CAAC,EAAsG;AAIvG,OAAO,MAAME,6BAA6BF,OAAO,WAAW,GAAG,CAAC;;;;AAIhE,CAAC,EAA6E;AAI9E,OAAO,MAAMG,oCAAoCH,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;AAYvE,CAAC,EAA4F;AAI7F,OAAO,MAAMI,wBAAwBJ,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;AAY3D,CAAC,EAAmE;AAIpE,OAAO,MAAMK,yBAAyBL,OAAO,WAAW,GAAG,CAAC;;;;;;;AAO5D,CAAC,EAAqE;AAItE,OAAO,MAAMM,oCAAoCN,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;;AAavE,CAAC,EAAyF;AAI1F,OAAO,MAAMO,6CAA6CP,OAAO,WAAW,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BhF,CAAC,EAAwF"}
|
|
@@ -504,7 +504,7 @@ export class FileSync {
|
|
|
504
504
|
this.ctx.log.debug("skipping send because there are no changes");
|
|
505
505
|
return;
|
|
506
506
|
}
|
|
507
|
-
const { publishFileSyncEvents: { remoteFilesVersion } } = await this.edit.mutate({
|
|
507
|
+
const { publishFileSyncEvents: { remoteFilesVersion, problems } } = await this.edit.mutate({
|
|
508
508
|
mutation: PUBLISH_FILE_SYNC_EVENTS_MUTATION,
|
|
509
509
|
variables: {
|
|
510
510
|
input: {
|
|
@@ -541,6 +541,24 @@ export class FileSync {
|
|
|
541
541
|
// received the intermediate filesVersions yet
|
|
542
542
|
throw new Error("Files version mismatch");
|
|
543
543
|
}
|
|
544
|
+
if (problems.length > 0) {
|
|
545
|
+
const problemGroup = {};
|
|
546
|
+
problems.forEach((problem)=>{
|
|
547
|
+
if (!(problem.path in problemGroup)) {
|
|
548
|
+
problemGroup[problem.path] = [];
|
|
549
|
+
}
|
|
550
|
+
problemGroup[problem.path]?.push(problem.message);
|
|
551
|
+
});
|
|
552
|
+
this.ctx.log.println2`{red Gadget has detected the following fatal errors with your files:}`;
|
|
553
|
+
Object.entries(problemGroup).forEach(([path, messages])=>{
|
|
554
|
+
this.ctx.log.println`{red [${path}]}`;
|
|
555
|
+
messages.forEach((message)=>{
|
|
556
|
+
this.ctx.log.println`{red - ${message}}`;
|
|
557
|
+
});
|
|
558
|
+
});
|
|
559
|
+
this.ctx.log.println("");
|
|
560
|
+
this.ctx.log.println2`{red Your app will not be operational until all fatal errors are fixed.}`;
|
|
561
|
+
}
|
|
544
562
|
await this._save(remoteFilesVersion);
|
|
545
563
|
}
|
|
546
564
|
async _writeToLocalFilesystem(options) {
|
|
@@ -571,7 +589,9 @@ export class FileSync {
|
|
|
571
589
|
swallowEnoent(error);
|
|
572
590
|
}
|
|
573
591
|
}, {
|
|
574
|
-
|
|
592
|
+
// windows tends to run into these issues way more often than
|
|
593
|
+
// mac/linux, so we retry more times
|
|
594
|
+
retries: config.windows ? 4 : 2,
|
|
575
595
|
minTimeout: ms("100ms"),
|
|
576
596
|
onFailedAttempt: (error)=>{
|
|
577
597
|
this.ctx.log.warn("failed to move file to backup", {
|
|
@@ -751,7 +771,7 @@ export const isFilesVersionMismatchError = (error)=>{
|
|
|
751
771
|
if (isGraphQLErrors(error)) {
|
|
752
772
|
error = error[0];
|
|
753
773
|
}
|
|
754
|
-
return isObject(error) && "message" in error && isString(error.message) && error.message.
|
|
774
|
+
return isObject(error) && "message" in error && isString(error.message) && error.message.includes("Files version mismatch");
|
|
755
775
|
};
|
|
756
776
|
const swallowFilesVersionMismatch = (ctx, error)=>{
|
|
757
777
|
if (isFilesVersionMismatchError(error)) {
|