guanghu-ice-heart/server-tools/lake-lamp-continuity-guard/code-channel-policy.mjs

54 lines
1.6 KiB
JavaScript
Raw Permalink Normal View History

const HOST = "guanghulab.com";
const PREFIX = "/code/bingshuo/";
const REPOSITORIES = new Set([
"guanghu-ice-heart",
"hololake-system-architecture",
]);
export function normalizeCodeChannelRepository(value) {
let url;
try {
url = new URL(String(value).trim().replace(/^repo:\/\//u, "https://"));
} catch {
throw new Error(
"INVALID_PUBLISH_REPOSITORY: use repo://guanghulab.com/code/bingshuo/<repository>",
);
}
if (url.username || url.password) {
throw new Error("PUBLISH_REPOSITORY_CREDENTIALS_FORBIDDEN");
}
const pathname = url.pathname.replace(/\.git$/u, "").replace(/\/+$/u, "");
const slug = pathname.startsWith(PREFIX)
? pathname.slice(PREFIX.length)
: "";
if (url.hostname !== HOST || !REPOSITORIES.has(slug)) {
throw new Error(
"NON_CANONICAL_CODE_CHANNEL_REPOSITORY: only the two registered /code/ repositories are current",
);
}
return `repo://${HOST}${PREFIX}${slug}`;
}
export function normalizePublishTarget(value = "main") {
const target = String(value).trim() || "main";
if (
!/^(?!\/)(?!.*(?:\.\.|\/\/|@\{|[~^:?*\[\\]))[A-Za-z0-9._/-]+$/u.test(
target,
) ||
target.endsWith("/") ||
target.endsWith(".")
) {
throw new Error("INVALID_PUBLISH_TARGET: use an exact Git branch name");
}
return target;
}
export function publishLeaseResource(repository, target = "main") {
return `${normalizeCodeChannelRepository(repository)}#${normalizePublishTarget(target)}`;
}
export const currentCodeChannelRepositories = Object.freeze([
"repo://guanghulab.com/code/bingshuo/guanghu-ice-heart",
"repo://guanghulab.com/code/bingshuo/hololake-system-architecture",
]);