es-toolkit 1.46.1-dev.1806 → 1.46.1-dev.1808

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.
@@ -0,0 +1,63 @@
1
+ import { SpawnOptions } from "node:child_process";
2
+
3
+ //#region src/server/exec.d.ts
4
+ interface ExecOptions {
5
+ signal?: AbortSignal;
6
+ timeout?: number;
7
+ stdin?: string;
8
+ spawnOptions?: SpawnOptions;
9
+ throwOnNonZeroExitCode?: boolean;
10
+ }
11
+ interface ExecResult {
12
+ pid: number | undefined;
13
+ stderr: string;
14
+ stdout: string;
15
+ exitCode: number | null;
16
+ }
17
+ /**
18
+ * Executes a command and captures its output.
19
+ *
20
+ * This function spawns a child process, collects its stdout and stderr, and resolves with the
21
+ * process result when execution finishes. By default, it throws an {@link ExecError} when the
22
+ * process exits with a non-zero exit code.
23
+ *
24
+ * @param {string} _command - The command to execute.
25
+ * @param {string[]} args - The arguments passed to the command.
26
+ * @param {ExecOptions} options - The options object.
27
+ * @param {AbortSignal} options.signal - An optional AbortSignal used to abort the process.
28
+ * @param {number} options.timeout - An optional timeout in milliseconds. When provided, the
29
+ * process is aborted after the timeout expires.
30
+ * @param {string} options.stdin - An optional string written to the process stdin.
31
+ * @param {SpawnOptions} options.spawnOptions - Additional options forwarded to `child_process.spawn`.
32
+ * @param {boolean} options.throwOnNonZeroExitCode - Whether to throw an {@link ExecError} when the
33
+ * process exits with a non-zero exit code. Defaults to `true`.
34
+ * @returns {Promise<ExecResult>} A promise that resolves with the process result.
35
+ * @throws {ExecError} Throws when `throwOnNonZeroExitCode` is enabled and the process exits with a
36
+ * non-zero exit code.
37
+ *
38
+ * @example
39
+ * const result = await exec('echo', ['hello']);
40
+ *
41
+ * console.log(result.stdout.trim());
42
+ * // => 'hello'
43
+ *
44
+ * @example
45
+ * const result = await exec('git', ['diff', '--quiet'], {
46
+ * throwOnNonZeroExitCode: false,
47
+ * });
48
+ *
49
+ * console.log(result.exitCode);
50
+ * // => 1 when there are changes
51
+ */
52
+ declare function exec(_command: string, args?: string[], options?: ExecOptions): Promise<ExecResult>;
53
+ /**
54
+ * Represents an error thrown when a process exits with a non-zero exit code.
55
+ *
56
+ * @param {ExecResult} result - The captured process result.
57
+ */
58
+ declare class ExecError extends Error {
59
+ readonly result: ExecResult;
60
+ constructor(result: ExecResult);
61
+ }
62
+ //#endregion
63
+ export { ExecError, exec };
@@ -0,0 +1,63 @@
1
+ import { SpawnOptions } from "node:child_process";
2
+
3
+ //#region src/server/exec.d.ts
4
+ interface ExecOptions {
5
+ signal?: AbortSignal;
6
+ timeout?: number;
7
+ stdin?: string;
8
+ spawnOptions?: SpawnOptions;
9
+ throwOnNonZeroExitCode?: boolean;
10
+ }
11
+ interface ExecResult {
12
+ pid: number | undefined;
13
+ stderr: string;
14
+ stdout: string;
15
+ exitCode: number | null;
16
+ }
17
+ /**
18
+ * Executes a command and captures its output.
19
+ *
20
+ * This function spawns a child process, collects its stdout and stderr, and resolves with the
21
+ * process result when execution finishes. By default, it throws an {@link ExecError} when the
22
+ * process exits with a non-zero exit code.
23
+ *
24
+ * @param {string} _command - The command to execute.
25
+ * @param {string[]} args - The arguments passed to the command.
26
+ * @param {ExecOptions} options - The options object.
27
+ * @param {AbortSignal} options.signal - An optional AbortSignal used to abort the process.
28
+ * @param {number} options.timeout - An optional timeout in milliseconds. When provided, the
29
+ * process is aborted after the timeout expires.
30
+ * @param {string} options.stdin - An optional string written to the process stdin.
31
+ * @param {SpawnOptions} options.spawnOptions - Additional options forwarded to `child_process.spawn`.
32
+ * @param {boolean} options.throwOnNonZeroExitCode - Whether to throw an {@link ExecError} when the
33
+ * process exits with a non-zero exit code. Defaults to `true`.
34
+ * @returns {Promise<ExecResult>} A promise that resolves with the process result.
35
+ * @throws {ExecError} Throws when `throwOnNonZeroExitCode` is enabled and the process exits with a
36
+ * non-zero exit code.
37
+ *
38
+ * @example
39
+ * const result = await exec('echo', ['hello']);
40
+ *
41
+ * console.log(result.stdout.trim());
42
+ * // => 'hello'
43
+ *
44
+ * @example
45
+ * const result = await exec('git', ['diff', '--quiet'], {
46
+ * throwOnNonZeroExitCode: false,
47
+ * });
48
+ *
49
+ * console.log(result.exitCode);
50
+ * // => 1 when there are changes
51
+ */
52
+ declare function exec(_command: string, args?: string[], options?: ExecOptions): Promise<ExecResult>;
53
+ /**
54
+ * Represents an error thrown when a process exits with a non-zero exit code.
55
+ *
56
+ * @param {ExecResult} result - The captured process result.
57
+ */
58
+ declare class ExecError extends Error {
59
+ readonly result: ExecResult;
60
+ constructor(result: ExecResult);
61
+ }
62
+ //#endregion
63
+ export { ExecError, exec };
@@ -0,0 +1,103 @@
1
+ let node_child_process = require("node:child_process");
2
+ let node_path = require("node:path");
3
+ //#region src/server/exec.ts
4
+ /**
5
+ * Executes a command and captures its output.
6
+ *
7
+ * This function spawns a child process, collects its stdout and stderr, and resolves with the
8
+ * process result when execution finishes. By default, it throws an {@link ExecError} when the
9
+ * process exits with a non-zero exit code.
10
+ *
11
+ * @param {string} _command - The command to execute.
12
+ * @param {string[]} args - The arguments passed to the command.
13
+ * @param {ExecOptions} options - The options object.
14
+ * @param {AbortSignal} options.signal - An optional AbortSignal used to abort the process.
15
+ * @param {number} options.timeout - An optional timeout in milliseconds. When provided, the
16
+ * process is aborted after the timeout expires.
17
+ * @param {string} options.stdin - An optional string written to the process stdin.
18
+ * @param {SpawnOptions} options.spawnOptions - Additional options forwarded to `child_process.spawn`.
19
+ * @param {boolean} options.throwOnNonZeroExitCode - Whether to throw an {@link ExecError} when the
20
+ * process exits with a non-zero exit code. Defaults to `true`.
21
+ * @returns {Promise<ExecResult>} A promise that resolves with the process result.
22
+ * @throws {ExecError} Throws when `throwOnNonZeroExitCode` is enabled and the process exits with a
23
+ * non-zero exit code.
24
+ *
25
+ * @example
26
+ * const result = await exec('echo', ['hello']);
27
+ *
28
+ * console.log(result.stdout.trim());
29
+ * // => 'hello'
30
+ *
31
+ * @example
32
+ * const result = await exec('git', ['diff', '--quiet'], {
33
+ * throwOnNonZeroExitCode: false,
34
+ * });
35
+ *
36
+ * console.log(result.exitCode);
37
+ * // => 1 when there are changes
38
+ */
39
+ async function exec(_command, args = [], options = {}) {
40
+ const command = (0, node_path.normalize)(_command);
41
+ const signal = parseAbortSignal(options);
42
+ const resolver = Promise.withResolvers();
43
+ const process = (0, node_child_process.spawn)(command, args, {
44
+ windowsHide: true,
45
+ ...options.spawnOptions,
46
+ signal
47
+ });
48
+ handleStdin(process, options);
49
+ process.once("close", () => {
50
+ resolver.resolve();
51
+ });
52
+ process.once("error", (error) => {
53
+ resolver.reject(error);
54
+ });
55
+ const stdoutPromise = process.stdout != null ? streamToString(process.stdout) : Promise.resolve("");
56
+ const stderrPromise = process.stderr != null ? streamToString(process.stderr) : Promise.resolve("");
57
+ await resolver.promise;
58
+ const stdout = await stdoutPromise;
59
+ const stderr = await stderrPromise;
60
+ if ((options.throwOnNonZeroExitCode ?? true) && process.exitCode !== 0) throw new ExecError({
61
+ pid: process.pid,
62
+ stdout,
63
+ stderr,
64
+ exitCode: process.exitCode
65
+ });
66
+ return {
67
+ pid: process.pid,
68
+ stdout,
69
+ stderr,
70
+ exitCode: process.exitCode
71
+ };
72
+ }
73
+ /**
74
+ * Represents an error thrown when a process exits with a non-zero exit code.
75
+ *
76
+ * @param {ExecResult} result - The captured process result.
77
+ */
78
+ var ExecError = class extends Error {
79
+ result;
80
+ constructor(result) {
81
+ super(`Process exited with non-zero exit code (${result.exitCode})`);
82
+ this.result = result;
83
+ this.name = "ExecError";
84
+ }
85
+ };
86
+ async function streamToString(stream) {
87
+ return Buffer.concat(await stream.toArray()).toString("utf-8");
88
+ }
89
+ function handleStdin(process, options) {
90
+ if (options.stdin == null) return;
91
+ if (typeof options.stdin === "string") process.stdin?.end(options.stdin);
92
+ }
93
+ function parseAbortSignal(options) {
94
+ const signals = [];
95
+ if (options.signal != null) signals.push(options.signal);
96
+ if (options.timeout != null) signals.push(AbortSignal.timeout(options.timeout));
97
+ if (options.spawnOptions?.signal != null) signals.push(options.spawnOptions.signal);
98
+ if (signals.length === 0) return;
99
+ return AbortSignal.any(signals);
100
+ }
101
+ //#endregion
102
+ exports.ExecError = ExecError;
103
+ exports.exec = exec;
@@ -0,0 +1,102 @@
1
+ import { spawn } from "node:child_process";
2
+ import { normalize } from "node:path";
3
+ //#region src/server/exec.ts
4
+ /**
5
+ * Executes a command and captures its output.
6
+ *
7
+ * This function spawns a child process, collects its stdout and stderr, and resolves with the
8
+ * process result when execution finishes. By default, it throws an {@link ExecError} when the
9
+ * process exits with a non-zero exit code.
10
+ *
11
+ * @param {string} _command - The command to execute.
12
+ * @param {string[]} args - The arguments passed to the command.
13
+ * @param {ExecOptions} options - The options object.
14
+ * @param {AbortSignal} options.signal - An optional AbortSignal used to abort the process.
15
+ * @param {number} options.timeout - An optional timeout in milliseconds. When provided, the
16
+ * process is aborted after the timeout expires.
17
+ * @param {string} options.stdin - An optional string written to the process stdin.
18
+ * @param {SpawnOptions} options.spawnOptions - Additional options forwarded to `child_process.spawn`.
19
+ * @param {boolean} options.throwOnNonZeroExitCode - Whether to throw an {@link ExecError} when the
20
+ * process exits with a non-zero exit code. Defaults to `true`.
21
+ * @returns {Promise<ExecResult>} A promise that resolves with the process result.
22
+ * @throws {ExecError} Throws when `throwOnNonZeroExitCode` is enabled and the process exits with a
23
+ * non-zero exit code.
24
+ *
25
+ * @example
26
+ * const result = await exec('echo', ['hello']);
27
+ *
28
+ * console.log(result.stdout.trim());
29
+ * // => 'hello'
30
+ *
31
+ * @example
32
+ * const result = await exec('git', ['diff', '--quiet'], {
33
+ * throwOnNonZeroExitCode: false,
34
+ * });
35
+ *
36
+ * console.log(result.exitCode);
37
+ * // => 1 when there are changes
38
+ */
39
+ async function exec(_command, args = [], options = {}) {
40
+ const command = normalize(_command);
41
+ const signal = parseAbortSignal(options);
42
+ const resolver = Promise.withResolvers();
43
+ const process = spawn(command, args, {
44
+ windowsHide: true,
45
+ ...options.spawnOptions,
46
+ signal
47
+ });
48
+ handleStdin(process, options);
49
+ process.once("close", () => {
50
+ resolver.resolve();
51
+ });
52
+ process.once("error", (error) => {
53
+ resolver.reject(error);
54
+ });
55
+ const stdoutPromise = process.stdout != null ? streamToString(process.stdout) : Promise.resolve("");
56
+ const stderrPromise = process.stderr != null ? streamToString(process.stderr) : Promise.resolve("");
57
+ await resolver.promise;
58
+ const stdout = await stdoutPromise;
59
+ const stderr = await stderrPromise;
60
+ if ((options.throwOnNonZeroExitCode ?? true) && process.exitCode !== 0) throw new ExecError({
61
+ pid: process.pid,
62
+ stdout,
63
+ stderr,
64
+ exitCode: process.exitCode
65
+ });
66
+ return {
67
+ pid: process.pid,
68
+ stdout,
69
+ stderr,
70
+ exitCode: process.exitCode
71
+ };
72
+ }
73
+ /**
74
+ * Represents an error thrown when a process exits with a non-zero exit code.
75
+ *
76
+ * @param {ExecResult} result - The captured process result.
77
+ */
78
+ var ExecError = class extends Error {
79
+ result;
80
+ constructor(result) {
81
+ super(`Process exited with non-zero exit code (${result.exitCode})`);
82
+ this.result = result;
83
+ this.name = "ExecError";
84
+ }
85
+ };
86
+ async function streamToString(stream) {
87
+ return Buffer.concat(await stream.toArray()).toString("utf-8");
88
+ }
89
+ function handleStdin(process, options) {
90
+ if (options.stdin == null) return;
91
+ if (typeof options.stdin === "string") process.stdin?.end(options.stdin);
92
+ }
93
+ function parseAbortSignal(options) {
94
+ const signals = [];
95
+ if (options.signal != null) signals.push(options.signal);
96
+ if (options.timeout != null) signals.push(AbortSignal.timeout(options.timeout));
97
+ if (options.spawnOptions?.signal != null) signals.push(options.spawnOptions.signal);
98
+ if (signals.length === 0) return;
99
+ return AbortSignal.any(signals);
100
+ }
101
+ //#endregion
102
+ export { ExecError, exec };
@@ -1,3 +1,4 @@
1
1
  import { ColorFunction } from "./colors/types.mjs";
