@geekmidas/cli 0.39.0 → 0.41.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-CyHg1v_T.cjs → bundler-BB-kETMd.cjs} +20 -49
- package/dist/bundler-BB-kETMd.cjs.map +1 -0
- package/dist/{bundler-DQIuE3Kn.mjs → bundler-DGry2vaR.mjs} +22 -51
- package/dist/bundler-DGry2vaR.mjs.map +1 -0
- package/dist/{config-BC5n1a2D.mjs → config-C0b0jdmU.mjs} +2 -2
- package/dist/{config-BC5n1a2D.mjs.map → config-C0b0jdmU.mjs.map} +1 -1
- package/dist/{config-BAE9LFC1.cjs → config-xVZsRjN7.cjs} +2 -2
- package/dist/{config-BAE9LFC1.cjs.map → config-xVZsRjN7.cjs.map} +1 -1
- package/dist/config.cjs +2 -2
- package/dist/config.d.cts +1 -1
- package/dist/config.d.mts +2 -2
- package/dist/config.mjs +2 -2
- package/dist/dokploy-api-Bdmk5ImW.cjs +3 -0
- package/dist/{dokploy-api-C5czOZoc.cjs → dokploy-api-BdxOMH_V.cjs} +43 -1
- package/dist/{dokploy-api-C5czOZoc.cjs.map → dokploy-api-BdxOMH_V.cjs.map} +1 -1
- package/dist/{dokploy-api-B9qR2Yn1.mjs → dokploy-api-DWsqNjwP.mjs} +43 -1
- package/dist/{dokploy-api-B9qR2Yn1.mjs.map → dokploy-api-DWsqNjwP.mjs.map} +1 -1
- package/dist/dokploy-api-tZSZaHd9.mjs +3 -0
- package/dist/{encryption-JtMsiGNp.mjs → encryption-BC4MAODn.mjs} +1 -1
- package/dist/{encryption-JtMsiGNp.mjs.map → encryption-BC4MAODn.mjs.map} +1 -1
- package/dist/encryption-Biq0EZ4m.cjs +4 -0
- package/dist/encryption-CQXBZGkt.mjs +3 -0
- package/dist/{encryption-BAz0xQ1Q.cjs → encryption-DaCB_NmS.cjs} +13 -3
- package/dist/{encryption-BAz0xQ1Q.cjs.map → encryption-DaCB_NmS.cjs.map} +1 -1
- package/dist/{index-C7TkoYmt.d.mts → index-CXa3odEw.d.mts} +68 -7
- package/dist/index-CXa3odEw.d.mts.map +1 -0
- package/dist/{index-CpchsC9w.d.cts → index-E8Nu2Rxl.d.cts} +67 -6
- package/dist/index-E8Nu2Rxl.d.cts.map +1 -0
- package/dist/index.cjs +698 -127
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +677 -106
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-CjYeF-Tg.mjs → openapi-D3pA6FfZ.mjs} +2 -2
- package/dist/{openapi-CjYeF-Tg.mjs.map → openapi-D3pA6FfZ.mjs.map} +1 -1
- package/dist/{openapi-a-e3Y8WA.cjs → openapi-DhcCtKzM.cjs} +2 -2
- package/dist/{openapi-a-e3Y8WA.cjs.map → openapi-DhcCtKzM.cjs.map} +1 -1
- package/dist/{openapi-react-query-DvNpdDpM.cjs → openapi-react-query-C_MxpBgF.cjs} +1 -1
- package/dist/{openapi-react-query-DvNpdDpM.cjs.map → openapi-react-query-C_MxpBgF.cjs.map} +1 -1
- package/dist/{openapi-react-query-5rSortLH.mjs → openapi-react-query-ZoP9DPbY.mjs} +1 -1
- package/dist/{openapi-react-query-5rSortLH.mjs.map → openapi-react-query-ZoP9DPbY.mjs.map} +1 -1
- package/dist/openapi-react-query.cjs +1 -1
- package/dist/openapi-react-query.mjs +1 -1
- package/dist/openapi.cjs +3 -3
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.mjs +3 -3
- package/dist/{types-K2uQJ-FO.d.mts → types-BtGL-8QS.d.mts} +1 -1
- package/dist/{types-K2uQJ-FO.d.mts.map → types-BtGL-8QS.d.mts.map} +1 -1
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +3 -3
- package/dist/workspace/index.mjs +1 -1
- package/dist/{workspace-My0A4IRO.cjs → workspace-BDAhr6Kb.cjs} +33 -4
- package/dist/{workspace-My0A4IRO.cjs.map → workspace-BDAhr6Kb.cjs.map} +1 -1
- package/dist/{workspace-DFJ3sWfY.mjs → workspace-D_6ZCaR_.mjs} +33 -4
- package/dist/{workspace-DFJ3sWfY.mjs.map → workspace-D_6ZCaR_.mjs.map} +1 -1
- package/package.json +5 -5
- package/src/build/bundler.ts +27 -79
- package/src/deploy/__tests__/domain.spec.ts +231 -0
- package/src/deploy/__tests__/secrets.spec.ts +300 -0
- package/src/deploy/__tests__/sniffer.spec.ts +221 -0
- package/src/deploy/docker.ts +40 -11
- package/src/deploy/dokploy-api.ts +99 -0
- package/src/deploy/domain.ts +125 -0
- package/src/deploy/index.ts +366 -148
- package/src/deploy/secrets.ts +182 -0
- package/src/deploy/sniffer.ts +180 -0
- package/src/dev/index.ts +11 -0
- package/src/docker/index.ts +24 -5
- package/src/docker/templates.ts +187 -1
- package/src/init/templates/api.ts +4 -4
- package/src/init/versions.ts +2 -2
- package/src/workspace/index.ts +2 -0
- package/src/workspace/schema.ts +32 -6
- package/src/workspace/types.ts +64 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/bundler-CyHg1v_T.cjs.map +0 -1
- package/dist/bundler-DQIuE3Kn.mjs.map +0 -1
- package/dist/dokploy-api-B0w17y4_.mjs +0 -3
- package/dist/dokploy-api-BnGeUqN4.cjs +0 -3
- package/dist/index-C7TkoYmt.d.mts.map +0 -1
- package/dist/index-CpchsC9w.d.cts.map +0 -1
|
@@ -458,6 +458,68 @@ export class DokployApi {
|
|
|
458
458
|
): Promise<void> {
|
|
459
459
|
await this.post('redis.update', { redisId, ...updates });
|
|
460
460
|
}
|
|
461
|
+
|
|
462
|
+
// ============================================
|
|
463
|
+
// Domain endpoints
|
|
464
|
+
// ============================================
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Create a new domain for an application
|
|
468
|
+
*/
|
|
469
|
+
async createDomain(options: DokployDomainCreate): Promise<DokployDomain> {
|
|
470
|
+
return this.post<DokployDomain>(
|
|
471
|
+
'domain.create',
|
|
472
|
+
options as unknown as Record<string, unknown>,
|
|
473
|
+
);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Update an existing domain
|
|
478
|
+
*/
|
|
479
|
+
async updateDomain(
|
|
480
|
+
domainId: string,
|
|
481
|
+
updates: Partial<DokployDomainCreate>,
|
|
482
|
+
): Promise<void> {
|
|
483
|
+
await this.post('domain.update', { domainId, ...updates });
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Delete a domain
|
|
488
|
+
*/
|
|
489
|
+
async deleteDomain(domainId: string): Promise<void> {
|
|
490
|
+
await this.post('domain.delete', { domainId });
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* Get a domain by ID
|
|
495
|
+
*/
|
|
496
|
+
async getDomain(domainId: string): Promise<DokployDomain> {
|
|
497
|
+
return this.get<DokployDomain>(`domain.one?domainId=${domainId}`);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Get all domains for an application
|
|
502
|
+
*/
|
|
503
|
+
async getDomainsByApplicationId(
|
|
504
|
+
applicationId: string,
|
|
505
|
+
): Promise<DokployDomain[]> {
|
|
506
|
+
return this.get<DokployDomain[]>(
|
|
507
|
+
`domain.byApplicationId?applicationId=${applicationId}`,
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Auto-generate a domain name for an application
|
|
513
|
+
*/
|
|
514
|
+
async generateDomain(
|
|
515
|
+
appName: string,
|
|
516
|
+
serverId?: string,
|
|
517
|
+
): Promise<{ domain: string }> {
|
|
518
|
+
return this.post<{ domain: string }>('domain.generateDomain', {
|
|
519
|
+
appName,
|
|
520
|
+
serverId,
|
|
521
|
+
});
|
|
522
|
+
}
|
|
461
523
|
}
|
|
462
524
|
|
|
463
525
|
// ============================================
|
|
@@ -552,6 +614,43 @@ export interface DokployRedisUpdate {
|
|
|
552
614
|
description: string;
|
|
553
615
|
}
|
|
554
616
|
|
|
617
|
+
export type DokployCertificateType = 'letsencrypt' | 'none' | 'custom';
|
|
618
|
+
export type DokployDomainType = 'application' | 'compose' | 'preview';
|
|
619
|
+
|
|
620
|
+
export interface DokployDomainCreate {
|
|
621
|
+
/** Domain hostname (e.g., 'api.example.com') */
|
|
622
|
+
host: string;
|
|
623
|
+
/** URL path (optional, e.g., '/api') */
|
|
624
|
+
path?: string | null;
|
|
625
|
+
/** Container port to route to (1-65535) */
|
|
626
|
+
port?: number | null;
|
|
627
|
+
/** Enable HTTPS */
|
|
628
|
+
https?: boolean;
|
|
629
|
+
/** Associated application ID */
|
|
630
|
+
applicationId?: string | null;
|
|
631
|
+
/** Certificate type for HTTPS */
|
|
632
|
+
certificateType?: DokployCertificateType;
|
|
633
|
+
/** Custom certificate resolver name */
|
|
634
|
+
customCertResolver?: string | null;
|
|
635
|
+
/** Docker Compose service ID */
|
|
636
|
+
composeId?: string | null;
|
|
637
|
+
/** Service name for compose */
|
|
638
|
+
serviceName?: string | null;
|
|
639
|
+
/** Domain type */
|
|
640
|
+
domainType?: DokployDomainType | null;
|
|
641
|
+
/** Preview deployment ID */
|
|
642
|
+
previewDeploymentId?: string | null;
|
|
643
|
+
/** Internal routing path */
|
|
644
|
+
internalPath?: string | null;
|
|
645
|
+
/** Strip path from forwarded requests */
|
|
646
|
+
stripPath?: boolean;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
export interface DokployDomain extends DokployDomainCreate {
|
|
650
|
+
domainId: string;
|
|
651
|
+
createdAt?: string;
|
|
652
|
+
}
|
|
653
|
+
|
|
555
654
|
/**
|
|
556
655
|
* Create a Dokploy API client from stored credentials or environment
|
|
557
656
|
*/
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { DokployWorkspaceConfig, NormalizedAppConfig } from '../workspace/types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the hostname for an app based on stage configuration.
|
|
5
|
+
*
|
|
6
|
+
* Domain resolution priority:
|
|
7
|
+
* 1. Explicit app.domain override (string or stage-specific)
|
|
8
|
+
* 2. Default pattern based on app type:
|
|
9
|
+
* - Main frontend app gets base domain (e.g., 'myapp.com')
|
|
10
|
+
* - Other apps get prefixed domain (e.g., 'api.myapp.com')
|
|
11
|
+
*
|
|
12
|
+
* @param appName - The name of the app
|
|
13
|
+
* @param app - The normalized app configuration
|
|
14
|
+
* @param stage - The deployment stage (e.g., 'production', 'development')
|
|
15
|
+
* @param dokployConfig - Dokploy workspace configuration with domain mappings
|
|
16
|
+
* @param isMainFrontend - Whether this is the main frontend app
|
|
17
|
+
* @returns The resolved hostname for the app
|
|
18
|
+
* @throws Error if no domain configuration is found for the stage
|
|
19
|
+
*/
|
|
20
|
+
export function resolveHost(
|
|
21
|
+
appName: string,
|
|
22
|
+
app: NormalizedAppConfig,
|
|
23
|
+
stage: string,
|
|
24
|
+
dokployConfig: DokployWorkspaceConfig | undefined,
|
|
25
|
+
isMainFrontend: boolean,
|
|
26
|
+
): string {
|
|
27
|
+
// 1. Check for explicit app domain override
|
|
28
|
+
if (app.domain) {
|
|
29
|
+
if (typeof app.domain === 'string') {
|
|
30
|
+
return app.domain;
|
|
31
|
+
}
|
|
32
|
+
if (app.domain[stage]) {
|
|
33
|
+
return app.domain[stage]!;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 2. Get base domain for this stage
|
|
38
|
+
const baseDomain = dokployConfig?.domains?.[stage];
|
|
39
|
+
if (!baseDomain) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`No domain configured for stage "${stage}". ` +
|
|
42
|
+
`Add deploy.dokploy.domains.${stage} to gkm.config.ts`,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 3. Main frontend app gets base domain, others get prefix
|
|
47
|
+
if (isMainFrontend) {
|
|
48
|
+
return baseDomain;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return `${appName}.${baseDomain}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Determine if an app is the "main" frontend (gets base domain).
|
|
56
|
+
*
|
|
57
|
+
* An app is considered the main frontend if:
|
|
58
|
+
* 1. It's named 'web' and is a frontend type
|
|
59
|
+
* 2. It's the first frontend app in the apps list
|
|
60
|
+
*
|
|
61
|
+
* @param appName - The name of the app to check
|
|
62
|
+
* @param app - The app configuration
|
|
63
|
+
* @param allApps - All apps in the workspace
|
|
64
|
+
* @returns True if this is the main frontend app
|
|
65
|
+
*/
|
|
66
|
+
export function isMainFrontendApp(
|
|
67
|
+
appName: string,
|
|
68
|
+
app: NormalizedAppConfig,
|
|
69
|
+
allApps: Record<string, NormalizedAppConfig>,
|
|
70
|
+
): boolean {
|
|
71
|
+
if (app.type !== 'frontend') {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// App named 'web' is always main
|
|
76
|
+
if (appName === 'web') {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Otherwise, check if this is the first frontend
|
|
81
|
+
for (const [name, a] of Object.entries(allApps)) {
|
|
82
|
+
if (a.type === 'frontend') {
|
|
83
|
+
return name === appName;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Generate public URL build args for a frontend app based on its dependencies.
|
|
92
|
+
*
|
|
93
|
+
* @param app - The frontend app configuration
|
|
94
|
+
* @param deployedUrls - Map of app name to deployed public URL
|
|
95
|
+
* @returns Array of build args like 'NEXT_PUBLIC_API_URL=https://api.example.com'
|
|
96
|
+
*/
|
|
97
|
+
export function generatePublicUrlBuildArgs(
|
|
98
|
+
app: NormalizedAppConfig,
|
|
99
|
+
deployedUrls: Record<string, string>,
|
|
100
|
+
): string[] {
|
|
101
|
+
const buildArgs: string[] = [];
|
|
102
|
+
|
|
103
|
+
for (const dep of app.dependencies) {
|
|
104
|
+
const publicUrl = deployedUrls[dep];
|
|
105
|
+
if (publicUrl) {
|
|
106
|
+
// Convert app name to UPPER_SNAKE_CASE for env var
|
|
107
|
+
const envVarName = `NEXT_PUBLIC_${dep.toUpperCase()}_URL`;
|
|
108
|
+
buildArgs.push(`${envVarName}=${publicUrl}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return buildArgs;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Get public URL arg names from app dependencies.
|
|
117
|
+
*
|
|
118
|
+
* @param app - The frontend app configuration
|
|
119
|
+
* @returns Array of arg names like 'NEXT_PUBLIC_API_URL'
|
|
120
|
+
*/
|
|
121
|
+
export function getPublicUrlArgNames(app: NormalizedAppConfig): string[] {
|
|
122
|
+
return app.dependencies.map(
|
|
123
|
+
(dep) => `NEXT_PUBLIC_${dep.toUpperCase()}_URL`,
|
|
124
|
+
);
|
|
125
|
+
}
|