@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.
Files changed (63) hide show
  1. package/bin/cicd/cli.d.ts +1 -1
  2. package/bin/cicd/cli.js +3 -1
  3. package/bin/cicd/form.js +5 -4
  4. package/bin/cli.d.ts +1 -5
  5. package/bin/cli.js +56 -6
  6. package/bin/commands/project.commands.js +233 -26
  7. package/bin/containerize/cli.d.ts +1 -1
  8. package/bin/containerize/cli.js +1 -1
  9. package/bin/containerize/form.js +49 -51
  10. package/bin/containerize/generators/ci-generator.js +16 -12
  11. package/bin/containerize/generators/docker-compose-generator.js +3 -2
  12. package/bin/containerize/generators/dockerfile-generator.js +50 -28
  13. package/bin/containerize/generators/kubernetes-generator.js +5 -4
  14. package/bin/costs/cli.d.ts +1 -1
  15. package/bin/costs/cli.js +4 -2
  16. package/bin/dev/cli.d.ts +1 -1
  17. package/bin/dev/cli.js +3 -1
  18. package/bin/generate/cli.d.ts +1 -1
  19. package/bin/generate/templates/nonopinionated/config.tpl +12 -12
  20. package/bin/generate/templates/nonopinionated/event.tpl +10 -10
  21. package/bin/generate/templates/nonopinionated/guard.tpl +18 -18
  22. package/bin/generate/templates/nonopinionated/handler.tpl +12 -12
  23. package/bin/generate/templates/nonopinionated/interceptor.tpl +27 -27
  24. package/bin/generate/templates/opinionated/config.tpl +47 -47
  25. package/bin/generate/templates/opinionated/event.tpl +15 -15
  26. package/bin/generate/templates/opinionated/guard.tpl +41 -41
  27. package/bin/generate/templates/opinionated/handler.tpl +23 -23
  28. package/bin/generate/templates/opinionated/interceptor.tpl +50 -50
  29. package/bin/generate/utils/command-utils.d.ts +13 -2
  30. package/bin/generate/utils/command-utils.js +50 -17
  31. package/bin/generate/utils/opinionated-cmd.js +19 -12
  32. package/bin/help/cli.d.ts +1 -1
  33. package/bin/help/command-help-registry.d.ts +23 -0
  34. package/bin/help/command-help-registry.js +303 -0
  35. package/bin/help/command-help.d.ts +36 -0
  36. package/bin/help/command-help.js +56 -0
  37. package/bin/help/form.js +127 -30
  38. package/bin/help/main-help.d.ts +8 -0
  39. package/bin/help/main-help.js +126 -0
  40. package/bin/help/render.d.ts +32 -0
  41. package/bin/help/render.js +46 -0
  42. package/bin/info/cli.d.ts +1 -1
  43. package/bin/info/form.d.ts +1 -1
  44. package/bin/info/form.js +11 -11
  45. package/bin/migrate/cli.d.ts +1 -1
  46. package/bin/migrate/cli.js +3 -1
  47. package/bin/migrate/form.js +4 -3
  48. package/bin/new/cli.d.ts +5 -1
  49. package/bin/new/cli.js +62 -14
  50. package/bin/new/form.d.ts +3 -1
  51. package/bin/new/form.js +338 -23
  52. package/bin/profile/cli.d.ts +1 -1
  53. package/bin/profile/cli.js +3 -1
  54. package/bin/profile/form.js +5 -4
  55. package/bin/providers/create/form.js +53 -4
  56. package/bin/studio/cli.js +9 -3
  57. package/bin/templates/cli.js +7 -5
  58. package/bin/utils/add-module-to-container.d.ts +14 -3
  59. package/bin/utils/add-module-to-container.js +330 -111
  60. package/bin/utils/cli-ui.d.ts +20 -1
  61. package/bin/utils/cli-ui.js +41 -3
  62. package/bin/utils/update-tsconfig-paths.js +73 -33
  63. package/package.json +22 -13
