@travetto/cli 7.0.0-rc.1 → 7.0.0-rc.3

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
@@ -133,9 +133,9 @@ HELLO
133
133
 
134
134
  The [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#L85) supports the following data types for flags:
135
135
  * Boolean values
136
- * Number values. The [@Integer](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L164), [@Float](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L171), [@Precision](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L157), [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L91) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L102) decorators help provide additional validation.
137
- * String values. [@MinLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L91), [@MaxLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L102), [@Match](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L82) and [@Enum](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L56) provide additional constraints
138
- * Date values. The [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L91) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L102) decorators help provide additional validation.
136
+ * Number values. The [@Integer](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L166), [@Float](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L173), [@Precision](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L159), [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L93) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L104) decorators help provide additional validation.
137
+ * String values. [@MinLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L93), [@MaxLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L104), [@Match](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L84) and [@Enum](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L58) provide additional constraints
138
+ * Date values. The [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L93) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L104) decorators help provide additional validation.
139
139
  * String lists. Same as String, but allowing multiple values.
140
140
  * Numeric lists. Same as Number, but allowing multiple values.
141
141
 
@@ -472,7 +472,7 @@ import type { WebHttpServer } from '../src/types.ts';
472
472
  /**
473
473
  * Run a web server
474
474
  */
475
- @CliCommand({ runTarget: true, with: { debugIpc: true, canRestart: true, module: true, env: true } })
475
+ @CliCommand({ runTarget: true, with: { debugIpc: true, restartForDev: true, module: true, env: true } })
476
476
  export class WebHttpCommand implements CliCommandShape {
477
477
 
478
478
  /** Port to run on */
@@ -502,7 +502,7 @@ export class WebHttpCommand implements CliCommandShape {
502
502
  }
503
503
  ```
504
504
 
505
- 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/context.ts#L12) `name` defined in the [Runtime](https://github.com/travetto/travetto/tree/main/module/runtime#readme "Runtime for travetto applications.") module.
505
+ 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/context.ts#L13) `name` defined in the [Runtime](https://github.com/travetto/travetto/tree/main/module/runtime#readme "Runtime for travetto applications.") module.
506
506
 
507
507
  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.
508
508
 
package/bin/trv.js CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ globalThis.__entry_point__ = __filename;
4
+
3
5
  // @ts-check
4
6
  require('@travetto/compiler/bin/entry.common.js')
5
- .load(ops => ops.exec('@travetto/cli/support/entry.trv.js'));
7
+ .load(operations => operations.exec('@travetto/cli/support/entry.trv.js'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/cli",
3
- "version": "7.0.0-rc.1",
3
+ "version": "7.0.0-rc.3",
4
4
  "description": "CLI infrastructure for Travetto framework",
5
5
  "keywords": [
6
6
  "cli",
@@ -28,8 +28,8 @@
28
28
  "directory": "module/cli"
29
29
  },
30
30
  "dependencies": {
31
- "@travetto/schema": "^7.0.0-rc.1",
32
- "@travetto/terminal": "^7.0.0-rc.1"
31
+ "@travetto/schema": "^7.0.0-rc.3",
32
+ "@travetto/terminal": "^7.0.0-rc.3"
33
33
  },
34
34
  "travetto": {
35
35
  "displayName": "Command Line Interface",
package/src/error.ts CHANGED
@@ -21,9 +21,9 @@ const COMMAND_PACKAGE = [
21
21
  export class CliUnknownCommandError extends Error {
22
22
 
23
23
  #getMissingCommandHelp(cmd: string): string | undefined {
24
- const matchedCfg = COMMAND_PACKAGE.find(([re]) => re.test(cmd));
25
- if (matchedCfg) {
26
- const [, pkg, prod] = matchedCfg;
24
+ const matchedConfig = COMMAND_PACKAGE.find(([regex]) => regex.test(cmd));
25
+ if (matchedConfig) {
26
+ const [, pkg, prod] = matchedConfig;
27
27
  const install = PackageUtil.getInstallCommand(Runtime, `@travetto/${pkg}`, prod);
28
28
  return cliTpl`
29
29
  ${{ title: 'Missing Package' }}\n${'-'.repeat(20)}\nTo use ${{ input: cmd }} please run:\n
package/src/execute.ts CHANGED
@@ -13,20 +13,20 @@ import { CliCommandShape } from './types.ts';
13
13
  export class ExecutionManager {
14
14
 
15
15
  /** Error handler */
16
- static async #onError(err: unknown): Promise<void> {
16
+ static async #onError(error: unknown): Promise<void> {
17
17
  process.exitCode ??= 1;
18
- if (err instanceof CliValidationResultError) {
19
- console.error!(await HelpUtil.renderValidationError(err));
20
- console.error!(await HelpUtil.renderCommandHelp(err.command));
21
- } else if (err instanceof CliUnknownCommandError) {
22
- if (err.help) {
23
- console.error!(err.help);
18
+ if (error instanceof CliValidationResultError) {
19
+ console.error!(await HelpUtil.renderValidationError(error));
20
+ console.error!(await HelpUtil.renderCommandHelp(error.command));
21
+ } else if (error instanceof CliUnknownCommandError) {
22
+ if (error.help) {
23
+ console.error!(error.help);
24
24
  } else {
25
- console.error!(err.defaultMessage, '\n');
25
+ console.error!(error.defaultMessage, '\n');
26
26
  console.error!(await HelpUtil.renderAllHelp(''));
27
27
  }
28
28
  } else {
29
- console.error!(err);
29
+ console.error!(error);
30
30
  }
31
31
  console.error!();
32
32
  }
@@ -72,8 +72,8 @@ export class ExecutionManager {
72
72
  } else {
73
73
  await this.#runCommand(cmd, args);
74
74
  }
75
- } catch (err) {
76
- await this.#onError(err);
75
+ } catch (error) {
76
+ await this.#onError(error);
77
77
  } finally {
78
78
  await ShutdownManager.gracefulShutdown('@travetto/cli:execute');
79
79
  }
package/src/help.ts CHANGED
@@ -14,8 +14,8 @@ const validationSourceMap: Record<string, string> = {
14
14
  flag: 'Flag'
15
15
  };
16
16
 
17
- const ifDefined = <T>(v: T | null | '' | undefined): T | undefined =>
18
- (v === null || v === '' || v === undefined) ? undefined : v;
17
+ const ifDefined = <T>(value: T | null | '' | undefined): T | undefined =>
18
+ (value === null || value === '' || value === undefined) ? undefined : value;
19
19
 
20
20
  /**
21
21
  * Utilities for showing help
@@ -47,11 +47,11 @@ export class HelpUtil {
47
47
 
48
48
  for (const field of Object.values(schema.fields)) {
49
49
  const key = castKey<CliCommandShape>(field.name);
50
- const def = ifDefined(command[key]) ?? ifDefined(field.default);
50
+ const defaultValue = ifDefined(command[key]) ?? ifDefined(field.default);
51
51
  const aliases = (field.aliases ?? [])
52
- .filter(x => x.startsWith('-'))
53
- .filter(x =>
54
- (field.type !== Boolean) || ((def !== true || field.name === 'help') ? !x.startsWith('--no-') : x.startsWith('--'))
52
+ .filter(flag => flag.startsWith('-'))
53
+ .filter(flag =>
54
+ (field.type !== Boolean) || ((defaultValue !== true || field.name === 'help') ? !flag.startsWith('--no-') : flag.startsWith('--'))
55
55
  );
56
56
  let type: string | undefined;
57
57
 
@@ -69,14 +69,14 @@ export class HelpUtil {
69
69
  params.push(param.join(' '));
70
70
  const desc = [cliTpl`${{ title: field.description }}`];
71
71
 
72
- if (key !== 'help' && def !== undefined) {
73
- desc.push(cliTpl`(default: ${{ input: JSON.stringify(def) }})`);
72
+ if (key !== 'help' && defaultValue !== undefined) {
73
+ desc.push(cliTpl`(default: ${{ input: JSON.stringify(defaultValue) }})`);
74
74
  }
75
75
  descriptions.push(desc.join(' '));
76
76
  }
77
77
 
78
- const paramWidths = params.map(x => util.stripVTControlCharacters(x).length);
79
- const descWidths = descriptions.map(x => util.stripVTControlCharacters(x).length);
78
+ const paramWidths = params.map(item => util.stripVTControlCharacters(item).length);
79
+ const descWidths = descriptions.map(item => util.stripVTControlCharacters(item).length);
80
80
 
81
81
  const paramWidth = Math.max(...paramWidths);
82
82
  const descWidth = Math.max(...descWidths);
@@ -95,7 +95,7 @@ export class HelpUtil {
95
95
  ),
96
96
  '',
97
97
  ...helpText
98
- ].map(x => x.trimEnd()).join('\n');
98
+ ].map(line => line.trimEnd()).join('\n');
99
99
  }
100
100
 
101
101
  /**
@@ -113,11 +113,11 @@ export class HelpUtil {
113
113
  if (schema && !schema.private) {
114
114
  rows.push(cliTpl` ${{ param: cmd.padEnd(maxWidth, ' ') }} ${{ title: schema.description || '' }}`);
115
115
  }
116
- } catch (err) {
117
- if (err instanceof Error) {
118
- rows.push(cliTpl` ${{ param: cmd.padEnd(maxWidth, ' ') }} ${{ failure: err.message.split(/\n/)[0] }}`);
116
+ } catch (error) {
117
+ if (error instanceof Error) {
118
+ rows.push(cliTpl` ${{ param: cmd.padEnd(maxWidth, ' ') }} ${{ failure: error.message.split(/\n/)[0] }}`);
119
119
  } else {
120
- throw err;
120
+ throw error;
121
121
  }
122
122
  }
123
123
  }
@@ -126,20 +126,20 @@ export class HelpUtil {
126
126
 
127
127
  lines.unshift(title ? cliTpl`${{ title }}` : cliTpl`${{ title: 'Usage:' }} ${{ param: '[options]' }} ${{ param: '[command]' }}`, '');
128
128
 
129
- return lines.map(x => x.trimEnd()).join('\n');
129
+ return lines.map(line => line.trimEnd()).join('\n');
130
130
  }
131
131
 
132
132
  /**
133
133
  * Render validation error to a string
134
134
  */
135
- static renderValidationError(err: CliValidationResultError): string {
135
+ static renderValidationError(validationError: CliValidationResultError): string {
136
136
  return [
137
137
  cliTpl`${{ failure: 'Execution failed' }}:`,
138
- ...err.details.errors.map(e => {
139
- if (e.source && e.source in validationSourceMap) {
140
- return cliTpl` * ${{ identifier: validationSourceMap[e.source] }} ${{ subtitle: e.message }}`;
138
+ ...validationError.details.errors.map(error => {
139
+ if (error.source && error.source in validationSourceMap) {
140
+ return cliTpl` * ${{ identifier: validationSourceMap[error.source] }} ${{ subtitle: error.message }}`;
141
141
  }
142
- return cliTpl` * ${{ failure: e.message }}`;
142
+ return cliTpl` * ${{ failure: error.message }}`;
143
143
  }),
144
144
  '',
145
145
  ].join('\n');
package/src/module.ts CHANGED
@@ -47,41 +47,41 @@ export class CliModuleUtil {
47
47
  static async findModules(mode: 'all' | 'changed' | 'workspace', fromHash?: string, toHash?: string): Promise<IndexedModule[]> {
48
48
  return (mode === 'changed' ?
49
49
  await this.findChangedModulesRecursive(fromHash, toHash, true) :
50
- [...RuntimeIndex.getModuleList(mode)].map(x => RuntimeIndex.getModule(x)!)
51
- ).filter(x => x.sourcePath !== Runtime.workspace.path);
50
+ [...RuntimeIndex.getModuleList(mode)].map(name => RuntimeIndex.getModule(name)!)
51
+ ).filter(mod => mod.sourcePath !== Runtime.workspace.path);
52
52
  }
53
53
 
54
54
  /**
55
55
  * Get module dependency graph, fully collapsed
56
56
  */
57
- static getDependencyGraph(mods: IndexedModule[]): Record<string, string[]> {
57
+ static getDependencyGraph(modules: IndexedModule[]): Record<string, string[]> {
58
58
  const childMap: Map<string, ModuleGraphEntry> = new Map();
59
59
  const get = (name: string): ModuleGraphEntry =>
60
60
  childMap.has(name) ? childMap.get(name)! : childMap.set(name, { children: new Set(), name, active: new Set() }).get(name)!;
61
61
 
62
- for (const el of mods) {
63
- get(el.name).parents = el.parents;
64
- for (const dep of el.parents) {
65
- const par = get(dep);
66
- par.children.add(el.name); // Store child into parent
67
- par.active.add(el.name);
62
+ for (const mod of modules) {
63
+ get(mod.name).parents = mod.parents;
64
+ for (const parentModule of mod.parents) {
65
+ const parent = get(parentModule);
66
+ parent.children.add(mod.name); // Store child into parent
67
+ parent.active.add(mod.name);
68
68
  }
69
69
  }
70
70
 
71
71
  const output: Record<string, string[]> = {};
72
72
 
73
73
  while (childMap.size > 0) {
74
- for (const el of [...childMap.values()].filter(x => x.active.size === 0)) {
75
- output[el.name] = [...el.children];
76
- for (const parent of el.parents ?? []) {
74
+ for (const item of [...childMap.values()].filter(entry => entry.active.size === 0)) {
75
+ output[item.name] = [...item.children];
76
+ for (const parent of item.parents ?? []) {
77
77
  const par = childMap.get(parent)!;
78
78
  // Extend children into parents
79
- for (const val of el.children) {
80
- par.children.add(val);
79
+ for (const child of item.children) {
80
+ par.children.add(child);
81
81
  }
82
- par.active.delete(el.name);
82
+ par.active.delete(item.name);
83
83
  }
84
- childMap.delete(el.name);
84
+ childMap.delete(item.name);
85
85
  }
86
86
  }
87
87
  return output;
@@ -106,16 +106,16 @@ export class CliModuleUtil {
106
106
  if (config.since) {
107
107
  try {
108
108
  const files = await CliScmUtil.findChangedFiles(config.since, 'HEAD');
109
- return files.filter(x => !x.endsWith('package.json') && !x.endsWith('package-lock.json'));
110
- } catch (err) {
111
- if (config.logError && err instanceof Error) {
112
- console.error(err.message);
109
+ return files.filter(file => !file.endsWith('package.json') && !file.endsWith('package-lock.json'));
110
+ } catch (error) {
111
+ if (config.logError && error instanceof Error) {
112
+ console.error(error.message);
113
113
  }
114
114
  return [];
115
115
  }
116
116
  } else {
117
117
  const mods = await this.findModules(config.changed ? 'changed' : 'workspace', undefined, 'HEAD');
118
- return mods.map(x => x.sourcePath);
118
+ return mods.map(mod => mod.sourcePath);
119
119
  }
120
120
  }
121
121
  }
package/src/parse.ts CHANGED
@@ -16,7 +16,7 @@ const CONFIG_PRE = '+=';
16
16
  const SPACE = new Set([32, 7, 13, 10]);
17
17
 
18
18
  export const ENV_PREFIX = 'env.';
19
- export const isBoolFlag = (x?: SchemaInputConfig): boolean => x?.type === Boolean && !x.array;
19
+ export const isBoolFlag = (value?: SchemaInputConfig): boolean => value?.type === Boolean && !value.array;
20
20
 
21
21
  export type AliasesParseResult = Record<'long' | 'short' | 'raw' | 'env', string[]>;
22
22
 
@@ -25,8 +25,8 @@ export type AliasesParseResult = Record<'long' | 'short' | 'raw' | 'env', string
25
25
  */
26
26
  export class CliParseUtil {
27
27
 
28
- static toEnvField(k: string): string {
29
- return k.startsWith(ENV_PREFIX) ? k : `${ENV_PREFIX}${k}`;
28
+ static toEnvField(key: string): string {
29
+ return key.startsWith(ENV_PREFIX) ? key : `${ENV_PREFIX}${key}`;
30
30
  }
31
31
 
32
32
  static readToken(text: string, start = 0): { next: number, value?: string } {
@@ -69,13 +69,13 @@ export class CliParseUtil {
69
69
  */
70
70
  static getSpecifiedModule(schema: SchemaClassConfig, args: string[]): string | undefined {
71
71
  const SEP = args.includes(RAW_SEP) ? args.indexOf(RAW_SEP) : args.length;
72
- const input = Object.values(schema.fields).find(x => x.specifiers?.includes('module'));
73
- const ENV_KEY = input?.aliases?.filter(x => x.startsWith(ENV_PREFIX)).map(x => x.replace(ENV_PREFIX, ''))[0] ?? '';
72
+ const input = Object.values(schema.fields).find(config => config.specifiers?.includes('module'));
73
+ const ENV_KEY = input?.aliases?.filter(alias => alias.startsWith(ENV_PREFIX)).map(alias => alias.replace(ENV_PREFIX, ''))[0] ?? '';
74
74
  const flags = new Set(input?.aliases ?? []);
75
- const check = (k?: string, v?: string): string | undefined => flags.has(k!) ? v : undefined;
75
+ const check = (key?: string, value?: string): string | undefined => flags.has(key!) ? value : undefined;
76
76
  return args.reduce(
77
- (m, x, i, arr) =>
78
- (i < SEP ? check(arr[i - 1], x) ?? check(...x.split('=')) : undefined) ?? m,
77
+ (name, value, i, values) =>
78
+ (i < SEP ? check(values[i - 1], value) ?? check(...value.split('=')) : undefined) ?? name,
79
79
  process.env[ENV_KEY]
80
80
  );
81
81
  }
@@ -88,10 +88,10 @@ export class CliParseUtil {
88
88
  const overrides = { '@': mod ?? Runtime.main.name };
89
89
 
90
90
  // We have a file
91
- const rel = (key.includes('/') ? key : `@#support/pack.${key}.flags`)
91
+ const relativePath = (key.includes('/') ? key : `@#support/pack.${key}.flags`)
92
92
  .replace(/^(@[^#]*)#(.*)$/, (_, imp, rest) => `${Runtime.modulePath(imp, overrides)}/${rest}`);
93
93
 
94
- const file = path.resolve(rel);
94
+ const file = path.resolve(relativePath);
95
95
 
96
96
  if (!await fs.stat(file).catch(() => false)) {
97
97
  throw new Error(`Missing flag file: ${key}, unable to proceed`);
@@ -122,10 +122,10 @@ export class CliParseUtil {
122
122
  const max = out.includes(RAW_SEP) ? out.indexOf(RAW_SEP) : out.length;
123
123
  const valid = out.slice(0, max);
124
124
  const cmd = valid.length > 0 && !valid[0].startsWith('-') ? valid[0] : undefined;
125
- const helpIdx = valid.findIndex(x => HELP_FLAG.test(x));
125
+ const helpIdx = valid.findIndex(flag => HELP_FLAG.test(flag));
126
126
  const args = out.slice(cmd ? 1 : 0);
127
- const res = { cmd, args, help: helpIdx >= 0 };
128
- return res;
127
+ const result = { cmd, args, help: helpIdx >= 0 };
128
+ return result;
129
129
  }
130
130
 
131
131
  /**
@@ -134,8 +134,8 @@ export class CliParseUtil {
134
134
  static async expandArgs(schema: SchemaClassConfig, args: string[]): Promise<string[]> {
135
135
  const SEP = args.includes(RAW_SEP) ? args.indexOf(RAW_SEP) : args.length;
136
136
  const mod = this.getSpecifiedModule(schema, args);
137
- return (await Promise.all(args.map((x, i) =>
138
- x.startsWith(CONFIG_PRE) && (i < SEP || SEP < 0) ? this.readFlagFile(x, mod) : x))).flat();
137
+ return (await Promise.all(args.map((arg, i) =>
138
+ arg.startsWith(CONFIG_PRE) && (i < SEP || SEP < 0) ? this.readFlagFile(arg, mod) : arg))).flat();
139
139
  }
140
140
 
141
141
  /**
@@ -143,21 +143,21 @@ export class CliParseUtil {
143
143
  */
144
144
  static async parse(schema: SchemaClassConfig, inputs: string[]): Promise<ParsedState> {
145
145
  const flagMap = new Map<string, SchemaFieldConfig>(
146
- Object.values(schema.fields).flatMap(f => (f.aliases ?? []).map(name => [name, f]))
146
+ Object.values(schema.fields).flatMap(field => (field.aliases ?? []).map(name => [name, field]))
147
147
  );
148
148
 
149
149
  const out: ParsedInput[] = [];
150
150
 
151
151
  // Load env vars to front
152
152
  for (const field of Object.values(schema.fields)) {
153
- for (const envName of (field.aliases ?? []).filter(x => x.startsWith(ENV_PREFIX))) {
153
+ for (const envName of (field.aliases ?? []).filter(alias => alias.startsWith(ENV_PREFIX))) {
154
154
  const simple = envName.replace(ENV_PREFIX, '');
155
155
  if (simple in process.env) {
156
156
  const value: string = process.env[simple]!;
157
157
  if (field.array) {
158
- out.push(...value.split(/\s*,\s*/g).map(v => ({ type: 'flag', fieldName: field.name.toString(), input: envName, value: v }) as const));
158
+ out.push(...value.split(/\s*,\s*/g).map(item => ({ type: 'flag', fieldName: field.name, input: envName, value: item }) as const));
159
159
  } else {
160
- out.push({ type: 'flag', fieldName: field.name.toString(), input: envName, value });
160
+ out.push({ type: 'flag', fieldName: field.name, input: envName, value });
161
161
  }
162
162
  }
163
163
  }
@@ -169,13 +169,13 @@ export class CliParseUtil {
169
169
  const input = inputs[i];
170
170
 
171
171
  if (input === RAW_SEP) { // Raw separator
172
- out.push(...inputs.slice(i + 1).map((x, idx) => ({ type: 'unknown', input: x, index: argIdx + idx }) as const));
172
+ out.push(...inputs.slice(i + 1).map((arg, idx) => ({ type: 'unknown', input: arg, index: argIdx + idx }) as const));
173
173
  break;
174
174
  } else if (LONG_FLAG_WITH_EQ.test(input)) {
175
- const [k, ...v] = input.split('=');
176
- const field = flagMap.get(k);
175
+ const [key, ...values] = input.split('=');
176
+ const field = flagMap.get(key);
177
177
  if (field) {
178
- out.push({ type: 'flag', fieldName: field.name.toString(), input: k, value: v.join('=') });
178
+ out.push({ type: 'flag', fieldName: field.name, input: key, value: values.join('=') });
179
179
  } else {
180
180
  out.push({ type: 'unknown', input });
181
181
  }
@@ -185,7 +185,7 @@ export class CliParseUtil {
185
185
  out.push({ type: 'unknown', input });
186
186
  } else {
187
187
  const next = inputs[i + 1];
188
- const base = { type: 'flag', fieldName: field.name.toString(), input, array: field.array } as const;
188
+ const base = { type: 'flag', fieldName: field.name, input, array: field.array } as const;
189
189
  if ((next && (VALID_FLAG.test(next) || next === RAW_SEP)) || isBoolFlag(field)) {
190
190
  if (isBoolFlag(field)) {
191
191
  out.push({ ...base, value: !input.startsWith('--no-') });
@@ -211,8 +211,8 @@ export class CliParseUtil {
211
211
  return {
212
212
  inputs,
213
213
  all: out,
214
- unknown: out.filter(x => x.type === 'unknown').map(x => x.input),
215
- flags: out.filter(x => x.type === 'flag')
214
+ unknown: out.filter(input => input.type === 'unknown').map(input => input.input),
215
+ flags: out.filter(input => input.type === 'flag')
216
216
  };
217
217
  }
218
218
 
@@ -220,19 +220,19 @@ export class CliParseUtil {
220
220
  * Parse aliases into categories for registration
221
221
  */
222
222
  static parseAliases(aliases: string[]): AliasesParseResult {
223
- return aliases.reduce<AliasesParseResult>((acc, curr) => {
224
- if (VALID_FLAG.test(curr)) {
225
- if (curr.startsWith('--')) {
226
- acc.long.push(curr);
223
+ return aliases.reduce<AliasesParseResult>((result, alias) => {
224
+ if (VALID_FLAG.test(alias)) {
225
+ if (alias.startsWith('--')) {
226
+ result.long.push(alias);
227
227
  } else {
228
- acc.short.push(curr);
228
+ result.short.push(alias);
229
229
  }
230
- } else if (curr.startsWith(ENV_PREFIX)) {
231
- acc.env.push(curr);
230
+ } else if (alias.startsWith(ENV_PREFIX)) {
231
+ result.env.push(alias);
232
232
  } else {
233
- acc.raw.push(curr);
233
+ result.raw.push(alias);
234
234
  }
235
- return acc;
235
+ return result;
236
236
  }, { long: [], short: [], raw: [], env: [] });
237
237
  }
238
238
  }
@@ -19,8 +19,8 @@ type CliCommandConfigOptions = {
19
19
  module?: boolean;
20
20
  /** Should debug invocation trigger via ipc */
21
21
  debugIpc?: boolean;
22
- /** Should the invocation automatically restart on exit */
23
- canRestart?: boolean;
22
+ /** Should restart on code change */
23
+ restartForDev?: boolean;
24
24
  };
25
25
  };
26
26
 
@@ -53,7 +53,7 @@ const FIELD_CONFIG: {
53
53
  },
54
54
  {
55
55
  name: 'debugIpc',
56
- run: cmd => CliUtil.debugIfIpc(cmd).then((v) => v && process.exit(0)),
56
+ run: cmd => CliUtil.debugIfIpc(cmd).then((executed) => executed && process.exit(0)),
57
57
  field: {
58
58
  type: Boolean,
59
59
  aliases: ['-di'],
@@ -63,13 +63,13 @@ const FIELD_CONFIG: {
63
63
  },
64
64
  },
65
65
  {
66
- name: 'canRestart',
67
- run: cmd => CliUtil.runWithRestart(cmd)?.then((v) => v && process.exit(0)),
66
+ name: 'restartForDev',
67
+ run: cmd => CliUtil.runWithRestartOnCodeChanges(cmd),
68
68
  field: {
69
69
  type: Boolean,
70
70
  aliases: ['-cr'],
71
- description: 'Should the invocation automatically restart on exit',
72
- default: false,
71
+ description: 'Should the invocation automatically restart on source changes',
72
+ default: Runtime.env === 'development',
73
73
  required: { active: false },
74
74
  },
75
75
  }
@@ -82,20 +82,19 @@ const FIELD_CONFIG: {
82
82
  * @example main
83
83
  * @kind decorator
84
84
  */
85
- export function CliCommand(cfg: CliCommandConfigOptions = {}) {
85
+ export function CliCommand(config: CliCommandConfigOptions = {}) {
86
86
  return function <T extends CliCommandShape>(target: Class<T>): void {
87
87
  const adapter = SchemaRegistryIndex.getForRegister(target);
88
88
  const description = describeFunction(target) ?? {};
89
89
 
90
-
91
90
  if (!target.Ⲑid || description.abstract) {
92
91
  return;
93
92
  }
94
93
 
95
- const VALID_FIELDS = FIELD_CONFIG.filter(f => !!cfg.with?.[f.name]);
94
+ const VALID_FIELDS = FIELD_CONFIG.filter(field => !!config.with?.[field.name]);
96
95
 
97
96
  CliCommandRegistryIndex.getForRegister(target).register({
98
- runTarget: cfg.runTarget,
97
+ runTarget: config.runTarget,
99
98
  preMain: async (cmd: Cmd) => {
100
99
  for (const field of VALID_FIELDS) {
101
100
  await field.run(cmd);
@@ -109,7 +108,7 @@ export function CliCommand(cfg: CliCommandConfigOptions = {}) {
109
108
  adapter.registerField(name, field, { type });
110
109
  }
111
110
 
112
- const runtimeModule = cfg.runtimeModule ?? (cfg.with?.module ? 'current' : undefined);
111
+ const runtimeModule = config.runtimeModule ?? (config.with?.module ? 'current' : undefined);
113
112
 
114
113
  if (runtimeModule) { // Validate module
115
114
  adapter.register({
@@ -139,14 +138,14 @@ export function CliCommand(cfg: CliCommandConfigOptions = {}) {
139
138
  * @augments `@travetto/schema:Input`
140
139
  * @kind decorator
141
140
  */
142
- export function CliFlag(cfg: { full?: string, short?: string, fileExtensions?: string[], envVars?: string[] } = {}) {
143
- return function (instance: ClassInstance, property: string | symbol): void {
141
+ export function CliFlag(config: { full?: string, short?: string, fileExtensions?: string[], envVars?: string[] } = {}) {
142
+ return function (instance: ClassInstance, property: string): void {
144
143
  const aliases = [
145
- ...(cfg.full ? [cfg.full.startsWith('-') ? cfg.full : `--${cfg.full}`] : []),
146
- ...(cfg.short ? [cfg.short.startsWith('-') ? cfg.short : `-${cfg.short}`] : []),
147
- ...(cfg.envVars ? cfg.envVars.map(CliParseUtil.toEnvField) : [])
144
+ ...(config.full ? [config.full.startsWith('-') ? config.full : `--${config.full}`] : []),
145
+ ...(config.short ? [config.short.startsWith('-') ? config.short : `-${config.short}`] : []),
146
+ ...(config.envVars ? config.envVars.map(CliParseUtil.toEnvField) : [])
148
147
  ];
149
- const specifiers = cfg.fileExtensions?.length ? ['file', ...cfg.fileExtensions.map(x => `ext:${x.replace(/[*.]/g, '')}`)] : [];
148
+ const specifiers = config.fileExtensions?.length ? ['file', ...config.fileExtensions.map(ext => `ext:${ext.replace(/[*.]/g, '')}`)] : [];
150
149
 
151
150
  SchemaRegistryIndex.getForRegister(getClass(instance)).registerField(property, { aliases, specifiers });
152
151
  };
@@ -7,9 +7,9 @@ import { CliParseUtil, ENV_PREFIX } from '../parse.ts';
7
7
 
8
8
  const CLI_FILE_REGEX = /\/cli[.](?<name>.{0,100}?)([.]tsx?)?$/;
9
9
 
10
- const getName = (s: string): string => (s.match(CLI_FILE_REGEX)?.groups?.name ?? s).replaceAll('_', ':');
11
- const stripDashes = (x?: string): string | undefined => x?.replace(/^-+/, '');
12
- const toFlagName = (x: string): string => x.replace(/([a-z])([A-Z])/g, (_, l: string, r: string) => `${l}-${r.toLowerCase()}`);
10
+ const getName = (name: string): string => (name.match(CLI_FILE_REGEX)?.groups?.name ?? name).replaceAll('_', ':');
11
+ const stripDashes = (flag?: string): string | undefined => flag?.replace(/^-+/, '');
12
+ const toFlagName = (field: string): string => field.replace(/([a-z])([A-Z])/g, (_, left: string, right: string) => `${left}-${right.toLowerCase()}`);
13
13
 
14
14
  export class CliCommandRegistryAdapter implements RegistryAdapter<CliCommandConfig> {
15
15
  #cls: Class;
@@ -27,7 +27,7 @@ export class CliCommandRegistryAdapter implements RegistryAdapter<CliCommandConf
27
27
  (schema.fields ??= {}).help = {
28
28
  type: Boolean,
29
29
  name: 'help',
30
- owner: this.#cls,
30
+ class: this.#cls,
31
31
  description: 'display help for command',
32
32
  required: { active: false },
33
33
  default: false,
@@ -36,17 +36,17 @@ export class CliCommandRegistryAdapter implements RegistryAdapter<CliCommandConf
36
36
  };
37
37
 
38
38
  const used = new Set(Object.values(schema.fields)
39
- .flatMap(f => f.aliases ?? [])
40
- .filter(x => !x.startsWith(ENV_PREFIX))
39
+ .flatMap(field => field.aliases ?? [])
40
+ .filter(alias => !alias.startsWith(ENV_PREFIX))
41
41
  .map(stripDashes)
42
42
  );
43
43
 
44
44
  for (const field of Object.values(schema.fields)) {
45
- const fieldName = field.name.toString();
45
+ const fieldName = field.name;
46
46
  const { long: longAliases, short: shortAliases, raw: rawAliases, env: envAliases } = CliParseUtil.parseAliases(field.aliases ?? []);
47
47
 
48
- let short = stripDashes(shortAliases?.[0]) ?? rawAliases.find(x => x.length <= 2);
49
- const long = stripDashes(longAliases?.[0]) ?? rawAliases.find(x => x.length >= 3) ?? toFlagName(fieldName);
48
+ let short = stripDashes(shortAliases?.[0]) ?? rawAliases.find(alias => alias.length <= 2);
49
+ const long = stripDashes(longAliases?.[0]) ?? rawAliases.find(alias => alias.length >= 3) ?? toFlagName(fieldName);
50
50
  const aliases: string[] = field.aliases = [...envAliases];
51
51
 
52
52
  if (short === undefined) {
@@ -74,14 +74,14 @@ export class CliCommandRegistryAdapter implements RegistryAdapter<CliCommandConf
74
74
  /**
75
75
  * Registers a cli command
76
76
  */
77
- register(...cfg: Partial<CliCommandConfig>[]): CliCommandConfig {
77
+ register(...configs: Partial<CliCommandConfig>[]): CliCommandConfig {
78
78
  const meta = describeFunction(this.#cls);
79
79
  this.#config ??= {
80
80
  cls: this.#cls,
81
81
  preMain: undefined,
82
82
  name: getName(meta.import),
83
83
  };
84
- Object.assign(this.#config, ...cfg);
84
+ Object.assign(this.#config, ...configs);
85
85
  return this.#config;
86
86
  }
87
87