backend-manager 4.0.8 → 4.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/cli/cli.js +153 -206
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backend-manager",
3
- "version": "4.0.8",
3
+ "version": "4.0.9",
4
4
  "description": "Quick tools for developing Firebase functions",
5
5
  "main": "src/manager/index.js",
6
6
  "bin": {
package/src/cli/cli.js CHANGED
@@ -13,7 +13,6 @@ const log = console.log;
13
13
  const Npm = require('npm-api');
14
14
  const semver = require('semver');
15
15
  const inquirer = require('inquirer');
16
- const { spawn, child, exec, fork } = require('child_process');
17
16
  const JSON5 = require('json5');
18
17
  const fetch = require('wonderful-fetch');
19
18
  const argv = require('yargs').argv;
@@ -120,16 +119,10 @@ Main.prototype.process = async function (args) {
120
119
  await cmd_configGet(self);
121
120
  await self.setup();
122
121
 
123
- let port = self.argv.port || _.get(self.argv, '_', [])[1] || '5000';
124
- let ls = spawn(`firebase serve --port ${port}`, {shell: true});
122
+ const port = self.argv.port || _.get(self.argv, '_', [])[1] || '5000';
125
123
 
126
- ls.stdout.on('data', (data) => {
127
- console.log(`${cleanOutput(data)}`);
128
- });
129
- ls.stderr.on('data', (data) => {
130
- console.error(chalk.red(`${cleanOutput(data)}`));
131
- // ls = null;
132
- });
124
+ // Execute
125
+ await powertools.execute(`firebase serve --port ${port}`, { log: true })
133
126
  }
134
127
 
135
128
  // Get indexes
@@ -172,53 +165,27 @@ Main.prototype.process = async function (args) {
172
165
  log(chalk.red(`Please remove local packages before deploying!`));
173
166
  return;
174
167
  }
175
- // let ls = spawn('firebase', ['deploy', '--only', 'functions']);
176
- // let ls = spawn('firebase', ['deploy', '--only', 'functions,firestore:rules']);
177
- let ls = spawn('firebase deploy --only functions,firestore:rules', {shell: true});
178
- ls.stdout.on('data', (data) => {
179
- // console.log(`${cleanOutput(data)}`);
180
- console.log(`${cleanOutput(data)}`);
181
- });
182
- ls.stderr.on('data', (data) => {
183
- console.error(chalk.red(`${cleanOutput(data)}`));
184
- // ls = null;
185
- });
168
+
169
+ // Execute
170
+ await powertools.execute('firebase deploy', { log: true })
186
171
  }
187
172
 
188
173
  // Test
189
174
  if (self.options['test']) {
190
175
  await self.setup();
191
- // firebase emulators:exec --only firestore 'npm test'
192
- // let ls = spawn('firebase', ['emulators:exec', '--only', 'firestore', 'npm test']);
176
+
177
+ // Execute
193
178
  // https://stackoverflow.com/questions/9722407/how-do-you-install-and-run-mocha-the-node-js-testing-module-getting-mocha-co
194
- let ls = spawn(`firebase emulators:exec --only firestore "npx ${MOCHA_PKG_SCRIPT}"`, {shell: true});
195
- ls.stdout.on('data', (data) => {
196
- console.log(`${cleanOutput(data)}`);
197
- });
198
- ls.stderr.on('data', (data) => {
199
- console.error(chalk.red(`${cleanOutput(data)}`));
200
- });
179
+ await powertools.execute(`firebase emulators:exec --only firestore "npx ${MOCHA_PKG_SCRIPT}"`, { log: true })
201
180
  }
202
181
 
203
182
  // Clean
204
183
  if (self.options['clean:npm']) {
205
184
  // await self.setup();
206
- // firebase emulators:exec --only firestore 'npm test'
207
- let ls = spawn(`${NPM_CLEAN_SCRIPT}`, {shell: true});
208
- ls.stdout.on('data', (data) => {
209
- console.log(`${cleanOutput(data)}`);
210
- });
211
- ls.stderr.on('data', (data) => {
212
- console.error(chalk.red(`${cleanOutput(data)}`));
213
- });
214
- }
215
-
216
- // if (self.options['url']) {
217
- // // await self.setup();
218
- // // firebase emulators:exec --only firestore 'npm test'
219
- // log(self.projectUrl)
220
- // }
221
185
 
