Skip to content

Commit 7a4bf98

Browse files
Merge pull request #6561 from Shopify/11-03-fix_how_app_name_is_set_from_the_apploader
Fix how app name is set from the AppLoader
2 parents e987aba + 64d1fc7 commit 7a4bf98

File tree

5 files changed

+90
-17
lines changed

5 files changed

+90
-17
lines changed

.changeset/happy-jobs-type.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@shopify/cli-kit': minor
3+
'@shopify/app': minor
4+
---
5+
6+
Use the handle to set the app version name, and the TOML name as a fallback

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

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ describe('load', () => {
6464
}
6565

6666
const appConfiguration = `
67+
name = "my_app"
6768
scopes = "read_products"
6869
`
6970
const linkedAppConfiguration = `
@@ -264,7 +265,54 @@ wrong = "property"
264265
const app = await loadApp({directory: tmpDir, specifications: [], userProvidedConfigName: undefined})
265266

266267
// Then
267-
expect(app.name).toBe('my_app')
268+
expect(app.name).toBe('for-testing')
269+
})
270+
271+
test('uses handle from configuration as app name when present', async () => {
272+
// Given
273+
const appConfiguration = `
274+
name = "display-name"
275+
handle = "app-handle"
276+
client_id = "1234567890"
277+
application_url = "https://example.com/lala"
278+
embedded = true
279+
280+
[webhooks]
281+
api_version = "2023-07"
282+
283+
[auth]
284+
redirect_urls = [ "https://example.com/api/auth" ]
285+
`
286+
await writeConfig(appConfiguration)
287+
288+
// When
289+
const app = await loadTestingApp()
290+
291+
// Then
292+
expect(app.name).toBe('app-handle')
293+
})
294+
295+
test('uses name from configuration when handle is not present', async () => {
296+
// Given
297+
const appConfiguration = `
298+
name = "config-name"
299+
client_id = "1234567890"
300+
application_url = "https://example.com/lala"
301+
embedded = true
302+
303+
[webhooks]
304+
api_version = "2023-07"
305+
306+
[auth]
307+
redirect_urls = [ "https://example.com/api/auth" ]
308+
`
309+
await writeConfig(appConfiguration)
310+
311+
// When
312+
const app = await loadTestingApp()
313+
314+
// Then
315+
expect(app.name).toBe('config-name')
268316
})
269317

270318
test('defaults to npm as the package manager when the configuration is valid', async () => {

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

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ import {readAndParseDotEnv, DotEnvFile} from '@shopify/cli-kit/node/dot-env'
4242
import {
4343
getDependencies,
4444
getPackageManager,
45-
getPackageName,
4645
usesWorkspaces as appUsesWorkspaces,
4746
} from '@shopify/cli-kit/node/node-package-manager'
4847
import {resolveFramework} from '@shopify/cli-kit/node/framework'
@@ -343,7 +342,10 @@ class AppLoader<TConfig extends AppConfiguration, TModuleSpec extends ExtensionS
343342
const packageJSONPath = joinPath(directory, 'package.json')
344343

345344
// These don't need to be processed again if the app is being reloaded
346-
const name = this.previousApp?.name ?? (await loadAppName(directory))
345+
// name is required by BrandingSchema, so it must be present in the configuration
346+
const configName = (configuration as CurrentAppConfiguration).name
347+
const configHandle: string | undefined = (configuration as CurrentAppConfiguration).handle
348+
const name: string = this.previousApp?.name ?? configHandle ?? configName ?? ''
347349
const nodeDependencies = this.previousApp?.nodeDependencies ?? (await getDependencies(packageJSONPath))
348350
const packageManager = this.previousApp?.packageManager ?? (await getPackageManager(directory))
349351
const usesWorkspaces = this.previousApp?.usesWorkspaces ?? (await appUsesWorkspaces(directory))
@@ -1108,11 +1110,6 @@ export async function loadHiddenConfig(
11081110
}
11091111
}
11101112

1111-
export async function loadAppName(appDirectory: string): Promise<string> {
1112-
const packageJSONPath = joinPath(appDirectory, 'package.json')
1113-
return (await getPackageName(packageJSONPath)) ?? basename(appDirectory)
1114-
}
1115-
11161113
async function getProjectType(webs: Web[]): Promise<'node' | 'php' | 'ruby' | 'frontend' | undefined> {
11171114
const backendWebs = webs.filter((web) => isWebType(web, WebType.Backend))
11181115
const frontendWebs = webs.filter((web) => isWebType(web, WebType.Frontend))

packages/app/src/cli/models/extensions/specifications/types/app_config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {WebhooksConfig} from './app_config_webhook.js'
1212
*/
1313
export interface AppConfigurationUsedByCli {
1414
name: string
15+
handle?: string
1516
application_url: string
1617
embedded: boolean
1718
app_proxy?: {

packages/app/src/cli/services/app-context.test.ts

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ describe('linkedAppContext', () => {
4949
test('returns linked app context when app is already linked', async () => {
5050
await inTemporaryDirectory(async (tmp) => {
5151
// Given
52-
const content = `client_id="test-api-key"`
52+
const content = `
53+
name = "test-app"
54+
client_id="test-api-key"`
5355
await writeAppConfig(tmp, content)
5456

5557
// When
@@ -65,6 +67,7 @@ describe('linkedAppContext', () => {
6567
app: expect.objectContaining({
6668
configuration: {
6769
client_id: 'test-api-key',
70+
name: 'test-app',
6871
path: normalizePath(joinPath(tmp, 'shopify.app.toml')),
6972
},
7073
}),
@@ -98,7 +101,10 @@ describe('linkedAppContext', () => {
98101
configurationPath: `${tmp}/shopify.app.stg.toml`,
99102
configSource: 'cached',
100103
configurationFileName: 'shopify.app.stg.toml',
101-
basicConfiguration: {client_id: 'test-api-key', path: normalizePath(joinPath(tmp, 'shopify.app.stg.toml'))},
104+
basicConfiguration: {
105+
client_id: 'test-api-key',
106+
path: normalizePath(joinPath(tmp, 'shopify.app.stg.toml')),
107+
},
102108
},
103109
configuration: {
104110
client_id: 'test-api-key',
@@ -133,7 +139,9 @@ describe('linkedAppContext', () => {
133139
await inTemporaryDirectory(async (tmp) => {
134140
// Given
135141
vi.mocked(appFromIdentifiers).mockResolvedValue({...mockRemoteApp, apiKey: 'test-api-key-new'})
136-
const content = `client_id="test-api-key-new"`
142+
const content = `
143+
name = "test-app"
144+
client_id="test-api-key-new"`
137145
await writeAppConfig(tmp, content)
138146
localStorage.setCachedAppInfo({
139147
appId: 'test-api-key-old',
@@ -166,7 +174,9 @@ describe('linkedAppContext', () => {
166174
test('uses provided clientId when available and updates the app configuration', async () => {
167175
await inTemporaryDirectory(async (tmp) => {
168176
// Given
169-
const content = `client_id="test-api-key"`
177+
const content = `
178+
name = "test-app"
179+
client_id="test-api-key"`
170180
await writeAppConfig(tmp, content)
171181
const newClientId = 'new-api-key'
172182

@@ -191,7 +201,9 @@ describe('linkedAppContext', () => {
191201
test('resets app when there is a valid toml but reset option is true', async () => {
192202
await inTemporaryDirectory(async (tmp) => {
193203
// Given
194-
const content = `client_id="test-api-key"`
204+
const content = `
205+
name = "test-app"
206+
client_id="test-api-key"`
195207
await writeAppConfig(tmp, content)
196208

197209
vi.mocked(link).mockResolvedValue({
@@ -202,7 +214,10 @@ describe('linkedAppContext', () => {
202214
configurationPath: `${tmp}/shopify.app.toml`,
203215
configSource: 'cached',
204216
configurationFileName: 'shopify.app.toml',
205-
basicConfiguration: {client_id: 'test-api-key', path: normalizePath(joinPath(tmp, 'shopify.app.toml'))},
217+
basicConfiguration: {
218+
client_id: 'test-api-key',
219+
path: normalizePath(joinPath(tmp, 'shopify.app.toml')),
220+
},
206221
},
207222
configuration: {
208223
client_id: 'test-api-key',
@@ -229,7 +244,9 @@ describe('linkedAppContext', () => {
229244
test('logs metadata', async () => {
230245
await inTemporaryDirectory(async (tmp) => {
231246
// Given
232-
const content = `client_id="test-api-key"`
247+
const content = `
248+
name = "test-app"
249+
client_id="test-api-key"`
233250
await writeAppConfig(tmp, content)
234251

235252
// When
@@ -255,7 +272,9 @@ describe('linkedAppContext', () => {
255272
test('uses unsafeReportMode when provided', async () => {
256273
await inTemporaryDirectory(async (tmp) => {
257274
// Given
258-
const content = `client_id="test-api-key"`
275+
const content = `
276+
name = "test-app"
277+
client_id="test-api-key"`
259278
await writeAppConfig(tmp, content)
260279
const loadSpy = vi.spyOn(loader, 'loadAppUsingConfigurationState')
261280

@@ -278,7 +297,9 @@ describe('linkedAppContext', () => {
278297
test('does not use unsafeReportMode when not provided', async () => {
279298
await inTemporaryDirectory(async (tmp) => {
280299
// Given
281-
const content = `client_id="test-api-key"`
300+
const content = `
301+
name = "test-app"
302+
client_id="test-api-key"`
282303
await writeAppConfig(tmp, content)
283304
const loadSpy = vi.spyOn(loader, 'loadAppUsingConfigurationState')
284305

0 commit comments

Comments
 (0)