@@ -12,6 +12,7 @@ import {
1212 addResolutionOrOverride ,
1313 writePackageJSON ,
1414 getPackageManager ,
15+ packageManagerBinaryCommandForDirectory ,
1516 installNPMDependenciesRecursively ,
1617 addNPMDependencies ,
1718 DependencyVersion ,
@@ -892,6 +893,21 @@ describe('getPackageManager', () => {
892893 } )
893894 } )
894895
896+ test ( 'finds if bun is being used from bun.lock' , async ( ) => {
897+ await inTemporaryDirectory ( async ( tmpDir ) => {
898+ // Given
899+ await writePackageJSON ( tmpDir , { name : 'mock name' } )
900+ await writeFile ( joinPath ( tmpDir , 'bun.lock' ) , '' )
901+ mockedCaptureOutput . mockReturnValueOnce ( Promise . resolve ( tmpDir ) )
902+
903+ // When
904+ const packageManager = await getPackageManager ( tmpDir )
905+
906+ // Then
907+ expect ( packageManager ) . toEqual ( 'bun' )
908+ } )
909+ } )
910+
895911 test ( 'falls back to packageManagerFromUserAgent when npm prefix fails' , async ( ) => {
896912 await inTemporaryDirectory ( async ( tmpDir ) => {
897913 // Given
@@ -927,6 +943,133 @@ describe('getPackageManager', () => {
927943 } )
928944} )
929945
946+ describe ( 'packageManagerBinaryCommandForDirectory' , ( ) => {
947+ test ( 'uses npm exec with -- for npm' , async ( ) => {
948+ await inTemporaryDirectory ( async ( tmpDir ) => {
949+ await writePackageJSON ( tmpDir , { name : 'mock name' } )
950+
951+ await expect (
952+ packageManagerBinaryCommandForDirectory ( tmpDir , 'graphql-code-generator' , '--config' , 'package.json' ) ,
953+ ) . resolves . toEqual ( {
954+ command : 'npm' ,
955+ args : [ 'exec' , '--' , 'graphql-code-generator' , '--config' , 'package.json' ] ,
956+ } )
957+ } )
958+ } )
959+
960+ test ( 'uses exec without -- for pnpm when detected from an ancestor workspace marker' , async ( ) => {
961+ await inTemporaryDirectory ( async ( tmpDir ) => {
962+ await writePackageJSON ( tmpDir , { name : 'app-root' } )
963+ await writeFile ( joinPath ( tmpDir , 'pnpm-workspace.yaml' ) , '' )
964+ const extensionDirectory = joinPath ( tmpDir , 'extensions' , 'my-function' )
965+ await mkdir ( extensionDirectory )
966+ await writePackageJSON ( extensionDirectory , { name : 'my-function' } )
967+
968+ await expect (
969+ packageManagerBinaryCommandForDirectory (
970+ extensionDirectory ,
971+ 'graphql-code-generator' ,
972+ '--config' ,
973+ 'package.json' ,
974+ ) ,
975+ ) . resolves . toEqual ( {
976+ command : 'pnpm' ,
977+ args : [ 'exec' , 'graphql-code-generator' , '--config' , 'package.json' ] ,
978+ } )
979+ } )
980+ } )
981+
982+ test ( 'uses yarn run when detected from yarn.lock' , async ( ) => {
983+ await inTemporaryDirectory ( async ( tmpDir ) => {
984+ await writePackageJSON ( tmpDir , { name : 'mock name' } )
985+ await writeFile ( joinPath ( tmpDir , 'yarn.lock' ) , '' )
986+
987+ await expect (
988+ packageManagerBinaryCommandForDirectory ( tmpDir , 'graphql-code-generator' , '--config' , 'package.json' ) ,
989+ ) . resolves . toEqual ( {
990+ command : 'yarn' ,
991+ args : [ 'run' , 'graphql-code-generator' , '--config' , 'package.json' ] ,
992+ } )
993+ } )
994+ } )
995+
996+ test ( 'uses bun x for bun when detected from bun.lock' , async ( ) => {
997+ await inTemporaryDirectory ( async ( tmpDir ) => {
998+ await writePackageJSON ( tmpDir , { name : 'mock name' } )
999+ await writeFile ( joinPath ( tmpDir , 'bun.lock' ) , '' )
1000+
1001+ await expect (
1002+ packageManagerBinaryCommandForDirectory ( tmpDir , 'graphql-code-generator' , '--config' , 'package.json' ) ,
1003+ ) . resolves . toEqual ( {
1004+ command : 'bun' ,
1005+ args : [ 'x' , 'graphql-code-generator' , '--config' , 'package.json' ] ,
1006+ } )
1007+ } )
1008+ } )
1009+
1010+ test ( 'uses bun x for bun when detected from bun.lockb' , async ( ) => {
1011+ await inTemporaryDirectory ( async ( tmpDir ) => {
1012+ await writePackageJSON ( tmpDir , { name : 'mock name' } )
1013+ await writeFile ( joinPath ( tmpDir , 'bun.lockb' ) , '' )
1014+
1015+ await expect (
1016+ packageManagerBinaryCommandForDirectory ( tmpDir , 'graphql-code-generator' , '--config' , 'package.json' ) ,
1017+ ) . resolves . toEqual ( {
1018+ command : 'bun' ,
1019+ args : [ 'x' , 'graphql-code-generator' , '--config' , 'package.json' ] ,
1020+ } )
1021+ } )
1022+ } )
1023+
1024+ test ( 'falls back to yarn run when the user agent is yarn' , async ( ) => {
1025+ await inTemporaryDirectory ( async ( tmpDir ) => {
1026+ const extensionDirectory = joinPath ( tmpDir , 'subdir' )
1027+ await mkdir ( extensionDirectory )
1028+ vi . stubEnv ( 'npm_config_user_agent' , 'yarn/1.22.0' )
1029+
1030+ try {
1031+ await expect (
1032+ packageManagerBinaryCommandForDirectory (
1033+ extensionDirectory ,
1034+ 'graphql-code-generator' ,
1035+ '--config' ,
1036+ 'package.json' ,
1037+ ) ,
1038+ ) . resolves . toEqual ( {
1039+ command : 'yarn' ,
1040+ args : [ 'run' , 'graphql-code-generator' , '--config' , 'package.json' ] ,
1041+ } )
1042+ } finally {
1043+ vi . unstubAllEnvs ( )
1044+ }
1045+ } )
1046+ } )
1047+
1048+ test ( 'falls back to npm when no package manager markers or user agent are available' , async ( ) => {
1049+ await inTemporaryDirectory ( async ( tmpDir ) => {
1050+ const extensionDirectory = joinPath ( tmpDir , 'subdir' )
1051+ await mkdir ( extensionDirectory )
1052+ vi . stubEnv ( 'npm_config_user_agent' , '' )
1053+
1054+ try {
1055+ await expect (
1056+ packageManagerBinaryCommandForDirectory (
1057+ extensionDirectory ,
1058+ 'graphql-code-generator' ,
1059+ '--config' ,
1060+ 'package.json' ,
1061+ ) ,
1062+ ) . resolves . toEqual ( {
1063+ command : 'npm' ,
1064+ args : [ 'exec' , '--' , 'graphql-code-generator' , '--config' , 'package.json' ] ,
1065+ } )
1066+ } finally {
1067+ vi . unstubAllEnvs ( )
1068+ }
1069+ } )
1070+ } )
1071+ } )
1072+
9301073describe ( 'addNPMDependencies' , ( ) => {
9311074 test ( 'when using npm with multiple dependencies they should be installed one by one, adding --save-exact if needed' , async ( ) => {
9321075 await inTemporaryDirectory ( async ( tmpDir ) => {
0 commit comments