61 lines
1.5 KiB
TypeScript
61 lines
1.5 KiB
TypeScript
export interface RunnerE2EHistoryPublicDestination {
|
|
prefix: string;
|
|
publicBaseUrl: string;
|
|
}
|
|
|
|
export function validateHistoryPublicDestination(input: {
|
|
prefix: string;
|
|
publicBaseUrl: string;
|
|
}): RunnerE2EHistoryPublicDestination {
|
|
const prefix = input.prefix.replace(/^\/+|\/+$/g, "");
|
|
const segments = prefix.split("/");
|
|
if (
|
|
!prefix ||
|
|
segments.some(
|
|
(segment) =>
|
|
!segment ||
|
|
segment === "." ||
|
|
segment === ".." ||
|
|
!/^[A-Za-z0-9._~-]+$/.test(segment),
|
|
)
|
|
) {
|
|
throw new Error(
|
|
"RUNNER_E2E_HISTORY_PREFIX must be a safe non-empty key prefix",
|
|
);
|
|
}
|
|
const publicUrl = new URL(input.publicBaseUrl);
|
|
if (
|
|
publicUrl.protocol !== "https:" ||
|
|
publicUrl.username ||
|
|
publicUrl.password ||
|
|
publicUrl.search ||
|
|
publicUrl.hash
|
|
) {
|
|
throw new Error(
|
|
"RUNNER_E2E_HISTORY_PUBLIC_BASE_URL must be a credential-free HTTPS URL",
|
|
);
|
|
}
|
|
return {
|
|
prefix,
|
|
publicBaseUrl: publicUrl.href.replace(/\/+$/, ""),
|
|
};
|
|
}
|
|
|
|
export function validateHistoryDestination(input: {
|
|
bucket: string;
|
|
prefix: string;
|
|
publicBaseUrl: string;
|
|
}) {
|
|
if (!/^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/.test(input.bucket)) {
|
|
throw new Error("RUNNER_E2E_HISTORY_S3_BUCKET is not a valid bucket name");
|
|
}
|
|
return validateHistoryPublicDestination(input);
|
|
}
|
|
|
|
export function runnerE2ECampaignPublicUrl(
|
|
destination: RunnerE2EHistoryPublicDestination,
|
|
campaignId: string,
|
|
) {
|
|
return `${destination.publicBaseUrl}/${destination.prefix}/campaigns/${encodeURIComponent(campaignId)}/index.html`;
|
|
}
|