@travetto/cli 8.0.0-alpha.3 → 8.0.0-alpha.31
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 +108 -86
- package/__index__.ts +10 -9
- package/bin/trv.js +3 -1
- package/package.json +3 -3
- package/src/color.ts +1 -1
- package/src/execute.ts +38 -20
- package/src/help.ts +129 -76
- package/src/module.ts +9 -10
- package/src/parse.ts +57 -42
- package/src/registry/decorator.ts +52 -47
- package/src/registry/registry-adapter.ts +22 -25
- package/src/registry/registry-index.ts +30 -26
- package/src/schema-export.ts +25 -16
- package/src/schema.ts +15 -10
- package/src/scm.ts +19 -10
- package/src/service.ts +34 -33
- package/src/types.ts +9 -7
- package/src/util.ts +25 -26
- package/support/cli.cli_schema.ts +8 -7
- package/support/cli.main.ts +12 -8
- package/support/cli.service.ts +25 -19
- package/support/entry.trv.ts +3 -2
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ npm install @travetto/cli
|
|
|
13
13
|
yarn add @travetto/cli
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
The cli module represents the primary entry point for execution within the framework. One of the main goals for this module is extensibility, as adding new entry points is meant to be trivial. The framework leverages this module for exposing all executable tools and entry points.
|
|
16
|
+
The cli module represents the primary entry point for execution within the framework. One of the main goals for this module is extensibility, as adding new entry points is meant to be trivial. The framework leverages this module for exposing all executable tools and entry points. To see a high level listing of all supported commands, invoke `trv --help`
|
|
17
17
|
|
|
18
18
|
**Terminal: General Usage**
|
|
19
19
|
```bash
|
|
@@ -22,44 +22,50 @@ $ trv --help
|
|
|
22
22
|
Usage: [options] [command]
|
|
23
23
|
|
|
24
24
|
Commands:
|
|
25
|
-
doc
|
|
26
|
-
doc:angular
|
|
27
|
-
doc:mapping
|
|
28
|
-
email:compile
|
|
29
|
-
email:editor
|
|
30
|
-
email:test
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
25
|
+
doc Generate documentation outputs from a module `DOC.tsx` entry file.
|
|
26
|
+
doc:angular Generate documentation into the angular webapp under related/travetto.github.io
|
|
27
|
+
doc:mapping Generate module mapping for
|
|
28
|
+
email:compile Compile all email templates into generated runtime artifacts.
|
|
29
|
+
email:editor Start the email template editor service for interactive preview and testing.
|
|
30
|
+
email:test Render and send a template file to a target recipient for quick validation.
|
|
31
|
+
firestore:indexes Generate the Firestore composite indexes JSON for all registered models.
|
|
32
|
+
lint Run Biome linter/formatter for the workspace or changed files.
|
|
33
|
+
lint:register Generate the workspace Biome configuration entry file.
|
|
34
|
+
llm:support:execute Execute llm-support operations with dry-run by default.
|
|
35
|
+
llm:support:inline Inline and compile reference snippets for llm-support packaging.
|
|
36
|
+
llm:support:mcp Minimal MCP stdio server for llm-support tools.
|
|
37
|
+
llm:support:plan Build plan-first execution details for llm-support operations.
|
|
38
|
+
llm:support:recommend Recommend llm-support bundles, workflows, and operations.
|
|
39
|
+
llm:support:status Show llm-support execution coverage status.
|
|
40
|
+
model:export Export model definitions for a selected provider and model set.
|
|
41
|
+
model:install Install or update model definitions for a selected provider.
|
|
42
|
+
openapi:client Generate API clients from an OpenAPI specification using the generator image.
|
|
43
|
+
openapi:spec Generate the OpenAPI specification for the selected module.
|
|
44
|
+
pack Build a standard module package artifact.
|
|
45
|
+
pack:docker Build container-ready artifacts and optionally publish Docker images.
|
|
46
|
+
pack:lambda Build an AWS Lambda-ready zip package using the pack pipeline.
|
|
47
|
+
pack:zip Build a deployable zip artifact using the standard pack pipeline.
|
|
48
|
+
repo:exec Execute a shell command across workspace modules.
|
|
49
|
+
repo:list List workspace modules and their relationships.
|
|
50
|
+
repo:publish Publish unpublished workspace modules to the package registry.
|
|
51
|
+
repo:version Bump workspace module versions and optionally commit/tag release metadata.
|
|
52
|
+
repo:version-sync Synchronize package versions and dependency ranges across the monorepo.
|
|
53
|
+
run:double Doubles a number
|
|
54
|
+
service Manage development services (start/stop/restart/status) across the workspace.
|
|
55
|
+
test Execute the test framework for targeted files, suites, or methods.
|
|
56
|
+
test:watch Start the test watcher for continuous test execution.
|
|
57
|
+
web:http Start the configured web HTTP server for a module.
|
|
58
|
+
web:rpc-client Generate web-rpc client artifacts from a specified provider or leveraging local config.
|
|
53
59
|
```
|
|
54
60
|
|
|
55
61
|
This listing is from the [Travetto](https://travetto.dev) monorepo, and represents the majority of tools that can be invoked from the command line.
|
|
56
62
|
|
|
57
|
-
This module also has a tight integration with the [VSCode plugin](https://marketplace.visualstudio.com/items?itemName=arcsine.travetto-plugin), allowing the editing experience to benefit from the commands defined. The most commonly used commands will be the ones packaged with the framework, but its also very easy to create new commands.
|
|
63
|
+
This module also has a tight integration with the [VSCode plugin](https://marketplace.visualstudio.com/items?itemName=arcsine.travetto-plugin), allowing the editing experience to benefit from the commands defined. The most commonly used commands will be the ones packaged with the framework, but its also very easy to create new commands. With the correct configuration, these commands will also be exposed within VSCode.
|
|
58
64
|
|
|
59
65
|
At it's heart, a cli command is the contract defined by what flags, and what arguments the command supports. Within the framework this requires three criteria to be met:
|
|
60
66
|
* The file must be located in the `support/` folder, and have a name that matches `cli.*.ts`
|
|
61
67
|
* The file must be a class that has a main method
|
|
62
|
-
* The class must use the [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#
|
|
68
|
+
* The class must use the [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#L20) decorator
|
|
63
69
|
|
|
64
70
|
**Code: Basic Command**
|
|
65
71
|
```typescript
|
|
@@ -75,16 +81,16 @@ export class BasicCommand {
|
|
|
75
81
|
|
|
76
82
|
**Terminal: Basic Command Help**
|
|
77
83
|
```bash
|
|
78
|
-
$ trv basic
|
|
84
|
+
$ trv basic --help
|
|
79
85
|
|
|
80
86
|
Usage: basic [options]
|
|
81
87
|
|
|
82
88
|
Options:
|
|
83
|
-
|
|
89
|
+
--help display help for command
|
|
84
90
|
```
|
|
85
91
|
|
|
86
92
|
## Command Naming
|
|
87
|
-
The file name `support/cli.<name>.ts` has a direct mapping to the cli command name.
|
|
93
|
+
The file name `support/cli.<name>.ts` has a direct mapping to the cli command name. This hard mapping allows for the framework to be able to know which file to invoke without needing to load all command-related files.
|
|
88
94
|
|
|
89
95
|
Examples of mappings:
|
|
90
96
|
* `cli.test.ts` maps to `test`
|
|
@@ -94,7 +100,7 @@ Examples of mappings:
|
|
|
94
100
|
The pattern is that underscores(_) translate to colons (:), and the `cli.` prefix, and `.ts` suffix are dropped.
|
|
95
101
|
|
|
96
102
|
## Binding Flags
|
|
97
|
-
[@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#
|
|
103
|
+
[@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#L20) is a wrapper for [@Schema](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/schema.ts#L19), and so every class that uses the [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#L20) decorator is now a full [@Schema](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/schema.ts#L19) class. The fields of the class represent the flags that are available to the command.
|
|
98
104
|
|
|
99
105
|
**Code: Basic Command with Flag**
|
|
100
106
|
```typescript
|
|
@@ -102,7 +108,6 @@ import { CliCommand } from '@travetto/cli';
|
|
|
102
108
|
|
|
103
109
|
@CliCommand()
|
|
104
110
|
export class BasicCommand {
|
|
105
|
-
|
|
106
111
|
loud?: boolean;
|
|
107
112
|
|
|
108
113
|
main() {
|
|
@@ -113,16 +118,16 @@ export class BasicCommand {
|
|
|
113
118
|
|
|
114
119
|
**Terminal: Basic Command with Flag Help**
|
|
115
120
|
```bash
|
|
116
|
-
$ trv basic:flag
|
|
121
|
+
$ trv basic:flag --help
|
|
117
122
|
|
|
118
123
|
Usage: basic:flag [options]
|
|
119
124
|
|
|
120
125
|
Options:
|
|
121
126
|
-l, --loud
|
|
122
|
-
|
|
127
|
+
--help display help for command
|
|
123
128
|
```
|
|
124
129
|
|
|
125
|
-
As you can see the command now has the support of a basic boolean flag to determine if the response should be loud or not.
|
|
130
|
+
As you can see the command now has the support of a basic boolean flag to determine if the response should be loud or not. The default value here is undefined/false, and so is an opt-in experience.
|
|
126
131
|
|
|
127
132
|
**Terminal: Basic Command with Loud Flag**
|
|
128
133
|
```bash
|
|
@@ -131,16 +136,16 @@ $ trv basic:flag --loud
|
|
|
131
136
|
HELLO
|
|
132
137
|
```
|
|
133
138
|
|
|
134
|
-
The [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#
|
|
139
|
+
The [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#L20) supports the following data types for flags:
|
|
135
140
|
* 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#
|
|
141
|
+
* Number values. The [@Integer](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L202), [@Float](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L211), [@Precision](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L193), [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L119) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L130) decorators help provide additional validation.
|
|
142
|
+
* String values. [@MinLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L119), [@MaxLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L130), [@Match](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L108) and [@Enum](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L78) provide additional constraints
|
|
143
|
+
* Date values. The [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L119) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/input.ts#L130) decorators help provide additional validation.
|
|
139
144
|
* String lists. Same as String, but allowing multiple values.
|
|
140
145
|
* Numeric lists. Same as Number, but allowing multiple values.
|
|
141
146
|
|
|
142
147
|
## Binding Arguments
|
|
143
|
-
The `main()` method is the entrypoint for the command, represents a series of parameters. Some will be required, some may be optional.
|
|
148
|
+
The `main()` method is the entrypoint for the command, represents a series of parameters. Some will be required, some may be optional. The arguments support all types supported by the flags, and decorators can be provided using the decorators inline on parameters. Optional arguments in the method, will be optional at run time, and filled with the provided default values.
|
|
144
149
|
|
|
145
150
|
**Code: Basic Command with Arg**
|
|
146
151
|
```typescript
|
|
@@ -149,7 +154,6 @@ import { Max, Min } from '@travetto/schema';
|
|
|
149
154
|
|
|
150
155
|
@CliCommand()
|
|
151
156
|
export class BasicCommand {
|
|
152
|
-
|
|
153
157
|
main(@Min(1) @Max(10) volume: number = 1) {
|
|
154
158
|
console.log(volume > 7 ? 'HELLO' : 'Hello');
|
|
155
159
|
}
|
|
@@ -158,12 +162,12 @@ export class BasicCommand {
|
|
|
158
162
|
|
|
159
163
|
**Terminal: Basic Command**
|
|
160
164
|
```bash
|
|
161
|
-
$ trv basic:arg
|
|
165
|
+
$ trv basic:arg --help
|
|
162
166
|
|
|
163
167
|
Usage: basic:arg [options] [volume:number]
|
|
164
168
|
|
|
165
169
|
Options:
|
|
166
|
-
|
|
170
|
+
--help display help for command
|
|
167
171
|
```
|
|
168
172
|
|
|
169
173
|
**Terminal: Basic Command with Invalid Loud Arg**
|
|
@@ -176,7 +180,7 @@ Execution failed:
|
|
|
176
180
|
Usage: basic:arg [options] [volume:number]
|
|
177
181
|
|
|
178
182
|
Options:
|
|
179
|
-
|
|
183
|
+
--help display help for command
|
|
180
184
|
```
|
|
181
185
|
|
|
182
186
|
**Terminal: Basic Command with Loud Arg > 7**
|
|
@@ -202,7 +206,6 @@ import { Max, Min } from '@travetto/schema';
|
|
|
202
206
|
|
|
203
207
|
@CliCommand()
|
|
204
208
|
export class BasicCommand {
|
|
205
|
-
|
|
206
209
|
reverse?: boolean;
|
|
207
210
|
|
|
208
211
|
main(@Min(1) @Max(10) volumes: number[]) {
|
|
@@ -213,13 +216,13 @@ export class BasicCommand {
|
|
|
213
216
|
|
|
214
217
|
**Terminal: Basic Command**
|
|
215
218
|
```bash
|
|
216
|
-
$ trv basic:arg-list
|
|
219
|
+
$ trv basic:arg-list --help
|
|
217
220
|
|
|
218
221
|
Usage: basic:arg-list [options] <volumes...:number>
|
|
219
222
|
|
|
220
223
|
Options:
|
|
221
224
|
-r, --reverse
|
|
222
|
-
|
|
225
|
+
--help display help for command
|
|
223
226
|
```
|
|
224
227
|
|
|
225
228
|
**Terminal: Basic Arg List**
|
|
@@ -240,7 +243,7 @@ Usage: basic:arg-list [options] <volumes...:number>
|
|
|
240
243
|
|
|
241
244
|
Options:
|
|
242
245
|
-r, --reverse
|
|
243
|
-
|
|
246
|
+
--help display help for command
|
|
244
247
|
```
|
|
245
248
|
|
|
246
249
|
**Terminal: Basic Arg List with Reverse**
|
|
@@ -251,7 +254,7 @@ $ trv basic:arg-list -r 10 5 3 9 8 1
|
|
|
251
254
|
```
|
|
252
255
|
|
|
253
256
|
## Customization
|
|
254
|
-
By default, all fields are treated as flags and all parameters of `main()` are treated as arguments within the validation process.
|
|
257
|
+
By default, all fields are treated as flags and all parameters of `main()` are treated as arguments within the validation process. Like the standard [@Schema](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/schema.ts#L19) behavior, we can leverage the metadata of the fields/parameters to help provide additional customization/context for the users of the commands.
|
|
255
258
|
|
|
256
259
|
**Code: Custom Command with Metadata**
|
|
257
260
|
```typescript
|
|
@@ -259,11 +262,10 @@ import { CliCommand } from '@travetto/cli';
|
|
|
259
262
|
import { Max, Min } from '@travetto/schema';
|
|
260
263
|
|
|
261
264
|
/**
|
|
262
|
-
*
|
|
265
|
+
* Example command with a custom argument
|
|
263
266
|
*/
|
|
264
267
|
@CliCommand()
|
|
265
268
|
export class CustomCommand {
|
|
266
|
-
|
|
267
269
|
/**
|
|
268
270
|
* The message to send back to the user
|
|
269
271
|
* @alias -m
|
|
@@ -279,13 +281,16 @@ export class CustomCommand {
|
|
|
279
281
|
|
|
280
282
|
**Terminal: Custom Command Help**
|
|
281
283
|
```bash
|
|
282
|
-
$ trv custom:arg
|
|
284
|
+
$ trv custom:arg --help
|
|
283
285
|
|
|
284
286
|
Usage: custom:arg [options] [volume:number]
|
|
285
287
|
|
|
288
|
+
Description:
|
|
289
|
+
Example command with a custom argument
|
|
290
|
+
|
|
286
291
|
Options:
|
|
287
292
|
-m, --message <string> The message to send back to the user (default: "hello")
|
|
288
|
-
|
|
293
|
+
--help display help for command
|
|
289
294
|
```
|
|
290
295
|
|
|
291
296
|
**Terminal: Custom Command Help with overridden Text**
|
|
@@ -311,11 +316,10 @@ import { CliCommand } from '@travetto/cli';
|
|
|
311
316
|
import { Max, Min } from '@travetto/schema';
|
|
312
317
|
|
|
313
318
|
/**
|
|
314
|
-
*
|
|
319
|
+
* Example of a command with a custom environment variable argument
|
|
315
320
|
*/
|
|
316
321
|
@CliCommand()
|
|
317
322
|
export class CustomCommand {
|
|
318
|
-
|
|
319
323
|
/**
|
|
320
324
|
* The message to send back to the user
|
|
321
325
|
* @alias env.MESSAGE
|
|
@@ -330,13 +334,16 @@ export class CustomCommand {
|
|
|
330
334
|
|
|
331
335
|
**Terminal: Custom Command Help**
|
|
332
336
|
```bash
|
|
333
|
-
$ trv custom:env-arg
|
|
337
|
+
$ trv custom:env-arg --help
|
|
334
338
|
|
|
335
339
|
Usage: custom:env-arg [options] [volume:number]
|
|
336
340
|
|
|
341
|
+
Description:
|
|
342
|
+
Example of a command with a custom environment variable argument
|
|
343
|
+
|
|
337
344
|
Options:
|
|
338
345
|
-t, --text <string> The message to send back to the user (default: "hello")
|
|
339
|
-
|
|
346
|
+
--help display help for command
|
|
340
347
|
```
|
|
341
348
|
|
|
342
349
|
**Terminal: Custom Command Help with default Text**
|
|
@@ -361,7 +368,7 @@ CuStOm
|
|
|
361
368
|
```
|
|
362
369
|
|
|
363
370
|
## Flag File Support
|
|
364
|
-
Sometimes its also convenient, especially with commands that support a variety of flags, to provide easy access to pre-defined sets of flags.
|
|
371
|
+
Sometimes its also convenient, especially with commands that support a variety of flags, to provide easy access to pre-defined sets of flags. Flag files represent a snapshot of command line arguments and flags, as defined in a file. When referenced, these inputs are essentially injected into the command line as if the user had typed them manually.
|
|
365
372
|
|
|
366
373
|
**Code: Example Flag File**
|
|
367
374
|
```bash
|
|
@@ -390,7 +397,7 @@ npx trv call:db --host localhost --port 3306 --username app --password <custom>
|
|
|
390
397
|
```
|
|
391
398
|
|
|
392
399
|
## VSCode Integration
|
|
393
|
-
By default, cli commands do not expose themselves to the VSCode extension, as the majority of them are not intended for that sort of operation.
|
|
400
|
+
By default, cli commands do not expose themselves to the VSCode extension, as the majority of them are not intended for that sort of operation. [Web API](https://github.com/travetto/travetto/tree/main/module/web#readme "Declarative support for creating Web Applications") does expose a cli target `web:http` that will show up, to help run/debug a web application. Any command can mark itself as being a run target, and will be eligible for running from within the [VSCode plugin](https://marketplace.visualstudio.com/items?itemName=arcsine.travetto-plugin). This is achieved by setting the `runTarget` field on the [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#L20) decorator. This means the target will be visible within the editor tooling.
|
|
394
401
|
|
|
395
402
|
**Code: Simple Run Target**
|
|
396
403
|
```typescript
|
|
@@ -401,7 +408,6 @@ import { CliCommand } from '@travetto/cli';
|
|
|
401
408
|
*/
|
|
402
409
|
@CliCommand({ runTarget: true })
|
|
403
410
|
export class RunCommand {
|
|
404
|
-
|
|
405
411
|
main(name: string) {
|
|
406
412
|
console.log(name);
|
|
407
413
|
}
|
|
@@ -433,20 +439,26 @@ If the goal is to run a more complex application, which may include depending on
|
|
|
433
439
|
|
|
434
440
|
**Code: Simple Run Target**
|
|
435
441
|
```typescript
|
|
436
|
-
import {
|
|
442
|
+
import { CliCommand, type CliCommandShape, CliDebugIpcFlag, CliModuleFlag, CliProfilesFlag, CliRestartOnChangeFlag } from '@travetto/cli';
|
|
437
443
|
import { DependencyRegistryIndex } from '@travetto/di';
|
|
438
|
-
import { CliCommand, CliDebugIpcFlag, CliModuleFlag, CliProfilesFlag, CliRestartOnChangeFlag, type CliCommandShape } from '@travetto/cli';
|
|
439
|
-
import { NetUtil } from '@travetto/web';
|
|
440
444
|
import { Registry } from '@travetto/registry';
|
|
445
|
+
import { Runtime, toConcrete } from '@travetto/runtime';
|
|
446
|
+
import { NetUtil } from '@travetto/web';
|
|
441
447
|
|
|
442
448
|
import type { WebHttpServer } from '../src/types.ts';
|
|
443
449
|
|
|
444
450
|
/**
|
|
445
|
-
*
|
|
451
|
+
* Start the configured web HTTP server for a module.
|
|
452
|
+
*
|
|
453
|
+
* Initializes registry and server bindings, supports restart-aware development
|
|
454
|
+
* flags, and can attempt to clear conflicting port owners in local workflows.
|
|
455
|
+
*
|
|
456
|
+
* @example
|
|
457
|
+
* Starting a web server on port 8000
|
|
458
|
+
* > trv web:http -m <MODULE> -p 8000
|
|
446
459
|
*/
|
|
447
460
|
@CliCommand()
|
|
448
461
|
export class WebHttpCommand implements CliCommandShape {
|
|
449
|
-
|
|
450
462
|
/** Port to run on */
|
|
451
463
|
port?: number;
|
|
452
464
|
|
|
@@ -460,7 +472,7 @@ export class WebHttpCommand implements CliCommandShape {
|
|
|
460
472
|
profile: string[];
|
|
461
473
|
|
|
462
474
|
@CliRestartOnChangeFlag()
|
|
463
|
-
restartOnChange: boolean =
|
|
475
|
+
restartOnChange: boolean = Runtime.localDevelopment;
|
|
464
476
|
|
|
465
477
|
@CliDebugIpcFlag()
|
|
466
478
|
debugIpc?: boolean;
|
|
@@ -493,7 +505,7 @@ export class WebHttpCommand implements CliCommandShape {
|
|
|
493
505
|
|
|
494
506
|
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.
|
|
495
507
|
|
|
496
|
-
The `module` field is slightly more complex, but is geared towards supporting commands within a monorepo context.
|
|
508
|
+
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.
|
|
497
509
|
|
|
498
510
|
### Custom Validation
|
|
499
511
|
In addition to dependency injection, the command contract also allows for a custom validation function, which will have access to bound command (flags, and args) as well as the unknown arguments. When a command implements this method, any [ValidationError](https://github.com/travetto/travetto/tree/main/module/schema/src/validate/types.ts#L10) errors that are returned will be shared with the user, and fail to invoke the `main` method.
|
|
@@ -540,37 +552,43 @@ A simple example of the validation can be found in the `doc` command:
|
|
|
540
552
|
|
|
541
553
|
**Code: Simple Validation Example**
|
|
542
554
|
```typescript
|
|
543
|
-
@Validator(async
|
|
555
|
+
@Validator(async cmd => {
|
|
544
556
|
const docFile = path.resolve(cmd.input);
|
|
545
|
-
if (!(await fs.stat(docFile
|
|
557
|
+
if (!(await fs.stat(docFile, { throwIfNoEntry: false }))) {
|
|
546
558
|
return { message: `input: ${cmd.input} does not exist`, path: 'input', source: 'flag', kind: 'invalid' };
|
|
547
559
|
}
|
|
548
560
|
})
|
|
549
561
|
```
|
|
550
562
|
|
|
551
563
|
## CLI - service
|
|
552
|
-
The module provides the ability to start/stop/restart services as [docker](https://www.docker.com/community-edition) containers.
|
|
564
|
+
The module provides the ability to start/stop/restart services as [docker](https://www.docker.com/community-edition) containers. This is meant to be used for development purposes, to minimize the effort of getting an application up and running. Services can be targeted individually or handled as a group.
|
|
553
565
|
|
|
554
|
-
**Terminal:
|
|
566
|
+
**Terminal: Help for service**
|
|
555
567
|
```bash
|
|
556
568
|
$ trv service --help
|
|
557
569
|
|
|
558
570
|
Usage: service [options] <action:restart|start|status|stop> [services...:string]
|
|
559
571
|
|
|
572
|
+
Description:
|
|
573
|
+
Manage development services (start/stop/restart/status) across the workspace.
|
|
574
|
+
|
|
575
|
+
Services are discovered from registered descriptors and executed with streamed
|
|
576
|
+
terminal feedback, including optional quiet mode.
|
|
577
|
+
|
|
560
578
|
Options:
|
|
561
579
|
-q, --quiet (default: false)
|
|
562
|
-
|
|
580
|
+
--help display help for command
|
|
563
581
|
|
|
564
582
|
Available Services
|
|
565
583
|
--------------------
|
|
566
584
|
* dynamodb@3.3.0
|
|
567
|
-
* elasticsearch@9.2.
|
|
585
|
+
* elasticsearch@9.2.8
|
|
568
586
|
* firestore@latest
|
|
569
|
-
* mongodb@8.
|
|
587
|
+
* mongodb@8.3
|
|
570
588
|
* mysql@9.6
|
|
571
|
-
* postgresql@18.
|
|
589
|
+
* postgresql@18.3
|
|
572
590
|
* redis@8.4
|
|
573
|
-
* s3@4.
|
|
591
|
+
* s3@4.12.4
|
|
574
592
|
```
|
|
575
593
|
|
|
576
594
|
A sample of all services available to the entire framework:
|
|
@@ -582,13 +600,13 @@ $ trv service status
|
|
|
582
600
|
Service Version Status
|
|
583
601
|
-------------------------------------------------
|
|
584
602
|
dynamodb 3.3.0 Running 93af422e793a
|
|
585
|
-
elasticsearch 9.2.
|
|
603
|
+
elasticsearch 9.2.8 Running ed76ee063d13
|
|
586
604
|
firestore latest Running feec2e5e95b4
|
|
587
|
-
mongodb 8.
|
|
605
|
+
mongodb 8.3 Running 5513eba6734e
|
|
588
606
|
mysql 9.6 Running 307bc66d442a
|
|
589
|
-
postgresql 18.
|
|
607
|
+
postgresql 18.3 Running e78291e71040
|
|
590
608
|
redis 8.4 Running 77ba279b4e30
|
|
591
|
-
s3 4.
|
|
609
|
+
s3 4.12.4 Running fdacfc55b9e3
|
|
592
610
|
```
|
|
593
611
|
|
|
594
612
|
### Defining new Services
|
|
@@ -598,12 +616,16 @@ The services are defined as plain typescript files within the framework and can
|
|
|
598
616
|
```typescript
|
|
599
617
|
import type { ServiceDescriptor } from '@travetto/cli';
|
|
600
618
|
|
|
601
|
-
const version = process.env.MONGO_VERSION || '8.
|
|
619
|
+
const version = process.env.MONGO_VERSION || '8.3';
|
|
602
620
|
|
|
603
621
|
export const service: ServiceDescriptor = {
|
|
604
622
|
name: 'mongodb',
|
|
605
623
|
version,
|
|
606
624
|
port: 27017,
|
|
607
|
-
image: `mongo:${version}
|
|
625
|
+
image: `mongo:${version}`,
|
|
626
|
+
env: {
|
|
627
|
+
// Temp until mongo image fixes orbstack issue
|
|
628
|
+
GLIBC_TUNABLES: 'glibc.pthread.rseq=1'
|
|
629
|
+
}
|
|
608
630
|
};
|
|
609
631
|
```
|
package/__index__.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type {} from './src/trv.d.ts';
|
|
2
|
+
|
|
3
|
+
export * from './src/color.ts';
|
|
3
4
|
export * from './src/execute.ts';
|
|
4
|
-
export * from './src/schema.ts';
|
|
5
|
-
export * from './src/schema-export.ts';
|
|
6
|
-
export * from './src/registry/decorator.ts';
|
|
7
|
-
export * from './src/registry/registry-index.ts';
|
|
8
|
-
export * from './src/registry/registry-adapter.ts';
|
|
9
5
|
export * from './src/help.ts';
|
|
10
|
-
export * from './src/color.ts';
|
|
11
6
|
export * from './src/module.ts';
|
|
12
|
-
export * from './src/scm.ts';
|
|
13
7
|
export * from './src/parse.ts';
|
|
8
|
+
export * from './src/registry/decorator.ts';
|
|
9
|
+
export * from './src/registry/registry-adapter.ts';
|
|
10
|
+
export * from './src/registry/registry-index.ts';
|
|
11
|
+
export * from './src/schema.ts';
|
|
12
|
+
export * from './src/schema-export.ts';
|
|
13
|
+
export * from './src/scm.ts';
|
|
14
14
|
export * from './src/service.ts';
|
|
15
|
+
export * from './src/types.ts';
|
|
15
16
|
export * from './src/util.ts';
|
package/bin/trv.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// @ts-check
|
|
3
|
+
import '@travetto/runtime/support/patch.js';
|
|
3
4
|
import '@travetto/compiler/bin/hook.js';
|
|
5
|
+
|
|
4
6
|
const { invoke } = await import('@travetto/compiler/support/invoke.ts');
|
|
5
|
-
await invoke('exec',
|
|
7
|
+
await invoke('exec', '@travetto/cli/support/entry.trv.ts', ...process.argv.slice(2));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/cli",
|
|
3
|
-
"version": "8.0.0-alpha.
|
|
3
|
+
"version": "8.0.0-alpha.31",
|
|
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": "^8.0.0-alpha.
|
|
33
|
-
"@travetto/terminal": "^8.0.0-alpha.
|
|
32
|
+
"@travetto/schema": "^8.0.0-alpha.25",
|
|
33
|
+
"@travetto/terminal": "^8.0.0-alpha.22"
|
|
34
34
|
},
|
|
35
35
|
"travetto": {
|
|
36
36
|
"displayName": "Command Line Interface",
|
package/src/color.ts
CHANGED
package/src/execute.ts
CHANGED
|
@@ -1,30 +1,41 @@
|
|
|
1
|
-
import { ConsoleManager, Runtime, ShutdownManager, Util } from '@travetto/runtime';
|
|
1
|
+
import { ConsoleManager, getClass, Runtime, ShutdownManager, Util } from '@travetto/runtime';
|
|
2
2
|
|
|
3
3
|
import { HelpUtil } from './help.ts';
|
|
4
|
+
import { CliParseUtil } from './parse.ts';
|
|
4
5
|
import { CliCommandRegistryIndex } from './registry/registry-index.ts';
|
|
5
6
|
import { CliCommandSchemaUtil } from './schema.ts';
|
|
6
|
-
import { CliParseUtil } from './parse.ts';
|
|
7
7
|
import type { CliCommandShape } from './types.ts';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Execution manager
|
|
11
11
|
*/
|
|
12
12
|
export class ExecutionManager {
|
|
13
|
+
/** Command Execution */
|
|
14
|
+
static async execute(instance: CliCommandShape, args: unknown[]): Promise<void> {
|
|
15
|
+
const config = CliCommandRegistryIndex.get(getClass(instance));
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
for (const item of config.preMain) {
|
|
18
|
+
await item.handler(instance);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Wait 50ms to allow stdout to flush on shutdown
|
|
22
|
+
ShutdownManager.signal.addEventListener('abort', () => Util.blockingTimeout(50));
|
|
23
|
+
ConsoleManager.debug(Runtime.debug);
|
|
24
|
+
await instance.main(...args);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Extract configuration and show help as needed */
|
|
28
|
+
static async getExecutionCommand(argv: string[]): Promise<(() => Promise<void>) | undefined> {
|
|
19
29
|
let command: CliCommandShape | undefined;
|
|
20
30
|
|
|
21
31
|
const { cmd, args, help } = CliParseUtil.getArgs(argv);
|
|
22
32
|
if (!cmd) {
|
|
23
|
-
|
|
33
|
+
console.info!(await HelpUtil.renderAllHelp());
|
|
34
|
+
return;
|
|
24
35
|
}
|
|
25
36
|
|
|
26
37
|
try {
|
|
27
|
-
const [{ instance, schema
|
|
38
|
+
const [{ instance, schema }] = await CliCommandRegistryIndex.load([cmd]);
|
|
28
39
|
command = instance;
|
|
29
40
|
const fullArgs = await CliParseUtil.expandArgs(schema, args);
|
|
30
41
|
|
|
@@ -35,24 +46,31 @@ export class ExecutionManager {
|
|
|
35
46
|
await instance.finalize?.(help);
|
|
36
47
|
|
|
37
48
|
if (help) {
|
|
38
|
-
|
|
49
|
+
console.log!(await HelpUtil.renderCommandHelp(instance));
|
|
50
|
+
return;
|
|
39
51
|
}
|
|
40
52
|
|
|
41
53
|
await CliCommandSchemaUtil.validate(command, boundArgs);
|
|
42
54
|
|
|
43
|
-
|
|
44
|
-
ShutdownManager.signal.addEventListener('abort', () => Util.blockingTimeout(50));
|
|
45
|
-
|
|
46
|
-
for (const preMain of config.preMain ?? []) {
|
|
47
|
-
await preMain(instance);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
ConsoleManager.debug(Runtime.debug);
|
|
51
|
-
await instance.main(...boundArgs);
|
|
55
|
+
return this.execute.bind(this, instance, boundArgs);
|
|
52
56
|
} catch (error) {
|
|
53
57
|
await HelpUtil.renderError(error, cmd, command);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Execute the command line
|
|
63
|
+
* @param args
|
|
64
|
+
*/
|
|
65
|
+
static async run(argv: string[]): Promise<void> {
|
|
66
|
+
try {
|
|
67
|
+
const execute = await this.getExecutionCommand(argv);
|
|
68
|
+
await execute?.();
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error!(error);
|
|
71
|
+
process.exitCode ??= 1;
|
|
54
72
|
} finally {
|
|
55
73
|
await ShutdownManager.shutdown();
|
|
56
74
|
}
|
|
57
75
|
}
|
|
58
|
-
}
|
|
76
|
+
}
|