⚠️ This is pre-release documentation for v3. For stable docs, visit v2.
Skip to content

Guide: product catalog syntax ​

ProductCatalog reads a TOML catalog that groups purchasable products by ingredient name. The format is intentionally compact, but it supports a few equivalent ways to describe the same product entries.

Overview ​

At the top level, each TOML table is an ingredient name such as eggs or flour. Inside that table you can define:

  • aliases: optional alternative ingredient names
  • product entries:
    • keys can be any string except the reserved aliases key
    • each entry must include name, size, and price.
    • arbitrary extra metadata can also be defined

Catalog shapes ​

You can write product entries in either canonical nested-table form or dotted-table form. Both parse to the same catalog.

Canonical nested form ​

toml
[eggs]
aliases = ["oeuf", "huevo"]
single = { name = "Single Egg", size = "1", price = 2 }
pack-6 = { name = "Pack of 6 eggs", size = "6", price = 10 }

[flour]
aliases = ["farine", "Mehl"]
01124 = { name = "Small pack", size = "100%g", price = 1.5 }
14141 = { name = "Big pack", size = "6%kg", price = 10, image = "flour.png" }

Equivalent dotted-table form ​

toml
[eggs.pack-6]
price = 10
name = "Pack of 6 eggs"
size = "6"

[eggs.single]
price = 2
name = "Single Egg"
size = "1"

[flour.big-pack]
price = 10
name = "Big pack"
size = "6%kg"

[flour.small-pack]
price = 1.5
name = "Small pack"
size = "100%g"

Size syntax ​

The size field accepts either a single string or an array of strings.

Single sizes:

toml
[eggs]
single = { name = "Single Egg", size = "1", price = 2 }

Sizes with a unit:

toml
[flour]
small-pack = { name = "Small pack", size = "100%g", price = 1.5 }

Multiple equivalent sizes for the same product:

toml
[eggs]
pack-of-12 = { name = "Pack of 12 eggs", size = ["1%dozen", "12"], price = 18 }

Metadata and aliases ​

Any additional keys on a product entry are preserved as metadata when parsing and are written back when stringifying.

toml
[flour]
small-pack = { name = "Small pack", size = "100%g", price = 1.5, image = "flour.png" }

aliases belongs on the ingredient table, not on the product entry. It is parsed as an array of alternate ingredient names:

toml
[eggs]
aliases = ["oeuf", "huevo"]
single = { name = "Single Egg", size = "1", price = 2 }

Full example ​

typescript
import { ProductCatalog } from "@tmlmt/cooklang-parser";

const catalog = new ProductCatalog(`
[eggs]
aliases = ["oeuf", "huevo"]
01123 = { name = "Single Egg", size = "1", price = 2 }
11244 = { name = "Pack of 6 eggs", size = "6", price = 10 }

[flour]
aliases = ["farine", "Mehl"]
01124 = { name = "Small pack", size = "100%g", price = 1.5 }
14141 = { name = "Big pack", size = "6%kg", price = 10, image = "flour.png" }
`);

const eggs = catalog.products.find((product) => product.ingredientName === "eggs");

If you only need a compact reference, the API page for ProductCatalog links back here.