@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.
Files changed (185) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/LICENSE +21 -0
  3. package/README.md +50 -7
  4. package/dist/chunk-D5CV3UF7.cjs +2754 -0
  5. package/dist/chunk-D5CV3UF7.cjs.map +1 -0
  6. package/dist/errors.js +76 -0
  7. package/dist/errors.js.map +1 -0
  8. package/dist/format/duration.js +36 -0
  9. package/dist/format/duration.js.map +1 -0
  10. package/dist/format/ingredient.js +49 -0
  11. package/dist/format/ingredient.js.map +1 -0
  12. package/dist/format/number.js +120 -0
  13. package/dist/format/number.js.map +1 -0
  14. package/dist/format/options.js +31 -0
  15. package/dist/format/options.js.map +1 -0
  16. package/dist/format/quantity.js +144 -0
  17. package/dist/format/quantity.js.map +1 -0
  18. package/dist/format/servings.js +68 -0
  19. package/dist/format/servings.js.map +1 -0
  20. package/dist/format/temperature.js +35 -0
  21. package/dist/format/temperature.js.map +1 -0
  22. package/dist/index.cjs +476 -0
  23. package/dist/index.cjs.map +1 -0
  24. package/dist/index.d.cts +994 -0
  25. package/dist/index.d.ts +994 -5
  26. package/dist/index.js +48 -1
  27. package/dist/index.js.map +1 -0
  28. package/dist/ingredient/parse.js +412 -0
  29. package/dist/ingredient/parse.js.map +1 -0
  30. package/dist/issues.js +26 -0
  31. package/dist/issues.js.map +1 -0
  32. package/dist/quantity/amount.js +78 -0
  33. package/dist/quantity/amount.js.map +1 -0
  34. package/dist/quantity/parse.js +255 -0
  35. package/dist/quantity/parse.js.map +1 -0
  36. package/dist/quantity/scale.js +23 -0
  37. package/dist/quantity/scale.js.map +1 -0
  38. package/dist/recipe/duration.js +28 -0
  39. package/dist/recipe/duration.js.map +1 -0
  40. package/dist/recipe/ids.js +68 -0
  41. package/dist/recipe/ids.js.map +1 -0
  42. package/dist/recipe/infer.js +24 -0
  43. package/dist/recipe/infer.js.map +1 -0
  44. package/dist/recipe/nutrient-units.js +18 -0
  45. package/dist/recipe/nutrient-units.js.map +1 -0
  46. package/dist/recipe/nutrition.js +26 -0
  47. package/dist/recipe/nutrition.js.map +1 -0
  48. package/dist/recipe/parse.js +854 -0
  49. package/dist/recipe/parse.js.map +1 -0
  50. package/dist/recipe/schema.js +32 -0
  51. package/dist/recipe/schema.js.map +1 -0
  52. package/dist/recipe/url.js +9 -0
  53. package/dist/recipe/url.js.map +1 -0
  54. package/dist/resolve.js +120 -0
  55. package/dist/resolve.js.map +1 -0
  56. package/dist/schema-org/find.js +158 -0
  57. package/dist/schema-org/find.js.map +1 -0
  58. package/dist/schema-org/from-json-ld.js +647 -0
  59. package/dist/schema-org/from-json-ld.js.map +1 -0
  60. package/dist/schema-org/nutrients.js +19 -0
  61. package/dist/schema-org/nutrients.js.map +1 -0
  62. package/dist/schema-org/text.js +125 -0
  63. package/dist/schema-org/text.js.map +1 -0
  64. package/dist/schema-org/to-json-ld.js +151 -0
  65. package/dist/schema-org/to-json-ld.js.map +1 -0
  66. package/dist/schema-org.cjs +1062 -0
  67. package/dist/schema-org.cjs.map +1 -0
  68. package/dist/schema-org.d.cts +223 -0
  69. package/dist/schema-org.d.ts +223 -0
  70. package/dist/schema-org.js +10 -0
  71. package/dist/schema-org.js.map +1 -0
  72. package/dist/steps/segment.js +45 -0
  73. package/dist/steps/segment.js.map +1 -0
  74. package/dist/steps/temperature.js +174 -0
  75. package/dist/steps/temperature.js.map +1 -0
  76. package/dist/suggest.js +50 -0
  77. package/dist/suggest.js.map +1 -0
  78. package/dist/types-BknM8KOd.d.cts +628 -0
  79. package/dist/types-BknM8KOd.d.ts +628 -0
  80. package/dist/units/convert.js +79 -0
  81. package/dist/units/convert.js.map +1 -0
  82. package/dist/units/lookup.js +86 -0
  83. package/dist/units/lookup.js.map +1 -0
  84. package/dist/units/registry.js +183 -0
  85. package/dist/units/registry.js.map +1 -0
  86. package/dist/units/system.js +91 -0
  87. package/dist/units/system.js.map +1 -0
  88. package/dist/units/temperature.js +40 -0
  89. package/dist/units/temperature.js.map +1 -0
  90. package/dist/validation.js +90 -0
  91. package/dist/validation.js.map +1 -0
  92. package/package.json +53 -8
  93. package/schema-org/package.json +5 -0
  94. package/dist/chunk-22RBQQWH.mjs +0 -1
  95. package/dist/chunk-3CSP4UZG.mjs +0 -1
  96. package/dist/chunk-3FFMHRB7.mjs +0 -26
  97. package/dist/chunk-4EB3HG6B.mjs +0 -50
  98. package/dist/chunk-4EHNJLGI.mjs +0 -50
  99. package/dist/chunk-4IA5EEKI.mjs +0 -81
  100. package/dist/chunk-4TATADPT.mjs +0 -51
  101. package/dist/chunk-6GI5KLI4.mjs +0 -22
  102. package/dist/chunk-6QJZOZ6W.mjs +0 -49
  103. package/dist/chunk-6YYQ4RYZ.mjs +0 -26
  104. package/dist/chunk-7BBUDI2L.mjs +0 -0
  105. package/dist/chunk-7KEMNCV7.mjs +0 -26
  106. package/dist/chunk-7MMJZZ7Z.mjs +0 -75
  107. package/dist/chunk-BES4V7DM.mjs +0 -26
  108. package/dist/chunk-BRDXRIAH.mjs +0 -50
  109. package/dist/chunk-C45UD45A.mjs +0 -1
  110. package/dist/chunk-CBLJXA6P.mjs +0 -1
  111. package/dist/chunk-CFR2ZBPB.mjs +0 -77
  112. package/dist/chunk-DYMNVFL2.mjs +0 -78
  113. package/dist/chunk-F6AQKXJU.mjs +0 -51
  114. package/dist/chunk-FW4M2R43.mjs +0 -51
  115. package/dist/chunk-GCCEDUST.mjs +0 -75
  116. package/dist/chunk-GE7KBYZR.mjs +0 -26
  117. package/dist/chunk-GN7ZDGYC.mjs +0 -51
  118. package/dist/chunk-GOO2SCQX.mjs +0 -75
  119. package/dist/chunk-HAVKBQLH.mjs +0 -51
  120. package/dist/chunk-HCBIPANU.mjs +0 -50
  121. package/dist/chunk-IEBAGBS7.mjs +0 -51
  122. package/dist/chunk-IQ6WN2V4.mjs +0 -75
  123. package/dist/chunk-JB4Z2FR7.mjs +0 -77
  124. package/dist/chunk-JMTQOTBM.mjs +0 -75
  125. package/dist/chunk-JRO6JUES.mjs +0 -51
  126. package/dist/chunk-KH3SRXET.mjs +0 -52
  127. package/dist/chunk-KNZMCAQZ.mjs +0 -51
  128. package/dist/chunk-KXFUCO3R.mjs +0 -1
  129. package/dist/chunk-LEBGCVCJ.mjs +0 -75
  130. package/dist/chunk-MAHWFCIL.mjs +0 -51
  131. package/dist/chunk-MPH76SLC.mjs +0 -51
  132. package/dist/chunk-MQGMFBJQ.mjs +0 -26
  133. package/dist/chunk-NMIVG7T4.mjs +0 -6
  134. package/dist/chunk-Q3TT3AZ4.mjs +0 -26
  135. package/dist/chunk-QY5HJQIL.mjs +0 -51
  136. package/dist/chunk-RCPLSNKM.mjs +0 -1
  137. package/dist/chunk-SR2KFBT3.mjs +0 -1
  138. package/dist/chunk-ULDLBAEG.mjs +0 -1
  139. package/dist/chunk-UQ3EUYFR.mjs +0 -1
  140. package/dist/chunk-V26OCCTL.mjs +0 -82
  141. package/dist/chunk-WBQAMGXK.mjs +0 -0
  142. package/dist/chunk-WSW6FMUL.mjs +0 -51
  143. package/dist/chunk-WU55SBIV.mjs +0 -75
  144. package/dist/chunk-XINK45P3.mjs +0 -51
  145. package/dist/chunk-XNOHIWI3.mjs +0 -1
  146. package/dist/chunk-XV4QN4LA.mjs +0 -6
  147. package/dist/chunk-YHBXEVUX.mjs +0 -51
  148. package/dist/chunk-YSZSCEI7.mjs +0 -75
  149. package/dist/chunk-YY3SUQ7P.mjs +0 -16
  150. package/dist/chunk-YZB3IG47.mjs +0 -80
  151. package/dist/chunk-ZPZT4LMQ.mjs +0 -25
  152. package/dist/const/conversion.d.mts +0 -7
  153. package/dist/const/conversion.d.ts +0 -7
  154. package/dist/const/conversion.js +0 -1
  155. package/dist/const/conversion.mjs +0 -1
  156. package/dist/const/unit.d.mts +0 -119
  157. package/dist/const/unit.d.ts +0 -119
  158. package/dist/const/unit.js +0 -1
  159. package/dist/const/unit.mjs +0 -1
  160. package/dist/index.d.mts +0 -5
  161. package/dist/index.mjs +0 -1
  162. package/dist/lib/assert.d.mts +0 -18
  163. package/dist/lib/assert.d.ts +0 -18
  164. package/dist/lib/assert.js +0 -1
  165. package/dist/lib/assert.mjs +0 -1
  166. package/dist/lib/ingredient.d.mts +0 -9
  167. package/dist/lib/ingredient.d.ts +0 -9
  168. package/dist/lib/ingredient.js +0 -1
  169. package/dist/lib/ingredient.mjs +0 -1
  170. package/dist/lib/recipe.d.mts +0 -12
  171. package/dist/lib/recipe.d.ts +0 -12
  172. package/dist/lib/recipe.js +0 -1
  173. package/dist/lib/recipe.mjs +0 -1
  174. package/dist/lib/runtime.d.mts +0 -3
  175. package/dist/lib/runtime.d.ts +0 -3
  176. package/dist/lib/runtime.js +0 -1
  177. package/dist/lib/runtime.mjs +0 -1
  178. package/dist/lib/unit.d.mts +0 -19
  179. package/dist/lib/unit.d.ts +0 -19
  180. package/dist/lib/unit.js +0 -1
  181. package/dist/lib/unit.mjs +0 -1
  182. package/dist/types.d.mts +0 -36
  183. package/dist/types.d.ts +0 -36
  184. package/dist/types.js +0 -1
  185. package/dist/types.mjs +0 -1
