Skip to content

Commit 42c916d

Browse files
committed
Fix dev issues with manifest generation and files copying
Include built assets in the manifest.json Allow serving static assets from the extensions directory
1 parent 8529847 commit 42c916d

11 files changed

Lines changed: 297 additions & 286 deletions

File tree

packages/app/src/cli/models/extensions/specifications/ui_extension.test.ts

Lines changed: 9 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -77,64 +77,6 @@ describe('ui_extension', async () => {
7777
})
7878
}
7979

80-
async function setupToolsExtension(
81-
tmpDir: string,
82-
options: {tools?: string; instructions?: string; createFiles?: boolean} = {},
83-
) {
84-
await mkdir(joinPath(tmpDir, 'src'))
85-
await touchFile(joinPath(tmpDir, 'src', 'ExtensionPointA.js'))
86-
87-
if (options.createFiles) {
88-
if (options.tools) {
89-
await writeFile(joinPath(tmpDir, options.tools), '{"tools": []}')
90-
}
91-
if (options.instructions) {
92-
await writeFile(joinPath(tmpDir, options.instructions), '# Instructions')
93-
}
94-
}
95-
96-
const allSpecs = await loadLocalExtensionsSpecifications()
97-
const specification = allSpecs.find((spec) => spec.identifier === 'ui_extension')!
98-
99-
const targetConfig: any = {
100-
target: 'EXTENSION::POINT::A',
101-
module: './src/ExtensionPointA.js',
102-
}
103-
104-
if (options.tools) targetConfig.tools = options.tools
105-
if (options.instructions) targetConfig.instructions = options.instructions
106-
107-
const configuration = {
108-
targeting: [targetConfig],
109-
api_version: '2023-01' as const,
110-
name: 'UI Extension',
111-
description: 'This is an ordinary test extension',
112-
type: 'ui_extension',
113-
handle: 'test-ui-extension',
114-
capabilities: {
115-
block_progress: false,
116-
network_access: false,
117-
api_access: false,
118-
collect_buyer_consent: {
119-
customer_privacy: true,
120-
sms_marketing: false,
121-
},
122-
iframe: {
123-
sources: [],
124-
},
125-
},
126-
settings: {},
127-
}
128-
129-
const parsed = specification.parseConfigurationObject(configuration)
130-
if (parsed.state !== 'ok') {
131-
throw new Error("Couldn't parse configuration")
132-
}
133-
134-
const result = await specification.validate?.(parsed.data, joinPath(tmpDir, 'shopify.extension.toml'), tmpDir)
135-
return {result, tmpDir}
136-
}
137-
13880
describe('validate()', () => {
13981
test('returns ok({}) if there are no errors', async () => {
14082
await inTemporaryDirectory(async (tmpDir) => {
@@ -208,6 +150,7 @@ describe('ui_extension', async () => {
208150
target: 'EXTENSION::POINT::A',
209151
tools: undefined,
210152
instructions: undefined,
153+
intents: undefined,
211154
module: './src/ExtensionPointA.js',
212155
metafields: [{namespace: 'test', key: 'test'}],
213156
default_placement_reference: undefined,
@@ -275,6 +218,7 @@ describe('ui_extension', async () => {
275218
target: 'EXTENSION::POINT::A',
276219
tools: undefined,
277220
instructions: undefined,
221+
intents: undefined,
278222
module: './src/ExtensionPointA.js',
279223
metafields: [],
280224
default_placement_reference: 'PLACEMENT_REFERENCE1',
@@ -338,6 +282,7 @@ describe('ui_extension', async () => {
338282
target: 'EXTENSION::POINT::A',
339283
tools: undefined,
340284
instructions: undefined,
285+
intents: undefined,
341286
module: './src/ExtensionPointA.js',
342287
metafields: [],
343288
urls: {},
@@ -401,6 +346,7 @@ describe('ui_extension', async () => {
401346
target: 'EXTENSION::POINT::A',
402347
tools: undefined,
403348
instructions: undefined,
349+
intents: undefined,
404350
module: './src/ExtensionPointA.js',
405351
metafields: [],
406352
default_placement_reference: undefined,
@@ -467,6 +413,7 @@ describe('ui_extension', async () => {
467413
target: 'EXTENSION::POINT::A',
468414
tools: undefined,
469415
instructions: undefined,
416+
intents: undefined,
470417
module: './src/ExtensionPointA.js',
471418
metafields: [],
472419
default_placement_reference: undefined,
@@ -535,6 +482,7 @@ describe('ui_extension', async () => {
535482
target: 'EXTENSION::POINT::A',
536483
tools: undefined,
537484
instructions: undefined,
485+
intents: undefined,
538486
module: './src/ExtensionPointA.js',
539487
metafields: [],
540488
default_placement_reference: undefined,
@@ -603,6 +551,7 @@ describe('ui_extension', async () => {
603551
module: './src/ExtensionPointA.js',
604552
tools: './tools.json',
605553
instructions: undefined,
554+
intents: undefined,
606555
metafields: [],
607556
default_placement_reference: undefined,
608557
capabilities: undefined,
@@ -613,11 +562,6 @@ describe('ui_extension', async () => {
613562
filepath: 'test-ui-extension.js',
614563
module: './src/ExtensionPointA.js',
615564
},
616-
tools: {
617-
filepath: 'test-ui-extension-tools-tools.json',
618-
module: './tools.json',
619-
static: true,
620-
},
621565
},
622566
},
623567
urls: {},
@@ -671,6 +615,7 @@ describe('ui_extension', async () => {
671615
module: './src/ExtensionPointA.js',
672616
tools: undefined,
673617
instructions: './instructions.md',
618+
intents: undefined,
674619
metafields: [],
675620
default_placement_reference: undefined,
676621
capabilities: undefined,
@@ -681,11 +626,6 @@ describe('ui_extension', async () => {
681626
filepath: 'test-ui-extension.js',
682627
module: './src/ExtensionPointA.js',
683628
},
684-
instructions: {
685-
filepath: 'test-ui-extension-instructions-instructions.md',
686-
module: './instructions.md',
687-
static: true,
688-
},
689629
},
690630
},
691631
urls: {},
@@ -791,66 +731,6 @@ Please check the configuration in ${uiExtension.configurationPath}`),
791731
})
792732
})
793733

794-
test('shows an error when the tools file is missing', async () => {
795-
await inTemporaryDirectory(async (tmpDir) => {
796-
const {result} = await setupToolsExtension(tmpDir, {tools: './tools.json'})
797-
798-
const notFoundPath = joinPath(tmpDir, './tools.json')
799-
expect(result).toEqual(
800-
err(`Couldn't find ${notFoundPath}
801-
Please check the tools path for EXTENSION::POINT::A
802-
803-
Please check the configuration in ${joinPath(tmpDir, 'shopify.extension.toml')}`),
804-
)
805-
})
806-
})
807-
808-
test('shows an error when the instructions file is missing', async () => {
809-
await inTemporaryDirectory(async (tmpDir) => {
810-
const {result} = await setupToolsExtension(tmpDir, {instructions: './instructions.md'})
811-
812-
const notFoundPath = joinPath(tmpDir, './instructions.md')
813-
expect(result).toEqual(
814-
err(`Couldn't find ${notFoundPath}
815-
Please check the instructions path for EXTENSION::POINT::A
816-
817-
Please check the configuration in ${joinPath(tmpDir, 'shopify.extension.toml')}`),
818-
)
819-
})
820-
})
821-
822-
test('shows multiple errors when both tools and instructions files are missing', async () => {
823-
await inTemporaryDirectory(async (tmpDir) => {
824-
const {result} = await setupToolsExtension(tmpDir, {
825-
tools: './tools.json',
826-
instructions: './instructions.md',
827-
})
828-
829-
const toolsNotFoundPath = joinPath(tmpDir, './tools.json')
830-
const instructionsNotFoundPath = joinPath(tmpDir, './instructions.md')
831-
expect(result).toEqual(
832-
err(`Couldn't find ${toolsNotFoundPath}
833-
Please check the tools path for EXTENSION::POINT::A
834-
835-
Couldn't find ${instructionsNotFoundPath}
836-
Please check the instructions path for EXTENSION::POINT::A
837-
838-
Please check the configuration in ${joinPath(tmpDir, 'shopify.extension.toml')}`),
839-
)
840-
})
841-
})
842-
843-
test('succeeds when both tools and instructions files exist', async () => {
844-
await inTemporaryDirectory(async (tmpDir) => {
845-
const {result} = await setupToolsExtension(tmpDir, {
846-
tools: './tools.json',
847-
instructions: './instructions.md',
848-
createFiles: true,
849-
})
850-
851-
expect(result).toStrictEqual(ok({}))
852-
})
853-
})
854734

855735
test('build_manifest includes both tools and instructions when both are present', async () => {
856736
const allSpecs = await loadLocalExtensionsSpecifications()
@@ -899,6 +779,7 @@ Please check the configuration in ${joinPath(tmpDir, 'shopify.extension.toml')}`
899779
module: './src/ExtensionPointA.js',
900780
tools: './tools.json',
901781
instructions: './instructions.md',
782+
intents: undefined,
902783
metafields: [],
903784
default_placement_reference: undefined,
904785
capabilities: undefined,
@@ -909,16 +790,6 @@ Please check the configuration in ${joinPath(tmpDir, 'shopify.extension.toml')}`
909790
filepath: 'test-ui-extension.js',
910791
module: './src/ExtensionPointA.js',
911792
},
912-
tools: {
913-
filepath: 'test-ui-extension-tools-tools.json',
914-
module: './tools.json',
915-
static: true,
916-
},
917-
instructions: {
918-
filepath: 'test-ui-extension-instructions-instructions.md',
919-
module: './instructions.md',
920-
static: true,
921-
},
922793
},
923794
},
924795
urls: {},

packages/app/src/cli/models/extensions/specifications/ui_extension.ts

Lines changed: 10 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {ExtensionInstance} from '../extension-instance.js'
1414
import {formatContent} from '../../../utilities/file-formatter.js'
1515
import {err, ok, Result} from '@shopify/cli-kit/node/result'
1616
import {copyFile, fileExists, readFile} from '@shopify/cli-kit/node/fs'
17-
import {joinPath, basename, dirname} from '@shopify/cli-kit/node/path'
17+
import {joinPath, dirname} from '@shopify/cli-kit/node/path'
1818
import {outputContent, outputToken, outputWarn} from '@shopify/cli-kit/node/output'
1919
import {zod} from '@shopify/cli-kit/node/schema'
2020

@@ -61,24 +61,6 @@ export const UIExtensionSchema = BaseSchema.extend({
6161
},
6262
}
6363
: null),
64-
...(targeting.tools
65-
? {
66-
[AssetIdentifier.Tools]: {
67-
filepath: `${config.handle}-${AssetIdentifier.Tools}-${basename(targeting.tools)}`,
68-
module: targeting.tools,
69-
static: true,
70-
},
71-
}
72-
: null),
73-
...(targeting.instructions
74-
? {
75-
[AssetIdentifier.Instructions]: {
76-
filepath: `${config.handle}-${AssetIdentifier.Instructions}-${basename(targeting.instructions)}`,
77-
module: targeting.instructions,
78-
static: true,
79-
},
80-
}
81-
: null),
8264
},
8365
}
8466

@@ -93,6 +75,7 @@ export const UIExtensionSchema = BaseSchema.extend({
9375
build_manifest: buildManifest,
9476
tools: targeting.tools,
9577
instructions: targeting.instructions,
78+
intents: targeting.intents,
9679
}
9780
})
9881
return {...config, extension_points: extensionPoints}
@@ -115,24 +98,25 @@ const uiExtensionSpec = createExtensionSpecification({
11598
type: 'include_assets',
11699
config: {
117100
generatesAssetsManifest: true,
101+
builtAssets: {anchor: 'extension_points[]', groupBy: 'target', key: 'build_manifest'},
118102
inclusions: [
119103
{
120104
type: 'configKey',
121-
anchor: 'targeting[]',
105+
anchor: 'extension_points[]',
122106
groupBy: 'target',
123-
key: 'targeting[].tools',
107+
key: 'extension_points[].tools',
124108
},
125109
{
126110
type: 'configKey',
127-
anchor: 'targeting[]',
111+
anchor: 'extension_points[]',
128112
groupBy: 'target',
129-
key: 'targeting[].instructions',
113+
key: 'extension_points[].instructions',
130114
},
131115
{
132116
type: 'configKey',
133-
anchor: 'targeting[]',
117+
anchor: 'extension_points[]',
134118
groupBy: 'target',
135-
key: 'targeting[].intents[].schema',
119+
key: 'extension_points[].intents[].schema',
136120
},
137121
],
138122
},
@@ -415,33 +399,13 @@ async function validateUIExtensionPointConfig(
415399
}
416400

417401
for await (const extensionPoint of extensionPoints) {
418-
const {module, target, build_manifest: buildManifest} = extensionPoint
402+
const {module, target} = extensionPoint
419403

420404
const missingModuleError = await checkForMissingPath(directory, module, target, 'module')
421405
if (missingModuleError) {
422406
errors.push(missingModuleError)
423407
}
424408

425-
const missingToolsError = await checkForMissingPath(
426-
directory,
427-
buildManifest?.assets[AssetIdentifier.Tools]?.module,
428-
target,
429-
AssetIdentifier.Tools,
430-
)
431-
if (missingToolsError) {
432-
errors.push(missingToolsError)
433-
}
434-
435-
const missingInstructionsError = await checkForMissingPath(
436-
directory,
437-
buildManifest?.assets[AssetIdentifier.Instructions]?.module,
438-
target,
439-
AssetIdentifier.Instructions,
440-
)
441-
if (missingInstructionsError) {
442-
errors.push(missingInstructionsError)
443-
}
444-
445409
if (uniqueTargets.includes(target)) {
446410
duplicateTargets.push(target)
447411
} else {

0 commit comments

Comments
 (0)