@geekmidas/cli 0.10.0 → 0.13.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 (146) hide show
  1. package/README.md +525 -0
  2. package/dist/bundler-B1qy9b-j.cjs +112 -0
  3. package/dist/bundler-B1qy9b-j.cjs.map +1 -0
  4. package/dist/bundler-DskIqW2t.mjs +111 -0
  5. package/dist/bundler-DskIqW2t.mjs.map +1 -0
  6. package/dist/{config-C9aXOHBe.cjs → config-AmInkU7k.cjs} +8 -8
  7. package/dist/config-AmInkU7k.cjs.map +1 -0
  8. package/dist/{config-BrkUalUh.mjs → config-DYULeEv8.mjs} +3 -3
  9. package/dist/config-DYULeEv8.mjs.map +1 -0
  10. package/dist/config.cjs +1 -1
  11. package/dist/config.d.cts +1 -1
  12. package/dist/config.d.mts +1 -1
  13. package/dist/config.mjs +1 -1
  14. package/dist/encryption-C8H-38Yy.mjs +42 -0
  15. package/dist/encryption-C8H-38Yy.mjs.map +1 -0
  16. package/dist/encryption-Dyf_r1h-.cjs +44 -0
  17. package/dist/encryption-Dyf_r1h-.cjs.map +1 -0
  18. package/dist/index.cjs +2123 -179
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.mjs +2141 -192
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/{openapi-CZLI4QTr.mjs → openapi-BfFlOBCG.mjs} +801 -38
  23. package/dist/openapi-BfFlOBCG.mjs.map +1 -0
  24. package/dist/{openapi-BeHLKcwP.cjs → openapi-Bt_1FDpT.cjs} +794 -31
  25. package/dist/openapi-Bt_1FDpT.cjs.map +1 -0
  26. package/dist/{openapi-react-query-o5iMi8tz.cjs → openapi-react-query-B-sNWHFU.cjs} +5 -5
  27. package/dist/openapi-react-query-B-sNWHFU.cjs.map +1 -0
  28. package/dist/{openapi-react-query-CcciaVu5.mjs → openapi-react-query-B6XTeGqS.mjs} +5 -5
  29. package/dist/openapi-react-query-B6XTeGqS.mjs.map +1 -0
  30. package/dist/openapi-react-query.cjs +1 -1
  31. package/dist/openapi-react-query.d.cts.map +1 -1
  32. package/dist/openapi-react-query.d.mts.map +1 -1
  33. package/dist/openapi-react-query.mjs +1 -1
  34. package/dist/openapi.cjs +2 -2
  35. package/dist/openapi.d.cts +1 -1
  36. package/dist/openapi.d.cts.map +1 -1
  37. package/dist/openapi.d.mts +1 -1
  38. package/dist/openapi.d.mts.map +1 -1
  39. package/dist/openapi.mjs +2 -2
  40. package/dist/storage-BOOpAF8N.cjs +5 -0
  41. package/dist/storage-Bj1E26lU.cjs +187 -0
  42. package/dist/storage-Bj1E26lU.cjs.map +1 -0
  43. package/dist/storage-kSxTjkNb.mjs +133 -0
  44. package/dist/storage-kSxTjkNb.mjs.map +1 -0
  45. package/dist/storage-tgZSUnKl.mjs +3 -0
  46. package/dist/{types-b-vwGpqc.d.cts → types-BR0M2v_c.d.mts} +100 -1
  47. package/dist/types-BR0M2v_c.d.mts.map +1 -0
  48. package/dist/{types-DXgiA1sF.d.mts → types-BhkZc-vm.d.cts} +100 -1
  49. package/dist/types-BhkZc-vm.d.cts.map +1 -0
  50. package/examples/cron-example.ts +27 -27
  51. package/examples/env.ts +27 -27
  52. package/examples/function-example.ts +31 -31
  53. package/examples/gkm.config.json +20 -20
  54. package/examples/gkm.config.ts +8 -8
  55. package/examples/gkm.minimal.config.json +5 -5
  56. package/examples/gkm.production.config.json +25 -25
  57. package/examples/logger.ts +2 -2
  58. package/package.json +6 -6
  59. package/src/__tests__/EndpointGenerator.hooks.spec.ts +191 -191
  60. package/src/__tests__/config.spec.ts +55 -55
  61. package/src/__tests__/loadEnvFiles.spec.ts +93 -93
  62. package/src/__tests__/normalizeHooksConfig.spec.ts +58 -58
  63. package/src/__tests__/openapi-react-query.spec.ts +497 -497
  64. package/src/__tests__/openapi.spec.ts +428 -428
  65. package/src/__tests__/test-helpers.ts +76 -76
  66. package/src/auth/__tests__/credentials.spec.ts +204 -0
  67. package/src/auth/__tests__/index.spec.ts +168 -0
  68. package/src/auth/credentials.ts +187 -0
  69. package/src/auth/index.ts +226 -0
  70. package/src/build/__tests__/bundler.spec.ts +444 -0
  71. package/src/build/__tests__/index-new.spec.ts +474 -474
  72. package/src/build/__tests__/manifests.spec.ts +333 -333
  73. package/src/build/bundler.ts +210 -0
  74. package/src/build/endpoint-analyzer.ts +236 -0
  75. package/src/build/handler-templates.ts +1253 -0
  76. package/src/build/index.ts +260 -179
  77. package/src/build/manifests.ts +52 -52
  78. package/src/build/providerResolver.ts +145 -145
  79. package/src/build/types.ts +64 -43
  80. package/src/config.ts +39 -39
  81. package/src/deploy/__tests__/docker.spec.ts +111 -0
  82. package/src/deploy/__tests__/dokploy.spec.ts +245 -0
  83. package/src/deploy/__tests__/init.spec.ts +662 -0
  84. package/src/deploy/docker.ts +128 -0
  85. package/src/deploy/dokploy.ts +204 -0
  86. package/src/deploy/index.ts +136 -0
  87. package/src/deploy/init.ts +484 -0
  88. package/src/deploy/types.ts +48 -0
  89. package/src/dev/__tests__/index.spec.ts +266 -266
  90. package/src/dev/index.ts +647 -601
  91. package/src/docker/__tests__/compose.spec.ts +531 -0
  92. package/src/docker/__tests__/templates.spec.ts +280 -0
  93. package/src/docker/compose.ts +273 -0
  94. package/src/docker/index.ts +230 -0
  95. package/src/docker/templates.ts +446 -0
  96. package/src/generators/CronGenerator.ts +72 -72
  97. package/src/generators/EndpointGenerator.ts +699 -398
  98. package/src/generators/FunctionGenerator.ts +84 -84
  99. package/src/generators/Generator.ts +72 -72
  100. package/src/generators/OpenApiTsGenerator.ts +577 -577
  101. package/src/generators/SubscriberGenerator.ts +124 -124
  102. package/src/generators/__tests__/CronGenerator.spec.ts +433 -433
  103. package/src/generators/__tests__/EndpointGenerator.spec.ts +532 -382
  104. package/src/generators/__tests__/FunctionGenerator.spec.ts +244 -244
  105. package/src/generators/__tests__/SubscriberGenerator.spec.ts +397 -382
  106. package/src/generators/index.ts +4 -4
  107. package/src/index.ts +623 -201
  108. package/src/init/__tests__/generators.spec.ts +334 -334
  109. package/src/init/__tests__/init.spec.ts +332 -332
  110. package/src/init/__tests__/utils.spec.ts +89 -89
  111. package/src/init/generators/config.ts +175 -175
  112. package/src/init/generators/docker.ts +41 -41
  113. package/src/init/generators/env.ts +72 -72
  114. package/src/init/generators/index.ts +1 -1
  115. package/src/init/generators/models.ts +64 -64
  116. package/src/init/generators/monorepo.ts +161 -161
  117. package/src/init/generators/package.ts +71 -71
  118. package/src/init/generators/source.ts +6 -6
  119. package/src/init/index.ts +203 -208
  120. package/src/init/templates/api.ts +115 -115
  121. package/src/init/templates/index.ts +75 -75
  122. package/src/init/templates/minimal.ts +98 -98
  123. package/src/init/templates/serverless.ts +89 -89
  124. package/src/init/templates/worker.ts +98 -98
  125. package/src/init/utils.ts +54 -56
  126. package/src/openapi-react-query.ts +194 -194
  127. package/src/openapi.ts +63 -63
  128. package/src/secrets/__tests__/encryption.spec.ts +226 -0
  129. package/src/secrets/__tests__/generator.spec.ts +319 -0
  130. package/src/secrets/__tests__/index.spec.ts +91 -0
  131. package/src/secrets/__tests__/storage.spec.ts +611 -0
  132. package/src/secrets/encryption.ts +91 -0
  133. package/src/secrets/generator.ts +164 -0
  134. package/src/secrets/index.ts +383 -0
  135. package/src/secrets/storage.ts +192 -0
  136. package/src/secrets/types.ts +53 -0
  137. package/src/types.ts +295 -176
  138. package/tsdown.config.ts +11 -8
  139. package/dist/config-BrkUalUh.mjs.map +0 -1
  140. package/dist/config-C9aXOHBe.cjs.map +0 -1
  141. package/dist/openapi-BeHLKcwP.cjs.map +0 -1
  142. package/dist/openapi-CZLI4QTr.mjs.map +0 -1
  143. package/dist/openapi-react-query-CcciaVu5.mjs.map +0 -1
  144. package/dist/openapi-react-query-o5iMi8tz.cjs.map +0 -1
  145. package/dist/types-DXgiA1sF.d.mts.map +0 -1
  146. package/dist/types-b-vwGpqc.d.cts.map +0 -1
