@tmlmt/cooklang-parser 3.0.0-alpha.11 → 3.0.0-alpha.13

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/dist/index.d.cts CHANGED
@@ -154,7 +154,7 @@ declare class Recipe {
154
154
  * Quantities are grouped by their alternative signature and summed using addEquivalentsAndSimplify.
155
155
  * @internal
156
156
  */
157
- private _populate_ingredient_quantities;
157
+ private _populateIngredientQuantities;
158
158
  /**
159
159
  * Gets ingredients with their quantities populated, optionally filtered by section/step
160
160
  * and respecting user choices for alternatives.
@@ -237,6 +237,42 @@ declare class Recipe {
237
237
  clone(): Recipe;
238
238
  }
239
239
 
240
+ /**
241
+ * Represents source attribution information for a recipe.
242
+ * @category Types
243
+ */
244
+ interface MetadataSource {
245
+ /** The name of the source (e.g., "New York Times Cooking"). */
246
+ name?: string;
247
+ /** The URL of the source recipe. */
248
+ url?: string;
249
+ /** The author at the source. */
250
+ author?: string;
251
+ }
252
+ /**
253
+ * Represents time information for a recipe.
254
+ * @category Types
255
+ */
256
+ interface MetadataTime {
257
+ /** The preparation time (not parsed into DateTime format). */
258
+ prep?: string;
259
+ /** The cooking time (not parsed into DateTime format). */
260
+ cook?: string;
261
+ /** The total time required (not parsed into DateTime format). */
262
+ total?: string;
263
+ }
264
+ /**
265
+ * Represents a nested metadata object with arbitrary keys.
266
+ * @category Types
267
+ */
268
+ interface MetadataObject {
269
+ [key: string]: MetadataValue;
270
+ }
271
+ /**
272
+ * Represents any value that can appear in recipe metadata.
273
+ * @category Types
274
+ */
275
+ type MetadataValue = string | number | (string | number)[] | MetadataObject | MetadataSource | MetadataTime | undefined;
240
276
  /**
241
277
  * Represents the metadata of a recipe.
242
278
  * @category Types
@@ -246,15 +282,12 @@ interface Metadata {
246
282
  title?: string;
247
283
  /** The tags of the recipe. */
248
284
  tags?: string[];
249
- /** The source of the recipe. */
250
- source?: string;
251
- /** The source name of the recipe. */
252
- "source.name"?: string;
253
- /** The source url of the recipe. */
254
- "source.url"?: string;
255
- /** The source author of the recipe. */
256
- "source.author"?: string;
257
- /** The author of the recipe. */
285
+ /**
286
+ * The source of the recipe. Can be a simple URL string or structured attribution.
287
+ * When parsed from YAML, `source.name`, `source.url`, `source.author` keys are merged here.
288
+ */
289
+ source?: string | MetadataSource;
290
+ /** The author of the recipe (separate from source author). */
258
291
  author?: string;
259
292
  /** The number of servings the recipe makes.
260
293
  * Should be either a number or a string which starts with a number
@@ -305,30 +338,11 @@ interface Metadata {
305
338
  /** The locale of the recipe. */
306
339
  locale?: string;
307
340
  /**
308
- * The preparation time of the recipe.
309
- * Will not be further parsed into any DateTime format nor normalize
310
- */
311
- "prep time"?: string;
312
- /**
313
- * Alias of `prep time`
341
+ * Time information for the recipe.
342
+ * When parsed from YAML, `prep time`, `time.prep`, `cook time`, `time.cook`,
343
+ * `time required`, `time`, `duration` keys are merged here.
314
344
  */
315
- "time.prep"?: string;
316
- /**
317
- * The cooking time of the recipe.
318
- * Will not be further parsed into any DateTime format nor normalize
319
- */
320
- "cook time"?: string;
321
- /**
322
- * Alias of `cook time`
323
- */
324
- "time.cook"?: string;
325
- /**
326
- * The total time of the recipe.
327
- * Will not be further parsed into any DateTime format nor normalize
328
- */
329
- "time required"?: string;
330
- time?: string;
331
- duration?: string;
345
+ time?: MetadataTime;
332
346
  /** The difficulty of the recipe. */
333
347
  difficulty?: string;
334
348
  /** The cuisine of the recipe. */
@@ -337,14 +351,10 @@ interface Metadata {
337
351
  diet?: string;
338
352
  /** The description of the recipe. */
339
353
  description?: string;
340
- /** The images of the recipe. Alias of `pictures` */
354
+ /** The images of the recipe. */
341
355
  images?: string[];
342
- /** The images of the recipe. Alias of `images` */
343
- pictures?: string[];
344
- /** The picture of the recipe. Alias of `picture` */
356
+ /** The primary image of the recipe. */
345
357
  image?: string;
346
- /** The picture of the recipe. Alias of `image` */
347
- picture?: string;
348
358
  /** The introduction of the recipe. */
349
359
  introduction?: string;
350
360
  /**
@@ -352,7 +362,12 @@ interface Metadata {
352
362
  * See [Unit Conversion Guide](/guide-unit-conversion) for more information.
353
363
  * This stores the original value as written by the user.
354
364
  */
355
- "unit system"?: string;
365
+ unitSystem?: string;
366
+ /**
367
+ * Index signature for additional metadata fields not explicitly typed.
368
+ * Any metadata key in the frontmatter will be captured here.
369
+ */
370
+ [key: string]: MetadataValue;
356
371
  }
357
372
  /**
358
373
  * Represents a quantity described by text, e.g. "a pinch"
@@ -508,31 +523,27 @@ interface Ingredient {
508
523
  /** The collection of potential additional metadata for the ingredient */
509
524
  extras?: IngredientExtras;
510
525
  }
