@expressots/cli 4.0.0-preview.2 โ 4.0.0-preview.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cicd/cli.d.ts +1 -1
- package/bin/cicd/cli.js +3 -1
- package/bin/cicd/form.js +5 -4
- package/bin/cli.d.ts +1 -5
- package/bin/cli.js +56 -6
- package/bin/commands/project.commands.js +233 -26
- package/bin/containerize/cli.d.ts +1 -1
- package/bin/containerize/cli.js +1 -1
- package/bin/containerize/form.js +49 -51
- package/bin/containerize/generators/ci-generator.js +16 -12
- package/bin/containerize/generators/docker-compose-generator.js +3 -2
- package/bin/containerize/generators/dockerfile-generator.js +50 -28
- package/bin/containerize/generators/kubernetes-generator.js +5 -4
- package/bin/costs/cli.d.ts +1 -1
- package/bin/costs/cli.js +4 -2
- package/bin/dev/cli.d.ts +1 -1
- package/bin/dev/cli.js +3 -1
- package/bin/generate/cli.d.ts +1 -1
- package/bin/generate/templates/nonopinionated/config.tpl +12 -12
- package/bin/generate/templates/nonopinionated/event.tpl +10 -10
- package/bin/generate/templates/nonopinionated/guard.tpl +18 -18
- package/bin/generate/templates/nonopinionated/handler.tpl +12 -12
- package/bin/generate/templates/nonopinionated/interceptor.tpl +27 -27
- package/bin/generate/templates/opinionated/config.tpl +47 -47
- package/bin/generate/templates/opinionated/event.tpl +15 -15
- package/bin/generate/templates/opinionated/guard.tpl +41 -41
- package/bin/generate/templates/opinionated/handler.tpl +23 -23
- package/bin/generate/templates/opinionated/interceptor.tpl +50 -50
- package/bin/generate/utils/command-utils.d.ts +13 -2
- package/bin/generate/utils/command-utils.js +50 -17
- package/bin/generate/utils/opinionated-cmd.js +19 -12
- package/bin/help/cli.d.ts +1 -1
- package/bin/help/command-help-registry.d.ts +23 -0
- package/bin/help/command-help-registry.js +303 -0
- package/bin/help/command-help.d.ts +36 -0
- package/bin/help/command-help.js +56 -0
- package/bin/help/form.js +127 -30
- package/bin/help/main-help.d.ts +8 -0
- package/bin/help/main-help.js +126 -0
- package/bin/help/render.d.ts +32 -0
- package/bin/help/render.js +46 -0
- package/bin/info/cli.d.ts +1 -1
- package/bin/info/form.d.ts +1 -1
- package/bin/info/form.js +11 -11
- package/bin/migrate/cli.d.ts +1 -1
- package/bin/migrate/cli.js +3 -1
- package/bin/migrate/form.js +4 -3
- package/bin/new/cli.d.ts +5 -1
- package/bin/new/cli.js +62 -14
- package/bin/new/form.d.ts +3 -1
- package/bin/new/form.js +338 -23
- package/bin/profile/cli.d.ts +1 -1
- package/bin/profile/cli.js +3 -1
- package/bin/profile/form.js +5 -4
- package/bin/providers/create/form.js +53 -4
- package/bin/studio/cli.js +9 -3
- package/bin/templates/cli.js +7 -5
- package/bin/utils/add-module-to-container.d.ts +14 -3
- package/bin/utils/add-module-to-container.js +330 -111
- package/bin/utils/cli-ui.d.ts +20 -1
- package/bin/utils/cli-ui.js +41 -3
- package/bin/utils/update-tsconfig-paths.js +73 -33
- package/package.json +22 -13
|
@@ -74,19 +74,20 @@ async function opinionatedProcess(schematic, target, method, expressoConfig, pat
|
|
|
74
74
|
method,
|
|
75
75
|
expressoConfig,
|
|
76
76
|
});
|
|
77
|
+
let moduleFile = m.file;
|
|
77
78
|
if (pathStyle === "sugar" /* PathStyle.Sugar */) {
|
|
78
|
-
await generateModuleServiceSugarPath(f.outputPath, m.className, m.moduleName, m.path, m.
|
|
79
|
+
moduleFile = await generateModuleServiceSugarPath(f.outputPath, m.className, m.moduleName, m.path, m.folderToScaffold);
|
|
79
80
|
}
|
|
80
81
|
else if (pathStyle === "nested" /* PathStyle.Nested */) {
|
|
81
|
-
await generateModuleServiceNestedPath(f.outputPath, m.className, m.path, m.folderToScaffold);
|
|
82
|
+
moduleFile = await generateModuleServiceNestedPath(f.outputPath, m.className, m.path, m.folderToScaffold);
|
|
82
83
|
}
|
|
83
84
|
else if (pathStyle === "single" /* PathStyle.Single */) {
|
|
84
|
-
await generateModuleServiceSinglePath(f.outputPath, m.className, m.moduleName, m.path, m.file, m.folderToScaffold);
|
|
85
|
+
moduleFile = await generateModuleServiceSinglePath(f.outputPath, m.className, m.moduleName, m.path, m.file, m.folderToScaffold);
|
|
85
86
|
}
|
|
86
87
|
await (0, cli_ui_1.printGenerateSuccess)("controller", f.file);
|
|
87
88
|
await (0, cli_ui_1.printGenerateSuccess)("usecase", f.file);
|
|
88
89
|
await (0, cli_ui_1.printGenerateSuccess)("dto", f.file);
|
|
89
|
-
await (0, cli_ui_1.printGenerateSuccess)("module",
|
|
90
|
+
await (0, cli_ui_1.printGenerateSuccess)("module", moduleFile);
|
|
90
91
|
break;
|
|
91
92
|
}
|
|
92
93
|
case "usecase":
|
|
@@ -369,8 +370,11 @@ async function generateMiddleware(outputPath, className, moduleName, path) {
|
|
|
369
370
|
* @param moduleName - The module name
|
|
370
371
|
* @param path - The path
|
|
371
372
|
*/
|
|
372
|
-
async function generateModuleServiceSugarPath(outputPathController, className, moduleName, path,
|
|
373
|
-
|
|
373
|
+
async function generateModuleServiceSugarPath(outputPathController, className, moduleName, path, folderToScaffold) {
|
|
374
|
+
// The module file is named after the feature (first word), e.g. `user`, and
|
|
375
|
+
// lives at the feature root (`useCases/user/user.module.ts`), grouping all of
|
|
376
|
+
// the feature's use-cases. `moduleName` already carries the feature word.
|
|
377
|
+
const newModuleFile = await (0, command_utils_1.getNameWithScaffoldPattern)(moduleName);
|
|
374
378
|
const newModulePath = nodePath
|
|
375
379
|
.join(folderToScaffold, path, "..")
|
|
376
380
|
.normalize();
|
|
@@ -387,7 +391,7 @@ async function generateModuleServiceSugarPath(outputPathController, className, m
|
|
|
387
391
|
.normalize();
|
|
388
392
|
if (fs_1.default.existsSync(newModuleOutputPath)) {
|
|
389
393
|
await (0, add_controller_to_module_1.addControllerToModule)(controllerFullPath, `${className}Controller`, controllerToModule);
|
|
390
|
-
return;
|
|
394
|
+
return newModuleName;
|
|
391
395
|
}
|
|
392
396
|
(0, command_utils_1.writeTemplate)({
|
|
393
397
|
outputPath: newModuleOutputPath,
|
|
@@ -402,7 +406,8 @@ async function generateModuleServiceSugarPath(outputPathController, className, m
|
|
|
402
406
|
});
|
|
403
407
|
// Extract folder name from folderToScaffold (e.g., "src/useCases" -> "useCases")
|
|
404
408
|
const folderName = nodePath.basename(folderToScaffold);
|
|
405
|
-
await (0, add_module_to_container_1.
|
|
409
|
+
await (0, add_module_to_container_1.addModuleToContainerByPath)(`${(0, string_utils_1.anyCaseToPascalCase)(moduleName)}Module`, newModuleOutputPath, folderToScaffold, folderName);
|
|
410
|
+
return newModuleName;
|
|
406
411
|
}
|
|
407
412
|
/**
|
|
408
413
|
* Generate a module for service scaffolding with single path
|
|
@@ -427,7 +432,7 @@ async function generateModuleServiceSinglePath(outputPathController, className,
|
|
|
427
432
|
.normalize();
|
|
428
433
|
if (fs_1.default.existsSync(newModuleOutputPath)) {
|
|
429
434
|
await (0, add_controller_to_module_1.addControllerToModule)(controllerFullPath, `${className}Controller`, controllerToModule);
|
|
430
|
-
return;
|
|
435
|
+
return newModuleName;
|
|
431
436
|
}
|
|
432
437
|
(0, command_utils_1.writeTemplate)({
|
|
433
438
|
outputPath: newModuleOutputPath,
|
|
@@ -442,7 +447,8 @@ async function generateModuleServiceSinglePath(outputPathController, className,
|
|
|
442
447
|
});
|
|
443
448
|
// Extract folder name from folderToScaffold (e.g., "src/useCases" -> "useCases")
|
|
444
449
|
const folderName = nodePath.basename(folderToScaffold);
|
|
445
|
-
await (0, add_module_to_container_1.
|
|
450
|
+
await (0, add_module_to_container_1.addModuleToContainerByPath)(`${(0, string_utils_1.anyCaseToPascalCase)(moduleName)}Module`, newModuleOutputPath, folderToScaffold, folderName);
|
|
451
|
+
return newModuleName;
|
|
446
452
|
}
|
|
447
453
|
/**
|
|
448
454
|
* Generate a module for service scaffolding with nested path
|
|
@@ -470,7 +476,7 @@ async function generateModuleServiceNestedPath(outputPathController, className,
|
|
|
470
476
|
.normalize();
|
|
471
477
|
if (fs_1.default.existsSync(newModuleOutputPath)) {
|
|
472
478
|
await (0, add_controller_to_module_1.addControllerToModule)(controllerFullPath, `${className}Controller`, controllerToModule);
|
|
473
|
-
return;
|
|
479
|
+
return newModuleName;
|
|
474
480
|
}
|
|
475
481
|
(0, command_utils_1.writeTemplate)({
|
|
476
482
|
outputPath: newModuleOutputPath,
|
|
@@ -485,7 +491,8 @@ async function generateModuleServiceNestedPath(outputPathController, className,
|
|
|
485
491
|
});
|
|
486
492
|
// Extract folder name from folderToScaffold (e.g., "src/useCases" -> "useCases")
|
|
487
493
|
const folderName = nodePath.basename(folderToScaffold);
|
|
488
|
-
await (0, add_module_to_container_1.
|
|
494
|
+
await (0, add_module_to_container_1.addModuleToContainerByPath)(`${(0, string_utils_1.anyCaseToPascalCase)(moduleFileName)}Module`, newModuleOutputPath, folderToScaffold, folderName);
|
|
495
|
+
return newModuleName;
|
|
489
496
|
}
|
|
490
497
|
/**
|
|
491
498
|
* Generate a module
|
package/bin/help/cli.d.ts
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type CommandHelpSpec } from "./command-help";
|
|
2
|
+
/**
|
|
3
|
+
* Structured help specs for the subcommands whose option-heavy `--help` would
|
|
4
|
+
* otherwise render as yargs' sprawling default table. Keeping them here lets
|
|
5
|
+
* the central interceptor in `cli.ts` render a refined, grouped screen that
|
|
6
|
+
* matches the rest of the CLI without touching each command's yargs builder.
|
|
7
|
+
*
|
|
8
|
+
* NOTE: these mirror the option definitions in each command's `cli.ts`. When
|
|
9
|
+
* an option/choice/default changes there, update the matching entry here.
|
|
10
|
+
*/
|
|
11
|
+
declare const SPECS: CommandHelpSpec[];
|
|
12
|
+
/**
|
|
13
|
+
* Resolve a command token (name or alias) to its help spec, if any.
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveCommandHelpSpec(token: string): CommandHelpSpec | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Detect a `<command> --help` / `<command> -h` invocation and, if the command
|
|
18
|
+
* has a registered spec, render the refined help screen.
|
|
19
|
+
*
|
|
20
|
+
* @returns `true` when custom help was printed (caller should exit), else `false`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function tryPrintCommandHelp(args: string[], version?: string): boolean;
|
|
23
|
+
export { SPECS as COMMAND_HELP_SPECS };
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.COMMAND_HELP_SPECS = exports.tryPrintCommandHelp = exports.resolveCommandHelpSpec = void 0;
|
|
4
|
+
const command_help_1 = require("./command-help");
|
|
5
|
+
/**
|
|
6
|
+
* Structured help specs for the subcommands whose option-heavy `--help` would
|
|
7
|
+
* otherwise render as yargs' sprawling default table. Keeping them here lets
|
|
8
|
+
* the central interceptor in `cli.ts` render a refined, grouped screen that
|
|
9
|
+
* matches the rest of the CLI without touching each command's yargs builder.
|
|
10
|
+
*
|
|
11
|
+
* NOTE: these mirror the option definitions in each command's `cli.ts`. When
|
|
12
|
+
* an option/choice/default changes there, update the matching entry here.
|
|
13
|
+
*/
|
|
14
|
+
const SPECS = [
|
|
15
|
+
{
|
|
16
|
+
name: "costs",
|
|
17
|
+
aliases: ["cost", "pricing"],
|
|
18
|
+
usage: "expressots costs <action> [options]",
|
|
19
|
+
description: "Estimate and compare cloud deployment costs.",
|
|
20
|
+
groups: [
|
|
21
|
+
{
|
|
22
|
+
title: "Actions",
|
|
23
|
+
entries: [
|
|
24
|
+
(0, command_help_1.helpEntry)("estimate", "Estimate cost for a provider/service"),
|
|
25
|
+
(0, command_help_1.helpEntry)("compare", "Compare costs across providers"),
|
|
26
|
+
(0, command_help_1.helpEntry)("optimize", "Suggest cost optimizations"),
|
|
27
|
+
(0, command_help_1.helpEntry)("pricing", "Show current pricing data"),
|
|
28
|
+
(0, command_help_1.helpEntry)("update", "Refresh pricing data from remote"),
|
|
29
|
+
(0, command_help_1.helpEntry)("info", "Show pricing system status & providers"),
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
title: "Options",
|
|
34
|
+
entries: [
|
|
35
|
+
(0, command_help_1.helpEntry)("-p, --provider", "Cloud provider", "aws, gcp, azure, railway, render, fly, digitalocean, heroku"),
|
|
36
|
+
(0, command_help_1.helpEntry)("-s, --service", "Service type", "ecs, eks, lambda, cloudrun, gke, aci, aks, web-service"),
|
|
37
|
+
(0, command_help_1.helpEntry)("-i, --instances", "Instances / replicas", "default: 1"),
|
|
38
|
+
(0, command_help_1.helpEntry)("-c, --cpu", "vCPUs per instance", "default: 1"),
|
|
39
|
+
(0, command_help_1.helpEntry)("-m, --memory", "Memory (GB) per instance", "default: 1"),
|
|
40
|
+
(0, command_help_1.helpEntry)("--storage", "Storage in GB", "default: 10"),
|
|
41
|
+
(0, command_help_1.helpEntry)("--bandwidth", "Bandwidth GB/month", "default: 100"),
|
|
42
|
+
(0, command_help_1.helpEntry)("-r, --region", "Cloud region", "default: us-east-1"),
|
|
43
|
+
(0, command_help_1.helpEntry)("--hours", "Running hours/month", "default: 720"),
|
|
44
|
+
(0, command_help_1.helpEntry)("--format", "Output format", "text, json, markdown ยท default: text"),
|
|
45
|
+
(0, command_help_1.helpEntry)("-o, --output", "Write output to a file"),
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: "cicd",
|
|
52
|
+
aliases: ["ci", "pipeline"],
|
|
53
|
+
usage: "expressots cicd <action> [platform] [options]",
|
|
54
|
+
description: "Generate and manage CI/CD pipeline configurations.",
|
|
55
|
+
groups: [
|
|
56
|
+
{
|
|
57
|
+
title: "Actions",
|
|
58
|
+
entries: [
|
|
59
|
+
(0, command_help_1.helpEntry)("init", "Interactive pipeline setup"),
|
|
60
|
+
(0, command_help_1.helpEntry)("generate", "Generate pipeline configuration"),
|
|
61
|
+
(0, command_help_1.helpEntry)("list", "List supported platforms"),
|
|
62
|
+
(0, command_help_1.helpEntry)("validate", "Validate existing pipelines"),
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
title: "Arguments",
|
|
67
|
+
entries: [
|
|
68
|
+
(0, command_help_1.helpEntry)("platform", "CI/CD platform", "github, gitlab, circleci, jenkins, bitbucket, azure, all"),
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
title: "Options",
|
|
73
|
+
entries: [
|
|
74
|
+
(0, command_help_1.helpEntry)("-s, --strategy", "Pipeline strategy", "basic, comprehensive, security-focused ยท default: comprehensive"),
|
|
75
|
+
(0, command_help_1.helpEntry)("--include-security", "Security scanning (Trivy, Snyk)", "default: true"),
|
|
76
|
+
(0, command_help_1.helpEntry)("--include-e2e", "End-to-end tests", "default: false"),
|
|
77
|
+
(0, command_help_1.helpEntry)("--include-coverage", "Coverage reporting", "default: true"),
|
|
78
|
+
(0, command_help_1.helpEntry)("-r, --docker-registry", "Docker registry URL", "e.g. ghcr.io, docker.io"),
|
|
79
|
+
(0, command_help_1.helpEntry)("--deploy-target", "Deploy target", "kubernetes, ecs, cloudrun, railway, render, fly, none ยท default: none"),
|
|
80
|
+
(0, command_help_1.helpEntry)("-b, --branch", "Trigger branch", "default: main"),
|
|
81
|
+
(0, command_help_1.helpEntry)("--node-version", "Node.js version", "default: 20"),
|
|
82
|
+
(0, command_help_1.helpEntry)("-o, --output-dir", "Output directory"),
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "migrate",
|
|
89
|
+
aliases: ["migration", "mig"],
|
|
90
|
+
usage: "expressots migrate <action> [options]",
|
|
91
|
+
description: "Generate migration scripts between cloud platforms.",
|
|
92
|
+
groups: [
|
|
93
|
+
{
|
|
94
|
+
title: "Actions",
|
|
95
|
+
entries: [
|
|
96
|
+
(0, command_help_1.helpEntry)("init", "Interactive migration setup"),
|
|
97
|
+
(0, command_help_1.helpEntry)("generate", "Generate migration scripts"),
|
|
98
|
+
(0, command_help_1.helpEntry)("list", "List supported platforms"),
|
|
99
|
+
(0, command_help_1.helpEntry)("analyze", "Analyze a migration path"),
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
title: "Options",
|
|
104
|
+
entries: [
|
|
105
|
+
(0, command_help_1.helpEntry)("-f, --from", "Source platform", "heroku, docker-compose, vercel, aws-ecs, gcp-cloudrun, azure-container"),
|
|
106
|
+
(0, command_help_1.helpEntry)("-t, --to", "Target platform", "railway, render, fly, kubernetes, aws-ecs, gcp-cloudrun, azure-container"),
|
|
107
|
+
(0, command_help_1.helpEntry)("--include-data", "Include data migration", "default: false"),
|
|
108
|
+
(0, command_help_1.helpEntry)("--include-secrets", "Include secrets/env migration", "default: true"),
|
|
109
|
+
(0, command_help_1.helpEntry)("--dry-run", "Preview without writing files", "default: false"),
|
|
110
|
+
(0, command_help_1.helpEntry)("-o, --output-dir", "Output directory", "default: ./migration"),
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: "profile",
|
|
117
|
+
aliases: ["prof", "analyze"],
|
|
118
|
+
usage: "expressots profile <action> [target] [options]",
|
|
119
|
+
description: "Analyze and optimize container configurations.",
|
|
120
|
+
groups: [
|
|
121
|
+
{
|
|
122
|
+
title: "Actions",
|
|
123
|
+
entries: [
|
|
124
|
+
(0, command_help_1.helpEntry)("container", "Analyze a container configuration"),
|
|
125
|
+
(0, command_help_1.helpEntry)("image", "Analyze a Docker image"),
|
|
126
|
+
(0, command_help_1.helpEntry)("optimize", "Suggest Dockerfile optimizations"),
|
|
127
|
+
(0, command_help_1.helpEntry)("report", "Show the latest profile report"),
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
title: "Arguments",
|
|
132
|
+
entries: [(0, command_help_1.helpEntry)("target", "Dockerfile path or image name")],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
title: "Options",
|
|
136
|
+
entries: [
|
|
137
|
+
(0, command_help_1.helpEntry)("-f, --dockerfile", "Path to Dockerfile", "default: Dockerfile"),
|
|
138
|
+
(0, command_help_1.helpEntry)("--format", "Output format", "text, json, html ยท default: text"),
|
|
139
|
+
(0, command_help_1.helpEntry)("--severity", "Minimum severity", "low, medium, high, critical ยท default: low"),
|
|
140
|
+
(0, command_help_1.helpEntry)("--auto-fix", "Apply safe optimizations", "default: false"),
|
|
141
|
+
(0, command_help_1.helpEntry)("-o, --output", "Output file for report"),
|
|
142
|
+
(0, command_help_1.helpEntry)("--include-security", "Security vulnerability scan", "default: true"),
|
|
143
|
+
(0, command_help_1.helpEntry)("--include-size", "Size analysis", "default: true"),
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: "containerize",
|
|
150
|
+
aliases: ["ctr"],
|
|
151
|
+
usage: "expressots containerize [target] [environment] [options]",
|
|
152
|
+
description: "Generate container configurations for your ExpressoTS application.",
|
|
153
|
+
groups: [
|
|
154
|
+
{
|
|
155
|
+
title: "Arguments",
|
|
156
|
+
entries: [
|
|
157
|
+
(0, command_help_1.helpEntry)("target", "Target platform", "docker, kubernetes, k8s, compose ยท default: docker"),
|
|
158
|
+
(0, command_help_1.helpEntry)("environment", "Target environment", "development, staging, production, all ยท default: production"),
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
title: "Options",
|
|
163
|
+
entries: [
|
|
164
|
+
(0, command_help_1.helpEntry)("--preset", "Container preset", "minimal, secure, fast-startup, dev, multi-arch, standard ยท default: standard"),
|
|
165
|
+
(0, command_help_1.helpEntry)("--analyze", "Analyze project before generating", "default: true"),
|
|
166
|
+
(0, command_help_1.helpEntry)("--skip-compose", "Skip docker-compose.yml", "default: false"),
|
|
167
|
+
(0, command_help_1.helpEntry)("--include-ci", "Include CI/CD pipeline", "default: false"),
|
|
168
|
+
(0, command_help_1.helpEntry)("--ci-platform", "CI/CD platform", "github, gitlab, circleci, jenkins, bitbucket, azure, all ยท default: github"),
|
|
169
|
+
(0, command_help_1.helpEntry)("--ci-strategy", "CI/CD strategy", "basic, comprehensive, security-focused ยท default: comprehensive"),
|
|
170
|
+
(0, command_help_1.helpEntry)("--include-security-scans", "Security scanning (Trivy, Snyk)", "default: true"),
|
|
171
|
+
(0, command_help_1.helpEntry)("--include-e2e", "End-to-end tests in CI", "default: false"),
|
|
172
|
+
],
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: "container-dev",
|
|
178
|
+
aliases: ["cdev", "docker-dev"],
|
|
179
|
+
usage: "expressots container-dev [action] [options]",
|
|
180
|
+
description: "Develop inside Docker containers with hot reload.",
|
|
181
|
+
groups: [
|
|
182
|
+
{
|
|
183
|
+
title: "Actions",
|
|
184
|
+
entries: [
|
|
185
|
+
(0, command_help_1.helpEntry)("start", "Start the dev container (default)"),
|
|
186
|
+
(0, command_help_1.helpEntry)("stop", "Stop the dev container"),
|
|
187
|
+
(0, command_help_1.helpEntry)("attach", "Attach to the running container"),
|
|
188
|
+
(0, command_help_1.helpEntry)("shell", "Open a shell in the container"),
|
|
189
|
+
(0, command_help_1.helpEntry)("status", "Show container status"),
|
|
190
|
+
(0, command_help_1.helpEntry)("logs", "Show container logs"),
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
title: "Options",
|
|
195
|
+
entries: [
|
|
196
|
+
(0, command_help_1.helpEntry)("-c, --container", "Run dev inside Docker", "default: false"),
|
|
197
|
+
(0, command_help_1.helpEntry)("-s, --service", "Compose service name", "default: app"),
|
|
198
|
+
(0, command_help_1.helpEntry)("-f, --compose-file", "docker-compose file", "default: docker-compose.development.yml"),
|
|
199
|
+
(0, command_help_1.helpEntry)("-b, --build", "Rebuild before starting", "default: false"),
|
|
200
|
+
(0, command_help_1.helpEntry)("-d, --detach", "Run in background", "default: false"),
|
|
201
|
+
(0, command_help_1.helpEntry)("-p, --port", "Override application port"),
|
|
202
|
+
(0, command_help_1.helpEntry)("--debug-port", "Node inspector port", "default: 9229"),
|
|
203
|
+
(0, command_help_1.helpEntry)("-w, --watch", "File watching / hot reload", "default: true"),
|
|
204
|
+
(0, command_help_1.helpEntry)("--follow", "Follow logs (logs action)", "default: true"),
|
|
205
|
+
(0, command_help_1.helpEntry)("--tail", "Log lines to show", "default: 100"),
|
|
206
|
+
],
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: "templates",
|
|
212
|
+
aliases: ["tpl"],
|
|
213
|
+
usage: "expressots templates <action> [args...] [options]",
|
|
214
|
+
description: "Manage CLI templates for CI/CD, Docker, and Kubernetes.",
|
|
215
|
+
groups: [
|
|
216
|
+
{
|
|
217
|
+
title: "Actions",
|
|
218
|
+
entries: [
|
|
219
|
+
(0, command_help_1.helpEntry)("list", "List available templates"),
|
|
220
|
+
(0, command_help_1.helpEntry)("update", "Update template cache from remote"),
|
|
221
|
+
(0, command_help_1.helpEntry)("clear", "Clear local template cache"),
|
|
222
|
+
(0, command_help_1.helpEntry)("info", "Show template info (info <category> <platform>)"),
|
|
223
|
+
(0, command_help_1.helpEntry)("repo", "View / set / reset template repository"),
|
|
224
|
+
(0, command_help_1.helpEntry)("status", "Show template system status"),
|
|
225
|
+
],
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
title: "Options",
|
|
229
|
+
entries: [
|
|
230
|
+
(0, command_help_1.helpEntry)("-c, --category", "Filter by category", "cicd, docker, kubernetes, migrations"),
|
|
231
|
+
(0, command_help_1.helpEntry)("-p, --platform", "Filter by platform", "github, gitlab, ..."),
|
|
232
|
+
],
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
notes: [
|
|
236
|
+
"Examples:",
|
|
237
|
+
" expressots templates list",
|
|
238
|
+
" expressots templates info cicd github",
|
|
239
|
+
" expressots templates repo set https://github.com/org/templates",
|
|
240
|
+
],
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: "dev",
|
|
244
|
+
usage: "expressots dev [options]",
|
|
245
|
+
description: "Start the development server.",
|
|
246
|
+
groups: [
|
|
247
|
+
{
|
|
248
|
+
title: "Options",
|
|
249
|
+
entries: [
|
|
250
|
+
(0, command_help_1.helpEntry)("-c, --container", "Run dev inside Docker", "default: false"),
|
|
251
|
+
(0, command_help_1.helpEntry)("-b, --build", "Rebuild container before starting", "with --container"),
|
|
252
|
+
(0, command_help_1.helpEntry)("-d, --detach", "Run container in background", "with --container"),
|
|
253
|
+
],
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
},
|
|
257
|
+
];
|
|
258
|
+
exports.COMMAND_HELP_SPECS = SPECS;
|
|
259
|
+
/**
|
|
260
|
+
* Index every spec by its canonical name and aliases for O(1) lookup.
|
|
261
|
+
*/
|
|
262
|
+
const SPEC_INDEX = (() => {
|
|
263
|
+
const index = new Map();
|
|
264
|
+
for (const spec of SPECS) {
|
|
265
|
+
index.set(spec.name, spec);
|
|
266
|
+
for (const alias of spec.aliases ?? []) {
|
|
267
|
+
index.set(alias, spec);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return index;
|
|
271
|
+
})();
|
|
272
|
+
/**
|
|
273
|
+
* Resolve a command token (name or alias) to its help spec, if any.
|
|
274
|
+
*/
|
|
275
|
+
function resolveCommandHelpSpec(token) {
|
|
276
|
+
return SPEC_INDEX.get(token);
|
|
277
|
+
}
|
|
278
|
+
exports.resolveCommandHelpSpec = resolveCommandHelpSpec;
|
|
279
|
+
/**
|
|
280
|
+
* Detect a `<command> --help` / `<command> -h` invocation and, if the command
|
|
281
|
+
* has a registered spec, render the refined help screen.
|
|
282
|
+
*
|
|
283
|
+
* @returns `true` when custom help was printed (caller should exit), else `false`.
|
|
284
|
+
*/
|
|
285
|
+
function tryPrintCommandHelp(args, version) {
|
|
286
|
+
const command = args[0];
|
|
287
|
+
if (!command || command.startsWith("-")) {
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
const wantsHelp = args
|
|
291
|
+
.slice(1)
|
|
292
|
+
.some((arg) => arg === "--help" || arg === "-h");
|
|
293
|
+
if (!wantsHelp) {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
const spec = resolveCommandHelpSpec(command);
|
|
297
|
+
if (!spec) {
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
(0, command_help_1.printCommandHelp)(spec, version);
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
exports.tryPrintCommandHelp = tryPrintCommandHelp;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type HelpEntry, type HelpGroup } from "./render";
|
|
2
|
+
/**
|
|
3
|
+
* A structured description of a single command's help surface. Rendered by
|
|
4
|
+
* {@link printCommandHelp} so every subcommand `--help` shares the exact visual
|
|
5
|
+
* language of the top-level help screen (see `main-help.ts`) and the command
|
|
6
|
+
* reference (`help/form.ts`), instead of yargs' sprawling default table.
|
|
7
|
+
*/
|
|
8
|
+
export interface CommandHelpSpec {
|
|
9
|
+
/** Canonical command name, e.g. `costs`. */
|
|
10
|
+
name: string;
|
|
11
|
+
/** Command aliases, e.g. `["cost", "pricing"]`. */
|
|
12
|
+
aliases?: string[];
|
|
13
|
+
/** Usage line, e.g. `expressots costs <action> [options]`. */
|
|
14
|
+
usage: string;
|
|
15
|
+
/** One-line description (matches the yargs `describe`). */
|
|
16
|
+
description: string;
|
|
17
|
+
/** Titled groups of entries (Arguments, Actions, Options, ...). */
|
|
18
|
+
groups: HelpGroup[];
|
|
19
|
+
/** Optional trailing notes / examples (rendered dim). */
|
|
20
|
+
notes?: string[];
|
|
21
|
+
/** Optional docs URL. */
|
|
22
|
+
docs?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Build an option/argument entry with an optional dim "hint" (choices,
|
|
26
|
+
* defaults, examples) appended to the description. Keeps the help compact while
|
|
27
|
+
* still surfacing the metadata yargs would otherwise sprawl across the line.
|
|
28
|
+
*/
|
|
29
|
+
export declare function helpEntry(name: string, desc: string, hint?: string): HelpEntry;
|
|
30
|
+
/**
|
|
31
|
+
* Print a refined, grouped, column-aligned help screen for a single command.
|
|
32
|
+
*
|
|
33
|
+
* Each group is rendered with its own column width so short action names and
|
|
34
|
+
* long option flags both stay tightly aligned.
|
|
35
|
+
*/
|
|
36
|
+
export declare function printCommandHelp(spec: CommandHelpSpec, version?: string): void;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.printCommandHelp = exports.helpEntry = void 0;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const process_1 = require("process");
|
|
9
|
+
const render_1 = require("./render");
|
|
10
|
+
const DEFAULT_DOCS = "https://doc.expresso-ts.com/docs/category/cli";
|
|
11
|
+
/**
|
|
12
|
+
* Build an option/argument entry with an optional dim "hint" (choices,
|
|
13
|
+
* defaults, examples) appended to the description. Keeps the help compact while
|
|
14
|
+
* still surfacing the metadata yargs would otherwise sprawl across the line.
|
|
15
|
+
*/
|
|
16
|
+
function helpEntry(name, desc, hint) {
|
|
17
|
+
return { name, desc: hint ? `${desc} ${chalk_1.default.dim(`(${hint})`)}` : desc };
|
|
18
|
+
}
|
|
19
|
+
exports.helpEntry = helpEntry;
|
|
20
|
+
/**
|
|
21
|
+
* Print a refined, grouped, column-aligned help screen for a single command.
|
|
22
|
+
*
|
|
23
|
+
* Each group is rendered with its own column width so short action names and
|
|
24
|
+
* long option flags both stay tightly aligned.
|
|
25
|
+
*/
|
|
26
|
+
function printCommandHelp(spec, version) {
|
|
27
|
+
const title = version
|
|
28
|
+
? `๐ ExpressoTS CLI v${version}`
|
|
29
|
+
: "๐ ExpressoTS CLI";
|
|
30
|
+
const lines = [
|
|
31
|
+
"",
|
|
32
|
+
chalk_1.default.bold.green(title),
|
|
33
|
+
"",
|
|
34
|
+
`${chalk_1.default.bold("Usage:")} ${spec.usage}`,
|
|
35
|
+
"",
|
|
36
|
+
spec.description,
|
|
37
|
+
];
|
|
38
|
+
if (spec.aliases && spec.aliases.length > 0) {
|
|
39
|
+
lines.push("", `${chalk_1.default.bold("Aliases:")} ${spec.aliases
|
|
40
|
+
.map((a) => chalk_1.default.green(a))
|
|
41
|
+
.join(", ")}`);
|
|
42
|
+
}
|
|
43
|
+
// Render each group independently so columns stay tight per-section.
|
|
44
|
+
for (const group of spec.groups) {
|
|
45
|
+
lines.push(...(0, render_1.renderHelpGroups)([group]));
|
|
46
|
+
}
|
|
47
|
+
if (spec.notes && spec.notes.length > 0) {
|
|
48
|
+
lines.push("");
|
|
49
|
+
for (const note of spec.notes) {
|
|
50
|
+
lines.push(chalk_1.default.dim(note));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
lines.push("", chalk_1.default.dim("Global: -h, --help ยท -V, --version"), "", `๐ ${chalk_1.default.dim("Docs:")} ${chalk_1.default.green(spec.docs ?? DEFAULT_DOCS)}`, "");
|
|
54
|
+
process_1.stdout.write(`${lines.join("\n")}\n`);
|
|
55
|
+
}
|
|
56
|
+
exports.printCommandHelp = printCommandHelp;
|