icore 1.0.14 → 1.0.16

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 (50) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/{argv.d.ts → argv/parser.d.ts} +3 -1
  3. package/dist/{argv.js → argv/parser.js} +5 -5
  4. package/dist/{commands.d.ts → command/mechanics.d.ts} +79 -6
  5. package/dist/{commands.js → command/mechanics.js} +60 -15
  6. package/dist/{errors.d.ts → errors/icore-error.d.ts} +2 -0
  7. package/dist/{errors.js → errors/icore-error.js} +2 -0
  8. package/dist/index.d.ts +28 -1
  9. package/dist/index.js +61 -16
  10. package/dist/options/parser.d.ts +43 -0
  11. package/dist/{options.js → options/parser.js} +27 -17
  12. package/dist/{options.d.ts → options/schema.d.ts} +16 -23
  13. package/dist/options/schema.js +23 -0
  14. package/dist/output/facade.d.ts +28 -0
  15. package/dist/output/facade.js +32 -0
  16. package/dist/output/node-writer.d.ts +17 -0
  17. package/dist/output/node-writer.js +25 -0
  18. package/dist/output/text-writer.d.ts +29 -0
  19. package/dist/output/text-writer.js +49 -0
  20. package/dist/presentation/facade.d.ts +39 -0
  21. package/dist/presentation/facade.js +47 -0
  22. package/dist/presentation/format-options.d.ts +31 -0
  23. package/dist/presentation/format-options.js +37 -0
  24. package/dist/presentation/renderers/csv.d.ts +18 -0
  25. package/dist/presentation/renderers/csv.js +35 -0
  26. package/dist/presentation/renderers/json.d.ts +13 -0
  27. package/dist/presentation/renderers/json.js +18 -0
  28. package/dist/presentation/renderers/table.d.ts +14 -0
  29. package/dist/presentation/renderers/table.js +29 -0
  30. package/dist/presentation/result-renderer.d.ts +25 -0
  31. package/dist/presentation/result-renderer.js +184 -0
  32. package/dist/presentation/view.d.ts +58 -0
  33. package/dist/presentation/view.js +56 -0
  34. package/dist/terminal/app.d.ts +51 -0
  35. package/dist/terminal/app.js +100 -0
  36. package/examples/cli-argument-syntax.md +218 -0
  37. package/examples/command-resolution.md +174 -0
  38. package/examples/custom-command-flow.md +109 -0
  39. package/examples/option-schemas.md +206 -0
  40. package/examples/output-writers.md +128 -0
  41. package/examples/practical-cli-patterns.md +385 -0
  42. package/examples/presentation-output.md +66 -0
  43. package/examples/presentation-primitives.md +190 -0
  44. package/examples/readme.md +48 -0
  45. package/examples/terminal-app.md +118 -0
  46. package/examples/two-phase-primitives.md +282 -0
  47. package/package.json +9 -3
  48. package/readme.md +281 -290
  49. package/dist/cli.d.ts +0 -14
  50. package/dist/cli.js +0 -31
package/CHANGELOG.md CHANGED
@@ -13,16 +13,33 @@ conservative.
13
13
 
14
14
  ### Added
15
15
 
16
+ - Added `createCommand` as a semantic command mechanics facade.
17
+ - Added `createCommands` as a high-level command mechanics facade.
18
+ - Added `createPresentation` and `PresentationResult` for terminal view-model rendering.
19
+ - Added semantic `Presentation` view factory methods such as `presentation.records(...)`.
20
+ - Added `createOutput` as a stdout/stderr output boundary facade.
21
+ - Added semantic `Output.write()` and `Output.error()` methods.
22
+ - Added `createTerminalApp` to compose command, presentation, and output mechanics.
23
+ - Added generic terminal presentation renderers for JSON, CSV, and text tables.
24
+ - Added reusable stdout/stderr text writers with backpressure handling.
25
+ - Added shared `presentationFormatOptions` for common `--format` command options.
16
26
  - Added machine-readable `IcoreError` codes and details.
27
+ - Added `parseOptionsSubsetDetailed` for validating known option subsets while preserving unknown raw options.
17
28
  - Added opt-in `strict: true` command resolution for rejecting options before command paths.
18
29
  - Added `strict: true` support to direct `runCommand` execution.
19
30
  - Added typed prepared command `payload` returned from `prepare` and passed to `handle`.
20
31
  - Added public `CommandPayload`, `CommandContext`, and `CommandResult` helper types.
32
+ - Added `isPreparedCommandName` for narrowing prepared command unions by name.
21
33
  - Added this changelog.
22
34
 
23
35
  ### Changed
24
36
 
25
37
  - Changed `PreparedCommand` typing to preserve payload correlation when narrowing registry unions by command name.
38
+ - Changed output writers to await promise-returning custom sinks.
39
+ - Reorganized internal source files by CLI framework responsibility without changing the root public API.
40
+ - Split option schema contracts from option value parsing internals.
41
+ - Changed npm package contents to include `CHANGELOG.md`.
42
+ - Removed the redundant `cli` barrel so `index` is the only package entrypoint.
26
43
 
27
44
  ### Removed
28
45
 
@@ -9,13 +9,15 @@
9
9
  *
10
10
  * This file must not contain typed option validation or command resolution.
11
11
  */