511
- /**
512
- * Represents a contributor to an ingredient's total quantity, corresponding
513
- * to a single mention in the recipe text. It can contain multiple
514
- * equivalent quantities (e.g., in different units).
515
- * @category Types
516
- */
517
- interface IngredientItemQuantity extends QuantityWithExtendedUnit {
518
- /**
519
- * A list of equivalent quantities/units for this ingredient mention besides the primary quantity.
520
- * For `@salt{1%tsp|5%g}`, the main quantity is 1 tsp and the equivalents will contain 5 g.
521
- */
522
- equivalents?: QuantityWithExtendedUnit[];
526
+ type MaybeScalableQuantity = QuantityWithExtendedUnit & {
523
527
  /** Indicates whether this quantity should be scaled when the recipe serving size changes. */
524
528
  scalable: boolean;
525
- }
529
+ /** A list of equivalent quantities/units for this ingredient mention besides the primary quantity.
530
+ * For `@salt{1%tsp|5%g}`, the main quantity is 1 tsp and the equivalents will contain 5 g. */
531
+ equivalents?: QuantityWithExtendedUnit[];
532
+ };
533
+ type WithOptionalQuantity<T> = (T & MaybeScalableQuantity) | (T & {
534
+ quantity?: undefined;
535
+ scalable?: never;
536
+ unit?: never;
537
+ equivalents?: never;
538
+ });
526
539
  /**
527
540
  * Represents a single ingredient choice within a single or a group of `IngredientItem`s. It points
528
541
  * to a specific ingredient and its corresponding quantity information.
529
542
  * @category Types
530
543
  */
