Skip to content

Commit f036539

Browse files
Merge pull request #7479 from Shopify/fix-uid-placement-single-extension-array
Fix uid placement for single-entry [[extensions]] TOMLs
2 parents e5701f6 + 35b2aa9 commit f036539

3 files changed

Lines changed: 69 additions & 4 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@shopify/app': patch
3+
---
4+
5+
Fix `uid` being written outside the `[[extensions]]` block in single-entry array-of-tables TOMLs (the shape produced by `shopify app init` templates).

packages/app/src/cli/services/app/add-uid-to-extension-toml.test.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,63 @@ describe('addUidToTomlsIfNecessary', () => {
6767
})
6868
})
6969

70+
test('adds uid inside the [[extensions]] block for a single-entry array TOML (matching the app init template shape)', async () => {
71+
await inTemporaryDirectory(async (tmpDir) => {
72+
// Given — a TOML using the modern `[[extensions]]` array-of-tables shape with a
73+
// single extension. This is the shape produced by `shopify app init` templates.
74+
const tomlPath = joinPath(tmpDir, 'shopify.extension.toml')
75+
const tomlContent = `api_version = "2026-07"
76+
77+
[[extensions]]
78+
# Change the merchant-facing name of the extension in locales/en.default.json
79+
name = "t:name"
80+
handle = "app-home"
81+
type = "ui_extension"
82+
83+
[[extensions.targeting]]
84+
module = "./src/AppHome.jsx"
85+
target = "admin.app.home.render"
86+
87+
[access_scopes]
88+
scopes = "write_metaobject_definitions,write_metaobjects,write_products"
89+
`
90+
await writeFile(tomlPath, tomlContent)
91+
92+
const extension = {
93+
configurationPath: tomlPath,
94+
handle: 'app-home',
95+
isUUIDStrategyExtension: true,
96+
uid: 'abc-123',
97+
configuration: {},
98+
} as ExtensionInstance
99+
100+
const client = testDeveloperPlatformClient({supportsAtomicDeployments: true})
101+
102+
// When
103+
await addUidToTomlsIfNecessary([extension], client)
104+
105+
// Then — uid must be inside the [[extensions]] block (right after handle), not at
106+
// the top level of the file.
107+
const updatedContent = await readFile(tomlPath)
108+
expect(updatedContent).toBe(`api_version = "2026-07"
109+
110+
[[extensions]]
111+
# Change the merchant-facing name of the extension in locales/en.default.json
112+
name = "t:name"
113+
handle = "app-home"
114+
uid = "abc-123"
115+
type = "ui_extension"
116+
117+
[[extensions.targeting]]
118+
module = "./src/AppHome.jsx"
119+
target = "admin.app.home.render"
120+
121+
[access_scopes]
122+
scopes = "write_metaobject_definitions,write_metaobjects,write_products"
123+
`)
124+
})
125+
})
126+
70127
test('adds uid to multi-extension TOML', async () => {
71128
await inTemporaryDirectory(async (tmpDir) => {
72129
// Given

packages/app/src/cli/services/app/add-uid-to-extension-toml.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,20 @@ async function addUidToToml(extension: ExtensionInstance) {
2828
if (currentExtension && 'uid' in currentExtension) return
2929
}
3030

31-
if (extensionsArray && extensionsArray.length > 1) {
32-
// Multi-extension TOML: use regex to insert uid after the correct handle.
31+
if (extensionsArray) {
32+
// [[extensions]] array-of-tables TOML: use regex to insert uid after the correct handle.
3333
// updateTomlValues (WASM) doesn't support patching individual array-of-tables entries,
34-
// so transformRaw with positional insertion is the pragmatic choice here.
34+
// so transformRaw with positional insertion is the pragmatic choice here. This applies
35+
// whether the array has one entry or many — putting `uid` at the top level of the file
36+
// would place it outside the [[extensions]] block, which is the wrong location.
3537
const handle = extension.handle
3638
await file.transformRaw((raw) => {
3739
const regex = new RegExp(`(\\n?(\\s*)handle\\s*=\\s*"${handle}")`)
3840
return raw.replace(regex, `$1\n$2uid = "${extension.uid}"`)
3941
})
4042
} else {
41-
// Single extension (or no extensions array): add uid at the top level via WASM patch
43+
// Legacy single-extension TOML with top-level `type`/`handle` fields: add uid at the
44+
// top level via WASM patch.
4245
await file.patch({uid: extension.uid})
4346
}
4447
}

0 commit comments

Comments
 (0)