Skip to content

Commit 0d9cb9f

Browse files
Do not offer to migrate extension types not present in the app
1 parent cf02a82 commit 0d9cb9f

File tree

3 files changed

+46
-31
lines changed

3 files changed

+46
-31
lines changed

packages/app/src/cli/commands/app/import-extensions.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import {appFlags} from '../../flags.js'
2-
import {importExtensions} from '../../services/import-extensions.js'
2+
import {importExtensions, pendingExtensions} from '../../services/import-extensions.js'
33
import AppLinkedCommand, {AppLinkedCommandOutput} from '../../utilities/app-linked-command.js'
44
import {linkedAppContext} from '../../services/app-context.js'
55
import {selectMigrationChoice} from '../../prompts/import-extensions.js'
66
import {Flags} from '@oclif/core'
77
import {globalFlags} from '@shopify/cli-kit/node/cli'
8+
import {renderSuccess} from '@shopify/cli-kit/node/ui'
89

910
export default class ImportExtensions extends AppLinkedCommand {
1011
static description = 'Import dashboard-managed extensions into your app.'
@@ -29,13 +30,22 @@ export default class ImportExtensions extends AppLinkedCommand {
2930
userProvidedConfigName: flags.config,
3031
})
3132

32-
const migrationChoice = await selectMigrationChoice()
33-
34-
await importExtensions({
35-
...appContext,
36-
extensionTypes: migrationChoice.extensionTypes,
37-
buildTomlObject: migrationChoice.buildTomlObject,
38-
})
33+
const {extensions, extensionRegistrations} = await pendingExtensions(
34+
appContext.remoteApp,
35+
appContext.developerPlatformClient,
36+
)
37+
if (extensions.length === 0) {
38+
renderSuccess({headline: ['No extensions to migrate.']})
39+
} else {
40+
const migrationChoice = await selectMigrationChoice(extensions)
41+
await importExtensions({
42+
...appContext,
43+
extensions,
44+
extensionRegistrations,
45+
extensionTypes: migrationChoice.extensionTypes,
46+
buildTomlObject: migrationChoice.buildTomlObject,
47+
})
48+
}
3949

4050
return {app: appContext.app}
4151
}

packages/app/src/cli/prompts/import-extensions.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export interface MigrationChoice {
1919
) => string
2020
}
2121

