@travetto/cli 7.0.0-rc.1 → 7.0.0-rc.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.
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
 
package/bin/trv.js CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  // @ts-check
4
4
  require('@travetto/compiler/bin/entry.common.js')
5
- .load(ops => ops.exec('@travetto/cli/support/entry.trv.js'));
5
+ .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.2",
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.2",
32
+ "@travetto/terminal": "^7.0.0-rc.2"
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(([re]) => re.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
  }
@@ -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((flag) => flag && process.exit(0)),
57
57
  field: {
58
58
  type: Boolean,
59
59
  aliases: ['-di'],
@@ -64,7 +64,7 @@ const FIELD_CONFIG: {
64
64
  },
65
65
  {
66
66
  name: 'canRestart',
67
- run: cmd => CliUtil.runWithRestart(cmd)?.then((v) => v && process.exit(0)),
67
+ run: cmd => CliUtil.runWithRestart(cmd)?.then((flag) => flag && process.exit(0)),
68
68
  field: {
69
69
  type: Boolean,
70
70
  aliases: ['-cr'],
@@ -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;
@@ -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
 
@@ -7,7 +7,7 @@ import { CliUnknownCommandError } from '../error.ts';
7
7
  import { CliCommandRegistryAdapter } from './registry-adapter.ts';
8
8
 
9
9
  const CLI_FILE_REGEX = /\/cli[.](?<name>.{0,100}?)([.]tsx?)?$/;
10
- const getName = (s: string): string => (s.match(CLI_FILE_REGEX)?.groups?.name ?? s).replaceAll('_', ':');
10
+ const getName = (field: string): string => (field.match(CLI_FILE_REGEX)?.groups?.name ?? field).replaceAll('_', ':');
11
11
 
12
12
  type CliCommandLoadResult = { command: string, config: CliCommandConfig, instance: CliCommandShape, schema: SchemaClassConfig };
13
13
 
@@ -38,12 +38,12 @@ export class CliCommandRegistryIndex implements RegistryIndex {
38
38
  get #commandMapping(): Map<string, string> {
39
39
  if (!this.#fileMapping) {
40
40
  const all = new Map<string, string>();
41
- for (const e of RuntimeIndex.find({
42
- module: m => !Runtime.production || m.prod,
43
- folder: f => f === 'support',
44
- file: f => f.role === 'std' && CLI_FILE_REGEX.test(f.sourceFile)
41
+ for (const entry of RuntimeIndex.find({
42
+ module: mod => !Runtime.production || mod.prod,
43
+ folder: folder => folder === 'support',
44
+ file: file => file.role === 'std' && CLI_FILE_REGEX.test(file.sourceFile)
45
45
  })) {
46
- all.set(getName(e.sourceFile), e.import);
46
+ all.set(getName(entry.sourceFile), entry.import);
47
47
  }
48
48
  this.#fileMapping = all;
49
49
  }
@@ -70,32 +70,32 @@ export class CliCommandRegistryIndex implements RegistryIndex {
70
70
  const found = this.#commandMapping.get(name)!;
71
71
  const values = Object.values(await Runtime.importFrom<Record<string, Class>>(found));
72
72
  const filtered = values
73
- .filter((v): v is Class => typeof v === 'function')
74
- .reduce<Class[]>((acc, v) => {
75
- const parent = getParentClass(v);
76
- if (parent && !acc.includes(parent)) {
77
- acc.push(parent);
73
+ .filter((value): value is Class => typeof value === 'function')
74
+ .reduce<Class[]>((classes, cls) => {
75
+ const parent = getParentClass(cls);
76
+ if (parent && !classes.includes(parent)) {
77
+ classes.push(parent);
78
78
  }
79
- acc.push(v);
80
- return acc;
79
+ classes.push(cls);
80
+ return classes;
81
81
  }, []);
82
82
 
83
83
  const uninitialized = filtered
84
- .filter(v => !this.store.finalized(v));
84
+ .filter(cls => !this.store.finalized(cls));
85
85
 
86
86
 
87
87
  // Initialize any uninitialized commands
88
88
  if (uninitialized.length) {
89
89
  // Ensure processed
90
- Registry.process(uninitialized.map(v => ({ type: 'added', curr: v })));
90
+ Registry.process(uninitialized.map(cls => ({ type: 'added', current: cls })));
91
91
  }
92
92
 
93
- for (const v of values) {
94
- const cfg = this.store.get(v);
95
- if (!cfg) {
93
+ for (const cls of values) {
94
+ const config = this.store.get(cls);
95
+ if (!config) {
96
96
  continue;
97
97
  }
98
- const result = cfg.getInstance();
98
+ const result = config.getInstance();
99
99
  if (result.isActive !== undefined && !result.isActive()) {
100
100
  continue;
101
101
  }
@@ -112,11 +112,11 @@ export class CliCommandRegistryIndex implements RegistryIndex {
112
112
  async load(names?: string[]): Promise<CliCommandLoadResult[]> {
113
113
  const keys = names ?? [...this.#commandMapping.keys()];
114
114
 
115
- const list = await Promise.all(keys.map(async x => {
116
- const instance = await this.#getInstance(x);
115
+ const list = await Promise.all(keys.map(async key => {
116
+ const instance = await this.#getInstance(key);
117
117
  const config = this.store.get(getClass(instance)).get();
118
118
  const schema = SchemaRegistryIndex.getConfig(getClass(instance));
119
- return { command: x, instance, config, schema };
119
+ return { command: key, instance, config, schema };
120
120
  }));
121
121
 
122
122
  return list.sort((a, b) => a.command.localeCompare(b.command));
@@ -37,18 +37,18 @@ export class CliSchemaExportUtil {
37
37
  /**
38
38
  * Get the base type for a CLI command input
39
39
  */
40
- static baseInputType(x: SchemaInputConfig): Pick<CliCommandInput, 'type' | 'fileExtensions'> {
41
- switch (x.type) {
40
+ static baseInputType(config: SchemaInputConfig): Pick<CliCommandInput, 'type' | 'fileExtensions'> {
41
+ switch (config.type) {
42
42
  case Date: return { type: 'date' };
43
43
  case Boolean: return { type: 'boolean' };
44
44
  case Number: return { type: 'number' };
45
45
  case RegExp: return { type: 'regex' };
46
46
  case String: {
47
47
  switch (true) {
48
- case x.specifiers?.includes('module'): return { type: 'module' };
49
- case x.specifiers?.includes('file'): return {
48
+ case config.specifiers?.includes('module'): return { type: 'module' };
49
+ case config.specifiers?.includes('file'): return {
50
50
  type: 'file',
51
- fileExtensions: x.specifiers?.map(s => s.split('ext:')[1]).filter(s => !!s)
51
+ fileExtensions: config.specifiers?.map(specifier => specifier.split('ext:')[1]).filter(specifier => !!specifier)
52
52
  };
53
53
  }
54
54
  }
@@ -59,30 +59,30 @@ export class CliSchemaExportUtil {
59
59
  /**
60
60
  * Process input configuration for CLI commands
61
61
  */
62
- static processInput(x: SchemaInputConfig): CliCommandInput {
62
+ static processInput(config: SchemaInputConfig): CliCommandInput {
63
63
  return {
64
- ...this.baseInputType(x),
65
- ...(('name' in x && typeof x.name === 'string') ? { name: x.name } : { name: '' }),
66
- description: x.description,
67
- array: x.array,
68
- required: x.required?.active !== false,
69
- choices: x.enum?.values,
70
- default: Array.isArray(x.default) ? x.default.slice(0) : x.default,
71
- flagNames: (x.aliases ?? []).slice(0).filter(v => !v.startsWith('env.')),
72
- envVars: (x.aliases ?? []).slice(0).filter(v => v.startsWith('env.')).map(v => v.replace('env.', ''))
64
+ ...this.baseInputType(config),
65
+ ...(('name' in config && typeof config.name === 'string') ? { name: config.name } : { name: '' }),
66
+ description: config.description,
67
+ array: config.array,
68
+ required: config.required?.active !== false,
69
+ choices: config.enum?.values,
70
+ default: Array.isArray(config.default) ? config.default.slice(0) : config.default,
71
+ flagNames: (config.aliases ?? []).slice(0).filter(value => !value.startsWith('env.')),
72
+ envVars: (config.aliases ?? []).slice(0).filter(value => value.startsWith('env.')).map(value => value.replace('env.', ''))
73
73
  };
74
74
  }
75
75
 
76
76
  static exportSchema(cls: Class): CliCommandSchema {
77
77
  const schema = SchemaRegistryIndex.getConfig(cls);
78
78
  const config = CliCommandRegistryIndex.get(cls);
79
- const processed = Object.values(schema.fields).map(v => this.processInput(v));
79
+ const processed = Object.values(schema.fields).map(value => this.processInput(value));
80
80
  return {
81
81
  name: config.name,
82
82
  module: describeFunction(config.cls).module,
83
83
  description: schema.description,
84
- flags: processed.filter(v => v.flagNames && v.flagNames.length > 0),
85
- args: processed.filter(v => !v.flagNames || v.flagNames.length === 0),
84
+ flags: processed.filter(value => value.flagNames && value.flagNames.length > 0),
85
+ args: processed.filter(value => !value.flagNames || value.flagNames.length === 0),
86
86
  runTarget: config.runTarget ?? false,
87
87
  commandModule: describeFunction(cls).module,
88
88
  };
package/src/schema.ts CHANGED
@@ -57,29 +57,29 @@ export class CliCommandSchemaUtil {
57
57
  */
58
58
  static async validate(cmd: CliCommandShape, args: unknown[]): Promise<typeof cmd> {
59
59
  const cls = getClass(cmd);
60
- const paramNames = SchemaRegistryIndex.get(cls).getMethod('main').parameters.map(x => x.name!);
60
+ const paramNames = SchemaRegistryIndex.get(cls).getMethod('main').parameters.map(config => config.name!);
61
61
 
62
62
  const validators = [
63
63
  (): Promise<void> => SchemaValidator.validate(cls, cmd).then(() => { }),
64
64
  (): Promise<void> => SchemaValidator.validateMethod(cls, 'main', args, paramNames),
65
65
  async (): Promise<void> => {
66
- const res = await cmd.validate?.(...args);
67
- if (res) {
68
- throw new CliValidationResultError(cmd, Array.isArray(res) ? res : [res]);
66
+ const result = await cmd.validate?.(...args);
67
+ if (result) {
68
+ throw new CliValidationResultError(cmd, Array.isArray(result) ? result : [result]);
69
69
  }
70
70
  },
71
71
  ];
72
72
 
73
73
  const SOURCES = ['flag', 'arg', 'custom'] as const;
74
74
 
75
- const results = validators.map((x, i) => x().catch(err => {
76
- if (!(err instanceof CliValidationResultError) && !(err instanceof ValidationResultError)) {
77
- throw err;
75
+ const results = validators.map((validator, i) => validator().catch(error => {
76
+ if (!(error instanceof CliValidationResultError) && !(error instanceof ValidationResultError)) {
77
+ throw error;
78
78
  }
79
- return err.details.errors.map(v => ({ ...v, source: getSource(v.source, SOURCES[i]) }));
79
+ return error.details.errors.map(value => ({ ...value, source: getSource(value.source, SOURCES[i]) }));
80
80
  }));
81
81
 
82
- const errors = (await Promise.all(results)).flatMap(x => (x ?? []));
82
+ const errors = (await Promise.all(results)).flatMap(result => (result ?? []));
83
83
  if (errors.length) {
84
84
  throw new CliValidationResultError(cmd, errors);
85
85
  }
package/src/scm.ts CHANGED
@@ -38,7 +38,7 @@ export class CliScmUtil {
38
38
  const result = await ExecUtil.getResult(spawn('git', ['log', '--pretty=oneline'], { cwd: Runtime.workspace.path }));
39
39
  return result.stdout
40
40
  .split(/\n/)
41
- .find(x => /Publish /.test(x))?.split(/\s+/)?.[0];
41
+ .find(line => /Publish /.test(line))?.split(/\s+/)?.[0];
42
42
  }
43
43
 
44
44
  /**
@@ -47,14 +47,14 @@ export class CliScmUtil {
47
47
  * @returns
48
48
  */
49
49
  static async findChangedFiles(fromHash: string, toHash: string = 'HEAD'): Promise<string[]> {
50
- const ws = Runtime.workspace.path;
51
- const result = await ExecUtil.getResult(spawn('git', ['diff', '--name-only', `${fromHash}..${toHash}`, ':!**/DOC.*', ':!**/README.*'], { cwd: ws }), { catch: true });
50
+ const rootPath = Runtime.workspace.path;
51
+ const result = await ExecUtil.getResult(spawn('git', ['diff', '--name-only', `${fromHash}..${toHash}`, ':!**/DOC.*', ':!**/README.*'], { cwd: rootPath }), { catch: true });
52
52
  if (!result.valid) {
53
53
  throw new AppError('Unable to detect changes between', { category: 'data', details: { fromHash, toHash, output: (result.stderr || result.stdout) } });
54
54
  }
55
55
  const out = new Set<string>();
56
56
  for (const line of result.stdout.split(/\n/g)) {
57
- const entry = RuntimeIndex.getEntry(path.resolve(ws, line));
57
+ const entry = RuntimeIndex.getEntry(path.resolve(rootPath, line));
58
58
  if (entry) {
59
59
  out.add(entry.sourceFile);
60
60
  }
@@ -71,10 +71,10 @@ export class CliScmUtil {
71
71
  static async findChangedModules(fromHash: string, toHash?: string): Promise<IndexedModule[]> {
72
72
  const files = await this.findChangedFiles(fromHash, toHash);
73
73
  const mods = files
74
- .map(x => RuntimeIndex.getFromSource(x))
75
- .filter(x => !!x)
76
- .map(x => RuntimeIndex.getModule(x.module))
77
- .filter(x => !!x);
74
+ .map(file => RuntimeIndex.getFromSource(file))
75
+ .filter(file => !!file)
76
+ .map(file => RuntimeIndex.getModule(file.module))
77
+ .filter(mod => !!mod);
78
78
 
79
79
  return [...new Set(mods)]
80
80
  .toSorted((a, b) => a.name.localeCompare(b.name));
@@ -84,7 +84,7 @@ export class CliScmUtil {
84
84
  * Create a commit
85
85
  */
86
86
  static createCommit(message: string): Promise<string> {
87
- return ExecUtil.getResult(spawn('git', ['commit', '.', '-m', message])).then(r => r.stdout);
87
+ return ExecUtil.getResult(spawn('git', ['commit', '.', '-m', message])).then(result => result.stdout);
88
88
  }
89
89
 
90
90
  /**
@@ -92,7 +92,7 @@ export class CliScmUtil {
92
92
  */
93
93
  static createTag(version: string): Promise<string> {
94
94
  version = version.replace(/[^0-9a-z_\-.]/g, '');
95
- return ExecUtil.getResult(spawn('git', ['tag', '-a', `${version}`, '-m', `Release ${version}`])).then(r => r.stdout);
95
+ return ExecUtil.getResult(spawn('git', ['tag', '-a', `${version}`, '-m', `Release ${version}`])).then(result => result.stdout);
96
96
  }
97
97
 
98
98
  /**
package/src/service.ts CHANGED
@@ -5,11 +5,11 @@ import net from 'node:net';
5
5
 
6
6
  import { ExecUtil, TimeUtil, Util } from '@travetto/runtime';
7
7
 
8
- const ports = (val: number | `${number}:${number}`): [number, number] =>
9
- typeof val === 'number' ?
10
- [val, val] :
8
+ const ports = (value: number | `${number}:${number}`): [number, number] =>
9
+ typeof value === 'number' ?
10
+ [value, value] :
11
11
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
12
- val.split(':').map(x => parseInt(x, 10)) as [number, number];
12
+ value.split(':').map(number => parseInt(number, 10)) as [number, number];
13
13
 
14
14
  type BodyCheck = (body: string) => boolean;
15
15
 
@@ -36,26 +36,26 @@ export type ServiceAction = 'start' | 'stop' | 'status' | 'restart';
36
36
  */
37
37
  export class ServiceRunner {
38
38
 
39
- svc: ServiceDescriptor;
40
- constructor(svc: ServiceDescriptor) { this.svc = svc; }
39
+ #descriptor: ServiceDescriptor;
40
+ constructor(descriptor: ServiceDescriptor) { this.#descriptor = descriptor; }
41
41
 
42
42
  async #isRunning(full = false): Promise<boolean> {
43
- const port = ports(this.svc.port!)[0];
43
+ const port = ports(this.#descriptor.port!)[0];
44
44
  const start = Date.now();
45
- const timeoutMs = TimeUtil.asMillis(full ? this.svc.startupTimeout ?? 5000 : 100);
45
+ const timeoutMs = TimeUtil.asMillis(full ? this.#descriptor.startupTimeout ?? 5000 : 100);
46
46
  while ((Date.now() - start) < timeoutMs) {
47
47
  try {
48
48
  const sock = net.createConnection(port, 'localhost');
49
- await new Promise<void>((res, rej) =>
50
- sock.on('connect', res).on('timeout', rej).on('error', rej)
49
+ await new Promise<void>((resolve, reject) =>
50
+ sock.on('connect', resolve).on('timeout', reject).on('error', reject)
51
51
  ).finally(() => sock.destroy());
52
52
 
53
- if (!this.svc.ready?.url || !full) {
53
+ if (!this.#descriptor.ready?.url || !full) {
54
54
  return true;
55
55
  } else {
56
- const response = await fetch(this.svc.ready.url, { method: 'GET' });
56
+ const response = await fetch(this.#descriptor.ready.url, { method: 'GET' });
57
57
  const text = await response.text();
58
- if (response.ok && (this.svc.ready.test?.(text) ?? true)) {
58
+ if (response.ok && (this.#descriptor.ready.test?.(text) ?? true)) {
59
59
  return true;
60
60
  }
61
61
  }
@@ -68,14 +68,14 @@ export class ServiceRunner {
68
68
  }
69
69
 
70
70
  async #hasImage(): Promise<boolean> {
71
- const result = await ExecUtil.getResult(spawn('docker', ['image', 'inspect', this.svc.image]), { catch: true });
71
+ const result = await ExecUtil.getResult(spawn('docker', ['image', 'inspect', this.#descriptor.image]), { catch: true });
72
72
  return result.valid;
73
73
  }
74
74
 
75
75
  async * #pullImage(): AsyncIterable<string> {
76
- const proc = spawn('docker', ['pull', this.svc.image], { stdio: [0, 'pipe', 'pipe'] });
77
- yield* rl.createInterface(proc.stdout!);
78
- await ExecUtil.getResult(proc);
76
+ const subProcess = spawn('docker', ['pull', this.#descriptor.image], { stdio: [0, 'pipe', 'pipe'] });
77
+ yield* rl.createInterface(subProcess.stdout!);
78
+ await ExecUtil.getResult(subProcess);
79
79
  }
80
80
 
81
81
  async #startContainer(): Promise<string> {
@@ -83,16 +83,16 @@ export class ServiceRunner {
83
83
  'run',
84
84
  '--rm',
85
85
  '--detach',
86
- ...this.svc.privileged ? ['--privileged'] : [],
87
- '--label', `trv-${this.svc.name}`,
88
- ...Object.entries(this.svc.env ?? {}).flatMap(([k, v]) => ['--env', `${k}=${v}`]),
89
- ...this.svc.port ? ['-p', ports(this.svc.port).join(':')] : [],
90
- ...Object.entries(this.svc.volumes ?? {}).flatMap(([k, v]) => ['--volume', `${k}:${v}`]),
91
- this.svc.image,
92
- ...this.svc.args ?? [],
86
+ ...this.#descriptor.privileged ? ['--privileged'] : [],
87
+ '--label', `trv-${this.#descriptor.name}`,
88
+ ...Object.entries(this.#descriptor.env ?? {}).flatMap(([key, value]) => ['--env', `${key}=${value}`]),
89
+ ...this.#descriptor.port ? ['-p', ports(this.#descriptor.port).join(':')] : [],
90
+ ...Object.entries(this.#descriptor.volumes ?? {}).flatMap(([key, value]) => ['--volume', `${key}:${value}`]),
91
+ this.#descriptor.image,
92
+ ...this.#descriptor.args ?? [],
93
93
  ];
94
94
 
95
- for (const item of Object.keys(this.svc.volumes ?? {})) {
95
+ for (const item of Object.keys(this.#descriptor.volumes ?? {})) {
96
96
  await fs.mkdir(item, { recursive: true });
97
97
  }
98
98
 
@@ -100,38 +100,38 @@ export class ServiceRunner {
100
100
  }
101
101
 
102
102
  async #getContainerId(): Promise<string | undefined> {
103
- return (await ExecUtil.getResult(spawn('docker', ['ps', '-q', '--filter', `label=trv-${this.svc.name}`]))).stdout.trim();
103
+ return (await ExecUtil.getResult(spawn('docker', ['ps', '-q', '--filter', `label=trv-${this.#descriptor.name}`]))).stdout.trim();
104
104
  }
105
105
 
106
- async #killContainer(cid: string): Promise<void> {
107
- await ExecUtil.getResult(spawn('docker', ['kill', cid]));
106
+ async #killContainer(containerId: string): Promise<void> {
107
+ await ExecUtil.getResult(spawn('docker', ['kill', containerId]));
108
108
  }
109
109
 
110
- async * action(op: ServiceAction): AsyncIterable<['success' | 'failure' | 'message', string]> {
110
+ async * action(operation: ServiceAction): AsyncIterable<['success' | 'failure' | 'message', string]> {
111
111
  try {
112
- const cid = await this.#getContainerId();
113
- const port = this.svc.port ? ports(this.svc.port)[0] : 0;
114
- const running = !!cid && (!port || await this.#isRunning());
112
+ const containerId = await this.#getContainerId();
113
+ const port = this.#descriptor.port ? ports(this.#descriptor.port)[0] : 0;
114
+ const running = !!containerId && (!port || await this.#isRunning());
115
115
 
116
- if (running && !cid) { // We don't own
117
- return yield [op === 'status' ? 'message' : 'failure', 'Running but not managed'];
116
+ if (running && !containerId) { // We don't own
117
+ return yield [operation === 'status' ? 'message' : 'failure', 'Running but not managed'];
118
118
  }
119
119
 
120
- if (op === 'status') {
121
- return yield !cid ? ['message', 'Not running'] : ['success', `Running ${cid}`];
122
- } else if (op === 'start' && running) {
120
+ if (operation === 'status') {
121
+ return yield !containerId ? ['message', 'Not running'] : ['success', `Running ${containerId}`];
122
+ } else if (operation === 'start' && running) {
123
123
  return yield ['message', 'Skipping, already running'];
124
- } else if (op === 'stop' && !running) {
124
+ } else if (operation === 'stop' && !running) {
125
125
  return yield ['message', 'Skipping, already stopped'];
126
126
  }
127
127
 
128
- if (running && (op === 'restart' || op === 'stop')) {
128
+ if (running && (operation === 'restart' || operation === 'stop')) {
129
129
  yield ['message', 'Stopping'];
130
- await this.#killContainer(cid);
130
+ await this.#killContainer(containerId);
131
131
  yield ['success', 'Stopped'];
132
132
  }
133
133
 
134
- if (op === 'restart' || op === 'start') {
134
+ if (operation === 'restart' || operation === 'start') {
135
135
  if (!await this.#hasImage()) {
136
136
  yield ['message', 'Starting image download'];
137
137
  for await (const line of await this.#pullImage()) {
@@ -144,7 +144,7 @@ export class ServiceRunner {
144
144
  const out = await this.#startContainer();
145
145
 
146
146
  if (port) {
147
- yield ['message', `Waiting for ${this.svc.ready?.url ?? 'container'}...`];
147
+ yield ['message', `Waiting for ${this.#descriptor.ready?.url ?? 'container'}...`];
148
148
  if (!await this.#isRunning(true)) {
149
149
  yield ['failure', 'Failed to start service correctly'];
150
150
  }
package/src/util.ts CHANGED
@@ -6,7 +6,9 @@ import { CliCommandShape, CliCommandShapeFields } from './types.ts';
6
6
 
7
7
  const IPC_ALLOWED_ENV = new Set(['NODE_OPTIONS']);
8
8
  const IPC_INVALID_ENV = new Set(['PS1', 'INIT_CWD', 'COLOR', 'LANGUAGE', 'PROFILEHOME', '_']);
9
- const validEnv = (k: string): boolean => IPC_ALLOWED_ENV.has(k) || (!IPC_INVALID_ENV.has(k) && !/^(npm_|GTK|GDK|TRV|NODE|GIT|TERM_)/.test(k) && !/VSCODE/.test(k));
9
+ const validEnv = (key: string): boolean => IPC_ALLOWED_ENV.has(key) || (
10
+ !IPC_INVALID_ENV.has(key) && !/^(npm_|GTK|GDK|TRV|NODE|GIT|TERM_)/.test(key) && !/VSCODE/.test(key)
11
+ );
10
12
 
11
13
  export class CliUtil {
12
14
  /**
@@ -51,14 +53,14 @@ export class CliUtil {
51
53
  return false;
52
54
  }
53
55
 
54
- const info = await fetch(Env.TRV_CLI_IPC.val!).catch(() => ({ ok: false }));
56
+ const info = await fetch(Env.TRV_CLI_IPC.value!).catch(() => ({ ok: false }));
55
57
 
56
58
  if (!info.ok) { // Server not running
57
59
  return false;
58
60
  }
59
61
 
60
62
  const env: Record<string, string> = {};
61
- const req = {
63
+ const request = {
62
64
  type: `@travetto/cli:${action}`,
63
65
  data: {
64
66
  name: cmd._cfg!.name,
@@ -69,10 +71,10 @@ export class CliUtil {
69
71
  args: process.argv.slice(3),
70
72
  }
71
73
  };
72
- console.log('Triggering IPC request', req);
74
+ console.log('Triggering IPC request', request);
73
75
 
74
- Object.entries(process.env).forEach(([k, v]) => validEnv(k) && (env[k] = v!));
75
- const sent = await fetch(Env.TRV_CLI_IPC.val!, { method: 'POST', body: JSON.stringify(req) });
76
+ Object.entries(process.env).forEach(([key, value]) => validEnv(key) && (env[key] = value!));
77
+ const sent = await fetch(Env.TRV_CLI_IPC.value!, { method: 'POST', body: JSON.stringify(request) });
76
78
  return sent.ok;
77
79
  }
78
80
 
@@ -87,6 +89,6 @@ export class CliUtil {
87
89
  * Write data to channel and ensure its flushed before continuing
88
90
  */
89
91
  static async writeAndEnsureComplete(data: unknown, channel: 'stdout' | 'stderr' = 'stdout'): Promise<void> {
90
- return await new Promise(r => process[channel].write(typeof data === 'string' ? data : JSON.stringify(data, null, 2), () => r()));
92
+ return await new Promise(resolve => process[channel].write(typeof data === 'string' ? data : JSON.stringify(data, null, 2), () => resolve()));
91
93
  }
92
94
  }
@@ -20,7 +20,7 @@ export class CliSchemaCommand implements CliCommandShape {
20
20
  return;
21
21
  }
22
22
  const resolved = await CliCommandRegistryIndex.load(names);
23
- const invalid = names.find(x => !resolved.find(r => r.command === x));
23
+ const invalid = names.find(name => !resolved.find(result => result.command === name));
24
24
 
25
25
  if (invalid) {
26
26
  return {
@@ -38,7 +38,7 @@ export class CliSchemaCommand implements CliCommandShape {
38
38
  const resolved = await CliCommandRegistryIndex.load(names);
39
39
 
40
40
  const output = resolved
41
- .map(x => CliSchemaExportUtil.exportSchema(x.config.cls));
41
+ .map(result => CliSchemaExportUtil.exportSchema(result.config.cls));
42
42
 
43
43
  await CliUtil.writeAndEnsureComplete(output);
44
44
  }
@@ -25,8 +25,8 @@ export class MainCommand implements CliCommandShape {
25
25
  try {
26
26
  const mod = await Runtime.importFrom<{ main(..._: unknown[]): Promise<unknown> }>(fileOrImport);
27
27
  result = await mod.main(...args, ...this._parsed.unknown);
28
- } catch (err) {
29
- result = err;
28
+ } catch (error) {
29
+ result = error;
30
30
  process.exitCode = Math.max(process.exitCode ? +process.exitCode : 1, 1);
31
31
  }
32
32
 
@@ -13,14 +13,14 @@ export class CliServiceCommand implements CliCommandShape {
13
13
  async #getServices(services: string[]): Promise<ServiceDescriptor[]> {
14
14
  return (await Promise.all(
15
15
  RuntimeIndex.find({
16
- module: m => m.roles.includes('std'),
17
- folder: f => f === 'support',
18
- file: f => /support\/service[.]/.test(f.sourceFile)
16
+ module: mod => mod.roles.includes('std'),
17
+ folder: folder => folder === 'support',
18
+ file: file => /support\/service[.]/.test(file.sourceFile)
19
19
  })
20
- .map(x => Runtime.importFrom<{ service: ServiceDescriptor }>(x.import).then(v => v.service))
20
+ .map(file => Runtime.importFrom<{ service: ServiceDescriptor }>(file.import).then(value => value.service))
21
21
  ))
22
- .filter(x => !!x)
23
- .filter(x => services?.length ? services.includes(x.name) : true)
22
+ .filter(file => !!file)
23
+ .filter(file => services?.length ? services.includes(file.name) : true)
24
24
  .toSorted((a, b) => a.name.localeCompare(b.name));
25
25
  }
26
26
 
@@ -37,29 +37,29 @@ export class CliServiceCommand implements CliCommandShape {
37
37
  return [
38
38
  cliTpl`${{ title: 'Available Services' }}`,
39
39
  '-'.repeat(20),
40
- ...all.map(x => cliTpl` * ${{ identifier: x.name }}@${{ type: x.version }}`)
40
+ ...all.map(service => cliTpl` * ${{ identifier: service.name }}@${{ type: service.version }}`)
41
41
  ];
42
42
  }
43
43
 
44
44
  async main(action: ServiceAction, services: string[] = []): Promise<void> {
45
45
  const all = await this.#getServices(services);
46
- const maxName = Math.max(...all.map(x => x.name.length), 'Service'.length) + 3;
47
- const maxVersion = Math.max(...all.map(x => `${x.version}`.length), 'Version'.length) + 3;
46
+ const maxName = Math.max(...all.map(service => service.name.length), 'Service'.length) + 3;
47
+ const maxVersion = Math.max(...all.map(service => `${service.version}`.length), 'Version'.length) + 3;
48
48
  const maxStatus = 20;
49
- const q = new AsyncQueue<{ idx: number, text: string, done?: boolean }>();
49
+ const queue = new AsyncQueue<{ idx: number, text: string, done?: boolean }>();
50
50
 
51
- const jobs = all.map(async (v, i) => {
52
- const identifier = v.name.padEnd(maxName);
53
- const type = `${v.version}`.padStart(maxVersion - 3).padEnd(maxVersion);
51
+ const jobs = all.map(async (descriptor, i) => {
52
+ const identifier = descriptor.name.padEnd(maxName);
53
+ const type = `${descriptor.version}`.padStart(maxVersion - 3).padEnd(maxVersion);
54
54
  let msg: string;
55
- for await (const [valueType, value] of new ServiceRunner(v).action(action)) {
55
+ for await (const [valueType, value] of new ServiceRunner(descriptor).action(action)) {
56
56
  const details = { [valueType === 'message' ? 'subtitle' : valueType]: value };
57
- q.add({ idx: i, text: msg = cliTpl`${{ identifier }} ${{ type }} ${details}` });
57
+ queue.add({ idx: i, text: msg = cliTpl`${{ identifier }} ${{ type }} ${details}` });
58
58
  }
59
- q.add({ idx: i, done: true, text: msg! });
59
+ queue.add({ idx: i, done: true, text: msg! });
60
60
  });
61
61
 
62
- Promise.all(jobs).then(() => Util.queueMacroTask()).then(() => q.close());
62
+ Promise.all(jobs).then(() => Util.queueMacroTask()).then(() => queue.close());
63
63
 
64
64
  const term = new Terminal();
65
65
  await term.writer.writeLines([
@@ -68,6 +68,6 @@ export class CliServiceCommand implements CliCommandShape {
68
68
  ''.padEnd(maxName + maxVersion + maxStatus + 3, '-'),
69
69
  ]).commit();
70
70
 
71
- await term.streamList(q);
71
+ await term.streamList(queue);
72
72
  }
73
73
  }