@travetto/cli 5.0.0-rc.8 → 5.0.0-rc.9

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 CHANGED
@@ -132,9 +132,9 @@ HELLO
132
132
 
133
133
  The [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/decorators.ts#L85) supports the following data types for flags:
134
134
  * Boolean values
135
- * Number values. The [@Integer](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L172), [@Float](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L178), [@Precision](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L166), [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L107) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L117) decorators help provide additional validation.
136
- * String values. [@MinLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L107), [@MaxLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L117), [@Match](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L99) and [@Enum](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L78) provide additional constraints
137
- * Date values. The [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L107) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L117) decorators help provide additional validation.
135
+ * Number values. The [@Integer](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L171), [@Float](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L177), [@Precision](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L165), [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L106) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L116) decorators help provide additional validation.
136
+ * String values. [@MinLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L106), [@MaxLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L116), [@Match](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L98) and [@Enum](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L77) provide additional constraints
137
+ * Date values. The [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L106) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L116) decorators help provide additional validation.
138
138
  * String lists. Same as String, but allowing multiple values.
139
139
  * Numeric lists. Same as Number, but allowing multiple values.
140
140
 
@@ -411,6 +411,7 @@ export class RunCommand {
411
411
  **Code: Anatomy of a Command**
412
412
  ```typescript
413
413
  export interface CliCommandShape<T extends unknown[] = unknown[]> {
414
+
414
415
  /**
415
416
  * Parsed state
416
417
  */
@@ -499,7 +500,7 @@ export class RunRestCommand implements CliCommandShape {
499
500
  }
500
501
  ```
501
502
 
502
- As noted in the example above, `fields` is specified in this execution, with support for `module`, and `env`. These env flag is directly tied to the [Runtime](https://github.com/travetto/travetto/tree/main/module/runtime/src/env.ts#L108) `name` defined in the [Base](https://github.com/travetto/travetto/tree/main/module/runtime#readme "Environment config and common utilities for travetto applications.") module.
503
+ As noted in the example above, `fields` is specified in this execution, with support for `module`, and `env`. These env flag is directly tied to the [Runtime](https://github.com/travetto/travetto/tree/main/module/runtime/src/env.ts#L109) `name` defined in the [Base](https://github.com/travetto/travetto/tree/main/module/runtime#readme "Environment config and common utilities for travetto applications.") module.
503
504
 
504
505
  The `module` field is slightly more complex, but is geared towards supporting commands within a monorepo context. This flag ensures that a module is specified if running from the root of the monorepo, and that the module provided is real, and can run the desired command. When running from an explicit module folder in the monorepo, the module flag is ignored.
505
506
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/cli",
3
- "version": "5.0.0-rc.8",
3
+ "version": "5.0.0-rc.9",
4
4
  "description": "CLI infrastructure for Travetto framework",
5
5
  "keywords": [
6
6
  "cli",
@@ -29,8 +29,8 @@
29
29
  "directory": "module/cli"
30
30
  },
31
31
  "dependencies": {
32
- "@travetto/schema": "^5.0.0-rc.8",
33
- "@travetto/terminal": "^5.0.0-rc.8"
32
+ "@travetto/schema": "^5.0.0-rc.9",
33
+ "@travetto/terminal": "^5.0.0-rc.9"
34
34
  },
35
35
  "travetto": {
36
36
  "displayName": "Command Line Interface",
package/src/decorators.ts CHANGED
@@ -109,16 +109,14 @@ export function CliCommand(cfg: CliCommandConfigOptions = {}) {
109
109
  const runtimeModule = cfg.runtimeModule ?? (cfg.with?.module ? 'current' : undefined);
110
110
 
111
111
  if (runtimeModule) { // Validate module
112
- (pendingCls.validators ??= []).push(async item => {
113
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
114
- const { module: mod } = item as CliCommandShapeFields;
112
+ (pendingCls.validators ??= []).push(async ({ module: mod }: Partial<CliCommandShapeFields>) => {
115
113
  const runModule = (runtimeModule === 'command' ? commandModule : mod) || Runtime.main.name;
116
114
 
117
115
  // If we need to run as a specific module
118
116
  if (runModule !== Runtime.main.name) {
119
117
  try {
120
118
  RuntimeIndex.reinitForModule(runModule);
121
- } catch (err) {
119
+ } catch {
122
120
  return { source: 'flag', message: `${runModule} is an unknown module`, kind: 'custom', path: '.' };
123
121
  }
124
122
  }
package/src/help.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import util from 'node:util';
2
2
 
3
- import { Primitive } from '@travetto/runtime';
3
+ import { castKey, castTo, Primitive } from '@travetto/runtime';
4
4
 
5
5
  import { cliTpl } from './color';
6
6
  import { CliCommandShape } from './types';
@@ -41,13 +41,11 @@ export class HelpUtil {
41
41
  }
42
42
 
43
43
  const params: string[] = [];
44
- const descs: string[] = [];
44
+ const descriptions: string[] = [];
45
45
 
46
46
  for (const flag of flags) {
47
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
48
- const key = flag.name as keyof CliCommandShape;
49
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
50
- const flagVal = command[key] as unknown as Primitive;
47
+ const key = castKey<CliCommandShape>(flag.name);
48
+ const flagVal: Primitive = castTo(command[key]);
51
49
 
52
50
  let aliases = flag.flagNames ?? [];
53
51
  if (isBoolFlag(flag)) {
@@ -68,11 +66,11 @@ export class HelpUtil {
68
66
  if (key !== 'help' && flagVal !== null && flagVal !== undefined && flagVal !== '') {
69
67
  desc.push(cliTpl`(default: ${{ input: JSON.stringify(flagVal) }})`);
70
68
  }
71
- descs.push(desc.join(' '));
69
+ descriptions.push(desc.join(' '));
72
70
  }
73
71
 
74
72
  const paramWidths = params.map(x => util.stripVTControlCharacters(x).length);
75
- const descWidths = descs.map(x => util.stripVTControlCharacters(x).length);
73
+ const descWidths = descriptions.map(x => util.stripVTControlCharacters(x).length);
76
74
 
77
75
  const paramWidth = Math.max(...paramWidths);
78
76
  const descWidth = Math.max(...descWidths);
@@ -87,7 +85,7 @@ export class HelpUtil {
87
85
  '',
88
86
  cliTpl`${{ title: 'Options:' }}`,
89
87
  ...params.map((_, i) =>
90
- ` ${params[i]}${' '.repeat((paramWidth - paramWidths[i]))} ${descs[i].padEnd(descWidth)}${' '.repeat((descWidth - descWidths[i]))}`
88
+ ` ${params[i]}${' '.repeat((paramWidth - paramWidths[i]))} ${descriptions[i].padEnd(descWidth)}${' '.repeat((descWidth - descWidths[i]))}`
91
89
  ),
92
90
  '',
93
91
  ...helpText
package/src/parse.ts CHANGED
@@ -191,7 +191,7 @@ export class CliParseUtil {
191
191
  } else {
192
192
  const field = schema.args[argIdx];
193
193
  out.push(getInput({ field, input, index: argIdx }));
194
- // Move argIdx along if not in a vararg situation
194
+ // Move argIdx along if not in a var arg situation
195
195
  if (!field?.array) {
196
196
  argIdx += 1;
197
197
  }
package/src/registry.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Class, ConcreteClass, describeFunction, Runtime, RuntimeIndex } from '@travetto/runtime';
1
+ import { asConstructable, Class, classConstruct, describeFunction, Runtime, RuntimeIndex } from '@travetto/runtime';
2
2
 
3
3
  import { CliCommandConfig, CliCommandShape } from './types';
4
4
  import { CliUnknownCommandError } from './error';
@@ -14,9 +14,8 @@ class $CliCommandRegistry {
14
14
  return this.#commands.get(cls);
15
15
  }
16
16
 
17
- #getClass(cmd: CliCommandShape): Class<CliCommandShape> {
18
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
19
- return cmd.constructor as Class;
17
+ getClass(cmd: CliCommandShape): Class<CliCommandShape> {
18
+ return asConstructable<CliCommandShape>(cmd).constructor;
20
19
  }
21
20
 
22
21
  /**
@@ -40,11 +39,10 @@ class $CliCommandRegistry {
40
39
  /**
41
40
  * Registers a cli command
42
41
  */
43
- registerClass(cls: Class, cfg: Partial<CliCommandConfig>): CliCommandConfig {
42
+ registerClass<T extends CliCommandShape>(cls: Class<T>, cfg: Partial<CliCommandConfig>): CliCommandConfig {
44
43
  const meta = describeFunction(cls);
45
44
  this.#commands.set(cls, {
46
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
47
- cls: cls as ConcreteClass,
45
+ cls,
48
46
  name: getName(meta.import),
49
47
  commandModule: meta.module,
50
48
  ...cfg,
@@ -56,7 +54,7 @@ class $CliCommandRegistry {
56
54
  * Get config for a given instance
57
55
  */
58
56
  getConfig(cmd: CliCommandShape): CliCommandConfig {
59
- return this.getByClass(this.#getClass(cmd))!;
57
+ return this.getByClass(this.getClass(cmd))!;
60
58
  }
61
59
 
62
60
  /**
@@ -80,7 +78,7 @@ class $CliCommandRegistry {
80
78
  for (const v of values) {
81
79
  const cfg = this.getByClass(v);
82
80
  if (cfg) {
83
- const inst = new cfg.cls();
81
+ const inst = classConstruct(cfg.cls);
84
82
  if (!inst.isActive || inst.isActive()) {
85
83
  inst._cfg = this.getConfig(inst);
86
84
  return inst;
package/src/schema.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Class } from '@travetto/runtime';
1
+ import { castKey, castTo, Class } from '@travetto/runtime';
2
2
  import { BindUtil, FieldConfig, SchemaRegistry, SchemaValidator, ValidationResultError } from '@travetto/schema';
3
3
 
4
4
  import { CliCommandRegistry } from './registry';
@@ -52,8 +52,7 @@ export class CliCommandSchemaUtil {
52
52
  * Get schema for a given command
53
53
  */
54
54
  static async getSchema(src: Class | CliCommandShape): Promise<CliCommandSchema> {
55
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
56
- const cls = 'main' in src ? src.constructor as Class : src;
55
+ const cls = 'main' in src ? CliCommandRegistry.getClass(src) : src;
57
56
  if (this.#schemas.has(cls)) {
58
57
  return this.#schemas.get(cls)!;
59
58
  }
@@ -127,22 +126,18 @@ export class CliCommandSchemaUtil {
127
126
  for (const arg of state.all) {
128
127
  switch (arg.type) {
129
128
  case 'flag': {
130
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
131
- const key = arg.fieldName as keyof T;
129
+ const key = castKey<T>(arg.fieldName);
132
130
  const value = arg.value!;
133
131
  if (arg.array) {
134
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
135
- ((template[key] as unknown[]) ??= []).push(value);
132
+ castTo<unknown[]>(template[key] ??= castTo([])).push(value);
136
133
  } else {
137
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
138
- template[key] = value as unknown as T[typeof key];
134
+ template[key] = castTo(value);
139
135
  }
140
136
  break;
141
137
  }
142
138
  case 'arg': {
143
139
  if (arg.array) {
144
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
145
- ((bound[arg.index] ??= []) as unknown[]).push(arg.input);
140
+ castTo<unknown[]>(bound[arg.index] ??= []).push(arg.input);
146
141
  } else {
147
142
  bound[arg.index] = arg.input;
148
143
  }
@@ -150,8 +145,7 @@ export class CliCommandSchemaUtil {
150
145
  }
151
146
  }
152
147
 
153
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
154
- const cls = cmd.constructor as Class<CliCommandShape>;
148
+ const cls = CliCommandRegistry.getClass(cmd);
155
149
  BindUtil.bindSchemaToObject(cls, cmd, template);
156
150
  return BindUtil.coerceMethodParams(cls, 'main', bound);
157
151
  }
@@ -160,9 +154,7 @@ export class CliCommandSchemaUtil {
160
154
  * Validate command shape with the given arguments
161
155
  */
162
156
  static async validate(cmd: CliCommandShape, args: unknown[]): Promise<typeof cmd> {
163
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
164
- const cls = cmd.constructor as Class<CliCommandShape>;
165
-
157
+ const cls = CliCommandRegistry.getClass(cmd);
166
158
  const paramNames = SchemaRegistry.getMethodSchema(cls, 'main').map(x => x.name);
167
159
 
168
160
  const validators = [
package/src/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ConcreteClass } from '@travetto/runtime';
1
+ import { Class } from '@travetto/runtime';
2
2
 
3
3
  type OrProm<T> = T | Promise<T>;
4
4
 
@@ -19,7 +19,7 @@ export type CliCommandConfig = {
19
19
  name: string;
20
20
  commandModule: string;
21
21
  runTarget?: boolean;
22
- cls: ConcreteClass<CliCommandShape>;
22
+ cls: Class<CliCommandShape>;
23
23
  hidden?: boolean;
24
24
  preMain?: (cmd: CliCommandShape) => void | Promise<void>;
25
25
  };
@@ -49,6 +49,7 @@ export type CliValidationError = {
49
49
  * CLI Command Contract
50
50
  */
51
51
  export interface CliCommandShape<T extends unknown[] = unknown[]> {
52
+
52
53
  /**
53
54
  * Parsed state
54
55
  */
@@ -116,7 +117,7 @@ export type CliCommandShapeFields = {
116
117
  /**
117
118
  * CLI Command argument/flag shape
118
119
  */
119
- export type CliCommandInput = {
120
+ export type CliCommandInput<K extends string = string> = {
120
121
  name: string;
121
122
  description?: string;
122
123
  type: 'string' | 'file' | 'number' | 'boolean' | 'date' | 'regex' | 'module';
@@ -125,19 +126,19 @@ export type CliCommandInput = {
125
126
  required?: boolean;
126
127
  array?: boolean;
127
128
  default?: unknown;
128
- flagNames?: string[];
129
+ flagNames?: K[];
129
130
  envVars?: string[];
130
131
  };
131
132
 
132
133
  /**
133
134
  * CLI Command schema shape
134
135
  */
135
- export type CliCommandSchema = {
136
+ export interface CliCommandSchema<K extends string = string> {
136
137
  name: string;
137
138
  title: string;
138
139
  commandModule: string;
139
140
  runTarget?: boolean;
140
141
  description?: string;
141
142
  args: CliCommandInput[];
142
- flags: CliCommandInput[];
143
- };
143
+ flags: CliCommandInput<K>[];
144
+ }