186
+ // Execute
187
+ await powertools.execute(`${NPM_CLEAN_SCRIPT}`, { log: true })
188
+ }
222
189
  };
223
190
 
224
191
  module.exports = Main;
@@ -539,12 +506,12 @@ Main.prototype.setup = async function () {
539
506
  const containsCore = contents.match(bem_allRulesRegex);
540
507
  const matchesVersion = contents.match(self.default.rulesVersionRegex);
541
508
 
542
- return (!!exists && !!containsCore && !!matchesVersion);
509
+ return (exists && !!containsCore && !!matchesVersion);
543
510
  }, fix_firestoreRulesFile);
544
511
 
545
512
  await self.test('update firestore indexes file', function () {
546
513
  const exists = jetpack.exists(`${self.firebaseProjectPath}/firestore.indexes.json`);
547
- return (!!exists);
514
+ return exists;
548
515
  }, fix_firestoreIndexesFile);
549
516
 
550
517
  await self.test('update realtime rules file', function () {
@@ -553,22 +520,22 @@ Main.prototype.setup = async function () {
553
520
  const containsCore = contents.match(bem_allRulesRegex);
554
521
  const matchesVersion = contents.match(self.default.rulesVersionRegex);
555
522
 
556
- return (!!exists && !!containsCore && !!matchesVersion);
523
+ return (exists && !!containsCore && !!matchesVersion);
557
524
  }, fix_realtimeRulesFile);
558
525
 
559
526
  await self.test('update storage rules file', function () {
560
- let exists = jetpack.exists(`${self.firebaseProjectPath}/storage.rules`);
561
- return (!!exists);
527
+ const exists = jetpack.exists(`${self.firebaseProjectPath}/storage.rules`);
528
+ return exists;
562
529
  }, fix_storageRulesFile);
563
530
 
564
531
  await self.test('update remoteconfig template file', function () {
565
- let exists = jetpack.exists(`${self.firebaseProjectPath}/remoteconfig.template.json`);
566
- return (!!exists);
532
+ const exists = jetpack.exists(`${self.firebaseProjectPath}/functions/remoteconfig.template.json`);
533
+ return exists;
567
534
  }, fix_remoteconfigTemplateFile);
568
535
 
569
536
  // Hosting
570
537
  await self.test('hosting is set to dedicated folder in JSON', function () {
571
- let hosting = _.get(self.firebaseJSON, 'hosting', {});
538
+ const hosting = _.get(self.firebaseJSON, 'hosting', {});
572
539
  return (hosting.public && (hosting.public === 'public' || hosting.public !== '.'))
573
540
  }, fix_firebaseHostingFolder);
574
541
 
@@ -1015,8 +982,8 @@ function fix_setStoragePolicy(self) {
1015
982
  function fix_firestoreRulesFile(self) {
1016
983
  return new Promise(function(resolve, reject) {
1017
984
  const name = 'firestore.rules'
1018
- let path = `${self.firebaseProjectPath}/${name}`;
1019
- let exists = jetpack.exists(path);
985
+ const path = `${self.firebaseProjectPath}/${name}`;
986
+ const exists = jetpack.exists(path);
1020
987
  let contents = jetpack.read(path) || '';
1021
988
 
1022
989
  if (!exists || !contents) {
@@ -1025,14 +992,13 @@ function fix_firestoreRulesFile(self) {
1025
992
  contents = jetpack.read(path) || '';
1026
993
  }
1027
994
 
1028
- let hasTemplate = contents.match(bem_allRulesRegex) || contents.match(bem_allRulesBackupRegex);
1029
-
995
+ const hasTemplate = contents.match(bem_allRulesRegex) || contents.match(bem_allRulesBackupRegex);
1030
996
  if (!hasTemplate) {
1031
997
  log(chalk.red(`Could not find rules template. Please edit ${name} file and add`), chalk.red(`{{backend-manager}}`), chalk.red(`to it.`));
1032
998
  return resolve()
1033
999
  }
1034
1000
 
1035
- let matchesVersion = contents.match(self.default.rulesVersionRegex);
1001
+ const matchesVersion = contents.match(self.default.rulesVersionRegex);
1036
1002
  if (!matchesVersion) {
1037
1003
  // console.log('replace wih', self.default.firestoreRulesCore);
1038
1004
  contents = contents.replace(bem_allRulesBackupRegex, self.default.firestoreRulesCore)
@@ -1047,8 +1013,8 @@ function fix_firestoreRulesFile(self) {
1047
1013
  function fix_realtimeRulesFile(self) {
1048
1014
  return new Promise(function(resolve, reject) {
1049
1015
  const name = 'database.rules.json'
1050
- let path = `${self.firebaseProjectPath}/${name}`;
1051
- let exists = jetpack.exists(path);
1016
+ const path = `${self.firebaseProjectPath}/${name}`;
1017
+ const exists = jetpack.exists(path);
1052
1018
  let contents = jetpack.read(path) || '';
1053
1019
 
1054
1020
  if (!exists || !contents) {
@@ -1057,14 +1023,13 @@ function fix_realtimeRulesFile(self) {
1057
1023
  contents = jetpack.read(path) || '';
1058
1024
  }
1059
1025
 
1060
- let hasTemplate = contents.match(bem_allRulesRegex) || contents.match(bem_allRulesBackupRegex);
1061
-
1026
+ const hasTemplate = contents.match(bem_allRulesRegex) || contents.match(bem_allRulesBackupRegex);
1062
1027
  if (!hasTemplate) {
1063
1028
  log(chalk.red(`Could not find rules template. Please edit ${name} file and add`), chalk.red(`{{backend-manager}}`), chalk.red(`to it.`));
1064
1029
  return resolve()
1065
1030
  }
1066
1031
 
1067
- let matchesVersion = contents.match(self.default.rulesVersionRegex);
1032
+ const matchesVersion = contents.match(self.default.rulesVersionRegex);
1068
1033
  if (!matchesVersion) {
1069
1034
  // console.log('replace wih', self.default.databaseRulesCore);
1070
1035
  contents = contents.replace(bem_allRulesBackupRegex, self.default.databaseRulesCore)
@@ -1079,8 +1044,8 @@ function fix_realtimeRulesFile(self) {
1079
1044
  // function fix_realtimeRulesFile(self) {
1080
1045
  // return new Promise(function(resolve, reject) {
1081
1046
  // const name = 'database.rules.json';
1082
- // let filePath = `${self.firebaseProjectPath}/${name}`;
1083
- // let exists = jetpack.exists(filePath);
1047
+ // const filePath = `${self.firebaseProjectPath}/${name}`;
1048
+ // const exists = jetpack.exists(filePath);
1084
1049
  // let contents = jetpack.read(filePath) || '';
1085
1050
  //
1086
1051
  // if (!exists) {
@@ -1096,8 +1061,8 @@ function fix_realtimeRulesFile(self) {
1096
1061
  function fix_firestoreIndexesFile(self) {
1097
1062
  return new Promise(async function(resolve, reject) {
1098
1063
  const name = 'firestore.indexes.json';
1099
- let filePath = `${self.firebaseProjectPath}/${name}`;
1100
- let exists = jetpack.exists(filePath);
1064
+ const filePath = `${self.firebaseProjectPath}/${name}`;
1065
+ const exists = jetpack.exists(filePath);
1101
1066
 
1102
1067
  if (!exists) {
1103
1068
  log(chalk.yellow(`Writing new ${name} file...`));
@@ -1111,8 +1076,8 @@ function fix_firestoreIndexesFile(self) {
1111
1076
  function fix_storageRulesFile(self) {
1112
1077
  return new Promise(function(resolve, reject) {
1113
1078
  const name = 'storage.rules';
1114
- let filePath = `${self.firebaseProjectPath}/${name}`;
1115
- let exists = jetpack.exists(filePath);
1079
+ const filePath = `${self.firebaseProjectPath}/${name}`;
1080
+ const exists = jetpack.exists(filePath);
1116
1081
  let contents = jetpack.read(filePath) || '';
1117
1082
 
1118
1083
  if (!exists) {
@@ -1128,8 +1093,8 @@ function fix_storageRulesFile(self) {
1128
1093
  function fix_remoteconfigTemplateFile(self) {
1129
1094
  return new Promise(function(resolve, reject) {
1130
1095
  const name = 'remoteconfig.template.json'
1131
- let filePath = `${self.firebaseProjectPath}/${name}`;
1132
- let exists = jetpack.exists(filePath);
1096
+ const filePath = `${self.firebaseProjectPath}/functions/${name}`;
1097
+ const exists = jetpack.exists(filePath);
1133
1098
  let contents = jetpack.read(filePath) || '';
1134
1099
 
1135
1100
  if (!exists) {
@@ -1178,7 +1143,8 @@ function fix_firebaseHostingAuth(self) {
1178
1143
 
1179
1144
  function getPkgVersion(package) {
1180
1145
  return new Promise(async function(resolve, reject) {
1181
- let npm = new Npm();
1146
+ const npm = new Npm();
1147
+
1182
1148
  npm.repo(package)
1183
1149
  .package()
1184
1150
  .then(function(pkg) {
@@ -1190,9 +1156,11 @@ function getPkgVersion(package) {
1190
1156
  }
1191
1157
 
1192
1158
  async function cmd_indexesGet(self, filePath, log) {
1193
- return new Promise(function(resolve, reject) {
1159
+ return new Promise(async function(resolve, reject) {
1194
1160
  const finalPath = `${self.firebaseProjectPath}/${filePath || 'firestore.indexes.json'}`;
1195
1161
  let existingIndexes;
1162
+
1163
+ // Read existing indexes
1196
1164
  try {
1197
1165
  existingIndexes = require(`${self.firebaseProjectPath}/firestore.indexes.json`)
1198
1166
  } catch (e) {
@@ -1200,75 +1168,33 @@ async function cmd_indexesGet(self, filePath, log) {
1200
1168
  console.error('Failed to read existing local indexes', e);
1201
1169
  }
1202
1170
  }
1203
- let cmd = exec(`firebase firestore:indexes > ${finalPath}`, function (error, stdout, stderr) {
1204
- if (error) {
1205
- if (log !== false) {
1206
- console.error(error);
1207
- }
1208
- reject(error);
1209
- } else {
1171
+
1172
+ // Run the command
1173
+ await powertools.execute(`firebase firestore:indexes > ${finalPath}`, { log: true })
1174
+ .then((output) => {
1210
1175
  const newIndexes = require(finalPath);
1176
+
1177
+ // Log
1211
1178
  if (log !== false) {
1212
1179
  console.log(chalk.green(`Saving indexes to: ${finalPath}`));
1213
- console.log(stdout);
1214
-
1215
- const equal = (_.isEqual(newIndexes, existingIndexes));
1216
1180
 
1181
+ // Check if the indexes are different
1182
+ const equal = _.isEqual(newIndexes, existingIndexes);
1217
1183
  if (!equal) {
1218
1184
  console.log(chalk.red(`The live and local index files did not match and have been overwritten by the ${chalk.bold('live indexes')}`));
1219
1185
  }
1220
-
1221
1186
  }
1222
- resolve(newIndexes);
1223
- }
1224
- });
1225
- });
1226
- }
1227
1187
 
1228
- async function execute(command, cwd) {
1229
- cwd = cwd || process.cwd();
1230
- return new Promise(function(resolve, reject) {
1231
- exec(command, { cwd: cwd, stdio: 'inherit' })
1232
- .on('error', function(err) {
1233
- reject(err);
1234
- })
1235
- .on('close', function (one, two, three) {
1236
- console.log('===', one, two, three);
1237
- resolve()
1188
+ // Return
1189
+ return resolve(newIndexes);
1238
1190
  })
1239
- // fork(command, function (error, stdout, stderr) {
1240
- // if (error) {
1241
- // reject(error);
1242
- // } else {
1243
- // resolve(stdout);
1244
- // }
1245
- // });
1246
-
1191
+ .catch((e) => {
1192
+ // Return
1193
+ return reject(error);
1194
+ });
1247
1195
  });
1248
1196
  }
1249
1197
 
1250
- // async function execute(command, args, cwd) {
1251
- // cwd = cwd || process.cwd();
1252
- // return new Promise(function(resolve, reject) {
1253
- // spawn(command, args, { cwd: cwd, stdio: 'inherit' })
1254
- // .on('error', function(err) {
1255
- // reject(err);
1256
- // })
1257
- // .on('close', function (one, two, three) {
1258
- // console.log('===', one, two, three);
1259
- // resolve()
1260
- // })
1261
- // // fork(command, function (error, stdout, stderr) {
1262
- // // if (error) {
1263
- // // reject(error);
1264
- // // } else {
1265
- // // resolve(stdout);
1266
- // // }
1267
- // // });
1268
-
1269
- // });
1270
- // }
1271
-
1272
1198
  async function cmd_configGet(self, filePath) {
1273
1199
  return new Promise(function(resolve, reject) {
1274
1200
  const finalPath = `${self.firebaseProjectPath}/${filePath || 'functions/.runtimeconfig.json'}`;
@@ -1276,26 +1202,28 @@ async function cmd_configGet(self, filePath) {
1276
1202
  const max = 10;
1277
1203
  let retries = 0;
1278
1204
 
1279
- function _attempt() {
1280
- exec(`firebase functions:config:get > ${finalPath}`, function (error, stdout, stderr) {
1281
- if (error) {
1282
- console.error(chalk.red(`Failed to get config: ${error}`));
1205
+ async function _attempt() {
1206
+ try {
1207
+ const output = await powertools.execute(`firebase functions:config:get > ${finalPath}`, { log: true });
1283
1208
 
1284
- // If retries are exhausted, reject
1285
- if (retries++ > max) {
1286
- return reject(error);
1287
- }
1209
+ // Log success message
1210
+ console.log(chalk.green(`Saving config to: ${finalPath}`));
1288
1211
 
1289
- // Retry
1290
- const delay = 2500 * retries
1291
- console.error(chalk.yellow(`Retrying config:get ${retries}/${max} in ${delay}ms...`));
1292
- setTimeout(_attempt, delay);
1293
- } else {
1294
- console.log(chalk.green(`Saving config to: ${finalPath}`));
1295
- console.log(stdout);
1296
- resolve(require(finalPath));
1212
+ // Resolve with the required config
1213
+ resolve(require(finalPath));
1214
+ } catch (error) {
1215
+ console.error(chalk.red(`Failed to get config: ${error}`));
1216
+
1217
+ // Check if retries are exhausted
1218
+ if (retries++ >= max) {
1219
+ return reject(error);
1297
1220
  }
1298
- });
1221
+
1222
+ // Retry logic with delay
1223
+ const delay = 2500 * retries;
1224
+ console.error(chalk.yellow(`Retrying config:get ${retries}/${max} in ${delay}ms...`));
1225
+ setTimeout(_attempt, delay);
1226
+ }
1299
1227
  }
1300
1228
 
1301
1229
  // Start the attempts
@@ -1381,22 +1309,28 @@ async function cmd_configSet(self, newPath, newValue) {
1381
1309
  isInvalid = true;
1382
1310
  newPath = newPath.replace(/([A-Z])/g, '_$1').trim().toLowerCase();
1383
1311
  }
1312
+
1384
1313
  log(chalk.yellow(`Saving to ${chalk.bold(newPath)}...`));
1385
- let cmd = exec(`firebase functions:config:set ${newPath}="${newValue}"`, function (error, stdout, stderr) {
1386
- if (error) {
1387
- log(chalk.red(`Failed to save ${chalk.bold(newPath)}: ${error}`));
1388
- reject(error);
1389
- } else {
1390
- console.log(stdout);
1314
+
1315
+ await powertools.execute(`firebase functions:config:set ${newPath}="${newValue}"`, { log: true })
1316
+ .then((output) => {
1317
+ // Check if it was invalid
1391
1318
  if (isInvalid) {
1392
1319
  log(chalk.red(`!!! Your path contained an invalid uppercase character`));
1393
1320
  log(chalk.red(`!!! It was set to: ${chalk.bold(newPath)}`));
1394
1321
  } else {
1395
1322
  log(chalk.green(`Successfully saved to ${chalk.bold(newPath)}`));
1396
1323
  }
1324
+
1325
+ // Resolve the promise
1397
1326
  resolve();
1398
- }
1399
- });
1327
+ })
1328
+ .catch((e) => {
1329
+ log(chalk.red(`Failed to save ${chalk.bold(newPath)}: ${e}`));
1330
+
1331
+ // Reject the promise with the error
1332
+ reject(e);
1333
+ });
1400
1334
  });
1401
1335
  }
1402
1336
 
@@ -1413,26 +1347,30 @@ async function cmd_configUnset(self) {
1413
1347
  default: 'service.key'
1414
1348
  }
1415
1349
  ])
1416
- .then(answers => {
1350
+ .then(async (answers) => {
1417
1351
  // Use user feedback for... whatever!!
1418
1352
  // console.log('answer', answers);
1419
1353
  log(chalk.yellow(`Deleting ${chalk.bold(answers.path)}...`));
1420
- let cmd = exec(`firebase functions:config:unset ${answers.path}`, function (error, stdout, stderr) {
1421
- if (error) {
1422
- log(chalk.red(`Failed to delete ${chalk.bold(answers.path)}: ${error}`));
1423
- reject(error);
1424
- } else {
1425
- console.log(stdout);
1354
+
1355
+ await powertools.execute(`firebase functions:config:unset ${answers.path}`, { log: true })
1356
+ .then((output) => {
1426
1357
  log(chalk.green(`Successfully deleted ${chalk.bold(answers.path)}`));
1358
+
1359
+ // Resolve the promise
1427
1360
  resolve();
1428
- }
1429
- });
1361
+ })
1362
+ .catch((e) => {
1363
+ log(chalk.red(`Failed to delete ${chalk.bold(answers.path)}: ${e}`));
1364
+
1365
+ // Reject the promise with the error
1366
+ reject(e);
1367
+ });
1430
1368
  });
1431
1369
  });
1432
1370
  }
1433
1371
 
1434
1372
  async function cmd_iamImportExport(self) {
1435
- return new Promise(function(resolve, reject) {
1373
+ return new Promise(async function(resolve, reject) {
1436
1374
  const command = `
1437
1375
  gcloud projects add-iam-policy-binding {projectId} \
1438
1376
  --member serviceAccount:{projectId}@appspot.gserviceaccount.com \
@@ -1440,20 +1378,21 @@ async function cmd_iamImportExport(self) {
1440
1378
  `
1441
1379
  .replace(/{projectId}/ig, self.projectId)
1442
1380
 
1443
- let cmd = exec(command, function (error, stdout, stderr) {
1444
- if (error) {
1445
- console.log(chalk.red(`Failed to run command`, error));
1446
- reject(error);
1447
- } else {
1448
- // console.log(chalk.green(`Added permission`));
1449
- resolve(stdout);
1450
- }
1451
- });
1381
+ await powertools.execute(command, { log: true })
1382
+ .then((output) => {
1383
+ // Resolve with the command's standard output
1384
+ })
1385
+ .catch((e) => {
1386
+ console.log(chalk.red(`Failed to run command`, e));
1387
+
1388
+ // Reject with the error
1389
+ reject(e);
1390
+ });
1452
1391
  });
1453
1392
  }
1454
1393
 
1455
1394
  async function cmd_setStorageLifecycle(self) {
1456
- return new Promise(function(resolve, reject) {
1395
+ return new Promise(async function(resolve, reject) {
1457
1396
  const command = `gsutil lifecycle set {config} gs://{bucket}`
1458
1397
  .replace(/{config}/ig, path.resolve(`${__dirname}/../../templates/storage-lifecycle-config-1-day.json`))
1459
1398
  .replace(/{bucket}/ig, `us.artifacts.${self.projectId}.appspot.com`)
@@ -1461,22 +1400,20 @@ async function cmd_setStorageLifecycle(self) {
1461
1400
  .replace(/{config}/ig, path.resolve(`${__dirname}/../../templates/storage-lifecycle-config-30-days.json`))
1462
1401
  .replace(/{bucket}/ig, `bm-backup-firestore-${self.projectId}`)
1463
1402
 
1464
- exec(command, function (error, stdout, stderr) {
1465
- if (error) {
1466
- console.log(chalk.red(`Failed to run command`, error));
1467
- reject(error);
1468
- } else {
1469
- exec(command2, function (error, stdout, stderr) {
1470
- if (error) {
1471
- console.log(chalk.red(`Failed to run command`, error));
1472
- reject(error);
1473
- } else {
1474
- // console.log(chalk.green(`Added lifecycle`));
1475
- resolve(stdout);
1476
- }
1477
- })
1478
- }
1479
- });
1403
+ await powertools.execute(command, { log: true })
1404
+ .then(() => {
1405
+ return powertools.execute(command2, { log: true });
1406
+ })
1407
+ .then((output) => {
1408
+ // Resolve with the output of the second command
1409
+ resolve(output.stdout);
1410
+ })
1411
+ .catch((e) => {
1412
+ console.log(chalk.red(`Failed to run command`, e));
1413
+
1414
+ // Reject with the error
1415
+ reject(e);
1416
+ });
1480
1417
  });
1481
1418
  }
1482
1419
 
@@ -1508,30 +1445,40 @@ function installPkg(name, version, type) {
1508
1445
  }
1509
1446
 
1510
1447
  let latest = version ? '' : '@latest';
1511
- return new Promise(function(resolve, reject) {
1512
- let command = `npm i ${name}${v}${t}`;
1448
+ return new Promise(async function(resolve, reject) {
1449
+ // Build the command
1450
+ const command = `npm i ${name}${v}${t}`;
1451
+
1452
+ // Log
1513
1453
  console.log('Running ', command);
1514
- let cmd = exec(command, function (error, stdout, stderr) {
1515
- if (error) {
1516
- reject(error);
1517
- } else {
1454
+
1455
+ // Execute
1456
+ await powertools.execute(command, { log: true })
1457
+ .then(() => {
1518
1458
  resolve();
1519
- }
1520
- });
1459
+ })
1460
+ .catch((e) => {
1461
+ reject(e);
1462
+ });
1521
1463
  });
1522
1464
  }
1523
1465
 
1524
1466
  function uninstallPkg(name) {
1525
- return new Promise(function(resolve, reject) {
1526
- let command = `npm uninstall ${name}`;
1467
+ return new Promise(async function(resolve, reject) {
1468
+ // Build the command
1469
+ const command = `npm uninstall ${name}`;
1470
+
1471
+ // Log
1527
1472
  console.log('Running ', command);
1528
- let cmd = exec(command, function (error, stdout, stderr) {
1529
- if (error) {
1530
- reject(error);
1531
- } else {
1473
+
1474
+ // Execute
1475
+ await powertools.execute(command, { log: true })
1476
+ .then(() => {
1532
1477
  resolve();
1533
- }
1534
- });
1478
+ })
1479
+ .catch((e) => {
1480
+ reject(e);
1481
+ });
1535
1482
  });
1536
1483
  }
1537
1484
  function loadJSON(path) {