3
3
} = require ( "fs" ) ;
4
4
const { join} = require ( "path" ) ;
5
5
6
- const getPackageJson = async ( ) => {
6
+ const getPackageJson = async ( dir = process . cwd ( ) ) => {
7
7
// load package.json file
8
- const pathToPackageJson = join ( process . cwd ( ) , "package.json" ) ;
8
+ const pathToPackageJson = join ( dir , "package.json" ) ;
9
9
const packageJson = await readFile ( pathToPackageJson , "utf8" ) . catch (
10
10
console . error
11
11
) ;
@@ -22,29 +22,40 @@ const getPackageJson = async () => {
22
22
23
23
exports . getPackageJson = getPackageJson ;
24
24
25
+ const versionMatch = ( current , expected ) => {
26
+ let currentSemver = current ;
27
+ if ( [ "~" , "^" ] . includes ( current [ 0 ] ) ) {
28
+ currentSemver = current . substring ( 1 ) ;
29
+ }
30
+ return currentSemver === expected ;
31
+ } ;
32
+
25
33
/**
26
34
* isModuleInstalled
27
35
*@param { name, type } params
28
36
* "name" - the name of the dependency
29
37
* "type" - "dependency", "devDependency", "peerDependency"
30
38
*@returns boolean
31
39
*/
32
- const isModuleInstalled = async ( { name, type} ) => {
40
+ const isModuleInstalled = async ( { name, type, version } ) => {
33
41
// 1. load package.json file
34
42
const json = await getPackageJson ( ) ;
35
43
36
44
// 2. verify package lists dependency by type
37
45
let installCommand ;
38
46
let hasDependency ;
47
+ let currentVersion ;
39
48
40
49
switch ( type ) {
41
50
case "dependency" :
42
51
installCommand = "--save" ;
43
52
hasDependency = ! ! json . dependencies && json . dependencies [ name ] ;
53
+ currentVersion = json . dependencies [ name ] ;
44
54
break ;
45
55
case "devDependency" :
46
56
installCommand = "--save-dev" ;
47
57
hasDependency = ! ! json . devDependencies && json . devDependencies [ name ] ;
58
+ currentVersion = json . devDependencies [ name ] ;
48
59
break ;
49
60
case "peerDependency" :
50
61
throw new Error ( "Peer dependencies unsupported" ) ;
@@ -56,7 +67,14 @@ const isModuleInstalled = async ({ name, type }) => {
56
67
throw new Error ( `Run "npm install${ installCommand } ${ name } "` ) ;
57
68
}
58
69
59
- // 3. verify node_module installed
70
+ // 3. if version, check dependency version
71
+ if ( version && ! versionMatch ( currentVersion , version ) ) {
72
+ throw new Error (
73
+ `Dependency${ name } version${ currentVersion } does not match expected${ version } `
74
+ ) ;
75
+ }
76
+
77
+ // 4. verify node_module installed
60
78
const pathToNodeModule = join ( process . cwd ( ) , "node_modules" , name ) ;
61
79
const hasNodeModules = await readdir ( pathToNodeModule ) . catch ( ( ) => {
62
80
throw new Error ( 'Missing node_modules. Run "npm install"' ) ;
@@ -65,7 +83,16 @@ const isModuleInstalled = async ({ name, type }) => {
65
83
throw new Error ( 'Missing node_modules. Run "npm install"' ) ;
66
84
}
67
85
68
- // 4. is installed
86
+ // 5. if version, has installed node_module version
87
+ if ( version ) {
88
+ const nodeModulePackageJson = await getPackageJson ( pathToNodeModule ) ;
89
+ if ( ! versionMatch ( nodeModulePackageJson . version , version ) ) {
90
+ throw new Error (
91
+ `Dependency${ name } version${ version } is not yet installed. Run "npm install"`
92
+ ) ;
93
+ }
94
+ }
95
+
69
96
return true ;
70
97
} ;
71
98