@@ -0,0 +1,484 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { readFile, writeFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { getDokployCredentials, getDokployToken } from '../auth';
5
+ import type { DokployDeployConfig } from './types';
6
+
7
+ const logger = console;
8
+
9
+ export interface DeployInitOptions {
10
+ /** Dokploy endpoint URL (optional if logged in) */
11
+ endpoint?: string;
12
+ /** Project name (creates new or uses existing) */
13
+ projectName: string;
14
+ /** Application name */
15
+ appName: string;
16
+ /** Use existing project ID instead of creating/finding */
17
+ projectId?: string;
18
+ /** Registry ID in Dokploy (optional) */
19
+ registryId?: string;
20
+ }
21
+
22
+ interface DokployProject {
23
+ projectId: string;
24
+ name: string;
25
+ description: string | null;
26
+ createdAt: string;
27
+ adminId: string;
28
+ environments?: Array<{
29
+ environmentId: string;
30
+ name: string;
31
+ description: string | null;
32
+ }>;
33
+ }
34
+
35
+ interface DokployApplication {
36
+ applicationId: string;
37
+ name: string;
38
+ appName: string;
39
+ projectId: string;
40
+ environmentId?: string;
41
+ }
42
+
43
+ interface DokployRegistry {
44
+ registryId: string;
45
+ registryName: string;
46
+ registryUrl: string;
47
+ username: string;
48
+ imagePrefix: string | null;
49
+ }
50
+
51
+ /**
52
+ * Get the Dokploy API token from stored credentials or environment
53
+ */
54
+ async function getApiToken(): Promise<string> {
55
+ const token = await getDokployToken();
56
+ if (!token) {
57
+ throw new Error(
58
+ 'Dokploy credentials not found.\n' +
59
+ 'Run "gkm login --service dokploy" to authenticate, or set DOKPLOY_API_TOKEN.',
60
+ );
61
+ }
62
+ return token;
63
+ }
64
+
65
+ /**
66
+ * Make a request to the Dokploy API
67
+ */
68
+ async function dokployRequest<T>(
69
+ method: 'GET' | 'POST',
70
+ endpoint: string,
71
+ baseUrl: string,
72
+ token: string,
73
+ body?: Record<string, unknown>,
74
+ ): Promise<T> {
75
+ const url = `${baseUrl}/api/${endpoint}`;
76
+
77
+ const response = await fetch(url, {
78
+ method,
79
+ headers: {
80
+ 'Content-Type': 'application/json',
81
+ Authorization: `Bearer ${token}`,
82
+ },
83
+ body: body ? JSON.stringify(body) : undefined,
84
+ });
85
+
86
+ if (!response.ok) {
87
+ let errorMessage = `Dokploy API error: ${response.status} ${response.statusText}`;
88
+
89
+ try {
90
+ const errorBody = (await response.json()) as { message?: string };
91
+ if (errorBody.message) {
92
+ errorMessage = `Dokploy API error: ${errorBody.message}`;
93
+ }
94
+ } catch {
95
+ // Ignore JSON parse errors
96
+ }
97
+
98
+ throw new Error(errorMessage);
99
+ }
100
+
101
+ // Handle empty responses
102
+ const text = await response.text();
103
+ if (!text) {
104
+ return {} as T;
105
+ }
106
+
107
+ return JSON.parse(text) as T;
108
+ }
109
+
110
+ /**
111
+ * Get all projects from Dokploy
112
+ */
113
+ async function getProjects(
114
+ baseUrl: string,
115
+ token: string,
116
+ ): Promise<DokployProject[]> {
117
+ return dokployRequest<DokployProject[]>('GET', 'project.all', baseUrl, token);
118
+ }
119
+
120
+ /**
121
+ * Create a new project in Dokploy
122
+ */
123
+ async function createProject(
124
+ baseUrl: string,
125
+ token: string,
126
+ name: string,
127
+ description?: string,
128
+ ): Promise<DokployProject> {
129
+ return dokployRequest<DokployProject>(
130
+ 'POST',
131
+ 'project.create',
132
+ baseUrl,
133
+ token,
134
+ {
135
+ name,
136
+ description: description || `Created by gkm CLI`,
137
+ },
138
+ );
139
+ }
140
+
141
+ /**
142
+ * Get project by ID to get environment info
143
+ */
144
+ async function getProject(
145
+ baseUrl: string,
146
+ token: string,
147
+ projectId: string,
148
+ ): Promise<DokployProject> {
149
+ return dokployRequest<DokployProject>('POST', 'project.one', baseUrl, token, {
150
+ projectId,
151
+ });
152
+ }
153
+
154
+ /**
155
+ * Create a new application in Dokploy
156
+ */
157
+ async function createApplication(
158
+ baseUrl: string,
159
+ token: string,
160
+ name: string,
161
+ projectId: string,
162
+ ): Promise<DokployApplication> {
163
+ // First get the project to find its environment ID
164
+ const project = await getProject(baseUrl, token, projectId);
165
+
166
+ // Use the first environment or create one
167
+ let environmentId: string;
168
+
169
+ const firstEnv = project.environments?.[0];
170
+ if (firstEnv) {
171
+ environmentId = firstEnv.environmentId;
172
+ } else {
173
+ // Create a default environment
174
+ const env = await dokployRequest<{ environmentId: string }>(
175
+ 'POST',
176
+ 'environment.create',
177
+ baseUrl,
178
+ token,
179
+ {
180
+ projectId,
181
+ name: 'production',
182
+ description: 'Production environment',
183
+ },
184
+ );
185
+ environmentId = env.environmentId;
186
+ }
187
+
188
+ return dokployRequest<DokployApplication>(
189
+ 'POST',
190
+ 'application.create',
191
+ baseUrl,
192
+ token,
193
+ {
194
+ name,
195
+ projectId,
196
+ environmentId,
197
+ },
198
+ );
199
+ }
200
+
201
+ /**
202
+ * Configure application for Docker registry deployment
203
+ */
204
+ async function configureApplicationRegistry(
205
+ baseUrl: string,
206
+ token: string,
207
+ applicationId: string,
208
+ registryId: string,
209
+ ): Promise<void> {
210
+ await dokployRequest('POST', 'application.update', baseUrl, token, {
211
+ applicationId,
212
+ registryId,
213
+ });
214
+ }
215
+
216
+ /**
217
+ * Get available registries
218
+ */
219
+ async function getRegistries(
220
+ baseUrl: string,
221
+ token: string,
222
+ ): Promise<DokployRegistry[]> {
223
+ return dokployRequest<DokployRegistry[]>(
224
+ 'GET',
225
+ 'registry.all',
226
+ baseUrl,
227
+ token,
228
+ );
229
+ }
230
+
231
+ /**
232
+ * Update gkm.config.ts with Dokploy configuration
233
+ */
234
+ export async function updateConfig(
235
+ config: DokployDeployConfig,
236
+ cwd: string = process.cwd(),
237
+ ): Promise<void> {
238
+ const configPath = join(cwd, 'gkm.config.ts');
239
+
240
+ if (!existsSync(configPath)) {
241
+ logger.warn(
242
+ '\n gkm.config.ts not found. Add this configuration manually:\n',
243
+ );
244
+ logger.log(` providers: {`);
245
+ logger.log(` dokploy: {`);
246
+ logger.log(` endpoint: '${config.endpoint}',`);
247
+ logger.log(` projectId: '${config.projectId}',`);
248
+ logger.log(` applicationId: '${config.applicationId}',`);
249
+ logger.log(` },`);
250
+ logger.log(` },`);
251
+ return;
252
+ }
253
+
254
+ const content = await readFile(configPath, 'utf-8');
255
+
256
+ // Check if providers.dokploy already exists
257
+ if (content.includes('dokploy:') && content.includes('applicationId:')) {
258
+ logger.log('\n Dokploy config already exists in gkm.config.ts');
259
+ logger.log(' Updating with new values...');
260
+ }
261
+
262
+ // Try to add or update the dokploy config
263
+ let newContent: string;
264
+
265
+ if (content.includes('providers:')) {
266
+ // Add dokploy to existing providers
267
+ if (content.includes('dokploy:')) {
268
+ // Update existing dokploy config
269
+ newContent = content.replace(
270
+ /dokploy:\s*\{[^}]*\}/,
271
+ `dokploy: {
272
+ endpoint: '${config.endpoint}',
273
+ projectId: '${config.projectId}',
274
+ applicationId: '${config.applicationId}',
275
+ }`,
276
+ );
277
+ } else {
278
+ // Add dokploy to providers
279
+ newContent = content.replace(
280
+ /providers:\s*\{/,
281
+ `providers: {
282
+ dokploy: {
283
+ endpoint: '${config.endpoint}',
284
+ projectId: '${config.projectId}',
285
+ applicationId: '${config.applicationId}',
286
+ },`,
287
+ );
288
+ }
289
+ } else {
290
+ // Add providers section before the closing of defineConfig
291
+ newContent = content.replace(
292
+ /}\s*\)\s*;?\s*$/,
293
+ `
294
+ providers: {
295
+ dokploy: {
296
+ endpoint: '${config.endpoint}',
297
+ projectId: '${config.projectId}',
298
+ applicationId: '${config.applicationId}',
299
+ },
300
+ },
301
+ });`,
302
+ );
303
+ }
304
+
305
+ await writeFile(configPath, newContent);
306
+ logger.log('\n ✓ Updated gkm.config.ts with Dokploy configuration');
307
+ }
308
+
309
+ /**
310
+ * Initialize Dokploy deployment configuration
311
+ */
312
+ export async function deployInitCommand(
313
+ options: DeployInitOptions,
314
+ ): Promise<DokployDeployConfig> {
315
+ const {
316
+ projectName,
317
+ appName,
318
+ projectId: existingProjectId,
319
+ registryId,
320
+ } = options;
321
+
322
+ // Get endpoint from options or stored credentials
323
+ let endpoint = options.endpoint;
324
+ if (!endpoint) {
325
+ const stored = await getDokployCredentials();
326
+ if (stored) {
327
+ endpoint = stored.endpoint;
328
+ } else {
329
+ throw new Error(
330
+ 'Dokploy endpoint not specified.\n' +
331
+ 'Either run "gkm login --service dokploy" first, or provide --endpoint.',
332
+ );
333
+ }
334
+ }
335
+
336
+ logger.log(`\n🚀 Initializing Dokploy deployment...`);
337
+ logger.log(` Endpoint: ${endpoint}`);
338
+
339
+ const token = await getApiToken();
340
+
341
+ // Step 1: Find or create project
342
+ let projectId: string;
343
+
344
+ if (existingProjectId) {
345
+ projectId = existingProjectId;
346
+ logger.log(`\n📁 Using existing project: ${projectId}`);
347
+ } else {
348
+ logger.log(`\n📁 Looking for project: ${projectName}`);
349
+
350
+ const projects = await getProjects(endpoint, token);
351
+ const existingProject = projects.find(
352
+ (p) => p.name.toLowerCase() === projectName.toLowerCase(),
353
+ );
354
+
355
+ if (existingProject) {
356
+ projectId = existingProject.projectId;
357
+ logger.log(` Found existing project: ${projectId}`);
358
+ } else {
359
+ logger.log(` Creating new project...`);
360
+ const project = await createProject(endpoint, token, projectName);
361
+ projectId = project.projectId;
362
+ logger.log(` ✓ Created project: ${projectId}`);
363
+ }
364
+ }
365
+
366
+ // Step 2: Create application
367
+ logger.log(`\n📦 Creating application: ${appName}`);
368
+ const application = await createApplication(
369
+ endpoint,
370
+ token,
371
+ appName,
372
+ projectId,
373
+ );
374
+ logger.log(` ✓ Created application: ${application.applicationId}`);
375
+
376
+ // Step 3: Configure registry if provided
377
+ if (registryId) {
378
+ logger.log(`\n🔧 Configuring registry: ${registryId}`);
379
+ await configureApplicationRegistry(
380
+ endpoint,
381
+ token,
382
+ application.applicationId,
383
+ registryId,
384
+ );
385
+ logger.log(` ✓ Registry configured`);
386
+ } else {
387
+ // List available registries
388
+ try {
389
+ const registries = await getRegistries(endpoint, token);
390
+ if (registries.length > 0) {
391
+ logger.log(`\n📋 Available registries:`);
392
+ for (const reg of registries) {
393
+ logger.log(
394
+ ` - ${reg.registryName}: ${reg.registryUrl} (${reg.registryId})`,
395
+ );
396
+ }
397
+ logger.log(`\n To use a registry, run with --registry-id <id>`);
398
+ }
399
+ } catch {
400
+ // Ignore registry listing errors
401
+ }
402
+ }
403
+
404
+ // Step 4: Build config
405
+ const config: DokployDeployConfig = {
406
+ endpoint,
407
+ projectId,
408
+ applicationId: application.applicationId,
409
+ };
410
+
411
+ // Step 5: Update gkm.config.ts
412
+ await updateConfig(config);
413
+
414
+ logger.log(`\n✅ Dokploy deployment initialized!`);
415
+ logger.log(`\n📋 Configuration:`);
416
+ logger.log(` Project ID: ${projectId}`);
417
+ logger.log(` Application ID: ${application.applicationId}`);
418
+ logger.log(`\n🔗 View in Dokploy: ${endpoint}/project/${projectId}`);
419
+ logger.log(`\n📝 Next steps:`);
420
+ logger.log(` 1. Initialize secrets: gkm secrets:init --stage production`);
421
+ logger.log(` 2. Deploy: gkm deploy --provider dokploy --stage production`);
422
+
423
+ return config;
424
+ }
425
+
426
+ /**
427
+ * List available Dokploy resources
428
+ */
429
+ export async function deployListCommand(options: {
430
+ endpoint?: string;
431
+ resource: 'projects' | 'registries';
432
+ }): Promise<void> {
433
+ // Get endpoint from options or stored credentials
434
+ let endpoint = options.endpoint;
435
+ if (!endpoint) {
436
+ const stored = await getDokployCredentials();
437
+ if (stored) {
438
+ endpoint = stored.endpoint;
439
+ } else {
440
+ throw new Error(
441
+ 'Dokploy endpoint not specified.\n' +
442
+ 'Either run "gkm login --service dokploy" first, or provide --endpoint.',
443
+ );
444
+ }
445
+ }
446
+
447
+ const { resource } = options;
448
+ const token = await getApiToken();
449
+
450
+ if (resource === 'projects') {
451
+ logger.log(`\n📁 Projects in ${endpoint}:`);
452
+ const projects = await getProjects(endpoint, token);
453
+
454
+ if (projects.length === 0) {
455
+ logger.log(' No projects found');
456
+ return;
457
+ }
458
+
459
+ for (const project of projects) {
460
+ logger.log(`\n ${project.name} (${project.projectId})`);
461
+ if (project.description) {
462
+ logger.log(` ${project.description}`);
463
+ }
464
+ }
465
+ } else if (resource === 'registries') {
466
+ logger.log(`\n🐳 Registries in ${endpoint}:`);
467
+ const registries = await getRegistries(endpoint, token);
468
+
469
+ if (registries.length === 0) {
470
+ logger.log(' No registries configured');
471
+ logger.log(' Add a registry in Dokploy: Settings > Docker Registry');
472
+ return;
473
+ }
474
+
475
+ for (const registry of registries) {
476
+ logger.log(`\n ${registry.registryName} (${registry.registryId})`);
477
+ logger.log(` URL: ${registry.registryUrl}`);
478
+ logger.log(` Username: ${registry.username}`);
479
+ if (registry.imagePrefix) {
480
+ logger.log(` Prefix: ${registry.imagePrefix}`);
481
+ }
482
+ }
483
+ }
484
+ }
@@ -0,0 +1,48 @@
1
+ /** Supported deploy providers */
2
+ export type DeployProvider = 'docker' | 'dokploy' | 'aws-lambda';
3
+
4
+ /** Options for the deploy command */
5
+ export interface DeployOptions {
6
+ /** Deploy provider */
7
+ provider: DeployProvider;
8
+ /** Deployment stage (e.g., 'production', 'staging') */
9
+ stage: string;
10
+ /** Image tag (default: stage-timestamp) */
11
+ tag?: string;
12
+ /** Skip pushing image to registry */
13
+ skipPush?: boolean;
14
+ /** Skip building (use existing build) */
15
+ skipBuild?: boolean;
16
+ }
17
+
18
+ /** Result from a deployment */
19
+ export interface DeployResult {
20
+ /** Docker image reference (if applicable) */
21
+ imageRef?: string;
22
+ /** Ephemeral master key for GKM_MASTER_KEY */
23
+ masterKey?: string;
24
+ /** Deployment ID (for Dokploy) */
25
+ deploymentId?: string;
26
+ /** Deployment URL (if available) */
27
+ url?: string;
28
+ }
29
+
30
+ /** Docker provider configuration */
31
+ export interface DockerDeployConfig {
32
+ /** Container registry URL */
33
+ registry?: string;
34
+ /** Image name (default: from package.json) */
35
+ imageName?: string;
36
+ }
37
+
38
+ /** Dokploy provider configuration */
39
+ export interface DokployDeployConfig {
40
+ /** Dokploy API endpoint */
41
+ endpoint: string;
42
+ /** Project ID in Dokploy */
43
+ projectId: string;
44
+ /** Application ID in Dokploy */
45
+ applicationId: string;
46
+ /** Container registry (inherits from docker if not set) */
47
+ registry?: string;
48
+ }