11const {
2- promises : { readFile }
2+ promises : { readFile, readdir }
33} = require ( "fs" ) ;
44const { join } = require ( "path" ) ;
55
@@ -21,3 +21,66 @@ const getPackageJson = async () => {
2121} ;
2222
2323exports . getPackageJson = getPackageJson ;
24+
25+ /**
26+ * isModuleInstalled
27+ * @param { name, type } params
28+ * "name" - the name of the dependency
29+ * "type" - "dependency", "devDependency", "peerDependency"
30+ * @returns boolean
31+ */
32+ const isModuleInstalled = async ( { name, type } ) => {
33+ // 1. load package.json file
34+ const json = await getPackageJson ( ) ;
35+
36+ // 2. verify package lists dependency by type
37+ let installCommand ;
38+ let hasDependency ;
39+
40+ switch ( type ) {
41+ case "dependency" :
42+ installCommand = "--save" ;
43+ hasDependency = ! ! json . dependencies && json . dependencies [ name ] ;
44+ break ;
45+ case "devDependency" :
46+ installCommand = "--save-dev" ;
47+ hasDependency = ! ! json . devDependencies && json . devDependencies [ name ] ;
48+ break ;
49+ case "peerDependency" :
50+ throw new Error ( "Peer dependencies unsupported" ) ;
51+ default :
52+ throw new Error ( "Unsupported packaged type" ) ;
53+ }
54+
55+ if ( ! hasDependency ) {
56+ throw new Error ( `Run "npm install ${ installCommand } ${ name } "` ) ;
57+ }
58+
59+ // 3. verify node_module installed
60+ const pathToNodeModule = join ( process . cwd ( ) , "node_modules" , name ) ;
61+ const hasNodeModules = await readdir ( pathToNodeModule ) . catch ( ( ) => {
62+ throw new Error ( 'Missing node_modules. Run "npm install"' ) ;
63+ } ) ;
64+ if ( ! hasNodeModules ) {
65+ throw new Error ( 'Missing node_modules. Run "npm install"' ) ;
66+ }
67+
68+ // 4. is installed
69+ return true ;
70+ } ;
71+
72+ exports . isModuleInstalled = isModuleInstalled ;
73+
74+ // created because assert.doesNotThrow not working predictably with async fns
75+ const doesNotThrow = async fn => {
76+ let result = true ;
77+ try {
78+ await fn ( ) ;
79+ } catch ( error ) {
80+ console . error ( error ) ;
81+ result = false ;
82+ }
83+ return result ;
84+ } ;
85+
86+ exports . doesNotThrow = doesNotThrow ;
0 commit comments