@gadgetinc/ggt 0.4.5 → 0.4.7
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 +1 -1
- package/lib/__generated__/graphql.js.map +1 -1
- package/lib/commands/deploy.js +39 -41
- package/lib/commands/deploy.js.map +1 -1
- package/lib/commands/root.js +4 -3
- package/lib/commands/root.js.map +1 -1
- package/lib/commands/sync.js +5 -15
- package/lib/commands/sync.js.map +1 -1
- package/lib/services/app/edit-graphql.js +6 -3
- package/lib/services/app/edit-graphql.js.map +1 -1
- package/lib/services/command/command.js +4 -0
- package/lib/services/command/command.js.map +1 -1
- package/lib/services/command/context.js +53 -18
- package/lib/services/command/context.js.map +1 -1
- package/lib/services/filesync/filesync.js +123 -60
- package/lib/services/filesync/filesync.js.map +1 -1
- package/lib/services/filesync/hashes.js +19 -17
- package/lib/services/filesync/hashes.js.map +1 -1
- package/lib/services/http/http.js +12 -5
- package/lib/services/http/http.js.map +1 -1
- package/lib/services/util/is.js +19 -1
- package/lib/services/util/is.js.map +1 -1
- package/lib/services/util/types.js +3 -0
- package/lib/services/util/types.js.map +1 -0
- package/npm-shrinkwrap.json +69 -69
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/__generated__/graphql.ts"],"sourcesContent":["/**\n * ======================================================\n * THIS IS A GENERATED FILE! DO NOT EDIT IT MANUALLY!\n *\n * You can regenerate it by running `npm run generate-graphql`.\n * ======================================================\n */\n\nexport type Maybe<T> = T | null;\nexport type InputMaybe<T> = Maybe<T>;\nexport type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };\nexport type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };\nexport type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };\nexport type MakeEmpty<T extends { [key: string]: unknown }, K extends keyof T> = { [_ in K]?: never };\nexport type Incremental<T> = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };\n/** All built-in and custom scalars, mapped to their actual values */\nexport type Scalars = {\n ID: { input: string; output: string; }\n String: { input: string; output: string; }\n Boolean: { input: boolean; output: boolean; }\n Int: { input: number; output: number; }\n Float: { input: number; output: number; }\n /** A date string, such as 2007-12-03, compliant with the `full-date` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. */\n Date: { input: any; output: any; }\n /** A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. */\n DateTime: { input: any; output: any; }\n JSON: { input: { [key: string]: any }; output: { [key: string]: any }; }\n /** The `Upload` scalar type represents a file upload. */\n Upload: { input: any; output: any; }\n};\n\nexport type ApiUpgradeConvergePlanResult = {\n __typename?: 'APIUpgradeConvergePlanResult';\n items: Array<Scalars['JSON']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type AddApplicationTagResult = {\n __typename?: 'AddApplicationTagResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type AddUserTagResult = {\n __typename?: 'AddUserTagResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type ChangeAppDomainResult = {\n __typename?: 'ChangeAppDomainResult';\n onlyValidate?: Maybe<Scalars['Boolean']['output']>;\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type ContributorResult = {\n __typename?: 'ContributorResult';\n email: Scalars['String']['output'];\n isOwner: Scalars['Boolean']['output'];\n isPending: Scalars['Boolean']['output'];\n};\n\nexport type DeleteAppStatusResult = {\n __typename?: 'DeleteAppStatusResult';\n isNotCreator?: Maybe<Scalars['Boolean']['output']>;\n isNotOwner?: Maybe<Scalars['Boolean']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnableFrontendResult = {\n __typename?: 'EnableFrontendResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnvironmentPatchResult = {\n __typename?: 'EnvironmentPatchResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnvironmentPublishResult = {\n __typename?: 'EnvironmentPublishResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnvironmentSubscriptionResult = {\n __typename?: 'EnvironmentSubscriptionResult';\n patches: Array<Scalars['JSON']['output']>;\n};\n\nexport type EnvironmentTreeClientId = {\n clientType: Scalars['String']['input'];\n id: Scalars['String']['input'];\n};\n\nexport type FileSyncChangedEvent = {\n __typename?: 'FileSyncChangedEvent';\n content: Scalars['String']['output'];\n encoding: FileSyncEncoding;\n mode: Scalars['Float']['output'];\n path: Scalars['String']['output'];\n};\n\nexport type FileSyncChangedEventInput = {\n content: Scalars['String']['input'];\n encoding?: InputMaybe<FileSyncEncoding>;\n mode: Scalars['Float']['input'];\n oldPath?: InputMaybe<Scalars['String']['input']>;\n path: Scalars['String']['input'];\n};\n\nexport type FileSyncComparisonHashes = {\n __typename?: 'FileSyncComparisonHashes';\n filesVersionHashes: FileSyncHashes;\n latestFilesVersionHashes: FileSyncHashes;\n};\n\nexport type FileSyncDeletedEvent = {\n __typename?: 'FileSyncDeletedEvent';\n path: Scalars['String']['output'];\n};\n\nexport type FileSyncDeletedEventInput = {\n path: Scalars['String']['input'];\n};\n\nexport enum FileSyncEncoding {\n Base64 = 'base64',\n Utf8 = 'utf8'\n}\n\nexport type FileSyncFile = {\n __typename?: 'FileSyncFile';\n content: Scalars['String']['output'];\n encoding: FileSyncEncoding;\n mode: Scalars['Float']['output'];\n path: Scalars['String']['output'];\n};\n\nexport type FileSyncFiles = {\n __typename?: 'FileSyncFiles';\n files: Array<FileSyncFile>;\n filesVersion: Scalars['String']['output'];\n};\n\nexport type FileSyncHashes = {\n __typename?: 'FileSyncHashes';\n filesVersion: Scalars['String']['output'];\n hashes: Scalars['JSON']['output'];\n};\n\nexport type GadgetRole = {\n __typename?: 'GadgetRole';\n key: Scalars['String']['output'];\n name: Scalars['String']['output'];\n order: Scalars['Int']['output'];\n selectable: Scalars['Boolean']['output'];\n};\n\nexport type IdentifySupportConversationResult = {\n __typename?: 'IdentifySupportConversationResult';\n identificationEmail: Scalars['String']['output'];\n identificationToken: Scalars['String']['output'];\n};\n\nexport type LogSearchResult = {\n __typename?: 'LogSearchResult';\n data: Scalars['JSON']['output'];\n status: Scalars['String']['output'];\n};\n\nexport type MigrateAacResult = {\n __typename?: 'MigrateAACResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type MigrateEnvironmentsResult = {\n __typename?: 'MigrateEnvironmentsResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type Mutation = {\n __typename?: 'Mutation';\n addApplicationTag?: Maybe<AddApplicationTagResult>;\n addUserTag?: Maybe<AddUserTagResult>;\n changeAppDomain?: Maybe<ChangeAppDomainResult>;\n convergePackages: Scalars['Boolean']['output'];\n deleteApp?: Maybe<DeleteAppStatusResult>;\n enableFrontend?: Maybe<EnableFrontendResult>;\n migrateAAC?: Maybe<MigrateAacResult>;\n migrateEnvironments?: Maybe<MigrateEnvironmentsResult>;\n patchEnvironmentTree?: Maybe<EnvironmentPatchResult>;\n publish?: Maybe<EnvironmentPublishResult>;\n publishFileSyncEvents: PublishFileSyncEventsResult;\n refreshScopes?: Maybe<RefreshScopesResult>;\n registerWebhooks?: Maybe<RegisterWebhooksResult>;\n /** @deprecated use team */\n removeContributor?: Maybe<RemoveContributorResult>;\n /** @deprecated app invitations are no longer supported */\n sendAppInvitation?: Maybe<SendAppInvitationResult>;\n setClientCurrentPath: EnvironmentPatchResult;\n setFrameworkVersion: SetFrameworkVersionResult;\n syncToWebflow: Scalars['Boolean']['output'];\n uninstallShop?: Maybe<UninstallShopResult>;\n unregisterWebhooks?: Maybe<UnregisterWebhooksResult>;\n uploadFiles: UploadFilesResult;\n uploadTemplateAsset: UploadTemplateAssetResult;\n};\n\n\nexport type MutationAddApplicationTagArgs = {\n tag: Scalars['String']['input'];\n};\n\n\nexport type MutationAddUserTagArgs = {\n replaceMatches?: InputMaybe<Array<Scalars['String']['input']>>;\n tag: Scalars['String']['input'];\n};\n\n\nexport type MutationChangeAppDomainArgs = {\n newSubdomain: Scalars['String']['input'];\n onlyValidate?: InputMaybe<Scalars['Boolean']['input']>;\n};\n\n\nexport type MutationDeleteAppArgs = {\n onlyProduction?: InputMaybe<Scalars['Boolean']['input']>;\n};\n\n\nexport type MutationEnableFrontendArgs = {\n hasShopifyConnection: Scalars['Boolean']['input'];\n};\n\n\nexport type MutationMigrateEnvironmentsArgs = {\n existingToProduction: Scalars['Boolean']['input'];\n};\n\n\nexport type MutationPatchEnvironmentTreeArgs = {\n clientID: EnvironmentTreeClientId;\n patches: Array<Scalars['JSON']['input']>;\n};\n\n\nexport type MutationPublishFileSyncEventsArgs = {\n input: PublishFileSyncEventsInput;\n};\n\n\nexport type MutationRefreshScopesArgs = {\n appConfigKey: Scalars['String']['input'];\n connectionKey: Scalars['String']['input'];\n shopId: Scalars['String']['input'];\n};\n\n\nexport type MutationRegisterWebhooksArgs = {\n connectionKey: Scalars['String']['input'];\n keepExtraTopics?: InputMaybe<Scalars['Boolean']['input']>;\n modelKeys?: InputMaybe<Array<Scalars['String']['input']>>;\n shopIds: Array<Scalars['String']['input']>;\n};\n\n\nexport type MutationRemoveContributorArgs = {\n email: Scalars['String']['input'];\n isInvitation: Scalars['Boolean']['input'];\n};\n\n\nexport type MutationSendAppInvitationArgs = {\n email?: InputMaybe<Scalars['String']['input']>;\n emails?: InputMaybe<Array<Scalars['String']['input']>>;\n resend?: InputMaybe<Scalars['Boolean']['input']>;\n};\n\n\nexport type MutationSetClientCurrentPathArgs = {\n clientID: EnvironmentTreeClientId;\n currentPath: Scalars['String']['input'];\n};\n\n\nexport type MutationSetFrameworkVersionArgs = {\n constraint: Scalars['String']['input'];\n};\n\n\nexport type MutationUninstallShopArgs = {\n shopId: Scalars['String']['input'];\n};\n\n\nexport type MutationUnregisterWebhooksArgs = {\n apiKeys?: InputMaybe<Array<Scalars['String']['input']>>;\n connectionKey: Scalars['String']['input'];\n modelKeys?: InputMaybe<Array<Scalars['String']['input']>>;\n};\n\n\nexport type MutationUploadFilesArgs = {\n files: Array<UploadFile>;\n};\n\n\nexport type MutationUploadTemplateAssetArgs = {\n file: Scalars['Upload']['input'];\n};\n\nexport type PublishFileSyncEventsInput = {\n changed: Array<FileSyncChangedEventInput>;\n deleted: Array<FileSyncDeletedEventInput>;\n expectedRemoteFilesVersion: Scalars['String']['input'];\n};\n\nexport type PublishFileSyncEventsResult = {\n __typename?: 'PublishFileSyncEventsResult';\n remoteFilesVersion: Scalars['String']['output'];\n};\n\nexport type PublishIssue = {\n __typename?: 'PublishIssue';\n message: Scalars['String']['output'];\n node?: Maybe<PublishIssueNode>;\n severity: Scalars['String']['output'];\n};\n\nexport type PublishIssueNode = {\n __typename?: 'PublishIssueNode';\n fieldType?: Maybe<Scalars['String']['output']>;\n key: Scalars['String']['output'];\n name?: Maybe<Scalars['String']['output']>;\n parentApiIdentifier?: Maybe<Scalars['String']['output']>;\n parentKey?: Maybe<Scalars['String']['output']>;\n type: Scalars['String']['output'];\n};\n\nexport type PublishStatusState = {\n __typename?: 'PublishStatusState';\n issues: Array<PublishIssue>;\n progress: Scalars['String']['output'];\n remoteFilesVersion: Scalars['String']['output'];\n};\n\nexport type Query = {\n __typename?: 'Query';\n apiUpgradeConvergePlan?: Maybe<ApiUpgradeConvergePlanResult>;\n currentUser: User;\n environmentTreeChildKeys: Array<Scalars['String']['output']>;\n environmentTreePath?: Maybe<Scalars['JSON']['output']>;\n fileSyncComparisonHashes: FileSyncComparisonHashes;\n fileSyncFiles: FileSyncFiles;\n fileSyncHashes: FileSyncHashes;\n identifySupportConversation?: Maybe<IdentifySupportConversationResult>;\n /** @deprecated use team */\n listContributors: Array<ContributorResult>;\n logsSearch: LogSearchResult;\n remoteFilesVersion: Scalars['String']['output'];\n roles: Array<GadgetRole>;\n runTestSupportFunction?: Maybe<Scalars['JSON']['output']>;\n team: TeamResult;\n typesManifest: TypesManifest;\n};\n\n\nexport type QueryApiUpgradeConvergePlanArgs = {\n currentVersion: Scalars['String']['input'];\n targetVersion: Scalars['String']['input'];\n};\n\n\nexport type QueryEnvironmentTreeChildKeysArgs = {\n path: Scalars['String']['input'];\n};\n\n\nexport type QueryEnvironmentTreePathArgs = {\n hydrateChildrenGlobs?: InputMaybe<Array<Scalars['String']['input']>>;\n path: Scalars['String']['input'];\n};\n\n\nexport type QueryFileSyncComparisonHashesArgs = {\n filesVersion: Scalars['String']['input'];\n};\n\n\nexport type QueryFileSyncFilesArgs = {\n encoding?: InputMaybe<FileSyncEncoding>;\n filesVersion?: InputMaybe<Scalars['String']['input']>;\n paths: Array<Scalars['String']['input']>;\n};\n\n\nexport type QueryFileSyncHashesArgs = {\n filesVersion?: InputMaybe<Scalars['String']['input']>;\n};\n\n\nexport type QueryLogsSearchArgs = {\n direction?: InputMaybe<Scalars['String']['input']>;\n end?: InputMaybe<Scalars['DateTime']['input']>;\n limit?: InputMaybe<Scalars['Int']['input']>;\n query: Scalars['String']['input'];\n start?: InputMaybe<Scalars['DateTime']['input']>;\n step?: InputMaybe<Scalars['Int']['input']>;\n};\n\n\nexport type QueryTypesManifestArgs = {\n dependenciesHash: Scalars['String']['input'];\n environmentStatus?: InputMaybe<Scalars['String']['input']>;\n};\n\nexport type RefreshScopesResult = {\n __typename?: 'RefreshScopesResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type RegisterWebhooksResult = {\n __typename?: 'RegisterWebhooksResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type RemoteFileSyncEvents = {\n __typename?: 'RemoteFileSyncEvents';\n changed: Array<FileSyncChangedEvent>;\n deleted: Array<FileSyncDeletedEvent>;\n remoteFilesVersion: Scalars['String']['output'];\n};\n\nexport type RemoveContributorResult = {\n __typename?: 'RemoveContributorResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type SendAppInvitationResult = {\n __typename?: 'SendAppInvitationResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type SetFrameworkVersionResult = {\n __typename?: 'SetFrameworkVersionResult';\n installDependenciesOperationKey?: Maybe<Scalars['String']['output']>;\n};\n\nexport type Subscription = {\n __typename?: 'Subscription';\n environmentTreePathPatches?: Maybe<EnvironmentSubscriptionResult>;\n logsSearch: LogSearchResult;\n publishStatus?: Maybe<PublishStatusState>;\n remoteFileSyncEvents: RemoteFileSyncEvents;\n reportClientPresence?: Maybe<Scalars['Boolean']['output']>;\n typesManifestStream: TypesManifest;\n};\n\n\nexport type SubscriptionEnvironmentTreePathPatchesArgs = {\n clientID: EnvironmentTreeClientId;\n path: Scalars['String']['input'];\n};\n\n\nexport type SubscriptionLogsSearchArgs = {\n limit?: InputMaybe<Scalars['Int']['input']>;\n query: Scalars['String']['input'];\n start?: InputMaybe<Scalars['DateTime']['input']>;\n};\n\n\nexport type SubscriptionPublishStatusArgs = {\n force?: InputMaybe<Scalars['Boolean']['input']>;\n localFilesVersion: Scalars['String']['input'];\n};\n\n\nexport type SubscriptionRemoteFileSyncEventsArgs = {\n encoding?: InputMaybe<FileSyncEncoding>;\n localFilesVersion: Scalars['String']['input'];\n};\n\n\nexport type SubscriptionReportClientPresenceArgs = {\n clientID: EnvironmentTreeClientId;\n};\n\nexport type TeamEntitlements = {\n __typename?: 'TeamEntitlements';\n openAICredits?: Maybe<Scalars['Boolean']['output']>;\n};\n\nexport type TeamMember = {\n __typename?: 'TeamMember';\n contributesToApp: Scalars['Boolean']['output'];\n email: Scalars['String']['output'];\n};\n\nexport type TeamResult = {\n __typename?: 'TeamResult';\n availableSeats?: Maybe<Scalars['Int']['output']>;\n canPublish: Scalars['Boolean']['output'];\n costPerApplication?: Maybe<Scalars['String']['output']>;\n costPerSeat?: Maybe<Scalars['String']['output']>;\n includedApplications?: Maybe<Scalars['Int']['output']>;\n includedApplicationsRemaining?: Maybe<Scalars['Int']['output']>;\n maxApplications?: Maybe<Scalars['Int']['output']>;\n teamEntitlements: TeamEntitlements;\n teamMembers: Array<TeamMember>;\n};\n\nexport type TypeManifestEntry = {\n __typename?: 'TypeManifestEntry';\n declaration: Scalars['String']['output'];\n path: Scalars['String']['output'];\n};\n\nexport type TypesManifest = {\n __typename?: 'TypesManifest';\n cdn: Array<Scalars['String']['output']>;\n dependenciesHash: Scalars['String']['output'];\n entries: Array<TypeManifestEntry>;\n environmentVersion: Scalars['Int']['output'];\n};\n\nexport type UninstallShopResult = {\n __typename?: 'UninstallShopResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type UnregisterWebhooksResult = {\n __typename?: 'UnregisterWebhooksResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type UploadFile = {\n file: Scalars['Upload']['input'];\n path: Scalars['String']['input'];\n};\n\nexport type UploadFilesResult = {\n __typename?: 'UploadFilesResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type UploadTemplateAssetResult = {\n __typename?: 'UploadTemplateAssetResult';\n success: Scalars['Boolean']['output'];\n url?: Maybe<Scalars['String']['output']>;\n};\n\nexport type User = {\n __typename?: 'User';\n email: Scalars['String']['output'];\n name?: Maybe<Scalars['String']['output']>;\n};\n\nexport type RemoteFileSyncEventsSubscriptionVariables = Exact<{\n localFilesVersion: Scalars['String']['input'];\n}>;\n\n\nexport type RemoteFileSyncEventsSubscription = { __typename?: 'Subscription', remoteFileSyncEvents: { __typename?: 'RemoteFileSyncEvents', remoteFilesVersion: string, changed: Array<{ __typename?: 'FileSyncChangedEvent', path: string, mode: number, content: string, encoding: FileSyncEncoding }>, deleted: Array<{ __typename?: 'FileSyncDeletedEvent', path: string }> } };\n\nexport type RemoteFilesVersionQueryVariables = Exact<{ [key: string]: never; }>;\n\n\nexport type RemoteFilesVersionQuery = { __typename?: 'Query', remoteFilesVersion: string };\n\nexport type PublishFileSyncEventsMutationVariables = Exact<{\n input: PublishFileSyncEventsInput;\n}>;\n\n\nexport type PublishFileSyncEventsMutation = { __typename?: 'Mutation', publishFileSyncEvents: { __typename?: 'PublishFileSyncEventsResult', remoteFilesVersion: string } };\n\nexport type FileSyncFilesQueryVariables = Exact<{\n paths: Array<Scalars['String']['input']> | Scalars['String']['input'];\n filesVersion?: InputMaybe<Scalars['String']['input']>;\n encoding?: InputMaybe<FileSyncEncoding>;\n}>;\n\n\nexport type FileSyncFilesQuery = { __typename?: 'Query', fileSyncFiles: { __typename?: 'FileSyncFiles', filesVersion: string, files: Array<{ __typename?: 'FileSyncFile', path: string, mode: number, content: string, encoding: FileSyncEncoding }> } };\n\nexport type FileSyncHashesQueryVariables = Exact<{\n filesVersion?: InputMaybe<Scalars['String']['input']>;\n}>;\n\n\nexport type FileSyncHashesQuery = { __typename?: 'Query', fileSyncHashes: { __typename?: 'FileSyncHashes', filesVersion: string, hashes: { [key: string]: any } } };\n\nexport type FileSyncComparisonHashesQueryVariables = Exact<{\n filesVersion: Scalars['String']['input'];\n}>;\n\n\nexport type FileSyncComparisonHashesQuery = { __typename?: 'Query', fileSyncComparisonHashes: { __typename?: 'FileSyncComparisonHashes', filesVersionHashes: { __typename?: 'FileSyncHashes', filesVersion: string, hashes: { [key: string]: any } }, latestFilesVersionHashes: { __typename?: 'FileSyncHashes', filesVersion: string, hashes: { [key: string]: any } } } };\n\nexport type PublishStatusSubscriptionVariables = Exact<{\n localFilesVersion: Scalars['String']['input'];\n force?: InputMaybe<Scalars['Boolean']['input']>;\n}>;\n\n\nexport type PublishStatusSubscription = { __typename?: 'Subscription', publishStatus?: { __typename?: 'PublishStatusState', remoteFilesVersion: string, progress: string, issues: Array<{ __typename?: 'PublishIssue', severity: string, message: string, node?: { __typename?: 'PublishIssueNode', type: string, key: string, name?: string | null, fieldType?: string | null, parentKey?: string | null, parentApiIdentifier?: string | null } | null }> } | null };\n"],"names":["FileSyncEncoding"],"mappings":"AAAA;;;;;;CAMC;UAyHWA;;;GAAAA,qBAAAA"}
|
|
1
|
+
{"version":3,"sources":["../../src/__generated__/graphql.ts"],"sourcesContent":["/**\n * ======================================================\n * THIS IS A GENERATED FILE! DO NOT EDIT IT MANUALLY!\n *\n * You can regenerate it by running `npm run generate-graphql`.\n * ======================================================\n */\n\nexport type Maybe<T> = T | null;\nexport type InputMaybe<T> = Maybe<T>;\nexport type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };\nexport type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };\nexport type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };\nexport type MakeEmpty<T extends { [key: string]: unknown }, K extends keyof T> = { [_ in K]?: never };\nexport type Incremental<T> = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };\n/** All built-in and custom scalars, mapped to their actual values */\nexport type Scalars = {\n ID: { input: string; output: string; }\n String: { input: string; output: string; }\n Boolean: { input: boolean; output: boolean; }\n Int: { input: number; output: number; }\n Float: { input: number; output: number; }\n /** A date string, such as 2007-12-03, compliant with the `full-date` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. */\n Date: { input: any; output: any; }\n /** A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. */\n DateTime: { input: any; output: any; }\n JSON: { input: { [key: string]: any }; output: { [key: string]: any }; }\n /** The `Upload` scalar type represents a file upload. */\n Upload: { input: any; output: any; }\n};\n\nexport type ApiUpgradeConvergePlanResult = {\n __typename?: 'APIUpgradeConvergePlanResult';\n items: Array<Scalars['JSON']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type AddApplicationTagResult = {\n __typename?: 'AddApplicationTagResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type AddUserTagResult = {\n __typename?: 'AddUserTagResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type ChangeAppDomainResult = {\n __typename?: 'ChangeAppDomainResult';\n onlyValidate?: Maybe<Scalars['Boolean']['output']>;\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type ContributorResult = {\n __typename?: 'ContributorResult';\n email: Scalars['String']['output'];\n isOwner: Scalars['Boolean']['output'];\n isPending: Scalars['Boolean']['output'];\n};\n\nexport type DeleteAppStatusResult = {\n __typename?: 'DeleteAppStatusResult';\n isNotCreator?: Maybe<Scalars['Boolean']['output']>;\n isNotOwner?: Maybe<Scalars['Boolean']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnableFrontendResult = {\n __typename?: 'EnableFrontendResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnvironmentPatchResult = {\n __typename?: 'EnvironmentPatchResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnvironmentPublishResult = {\n __typename?: 'EnvironmentPublishResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type EnvironmentSubscriptionResult = {\n __typename?: 'EnvironmentSubscriptionResult';\n patches: Array<Scalars['JSON']['output']>;\n};\n\nexport type EnvironmentTreeClientId = {\n clientType: Scalars['String']['input'];\n id: Scalars['String']['input'];\n};\n\nexport type FileSyncChangedEvent = {\n __typename?: 'FileSyncChangedEvent';\n content: Scalars['String']['output'];\n encoding: FileSyncEncoding;\n mode: Scalars['Float']['output'];\n path: Scalars['String']['output'];\n};\n\nexport type FileSyncChangedEventInput = {\n content: Scalars['String']['input'];\n encoding?: InputMaybe<FileSyncEncoding>;\n mode: Scalars['Float']['input'];\n oldPath?: InputMaybe<Scalars['String']['input']>;\n path: Scalars['String']['input'];\n};\n\nexport type FileSyncComparisonHashes = {\n __typename?: 'FileSyncComparisonHashes';\n filesVersionHashes: FileSyncHashes;\n latestFilesVersionHashes: FileSyncHashes;\n};\n\nexport type FileSyncDeletedEvent = {\n __typename?: 'FileSyncDeletedEvent';\n path: Scalars['String']['output'];\n};\n\nexport type FileSyncDeletedEventInput = {\n path: Scalars['String']['input'];\n};\n\nexport enum FileSyncEncoding {\n Base64 = 'base64',\n Utf8 = 'utf8'\n}\n\nexport type FileSyncFile = {\n __typename?: 'FileSyncFile';\n content: Scalars['String']['output'];\n encoding: FileSyncEncoding;\n mode: Scalars['Float']['output'];\n path: Scalars['String']['output'];\n};\n\nexport type FileSyncFiles = {\n __typename?: 'FileSyncFiles';\n files: Array<FileSyncFile>;\n filesVersion: Scalars['String']['output'];\n};\n\nexport type FileSyncHashes = {\n __typename?: 'FileSyncHashes';\n filesVersion: Scalars['String']['output'];\n hashes: Scalars['JSON']['output'];\n};\n\nexport type GadgetRole = {\n __typename?: 'GadgetRole';\n key: Scalars['String']['output'];\n name: Scalars['String']['output'];\n order: Scalars['Int']['output'];\n selectable: Scalars['Boolean']['output'];\n};\n\nexport type IdentifySupportConversationResult = {\n __typename?: 'IdentifySupportConversationResult';\n identificationEmail: Scalars['String']['output'];\n identificationToken: Scalars['String']['output'];\n};\n\nexport type LogSearchResult = {\n __typename?: 'LogSearchResult';\n data: Scalars['JSON']['output'];\n status: Scalars['String']['output'];\n};\n\nexport type MigrateAacResult = {\n __typename?: 'MigrateAACResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type MigrateEnvironmentsResult = {\n __typename?: 'MigrateEnvironmentsResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type Mutation = {\n __typename?: 'Mutation';\n addApplicationTag?: Maybe<AddApplicationTagResult>;\n addUserTag?: Maybe<AddUserTagResult>;\n changeAppDomain?: Maybe<ChangeAppDomainResult>;\n convergePackages: Scalars['Boolean']['output'];\n deleteApp?: Maybe<DeleteAppStatusResult>;\n enableFrontend?: Maybe<EnableFrontendResult>;\n migrateAAC?: Maybe<MigrateAacResult>;\n migrateEnvironments?: Maybe<MigrateEnvironmentsResult>;\n patchEnvironmentTree?: Maybe<EnvironmentPatchResult>;\n publish?: Maybe<EnvironmentPublishResult>;\n publishFileSyncEvents: PublishFileSyncEventsResult;\n refreshScopes?: Maybe<RefreshScopesResult>;\n registerWebhooks?: Maybe<RegisterWebhooksResult>;\n /** @deprecated use team */\n removeContributor?: Maybe<RemoveContributorResult>;\n /** @deprecated app invitations are no longer supported */\n sendAppInvitation?: Maybe<SendAppInvitationResult>;\n setClientCurrentPath: EnvironmentPatchResult;\n setFrameworkVersion: SetFrameworkVersionResult;\n syncToWebflow: Scalars['Boolean']['output'];\n uninstallShop?: Maybe<UninstallShopResult>;\n unregisterWebhooks?: Maybe<UnregisterWebhooksResult>;\n uploadFiles: UploadFilesResult;\n uploadTemplateAsset: UploadTemplateAssetResult;\n};\n\n\nexport type MutationAddApplicationTagArgs = {\n tag: Scalars['String']['input'];\n};\n\n\nexport type MutationAddUserTagArgs = {\n replaceMatches?: InputMaybe<Array<Scalars['String']['input']>>;\n tag: Scalars['String']['input'];\n};\n\n\nexport type MutationChangeAppDomainArgs = {\n newSubdomain: Scalars['String']['input'];\n onlyValidate?: InputMaybe<Scalars['Boolean']['input']>;\n};\n\n\nexport type MutationDeleteAppArgs = {\n onlyProduction?: InputMaybe<Scalars['Boolean']['input']>;\n};\n\n\nexport type MutationEnableFrontendArgs = {\n hasShopifyConnection: Scalars['Boolean']['input'];\n};\n\n\nexport type MutationMigrateEnvironmentsArgs = {\n existingToProduction: Scalars['Boolean']['input'];\n};\n\n\nexport type MutationPatchEnvironmentTreeArgs = {\n clientID: EnvironmentTreeClientId;\n patches: Array<Scalars['JSON']['input']>;\n};\n\n\nexport type MutationPublishFileSyncEventsArgs = {\n input: PublishFileSyncEventsInput;\n};\n\n\nexport type MutationRefreshScopesArgs = {\n appConfigKey: Scalars['String']['input'];\n connectionKey: Scalars['String']['input'];\n shopId: Scalars['String']['input'];\n};\n\n\nexport type MutationRegisterWebhooksArgs = {\n connectionKey: Scalars['String']['input'];\n keepExtraTopics?: InputMaybe<Scalars['Boolean']['input']>;\n modelKeys?: InputMaybe<Array<Scalars['String']['input']>>;\n shopIds: Array<Scalars['String']['input']>;\n};\n\n\nexport type MutationRemoveContributorArgs = {\n email: Scalars['String']['input'];\n isInvitation: Scalars['Boolean']['input'];\n};\n\n\nexport type MutationSendAppInvitationArgs = {\n email?: InputMaybe<Scalars['String']['input']>;\n emails?: InputMaybe<Array<Scalars['String']['input']>>;\n resend?: InputMaybe<Scalars['Boolean']['input']>;\n};\n\n\nexport type MutationSetClientCurrentPathArgs = {\n clientID: EnvironmentTreeClientId;\n currentPath: Scalars['String']['input'];\n};\n\n\nexport type MutationSetFrameworkVersionArgs = {\n constraint: Scalars['String']['input'];\n};\n\n\nexport type MutationUninstallShopArgs = {\n shopId: Scalars['String']['input'];\n};\n\n\nexport type MutationUnregisterWebhooksArgs = {\n apiKeys?: InputMaybe<Array<Scalars['String']['input']>>;\n connectionKey: Scalars['String']['input'];\n modelKeys?: InputMaybe<Array<Scalars['String']['input']>>;\n};\n\n\nexport type MutationUploadFilesArgs = {\n files: Array<UploadFile>;\n};\n\n\nexport type MutationUploadTemplateAssetArgs = {\n file: Scalars['Upload']['input'];\n};\n\nexport type PublishFileSyncEventsInput = {\n changed: Array<FileSyncChangedEventInput>;\n deleted: Array<FileSyncDeletedEventInput>;\n expectedRemoteFilesVersion: Scalars['String']['input'];\n};\n\nexport type PublishFileSyncEventsResult = {\n __typename?: 'PublishFileSyncEventsResult';\n remoteFilesVersion: Scalars['String']['output'];\n};\n\nexport type PublishIssue = {\n __typename?: 'PublishIssue';\n message: Scalars['String']['output'];\n node?: Maybe<PublishIssueNode>;\n severity: Scalars['String']['output'];\n};\n\nexport type PublishIssueNode = {\n __typename?: 'PublishIssueNode';\n apiIdentifier?: Maybe<Scalars['String']['output']>;\n fieldType?: Maybe<Scalars['String']['output']>;\n key: Scalars['String']['output'];\n name?: Maybe<Scalars['String']['output']>;\n parentApiIdentifier?: Maybe<Scalars['String']['output']>;\n parentKey?: Maybe<Scalars['String']['output']>;\n type: Scalars['String']['output'];\n};\n\nexport type PublishStatusState = {\n __typename?: 'PublishStatusState';\n issues: Array<PublishIssue>;\n progress: Scalars['String']['output'];\n remoteFilesVersion: Scalars['String']['output'];\n};\n\nexport type Query = {\n __typename?: 'Query';\n apiUpgradeConvergePlan?: Maybe<ApiUpgradeConvergePlanResult>;\n currentUser: User;\n environmentTreeChildKeys: Array<Scalars['String']['output']>;\n environmentTreePath?: Maybe<Scalars['JSON']['output']>;\n fileSyncComparisonHashes: FileSyncComparisonHashes;\n fileSyncFiles: FileSyncFiles;\n fileSyncHashes: FileSyncHashes;\n identifySupportConversation?: Maybe<IdentifySupportConversationResult>;\n /** @deprecated use team */\n listContributors: Array<ContributorResult>;\n logsSearch: LogSearchResult;\n publishIssues: Array<PublishIssue>;\n remoteFilesVersion: Scalars['String']['output'];\n roles: Array<GadgetRole>;\n runTestSupportFunction?: Maybe<Scalars['JSON']['output']>;\n team: TeamResult;\n typesManifest: TypesManifest;\n};\n\n\nexport type QueryApiUpgradeConvergePlanArgs = {\n currentVersion: Scalars['String']['input'];\n targetVersion: Scalars['String']['input'];\n};\n\n\nexport type QueryEnvironmentTreeChildKeysArgs = {\n path: Scalars['String']['input'];\n};\n\n\nexport type QueryEnvironmentTreePathArgs = {\n hydrateChildrenGlobs?: InputMaybe<Array<Scalars['String']['input']>>;\n path: Scalars['String']['input'];\n};\n\n\nexport type QueryFileSyncComparisonHashesArgs = {\n filesVersion: Scalars['String']['input'];\n};\n\n\nexport type QueryFileSyncFilesArgs = {\n encoding?: InputMaybe<FileSyncEncoding>;\n filesVersion?: InputMaybe<Scalars['String']['input']>;\n paths: Array<Scalars['String']['input']>;\n};\n\n\nexport type QueryFileSyncHashesArgs = {\n filesVersion?: InputMaybe<Scalars['String']['input']>;\n};\n\n\nexport type QueryLogsSearchArgs = {\n direction?: InputMaybe<Scalars['String']['input']>;\n end?: InputMaybe<Scalars['DateTime']['input']>;\n limit?: InputMaybe<Scalars['Int']['input']>;\n query: Scalars['String']['input'];\n start?: InputMaybe<Scalars['DateTime']['input']>;\n step?: InputMaybe<Scalars['Int']['input']>;\n};\n\n\nexport type QueryTypesManifestArgs = {\n dependenciesHash: Scalars['String']['input'];\n environmentStatus?: InputMaybe<Scalars['String']['input']>;\n};\n\nexport type RefreshScopesResult = {\n __typename?: 'RefreshScopesResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type RegisterWebhooksResult = {\n __typename?: 'RegisterWebhooksResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type RemoteFileSyncEvents = {\n __typename?: 'RemoteFileSyncEvents';\n changed: Array<FileSyncChangedEvent>;\n deleted: Array<FileSyncDeletedEvent>;\n remoteFilesVersion: Scalars['String']['output'];\n};\n\nexport type RemoveContributorResult = {\n __typename?: 'RemoveContributorResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type SendAppInvitationResult = {\n __typename?: 'SendAppInvitationResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type SetFrameworkVersionResult = {\n __typename?: 'SetFrameworkVersionResult';\n installDependenciesOperationKey?: Maybe<Scalars['String']['output']>;\n};\n\nexport type Subscription = {\n __typename?: 'Subscription';\n environmentTreePathPatches?: Maybe<EnvironmentSubscriptionResult>;\n logsSearch: LogSearchResult;\n publishStatus?: Maybe<PublishStatusState>;\n remoteFileSyncEvents: RemoteFileSyncEvents;\n reportClientPresence?: Maybe<Scalars['Boolean']['output']>;\n typesManifestStream: TypesManifest;\n};\n\n\nexport type SubscriptionEnvironmentTreePathPatchesArgs = {\n clientID: EnvironmentTreeClientId;\n path: Scalars['String']['input'];\n};\n\n\nexport type SubscriptionLogsSearchArgs = {\n limit?: InputMaybe<Scalars['Int']['input']>;\n query: Scalars['String']['input'];\n start?: InputMaybe<Scalars['DateTime']['input']>;\n};\n\n\nexport type SubscriptionPublishStatusArgs = {\n force?: InputMaybe<Scalars['Boolean']['input']>;\n localFilesVersion: Scalars['String']['input'];\n};\n\n\nexport type SubscriptionRemoteFileSyncEventsArgs = {\n encoding?: InputMaybe<FileSyncEncoding>;\n localFilesVersion: Scalars['String']['input'];\n};\n\n\nexport type SubscriptionReportClientPresenceArgs = {\n clientID: EnvironmentTreeClientId;\n};\n\nexport type TeamEntitlements = {\n __typename?: 'TeamEntitlements';\n openAICredits?: Maybe<Scalars['Boolean']['output']>;\n};\n\nexport type TeamMember = {\n __typename?: 'TeamMember';\n contributesToApp: Scalars['Boolean']['output'];\n email: Scalars['String']['output'];\n};\n\nexport type TeamResult = {\n __typename?: 'TeamResult';\n availableSeats?: Maybe<Scalars['Int']['output']>;\n canPublish: Scalars['Boolean']['output'];\n costPerApplication?: Maybe<Scalars['String']['output']>;\n costPerSeat?: Maybe<Scalars['String']['output']>;\n includedApplications?: Maybe<Scalars['Int']['output']>;\n includedApplicationsRemaining?: Maybe<Scalars['Int']['output']>;\n maxApplications?: Maybe<Scalars['Int']['output']>;\n teamEntitlements: TeamEntitlements;\n teamMembers: Array<TeamMember>;\n};\n\nexport type TypeManifestEntry = {\n __typename?: 'TypeManifestEntry';\n declaration: Scalars['String']['output'];\n path: Scalars['String']['output'];\n};\n\nexport type TypesManifest = {\n __typename?: 'TypesManifest';\n cdn: Array<Scalars['String']['output']>;\n dependenciesHash: Scalars['String']['output'];\n entries: Array<TypeManifestEntry>;\n environmentVersion: Scalars['Int']['output'];\n};\n\nexport type UninstallShopResult = {\n __typename?: 'UninstallShopResult';\n reason?: Maybe<Scalars['String']['output']>;\n success: Scalars['Boolean']['output'];\n};\n\nexport type UnregisterWebhooksResult = {\n __typename?: 'UnregisterWebhooksResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type UploadFile = {\n file: Scalars['Upload']['input'];\n path: Scalars['String']['input'];\n};\n\nexport type UploadFilesResult = {\n __typename?: 'UploadFilesResult';\n success: Scalars['Boolean']['output'];\n};\n\nexport type UploadTemplateAssetResult = {\n __typename?: 'UploadTemplateAssetResult';\n success: Scalars['Boolean']['output'];\n url?: Maybe<Scalars['String']['output']>;\n};\n\nexport type User = {\n __typename?: 'User';\n email: Scalars['String']['output'];\n name?: Maybe<Scalars['String']['output']>;\n};\n\nexport type RemoteFileSyncEventsSubscriptionVariables = Exact<{\n localFilesVersion: Scalars['String']['input'];\n}>;\n\n\nexport type RemoteFileSyncEventsSubscription = { __typename?: 'Subscription', remoteFileSyncEvents: { __typename?: 'RemoteFileSyncEvents', remoteFilesVersion: string, changed: Array<{ __typename?: 'FileSyncChangedEvent', path: string, mode: number, content: string, encoding: FileSyncEncoding }>, deleted: Array<{ __typename?: 'FileSyncDeletedEvent', path: string }> } };\n\nexport type RemoteFilesVersionQueryVariables = Exact<{ [key: string]: never; }>;\n\n\nexport type RemoteFilesVersionQuery = { __typename?: 'Query', remoteFilesVersion: string };\n\nexport type PublishFileSyncEventsMutationVariables = Exact<{\n input: PublishFileSyncEventsInput;\n}>;\n\n\nexport type PublishFileSyncEventsMutation = { __typename?: 'Mutation', publishFileSyncEvents: { __typename?: 'PublishFileSyncEventsResult', remoteFilesVersion: string } };\n\nexport type FileSyncFilesQueryVariables = Exact<{\n paths: Array<Scalars['String']['input']> | Scalars['String']['input'];\n filesVersion?: InputMaybe<Scalars['String']['input']>;\n encoding?: InputMaybe<FileSyncEncoding>;\n}>;\n\n\nexport type FileSyncFilesQuery = { __typename?: 'Query', fileSyncFiles: { __typename?: 'FileSyncFiles', filesVersion: string, files: Array<{ __typename?: 'FileSyncFile', path: string, mode: number, content: string, encoding: FileSyncEncoding }> } };\n\nexport type FileSyncHashesQueryVariables = Exact<{\n filesVersion?: InputMaybe<Scalars['String']['input']>;\n}>;\n\n\nexport type FileSyncHashesQuery = { __typename?: 'Query', fileSyncHashes: { __typename?: 'FileSyncHashes', filesVersion: string, hashes: { [key: string]: any } } };\n\nexport type FileSyncComparisonHashesQueryVariables = Exact<{\n filesVersion: Scalars['String']['input'];\n}>;\n\n\nexport type FileSyncComparisonHashesQuery = { __typename?: 'Query', fileSyncComparisonHashes: { __typename?: 'FileSyncComparisonHashes', filesVersionHashes: { __typename?: 'FileSyncHashes', filesVersion: string, hashes: { [key: string]: any } }, latestFilesVersionHashes: { __typename?: 'FileSyncHashes', filesVersion: string, hashes: { [key: string]: any } } } };\n\nexport type PublishStatusSubscriptionVariables = Exact<{\n localFilesVersion: Scalars['String']['input'];\n force?: InputMaybe<Scalars['Boolean']['input']>;\n}>;\n\n\nexport type PublishStatusSubscription = { __typename?: 'Subscription', publishStatus?: { __typename?: 'PublishStatusState', remoteFilesVersion: string, progress: string, issues: Array<{ __typename?: 'PublishIssue', severity: string, message: string, node?: { __typename?: 'PublishIssueNode', type: string, key: string, apiIdentifier?: string | null, name?: string | null, fieldType?: string | null, parentKey?: string | null, parentApiIdentifier?: string | null } | null }> } | null };\n"],"names":["FileSyncEncoding"],"mappings":"AAAA;;;;;;CAMC;UAyHWA;;;GAAAA,qBAAAA"}
|
package/lib/commands/deploy.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import ora from "ora";
|
|
3
|
-
import { AppArg } from "../services/app/arg.js";
|
|
4
3
|
import { REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION } from "../services/app/edit-graphql.js";
|
|
5
|
-
import { FileSync } from "../services/filesync/filesync.js";
|
|
4
|
+
import { FileSync, FileSyncArgs } from "../services/filesync/filesync.js";
|
|
6
5
|
import { select } from "../services/output/prompt.js";
|
|
7
6
|
import { sprint } from "../services/output/sprint.js";
|
|
8
7
|
import { getUserOrLogin } from "../services/user/user.js";
|
|
@@ -22,20 +21,20 @@ export const usage = ()=>sprint`
|
|
|
22
21
|
|
|
23
22
|
{bold DESCRIPTION}
|
|
24
23
|
Deploy allows you to deploy your current Gadget application in development to production.
|
|
25
|
-
|
|
26
|
-
It detects if local files are up to date with remote and if the Gadget application
|
|
27
|
-
is in a deployable state. If there are any issues, it will display them and ask if
|
|
28
|
-
you would like to deploy anyways.
|
|
29
|
-
|
|
24
|
+
|
|
25
|
+
It detects if local files are up to date with remote and if the Gadget application
|
|
26
|
+
is in a deployable state. If there are any issues, it will display them and ask if
|
|
27
|
+
you would like to deploy anyways.
|
|
28
|
+
|
|
30
29
|
Note:
|
|
31
30
|
• If local files are not up to date or have not recently been synced with remote ones,
|
|
32
|
-
you will be prompted to run a one-time sync to ensure the files remain consistent with
|
|
33
|
-
what is on the remote.
|
|
31
|
+
you will be prompted to run a one-time sync to ensure the files remain consistent with
|
|
32
|
+
what is on the remote.
|
|
34
33
|
• You may wish to keep ggt sync running in the background before trying to run ggt deploy
|
|
35
|
-
|
|
36
|
-
{bold EXAMPLE}
|
|
34
|
+
|
|
35
|
+
{bold EXAMPLE}
|
|
37
36
|
$ ggt deploy ~/gadget/example --app example
|
|
38
|
-
|
|
37
|
+
|
|
39
38
|
App example
|
|
40
39
|
Editor https://example.gadget.app/edit
|
|
41
40
|
Playground https://example.gadget.app/api/graphql/playground
|
|
@@ -44,28 +43,24 @@ export const usage = ()=>sprint`
|
|
|
44
43
|
Endpoints
|
|
45
44
|
• https://example.gadget.app
|
|
46
45
|
• https://example--development.gadget.app
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
|
|
47
|
+
|
|
49
48
|
Building frontend assets ...
|
|
50
49
|
✔ DONE
|
|
51
|
-
|
|
50
|
+
|
|
52
51
|
Setting up database ...
|
|
53
52
|
✔ DONE
|
|
54
|
-
|
|
53
|
+
|
|
55
54
|
Copying development ...
|
|
56
55
|
✔ DONE
|
|
57
|
-
|
|
56
|
+
|
|
58
57
|
Restarting app ...
|
|
59
58
|
✔ DONE
|
|
60
|
-
|
|
59
|
+
|
|
61
60
|
Deploy completed. Good bye!
|
|
62
61
|
`;
|
|
63
62
|
export const args = {
|
|
64
|
-
|
|
65
|
-
type: AppArg,
|
|
66
|
-
alias: "-a"
|
|
67
|
-
},
|
|
68
|
-
"--force": Boolean
|
|
63
|
+
...FileSyncArgs
|
|
69
64
|
};
|
|
70
65
|
export var Action;
|
|
71
66
|
(function(Action) {
|
|
@@ -111,19 +106,22 @@ var AppDeploymentSteps;
|
|
|
111
106
|
let prevProgress = AppDeploymentStepsToAppDeployState("NOT_STARTED");
|
|
112
107
|
let action;
|
|
113
108
|
const filesync = await FileSync.init({
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
109
|
+
// deploy --force != sync --force
|
|
110
|
+
ctx: ctx.clone({
|
|
111
|
+
args: {
|
|
112
|
+
"--force": false
|
|
113
|
+
}
|
|
114
|
+
}),
|
|
115
|
+
user: await getUserOrLogin()
|
|
117
116
|
});
|
|
118
|
-
const log = filesync.log.extend("deploy");
|
|
119
117
|
if (firstRun) {
|
|
120
|
-
log.printlns`App: ${filesync.app.slug}`;
|
|
118
|
+
ctx.log.printlns`App: ${filesync.app.slug}`;
|
|
121
119
|
}
|
|
122
120
|
const { inSync } = await filesync.hashes();
|
|
123
121
|
if (!inSync) {
|
|
124
|
-
log.printlns`
|
|
125
|
-
|
|
126
|
-
|
|
122
|
+
ctx.log.printlns`
|
|
123
|
+
Local files have diverged from remote. Run a sync once to converge your files or keep {italic ggt sync} running in the background.
|
|
124
|
+
`;
|
|
127
125
|
action = await select({
|
|
128
126
|
message: "How would you like to proceed?",
|
|
129
127
|
choices: [
|
|
@@ -153,16 +151,16 @@ var AppDeploymentSteps;
|
|
|
153
151
|
onError: (error)=>{
|
|
154
152
|
if (isCloseEvent(error.cause)) {
|
|
155
153
|
spinner.fail("Failed");
|
|
156
|
-
log.printlns(error.message);
|
|
154
|
+
ctx.log.printlns(error.message);
|
|
157
155
|
} else if (isGraphQLErrors(error.cause)) {
|
|
158
156
|
const message = error.cause[0]?.message;
|
|
159
157
|
if (message && message.includes("GGT_PAYMENT_REQUIRED")) {
|
|
160
|
-
log.println("Production environment limit reached. Upgrade your plan to deploy");
|
|
158
|
+
ctx.log.println("Production environment limit reached. Upgrade your plan to deploy");
|
|
161
159
|
} else {
|
|
162
|
-
log.println(`${message}`);
|
|
160
|
+
ctx.log.println(`${message}`);
|
|
163
161
|
}
|
|
164
162
|
}
|
|
165
|
-
log.error("failed to deploy", {
|
|
163
|
+
ctx.log.error("failed to deploy", {
|
|
166
164
|
error
|
|
167
165
|
});
|
|
168
166
|
unsubscribe();
|
|
@@ -172,14 +170,14 @@ var AppDeploymentSteps;
|
|
|
172
170
|
const { progress, issues } = publishStatus ?? {};
|
|
173
171
|
const hasIssues = issues?.length;
|
|
174
172
|
if (firstRun && hasIssues) {
|
|
175
|
-
log.printlns`{underline Issues detected}`;
|
|
173
|
+
ctx.log.printlns`{underline Issues detected}`;
|
|
176
174
|
for (const issue of issues){
|
|
177
175
|
const message = issue.message.replace(/"/g, "");
|
|
178
176
|
const nodeType = issue.node?.type;
|
|
179
|
-
const nodeName = issue.node?.name;
|
|
177
|
+
const nodeName = issue.node?.apiIdentifier ?? issue.node?.name;
|
|
180
178
|
const nodeParent = issue.node?.parentApiIdentifier;
|
|
181
|
-
log.printlns(`
|
|
182
|
-
• ${message}
|
|
179
|
+
ctx.log.printlns(`
|
|
180
|
+
• ${message}
|
|
183
181
|
${nodeType ? `${nodeType}: ${chalk.cyan(nodeName)}` : ""} ${nodeParent ? `ParentResource: ${chalk.cyan(nodeParent)}` : ""}
|
|
184
182
|
`.trim());
|
|
185
183
|
}
|
|
@@ -209,7 +207,7 @@ var AppDeploymentSteps;
|
|
|
209
207
|
} else {
|
|
210
208
|
if (progress === "COMPLETED") {
|
|
211
209
|
spinner.succeed("DONE");
|
|
212
|
-
log.printlns("Deploy completed. Good bye!");
|
|
210
|
+
ctx.log.printlns("Deploy completed. Good bye!");
|
|
213
211
|
unsubscribe();
|
|
214
212
|
return;
|
|
215
213
|
}
|
|
@@ -219,7 +217,7 @@ var AppDeploymentSteps;
|
|
|
219
217
|
spinner.succeed("DONE");
|
|
220
218
|
}
|
|
221
219
|
prevProgress = currentProgress;
|
|
222
|
-
log.printlns(`${currentProgress} ...`);
|
|
220
|
+
ctx.log.printlns(`${currentProgress} ...`);
|
|
223
221
|
spinner.start("Working ...");
|
|
224
222
|
}
|
|
225
223
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/deploy.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { AppArg } from \"../services/app/arg.js\";\nimport { REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION } from \"../services/app/edit-graphql.js\";\nimport type { ArgsSpec } from \"../services/command/arg.js\";\nimport { type Command, type Usage } from \"../services/command/command.js\";\nimport { FileSync } from \"../services/filesync/filesync.js\";\nimport { select } from \"../services/output/prompt.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { getUserOrLogin } from \"../services/user/user.js\";\nimport { isCloseEvent, isGraphQLErrors } from \"../services/util/is.js\";\n\nexport const usage: Usage = () => sprint`\n Deploy your Gadget application's development source code to production.\n\n {bold USAGE}\n ggt deploy [DIRECTORY] [--app=<name>]\n\n {bold ARGUMENTS}\n DIRECTORY The directory to sync files to and deploy (default: \".\")\n\n {bold FLAGS}\n -a, --app=<name> The Gadget application to deploy\n --force Deploy the Gadget application regardless of any issues it may have\n\n {bold DESCRIPTION}\n Deploy allows you to deploy your current Gadget application in development to production.\n \n It detects if local files are up to date with remote and if the Gadget application \n is in a deployable state. If there are any issues, it will display them and ask if \n you would like to deploy anyways. \n \n Note:\n • If local files are not up to date or have not recently been synced with remote ones,\n you will be prompted to run a one-time sync to ensure the files remain consistent with \n what is on the remote. \n • You may wish to keep ggt sync running in the background before trying to run ggt deploy\n \n {bold EXAMPLE} \n $ ggt deploy ~/gadget/example --app example\n \n App example\n Editor https://example.gadget.app/edit\n Playground https://example.gadget.app/api/graphql/playground\n Docs https://docs.gadget.dev/api/example\n\n Endpoints\n • https://example.gadget.app\n • https://example--development.gadget.app\n \n \n Building frontend assets ...\n ✔ DONE\n \n Setting up database ...\n ✔ DONE\n \n Copying development ...\n ✔ DONE\n \n Restarting app ...\n ✔ DONE\n \n Deploy completed. Good bye!\n`;\n\nexport const args = {\n \"--app\": {\n type: AppArg,\n alias: \"-a\",\n },\n \"--force\": Boolean,\n} satisfies ArgsSpec;\n\nexport enum Action {\n DEPLOY_ANYWAYS = \"Deploy anyways\",\n SYNC_ONCE = \"Sync once\",\n CANCEL = \"Cancel (Ctrl+C)\",\n}\n\nconst AppDeploymentStepsToAppDeployState = (step: string | undefined): string => {\n switch (step) {\n case \"NOT_STARTED\":\n return \"Deploy not started\";\n case \"STARTING\":\n case \"BUILDING_ASSETS\":\n case \"UPLOADING_ASSETS\":\n return \"Building frontend assets\";\n case \"CONVERGING_STORAGE\":\n return \"Setting up database\";\n case \"PUBLISHING_TREE\":\n return \"Copying development\";\n case \"RELOADING_SANDBOX\":\n return \"Restarting app\";\n case \"COMPLETED\":\n return \"Deploy completed\";\n default:\n return \"Unknown step\";\n }\n};\n\nenum AppDeploymentSteps {\n NOT_STARTED = \"NOT_STARTED\",\n STARTING = \"STARTING\",\n BUILDING_ASSETS = \"BUILDING_ASSETS\",\n UPLOADING_ASSETS = \"UPLOADING_ASSETS\",\n CONVERGING_STORAGE = \"CONVERGING_STORAGE\",\n PUBLISHING_TREE = \"PUBLISHING_TREE\",\n RELOADING_SANDBOX = \"RELOADING_SANDBOX\",\n COMPLETED = \"COMPLETED\",\n}\n\n/**\n * Runs the deploy process.\n */\n\nexport const command = (async (ctx, firstRun = true) => {\n const spinner = ora();\n let prevProgress: string | undefined = AppDeploymentStepsToAppDeployState(\"NOT_STARTED\");\n let action: Action;\n\n const filesync = await FileSync.init({\n user: await getUserOrLogin(),\n dir: ctx.args._[0],\n app: ctx.args[\"--app\"],\n });\n\n const log = filesync.log.extend(\"deploy\");\n\n if (firstRun) {\n log.printlns`App: ${filesync.app.slug}`;\n }\n\n const { inSync } = await filesync.hashes();\n if (!inSync) {\n log.printlns`\n Local files have diverged from remote. Run a sync once to converge your files or keep {italic ggt sync} running in the background.\n `;\n\n action = await select({\n message: \"How would you like to proceed?\",\n choices: [Action.CANCEL, Action.SYNC_ONCE],\n });\n\n switch (action) {\n case Action.SYNC_ONCE: {\n await filesync.sync();\n\n break;\n }\n case Action.CANCEL: {\n process.exit(0);\n }\n }\n }\n\n // subscribes to the graphql subscription that will listen and send back the server contract status\n const unsubscribe = filesync.editGraphQL.subscribe({\n query: REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION,\n variables: () => ({ localFilesVersion: String(filesync.filesVersion), force: ctx.args[\"--force\"] }),\n onError: (error) => {\n if (isCloseEvent(error.cause)) {\n spinner.fail(\"Failed\");\n log.printlns(error.message);\n } else if (isGraphQLErrors(error.cause)) {\n const message = error.cause[0]?.message;\n if (message && message.includes(\"GGT_PAYMENT_REQUIRED\")) {\n log.println(\"Production environment limit reached. Upgrade your plan to deploy\");\n } else {\n log.println(`${message}`);\n }\n }\n log.error(\"failed to deploy\", { error });\n unsubscribe();\n return;\n },\n onData: async ({ publishStatus }): Promise<void> => {\n const { progress, issues } = publishStatus ?? {};\n\n const hasIssues = issues?.length;\n\n if (firstRun && hasIssues) {\n log.printlns`{underline Issues detected}`;\n\n for (const issue of issues) {\n const message = issue.message.replace(/\"/g, \"\");\n const nodeType = issue.node?.type;\n const nodeName = issue.node?.name;\n const nodeParent = issue.node?.parentApiIdentifier;\n\n log.printlns(\n `\n • ${message} \n ${nodeType ? `${nodeType}: ${chalk.cyan(nodeName)}` : \"\"} ${\n nodeParent ? `ParentResource: ${chalk.cyan(nodeParent)}` : \"\"\n }\n `.trim(),\n );\n }\n\n if (!ctx.args[\"--force\"]) {\n unsubscribe();\n\n action = await select({\n message: \"Detected some issues with your app. How would you like to proceed?\",\n choices: [Action.CANCEL, Action.DEPLOY_ANYWAYS],\n });\n\n switch (action) {\n case Action.DEPLOY_ANYWAYS: {\n ctx.args[\"--force\"] = true;\n await command(ctx, false);\n break;\n }\n case Action.CANCEL: {\n process.exit(0);\n }\n }\n }\n\n firstRun = false;\n } else {\n if (progress === AppDeploymentSteps.COMPLETED) {\n spinner.succeed(\"DONE\");\n log.printlns(\"Deploy completed. Good bye!\");\n unsubscribe();\n return;\n }\n\n const currentProgress = AppDeploymentStepsToAppDeployState(progress);\n\n if (progress && currentProgress !== prevProgress) {\n if ((progress as AppDeploymentSteps) !== AppDeploymentSteps.STARTING) {\n spinner.succeed(\"DONE\");\n }\n\n prevProgress = currentProgress;\n log.printlns(`${currentProgress} ...`);\n spinner.start(\"Working ...\");\n }\n }\n },\n });\n}) satisfies Command<typeof args>;\n"],"names":["chalk","ora","AppArg","REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION","FileSync","select","sprint","getUserOrLogin","isCloseEvent","isGraphQLErrors","usage","args","type","alias","Boolean","Action","AppDeploymentStepsToAppDeployState","step","AppDeploymentSteps","command","ctx","firstRun","spinner","prevProgress","action","filesync","init","user","dir","_","app","log","extend","printlns","slug","inSync","hashes","message","choices","sync","process","exit","unsubscribe","editGraphQL","subscribe","query","variables","localFilesVersion","String","filesVersion","force","onError","error","cause","fail","includes","println","onData","publishStatus","progress","issues","hasIssues","length","issue","replace","nodeType","node","nodeName","name","nodeParent","parentApiIdentifier","cyan","trim","succeed","currentProgress","start"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/deploy.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION } from \"../services/app/edit-graphql.js\";\nimport type { ArgsSpec } 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 { getUserOrLogin } from \"../services/user/user.js\";\nimport { isCloseEvent, isGraphQLErrors } from \"../services/util/is.js\";\n\nexport const usage: Usage = () => sprint`\n Deploy your Gadget application's development source code to production.\n\n {bold USAGE}\n ggt deploy [DIRECTORY] [--app=<name>]\n\n {bold ARGUMENTS}\n DIRECTORY The directory to sync files to and deploy (default: \".\")\n\n {bold FLAGS}\n -a, --app=<name> The Gadget application to deploy\n --force Deploy the Gadget application regardless of any issues it may have\n\n {bold DESCRIPTION}\n Deploy allows you to deploy your current Gadget application in development to production.\n\n It detects if local files are up to date with remote and if the Gadget application\n is in a deployable state. If there are any issues, it will display them and ask if\n you would like to deploy anyways.\n\n Note:\n • If local files are not up to date or have not recently been synced with remote ones,\n you will be prompted to run a one-time sync to ensure the files remain consistent with\n what is on the remote.\n • You may wish to keep ggt sync running in the background before trying to run ggt deploy\n\n {bold EXAMPLE}\n $ ggt deploy ~/gadget/example --app example\n\n App example\n Editor https://example.gadget.app/edit\n Playground https://example.gadget.app/api/graphql/playground\n Docs https://docs.gadget.dev/api/example\n\n Endpoints\n • https://example.gadget.app\n • https://example--development.gadget.app\n\n\n Building frontend assets ...\n ✔ DONE\n\n Setting up database ...\n ✔ DONE\n\n Copying development ...\n ✔ DONE\n\n Restarting app ...\n ✔ DONE\n\n Deploy completed. Good bye!\n`;\n\nexport const args = {\n ...FileSyncArgs,\n} satisfies ArgsSpec;\n\nexport enum Action {\n DEPLOY_ANYWAYS = \"Deploy anyways\",\n SYNC_ONCE = \"Sync once\",\n CANCEL = \"Cancel (Ctrl+C)\",\n}\n\nconst AppDeploymentStepsToAppDeployState = (step: string | undefined): string => {\n switch (step) {\n case \"NOT_STARTED\":\n return \"Deploy not started\";\n case \"STARTING\":\n case \"BUILDING_ASSETS\":\n case \"UPLOADING_ASSETS\":\n return \"Building frontend assets\";\n case \"CONVERGING_STORAGE\":\n return \"Setting up database\";\n case \"PUBLISHING_TREE\":\n return \"Copying development\";\n case \"RELOADING_SANDBOX\":\n return \"Restarting app\";\n case \"COMPLETED\":\n return \"Deploy completed\";\n default:\n return \"Unknown step\";\n }\n};\n\nenum AppDeploymentSteps {\n NOT_STARTED = \"NOT_STARTED\",\n STARTING = \"STARTING\",\n BUILDING_ASSETS = \"BUILDING_ASSETS\",\n UPLOADING_ASSETS = \"UPLOADING_ASSETS\",\n CONVERGING_STORAGE = \"CONVERGING_STORAGE\",\n PUBLISHING_TREE = \"PUBLISHING_TREE\",\n RELOADING_SANDBOX = \"RELOADING_SANDBOX\",\n COMPLETED = \"COMPLETED\",\n}\n\n/**\n * Runs the deploy process.\n */\n\nexport const command = (async (ctx, firstRun = true) => {\n const spinner = ora();\n let prevProgress: string | undefined = AppDeploymentStepsToAppDeployState(\"NOT_STARTED\");\n let action: Action;\n\n const filesync = await FileSync.init({\n // deploy --force != sync --force\n ctx: ctx.clone({ args: { \"--force\": false } }),\n user: await getUserOrLogin(),\n });\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({\n message: \"How would you like to proceed?\",\n choices: [Action.CANCEL, Action.SYNC_ONCE],\n });\n\n switch (action) {\n case Action.SYNC_ONCE: {\n await filesync.sync();\n\n break;\n }\n case Action.CANCEL: {\n process.exit(0);\n }\n }\n }\n\n // subscribes to the graphql subscription that will listen and send back the server contract status\n const unsubscribe = filesync.editGraphQL.subscribe({\n query: REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION,\n variables: () => ({ localFilesVersion: String(filesync.filesVersion), force: ctx.args[\"--force\"] }),\n onError: (error) => {\n if (isCloseEvent(error.cause)) {\n spinner.fail(\"Failed\");\n 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({\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","getUserOrLogin","isCloseEvent","isGraphQLErrors","usage","args","Action","AppDeploymentStepsToAppDeployState","step","AppDeploymentSteps","command","ctx","firstRun","spinner","prevProgress","action","filesync","init","clone","user","log","printlns","app","slug","inSync","hashes","message","choices","sync","process","exit","unsubscribe","editGraphQL","subscribe","query","variables","localFilesVersion","String","filesVersion","force","onError","error","cause","fail","includes","println","onData","publishStatus","progress","issues","hasIssues","length","issue","replace","nodeType","node","type","nodeName","apiIdentifier","name","nodeParent","parentApiIdentifier","cyan","trim","succeed","currentProgress","start"],"mappings":"AAAA,OAAOA,WAAW,QAAQ;AAC1B,OAAOC,SAAS,MAAM;AACtB,SAASC,0CAA0C,QAAQ,kCAAkC;AAG7F,SAASC,QAAQ,EAAEC,YAAY,QAAQ,mCAAmC;AAC1E,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,cAAc,QAAQ,2BAA2B;AAC1D,SAASC,YAAY,EAAEC,eAAe,QAAQ,yBAAyB;AAEvE,OAAO,MAAMC,QAAe,IAAMJ,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDzC,CAAC,CAAC;AAEF,OAAO,MAAMK,OAAO;IAClB,GAAGP,YAAY;AACjB,EAAqB;;UAETQ;;;;GAAAA,WAAAA;AAMZ,MAAMC,qCAAqC,CAACC;IAC1C,OAAQA;QACN,KAAK;YACH,OAAO;QACT,KAAK;QACL,KAAK;QACL,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;QACT;YACE,OAAO;IACX;AACF;;UAEKC;;;;;;;;;GAAAA,uBAAAA;AAWL;;CAEC,GAED,OAAO,MAAMC,UAAW,OAAOC,KAAKC,WAAW,IAAI;IACjD,MAAMC,UAAUlB;IAChB,IAAImB,eAAmCP,mCAAmC;IAC1E,IAAIQ;IAEJ,MAAMC,WAAW,MAAMnB,SAASoB,IAAI,CAAC;QACnC,iCAAiC;QACjCN,KAAKA,IAAIO,KAAK,CAAC;YAAEb,MAAM;gBAAE,WAAW;YAAM;QAAE;QAC5Cc,MAAM,MAAMlB;IACd;IAEA,IAAIW,UAAU;QACZD,IAAIS,GAAG,CAACC,QAAQ,CAAC,KAAK,EAAEL,SAASM,GAAG,CAACC,IAAI,CAAC,CAAC;IAC7C;IAEA,MAAM,EAAEC,MAAM,EAAE,GAAG,MAAMR,SAASS,MAAM;IACxC,IAAI,CAACD,QAAQ;QACXb,IAAIS,GAAG,CAACC,QAAQ,CAAC;;IAEjB,CAAC;QAEDN,SAAS,MAAMhB,OAAO;YACpB2B,SAAS;YACTC,SAAS;;;aAAiC;QAC5C;QAEA,OAAQZ;YACN;gBAAuB;oBACrB,MAAMC,SAASY,IAAI;oBAEnB;gBACF;YACA;gBAAoB;oBAClBC,QAAQC,IAAI,CAAC;gBACf;QACF;IACF;IAEA,mGAAmG;IACnG,MAAMC,cAAcf,SAASgB,WAAW,CAACC,SAAS,CAAC;QACjDC,OAAOtC;QACPuC,WAAW,IAAO,CAAA;gBAAEC,mBAAmBC,OAAOrB,SAASsB,YAAY;gBAAGC,OAAO5B,IAAIN,IAAI,CAAC,UAAU;YAAC,CAAA;QACjGmC,SAAS,CAACC;YACR,IAAIvC,aAAauC,MAAMC,KAAK,GAAG;gBAC7B7B,QAAQ8B,IAAI,CAAC;gBACbhC,IAAIS,GAAG,CAACC,QAAQ,CAACoB,MAAMf,OAAO;YAChC,OAAO,IAAIvB,gBAAgBsC,MAAMC,KAAK,GAAG;gBACvC,MAAMhB,UAAUe,MAAMC,KAAK,CAAC,EAAE,EAAEhB;gBAChC,IAAIA,WAAWA,QAAQkB,QAAQ,CAAC,yBAAyB;oBACvDjC,IAAIS,GAAG,CAACyB,OAAO,CAAC;gBAClB,OAAO;oBACLlC,IAAIS,GAAG,CAACyB,OAAO,CAAC,CAAC,EAAEnB,QAAQ,CAAC;gBAC9B;YACF;YACAf,IAAIS,GAAG,CAACqB,KAAK,CAAC,oBAAoB;gBAAEA;YAAM;YAC1CV;YACA;QACF;QACAe,QAAQ,OAAO,EAAEC,aAAa,EAAE;YAC9B,MAAM,EAAEC,QAAQ,EAAEC,MAAM,EAAE,GAAGF,iBAAiB,CAAC;YAE/C,MAAMG,YAAYD,QAAQE;YAE1B,IAAIvC,YAAYsC,WAAW;gBACzBvC,IAAIS,GAAG,CAACC,QAAQ,CAAC,2BAA2B,CAAC;gBAE7C,KAAK,MAAM+B,SAASH,OAAQ;oBAC1B,MAAMvB,UAAU0B,MAAM1B,OAAO,CAAC2B,OAAO,CAAC,MAAM;oBAC5C,MAAMC,WAAWF,MAAMG,IAAI,EAAEC;oBAC7B,MAAMC,WAAWL,MAAMG,IAAI,EAAEG,iBAAiBN,MAAMG,IAAI,EAAEI;oBAC1D,MAAMC,aAAaR,MAAMG,IAAI,EAAEM;oBAE/BlD,IAAIS,GAAG,CAACC,QAAQ,CACd,CAAC;sBACS,EAAEK,QAAQ;sBACV,EAAE4B,WAAW,CAAC,EAAEA,SAAS,EAAE,EAAE5D,MAAMoE,IAAI,CAACL,UAAU,CAAC,GAAG,GAAG,iBAAiB,EACxEG,aAAa,CAAC,gBAAgB,EAAElE,MAAMoE,IAAI,CAACF,YAAY,CAAC,GAAG,GAC5D;YACX,CAAC,CAACG,IAAI;gBAEV;gBAEA,IAAI,CAACpD,IAAIN,IAAI,CAAC,UAAU,EAAE;oBACxB0B;oBAEAhB,SAAS,MAAMhB,OAAO;wBACpB2B,SAAS;wBACTC,SAAS;;;yBAAsC;oBACjD;oBAEA,OAAQZ;wBACN;4BAA4B;gCAC1BJ,IAAIN,IAAI,CAAC,UAAU,GAAG;gCACtB,MAAMK,QAAQC,KAAK;gCACnB;4BACF;wBACA;4BAAoB;gCAClBkB,QAAQC,IAAI,CAAC;4BACf;oBACF;gBACF;gBAEAlB,WAAW;YACb,OAAO;gBACL,IAAIoC,0BAA2C;oBAC7CnC,QAAQmD,OAAO,CAAC;oBAChBrD,IAAIS,GAAG,CAACC,QAAQ,CAAC;oBACjBU;oBACA;gBACF;gBAEA,MAAMkC,kBAAkB1D,mCAAmCyC;gBAE3D,IAAIA,YAAYiB,oBAAoBnD,cAAc;oBAChD,IAAI,AAACkC,yBAAiE;wBACpEnC,QAAQmD,OAAO,CAAC;oBAClB;oBAEAlD,eAAemD;oBACftD,IAAIS,GAAG,CAACC,QAAQ,CAAC,CAAC,EAAE4C,gBAAgB,IAAI,CAAC;oBACzCpD,QAAQqD,KAAK,CAAC;gBAChB;YACF;QACF;IACF;AACF,EAAkC"}
|
package/lib/commands/root.js
CHANGED
|
@@ -50,7 +50,8 @@ export const rootArgs = {
|
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
52
|
export const command = async ()=>{
|
|
53
|
-
const ctx =
|
|
53
|
+
const ctx = Context.init({
|
|
54
|
+
args: rootArgs,
|
|
54
55
|
argv: process.argv.slice(2),
|
|
55
56
|
permissive: true
|
|
56
57
|
});
|
|
@@ -77,7 +78,7 @@ export const command = async ()=>{
|
|
|
77
78
|
`;
|
|
78
79
|
process.exit(1);
|
|
79
80
|
}
|
|
80
|
-
const { usage, command, args } = await importCommand(cmd);
|
|
81
|
+
const { usage, command, args = {} } = await importCommand(cmd);
|
|
81
82
|
if (ctx.args["--help"]) {
|
|
82
83
|
log.println(usage());
|
|
83
84
|
process.exit(0);
|
|
@@ -85,7 +86,7 @@ export const command = async ()=>{
|
|
|
85
86
|
try {
|
|
86
87
|
await command(ctx.extend({
|
|
87
88
|
args,
|
|
88
|
-
|
|
89
|
+
name: cmd
|
|
89
90
|
}));
|
|
90
91
|
} catch (error) {
|
|
91
92
|
await reportErrorAndExit(error);
|
package/lib/commands/root.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/root.ts"],"sourcesContent":["import arg from \"arg\";\nimport ms from \"ms\";\nimport type { ArgsSpec } from \"../services/command/arg.js\";\nimport { AvailableCommands, importCommand, isAvailableCommand, type Usage } from \"../services/command/command.js\";\nimport { Context } from \"../services/command/context.js\";\nimport { verbosityToLevel } from \"../services/output/log/level.js\";\nimport { createLogger } from \"../services/output/log/logger.js\";\nimport { reportErrorAndExit } from \"../services/output/report.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { warnIfUpdateAvailable } from \"../services/output/update.js\";\nimport { sortBySimilar } from \"../services/util/collection.js\";\nimport { isNil } from \"../services/util/is.js\";\n\nconst log = createLogger({ name: \"root\" });\n\nexport const rootUsage: Usage = () => sprint`\n The command-line interface for Gadget\n\n {bold USAGE}\n ggt [COMMAND]\n\n {bold COMMANDS}\n sync Sync your Gadget application's source code\n list List your apps\n login Log in to your account\n logout Log out of your account\n whoami Print the currently logged in account\n version Print the version of ggt\n\n {bold FLAGS}\n -h, --help Print command's usage\n -v, --verbose Print verbose output\n --json Print output as JSON\n\n For more information on a specific command, use 'ggt [COMMAND] --help'\n`;\n\nexport const rootArgs = {\n \"--help\": {
|
|
1
|
+
{"version":3,"sources":["../../src/commands/root.ts"],"sourcesContent":["import arg from \"arg\";\nimport ms from \"ms\";\nimport type { ArgsSpec } from \"../services/command/arg.js\";\nimport { AvailableCommands, importCommand, isAvailableCommand, type Usage } from \"../services/command/command.js\";\nimport { Context } from \"../services/command/context.js\";\nimport { verbosityToLevel } from \"../services/output/log/level.js\";\nimport { createLogger } from \"../services/output/log/logger.js\";\nimport { reportErrorAndExit } from \"../services/output/report.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { warnIfUpdateAvailable } from \"../services/output/update.js\";\nimport { sortBySimilar } from \"../services/util/collection.js\";\nimport { isNil } from \"../services/util/is.js\";\n\nconst log = createLogger({ name: \"root\" });\n\nexport const rootUsage: Usage = () => sprint`\n The command-line interface for Gadget\n\n {bold USAGE}\n ggt [COMMAND]\n\n {bold COMMANDS}\n sync Sync your Gadget application's source code\n list List your apps\n login Log in to your account\n logout Log out of your account\n whoami Print the currently logged in account\n version Print the version of ggt\n\n {bold FLAGS}\n -h, --help Print command's usage\n -v, --verbose Print verbose output\n --json Print output as JSON\n\n For more information on a specific command, use 'ggt [COMMAND] --help'\n`;\n\nexport const rootArgs = {\n \"--help\": { type: Boolean, alias: \"-h\" },\n \"--verbose\": { type: arg.COUNT, alias: [\"-v\", \"--debug\"] },\n \"--json\": { type: Boolean },\n} satisfies ArgsSpec;\n\nexport type RootArgs = typeof rootArgs;\n\nexport const command = async (): Promise<void> => {\n const ctx = Context.init({ args: rootArgs, argv: process.argv.slice(2), permissive: true });\n\n await warnIfUpdateAvailable();\n\n if (ctx.args[\"--json\"]) {\n process.env[\"GGT_LOG_FORMAT\"] = \"json\";\n }\n\n if (ctx.args[\"--verbose\"]) {\n process.env[\"GGT_LOG_LEVEL\"] = verbosityToLevel(ctx.args[\"--verbose\"]).toString();\n }\n\n const cmd = ctx.args._.shift();\n if (isNil(cmd)) {\n log.println(rootUsage());\n process.exit(0);\n }\n\n if (!isAvailableCommand(cmd)) {\n const [closest] = sortBySimilar(cmd, AvailableCommands);\n log.println`\n Unknown command {yellow ${cmd}}\n\n Did you mean {blueBright ${closest}}?\n\n Run {gray ggt --help} for usage\n `;\n process.exit(1);\n }\n\n const { usage, command, args = {} } = await importCommand(cmd);\n\n if (ctx.args[\"--help\"]) {\n log.println(usage());\n process.exit(0);\n }\n\n try {\n await command(ctx.extend({ args, name: cmd }));\n } catch (error) {\n await reportErrorAndExit(error);\n }\n\n for (const signal of [\"SIGINT\", \"SIGTERM\"] as const) {\n process.once(signal, () => {\n log.trace(\"received signal\", { signal });\n log.println` Stopping... {gray Press Ctrl+C again to force}`;\n ctx.abort();\n\n // when ggt is run via npx, and the user presses ctrl+c, npx\n // sends sigint twice in quick succession. in order to prevent\n // the second sigint from triggering the force exit listener,\n // we wait a bit before registering it\n setTimeout(() => {\n process.once(signal, () => {\n log.println(\" Exiting immediately\");\n process.exit(1);\n });\n }, ms(\"100ms\")).unref();\n });\n }\n};\n"],"names":["arg","ms","AvailableCommands","importCommand","isAvailableCommand","Context","verbosityToLevel","createLogger","reportErrorAndExit","sprint","warnIfUpdateAvailable","sortBySimilar","isNil","log","name","rootUsage","rootArgs","type","Boolean","alias","COUNT","command","ctx","init","args","argv","process","slice","permissive","env","toString","cmd","_","shift","println","exit","closest","usage","extend","error","signal","once","trace","abort","setTimeout","unref"],"mappings":"AAAA,OAAOA,SAAS,MAAM;AACtB,OAAOC,QAAQ,KAAK;AAEpB,SAASC,iBAAiB,EAAEC,aAAa,EAAEC,kBAAkB,QAAoB,iCAAiC;AAClH,SAASC,OAAO,QAAQ,iCAAiC;AACzD,SAASC,gBAAgB,QAAQ,kCAAkC;AACnE,SAASC,YAAY,QAAQ,mCAAmC;AAChE,SAASC,kBAAkB,QAAQ,+BAA+B;AAClE,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,qBAAqB,QAAQ,+BAA+B;AACrE,SAASC,aAAa,QAAQ,iCAAiC;AAC/D,SAASC,KAAK,QAAQ,yBAAyB;AAE/C,MAAMC,MAAMN,aAAa;IAAEO,MAAM;AAAO;AAExC,OAAO,MAAMC,YAAmB,IAAMN,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;AAoB7C,CAAC,CAAC;AAEF,OAAO,MAAMO,WAAW;IACtB,UAAU;QAAEC,MAAMC;QAASC,OAAO;IAAK;IACvC,aAAa;QAAEF,MAAMjB,IAAIoB,KAAK;QAAED,OAAO;YAAC;YAAM;SAAU;IAAC;IACzD,UAAU;QAAEF,MAAMC;IAAQ;AAC5B,EAAqB;AAIrB,OAAO,MAAMG,UAAU;IACrB,MAAMC,MAAMjB,QAAQkB,IAAI,CAAC;QAAEC,MAAMR;QAAUS,MAAMC,QAAQD,IAAI,CAACE,KAAK,CAAC;QAAIC,YAAY;IAAK;IAEzF,MAAMlB;IAEN,IAAIY,IAAIE,IAAI,CAAC,SAAS,EAAE;QACtBE,QAAQG,GAAG,CAAC,iBAAiB,GAAG;IAClC;IAEA,IAAIP,IAAIE,IAAI,CAAC,YAAY,EAAE;QACzBE,QAAQG,GAAG,CAAC,gBAAgB,GAAGvB,iBAAiBgB,IAAIE,IAAI,CAAC,YAAY,EAAEM,QAAQ;IACjF;IAEA,MAAMC,MAAMT,IAAIE,IAAI,CAACQ,CAAC,CAACC,KAAK;IAC5B,IAAIrB,MAAMmB,MAAM;QACdlB,IAAIqB,OAAO,CAACnB;QACZW,QAAQS,IAAI,CAAC;IACf;IAEA,IAAI,CAAC/B,mBAAmB2B,MAAM;QAC5B,MAAM,CAACK,QAAQ,GAAGzB,cAAcoB,KAAK7B;QACrCW,IAAIqB,OAAO,CAAC;8BACc,EAAEH,IAAI;;+BAEL,EAAEK,QAAQ;;;IAGrC,CAAC;QACDV,QAAQS,IAAI,CAAC;IACf;IAEA,MAAM,EAAEE,KAAK,EAAEhB,OAAO,EAAEG,OAAO,CAAC,CAAC,EAAE,GAAG,MAAMrB,cAAc4B;IAE1D,IAAIT,IAAIE,IAAI,CAAC,SAAS,EAAE;QACtBX,IAAIqB,OAAO,CAACG;QACZX,QAAQS,IAAI,CAAC;IACf;IAEA,IAAI;QACF,MAAMd,QAAQC,IAAIgB,MAAM,CAAC;YAAEd;YAAMV,MAAMiB;QAAI;IAC7C,EAAE,OAAOQ,OAAO;QACd,MAAM/B,mBAAmB+B;IAC3B;IAEA,KAAK,MAAMC,UAAU;QAAC;QAAU;KAAU,CAAW;QACnDd,QAAQe,IAAI,CAACD,QAAQ;YACnB3B,IAAI6B,KAAK,CAAC,mBAAmB;gBAAEF;YAAO;YACtC3B,IAAIqB,OAAO,CAAC,+CAA+C,CAAC;YAC5DZ,IAAIqB,KAAK;YAET,4DAA4D;YAC5D,8DAA8D;YAC9D,6DAA6D;YAC7D,sCAAsC;YACtCC,WAAW;gBACTlB,QAAQe,IAAI,CAACD,QAAQ;oBACnB3B,IAAIqB,OAAO,CAAC;oBACZR,QAAQS,IAAI,CAAC;gBACf;YACF,GAAGlC,GAAG,UAAU4C,KAAK;QACvB;IACF;AACF,EAAE"}
|
package/lib/commands/sync.js
CHANGED
|
@@ -4,11 +4,10 @@ import ms from "ms";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import Watcher from "watcher";
|
|
6
6
|
import which from "which";
|
|
7
|
-
import { AppArg } from "../services/app/arg.js";
|
|
8
7
|
import { config } from "../services/config/config.js";
|
|
9
8
|
import { Changes } from "../services/filesync/changes.js";
|
|
10
9
|
import { YarnNotFoundError } from "../services/filesync/error.js";
|
|
11
|
-
import {
|
|
10
|
+
import { FileSync, FileSyncArgs } from "../services/filesync/filesync.js";
|
|
12
11
|
import { notify } from "../services/output/notify.js";
|
|
13
12
|
import { reportErrorAndExit } from "../services/output/report.js";
|
|
14
13
|
import { sprint } from "../services/output/sprint.js";
|
|
@@ -86,13 +85,8 @@ export const usage = ()=>sprint`
|
|
|
86
85
|
Goodbye!
|
|
87
86
|
`;
|
|
88
87
|
export const args = {
|
|
89
|
-
|
|
90
|
-
type: AppArg,
|
|
91
|
-
alias: "-a"
|
|
92
|
-
},
|
|
93
|
-
"--force": Boolean,
|
|
88
|
+
...FileSyncArgs,
|
|
94
89
|
"--once": Boolean,
|
|
95
|
-
"--prefer": ConflictPreferenceArg,
|
|
96
90
|
"--file-push-delay": {
|
|
97
91
|
type: Number,
|
|
98
92
|
default: ms("100ms")
|
|
@@ -118,14 +112,10 @@ export const args = {
|
|
|
118
112
|
* Runs the sync process until it is stopped or an error occurs.
|
|
119
113
|
*/ export const command = async (ctx)=>{
|
|
120
114
|
const filesync = await FileSync.init({
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
app: ctx.args["--app"],
|
|
124
|
-
force: ctx.args["--force"]
|
|
125
|
-
});
|
|
126
|
-
await filesync.sync({
|
|
127
|
-
preference: ctx.args["--prefer"]
|
|
115
|
+
ctx,
|
|
116
|
+
user: await getUserOrLogin()
|
|
128
117
|
});
|
|
118
|
+
await filesync.sync();
|
|
129
119
|
if (ctx.args["--once"]) {
|
|
130
120
|
ctx.log.println("Done!");
|
|
131
121
|
return;
|
package/lib/commands/sync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/sync.ts"],"sourcesContent":["import dayjs from \"dayjs\";\nimport { execa } from \"execa\";\nimport ms from \"ms\";\nimport path from \"node:path\";\nimport Watcher from \"watcher\";\nimport which from \"which\";\nimport { AppArg } from \"../services/app/arg.js\";\nimport type { ArgsSpec } 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 { ConflictPreferenceArg, FileSync } 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 { getUserOrLogin } from \"../services/user/user.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 \"--app\": { type: AppArg, alias: \"-a\" },\n \"--force\": Boolean,\n \"--once\": Boolean,\n \"--prefer\": ConflictPreferenceArg,\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 ArgsSpec;\n\n/**\n * Runs the sync process until it is stopped or an error occurs.\n */\nexport const command: Command<typeof args> = async (ctx) => {\n const filesync = await FileSync.init({\n user: await getUserOrLogin(),\n dir: ctx.args._[0],\n app: ctx.args[\"--app\"],\n force: ctx.args[\"--force\"],\n });\n\n await filesync.sync({ preference: ctx.args[\"--prefer\"] });\n\n if (ctx.args[\"--once\"]) {\n ctx.log.println(\"Done!\");\n return;\n }\n\n if (!which.sync(\"yarn\", { nothrow: true })) {\n throw new YarnNotFoundError();\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 afterChanges: async ({ changes }) => {\n if (changes.has(\"yarn.lock\")) {\n await execa(\"yarn\", [\"install\", \"--check-files\"], { cwd: filesync.directory.path }).catch((error) => {\n ctx.log.error(\"yarn install failed\", { error });\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({ subtitle: \"Uh oh!\", message: \"An error occurred while syncing files\" });\n await reportErrorAndExit(reason);\n });\n};\n"],"names":["dayjs","execa","ms","path","Watcher","which","AppArg","config","Changes","YarnNotFoundError","ConflictPreferenceArg","FileSync","notify","reportErrorAndExit","sprint","getUserOrLogin","debounce","isAbortError","usage","args","type","alias","Boolean","Number","default","command","ctx","filesync","init","user","dir","_","app","force","sync","preference","log","println","nothrow","recentWritesToLocalFilesystem","Map","clearRecentWritesInterval","setInterval","timestamp","isAfter","delete","unref","unsubscribeFromGadgetChanges","subscribeToGadgetChanges","onError","error","abort","beforeChanges","changed","deleted","filepath","set","Date","now","dirname","afterChanges","changes","has","cwd","directory","catch","localChangesBuffer","sendChangesToGadget","entries","clear","debug","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","slug","hasSplitEnvironments","primaryDomain","onAbort","reason","info","close","clearInterval","flush","idle","subtitle","message"],"mappings":"AAAA,OAAOA,WAAW,QAAQ;AAC1B,SAASC,KAAK,QAAQ,QAAQ;AAC9B,OAAOC,QAAQ,KAAK;AACpB,OAAOC,UAAU,YAAY;AAC7B,OAAOC,aAAa,UAAU;AAC9B,OAAOC,WAAW,QAAQ;AAC1B,SAASC,MAAM,QAAQ,yBAAyB;AAGhD,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,OAAO,QAAQ,kCAAkC;AAC1D,SAASC,iBAAiB,QAAQ,gCAAgC;AAClE,SAASC,qBAAqB,EAAEC,QAAQ,QAAQ,mCAAmC;AACnF,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,kBAAkB,QAAQ,+BAA+B;AAClE,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,cAAc,QAAQ,2BAA2B;AAC1D,SAASC,QAAQ,QAAQ,+BAA+B;AACxD,SAASC,YAAY,QAAQ,yBAAyB;AAEtD,OAAO,MAAMC,QAAe,IAAMJ,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqEzC,CAAC,CAAC;AAEF,OAAO,MAAMK,OAAO;IAClB,SAAS;QAAEC,MAAMd;QAAQe,OAAO;IAAK;IACrC,WAAWC;IACX,UAAUA;IACV,YAAYZ;IACZ,qBAAqB;QAAEU,MAAMG;QAAQC,SAAStB,GAAG;IAAS;IAC1D,yBAAyB;QAAEkB,MAAMG;QAAQC,SAAStB,GAAG;IAAS;IAC9D,8BAA8B;QAAEkB,MAAMG;QAAQC,SAAStB,GAAG;IAAM;IAChE,6BAA6B;QAAEkB,MAAMG;QAAQC,SAAStB,GAAG;IAAO;IAChE,+BAA+B;QAAEkB,MAAMG;QAAQC,SAAStB,GAAG;IAAS;AACtE,EAAqB;AAErB;;CAEC,GACD,OAAO,MAAMuB,UAAgC,OAAOC;IAClD,MAAMC,WAAW,MAAMhB,SAASiB,IAAI,CAAC;QACnCC,MAAM,MAAMd;QACZe,KAAKJ,IAAIP,IAAI,CAACY,CAAC,CAAC,EAAE;QAClBC,KAAKN,IAAIP,IAAI,CAAC,QAAQ;QACtBc,OAAOP,IAAIP,IAAI,CAAC,UAAU;IAC5B;IAEA,MAAMQ,SAASO,IAAI,CAAC;QAAEC,YAAYT,IAAIP,IAAI,CAAC,WAAW;IAAC;IAEvD,IAAIO,IAAIP,IAAI,CAAC,SAAS,EAAE;QACtBO,IAAIU,GAAG,CAACC,OAAO,CAAC;QAChB;IACF;IAEA,IAAI,CAAChC,MAAM6B,IAAI,CAAC,QAAQ;QAAEI,SAAS;IAAK,IAAI;QAC1C,MAAM,IAAI7B;IACZ;IAEA;;;;GAIC,GACD,MAAM8B,gCAAgC,IAAIC;IAE1C,MAAMC,4BAA4BC,YAAY;QAC5C,KAAK,MAAM,CAACvC,MAAMwC,UAAU,IAAIJ,8BAA+B;YAC7D,IAAIvC,QAAQ4C,OAAO,CAACD,YAAYzC,GAAG,QAAQ;gBACzC,2CAA2C;gBAC3CqC,8BAA8BM,MAAM,CAAC1C;YACvC;QACF;IACF,GAAGD,GAAG,OAAO4C,KAAK;IAElB;;;GAGC,GACD,MAAMC,+BAA+BpB,SAASqB,wBAAwB,CAAC;QACrEC,SAAS,CAACC,QAAUxB,IAAIyB,KAAK,CAACD;QAC9BE,eAAe,CAAC,EAAEC,OAAO,EAAEC,OAAO,EAAE;YAClC,4DAA4D;YAC5D,gEAAgE;YAChE,YAAY;YACZ,KAAK,MAAMC,YAAY;mBAAIF;mBAAYC;aAAQ,CAAE;gBAC/Cf,8BAA8BiB,GAAG,CAACD,UAAUE,KAAKC,GAAG;gBAEpD,IAAI5B,MAAM3B,KAAKwD,OAAO,CAACJ;gBACvB,MAAOzB,QAAQ,IAAK;oBAClBS,8BAA8BiB,GAAG,CAAC1B,MAAM,KAAK2B,KAAKC,GAAG;oBACrD5B,MAAM3B,KAAKwD,OAAO,CAAC7B;gBACrB;YACF;QACF;QACA8B,cAAc,OAAO,EAAEC,OAAO,EAAE;YAC9B,IAAIA,QAAQC,GAAG,CAAC,cAAc;gBAC5B,MAAM7D,MAAM,QAAQ;oBAAC;oBAAW;iBAAgB,EAAE;oBAAE8D,KAAKpC,SAASqC,SAAS,CAAC7D,IAAI;gBAAC,GAAG8D,KAAK,CAAC,CAACf;oBACzFxB,IAAIU,GAAG,CAACc,KAAK,CAAC,uBAAuB;wBAAEA;oBAAM;gBAC/C;YACF;QACF;IACF;IAEA;;GAEC,GACD,MAAMgB,qBAAqB,IAAI1D;IAE/B;;GAEC,GACD,MAAM2D,sBAAsBnD,SAASU,IAAIP,IAAI,CAAC,oBAAoB,EAAE;QAClE,MAAM0C,UAAU,IAAIrD,QAAQ0D,mBAAmBE,OAAO;QACtDF,mBAAmBG,KAAK;QACxB1C,SAASwC,mBAAmB,CAAC;YAAEN;QAAQ,GAAGI,KAAK,CAAC,CAACf,QAAUxB,IAAIyB,KAAK,CAACD;IACvE;IAEAxB,IAAIU,GAAG,CAACkC,KAAK,CAAC,YAAY;QAAEnE,MAAMwB,SAASqC,SAAS,CAAC7D,IAAI;IAAC;IAE1D;;GAEC,GACD,MAAMoE,cAAc,IAAInE,QACtBuB,SAASqC,SAAS,CAAC7D,IAAI,EACvB;QACE,qDAAqD;QACrDqE,eAAe;QACf,sFAAsF;QACtFC,QAAQ,CAACtE,OAAiBwB,SAASqC,SAAS,CAACU,QAAQ,CAACvE,MAAMwE,UAAU,CAAC,cAAchD,SAASqC,SAAS,CAACY,OAAO,CAACzE;QAChH0E,iBAAiB;QACjBC,WAAW;QACX9D,UAAUU,IAAIP,IAAI,CAAC,wBAAwB;QAC3C4D,iBAAiBrD,IAAIP,IAAI,CAAC,6BAA6B;QACvD6D,gBAAgBtD,IAAIP,IAAI,CAAC,4BAA4B;QACrD8D,eAAevD,IAAIP,IAAI,CAAC,8BAA8B;IACxD,GACA,CAAC+D,OAAeC,cAAsBC;QACpC,MAAM7B,WAAW2B,UAAU,YAAYA,UAAU,cAAcE,cAAcD;QAC7E,MAAME,cAAcH,UAAU,eAAeA,UAAU,YAAYA,UAAU;QAC7E,MAAMI,iBAAiB3D,SAASqC,SAAS,CAACuB,SAAS,CAAChC,UAAU8B;QAE9D3D,IAAIU,GAAG,CAACoD,KAAK,CAAC,cAAc;YAAEN;YAAOG;YAAalF,MAAMmF;QAAe;QAEvE,IAAI/B,aAAa5B,SAASqC,SAAS,CAACyB,QAAQ,CAAC,YAAY;YACvD9D,SAASqC,SAAS,CAAC0B,cAAc,GAAGzB,KAAK,CAAC,CAACf,QAAUxB,IAAIyB,KAAK,CAACD;QACjE,OAAO,IAAIvB,SAASqC,SAAS,CAACY,OAAO,CAACrB,WAAW;YAC/C;QACF;QAEA,IAAIhB,8BAA8BM,MAAM,CAACyC,iBAAiB;YACxD5D,IAAIU,GAAG,CAACoD,KAAK,CAAC,uCAAuC;gBAAEN;gBAAO/E,MAAMmF;YAAe;YACnF;QACF;QAEA,OAAQJ;YACN,KAAK;YACL,KAAK;gBACHhB,mBAAmBV,GAAG,CAAC8B,gBAAgB;oBAAElE,MAAM;gBAAS;gBACxD;YACF,KAAK;YACL,KAAK;gBAAa;oBAChB,MAAMuE,oBAAoBhE,SAASqC,SAAS,CAACuB,SAAS,CAACJ,cAAcE;oBACrEnB,mBAAmBV,GAAG,CAAC8B,gBAAgB;wBAAElE,MAAM;wBAAUwE,SAASD;oBAAkB;oBACpF;gBACF;YACA,KAAK;gBAAU;oBACbzB,mBAAmBV,GAAG,CAAC8B,gBAAgB;wBAAElE,MAAM;oBAAS;oBACxD;gBACF;YACA,KAAK;YACL,KAAK;gBAAa;oBAChB8C,mBAAmBV,GAAG,CAAC8B,gBAAgB;wBAAElE,MAAM;oBAAS;oBACxD;gBACF;QACF;QAEA+C;IACF,GACA0B,IAAI,CAAC,SAAS,CAAC3C,QAAUxB,IAAIyB,KAAK,CAACD;IAErCxB,IAAIU,GAAG,CAAC0D,QAAQ,CAAC;SACV,EAAEvF,OAAOwF,OAAO,CAAC;;gBAEV,EAAEpE,SAASK,GAAG,CAACgE,IAAI,CAAC;wBACZ,EAAErE,SAASK,GAAG,CAACgE,IAAI,CAAC;wBACpB,EAAErE,SAASK,GAAG,CAACgE,IAAI,CAAC;4CACA,EAAErE,SAASK,GAAG,CAACgE,IAAI,CAAC;;cAElD,EACRrE,SAASK,GAAG,CAACiE,oBAAoB,GAC7B,CAAC;gBACK,EAAEtE,SAASK,GAAG,CAACkE,aAAa,CAAC;gBAC7B,EAAEvE,SAASK,GAAG,CAACgE,IAAI,CAAC,wBAAwB,CAAC,GACnD,CAAC;gBACK,EAAErE,SAASK,GAAG,CAACkE,aAAa,CAAC,CAAC,CACzC;;;EAGH,CAAC;IAEDxE,IAAIyE,OAAO,CAAC,OAAOC;QACjB1E,IAAIU,GAAG,CAACiE,IAAI,CAAC,YAAY;YAAED;QAAO;QAElCrD;QACAwB,YAAY+B,KAAK;QACjBC,cAAc9D;QACd0B,oBAAoBqC,KAAK;QAEzB,IAAI;YACF,MAAM7E,SAAS8E,IAAI;QACrB,EAAE,OAAOvD,OAAO;YACdxB,IAAIU,GAAG,CAACc,KAAK,CAAC,gCAAgC;gBAAEA;YAAM;QACxD;QAEA,IAAIjC,aAAamF,SAAS;YACxB1E,IAAIU,GAAG,CAAC0D,QAAQ,CAAC;YACjB;QACF;QAEAlF,OAAO;YAAE8F,UAAU;YAAUC,SAAS;QAAwC;QAC9E,MAAM9F,mBAAmBuF;IAC3B;AACF,EAAE"}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/sync.ts"],"sourcesContent":["import dayjs from \"dayjs\";\nimport { execa } from \"execa\";\nimport ms from \"ms\";\nimport path from \"node:path\";\nimport Watcher from \"watcher\";\nimport which from \"which\";\nimport type { ArgsSpec } 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 { getUserOrLogin } from \"../services/user/user.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 ArgsSpec;\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<typeof args> = async (ctx) => {\n const filesync = await FileSync.init({ ctx, user: await getUserOrLogin() });\n await filesync.sync();\n\n if (ctx.args[\"--once\"]) {\n ctx.log.println(\"Done!\");\n return;\n }\n\n if (!which.sync(\"yarn\", { nothrow: true })) {\n throw new YarnNotFoundError();\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 afterChanges: async ({ changes }) => {\n if (changes.has(\"yarn.lock\")) {\n await execa(\"yarn\", [\"install\", \"--check-files\"], { cwd: filesync.directory.path }).catch((error) => {\n ctx.log.error(\"yarn install failed\", { error });\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({ subtitle: \"Uh oh!\", message: \"An error occurred while syncing files\" });\n await reportErrorAndExit(reason);\n });\n};\n"],"names":["dayjs","execa","ms","path","Watcher","which","config","Changes","YarnNotFoundError","FileSync","FileSyncArgs","notify","reportErrorAndExit","sprint","getUserOrLogin","debounce","isAbortError","usage","args","Boolean","type","Number","default","command","ctx","filesync","init","user","sync","log","println","nothrow","recentWritesToLocalFilesystem","Map","clearRecentWritesInterval","setInterval","timestamp","isAfter","delete","unref","unsubscribeFromGadgetChanges","subscribeToGadgetChanges","onError","error","abort","beforeChanges","changed","deleted","filepath","set","Date","now","dir","dirname","afterChanges","changes","has","cwd","directory","catch","localChangesBuffer","sendChangesToGadget","entries","clear","debug","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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"}
|
|
@@ -61,10 +61,11 @@ const log = createLogger({
|
|
|
61
61
|
*
|
|
62
62
|
* @param payload The query and variables to send to the server.
|
|
63
63
|
* @returns The data returned by the server.
|
|
64
|
-
*/ async query({ query, variables }) {
|
|
64
|
+
*/ async query({ query, variables, http }) {
|
|
65
65
|
const result = await this._query({
|
|
66
66
|
query,
|
|
67
|
-
variables
|
|
67
|
+
variables,
|
|
68
|
+
http
|
|
68
69
|
});
|
|
69
70
|
if (result.errors) {
|
|
70
71
|
throw new EditGraphQLError(query, result.errors);
|
|
@@ -155,7 +156,8 @@ const log = createLogger({
|
|
|
155
156
|
json: payload,
|
|
156
157
|
responseType: "json",
|
|
157
158
|
resolveBodyOnly: true,
|
|
158
|
-
throwHttpErrors: false
|
|
159
|
+
throwHttpErrors: false,
|
|
160
|
+
...input.http
|
|
159
161
|
});
|
|
160
162
|
if (!isObject(json) || !("data" in json) && !("errors" in json)) {
|
|
161
163
|
log.error("received invalid graphql response", {
|
|
@@ -376,6 +378,7 @@ export const REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION = sprint(/* GraphQL */ `
|
|
|
376
378
|
node {
|
|
377
379
|
type
|
|
378
380
|
key
|
|
381
|
+
apiIdentifier
|
|
379
382
|
name
|
|
380
383
|
fieldType
|
|
381
384
|
parentKey
|