@@ -15,7 +15,11 @@ import checkoutPostPurchaseExtension from '../../models/templates/ui-specificati
1515import { ExtensionTemplate } from '../../models/app/template.js'
1616import { describe , expect , vi , test } from 'vitest'
1717import * as output from '@shopify/cli-kit/node/output'
18- import { addNPMDependenciesIfNeeded , addResolutionOrOverride } from '@shopify/cli-kit/node/node-package-manager'
18+ import {
19+ installNodeModules ,
20+ addNPMDependenciesIfNeeded ,
21+ addResolutionOrOverride ,
22+ } from '@shopify/cli-kit/node/node-package-manager'
1923import * as template from '@shopify/cli-kit/node/liquid'
2024import * as file from '@shopify/cli-kit/node/fs'
2125import * as git from '@shopify/cli-kit/node/git'
@@ -28,6 +32,7 @@ vi.mock('@shopify/cli-kit/node/node-package-manager', async () => {
2832 ...actual ,
2933 addNPMDependenciesIfNeeded : vi . fn ( ) ,
3034 addResolutionOrOverride : vi . fn ( ) ,
35+ installNodeModules : vi . fn ( ) ,
3136 }
3237} )
3338
@@ -324,48 +329,52 @@ describe('initialize a extension', async () => {
324329 } )
325330
326331 test ( 'generates a JS function' , async ( ) => {
327- await withTemporaryApp ( async ( tmpDir ) => {
328- // Given
329- const name = 'my-fun-1'
330- const specification = allFunctionTemplates . find ( ( spec ) => spec . identifier === 'order_discounts' ) !
331- const extensionFlavor = 'vanilla-js'
332-
333- vi . spyOn ( git , 'downloadGitRepository' ) . mockResolvedValue ( )
334- vi . spyOn ( extensionsCommon , 'ensureDownloadedExtensionFlavorExists' ) . mockImplementationOnce ( async ( ) => tmpDir )
335- vi . spyOn ( template , 'recursiveLiquidTemplateCopy' ) . mockImplementationOnce ( async ( _origin , destination ) => {
336- await file . writeFile (
337- joinPath ( destination , 'shopify.function.extension.toml' ) ,
338- `name = "my-fun-1"
332+ await withTemporaryApp (
333+ async ( tmpDir ) => {
334+ // Given
335+ const name = 'my-fun-1'
336+ const specification = allFunctionTemplates . find ( ( spec ) => spec . identifier === 'order_discounts' ) !
337+ const extensionFlavor = 'vanilla-js'
338+
339+ vi . spyOn ( git , 'downloadGitRepository' ) . mockResolvedValue ( )
340+ vi . spyOn ( extensionsCommon , 'ensureDownloadedExtensionFlavorExists' ) . mockImplementationOnce ( async ( ) => tmpDir )
341+ vi . spyOn ( template , 'recursiveLiquidTemplateCopy' ) . mockImplementationOnce ( async ( _origin , destination ) => {
342+ await file . writeFile (
343+ joinPath ( destination , 'shopify.function.extension.toml' ) ,
344+ `name = "my-fun-1"
339345 type = "order_discounts"
340346 api_version = "2023-01"
341347
342348 [build]
343349 path = "dist/function.wasm"` ,
344- )
345- await file . mkdir ( joinPath ( destination , 'src' ) )
346- await file . writeFile ( joinPath ( destination , 'src' , 'index' ) , '' )
347- } )
348- const buildGraphqlTypesSpy = vi . spyOn ( functionBuild , 'buildGraphqlTypes' ) . mockResolvedValue ( )
349-
350- // When
351- const extensionDir = await createFromTemplate ( {
352- name,
353- extensionTemplate : specification ,
354- extensionFlavor,
355- appDirectory : tmpDir ,
356- specifications,
357- } )
350+ )
351+ await file . mkdir ( joinPath ( destination , 'src' ) )
352+ await file . writeFile ( joinPath ( destination , 'src' , 'index' ) , '' )
353+ } )
354+ const buildGraphqlTypesSpy = vi . spyOn ( functionBuild , 'buildGraphqlTypes' ) . mockResolvedValue ( )
358355
359- // Then
360- const app = await loadApp ( { directory : tmpDir , specifications} )
361- const generatedFunction = app . extensions . function [ 0 ] !
362- expect ( extensionDir ) . toEqual ( joinPath ( tmpDir , 'extensions' , name ) )
363- expect ( generatedFunction . configuration . name ) . toBe ( name )
364- expect ( generatedFunction . entrySourceFilePath ) . toBe ( joinPath ( extensionDir , 'src' , 'index.js' ) )
356+ // When
357+ const extensionDir = await createFromTemplate ( {
358+ name,
359+ extensionTemplate : specification ,
360+ extensionFlavor,
361+ appDirectory : tmpDir ,
362+ specifications,
363+ } )
365364
366- expect ( addNPMDependenciesIfNeeded ) . toHaveBeenCalledOnce ( )
367- expect ( buildGraphqlTypesSpy ) . toHaveBeenCalledOnce ( )
368- } )
365+ // Then
366+ const app = await loadApp ( { directory : tmpDir , specifications} )
367+ const generatedFunction = app . extensions . function [ 0 ] !
368+ expect ( extensionDir ) . toEqual ( joinPath ( tmpDir , 'extensions' , name ) )
369+ expect ( generatedFunction . configuration . name ) . toBe ( name )
370+ expect ( generatedFunction . entrySourceFilePath ) . toBe ( joinPath ( extensionDir , 'src' , 'index.js' ) )
371+
372+ expect ( installNodeModules ) . toHaveBeenCalledOnce ( )
373+ expect ( addNPMDependenciesIfNeeded ) . toHaveBeenCalledOnce ( )
374+ expect ( buildGraphqlTypesSpy ) . toHaveBeenCalledOnce ( )
375+ } ,
376+ { useWorkspaces : true } ,
377+ )
369378 } )
370379
371380 test ( 'throws an error if there is no folder for selected flavor' , async ( ) => {
@@ -417,7 +426,10 @@ async function createFromTemplate({
417426 } )
418427 return result [ 0 ] ! . directory
419428}
420- async function withTemporaryApp ( callback : ( tmpDir : string ) => Promise < void > | void ) {
429+ async function withTemporaryApp (
430+ callback : ( tmpDir : string ) => Promise < void > | void ,
431+ options ?: { useWorkspaces : boolean } ,
432+ ) {
421433 await file . inTemporaryDirectory ( async ( tmpDir ) => {
422434 const appConfigurationPath = joinPath ( tmpDir , configurationFileNames . app )
423435 const webConfigurationPath = joinPath ( tmpDir , blocks . web . directoryName , blocks . web . configurationName )
@@ -436,7 +448,18 @@ async function withTemporaryApp(callback: (tmpDir: string) => Promise<void> | vo
436448 await file . writeFile ( appConfigurationPath , appConfiguration )
437449 await file . mkdir ( dirname ( webConfigurationPath ) )
438450 await file . writeFile ( webConfigurationPath , webConfiguration )
439- await file . writeFile ( joinPath ( tmpDir , 'package.json' ) , JSON . stringify ( { dependencies : { } , devDependencies : { } } ) )
451+
452+ const packageJsonContents : {
453+ workspaces ?: string [ ]
454+ dependencies : { [ key : string ] : string }
455+ devDependencies : { [ key : string ] : string }
456+ } = { dependencies : { } , devDependencies : { } }
457+
458+ if ( options ?. useWorkspaces ) {
459+ packageJsonContents . workspaces = [ 'extensions/*' ]
460+ }
461+
462+ await file . writeFile ( joinPath ( tmpDir , 'package.json' ) , JSON . stringify ( packageJsonContents ) )
440463 return callback ( tmpDir )
441464 } )
442465}
0 commit comments