@expressots/cli 3.0.0 → 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 (194) hide show
  1. package/README.md +41 -95
  2. package/bin/cicd/cli.d.ts +6 -0
  3. package/bin/cicd/cli.js +128 -0
  4. package/bin/cicd/form.d.ts +29 -0
  5. package/bin/cicd/form.js +346 -0
  6. package/bin/cicd/generators/azure-devops.d.ts +2 -0
  7. package/bin/cicd/generators/azure-devops.js +370 -0
  8. package/bin/cicd/generators/bitbucket.d.ts +2 -0
  9. package/bin/cicd/generators/bitbucket.js +217 -0
  10. package/bin/cicd/generators/circleci.d.ts +2 -0
  11. package/bin/cicd/generators/circleci.js +274 -0
  12. package/bin/cicd/generators/github-actions.d.ts +14 -0
  13. package/bin/cicd/generators/github-actions.js +426 -0
  14. package/bin/cicd/generators/gitlab-ci.d.ts +2 -0
  15. package/bin/cicd/generators/gitlab-ci.js +237 -0
  16. package/bin/cicd/generators/index.d.ts +6 -0
  17. package/bin/cicd/generators/index.js +15 -0
  18. package/bin/cicd/generators/jenkins.d.ts +2 -0
  19. package/bin/cicd/generators/jenkins.js +248 -0
  20. package/bin/cicd/generators/template-loader.d.ts +17 -0
  21. package/bin/cicd/generators/template-loader.js +128 -0
  22. package/bin/cicd/index.d.ts +1 -0
  23. package/bin/cicd/index.js +5 -0
  24. package/bin/cli.d.ts +1 -5
  25. package/bin/cli.js +72 -7
  26. package/bin/commands/project.commands.d.ts +19 -6
  27. package/bin/commands/project.commands.js +602 -66
  28. package/bin/config/index.d.ts +5 -0
  29. package/bin/config/index.js +10 -0
  30. package/bin/config/manager.d.ts +98 -0
  31. package/bin/config/manager.js +222 -0
  32. package/bin/containerize/analyzers/bootstrap-analyzer.d.ts +46 -0
  33. package/bin/containerize/analyzers/bootstrap-analyzer.js +187 -0
  34. package/bin/containerize/analyzers/project-analyzer.d.ts +20 -0
  35. package/bin/containerize/analyzers/project-analyzer.js +150 -0
  36. package/bin/containerize/cli.d.ts +4 -0
  37. package/bin/containerize/cli.js +113 -0
  38. package/bin/containerize/form.d.ts +15 -0
  39. package/bin/containerize/form.js +152 -0
  40. package/bin/containerize/generators/ci-generator.d.ts +31 -0
  41. package/bin/containerize/generators/ci-generator.js +940 -0
  42. package/bin/containerize/generators/docker-compose-generator.d.ts +8 -0
  43. package/bin/containerize/generators/docker-compose-generator.js +187 -0
  44. package/bin/containerize/generators/dockerfile-generator.d.ts +8 -0
  45. package/bin/containerize/generators/dockerfile-generator.js +657 -0
  46. package/bin/containerize/generators/kubernetes-generator.d.ts +8 -0
  47. package/bin/containerize/generators/kubernetes-generator.js +134 -0
  48. package/bin/containerize/generators/template-loader.d.ts +36 -0
  49. package/bin/containerize/generators/template-loader.js +129 -0
  50. package/bin/containerize/index.d.ts +4 -0
  51. package/bin/containerize/index.js +13 -0
  52. package/bin/containerize/presets/preset-registry.d.ts +20 -0
  53. package/bin/containerize/presets/preset-registry.js +102 -0
  54. package/bin/costs/cli.d.ts +5 -0
  55. package/bin/costs/cli.js +185 -0
  56. package/bin/costs/form.d.ts +44 -0
  57. package/bin/costs/form.js +412 -0
  58. package/bin/costs/index.d.ts +4 -0
  59. package/bin/costs/index.js +25 -0
  60. package/bin/costs/pricing-manager.d.ts +84 -0
  61. package/bin/costs/pricing-manager.js +342 -0
  62. package/bin/costs/providers/index.d.ts +32 -0
  63. package/bin/costs/providers/index.js +153 -0
  64. package/bin/costs/sources/api-source.d.ts +10 -0
  65. package/bin/costs/sources/api-source.js +32 -0
  66. package/bin/costs/sources/index.d.ts +6 -0
  67. package/bin/costs/sources/index.js +15 -0
  68. package/bin/costs/sources/local-json-source.d.ts +23 -0
  69. package/bin/costs/sources/local-json-source.js +59 -0
  70. package/bin/costs/sources/remote-json-source.d.ts +11 -0
  71. package/bin/costs/sources/remote-json-source.js +53 -0
  72. package/bin/costs/types.d.ts +53 -0
  73. package/bin/costs/types.js +5 -0
  74. package/bin/dev/cli.d.ts +4 -0
  75. package/bin/dev/cli.js +136 -0
  76. package/bin/dev/form.d.ts +36 -0
  77. package/bin/dev/form.js +254 -0
  78. package/bin/dev/index.d.ts +1 -0
  79. package/bin/dev/index.js +5 -0
  80. package/bin/generate/cli.d.ts +1 -1
  81. package/bin/generate/cli.js +29 -2
  82. package/bin/generate/form.d.ts +5 -1
  83. package/bin/generate/form.js +3 -3
  84. package/bin/generate/templates/nonopinionated/config.tpl +12 -0
  85. package/bin/generate/templates/nonopinionated/event.tpl +10 -0
  86. package/bin/generate/templates/nonopinionated/guard.tpl +18 -0
  87. package/bin/generate/templates/nonopinionated/handler.tpl +12 -0
  88. package/bin/generate/templates/nonopinionated/interceptor.tpl +27 -0
  89. package/bin/generate/templates/opinionated/config.tpl +47 -0
  90. package/bin/generate/templates/opinionated/entity.tpl +1 -8
  91. package/bin/generate/templates/opinionated/event.tpl +15 -0
  92. package/bin/generate/templates/opinionated/guard.tpl +41 -0
  93. package/bin/generate/templates/opinionated/handler.tpl +23 -0
  94. package/bin/generate/templates/opinionated/interceptor.tpl +50 -0
  95. package/bin/generate/utils/command-utils.d.ts +20 -5
  96. package/bin/generate/utils/command-utils.js +145 -48
  97. package/bin/generate/utils/nonopininated-cmd.d.ts +10 -1
  98. package/bin/generate/utils/nonopininated-cmd.js +100 -1
  99. package/bin/generate/utils/opinionated-cmd.d.ts +10 -1
  100. package/bin/generate/utils/opinionated-cmd.js +128 -16
  101. package/bin/generate/utils/string-utils.d.ts +6 -0
  102. package/bin/generate/utils/string-utils.js +13 -1
  103. package/bin/help/cli.d.ts +1 -1
  104. package/bin/help/command-help-registry.d.ts +23 -0
  105. package/bin/help/command-help-registry.js +303 -0
  106. package/bin/help/command-help.d.ts +36 -0
  107. package/bin/help/command-help.js +56 -0
  108. package/bin/help/form.js +127 -22
  109. package/bin/help/main-help.d.ts +8 -0
  110. package/bin/help/main-help.js +126 -0
  111. package/bin/help/render.d.ts +32 -0
  112. package/bin/help/render.js +46 -0
  113. package/bin/info/cli.d.ts +1 -1
  114. package/bin/info/form.d.ts +1 -1
  115. package/bin/info/form.js +11 -11
  116. package/bin/migrate/analyzers/platform-detector.d.ts +14 -0
  117. package/bin/migrate/analyzers/platform-detector.js +116 -0
  118. package/bin/migrate/cli.d.ts +6 -0
  119. package/bin/migrate/cli.js +98 -0
  120. package/bin/migrate/form.d.ts +25 -0
  121. package/bin/migrate/form.js +348 -0
  122. package/bin/migrate/generators/compose-to-k8s.d.ts +2 -0
  123. package/bin/migrate/generators/compose-to-k8s.js +324 -0
  124. package/bin/migrate/generators/compose-to-railway.d.ts +2 -0
  125. package/bin/migrate/generators/compose-to-railway.js +138 -0
  126. package/bin/migrate/generators/compose-to-render.d.ts +2 -0
  127. package/bin/migrate/generators/compose-to-render.js +148 -0
  128. package/bin/migrate/generators/generic-migration.d.ts +9 -0
  129. package/bin/migrate/generators/generic-migration.js +221 -0
  130. package/bin/migrate/generators/heroku-to-fly.d.ts +2 -0
  131. package/bin/migrate/generators/heroku-to-fly.js +291 -0
  132. package/bin/migrate/generators/heroku-to-railway.d.ts +2 -0
  133. package/bin/migrate/generators/heroku-to-railway.js +283 -0
  134. package/bin/migrate/generators/heroku-to-render.d.ts +2 -0
  135. package/bin/migrate/generators/heroku-to-render.js +148 -0
  136. package/bin/migrate/generators/index.d.ts +7 -0
  137. package/bin/migrate/generators/index.js +17 -0
  138. package/bin/migrate/generators/template-loader.d.ts +21 -0
  139. package/bin/migrate/generators/template-loader.js +59 -0
  140. package/bin/migrate/index.d.ts +1 -0
  141. package/bin/migrate/index.js +5 -0
  142. package/bin/new/cli.d.ts +5 -1
  143. package/bin/new/cli.js +77 -14
  144. package/bin/new/form.d.ts +27 -4
  145. package/bin/new/form.js +605 -75
  146. package/bin/profile/analyzers/dockerfile-analyzer.d.ts +27 -0
  147. package/bin/profile/analyzers/dockerfile-analyzer.js +122 -0
  148. package/bin/profile/analyzers/image-analyzer.d.ts +19 -0
  149. package/bin/profile/analyzers/image-analyzer.js +85 -0
  150. package/bin/profile/cli.d.ts +4 -0
  151. package/bin/profile/cli.js +94 -0
  152. package/bin/profile/form.d.ts +56 -0
  153. package/bin/profile/form.js +401 -0
  154. package/bin/profile/index.d.ts +1 -0
  155. package/bin/profile/index.js +5 -0
  156. package/bin/profile/optimizers/index.d.ts +19 -0
  157. package/bin/profile/optimizers/index.js +137 -0
  158. package/bin/providers/add/form.d.ts +1 -1
  159. package/bin/providers/add/form.js +27 -6
  160. package/bin/providers/create/form.js +53 -3
  161. package/bin/scripts/form.js +27 -5
  162. package/bin/studio/cli.d.ts +15 -0
  163. package/bin/studio/cli.js +172 -0
  164. package/bin/studio/index.d.ts +5 -0
  165. package/bin/studio/index.js +9 -0
  166. package/bin/templates/cache.d.ts +54 -0
  167. package/bin/templates/cache.js +180 -0
  168. package/bin/templates/cli.d.ts +8 -0
  169. package/bin/templates/cli.js +294 -0
  170. package/bin/templates/fetcher.d.ts +49 -0
  171. package/bin/templates/fetcher.js +208 -0
  172. package/bin/templates/index.d.ts +11 -0
  173. package/bin/templates/index.js +37 -0
  174. package/bin/templates/manager.d.ts +116 -0
  175. package/bin/templates/manager.js +323 -0
  176. package/bin/templates/renderer.d.ts +49 -0
  177. package/bin/templates/renderer.js +204 -0
  178. package/bin/templates/types.d.ts +51 -0
  179. package/bin/templates/types.js +5 -0
  180. package/bin/utils/add-module-to-container.d.ts +14 -3
  181. package/bin/utils/add-module-to-container.js +327 -98
  182. package/bin/utils/cli-ui.d.ts +49 -3
  183. package/bin/utils/cli-ui.js +133 -13
  184. package/bin/utils/index.d.ts +4 -0
  185. package/bin/utils/index.js +4 -0
  186. package/bin/utils/input-validation.d.ts +50 -0
  187. package/bin/utils/input-validation.js +143 -0
  188. package/bin/utils/package-manager-commands.d.ts +24 -0
  189. package/bin/utils/package-manager-commands.js +50 -0
  190. package/bin/utils/safe-spawn.d.ts +35 -0
  191. package/bin/utils/safe-spawn.js +51 -0
  192. package/bin/utils/update-tsconfig-paths.d.ts +35 -0
  193. package/bin/utils/update-tsconfig-paths.js +326 -0
  194. package/package.json +165 -156
