katax-cli 1.3.1 ā 1.3.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/dist/commands/generate-docs.d.ts.map +1 -1
- package/dist/commands/generate-docs.js +46 -11
- package/dist/commands/generate-docs.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +224 -24
- package/dist/commands/init.js.map +1 -1
- package/dist/services/openapi-generator.service.d.ts +9 -1
- package/dist/services/openapi-generator.service.d.ts.map +1 -1
- package/dist/services/openapi-generator.service.js +268 -68
- package/dist/services/openapi-generator.service.js.map +1 -1
- package/dist/templates/generators/swagger-template.d.ts +2 -2
- package/dist/templates/generators/swagger-template.d.ts.map +1 -1
- package/dist/templates/generators/swagger-template.js +10 -7
- package/dist/templates/generators/swagger-template.js.map +1 -1
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-docs.d.ts","sourceRoot":"","sources":["../../src/commands/generate-docs.ts"],"names":[],"mappings":"AAYA,UAAU,mBAAmB;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;
|
|
1
|
+
{"version":3,"file":"generate-docs.d.ts","sourceRoot":"","sources":["../../src/commands/generate-docs.ts"],"names":[],"mappings":"AAYA,UAAU,mBAAmB;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA+CD,wBAAsB,kBAAkB,CACtC,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,IAAI,CAAC,CAkCf;AAKD,wBAAsB,mBAAmB,CACvC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,IAAI,CAAC,CA+Gf"}
|
|
@@ -6,6 +6,47 @@ import { OpenAPIGenerator } from "../services/openapi-generator.service.js";
|
|
|
6
6
|
import { generateSwaggerSetup, generateSwaggerReadme, } from "../templates/generators/swagger-template.js";
|
|
7
7
|
import { success, error, warning, info, title } from "../utils/logger.js";
|
|
8
8
|
import { writeFile } from "../utils/file-utils.js";
|
|
9
|
+
function extractPort(value) {
|
|
10
|
+
if (!value)
|
|
11
|
+
return undefined;
|
|
12
|
+
const trimmed = value.trim().replace(/^['\"]|['\"]$/g, "");
|
|
13
|
+
const match = trimmed.match(/\b(\d{2,5})\b/);
|
|
14
|
+
if (!match)
|
|
15
|
+
return undefined;
|
|
16
|
+
const port = Number(match[1]);
|
|
17
|
+
if (Number.isNaN(port) || port < 1 || port > 65535)
|
|
18
|
+
return undefined;
|
|
19
|
+
return String(port);
|
|
20
|
+
}
|
|
21
|
+
function resolveProjectPort(projectPath, preferredPort) {
|
|
22
|
+
const fromOption = extractPort(preferredPort);
|
|
23
|
+
if (fromOption)
|
|
24
|
+
return fromOption;
|
|
25
|
+
const envPath = path.join(projectPath, ".env");
|
|
26
|
+
if (existsSync(envPath)) {
|
|
27
|
+
const envContent = readFileSync(envPath, "utf-8");
|
|
28
|
+
const portMatch = envContent.match(/^PORT\s*=\s*(.+)$/m);
|
|
29
|
+
const fromEnv = extractPort(portMatch?.[1]);
|
|
30
|
+
if (fromEnv)
|
|
31
|
+
return fromEnv;
|
|
32
|
+
}
|
|
33
|
+
const indexPath = path.join(projectPath, "src", "index.ts");
|
|
34
|
+
if (existsSync(indexPath)) {
|
|
35
|
+
const indexContent = readFileSync(indexPath, "utf-8");
|
|
36
|
+
const patterns = [
|
|
37
|
+
/katax\.env\(\s*['\"]PORT['\"]\s*,\s*['\"](\d{2,5})['\"]\s*\)/,
|
|
38
|
+
/process\.env\.PORT\s*\|\|\s*['\"]?(\d{2,5})['\"]?/,
|
|
39
|
+
/process\.env\.PORT\s*\?\?\s*['\"]?(\d{2,5})['\"]?/,
|
|
40
|
+
];
|
|
41
|
+
for (const pattern of patterns) {
|
|
42
|
+
const match = indexContent.match(pattern);
|
|
43
|
+
const parsed = extractPort(match?.[1]);
|
|
44
|
+
if (parsed)
|
|
45
|
+
return parsed;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return "3000";
|
|
49
|
+
}
|
|
9
50
|
export async function autoRegenerateDocs(projectPath = process.cwd()) {
|
|
10
51
|
try {
|
|
11
52
|
const apiPath = path.join(projectPath, "src", "api");
|
|
@@ -47,22 +88,16 @@ export async function generateDocsCommand(options = {}) {
|
|
|
47
88
|
const spinner = ora("Scanning project structure...").start();
|
|
48
89
|
try {
|
|
49
90
|
const envPath = path.join(projectPath, ".env");
|
|
50
|
-
let port = options.port;
|
|
91
|
+
let port = resolveProjectPort(projectPath, options.port);
|
|
51
92
|
let productionUrl = options.url;
|
|
52
93
|
if (existsSync(envPath)) {
|
|
53
94
|
const envContent = readFileSync(envPath, "utf-8");
|
|
54
|
-
if (!port) {
|
|
55
|
-
const portMatch = envContent.match(/^PORT\s*=\s*(\d+)/m);
|
|
56
|
-
if (portMatch)
|
|
57
|
-
port = portMatch[1];
|
|
58
|
-
}
|
|
59
95
|
if (!productionUrl) {
|
|
60
96
|
const urlMatch = envContent.match(/^(?:API_URL|PRODUCTION_URL)\s*=\s*(.+)/m);
|
|
61
97
|
if (urlMatch)
|
|
62
98
|
productionUrl = urlMatch[1].trim();
|
|
63
99
|
}
|
|
64
100
|
}
|
|
65
|
-
port = port || "3000";
|
|
66
101
|
const generator = new OpenAPIGenerator(projectPath, {
|
|
67
102
|
port,
|
|
68
103
|
productionUrl,
|
|
@@ -79,7 +114,7 @@ export async function generateDocsCommand(options = {}) {
|
|
|
79
114
|
const outputPath = options.output || path.join(projectPath, "src", "openapi.json");
|
|
80
115
|
await writeFile(outputPath, JSON.stringify(spec, null, 2));
|
|
81
116
|
spinner.succeed("OpenAPI specification generated");
|
|
82
|
-
await setupSwaggerUI(projectPath, options.force);
|
|
117
|
+
await setupSwaggerUI(projectPath, options.force, port);
|
|
83
118
|
success("\nā
API Documentation generated successfully!\n");
|
|
84
119
|
const endpointCount = Object.values(spec.paths).reduce((count, methods) => count + Object.keys(methods).length, 0);
|
|
85
120
|
info(`š Documentation Stats:`);
|
|
@@ -102,7 +137,7 @@ export async function generateDocsCommand(options = {}) {
|
|
|
102
137
|
process.exit(1);
|
|
103
138
|
}
|
|
104
139
|
}
|
|
105
|
-
async function setupSwaggerUI(projectPath, force = false) {
|
|
140
|
+
async function setupSwaggerUI(projectPath, force = false, port = "3000") {
|
|
106
141
|
const configDir = path.join(projectPath, "src", "config");
|
|
107
142
|
const swaggerConfigPath = path.join(configDir, "swagger.config.ts");
|
|
108
143
|
if (existsSync(swaggerConfigPath) && !force) {
|
|
@@ -111,7 +146,7 @@ async function setupSwaggerUI(projectPath, force = false) {
|
|
|
111
146
|
}
|
|
112
147
|
const spinner = ora("Setting up Swagger UI...").start();
|
|
113
148
|
try {
|
|
114
|
-
await writeFile(swaggerConfigPath, generateSwaggerSetup());
|
|
149
|
+
await writeFile(swaggerConfigPath, generateSwaggerSetup(port));
|
|
115
150
|
const appPath = path.join(projectPath, "src", "app.ts");
|
|
116
151
|
if (existsSync(appPath)) {
|
|
117
152
|
let appContent = readFileSync(appPath, "utf-8");
|
|
@@ -144,7 +179,7 @@ async function setupSwaggerUI(projectPath, force = false) {
|
|
|
144
179
|
}
|
|
145
180
|
const docsReadmePath = path.join(projectPath, "DOCS.md");
|
|
146
181
|
if (!existsSync(docsReadmePath) || force) {
|
|
147
|
-
await writeFile(docsReadmePath, generateSwaggerReadme());
|
|
182
|
+
await writeFile(docsReadmePath, generateSwaggerReadme(port));
|
|
148
183
|
}
|
|
149
184
|
await updatePackageJsonDependencies(projectPath);
|
|
150
185
|
spinner.succeed("Swagger UI configured");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-docs.js","sourceRoot":"","sources":["../../src/commands/generate-docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC7D,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"generate-docs.js","sourceRoot":"","sources":["../../src/commands/generate-docs.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAgBA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,WAAW,CAC/B,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,GAAE,WAAgB,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAgBA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,WAAW,CAC/B,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,GAAE,WAAgB,iBA6Z1B"}
|
package/dist/commands/init.js
CHANGED
|
@@ -79,6 +79,55 @@ export async function initCommand(projectName, options = {}) {
|
|
|
79
79
|
message: "Use katax-service-manager for services? (logger, database, etc.)",
|
|
80
80
|
default: true,
|
|
81
81
|
},
|
|
82
|
+
{
|
|
83
|
+
type: "list",
|
|
84
|
+
name: "kataxMode",
|
|
85
|
+
message: "Katax mode:",
|
|
86
|
+
choices: [
|
|
87
|
+
{ name: "Singleton (shared katax instance)", value: "singleton" },
|
|
88
|
+
{ name: "Instance (new Katax())", value: "instance" },
|
|
89
|
+
],
|
|
90
|
+
default: "singleton",
|
|
91
|
+
when: (answers) => answers.useKataxServiceManager,
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
type: "confirm",
|
|
95
|
+
name: "useRegistry",
|
|
96
|
+
message: "Enable Katax registry integration?",
|
|
97
|
+
default: false,
|
|
98
|
+
when: (answers) => answers.useKataxServiceManager,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
type: "list",
|
|
102
|
+
name: "registryMode",
|
|
103
|
+
message: "Registry integration mode:",
|
|
104
|
+
choices: [
|
|
105
|
+
{ name: "HTTP URL registry", value: "url" },
|
|
106
|
+
{ name: "Callback handler (custom integration)", value: "handler" },
|
|
107
|
+
],
|
|
108
|
+
default: "url",
|
|
109
|
+
when: (answers) => answers.useKataxServiceManager && answers.useRegistry,
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
type: "input",
|
|
113
|
+
name: "registryUrl",
|
|
114
|
+
message: "Registry URL (e.g. https://dashboard.example.com/api/services):",
|
|
115
|
+
default: "http://localhost:4000/api/services",
|
|
116
|
+
when: (answers) => answers.useKataxServiceManager && answers.useRegistry && answers.registryMode === "url",
|
|
117
|
+
validate: (input) => {
|
|
118
|
+
if (!input?.trim()) {
|
|
119
|
+
return "Registry URL is required";
|
|
120
|
+
}
|
|
121
|
+
return true;
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
type: "confirm",
|
|
126
|
+
name: "useLifecycleHooks",
|
|
127
|
+
message: "Generate Katax lifecycle hooks scaffold?",
|
|
128
|
+
default: false,
|
|
129
|
+
when: (answers) => answers.useKataxServiceManager,
|
|
130
|
+
},
|
|
82
131
|
{
|
|
83
132
|
type: "confirm",
|
|
84
133
|
name: "useRedis",
|
|
@@ -249,10 +298,15 @@ export async function initCommand(projectName, options = {}) {
|
|
|
249
298
|
orm: "none",
|
|
250
299
|
port: parseInt(answers.port),
|
|
251
300
|
useKataxServiceManager: answers.useKataxServiceManager,
|
|
301
|
+
kataxMode: answers.kataxMode || "singleton",
|
|
252
302
|
useRedis: answers.useRedis || false,
|
|
253
303
|
useWebSocket: answers.useWebSocket || false,
|
|
254
304
|
useSeparateSocketPort: answers.useSeparateSocketPort || false,
|
|
255
305
|
socketPort: answers.socketPort ? parseInt(answers.socketPort) : 3001,
|
|
306
|
+
useRegistry: answers.useRegistry || false,
|
|
307
|
+
registryMode: answers.useRegistry ? (answers.registryMode || "url") : "none",
|
|
308
|
+
registryUrl: answers.registryUrl,
|
|
309
|
+
useLifecycleHooks: answers.useLifecycleHooks || false,
|
|
256
310
|
initGit: answers.initGit,
|
|
257
311
|
redisConfig,
|
|
258
312
|
dbConfig,
|
|
@@ -277,6 +331,9 @@ export async function initCommand(projectName, options = {}) {
|
|
|
277
331
|
gray(` Swagger: ${config.swagger ? "Yes" : "No"}`);
|
|
278
332
|
gray(` Service Manager: ${config.useKataxServiceManager ? "katax-service-manager" : "manual"}`);
|
|
279
333
|
if (config.useKataxServiceManager) {
|
|
334
|
+
gray(` Katax Mode: ${config.kataxMode === "instance" ? "Instance (new Katax())" : "Singleton"}`);
|
|
335
|
+
gray(` Registry: ${config.useRegistry ? (config.registryMode === "url" ? `URL (${config.registryUrl})` : "Callback handler") : "No"}`);
|
|
336
|
+
gray(` Lifecycle Hooks: ${config.useLifecycleHooks ? "Yes" : "No"}`);
|
|
280
337
|
gray(` Redis Cache: ${config.useRedis ? "Yes" : "No"}`);
|
|
281
338
|
gray(` WebSocket: ${config.useWebSocket ? (config.useSeparateSocketPort ? `Yes (port ${config.socketPort})` : "Yes (shared port)") : "No"}`);
|
|
282
339
|
}
|
|
@@ -508,7 +565,7 @@ async function createProjectStructure(projectPath, config, generateJwtSecrets) {
|
|
|
508
565
|
cors: "^2.8.5",
|
|
509
566
|
dotenv: "^16.3.1",
|
|
510
567
|
...(config.useKataxServiceManager
|
|
511
|
-
? { "katax-service-manager": "
|
|
568
|
+
? { "katax-service-manager": "^0.3.3", "pino-pretty": "^10.3.1" }
|
|
512
569
|
: { pino: "^8.17.2", "pino-pretty": "^10.3.1" }),
|
|
513
570
|
...(config.validation === "katax-core" && { "katax-core": "latest" }),
|
|
514
571
|
...(config.authentication === "jwt" && {
|
|
@@ -625,6 +682,17 @@ REDIS_HOST=${host || "localhost"}
|
|
|
625
682
|
REDIS_PORT=${port || "6379"}
|
|
626
683
|
REDIS_PASSWORD=${password || ""}
|
|
627
684
|
REDIS_DB=${db || "0"}`;
|
|
685
|
+
}
|
|
686
|
+
let registryEnvVars = "";
|
|
687
|
+
if (config.useKataxServiceManager && config.useRegistry && config.registryMode === "url") {
|
|
688
|
+
registryEnvVars = `
|
|
689
|
+
# Katax Registry Configuration
|
|
690
|
+
REGISTRY_URL=${config.registryUrl || "http://localhost:4000/api/services"}
|
|
691
|
+
REGISTRY_API_KEY=
|
|
692
|
+
REGISTRY_HEARTBEAT_MS=30000
|
|
693
|
+
REGISTRY_TIMEOUT_MS=5000
|
|
694
|
+
REGISTRY_RETRY_ATTEMPTS=2
|
|
695
|
+
REGISTRY_RETRY_BASE_DELAY_MS=300`;
|
|
628
696
|
}
|
|
629
697
|
const envContent = `# Server Configuration
|
|
630
698
|
PORT=${config.port}
|
|
@@ -640,6 +708,7 @@ ${databaseUrl}
|
|
|
640
708
|
${dbEnvVars ? "\n# DB connection variables for pool\n" + dbEnvVars : ""}`
|
|
641
709
|
: ""}
|
|
642
710
|
${redisEnvVars}
|
|
711
|
+
${registryEnvVars}
|
|
643
712
|
${config.authentication === "jwt" ? `\n# JWT Configuration\n${jwtConfig}` : ""}
|
|
644
713
|
`;
|
|
645
714
|
await writeFile(path.join(projectPath, ".env.example"), envContent);
|
|
@@ -674,8 +743,17 @@ coverage/
|
|
|
674
743
|
`;
|
|
675
744
|
await writeFile(path.join(projectPath, ".gitattributes"), gitattributesContent);
|
|
676
745
|
let indexContent;
|
|
746
|
+
const kataxImportSourceRoot = config.useKataxServiceManager && config.kataxMode === "instance"
|
|
747
|
+
? "./config/katax.instance.js"
|
|
748
|
+
: "katax-service-manager";
|
|
749
|
+
const kataxImportSourceShared = config.useKataxServiceManager && config.kataxMode === "instance"
|
|
750
|
+
? "../config/katax.instance.js"
|
|
751
|
+
: "katax-service-manager";
|
|
752
|
+
const kataxImportSourceApi = config.useKataxServiceManager && config.kataxMode === "instance"
|
|
753
|
+
? "../../config/katax.instance.js"
|
|
754
|
+
: "katax-service-manager";
|
|
677
755
|
if (config.useKataxServiceManager) {
|
|
678
|
-
const dbInitCode = config.database
|
|
756
|
+
const dbInitCode = config.database === "postgresql" || config.database === "mysql"
|
|
679
757
|
? `
|
|
680
758
|
// Initialize database
|
|
681
759
|
await katax.database({
|
|
@@ -690,7 +768,23 @@ coverage/
|
|
|
690
768
|
}
|
|
691
769
|
});
|
|
692
770
|
`
|
|
693
|
-
: ""
|
|
771
|
+
: config.database === "mongodb"
|
|
772
|
+
? `
|
|
773
|
+
// Initialize MongoDB
|
|
774
|
+
await katax.database({
|
|
775
|
+
name: 'main',
|
|
776
|
+
type: 'mongodb',
|
|
777
|
+
connection: {
|
|
778
|
+
host: katax.envRequired('DB_HOST'),
|
|
779
|
+
port: parseInt(katax.env('DB_PORT', '27017')),
|
|
780
|
+
database: katax.envRequired('DB_NAME'),
|
|
781
|
+
user: katax.env('DB_USER') || undefined,
|
|
782
|
+
password: katax.env('DB_PASSWORD') || undefined,
|
|
783
|
+
authSource: katax.env('DB_AUTH_SOURCE') || undefined,
|
|
784
|
+
}
|
|
785
|
+
});
|
|
786
|
+
`
|
|
787
|
+
: "";
|
|
694
788
|
const cacheInitCode = config.useRedis
|
|
695
789
|
? `
|
|
696
790
|
// Initialize Redis cache connection
|
|
@@ -706,6 +800,52 @@ coverage/
|
|
|
706
800
|
});
|
|
707
801
|
`
|
|
708
802
|
: "";
|
|
803
|
+
const registryInitCode = config.useRegistry && config.registryMode === "url"
|
|
804
|
+
? `
|
|
805
|
+
registry: {
|
|
806
|
+
url: katax.envRequired('REGISTRY_URL'),
|
|
807
|
+
apiKey: katax.env('REGISTRY_API_KEY') || undefined,
|
|
808
|
+
heartbeatInterval: parseInt(katax.env('REGISTRY_HEARTBEAT_MS', '30000')),
|
|
809
|
+
requestTimeoutMs: parseInt(katax.env('REGISTRY_TIMEOUT_MS', '5000')),
|
|
810
|
+
retryAttempts: parseInt(katax.env('REGISTRY_RETRY_ATTEMPTS', '2')),
|
|
811
|
+
retryBaseDelayMs: parseInt(katax.env('REGISTRY_RETRY_BASE_DELAY_MS', '300')),
|
|
812
|
+
},`
|
|
813
|
+
: config.useRegistry && config.registryMode === "handler"
|
|
814
|
+
? `
|
|
815
|
+
registry: {
|
|
816
|
+
handler: {
|
|
817
|
+
register: async (serviceInfo) => {
|
|
818
|
+
katax.logger.info({ message: 'Registry register callback', serviceInfo });
|
|
819
|
+
},
|
|
820
|
+
heartbeat: async (serviceInfo) => {
|
|
821
|
+
katax.logger.debug({ message: 'Registry heartbeat callback', serviceInfo });
|
|
822
|
+
},
|
|
823
|
+
unregister: async (payload) => {
|
|
824
|
+
katax.logger.info({ message: 'Registry unregister callback', payload });
|
|
825
|
+
},
|
|
826
|
+
},
|
|
827
|
+
},`
|
|
828
|
+
: "";
|
|
829
|
+
const hooksInitCode = config.useLifecycleHooks
|
|
830
|
+
? `
|
|
831
|
+
hooks: {
|
|
832
|
+
beforeInit: async () => {
|
|
833
|
+
console.log('Katax beforeInit hook');
|
|
834
|
+
},
|
|
835
|
+
afterInit: async () => {
|
|
836
|
+
katax.logger.info({ message: 'Katax afterInit hook' });
|
|
837
|
+
},
|
|
838
|
+
beforeShutdown: async () => {
|
|
839
|
+
katax.logger.info({ message: 'Katax beforeShutdown hook' });
|
|
840
|
+
},
|
|
841
|
+
afterShutdown: async () => {
|
|
842
|
+
console.log('Katax afterShutdown hook');
|
|
843
|
+
},
|
|
844
|
+
onError: async (err) => {
|
|
845
|
+
console.error('Katax lifecycle error:', err);
|
|
846
|
+
},
|
|
847
|
+
},`
|
|
848
|
+
: "";
|
|
709
849
|
let socketInitCode = "";
|
|
710
850
|
let httpImport = "";
|
|
711
851
|
let serverSetup = "";
|
|
@@ -716,8 +856,7 @@ coverage/
|
|
|
716
856
|
// Initialize WebSocket (separate port)
|
|
717
857
|
await katax.socket({
|
|
718
858
|
name: 'main',
|
|
719
|
-
port: ${config.socketPort}
|
|
720
|
-
cors: { origin: '*' }
|
|
859
|
+
port: ${config.socketPort}
|
|
721
860
|
});
|
|
722
861
|
`;
|
|
723
862
|
listenCode = ` const PORT = katax.env('PORT', '${config.port}');
|
|
@@ -738,8 +877,7 @@ coverage/
|
|
|
738
877
|
// Initialize WebSocket (same port as Express)
|
|
739
878
|
await katax.socket({
|
|
740
879
|
name: 'main',
|
|
741
|
-
httpServer
|
|
742
|
-
cors: { origin: '*' }
|
|
880
|
+
httpServer
|
|
743
881
|
});
|
|
744
882
|
`;
|
|
745
883
|
listenCode = ` httpServer.listen(PORT, () => {
|
|
@@ -758,29 +896,46 @@ coverage/
|
|
|
758
896
|
katax.logger.info({ message: \`Health check: http://localhost:\${PORT}/api/health\` });
|
|
759
897
|
});`;
|
|
760
898
|
}
|
|
761
|
-
indexContent = `import { katax } from '
|
|
899
|
+
indexContent = `import { katax } from '${kataxImportSourceRoot}';
|
|
762
900
|
import app from './app.js';${httpImport}
|
|
763
901
|
import dotenv from 'dotenv';
|
|
764
902
|
|
|
765
903
|
dotenv.config();
|
|
766
904
|
|
|
767
905
|
// Initialize katax and start server
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
906
|
+
async function bootstrap(): Promise<void> {
|
|
907
|
+
try {
|
|
908
|
+
await katax.init({
|
|
909
|
+
logger: {
|
|
910
|
+
level: katax.env('LOG_LEVEL', 'info') as 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal',
|
|
911
|
+
prettyPrint: katax.isDev,
|
|
912
|
+
},${registryInitCode}${hooksInitCode}
|
|
913
|
+
});
|
|
914
|
+
|
|
774
915
|
${dbInitCode}${cacheInitCode}${serverSetup}${socketInitCode}
|
|
775
916
|
${listenCode}
|
|
776
917
|
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
918
|
+
const shutdown = async (signal: string): Promise<void> => {
|
|
919
|
+
katax.logger.info({ message: signal + ' received, shutting down...' });
|
|
920
|
+
await katax.shutdown();
|
|
921
|
+
process.exit(0);
|
|
922
|
+
};
|
|
923
|
+
|
|
924
|
+
// Graceful shutdown
|
|
925
|
+
process.on('SIGTERM', () => {
|
|
926
|
+
void shutdown('SIGTERM');
|
|
927
|
+
});
|
|
928
|
+
|
|
929
|
+
process.on('SIGINT', () => {
|
|
930
|
+
void shutdown('SIGINT');
|
|
931
|
+
});
|
|
932
|
+
} catch (err) {
|
|
933
|
+
console.error('Failed to start application:', err);
|
|
934
|
+
process.exit(1);
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
void bootstrap();
|
|
784
939
|
`;
|
|
785
940
|
}
|
|
786
941
|
else {
|
|
@@ -804,6 +959,13 @@ app.listen(PORT, () => {
|
|
|
804
959
|
`;
|
|
805
960
|
}
|
|
806
961
|
await writeFile(path.join(projectPath, "src/index.ts"), indexContent);
|
|
962
|
+
if (config.useKataxServiceManager && config.kataxMode === "instance") {
|
|
963
|
+
const kataxInstanceContent = `import { Katax } from 'katax-service-manager';
|
|
964
|
+
|
|
965
|
+
export const katax = new Katax();
|
|
966
|
+
`;
|
|
967
|
+
await writeFile(path.join(projectPath, "src/config/katax.instance.ts"), kataxInstanceContent);
|
|
968
|
+
}
|
|
807
969
|
const appContent = `import express from 'express';
|
|
808
970
|
import cors from 'cors';
|
|
809
971
|
import router from './api/routes.js';
|
|
@@ -1151,7 +1313,7 @@ export function requireRole(...roles: string[]) {
|
|
|
1151
1313
|
}
|
|
1152
1314
|
let loggerUtilsContent;
|
|
1153
1315
|
if (config.useKataxServiceManager) {
|
|
1154
|
-
loggerUtilsContent = `import { katax } from '
|
|
1316
|
+
loggerUtilsContent = `import { katax } from '${kataxImportSourceShared}';
|
|
1155
1317
|
|
|
1156
1318
|
/**
|
|
1157
1319
|
* Lazy logger proxy - forwards calls to katax.logger after init()
|
|
@@ -1360,7 +1522,7 @@ ${config.database !== "none" ? ` // Database variables\n required.DATABASE_URL
|
|
|
1360
1522
|
`;
|
|
1361
1523
|
await writeFile(path.join(projectPath, "src/config/env.validator.ts"), envValidatorContent);
|
|
1362
1524
|
if (config.swagger) {
|
|
1363
|
-
await writeFile(path.join(projectPath, "src/config/swagger.config.ts"), generateSwaggerSetup());
|
|
1525
|
+
await writeFile(path.join(projectPath, "src/config/swagger.config.ts"), generateSwaggerSetup(String(config.port)));
|
|
1364
1526
|
const initialOpenAPISpec = {
|
|
1365
1527
|
openapi: "3.0.0",
|
|
1366
1528
|
info: {
|
|
@@ -1430,7 +1592,45 @@ ${config.database !== "none" ? ` // Database variables\n required.DATABASE_URL
|
|
|
1430
1592
|
};
|
|
1431
1593
|
await writeFile(path.join(projectPath, "src/openapi.json"), JSON.stringify(initialOpenAPISpec, null, 2));
|
|
1432
1594
|
}
|
|
1433
|
-
const healthHandlerContent =
|
|
1595
|
+
const healthHandlerContent = config.useKataxServiceManager
|
|
1596
|
+
? `import { Request, Response } from 'express';
|
|
1597
|
+
import { katax } from '${kataxImportSourceApi}';
|
|
1598
|
+
|
|
1599
|
+
/**
|
|
1600
|
+
* Health check endpoint handler
|
|
1601
|
+
* Returns Katax service status and app metadata
|
|
1602
|
+
*/
|
|
1603
|
+
export async function healthCheckHandler(req: Request, res: Response): Promise<void> {
|
|
1604
|
+
try {
|
|
1605
|
+
const health = await katax.healthCheck();
|
|
1606
|
+
|
|
1607
|
+
const statusCode =
|
|
1608
|
+
health.status === 'healthy'
|
|
1609
|
+
? 200
|
|
1610
|
+
: health.status === 'degraded'
|
|
1611
|
+
? 503
|
|
1612
|
+
: 500;
|
|
1613
|
+
|
|
1614
|
+
res.status(statusCode).json({
|
|
1615
|
+
...health,
|
|
1616
|
+
environment: katax.nodeEnv,
|
|
1617
|
+
app: {
|
|
1618
|
+
name: katax.appName,
|
|
1619
|
+
version: katax.version,
|
|
1620
|
+
registered: katax.isRegistered,
|
|
1621
|
+
},
|
|
1622
|
+
});
|
|
1623
|
+
} catch (err) {
|
|
1624
|
+
res.status(500).json({
|
|
1625
|
+
status: 'unhealthy',
|
|
1626
|
+
message: 'Failed to evaluate health status',
|
|
1627
|
+
error: err instanceof Error ? err.message : 'Unknown error',
|
|
1628
|
+
timestamp: Date.now(),
|
|
1629
|
+
});
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
`
|
|
1633
|
+
: `import { Request, Response } from 'express';
|
|
1434
1634
|
import os from 'os';
|
|
1435
1635
|
|
|
1436
1636
|
/**
|