@geekmidas/cli 0.45.0 → 0.46.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/{config-C0b0jdmU.mjs → config-C3LSBNSl.mjs} +2 -2
- package/dist/{config-C0b0jdmU.mjs.map → config-C3LSBNSl.mjs.map} +1 -1
- package/dist/{config-xVZsRjN7.cjs → config-HYiM3iQJ.cjs} +2 -2
- package/dist/{config-xVZsRjN7.cjs.map → config-HYiM3iQJ.cjs.map} +1 -1
- package/dist/config.cjs +2 -2
- package/dist/config.d.cts +1 -1
- package/dist/config.d.mts +1 -1
- package/dist/config.mjs +2 -2
- package/dist/dokploy-api-C1JgU9Vr.mjs +3 -0
- package/dist/dokploy-api-Cpq_tLSz.cjs +3 -0
- package/dist/{dokploy-api-BdxOMH_V.cjs → dokploy-api-D8a0eQQB.cjs} +110 -1
- package/dist/dokploy-api-D8a0eQQB.cjs.map +1 -0
- package/dist/{dokploy-api-DWsqNjwP.mjs → dokploy-api-b6usLLKk.mjs} +110 -1
- package/dist/dokploy-api-b6usLLKk.mjs.map +1 -0
- package/dist/{index-CXa3odEw.d.mts → index-BtnjoghR.d.mts} +540 -46
- package/dist/index-BtnjoghR.d.mts.map +1 -0
- package/dist/{index-E8Nu2Rxl.d.cts → index-c89X2mi2.d.cts} +540 -46
- package/dist/index-c89X2mi2.d.cts.map +1 -0
- package/dist/index.cjs +254 -135
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +254 -135
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-D3pA6FfZ.mjs → openapi-C3C-BzIZ.mjs} +2 -2
- package/dist/{openapi-D3pA6FfZ.mjs.map → openapi-C3C-BzIZ.mjs.map} +1 -1
- package/dist/{openapi-DhcCtKzM.cjs → openapi-D7WwlpPF.cjs} +2 -2
- package/dist/{openapi-DhcCtKzM.cjs.map → openapi-D7WwlpPF.cjs.map} +1 -1
- package/dist/openapi.cjs +3 -3
- package/dist/openapi.mjs +3 -3
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.d.cts +1 -1
- package/dist/workspace/index.d.mts +1 -1
- package/dist/workspace/index.mjs +1 -1
- package/dist/{workspace-BDAhr6Kb.cjs → workspace-CaVW6j2q.cjs} +10 -1
- package/dist/{workspace-BDAhr6Kb.cjs.map → workspace-CaVW6j2q.cjs.map} +1 -1
- package/dist/{workspace-D_6ZCaR_.mjs → workspace-DLFRaDc-.mjs} +10 -1
- package/dist/{workspace-D_6ZCaR_.mjs.map → workspace-DLFRaDc-.mjs.map} +1 -1
- package/package.json +3 -3
- package/src/deploy/dokploy-api.ts +163 -0
- package/src/deploy/index.ts +313 -233
- package/src/deploy/state.ts +146 -0
- package/src/workspace/types.ts +566 -47
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/dokploy-api-Bdmk5ImW.cjs +0 -3
- package/dist/dokploy-api-BdxOMH_V.cjs.map +0 -1
- package/dist/dokploy-api-DWsqNjwP.mjs.map +0 -1
- package/dist/dokploy-api-tZSZaHd9.mjs +0 -3
- package/dist/index-CXa3odEw.d.mts.map +0 -1
- package/dist/index-E8Nu2Rxl.d.cts.map +0 -1
package/src/workspace/types.ts
CHANGED
|
@@ -11,23 +11,78 @@ import type {
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Deploy target for an app.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
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,44 +165,112 @@ export interface ServicesConfig {
|
|
|
63
165
|
|
|
64
166
|
/**
|
|
65
167
|
* Stage-based domain configuration.
|
|
66
|
-
*
|
|
67
|
-
*
|
|
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
|
-
*
|
|
74
|
-
*
|
|
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 (
|
|
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
|
|
|
99
248
|
/**
|
|
100
249
|
* Deployment configuration for the workspace.
|
|
250
|
+
*
|
|
251
|
+
* @example
|
|
252
|
+
* ```ts
|
|
253
|
+
* // Minimal - just set default target
|
|
254
|
+
* deploy: {
|
|
255
|
+
* default: 'dokploy',
|
|
256
|
+
* }
|
|
257
|
+
*
|
|
258
|
+
* // Full Dokploy configuration
|
|
259
|
+
* deploy: {
|
|
260
|
+
* default: 'dokploy',
|
|
261
|
+
* dokploy: {
|
|
262
|
+
* endpoint: 'https://dokploy.myserver.com',
|
|
263
|
+
* projectId: 'proj_abc123',
|
|
264
|
+
* registry: 'ghcr.io/myorg',
|
|
265
|
+
* domains: {
|
|
266
|
+
* production: 'myapp.com',
|
|
267
|
+
* },
|
|
268
|
+
* },
|
|
269
|
+
* }
|
|
270
|
+
* ```
|
|
101
271
|
*/
|
|
102
272
|
export interface DeployConfig {
|
|
103
|
-
/** Default deploy target for all apps */
|
|
273
|
+
/** Default deploy target for all apps (default: 'dokploy') */
|
|
104
274
|
default?: DeployTarget;
|
|
105
275
|
/** Dokploy-specific configuration */
|
|
106
276
|
dokploy?: DokployWorkspaceConfig;
|
|
@@ -108,12 +278,25 @@ export interface DeployConfig {
|
|
|
108
278
|
|
|
109
279
|
/**
|
|
110
280
|
* Models package configuration for shared schemas.
|
|
281
|
+
*
|
|
282
|
+
* Configures a shared models package containing Zod schemas
|
|
283
|
+
* that can be used across backend and frontend apps.
|
|
284
|
+
*
|
|
285
|
+
* @example
|
|
286
|
+
* ```ts
|
|
287
|
+
* shared: {
|
|
288
|
+
* models: {
|
|
289
|
+
* path: 'packages/models',
|
|
290
|
+
* schema: 'zod',
|
|
291
|
+
* },
|
|
292
|
+
* }
|
|
293
|
+
* ```
|
|
111
294
|
*/
|
|
112
295
|
export interface ModelsConfig {
|
|
113
|
-
/** Path to models package (default: packages/models) */
|
|
296
|
+
/** Path to models package relative to workspace root (default: 'packages/models') */
|
|
114
297
|
path?: string;
|
|
115
298
|
/**
|
|
116
|
-
* Schema library to use.
|
|
299
|
+
* Schema library to use (default: 'zod').
|
|
117
300
|
* Currently only 'zod' is supported.
|
|
118
301
|
* Future: any StandardSchema-compatible library
|
|
119
302
|
*/
|
|
@@ -122,6 +305,20 @@ export interface ModelsConfig {
|
|
|
122
305
|
|
|
123
306
|
/**
|
|
124
307
|
* Shared packages configuration.
|
|
308
|
+
*
|
|
309
|
+
* Configures shared packages in the monorepo that are
|
|
310
|
+
* used by multiple apps.
|
|
311
|
+
*
|
|
312
|
+
* @example
|
|
313
|
+
* ```ts
|
|
314
|
+
* shared: {
|
|
315
|
+
* packages: ['packages/*', 'libs/*'],
|
|
316
|
+
* models: {
|
|
317
|
+
* path: 'packages/models',
|
|
318
|
+
* schema: 'zod',
|
|
319
|
+
* },
|
|
320
|
+
* }
|
|
321
|
+
* ```
|
|
125
322
|
*/
|
|
126
323
|
export interface SharedConfig {
|
|
127
324
|
/** Glob patterns for shared packages (default: ['packages/*']) */
|
|
@@ -132,18 +329,46 @@ export interface SharedConfig {
|
|
|
132
329
|
|
|
133
330
|
/**
|
|
134
331
|
* Secrets encryption configuration.
|
|
332
|
+
*
|
|
333
|
+
* Configures how secrets are encrypted for deployment.
|
|
334
|
+
* Secrets are stored encrypted in `.gkm/secrets/{stage}.json`
|
|
335
|
+
* with keys stored separately in `~/.gkm/{project}/{stage}.key`.
|
|
336
|
+
*
|
|
337
|
+
* @example
|
|
338
|
+
* ```ts
|
|
339
|
+
* secrets: {
|
|
340
|
+
* enabled: true,
|
|
341
|
+
* algorithm: 'aes-256-gcm',
|
|
342
|
+
* kdf: 'scrypt',
|
|
343
|
+
* }
|
|
344
|
+
* ```
|
|
135
345
|
*/
|
|
136
346
|
export interface SecretsConfig {
|
|
137
|
-
/** Enable encrypted secrets */
|
|
347
|
+
/** Enable encrypted secrets (default: true) */
|
|
138
348
|
enabled?: boolean;
|
|
139
|
-
/** Encryption algorithm (default: aes-256-gcm) */
|
|
349
|
+
/** Encryption algorithm (default: 'aes-256-gcm') */
|
|
140
350
|
algorithm?: string;
|
|
141
|
-
/** Key derivation function (default: scrypt) */
|
|
351
|
+
/** Key derivation function (default: 'scrypt') */
|
|
142
352
|
kdf?: 'scrypt' | 'pbkdf2';
|
|
143
353
|
}
|
|
144
354
|
|
|
145
355
|
/**
|
|
146
356
|
* Client generation configuration for frontend apps.
|
|
357
|
+
*
|
|
358
|
+
* Configures automatic API client generation from OpenAPI specs.
|
|
359
|
+
*
|
|
360
|
+
* @example
|
|
361
|
+
* ```ts
|
|
362
|
+
* // In a frontend app config
|
|
363
|
+
* {
|
|
364
|
+
* type: 'frontend',
|
|
365
|
+
* framework: 'nextjs',
|
|
366
|
+
* dependencies: ['api'],
|
|
367
|
+
* client: {
|
|
368
|
+
* output: './src/lib/api',
|
|
369
|
+
* },
|
|
370
|
+
* }
|
|
371
|
+
* ```
|
|
147
372
|
*/
|
|
148
373
|
export interface ClientConfig {
|
|
149
374
|
/** Output directory for generated client (relative to app path) */
|
|
@@ -152,81 +377,242 @@ export interface ClientConfig {
|
|
|
152
377
|
|
|
153
378
|
/**
|
|
154
379
|
* Base app configuration properties (shared between input and normalized).
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* ```ts
|
|
383
|
+
* // Backend app with gkm routes
|
|
384
|
+
* api: {
|
|
385
|
+
* type: 'backend',
|
|
386
|
+
* path: 'apps/api',
|
|
387
|
+
* port: 3000,
|
|
388
|
+
* routes: './src/endpoints/**\/*.ts',
|
|
389
|
+
* envParser: './src/config/env',
|
|
390
|
+
* logger: './src/config/logger',
|
|
391
|
+
* }
|
|
392
|
+
*
|
|
393
|
+
* // Backend app with entry point (e.g., Better Auth)
|
|
394
|
+
* auth: {
|
|
395
|
+
* type: 'backend',
|
|
396
|
+
* path: 'apps/auth',
|
|
397
|
+
* port: 3001,
|
|
398
|
+
* entry: './src/index.ts',
|
|
399
|
+
* framework: 'better-auth',
|
|
400
|
+
* requiredEnv: ['DATABASE_URL', 'BETTER_AUTH_SECRET'],
|
|
401
|
+
* }
|
|
402
|
+
*
|
|
403
|
+
* // Frontend app
|
|
404
|
+
* web: {
|
|
405
|
+
* type: 'frontend',
|
|
406
|
+
* path: 'apps/web',
|
|
407
|
+
* port: 3002,
|
|
408
|
+
* framework: 'nextjs',
|
|
409
|
+
* dependencies: ['api', 'auth'],
|
|
410
|
+
* }
|
|
411
|
+
* ```
|
|
155
412
|
*/
|
|
156
413
|
interface AppConfigBase {
|
|
157
|
-
/**
|
|
414
|
+
/**
|
|
415
|
+
* App type.
|
|
416
|
+
* - 'backend': Server-side app (API, auth service, etc.)
|
|
417
|
+
* - 'frontend': Client-side app (Next.js, Vite, etc.)
|
|
418
|
+
* @default 'backend'
|
|
419
|
+
*/
|
|
158
420
|
type?: 'backend' | 'frontend';
|
|
159
421
|
|
|
160
|
-
/**
|
|
422
|
+
/**
|
|
423
|
+
* Path to the app relative to workspace root.
|
|
424
|
+
* @example 'apps/api', 'apps/web', 'services/auth'
|
|
425
|
+
*/
|
|
161
426
|
path: string;
|
|
162
427
|
|
|
163
|
-
/**
|
|
428
|
+
/**
|
|
429
|
+
* Development server port.
|
|
430
|
+
* Must be unique across all apps in the workspace.
|
|
431
|
+
* @example 3000, 3001, 3002
|
|
432
|
+
*/
|
|
164
433
|
port: number;
|
|
165
434
|
|
|
166
|
-
/**
|
|
435
|
+
/**
|
|
436
|
+
* Per-app deploy target override.
|
|
437
|
+
* Overrides `deploy.default` for this specific app.
|
|
438
|
+
* @example 'dokploy', 'vercel'
|
|
439
|
+
*/
|
|
167
440
|
deploy?: DeployTarget;
|
|
168
441
|
|
|
169
|
-
//
|
|
170
|
-
|
|
442
|
+
// ─────────────────────────────────────────────────────────────────
|
|
443
|
+
// Backend-specific (gkm routes mode)
|
|
444
|
+
// ─────────────────────────────────────────────────────────────────
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Routes glob pattern for gkm endpoints.
|
|
448
|
+
* @example './src/endpoints/**\/*.ts'
|
|
449
|
+
*/
|
|
171
450
|
routes?: Routes;
|
|
172
|
-
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Functions glob pattern for Lambda functions.
|
|
454
|
+
* @example './src/functions/**\/*.ts'
|
|
455
|
+
*/
|
|
173
456
|
functions?: Routes;
|
|
174
|
-
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Crons glob pattern for scheduled tasks.
|
|
460
|
+
* @example './src/crons/**\/*.ts'
|
|
461
|
+
*/
|
|
175
462
|
crons?: Routes;
|
|
176
|
-
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Subscribers glob pattern for event handlers.
|
|
466
|
+
* @example './src/subscribers/**\/*.ts'
|
|
467
|
+
*/
|
|
177
468
|
subscribers?: Routes;
|
|
178
|
-
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Path to environment parser module.
|
|
472
|
+
* @example './src/config/env'
|
|
473
|
+
*/
|
|
179
474
|
envParser?: string;
|
|
180
|
-
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Path to logger module.
|
|
478
|
+
* @example './src/config/logger'
|
|
479
|
+
*/
|
|
181
480
|
logger?: string;
|
|
182
|
-
|
|
481
|
+
|
|
482
|
+
/** Provider configuration (AWS, Docker, etc.) */
|
|
183
483
|
providers?: ProvidersConfig;
|
|
184
|
-
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Server lifecycle hooks.
|
|
487
|
+
* @example { beforeSetup: './src/hooks/setup.ts' }
|
|
488
|
+
*/
|
|
185
489
|
hooks?: HooksConfig;
|
|
186
|
-
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Telescope debugging dashboard configuration.
|
|
493
|
+
* @example true, './src/config/telescope', { enabled: true, path: '/__telescope' }
|
|
494
|
+
*/
|
|
187
495
|
telescope?: string | boolean | TelescopeConfig;
|
|
188
|
-
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* Studio admin panel configuration.
|
|
499
|
+
* @example true, './src/config/studio'
|
|
500
|
+
*/
|
|
189
501
|
studio?: string | boolean | StudioConfig;
|
|
190
|
-
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* OpenAPI documentation configuration.
|
|
505
|
+
* @example true, { output: './src/openapi.ts' }
|
|
506
|
+
*/
|
|
191
507
|
openapi?: boolean | OpenApiConfig;
|
|
192
|
-
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Runtime environment.
|
|
511
|
+
* @default 'node'
|
|
512
|
+
*/
|
|
193
513
|
runtime?: Runtime;
|
|
194
|
-
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Environment file(s) to load during development.
|
|
517
|
+
* @example '.env', ['.env', '.env.local']
|
|
518
|
+
*/
|
|
195
519
|
env?: string | string[];
|
|
196
520
|
|
|
197
|
-
//
|
|
521
|
+
// ─────────────────────────────────────────────────────────────────
|
|
522
|
+
// Entry point mode (non-gkm apps)
|
|
523
|
+
// ─────────────────────────────────────────────────────────────────
|
|
524
|
+
|
|
198
525
|
/**
|
|
199
526
|
* Entry file path for apps that don't use gkm routes.
|
|
200
|
-
*
|
|
201
|
-
*
|
|
527
|
+
*
|
|
528
|
+
* When specified, the app is run directly with tsx in development
|
|
529
|
+
* and bundled with esbuild for production Docker builds.
|
|
530
|
+
*
|
|
531
|
+
* Use this for:
|
|
532
|
+
* - Better Auth servers
|
|
533
|
+
* - Custom Hono/Express apps
|
|
534
|
+
* - Any backend that doesn't use gkm's endpoint builder
|
|
535
|
+
*
|
|
536
|
+
* @example './src/index.ts', './src/server.ts'
|
|
202
537
|
*/
|
|
203
538
|
entry?: string;
|
|
204
539
|
|
|
540
|
+
// ─────────────────────────────────────────────────────────────────
|
|
205
541
|
// Frontend-specific
|
|
206
|
-
|
|
542
|
+
// ─────────────────────────────────────────────────────────────────
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Framework for the app.
|
|
546
|
+
*
|
|
547
|
+
* Backend frameworks: 'hono', 'better-auth', 'express', 'fastify'
|
|
548
|
+
* Frontend frameworks: 'nextjs', 'remix', 'vite'
|
|
549
|
+
*
|
|
550
|
+
* @example 'nextjs', 'better-auth', 'hono'
|
|
551
|
+
*/
|
|
207
552
|
framework?: BackendFramework | FrontendFramework;
|
|
208
|
-
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Client generation configuration.
|
|
556
|
+
* Generates typed API client from backend dependencies.
|
|
557
|
+
*/
|
|
209
558
|
client?: ClientConfig;
|
|
210
559
|
|
|
560
|
+
// ─────────────────────────────────────────────────────────────────
|
|
211
561
|
// Deployment
|
|
562
|
+
// ─────────────────────────────────────────────────────────────────
|
|
563
|
+
|
|
212
564
|
/**
|
|
213
|
-
* Override domain for this app
|
|
214
|
-
*
|
|
565
|
+
* Override domain for this app.
|
|
566
|
+
*
|
|
567
|
+
* By default, apps get `{appName}.{baseDomain}` (or just `{baseDomain}`
|
|
568
|
+
* for the main frontend). Use this to specify a custom domain.
|
|
569
|
+
*
|
|
570
|
+
* @example
|
|
571
|
+
* ```ts
|
|
572
|
+
* // Single domain for all stages
|
|
573
|
+
* domain: 'api.custom.com'
|
|
574
|
+
*
|
|
575
|
+
* // Stage-specific domains
|
|
576
|
+
* domain: {
|
|
577
|
+
* production: 'api.custom.com',
|
|
578
|
+
* staging: 'api.staging.custom.com',
|
|
579
|
+
* }
|
|
580
|
+
* ```
|
|
215
581
|
*/
|
|
216
582
|
domain?: AppDomainConfig;
|
|
217
583
|
|
|
218
584
|
/**
|
|
219
585
|
* Required environment variables for entry-based apps.
|
|
586
|
+
*
|
|
220
587
|
* 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
|
-
*
|
|
588
|
+
* The deploy command uses this list to filter which secrets to embed
|
|
589
|
+
* in the Docker image.
|
|
590
|
+
*
|
|
591
|
+
* @example ['DATABASE_URL', 'BETTER_AUTH_SECRET', 'REDIS_URL']
|
|
223
592
|
*/
|
|
224
593
|
requiredEnv?: string[];
|
|
225
594
|
}
|
|
226
595
|
|
|
227
596
|
/**
|
|
228
597
|
* App configuration input with type-safe dependencies.
|
|
229
|
-
*
|
|
598
|
+
*
|
|
599
|
+
* @template TAppNames - Union of valid app names in the workspace (auto-inferred)
|
|
600
|
+
*
|
|
601
|
+
* @example
|
|
602
|
+
* ```ts
|
|
603
|
+
* // Dependencies are type-checked against app names
|
|
604
|
+
* apps: {
|
|
605
|
+
* api: { path: 'apps/api', port: 3000 },
|
|
606
|
+
* auth: { path: 'apps/auth', port: 3001 },
|
|
607
|
+
* web: {
|
|
608
|
+
* path: 'apps/web',
|
|
609
|
+
* port: 3002,
|
|
610
|
+
* type: 'frontend',
|
|
611
|
+
* dependencies: ['api', 'auth'], // ✓ Valid
|
|
612
|
+
* // dependencies: ['invalid'], // ✗ Type error
|
|
613
|
+
* },
|
|
614
|
+
* }
|
|
615
|
+
* ```
|
|
230
616
|
*/
|
|
231
617
|
export interface AppConfigInput<TAppNames extends string = string>
|
|
232
618
|
extends AppConfigBase {
|
|
@@ -267,13 +653,49 @@ export type ConstrainedApps<TApps extends AppsRecord> = {
|
|
|
267
653
|
|
|
268
654
|
/**
|
|
269
655
|
* Full workspace input type with constrained dependencies.
|
|
656
|
+
*
|
|
657
|
+
* @example
|
|
658
|
+
* ```ts
|
|
659
|
+
* import { defineWorkspace } from '@geekmidas/cli';
|
|
660
|
+
*
|
|
661
|
+
* export default defineWorkspace({
|
|
662
|
+
* name: 'my-app',
|
|
663
|
+
* apps: {
|
|
664
|
+
* api: {
|
|
665
|
+
* path: 'apps/api',
|
|
666
|
+
* port: 3000,
|
|
667
|
+
* routes: './src/endpoints/**\/*.ts',
|
|
668
|
+
* },
|
|
669
|
+
* web: {
|
|
670
|
+
* type: 'frontend',
|
|
671
|
+
* path: 'apps/web',
|
|
672
|
+
* port: 3001,
|
|
673
|
+
* framework: 'nextjs',
|
|
674
|
+
* dependencies: ['api'],
|
|
675
|
+
* },
|
|
676
|
+
* },
|
|
677
|
+
* services: {
|
|
678
|
+
* db: true,
|
|
679
|
+
* cache: true,
|
|
680
|
+
* },
|
|
681
|
+
* deploy: {
|
|
682
|
+
* default: 'dokploy',
|
|
683
|
+
* },
|
|
684
|
+
* });
|
|
685
|
+
* ```
|
|
270
686
|
*/
|
|
271
687
|
export type WorkspaceInput<TApps extends AppsRecord> = {
|
|
688
|
+
/** Workspace name (defaults to root package.json name) */
|
|
272
689
|
name?: string;
|
|
690
|
+
/** App definitions */
|
|
273
691
|
apps: ConstrainedApps<TApps>;
|
|
692
|
+
/** Shared packages configuration */
|
|
274
693
|
shared?: SharedConfig;
|
|
694
|
+
/** Deployment configuration */
|
|
275
695
|
deploy?: DeployConfig;
|
|
696
|
+
/** Development services (db, cache, mail) */
|
|
276
697
|
services?: ServicesConfig;
|
|
698
|
+
/** Encrypted secrets configuration */
|
|
277
699
|
secrets?: SecretsConfig;
|
|
278
700
|
};
|
|
279
701
|
|
|
@@ -315,8 +737,79 @@ export type WorkspaceConfigInput<
|
|
|
315
737
|
> = WorkspaceInput<T['apps']>;
|
|
316
738
|
|
|
317
739
|
/**
|
|
318
|
-
* Workspace configuration for multi-app monorepos
|
|
319
|
-
*
|
|
740
|
+
* Workspace configuration for multi-app monorepos.
|
|
741
|
+
*
|
|
742
|
+
* Use `defineWorkspace()` helper for type-safe configuration with
|
|
743
|
+
* auto-completion and dependency validation.
|
|
744
|
+
*
|
|
745
|
+
* @example
|
|
746
|
+
* ```ts
|
|
747
|
+
* // gkm.config.ts
|
|
748
|
+
* import { defineWorkspace } from '@geekmidas/cli';
|
|
749
|
+
*
|
|
750
|
+
* export default defineWorkspace({
|
|
751
|
+
* name: 'my-saas',
|
|
752
|
+
*
|
|
753
|
+
* // App definitions
|
|
754
|
+
* apps: {
|
|
755
|
+
* // Backend API with gkm routes
|
|
756
|
+
* api: {
|
|
757
|
+
* path: 'apps/api',
|
|
758
|
+
* port: 3000,
|
|
759
|
+
* routes: './src/endpoints/**\/*.ts',
|
|
760
|
+
* envParser: './src/config/env',
|
|
761
|
+
* logger: './src/config/logger',
|
|
762
|
+
* telescope: true,
|
|
763
|
+
* },
|
|
764
|
+
*
|
|
765
|
+
* // Better Auth service
|
|
766
|
+
* auth: {
|
|
767
|
+
* path: 'apps/auth',
|
|
768
|
+
* port: 3001,
|
|
769
|
+
* entry: './src/index.ts',
|
|
770
|
+
* framework: 'better-auth',
|
|
771
|
+
* requiredEnv: ['DATABASE_URL', 'BETTER_AUTH_SECRET'],
|
|
772
|
+
* },
|
|
773
|
+
*
|
|
774
|
+
* // Next.js frontend
|
|
775
|
+
* web: {
|
|
776
|
+
* type: 'frontend',
|
|
777
|
+
* path: 'apps/web',
|
|
778
|
+
* port: 3002,
|
|
779
|
+
* framework: 'nextjs',
|
|
780
|
+
* dependencies: ['api', 'auth'],
|
|
781
|
+
* },
|
|
782
|
+
* },
|
|
783
|
+
*
|
|
784
|
+
* // Infrastructure services
|
|
785
|
+
* services: {
|
|
786
|
+
* db: true, // PostgreSQL
|
|
787
|
+
* cache: true, // Redis
|
|
788
|
+
* },
|
|
789
|
+
*
|
|
790
|
+
* // Deployment configuration
|
|
791
|
+
* deploy: {
|
|
792
|
+
* default: 'dokploy',
|
|
793
|
+
* dokploy: {
|
|
794
|
+
* endpoint: 'https://dokploy.myserver.com',
|
|
795
|
+
* projectId: 'proj_abc123',
|
|
796
|
+
* registry: 'ghcr.io/myorg',
|
|
797
|
+
* domains: {
|
|
798
|
+
* production: 'myapp.com',
|
|
799
|
+
* staging: 'staging.myapp.com',
|
|
800
|
+
* },
|
|
801
|
+
* },
|
|
802
|
+
* },
|
|
803
|
+
*
|
|
804
|
+
* // Shared packages
|
|
805
|
+
* shared: {
|
|
806
|
+
* packages: ['packages/*'],
|
|
807
|
+
* models: { path: 'packages/models' },
|
|
808
|
+
* },
|
|
809
|
+
* });
|
|
810
|
+
* ```
|
|
811
|
+
*
|
|
812
|
+
* @deprecated Use WorkspaceInput with defineWorkspace for type inference
|
|
320
813
|
*/
|
|
321
814
|
export interface WorkspaceConfig {
|
|
322
815
|
/** Workspace name (defaults to root package.json name) */
|
|
@@ -340,11 +833,18 @@ export interface WorkspaceConfig {
|
|
|
340
833
|
|
|
341
834
|
/**
|
|
342
835
|
* Normalized app configuration with resolved defaults.
|
|
836
|
+
*
|
|
837
|
+
* This is the internal representation after processing user input.
|
|
838
|
+
* All optional fields have been resolved to their defaults.
|
|
343
839
|
*/
|
|
344
840
|
export interface NormalizedAppConfig extends Omit<AppConfigBase, 'type'> {
|
|
841
|
+
/** App type (always defined after normalization) */
|
|
345
842
|
type: 'backend' | 'frontend';
|
|
843
|
+
/** Path to the app */
|
|
346
844
|
path: string;
|
|
845
|
+
/** Development server port */
|
|
347
846
|
port: number;
|
|
847
|
+
/** Resolved dependencies array (empty array if none) */
|
|
348
848
|
dependencies: string[];
|
|
349
849
|
/** Resolved deploy target (app.deploy > deploy.default > 'dokploy') */
|
|
350
850
|
resolvedDeployTarget: DeployTarget;
|
|
@@ -360,14 +860,24 @@ export interface NormalizedAppConfig extends Omit<AppConfigBase, 'type'> {
|
|
|
360
860
|
|
|
361
861
|
/**
|
|
362
862
|
* Normalized workspace configuration with resolved defaults.
|
|
863
|
+
*
|
|
864
|
+
* This is the internal representation after processing user input.
|
|
865
|
+
* All optional fields have been resolved to their defaults.
|
|
363
866
|
*/
|
|
364
867
|
export interface NormalizedWorkspace {
|
|
868
|
+
/** Workspace name (resolved from package.json if not specified) */
|
|
365
869
|
name: string;
|
|
870
|
+
/** Absolute path to workspace root */
|
|
366
871
|
root: string;
|
|
872
|
+
/** Normalized app configurations */
|
|
367
873
|
apps: Record<string, NormalizedAppConfig>;
|
|
874
|
+
/** Services configuration (empty object if not specified) */
|
|
368
875
|
services: ServicesConfig;
|
|
876
|
+
/** Deploy configuration (empty object if not specified) */
|
|
369
877
|
deploy: DeployConfig;
|
|
878
|
+
/** Shared packages configuration (empty object if not specified) */
|
|
370
879
|
shared: SharedConfig;
|
|
880
|
+
/** Secrets configuration (empty object if not specified) */
|
|
371
881
|
secrets: SecretsConfig;
|
|
372
882
|
}
|
|
373
883
|
|
|
@@ -385,6 +895,15 @@ export interface LoadedConfig {
|
|
|
385
895
|
|
|
386
896
|
/**
|
|
387
897
|
* Type guard to check if a config is a WorkspaceConfig.
|
|
898
|
+
*
|
|
899
|
+
* @example
|
|
900
|
+
* ```ts
|
|
901
|
+
* const config = await loadConfig();
|
|
902
|
+
* if (isWorkspaceConfig(config)) {
|
|
903
|
+
* // config.apps is available
|
|
904
|
+
* console.log(Object.keys(config.apps));
|
|
905
|
+
* }
|
|
906
|
+
* ```
|
|
388
907
|
*/
|
|
389
908
|
export function isWorkspaceConfig(
|
|
390
909
|
config: GkmConfig | WorkspaceConfig,
|