@alpacakit/channels 0.1.0-beta.37 → 0.2.0-beta.2

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.
Files changed (99) hide show
  1. package/README.md +204 -723
  2. package/dist/binding-compiler.d.ts +12 -2
  3. package/dist/binding-compiler.d.ts.map +1 -1
  4. package/dist/binding-compiler.js +25 -0
  5. package/dist/cli-coercion.d.ts +1 -1
  6. package/dist/cli-coercion.d.ts.map +1 -1
  7. package/dist/cli-coercion.js +14 -29
  8. package/dist/cli-compiler.d.ts +4 -17
  9. package/dist/cli-compiler.d.ts.map +1 -1
  10. package/dist/cli-compiler.js +78 -39
  11. package/dist/cli-help-projection.d.ts.map +1 -1
  12. package/dist/cli-help-projection.js +41 -36
  13. package/dist/cli-model.d.ts +50 -65
  14. package/dist/cli-model.d.ts.map +1 -1
  15. package/dist/cli-model.js +26 -34
  16. package/dist/cli-tree.d.ts +6 -3
  17. package/dist/cli-tree.d.ts.map +1 -1
  18. package/dist/cli-tree.js +161 -387
  19. package/dist/cli.d.ts +1 -5
  20. package/dist/cli.d.ts.map +1 -1
  21. package/dist/cli.js +1 -5
  22. package/dist/codecs.d.ts +20 -18
  23. package/dist/codecs.d.ts.map +1 -1
  24. package/dist/codecs.js +21 -31
  25. package/dist/contract.d.ts.map +1 -1
  26. package/dist/contract.js +8 -3
  27. package/dist/definition-error.d.ts +5 -0
  28. package/dist/definition-error.d.ts.map +1 -0
  29. package/dist/definition-error.js +8 -0
  30. package/dist/factory.d.ts +25 -11
  31. package/dist/factory.d.ts.map +1 -1
  32. package/dist/factory.js +28 -18
  33. package/dist/http-compiler.d.ts +15 -0
  34. package/dist/http-compiler.d.ts.map +1 -0
  35. package/dist/http-compiler.js +37 -0
  36. package/dist/http-model.d.ts +42 -0
  37. package/dist/http-model.d.ts.map +1 -0
  38. package/dist/http-model.js +20 -0
  39. package/dist/http-tree.d.ts +7 -0
  40. package/dist/http-tree.d.ts.map +1 -0
  41. package/dist/http-tree.js +181 -0
  42. package/dist/http.d.ts +3 -0
  43. package/dist/http.d.ts.map +1 -0
  44. package/dist/http.js +2 -0
  45. package/dist/index.d.ts +2 -1
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +1 -1
  48. package/dist/input-compiler.d.ts +13 -0
  49. package/dist/input-compiler.d.ts.map +1 -0
  50. package/dist/input-compiler.js +122 -0
  51. package/dist/introspection.d.ts +1 -1
  52. package/dist/introspection.d.ts.map +1 -1
  53. package/dist/introspection.js +30 -16
  54. package/dist/mcp.d.ts +25 -24
  55. package/dist/mcp.d.ts.map +1 -1
  56. package/dist/mcp.js +87 -65
  57. package/dist/model.d.ts +44 -42
  58. package/dist/model.d.ts.map +1 -1
  59. package/dist/model.js +44 -9
  60. package/dist/owned.d.ts +12 -0
  61. package/dist/owned.d.ts.map +1 -0
  62. package/dist/owned.js +61 -0
  63. package/dist/registration.d.ts +41 -0
  64. package/dist/registration.d.ts.map +1 -0
  65. package/dist/registration.js +14 -0
  66. package/dist/runtime.d.ts +2 -35
  67. package/dist/runtime.d.ts.map +1 -1
  68. package/dist/runtime.js +2 -127
  69. package/dist/schema.d.ts +11 -8
  70. package/dist/schema.d.ts.map +1 -1
  71. package/dist/schema.js +110 -47
  72. package/dist/string-coercion.d.ts +4 -0
  73. package/dist/string-coercion.d.ts.map +1 -0
  74. package/dist/string-coercion.js +24 -0
  75. package/dist/tree-internal.d.ts +4 -2
  76. package/dist/tree-internal.d.ts.map +1 -1
  77. package/dist/tree-internal.js +5 -2
  78. package/dist/values.d.ts +1 -6
  79. package/dist/values.d.ts.map +1 -1
  80. package/dist/values.js +1 -6
  81. package/examples/README.md +28 -0
  82. package/examples/book-search.ts +151 -0
  83. package/examples/greeting.ts +193 -0
  84. package/package.json +9 -4
  85. package/dist/cli-application.d.ts +0 -40
  86. package/dist/cli-application.d.ts.map +0 -1
  87. package/dist/cli-application.js +0 -90
  88. package/dist/cli-executor.d.ts +0 -25
  89. package/dist/cli-executor.d.ts.map +0 -1
  90. package/dist/cli-executor.js +0 -44
  91. package/dist/cli-presentation.d.ts +0 -38
  92. package/dist/cli-presentation.d.ts.map +0 -1
  93. package/dist/cli-presentation.js +0 -301
  94. package/dist/cli-result-envelope.d.ts +0 -104
  95. package/dist/cli-result-envelope.d.ts.map +0 -1
  96. package/dist/cli-result-envelope.js +0 -137
  97. package/dist/cli-schema.d.ts +0 -4
  98. package/dist/cli-schema.d.ts.map +0 -1
  99. 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
- export type ParameterBindingRow = {
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
- export type ParameterBindingCompilation<Row extends ParameterBindingRow> = {
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;;;;CAI/B,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG;IAChC,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,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,MAAM,MAAM,2BAA2B,CAAC,GAAG,SAAS,mBAAmB,IAAI;IACzE,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"}
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"}
@@ -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
+ }
@@ -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;AAG7C,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,GAChC,SAAS,GAAG,SAAS,CAWvB"}
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"}
@@ -1,38 +1,20 @@
1
1
  import { CLI_VALUE_COERCION } from "./cli-model.js";
2
- import { VALUE_SHAPE_KIND } from "./values.js";
3
- export function coerceCliArgvValue(shape, rawValue, coercion) {
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
- if (shape.kind === VALUE_SHAPE_KIND.array) {
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 Error(`Invalid JSON value: ${errorMessage(error)}`);
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) {
@@ -1,10 +1,7 @@
1
- import { type CliEntryBinding, type CliLongOptionFlag, type CliOptionFlag, type CliOptionValueMode, type CliValueCoercion } from "./cli-model.js";
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 help: CliEntryBinding["help"];
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":"AAMA,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEL,eAAe,EAEf,wBAAwB,EACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAG/E,eAAO,MAAM,sBAAsB;;;CAGzB,CAAC;AAUX,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,eAAe,GACvB;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,sBAAsB,CAAC,UAAU,CAAC;IACxD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,sBAAsB,CAAC,SAAS,CAAC;IACvD,QAAQ,CAAC,MAAM,EAAE,OAAO,CACtB,iBAAiB,EACjB;QAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,eAAe,CAAC,KAAK,CAAA;KAAE,CAChD,CAAC;CACH,CAAC;AAEN,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC/C,QAAQ,CAAC,WAAW,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACvD,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC9D,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"}
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"}
@@ -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
- help: binding.help,
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;AA4ChD,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,CAmBjB;AAkCD,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,mBAAmB,EAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EAAE,GACf,IAAI,CA2BN;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EAAE,GACf,IAAI,CAaN"}
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: [...input.segment.help.examples, ...endpoint.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, options } = endpoint;
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
  }