soustack 0.2.1 → 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/LICENSE +21 -21
- package/README.md +301 -244
- package/dist/cli/index.js +1697 -1357
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.mts +48 -138
- package/dist/index.d.ts +48 -138
- package/dist/index.js +1093 -1466
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1092 -1453
- package/dist/index.mjs.map +1 -1
- package/dist/scrape.d.mts +308 -0
- package/dist/scrape.d.ts +308 -0
- package/dist/scrape.js +819 -0
- package/dist/scrape.js.map +1 -0
- package/dist/scrape.mjs +814 -0
- package/dist/scrape.mjs.map +1 -0
- package/package.json +86 -75
- package/src/profiles/.gitkeep +0 -0
- package/src/profiles/base.schema.json +9 -0
- package/src/profiles/cookable.schema.json +18 -0
- package/src/profiles/illustrated.schema.json +48 -0
- package/src/profiles/quantified.schema.json +43 -0
- package/src/profiles/scalable.schema.json +75 -0
- package/src/profiles/schedulable.schema.json +43 -0
- package/src/schema.json +43 -22
- package/src/soustack.schema.json +344 -0
package/dist/index.d.mts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
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
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") */
|
|
@@ -29,6 +35,8 @@ interface SoustackRecipe {
|
|
|
29
35
|
storage?: Storage;
|
|
30
36
|
substitutions?: Substitution[];
|
|
31
37
|
nutrition?: NutritionFacts;
|
|
38
|
+
metadata?: Record<string, unknown>;
|
|
39
|
+
[k: `x-${string}`]: unknown;
|
|
32
40
|
}
|
|
33
41
|
type Recipe = SoustackRecipe;
|
|
34
42
|
interface Source {
|
|
@@ -162,7 +170,7 @@ interface SoustackInstruction {
|
|
|
162
170
|
}
|
|
163
171
|
type Instruction = SoustackInstruction;
|
|
164
172
|
interface StepTiming {
|
|
165
|
-
duration: number;
|
|
173
|
+
duration: number | string;
|
|
166
174
|
type: "active" | "passive";
|
|
167
175
|
scaling?: "linear" | "fixed" | "sqrt";
|
|
168
176
|
}
|
|
@@ -211,46 +219,43 @@ interface NutritionFacts {
|
|
|
211
219
|
[key: string]: string | number | null | string[] | undefined;
|
|
212
220
|
}
|
|
213
221
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
metadata: {
|
|
220
|
-
targetYield: number;
|
|
221
|
-
baseYield: number;
|
|
222
|
-
multiplier: number;
|
|
223
|
-
};
|
|
224
|
-
ingredients: ComputedIngredient[];
|
|
225
|
-
instructions: ComputedInstruction[];
|
|
226
|
-
timing: {
|
|
227
|
-
active: number;
|
|
228
|
-
passive: number;
|
|
229
|
-
total: number;
|
|
222
|
+
interface ScaleRecipeOptions {
|
|
223
|
+
multiplier?: number;
|
|
224
|
+
targetYield?: {
|
|
225
|
+
amount: number;
|
|
226
|
+
unit?: string;
|
|
230
227
|
};
|
|
231
228
|
}
|
|
232
|
-
|
|
233
|
-
id: string;
|
|
234
|
-
name: string;
|
|
235
|
-
amount: number;
|
|
236
|
-
unit: string | null;
|
|
237
|
-
text: string;
|
|
238
|
-
notes?: string;
|
|
239
|
-
}
|
|
240
|
-
interface ComputedInstruction {
|
|
241
|
-
id: string;
|
|
242
|
-
text: string;
|
|
243
|
-
durationMinutes: number;
|
|
244
|
-
type: 'active' | 'passive';
|
|
245
|
-
}
|
|
246
|
-
declare function scaleRecipe(recipe: Recipe, targetYieldAmount: number): ComputedRecipe;
|
|
229
|
+
declare function scaleRecipe(recipe: Recipe, options?: ScaleRecipeOptions): Recipe;
|
|
247
230
|
|
|
248
|
-
|
|
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[];
|
|
249
254
|
|
|
250
255
|
declare function fromSchemaOrg(input: unknown): Recipe | null;
|
|
251
256
|
|
|
252
257
|
interface SchemaOrgRecipe$1 {
|
|
253
|
-
'@context'?: string
|
|
258
|
+
'@context'?: string | Array<string | Record<string, unknown>> | Record<string, unknown>;
|
|
254
259
|
'@type'?: string | string[];
|
|
255
260
|
name: string;
|
|
256
261
|
description?: string;
|
|
@@ -295,6 +300,12 @@ interface HowToStep$1 {
|
|
|
295
300
|
name?: string;
|
|
296
301
|
url?: string;
|
|
297
302
|
image?: SchemaOrgImage;
|
|
303
|
+
'@id'?: string;
|
|
304
|
+
id?: string;
|
|
305
|
+
totalTime?: string;
|
|
306
|
+
performTime?: string;
|
|
307
|
+
prepTime?: string;
|
|
308
|
+
duration?: string;
|
|
298
309
|
}
|
|
299
310
|
interface HowToSection {
|
|
300
311
|
'@type': 'HowToSection';
|
|
@@ -334,110 +345,9 @@ interface SchemaOrgRecipe {
|
|
|
334
345
|
aggregateRating?: unknown;
|
|
335
346
|
[key: string]: unknown;
|
|
336
347
|
}
|
|
337
|
-
interface FetchRequestInit {
|
|
338
|
-
headers?: Record<string, string>;
|
|
339
|
-
signal?: AbortSignal;
|
|
340
|
-
redirect?: 'follow' | 'error' | 'manual';
|
|
341
|
-
}
|
|
342
|
-
interface FetchResponse {
|
|
343
|
-
ok: boolean;
|
|
344
|
-
status: number;
|
|
345
|
-
statusText: string;
|
|
346
|
-
text(): Promise<string>;
|
|
347
|
-
}
|
|
348
|
-
type FetchImplementation = (url: string, init?: FetchRequestInit) => Promise<FetchResponse>;
|
|
349
|
-
interface FetchOptions {
|
|
350
|
-
timeout?: number;
|
|
351
|
-
userAgent?: string;
|
|
352
|
-
maxRetries?: number;
|
|
353
|
-
fetchFn?: FetchImplementation;
|
|
354
|
-
}
|
|
355
|
-
interface ScrapeRecipeOptions extends FetchOptions {
|
|
356
|
-
}
|
|
357
348
|
|
|
358
|
-
/**
|
|
359
|
-
* Scrapes a recipe from a URL (Node.js only).
|
|
360
|
-
*
|
|
361
|
-
* ⚠️ Not available in browser environments due to CORS restrictions.
|
|
362
|
-
* For browser usage, fetch the HTML yourself and use extractRecipeFromHTML().
|
|
363
|
-
*
|
|
364
|
-
* @param url - The URL of the recipe page to scrape
|
|
365
|
-
* @param options - Fetch options (timeout, userAgent, maxRetries)
|
|
366
|
-
* @returns A Soustack recipe object
|
|
367
|
-
* @throws Error if no recipe is found
|
|
368
|
-
*/
|
|
369
|
-
declare function scrapeRecipe(url: string, options?: ScrapeRecipeOptions): Promise<Recipe>;
|
|
370
|
-
/**
|
|
371
|
-
* Extracts a recipe from HTML string (browser and Node.js compatible).
|
|
372
|
-
*
|
|
373
|
-
* This function works in both environments and doesn't require network access.
|
|
374
|
-
* Perfect for browser usage where you fetch HTML yourself (with cookies/session).
|
|
375
|
-
*
|
|
376
|
-
* @example
|
|
377
|
-
* ```ts
|
|
378
|
-
* // In browser:
|
|
379
|
-
* const response = await fetch('https://example.com/recipe');
|
|
380
|
-
* const html = await response.text();
|
|
381
|
-
* const recipe = extractRecipeFromHTML(html);
|
|
382
|
-
* ```
|
|
383
|
-
*
|
|
384
|
-
* @param html - The HTML string containing Schema.org recipe data
|
|
385
|
-
* @returns A Soustack recipe object
|
|
386
|
-
* @throws Error if no recipe is found
|
|
387
|
-
*/
|
|
388
|
-
declare function extractRecipeFromHTML(html: string): Recipe;
|
|
389
|
-
/**
|
|
390
|
-
* Extract Schema.org recipe data from HTML string (browser-compatible).
|
|
391
|
-
*
|
|
392
|
-
* Returns the raw Schema.org recipe object, which can then be converted
|
|
393
|
-
* to Soustack format using fromSchemaOrg(). This gives you access to the
|
|
394
|
-
* original Schema.org data for inspection, debugging, or custom transformations.
|
|
395
|
-
*
|
|
396
|
-
* @param html - HTML string containing Schema.org recipe data
|
|
397
|
-
* @returns Schema.org recipe object, or null if not found
|
|
398
|
-
*
|
|
399
|
-
* @example
|
|
400
|
-
* ```ts
|
|
401
|
-
* // In browser:
|
|
402
|
-
* const response = await fetch('https://example.com/recipe');
|
|
403
|
-
* const html = await response.text();
|
|
404
|
-
* const schemaOrgRecipe = extractSchemaOrgRecipeFromHTML(html);
|
|
405
|
-
*
|
|
406
|
-
* if (schemaOrgRecipe) {
|
|
407
|
-
* // Inspect or modify Schema.org data before converting
|
|
408
|
-
* console.log('Found recipe:', schemaOrgRecipe.name);
|
|
409
|
-
*
|
|
410
|
-
* // Convert to Soustack format
|
|
411
|
-
* const soustackRecipe = fromSchemaOrg(schemaOrgRecipe);
|
|
412
|
-
* }
|
|
413
|
-
* ```
|
|
414
|
-
*/
|
|
415
349
|
declare function extractSchemaOrgRecipeFromHTML(html: string): SchemaOrgRecipe | null;
|
|
416
350
|
|
|
417
|
-
declare
|
|
418
|
-
declare function parseIngredient(text: string): ParsedIngredient;
|
|
419
|
-
declare function parseIngredientLine(text: string): ParsedIngredient;
|
|
420
|
-
declare function parseIngredients(texts: string[]): ParsedIngredient[];
|
|
421
|
-
|
|
422
|
-
declare function parseDuration(iso: string): number | null;
|
|
423
|
-
declare function parseDuration(iso: string | null | undefined): number | null;
|
|
424
|
-
declare function formatDuration(minutes: number): string;
|
|
425
|
-
declare function formatDuration(minutes: number | null | undefined): string;
|
|
426
|
-
declare function parseHumanDuration(text: string): number | null;
|
|
427
|
-
declare function parseHumanDuration(text: string | null | undefined): number | null;
|
|
428
|
-
declare function smartParseDuration(input: string): number | null;
|
|
429
|
-
declare function smartParseDuration(input: string | null | undefined): number | null;
|
|
430
|
-
|
|
431
|
-
declare function normalizeYield(text: string): string;
|
|
432
|
-
declare function parseYield(text: string): ParsedYield | null;
|
|
433
|
-
declare function formatYield(value: ParsedYield): string;
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* Normalize Schema.org image formats to Soustack format.
|
|
437
|
-
* - String values pass through
|
|
438
|
-
* - Arrays collapse to string or string[] after URL extraction
|
|
439
|
-
* - ImageObjects extract their url/contentUrl
|
|
440
|
-
*/
|
|
441
|
-
declare function normalizeImage(image: SchemaOrgImage | undefined | null): string | string[] | undefined;
|
|
351
|
+
declare const SOUSTACK_SPEC_VERSION = "0.2.1";
|
|
442
352
|
|
|
443
|
-
export { type Alternative, type
|
|
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,13 +1,19 @@
|
|
|
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
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") */
|
|
@@ -29,6 +35,8 @@ interface SoustackRecipe {
|
|
|
29
35
|
storage?: Storage;
|
|
30
36
|
substitutions?: Substitution[];
|
|
31
37
|
nutrition?: NutritionFacts;
|
|
38
|
+
metadata?: Record<string, unknown>;
|
|
39
|
+
[k: `x-${string}`]: unknown;
|
|
32
40
|
}
|
|
33
41
|
type Recipe = SoustackRecipe;
|
|
34
42
|
interface Source {
|
|
@@ -162,7 +170,7 @@ interface SoustackInstruction {
|
|
|
162
170
|
}
|
|
163
171
|
type Instruction = SoustackInstruction;
|
|
164
172
|
interface StepTiming {
|
|
165
|
-
duration: number;
|
|
173
|
+
duration: number | string;
|
|
166
174
|
type: "active" | "passive";
|
|
167
175
|
scaling?: "linear" | "fixed" | "sqrt";
|
|
168
176
|
}
|
|
@@ -211,46 +219,43 @@ interface NutritionFacts {
|
|
|
211
219
|
[key: string]: string | number | null | string[] | undefined;
|
|
212
220
|
}
|
|
213
221
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
metadata: {
|
|
220
|
-
targetYield: number;
|
|
221
|
-
baseYield: number;
|
|
222
|
-
multiplier: number;
|
|
223
|
-
};
|
|
224
|
-
ingredients: ComputedIngredient[];
|
|
225
|
-
instructions: ComputedInstruction[];
|
|
226
|
-
timing: {
|
|
227
|
-
active: number;
|
|
228
|
-
passive: number;
|
|
229
|
-
total: number;
|
|
222
|
+
interface ScaleRecipeOptions {
|
|
223
|
+
multiplier?: number;
|
|
224
|
+
targetYield?: {
|
|
225
|
+
amount: number;
|
|
226
|
+
unit?: string;
|
|
230
227
|
};
|
|
231
228
|
}
|
|
232
|
-
|
|
233
|
-
id: string;
|
|
234
|
-
name: string;
|
|
235
|
-
amount: number;
|
|
236
|
-
unit: string | null;
|
|
237
|
-
text: string;
|
|
238
|
-
notes?: string;
|
|
239
|
-
}
|
|
240
|
-
interface ComputedInstruction {
|
|
241
|
-
id: string;
|
|
242
|
-
text: string;
|
|
243
|
-
durationMinutes: number;
|
|
244
|
-
type: 'active' | 'passive';
|
|
245
|
-
}
|
|
246
|
-
declare function scaleRecipe(recipe: Recipe, targetYieldAmount: number): ComputedRecipe;
|
|
229
|
+
declare function scaleRecipe(recipe: Recipe, options?: ScaleRecipeOptions): Recipe;
|
|
247
230
|
|
|
248
|
-
|
|
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[];
|
|
249
254
|
|
|
250
255
|
declare function fromSchemaOrg(input: unknown): Recipe | null;
|
|
251
256
|
|
|
252
257
|
interface SchemaOrgRecipe$1 {
|
|
253
|
-
'@context'?: string
|
|
258
|
+
'@context'?: string | Array<string | Record<string, unknown>> | Record<string, unknown>;
|
|
254
259
|
'@type'?: string | string[];
|
|
255
260
|
name: string;
|
|
256
261
|
description?: string;
|
|
@@ -295,6 +300,12 @@ interface HowToStep$1 {
|
|
|
295
300
|
name?: string;
|
|
296
301
|
url?: string;
|
|
297
302
|
image?: SchemaOrgImage;
|
|
303
|
+
'@id'?: string;
|
|
304
|
+
id?: string;
|
|
305
|
+
totalTime?: string;
|
|
306
|
+
performTime?: string;
|
|
307
|
+
prepTime?: string;
|
|
308
|
+
duration?: string;
|
|
298
309
|
}
|
|
299
310
|
interface HowToSection {
|
|
300
311
|
'@type': 'HowToSection';
|
|
@@ -334,110 +345,9 @@ interface SchemaOrgRecipe {
|
|
|
334
345
|
aggregateRating?: unknown;
|
|
335
346
|
[key: string]: unknown;
|
|
336
347
|
}
|
|
337
|
-
interface FetchRequestInit {
|
|
338
|
-
headers?: Record<string, string>;
|
|
339
|
-
signal?: AbortSignal;
|
|
340
|
-
redirect?: 'follow' | 'error' | 'manual';
|
|
341
|
-
}
|
|
342
|
-
interface FetchResponse {
|
|
343
|
-
ok: boolean;
|
|
344
|
-
status: number;
|
|
345
|
-
statusText: string;
|
|
346
|
-
text(): Promise<string>;
|
|
347
|
-
}
|
|
348
|
-
type FetchImplementation = (url: string, init?: FetchRequestInit) => Promise<FetchResponse>;
|
|
349
|
-
interface FetchOptions {
|
|
350
|
-
timeout?: number;
|
|
351
|
-
userAgent?: string;
|
|
352
|
-
maxRetries?: number;
|
|
353
|
-
fetchFn?: FetchImplementation;
|
|
354
|
-
}
|
|
355
|
-
interface ScrapeRecipeOptions extends FetchOptions {
|
|
356
|
-
}
|
|
357
348
|
|
|
358
|
-
/**
|
|
359
|
-
* Scrapes a recipe from a URL (Node.js only).
|
|
360
|
-
*
|
|
361
|
-
* ⚠️ Not available in browser environments due to CORS restrictions.
|
|
362
|
-
* For browser usage, fetch the HTML yourself and use extractRecipeFromHTML().
|
|
363
|
-
*
|
|
364
|
-
* @param url - The URL of the recipe page to scrape
|
|
365
|
-
* @param options - Fetch options (timeout, userAgent, maxRetries)
|
|
366
|
-
* @returns A Soustack recipe object
|
|
367
|
-
* @throws Error if no recipe is found
|
|
368
|
-
*/
|
|
369
|
-
declare function scrapeRecipe(url: string, options?: ScrapeRecipeOptions): Promise<Recipe>;
|
|
370
|
-
/**
|
|
371
|
-
* Extracts a recipe from HTML string (browser and Node.js compatible).
|
|
372
|
-
*
|
|
373
|
-
* This function works in both environments and doesn't require network access.
|
|
374
|
-
* Perfect for browser usage where you fetch HTML yourself (with cookies/session).
|
|
375
|
-
*
|
|
376
|
-
* @example
|
|
377
|
-
* ```ts
|
|
378
|
-
* // In browser:
|
|
379
|
-
* const response = await fetch('https://example.com/recipe');
|
|
380
|
-
* const html = await response.text();
|
|
381
|
-
* const recipe = extractRecipeFromHTML(html);
|
|
382
|
-
* ```
|
|
383
|
-
*
|
|
384
|
-
* @param html - The HTML string containing Schema.org recipe data
|
|
385
|
-
* @returns A Soustack recipe object
|
|
386
|
-
* @throws Error if no recipe is found
|
|
387
|
-
*/
|
|
388
|
-
declare function extractRecipeFromHTML(html: string): Recipe;
|
|
389
|
-
/**
|
|
390
|
-
* Extract Schema.org recipe data from HTML string (browser-compatible).
|
|
391
|
-
*
|
|
392
|
-
* Returns the raw Schema.org recipe object, which can then be converted
|
|
393
|
-
* to Soustack format using fromSchemaOrg(). This gives you access to the
|
|
394
|
-
* original Schema.org data for inspection, debugging, or custom transformations.
|
|
395
|
-
*
|
|
396
|
-
* @param html - HTML string containing Schema.org recipe data
|
|
397
|
-
* @returns Schema.org recipe object, or null if not found
|
|
398
|
-
*
|
|
399
|
-
* @example
|
|
400
|
-
* ```ts
|
|
401
|
-
* // In browser:
|
|
402
|
-
* const response = await fetch('https://example.com/recipe');
|
|
403
|
-
* const html = await response.text();
|
|
404
|
-
* const schemaOrgRecipe = extractSchemaOrgRecipeFromHTML(html);
|
|
405
|
-
*
|
|
406
|
-
* if (schemaOrgRecipe) {
|
|
407
|
-
* // Inspect or modify Schema.org data before converting
|
|
408
|
-
* console.log('Found recipe:', schemaOrgRecipe.name);
|
|
409
|
-
*
|
|
410
|
-
* // Convert to Soustack format
|
|
411
|
-
* const soustackRecipe = fromSchemaOrg(schemaOrgRecipe);
|
|
412
|
-
* }
|
|
413
|
-
* ```
|
|
414
|
-
*/
|
|
415
349
|
declare function extractSchemaOrgRecipeFromHTML(html: string): SchemaOrgRecipe | null;
|
|
416
350
|
|
|
417
|
-
declare
|
|
418
|
-
declare function parseIngredient(text: string): ParsedIngredient;
|
|
419
|
-
declare function parseIngredientLine(text: string): ParsedIngredient;
|
|
420
|
-
declare function parseIngredients(texts: string[]): ParsedIngredient[];
|
|
421
|
-
|
|
422
|
-
declare function parseDuration(iso: string): number | null;
|
|
423
|
-
declare function parseDuration(iso: string | null | undefined): number | null;
|
|
424
|
-
declare function formatDuration(minutes: number): string;
|
|
425
|
-
declare function formatDuration(minutes: number | null | undefined): string;
|
|
426
|
-
declare function parseHumanDuration(text: string): number | null;
|
|
427
|
-
declare function parseHumanDuration(text: string | null | undefined): number | null;
|
|
428
|
-
declare function smartParseDuration(input: string): number | null;
|
|
429
|
-
declare function smartParseDuration(input: string | null | undefined): number | null;
|
|
430
|
-
|
|
431
|
-
declare function normalizeYield(text: string): string;
|
|
432
|
-
declare function parseYield(text: string): ParsedYield | null;
|
|
433
|
-
declare function formatYield(value: ParsedYield): string;
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* Normalize Schema.org image formats to Soustack format.
|
|
437
|
-
* - String values pass through
|
|
438
|
-
* - Arrays collapse to string or string[] after URL extraction
|
|
439
|
-
* - ImageObjects extract their url/contentUrl
|
|
440
|
-
*/
|
|
441
|
-
declare function normalizeImage(image: SchemaOrgImage | undefined | null): string | string[] | undefined;
|
|
351
|
+
declare const SOUSTACK_SPEC_VERSION = "0.2.1";
|
|
442
352
|
|
|
443
|
-
export { type Alternative, type
|
|
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 };
|