@mikeyt23/node-cli-utils 1.4.0 → 2.0.0-beta.1

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 (64) hide show
  1. package/README.md +45 -87
  2. package/dist/cjs/NodeCliUtilsConfig.d.ts +21 -0
  3. package/dist/cjs/NodeCliUtilsConfig.d.ts.map +1 -0
  4. package/dist/cjs/NodeCliUtilsConfig.js +41 -0
  5. package/dist/cjs/TarballUtility.d.ts +53 -0
  6. package/dist/cjs/TarballUtility.d.ts.map +1 -0
  7. package/dist/cjs/TarballUtility.js +149 -0
  8. package/dist/cjs/certUtils.d.ts +30 -0
  9. package/dist/cjs/certUtils.d.ts.map +1 -0
  10. package/dist/cjs/certUtils.js +219 -0
  11. package/dist/cjs/dbMigrationUtils.d.ts +39 -0
  12. package/dist/cjs/dbMigrationUtils.d.ts.map +1 -0
  13. package/dist/cjs/dbMigrationUtils.js +205 -0
  14. package/dist/cjs/dotnetUtils.d.ts +25 -0
  15. package/dist/cjs/dotnetUtils.d.ts.map +1 -0
  16. package/dist/cjs/dotnetUtils.js +59 -0
  17. package/dist/cjs/esmSpecific.d.mts +2 -0
  18. package/dist/cjs/esmSpecific.d.mts.map +1 -0
  19. package/dist/cjs/esmSpecific.mjs +10 -0
  20. package/dist/cjs/generalUtils.d.ts +323 -0
  21. package/dist/cjs/generalUtils.d.ts.map +1 -0
  22. package/dist/cjs/generalUtils.js +652 -0
  23. package/dist/cjs/generalUtilsInternal.d.ts +9 -0
  24. package/dist/cjs/generalUtilsInternal.d.ts.map +1 -0
  25. package/dist/cjs/generalUtilsInternal.js +217 -0
  26. package/dist/cjs/index.d.ts +4 -0
  27. package/dist/cjs/index.d.ts.map +1 -0
  28. package/dist/cjs/index.js +25 -0
  29. package/dist/cjs/package.json +5 -0
  30. package/dist/cjs/runWhileParentAlive.d.ts +2 -0
  31. package/dist/cjs/runWhileParentAlive.d.ts.map +1 -0
  32. package/dist/cjs/runWhileParentAlive.js +161 -0
  33. package/dist/esm/NodeCliUtilsConfig.d.ts +21 -0
  34. package/dist/esm/NodeCliUtilsConfig.d.ts.map +1 -0
  35. package/dist/esm/NodeCliUtilsConfig.js +35 -0
  36. package/dist/esm/TarballUtility.d.ts +53 -0
  37. package/dist/esm/TarballUtility.d.ts.map +1 -0
  38. package/dist/esm/TarballUtility.js +143 -0
  39. package/dist/esm/certUtils.d.ts +30 -0
  40. package/dist/esm/certUtils.d.ts.map +1 -0
  41. package/dist/esm/certUtils.js +185 -0
  42. package/dist/esm/dbMigrationUtils.d.ts +39 -0
  43. package/dist/esm/dbMigrationUtils.d.ts.map +1 -0
  44. package/dist/esm/dbMigrationUtils.js +194 -0
  45. package/dist/esm/dotnetUtils.d.ts +25 -0
  46. package/dist/esm/dotnetUtils.d.ts.map +1 -0
  47. package/dist/esm/dotnetUtils.js +52 -0
  48. package/dist/esm/esmSpecific.d.mts +2 -0
  49. package/dist/esm/esmSpecific.d.mts.map +1 -0
  50. package/dist/esm/esmSpecific.mjs +6 -0
  51. package/dist/esm/generalUtils.d.ts +323 -0
  52. package/dist/esm/generalUtils.d.ts.map +1 -0
  53. package/dist/esm/generalUtils.js +591 -0
  54. package/dist/esm/generalUtilsInternal.d.ts +9 -0
  55. package/dist/esm/generalUtilsInternal.d.ts.map +1 -0
  56. package/dist/esm/generalUtilsInternal.js +185 -0
  57. package/dist/esm/index.d.ts +4 -0
  58. package/dist/esm/index.d.ts.map +1 -0
  59. package/dist/esm/index.js +4 -0
  60. package/dist/esm/runWhileParentAlive.d.ts +2 -0
  61. package/dist/esm/runWhileParentAlive.d.ts.map +1 -0
  62. package/dist/esm/runWhileParentAlive.js +153 -0
  63. package/package.json +67 -10
  64. package/index.js +0 -615
