@procedures/shell 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/CHANGELOG.md +5 -0
- package/LICENSE +21 -0
- package/README.md +421 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/command/index.d.ts +18 -0
- package/dist/command/index.d.ts.map +1 -0
- package/dist/command/index.js +17 -0
- package/dist/command/index.js.map +1 -0
- package/dist/command/output.d.ts +22 -0
- package/dist/command/output.d.ts.map +1 -0
- package/dist/command/output.js +67 -0
- package/dist/command/output.js.map +1 -0
- package/dist/command/processes.d.ts +89 -0
- package/dist/command/processes.d.ts.map +1 -0
- package/dist/command/processes.js +223 -0
- package/dist/command/processes.js.map +1 -0
- package/dist/command/run.d.ts +48 -0
- package/dist/command/run.d.ts.map +1 -0
- package/dist/command/run.js +89 -0
- package/dist/command/run.js.map +1 -0
- package/dist/command/spawn.d.ts +26 -0
- package/dist/command/spawn.d.ts.map +1 -0
- package/dist/command/spawn.js +28 -0
- package/dist/command/spawn.js.map +1 -0
- package/dist/command/stream.d.ts +42 -0
- package/dist/command/stream.d.ts.map +1 -0
- package/dist/command/stream.js +158 -0
- package/dist/command/stream.js.map +1 -0
- package/dist/command/tree-kill.d.ts +26 -0
- package/dist/command/tree-kill.d.ts.map +1 -0
- package/dist/command/tree-kill.js +122 -0
- package/dist/command/tree-kill.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/module.d.ts +13 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +79 -0
- package/dist/module.js.map +1 -0
- package/dist/procedures/shell/exec.d.ts +21 -0
- package/dist/procedures/shell/exec.d.ts.map +1 -0
- package/dist/procedures/shell/exec.js +45 -0
- package/dist/procedures/shell/exec.js.map +1 -0
- package/dist/procedures/shell/index.d.ts +5 -0
- package/dist/procedures/shell/index.d.ts.map +1 -0
- package/dist/procedures/shell/index.js +5 -0
- package/dist/procedures/shell/index.js.map +1 -0
- package/dist/procedures/shell/run.d.ts +14 -0
- package/dist/procedures/shell/run.d.ts.map +1 -0
- package/dist/procedures/shell/run.js +40 -0
- package/dist/procedures/shell/run.js.map +1 -0
- package/dist/procedures/shell/stream.d.ts +20 -0
- package/dist/procedures/shell/stream.d.ts.map +1 -0
- package/dist/procedures/shell/stream.js +39 -0
- package/dist/procedures/shell/stream.js.map +1 -0
- package/dist/procedures/shell/which.d.ts +10 -0
- package/dist/procedures/shell/which.d.ts.map +1 -0
- package/dist/procedures/shell/which.js +21 -0
- package/dist/procedures/shell/which.js.map +1 -0
- package/dist/register.d.ts +8 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +14 -0
- package/dist/register.js.map +1 -0
- package/dist/types.d.ts +79 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +89 -0
- package/dist/types.js.map +1 -0
- package/package.json +78 -3
- package/src/command/index.ts +24 -0
- package/src/command/output.ts +67 -0
- package/src/command/processes.ts +271 -0
- package/src/command/run.ts +127 -0
- package/src/command/spawn.ts +44 -0
- package/src/command/stream.ts +186 -0
- package/src/command/tree-kill.ts +121 -0
- package/src/index.ts +53 -0
- package/src/module.ts +102 -0
- package/src/procedures/shell/exec.ts +55 -0
- package/src/procedures/shell/index.ts +4 -0
- package/src/procedures/shell/run.ts +47 -0
- package/src/procedures/shell/stream.ts +43 -0
- package/src/procedures/shell/which.ts +26 -0
- package/src/register.ts +17 -0
- package/src/types.ts +172 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* shell.run procedure
|
|
3
|
+
*
|
|
4
|
+
* Run a command with arguments and return output.
|
|
5
|
+
*/
|
|
6
|
+
import { runCommand } from "../../command/run.js";
|
|
7
|
+
/**
|
|
8
|
+
* Most output kept per stream. Output beyond it is dropped (and reported), so a command
|
|
9
|
+
* that prints without end cannot exhaust memory. The process is not killed.
|
|
10
|
+
*/
|
|
11
|
+
const MAX_OUTPUT_BYTES = 64 * 1024 * 1024;
|
|
12
|
+
/**
|
|
13
|
+
* Run a command with its arguments and no shell. The timeout and `ctx.signal` kill the whole
|
|
14
|
+
* process tree (deep dive WRP-10).
|
|
15
|
+
*/
|
|
16
|
+
export async function shellRun(input, ctx) {
|
|
17
|
+
const result = await runCommand(input.command, {
|
|
18
|
+
args: input.args,
|
|
19
|
+
cwd: input.cwd,
|
|
20
|
+
env: input.env,
|
|
21
|
+
timeout: input.timeout,
|
|
22
|
+
signal: ctx?.signal,
|
|
23
|
+
maxOutputBytes: MAX_OUTPUT_BYTES,
|
|
24
|
+
encoding: input.encoding,
|
|
25
|
+
});
|
|
26
|
+
const note = `\n[output truncated at ${MAX_OUTPUT_BYTES} bytes]`;
|
|
27
|
+
const output = {
|
|
28
|
+
exitCode: result.exitCode,
|
|
29
|
+
stdout: result.truncated?.stdout ? result.stdout + note : result.stdout,
|
|
30
|
+
stderr: result.truncated?.stderr ? result.stderr + note : result.stderr,
|
|
31
|
+
success: result.success,
|
|
32
|
+
duration: result.duration,
|
|
33
|
+
};
|
|
34
|
+
// A signal means the process was killed (for example by the timeout)
|
|
35
|
+
if (result.signal) {
|
|
36
|
+
output.signal = result.signal;
|
|
37
|
+
}
|
|
38
|
+
return output;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/procedures/shell/run.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlD;;;GAGG;AACH,MAAM,gBAAgB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAE1C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,KAAoB,EACpB,GAA0C;IAE1C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE;QAC7C,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,GAAG,EAAE,MAAM;QACnB,cAAc,EAAE,gBAAgB;QAChC,QAAQ,EAAE,KAAK,CAAC,QAA0B;KAC3C,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,0BAA0B,gBAAgB,SAAS,CAAC;IACjE,MAAM,MAAM,GAAmB;QAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM;QACvE,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM;QACvE,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC;IACF,qEAAqE;IACrE,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAChC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* shell.stream procedure
|
|
3
|
+
*
|
|
4
|
+
* Run a command and stream each output line as it arrives. The procedure is a generator: the
|
|
5
|
+
* caller reads `{ type: "stdout" | "stderr", line }` items while the command runs, then one
|
|
6
|
+
* `{ type: "exit" }` item. When the caller stops reading, or its signal aborts, the command and
|
|
7
|
+
* the programs that it started end.
|
|
8
|
+
*
|
|
9
|
+
* The queue to the reader has a limit: when the reader is slow, the command waits in its next
|
|
10
|
+
* write (deep dive WRP-9). A character whose bytes arrive in two chunks stays whole (deep dive
|
|
11
|
+
* WRP-2). The work is done by `streamCommand`.
|
|
12
|
+
*/
|
|
13
|
+
import type { ShellStreamInput, ShellStreamItem } from "../../types.js";
|
|
14
|
+
/**
|
|
15
|
+
* Run a command and stream each output line as it arrives
|
|
16
|
+
*/
|
|
17
|
+
export declare function shellStream(input: ShellStreamInput, ctx?: {
|
|
18
|
+
signal?: AbortSignal | undefined;
|
|
19
|
+
}): AsyncGenerator<ShellStreamItem, void, undefined>;
|
|
20
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../src/procedures/shell/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAExE;;GAEG;AACH,wBAAuB,WAAW,CAChC,KAAK,EAAE,gBAAgB,EACvB,GAAG,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;CAAE,GACzC,cAAc,CAAC,eAAe,EAAE,IAAI,EAAE,SAAS,CAAC,CAoBlD"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* shell.stream procedure
|
|
3
|
+
*
|
|
4
|
+
* Run a command and stream each output line as it arrives. The procedure is a generator: the
|
|
5
|
+
* caller reads `{ type: "stdout" | "stderr", line }` items while the command runs, then one
|
|
6
|
+
* `{ type: "exit" }` item. When the caller stops reading, or its signal aborts, the command and
|
|
7
|
+
* the programs that it started end.
|
|
8
|
+
*
|
|
9
|
+
* The queue to the reader has a limit: when the reader is slow, the command waits in its next
|
|
10
|
+
* write (deep dive WRP-9). A character whose bytes arrive in two chunks stays whole (deep dive
|
|
11
|
+
* WRP-2). The work is done by `streamCommand`.
|
|
12
|
+
*/
|
|
13
|
+
import { streamCommand } from "../../command/stream.js";
|
|
14
|
+
/**
|
|
15
|
+
* Run a command and stream each output line as it arrives
|
|
16
|
+
*/
|
|
17
|
+
export async function* shellStream(input, ctx) {
|
|
18
|
+
// No shell: the arguments cannot inject commands
|
|
19
|
+
for await (const item of streamCommand(input.command, {
|
|
20
|
+
args: input.args,
|
|
21
|
+
cwd: input.cwd,
|
|
22
|
+
env: input.env,
|
|
23
|
+
timeout: input.timeout,
|
|
24
|
+
signal: ctx?.signal,
|
|
25
|
+
})) {
|
|
26
|
+
if (item.type === "exit") {
|
|
27
|
+
yield {
|
|
28
|
+
type: "exit",
|
|
29
|
+
exitCode: item.exitCode,
|
|
30
|
+
duration: item.duration,
|
|
31
|
+
...(item.signal ? { signal: item.signal } : {}),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
yield item;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../../src/procedures/shell/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGxD;;GAEG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,WAAW,CAChC,KAAuB,EACvB,GAA0C;IAE1C,iDAAiD;IACjD,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,aAAa,CAAC,KAAK,CAAC,OAAO,EAAE;QACpD,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,GAAG,EAAE,MAAM;KACpB,CAAC,EAAE,CAAC;QACH,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,MAAM;gBACJ,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAChD,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC;QACb,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* shell.which procedure
|
|
3
|
+
*
|
|
4
|
+
* Find the full path to a command.
|
|
5
|
+
*/
|
|
6
|
+
import type { ShellWhichInput, ShellWhichOutput } from "../../types.js";
|
|
7
|
+
export declare function shellWhich(input: ShellWhichInput, ctx?: {
|
|
8
|
+
signal?: AbortSignal | undefined;
|
|
9
|
+
}): Promise<ShellWhichOutput>;
|
|
10
|
+
//# sourceMappingURL=which.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"which.d.ts","sourceRoot":"","sources":["../../../src/procedures/shell/which.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAExE,wBAAsB,UAAU,CAC9B,KAAK,EAAE,eAAe,EACtB,GAAG,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;CAAE,GACzC,OAAO,CAAC,gBAAgB,CAAC,CAa3B"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* shell.which procedure
|
|
3
|
+
*
|
|
4
|
+
* Find the full path to a command.
|
|
5
|
+
*/
|
|
6
|
+
import { runCommand } from "../../command/run.js";
|
|
7
|
+
export async function shellWhich(input, ctx) {
|
|
8
|
+
// The name is one argument of where/which, with no shell. (Before, `where ${command}` ran in a
|
|
9
|
+
// shell, so a name such as `x & calc` ran a second command: deep dive WRP-6.)
|
|
10
|
+
if (input.command.startsWith("-")) {
|
|
11
|
+
return { path: null, found: false };
|
|
12
|
+
}
|
|
13
|
+
const program = process.platform === "win32" ? "where" : "which";
|
|
14
|
+
const result = await runCommand(program, { args: [input.command], signal: ctx?.signal, timeout: 30_000 });
|
|
15
|
+
if (!result.success) {
|
|
16
|
+
return { path: null, found: false };
|
|
17
|
+
}
|
|
18
|
+
const path = result.stdout.trim().split(/\r?\n/)[0]?.trim() ?? "";
|
|
19
|
+
return path.length > 0 ? { path, found: true } : { path: null, found: false };
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=which.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"which.js","sourceRoot":"","sources":["../../../src/procedures/shell/which.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlD,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAsB,EACtB,GAA0C;IAE1C,+FAA+F;IAC/F,8EAA8E;IAC9E,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACtC,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IACjE,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1G,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACtC,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAClE,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAChF,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Importing this file registers the procedures of @procedures/shell in the global registry
|
|
3
|
+
* (DECISIONS-2026-10, "Every package root registers its procedures"). The procedures as data
|
|
4
|
+
* are in `module.ts`, which registers nothing: a host with its own registry uses that one.
|
|
5
|
+
*/
|
|
6
|
+
export * from "./module.js";
|
|
7
|
+
export declare function registerShellProcedures(): void;
|
|
8
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,cAAc,aAAa,CAAC;AAE5B,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}
|
package/dist/register.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Importing this file registers the procedures of @procedures/shell in the global registry
|
|
3
|
+
* (DECISIONS-2026-10, "Every package root registers its procedures"). The procedures as data
|
|
4
|
+
* are in `module.ts`, which registers nothing: a host with its own registry uses that one.
|
|
5
|
+
*/
|
|
6
|
+
import { registerProcedures } from "@procedures/client";
|
|
7
|
+
import { shellModule } from "./module.js";
|
|
8
|
+
export * from "./module.js";
|
|
9
|
+
export function registerShellProcedures() {
|
|
10
|
+
registerProcedures(shellModule.procedures);
|
|
11
|
+
}
|
|
12
|
+
// Auto-register when this module is loaded
|
|
13
|
+
registerShellProcedures();
|
|
14
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,cAAc,aAAa,CAAC;AAE5B,MAAM,UAAU,uBAAuB;IACrC,kBAAkB,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;AAC7C,CAAC;AAED,2CAA2C;AAC3C,uBAAuB,EAAE,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell command types
|
|
3
|
+
*/
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
export declare const ShellRunInputSchema: z.ZodObject<{
|
|
6
|
+
command: z.ZodString;
|
|
7
|
+
args: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
8
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
9
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
10
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
11
|
+
encoding: z.ZodDefault<z.ZodString>;
|
|
12
|
+
}>;
|
|
13
|
+
export type ShellRunInput = z.infer<typeof ShellRunInputSchema>;
|
|
14
|
+
export interface ShellRunOutput {
|
|
15
|
+
/** Exit code */
|
|
16
|
+
exitCode: number;
|
|
17
|
+
/** Standard output */
|
|
18
|
+
stdout: string;
|
|
19
|
+
/** Standard error */
|
|
20
|
+
stderr: string;
|
|
21
|
+
/** Whether command succeeded (exit code 0) */
|
|
22
|
+
success: boolean;
|
|
23
|
+
/** Duration in milliseconds */
|
|
24
|
+
duration: number;
|
|
25
|
+
/** The signal that ended the process, if it was killed (for example by the timeout) */
|
|
26
|
+
signal?: string | undefined;
|
|
27
|
+
}
|
|
28
|
+
export declare const ShellExecInputSchema: z.ZodObject<{
|
|
29
|
+
command: z.ZodString;
|
|
30
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
31
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
32
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
shell: z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
34
|
+
maxBuffer: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
stdin: z.ZodOptional<z.ZodString>;
|
|
36
|
+
}>;
|
|
37
|
+
export type ShellExecInput = z.infer<typeof ShellExecInputSchema>;
|
|
38
|
+
export interface ShellExecOutput {
|
|
39
|
+
exitCode: number;
|
|
40
|
+
stdout: string;
|
|
41
|
+
stderr: string;
|
|
42
|
+
success: boolean;
|
|
43
|
+
duration: number;
|
|
44
|
+
/** Signal that terminated the process (if any) */
|
|
45
|
+
signal?: string | undefined;
|
|
46
|
+
}
|
|
47
|
+
export declare const ShellWhichInputSchema: z.ZodObject<{
|
|
48
|
+
command: z.ZodString;
|
|
49
|
+
}>;
|
|
50
|
+
export type ShellWhichInput = z.infer<typeof ShellWhichInputSchema>;
|
|
51
|
+
export interface ShellWhichOutput {
|
|
52
|
+
/** Full path to command, or null if not found */
|
|
53
|
+
path: string | null;
|
|
54
|
+
/** Whether command was found */
|
|
55
|
+
found: boolean;
|
|
56
|
+
}
|
|
57
|
+
export declare const ShellStreamInputSchema: z.ZodObject<{
|
|
58
|
+
command: z.ZodString;
|
|
59
|
+
args: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
60
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
61
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
62
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
63
|
+
}>;
|
|
64
|
+
export type ShellStreamInput = z.infer<typeof ShellStreamInputSchema>;
|
|
65
|
+
/** One item of shell.stream: an output line, or the exit of the command (the last item). */
|
|
66
|
+
export type ShellStreamItem = {
|
|
67
|
+
type: "stdout" | "stderr";
|
|
68
|
+
line: string;
|
|
69
|
+
} | {
|
|
70
|
+
type: "exit";
|
|
71
|
+
exitCode: number;
|
|
72
|
+
duration: number;
|
|
73
|
+
signal?: string | undefined;
|
|
74
|
+
};
|
|
75
|
+
export declare const ShellRunOutputSchema: z.ZodType<ShellRunOutput>;
|
|
76
|
+
export declare const ShellExecOutputSchema: z.ZodType<ShellExecOutput>;
|
|
77
|
+
export declare const ShellWhichOutputSchema: z.ZodType<ShellWhichOutput>;
|
|
78
|
+
export declare const ShellStreamItemSchema: z.ZodType<ShellStreamItem>;
|
|
79
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,mBAAmB,EAAE,CAAC,CAAC,SAAS,CAAC;IAC5C,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5C,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAChC,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC1D,OAAO,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACpC,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;CACrC,CAaC,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,MAAM,WAAW,cAAc;IAC7B,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,uFAAuF;IACvF,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAMD,eAAO,MAAM,oBAAoB,EAAE,CAAC,CAAC,SAAS,CAAC;IAC7C,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAChC,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC1D,OAAO,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACpC,KAAK,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACtE,SAAS,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACtC,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;CACnC,CAeC,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAMD,eAAO,MAAM,qBAAqB,EAAE,CAAC,CAAC,SAAS,CAAC;IAC9C,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC;CACtB,CAGC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,gCAAgC;IAChC,KAAK,EAAE,OAAO,CAAC;CAChB;AAMD,eAAO,MAAM,sBAAsB,EAAE,CAAC,CAAC,SAAS,CAAC;IAC/C,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5C,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAChC,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC1D,OAAO,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;CACrC,CAMC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,4FAA4F;AAC5F,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAkBtF,eAAO,MAAM,oBAAoB,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAgC,CAAC;AAE5F,eAAO,MAAM,qBAAqB,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,CAAgC,CAAC;AAE9F,eAAO,MAAM,sBAAsB,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAG7D,CAAC;AAEH,eAAO,MAAM,qBAAqB,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,CAW3D,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell command types
|
|
3
|
+
*/
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
// =============================================================================
|
|
6
|
+
// shell.run Types
|
|
7
|
+
// =============================================================================
|
|
8
|
+
export const ShellRunInputSchema = z.object({
|
|
9
|
+
/** Command to run */
|
|
10
|
+
command: z.string().describe("Command to run"),
|
|
11
|
+
/** Arguments to pass */
|
|
12
|
+
args: z.array(z.string()).default([]).describe("Arguments to pass"),
|
|
13
|
+
/** Working directory */
|
|
14
|
+
cwd: z.string().optional().describe("Working directory"),
|
|
15
|
+
/** Environment variables to set */
|
|
16
|
+
env: z.record(z.string(), z.string()).optional().describe("Environment variables to set"),
|
|
17
|
+
/** Timeout in milliseconds */
|
|
18
|
+
timeout: z.number().optional().describe("Timeout in milliseconds"),
|
|
19
|
+
/** Encoding for output (default: utf8) */
|
|
20
|
+
encoding: z.string().default("utf8").describe("Encoding for output (default: utf8)"),
|
|
21
|
+
});
|
|
22
|
+
// =============================================================================
|
|
23
|
+
// shell.exec Types (more options)
|
|
24
|
+
// =============================================================================
|
|
25
|
+
export const ShellExecInputSchema = z.object({
|
|
26
|
+
/** Full command string to execute via shell */
|
|
27
|
+
command: z.string().describe("Full command string to execute via shell"),
|
|
28
|
+
/** Working directory */
|
|
29
|
+
cwd: z.string().optional().describe("Working directory"),
|
|
30
|
+
/** Environment variables */
|
|
31
|
+
env: z.record(z.string(), z.string()).optional().describe("Environment variables"),
|
|
32
|
+
/** Timeout in milliseconds. At the timeout, the shell and the programs that it started are killed. */
|
|
33
|
+
timeout: z.number().optional().describe("Timeout in milliseconds. At the timeout, the shell and the programs that it started are killed."),
|
|
34
|
+
/** Shell to use: a path, or `true` for the system shell (`cmd.exe` or `/bin/sh`). `false` is the same as `true`. */
|
|
35
|
+
shell: z.union([z.boolean(), z.string()]).default(true).describe("Shell to use: a path, or `true` for the system shell (`cmd.exe` or `/bin/sh`). `false` is the same as `true`."),
|
|
36
|
+
/** The most bytes kept of each output stream (default: 64 MiB). The procedure drops the rest. */
|
|
37
|
+
maxBuffer: z.number().optional().describe("The most bytes kept of each output stream (default: 64 MiB). The procedure drops the rest."),
|
|
38
|
+
/** Text to write to stdin. Without it, stdin is empty. */
|
|
39
|
+
stdin: z.string().optional().describe("Text to write to stdin. Without it, stdin is empty."),
|
|
40
|
+
});
|
|
41
|
+
// =============================================================================
|
|
42
|
+
// shell.which Types
|
|
43
|
+
// =============================================================================
|
|
44
|
+
export const ShellWhichInputSchema = z.object({
|
|
45
|
+
/** Command to find */
|
|
46
|
+
command: z.string().describe("Command to find"),
|
|
47
|
+
});
|
|
48
|
+
// =============================================================================
|
|
49
|
+
// shell.stream Types - Run a command and stream each output line as it arrives
|
|
50
|
+
// =============================================================================
|
|
51
|
+
export const ShellStreamInputSchema = z.object({
|
|
52
|
+
command: z.string().describe("The program to start (no shell: arguments go in args)"),
|
|
53
|
+
args: z.array(z.string()).default([]).describe("The arguments of the program"),
|
|
54
|
+
cwd: z.string().optional().describe("Working directory"),
|
|
55
|
+
env: z.record(z.string(), z.string()).optional().describe("Environment variables (added to the environment of the host)"),
|
|
56
|
+
timeout: z.number().optional().describe("Timeout in milliseconds. At the timeout, the program and its children are killed."),
|
|
57
|
+
});
|
|
58
|
+
// =============================================================================
|
|
59
|
+
// Output schemas (roadmap 2.1)
|
|
60
|
+
// =============================================================================
|
|
61
|
+
// Loose objects: a field that a schema does not name stays in the result (a strict schema would
|
|
62
|
+
// remove it when the output is validated).
|
|
63
|
+
const commandResult = {
|
|
64
|
+
exitCode: z.number().describe("The exit code (0 is success, -1 when a signal ended the program)"),
|
|
65
|
+
stdout: z.string().describe("The standard output"),
|
|
66
|
+
stderr: z.string().describe("The standard error"),
|
|
67
|
+
success: z.boolean().describe("True when the exit code is 0"),
|
|
68
|
+
duration: z.number().describe("The time of the command, in milliseconds"),
|
|
69
|
+
signal: z.string().optional().describe("The signal that ended the program (for example at the timeout)"),
|
|
70
|
+
};
|
|
71
|
+
export const ShellRunOutputSchema = z.looseObject(commandResult);
|
|
72
|
+
export const ShellExecOutputSchema = z.looseObject(commandResult);
|
|
73
|
+
export const ShellWhichOutputSchema = z.looseObject({
|
|
74
|
+
path: z.string().nullable().describe("The full path of the program, or null when it is not found"),
|
|
75
|
+
found: z.boolean().describe("True when the program is found"),
|
|
76
|
+
});
|
|
77
|
+
export const ShellStreamItemSchema = z.union([
|
|
78
|
+
z.looseObject({
|
|
79
|
+
type: z.enum(["stdout", "stderr"]).describe("The stream of the line"),
|
|
80
|
+
line: z.string().describe("One line of output, without its line end"),
|
|
81
|
+
}),
|
|
82
|
+
z.looseObject({
|
|
83
|
+
type: z.literal("exit").describe("The end of the stream (the last item)"),
|
|
84
|
+
exitCode: z.number().describe("The exit code (-1 when a signal ended the program)"),
|
|
85
|
+
duration: z.number().describe("The time of the command, in milliseconds"),
|
|
86
|
+
signal: z.string().optional().describe("The signal that ended the program"),
|
|
87
|
+
}),
|
|
88
|
+
]);
|
|
89
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,81 @@
|
|
|
1
1
|
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package",
|
|
2
3
|
"name": "@procedures/shell",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "Safe command execution for TypeScript: shell.run with argv and no shell, shell.stream line streaming with backpressure, process-tree kill, timeouts and output caps.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"shell",
|
|
8
|
+
"exec",
|
|
9
|
+
"spawn",
|
|
10
|
+
"child-process",
|
|
11
|
+
"streaming",
|
|
12
|
+
"procedures"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://mark1russell7.github.io/client/",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/mark1russell7/client/issues"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/mark1russell7/client.git",
|
|
21
|
+
"directory": "packages/client-shell"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"author": "Mark Russell (https://github.com/mark1russell7)",
|
|
25
|
+
"type": "module",
|
|
26
|
+
"main": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./module": {
|
|
34
|
+
"types": "./dist/module.d.ts",
|
|
35
|
+
"import": "./dist/module.js"
|
|
36
|
+
},
|
|
37
|
+
"./command": {
|
|
38
|
+
"types": "./dist/command/index.d.ts",
|
|
39
|
+
"import": "./dist/command/index.js"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist",
|
|
44
|
+
"src",
|
|
45
|
+
"!src/**/*.test.ts",
|
|
46
|
+
"!src/**/*.test.tsx",
|
|
47
|
+
"!src/**/__tests__",
|
|
48
|
+
"CHANGELOG.md"
|
|
49
|
+
],
|
|
50
|
+
"sideEffects": [
|
|
51
|
+
"./dist/index.js",
|
|
52
|
+
"./dist/register.js"
|
|
53
|
+
],
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=22"
|
|
56
|
+
},
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public",
|
|
59
|
+
"provenance": true
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"typescript": "^7.0.2",
|
|
63
|
+
"@types/node": "^22.0.0",
|
|
64
|
+
"@mark1russell7/cue": "^1.0.0",
|
|
65
|
+
"vitest": "^5.0.3"
|
|
66
|
+
},
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"@procedures/client": "0.1.0",
|
|
69
|
+
"zod": "^4.6.5"
|
|
70
|
+
},
|
|
71
|
+
"client": {
|
|
72
|
+
"procedures": "./dist/register.js"
|
|
73
|
+
},
|
|
74
|
+
"scripts": {
|
|
75
|
+
"build": "tsc -b",
|
|
76
|
+
"typecheck": "tsc --noEmit",
|
|
77
|
+
"clean": "rm -rf dist .tsbuildinfo",
|
|
78
|
+
"test": "vitest run",
|
|
79
|
+
"test:watch": "vitest"
|
|
80
|
+
}
|
|
6
81
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@procedures/shell/command`: the helpers that start programs (roadmap 2.2).
|
|
3
|
+
*
|
|
4
|
+
* Each wrapper package starts its program through these helpers:
|
|
5
|
+
* - an argument list, never a shell string;
|
|
6
|
+
* - `ctx.signal` and a timeout kill the whole process tree;
|
|
7
|
+
* - each output stream has a limit;
|
|
8
|
+
* - a long-running process has a record in `processes`, and ends with the host.
|
|
9
|
+
*
|
|
10
|
+
* This entry point has no side effects: unlike the package root, it registers no procedures.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export { runCommand, type CommandOptions, type CommandResult } from "./run.js";
|
|
14
|
+
export { streamCommand, type StreamCommandOptions, type CommandStreamItem } from "./stream.js";
|
|
15
|
+
export {
|
|
16
|
+
ProcessRegistry,
|
|
17
|
+
processes,
|
|
18
|
+
type ManagedProcessInfo,
|
|
19
|
+
type StartProcessOptions,
|
|
20
|
+
type StopResult,
|
|
21
|
+
} from "./processes.js";
|
|
22
|
+
export { killTree } from "./tree-kill.js";
|
|
23
|
+
export type { SpawnOptions } from "./spawn.js";
|
|
24
|
+
export { DEFAULT_MAX_OUTPUT_BYTES } from "./output.js";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collect the output of a stream as bytes, with a limit.
|
|
3
|
+
*
|
|
4
|
+
* The collector decodes the bytes once at the end, so a multibyte character split across two
|
|
5
|
+
* chunks stays whole (BUGS-2026-07 L4). Past the limit, it keeps the first bytes ("head") or the
|
|
6
|
+
* last bytes ("tail"), so a program that prints without end cannot fill the memory.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** The default limit of each output stream. */
|
|
10
|
+
export const DEFAULT_MAX_OUTPUT_BYTES: number = 64 * 1024 * 1024;
|
|
11
|
+
|
|
12
|
+
export class OutputCollector {
|
|
13
|
+
private chunks: Buffer[] = [];
|
|
14
|
+
private bytes = 0;
|
|
15
|
+
truncated = false;
|
|
16
|
+
|
|
17
|
+
constructor(
|
|
18
|
+
private readonly limit: number = DEFAULT_MAX_OUTPUT_BYTES,
|
|
19
|
+
private readonly keep: "head" | "tail" = "head",
|
|
20
|
+
) {}
|
|
21
|
+
|
|
22
|
+
add(chunk: Buffer): void {
|
|
23
|
+
if (this.keep === "head") {
|
|
24
|
+
const room = this.limit - this.bytes;
|
|
25
|
+
if (room <= 0) {
|
|
26
|
+
this.truncated = true;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const kept = chunk.length > room ? chunk.subarray(0, room) : chunk;
|
|
30
|
+
if (kept.length < chunk.length) this.truncated = true;
|
|
31
|
+
this.chunks.push(kept);
|
|
32
|
+
this.bytes += kept.length;
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this.chunks.push(chunk);
|
|
36
|
+
this.bytes += chunk.length;
|
|
37
|
+
// Drop whole chunks from the start while the rest is above the limit, then cut the first one
|
|
38
|
+
while (this.bytes > this.limit && this.chunks.length > 0) {
|
|
39
|
+
const first = this.chunks[0]!;
|
|
40
|
+
const excess = this.bytes - this.limit;
|
|
41
|
+
this.truncated = true;
|
|
42
|
+
if (first.length <= excess) {
|
|
43
|
+
this.chunks.shift();
|
|
44
|
+
this.bytes -= first.length;
|
|
45
|
+
} else {
|
|
46
|
+
this.chunks[0] = first.subarray(excess);
|
|
47
|
+
this.bytes -= excess;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** The collected bytes. */
|
|
53
|
+
buffer(): Buffer {
|
|
54
|
+
let data = Buffer.concat(this.chunks);
|
|
55
|
+
// A cut tail can start inside a UTF-8 character: drop its continuation bytes
|
|
56
|
+
if (this.keep === "tail" && this.truncated) {
|
|
57
|
+
let start = 0;
|
|
58
|
+
while (start < data.length && start < 4 && (data[start]! & 0xc0) === 0x80) start++;
|
|
59
|
+
data = data.subarray(start);
|
|
60
|
+
}
|
|
61
|
+
return data;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
text(encoding: BufferEncoding = "utf8"): string {
|
|
65
|
+
return this.buffer().toString(encoding);
|
|
66
|
+
}
|
|
67
|
+
}
|