531
- interface IngredientAlternative {
544
+ type IngredientAlternativeBase = {
532
545
  /** The index of the ingredient within the {@link Recipe.ingredients} array. */
533
546
  index: number;
534
- /** The quantity of this specific mention of the ingredient */
535
- itemQuantity?: IngredientItemQuantity;
536
547
  /** The alias/name of the ingredient as it should be displayed for this occurrence. */
537
548
  displayName: string;
538
549
  /** An optional note for this specific choice (e.g., "for a vegan version"). */
@@ -541,7 +552,8 @@ interface IngredientAlternative {
541
552
  * with group keys: the id of the corresponding ingredient item (e.g. "ingredient-item-2").
542
553
  * Can be useful for creating alternative selection UI elements with anchor links */
543
554
  itemId?: string;
544
- }
555
+ };
556
+ type IngredientAlternative = WithOptionalQuantity<IngredientAlternativeBase>;
545
557
  /**
546
558
  * Represents an ingredient item in a recipe step.
547
559
  * @category Types
@@ -1160,7 +1172,7 @@ declare class ProductCatalog {
1160
1172
  * ## Usage
1161
1173
  *
1162
1174
  * - Create a new ShoppingList instance with an optional category configuration (see {@link ShoppingList."constructor" | constructor})
1163
- * - Add recipes, scaling them as needed (see {@link ShoppingList.add_recipe | add_recipe()})
1175
+ * - Add recipes, scaling them as needed (see {@link ShoppingList.addRecipe | addRecipe()})
1164
1176
  * - Categorize the ingredients (see {@link ShoppingList.categorize | categorize()})
1165
1177
  *
1166
1178
  * @example
@@ -1172,10 +1184,10 @@ declare class ProductCatalog {
1172
1184
  * const categoryConfig = fs.readFileSync("./myconfig.txt", "utf-8")
1173
1185
  * const recipe1 = new Recipe(fs.readFileSync("./myrecipe.cook", "utf-8"));
1174
1186
  * const shoppingList = new ShoppingList();
1175
- * shoppingList.set_category_config(categoryConfig);
1187
+ * shoppingList.setCategoryConfig(categoryConfig);
1176
1188
  * // Quantities are automatically calculated and ingredients categorized
1177
1189
  * // when adding a recipe
1178
- * shoppingList.add_recipe(recipe1);
1190
+ * shoppingList.addRecipe(recipe1);
1179
1191
  * ```
1180
1192
  *
1181
1193
  * @category Classes
@@ -1192,17 +1204,17 @@ declare class ShoppingList {
1192
1204
  /**
1193
1205
  * The category configuration for the shopping list.
1194
1206
  */
1195
- category_config?: CategoryConfig;
1207
+ categoryConfig?: CategoryConfig;
1196
1208
  /**
1197
1209
  * The categorized ingredients in the shopping list.
1198
1210
  */
1199
1211
  categories?: CategorizedIngredients;
1200
1212
  /**
1201
1213
  * Creates a new ShoppingList instance
1202
- * @param category_config_str - The category configuration to parse.
1214
+ * @param categoryConfigStr - The category configuration to parse.
1203
1215
  */
1204
- constructor(category_config_str?: string | CategoryConfig);
1205
- private calculate_ingredients;
1216
+ constructor(categoryConfigStr?: string | CategoryConfig);
1217
+ private calculateIngredients;
1206
1218
  /**
1207
1219
  * Adds a recipe to the shopping list, then automatically
1208
1220
  * recalculates the quantities and recategorize the ingredients.
@@ -1210,7 +1222,7 @@ declare class ShoppingList {
1210
1222
  * @param options - Options for adding the recipe.
1211
1223
  * @throws Error if the recipe has alternatives without corresponding choices.
1212
1224
  */
1213
- add_recipe(recipe: Recipe, options?: AddedRecipeOptions): void;
1225
+ addRecipe(recipe: Recipe, options?: AddedRecipeOptions): void;
1214
1226
  /**
1215
1227
  * Checks if a recipe has unresolved alternatives (alternatives without provided choices).
1216
1228
  * @param recipe - The recipe to check.
@@ -1220,16 +1232,16 @@ declare class ShoppingList {
1220
1232
  private getUnresolvedAlternativesError;
1221
1233
  /**
1222
1234
  * Removes a recipe from the shopping list, then automatically
1223
- * recalculates the quantities and recategorize the ingredients.s
1235
+ * recalculates the quantities and recategorize the ingredients.
1224
1236
  * @param index - The index of the recipe to remove.
1225
1237
  */
1226
- remove_recipe(index: number): void;
1238
+ removeRecipe(index: number): void;
1227
1239
  /**
1228
1240
  * Sets the category configuration for the shopping list
1229
1241
  * and automatically categorize current ingredients from the list.
1230
1242
  * @param config - The category configuration to parse.
1231
1243
  */
1232
- set_category_config(config: string | CategoryConfig): void;
1244
+ setCategoryConfig(config: string | CategoryConfig): void;
1233
1245
  /**
1234
1246
  * Categorizes the ingredients in the shopping list
1235
1247
  * Will use the category config if any, otherwise all ingredients will be placed in the "other" category
@@ -1272,7 +1284,7 @@ interface ShoppingCartSummary {
1272
1284
  * ```ts
1273
1285
  * const shoppingList = new ShoppingList();
1274
1286
  * const recipe = new Recipe("@flour{600%g}");
1275
- * shoppingList.add_recipe(recipe);
1287
+ * shoppingList.addRecipe(recipe);
1276
1288
  *
1277
1289
  * const catalog = new ProductCatalog();
1278
1290
  * catalog.products = [
@@ -1500,7 +1512,7 @@ declare function formatExtendedQuantity(item: QuantityWithExtendedUnit): string;
1500
1512
  * formatItemQuantity(itemQuantity, " / "); // "100 g / 3.5 oz"
1501
1513
  * ```
1502
1514
  */
1503
- declare function formatItemQuantity(itemQuantity: IngredientItemQuantity, separator?: string): string;
1515
+ declare function formatItemQuantity(itemQuantity: MaybeScalableQuantity, separator?: string): string;
1504
1516
  /**
1505
1517
  * Check if an ingredient item is a grouped alternative (vs inline alternative).
1506
1518
  *
@@ -1642,4 +1654,4 @@ declare class NoShoppingListForCartError extends Error {
1642
1654
  constructor();
1643
1655
  }
1644
1656
 
1645
- export { type AddedIngredient, type AddedRecipe, type AddedRecipeOptions, type AlternativeIngredientRef, type AndGroup, type ArbitraryScalable, type ArbitraryScalableItem, type CartContent, type CartMatch, type CartMisMatch, type CategorizedIngredients, type Category, CategoryConfig, type CategoryIngredient, type Cookware, type CookwareFlag, type CookwareItem, type DecimalValue, type FixedNumericValue, type FixedValue, type FlatAndGroup, type FlatGroup, type FlatOrGroup, type FractionValue, type GetIngredientQuantitiesOptions, type Group, type Ingredient, type IngredientAlternative, type IngredientExtras, type IngredientFlag, type IngredientItem, type IngredientItemQuantity, type IngredientQuantityAndGroup, type IngredientQuantityGroup, type MaybeNestedAndGroup, type MaybeNestedGroup, type MaybeNestedOrGroup, type Metadata, NoProductCatalogForCartError, type NoProductMatchErrorCode, NoShoppingListForCartError, type Note, type NoteItem, type OrGroup, ProductCatalog, type ProductMatch, type ProductMisMatch, type ProductOption, type ProductOptionBase, type ProductOptionCore, type ProductSelection, type ProductSize, type QuantityBase, type QuantityWithExtendedUnit, type QuantityWithPlainUnit, type QuantityWithUnitDef, type QuantityWithUnitLike, type Range, Recipe, type RecipeAlternatives, type RecipeChoices, type RecipeWithFactor, type RecipeWithServings, Section, ShoppingCart, type ShoppingCartOptions, type ShoppingCartSummary, ShoppingList, type SpecificUnitSystem, type Step, type StepItem, type TextItem, type TextValue, type Timer, type TimerItem, type ToBaseBySystem, type Unit, type UnitDefinition, type UnitDefinitionLike, type UnitSystem, type UnitType, convertQuantityToSystem, formatExtendedQuantity, formatItemQuantity, formatNumericValue, formatQuantity, formatQuantityWithUnit, formatSingleValue, formatUnit, hasAlternatives, isAlternativeSelected, isAndGroup, isGroupedItem, isSimpleGroup, renderFractionAsVulgar };
1657
+ export { type AddedIngredient, type AddedRecipe, type AddedRecipeOptions, type AlternativeIngredientRef, type AndGroup, type ArbitraryScalable, type ArbitraryScalableItem, type CartContent, type CartMatch, type CartMisMatch, type CategorizedIngredients, type Category, CategoryConfig, type CategoryIngredient, type Cookware, type CookwareFlag, type CookwareItem, type DecimalValue, type FixedNumericValue, type FixedValue, type FlatAndGroup, type FlatGroup, type FlatOrGroup, type FractionValue, type GetIngredientQuantitiesOptions, type Group, type Ingredient, type IngredientAlternative, type IngredientExtras, type IngredientFlag, type IngredientItem, type IngredientQuantityAndGroup, type IngredientQuantityGroup, type MaybeNestedAndGroup, type MaybeNestedGroup, type MaybeNestedOrGroup, type MaybeScalableQuantity, type Metadata, type MetadataObject, type MetadataSource, type MetadataTime, type MetadataValue, NoProductCatalogForCartError, type NoProductMatchErrorCode, NoShoppingListForCartError, type Note, type NoteItem, type OrGroup, ProductCatalog, type ProductMatch, type ProductMisMatch, type ProductOption, type ProductOptionBase, type ProductOptionCore, type ProductSelection, type ProductSize, type QuantityBase, type QuantityWithExtendedUnit, type QuantityWithPlainUnit, type QuantityWithUnitDef, type QuantityWithUnitLike, type Range, Recipe, type RecipeAlternatives, type RecipeChoices, type RecipeWithFactor, type RecipeWithServings, Section, ShoppingCart, type ShoppingCartOptions, type ShoppingCartSummary, ShoppingList, type SpecificUnitSystem, type Step, type StepItem, type TextItem, type TextValue, type Timer, type TimerItem, type ToBaseBySystem, type Unit, type UnitDefinition, type UnitDefinitionLike, type UnitSystem, type UnitType, convertQuantityToSystem, formatExtendedQuantity, formatItemQuantity, formatNumericValue, formatQuantity, formatQuantityWithUnit, formatSingleValue, formatUnit, hasAlternatives, isAlternativeSelected, isAndGroup, isGroupedItem, isSimpleGroup, renderFractionAsVulgar };
package/dist/index.d.ts CHANGED
@@ -154,7 +154,7 @@ declare class Recipe {
154
154
  * Quantities are grouped by their alternative signature and summed using addEquivalentsAndSimplify.
155
155
  * @internal
156
156
  */
157
- private _populate_ingredient_quantities;
157
+ private _populateIngredientQuantities;
158
158
  /**
159
159
  * Gets ingredients with their quantities populated, optionally filtered by section/step
160
160
  * and respecting user choices for alternatives.
@@ -237,6 +237,42 @@ declare class Recipe {
237
237
  clone(): Recipe;
238
238
  }
239
239
 
240
+ /**
241
+ * Represents source attribution information for a recipe.
242
+ * @category Types
243
+ */
244
+ interface MetadataSource {
245
+ /** The name of the source (e.g., "New York Times Cooking"). */
246
+ name?: string;
247
+ /** The URL of the source recipe. */
248
+ url?: string;
249
+ /** The author at the source. */
250
+ author?: string;
251
+ }
252
+ /**
253
+ * Represents time information for a recipe.
254
+ * @category Types
255
+ */
256
+ interface MetadataTime {
257
+ /** The preparation time (not parsed into DateTime format). */
258
+ prep?: string;
259
+ /** The cooking time (not parsed into DateTime format). */
260
+ cook?: string;
261
+ /** The total time required (not parsed into DateTime format). */
262
+ total?: string;
263
+ }
264
+ /**
265
+ * Represents a nested metadata object with arbitrary keys.
266
+ * @category Types
267
+ */
268
+ interface MetadataObject {
269
+ [key: string]: MetadataValue;
270
+ }
271
+ /**
272
+ * Represents any value that can appear in recipe metadata.
273
+ * @category Types
274
+ */
275
+ type MetadataValue = string | number | (string | number)[] | MetadataObject | MetadataSource | MetadataTime | undefined;
240
276
  /**
241
277
  * Represents the metadata of a recipe.
242
278
  * @category Types
@@ -246,15 +282,12 @@ interface Metadata {
246
282
  title?: string;
247
283
  /** The tags of the recipe. */
248
284
  tags?: string[];
249
- /** The source of the recipe. */
250
- source?: string;
251
- /** The source name of the recipe. */
252
- "source.name"?: string;
253
- /** The source url of the recipe. */
254
- "source.url"?: string;
255
- /** The source author of the recipe. */
256
- "source.author"?: string;
257
- /** The author of the recipe. */
285
+ /**
286
+ * The source of the recipe. Can be a simple URL string or structured attribution.
287
+ * When parsed from YAML, `source.name`, `source.url`, `source.author` keys are merged here.
288
+ */
289
+ source?: string | MetadataSource;
290
+ /** The author of the recipe (separate from source author). */
258
291
  author?: string;
259
292
  /** The number of servings the recipe makes.
260
293
  * Should be either a number or a string which starts with a number
@@ -305,30 +338,11 @@ interface Metadata {
305
338
  /** The locale of the recipe. */
306
339
  locale?: string;
307
340
  /**
308
- * The preparation time of the recipe.
309
- * Will not be further parsed into any DateTime format nor normalize
310
- */
311
- "prep time"?: string;
312
- /**
313
- * Alias of `prep time`
341
+ * Time information for the recipe.
342
+ * When parsed from YAML, `prep time`, `time.prep`, `cook time`, `time.cook`,
343
+ * `time required`, `time`, `duration` keys are merged here.
314
344
  */
315
- "time.prep"?: string;
316
- /**
317
- * The cooking time of the recipe.
318
- * Will not be further parsed into any DateTime format nor normalize
319
- */
320
- "cook time"?: string;
321
- /**
322
- * Alias of `cook time`
323
- */
324
- "time.cook"?: string;
325
- /**
326
- * The total time of the recipe.
327
- * Will not be further parsed into any DateTime format nor normalize
328
- */
329
- "time required"?: string;
330
- time?: string;
331
- duration?: string;
345
+ time?: MetadataTime;
332
346
  /** The difficulty of the recipe. */
333
347
  difficulty?: string;
334
348
  /** The cuisine of the recipe. */
@@ -337,14 +351,10 @@ interface Metadata {
337
351
  diet?: string;
338
352
  /** The description of the recipe. */
339
353
  description?: string;
340
- /** The images of the recipe. Alias of `pictures` */
354
+ /** The images of the recipe. */
341
355
  images?: string[];
342
- /** The images of the recipe. Alias of `images` */
343
- pictures?: string[];
344
- /** The picture of the recipe. Alias of `picture` */
356
+ /** The primary image of the recipe. */
345
357
  image?: string;
346
- /** The picture of the recipe. Alias of `image` */
347
- picture?: string;
348
358
  /** The introduction of the recipe. */
349
359
  introduction?: string;
350
360
  /**
@@ -352,7 +362,12 @@ interface Metadata {
352
362
  * See [Unit Conversion Guide](/guide-unit-conversion) for more information.
353
363
  * This stores the original value as written by the user.
354
364
  */
355
- "unit system"?: string;
365
+ unitSystem?: string;
366
+ /**
367
+ * Index signature for additional metadata fields not explicitly typed.
368
+ * Any metadata key in the frontmatter will be captured here.
369
+ */
370
+ [key: string]: MetadataValue;
356
371
  }
357
372
  /**
358
373
  * Represents a quantity described by text, e.g. "a pinch"
@@ -508,31 +523,27 @@ interface Ingredient {
508
523
  /** The collection of potential additional metadata for the ingredient */
509
524
  extras?: IngredientExtras;
510
525
  }
