@recipe-book/core 0.1.0 → 0.1.2

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +138 -0
  2. package/README.md +1 -1
  3. package/dist/{chunk-VWVIBCTG.cjs → chunk-ISRDJR2O.cjs} +227 -179
  4. package/dist/chunk-ISRDJR2O.cjs.map +1 -0
  5. package/dist/errors.js +29 -1
  6. package/dist/errors.js.map +1 -1
  7. package/dist/format/duration.js.map +1 -1
  8. package/dist/format/ingredient.js.map +1 -1
  9. package/dist/format/number.js +1 -1
  10. package/dist/format/number.js.map +1 -1
  11. package/dist/format/options.js.map +1 -1
  12. package/dist/format/quantity.js.map +1 -1
  13. package/dist/format/servings.js.map +1 -1
  14. package/dist/format/temperature.js.map +1 -1
  15. package/dist/index.cjs +87 -74
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +71 -28
  18. package/dist/index.d.ts +71 -28
  19. package/dist/index.js +6 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/ingredient/parse.js +27 -22
  22. package/dist/ingredient/parse.js.map +1 -1
  23. package/dist/issues.js.map +1 -1
  24. package/dist/quantity/amount.js +11 -0
  25. package/dist/quantity/amount.js.map +1 -1
  26. package/dist/quantity/parse.js +58 -81
  27. package/dist/quantity/parse.js.map +1 -1
  28. package/dist/quantity/scale.js +5 -2
  29. package/dist/quantity/scale.js.map +1 -1
  30. package/dist/recipe/ids.js.map +1 -1
  31. package/dist/recipe/parse.js +80 -60
  32. package/dist/recipe/parse.js.map +1 -1
  33. package/dist/recipe/schema.js +8 -6
  34. package/dist/recipe/schema.js.map +1 -1
  35. package/dist/resolve.js +6 -1
  36. package/dist/resolve.js.map +1 -1
  37. package/dist/schema-org/find.js +46 -13
  38. package/dist/schema-org/find.js.map +1 -1
  39. package/dist/schema-org/from-json-ld.js +134 -71
  40. package/dist/schema-org/from-json-ld.js.map +1 -1
  41. package/dist/schema-org/text.js.map +1 -1
  42. package/dist/schema-org/to-json-ld.js +12 -15
  43. package/dist/schema-org/to-json-ld.js.map +1 -1
  44. package/dist/schema-org.cjs +239 -147
  45. package/dist/schema-org.cjs.map +1 -1
  46. package/dist/schema-org.d.cts +35 -21
  47. package/dist/schema-org.d.ts +35 -21
  48. package/dist/steps/segment.js.map +1 -1
  49. package/dist/steps/temperature.js +13 -13
  50. package/dist/steps/temperature.js.map +1 -1
  51. package/dist/{types-DSMf45H5.d.cts → types-CKIoWsz8.d.cts} +25 -7
  52. package/dist/{types-DSMf45H5.d.ts → types-CKIoWsz8.d.ts} +25 -7
  53. package/dist/units/convert.js +16 -8
  54. package/dist/units/convert.js.map +1 -1
  55. package/dist/units/temperature.js +7 -1
  56. package/dist/units/temperature.js.map +1 -1
  57. package/dist/validation.js +1 -1
  58. package/dist/validation.js.map +1 -1
  59. package/package.json +1 -1
  60. package/dist/chunk-VWVIBCTG.cjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,143 @@
1
1
  # @recipe-book/core
2
2
 
