@geekmidas/cli 0.22.0 → 0.24.0

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/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env -S npx tsx
2
2
  import { __require, getAppBuildOrder, getDependencyEnvVars, getDeployTargetError, isDeployTargetSupported } from "./workspace-CPLEZDZf.mjs";
3
- import { loadConfig, loadWorkspaceConfig, parseModuleConfig } from "./config-BaYqrF3n.mjs";
4
- import { ConstructGenerator, EndpointGenerator, OPENAPI_OUTPUT_PATH, OpenApiTsGenerator, generateOpenApi, openapiCommand, resolveOpenApiConfig } from "./openapi-CgqR6Jkw.mjs";
3
+ import { getAppNameFromCwd, loadAppConfig, loadConfig, loadWorkspaceConfig, parseModuleConfig } from "./config-BogU0_oQ.mjs";
4
+ import { ConstructGenerator, EndpointGenerator, OPENAPI_OUTPUT_PATH, OpenApiTsGenerator, generateOpenApi, openapiCommand, resolveOpenApiConfig } from "./openapi-DNbXfhXE.mjs";
5
5
  import { getKeyPath, maskPassword, readStageSecrets, secretsExist, setCustomSecret, toEmbeddableSecrets, writeStageSecrets } from "./storage-Dhst7BhI.mjs";
6
6
  import { DokployApi } from "./dokploy-api-B9qR2Yn1.mjs";
7
7
  import { generateReactQueryCommand } from "./openapi-react-query-5rSortLH.mjs";
@@ -26,7 +26,7 @@ import prompts from "prompts";
26
26
 
27
27
  //#region package.json
28
28
  var name = "@geekmidas/cli";
29
- var version = "0.22.0";
29
+ var version = "0.24.0";
30
30
  var description = "CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs";
31
31
  var private$1 = false;
32
32
  var type = "module";
