@tmlmt/cooklang-parser 1.2.3 → 1.3.0
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/README.md +11 -47
- package/dist/index.cjs +50 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +148 -61
- package/dist/index.d.ts +148 -61
- package/dist/index.js +49 -44
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Represents a recipe section
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* Wrapped as a _Class_ and not defined as a simple _Type_ to expose some useful helper
|
|
5
|
+
* classes (e.g. {@link Section.isBlank | isBlank()})
|
|
6
|
+
*
|
|
5
7
|
* @category Types
|
|
6
8
|
*/
|
|
7
9
|
declare class Section {
|
|
8
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* The name of the section. Can be an empty string for the default (first) section.
|
|
12
|
+
* @defaultValue `""`
|
|
13
|
+
*/
|
|
9
14
|
name: string;
|
|
10
15
|
/** An array of steps and notes that make up the content of the section. */
|
|
11
16
|
content: (Step | Note)[];
|
|
@@ -23,37 +28,63 @@ declare class Section {
|
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
/**
|
|
26
|
-
*
|
|
31
|
+
* Recipe parser.
|
|
32
|
+
*
|
|
33
|
+
* ## Usage
|
|
34
|
+
*
|
|
35
|
+
* You can either directly provide the recipe string when creating the instance
|
|
36
|
+
* e.g. `const recipe = new Recipe('Add @eggs{3}')`, or create it first and then pass
|
|
37
|
+
* the recipe string to the {@link Recipe.parse | parse()} method.
|
|
38
|
+
*
|
|
39
|
+
* Look at the [properties](#properties) to see how the recipe's properties are parsed.
|
|
40
|
+
*
|
|
27
41
|
* @category Classes
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* import { Recipe } from "@tmlmt/cooklang-parser";
|
|
46
|
+
*
|
|
47
|
+
* const recipeString = `
|
|
48
|
+
* ---
|
|
49
|
+
* title: Pancakes
|
|
50
|
+
* tags: [breakfast, easy]
|
|
51
|
+
* ---
|
|
52
|
+
* Crack the @eggs{3} with @flour{100%g} and @milk{200%mL}
|
|
53
|
+
*
|
|
54
|
+
* Melt some @butter{50%g} in a #pan on medium heat.
|
|
55
|
+
*
|
|
56
|
+
* Cook for ~{5%minutes} on each side.
|
|
57
|
+
* `
|
|
58
|
+
* const recipe = new Recipe(recipeString);
|
|
59
|
+
* ```
|
|
28
60
|
*/
|
|
29
61
|
declare class Recipe {
|
|
30
62
|
/**
|
|
31
|
-
* The recipe
|
|
32
|
-
* @see {@link Metadata}
|
|
63
|
+
* The parsed recipe metadata.
|
|
33
64
|
*/
|
|
34
65
|
metadata: Metadata;
|
|
35
66
|
/**
|
|
36
|
-
* The recipe
|
|
37
|
-
* @see {@link Ingredient}
|
|
67
|
+
* The parsed recipe ingredients.
|
|
38
68
|
*/
|
|
39
69
|
ingredients: Ingredient[];
|
|
40
70
|
/**
|
|
41
|
-
* The recipe
|
|
42
|
-
* @see {@link Section}
|
|
71
|
+
* The parsed recipe sections.
|
|
43
72
|
*/
|
|
44
73
|
sections: Section[];
|
|
45
74
|
/**
|
|
46
|
-
* The recipe
|
|
47
|
-
* @see {@link Cookware}
|
|
75
|
+
* The parsed recipe cookware.
|
|
48
76
|
*/
|
|
49
77
|
cookware: Cookware[];
|
|
50
78
|
/**
|
|
51
|
-
* The recipe
|
|
52
|
-
* @see {@link Timer}
|
|
79
|
+
* The parsed recipe timers.
|
|
53
80
|
*/
|
|
54
81
|
timers: Timer[];
|
|
55
82
|
/**
|
|
56
|
-
* The recipe
|
|
83
|
+
* The parsed recipe servings. Used for scaling. Parsed from one of
|
|
84
|
+
* {@link Metadata.servings}, {@link Metadata.yield} or {@link Metadata.serves}
|
|
85
|
+
* metadata fields.
|
|
86
|
+
*
|
|
87
|
+
* @see {@link Recipe.scaleBy | scaleBy()} and {@link Recipe.scaleTo | scaleTo()} methods
|
|
57
88
|
*/
|
|
58
89
|
servings?: number;
|
|
59
90
|
/**
|
|
@@ -67,9 +98,12 @@ declare class Recipe {
|
|
|
67
98
|
*/
|
|
68
99
|
parse(content: string): void;
|
|
69
100
|
/**
|
|
70
|
-
* Scales the recipe to a new number of servings.
|
|
101
|
+
* Scales the recipe to a new number of servings. In practice, it calls
|
|
102
|
+
* {@link Recipe.scaleBy | scaleBy} with a factor corresponding to the ratio between `newServings`
|
|
103
|
+
* and the recipe's {@link Recipe.servings | servings} value.
|
|
71
104
|
* @param newServings - The new number of servings.
|
|
72
105
|
* @returns A new Recipe instance with the scaled ingredients.
|
|
106
|
+
* @throws `Error` if the recipe does not contains an initial {@link Recipe.servings | servings} value
|
|
73
107
|
*/
|
|
74
108
|
scaleTo(newServings: number): Recipe;
|
|
75
109
|
/**
|
|
@@ -102,26 +136,37 @@ interface Metadata {
|
|
|
102
136
|
tags?: string[];
|
|
103
137
|
/** The source of the recipe. */
|
|
104
138
|
source?: string;
|
|
139
|
+
/** The source name of the recipe. */
|
|
140
|
+
"source.name"?: string;
|
|
141
|
+
/** The source url of the recipe. */
|
|
142
|
+
"source.url"?: string;
|
|
143
|
+
/** The source author of the recipe. */
|
|
144
|
+
"source.author"?: string;
|
|
105
145
|
/** The author of the recipe. */
|
|
106
146
|
author?: string;
|
|
107
147
|
/** The number of servings the recipe makes.
|
|
108
148
|
* Complex info can be given, as long as the first part before a comma has a numerical value, which will be used for scaling
|
|
149
|
+
*
|
|
109
150
|
* Interchangeable with `yield` or `serves`. If multiple ones are defined, the latest one will be used for scaling */
|
|
110
151
|
servings?: string;
|
|
111
152
|
/** The yield of the recipe.
|
|
112
|
-
*
|
|
113
|
-
*
|
|
153
|
+
* Complex info can be given, as long as the first part before a comma has a numerical value, which will be used for scaling
|
|
154
|
+
*
|
|
155
|
+
* Interchangeable with `servings` or `serves`. If multiple ones are defined, the latest one will be used for scaling
|
|
114
156
|
*/
|
|
115
157
|
yield?: string;
|
|
116
158
|
/** The number of people the recipe serves.
|
|
117
|
-
*
|
|
118
|
-
*
|
|
159
|
+
* Complex info can be given, as long as the first part before a comma has a numerical value, which will be used for scaling
|
|
160
|
+
*
|
|
161
|
+
* Interchangeable with `servings` or `yield`. If multiple ones are defined, the latest one will be used for scaling
|
|
119
162
|
*/
|
|
120
163
|
serves?: string;
|
|
121
164
|
/** The course of the recipe. */
|
|
122
165
|
course?: string;
|
|
123
166
|
/** The category of the recipe. */
|
|
124
167
|
category?: string;
|
|
168
|
+
/** The locale of the recipe. */
|
|
169
|
+
locale?: string;
|
|
125
170
|
/**
|
|
126
171
|
* The preparation time of the recipe.
|
|
127
172
|
* Will not be further parsed into any DateTime format nor normalize
|
|
@@ -155,18 +200,16 @@ interface Metadata {
|
|
|
155
200
|
diet?: string;
|
|
156
201
|
/** The description of the recipe. */
|
|
157
202
|
description?: string;
|
|
158
|
-
/** The images of the recipe. */
|
|
203
|
+
/** The images of the recipe. Alias of `pictures` */
|
|
159
204
|
images?: string[];
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
*/
|
|
165
|
-
|
|
166
|
-
/** The
|
|
167
|
-
|
|
168
|
-
/** The number of servings the recipe makes. Used for scaling */
|
|
169
|
-
servings?: number;
|
|
205
|
+
/** The images of the recipe. Alias of `images` */
|
|
206
|
+
pictures?: string[];
|
|
207
|
+
/** The picture of the recipe. Alias of `picture` */
|
|
208
|
+
image?: string;
|
|
209
|
+
/** The picture of the recipe. Alias of `image` */
|
|
210
|
+
picture?: string;
|
|
211
|
+
/** The introduction of the recipe. */
|
|
212
|
+
introduction?: string;
|
|
170
213
|
}
|
|
171
214
|
/**
|
|
172
215
|
* Represents a quantity described by text, e.g. "a pinch"
|
|
@@ -335,7 +378,6 @@ interface Cookware {
|
|
|
335
378
|
* @category Types
|
|
336
379
|
*/
|
|
337
380
|
interface CategorizedIngredients {
|
|
338
|
-
/** The category of the ingredients. */
|
|
339
381
|
[category: string]: Ingredient[];
|
|
340
382
|
}
|
|
341
383
|
/**
|
|
@@ -349,78 +391,122 @@ interface AddedRecipe {
|
|
|
349
391
|
factor: number;
|
|
350
392
|
}
|
|
351
393
|
/**
|
|
352
|
-
* Represents an ingredient in
|
|
394
|
+
* Represents an ingredient in a category.
|
|
353
395
|
* @category Types
|
|
354
396
|
*/
|
|
355
|
-
interface
|
|
397
|
+
interface CategoryIngredient {
|
|
356
398
|
/** The name of the ingredient. */
|
|
357
399
|
name: string;
|
|
358
400
|
/** The aliases of the ingredient. */
|
|
359
401
|
aliases: string[];
|
|
360
402
|
}
|
|
361
403
|
/**
|
|
362
|
-
* Represents a category of
|
|
404
|
+
* Represents a category of ingredients.
|
|
363
405
|
* @category Types
|
|
364
406
|
*/
|
|
365
|
-
interface
|
|
407
|
+
interface Category {
|
|
366
408
|
/** The name of the category. */
|
|
367
409
|
name: string;
|
|
368
410
|
/** The ingredients in the category. */
|
|
369
|
-
ingredients:
|
|
411
|
+
ingredients: CategoryIngredient[];
|
|
370
412
|
}
|
|
371
413
|
|
|
372
414
|
/**
|
|
373
|
-
*
|
|
415
|
+
* Parser for category configurations specified à-la-cooklang.
|
|
416
|
+
*
|
|
417
|
+
* ## Usage
|
|
418
|
+
*
|
|
419
|
+
* You can either directly provide the category configuration string when creating the instance
|
|
420
|
+
* e.g. `const categoryConfig = new CategoryConfig(<...>)`, or create it first and then pass
|
|
421
|
+
* the category configuration string to the {@link CategoryConfig.parse | parse()} method.
|
|
422
|
+
*
|
|
423
|
+
* The initialized `CategoryConfig` can then be fed to a {@link ShoppingList}
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* ```typescript
|
|
427
|
+
* import { CategoryConfig } from @tmlmt/cooklang-parser;
|
|
428
|
+
*
|
|
429
|
+
* const categoryConfigString = `
|
|
430
|
+
* [Dairy]
|
|
431
|
+
* milk
|
|
432
|
+
* butter
|
|
433
|
+
*
|
|
434
|
+
* [Bakery]
|
|
435
|
+
* flour
|
|
436
|
+
* sugar`;
|
|
437
|
+
*
|
|
438
|
+
* const categoryConfig = new CategoryConfig(categoryConfigString);
|
|
439
|
+
* ```
|
|
440
|
+
*
|
|
441
|
+
* @see [Category Configuration](https://cooklang.org/docs/spec/#shopping-lists) section of the cooklang specs
|
|
442
|
+
*
|
|
374
443
|
* @category Classes
|
|
375
444
|
*/
|
|
376
|
-
declare class
|
|
445
|
+
declare class CategoryConfig {
|
|
377
446
|
/**
|
|
378
|
-
* The categories of
|
|
379
|
-
* @see {@link AisleCategory}
|
|
447
|
+
* The parsed categories of ingredients.
|
|
380
448
|
*/
|
|
381
|
-
categories:
|
|
449
|
+
categories: Category[];
|
|
382
450
|
/**
|
|
383
|
-
* Creates a new
|
|
384
|
-
* @param config - The
|
|
451
|
+
* Creates a new CategoryConfig instance.
|
|
452
|
+
* @param config - The category configuration to parse.
|
|
385
453
|
*/
|
|
386
454
|
constructor(config?: string);
|
|
387
455
|
/**
|
|
388
|
-
* Parses
|
|
389
|
-
*
|
|
456
|
+
* Parses a category configuration from a string into property
|
|
457
|
+
* {@link CategoryConfig.categories | categories}
|
|
458
|
+
* @param config - The category configuration to parse.
|
|
390
459
|
*/
|
|
391
460
|
parse(config: string): void;
|
|
392
461
|
}
|
|
393
462
|
|
|
394
463
|
/**
|
|
395
|
-
*
|
|
464
|
+
* Shopping List generator.
|
|
465
|
+
*
|
|
466
|
+
* ## Usage
|
|
467
|
+
*
|
|
468
|
+
* - Create a new ShoppingList instance with an optional category configuration (see {@link ShoppingList."constructor" | constructor})
|
|
469
|
+
* - Add recipes, scaling them as needed (see {@link ShoppingList.add_recipe | add_recipe()})
|
|
470
|
+
* - Categorize the ingredients (see {@link ShoppingList.categorize | categorize()})
|
|
471
|
+
*
|
|
472
|
+
* @example
|
|
473
|
+
*
|
|
474
|
+
* ```typescript
|
|
475
|
+
* import * as fs from "fs";
|
|
476
|
+
* import { ShoppingList } from @tmlmt/cooklang-parser;
|
|
477
|
+
*
|
|
478
|
+
* const categoryConfig = fs.readFileSync("./myconfig.txt", "utf-8")
|
|
479
|
+
* const recipe1 = new Recipe(fs.readFileSync("./myrecipe.cook", "utf-8"));
|
|
480
|
+
* const shoppingList = new ShoppingList();
|
|
481
|
+
* shoppingList.set_category_config(categoryConfig);
|
|
482
|
+
* shoppingList.add_recipe(recipe1);
|
|
483
|
+
* shoppingList.categorize();
|
|
484
|
+
* ```
|
|
485
|
+
*
|
|
396
486
|
* @category Classes
|
|
397
487
|
*/
|
|
398
488
|
declare class ShoppingList {
|
|
399
489
|
/**
|
|
400
490
|
* The ingredients in the shopping list.
|
|
401
|
-
* @see {@link Ingredient}
|
|
402
491
|
*/
|
|
403
492
|
ingredients: Ingredient[];
|
|
404
493
|
/**
|
|
405
494
|
* The recipes in the shopping list.
|
|
406
|
-
* @see {@link AddedRecipe}
|
|
407
495
|
*/
|
|
408
496
|
recipes: AddedRecipe[];
|
|
409
497
|
/**
|
|
410
|
-
* The
|
|
411
|
-
* @see {@link AisleConfig}
|
|
498
|
+
* The category configuration for the shopping list.
|
|
412
499
|
*/
|
|
413
|
-
|
|
500
|
+
category_config?: CategoryConfig;
|
|
414
501
|
/**
|
|
415
502
|
* The categorized ingredients in the shopping list.
|
|
416
|
-
* @see {@link CategorizedIngredients}
|
|
417
503
|
*/
|
|
418
504
|
categories?: CategorizedIngredients;
|
|
419
505
|
/**
|
|
420
|
-
* Creates a new ShoppingList instance
|
|
421
|
-
* @param
|
|
506
|
+
* Creates a new ShoppingList instance
|
|
507
|
+
* @param category_config_str - The category configuration to parse.
|
|
422
508
|
*/
|
|
423
|
-
constructor(
|
|
509
|
+
constructor(category_config_str?: string | CategoryConfig);
|
|
424
510
|
private calculate_ingredients;
|
|
425
511
|
/**
|
|
426
512
|
* Adds a recipe to the shopping list.
|
|
@@ -434,15 +520,16 @@ declare class ShoppingList {
|
|
|
434
520
|
*/
|
|
435
521
|
remove_recipe(index: number): void;
|
|
436
522
|
/**
|
|
437
|
-
* Sets the
|
|
438
|
-
*
|
|
523
|
+
* Sets the category configuration for the shopping list
|
|
524
|
+
* and automatically categorize current ingredients from the list.
|
|
525
|
+
* @param config - The category configuration to parse.
|
|
439
526
|
*/
|
|
440
|
-
|
|
527
|
+
set_category_config(config: string | CategoryConfig): void;
|
|
441
528
|
/**
|
|
442
529
|
* Categorizes the ingredients in the shopping list
|
|
443
|
-
* Will use the
|
|
530
|
+
* Will use the category config if any, otherwise all ingredients will be placed in the "other" category
|
|
444
531
|
*/
|
|
445
532
|
categorize(): void;
|
|
446
533
|
}
|
|
447
534
|
|
|
448
|
-
export { type AddedRecipe, type
|
|
535
|
+
export { type AddedRecipe, type CategorizedIngredients, type Category, CategoryConfig, type CategoryIngredient, type Cookware, type CookwareItem, type DecimalValue, type FixedValue, type FractionValue, type Ingredient, type IngredientItem, type Item, type Metadata, type Note, type Range, Recipe, Section, ShoppingList, type Step, type TextItem, type TextValue, type Timer, type TimerItem };
|
package/dist/index.js
CHANGED
|
@@ -2,16 +2,15 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
|
|
5
|
-
// src/classes/
|
|
6
|
-
var
|
|
5
|
+
// src/classes/category_config.ts
|
|
6
|
+
var CategoryConfig = class {
|
|
7
7
|
/**
|
|
8
|
-
* Creates a new
|
|
9
|
-
* @param config - The
|
|
8
|
+
* Creates a new CategoryConfig instance.
|
|
9
|
+
* @param config - The category configuration to parse.
|
|
10
10
|
*/
|
|
11
11
|
constructor(config) {
|
|
12
12
|
/**
|
|
13
|
-
* The categories of
|
|
14
|
-
* @see {@link AisleCategory}
|
|
13
|
+
* The parsed categories of ingredients.
|
|
15
14
|
*/
|
|
16
15
|
__publicField(this, "categories", []);
|
|
17
16
|
if (config) {
|
|
@@ -19,8 +18,9 @@ var AisleConfig = class {
|
|
|
19
18
|
}
|
|
20
19
|
}
|
|
21
20
|
/**
|
|
22
|
-
* Parses
|
|
23
|
-
*
|
|
21
|
+
* Parses a category configuration from a string into property
|
|
22
|
+
* {@link CategoryConfig.categories | categories}
|
|
23
|
+
* @param config - The category configuration to parse.
|
|
24
24
|
*/
|
|
25
25
|
parse(config) {
|
|
26
26
|
let currentCategory = null;
|
|
@@ -70,7 +70,10 @@ var Section = class {
|
|
|
70
70
|
* @param name - The name of the section. Defaults to an empty string.
|
|
71
71
|
*/
|
|
72
72
|
constructor(name = "") {
|
|
73
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* The name of the section. Can be an empty string for the default (first) section.
|
|
75
|
+
* @defaultValue `""`
|
|
76
|
+
*/
|
|
74
77
|
__publicField(this, "name");
|
|
75
78
|
/** An array of steps and notes that make up the content of the section. */
|
|
76
79
|
__publicField(this, "content", []);
|
|
@@ -693,7 +696,7 @@ function parseScalingMetaVar(content, varName) {
|
|
|
693
696
|
if (isNaN(Number(varMatch[2]?.trim()))) {
|
|
694
697
|
throw new Error("Scaling variables should be numbers");
|
|
695
698
|
}
|
|
696
|
-
return [Number(varMatch[2]?.trim()), varMatch[1]
|
|
699
|
+
return [Number(varMatch[2]?.trim()), varMatch[1].trim()];
|
|
697
700
|
}
|
|
698
701
|
function parseListMetaVar(content, varName) {
|
|
699
702
|
const listMatch = content.match(
|
|
@@ -766,32 +769,31 @@ var Recipe = class _Recipe {
|
|
|
766
769
|
*/
|
|
767
770
|
constructor(content) {
|
|
768
771
|
/**
|
|
769
|
-
* The recipe
|
|
770
|
-
* @see {@link Metadata}
|
|
772
|
+
* The parsed recipe metadata.
|
|
771
773
|
*/
|
|
772
774
|
__publicField(this, "metadata", {});
|
|
773
775
|
/**
|
|
774
|
-
* The recipe
|
|
775
|
-
* @see {@link Ingredient}
|
|
776
|
+
* The parsed recipe ingredients.
|
|
776
777
|
*/
|
|
777
778
|
__publicField(this, "ingredients", []);
|
|
778
779
|
/**
|
|
779
|
-
* The recipe
|
|
780
|
-
* @see {@link Section}
|
|
780
|
+
* The parsed recipe sections.
|
|
781
781
|
*/
|
|
782
782
|
__publicField(this, "sections", []);
|
|
783
783
|
/**
|
|
784
|
-
* The recipe
|
|
785
|
-
* @see {@link Cookware}
|
|
784
|
+
* The parsed recipe cookware.
|
|
786
785
|
*/
|
|
787
786
|
__publicField(this, "cookware", []);
|
|
788
787
|
/**
|
|
789
|
-
* The recipe
|
|
790
|
-
* @see {@link Timer}
|
|
788
|
+
* The parsed recipe timers.
|
|
791
789
|
*/
|
|
792
790
|
__publicField(this, "timers", []);
|
|
793
791
|
/**
|
|
794
|
-
* The recipe
|
|
792
|
+
* The parsed recipe servings. Used for scaling. Parsed from one of
|
|
793
|
+
* {@link Metadata.servings}, {@link Metadata.yield} or {@link Metadata.serves}
|
|
794
|
+
* metadata fields.
|
|
795
|
+
*
|
|
796
|
+
* @see {@link Recipe.scaleBy | scaleBy()} and {@link Recipe.scaleTo | scaleTo()} methods
|
|
795
797
|
*/
|
|
796
798
|
__publicField(this, "servings");
|
|
797
799
|
if (content) {
|
|
@@ -953,9 +955,12 @@ var Recipe = class _Recipe {
|
|
|
953
955
|
}
|
|
954
956
|
}
|
|
955
957
|
/**
|
|
956
|
-
* Scales the recipe to a new number of servings.
|
|
958
|
+
* Scales the recipe to a new number of servings. In practice, it calls
|
|
959
|
+
* {@link Recipe.scaleBy | scaleBy} with a factor corresponding to the ratio between `newServings`
|
|
960
|
+
* and the recipe's {@link Recipe.servings | servings} value.
|
|
957
961
|
* @param newServings - The new number of servings.
|
|
958
962
|
* @returns A new Recipe instance with the scaled ingredients.
|
|
963
|
+
* @throws `Error` if the recipe does not contains an initial {@link Recipe.servings | servings} value
|
|
959
964
|
*/
|
|
960
965
|
scaleTo(newServings) {
|
|
961
966
|
const originalServings = this.getServings();
|
|
@@ -1040,32 +1045,28 @@ var Recipe = class _Recipe {
|
|
|
1040
1045
|
// src/classes/shopping_list.ts
|
|
1041
1046
|
var ShoppingList = class {
|
|
1042
1047
|
/**
|
|
1043
|
-
* Creates a new ShoppingList instance
|
|
1044
|
-
* @param
|
|
1048
|
+
* Creates a new ShoppingList instance
|
|
1049
|
+
* @param category_config_str - The category configuration to parse.
|
|
1045
1050
|
*/
|
|
1046
|
-
constructor(
|
|
1051
|
+
constructor(category_config_str) {
|
|
1047
1052
|
/**
|
|
1048
1053
|
* The ingredients in the shopping list.
|
|
1049
|
-
* @see {@link Ingredient}
|
|
1050
1054
|
*/
|
|
1051
1055
|
__publicField(this, "ingredients", []);
|
|
1052
1056
|
/**
|
|
1053
1057
|
* The recipes in the shopping list.
|
|
1054
|
-
* @see {@link AddedRecipe}
|
|
1055
1058
|
*/
|
|
1056
1059
|
__publicField(this, "recipes", []);
|
|
1057
1060
|
/**
|
|
1058
|
-
* The
|
|
1059
|
-
* @see {@link AisleConfig}
|
|
1061
|
+
* The category configuration for the shopping list.
|
|
1060
1062
|
*/
|
|
1061
|
-
__publicField(this, "
|
|
1063
|
+
__publicField(this, "category_config");
|
|
1062
1064
|
/**
|
|
1063
1065
|
* The categorized ingredients in the shopping list.
|
|
1064
|
-
* @see {@link CategorizedIngredients}
|
|
1065
1066
|
*/
|
|
1066
1067
|
__publicField(this, "categories");
|
|
1067
|
-
if (
|
|
1068
|
-
this.
|
|
1068
|
+
if (category_config_str) {
|
|
1069
|
+
this.set_category_config(category_config_str);
|
|
1069
1070
|
}
|
|
1070
1071
|
}
|
|
1071
1072
|
calculate_ingredients() {
|
|
@@ -1143,31 +1144,35 @@ var ShoppingList = class {
|
|
|
1143
1144
|
this.categorize();
|
|
1144
1145
|
}
|
|
1145
1146
|
/**
|
|
1146
|
-
* Sets the
|
|
1147
|
-
*
|
|
1147
|
+
* Sets the category configuration for the shopping list
|
|
1148
|
+
* and automatically categorize current ingredients from the list.
|
|
1149
|
+
* @param config - The category configuration to parse.
|
|
1148
1150
|
*/
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
+
set_category_config(config) {
|
|
1152
|
+
if (typeof config === "string")
|
|
1153
|
+
this.category_config = new CategoryConfig(config);
|
|
1154
|
+
else if (config instanceof CategoryConfig) this.category_config = config;
|
|
1155
|
+
else throw new Error("Invalid category configuration");
|
|
1151
1156
|
this.categorize();
|
|
1152
1157
|
}
|
|
1153
1158
|
/**
|
|
1154
1159
|
* Categorizes the ingredients in the shopping list
|
|
1155
|
-
* Will use the
|
|
1160
|
+
* Will use the category config if any, otherwise all ingredients will be placed in the "other" category
|
|
1156
1161
|
*/
|
|
1157
1162
|
categorize() {
|
|
1158
|
-
if (!this.
|
|
1163
|
+
if (!this.category_config) {
|
|
1159
1164
|
this.categories = { other: this.ingredients };
|
|
1160
1165
|
return;
|
|
1161
1166
|
}
|
|
1162
1167
|
const categories = { other: [] };
|
|
1163
|
-
for (const category of this.
|
|
1168
|
+
for (const category of this.category_config.categories) {
|
|
1164
1169
|
categories[category.name] = [];
|
|
1165
1170
|
}
|
|
1166
1171
|
for (const ingredient of this.ingredients) {
|
|
1167
1172
|
let found = false;
|
|
1168
|
-
for (const category of this.
|
|
1169
|
-
for (const
|
|
1170
|
-
if (
|
|
1173
|
+
for (const category of this.category_config.categories) {
|
|
1174
|
+
for (const categoryIngredient of category.ingredients) {
|
|
1175
|
+
if (categoryIngredient.aliases.includes(ingredient.name)) {
|
|
1171
1176
|
categories[category.name].push(ingredient);
|
|
1172
1177
|
found = true;
|
|
1173
1178
|
break;
|
|
@@ -1185,7 +1190,7 @@ var ShoppingList = class {
|
|
|
1185
1190
|
}
|
|
1186
1191
|
};
|
|
1187
1192
|
export {
|
|
1188
|
-
|
|
1193
|
+
CategoryConfig,
|
|
1189
1194
|
Recipe,
|
|
1190
1195
|
Section,
|
|
1191
1196
|
ShoppingList
|