@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.
- 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-4a6h35VY.cjs +3 -0
- package/dist/{dokploy-api-BdxOMH_V.cjs → dokploy-api-BnX2OxyF.cjs} +121 -1
- package/dist/dokploy-api-BnX2OxyF.cjs.map +1 -0
- package/dist/{dokploy-api-DWsqNjwP.mjs → dokploy-api-CMWlWq7-.mjs} +121 -1
- package/dist/dokploy-api-CMWlWq7-.mjs.map +1 -0
- package/dist/dokploy-api-DQvi9iZa.mjs +3 -0
- package/dist/{index-CXa3odEw.d.mts → index-A70abJ1m.d.mts} +598 -46
- package/dist/index-A70abJ1m.d.mts.map +1 -0
- package/dist/{index-E8Nu2Rxl.d.cts → index-pOA56MWT.d.cts} +598 -46
- package/dist/index-pOA56MWT.d.cts.map +1 -0
- package/dist/index.cjs +916 -357
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +916 -357
- 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/auth/credentials.ts +66 -0
- package/src/deploy/dns/hostinger-api.ts +258 -0
- package/src/deploy/dns/index.ts +399 -0
- package/src/deploy/dokploy-api.ts +175 -0
- package/src/deploy/index.ts +389 -240
- package/src/deploy/state.ts +146 -0
- package/src/workspace/types.ts +629 -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,57 +165,201 @@ 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
|
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
//
|
|
170
|
-
|
|
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
|
-
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Functions glob pattern for Lambda functions.
|
|
517
|
+
* @example './src/functions/**\/*.ts'
|
|
518
|
+
*/
|
|
173
519
|
functions?: Routes;
|
|
174
|
-
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Crons glob pattern for scheduled tasks.
|
|
523
|
+
* @example './src/crons/**\/*.ts'
|
|
524
|
+
*/
|
|
175
525
|
crons?: Routes;
|
|
176
|
-
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Subscribers glob pattern for event handlers.
|
|
529
|
+
* @example './src/subscribers/**\/*.ts'
|
|
530
|
+
*/
|
|
177
531
|
subscribers?: Routes;
|
|
178
|
-
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Path to environment parser module.
|
|
535
|
+
* @example './src/config/env'
|
|
536
|
+
*/
|
|
179
537
|
envParser?: string;
|
|
180
|
-
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Path to logger module.
|
|
541
|
+
* @example './src/config/logger'
|
|
542
|
+
*/
|
|
181
543
|
logger?: string;
|
|
182
|
-
|
|
544
|
+
|
|
545
|
+
/** Provider configuration (AWS, Docker, etc.) */
|
|
183
546
|
providers?: ProvidersConfig;
|
|
184
|
-
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Server lifecycle hooks.
|
|
550
|
+
* @example { beforeSetup: './src/hooks/setup.ts' }
|
|
551
|
+
*/
|
|
185
552
|
hooks?: HooksConfig;
|
|
186
|
-
|
|
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
|
-
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Studio admin panel configuration.
|
|
562
|
+
* @example true, './src/config/studio'
|
|
563
|
+
*/
|
|
189
564
|
studio?: string | boolean | StudioConfig;
|
|
190
|
-
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* OpenAPI documentation configuration.
|
|
568
|
+
* @example true, { output: './src/openapi.ts' }
|
|
569
|
+
*/
|
|
191
570
|
openapi?: boolean | OpenApiConfig;
|
|
192
|
-
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Runtime environment.
|
|
574
|
+
* @default 'node'
|
|
575
|
+
*/
|
|
193
576
|
runtime?: Runtime;
|
|
194
|
-
|
|
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
|
-
//
|
|
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
|
-
*
|
|
201
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
214
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
319
|
-
*
|
|
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,
|