package/README.md CHANGED
@@ -1,107 +1,65 @@
1
- # @mikeyt23/node-cli-utils
2
-
3
- Simple node cli utils to:
4
-
5
- - Wait for a node spawned process
6
- - Copy env template file to env file
7
- - Sync new env values from template to "real" env files
8
- - Manage all env values in root files that then get copied to other locations
9
- - Dotnet helper methods:
10
- - Pack and publish a NuGet package
11
- - Wrapper commands to install or update dotnet ef tool
12
- - Wrapper commands to spawn dotnet run and publish
13
- - Helper methods for DB migration commands (see [mikey-t/db-migrations-dotnet](https://github.com/mikey-t/db-migrations-dotnet))
14
-
15
- # Env Utility Function Notes
16
-
17
- A project can have multiple locations that require the same env values. For example, you might have a database that needs to be used by a docker project, your main app and also a db migration project. Rather than having to remember where each of the .env files is, we want to use the root directory and overwrite subdirectory env files with the ones in the root. We also want to add new `.env.template` values to the root `.env` files and propagate them to subdirectories - all without having to know about anything about any of the .env files except the ones in the root of the project.
18
-
19
- # Examples
20
-
21
- An example syncEnvFiles gulp task function:
22
-
23
- ```JavaScript
24
- const projectDir = 'src/YourProjectDir/'
25
- const serverAppDir = `src/${projectDir}`
26
- const clientAppDir = `src/${projectDir}client-app/`
27
- const dockerDir = 'docker/'
28
-
29
- async function syncEnvFiles() {
30
- const rootServerEnv = './.env.server'
31
- const rootClientEnv = './.env.client'
32
-
33
- // Copy new values from root .env.[category].template to .env.[category]
34
- await copyNewEnvValues('./.env.server.template', rootServerEnv)
35
- await copyNewEnvValues('./.env.client.template', rootClientEnv)
36
-
37
- // Copy root .env.[category] to subdirectory .env files (overwrites target env file)
38
- // Server env to server app and docker directories
39
- await overwriteEnvFile(rootServerEnv, path.join(serverAppDir, '.env'))
40
- await overwriteEnvFile(rootServerEnv, path.join(dockerDir, '.env'))
41
- // Client env to client app directory
42
- await overwriteEnvFile(rootClientEnv, path.join(clientAppDir, '.env'))
43
- }
44
-
45
- exports.syncEnvFiles = syncEnvFiles
1
+ # node-cli-utils
2
+
3
+ This library is a collection of miscellaneous utility functions for Node CLI scripting.
4
+
5
+ I primarily use this library with [swig-cli](https://github.com/mikey-t/swig) to automate project dev tasks and generally to glue all the things together. Check out an example project that uses both swig-cli and node-cli-utils: [dotnet-react-sandbox](https://github.com/mikey-t/dotnet-react-sandbox).
6
+
7
+ The auto-generated portion of this project's documentation is auto-generated from JSDoc using [TypeDoc](https://github.com/TypeStrong/typedoc).
8
+
9
+ ## Install
10
+
11
+ ```
12
+ npm install @mikeyt23/node-cli-utils --save-dev
46
13
  ```
47
14
 
48
- > **WARNING**: Be sure to .gitignore `.env`, `.env.server` and `.env.client` files in the root **AND** the location they're being copied to. Only the template files with placeholder values should go in source control. For example, your .gitignore could have `**/.env*` and then `!.env.server.template` and `!.env.client.template`, etc.
15
+ ## Exported Modules
49
16
 
50
- Example gulp task calling docker-compose:
17
+ Utility functions are loosely grouped into 4 modules:
51
18
 
52
- ```JavaScript
53
- const spawnOptions = {...defaultSpawnOptions}
19
+ | Module | Description |
20
+ |--------|-------------|
21
+ | @mikeyt23/node-cli-util | General utils |
22
+ | @mikeyt23/node-cli-util/dbMigrationUtils | DB migration utils (see [db-migrations-dotnet](https://github.com/mikey-t/db-migrations-dotnet)) |
23
+ | @mikeyt23/node-cli-util/dotnetUtils | Dotnet utils |
24
+ | @mikeyt23/node-cli-util/certUtils | Cert utils |
54
25
 
55
- const dockerDirPath = 'docker/'
56
- const dockerDepsProjectName = 'your_project'
57
- const dockerDepsComposeName = 'docker-compose.deps.yml'
26
+ ## Reasoning
58
27
 
59
- const dockerSpawnOptions = {...spawnOptions, cwd: path.resolve(__dirname, dockerDirPath)}
28
+ NodeJS projects are out-of-control with the depth of their dependency trees. Rather than giving in to that trend, I'm attempting to maintain a small set of simple helper methods using built-in NodeJS functionality whenever possible, and only importing things when I simply can't easily reproduce the functionality myself. And when I do import a dependency, it will preferably be one with a shallow dependency tree.
60
29
 
61
- async function dockerDepsUpDetached() {
62
- return waitForProcess(spawn('docker-compose', ['--project-name', dockerDepsProjectName, '-f', dockerDepsComposeName, 'up', '-d'], dockerSpawnOptions))
63
- }
30
+ In some ways this is bad because I'm obviously re-inventing the wheel and there's other libraries that do some of this stuff way better. But here's what I'm getting by doing it this way:
64
31
 
65
- exports.dockerDepsUpDetached = series(syncEnvFiles, dockerDepsUpDetached)
66
- ```
32
+ - Significantly less work to keep things up to date - I don't have to audit dozens or hundreds or thousands of dependency and transitive dependency updates on a regular basis
33
+ - Significantly less (or zero) risk of NPM supply chain attacks
34
+ - Getting more hands-on XP with the fundamentals of NodeJS Typescript development
35
+ - Control. Do I know who to talk to for bug fixes or feature improvements? Of course I know him - he's me!
67
36
 
68
- Example gulp task using util method `throwIfDockerNotRunning`:
37
+ Originally I made an exception to this rule for [node-tar](https://github.com/isaacs/node-tar). However, I replaced this with a system call to the OS built-in `tar` utility since even Windows has this built-in since 2018.
69
38
 
39
+ Also - just my personal opinion - every serious developer should create and maintain libraries like this. It's not always about reinventing the wheel or not. Sometimes it's about learning about different types of wheels by creating some yourself.
70
40
 
71
- ```JavaScript
72
- async function dockerDepsUp() {
73
- await throwIfDockerNotRunning()
74
- return waitForProcess(spawn('docker-compose', ['--project-name', dockerDepsProjectName, '-f', dockerDepsComposeName, 'up'], dockerSpawnOptions))
75
- }
41
+ ## Noteworthy Features
76
42
 
77
- exports.dockerDepsUp = series(syncEnvFiles, dockerDepsUp)
78
- ```
43
+ ### Process Spawning Cross-Platform Workarounds
79
44
 
80
- Example gulp task using util method `dockerContainerIsRunning`:
45
+ Dev automation tasks in all my projects make heavy use of spawning child processes, but unfortunately there's a lot of issues that cause this to be inconsistent across platforms. I've attempted to normalize some of the more annoying edge cases.
81
46
 
82
- ```JavaScript
83
- async function throwIfDockerDepsNotUp() {
84
- const postgresIsRunning = await dockerContainerIsRunning(`${dockerDepsProjectName}_postgresql`)
85
- if (!postgresIsRunning) {
86
- throw 'Docker dependencies are not running'
87
- }
88
- }
47
+ For example, sometimes the only way to get a command to work how you want on windows is to pass the `shell: true` option. One case where this is useful is for running commands for a long running process that you want to be able to terminate with `ctrl+c` when you're done with it. These are commands like `docker compose up`, or running a dev web server, or anything that runs until you stop it. But on windows when you use `ctrl+c` to terminate a process spawned without the `shell: true` option, it immediately kills all the processes in the tree without warning or signaling, which is bad if those processes need to shut down gracefully before exiting. For example, on windows if you use `ctrl+c` on `docker compose up` spawned by Node, you'll notice that the containers are still running even after the attached command exits. But if you do the same thing on a nix machine, docker is given the `SIGINT` signal and it gracefully stops the containers before shutting down.
89
48
 
90
- async function runDbMigrator() {
91
- return waitForProcess(spawn('dotnet', [`publish/${DotnetNamespace}.DbMigrator.dll`], migratorSpawnOptions))
92
- }
49
+ But this issue is of the whack-a-mole variety, because if you do go ahead and pass the `shell: true` option, then unexpected termination of the parent process will simply orphan your child process tree, forcing you to kill it yourself manually, or with some other scripting.
93
50
 
94
- exports.dbMigrate = series(throwIfDockerDepsNotUp, parallel(syncEnvFiles, deleteMigratorPublishDir), publishMigrator, runDbMigrator)
95
- ```
51
+ So normally you can do one of a couple things so that your process spawning code works well on windows in addition to nix machines:
96
52
 
97
- Example gulp task using util method `bashIntoRunningDockerContainer` and `argv` to pass in param `--imageName`:
53
+ - Use another library where someone claims to have solved this completely in a cross-platform way (`press x to doubt`), and accept a non-trivial number of dependencies into your project
54
+ - Use the non-shell option and just deal with some commands terminating non-gracefully
55
+ - Use the shell option and just deal with long running processes sometimes getting orphaned
98
56
 
99
- ```JavaScript
100
- async function dockerBashRunningContainer() {
101
- await throwIfDockerNotRunning()
102
- await bashIntoRunningDockerContainer(`${dockerDepsProjectName}_${argv['imageName']}`)
103
- }
57
+ Instead I've chosen to create a couple of different wrapper methods for Node's spawn method. One calls spawn fairly normally (`spawnAsync` in [./src/generalUtils.ts](./src/generalUtils.ts)), with an additional option to get the exec-like functionality of throwing on non-zero return code if you want. And another wrapper that is used for long running processes that uses the shell option, but if you're on windows does a nifty little hack to spawn a "middle" watchdog process that polls for whether the parent is alive or not and kills the child process tree if it becomes orphaned (`spawnAsyncLongRunning` in [./src/generalUtils.ts](./src/generalUtils.ts)).
104
58
 
105
- exports.dockerBash = dockerBashRunningContainer
106
- ```
59
+ In the future I may go research how others have solved cross-platform process spawning, but for now this little hack works fine.
60
+
61
+ ## TODO
107
62
 
63
+ - More unit tests
64
+ - Build out example projects that use both CommonJS and ESM
65
+ - Move the DB migration utils out of this library into it's own space
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Config to control a few misc settings in the node-cli-utils package. This module exports a singleton instance.
3
+ */
4
+ export declare class NodeCliUtilsConfig {
5
+ private _traceEnabled;
6
+ private _orphanProtectionPollingIntervalMillis;
7
+ private _orphanProtectionLoggingEnabled;
8
+ private _orphanProtectionLoggingPath;
9
+ get traceEnabled(): boolean;
10
+ set traceEnabled(value: boolean);
11
+ get orphanProtectionPollingIntervalMillis(): number;
12
+ set orphanProtectionPollingIntervalMillis(value: number);
13
+ get orphanProtectionLoggingEnabled(): boolean;
14
+ set orphanProtectionLoggingEnabled(value: boolean);
15
+ get orphanProtectionLoggingPath(): string;
16
+ }
17
+ /**
18
+ * Singleton instance of {@link NodeCliUtilsConfig}.
19
+ */
20
+ export declare const config: NodeCliUtilsConfig;
21
+ //# sourceMappingURL=NodeCliUtilsConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeCliUtilsConfig.d.ts","sourceRoot":"","sources":["../../src/NodeCliUtilsConfig.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,sCAAsC,CAAQ;IACtD,OAAO,CAAC,+BAA+B,CAAQ;IAC/C,OAAO,CAAC,4BAA4B,CAA2B;IAE/D,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,OAAO,EAE9B;IAED,IAAI,qCAAqC,IAAI,MAAM,CAElD;IAED,IAAI,qCAAqC,CAAC,KAAK,EAAE,MAAM,EAEtD;IAED,IAAI,8BAA8B,IAAI,OAAO,CAE5C;IAED,IAAI,8BAA8B,CAAC,KAAK,EAAE,OAAO,EAEhD;IAED,IAAI,2BAA2B,IAAI,MAAM,CAExC;CACF;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,oBAA2B,CAAA"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.config = exports.NodeCliUtilsConfig = void 0;
4
+ /**
5
+ * Config to control a few misc settings in the node-cli-utils package. This module exports a singleton instance.
6
+ */
7
+ class NodeCliUtilsConfig {
8
+ constructor() {
9
+ this._traceEnabled = false;
10
+ this._orphanProtectionPollingIntervalMillis = 15000;
11
+ this._orphanProtectionLoggingEnabled = false;
12
+ this._orphanProtectionLoggingPath = './orphanProtection.log';
13
+ }
14
+ get traceEnabled() {
15
+ return this._traceEnabled;
16
+ }
17
+ set traceEnabled(value) {
18
+ this._traceEnabled = value;
19
+ }
20
+ get orphanProtectionPollingIntervalMillis() {
21
+ return this._orphanProtectionPollingIntervalMillis;
22
+ }
23
+ set orphanProtectionPollingIntervalMillis(value) {
24
+ this._orphanProtectionPollingIntervalMillis = value;
25
+ }
26
+ get orphanProtectionLoggingEnabled() {
27
+ return this._orphanProtectionLoggingEnabled;
28
+ }
29
+ set orphanProtectionLoggingEnabled(value) {
30
+ this._orphanProtectionLoggingEnabled = value;
31
+ }
32
+ get orphanProtectionLoggingPath() {
33
+ return this._orphanProtectionLoggingPath;
34
+ }
35
+ }
36
+ exports.NodeCliUtilsConfig = NodeCliUtilsConfig;
37
+ /**
38
+ * Singleton instance of {@link NodeCliUtilsConfig}.
39
+ */
40
+ exports.config = new NodeCliUtilsConfig();
41
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTm9kZUNsaVV0aWxzQ29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL05vZGVDbGlVdGlsc0NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7R0FFRztBQUNILE1BQWEsa0JBQWtCO0lBQS9CO1FBQ1Usa0JBQWEsR0FBWSxLQUFLLENBQUM7UUFDL0IsMkNBQXNDLEdBQUcsS0FBSyxDQUFBO1FBQzlDLG9DQUErQixHQUFHLEtBQUssQ0FBQTtRQUN2QyxpQ0FBNEIsR0FBRyx3QkFBd0IsQ0FBQTtJQTZCakUsQ0FBQztJQTNCQyxJQUFJLFlBQVk7UUFDZCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUE7SUFDM0IsQ0FBQztJQUVELElBQUksWUFBWSxDQUFDLEtBQWM7UUFDN0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUE7SUFDNUIsQ0FBQztJQUVELElBQUkscUNBQXFDO1FBQ3ZDLE9BQU8sSUFBSSxDQUFDLHNDQUFzQyxDQUFBO0lBQ3BELENBQUM7SUFFRCxJQUFJLHFDQUFxQyxDQUFDLEtBQWE7UUFDckQsSUFBSSxDQUFDLHNDQUFzQyxHQUFHLEtBQUssQ0FBQTtJQUNyRCxDQUFDO0lBRUQsSUFBSSw4QkFBOEI7UUFDaEMsT0FBTyxJQUFJLENBQUMsK0JBQStCLENBQUE7SUFDN0MsQ0FBQztJQUVELElBQUksOEJBQThCLENBQUMsS0FBYztRQUMvQyxJQUFJLENBQUMsK0JBQStCLEdBQUcsS0FBSyxDQUFBO0lBQzlDLENBQUM7SUFFRCxJQUFJLDJCQUEyQjtRQUM3QixPQUFPLElBQUksQ0FBQyw0QkFBNEIsQ0FBQTtJQUMxQyxDQUFDO0NBQ0Y7QUFqQ0QsZ0RBaUNDO0FBRUQ7O0dBRUc7QUFDVSxRQUFBLE1BQU0sR0FBRyxJQUFJLGtCQUFrQixFQUFFLENBQUEifQ==
@@ -0,0 +1,53 @@
1
+ import { whichSync } from './generalUtils.js';
2
+ export interface CreateTarballOptions {
3
+ /**
4
+ * A list of files or directories to exclude from the tarball.
5
+ * The paths should be relative to the directoryToTarball.
6
+ */
7
+ excludes?: string[];
8
+ }
9
+ export interface TarballUnpackOptions {
10
+ createDirIfNotExists?: boolean;
11
+ stripComponents?: number;
12
+ throwOnNonEmptyUnpackDir?: boolean;
13
+ }
14
+ /**
15
+ * This utility class exists so we can mock the `which` dependency in unit tests without resorting to libraries that hack the import system.
16
+ */
17
+ export declare class TarballUtility {
18
+ private whichSyncFn;
19
+ constructor(whichSyncFn: typeof whichSync);
20
+ /**
21
+ * Creates a gzipped tarball from a directory by spawning a process to run OS-installed `tar` to avoid pulling in npm package dependencies.
22
+ * Note that Windows has tar since Windows 10 1803 (see https://devblogs.microsoft.com/commandline/windows10v1803/.
23
+ *
24
+ * It's possible this isn't 100% reliable due to differences in `tar` versions across platforms. If better normalization
25
+ * is required, consider using the npm package `node-tar` instead.
26
+ * @param directoryToTarball The directory to tarball. The directory name will be used as the root directory in the tarball
27
+ * @param tarballPath The path to the tarball to create - must end with '.tar.gz'
28
+ * @param options See {@link CreateTarballOptions}
29
+ */
30
+ createTarball: (directoryToTarball: string, tarballPath: string, options?: CreateTarballOptions) => Promise<void>;
31
+ /**
32
+ * Unpacks a gzipped tarball by spawning a process to run OS-installed `tar` to avoid pulling in npm package dependencies.
33
+ * This method will throw an error if the unpackDirectory is not empty, unless the `throwOnNonEmptyUnpackDir` option is set to false.
34
+ * @param tarballPath The path to the tarball to unpack
35
+ * @param unpackDirectory The directory to unpack the tarball into
36
+ * @param options The options to use when unpacking the tarball. See {@link TarballUnpackOptions}.
37
+ */
38
+ unpackTarball: (tarballPath: string, unpackDirectory: string, options?: TarballUnpackOptions) => Promise<void>;
39
+ /**
40
+ * A more opinionated version of {@link unpackTarball} that assumes you want to create the directory and strip the first directory out of the unpacked files.
41
+ * @param tarballPath The path to the tarball to unpack
42
+ * @param unpackDirectory The directory to unpack the tarball into - will be created if it doesn't exist and will throw if it exists but is not empty
43
+ * @param stripComponents The number of leading directories to strip out of the unpacked files, defaults to 1
44
+ */
45
+ unpackTarballContents: (tarballPath: string, unpackDirectory: string, stripComponents?: number) => Promise<void>;
46
+ private isDirectory;
47
+ private dirIsNotEmpty;
48
+ private tryCreateDirectory;
49
+ }
50
+ export declare const createTarball: (directoryToTarball: string, tarballPath: string, options?: CreateTarballOptions) => Promise<void>;
51
+ export declare const unpackTarball: (tarballPath: string, unpackDirectory: string, options?: TarballUnpackOptions) => Promise<void>;
52
+ export declare const unpackTarballContents: (tarballPath: string, unpackDirectory: string, stripComponents?: number) => Promise<void>;
53
+ //# sourceMappingURL=TarballUtility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TarballUtility.d.ts","sourceRoot":"","sources":["../../src/TarballUtility.ts"],"names":[],"mappings":"AAGA,OAAO,EAA8D,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAGzG,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,wBAAwB,CAAC,EAAE,OAAO,CAAA;CACnC;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAkB;gBAEzB,WAAW,EAAE,OAAO,SAAS;IAIzC;;;;;;;;;OASG;IACH,aAAa,uBAA8B,MAAM,eAAe,MAAM,YAAY,oBAAoB,mBA4CrG;IAED;;;;;;OAMG;IACH,aAAa,gBAAuB,MAAM,mBAAmB,MAAM,YAAY,oBAAoB,mBA0ClG;IAED;;;;;OAKG;IACH,qBAAqB,gBAAuB,MAAM,mBAAmB,MAAM,oBAAmB,MAAM,mBAEnG;IAED,OAAO,CAAC,WAAW,CAOlB;IAED,OAAO,CAAC,aAAa,CAOpB;IAED,OAAO,CAAC,kBAAkB,CAUzB;CACF;AAID,eAAO,MAAM,aAAa,uBA5ImB,MAAM,eAAe,MAAM,YAAY,oBAAoB,kBA4IlD,CAAA;AACtD,eAAO,MAAM,aAAa,gBAxFY,MAAM,mBAAmB,MAAM,YAAY,oBAAoB,kBAwF/C,CAAA;AACtD,eAAO,MAAM,qBAAqB,gBAvCY,MAAM,mBAAmB,MAAM,oBAAmB,MAAM,kBAuChC,CAAA"}
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.unpackTarballContents = exports.unpackTarball = exports.createTarball = exports.TarballUtility = void 0;
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const promises_1 = __importDefault(require("node:fs/promises"));
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const generalUtils_js_1 = require("./generalUtils.js");
11
+ const NodeCliUtilsConfig_js_1 = require("./NodeCliUtilsConfig.js");
12
+ /**
13
+ * This utility class exists so we can mock the `which` dependency in unit tests without resorting to libraries that hack the import system.
14
+ */
15
+ class TarballUtility {
16
+ constructor(whichSyncFn) {
17
+ /**
18
+ * Creates a gzipped tarball from a directory by spawning a process to run OS-installed `tar` to avoid pulling in npm package dependencies.
19
+ * Note that Windows has tar since Windows 10 1803 (see https://devblogs.microsoft.com/commandline/windows10v1803/.
20
+ *
21
+ * It's possible this isn't 100% reliable due to differences in `tar` versions across platforms. If better normalization
22
+ * is required, consider using the npm package `node-tar` instead.
23
+ * @param directoryToTarball The directory to tarball. The directory name will be used as the root directory in the tarball
24
+ * @param tarballPath The path to the tarball to create - must end with '.tar.gz'
25
+ * @param options See {@link CreateTarballOptions}
26
+ */
27
+ this.createTarball = async (directoryToTarball, tarballPath, options) => {
28
+ (0, generalUtils_js_1.requireValidPath)('directoryToTarball', directoryToTarball);
29
+ (0, generalUtils_js_1.requireString)('tarballPath', tarballPath);
30
+ const defaultOptions = { excludes: [] };
31
+ const mergedOptions = { ...defaultOptions, ...options };
32
+ if (!this.whichSyncFn('tar').location) {
33
+ throw new Error('tar command not found - please install tar on your OS to use this method, or consider using the npm package node-tar instead');
34
+ }
35
+ if (!node_fs_1.default.existsSync(directoryToTarball)) {
36
+ throw new Error(`directoryToTarball does not exist: ${directoryToTarball}`);
37
+ }
38
+ if (tarballPath.endsWith('.tar.gz') === false) {
39
+ throw new Error(`tarballPath must end with '.tar.gz': ${tarballPath}`);
40
+ }
41
+ const directoryToTarballParentDir = node_path_1.default.dirname(directoryToTarball);
42
+ const directoryToTarballName = node_path_1.default.basename(directoryToTarball);
43
+ const outputDirectory = node_path_1.default.dirname(tarballPath);
44
+ const tarballName = node_path_1.default.basename(tarballPath);
45
+ if (!node_fs_1.default.existsSync(outputDirectory)) {
46
+ (0, generalUtils_js_1.trace)(`tarballPath directory does not exist - creating '${outputDirectory}'`);
47
+ await (0, generalUtils_js_1.mkdirp)(outputDirectory);
48
+ }
49
+ else if (node_fs_1.default.existsSync(tarballPath)) {
50
+ (0, generalUtils_js_1.trace)(`removing existing tarball '${tarballName}' before creating new one`);
51
+ await promises_1.default.unlink(tarballPath);
52
+ }
53
+ const excludesArgs = mergedOptions.excludes.length > 0 ? mergedOptions.excludes.map(exclude => `--exclude=${exclude}`) : [];
54
+ const verboseFlag = NodeCliUtilsConfig_js_1.config.traceEnabled ? ['-v'] : [];
55
+ const args = [...(verboseFlag), '-czf', tarballPath, '-C', directoryToTarballParentDir, ...excludesArgs, directoryToTarballName];
56
+ const result = await (0, generalUtils_js_1.spawnAsync)('tar', args);
57
+ if (result.code !== 0) {
58
+ throw new Error(`tar command failed with code ${result.code}`);
59
+ }
60
+ (0, generalUtils_js_1.trace)('tarball created: ' + tarballPath);
61
+ };
62
+ /**
63
+ * Unpacks a gzipped tarball by spawning a process to run OS-installed `tar` to avoid pulling in npm package dependencies.
64
+ * This method will throw an error if the unpackDirectory is not empty, unless the `throwOnNonEmptyUnpackDir` option is set to false.
65
+ * @param tarballPath The path to the tarball to unpack
66
+ * @param unpackDirectory The directory to unpack the tarball into
67
+ * @param options The options to use when unpacking the tarball. See {@link TarballUnpackOptions}.
68
+ */
69
+ this.unpackTarball = async (tarballPath, unpackDirectory, options) => {
70
+ (0, generalUtils_js_1.requireValidPath)('tarballPath', tarballPath);
71
+ (0, generalUtils_js_1.requireString)('unpackDirectory', unpackDirectory);
72
+ if (!this.whichSyncFn('tar').location) {
73
+ throw new Error('tar command not found - please install tar on your OS to use this method, or consider using the npm package node-tar instead');
74
+ }
75
+ const defaultOptions = { createDirIfNotExists: false, stripComponents: 0, throwOnNonEmptyUnpackDir: true };
76
+ const mergedOptions = { ...defaultOptions, ...options };
77
+ if (mergedOptions.stripComponents < 0) {
78
+ throw new Error('stripComponents must be greater than or equal to 0 if provided');
79
+ }
80
+ const unpackedDirExists = node_fs_1.default.existsSync(unpackDirectory);
81
+ if (unpackedDirExists && !this.isDirectory(unpackDirectory)) {
82
+ throw new Error(`unpackDirectory exists but is not a directory: ${unpackDirectory}`);
83
+ }
84
+ if (mergedOptions.createDirIfNotExists && !unpackedDirExists) {
85
+ await this.tryCreateDirectory(unpackDirectory);
86
+ }
87
+ if (!mergedOptions.createDirIfNotExists && !unpackedDirExists) {
88
+ throw new Error(`unpackDirectory does not exist: ${unpackDirectory}`);
89
+ }
90
+ if (mergedOptions.throwOnNonEmptyUnpackDir && this.dirIsNotEmpty(unpackDirectory)) {
91
+ throw new Error(`unpackDirectory exists but is not empty: ${unpackDirectory}`);
92
+ }
93
+ const verboseFlag = NodeCliUtilsConfig_js_1.config.traceEnabled ? ['-v'] : [];
94
+ const args = [...(verboseFlag), '-xzf', tarballPath, '-C', unpackDirectory, '--strip-components', mergedOptions.stripComponents.toString()];
95
+ const result = await (0, generalUtils_js_1.spawnAsync)('tar', args);
96
+ if (result.code !== 0) {
97
+ throw new Error(`tar command failed with code ${result.code}`);
98
+ }
99
+ (0, generalUtils_js_1.trace)(`tarball unpacked at ${unpackDirectory}`);
100
+ };
101
+ /**
102
+ * A more opinionated version of {@link unpackTarball} that assumes you want to create the directory and strip the first directory out of the unpacked files.
103
+ * @param tarballPath The path to the tarball to unpack
104
+ * @param unpackDirectory The directory to unpack the tarball into - will be created if it doesn't exist and will throw if it exists but is not empty
105
+ * @param stripComponents The number of leading directories to strip out of the unpacked files, defaults to 1
106
+ */
107
+ this.unpackTarballContents = async (tarballPath, unpackDirectory, stripComponents = 1) => {
108
+ await this.unpackTarball(tarballPath, unpackDirectory, { stripComponents, createDirIfNotExists: true });
109
+ };
110
+ this.isDirectory = (path) => {
111
+ try {
112
+ const stats = node_fs_1.default.statSync(path);
113
+ return stats.isDirectory();
114
+ }
115
+ catch (err) {
116
+ return false;
117
+ }
118
+ };
119
+ this.dirIsNotEmpty = (dirPath) => {
120
+ try {
121
+ const stats = node_fs_1.default.statSync(dirPath);
122
+ return stats.isDirectory() && node_fs_1.default.readdirSync(dirPath).length > 0;
123
+ }
124
+ catch (err) {
125
+ return false;
126
+ }
127
+ };
128
+ this.tryCreateDirectory = async (dirPath) => {
129
+ try {
130
+ await (0, generalUtils_js_1.mkdirp)(dirPath);
131
+ }
132
+ catch (err) {
133
+ if (err instanceof Error) {
134
+ throw new Error(`Error creating unpackDirectory: ${err.message}`);
135
+ }
136
+ else {
137
+ throw new Error(`Error creating unpackDirectory: ${err}`);
138
+ }
139
+ }
140
+ };
141
+ this.whichSyncFn = whichSyncFn;
142
+ }
143
+ }
144
+ exports.TarballUtility = TarballUtility;
145
+ const defaultUtil = new TarballUtility(generalUtils_js_1.whichSync);
146
+ exports.createTarball = defaultUtil.createTarball;
147
+ exports.unpackTarball = defaultUtil.unpackTarball;
148
+ exports.unpackTarballContents = defaultUtil.unpackTarballContents;
149
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGFyYmFsbFV0aWxpdHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvVGFyYmFsbFV0aWxpdHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsc0RBQXdCO0FBQ3hCLGdFQUFrQztBQUNsQywwREFBNEI7QUFDNUIsdURBQXlHO0FBQ3pHLG1FQUFnRDtBQWdCaEQ7O0dBRUc7QUFDSCxNQUFhLGNBQWM7SUFHekIsWUFBWSxXQUE2QjtRQUl6Qzs7Ozs7Ozs7O1dBU0c7UUFDSCxrQkFBYSxHQUFHLEtBQUssRUFBRSxrQkFBMEIsRUFBRSxXQUFtQixFQUFFLE9BQThCLEVBQUUsRUFBRTtZQUN4RyxJQUFBLGtDQUFnQixFQUFDLG9CQUFvQixFQUFFLGtCQUFrQixDQUFDLENBQUE7WUFDMUQsSUFBQSwrQkFBYSxFQUFDLGFBQWEsRUFBRSxXQUFXLENBQUMsQ0FBQTtZQUV6QyxNQUFNLGNBQWMsR0FBRyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsQ0FBQTtZQUN2QyxNQUFNLGFBQWEsR0FBRyxFQUFFLEdBQUcsY0FBYyxFQUFFLEdBQUcsT0FBTyxFQUFFLENBQUE7WUFFdkQsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxFQUFFO2dCQUNyQyxNQUFNLElBQUksS0FBSyxDQUFDLDhIQUE4SCxDQUFDLENBQUE7YUFDaEo7WUFFRCxJQUFJLENBQUMsaUJBQUUsQ0FBQyxVQUFVLENBQUMsa0JBQWtCLENBQUMsRUFBRTtnQkFDdEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQ0FBc0Msa0JBQWtCLEVBQUUsQ0FBQyxDQUFBO2FBQzVFO1lBRUQsSUFBSSxXQUFXLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEtBQUssRUFBRTtnQkFDN0MsTUFBTSxJQUFJLEtBQUssQ0FBQyx3Q0FBd0MsV0FBVyxFQUFFLENBQUMsQ0FBQTthQUN2RTtZQUVELE1BQU0sMkJBQTJCLEdBQUcsbUJBQUks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
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Wrapper function for calling openssl to generate a self-signed cert to be used for developing a local website with trusted https.
3
+ * @param url The url to generate a cert for. This will be used as the common name (CN) in the cert as well as the filename for the generated cert files.
4
+ * @param outputDirectory The directory to write the generated cert files to. Defaults to './cert'.
5
+ */
6
+ export declare function generateCertWithOpenSsl(url: string, outputDirectory?: string): Promise<void>;
7
+ /**
8
+ * Uses Powershell to install a cert to the local machine's trusted root store. Must have admin permissions.
9
+ *
10
+ * If the cert is already installed, this method will do nothing.
11
+ * @param urlOrCertFilename The url or cert filename to install. The url + '.pfx' or the cert filename passed must match a file that exists in the certDirectory.
12
+ * @param certDirectory The directory to look for the cert file in. Defaults to './cert'.
13
+ */
14
+ export declare function winInstallCert(urlOrCertFilename: string, certDirectory?: string): Promise<void>;
15
+ /**
16
+ * Uses Powershell to uninstall a cert from the local machine's trusted root store. Must have admin permissions.
17
+ * @param urlOrSubject The url or subject of the cert to uninstall. If the cert was installed with the winInstallCert method, this will be the url passed to that method.
18
+ */
19
+ export declare function winUninstallCert(urlOrSubject: string): Promise<void>;
20
+ /**
21
+ * Does not actually do anything - just outputs the manual instructions for installing a cert for use by chrome on linux.
22
+ */
23
+ export declare function linuxInstallCert(): void;
24
+ /**
25
+ * Uses Powershell to check if a cert is already installed to the local machine's trusted root store.
26
+ * @param urlOrSubject The url or subject of the cert to check. If the cert was installed with the winInstallCert method, this will be the url passed to that method.
27
+ * @returns `true` if the cert is already installed, `false` otherwise.
28
+ */
29
+ export declare function winCertAlreadyInstalled(urlOrSubject: string): Promise<boolean>;
30
+ //# sourceMappingURL=certUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"certUtils.d.ts","sourceRoot":"","sources":["../../src/certUtils.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,eAAe,GAAE,MAAiB,iBAuD5F;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,iBAAiB,EAAE,MAAM,EAAE,aAAa,SAAW,iBA8BvF;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,MAAM,iBAY1D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,SAU/B;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAmBpF"}