@@ -0,0 +1,46 @@
|
||||
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
|
||||
import { ConvexHttpClient } from "convex/browser"
|
||||
|
||||
// Convex 1.45's CLI lists env through a WebSocket subscription. Linked-service relays are
|
||||
// deliberately HTTP-only. Query the same system function once over HTTP, then use the CLI's
|
||||
// update endpoint with its default (no --force) semantics: equal values stay, conflicts fail
|
||||
// the whole batch, missing values are created, and unlisted variables are untouched.
|
||||
export async function syncPlatformEnvironment({ url, adminKey, variables, timeoutMs = 30_000 }) {
|
||||
const controller = new AbortController()
|
||||
const timer = setTimeout(() => controller.abort(), timeoutMs)
|
||||
const boundedFetch = (input, options) => fetch(input, { ...options, signal: controller.signal, redirect: "error" })
|
||||
try {
|
||||
const client = new ConvexHttpClient(url, { logger: false, fetch: boundedFetch })
|
||||
client.setAdminAuth(adminKey)
|
||||
const existing = await client.query("_system/cli/queryEnvironmentVariables", {})
|
||||
if (
|
||||
!Array.isArray(existing) ||
|
||||
existing.some((entry) => typeof entry?.name !== "string" || typeof entry?.value !== "string")
|
||||
) {
|
||||
throw new Error("Invalid environment response")
|
||||
}
|
||||
const current = new Map(existing.map(({ name, value }) => [name, value]))
|
||||
const changes = []
|
||||
for (const [name, value] of Object.entries(variables)) {
|
||||
if (current.has(name) && current.get(name) !== value) {
|
||||
throw new Error("Environment conflict")
|
||||
}
|
||||
if (!current.has(name)) changes.push({ name, value })
|
||||
}
|
||||
if (changes.length > 0) {
|
||||
const response = await boundedFetch(new URL("/api/update_environment_variables", url), {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", Authorization: `Convex ${adminKey}` },
|
||||
body: JSON.stringify({ changes }),
|
||||
})
|
||||
await response.body?.cancel()
|
||||
if (!response.ok) throw new Error("Environment update refused")
|
||||
}
|
||||
} catch {
|
||||
// Upstream failures can contain environment values or credentials. Never surface their
|
||||
// bodies, messages or causes in deployment logs, including a conflicting existing value.
|
||||
throw new Error("Convex platform service environment sync failed")
|
||||
} finally {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user