@geekmidas/cli 0.45.0 → 0.47.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.
Files changed (51) hide show
  1. package/dist/{config-C0b0jdmU.mjs → config-C3LSBNSl.mjs} +2 -2
  2. package/dist/{config-C0b0jdmU.mjs.map → config-C3LSBNSl.mjs.map} +1 -1
  3. package/dist/{config-xVZsRjN7.cjs → config-HYiM3iQJ.cjs} +2 -2
  4. package/dist/{config-xVZsRjN7.cjs.map → config-HYiM3iQJ.cjs.map} +1 -1
  5. package/dist/config.cjs +2 -2
  6. package/dist/config.d.cts +1 -1
  7. package/dist/config.d.mts +1 -1
  8. package/dist/config.mjs +2 -2
  9. package/dist/dokploy-api-4a6h35VY.cjs +3 -0
  10. package/dist/{dokploy-api-BdxOMH_V.cjs → dokploy-api-BnX2OxyF.cjs} +121 -1
  11. package/dist/dokploy-api-BnX2OxyF.cjs.map +1 -0
  12. package/dist/{dokploy-api-DWsqNjwP.mjs → dokploy-api-CMWlWq7-.mjs} +121 -1
  13. package/dist/dokploy-api-CMWlWq7-.mjs.map +1 -0
  14. package/dist/dokploy-api-DQvi9iZa.mjs +3 -0
  15. package/dist/{index-CXa3odEw.d.mts → index-A70abJ1m.d.mts} +598 -46
  16. package/dist/index-A70abJ1m.d.mts.map +1 -0
  17. package/dist/{index-E8Nu2Rxl.d.cts → index-pOA56MWT.d.cts} +598 -46
  18. package/dist/index-pOA56MWT.d.cts.map +1 -0
  19. package/dist/index.cjs +916 -357
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.mjs +916 -357
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/{openapi-D3pA6FfZ.mjs → openapi-C3C-BzIZ.mjs} +2 -2
  24. package/dist/{openapi-D3pA6FfZ.mjs.map → openapi-C3C-BzIZ.mjs.map} +1 -1
  25. package/dist/{openapi-DhcCtKzM.cjs → openapi-D7WwlpPF.cjs} +2 -2
  26. package/dist/{openapi-DhcCtKzM.cjs.map → openapi-D7WwlpPF.cjs.map} +1 -1
  27. package/dist/openapi.cjs +3 -3
  28. package/dist/openapi.mjs +3 -3
  29. package/dist/workspace/index.cjs +1 -1
  30. package/dist/workspace/index.d.cts +1 -1
  31. package/dist/workspace/index.d.mts +1 -1
  32. package/dist/workspace/index.mjs +1 -1
  33. package/dist/{workspace-BDAhr6Kb.cjs → workspace-CaVW6j2q.cjs} +10 -1
  34. package/dist/{workspace-BDAhr6Kb.cjs.map → workspace-CaVW6j2q.cjs.map} +1 -1
  35. package/dist/{workspace-D_6ZCaR_.mjs → workspace-DLFRaDc-.mjs} +10 -1
  36. package/dist/{workspace-D_6ZCaR_.mjs.map → workspace-DLFRaDc-.mjs.map} +1 -1
  37. package/package.json +3 -3
  38. package/src/auth/credentials.ts +66 -0
  39. package/src/deploy/dns/hostinger-api.ts +258 -0
  40. package/src/deploy/dns/index.ts +399 -0
  41. package/src/deploy/dokploy-api.ts +175 -0
  42. package/src/deploy/index.ts +389 -240
  43. package/src/deploy/state.ts +146 -0
  44. package/src/workspace/types.ts +629 -47
  45. package/tsconfig.tsbuildinfo +1 -1
  46. package/dist/dokploy-api-Bdmk5ImW.cjs +0 -3
  47. package/dist/dokploy-api-BdxOMH_V.cjs.map +0 -1
  48. package/dist/dokploy-api-DWsqNjwP.mjs.map +0 -1
  49. package/dist/dokploy-api-tZSZaHd9.mjs +0 -3
  50. package/dist/index-CXa3odEw.d.mts.map +0 -1
  51. package/dist/index-E8Nu2Rxl.d.cts.map +0 -1
