Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/remove-supports-dev-sessions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/app': patch
---

Always use dev sessions for app dev
2 changes: 0 additions & 2 deletions packages/app/src/cli/models/app/app.test-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 +1353,6 @@ export function testDeveloperPlatformClient(stubs: Partial<DeveloperPlatformClie
clientName: ClientName.AppManagement,
webUiName: 'Test Dashboard',
supportsAtomicDeployments: false,
supportsDevSessions: stubs.supportsDevSessions ?? false,
supportsStoreSearch: false,
organizationSource: OrganizationSource.BusinessPlatform,
bundleFormat: 'zip',
Expand Down Expand Up @@ -1441,7 +1440,6 @@ export function testDeveloperPlatformClient(stubs: Partial<DeveloperPlatformClie
| 'supportsAtomicDeployments'
| 'clientName'
| 'webUiName'
| 'supportsDevSessions'
| 'supportsStoreSearch'
| 'organizationSource'
| 'bundleFormat'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ use_legacy_install_flow = true

[build]
include_config_on_deploy = true
automatically_update_urls_on_dev = true
"
`;

Expand Down Expand Up @@ -515,6 +516,7 @@ url = "https://api-client-config.com/preferences"

[build]
include_config_on_deploy = true
automatically_update_urls_on_dev = true
"
`;

Expand Down Expand Up @@ -542,10 +544,11 @@ embedded = false

[build]
include_config_on_deploy = true
automatically_update_urls_on_dev = true
"
`;

exports[`link > when remote app is new and supports dev sessions then include automatically_update_urls_on_dev = true 1`] = `
exports[`link > when remote app is new then include automatically_update_urls_on_dev = true 1`] = `
"# Learn more about configuring your app at https://shopify.dev/docs/apps/tools/cli/configuration

application_url = "https://example.com"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ beforeEach(async () => {

function buildDeveloperPlatformClient(): DeveloperPlatformClient {
return testDeveloperPlatformClient({
supportsDevSessions: true,
async appFromIdentifiers(apiKey: string): Promise<OrganizationApp | undefined> {
switch (apiKey) {
case 'api-key':
Expand Down
6 changes: 4 additions & 2 deletions packages/app/src/cli/services/app/config/link.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ describe('link', () => {
},
build: {
include_config_on_deploy: true,
automatically_update_urls_on_dev: true,
},
})
expect(content).toMatchSnapshot()
Expand Down Expand Up @@ -342,6 +343,7 @@ describe('link', () => {
},
build: {
include_config_on_deploy: true,
automatically_update_urls_on_dev: true,
},
})
expect(content).toMatchSnapshot()
Expand Down Expand Up @@ -1195,14 +1197,14 @@ describe('link', () => {
})
})

test('when remote app is new and supports dev sessions then include automatically_update_urls_on_dev = true', async () => {
test('when remote app is new then include automatically_update_urls_on_dev = true', async () => {
await inTemporaryDirectory(async (tmp) => {
// Given
const filePath = joinPath(tmp, 'shopify.app.toml')
const initialContent = `scopes = ""
`
writeFileSync(filePath, initialContent)
const developerPlatformClient = buildDeveloperPlatformClient({supportsDevSessions: true})
const developerPlatformClient = buildDeveloperPlatformClient()
const options: LinkOptions = {
directory: tmp,
developerPlatformClient,
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/cli/services/app/config/link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ export async function overwriteLocalConfigFileWithRemoteAppConfiguration(options
existingBuildOptions: localAppOptions.existingBuildOptions,
linkedAppAndClientIdFromFileAreInSync: localAppOptions.localAppIdMatchedRemote,
linkedAppWasNewlyCreated: Boolean(remoteApp.newApp),
defaultToUpdateUrlsOnDev: developerPlatformClient.supportsDevSessions,
defaultToUpdateUrlsOnDev: true,
}),
}

Expand Down
44 changes: 0 additions & 44 deletions packages/app/src/cli/services/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ import {getAppConfigurationFileName} from '../models/app/loader.js'
import {ExtensionInstance} from '../models/extensions/extension-instance.js'

import {ExtensionRegistration} from '../api/graphql/all_app_extension_registrations.js'
import {
DevelopmentStorePreviewUpdateInput,
DevelopmentStorePreviewUpdateSchema,
} from '../api/graphql/development_preview.js'
import {
allDeveloperPlatformClients,
CreateAppOptions,
Expand Down Expand Up @@ -410,43 +406,3 @@ export async function logMetadataForLoadedContext(
api_key: app.apiKey,
}))
}

export async function enableDeveloperPreview({
apiKey,
developerPlatformClient,
}: {
apiKey: string
developerPlatformClient: DeveloperPlatformClient
}) {
return developerPreviewUpdate({apiKey, developerPlatformClient, enabled: true})
}

export async function disableDeveloperPreview({
apiKey,
developerPlatformClient,
}: {
apiKey: string
developerPlatformClient: DeveloperPlatformClient
}) {
await developerPreviewUpdate({apiKey, developerPlatformClient, enabled: false})
}

export async function developerPreviewUpdate({
apiKey,
developerPlatformClient,
enabled,
}: {
apiKey: string
developerPlatformClient: DeveloperPlatformClient
enabled: boolean
}) {
const input: DevelopmentStorePreviewUpdateInput = {
input: {
apiKey,
enabled,
},
}
const result: DevelopmentStorePreviewUpdateSchema = await developerPlatformClient.updateDeveloperPreview(input)
const userErrors = result.developmentStorePreviewUpdate.userErrors
return !userErrors || userErrors.length === 0
}
11 changes: 1 addition & 10 deletions packages/app/src/cli/services/dev-clean.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,10 @@ describe('devClean', () => {
// When/Then
await expect(devClean(mockOptions)).rejects.toThrow(`Failed to stop the dev preview: ${errorMessage}`)
})

test('throws AbortError when devSessions are not supported', async () => {
// Given
mockOptions.appContextResult.developerPlatformClient = customDevPlatformClient(undefined, false)

// When/Then
await expect(devClean(mockOptions)).rejects.toThrow('Dev preview is not supported for this app.')
})
})

function customDevPlatformClient(devSessionDeleteError?: string, supportsDevSessions = true) {
function customDevPlatformClient(devSessionDeleteError?: string) {
return testDeveloperPlatformClient({
supportsDevSessions,
devSessionDelete: vi.fn().mockResolvedValue({
devSessionDelete: {
userErrors: devSessionDeleteError ? [{message: devSessionDeleteError}] : [],
Expand Down
6 changes: 0 additions & 6 deletions packages/app/src/cli/services/dev-clean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ export async function devClean(options: DevCleanOptions) {
const client = options.appContextResult.developerPlatformClient
const remoteApp = options.appContextResult.remoteApp

if (!client.supportsDevSessions) {
throw new AbortError(
`Dev preview is not supported for this app. It's valid only for apps created on the Next-Gen Dev Platform.`,
)
}

