forked from farhoodlabs/paperclip
60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
/**
|
|
* Glob matching for image references.
|
|
* - `*` matches any sequence of characters EXCEPT `/` (so a wildcard doesn't span path segments)
|
|
* - `?` matches exactly one character (excluding `/`)
|
|
*/
|
|
export function globMatch(pattern: string, value: string): boolean {
|
|
const re = new RegExp(
|
|
"^" +
|
|
pattern
|
|
.replace(/[.+^${}()|[\]\\]/g, "\\$&")
|
|
.replace(/\*/g, "[^/]*")
|
|
.replace(/\?/g, "[^/]") +
|
|
"$",
|
|
);
|
|
return re.test(value);
|
|
}
|
|
|
|
export interface ResolveImageInput {
|
|
imageOverride?: string | null;
|
|
}
|
|
|
|
export interface ResolveImageDefaults {
|
|
runtimeImage: string;
|
|
}
|
|
|
|
export interface ResolveImageConfig {
|
|
imageAllowList: string[];
|
|
imageRegistry?: string;
|
|
}
|
|
|
|
export function resolveImage(
|
|
target: ResolveImageInput,
|
|
defaults: ResolveImageDefaults,
|
|
config: ResolveImageConfig,
|
|
): string {
|
|
if (target.imageOverride) {
|
|
if (!config.imageAllowList.some((p) => globMatch(p, target.imageOverride!))) {
|
|
throw new Error(`Image override "${target.imageOverride}" is not in allowlist`);
|
|
}
|
|
return target.imageOverride;
|
|
}
|
|
if (config.imageRegistry) {
|
|
return rewriteRegistry(defaults.runtimeImage, config.imageRegistry);
|
|
}
|
|
return defaults.runtimeImage;
|
|
}
|
|
|
|
function rewriteRegistry(image: string, registry: string): string {
|
|
// image is like "ghcr.io/paperclipai/agent-runtime-claude:v1"
|
|
// we want to replace the first two path segments (host + org) with `registry`
|
|
const cleanRegistry = registry.replace(/\/+$/, "");
|
|
const colonIdx = image.lastIndexOf(":");
|
|
const tag = colonIdx >= 0 ? image.slice(colonIdx) : "";
|
|
const path = colonIdx >= 0 ? image.slice(0, colonIdx) : image;
|
|
const segments = path.split("/");
|
|
// Strip the host+org (first two segments), keep the image name
|
|
const imageName = segments.slice(2).join("/") || segments[segments.length - 1];
|
|
return `${cleanRegistry}/${imageName}${tag}`;
|
|
}
|