|
| 1 | +--- |
| 2 | +outline: deep |
| 3 | +--- |
| 4 | + |
| 5 | +# Guide: product catalog syntax |
| 6 | + |
| 7 | +`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. |
| 8 | + |
| 9 | +## Overview |
| 10 | + |
| 11 | +At the top level, each TOML table is an ingredient name such as `eggs` or `flour`. Inside that table you can define: |
| 12 | + |
| 13 | +- `aliases`: optional alternative ingredient names |
| 14 | +- product entries: |
| 15 | + - keys can be any string except the reserved `aliases` key |
| 16 | + - each entry must include `name`, `size`, and `price`. |
| 17 | + - arbitrary extra metadata can also be defined |
| 18 | + |
| 19 | + |
| 20 | +## Catalog shapes |
| 21 | + |
| 22 | +You can write product entries in either canonical nested-table form or dotted-table form. Both parse to the same catalog. |
| 23 | + |
| 24 | +### Canonical nested form |
| 25 | + |
| 26 | +```toml |
| 27 | +[eggs] |
| 28 | +aliases = ["oeuf", "huevo"] |
| 29 | +single = { name = "Single Egg", size = "1", price = 2 } |
| 30 | +pack-6 = { name = "Pack of 6 eggs", size = "6", price = 10 } |
| 31 | + |
| 32 | +[flour] |
| 33 | +aliases = ["farine", "Mehl"] |
| 34 | +01124 = { name = "Small pack", size = "100%g", price = 1.5 } |
| 35 | +14141 = { name = "Big pack", size = "6%kg", price = 10, image = "flour.png" } |
| 36 | +``` |
| 37 | + |
| 38 | +### Equivalent dotted-table form |
| 39 | + |
| 40 | +```toml |
| 41 | +[eggs.pack-6] |
| 42 | +price = 10 |
| 43 | +name = "Pack of 6 eggs" |
| 44 | +size = "6" |
| 45 | + |
| 46 | +[eggs.single] |
| 47 | +price = 2 |
| 48 | +name = "Single Egg" |
| 49 | +size = "1" |
| 50 | + |
| 51 | +[flour.big-pack] |
| 52 | +price = 10 |
| 53 | +name = "Big pack" |
| 54 | +size = "6%kg" |
| 55 | + |
| 56 | +[flour.small-pack] |
| 57 | +price = 1.5 |
| 58 | +name = "Small pack" |
| 59 | +size = "100%g" |
| 60 | +``` |
| 61 | + |
| 62 | +## Size syntax |
| 63 | + |
| 64 | +The `size` field accepts either a single string or an array of strings. |
| 65 | + |
| 66 | +Single sizes: |
| 67 | + |
| 68 | +```toml |
| 69 | +[eggs] |
| 70 | +single = { name = "Single Egg", size = "1", price = 2 } |
| 71 | +``` |
| 72 | + |
| 73 | +Sizes with a unit: |
| 74 | + |
| 75 | +```toml |
| 76 | +[flour] |
| 77 | +small-pack = { name = "Small pack", size = "100%g", price = 1.5 } |
| 78 | +``` |
| 79 | + |
| 80 | +Multiple equivalent sizes for the same product: |
| 81 | + |
| 82 | +```toml |
| 83 | +[eggs] |
| 84 | +pack-of-12 = { name = "Pack of 12 eggs", size = ["1%dozen", "12"], price = 18 } |
| 85 | +``` |
| 86 | + |
| 87 | +## Metadata and aliases |
| 88 | + |
| 89 | +Any additional keys on a product entry are preserved as metadata when parsing and are written back when stringifying. |
| 90 | + |
| 91 | +```toml |
| 92 | +[flour] |
| 93 | +small-pack = { name = "Small pack", size = "100%g", price = 1.5, image = "flour.png" } |
| 94 | +``` |
| 95 | + |
| 96 | +`aliases` belongs on the ingredient table, not on the product entry. It is parsed as an array of alternate ingredient names: |
| 97 | + |
| 98 | +```toml |
| 99 | +[eggs] |
| 100 | +aliases = ["oeuf", "huevo"] |
| 101 | +single = { name = "Single Egg", size = "1", price = 2 } |
| 102 | +``` |
| 103 | + |
| 104 | +## Full example |
| 105 | + |
| 106 | +```typescript |
| 107 | +import { ProductCatalog } from "@tmlmt/cooklang-parser"; |
| 108 | + |
| 109 | +const catalog = new ProductCatalog(` |
| 110 | +[eggs] |
| 111 | +aliases = ["oeuf", "huevo"] |
| 112 | +01123 = { name = "Single Egg", size = "1", price = 2 } |
| 113 | +11244 = { name = "Pack of 6 eggs", size = "6", price = 10 } |
| 114 | +
|
| 115 | +[flour] |
| 116 | +aliases = ["farine", "Mehl"] |
| 117 | +01124 = { name = "Small pack", size = "100%g", price = 1.5 } |
| 118 | +14141 = { name = "Big pack", size = "6%kg", price = 10, image = "flour.png" } |
| 119 | +`); |
| 120 | + |
| 121 | +const eggs = catalog.products.find((product) => product.ingredientName === "eggs"); |
| 122 | +``` |
| 123 | + |
| 124 | +If you only need a compact reference, the API page for [ProductCatalog](/api/classes/ProductCatalog) links back here. |
0 commit comments