Functional Weave
Code in TypeScript

retail.sku-generate@1.0.0

README.md

1,729 bytes · view raw

# retail.sku-generate

Builds a stock-keeping unit code from a product family prefix and the
variant's attributes, so the same product and options always give the same
SKU: `generateSku("TSH", ["Navy Blue", "Large", "Cotton"], 3)` is
`"TSH-NAV-LAR-COT"`.

## The scheme

1. Each part (the prefix, then each attribute in the order given) keeps only
   the ASCII letters and digits `A-Z a-z 0-9`, in order. Spaces, punctuation
   and every non-ASCII character are dropped.
2. What is left is uppercased.
3. Each attribute, not the prefix, is cut to its first `segmentLength`
   characters. `0` keeps it whole.
4. The parts are joined with `-`. An empty prefix is left out.

Filtering happens before uppercasing on purpose: German sharp s uppercases to
"SS" in all three languages, so uppercasing first would turn "Straße" into
`STRASSE` in some places and `STRAE` in others. Here it is always `STRAE`.
Accented letters are dropped, not transliterated ("Crème" is `CRME`); run
the attribute through `text.slugify` first if you want `CREME`.

## What it does not do

It does not guarantee uniqueness. Two attributes that agree in their first
`segmentLength` characters collide ("Brown" and "Bronze" are both `BRO` at
3), and so do "10.5" and "105" (both `105`). A SKU scheme with a fixed segment
length needs a catalogue-level check, or a longer segment, and that belongs to
whoever owns the catalogue. The order of the attributes is part of the SKU, so
fix it per product family (colour, then size, then material).

## Errors

No attributes, a negative `segmentLength`, or a prefix or attribute with no
letters or digits at all (`"***"`) are errors, because a SKU with an empty
segment would silently collide with its neighbours.