@geekmidas/cli 0.12.0 → 0.14.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/bundler-BjholBlA.cjs +131 -0
- package/dist/bundler-BjholBlA.cjs.map +1 -0
- package/dist/bundler-DWctKN1z.mjs +130 -0
- package/dist/bundler-DWctKN1z.mjs.map +1 -0
- package/dist/config.d.cts +1 -1
- package/dist/config.d.mts +1 -1
- package/dist/dokploy-api-B7KxOQr3.cjs +3 -0
- package/dist/dokploy-api-C7F9VykY.cjs +317 -0
- package/dist/dokploy-api-C7F9VykY.cjs.map +1 -0
- package/dist/dokploy-api-CaETb2L6.mjs +305 -0
- package/dist/dokploy-api-CaETb2L6.mjs.map +1 -0
- package/dist/dokploy-api-DHvfmWbi.mjs +3 -0
- package/dist/{encryption-Dyf_r1h-.cjs → encryption-D7Efcdi9.cjs} +1 -1
- package/dist/{encryption-Dyf_r1h-.cjs.map → encryption-D7Efcdi9.cjs.map} +1 -1
- package/dist/{encryption-C8H-38Yy.mjs → encryption-h4Nb6W-M.mjs} +1 -1
- package/dist/{encryption-C8H-38Yy.mjs.map → encryption-h4Nb6W-M.mjs.map} +1 -1
- package/dist/index.cjs +1520 -1136
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1520 -1136
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-Bt_1FDpT.cjs → openapi-C89hhkZC.cjs} +3 -3
- package/dist/{openapi-Bt_1FDpT.cjs.map → openapi-C89hhkZC.cjs.map} +1 -1
- package/dist/{openapi-BfFlOBCG.mjs → openapi-CZVcfxk-.mjs} +3 -3
- package/dist/{openapi-BfFlOBCG.mjs.map → openapi-CZVcfxk-.mjs.map} +1 -1
- package/dist/{openapi-react-query-B6XTeGqS.mjs → openapi-react-query-CM2_qlW9.mjs} +1 -1
- package/dist/{openapi-react-query-B6XTeGqS.mjs.map → openapi-react-query-CM2_qlW9.mjs.map} +1 -1
- package/dist/{openapi-react-query-B-sNWHFU.cjs → openapi-react-query-iKjfLzff.cjs} +1 -1
- package/dist/{openapi-react-query-B-sNWHFU.cjs.map → openapi-react-query-iKjfLzff.cjs.map} +1 -1
- package/dist/openapi-react-query.cjs +1 -1
- package/dist/openapi-react-query.mjs +1 -1
- package/dist/openapi.cjs +1 -1
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.mjs +1 -1
- package/dist/{storage-C9PU_30f.mjs → storage-BaOP55oq.mjs} +48 -2
- package/dist/storage-BaOP55oq.mjs.map +1 -0
- package/dist/{storage-BXoJvmv2.cjs → storage-Bn3K9Ccu.cjs} +59 -1
- package/dist/storage-Bn3K9Ccu.cjs.map +1 -0
- package/dist/storage-UfyTn7Zm.cjs +7 -0
- package/dist/storage-nkGIjeXt.mjs +3 -0
- package/dist/{types-BR0M2v_c.d.mts → types-BgaMXsUa.d.cts} +3 -1
- package/dist/{types-BR0M2v_c.d.mts.map → types-BgaMXsUa.d.cts.map} +1 -1
- package/dist/{types-BhkZc-vm.d.cts → types-iFk5ms7y.d.mts} +3 -1
- package/dist/{types-BhkZc-vm.d.cts.map → types-iFk5ms7y.d.mts.map} +1 -1
- package/package.json +4 -4
- package/src/auth/__tests__/credentials.spec.ts +127 -0
- package/src/auth/__tests__/index.spec.ts +69 -0
- package/src/auth/credentials.ts +33 -0
- package/src/auth/index.ts +57 -50
- package/src/build/__tests__/bundler.spec.ts +444 -0
- package/src/build/__tests__/endpoint-analyzer.spec.ts +623 -0
- package/src/build/__tests__/handler-templates.spec.ts +272 -0
- package/src/build/bundler.ts +126 -8
- package/src/build/index.ts +31 -0
- package/src/build/types.ts +6 -0
- package/src/deploy/__tests__/dokploy-api.spec.ts +698 -0
- package/src/deploy/__tests__/dokploy.spec.ts +196 -6
- package/src/deploy/__tests__/index.spec.ts +339 -0
- package/src/deploy/__tests__/init.spec.ts +147 -16
- package/src/deploy/docker.ts +32 -3
- package/src/deploy/dokploy-api.ts +581 -0
- package/src/deploy/dokploy.ts +66 -93
- package/src/deploy/index.ts +587 -32
- package/src/deploy/init.ts +192 -249
- package/src/deploy/types.ts +19 -1
- package/src/dev/__tests__/index.spec.ts +95 -0
- package/src/docker/__tests__/templates.spec.ts +144 -0
- package/src/docker/index.ts +96 -6
- package/src/docker/templates.ts +114 -27
- package/src/generators/EndpointGenerator.ts +2 -2
- package/src/index.ts +34 -13
- package/src/secrets/__tests__/storage.spec.ts +208 -0
- package/src/secrets/storage.ts +73 -0
- package/src/types.ts +2 -0
- package/dist/bundler-DRXCw_YR.mjs +0 -70
- package/dist/bundler-DRXCw_YR.mjs.map +0 -1
- package/dist/bundler-WsEvH_b2.cjs +0 -71
- package/dist/bundler-WsEvH_b2.cjs.map +0 -1
- package/dist/storage-BUYQJgz7.cjs +0 -4
- package/dist/storage-BXoJvmv2.cjs.map +0 -1
- package/dist/storage-C9PU_30f.mjs.map +0 -1
- package/dist/storage-DLJAYxzJ.mjs +0 -3
|
@@ -41,7 +41,7 @@ describe('Dokploy API interactions', () => {
|
|
|
41
41
|
method: 'GET',
|
|
42
42
|
headers: {
|
|
43
43
|
'Content-Type': 'application/json',
|
|
44
|
-
|
|
44
|
+
'x-api-key': 'test-token',
|
|
45
45
|
},
|
|
46
46
|
},
|
|
47
47
|
);
|
|
@@ -62,11 +62,18 @@ describe('Dokploy API interactions', () => {
|
|
|
62
62
|
description?: string;
|
|
63
63
|
};
|
|
64
64
|
return HttpResponse.json({
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
project: {
|
|
66
|
+
projectId: 'proj_new',
|
|
67
|
+
name: body.name,
|
|
68
|
+
description: body.description || null,
|
|
69
|
+
createdAt: new Date().toISOString(),
|
|
70
|
+
adminId: 'admin_1',
|
|
71
|
+
},
|
|
72
|
+
environment: {
|
|
73
|
+
environmentId: 'env_default',
|
|
74
|
+
name: 'production',
|
|
75
|
+
description: 'Production environment',
|
|
76
|
+
},
|
|
70
77
|
});
|
|
71
78
|
},
|
|
72
79
|
),
|
|
@@ -78,7 +85,7 @@ describe('Dokploy API interactions', () => {
|
|
|
78
85
|
method: 'POST',
|
|
79
86
|
headers: {
|
|
80
87
|
'Content-Type': 'application/json',
|
|
81
|
-
|
|
88
|
+
'x-api-key': 'test-token',
|
|
82
89
|
},
|
|
83
90
|
body: JSON.stringify({
|
|
84
91
|
name: 'New Project',
|
|
@@ -88,9 +95,10 @@ describe('Dokploy API interactions', () => {
|
|
|
88
95
|
);
|
|
89
96
|
|
|
90
97
|
expect(response.ok).toBe(true);
|
|
91
|
-
const
|
|
92
|
-
expect(project.projectId).toBe('proj_new');
|
|
93
|
-
expect(project.name).toBe('New Project');
|
|
98
|
+
const result = await response.json();
|
|
99
|
+
expect(result.project.projectId).toBe('proj_new');
|
|
100
|
+
expect(result.project.name).toBe('New Project');
|
|
101
|
+
expect(result.environment.environmentId).toBe('env_default');
|
|
94
102
|
});
|
|
95
103
|
|
|
96
104
|
it('should get a single project', async () => {
|
|
@@ -120,7 +128,7 @@ describe('Dokploy API interactions', () => {
|
|
|
120
128
|
method: 'POST',
|
|
121
129
|
headers: {
|
|
122
130
|
'Content-Type': 'application/json',
|
|
123
|
-
|
|
131
|
+
'x-api-key': 'test-token',
|
|
124
132
|
},
|
|
125
133
|
body: JSON.stringify({ projectId: 'proj_1' }),
|
|
126
134
|
},
|
|
@@ -159,7 +167,7 @@ describe('Dokploy API interactions', () => {
|
|
|
159
167
|
method: 'POST',
|
|
160
168
|
headers: {
|
|
161
169
|
'Content-Type': 'application/json',
|
|
162
|
-
|
|
170
|
+
'x-api-key': 'test-token',
|
|
163
171
|
},
|
|
164
172
|
body: JSON.stringify({
|
|
165
173
|
name: 'api',
|
|
@@ -194,7 +202,7 @@ describe('Dokploy API interactions', () => {
|
|
|
194
202
|
method: 'POST',
|
|
195
203
|
headers: {
|
|
196
204
|
'Content-Type': 'application/json',
|
|
197
|
-
|
|
205
|
+
'x-api-key': 'test-token',
|
|
198
206
|
},
|
|
199
207
|
body: JSON.stringify({
|
|
200
208
|
applicationId: 'app_1',
|
|
@@ -229,7 +237,7 @@ describe('Dokploy API interactions', () => {
|
|
|
229
237
|
method: 'GET',
|
|
230
238
|
headers: {
|
|
231
239
|
'Content-Type': 'application/json',
|
|
232
|
-
|
|
240
|
+
'x-api-key': 'test-token',
|
|
233
241
|
},
|
|
234
242
|
},
|
|
235
243
|
);
|
|
@@ -265,7 +273,7 @@ describe('Dokploy API interactions', () => {
|
|
|
265
273
|
method: 'POST',
|
|
266
274
|
headers: {
|
|
267
275
|
'Content-Type': 'application/json',
|
|
268
|
-
|
|
276
|
+
'x-api-key': 'test-token',
|
|
269
277
|
},
|
|
270
278
|
body: JSON.stringify({
|
|
271
279
|
projectId: 'proj_1',
|
|
@@ -298,7 +306,7 @@ describe('Dokploy API interactions', () => {
|
|
|
298
306
|
method: 'GET',
|
|
299
307
|
headers: {
|
|
300
308
|
'Content-Type': 'application/json',
|
|
301
|
-
|
|
309
|
+
'x-api-key': 'invalid-token',
|
|
302
310
|
},
|
|
303
311
|
},
|
|
304
312
|
);
|
|
@@ -659,4 +667,127 @@ export default defineConfig({
|
|
|
659
667
|
),
|
|
660
668
|
).resolves.toBeUndefined();
|
|
661
669
|
});
|
|
670
|
+
|
|
671
|
+
it('should include registryId when provided', async () => {
|
|
672
|
+
const configPath = join(tempDir, 'gkm.config.ts');
|
|
673
|
+
await writeFile(
|
|
674
|
+
configPath,
|
|
675
|
+
`import { defineConfig } from '@geekmidas/cli';
|
|
676
|
+
|
|
677
|
+
export default defineConfig({
|
|
678
|
+
routes: 'src/endpoints/**/*.ts',
|
|
679
|
+
envParser: './src/env.ts',
|
|
680
|
+
});`,
|
|
681
|
+
);
|
|
682
|
+
|
|
683
|
+
await updateConfig(
|
|
684
|
+
{
|
|
685
|
+
endpoint: 'https://dokploy.example.com',
|
|
686
|
+
projectId: 'proj_123',
|
|
687
|
+
applicationId: 'app_456',
|
|
688
|
+
registryId: 'reg_789',
|
|
689
|
+
},
|
|
690
|
+
tempDir,
|
|
691
|
+
);
|
|
692
|
+
|
|
693
|
+
const content = await readFile(configPath, 'utf-8');
|
|
694
|
+
expect(content).toContain("registryId: 'reg_789'");
|
|
695
|
+
expect(content).toContain("endpoint: 'https://dokploy.example.com'");
|
|
696
|
+
expect(content).toContain("projectId: 'proj_123'");
|
|
697
|
+
expect(content).toContain("applicationId: 'app_456'");
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
it('should omit registryId when not provided', async () => {
|
|
701
|
+
const configPath = join(tempDir, 'gkm.config.ts');
|
|
702
|
+
await writeFile(
|
|
703
|
+
configPath,
|
|
704
|
+
`import { defineConfig } from '@geekmidas/cli';
|
|
705
|
+
|
|
706
|
+
export default defineConfig({
|
|
707
|
+
routes: 'src/endpoints/**/*.ts',
|
|
708
|
+
});`,
|
|
709
|
+
);
|
|
710
|
+
|
|
711
|
+
await updateConfig(
|
|
712
|
+
{
|
|
713
|
+
endpoint: 'https://dokploy.example.com',
|
|
714
|
+
projectId: 'proj_123',
|
|
715
|
+
applicationId: 'app_456',
|
|
716
|
+
},
|
|
717
|
+
tempDir,
|
|
718
|
+
);
|
|
719
|
+
|
|
720
|
+
const content = await readFile(configPath, 'utf-8');
|
|
721
|
+
expect(content).not.toContain('registryId:');
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
it('should update existing dokploy config with registryId', async () => {
|
|
725
|
+
const configPath = join(tempDir, 'gkm.config.ts');
|
|
726
|
+
await writeFile(
|
|
727
|
+
configPath,
|
|
728
|
+
`import { defineConfig } from '@geekmidas/cli';
|
|
729
|
+
|
|
730
|
+
export default defineConfig({
|
|
731
|
+
routes: 'src/endpoints/**/*.ts',
|
|
732
|
+
providers: {
|
|
733
|
+
dokploy: {
|
|
734
|
+
endpoint: 'https://old.dokploy.com',
|
|
735
|
+
projectId: 'old_proj',
|
|
736
|
+
applicationId: 'old_app',
|
|
737
|
+
},
|
|
738
|
+
},
|
|
739
|
+
});`,
|
|
740
|
+
);
|
|
741
|
+
|
|
742
|
+
await updateConfig(
|
|
743
|
+
{
|
|
744
|
+
endpoint: 'https://new.dokploy.com',
|
|
745
|
+
projectId: 'new_proj',
|
|
746
|
+
applicationId: 'new_app',
|
|
747
|
+
registryId: 'new_reg',
|
|
748
|
+
},
|
|
749
|
+
tempDir,
|
|
750
|
+
);
|
|
751
|
+
|
|
752
|
+
const content = await readFile(configPath, 'utf-8');
|
|
753
|
+
expect(content).toContain("registryId: 'new_reg'");
|
|
754
|
+
expect(content).toContain("endpoint: 'https://new.dokploy.com'");
|
|
755
|
+
expect(content).not.toContain('old.dokploy.com');
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
it('should preserve existing config with multi-line dokploy that has registryId', async () => {
|
|
759
|
+
const configPath = join(tempDir, 'gkm.config.ts');
|
|
760
|
+
await writeFile(
|
|
761
|
+
configPath,
|
|
762
|
+
`import { defineConfig } from '@geekmidas/cli';
|
|
763
|
+
|
|
764
|
+
export default defineConfig({
|
|
765
|
+
routes: 'src/endpoints/**/*.ts',
|
|
766
|
+
providers: {
|
|
767
|
+
dokploy: {
|
|
768
|
+
endpoint: 'https://old.dokploy.com',
|
|
769
|
+
projectId: 'old_proj',
|
|
770
|
+
applicationId: 'old_app',
|
|
771
|
+
registryId: 'old_reg',
|
|
772
|
+
},
|
|
773
|
+
},
|
|
774
|
+
});`,
|
|
775
|
+
);
|
|
776
|
+
|
|
777
|
+
await updateConfig(
|
|
778
|
+
{
|
|
779
|
+
endpoint: 'https://new.dokploy.com',
|
|
780
|
+
projectId: 'new_proj',
|
|
781
|
+
applicationId: 'new_app',
|
|
782
|
+
registryId: 'new_reg',
|
|
783
|
+
},
|
|
784
|
+
tempDir,
|
|
785
|
+
);
|
|
786
|
+
|
|
787
|
+
const content = await readFile(configPath, 'utf-8');
|
|
788
|
+
expect(content).toContain("registryId: 'new_reg'");
|
|
789
|
+
expect(content).toContain("endpoint: 'https://new.dokploy.com'");
|
|
790
|
+
expect(content).not.toContain('old.dokploy.com');
|
|
791
|
+
expect(content).not.toContain('old_reg');
|
|
792
|
+
});
|
|
662
793
|
});
|
package/src/deploy/docker.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { execSync } from 'node:child_process';
|
|
2
|
-
import
|
|
2
|
+
import { dirname, join, relative } from 'node:path';
|
|
3
|
+
import { dockerCommand, findLockfilePath, isMonorepo } from '../docker';
|
|
3
4
|
import type { DeployResult, DockerDeployConfig } from './types';
|
|
4
5
|
|
|
5
6
|
const logger = console;
|
|
@@ -37,11 +38,39 @@ export function getImageRef(
|
|
|
37
38
|
async function buildImage(imageRef: string): Promise<void> {
|
|
38
39
|
logger.log(`\n🔨 Building Docker image: ${imageRef}`);
|
|
39
40
|
|
|
41
|
+
const cwd = process.cwd();
|
|
42
|
+
const inMonorepo = isMonorepo(cwd);
|
|
43
|
+
|
|
44
|
+
// Generate appropriate Dockerfile
|
|
45
|
+
if (inMonorepo) {
|
|
46
|
+
logger.log(' Generating Dockerfile for monorepo (turbo prune)...');
|
|
47
|
+
} else {
|
|
48
|
+
logger.log(' Generating Dockerfile...');
|
|
49
|
+
}
|
|
50
|
+
await dockerCommand({});
|
|
51
|
+
|
|
52
|
+
// Determine build context and Dockerfile path
|
|
53
|
+
let buildCwd = cwd;
|
|
54
|
+
let dockerfilePath = '.gkm/docker/Dockerfile';
|
|
55
|
+
|
|
56
|
+
if (inMonorepo) {
|
|
57
|
+
// For monorepos, build from root so turbo prune can access all packages
|
|
58
|
+
const lockfilePath = findLockfilePath(cwd);
|
|
59
|
+
if (lockfilePath) {
|
|
60
|
+
const monorepoRoot = dirname(lockfilePath);
|
|
61
|
+
const appRelPath = relative(monorepoRoot, cwd);
|
|
62
|
+
dockerfilePath = join(appRelPath, '.gkm/docker/Dockerfile');
|
|
63
|
+
buildCwd = monorepoRoot;
|
|
64
|
+
logger.log(` Building from monorepo root: ${monorepoRoot}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
40
68
|
try {
|
|
69
|
+
// Build for linux/amd64 to ensure compatibility with most cloud servers
|
|
41
70
|
execSync(
|
|
42
|
-
`DOCKER_BUILDKIT=1 docker build -f
|
|
71
|
+
`DOCKER_BUILDKIT=1 docker build --platform linux/amd64 -f ${dockerfilePath} -t ${imageRef} .`,
|
|
43
72
|
{
|
|
44
|
-
cwd:
|
|
73
|
+
cwd: buildCwd,
|
|
45
74
|
stdio: 'inherit',
|
|
46
75
|
env: { ...process.env, DOCKER_BUILDKIT: '1' },
|
|
47
76
|
},
|