@geekmidas/cli 0.13.0 → 0.15.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-DskIqW2t.mjs → bundler-D7cM_FWw.mjs} +34 -10
- package/dist/bundler-D7cM_FWw.mjs.map +1 -0
- package/dist/{bundler-B1qy9b-j.cjs → bundler-Nuew7Xcn.cjs} +33 -9
- package/dist/bundler-Nuew7Xcn.cjs.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 +1508 -1073
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1508 -1073
- 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-kSxTjkNb.mjs → storage-BaOP55oq.mjs} +16 -2
- package/dist/storage-BaOP55oq.mjs.map +1 -0
- package/dist/{storage-Bj1E26lU.cjs → storage-Bn3K9Ccu.cjs} +21 -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-BhkZc-vm.d.cts → types-BgaMXsUa.d.cts} +3 -1
- package/dist/{types-BR0M2v_c.d.mts.map → types-BgaMXsUa.d.cts.map} +1 -1
- package/dist/{types-BR0M2v_c.d.mts → 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 +5 -4
- 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 +61 -8
- package/src/build/index.ts +21 -0
- package/src/build/types.ts +6 -0
- package/src/deploy/__tests__/docker.spec.ts +44 -6
- 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 +401 -0
- package/src/deploy/__tests__/init.spec.ts +147 -16
- package/src/deploy/docker.ts +109 -5
- package/src/deploy/dokploy-api.ts +581 -0
- package/src/deploy/dokploy.ts +66 -93
- package/src/deploy/index.ts +630 -32
- package/src/deploy/init.ts +192 -249
- package/src/deploy/types.ts +24 -2
- 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/storage.ts +15 -0
- package/src/types.ts +2 -0
- package/dist/bundler-B1qy9b-j.cjs.map +0 -1
- package/dist/bundler-DskIqW2t.mjs.map +0 -1
- package/dist/storage-BOOpAF8N.cjs +0 -5
- package/dist/storage-Bj1E26lU.cjs.map +0 -1
- package/dist/storage-kSxTjkNb.mjs.map +0 -1
- package/dist/storage-tgZSUnKl.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,7 +1,68 @@
|
|
|
1
1
|
import { execSync } from 'node:child_process';
|
|
2
|
-
import
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join, relative } from 'node:path';
|
|
4
|
+
import type { GkmConfig } from '../config';
|
|
5
|
+
import { dockerCommand, findLockfilePath, isMonorepo } from '../docker';
|
|
3
6
|
import type { DeployResult, DockerDeployConfig } from './types';
|
|
4
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Get app name from package.json in the current working directory
|
|
10
|
+
* Used for Dokploy app/project naming
|
|
11
|
+
*/
|
|
12
|
+
export function getAppNameFromCwd(): string | undefined {
|
|
13
|
+
const packageJsonPath = join(process.cwd(), 'package.json');
|
|
14
|
+
|
|
15
|
+
if (!existsSync(packageJsonPath)) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
21
|
+
if (pkg.name) {
|
|
22
|
+
// Strip org scope if present (e.g., @myorg/app -> app)
|
|
23
|
+
return pkg.name.replace(/^@[^/]+\//, '');
|
|
24
|
+
}
|
|
25
|
+
} catch {
|
|
26
|
+
// Ignore parse errors
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get app name from package.json adjacent to the lockfile (project root)
|
|
34
|
+
* Used for Docker image naming
|
|
35
|
+
*/
|
|
36
|
+
export function getAppNameFromPackageJson(): string | undefined {
|
|
37
|
+
const cwd = process.cwd();
|
|
38
|
+
|
|
39
|
+
// Find the lockfile to determine the project root
|
|
40
|
+
const lockfilePath = findLockfilePath(cwd);
|
|
41
|
+
if (!lockfilePath) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Use the package.json adjacent to the lockfile
|
|
46
|
+
const projectRoot = dirname(lockfilePath);
|
|
47
|
+
const packageJsonPath = join(projectRoot, 'package.json');
|
|
48
|
+
|
|
49
|
+
if (!existsSync(packageJsonPath)) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
55
|
+
if (pkg.name) {
|
|
56
|
+
// Strip org scope if present (e.g., @myorg/app -> app)
|
|
57
|
+
return pkg.name.replace(/^@[^/]+\//, '');
|
|
58
|
+
}
|
|
59
|
+
} catch {
|
|
60
|
+
// Ignore parse errors
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
5
66
|
const logger = console;
|
|
6
67
|
|
|
7
68
|
export interface DockerDeployOptions {
|
|
@@ -37,11 +98,39 @@ export function getImageRef(
|
|
|
37
98
|
async function buildImage(imageRef: string): Promise<void> {
|
|
38
99
|
logger.log(`\n🔨 Building Docker image: ${imageRef}`);
|
|
39
100
|
|
|
101
|
+
const cwd = process.cwd();
|
|
102
|
+
const inMonorepo = isMonorepo(cwd);
|
|
103
|
+
|
|
104
|
+
// Generate appropriate Dockerfile
|
|
105
|
+
if (inMonorepo) {
|
|
106
|
+
logger.log(' Generating Dockerfile for monorepo (turbo prune)...');
|
|
107
|
+
} else {
|
|
108
|
+
logger.log(' Generating Dockerfile...');
|
|
109
|
+
}
|
|
110
|
+
await dockerCommand({});
|
|
111
|
+
|
|
112
|
+
// Determine build context and Dockerfile path
|
|
113
|
+
let buildCwd = cwd;
|
|
114
|
+
let dockerfilePath = '.gkm/docker/Dockerfile';
|
|
115
|
+
|
|
116
|
+
if (inMonorepo) {
|
|
117
|
+
// For monorepos, build from root so turbo prune can access all packages
|
|
118
|
+
const lockfilePath = findLockfilePath(cwd);
|
|
119
|
+
if (lockfilePath) {
|
|
120
|
+
const monorepoRoot = dirname(lockfilePath);
|
|
121
|
+
const appRelPath = relative(monorepoRoot, cwd);
|
|
122
|
+
dockerfilePath = join(appRelPath, '.gkm/docker/Dockerfile');
|
|
123
|
+
buildCwd = monorepoRoot;
|
|
124
|
+
logger.log(` Building from monorepo root: ${monorepoRoot}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
40
128
|
try {
|
|
129
|
+
// Build for linux/amd64 to ensure compatibility with most cloud servers
|
|
41
130
|
execSync(
|
|
42
|
-
`DOCKER_BUILDKIT=1 docker build -f
|
|
131
|
+
`DOCKER_BUILDKIT=1 docker build --platform linux/amd64 -f ${dockerfilePath} -t ${imageRef} .`,
|
|
43
132
|
{
|
|
44
|
-
cwd:
|
|
133
|
+
cwd: buildCwd,
|
|
45
134
|
stdio: 'inherit',
|
|
46
135
|
env: { ...process.env, DOCKER_BUILDKIT: '1' },
|
|
47
136
|
},
|
|
@@ -81,7 +170,8 @@ export async function deployDocker(
|
|
|
81
170
|
): Promise<DeployResult> {
|
|
82
171
|
const { stage, tag, skipPush, masterKey, config } = options;
|
|
83
172
|
|
|
84
|
-
|
|
173
|
+
// imageName should always be set by resolveDockerConfig
|
|
174
|
+
const imageName = config.imageName!;
|
|
85
175
|
const imageRef = getImageRef(config.registry, imageName, tag);
|
|
86
176
|
|
|
87
177
|
// Build image
|
|
@@ -119,10 +209,24 @@ export async function deployDocker(
|
|
|
119
209
|
|
|
120
210
|
/**
|
|
121
211
|
* Resolve Docker deploy config from gkm config
|
|
212
|
+
* - imageName: from config, or cwd package.json, or 'app' (for Docker image)
|
|
213
|
+
* - projectName: from root package.json, or 'app' (for Dokploy project)
|
|
214
|
+
* - appName: from cwd package.json, or projectName (for Dokploy app within project)
|
|
122
215
|
*/
|
|
123
216
|
export function resolveDockerConfig(config: GkmConfig): DockerDeployConfig {
|
|
217
|
+
// projectName comes from root package.json (monorepo name)
|
|
218
|
+
const projectName = getAppNameFromPackageJson() ?? 'app';
|
|
219
|
+
|
|
220
|
+
// appName comes from cwd package.json (the app being deployed)
|
|
221
|
+
const appName = getAppNameFromCwd() ?? projectName;
|
|
222
|
+
|
|
223
|
+
// imageName defaults to appName (cwd package.json)
|
|
224
|
+
const imageName = config.docker?.imageName ?? appName;
|
|
225
|
+
|
|
124
226
|
return {
|
|
125
227
|
registry: config.docker?.registry,
|
|
126
|
-
imageName
|
|
228
|
+
imageName,
|
|
229
|
+
projectName,
|
|
230
|
+
appName,
|
|
127
231
|
};
|
|
128
232
|
}
|