soustack 0.1.3 → 0.2.3

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.mts CHANGED
@@ -1,21 +1,27 @@
1
1
  /**
2
- * Soustack Recipe Schema v0.1
2
+ * Soustack Recipe Schema v0.2.1
3
3
  * A portable, scalable, interoperable recipe format.
4
4
  */
5
- interface Recipe {
5
+ interface SoustackRecipe {
6
+ /** Optional $schema pointer for profile-aware validation */
7
+ $schema?: string;
6
8
  /** Unique identifier (slug or UUID) */
7
9
  id?: string;
10
+ /** Optional display title */
11
+ title?: string;
8
12
  /** The title of the recipe */
9
13
  name: string;
10
14
  /** Semantic versioning (e.g., 1.0.0) */
15
+ recipeVersion?: string;
16
+ /** Deprecated alias for recipeVersion */
11
17
  version?: string;
12
18
  description?: string;
13
19
  /** Primary category (e.g., "Main Course") */
14
20
  category?: string;
15
21
  /** Additional tags for filtering */
16
22
  tags?: string[];
17
- /** URL to recipe image */
18
- image?: string;
23
+ /** URL(s) to recipe image(s) */
24
+ image?: string | string[];
19
25
  /** ISO 8601 date string */
20
26
  dateAdded?: string;
21
27
  /** Last updated timestamp */
@@ -29,7 +35,10 @@ interface Recipe {
29
35
  storage?: Storage;
30
36
  substitutions?: Substitution[];
31
37
  nutrition?: NutritionFacts;
38
+ metadata?: Record<string, unknown>;
39
+ [k: `x-${string}`]: unknown;
32
40
  }
41
+ type Recipe = SoustackRecipe;
33
42
  interface Source {
34
43
  author?: string;
35
44
  url?: string;
@@ -147,7 +156,7 @@ interface InstructionSubsection {
147
156
  subsection: string;
148
157
  items: (string | Instruction)[];
149
158
  }
150
- interface Instruction {
159
+ interface SoustackInstruction {
151
160
  id?: string;
152
161
  text: string;
153
162
  destination?: string;
@@ -156,9 +165,12 @@ interface Instruction {
156
165
  /** IDs of ingredients used in this step */
157
166
  inputs?: string[];
158
167
  timing?: StepTiming;
168
+ /** Optional image URL for this instruction */
169
+ image?: string;
159
170
  }
171
+ type Instruction = SoustackInstruction;
160
172
  interface StepTiming {
161
- duration: number;
173
+ duration: number | string;
162
174
  type: "active" | "passive";
163
175
  scaling?: "linear" | "fixed" | "sqrt";
164
176
  }
@@ -207,46 +219,43 @@ interface NutritionFacts {
207
219
  [key: string]: string | number | null | string[] | undefined;
208
220
  }
209
221
 
210
- /**
211
- * A "Computed Recipe" is the result of running the parser.
212
- * It is flat, strict, and ready for the UI to render.
213
- */
214
- interface ComputedRecipe {
215
- metadata: {
216
- targetYield: number;
217
- baseYield: number;
218
- multiplier: number;
219
- };
220
- ingredients: ComputedIngredient[];
221
- instructions: ComputedInstruction[];
222
- timing: {
223
- active: number;
224
- passive: number;
225
- total: number;
222
+ interface ScaleRecipeOptions {
223
+ multiplier?: number;
224
+ targetYield?: {
225
+ amount: number;
226
+ unit?: string;
226
227
  };
227
228
  }
228
- interface ComputedIngredient {
229
- id: string;
230
- name: string;
231
- amount: number;
232
- unit: string | null;
233
- text: string;
234
- notes?: string;
235
- }
236
- interface ComputedInstruction {
237
- id: string;
238
- text: string;
239
- durationMinutes: number;
240
- type: 'active' | 'passive';
241
- }
242
- declare function scaleRecipe(recipe: Recipe, targetYieldAmount: number): ComputedRecipe;
229
+ declare function scaleRecipe(recipe: Recipe, options?: ScaleRecipeOptions): Recipe;
243
230
 
244
- declare function validateRecipe(data: any): data is Recipe;
231
+ type ProfileName = "base" | "cookable" | "scalable" | "quantified" | "illustrated" | "schedulable";
232
+ interface NormalizedError {
233
+ path: string;
234
+ message: string;
235
+ keyword?: string;
236
+ }
237
+ interface NormalizedWarning {
238
+ path: string;
239
+ message: string;
240
+ }
241
+ interface ValidateOptions {
242
+ profile?: ProfileName;
243
+ schema?: string;
244
+ collectAllErrors?: boolean;
245
+ }
246
+ interface ValidationResult {
247
+ valid: boolean;
248
+ errors: NormalizedError[];
249
+ warnings: NormalizedWarning[];
250
+ normalized?: Recipe;
251
+ }
252
+ declare function validateRecipe(input: any, options?: ValidateOptions): ValidationResult;
253
+ declare function detectProfiles(recipe: any): ProfileName[];
245
254
 
246
255
  declare function fromSchemaOrg(input: unknown): Recipe | null;
247
256
 
248
257
  interface SchemaOrgRecipe$1 {
249
- '@context'?: string;
258
+ '@context'?: string | Array<string | Record<string, unknown>> | Record<string, unknown>;
250
259
  '@type'?: string | string[];
251
260
  name: string;
252
261
  description?: string;
@@ -275,6 +284,9 @@ interface SchemaOrgImageObject {
275
284
  '@type'?: string;
276
285
  url?: string;
277
286
  contentUrl?: string;
287
+ width?: number;
288
+ height?: number;
289
+ [key: string]: unknown;
278
290
  }
279
291
  type SchemaOrgImage = string | SchemaOrgImageObject | Array<string | SchemaOrgImageObject>;
280
292
  interface SchemaOrgYield {
@@ -287,7 +299,13 @@ interface HowToStep$1 {
287
299
  text?: string;
288
300
  name?: string;
289
301
  url?: string;
290
- image?: string;
302
+ image?: SchemaOrgImage;
303
+ '@id'?: string;
304
+ id?: string;
305
+ totalTime?: string;
306
+ performTime?: string;
307
+ prepTime?: string;
308
+ duration?: string;
291
309
  }
292
310
  interface HowToSection {
293
311
  '@type': 'HowToSection';
@@ -327,102 +345,9 @@ interface SchemaOrgRecipe {
327
345
  aggregateRating?: unknown;
328
346
  [key: string]: unknown;
329
347
  }
330
- interface FetchRequestInit {
331
- headers?: Record<string, string>;
332
- signal?: AbortSignal;
333
- redirect?: 'follow' | 'error' | 'manual';
334
- }
335
- interface FetchResponse {
336
- ok: boolean;
337
- status: number;
338
- statusText: string;
339
- text(): Promise<string>;
340
- }
341
- type FetchImplementation = (url: string, init?: FetchRequestInit) => Promise<FetchResponse>;
342
- interface FetchOptions {
343
- timeout?: number;
344
- userAgent?: string;
345
- maxRetries?: number;
346
- fetchFn?: FetchImplementation;
347
- }
348
- interface ScrapeRecipeOptions extends FetchOptions {
349
- }
350
348
 
351
- /**
352
- * Scrapes a recipe from a URL (Node.js only).
353
- *
354
- * ⚠️ Not available in browser environments due to CORS restrictions.
355
- * For browser usage, fetch the HTML yourself and use extractRecipeFromHTML().
356
- *
357
- * @param url - The URL of the recipe page to scrape
358
- * @param options - Fetch options (timeout, userAgent, maxRetries)
359
- * @returns A Soustack recipe object
360
- * @throws Error if no recipe is found
361
- */
362
- declare function scrapeRecipe(url: string, options?: ScrapeRecipeOptions): Promise<Recipe>;
363
- /**
364
- * Extracts a recipe from HTML string (browser and Node.js compatible).
365
- *
366
- * This function works in both environments and doesn't require network access.
367
- * Perfect for browser usage where you fetch HTML yourself (with cookies/session).
368
- *
369
- * @example
370
- * ```ts
371
- * // In browser:
372
- * const response = await fetch('https://example.com/recipe');
373
- * const html = await response.text();
374
- * const recipe = extractRecipeFromHTML(html);
375
- * ```
376
- *
377
- * @param html - The HTML string containing Schema.org recipe data
378
- * @returns A Soustack recipe object
379
- * @throws Error if no recipe is found
380
- */
381
- declare function extractRecipeFromHTML(html: string): Recipe;
382
- /**
383
- * Extract Schema.org recipe data from HTML string (browser-compatible).
384
- *
385
- * Returns the raw Schema.org recipe object, which can then be converted
386
- * to Soustack format using fromSchemaOrg(). This gives you access to the
387
- * original Schema.org data for inspection, debugging, or custom transformations.
388
- *
389
- * @param html - HTML string containing Schema.org recipe data
390
- * @returns Schema.org recipe object, or null if not found
391
- *
392
- * @example
393
- * ```ts
394
- * // In browser:
395
- * const response = await fetch('https://example.com/recipe');
396
- * const html = await response.text();
397
- * const schemaOrgRecipe = extractSchemaOrgRecipeFromHTML(html);
398
- *
399
- * if (schemaOrgRecipe) {
400
- * // Inspect or modify Schema.org data before converting
401
- * console.log('Found recipe:', schemaOrgRecipe.name);
402
- *
403
- * // Convert to Soustack format
404
- * const soustackRecipe = fromSchemaOrg(schemaOrgRecipe);
405
- * }
406
- * ```
407
- */
408
349
  declare function extractSchemaOrgRecipeFromHTML(html: string): SchemaOrgRecipe | null;
409
350
 
410
- declare function normalizeIngredientInput(input: string): string;
411
- declare function parseIngredient(text: string): ParsedIngredient;
412
- declare function parseIngredientLine(text: string): ParsedIngredient;
413
- declare function parseIngredients(texts: string[]): ParsedIngredient[];
414
-
415
- declare function parseDuration(iso: string): number | null;
416
- declare function parseDuration(iso: string | null | undefined): number | null;
417
- declare function formatDuration(minutes: number): string;
418
- declare function formatDuration(minutes: number | null | undefined): string;
419
- declare function parseHumanDuration(text: string): number | null;
420
- declare function parseHumanDuration(text: string | null | undefined): number | null;
421
- declare function smartParseDuration(input: string): number | null;
422
- declare function smartParseDuration(input: string | null | undefined): number | null;
423
-
424
- declare function normalizeYield(text: string): string;
425
- declare function parseYield(text: string): ParsedYield | null;
426
- declare function formatYield(value: ParsedYield): string;
351
+ declare const SOUSTACK_SPEC_VERSION = "0.2.1";
427
352
 
428
- export { type Alternative, type ComputedIngredient, type ComputedInstruction, type ComputedRecipe, type Equipment, type FrozenStorageMethod, type Ingredient, type IngredientItem, type IngredientSubsection, type Instruction, type InstructionItem, type InstructionSubsection, type MakeAheadComponent, type NutritionFacts, type ParsedIngredient, type ParsedYield, type Quantity, type Recipe, type Scaling, type ScalingBakersPercentage, type ScalingBase, type ScalingDiscrete, type ScalingFixed, type ScalingLinear, type ScalingProportional, type SchemaOrgRecipe, type SimpleTime, type Source, type StepTiming, type Storage, type StorageMethod, type StructuredTime, type Substitution, type Time, type Yield, extractRecipeFromHTML, extractSchemaOrgRecipeFromHTML, formatDuration, formatYield, fromSchemaOrg, normalizeIngredientInput, normalizeYield, parseDuration, parseHumanDuration, parseIngredient, parseIngredientLine, parseIngredients, parseYield, scaleRecipe, scrapeRecipe, smartParseDuration, toSchemaOrg, validateRecipe };
353
+ export { type Alternative, type Equipment, type FrozenStorageMethod, type Ingredient, type IngredientItem, type IngredientSubsection, type Instruction, type InstructionItem, type InstructionSubsection, type MakeAheadComponent, type NutritionFacts, type ParsedIngredient, type ParsedYield, type Quantity, type Recipe, SOUSTACK_SPEC_VERSION, type Scaling, type ScalingBakersPercentage, type ScalingBase, type ScalingDiscrete, type ScalingFixed, type ScalingLinear, type ScalingProportional, type SimpleTime, type Source, type SoustackInstruction, type SoustackRecipe, type StepTiming, type Storage, type StorageMethod, type StructuredTime, type Substitution, type Time, type Yield, detectProfiles, extractSchemaOrgRecipeFromHTML, fromSchemaOrg, scaleRecipe, toSchemaOrg, validateRecipe };
package/dist/index.d.ts CHANGED
@@ -1,21 +1,27 @@
1
1
  /**
2
- * Soustack Recipe Schema v0.1
2
+ * Soustack Recipe Schema v0.2.1
3
3
  * A portable, scalable, interoperable recipe format.
4
4
  */
5
- interface Recipe {
5
+ interface SoustackRecipe {
6
+ /** Optional $schema pointer for profile-aware validation */
7
+ $schema?: string;
6
8
  /** Unique identifier (slug or UUID) */
7
9
  id?: string;
10
+ /** Optional display title */
11
+ title?: string;
8
12
  /** The title of the recipe */
9
13
  name: string;
10
14
  /** Semantic versioning (e.g., 1.0.0) */
15
+ recipeVersion?: string;
16
+ /** Deprecated alias for recipeVersion */
11
17
  version?: string;
12
18
  description?: string;
13
19
  /** Primary category (e.g., "Main Course") */
14
20
  category?: string;
15
21
  /** Additional tags for filtering */
16
22
  tags?: string[];
17
- /** URL to recipe image */
18
- image?: string;
23
+ /** URL(s) to recipe image(s) */
24
+ image?: string | string[];
19
25
  /** ISO 8601 date string */
20
26
  dateAdded?: string;
21
27
  /** Last updated timestamp */
@@ -29,7 +35,10 @@ interface Recipe {
29
35
  storage?: Storage;
30
36
  substitutions?: Substitution[];
31
37
  nutrition?: NutritionFacts;
38
+ metadata?: Record<string, unknown>;
39
+ [k: `x-${string}`]: unknown;
32
40
  }
41
+ type Recipe = SoustackRecipe;
33
42
  interface Source {
34
43
  author?: string;
35
44
  url?: string;
@@ -147,7 +156,7 @@ interface InstructionSubsection {
147
156
  subsection: string;
148
157
  items: (string | Instruction)[];
149
158
  }
150
- interface Instruction {
159
+ interface SoustackInstruction {
151
160
  id?: string;
152
161
  text: string;
153
162
  destination?: string;
@@ -156,9 +165,12 @@ interface Instruction {
156
165
  /** IDs of ingredients used in this step */
157
166
  inputs?: string[];
158
167
  timing?: StepTiming;
168
+ /** Optional image URL for this instruction */
169
+ image?: string;
159
170
  }
171
+ type Instruction = SoustackInstruction;
160
172
  interface StepTiming {
161
- duration: number;
173
+ duration: number | string;
162
174
  type: "active" | "passive";
163
175
  scaling?: "linear" | "fixed" | "sqrt";
164
176
  }
@@ -207,46 +219,43 @@ interface NutritionFacts {
207
219
  [key: string]: string | number | null | string[] | undefined;
208
220
  }
209
221
 
210
- /**
211
- * A "Computed Recipe" is the result of running the parser.
212
- * It is flat, strict, and ready for the UI to render.
213
- */
214
- interface ComputedRecipe {
215
- metadata: {
216
- targetYield: number;
217
- baseYield: number;
218
- multiplier: number;
219
- };
220
- ingredients: ComputedIngredient[];
221
- instructions: ComputedInstruction[];
222
- timing: {
223
- active: number;
224
- passive: number;
225
- total: number;
222
+ interface ScaleRecipeOptions {
223
+ multiplier?: number;
224
+ targetYield?: {
225
+ amount: number;
226
+ unit?: string;
226
227
  };
227
228
  }
228
- interface ComputedIngredient {
229
- id: string;
230
- name: string;
231
- amount: number;
232
- unit: string | null;
233
- text: string;
234
- notes?: string;
235
- }
236
- interface ComputedInstruction {
237
- id: string;
238
- text: string;
239
- durationMinutes: number;
240
- type: 'active' | 'passive';
241
- }
242
- declare function scaleRecipe(recipe: Recipe, targetYieldAmount: number): ComputedRecipe;
229
+ declare function scaleRecipe(recipe: Recipe, options?: ScaleRecipeOptions): Recipe;
243
230
 
244
- declare function validateRecipe(data: any): data is Recipe;
231
+ type ProfileName = "base" | "cookable" | "scalable" | "quantified" | "illustrated" | "schedulable";
232
+ interface NormalizedError {
233
+ path: string;
234
+ message: string;
235
+ keyword?: string;
236
+ }
237
+ interface NormalizedWarning {
238
+ path: string;
239
+ message: string;
240
+ }
241
+ interface ValidateOptions {
242
+ profile?: ProfileName;
243
+ schema?: string;
244
+ collectAllErrors?: boolean;
245
+ }
246
+ interface ValidationResult {
247
+ valid: boolean;
248
+ errors: NormalizedError[];
249
+ warnings: NormalizedWarning[];
250
+ normalized?: Recipe;
251
+ }
252
+ declare function validateRecipe(input: any, options?: ValidateOptions): ValidationResult;
253
+ declare function detectProfiles(recipe: any): ProfileName[];
245
254
 
246
255
  declare function fromSchemaOrg(input: unknown): Recipe | null;
247
256
 
248
257
  interface SchemaOrgRecipe$1 {
249
- '@context'?: string;
258
+ '@context'?: string | Array<string | Record<string, unknown>> | Record<string, unknown>;
250
259
  '@type'?: string | string[];
251
260
  name: string;
252
261
  description?: string;
@@ -275,6 +284,9 @@ interface SchemaOrgImageObject {
275
284
  '@type'?: string;
276
285
  url?: string;
277
286
  contentUrl?: string;
287
+ width?: number;
288
+ height?: number;
289
+ [key: string]: unknown;
278
290
  }
279
291
  type SchemaOrgImage = string | SchemaOrgImageObject | Array<string | SchemaOrgImageObject>;
280
292
  interface SchemaOrgYield {
@@ -287,7 +299,13 @@ interface HowToStep$1 {
287
299
  text?: string;
288
300
  name?: string;
289
301
  url?: string;
290
- image?: string;
302
+ image?: SchemaOrgImage;
303
+ '@id'?: string;
304
+ id?: string;
305
+ totalTime?: string;
306
+ performTime?: string;
307
+ prepTime?: string;
308
+ duration?: string;
291
309
  }
292
310
  interface HowToSection {
293
311
  '@type': 'HowToSection';
@@ -327,102 +345,9 @@ interface SchemaOrgRecipe {
327
345
  aggregateRating?: unknown;
328
346
  [key: string]: unknown;
329
347
  }
330
- interface FetchRequestInit {
331
- headers?: Record<string, string>;
332
- signal?: AbortSignal;
333
- redirect?: 'follow' | 'error' | 'manual';
334
- }
335
- interface FetchResponse {
336
- ok: boolean;
337
- status: number;
338
- statusText: string;
339
- text(): Promise<string>;
340
- }
341
- type FetchImplementation = (url: string, init?: FetchRequestInit) => Promise<FetchResponse>;
342
- interface FetchOptions {
343
- timeout?: number;
344
- userAgent?: string;
345
- maxRetries?: number;
346
- fetchFn?: FetchImplementation;
347
- }
348
- interface ScrapeRecipeOptions extends FetchOptions {
349
- }
350
348
 
351
- /**
352
- * Scrapes a recipe from a URL (Node.js only).
353
- *
354
- * ⚠️ Not available in browser environments due to CORS restrictions.
355
- * For browser usage, fetch the HTML yourself and use extractRecipeFromHTML().
356
- *
357
- * @param url - The URL of the recipe page to scrape
358
- * @param options - Fetch options (timeout, userAgent, maxRetries)
359
- * @returns A Soustack recipe object
360
- * @throws Error if no recipe is found
361
- */
362
- declare function scrapeRecipe(url: string, options?: ScrapeRecipeOptions): Promise<Recipe>;
363
- /**
364
- * Extracts a recipe from HTML string (browser and Node.js compatible).
365
- *
366
- * This function works in both environments and doesn't require network access.
367
- * Perfect for browser usage where you fetch HTML yourself (with cookies/session).
368
- *
369
- * @example
370
- * ```ts
371
- * // In browser:
372
- * const response = await fetch('https://example.com/recipe');
373
- * const html = await response.text();
374
- * const recipe = extractRecipeFromHTML(html);
375
- * ```
376
- *
377
- * @param html - The HTML string containing Schema.org recipe data
378
- * @returns A Soustack recipe object
379
- * @throws Error if no recipe is found
380
- */
381
- declare function extractRecipeFromHTML(html: string): Recipe;
382
- /**
383
- * Extract Schema.org recipe data from HTML string (browser-compatible).
384
- *
385
- * Returns the raw Schema.org recipe object, which can then be converted
386
- * to Soustack format using fromSchemaOrg(). This gives you access to the
387
- * original Schema.org data for inspection, debugging, or custom transformations.
388
- *
389
- * @param html - HTML string containing Schema.org recipe data
390
- * @returns Schema.org recipe object, or null if not found
391
- *
392
- * @example
393
- * ```ts
394
- * // In browser:
395
- * const response = await fetch('https://example.com/recipe');
396
- * const html = await response.text();
397
- * const schemaOrgRecipe = extractSchemaOrgRecipeFromHTML(html);
398
- *
399
- * if (schemaOrgRecipe) {
400
- * // Inspect or modify Schema.org data before converting
401
- * console.log('Found recipe:', schemaOrgRecipe.name);
402
- *
403
- * // Convert to Soustack format
404
- * const soustackRecipe = fromSchemaOrg(schemaOrgRecipe);
405
- * }
406
- * ```
407
- */
408
349
  declare function extractSchemaOrgRecipeFromHTML(html: string): SchemaOrgRecipe | null;
409
350
 
410
- declare function normalizeIngredientInput(input: string): string;
411
- declare function parseIngredient(text: string): ParsedIngredient;
412
- declare function parseIngredientLine(text: string): ParsedIngredient;
413
- declare function parseIngredients(texts: string[]): ParsedIngredient[];
414
-
415
- declare function parseDuration(iso: string): number | null;
416
- declare function parseDuration(iso: string | null | undefined): number | null;
417
- declare function formatDuration(minutes: number): string;
418
- declare function formatDuration(minutes: number | null | undefined): string;
419
- declare function parseHumanDuration(text: string): number | null;
420
- declare function parseHumanDuration(text: string | null | undefined): number | null;
421
- declare function smartParseDuration(input: string): number | null;
422
- declare function smartParseDuration(input: string | null | undefined): number | null;
423
-
424
- declare function normalizeYield(text: string): string;
425
- declare function parseYield(text: string): ParsedYield | null;
426
- declare function formatYield(value: ParsedYield): string;
351
+ declare const SOUSTACK_SPEC_VERSION = "0.2.1";
427
352
 
428
- export { type Alternative, type ComputedIngredient, type ComputedInstruction, type ComputedRecipe, type Equipment, type FrozenStorageMethod, type Ingredient, type IngredientItem, type IngredientSubsection, type Instruction, type InstructionItem, type InstructionSubsection, type MakeAheadComponent, type NutritionFacts, type ParsedIngredient, type ParsedYield, type Quantity, type Recipe, type Scaling, type ScalingBakersPercentage, type ScalingBase, type ScalingDiscrete, type ScalingFixed, type ScalingLinear, type ScalingProportional, type SchemaOrgRecipe, type SimpleTime, type Source, type StepTiming, type Storage, type StorageMethod, type StructuredTime, type Substitution, type Time, type Yield, extractRecipeFromHTML, extractSchemaOrgRecipeFromHTML, formatDuration, formatYield, fromSchemaOrg, normalizeIngredientInput, normalizeYield, parseDuration, parseHumanDuration, parseIngredient, parseIngredientLine, parseIngredients, parseYield, scaleRecipe, scrapeRecipe, smartParseDuration, toSchemaOrg, validateRecipe };
353
+ export { type Alternative, type Equipment, type FrozenStorageMethod, type Ingredient, type IngredientItem, type IngredientSubsection, type Instruction, type InstructionItem, type InstructionSubsection, type MakeAheadComponent, type NutritionFacts, type ParsedIngredient, type ParsedYield, type Quantity, type Recipe, SOUSTACK_SPEC_VERSION, type Scaling, type ScalingBakersPercentage, type ScalingBase, type ScalingDiscrete, type ScalingFixed, type ScalingLinear, type ScalingProportional, type SimpleTime, type Source, type SoustackInstruction, type SoustackRecipe, type StepTiming, type Storage, type StorageMethod, type StructuredTime, type Substitution, type Time, type Yield, detectProfiles, extractSchemaOrgRecipeFromHTML, fromSchemaOrg, scaleRecipe, toSchemaOrg, validateRecipe };