const result = await client.devSessionDelete({shopFqdn: options.store.shopDomain, appId: remoteApp.id})

if (result.devSessionDelete?.userErrors.length) {
Expand Down
116 changes: 3 additions & 113 deletions packages/app/src/cli/services/dev.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {dev, warnIfScopesDifferBeforeDev, blockIfMigrationIncomplete} from './dev.js'
import {dev, blockIfMigrationIncomplete} from './dev.js'
import {setupDevProcesses} from './dev/processes/setup-dev-processes.js'
import {renderDev} from './dev/ui.js'
import {fetchAppRemoteConfiguration} from './app/select-app.js'
Expand All @@ -12,7 +12,6 @@ import {
} from '../models/app/app.test-data.js'
import metadata from '../metadata.js'
import {describe, expect, test, vi} from 'vitest'
import {mockAndCaptureOutput} from '@shopify/cli-kit/node/testing/output'
import {hashString} from '@shopify/cli-kit/node/crypto'
import {reportAnalyticsEvent} from '@shopify/cli-kit/node/analytics'
import {checkPortAvailability, getAvailableTCPPort} from '@shopify/cli-kit/node/tcp'
Expand Down Expand Up @@ -56,7 +55,7 @@ describe('dev', () => {
remoteApp: testOrganizationApp({apiKey: 'api-key'}),
organization: testOrganization(),
specifications: [],
developerPlatformClient: testDeveloperPlatformClient({supportsDevSessions: false}),
developerPlatformClient: testDeveloperPlatformClient(),
store,
directory: app.directory,
update: false,
Expand Down Expand Up @@ -87,97 +86,15 @@ describe('dev', () => {
})
})

describe('warnIfScopesDifferBeforeDev', () => {
const appsWithScopes = (local: string, remote: string) => {
const localApp = testAppLinked({})
const remoteApp = testOrganizationApp()
localApp.configuration = {
...localApp.configuration,
access_scopes: {scopes: local, use_legacy_install_flow: false},
}
remoteApp.configuration = {
...remoteApp.configuration,
access_scopes: {scopes: remote, use_legacy_install_flow: false},
} as any
return {
localApp,
remoteApp,
}
}

test('does not warn if the scopes are the same', async () => {
// Given
const developerPlatformClient = testDeveloperPlatformClient({supportsDevSessions: false})
const apps = appsWithScopes('scopes1,scopes2', 'scopes1,scopes2')

// When
const mockOutput = mockAndCaptureOutput()
mockOutput.clear()
await warnIfScopesDifferBeforeDev({
...apps,
developerPlatformClient,
commandOptions: {project: testProject()} as any,
})

// Then
expect(mockOutput.warn()).toBe('')
})

test('warns if the scopes differ', async () => {
// Given
const apps = appsWithScopes('scopes1,scopes2', 'scopes3,scopes4')
const developerPlatformClient = testDeveloperPlatformClient({supportsDevSessions: false})

// When
const mockOutput = mockAndCaptureOutput()
mockOutput.clear()
await warnIfScopesDifferBeforeDev({
...apps,
developerPlatformClient,
commandOptions: {project: testProject()} as any,
})

// Then
expect(mockOutput.warn()).toContain("The scopes in your TOML don't match")
})

test('silent if scopes differ cosmetically', async () => {
// Given
const apps = appsWithScopes('scopes1, scopes2 ', ' scopes2, scopes1')
const developerPlatformClient = testDeveloperPlatformClient({supportsDevSessions: false})

// When
const mockOutput = mockAndCaptureOutput()
mockOutput.clear()
await warnIfScopesDifferBeforeDev({
...apps,
developerPlatformClient,
commandOptions: {project: testProject()} as any,
})

// Then
expect(mockOutput.warn()).toBe('')
})
})

describe('blockIfMigrationIncomplete', () => {
const baseConfig = () => ({
localApp: testAppLinked({}),
remoteApp: testOrganizationApp(),
developerPlatformClient: testDeveloperPlatformClient({supportsDevSessions: true}),
})

test('does nothing when dev sessions not supported', async () => {
const devConfig = {
...baseConfig(),
developerPlatformClient: testDeveloperPlatformClient({supportsDevSessions: false}),
} as any
await expect(blockIfMigrationIncomplete(devConfig)).resolves.toBeUndefined()
developerPlatformClient: testDeveloperPlatformClient(),
})

test('does nothing when all remote extensions have ids (migrated)', async () => {
const developerPlatformClient = testDeveloperPlatformClient({
supportsDevSessions: true,
async appExtensionRegistrations() {
return {
app: {
Expand All @@ -202,7 +119,6 @@ describe('blockIfMigrationIncomplete', () => {

test('does nothing remote extensions dont have uids but are webhook subscriptions', async () => {
const developerPlatformClient = testDeveloperPlatformClient({
supportsDevSessions: true,
async appExtensionRegistrations() {
return {
app: {
Expand All @@ -227,7 +143,6 @@ describe('blockIfMigrationIncomplete', () => {

test('throws AbortError when some remote extensions are missing ids (not migrated)', async () => {
const developerPlatformClient = testDeveloperPlatformClient({
supportsDevSessions: true,
async appExtensionRegistrations() {
return {
app: {
Expand All @@ -249,29 +164,4 @@ describe('blockIfMigrationIncomplete', () => {

await expect(blockIfMigrationIncomplete(devConfig)).rejects.toThrow(/need to be assigned uid identifiers/)
})

test('does nothing for Partners with missing ids (not migrated)', async () => {
const developerPlatformClient = testDeveloperPlatformClient({
supportsDevSessions: false,
async appExtensionRegistrations() {
return {
app: {
extensionRegistrations: [
{id: '', uuid: 'u1', title: 'Legacy Ext 1', type: 'theme'},
{uuid: 'u2', title: 'Legacy Ext 2', type: 'web_pixel_extension'},
],
configurationRegistrations: [],
dashboardManagedExtensionRegistrations: [],
},
} as any
},
})

const devConfig = {
...baseConfig(),
developerPlatformClient,
} as any

await expect(blockIfMigrationIncomplete(devConfig)).resolves.toBeUndefined()
})
})
Loading
Loading