@travetto/cli 3.0.2 → 3.1.0-rc.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 +362 -42
- package/__index__.ts +5 -2
- package/package.json +4 -5
- package/src/color.ts +4 -4
- package/src/decorators.ts +104 -0
- package/src/execute.ts +94 -36
- package/src/help.ts +104 -170
- package/src/module.ts +63 -0
- package/src/registry.ts +122 -0
- package/src/schema.ts +253 -0
- package/src/types.ts +97 -0
- package/src/util.ts +18 -0
- package/support/cli.cli_schema.ts +36 -0
- package/support/cli.exec.ts +31 -33
- package/support/cli.list.ts +31 -27
- package/support/cli.main.ts +31 -20
- package/support/cli.version-sync.ts +4 -5
- package/support/entry.cli.ts +3 -4
- package/support/transformer.cli.ts +69 -0
- package/src/command-manager.ts +0 -101
- package/src/command.ts +0 -274
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<!-- This file was generated by @travetto/doc and should not be modified directly -->
|
|
2
|
-
<!-- Please modify https://github.com/travetto/travetto/tree/main/module/cli/DOC.
|
|
2
|
+
<!-- Please modify https://github.com/travetto/travetto/tree/main/module/cli/DOC.tsx and execute "npx trv doc" to rebuild -->
|
|
3
3
|
# Command Line Interface
|
|
4
|
+
|
|
4
5
|
## CLI infrastructure for Travetto framework
|
|
5
6
|
|
|
6
7
|
**Install: @travetto/cli**
|
|
@@ -12,11 +13,7 @@ npm install @travetto/cli
|
|
|
12
13
|
yarn add @travetto/cli
|
|
13
14
|
```
|
|
14
15
|
|
|
15
|
-
The cli
|
|
16
|
-
|
|
17
|
-
As is the custom, modules are able to register their own cli extensions as scripts, whose name starts with `cli.`. These scripts are then picked up at runtime and all available options are provided when viewing the help documentation. The following are all the supported cli operations and the various settings they allow.
|
|
18
|
-
|
|
19
|
-
## General
|
|
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`
|
|
20
17
|
|
|
21
18
|
**Terminal: General Usage**
|
|
22
19
|
```bash
|
|
@@ -24,69 +21,392 @@ $ trv --help
|
|
|
24
21
|
|
|
25
22
|
Usage: [options] [command]
|
|
26
23
|
|
|
24
|
+
Commands:
|
|
25
|
+
doc Command line support for generating module docs.
|
|
26
|
+
doc:angular Generate documentation into the angular webapp under related/travetto.github.io
|
|
27
|
+
doc:mapping Generate module mapping for @travetto/doc
|
|
28
|
+
email:compile CLI Entry point for running the email server
|
|
29
|
+
email:editor The email editor compilation service and output serving
|
|
30
|
+
exec Repo execution
|
|
31
|
+
lint Command line support for linting
|
|
32
|
+
lint:register Writes the lint configuration file
|
|
33
|
+
list Allows for listing of modules
|
|
34
|
+
model:export Exports model schemas
|
|
35
|
+
model:install Installing models
|
|
36
|
+
openapi:client CLI for generating the cli client
|
|
37
|
+
openapi:spec CLI for outputting the open api spec to a local file
|
|
38
|
+
pack Standard pack support
|
|
39
|
+
pack:docker Standard docker support for pack
|
|
40
|
+
pack:lambda Standard lambda support for pack
|
|
41
|
+
pack:zip Standard zip support for pack
|
|
42
|
+
repo:publish Publish all pending modules
|
|
43
|
+
repo:version Version all changed dependencies
|
|
44
|
+
run:double Doubles a number
|
|
45
|
+
run:rest Run a rest server as an application
|
|
46
|
+
scaffold Command to run scaffolding
|
|
47
|
+
service Allows for running services
|
|
48
|
+
test Launch test framework and execute tests
|
|
49
|
+
test:watch Invoke the test watcher
|
|
50
|
+
version-sync Enforces all packages to write out their versions and dependencies
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
This listing is from the [Travetto](https://travetto.dev) monorepo, and represents the majority of tools that can be invoked from the command line.
|
|
54
|
+
|
|
55
|
+
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.
|
|
56
|
+
|
|
57
|
+
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:
|
|
58
|
+
* The file must be located in the `support/` folder, and have a name that matches `cli.*.ts`
|
|
59
|
+
* The file must be a class that has a main method
|
|
60
|
+
* The class must use the [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/decorators.ts#L20) decorator
|
|
61
|
+
|
|
62
|
+
**Code: Basic Command**
|
|
63
|
+
```typescript
|
|
64
|
+
import { CliCommand } from '@travetto/cli';
|
|
65
|
+
|
|
66
|
+
@CliCommand()
|
|
67
|
+
export class BasicCommand {
|
|
68
|
+
main() {
|
|
69
|
+
console.log('Hello');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Terminal: Basic Command Help**
|
|
75
|
+
```bash
|
|
76
|
+
$ trv basic -h
|
|
77
|
+
|
|
78
|
+
Usage: doc/cli.basic [options]
|
|
79
|
+
|
|
27
80
|
Options:
|
|
28
|
-
-
|
|
29
|
-
|
|
81
|
+
-h, --help display help for command
|
|
82
|
+
```
|
|
30
83
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
84
|
+
## Command Naming
|
|
85
|
+
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.
|
|
86
|
+
|
|
87
|
+
Examples of mappings:
|
|
88
|
+
* `cli.test.ts` maps to `test`
|
|
89
|
+
* `cli.pack_docker.ts` maps to `pack:docker`
|
|
90
|
+
* `cli.email_template.ts` maps to `email:template`
|
|
91
|
+
The pattern is that underscores(_) translate to colons (:), and the `cli.` prefix, and `.ts` suffix are dropped.
|
|
92
|
+
|
|
93
|
+
## Binding Flags
|
|
94
|
+
[@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/decorators.ts#L20) is a wrapper for [@Schema](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/schema.ts#L14), and so every class that uses the [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/decorators.ts#L20) decorator is now a full [@Schema](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/schema.ts#L14) class. The fields of the class represent the flags that are available to the command.
|
|
95
|
+
|
|
96
|
+
**Code: Basic Command with Flag**
|
|
97
|
+
```typescript
|
|
98
|
+
import { CliCommand } from '@travetto/cli';
|
|
99
|
+
|
|
100
|
+
@CliCommand()
|
|
101
|
+
export class BasicCommand {
|
|
102
|
+
|
|
103
|
+
loud?: boolean;
|
|
104
|
+
|
|
105
|
+
main() {
|
|
106
|
+
console.log(this.loud ? 'HELLO' : 'Hello');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
35
109
|
```
|
|
36
110
|
|
|
37
|
-
|
|
111
|
+
**Terminal: Basic Command with Flag Help**
|
|
112
|
+
```bash
|
|
113
|
+
$ trv basic:flag -h
|
|
114
|
+
|
|
115
|
+
Usage: doc/cli.basic:flag [options]
|
|
116
|
+
|
|
117
|
+
Options:
|
|
118
|
+
-l, --loud
|
|
119
|
+
-h, --help display help for command
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
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.
|
|
123
|
+
|
|
124
|
+
**Terminal: Basic Command with Loud Flag**
|
|
125
|
+
```bash
|
|
126
|
+
$ trv basic:flag --loud
|
|
127
|
+
|
|
128
|
+
HELLO
|
|
129
|
+
```
|
|
38
130
|
|
|
39
|
-
|
|
131
|
+
The [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/decorators.ts#L20) supports the following data types for flags:
|
|
132
|
+
* Boolean values
|
|
133
|
+
* Number values. The [@Integer](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L179), [@Float](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L185), [@Precision](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L173), [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L114) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L124) decorators help provide additional validation.
|
|
134
|
+
* String values. [@MinLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L114), [@MaxLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L124), [@Match](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L106) and [@Enum](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L85) provide additional constraints
|
|
135
|
+
* Date values. The [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L114) and [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L124) decorators help provide additional validation.
|
|
136
|
+
* String lists. Same as String, but allowing multiple values.
|
|
137
|
+
* Numeric lists. Same as Number, but allowing multiple values.
|
|
40
138
|
|
|
41
|
-
|
|
139
|
+
## Binding Arguments
|
|
140
|
+
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.
|
|
42
141
|
|
|
43
|
-
**Code:
|
|
142
|
+
**Code: Basic Command with Arg**
|
|
44
143
|
```typescript
|
|
45
144
|
import { CliCommand } from '@travetto/cli';
|
|
145
|
+
import { Max, Min } from '@travetto/schema';
|
|
46
146
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
*
|
|
50
|
-
* Allows for cleaning of the cache dire
|
|
51
|
-
*/
|
|
52
|
-
export class CliEchoCommand extends CliCommand {
|
|
53
|
-
name = 'echo';
|
|
147
|
+
@CliCommand()
|
|
148
|
+
export class BasicCommand {
|
|
54
149
|
|
|
55
|
-
|
|
56
|
-
|
|
150
|
+
main(@Min(1) @Max(10) volume: number = 1) {
|
|
151
|
+
console.log(volume > 7 ? 'HELLO' : 'Hello');
|
|
57
152
|
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Terminal: Basic Command**
|
|
157
|
+
```bash
|
|
158
|
+
$ trv basic:arg -h
|
|
159
|
+
|
|
160
|
+
Usage: doc/cli.basic:arg [options] [volume:number]
|
|
161
|
+
|
|
162
|
+
Options:
|
|
163
|
+
-h, --help display help for command
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Terminal: Basic Command with Invalid Loud Arg**
|
|
167
|
+
```bash
|
|
168
|
+
$ trv basic:arg 20
|
|
169
|
+
|
|
170
|
+
Execution failed:
|
|
171
|
+
* volume is bigger than (10). [1]
|
|
172
|
+
|
|
173
|
+
Usage: doc/cli.basic:arg [options] [volume:number]
|
|
174
|
+
|
|
175
|
+
Options:
|
|
176
|
+
-h, --help display help for command
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Terminal: Basic Command with Loud Arg > 7**
|
|
180
|
+
```bash
|
|
181
|
+
$ trv basic:arg 8
|
|
182
|
+
|
|
183
|
+
HELLO
|
|
184
|
+
```
|
|
58
185
|
|
|
59
|
-
|
|
60
|
-
|
|
186
|
+
**Terminal: Basic Command without Arg**
|
|
187
|
+
```bash
|
|
188
|
+
$ trv basic:arg
|
|
189
|
+
|
|
190
|
+
Hello
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Additionally, if you provide a field as an array, it will collect all valid values (excludes flags, and any arguments past a `--`).
|
|
194
|
+
|
|
195
|
+
**Code: Basic Command with Arg List**
|
|
196
|
+
```typescript
|
|
197
|
+
import { CliCommand } from '@travetto/cli';
|
|
198
|
+
import { Max, Min } from '@travetto/schema';
|
|
199
|
+
|
|
200
|
+
@CliCommand()
|
|
201
|
+
export class BasicCommand {
|
|
202
|
+
|
|
203
|
+
reverse?: boolean;
|
|
204
|
+
|
|
205
|
+
main(@Min(1) @Max(10) volumes: number[]) {
|
|
206
|
+
console.log(volumes.sort((a, b) => (a - b) * (this.reverse ? -1 : 1)).join(' '));
|
|
61
207
|
}
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Terminal: Basic Command**
|
|
212
|
+
```bash
|
|
213
|
+
$ trv basic:arglist -h
|
|
214
|
+
|
|
215
|
+
Usage: doc/cli.basic:arglist [options] <volumes...:number>
|
|
216
|
+
|
|
217
|
+
Options:
|
|
218
|
+
-r, --reverse
|
|
219
|
+
-h, --help display help for command
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Terminal: Basic Arg List**
|
|
223
|
+
```bash
|
|
224
|
+
$ trv basic:arglist 10 5 3 9 8 1
|
|
62
225
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
226
|
+
1 3 5 8 9 10
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Terminal: Basic Arg List with Invalid Number**
|
|
230
|
+
```bash
|
|
231
|
+
$ trv basic:arglist 10 5 3 9 20 1
|
|
232
|
+
|
|
233
|
+
Execution failed:
|
|
234
|
+
* volumes[4] is bigger than (10). [1]
|
|
235
|
+
|
|
236
|
+
Usage: doc/cli.basic:arglist [options] <volumes...:number>
|
|
237
|
+
|
|
238
|
+
Options:
|
|
239
|
+
-r, --reverse
|
|
240
|
+
-h, --help display help for command
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**Terminal: Basic Arg List with Reverse**
|
|
244
|
+
```bash
|
|
245
|
+
$ trv basic:arglist -r 10 5 3 9 8 1
|
|
246
|
+
|
|
247
|
+
10 9 8 5 3 1
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Customization
|
|
251
|
+
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#L14) behavior, we can leverage the metadata of the fields/parameters to help provide additional customization/context for the users of the commands.
|
|
252
|
+
|
|
253
|
+
**Code: Custom Command with Metadata**
|
|
254
|
+
```typescript
|
|
255
|
+
import { CliCommand } from '@travetto/cli';
|
|
256
|
+
import { Max, Min } from '@travetto/schema';
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Custom Argument Command
|
|
260
|
+
*/
|
|
261
|
+
@CliCommand()
|
|
262
|
+
export class CustomCommand {
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* The message to send back to the user
|
|
266
|
+
* @alias -m
|
|
267
|
+
* @alias --message
|
|
268
|
+
*/
|
|
269
|
+
text: string = 'hello';
|
|
270
|
+
|
|
271
|
+
main(@Min(1) @Max(10) volume: number = 1) {
|
|
272
|
+
console.log(volume > 7 ? this.text.toUpperCase() : this.text);
|
|
68
273
|
}
|
|
69
274
|
}
|
|
70
275
|
```
|
|
71
276
|
|
|
72
|
-
|
|
277
|
+
**Terminal: Custom Command Help**
|
|
278
|
+
```bash
|
|
279
|
+
$ trv custom:arg -h
|
|
280
|
+
|
|
281
|
+
Usage: doc/cli.custom:arg [options] [volume:number]
|
|
282
|
+
|
|
283
|
+
Options:
|
|
284
|
+
-m, --message <string> The message to send back to the user (default: "hello")
|
|
285
|
+
-h, --help display help for command
|
|
286
|
+
```
|
|
73
287
|
|
|
74
|
-
**Terminal:
|
|
288
|
+
**Terminal: Custom Command Help with overridden Text**
|
|
75
289
|
```bash
|
|
76
|
-
$ trv
|
|
290
|
+
$ trv custom:arg 10 -m cUsToM
|
|
291
|
+
|
|
292
|
+
CUSTOM
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Terminal: Custom Command Help with default Text**
|
|
296
|
+
```bash
|
|
297
|
+
$ trv custom:arg 6
|
|
298
|
+
|
|
299
|
+
hello
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Environment Variable Support
|
|
303
|
+
In addition to standard flag overriding (e.g. `/** @alias -m */`), the command execution also supports allowing environment variables to provide values (secondary to whatever is passed in on the command line).
|
|
304
|
+
|
|
305
|
+
**Code: Custom Command with Env Var**
|
|
306
|
+
```typescript
|
|
307
|
+
import { CliCommand } from '@travetto/cli';
|
|
308
|
+
import { Max, Min } from '@travetto/schema';
|
|
77
309
|
|
|
78
|
-
|
|
310
|
+
/**
|
|
311
|
+
* Custom Argument Command
|
|
312
|
+
*/
|
|
313
|
+
@CliCommand()
|
|
314
|
+
export class CustomCommand {
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* The message to send back to the user
|
|
318
|
+
* @alias env.MESSAGE
|
|
319
|
+
*/
|
|
320
|
+
text: string = 'hello';
|
|
321
|
+
|
|
322
|
+
main(@Min(1) @Max(10) volume: number = 1) {
|
|
323
|
+
console.log(volume > 7 ? this.text.toUpperCase() : this.text);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Terminal: Custom Command Help**
|
|
329
|
+
```bash
|
|
330
|
+
$ trv custom:env-arg -h
|
|
331
|
+
|
|
332
|
+
Usage: doc/cli.custom:env-arg [options] [volume:number]
|
|
79
333
|
|
|
80
334
|
Options:
|
|
81
|
-
-
|
|
82
|
-
-h, --help
|
|
335
|
+
-t, --text <string> The message to send back to the user (default: "hello")
|
|
336
|
+
-h, --help display help for command
|
|
83
337
|
```
|
|
84
338
|
|
|
85
|
-
|
|
339
|
+
**Terminal: Custom Command Help with default Text**
|
|
340
|
+
```bash
|
|
341
|
+
$ trv custom:env-arg 6
|
|
342
|
+
|
|
343
|
+
hello
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Terminal: Custom Command Help with overridden Text**
|
|
347
|
+
```bash
|
|
348
|
+
$ MESSAGE=CuStOm trv custom:env-arg 10
|
|
349
|
+
|
|
350
|
+
CUSTOM
|
|
351
|
+
```
|
|
86
352
|
|
|
87
|
-
**Terminal:
|
|
353
|
+
**Terminal: Custom Command Help with overridden Text**
|
|
88
354
|
```bash
|
|
89
|
-
$ trv
|
|
355
|
+
$ MESSAGE=CuStOm trv custom:env-arg 7
|
|
356
|
+
|
|
357
|
+
CuStOm
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## VSCode Integration
|
|
361
|
+
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. [RESTful API](https://github.com/travetto/travetto/tree/main/module/rest#readme "Declarative api for RESTful APIs with support for the dependency injection module.") does expose a cli target `run:rest` that will show up, to help run/debug a rest 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).
|
|
362
|
+
|
|
363
|
+
**Code: Simple Run Target**
|
|
364
|
+
```typescript
|
|
365
|
+
import { CliCommand } from '@travetto/cli';
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Simple Run Target
|
|
369
|
+
*/
|
|
370
|
+
@CliCommand({ runTarget: true })
|
|
371
|
+
export class RunCommand {
|
|
372
|
+
|
|
373
|
+
main(name: string) {
|
|
374
|
+
console.log(name);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Also, any command name that starts with `run:` (i.e. `support/cli.run_*.ts`), will be opted-in to the run behavior unless explicitly disabled.
|
|
380
|
+
|
|
381
|
+
## Advanced Usage
|
|
382
|
+
If the goal is to run a more complex application, which may include depending on [Dependency Injection](https://github.com/travetto/travetto/tree/main/module/di#readme "Dependency registration/management and injection support."), we can take a look at [RESTful API](https://github.com/travetto/travetto/tree/main/module/rest#readme "Declarative api for RESTful APIs with support for the dependency injection module.")'s target:
|
|
383
|
+
|
|
384
|
+
**Code: Simple Run Target**
|
|
385
|
+
```typescript
|
|
386
|
+
import { DependencyRegistry } from '@travetto/di';
|
|
387
|
+
import { CliCommand } from '@travetto/cli';
|
|
388
|
+
import { ServerHandle } from '../src/types';
|
|
90
389
|
|
|
91
|
-
|
|
390
|
+
/**
|
|
391
|
+
* Run a rest server as an application
|
|
392
|
+
*/
|
|
393
|
+
@CliCommand({ fields: ['module', 'env', 'profile'] })
|
|
394
|
+
export class RunRestCommand {
|
|
395
|
+
|
|
396
|
+
/** Port to run on */
|
|
397
|
+
port?: number;
|
|
398
|
+
|
|
399
|
+
envInit(): Record<string, string | number | boolean> {
|
|
400
|
+
return this.port ? { REST_PORT: `${this.port}` } : {};
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
async main(): Promise<ServerHandle> {
|
|
404
|
+
const { RestApplication } = await import('../src/application/rest.js');
|
|
405
|
+
return DependencyRegistry.runInstance(RestApplication);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
92
408
|
```
|
|
409
|
+
|
|
410
|
+
As noted in the example above, `fields` is specified in this execution, with support for `module`, `env`, and `profile`. These env and profile flags are directly tied to the GlobalEnv flags defined in the [Base](https://github.com/travetto/travetto/tree/main/module/base#readme "Environment config and common utilities for travetto applications.") module.
|
|
411
|
+
|
|
412
|
+
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.
|
package/__index__.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
export * from './src/
|
|
2
|
-
export * from './src/
|
|
1
|
+
export * from './src/types';
|
|
2
|
+
export * from './src/decorators';
|
|
3
3
|
export * from './src/execute';
|
|
4
|
+
export * from './src/schema';
|
|
5
|
+
export * from './src/registry';
|
|
4
6
|
export * from './src/help';
|
|
5
7
|
export * from './src/color';
|
|
6
8
|
export * from './src/module';
|
|
7
9
|
export * from './src/scm';
|
|
10
|
+
export * from './src/util';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/cli",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.1.0-rc.0",
|
|
4
4
|
"description": "CLI infrastructure for Travetto framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -24,10 +24,9 @@
|
|
|
24
24
|
"directory": "module/cli"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@travetto/
|
|
28
|
-
"@travetto/terminal": "^3.0.
|
|
29
|
-
"@travetto/worker": "^3.0.
|
|
30
|
-
"commander": "^10.0.0"
|
|
27
|
+
"@travetto/schema": "^3.1.0-rc.0",
|
|
28
|
+
"@travetto/terminal": "^3.1.0-rc.0",
|
|
29
|
+
"@travetto/worker": "^3.1.0-rc.0"
|
|
31
30
|
},
|
|
32
31
|
"travetto": {
|
|
33
32
|
"displayName": "Command Line Interface"
|
package/src/color.ts
CHANGED
|
@@ -7,12 +7,12 @@ const tplFn = GlobalTerminal.templateFunction({
|
|
|
7
7
|
path: 'teal',
|
|
8
8
|
success: 'green',
|
|
9
9
|
failure: 'red',
|
|
10
|
-
param: 'yellow',
|
|
10
|
+
param: ['yellow', 'goldenrod'],
|
|
11
11
|
type: 'cyan',
|
|
12
|
-
description: 'white',
|
|
13
|
-
title: 'brightWhite',
|
|
12
|
+
description: ['white', 'gray'],
|
|
13
|
+
title: ['brightWhite', 'black'],
|
|
14
14
|
identifier: 'dodgerBlue',
|
|
15
|
-
subtitle: 'lightGray',
|
|
15
|
+
subtitle: ['lightGray', 'darkGray'],
|
|
16
16
|
subsubtitle: 'darkGray'
|
|
17
17
|
});
|
|
18
18
|
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { Class, ClassInstance, ConcreteClass, ConsoleManager, defineGlobalEnv } from '@travetto/base';
|
|
2
|
+
import { RootIndex } from '@travetto/manifest';
|
|
3
|
+
import { SchemaRegistry } from '@travetto/schema';
|
|
4
|
+
|
|
5
|
+
import { CliCommandShape } from './types';
|
|
6
|
+
import { CliCommandRegistry } from './registry';
|
|
7
|
+
import { CliModuleUtil } from './module';
|
|
8
|
+
import { CliUtil } from './util';
|
|
9
|
+
|
|
10
|
+
type ExtraFields = 'module' | 'profile' | 'env';
|
|
11
|
+
|
|
12
|
+
const getName = (source: string): string => source.match(/cli.(.*)[.]tsx?$/)![1].replaceAll('_', ':');
|
|
13
|
+
const getMod = (cls: Class): string => RootIndex.getModuleFromSource(RootIndex.getFunctionMetadata(cls)!.source)!.name;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Decorator to register a CLI command
|
|
17
|
+
* @augments `@travetto/schema:Schema`
|
|
18
|
+
* @augments `@travetto/cli:CliCommand`
|
|
19
|
+
*/
|
|
20
|
+
export function CliCommand(cfg: { fields?: ExtraFields[], runTarget?: boolean, hidden?: boolean } = {}) {
|
|
21
|
+
return function <T extends CliCommandShape>(target: Class<T>): void {
|
|
22
|
+
const meta = RootIndex.getFunctionMetadata(target);
|
|
23
|
+
if (!meta || meta.abstract) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const name = getName(meta.source);
|
|
28
|
+
const addEnv = cfg.fields?.includes('env');
|
|
29
|
+
const addProfile = cfg.fields?.includes('profile');
|
|
30
|
+
const addModule = cfg.fields?.includes('module');
|
|
31
|
+
|
|
32
|
+
CliCommandRegistry.registerClass({
|
|
33
|
+
module: getMod(target),
|
|
34
|
+
name,
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
36
|
+
cls: target as ConcreteClass<T>,
|
|
37
|
+
hidden: cfg.hidden,
|
|
38
|
+
runTarget: cfg.runTarget ?? name.startsWith('run:'),
|
|
39
|
+
preMain: (cmd: CliCommandShape & { env?: string, profile?: string[], module?: string }) => {
|
|
40
|
+
if (addEnv) { defineGlobalEnv({ envName: cmd.env }); }
|
|
41
|
+
if (addProfile) { defineGlobalEnv({ profiles: cmd.profile }); }
|
|
42
|
+
if (addEnv || addProfile) { ConsoleManager.setDebugFromEnv(); }
|
|
43
|
+
if (addModule && cmd.module && cmd.module !== RootIndex.mainModule.name) { // Mono-repo support
|
|
44
|
+
RootIndex.reinitForModule(cmd.module); // Reinit with specified module
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const pendingCls = SchemaRegistry.getOrCreatePending(target);
|
|
50
|
+
|
|
51
|
+
if (addEnv) {
|
|
52
|
+
SchemaRegistry.registerPendingFieldConfig(target, 'env', String, {
|
|
53
|
+
aliases: ['e'],
|
|
54
|
+
description: 'Application environment',
|
|
55
|
+
required: { active: false }
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (addProfile) {
|
|
60
|
+
SchemaRegistry.registerPendingFieldConfig(target, 'profile', [String], {
|
|
61
|
+
aliases: ['p'],
|
|
62
|
+
description: 'Additional application profiles',
|
|
63
|
+
required: { active: false }
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (addModule) {
|
|
68
|
+
SchemaRegistry.registerPendingFieldConfig(target, 'module', String, {
|
|
69
|
+
aliases: ['m', 'env.TRV_MODULE'],
|
|
70
|
+
description: 'Module to run for',
|
|
71
|
+
required: { active: CliUtil.monoRoot }
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Register validator for module
|
|
75
|
+
(pendingCls.validators ??= []).push(item =>
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
77
|
+
CliModuleUtil.validateCommandModule(getMod(target), item as { module?: string })
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Decorator to register a CLI command flag
|
|
85
|
+
*/
|
|
86
|
+
export function CliFlag(cfg: { name?: string, short?: string, desc?: string, file?: boolean, envVars?: string[] }) {
|
|
87
|
+
return function (target: ClassInstance, prop: string | symbol): void {
|
|
88
|
+
const aliases: string[] = [];
|
|
89
|
+
if (cfg.name) {
|
|
90
|
+
aliases.push(cfg.name.startsWith('-') ? cfg.name : `--${cfg.name}`);
|
|
91
|
+
}
|
|
92
|
+
if (cfg.short) {
|
|
93
|
+
aliases.push(cfg.short.startsWith('-') ? cfg.short : `-${cfg.short}`);
|
|
94
|
+
}
|
|
95
|
+
if (cfg.envVars) {
|
|
96
|
+
aliases.push(...cfg.envVars.map(v => `env.${v}`));
|
|
97
|
+
}
|
|
98
|
+
if (typeof prop === 'string') {
|
|
99
|
+
SchemaRegistry.registerPendingFieldFacet(target.constructor, prop, {
|
|
100
|
+
aliases, description: cfg.desc, specifier: cfg.file ? 'file' : undefined
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|