@geekmidas/cli 0.2.2 → 0.2.4
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/{CronGenerator-DXRfHQcV.mjs → CronGenerator-Bh26MaNA.mjs} +2 -1
- package/dist/CronGenerator-Bh26MaNA.mjs.map +1 -0
- package/dist/{CronGenerator-1PflEYe2.cjs → CronGenerator-C6MF8rlG.cjs} +2 -1
- package/dist/CronGenerator-C6MF8rlG.cjs.map +1 -0
- package/dist/{EndpointGenerator-BbGrDiCP.cjs → EndpointGenerator-C73wNoih.cjs} +12 -5
- package/dist/EndpointGenerator-C73wNoih.cjs.map +1 -0
- package/dist/{EndpointGenerator-BmZ9BxbO.mjs → EndpointGenerator-CWh18d92.mjs} +12 -5
- package/dist/EndpointGenerator-CWh18d92.mjs.map +1 -0
- package/dist/{FunctionGenerator-DOEB_yPh.mjs → FunctionGenerator-BNE_GC7N.mjs} +2 -1
- package/dist/FunctionGenerator-BNE_GC7N.mjs.map +1 -0
- package/dist/{FunctionGenerator-Clw64SwQ.cjs → FunctionGenerator-FgZUTd8L.cjs} +2 -1
- package/dist/FunctionGenerator-FgZUTd8L.cjs.map +1 -0
- package/dist/{SubscriberGenerator-CB-NHtZW.cjs → SubscriberGenerator-Bd-a7aiw.cjs} +2 -1
- package/dist/SubscriberGenerator-Bd-a7aiw.cjs.map +1 -0
- package/dist/{SubscriberGenerator-Cuu4co3-.mjs → SubscriberGenerator-Dnlj_1FK.mjs} +2 -1
- package/dist/SubscriberGenerator-Dnlj_1FK.mjs.map +1 -0
- package/dist/build/index.cjs +5 -5
- package/dist/build/index.mjs +5 -5
- package/dist/{build-Ajg356_5.cjs → build-BVng9MQX.cjs} +5 -5
- package/dist/{build-Ajg356_5.cjs.map → build-BVng9MQX.cjs.map} +1 -1
- package/dist/{build-zpABVsc0.mjs → build-BqexeI-W.mjs} +5 -5
- package/dist/{build-zpABVsc0.mjs.map → build-BqexeI-W.mjs.map} +1 -1
- package/dist/dev/index.cjs +13 -0
- package/dist/dev/index.mjs +11 -0
- package/dist/dev-DbtyToc7.cjs +259 -0
- package/dist/dev-DbtyToc7.cjs.map +1 -0
- package/dist/dev-DnGYXuMn.mjs +241 -0
- package/dist/dev-DnGYXuMn.mjs.map +1 -0
- package/dist/generators/CronGenerator.cjs +1 -1
- package/dist/generators/CronGenerator.mjs +1 -1
- package/dist/generators/EndpointGenerator.cjs +1 -1
- package/dist/generators/EndpointGenerator.mjs +1 -1
- package/dist/generators/FunctionGenerator.cjs +1 -1
- package/dist/generators/FunctionGenerator.mjs +1 -1
- package/dist/generators/SubscriberGenerator.cjs +1 -1
- package/dist/generators/SubscriberGenerator.mjs +1 -1
- package/dist/generators/index.cjs +4 -4
- package/dist/generators/index.mjs +4 -4
- package/dist/index.cjs +33 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +33 -12
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-BQx3_JbM.mjs → openapi-BTHbPrxS.mjs} +2 -2
- package/dist/{openapi-BQx3_JbM.mjs.map → openapi-BTHbPrxS.mjs.map} +1 -1
- package/dist/{openapi-CMLr04cz.cjs → openapi-CewcfoRH.cjs} +2 -2
- package/dist/{openapi-CMLr04cz.cjs.map → openapi-CewcfoRH.cjs.map} +1 -1
- package/dist/{openapi-react-query-Dvjqx_Eo.cjs → openapi-react-query-D9Z7lh0p.cjs} +1 -1
- package/dist/{openapi-react-query-Dvjqx_Eo.cjs.map → openapi-react-query-D9Z7lh0p.cjs.map} +1 -1
- package/dist/{openapi-react-query-DbrWwQzb.mjs → openapi-react-query-MEBlYIM1.mjs} +1 -1
- package/dist/{openapi-react-query-DbrWwQzb.mjs.map → openapi-react-query-MEBlYIM1.mjs.map} +1 -1
- package/dist/openapi-react-query.cjs +1 -1
- package/dist/openapi-react-query.mjs +1 -1
- package/dist/openapi.cjs +2 -2
- package/dist/openapi.mjs +2 -2
- package/package.json +12 -6
- package/src/dev/__tests__/index.spec.ts +208 -0
- package/src/dev/index.ts +377 -0
- package/src/generators/CronGenerator.ts +8 -3
- package/src/generators/EndpointGenerator.ts +94 -6
- package/src/generators/FunctionGenerator.ts +21 -3
- package/src/generators/SubscriberGenerator.ts +1 -0
- package/src/generators/__tests__/SubscriberGenerator.spec.ts +12 -9
- package/src/index.ts +27 -0
- package/src/types.ts +3 -0
- package/dist/CronGenerator-1PflEYe2.cjs.map +0 -1
- package/dist/CronGenerator-DXRfHQcV.mjs.map +0 -1
- package/dist/EndpointGenerator-BbGrDiCP.cjs.map +0 -1
- package/dist/EndpointGenerator-BmZ9BxbO.mjs.map +0 -1
- package/dist/FunctionGenerator-Clw64SwQ.cjs.map +0 -1
- package/dist/FunctionGenerator-DOEB_yPh.mjs.map +0 -1
- package/dist/SubscriberGenerator-CB-NHtZW.cjs.map +0 -1
- package/dist/SubscriberGenerator-Cuu4co3-.mjs.map +0 -1
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
+
const require_config = require('./config-D1EpSGk6.cjs');
|
|
3
|
+
const require_CronGenerator = require('./CronGenerator-C6MF8rlG.cjs');
|
|
4
|
+
const require_EndpointGenerator = require('./EndpointGenerator-C73wNoih.cjs');
|
|
5
|
+
const require_FunctionGenerator = require('./FunctionGenerator-FgZUTd8L.cjs');
|
|
6
|
+
const require_SubscriberGenerator = require('./SubscriberGenerator-Bd-a7aiw.cjs');
|
|
7
|
+
const require_providerResolver = require('./providerResolver-DgvzNfP4.cjs');
|
|
8
|
+
const node_fs_promises = require_chunk.__toESM(require("node:fs/promises"));
|
|
9
|
+
const node_path = require_chunk.__toESM(require("node:path"));
|
|
10
|
+
const node_child_process = require_chunk.__toESM(require("node:child_process"));
|
|
11
|
+
const node_net = require_chunk.__toESM(require("node:net"));
|
|
12
|
+
const chokidar = require_chunk.__toESM(require("chokidar"));
|
|
13
|
+
|
|
14
|
+
//#region src/dev/index.ts
|
|
15
|
+
const logger = console;
|
|
16
|
+
/**
|
|
17
|
+
* Check if a port is available
|
|
18
|
+
* @internal Exported for testing
|
|
19
|
+
*/
|
|
20
|
+
async function isPortAvailable(port) {
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
const server = (0, node_net.createServer)();
|
|
23
|
+
server.once("error", (err) => {
|
|
24
|
+
if (err.code === "EADDRINUSE") resolve(false);
|
|
25
|
+
else resolve(false);
|
|
26
|
+
});
|
|
27
|
+
server.once("listening", () => {
|
|
28
|
+
server.close();
|
|
29
|
+
resolve(true);
|
|
30
|
+
});
|
|
31
|
+
server.listen(port);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Find an available port starting from the preferred port
|
|
36
|
+
* @internal Exported for testing
|
|
37
|
+
*/
|
|
38
|
+
async function findAvailablePort(preferredPort, maxAttempts = 10) {
|
|
39
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
40
|
+
const port = preferredPort + i;
|
|
41
|
+
if (await isPortAvailable(port)) return port;
|
|
42
|
+
logger.log(`⚠️ Port ${port} is in use, trying ${port + 1}...`);
|
|
43
|
+
}
|
|
44
|
+
throw new Error(`Could not find an available port after trying ${maxAttempts} ports starting from ${preferredPort}`);
|
|
45
|
+
}
|
|
46
|
+
async function devCommand(options) {
|
|
47
|
+
const config = await require_config.loadConfig();
|
|
48
|
+
const resolved = require_providerResolver.resolveProviders(config, { provider: "server" });
|
|
49
|
+
logger.log("🚀 Starting development server...");
|
|
50
|
+
logger.log(`Loading routes from: ${config.routes}`);
|
|
51
|
+
if (config.functions) logger.log(`Loading functions from: ${config.functions}`);
|
|
52
|
+
if (config.crons) logger.log(`Loading crons from: ${config.crons}`);
|
|
53
|
+
if (config.subscribers) logger.log(`Loading subscribers from: ${config.subscribers}`);
|
|
54
|
+
logger.log(`Using envParser: ${config.envParser}`);
|
|
55
|
+
const [envParserPath, envParserName] = config.envParser.split("#");
|
|
56
|
+
const envParserImportPattern = !envParserName ? "envParser" : envParserName === "envParser" ? "{ envParser }" : `{ ${envParserName} as envParser }`;
|
|
57
|
+
const [loggerPath, loggerName] = config.logger.split("#");
|
|
58
|
+
const loggerImportPattern = !loggerName ? "logger" : loggerName === "logger" ? "{ logger }" : `{ ${loggerName} as logger }`;
|
|
59
|
+
const buildContext = {
|
|
60
|
+
envParserPath,
|
|
61
|
+
envParserImportPattern,
|
|
62
|
+
loggerPath,
|
|
63
|
+
loggerImportPattern
|
|
64
|
+
};
|
|
65
|
+
await buildServer(config, buildContext, resolved.providers[0], resolved.enableOpenApi);
|
|
66
|
+
const devServer = new DevServer(resolved.providers[0], options.port || 3e3, resolved.enableOpenApi);
|
|
67
|
+
await devServer.start();
|
|
68
|
+
const watchPatterns = [
|
|
69
|
+
config.routes,
|
|
70
|
+
...config.functions ? [config.functions] : [],
|
|
71
|
+
...config.crons ? [config.crons] : [],
|
|
72
|
+
...config.subscribers ? [config.subscribers] : [],
|
|
73
|
+
config.envParser.split("#")[0],
|
|
74
|
+
config.logger.split("#")[0]
|
|
75
|
+
].flat();
|
|
76
|
+
logger.log(`👀 Watching for changes in: ${watchPatterns.join(", ")}`);
|
|
77
|
+
const watcher = chokidar.default.watch(watchPatterns, {
|
|
78
|
+
ignored: /(^|[\/\\])\../,
|
|
79
|
+
persistent: true,
|
|
80
|
+
ignoreInitial: true
|
|
81
|
+
});
|
|
82
|
+
let rebuildTimeout = null;
|
|
83
|
+
watcher.on("change", async (path) => {
|
|
84
|
+
logger.log(`📝 File changed: ${path}`);
|
|
85
|
+
if (rebuildTimeout) clearTimeout(rebuildTimeout);
|
|
86
|
+
rebuildTimeout = setTimeout(async () => {
|
|
87
|
+
try {
|
|
88
|
+
logger.log("🔄 Rebuilding...");
|
|
89
|
+
await buildServer(config, buildContext, resolved.providers[0], resolved.enableOpenApi);
|
|
90
|
+
logger.log("✅ Rebuild complete, restarting server...");
|
|
91
|
+
await devServer.restart();
|
|
92
|
+
} catch (error) {
|
|
93
|
+
logger.error("❌ Rebuild failed:", error.message);
|
|
94
|
+
}
|
|
95
|
+
}, 300);
|
|
96
|
+
});
|
|
97
|
+
const shutdown = async () => {
|
|
98
|
+
logger.log("\n🛑 Shutting down...");
|
|
99
|
+
await watcher.close();
|
|
100
|
+
await devServer.stop();
|
|
101
|
+
process.exit(0);
|
|
102
|
+
};
|
|
103
|
+
process.on("SIGINT", shutdown);
|
|
104
|
+
process.on("SIGTERM", shutdown);
|
|
105
|
+
}
|
|
106
|
+
async function buildServer(config, context, provider, enableOpenApi) {
|
|
107
|
+
const endpointGenerator = new require_EndpointGenerator.EndpointGenerator();
|
|
108
|
+
const functionGenerator = new require_FunctionGenerator.FunctionGenerator();
|
|
109
|
+
const cronGenerator = new require_CronGenerator.CronGenerator();
|
|
110
|
+
const subscriberGenerator = new require_SubscriberGenerator.SubscriberGenerator();
|
|
111
|
+
const [allEndpoints, allFunctions, allCrons, allSubscribers] = await Promise.all([
|
|
112
|
+
endpointGenerator.load(config.routes),
|
|
113
|
+
config.functions ? functionGenerator.load(config.functions) : [],
|
|
114
|
+
config.crons ? cronGenerator.load(config.crons) : [],
|
|
115
|
+
config.subscribers ? subscriberGenerator.load(config.subscribers) : []
|
|
116
|
+
]);
|
|
117
|
+
const outputDir = (0, node_path.join)(process.cwd(), ".gkm", provider);
|
|
118
|
+
await (0, node_fs_promises.mkdir)(outputDir, { recursive: true });
|
|
119
|
+
await Promise.all([
|
|
120
|
+
endpointGenerator.build(context, allEndpoints, outputDir, {
|
|
121
|
+
provider,
|
|
122
|
+
enableOpenApi
|
|
123
|
+
}),
|
|
124
|
+
functionGenerator.build(context, allFunctions, outputDir, { provider }),
|
|
125
|
+
cronGenerator.build(context, allCrons, outputDir, { provider }),
|
|
126
|
+
subscriberGenerator.build(context, allSubscribers, outputDir, { provider })
|
|
127
|
+
]);
|
|
128
|
+
}
|
|
129
|
+
var DevServer = class {
|
|
130
|
+
serverProcess = null;
|
|
131
|
+
isRunning = false;
|
|
132
|
+
actualPort;
|
|
133
|
+
constructor(provider, requestedPort, enableOpenApi) {
|
|
134
|
+
this.provider = provider;
|
|
135
|
+
this.requestedPort = requestedPort;
|
|
136
|
+
this.enableOpenApi = enableOpenApi;
|
|
137
|
+
this.actualPort = requestedPort;
|
|
138
|
+
}
|
|
139
|
+
async start() {
|
|
140
|
+
if (this.isRunning) await this.stop();
|
|
141
|
+
this.actualPort = await findAvailablePort(this.requestedPort);
|
|
142
|
+
if (this.actualPort !== this.requestedPort) logger.log(`ℹ️ Port ${this.requestedPort} was in use, using port ${this.actualPort} instead`);
|
|
143
|
+
const serverEntryPath = (0, node_path.join)(process.cwd(), ".gkm", this.provider, "server.ts");
|
|
144
|
+
await this.createServerEntry();
|
|
145
|
+
logger.log(`\n✨ Starting server on port ${this.actualPort}...`);
|
|
146
|
+
this.serverProcess = (0, node_child_process.spawn)("npx", [
|
|
147
|
+
"tsx",
|
|
148
|
+
serverEntryPath,
|
|
149
|
+
"--port",
|
|
150
|
+
this.actualPort.toString()
|
|
151
|
+
], {
|
|
152
|
+
stdio: "inherit",
|
|
153
|
+
env: {
|
|
154
|
+
...process.env,
|
|
155
|
+
NODE_ENV: "development"
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
this.isRunning = true;
|
|
159
|
+
this.serverProcess.on("error", (error) => {
|
|
160
|
+
logger.error("❌ Server error:", error);
|
|
161
|
+
});
|
|
162
|
+
this.serverProcess.on("exit", (code, signal) => {
|
|
163
|
+
if (code !== null && code !== 0 && signal !== "SIGTERM") logger.error(`❌ Server exited with code ${code}`);
|
|
164
|
+
this.isRunning = false;
|
|
165
|
+
});
|
|
166
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
167
|
+
if (this.isRunning) {
|
|
168
|
+
logger.log(`\n🎉 Server running at http://localhost:${this.actualPort}`);
|
|
169
|
+
if (this.enableOpenApi) logger.log(`📚 API Docs available at http://localhost:${this.actualPort}/docs`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async stop() {
|
|
173
|
+
if (this.serverProcess && this.isRunning) {
|
|
174
|
+
this.serverProcess.kill("SIGTERM");
|
|
175
|
+
await new Promise((resolve) => {
|
|
176
|
+
const timeout = setTimeout(() => {
|
|
177
|
+
this.serverProcess?.kill("SIGKILL");
|
|
178
|
+
resolve();
|
|
179
|
+
}, 5e3);
|
|
180
|
+
this.serverProcess?.on("exit", () => {
|
|
181
|
+
clearTimeout(timeout);
|
|
182
|
+
resolve();
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
this.serverProcess = null;
|
|
186
|
+
this.isRunning = false;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
async restart() {
|
|
190
|
+
await this.stop();
|
|
191
|
+
await this.start();
|
|
192
|
+
}
|
|
193
|
+
async createServerEntry() {
|
|
194
|
+
const { writeFile } = await import("node:fs/promises");
|
|
195
|
+
const { relative, dirname } = await import("node:path");
|
|
196
|
+
const serverPath = (0, node_path.join)(process.cwd(), ".gkm", this.provider, "server.ts");
|
|
197
|
+
const relativeAppPath = relative(dirname(serverPath), (0, node_path.join)(dirname(serverPath), "app.js"));
|
|
198
|
+
const content = `#!/usr/bin/env node
|
|
199
|
+
/**
|
|
200
|
+
* Development server entry point
|
|
201
|
+
* This file is auto-generated by 'gkm dev'
|
|
202
|
+
*/
|
|
203
|
+
import { createApp } from './${relativeAppPath.startsWith(".") ? relativeAppPath : "./" + relativeAppPath}';
|
|
204
|
+
|
|
205
|
+
const port = process.argv.includes('--port')
|
|
206
|
+
? Number.parseInt(process.argv[process.argv.indexOf('--port') + 1])
|
|
207
|
+
: 3000;
|
|
208
|
+
|
|
209
|
+
const { app, start } = createApp(undefined, ${this.enableOpenApi});
|
|
210
|
+
|
|
211
|
+
// Start the server
|
|
212
|
+
start({
|
|
213
|
+
port,
|
|
214
|
+
serve: async (app, port) => {
|
|
215
|
+
// Detect runtime and use appropriate server
|
|
216
|
+
if (typeof Bun !== 'undefined') {
|
|
217
|
+
// Bun runtime
|
|
218
|
+
Bun.serve({
|
|
219
|
+
port,
|
|
220
|
+
fetch: app.fetch,
|
|
221
|
+
});
|
|
222
|
+
} else {
|
|
223
|
+
// Node.js runtime with @hono/node-server
|
|
224
|
+
const { serve } = await import('@hono/node-server');
|
|
225
|
+
serve({
|
|
226
|
+
fetch: app.fetch,
|
|
227
|
+
port,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
}).catch((error) => {
|
|
232
|
+
console.error('Failed to start server:', error);
|
|
233
|
+
process.exit(1);
|
|
234
|
+
});
|
|
235
|
+
`;
|
|
236
|
+
await writeFile(serverPath, content);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
//#endregion
|
|
241
|
+
Object.defineProperty(exports, 'devCommand', {
|
|
242
|
+
enumerable: true,
|
|
243
|
+
get: function () {
|
|
244
|
+
return devCommand;
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
Object.defineProperty(exports, 'findAvailablePort', {
|
|
248
|
+
enumerable: true,
|
|
249
|
+
get: function () {
|
|
250
|
+
return findAvailablePort;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
Object.defineProperty(exports, 'isPortAvailable', {
|
|
254
|
+
enumerable: true,
|
|
255
|
+
get: function () {
|
|
256
|
+
return isPortAvailable;
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
//# sourceMappingURL=dev-DbtyToc7.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-DbtyToc7.cjs","names":["port: number","err: NodeJS.ErrnoException","preferredPort: number","options: DevOptions","buildContext: BuildContext","rebuildTimeout: NodeJS.Timeout | null","config: any","context: BuildContext","provider: LegacyProvider","enableOpenApi: boolean","EndpointGenerator","FunctionGenerator","CronGenerator","SubscriberGenerator","requestedPort: number"],"sources":["../src/dev/index.ts"],"sourcesContent":["import { type ChildProcess, spawn } from 'node:child_process';\nimport { mkdir } from 'node:fs/promises';\nimport { createServer } from 'node:net';\nimport { join } from 'node:path';\nimport chokidar from 'chokidar';\nimport { resolveProviders } from '../build/providerResolver';\nimport type { BuildContext } from '../build/types';\nimport { loadConfig } from '../config';\nimport {\n CronGenerator,\n EndpointGenerator,\n FunctionGenerator,\n SubscriberGenerator,\n} from '../generators';\nimport type { LegacyProvider } from '../types';\n\nconst logger = console;\n\n/**\n * Check if a port is available\n * @internal Exported for testing\n */\nexport async function isPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = createServer();\n\n server.once('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n resolve(false);\n } else {\n resolve(false);\n }\n });\n\n server.once('listening', () => {\n server.close();\n resolve(true);\n });\n\n server.listen(port);\n });\n}\n\n/**\n * Find an available port starting from the preferred port\n * @internal Exported for testing\n */\nexport async function findAvailablePort(\n preferredPort: number,\n maxAttempts = 10,\n): Promise<number> {\n for (let i = 0; i < maxAttempts; i++) {\n const port = preferredPort + i;\n if (await isPortAvailable(port)) {\n return port;\n }\n logger.log(`⚠️ Port ${port} is in use, trying ${port + 1}...`);\n }\n\n throw new Error(\n `Could not find an available port after trying ${maxAttempts} ports starting from ${preferredPort}`,\n );\n}\n\nexport interface DevOptions {\n port?: number;\n enableOpenApi?: boolean;\n}\n\nexport async function devCommand(options: DevOptions): Promise<void> {\n const config = await loadConfig();\n\n // Force server provider for dev mode\n const resolved = resolveProviders(config, { provider: 'server' });\n\n logger.log('🚀 Starting development server...');\n logger.log(`Loading routes from: ${config.routes}`);\n if (config.functions) {\n logger.log(`Loading functions from: ${config.functions}`);\n }\n if (config.crons) {\n logger.log(`Loading crons from: ${config.crons}`);\n }\n if (config.subscribers) {\n logger.log(`Loading subscribers from: ${config.subscribers}`);\n }\n logger.log(`Using envParser: ${config.envParser}`);\n\n // Parse envParser configuration\n const [envParserPath, envParserName] = config.envParser.split('#');\n const envParserImportPattern = !envParserName\n ? 'envParser'\n : envParserName === 'envParser'\n ? '{ envParser }'\n : `{ ${envParserName} as envParser }`;\n\n // Parse logger configuration\n const [loggerPath, loggerName] = config.logger.split('#');\n const loggerImportPattern = !loggerName\n ? 'logger'\n : loggerName === 'logger'\n ? '{ logger }'\n : `{ ${loggerName} as logger }`;\n\n const buildContext: BuildContext = {\n envParserPath,\n envParserImportPattern,\n loggerPath,\n loggerImportPattern,\n };\n\n // Build initial version\n await buildServer(\n config,\n buildContext,\n resolved.providers[0] as LegacyProvider,\n resolved.enableOpenApi,\n );\n\n // Start the dev server\n const devServer = new DevServer(\n resolved.providers[0] as LegacyProvider,\n options.port || 3000,\n resolved.enableOpenApi,\n );\n\n await devServer.start();\n\n // Watch for file changes\n const watchPatterns = [\n config.routes,\n ...(config.functions ? [config.functions] : []),\n ...(config.crons ? [config.crons] : []),\n ...(config.subscribers ? [config.subscribers] : []),\n config.envParser.split('#')[0],\n config.logger.split('#')[0],\n ].flat();\n\n logger.log(`👀 Watching for changes in: ${watchPatterns.join(', ')}`);\n\n const watcher = chokidar.watch(watchPatterns, {\n ignored: /(^|[\\/\\\\])\\../, // ignore dotfiles\n persistent: true,\n ignoreInitial: true,\n });\n\n let rebuildTimeout: NodeJS.Timeout | null = null;\n\n watcher.on('change', async (path) => {\n logger.log(`📝 File changed: ${path}`);\n\n // Debounce rebuilds\n if (rebuildTimeout) {\n clearTimeout(rebuildTimeout);\n }\n\n rebuildTimeout = setTimeout(async () => {\n try {\n logger.log('🔄 Rebuilding...');\n await buildServer(\n config,\n buildContext,\n resolved.providers[0] as LegacyProvider,\n resolved.enableOpenApi,\n );\n logger.log('✅ Rebuild complete, restarting server...');\n await devServer.restart();\n } catch (error) {\n logger.error('❌ Rebuild failed:', (error as Error).message);\n }\n }, 300);\n });\n\n // Handle graceful shutdown\n const shutdown = async () => {\n logger.log('\\n🛑 Shutting down...');\n await watcher.close();\n await devServer.stop();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\nasync function buildServer(\n config: any,\n context: BuildContext,\n provider: LegacyProvider,\n enableOpenApi: boolean,\n): Promise<void> {\n // Initialize generators\n const endpointGenerator = new EndpointGenerator();\n const functionGenerator = new FunctionGenerator();\n const cronGenerator = new CronGenerator();\n const subscriberGenerator = new SubscriberGenerator();\n\n // Load all constructs\n const [allEndpoints, allFunctions, allCrons, allSubscribers] =\n await Promise.all([\n endpointGenerator.load(config.routes),\n config.functions ? functionGenerator.load(config.functions) : [],\n config.crons ? cronGenerator.load(config.crons) : [],\n config.subscribers ? subscriberGenerator.load(config.subscribers) : [],\n ]);\n\n // Ensure .gkm directory exists\n const outputDir = join(process.cwd(), '.gkm', provider);\n await mkdir(outputDir, { recursive: true });\n\n // Build for server provider\n await Promise.all([\n endpointGenerator.build(context, allEndpoints, outputDir, {\n provider,\n enableOpenApi,\n }),\n functionGenerator.build(context, allFunctions, outputDir, { provider }),\n cronGenerator.build(context, allCrons, outputDir, { provider }),\n subscriberGenerator.build(context, allSubscribers, outputDir, { provider }),\n ]);\n}\n\nclass DevServer {\n private serverProcess: ChildProcess | null = null;\n private isRunning = false;\n private actualPort: number;\n\n constructor(\n private provider: LegacyProvider,\n private requestedPort: number,\n private enableOpenApi: boolean,\n ) {\n this.actualPort = requestedPort;\n }\n\n async start(): Promise<void> {\n if (this.isRunning) {\n await this.stop();\n }\n\n // Find an available port\n this.actualPort = await findAvailablePort(this.requestedPort);\n\n if (this.actualPort !== this.requestedPort) {\n logger.log(\n `ℹ️ Port ${this.requestedPort} was in use, using port ${this.actualPort} instead`,\n );\n }\n\n const serverEntryPath = join(\n process.cwd(),\n '.gkm',\n this.provider,\n 'server.ts',\n );\n\n // Create server entry file\n await this.createServerEntry();\n\n logger.log(`\\n✨ Starting server on port ${this.actualPort}...`);\n\n // Start the server using tsx (TypeScript execution)\n this.serverProcess = spawn(\n 'npx',\n ['tsx', serverEntryPath, '--port', this.actualPort.toString()],\n {\n stdio: 'inherit',\n env: { ...process.env, NODE_ENV: 'development' },\n },\n );\n\n this.isRunning = true;\n\n this.serverProcess.on('error', (error) => {\n logger.error('❌ Server error:', error);\n });\n\n this.serverProcess.on('exit', (code, signal) => {\n if (code !== null && code !== 0 && signal !== 'SIGTERM') {\n logger.error(`❌ Server exited with code ${code}`);\n }\n this.isRunning = false;\n });\n\n // Give the server a moment to start\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n if (this.isRunning) {\n logger.log(`\\n🎉 Server running at http://localhost:${this.actualPort}`);\n if (this.enableOpenApi) {\n logger.log(\n `📚 API Docs available at http://localhost:${this.actualPort}/docs`,\n );\n }\n }\n }\n\n async stop(): Promise<void> {\n if (this.serverProcess && this.isRunning) {\n this.serverProcess.kill('SIGTERM');\n\n // Wait for process to exit\n await new Promise<void>((resolve) => {\n const timeout = setTimeout(() => {\n this.serverProcess?.kill('SIGKILL');\n resolve();\n }, 5000);\n\n this.serverProcess?.on('exit', () => {\n clearTimeout(timeout);\n resolve();\n });\n });\n\n this.serverProcess = null;\n this.isRunning = false;\n }\n }\n\n async restart(): Promise<void> {\n await this.stop();\n await this.start();\n }\n\n private async createServerEntry(): Promise<void> {\n const { writeFile } = await import('node:fs/promises');\n const { relative, dirname } = await import('node:path');\n\n const serverPath = join(process.cwd(), '.gkm', this.provider, 'server.ts');\n\n const relativeAppPath = relative(\n dirname(serverPath),\n join(dirname(serverPath), 'app.js'),\n );\n\n const content = `#!/usr/bin/env node\n/**\n * Development server entry point\n * This file is auto-generated by 'gkm dev'\n */\nimport { createApp } from './${relativeAppPath.startsWith('.') ? relativeAppPath : './' + relativeAppPath}';\n\nconst port = process.argv.includes('--port')\n ? Number.parseInt(process.argv[process.argv.indexOf('--port') + 1])\n : 3000;\n\nconst { app, start } = createApp(undefined, ${this.enableOpenApi});\n\n// Start the server\nstart({\n port,\n serve: async (app, port) => {\n // Detect runtime and use appropriate server\n if (typeof Bun !== 'undefined') {\n // Bun runtime\n Bun.serve({\n port,\n fetch: app.fetch,\n });\n } else {\n // Node.js runtime with @hono/node-server\n const { serve } = await import('@hono/node-server');\n serve({\n fetch: app.fetch,\n port,\n });\n }\n },\n}).catch((error) => {\n console.error('Failed to start server:', error);\n process.exit(1);\n});\n`;\n\n await writeFile(serverPath, content);\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { loadConfig } from "./config-U-mdW-7Y.mjs";
|
|
2
|
+
import { CronGenerator } from "./CronGenerator-Bh26MaNA.mjs";
|
|
3
|
+
import { EndpointGenerator } from "./EndpointGenerator-CWh18d92.mjs";
|
|
4
|
+
import { FunctionGenerator } from "./FunctionGenerator-BNE_GC7N.mjs";
|
|
5
|
+
import { SubscriberGenerator } from "./SubscriberGenerator-Dnlj_1FK.mjs";
|
|
6
|
+
import { resolveProviders } from "./providerResolver-B_TjNF0_.mjs";
|
|
7
|
+
import { mkdir } from "node:fs/promises";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { spawn } from "node:child_process";
|
|
10
|
+
import { createServer } from "node:net";
|
|
11
|
+
import chokidar from "chokidar";
|
|
12
|
+
|
|
13
|
+
//#region src/dev/index.ts
|
|
14
|
+
const logger = console;
|
|
15
|
+
/**
|
|
16
|
+
* Check if a port is available
|
|
17
|
+
* @internal Exported for testing
|
|
18
|
+
*/
|
|
19
|
+
async function isPortAvailable(port) {
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
const server = createServer();
|
|
22
|
+
server.once("error", (err) => {
|
|
23
|
+
if (err.code === "EADDRINUSE") resolve(false);
|
|
24
|
+
else resolve(false);
|
|
25
|
+
});
|
|
26
|
+
server.once("listening", () => {
|
|
27
|
+
server.close();
|
|
28
|
+
resolve(true);
|
|
29
|
+
});
|
|
30
|
+
server.listen(port);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Find an available port starting from the preferred port
|
|
35
|
+
* @internal Exported for testing
|
|
36
|
+
*/
|
|
37
|
+
async function findAvailablePort(preferredPort, maxAttempts = 10) {
|
|
38
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
39
|
+
const port = preferredPort + i;
|
|
40
|
+
if (await isPortAvailable(port)) return port;
|
|
41
|
+
logger.log(`⚠️ Port ${port} is in use, trying ${port + 1}...`);
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`Could not find an available port after trying ${maxAttempts} ports starting from ${preferredPort}`);
|
|
44
|
+
}
|
|
45
|
+
async function devCommand(options) {
|
|
46
|
+
const config = await loadConfig();
|
|
47
|
+
const resolved = resolveProviders(config, { provider: "server" });
|
|
48
|
+
logger.log("🚀 Starting development server...");
|
|
49
|
+
logger.log(`Loading routes from: ${config.routes}`);
|
|
50
|
+
if (config.functions) logger.log(`Loading functions from: ${config.functions}`);
|
|
51
|
+
if (config.crons) logger.log(`Loading crons from: ${config.crons}`);
|
|
52
|
+
if (config.subscribers) logger.log(`Loading subscribers from: ${config.subscribers}`);
|
|
53
|
+
logger.log(`Using envParser: ${config.envParser}`);
|
|
54
|
+
const [envParserPath, envParserName] = config.envParser.split("#");
|
|
55
|
+
const envParserImportPattern = !envParserName ? "envParser" : envParserName === "envParser" ? "{ envParser }" : `{ ${envParserName} as envParser }`;
|
|
56
|
+
const [loggerPath, loggerName] = config.logger.split("#");
|
|
57
|
+
const loggerImportPattern = !loggerName ? "logger" : loggerName === "logger" ? "{ logger }" : `{ ${loggerName} as logger }`;
|
|
58
|
+
const buildContext = {
|
|
59
|
+
envParserPath,
|
|
60
|
+
envParserImportPattern,
|
|
61
|
+
loggerPath,
|
|
62
|
+
loggerImportPattern
|
|
63
|
+
};
|
|
64
|
+
await buildServer(config, buildContext, resolved.providers[0], resolved.enableOpenApi);
|
|
65
|
+
const devServer = new DevServer(resolved.providers[0], options.port || 3e3, resolved.enableOpenApi);
|
|
66
|
+
await devServer.start();
|
|
67
|
+
const watchPatterns = [
|
|
68
|
+
config.routes,
|
|
69
|
+
...config.functions ? [config.functions] : [],
|
|
70
|
+
...config.crons ? [config.crons] : [],
|
|
71
|
+
...config.subscribers ? [config.subscribers] : [],
|
|
72
|
+
config.envParser.split("#")[0],
|
|
73
|
+
config.logger.split("#")[0]
|
|
74
|
+
].flat();
|
|
75
|
+
logger.log(`👀 Watching for changes in: ${watchPatterns.join(", ")}`);
|
|
76
|
+
const watcher = chokidar.watch(watchPatterns, {
|
|
77
|
+
ignored: /(^|[\/\\])\../,
|
|
78
|
+
persistent: true,
|
|
79
|
+
ignoreInitial: true
|
|
80
|
+
});
|
|
81
|
+
let rebuildTimeout = null;
|
|
82
|
+
watcher.on("change", async (path) => {
|
|
83
|
+
logger.log(`📝 File changed: ${path}`);
|
|
84
|
+
if (rebuildTimeout) clearTimeout(rebuildTimeout);
|
|
85
|
+
rebuildTimeout = setTimeout(async () => {
|
|
86
|
+
try {
|
|
87
|
+
logger.log("🔄 Rebuilding...");
|
|
88
|
+
await buildServer(config, buildContext, resolved.providers[0], resolved.enableOpenApi);
|
|
89
|
+
logger.log("✅ Rebuild complete, restarting server...");
|
|
90
|
+
await devServer.restart();
|
|
91
|
+
} catch (error) {
|
|
92
|
+
logger.error("❌ Rebuild failed:", error.message);
|
|
93
|
+
}
|
|
94
|
+
}, 300);
|
|
95
|
+
});
|
|
96
|
+
const shutdown = async () => {
|
|
97
|
+
logger.log("\n🛑 Shutting down...");
|
|
98
|
+
await watcher.close();
|
|
99
|
+
await devServer.stop();
|
|
100
|
+
process.exit(0);
|
|
101
|
+
};
|
|
102
|
+
process.on("SIGINT", shutdown);
|
|
103
|
+
process.on("SIGTERM", shutdown);
|
|
104
|
+
}
|
|
105
|
+
async function buildServer(config, context, provider, enableOpenApi) {
|
|
106
|
+
const endpointGenerator = new EndpointGenerator();
|
|
107
|
+
const functionGenerator = new FunctionGenerator();
|
|
108
|
+
const cronGenerator = new CronGenerator();
|
|
109
|
+
const subscriberGenerator = new SubscriberGenerator();
|
|
110
|
+
const [allEndpoints, allFunctions, allCrons, allSubscribers] = await Promise.all([
|
|
111
|
+
endpointGenerator.load(config.routes),
|
|
112
|
+
config.functions ? functionGenerator.load(config.functions) : [],
|
|
113
|
+
config.crons ? cronGenerator.load(config.crons) : [],
|
|
114
|
+
config.subscribers ? subscriberGenerator.load(config.subscribers) : []
|
|
115
|
+
]);
|
|
116
|
+
const outputDir = join(process.cwd(), ".gkm", provider);
|
|
117
|
+
await mkdir(outputDir, { recursive: true });
|
|
118
|
+
await Promise.all([
|
|
119
|
+
endpointGenerator.build(context, allEndpoints, outputDir, {
|
|
120
|
+
provider,
|
|
121
|
+
enableOpenApi
|
|
122
|
+
}),
|
|
123
|
+
functionGenerator.build(context, allFunctions, outputDir, { provider }),
|
|
124
|
+
cronGenerator.build(context, allCrons, outputDir, { provider }),
|
|
125
|
+
subscriberGenerator.build(context, allSubscribers, outputDir, { provider })
|
|
126
|
+
]);
|
|
127
|
+
}
|
|
128
|
+
var DevServer = class {
|
|
129
|
+
serverProcess = null;
|
|
130
|
+
isRunning = false;
|
|
131
|
+
actualPort;
|
|
132
|
+
constructor(provider, requestedPort, enableOpenApi) {
|
|
133
|
+
this.provider = provider;
|
|
134
|
+
this.requestedPort = requestedPort;
|
|
135
|
+
this.enableOpenApi = enableOpenApi;
|
|
136
|
+
this.actualPort = requestedPort;
|
|
137
|
+
}
|
|
138
|
+
async start() {
|
|
139
|
+
if (this.isRunning) await this.stop();
|
|
140
|
+
this.actualPort = await findAvailablePort(this.requestedPort);
|
|
141
|
+
if (this.actualPort !== this.requestedPort) logger.log(`ℹ️ Port ${this.requestedPort} was in use, using port ${this.actualPort} instead`);
|
|
142
|
+
const serverEntryPath = join(process.cwd(), ".gkm", this.provider, "server.ts");
|
|
143
|
+
await this.createServerEntry();
|
|
144
|
+
logger.log(`\n✨ Starting server on port ${this.actualPort}...`);
|
|
145
|
+
this.serverProcess = spawn("npx", [
|
|
146
|
+
"tsx",
|
|
147
|
+
serverEntryPath,
|
|
148
|
+
"--port",
|
|
149
|
+
this.actualPort.toString()
|
|
150
|
+
], {
|
|
151
|
+
stdio: "inherit",
|
|
152
|
+
env: {
|
|
153
|
+
...process.env,
|
|
154
|
+
NODE_ENV: "development"
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
this.isRunning = true;
|
|
158
|
+
this.serverProcess.on("error", (error) => {
|
|
159
|
+
logger.error("❌ Server error:", error);
|
|
160
|
+
});
|
|
161
|
+
this.serverProcess.on("exit", (code, signal) => {
|
|
162
|
+
if (code !== null && code !== 0 && signal !== "SIGTERM") logger.error(`❌ Server exited with code ${code}`);
|
|
163
|
+
this.isRunning = false;
|
|
164
|
+
});
|
|
165
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
166
|
+
if (this.isRunning) {
|
|
167
|
+
logger.log(`\n🎉 Server running at http://localhost:${this.actualPort}`);
|
|
168
|
+
if (this.enableOpenApi) logger.log(`📚 API Docs available at http://localhost:${this.actualPort}/docs`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async stop() {
|
|
172
|
+
if (this.serverProcess && this.isRunning) {
|
|
173
|
+
this.serverProcess.kill("SIGTERM");
|
|
174
|
+
await new Promise((resolve) => {
|
|
175
|
+
const timeout = setTimeout(() => {
|
|
176
|
+
this.serverProcess?.kill("SIGKILL");
|
|
177
|
+
resolve();
|
|
178
|
+
}, 5e3);
|
|
179
|
+
this.serverProcess?.on("exit", () => {
|
|
180
|
+
clearTimeout(timeout);
|
|
181
|
+
resolve();
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
this.serverProcess = null;
|
|
185
|
+
this.isRunning = false;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
async restart() {
|
|
189
|
+
await this.stop();
|
|
190
|
+
await this.start();
|
|
191
|
+
}
|
|
192
|
+
async createServerEntry() {
|
|
193
|
+
const { writeFile: writeFile$1 } = await import("node:fs/promises");
|
|
194
|
+
const { relative: relative$1, dirname: dirname$1 } = await import("node:path");
|
|
195
|
+
const serverPath = join(process.cwd(), ".gkm", this.provider, "server.ts");
|
|
196
|
+
const relativeAppPath = relative$1(dirname$1(serverPath), join(dirname$1(serverPath), "app.js"));
|
|
197
|
+
const content = `#!/usr/bin/env node
|
|
198
|
+
/**
|
|
199
|
+
* Development server entry point
|
|
200
|
+
* This file is auto-generated by 'gkm dev'
|
|
201
|
+
*/
|
|
202
|
+
import { createApp } from './${relativeAppPath.startsWith(".") ? relativeAppPath : "./" + relativeAppPath}';
|
|
203
|
+
|
|
204
|
+
const port = process.argv.includes('--port')
|
|
205
|
+
? Number.parseInt(process.argv[process.argv.indexOf('--port') + 1])
|
|
206
|
+
: 3000;
|
|
207
|
+
|
|
208
|
+
const { app, start } = createApp(undefined, ${this.enableOpenApi});
|
|
209
|
+
|
|
210
|
+
// Start the server
|
|
211
|
+
start({
|
|
212
|
+
port,
|
|
213
|
+
serve: async (app, port) => {
|
|
214
|
+
// Detect runtime and use appropriate server
|
|
215
|
+
if (typeof Bun !== 'undefined') {
|
|
216
|
+
// Bun runtime
|
|
217
|
+
Bun.serve({
|
|
218
|
+
port,
|
|
219
|
+
fetch: app.fetch,
|
|
220
|
+
});
|
|
221
|
+
} else {
|
|
222
|
+
// Node.js runtime with @hono/node-server
|
|
223
|
+
const { serve } = await import('@hono/node-server');
|
|
224
|
+
serve({
|
|
225
|
+
fetch: app.fetch,
|
|
226
|
+
port,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
}).catch((error) => {
|
|
231
|
+
console.error('Failed to start server:', error);
|
|
232
|
+
process.exit(1);
|
|
233
|
+
});
|
|
234
|
+
`;
|
|
235
|
+
await writeFile$1(serverPath, content);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
//#endregion
|
|
240
|
+
export { devCommand, findAvailablePort, isPortAvailable };
|
|
241
|
+
//# sourceMappingURL=dev-DnGYXuMn.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-DnGYXuMn.mjs","names":["port: number","err: NodeJS.ErrnoException","preferredPort: number","options: DevOptions","buildContext: BuildContext","rebuildTimeout: NodeJS.Timeout | null","config: any","context: BuildContext","provider: LegacyProvider","enableOpenApi: boolean","requestedPort: number"],"sources":["../src/dev/index.ts"],"sourcesContent":["import { type ChildProcess, spawn } from 'node:child_process';\nimport { mkdir } from 'node:fs/promises';\nimport { createServer } from 'node:net';\nimport { join } from 'node:path';\nimport chokidar from 'chokidar';\nimport { resolveProviders } from '../build/providerResolver';\nimport type { BuildContext } from '../build/types';\nimport { loadConfig } from '../config';\nimport {\n CronGenerator,\n EndpointGenerator,\n FunctionGenerator,\n SubscriberGenerator,\n} from '../generators';\nimport type { LegacyProvider } from '../types';\n\nconst logger = console;\n\n/**\n * Check if a port is available\n * @internal Exported for testing\n */\nexport async function isPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = createServer();\n\n server.once('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n resolve(false);\n } else {\n resolve(false);\n }\n });\n\n server.once('listening', () => {\n server.close();\n resolve(true);\n });\n\n server.listen(port);\n });\n}\n\n/**\n * Find an available port starting from the preferred port\n * @internal Exported for testing\n */\nexport async function findAvailablePort(\n preferredPort: number,\n maxAttempts = 10,\n): Promise<number> {\n for (let i = 0; i < maxAttempts; i++) {\n const port = preferredPort + i;\n if (await isPortAvailable(port)) {\n return port;\n }\n logger.log(`⚠️ Port ${port} is in use, trying ${port + 1}...`);\n }\n\n throw new Error(\n `Could not find an available port after trying ${maxAttempts} ports starting from ${preferredPort}`,\n );\n}\n\nexport interface DevOptions {\n port?: number;\n enableOpenApi?: boolean;\n}\n\nexport async function devCommand(options: DevOptions): Promise<void> {\n const config = await loadConfig();\n\n // Force server provider for dev mode\n const resolved = resolveProviders(config, { provider: 'server' });\n\n logger.log('🚀 Starting development server...');\n logger.log(`Loading routes from: ${config.routes}`);\n if (config.functions) {\n logger.log(`Loading functions from: ${config.functions}`);\n }\n if (config.crons) {\n logger.log(`Loading crons from: ${config.crons}`);\n }\n if (config.subscribers) {\n logger.log(`Loading subscribers from: ${config.subscribers}`);\n }\n logger.log(`Using envParser: ${config.envParser}`);\n\n // Parse envParser configuration\n const [envParserPath, envParserName] = config.envParser.split('#');\n const envParserImportPattern = !envParserName\n ? 'envParser'\n : envParserName === 'envParser'\n ? '{ envParser }'\n : `{ ${envParserName} as envParser }`;\n\n // Parse logger configuration\n const [loggerPath, loggerName] = config.logger.split('#');\n const loggerImportPattern = !loggerName\n ? 'logger'\n : loggerName === 'logger'\n ? '{ logger }'\n : `{ ${loggerName} as logger }`;\n\n const buildContext: BuildContext = {\n envParserPath,\n envParserImportPattern,\n loggerPath,\n loggerImportPattern,\n };\n\n // Build initial version\n await buildServer(\n config,\n buildContext,\n resolved.providers[0] as LegacyProvider,\n resolved.enableOpenApi,\n );\n\n // Start the dev server\n const devServer = new DevServer(\n resolved.providers[0] as LegacyProvider,\n options.port || 3000,\n resolved.enableOpenApi,\n );\n\n await devServer.start();\n\n // Watch for file changes\n const watchPatterns = [\n config.routes,\n ...(config.functions ? [config.functions] : []),\n ...(config.crons ? [config.crons] : []),\n ...(config.subscribers ? [config.subscribers] : []),\n config.envParser.split('#')[0],\n config.logger.split('#')[0],\n ].flat();\n\n logger.log(`👀 Watching for changes in: ${watchPatterns.join(', ')}`);\n\n const watcher = chokidar.watch(watchPatterns, {\n ignored: /(^|[\\/\\\\])\\../, // ignore dotfiles\n persistent: true,\n ignoreInitial: true,\n });\n\n let rebuildTimeout: NodeJS.Timeout | null = null;\n\n watcher.on('change', async (path) => {\n logger.log(`📝 File changed: ${path}`);\n\n // Debounce rebuilds\n if (rebuildTimeout) {\n clearTimeout(rebuildTimeout);\n }\n\n rebuildTimeout = setTimeout(async () => {\n try {\n logger.log('🔄 Rebuilding...');\n await buildServer(\n config,\n buildContext,\n resolved.providers[0] as LegacyProvider,\n resolved.enableOpenApi,\n );\n logger.log('✅ Rebuild complete, restarting server...');\n await devServer.restart();\n } catch (error) {\n logger.error('❌ Rebuild failed:', (error as Error).message);\n }\n }, 300);\n });\n\n // Handle graceful shutdown\n const shutdown = async () => {\n logger.log('\\n🛑 Shutting down...');\n await watcher.close();\n await devServer.stop();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\nasync function buildServer(\n config: any,\n context: BuildContext,\n provider: LegacyProvider,\n enableOpenApi: boolean,\n): Promise<void> {\n // Initialize generators\n const endpointGenerator = new EndpointGenerator();\n const functionGenerator = new FunctionGenerator();\n const cronGenerator = new CronGenerator();\n const subscriberGenerator = new SubscriberGenerator();\n\n // Load all constructs\n const [allEndpoints, allFunctions, allCrons, allSubscribers] =\n await Promise.all([\n endpointGenerator.load(config.routes),\n config.functions ? functionGenerator.load(config.functions) : [],\n config.crons ? cronGenerator.load(config.crons) : [],\n config.subscribers ? subscriberGenerator.load(config.subscribers) : [],\n ]);\n\n // Ensure .gkm directory exists\n const outputDir = join(process.cwd(), '.gkm', provider);\n await mkdir(outputDir, { recursive: true });\n\n // Build for server provider\n await Promise.all([\n endpointGenerator.build(context, allEndpoints, outputDir, {\n provider,\n enableOpenApi,\n }),\n functionGenerator.build(context, allFunctions, outputDir, { provider }),\n cronGenerator.build(context, allCrons, outputDir, { provider }),\n subscriberGenerator.build(context, allSubscribers, outputDir, { provider }),\n ]);\n}\n\nclass DevServer {\n private serverProcess: ChildProcess | null = null;\n private isRunning = false;\n private actualPort: number;\n\n constructor(\n private provider: LegacyProvider,\n private requestedPort: number,\n private enableOpenApi: boolean,\n ) {\n this.actualPort = requestedPort;\n }\n\n async start(): Promise<void> {\n if (this.isRunning) {\n await this.stop();\n }\n\n // Find an available port\n this.actualPort = await findAvailablePort(this.requestedPort);\n\n if (this.actualPort !== this.requestedPort) {\n logger.log(\n `ℹ️ Port ${this.requestedPort} was in use, using port ${this.actualPort} instead`,\n );\n }\n\n const serverEntryPath = join(\n process.cwd(),\n '.gkm',\n this.provider,\n 'server.ts',\n );\n\n // Create server entry file\n await this.createServerEntry();\n\n logger.log(`\\n✨ Starting server on port ${this.actualPort}...`);\n\n // Start the server using tsx (TypeScript execution)\n this.serverProcess = spawn(\n 'npx',\n ['tsx', serverEntryPath, '--port', this.actualPort.toString()],\n {\n stdio: 'inherit',\n env: { ...process.env, NODE_ENV: 'development' },\n },\n );\n\n this.isRunning = true;\n\n this.serverProcess.on('error', (error) => {\n logger.error('❌ Server error:', error);\n });\n\n this.serverProcess.on('exit', (code, signal) => {\n if (code !== null && code !== 0 && signal !== 'SIGTERM') {\n logger.error(`❌ Server exited with code ${code}`);\n }\n this.isRunning = false;\n });\n\n // Give the server a moment to start\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n if (this.isRunning) {\n logger.log(`\\n🎉 Server running at http://localhost:${this.actualPort}`);\n if (this.enableOpenApi) {\n logger.log(\n `📚 API Docs available at http://localhost:${this.actualPort}/docs`,\n );\n }\n }\n }\n\n async stop(): Promise<void> {\n if (this.serverProcess && this.isRunning) {\n this.serverProcess.kill('SIGTERM');\n\n // Wait for process to exit\n await new Promise<void>((resolve) => {\n const timeout = setTimeout(() => {\n this.serverProcess?.kill('SIGKILL');\n resolve();\n }, 5000);\n\n this.serverProcess?.on('exit', () => {\n clearTimeout(timeout);\n resolve();\n });\n });\n\n this.serverProcess = null;\n this.isRunning = false;\n }\n }\n\n async restart(): Promise<void> {\n await this.stop();\n await this.start();\n }\n\n private async createServerEntry(): Promise<void> {\n const { writeFile } = await import('node:fs/promises');\n const { relative, dirname } = await import('node:path');\n\n const serverPath = join(process.cwd(), '.gkm', this.provider, 'server.ts');\n\n const relativeAppPath = relative(\n dirname(serverPath),\n join(dirname(serverPath), 'app.js'),\n );\n\n const content = `#!/usr/bin/env node\n/**\n * Development server entry point\n * This file is auto-generated by 'gkm dev'\n */\nimport { createApp } from './${relativeAppPath.startsWith('.') ? relativeAppPath : './' + relativeAppPath}';\n\nconst port = process.argv.includes('--port')\n ? Number.parseInt(process.argv[process.argv.indexOf('--port') + 1])\n : 3000;\n\nconst { app, start } = createApp(undefined, ${this.enableOpenApi});\n\n// Start the server\nstart({\n port,\n serve: async (app, port) => {\n // Detect runtime and use appropriate server\n if (typeof Bun !== 'undefined') {\n // Bun runtime\n Bun.serve({\n port,\n fetch: app.fetch,\n });\n } else {\n // Node.js runtime with @hono/node-server\n const { serve } = await import('@hono/node-server');\n serve({\n fetch: app.fetch,\n port,\n });\n }\n },\n}).catch((error) => {\n console.error('Failed to start server:', error);\n process.exit(1);\n});\n`;\n\n await writeFile(serverPath, content);\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
require('../Generator-CDoEXCDg.cjs');
|
|
2
|
-
const require_EndpointGenerator = require('../EndpointGenerator-
|
|
2
|
+
const require_EndpointGenerator = require('../EndpointGenerator-C73wNoih.cjs');
|
|
3
3
|
|
|
4
4
|
exports.EndpointGenerator = require_EndpointGenerator.EndpointGenerator;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
require('../Generator-CDoEXCDg.cjs');
|
|
2
|
-
const require_FunctionGenerator = require('../FunctionGenerator-
|
|
2
|
+
const require_FunctionGenerator = require('../FunctionGenerator-FgZUTd8L.cjs');
|
|
3
3
|
|
|
4
4
|
exports.FunctionGenerator = require_FunctionGenerator.FunctionGenerator;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
require('../Generator-CDoEXCDg.cjs');
|
|
2
|
-
const require_SubscriberGenerator = require('../SubscriberGenerator-
|
|
2
|
+
const require_SubscriberGenerator = require('../SubscriberGenerator-Bd-a7aiw.cjs');
|
|
3
3
|
|
|
4
4
|
exports.SubscriberGenerator = require_SubscriberGenerator.SubscriberGenerator;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const require_Generator = require('../Generator-CDoEXCDg.cjs');
|
|
2
|
-
const require_CronGenerator = require('../CronGenerator-
|
|
3
|
-
const require_EndpointGenerator = require('../EndpointGenerator-
|
|
4
|
-
const require_FunctionGenerator = require('../FunctionGenerator-
|
|
5
|
-
const require_SubscriberGenerator = require('../SubscriberGenerator-
|
|
2
|
+
const require_CronGenerator = require('../CronGenerator-C6MF8rlG.cjs');
|
|
3
|
+
const require_EndpointGenerator = require('../EndpointGenerator-C73wNoih.cjs');
|
|
4
|
+
const require_FunctionGenerator = require('../FunctionGenerator-FgZUTd8L.cjs');
|
|
5
|
+
const require_SubscriberGenerator = require('../SubscriberGenerator-Bd-a7aiw.cjs');
|
|
6
6
|
require('../generators-CEKtVh81.cjs');
|
|
7
7
|
|
|
8
8
|
exports.ConstructGenerator = require_Generator.ConstructGenerator;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ConstructGenerator } from "../Generator-UanJW0_V.mjs";
|
|
2
|
-
import { CronGenerator } from "../CronGenerator-
|
|
3
|
-
import { EndpointGenerator } from "../EndpointGenerator-
|
|
4
|
-
import { FunctionGenerator } from "../FunctionGenerator-
|
|
5
|
-
import { SubscriberGenerator } from "../SubscriberGenerator-
|
|
2
|
+
import { CronGenerator } from "../CronGenerator-Bh26MaNA.mjs";
|
|
3
|
+
import { EndpointGenerator } from "../EndpointGenerator-CWh18d92.mjs";
|
|
4
|
+
import { FunctionGenerator } from "../FunctionGenerator-BNE_GC7N.mjs";
|
|
5
|
+
import { SubscriberGenerator } from "../SubscriberGenerator-Dnlj_1FK.mjs";
|
|
6
6
|
import "../generators-CsLujGXs.mjs";
|
|
7
7
|
|
|
8
8
|
export { ConstructGenerator, CronGenerator, EndpointGenerator, FunctionGenerator, SubscriberGenerator };
|