@@ -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;
@@ -0,0 +1,14 @@
1
+ import type { MigrationSource } from "../cli";
2
+ /**
3
+ * Detect the current deployment platform based on configuration files
4
+ */
5
+ export declare function detectCurrentPlatform(): Promise<MigrationSource | null>;
6
+ /**
7
+ * Analyze the current platform configuration
8
+ */
9
+ export declare function analyzePlatformConfig(): Promise<{
10
+ platform: MigrationSource | null;
11
+ envVars: string[];
12
+ services: string[];
13
+ databases: string[];
14
+ }>;
@@ -0,0 +1,116 @@
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.analyzePlatformConfig = exports.detectCurrentPlatform = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ /**
10
+ * Detect the current deployment platform based on configuration files
11
+ */
12
+ async function detectCurrentPlatform() {
13
+ const cwd = process.cwd();
14
+ // Check for platform-specific files
15
+ const checks = [
16
+ { platform: "heroku", files: ["Procfile", "app.json"] },
17
+ { platform: "vercel", files: ["vercel.json", ".vercel"] },
18
+ {
19
+ platform: "docker-compose",
20
+ files: ["docker-compose.yml", "docker-compose.yaml"],
21
+ },
22
+ {
23
+ platform: "aws-ecs",
24
+ files: ["ecs-task-definition.json", ".aws/ecs"],
25
+ },
26
+ {
27
+ platform: "gcp-cloudrun",
28
+ files: ["cloudbuild.yaml", ".gcp/cloudrun.yaml"],
29
+ },
30
+ { platform: "azure-container", files: ["azure-pipelines.yml"] },
31
+ ];
32
+ for (const check of checks) {
33
+ for (const file of check.files) {
34
+ if (fs_1.default.existsSync(path_1.default.join(cwd, file))) {
35
+ return check.platform;
36
+ }
37
+ }
38
+ }
39
+ // Check for platform indicators in package.json scripts
40
+ const packageJsonPath = path_1.default.join(cwd, "package.json");
41
+ if (fs_1.default.existsSync(packageJsonPath)) {
42
+ try {
43
+ const pkg = JSON.parse(fs_1.default.readFileSync(packageJsonPath, "utf-8"));
44
+ const scripts = JSON.stringify(pkg.scripts || {});
45
+ if (scripts.includes("heroku"))
46
+ return "heroku";
47
+ if (scripts.includes("vercel"))
48
+ return "vercel";
49
+ if (scripts.includes("railway"))
50
+ return "docker-compose"; // likely uses Docker
51
+ if (scripts.includes("docker-compose"))
52
+ return "docker-compose";
53
+ }
54
+ catch {
55
+ // Ignore parse errors
56
+ }
57
+ }
58
+ // If Dockerfile exists, assume docker-compose
59
+ if (fs_1.default.existsSync(path_1.default.join(cwd, "Dockerfile"))) {
60
+ return "docker-compose";
61
+ }
62
+ return null;
63
+ }
64
+ exports.detectCurrentPlatform = detectCurrentPlatform;
65
+ /**
66
+ * Analyze the current platform configuration
67
+ */
68
+ async function analyzePlatformConfig() {
69
+ const cwd = process.cwd();
70
+ const platform = await detectCurrentPlatform();
71
+ const envVars = [];
72
+ const services = [];
73
+ const databases = [];
74
+ // Parse .env.example for environment variables
75
+ const envExamplePath = path_1.default.join(cwd, ".env.example");
76
+ if (fs_1.default.existsSync(envExamplePath)) {
77
+ const content = fs_1.default.readFileSync(envExamplePath, "utf-8");
78
+ const lines = content.split("\n");
79
+ for (const line of lines) {
80
+ const match = line.match(/^([A-Z_][A-Z0-9_]*)=/);
81
+ if (match) {
82
+ envVars.push(match[1]);
83
+ }
84
+ }
85
+ }
86
+ // Parse docker-compose for services
87
+ const composePath = path_1.default.join(cwd, "docker-compose.yml");
88
+ if (fs_1.default.existsSync(composePath)) {
89
+ const content = fs_1.default.readFileSync(composePath, "utf-8");
90
+ const serviceMatch = content.match(/services:\n([\s\S]*?)(?=\n\w|$)/);
91
+ if (serviceMatch) {
92
+ const serviceLines = serviceMatch[1].match(/^\s{2}(\w+):/gm);
93
+ if (serviceLines) {
94
+ for (const line of serviceLines) {
95
+ const name = line.trim().replace(":", "");
96
+ services.push(name);
97
+ // Check if it's a database
98
+ if (name.includes("postgres") || name.includes("pg")) {
99
+ databases.push("postgresql");
100
+ }
101
+ else if (name.includes("mysql")) {
102
+ databases.push("mysql");
103
+ }
104
+ else if (name.includes("mongo")) {
105
+ databases.push("mongodb");
106
+ }
107
+ else if (name.includes("redis")) {
108
+ databases.push("redis");
109
+ }
110
+ }
111
+ }
112
+ }
113
+ }
114
+ return { platform, envVars, services, databases };
115
+ }
116
+ exports.analyzePlatformConfig = analyzePlatformConfig;
@@ -0,0 +1,6 @@
1
+ import { CommandModule } from "yargs";
2
+ type CommandModuleArgs = Record<string, never>;
3
+ export type MigrationSource = "heroku" | "docker-compose" | "vercel" | "aws-ecs" | "gcp-cloudrun" | "azure-container";
4
+ export type MigrationTarget = "railway" | "render" | "fly" | "kubernetes" | "aws-ecs" | "gcp-cloudrun" | "azure-container";
5
+ declare const migrateCommand: () => CommandModule<CommandModuleArgs, any>;
6
+ export { migrateCommand };
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.migrateCommand = void 0;
4
+ const form_1 = require("./form");
5
+ const cli_ui_1 = require("../utils/cli-ui");
6
+ const migrateCommand = () => {
7
+ return {
8
+ command: "migrate <action> [options]",
9
+ describe: "Generate migration scripts between cloud platforms.",
10
+ aliases: ["migration", "mig"],
11
+ builder: (yargs) => {
12
+ yargs.positional("action", {
13
+ choices: ["init", "generate", "list", "analyze"],
14
+ describe: "Action to perform",
15
+ type: "string",
16
+ demandOption: true,
17
+ });
18
+ yargs.option("from", {
19
+ choices: [
20
+ "heroku",
21
+ "docker-compose",
22
+ "vercel",
23
+ "aws-ecs",
24
+ "gcp-cloudrun",
25
+ "azure-container",
26
+ ],
27
+ describe: "Source platform to migrate from",
28
+ type: "string",
29
+ alias: "f",
30
+ });
31
+ yargs.option("to", {
32
+ choices: [
33
+ "railway",
34
+ "render",
35
+ "fly",
36
+ "kubernetes",
37
+ "aws-ecs",
38
+ "gcp-cloudrun",
39
+ "azure-container",
40
+ ],
41
+ describe: "Target platform to migrate to",
42
+ type: "string",
43
+ alias: "t",
44
+ });
45
+ yargs.option("include-data", {
46
+ describe: "Include data migration scripts",
47
+ type: "boolean",
48
+ default: false,
49
+ });
50
+ yargs.option("include-secrets", {
51
+ describe: "Include secrets/environment variable migration",
52
+ type: "boolean",
53
+ default: true,
54
+ });
55
+ yargs.option("dry-run", {
56
+ describe: "Show migration steps without generating files",
57
+ type: "boolean",
58
+ default: false,
59
+ });
60
+ yargs.option("output-dir", {
61
+ describe: "Output directory for migration files",
62
+ type: "string",
63
+ alias: "o",
64
+ default: "./migration",
65
+ });
66
+ return yargs;
67
+ },
68
+ handler: async (argv) => {
69
+ const { action, from, to, includeData, includeSecrets, dryRun, outputDir, } = argv;
70
+ const options = {
71
+ from: from,
72
+ to: to,
73
+ includeData,
74
+ includeSecrets,
75
+ dryRun,
76
+ outputDir,
77
+ };
78
+ switch (action) {
79
+ case "init":
80
+ await (0, form_1.initMigration)(options);
81
+ break;
82
+ case "generate":
83
+ await (0, form_1.generateMigration)(options);
84
+ break;
85
+ case "list":
86
+ await (0, form_1.listMigrations)();
87
+ break;
88
+ case "analyze":
89
+ await (0, form_1.analyzeMigration)(options);
90
+ break;
91
+ default:
92
+ (0, cli_ui_1.printError)(`Unknown action: ${action}`, "migrate");
93
+ process.exit(1);
94
+ }
95
+ },
96
+ };
97
+ };
98
+ exports.migrateCommand = migrateCommand;
@@ -0,0 +1,25 @@
1
+ import type { MigrationSource, MigrationTarget } from "./cli";
2
+ export interface MigrationOptions {
3
+ from?: MigrationSource;
4
+ to?: MigrationTarget;
5
+ includeData: boolean;
6
+ includeSecrets: boolean;
7
+ dryRun: boolean;
8
+ outputDir: string;
9
+ }
10
+ /**
11
+ * Interactive migration setup wizard
12
+ */
13
+ export declare function initMigration(options: MigrationOptions): Promise<void>;
14
+ /**
15
+ * Generate migration scripts
16
+ */
17
+ export declare function generateMigration(options: MigrationOptions): Promise<void>;
18
+ /**
19
+ * List available migrations
20
+ */
21
+ export declare function listMigrations(): Promise<void>;
22
+ /**
23
+ * Analyze migration complexity
24
+ */
25
+ export declare function analyzeMigration(options: MigrationOptions): Promise<void>;