@travetto/cli 7.1.4 → 8.0.0-alpha.0
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 +9 -9
- package/package.json +3 -3
- package/src/error.ts +2 -2
- package/src/execute.ts +2 -2
- package/src/help.ts +2 -2
- package/src/module.ts +1 -1
- package/src/parse.ts +6 -3
- package/src/registry/registry-adapter.ts +2 -6
- package/src/scm.ts +2 -2
- package/src/service.ts +2 -2
- package/src/util.ts +5 -4
- package/support/cli.main.ts +2 -2
- package/support/entry.trv.ts +1 -0
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#L98) 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#
|
|
137
|
-
* String values. [@MinLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#
|
|
138
|
-
* Date values. The [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#
|
|
136
|
+
* Number values. The [@Integer](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L172), [@Float](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L179), [@Precision](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L165), [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L99) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L110) decorators help provide additional validation.
|
|
137
|
+
* String values. [@MinLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L99), [@MaxLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L110), [@Match](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L90) and [@Enum](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L64) provide additional constraints
|
|
138
|
+
* Date values. The [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L99) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L110) 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
|
|
|
@@ -554,11 +554,11 @@ Options:
|
|
|
554
554
|
|
|
555
555
|
Available Services
|
|
556
556
|
--------------------
|
|
557
|
-
* dynamodb@3.
|
|
558
|
-
* elasticsearch@9.2.
|
|
557
|
+
* dynamodb@3.3.0
|
|
558
|
+
* elasticsearch@9.2.4
|
|
559
559
|
* firestore@latest
|
|
560
560
|
* mongodb@8.2
|
|
561
|
-
* mysql@9.
|
|
561
|
+
* mysql@9.6
|
|
562
562
|
* postgresql@18.1
|
|
563
563
|
* redis@8.4
|
|
564
564
|
* s3@4.11.0
|
|
@@ -572,11 +572,11 @@ $ trv service status
|
|
|
572
572
|
|
|
573
573
|
Service Version Status
|
|
574
574
|
-------------------------------------------------
|
|
575
|
-
dynamodb 3.
|
|
576
|
-
elasticsearch 9.2.
|
|
575
|
+
dynamodb 3.3.0 Running 93af422e793a
|
|
576
|
+
elasticsearch 9.2.4 Running ed76ee063d13
|
|
577
577
|
firestore latest Running feec2e5e95b4
|
|
578
578
|
mongodb 8.2 Running 5513eba6734e
|
|
579
|
-
mysql 9.
|
|
579
|
+
mysql 9.6 Running 307bc66d442a
|
|
580
580
|
postgresql 18.1 Running e78291e71040
|
|
581
581
|
redis 8.4 Running 77ba279b4e30
|
|
582
582
|
s3 4.11.0 Running fdacfc55b9e3
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0-alpha.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI infrastructure for Travetto framework",
|
|
6
6
|
"keywords": [
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"directory": "module/cli"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@travetto/schema": "^
|
|
33
|
-
"@travetto/terminal": "^
|
|
32
|
+
"@travetto/schema": "^8.0.0-alpha.0",
|
|
33
|
+
"@travetto/terminal": "^8.0.0-alpha.0"
|
|
34
34
|
},
|
|
35
35
|
"travetto": {
|
|
36
36
|
"displayName": "Command Line Interface",
|
package/src/error.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RuntimeError, Runtime } from '@travetto/runtime';
|
|
2
2
|
|
|
3
3
|
import { cliTpl } from './color.ts';
|
|
4
4
|
import type { CliValidationError, CliCommandShape } from './types.ts';
|
|
@@ -48,7 +48,7 @@ ${{ identifier: install }}
|
|
|
48
48
|
/**
|
|
49
49
|
* Provides a basic error wrapper for cli validation issues
|
|
50
50
|
*/
|
|
51
|
-
export class CliValidationResultError extends
|
|
51
|
+
export class CliValidationResultError extends RuntimeError<{ errors: CliValidationError[] }> {
|
|
52
52
|
command: CliCommandShape;
|
|
53
53
|
|
|
54
54
|
constructor(command: CliCommandShape, errors: CliValidationError[]) {
|
package/src/execute.ts
CHANGED
|
@@ -16,7 +16,7 @@ export class ExecutionManager {
|
|
|
16
16
|
static async #onError(error: unknown): Promise<void> {
|
|
17
17
|
process.exitCode ??= 1;
|
|
18
18
|
if (error instanceof CliValidationResultError) {
|
|
19
|
-
console.error!(
|
|
19
|
+
console.error!(HelpUtil.renderValidationError(error));
|
|
20
20
|
console.error!(await HelpUtil.renderCommandHelp(error.command));
|
|
21
21
|
} else if (error instanceof CliUnknownCommandError) {
|
|
22
22
|
if (error.help) {
|
|
@@ -39,7 +39,7 @@ export class ExecutionManager {
|
|
|
39
39
|
const state = command._parsed = await CliParseUtil.parse(schema, fullArgs);
|
|
40
40
|
|
|
41
41
|
await command.preBind?.();
|
|
42
|
-
const boundArgs =
|
|
42
|
+
const boundArgs = CliCommandSchemaUtil.bindInput(command, state);
|
|
43
43
|
return { command, boundArgs };
|
|
44
44
|
}
|
|
45
45
|
|
package/src/help.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import util from 'node:util';
|
|
2
2
|
|
|
3
|
-
import { castKey, getClass } from '@travetto/runtime';
|
|
3
|
+
import { castKey, getClass, JSONUtil } from '@travetto/runtime';
|
|
4
4
|
import { SchemaRegistryIndex } from '@travetto/schema';
|
|
5
5
|
|
|
6
6
|
import { cliTpl } from './color.ts';
|
|
@@ -70,7 +70,7 @@ export class HelpUtil {
|
|
|
70
70
|
const desc = [cliTpl`${{ title: field.description }}`];
|
|
71
71
|
|
|
72
72
|
if (key !== 'help' && defaultValue !== undefined) {
|
|
73
|
-
desc.push(cliTpl`(default: ${{ input:
|
|
73
|
+
desc.push(cliTpl`(default: ${{ input: JSONUtil.toUTF8(defaultValue) }})`);
|
|
74
74
|
}
|
|
75
75
|
descriptions.push(desc.join(' '));
|
|
76
76
|
}
|
package/src/module.ts
CHANGED
|
@@ -28,7 +28,7 @@ export class CliModuleUtil {
|
|
|
28
28
|
for (const module of await CliScmUtil.findChangedModules(fromHash, toHash)) {
|
|
29
29
|
out.set(module.name, module);
|
|
30
30
|
if (transitive) {
|
|
31
|
-
for (const sub of
|
|
31
|
+
for (const sub of RuntimeIndex.getDependentModules(module, 'parents')) {
|
|
32
32
|
out.set(sub.name, sub);
|
|
33
33
|
}
|
|
34
34
|
}
|
package/src/parse.ts
CHANGED
|
@@ -10,7 +10,7 @@ type ParsedInput = ParsedState['all'][number];
|
|
|
10
10
|
|
|
11
11
|
const RAW_SEPARATOR = '--';
|
|
12
12
|
const VALID_FLAG = /^-{1,2}[a-z]/i;
|
|
13
|
-
const HELP_FLAG =
|
|
13
|
+
const HELP_FLAG = /^(-h|--help)$/;
|
|
14
14
|
const LONG_FLAG_WITH_EQ = /^--[a-z][^= ]+=\S+/i;
|
|
15
15
|
const CONFIG_PREFIX = '+=';
|
|
16
16
|
const SPACE = new Set([32, 7, 13, 10]);
|
|
@@ -134,8 +134,11 @@ export class CliParseUtil {
|
|
|
134
134
|
static async expandArgs(schema: SchemaClassConfig, args: string[]): Promise<string[]> {
|
|
135
135
|
const separatorIndex = args.includes(RAW_SEPARATOR) ? args.indexOf(RAW_SEPARATOR) : args.length;
|
|
136
136
|
const module = this.getSpecifiedModule(schema, args);
|
|
137
|
-
return
|
|
138
|
-
|
|
137
|
+
return Promise
|
|
138
|
+
.all(args.map(async (arg, i) =>
|
|
139
|
+
await (arg.startsWith(CONFIG_PREFIX) && (i < separatorIndex || separatorIndex < 0) ? this.readFlagFile(arg, module) : arg))
|
|
140
|
+
)
|
|
141
|
+
.then(expanded => expanded.flat());
|
|
139
142
|
}
|
|
140
143
|
|
|
141
144
|
/**
|
|
@@ -75,12 +75,8 @@ export class CliCommandRegistryAdapter implements RegistryAdapter<CliCommandConf
|
|
|
75
75
|
* Registers a cli command
|
|
76
76
|
*/
|
|
77
77
|
register(...configs: Partial<CliCommandConfig>[]): CliCommandConfig {
|
|
78
|
-
const
|
|
79
|
-
this.#config ??= {
|
|
80
|
-
cls: this.#cls,
|
|
81
|
-
preMain: undefined,
|
|
82
|
-
name: getName(meta.import),
|
|
83
|
-
};
|
|
78
|
+
const metadata = describeFunction(this.#cls);
|
|
79
|
+
this.#config ??= { cls: this.#cls, name: getName(metadata.import) };
|
|
84
80
|
Object.assign(this.#config, ...configs);
|
|
85
81
|
return this.#config;
|
|
86
82
|
}
|
package/src/scm.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { spawn } from 'node:child_process';
|
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { RuntimeError, ExecUtil, Runtime, RuntimeIndex } from '@travetto/runtime';
|
|
6
6
|
import type { IndexedModule } from '@travetto/manifest';
|
|
7
7
|
|
|
8
8
|
export class CliScmUtil {
|
|
@@ -50,7 +50,7 @@ export class CliScmUtil {
|
|
|
50
50
|
const rootPath = Runtime.workspace.path;
|
|
51
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
|
-
throw new
|
|
53
|
+
throw new RuntimeError('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)) {
|
package/src/service.ts
CHANGED
|
@@ -42,7 +42,7 @@ export class ServiceRunner {
|
|
|
42
42
|
async #isRunning(full = false): Promise<boolean> {
|
|
43
43
|
const port = ports(this.#descriptor.port!)[0];
|
|
44
44
|
const start = Date.now();
|
|
45
|
-
const timeoutMs = TimeUtil.
|
|
45
|
+
const timeoutMs = TimeUtil.duration(full ? this.#descriptor.startupTimeout ?? 5000 : 100, 'ms');
|
|
46
46
|
while ((Date.now() - start) < timeoutMs) {
|
|
47
47
|
try {
|
|
48
48
|
const sock = net.createConnection(port, 'localhost');
|
|
@@ -134,7 +134,7 @@ export class ServiceRunner {
|
|
|
134
134
|
if (operation === 'restart' || operation === 'start') {
|
|
135
135
|
if (!await this.#hasImage()) {
|
|
136
136
|
yield ['message', 'Starting image download'];
|
|
137
|
-
for await (const line of
|
|
137
|
+
for await (const line of this.#pullImage()) {
|
|
138
138
|
yield ['message', `Downloading: ${line}`];
|
|
139
139
|
}
|
|
140
140
|
yield ['message', 'Image download complete'];
|
package/src/util.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn, type ChildProcess } from 'node:child_process';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { RuntimeError, JSONUtil, Env, ExecUtil, Runtime, ShutdownManager, Util, WatchUtil } from '@travetto/runtime';
|
|
4
4
|
|
|
5
5
|
import type { CliCommandShape, CliCommandShapeFields } from './types.ts';
|
|
6
6
|
|
|
@@ -96,10 +96,10 @@ export class CliUtil {
|
|
|
96
96
|
console.log('Triggering IPC request', request);
|
|
97
97
|
|
|
98
98
|
Object.entries(process.env).forEach(([key, value]) => validEnv(key) && (env[key] = value!));
|
|
99
|
-
const sent = await fetch(Env.TRV_CLI_IPC.value!, { method: 'POST', body:
|
|
99
|
+
const sent = await fetch(Env.TRV_CLI_IPC.value!, { method: 'POST', body: JSONUtil.toUTF8(request) });
|
|
100
100
|
|
|
101
101
|
if (!sent.ok) {
|
|
102
|
-
throw new
|
|
102
|
+
throw new RuntimeError(`IPC Request failed: ${sent.status} ${await sent.text()}`);
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
|
|
@@ -107,7 +107,8 @@ export class CliUtil {
|
|
|
107
107
|
* Write data to channel and ensure its flushed before continuing
|
|
108
108
|
*/
|
|
109
109
|
static async writeAndEnsureComplete(data: unknown, channel: 'stdout' | 'stderr' = 'stdout'): Promise<void> {
|
|
110
|
-
return await new Promise(resolve => process[channel].write(typeof data === 'string' ? data :
|
|
110
|
+
return await new Promise(resolve => process[channel].write(typeof data === 'string' ? data :
|
|
111
|
+
JSONUtil.toUTF8Pretty(data), () => resolve()));
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
/**
|
package/support/cli.main.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Runtime } from '@travetto/runtime';
|
|
1
|
+
import { JSONUtil, Runtime } from '@travetto/runtime';
|
|
2
2
|
import { type CliCommandShape, CliCommand, type CliValidationError, type ParsedState } from '@travetto/cli';
|
|
3
3
|
import { Ignore, IsPrivate } from '@travetto/schema';
|
|
4
4
|
|
|
@@ -32,7 +32,7 @@ export class MainCommand implements CliCommandShape {
|
|
|
32
32
|
|
|
33
33
|
if (result !== undefined) {
|
|
34
34
|
if (process.connected) { process.send?.(result); }
|
|
35
|
-
const payload = typeof result === 'string' ? result : (result instanceof Error ? result.stack :
|
|
35
|
+
const payload = typeof result === 'string' ? result : (result instanceof Error ? result.stack : JSONUtil.toUTF8(result));
|
|
36
36
|
process[process.exitCode ? 'stderr' : 'stdout'].write(`${payload}\n`);
|
|
37
37
|
}
|
|
38
38
|
}
|
package/support/entry.trv.ts
CHANGED