47 lines
2.2 KiB
JavaScript
47 lines
2.2 KiB
JavaScript
// 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)
|
|
}
|
|
}
|