UNPKG

4.02 kBJavaScriptView Raw
1var check = require('check-more-types');
2
3function loadPackage() {
4 var filename = './package.json';
5 var fs = require('fs');
6 if (fs.existsSync(filename)) {
7 var txt = fs.readFileSync(filename, 'utf-8');
8 if (txt) {
9 return JSON.parse(txt);
10 }
11 }
12}
13
14function saveOption(type) {
15 var saveCommands = {
16 dependencies: '--save --save-exact',
17 devDependencies: '--save-dev --save-exact',
18 peerDependencies: '--save-peer --save-exact'
19 };
20 return saveCommands[type];
21}
22
23function splitByType(updates, pkg) {
24 check.verify.array(updates, 'expected array of updates');
25 check.verify.object(pkg, 'expected package object');
26
27 var result = {
28 dependencies: [],
29 devDependencies: [],
30 peerDependencies: []
31 };
32
33 updates.forEach(function (moduleList) {
34 if (!moduleList.length) {
35 return;
36 }
37 var moduleName = moduleList[0].name;
38 check.verify.string(moduleName, 'missing module name');
39 if (pkg.dependencies && pkg.dependencies[moduleName]) {
40 result.dependencies.push(moduleList);
41 } else if (pkg.devDependencies && pkg.devDependencies[moduleName]) {
42 result.devDependencies.push(moduleList);
43 } else if (pkg.peerDependencies && pkg.peerDependencies[moduleName]) {
44 result.peerDependencies.push(moduleList);
45 } else {
46 console.warn('Could not find dependency for', moduleName, 'assuming normal');
47 result.dependencies.push(moduleList);
48 }
49 });
50 return result;
51}
52
53function installCommand(updates) {
54 check.verify.array(updates, 'expected array of updates');
55 if (!updates.length) {
56 return;
57 }
58
59 var cmd = '';
60 var pkg = loadPackage();
61 if (!pkg) {
62 // assume all dependencies are normal
63 cmd = installCommandType(updates, 'dependencies');
64 } else {
65
66 var updatesByDependencyType = splitByType(updates, pkg);
67 console.assert(updatesByDependencyType, 'could not split updates by type');
68
69 // console.log(updatesByDependencyType)
70
71 var depCmd = installCommandType(updatesByDependencyType.dependencies, 'dependencies');
72 var devCmd = installCommandType(updatesByDependencyType.devDependencies, 'devDependencies');
73 var peerCmd = installCommandType(updatesByDependencyType.peerDependencies,
74 'peerDependencies');
75 if (depCmd) {
76 cmd += depCmd + '\n';
77 }
78 if (devCmd) {
79 cmd += devCmd + '\n';
80 }
81 if (peerCmd) {
82 cmd += peerCmd + '\n';
83 }
84 }
85 if (cmd) {
86 return cmd;
87 }
88}
89
90function getLatestWorkingVersion(versions) {
91 check.verify.array(versions, 'expected array of versions');
92 var working;
93 versions.forEach(function (info) {
94 check.verify.string(info.name, 'missing package name ' + info);
95 if (info.works) {
96 working = info;
97 }
98 });
99
100 return working;
101}
102
103function setWorkingVersion(updates) {
104 updates.forEach(function (moduleVersions) {
105 moduleVersions.latestWorkingVersion = getLatestWorkingVersion(moduleVersions);
106 });
107}
108
109function installCommandType(updates, type) {
110 check.verify.array(updates, 'expected array of updates');
111 if (!updates.length) {
112 return;
113 }
114 check.verify.string(type, 'missing type');
115
116 var saveCommand = saveOption(type);
117 if (!saveCommand) {
118 throw new Error('invalid dependency type ' + type);
119 }
120
121 setWorkingVersion(updates);
122
123 var originalCmd, cmd;
124 originalCmd = cmd = 'npm install ' + saveCommand;
125 updates.forEach(function (moduleVersions) {
126 var latestWorkingVersion = moduleVersions.latestWorkingVersion;
127 if (latestWorkingVersion) {
128 cmd += ' ' + latestWorkingVersion.name + '@' + latestWorkingVersion.version;
129 }
130 });
131
132 if (originalCmd === cmd) {
133 return;
134 }
135
136 return cmd;
137}
138
139module.exports = installCommand;