@plurnk/plurnk-execs-jq 1.3.12 → 1.5.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/README.md +20 -13
- package/dist/Jq.d.ts +1 -1
- package/dist/Jq.d.ts.map +1 -1
- package/dist/Jq.js +40 -18
- package/dist/Jq.js.map +1 -1
- package/docs/jq.md +13 -7
- package/package.json +9 -7
package/README.md
CHANGED
|
@@ -2,29 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
`jq` runtime executor for [plurnk-service](https://github.com/plurnk/plurnk-service)'s `exec` scheme. Drives `EXEC[jq]` by shelling the system `jq` binary to filter/transform JSON — no third-party JSON-filter library.
|
|
4
4
|
|
|
5
|
-
A `@plurnk/plurnk-execs-*` sibling built on the [plurnk-execs](https://github.com/plurnk/plurnk-execs) framework.
|
|
5
|
+
A `@plurnk/plurnk-execs-*` sibling built on the [plurnk-execs](https://github.com/plurnk/plurnk-service/tree/main/plurnk-execs) framework.
|
|
6
6
|
|
|
7
7
|
## Invocation model
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
The body is the jq program and defaults to `.` when empty. The optional target
|
|
10
|
+
is the data source. Without one, jq receives `-n` (null input), so the program
|
|
11
|
+
is self-contained.
|
|
10
12
|
|
|
11
|
-
| EXEC
|
|
12
|
-
|
|
13
|
-
| `<<EXEC[jq]:{"a":1}:EXEC`
|
|
14
|
-
| `<<EXEC[jq]:[1,2,3] \| add:EXEC`
|
|
15
|
-
| `<<EXEC[jq](data.json):.users[].name:EXEC`
|
|
16
|
-
| `<<EXEC[jq](data.json):EXEC`
|
|
17
|
-
| `<<EXEC[jq](
|
|
13
|
+
| EXEC | Runs | Purpose |
|
|
14
|
+
| -------------------------------------------------------- | --------------------------------- | ---------------------------------- |
|
|
15
|
+
| `<<EXEC[jq]:{"a":1}:EXEC` | `jq -n '{"a":1}'` | Construct or validate inline JSON. |
|
|
16
|
+
| `<<EXEC[jq]:[1,2,3] \| add:EXEC` | `jq -n '[1,2,3] \| add'` | Compute without input. |
|
|
17
|
+
| `<<EXEC[jq](data.json):.users[].name:EXEC` | `jq '.users[].name' data.json` | Filter a file. |
|
|
18
|
+
| `<<EXEC[jq](data.json):EXEC` | `jq '.' data.json` | Apply identity to a file. |
|
|
19
|
+
| `<<EXEC[jq](search:///1/2/3#results):.[] \| .title:EXEC` | Consumer materializes the target. | Filter a prior runtime's output. |
|
|
18
20
|
|
|
19
|
-
Output
|
|
21
|
+
Output streams to `#results` as `application/jsonl`: one compact JSON value per
|
|
22
|
+
line ({§executor-output-address}).
|
|
20
23
|
|
|
21
24
|
## Effect & availability
|
|
22
25
|
|
|
23
|
-
- **`effect`** — inline/`-n`
|
|
26
|
+
- **`effect`** — inline/`-n` is `pure`; a target data source is `read`. Both
|
|
27
|
+
bypass the human proposal gate, then stream on the same next-turn path as
|
|
28
|
+
every EXEC ({§executor-effect}).
|
|
24
29
|
- **`probe`** — `jq` on PATH (`jq --version`).
|
|
25
|
-
- **Errors**
|
|
30
|
+
- **Errors** return RFC 9457 Problems (`jq-error`, `spawn-failed`) in the
|
|
31
|
+
terminal operation result.
|
|
26
32
|
|
|
27
|
-
jq is a leaf process, so cancellation is a plain signal kill
|
|
33
|
+
jq is a leaf process, so cancellation is a plain signal kill; it needs no
|
|
34
|
+
process-group handling.
|
|
28
35
|
|
|
29
36
|
## Tests
|
|
30
37
|
|
package/dist/Jq.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ export default class Jq extends BaseExecutor {
|
|
|
4
4
|
get channels(): Readonly<Record<string, ChannelDecl>>;
|
|
5
5
|
effect(target: string | null): Effect;
|
|
6
6
|
probe(signal?: AbortSignal): Promise<RuntimeAvailability>;
|
|
7
|
-
run({ command, cwd, target, env, signal, write, setState
|
|
7
|
+
run({ command, cwd, target, env, signal, write, setState }: ExecArgs): Promise<ExecResult>;
|
|
8
8
|
}
|
|
9
9
|
//# sourceMappingURL=Jq.d.ts.map
|
package/dist/Jq.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Jq.d.ts","sourceRoot":"","sources":["../src/Jq.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"Jq.d.ts","sourceRoot":"","sources":["../src/Jq.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAwB,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAgB3G,MAAM,CAAC,OAAO,OAAO,EAAG,SAAQ,YAAY;IAKxC,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAEpD;IAGQ,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE7C;IAEc,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAevE;IAEK,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAwF/F;CACJ"}
|
package/dist/Jq.js
CHANGED
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
import { BaseExecutor } from "@plurnk/plurnk-execs";
|
|
2
|
+
import { BaseExecutor, ErrorDetail, Results } from "@plurnk/plurnk-execs";
|
|
3
3
|
// jq executor — shells the system `jq` binary (no third-party JSON-filter lib).
|
|
4
4
|
// Invocation model:
|
|
5
5
|
// body = the jq program (defaults to `.` identity if empty)
|
|
6
6
|
// target = optional data source; present → jq reads that file; absent → `-n`
|
|
7
7
|
// (null input) so the body is self-contained.
|
|
8
8
|
// So `EXEC[jq](data.json):.users[].name` filters a file, `EXEC[jq]:[1,2,3]|add`
|
|
9
|
-
// computes
|
|
10
|
-
// the
|
|
9
|
+
// computes without input, and a tag-addressed prior stream can be the target
|
|
10
|
+
// once the consumer resolves it to a path ({§executor-output-address}).
|
|
11
11
|
//
|
|
12
12
|
// jq is a leaf process (no shell, no grandchildren), so a plain signal-based
|
|
13
13
|
// spawn is sufficient — no process-group machinery needed. It's a pure filter
|
|
14
|
-
// (no host writes / exec), so `effect` is `pure`/`read`
|
|
14
|
+
// (no host writes / exec), so `effect` is `pure`/`read` and bypasses proposal
|
|
15
|
+
// admission; output still follows the universal background stream path
|
|
16
|
+
// ({§executor-effect}).
|
|
15
17
|
export default class Jq extends BaseExecutor {
|
|
16
18
|
// jq is a streaming filter: a multi-value program emits one value per line.
|
|
17
19
|
// run() spawns with -c so each value stays compact on its own line, making
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
+
// {§executor-channels} The channel is honest JSONL; a single value is a valid
|
|
21
|
+
// one-line JSONL document too.
|
|
20
22
|
get channels() {
|
|
21
23
|
return { results: { mimetype: "application/jsonl" } };
|
|
22
24
|
}
|
|
23
|
-
// Inline/`-n` → pure; a
|
|
25
|
+
// Inline/`-n` → pure; a target data source → read ({§executor-effect}).
|
|
24
26
|
effect(target) {
|
|
25
27
|
return target ? "read" : "pure";
|
|
26
28
|
}
|
|
@@ -30,7 +32,7 @@ export default class Jq extends BaseExecutor {
|
|
|
30
32
|
return new Promise((resolve) => {
|
|
31
33
|
let out = "";
|
|
32
34
|
// Honor the consumer's per-probe signal so a resolved/timed-out probe
|
|
33
|
-
// reaps the child (
|
|
35
|
+
// reaps the child ({§executor-probe}); /dev/null stdin+stderr.
|
|
34
36
|
const child = spawn("jq", ["--version"], { signal, stdio: ["ignore", "pipe", "ignore"] });
|
|
35
37
|
child.stdout?.on("data", (c) => { out += c.toString("utf8"); });
|
|
36
38
|
child.on("error", (err) => resolve(err.code === "ABORT_ERR"
|
|
@@ -41,12 +43,18 @@ export default class Jq extends BaseExecutor {
|
|
|
41
43
|
: { available: false, detail: `jq --version exited ${code}` }));
|
|
42
44
|
});
|
|
43
45
|
}
|
|
44
|
-
async run({ command, cwd, target, env, signal, write, setState
|
|
46
|
+
async run({ command, cwd, target, env, signal, write, setState }) {
|
|
47
|
+
const detailLimit = ErrorDetail.configuredLimit();
|
|
48
|
+
if (detailLimit === null) {
|
|
49
|
+
setState("results", "errored");
|
|
50
|
+
return ErrorDetail.invalidConfiguration("executor:jq");
|
|
51
|
+
}
|
|
45
52
|
const program = command.trim() || ".";
|
|
46
53
|
// target = the data-source file; spawn resolves a relative one against cwd
|
|
47
|
-
// (the workspace)
|
|
54
|
+
// (the workspace). Absent → -n, the program stands alone
|
|
55
|
+
// ({§executor-sinks}).
|
|
48
56
|
// -c keeps each value compact on its own line so multi-value output is
|
|
49
|
-
// honest JSONL
|
|
57
|
+
// honest JSONL.
|
|
50
58
|
const args = target !== null ? ["-c", program, target] : ["-c", "-n", program];
|
|
51
59
|
return new Promise((resolve) => {
|
|
52
60
|
let settled = false;
|
|
@@ -59,29 +67,43 @@ export default class Jq extends BaseExecutor {
|
|
|
59
67
|
};
|
|
60
68
|
let err = "";
|
|
61
69
|
// jq can read the environment (`env`, `$ENV`), so honor the
|
|
62
|
-
// consumer's scoped env when provided (
|
|
70
|
+
// consumer's scoped env when provided ({§exec-env-scoped}).
|
|
63
71
|
const child = spawn("jq", args, { signal, cwd: cwd ?? undefined, env: env ?? process.env });
|
|
64
72
|
child.stdout?.on("data", (c) => write("results", c.toString("utf8")));
|
|
65
73
|
child.stderr?.on("data", (c) => { err += c.toString("utf8"); });
|
|
66
74
|
child.on("error", (e) => {
|
|
67
75
|
if (e.code === "ABORT_ERR") {
|
|
68
|
-
finish(
|
|
76
|
+
finish(Results.failure("executor:jq", "cancelled", 499, "jq execution was cancelled.", {}, {
|
|
77
|
+
stage: "execution",
|
|
78
|
+
retryable: false,
|
|
79
|
+
}), "errored");
|
|
69
80
|
return;
|
|
70
81
|
}
|
|
71
|
-
|
|
72
|
-
|
|
82
|
+
finish(Results.failure("executor:jq", "spawn-failed", 500, `Could not start jq: ${ErrorDetail.preview(e, detailLimit)}`, {}, {
|
|
83
|
+
stage: "spawn",
|
|
84
|
+
errorCode: e.code,
|
|
85
|
+
retryable: false,
|
|
86
|
+
}), "errored");
|
|
73
87
|
});
|
|
74
88
|
child.on("close", (code) => {
|
|
75
89
|
if (signal.aborted) {
|
|
76
|
-
finish(
|
|
90
|
+
finish(Results.failure("executor:jq", "cancelled", 499, "jq execution was cancelled.", {}, {
|
|
91
|
+
stage: "execution",
|
|
92
|
+
retryable: false,
|
|
93
|
+
}), "errored");
|
|
77
94
|
return;
|
|
78
95
|
}
|
|
79
96
|
if (code === 0) {
|
|
80
97
|
finish({ status: 200 }, "closed");
|
|
81
98
|
return;
|
|
82
99
|
}
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
finish(Results.failure("executor:jq", "jq-error", 500, err.trim() === ""
|
|
101
|
+
? `jq exited with code ${code ?? -1}.`
|
|
102
|
+
: ErrorDetail.preview(err.trim(), detailLimit), { exitCode: code ?? -1 }, {
|
|
103
|
+
stage: "execution",
|
|
104
|
+
recovery: "Correct the jq program or its input.",
|
|
105
|
+
retryable: false,
|
|
106
|
+
}), "errored");
|
|
85
107
|
});
|
|
86
108
|
});
|
|
87
109
|
}
|
package/dist/Jq.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Jq.js","sourceRoot":"","sources":["../src/Jq.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"Jq.js","sourceRoot":"","sources":["../src/Jq.ts"],"names":[],"mappings":"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"}
|
package/docs/jq.md
CHANGED
|
@@ -2,15 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
The system `jq` as a runtime: the **body is the jq program**, the **`(target)` is the data source**.
|
|
4
4
|
|
|
5
|
+
```plurnk
|
|
6
|
+
<<EXEC[jq]:[1,2,3] | add:EXEC
|
|
7
|
+
<<EXEC[jq](data.json):.users[].name:EXEC
|
|
8
|
+
<<EXEC[jq](search:///1/2/3#results):.[] | .title:EXEC
|
|
5
9
|
```
|
|
6
|
-
<<EXEC[jq]:[1,2,3] | add:EXEC inline — no input (-n), the program stands alone
|
|
7
|
-
<<EXEC[jq](data.json):.users[].name:EXEC filter a file
|
|
8
|
-
<<EXEC[jq](exec://…#results):.items[]:EXEC filter a prior op's output
|
|
9
|
-
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
The first form has no input and uses `-n`. The second filters a file. The third
|
|
12
|
+
filters the result stream at the emitted search address.
|
|
13
|
+
|
|
14
|
+
An empty body defaults to `.` (identity). Results land on `#results` as
|
|
15
|
+
`application/jsonl`—one compact value per line—under the emitted `jq://`
|
|
16
|
+
address.
|
|
12
17
|
|
|
13
|
-
## Deliberate departures from the `jq` CLI
|
|
18
|
+
## Deliberate departures from the `jq` CLI
|
|
14
19
|
|
|
15
20
|
- **No stdin.** The op grammar has no pipe; `jq`'s read-stdin default maps to `-n` (null input) when no target is given, so an inline program constructs its own input. A file target matches `jq program file` exactly.
|
|
16
21
|
- **Compact output is forced (`-c`).** `jq`'s pretty-print default would break the channel's JSONL contract; presentation belongs to the consumer's mimetype pipeline, not the filter.
|
|
@@ -20,4 +25,5 @@ An empty body defaults to `.` (identity). Results land on `results` as `applicat
|
|
|
20
25
|
|
|
21
26
|
## Errors
|
|
22
27
|
|
|
23
|
-
A failed program or spawn closes `results` as `errored` with status 500 and
|
|
28
|
+
A failed program or spawn closes `results` as `errored` with status 500 and an
|
|
29
|
+
RFC 9457 Problem carrying jq's own stderr.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plurnk/plurnk-execs-jq",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "jq runtime executor for plurnk-service's exec scheme — shells the system jq binary to filter/transform JSON for EXEC[jq].",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"plurnk",
|
|
@@ -11,13 +11,14 @@
|
|
|
11
11
|
"json",
|
|
12
12
|
"filter"
|
|
13
13
|
],
|
|
14
|
-
"homepage": "https://github.com/plurnk/plurnk-execs-jq#readme",
|
|
14
|
+
"homepage": "https://github.com/plurnk/plurnk-service/tree/main/plurnk-execs-jq#readme",
|
|
15
15
|
"bugs": {
|
|
16
|
-
"url": "https://
|
|
16
|
+
"url": "https://repo.possumtech.com/plurnk/plurnk-service/issues"
|
|
17
17
|
},
|
|
18
18
|
"repository": {
|
|
19
19
|
"type": "git",
|
|
20
|
-
"url": "git+https://github.com/plurnk/plurnk-
|
|
20
|
+
"url": "git+https://github.com/plurnk/plurnk-service.git",
|
|
21
|
+
"directory": "plurnk-execs-jq"
|
|
21
22
|
},
|
|
22
23
|
"engines": {
|
|
23
24
|
"node": ">=26"
|
|
@@ -53,14 +54,15 @@
|
|
|
53
54
|
],
|
|
54
55
|
"scripts": {
|
|
55
56
|
"test:lint": "tsc --noEmit",
|
|
56
|
-
"test:unit": "node --conditions=plurnk-dev --test \"src/**/*.test.ts\"",
|
|
57
|
+
"test:unit": "node --conditions=plurnk-dev --env-file-if-exists=../plurnk-execs/.env.defaults --test \"src/**/*.test.ts\"",
|
|
57
58
|
"test": "npm run test:lint && npm run test:unit",
|
|
59
|
+
"build:clean": "rm -rf dist",
|
|
58
60
|
"build:dist": "tsc -p tsconfig.build.json",
|
|
59
|
-
"build": "npm run build:dist",
|
|
61
|
+
"build": "npm run build:clean && npm run build:dist",
|
|
60
62
|
"prepack": "npm run build",
|
|
61
63
|
"prepublishOnly": "npm audit --audit-level=moderate && npm test"
|
|
62
64
|
},
|
|
63
65
|
"peerDependencies": {
|
|
64
|
-
"@plurnk/plurnk-execs": "^1.
|
|
66
|
+
"@plurnk/plurnk-execs": "^1.5.0"
|
|
65
67
|
}
|
|
66
68
|
}
|