@mikeyt23/node-cli-utils 1.3.1 → 1.4.0
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.
- package/index.js +142 -23
- package/package.json +4 -3
package/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const fsp = require('fs').promises
|
|
3
|
+
const fse = require('fs-extra')
|
|
3
4
|
const which = require('which')
|
|
4
|
-
const {spawn, spawnSync} = require('child_process')
|
|
5
|
+
const { spawn, spawnSync } = require('child_process')
|
|
5
6
|
const path = require('path')
|
|
6
7
|
const tar = require('tar')
|
|
7
8
|
|
|
@@ -9,7 +10,7 @@ const defaultSpawnOptions = {
|
|
|
9
10
|
shell: true,
|
|
10
11
|
stdio: ['ignore', 'inherit', 'inherit']
|
|
11
12
|
}
|
|
12
|
-
const defaultSpawnOptionsWithInput = {...defaultSpawnOptions, stdio: 'inherit'}
|
|
13
|
+
const defaultSpawnOptionsWithInput = { ...defaultSpawnOptions, stdio: 'inherit' }
|
|
13
14
|
|
|
14
15
|
function waitForProcess(childProcess) {
|
|
15
16
|
return new Promise((resolve, reject) => {
|
|
@@ -39,7 +40,7 @@ async function throwIfDockerNotRunning() {
|
|
|
39
40
|
throw Error('docker command not found')
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
let childProcess = spawnSync('docker', ['info'], {encoding: 'utf8'})
|
|
43
|
+
let childProcess = spawnSync('docker', ['info'], { encoding: 'utf8' })
|
|
43
44
|
if (childProcess.error) {
|
|
44
45
|
throw childProcess.error
|
|
45
46
|
}
|
|
@@ -51,7 +52,7 @@ async function throwIfDockerNotRunning() {
|
|
|
51
52
|
async function bashIntoRunningDockerContainer(containerNamePartial, entryPoint = 'bash') {
|
|
52
53
|
await throwIfDockerNotRunning()
|
|
53
54
|
|
|
54
|
-
let childProcess = spawnSync('docker', ['container', 'ls'], {encoding: 'utf8'})
|
|
55
|
+
let childProcess = spawnSync('docker', ['container', 'ls'], { encoding: 'utf8' })
|
|
55
56
|
if (childProcess.error) {
|
|
56
57
|
throw childProcess.error
|
|
57
58
|
}
|
|
@@ -79,7 +80,7 @@ async function bashIntoRunningDockerContainer(containerNamePartial, entryPoint =
|
|
|
79
80
|
async function dockerContainerIsRunning(containerNamePartial) {
|
|
80
81
|
await throwIfDockerNotRunning()
|
|
81
82
|
|
|
82
|
-
let childProcess = spawnSync('docker', ['container', 'ls'], {encoding: 'utf8'})
|
|
83
|
+
let childProcess = spawnSync('docker', ['container', 'ls'], { encoding: 'utf8' })
|
|
83
84
|
if (childProcess.error) {
|
|
84
85
|
throw childProcess.error
|
|
85
86
|
}
|
|
@@ -188,12 +189,12 @@ async function createTarball(directoryToTarball, outputDirectory, tarballName, c
|
|
|
188
189
|
}
|
|
189
190
|
}
|
|
190
191
|
|
|
191
|
-
let options = {gzip: true, file: tarballPath}
|
|
192
|
+
let options = { gzip: true, file: tarballPath }
|
|
192
193
|
if (!!cwd) {
|
|
193
194
|
options.cwd = cwd
|
|
194
195
|
}
|
|
195
196
|
|
|
196
|
-
|
|
197
|
+
tar.c(options, [directoryToTarball])
|
|
197
198
|
}
|
|
198
199
|
|
|
199
200
|
async function dockerCompose(command, projectName, dockerRelativeDirectory = 'docker', detached = false) {
|
|
@@ -210,7 +211,7 @@ async function dockerCompose(command, projectName, dockerRelativeDirectory = 'do
|
|
|
210
211
|
|
|
211
212
|
await throwIfDockerNotRunning()
|
|
212
213
|
|
|
213
|
-
const dockerSpawnOptions = {...defaultSpawnOptions, cwd: dockerWorkingDir, stdio: 'inherit'}
|
|
214
|
+
const dockerSpawnOptions = { ...defaultSpawnOptions, cwd: dockerWorkingDir, stdio: 'inherit' }
|
|
214
215
|
|
|
215
216
|
let args = ['--project-name', projectName, command]
|
|
216
217
|
if (detached) {
|
|
@@ -255,7 +256,7 @@ async function dotnetPack(projectDirectoryPath, release = true) {
|
|
|
255
256
|
args.push('-c', 'Release')
|
|
256
257
|
}
|
|
257
258
|
|
|
258
|
-
const spawnOptions = {...defaultSpawnOptions, cwd: projectDirectoryPath}
|
|
259
|
+
const spawnOptions = { ...defaultSpawnOptions, cwd: projectDirectoryPath }
|
|
259
260
|
logCommand('dotnet', args, spawnOptions)
|
|
260
261
|
await waitForProcess(spawn('dotnet', args, spawnOptions))
|
|
261
262
|
}
|
|
@@ -270,7 +271,7 @@ async function dotnetNugetPublish(projectDirectoryPath, csprojFilename, release
|
|
|
270
271
|
|
|
271
272
|
const packageName = await getPackageName(projectDirectoryPath, csprojFilename)
|
|
272
273
|
console.log('publishing package ' + packageName)
|
|
273
|
-
const spawnOptions = {...defaultSpawnOptions, cwd: packageDir}
|
|
274
|
+
const spawnOptions = { ...defaultSpawnOptions, cwd: packageDir }
|
|
274
275
|
await waitForProcess(spawn('dotnet', [
|
|
275
276
|
'nuget',
|
|
276
277
|
'push',
|
|
@@ -304,21 +305,21 @@ async function dotnetDllCommand(relativeDllPath, argsArray, cwd = null, useStdin
|
|
|
304
305
|
|
|
305
306
|
let args = [relativeDllPath, ...argsArray]
|
|
306
307
|
|
|
307
|
-
let spawnOptions = {...defaultSpawnOptions}
|
|
308
|
+
let spawnOptions = { ...defaultSpawnOptions }
|
|
308
309
|
if (cwd !== null) {
|
|
309
|
-
spawnOptions = {...spawnOptions, cwd: cwd}
|
|
310
|
+
spawnOptions = { ...spawnOptions, cwd: cwd }
|
|
310
311
|
}
|
|
311
312
|
if (useStdin) {
|
|
312
|
-
spawnOptions = {...spawnOptions, stdio: 'inherit'}
|
|
313
|
+
spawnOptions = { ...spawnOptions, stdio: 'inherit' }
|
|
313
314
|
}
|
|
314
315
|
|
|
315
316
|
return waitForProcess(spawn('dotnet', args, spawnOptions))
|
|
316
317
|
}
|
|
317
318
|
|
|
318
319
|
async function dotnetPublish(cwd = null, outputDir = 'publish') {
|
|
319
|
-
let spawnOptions = {...defaultSpawnOptions}
|
|
320
|
+
let spawnOptions = { ...defaultSpawnOptions }
|
|
320
321
|
if (!!cwd) {
|
|
321
|
-
spawnOptions = {...spawnOptions, cwd: cwd}
|
|
322
|
+
spawnOptions = { ...spawnOptions, cwd: cwd }
|
|
322
323
|
}
|
|
323
324
|
if (!outputDir) {
|
|
324
325
|
outputDir = 'publish'
|
|
@@ -330,7 +331,7 @@ async function dotnetPublish(cwd = null, outputDir = 'publish') {
|
|
|
330
331
|
async function dotnetDbMigrationsList(dbContextName, relativeDbMigratorDirectoryPath) {
|
|
331
332
|
throwIfRequiredIsFalsy(dbContextName, 'dbContextName')
|
|
332
333
|
throwIfRequiredIsFalsy(relativeDbMigratorDirectoryPath, 'relativeDbMigratorDirectoryPath')
|
|
333
|
-
let spawnOptions = {...defaultSpawnOptions, cwd: relativeDbMigratorDirectoryPath}
|
|
334
|
+
let spawnOptions = { ...defaultSpawnOptions, cwd: relativeDbMigratorDirectoryPath }
|
|
334
335
|
return waitForProcess(spawn('dotnet', ['ef', 'migrations', 'list', '--context', dbContextName], spawnOptions))
|
|
335
336
|
}
|
|
336
337
|
|
|
@@ -342,7 +343,7 @@ async function dotnetDbMigrate(dbContextName, relativeDbMigratorDirectoryPath, m
|
|
|
342
343
|
args.push(migrationName)
|
|
343
344
|
}
|
|
344
345
|
args = [...args, '--context', dbContextName]
|
|
345
|
-
let spawnOptions = {...defaultSpawnOptions, cwd: relativeDbMigratorDirectoryPath}
|
|
346
|
+
let spawnOptions = { ...defaultSpawnOptions, cwd: relativeDbMigratorDirectoryPath }
|
|
346
347
|
return waitForProcess(spawn('dotnet', args, spawnOptions))
|
|
347
348
|
}
|
|
348
349
|
|
|
@@ -354,7 +355,7 @@ async function dotnetDbAddMigration(dbContextName, relativeDbMigratorDirectoryPa
|
|
|
354
355
|
const migrationsOutputDir = `Migrations/${dbContextName}Migrations`
|
|
355
356
|
|
|
356
357
|
let args = ['ef', 'migrations', 'add', migrationName, '--context', dbContextName, '-o', migrationsOutputDir]
|
|
357
|
-
let spawnOptions = {...defaultSpawnOptions, cwd: relativeDbMigratorDirectoryPath}
|
|
358
|
+
let spawnOptions = { ...defaultSpawnOptions, cwd: relativeDbMigratorDirectoryPath }
|
|
358
359
|
await waitForProcess(spawn('dotnet', args, spawnOptions))
|
|
359
360
|
|
|
360
361
|
if (withBoilerplate) {
|
|
@@ -388,7 +389,7 @@ async function dotnetDbAddMigrationBoilerplate(dbContextName, relativeDbMigrator
|
|
|
388
389
|
const upLine = `MigrationScriptRunner.RunScript(migrationBuilder, "${migrationName}.sql");`
|
|
389
390
|
const downLine = `MigrationScriptRunner.RunScript(migrationBuilder, "${migrationName}_Down.sql");`
|
|
390
391
|
|
|
391
|
-
const fileContents = await fsp.readFile(filePath, {encoding: 'utf8'})
|
|
392
|
+
const fileContents = await fsp.readFile(filePath, { encoding: 'utf8' })
|
|
392
393
|
let lines = fileContents.replaceAll('\r', '').split('\n')
|
|
393
394
|
|
|
394
395
|
let newLines = []
|
|
@@ -429,7 +430,7 @@ async function dotnetDbAddMigrationBoilerplate(dbContextName, relativeDbMigrator
|
|
|
429
430
|
|
|
430
431
|
const newFileContents = newLines.join('\n')
|
|
431
432
|
|
|
432
|
-
await fsp.writeFile(filePath, newFileContents, {encoding: 'utf8'})
|
|
433
|
+
await fsp.writeFile(filePath, newFileContents, { encoding: 'utf8' })
|
|
433
434
|
|
|
434
435
|
console.log(`Updated file with boilerplate - please ensure it is correct: ${filePath}`)
|
|
435
436
|
|
|
@@ -441,13 +442,13 @@ async function dotnetDbAddMigrationBoilerplate(dbContextName, relativeDbMigrator
|
|
|
441
442
|
console.log(` - ${downScriptPath}`)
|
|
442
443
|
|
|
443
444
|
if (!fs.existsSync(upScriptPath)) {
|
|
444
|
-
await fsp.writeFile(upScriptPath, '', {encoding: 'utf8'})
|
|
445
|
+
await fsp.writeFile(upScriptPath, '', { encoding: 'utf8' })
|
|
445
446
|
} else {
|
|
446
447
|
console.log('Skipping Up sql script (already exists)')
|
|
447
448
|
}
|
|
448
449
|
|
|
449
450
|
if (!fs.existsSync(downScriptPath)) {
|
|
450
|
-
await fsp.writeFile(downScriptPath, '', {encoding: 'utf8'})
|
|
451
|
+
await fsp.writeFile(downScriptPath, '', { encoding: 'utf8' })
|
|
451
452
|
} else {
|
|
452
453
|
console.log('Skipping Down sql script (already exists)')
|
|
453
454
|
}
|
|
@@ -456,7 +457,7 @@ async function dotnetDbAddMigrationBoilerplate(dbContextName, relativeDbMigrator
|
|
|
456
457
|
async function dotnetDbRemoveMigration(dbContextName, relativeDbMigratorDirectoryPath) {
|
|
457
458
|
throwIfRequiredIsFalsy(dbContextName, 'dbContextName')
|
|
458
459
|
throwIfRequiredIsFalsy(relativeDbMigratorDirectoryPath, 'relativeDbMigratorDirectoryPath')
|
|
459
|
-
let spawnOptions = {...defaultSpawnOptions, cwd: relativeDbMigratorDirectoryPath}
|
|
460
|
+
let spawnOptions = { ...defaultSpawnOptions, cwd: relativeDbMigratorDirectoryPath }
|
|
460
461
|
return waitForProcess(spawn('dotnet', ['ef', 'migrations', 'remove', '--context', dbContextName], spawnOptions))
|
|
461
462
|
}
|
|
462
463
|
|
|
@@ -472,6 +473,120 @@ function throwIfRequiredArrayIsFalsyOrEmpty(requiredArrayArg, argName) {
|
|
|
472
473
|
}
|
|
473
474
|
}
|
|
474
475
|
|
|
476
|
+
async function generateCertWithOpenSsl(url, outputDirectory = './cert') {
|
|
477
|
+
if (!url) {
|
|
478
|
+
throw Error('Param \'url\' is required.')
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Check if openssl is installed
|
|
482
|
+
let macOpenSslPath
|
|
483
|
+
if (process.platform !== 'darwin') {
|
|
484
|
+
if (!which.sync('openssl', { nothrow: true })) {
|
|
485
|
+
throw Error('openssl is required but was not found in the path')
|
|
486
|
+
}
|
|
487
|
+
} else {
|
|
488
|
+
console.log('*****************************************************************')
|
|
489
|
+
console.log('* Important: mac support requires openssl be installed via brew *')
|
|
490
|
+
console.log('*****************************************************************')
|
|
491
|
+
|
|
492
|
+
macOpenSslPath = `${getBrewOpensslPath()}/bin/openssl`
|
|
493
|
+
console.log(`openssl path: ${macOpenSslPath}`)
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
console.log('openssl is installed, continuing...')
|
|
497
|
+
|
|
498
|
+
fse.mkdirpSync(outputDirectory)
|
|
499
|
+
|
|
500
|
+
const keyName = url + '.key'
|
|
501
|
+
const crtName = url + '.crt'
|
|
502
|
+
const pfxName = url + '.pfx'
|
|
503
|
+
|
|
504
|
+
pfxPath = path.join(outputDirectory, pfxName)
|
|
505
|
+
|
|
506
|
+
if (fse.pathExistsSync(pfxPath)) {
|
|
507
|
+
throw Error(`File ${pfxPath} already exists. Delete this first if you want to generate a new version.`)
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
console.log(`attempting to generate cert ${pfxName}`)
|
|
511
|
+
|
|
512
|
+
const genCertSpawnArgs = { ...defaultSpawnOptions, cwd: outputDirectory }
|
|
513
|
+
|
|
514
|
+
const genKeyAndCrtArgs = `req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout ${keyName} -out ${crtName} -subj "/CN=${url}" -addext "subjectAltName=DNS:${url},IP:127.0.0.1"`.split(' ')
|
|
515
|
+
|
|
516
|
+
const cmd = process.platform !== 'darwin' ? 'openssl' : macOpenSslPath
|
|
517
|
+
|
|
518
|
+
console.log('cmd: ' + cmd)
|
|
519
|
+
|
|
520
|
+
await waitForProcess(spawn(cmd, genKeyAndCrtArgs, genCertSpawnArgs))
|
|
521
|
+
|
|
522
|
+
console.log('converting key and crt to pfx...')
|
|
523
|
+
|
|
524
|
+
const convertToPfxArgs = `pkcs12 -certpbe AES-256-CBC -export -out ${pfxName} -aes256 -inkey ${keyName} -in ${crtName} -password pass:`.split(' ')
|
|
525
|
+
|
|
526
|
+
await waitForProcess(spawn(cmd, convertToPfxArgs, genCertSpawnArgs))
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
function getBrewOpensslPath() {
|
|
530
|
+
let childProc = spawnSync('brew', ['--prefix', 'openssl'], { encoding: 'utf-8' })
|
|
531
|
+
if (childProc.error) {
|
|
532
|
+
throw Error('error attempting to find openssl installed by brew')
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
const output = childProc.stdout
|
|
536
|
+
|
|
537
|
+
if (!output || output.length === 0 || output.toLowerCase().startsWith('error')) {
|
|
538
|
+
throw Error('unexpected output while attempting to find openssl')
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
return output.replace('\n', '')
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
async function winInstallCert(urlOrCertFilename, relativeCertDirectoryPath = './cert') {
|
|
545
|
+
if (!urlOrCertFilename) {
|
|
546
|
+
throw Error('Param \'urlOrCertFilename\' is required.')
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
console.log('******************************\n* Requires admin permissions *\n******************************')
|
|
550
|
+
|
|
551
|
+
let certName = urlOrCertFilename.endsWith('.pfx') ? urlOrCertFilename : urlOrCertFilename + '.pfx'
|
|
552
|
+
|
|
553
|
+
const certPath = path.join(process.cwd(), relativeCertDirectoryPath, certName)
|
|
554
|
+
|
|
555
|
+
if (!fse.pathExistsSync(certPath)) {
|
|
556
|
+
throw Error(`File ${certPath} does not exist. Generate this first if you want to install it.`)
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
const psCommand = `$env:PSModulePath = [Environment]::GetEnvironmentVariable('PSModulePath', 'Machine'); Import-PfxCertificate -FilePath '${certPath}' -CertStoreLocation Cert:\\LocalMachine\\Root`
|
|
560
|
+
|
|
561
|
+
await waitForProcess(spawn('powershell', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', psCommand]))
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
async function winUninstallCert(urlOrSubject) {
|
|
565
|
+
if (!urlOrSubject) {
|
|
566
|
+
throw Error('Param \'urlOrSubject\' is required.')
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
console.log('******************************\n* Requires admin permissions *\n******************************')
|
|
570
|
+
|
|
571
|
+
const psCommand = `$env:PSModulePath = [Environment]::GetEnvironmentVariable('PSModulePath', 'Machine'); Get-ChildItem Cert:\\LocalMachine\\Root | Where-Object { $_.Subject -match '${urlOrSubject}' } | Remove-Item`;
|
|
572
|
+
|
|
573
|
+
await waitForProcess(spawn('powershell', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', psCommand]))
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
function linuxInstallCert() {
|
|
577
|
+
const instructions = `
|
|
578
|
+
Automated linux cert install not supported (chrome does not use system certs without significant extra configuration).
|
|
579
|
+
|
|
580
|
+
Manual Instructions:
|
|
581
|
+
- In Chrome, go to chrome://settings/certificates
|
|
582
|
+
- Select Authorities -> import
|
|
583
|
+
- Select your generated .crt file (in the ./cert/ directory by default - if you haven't generated it, see the generateCertWithOpenSsl method)
|
|
584
|
+
- Check box for "Trust certificate for identifying websites"
|
|
585
|
+
- Click OK
|
|
586
|
+
- Reload site`
|
|
587
|
+
console.log(instructions)
|
|
588
|
+
}
|
|
589
|
+
|
|
475
590
|
exports.defaultSpawnOptions = defaultSpawnOptions
|
|
476
591
|
exports.defaultSpawnOptionsWithInput = defaultSpawnOptionsWithInput
|
|
477
592
|
exports.waitForProcess = waitForProcess
|
|
@@ -494,3 +609,7 @@ exports.dotnetDbMigrationsList = dotnetDbMigrationsList
|
|
|
494
609
|
exports.dotnetDbMigrate = dotnetDbMigrate
|
|
495
610
|
exports.dotnetDbAddMigration = dotnetDbAddMigration
|
|
496
611
|
exports.dotnetDbRemoveMigration = dotnetDbRemoveMigration
|
|
612
|
+
exports.generateCertWithOpenSsl = generateCertWithOpenSsl
|
|
613
|
+
exports.winInstallCert = winInstallCert
|
|
614
|
+
exports.winUninstallCert = winUninstallCert
|
|
615
|
+
exports.linuxInstallCert = linuxInstallCert
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikeyt23/node-cli-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Some node cli utility functions",
|
|
5
5
|
"author": "Mike Thompson",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
},
|
|
16
16
|
"main": "index.js",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"
|
|
19
|
-
"
|
|
18
|
+
"fs-extra": "^11.1.1",
|
|
19
|
+
"tar": "^6.1.15",
|
|
20
|
+
"which": "^3.0.1"
|
|
20
21
|
}
|
|
21
22
|
}
|