@forwardimpact/libcli 0.1.10 → 0.1.12
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/package.json +2 -2
- package/src/cli.js +17 -6
- package/src/invocation-context.js +9 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forwardimpact/libcli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "Agent-friendly CLIs — self-documenting entry points that humans and agents reach through the same interface.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"test": "bun test test/*.test.js"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@forwardimpact/
|
|
43
|
+
"@forwardimpact/libmock": "^0.1.0"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|
|
46
46
|
"bun": ">=1.2.0",
|
package/src/cli.js
CHANGED
|
@@ -134,8 +134,8 @@ export class Cli {
|
|
|
134
134
|
return null;
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
/** Match parsed positionals to a subcommand and invoke its handler with a frozen invocation context. */
|
|
138
|
-
dispatch(parsed, { data }) {
|
|
137
|
+
/** Match parsed positionals to a subcommand and invoke its handler with a frozen invocation context. `deps` carries host-injected collaborators (the runtime bag); `data` carries host-loaded domain values. */
|
|
138
|
+
dispatch(parsed, { data, deps } = {}) {
|
|
139
139
|
const command = this.#findCommand(parsed.positionals);
|
|
140
140
|
if (!command) {
|
|
141
141
|
throw new Error(`${this.#definition.name}: no matching subcommand`);
|
|
@@ -156,6 +156,7 @@ export class Cli {
|
|
|
156
156
|
data,
|
|
157
157
|
args,
|
|
158
158
|
options: parsed.values,
|
|
159
|
+
deps,
|
|
159
160
|
});
|
|
160
161
|
return command.handler(ctx);
|
|
161
162
|
}
|
|
@@ -178,8 +179,18 @@ export class Cli {
|
|
|
178
179
|
}
|
|
179
180
|
}
|
|
180
181
|
|
|
181
|
-
/**
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
182
|
+
/**
|
|
183
|
+
* Create a Cli instance. When `runtime` is provided, error,
|
|
184
|
+
* usage-error, and help output route through `runtime.proc` instead of the
|
|
185
|
+
* global `process`. The zero-arg form keeps reading the global `process` as a
|
|
186
|
+
* deprecated alias for one migration cycle.
|
|
187
|
+
* @param {object} definition - The CLI definition.
|
|
188
|
+
* @param {object} [options]
|
|
189
|
+
* @param {import('@forwardimpact/libutil/runtime').Runtime} [options.runtime]
|
|
190
|
+
* @returns {Cli}
|
|
191
|
+
*/
|
|
192
|
+
export function createCli(definition, { runtime } = {}) {
|
|
193
|
+
const proc = runtime ? runtime.proc : process;
|
|
194
|
+
const helpRenderer = new HelpRenderer({ process: proc });
|
|
195
|
+
return new Cli(definition, { process: proc, helpRenderer });
|
|
185
196
|
}
|
|
@@ -35,14 +35,20 @@
|
|
|
35
35
|
* empty-valued query parameter), or an array of strings (when the same
|
|
36
36
|
* key appears more than once). Absent options are not present in the
|
|
37
37
|
* object — 'foo' in ctx.options is the membership test.
|
|
38
|
+
*
|
|
39
|
+
* @property {Readonly<Object>} deps
|
|
40
|
+
* Host-injected ambient collaborators (the `runtime` bag and typed
|
|
41
|
+
* clients). The handler treats deps as immutable input.
|
|
42
|
+
* Distinct from `data` (host-loaded domain values). Defaults to
|
|
43
|
+
* `undefined` for hosts that do not inject collaborators.
|
|
38
44
|
*/
|
|
39
45
|
|
|
40
46
|
/**
|
|
41
47
|
* Deep-freeze an invocation context so handlers may assume immutability.
|
|
42
|
-
* @param {{ data: Object, args: Object<string,string>, options: Object<string,string|boolean|string[]
|
|
48
|
+
* @param {{ data: Object, args: Object<string,string>, options: Object<string,string|boolean|string[]>, deps?: Object }} raw
|
|
43
49
|
* @returns {InvocationContext}
|
|
44
50
|
*/
|
|
45
|
-
export function freezeInvocationContext({ data, args, options }) {
|
|
51
|
+
export function freezeInvocationContext({ data, args, options, deps }) {
|
|
46
52
|
for (const v of Object.values(options)) {
|
|
47
53
|
if (Array.isArray(v)) Object.freeze(v);
|
|
48
54
|
}
|
|
@@ -50,5 +56,6 @@ export function freezeInvocationContext({ data, args, options }) {
|
|
|
50
56
|
data,
|
|
51
57
|
args: Object.freeze({ ...args }),
|
|
52
58
|
options: Object.freeze({ ...options }),
|
|
59
|
+
deps: deps === undefined ? undefined : Object.freeze(deps),
|
|
53
60
|
});
|
|
54
61
|
}
|