@vellumai/cli 0.5.11 → 0.5.13
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/package.json +1 -1
- package/src/commands/backup.ts +14 -5
- package/src/commands/hatch.ts +48 -2
- package/src/commands/restore.ts +9 -2
- package/src/commands/retire.ts +8 -4
- package/src/commands/rollback.ts +7 -2
- package/src/commands/upgrade.ts +2 -2
- package/src/lib/assistant-config.ts +3 -5
- package/src/lib/constants.ts +11 -0
- package/src/lib/health-check.ts +1 -1
- package/src/lib/ngrok.ts +7 -0
- package/src/lib/platform-client.ts +89 -16
package/package.json
CHANGED
package/src/commands/backup.ts
CHANGED
|
@@ -66,7 +66,7 @@ export async function backup(): Promise<void> {
|
|
|
66
66
|
const cloud =
|
|
67
67
|
entry.cloud || (entry.project ? "gcp" : entry.sshUser ? "custom" : "local");
|
|
68
68
|
if (cloud === "vellum") {
|
|
69
|
-
await backupPlatform(name, outputArg);
|
|
69
|
+
await backupPlatform(name, outputArg, entry.runtimeUrl);
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
72
|
|
|
@@ -184,7 +184,11 @@ export async function backup(): Promise<void> {
|
|
|
184
184
|
// Platform (Vellum-hosted) backup via Django async migration export
|
|
185
185
|
// ---------------------------------------------------------------------------
|
|
186
186
|
|
|
187
|
-
async function backupPlatform(
|
|
187
|
+
async function backupPlatform(
|
|
188
|
+
name: string,
|
|
189
|
+
outputArg?: string,
|
|
190
|
+
runtimeUrl?: string,
|
|
191
|
+
): Promise<void> {
|
|
188
192
|
// Step 1 — Authenticate
|
|
189
193
|
const token = readPlatformToken();
|
|
190
194
|
if (!token) {
|
|
@@ -194,7 +198,7 @@ async function backupPlatform(name: string, outputArg?: string): Promise<void> {
|
|
|
194
198
|
|
|
195
199
|
let orgId: string;
|
|
196
200
|
try {
|
|
197
|
-
orgId = await fetchOrganizationId(token);
|
|
201
|
+
orgId = await fetchOrganizationId(token, runtimeUrl);
|
|
198
202
|
} catch (err) {
|
|
199
203
|
const msg = err instanceof Error ? err.message : String(err);
|
|
200
204
|
if (msg.includes("401") || msg.includes("403")) {
|
|
@@ -207,7 +211,12 @@ async function backupPlatform(name: string, outputArg?: string): Promise<void> {
|
|
|
207
211
|
// Step 2 — Initiate export job
|
|
208
212
|
let jobId: string;
|
|
209
213
|
try {
|
|
210
|
-
const result = await platformInitiateExport(
|
|
214
|
+
const result = await platformInitiateExport(
|
|
215
|
+
token,
|
|
216
|
+
orgId,
|
|
217
|
+
"CLI backup",
|
|
218
|
+
runtimeUrl,
|
|
219
|
+
);
|
|
211
220
|
jobId = result.jobId;
|
|
212
221
|
} catch (err) {
|
|
213
222
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -235,7 +244,7 @@ async function backupPlatform(name: string, outputArg?: string): Promise<void> {
|
|
|
235
244
|
while (Date.now() < deadline) {
|
|
236
245
|
let status: { status: string; downloadUrl?: string; error?: string };
|
|
237
246
|
try {
|
|
238
|
-
status = await platformPollExportStatus(jobId, token, orgId);
|
|
247
|
+
status = await platformPollExportStatus(jobId, token, orgId, runtimeUrl);
|
|
239
248
|
} catch (err) {
|
|
240
249
|
const msg = err instanceof Error ? err.message : String(err);
|
|
241
250
|
// Let non-transient errors (e.g. 404 "job not found") propagate immediately
|
package/src/commands/hatch.ts
CHANGED
|
@@ -47,7 +47,11 @@ import {
|
|
|
47
47
|
stopLocalProcesses,
|
|
48
48
|
} from "../lib/local";
|
|
49
49
|
import { maybeStartNgrokTunnel } from "../lib/ngrok";
|
|
50
|
-
import {
|
|
50
|
+
import {
|
|
51
|
+
getPlatformUrl,
|
|
52
|
+
hatchAssistant,
|
|
53
|
+
readPlatformToken,
|
|
54
|
+
} from "../lib/platform-client";
|
|
51
55
|
import { httpHealthCheck } from "../lib/http-client";
|
|
52
56
|
import { detectOrphanedProcesses } from "../lib/orphan-detection";
|
|
53
57
|
import { isProcessAlive, stopProcess } from "../lib/process";
|
|
@@ -237,7 +241,7 @@ function parseArgs(): HatchArgs {
|
|
|
237
241
|
console.log(" -d Run in detached mode");
|
|
238
242
|
console.log(" --name <name> Custom instance name");
|
|
239
243
|
console.log(
|
|
240
|
-
" --remote <host> Remote host (local, gcp, aws, docker, custom)",
|
|
244
|
+
" --remote <host> Remote host (local, gcp, aws, docker, custom, vellum)",
|
|
241
245
|
);
|
|
242
246
|
console.log(
|
|
243
247
|
" --restart Restart processes without onboarding side effects",
|
|
@@ -943,6 +947,48 @@ export async function hatch(): Promise<void> {
|
|
|
943
947
|
return;
|
|
944
948
|
}
|
|
945
949
|
|
|
950
|
+
if (remote === "vellum") {
|
|
951
|
+
await hatchVellumPlatform();
|
|
952
|
+
return;
|
|
953
|
+
}
|
|
954
|
+
|
|
946
955
|
console.error(`Error: Remote host '${remote}' is not yet supported.`);
|
|
947
956
|
process.exit(1);
|
|
948
957
|
}
|
|
958
|
+
|
|
959
|
+
async function hatchVellumPlatform(): Promise<void> {
|
|
960
|
+
const token = readPlatformToken();
|
|
961
|
+
if (!token) {
|
|
962
|
+
console.error("Not logged in. Run `vellum login --token <token>` first.");
|
|
963
|
+
process.exit(1);
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
const config = SPECIES_CONFIG.vellum;
|
|
967
|
+
console.log("");
|
|
968
|
+
for (const line of config.art) {
|
|
969
|
+
console.log(` ${line}`);
|
|
970
|
+
}
|
|
971
|
+
console.log("");
|
|
972
|
+
console.log(" Hatching assistant on Vellum platform...");
|
|
973
|
+
console.log("");
|
|
974
|
+
|
|
975
|
+
const result = await hatchAssistant(token);
|
|
976
|
+
|
|
977
|
+
const platformUrl = getPlatformUrl();
|
|
978
|
+
|
|
979
|
+
saveAssistantEntry({
|
|
980
|
+
assistantId: result.id,
|
|
981
|
+
runtimeUrl: platformUrl,
|
|
982
|
+
cloud: "vellum",
|
|
983
|
+
species: "vellum",
|
|
984
|
+
hatchedAt: new Date().toISOString(),
|
|
985
|
+
});
|
|
986
|
+
setActiveAssistant(result.id);
|
|
987
|
+
|
|
988
|
+
console.log(` ${config.hatchedEmoji} Your assistant has hatched!`);
|
|
989
|
+
console.log("");
|
|
990
|
+
console.log(` ID: ${result.id}`);
|
|
991
|
+
console.log(` Name: ${result.name}`);
|
|
992
|
+
console.log(` Status: ${result.status}`);
|
|
993
|
+
console.log("");
|
|
994
|
+
}
|
package/src/commands/restore.ts
CHANGED
|
@@ -179,7 +179,7 @@ async function restorePlatform(
|
|
|
179
179
|
|
|
180
180
|
let orgId: string;
|
|
181
181
|
try {
|
|
182
|
-
orgId = await fetchOrganizationId(token);
|
|
182
|
+
orgId = await fetchOrganizationId(token, entry.runtimeUrl);
|
|
183
183
|
} catch (err) {
|
|
184
184
|
const msg = err instanceof Error ? err.message : String(err);
|
|
185
185
|
if (msg.includes("401") || msg.includes("403")) {
|
|
@@ -206,6 +206,7 @@ async function restorePlatform(
|
|
|
206
206
|
new Uint8Array(bundleData),
|
|
207
207
|
token,
|
|
208
208
|
orgId,
|
|
209
|
+
entry.runtimeUrl,
|
|
209
210
|
);
|
|
210
211
|
} catch (err) {
|
|
211
212
|
if (err instanceof Error && err.name === "TimeoutError") {
|
|
@@ -315,7 +316,12 @@ async function restorePlatform(
|
|
|
315
316
|
);
|
|
316
317
|
|
|
317
318
|
try {
|
|
318
|
-
await rollbackPlatformAssistant(
|
|
319
|
+
await rollbackPlatformAssistant(
|
|
320
|
+
token,
|
|
321
|
+
orgId,
|
|
322
|
+
opts.version,
|
|
323
|
+
entry.runtimeUrl,
|
|
324
|
+
);
|
|
319
325
|
} catch (err) {
|
|
320
326
|
const msg = err instanceof Error ? err.message : String(err);
|
|
321
327
|
if (msg.includes("401") || msg.includes("403")) {
|
|
@@ -340,6 +346,7 @@ async function restorePlatform(
|
|
|
340
346
|
new Uint8Array(bundleData),
|
|
341
347
|
token,
|
|
342
348
|
orgId,
|
|
349
|
+
entry.runtimeUrl,
|
|
343
350
|
);
|
|
344
351
|
} catch (err) {
|
|
345
352
|
if (err instanceof Error && err.name === "TimeoutError") {
|
package/src/commands/retire.ts
CHANGED
|
@@ -197,7 +197,10 @@ async function retireCustom(entry: AssistantEntry): Promise<void> {
|
|
|
197
197
|
console.log(`\u2705 Custom instance retired.`);
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
async function retireVellum(
|
|
200
|
+
async function retireVellum(
|
|
201
|
+
assistantId: string,
|
|
202
|
+
runtimeUrl?: string,
|
|
203
|
+
): Promise<void> {
|
|
201
204
|
console.log("\u{1F5D1}\ufe0f Retiring platform-hosted instance...\n");
|
|
202
205
|
|
|
203
206
|
const token = readPlatformToken();
|
|
@@ -208,9 +211,10 @@ async function retireVellum(assistantId: string): Promise<void> {
|
|
|
208
211
|
process.exit(1);
|
|
209
212
|
}
|
|
210
213
|
|
|
211
|
-
const orgId = await fetchOrganizationId(token);
|
|
214
|
+
const orgId = await fetchOrganizationId(token, runtimeUrl);
|
|
212
215
|
|
|
213
|
-
const
|
|
216
|
+
const platformUrl = runtimeUrl || getPlatformUrl();
|
|
217
|
+
const url = `${platformUrl}/v1/assistants/${encodeURIComponent(assistantId)}/retire/`;
|
|
214
218
|
const response = await fetch(url, {
|
|
215
219
|
method: "DELETE",
|
|
216
220
|
headers: {
|
|
@@ -343,7 +347,7 @@ async function retireInner(): Promise<void> {
|
|
|
343
347
|
} else if (cloud === "custom") {
|
|
344
348
|
await retireCustom(entry);
|
|
345
349
|
} else if (cloud === "vellum") {
|
|
346
|
-
await retireVellum(entry.assistantId);
|
|
350
|
+
await retireVellum(entry.assistantId, entry.runtimeUrl);
|
|
347
351
|
} else {
|
|
348
352
|
console.error(`Error: Unknown cloud type '${cloud}'.`);
|
|
349
353
|
process.exit(1);
|
package/src/commands/rollback.ts
CHANGED
|
@@ -185,7 +185,7 @@ async function rollbackPlatformViaEndpoint(
|
|
|
185
185
|
|
|
186
186
|
let orgId: string;
|
|
187
187
|
try {
|
|
188
|
-
orgId = await fetchOrganizationId(token);
|
|
188
|
+
orgId = await fetchOrganizationId(token, entry.runtimeUrl);
|
|
189
189
|
} catch (err) {
|
|
190
190
|
const msg = err instanceof Error ? err.message : String(err);
|
|
191
191
|
if (msg.includes("401") || msg.includes("403")) {
|
|
@@ -206,7 +206,12 @@ async function rollbackPlatformViaEndpoint(
|
|
|
206
206
|
|
|
207
207
|
let result: { detail: string; version: string | null };
|
|
208
208
|
try {
|
|
209
|
-
result = await rollbackPlatformAssistant(
|
|
209
|
+
result = await rollbackPlatformAssistant(
|
|
210
|
+
token,
|
|
211
|
+
orgId,
|
|
212
|
+
version,
|
|
213
|
+
entry.runtimeUrl,
|
|
214
|
+
);
|
|
210
215
|
} catch (err) {
|
|
211
216
|
const detail = err instanceof Error ? err.message : String(err);
|
|
212
217
|
|
package/src/commands/upgrade.ts
CHANGED
|
@@ -729,9 +729,9 @@ async function upgradePlatform(
|
|
|
729
729
|
process.exit(1);
|
|
730
730
|
}
|
|
731
731
|
|
|
732
|
-
const orgId = await fetchOrganizationId(token);
|
|
732
|
+
const orgId = await fetchOrganizationId(token, entry.runtimeUrl);
|
|
733
733
|
|
|
734
|
-
const url = `${getPlatformUrl()}/v1/assistants/upgrade/`;
|
|
734
|
+
const url = `${entry.runtimeUrl || getPlatformUrl()}/v1/assistants/upgrade/`;
|
|
735
735
|
const body: { assistant_id?: string; version?: string } = {
|
|
736
736
|
assistant_id: entry.assistantId,
|
|
737
737
|
};
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
DEFAULT_DAEMON_PORT,
|
|
17
17
|
DEFAULT_GATEWAY_PORT,
|
|
18
18
|
DEFAULT_QDRANT_PORT,
|
|
19
|
+
LOCKFILE_NAMES,
|
|
19
20
|
} from "./constants.js";
|
|
20
21
|
import { probePort } from "./port-probe.js";
|
|
21
22
|
|
|
@@ -119,10 +120,7 @@ function getLockfileDir(): string {
|
|
|
119
120
|
|
|
120
121
|
function readLockfile(): LockfileData {
|
|
121
122
|
const base = getLockfileDir();
|
|
122
|
-
const candidates =
|
|
123
|
-
join(base, ".vellum.lock.json"),
|
|
124
|
-
join(base, ".vellum.lockfile.json"),
|
|
125
|
-
];
|
|
123
|
+
const candidates = LOCKFILE_NAMES.map((name) => join(base, name));
|
|
126
124
|
for (const lockfilePath of candidates) {
|
|
127
125
|
if (!existsSync(lockfilePath)) continue;
|
|
128
126
|
try {
|
|
@@ -139,7 +137,7 @@ function readLockfile(): LockfileData {
|
|
|
139
137
|
}
|
|
140
138
|
|
|
141
139
|
function writeLockfile(data: LockfileData): void {
|
|
142
|
-
const lockfilePath = join(getLockfileDir(),
|
|
140
|
+
const lockfilePath = join(getLockfileDir(), LOCKFILE_NAMES[0]);
|
|
143
141
|
const tmpPath = `${lockfilePath}.${randomBytes(4).toString("hex")}.tmp`;
|
|
144
142
|
try {
|
|
145
143
|
writeFileSync(tmpPath, JSON.stringify(data, null, 2) + "\n");
|
package/src/lib/constants.ts
CHANGED
|
@@ -18,6 +18,16 @@ export const DEFAULT_GATEWAY_PORT = 7830;
|
|
|
18
18
|
export const DEFAULT_QDRANT_PORT = 6333;
|
|
19
19
|
export const DEFAULT_CES_PORT = 8090;
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Lockfile candidate filenames, checked in priority order.
|
|
23
|
+
* `.vellum.lock.json` is the current name; `.vellum.lockfile.json` is the
|
|
24
|
+
* legacy name kept for backwards compatibility with older installs.
|
|
25
|
+
*/
|
|
26
|
+
export const LOCKFILE_NAMES = [
|
|
27
|
+
".vellum.lock.json",
|
|
28
|
+
".vellum.lockfile.json",
|
|
29
|
+
] as const;
|
|
30
|
+
|
|
21
31
|
/**
|
|
22
32
|
* Environment variable names for provider API keys, keyed by provider ID.
|
|
23
33
|
* Loaded from the shared registry at `meta/provider-env-vars.json` — the
|
|
@@ -33,6 +43,7 @@ export const VALID_REMOTE_HOSTS = [
|
|
|
33
43
|
"aws",
|
|
34
44
|
"docker",
|
|
35
45
|
"custom",
|
|
46
|
+
"vellum",
|
|
36
47
|
] as const;
|
|
37
48
|
export type RemoteHost = (typeof VALID_REMOTE_HOSTS)[number];
|
|
38
49
|
export const VALID_SPECIES = ["openclaw", "vellum"] as const;
|
package/src/lib/health-check.ts
CHANGED
|
@@ -28,7 +28,7 @@ export async function checkManagedHealth(
|
|
|
28
28
|
let orgId: string;
|
|
29
29
|
try {
|
|
30
30
|
const { fetchOrganizationId } = await import("./platform-client.js");
|
|
31
|
-
orgId = await fetchOrganizationId(token);
|
|
31
|
+
orgId = await fetchOrganizationId(token, runtimeUrl);
|
|
32
32
|
} catch (err) {
|
|
33
33
|
return {
|
|
34
34
|
status: "error (auth)",
|
package/src/lib/ngrok.ts
CHANGED
|
@@ -235,6 +235,13 @@ function hasNonNgrokIngressUrl(): boolean {
|
|
|
235
235
|
export async function maybeStartNgrokTunnel(
|
|
236
236
|
targetPort: number,
|
|
237
237
|
): Promise<ChildProcess | null> {
|
|
238
|
+
// Managed/containerized deployments route webhooks through the platform's
|
|
239
|
+
// callback proxy. ngrok is not needed and would not be reachable from the
|
|
240
|
+
// platform anyway — skip it entirely.
|
|
241
|
+
const isContainerized =
|
|
242
|
+
process.env.IS_CONTAINERIZED === "true" ||
|
|
243
|
+
process.env.IS_CONTAINERIZED === "1";
|
|
244
|
+
if (isContainerized) return null;
|
|
238
245
|
if (!hasWebhookIntegrationsConfigured()) return null;
|
|
239
246
|
if (hasNonNgrokIngressUrl()) return null;
|
|
240
247
|
|
|
@@ -65,6 +65,67 @@ export function clearPlatformToken(): void {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
const VAK_PREFIX = "vak_";
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Returns the appropriate auth header for the given platform token.
|
|
72
|
+
*
|
|
73
|
+
* - `vak_`-prefixed tokens are long-lived platform API keys and use
|
|
74
|
+
* `Authorization: Bearer`.
|
|
75
|
+
* - All other tokens are allauth session tokens and use `X-Session-Token`.
|
|
76
|
+
*/
|
|
77
|
+
export function authHeaders(token: string): Record<string, string> {
|
|
78
|
+
if (token.startsWith(VAK_PREFIX)) {
|
|
79
|
+
return { Authorization: `Bearer ${token}` };
|
|
80
|
+
}
|
|
81
|
+
return { "X-Session-Token": token };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface HatchedAssistant {
|
|
85
|
+
id: string;
|
|
86
|
+
name: string;
|
|
87
|
+
status: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export async function hatchAssistant(token: string): Promise<HatchedAssistant> {
|
|
91
|
+
const url = `${getPlatformUrl()}/v1/assistants/hatch/`;
|
|
92
|
+
|
|
93
|
+
const response = await fetch(url, {
|
|
94
|
+
method: "POST",
|
|
95
|
+
headers: {
|
|
96
|
+
"Content-Type": "application/json",
|
|
97
|
+
...authHeaders(token),
|
|
98
|
+
},
|
|
99
|
+
body: JSON.stringify({}),
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
if (response.ok) {
|
|
103
|
+
return (await response.json()) as HatchedAssistant;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (response.status === 401 || response.status === 403) {
|
|
107
|
+
const detail = (await response.json().catch(() => ({}))) as {
|
|
108
|
+
detail?: string;
|
|
109
|
+
};
|
|
110
|
+
throw new Error(
|
|
111
|
+
detail.detail ??
|
|
112
|
+
"Invalid or expired token. Run `vellum login` to re-authenticate.",
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (response.status === 402) {
|
|
117
|
+
throw new Error("Insufficient balance to hatch a new assistant.");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const errorBody = (await response.json().catch(() => ({}))) as {
|
|
121
|
+
detail?: string;
|
|
122
|
+
};
|
|
123
|
+
throw new Error(
|
|
124
|
+
errorBody.detail ??
|
|
125
|
+
`Platform API error: ${response.status} ${response.statusText}`,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
68
129
|
export interface PlatformUser {
|
|
69
130
|
id: string;
|
|
70
131
|
email: string;
|
|
@@ -75,16 +136,19 @@ interface OrganizationListResponse {
|
|
|
75
136
|
results: { id: string; name: string }[];
|
|
76
137
|
}
|
|
77
138
|
|
|
78
|
-
export async function fetchOrganizationId(
|
|
79
|
-
|
|
80
|
-
|
|
139
|
+
export async function fetchOrganizationId(
|
|
140
|
+
token: string,
|
|
141
|
+
platformUrl?: string,
|
|
142
|
+
): Promise<string> {
|
|
143
|
+
const resolvedUrl = platformUrl || getPlatformUrl();
|
|
144
|
+
const url = `${resolvedUrl}/v1/organizations/`;
|
|
81
145
|
const response = await fetch(url, {
|
|
82
146
|
headers: { "X-Session-Token": token },
|
|
83
147
|
});
|
|
84
148
|
|
|
85
149
|
if (!response.ok) {
|
|
86
150
|
throw new Error(
|
|
87
|
-
`Failed to fetch organizations from ${
|
|
151
|
+
`Failed to fetch organizations from ${resolvedUrl} (${response.status}). Try logging in again.`,
|
|
88
152
|
);
|
|
89
153
|
}
|
|
90
154
|
|
|
@@ -107,8 +171,12 @@ interface AllauthSessionResponse {
|
|
|
107
171
|
};
|
|
108
172
|
}
|
|
109
173
|
|
|
110
|
-
export async function fetchCurrentUser(
|
|
111
|
-
|
|
174
|
+
export async function fetchCurrentUser(
|
|
175
|
+
token: string,
|
|
176
|
+
platformUrl?: string,
|
|
177
|
+
): Promise<PlatformUser> {
|
|
178
|
+
const resolvedUrl = platformUrl || getPlatformUrl();
|
|
179
|
+
const url = `${resolvedUrl}/_allauth/app/v1/auth/session`;
|
|
112
180
|
const response = await fetch(url, {
|
|
113
181
|
headers: { "X-Session-Token": token },
|
|
114
182
|
});
|
|
@@ -138,9 +206,10 @@ export async function rollbackPlatformAssistant(
|
|
|
138
206
|
token: string,
|
|
139
207
|
orgId: string,
|
|
140
208
|
version?: string,
|
|
209
|
+
platformUrl?: string,
|
|
141
210
|
): Promise<{ detail: string; version: string | null }> {
|
|
142
|
-
const
|
|
143
|
-
const response = await fetch(`${
|
|
211
|
+
const resolvedUrl = platformUrl || getPlatformUrl();
|
|
212
|
+
const response = await fetch(`${resolvedUrl}/v1/assistants/rollback/`, {
|
|
144
213
|
method: "POST",
|
|
145
214
|
headers: {
|
|
146
215
|
"Content-Type": "application/json",
|
|
@@ -182,9 +251,10 @@ export async function platformInitiateExport(
|
|
|
182
251
|
token: string,
|
|
183
252
|
orgId: string,
|
|
184
253
|
description?: string,
|
|
254
|
+
platformUrl?: string,
|
|
185
255
|
): Promise<{ jobId: string; status: string }> {
|
|
186
|
-
const
|
|
187
|
-
const response = await fetch(`${
|
|
256
|
+
const resolvedUrl = platformUrl || getPlatformUrl();
|
|
257
|
+
const response = await fetch(`${resolvedUrl}/v1/migrations/export/`, {
|
|
188
258
|
method: "POST",
|
|
189
259
|
headers: {
|
|
190
260
|
"Content-Type": "application/json",
|
|
@@ -215,10 +285,11 @@ export async function platformPollExportStatus(
|
|
|
215
285
|
jobId: string,
|
|
216
286
|
token: string,
|
|
217
287
|
orgId: string,
|
|
288
|
+
platformUrl?: string,
|
|
218
289
|
): Promise<{ status: string; downloadUrl?: string; error?: string }> {
|
|
219
|
-
const
|
|
290
|
+
const resolvedUrl = platformUrl || getPlatformUrl();
|
|
220
291
|
const response = await fetch(
|
|
221
|
-
`${
|
|
292
|
+
`${resolvedUrl}/v1/migrations/export/${jobId}/status/`,
|
|
222
293
|
{
|
|
223
294
|
headers: {
|
|
224
295
|
"X-Session-Token": token,
|
|
@@ -269,10 +340,11 @@ export async function platformImportPreflight(
|
|
|
269
340
|
bundleData: Uint8Array<ArrayBuffer>,
|
|
270
341
|
token: string,
|
|
271
342
|
orgId: string,
|
|
343
|
+
platformUrl?: string,
|
|
272
344
|
): Promise<{ statusCode: number; body: Record<string, unknown> }> {
|
|
273
|
-
const
|
|
345
|
+
const resolvedUrl = platformUrl || getPlatformUrl();
|
|
274
346
|
const response = await fetch(
|
|
275
|
-
`${
|
|
347
|
+
`${resolvedUrl}/v1/migrations/import-preflight/`,
|
|
276
348
|
{
|
|
277
349
|
method: "POST",
|
|
278
350
|
headers: {
|
|
@@ -296,9 +368,10 @@ export async function platformImportBundle(
|
|
|
296
368
|
bundleData: Uint8Array<ArrayBuffer>,
|
|
297
369
|
token: string,
|
|
298
370
|
orgId: string,
|
|
371
|
+
platformUrl?: string,
|
|
299
372
|
): Promise<{ statusCode: number; body: Record<string, unknown> }> {
|
|
300
|
-
const
|
|
301
|
-
const response = await fetch(`${
|
|
373
|
+
const resolvedUrl = platformUrl || getPlatformUrl();
|
|
374
|
+
const response = await fetch(`${resolvedUrl}/v1/migrations/import/`, {
|
|
302
375
|
method: "POST",
|
|
303
376
|
headers: {
|
|
304
377
|
"Content-Type": "application/octet-stream",
|