@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.
- package/README.md +525 -0
- package/dist/bundler-B1qy9b-j.cjs +112 -0
- package/dist/bundler-B1qy9b-j.cjs.map +1 -0
- package/dist/bundler-DskIqW2t.mjs +111 -0
- package/dist/bundler-DskIqW2t.mjs.map +1 -0
- package/dist/{config-C9aXOHBe.cjs → config-AmInkU7k.cjs} +8 -8
- package/dist/config-AmInkU7k.cjs.map +1 -0
- package/dist/{config-BrkUalUh.mjs → config-DYULeEv8.mjs} +3 -3
- package/dist/config-DYULeEv8.mjs.map +1 -0
- package/dist/config.cjs +1 -1
- package/dist/config.d.cts +1 -1
- package/dist/config.d.mts +1 -1
- package/dist/config.mjs +1 -1
- package/dist/encryption-C8H-38Yy.mjs +42 -0
- package/dist/encryption-C8H-38Yy.mjs.map +1 -0
- package/dist/encryption-Dyf_r1h-.cjs +44 -0
- package/dist/encryption-Dyf_r1h-.cjs.map +1 -0
- package/dist/index.cjs +2123 -179
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +2141 -192
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-CZLI4QTr.mjs → openapi-BfFlOBCG.mjs} +801 -38
- package/dist/openapi-BfFlOBCG.mjs.map +1 -0
- package/dist/{openapi-BeHLKcwP.cjs → openapi-Bt_1FDpT.cjs} +794 -31
- package/dist/openapi-Bt_1FDpT.cjs.map +1 -0
- package/dist/{openapi-react-query-o5iMi8tz.cjs → openapi-react-query-B-sNWHFU.cjs} +5 -5
- package/dist/openapi-react-query-B-sNWHFU.cjs.map +1 -0
- package/dist/{openapi-react-query-CcciaVu5.mjs → openapi-react-query-B6XTeGqS.mjs} +5 -5
- package/dist/openapi-react-query-B6XTeGqS.mjs.map +1 -0
- package/dist/openapi-react-query.cjs +1 -1
- package/dist/openapi-react-query.d.cts.map +1 -1
- package/dist/openapi-react-query.d.mts.map +1 -1
- package/dist/openapi-react-query.mjs +1 -1
- package/dist/openapi.cjs +2 -2
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.d.mts.map +1 -1
- package/dist/openapi.mjs +2 -2
- package/dist/storage-BOOpAF8N.cjs +5 -0
- package/dist/storage-Bj1E26lU.cjs +187 -0
- package/dist/storage-Bj1E26lU.cjs.map +1 -0
- package/dist/storage-kSxTjkNb.mjs +133 -0
- package/dist/storage-kSxTjkNb.mjs.map +1 -0
- package/dist/storage-tgZSUnKl.mjs +3 -0
- package/dist/{types-b-vwGpqc.d.cts → types-BR0M2v_c.d.mts} +100 -1
- package/dist/types-BR0M2v_c.d.mts.map +1 -0
- package/dist/{types-DXgiA1sF.d.mts → types-BhkZc-vm.d.cts} +100 -1
- package/dist/types-BhkZc-vm.d.cts.map +1 -0
- package/examples/cron-example.ts +27 -27
- package/examples/env.ts +27 -27
- package/examples/function-example.ts +31 -31
- package/examples/gkm.config.json +20 -20
- package/examples/gkm.config.ts +8 -8
- package/examples/gkm.minimal.config.json +5 -5
- package/examples/gkm.production.config.json +25 -25
- package/examples/logger.ts +2 -2
- package/package.json +6 -6
- package/src/__tests__/EndpointGenerator.hooks.spec.ts +191 -191
- package/src/__tests__/config.spec.ts +55 -55
- package/src/__tests__/loadEnvFiles.spec.ts +93 -93
- package/src/__tests__/normalizeHooksConfig.spec.ts +58 -58
- package/src/__tests__/openapi-react-query.spec.ts +497 -497
- package/src/__tests__/openapi.spec.ts +428 -428
- package/src/__tests__/test-helpers.ts +76 -76
- package/src/auth/__tests__/credentials.spec.ts +204 -0
- package/src/auth/__tests__/index.spec.ts +168 -0
- package/src/auth/credentials.ts +187 -0
- package/src/auth/index.ts +226 -0
- package/src/build/__tests__/bundler.spec.ts +444 -0
- package/src/build/__tests__/index-new.spec.ts +474 -474
- package/src/build/__tests__/manifests.spec.ts +333 -333
- package/src/build/bundler.ts +210 -0
- package/src/build/endpoint-analyzer.ts +236 -0
- package/src/build/handler-templates.ts +1253 -0
- package/src/build/index.ts +260 -179
- package/src/build/manifests.ts +52 -52
- package/src/build/providerResolver.ts +145 -145
- package/src/build/types.ts +64 -43
- package/src/config.ts +39 -39
- package/src/deploy/__tests__/docker.spec.ts +111 -0
- package/src/deploy/__tests__/dokploy.spec.ts +245 -0
- package/src/deploy/__tests__/init.spec.ts +662 -0
- package/src/deploy/docker.ts +128 -0
- package/src/deploy/dokploy.ts +204 -0
- package/src/deploy/index.ts +136 -0
- package/src/deploy/init.ts +484 -0
- package/src/deploy/types.ts +48 -0
- package/src/dev/__tests__/index.spec.ts +266 -266
- package/src/dev/index.ts +647 -601
- package/src/docker/__tests__/compose.spec.ts +531 -0
- package/src/docker/__tests__/templates.spec.ts +280 -0
- package/src/docker/compose.ts +273 -0
- package/src/docker/index.ts +230 -0
- package/src/docker/templates.ts +446 -0
- package/src/generators/CronGenerator.ts +72 -72
- package/src/generators/EndpointGenerator.ts +699 -398
- package/src/generators/FunctionGenerator.ts +84 -84
- package/src/generators/Generator.ts +72 -72
- package/src/generators/OpenApiTsGenerator.ts +577 -577
- package/src/generators/SubscriberGenerator.ts +124 -124
- package/src/generators/__tests__/CronGenerator.spec.ts +433 -433
- package/src/generators/__tests__/EndpointGenerator.spec.ts +532 -382
- package/src/generators/__tests__/FunctionGenerator.spec.ts +244 -244
- package/src/generators/__tests__/SubscriberGenerator.spec.ts +397 -382
- package/src/generators/index.ts +4 -4
- package/src/index.ts +623 -201
- package/src/init/__tests__/generators.spec.ts +334 -334
- package/src/init/__tests__/init.spec.ts +332 -332
- package/src/init/__tests__/utils.spec.ts +89 -89
- package/src/init/generators/config.ts +175 -175
- package/src/init/generators/docker.ts +41 -41
- package/src/init/generators/env.ts +72 -72
- package/src/init/generators/index.ts +1 -1
- package/src/init/generators/models.ts +64 -64
- package/src/init/generators/monorepo.ts +161 -161
- package/src/init/generators/package.ts +71 -71
- package/src/init/generators/source.ts +6 -6
- package/src/init/index.ts +203 -208
- package/src/init/templates/api.ts +115 -115
- package/src/init/templates/index.ts +75 -75
- package/src/init/templates/minimal.ts +98 -98
- package/src/init/templates/serverless.ts +89 -89
- package/src/init/templates/worker.ts +98 -98
- package/src/init/utils.ts +54 -56
- package/src/openapi-react-query.ts +194 -194
- package/src/openapi.ts +63 -63
- package/src/secrets/__tests__/encryption.spec.ts +226 -0
- package/src/secrets/__tests__/generator.spec.ts +319 -0
- package/src/secrets/__tests__/index.spec.ts +91 -0
- package/src/secrets/__tests__/storage.spec.ts +611 -0
- package/src/secrets/encryption.ts +91 -0
- package/src/secrets/generator.ts +164 -0
- package/src/secrets/index.ts +383 -0
- package/src/secrets/storage.ts +192 -0
- package/src/secrets/types.ts +53 -0
- package/src/types.ts +295 -176
- package/tsdown.config.ts +11 -8
- package/dist/config-BrkUalUh.mjs.map +0 -1
- package/dist/config-C9aXOHBe.cjs.map +0 -1
- package/dist/openapi-BeHLKcwP.cjs.map +0 -1
- package/dist/openapi-CZLI4QTr.mjs.map +0 -1
- package/dist/openapi-react-query-CcciaVu5.mjs.map +0 -1
- package/dist/openapi-react-query-o5iMi8tz.cjs.map +0 -1
- package/dist/types-DXgiA1sF.d.mts.map +0 -1
- package/dist/types-b-vwGpqc.d.cts.map +0 -1
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { readFile, unlink, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Stored credentials for various services
|
|
8
|
+
*/
|
|
9
|
+
export interface StoredCredentials {
|
|
10
|
+
dokploy?: {
|
|
11
|
+
/** API token */
|
|
12
|
+
token: string;
|
|
13
|
+
/** Dokploy endpoint URL */
|
|
14
|
+
endpoint: string;
|
|
15
|
+
/** When the credentials were stored */
|
|
16
|
+
storedAt: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Options for credential operations
|
|
22
|
+
*/
|
|
23
|
+
export interface CredentialOptions {
|
|
24
|
+
/** Root directory for credentials storage (default: user home directory) */
|
|
25
|
+
root?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get the path to the credentials directory
|
|
30
|
+
*/
|
|
31
|
+
export function getCredentialsDir(options?: CredentialOptions): string {
|
|
32
|
+
const root = options?.root ?? homedir();
|
|
33
|
+
return join(root, '.gkm');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get the path to the credentials file
|
|
38
|
+
*/
|
|
39
|
+
export function getCredentialsPath(options?: CredentialOptions): string {
|
|
40
|
+
return join(getCredentialsDir(options), 'credentials.json');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Ensure the credentials directory exists
|
|
45
|
+
*/
|
|
46
|
+
function ensureCredentialsDir(options?: CredentialOptions): void {
|
|
47
|
+
const dir = getCredentialsDir(options);
|
|
48
|
+
if (!existsSync(dir)) {
|
|
49
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Read stored credentials from disk
|
|
55
|
+
*/
|
|
56
|
+
export async function readCredentials(
|
|
57
|
+
options?: CredentialOptions,
|
|
58
|
+
): Promise<StoredCredentials> {
|
|
59
|
+
const path = getCredentialsPath(options);
|
|
60
|
+
|
|
61
|
+
if (!existsSync(path)) {
|
|
62
|
+
return {};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const content = await readFile(path, 'utf-8');
|
|
67
|
+
return JSON.parse(content) as StoredCredentials;
|
|
68
|
+
} catch {
|
|
69
|
+
return {};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Write credentials to disk
|
|
75
|
+
*/
|
|
76
|
+
export async function writeCredentials(
|
|
77
|
+
credentials: StoredCredentials,
|
|
78
|
+
options?: CredentialOptions,
|
|
79
|
+
): Promise<void> {
|
|
80
|
+
ensureCredentialsDir(options);
|
|
81
|
+
const path = getCredentialsPath(options);
|
|
82
|
+
|
|
83
|
+
await writeFile(path, JSON.stringify(credentials, null, 2), {
|
|
84
|
+
mode: 0o600, // Owner read/write only
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Store Dokploy credentials
|
|
90
|
+
*/
|
|
91
|
+
export async function storeDokployCredentials(
|
|
92
|
+
token: string,
|
|
93
|
+
endpoint: string,
|
|
94
|
+
options?: CredentialOptions,
|
|
95
|
+
): Promise<void> {
|
|
96
|
+
const credentials = await readCredentials(options);
|
|
97
|
+
|
|
98
|
+
credentials.dokploy = {
|
|
99
|
+
token,
|
|
100
|
+
endpoint,
|
|
101
|
+
storedAt: new Date().toISOString(),
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
await writeCredentials(credentials, options);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Get stored Dokploy credentials
|
|
109
|
+
*/
|
|
110
|
+
export async function getDokployCredentials(
|
|
111
|
+
options?: CredentialOptions,
|
|
112
|
+
): Promise<{
|
|
113
|
+
token: string;
|
|
114
|
+
endpoint: string;
|
|
115
|
+
} | null> {
|
|
116
|
+
const credentials = await readCredentials(options);
|
|
117
|
+
|
|
118
|
+
if (!credentials.dokploy) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
token: credentials.dokploy.token,
|
|
124
|
+
endpoint: credentials.dokploy.endpoint,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Remove Dokploy credentials
|
|
130
|
+
*/
|
|
131
|
+
export async function removeDokployCredentials(
|
|
132
|
+
options?: CredentialOptions,
|
|
133
|
+
): Promise<boolean> {
|
|
134
|
+
const credentials = await readCredentials(options);
|
|
135
|
+
|
|
136
|
+
if (!credentials.dokploy) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
delete credentials.dokploy;
|
|
141
|
+
await writeCredentials(credentials, options);
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Remove all stored credentials
|
|
147
|
+
*/
|
|
148
|
+
export async function removeAllCredentials(
|
|
149
|
+
options?: CredentialOptions,
|
|
150
|
+
): Promise<void> {
|
|
151
|
+
const path = getCredentialsPath(options);
|
|
152
|
+
|
|
153
|
+
if (existsSync(path)) {
|
|
154
|
+
await unlink(path);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Get Dokploy API token, checking stored credentials first, then environment
|
|
160
|
+
*/
|
|
161
|
+
export async function getDokployToken(
|
|
162
|
+
options?: CredentialOptions,
|
|
163
|
+
): Promise<string | null> {
|
|
164
|
+
// First check environment variable (takes precedence)
|
|
165
|
+
const envToken = process.env.DOKPLOY_API_TOKEN;
|
|
166
|
+
if (envToken) {
|
|
167
|
+
return envToken;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Then check stored credentials
|
|
171
|
+
const stored = await getDokployCredentials(options);
|
|
172
|
+
if (stored) {
|
|
173
|
+
return stored.token;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Get Dokploy endpoint from stored credentials
|
|
181
|
+
*/
|
|
182
|
+
export async function getDokployEndpoint(
|
|
183
|
+
options?: CredentialOptions,
|
|
184
|
+
): Promise<string | null> {
|
|
185
|
+
const stored = await getDokployCredentials(options);
|
|
186
|
+
return stored?.endpoint ?? null;
|
|
187
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { stdin as input, stdout as output } from 'node:process';
|
|
2
|
+
import * as readline from 'node:readline/promises';
|
|
3
|
+
import {
|
|
4
|
+
getCredentialsPath,
|
|
5
|
+
getDokployCredentials,
|
|
6
|
+
removeDokployCredentials,
|
|
7
|
+
storeDokployCredentials,
|
|
8
|
+
} from './credentials';
|
|
9
|
+
|
|
10
|
+
const logger = console;
|
|
11
|
+
|
|
12
|
+
export interface LoginOptions {
|
|
13
|
+
/** Service to login to */
|
|
14
|
+
service: 'dokploy';
|
|
15
|
+
/** API token (if not provided, will prompt) */
|
|
16
|
+
token?: string;
|
|
17
|
+
/** Endpoint URL */
|
|
18
|
+
endpoint?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface LogoutOptions {
|
|
22
|
+
/** Service to logout from */
|
|
23
|
+
service?: 'dokploy' | 'all';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Validate Dokploy token by making a test API call
|
|
28
|
+
*/
|
|
29
|
+
export async function validateDokployToken(
|
|
30
|
+
endpoint: string,
|
|
31
|
+
token: string,
|
|
32
|
+
): Promise<boolean> {
|
|
33
|
+
try {
|
|
34
|
+
const response = await fetch(`${endpoint}/api/project.all`, {
|
|
35
|
+
method: 'GET',
|
|
36
|
+
headers: {
|
|
37
|
+
'Content-Type': 'application/json',
|
|
38
|
+
Authorization: `Bearer ${token}`,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return response.ok;
|
|
43
|
+
} catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Prompt for input (handles both TTY and non-TTY)
|
|
50
|
+
*/
|
|
51
|
+
async function prompt(message: string, hidden = false): Promise<string> {
|
|
52
|
+
if (!process.stdin.isTTY) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
'Interactive input required. Please provide --token option.',
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const rl = readline.createInterface({ input, output });
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
if (hidden) {
|
|
62
|
+
// For hidden input, we need to handle it differently
|
|
63
|
+
process.stdout.write(message);
|
|
64
|
+
|
|
65
|
+
return new Promise((resolve) => {
|
|
66
|
+
let value = '';
|
|
67
|
+
|
|
68
|
+
const onData = (char: Buffer) => {
|
|
69
|
+
const c = char.toString();
|
|
70
|
+
|
|
71
|
+
if (c === '\n' || c === '\r') {
|
|
72
|
+
process.stdin.removeListener('data', onData);
|
|
73
|
+
process.stdin.setRawMode(false);
|
|
74
|
+
process.stdout.write('\n');
|
|
75
|
+
resolve(value);
|
|
76
|
+
} else if (c === '\u0003') {
|
|
77
|
+
// Ctrl+C
|
|
78
|
+
process.exit(1);
|
|
79
|
+
} else if (c === '\u007F' || c === '\b') {
|
|
80
|
+
// Backspace
|
|
81
|
+
if (value.length > 0) {
|
|
82
|
+
value = value.slice(0, -1);
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
value += c;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
process.stdin.setRawMode(true);
|
|
90
|
+
process.stdin.resume();
|
|
91
|
+
process.stdin.on('data', onData);
|
|
92
|
+
});
|
|
93
|
+
} else {
|
|
94
|
+
return await rl.question(message);
|
|
95
|
+
}
|
|
96
|
+
} finally {
|
|
97
|
+
rl.close();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Login to a service
|
|
103
|
+
*/
|
|
104
|
+
export async function loginCommand(options: LoginOptions): Promise<void> {
|
|
105
|
+
const { service, token: providedToken, endpoint: providedEndpoint } = options;
|
|
106
|
+
|
|
107
|
+
if (service === 'dokploy') {
|
|
108
|
+
logger.log('\n🔐 Logging in to Dokploy...\n');
|
|
109
|
+
|
|
110
|
+
// Get endpoint
|
|
111
|
+
let endpoint = providedEndpoint;
|
|
112
|
+
if (!endpoint) {
|
|
113
|
+
endpoint = await prompt(
|
|
114
|
+
'Dokploy URL (e.g., https://dokploy.example.com): ',
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Normalize endpoint (remove trailing slash)
|
|
119
|
+
endpoint = endpoint.replace(/\/$/, '');
|
|
120
|
+
|
|
121
|
+
// Validate endpoint format
|
|
122
|
+
try {
|
|
123
|
+
new URL(endpoint);
|
|
124
|
+
} catch {
|
|
125
|
+
logger.error('Invalid URL format');
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Get token
|
|
130
|
+
let token = providedToken;
|
|
131
|
+
if (!token) {
|
|
132
|
+
logger.log(`\nGenerate a token at: ${endpoint}/settings/profile\n`);
|
|
133
|
+
token = await prompt('API Token: ', true);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!token) {
|
|
137
|
+
logger.error('Token is required');
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Validate token
|
|
142
|
+
logger.log('\nValidating credentials...');
|
|
143
|
+
const isValid = await validateDokployToken(endpoint, token);
|
|
144
|
+
|
|
145
|
+
if (!isValid) {
|
|
146
|
+
logger.error(
|
|
147
|
+
'\n✗ Invalid credentials. Please check your token and try again.',
|
|
148
|
+
);
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Store credentials
|
|
153
|
+
await storeDokployCredentials(token, endpoint);
|
|
154
|
+
|
|
155
|
+
logger.log('\n✓ Successfully logged in to Dokploy!');
|
|
156
|
+
logger.log(` Endpoint: ${endpoint}`);
|
|
157
|
+
logger.log(` Credentials stored in: ${getCredentialsPath()}`);
|
|
158
|
+
logger.log(
|
|
159
|
+
'\nYou can now use deploy commands without setting DOKPLOY_API_TOKEN.',
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Logout from a service
|
|
166
|
+
*/
|
|
167
|
+
export async function logoutCommand(options: LogoutOptions): Promise<void> {
|
|
168
|
+
const { service = 'dokploy' } = options;
|
|
169
|
+
|
|
170
|
+
if (service === 'all') {
|
|
171
|
+
const dokployRemoved = await removeDokployCredentials();
|
|
172
|
+
|
|
173
|
+
if (dokployRemoved) {
|
|
174
|
+
logger.log('\n✓ Logged out from all services');
|
|
175
|
+
} else {
|
|
176
|
+
logger.log('\nNo stored credentials found');
|
|
177
|
+
}
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (service === 'dokploy') {
|
|
182
|
+
const removed = await removeDokployCredentials();
|
|
183
|
+
|
|
184
|
+
if (removed) {
|
|
185
|
+
logger.log('\n✓ Logged out from Dokploy');
|
|
186
|
+
} else {
|
|
187
|
+
logger.log('\nNo Dokploy credentials found');
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Show current login status
|
|
194
|
+
*/
|
|
195
|
+
export async function whoamiCommand(): Promise<void> {
|
|
196
|
+
logger.log('\n📋 Current credentials:\n');
|
|
197
|
+
|
|
198
|
+
const dokploy = await getDokployCredentials();
|
|
199
|
+
|
|
200
|
+
if (dokploy) {
|
|
201
|
+
logger.log(' Dokploy:');
|
|
202
|
+
logger.log(` Endpoint: ${dokploy.endpoint}`);
|
|
203
|
+
logger.log(` Token: ${maskToken(dokploy.token)}`);
|
|
204
|
+
} else {
|
|
205
|
+
logger.log(' Dokploy: Not logged in');
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
logger.log(`\n Credentials file: ${getCredentialsPath()}`);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Mask a token for display
|
|
213
|
+
*/
|
|
214
|
+
export function maskToken(token: string): string {
|
|
215
|
+
if (token.length <= 8) {
|
|
216
|
+
return '****';
|
|
217
|
+
}
|
|
218
|
+
return `${token.slice(0, 4)}...${token.slice(-4)}`;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Re-export credentials utilities for use in other modules
|
|
222
|
+
export {
|
|
223
|
+
getDokployCredentials,
|
|
224
|
+
getDokployEndpoint,
|
|
225
|
+
getDokployToken,
|
|
226
|
+
} from './credentials';
|