refactor: hoist objectKeyFromArtifactUrl into helpers

Both src/releases.ts and scripts/sync-releases.ts had their own copy of the
same URL-to-S3-key conversion. Moved into src/helpers.ts and imported from
both call sites so a future change (e.g. CDN path prefix handling) only needs
to land once.
This commit is contained in:
Adam Shiervani
2026-04-28 10:39:30 +02:00
parent 50aa460c2a
commit e6cb7952d8
3 changed files with 11 additions and 11 deletions
+2 -6
View File
@@ -17,7 +17,7 @@ import {
import { PrismaClient } from "@prisma/client";
import semver from "semver";
import { streamToString } from "../src/helpers";
import { objectKeyFromArtifactUrl, streamToString } from "../src/helpers";
const OTA_ROOT_KEY_FPR = "AF5A36A993D828FEFE7C18C2D1B9856C26A79E95";
@@ -85,10 +85,6 @@ interface ArtifactDisplayInfo {
signature: SignatureStatus;
}
function s3KeyFromArtifactUrl(artifactUrl: string): string {
return decodeURIComponent(new URL(artifactUrl).pathname.replace(/^\/+/, ""));
}
function shortFpr(fpr: string): string {
// Keep the leading 16 hex chars (8 bytes) — enough to be unambiguous in a log
// line while staying readable. The full fingerprint is what we actually
@@ -243,7 +239,7 @@ async function loadArtifactDisplayInfo(
const signature = await verifySignature(
clients.s3Client,
config.bucketName,
s3KeyFromArtifactUrl(artifact.url),
objectKeyFromArtifactUrl(artifact.url),
);
return { artifact, signature };
}),
+8
View File
@@ -56,4 +56,12 @@ export function getDeviceRolloutBucket(deviceId: string): number {
const hash = createHash("md5").update(deviceId).digest("hex");
const hashPrefix = hash.substring(0, 8);
return parseInt(hashPrefix, 16) % 100;
}
/**
* Extracts the S3 object key from an artifact URL like
* `https://cdn.example.com/app/0.5.0/jetkvm_app` → `app/0.5.0/jetkvm_app`.
*/
export function objectKeyFromArtifactUrl(artifactUrl: string): string {
return decodeURIComponent(new URL(artifactUrl).pathname.replace(/^\/+/, ""));
}
+1 -5
View File
@@ -13,6 +13,7 @@ import { LRUCache } from "lru-cache";
import {
getDeviceRolloutBucket,
objectKeyFromArtifactUrl,
streamToString,
toSemverRange,
verifyHash,
@@ -388,11 +389,6 @@ function toRelease(
return release as Release;
}
function objectKeyFromArtifactUrl(artifactUrl: string): string {
const parsed = new URL(artifactUrl);
return decodeURIComponent(parsed.pathname.replace(/^\/+/, ""));
}
async function resolveSigUrlFromArtifactUrl(
artifactUrl: string,
): Promise<string | undefined> {