2
2
  import { colors } from "./colors/index.mjs";
3
- export { type ColorFunction, colors };
3
+ import { ExecError, exec } from "./exec.mjs";
4
+ export { type ColorFunction, ExecError, colors, exec };
@@ -1,3 +1,4 @@
1
1
  import { ColorFunction } from "./colors/types.js";
2
2
  import { colors } from "./colors/index.js";
3
- export { type ColorFunction, colors };
3
+ import { ExecError, exec } from "./exec.js";
4
+ export { type ColorFunction, ExecError, colors, exec };
@@ -1,3 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_index = require("./colors/index.js");
3
+ const require_exec = require("./exec.js");
4
+ exports.ExecError = require_exec.ExecError;
3
5
  exports.colors = require_index.colors;
6
+ exports.exec = require_exec.exec;
@@ -1,2 +1,3 @@
1
1
  import { colors } from "./colors/index.mjs";
2
- export { colors };
2
+ import { ExecError, exec } from "./exec.mjs";
3
+ export { ExecError, colors, exec };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "es-toolkit",
3
- "version": "1.46.1-dev.1806+e105eb93",
3
+ "version": "1.46.1-dev.1808+66f2610f",
4
4
  "description": "A state-of-the-art, high-performance JavaScript utility library with a small bundle size and strong type annotations.",
5
5
  "homepage": "https://es-toolkit.dev",
6
6
  "bugs": "https://github.com/toss/es-toolkit/issues",