Skip to content

Commit 4892638

Browse files
authored
Merge pull request #6949 from Shopify/rcb/config-model-extract-path
Extract path from AppConfiguration into App.configPath
2 parents f1bbbcc + d965024 commit 4892638

44 files changed

Lines changed: 165 additions & 213 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/app/src/cli/commands/app/config/pull.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,17 @@ This command reuses the existing linked app and organization and skips all inter
3030
userProvidedConfigName: flags.config,
3131
})
3232

33-
const {configuration} = await pull({
33+
const {configuration, configPath} = await pull({
3434
directory: flags.path,
3535
configName: flags.config,
36+
configPath: app.configPath,
3637
configuration: app.configuration,
3738
remoteApp,
3839
})
3940

4041
renderSuccess({
4142
headline: `Pulled latest configuration for "${configuration.name}"`,
42-
body: `Updated ${basename(configuration.path)} with the remote data.`,
43+
body: `Updated ${basename(configPath)} with the remote data.`,
4344
})
4445

4546
return {app}

packages/app/src/cli/commands/app/env/pull.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export default class EnvPull extends AppLinkedCommand {
3636
forceRelink: flags.reset,
3737
userProvidedConfigName: flags.config,
3838
})
39-
const envFile = joinPath(app.directory, flags['env-file'] ?? getDotEnvFileName(app.configuration.path))
39+
const envFile = joinPath(app.directory, flags['env-file'] ?? getDotEnvFileName(app.configPath))
4040
outputResult(await pullEnv({app, remoteApp, organization, envFile}))
4141
return {app}
4242
}

