hereya-cli 0.89.1 → 0.91.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 +88 -75
- package/dist/backend/cloud/cloud-backend/apps-deploy.d.ts +69 -0
- package/dist/backend/cloud/cloud-backend/apps-deploy.js +94 -0
- package/dist/backend/cloud/cloud-backend/apps-versions.d.ts +69 -0
- package/dist/backend/cloud/cloud-backend/apps-versions.js +113 -0
- package/dist/backend/cloud/cloud-backend/executor-broker.d.ts +25 -0
- package/dist/backend/cloud/cloud-backend/executor-broker.js +38 -0
- package/dist/backend/cloud/cloud-backend/executor-jobs.d.ts +75 -0
- package/dist/backend/cloud/cloud-backend/executor-jobs.js +110 -0
- package/dist/backend/cloud/cloud-backend/misc.d.ts +5 -0
- package/dist/backend/cloud/cloud-backend/misc.js +78 -0
- package/dist/backend/cloud/cloud-backend/packages-publish.d.ts +3 -0
- package/dist/backend/cloud/cloud-backend/packages-publish.js +99 -0
- package/dist/backend/cloud/cloud-backend/packages-registry.d.ts +6 -0
- package/dist/backend/cloud/cloud-backend/packages-registry.js +146 -0
- package/dist/backend/cloud/cloud-backend/packages-workspace.d.ts +4 -0
- package/dist/backend/cloud/cloud-backend/packages-workspace.js +50 -0
- package/dist/backend/cloud/cloud-backend/projects.d.ts +7 -0
- package/dist/backend/cloud/cloud-backend/projects.js +122 -0
- package/dist/backend/cloud/cloud-backend/state.d.ts +6 -0
- package/dist/backend/cloud/cloud-backend/state.js +86 -0
- package/dist/backend/cloud/cloud-backend/utils.d.ts +55 -0
- package/dist/backend/cloud/cloud-backend/utils.js +56 -0
- package/dist/backend/cloud/cloud-backend/workspace-env.d.ts +5 -0
- package/dist/backend/cloud/cloud-backend/workspace-env.js +63 -0
- package/dist/backend/cloud/cloud-backend/workspaces.d.ts +7 -0
- package/dist/backend/cloud/cloud-backend/workspaces.js +124 -0
- package/dist/backend/cloud/cloud-backend.d.ts +59 -126
- package/dist/backend/cloud/cloud-backend.js +100 -1087
- package/dist/backend/cloud/cloud-backend.test.setup.d.ts +13 -0
- package/dist/backend/cloud/cloud-backend.test.setup.js +14 -0
- package/dist/backend/common.d.ts +2 -2
- package/dist/backend/local.setup.d.ts +10 -0
- package/dist/backend/local.setup.js +20 -0
- package/dist/commands/executor/start/index.d.ts +4 -11
- package/dist/commands/executor/start/index.js +118 -520
- package/dist/commands/workspace/executor/install/index.d.ts +3 -0
- package/dist/commands/workspace/executor/install/index.js +210 -76
- package/dist/commands/workspace/executor/uninstall/index.d.ts +1 -0
- package/dist/commands/workspace/executor/uninstall/index.js +30 -4
- package/dist/executor/local.d.ts +0 -1
- package/dist/executor/local.js +10 -62
- package/dist/executor/resolve-env.d.ts +88 -0
- package/dist/executor/resolve-env.js +77 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +7 -0
- package/dist/infrastructure/index.d.ts +12 -16
- package/dist/infrastructure/index.js +18 -25
- package/dist/infrastructure/registry.d.ts +38 -0
- package/dist/infrastructure/registry.js +61 -0
- package/dist/lib/env/test.setup.d.ts +7 -0
- package/dist/lib/env/test.setup.js +18 -0
- package/dist/lib/executor-start/auth.d.ts +2 -0
- package/dist/lib/executor-start/auth.js +21 -0
- package/dist/lib/executor-start/execute-app-job.d.ts +13 -0
- package/dist/lib/executor-start/execute-app-job.js +146 -0
- package/dist/lib/executor-start/execute-deploy-job.d.ts +14 -0
- package/dist/lib/executor-start/execute-deploy-job.js +64 -0
- package/dist/lib/executor-start/execute-init-job.d.ts +14 -0
- package/dist/lib/executor-start/execute-init-job.js +135 -0
- package/dist/lib/executor-start/format.d.ts +13 -0
- package/dist/lib/executor-start/format.js +22 -0
- package/dist/lib/executor-start/job-dispatch.d.ts +15 -0
- package/dist/lib/executor-start/job-dispatch.js +89 -0
- package/dist/lib/package/index.d.ts +25 -25
- package/oclif.manifest.json +43 -3
- package/package.json +1 -1
|
@@ -1,1137 +1,150 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as appsDeploy from './cloud-backend/apps-deploy.js';
|
|
2
|
+
import * as appsVersions from './cloud-backend/apps-versions.js';
|
|
3
|
+
import * as executorBroker from './cloud-backend/executor-broker.js';
|
|
4
|
+
import * as executorJobs from './cloud-backend/executor-jobs.js';
|
|
5
|
+
import * as misc from './cloud-backend/misc.js';
|
|
6
|
+
import * as packagesPublish from './cloud-backend/packages-publish.js';
|
|
7
|
+
import * as packagesRegistry from './cloud-backend/packages-registry.js';
|
|
8
|
+
import * as packagesWorkspace from './cloud-backend/packages-workspace.js';
|
|
9
|
+
import * as projects from './cloud-backend/projects.js';
|
|
10
|
+
import * as state from './cloud-backend/state.js';
|
|
11
|
+
import * as workspaceEnv from './cloud-backend/workspace-env.js';
|
|
12
|
+
import * as workspaces from './cloud-backend/workspaces.js';
|
|
2
13
|
export class CloudBackend {
|
|
3
14
|
config;
|
|
4
15
|
constructor(config) {
|
|
5
16
|
this.config = config;
|
|
6
17
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
formData.append('package', input.package);
|
|
10
|
-
formData.append('infra', input.infra);
|
|
11
|
-
formData.append('env', JSON.stringify(input.env));
|
|
12
|
-
if (input.parameters) {
|
|
13
|
-
formData.append('parameters', JSON.stringify(input.parameters));
|
|
14
|
-
}
|
|
15
|
-
if (input.version) {
|
|
16
|
-
formData.append('version', input.version);
|
|
17
|
-
}
|
|
18
|
-
const response = await fetch(`${this.config.url}/api/workspaces/${encodeURIComponent(input.workspace)}/packages`, {
|
|
19
|
-
body: formData,
|
|
20
|
-
headers: {
|
|
21
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
22
|
-
},
|
|
23
|
-
method: 'POST',
|
|
24
|
-
});
|
|
25
|
-
if (!response.ok) {
|
|
26
|
-
return {
|
|
27
|
-
reason: JSON.stringify(await this.safeResponseJson(response)),
|
|
28
|
-
success: false,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
const result = await response.json();
|
|
32
|
-
return {
|
|
33
|
-
success: true,
|
|
34
|
-
workspace: this.convertWorkspace(result.workspace),
|
|
35
|
-
};
|
|
18
|
+
addPackageToWorkspace(input) {
|
|
19
|
+
return packagesWorkspace.addPackageToWorkspace(this.config, input);
|
|
36
20
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
formData.append('name', input.name);
|
|
40
|
-
if (input.mirrorOf) {
|
|
41
|
-
formData.append('mirrorOf', input.mirrorOf);
|
|
42
|
-
}
|
|
43
|
-
if (input.profile) {
|
|
44
|
-
formData.append('profile', input.profile);
|
|
45
|
-
}
|
|
46
|
-
if (input.isDeploy !== undefined) {
|
|
47
|
-
formData.append('isDeploy', String(input.isDeploy));
|
|
48
|
-
}
|
|
49
|
-
const response = await fetch(`${this.config.url}/api/workspaces`, {
|
|
50
|
-
body: formData,
|
|
51
|
-
headers: {
|
|
52
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
53
|
-
},
|
|
54
|
-
method: 'POST',
|
|
55
|
-
});
|
|
56
|
-
if (!response.ok) {
|
|
57
|
-
return {
|
|
58
|
-
reason: JSON.stringify(await this.safeResponseJson(response)),
|
|
59
|
-
success: false,
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
const result = await response.json();
|
|
63
|
-
return {
|
|
64
|
-
isNew: true,
|
|
65
|
-
success: true,
|
|
66
|
-
workspace: this.convertWorkspace(result.workspace),
|
|
67
|
-
};
|
|
21
|
+
createWorkspace(input) {
|
|
22
|
+
return workspaces.createWorkspace(this.config, input);
|
|
68
23
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
headers: {
|
|
72
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
73
|
-
},
|
|
74
|
-
method: 'DELETE',
|
|
75
|
-
});
|
|
76
|
-
if (!response.ok) {
|
|
77
|
-
return {
|
|
78
|
-
reason: JSON.stringify(await this.safeResponseJson(response)),
|
|
79
|
-
success: false,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
return {
|
|
83
|
-
message: `State for project ${input.project} in workspace ${input.workspace} deleted successfully`,
|
|
84
|
-
success: true,
|
|
85
|
-
};
|
|
24
|
+
deleteState(input) {
|
|
25
|
+
return state.deleteState(this.config, input);
|
|
86
26
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
headers: {
|
|
90
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
91
|
-
},
|
|
92
|
-
method: 'DELETE',
|
|
93
|
-
});
|
|
94
|
-
if (!response.ok) {
|
|
95
|
-
return {
|
|
96
|
-
reason: JSON.stringify(await this.safeResponseJson(response)),
|
|
97
|
-
success: false,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
return {
|
|
101
|
-
success: true,
|
|
102
|
-
};
|
|
27
|
+
deleteWorkspace(input) {
|
|
28
|
+
return workspaces.deleteWorkspace(this.config, input);
|
|
103
29
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
workspace: input.workspace,
|
|
107
|
-
};
|
|
108
|
-
if (input.version)
|
|
109
|
-
body.version = input.version;
|
|
110
|
-
if (input.parameters)
|
|
111
|
-
body.parameters = input.parameters;
|
|
112
|
-
const response = await fetch(`${this.config.url}/api/apps/${encodeURIComponent(input.name)}/deployments`, {
|
|
113
|
-
body: JSON.stringify(body),
|
|
114
|
-
headers: {
|
|
115
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
116
|
-
'Content-Type': 'application/json',
|
|
117
|
-
},
|
|
118
|
-
method: 'POST',
|
|
119
|
-
});
|
|
120
|
-
if (!response.ok) {
|
|
121
|
-
const error = await this.safeResponseJson(response);
|
|
122
|
-
return { reason: error.error || `Failed to deploy app (status ${response.status})`, success: false };
|
|
123
|
-
}
|
|
124
|
-
const result = await response.json();
|
|
125
|
-
return { deploymentId: result.deploymentId, jobId: result.jobId, success: true };
|
|
30
|
+
deployApp(input) {
|
|
31
|
+
return appsDeploy.deployApp(this.config, input);
|
|
126
32
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const response = await fetch(`${this.config.url}/api/apps/${encodeURIComponent(input.name)}/deployments/${encodeURIComponent(input.workspace)}`, {
|
|
130
|
-
body,
|
|
131
|
-
headers: {
|
|
132
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
133
|
-
...(body ? { 'Content-Type': 'application/json' } : {}),
|
|
134
|
-
},
|
|
135
|
-
method: 'DELETE',
|
|
136
|
-
});
|
|
137
|
-
if (!response.ok) {
|
|
138
|
-
const error = await this.safeResponseJson(response);
|
|
139
|
-
return { reason: error.error || `Failed to destroy app (status ${response.status})`, success: false };
|
|
140
|
-
}
|
|
141
|
-
const result = await response.json();
|
|
142
|
-
return { jobId: result.jobId, success: true };
|
|
33
|
+
destroyApp(input) {
|
|
34
|
+
return appsDeploy.destroyApp(this.config, input);
|
|
143
35
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
headers: {
|
|
147
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
148
|
-
},
|
|
149
|
-
method: 'GET',
|
|
150
|
-
});
|
|
151
|
-
if (!response.ok) {
|
|
152
|
-
return {
|
|
153
|
-
reason: JSON.stringify(await this.safeResponseJson(response)),
|
|
154
|
-
success: false,
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
const result = await response.json();
|
|
158
|
-
if (!result.success) {
|
|
159
|
-
return {
|
|
160
|
-
reason: JSON.stringify(result),
|
|
161
|
-
success: false,
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
return {
|
|
165
|
-
data: JSON.stringify(result.data),
|
|
166
|
-
success: true,
|
|
167
|
-
};
|
|
36
|
+
exportBackend() {
|
|
37
|
+
return misc.exportBackend(this.config);
|
|
168
38
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
headers: { 'Authorization': `Bearer ${this.config.accessToken}` },
|
|
172
|
-
method: 'POST',
|
|
173
|
-
});
|
|
174
|
-
if (!response.ok) {
|
|
175
|
-
const error = await this.safeResponseJson(response);
|
|
176
|
-
return { reason: error.error || 'Failed to generate executor token', success: false };
|
|
177
|
-
}
|
|
178
|
-
const result = await response.json();
|
|
179
|
-
return { expiresAt: result.expiresAt, success: true, token: result.token };
|
|
39
|
+
generateExecutorToken(input) {
|
|
40
|
+
return executorJobs.generateExecutorToken(this.config, input);
|
|
180
41
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
headers: { 'Authorization': `Bearer ${this.config.accessToken}` },
|
|
184
|
-
method: 'GET',
|
|
185
|
-
});
|
|
186
|
-
if (!response.ok) {
|
|
187
|
-
const error = await this.safeResponseJson(response);
|
|
188
|
-
let errorMessage = error.error || `Failed to get app (status ${response.status})`;
|
|
189
|
-
if (response.status === 404) {
|
|
190
|
-
errorMessage = `App '${name}' not found`;
|
|
191
|
-
}
|
|
192
|
-
return { reason: errorMessage, success: false };
|
|
193
|
-
}
|
|
194
|
-
const result = await response.json();
|
|
195
|
-
return { app: result.app, success: true };
|
|
42
|
+
getApp(name) {
|
|
43
|
+
return appsVersions.getApp(this.config, name);
|
|
196
44
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
headers: { 'Authorization': `Bearer ${this.config.accessToken}` },
|
|
200
|
-
method: 'GET',
|
|
201
|
-
});
|
|
202
|
-
if (!response.ok) {
|
|
203
|
-
const error = await this.safeResponseJson(response);
|
|
204
|
-
let errorMessage = error.error || `Failed to get app deployment (status ${response.status})`;
|
|
205
|
-
if (response.status === 404) {
|
|
206
|
-
errorMessage = `Deployment for app '${input.name}' on workspace '${input.workspace}' not found`;
|
|
207
|
-
}
|
|
208
|
-
return { reason: errorMessage, success: false };
|
|
209
|
-
}
|
|
210
|
-
const result = await response.json();
|
|
211
|
-
return { deployment: result.deployment, success: true };
|
|
45
|
+
getAppDeployment(input) {
|
|
46
|
+
return appsDeploy.getAppDeployment(this.config, input);
|
|
212
47
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
? `${this.config.url}/api/apps/${encodeURIComponent(input.name)}/versions/${encodeURIComponent(input.version)}`
|
|
216
|
-
: `${this.config.url}/api/apps/${encodeURIComponent(input.name)}/versions/latest`;
|
|
217
|
-
const response = await fetch(url, {
|
|
218
|
-
headers: { 'Authorization': `Bearer ${this.config.accessToken}` },
|
|
219
|
-
method: 'GET',
|
|
220
|
-
});
|
|
221
|
-
if (!response.ok) {
|
|
222
|
-
const error = await this.safeResponseJson(response);
|
|
223
|
-
let errorMessage = error.error || `Failed to get app version (status ${response.status})`;
|
|
224
|
-
if (response.status === 404) {
|
|
225
|
-
errorMessage = input.version
|
|
226
|
-
? `App version '${input.name}@${input.version}' not found`
|
|
227
|
-
: `App '${input.name}' not found`;
|
|
228
|
-
}
|
|
229
|
-
return { reason: errorMessage, success: false };
|
|
230
|
-
}
|
|
231
|
-
const result = await response.json();
|
|
232
|
-
return { appVersion: result.appVersion ?? result.version, success: true };
|
|
48
|
+
getAppVersion(input) {
|
|
49
|
+
return appsVersions.getAppVersion(this.config, input);
|
|
233
50
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
if (input.poll) {
|
|
237
|
-
url.searchParams.set('poll', 'true');
|
|
238
|
-
}
|
|
239
|
-
if (input.lastStatus) {
|
|
240
|
-
url.searchParams.set('lastStatus', input.lastStatus);
|
|
241
|
-
}
|
|
242
|
-
const response = await fetch(url.toString(), {
|
|
243
|
-
headers: { 'Authorization': `Bearer ${this.config.accessToken}` },
|
|
244
|
-
method: 'GET',
|
|
245
|
-
});
|
|
246
|
-
if (!response.ok) {
|
|
247
|
-
if (response.status === 401) {
|
|
248
|
-
return { reason: 'Unauthorized', success: false };
|
|
249
|
-
}
|
|
250
|
-
const error = await this.safeResponseJson(response);
|
|
251
|
-
return { reason: error.error || 'Failed to get job status', success: false };
|
|
252
|
-
}
|
|
253
|
-
const result = await response.json();
|
|
254
|
-
return { job: result.job, success: true };
|
|
51
|
+
getExecutorJobStatus(input) {
|
|
52
|
+
return executorJobs.getExecutorJobStatus(this.config, input);
|
|
255
53
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
headers: {
|
|
259
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
260
|
-
},
|
|
261
|
-
method: 'GET',
|
|
262
|
-
});
|
|
263
|
-
const result = await this.safeResponseJson(response);
|
|
264
|
-
if (!response.ok) {
|
|
265
|
-
// Handle error responses
|
|
266
|
-
let errorMessage = result.error || 'Failed to get package';
|
|
267
|
-
switch (response.status) {
|
|
268
|
-
case 401: {
|
|
269
|
-
errorMessage = 'Authentication failed. Please run `hereya login` to refresh your credentials.';
|
|
270
|
-
break;
|
|
271
|
-
}
|
|
272
|
-
case 403: {
|
|
273
|
-
errorMessage = `Access denied: ${errorMessage}`;
|
|
274
|
-
break;
|
|
275
|
-
}
|
|
276
|
-
case 404: {
|
|
277
|
-
errorMessage = `Package '${name}@${version}' not found`;
|
|
278
|
-
break;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
return {
|
|
282
|
-
reason: errorMessage,
|
|
283
|
-
success: false,
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
return {
|
|
287
|
-
package: result.package,
|
|
288
|
-
success: true,
|
|
289
|
-
};
|
|
54
|
+
getPackageByVersion(name, version) {
|
|
55
|
+
return packagesRegistry.getPackageByVersion(this.config, name, version);
|
|
290
56
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
headers: {
|
|
294
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
295
|
-
},
|
|
296
|
-
method: 'GET',
|
|
297
|
-
});
|
|
298
|
-
const result = await this.safeResponseJson(response);
|
|
299
|
-
if (!response.ok) {
|
|
300
|
-
// Handle error responses
|
|
301
|
-
let errorMessage = result.error || 'Failed to get package';
|
|
302
|
-
switch (response.status) {
|
|
303
|
-
case 401: {
|
|
304
|
-
errorMessage = 'Authentication failed. Please run `hereya login` to refresh your credentials.';
|
|
305
|
-
break;
|
|
306
|
-
}
|
|
307
|
-
case 403: {
|
|
308
|
-
errorMessage = `Access denied: ${errorMessage}`;
|
|
309
|
-
break;
|
|
310
|
-
}
|
|
311
|
-
case 404: {
|
|
312
|
-
errorMessage = `Package '${name}' not found`;
|
|
313
|
-
break;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
return {
|
|
317
|
-
reason: errorMessage,
|
|
318
|
-
success: false,
|
|
319
|
-
};
|
|
320
|
-
}
|
|
321
|
-
return {
|
|
322
|
-
package: result.package,
|
|
323
|
-
success: true,
|
|
324
|
-
};
|
|
57
|
+
getPackageLatest(name) {
|
|
58
|
+
return packagesRegistry.getPackageLatest(this.config, name);
|
|
325
59
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
headers: {
|
|
329
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
330
|
-
},
|
|
331
|
-
method: 'GET',
|
|
332
|
-
});
|
|
333
|
-
if (!response.ok) {
|
|
334
|
-
return {
|
|
335
|
-
found: false,
|
|
336
|
-
reason: JSON.stringify(await this.safeResponseJson(response)),
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
const result = await this.safeResponseJson(response);
|
|
340
|
-
if (!result.metadata) {
|
|
341
|
-
return {
|
|
342
|
-
found: false,
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
return {
|
|
346
|
-
defaultWorkspace: result.defaultWorkspace,
|
|
347
|
-
found: true,
|
|
348
|
-
metadata: result.metadata,
|
|
349
|
-
};
|
|
60
|
+
getProjectMetadata(input) {
|
|
61
|
+
return projects.getProjectMetadata(this.config, input);
|
|
350
62
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
formData.append('packageCanonicalName', input.packageCanonicalName);
|
|
354
|
-
formData.append('logicalId', input.logicalId);
|
|
355
|
-
if (input.app) {
|
|
356
|
-
formData.append('app', input.app);
|
|
357
|
-
}
|
|
358
|
-
if (input.project) {
|
|
359
|
-
formData.append('project', input.project);
|
|
360
|
-
}
|
|
361
|
-
if (input.workspace) {
|
|
362
|
-
formData.append('workspace', input.workspace);
|
|
363
|
-
}
|
|
364
|
-
const response = await fetch(`${this.config.url}/api/provisioning-id`, {
|
|
365
|
-
body: formData,
|
|
366
|
-
headers: {
|
|
367
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
368
|
-
},
|
|
369
|
-
method: 'POST',
|
|
370
|
-
});
|
|
371
|
-
if (!response.ok) {
|
|
372
|
-
return {
|
|
373
|
-
reason: JSON.stringify(await this.safeResponseJson(response)),
|
|
374
|
-
success: false,
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
const result = await response.json();
|
|
378
|
-
return {
|
|
379
|
-
id: result.provisioningId.id,
|
|
380
|
-
success: true,
|
|
381
|
-
};
|
|
63
|
+
getProvisioningId(input) {
|
|
64
|
+
return misc.getProvisioningId(this.config, input);
|
|
382
65
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
url.searchParams.append('workspace', input.workspace);
|
|
386
|
-
const response = await fetch(url, {
|
|
387
|
-
headers: {
|
|
388
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
389
|
-
},
|
|
390
|
-
method: 'GET',
|
|
391
|
-
});
|
|
392
|
-
if (!response.ok) {
|
|
393
|
-
return {
|
|
394
|
-
found: false,
|
|
395
|
-
reason: JSON.stringify(await this.safeResponseJson(response)),
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
const result = await response.json();
|
|
399
|
-
if (!result.success) {
|
|
400
|
-
return {
|
|
401
|
-
found: false,
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
const deploy = {};
|
|
405
|
-
for (const item of result.config.deploy) {
|
|
406
|
-
deploy[item.name] = { version: item.version };
|
|
407
|
-
}
|
|
408
|
-
const packages = {};
|
|
409
|
-
for (const item of result.config.packages) {
|
|
410
|
-
packages[item.name] = { version: item.version };
|
|
411
|
-
}
|
|
412
|
-
return {
|
|
413
|
-
config: {
|
|
414
|
-
deploy,
|
|
415
|
-
packages,
|
|
416
|
-
project: input.project,
|
|
417
|
-
workspace: input.workspace,
|
|
418
|
-
},
|
|
419
|
-
found: true,
|
|
420
|
-
};
|
|
66
|
+
getState(input) {
|
|
67
|
+
return state.getState(this.config, input);
|
|
421
68
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
headers: {
|
|
425
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
426
|
-
},
|
|
427
|
-
method: 'GET',
|
|
428
|
-
});
|
|
429
|
-
// Handle 404 as "not found" rather than error
|
|
430
|
-
if (response.status === 404) {
|
|
431
|
-
return {
|
|
432
|
-
found: false,
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
if (!response.ok) {
|
|
436
|
-
const error = await this.safeResponseJson(response);
|
|
437
|
-
return {
|
|
438
|
-
error: JSON.stringify(error),
|
|
439
|
-
found: true,
|
|
440
|
-
hasError: true,
|
|
441
|
-
};
|
|
442
|
-
}
|
|
443
|
-
const result = await response.json();
|
|
444
|
-
return {
|
|
445
|
-
found: true,
|
|
446
|
-
hasError: false,
|
|
447
|
-
workspace: this.convertWorkspace(result.workspace),
|
|
448
|
-
};
|
|
69
|
+
getWorkspace(name) {
|
|
70
|
+
return workspaces.getWorkspace(this.config, name);
|
|
449
71
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
const workspaceName = resolveWorkspaceName(input.workspace, input.project);
|
|
453
|
-
const workspace$ = await this.getWorkspace(workspaceName);
|
|
454
|
-
if (!workspace$.found) {
|
|
455
|
-
return {
|
|
456
|
-
reason: `Workspace ${input.workspace} not found`,
|
|
457
|
-
success: false,
|
|
458
|
-
};
|
|
459
|
-
}
|
|
460
|
-
if (workspace$.hasError) {
|
|
461
|
-
return {
|
|
462
|
-
reason: workspace$.error,
|
|
463
|
-
success: false,
|
|
464
|
-
};
|
|
465
|
-
}
|
|
466
|
-
return {
|
|
467
|
-
env: workspace$.workspace.env ?? {},
|
|
468
|
-
success: true,
|
|
469
|
-
};
|
|
72
|
+
getWorkspaceEnv(input) {
|
|
73
|
+
return workspaceEnv.getWorkspaceEnv(this.config, input);
|
|
470
74
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
formData.append('data', input.data);
|
|
474
|
-
const response = await fetch(`${this.config.url}/api/import`, {
|
|
475
|
-
body: formData,
|
|
476
|
-
headers: {
|
|
477
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
478
|
-
},
|
|
479
|
-
method: 'POST',
|
|
480
|
-
});
|
|
481
|
-
if (!response.ok) {
|
|
482
|
-
return {
|
|
483
|
-
reason: JSON.stringify(await this.safeResponseJson(response)),
|
|
484
|
-
success: false,
|
|
485
|
-
};
|
|
486
|
-
}
|
|
487
|
-
return {
|
|
488
|
-
success: true,
|
|
489
|
-
};
|
|
75
|
+
importBackend(input) {
|
|
76
|
+
return misc.importBackend(this.config, input);
|
|
490
77
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
body: JSON.stringify({ repoUrl: input.repoUrl, workspace: input.workspace }),
|
|
494
|
-
headers: {
|
|
495
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
496
|
-
'Content-Type': 'application/json',
|
|
497
|
-
},
|
|
498
|
-
method: 'POST',
|
|
499
|
-
});
|
|
500
|
-
const result = await this.safeResponseJson(response);
|
|
501
|
-
if (!response.ok) {
|
|
502
|
-
const reason = typeof result?.error === 'string'
|
|
503
|
-
? result.error
|
|
504
|
-
: (result?.errors && typeof result.errors === 'object'
|
|
505
|
-
? JSON.stringify(result.errors)
|
|
506
|
-
: JSON.stringify(result));
|
|
507
|
-
return {
|
|
508
|
-
...(typeof result?.code === 'string' ? { code: result.code } : {}),
|
|
509
|
-
reason,
|
|
510
|
-
success: false,
|
|
511
|
-
};
|
|
512
|
-
}
|
|
513
|
-
if (!result?.success || !result?.project) {
|
|
514
|
-
return {
|
|
515
|
-
reason: typeof result?.error === 'string' ? result.error : 'Unexpected response from server',
|
|
516
|
-
success: false,
|
|
517
|
-
};
|
|
518
|
-
}
|
|
519
|
-
return {
|
|
520
|
-
project: {
|
|
521
|
-
defaultWorkspace: result.project.defaultWorkspace,
|
|
522
|
-
name: result.project.name,
|
|
523
|
-
},
|
|
524
|
-
success: true,
|
|
525
|
-
};
|
|
78
|
+
importProject(input) {
|
|
79
|
+
return projects.importProject(this.config, input);
|
|
526
80
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
formData.append('name', input.project);
|
|
530
|
-
formData.append('workspace', input.workspace);
|
|
531
|
-
const response = await fetch(`${this.config.url}/api/projects`, {
|
|
532
|
-
body: formData,
|
|
533
|
-
headers: {
|
|
534
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
535
|
-
},
|
|
536
|
-
method: 'POST',
|
|
537
|
-
});
|
|
538
|
-
if (!response.ok) {
|
|
539
|
-
throw new Error(JSON.stringify(await this.safeResponseJson(response)));
|
|
540
|
-
}
|
|
541
|
-
const result = await response.json();
|
|
542
|
-
return {
|
|
543
|
-
project: {
|
|
544
|
-
id: result.project.id,
|
|
545
|
-
name: result.project.name,
|
|
546
|
-
},
|
|
547
|
-
workspace: {
|
|
548
|
-
id: result.project.defaultWorkspace.id,
|
|
549
|
-
name: result.project.defaultWorkspace.name,
|
|
550
|
-
},
|
|
551
|
-
};
|
|
81
|
+
init(input) {
|
|
82
|
+
return projects.init(this.config, input);
|
|
552
83
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
headers: { 'Authorization': `Bearer ${this.config.accessToken}` },
|
|
556
|
-
method: 'GET',
|
|
557
|
-
});
|
|
558
|
-
if (!response.ok) {
|
|
559
|
-
const error = await this.safeResponseJson(response);
|
|
560
|
-
return { reason: error.error || `Failed to list app deployments (status ${response.status})`, success: false };
|
|
561
|
-
}
|
|
562
|
-
const result = await response.json();
|
|
563
|
-
return { deployments: result.deployments || [], success: true };
|
|
84
|
+
listAppDeployments(name) {
|
|
85
|
+
return appsDeploy.listAppDeployments(this.config, name);
|
|
564
86
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
headers: { 'Authorization': `Bearer ${this.config.accessToken}` },
|
|
568
|
-
method: 'GET',
|
|
569
|
-
});
|
|
570
|
-
if (!response.ok) {
|
|
571
|
-
const error = await this.safeResponseJson(response);
|
|
572
|
-
return { reason: error.error || `Failed to list apps (status ${response.status})`, success: false };
|
|
573
|
-
}
|
|
574
|
-
const result = await response.json();
|
|
575
|
-
return { apps: result.apps || [], success: true };
|
|
87
|
+
listApps() {
|
|
88
|
+
return appsVersions.listApps(this.config);
|
|
576
89
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
headers: { 'Authorization': `Bearer ${this.config.accessToken}` },
|
|
580
|
-
method: 'GET',
|
|
581
|
-
});
|
|
582
|
-
if (!response.ok) {
|
|
583
|
-
const error = await this.safeResponseJson(response);
|
|
584
|
-
return { reason: error.error || `Failed to list app versions (status ${response.status})`, success: false };
|
|
585
|
-
}
|
|
586
|
-
const result = await response.json();
|
|
587
|
-
return { success: true, versions: result.versions || [] };
|
|
90
|
+
listAppVersions(name) {
|
|
91
|
+
return appsVersions.listAppVersions(this.config, name);
|
|
588
92
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
headers: {
|
|
592
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
593
|
-
},
|
|
594
|
-
method: 'GET',
|
|
595
|
-
});
|
|
596
|
-
const result = await this.safeResponseJson(response);
|
|
597
|
-
if (!response.ok) {
|
|
598
|
-
// Handle error responses
|
|
599
|
-
let errorMessage = result.error || 'Failed to list package versions';
|
|
600
|
-
switch (response.status) {
|
|
601
|
-
case 401: {
|
|
602
|
-
errorMessage = 'Authentication failed. Please run `hereya login` to refresh your credentials.';
|
|
603
|
-
break;
|
|
604
|
-
}
|
|
605
|
-
case 403: {
|
|
606
|
-
errorMessage = `Access denied: ${errorMessage}`;
|
|
607
|
-
break;
|
|
608
|
-
}
|
|
609
|
-
case 404: {
|
|
610
|
-
errorMessage = `Package '${name}' not found`;
|
|
611
|
-
break;
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
return {
|
|
615
|
-
reason: errorMessage,
|
|
616
|
-
success: false,
|
|
617
|
-
};
|
|
618
|
-
}
|
|
619
|
-
return {
|
|
620
|
-
packages: result.packages || [],
|
|
621
|
-
success: true,
|
|
622
|
-
};
|
|
93
|
+
listPackageVersions(name) {
|
|
94
|
+
return packagesRegistry.listPackageVersions(this.config, name);
|
|
623
95
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
headers: { 'Authorization': `Bearer ${this.config.accessToken}` },
|
|
627
|
-
method: 'GET',
|
|
628
|
-
});
|
|
629
|
-
if (!response.ok) {
|
|
630
|
-
throw new Error(JSON.stringify(await this.safeResponseJson(response)));
|
|
631
|
-
}
|
|
632
|
-
const result = await response.json();
|
|
633
|
-
return (result.projects ?? []).map((p) => ({
|
|
634
|
-
defaultWorkspace: p.defaultWorkspace?.name ?? '-',
|
|
635
|
-
name: p.name,
|
|
636
|
-
}));
|
|
96
|
+
listProjects() {
|
|
97
|
+
return projects.listProjects(this.config);
|
|
637
98
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
if (input?.org) {
|
|
641
|
-
url.searchParams.set('org', input.org);
|
|
642
|
-
}
|
|
643
|
-
const response = await fetch(url.toString(), {
|
|
644
|
-
headers: {
|
|
645
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
646
|
-
},
|
|
647
|
-
method: 'GET',
|
|
648
|
-
});
|
|
649
|
-
if (!response.ok) {
|
|
650
|
-
throw new Error(JSON.stringify(await this.safeResponseJson(response)));
|
|
651
|
-
}
|
|
652
|
-
const result = await response.json();
|
|
653
|
-
return result.workspaces.map((workspace) => workspace.name);
|
|
99
|
+
listWorkspaces(input) {
|
|
100
|
+
return workspaces.listWorkspaces(this.config, input);
|
|
654
101
|
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
url.searchParams.set('workspace', input.workspace);
|
|
658
|
-
if (input.executorId) {
|
|
659
|
-
url.searchParams.set('executorId', input.executorId);
|
|
660
|
-
}
|
|
661
|
-
const response = await fetch(url.toString(), {
|
|
662
|
-
headers: { 'Authorization': `Bearer ${this.config.accessToken}` },
|
|
663
|
-
method: 'GET',
|
|
664
|
-
});
|
|
665
|
-
if (!response.ok) {
|
|
666
|
-
if (response.status === 401) {
|
|
667
|
-
return { reason: 'Unauthorized', success: false, unauthorized: true };
|
|
668
|
-
}
|
|
669
|
-
const error = await this.safeResponseJson(response);
|
|
670
|
-
return { reason: error.error || 'Failed to poll for jobs', success: false };
|
|
671
|
-
}
|
|
672
|
-
const result = await response.json();
|
|
673
|
-
return { job: result.job, success: true };
|
|
102
|
+
pollExecutorJobs(input) {
|
|
103
|
+
return executorJobs.pollExecutorJobs(this.config, input);
|
|
674
104
|
}
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
commit: input.commit,
|
|
678
|
-
hereyaYaml: input.hereyaYaml,
|
|
679
|
-
repository: input.repository,
|
|
680
|
-
sha256: input.sha256,
|
|
681
|
-
version: input.version,
|
|
682
|
-
};
|
|
683
|
-
if (input.description !== undefined)
|
|
684
|
-
requestBody.description = input.description;
|
|
685
|
-
if (input.visibility !== undefined)
|
|
686
|
-
requestBody.visibility = input.visibility;
|
|
687
|
-
if (input.parameters !== undefined)
|
|
688
|
-
requestBody.parameters = input.parameters;
|
|
689
|
-
const response = await fetch(`${this.config.url}/api/apps/${encodeURIComponent(input.name)}/versions`, {
|
|
690
|
-
body: JSON.stringify(requestBody),
|
|
691
|
-
headers: {
|
|
692
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
693
|
-
'Content-Type': 'application/json',
|
|
694
|
-
},
|
|
695
|
-
method: 'POST',
|
|
696
|
-
});
|
|
697
|
-
const result = await this.safeResponseJson(response);
|
|
698
|
-
if (!response.ok) {
|
|
699
|
-
let errorMessage = result.error || 'Failed to publish app version';
|
|
700
|
-
switch (response.status) {
|
|
701
|
-
case 401: {
|
|
702
|
-
errorMessage = 'Authentication failed. Please run `hereya login` to refresh your credentials.';
|
|
703
|
-
break;
|
|
704
|
-
}
|
|
705
|
-
case 403: {
|
|
706
|
-
errorMessage = `Permission denied: ${errorMessage}`;
|
|
707
|
-
break;
|
|
708
|
-
}
|
|
709
|
-
case 409: {
|
|
710
|
-
errorMessage = `Conflict: ${errorMessage}`;
|
|
711
|
-
break;
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
return { reason: errorMessage, success: false };
|
|
715
|
-
}
|
|
716
|
-
const app = result.appVersion ?? result.app ?? { name: input.name, version: input.version };
|
|
717
|
-
return {
|
|
718
|
-
app: {
|
|
719
|
-
id: app.id,
|
|
720
|
-
name: app.name ?? input.name,
|
|
721
|
-
version: app.version ?? input.version,
|
|
722
|
-
},
|
|
723
|
-
success: true,
|
|
724
|
-
};
|
|
105
|
+
publishAppVersion(input) {
|
|
106
|
+
return appsVersions.publishAppVersion(this.config, input);
|
|
725
107
|
}
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
formData.append('name', input.name);
|
|
729
|
-
formData.append('version', input.version);
|
|
730
|
-
formData.append('description', input.description);
|
|
731
|
-
formData.append('repository', input.repository);
|
|
732
|
-
formData.append('commit', input.commit);
|
|
733
|
-
formData.append('sha256', input.sha256);
|
|
734
|
-
formData.append('iac', input.iac);
|
|
735
|
-
formData.append('infra', input.infra);
|
|
736
|
-
if (input.doc) {
|
|
737
|
-
formData.append('doc', input.doc);
|
|
738
|
-
}
|
|
739
|
-
if (input.visibility) {
|
|
740
|
-
formData.append('visibility', input.visibility);
|
|
741
|
-
}
|
|
742
|
-
if (input.onDeployPkg) {
|
|
743
|
-
formData.append('onDeployPkg', input.onDeployPkg);
|
|
744
|
-
}
|
|
745
|
-
if (input.onDeployVersion) {
|
|
746
|
-
formData.append('onDeployVersion', input.onDeployVersion);
|
|
747
|
-
}
|
|
748
|
-
const response = await fetch(`${this.config.url}/api/registry/packages`, {
|
|
749
|
-
body: formData,
|
|
750
|
-
headers: {
|
|
751
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
752
|
-
},
|
|
753
|
-
method: 'POST',
|
|
754
|
-
});
|
|
755
|
-
const result = await this.safeResponseJson(response);
|
|
756
|
-
if (!response.ok) {
|
|
757
|
-
// Handle validation errors (field-specific errors)
|
|
758
|
-
if (result.errors && typeof result.errors === 'object') {
|
|
759
|
-
const errorMessages = [];
|
|
760
|
-
// Add main error message if present
|
|
761
|
-
if (result.error) {
|
|
762
|
-
errorMessages.push(result.error, ''); // Empty line for separation
|
|
763
|
-
}
|
|
764
|
-
// Add field-specific errors
|
|
765
|
-
for (const [field, messages] of Object.entries(result.errors)) {
|
|
766
|
-
if (Array.isArray(messages)) {
|
|
767
|
-
errorMessages.push(`${field}: ${messages.join(', ')}`);
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
// Add help message if present
|
|
771
|
-
if (result.help) {
|
|
772
|
-
errorMessages.push('', `ℹ️ ${result.help}`);
|
|
773
|
-
}
|
|
774
|
-
return {
|
|
775
|
-
reason: errorMessages.join('\n'),
|
|
776
|
-
success: false,
|
|
777
|
-
};
|
|
778
|
-
}
|
|
779
|
-
// Handle other errors with more context
|
|
780
|
-
const errorMessages = [];
|
|
781
|
-
const errorMessage = result.error || 'Unknown error occurred';
|
|
782
|
-
// Add main error with context based on errorType or status code
|
|
783
|
-
if (result.errorType) {
|
|
784
|
-
errorMessages.push(`[${result.errorType}] ${errorMessage}`);
|
|
785
|
-
}
|
|
786
|
-
else {
|
|
787
|
-
// Fallback to status-based context
|
|
788
|
-
switch (response.status) {
|
|
789
|
-
case 401: {
|
|
790
|
-
errorMessages.push('Authentication failed. Please run `hereya login` to refresh your credentials.');
|
|
791
|
-
break;
|
|
792
|
-
}
|
|
793
|
-
case 403: {
|
|
794
|
-
errorMessages.push(`Permission denied: ${errorMessage}`);
|
|
795
|
-
break;
|
|
796
|
-
}
|
|
797
|
-
case 409: {
|
|
798
|
-
errorMessages.push(`Conflict: ${errorMessage}`);
|
|
799
|
-
break;
|
|
800
|
-
}
|
|
801
|
-
default: {
|
|
802
|
-
if (response.status >= 500) {
|
|
803
|
-
errorMessages.push(`Server error: ${errorMessage} (status ${response.status})`);
|
|
804
|
-
}
|
|
805
|
-
else {
|
|
806
|
-
errorMessages.push(errorMessage);
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
// Add help message if present
|
|
812
|
-
if (result.help) {
|
|
813
|
-
errorMessages.push('', `ℹ️ ${result.help}`);
|
|
814
|
-
}
|
|
815
|
-
// Add package info if present (helpful for debugging)
|
|
816
|
-
if (result.package) {
|
|
817
|
-
errorMessages.push('', `Package: ${result.package.name}@${result.package.version}`);
|
|
818
|
-
}
|
|
819
|
-
return {
|
|
820
|
-
reason: errorMessages.join('\n'),
|
|
821
|
-
success: false,
|
|
822
|
-
};
|
|
823
|
-
}
|
|
824
|
-
return {
|
|
825
|
-
package: result.package,
|
|
826
|
-
success: true,
|
|
827
|
-
};
|
|
108
|
+
publishPackage(input) {
|
|
109
|
+
return packagesPublish.publishPackage(this.config, input);
|
|
828
110
|
}
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
headers: {
|
|
832
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
833
|
-
},
|
|
834
|
-
method: 'DELETE',
|
|
835
|
-
});
|
|
836
|
-
if (!response.ok) {
|
|
837
|
-
return {
|
|
838
|
-
reason: JSON.stringify(await this.safeResponseJson(response)),
|
|
839
|
-
success: false,
|
|
840
|
-
};
|
|
841
|
-
}
|
|
842
|
-
const result = await response.json();
|
|
843
|
-
return {
|
|
844
|
-
success: true,
|
|
845
|
-
workspace: this.convertWorkspace(result.workspace),
|
|
846
|
-
};
|
|
111
|
+
registerExecutorBroker(input) {
|
|
112
|
+
return executorBroker.registerExecutorBroker(this.config, input);
|
|
847
113
|
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
headers: { 'Authorization': `Bearer ${this.config.accessToken}` },
|
|
851
|
-
method: 'DELETE',
|
|
852
|
-
});
|
|
853
|
-
if (!response.ok) {
|
|
854
|
-
const error = await this.safeResponseJson(response);
|
|
855
|
-
return { reason: error.error || 'Failed to revoke executor token', success: false };
|
|
856
|
-
}
|
|
857
|
-
return { success: true };
|
|
114
|
+
removePackageFromWorkspace(input) {
|
|
115
|
+
return packagesWorkspace.removePackageFromWorkspace(this.config, input);
|
|
858
116
|
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
formData.append('metadata', JSON.stringify(input.metadata));
|
|
862
|
-
const response = await fetch(`${this.config.url}/api/projects/${encodeURIComponent(input.project)}/metadata`, {
|
|
863
|
-
body: formData,
|
|
864
|
-
headers: {
|
|
865
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
866
|
-
},
|
|
867
|
-
method: 'POST',
|
|
868
|
-
});
|
|
869
|
-
if (!response.ok) {
|
|
870
|
-
return {
|
|
871
|
-
reason: JSON.stringify(await this.safeResponseJson(response)),
|
|
872
|
-
success: false,
|
|
873
|
-
};
|
|
874
|
-
}
|
|
875
|
-
return {
|
|
876
|
-
success: true,
|
|
877
|
-
};
|
|
117
|
+
revokeExecutorToken(input) {
|
|
118
|
+
return executorJobs.revokeExecutorToken(this.config, input);
|
|
878
119
|
}
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
if (workspace) {
|
|
882
|
-
formData.append('workspace', workspace);
|
|
883
|
-
}
|
|
884
|
-
if (config.deploy) {
|
|
885
|
-
const deployArray = Object.entries(config.deploy).map(([name, { version }]) => ({ name, version })).sort((a, b) => a.name.localeCompare(b.name));
|
|
886
|
-
formData.append('deploy', JSON.stringify(deployArray));
|
|
887
|
-
}
|
|
888
|
-
if (config.packages) {
|
|
889
|
-
const packagesArray = Object.entries(config.packages).map(([name, { version }]) => ({ name, version })).sort((a, b) => a.name.localeCompare(b.name));
|
|
890
|
-
formData.append('packages', JSON.stringify(packagesArray));
|
|
891
|
-
}
|
|
892
|
-
const response = await fetch(`${this.config.url}/api/projects/${encodeURIComponent(config.project)}/state`, {
|
|
893
|
-
body: formData,
|
|
894
|
-
headers: {
|
|
895
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
896
|
-
},
|
|
897
|
-
method: 'POST',
|
|
898
|
-
});
|
|
899
|
-
if (!response.ok) {
|
|
900
|
-
throw new Error(JSON.stringify(await this.safeResponseJson(response)));
|
|
901
|
-
}
|
|
120
|
+
saveProjectMetadata(input) {
|
|
121
|
+
return projects.saveProjectMetadata(this.config, input);
|
|
902
122
|
}
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
url.searchParams.append('q', input.query);
|
|
906
|
-
if (input.limit !== undefined) {
|
|
907
|
-
url.searchParams.append('limit', String(input.limit));
|
|
908
|
-
}
|
|
909
|
-
if (input.offset !== undefined) {
|
|
910
|
-
url.searchParams.append('offset', String(input.offset));
|
|
911
|
-
}
|
|
912
|
-
const response = await fetch(url, {
|
|
913
|
-
headers: {
|
|
914
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
915
|
-
},
|
|
916
|
-
method: 'GET',
|
|
917
|
-
});
|
|
918
|
-
const result = await this.safeResponseJson(response);
|
|
919
|
-
if (!response.ok) {
|
|
920
|
-
let errorMessage = result.error || 'Failed to search packages';
|
|
921
|
-
switch (response.status) {
|
|
922
|
-
case 400: {
|
|
923
|
-
errorMessage = `Invalid search query: ${errorMessage}`;
|
|
924
|
-
break;
|
|
925
|
-
}
|
|
926
|
-
case 401: {
|
|
927
|
-
errorMessage = 'Authentication failed. Please run `hereya login` to refresh your credentials.';
|
|
928
|
-
break;
|
|
929
|
-
}
|
|
930
|
-
case 500: {
|
|
931
|
-
errorMessage = `Server error: ${errorMessage}`;
|
|
932
|
-
break;
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
return {
|
|
936
|
-
reason: errorMessage,
|
|
937
|
-
success: false,
|
|
938
|
-
};
|
|
939
|
-
}
|
|
940
|
-
return {
|
|
941
|
-
hasMore: result.hasMore ?? false,
|
|
942
|
-
packages: result.packages || [],
|
|
943
|
-
success: true,
|
|
944
|
-
};
|
|
123
|
+
saveState(config, workspace) {
|
|
124
|
+
return state.saveState(this.config, config, workspace);
|
|
945
125
|
}
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
formData.append('key', input.name);
|
|
949
|
-
formData.append('value', input.value);
|
|
950
|
-
formData.append('infrastructure', input.infrastructure);
|
|
951
|
-
const response = await fetch(`${this.config.url}/api/workspaces/${encodeURIComponent(input.workspace)}/env`, {
|
|
952
|
-
body: formData,
|
|
953
|
-
headers: {
|
|
954
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
955
|
-
},
|
|
956
|
-
method: 'POST',
|
|
957
|
-
});
|
|
958
|
-
if (!response.ok) {
|
|
959
|
-
return {
|
|
960
|
-
reason: JSON.stringify(await this.safeResponseJson(response)),
|
|
961
|
-
success: false,
|
|
962
|
-
};
|
|
963
|
-
}
|
|
964
|
-
return {
|
|
965
|
-
success: true,
|
|
966
|
-
};
|
|
126
|
+
searchPackages(input) {
|
|
127
|
+
return packagesRegistry.searchPackages(this.config, input);
|
|
967
128
|
}
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
formData.append('type', input.type);
|
|
971
|
-
formData.append('payload', JSON.stringify(input.payload));
|
|
972
|
-
const response = await fetch(`${this.config.url}/api/workspaces/${encodeURIComponent(input.workspace)}/jobs`, {
|
|
973
|
-
body: formData,
|
|
974
|
-
headers: { 'Authorization': `Bearer ${this.config.accessToken}` },
|
|
975
|
-
method: 'POST',
|
|
976
|
-
});
|
|
977
|
-
if (!response.ok) {
|
|
978
|
-
if (response.status === 401) {
|
|
979
|
-
return { reason: 'Unauthorized', success: false };
|
|
980
|
-
}
|
|
981
|
-
const error = await this.safeResponseJson(response);
|
|
982
|
-
return { reason: error.error || 'Failed to submit executor job', success: false };
|
|
983
|
-
}
|
|
984
|
-
const result = await response.json();
|
|
985
|
-
return { jobId: result.jobId, success: true };
|
|
129
|
+
setEnvVar(input) {
|
|
130
|
+
return workspaceEnv.setEnvVar(this.config, input);
|
|
986
131
|
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
headers: {
|
|
990
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
991
|
-
},
|
|
992
|
-
method: 'DELETE',
|
|
993
|
-
});
|
|
994
|
-
if (!response.ok) {
|
|
995
|
-
return {
|
|
996
|
-
reason: JSON.stringify(await this.safeResponseJson(response)),
|
|
997
|
-
success: false,
|
|
998
|
-
};
|
|
999
|
-
}
|
|
1000
|
-
return {
|
|
1001
|
-
success: true,
|
|
1002
|
-
};
|
|
132
|
+
submitExecutorJob(input) {
|
|
133
|
+
return executorJobs.submitExecutorJob(this.config, input);
|
|
1003
134
|
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
if (input.state !== undefined)
|
|
1007
|
-
body.state = input.state;
|
|
1008
|
-
if (input.env !== undefined)
|
|
1009
|
-
body.env = input.env;
|
|
1010
|
-
if (input.lastJobId !== undefined)
|
|
1011
|
-
body.lastJobId = input.lastJobId;
|
|
1012
|
-
const response = await fetch(`${this.config.url}/api/apps/${encodeURIComponent(input.name)}/deployments/${encodeURIComponent(input.workspace)}`, {
|
|
1013
|
-
body: JSON.stringify(body),
|
|
1014
|
-
headers: {
|
|
1015
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
1016
|
-
'Content-Type': 'application/json',
|
|
1017
|
-
},
|
|
1018
|
-
method: 'PATCH',
|
|
1019
|
-
});
|
|
1020
|
-
if (!response.ok) {
|
|
1021
|
-
const error = await this.safeResponseJson(response);
|
|
1022
|
-
return { reason: error.error || `Failed to update app deployment (status ${response.status})`, success: false };
|
|
1023
|
-
}
|
|
1024
|
-
return { success: true };
|
|
135
|
+
unregisterExecutorBroker(input) {
|
|
136
|
+
return executorBroker.unregisterExecutorBroker(this.config, input);
|
|
1025
137
|
}
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
if (input.logs) {
|
|
1029
|
-
formData.append('logs', input.logs);
|
|
1030
|
-
}
|
|
1031
|
-
if (input.status) {
|
|
1032
|
-
formData.append('status', input.status);
|
|
1033
|
-
}
|
|
1034
|
-
if (input.result) {
|
|
1035
|
-
formData.append('result', JSON.stringify(input.result));
|
|
1036
|
-
}
|
|
1037
|
-
const response = await fetch(`${this.config.url}/api/executor/jobs/${encodeURIComponent(input.jobId)}`, {
|
|
1038
|
-
body: formData,
|
|
1039
|
-
headers: { 'Authorization': `Bearer ${this.config.accessToken}` },
|
|
1040
|
-
method: 'PATCH',
|
|
1041
|
-
});
|
|
1042
|
-
if (!response.ok) {
|
|
1043
|
-
if (response.status === 401) {
|
|
1044
|
-
return { reason: 'Unauthorized', success: false, unauthorized: true };
|
|
1045
|
-
}
|
|
1046
|
-
const error = await this.safeResponseJson(response);
|
|
1047
|
-
return { reason: error.error || 'Failed to update job', success: false };
|
|
1048
|
-
}
|
|
1049
|
-
return { success: true };
|
|
138
|
+
unsetEnvVar(input) {
|
|
139
|
+
return workspaceEnv.unsetEnvVar(this.config, input);
|
|
1050
140
|
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
if (input.profile !== undefined) {
|
|
1054
|
-
formData.append('profile', input.profile === null ? '' : input.profile);
|
|
1055
|
-
}
|
|
1056
|
-
if (input.hasExecutor !== undefined) {
|
|
1057
|
-
formData.append('hasExecutor', input.hasExecutor === null ? '' : String(input.hasExecutor));
|
|
1058
|
-
}
|
|
1059
|
-
if (input.isDeploy !== undefined) {
|
|
1060
|
-
formData.append('isDeploy', input.isDeploy === null ? '' : String(input.isDeploy));
|
|
1061
|
-
}
|
|
1062
|
-
const response = await fetch(`${this.config.url}/api/workspaces/${encodeURIComponent(input.name)}`, {
|
|
1063
|
-
body: formData,
|
|
1064
|
-
headers: {
|
|
1065
|
-
'Authorization': `Bearer ${this.config.accessToken}`,
|
|
1066
|
-
},
|
|
1067
|
-
method: 'PATCH',
|
|
1068
|
-
});
|
|
1069
|
-
if (!response.ok) {
|
|
1070
|
-
return {
|
|
1071
|
-
reason: JSON.stringify(await this.safeResponseJson(response)),
|
|
1072
|
-
success: false,
|
|
1073
|
-
};
|
|
1074
|
-
}
|
|
1075
|
-
const result = await response.json();
|
|
1076
|
-
return {
|
|
1077
|
-
success: true,
|
|
1078
|
-
workspace: this.convertWorkspace(result.workspace),
|
|
1079
|
-
};
|
|
141
|
+
updateAppDeployment(input) {
|
|
142
|
+
return appsDeploy.updateAppDeployment(this.config, input);
|
|
1080
143
|
}
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
if (workspace.packages) {
|
|
1084
|
-
for (const pkg of workspace.packages) {
|
|
1085
|
-
if (pkg.env) {
|
|
1086
|
-
for (const e of pkg.env) {
|
|
1087
|
-
env[e.key] = `${e.infrastructure}:${e.value}`;
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
if (workspace.env) {
|
|
1093
|
-
for (const e of workspace.env) {
|
|
1094
|
-
env[e.key] = `${e.infrastructure}:${e.value}`;
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
const packages = {};
|
|
1098
|
-
if (workspace.packages) {
|
|
1099
|
-
for (const pkg of workspace.packages) {
|
|
1100
|
-
packages[pkg.name] = {
|
|
1101
|
-
parameters: pkg.parameters,
|
|
1102
|
-
version: pkg.version,
|
|
1103
|
-
};
|
|
1104
|
-
}
|
|
1105
|
-
}
|
|
1106
|
-
let ownPackages;
|
|
1107
|
-
if (workspace.ownPackages) {
|
|
1108
|
-
ownPackages = {};
|
|
1109
|
-
for (const pkg of workspace.ownPackages) {
|
|
1110
|
-
ownPackages[pkg.name] = {
|
|
1111
|
-
parameters: pkg.parameters,
|
|
1112
|
-
version: pkg.version,
|
|
1113
|
-
};
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
return {
|
|
1117
|
-
env,
|
|
1118
|
-
hasExecutor: workspace.hasExecutor ?? undefined,
|
|
1119
|
-
id: workspace.id,
|
|
1120
|
-
isDeploy: workspace.isDeploy,
|
|
1121
|
-
mirrorOf: workspace.mirrorOf?.name,
|
|
1122
|
-
name: workspace.name,
|
|
1123
|
-
...(ownPackages === undefined ? {} : { ownPackages }),
|
|
1124
|
-
packages,
|
|
1125
|
-
profile: workspace.profile === null ? undefined : workspace.profile,
|
|
1126
|
-
};
|
|
144
|
+
updateExecutorJob(input) {
|
|
145
|
+
return executorJobs.updateExecutorJob(this.config, input);
|
|
1127
146
|
}
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
try {
|
|
1131
|
-
return JSON.parse(text);
|
|
1132
|
-
}
|
|
1133
|
-
catch {
|
|
1134
|
-
return { error: text || 'Unknown error' };
|
|
1135
|
-
}
|
|
147
|
+
updateWorkspace(input) {
|
|
148
|
+
return workspaces.updateWorkspace(this.config, input);
|
|
1136
149
|
}
|
|
1137
150
|
}
|