22-
export const getMigrationChoices = (): MigrationChoice[] => [
22+
export const allMigrationChoices: MigrationChoice[] = [
2323
{
2424
label: 'Payments Extensions',
2525
value: 'payments',
@@ -59,8 +59,18 @@ export const getMigrationChoices = (): MigrationChoice[] => [
5959
},
6060
]
6161

62-
export async function selectMigrationChoice(): Promise<MigrationChoice> {
63-
const migrationChoices = getMigrationChoices()
62+
export function getMigrationChoices(extensions: ExtensionRegistration[]): MigrationChoice[] {
63+
return allMigrationChoices.filter((choice) =>
64+
choice.extensionTypes.some((type) => extensions.some((ext) => ext.type.toLowerCase() === type.toLowerCase())),
65+
)
66+
}
67+
68+
export async function selectMigrationChoice(extensions: ExtensionRegistration[]): Promise<MigrationChoice> {
69+
const migrationChoices = getMigrationChoices(extensions)
70+
if (migrationChoices.length === 1 && migrationChoices[0]) {
71+
return migrationChoices[0]
72+
}
73+
6474
const choices = migrationChoices.map((choice) => {
6575
return {label: choice.label, value: choice.value}
6676
})

packages/app/src/cli/services/import-extensions.ts

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ import {ExtensionRegistration} from '../api/graphql/all_app_extension_registrati
66
import {DeveloperPlatformClient} from '../utilities/developer-platform-client.js'
77
import {MAX_EXTENSION_HANDLE_LENGTH} from '../models/extensions/schemas.js'
88
import {OrganizationApp} from '../models/organization.js'
9-
import {getMigrationChoices} from '../prompts/import-extensions.js'
9+
import {allMigrationChoices} from '../prompts/import-extensions.js'
1010
import {renderSelectPrompt, renderSuccess} from '@shopify/cli-kit/node/ui'
1111
import {basename, joinPath} from '@shopify/cli-kit/node/path'
1212
import {writeFile} from '@shopify/cli-kit/node/fs'
1313
import {outputContent} from '@shopify/cli-kit/node/output'
1414
import {slugify} from '@shopify/cli-kit/common/string'
1515

16-
const allExtensionTypes = getMigrationChoices().map((choice) => choice.value)
16+
const allExtensionTypes = allMigrationChoices.flatMap((choice) => choice.extensionTypes)
1717

1818
export async function pendingExtensions(
1919
remoteApp: OrganizationApp,
@@ -40,6 +40,8 @@ interface ImportOptions {
4040
remoteApp: OrganizationApp
4141
developerPlatformClient: DeveloperPlatformClient
4242
extensionTypes: string[]
43+
extensions: ExtensionRegistration[]
44+
extensionRegistrations: ExtensionRegistration[]
4345
buildTomlObject: (
4446
ext: ExtensionRegistration,
4547
allExtensions: ExtensionRegistration[],
@@ -48,36 +50,29 @@ interface ImportOptions {
4850
}
4951

5052
export async function importExtensions(options: ImportOptions) {
51-
const {remoteApp, developerPlatformClient} = options
53+
const {app, remoteApp, developerPlatformClient, extensionTypes, extensions, extensionRegistrations, buildTomlObject} =
54+
options
5255

53-
const {extensions, extensionRegistrations} = await pendingExtensions(
54-
remoteApp,
55-
developerPlatformClient,
56-
options.extensionTypes,
57-
)
58-
59-
if (extensions.length === 0) {
60-
renderSuccess({headline: ['No extensions to migrate.']})
61-
return
62-
}
56+
let extensionsToMigrate = extensions.filter((ext) => extensionTypes.includes(ext.type.toLowerCase()))
6357

64-
const choices = extensions.map((ext) => {
58+
const choices = extensionsToMigrate.map((ext) => {
6559
return {label: ext.title, value: ext.uuid}
6660
})
6761

68-
if (extensions.length > 1) {
62+
if (extensionsToMigrate.length > 1) {
6963
choices.push({label: 'All', value: 'All'})
7064
}
7165
const promptAnswer = await renderSelectPrompt({message: 'Extensions to migrate', choices})
7266

73-
const extensionsToMigrate =
67+
if (promptAnswer !== 'All') {
7468
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
75-
promptAnswer === 'All' ? extensions : [extensions.find((ext) => ext?.uuid === promptAnswer)!]
69+
extensionsToMigrate = [extensionsToMigrate.find((ext) => ext?.uuid === promptAnswer)!]
70+
}
7671

7772
const extensionUuids: IdentifiersExtensions = {}
7873
const importPromises = extensionsToMigrate.map(async (ext) => {
79-
const directory = await ensureExtensionDirectoryExists({app: options.app, name: ext.title})
80-
const tomlObject = options.buildTomlObject(ext, extensionRegistrations, options.app.configuration)
74+
const directory = await ensureExtensionDirectoryExists({app, name: ext.title})
75+
const tomlObject = buildTomlObject(ext, extensionRegistrations, app.configuration)
8176
const path = joinPath(directory, 'shopify.extension.toml')
8277
await writeFile(path, tomlObject)
8378
const handle = slugify(ext.title.substring(0, MAX_EXTENSION_HANDLE_LENGTH))
@@ -88,7 +83,7 @@ export async function importExtensions(options: ImportOptions) {
8883
const generatedExtensions = await Promise.all(importPromises)
8984
renderSuccessMessages(generatedExtensions)
9085
await updateAppIdentifiers({
91-
app: options.app,
86+
app,
9287
identifiers: {
9388
extensions: extensionUuids,
9489
app: remoteApp.apiKey,

0 commit comments

Comments
 (0)