@expressots/cli 3.0.0 → 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
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global configuration manager for ExpressoTS CLI
|
|
3
|
+
* Manages user preferences stored in ~/.expressots/config.json
|
|
4
|
+
*/
|
|
5
|
+
export interface TemplateConfig {
|
|
6
|
+
repository: string;
|
|
7
|
+
branch: string;
|
|
8
|
+
cacheTTL: number;
|
|
9
|
+
}
|
|
10
|
+
export interface PricingConfig {
|
|
11
|
+
sources: ("api" | "remote" | "local")[];
|
|
12
|
+
cacheTTL: number;
|
|
13
|
+
customFile: string | null;
|
|
14
|
+
}
|
|
15
|
+
export interface GlobalConfig {
|
|
16
|
+
templates: TemplateConfig;
|
|
17
|
+
pricing: PricingConfig;
|
|
18
|
+
offline: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare class ConfigManager {
|
|
21
|
+
private config;
|
|
22
|
+
private configPath;
|
|
23
|
+
constructor();
|
|
24
|
+
/**
|
|
25
|
+
* Ensure config directory exists
|
|
26
|
+
*/
|
|
27
|
+
private ensureConfigDir;
|
|
28
|
+
/**
|
|
29
|
+
* Load configuration from file
|
|
30
|
+
*/
|
|
31
|
+
private load;
|
|
32
|
+
/**
|
|
33
|
+
* Merge loaded config with defaults
|
|
34
|
+
*/
|
|
35
|
+
private mergeWithDefaults;
|
|
36
|
+
/**
|
|
37
|
+
* Save configuration to file
|
|
38
|
+
*/
|
|
39
|
+
save(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Get full configuration
|
|
42
|
+
*/
|
|
43
|
+
getConfig(): GlobalConfig;
|
|
44
|
+
/**
|
|
45
|
+
* Get template configuration
|
|
46
|
+
*/
|
|
47
|
+
getTemplateConfig(): TemplateConfig;
|
|
48
|
+
/**
|
|
49
|
+
* Get pricing configuration
|
|
50
|
+
*/
|
|
51
|
+
getPricingConfig(): PricingConfig;
|
|
52
|
+
/**
|
|
53
|
+
* Set template repository
|
|
54
|
+
*/
|
|
55
|
+
setTemplateRepository(repository: string, branch?: string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Reset template repository to default
|
|
58
|
+
*/
|
|
59
|
+
resetTemplateRepository(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Set template cache TTL
|
|
62
|
+
*/
|
|
63
|
+
setTemplateCacheTTL(ttl: number): void;
|
|
64
|
+
/**
|
|
65
|
+
* Set pricing sources
|
|
66
|
+
*/
|
|
67
|
+
setPricingSources(sources: ("api" | "remote" | "local")[]): void;
|
|
68
|
+
/**
|
|
69
|
+
* Set custom pricing file
|
|
70
|
+
*/
|
|
71
|
+
setCustomPricingFile(filePath: string | null): void;
|
|
72
|
+
/**
|
|
73
|
+
* Set pricing cache TTL
|
|
74
|
+
*/
|
|
75
|
+
setPricingCacheTTL(ttl: number): void;
|
|
76
|
+
/**
|
|
77
|
+
* Set offline mode
|
|
78
|
+
*/
|
|
79
|
+
setOfflineMode(offline: boolean): void;
|
|
80
|
+
/**
|
|
81
|
+
* Get offline mode
|
|
82
|
+
*/
|
|
83
|
+
isOffline(): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Reset all configuration to defaults
|
|
86
|
+
*/
|
|
87
|
+
reset(): void;
|
|
88
|
+
/**
|
|
89
|
+
* Get config file path
|
|
90
|
+
*/
|
|
91
|
+
getConfigPath(): string;
|
|
92
|
+
/**
|
|
93
|
+
* Get config directory path
|
|
94
|
+
*/
|
|
95
|
+
getConfigDir(): string;
|
|
96
|
+
}
|
|
97
|
+
export declare function getConfigManager(): ConfigManager;
|
|
98
|
+
export declare function resetConfigManager(): void;
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Global configuration manager for ExpressoTS CLI
|
|
4
|
+
* Manages user preferences stored in ~/.expressots/config.json
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.resetConfigManager = exports.getConfigManager = exports.ConfigManager = void 0;
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const os_1 = __importDefault(require("os"));
|
|
14
|
+
const cli_ui_1 = require("../utils/cli-ui");
|
|
15
|
+
const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), ".expressots");
|
|
16
|
+
const CONFIG_FILE = path_1.default.join(CONFIG_DIR, "config.json");
|
|
17
|
+
const DEFAULT_CONFIG = {
|
|
18
|
+
templates: {
|
|
19
|
+
repository: "expressots/templates",
|
|
20
|
+
branch: "main",
|
|
21
|
+
cacheTTL: 86400, // 24 hours
|
|
22
|
+
},
|
|
23
|
+
pricing: {
|
|
24
|
+
sources: ["api", "remote", "local"],
|
|
25
|
+
cacheTTL: 21600,
|
|
26
|
+
customFile: null,
|
|
27
|
+
},
|
|
28
|
+
offline: false,
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Returns a deep clone of the default config so callers can mutate
|
|
32
|
+
* their copy without poisoning the module-level constant. A previous
|
|
33
|
+
* implementation used `{ ...DEFAULT_CONFIG }` which kept the inner
|
|
34
|
+
* `templates`/`pricing` objects shared, so `setTemplateRepository`
|
|
35
|
+
* mutated the defaults and broke `reset()`.
|
|
36
|
+
*/
|
|
37
|
+
function freshDefaults() {
|
|
38
|
+
return {
|
|
39
|
+
templates: { ...DEFAULT_CONFIG.templates },
|
|
40
|
+
pricing: {
|
|
41
|
+
...DEFAULT_CONFIG.pricing,
|
|
42
|
+
sources: [...DEFAULT_CONFIG.pricing.sources],
|
|
43
|
+
},
|
|
44
|
+
offline: DEFAULT_CONFIG.offline,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
class ConfigManager {
|
|
48
|
+
constructor() {
|
|
49
|
+
this.configPath = CONFIG_FILE;
|
|
50
|
+
this.config = this.load();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Ensure config directory exists
|
|
54
|
+
*/
|
|
55
|
+
ensureConfigDir() {
|
|
56
|
+
if (!fs_1.default.existsSync(CONFIG_DIR)) {
|
|
57
|
+
fs_1.default.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Load configuration from file
|
|
62
|
+
*/
|
|
63
|
+
load() {
|
|
64
|
+
if (!fs_1.default.existsSync(this.configPath)) {
|
|
65
|
+
return freshDefaults();
|
|
66
|
+
}
|
|
67
|
+
let content;
|
|
68
|
+
try {
|
|
69
|
+
content = fs_1.default.readFileSync(this.configPath, "utf-8");
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
(0, cli_ui_1.printWarning)(`Could not read ${this.configPath}: ${err.message}. Falling back to defaults.`, "config");
|
|
73
|
+
return freshDefaults();
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const loaded = JSON.parse(content);
|
|
77
|
+
if (loaded === null ||
|
|
78
|
+
typeof loaded !== "object" ||
|
|
79
|
+
Array.isArray(loaded)) {
|
|
80
|
+
(0, cli_ui_1.printWarning)(`${this.configPath} is not a JSON object. Falling back to defaults.`, "config");
|
|
81
|
+
return freshDefaults();
|
|
82
|
+
}
|
|
83
|
+
return this.mergeWithDefaults(loaded);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
(0, cli_ui_1.printWarning)(`${this.configPath} is not valid JSON: ${err.message}. Falling back to defaults.`, "config");
|
|
87
|
+
return freshDefaults();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Merge loaded config with defaults
|
|
92
|
+
*/
|
|
93
|
+
mergeWithDefaults(loaded) {
|
|
94
|
+
return {
|
|
95
|
+
templates: {
|
|
96
|
+
...DEFAULT_CONFIG.templates,
|
|
97
|
+
...loaded.templates,
|
|
98
|
+
},
|
|
99
|
+
pricing: {
|
|
100
|
+
...DEFAULT_CONFIG.pricing,
|
|
101
|
+
...loaded.pricing,
|
|
102
|
+
},
|
|
103
|
+
offline: loaded.offline ?? DEFAULT_CONFIG.offline,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Save configuration to file
|
|
108
|
+
*/
|
|
109
|
+
save() {
|
|
110
|
+
this.ensureConfigDir();
|
|
111
|
+
fs_1.default.writeFileSync(this.configPath, JSON.stringify(this.config, null, 2), "utf-8");
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get full configuration
|
|
115
|
+
*/
|
|
116
|
+
getConfig() {
|
|
117
|
+
return { ...this.config };
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get template configuration
|
|
121
|
+
*/
|
|
122
|
+
getTemplateConfig() {
|
|
123
|
+
return { ...this.config.templates };
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get pricing configuration
|
|
127
|
+
*/
|
|
128
|
+
getPricingConfig() {
|
|
129
|
+
return { ...this.config.pricing };
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Set template repository
|
|
133
|
+
*/
|
|
134
|
+
setTemplateRepository(repository, branch) {
|
|
135
|
+
this.config.templates.repository = repository;
|
|
136
|
+
if (branch) {
|
|
137
|
+
this.config.templates.branch = branch;
|
|
138
|
+
}
|
|
139
|
+
this.save();
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Reset template repository to default
|
|
143
|
+
*/
|
|
144
|
+
resetTemplateRepository() {
|
|
145
|
+
this.config.templates = { ...DEFAULT_CONFIG.templates };
|
|
146
|
+
this.save();
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Set template cache TTL
|
|
150
|
+
*/
|
|
151
|
+
setTemplateCacheTTL(ttl) {
|
|
152
|
+
this.config.templates.cacheTTL = ttl;
|
|
153
|
+
this.save();
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Set pricing sources
|
|
157
|
+
*/
|
|
158
|
+
setPricingSources(sources) {
|
|
159
|
+
this.config.pricing.sources = sources;
|
|
160
|
+
this.save();
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Set custom pricing file
|
|
164
|
+
*/
|
|
165
|
+
setCustomPricingFile(filePath) {
|
|
166
|
+
this.config.pricing.customFile = filePath;
|
|
167
|
+
this.save();
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Set pricing cache TTL
|
|
171
|
+
*/
|
|
172
|
+
setPricingCacheTTL(ttl) {
|
|
173
|
+
this.config.pricing.cacheTTL = ttl;
|
|
174
|
+
this.save();
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Set offline mode
|
|
178
|
+
*/
|
|
179
|
+
setOfflineMode(offline) {
|
|
180
|
+
this.config.offline = offline;
|
|
181
|
+
this.save();
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get offline mode
|
|
185
|
+
*/
|
|
186
|
+
isOffline() {
|
|
187
|
+
return this.config.offline;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Reset all configuration to defaults
|
|
191
|
+
*/
|
|
192
|
+
reset() {
|
|
193
|
+
this.config = freshDefaults();
|
|
194
|
+
this.save();
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Get config file path
|
|
198
|
+
*/
|
|
199
|
+
getConfigPath() {
|
|
200
|
+
return this.configPath;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Get config directory path
|
|
204
|
+
*/
|
|
205
|
+
getConfigDir() {
|
|
206
|
+
return CONFIG_DIR;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
exports.ConfigManager = ConfigManager;
|
|
210
|
+
// Singleton instance
|
|
211
|
+
let configInstance = null;
|
|
212
|
+
function getConfigManager() {
|
|
213
|
+
if (!configInstance) {
|
|
214
|
+
configInstance = new ConfigManager();
|
|
215
|
+
}
|
|
216
|
+
return configInstance;
|
|
217
|
+
}
|
|
218
|
+
exports.getConfigManager = getConfigManager;
|
|
219
|
+
function resetConfigManager() {
|
|
220
|
+
configInstance = null;
|
|
221
|
+
}
|
|
222
|
+
exports.resetConfigManager = resetConfigManager;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment file mapping from bootstrap configuration
|
|
3
|
+
*/
|
|
4
|
+
export interface EnvFileMapping {
|
|
5
|
+
[environment: string]: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Bootstrap configuration detected from main.ts
|
|
9
|
+
*/
|
|
10
|
+
export interface BootstrapConfig {
|
|
11
|
+
/** Whether envFileConfig is used */
|
|
12
|
+
hasEnvFileConfig: boolean;
|
|
13
|
+
/** Whether skipFileLoading is set to true (container-friendly) */
|
|
14
|
+
skipFileLoading: boolean;
|
|
15
|
+
/** Whether ciMode is explicitly set */
|
|
16
|
+
ciMode: boolean | undefined;
|
|
17
|
+
/** Environment file mappings */
|
|
18
|
+
envFiles: EnvFileMapping;
|
|
19
|
+
/** Required environment variables */
|
|
20
|
+
requiredVariables: string[];
|
|
21
|
+
/** Whether autoCreateTemplate is enabled */
|
|
22
|
+
autoCreateTemplate: boolean;
|
|
23
|
+
/** Current environment if specified */
|
|
24
|
+
currentEnvironment: string | undefined;
|
|
25
|
+
/** Detected env files that exist on disk */
|
|
26
|
+
existingEnvFiles: string[];
|
|
27
|
+
/** Detected env files that are missing */
|
|
28
|
+
missingEnvFiles: string[];
|
|
29
|
+
/** Whether the configuration is container-ready */
|
|
30
|
+
isContainerReady: boolean;
|
|
31
|
+
/** Recommendations for container deployment */
|
|
32
|
+
recommendations: string[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Analyze the bootstrap configuration in main.ts
|
|
36
|
+
* Detects environment file configurations that affect container deployment
|
|
37
|
+
*/
|
|
38
|
+
export declare function analyzeBootstrapConfig(): Promise<BootstrapConfig>;
|
|
39
|
+
/**
|
|
40
|
+
* Get the env file for a specific environment
|
|
41
|
+
*/
|
|
42
|
+
export declare function getEnvFileForEnvironment(config: BootstrapConfig, environment: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* Check if env files should be copied to the container
|
|
45
|
+
*/
|
|
46
|
+
export declare function shouldCopyEnvFiles(config: BootstrapConfig): boolean;
|
|
@@ -0,0 +1,187 @@
|
|
|
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.shouldCopyEnvFiles = exports.getEnvFileForEnvironment = exports.analyzeBootstrapConfig = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
/**
|
|
10
|
+
* Analyze the bootstrap configuration in main.ts
|
|
11
|
+
* Detects environment file configurations that affect container deployment
|
|
12
|
+
*/
|
|
13
|
+
async function analyzeBootstrapConfig() {
|
|
14
|
+
const cwd = process.cwd();
|
|
15
|
+
const result = {
|
|
16
|
+
hasEnvFileConfig: false,
|
|
17
|
+
skipFileLoading: false,
|
|
18
|
+
ciMode: undefined,
|
|
19
|
+
envFiles: {},
|
|
20
|
+
requiredVariables: [],
|
|
21
|
+
autoCreateTemplate: false,
|
|
22
|
+
currentEnvironment: undefined,
|
|
23
|
+
existingEnvFiles: [],
|
|
24
|
+
missingEnvFiles: [],
|
|
25
|
+
isContainerReady: true,
|
|
26
|
+
recommendations: [],
|
|
27
|
+
};
|
|
28
|
+
// Find main.ts file
|
|
29
|
+
const mainTsPath = findMainFile(cwd);
|
|
30
|
+
if (!mainTsPath) {
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
const content = fs_1.default.readFileSync(mainTsPath, "utf-8");
|
|
34
|
+
// Check if bootstrap is imported and used
|
|
35
|
+
if (!content.includes("bootstrap")) {
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
// Parse bootstrap configuration
|
|
39
|
+
parseBootstrapConfig(content, result);
|
|
40
|
+
// Detect existing env files
|
|
41
|
+
detectExistingEnvFiles(cwd, result);
|
|
42
|
+
// Determine if configuration is container-ready
|
|
43
|
+
evaluateContainerReadiness(result);
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
exports.analyzeBootstrapConfig = analyzeBootstrapConfig;
|
|
47
|
+
/**
|
|
48
|
+
* Find the main.ts file in the project
|
|
49
|
+
*/
|
|
50
|
+
function findMainFile(cwd) {
|
|
51
|
+
const possiblePaths = [
|
|
52
|
+
path_1.default.join(cwd, "src", "main.ts"),
|
|
53
|
+
path_1.default.join(cwd, "src", "index.ts"),
|
|
54
|
+
path_1.default.join(cwd, "main.ts"),
|
|
55
|
+
path_1.default.join(cwd, "index.ts"),
|
|
56
|
+
];
|
|
57
|
+
for (const filePath of possiblePaths) {
|
|
58
|
+
if (fs_1.default.existsSync(filePath)) {
|
|
59
|
+
return filePath;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Parse bootstrap configuration from file content
|
|
66
|
+
* Uses regex patterns to extract configuration without full AST parsing
|
|
67
|
+
*/
|
|
68
|
+
function parseBootstrapConfig(content, result) {
|
|
69
|
+
// Check for envFileConfig usage
|
|
70
|
+
const envFileConfigMatch = content.match(/envFileConfig\s*[:{]/);
|
|
71
|
+
if (envFileConfigMatch) {
|
|
72
|
+
result.hasEnvFileConfig = true;
|
|
73
|
+
}
|
|
74
|
+
// Check for skipFileLoading: true
|
|
75
|
+
if (/skipFileLoading\s*:\s*true/.test(content)) {
|
|
76
|
+
result.skipFileLoading = true;
|
|
77
|
+
}
|
|
78
|
+
// Check for ciMode
|
|
79
|
+
const ciModeMatch = content.match(/ciMode\s*:\s*(true|false)/);
|
|
80
|
+
if (ciModeMatch) {
|
|
81
|
+
result.ciMode = ciModeMatch[1] === "true";
|
|
82
|
+
}
|
|
83
|
+
// Check for autoCreateTemplate
|
|
84
|
+
if (/autoCreateTemplate\s*:\s*true/.test(content)) {
|
|
85
|
+
result.autoCreateTemplate = true;
|
|
86
|
+
}
|
|
87
|
+
// Extract files mapping
|
|
88
|
+
const filesMatch = content.match(/files\s*:\s*\{([^}]+)\}/s);
|
|
89
|
+
if (filesMatch) {
|
|
90
|
+
const filesContent = filesMatch[1];
|
|
91
|
+
// Match key-value pairs like: development: ".env.dev"
|
|
92
|
+
const envMappings = filesContent.matchAll(/(\w+)\s*:\s*["'`]([^"'`]+)["'`]/g);
|
|
93
|
+
for (const match of envMappings) {
|
|
94
|
+
result.envFiles[match[1]] = match[2];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Extract required variables
|
|
98
|
+
const requiredMatch = content.match(/required\s*:\s*\[([^\]]+)\]/s);
|
|
99
|
+
if (requiredMatch) {
|
|
100
|
+
const requiredContent = requiredMatch[1];
|
|
101
|
+
const variables = requiredContent.matchAll(/["'`]([^"'`]+)["'`]/g);
|
|
102
|
+
for (const match of variables) {
|
|
103
|
+
result.requiredVariables.push(match[1]);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Extract currentEnvironment
|
|
107
|
+
const envMatch = content.match(/currentEnvironment\s*:\s*["'`]([^"'`]+)["'`]/);
|
|
108
|
+
if (envMatch) {
|
|
109
|
+
result.currentEnvironment = envMatch[1];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Detect which env files exist and which are missing
|
|
114
|
+
*/
|
|
115
|
+
function detectExistingEnvFiles(cwd, result) {
|
|
116
|
+
// If no explicit files mapping, use convention
|
|
117
|
+
if (Object.keys(result.envFiles).length === 0 && result.hasEnvFileConfig) {
|
|
118
|
+
// Default convention: .env.{environment}
|
|
119
|
+
const defaultEnvs = ["development", "production", "staging", "test"];
|
|
120
|
+
for (const env of defaultEnvs) {
|
|
121
|
+
result.envFiles[env] = `.env.${env}`;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Check each mapped file
|
|
125
|
+
for (const [env, fileName] of Object.entries(result.envFiles)) {
|
|
126
|
+
const filePath = path_1.default.join(cwd, fileName);
|
|
127
|
+
if (fs_1.default.existsSync(filePath)) {
|
|
128
|
+
result.existingEnvFiles.push(fileName);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
result.missingEnvFiles.push(fileName);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Also check for common env files
|
|
135
|
+
const commonEnvFiles = [".env", ".env.local", ".env.example"];
|
|
136
|
+
for (const fileName of commonEnvFiles) {
|
|
137
|
+
const filePath = path_1.default.join(cwd, fileName);
|
|
138
|
+
if (fs_1.default.existsSync(filePath) &&
|
|
139
|
+
!result.existingEnvFiles.includes(fileName)) {
|
|
140
|
+
result.existingEnvFiles.push(fileName);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Evaluate if the bootstrap configuration is container-ready
|
|
146
|
+
*/
|
|
147
|
+
function evaluateContainerReadiness(result) {
|
|
148
|
+
result.isContainerReady = true;
|
|
149
|
+
result.recommendations = [];
|
|
150
|
+
// If envFileConfig is used but skipFileLoading is not true
|
|
151
|
+
if (result.hasEnvFileConfig && !result.skipFileLoading && !result.ciMode) {
|
|
152
|
+
// Check if there are missing env files for development
|
|
153
|
+
const devEnvFile = result.envFiles["development"] || ".env.development";
|
|
154
|
+
if (result.missingEnvFiles.includes(devEnvFile)) {
|
|
155
|
+
result.isContainerReady = false;
|
|
156
|
+
result.recommendations.push(`Create ${devEnvFile} or set skipFileLoading: true for containers`);
|
|
157
|
+
}
|
|
158
|
+
// Recommend container-friendly configuration
|
|
159
|
+
if (!result.skipFileLoading) {
|
|
160
|
+
result.recommendations.push("Consider using skipFileLoading: true for Docker deployments");
|
|
161
|
+
result.recommendations.push("Use docker-compose environment variables instead of .env files");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// If there are required variables, they need to be provided
|
|
165
|
+
if (result.requiredVariables.length > 0) {
|
|
166
|
+
result.recommendations.push(`Ensure these variables are set in docker-compose: ${result.requiredVariables.join(", ")}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get the env file for a specific environment
|
|
171
|
+
*/
|
|
172
|
+
function getEnvFileForEnvironment(config, environment) {
|
|
173
|
+
return config.envFiles[environment] || `.env.${environment}`;
|
|
174
|
+
}
|
|
175
|
+
exports.getEnvFileForEnvironment = getEnvFileForEnvironment;
|
|
176
|
+
/**
|
|
177
|
+
* Check if env files should be copied to the container
|
|
178
|
+
*/
|
|
179
|
+
function shouldCopyEnvFiles(config) {
|
|
180
|
+
// Don't copy if skipFileLoading is true or ciMode is true
|
|
181
|
+
if (config.skipFileLoading || config.ciMode) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
// Copy if envFileConfig is used and there are existing files
|
|
185
|
+
return config.hasEnvFileConfig && config.existingEnvFiles.length > 0;
|
|
186
|
+
}
|
|
187
|
+
exports.shouldCopyEnvFiles = shouldCopyEnvFiles;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type BootstrapConfig } from "./bootstrap-analyzer";
|
|
2
|
+
export interface ProjectAnalysis {
|
|
3
|
+
nodeVersion: string;
|
|
4
|
+
packageManager: "npm" | "pnpm" | "yarn" | "bun";
|
|
5
|
+
dependencies: string[];
|
|
6
|
+
devDependencies: string[];
|
|
7
|
+
controllers: string[];
|
|
8
|
+
hasDatabase: boolean;
|
|
9
|
+
hasRedis: boolean;
|
|
10
|
+
hasCors: boolean;
|
|
11
|
+
estimatedMemory: string;
|
|
12
|
+
estimatedCpu: string;
|
|
13
|
+
healthCheckPaths: string[];
|
|
14
|
+
port: number;
|
|
15
|
+
hasLocalDependencies: boolean;
|
|
16
|
+
localDependencyPaths: string[];
|
|
17
|
+
/** Bootstrap configuration analysis */
|
|
18
|
+
bootstrapConfig: BootstrapConfig;
|
|
19
|
+
}
|
|
20
|
+
export declare function analyzeProject(): Promise<ProjectAnalysis>;
|