Skip to content

Commit fe500a2

Browse files
authored
Merge pull request #7530 from Shopify/05-11-reject_empty_or_whitespace-only_configkey_values_in_include_assets_builds
Reject empty or whitespace-only configKey values in include_assets builds
2 parents 1aee8d0 + 3880b9a commit fe500a2

2 files changed

Lines changed: 59 additions & 0 deletions

File tree

packages/app/src/cli/services/build/steps/include-assets/copy-config-key-entry.test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,4 +354,57 @@ describe('copyConfigKeyEntry', () => {
354354
await expect(fileExists(joinPath(outDir, 'tools.json'))).resolves.toBe(true)
355355
})
356356
})
357+
358+
describe('value guard', () => {
359+
test('throws when value is an empty string', async () => {
360+
await inTemporaryDirectory(async (tmpDir) => {
361+
const outDir = joinPath(tmpDir, 'out')
362+
await mkdir(outDir)
363+
const context = makeContext({assets: ''})
364+
const promise = copyConfigKeyEntry({
365+
key: 'assets',
366+
baseDir: tmpDir,
367+
outputDir: outDir,
368+
context,
369+
appDirectory: tmpDir,
370+
})
371+
await expect(promise).rejects.toThrow(AbortError)
372+
await expect(promise).rejects.toThrow(`'assets' can't be empty.`)
373+
})
374+
})
375+
376+
test('throws when value is whitespace-only', async () => {
377+
await inTemporaryDirectory(async (tmpDir) => {
378+
const outDir = joinPath(tmpDir, 'out')
379+
await mkdir(outDir)
380+
const context = makeContext({assets: ' '})
381+
const promise = copyConfigKeyEntry({
382+
key: 'assets',
383+
baseDir: tmpDir,
384+
outputDir: outDir,
385+
context,
386+
appDirectory: tmpDir,
387+
})
388+
await expect(promise).rejects.toThrow(AbortError)
389+
await expect(promise).rejects.toThrow(`'assets' can't be empty.`)
390+
})
391+
})
392+
393+
test('throws with the full configKey when the key is nested', async () => {
394+
await inTemporaryDirectory(async (tmpDir) => {
395+
const outDir = joinPath(tmpDir, 'out')
396+
await mkdir(outDir)
397+
const context = makeContext({extension_points: [{assets: ''}]})
398+
const promise = copyConfigKeyEntry({
399+
key: 'extension_points[].assets',
400+
baseDir: tmpDir,
401+
outputDir: outDir,
402+
context,
403+
appDirectory: tmpDir,
404+
})
405+
await expect(promise).rejects.toThrow(AbortError)
406+
await expect(promise).rejects.toThrow(`'extension_points[].assets' can't be empty.`)
407+
})
408+
})
409+
})
357410
})

packages/app/src/cli/services/build/steps/include-assets/copy-config-key-entry.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ export async function copyConfigKeyEntry(config: {
5151
paths = []
5252
}
5353

54+
for (const sourcePath of paths) {
55+
if (sourcePath.trim() === '') {
56+
throw new AbortError(`'${key}' can't be empty.`)
57+
}
58+
}
59+
5460
if (paths.length === 0) {
5561
outputDebug(`No value for configKey '${key}', skipping\n`, stdout)
5662
return {filesCopied: 0, pathMap: new Map()}

0 commit comments

Comments
 (0)