dockup-cli 1.0.2 → 1.2.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/bin/dockup +2 -0
- package/dist/commands/agent.js +432 -0
- package/dist/commands/auth.js +123 -126
- package/dist/commands/database.js +315 -563
- package/dist/commands/env.js +125 -93
- package/dist/commands/link.js +148 -189
- package/dist/commands/logs.js +100 -82
- package/dist/commands/open.js +69 -41
- package/dist/commands/projects.js +128 -94
- package/dist/commands/push.js +138 -122
- package/dist/commands/service.js +143 -119
- package/dist/commands/status.js +116 -89
- package/dist/commands/workspace.js +210 -220
- package/dist/index.js +77 -179
- package/dist/lib/api.js +248 -185
- package/dist/lib/config.js +135 -142
- package/dist/lib/flags.js +36 -0
- package/dist/lib/output.js +65 -0
- package/dist/lib/target.js +40 -0
- package/dockupcli.md +211 -0
- package/package.json +13 -25
- package/dist/commands/auth.d.ts +0 -5
- package/dist/commands/database.d.ts +0 -16
- package/dist/commands/env.d.ts +0 -5
- package/dist/commands/link.d.ts +0 -2
- package/dist/commands/logs.d.ts +0 -4
- package/dist/commands/open.d.ts +0 -3
- package/dist/commands/projects.d.ts +0 -2
- package/dist/commands/push.d.ts +0 -3
- package/dist/commands/service.d.ts +0 -8
- package/dist/commands/status.d.ts +0 -1
- package/dist/commands/workspace.d.ts +0 -10
- package/dist/index.d.ts +0 -2
- package/dist/lib/api.d.ts +0 -39
- package/dist/lib/config.d.ts +0 -51
package/dist/lib/api.js
CHANGED
|
@@ -1,196 +1,259 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
4
11
|
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var api_exports = {};
|
|
30
|
+
__export(api_exports, {
|
|
31
|
+
api: () => api
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(api_exports);
|
|
34
|
+
var import_node_fetch = __toESM(require("node-fetch"));
|
|
35
|
+
var import_config = require("./config");
|
|
9
36
|
class ApiClient {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
headers['Authorization'] = `Bearer ${token}`;
|
|
18
|
-
}
|
|
19
|
-
return headers;
|
|
20
|
-
}
|
|
21
|
-
async get(path) {
|
|
22
|
-
const url = `${(0, config_1.getApiUrl)()}${path}`;
|
|
23
|
-
const response = await (0, node_fetch_1.default)(url, {
|
|
24
|
-
method: 'GET',
|
|
25
|
-
headers: this.getHeaders(),
|
|
26
|
-
});
|
|
27
|
-
if (!response.ok) {
|
|
28
|
-
const error = await response.json().catch(() => ({}));
|
|
29
|
-
throw new Error(error.error || error.message || `Request failed with status ${response.status}`);
|
|
30
|
-
}
|
|
31
|
-
return response.json();
|
|
32
|
-
}
|
|
33
|
-
async post(path, body) {
|
|
34
|
-
const url = `${(0, config_1.getApiUrl)()}${path}`;
|
|
35
|
-
const response = await (0, node_fetch_1.default)(url, {
|
|
36
|
-
method: 'POST',
|
|
37
|
-
headers: this.getHeaders(!!body),
|
|
38
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
39
|
-
});
|
|
40
|
-
if (!response.ok) {
|
|
41
|
-
const error = await response.json().catch(() => ({}));
|
|
42
|
-
throw new Error(error.error || error.message || `Request failed with status ${response.status}`);
|
|
43
|
-
}
|
|
44
|
-
return response.json();
|
|
45
|
-
}
|
|
46
|
-
async put(path, body) {
|
|
47
|
-
const url = `${(0, config_1.getApiUrl)()}${path}`;
|
|
48
|
-
const response = await (0, node_fetch_1.default)(url, {
|
|
49
|
-
method: 'PUT',
|
|
50
|
-
headers: this.getHeaders(!!body),
|
|
51
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
52
|
-
});
|
|
53
|
-
if (!response.ok) {
|
|
54
|
-
const error = await response.json().catch(() => ({}));
|
|
55
|
-
throw new Error(error.error || error.message || `Request failed with status ${response.status}`);
|
|
56
|
-
}
|
|
57
|
-
return response.json();
|
|
58
|
-
}
|
|
59
|
-
async delete(path) {
|
|
60
|
-
const url = `${(0, config_1.getApiUrl)()}${path}`;
|
|
61
|
-
const response = await (0, node_fetch_1.default)(url, {
|
|
62
|
-
method: 'DELETE',
|
|
63
|
-
headers: this.getHeaders(),
|
|
64
|
-
});
|
|
65
|
-
if (!response.ok) {
|
|
66
|
-
const error = await response.json().catch(() => ({}));
|
|
67
|
-
throw new Error(error.error || error.message || `Request failed with status ${response.status}`);
|
|
68
|
-
}
|
|
69
|
-
return response.json();
|
|
70
|
-
}
|
|
71
|
-
// Verify token and get user info
|
|
72
|
-
async verifyToken() {
|
|
73
|
-
try {
|
|
74
|
-
const response = await this.get('/auth/me');
|
|
75
|
-
return response.user;
|
|
76
|
-
}
|
|
77
|
-
catch {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
// Get projects list
|
|
82
|
-
async getProjects() {
|
|
83
|
-
const response = await this.get('/projects');
|
|
84
|
-
return response.projects || [];
|
|
85
|
-
}
|
|
86
|
-
// Get services for a project
|
|
87
|
-
async getServices(projectSlug) {
|
|
88
|
-
const response = await this.get(`/projects/${projectSlug}/services`);
|
|
89
|
-
return response.services || [];
|
|
37
|
+
getHeaders() {
|
|
38
|
+
const headers = {
|
|
39
|
+
"Content-Type": "application/json"
|
|
40
|
+
};
|
|
41
|
+
const token = (0, import_config.getToken)();
|
|
42
|
+
if (token) {
|
|
43
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
90
44
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
45
|
+
return headers;
|
|
46
|
+
}
|
|
47
|
+
async get(path) {
|
|
48
|
+
const url = `${(0, import_config.getApiUrl)()}${path}`;
|
|
49
|
+
const response = await (0, import_node_fetch.default)(url, {
|
|
50
|
+
method: "GET",
|
|
51
|
+
headers: this.getHeaders()
|
|
52
|
+
});
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
const error = await response.json().catch(() => ({}));
|
|
55
|
+
throw new Error(error.error || error.message || `Request failed with status ${response.status}`);
|
|
94
56
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
57
|
+
return response.json();
|
|
58
|
+
}
|
|
59
|
+
async post(path, body) {
|
|
60
|
+
const url = `${(0, import_config.getApiUrl)()}${path}`;
|
|
61
|
+
const response = await (0, import_node_fetch.default)(url, {
|
|
62
|
+
method: "POST",
|
|
63
|
+
headers: this.getHeaders(),
|
|
64
|
+
body: body ? JSON.stringify(body) : void 0
|
|
65
|
+
});
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
const error = await response.json().catch(() => ({}));
|
|
68
|
+
throw new Error(error.error || error.message || `Request failed with status ${response.status}`);
|
|
98
69
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
70
|
+
return response.json();
|
|
71
|
+
}
|
|
72
|
+
async put(path, body) {
|
|
73
|
+
const url = `${(0, import_config.getApiUrl)()}${path}`;
|
|
74
|
+
const response = await (0, import_node_fetch.default)(url, {
|
|
75
|
+
method: "PUT",
|
|
76
|
+
headers: this.getHeaders(),
|
|
77
|
+
body: body ? JSON.stringify(body) : void 0
|
|
78
|
+
});
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
const error = await response.json().catch(() => ({}));
|
|
81
|
+
throw new Error(error.error || error.message || `Request failed with status ${response.status}`);
|
|
103
82
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
83
|
+
return response.json();
|
|
84
|
+
}
|
|
85
|
+
async delete(path) {
|
|
86
|
+
const url = `${(0, import_config.getApiUrl)()}${path}`;
|
|
87
|
+
const response = await (0, import_node_fetch.default)(url, {
|
|
88
|
+
method: "DELETE",
|
|
89
|
+
headers: this.getHeaders()
|
|
90
|
+
});
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
const error = await response.json().catch(() => ({}));
|
|
93
|
+
throw new Error(error.error || error.message || `Request failed with status ${response.status}`);
|
|
111
94
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
95
|
+
return response.json();
|
|
96
|
+
}
|
|
97
|
+
// Verify token and get user info
|
|
98
|
+
async verifyToken() {
|
|
99
|
+
try {
|
|
100
|
+
const response = await this.get("/auth/me");
|
|
101
|
+
return response.user;
|
|
102
|
+
} catch {
|
|
103
|
+
return null;
|
|
115
104
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
105
|
+
}
|
|
106
|
+
// Get projects list
|
|
107
|
+
async getProjects() {
|
|
108
|
+
const response = await this.get("/projects");
|
|
109
|
+
return response.projects || [];
|
|
110
|
+
}
|
|
111
|
+
// Get services for a project
|
|
112
|
+
async getServices(projectSlug) {
|
|
113
|
+
const response = await this.get(`/projects/${projectSlug}/services`);
|
|
114
|
+
return response.services || [];
|
|
115
|
+
}
|
|
116
|
+
// Trigger deploy
|
|
117
|
+
async deploy(projectSlug, serviceSlug, options) {
|
|
118
|
+
return this.post(`/projects/${projectSlug}/services/${serviceSlug}/deploy`, options);
|
|
119
|
+
}
|
|
120
|
+
// Get service status
|
|
121
|
+
async getServiceStatus(projectSlug, serviceSlug) {
|
|
122
|
+
return this.get(`/projects/${projectSlug}/services/${serviceSlug}`);
|
|
123
|
+
}
|
|
124
|
+
// Get env variables
|
|
125
|
+
async getEnvVariables(projectSlug, serviceSlug) {
|
|
126
|
+
const service = await this.getServiceStatus(projectSlug, serviceSlug);
|
|
127
|
+
return service.envVariables || [];
|
|
128
|
+
}
|
|
129
|
+
// Set env variable
|
|
130
|
+
async setEnvVariable(projectSlug, serviceSlug, key, value, isSecret = false) {
|
|
131
|
+
await this.post(`/projects/${projectSlug}/services/${serviceSlug}/env`, {
|
|
132
|
+
key,
|
|
133
|
+
value,
|
|
134
|
+
isSecret
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
// Delete env variable
|
|
138
|
+
async deleteEnvVariable(projectSlug, serviceSlug, key) {
|
|
139
|
+
await this.delete(`/projects/${projectSlug}/services/${serviceSlug}/env/${key}`);
|
|
140
|
+
}
|
|
141
|
+
// =================== WORKSPACE METHODS ===================
|
|
142
|
+
// Get all workspaces (projects)
|
|
143
|
+
async getWorkspaces() {
|
|
144
|
+
const response = await this.get("/projects");
|
|
145
|
+
return response.projects || [];
|
|
146
|
+
}
|
|
147
|
+
// Create workspace
|
|
148
|
+
async createWorkspace(name) {
|
|
149
|
+
const response = await this.post("/projects", { name });
|
|
150
|
+
return response.project;
|
|
151
|
+
}
|
|
152
|
+
// Rename workspace
|
|
153
|
+
async renameWorkspace(id, name) {
|
|
154
|
+
const response = await this.put(`/projects/${id}`, { name });
|
|
155
|
+
return response.project;
|
|
156
|
+
}
|
|
157
|
+
// Delete workspace
|
|
158
|
+
async deleteWorkspace(id) {
|
|
159
|
+
await this.delete(`/projects/${id}`);
|
|
160
|
+
}
|
|
161
|
+
// =================== DATABASE METHODS ===================
|
|
162
|
+
// Get databases for workspace
|
|
163
|
+
async getDatabases(workspaceId) {
|
|
164
|
+
const response = await this.get(`/databases?projectId=${workspaceId}`);
|
|
165
|
+
return response.databases || [];
|
|
166
|
+
}
|
|
167
|
+
// Create database
|
|
168
|
+
async createDatabase(workspaceId, name, type, version) {
|
|
169
|
+
const response = await this.post("/databases", {
|
|
170
|
+
projectId: workspaceId,
|
|
171
|
+
name,
|
|
172
|
+
type,
|
|
173
|
+
version
|
|
174
|
+
});
|
|
175
|
+
return response.database;
|
|
176
|
+
}
|
|
177
|
+
// Get database details
|
|
178
|
+
async getDatabase(id) {
|
|
179
|
+
const response = await this.get(`/databases/${id}`);
|
|
180
|
+
return response.database;
|
|
181
|
+
}
|
|
182
|
+
// Rename database
|
|
183
|
+
async renameDatabase(id, name) {
|
|
184
|
+
const response = await this.put(`/databases/${id}`, { name });
|
|
185
|
+
return response.database;
|
|
186
|
+
}
|
|
187
|
+
// Delete database
|
|
188
|
+
async deleteDatabase(id) {
|
|
189
|
+
await this.delete(`/databases/${id}`);
|
|
190
|
+
}
|
|
191
|
+
// Get database credentials
|
|
192
|
+
async getDatabaseCredentials(id) {
|
|
193
|
+
return this.get(`/databases/${id}/credentials`);
|
|
194
|
+
}
|
|
195
|
+
// =================== AGENT / READ METHODS ===================
|
|
196
|
+
// Flatten all services across all projects (for discovery).
|
|
197
|
+
async getAllServices() {
|
|
198
|
+
const projects = await this.getProjects();
|
|
199
|
+
const out = [];
|
|
200
|
+
for (const p of projects) {
|
|
201
|
+
try {
|
|
202
|
+
const services = await this.getServices(p.slug);
|
|
203
|
+
for (const s of services) {
|
|
204
|
+
out.push({ ...s, projectSlug: p.slug, projectName: p.name, target: `${p.slug}/${s.slug}` });
|
|
205
|
+
}
|
|
206
|
+
} catch {
|
|
207
|
+
}
|
|
194
208
|
}
|
|
209
|
+
return out;
|
|
210
|
+
}
|
|
211
|
+
// Deployment history (most recent first).
|
|
212
|
+
async getDeployments(projectSlug, serviceSlug, limit = 10) {
|
|
213
|
+
const res = await this.get(
|
|
214
|
+
`/projects/${projectSlug}/services/${serviceSlug}/deployments?limit=${limit}`
|
|
215
|
+
);
|
|
216
|
+
return res.deployments || [];
|
|
217
|
+
}
|
|
218
|
+
// Single deployment details (full build log).
|
|
219
|
+
async getDeployment(projectSlug, serviceSlug, deploymentId) {
|
|
220
|
+
const res = await this.get(
|
|
221
|
+
`/projects/${projectSlug}/services/${serviceSlug}/deployments/${deploymentId}`
|
|
222
|
+
);
|
|
223
|
+
return res.deployment;
|
|
224
|
+
}
|
|
225
|
+
// Build logs of the latest deployment.
|
|
226
|
+
async getBuildLogs(projectSlug, serviceSlug) {
|
|
227
|
+
return this.get(`/projects/${projectSlug}/services/${serviceSlug}/build-logs`);
|
|
228
|
+
}
|
|
229
|
+
// Runtime logs from the running container/pods.
|
|
230
|
+
async getRuntimeLogs(projectSlug, serviceSlug, lines = 100) {
|
|
231
|
+
return this.get(`/projects/${projectSlug}/services/${serviceSlug}/logs?lines=${lines}`);
|
|
232
|
+
}
|
|
233
|
+
// Set private registry credentials (for pulling a private FROM base image).
|
|
234
|
+
async setRegistry(projectSlug, serviceSlug, registryUrl, registryUsername, registryPassword) {
|
|
235
|
+
return this.post(`/projects/${projectSlug}/services/${serviceSlug}/registry`, { registryUrl, registryUsername, registryPassword });
|
|
236
|
+
}
|
|
237
|
+
// Clear private registry credentials.
|
|
238
|
+
async clearRegistry(projectSlug, serviceSlug) {
|
|
239
|
+
return this.delete(`/projects/${projectSlug}/services/${serviceSlug}/registry`);
|
|
240
|
+
}
|
|
241
|
+
// ==================== RESOURCES (reserved CPU/RAM) ====================
|
|
242
|
+
// Database detail (project-scoped) — includes memoryLimitMB / cpuLimit.
|
|
243
|
+
async getDatabaseDetail(projectSlug, dbSlug) {
|
|
244
|
+
return this.get(`/projects/${projectSlug}/databases/${dbSlug}`);
|
|
245
|
+
}
|
|
246
|
+
// Set reserved CPU/RAM for a service (PRO). Applied by recreating the container.
|
|
247
|
+
async setServiceResources(projectSlug, serviceSlug, memoryLimit, cpuLimit) {
|
|
248
|
+
return this.post(`/projects/${projectSlug}/services/${serviceSlug}/resources`, { memoryLimit, cpuLimit });
|
|
249
|
+
}
|
|
250
|
+
// Set reserved CPU/RAM for a database (PRO, main-server only).
|
|
251
|
+
async setDatabaseResources(projectSlug, dbSlug, memoryLimitMB, cpuLimit) {
|
|
252
|
+
return this.post(`/projects/${projectSlug}/databases/${dbSlug}/resources`, { memoryLimitMB, cpuLimit });
|
|
253
|
+
}
|
|
195
254
|
}
|
|
196
|
-
|
|
255
|
+
const api = new ApiClient();
|
|
256
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
257
|
+
0 && (module.exports = {
|
|
258
|
+
api
|
|
259
|
+
});
|