@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,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Template cache management
|
|
4
|
+
* Stores templates locally for offline access and performance
|
|
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.getTemplateCache = exports.TemplateCache = 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 DEFAULT_CACHE_DIR = path_1.default.join(os_1.default.homedir(), ".expressots", "cache", "templates");
|
|
15
|
+
const DEFAULT_TTL = 86400; // 24 hours in seconds
|
|
16
|
+
class TemplateCache {
|
|
17
|
+
constructor(config) {
|
|
18
|
+
this.config = {
|
|
19
|
+
directory: config?.directory || DEFAULT_CACHE_DIR,
|
|
20
|
+
ttl: config?.ttl || DEFAULT_TTL,
|
|
21
|
+
};
|
|
22
|
+
this.ensureCacheDir();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Ensure cache directory exists
|
|
26
|
+
*/
|
|
27
|
+
ensureCacheDir() {
|
|
28
|
+
if (!fs_1.default.existsSync(this.config.directory)) {
|
|
29
|
+
fs_1.default.mkdirSync(this.config.directory, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Generate cache key from template identifier
|
|
34
|
+
*/
|
|
35
|
+
getCacheKey(category, platform, variant) {
|
|
36
|
+
const parts = [category, platform];
|
|
37
|
+
if (variant)
|
|
38
|
+
parts.push(variant);
|
|
39
|
+
return parts.join("-") + ".cache.json";
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get cache file path
|
|
43
|
+
*/
|
|
44
|
+
getCachePath(key) {
|
|
45
|
+
return path_1.default.join(this.config.directory, key);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if cache entry is valid (not expired)
|
|
49
|
+
*/
|
|
50
|
+
isValid(entry) {
|
|
51
|
+
const now = Date.now();
|
|
52
|
+
const expiresAt = entry.timestamp + entry.ttl * 1000;
|
|
53
|
+
return now < expiresAt;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get cached template content
|
|
57
|
+
*/
|
|
58
|
+
get(category, platform, variant) {
|
|
59
|
+
const key = this.getCacheKey(category, platform, variant);
|
|
60
|
+
const cachePath = this.getCachePath(key);
|
|
61
|
+
try {
|
|
62
|
+
if (!fs_1.default.existsSync(cachePath)) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const content = fs_1.default.readFileSync(cachePath, "utf-8");
|
|
66
|
+
const entry = JSON.parse(content);
|
|
67
|
+
if (!this.isValid(entry)) {
|
|
68
|
+
// Cache expired, remove it
|
|
69
|
+
this.delete(category, platform, variant);
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
return entry.data;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Set cached template content
|
|
80
|
+
*/
|
|
81
|
+
set(category, platform, data, variant, ttl) {
|
|
82
|
+
const key = this.getCacheKey(category, platform, variant);
|
|
83
|
+
const cachePath = this.getCachePath(key);
|
|
84
|
+
const entry = {
|
|
85
|
+
data,
|
|
86
|
+
timestamp: Date.now(),
|
|
87
|
+
ttl: ttl || this.config.ttl,
|
|
88
|
+
};
|
|
89
|
+
try {
|
|
90
|
+
fs_1.default.writeFileSync(cachePath, JSON.stringify(entry, null, 2), "utf-8");
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
// Silently fail - cache is optional
|
|
94
|
+
console.error("Failed to write cache:", error);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Delete cached template
|
|
99
|
+
*/
|
|
100
|
+
delete(category, platform, variant) {
|
|
101
|
+
const key = this.getCacheKey(category, platform, variant);
|
|
102
|
+
const cachePath = this.getCachePath(key);
|
|
103
|
+
try {
|
|
104
|
+
if (fs_1.default.existsSync(cachePath)) {
|
|
105
|
+
fs_1.default.unlinkSync(cachePath);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// Ignore deletion errors
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Clear all cached templates
|
|
114
|
+
*/
|
|
115
|
+
clear() {
|
|
116
|
+
try {
|
|
117
|
+
const files = fs_1.default.readdirSync(this.config.directory);
|
|
118
|
+
for (const file of files) {
|
|
119
|
+
if (file.endsWith(".cache.json")) {
|
|
120
|
+
fs_1.default.unlinkSync(path_1.default.join(this.config.directory, file));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// Ignore errors
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get cache statistics
|
|
130
|
+
*/
|
|
131
|
+
getStats() {
|
|
132
|
+
let files = 0;
|
|
133
|
+
let totalSize = 0;
|
|
134
|
+
let oldestTimestamp = Infinity;
|
|
135
|
+
try {
|
|
136
|
+
const entries = fs_1.default.readdirSync(this.config.directory);
|
|
137
|
+
for (const file of entries) {
|
|
138
|
+
if (!file.endsWith(".cache.json"))
|
|
139
|
+
continue;
|
|
140
|
+
const filePath = path_1.default.join(this.config.directory, file);
|
|
141
|
+
const stat = fs_1.default.statSync(filePath);
|
|
142
|
+
files++;
|
|
143
|
+
totalSize += stat.size;
|
|
144
|
+
try {
|
|
145
|
+
const content = JSON.parse(fs_1.default.readFileSync(filePath, "utf-8"));
|
|
146
|
+
if (content.timestamp < oldestTimestamp) {
|
|
147
|
+
oldestTimestamp = content.timestamp;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
// Skip invalid cache files
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// Directory doesn't exist or can't be read
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
files,
|
|
160
|
+
totalSize,
|
|
161
|
+
oldestEntry: oldestTimestamp === Infinity ? null : new Date(oldestTimestamp),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get cache directory path
|
|
166
|
+
*/
|
|
167
|
+
getCacheDirectory() {
|
|
168
|
+
return this.config.directory;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
exports.TemplateCache = TemplateCache;
|
|
172
|
+
// Singleton instance
|
|
173
|
+
let cacheInstance = null;
|
|
174
|
+
function getTemplateCache(config) {
|
|
175
|
+
if (!cacheInstance) {
|
|
176
|
+
cacheInstance = new TemplateCache(config);
|
|
177
|
+
}
|
|
178
|
+
return cacheInstance;
|
|
179
|
+
}
|
|
180
|
+
exports.getTemplateCache = getTemplateCache;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Templates CLI command
|
|
3
|
+
* Manage template sources, cache, and configuration
|
|
4
|
+
*/
|
|
5
|
+
import { CommandModule } from "yargs";
|
|
6
|
+
type CommandModuleArgs = Record<string, never>;
|
|
7
|
+
declare const templatesCommand: () => CommandModule<CommandModuleArgs, any>;
|
|
8
|
+
export { templatesCommand };
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Templates CLI command
|
|
4
|
+
* Manage template sources, cache, and configuration
|
|
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.templatesCommand = void 0;
|
|
11
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
+
const manager_1 = require("./manager");
|
|
13
|
+
const config_1 = require("../config");
|
|
14
|
+
const templatesCommand = () => {
|
|
15
|
+
return {
|
|
16
|
+
command: "templates <action> [args...]",
|
|
17
|
+
describe: "Manage CLI templates for CI/CD, Docker, and Kubernetes.",
|
|
18
|
+
aliases: ["tpl"],
|
|
19
|
+
builder: (yargs) => {
|
|
20
|
+
yargs.positional("action", {
|
|
21
|
+
choices: [
|
|
22
|
+
"list",
|
|
23
|
+
"update",
|
|
24
|
+
"clear",
|
|
25
|
+
"info",
|
|
26
|
+
"repo",
|
|
27
|
+
"status",
|
|
28
|
+
],
|
|
29
|
+
describe: "Action to perform",
|
|
30
|
+
type: "string",
|
|
31
|
+
demandOption: true,
|
|
32
|
+
});
|
|
33
|
+
yargs.positional("args", {
|
|
34
|
+
describe: "Additional arguments for the action",
|
|
35
|
+
type: "string",
|
|
36
|
+
array: true,
|
|
37
|
+
});
|
|
38
|
+
yargs.option("category", {
|
|
39
|
+
alias: "c",
|
|
40
|
+
type: "string",
|
|
41
|
+
describe: "Filter by category (cicd, docker, kubernetes, migrations)",
|
|
42
|
+
});
|
|
43
|
+
yargs.option("platform", {
|
|
44
|
+
alias: "p",
|
|
45
|
+
type: "string",
|
|
46
|
+
describe: "Filter by platform (github, gitlab, etc.)",
|
|
47
|
+
});
|
|
48
|
+
yargs.example("$0 templates list", "List all available templates");
|
|
49
|
+
yargs.example("$0 templates update", "Update template cache from remote");
|
|
50
|
+
yargs.example("$0 templates clear", "Clear local template cache");
|
|
51
|
+
yargs.example("$0 templates info cicd github", "Show template info");
|
|
52
|
+
yargs.example("$0 templates repo set https://github.com/myorg/templates", "Set custom repository");
|
|
53
|
+
yargs.example("$0 templates repo reset", "Reset to default repository");
|
|
54
|
+
yargs.example("$0 templates status", "Show template system status");
|
|
55
|
+
return yargs;
|
|
56
|
+
},
|
|
57
|
+
handler: async (argv) => {
|
|
58
|
+
const action = argv.action;
|
|
59
|
+
const args = argv.args || [];
|
|
60
|
+
switch (action) {
|
|
61
|
+
case "list":
|
|
62
|
+
await listTemplates(argv.category, argv.platform);
|
|
63
|
+
break;
|
|
64
|
+
case "update":
|
|
65
|
+
await updateTemplates();
|
|
66
|
+
break;
|
|
67
|
+
case "clear":
|
|
68
|
+
await clearCache();
|
|
69
|
+
break;
|
|
70
|
+
case "info":
|
|
71
|
+
await showTemplateInfo(args[0], args[1]);
|
|
72
|
+
break;
|
|
73
|
+
case "repo":
|
|
74
|
+
await manageRepository(args);
|
|
75
|
+
break;
|
|
76
|
+
case "status":
|
|
77
|
+
await showStatus();
|
|
78
|
+
break;
|
|
79
|
+
default:
|
|
80
|
+
console.log(chalk_1.default.red(`Unknown action: ${action}`));
|
|
81
|
+
console.log(chalk_1.default.gray("Run 'expressots templates --help' for usage."));
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
exports.templatesCommand = templatesCommand;
|
|
87
|
+
/**
|
|
88
|
+
* List available templates
|
|
89
|
+
*/
|
|
90
|
+
async function listTemplates(category, platform) {
|
|
91
|
+
console.log(chalk_1.default.cyan("\nš Available Templates\n"));
|
|
92
|
+
const manager = (0, manager_1.getTemplateManager)();
|
|
93
|
+
const templates = await manager.listTemplates();
|
|
94
|
+
// Show template source
|
|
95
|
+
const sourceLabel = templates.source === "remote"
|
|
96
|
+
? chalk_1.default.green("(from remote repository)")
|
|
97
|
+
: chalk_1.default.yellow("(embedded fallback)");
|
|
98
|
+
console.log(chalk_1.default.gray(` Source: ${sourceLabel}\n`));
|
|
99
|
+
if (Object.keys(templates.cicd).length === 0 &&
|
|
100
|
+
templates.docker.length === 0 &&
|
|
101
|
+
templates.kubernetes.length === 0) {
|
|
102
|
+
console.log(chalk_1.default.yellow("No templates available. Run 'expressots templates update' to fetch templates."));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// CI/CD Templates
|
|
106
|
+
if (!category || category === "cicd") {
|
|
107
|
+
console.log(chalk_1.default.bold("CI/CD Pipelines:"));
|
|
108
|
+
if (Object.keys(templates.cicd).length === 0) {
|
|
109
|
+
console.log(chalk_1.default.gray(" No CI/CD templates available"));
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
for (const [plat, strategies] of Object.entries(templates.cicd)) {
|
|
113
|
+
if (!platform || platform === plat) {
|
|
114
|
+
console.log(` ${chalk_1.default.yellow(plat)}: ${strategies.join(", ")}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
console.log();
|
|
119
|
+
}
|
|
120
|
+
// Docker Templates
|
|
121
|
+
if (!category || category === "docker") {
|
|
122
|
+
console.log(chalk_1.default.bold("Docker:"));
|
|
123
|
+
if (templates.docker.length === 0) {
|
|
124
|
+
console.log(chalk_1.default.gray(" No Docker templates available"));
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
for (const tpl of templates.docker) {
|
|
128
|
+
console.log(` ${chalk_1.default.cyan(tpl)}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
console.log();
|
|
132
|
+
}
|
|
133
|
+
// Kubernetes Templates
|
|
134
|
+
if (!category || category === "kubernetes") {
|
|
135
|
+
console.log(chalk_1.default.bold("Kubernetes:"));
|
|
136
|
+
if (templates.kubernetes.length === 0) {
|
|
137
|
+
console.log(chalk_1.default.gray(" No Kubernetes templates available"));
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
for (const tpl of templates.kubernetes) {
|
|
141
|
+
console.log(` ${chalk_1.default.green(tpl)}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
console.log();
|
|
145
|
+
}
|
|
146
|
+
// Migration Templates
|
|
147
|
+
if (!category || category === "migrations") {
|
|
148
|
+
console.log(chalk_1.default.bold("Migrations:"));
|
|
149
|
+
if (templates.migrations.length === 0) {
|
|
150
|
+
console.log(chalk_1.default.gray(" No migration templates available"));
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
for (const tpl of templates.migrations) {
|
|
154
|
+
console.log(` ${chalk_1.default.magenta(tpl)}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
console.log();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Update template cache
|
|
162
|
+
*/
|
|
163
|
+
async function updateTemplates() {
|
|
164
|
+
console.log(chalk_1.default.cyan("\nš Updating Templates...\n"));
|
|
165
|
+
const manager = (0, manager_1.getTemplateManager)();
|
|
166
|
+
const result = await manager.updateCache();
|
|
167
|
+
if (result.updated > 0) {
|
|
168
|
+
console.log(chalk_1.default.green(`ā Updated ${result.updated} templates`));
|
|
169
|
+
}
|
|
170
|
+
if (result.errors.length > 0) {
|
|
171
|
+
console.log(chalk_1.default.yellow(`\nā ļø ${result.errors.length} errors occurred:`));
|
|
172
|
+
for (const error of result.errors) {
|
|
173
|
+
console.log(chalk_1.default.gray(` - ${error}`));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (result.updated === 0 && result.errors.length === 0) {
|
|
177
|
+
console.log(chalk_1.default.yellow("No templates were updated. Check your network connection."));
|
|
178
|
+
}
|
|
179
|
+
console.log();
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Clear template cache
|
|
183
|
+
*/
|
|
184
|
+
async function clearCache() {
|
|
185
|
+
console.log(chalk_1.default.cyan("\nšļø Clearing Template Cache...\n"));
|
|
186
|
+
const manager = (0, manager_1.getTemplateManager)();
|
|
187
|
+
const stats = manager.getCacheStats();
|
|
188
|
+
manager.clearCache();
|
|
189
|
+
console.log(chalk_1.default.green(`ā Cleared ${stats.files} cached templates`));
|
|
190
|
+
console.log(chalk_1.default.gray(` Freed ${(stats.totalSize / 1024).toFixed(2)} KB`));
|
|
191
|
+
console.log();
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Show template info
|
|
195
|
+
*/
|
|
196
|
+
async function showTemplateInfo(category, platform) {
|
|
197
|
+
if (!category) {
|
|
198
|
+
console.log(chalk_1.default.red("Please specify a category and platform."));
|
|
199
|
+
console.log(chalk_1.default.gray("Example: expressots templates info cicd github"));
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
console.log(chalk_1.default.cyan(`\nš Template Info: ${category}${platform ? `/${platform}` : ""}\n`));
|
|
203
|
+
const manager = (0, manager_1.getTemplateManager)();
|
|
204
|
+
const manifest = await manager.getManifest();
|
|
205
|
+
if (!manifest) {
|
|
206
|
+
console.log(chalk_1.default.yellow("No manifest available. Run 'expressots templates update' first."));
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const categoryTemplates = manifest.templates[category];
|
|
210
|
+
if (!categoryTemplates) {
|
|
211
|
+
console.log(chalk_1.default.red(`Category '${category}' not found.`));
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (platform) {
|
|
215
|
+
const platformTemplates = categoryTemplates[platform];
|
|
216
|
+
if (!platformTemplates) {
|
|
217
|
+
console.log(chalk_1.default.red(`Platform '${platform}' not found in category '${category}'.`));
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
console.log(chalk_1.default.bold(`${category}/${platform}:`));
|
|
221
|
+
for (const [variant, info] of Object.entries(platformTemplates)) {
|
|
222
|
+
console.log(` ${chalk_1.default.yellow(variant)}:`);
|
|
223
|
+
console.log(` Path: ${info.path}`);
|
|
224
|
+
console.log(` Version: ${info.version}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
console.log(chalk_1.default.bold(`${category}:`));
|
|
229
|
+
for (const [key, value] of Object.entries(categoryTemplates)) {
|
|
230
|
+
console.log(` ${chalk_1.default.yellow(key)}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
console.log();
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Manage template repository
|
|
237
|
+
*/
|
|
238
|
+
async function manageRepository(args) {
|
|
239
|
+
const configManager = (0, config_1.getConfigManager)();
|
|
240
|
+
const subAction = args[0];
|
|
241
|
+
if (!subAction) {
|
|
242
|
+
const config = configManager.getTemplateConfig();
|
|
243
|
+
console.log(chalk_1.default.cyan("\nš¦ Template Repository Configuration\n"));
|
|
244
|
+
console.log(` Repository: ${chalk_1.default.yellow(config.repository)}`);
|
|
245
|
+
console.log(` Branch: ${chalk_1.default.cyan(config.branch)}`);
|
|
246
|
+
console.log(` Cache TTL: ${config.cacheTTL} seconds`);
|
|
247
|
+
console.log();
|
|
248
|
+
console.log(chalk_1.default.gray("Use 'expressots templates repo set <url>' to change."));
|
|
249
|
+
console.log(chalk_1.default.gray("Use 'expressots templates repo reset' to restore defaults."));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
switch (subAction) {
|
|
253
|
+
case "set": {
|
|
254
|
+
const repository = args[1];
|
|
255
|
+
const branch = args[2];
|
|
256
|
+
if (!repository) {
|
|
257
|
+
console.log(chalk_1.default.red("Please specify a repository URL."));
|
|
258
|
+
console.log(chalk_1.default.gray("Example: expressots templates repo set https://github.com/myorg/templates"));
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
configManager.setTemplateRepository(repository, branch);
|
|
262
|
+
// Clear cache when repository changes
|
|
263
|
+
const manager = (0, manager_1.getTemplateManager)();
|
|
264
|
+
manager.clearCache();
|
|
265
|
+
manager.setRepository(repository, branch);
|
|
266
|
+
console.log(chalk_1.default.green(`\nā Template repository set to: ${repository}`));
|
|
267
|
+
if (branch) {
|
|
268
|
+
console.log(chalk_1.default.green(` Branch: ${branch}`));
|
|
269
|
+
}
|
|
270
|
+
console.log(chalk_1.default.gray("\nRun 'expressots templates update' to fetch templates from the new repository."));
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
case "reset": {
|
|
274
|
+
configManager.resetTemplateRepository();
|
|
275
|
+
const manager = (0, manager_1.getTemplateManager)();
|
|
276
|
+
manager.clearCache();
|
|
277
|
+
manager.setRepository("expressots/templates", "main");
|
|
278
|
+
console.log(chalk_1.default.green("\nā Template repository reset to default (expressots/templates)"));
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
default:
|
|
282
|
+
console.log(chalk_1.default.red(`Unknown repository action: ${subAction}`));
|
|
283
|
+
console.log(chalk_1.default.gray("Use 'set' or 'reset'."));
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Show template system status
|
|
288
|
+
*/
|
|
289
|
+
async function showStatus() {
|
|
290
|
+
const manager = (0, manager_1.getTemplateManager)();
|
|
291
|
+
await manager.printStatus();
|
|
292
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template fetcher - fetches templates from GitHub repository
|
|
3
|
+
*/
|
|
4
|
+
import type { TemplateManifest, FetchResult } from "./types";
|
|
5
|
+
export interface FetcherConfig {
|
|
6
|
+
repository: string;
|
|
7
|
+
branch: string;
|
|
8
|
+
timeout: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class GitHubFetcher {
|
|
11
|
+
private config;
|
|
12
|
+
private retryCount;
|
|
13
|
+
private retryDelay;
|
|
14
|
+
constructor(config?: Partial<FetcherConfig>);
|
|
15
|
+
/**
|
|
16
|
+
* Build raw GitHub URL for a file
|
|
17
|
+
*/
|
|
18
|
+
private buildUrl;
|
|
19
|
+
/**
|
|
20
|
+
* Fetch content from URL with retry logic
|
|
21
|
+
*/
|
|
22
|
+
private fetchWithRetry;
|
|
23
|
+
/**
|
|
24
|
+
* Fetch template manifest
|
|
25
|
+
*/
|
|
26
|
+
fetchManifest(): Promise<FetchResult<TemplateManifest>>;
|
|
27
|
+
/**
|
|
28
|
+
* Fetch template content by path
|
|
29
|
+
*/
|
|
30
|
+
fetchTemplate(templatePath: string): Promise<FetchResult<string>>;
|
|
31
|
+
/**
|
|
32
|
+
* Fetch template by category, platform, and variant
|
|
33
|
+
*/
|
|
34
|
+
fetchByType(category: string, platform: string, variant?: string): Promise<FetchResult<string>>;
|
|
35
|
+
/**
|
|
36
|
+
* Check if repository is accessible
|
|
37
|
+
*/
|
|
38
|
+
checkConnection(): Promise<boolean>;
|
|
39
|
+
/**
|
|
40
|
+
* Update repository configuration
|
|
41
|
+
*/
|
|
42
|
+
setRepository(repository: string, branch?: string): void;
|
|
43
|
+
/**
|
|
44
|
+
* Get current configuration
|
|
45
|
+
*/
|
|
46
|
+
getConfig(): FetcherConfig;
|
|
47
|
+
}
|
|
48
|
+
export declare function getGitHubFetcher(config?: Partial<FetcherConfig>): GitHubFetcher;
|
|
49
|
+
export declare function resetFetcher(): void;
|