@recipe-book/core 0.0.3 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +116 -0
- package/LICENSE +21 -0
- package/README.md +50 -7
- package/dist/chunk-D5CV3UF7.cjs +2754 -0
- package/dist/chunk-D5CV3UF7.cjs.map +1 -0
- package/dist/errors.js +76 -0
- package/dist/errors.js.map +1 -0
- package/dist/format/duration.js +36 -0
- package/dist/format/duration.js.map +1 -0
- package/dist/format/ingredient.js +49 -0
- package/dist/format/ingredient.js.map +1 -0
- package/dist/format/number.js +120 -0
- package/dist/format/number.js.map +1 -0
- package/dist/format/options.js +31 -0
- package/dist/format/options.js.map +1 -0
- package/dist/format/quantity.js +144 -0
- package/dist/format/quantity.js.map +1 -0
- package/dist/format/servings.js +68 -0
- package/dist/format/servings.js.map +1 -0
- package/dist/format/temperature.js +35 -0
- package/dist/format/temperature.js.map +1 -0
- package/dist/index.cjs +476 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +994 -0
- package/dist/index.d.ts +994 -5
- package/dist/index.js +48 -1
- package/dist/index.js.map +1 -0
- package/dist/ingredient/parse.js +412 -0
- package/dist/ingredient/parse.js.map +1 -0
- package/dist/issues.js +26 -0
- package/dist/issues.js.map +1 -0
- package/dist/quantity/amount.js +78 -0
- package/dist/quantity/amount.js.map +1 -0
- package/dist/quantity/parse.js +255 -0
- package/dist/quantity/parse.js.map +1 -0
- package/dist/quantity/scale.js +23 -0
- package/dist/quantity/scale.js.map +1 -0
- package/dist/recipe/duration.js +28 -0
- package/dist/recipe/duration.js.map +1 -0
- package/dist/recipe/ids.js +68 -0
- package/dist/recipe/ids.js.map +1 -0
- package/dist/recipe/infer.js +24 -0
- package/dist/recipe/infer.js.map +1 -0
- package/dist/recipe/nutrient-units.js +18 -0
- package/dist/recipe/nutrient-units.js.map +1 -0
- package/dist/recipe/nutrition.js +26 -0
- package/dist/recipe/nutrition.js.map +1 -0
- package/dist/recipe/parse.js +854 -0
- package/dist/recipe/parse.js.map +1 -0
- package/dist/recipe/schema.js +32 -0
- package/dist/recipe/schema.js.map +1 -0
- package/dist/recipe/url.js +9 -0
- package/dist/recipe/url.js.map +1 -0
- package/dist/resolve.js +120 -0
- package/dist/resolve.js.map +1 -0
- package/dist/schema-org/find.js +158 -0
- package/dist/schema-org/find.js.map +1 -0
- package/dist/schema-org/from-json-ld.js +647 -0
- package/dist/schema-org/from-json-ld.js.map +1 -0
- package/dist/schema-org/nutrients.js +19 -0
- package/dist/schema-org/nutrients.js.map +1 -0
- package/dist/schema-org/text.js +125 -0
- package/dist/schema-org/text.js.map +1 -0
- package/dist/schema-org/to-json-ld.js +151 -0
- package/dist/schema-org/to-json-ld.js.map +1 -0
- package/dist/schema-org.cjs +1062 -0
- package/dist/schema-org.cjs.map +1 -0
- package/dist/schema-org.d.cts +223 -0
- package/dist/schema-org.d.ts +223 -0
- package/dist/schema-org.js +10 -0
- package/dist/schema-org.js.map +1 -0
- package/dist/steps/segment.js +45 -0
- package/dist/steps/segment.js.map +1 -0
- package/dist/steps/temperature.js +174 -0
- package/dist/steps/temperature.js.map +1 -0
- package/dist/suggest.js +50 -0
- package/dist/suggest.js.map +1 -0
- package/dist/types-BknM8KOd.d.cts +628 -0
- package/dist/types-BknM8KOd.d.ts +628 -0
- package/dist/units/convert.js +79 -0
- package/dist/units/convert.js.map +1 -0
- package/dist/units/lookup.js +86 -0
- package/dist/units/lookup.js.map +1 -0
- package/dist/units/registry.js +183 -0
- package/dist/units/registry.js.map +1 -0
- package/dist/units/system.js +91 -0
- package/dist/units/system.js.map +1 -0
- package/dist/units/temperature.js +40 -0
- package/dist/units/temperature.js.map +1 -0
- package/dist/validation.js +90 -0
- package/dist/validation.js.map +1 -0
- package/package.json +53 -8
- package/schema-org/package.json +5 -0
- package/dist/chunk-22RBQQWH.mjs +0 -1
- package/dist/chunk-3CSP4UZG.mjs +0 -1
- package/dist/chunk-3FFMHRB7.mjs +0 -26
- package/dist/chunk-4EB3HG6B.mjs +0 -50
- package/dist/chunk-4EHNJLGI.mjs +0 -50
- package/dist/chunk-4IA5EEKI.mjs +0 -81
- package/dist/chunk-4TATADPT.mjs +0 -51
- package/dist/chunk-6GI5KLI4.mjs +0 -22
- package/dist/chunk-6QJZOZ6W.mjs +0 -49
- package/dist/chunk-6YYQ4RYZ.mjs +0 -26
- package/dist/chunk-7BBUDI2L.mjs +0 -0
- package/dist/chunk-7KEMNCV7.mjs +0 -26
- package/dist/chunk-7MMJZZ7Z.mjs +0 -75
- package/dist/chunk-BES4V7DM.mjs +0 -26
- package/dist/chunk-BRDXRIAH.mjs +0 -50
- package/dist/chunk-C45UD45A.mjs +0 -1
- package/dist/chunk-CBLJXA6P.mjs +0 -1
- package/dist/chunk-CFR2ZBPB.mjs +0 -77
- package/dist/chunk-DYMNVFL2.mjs +0 -78
- package/dist/chunk-F6AQKXJU.mjs +0 -51
- package/dist/chunk-FW4M2R43.mjs +0 -51
- package/dist/chunk-GCCEDUST.mjs +0 -75
- package/dist/chunk-GE7KBYZR.mjs +0 -26
- package/dist/chunk-GN7ZDGYC.mjs +0 -51
- package/dist/chunk-GOO2SCQX.mjs +0 -75
- package/dist/chunk-HAVKBQLH.mjs +0 -51
- package/dist/chunk-HCBIPANU.mjs +0 -50
- package/dist/chunk-IEBAGBS7.mjs +0 -51
- package/dist/chunk-IQ6WN2V4.mjs +0 -75
- package/dist/chunk-JB4Z2FR7.mjs +0 -77
- package/dist/chunk-JMTQOTBM.mjs +0 -75
- package/dist/chunk-JRO6JUES.mjs +0 -51
- package/dist/chunk-KH3SRXET.mjs +0 -52
- package/dist/chunk-KNZMCAQZ.mjs +0 -51
- package/dist/chunk-KXFUCO3R.mjs +0 -1
- package/dist/chunk-LEBGCVCJ.mjs +0 -75
- package/dist/chunk-MAHWFCIL.mjs +0 -51
- package/dist/chunk-MPH76SLC.mjs +0 -51
- package/dist/chunk-MQGMFBJQ.mjs +0 -26
- package/dist/chunk-NMIVG7T4.mjs +0 -6
- package/dist/chunk-Q3TT3AZ4.mjs +0 -26
- package/dist/chunk-QY5HJQIL.mjs +0 -51
- package/dist/chunk-RCPLSNKM.mjs +0 -1
- package/dist/chunk-SR2KFBT3.mjs +0 -1
- package/dist/chunk-ULDLBAEG.mjs +0 -1
- package/dist/chunk-UQ3EUYFR.mjs +0 -1
- package/dist/chunk-V26OCCTL.mjs +0 -82
- package/dist/chunk-WBQAMGXK.mjs +0 -0
- package/dist/chunk-WSW6FMUL.mjs +0 -51
- package/dist/chunk-WU55SBIV.mjs +0 -75
- package/dist/chunk-XINK45P3.mjs +0 -51
- package/dist/chunk-XNOHIWI3.mjs +0 -1
- package/dist/chunk-XV4QN4LA.mjs +0 -6
- package/dist/chunk-YHBXEVUX.mjs +0 -51
- package/dist/chunk-YSZSCEI7.mjs +0 -75
- package/dist/chunk-YY3SUQ7P.mjs +0 -16
- package/dist/chunk-YZB3IG47.mjs +0 -80
- package/dist/chunk-ZPZT4LMQ.mjs +0 -25
- package/dist/const/conversion.d.mts +0 -7
- package/dist/const/conversion.d.ts +0 -7
- package/dist/const/conversion.js +0 -1
- package/dist/const/conversion.mjs +0 -1
- package/dist/const/unit.d.mts +0 -119
- package/dist/const/unit.d.ts +0 -119
- package/dist/const/unit.js +0 -1
- package/dist/const/unit.mjs +0 -1
- package/dist/index.d.mts +0 -5
- package/dist/index.mjs +0 -1
- package/dist/lib/assert.d.mts +0 -18
- package/dist/lib/assert.d.ts +0 -18
- package/dist/lib/assert.js +0 -1
- package/dist/lib/assert.mjs +0 -1
- package/dist/lib/ingredient.d.mts +0 -9
- package/dist/lib/ingredient.d.ts +0 -9
- package/dist/lib/ingredient.js +0 -1
- package/dist/lib/ingredient.mjs +0 -1
- package/dist/lib/recipe.d.mts +0 -12
- package/dist/lib/recipe.d.ts +0 -12
- package/dist/lib/recipe.js +0 -1
- package/dist/lib/recipe.mjs +0 -1
- package/dist/lib/runtime.d.mts +0 -3
- package/dist/lib/runtime.d.ts +0 -3
- package/dist/lib/runtime.js +0 -1
- package/dist/lib/runtime.mjs +0 -1
- package/dist/lib/unit.d.mts +0 -19
- package/dist/lib/unit.d.ts +0 -19
- package/dist/lib/unit.js +0 -1
- package/dist/lib/unit.mjs +0 -1
- package/dist/types.d.mts +0 -36
- package/dist/types.d.ts +0 -36
- package/dist/types.js +0 -1
- package/dist/types.mjs +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# @recipe-book/core
|
|
2
|
+
|
|
3
|
+
## 0.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- `convert`, `toSystem`, and `scaleQuantity` throw `invalid_argument` when the result overflows to `Infinity` or underflows to 0, and `convertTemperature` throws it when the result overflows to `Infinity` or `-Infinity`. ([#1014](https://github.com/SirajChokshi/recipe-book/pull/1014) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
8
|
+
|
|
9
|
+
- They used to return the `Infinity` or 0, which no recipe can use.
|
|
10
|
+
- A result only gets there from an amount near the largest or smallest number a JavaScript number can hold, such as `convert({ amount: 1e308, unit: 'gallon' }, 'cup')`, or from a `scaleQuantity` factor that takes an amount there, such as `scaleQuantity({ amount: 2, unit: 'cup' }, 1e308)`.
|
|
11
|
+
|
|
12
|
+
- `fromJsonLd` leaves a field that nests more than 32 levels deep out of `extra`, with a warning, so a page with a deeply nested `author` no longer gives a result that `JSON.stringify` can't serialize. ([#383](https://github.com/SirajChokshi/recipe-book/pull/383) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
13
|
+
|
|
14
|
+
- `fromJsonLd` no longer throws a `TypeError` for arrays that only JSON-LD built in code can have, never plain `JSON.parse` output. ([#948](https://github.com/SirajChokshi/recipe-book/pull/948) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
15
|
+
|
|
16
|
+
- A `tool` list with a hole in it is read without the hole.
|
|
17
|
+
- An array with another prototype, such as `null`, or with a `constructor` that isn't one, such as a number, is read as a list.
|
|
18
|
+
- It also orders a list with a hole in it by `position` when every element it holds has one.
|
|
19
|
+
|
|
20
|
+
- `findRecipeJsonLd` and `fromJsonLd` find the Recipes in an `ItemList`, such as a roundup page's list of recipes, when they find no other Recipe. ([#995](https://github.com/SirajChokshi/recipe-book/pull/995) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
21
|
+
|
|
22
|
+
- They find each Recipe in a list's `itemListElement`, or in a `ListItem`'s `item` there, in document order.
|
|
23
|
+
- They read a list at the top level, in arrays and `@graph`, and as the `mainEntity` of a node there.
|
|
24
|
+
- They skip a `ListItem` with only a `url`. To read its recipe, fetch that page and find it there.
|
|
25
|
+
- JSON-LD in which they already find a Recipe gives the same result as before, so they ignore a "related recipes" list beside a page's own Recipe.
|
|
26
|
+
- Given a roundup's JSON-LD, `fromJsonLd` now reads its first Recipe, with an `ignored_value` warning for the others, instead of failing.
|
|
27
|
+
- `fromJsonLd`'s `invalid_type` message for input with no Recipe now says "an array, @graph, mainEntity, or ItemList that holds one".
|
|
28
|
+
|
|
29
|
+
- `scaleQuantity` and `toSystem` now scale or convert the `amount` and `unit` they checked, so a quantity whose `amount`, range ends, or `unit` are getters can't pass the checks with one value and be used with another. ([#1013](https://github.com/SirajChokshi/recipe-book/pull/1013) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
30
|
+
|
|
31
|
+
- Before, `scaleQuantity` could return `NaN`, a negative amount, or a range whose `min` is above its `max`, and `toSystem` could convert `NaN` or the wrong unit.
|
|
32
|
+
- `convert` already worked this way.
|
|
33
|
+
|
|
34
|
+
- `fromJsonLd` no longer lets a step, section step, or tool it ignores come back from a polluted `Object.prototype`, and `parseRecipe` skips a hole in a list, including `equivalents`, instead of reading it from the prototype. ([#1012](https://github.com/SirajChokshi/recipe-book/pull/1012) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
35
|
+
|
|
36
|
+
- `fromJsonLd` reads a `ListItem` in `recipeIngredient` or `recipeInstructions` as the item it holds. ([#972](https://github.com/SirajChokshi/recipe-book/pull/972) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
37
|
+
|
|
38
|
+
- A `ListItem` whose `item` is a list adds each entry, and one whose `item` is a named `HowToSection` adds that section.
|
|
39
|
+
- One with no `item`, or with blank text as its `item`, is read by its name.
|
|
40
|
+
- An item in nested `ListItem`s is left out more than 32 levels deep, like any other, with the same `invalid_type` warning at its path.
|
|
41
|
+
- An image more than 32 levels deep is left out whether it's a URL or an `ImageObject`, with an `invalid_type` warning that says it's nested more than 32 levels deep.
|
|
42
|
+
|
|
43
|
+
- The `invalid_argument` message for a bad `locale` now says it must be a language tag that `Intl` accepts, such as `"en-US"`, rather than any BCP 47 language tag. ([#967](https://github.com/SirajChokshi/recipe-book/pull/967) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
44
|
+
|
|
45
|
+
- `Intl` rejects some BCP 47 tags, such as `'i-klingon'` and `'x-private'`, and those still throw.
|
|
46
|
+
|
|
47
|
+
- `fromJsonLd` reads each node once when several images share it, and gives its warnings once, so a page that shares a node of `data:` URLs among many images no longer takes seconds to read. ([#381](https://github.com/SirajChokshi/recipe-book/pull/381) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
48
|
+
|
|
49
|
+
- `fromJsonLd` leaves out an image URL longer than 4,096 UTF-16 code units, with an `invalid_url` warning. ([#385](https://github.com/SirajChokshi/recipe-book/pull/385) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
50
|
+
|
|
51
|
+
- Each step that refers to an image holds its own copy of the URL, so this bounds how much a long image URL can grow the recipe.
|
|
52
|
+
|
|
53
|
+
- `parseIngredientLine`, `parseRecipe`, and `fromJsonLd` read an amount and unit after a name and a colon, so `'salt: 1.25 g'`, which they used to read whole as the name, gets `name: 'salt'` and `quantity: { amount: 1.25, unit: 'g' }`. ([#1025](https://github.com/SirajChokshi/recipe-book/pull/1025) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
54
|
+
|
|
55
|
+
- Only a note after a comma can follow the unit: `'nagaimo: 160 g, grated'` also gets `note: 'grated'`.
|
|
56
|
+
- After a leading `optional`, `'Optional salt: 1 g'` also gets `optional: true`.
|
|
57
|
+
- Text before the colon isn't read as a name if it has a digit or starts with the word `for`, `to`, `a`, `an`, `yield`, `yields`, or `total`, so `'For the sauce: 1 cup'` and `'Yield: 2 cups'` are unchanged.
|
|
58
|
+
- Text that is just `makes`, `serves`, `serving`, `servings`, `serving size`, `protein`, `carbs`, `carbohydrate`, `carbohydrates`, `fiber`, `fibre`, `sodium`, `cholesterol`, `saturated fat`, or `fat` isn't read as a name either. So `'Serves: 2 cups'` and `'Protein: 12 g'` are unchanged, but `'Protein powder: 30 g'` gets `name: 'Protein powder'`.
|
|
59
|
+
- A bare count after the colon, as in `'shiitake: 6'`, or a word that isn't a unit alias, as in `'salt: 1 zork'`, leaves the whole line as the name.
|
|
60
|
+
|
|
61
|
+
- `parseIngredientLine`, `parseRecipe`, and `fromJsonLd` read a bare count followed by a word that starts with `or`, `to`, `and`, `plus`, or `half` and continues with an accented letter, so `'2 orégano sprigs'`, which they used to keep whole as the name with an `invalid_quantity` warning, gets `name: 'orégano sprig'` and `quantity: { amount: 2 }`. ([#1090](https://github.com/SirajChokshi/recipe-book/pull/1090) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
62
|
+
|
|
63
|
+
- After a unit, a word that starts with `and` or `plus` and continues with an accented letter is read as part of the name, so `'1 kg Andújar olives'`, which they also kept whole with an `invalid_quantity` warning, gets `name: 'Andújar olives'` and `quantity: { amount: 1, unit: 'kg' }`.
|
|
64
|
+
|
|
65
|
+
- `parseRecipe` reports an amount below 1e-300 or above 1e290 as `invalid_amount`, and `recipeSchema` and `createRecipeSchema` reject it. ([#1037](https://github.com/SirajChokshi/recipe-book/pull/1037) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
66
|
+
|
|
67
|
+
- Before, they accepted any finite amount greater than 0, so a large or small enough one could resolve to `Infinity` or 0 when scaled and converted, and `formatIngredient`, `formatServings`, and `formatYield` threw on it. Within the limits, scaling by up to 1e6 either way and converting to any unit keeps an amount finite and greater than 0.
|
|
68
|
+
- The limits apply to ingredient quantities and equivalents, both ends of a range, servings, and yield, whether written as numbers, objects, or text.
|
|
69
|
+
- `fromJsonLd` leaves out a yield or ingredient line that holds such an amount, with a warning, as it does other values it can't read.
|
|
70
|
+
- `parseQuantity` and `parseIngredientLine` still accept such amounts.
|
|
71
|
+
|
|
72
|
+
- `parseRecipe` no longer throws for arrays that only code can build, never `JSON.parse` output, and reads them as lists. ([#1069](https://github.com/SirajChokshi/recipe-book/pull/1069) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
73
|
+
|
|
74
|
+
- An array with another prototype, such as `null`, is read as a list. So is one with its own `forEach` or `flatMap` that isn't a function, or its own `constructor` that isn't a constructor, such as a number.
|
|
75
|
+
- An `Array` subclass whose `Symbol.species` getter throws is read as a list too, instead of `parseRecipe` throwing that error.
|
|
76
|
+
- This holds for `ingredients`, a section's `items`, `steps`, `notes`, `equipment`, `times.custom`, and `equivalents`, and for `recipeSchema`.
|
|
77
|
+
|
|
78
|
+
- `recipeSchema`, and `createRecipeSchema` without `parseIngredientLine`, now end the message for an ingredient written as text with `To read ingredient lines, use createRecipeSchema({ parseIngredientLine }).` ([#965](https://github.com/SirajChokshi/recipe-book/pull/965) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
79
|
+
|
|
80
|
+
- The message used to say to pass `parseIngredientLine` to `parseRecipe`, which isn't how a schema reads lines.
|
|
81
|
+
- `parseRecipe`'s own message is unchanged.
|
|
82
|
+
|
|
83
|
+
- `resolveRecipe` accepts `servings` of exactly a millionth or a million times the scaling base, such as 700000 for a base of 0.7 or 0.0000161 for a base of 16.1, which dividing by the base put just outside the window. ([#911](https://github.com/SirajChokshi/recipe-book/pull/911) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
84
|
+
|
|
85
|
+
- It also stops accepting a number just past a bound that rounding used to let in.
|
|
86
|
+
- The `scale` for servings at a bound stays from 1e-6 to 1e6, as `ResolvedRecipe.scale` says.
|
|
87
|
+
|
|
88
|
+
- `segmentStepText` no longer reads part of a word with an accented letter, such as the `f` in "200 fèves", as a temperature unit, a fan marker, or a word such as "is" or "by". ([#1093](https://github.com/SirajChokshi/recipe-book/pull/1093) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
89
|
+
|
|
90
|
+
- `'Ajoutez 200 fèves et mélangez.'` and `'Cuire à 180° côté peau.'` are text. Before, they read as 200 °F and 180 °C.
|
|
91
|
+
- The same goes for a Cyrillic word that starts with `С`, as in `'Нагреть до 180 °Сначала'`.
|
|
92
|
+
- `'Asse os pastéis 180 °.'` is text, even with `assumeTemperatureUnit`, since the "is" that ends "pastéis" isn't the word "is". Before, it read as 180 °C.
|
|
93
|
+
- `'Ofen 200 °C Umluftöfen'` reads as 200 °C without `fan`. Before, `200 °C Umluft` was a fan setting.
|
|
94
|
+
- `'Stéfan 180 °C'` reads as 180 °C without `fan`. Before, `fan 180 °C` was a fan setting.
|
|
95
|
+
- `'Upečte chléby 220 °C'` reads as 220 °C. Before, the "by" that ends "chléby" made it a change in temperature, so it stayed text.
|
|
96
|
+
- A unit right before Chinese, Japanese, or Korean text is still read, as in `'45°C/113°F的温水'` and `'180°Cで20分焼く'`.
|
|
97
|
+
|
|
98
|
+
- `parseIngredientLine` and `parseRecipe` read a unit before `of` with no amount as 1 when it has a period or two words, or follows a size word, as they already did for a unit written in letters only. ([#970](https://github.com/SirajChokshi/recipe-book/pull/970) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
99
|
+
|
|
100
|
+
- `'tsp. of salt'` gets `quantity: { amount: 1, unit: 'tsp' }`, `'fl oz of water'` gets `quantity: { amount: 1, unit: 'fl-oz' }`, and `'big pinch of salt'` gets `quantity: { amount: 1, unit: 'pinch' }` and `note: 'big'`. Before, the whole line was the name.
|
|
101
|
+
- `'pinch of the salt'` gets `name: 'salt'`, as `'1 pinch of the salt'` does.
|
|
102
|
+
- A line with nothing after `of`, such as `'pinch of'`, gets the same warning as `'2 cups of'`.
|
|
103
|
+
|
|
104
|
+
- `toJsonLd` now replaces a fragment in `url` even when the fragment holds a line break, so each step's `url` is everything before the first `#`, with the step's id, percent-encoded, as the fragment. ([#420](https://github.com/SirajChokshi/recipe-book/pull/420) by [@SirajChokshi](https://github.com/SirajChokshi))
|
|
105
|
+
|
|
106
|
+
## 0.1.0
|
|
107
|
+
|
|
108
|
+
- `parseRecipe` validates recipe input and returns a normalized `Recipe`, or every issue it found, each with a code, a path and, for a likely typo, a suggestion. `recipeSchema` is the same check as a Standard Schema.
|
|
109
|
+
- `parseIngredientLine` reads a line such as `'1 ½ cups (190 g) flour, sifted'`, and `parseQuantity` reads quantity text.
|
|
110
|
+
- A unit registry with exact sizes, `findUnit` for unit text, and `convert`, `toSystem` and `convertTemperature`.
|
|
111
|
+
- `resolveRecipe` scales a recipe and expresses each ingredient in metric or US units.
|
|
112
|
+
- `formatQuantity`, `formatIngredient` and the other `format*` functions write display text. With the default `en-US` locale, that text is the same on a server and in a browser, because English output doesn't use `Intl`. Other locales format numbers with the runtime's `Intl` data.
|
|
113
|
+
- `segmentStepText` finds the temperatures in step text.
|
|
114
|
+
- `@recipe-book/core/schema-org` reads recipes from schema.org Recipe JSON-LD and writes a recipe as JSON-LD.
|
|
115
|
+
- ESM and CommonJS builds, each with type declarations and source maps. Requires Node 22 or later.
|
|
116
|
+
- The ESM build keeps each source module in its own file. With Next.js (Turbopack or webpack), and with Vite when each page loads as its own chunk, such as a lazy route, only the pages that import a parser, or an export built on one such as `recipeSchema`, `createRecipeSchema`, or `fromJsonLd`, download it, so a page that renders `@recipe-book/react` parts or formats quantities stays free of the parser even when another page parses in the browser. `import('@recipe-book/core')` can still download a parser, on the page that calls it in Next.js and on every page that uses `@recipe-book/react` in Vite.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Siraj Chokshi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,11 +1,54 @@
|
|
|
1
1
|
# @recipe-book/core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Parse, validate, scale, convert, and format recipes. Core has no runtime dependencies and doesn't use React, so it works in scripts, on servers, in browsers, and in React Server Components. To render recipes with unstyled React components, install [`@recipe-book/react`](https://www.npmjs.com/package/@recipe-book/react) instead, and import core's functions and types from `@recipe-book/react/core`.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Install
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
```sh
|
|
8
|
+
npm i @recipe-book/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
Parse recipe input with [`parseRecipe`](https://recipe-book.siraj.page/reference/core/parsing/#parserecipe). Then resolve the parsed recipe to a number of servings and a measurement system with [`resolveRecipe`](https://recipe-book.siraj.page/reference/core/resolving/#resolverecipe), and format each ingredient as a line with [`formatIngredient`](https://recipe-book.siraj.page/reference/core/formatting/#formatingredient).
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { formatIngredient, parseRecipe, resolveRecipe } from '@recipe-book/core'
|
|
17
|
+
|
|
18
|
+
const result = parseRecipe({
|
|
19
|
+
name: 'Buttermilk pancakes',
|
|
20
|
+
servings: 4,
|
|
21
|
+
ingredients: [
|
|
22
|
+
{ name: 'all-purpose flour', quantity: '1 ½ cups', equivalents: ['190 g'] },
|
|
23
|
+
{ name: 'buttermilk', quantity: '1 ¼ cups' },
|
|
24
|
+
{ name: 'egg', plural: 'eggs', quantity: 2 },
|
|
25
|
+
],
|
|
26
|
+
steps: [
|
|
27
|
+
'Whisk the flour, buttermilk, and eggs.',
|
|
28
|
+
'Cook ¼-cup portions on a buttered griddle, 2–3 minutes per side.',
|
|
29
|
+
],
|
|
30
|
+
})
|
|
31
|
+
if (!result.success) throw result.error
|
|
32
|
+
|
|
33
|
+
const recipe = resolveRecipe(result.data, { servings: 8, system: 'metric' })
|
|
34
|
+
|
|
35
|
+
for (const section of recipe.ingredients) {
|
|
36
|
+
for (const item of section.items) {
|
|
37
|
+
console.log(formatIngredient(item).text)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
It prints:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
380 g all-purpose flour
|
|
46
|
+
591 mL buttermilk
|
|
47
|
+
4 eggs
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The recipe has 4 servings, so 8 servings doubles each quantity. In metric, the flour uses its 190 g equivalent. The buttermilk has no metric equivalent, so `resolveRecipe` converts it from cups, and `formatIngredient` rounds it for display.
|
|
51
|
+
|
|
52
|
+
## Documentation
|
|
53
|
+
|
|
54
|
+
[recipe-book.siraj.page](https://recipe-book.siraj.page)
|