@goodbyenjn/utils 1.2.0 → 1.3.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/fs.d.ts +14 -14
- package/dist/fs.js +137 -72
- package/dist/global-types.d.ts +6 -0
- package/dist/index.d.ts +6 -8
- package/dist/index.js +2 -2
- package/dist/libs/{common-7de47aac.js → common-ca6da438.js} +15 -12
- package/dist/libs/result-1bfb809c.js +179 -0
- package/dist/libs/result-4e97f1e0.d.ts +133 -0
- package/dist/libs/{types-4042b7e8.d.ts → types-92e74e19.d.ts} +5 -1
- package/dist/remeda.d.ts +1 -1
- package/dist/result.d.ts +3 -3
- package/dist/result.js +3 -2
- package/dist/types.d.ts +2 -2
- package/package.json +1 -1
- package/dist/libs/result-6175a096.js +0 -302
- package/dist/libs/result-81665e58.d.ts +0 -188
package/dist/fs.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./libs/types-
|
|
2
|
-
import { Result
|
|
1
|
+
import "./libs/types-92e74e19.js";
|
|
2
|
+
import { Result } from "./libs/result-4e97f1e0.js";
|
|
3
3
|
|
|
4
4
|
//#region src/fs/types.d.ts
|
|
5
5
|
type PathLike = string | URL;
|
|
@@ -27,26 +27,26 @@ interface CpOptions {
|
|
|
27
27
|
}
|
|
28
28
|
//#endregion
|
|
29
29
|
//#region src/fs/safe.d.ts
|
|
30
|
-
declare const appendFile$1: (path: PathLike, data: string, options?: AppendFileOptions) =>
|
|
30
|
+
declare const appendFile$1: (path: PathLike, data: string, options?: AppendFileOptions) => Promise<Result<void, string>>;
|
|
31
31
|
declare const appendFileSync$1: (path: PathLike, data: string, options?: AppendFileOptions) => Result<void, string>;
|
|
32
|
-
declare const cp$1: (source: PathLike, destination: PathLike, options?: CpOptions) =>
|
|
32
|
+
declare const cp$1: (source: PathLike, destination: PathLike, options?: CpOptions) => Promise<Result<void, string>>;
|
|
33
33
|
declare const cpSync$1: (source: PathLike, destination: PathLike, options?: CpOptions) => Result<void, string>;
|
|
34
|
-
declare const exists$1: (path: PathLike) =>
|
|
34
|
+
declare const exists$1: (path: PathLike) => Promise<Result<true, string>>;
|
|
35
35
|
declare const existsSync$1: (path: PathLike) => Result<true, string>;
|
|
36
|
-
declare const mkdir$1: (path: PathLike, options?: MkdirOptions) =>
|
|
36
|
+
declare const mkdir$1: (path: PathLike, options?: MkdirOptions) => Promise<Result<void, string>>;
|
|
37
37
|
declare const mkdirSync$1: (path: PathLike, options?: MkdirOptions) => Result<void, string>;
|
|
38
|
-
declare function readFile$1(path: PathLike, options: BufferEncodingOptions):
|
|
39
|
-
declare function readFile$1(path: PathLike, options?: StringEncodingOptions):
|
|
38
|
+
declare function readFile$1(path: PathLike, options: BufferEncodingOptions): Promise<Result<Buffer, string>>;
|
|
39
|
+
declare function readFile$1(path: PathLike, options?: StringEncodingOptions): Promise<Result<string, string>>;
|
|
40
40
|
declare function readFileSync$1(path: PathLike, options: BufferEncodingOptions): Result<Buffer, string>;
|
|
41
41
|
declare function readFileSync$1(path: PathLike, options?: StringEncodingOptions): Result<string, string>;
|
|
42
|
-
declare const readFileByLine$1: (path: PathLike, options?: StringEncodingOptions) =>
|
|
43
|
-
declare const readJson$1: <T = any>(path: PathLike, options?: StringEncodingOptions) =>
|
|
42
|
+
declare const readFileByLine$1: (path: PathLike, options?: StringEncodingOptions) => Promise<Result<AsyncIterator<string>, string>>;
|
|
43
|
+
declare const readJson$1: <T = any>(path: PathLike, options?: StringEncodingOptions) => Promise<Result<T, string>>;
|
|
44
44
|
declare const readJsonSync$1: <T = any>(path: PathLike, options?: StringEncodingOptions) => Result<T, string>;
|
|
45
|
-
declare const rm$1: (path: PathLike, options?: RmOptions) =>
|
|
45
|
+
declare const rm$1: (path: PathLike, options?: RmOptions) => Promise<Result<void, string>>;
|
|
46
46
|
declare const rmSync$1: (path: PathLike, options?: RmOptions) => Result<void, string>;
|
|
47
|
-
declare const writeFile: (path: PathLike, data: string, options?: StringEncodingOptions) =>
|
|
47
|
+
declare const writeFile: (path: PathLike, data: string, options?: StringEncodingOptions) => Promise<Result<void, string>>;
|
|
48
48
|
declare const writeFileSync: (path: PathLike, data: string, options?: StringEncodingOptions) => Result<void, string>;
|
|
49
|
-
declare const writeJson: (path: PathLike, data: any, indentOrOptions?: WriteJsonOptions) =>
|
|
49
|
+
declare const writeJson: (path: PathLike, data: any, indentOrOptions?: WriteJsonOptions) => Promise<Result<void, string>>;
|
|
50
50
|
declare const writeJsonSync: (path: PathLike, data: any, indentOrOptions?: WriteJsonOptions) => Result<void, string>;
|
|
51
51
|
//#endregion
|
|
52
52
|
//#region src/fs/unsafe.d.ts
|
|
@@ -79,7 +79,7 @@ interface VFileOptions {
|
|
|
79
79
|
cwd?: string | undefined;
|
|
80
80
|
}
|
|
81
81
|
declare class VFile {
|
|
82
|
-
static fromFilepath(pathname: string, cwd?: string):
|
|
82
|
+
static fromFilepath(pathname: string, cwd?: string): any;
|
|
83
83
|
content: string;
|
|
84
84
|
/**
|
|
85
85
|
* @example
|
package/dist/fs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { e$3 as e } from "./libs/remeda-662cc9ef.js";
|
|
2
|
-
import { errorToMessage, removePrefix } from "./libs/common-
|
|
3
|
-
import { Result,
|
|
2
|
+
import { errorToMessage, removePrefix } from "./libs/common-ca6da438.js";
|
|
3
|
+
import { Result, err, ok, safeTry } from "./libs/result-1bfb809c.js";
|
|
4
4
|
import fs, { promises } from "node:fs";
|
|
5
5
|
import path, { dirname } from "node:path";
|
|
6
6
|
|
|
@@ -20,63 +20,108 @@ const parseWriteJsonOptions = (options) => {
|
|
|
20
20
|
encoding: parseEncodingOptions(options)
|
|
21
21
|
};
|
|
22
22
|
};
|
|
23
|
-
const appendFile$1 = (path$1, data, options) => safeTry(async function* () {
|
|
23
|
+
const appendFile$1 = async (path$1, data, options) => safeTry(async function* () {
|
|
24
24
|
const newline = options?.newline ?? true;
|
|
25
|
-
yield* mkdir$1(dirname(pathLikeToPath(path$1).toString()));
|
|
26
|
-
const fn =
|
|
27
|
-
|
|
25
|
+
yield* await mkdir$1(dirname(pathLikeToPath(path$1).toString()));
|
|
26
|
+
const fn = async () => {
|
|
27
|
+
await promises.appendFile(path$1, newline ? `\n${data}` : data, parseEncodingOptions(options));
|
|
28
|
+
};
|
|
29
|
+
const onThrow = errorToMessage(`Failed to append file: ${path$1}`);
|
|
30
|
+
const result = await Result.try(fn, onThrow);
|
|
28
31
|
return result;
|
|
29
32
|
});
|
|
30
33
|
const appendFileSync$1 = (path$1, data, options) => safeTry(function* () {
|
|
31
34
|
const newline = options?.newline ?? true;
|
|
32
35
|
yield* mkdirSync$1(dirname(pathLikeToPath(path$1).toString()));
|
|
33
|
-
const fn =
|
|
34
|
-
|
|
36
|
+
const fn = () => {
|
|
37
|
+
fs.appendFileSync(path$1, newline ? `\n${data}` : data, parseEncodingOptions(options));
|
|
38
|
+
};
|
|
39
|
+
const onThrow = errorToMessage(`Failed to append file: ${path$1}`);
|
|
40
|
+
const result = Result.try(fn, onThrow);
|
|
35
41
|
return result;
|
|
36
42
|
});
|
|
37
|
-
const cp$1 = (source, destination, options) => {
|
|
43
|
+
const cp$1 = async (source, destination, options) => {
|
|
38
44
|
const { recursive = true } = options || {};
|
|
39
|
-
const fn =
|
|
40
|
-
|
|
45
|
+
const fn = async () => {
|
|
46
|
+
await promises.cp(source, destination, { recursive });
|
|
47
|
+
};
|
|
48
|
+
const onThrow = errorToMessage(`Failed to copy path: ${source} to ${destination}`);
|
|
49
|
+
const result = await Result.try(fn, onThrow);
|
|
41
50
|
return result;
|
|
42
51
|
};
|
|
43
52
|
const cpSync$1 = (source, destination, options) => {
|
|
44
53
|
const { recursive = true } = options || {};
|
|
45
|
-
const fn =
|
|
46
|
-
|
|
54
|
+
const fn = () => {
|
|
55
|
+
fs.cpSync(source, destination, { recursive });
|
|
56
|
+
};
|
|
57
|
+
const onThrow = errorToMessage(`Failed to copy path: ${source} to ${destination}`);
|
|
58
|
+
const result = Result.try(fn, onThrow);
|
|
47
59
|
return result;
|
|
48
60
|
};
|
|
49
|
-
const exists$1 = (path$1) => {
|
|
50
|
-
const fn =
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
const exists$1 = async (path$1) => {
|
|
62
|
+
const fn = async () => {
|
|
63
|
+
await promises.access(path$1);
|
|
64
|
+
return true;
|
|
65
|
+
};
|
|
66
|
+
const onThrow = errorToMessage(`Failed to check exists of path: ${path$1}`);
|
|
67
|
+
const result = await Result.try(fn, onThrow);
|
|
68
|
+
return result;
|
|
53
69
|
};
|
|
54
70
|
const existsSync$1 = (path$1) => {
|
|
55
|
-
const fn =
|
|
56
|
-
|
|
57
|
-
|
|
71
|
+
const fn = () => {
|
|
72
|
+
fs.accessSync(path$1);
|
|
73
|
+
return true;
|
|
74
|
+
};
|
|
75
|
+
const onThrow = errorToMessage(`Failed to check exists of path: ${path$1}`);
|
|
76
|
+
const result = Result.try(fn, onThrow);
|
|
77
|
+
return result;
|
|
58
78
|
};
|
|
59
|
-
const mkdir$1 = (path$1, options) => {
|
|
79
|
+
const mkdir$1 = async (path$1, options) => {
|
|
60
80
|
const { recursive = true } = options || {};
|
|
61
|
-
|
|
62
|
-
|
|
81
|
+
if ((await exists$1(path$1)).isOk()) return ok();
|
|
82
|
+
const fn = async () => {
|
|
83
|
+
await promises.mkdir(path$1, { recursive });
|
|
84
|
+
};
|
|
85
|
+
const onThrow = errorToMessage(`Failed to create directory: ${path$1}`);
|
|
86
|
+
const result = await Result.try(fn, onThrow);
|
|
87
|
+
return result;
|
|
63
88
|
};
|
|
64
89
|
const mkdirSync$1 = (path$1, options) => {
|
|
65
90
|
const { recursive = true } = options || {};
|
|
66
|
-
|
|
67
|
-
|
|
91
|
+
if (existsSync$1(path$1).isOk()) return ok();
|
|
92
|
+
const fn = () => {
|
|
93
|
+
fs.mkdirSync(path$1, { recursive });
|
|
94
|
+
};
|
|
95
|
+
const onThrow = errorToMessage(`Failed to create directory: ${path$1}`);
|
|
96
|
+
const result = Result.try(fn, onThrow);
|
|
97
|
+
return result;
|
|
68
98
|
};
|
|
69
|
-
function readFile$1(path$1, options) {
|
|
70
|
-
|
|
71
|
-
|
|
99
|
+
async function readFile$1(path$1, options) {
|
|
100
|
+
return safeTry(async function* () {
|
|
101
|
+
yield* await exists$1(path$1);
|
|
102
|
+
const fn = async () => {
|
|
103
|
+
return await promises.readFile(path$1, parseEncodingOptions(options));
|
|
104
|
+
};
|
|
105
|
+
const onThrow = errorToMessage(`Failed to read file: ${path$1}`);
|
|
106
|
+
const result = await Result.try(fn, onThrow);
|
|
107
|
+
return result;
|
|
108
|
+
});
|
|
72
109
|
}
|
|
73
110
|
function readFileSync$1(path$1, options) {
|
|
74
|
-
|
|
75
|
-
|
|
111
|
+
return safeTry(function* () {
|
|
112
|
+
yield* existsSync$1(path$1);
|
|
113
|
+
const fn = () => {
|
|
114
|
+
return fs.readFileSync(path$1, parseEncodingOptions(options));
|
|
115
|
+
};
|
|
116
|
+
const onThrow = errorToMessage(`Failed to read file: ${path$1}`);
|
|
117
|
+
const result = Result.try(fn, onThrow);
|
|
118
|
+
return result;
|
|
119
|
+
});
|
|
76
120
|
}
|
|
77
|
-
const readFileByLine$1 = (path$1, options) => {
|
|
78
|
-
|
|
79
|
-
|
|
121
|
+
const readFileByLine$1 = async (path$1, options) => safeTry(async function* () {
|
|
122
|
+
yield* await exists$1(path$1);
|
|
123
|
+
const { createInterface } = await import("node:readline");
|
|
124
|
+
const fn = () => {
|
|
80
125
|
const stream = fs.createReadStream(path$1, {
|
|
81
126
|
...parseEncodingOptions(options),
|
|
82
127
|
autoClose: true
|
|
@@ -84,58 +129,78 @@ const readFileByLine$1 = (path$1, options) => {
|
|
|
84
129
|
stream.on("error", (error) => {
|
|
85
130
|
throw error;
|
|
86
131
|
});
|
|
87
|
-
const reader
|
|
132
|
+
const reader = createInterface({
|
|
88
133
|
input: stream,
|
|
89
134
|
crlfDelay: Infinity
|
|
90
135
|
});
|
|
91
|
-
return reader
|
|
136
|
+
return reader[Symbol.asyncIterator]();
|
|
92
137
|
};
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
138
|
+
const onThrow = errorToMessage(`Failed to read file: ${path$1}`);
|
|
139
|
+
const result = Result.try(fn, onThrow);
|
|
140
|
+
return result;
|
|
141
|
+
});
|
|
142
|
+
const readJson$1 = async (path$1, options) => safeTry(async function* () {
|
|
143
|
+
const content = yield* await readFile$1(path$1, options);
|
|
144
|
+
if (!content) return err(`JSON file is empty: ${path$1}`);
|
|
145
|
+
const fn = () => {
|
|
146
|
+
return JSON.parse(content);
|
|
147
|
+
};
|
|
148
|
+
const onThrow = errorToMessage(`Failed to parse JSON file: ${path$1}`);
|
|
149
|
+
const result = Result.try(fn, onThrow);
|
|
150
|
+
return result;
|
|
151
|
+
});
|
|
152
|
+
const readJsonSync$1 = (path$1, options) => safeTry(function* () {
|
|
153
|
+
const content = yield* readFileSync$1(path$1, options);
|
|
154
|
+
if (!content) return err(`JSON file is empty: ${path$1}`);
|
|
155
|
+
const fn = () => {
|
|
156
|
+
return JSON.parse(content);
|
|
157
|
+
};
|
|
158
|
+
const onThrow = errorToMessage(`Failed to parse JSON file: ${path$1}`);
|
|
159
|
+
const result = Result.try(fn, onThrow);
|
|
160
|
+
return result;
|
|
161
|
+
});
|
|
162
|
+
const rm$1 = async (path$1, options) => {
|
|
113
163
|
const { force = true, recursive = true } = options || {};
|
|
114
|
-
const fn =
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
164
|
+
const fn = async () => {
|
|
165
|
+
await promises.rm(path$1, {
|
|
166
|
+
force,
|
|
167
|
+
recursive
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
const onThrow = errorToMessage(`Failed to remove path: ${path$1}`);
|
|
171
|
+
const result = await Result.try(fn, onThrow);
|
|
119
172
|
return result;
|
|
120
173
|
};
|
|
121
174
|
const rmSync$1 = (path$1, options) => {
|
|
122
175
|
const { force = true, recursive = true } = options || {};
|
|
123
|
-
const fn =
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
176
|
+
const fn = () => {
|
|
177
|
+
fs.rmSync(path$1, {
|
|
178
|
+
force,
|
|
179
|
+
recursive
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
const onThrow = errorToMessage(`Failed to remove path: ${path$1}`);
|
|
183
|
+
const result = Result.try(fn, onThrow);
|
|
128
184
|
return result;
|
|
129
185
|
};
|
|
130
|
-
const writeFile = (path$1, data, options) => {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
186
|
+
const writeFile = async (path$1, data, options) => safeTry(async function* () {
|
|
187
|
+
yield* await mkdir$1(dirname(pathLikeToPath(path$1).toString()));
|
|
188
|
+
const fn = async () => {
|
|
189
|
+
await promises.writeFile(path$1, data, parseEncodingOptions(options));
|
|
190
|
+
};
|
|
191
|
+
const onThrow = errorToMessage(`Failed to write file: ${path$1}`);
|
|
192
|
+
const result = await Result.try(fn, onThrow);
|
|
193
|
+
return result;
|
|
194
|
+
});
|
|
134
195
|
const writeFileSync = (path$1, data, options) => {
|
|
135
|
-
const fn =
|
|
136
|
-
|
|
196
|
+
const fn = () => {
|
|
197
|
+
fs.writeFileSync(path$1, data, parseEncodingOptions(options));
|
|
198
|
+
};
|
|
199
|
+
const onThrow = errorToMessage(`Failed to write file: ${path$1}`);
|
|
200
|
+
const result = Result.try(fn, onThrow);
|
|
201
|
+
return result;
|
|
137
202
|
};
|
|
138
|
-
const writeJson = (path$1, data, indentOrOptions) => {
|
|
203
|
+
const writeJson = async (path$1, data, indentOrOptions) => {
|
|
139
204
|
const { indent, encoding } = parseWriteJsonOptions(indentOrOptions);
|
|
140
205
|
const content = JSON.stringify(data, null, indent);
|
|
141
206
|
return writeFile(path$1, content, encoding);
|
package/dist/global-types.d.ts
CHANGED
|
@@ -63,6 +63,12 @@ declare global {
|
|
|
63
63
|
Args extends readonly any[] = any[],
|
|
64
64
|
This = unknown,
|
|
65
65
|
> = Types.FnWithThis<Return, Args, This>;
|
|
66
|
+
type SyncFn<Return = any, Args extends readonly any[] = any[]> = Types.SyncFn<Return, Args>;
|
|
67
|
+
type SyncFnWithThis<
|
|
68
|
+
Return = any,
|
|
69
|
+
Args extends readonly any[] = any[],
|
|
70
|
+
This = unknown,
|
|
71
|
+
> = Types.SyncFnWithThis<Return, Args, This>;
|
|
66
72
|
|
|
67
73
|
type Entries<BaseType> = Types.Entries<BaseType>;
|
|
68
74
|
type Entry<BaseType> = Types.Entry<BaseType>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AsyncFn, Fn } from "./libs/types-
|
|
2
|
-
import {
|
|
1
|
+
import { AsyncFn, Fn } from "./libs/types-92e74e19.js";
|
|
2
|
+
import { Result } from "./libs/result-4e97f1e0.js";
|
|
3
3
|
|
|
4
4
|
//#region src/common/error.d.ts
|
|
5
5
|
interface ErrorLike extends Partial<Error> {
|
|
@@ -63,14 +63,12 @@ declare const createLock: () => {
|
|
|
63
63
|
declare const PromiseWithResolvers: <T>() => PromiseWithResolvers<T>;
|
|
64
64
|
//#endregion
|
|
65
65
|
//#region src/common/shell.d.ts
|
|
66
|
-
|
|
66
|
+
interface ShellExecResult {
|
|
67
67
|
stdout: string;
|
|
68
68
|
stderr: string;
|
|
69
|
-
}
|
|
70
|
-
declare function $(cmd:
|
|
71
|
-
|
|
72
|
-
stderr: string;
|
|
73
|
-
}, string>;
|
|
69
|
+
}
|
|
70
|
+
declare function $(cmd: string): Promise<Result<ShellExecResult, string>>;
|
|
71
|
+
declare function $(cmd: TemplateStringsArray, ...values: any[]): Promise<Result<ShellExecResult, string>>;
|
|
74
72
|
declare const quoteShellArg: (arg: string) => string;
|
|
75
73
|
//#endregion
|
|
76
74
|
//#region src/common/string.d.ts
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./libs/remeda-662cc9ef.js";
|
|
2
|
-
import { $, PromiseWithResolvers, addPrefix, addSuffix, createLock, createSingleton, debounce, errorToMessage, getErrorMessage, isErrorLike, join, joinWithSlash, linear, normalizeError, parseKeyValuePairs, parseValueToBoolean, quoteShellArg, removePrefix, removeSuffix, scale, sleep, split, splitWithSlash, template, throttle, toForwardSlash, unindent } from "./libs/common-
|
|
3
|
-
import "./libs/result-
|
|
2
|
+
import { $, PromiseWithResolvers, addPrefix, addSuffix, createLock, createSingleton, debounce, errorToMessage, getErrorMessage, isErrorLike, join, joinWithSlash, linear, normalizeError, parseKeyValuePairs, parseValueToBoolean, quoteShellArg, removePrefix, removeSuffix, scale, sleep, split, splitWithSlash, template, throttle, toForwardSlash, unindent } from "./libs/common-ca6da438.js";
|
|
3
|
+
import "./libs/result-1bfb809c.js";
|
|
4
4
|
|
|
5
5
|
export { $, PromiseWithResolvers, addPrefix, addSuffix, createLock, createSingleton, debounce, errorToMessage, getErrorMessage, isErrorLike, join, joinWithSlash, linear, normalizeError, parseKeyValuePairs, parseValueToBoolean, quoteShellArg, removePrefix, removeSuffix, scale, sleep, split, splitWithSlash, template, throttle, toForwardSlash, unindent };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { l$1 as l, o$5 as o, r$4 as r, t$4 as t$1, t$6 as t, u } from "./remeda-662cc9ef.js";
|
|
2
|
-
import {
|
|
2
|
+
import { Result } from "./result-1bfb809c.js";
|
|
3
3
|
|
|
4
4
|
//#region src/common/error.ts
|
|
5
5
|
const isErrorLike = (error) => o(error) && t(error.message);
|
|
@@ -199,24 +199,27 @@ const PromiseWithResolvers = () => {
|
|
|
199
199
|
|
|
200
200
|
//#endregion
|
|
201
201
|
//#region src/common/shell.ts
|
|
202
|
-
|
|
202
|
+
const REGEXP_NULL_CHAR = /\x00+/g;
|
|
203
|
+
const REGEXP_SAFE_CHARS = /^[A-Za-z0-9,:=_./-]+$/;
|
|
204
|
+
const REGEXP_SINGLE_QUOTES = /'+/g;
|
|
205
|
+
async function $(cmd, ...values) {
|
|
206
|
+
const { exec } = await import("node:child_process");
|
|
203
207
|
const command = t(cmd) ? cmd : cmd.reduce((acc, part, index) => acc + part + (values[index] ?? ""), "");
|
|
204
|
-
const
|
|
205
|
-
const { promise
|
|
208
|
+
const fn = async () => {
|
|
209
|
+
const { promise, reject, resolve } = PromiseWithResolvers();
|
|
206
210
|
exec(command, (error, stdout, stderr) => {
|
|
207
211
|
if (error) reject(error);
|
|
208
212
|
else resolve({
|
|
209
|
-
stdout,
|
|
210
|
-
stderr
|
|
213
|
+
stdout: stdout.trim(),
|
|
214
|
+
stderr: stderr.trim()
|
|
211
215
|
});
|
|
212
216
|
});
|
|
213
|
-
return promise
|
|
214
|
-
}
|
|
215
|
-
|
|
217
|
+
return await promise;
|
|
218
|
+
};
|
|
219
|
+
const onThrow = errorToMessage(`Failed to execute command: ${cmd}`);
|
|
220
|
+
const result = Result.try(fn, onThrow);
|
|
221
|
+
return result;
|
|
216
222
|
}
|
|
217
|
-
const REGEXP_NULL_CHAR = /\x00+/g;
|
|
218
|
-
const REGEXP_SAFE_CHARS = /^[A-Za-z0-9,:=_./-]+$/;
|
|
219
|
-
const REGEXP_SINGLE_QUOTES = /'+/g;
|
|
220
223
|
const quoteShellArg = (arg) => {
|
|
221
224
|
if (!arg) return "''";
|
|
222
225
|
const cleaned = String(arg).replace(REGEXP_NULL_CHAR, "");
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { isPromiseLike, t$4 as t } from "./remeda-662cc9ef.js";
|
|
2
|
+
|
|
3
|
+
//#region src/result/result.ts
|
|
4
|
+
var Result = class {
|
|
5
|
+
static ok(value) {
|
|
6
|
+
return new Ok(value);
|
|
7
|
+
}
|
|
8
|
+
static err(error) {
|
|
9
|
+
return new Err(error);
|
|
10
|
+
}
|
|
11
|
+
static try(fnOrData, onThrow) {
|
|
12
|
+
try {
|
|
13
|
+
let data = fnOrData;
|
|
14
|
+
if (t(fnOrData)) data = fnOrData();
|
|
15
|
+
if (!isPromiseLike(data)) return ok(data);
|
|
16
|
+
return data.then((value) => ok(value), (error) => err(onThrow ? onThrow(error) : error));
|
|
17
|
+
} catch (error) {
|
|
18
|
+
return err(onThrow ? onThrow(error) : error);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
static all(results) {
|
|
22
|
+
let acc = ok([]);
|
|
23
|
+
for (const result of results) {
|
|
24
|
+
if (!result.isOk()) {
|
|
25
|
+
acc = err(result.error);
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
acc = acc.map((values) => [...values, result.value]);
|
|
29
|
+
}
|
|
30
|
+
return acc;
|
|
31
|
+
}
|
|
32
|
+
static allSettled(results) {
|
|
33
|
+
let acc = ok([]);
|
|
34
|
+
for (const result of results) if (result.isErr() && acc.isErr()) acc = acc.mapErr((errors) => [...errors, result.error]);
|
|
35
|
+
else if (result.isOk() && acc.isOk()) acc = acc.map((values) => [...values, result.value]);
|
|
36
|
+
else if (result.isErr() && acc.isOk()) acc = err([result.error]);
|
|
37
|
+
return acc;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Check if `Result` is `OK`
|
|
41
|
+
*/
|
|
42
|
+
isOk() {
|
|
43
|
+
return this.ok;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Check if `Result` is `OK` and the value matches the predicate
|
|
47
|
+
*/
|
|
48
|
+
isOkAnd(predicate) {
|
|
49
|
+
return this.isOk() && predicate(this.value);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Check if `Result` is `Err`
|
|
53
|
+
*/
|
|
54
|
+
isErr() {
|
|
55
|
+
return !this.ok;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Check if `Result` is `Err` and the error matches the predicate
|
|
59
|
+
*/
|
|
60
|
+
isErrAnd(predicate) {
|
|
61
|
+
return this.isErr() && predicate(this.error);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Maps `Result<T, E>` to `Result<U, E>`
|
|
65
|
+
*/
|
|
66
|
+
map(fn) {
|
|
67
|
+
return this.isErr() ? this : ok(fn(this.value));
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Maps `Result<T, E>` to `Result<T, F>`
|
|
71
|
+
*/
|
|
72
|
+
mapErr(fn) {
|
|
73
|
+
return this.isOk() ? this : err(fn(this.error));
|
|
74
|
+
}
|
|
75
|
+
and(result) {
|
|
76
|
+
return this.isErr() ? this : result;
|
|
77
|
+
}
|
|
78
|
+
andThen(fn) {
|
|
79
|
+
return this.isErr() ? this : fn(this.value);
|
|
80
|
+
}
|
|
81
|
+
or(result) {
|
|
82
|
+
return this.isOk() ? this : result;
|
|
83
|
+
}
|
|
84
|
+
orElse(fn) {
|
|
85
|
+
return this.isOk() ? this : fn(this.error);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Calls the function with the value if `Result` is `Ok` and returns the result unchanged
|
|
89
|
+
*/
|
|
90
|
+
inspect(fn) {
|
|
91
|
+
try {
|
|
92
|
+
this.isOk() && fn(this.value);
|
|
93
|
+
} catch {}
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Calls the function with the error if `Result` is `Err` and returns the result unchanged
|
|
98
|
+
*/
|
|
99
|
+
inspectErr(fn) {
|
|
100
|
+
try {
|
|
101
|
+
this.isErr() && fn(this.error);
|
|
102
|
+
} catch {}
|
|
103
|
+
return this;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Unwrap the `Ok` value, or return the provided value if `Result` is `Err`
|
|
107
|
+
*/
|
|
108
|
+
unwrapOr(defaultValue) {
|
|
109
|
+
return this.isOk() ? this.value : defaultValue;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Matches the `Result` variant and executes the corresponding function
|
|
113
|
+
*/
|
|
114
|
+
match(ok$1, err$1) {
|
|
115
|
+
return this.isOk() ? ok$1(this.value) : err$1(this.error);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Returns an iterable object that yields the `Ok` value and `Err` value
|
|
119
|
+
*/
|
|
120
|
+
iter() {
|
|
121
|
+
if (this.isOk()) return [
|
|
122
|
+
true,
|
|
123
|
+
null,
|
|
124
|
+
this.value
|
|
125
|
+
];
|
|
126
|
+
else return [
|
|
127
|
+
false,
|
|
128
|
+
this.error,
|
|
129
|
+
null
|
|
130
|
+
];
|
|
131
|
+
}
|
|
132
|
+
*[Symbol.iterator]() {
|
|
133
|
+
if (this.isOk()) return this.value;
|
|
134
|
+
const self = this;
|
|
135
|
+
yield self;
|
|
136
|
+
return self;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
var Ok = class extends Result {
|
|
140
|
+
ok = true;
|
|
141
|
+
_value;
|
|
142
|
+
constructor(value) {
|
|
143
|
+
super();
|
|
144
|
+
this._value = value;
|
|
145
|
+
}
|
|
146
|
+
get value() {
|
|
147
|
+
return this._value;
|
|
148
|
+
}
|
|
149
|
+
get error() {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
var Err = class extends Result {
|
|
154
|
+
ok = false;
|
|
155
|
+
_error;
|
|
156
|
+
constructor(error) {
|
|
157
|
+
super();
|
|
158
|
+
this._error = error;
|
|
159
|
+
}
|
|
160
|
+
get value() {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
get error() {
|
|
164
|
+
return this._error;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const ok = Result.ok;
|
|
168
|
+
const err = Result.err;
|
|
169
|
+
|
|
170
|
+
//#endregion
|
|
171
|
+
//#region src/result/utils.ts
|
|
172
|
+
function safeTry(body) {
|
|
173
|
+
const next = body().next();
|
|
174
|
+
if (isPromiseLike(next)) return next.then((res) => res.value);
|
|
175
|
+
return next.value;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
//#endregion
|
|
179
|
+
export { Err, Ok, Result, err, ok, safeTry };
|