recipe-scrapers-js 1.0.0-rc.2 → 1.0.0-rc.4
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/CHANGELOG.md +19 -5
- package/dist/index.d.mts +53 -89
- package/dist/index.mjs +9 -9
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,20 @@ All notable changes to this project will be documented in this file.
|
|
|
6
6
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
7
7
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
8
8
|
|
|
9
|
+
## [1.0.0-rc.4] - 2025-12-21
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Fix `zNonEmptyArray` typing
|
|
14
|
+
|
|
15
|
+
## [1.0.0-rc.3] - 2025-12-21
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Enforce positive integer values for recipe time fields (`totalTime`, `cookTime`, `prepTime`)
|
|
20
|
+
- Rename schema helper `zPositiveNumber` to `zPositiveInteger`
|
|
21
|
+
- Stop defaulting nullable schema fields to `null`
|
|
22
|
+
|
|
9
23
|
## [1.0.0-rc.2] - 2025-12-20
|
|
10
24
|
|
|
11
25
|
### Added
|
|
@@ -14,8 +28,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
14
28
|
|
|
15
29
|
### Changed
|
|
16
30
|
|
|
17
|
-
- Make `links`
|
|
18
|
-
-
|
|
31
|
+
- Make `links` optional; it stays `undefined` unless link parsing is enabled
|
|
32
|
+
- Extract schema transform/refinement validations into `applyRecipeValidations`
|
|
19
33
|
|
|
20
34
|
## [1.0.0-rc.1] - 2025-12-20
|
|
21
35
|
|
|
@@ -25,18 +39,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
25
39
|
|
|
26
40
|
### Fixed
|
|
27
41
|
|
|
28
|
-
- Fix main
|
|
42
|
+
- Fix `main`/`module`/`types` entries in `package.json`; add `exports`
|
|
29
43
|
|
|
30
44
|
## [1.0.0-rc.0] - 2025-12-20
|
|
31
45
|
|
|
32
46
|
### Added
|
|
33
47
|
|
|
34
48
|
- Optional ingredient parsing via [parse-ingredient](https://github.com/jakeboone02/parse-ingredient)
|
|
35
|
-
- `parse()` and `safeParse()` methods for Zod
|
|
49
|
+
- `parse()` and `safeParse()` methods for Zod-validated recipe extraction
|
|
36
50
|
|
|
37
51
|
### Changed
|
|
38
52
|
|
|
39
|
-
- **BREAKING**:
|
|
53
|
+
- **BREAKING**: Rename `toObject()` method to `toRecipeObject()` for clarity
|
|
40
54
|
- **BREAKING**: Ingredients and instructions now require grouped structures (each group has `name` and `items`) instead of flat arrays
|
|
41
55
|
|
|
42
56
|
---
|
package/dist/index.d.mts
CHANGED
|
@@ -73,56 +73,36 @@ declare const IngredientItemSchema: z.ZodObject<{
|
|
|
73
73
|
* Schema for a group of ingredients
|
|
74
74
|
*/
|
|
75
75
|
declare const IngredientGroupSchema: z.ZodObject<{
|
|
76
|
-
name: z.
|
|
77
|
-
items: z.ZodArray<z.
|
|
78
|
-
value: string
|
|
79
|
-
parsed
|
|
80
|
-
quantity:
|
|
81
|
-
quantity2:
|
|
82
|
-
unitOfMeasureID:
|
|
83
|
-
unitOfMeasure:
|
|
84
|
-
description:
|
|
85
|
-
isGroupHeader:
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
value: string;
|
|
89
|
-
parsed?: {
|
|
90
|
-
quantity: number | null;
|
|
91
|
-
quantity2: number | null;
|
|
92
|
-
unitOfMeasureID: string | null;
|
|
93
|
-
unitOfMeasure: string | null;
|
|
94
|
-
description: string;
|
|
95
|
-
isGroupHeader: boolean;
|
|
96
|
-
} | undefined;
|
|
97
|
-
}, unknown>>>;
|
|
76
|
+
name: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
77
|
+
items: z.ZodArray<z.ZodObject<{
|
|
78
|
+
value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
79
|
+
parsed: z.ZodOptional<z.ZodObject<{
|
|
80
|
+
quantity: z.ZodNullable<z.ZodNumber>;
|
|
81
|
+
quantity2: z.ZodNullable<z.ZodNumber>;
|
|
82
|
+
unitOfMeasureID: z.ZodNullable<z.ZodString>;
|
|
83
|
+
unitOfMeasure: z.ZodNullable<z.ZodString>;
|
|
84
|
+
description: z.ZodString;
|
|
85
|
+
isGroupHeader: z.ZodBoolean;
|
|
86
|
+
}, z.core.$strip>>;
|
|
87
|
+
}, z.core.$strip>>;
|
|
98
88
|
}, z.core.$strip>;
|
|
99
89
|
/**
|
|
100
90
|
* Schema for all recipe ingredients
|
|
101
91
|
* Must have at least one group with at least one ingredient
|
|
102
92
|
*/
|
|
103
93
|
declare const IngredientsSchema: z.ZodArray<z.ZodObject<{
|
|
104
|
-
name: z.
|
|
105
|
-
items: z.ZodArray<z.
|
|
106
|
-
value: string
|
|
107
|
-
parsed
|
|
108
|
-
quantity:
|
|
109
|
-
quantity2:
|
|
110
|
-
unitOfMeasureID:
|
|
111
|
-
unitOfMeasure:
|
|
112
|
-
description:
|
|
113
|
-
isGroupHeader:
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
value: string;
|
|
117
|
-
parsed?: {
|
|
118
|
-
quantity: number | null;
|
|
119
|
-
quantity2: number | null;
|
|
120
|
-
unitOfMeasureID: string | null;
|
|
121
|
-
unitOfMeasure: string | null;
|
|
122
|
-
description: string;
|
|
123
|
-
isGroupHeader: boolean;
|
|
124
|
-
} | undefined;
|
|
125
|
-
}, unknown>>>;
|
|
94
|
+
name: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
95
|
+
items: z.ZodArray<z.ZodObject<{
|
|
96
|
+
value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
97
|
+
parsed: z.ZodOptional<z.ZodObject<{
|
|
98
|
+
quantity: z.ZodNullable<z.ZodNumber>;
|
|
99
|
+
quantity2: z.ZodNullable<z.ZodNumber>;
|
|
100
|
+
unitOfMeasureID: z.ZodNullable<z.ZodString>;
|
|
101
|
+
unitOfMeasure: z.ZodNullable<z.ZodString>;
|
|
102
|
+
description: z.ZodString;
|
|
103
|
+
isGroupHeader: z.ZodBoolean;
|
|
104
|
+
}, z.core.$strip>>;
|
|
105
|
+
}, z.core.$strip>>;
|
|
126
106
|
}, z.core.$strip>>;
|
|
127
107
|
/**
|
|
128
108
|
* Schema for a single instruction step
|
|
@@ -134,24 +114,20 @@ declare const InstructionItemSchema: z.ZodObject<{
|
|
|
134
114
|
* Schema for a group of instruction steps
|
|
135
115
|
*/
|
|
136
116
|
declare const InstructionGroupSchema: z.ZodObject<{
|
|
137
|
-
name: z.
|
|
138
|
-
items: z.ZodArray<z.
|
|
139
|
-
value: string
|
|
140
|
-
},
|
|
141
|
-
value: string;
|
|
142
|
-
}, unknown>>>;
|
|
117
|
+
name: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
118
|
+
items: z.ZodArray<z.ZodObject<{
|
|
119
|
+
value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
120
|
+
}, z.core.$strip>>;
|
|
143
121
|
}, z.core.$strip>;
|
|
144
122
|
/**
|
|
145
123
|
* Schema for all recipe instructions
|
|
146
124
|
* Must have at least one group with at least one step
|
|
147
125
|
*/
|
|
148
126
|
declare const InstructionsSchema: z.ZodArray<z.ZodObject<{
|
|
149
|
-
name: z.
|
|
150
|
-
items: z.ZodArray<z.
|
|
151
|
-
value: string
|
|
152
|
-
},
|
|
153
|
-
value: string;
|
|
154
|
-
}, unknown>>>;
|
|
127
|
+
name: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
128
|
+
items: z.ZodArray<z.ZodObject<{
|
|
129
|
+
value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
130
|
+
}, z.core.$strip>>;
|
|
155
131
|
}, z.core.$strip>>;
|
|
156
132
|
/**
|
|
157
133
|
* Schema for a link object
|
|
@@ -182,49 +158,37 @@ declare const RecipeObjectBaseSchema: z.ZodObject<{
|
|
|
182
158
|
title: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
183
159
|
author: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
184
160
|
ingredients: z.ZodArray<z.ZodObject<{
|
|
185
|
-
name: z.
|
|
186
|
-
items: z.ZodArray<z.
|
|
187
|
-
value: string
|
|
188
|
-
parsed
|
|
189
|
-
quantity:
|
|
190
|
-
quantity2:
|
|
191
|
-
unitOfMeasureID:
|
|
192
|
-
unitOfMeasure:
|
|
193
|
-
description:
|
|
194
|
-
isGroupHeader:
|
|
195
|
-
}
|
|
196
|
-
},
|
|
197
|
-
value: string;
|
|
198
|
-
parsed?: {
|
|
199
|
-
quantity: number | null;
|
|
200
|
-
quantity2: number | null;
|
|
201
|
-
unitOfMeasureID: string | null;
|
|
202
|
-
unitOfMeasure: string | null;
|
|
203
|
-
description: string;
|
|
204
|
-
isGroupHeader: boolean;
|
|
205
|
-
} | undefined;
|
|
206
|
-
}, unknown>>>;
|
|
161
|
+
name: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
162
|
+
items: z.ZodArray<z.ZodObject<{
|
|
163
|
+
value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
164
|
+
parsed: z.ZodOptional<z.ZodObject<{
|
|
165
|
+
quantity: z.ZodNullable<z.ZodNumber>;
|
|
166
|
+
quantity2: z.ZodNullable<z.ZodNumber>;
|
|
167
|
+
unitOfMeasureID: z.ZodNullable<z.ZodString>;
|
|
168
|
+
unitOfMeasure: z.ZodNullable<z.ZodString>;
|
|
169
|
+
description: z.ZodString;
|
|
170
|
+
isGroupHeader: z.ZodBoolean;
|
|
171
|
+
}, z.core.$strip>>;
|
|
172
|
+
}, z.core.$strip>>;
|
|
207
173
|
}, z.core.$strip>>;
|
|
208
174
|
instructions: z.ZodArray<z.ZodObject<{
|
|
209
|
-
name: z.
|
|
210
|
-
items: z.ZodArray<z.
|
|
211
|
-
value: string
|
|
212
|
-
},
|
|
213
|
-
value: string;
|
|
214
|
-
}, unknown>>>;
|
|
175
|
+
name: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
176
|
+
items: z.ZodArray<z.ZodObject<{
|
|
177
|
+
value: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
178
|
+
}, z.core.$strip>>;
|
|
215
179
|
}, z.core.$strip>>;
|
|
216
180
|
canonicalUrl: z.ZodURL;
|
|
217
181
|
image: z.ZodURL;
|
|
218
|
-
totalTime: z.
|
|
219
|
-
cookTime: z.
|
|
220
|
-
prepTime: z.
|
|
182
|
+
totalTime: z.ZodNullable<z.ZodInt>;
|
|
183
|
+
cookTime: z.ZodNullable<z.ZodInt>;
|
|
184
|
+
prepTime: z.ZodNullable<z.ZodInt>;
|
|
221
185
|
ratings: z.ZodDefault<z.ZodNumber>;
|
|
222
186
|
ratingsCount: z.ZodDefault<z.ZodInt>;
|
|
223
187
|
yields: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
224
188
|
description: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
225
189
|
language: z.ZodDefault<z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
|
|
226
|
-
siteName: z.
|
|
227
|
-
cookingMethod: z.
|
|
190
|
+
siteName: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
191
|
+
cookingMethod: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
228
192
|
category: z.ZodDefault<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
|
|
229
193
|
cuisine: z.ZodDefault<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
|
|
230
194
|
keywords: z.ZodDefault<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
|
package/dist/index.mjs
CHANGED
|
@@ -48,9 +48,9 @@ const zString = (fieldName, { min = 1, max = 0 } = {}) => z.string(`${fieldName}
|
|
|
48
48
|
*/
|
|
49
49
|
const zHttpUrl = (fieldName) => z.httpUrl(`${fieldName} must be a valid URL`);
|
|
50
50
|
/**
|
|
51
|
-
* Helper to create a positive
|
|
51
|
+
* Helper to create a positive integer field
|
|
52
52
|
*/
|
|
53
|
-
const
|
|
53
|
+
const zPositiveInteger = (fieldName) => z.int(`${fieldName} must be an integer`).positive(`${fieldName} must be positive`).nullable();
|
|
54
54
|
const zNonEmptyArray = (schema, fieldName) => z.array(schema, `${fieldName} items must be an array`).min(1, `${fieldName} group must have at least one item`);
|
|
55
55
|
|
|
56
56
|
//#endregion
|
|
@@ -87,7 +87,7 @@ const IngredientItemSchema = z.object({
|
|
|
87
87
|
* Schema for a group of ingredients
|
|
88
88
|
*/
|
|
89
89
|
const IngredientGroupSchema = z.object({
|
|
90
|
-
name: zString("Ingredient group name").nullable()
|
|
90
|
+
name: zString("Ingredient group name").nullable(),
|
|
91
91
|
items: zNonEmptyArray(IngredientItemSchema, "Ingredient")
|
|
92
92
|
});
|
|
93
93
|
/**
|
|
@@ -103,7 +103,7 @@ const InstructionItemSchema = z.object({ value: zString("Instruction value") });
|
|
|
103
103
|
* Schema for a group of instruction steps
|
|
104
104
|
*/
|
|
105
105
|
const InstructionGroupSchema = z.object({
|
|
106
|
-
name: zString("Instruction group name").nullable()
|
|
106
|
+
name: zString("Instruction group name").nullable(),
|
|
107
107
|
items: zNonEmptyArray(InstructionItemSchema, "Instruction")
|
|
108
108
|
});
|
|
109
109
|
/**
|
|
@@ -143,16 +143,16 @@ const RecipeObjectBaseSchema = z.object({
|
|
|
143
143
|
instructions: InstructionsSchema,
|
|
144
144
|
canonicalUrl: zHttpUrl("Canonical URL"),
|
|
145
145
|
image: zHttpUrl("Image"),
|
|
146
|
-
totalTime:
|
|
147
|
-
cookTime:
|
|
148
|
-
prepTime:
|
|
146
|
+
totalTime: zPositiveInteger("Total time"),
|
|
147
|
+
cookTime: zPositiveInteger("Cook time"),
|
|
148
|
+
prepTime: zPositiveInteger("Prep time"),
|
|
149
149
|
ratings: z.number("Ratings must be a number").min(0, "Ratings must be at least 0").max(5, "Ratings must be at most 5").default(0),
|
|
150
150
|
ratingsCount: z.int("Ratings count must be an integer").nonnegative("Ratings count must be non-negative").default(0),
|
|
151
151
|
yields: zString("Yields"),
|
|
152
152
|
description: zString("Description"),
|
|
153
153
|
language: zString("Language", { min: 2 }).optional().default("en"),
|
|
154
|
-
siteName: zString("Site name").nullable()
|
|
155
|
-
cookingMethod: zString("Cooking method").nullable()
|
|
154
|
+
siteName: zString("Site name").nullable(),
|
|
155
|
+
cookingMethod: zString("Cooking method").nullable(),
|
|
156
156
|
category: z.array(zString("Category item"), "Category must be an array").default([]),
|
|
157
157
|
cuisine: z.array(zString("Cuisine item"), "Cuisine must be an array").default([]),
|
|
158
158
|
keywords: z.array(zString("Keyword item"), "Keywords must be an array").default([]),
|