@expressots/cli 3.0.0-beta.4 → 4.0.0-preview.2
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 +41 -95
- package/bin/cicd/cli.d.ts +6 -0
- package/bin/cicd/cli.js +126 -0
- package/bin/cicd/form.d.ts +29 -0
- package/bin/cicd/form.js +345 -0
- package/bin/cicd/generators/azure-devops.d.ts +2 -0
- package/bin/cicd/generators/azure-devops.js +370 -0
- package/bin/cicd/generators/bitbucket.d.ts +2 -0
- package/bin/cicd/generators/bitbucket.js +217 -0
- package/bin/cicd/generators/circleci.d.ts +2 -0
- package/bin/cicd/generators/circleci.js +274 -0
- package/bin/cicd/generators/github-actions.d.ts +14 -0
- package/bin/cicd/generators/github-actions.js +426 -0
- package/bin/cicd/generators/gitlab-ci.d.ts +2 -0
- package/bin/cicd/generators/gitlab-ci.js +237 -0
- package/bin/cicd/generators/index.d.ts +6 -0
- package/bin/cicd/generators/index.js +15 -0
- package/bin/cicd/generators/jenkins.d.ts +2 -0
- package/bin/cicd/generators/jenkins.js +248 -0
- package/bin/cicd/generators/template-loader.d.ts +17 -0
- package/bin/cicd/generators/template-loader.js +128 -0
- package/bin/cicd/index.d.ts +1 -0
- package/bin/cicd/index.js +5 -0
- package/bin/cli.d.ts +1 -1
- package/bin/cli.js +18 -3
- package/bin/commands/project.commands.d.ts +19 -6
- package/bin/commands/project.commands.js +390 -61
- package/bin/config/index.d.ts +5 -0
- package/bin/config/index.js +10 -0
- package/bin/config/manager.d.ts +98 -0
- package/bin/config/manager.js +222 -0
- package/bin/containerize/analyzers/bootstrap-analyzer.d.ts +46 -0
- package/bin/containerize/analyzers/bootstrap-analyzer.js +187 -0
- package/bin/containerize/analyzers/project-analyzer.d.ts +20 -0
- package/bin/containerize/analyzers/project-analyzer.js +150 -0
- package/bin/containerize/cli.d.ts +4 -0
- package/bin/containerize/cli.js +113 -0
- package/bin/containerize/form.d.ts +15 -0
- package/bin/containerize/form.js +154 -0
- package/bin/containerize/generators/ci-generator.d.ts +31 -0
- package/bin/containerize/generators/ci-generator.js +936 -0
- package/bin/containerize/generators/docker-compose-generator.d.ts +8 -0
- package/bin/containerize/generators/docker-compose-generator.js +186 -0
- package/bin/containerize/generators/dockerfile-generator.d.ts +8 -0
- package/bin/containerize/generators/dockerfile-generator.js +635 -0
- package/bin/containerize/generators/kubernetes-generator.d.ts +8 -0
- package/bin/containerize/generators/kubernetes-generator.js +133 -0
- package/bin/containerize/generators/template-loader.d.ts +36 -0
- package/bin/containerize/generators/template-loader.js +129 -0
- package/bin/containerize/index.d.ts +4 -0
- package/bin/containerize/index.js +13 -0
- package/bin/containerize/presets/preset-registry.d.ts +20 -0
- package/bin/containerize/presets/preset-registry.js +102 -0
- package/bin/costs/cli.d.ts +5 -0
- package/bin/costs/cli.js +183 -0
- package/bin/costs/form.d.ts +44 -0
- package/bin/costs/form.js +412 -0
- package/bin/costs/index.d.ts +4 -0
- package/bin/costs/index.js +25 -0
- package/bin/costs/pricing-manager.d.ts +84 -0
- package/bin/costs/pricing-manager.js +342 -0
- package/bin/costs/providers/index.d.ts +32 -0
- package/bin/costs/providers/index.js +153 -0
- package/bin/costs/sources/api-source.d.ts +10 -0
- package/bin/costs/sources/api-source.js +32 -0
- package/bin/costs/sources/index.d.ts +6 -0
- package/bin/costs/sources/index.js +15 -0
- package/bin/costs/sources/local-json-source.d.ts +23 -0
- package/bin/costs/sources/local-json-source.js +59 -0
- package/bin/costs/sources/remote-json-source.d.ts +11 -0
- package/bin/costs/sources/remote-json-source.js +53 -0
- package/bin/costs/types.d.ts +53 -0
- package/bin/costs/types.js +5 -0
- package/bin/dev/cli.d.ts +4 -0
- package/bin/dev/cli.js +134 -0
- package/bin/dev/form.d.ts +36 -0
- package/bin/dev/form.js +254 -0
- package/bin/dev/index.d.ts +1 -0
- package/bin/dev/index.js +5 -0
- package/bin/generate/cli.js +29 -2
- package/bin/generate/form.d.ts +5 -1
- package/bin/generate/form.js +3 -3
- package/bin/generate/templates/nonopinionated/config.tpl +12 -0
- package/bin/generate/templates/nonopinionated/event.tpl +10 -0
- package/bin/generate/templates/nonopinionated/guard.tpl +18 -0
- package/bin/generate/templates/nonopinionated/handler.tpl +12 -0
- package/bin/generate/templates/nonopinionated/interceptor.tpl +27 -0
- package/bin/generate/templates/opinionated/config.tpl +47 -0
- package/bin/generate/templates/opinionated/entity.tpl +1 -8
- package/bin/generate/templates/opinionated/event.tpl +15 -0
- package/bin/generate/templates/opinionated/guard.tpl +41 -0
- package/bin/generate/templates/opinionated/handler.tpl +23 -0
- package/bin/generate/templates/opinionated/interceptor.tpl +50 -0
- package/bin/generate/utils/command-utils.d.ts +7 -3
- package/bin/generate/utils/command-utils.js +95 -31
- package/bin/generate/utils/nonopininated-cmd.d.ts +10 -1
- package/bin/generate/utils/nonopininated-cmd.js +100 -1
- package/bin/generate/utils/opinionated-cmd.d.ts +10 -1
- package/bin/generate/utils/opinionated-cmd.js +112 -7
- package/bin/generate/utils/string-utils.d.ts +6 -0
- package/bin/generate/utils/string-utils.js +13 -1
- package/bin/help/form.js +11 -3
- package/bin/migrate/analyzers/platform-detector.d.ts +14 -0
- package/bin/migrate/analyzers/platform-detector.js +116 -0
- package/bin/migrate/cli.d.ts +6 -0
- package/bin/migrate/cli.js +96 -0
- package/bin/migrate/form.d.ts +25 -0
- package/bin/migrate/form.js +347 -0
- package/bin/migrate/generators/compose-to-k8s.d.ts +2 -0
- package/bin/migrate/generators/compose-to-k8s.js +324 -0
- package/bin/migrate/generators/compose-to-railway.d.ts +2 -0
- package/bin/migrate/generators/compose-to-railway.js +138 -0
- package/bin/migrate/generators/compose-to-render.d.ts +2 -0
- package/bin/migrate/generators/compose-to-render.js +148 -0
- package/bin/migrate/generators/generic-migration.d.ts +9 -0
- package/bin/migrate/generators/generic-migration.js +221 -0
- package/bin/migrate/generators/heroku-to-fly.d.ts +2 -0
- package/bin/migrate/generators/heroku-to-fly.js +291 -0
- package/bin/migrate/generators/heroku-to-railway.d.ts +2 -0
- package/bin/migrate/generators/heroku-to-railway.js +283 -0
- package/bin/migrate/generators/heroku-to-render.d.ts +2 -0
- package/bin/migrate/generators/heroku-to-render.js +148 -0
- package/bin/migrate/generators/index.d.ts +7 -0
- package/bin/migrate/generators/index.js +17 -0
- package/bin/migrate/generators/template-loader.d.ts +21 -0
- package/bin/migrate/generators/template-loader.js +59 -0
- package/bin/migrate/index.d.ts +1 -0
- package/bin/migrate/index.js +5 -0
- package/bin/new/cli.js +21 -6
- package/bin/new/form.d.ts +25 -4
- package/bin/new/form.js +285 -70
- package/bin/profile/analyzers/dockerfile-analyzer.d.ts +27 -0
- package/bin/profile/analyzers/dockerfile-analyzer.js +122 -0
- package/bin/profile/analyzers/image-analyzer.d.ts +19 -0
- package/bin/profile/analyzers/image-analyzer.js +85 -0
- package/bin/profile/cli.d.ts +4 -0
- package/bin/profile/cli.js +92 -0
- package/bin/profile/form.d.ts +56 -0
- package/bin/profile/form.js +400 -0
- package/bin/profile/index.d.ts +1 -0
- package/bin/profile/index.js +5 -0
- package/bin/profile/optimizers/index.d.ts +19 -0
- package/bin/profile/optimizers/index.js +137 -0
- package/bin/providers/add/form.d.ts +1 -1
- package/bin/providers/add/form.js +27 -6
- package/bin/providers/create/form.js +2 -1
- package/bin/scripts/form.js +27 -5
- package/bin/studio/cli.d.ts +15 -0
- package/bin/studio/cli.js +166 -0
- package/bin/studio/index.d.ts +5 -0
- package/bin/studio/index.js +9 -0
- package/bin/templates/cache.d.ts +54 -0
- package/bin/templates/cache.js +180 -0
- package/bin/templates/cli.d.ts +8 -0
- package/bin/templates/cli.js +292 -0
- package/bin/templates/fetcher.d.ts +49 -0
- package/bin/templates/fetcher.js +208 -0
- package/bin/templates/index.d.ts +11 -0
- package/bin/templates/index.js +37 -0
- package/bin/templates/manager.d.ts +116 -0
- package/bin/templates/manager.js +323 -0
- package/bin/templates/renderer.d.ts +49 -0
- package/bin/templates/renderer.js +204 -0
- package/bin/templates/types.d.ts +51 -0
- package/bin/templates/types.js +5 -0
- package/bin/utils/add-module-to-container.d.ts +2 -2
- package/bin/utils/add-module-to-container.js +15 -5
- package/bin/utils/cli-ui.d.ts +30 -3
- package/bin/utils/cli-ui.js +95 -13
- package/bin/utils/index.d.ts +4 -0
- package/bin/utils/index.js +4 -0
- package/bin/utils/input-validation.d.ts +50 -0
- package/bin/utils/input-validation.js +143 -0
- package/bin/utils/package-manager-commands.d.ts +24 -0
- package/bin/utils/package-manager-commands.js +50 -0
- package/bin/utils/safe-spawn.d.ts +35 -0
- package/bin/utils/safe-spawn.js +51 -0
- package/bin/utils/update-tsconfig-paths.d.ts +35 -0
- package/bin/utils/update-tsconfig-paths.js +286 -0
- package/package.json +154 -154
|
@@ -41,9 +41,10 @@ const add_module_to_container_1 = require("../../utils/add-module-to-container")
|
|
|
41
41
|
* @param method - HTTP method
|
|
42
42
|
* @param expressoConfig - Expresso configuration [expressots.config.ts]
|
|
43
43
|
* @param pathStyle - Path command style [sugar, nested, single]
|
|
44
|
+
* @param v4Options - Additional options for v4.0 schematics
|
|
44
45
|
* @returns
|
|
45
46
|
*/
|
|
46
|
-
async function opinionatedProcess(schematic, target, method, expressoConfig, pathStyle) {
|
|
47
|
+
async function opinionatedProcess(schematic, target, method, expressoConfig, pathStyle, v4Options = {}) {
|
|
47
48
|
const f = await (0, command_utils_1.validateAndPrepareFile)({
|
|
48
49
|
schematic,
|
|
49
50
|
target,
|
|
@@ -116,6 +117,27 @@ async function opinionatedProcess(schematic, target, method, expressoConfig, pat
|
|
|
116
117
|
await generateModule(f.outputPath, f.className, f.moduleName, f.path);
|
|
117
118
|
await (0, cli_ui_1.printGenerateSuccess)(schematic, f.file);
|
|
118
119
|
break;
|
|
120
|
+
// NEW v4.0 schematics
|
|
121
|
+
case "interceptor":
|
|
122
|
+
await generateInterceptor(f.outputPath, f.className, v4Options.priority ?? 10);
|
|
123
|
+
await (0, cli_ui_1.printGenerateSuccess)("interceptor", f.file);
|
|
124
|
+
break;
|
|
125
|
+
case "event":
|
|
126
|
+
await generateEvent(f.outputPath, f.className);
|
|
127
|
+
await (0, cli_ui_1.printGenerateSuccess)("event", f.file);
|
|
128
|
+
break;
|
|
129
|
+
case "handler":
|
|
130
|
+
await generateHandler(f.outputPath, f.className, v4Options.event ?? "MyEvent", v4Options.priority ?? 10);
|
|
131
|
+
await (0, cli_ui_1.printGenerateSuccess)("handler", f.file);
|
|
132
|
+
break;
|
|
133
|
+
case "guard":
|
|
134
|
+
await generateGuard(f.outputPath, f.className);
|
|
135
|
+
await (0, cli_ui_1.printGenerateSuccess)("guard", f.file);
|
|
136
|
+
break;
|
|
137
|
+
case "config":
|
|
138
|
+
await generateConfig(f.outputPath, f.className, f.moduleName);
|
|
139
|
+
await (0, cli_ui_1.printGenerateSuccess)("config", f.file);
|
|
140
|
+
break;
|
|
119
141
|
}
|
|
120
142
|
return f.file;
|
|
121
143
|
}
|
|
@@ -353,7 +375,7 @@ async function generateModuleServiceSugarPath(outputPathController, className, m
|
|
|
353
375
|
.join(folderToScaffold, path, "..")
|
|
354
376
|
.normalize();
|
|
355
377
|
const newModuleName = `${newModuleFile}.module.ts`;
|
|
356
|
-
const newModuleOutputPath = `${newModulePath}/${newModuleName}`.replace(
|
|
378
|
+
const newModuleOutputPath = `${newModulePath}/${newModuleName}`.replace(/\\/g, "/");
|
|
357
379
|
const controllerToModule = nodePath
|
|
358
380
|
.relative(newModuleOutputPath, outputPathController)
|
|
359
381
|
.normalize()
|
|
@@ -378,7 +400,9 @@ async function generateModuleServiceSugarPath(outputPathController, className, m
|
|
|
378
400
|
},
|
|
379
401
|
},
|
|
380
402
|
});
|
|
381
|
-
|
|
403
|
+
// Extract folder name from folderToScaffold (e.g., "src/useCases" -> "useCases")
|
|
404
|
+
const folderName = nodePath.basename(folderToScaffold);
|
|
405
|
+
await (0, add_module_to_container_1.addModuleToContainer)((0, string_utils_1.anyCaseToPascalCase)(moduleName), `${moduleName}/${file.replace(".ts", "")}`, path, folderName);
|
|
382
406
|
}
|
|
383
407
|
/**
|
|
384
408
|
* Generate a module for service scaffolding with single path
|
|
@@ -391,7 +415,7 @@ async function generateModuleServiceSinglePath(outputPathController, className,
|
|
|
391
415
|
const newModuleFile = await (0, command_utils_1.extractFirstWord)(file);
|
|
392
416
|
const newModulePath = nodePath.join(folderToScaffold, path).normalize();
|
|
393
417
|
const newModuleName = `${newModuleFile}.module.ts`;
|
|
394
|
-
const newModuleOutputPath = `${newModulePath}/${newModuleName}`.replace(
|
|
418
|
+
const newModuleOutputPath = `${newModulePath}/${newModuleName}`.replace(/\\/g, "/");
|
|
395
419
|
const controllerToModule = nodePath
|
|
396
420
|
.relative(newModuleOutputPath, outputPathController)
|
|
397
421
|
.normalize()
|
|
@@ -416,7 +440,9 @@ async function generateModuleServiceSinglePath(outputPathController, className,
|
|
|
416
440
|
},
|
|
417
441
|
},
|
|
418
442
|
});
|
|
419
|
-
|
|
443
|
+
// Extract folder name from folderToScaffold (e.g., "src/useCases" -> "useCases")
|
|
444
|
+
const folderName = nodePath.basename(folderToScaffold);
|
|
445
|
+
await (0, add_module_to_container_1.addModuleToContainer)((0, string_utils_1.anyCaseToPascalCase)(moduleName), `${moduleName}/${file.replace(".ts", "")}`, path, folderName);
|
|
420
446
|
}
|
|
421
447
|
/**
|
|
422
448
|
* Generate a module for service scaffolding with nested path
|
|
@@ -432,7 +458,7 @@ async function generateModuleServiceNestedPath(outputPathController, className,
|
|
|
432
458
|
.join(folderToScaffold, path, "..")
|
|
433
459
|
.normalize();
|
|
434
460
|
const newModuleName = `${moduleFileName}.module.ts`;
|
|
435
|
-
const newModuleOutputPath = `${newModulePath}/${newModuleName}`.replace(
|
|
461
|
+
const newModuleOutputPath = `${newModulePath}/${newModuleName}`.replace(/\\/g, "/");
|
|
436
462
|
const controllerToModule = nodePath
|
|
437
463
|
.relative(newModuleOutputPath, outputPathController)
|
|
438
464
|
.normalize()
|
|
@@ -457,7 +483,9 @@ async function generateModuleServiceNestedPath(outputPathController, className,
|
|
|
457
483
|
},
|
|
458
484
|
},
|
|
459
485
|
});
|
|
460
|
-
|
|
486
|
+
// Extract folder name from folderToScaffold (e.g., "src/useCases" -> "useCases")
|
|
487
|
+
const folderName = nodePath.basename(folderToScaffold);
|
|
488
|
+
await (0, add_module_to_container_1.addModuleToContainerNestedPath)((0, string_utils_1.anyCaseToPascalCase)(moduleFileName), path, folderName);
|
|
461
489
|
}
|
|
462
490
|
/**
|
|
463
491
|
* Generate a module
|
|
@@ -479,3 +507,80 @@ async function generateModule(outputPath, className, moduleName, path) {
|
|
|
479
507
|
},
|
|
480
508
|
});
|
|
481
509
|
}
|
|
510
|
+
// NEW v4.0 Schematic Generators
|
|
511
|
+
/**
|
|
512
|
+
* Generate an interceptor
|
|
513
|
+
*/
|
|
514
|
+
async function generateInterceptor(outputPath, className, priority) {
|
|
515
|
+
(0, command_utils_1.writeTemplate)({
|
|
516
|
+
outputPath,
|
|
517
|
+
template: {
|
|
518
|
+
path: "../templates/opinionated/interceptor.tpl",
|
|
519
|
+
data: {
|
|
520
|
+
className: (0, string_utils_1.anyCaseToPascalCase)(className),
|
|
521
|
+
priority: priority.toString(),
|
|
522
|
+
},
|
|
523
|
+
},
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Generate an event
|
|
528
|
+
*/
|
|
529
|
+
async function generateEvent(outputPath, className) {
|
|
530
|
+
(0, command_utils_1.writeTemplate)({
|
|
531
|
+
outputPath,
|
|
532
|
+
template: {
|
|
533
|
+
path: "../templates/opinionated/event.tpl",
|
|
534
|
+
data: {
|
|
535
|
+
className: (0, string_utils_1.anyCaseToPascalCase)(className),
|
|
536
|
+
},
|
|
537
|
+
},
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Generate an event handler
|
|
542
|
+
*/
|
|
543
|
+
async function generateHandler(outputPath, className, eventName, priority) {
|
|
544
|
+
(0, command_utils_1.writeTemplate)({
|
|
545
|
+
outputPath,
|
|
546
|
+
template: {
|
|
547
|
+
path: "../templates/opinionated/handler.tpl",
|
|
548
|
+
data: {
|
|
549
|
+
className: (0, string_utils_1.anyCaseToPascalCase)(className),
|
|
550
|
+
eventName: (0, string_utils_1.anyCaseToPascalCase)(eventName),
|
|
551
|
+
eventPath: `@events/${(0, string_utils_1.anyCaseToKebabCase)(eventName)}.event`,
|
|
552
|
+
priority: priority.toString(),
|
|
553
|
+
},
|
|
554
|
+
},
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Generate a guard
|
|
559
|
+
*/
|
|
560
|
+
async function generateGuard(outputPath, className) {
|
|
561
|
+
(0, command_utils_1.writeTemplate)({
|
|
562
|
+
outputPath,
|
|
563
|
+
template: {
|
|
564
|
+
path: "../templates/opinionated/guard.tpl",
|
|
565
|
+
data: {
|
|
566
|
+
className: (0, string_utils_1.anyCaseToPascalCase)(className),
|
|
567
|
+
},
|
|
568
|
+
},
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Generate a config module
|
|
573
|
+
*/
|
|
574
|
+
async function generateConfig(outputPath, className, moduleName) {
|
|
575
|
+
(0, command_utils_1.writeTemplate)({
|
|
576
|
+
outputPath,
|
|
577
|
+
template: {
|
|
578
|
+
path: "../templates/opinionated/config.tpl",
|
|
579
|
+
data: {
|
|
580
|
+
className: (0, string_utils_1.anyCaseToPascalCase)(className),
|
|
581
|
+
moduleName: (0, string_utils_1.anyCaseToCamelCase)(moduleName || className),
|
|
582
|
+
envPrefix: (0, string_utils_1.anyCaseToUpperSnakeCase)(className),
|
|
583
|
+
},
|
|
584
|
+
},
|
|
585
|
+
});
|
|
586
|
+
}
|
|
@@ -34,3 +34,9 @@ export declare function anyCaseToUpperCase(str: string): string;
|
|
|
34
34
|
* @returns The converted string in lower case.
|
|
35
35
|
*/
|
|
36
36
|
export declare function anyCaseToLowerCase(str: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Converts a string from any case (camelCase, PascalCase, kebab-case, snake_case) to UPPER_SNAKE_CASE.
|
|
39
|
+
* @param str - The input string to be converted.
|
|
40
|
+
* @returns The converted string in UPPER_SNAKE_CASE.
|
|
41
|
+
*/
|
|
42
|
+
export declare function anyCaseToUpperSnakeCase(str: string): string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.anyCaseToLowerCase = exports.anyCaseToUpperCase = exports.anyCaseToSnakeCase = exports.anyCaseToPascalCase = exports.anyCaseToKebabCase = exports.anyCaseToCamelCase = void 0;
|
|
3
|
+
exports.anyCaseToUpperSnakeCase = exports.anyCaseToLowerCase = exports.anyCaseToUpperCase = exports.anyCaseToSnakeCase = exports.anyCaseToPascalCase = exports.anyCaseToKebabCase = exports.anyCaseToCamelCase = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Converts a string from any case (camelCase, PascalCase, kebab-case, snake_case) to camelCase.
|
|
6
6
|
* @param str - The input string to be converted.
|
|
@@ -69,3 +69,15 @@ function anyCaseToLowerCase(str) {
|
|
|
69
69
|
.toLowerCase();
|
|
70
70
|
}
|
|
71
71
|
exports.anyCaseToLowerCase = anyCaseToLowerCase;
|
|
72
|
+
/**
|
|
73
|
+
* Converts a string from any case (camelCase, PascalCase, kebab-case, snake_case) to UPPER_SNAKE_CASE.
|
|
74
|
+
* @param str - The input string to be converted.
|
|
75
|
+
* @returns The converted string in UPPER_SNAKE_CASE.
|
|
76
|
+
*/
|
|
77
|
+
function anyCaseToUpperSnakeCase(str) {
|
|
78
|
+
return str
|
|
79
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1_$2")
|
|
80
|
+
.replace(/[-]+/g, "_")
|
|
81
|
+
.toUpperCase();
|
|
82
|
+
}
|
|
83
|
+
exports.anyCaseToUpperSnakeCase = anyCaseToUpperSnakeCase;
|
package/bin/help/form.js
CHANGED
|
@@ -15,15 +15,23 @@ const helpForm = async () => {
|
|
|
15
15
|
],
|
|
16
16
|
colWidths: [15, 15, 60],
|
|
17
17
|
});
|
|
18
|
-
table.push(
|
|
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
|
+
[
|
|
19
23
|
"service",
|
|
20
24
|
"g s",
|
|
21
25
|
"Generate a service [controller, usecase, dto, module]",
|
|
22
|
-
], ["controller", "g c", "Generate a controller"], ["usecase", "g u", "Generate a usecase"], ["dto", "g d", "Generate a dto"], ["entity", "g e", "Generate an entity"], ["
|
|
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"], [
|
|
23
31
|
"provider",
|
|
24
32
|
"add",
|
|
25
33
|
"Add provider to the project. Use -d to add as dev dependency",
|
|
26
|
-
], ["provider", "remove", "Remove provider from the project"], ["provider", "create", "Create external provider"]
|
|
34
|
+
], ["provider", "remove", "Remove provider from the project"], ["provider", "create", "Create external provider"]);
|
|
27
35
|
console.log(chalk_1.default.bold.white("ExpressoTS:", `${chalk_1.default.green("Resources List")}`));
|
|
28
36
|
console.log(chalk_1.default.whiteBright(table.toString()));
|
|
29
37
|
console.log(chalk_1.default.bold.white(`📝 More info: ${chalk_1.default.green("https://doc.expresso-ts.com/docs/category/cli")}`));
|
|
@@ -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 = {};
|
|
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,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.migrateCommand = void 0;
|
|
4
|
+
const form_1 = require("./form");
|
|
5
|
+
const migrateCommand = () => {
|
|
6
|
+
return {
|
|
7
|
+
command: "migrate <action> [options]",
|
|
8
|
+
describe: "Generate migration scripts between cloud platforms.",
|
|
9
|
+
aliases: ["migration", "mig"],
|
|
10
|
+
builder: (yargs) => {
|
|
11
|
+
yargs.positional("action", {
|
|
12
|
+
choices: ["init", "generate", "list", "analyze"],
|
|
13
|
+
describe: "Action to perform",
|
|
14
|
+
type: "string",
|
|
15
|
+
demandOption: true,
|
|
16
|
+
});
|
|
17
|
+
yargs.option("from", {
|
|
18
|
+
choices: [
|
|
19
|
+
"heroku",
|
|
20
|
+
"docker-compose",
|
|
21
|
+
"vercel",
|
|
22
|
+
"aws-ecs",
|
|
23
|
+
"gcp-cloudrun",
|
|
24
|
+
"azure-container",
|
|
25
|
+
],
|
|
26
|
+
describe: "Source platform to migrate from",
|
|
27
|
+
type: "string",
|
|
28
|
+
alias: "f",
|
|
29
|
+
});
|
|
30
|
+
yargs.option("to", {
|
|
31
|
+
choices: [
|
|
32
|
+
"railway",
|
|
33
|
+
"render",
|
|
34
|
+
"fly",
|
|
35
|
+
"kubernetes",
|
|
36
|
+
"aws-ecs",
|
|
37
|
+
"gcp-cloudrun",
|
|
38
|
+
"azure-container",
|
|
39
|
+
],
|
|
40
|
+
describe: "Target platform to migrate to",
|
|
41
|
+
type: "string",
|
|
42
|
+
alias: "t",
|
|
43
|
+
});
|
|
44
|
+
yargs.option("include-data", {
|
|
45
|
+
describe: "Include data migration scripts",
|
|
46
|
+
type: "boolean",
|
|
47
|
+
default: false,
|
|
48
|
+
});
|
|
49
|
+
yargs.option("include-secrets", {
|
|
50
|
+
describe: "Include secrets/environment variable migration",
|
|
51
|
+
type: "boolean",
|
|
52
|
+
default: true,
|
|
53
|
+
});
|
|
54
|
+
yargs.option("dry-run", {
|
|
55
|
+
describe: "Show migration steps without generating files",
|
|
56
|
+
type: "boolean",
|
|
57
|
+
default: false,
|
|
58
|
+
});
|
|
59
|
+
yargs.option("output-dir", {
|
|
60
|
+
describe: "Output directory for migration files",
|
|
61
|
+
type: "string",
|
|
62
|
+
alias: "o",
|
|
63
|
+
default: "./migration",
|
|
64
|
+
});
|
|
65
|
+
return yargs;
|
|
66
|
+
},
|
|
67
|
+
handler: async (argv) => {
|
|
68
|
+
const { action, from, to, includeData, includeSecrets, dryRun, outputDir, } = argv;
|
|
69
|
+
const options = {
|
|
70
|
+
from: from,
|
|
71
|
+
to: to,
|
|
72
|
+
includeData,
|
|
73
|
+
includeSecrets,
|
|
74
|
+
dryRun,
|
|
75
|
+
outputDir,
|
|
76
|
+
};
|
|
77
|
+
switch (action) {
|
|
78
|
+
case "init":
|
|
79
|
+
await (0, form_1.initMigration)(options);
|
|
80
|
+
break;
|
|
81
|
+
case "generate":
|
|
82
|
+
await (0, form_1.generateMigration)(options);
|
|
83
|
+
break;
|
|
84
|
+
case "list":
|
|
85
|
+
await (0, form_1.listMigrations)();
|
|
86
|
+
break;
|
|
87
|
+
case "analyze":
|
|
88
|
+
await (0, form_1.analyzeMigration)(options);
|
|
89
|
+
break;
|
|
90
|
+
default:
|
|
91
|
+
console.log(`Unknown action: ${action}`);
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
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>;
|