package/bin/help/form.js CHANGED
@@ -5,36 +5,133 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.helpForm = void 0;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
- const cli_table3_1 = __importDefault(require("cli-table3"));
9
- const helpForm = async () => {
10
- const table = new cli_table3_1.default({
11
- head: [
12
- chalk_1.default.green("Name"),
13
- chalk_1.default.green("Alias"),
14
- chalk_1.default.green("Description"),
8
+ const process_1 = require("process");
9
+ const render_1 = require("./render");
10
+ /**
11
+ * The full command + schematics reference. Shares the exact visual
12
+ * language of the top-level help screen (see `main-help.ts`) via the
13
+ * common `renderHelpGroups` helper, but goes deeper: it enumerates every
14
+ * `generate` schematic and provider sub-command.
15
+ */
16
+ const RESOURCE_GROUPS = [
17
+ {
18
+ title: "Project",
19
+ entries: [
20
+ {
21
+ name: "new",
22
+ desc: "Generate a new project (application or micro)",
23
+ },
24
+ { name: "dev", desc: "Start the development server" },
25
+ { name: "build", desc: "Build the project for production" },
26
+ { name: "prod", desc: "Run in production mode" },
27
+ { name: "info", alias: "i", desc: "Display project information" },
28
+ { name: "scripts", desc: "Run scripts list or specific scripts" },
29
+ { name: "help", alias: "h", desc: "Show command help" },
30
+ ],
31
+ },
32
+ {
33
+ title: "Generate",
34
+ entries: [
35
+ {
36
+ name: "service",
37
+ alias: "g s",
38
+ desc: "Service [controller, usecase, dto, module]",
39
+ },
40
+ { name: "controller", alias: "g c", desc: "Controller" },
41
+ { name: "usecase", alias: "g u", desc: "Use case" },
42
+ { name: "dto", alias: "g d", desc: "DTO" },
43
+ { name: "entity", alias: "g e", desc: "Entity" },
44
+ { name: "module", alias: "g mo", desc: "Module" },
45
+ { name: "middleware", alias: "g mi", desc: "Middleware" },
46
+ {
47
+ name: "interceptor",
48
+ alias: "g i",
49
+ desc: "Interceptor (--priority)",
50
+ },
51
+ { name: "event", alias: "g ev", desc: "Type-safe event" },
52
+ {
53
+ name: "handler",
54
+ alias: "g h",
55
+ desc: "Event handler (--event, --priority)",
56
+ },
57
+ { name: "guard", alias: "g gu", desc: "Authorization guard" },
58
+ { name: "config", alias: "g cfg", desc: "Config module" },
59
+ ],
60
+ },
61
+ {
62
+ title: "Providers",
63
+ entries: [
64
+ {
65
+ name: "provider",
66
+ alias: "g p",
67
+ desc: "Generate internal provider",
68
+ },
69
+ {
70
+ name: "add",
71
+ desc: "Add provider to the project (-d for devDependency)",
72
+ },
73
+ { name: "remove", desc: "Remove provider from the project" },
74
+ { name: "create", desc: "Create external provider" },
15
75
  ],
16
- colWidths: [15, 15, 60],
17
- });
18
- table.push(
19
- // Project commands
20
- ["new project", "new", "Generate a new project (application or micro)"], ["info", "i", "Provides project information"], ["resources", "r", "Displays cli commands and resources"], ["scripts", "scripts", "Run scripts list or specific scripts"], ["help", "h", "Show command help"],
21
- // Core schematics
22
- [
23
- "service",
24
- "g s",
25
- "Generate a service [controller, usecase, dto, module]",
26
- ], ["controller", "g c", "Generate a controller"], ["usecase", "g u", "Generate a usecase"], ["dto", "g d", "Generate a dto"], ["entity", "g e", "Generate an entity"], ["module", "g mo", "Generate a module"], ["middleware", "g mi", "Generate a middleware"],
27
- // v4.0 schematics
28
- ["interceptor", "g i", "Generate an interceptor (--priority)"], ["event", "g ev", "Generate a type-safe event"], ["handler", "g h", "Generate an event handler (--event, --priority)"], ["guard", "g gu", "Generate an authorization guard"], ["config", "g cfg", "Generate a config module"],
29
- // Provider commands
30
- ["provider", "g p", "Generate internal provider"], [
31
- "provider",
32
- "add",
33
- "Add provider to the project. Use -d to add as dev dependency",
34
- ], ["provider", "remove", "Remove provider from the project"], ["provider", "create", "Create external provider"]);
35
- console.log(chalk_1.default.bold.white("ExpressoTS:", `${chalk_1.default.green("Resources List")}`));
36
- console.log(chalk_1.default.whiteBright(table.toString()));
37
- console.log(chalk_1.default.bold.white(`📝 More info: ${chalk_1.default.green("https://doc.expresso-ts.com/docs/category/cli")}`));
38
- console.log("\n");
76
+ },
77
+ {
78
+ title: "DevOps",
79
+ entries: [
80
+ {
81
+ name: "containerize",
82
+ alias: "ctr",
83
+ desc: "Generate Docker / Kubernetes / Compose configs",
84
+ },
85
+ {
86
+ name: "cicd",
87
+ alias: "ci",
88
+ desc: "Generate and manage CI/CD pipelines",
89
+ },
90
+ {
91
+ name: "migrate",
92
+ alias: "mig",
93
+ desc: "Generate migration scripts between platforms",
94
+ },
95
+ {
96
+ name: "profile",
97
+ alias: "prof",
98
+ desc: "Analyze and optimize container configs",
99
+ },
100
+ {
101
+ name: "container-dev",
102
+ alias: "cdev",
103
+ desc: "Develop inside Docker with hot reload",
104
+ },
105
+ {
106
+ name: "costs",
107
+ alias: "cost",
108
+ desc: "Estimate and compare cloud deployment costs",
109
+ },
110
+ {
111
+ name: "templates",
112
+ alias: "tpl",
113
+ desc: "Manage CI/CD, Docker, and Kubernetes templates",
114
+ },
115
+ ],
116
+ },
117
+ {
118
+ title: "Studio & Help",
119
+ entries: [
120
+ { name: "studio", desc: "Launch ExpressoTS Studio" },
121
+ { name: "resources", alias: "r", desc: "Show this reference" },
122
+ { name: "completion", desc: "Generate a shell completion script" },
123
+ ],
124
+ },
125
+ ];
126
+ const helpForm = async () => {
127
+ const lines = [
128
+ "",
129
+ `${chalk_1.default.bold.green("🐎 ExpressoTS CLI")} ${chalk_1.default.dim("· Command Reference")}`,
130
+ ...(0, render_1.renderHelpGroups)(RESOURCE_GROUPS),
131
+ "",
132
+ `📝 ${chalk_1.default.dim("Docs:")} ${chalk_1.default.green("https://doc.expresso-ts.com/docs/category/cli")}`,
133
+ "",
134
+ ];
135
+ process_1.stdout.write(`${lines.join("\n")}\n`);
39
136
  };
40
137
  exports.helpForm = helpForm;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Print a refined, grouped, column-aligned top-level help screen.
3
+ *
4
+ * Unlike the default yargs help, this drops the repeated `expressots`
5
+ * prefix on every line and renders aliases inline, keeping the whole
6
+ * reference compact while still listing every command.
7
+ */
8
+ export declare function printMainHelp(version?: string): void;
@@ -0,0 +1,126 @@
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.printMainHelp = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const process_1 = require("process");
9
+ const render_1 = require("./render");
10
+ const COMMAND_GROUPS = [
11
+ {
12
+ title: "Project",
13
+ entries: [
14
+ { name: "new", desc: "Create a new application or micro project" },
15
+ { name: "dev", desc: "Start the development server" },
16
+ { name: "build", desc: "Build the project for production" },
17
+ { name: "prod", desc: "Run in production mode" },
18
+ { name: "info", alias: "i", desc: "Display project information" },
19
+ { name: "scripts", desc: "Run one or more package scripts" },
20
+ ],
21
+ },
22
+ {
23
+ title: "Generate",
24
+ entries: [
25
+ {
26
+ name: "generate",
27
+ alias: "g",
28
+ desc: "Scaffold a resource (controller, usecase, dto, ...)",
29
+ },
30
+ ],
31
+ },
32
+ {
33
+ title: "Providers",
34
+ entries: [
35
+ { name: "create", desc: "Create an external provider" },
36
+ { name: "add", desc: "Add a provider to the project" },
37
+ { name: "remove", desc: "Remove a provider from the project" },
38
+ ],
39
+ },
40
+ {
41
+ title: "DevOps",
42
+ entries: [
43
+ {
44
+ name: "containerize",
45
+ alias: "ctr",
46
+ desc: "Generate Docker / Kubernetes / Compose configs",
47
+ },
48
+ {
49
+ name: "cicd",
50
+ alias: "ci",
51
+ desc: "Generate and manage CI/CD pipelines",
52
+ },
53
+ {
54
+ name: "migrate",
55
+ alias: "mig",
56
+ desc: "Generate migration scripts between platforms",
57
+ },
58
+ {
59
+ name: "profile",
60
+ alias: "prof",
61
+ desc: "Analyze and optimize container configs",
62
+ },
63
+ {
64
+ name: "container-dev",
65
+ alias: "cdev",
66
+ desc: "Develop inside Docker with hot reload",
67
+ },
68
+ {
69
+ name: "costs",
70
+ alias: "cost",
71
+ desc: "Estimate and compare cloud deployment costs",
72
+ },
73
+ {
74
+ name: "templates",
75
+ alias: "tpl",
76
+ desc: "Manage CI/CD, Docker, and Kubernetes templates",
77
+ },
78
+ ],
79
+ },
80
+ {
81
+ title: "Studio & Help",
82
+ entries: [
83
+ { name: "studio", desc: "Launch ExpressoTS Studio" },
84
+ {
85
+ name: "resources",
86
+ alias: "r",
87
+ desc: "Show full command & schematics reference",
88
+ },
89
+ { name: "completion", desc: "Generate a shell completion script" },
90
+ ],
91
+ },
92
+ {
93
+ title: "Options",
94
+ entries: [
95
+ { name: "-h, --help", desc: "Show help" },
96
+ { name: "-V, --version", desc: "Show version" },
97
+ ],
98
+ },
99
+ ];
100
+ /**
101
+ * Print a refined, grouped, column-aligned top-level help screen.
102
+ *
103
+ * Unlike the default yargs help, this drops the repeated `expressots`
104
+ * prefix on every line and renders aliases inline, keeping the whole
105
+ * reference compact while still listing every command.
106
+ */
107
+ function printMainHelp(version) {
108
+ const title = version
109
+ ? `🐎 ExpressoTS CLI v${version}`
110
+ : "🐎 ExpressoTS CLI";
111
+ const lines = [
112
+ "",
113
+ chalk_1.default.bold.green(title),
114
+ "",
115
+ `${chalk_1.default.bold("Usage:")} expressots <command> [options]`,
116
+ ...(0, render_1.renderHelpGroups)(COMMAND_GROUPS),
117
+ "",
118
+ chalk_1.default.dim("Run 'expressots <command> --help' for details on a command."),
119
+ "",
120
+ `🌐 ${chalk_1.default.green("https://expresso-ts.com")} ` +
121
+ `💖 ${chalk_1.default.green("https://github.com/sponsors/expressots")}`,
122
+ "",
123
+ ];
124
+ process_1.stdout.write(`${lines.join("\n")}\n`);
125
+ }
126
+ exports.printMainHelp = printMainHelp;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * A single command/option row in a help surface.
3
+ */
4
+ export interface HelpEntry {
5
+ name: string;
6
+ alias?: string;
7
+ desc: string;
8
+ }
9
+ /**
10
+ * A titled group of entries (e.g. "Project", "DevOps").
11
+ */
12
+ export interface HelpGroup {
13
+ title: string;
14
+ entries: HelpEntry[];
15
+ }
16
+ /**
17
+ * Format an alias as `(g)`, or an empty string when there is none.
18
+ */
19
+ export declare function formatAlias(alias?: string): string;
20
+ /**
21
+ * Render one aligned row: ` name alias description`.
22
+ */
23
+ export declare function renderRow(entry: HelpEntry, nameWidth: number, aliasWidth: number): string;
24
+ /**
25
+ * Render grouped, column-aligned rows. A single name/alias width is
26
+ * computed across *all* groups so every column lines up, giving every
27
+ * help surface (top-level help, resources reference) one cohesive look.
28
+ *
29
+ * Returns the lines (no trailing newline). Each group is preceded by a
30
+ * blank line and a bold cyan title.
31
+ */
32
+ export declare function renderHelpGroups(groups: HelpGroup[]): string[];
@@ -0,0 +1,46 @@
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.renderHelpGroups = exports.renderRow = exports.formatAlias = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ /**
9
+ * Format an alias as `(g)`, or an empty string when there is none.
10
+ */
11
+ function formatAlias(alias) {
12
+ return alias ? `(${alias})` : "";
13
+ }
14
+ exports.formatAlias = formatAlias;
15
+ /**
16
+ * Render one aligned row: ` name alias description`.
17
+ */
18
+ function renderRow(entry, nameWidth, aliasWidth) {
19
+ const name = chalk_1.default.green(entry.name.padEnd(nameWidth));
20
+ const alias = chalk_1.default.dim(formatAlias(entry.alias).padEnd(aliasWidth));
21
+ return ` ${name} ${alias} ${entry.desc}`;
22
+ }
23
+ exports.renderRow = renderRow;
24
+ /**
25
+ * Render grouped, column-aligned rows. A single name/alias width is
26
+ * computed across *all* groups so every column lines up, giving every
27
+ * help surface (top-level help, resources reference) one cohesive look.
28
+ *
29
+ * Returns the lines (no trailing newline). Each group is preceded by a
30
+ * blank line and a bold cyan title.
31
+ */
32
+ function renderHelpGroups(groups) {
33
+ const all = groups.flatMap((g) => g.entries);
34
+ const nameWidth = Math.max(...all.map((e) => e.name.length));
35
+ const aliasWidth = Math.max(...all.map((e) => formatAlias(e.alias).length));
36
+ const lines = [];
37
+ for (const group of groups) {
38
+ lines.push("");
39
+ lines.push(chalk_1.default.bold.cyan(group.title));
40
+ for (const entry of group.entries) {
41
+ lines.push(renderRow(entry, nameWidth, aliasWidth));
42
+ }
43
+ }
44
+ return lines;
45
+ }
46
+ exports.renderHelpGroups = renderHelpGroups;
package/bin/info/cli.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import { CommandModule } from "yargs";
2
- type CommandModuleArgs = {};
2
+ type CommandModuleArgs = object;
3
3
  declare const infoProject: () => CommandModule<CommandModuleArgs, any>;
4
4
  export { infoProject };
@@ -1 +1 @@
1
- export declare const infoForm: () => void;
1
+ export declare const infoForm: () => Promise<void>;
package/bin/info/form.js CHANGED
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.infoForm = void 0;
7
- const chalk_1 = __importDefault(require("chalk"));
8
7
  const fs_1 = __importDefault(require("fs"));
9
8
  const os_1 = __importDefault(require("os"));
10
9
  const path_1 = __importDefault(require("path"));
@@ -18,21 +17,22 @@ function getInfosFromPackage() {
18
17
  const packageJsonPath = path_1.default.join(absDirPath, "package.json");
19
18
  const fileContents = fs_1.default.readFileSync(packageJsonPath, "utf-8");
20
19
  const packageJson = JSON.parse(fileContents);
21
- console.log(chalk_1.default.green("ExpressoTS Project:"));
22
- console.log(chalk_1.default.white(`\tName: ${packageJson.name}`));
23
- console.log(chalk_1.default.white(`\tDescription: ${packageJson.description}`));
24
- console.log(chalk_1.default.white(`\tVersion: ${packageJson.version}`));
25
- console.log(chalk_1.default.white(`\tAuthor: ${packageJson.author}`));
20
+ (0, cli_ui_1.printSection)("📦 Project");
21
+ (0, cli_ui_1.printKeyValue)("Name", `${packageJson.name}`);
22
+ (0, cli_ui_1.printKeyValue)("Description", `${packageJson.description}`);
23
+ (0, cli_ui_1.printKeyValue)("Version", `${packageJson.version}`);
24
+ (0, cli_ui_1.printKeyValue)("Author", `${packageJson.author}`);
26
25
  }
27
26
  catch (error) {
28
27
  (0, cli_ui_1.printError)("No project information available.", "package.json not found!");
29
28
  }
30
29
  }
31
- const infoForm = () => {
30
+ const infoForm = async () => {
32
31
  getInfosFromPackage();
33
- console.log(chalk_1.default.green("System information:"));
34
- console.log(chalk_1.default.white(`\tOS Version: ${os_1.default.version()}`));
35
- console.log(chalk_1.default.white(`\tNodeJS version: ${process.version}`));
36
- (0, cli_ui_1.printSuccess)("CLI version:", cli_1.BUNDLE_VERSION);
32
+ (0, cli_ui_1.printSection)("💻 System");
33
+ (0, cli_ui_1.printKeyValue)("OS", `${os_1.default.type()} ${os_1.default.release()} (${os_1.default.arch()})`);
34
+ (0, cli_ui_1.printKeyValue)("Node.js", process.version);
35
+ (0, cli_ui_1.printKeyValue)("CLI", cli_1.BUNDLE_VERSION);
36
+ console.log("");
37
37
  };
38
38
  exports.infoForm = infoForm;
@@ -1,5 +1,5 @@
1
1
  import { CommandModule } from "yargs";
2
- type CommandModuleArgs = {};
2
+ type CommandModuleArgs = Record<string, never>;
3
3
  export type MigrationSource = "heroku" | "docker-compose" | "vercel" | "aws-ecs" | "gcp-cloudrun" | "azure-container";
4
4
  export type MigrationTarget = "railway" | "render" | "fly" | "kubernetes" | "aws-ecs" | "gcp-cloudrun" | "azure-container";
5
5
  declare const migrateCommand: () => CommandModule<CommandModuleArgs, any>;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.migrateCommand = void 0;
4
4
  const form_1 = require("./form");
5
+ const cli_ui_1 = require("../utils/cli-ui");
5
6
  const migrateCommand = () => {
6
7
  return {
7
8
  command: "migrate <action> [options]",
@@ -88,7 +89,8 @@ const migrateCommand = () => {
88
89
  await (0, form_1.analyzeMigration)(options);
89
90
  break;
90
91
  default:
91
- console.log(`Unknown action: ${action}`);
92
+ (0, cli_ui_1.printError)(`Unknown action: ${action}`, "migrate");
93
+ process.exit(1);
92
94
  }
93
95
  },
94
96
  };
@@ -10,6 +10,7 @@ const chalk_1 = __importDefault(require("chalk"));
10
10
  const inquirer_1 = __importDefault(require("inquirer"));
11
11
  const platform_detector_1 = require("./analyzers/platform-detector");
12
12
  const generators_1 = require("./generators");
13
+ const cli_ui_1 = require("../utils/cli-ui");
13
14
  const SUPPORTED_MIGRATIONS = [
14
15
  {
15
16
  from: "heroku",
@@ -94,7 +95,7 @@ const SUPPORTED_MIGRATIONS = [
94
95
  * Interactive migration setup wizard
95
96
  */
96
97
  async function initMigration(options) {
97
- console.log(chalk_1.default.cyan("\n🚀 ExpressoTS Migration Wizard\n"));
98
+ (0, cli_ui_1.printSection)("🚀 ExpressoTS Migration Wizard");
98
99
  // Detect current platform
99
100
  const detected = await (0, platform_detector_1.detectCurrentPlatform)();
100
101
  if (detected) {
@@ -206,7 +207,7 @@ exports.generateMigration = generateMigration;
206
207
  * List available migrations
207
208
  */
208
209
  async function listMigrations() {
209
- console.log(chalk_1.default.cyan("\n📋 Available Migration Paths\n"));
210
+ (0, cli_ui_1.printSection)("📋 Available Migration Paths");
210
211
  // Group by source
211
212
  const bySource = SUPPORTED_MIGRATIONS.reduce((acc, m) => {
212
213
  if (!acc[m.from])
@@ -233,7 +234,7 @@ exports.listMigrations = listMigrations;
233
234
  * Analyze migration complexity
234
235
  */
235
236
  async function analyzeMigration(options) {
236
- console.log(chalk_1.default.cyan("\n🔍 Migration Analysis\n"));
237
+ (0, cli_ui_1.printSection)("🔍 Migration Analysis");
237
238
  const detected = await (0, platform_detector_1.detectCurrentPlatform)();
238
239
  const cwd = process.cwd();
239
240
  console.log(chalk_1.default.bold("Current Setup:"));
package/bin/new/cli.d.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  import { CommandModule } from "yargs";
2
2
  type CommandModuleArgs = object;
3
+ export declare const PACKAGE_MANAGER_CHOICES: readonly ["npm", "yarn", "pnpm", ...string[]];
4
+ export declare const TEMPLATE_CHOICES: readonly ["application", "micro"];
5
+ export declare const MIDDLEWARE_PRESET_CHOICES: readonly ["api", "web", "graphql", "microservice", "minimal"];
6
+ declare const NEW_COMMAND_EPILOG: string;
3
7
  declare const createProject: () => CommandModule<CommandModuleArgs, any>;
4
- export { createProject };
8
+ export { createProject, NEW_COMMAND_EPILOG };
package/bin/new/cli.js CHANGED
@@ -3,56 +3,103 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createProject = void 0;
7
- const form_1 = require("./form");
6
+ exports.NEW_COMMAND_EPILOG = exports.createProject = exports.MIDDLEWARE_PRESET_CHOICES = exports.TEMPLATE_CHOICES = exports.PACKAGE_MANAGER_CHOICES = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
8
  const semver_1 = __importDefault(require("semver"));
9
+ const form_1 = require("./form");
9
10
  const cli_ui_1 = require("../utils/cli-ui");
10
- const chalk_1 = __importDefault(require("chalk"));
11
- const packageManagers = [
11
+ exports.PACKAGE_MANAGER_CHOICES = [
12
12
  "npm",
13
13
  "yarn",
14
14
  "pnpm",
15
15
  ...(process.platform !== "win32" ? ["bun"] : []),
16
16
  ];
17
- const middlewarePresets = [
17
+ exports.TEMPLATE_CHOICES = ["application", "micro"];
18
+ exports.MIDDLEWARE_PRESET_CHOICES = [
18
19
  "api",
19
20
  "web",
20
21
  "graphql",
21
22
  "microservice",
22
23
  "minimal",
23
24
  ];
25
+ const formatInlineChoices = (choices) => choices.join(", ");
26
+ const NEW_COMMAND_EPILOG = [
27
+ chalk_1.default.bold("Available choices"),
28
+ "",
29
+ chalk_1.default.bold("Templates") + ` (${formatInlineChoices(exports.TEMPLATE_CHOICES)})`,
30
+ " application Full REST/GraphQL API (DI, controllers, lifecycle, presets)",
31
+ " micro Single-file HTTP service via micro(), no DI container",
32
+ chalk_1.default.dim(" Tip: add -e / --events with application to scaffold application-with-events"),
33
+ "",
34
+ chalk_1.default.bold("Package managers") +
35
+ ` (${formatInlineChoices(exports.PACKAGE_MANAGER_CHOICES)})`,
36
+ ...(process.platform === "win32"
37
+ ? [chalk_1.default.dim(" bun is not available on Windows")]
38
+ : []),
39
+ "",
40
+ chalk_1.default.bold("Middleware presets") +
41
+ ` (${formatInlineChoices(exports.MIDDLEWARE_PRESET_CHOICES)})` +
42
+ chalk_1.default.dim(" (application template only)"),
43
+ " api REST API: security, compression, rate limit (default)",
44
+ " web api + cookies and session",
45
+ " graphql GraphQL stack + Apollo scaffold",
46
+ " microservice Minimal parsing + compression",
47
+ " minimal parse() only; wire the rest yourself",
48
+ "",
49
+ chalk_1.default.bold("Flags"),
50
+ " -e, --events boolean: use application-with-events (not a separate -t value)",
51
+ "",
52
+ chalk_1.default.bold("Provider packages") +
53
+ chalk_1.default.dim(" (not expressots new): expressots create --provider <name>"),
54
+ "",
55
+ chalk_1.default.bold("Silent vs interactive"),
56
+ " Pass -t and -p together for non-interactive scaffold (CI-friendly).",
57
+ " Omit both for prompts (template, package manager, preset, events).",
58
+ ].join("\n");
59
+ exports.NEW_COMMAND_EPILOG = NEW_COMMAND_EPILOG;
24
60
  const commandOptions = (yargs) => {
61
+ const terminalWidth = typeof process.stdout.columns === "number" && process.stdout.columns > 0
62
+ ? Math.max(process.stdout.columns, 100)
63
+ : 120;
25
64
  return yargs
65
+ .wrap(terminalWidth)
26
66
  .positional("project-name", {
27
67
  describe: "The name of the project",
28
68
  type: "string",
29
69
  })
30
70
  .option("template", {
31
- describe: "The project template to use",
71
+ describe: "Project template",
32
72
  type: "string",
33
- choices: ["application", "micro"],
73
+ choices: [...exports.TEMPLATE_CHOICES],
34
74
  alias: "t",
35
75
  })
36
76
  .option("package-manager", {
37
- describe: "The package manager to use",
77
+ describe: "Package manager",
38
78
  type: "string",
39
- choices: packageManagers,
79
+ choices: [...exports.PACKAGE_MANAGER_CHOICES],
40
80
  alias: "p",
41
81
  })
42
82
  .option("preset", {
43
- describe: "Middleware preset for Application template",
83
+ describe: "Middleware preset (application template only)",
44
84
  type: "string",
45
- choices: middlewarePresets,
85
+ choices: [...exports.MIDDLEWARE_PRESET_CHOICES],
46
86
  alias: "s",
87
+ })
88
+ .option("events", {
89
+ describe: "Scaffold application-with-events (boolean flag; do not pass a value)",
90
+ type: "boolean",
91
+ alias: "e",
47
92
  })
48
93
  .option("directory", {
49
- describe: "The directory for new project",
94
+ describe: "Parent directory for the new project",
50
95
  type: "string",
51
96
  alias: "d",
52
97
  })
53
98
  .implies("package-manager", "template")
54
99
  .implies("template", "package-manager")
55
- .implies("preset", "template");
100
+ .implies("preset", "template")
101
+ .implies("events", "template")
102
+ .epilog(NEW_COMMAND_EPILOG);
56
103
  };
57
104
  const checkNodeVersion = () => {
58
105
  const minVersion = "20.0.0";
@@ -68,13 +115,14 @@ const createProject = () => {
68
115
  command: "new <project-name> [package-manager] [template] [directory]",
69
116
  describe: "Create ExpressoTS application.",
70
117
  builder: commandOptions,
71
- handler: async ({ projectName, packageManager, template, directory, preset, }) => {
118
+ handler: async ({ projectName, packageManager, template, directory, preset, events, }) => {
72
119
  checkNodeVersion();
73
120
  return await (0, form_1.projectForm)(projectName, [
74
121
  packageManager,
75
122
  template,
76
123
  directory,
77
124
  preset,
125
+ events,
78
126
  ]);
79
127
  },
80
128
  };
package/bin/new/form.d.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  */
4
4
  declare enum Template {
5
5
  application = "Application :: Full-featured ExpressoTS application. (Recommended)",
6
+ applicationWithEvents = "Application with Events :: Application template pre-wired with the type-safe Event Bus example.",
6
7
  micro = "Micro :: A minimalistic template for building micro APIs and serverless functions."
7
8
  }
8
9
  declare const enum PackageManager {
@@ -27,7 +28,8 @@ type ProjectFormArgs = [
27
28
  PackageManager,
28
29
  TemplateKeys,
29
30
  string,
30
- MiddlewarePresetKeys
31
+ MiddlewarePresetKeys,
32
+ boolean | undefined
31
33
  ];
32
34
  /**
33
35
  * Main project creation form