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 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` field optional, and thus `undefined` in the recipe object, unless link parsing is enabled
18
- - Move schema transform & refinement validations into a helper function `applyRecipeValidations`
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/module/type entriess in package.json; add exports field
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 schema validated recipe extraction
49
+ - `parse()` and `safeParse()` methods for Zod-validated recipe extraction
36
50
 
37
51
  ### Changed
38
52
 
39
- - **BREAKING**: Renamed `toObject()` method to `toRecipeObject()` for clarity
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.ZodDefault<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
77
- items: z.ZodArray<z.core.$ZodType<{
78
- value: string;
79
- parsed?: {
80
- quantity: number | null;
81
- quantity2: number | null;
82
- unitOfMeasureID: string | null;
83
- unitOfMeasure: string | null;
84
- description: string;
85
- isGroupHeader: boolean;
86
- } | undefined;
87
- }, unknown, z.core.$ZodTypeInternals<{
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.ZodDefault<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
105
- items: z.ZodArray<z.core.$ZodType<{
106
- value: string;
107
- parsed?: {
108
- quantity: number | null;
109
- quantity2: number | null;
110
- unitOfMeasureID: string | null;
111
- unitOfMeasure: string | null;
112
- description: string;
113
- isGroupHeader: boolean;
114
- } | undefined;
115
- }, unknown, z.core.$ZodTypeInternals<{
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.ZodDefault<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
138
- items: z.ZodArray<z.core.$ZodType<{
139
- value: string;
140
- }, unknown, z.core.$ZodTypeInternals<{
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.ZodDefault<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
150
- items: z.ZodArray<z.core.$ZodType<{
151
- value: string;
152
- }, unknown, z.core.$ZodTypeInternals<{
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.ZodDefault<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
186
- items: z.ZodArray<z.core.$ZodType<{
187
- value: string;
188
- parsed?: {
189
- quantity: number | null;
190
- quantity2: number | null;
191
- unitOfMeasureID: string | null;
192
- unitOfMeasure: string | null;
193
- description: string;
194
- isGroupHeader: boolean;
195
- } | undefined;
196
- }, unknown, z.core.$ZodTypeInternals<{
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.ZodDefault<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
210
- items: z.ZodArray<z.core.$ZodType<{
211
- value: string;
212
- }, unknown, z.core.$ZodTypeInternals<{
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.ZodDefault<z.ZodNullable<z.ZodNumber>>;
219
- cookTime: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
220
- prepTime: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
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.ZodDefault<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
227
- cookingMethod: z.ZodDefault<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
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 number field
51
+ * Helper to create a positive integer field
52
52
  */
53
- const zPositiveNumber = (fieldName) => z.number(`${fieldName} must be a number`).positive(`${fieldName} must be positive`).nullable().default(null);
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().default(null),
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().default(null),
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: zPositiveNumber("Total time"),
147
- cookTime: zPositiveNumber("Cook time"),
148
- prepTime: zPositiveNumber("Prep time"),
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().default(null),
155
- cookingMethod: zString("Cooking method").nullable().default(null),
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([]),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "recipe-scrapers-js",
3
- "version": "1.0.0-rc.2",
3
+ "version": "1.0.0-rc.4",
4
4
  "license": "MIT",
5
5
  "description": "A recipe scrapers library",
6
6
  "author": {