511
- /**
512
- * Represents a contributor to an ingredient's total quantity, corresponding
513
- * to a single mention in the recipe text. It can contain multiple
514
- * equivalent quantities (e.g., in different units).
515
- * @category Types
516
- */
517
- interface IngredientItemQuantity extends QuantityWithExtendedUnit {
518
- /**
519
- * A list of equivalent quantities/units for this ingredient mention besides the primary quantity.
520
- * For `@salt{1%tsp|5%g}`, the main quantity is 1 tsp and the equivalents will contain 5 g.
521
- */
522
- equivalents?: QuantityWithExtendedUnit[];
526
+ type MaybeScalableQuantity = QuantityWithExtendedUnit & {
523
527
  /** Indicates whether this quantity should be scaled when the recipe serving size changes. */
524
528
  scalable: boolean;
525
- }
529
+ /** A list of equivalent quantities/units for this ingredient mention besides the primary quantity.
530
+ * For `@salt{1%tsp|5%g}`, the main quantity is 1 tsp and the equivalents will contain 5 g. */
531
+ equivalents?: QuantityWithExtendedUnit[];
532
+ };
533
+ type WithOptionalQuantity<T> = (T & MaybeScalableQuantity) | (T & {
534
+ quantity?: undefined;
535
+ scalable?: never;
536
+ unit?: never;
537
+ equivalents?: never;
538
+ });
526
539
  /**
527
540
  * Represents a single ingredient choice within a single or a group of `IngredientItem`s. It points
528
541
  * to a specific ingredient and its corresponding quantity information.
529
542
  * @category Types
530
543
  */
