@alpacakit/channels 0.1.0-beta.37 → 0.1.0-beta.39
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 +204 -723
- package/dist/binding-compiler.d.ts +12 -2
- package/dist/binding-compiler.d.ts.map +1 -1
- package/dist/binding-compiler.js +25 -0
- package/dist/cli-coercion.d.ts +1 -1
- package/dist/cli-coercion.d.ts.map +1 -1
- package/dist/cli-coercion.js +14 -29
- package/dist/cli-compiler.d.ts +4 -17
- package/dist/cli-compiler.d.ts.map +1 -1
- package/dist/cli-compiler.js +78 -39
- package/dist/cli-help-projection.d.ts.map +1 -1
- package/dist/cli-help-projection.js +41 -36
- package/dist/cli-model.d.ts +50 -65
- package/dist/cli-model.d.ts.map +1 -1
- package/dist/cli-model.js +26 -34
- package/dist/cli-tree.d.ts +6 -3
- package/dist/cli-tree.d.ts.map +1 -1
- package/dist/cli-tree.js +161 -387
- package/dist/cli.d.ts +1 -5
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -5
- package/dist/codecs.d.ts +20 -18
- package/dist/codecs.d.ts.map +1 -1
- package/dist/codecs.js +21 -31
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +8 -3
- package/dist/definition-error.d.ts +5 -0
- package/dist/definition-error.d.ts.map +1 -0
- package/dist/definition-error.js +8 -0
- package/dist/factory.d.ts +25 -11
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +28 -18
- package/dist/http-compiler.d.ts +15 -0
- package/dist/http-compiler.d.ts.map +1 -0
- package/dist/http-compiler.js +37 -0
- package/dist/http-model.d.ts +42 -0
- package/dist/http-model.d.ts.map +1 -0
- package/dist/http-model.js +20 -0
- package/dist/http-tree.d.ts +7 -0
- package/dist/http-tree.d.ts.map +1 -0
- package/dist/http-tree.js +181 -0
- package/dist/http.d.ts +3 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +2 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/input-compiler.d.ts +13 -0
- package/dist/input-compiler.d.ts.map +1 -0
- package/dist/input-compiler.js +122 -0
- package/dist/introspection.d.ts +1 -1
- package/dist/introspection.d.ts.map +1 -1
- package/dist/introspection.js +30 -16
- package/dist/mcp.d.ts +25 -24
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +87 -65
- package/dist/model.d.ts +44 -42
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +44 -9
- package/dist/owned.d.ts +12 -0
- package/dist/owned.d.ts.map +1 -0
- package/dist/owned.js +61 -0
- package/dist/registration.d.ts +41 -0
- package/dist/registration.d.ts.map +1 -0
- package/dist/registration.js +14 -0
- package/dist/runtime.d.ts +2 -35
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +2 -127
- package/dist/schema.d.ts +11 -8
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +110 -47
- package/dist/string-coercion.d.ts +4 -0
- package/dist/string-coercion.d.ts.map +1 -0
- package/dist/string-coercion.js +24 -0
- package/dist/tree-internal.d.ts +4 -2
- package/dist/tree-internal.d.ts.map +1 -1
- package/dist/tree-internal.js +5 -2
- package/dist/values.d.ts +1 -6
- package/dist/values.d.ts.map +1 -1
- package/dist/values.js +1 -6
- package/examples/README.md +28 -0
- package/examples/book-search.ts +151 -0
- package/examples/greeting.ts +193 -0
- package/package.json +9 -4
- package/dist/cli-application.d.ts +0 -40
- package/dist/cli-application.d.ts.map +0 -1
- package/dist/cli-application.js +0 -90
- package/dist/cli-executor.d.ts +0 -25
- package/dist/cli-executor.d.ts.map +0 -1
- package/dist/cli-executor.js +0 -44
- package/dist/cli-presentation.d.ts +0 -38
- package/dist/cli-presentation.d.ts.map +0 -1
- package/dist/cli-presentation.js +0 -301
- package/dist/cli-result-envelope.d.ts +0 -104
- package/dist/cli-result-envelope.d.ts.map +0 -1
- package/dist/cli-result-envelope.js +0 -137
- package/dist/cli-schema.d.ts +0 -4
- package/dist/cli-schema.d.ts.map +0 -1
- package/dist/cli-schema.js +0 -7
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { ErasedEntryDefinition, ErasedParameterDefinition } from "./model.js";
|
|
2
2
|
export declare const PARAMETER_BINDING_ISSUE_KIND: {
|
|
3
3
|
readonly duplicate: "duplicate";
|
|
4
|
+
readonly duplicateExclusion: "duplicate_exclusion";
|
|
5
|
+
readonly nonexistentExclusion: "nonexistent_exclusion";
|
|
4
6
|
readonly nonexistent: "nonexistent";
|
|
5
7
|
readonly requiredUnreachable: "required_unreachable";
|
|
6
8
|
};
|
|
7
|
-
|
|
9
|
+
type ParameterBindingRow = {
|
|
8
10
|
readonly parameterName: string;
|
|
9
11
|
};
|
|
10
12
|
export type CompiledParameterBinding<Row extends ParameterBindingRow = ParameterBindingRow> = {
|
|
@@ -12,6 +14,12 @@ export type CompiledParameterBinding<Row extends ParameterBindingRow = Parameter
|
|
|
12
14
|
readonly parameter: ErasedParameterDefinition;
|
|
13
15
|
};
|
|
14
16
|
export type ParameterBindingIssue = {
|
|
17
|
+
readonly kind: typeof PARAMETER_BINDING_ISSUE_KIND.duplicateExclusion;
|
|
18
|
+
readonly parameterName: string;
|
|
19
|
+
} | {
|
|
20
|
+
readonly kind: typeof PARAMETER_BINDING_ISSUE_KIND.nonexistentExclusion;
|
|
21
|
+
readonly parameterName: string;
|
|
22
|
+
} | {
|
|
15
23
|
readonly kind: typeof PARAMETER_BINDING_ISSUE_KIND.duplicate;
|
|
16
24
|
readonly parameterName: string;
|
|
17
25
|
} | {
|
|
@@ -21,9 +29,11 @@ export type ParameterBindingIssue = {
|
|
|
21
29
|
readonly kind: typeof PARAMETER_BINDING_ISSUE_KIND.requiredUnreachable;
|
|
22
30
|
readonly parameterName: string;
|
|
23
31
|
};
|
|
24
|
-
|
|
32
|
+
type ParameterBindingCompilation<Row extends ParameterBindingRow> = {
|
|
25
33
|
readonly bindings: readonly CompiledParameterBinding<Row>[];
|
|
26
34
|
readonly issues: readonly ParameterBindingIssue[];
|
|
27
35
|
};
|
|
28
36
|
export declare function compileParameterBindings<Row extends ParameterBindingRow>(entry: ErasedEntryDefinition, rows: readonly Row[]): ParameterBindingCompilation<Row>;
|
|
37
|
+
export declare function compileParameterExclusions(entry: ErasedEntryDefinition, exclusions: readonly string[]): ParameterBindingCompilation<ParameterBindingRow>;
|
|
38
|
+
export {};
|
|
29
39
|
//# sourceMappingURL=binding-compiler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binding-compiler.d.ts","sourceRoot":"","sources":["../src/binding-compiler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,yBAAyB,EAC1B,MAAM,YAAY,CAAC;AAGpB,eAAO,MAAM,4BAA4B
|
|
1
|
+
{"version":3,"file":"binding-compiler.d.ts","sourceRoot":"","sources":["../src/binding-compiler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,yBAAyB,EAC1B,MAAM,YAAY,CAAC;AAGpB,eAAO,MAAM,4BAA4B;;;;;;CAM/B,CAAC;AAEX,KAAK,mBAAmB,GAAG;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,wBAAwB,CAClC,GAAG,SAAS,mBAAmB,GAAG,mBAAmB,IACnD;IACF,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAClB,QAAQ,CAAC,SAAS,EAAE,yBAAyB,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,4BAA4B,CAAC,kBAAkB,CAAC;IACtE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,4BAA4B,CAAC,oBAAoB,CAAC;IACxE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,4BAA4B,CAAC,SAAS,CAAC;IAC7D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,4BAA4B,CAAC,WAAW,CAAC;IAC/D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,4BAA4B,CAAC,mBAAmB,CAAC;IACvE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC,CAAC;AAEN,KAAK,2BAA2B,CAAC,GAAG,SAAS,mBAAmB,IAAI;IAClE,QAAQ,CAAC,QAAQ,EAAE,SAAS,wBAAwB,CAAC,GAAG,CAAC,EAAE,CAAC;IAC5D,QAAQ,CAAC,MAAM,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACnD,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,GAAG,SAAS,mBAAmB,EACtE,KAAK,EAAE,qBAAqB,EAC5B,IAAI,EAAE,SAAS,GAAG,EAAE,GACnB,2BAA2B,CAAC,GAAG,CAAC,CAkClC;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,qBAAqB,EAC5B,UAAU,EAAE,SAAS,MAAM,EAAE,GAC5B,2BAA2B,CAAC,mBAAmB,CAAC,CAyBlD"}
|
package/dist/binding-compiler.js
CHANGED
|
@@ -2,6 +2,8 @@ import { findParameter } from "./internal.js";
|
|
|
2
2
|
import { PARAMETER_REQUIREMENT_KIND } from "./values.js";
|
|
3
3
|
export const PARAMETER_BINDING_ISSUE_KIND = {
|
|
4
4
|
duplicate: "duplicate",
|
|
5
|
+
duplicateExclusion: "duplicate_exclusion",
|
|
6
|
+
nonexistentExclusion: "nonexistent_exclusion",
|
|
5
7
|
nonexistent: "nonexistent",
|
|
6
8
|
requiredUnreachable: "required_unreachable",
|
|
7
9
|
};
|
|
@@ -38,3 +40,26 @@ export function compileParameterBindings(entry, rows) {
|
|
|
38
40
|
}
|
|
39
41
|
return { bindings, issues };
|
|
40
42
|
}
|
|
43
|
+
export function compileParameterExclusions(entry, exclusions) {
|
|
44
|
+
const excluded = new Set();
|
|
45
|
+
const issues = [];
|
|
46
|
+
for (const parameterName of exclusions) {
|
|
47
|
+
if (excluded.has(parameterName)) {
|
|
48
|
+
issues.push({
|
|
49
|
+
kind: PARAMETER_BINDING_ISSUE_KIND.duplicateExclusion,
|
|
50
|
+
parameterName,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
excluded.add(parameterName);
|
|
54
|
+
if (findParameter(entry.parameters, parameterName) === null) {
|
|
55
|
+
issues.push({
|
|
56
|
+
kind: PARAMETER_BINDING_ISSUE_KIND.nonexistentExclusion,
|
|
57
|
+
parameterName,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const exposed = compileParameterBindings(entry, entry.parameters
|
|
62
|
+
.filter((parameter) => !excluded.has(parameter.name))
|
|
63
|
+
.map((parameter) => ({ parameterName: parameter.name })));
|
|
64
|
+
return { bindings: exposed.bindings, issues: [...issues, ...exposed.issues] };
|
|
65
|
+
}
|
package/dist/cli-coercion.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { JsonValue } from "@alpacakit/core";
|
|
2
2
|
import { type CliValueCoercion } from "./cli-model.js";
|
|
3
3
|
import type { ValueShape } from "./model.js";
|
|
4
|
-
export declare function coerceCliArgvValue(shape: ValueShape, rawValue: unknown, coercion: CliValueCoercion | null): JsonValue | undefined;
|
|
4
|
+
export declare function coerceCliArgvValue(parameterName: string, shape: ValueShape, rawValue: unknown, coercion: CliValueCoercion | null): JsonValue | undefined;
|
|
5
5
|
//# sourceMappingURL=cli-coercion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-coercion.d.ts","sourceRoot":"","sources":["../src/cli-coercion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cli-coercion.d.ts","sourceRoot":"","sources":["../src/cli-coercion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAK7C,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,GAChC,SAAS,GAAG,SAAS,CAKvB"}
|
package/dist/cli-coercion.js
CHANGED
|
@@ -1,38 +1,20 @@
|
|
|
1
1
|
import { CLI_VALUE_COERCION } from "./cli-model.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { EntryInputError } from "./runtime.js";
|
|
3
|
+
import { coerceStringValue } from "./string-coercion.js";
|
|
4
|
+
import { ENTRY_INPUT_TARGET_KIND } from "./values.js";
|
|
5
|
+
export function coerceCliArgvValue(parameterName, shape, rawValue, coercion) {
|
|
4
6
|
if (coercion !== null) {
|
|
5
|
-
return coerceExplicitCliValue(rawValue, coercion);
|
|
7
|
+
return coerceExplicitCliValue(parameterName, rawValue, coercion);
|
|
6
8
|
}
|
|
7
|
-
|
|
8
|
-
const values = Array.isArray(rawValue) ? rawValue : [rawValue];
|
|
9
|
-
return values.map((value) => coerceCliArgvScalarValue(shape.element, value));
|
|
10
|
-
}
|
|
11
|
-
return coerceCliArgvScalarValue(shape, rawValue);
|
|
12
|
-
}
|
|
13
|
-
function coerceCliArgvScalarValue(shape, value) {
|
|
14
|
-
if (shape.kind === VALUE_SHAPE_KIND.boolean) {
|
|
15
|
-
if (value === "true") {
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
if (value === "false") {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
if (shape.kind === VALUE_SHAPE_KIND.positiveInteger &&
|
|
23
|
-
typeof value === "string" &&
|
|
24
|
-
/^[+-]?\d+$/.test(value)) {
|
|
25
|
-
return Number(value);
|
|
26
|
-
}
|
|
27
|
-
return value;
|
|
9
|
+
return coerceStringValue(shape, rawValue);
|
|
28
10
|
}
|
|
29
|
-
function coerceExplicitCliValue(rawValue, coercion) {
|
|
11
|
+
function coerceExplicitCliValue(parameterName, rawValue, coercion) {
|
|
30
12
|
if (Array.isArray(rawValue)) {
|
|
31
|
-
return rawValue.map((value) => coerceExplicitCliScalar(value, coercion));
|
|
13
|
+
return rawValue.map((value) => coerceExplicitCliScalar(parameterName, value, coercion));
|
|
32
14
|
}
|
|
33
|
-
return coerceExplicitCliScalar(rawValue, coercion);
|
|
15
|
+
return coerceExplicitCliScalar(parameterName, rawValue, coercion);
|
|
34
16
|
}
|
|
35
|
-
function coerceExplicitCliScalar(value, coercion) {
|
|
17
|
+
function coerceExplicitCliScalar(parameterName, value, coercion) {
|
|
36
18
|
if (typeof value !== "string") {
|
|
37
19
|
return value;
|
|
38
20
|
}
|
|
@@ -43,7 +25,10 @@ function coerceExplicitCliScalar(value, coercion) {
|
|
|
43
25
|
if (coercion === CLI_VALUE_COERCION.jsonOrString) {
|
|
44
26
|
return value;
|
|
45
27
|
}
|
|
46
|
-
throw new
|
|
28
|
+
throw new EntryInputError([`Invalid JSON value: ${errorMessage(error)}`], {
|
|
29
|
+
kind: ENTRY_INPUT_TARGET_KIND.parameter,
|
|
30
|
+
parameterName,
|
|
31
|
+
});
|
|
47
32
|
}
|
|
48
33
|
}
|
|
49
34
|
function errorMessage(error) {
|
package/dist/cli-compiler.d.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type CompiledParameterBinding } from "./binding-compiler.js";
|
|
2
|
+
import { type CliArgBinding, type CliEntryBinding, type CliLongOptionFlag, type CliOptionFlag, type CliOptionValueMode, type CliParameterView, type CliValueCoercion } from "./cli-model.js";
|
|
2
3
|
import { CLI_OPTION_KIND, CLI_POSITIONAL_PLAN_KIND } from "./cli-values.js";
|
|
3
4
|
import type { EntryTreeEndpoint, ErasedParameterDefinition } from "./model.js";
|
|
4
|
-
export declare const CLI_OPTION_ACTION_KIND: {
|
|
5
|
-
readonly setBoolean: "set_boolean";
|
|
6
|
-
readonly readValue: "read_value";
|
|
7
|
-
};
|
|
8
5
|
type CompiledCliOptionBase = {
|
|
9
6
|
readonly parameter: ErasedParameterDefinition;
|
|
10
7
|
readonly flags: readonly CliOptionFlag[];
|
|
@@ -24,24 +21,14 @@ export type CompiledCliPositional = {
|
|
|
24
21
|
readonly valueName: string;
|
|
25
22
|
readonly coercion: CliValueCoercion | null;
|
|
26
23
|
};
|
|
27
|
-
export type CliOptionAction = {
|
|
28
|
-
readonly kind: typeof CLI_OPTION_ACTION_KIND.setBoolean;
|
|
29
|
-
readonly parameterName: string;
|
|
30
|
-
readonly value: boolean;
|
|
31
|
-
} | {
|
|
32
|
-
readonly kind: typeof CLI_OPTION_ACTION_KIND.readValue;
|
|
33
|
-
readonly option: Extract<CompiledCliOption, {
|
|
34
|
-
readonly kind: typeof CLI_OPTION_KIND.value;
|
|
35
|
-
}>;
|
|
36
|
-
};
|
|
37
24
|
export type CompiledCliEndpoint = {
|
|
38
25
|
readonly endpoint: EntryTreeEndpoint;
|
|
39
26
|
readonly binding: CliEntryBinding;
|
|
40
|
-
readonly
|
|
27
|
+
readonly parameterBindings: readonly CompiledParameterBinding<CliArgBinding>[];
|
|
41
28
|
readonly options: readonly CompiledCliOption[];
|
|
42
29
|
readonly positionals: readonly CompiledCliPositional[];
|
|
43
|
-
readonly optionByToken: ReadonlyMap<string, CliOptionAction>;
|
|
44
30
|
};
|
|
45
31
|
export declare function compileCliBinding(endpoint: EntryTreeEndpoint, binding: CliEntryBinding, location: string, issues: string[]): CompiledCliEndpoint;
|
|
32
|
+
export declare function projectCliParameters(endpoint: CompiledCliEndpoint): readonly CliParameterView[];
|
|
46
33
|
export {};
|
|
47
34
|
//# sourceMappingURL=cli-compiler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-compiler.d.ts","sourceRoot":"","sources":["../src/cli-compiler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli-compiler.d.ts","sourceRoot":"","sources":["../src/cli-compiler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,wBAAwB,EAI9B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEL,eAAe,EAEf,wBAAwB,EACzB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAY/E,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,CAAC,SAAS,EAAE,yBAAyB,CAAC;IAC9C,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,iBAAiB,GACzB,CAAC,qBAAqB,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,eAAe,CAAC,WAAW,CAAC;IAClD,QAAQ,CAAC,aAAa,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACtD,CAAC,GACF,CAAC,qBAAqB,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,eAAe,CAAC,KAAK,CAAC;IAC5C,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,CAAC,CAAC;AAEP,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,IAAI,EACT,OAAO,wBAAwB,CAAC,MAAM,GACtC,OAAO,wBAAwB,CAAC,IAAI,CAAC;IACzC,QAAQ,CAAC,SAAS,EAAE,yBAAyB,CAAC;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,iBAAiB,EAAE,SAAS,wBAAwB,CAAC,aAAa,CAAC,EAAE,CAAC;IAC/E,QAAQ,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC/C,QAAQ,CAAC,WAAW,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACxD,CAAC;AAEF,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EAAE,GACf,mBAAmB,CAiDrB;AAsBD,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,mBAAmB,GAC5B,SAAS,gBAAgB,EAAE,CAmC7B"}
|
package/dist/cli-compiler.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { compileParameterBindings, PARAMETER_BINDING_ISSUE_KIND, } from "./binding-compiler.js";
|
|
2
2
|
import { CLI_ARG_KIND, } from "./cli-model.js";
|
|
3
3
|
import { CLI_BOOLEAN_MODE, CLI_OPTION_KIND, CLI_OPTION_VALUE_MODE, CLI_POSITIONAL_PLAN_KIND, } from "./cli-values.js";
|
|
4
|
+
import { describeParameterRequirement } from "./introspection.js";
|
|
5
|
+
import { ownedArray, ownedRecord } from "./owned.js";
|
|
4
6
|
import { PARAMETER_REQUIREMENT_KIND, VALUE_SHAPE_KIND } from "./values.js";
|
|
5
|
-
export const CLI_OPTION_ACTION_KIND = {
|
|
6
|
-
setBoolean: "set_boolean",
|
|
7
|
-
readValue: "read_value",
|
|
8
|
-
};
|
|
9
7
|
const CLI_COMPILER_SYNTAX = {
|
|
10
8
|
assignmentSeparator: "=",
|
|
11
9
|
invalidLongOptionPrefix: "---",
|
|
@@ -32,15 +30,85 @@ export function compileCliBinding(endpoint, binding, location, issues) {
|
|
|
32
30
|
issues.push(`${location}: variadic positional ${positional.parameter.name} must be last`);
|
|
33
31
|
}
|
|
34
32
|
}
|
|
33
|
+
validateUniqueOptionFlags(options, location, issues);
|
|
35
34
|
return {
|
|
36
35
|
endpoint,
|
|
37
36
|
binding,
|
|
38
|
-
|
|
37
|
+
parameterBindings: compiledParameters.bindings,
|
|
39
38
|
options,
|
|
40
39
|
positionals,
|
|
41
|
-
optionByToken: createCliOptionActionIndex(options, location, issues),
|
|
42
40
|
};
|
|
43
41
|
}
|
|
42
|
+
function validateUniqueOptionFlags(options, location, issues) {
|
|
43
|
+
const flags = new Set();
|
|
44
|
+
for (const option of options) {
|
|
45
|
+
const optionFlags = option.kind === CLI_OPTION_KIND.booleanFlag
|
|
46
|
+
? [...option.flags, ...option.negativeFlags]
|
|
47
|
+
: option.flags;
|
|
48
|
+
for (const flag of optionFlags) {
|
|
49
|
+
if (flags.has(flag)) {
|
|
50
|
+
issues.push(`${location}: duplicate CLI option flag ${flag}`);
|
|
51
|
+
}
|
|
52
|
+
flags.add(flag);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function projectCliParameters(endpoint) {
|
|
57
|
+
const options = new Map(endpoint.options.map((option) => [option.parameter.name, option]));
|
|
58
|
+
const positionals = new Map(endpoint.positionals.map((positional) => [
|
|
59
|
+
positional.parameter.name,
|
|
60
|
+
positional,
|
|
61
|
+
]));
|
|
62
|
+
return ownedArray(endpoint.binding.parameters.flatMap((row) => {
|
|
63
|
+
if (row.kind === CLI_ARG_KIND.option) {
|
|
64
|
+
const option = options.get(row.parameterName);
|
|
65
|
+
return option === undefined ? [] : [projectCliOption(option)];
|
|
66
|
+
}
|
|
67
|
+
const positional = positionals.get(row.parameterName);
|
|
68
|
+
return positional === undefined
|
|
69
|
+
? []
|
|
70
|
+
: [
|
|
71
|
+
ownedRecord({
|
|
72
|
+
kind: CLI_ARG_KIND.positional,
|
|
73
|
+
parameterName: positional.parameter.name,
|
|
74
|
+
description: positional.parameter.description,
|
|
75
|
+
requirement: describeParameterRequirement(positional.parameter.requirement),
|
|
76
|
+
shape: positional.parameter.codec.shape,
|
|
77
|
+
coercion: positional.coercion,
|
|
78
|
+
valueName: positional.valueName,
|
|
79
|
+
variadic: positional.kind === CLI_POSITIONAL_PLAN_KIND.rest,
|
|
80
|
+
}),
|
|
81
|
+
];
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
function projectCliOption(option) {
|
|
85
|
+
const base = {
|
|
86
|
+
parameterName: option.parameter.name,
|
|
87
|
+
description: option.parameter.description,
|
|
88
|
+
requirement: describeParameterRequirement(option.parameter.requirement),
|
|
89
|
+
shape: option.parameter.codec.shape,
|
|
90
|
+
coercion: option.coercion,
|
|
91
|
+
};
|
|
92
|
+
return option.kind === CLI_OPTION_KIND.booleanFlag
|
|
93
|
+
? ownedRecord({
|
|
94
|
+
...base,
|
|
95
|
+
kind: CLI_ARG_KIND.option,
|
|
96
|
+
optionKind: option.kind,
|
|
97
|
+
flags: option.flags,
|
|
98
|
+
negativeFlags: option.negativeFlags,
|
|
99
|
+
valueName: null,
|
|
100
|
+
valueMode: null,
|
|
101
|
+
})
|
|
102
|
+
: ownedRecord({
|
|
103
|
+
...base,
|
|
104
|
+
kind: CLI_ARG_KIND.option,
|
|
105
|
+
optionKind: option.kind,
|
|
106
|
+
flags: option.flags,
|
|
107
|
+
negativeFlags: ownedArray([]),
|
|
108
|
+
valueName: option.valueName,
|
|
109
|
+
valueMode: option.valueMode,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
44
112
|
function compileCliOption(compiled, location, issues) {
|
|
45
113
|
const { row, parameter } = compiled;
|
|
46
114
|
const flags = row.flags;
|
|
@@ -169,43 +237,14 @@ function compileCliPositional(compiled, location, issues) {
|
|
|
169
237
|
coercion: row.coercion,
|
|
170
238
|
};
|
|
171
239
|
}
|
|
172
|
-
function createCliOptionActionIndex(options, location, issues) {
|
|
173
|
-
const actions = new Map();
|
|
174
|
-
for (const option of options) {
|
|
175
|
-
if (option.kind === CLI_OPTION_KIND.booleanFlag) {
|
|
176
|
-
for (const token of option.flags) {
|
|
177
|
-
registerCliOptionAction(actions, token, {
|
|
178
|
-
kind: CLI_OPTION_ACTION_KIND.setBoolean,
|
|
179
|
-
parameterName: option.parameter.name,
|
|
180
|
-
value: true,
|
|
181
|
-
}, location, issues);
|
|
182
|
-
}
|
|
183
|
-
for (const token of option.negativeFlags) {
|
|
184
|
-
registerCliOptionAction(actions, token, {
|
|
185
|
-
kind: CLI_OPTION_ACTION_KIND.setBoolean,
|
|
186
|
-
parameterName: option.parameter.name,
|
|
187
|
-
value: false,
|
|
188
|
-
}, location, issues);
|
|
189
|
-
}
|
|
190
|
-
continue;
|
|
191
|
-
}
|
|
192
|
-
for (const token of option.flags) {
|
|
193
|
-
registerCliOptionAction(actions, token, { kind: CLI_OPTION_ACTION_KIND.readValue, option }, location, issues);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return actions;
|
|
197
|
-
}
|
|
198
|
-
function registerCliOptionAction(actions, token, action, location, issues) {
|
|
199
|
-
if (actions.has(token)) {
|
|
200
|
-
issues.push(`${location}: duplicate CLI option flag ${token}`);
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
actions.set(token, action);
|
|
204
|
-
}
|
|
205
240
|
function formatCliParameterBindingIssue(location, issue) {
|
|
206
241
|
switch (issue.kind) {
|
|
207
242
|
case PARAMETER_BINDING_ISSUE_KIND.duplicate:
|
|
208
243
|
return `${location}: duplicate binding for parameter ${issue.parameterName}`;
|
|
244
|
+
case PARAMETER_BINDING_ISSUE_KIND.duplicateExclusion:
|
|
245
|
+
return `${location}: duplicate exclusion for parameter ${issue.parameterName}`;
|
|
246
|
+
case PARAMETER_BINDING_ISSUE_KIND.nonexistentExclusion:
|
|
247
|
+
return `${location}: exclusion names nonexistent parameter ${issue.parameterName}`;
|
|
209
248
|
case PARAMETER_BINDING_ISSUE_KIND.nonexistent:
|
|
210
249
|
return `${location}: binding names nonexistent parameter ${issue.parameterName}`;
|
|
211
250
|
case PARAMETER_BINDING_ISSUE_KIND.requiredUnreachable:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-help-projection.d.ts","sourceRoot":"","sources":["../src/cli-help-projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EAGpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,cAAc,EAKd,cAAc,EAGd,UAAU,EACX,MAAM,gBAAgB,CAAC;AAOxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cli-help-projection.d.ts","sourceRoot":"","sources":["../src/cli-help-projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EAGpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,cAAc,EAKd,cAAc,EAGd,UAAU,EACX,MAAM,gBAAgB,CAAC;AAOxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA6ChD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC9C,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB,GAAG,cAAc,CAsBjB;AAwCD,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,mBAAmB,EAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EAAE,GACf,IAAI,CA4BN;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EAAE,GACf,IAAI,CAaN"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CLI_HELP_USAGE_KIND, CLI_OPTION_KIND, CLI_POSITIONAL_PLAN_KIND, } from "./cli-values.js";
|
|
2
2
|
import { describeParameterRequirement } from "./introspection.js";
|
|
3
|
+
import { ownedArray, ownedRecord } from "./owned.js";
|
|
3
4
|
import { PARAMETER_REQUIREMENT_KIND } from "./values.js";
|
|
4
5
|
const CLI_HELP_USAGE_SYNTAX = {
|
|
5
6
|
commandArgument: "<command>",
|
|
@@ -18,51 +19,55 @@ const CLI_HELP_VALIDATION_ISSUE = {
|
|
|
18
19
|
emptyExampleTitle: "CLI help example title must not be empty",
|
|
19
20
|
nonOptionSectionParameter: (location, heading, parameterName) => `${location}: help option section ${JSON.stringify(heading)} names non-option parameter ${parameterName}`,
|
|
20
21
|
};
|
|
21
|
-
const GROUP_HELP_PROJECTION = {
|
|
22
|
-
examples: [],
|
|
23
|
-
options: [],
|
|
24
|
-
optionSections: [],
|
|
25
|
-
positionals: [],
|
|
26
|
-
usage: { kind: CLI_HELP_USAGE_KIND.derived },
|
|
27
|
-
};
|
|
22
|
+
const GROUP_HELP_PROJECTION = ownedRecord({
|
|
23
|
+
examples: ownedArray([]),
|
|
24
|
+
options: ownedArray([]),
|
|
25
|
+
optionSections: ownedArray([]),
|
|
26
|
+
positionals: ownedArray([]),
|
|
27
|
+
usage: ownedRecord({ kind: CLI_HELP_USAGE_KIND.derived }),
|
|
28
|
+
});
|
|
28
29
|
export function createCliHelpSurface(input) {
|
|
29
30
|
const endpoint = projectCliEndpointHelp(input.endpoint);
|
|
30
31
|
const hasChildren = input.childHelp.length > 0;
|
|
31
|
-
return {
|
|
32
|
+
return ownedRecord({
|
|
32
33
|
name: input.node.name,
|
|
33
34
|
token: input.root ? null : input.segment.token,
|
|
34
35
|
description: input.node.description,
|
|
35
|
-
remarks: input.node.documentation.remarks,
|
|
36
|
-
relatedDocs: input.node.documentation.relatedDocs,
|
|
36
|
+
remarks: ownedArray(input.node.documentation.remarks),
|
|
37
|
+
relatedDocs: ownedArray(input.node.documentation.relatedDocs),
|
|
37
38
|
optionGroups: projectCliHelpOptionGroups(endpoint.options, endpoint.optionSections),
|
|
38
|
-
positionals: endpoint.positionals,
|
|
39
|
+
positionals: ownedArray(endpoint.positionals),
|
|
39
40
|
usages: resolveCliUsages(endpoint, hasChildren),
|
|
40
|
-
examples: [
|
|
41
|
+
examples: ownedArray([
|
|
42
|
+
...input.segment.help.examples,
|
|
43
|
+
...endpoint.examples,
|
|
44
|
+
]),
|
|
41
45
|
subcommandHint: input.segment.help.subcommandHint,
|
|
42
|
-
children: input.childHelp,
|
|
43
|
-
};
|
|
46
|
+
children: ownedArray(input.childHelp),
|
|
47
|
+
});
|
|
44
48
|
}
|
|
45
49
|
function projectCliHelpOptionGroups(options, sections) {
|
|
46
50
|
const optionByParameterName = new Map(options.map((option) => [option.parameterName, option]));
|
|
47
51
|
const sectionedParameterNames = new Set(sections.flatMap((section) => section.parameterNames));
|
|
48
|
-
const groups = sections.map((section) => ({
|
|
52
|
+
const groups = sections.map((section) => ownedRecord({
|
|
49
53
|
heading: section.heading,
|
|
50
54
|
description: section.description,
|
|
51
55
|
// Section references are validated before the completed router is exposed.
|
|
52
|
-
options: section.parameterNames.map((parameterName) => optionByParameterName.get(parameterName)),
|
|
56
|
+
options: ownedArray(section.parameterNames.map((parameterName) => optionByParameterName.get(parameterName))),
|
|
53
57
|
}));
|
|
54
58
|
const unsectionedOptions = options.filter((option) => !sectionedParameterNames.has(option.parameterName));
|
|
55
59
|
if (unsectionedOptions.length > 0) {
|
|
56
|
-
groups.push({
|
|
60
|
+
groups.push(ownedRecord({
|
|
57
61
|
heading: null,
|
|
58
62
|
description: null,
|
|
59
|
-
options: unsectionedOptions,
|
|
60
|
-
});
|
|
63
|
+
options: ownedArray(unsectionedOptions),
|
|
64
|
+
}));
|
|
61
65
|
}
|
|
62
|
-
return groups;
|
|
66
|
+
return ownedArray(groups);
|
|
63
67
|
}
|
|
64
68
|
export function validateCliCommandHelp(endpoint, location, issues) {
|
|
65
|
-
const { help
|
|
69
|
+
const { help } = endpoint.binding;
|
|
70
|
+
const { options } = endpoint;
|
|
66
71
|
validateCliHelpExamples(help.examples, location, issues);
|
|
67
72
|
const optionNames = new Set(options.map((option) => option.parameter.name));
|
|
68
73
|
const sectionedNames = new Set();
|
|
@@ -92,20 +97,20 @@ function projectCliEndpointHelp(endpoint) {
|
|
|
92
97
|
if (endpoint === null) {
|
|
93
98
|
return GROUP_HELP_PROJECTION;
|
|
94
99
|
}
|
|
95
|
-
return {
|
|
96
|
-
examples: endpoint.help.examples,
|
|
97
|
-
options: endpoint.options.map(cliHelpOptionFor),
|
|
98
|
-
optionSections: endpoint.help.optionSections,
|
|
99
|
-
positionals: endpoint.positionals.map(cliHelpPositionalFor),
|
|
100
|
-
usage: endpoint.help.usage,
|
|
101
|
-
};
|
|
100
|
+
return ownedRecord({
|
|
101
|
+
examples: endpoint.binding.help.examples,
|
|
102
|
+
options: ownedArray(endpoint.options.map(cliHelpOptionFor)),
|
|
103
|
+
optionSections: endpoint.binding.help.optionSections,
|
|
104
|
+
positionals: ownedArray(endpoint.positionals.map(cliHelpPositionalFor)),
|
|
105
|
+
usage: endpoint.binding.help.usage,
|
|
106
|
+
});
|
|
102
107
|
}
|
|
103
108
|
function resolveCliUsages(endpoint, hasChildren) {
|
|
104
109
|
switch (endpoint.usage.kind) {
|
|
105
110
|
case CLI_HELP_USAGE_KIND.authored:
|
|
106
111
|
return endpoint.usage.values;
|
|
107
112
|
case CLI_HELP_USAGE_KIND.derived:
|
|
108
|
-
return [deriveCliUsage(endpoint, hasChildren)];
|
|
113
|
+
return ownedArray([deriveCliUsage(endpoint, hasChildren)]);
|
|
109
114
|
}
|
|
110
115
|
}
|
|
111
116
|
function deriveCliUsage(endpoint, hasChildren) {
|
|
@@ -135,24 +140,24 @@ function cliHelpOptionFor(option) {
|
|
|
135
140
|
requirement: describeParameterRequirement(option.parameter.requirement),
|
|
136
141
|
};
|
|
137
142
|
return option.kind === CLI_OPTION_KIND.booleanFlag
|
|
138
|
-
? {
|
|
143
|
+
? ownedRecord({
|
|
139
144
|
...base,
|
|
140
145
|
kind: CLI_OPTION_KIND.booleanFlag,
|
|
141
|
-
negativeFlags: option.negativeFlags,
|
|
142
|
-
}
|
|
143
|
-
: {
|
|
146
|
+
negativeFlags: ownedArray(option.negativeFlags),
|
|
147
|
+
})
|
|
148
|
+
: ownedRecord({
|
|
144
149
|
...base,
|
|
145
150
|
kind: CLI_OPTION_KIND.value,
|
|
146
151
|
valueName: option.valueName,
|
|
147
152
|
valueMode: option.valueMode,
|
|
148
|
-
};
|
|
153
|
+
});
|
|
149
154
|
}
|
|
150
155
|
function cliHelpPositionalFor(positional) {
|
|
151
|
-
return {
|
|
156
|
+
return ownedRecord({
|
|
152
157
|
parameterName: positional.parameter.name,
|
|
153
158
|
valueName: positional.valueName,
|
|
154
159
|
description: positional.parameter.description,
|
|
155
160
|
requirement: describeParameterRequirement(positional.parameter.requirement),
|
|
156
161
|
variadic: positional.kind === CLI_POSITIONAL_PLAN_KIND.rest,
|
|
157
|
-
};
|
|
162
|
+
});
|
|
158
163
|
}
|