diff --git a/packages/app/src/cli/api/graphql/app-dev/generated/dev-session-create.ts b/packages/app/src/cli/api/graphql/app-dev/generated/dev-session-create.ts index e1d612e54bc..bffec8887ed 100644 --- a/packages/app/src/cli/api/graphql/app-dev/generated/dev-session-create.ts +++ b/packages/app/src/cli/api/graphql/app-dev/generated/dev-session-create.ts @@ -7,6 +7,7 @@ import {TypedDocumentNode as DocumentNode} from '@graphql-typed-document-node/co export type DevSessionCreateMutationVariables = Types.Exact<{ appId: Types.Scalars['String']['input'] assetsUrl: Types.Scalars['String']['input'] + websocketUrl?: Types.InputMaybe }> export type DevSessionCreateMutation = { @@ -15,7 +16,7 @@ export type DevSessionCreateMutation = { } | null } -export const DevSessionCreate = { +export const DevSessionCreateDocument = { kind: 'Document', definitions: [ { @@ -33,6 +34,11 @@ export const DevSessionCreate = { variable: {kind: 'Variable', name: {kind: 'Name', value: 'assetsUrl'}}, type: {kind: 'NonNullType', type: {kind: 'NamedType', name: {kind: 'Name', value: 'String'}}}, }, + { + kind: 'VariableDefinition', + variable: {kind: 'Variable', name: {kind: 'Name', value: 'websocketUrl'}}, + type: {kind: 'NamedType', name: {kind: 'Name', value: 'String'}}, + }, ], selectionSet: { kind: 'SelectionSet', @@ -51,6 +57,11 @@ export const DevSessionCreate = { name: {kind: 'Name', value: 'assetsUrl'}, value: {kind: 'Variable', name: {kind: 'Name', value: 'assetsUrl'}}, }, + { + kind: 'Argument', + name: {kind: 'Name', value: 'websocketUrl'}, + value: {kind: 'Variable', name: {kind: 'Name', value: 'websocketUrl'}}, + }, ], selectionSet: { kind: 'SelectionSet', diff --git a/packages/app/src/cli/api/graphql/app-dev/generated/dev-session-delete.ts b/packages/app/src/cli/api/graphql/app-dev/generated/dev-session-delete.ts index 3f6ccb87cae..f4ee5554fb8 100644 --- a/packages/app/src/cli/api/graphql/app-dev/generated/dev-session-delete.ts +++ b/packages/app/src/cli/api/graphql/app-dev/generated/dev-session-delete.ts @@ -9,7 +9,7 @@ export type DevSessionDeleteMutationVariables = Types.Exact<{ export type DevSessionDeleteMutation = {devSessionDelete?: {userErrors: {message: string}[]} | null} -export const DevSessionDelete = { +export const DevSessionDeleteDocument = { kind: 'Document', definitions: [ { diff --git a/packages/app/src/cli/api/graphql/app-dev/generated/dev-session-update.ts b/packages/app/src/cli/api/graphql/app-dev/generated/dev-session-update.ts index 243629fa441..142fae8b5b0 100644 --- a/packages/app/src/cli/api/graphql/app-dev/generated/dev-session-update.ts +++ b/packages/app/src/cli/api/graphql/app-dev/generated/dev-session-update.ts @@ -7,6 +7,7 @@ import {TypedDocumentNode as DocumentNode} from '@graphql-typed-document-node/co export type DevSessionUpdateMutationVariables = Types.Exact<{ appId: Types.Scalars['String']['input'] assetsUrl?: Types.InputMaybe + websocketUrl?: Types.InputMaybe manifest?: Types.InputMaybe inheritedModuleUids: Types.Scalars['String']['input'][] | Types.Scalars['String']['input'] }> @@ -17,7 +18,7 @@ export type DevSessionUpdateMutation = { } | null } -export const DevSessionUpdate = { +export const DevSessionUpdateDocument = { kind: 'Document', definitions: [ { @@ -35,6 +36,11 @@ export const DevSessionUpdate = { variable: {kind: 'Variable', name: {kind: 'Name', value: 'assetsUrl'}}, type: {kind: 'NamedType', name: {kind: 'Name', value: 'String'}}, }, + { + kind: 'VariableDefinition', + variable: {kind: 'Variable', name: {kind: 'Name', value: 'websocketUrl'}}, + type: {kind: 'NamedType', name: {kind: 'Name', value: 'String'}}, + }, { kind: 'VariableDefinition', variable: {kind: 'Variable', name: {kind: 'Name', value: 'manifest'}}, @@ -69,6 +75,11 @@ export const DevSessionUpdate = { name: {kind: 'Name', value: 'assetsUrl'}, value: {kind: 'Variable', name: {kind: 'Name', value: 'assetsUrl'}}, }, + { + kind: 'Argument', + name: {kind: 'Name', value: 'websocketUrl'}, + value: {kind: 'Variable', name: {kind: 'Name', value: 'websocketUrl'}}, + }, { kind: 'Argument', name: {kind: 'Name', value: 'manifest'}, diff --git a/packages/app/src/cli/api/graphql/app-dev/queries/dev-session-create.graphql b/packages/app/src/cli/api/graphql/app-dev/queries/dev-session-create.graphql index d99cc3dddcc..f32b7fb9610 100644 --- a/packages/app/src/cli/api/graphql/app-dev/queries/dev-session-create.graphql +++ b/packages/app/src/cli/api/graphql/app-dev/queries/dev-session-create.graphql @@ -1,5 +1,5 @@ -mutation DevSessionCreate($appId: String!, $assetsUrl: String!) { - devSessionCreate(appId: $appId, assetsUrl: $assetsUrl) { +mutation DevSessionCreate($appId: String!, $assetsUrl: String!, $websocketUrl: String) { + devSessionCreate(appId: $appId, assetsUrl: $assetsUrl, websocketUrl: $websocketUrl) { userErrors { message on diff --git a/packages/app/src/cli/api/graphql/app-dev/queries/dev-session-update.graphql b/packages/app/src/cli/api/graphql/app-dev/queries/dev-session-update.graphql index 6d58ddbf1c9..e0237c71c23 100644 --- a/packages/app/src/cli/api/graphql/app-dev/queries/dev-session-update.graphql +++ b/packages/app/src/cli/api/graphql/app-dev/queries/dev-session-update.graphql @@ -1,5 +1,5 @@ -mutation DevSessionUpdate($appId: String!, $assetsUrl: String, $manifest: JSON, $inheritedModuleUids: [String!]!) { - devSessionUpdate(appId: $appId, assetsUrl: $assetsUrl, manifest: $manifest, inheritedModuleUids: $inheritedModuleUids) { +mutation DevSessionUpdate($appId: String!, $assetsUrl: String, $websocketUrl: String, $manifest: JSON, $inheritedModuleUids: [String!]!) { + devSessionUpdate(appId: $appId, assetsUrl: $assetsUrl, websocketUrl: $websocketUrl, manifest: $manifest, inheritedModuleUids: $inheritedModuleUids) { userErrors { message on diff --git a/packages/app/src/cli/api/graphql/business-platform-organizations/generated/types.d.ts b/packages/app/src/cli/api/graphql/business-platform-organizations/generated/types.d.ts index af5f0d3a1b7..5a0339234cd 100644 --- a/packages/app/src/cli/api/graphql/business-platform-organizations/generated/types.d.ts +++ b/packages/app/src/cli/api/graphql/business-platform-organizations/generated/types.d.ts @@ -1,6 +1,4 @@ /* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any */ -import {JsonMapType} from '@shopify/cli-kit/node/toml' - export type Maybe = T | null export type InputMaybe = Maybe export type Exact = {[K in keyof T]: T[K]} @@ -42,8 +40,6 @@ export type Scalars = { ISO8601Date: {input: any; output: any} /** An ISO 8601-encoded datetime */ ISO8601DateTime: {input: any; output: any} - /** Represents untyped JSON */ - JSON: {input: JsonMapType | string; output: JsonMapType} /** The ID for a LegalEntity. */ LegalEntityID: {input: any; output: any} /** The ID for a OrganizationDomain. */ diff --git a/packages/app/src/cli/services/dev/extension.ts b/packages/app/src/cli/services/dev/extension.ts index 59ec96db0d1..301f1313c4d 100644 --- a/packages/app/src/cli/services/dev/extension.ts +++ b/packages/app/src/cli/services/dev/extension.ts @@ -183,7 +183,7 @@ export async function devUIExtensions(options: ExtensionDevOptions): Promise { abortController = new AbortController() devSessionStatusManager = new DevSessionStatusManager() options = { + app: {} as AppLinkedInterface, + apiKey: 'test-api-key', developerPlatformClient, appWatcher, storeFqdn: 'test.myshopify.com', + url: 'https://test.dev', appId: 'app123', organizationId: 'org123', appPreviewURL: 'https://test.preview.url', @@ -404,6 +407,7 @@ describe('pushUpdatesForDevSession', () => { appId: 'app123', // Assets URL is empty because the affected extension has no assets assetsUrl: undefined, + websocketUrl: 'wss://test.dev/extensions', manifest: { name: 'App', handle: '', @@ -449,6 +453,7 @@ describe('pushUpdatesForDevSession', () => { shopFqdn: 'test.myshopify.com', appId: 'app123', assetsUrl: 'https://gcs.url', + websocketUrl: 'wss://test.dev/extensions', manifest: expect.any(Object), inheritedModuleUids: [], }) @@ -469,8 +474,7 @@ describe('pushUpdatesForDevSession', () => { shopFqdn: 'test.myshopify.com', appId: 'app123', assetsUrl: 'https://gcs.url', - manifest: expect.any(Object), - inheritedModuleUids: [], + websocketUrl: 'wss://test.dev/extensions', }) }) diff --git a/packages/app/src/cli/services/dev/processes/dev-session/dev-session.ts b/packages/app/src/cli/services/dev/processes/dev-session/dev-session.ts index 0572ed82db8..307e9a42dbf 100644 --- a/packages/app/src/cli/services/dev/processes/dev-session/dev-session.ts +++ b/packages/app/src/cli/services/dev/processes/dev-session/dev-session.ts @@ -5,6 +5,7 @@ import {AppEvent, AppEventWatcher, ExtensionEvent} from '../../app-events/app-ev import {compressBundle, getUploadURL, uploadToGCS, writeManifestToBundle} from '../../../bundle.js' import {DevSessionCreateOptions, DevSessionUpdateOptions} from '../../../../utilities/developer-platform-client.js' import {AppManifest} from '../../../../models/app/app.js' +import {getWebSocketUrl} from '../../extension.js' import {endHRTimeInMs, startHRTime} from '@shopify/cli-kit/node/hrtime' import {ClientError} from 'graphql-request' import {JsonMapType} from '@shopify/cli-kit/node/toml' @@ -276,16 +277,24 @@ export class DevSession { const {manifest, inheritedModuleUids, assets} = await this.createManifest(appEvent) const signedURL = await this.uploadAssetsIfNeeded(assets, !this.statusManager.status.isReady) - const payload = { - shopFqdn: this.options.storeFqdn, - appId: this.options.appId, - assetsUrl: signedURL, - manifest, - inheritedModuleUids, - } + const websocketUrl = getWebSocketUrl(this.options.url) if (this.statusManager.status.isReady) { + const payload: DevSessionUpdateOptions = { + shopFqdn: this.options.storeFqdn, + appId: this.options.appId, + assetsUrl: signedURL, + manifest, + inheritedModuleUids, + websocketUrl, + } return this.devSessionUpdateWithRetry(payload) } else { + const payload: DevSessionCreateOptions = { + shopFqdn: this.options.storeFqdn, + appId: this.options.appId, + assetsUrl: signedURL, + websocketUrl, + } return this.devSessionCreateWithRetry(payload) } // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/app/src/cli/utilities/developer-platform-client.ts b/packages/app/src/cli/utilities/developer-platform-client.ts index a919f8e00e6..56f2f754f24 100644 --- a/packages/app/src/cli/utilities/developer-platform-client.ts +++ b/packages/app/src/cli/utilities/developer-platform-client.ts @@ -163,13 +163,14 @@ interface DevSessionSharedOptions { export interface DevSessionCreateOptions extends DevSessionSharedOptions { assetsUrl?: string - manifest: AppManifest + websocketUrl?: string } export interface DevSessionUpdateOptions extends DevSessionSharedOptions { assetsUrl?: string manifest: AppManifest inheritedModuleUids: string[] + websocketUrl?: string } export type DevSessionDeleteOptions = DevSessionSharedOptions diff --git a/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts b/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts index f74ceebd240..b9990f35330 100644 --- a/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts +++ b/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts @@ -79,13 +79,19 @@ import {AppHomeSpecIdentifier} from '../../models/extensions/specifications/app_ import {BrandingSpecIdentifier} from '../../models/extensions/specifications/app_config_branding.js' import {AppAccessSpecIdentifier} from '../../models/extensions/specifications/app_config_app_access.js' import {CONFIG_EXTENSION_IDS} from '../../models/extensions/extension-instance.js' -import {DevSessionCreate, DevSessionCreateMutation} from '../../api/graphql/app-dev/generated/dev-session-create.js' import { - DevSessionUpdate, + DevSessionCreateDocument as DevSessionCreate, + DevSessionCreateMutation, +} from '../../api/graphql/app-dev/generated/dev-session-create.js' +import { + DevSessionUpdateDocument as DevSessionUpdate, DevSessionUpdateMutation, DevSessionUpdateMutationVariables, } from '../../api/graphql/app-dev/generated/dev-session-update.js' -import {DevSessionDelete, DevSessionDeleteMutation} from '../../api/graphql/app-dev/generated/dev-session-delete.js' +import { + DevSessionDeleteDocument as DevSessionDelete, + DevSessionDeleteMutation, +} from '../../api/graphql/app-dev/generated/dev-session-delete.js' import { FetchDevStoreByDomain, FetchDevStoreByDomainQueryVariables, @@ -1013,12 +1019,17 @@ export class AppManagementClient implements DeveloperPlatformClient { return appDeepLink({id, organizationId}) } - async devSessionCreate({appId, assetsUrl, shopFqdn}: DevSessionCreateOptions): Promise { + async devSessionCreate({ + appId, + assetsUrl, + shopFqdn, + websocketUrl, + }: DevSessionCreateOptions): Promise { const appIdNumber = String(numberFromGid(appId)) return this.appDevRequest({ query: DevSessionCreate, shopFqdn, - variables: {appId: appIdNumber, assetsUrl: assetsUrl ?? ''}, + variables: {appId: appIdNumber, assetsUrl: assetsUrl ?? '', websocketUrl}, requestOptions: {requestMode: 'slow-request'}, }) } @@ -1029,6 +1040,7 @@ export class AppManagementClient implements DeveloperPlatformClient { shopFqdn, manifest, inheritedModuleUids, + websocketUrl, }: DevSessionUpdateOptions): Promise { const appIdNumber = String(numberFromGid(appId)) const variables: DevSessionUpdateMutationVariables = { @@ -1036,6 +1048,7 @@ export class AppManagementClient implements DeveloperPlatformClient { assetsUrl, manifest: JSON.stringify(manifest), inheritedModuleUids, + websocketUrl, } return this.appDevRequest({query: DevSessionUpdate, shopFqdn, variables}) }