3
+ ## 0.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - `docsUrl`, and the link at the end of every error message, now end with a slash, such as `https://recipe-book.siraj.page/errors/unknown_unit/`, so they open the page without a redirect. ([#1377](https://github.com/SirajChokshi/recipe-book/pull/1377) by [@SirajChokshi](https://github.com/SirajChokshi))
8
+
9
+ - `RecipeBookError` now sets `cause` from its options in browsers whose built-in `Error` ignores them. ([#1217](https://github.com/SirajChokshi/recipe-book/pull/1217) by [@SirajChokshi](https://github.com/SirajChokshi))
10
+
11
+ - In Chrome and Edge before 93, Firefox before 91, and Safari before 15, `error.cause` was `undefined`.
12
+
13
+ - The TSDoc for core's conversion, format, and resolve functions now says which inputs pass through an error thrown by a getter or proxy. ([#1368](https://github.com/SirajChokshi/recipe-book/pull/1368) by [@SirajChokshi](https://github.com/SirajChokshi))
14
+
15
+ - The input and options: `resolveIngredient`, `formatQuantity`, `formatQuantityToParts`, `formatIngredient`, `formatServings`, `formatYield`, and `formatTemperature`.
16
+ - The input: `scaleQuantity`, `convert`, `toSystem`, and `convertTemperature`.
17
+ - The options: `segmentStepText`, `formatDuration`, and `toJsonLd`.
18
+
19
+ - Add `isRecipeValidationError`, which checks whether a caught value is a `RecipeValidationError` and narrows its type, so `issues` needs no cast. ([#1266](https://github.com/SirajChokshi/recipe-book/pull/1266) by [@SirajChokshi](https://github.com/SirajChokshi))
20
+
21
+ - It checks the error's `name`, `code`, and `issues` rather than using `instanceof`, so it also recognizes errors from another installed copy of `@recipe-book/core`, as `isRecipeBookError` does.
22
+
23
+ - Add `ParsedRecipe`, the same type as `Recipe` under another name. ([#924](https://github.com/SirajChokshi/recipe-book/pull/924) by [@SirajChokshi](https://github.com/SirajChokshi))
24
+
25
+ - A file that imports `@recipe-book/react` as `Recipe` can import `ParsedRecipe` from `@recipe-book/react/core` instead of renaming the type with `import type { Recipe as ParsedRecipe }`.
26
+
27
+ - `parseRecipe` and `recipeSchema` now list `duplicate_id` warnings in input order when a repeated section id follows repeated item ids in earlier sections. ([#1221](https://github.com/SirajChokshi/recipe-book/pull/1221) by [@SirajChokshi](https://github.com/SirajChokshi))
28
+
29
+ - Before, when no other issue came between them, the section's warning came before the items' warnings.
30
+
31
+ - The TSDoc for `ResolvedRecipe.servings` and `yield` now says that at a scale within 1e-9 of 1, including one the `servings` option sets, they're the authored servings and yield. ([#1368](https://github.com/SirajChokshi/recipe-book/pull/1368) by [@SirajChokshi](https://github.com/SirajChokshi))
32
+
33
+ - `segmentStepText` no longer reads a "-" right after a number with no unit of its own, or with only a degree sign, as a minus sign. ([#919](https://github.com/SirajChokshi/recipe-book/pull/919) by [@SirajChokshi](https://github.com/SirajChokshi))
34
+
35
+ - In `Bake at 350 -375°F.` and `Bake at 350° -375°F.`, it read the second end as a negative temperature, −375 °F. Such a range now stays text, as `350–375°F` does.
36
+ - After a unit, as in `350°F -375°F`, the "-" is still a minus sign.
37
+
38
+ ## 0.1.1
39
+
40
+ ### Patch Changes
41
+
42
+ - `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))
43
+
44
+ - They used to return the `Infinity` or 0, which no recipe can use.
45
+ - 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)`.
46
+
47
+ - `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))
48
+
49
+ - `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))
50
+
51
+ - A `tool` list with a hole in it is read without the hole.
52
+ - 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.
53
+ - It also orders a list with a hole in it by `position` when every element it holds has one.
54
+
55
+ - `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))
56
+
57
+ - They find each Recipe in a list's `itemListElement`, or in a `ListItem`'s `item` there, in document order.
58
+ - They read a list at the top level, in arrays and `@graph`, and as the `mainEntity` of a node there.
59
+ - They skip a `ListItem` with only a `url`. To read its recipe, fetch that page and find it there.
60
+ - 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.
61
+ - Given a roundup's JSON-LD, `fromJsonLd` now reads its first Recipe, with an `ignored_value` warning for the others, instead of failing.
62
+ - `fromJsonLd`'s `invalid_type` message for input with no Recipe now says "an array, @graph, mainEntity, or ItemList that holds one".
63
+
64
+ - `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))
65
+
66
+ - 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.
67
+ - `convert` already worked this way.
68
+
69
+ - `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))
70
+
71
+ - `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))
72
+
73
+ - A `ListItem` whose `item` is a list adds each entry, and one whose `item` is a named `HowToSection` adds that section.
74
+ - One with no `item`, or with blank text as its `item`, is read by its name.
75
+ - 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.
76
+ - 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.
77
+
78
+ - 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))
79
+
80
+ - `Intl` rejects some BCP 47 tags, such as `'i-klingon'` and `'x-private'`, and those still throw.
81
+
82
+ - `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))
83
+
84
+ - `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))
85
+
86
+ - 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.
87
+
88
+ - `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))
89
+
90
+ - Only a note after a comma can follow the unit: `'nagaimo: 160 g, grated'` also gets `note: 'grated'`.
91
+ - After a leading `optional`, `'Optional salt: 1 g'` also gets `optional: true`.
92
+ - 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.
93
+ - 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'`.
94
+ - 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.
95
+
96
+ - `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))
97
+
98
+ - 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' }`.
99
+
100
+ - `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))
101
+
102
+ - 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.
103
+ - The limits apply to ingredient quantities and equivalents, both ends of a range, servings, and yield, whether written as numbers, objects, or text.
104
+ - `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.
105
+ - `parseQuantity` and `parseIngredientLine` still accept such amounts.
106
+
107
+ - `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))
108
+
109
+ - 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.
110
+ - An `Array` subclass whose `Symbol.species` getter throws is read as a list too, instead of `parseRecipe` throwing that error.
111
+ - This holds for `ingredients`, a section's `items`, `steps`, `notes`, `equipment`, `times.custom`, and `equivalents`, and for `recipeSchema`.
112
+
113
+ - `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))
114
+
115
+ - The message used to say to pass `parseIngredientLine` to `parseRecipe`, which isn't how a schema reads lines.
116
+ - `parseRecipe`'s own message is unchanged.
117
+
118
+ - `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))
119
+
120
+ - It also stops accepting a number just past a bound that rounding used to let in.
121
+ - The `scale` for servings at a bound stays from 1e-6 to 1e6, as `ResolvedRecipe.scale` says.
122
+
123
+ - `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))
124
+
125
+ - `'Ajoutez 200 fèves et mélangez.'` and `'Cuire à 180° côté peau.'` are text. Before, they read as 200 °F and 180 °C.
126
+ - The same goes for a Cyrillic word that starts with `С`, as in `'Нагреть до 180 °Сначала'`.
127
+ - `'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.
128
+ - `'Ofen 200 °C Umluftöfen'` reads as 200 °C without `fan`. Before, `200 °C Umluft` was a fan setting.
129
+ - `'Stéfan 180 °C'` reads as 180 °C without `fan`. Before, `fan 180 °C` was a fan setting.
130
+ - `'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.
131
+ - A unit right before Chinese, Japanese, or Korean text is still read, as in `'45°C/113°F的温水'` and `'180°Cで20分焼く'`.
132
+
133
+ - `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))
134
+
135
+ - `'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.
136
+ - `'pinch of the salt'` gets `name: 'salt'`, as `'1 pinch of the salt'` does.
137
+ - A line with nothing after `of`, such as `'pinch of'`, gets the same warning as `'2 cups of'`.
138
+
139
+ - `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))
140
+
3
141
  ## 0.1.0
4
142
 
5
143
  - `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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @recipe-book/core
2
2
 
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, use it with [`@recipe-book/react`](https://www.npmjs.com/package/@recipe-book/react).
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