12
- import type { OptionsSchema, RawOptionValue } from './options';
12
+ import type { OptionsSchema, RawOptionValue } from '../options/schema';
13
13
  /**
14
14
  * Parsed CLI arguments split into positional command path segments and raw
15
15
  * named options.
16
16
  */
17
17
  export type ParsedArgv = {
18
+ /** Non-option tokens. */
18
19
  positionals: string[];
20
+ /** Unvalidated option values. */
19
21
  options: Record<string, RawOptionValue>;
20
22
  };
21
23
  /**
@@ -12,7 +12,7 @@
12
12
  */
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.parseArgv = parseArgv;
15
- const errors_1 = require("./errors");
15
+ const icore_error_1 = require("../errors/icore-error");
16
16
  /**
17
17
  * Parses raw CLI arguments into positionals and raw long-option values.
18
18
  */
@@ -140,24 +140,24 @@ function isShortOptionToken(arg) {
140
140
  return arg.length === 2 && arg.startsWith('-') && !arg.startsWith('--');
141
141
  }
142
142
  function createDuplicateArgumentError(name) {
143
- return new errors_1.IcoreError('DUPLICATE_ARGUMENT', `Unexpected duplicate argument '--${name}'`, {
143
+ return new icore_error_1.IcoreError('DUPLICATE_ARGUMENT', `Unexpected duplicate argument '--${name}'`, {
144
144
  argument: `--${name}`,
145
145
  option: name
146
146
  });
147
147
  }
148
148
  function createUnexpectedArgumentError(argument) {
149
- return new errors_1.IcoreError('UNEXPECTED_ARGUMENT', `Unexpected argument '${argument}'`, {
149
+ return new icore_error_1.IcoreError('UNEXPECTED_ARGUMENT', `Unexpected argument '${argument}'`, {
150
150
  argument
151
151
  });
152
152
  }
153
153
  function createDuplicateAliasError(alias) {
154
- return new errors_1.IcoreError('DUPLICATE_ALIAS', `Unexpected duplicate alias '-${alias}'`, {
154
+ return new icore_error_1.IcoreError('DUPLICATE_ALIAS', `Unexpected duplicate alias '-${alias}'`, {
155
155
  alias,
156
156
  argument: `-${alias}`
157
157
  });
158
158
  }
159
159
  function createInvalidOptionAliasError(name, alias) {
160
- return new errors_1.IcoreError('INVALID_OPTION_ALIAS', `Expected alias for '--${name}' as single ASCII letter`, {
160
+ return new icore_error_1.IcoreError('INVALID_OPTION_ALIAS', `Expected alias for '--${name}' as single ASCII letter`, {
161
161
  argument: `--${name}`,
162
162
  option: name,
163
163
  alias
@@ -10,26 +10,32 @@
10
10
  * This file must not contain raw token parsing, option schema validation,
11
11
  * domain behavior, SDK calls, or output formatting.
12
12
  */
13
- import { type InferOptions, type InferProvidedOptions, type OptionsSchema } from './options';
13
+ import type { InferOptions, InferProvidedOptions, OptionsSchema } from '../options/schema';
14
14
  /**
15
15
  * Input produced after command path and option validation, before runtime
16
16
  * context is attached.
17
17
  */
18
18
  export type PreparedCommandInput<TSchema extends OptionsSchema> = {
19
+ /** Parsed option values. */
19
20
  options: InferOptions<TSchema>;
21
+ /** Explicit option presence metadata. */
20
22
  provided: InferProvidedOptions<TSchema>;
23
+ /** Positionals after the command path. */
21
24
  positionals: string[];
22
25
  };
23
26
  /**
24
27
  * Input passed to a command handler after command path and option validation.
25
28
  */
26
29
  export type CommandInput<TSchema extends OptionsSchema, TContext, TPayload = void> = PreparedCommandInput<TSchema> & {
30
+ /** Application runtime context. */
27
31
  context: TContext;
28
32
  } & ([
29
33
  TPayload
30
34
  ] extends [void] ? {
35
+ /** Optional prepared payload. */
31
36
  payload?: TPayload;
32
37
  } : {
38
+ /** Prepared payload. */
33
39
  payload: TPayload;
34
40
  });
35
41
  /**
@@ -40,11 +46,17 @@ export type CommandInput<TSchema extends OptionsSchema, TContext, TPayload = voi
40
46
  * formatting.
41
47
  */
42
48
  export type CommandDefinition<TSchema extends OptionsSchema, TContext, TResult, TPath extends readonly [string, ...string[]] = readonly [string, ...string[]], TMetadata = unknown, TPayload = void> = {
49
+ /** Command path segments. */
43
50
  path: TPath;
51
+ /** Command option schema. */
44
52
  options: TSchema;
53
+ /** Caller-owned static metadata. */
45
54
  metadata?: TMetadata;
55
+ /** Allows extra positionals. */
46
56
  allowExtraPositionals?: boolean;
57
+ /** Prepares payload before runtime context. */
47
58
  prepare?(input: PreparedCommandInput<TSchema>): TPayload | Promise<TPayload>;
59
+ /** Runs application command behavior. */
48
60
  handle(input: CommandInput<TSchema, TContext, TPayload>): TResult | Promise<TResult>;
49
61
  };
50
62
  type AnyCommandInput = PreparedCommandInput<OptionsSchema> & {
@@ -78,9 +90,18 @@ type CommandDefinitionParts<TCommand extends AnyCommandDefinition> = TCommand ex
78
90
  metadata: TCommand['metadata'];
79
91
  payload: unknown;
80
92
  };
93
+ /**
94
+ * Infers the runtime context type required by a command.
95
+ */
81
96
  export type CommandContext<TCommand extends AnyCommandDefinition> = CommandDefinitionParts<TCommand>['context'];
97
+ /**
98
+ * Infers the awaited command handler result type.
99
+ */
82
100
  export type CommandResult<TCommand extends AnyCommandDefinition> = Awaited<CommandDefinitionParts<TCommand>['result']>;
83
101
  type CommandSchema<TCommand extends AnyCommandDefinition> = CommandDefinitionParts<TCommand>['schema'];
102
+ /**
103
+ * Infers the payload type produced by a command prepare hook.
104
+ */
84
105
  export type CommandPayload<TCommand extends AnyCommandDefinition> = CommandDefinitionParts<TCommand>['payload'];
85
106
  /**
86
107
  * Infers the public command name from a command path.
@@ -90,39 +111,77 @@ export type CommandName<TCommand extends AnyCommandDefinition> = CommandPathName
90
111
  * Declarative command registry used to resolve command paths.
91
112
  */
92
113
  export type CommandRegistry<TCommands extends readonly AnyCommandDefinition[]> = {
114
+ /** Registered command definitions. */
93
115
  commands: TCommands;
116
+ /** Derived public command names. */
94
117
  commandNames: readonly CommandName<TCommands[number]>[];
95
118
  };
119
+ /**
120
+ * High-level command mechanics facade for terminal applications.
121
+ */
122
+ export type Commands<TCommands extends readonly AnyCommandDefinition[]> = {
123
+ /** Original command definitions. */
124
+ definitions: TCommands;
125
+ /** Public command names. */
126
+ names: readonly CommandName<TCommands[number]>[];
127
+ /** Lower-level command registry. */
128
+ registry: CommandRegistry<TCommands>;
129
+ /** Resolves from positionals. */
130
+ resolve(positionals: readonly string[]): ResolvedCommand<TCommands[number]>;
131
+ /** Resolves from raw argv. */
132
+ resolveFromArgs(args: readonly string[]): ResolvedCommand<TCommands[number]>;
133
+ /** Prepares without runtime context. */
134
+ prepare(args: readonly string[], options?: CommandResolutionOptions): Promise<PreparedCommand<TCommands[number]>>;
135
+ /** Runs a prepared command. */
136
+ run(prepared: PreparedCommand<TCommands[number]>, context: CommandContext<TCommands[number]>): Promise<CommandResult<TCommands[number]>>;
137
+ /** Resolves, prepares, and runs. */
138
+ runFromArgs(args: readonly string[], context: CommandContext<TCommands[number]>, options?: CommandResolutionOptions): Promise<CommandResult<TCommands[number]>>;
139
+ };
140
+ /**
141
+ * Semantic facade for command mechanics.
142
+ */
143
+ export type Command = {
144
+ define: typeof defineCommand;
145
+ registry: typeof createCommands;
146
+ run: typeof runCommand;
147
+ };
96
148
  /**
97
149
  * Options for command resolution from raw CLI arguments.
98
150
  */
99
151
  export type CommandResolutionOptions = {
100
- /**
101
- * When enabled, command path must appear before options. Options before the
102
- * command path are rejected instead of participating in legacy candidate
103
- * schema parsing.
104
- */
152
+ /** Rejects options before command path. */
105
153
  strict?: boolean;
106
154
  };
107
155
  /**
108
156
  * Result of resolving a command from user positionals.
109
157
  */
110
158
  export type ResolvedCommand<TCommand extends AnyCommandDefinition> = {
159
+ /** Space-joined command name. */
111
160
  name: CommandName<TCommand>;
161
+ /** Literal command path. */
112
162
  path: TCommand['path'];
163
+ /** Selected command definition. */
113
164
  command: TCommand;
165
+ /** Positionals after the command path. */
114
166
  positionals: string[];
115
167
  };
116
168
  /**
117
169
  * Command resolved and validated without runtime context.
118
170
  */
119
171
  export type PreparedCommand<TCommand extends AnyCommandDefinition> = TCommand extends AnyCommandDefinition ? {
172
+ /** Space-joined command name. */
120
173
  name: CommandName<TCommand>;
174
+ /** Literal command path. */
121
175
  path: TCommand['path'];
176
+ /** Selected command definition. */
122
177
  command: TCommand;
178
+ /** Parsed option values. */
123
179
  options: InferOptions<CommandSchema<TCommand>>;
180
+ /** Explicit option presence metadata. */
124
181
  provided: InferProvidedOptions<CommandSchema<TCommand>>;
182
+ /** Positionals after the command path. */
125
183
  positionals: string[];
184
+ /** Prepared payload. */
126
185
  payload: CommandPayload<TCommand>;
127
186
  } : never;
128
187
  /**
@@ -133,10 +192,24 @@ export declare function defineCommand<const TSchema extends OptionsSchema, const
133
192
  * Defines a command registry while preserving literal command path types.
134
193
  */
135
194
  export declare function defineCommandRegistry<const TCommands extends readonly AnyCommandDefinition[]>(commands: TCommands): CommandRegistry<TCommands>;
195
+ /**
196
+ * Creates a command mechanics facade from declarative command definitions.
197
+ */
198
+ export declare function createCommands<const TCommands extends readonly AnyCommandDefinition[]>(definitions: TCommands): Commands<TCommands>;
199
+ /**
200
+ * Creates a semantic command mechanics facade.
201
+ */
202
+ export declare function createCommand(): Command;
136
203
  /**
137
204
  * Checks whether a value is a command name registered in the given registry.
138
205
  */
139
206
  export declare function isCommandName<const TCommands extends readonly AnyCommandDefinition[]>(registry: CommandRegistry<TCommands>, value: unknown): value is CommandName<TCommands[number]>;
207
+ /**
208
+ * Checks whether a prepared command has the given command name.
209
+ */
210
+ export declare function isPreparedCommandName<TPrepared extends PreparedCommand<AnyCommandDefinition>, TName extends TPrepared['name']>(prepared: TPrepared, name: TName): prepared is Extract<TPrepared, {
211
+ name: TName;
212
+ }>;
140
213
  /**
141
214
  * Resolves a command from already parsed positional arguments.
142
215
  */
@@ -14,16 +14,19 @@
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.defineCommand = defineCommand;
16
16
  exports.defineCommandRegistry = defineCommandRegistry;
17
+ exports.createCommands = createCommands;
18
+ exports.createCommand = createCommand;
17
19
  exports.isCommandName = isCommandName;
20
+ exports.isPreparedCommandName = isPreparedCommandName;
18
21
  exports.resolveCommand = resolveCommand;
19
22
  exports.resolveCommandFromArgs = resolveCommandFromArgs;
20
23
  exports.prepareCommandFromArgs = prepareCommandFromArgs;
21
24
  exports.runPreparedCommand = runPreparedCommand;
22
25
  exports.runCommandFromRegistry = runCommandFromRegistry;
23
26
  exports.runCommand = runCommand;
24
- const argv_1 = require("./argv");
25
- const errors_1 = require("./errors");
26
- const options_1 = require("./options");
27
+ const parser_1 = require("../argv/parser");
28
+ const icore_error_1 = require("../errors/icore-error");
29
+ const parser_2 = require("../options/parser");
27
30
  /**
28
31
  * Defines a command while preserving literal option schema types.
29
32
  */
@@ -41,6 +44,42 @@ function defineCommandRegistry(commands) {
41
44
  commandNames: commandNames
42
45
  };
43
46
  }
47
+ /**
48
+ * Creates a command mechanics facade from declarative command definitions.
49
+ */
50
+ function createCommands(definitions) {
51
+ const registry = defineCommandRegistry(definitions);
52
+ return {
53
+ definitions,
54
+ names: registry.commandNames,
55
+ registry,
56
+ resolve(positionals) {
57
+ return resolveCommand(registry, positionals);
58
+ },
59
+ resolveFromArgs(args) {
60
+ return resolveCommandFromArgs(registry, args);
61
+ },
62
+ prepare(args, options) {
63
+ return prepareCommandFromArgs(registry, args, options);
64
+ },
65
+ run(prepared, context) {
66
+ return runPreparedCommand(prepared, context);
67
+ },
68
+ runFromArgs(args, context, options) {
69
+ return runCommandFromRegistry(registry, args, context, options);
70
+ }
71
+ };
72
+ }
73
+ /**
74
+ * Creates a semantic command mechanics facade.
75
+ */
76
+ function createCommand() {
77
+ return {
78
+ define: defineCommand,
79
+ registry: createCommands,
80
+ run: runCommand
81
+ };
82
+ }
44
83
  /**
45
84
  * Checks whether a value is a command name registered in the given registry.
46
85
  */
@@ -48,6 +87,12 @@ function isCommandName(registry, value) {
48
87
  return typeof value === 'string'
49
88
  && registry.commandNames.includes(value);
50
89
  }
90
+ /**
91
+ * Checks whether a prepared command has the given command name.
92
+ */
93
+ function isPreparedCommandName(prepared, name) {
94
+ return prepared.name === name;
95
+ }
51
96
  /**
52
97
  * Resolves a command from already parsed positional arguments.
53
98
  */
@@ -65,13 +110,13 @@ function resolveCommand(registry, positionals) {
65
110
  */
66
111
  function resolveCommandFromArgs(registry, args) {
67
112
  for (const command of commandsBySpecificity(registry.commands)) {
68
- const argv = (0, argv_1.parseArgv)(args, command.options);
113
+ const argv = (0, parser_1.parseArgv)(args, command.options);
69
114
  const resolved = resolveCommandCandidate(command, argv.positionals);
70
115
  if (resolved !== undefined) {
71
116
  return resolved;
72
117
  }
73
118
  }
74
- throw createUnknownCommandError((0, argv_1.parseArgv)(args).positionals);
119
+ throw createUnknownCommandError((0, parser_1.parseArgv)(args).positionals);
75
120
  }
76
121
  /**
77
122
  * Resolves and validates a command without requiring runtime context.
@@ -81,13 +126,13 @@ async function prepareCommandFromArgs(registry, args, options = {}) {
81
126
  return prepareCommandFromArgsStrict(registry, args);
82
127
  }
83
128
  for (const command of commandsBySpecificity(registry.commands)) {
84
- const argv = (0, argv_1.parseArgv)(args, command.options);
129
+ const argv = (0, parser_1.parseArgv)(args, command.options);
85
130
  const resolved = resolveCommandCandidate(command, argv.positionals);
86
131
  if (resolved !== undefined) {
87
132
  return prepareResolvedCommand(resolved, argv.options);
88
133
  }
89
134
  }
90
- throw createUnknownCommandError((0, argv_1.parseArgv)(args).positionals);
135
+ throw createUnknownCommandError((0, parser_1.parseArgv)(args).positionals);
91
136
  }
92
137
  /**
93
138
  * Runs a prepared command with caller-provided runtime context.
@@ -121,7 +166,7 @@ async function prepareCommand(command, args, options = {}) {
121
166
  if (options.strict === true) {
122
167
  assertNoOptionBeforeCommand(args);
123
168
  }
124
- const argv = (0, argv_1.parseArgv)(args, command.options);
169
+ const argv = (0, parser_1.parseArgv)(args, command.options);
125
170
  const extraPositionals = resolveCommandPositionals(command.path, argv.positionals);
126
171
  const resolved = {
127
172
  name: commandPathToName(command.path),
@@ -136,7 +181,7 @@ async function prepareCommandFromArgsStrict(registry, args) {
136
181
  if (command === undefined) {
137
182
  throw createUnknownCommandError(commandPositionalsBeforeOptions(args));
138
183
  }
139
- const argv = (0, argv_1.parseArgv)(args, command.options);
184
+ const argv = (0, parser_1.parseArgv)(args, command.options);
140
185
  const resolved = resolveCommandCandidate(command, argv.positionals);
141
186
  if (resolved === undefined) {
142
187
  throw createUnknownCommandError(argv.positionals);
@@ -147,13 +192,13 @@ async function prepareResolvedCommand(resolved, rawOptions) {
147
192
  const { command } = resolved;
148
193
  if (resolved.positionals.length > 0 && command.allowExtraPositionals !== true) {
149
194
  const positional = resolved.positionals[0] ?? '';
150
- throw new errors_1.IcoreError('UNEXPECTED_POSITIONAL', `Unexpected positional argument for '${command.path.join(' ')}': ${positional}`, {
195
+ throw new icore_error_1.IcoreError('UNEXPECTED_POSITIONAL', `Unexpected positional argument for '${command.path.join(' ')}': ${positional}`, {
151
196
  command: command.path.join(' '),
152
197
  positional,
153
198
  positionals: [...resolved.positionals]
154
199
  });
155
200
  }
156
- const parsed = (0, options_1.parseOptionsDetailed)(command.options, rawOptions);
201
+ const parsed = (0, parser_2.parseOptionsDetailed)(command.options, rawOptions);
157
202
  const input = {
158
203
  options: parsed.options,
159
204
  provided: parsed.provided,
@@ -174,7 +219,7 @@ function resolveCommandPositionals(path, positionals) {
174
219
  for (let index = 0; index < path.length; index += 1) {
175
220
  if (positionals[index] !== path[index]) {
176
221
  const command = path.join(' ');
177
- throw new errors_1.IcoreError('UNKNOWN_COMMAND', `Expected command '${command}'`, {
222
+ throw new icore_error_1.IcoreError('UNKNOWN_COMMAND', `Expected command '${command}'`, {
178
223
  command,
179
224
  path: [...path],
180
225
  positionals: [...positionals]
@@ -259,18 +304,18 @@ function isOptionBeforeCommand(arg) {
259
304
  }
260
305
  function createUnknownCommandError(positionals) {
261
306
  const command = formatCommandPositionals(positionals);
262
- return new errors_1.IcoreError('UNKNOWN_COMMAND', `Unknown command: ${command}`, {
307
+ return new icore_error_1.IcoreError('UNKNOWN_COMMAND', `Unknown command: ${command}`, {
263
308
  command,
264
309
  positionals: [...positionals]
265
310
  });
266
311
  }
267
312
  function createUnexpectedArgumentError(argument) {
268
- return new errors_1.IcoreError('UNEXPECTED_ARGUMENT', `Unexpected argument '${argument}'`, {
313
+ return new icore_error_1.IcoreError('UNEXPECTED_ARGUMENT', `Unexpected argument '${argument}'`, {
269
314
  argument
270
315
  });
271
316
  }
272
317
  function createDuplicateCommandError(command) {
273
- return new errors_1.IcoreError('DUPLICATE_COMMAND', `Unexpected duplicate command '${command}'`, {
318
+ return new icore_error_1.IcoreError('DUPLICATE_COMMAND', `Unexpected duplicate command '${command}'`, {
274
319
  command
275
320
  });
276
321
  }
@@ -21,7 +21,9 @@ export type IcoreErrorDetails = Readonly<Record<string, unknown>>;
21
21
  * resolution, and schema configuration failures.
22
22
  */
23
23
  export declare class IcoreError extends Error {
24
+ /** Stable machine-readable code. */
24
25
  readonly code: IcoreErrorCode;
26
+ /** Structured error context. */
25
27
  readonly details: IcoreErrorDetails;
26
28
  constructor(code: IcoreErrorCode, message: string, details?: IcoreErrorDetails);
27
29
  }
@@ -16,7 +16,9 @@ exports.IcoreError = void 0;
16
16
  * resolution, and schema configuration failures.
17
17
  */
18
18
  class IcoreError extends Error {
19
+ /** Stable machine-readable code. */
19
20
  code;
21
+ /** Structured error context. */
20
22
  details;
21
23
  constructor(code, message, details = {}) {
22
24
  super(message);
package/dist/index.d.ts CHANGED
@@ -1 +1,28 @@
1
- export { defineCommand, defineCommandRegistry, IcoreError, isCommandName, mergeOptionsSchema, parseArgv, parseOptions, parseOptionsDetailed, prepareCommandFromArgs, resolveCommand, resolveCommandFromArgs, runCommand, runPreparedCommand, runCommandFromRegistry, type BooleanOption, type CommandDefinition, type CommandContext, type CommandInput, type CommandName, type CommandPayload, type CommandRegistry, type CommandResolutionOptions, type CommandResult, type InferOptions, type InferProvidedOptions, type IcoreErrorCode, type IcoreErrorDetails, type MergeOptionsSchemas, type NumberOption, type OptionDefinition, type OptionsSchema, type ParseOptionsResult, type ParsedArgv, type PreparedCommand, type PreparedCommandInput, type RawOptionValue, type ResolvedCommand, type StringOption } from './cli';
1
+ /**
2
+ * The package entrypoint exposes the supported command mechanics API.
3
+ *
4
+ * Allowed here:
5
+ * - re-exporting public argv parser contracts;
6
+ * - re-exporting public option schema contracts;
7
+ * - re-exporting public command registry contracts;
8
+ * - re-exporting public presentation and output contracts;
9
+ * - re-exporting public terminal app composition contracts;
10
+ *
11
+ * This file must not contain parser, validator, or command runtime logic.
12
+ */
13
+ export { parseArgv, type ParsedArgv } from './argv/parser';
14
+ export { createCommand, createCommands, defineCommand, defineCommandRegistry, isCommandName, isPreparedCommandName, prepareCommandFromArgs, resolveCommand, resolveCommandFromArgs, runCommand, runPreparedCommand, runCommandFromRegistry, type Command, type CommandDefinition, type CommandContext, type CommandInput, type CommandName, type CommandPayload, type CommandRegistry, type CommandResolutionOptions, type CommandResult, type Commands, type PreparedCommand, type PreparedCommandInput, type ResolvedCommand } from './command/mechanics';
15
+ export { IcoreError, type IcoreErrorCode, type IcoreErrorDetails } from './errors/icore-error';
16
+ export { parseOptions, parseOptionsDetailed, parseOptionsSubsetDetailed, type ParseOptionsResult, type ParseOptionsSubsetResult } from './options/parser';
17
+ export { mergeOptionsSchema, type BooleanOption, type InferOptions, type InferProvidedOptions, type MergeOptionsSchemas, type NumberOption, type OptionDefinition, type OptionsSchema, type RawOptionValue, type StringOption } from './options/schema';
18
+ export { createPresentation, type Presentation, type PresentationRenderers } from './presentation/facade';
19
+ export { isPresentationFormat, presentationFormatOptions, presentationFormats, type PresentationFormat } from './presentation/format-options';
20
+ export { renderCsv, renderCsvRow } from './presentation/renderers/csv';
21
+ export { renderJson } from './presentation/renderers/json';
22
+ export { renderTextTable } from './presentation/renderers/table';
23
+ export { isPresentationResult, renderPresentationResult } from './presentation/result-renderer';
24
+ export { type CsvCell, type CsvRow, type CsvPresentationView, type EmptyPresentationView, type PresentationRecord, type PresentationResult, type PresentationView, type PresentationViewFactory, type RecordPresentationView, type RecordsPresentationView, type TablePresentationView, type TextPresentationView, type TextTableRow } from './presentation/view';
25
+ export { createOutput, type Output, type OutputOptions } from './output/facade';
26
+ export { createStderrWriter, createStdoutWriter } from './output/node-writer';
27
+ export { createBackpressureTextWriter, type BackpressureTextSink, type TextWriter } from './output/text-writer';
28
+ export { createTerminalApp, type TerminalApp, type TerminalAppOptions, type TerminalCommandOutput } from './terminal/app';
package/dist/index.js CHANGED
@@ -1,18 +1,63 @@
1
1
  "use strict";
2
+ /**
3
+ * The package entrypoint exposes the supported command mechanics API.
4
+ *
5
+ * Allowed here:
6
+ * - re-exporting public argv parser contracts;
7
+ * - re-exporting public option schema contracts;
8
+ * - re-exporting public command registry contracts;
9
+ * - re-exporting public presentation and output contracts;
10
+ * - re-exporting public terminal app composition contracts;
11
+ *
12
+ * This file must not contain parser, validator, or command runtime logic.
13
+ */
2
14
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runCommandFromRegistry = exports.runPreparedCommand = exports.runCommand = exports.resolveCommandFromArgs = exports.resolveCommand = exports.prepareCommandFromArgs = exports.parseOptionsDetailed = exports.parseOptions = exports.parseArgv = exports.mergeOptionsSchema = exports.isCommandName = exports.IcoreError = exports.defineCommandRegistry = exports.defineCommand = void 0;
4
- var cli_1 = require("./cli");
5
- Object.defineProperty(exports, "defineCommand", { enumerable: true, get: function () { return cli_1.defineCommand; } });
6
- Object.defineProperty(exports, "defineCommandRegistry", { enumerable: true, get: function () { return cli_1.defineCommandRegistry; } });
7
- Object.defineProperty(exports, "IcoreError", { enumerable: true, get: function () { return cli_1.IcoreError; } });
8
- Object.defineProperty(exports, "isCommandName", { enumerable: true, get: function () { return cli_1.isCommandName; } });
9
- Object.defineProperty(exports, "mergeOptionsSchema", { enumerable: true, get: function () { return cli_1.mergeOptionsSchema; } });
10
- Object.defineProperty(exports, "parseArgv", { enumerable: true, get: function () { return cli_1.parseArgv; } });
11
- Object.defineProperty(exports, "parseOptions", { enumerable: true, get: function () { return cli_1.parseOptions; } });
12
- Object.defineProperty(exports, "parseOptionsDetailed", { enumerable: true, get: function () { return cli_1.parseOptionsDetailed; } });
13
- Object.defineProperty(exports, "prepareCommandFromArgs", { enumerable: true, get: function () { return cli_1.prepareCommandFromArgs; } });
14
- Object.defineProperty(exports, "resolveCommand", { enumerable: true, get: function () { return cli_1.resolveCommand; } });
15
- Object.defineProperty(exports, "resolveCommandFromArgs", { enumerable: true, get: function () { return cli_1.resolveCommandFromArgs; } });
16
- Object.defineProperty(exports, "runCommand", { enumerable: true, get: function () { return cli_1.runCommand; } });
17
- Object.defineProperty(exports, "runPreparedCommand", { enumerable: true, get: function () { return cli_1.runPreparedCommand; } });
18
- Object.defineProperty(exports, "runCommandFromRegistry", { enumerable: true, get: function () { return cli_1.runCommandFromRegistry; } });
15
+ exports.createTerminalApp = exports.createBackpressureTextWriter = exports.createStdoutWriter = exports.createStderrWriter = exports.createOutput = exports.renderPresentationResult = exports.isPresentationResult = exports.renderTextTable = exports.renderJson = exports.renderCsvRow = exports.renderCsv = exports.presentationFormats = exports.presentationFormatOptions = exports.isPresentationFormat = exports.createPresentation = exports.mergeOptionsSchema = exports.parseOptionsSubsetDetailed = exports.parseOptionsDetailed = exports.parseOptions = exports.IcoreError = exports.runCommandFromRegistry = exports.runPreparedCommand = exports.runCommand = exports.resolveCommandFromArgs = exports.resolveCommand = exports.prepareCommandFromArgs = exports.isPreparedCommandName = exports.isCommandName = exports.defineCommandRegistry = exports.defineCommand = exports.createCommands = exports.createCommand = exports.parseArgv = void 0;
16
+ var parser_1 = require("./argv/parser");
17
+ Object.defineProperty(exports, "parseArgv", { enumerable: true, get: function () { return parser_1.parseArgv; } });
18
+ var mechanics_1 = require("./command/mechanics");
19
+ Object.defineProperty(exports, "createCommand", { enumerable: true, get: function () { return mechanics_1.createCommand; } });
20
+ Object.defineProperty(exports, "createCommands", { enumerable: true, get: function () { return mechanics_1.createCommands; } });
21
+ Object.defineProperty(exports, "defineCommand", { enumerable: true, get: function () { return mechanics_1.defineCommand; } });
22
+ Object.defineProperty(exports, "defineCommandRegistry", { enumerable: true, get: function () { return mechanics_1.defineCommandRegistry; } });
23
+ Object.defineProperty(exports, "isCommandName", { enumerable: true, get: function () { return mechanics_1.isCommandName; } });
24
+ Object.defineProperty(exports, "isPreparedCommandName", { enumerable: true, get: function () { return mechanics_1.isPreparedCommandName; } });
25
+ Object.defineProperty(exports, "prepareCommandFromArgs", { enumerable: true, get: function () { return mechanics_1.prepareCommandFromArgs; } });
26
+ Object.defineProperty(exports, "resolveCommand", { enumerable: true, get: function () { return mechanics_1.resolveCommand; } });
27
+ Object.defineProperty(exports, "resolveCommandFromArgs", { enumerable: true, get: function () { return mechanics_1.resolveCommandFromArgs; } });
28
+ Object.defineProperty(exports, "runCommand", { enumerable: true, get: function () { return mechanics_1.runCommand; } });
29
+ Object.defineProperty(exports, "runPreparedCommand", { enumerable: true, get: function () { return mechanics_1.runPreparedCommand; } });
30
+ Object.defineProperty(exports, "runCommandFromRegistry", { enumerable: true, get: function () { return mechanics_1.runCommandFromRegistry; } });
31
+ var icore_error_1 = require("./errors/icore-error");
32
+ Object.defineProperty(exports, "IcoreError", { enumerable: true, get: function () { return icore_error_1.IcoreError; } });
33
+ var parser_2 = require("./options/parser");
34
+ Object.defineProperty(exports, "parseOptions", { enumerable: true, get: function () { return parser_2.parseOptions; } });
35
+ Object.defineProperty(exports, "parseOptionsDetailed", { enumerable: true, get: function () { return parser_2.parseOptionsDetailed; } });
36
+ Object.defineProperty(exports, "parseOptionsSubsetDetailed", { enumerable: true, get: function () { return parser_2.parseOptionsSubsetDetailed; } });
37
+ var schema_1 = require("./options/schema");
38
+ Object.defineProperty(exports, "mergeOptionsSchema", { enumerable: true, get: function () { return schema_1.mergeOptionsSchema; } });
39
+ var facade_1 = require("./presentation/facade");
40
+ Object.defineProperty(exports, "createPresentation", { enumerable: true, get: function () { return facade_1.createPresentation; } });
41
+ var format_options_1 = require("./presentation/format-options");
42
+ Object.defineProperty(exports, "isPresentationFormat", { enumerable: true, get: function () { return format_options_1.isPresentationFormat; } });
43
+ Object.defineProperty(exports, "presentationFormatOptions", { enumerable: true, get: function () { return format_options_1.presentationFormatOptions; } });
44
+ Object.defineProperty(exports, "presentationFormats", { enumerable: true, get: function () { return format_options_1.presentationFormats; } });
45
+ var csv_1 = require("./presentation/renderers/csv");
46
+ Object.defineProperty(exports, "renderCsv", { enumerable: true, get: function () { return csv_1.renderCsv; } });
47
+ Object.defineProperty(exports, "renderCsvRow", { enumerable: true, get: function () { return csv_1.renderCsvRow; } });
48
+ var json_1 = require("./presentation/renderers/json");
49
+ Object.defineProperty(exports, "renderJson", { enumerable: true, get: function () { return json_1.renderJson; } });
50
+ var table_1 = require("./presentation/renderers/table");
51
+ Object.defineProperty(exports, "renderTextTable", { enumerable: true, get: function () { return table_1.renderTextTable; } });
52
+ var result_renderer_1 = require("./presentation/result-renderer");
53
+ Object.defineProperty(exports, "isPresentationResult", { enumerable: true, get: function () { return result_renderer_1.isPresentationResult; } });
54
+ Object.defineProperty(exports, "renderPresentationResult", { enumerable: true, get: function () { return result_renderer_1.renderPresentationResult; } });
55
+ var facade_2 = require("./output/facade");
56
+ Object.defineProperty(exports, "createOutput", { enumerable: true, get: function () { return facade_2.createOutput; } });
57
+ var node_writer_1 = require("./output/node-writer");
58
+ Object.defineProperty(exports, "createStderrWriter", { enumerable: true, get: function () { return node_writer_1.createStderrWriter; } });
59
+ Object.defineProperty(exports, "createStdoutWriter", { enumerable: true, get: function () { return node_writer_1.createStdoutWriter; } });
60
+ var text_writer_1 = require("./output/text-writer");
61
+ Object.defineProperty(exports, "createBackpressureTextWriter", { enumerable: true, get: function () { return text_writer_1.createBackpressureTextWriter; } });
62
+ var app_1 = require("./terminal/app");
63
+ Object.defineProperty(exports, "createTerminalApp", { enumerable: true, get: function () { return app_1.createTerminalApp; } });
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The option parser module validates raw option values against declarative
3
+ * primitive option contracts.
4
+ *
5
+ * Allowed here:
6
+ * - applying and validating default values;
7
+ * - producing typed option values and user-provided metadata;
8
+ *
9
+ * This file must not contain argv tokenization, command resolution, or
10
+ * application-specific validation rules.
11
+ */
12
+ import type { InferOptions, InferProvidedOptions, OptionsSchema, RawOptionValue } from './schema';
13
+ /**
14
+ * Detailed option parsing result with values and user-provided metadata.
15
+ */
16
+ export type ParseOptionsResult<TSchema extends OptionsSchema> = {
17
+ /** Parsed values. */
18
+ options: InferOptions<TSchema>;
19
+ /** Explicit option presence metadata. */
20
+ provided: InferProvidedOptions<TSchema>;
21
+ };
22
+ /**
23
+ * Detailed option subset parsing result with untouched options for later
24
+ * command-layer validation.
25
+ */
26
+ export type ParseOptionsSubsetResult<TSchema extends OptionsSchema> = ParseOptionsResult<TSchema> & {
27
+ /** Unparsed raw values. */
28
+ rest: Record<string, RawOptionValue>;
29
+ };
30
+ /**
31
+ * Validates raw option values against a declarative option schema.
32
+ */
33
+ export declare function parseOptions<const TSchema extends OptionsSchema>(schema: TSchema, values: Record<string, RawOptionValue>): InferOptions<TSchema>;
34
+ /**
35
+ * Validates raw option values and returns parsed values with user-provided
36
+ * metadata.
37
+ */
38
+ export declare function parseOptionsDetailed<const TSchema extends OptionsSchema>(schema: TSchema, values: Record<string, RawOptionValue>): ParseOptionsResult<TSchema>;
39
+ /**
40
+ * Validates only raw option values known by the given schema and leaves the
41
+ * remaining raw options untouched.
42
+ */
43
+ export declare function parseOptionsSubsetDetailed<const TSchema extends OptionsSchema>(schema: TSchema, values: Record<string, RawOptionValue>): ParseOptionsSubsetResult<TSchema>;