531
- interface IngredientAlternative {
544
+ type IngredientAlternativeBase = {
532
545
  /** The index of the ingredient within the {@link Recipe.ingredients} array. */
533
546
  index: number;
534
- /** The quantity of this specific mention of the ingredient */
535
- itemQuantity?: IngredientItemQuantity;
536
547
  /** The alias/name of the ingredient as it should be displayed for this occurrence. */
537
548
  displayName: string;
538
549
  /** An optional note for this specific choice (e.g., "for a vegan version"). */
@@ -541,7 +552,8 @@ interface IngredientAlternative {
541
552
  * with group keys: the id of the corresponding ingredient item (e.g. "ingredient-item-2").
542
553
  * Can be useful for creating alternative selection UI elements with anchor links */
543
554
  itemId?: string;
544
- }
555
+ };
556
+ type IngredientAlternative = WithOptionalQuantity<IngredientAlternativeBase>;
545
557
  /**
546
558
  * Represents an ingredient item in a recipe step.
547
559
  * @category Types
@@ -1160,7 +1172,7 @@ declare class ProductCatalog {
1160
1172
  * ## Usage
1161
1173
  *
1162
1174
  * - Create a new ShoppingList instance with an optional category configuration (see {@link ShoppingList."constructor" | constructor})
1163
- * - Add recipes, scaling them as needed (see {@link ShoppingList.add_recipe | add_recipe()})
1175
+ * - Add recipes, scaling them as needed (see {@link ShoppingList.addRecipe | addRecipe()})
1164
1176
  * - Categorize the ingredients (see {@link ShoppingList.categorize | categorize()})
1165
1177
  *
1166
1178
  * @example
@@ -1172,10 +1184,10 @@ declare class ProductCatalog {
1172
1184
  * const categoryConfig = fs.readFileSync("./myconfig.txt", "utf-8")
1173
1185
  * const recipe1 = new Recipe(fs.readFileSync("./myrecipe.cook", "utf-8"));
1174
1186
  * const shoppingList = new ShoppingList();
1175
- * shoppingList.set_category_config(categoryConfig);
1187
+ * shoppingList.setCategoryConfig(categoryConfig);
1176
1188
  * // Quantities are automatically calculated and ingredients categorized
1177
1189
  * // when adding a recipe
1178
- * shoppingList.add_recipe(recipe1);
1190
+ * shoppingList.addRecipe(recipe1);
1179
1191
  * ```
1180
1192
  *
1181
1193
  * @category Classes
@@ -1192,17 +1204,17 @@ declare class ShoppingList {
1192
1204
  /**
1193
1205
  * The category configuration for the shopping list.
1194
1206
  */
1195
- category_config?: CategoryConfig;
1207
+ categoryConfig?: CategoryConfig;
1196
1208
  /**
1197
1209
  * The categorized ingredients in the shopping list.
1198
1210
  */
1199
1211
  categories?: CategorizedIngredients;
1200
1212
  /**
1201
1213
  * Creates a new ShoppingList instance
1202
- * @param category_config_str - The category configuration to parse.
1214
+ * @param categoryConfigStr - The category configuration to parse.
1203
1215
  */
1204
- constructor(category_config_str?: string | CategoryConfig);
1205
- private calculate_ingredients;
1216
+ constructor(categoryConfigStr?: string | CategoryConfig);
1217
+ private calculateIngredients;
1206
1218
  /**
1207
1219
  * Adds a recipe to the shopping list, then automatically
1208
1220
  * recalculates the quantities and recategorize the ingredients.
@@ -1210,7 +1222,7 @@ declare class ShoppingList {
1210
1222
  * @param options - Options for adding the recipe.
1211
1223
  * @throws Error if the recipe has alternatives without corresponding choices.
1212
1224
  */
1213
- add_recipe(recipe: Recipe, options?: AddedRecipeOptions): void;
1225
+ addRecipe(recipe: Recipe, options?: AddedRecipeOptions): void;
1214
1226
  /**
1215
1227
  * Checks if a recipe has unresolved alternatives (alternatives without provided choices).
1216
1228
  * @param recipe - The recipe to check.
@@ -1220,16 +1232,16 @@ declare class ShoppingList {
1220
1232
  private getUnresolvedAlternativesError;
1221
1233
  /**
1222
1234
  * Removes a recipe from the shopping list, then automatically
1223
- * recalculates the quantities and recategorize the ingredients.s
1235
+ * recalculates the quantities and recategorize the ingredients.
1224
1236
  * @param index - The index of the recipe to remove.
1225
1237
  */
1226
- remove_recipe(index: number): void;
1238
+ removeRecipe(index: number): void;
1227
1239
  /**
1228
1240
  * Sets the category configuration for the shopping list
1229
1241
  * and automatically categorize current ingredients from the list.
1230
1242
  * @param config - The category configuration to parse.
1231
1243
  */
1232
- set_category_config(config: string | CategoryConfig): void;
1244
+ setCategoryConfig(config: string | CategoryConfig): void;
1233
1245
  /**
1234
1246
  * Categorizes the ingredients in the shopping list
1235
1247
  * Will use the category config if any, otherwise all ingredients will be placed in the "other" category
@@ -1272,7 +1284,7 @@ interface ShoppingCartSummary {
1272
1284
  * ```ts
1273
1285
  * const shoppingList = new ShoppingList();
1274
1286
  * const recipe = new Recipe("@flour{600%g}");
1275
- * shoppingList.add_recipe(recipe);
1287
+ * shoppingList.addRecipe(recipe);
1276
1288
  *
1277
1289
  * const catalog = new ProductCatalog();
1278
1290
  * catalog.products = [
@@ -1500,7 +1512,7 @@ declare function formatExtendedQuantity(item: QuantityWithExtendedUnit): string;
1500
1512
  * formatItemQuantity(itemQuantity, " / "); // "100 g / 3.5 oz"
1501
1513
  * ```
1502
1514
  */
1503
- declare function formatItemQuantity(itemQuantity: IngredientItemQuantity, separator?: string): string;
1515
+ declare function formatItemQuantity(itemQuantity: MaybeScalableQuantity, separator?: string): string;
1504
1516
  /**
1505
1517
  * Check if an ingredient item is a grouped alternative (vs inline alternative).
1506
1518
  *
@@ -1642,4 +1654,4 @@ declare class NoShoppingListForCartError extends Error {
1642
1654
  constructor();
1643
1655
  }
1644
1656
 
1645
- export { type AddedIngredient, type AddedRecipe, type AddedRecipeOptions, type AlternativeIngredientRef, type AndGroup, type ArbitraryScalable, type ArbitraryScalableItem, type CartContent, type CartMatch, type CartMisMatch, type CategorizedIngredients, type Category, CategoryConfig, type CategoryIngredient, type Cookware, type CookwareFlag, type CookwareItem, type DecimalValue, type FixedNumericValue, type FixedValue, type FlatAndGroup, type FlatGroup, type FlatOrGroup, type FractionValue, type GetIngredientQuantitiesOptions, type Group, type Ingredient, type IngredientAlternative, type IngredientExtras, type IngredientFlag, type IngredientItem, type IngredientItemQuantity, type IngredientQuantityAndGroup, type IngredientQuantityGroup, type MaybeNestedAndGroup, type MaybeNestedGroup, type MaybeNestedOrGroup, type Metadata, NoProductCatalogForCartError, type NoProductMatchErrorCode, NoShoppingListForCartError, type Note, type NoteItem, type OrGroup, ProductCatalog, type ProductMatch, type ProductMisMatch, type ProductOption, type ProductOptionBase, type ProductOptionCore, type ProductSelection, type ProductSize, type QuantityBase, type QuantityWithExtendedUnit, type QuantityWithPlainUnit, type QuantityWithUnitDef, type QuantityWithUnitLike, type Range, Recipe, type RecipeAlternatives, type RecipeChoices, type RecipeWithFactor, type RecipeWithServings, Section, ShoppingCart, type ShoppingCartOptions, type ShoppingCartSummary, ShoppingList, type SpecificUnitSystem, type Step, type StepItem, type TextItem, type TextValue, type Timer, type TimerItem, type ToBaseBySystem, type Unit, type UnitDefinition, type UnitDefinitionLike, type UnitSystem, type UnitType, convertQuantityToSystem, formatExtendedQuantity, formatItemQuantity, formatNumericValue, formatQuantity, formatQuantityWithUnit, formatSingleValue, formatUnit, hasAlternatives, isAlternativeSelected, isAndGroup, isGroupedItem, isSimpleGroup, renderFractionAsVulgar };
1657
+ export { type AddedIngredient, type AddedRecipe, type AddedRecipeOptions, type AlternativeIngredientRef, type AndGroup, type ArbitraryScalable, type ArbitraryScalableItem, type CartContent, type CartMatch, type CartMisMatch, type CategorizedIngredients, type Category, CategoryConfig, type CategoryIngredient, type Cookware, type CookwareFlag, type CookwareItem, type DecimalValue, type FixedNumericValue, type FixedValue, type FlatAndGroup, type FlatGroup, type FlatOrGroup, type FractionValue, type GetIngredientQuantitiesOptions, type Group, type Ingredient, type IngredientAlternative, type IngredientExtras, type IngredientFlag, type IngredientItem, type IngredientQuantityAndGroup, type IngredientQuantityGroup, type MaybeNestedAndGroup, type MaybeNestedGroup, type MaybeNestedOrGroup, type MaybeScalableQuantity, type Metadata, type MetadataObject, type MetadataSource, type MetadataTime, type MetadataValue, NoProductCatalogForCartError, type NoProductMatchErrorCode, NoShoppingListForCartError, type Note, type NoteItem, type OrGroup, ProductCatalog, type ProductMatch, type ProductMisMatch, type ProductOption, type ProductOptionBase, type ProductOptionCore, type ProductSelection, type ProductSize, type QuantityBase, type QuantityWithExtendedUnit, type QuantityWithPlainUnit, type QuantityWithUnitDef, type QuantityWithUnitLike, type Range, Recipe, type RecipeAlternatives, type RecipeChoices, type RecipeWithFactor, type RecipeWithServings, Section, ShoppingCart, type ShoppingCartOptions, type ShoppingCartSummary, ShoppingList, type SpecificUnitSystem, type Step, type StepItem, type TextItem, type TextValue, type Timer, type TimerItem, type ToBaseBySystem, type Unit, type UnitDefinition, type UnitDefinitionLike, type UnitSystem, type UnitType, convertQuantityToSystem, formatExtendedQuantity, formatItemQuantity, formatNumericValue, formatQuantity, formatQuantityWithUnit, formatSingleValue, formatUnit, hasAlternatives, isAlternativeSelected, isAndGroup, isGroupedItem, isSimpleGroup, renderFractionAsVulgar };