@akterjs/cli 0.0.0-stage → 0.1.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/LICENSE +201 -0
- package/README.md +47 -2
- package/dist/Argument-D81dqizB.mjs +57 -0
- package/dist/Array-B4kuTQeW.mjs +2323 -0
- package/dist/Boolean-kILIvmhE.mjs +26 -0
- package/dist/ChildProcess-BCIwxPGc.mjs +577 -0
- package/dist/CliError-Cf5xqkkj.mjs +633 -0
- package/dist/Command-Dzq9KM-h.mjs +5135 -0
- package/dist/Config-B6OND9WR.mjs +854 -0
- package/dist/Console-BKHUkH6a.mjs +141 -0
- package/dist/Data-CeCULr0-.mjs +251 -0
- package/dist/Digest-CBd3uv5B.mjs +348 -0
- package/dist/Duration-EH9Vy4U6.mjs +791 -0
- package/dist/Effect-CKFpqbmw.mjs +12911 -0
- package/dist/FileSystem-4pPcEb_i.mjs +1366 -0
- package/dist/HttpClientError-BUeMWx70.mjs +303 -0
- package/dist/HttpClientResponse-D5ZKICVV.mjs +855 -0
- package/dist/Match-CGPLZYrV.mjs +434 -0
- package/dist/MutableHashMap-f8nW8AJR.mjs +376 -0
- package/dist/MutableHashSet-_HI572Ya.mjs +155 -0
- package/dist/MutableRef-D4Qv592C.mjs +107 -0
- package/dist/Number-BvkRkfc-.mjs +137 -0
- package/dist/Option-DkxSnBhp.mjs +3967 -0
- package/dist/Order-C1JC991I.mjs +481 -0
- package/dist/Path-Djdv_eF5.mjs +130 -0
- package/dist/Queue-CO5UQ6os.mjs +1394 -0
- package/dist/Redacted-RkJrG5Me.mjs +160 -0
- package/dist/Ref-BIPOxJNH.mjs +267 -0
- package/dist/Runtime-BInIAwK3.mjs +297 -0
- package/dist/Schema-MiKt5K1v.mjs +10999 -0
- package/dist/SecureRandom-B_U4ysO3.mjs +279 -0
- package/dist/Semaphore-DOVJ4ZGS.mjs +177 -0
- package/dist/Stdio-KylmOBX_.mjs +74 -0
- package/dist/Stream-bK9QIETN.mjs +4012 -0
- package/dist/String-q5dcsVe4.mjs +351 -0
- package/dist/TerminalCapabilities-w_44MAca.mjs +1769 -0
- package/dist/WebCrypto-ZI_GNVlw.mjs +33 -0
- package/dist/actor-call.service-CGM_vD9u.mjs +1269 -0
- package/dist/actor-client.adapter-Coem7gF1.mjs +3691 -0
- package/dist/akter-program.config-C4cXx4Fr.mjs +7034 -0
- package/dist/akter.cli.mjs +5 -0
- package/dist/app-cli.config.mjs +49 -0
- package/dist/app-entry.pure.mjs +31 -0
- package/dist/archive/akter-archive.schema.mjs +65 -0
- package/dist/archive/akter-archive.service.mjs +309 -0
- package/dist/archive/archive-cli.config.mjs +45 -0
- package/dist/archive/archive-invalid.errors.mjs +5 -0
- package/dist/archive/archived-lineage.pure.mjs +13 -0
- package/dist/archive/tar.pure.mjs +291 -0
- package/dist/archive/zstd.adapter.mjs +46 -0
- package/dist/bench/bench-report.pure.mjs +120 -0
- package/dist/bench/bench-runner.pure.mjs +89 -0
- package/dist/bench/bench.service.mjs +301 -0
- package/dist/cli-runtime.layer-BqK2mmVL.mjs +1191 -0
- package/dist/cli-runtime.layer.mjs +1 -0
- package/dist/cloud-client.adapter-Cy1BjDbG.mjs +3186 -0
- package/dist/cloud-client.adapter-DOVMoYAj.mjs +304 -0
- package/dist/command/akter-commands.config.mjs +32 -0
- package/dist/command/akter-program.config.mjs +1 -0
- package/dist/credentials/credentials.service.mjs +226 -0
- package/dist/credentials/keychain.adapter.mjs +92 -0
- package/dist/credentials/login.config.mjs +251 -0
- package/dist/deploy/auth/api-attempt.service.mjs +30 -0
- package/dist/deploy/auth/token-refresh.errors.mjs +4 -0
- package/dist/deploy/build-bundle.adapter.mjs +133 -0
- package/dist/deploy/build-manifest.pure.mjs +44 -0
- package/dist/deploy/cloud-client.adapter.mjs +1 -0
- package/dist/deploy/cloud-url.pure.mjs +17 -0
- package/dist/deploy/deploy-failed.errors.mjs +17 -0
- package/dist/deploy/deploy.service.mjs +156 -0
- package/dist/deploy/request-failure.pure.mjs +87 -0
- package/dist/dev-runner.pure.mjs +30 -0
- package/dist/docs/doc-topics.pure.mjs +21 -0
- package/dist/docs/docs.config.mjs +1 -0
- package/dist/docs.config-_21Xi6HU.mjs +190 -0
- package/dist/export/actor-export.service.mjs +267 -0
- package/dist/export/export-failed.errors.mjs +4 -0
- package/dist/export/export-failure.pure.mjs +18 -0
- package/dist/export/ordered-lines.pure.mjs +43 -0
- package/dist/export/ranged-download.pure.mjs +66 -0
- package/dist/export/snapshot-download.pure.mjs +86 -0
- package/dist/history-runner.pure.mjs +186 -0
- package/dist/history-since.pure.mjs +17 -0
- package/dist/hosted-runtime.layer-Cx3IPsEd.mjs +16358 -0
- package/dist/local/environment-cli.config.mjs +90 -0
- package/dist/local/environment-runner.pure.mjs +75 -0
- package/dist/local/local-cli.config.mjs +159 -0
- package/dist/logs/log-follow.config.mjs +21 -0
- package/dist/logs/log-follow.service.mjs +87 -0
- package/dist/logs/log-lines.pure.mjs +44 -0
- package/dist/migrate-runner.pure.mjs +28 -0
- package/dist/operation-input.pure-CS9iUhqK.mjs +1383 -0
- package/dist/operation-registry.pure-DVC8EDgj.mjs +283 -0
- package/dist/registry/actor-call.service.mjs +1 -0
- package/dist/registry/actor-commands.config.mjs +127 -0
- package/dist/registry/actor-refusal.pure.mjs +34 -0
- package/dist/registry/approval.service.mjs +80 -0
- package/dist/registry/cloud-commands.config.mjs +151 -0
- package/dist/registry/cloud-served.pure.mjs +31 -0
- package/dist/registry/operation-call.service.mjs +262 -0
- package/dist/registry/operation-input.pure.mjs +1 -0
- package/dist/registry/operation-output.pure.mjs +91 -0
- package/dist/registry/served-command.config.mjs +57 -0
- package/dist/runner-exited.errors.mjs +10 -0
- package/dist/terminal/cli-exit.errors.mjs +38 -0
- package/dist/terminal/cli-failure.pure.mjs +31 -0
- package/dist/terminal/confirm.adapter.mjs +27 -0
- package/package.json +61 -3
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { bn as dual } from "./Option-DkxSnBhp.mjs";
|
|
2
|
+
globalThis.Boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Chooses between two lazy branches based on a boolean value.
|
|
5
|
+
*
|
|
6
|
+
* **When to use**
|
|
7
|
+
*
|
|
8
|
+
* Use to choose between two lazy branches based on a boolean value.
|
|
9
|
+
*
|
|
10
|
+
* **Example** (Pattern matching on booleans)
|
|
11
|
+
*
|
|
12
|
+
* ```ts import.meta.vitest
|
|
13
|
+
* import { Boolean } from "effect"
|
|
14
|
+
*
|
|
15
|
+
* Boolean.match(true, {
|
|
16
|
+
* onFalse: () => "It's false!",
|
|
17
|
+
* onTrue: () => "It's true!"
|
|
18
|
+
* }) // => "It's true!"
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @stability stable
|
|
22
|
+
* @category pattern matching
|
|
23
|
+
* @since 2.0.0
|
|
24
|
+
*/
|
|
25
|
+
const match = /*#__PURE__*/ dual(2, (value, options) => value ? options.onTrue() : options.onFalse());
|
|
26
|
+
export { match as t };
|
|
@@ -0,0 +1,577 @@
|
|
|
1
|
+
import { B as flatMap, Gt as scoped, Nt as raceFirst, aa as Service, bt as never, dt as map, fa as getUnsafe, o as andThen, va as Prototype } from "./Effect-CKFpqbmw.mjs";
|
|
2
|
+
import { Q as getOrThrow, Y as fail, at as succeed } from "./Array-B4kuTQeW.mjs";
|
|
3
|
+
import { w as some, xt as BaseProto } from "./Option-DkxSnBhp.mjs";
|
|
4
|
+
import { B as runCollect, K as splitLines, M as mkString, V as runDrain, i as decodeText, nt as unwrap$1, s as drainFork } from "./Stream-bK9QIETN.mjs";
|
|
5
|
+
import { i as TaggedError } from "./Data-CeCULr0-.mjs";
|
|
6
|
+
import { i as value, n as make$2, t as isRedacted } from "./Redacted-RkJrG5Me.mjs";
|
|
7
|
+
// ../../node_modules/.pnpm/effect@4.1.2_patch_hash=0e61176203bb1256381ce1c5b488d7951983ce38ff698647d3f4617383abbf07/node_modules/effect/dist/Brand.js
|
|
8
|
+
/**
|
|
9
|
+
* Returns a `Constructor` that **does not apply any runtime checks** and just
|
|
10
|
+
* returns the provided value.
|
|
11
|
+
*
|
|
12
|
+
* **When to use**
|
|
13
|
+
*
|
|
14
|
+
* Use to create nominal types that allow distinguishing between two values
|
|
15
|
+
* of the same type but with different meanings.
|
|
16
|
+
*
|
|
17
|
+
* @see {@link make} for constructing branded values with validation.
|
|
18
|
+
* @see {@link check} for constructing branded values from schema checks.
|
|
19
|
+
*
|
|
20
|
+
* @stability stable
|
|
21
|
+
* @category constructors
|
|
22
|
+
* @since 2.0.0
|
|
23
|
+
*/
|
|
24
|
+
function nominal() {
|
|
25
|
+
return Object.assign((input) => input, {
|
|
26
|
+
option: (input) => some(input),
|
|
27
|
+
result: (input) => succeed(input),
|
|
28
|
+
is: (_) => true
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
// ../../node_modules/.pnpm/effect@4.1.2_patch_hash=0e61176203bb1256381ce1c5b488d7951983ce38ff698647d3f4617383abbf07/node_modules/effect/dist/process/ChildProcessSpawner.js
|
|
32
|
+
/**
|
|
33
|
+
* Service boundary for starting and controlling child processes.
|
|
34
|
+
*
|
|
35
|
+
* `ChildProcessSpawner` is the service used by `ChildProcess` commands to start
|
|
36
|
+
* operating-system processes. A spawner turns a command description into a
|
|
37
|
+
* handle that can write to stdin, read stdout and stderr, wait for exit, kill
|
|
38
|
+
* the process, and manage whether the process keeps its parent alive. Platform
|
|
39
|
+
* backends implement this service, while most application code uses the higher
|
|
40
|
+
* level `ChildProcess` module.
|
|
41
|
+
*
|
|
42
|
+
* @stability unstable
|
|
43
|
+
* @since 4.0.0
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* Constructs branded child process `ExitCode` values.
|
|
47
|
+
*
|
|
48
|
+
* @stability unstable
|
|
49
|
+
* @category constructors
|
|
50
|
+
* @since 4.0.0
|
|
51
|
+
*/
|
|
52
|
+
const ExitCode = /*#__PURE__*/ nominal();
|
|
53
|
+
/**
|
|
54
|
+
* Constructs branded child process `ProcessId` values.
|
|
55
|
+
*
|
|
56
|
+
* @stability unstable
|
|
57
|
+
* @category constructors
|
|
58
|
+
* @since 4.0.0
|
|
59
|
+
*/
|
|
60
|
+
const ProcessId = /*#__PURE__*/ nominal();
|
|
61
|
+
const HandleTypeId = "~effect/process/ChildProcessSpawner/ChildProcessHandle";
|
|
62
|
+
const HandleProto = {
|
|
63
|
+
[HandleTypeId]: HandleTypeId,
|
|
64
|
+
...BaseProto,
|
|
65
|
+
toJSON() {
|
|
66
|
+
return {
|
|
67
|
+
_id: "ChildProcessHandle",
|
|
68
|
+
pid: this.pid
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Constructs a new `ChildProcessHandle`.
|
|
74
|
+
*
|
|
75
|
+
* @stability unstable
|
|
76
|
+
* @category constructors
|
|
77
|
+
* @since 4.0.0
|
|
78
|
+
*/
|
|
79
|
+
const makeHandle = (params) => Object.setPrototypeOf({ ...params }, HandleProto);
|
|
80
|
+
/**
|
|
81
|
+
* Creates a `ChildProcessSpawner` service from a `spawn` function, deriving
|
|
82
|
+
* helpers for exit codes and output collection from that implementation.
|
|
83
|
+
*
|
|
84
|
+
* @stability unstable
|
|
85
|
+
* @category constructors
|
|
86
|
+
* @since 4.0.0
|
|
87
|
+
*/
|
|
88
|
+
const make$1 = (spawn) => {
|
|
89
|
+
const streamString = (command, options) => spawn(command).pipe(map((handle) => decodeText(options?.includeStderr === true ? handle.all : drainFork(handle.stdout, handle.stderr))), unwrap$1);
|
|
90
|
+
const streamLines = (command, options) => splitLines(streamString(command, options));
|
|
91
|
+
return ChildProcessSpawner.of({
|
|
92
|
+
spawn,
|
|
93
|
+
exitCode: (command) => scoped(flatMap(spawn(command), (handle) => raceFirst(handle.exitCode, andThen(runDrain(handle.all), never)))),
|
|
94
|
+
streamString,
|
|
95
|
+
streamLines,
|
|
96
|
+
lines: (command, options) => runCollect(streamLines(command, options)),
|
|
97
|
+
string: (command, options) => mkString(streamString(command, options))
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Service tag for child process spawning.
|
|
102
|
+
*
|
|
103
|
+
* @stability unstable
|
|
104
|
+
* @category services
|
|
105
|
+
* @since 4.0.0
|
|
106
|
+
*/
|
|
107
|
+
var ChildProcessSpawner = class extends (/*#__PURE__*/ Service()("effect/process/ChildProcessSpawner")) {};
|
|
108
|
+
// ../../node_modules/.pnpm/effect@4.1.2_patch_hash=0e61176203bb1256381ce1c5b488d7951983ce38ff698647d3f4617383abbf07/node_modules/effect/dist/process/CommandLine.js
|
|
109
|
+
/**
|
|
110
|
+
* Builds command lines, the single strings that a shell or a Windows program
|
|
111
|
+
* turns back into arguments, and argument lists from templates. It is
|
|
112
|
+
* unrelated to `effect/cli`, which parses the arguments of your own program.
|
|
113
|
+
*
|
|
114
|
+
* The rules depend on what parses the string, not on the platform that builds
|
|
115
|
+
* it, so `quote`, `join` and `display` take an explicit `format`:
|
|
116
|
+
*
|
|
117
|
+
* - `"posix"` (the default) for `sh`, `dash`, `bash` and `zsh`. Quoted output
|
|
118
|
+
* is also read the same way by `fish`.
|
|
119
|
+
* - `"powershell"` for PowerShell 7.3 or later.
|
|
120
|
+
* - `"windows"` for the Microsoft C runtime rules that most Windows programs
|
|
121
|
+
* use to split their command line.
|
|
122
|
+
*
|
|
123
|
+
* SSH sends one command line to the login shell of the remote account, so the
|
|
124
|
+
* format must match that shell. The remote shell must be a POSIX shell or
|
|
125
|
+
* PowerShell: Windows OpenSSH uses `cmd.exe` by default, which no format
|
|
126
|
+
* supports, so set its `DefaultShell` to PowerShell. Docker and Kubernetes exec
|
|
127
|
+
* take argument lists and need no command line at all.
|
|
128
|
+
*
|
|
129
|
+
* Arguments can be `Redacted` strings. `quote` and `join` include their values,
|
|
130
|
+
* because their output is meant to run, while `display` replaces them with
|
|
131
|
+
* `<redacted>`.
|
|
132
|
+
*
|
|
133
|
+
* @stability unstable
|
|
134
|
+
* @since 4.0.7
|
|
135
|
+
*/
|
|
136
|
+
/**
|
|
137
|
+
* Error returned when a command line or a template cannot be built.
|
|
138
|
+
*
|
|
139
|
+
* **Details**
|
|
140
|
+
*
|
|
141
|
+
* - `NulCharacter`: an argument passed to {@link quote} or {@link join}
|
|
142
|
+
* contains a NUL character, which no command line can carry.
|
|
143
|
+
* - `InvalidArgument`: the format cannot carry an argument: a Windows program
|
|
144
|
+
* name with a double quote, or the argument `--%`, which PowerShell drops
|
|
145
|
+
* when it calls a native program.
|
|
146
|
+
* - `InvalidEscape`: template text ends with a backslash that escapes nothing,
|
|
147
|
+
* or contains an invalid JavaScript escape sequence.
|
|
148
|
+
* - `UnterminatedQuote`: a quoted section of a template is not closed.
|
|
149
|
+
* - `UnsupportedSyntax`: template text contains shell syntax that cannot work
|
|
150
|
+
* without a shell, such as operators, expansions, globs, comments or
|
|
151
|
+
* variable assignments, or an interpolated array is not a separate argument.
|
|
152
|
+
*
|
|
153
|
+
* Messages never include the input, which may contain secrets.
|
|
154
|
+
*
|
|
155
|
+
* @stability unstable
|
|
156
|
+
* @category errors
|
|
157
|
+
* @since 4.0.7
|
|
158
|
+
*/
|
|
159
|
+
var CommandLineError = class extends (/*#__PURE__*/ TaggedError("CommandLineError")) {};
|
|
160
|
+
/**
|
|
161
|
+
* Renders a command for logs and error messages.
|
|
162
|
+
*
|
|
163
|
+
* **When to use**
|
|
164
|
+
*
|
|
165
|
+
* Use when you show a command to a person, for example in an error message,
|
|
166
|
+
* and secrets and control characters must not reach the output.
|
|
167
|
+
*
|
|
168
|
+
* **Details**
|
|
169
|
+
*
|
|
170
|
+
* - Quotes like {@link join}, so commands without control characters or
|
|
171
|
+
* secrets can be copied into a terminal of the given format.
|
|
172
|
+
* - Replaces `Redacted` arguments with `<redacted>`.
|
|
173
|
+
* - Writes control characters and Unicode line separators as escapes such as
|
|
174
|
+
* `\n` or `\u001b`, so output cannot move the cursor or inject terminal
|
|
175
|
+
* sequences.
|
|
176
|
+
* - Never fails: input that {@link join} rejects is rendered anyway.
|
|
177
|
+
*
|
|
178
|
+
* **Gotchas**
|
|
179
|
+
*
|
|
180
|
+
* The output is for reading only. It is not a reliable command line: escapes
|
|
181
|
+
* and `<redacted>` change what a shell would run.
|
|
182
|
+
*
|
|
183
|
+
* **Example** (Showing a command with a secret)
|
|
184
|
+
*
|
|
185
|
+
* ```ts import.meta.vitest
|
|
186
|
+
* import { Redacted } from "effect"
|
|
187
|
+
* import { CommandLine } from "effect/process"
|
|
188
|
+
*
|
|
189
|
+
* const token = Redacted.make("hunter2")
|
|
190
|
+
*
|
|
191
|
+
* CommandLine.display(["curl", "-H", token, "https://x.dev/a b"]) // => "curl -H <redacted> 'https://x.dev/a b'"
|
|
192
|
+
* ```
|
|
193
|
+
*
|
|
194
|
+
* @see {@link join} for building a command line to run
|
|
195
|
+
*
|
|
196
|
+
* @stability unstable
|
|
197
|
+
* @category encoding
|
|
198
|
+
* @since 4.0.7
|
|
199
|
+
*/
|
|
200
|
+
const display = (words, options) => {
|
|
201
|
+
if (words.length === 0) return "";
|
|
202
|
+
const format = options?.format ?? "posix";
|
|
203
|
+
return joinWords(format, words.map((word, i) => isRedacted(word) ? "<redacted>" : escapeControlCharacters(quoteWord(format, word, i === 0))));
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* Builds an argument list from a template literal.
|
|
207
|
+
*
|
|
208
|
+
* **When to use**
|
|
209
|
+
*
|
|
210
|
+
* Use to write a command as it would look in a shell while keeping every
|
|
211
|
+
* interpolated value a literal argument.
|
|
212
|
+
*
|
|
213
|
+
* **Details**
|
|
214
|
+
*
|
|
215
|
+
* - The template text is split into words as a POSIX shell does: spaces,
|
|
216
|
+
* tabs and line breaks separate words, and quotes and backslash escapes are
|
|
217
|
+
* removed. A long command can span several lines.
|
|
218
|
+
* - Text that would need a shell fails with `UnsupportedSyntax`: operators
|
|
219
|
+
* (`| & ; < > ( )`), expansions (`$NAME`, `${...}`, `$(...)`, backticks, a
|
|
220
|
+
* leading `~`, braces such as `{a,b}`, and a leading `=` that `zsh`
|
|
221
|
+
* expands), globs (`* ? [`), comments (`#` at the start of a word), and a
|
|
222
|
+
* variable assignment in the program position. Quote such characters to
|
|
223
|
+
* pass them literally.
|
|
224
|
+
* - No shell runs, so a program such as `if` or `time` names an executable.
|
|
225
|
+
* - Each `${}` value is inserted literally, without splitting or quote
|
|
226
|
+
* processing. Next to other text or inside quotes, it becomes part of the
|
|
227
|
+
* surrounding argument.
|
|
228
|
+
* - An array adds one argument per element and must stand alone as a whole
|
|
229
|
+
* argument.
|
|
230
|
+
* - Numbers and booleans are converted with `String`.
|
|
231
|
+
* - An argument that contains a `Redacted` value becomes `Redacted` as a
|
|
232
|
+
* whole.
|
|
233
|
+
*
|
|
234
|
+
* **Gotchas**
|
|
235
|
+
*
|
|
236
|
+
* - An invalid JavaScript escape sequence in the text, such as `\u` without
|
|
237
|
+
* hex digits, fails with `InvalidEscape`. Use `String.raw` or a `${}` value
|
|
238
|
+
* for backslashes.
|
|
239
|
+
* - Neither the text nor the values are checked for NUL characters.
|
|
240
|
+
* {@link join} and the child process spawners reject them where they would
|
|
241
|
+
* truncate an argument.
|
|
242
|
+
*
|
|
243
|
+
* **Example** (Building arguments with interpolated values)
|
|
244
|
+
*
|
|
245
|
+
* ```ts import.meta.vitest
|
|
246
|
+
* import { Redacted, Result } from "effect"
|
|
247
|
+
* import { CommandLine } from "effect/process"
|
|
248
|
+
*
|
|
249
|
+
* const msg = "fix: handle $HOME"
|
|
250
|
+
* const files = ["a.ts", "b.ts"]
|
|
251
|
+
*
|
|
252
|
+
* CommandLine.template`git commit -m ${msg} ${files}` // => Result.succeed(["git", "commit", "-m", msg, ...files])
|
|
253
|
+
*
|
|
254
|
+
* const password = Redacted.make("hunter2")
|
|
255
|
+
* const words = Result.getOrThrow(CommandLine.template`psql "--password=${password}"`)
|
|
256
|
+
*
|
|
257
|
+
* CommandLine.display(words) // => "psql <redacted>"
|
|
258
|
+
* ```
|
|
259
|
+
*
|
|
260
|
+
* @stability unstable
|
|
261
|
+
* @category constructors
|
|
262
|
+
* @since 4.0.7
|
|
263
|
+
*/
|
|
264
|
+
const template = (strings, ...expressions) => {
|
|
265
|
+
const index = strings.findIndex((text) => text === void 0);
|
|
266
|
+
if (index !== -1) return fail(new CommandLineError({
|
|
267
|
+
reason: "InvalidEscape",
|
|
268
|
+
message: `Template part ${index} contains an invalid escape sequence`
|
|
269
|
+
}));
|
|
270
|
+
return parseTemplate$1(strings, expressions);
|
|
271
|
+
};
|
|
272
|
+
const unwrap = (item) => isRedacted(item) ? value(item) : String(item);
|
|
273
|
+
const toWord = (item) => isRedacted(item) ? item : String(item);
|
|
274
|
+
const reservedWords = /*#__PURE__*/ new Set([
|
|
275
|
+
"!",
|
|
276
|
+
"{",
|
|
277
|
+
"}",
|
|
278
|
+
"and",
|
|
279
|
+
"begin",
|
|
280
|
+
"case",
|
|
281
|
+
"coproc",
|
|
282
|
+
"do",
|
|
283
|
+
"done",
|
|
284
|
+
"elif",
|
|
285
|
+
"else",
|
|
286
|
+
"end",
|
|
287
|
+
"esac",
|
|
288
|
+
"fi",
|
|
289
|
+
"for",
|
|
290
|
+
"foreach",
|
|
291
|
+
"function",
|
|
292
|
+
"if",
|
|
293
|
+
"in",
|
|
294
|
+
"nocorrect",
|
|
295
|
+
"not",
|
|
296
|
+
"or",
|
|
297
|
+
"repeat",
|
|
298
|
+
"select",
|
|
299
|
+
"switch",
|
|
300
|
+
"then",
|
|
301
|
+
"time",
|
|
302
|
+
"until",
|
|
303
|
+
"while"
|
|
304
|
+
]);
|
|
305
|
+
const quoteWord = (format, value, program) => {
|
|
306
|
+
switch (format) {
|
|
307
|
+
case "posix": return program && reservedWords.has(value) ? `'${value}'` : quotePosix(value);
|
|
308
|
+
case "powershell": return quotePowerShell(value);
|
|
309
|
+
case "windows": return program && !value.includes("\"") ? quoteWindowsProgram(value) : quoteWindowsArgument(value);
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
const joinWords = (format, quoted) => format === "powershell" ? `& ${quoted.join(" ")}` : quoted.join(" ");
|
|
313
|
+
const posixSafe = /^[A-Za-z0-9_@+:,./-]+$/;
|
|
314
|
+
const quotePosix = (value) => posixSafe.test(value) ? value : `'${value.replace(/['\\]/g, (char) => `'\\${char}'`)}'`;
|
|
315
|
+
const quotePowerShell = (value) => `'${value.replace(/['\u2018\u2019\u201A\u201B]/g, "$&$&")}'`;
|
|
316
|
+
const windowsNeedsQuotes = /[ \t\n\v"]/;
|
|
317
|
+
const quoteWindowsArgument = (value) => {
|
|
318
|
+
if (value.length > 0 && !windowsNeedsQuotes.test(value)) return value;
|
|
319
|
+
let out = "\"";
|
|
320
|
+
let backslashes = 0;
|
|
321
|
+
for (const char of value) if (char === "\\") backslashes++;
|
|
322
|
+
else if (char === "\"") {
|
|
323
|
+
out += "\\".repeat(backslashes * 2 + 1) + "\"";
|
|
324
|
+
backslashes = 0;
|
|
325
|
+
} else {
|
|
326
|
+
out += "\\".repeat(backslashes) + char;
|
|
327
|
+
backslashes = 0;
|
|
328
|
+
}
|
|
329
|
+
return out + "\\".repeat(backslashes * 2) + "\"";
|
|
330
|
+
};
|
|
331
|
+
const quoteWindowsProgram = (value) => value.length > 0 && !/[ \t]/.test(value) ? value : `"${value}"`;
|
|
332
|
+
const controlCharacters = /[\u0000-\u001f\u007f-\u009f\u2028\u2029]/g;
|
|
333
|
+
const controlEscapes = {
|
|
334
|
+
"\n": "\\n",
|
|
335
|
+
"\r": "\\r",
|
|
336
|
+
" ": "\\t"
|
|
337
|
+
};
|
|
338
|
+
const escapeControlCharacters = (value) => value.replace(controlCharacters, (char) => controlEscapes[char] ?? `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}`);
|
|
339
|
+
const operators = "|&;<>()";
|
|
340
|
+
const globs = "*?[";
|
|
341
|
+
const expansionStart = /[A-Za-z_0-9{(@*#?$!'"-]/;
|
|
342
|
+
const quotedExpansionStart = /[A-Za-z_0-9{(@*#?$!-]/;
|
|
343
|
+
const assignmentName = /^[A-Za-z_][A-Za-z0-9_]*\+?$/;
|
|
344
|
+
const isBlank = (char) => char === " " || char === " " || char === "\n";
|
|
345
|
+
const unsupportedSyntax = (char, next, wordStart) => {
|
|
346
|
+
if (operators.includes(char)) return `The operator "${char}" needs a shell`;
|
|
347
|
+
if (char === "`") return "Command substitution needs a shell";
|
|
348
|
+
if (char === "$" && next !== void 0 && expansionStart.test(next)) return `The expansion "$${next}" needs a shell`;
|
|
349
|
+
if (globs.includes(char)) return `The glob character "${char}" needs a shell`;
|
|
350
|
+
if (!wordStart) return void 0;
|
|
351
|
+
if (char === "#") return "A comment needs a shell";
|
|
352
|
+
if (char === "~") return "Tilde expansion needs a shell";
|
|
353
|
+
if (char === "=" && next !== void 0 && !isBlank(next)) return "A leading \"=\" is expanded by zsh";
|
|
354
|
+
};
|
|
355
|
+
const parseTemplate$1 = (texts, values) => {
|
|
356
|
+
const words = [];
|
|
357
|
+
let word = [];
|
|
358
|
+
let plain = true;
|
|
359
|
+
let braceDepth = 0;
|
|
360
|
+
let quote = void 0;
|
|
361
|
+
let quotePart = 0;
|
|
362
|
+
let part = 0;
|
|
363
|
+
const error = (reason, message, at = part) => fail(new CommandLineError({
|
|
364
|
+
reason,
|
|
365
|
+
message: `${message} in template part ${at}`
|
|
366
|
+
}));
|
|
367
|
+
const endWord = () => {
|
|
368
|
+
if (word.length === 0) return;
|
|
369
|
+
const value = word.map(unwrap).join("");
|
|
370
|
+
words.push(word.length === 1 && isRedacted(word[0]) ? word[0] : word.some(isRedacted) ? make$2(value) : value);
|
|
371
|
+
word = [];
|
|
372
|
+
plain = true;
|
|
373
|
+
braceDepth = 0;
|
|
374
|
+
};
|
|
375
|
+
const scan = (text) => {
|
|
376
|
+
for (let i = 0; i < text.length; i++) {
|
|
377
|
+
const char = text[i];
|
|
378
|
+
const next = text[i + 1];
|
|
379
|
+
if (quote === "'") {
|
|
380
|
+
if (char === "'") quote = void 0;
|
|
381
|
+
else word.push(char);
|
|
382
|
+
} else if (quote === "\"") {
|
|
383
|
+
if (char === "\"") quote = void 0;
|
|
384
|
+
else if (char === "\\" && next !== void 0 && "$`\"\\\n".includes(next)) {
|
|
385
|
+
if (next !== "\n") word.push(next);
|
|
386
|
+
i++;
|
|
387
|
+
} else if (char === "`") return error("UnsupportedSyntax", "Command substitution needs a shell");
|
|
388
|
+
else if (char === "$" && next !== void 0 && quotedExpansionStart.test(next)) return error("UnsupportedSyntax", `The expansion "$${next}" needs a shell`);
|
|
389
|
+
else word.push(char);
|
|
390
|
+
} else if (isBlank(char)) endWord();
|
|
391
|
+
else if (char === "\\") {
|
|
392
|
+
if (next === void 0) return error("InvalidEscape", "A trailing backslash escapes nothing");
|
|
393
|
+
if (next !== "\n") {
|
|
394
|
+
word.push(next);
|
|
395
|
+
plain = false;
|
|
396
|
+
}
|
|
397
|
+
i++;
|
|
398
|
+
} else if (char === "'" || char === "\"") {
|
|
399
|
+
quote = char;
|
|
400
|
+
quotePart = part;
|
|
401
|
+
word.push("");
|
|
402
|
+
plain = false;
|
|
403
|
+
} else {
|
|
404
|
+
const unsupported = unsupportedSyntax(char, next, word.length === 0);
|
|
405
|
+
if (unsupported !== void 0) return error("UnsupportedSyntax", unsupported);
|
|
406
|
+
if (char === "{") braceDepth++;
|
|
407
|
+
else if (char === "}") {
|
|
408
|
+
if (braceDepth > 0) braceDepth--;
|
|
409
|
+
} else if (braceDepth > 0 && (char === "," || char === "." && next === ".")) return error("UnsupportedSyntax", "Brace expansion needs a shell");
|
|
410
|
+
else if (char === "=" && words.length === 0 && plain && assignmentName.test(word.join(""))) return error("UnsupportedSyntax", "A variable assignment needs a shell");
|
|
411
|
+
word.push(char);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
for (; part < texts.length; part++) {
|
|
416
|
+
const failure = scan(texts[part]);
|
|
417
|
+
if (failure !== void 0) return failure;
|
|
418
|
+
if (part === values.length) break;
|
|
419
|
+
const expression = values[part];
|
|
420
|
+
if (Array.isArray(expression)) {
|
|
421
|
+
const after = texts[part + 1][0];
|
|
422
|
+
if (word.length > 0 || (after === void 0 ? part + 1 < values.length : !isBlank(after))) return error("UnsupportedSyntax", "An interpolated array must be a separate argument");
|
|
423
|
+
for (const item of expression) words.push(toWord(item));
|
|
424
|
+
} else {
|
|
425
|
+
word.push(toWord(expression));
|
|
426
|
+
plain = false;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if (quote !== void 0) return error("UnterminatedQuote", "The quote is not closed", quotePart);
|
|
430
|
+
endWord();
|
|
431
|
+
return succeed(words);
|
|
432
|
+
};
|
|
433
|
+
// ../../node_modules/.pnpm/effect@4.1.2_patch_hash=0e61176203bb1256381ce1c5b488d7951983ce38ff698647d3f4617383abbf07/node_modules/effect/dist/process/ChildProcess.js
|
|
434
|
+
/**
|
|
435
|
+
* Describes child processes before they are started.
|
|
436
|
+
*
|
|
437
|
+
* A `Command` stores the executable, arguments, environment, standard streams,
|
|
438
|
+
* working directory, and other process options. Commands can also be piped
|
|
439
|
+
* together. A command is an `Effect`; running it asks the
|
|
440
|
+
* `ChildProcessSpawner` service to start the process and returns a
|
|
441
|
+
* `ChildProcessHandle`.
|
|
442
|
+
*
|
|
443
|
+
* @stability unstable
|
|
444
|
+
* @since 4.0.0
|
|
445
|
+
*/
|
|
446
|
+
const TypeId = "~effect/process/ChildProcess";
|
|
447
|
+
const Proto = {
|
|
448
|
+
.../*#__PURE__*/ Prototype({
|
|
449
|
+
label: "Command",
|
|
450
|
+
evaluate(fiber) {
|
|
451
|
+
return getUnsafe(fiber.context, ChildProcessSpawner).spawn(this);
|
|
452
|
+
}
|
|
453
|
+
}),
|
|
454
|
+
[TypeId]: TypeId
|
|
455
|
+
};
|
|
456
|
+
const makeStandardCommand = (command, args, options) => Object.assign(Object.create(Proto), {
|
|
457
|
+
_tag: "StandardCommand",
|
|
458
|
+
command,
|
|
459
|
+
args,
|
|
460
|
+
options
|
|
461
|
+
});
|
|
462
|
+
/**
|
|
463
|
+
* Create a command from a template literal, options + template, or array form.
|
|
464
|
+
*
|
|
465
|
+
* **Details**
|
|
466
|
+
*
|
|
467
|
+
* This function supports three calling conventions:
|
|
468
|
+
* 1. Template literal: `make\`npm run build\``
|
|
469
|
+
* 2. Options + template literal: `make({ cwd: "/app" })\`npm run build\``
|
|
470
|
+
* 3. Array form: `make("npm", ["run", "build"], options?)`
|
|
471
|
+
*
|
|
472
|
+
* Templates are split with `CommandLine.template`: quotes group words, each
|
|
473
|
+
* `${}` value is one literal argument, and an argument that contains a
|
|
474
|
+
* `Redacted` value stays `Redacted`. Arguments in the array form can be
|
|
475
|
+
* `Redacted` too.
|
|
476
|
+
*
|
|
477
|
+
* With the `shell` option, the template text is the shell script and is kept
|
|
478
|
+
* as written.
|
|
479
|
+
*
|
|
480
|
+
* **Gotchas**
|
|
481
|
+
*
|
|
482
|
+
* - A template is parsed when `make` is called. Shell syntax such as `|`,
|
|
483
|
+
* `$HOME`, `*` or `~` throws a `CommandLine.CommandLineError`: quote it, or
|
|
484
|
+
* pass the value with `${}`.
|
|
485
|
+
* - A template with the `shell` option cannot contain `${}` values, because
|
|
486
|
+
* their quoting depends on the shell. Build the script with
|
|
487
|
+
* `CommandLine.quote` and pass it as a string.
|
|
488
|
+
* - The program name, the first word, cannot be `Redacted`.
|
|
489
|
+
* - A NUL character in the command, an argument or an `env` value fails with
|
|
490
|
+
* a `BadArgument` error when the command is spawned.
|
|
491
|
+
*
|
|
492
|
+
* **Example** (Creating commands)
|
|
493
|
+
*
|
|
494
|
+
* ```ts import.meta.vitest
|
|
495
|
+
* import { ChildProcess } from "effect/process"
|
|
496
|
+
*
|
|
497
|
+
* // Template literal form; quotes group words
|
|
498
|
+
* const cmd1 = ChildProcess.make`echo "hello world"`
|
|
499
|
+
*
|
|
500
|
+
* // With options
|
|
501
|
+
* const cmd2 = ChildProcess.make({ cwd: "/tmp" })`ls -la`
|
|
502
|
+
*
|
|
503
|
+
* // Array form
|
|
504
|
+
* const cmd3 = ChildProcess.make("git", ["status"])
|
|
505
|
+
*
|
|
506
|
+
* const result = [cmd1.args[0], cmd2.options.cwd, cmd3.args[0]] // => ["hello world", "/tmp", "status"]
|
|
507
|
+
* ```
|
|
508
|
+
*
|
|
509
|
+
* @stability unstable
|
|
510
|
+
* @category constructors
|
|
511
|
+
* @since 4.0.0
|
|
512
|
+
*/
|
|
513
|
+
const make = function make(...args) {
|
|
514
|
+
if (isTemplateString(args[0])) {
|
|
515
|
+
const [templates, ...expressions] = args;
|
|
516
|
+
const [command, cmdArgs] = parseTemplate(templates, expressions);
|
|
517
|
+
return makeStandardCommand(command, cmdArgs, {});
|
|
518
|
+
}
|
|
519
|
+
if (typeof args[0] === "object" && !Array.isArray(args[0]) && !isTemplateString(args[0])) {
|
|
520
|
+
const options = args[0];
|
|
521
|
+
return function(templates, ...expressions) {
|
|
522
|
+
if (options.shell !== void 0 && options.shell !== false) return makeStandardCommand(shellScript(templates, expressions), [], options);
|
|
523
|
+
const [command, cmdArgs] = parseTemplate(templates, expressions);
|
|
524
|
+
return makeStandardCommand(command, cmdArgs, options);
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
if (typeof args[0] === "string" && !Array.isArray(args[1])) {
|
|
528
|
+
const [command, options = {}] = args;
|
|
529
|
+
return makeStandardCommand(command, [], options);
|
|
530
|
+
}
|
|
531
|
+
const [command, cmdArgs = [], options = {}] = args;
|
|
532
|
+
return makeStandardCommand(command, cmdArgs, options);
|
|
533
|
+
};
|
|
534
|
+
const isTemplateString = (u) => Array.isArray(u) && "raw" in u && Array.isArray(u.raw);
|
|
535
|
+
/**
|
|
536
|
+
* Parses an fd name like "fd3" to its numeric index.
|
|
537
|
+
* Returns undefined if the name is invalid.
|
|
538
|
+
*
|
|
539
|
+
* @stability unstable
|
|
540
|
+
* @category converting
|
|
541
|
+
* @since 4.0.0
|
|
542
|
+
*/
|
|
543
|
+
const parseFdName = (name) => {
|
|
544
|
+
const match = /^fd(\d+)$/.exec(name);
|
|
545
|
+
if (match === null) return void 0;
|
|
546
|
+
const fd = parseInt(match[1], 10);
|
|
547
|
+
return fd >= 3 ? fd : void 0;
|
|
548
|
+
};
|
|
549
|
+
/**
|
|
550
|
+
* Create an fd name from its numeric index.
|
|
551
|
+
*
|
|
552
|
+
* @stability unstable
|
|
553
|
+
* @category converting
|
|
554
|
+
* @since 4.0.0
|
|
555
|
+
*/
|
|
556
|
+
const fdName = (fd) => `fd${fd}`;
|
|
557
|
+
const parseTemplate = (templates, expressions) => {
|
|
558
|
+
const [program = "", ...args] = getOrThrow(template(templates, ...expressions));
|
|
559
|
+
if (typeof program !== "string") throw new CommandLineError({
|
|
560
|
+
reason: "InvalidArgument",
|
|
561
|
+
message: "The program name of a command cannot be Redacted"
|
|
562
|
+
});
|
|
563
|
+
return [program, args];
|
|
564
|
+
};
|
|
565
|
+
const shellScript = (templates, expressions) => {
|
|
566
|
+
if (expressions.length > 0) throw new CommandLineError({
|
|
567
|
+
reason: "UnsupportedSyntax",
|
|
568
|
+
message: "A shell template cannot interpolate values; build the script with CommandLine.quote"
|
|
569
|
+
});
|
|
570
|
+
const script = templates[0];
|
|
571
|
+
if (script === void 0) throw new CommandLineError({
|
|
572
|
+
reason: "InvalidEscape",
|
|
573
|
+
message: "Template part 0 contains an invalid escape sequence"
|
|
574
|
+
});
|
|
575
|
+
return script;
|
|
576
|
+
};
|
|
577
|
+
export { ChildProcessSpawner as a, make$1 as c, display as i, makeHandle as l, make as n, ExitCode as o, parseFdName as r, ProcessId as s, fdName as t };
|