@@ -11,23 +11,78 @@ import type {
11
11
 
12
12
  /**
13
13
  * Deploy target for an app.
14
- * Currently only 'dokploy' is supported.
15
- * Future: 'vercel' | 'cloudflare'
14
+ *
15
+ * Specifies where the app will be deployed.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * // Currently supported
20
+ * deploy: 'dokploy'
21
+ *
22
+ * // Future support (not yet implemented)
23
+ * deploy: 'vercel'
24
+ * deploy: 'cloudflare'
25
+ * ```
16
26
  */
17
27
  export type DeployTarget = 'dokploy' | 'vercel' | 'cloudflare';
18
28
 
19
29
  /**
20
30
  * Backend framework types for apps that don't use gkm routes.
31
+ *
32
+ * Used with `entry` to specify the framework for proper Docker builds.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * // Better Auth server
37
+ * {
38
+ * entry: './src/index.ts',
39
+ * framework: 'better-auth',
40
+ * port: 3001,
41
+ * }
42
+ *
43
+ * // Hono app without gkm routes
44
+ * {
45
+ * entry: './src/server.ts',
46
+ * framework: 'hono',
47
+ * port: 3000,
48
+ * }
49
+ * ```
21
50
  */
22
51
  export type BackendFramework = 'hono' | 'better-auth' | 'express' | 'fastify';
23
52
 
24
53
  /**
25
54
  * Frontend framework types.
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * // Next.js app
59
+ * {
60
+ * type: 'frontend',
61
+ * framework: 'nextjs',
62
+ * port: 3000,
63
+ * }
64
+ *
65
+ * // Vite SPA
66
+ * {
67
+ * type: 'frontend',
68
+ * framework: 'vite',
69
+ * port: 5173,
70
+ * }
71
+ * ```
26
72
  */
27
73
  export type FrontendFramework = 'nextjs' | 'remix' | 'vite';
28
74
 
29
75
  /**
30
76
  * Service image configuration for custom Docker images.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * // Use specific version
81
+ * db: { version: '16-alpine' }
82
+ *
83
+ * // Use custom image
84
+ * db: { image: 'timescale/timescaledb:latest-pg16' }
85
+ * ```
31
86
  */
32
87
  export interface ServiceImageConfig {
33
88
  /** Docker image version/tag (e.g., '18-alpine') */
@@ -38,6 +93,23 @@ export interface ServiceImageConfig {
38
93
 
39
94
  /**
40
95
  * Mail service configuration.
96
+ *
97
+ * In development, uses Mailpit for email testing.
98
+ * In production, uses SMTP configuration.
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * services: {
103
+ * mail: {
104
+ * smtp: {
105
+ * host: 'smtp.sendgrid.net',
106
+ * port: 587,
107
+ * user: 'apikey',
108
+ * pass: process.env.SENDGRID_API_KEY,
109
+ * }
110
+ * }
111
+ * }
112
+ * ```
41
113
  */
42
114
  export interface MailServiceConfig extends ServiceImageConfig {
43
115
  /** SMTP configuration for production */
@@ -51,6 +123,36 @@ export interface MailServiceConfig extends ServiceImageConfig {
51
123
 
52
124
  /**
53
125
  * Development services configuration.
126
+ *
127
+ * Configures shared infrastructure services like databases and caches.
128
+ * These are automatically provisioned in Dokploy during deployment.
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * // Enable with defaults
133
+ * services: {
134
+ * db: true, // postgres:18-alpine
135
+ * cache: true, // redis:8-alpine
136
+ * }
137
+ *
138
+ * // Custom versions
139
+ * services: {
140
+ * db: { version: '16-alpine' },
141
+ * cache: { version: '7-alpine' },
142
+ * }
143
+ *
144
+ * // Custom images
145
+ * services: {
146
+ * db: { image: 'timescale/timescaledb:latest-pg16' },
147
+ * }
148
+ *
149
+ * // With mail service
150
+ * services: {
151
+ * db: true,
152
+ * cache: true,
153
+ * mail: true, // Mailpit in dev
154
+ * }
155
+ * ```
54
156
  */
55
157
  export interface ServicesConfig {
56
158
  /** PostgreSQL database (default: postgres:18-alpine) */
@@ -63,57 +165,201 @@ export interface ServicesConfig {
63
165
 
64
166
  /**
65
167
  * Stage-based domain configuration.
66
- * Maps deployment stages to base domains.
67
- * @example { development: 'dev.myapp.com', production: 'myapp.com' }
168
+ *
169
+ * Maps deployment stages to base domains. The main frontend app
170
+ * gets the base domain, other apps get `{appName}.{baseDomain}`.
171
+ *
172
+ * @example
173
+ * ```ts
174
+ * domains: {
175
+ * development: 'dev.myapp.com',
176
+ * staging: 'staging.myapp.com',
177
+ * production: 'myapp.com',
178
+ * }
179
+ *
180
+ * // Result for production stage:
181
+ * // - web (main frontend): myapp.com
182
+ * // - api: api.myapp.com
183
+ * // - auth: auth.myapp.com
184
+ * ```
68
185
  */
69
186
  export type DokployDomainsConfig = Record<string, string>;
70
187
 
71
188
  /**
72
189
  * Per-app domain override configuration.
73
- * Can be a single domain string or stage-specific domains.
74
- * @example 'api.custom.com' or { production: 'api.custom.com', staging: 'api.staging.com' }
190
+ *
191
+ * Can be a single domain string (used for all stages) or
192
+ * stage-specific domains.
193
+ *
194
+ * @example
195
+ * ```ts
196
+ * // Single domain for all stages
197
+ * domain: 'api.custom.com'
198
+ *
199
+ * // Stage-specific domains
200
+ * domain: {
201
+ * development: 'api.dev.custom.com',
202
+ * staging: 'api.staging.custom.com',
203
+ * production: 'api.custom.com',
204
+ * }
205
+ * ```
75
206
  */
76
207
  export type AppDomainConfig = string | Record<string, string>;
77
208
 
78
209
  /**
79
210
  * Dokploy workspace deployment configuration.
211
+ *
212
+ * Configures how the workspace is deployed to a Dokploy server.
213
+ * One workspace maps to one Dokploy project with stage-based environments.
214
+ *
215
+ * @example
216
+ * ```ts
217
+ * deploy: {
218
+ * default: 'dokploy',
219
+ * dokploy: {
220
+ * endpoint: 'https://dokploy.myserver.com',
221
+ * projectId: 'proj_abc123',
222
+ * registry: 'ghcr.io/myorg',
223
+ * domains: {
224
+ * development: 'dev.myapp.com',
225
+ * production: 'myapp.com',
226
+ * },
227
+ * },
228
+ * }
229
+ * ```
80
230
  */
81
231
  export interface DokployWorkspaceConfig {
82
- /** Dokploy API endpoint */
232
+ /** Dokploy API endpoint (e.g., 'https://dokploy.myserver.com') */
83
233
  endpoint: string;
84
- /** Project ID (1 workspace = 1 project) */
234
+ /** Project ID in Dokploy (auto-created on first deploy) */
85
235
  projectId: string;
86
- /** Container registry for images */
236
+ /** Container registry for Docker images (e.g., 'ghcr.io/myorg') */
87
237
  registry?: string;
88
- /** Registry ID in Dokploy */
238
+ /** Registry ID in Dokploy (auto-configured) */
89
239
  registryId?: string;
90
240
  /**
91
241
  * Stage-based domain configuration.
92
242
  * The main frontend app gets the base domain.
93
243
  * Other apps get {appName}.{baseDomain} by default.
94
- * @example { development: 'dev.myapp.com', production: 'myapp.com' }
95
244
  */
96
245
  domains?: DokployDomainsConfig;
97
246
  }
98
247
 
248
+ /**
249
+ * DNS provider types for automatic DNS record creation.
250
+ */
251
+ export type DnsProvider = 'hostinger' | 'cloudflare' | 'manual';
252
+
253
+ /**
254
+ * DNS configuration for automatic record creation during deployment.
255
+ *
256
+ * When configured, the deploy command will automatically create DNS
257
+ * A records pointing to your Dokploy server for each app's domain.
258
+ *
259
+ * @example
260
+ * ```ts
261
+ * // Auto-create DNS records at Hostinger
262
+ * dns: {
263
+ * provider: 'hostinger',
264
+ * domain: 'traflabs.io',
265
+ * autoCreate: true,
266
+ * }
267
+ *
268
+ * // Manual mode - just print required records
269
+ * dns: {
270
+ * provider: 'manual',
271
+ * domain: 'traflabs.io',
272
+ * }
273
+ * ```
274
+ */
275
+ export interface DnsConfig {
276
+ /**
277
+ * DNS provider for automatic record creation.
278
+ * - 'hostinger': Use Hostinger DNS API
279
+ * - 'cloudflare': Use Cloudflare DNS API (future)
280
+ * - 'manual': Don't create records, just print required records
281
+ */
282
+ provider: DnsProvider;
283
+
284
+ /**
285
+ * Root domain where records will be created.
286
+ * @example 'traflabs.io', 'example.com'
287
+ */
288
+ domain: string;
289
+
290
+ /**
291
+ * Automatically create DNS records during deploy.
292
+ * If false, only prints required records for manual setup.
293
+ * @default true
294
+ */
295
+ autoCreate?: boolean;
296
+
297
+ /**
298
+ * TTL for created DNS records in seconds.
299
+ * @default 300 (5 minutes)
300
+ */
301
+ ttl?: number;
302
+ }
303
+
99
304
  /**
100
305
  * Deployment configuration for the workspace.
306
+ *
307
+ * @example
308
+ * ```ts
309
+ * // Minimal - just set default target
310
+ * deploy: {
311
+ * default: 'dokploy',
312
+ * }
313
+ *
314
+ * // Full configuration with DNS
315
+ * deploy: {
316
+ * default: 'dokploy',
317
+ * dokploy: {
318
+ * endpoint: 'https://dokploy.myserver.com',
319
+ * projectId: 'proj_abc123',
320
+ * registry: 'ghcr.io/myorg',
321
+ * domains: {
322
+ * production: 'myapp.com',
323
+ * },
324
+ * },
325
+ * dns: {
326
+ * provider: 'hostinger',
327
+ * domain: 'myapp.com',
328
+ * autoCreate: true,
329
+ * },
330
+ * }
331
+ * ```
101
332
  */
102
333
  export interface DeployConfig {
103
- /** Default deploy target for all apps */
334
+ /** Default deploy target for all apps (default: 'dokploy') */
104
335
  default?: DeployTarget;
105
336
  /** Dokploy-specific configuration */
106
337
  dokploy?: DokployWorkspaceConfig;
338
+ /** DNS configuration for automatic record creation */
339
+ dns?: DnsConfig;
107
340
  }
108
341
 
109
342
  /**
110
343
  * Models package configuration for shared schemas.
344
+ *
345
+ * Configures a shared models package containing Zod schemas
346
+ * that can be used across backend and frontend apps.
347
+ *
348
+ * @example
349
+ * ```ts
350
+ * shared: {
351
+ * models: {
352
+ * path: 'packages/models',
353
+ * schema: 'zod',
354
+ * },
355
+ * }
356
+ * ```
111
357
  */
112
358
  export interface ModelsConfig {
113
- /** Path to models package (default: packages/models) */
359
+ /** Path to models package relative to workspace root (default: 'packages/models') */
114
360
  path?: string;
115
361
  /**
116
- * Schema library to use.
362
+ * Schema library to use (default: 'zod').
117
363
  * Currently only 'zod' is supported.
118
364
  * Future: any StandardSchema-compatible library
119
365
  */
@@ -122,6 +368,20 @@ export interface ModelsConfig {
122
368
 
123
369
  /**
124
370
  * Shared packages configuration.
371
+ *
372
+ * Configures shared packages in the monorepo that are
373
+ * used by multiple apps.
374
+ *
375
+ * @example
376
+ * ```ts
377
+ * shared: {
378
+ * packages: ['packages/*', 'libs/*'],
379
+ * models: {
380
+ * path: 'packages/models',
381
+ * schema: 'zod',
382
+ * },
383
+ * }
384
+ * ```
125
385
  */
126
386
  export interface SharedConfig {
127
387
  /** Glob patterns for shared packages (default: ['packages/*']) */
@@ -132,18 +392,46 @@ export interface SharedConfig {
132
392
 
133
393
  /**
134
394
  * Secrets encryption configuration.
395
+ *
396
+ * Configures how secrets are encrypted for deployment.
397
+ * Secrets are stored encrypted in `.gkm/secrets/{stage}.json`
398
+ * with keys stored separately in `~/.gkm/{project}/{stage}.key`.
399
+ *
400
+ * @example
401
+ * ```ts
402
+ * secrets: {
403
+ * enabled: true,
404
+ * algorithm: 'aes-256-gcm',
405
+ * kdf: 'scrypt',
406
+ * }
407
+ * ```
135
408
  */
136
409
  export interface SecretsConfig {
137
- /** Enable encrypted secrets */
410
+ /** Enable encrypted secrets (default: true) */
138
411
  enabled?: boolean;
139
- /** Encryption algorithm (default: aes-256-gcm) */
412
+ /** Encryption algorithm (default: 'aes-256-gcm') */
140
413
  algorithm?: string;
141
- /** Key derivation function (default: scrypt) */
414
+ /** Key derivation function (default: 'scrypt') */
142
415
  kdf?: 'scrypt' | 'pbkdf2';
143
416
  }
144
417
 
145
418
  /**
146
419
  * Client generation configuration for frontend apps.
420
+ *
421
+ * Configures automatic API client generation from OpenAPI specs.
422
+ *
423
+ * @example
424
+ * ```ts
425
+ * // In a frontend app config
426
+ * {
427
+ * type: 'frontend',
428
+ * framework: 'nextjs',
429
+ * dependencies: ['api'],
430
+ * client: {
431
+ * output: './src/lib/api',
432
+ * },
433
+ * }
434
+ * ```
147
435
  */
148
436
  export interface ClientConfig {
149
437
  /** Output directory for generated client (relative to app path) */
@@ -152,81 +440,242 @@ export interface ClientConfig {
152
440
 
153
441
  /**
154
442
  * Base app configuration properties (shared between input and normalized).
443
+ *
444
+ * @example
445
+ * ```ts
446
+ * // Backend app with gkm routes
447
+ * api: {
448
+ * type: 'backend',
449
+ * path: 'apps/api',
450
+ * port: 3000,
451
+ * routes: './src/endpoints/**\/*.ts',
452
+ * envParser: './src/config/env',
453
+ * logger: './src/config/logger',
454
+ * }
455
+ *
456
+ * // Backend app with entry point (e.g., Better Auth)
457
+ * auth: {
458
+ * type: 'backend',
459
+ * path: 'apps/auth',
460
+ * port: 3001,
461
+ * entry: './src/index.ts',
462
+ * framework: 'better-auth',
463
+ * requiredEnv: ['DATABASE_URL', 'BETTER_AUTH_SECRET'],
464
+ * }
465
+ *
466
+ * // Frontend app
467
+ * web: {
468
+ * type: 'frontend',
469
+ * path: 'apps/web',
470
+ * port: 3002,
471
+ * framework: 'nextjs',
472
+ * dependencies: ['api', 'auth'],
473
+ * }
474
+ * ```
155
475
  */
156
476
  interface AppConfigBase {
157
- /** App type (default: 'backend') */
477
+ /**
478
+ * App type.
479
+ * - 'backend': Server-side app (API, auth service, etc.)
480
+ * - 'frontend': Client-side app (Next.js, Vite, etc.)
481
+ * @default 'backend'
482
+ */
158
483
  type?: 'backend' | 'frontend';
159
484
 
160
- /** Path relative to workspace root */
485
+ /**
486
+ * Path to the app relative to workspace root.
487
+ * @example 'apps/api', 'apps/web', 'services/auth'
488
+ */
161
489
  path: string;
162
490
 
163
- /** Dev server port */
491
+ /**
492
+ * Development server port.
493
+ * Must be unique across all apps in the workspace.
494
+ * @example 3000, 3001, 3002
495
+ */
164
496
  port: number;
165
497
 
166
- /** Per-app deploy target override */
498
+ /**
499
+ * Per-app deploy target override.
500
+ * Overrides `deploy.default` for this specific app.
501
+ * @example 'dokploy', 'vercel'
502
+ */
167
503
  deploy?: DeployTarget;
168
504
 
169
- // Backend-specific (from GkmConfig)
170
- /** Routes glob pattern */
505
+ // ─────────────────────────────────────────────────────────────────
506
+ // Backend-specific (gkm routes mode)
507
+ // ─────────────────────────────────────────────────────────────────
508
+
509
+ /**
510
+ * Routes glob pattern for gkm endpoints.
511
+ * @example './src/endpoints/**\/*.ts'
512
+ */
171
513
  routes?: Routes;
172
- /** Functions glob pattern */
514
+
515
+ /**
516
+ * Functions glob pattern for Lambda functions.
517
+ * @example './src/functions/**\/*.ts'
518
+ */
173
519
  functions?: Routes;
174
- /** Crons glob pattern */
520
+
521
+ /**
522
+ * Crons glob pattern for scheduled tasks.
523
+ * @example './src/crons/**\/*.ts'
524
+ */
175
525
  crons?: Routes;
176
- /** Subscribers glob pattern */
526
+
527
+ /**
528
+ * Subscribers glob pattern for event handlers.
529
+ * @example './src/subscribers/**\/*.ts'
530
+ */
177
531
  subscribers?: Routes;
178
- /** Path to environment parser module */
532
+
533
+ /**
534
+ * Path to environment parser module.
535
+ * @example './src/config/env'
536
+ */
179
537
  envParser?: string;
180
- /** Path to logger module */
538
+
539
+ /**
540
+ * Path to logger module.
541
+ * @example './src/config/logger'
542
+ */
181
543
  logger?: string;
182
- /** Provider configuration */
544
+
545
+ /** Provider configuration (AWS, Docker, etc.) */
183
546
  providers?: ProvidersConfig;
184
- /** Server lifecycle hooks */
547
+
548
+ /**
549
+ * Server lifecycle hooks.
550
+ * @example { beforeSetup: './src/hooks/setup.ts' }
551
+ */
185
552
  hooks?: HooksConfig;
186
- /** Telescope configuration */
553
+
554
+ /**
555
+ * Telescope debugging dashboard configuration.
556
+ * @example true, './src/config/telescope', { enabled: true, path: '/__telescope' }
557
+ */
187
558
  telescope?: string | boolean | TelescopeConfig;
188
- /** Studio configuration */
559
+
560
+ /**
561
+ * Studio admin panel configuration.
562
+ * @example true, './src/config/studio'
563
+ */
189
564
  studio?: string | boolean | StudioConfig;
190
- /** OpenAPI configuration */
565
+
566
+ /**
567
+ * OpenAPI documentation configuration.
568
+ * @example true, { output: './src/openapi.ts' }
569
+ */
191
570
  openapi?: boolean | OpenApiConfig;
192
- /** Runtime (node or bun) */
571
+
572
+ /**
573
+ * Runtime environment.
574
+ * @default 'node'
575
+ */
193
576
  runtime?: Runtime;
194
- /** Environment file(s) to load */
577
+
578
+ /**
579
+ * Environment file(s) to load during development.
580
+ * @example '.env', ['.env', '.env.local']
581
+ */
195
582
  env?: string | string[];
196
583
 
197
- // Entry point for non-gkm apps
584
+ // ─────────────────────────────────────────────────────────────────
585
+ // Entry point mode (non-gkm apps)
586
+ // ─────────────────────────────────────────────────────────────────
587
+
198
588
  /**
199
589
  * Entry file path for apps that don't use gkm routes.
200
- * Used by both `gkm dev` (runs with tsx) and Docker builds (bundles with tsdown).
201
- * @example './src/index.ts'
590
+ *
591
+ * When specified, the app is run directly with tsx in development
592
+ * and bundled with esbuild for production Docker builds.
593
+ *
594
+ * Use this for:
595
+ * - Better Auth servers
596
+ * - Custom Hono/Express apps
597
+ * - Any backend that doesn't use gkm's endpoint builder
598
+ *
599
+ * @example './src/index.ts', './src/server.ts'
202
600
  */
203
601
  entry?: string;
204
602
 
603
+ // ─────────────────────────────────────────────────────────────────
205
604
  // Frontend-specific
206
- /** Framework for the app (frontend or backend without gkm routes) */
605
+ // ─────────────────────────────────────────────────────────────────
606
+
607
+ /**
608
+ * Framework for the app.
609
+ *
610
+ * Backend frameworks: 'hono', 'better-auth', 'express', 'fastify'
611
+ * Frontend frameworks: 'nextjs', 'remix', 'vite'
612
+ *
613
+ * @example 'nextjs', 'better-auth', 'hono'
614
+ */
207
615
  framework?: BackendFramework | FrontendFramework;
208
- /** Client generation configuration */
616
+
617
+ /**
618
+ * Client generation configuration.
619
+ * Generates typed API client from backend dependencies.
620
+ */
209
621
  client?: ClientConfig;
210
622
 
623
+ // ─────────────────────────────────────────────────────────────────
211
624
  // Deployment
625
+ // ─────────────────────────────────────────────────────────────────
626
+
212
627
  /**
213
- * Override domain for this app (per-stage or single value).
214
- * @example 'api.custom.com' or { production: 'api.custom.com', staging: 'api.staging.com' }
628
+ * Override domain for this app.
629
+ *
630
+ * By default, apps get `{appName}.{baseDomain}` (or just `{baseDomain}`
631
+ * for the main frontend). Use this to specify a custom domain.
632
+ *
633
+ * @example
634
+ * ```ts
635
+ * // Single domain for all stages
636
+ * domain: 'api.custom.com'
637
+ *
638
+ * // Stage-specific domains
639
+ * domain: {
640
+ * production: 'api.custom.com',
641
+ * staging: 'api.staging.custom.com',
642
+ * }
643
+ * ```
215
644
  */
216
645
  domain?: AppDomainConfig;
217
646
 
218
647
  /**
219
648
  * Required environment variables for entry-based apps.
649
+ *
220
650
  * Use this instead of envParser for apps that don't use gkm routes.
221
- * The deploy command uses this to filter which secrets to embed.
222
- * @example ['DATABASE_URL', 'BETTER_AUTH_SECRET']
651
+ * The deploy command uses this list to filter which secrets to embed
652
+ * in the Docker image.
653
+ *
654
+ * @example ['DATABASE_URL', 'BETTER_AUTH_SECRET', 'REDIS_URL']
223
655
  */
224
656
  requiredEnv?: string[];
225
657
  }
226
658
 
227
659
  /**
228
660
  * App configuration input with type-safe dependencies.
229
- * @template TAppNames - Union of valid app names in the workspace
661
+ *
662
+ * @template TAppNames - Union of valid app names in the workspace (auto-inferred)
663
+ *
664
+ * @example
665
+ * ```ts
666
+ * // Dependencies are type-checked against app names
667
+ * apps: {
668
+ * api: { path: 'apps/api', port: 3000 },
669
+ * auth: { path: 'apps/auth', port: 3001 },
670
+ * web: {
671
+ * path: 'apps/web',
672
+ * port: 3002,
673
+ * type: 'frontend',
674
+ * dependencies: ['api', 'auth'], // ✓ Valid
675
+ * // dependencies: ['invalid'], // ✗ Type error
676
+ * },
677
+ * }
678
+ * ```
230
679
  */
231
680
  export interface AppConfigInput<TAppNames extends string = string>
232
681
  extends AppConfigBase {
@@ -267,13 +716,49 @@ export type ConstrainedApps<TApps extends AppsRecord> = {
267
716
 
268
717
  /**
269
718
  * Full workspace input type with constrained dependencies.
719
+ *
720
+ * @example
721
+ * ```ts
722
+ * import { defineWorkspace } from '@geekmidas/cli';
723
+ *
724
+ * export default defineWorkspace({
725
+ * name: 'my-app',
726
+ * apps: {
727
+ * api: {
728
+ * path: 'apps/api',
729
+ * port: 3000,
730
+ * routes: './src/endpoints/**\/*.ts',
731
+ * },
732
+ * web: {
733
+ * type: 'frontend',
734
+ * path: 'apps/web',
735
+ * port: 3001,
736
+ * framework: 'nextjs',
737
+ * dependencies: ['api'],
738
+ * },
739
+ * },
740
+ * services: {
741
+ * db: true,
742
+ * cache: true,
743
+ * },
744
+ * deploy: {
745
+ * default: 'dokploy',
746
+ * },
747
+ * });
748
+ * ```
270
749
  */
271
750
  export type WorkspaceInput<TApps extends AppsRecord> = {
751
+ /** Workspace name (defaults to root package.json name) */
272
752
  name?: string;
753
+ /** App definitions */
273
754
  apps: ConstrainedApps<TApps>;
755
+ /** Shared packages configuration */
274
756
  shared?: SharedConfig;
757
+ /** Deployment configuration */
275
758
  deploy?: DeployConfig;
759
+ /** Development services (db, cache, mail) */
276
760
  services?: ServicesConfig;
761
+ /** Encrypted secrets configuration */
277
762
  secrets?: SecretsConfig;
278
763
  };
279
764
 
@@ -315,8 +800,79 @@ export type WorkspaceConfigInput<
315
800
  > = WorkspaceInput<T['apps']>;
316
801
 
317
802
  /**
318
- * Workspace configuration for multi-app monorepos (legacy).
319
- * @deprecated Use WorkspaceConfigInput with defineWorkspace for type inference
803
+ * Workspace configuration for multi-app monorepos.
804
+ *
805
+ * Use `defineWorkspace()` helper for type-safe configuration with
806
+ * auto-completion and dependency validation.
807
+ *
808
+ * @example
809
+ * ```ts
810
+ * // gkm.config.ts
811
+ * import { defineWorkspace } from '@geekmidas/cli';
812
+ *
813
+ * export default defineWorkspace({
814
+ * name: 'my-saas',
815
+ *
816
+ * // App definitions
817
+ * apps: {
818
+ * // Backend API with gkm routes
819
+ * api: {
820
+ * path: 'apps/api',
821
+ * port: 3000,
822
+ * routes: './src/endpoints/**\/*.ts',
823
+ * envParser: './src/config/env',
824
+ * logger: './src/config/logger',
825
+ * telescope: true,
826
+ * },
827
+ *
828
+ * // Better Auth service
829
+ * auth: {
830
+ * path: 'apps/auth',
831
+ * port: 3001,
832
+ * entry: './src/index.ts',
833
+ * framework: 'better-auth',
834
+ * requiredEnv: ['DATABASE_URL', 'BETTER_AUTH_SECRET'],
835
+ * },
836
+ *
837
+ * // Next.js frontend
838
+ * web: {
839
+ * type: 'frontend',
840
+ * path: 'apps/web',
841
+ * port: 3002,
842
+ * framework: 'nextjs',
843
+ * dependencies: ['api', 'auth'],
844
+ * },
845
+ * },
846
+ *
847
+ * // Infrastructure services
848
+ * services: {
849
+ * db: true, // PostgreSQL
850
+ * cache: true, // Redis
851
+ * },
852
+ *
853
+ * // Deployment configuration
854
+ * deploy: {
855
+ * default: 'dokploy',
856
+ * dokploy: {
857
+ * endpoint: 'https://dokploy.myserver.com',
858
+ * projectId: 'proj_abc123',
859
+ * registry: 'ghcr.io/myorg',
860
+ * domains: {
861
+ * production: 'myapp.com',
862
+ * staging: 'staging.myapp.com',
863
+ * },
864
+ * },
865
+ * },
866
+ *
867
+ * // Shared packages
868
+ * shared: {
869
+ * packages: ['packages/*'],
870
+ * models: { path: 'packages/models' },
871
+ * },
872
+ * });
873
+ * ```
874
+ *
875
+ * @deprecated Use WorkspaceInput with defineWorkspace for type inference
320
876
  */
321
877
  export interface WorkspaceConfig {
322
878
  /** Workspace name (defaults to root package.json name) */
@@ -340,11 +896,18 @@ export interface WorkspaceConfig {
340
896
 
341
897
  /**
342
898
  * Normalized app configuration with resolved defaults.
899
+ *
900
+ * This is the internal representation after processing user input.
901
+ * All optional fields have been resolved to their defaults.
343
902
  */
344
903
  export interface NormalizedAppConfig extends Omit<AppConfigBase, 'type'> {
904
+ /** App type (always defined after normalization) */
345
905
  type: 'backend' | 'frontend';
906
+ /** Path to the app */
346
907
  path: string;
908
+ /** Development server port */
347
909
  port: number;
910
+ /** Resolved dependencies array (empty array if none) */
348
911
  dependencies: string[];
349
912
  /** Resolved deploy target (app.deploy > deploy.default > 'dokploy') */
350
913
  resolvedDeployTarget: DeployTarget;
@@ -360,14 +923,24 @@ export interface NormalizedAppConfig extends Omit<AppConfigBase, 'type'> {
360
923
 
361
924
  /**
362
925
  * Normalized workspace configuration with resolved defaults.
926
+ *
927
+ * This is the internal representation after processing user input.
928
+ * All optional fields have been resolved to their defaults.
363
929
  */
364
930
  export interface NormalizedWorkspace {
931
+ /** Workspace name (resolved from package.json if not specified) */
365
932
  name: string;
933
+ /** Absolute path to workspace root */
366
934
  root: string;
935
+ /** Normalized app configurations */
367
936
  apps: Record<string, NormalizedAppConfig>;
937
+ /** Services configuration (empty object if not specified) */
368
938
  services: ServicesConfig;
939
+ /** Deploy configuration (empty object if not specified) */
369
940
  deploy: DeployConfig;
941
+ /** Shared packages configuration (empty object if not specified) */
370
942
  shared: SharedConfig;
943
+ /** Secrets configuration (empty object if not specified) */
371
944
  secrets: SecretsConfig;
372
945
  }
373
946
 
@@ -385,6 +958,15 @@ export interface LoadedConfig {
385
958
 
386
959
  /**
387
960
  * Type guard to check if a config is a WorkspaceConfig.
961
+ *
962
+ * @example
963
+ * ```ts
964
+ * const config = await loadConfig();
965
+ * if (isWorkspaceConfig(config)) {
966
+ * // config.apps is available
967
+ * console.log(Object.keys(config.apps));
968
+ * }
969
+ * ```
388
970
  */
389
971
  export function isWorkspaceConfig(
390
972
  config: GkmConfig | WorkspaceConfig,