soustack 0.1.2 → 0.2.1
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 +86 -10
- package/dist/cli/index.js +159 -53
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.mts +75 -11
- package/dist/index.d.ts +75 -11
- package/dist/index.js +165 -53
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +164 -54
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/schema.json +22 -4
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Soustack Recipe Schema v0.1
|
|
3
3
|
* A portable, scalable, interoperable recipe format.
|
|
4
4
|
*/
|
|
5
|
-
interface
|
|
5
|
+
interface SoustackRecipe {
|
|
6
6
|
/** Unique identifier (slug or UUID) */
|
|
7
7
|
id?: string;
|
|
8
8
|
/** The title of the recipe */
|
|
@@ -14,8 +14,8 @@ interface Recipe {
|
|
|
14
14
|
category?: string;
|
|
15
15
|
/** Additional tags for filtering */
|
|
16
16
|
tags?: string[];
|
|
17
|
-
/** URL to recipe image */
|
|
18
|
-
image?: string;
|
|
17
|
+
/** URL(s) to recipe image(s) */
|
|
18
|
+
image?: string | string[];
|
|
19
19
|
/** ISO 8601 date string */
|
|
20
20
|
dateAdded?: string;
|
|
21
21
|
/** Last updated timestamp */
|
|
@@ -30,6 +30,7 @@ interface Recipe {
|
|
|
30
30
|
substitutions?: Substitution[];
|
|
31
31
|
nutrition?: NutritionFacts;
|
|
32
32
|
}
|
|
33
|
+
type Recipe = SoustackRecipe;
|
|
33
34
|
interface Source {
|
|
34
35
|
author?: string;
|
|
35
36
|
url?: string;
|
|
@@ -147,7 +148,7 @@ interface InstructionSubsection {
|
|
|
147
148
|
subsection: string;
|
|
148
149
|
items: (string | Instruction)[];
|
|
149
150
|
}
|
|
150
|
-
interface
|
|
151
|
+
interface SoustackInstruction {
|
|
151
152
|
id?: string;
|
|
152
153
|
text: string;
|
|
153
154
|
destination?: string;
|
|
@@ -156,7 +157,10 @@ interface Instruction {
|
|
|
156
157
|
/** IDs of ingredients used in this step */
|
|
157
158
|
inputs?: string[];
|
|
158
159
|
timing?: StepTiming;
|
|
160
|
+
/** Optional image URL for this instruction */
|
|
161
|
+
image?: string;
|
|
159
162
|
}
|
|
163
|
+
type Instruction = SoustackInstruction;
|
|
160
164
|
interface StepTiming {
|
|
161
165
|
duration: number;
|
|
162
166
|
type: "active" | "passive";
|
|
@@ -245,7 +249,7 @@ declare function validateRecipe(data: any): data is Recipe;
|
|
|
245
249
|
|
|
246
250
|
declare function fromSchemaOrg(input: unknown): Recipe | null;
|
|
247
251
|
|
|
248
|
-
interface SchemaOrgRecipe {
|
|
252
|
+
interface SchemaOrgRecipe$1 {
|
|
249
253
|
'@context'?: string;
|
|
250
254
|
'@type'?: string | string[];
|
|
251
255
|
name: string;
|
|
@@ -270,11 +274,14 @@ interface SchemaOrgRecipe {
|
|
|
270
274
|
'@graph'?: unknown;
|
|
271
275
|
}
|
|
272
276
|
type SchemaOrgIngredientList = string | string[];
|
|
273
|
-
type SchemaOrgInstructionList = string | HowToStep | HowToSection | Array<string | HowToStep | HowToSection>;
|
|
277
|
+
type SchemaOrgInstructionList = string | HowToStep$1 | HowToSection | Array<string | HowToStep$1 | HowToSection>;
|
|
274
278
|
interface SchemaOrgImageObject {
|
|
275
279
|
'@type'?: string;
|
|
276
280
|
url?: string;
|
|
277
281
|
contentUrl?: string;
|
|
282
|
+
width?: number;
|
|
283
|
+
height?: number;
|
|
284
|
+
[key: string]: unknown;
|
|
278
285
|
}
|
|
279
286
|
type SchemaOrgImage = string | SchemaOrgImageObject | Array<string | SchemaOrgImageObject>;
|
|
280
287
|
interface SchemaOrgYield {
|
|
@@ -282,17 +289,17 @@ interface SchemaOrgYield {
|
|
|
282
289
|
unit?: string;
|
|
283
290
|
description?: string;
|
|
284
291
|
}
|
|
285
|
-
interface HowToStep {
|
|
292
|
+
interface HowToStep$1 {
|
|
286
293
|
'@type': 'HowToStep';
|
|
287
294
|
text?: string;
|
|
288
295
|
name?: string;
|
|
289
296
|
url?: string;
|
|
290
|
-
image?:
|
|
297
|
+
image?: SchemaOrgImage;
|
|
291
298
|
}
|
|
292
299
|
interface HowToSection {
|
|
293
300
|
'@type': 'HowToSection';
|
|
294
301
|
name: string;
|
|
295
|
-
itemListElement: Array<string | HowToStep | HowToSection>;
|
|
302
|
+
itemListElement: Array<string | HowToStep$1 | HowToSection>;
|
|
296
303
|
}
|
|
297
304
|
interface SchemaOrgPersonOrOrganization {
|
|
298
305
|
'@type'?: 'Person' | 'Organization';
|
|
@@ -303,8 +310,30 @@ interface NutritionInformation {
|
|
|
303
310
|
[key: string]: string | number | null | undefined;
|
|
304
311
|
}
|
|
305
312
|
|
|
306
|
-
declare function toSchemaOrg(recipe: Recipe): SchemaOrgRecipe;
|
|
313
|
+
declare function toSchemaOrg(recipe: Recipe): SchemaOrgRecipe$1;
|
|
307
314
|
|
|
315
|
+
interface HowToStep {
|
|
316
|
+
'@type'?: 'HowToStep' | 'HowToSection' | string;
|
|
317
|
+
name?: string;
|
|
318
|
+
text?: string;
|
|
319
|
+
itemListElement?: Array<string | HowToStep>;
|
|
320
|
+
}
|
|
321
|
+
interface SchemaOrgRecipe {
|
|
322
|
+
'@type': string | string[];
|
|
323
|
+
name?: string;
|
|
324
|
+
description?: string;
|
|
325
|
+
image?: string | string[];
|
|
326
|
+
recipeIngredient?: string[];
|
|
327
|
+
recipeInstructions?: Array<string | HowToStep>;
|
|
328
|
+
recipeYield?: string | number;
|
|
329
|
+
prepTime?: string;
|
|
330
|
+
cookTime?: string;
|
|
331
|
+
totalTime?: string;
|
|
332
|
+
author?: unknown;
|
|
333
|
+
datePublished?: string;
|
|
334
|
+
aggregateRating?: unknown;
|
|
335
|
+
[key: string]: unknown;
|
|
336
|
+
}
|
|
308
337
|
interface FetchRequestInit {
|
|
309
338
|
headers?: Record<string, string>;
|
|
310
339
|
signal?: AbortSignal;
|
|
@@ -357,6 +386,33 @@ declare function scrapeRecipe(url: string, options?: ScrapeRecipeOptions): Promi
|
|
|
357
386
|
* @throws Error if no recipe is found
|
|
358
387
|
*/
|
|
359
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
|
+
declare function extractSchemaOrgRecipeFromHTML(html: string): SchemaOrgRecipe | null;
|
|
360
416
|
|
|
361
417
|
declare function normalizeIngredientInput(input: string): string;
|
|
362
418
|
declare function parseIngredient(text: string): ParsedIngredient;
|
|
@@ -376,4 +432,12 @@ declare function normalizeYield(text: string): string;
|
|
|
376
432
|
declare function parseYield(text: string): ParsedYield | null;
|
|
377
433
|
declare function formatYield(value: ParsedYield): string;
|
|
378
434
|
|
|
379
|
-
|
|
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;
|
|
442
|
+
|
|
443
|
+
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 SoustackInstruction, type SoustackRecipe, type StepTiming, type Storage, type StorageMethod, type StructuredTime, type Substitution, type Time, type Yield, extractRecipeFromHTML, extractSchemaOrgRecipeFromHTML, formatDuration, formatYield, fromSchemaOrg, normalizeImage, normalizeIngredientInput, normalizeYield, parseDuration, parseHumanDuration, parseIngredient, parseIngredientLine, parseIngredients, parseYield, scaleRecipe, scrapeRecipe, smartParseDuration, toSchemaOrg, validateRecipe };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Soustack Recipe Schema v0.1
|
|
3
3
|
* A portable, scalable, interoperable recipe format.
|
|
4
4
|
*/
|
|
5
|
-
interface
|
|
5
|
+
interface SoustackRecipe {
|
|
6
6
|
/** Unique identifier (slug or UUID) */
|
|
7
7
|
id?: string;
|
|
8
8
|
/** The title of the recipe */
|
|
@@ -14,8 +14,8 @@ interface Recipe {
|
|
|
14
14
|
category?: string;
|
|
15
15
|
/** Additional tags for filtering */
|
|
16
16
|
tags?: string[];
|
|
17
|
-
/** URL to recipe image */
|
|
18
|
-
image?: string;
|
|
17
|
+
/** URL(s) to recipe image(s) */
|
|
18
|
+
image?: string | string[];
|
|
19
19
|
/** ISO 8601 date string */
|
|
20
20
|
dateAdded?: string;
|
|
21
21
|
/** Last updated timestamp */
|
|
@@ -30,6 +30,7 @@ interface Recipe {
|
|
|
30
30
|
substitutions?: Substitution[];
|
|
31
31
|
nutrition?: NutritionFacts;
|
|
32
32
|
}
|
|
33
|
+
type Recipe = SoustackRecipe;
|
|
33
34
|
interface Source {
|
|
34
35
|
author?: string;
|
|
35
36
|
url?: string;
|
|
@@ -147,7 +148,7 @@ interface InstructionSubsection {
|
|
|
147
148
|
subsection: string;
|
|
148
149
|
items: (string | Instruction)[];
|
|
149
150
|
}
|
|
150
|
-
interface
|
|
151
|
+
interface SoustackInstruction {
|
|
151
152
|
id?: string;
|
|
152
153
|
text: string;
|
|
153
154
|
destination?: string;
|
|
@@ -156,7 +157,10 @@ interface Instruction {
|
|
|
156
157
|
/** IDs of ingredients used in this step */
|
|
157
158
|
inputs?: string[];
|
|
158
159
|
timing?: StepTiming;
|
|
160
|
+
/** Optional image URL for this instruction */
|
|
161
|
+
image?: string;
|
|
159
162
|
}
|
|
163
|
+
type Instruction = SoustackInstruction;
|
|
160
164
|
interface StepTiming {
|
|
161
165
|
duration: number;
|
|
162
166
|
type: "active" | "passive";
|
|
@@ -245,7 +249,7 @@ declare function validateRecipe(data: any): data is Recipe;
|
|
|
245
249
|
|
|
246
250
|
declare function fromSchemaOrg(input: unknown): Recipe | null;
|
|
247
251
|
|
|
248
|
-
interface SchemaOrgRecipe {
|
|
252
|
+
interface SchemaOrgRecipe$1 {
|
|
249
253
|
'@context'?: string;
|
|
250
254
|
'@type'?: string | string[];
|
|
251
255
|
name: string;
|
|
@@ -270,11 +274,14 @@ interface SchemaOrgRecipe {
|
|
|
270
274
|
'@graph'?: unknown;
|
|
271
275
|
}
|
|
272
276
|
type SchemaOrgIngredientList = string | string[];
|
|
273
|
-
type SchemaOrgInstructionList = string | HowToStep | HowToSection | Array<string | HowToStep | HowToSection>;
|
|
277
|
+
type SchemaOrgInstructionList = string | HowToStep$1 | HowToSection | Array<string | HowToStep$1 | HowToSection>;
|
|
274
278
|
interface SchemaOrgImageObject {
|
|
275
279
|
'@type'?: string;
|
|
276
280
|
url?: string;
|
|
277
281
|
contentUrl?: string;
|
|
282
|
+
width?: number;
|
|
283
|
+
height?: number;
|
|
284
|
+
[key: string]: unknown;
|
|
278
285
|
}
|
|
279
286
|
type SchemaOrgImage = string | SchemaOrgImageObject | Array<string | SchemaOrgImageObject>;
|
|
280
287
|
interface SchemaOrgYield {
|
|
@@ -282,17 +289,17 @@ interface SchemaOrgYield {
|
|
|
282
289
|
unit?: string;
|
|
283
290
|
description?: string;
|
|
284
291
|
}
|
|
285
|
-
interface HowToStep {
|
|
292
|
+
interface HowToStep$1 {
|
|
286
293
|
'@type': 'HowToStep';
|
|
287
294
|
text?: string;
|
|
288
295
|
name?: string;
|
|
289
296
|
url?: string;
|
|
290
|
-
image?:
|
|
297
|
+
image?: SchemaOrgImage;
|
|
291
298
|
}
|
|
292
299
|
interface HowToSection {
|
|
293
300
|
'@type': 'HowToSection';
|
|
294
301
|
name: string;
|
|
295
|
-
itemListElement: Array<string | HowToStep | HowToSection>;
|
|
302
|
+
itemListElement: Array<string | HowToStep$1 | HowToSection>;
|
|
296
303
|
}
|
|
297
304
|
interface SchemaOrgPersonOrOrganization {
|
|
298
305
|
'@type'?: 'Person' | 'Organization';
|
|
@@ -303,8 +310,30 @@ interface NutritionInformation {
|
|
|
303
310
|
[key: string]: string | number | null | undefined;
|
|
304
311
|
}
|
|
305
312
|
|
|
306
|
-
declare function toSchemaOrg(recipe: Recipe): SchemaOrgRecipe;
|
|
313
|
+
declare function toSchemaOrg(recipe: Recipe): SchemaOrgRecipe$1;
|
|
307
314
|
|
|
315
|
+
interface HowToStep {
|
|
316
|
+
'@type'?: 'HowToStep' | 'HowToSection' | string;
|
|
317
|
+
name?: string;
|
|
318
|
+
text?: string;
|
|
319
|
+
itemListElement?: Array<string | HowToStep>;
|
|
320
|
+
}
|
|
321
|
+
interface SchemaOrgRecipe {
|
|
322
|
+
'@type': string | string[];
|
|
323
|
+
name?: string;
|
|
324
|
+
description?: string;
|
|
325
|
+
image?: string | string[];
|
|
326
|
+
recipeIngredient?: string[];
|
|
327
|
+
recipeInstructions?: Array<string | HowToStep>;
|
|
328
|
+
recipeYield?: string | number;
|
|
329
|
+
prepTime?: string;
|
|
330
|
+
cookTime?: string;
|
|
331
|
+
totalTime?: string;
|
|
332
|
+
author?: unknown;
|
|
333
|
+
datePublished?: string;
|
|
334
|
+
aggregateRating?: unknown;
|
|
335
|
+
[key: string]: unknown;
|
|
336
|
+
}
|
|
308
337
|
interface FetchRequestInit {
|
|
309
338
|
headers?: Record<string, string>;
|
|
310
339
|
signal?: AbortSignal;
|
|
@@ -357,6 +386,33 @@ declare function scrapeRecipe(url: string, options?: ScrapeRecipeOptions): Promi
|
|
|
357
386
|
* @throws Error if no recipe is found
|
|
358
387
|
*/
|
|
359
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
|
+
declare function extractSchemaOrgRecipeFromHTML(html: string): SchemaOrgRecipe | null;
|
|
360
416
|
|
|
361
417
|
declare function normalizeIngredientInput(input: string): string;
|
|
362
418
|
declare function parseIngredient(text: string): ParsedIngredient;
|
|
@@ -376,4 +432,12 @@ declare function normalizeYield(text: string): string;
|
|
|
376
432
|
declare function parseYield(text: string): ParsedYield | null;
|
|
377
433
|
declare function formatYield(value: ParsedYield): string;
|
|
378
434
|
|
|
379
|
-
|
|
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;
|
|
442
|
+
|
|
443
|
+
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 SoustackInstruction, type SoustackRecipe, type StepTiming, type Storage, type StorageMethod, type StructuredTime, type Substitution, type Time, type Yield, extractRecipeFromHTML, extractSchemaOrgRecipeFromHTML, formatDuration, formatYield, fromSchemaOrg, normalizeImage, normalizeIngredientInput, normalizeYield, parseDuration, parseHumanDuration, parseIngredient, parseIngredientLine, parseIngredients, parseYield, scaleRecipe, scrapeRecipe, smartParseDuration, toSchemaOrg, validateRecipe };
|