@versatiles/release-tool 2.5.0 → 2.7.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/dist/lib/log.d.ts CHANGED
@@ -1,5 +1,65 @@
1
+ /**
2
+ * Enables or disables verbose logging mode.
3
+ * When enabled, debug messages will be printed to stderr.
4
+ *
5
+ * @param enabled - Whether to enable verbose mode.
6
+ */
7
+ export declare function setVerbose(enabled: boolean): void;
8
+ /**
9
+ * Checks if verbose mode is currently enabled.
10
+ *
11
+ * @returns `true` if verbose mode is enabled, `false` otherwise.
12
+ */
13
+ export declare function isVerbose(): boolean;
14
+ /**
15
+ * Logs a fatal error message and terminates the process.
16
+ * The message is displayed in bold red text.
17
+ *
18
+ * @param text - The error message to display.
19
+ * @returns Never returns as the process is terminated.
20
+ */
1
21
  export declare function panic(text: string): never;
22
+ /**
23
+ * Logs a warning message to stderr.
24
+ * The message is displayed in bold yellow text.
25
+ *
26
+ * @param text - The warning message to display.
27
+ */
2
28
  export declare function warn(text: string): void;
29
+ /**
30
+ * Logs an informational message to stderr.
31
+ *
32
+ * @param text - The informational message to display.
33
+ */
3
34
  export declare function info(text: string): void;
35
+ /**
36
+ * Logs a debug message to stderr if verbose mode is enabled.
37
+ * The message is displayed in gray text.
38
+ *
39
+ * @param text - The debug message to display.
40
+ */
41
+ export declare function debug(text: string): void;
42
+ /**
43
+ * Logs an abort message and terminates the process with exit code 1.
44
+ *
45
+ * @returns Never returns as the process is terminated.
46
+ */
4
47
  export declare function abort(): never;
5
- export declare function check<T>(message: string, promise: (Promise<T>) | (() => Promise<T>)): Promise<T>;
48
+ /**
49
+ * Executes an async operation with progress indication.
50
+ * Displays a spinner-like message while the operation is in progress,
51
+ * then shows a success checkmark or failure X based on the result.
52
+ *
53
+ * @typeParam T - The return type of the promise.
54
+ * @param message - The message to display while the operation is running.
55
+ * @param promise - The promise to await, or a function that returns a promise.
56
+ * @returns The resolved value of the promise.
57
+ * @throws Calls `panic()` if the promise rejects, terminating the process.
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * const result = await check('Fetching data', fetchData());
62
+ * const result = await check('Processing', async () => processData());
63
+ * ```
64
+ */
65
+ export declare function check<T>(message: string, promise: Promise<T> | (() => Promise<T>)): Promise<T>;
package/dist/lib/log.js CHANGED
@@ -1,17 +1,88 @@
1
+ import { VrtError } from './errors.js';
2
+ /** Internal flag to track verbose mode state. */
3
+ let verboseMode = false;
4
+ /**
5
+ * Enables or disables verbose logging mode.
6
+ * When enabled, debug messages will be printed to stderr.
7
+ *
8
+ * @param enabled - Whether to enable verbose mode.
9
+ */
10
+ export function setVerbose(enabled) {
11
+ verboseMode = enabled;
12
+ }
13
+ /**
14
+ * Checks if verbose mode is currently enabled.
15
+ *
16
+ * @returns `true` if verbose mode is enabled, `false` otherwise.
17
+ */
18
+ export function isVerbose() {
19
+ return verboseMode;
20
+ }
21
+ /**
22
+ * Logs a fatal error message and terminates the process.
23
+ * The message is displayed in bold red text.
24
+ *
25
+ * @param text - The error message to display.
26
+ * @returns Never returns as the process is terminated.
27
+ */
1
28
  export function panic(text) {
2
29
  process.stderr.write(`\x1b[1;31m! ERROR: ${text}\x1b[0m\n`);
3
30
  abort();
4
31
  }
32
+ /**
33
+ * Logs a warning message to stderr.
34
+ * The message is displayed in bold yellow text.
35
+ *
36
+ * @param text - The warning message to display.
37
+ */
5
38
  export function warn(text) {
6
39
  process.stderr.write(`\x1b[1;33m! warning: ${text}\x1b[0m\n`);
7
40
  }