@@ -79,6 +79,7 @@ var dependencies = {
79
79
  "commander": "^12.1.0",
80
80
  "dotenv": "~17.2.3",
81
81
  "fast-glob": "^3.3.2",
82
+ "hono": "~4.8.0",
82
83
  "lodash.kebabcase": "^4.1.1",
83
84
  "openapi-typescript": "^7.4.2",
84
85
  "prompts": "~2.4.2"
@@ -975,10 +976,10 @@ function normalizeStudioConfig(config$1) {
975
976
  * Normalize hooks configuration
976
977
  * @internal Exported for testing
977
978
  */
978
- function normalizeHooksConfig(config$1) {
979
+ function normalizeHooksConfig(config$1, cwd = process.cwd()) {
979
980
  if (!config$1?.server) return void 0;
980
981
  const serverPath = config$1.server.endsWith(".ts") ? config$1.server : `${config$1.server}.ts`;
981
- const resolvedPath = resolve(process.cwd(), serverPath);
982
+ const resolvedPath = resolve(cwd, serverPath);
982
983
  return { serverHooksPath: resolvedPath };
983
984
  }
984
985
  /**
@@ -1012,14 +1013,32 @@ function getProductionConfigFromGkm(config$1) {
1012
1013
  async function devCommand(options) {
1013
1014
  const defaultEnv = loadEnvFiles(".env");
1014
1015
  if (defaultEnv.loaded.length > 0) logger$8.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
1015
- const loadedConfig = await loadWorkspaceConfig();
1016
- if (loadedConfig.type === "workspace") {
1017
- logger$8.log("📦 Detected workspace configuration");
1018
- return workspaceDevCommand(loadedConfig.workspace, options);
1016
+ const appName = getAppNameFromCwd();
1017
+ let config$1;
1018
+ let appRoot = process.cwd();
1019
+ if (appName) try {
1020
+ const appConfig = await loadAppConfig();
1021
+ config$1 = appConfig.gkmConfig;
1022
+ appRoot = appConfig.appRoot;
1023
+ logger$8.log(`📦 Running app: ${appConfig.appName}`);
1024
+ } catch {
1025
+ const loadedConfig = await loadWorkspaceConfig();
1026
+ if (loadedConfig.type === "workspace") {
1027
+ logger$8.log("📦 Detected workspace configuration");
1028
+ return workspaceDevCommand(loadedConfig.workspace, options);
1029
+ }
1030
+ config$1 = loadedConfig.raw;
1031
+ }
1032
+ else {
1033
+ const loadedConfig = await loadWorkspaceConfig();
1034
+ if (loadedConfig.type === "workspace") {
1035
+ logger$8.log("📦 Detected workspace configuration");
1036
+ return workspaceDevCommand(loadedConfig.workspace, options);
1037
+ }
1038
+ config$1 = loadedConfig.raw;
1019
1039
  }
1020
- const config$1 = loadedConfig.raw;
1021
1040
  if (config$1.env) {
1022
- const { loaded, missing } = loadEnvFiles(config$1.env);
1041
+ const { loaded, missing } = loadEnvFiles(config$1.env, appRoot);
1023
1042
  if (loaded.length > 0) logger$8.log(`📦 Loaded env: ${loaded.join(", ")}`);
1024
1043
  if (missing.length > 0) logger$8.warn(`⚠️ Missing env files: ${missing.join(", ")}`);
1025
1044
  }
@@ -1036,7 +1055,7 @@ async function devCommand(options) {
1036
1055
  if (telescope) logger$8.log(`🔭 Telescope enabled at ${telescope.path}`);
1037
1056
  const studio = normalizeStudioConfig(config$1.studio);
1038
1057
  if (studio) logger$8.log(`🗄️ Studio enabled at ${studio.path}`);
1039
- const hooks = normalizeHooksConfig(config$1.hooks);
1058
+ const hooks = normalizeHooksConfig(config$1.hooks, appRoot);
1040
1059
  if (hooks) logger$8.log(`🪝 Server hooks enabled from ${config$1.hooks?.server}`);
1041
1060
  const openApiConfig = resolveOpenApiConfig(config$1);
1042
1061
  const enableOpenApi = openApiConfig.enabled || resolved.enableOpenApi;
@@ -1050,10 +1069,10 @@ async function devCommand(options) {
1050
1069
  studio,
1051
1070
  hooks
1052
1071
  };
1053
- await buildServer(config$1, buildContext, resolved.providers[0], enableOpenApi);
1072
+ await buildServer(config$1, buildContext, resolved.providers[0], enableOpenApi, appRoot);
1054
1073
  if (enableOpenApi) await generateOpenApi(config$1);
1055
1074
  const runtime = config$1.runtime ?? "node";
1056
- const devServer = new DevServer(resolved.providers[0], options.port || 3e3, options.portExplicit ?? false, enableOpenApi, telescope, studio, runtime);
1075
+ const devServer = new DevServer(resolved.providers[0], options.port || 3e3, options.portExplicit ?? false, enableOpenApi, telescope, studio, runtime, appRoot);
1057
1076
  await devServer.start();
1058
1077
  const envParserFile = config$1.envParser.split("#")[0] ?? config$1.envParser;
1059
1078
  const loggerFile = config$1.logger.split("#")[0] ?? config$1.logger;
@@ -1071,7 +1090,7 @@ async function devCommand(options) {
1071
1090
  const normalizedPatterns = watchPatterns.map((p) => p.startsWith("./") ? p.slice(2) : p);
1072
1091
  logger$8.log(`👀 Watching for changes in: ${normalizedPatterns.join(", ")}`);
1073
1092
  const resolvedFiles = await fg(normalizedPatterns, {
1074
- cwd: process.cwd(),
1093
+ cwd: appRoot,
1075
1094
  absolute: false,
1076
1095
  onlyFiles: true
1077
1096
  });
@@ -1084,7 +1103,7 @@ async function devCommand(options) {
1084
1103
  ignored: /(^|[/\\])\../,
1085
1104
  persistent: true,
1086
1105
  ignoreInitial: true,
1087
- cwd: process.cwd()
1106
+ cwd: appRoot
1088
1107
  });
1089
1108
  watcher.on("ready", () => {
1090
1109
  logger$8.log("🔍 File watcher ready");
@@ -1099,7 +1118,7 @@ async function devCommand(options) {
1099
1118
  rebuildTimeout = setTimeout(async () => {
1100
1119
  try {
1101
1120
  logger$8.log("🔄 Rebuilding...");
1102
- await buildServer(config$1, buildContext, resolved.providers[0], enableOpenApi);
1121
+ await buildServer(config$1, buildContext, resolved.providers[0], enableOpenApi, appRoot);
1103
1122
  if (enableOpenApi) await generateOpenApi(config$1, { silent: true });
1104
1123
  logger$8.log("✅ Rebuild complete, restarting server...");
1105
1124
  await devServer.restart();
@@ -1321,11 +1340,25 @@ async function workspaceDevCommand(workspace, options) {
1321
1340
  const deps = app.dependencies.length > 0 ? ` (depends on: ${app.dependencies.join(", ")})` : "";
1322
1341
  logger$8.log(` ${app.type === "backend" ? "🔧" : "🌐"} ${appName} → http://localhost:${app.port}${deps}`);
1323
1342
  }
1343
+ const configFiles = [
1344
+ "gkm.config.ts",
1345
+ "gkm.config.js",
1346
+ "gkm.config.json"
1347
+ ];
1348
+ let configPath = "";
1349
+ for (const file of configFiles) {
1350
+ const fullPath = join(workspace.root, file);
1351
+ if (existsSync(fullPath)) {
1352
+ configPath = fullPath;
1353
+ break;
1354
+ }
1355
+ }
1324
1356
  const turboEnv = {
1325
1357
  ...process.env,
1326
1358
  ...secretsEnv,
1327
1359
  ...dependencyEnv,
1328
- NODE_ENV: "development"
1360
+ NODE_ENV: "development",
1361
+ ...configPath ? { GKM_CONFIG_PATH: configPath } : {}
1329
1362
  };
1330
1363
  logger$8.log("\n🏃 Starting turbo run dev...\n");
1331
1364
  const turboProcess = spawn("pnpm", [
@@ -1428,18 +1461,18 @@ async function workspaceDevCommand(workspace, options) {
1428
1461
  });
1429
1462
  });
1430
1463
  }
1431
- async function buildServer(config$1, context, provider, enableOpenApi) {
1464
+ async function buildServer(config$1, context, provider, enableOpenApi, appRoot = process.cwd()) {
1432
1465
  const endpointGenerator = new EndpointGenerator();
1433
1466
  const functionGenerator = new FunctionGenerator();
1434
1467
  const cronGenerator = new CronGenerator();
1435
1468
  const subscriberGenerator = new SubscriberGenerator();
1436
1469
  const [allEndpoints, allFunctions, allCrons, allSubscribers] = await Promise.all([
1437
- endpointGenerator.load(config$1.routes),
1438
- config$1.functions ? functionGenerator.load(config$1.functions) : [],
1439
- config$1.crons ? cronGenerator.load(config$1.crons) : [],
1440
- config$1.subscribers ? subscriberGenerator.load(config$1.subscribers) : []
1470
+ endpointGenerator.load(config$1.routes, appRoot),
1471
+ config$1.functions ? functionGenerator.load(config$1.functions, appRoot) : [],
1472
+ config$1.crons ? cronGenerator.load(config$1.crons, appRoot) : [],
1473
+ config$1.subscribers ? subscriberGenerator.load(config$1.subscribers, appRoot) : []
1441
1474
  ]);
1442
- const outputDir = join(process.cwd(), ".gkm", provider);
1475
+ const outputDir = join(appRoot, ".gkm", provider);
1443
1476
  await mkdir(outputDir, { recursive: true });
1444
1477
  await Promise.all([
1445
1478
  endpointGenerator.build(context, allEndpoints, outputDir, {
@@ -1455,7 +1488,7 @@ var DevServer = class {
1455
1488
  serverProcess = null;
1456
1489
  isRunning = false;
1457
1490
  actualPort;
1458
- constructor(provider, requestedPort, portExplicit, enableOpenApi, telescope, studio, runtime = "node") {
1491
+ constructor(provider, requestedPort, portExplicit, enableOpenApi, telescope, studio, runtime = "node", appRoot = process.cwd()) {
1459
1492
  this.provider = provider;
1460
1493
  this.requestedPort = requestedPort;
1461
1494
  this.portExplicit = portExplicit;
@@ -1463,6 +1496,7 @@ var DevServer = class {
1463
1496
  this.telescope = telescope;
1464
1497
  this.studio = studio;
1465
1498
  this.runtime = runtime;
1499
+ this.appRoot = appRoot;
1466
1500
  this.actualPort = requestedPort;
1467
1501
  }
1468
1502
  async start() {
@@ -1475,7 +1509,7 @@ var DevServer = class {
1475
1509
  this.actualPort = await findAvailablePort(this.requestedPort);
1476
1510
  if (this.actualPort !== this.requestedPort) logger$8.log(`ℹ️ Port ${this.requestedPort} was in use, using port ${this.actualPort} instead`);
1477
1511
  }
1478
- const serverEntryPath = join(process.cwd(), ".gkm", this.provider, "server.ts");
1512
+ const serverEntryPath = join(this.appRoot, ".gkm", this.provider, "server.ts");
1479
1513
  await this.createServerEntry();
1480
1514
  logger$8.log(`\n✨ Starting server on port ${this.actualPort}...`);
1481
1515
  this.serverProcess = spawn("npx", [
@@ -1543,7 +1577,7 @@ var DevServer = class {
1543
1577
  async createServerEntry() {
1544
1578
  const { writeFile: writeFile$1 } = await import("node:fs/promises");
1545
1579
  const { relative: relative$1, dirname: dirname$1 } = await import("node:path");
1546
- const serverPath = join(process.cwd(), ".gkm", this.provider, "server.ts");
1580
+ const serverPath = join(this.appRoot, ".gkm", this.provider, "server.ts");
1547
1581
  const relativeAppPath = relative$1(dirname$1(serverPath), join(dirname$1(serverPath), "app.js"));
1548
1582
  const serveCode = this.runtime === "bun" ? `Bun.serve({
1549
1583
  port,
@@ -3068,7 +3102,7 @@ async function workspaceDockerCommand(workspace, options) {
3068
3102
  * Get app name from package.json in the current working directory
3069
3103
  * Used for Dokploy app/project naming
3070
3104
  */
3071
- function getAppNameFromCwd() {
3105
+ function getAppNameFromCwd$1() {
3072
3106
  const packageJsonPath = join(process.cwd(), "package.json");
3073
3107
  if (!existsSync(packageJsonPath)) return void 0;
3074
3108
  try {
@@ -3186,7 +3220,7 @@ async function deployDocker(options) {
3186
3220
  */
3187
3221
  function resolveDockerConfig(config$1) {
3188
3222
  const projectName = getAppNameFromPackageJson() ?? "app";
3189
- const appName = getAppNameFromCwd() ?? projectName;
3223
+ const appName = getAppNameFromCwd$1() ?? projectName;
3190
3224
  const imageName = config$1.docker?.imageName ?? appName;
3191
3225
  return {
3192
3226
  registry: config$1.docker?.registry,
@@ -4222,7 +4256,14 @@ function rotateServicePassword(secrets, service) {
4222
4256
  //#endregion
4223
4257
  //#region src/init/versions.ts
4224
4258
  const require$1 = createRequire(import.meta.url);
4225
- const pkg = require$1("../package.json");
4259
+ function loadPackageJson() {
4260
+ try {
4261
+ return require$1("../package.json");
4262
+ } catch {
4263
+ return require$1("../../package.json");
4264
+ }
4265
+ }
4266
+ const pkg = loadPackageJson();
4226
4267
  /**
4227
4268
  * CLI version from package.json (used for scaffolded projects)
4228
4269
  */
@@ -4752,7 +4793,7 @@ function generateDockerFiles(options, template, dbApps) {
4752
4793
  retries: 5`);
4753
4794
  volumes.push(" rabbitmq_data:");
4754
4795
  }
4755
- if (options.services.mail) services.push(` mailpit:
4796
+ if (options.services?.mail) services.push(` mailpit:
4756
4797
  image: axllent/mailpit:latest
4757
4798
  container_name: ${options.name}-mailpit
4758
4799
  restart: unless-stopped