@tmlmt/cooklang-parser 3.0.0-alpha.8 → 3.0.0-alpha.9

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
@@ -66,8 +66,7 @@ declare class Recipe {
66
66
  */
67
67
  metadata: Metadata;
68
68
  /**
69
- * The default or manual choice of alternative ingredients.
70
- * Contains the full context including alternatives list and active selection index.
69
+ * The possible choices of alternative ingredients for this recipe.
71
70
  */
72
71
  choices: RecipeAlternatives;
73
72
  /**
@@ -145,14 +144,33 @@ declare class Recipe {
145
144
  */
146
145
  private _populate_ingredient_quantities;
147
146
  /**
148
- * Calculates ingredient quantities based on the provided choices.
149
- * Returns a list of computed ingredients with their total quantities.
147
+ * Gets ingredients with their quantities populated, optionally filtered by section/step
148
+ * and respecting user choices for alternatives.
150
149
  *
151
- * @param choices - The recipe choices to apply when computing quantities.
152
- * If not provided, uses the default choices (first alternative for each item).
153
- * @returns An array of ComputedIngredient with quantityTotal calculated based on choices.
150
+ * When no options are provided, returns all recipe ingredients with quantities
151
+ * calculated using primary alternatives (same as after parsing).
152
+ *
153
+ * @param options - Options for filtering and choice selection:
154
+ * - `section`: Filter to a specific section (Section object or 0-based index)
155
+ * - `step`: Filter to a specific step (Step object or 0-based index)
156
+ * - `choices`: Choices for alternative ingredients (defaults to primary)
157
+ * @returns Array of Ingredient objects with quantities populated
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * // Get all ingredients with primary alternatives
162
+ * const ingredients = recipe.getIngredientQuantities();
163
+ *
164
+ * // Get ingredients for a specific section
165
+ * const sectionIngredients = recipe.getIngredientQuantities({ section: 0 });
166
+ *
167
+ * // Get ingredients with specific choices applied
168
+ * const withChoices = recipe.getIngredientQuantities({
169
+ * choices: { ingredientItems: new Map([['ingredient-item-2', 1]]) }
170
+ * });
171
+ * ```
154
172
  */
155
- calc_ingredient_quantities(choices?: RecipeChoices): ComputedIngredient[];
173
+ getIngredientQuantities(options?: GetIngredientQuantitiesOptions): Ingredient[];
156
174
  /**
157
175
  * Parses a recipe from a string.
158
176
  * @param content - The recipe content to parse.
@@ -409,11 +427,10 @@ interface IngredientQuantityGroup extends QuantityWithPlainUnit {
409
427
  * @category Types
410
428
  */
411
429
  interface IngredientQuantityAndGroup {
412
- type: "and";
413
430
  /**
414
431
  * The incompatible primary quantities (e.g., "1 large" and "2 small").
415
432
  */
416
- entries: QuantityWithPlainUnit[];
433
+ and: QuantityWithPlainUnit[];
417
434
  /**
418
435
  * The summed equivalent quantities (e.g., "5 cups" from summing "1.5 cup + 2 cup + 1.5 cup").
419
436
  */
@@ -558,6 +575,27 @@ interface RecipeChoices {
558
575
  /** Map of choices that can be made for Grouped Ingredient StepItem's */
559
576
  ingredientGroups?: Map<string, number>;
560
577
  }
578
+ /**
579
+ * Options for the {@link Recipe.getIngredientQuantities | getIngredientQuantities()} method.
580
+ * @category Types
581
+ */
582
+ interface GetIngredientQuantitiesOptions {
583
+ /**
584
+ * Filter ingredients to only those appearing in a specific section.
585
+ * Can be a Section object or section index (0-based).
586
+ */
587
+ section?: Section | number;
588
+ /**
589
+ * Filter ingredients to only those appearing in a specific step.
590
+ * Can be a Step object or step index (0-based within the section, or global if no section specified).
591
+ */
592
+ step?: Step | number;
593
+ /**
594
+ * The choices to apply when computing quantities.
595
+ * If not provided, uses primary alternatives (index 0 for all).
596
+ */
597
+ choices?: RecipeChoices;
598
+ }
561
599
  /**
562
600
  * Represents a cookware item in a recipe step.
563
601
  * @category Types
@@ -913,16 +951,14 @@ type QuantityWithUnitLike = QuantityWithPlainUnit | QuantityWithExtendedUnit | Q
913
951
  * @category Types
914
952
  */
915
953
  interface MaybeNestedOrGroup<T = QuantityWithUnitLike> {
916
- type: "or";
917
- entries: (T | MaybeNestedGroup<T>)[];
954
+ or: (T | MaybeNestedGroup<T>)[];
918
955
  }
919
956
  /**
920
957
  * Represents an "and" group of quantities that may contain nested groups (combinations with nested structure)
921
958
  * @category Types
922
959
  */
923
960
  interface MaybeNestedAndGroup<T = QuantityWithUnitLike> {
924
- type: "and";
925
- entries: (T | MaybeNestedGroup<T>)[];
961
+ and: (T | MaybeNestedGroup<T>)[];
926
962
  }
927
963
  /**
928
964
  * Represents any group type that may include nested groups
@@ -1089,8 +1125,16 @@ declare class ShoppingList {
1089
1125
  * recalculates the quantities and recategorize the ingredients.
1090
1126
  * @param recipe - The recipe to add.
1091
1127
  * @param options - Options for adding the recipe.
1128
+ * @throws Error if the recipe has alternatives without corresponding choices.
1092
1129
  */
1093
1130
  add_recipe(recipe: Recipe, options?: AddedRecipeOptions): void;
1131
+ /**
1132
+ * Checks if a recipe has unresolved alternatives (alternatives without provided choices).
1133
+ * @param recipe - The recipe to check.
1134
+ * @param choices - The choices provided for the recipe.
1135
+ * @returns An error message if there are unresolved alternatives, undefined otherwise.
1136
+ */
1137
+ private getUnresolvedAlternativesError;
1094
1138
  /**
1095
1139
  * Removes a recipe from the shopping list, then automatically
1096
1140
  * recalculates the quantities and recategorize the ingredients.s
@@ -1255,6 +1299,34 @@ declare class ShoppingCart {
1255
1299
  summarize(): ShoppingCartSummary;
1256
1300
  }
1257
1301
 
1302
+ /**
1303
+ * Determines if a specific alternative in an IngredientItem is selected
1304
+ * based on the applied choices.
1305
+ *
1306
+ * Use this in renderers to determine how an ingredient alternative should be displayed.
1307
+ *
1308
+ * @param recipe - The Recipe instance containing choices
1309
+ * @param choices - The choices that have been made
1310
+ * @param item - The IngredientItem to check
1311
+ * @param alternativeIndex - The index within item.alternatives to check (for inline alternatives only)
1312
+ * @returns true if this alternative is the selected one
1313
+ * @category Helpers
1314
+ *
1315
+ * @example
1316
+ * ```typescript
1317
+ * const recipe = new Recipe(cooklangText);
1318
+ * for (const item of step.items) {
1319
+ * if (item.type === 'ingredient') {
1320
+ * item.alternatives.forEach((alt, idx) => {
1321
+ * const isSelected = isAlternativeSelected(item, idx, recipe, choices);
1322
+ * // Render differently based on isSelected
1323
+ * });
1324
+ * }
1325
+ * }
1326
+ * ```
1327
+ */
1328
+ declare function isAlternativeSelected(recipe: Recipe, choices: RecipeChoices, item: IngredientItem, alternativeIndex?: number): boolean;
1329
+
1258
1330
  /**
1259
1331
  * Error thrown when trying to build a shopping cart without a product catalog
1260
1332
  * @category Errors
@@ -1270,4 +1342,4 @@ declare class NoShoppingListForCartError extends Error {
1270
1342
  constructor();
1271
1343
  }
1272
1344
 
1273
- export { type AddedIngredient, type AddedRecipe, type AddedRecipeOptions, type AlternativeIngredientRef, type ArbitraryScalable, type ArbitraryScalableItem, type CartContent, type CartMatch, type CartMisMatch, type CategorizedIngredients, type Category, CategoryConfig, type CategoryIngredient, type ComputedIngredient, type Cookware, type CookwareFlag, type CookwareItem, type DecimalValue, type FixedNumericValue, type FixedValue, type FractionValue, 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, 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 Step, type StepItem, type TextItem, type TextValue, type Timer, type TimerItem, type Unit, type UnitDefinition, type UnitDefinitionLike, type UnitSystem, type UnitType };
1345
+ export { type AddedIngredient, type AddedRecipe, type AddedRecipeOptions, type AlternativeIngredientRef, type ArbitraryScalable, type ArbitraryScalableItem, type CartContent, type CartMatch, type CartMisMatch, type CategorizedIngredients, type Category, CategoryConfig, type CategoryIngredient, type ComputedIngredient, type Cookware, type CookwareFlag, type CookwareItem, type DecimalValue, type FixedNumericValue, type FixedValue, type FractionValue, type GetIngredientQuantitiesOptions, 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, 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 Step, type StepItem, type TextItem, type TextValue, type Timer, type TimerItem, type Unit, type UnitDefinition, type UnitDefinitionLike, type UnitSystem, type UnitType, isAlternativeSelected };
package/dist/index.d.ts CHANGED
@@ -66,8 +66,7 @@ declare class Recipe {
66
66
  */
67
67
  metadata: Metadata;
68
68
  /**
69
- * The default or manual choice of alternative ingredients.
70
- * Contains the full context including alternatives list and active selection index.
69
+ * The possible choices of alternative ingredients for this recipe.
71
70
  */
72
71
  choices: RecipeAlternatives;
73
72
  /**
@@ -145,14 +144,33 @@ declare class Recipe {
145
144
  */
146
145
  private _populate_ingredient_quantities;
147
146
  /**
148
- * Calculates ingredient quantities based on the provided choices.
149
- * Returns a list of computed ingredients with their total quantities.
147
+ * Gets ingredients with their quantities populated, optionally filtered by section/step
148
+ * and respecting user choices for alternatives.
150
149
  *
151
- * @param choices - The recipe choices to apply when computing quantities.
152
- * If not provided, uses the default choices (first alternative for each item).
153
- * @returns An array of ComputedIngredient with quantityTotal calculated based on choices.
150
+ * When no options are provided, returns all recipe ingredients with quantities
151
+ * calculated using primary alternatives (same as after parsing).
152
+ *
153
+ * @param options - Options for filtering and choice selection:
154
+ * - `section`: Filter to a specific section (Section object or 0-based index)
155
+ * - `step`: Filter to a specific step (Step object or 0-based index)
156
+ * - `choices`: Choices for alternative ingredients (defaults to primary)
157
+ * @returns Array of Ingredient objects with quantities populated
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * // Get all ingredients with primary alternatives
162
+ * const ingredients = recipe.getIngredientQuantities();
163
+ *
164
+ * // Get ingredients for a specific section
165
+ * const sectionIngredients = recipe.getIngredientQuantities({ section: 0 });
166
+ *
167
+ * // Get ingredients with specific choices applied
168
+ * const withChoices = recipe.getIngredientQuantities({
169
+ * choices: { ingredientItems: new Map([['ingredient-item-2', 1]]) }
170
+ * });
171
+ * ```
154
172
  */
155
- calc_ingredient_quantities(choices?: RecipeChoices): ComputedIngredient[];
173
+ getIngredientQuantities(options?: GetIngredientQuantitiesOptions): Ingredient[];
156
174
  /**
157
175
  * Parses a recipe from a string.
158
176
  * @param content - The recipe content to parse.
@@ -409,11 +427,10 @@ interface IngredientQuantityGroup extends QuantityWithPlainUnit {
409
427
  * @category Types
410
428
  */
411
429
  interface IngredientQuantityAndGroup {
412
- type: "and";
413
430
  /**
414
431
  * The incompatible primary quantities (e.g., "1 large" and "2 small").
415
432
  */
416
- entries: QuantityWithPlainUnit[];
433
+ and: QuantityWithPlainUnit[];
417
434
  /**
418
435
  * The summed equivalent quantities (e.g., "5 cups" from summing "1.5 cup + 2 cup + 1.5 cup").
419
436
  */
@@ -558,6 +575,27 @@ interface RecipeChoices {
558
575
  /** Map of choices that can be made for Grouped Ingredient StepItem's */
559
576
  ingredientGroups?: Map<string, number>;
560
577
  }
578
+ /**
579
+ * Options for the {@link Recipe.getIngredientQuantities | getIngredientQuantities()} method.
580
+ * @category Types
581
+ */
582
+ interface GetIngredientQuantitiesOptions {
583
+ /**
584
+ * Filter ingredients to only those appearing in a specific section.
585
+ * Can be a Section object or section index (0-based).
586
+ */
587
+ section?: Section | number;
588
+ /**
589
+ * Filter ingredients to only those appearing in a specific step.
590
+ * Can be a Step object or step index (0-based within the section, or global if no section specified).
591
+ */
592
+ step?: Step | number;
593
+ /**
594
+ * The choices to apply when computing quantities.
595
+ * If not provided, uses primary alternatives (index 0 for all).
596
+ */
597
+ choices?: RecipeChoices;
598
+ }
561
599
  /**
562
600
  * Represents a cookware item in a recipe step.
563
601
  * @category Types
@@ -913,16 +951,14 @@ type QuantityWithUnitLike = QuantityWithPlainUnit | QuantityWithExtendedUnit | Q
913
951
  * @category Types
914
952
  */
915
953
  interface MaybeNestedOrGroup<T = QuantityWithUnitLike> {
916
- type: "or";
917
- entries: (T | MaybeNestedGroup<T>)[];
954
+ or: (T | MaybeNestedGroup<T>)[];
918
955
  }
919
956
  /**
920
957
  * Represents an "and" group of quantities that may contain nested groups (combinations with nested structure)
921
958
  * @category Types
922
959
  */
923
960
  interface MaybeNestedAndGroup<T = QuantityWithUnitLike> {
924
- type: "and";
925
- entries: (T | MaybeNestedGroup<T>)[];
961
+ and: (T | MaybeNestedGroup<T>)[];
926
962
  }
927
963
  /**
928
964
  * Represents any group type that may include nested groups
@@ -1089,8 +1125,16 @@ declare class ShoppingList {
1089
1125
  * recalculates the quantities and recategorize the ingredients.
1090
1126
  * @param recipe - The recipe to add.
1091
1127
  * @param options - Options for adding the recipe.
1128
+ * @throws Error if the recipe has alternatives without corresponding choices.
1092
1129
  */
1093
1130
  add_recipe(recipe: Recipe, options?: AddedRecipeOptions): void;
1131
+ /**
1132
+ * Checks if a recipe has unresolved alternatives (alternatives without provided choices).
1133
+ * @param recipe - The recipe to check.
1134
+ * @param choices - The choices provided for the recipe.
1135
+ * @returns An error message if there are unresolved alternatives, undefined otherwise.
1136
+ */
1137
+ private getUnresolvedAlternativesError;
1094
1138
  /**
1095
1139
  * Removes a recipe from the shopping list, then automatically
1096
1140
  * recalculates the quantities and recategorize the ingredients.s
@@ -1255,6 +1299,34 @@ declare class ShoppingCart {
1255
1299
  summarize(): ShoppingCartSummary;
1256
1300
  }
1257
1301
 
1302
+ /**
1303
+ * Determines if a specific alternative in an IngredientItem is selected
1304
+ * based on the applied choices.
1305
+ *
1306
+ * Use this in renderers to determine how an ingredient alternative should be displayed.
1307
+ *
1308
+ * @param recipe - The Recipe instance containing choices
1309
+ * @param choices - The choices that have been made
1310
+ * @param item - The IngredientItem to check
1311
+ * @param alternativeIndex - The index within item.alternatives to check (for inline alternatives only)
1312
+ * @returns true if this alternative is the selected one
1313
+ * @category Helpers
1314
+ *
1315
+ * @example
1316
+ * ```typescript
1317
+ * const recipe = new Recipe(cooklangText);
1318
+ * for (const item of step.items) {
1319
+ * if (item.type === 'ingredient') {
1320
+ * item.alternatives.forEach((alt, idx) => {
1321
+ * const isSelected = isAlternativeSelected(item, idx, recipe, choices);
1322
+ * // Render differently based on isSelected
1323
+ * });
1324
+ * }
1325
+ * }
1326
+ * ```
1327
+ */
1328
+ declare function isAlternativeSelected(recipe: Recipe, choices: RecipeChoices, item: IngredientItem, alternativeIndex?: number): boolean;
1329
+
1258
1330
  /**
1259
1331
  * Error thrown when trying to build a shopping cart without a product catalog
1260
1332
  * @category Errors
@@ -1270,4 +1342,4 @@ declare class NoShoppingListForCartError extends Error {
1270
1342
  constructor();
1271
1343
  }
1272
1344
 
1273
- export { type AddedIngredient, type AddedRecipe, type AddedRecipeOptions, type AlternativeIngredientRef, type ArbitraryScalable, type ArbitraryScalableItem, type CartContent, type CartMatch, type CartMisMatch, type CategorizedIngredients, type Category, CategoryConfig, type CategoryIngredient, type ComputedIngredient, type Cookware, type CookwareFlag, type CookwareItem, type DecimalValue, type FixedNumericValue, type FixedValue, type FractionValue, 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, 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 Step, type StepItem, type TextItem, type TextValue, type Timer, type TimerItem, type Unit, type UnitDefinition, type UnitDefinitionLike, type UnitSystem, type UnitType };
1345
+ export { type AddedIngredient, type AddedRecipe, type AddedRecipeOptions, type AlternativeIngredientRef, type ArbitraryScalable, type ArbitraryScalableItem, type CartContent, type CartMatch, type CartMisMatch, type CategorizedIngredients, type Category, CategoryConfig, type CategoryIngredient, type ComputedIngredient, type Cookware, type CookwareFlag, type CookwareItem, type DecimalValue, type FixedNumericValue, type FixedValue, type FractionValue, type GetIngredientQuantitiesOptions, 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, 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 Step, type StepItem, type TextItem, type TextValue, type Timer, type TimerItem, type Unit, type UnitDefinition, type UnitDefinitionLike, type UnitSystem, type UnitType, isAlternativeSelected };