41
+ /**
42
+ * Logs an informational message to stderr.
43
+ *
44
+ * @param text - The informational message to display.
45
+ */
8
46
  export function info(text) {
9
47
  process.stderr.write(`\x1b[0mi ${text}\n`);
10
48
  }
49
+ /**
50
+ * Logs a debug message to stderr if verbose mode is enabled.
51
+ * The message is displayed in gray text.
52
+ *
53
+ * @param text - The debug message to display.
54
+ */
55
+ export function debug(text) {
56
+ if (verboseMode) {
57
+ process.stderr.write(`\x1b[0;90m ${text}\x1b[0m\n`);
58
+ }
59
+ }
60
+ /**
61
+ * Logs an abort message and terminates the process with exit code 1.
62
+ *
63
+ * @returns Never returns as the process is terminated.
64
+ */
11
65
  export function abort() {
12
66
  info('abort');
13
- process.exit();
67
+ process.exit(1);
14
68
  }
69
+ /**
70
+ * Executes an async operation with progress indication.
71
+ * Displays a spinner-like message while the operation is in progress,
72
+ * then shows a success checkmark or failure X based on the result.
73
+ *
74
+ * @typeParam T - The return type of the promise.
75
+ * @param message - The message to display while the operation is running.
76
+ * @param promise - The promise to await, or a function that returns a promise.
77
+ * @returns The resolved value of the promise.
78
+ * @throws Calls `panic()` if the promise rejects, terminating the process.
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * const result = await check('Fetching data', fetchData());
83
+ * const result = await check('Processing', async () => processData());
84
+ * ```
85
+ */
15
86
  export async function check(message, promise) {
16
87
  process.stderr.write(`\x1b[0;90m\u2B95 ${message}\x1b[0m`);
17
88
  try {
@@ -21,8 +92,10 @@ export async function check(message, promise) {
21
92
  }
22
93
  catch (error) {
23
94
  process.stderr.write(`\r\x1b[0;91m\u2718 ${message}\x1b[0m\n`);
24
- panic(error.message);
25
- throw error;
95
+ if (error instanceof VrtError) {
96
+ panic(`[${error.code}] ${error.message}`);
97
+ }
98
+ panic(error.message ?? String(error));
26
99
  }
27
100
  }
28
101
  //# sourceMappingURL=log.js.map
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Options for retry behavior
3
+ */
4
+ export interface RetryOptions {
5
+ /** Maximum number of retry attempts (default: 3) */
6
+ maxRetries?: number;
7
+ /** Initial delay in milliseconds before first retry (default: 1000) */
8
+ initialDelayMs?: number;
9
+ /** Multiplier for exponential backoff (default: 2) */
10
+ backoffMultiplier?: number;
11
+ /** Maximum delay in milliseconds (default: 30000) */
12
+ maxDelayMs?: number;
13
+ /** Optional callback called before each retry */
14
+ onRetry?: (attempt: number, error: Error, nextDelayMs: number) => void;
15
+ }
16
+ /**
17
+ * Executes an async function with retry logic and exponential backoff.
18
+ *
19
+ * @param fn - The async function to execute
20
+ * @param options - Retry configuration options
21
+ * @returns The result of the function if successful
22
+ * @throws The last error encountered after all retries are exhausted
23
+ */
24
+ export declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
@@ -0,0 +1,44 @@
1
+ const DEFAULT_OPTIONS = {
2
+ maxRetries: 3,
3
+ initialDelayMs: 1000,
4
+ backoffMultiplier: 2,
5
+ maxDelayMs: 30000,
6
+ };
7
+ /**
8
+ * Executes an async function with retry logic and exponential backoff.
9
+ *
10
+ * @param fn - The async function to execute
11
+ * @param options - Retry configuration options
12
+ * @returns The result of the function if successful
13
+ * @throws The last error encountered after all retries are exhausted
14
+ */
15
+ export async function withRetry(fn, options = {}) {
16
+ const { maxRetries, initialDelayMs, backoffMultiplier, maxDelayMs } = { ...DEFAULT_OPTIONS, ...options };
17
+ const { onRetry } = options;
18
+ let lastError;
19
+ let currentDelay = initialDelayMs;
20
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
21
+ try {
22
+ return await fn();
23
+ }
24
+ catch (error) {
25
+ lastError = error instanceof Error ? error : new Error(String(error));
26
+ if (attempt < maxRetries) {
27
+ const nextDelay = Math.min(currentDelay, maxDelayMs);
28
+ if (onRetry) {
29
+ onRetry(attempt + 1, lastError, nextDelay);
30
+ }
31
+ await sleep(nextDelay);
32
+ currentDelay *= backoffMultiplier;
33
+ }
34
+ }
35
+ }
36
+ throw lastError;
37
+ }
38
+ /**
39
+ * Sleep for a specified number of milliseconds
40
+ */
41
+ function sleep(ms) {
42
+ return new Promise((resolve) => setTimeout(resolve, ms));
43
+ }
44
+ //# sourceMappingURL=retry.js.map
@@ -1,17 +1,138 @@
1
+ /**
2
+ * Result of a shell command execution.
3
+ */
4
+ export interface ShellResult {
5
+ /** Exit code of the process, or null if terminated by signal. */
6
+ code: number | null;
7
+ /** Signal that terminated the process, or null if exited normally. */
8
+ signal: string | null;
9
+ /** Captured standard output. */
10
+ stdout: string;
11
+ /** Captured standard error. */
12
+ stderr: string;
13
+ }
14
+ /**
15
+ * Result of an interactive shell command execution.
16
+ */
17
+ export interface ShellInteractiveResult {
18
+ /** Exit code of the process, or null if terminated by signal. */
19
+ code: number | null;
20
+ /** Signal that terminated the process, or null if exited normally. */
21
+ signal: string | null;
22
+ }
23
+ /**
24
+ * A utility class for executing shell commands in a specified working directory.
25
+ * Provides methods for running commands with captured output, interactive commands,
26
+ * and convenience methods for common patterns.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * const shell = new Shell('/path/to/project');
31
+ * const output = await shell.stdout('git status');
32
+ * const success = await shell.ok('npm test');
33
+ * ```
34
+ */
1
35
  export declare class Shell {
36
+ /** The working directory for all commands. */
2
37
  private cwd;
38
+ /**
39
+ * Creates a new Shell instance.
40
+ *
41
+ * @param cwd - The working directory for executing commands.
42
+ */
3
43
  constructor(cwd: string);
4
- run(command: string, errorOnCodeNonZero?: boolean): Promise<{
5
- code: number | null;
6
- signal: string | null;
7
- stdout: string;
8
- stderr: string;
9
- }>;
10
- runInteractive(command: string, errorOnCodeNonZero?: boolean): Promise<{
11
- code: number | null;
12
- signal: string | null;
13
- }>;
44
+ /**
45
+ * Runs a shell command through bash and captures its output.
46
+ *
47
+ * @remarks
48
+ * **⚠️ SECURITY WARNING: Command Injection Risk**
49
+ *
50
+ * This method passes the command string directly to `bash -c`, which means
51
+ * shell metacharacters (`;`, `|`, `$()`, `` ` ``, etc.) are interpreted.
52
+ *
53
+ * **NEVER** pass unsanitized user input to this method:
54
+ * ```ts
55
+ * // DANGEROUS - command injection vulnerability!
56
+ * shell.run(`git checkout ${userInput}`); // userInput could be "; rm -rf /"
57
+ *
58
+ * // SAFE - use exec() with array arguments instead
59
+ * shell.exec('git', ['checkout', userInput]);
60
+ * ```
61
+ *
62
+ * Only use this method with:
63
+ * - Hardcoded command strings
64
+ * - Values that have been strictly validated (e.g., version numbers matching `/^\d+\.\d+\.\d+$/`)
65
+ *
66
+ * For commands with dynamic arguments, prefer {@link Shell.exec} which passes
67
+ * arguments directly without shell interpretation.
68
+ *
69
+ * @param command - The shell command to execute. Must be a trusted string.
70
+ * @param errorOnCodeNonZero - If true (default), rejects the promise on non-zero exit code.
71
+ * @returns A promise resolving to the command result with exit code, signal, stdout, and stderr.
72
+ * @throws Rejects with the result object if errorOnCodeNonZero is true and exit code is non-zero.
73
+ */
74
+ run(command: string, errorOnCodeNonZero?: boolean): Promise<ShellResult>;
75
+ /**
76
+ * Executes a command with arguments directly, avoiding shell escaping issues.
77
+ * Preferred over `run()` when dealing with arguments that may contain special characters.
78
+ *
79
+ * @param command - The command executable to run.
80
+ * @param args - Array of arguments to pass to the command.
81
+ * @param errorOnCodeNonZero - If true (default), rejects the promise on non-zero exit code.
82
+ * @param skipLog - If true, suppresses debug logging of the command.
83
+ * @returns A promise resolving to the command result with exit code, signal, stdout, and stderr.
84
+ * @throws Rejects with the result object if errorOnCodeNonZero is true and exit code is non-zero.
85
+ */
86
+ exec(command: string, args: string[], errorOnCodeNonZero?: boolean, skipLog?: boolean): Promise<ShellResult>;
87
+ /**
88
+ * Runs a command interactively with full TTY passthrough.
89
+ * The user can interact with the command's stdin/stdout/stderr directly.
90
+ * Useful for commands that require user input (e.g., npm publish with OTP).
91
+ *
92
+ * @remarks
93
+ * **⚠️ SECURITY WARNING:** Same command injection risks as {@link Shell.run}.
94
+ * Never pass unsanitized user input. See {@link Shell.run} for details.
95
+ *
96
+ * @param command - The shell command to execute. Must be a trusted string.
97
+ * @param errorOnCodeNonZero - If true (default), rejects the promise on non-zero exit code.
98
+ * @returns A promise resolving to the exit code and signal (no captured output).
99
+ * @throws Rejects with the result object if errorOnCodeNonZero is true and exit code is non-zero.
100
+ */
101
+ runInteractive(command: string, errorOnCodeNonZero?: boolean): Promise<ShellInteractiveResult>;
102
+ /**
103
+ * Runs a command and returns only the trimmed stderr output.
104
+ *
105
+ * @remarks
106
+ * **⚠️ SECURITY WARNING:** Uses {@link Shell.run} internally.
107
+ * Never pass unsanitized user input. See {@link Shell.run} for details.
108
+ *
109
+ * @param command - The shell command to execute. Must be a trusted string.
110
+ * @param errorOnCodeZero - If true (default), rejects on non-zero exit code.
111
+ * @returns A promise resolving to the trimmed stderr string.
112
+ */
14
113
  stderr(command: string, errorOnCodeZero?: boolean): Promise<string>;
114
+ /**
115
+ * Runs a command and returns only the trimmed stdout output.
116
+ *
117
+ * @remarks
118
+ * **⚠️ SECURITY WARNING:** Uses {@link Shell.run} internally.
119
+ * Never pass unsanitized user input. See {@link Shell.run} for details.
120
+ *
121
+ * @param command - The shell command to execute. Must be a trusted string.
122
+ * @param errorOnCodeZero - If true (default), rejects on non-zero exit code.
123
+ * @returns A promise resolving to the trimmed stdout string.
124
+ */
15
125
  stdout(command: string, errorOnCodeZero?: boolean): Promise<string>;
126
+ /**
127
+ * Runs a command and returns whether it succeeded (exit code 0).
128
+ * Never throws on non-zero exit codes.
129
+ *
130
+ * @remarks
131
+ * **⚠️ SECURITY WARNING:** Uses {@link Shell.run} internally.
132
+ * Never pass unsanitized user input. See {@link Shell.run} for details.
133
+ *
134
+ * @param command - The shell command to execute. Must be a trusted string.
135
+ * @returns A promise resolving to true if exit code is 0, false otherwise.
136
+ */
16
137
  ok(command: string): Promise<boolean>;
17
138
  }