@@ -0,0 +1,628 @@
1
+ /** Thrown, or returned by the `parse*` functions, when data fails validation. */
2
+ declare class RecipeValidationError extends RecipeBookError {
3
+ readonly code: ValidationErrorCode;
4
+ /**
5
+ * Every problem found, errors and warnings, in a stable order: fields in
6
+ * model order (recipe fields, ingredients, steps, notes, equipment, then
7
+ * nutrition), list items in input order, and unknown fields last within
8
+ * their object.
9
+ */
10
+ readonly issues: readonly RecipeIssue[];
11
+ /**
12
+ * @param subject - What was validated, shown as given at the start of the
13
+ * message, e.g. `'"Buttermilk pancakes"'`. Recipe Book's own errors quote
14
+ * the recipe's name or the input text like a JSON string, cut with "…"
15
+ * when longer than 60 UTF-16 code units.
16
+ */
17
+ constructor(code: ValidationErrorCode, issues: readonly RecipeIssue[], subject?: string);
18
+ }
19
+
20
+ /**
21
+ * Codes for errors thrown by Recipe Book. May grow in minor releases.
22
+ *
23
+ * @see https://recipe-book.siraj.page/errors
24
+ */
25
+ type RecipeBookErrorCode = 'invalid_recipe' | 'invalid_quantity' | 'invalid_ingredient' | 'invalid_argument' | 'incompatible_units' | 'unknown_unit' | 'missing_parent';
26
+ /** Codes for problems found in recipe data. May grow in minor releases. */
27
+ type RecipeIssueCode = 'invalid_type' | 'missing_field' | 'unknown_unit' | 'invalid_quantity' | 'invalid_amount' | 'invalid_range' | 'invalid_duration' | 'invalid_url' | 'unknown_field' | 'duplicate_id' | 'empty_list' | 'ignored_value';
28
+ /** A problem found in recipe data. Data problems are returned as values, never thrown one by one. */
29
+ type RecipeIssue = {
30
+ code: RecipeIssueCode;
31
+ severity: 'error' | 'warning';
32
+ /** Location in the input, e.g. `['ingredients', 0, 'quantity']`. */
33
+ path: readonly (string | number)[];
34
+ /** A complete sentence that names the fix. */
35
+ message: string;
36
+ /** The value the input most likely meant, for "did you mean" hints. */
37
+ suggestion?: string | undefined;
38
+ };
39
+ /**
40
+ * Thrown for programmer errors, such as converting cups to grams or passing an
41
+ * unknown unit id. Each error has a stable `code` and a `docsUrl` that explains the fix.
42
+ *
43
+ * Use {@link isRecipeBookError} rather than `instanceof` to detect it, so the
44
+ * check also works when two copies of the package are installed.
45
+ */
46
+ declare class RecipeBookError extends Error {
47
+ readonly name: string;
48
+ readonly code: RecipeBookErrorCode;
49
+ readonly docsUrl: string;
50
+ constructor(code: RecipeBookErrorCode, message: string, options?: {
51
+ cause?: unknown;
52
+ });
53
+ }
54
+ /** Codes for `RecipeValidationError`. May grow in minor releases. */
55
+ type ValidationErrorCode = 'invalid_recipe' | 'invalid_quantity' | 'invalid_ingredient';
56
+ /**
57
+ * What `parseRecipe`, `parseQuantity`, and `parseIngredientLine` return. They
58
+ * never throw for bad data: check `success`, or `throw result.error` to fail
59
+ * loudly.
60
+ *
61
+ * @example
62
+ * const result = parseRecipe(json)
63
+ * if (!result.success) throw result.error // message lists the first 10 issues with their paths
64
+ * result.data // Recipe
65
+ */
66
+ type ParseResult<T> = {
67
+ success: true;
68
+ data: T;
69
+ warnings: RecipeIssue[];
70
+ } | {
71
+ success: false;
72
+ error: RecipeValidationError;
73
+ };
74
+ /** True for errors thrown by any copy of Recipe Book. Checks `name` and `code`, not `instanceof`. */
75
+ declare function isRecipeBookError(error: unknown): error is RecipeBookError;
76
+
77
+ /** A measurement system. `'us'` is US customary. */
78
+ type System = 'metric' | 'us';
79
+ /** What a unit measures. Count units, such as `clove` or `pinch`, have no fixed size. */
80
+ type Dimension = 'mass' | 'volume' | 'count';
81
+ type Label = {
82
+ one: string;
83
+ other: string;
84
+ };
85
+ declare function definitions(): {
86
+ readonly mg: {
87
+ readonly dimension: "mass";
88
+ readonly systems: readonly ["metric"];
89
+ readonly toBase: 0.001;
90
+ readonly aliases: readonly ["milligram", "milligrams", "milligramme", "milligrammes"];
91
+ readonly labels: {
92
+ readonly short: Label;
93
+ readonly long: Label;
94
+ };
95
+ };
96
+ readonly g: {
97
+ readonly dimension: "mass";
98
+ readonly systems: readonly ["metric"];
99
+ readonly toBase: 1;
100
+ readonly aliases: readonly ["gram", "grams", "gramme", "grammes"];
101
+ readonly labels: {
102
+ readonly short: Label;
103
+ readonly long: Label;
104
+ };
105
+ };
106
+ readonly kg: {
107
+ readonly dimension: "mass";
108
+ readonly systems: readonly ["metric"];
109
+ readonly toBase: 1000;
110
+ readonly aliases: readonly ["kgs", "kilo", "kilos", "kilogram", "kilograms", "kilogramme", "kilogrammes"];
111
+ readonly labels: {
112
+ readonly short: Label;
113
+ readonly long: Label;
114
+ };
115
+ };
116
+ readonly oz: {
117
+ readonly dimension: "mass";
118
+ readonly systems: readonly ["us"];
119
+ readonly toBase: 28.349523125;
120
+ readonly aliases: readonly ["ounce", "ounces"];
121
+ readonly labels: {
122
+ readonly short: Label;
123
+ readonly long: Label;
124
+ };
125
+ };
126
+ readonly lb: {
127
+ readonly dimension: "mass";
128
+ readonly systems: readonly ["us"];
129
+ readonly toBase: number;
130
+ readonly aliases: readonly ["lbs", "pound", "pounds"];
131
+ readonly labels: {
132
+ readonly short: Label;
133
+ readonly long: Label;
134
+ };
135
+ };
136
+ readonly ml: {
137
+ readonly dimension: "volume";
138
+ readonly systems: readonly ["metric"];
139
+ readonly toBase: 1;
140
+ readonly aliases: readonly ["mL", "milliliter", "milliliters", "millilitre", "millilitres"];
141
+ readonly labels: {
142
+ readonly short: Label;
143
+ readonly long: Label;
144
+ };
145
+ };
146
+ readonly cl: {
147
+ readonly dimension: "volume";
148
+ readonly systems: readonly ["metric"];
149
+ readonly toBase: 10;
150
+ readonly aliases: readonly ["cL", "centiliter", "centiliters", "centilitre", "centilitres"];
151
+ readonly labels: {
152
+ readonly short: Label;
153
+ readonly long: Label;
154
+ };
155
+ };
156
+ readonly dl: {
157
+ readonly dimension: "volume";
158
+ readonly systems: readonly ["metric"];
159
+ readonly toBase: 100;
160
+ readonly aliases: readonly ["dL", "deciliter", "deciliters", "decilitre", "decilitres"];
161
+ readonly labels: {
162
+ readonly short: Label;
163
+ readonly long: Label;
164
+ };
165
+ };
166
+ readonly l: {
167
+ readonly dimension: "volume";
168
+ readonly systems: readonly ["metric"];
169
+ readonly toBase: 1000;
170
+ readonly aliases: readonly ["L", "liter", "liters", "litre", "litres"];
171
+ readonly labels: {
172
+ readonly short: Label;
173
+ readonly long: Label;
174
+ };
175
+ };
176
+ readonly tsp: {
177
+ readonly dimension: "volume";
178
+ readonly systems: readonly ["metric", "us"];
179
+ readonly toBase: 4.92892159375;
180
+ readonly aliases: readonly ["t", "tsps", "teaspoon", "teaspoons"];
181
+ readonly labels: {
182
+ readonly short: Label;
183
+ readonly long: Label;
184
+ };
185
+ };
186
+ readonly tbsp: {
187
+ readonly dimension: "volume";
188
+ readonly systems: readonly ["metric", "us"];
189
+ readonly toBase: number;
190
+ readonly aliases: readonly ["T", "tbs", "tbsps", "tablespoon", "tablespoons"];
191
+ readonly labels: {
192
+ readonly short: Label;
193
+ readonly long: Label;
194
+ };
195
+ };
196
+ readonly 'fl-oz': {
197
+ readonly dimension: "volume";
198
+ readonly systems: readonly ["us"];
199
+ readonly toBase: number;
200
+ readonly aliases: readonly ["fl oz", "fluid ounce", "fluid ounces"];
201
+ readonly labels: {
202
+ readonly short: Label;
203
+ readonly long: Label;
204
+ };
205
+ };
206
+ readonly cup: {
207
+ readonly dimension: "volume";
208
+ readonly systems: readonly ["us"];
209
+ readonly toBase: number;
210
+ readonly aliases: readonly ["cups", "c"];
211
+ readonly labels: {
212
+ readonly short: Label;
213
+ readonly long: Label;
214
+ };
215
+ };
216
+ readonly pint: {
217
+ readonly dimension: "volume";
218
+ readonly systems: readonly ["us"];
219
+ readonly toBase: number;
220
+ readonly aliases: readonly ["pt", "pts", "pints"];
221
+ readonly labels: {
222
+ readonly short: Label;
223
+ readonly long: Label;
224
+ };
225
+ };
226
+ readonly quart: {
227
+ readonly dimension: "volume";
228
+ readonly systems: readonly ["us"];
229
+ readonly toBase: number;
230
+ readonly aliases: readonly ["qt", "qts", "quarts"];
231
+ readonly labels: {
232
+ readonly short: Label;
233
+ readonly long: Label;
234
+ };
235
+ };
236
+ readonly gallon: {
237
+ readonly dimension: "volume";
238
+ readonly systems: readonly ["us"];
239
+ readonly toBase: number;
240
+ readonly aliases: readonly ["gal", "gals", "gallons"];
241
+ readonly labels: {
242
+ readonly short: Label;
243
+ readonly long: Label;
244
+ };
245
+ };
246
+ readonly pinch: {
247
+ dimension: "count";
248
+ systems: readonly ["metric", "us"];
249
+ aliases: readonly ["pinches"];
250
+ labels: {
251
+ short: Label;
252
+ long: Label;
253
+ };
254
+ };
255
+ readonly dash: {
256
+ dimension: "count";
257
+ systems: readonly ["metric", "us"];
258
+ aliases: readonly ["dashes"];
259
+ labels: {
260
+ short: Label;
261
+ long: Label;
262
+ };
263
+ };
264
+ readonly clove: {
265
+ dimension: "count";
266
+ systems: readonly ["metric", "us"];
267
+ aliases: readonly ["cloves"];
268
+ labels: {
269
+ short: Label;
270
+ long: Label;
271
+ };
272
+ };
273
+ readonly slice: {
274
+ dimension: "count";
275
+ systems: readonly ["metric", "us"];
276
+ aliases: readonly ["slices"];
277
+ labels: {
278
+ short: Label;
279
+ long: Label;
280
+ };
281
+ };
282
+ readonly piece: {
283
+ dimension: "count";
284
+ systems: readonly ["metric", "us"];
285
+ aliases: readonly ["pieces", "pc", "pcs"];
286
+ labels: {
287
+ short: Label;
288
+ long: Label;
289
+ };
290
+ };
291
+ readonly can: {
292
+ dimension: "count";
293
+ systems: readonly ["metric", "us"];
294
+ aliases: readonly ["cans"];
295
+ labels: {
296
+ short: Label;
297
+ long: Label;
298
+ };
299
+ };
300
+ readonly package: {
301
+ dimension: "count";
302
+ systems: readonly ["metric", "us"];
303
+ aliases: readonly ["packages", "pkg", "pkgs"];
304
+ labels: {
305
+ short: Label;
306
+ long: Label;
307
+ };
308
+ };
309
+ readonly stick: {
310
+ dimension: "count";
311
+ systems: readonly ["metric", "us"];
312
+ aliases: readonly ["sticks"];
313
+ labels: {
314
+ short: Label;
315
+ long: Label;
316
+ };
317
+ };
318
+ readonly sprig: {
319
+ dimension: "count";
320
+ systems: readonly ["metric", "us"];
321
+ aliases: readonly ["sprigs"];
322
+ labels: {
323
+ short: Label;
324
+ long: Label;
325
+ };
326
+ };
327
+ readonly bunch: {
328
+ dimension: "count";
329
+ systems: readonly ["metric", "us"];
330
+ aliases: readonly ["bunches"];
331
+ labels: {
332
+ short: Label;
333
+ long: Label;
334
+ };
335
+ };
336
+ readonly head: {
337
+ dimension: "count";
338
+ systems: readonly ["metric", "us"];
339
+ aliases: readonly ["heads"];
340
+ labels: {
341
+ short: Label;
342
+ long: Label;
343
+ };
344
+ };
345
+ };
346
+ type Definitions = ReturnType<typeof definitions>;
347
+ /**
348
+ * A unit id, such as `'g'`, `'ml'`, `'cup'`, or `'fl-oz'`. Quantities always
349
+ * store ids; use {@link findUnit} to turn author text into one. May grow in minor releases.
350
+ */
351
+ type UnitId = keyof Definitions;
352
+ type AliasOf<Id extends UnitId> = Id | Definitions[Id]['aliases'][number];
353
+ /**
354
+ * A spelling of a unit in the registry, such as `'cups'`, `'T'`, or `'litre'`.
355
+ * {@link findUnit} also accepts it in any case (except `'T'`, `'t'`, and
356
+ * `'c'`) and with a trailing period.
357
+ */
358
+ type UnitAlias = {
359
+ [Id in UnitId]: AliasOf<Id>;
360
+ }[UnitId];
361
+ /** The id of the unit an alias names: `UnitIdOf<'tablespoons'>` is `'tbsp'`. */
362
+ type UnitIdOf<Alias extends UnitAlias> = {
363
+ [Id in UnitId]: Alias extends AliasOf<Id> ? Id : never;
364
+ }[UnitId];
365
+ /** One entry in the {@link units} registry. */
366
+ type UnitDefinition = {
367
+ readonly id: UnitId;
368
+ readonly dimension: Dimension;
369
+ /** Systems where the unit is native. tsp, tbsp, and count units are native to both. */
370
+ readonly systems: readonly System[];
371
+ /** Exact size in grams (mass) or millilitres (volume). Absent for count units. */
372
+ readonly toBase?: number;
373
+ /**
374
+ * Every accepted spelling, starting with the id. Matched case-insensitively,
375
+ * except `'T'` (tbsp), `'t'` (tsp), and `'c'` (cup).
376
+ */
377
+ readonly aliases: readonly UnitAlias[];
378
+ /** English labels for one and for many, in short (`'tbsp'`) and long (`'tablespoon'`) form. */
379
+ readonly labels: {
380
+ readonly short: Readonly<Label>;
381
+ readonly long: Readonly<Label>;
382
+ };
383
+ };
384
+ type Registry = {
385
+ readonly [Id in UnitId]: UnitDefinition & {
386
+ readonly id: Id;
387
+ };
388
+ };
389
+ /**
390
+ * The read-only unit registry, keyed by id. Volume and mass units carry exact
391
+ * factors to millilitres and grams.
392
+ *
393
+ * @example
394
+ * units.cup.toBase // 236.5882365
395
+ * Object.values(units).filter((unit) => unit.dimension === 'mass')
396
+ */
397
+ declare const units: Registry;
398
+
399
+ /**
400
+ * An inclusive range, such as 2–3 tbsp. Both ends are finite and greater
401
+ * than 0, and `min < max`, though `convert`, `toSystem`, and
402
+ * `scaleQuantity` can return equal ends for a range whose ends differ only
403
+ * in their last digit.
404
+ */
405
+ type Range = {
406
+ min: number;
407
+ max: number;
408
+ };
409
+ /** A finite number greater than 0, or a {@link Range}. */
410
+ type Amount = number | Range;
411
+ /**
412
+ * An amount with an optional unit id. No unit means a bare count, as in "2 eggs".
413
+ *
414
+ * @example
415
+ * const flour: Quantity = { amount: 1.5, unit: 'cup' }
416
+ * const oil: Quantity = { amount: { min: 2, max: 3 }, unit: 'tbsp' }
417
+ * const eggs: Quantity = { amount: 2 }
418
+ */
419
+ type Quantity = {
420
+ amount: Amount;
421
+ unit?: UnitId | undefined;
422
+ /** Always left out or `undefined`; the quantity functions throw otherwise. A quantity range is `amount: { min, max }`. A `Servings` or `Yield` writes `{ amount, max }`, so it isn't a quantity. */
423
+ max?: undefined;
424
+ };
425
+
426
+ /**
427
+ * A normalized ingredient. Absent `quantity` means unquantified, as in "salt, to taste".
428
+ *
429
+ * @example
430
+ * const flour: Ingredient = {
431
+ * id: 'all-purpose-flour',
432
+ * name: 'all-purpose flour',
433
+ * quantity: { amount: 1.5, unit: 'cup' },
434
+ * equivalents: [{ amount: 190, unit: 'g' }],
435
+ * optional: false,
436
+ * }
437
+ */
438
+ type Ingredient = {
439
+ /** Authored, or derived from the name and de-duplicated: `'egg'`, `'egg-2'`. */
440
+ id: string;
441
+ /** Singular, or as written. */
442
+ name: string;
443
+ /**
444
+ * Used after a bare count above 1, a decimal, or a range: "2 eggs", "1–2
445
+ * eggs". 1 and fractions below 1 keep `name`: "1 egg", "½ egg".
446
+ */
447
+ plural?: string | undefined;
448
+ quantity?: Quantity | undefined;
449
+ /** Author-verified alternatives to `quantity`, in preference order. */
450
+ equivalents: Quantity[];
451
+ /** "sifted", "to taste", "melted". */
452
+ note?: string | undefined;
453
+ /** A product page or another recipe. An http or https URL, or a relative one, including protocol-relative `//host/path`. */
454
+ url?: string | undefined;
455
+ optional: boolean;
456
+ };
457
+ /** A group of ingredients, such as "For the frosting". Untitled sections have no `title`. */
458
+ type IngredientSection = {
459
+ id: string;
460
+ title?: string | undefined;
461
+ items: Ingredient[];
462
+ };
463
+ /** One instruction. Display numbers run across sections and aren't stored. */
464
+ type Step = {
465
+ /** Authored, or derived from `name`, else from the step number, and de-duplicated: `'step-1'`, `'mix-2'`. */
466
+ id: string;
467
+ text: string;
468
+ /** A short label, such as "Make the dough". */
469
+ name?: string | undefined;
470
+ /** An http or https URL, or a relative one, including protocol-relative `//host/path`. */
471
+ image?: string | undefined;
472
+ };
473
+ /** A group of steps, such as "Make the frosting". Untitled sections have no `title`. */
474
+ type StepSection = {
475
+ id: string;
476
+ title?: string | undefined;
477
+ items: Step[];
478
+ };
479
+ /**
480
+ * How many people the recipe serves. `max` is the upper end of a range, as in
481
+ * "serves 4–6"; scaling uses `amount`. Print it with `formatServings`.
482
+ *
483
+ * @example
484
+ * const serves4: Servings = { amount: 4 }
485
+ * const serves4to6: Servings = { amount: 4, max: 6 }
486
+ */
487
+ type Servings = {
488
+ amount: number;
489
+ /** Greater than `amount` when present. */
490
+ max?: number | undefined;
491
+ };
492
+ /**
493
+ * What a batch makes, such as 24 cookies or 2 loaves. `max` is the upper end
494
+ * of a range; scaling uses `amount`. Only `amount` and `max` scale, so a
495
+ * number inside `unit`, as in `'24 cookies or 12 bars'`, stays as written.
496
+ * Print it with `formatYield`.
497
+ *
498
+ * @example
499
+ * const cookies: Yield = { amount: 24, unit: 'cookie', plural: 'cookies' }
500
+ * const loaves: Yield = { amount: 2, max: 3, unit: 'loaf', plural: 'loaves' }
501
+ */
502
+ type Yield = {
503
+ amount: number;
504
+ /** Greater than `amount` when present. */
505
+ max?: number | undefined;
506
+ /** Singular, or as written. */
507
+ unit: string;
508
+ /**
509
+ * Used for amounts above 1, decimals, and ranges. 1 and fractions below 1,
510
+ * such as ½, use `unit`.
511
+ */
512
+ plural?: string | undefined;
513
+ };
514
+ /** Durations in minutes. `total` is kept as authored, never computed. */
515
+ type Times = {
516
+ prep?: number | undefined;
517
+ cook?: number | undefined;
518
+ total?: number | undefined;
519
+ /** Other named times, such as chilling or rising. */
520
+ custom: CustomTime[];
521
+ };
522
+ /**
523
+ * A named time, such as chilling or rising, in minutes.
524
+ *
525
+ * @example
526
+ * const chill: CustomTime = { id: 'chill', label: 'Chill', minutes: 120 }
527
+ */
528
+ type CustomTime = {
529
+ /** Authored, or derived from the label and de-duplicated: `'chill'`, `'chill-2'`. */
530
+ id: string;
531
+ label: string;
532
+ minutes: number;
533
+ };
534
+ /**
535
+ * A recipe note, such as a tip or a substitution.
536
+ *
537
+ * @example
538
+ * const note: Note = { id: 'make-ahead', title: 'Make ahead', text: 'The dough keeps for 3 days.' }
539
+ */
540
+ type Note = {
541
+ /** Authored, or derived from the title, falling back to its position, and de-duplicated: `'note-1'`, `'make-ahead-2'`. */
542
+ id: string;
543
+ title?: string | undefined;
544
+ /** Plain text. Renderers show it as text, never as HTML. */
545
+ text: string;
546
+ };
547
+ /**
548
+ * A tool the recipe needs. Equipment never scales with servings.
549
+ *
550
+ * @example
551
+ * const pans: Equipment = {
552
+ * id: 'baking-sheet',
553
+ * name: 'baking sheet',
554
+ * plural: 'baking sheets',
555
+ * quantity: 2,
556
+ * }
557
+ */
558
+ type Equipment = {
559
+ /** Authored, or derived from the name and de-duplicated: `'whisk'`, `'whisk-2'`. */
560
+ id: string;
561
+ name: string;
562
+ /** Used when `quantity` is above 1: "2 baking sheets". */
563
+ plural?: string | undefined;
564
+ /** A whole number, such as `2` for two baking sheets. */
565
+ quantity?: number | undefined;
566
+ /** A product page. An http or https URL, or a relative one, including protocol-relative `//host/path`. */
567
+ url?: string | undefined;
568
+ note?: string | undefined;
569
+ };
570
+ /**
571
+ * Nutrition for one of the recipe's `servings`. It never scales.
572
+ *
573
+ * @example
574
+ * const nutrition: Nutrition = { servingSize: '1 slice', calories: 250, fat: 12, sodium: 300 }
575
+ */
576
+ type Nutrition = {
577
+ /** "1 slice", "100 g". */
578
+ servingSize?: string | undefined;
579
+ /** kcal. */
580
+ calories?: number | undefined;
581
+ /** g. */
582
+ fat?: number | undefined;
583
+ /** g. */
584
+ saturatedFat?: number | undefined;
585
+ /** g. */
586
+ transFat?: number | undefined;
587
+ /** g. */
588
+ unsaturatedFat?: number | undefined;
589
+ /** g. */
590
+ carbohydrates?: number | undefined;
591
+ /** g. */
592
+ sugar?: number | undefined;
593
+ /** g. */
594
+ fiber?: number | undefined;
595
+ /** g. */
596
+ protein?: number | undefined;
597
+ /** mg. */
598
+ sodium?: number | undefined;
599
+ /** mg. */
600
+ cholesterol?: number | undefined;
601
+ };
602
+ /**
603
+ * A normalized recipe, as returned by `parseRecipe`. Plain JSON data: it can be
604
+ * cached, stored, or passed from a Server Component to a Client Component.
605
+ * A `Recipe` whose quantity, servings, and yield amounts are from 1e-300 to
606
+ * 1e290, as in every recipe that `parseRecipe` or `fromJsonLd` returns, is also
607
+ * a valid `RecipeInput`, and parsing it returns an equal recipe.
608
+ */
609
+ type Recipe = {
610
+ id: string;
611
+ name: string;
612
+ description?: string | undefined;
613
+ /** An http or https URL, or a relative one, including protocol-relative `//host/path`. */
614
+ image?: string | undefined;
615
+ servings?: Servings | undefined;
616
+ yield?: Yield | undefined;
617
+ /** The system the recipe was written in, authored or inferred. Absent means system-neutral. */
618
+ system?: System | undefined;
619
+ times: Times;
620
+ ingredients: IngredientSection[];
621
+ steps: StepSection[];
622
+ notes: Note[];
623
+ equipment: Equipment[];
624
+ nutrition?: Nutrition | undefined;
625
+ };
626
+
627
+ export { RecipeBookError as i, RecipeValidationError as m, isRecipeBookError as o, units as u };
628
+ export type { Amount as A, CustomTime as C, Dimension as D, Equipment as E, Ingredient as I, Note as N, ParseResult as P, Quantity as Q, Recipe as R, System as S, Times as T, UnitAlias as U, ValidationErrorCode as V, Yield as Y, Servings as a, Step as b, Range as c, UnitId as d, UnitIdOf as e, UnitDefinition as f, IngredientSection as g, Nutrition as h, RecipeBookErrorCode as j, RecipeIssue as k, RecipeIssueCode as l, StepSection as n };