packages/app/src/cli/models/app/app.test-data.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {
22
App,
33
AppSchema,
4-
AppConfigurationWithoutPath,
4+
AppConfiguration,
55
AppInterface,
66
AppLinkedInterface,
77
CurrentAppConfiguration,
@@ -82,7 +82,6 @@ import {vi} from 'vitest'
8282
import {joinPath} from '@shopify/cli-kit/node/path'
8383

8484
export const DEFAULT_CONFIG = {
85-
path: '/tmp/project/shopify.app.toml',
8685
application_url: 'https://myapp.com',
8786
client_id: 'api-key',
8887
name: 'my app',
@@ -96,14 +95,15 @@ export const DEFAULT_CONFIG = {
9695
},
9796
}
9897

99-
export function testApp(app: Partial<AppInterface> = {}, schemaType: 'current' | 'legacy' = 'legacy'): AppInterface {
98+
export function testApp(app: Partial<AppInterface> = {}): AppInterface {
10099
const getConfig = () => {
101100
return DEFAULT_CONFIG as CurrentAppConfiguration
102101
}
103102

104103
const newApp = new App({
105104
name: app.name ?? 'App',
106105
directory: app.directory ?? '/tmp/project',
106+
configPath: app.configPath ?? '/tmp/project/shopify.app.toml',
107107
packageManager: app.packageManager ?? 'yarn',
108108
configuration: app.configuration ?? getConfig(),
109109
nodeDependencies: app.nodeDependencies ?? {},
@@ -137,7 +137,7 @@ export function testApp(app: Partial<AppInterface> = {}, schemaType: 'current' |
137137
}
138138

139139
export function testAppLinked(app: Partial<AppInterface> = {}): AppLinkedInterface {
140-
return testApp(app, 'current') as AppLinkedInterface
140+
return testApp(app) as AppLinkedInterface
141141
}
142142

143143
interface TestAppWithConfigOptions {
@@ -188,7 +188,7 @@ export function testOrganizationApp(app: Partial<OrganizationApp> = {}): Organiz
188188
return {...defaultApp, ...app}
189189
}
190190

191-
export const placeholderAppConfiguration: AppConfigurationWithoutPath = {
191+
export const placeholderAppConfiguration: AppConfiguration = {
192192
client_id: '',
193193
}
194194

packages/app/src/cli/models/app/app.test.ts

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import {joinPath} from '@shopify/cli-kit/node/path'
2929
import {AbortError} from '@shopify/cli-kit/node/error'
3030

3131
const CORRECT_CURRENT_APP_SCHEMA: CurrentAppConfiguration = {
32-
path: '',
3332
name: 'app 1',
3433
client_id: '12345',
3534
extension_directories: ['extensions/*'],
@@ -574,14 +573,11 @@ describe('allExtensions', () => {
574573

575574
test('keeps declarative webhook config when flag is enabled', async () => {
576575
const webhookExtensions = await testWebhookExtensions({complianceTopics: true})
577-
const app = testApp(
578-
{
579-
configuration: CORRECT_CURRENT_APP_SCHEMA,
580-
allExtensions: webhookExtensions,
581-
remoteFlags: [],
582-
},
583-
'current',
584-
)
576+
const app = testApp({
577+
configuration: CORRECT_CURRENT_APP_SCHEMA,
578+
allExtensions: webhookExtensions,
579+
remoteFlags: [],
580+
})
585581

586582
const webhookConfig = app.allExtensions.find((ext) => ext.handle === 'webhooks')!
587583
.configuration as unknown as WebhookTestConfig
@@ -596,33 +592,27 @@ describe('allExtensions', () => {
596592

597593
test('includes configuration extensions when include_config_on_deploy is enabled', async () => {
598594
const configExtension = await testAppAccessConfigExtension()
599-
const app = testApp(
600-
{
601-
configuration: CORRECT_CURRENT_APP_SCHEMA,
602-
allExtensions: [configExtension],
603-
},
604-
'current',
605-
)
595+
const app = testApp({
596+
configuration: CORRECT_CURRENT_APP_SCHEMA,
597+
allExtensions: [configExtension],
598+
})
606599

607600
expect(app.allExtensions).toContain(configExtension)
608601
})
609602

610603
test('includes configuration extensions by default when include_config_on_deploy is undefined', async () => {
611604
const configExtension = await testAppAccessConfigExtension()
612-
const app = testApp(
613-
{
614-
configuration: {
615-
...CORRECT_CURRENT_APP_SCHEMA,
616-
build: {
617-
automatically_update_urls_on_dev: true,
618-
dev_store_url: 'https://google.com',
619-
include_config_on_deploy: undefined,
620-
},
605+
const app = testApp({
606+
configuration: {
607+
...CORRECT_CURRENT_APP_SCHEMA,
608+
build: {
609+
automatically_update_urls_on_dev: true,
610+
dev_store_url: 'https://google.com',
611+
include_config_on_deploy: undefined,
621612
},
622-
allExtensions: [configExtension],
623613
},
624-
'current',
625-
)
614+
allExtensions: [configExtension],
615+
})
626616

627617
expect(app.allExtensions).toContain(configExtension)
628618
})
@@ -637,13 +627,10 @@ describe('allExtensions', () => {
637627
},
638628
}
639629
const configExtension = await testAppAccessConfigExtension()
640-
const app = testApp(
641-
{
642-
configuration,
643-
allExtensions: [configExtension],
644-
},
645-
'current',
646-
)
630+
const app = testApp({
631+
configuration,
632+
allExtensions: [configExtension],
633+
})
647634

648635
expect(app.allExtensions).toHaveLength(0)
649636
})

packages/app/src/cli/models/app/app.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,12 @@ export interface AppHiddenConfig {
8484
*
8585
* Try to avoid using this: generally you should be working with a more specific type.
8686
*/
87-
export type AppConfiguration = zod.infer<typeof AppSchema> & {path: string}
88-
export type AppConfigurationWithoutPath = zod.infer<typeof AppSchema>
87+
export type AppConfiguration = zod.infer<typeof AppSchema>
8988

9089
/**
9190
* App configuration for a normal, linked, app. Doesn't include properties that are module derived.
9291
*/
93-
export type BasicAppConfigurationWithoutModules = zod.infer<typeof AppSchema> & {path: string}
92+
export type BasicAppConfigurationWithoutModules = zod.infer<typeof AppSchema>
9493

9594
/**
9695
* The build section for a normal, linked app. The options here tweak the CLI's behavior when working with the app.
@@ -103,12 +102,12 @@ export type CliBuildPreferences = BasicAppConfigurationWithoutModules['build']
103102
export type CurrentAppConfiguration = BasicAppConfigurationWithoutModules & AppConfigurationUsedByCli
104103

105104
/** Validation schema that produces a provided app configuration type */
106-
export type SchemaForConfig<TConfig extends {path: string}> = ZodObjectOf<Omit<TConfig, 'path'>>
105+
export type SchemaForConfig<TConfig> = ZodObjectOf<TConfig>
107106

108107
export function getAppVersionedSchema(
109108
specs: ExtensionSpecification[],
110109
allowDynamicallySpecifiedConfigs = true,
111-
): ZodObjectOf<Omit<CurrentAppConfiguration, 'path'>> {
110+
): ZodObjectOf<CurrentAppConfiguration> {
112111
// eslint-disable-next-line @typescript-eslint/no-explicit-any
113112
const schema = specs.reduce<any>((schema, spec) => spec.contributeToAppConfigurationSchema(schema), AppSchema)
114113

@@ -144,7 +143,7 @@ export function appHiddenConfigPath(appDirectory: string) {
144143
* Get the field names from the configuration that aren't found in the basic built-in app configuration schema.
145144
*/
146145
export function filterNonVersionedAppFields(configuration: object): string[] {
147-
const builtInFieldNames = Object.keys(AppSchema.shape).concat('path', 'organization_id')
146+
const builtInFieldNames = Object.keys(AppSchema.shape).concat('organization_id')
148147
return Object.keys(configuration).filter((fieldName) => {
149148
return !builtInFieldNames.includes(fieldName)
150149
})
@@ -194,6 +193,7 @@ export interface AppConfigurationInterface<
194193
TModuleSpec extends ExtensionSpecification = ExtensionSpecification,
195194
> {
196195
directory: string
196+
configPath: string
197197
configuration: TConfig
198198
configSchema: SchemaForConfig<TConfig>
199199
specifications: TModuleSpec[]
@@ -284,6 +284,7 @@ export class App<
284284
name: string
285285
idEnvironmentVariableName: 'SHOPIFY_API_KEY' = 'SHOPIFY_API_KEY' as const
286286
directory: string
287+
configPath: string
287288
packageManager: PackageManager
288289
configuration: TConfig
289290
nodeDependencies: {[key: string]: string}
@@ -292,7 +293,7 @@ export class App<
292293
dotenv?: DotEnvFile
293294
errors?: AppErrors
294295
specifications: TModuleSpec[]
295-
configSchema: ZodObjectOf<Omit<TConfig, 'path'>>
296+
configSchema: SchemaForConfig<TConfig>
296297
remoteFlags: Flag[]
297298
realExtensions: ExtensionInstance[]
298299
devApplicationURLs?: ApplicationURLs
@@ -301,6 +302,7 @@ export class App<
301302
constructor({
302303
name,
303304
directory,
305+
configPath,
304306
packageManager,
305307
configuration,
306308
nodeDependencies,
@@ -317,6 +319,7 @@ export class App<
317319
}: AppConstructor<TConfig, TModuleSpec>) {
318320
this.name = name
319321
this.directory = directory
322+
this.configPath = configPath
320323
this.packageManager = packageManager
321324
this.configuration = configuration
322325
this.nodeDependencies = nodeDependencies

packages/app/src/cli/models/app/identifiers.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,10 @@ describe('updateAppIdentifiers', () => {
4646
const app = testAppWithConfig({
4747
app: {
4848
directory: tmpDir,
49+
configPath: joinPath(tmpDir, 'shopify.app.staging.toml'),
4950
allExtensions: [uiExtension],
5051
},
51-
config: {
52-
path: joinPath(tmpDir, 'shopify.app.staging.toml'),
53-
},
52+
config: {},
5453
})
5554

5655
// When

packages/app/src/cli/models/app/identifiers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export async function updateAppIdentifiers(
5454

5555
if (!dotenvFile) {
5656
dotenvFile = {
57-
path: joinPath(app.directory, getDotEnvFileName(app.configuration.path)),
57+
path: joinPath(app.directory, getDotEnvFileName(app.configPath)),
5858
variables: {},
5959
}
6060
}

packages/app/src/cli/models/app/loader.test.ts

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
loadHiddenConfig,
1414
} from './loader.js'
1515
import {parseHumanReadableError} from './error-parsing.js'
16-
import {App, AppInterface, AppLinkedInterface, AppSchema, WebConfigurationSchema} from './app.js'
16+
import {App, AppConfiguration, AppInterface, AppLinkedInterface, AppSchema, WebConfigurationSchema} from './app.js'
1717
import {DEFAULT_CONFIG, buildVersionedAppSchema, getWebhookConfig} from './app.test-data.js'
1818
import {ExtensionInstance} from '../extensions/extension-instance.js'
1919
import {configurationFileNames, blocks} from '../../constants.js'
@@ -2908,8 +2908,7 @@ describe('parseConfigurationObject', () => {
29082908
const abortOrReport = vi.fn()
29092909

29102910
const {schema} = await buildVersionedAppSchema()
2911-
const {path, ...toParse} = configurationObject
2912-
await parseConfigurationObject(schema, 'tmp', toParse, abortOrReport)
2911+
await parseConfigurationObject(schema, 'tmp', configurationObject, abortOrReport)
29132912

29142913
expect(abortOrReport).toHaveBeenCalledWith(expectedFormatted, {}, 'tmp')
29152914
})
@@ -3479,7 +3478,7 @@ describe('WebhooksSchema', () => {
34793478
)} in tmp:\n\n${parseHumanReadableError(err)}`
34803479
const abortOrReport = vi.fn()
34813480

3482-
const {path, ...toParse} = getWebhookConfig(webhookConfigOverrides)
3481+
const toParse = getWebhookConfig(webhookConfigOverrides)
34833482
const parsedConfiguration = await parseConfigurationObject(WebhooksSchema, 'tmp', toParse, abortOrReport)
34843483
return {abortOrReport, expectedFormatted, parsedConfiguration}
34853484
}
@@ -3491,7 +3490,6 @@ describe('getAppConfigurationState', () => {
34913490
`client_id="abcdef"`,
34923491
{
34933492
basicConfiguration: {
3494-
path: expect.stringMatching(/shopify.app.toml$/),
34953493
client_id: 'abcdef',
34963494
},
34973495
isLinked: true,
@@ -3502,7 +3500,6 @@ describe('getAppConfigurationState', () => {
35023500
something_extra="keep"`,
35033501
{
35043502
basicConfiguration: {
3505-
path: expect.stringMatching(/shopify.app.toml$/),
35063503
client_id: 'abcdef',
35073504
something_extra: 'keep',
35083505
},
@@ -3513,7 +3510,6 @@ describe('getAppConfigurationState', () => {
35133510
`client_id=""`,
35143511
{
35153512
basicConfiguration: {
3516-
path: expect.stringMatching(/shopify.app.toml$/),
35173513
client_id: '',
35183514
},
35193515
isLinked: false,
@@ -3692,9 +3688,8 @@ describe('loadHiddenConfig', () => {
36923688
await inTemporaryDirectory(async (tmpDir) => {
36933689
// Given
36943690
const configuration = {
3695-
path: joinPath(tmpDir, 'shopify.app.toml'),
36963691
client_id: '12345',
3697-
}
3692+
} as AppConfiguration
36983693
await writeFile(joinPath(tmpDir, '.gitignore'), '')
36993694

37003695
// When
@@ -3714,9 +3709,8 @@ describe('loadHiddenConfig', () => {
37143709
await inTemporaryDirectory(async (tmpDir) => {
37153710
// Given
37163711
const configuration = {
3717-
path: joinPath(tmpDir, 'shopify.app.toml'),
37183712
client_id: '12345',
3719-
}
3713+
} as AppConfiguration
37203714
const hiddenConfigPath = joinPath(tmpDir, '.shopify', 'project.json')
37213715
await mkdir(dirname(hiddenConfigPath))
37223716
await writeFile(
@@ -3739,9 +3733,8 @@ describe('loadHiddenConfig', () => {
37393733
await inTemporaryDirectory(async (tmpDir) => {
37403734
// Given
37413735
const configuration = {
3742-
path: joinPath(tmpDir, 'shopify.app.toml'),
37433736
client_id: 'not-found',
3744-
}
3737+
} as AppConfiguration
37453738
const hiddenConfigPath = joinPath(tmpDir, '.shopify', 'project.json')
37463739
await mkdir(dirname(hiddenConfigPath))
37473740
await writeFile(
@@ -3763,9 +3756,8 @@ describe('loadHiddenConfig', () => {
37633756
await inTemporaryDirectory(async (tmpDir) => {
37643757
// Given
37653758
const configuration = {
3766-
path: joinPath(tmpDir, 'shopify.app.toml'),
37673759
client_id: 'not-found',
3768-
}
3760+
} as AppConfiguration
37693761
const hiddenConfigPath = joinPath(tmpDir, '.shopify', 'project.json')
37703762
await mkdir(dirname(hiddenConfigPath))
37713763
await writeFile(
@@ -3787,9 +3779,8 @@ describe('loadHiddenConfig', () => {
37873779
await inTemporaryDirectory(async (tmpDir) => {
37883780
// Given
37893781
const configuration = {
3790-
path: joinPath(tmpDir, 'shopify.app.toml'),
37913782
client_id: '12345',
3792-
}
3783+
} as AppConfiguration
37933784
const hiddenConfigPath = joinPath(tmpDir, '.shopify', 'project.json')
37943785
await mkdir(dirname(hiddenConfigPath))
37953786
await writeFile(hiddenConfigPath, 'invalid json')

0 commit comments

Comments
 (0)