zephyr-agent
Version:
Zephyr plugin agent
82 lines (81 loc) • 3.13 kB
JavaScript
import "node:module";
import { forEachLimit } from "zephyr-edge-contract";
import { getApplicationConfiguration } from "../edge-requests/get-application-configuration.mjs";
import { ZeErrors, ZephyrError } from "../errors/index.mjs";
import { ze_log } from "../logging/index.mjs";
import { makeRequest } from "./http-request.mjs";
const MAX_SNAPSHOT_TARGET_CONCURRENCY = 3;
function canonicalEdgeUrl(edgeUrl) {
return new URL(edgeUrl).toString();
}
function snapshotForTarget(snapshot, edgeUrl) {
return {
...snapshot,
domain: edgeUrl
};
}
function createSnapshotUploadTargets(snapshot, config) {
const targets = new Map();
const addTarget = (edgeUrl)=>{
const canonicalUrl = canonicalEdgeUrl(edgeUrl);
if (targets.has(canonicalUrl)) return;
targets.set(canonicalUrl, {
edgeUrl,
snapshot: snapshotForTarget(snapshot, edgeUrl)
});
};
addTarget(config.EDGE_URL);
for (const [, target] of Object.entries(config.ENVIRONMENTS ?? {}).sort(([left], [right])=>left.localeCompare(right)))addTarget(target.edgeUrl);
return [
...targets.values()
].map(({ edgeUrl, snapshot: targetSnapshot })=>({
edgeUrl,
snapshot: targetSnapshot
}));
}
async function uploadSnapshot({ body, application_uid }) {
const config = await getApplicationConfiguration({
application_uid
});
const targets = createSnapshotUploadTargets(body, config);
const [primary, ...additionalTargets] = targets;
if (!primary) throw new ZephyrError(ZeErrors.ERR_FAILED_UPLOAD, {
type: 'snapshot',
cause: new Error('No snapshot upload target was configured.')
});
ze_log.snapshot('Sending target-specific snapshot to edge:', JSON.stringify(primary.snapshot, null, 2));
const resp = await doUploadSnapshotRequest({
json: JSON.stringify(primary.snapshot),
edge_url: primary.edgeUrl,
jwt: config.jwt
});
await forEachLimit(additionalTargets.map((target)=>()=>doUploadSnapshotRequest({
json: JSON.stringify(target.snapshot),
edge_url: target.edgeUrl,
jwt: config.jwt
})), MAX_SNAPSHOT_TARGET_CONCURRENCY);
ze_log.snapshot('Done: snapshot uploaded');
return resp;
}
async function doUploadSnapshotRequest({ json, edge_url, jwt }) {
const options = {
method: 'POST',
headers: {
'Content-Length': Buffer.byteLength(json).toString(),
'Content-Type': 'application/json; charset=utf-8',
can_write_jwt: jwt
}
};
const url = new URL('/upload', edge_url);
url.searchParams.append('type', 'snapshot');
url.searchParams.append('skip_assets', 'true');
ze_log.snapshot('Upload URL:', url.toString());
const [ok, cause, resp] = await makeRequest(url, options, json);
if (!ok) throw new ZephyrError(ZeErrors.ERR_FAILED_UPLOAD, {
type: 'snapshot',
cause
});
return resp;
}
export { createSnapshotUploadTargets, uploadSnapshot };
//# sourceMappingURL=upload-snapshot.mjs.map