1,365 bytes · the TypeScript implementation · view raw
// Keep ASCII letters and digits only, then uppercase. Filtering first matters:// "ß".toUpperCase() is "SS", which would make the SKU depend on how each// language's Unicode tables treat one letter.function clean(part: string): string {
return part.replace(/[^A-Za-z0-9]/g, "").toUpperCase();
}
/** * A deterministic SKU: the cleaned prefix and attributes, joined by hyphens. * Each attribute is cut to `segmentLength` characters (0 keeps it whole). */exportfunction generateSku(prefix: string, attributes: readonly string[], segmentLength: number): string {
if (!Number.isInteger(segmentLength) || segmentLength < 0) {
thrownew RangeError(`segmentLength must be 0 or more, received ${segmentLength}`);
}
if (attributes.length === 0) {
thrownew RangeError("a SKU needs at least one attribute");
}
const parts: string[] = [];
if (prefix !== "") {
const cleaned = clean(prefix);
if (cleaned === "") thrownew RangeError(`prefix ("${prefix}") has no letters or digits`);
parts.push(cleaned);
}
attributes.forEach((attribute, index) => {
const cleaned = clean(attribute);
if (cleaned === "") {
thrownew RangeError(`attribute ${index + 1} ("${attribute}") has no letters or digits`);
}
parts.push(segmentLength === 0 ? cleaned : cleaned.slice(0, segmentLength));
});
return parts.join("-");
}