package/dist/lib/shell.js CHANGED
@@ -1,40 +1,121 @@
1
1
  import { spawn } from 'child_process';
2
+ import { debug, isVerbose } from './log.js';
3
+ /**
4
+ * A utility class for executing shell commands in a specified working directory.
5
+ * Provides methods for running commands with captured output, interactive commands,
6
+ * and convenience methods for common patterns.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * const shell = new Shell('/path/to/project');
11
+ * const output = await shell.stdout('git status');
12
+ * const success = await shell.ok('npm test');
13
+ * ```
14
+ */
2
15
  export class Shell {
16
+ /** The working directory for all commands. */
3
17
  cwd;
18
+ /**
19
+ * Creates a new Shell instance.
20
+ *
21
+ * @param cwd - The working directory for executing commands.
22
+ */
4
23
  constructor(cwd) {
5
24
  this.cwd = cwd;
6
25
  }
26
+ /**
27
+ * Runs a shell command through bash and captures its output.
28
+ *
29
+ * @remarks
30
+ * **⚠️ SECURITY WARNING: Command Injection Risk**
31
+ *
32
+ * This method passes the command string directly to `bash -c`, which means
33
+ * shell metacharacters (`;`, `|`, `$()`, `` ` ``, etc.) are interpreted.
34
+ *
35
+ * **NEVER** pass unsanitized user input to this method:
36
+ * ```ts
37
+ * // DANGEROUS - command injection vulnerability!
38
+ * shell.run(`git checkout ${userInput}`); // userInput could be "; rm -rf /"
39
+ *
40
+ * // SAFE - use exec() with array arguments instead
41
+ * shell.exec('git', ['checkout', userInput]);
42
+ * ```
43
+ *
44
+ * Only use this method with:
45
+ * - Hardcoded command strings
46
+ * - Values that have been strictly validated (e.g., version numbers matching `/^\d+\.\d+\.\d+$/`)
47
+ *
48
+ * For commands with dynamic arguments, prefer {@link Shell.exec} which passes
49
+ * arguments directly without shell interpretation.
50
+ *
51
+ * @param command - The shell command to execute. Must be a trusted string.
52
+ * @param errorOnCodeNonZero - If true (default), rejects the promise on non-zero exit code.
53
+ * @returns A promise resolving to the command result with exit code, signal, stdout, and stderr.
54
+ * @throws Rejects with the result object if errorOnCodeNonZero is true and exit code is non-zero.
55
+ */
7
56
  async run(command, errorOnCodeNonZero = true) {
8
- try {
9
- return await new Promise((resolve, reject) => {
10
- const stdout = [];
11
- const stderr = [];
12
- const cp = spawn('bash', ['-c', command], { cwd: this.cwd })
13
- .on('error', error => reject(error))
14
- .on('close', (code, signal) => {
15
- const result = {
16
- code,
17
- signal,
18
- stdout: Buffer.concat(stdout).toString(),
19
- stderr: Buffer.concat(stderr).toString(),
20
- };
21
- if (errorOnCodeNonZero && code !== 0) {
22
- reject(result);
23
- }
24
- else {
25
- resolve(result);
26
- }
27
- });
28
- cp.stdout.on('data', chunk => stdout.push(chunk));
29
- cp.stderr.on('data', chunk => stderr.push(chunk));
30
- });
31
- }
32
- catch (error) {
33
- console.error(error);
34
- throw error;
57
+ debug(`$ ${command}`);
58
+ return this.exec('bash', ['-c', command], errorOnCodeNonZero, true);
59
+ }
60
+ /**
61
+ * Executes a command with arguments directly, avoiding shell escaping issues.
62
+ * Preferred over `run()` when dealing with arguments that may contain special characters.
63
+ *
64
+ * @param command - The command executable to run.
65
+ * @param args - Array of arguments to pass to the command.
66
+ * @param errorOnCodeNonZero - If true (default), rejects the promise on non-zero exit code.
67
+ * @param skipLog - If true, suppresses debug logging of the command.
68
+ * @returns A promise resolving to the command result with exit code, signal, stdout, and stderr.
69
+ * @throws Rejects with the result object if errorOnCodeNonZero is true and exit code is non-zero.
70
+ */
71
+ async exec(command, args, errorOnCodeNonZero = true, skipLog = false) {
72
+ if (!skipLog) {
73
+ debug(`$ ${command} ${args.join(' ')}`);
35
74
  }
75
+ return await new Promise((resolve, reject) => {
76
+ const stdout = [];
77
+ const stderr = [];
78
+ const cp = spawn(command, args, { cwd: this.cwd })
79
+ .on('error', (error) => reject(error))
80
+ .on('close', (code, signal) => {
81
+ const result = {
82
+ code,
83
+ signal,
84
+ stdout: Buffer.concat(stdout).toString(),
85
+ stderr: Buffer.concat(stderr).toString(),
86
+ };
87
+ if (isVerbose()) {
88
+ if (result.stdout)
89
+ result.stdout.split('\n').forEach((line) => debug(` stdout: ${line}`));
90
+ if (result.stderr)
91
+ result.stderr.split('\n').forEach((line) => debug(` stderr: ${line}`));
92
+ debug(` exit code: ${code}`);
93
+ }
94
+ if (errorOnCodeNonZero && code !== 0) {
95
+ reject(result);
96
+ }
97
+ else {
98
+ resolve(result);
99
+ }
100
+ });
101
+ cp.stdout.on('data', (chunk) => stdout.push(chunk));
102
+ cp.stderr.on('data', (chunk) => stderr.push(chunk));
103
+ });
36
104
  }
37
- // Runs a command interactively, so the user can interact with stdin/stdout/stderr directly.
105
+ /**
106
+ * Runs a command interactively with full TTY passthrough.
107
+ * The user can interact with the command's stdin/stdout/stderr directly.
108
+ * Useful for commands that require user input (e.g., npm publish with OTP).
109
+ *
110
+ * @remarks
111
+ * **⚠️ SECURITY WARNING:** Same command injection risks as {@link Shell.run}.
112
+ * Never pass unsanitized user input. See {@link Shell.run} for details.
113
+ *
114
+ * @param command - The shell command to execute. Must be a trusted string.
115
+ * @param errorOnCodeNonZero - If true (default), rejects the promise on non-zero exit code.
116
+ * @returns A promise resolving to the exit code and signal (no captured output).
117
+ * @throws Rejects with the result object if errorOnCodeNonZero is true and exit code is non-zero.
118
+ */
38
119
  async runInteractive(command, errorOnCodeNonZero = true) {
39
120
  return await new Promise((resolve, reject) => {
40
121
  const cp = spawn('bash', ['-c', command], {
@@ -53,14 +134,47 @@ export class Shell {
53
134
  });
54
135
  });
55
136
  }
137
+ /**
138
+ * Runs a command and returns only the trimmed stderr output.
139
+ *
140
+ * @remarks
141
+ * **⚠️ SECURITY WARNING:** Uses {@link Shell.run} internally.
142
+ * Never pass unsanitized user input. See {@link Shell.run} for details.
143
+ *
144
+ * @param command - The shell command to execute. Must be a trusted string.
145
+ * @param errorOnCodeZero - If true (default), rejects on non-zero exit code.
146
+ * @returns A promise resolving to the trimmed stderr string.
147
+ */
56
148
  async stderr(command, errorOnCodeZero) {
57
149
  const result = await this.run(command, errorOnCodeZero);
58
150
  return result.stderr.trim();
59
151
  }
152
+ /**
153
+ * Runs a command and returns only the trimmed stdout output.
154
+ *
155
+ * @remarks
156
+ * **⚠️ SECURITY WARNING:** Uses {@link Shell.run} internally.
157
+ * Never pass unsanitized user input. See {@link Shell.run} for details.
158
+ *
159
+ * @param command - The shell command to execute. Must be a trusted string.
160
+ * @param errorOnCodeZero - If true (default), rejects on non-zero exit code.
161
+ * @returns A promise resolving to the trimmed stdout string.
162
+ */
60
163
  async stdout(command, errorOnCodeZero) {
61
164
  const result = await this.run(command, errorOnCodeZero);
62
165
  return result.stdout.trim();
63
166
  }
167
+ /**
168
+ * Runs a command and returns whether it succeeded (exit code 0).
169
+ * Never throws on non-zero exit codes.
170
+ *
171
+ * @remarks
172
+ * **⚠️ SECURITY WARNING:** Uses {@link Shell.run} internally.
173
+ * Never pass unsanitized user input. See {@link Shell.run} for details.
174
+ *
175
+ * @param command - The shell command to execute. Must be a trusted string.
176
+ * @returns A promise resolving to true if exit code is 0, false otherwise.
177
+ */
64
178
  async ok(command) {
65
179
  const result = await this.run(command, false);
66
180
  return result.code === 0;
@@ -1,2 +1,31 @@
1
+ /**
2
+ * Extracts a human-readable error message from an unknown error value.
3
+ * Safely handles various error formats including Error objects, objects with message properties,
4
+ * and other unknown values.
5
+ *
6
+ * @param error - The error value to extract a message from. Can be any type.
7
+ * @returns The extracted error message string, or 'unknown' if no message could be extracted.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * getErrorMessage(new Error('Something went wrong')); // 'Something went wrong'
12
+ * getErrorMessage({ message: 'Custom error' }); // 'Custom error'
13
+ * getErrorMessage(null); // 'unknown'
14
+ * ```
15
+ */
1
16
  export declare function getErrorMessage(error: unknown): string;
17
+ /**
18
+ * Formats JSON data with custom styling rules for map-style configurations.
19
+ * Applies special formatting for certain paths (like bounds, layers, filters, paint, layout)
20
+ * to keep them on a single line while expanding other nested structures.
21
+ *
22
+ * @param inputData - The data to format as styled JSON.
23
+ * @returns A formatted JSON string with custom indentation and line breaks.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * prettyStyleJSON({ name: 'test', bounds: [0, 0, 1, 1] });
28
+ * // Returns formatted JSON with bounds on a single line
29
+ * ```
30
+ */
2
31
  export declare function prettyStyleJSON(inputData: unknown): string;
package/dist/lib/utils.js CHANGED
@@ -1,3 +1,18 @@
1
+ /**
2
+ * Extracts a human-readable error message from an unknown error value.
3
+ * Safely handles various error formats including Error objects, objects with message properties,
4
+ * and other unknown values.
5
+ *
6
+ * @param error - The error value to extract a message from. Can be any type.
7
+ * @returns The extracted error message string, or 'unknown' if no message could be extracted.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * getErrorMessage(new Error('Something went wrong')); // 'Something went wrong'
12
+ * getErrorMessage({ message: 'Custom error' }); // 'Custom error'
13
+ * getErrorMessage(null); // 'unknown'
14
+ * ```
15
+ */
1
16
  export function getErrorMessage(error) {
2
17
  if (error == null)
3
18
  return 'unknown';
@@ -10,6 +25,20 @@ export function getErrorMessage(error) {
10
25
  }
11
26
  return 'unknown';
12
27
  }
28
+ /**
29
+ * Formats JSON data with custom styling rules for map-style configurations.
30
+ * Applies special formatting for certain paths (like bounds, layers, filters, paint, layout)
31
+ * to keep them on a single line while expanding other nested structures.
32
+ *
33
+ * @param inputData - The data to format as styled JSON.
34
+ * @returns A formatted JSON string with custom indentation and line breaks.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * prettyStyleJSON({ name: 'test', bounds: [0, 0, 1, 1] });
39
+ * // Returns formatted JSON with bounds on a single line
40
+ * ```
41
+ */
13
42
  export function prettyStyleJSON(inputData) {
14
43
  return recursive(inputData);
15
44
  function recursive(data, prefix = '', path = '') {
@@ -24,10 +53,22 @@ export function prettyStyleJSON(inputData) {
24
53
  return singleLine(data);
25
54
  if (typeof data === 'object') {
26
55
  if (Array.isArray(data)) {
27
- return '[\n\t' + prefix + data.map((value) => recursive(value, prefix + '\t', path + '[]')).join(',\n\t' + prefix) + '\n' + prefix + ']';
56
+ return ('[\n\t' +
57
+ prefix +
58
+ data.map((value) => recursive(value, prefix + '\t', path + '[]')).join(',\n\t' + prefix) +
59
+ '\n' +
60
+ prefix +
61
+ ']');
28
62
  }
29
63
  if (data) {
30
- return '{\n\t' + prefix + Object.entries(data).map(([key, value]) => '"' + key + '": ' + recursive(value, prefix + '\t', path + '.' + key)).join(',\n\t' + prefix) + '\n' + prefix + '}';
64
+ return ('{\n\t' +
65
+ prefix +
66
+ Object.entries(data)
67
+ .map(([key, value]) => '"' + key + '": ' + recursive(value, prefix + '\t', path + '.' + key))
68
+ .join(',\n\t' + prefix) +
69
+ '\n' +
70
+ prefix +
71
+ '}');
31
72
  }
32
73
  }
33
74
  return singleLine(data);