1/** Limit the slug to 48 chars so the composed ProviderInstanceId fits its 64-char cap. */
2function slugifyLabel(value: string): string {
3 return value
4 .trim()
5 .toLowerCase()
6 .replace(/[^a-z0-9]+/g, "_")
7 .replace(/^_+|_+$/g, "")
8 .slice(0, 48);
9}
10
11export function deriveInstanceId(driver: string, label: string): string {
12 const slug = slugifyLabel(label);
13 return slug ? `${driver}_${slug}` : "";
14}
15
16export function deriveAvailableInstanceId(
17 derive: (label: string) => string,
18 label: string,
19 existing: ReadonlySet<string>,
20): string {
21 const base = derive(label);
22 if (!base || !existing.has(base)) return base;
23
24 for (let suffix = 2; ; suffix += 1) {
25 const suffixText = `_${suffix}`;
26 const candidate = `${base.slice(0, 64 - suffixText.length)}${suffixText}`;
27 if (!existing.has(candidate)) return candidate;
28 }
29}