@thg-altitude/schemaorg 1.0.33 → 1.0.34
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/package.json
CHANGED
|
@@ -118,7 +118,7 @@ function generateProductSchema() {
|
|
|
118
118
|
const weightChoice = variant.choices.find(c =>
|
|
119
119
|
c.optionKey === 'Weight' ||
|
|
120
120
|
(c.optionKey === 'Size' && c.title && (c.title.includes('kg') || c.title.includes('g') || c.title.includes('lb'))) ||
|
|
121
|
-
(c.title && (c.title.includes('kg') || c.title.includes('
|
|
121
|
+
(c.title && (c.title.includes('kg') || c.title.includes('lb') || /\d+\s*g\b/.test(c.title)))
|
|
122
122
|
);
|
|
123
123
|
if (weightChoice && weightChoice.title) attributes.push(weightChoice.title);
|
|
124
124
|
|
|
@@ -142,8 +142,8 @@ function generateProductSchema() {
|
|
|
142
142
|
// Color
|
|
143
143
|
const colorChoice = variant.choices.find(c => c.optionKey === 'Color' || c.optionKey === 'Colour' || c.colour);
|
|
144
144
|
if (colorChoice) {
|
|
145
|
-
if (colorChoice.
|
|
146
|
-
else if (colorChoice.
|
|
145
|
+
if (colorChoice.title) attributes.push(colorChoice.title);
|
|
146
|
+
else if (colorChoice.colour) attributes.push(colorChoice.colour);
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
// Material
|
|
@@ -162,20 +162,20 @@ function generateProductSchema() {
|
|
|
162
162
|
...(description && { description }),
|
|
163
163
|
...(imageUrl && { image: imageUrl }),
|
|
164
164
|
// Extract variant-specific properties from choices using correct schema.org properties
|
|
165
|
-
...(variant.choices && variant.choices.some(c => c.optionKey === 'Weight' || (c.title && (c.title.includes('kg') || c.title.includes('
|
|
166
|
-
weight: variant.choices.find(c => c.optionKey === 'Weight' || (c.title && (c.title.includes('kg') || c.title.includes('
|
|
165
|
+
...(variant.choices && variant.choices.some(c => c.optionKey === 'Weight' || (c.title && (c.title.includes('kg') || c.title.includes('lb') || /\d+\s*g\b/.test(c.title)))) && {
|
|
166
|
+
weight: variant.choices.find(c => c.optionKey === 'Weight' || (c.title && (c.title.includes('kg') || c.title.includes('lb') || /\d+\s*g\b/.test(c.title))))?.title
|
|
167
167
|
}),
|
|
168
168
|
...(variant.choices && variant.choices.some(c => c.optionKey === 'Size' && c.title && !c.title.includes('kg') && !c.title.includes('g') && !c.title.includes('lb')) && {
|
|
169
169
|
size: variant.choices.find(c => c.optionKey === 'Size' && c.title && !c.title.includes('kg') && !c.title.includes('g') && !c.title.includes('lb'))?.title
|
|
170
170
|
}),
|
|
171
171
|
...(variant.choices && variant.choices.some(c => c.optionKey === 'Color' || c.optionKey === 'Colour' || c.colour) && {
|
|
172
|
-
color: variant.choices.find(c => c.optionKey === 'Color' || c.optionKey === 'Colour'
|
|
173
|
-
variant.choices.find(c => c.optionKey === 'Color' || c.optionKey === 'Colour')?.
|
|
172
|
+
color: variant.choices.find(c => c.optionKey === 'Color' || c.optionKey === 'Colour')?.title ||
|
|
173
|
+
variant.choices.find(c => c.optionKey === 'Color' || c.optionKey === 'Colour' || c.colour)?.colour
|
|
174
174
|
}),
|
|
175
175
|
...(variant.choices && variant.choices.some(c => c.optionKey === 'Material') && {
|
|
176
176
|
material: variant.choices.find(c => c.optionKey === 'Material')?.title
|
|
177
177
|
}),
|
|
178
|
-
// Handle non-standard properties (amount,
|
|
178
|
+
// Handle non-standard properties (amount, flavour) as additionalProperty
|
|
179
179
|
...(() => {
|
|
180
180
|
const additionalProperties = [];
|
|
181
181
|
|
|
@@ -189,13 +189,13 @@ function generateProductSchema() {
|
|
|
189
189
|
});
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
//
|
|
193
|
-
const
|
|
194
|
-
if (
|
|
192
|
+
// Flavour (as additionalProperty since it doesn't exist in schema.org)
|
|
193
|
+
const flavourChoice = variant.choices?.find(c => c.optionKey === 'Flavour' || c.optionKey === 'Flavor' || c.optionKey === 'Taste');
|
|
194
|
+
if (flavourChoice?.title) {
|
|
195
195
|
additionalProperties.push({
|
|
196
196
|
"@type": "PropertyValue",
|
|
197
|
-
"name": "
|
|
198
|
-
"value":
|
|
197
|
+
"name": "flavour",
|
|
198
|
+
"value": flavourChoice.title
|
|
199
199
|
});
|
|
200
200
|
}
|
|
201
201
|
|
|
@@ -264,7 +264,7 @@ function generateProductSchema() {
|
|
|
264
264
|
const weightChoice = variant.choices.find(c =>
|
|
265
265
|
c.optionKey === 'Weight' ||
|
|
266
266
|
(c.optionKey === 'Size' && c.title && (c.title.includes('kg') || c.title.includes('g') || c.title.includes('lb'))) ||
|
|
267
|
-
(c.title && (c.title.includes('kg') || c.title.includes('
|
|
267
|
+
(c.title && (c.title.includes('kg') || c.title.includes('lb') || /\d+\s*g\b/.test(c.title)))
|
|
268
268
|
);
|
|
269
269
|
if (weightChoice && weightChoice.title) attributes.push(weightChoice.title);
|
|
270
270
|
|
|
@@ -288,8 +288,8 @@ function generateProductSchema() {
|
|
|
288
288
|
// Color
|
|
289
289
|
const colorChoice = variant.choices.find(c => c.optionKey === 'Color' || c.optionKey === 'Colour' || c.colour);
|
|
290
290
|
if (colorChoice) {
|
|
291
|
-
if (colorChoice.
|
|
292
|
-
else if (colorChoice.
|
|
291
|
+
if (colorChoice.title) attributes.push(colorChoice.title);
|
|
292
|
+
else if (colorChoice.colour) attributes.push(colorChoice.colour);
|
|
293
293
|
}
|
|
294
294
|
|
|
295
295
|
// Material
|
|
@@ -358,7 +358,7 @@ function generateProductSchema() {
|
|
|
358
358
|
const variesBy = [];
|
|
359
359
|
|
|
360
360
|
// Check what attributes exist across variants based on choices using correct schema.org properties
|
|
361
|
-
if (variants.some(v => v.choices && v.choices.some(c => c.optionKey === 'Weight' || (c.title && (c.title.includes('kg') || c.title.includes('
|
|
361
|
+
if (variants.some(v => v.choices && v.choices.some(c => c.optionKey === 'Weight' || (c.title && (c.title.includes('kg') || c.title.includes('lb') || /\d+\s*g\b/.test(c.title)))))) {
|
|
362
362
|
variesBy.push("https://schema.org/weight");
|
|
363
363
|
}
|
|
364
364
|
if (variants.some(v => v.choices && v.choices.some(c => c.optionKey === 'Size' && c.title && !c.title.includes('kg') && !c.title.includes('g') && !c.title.includes('lb')))) {
|
|
@@ -370,10 +370,11 @@ function generateProductSchema() {
|
|
|
370
370
|
if (variants.some(v => v.choices && v.choices.some(c => c.optionKey === 'Material'))) {
|
|
371
371
|
variesBy.push("https://schema.org/material");
|
|
372
372
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
373
|
+
// For non-standard properties like amount and flavour, use additionalProperty
|
|
374
|
+
if (variants.some(v => v.choices && v.choices.some(c => c.optionKey === 'Amount'))) {
|
|
375
|
+
variesBy.push("https://schema.org/additionalProperty");
|
|
376
|
+
}
|
|
377
|
+
if (variants.some(v => v.choices && v.choices.some(c => c.optionKey === 'Flavour' || c.optionKey === 'Flavor' || c.optionKey === 'Taste'))) {
|
|
377
378
|
variesBy.push("https://schema.org/additionalProperty");
|
|
378
379
|
}
|
|
379
380
|
|
|
@@ -438,6 +439,22 @@ function generateProductSchema() {
|
|
|
438
439
|
"value": gender
|
|
439
440
|
});
|
|
440
441
|
}
|
|
442
|
+
|
|
443
|
+
// Add flavour as additionalProperty for ProductGroup level
|
|
444
|
+
const flavourValues = variants?.map(v =>
|
|
445
|
+
v.choices?.find(c => c.optionKey === 'Flavour' || c.optionKey === 'Flavor' || c.optionKey === 'Taste')?.title
|
|
446
|
+
).filter(Boolean);
|
|
447
|
+
|
|
448
|
+
if (flavourValues && flavourValues.length > 0) {
|
|
449
|
+
// If multiple unique flavours, list them all; if single flavour, just that one
|
|
450
|
+
const uniqueFlavours = [...new Set(flavourValues)];
|
|
451
|
+
additionalProperties.push({
|
|
452
|
+
"@type": "PropertyValue",
|
|
453
|
+
"name": "flavour",
|
|
454
|
+
"value": uniqueFlavours.length === 1 ? uniqueFlavours[0] : uniqueFlavours.join(', ')
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
|
|
441
458
|
return additionalProperties.length > 0 ? { additionalProperty: additionalProperties } : {};
|
|
442
459
|
})(),
|
|
443
460
|
};
|
|
@@ -504,6 +521,22 @@ function generateProductSchema() {
|
|
|
504
521
|
"value": gender
|
|
505
522
|
});
|
|
506
523
|
}
|
|
524
|
+
|
|
525
|
+
// Add flavour as additionalProperty for single product
|
|
526
|
+
const flavourValues = variants?.map(v =>
|
|
527
|
+
v.choices?.find(c => c.optionKey === 'Flavour' || c.optionKey === 'Flavor' || c.optionKey === 'Taste')?.title
|
|
528
|
+
).filter(Boolean);
|
|
529
|
+
|
|
530
|
+
if (flavourValues && flavourValues.length > 0) {
|
|
531
|
+
// If multiple unique flavours, list them all; if single flavour, just that one
|
|
532
|
+
const uniqueFlavours = [...new Set(flavourValues)];
|
|
533
|
+
additionalProperties.push({
|
|
534
|
+
"@type": "PropertyValue",
|
|
535
|
+
"name": "flavour",
|
|
536
|
+
"value": uniqueFlavours.length === 1 ? uniqueFlavours[0] : uniqueFlavours.join(', ')
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
|
|
507
540
|
return additionalProperties.length > 0 ? { additionalProperty: additionalProperties } : {};
|
|
508
541
|
})(),
|
|
509
542
|
...(offersArray.length > 0 && { offers: offersArray }),
|
|
@@ -84,7 +84,7 @@ if (hasMultipleVariants) {
|
|
|
84
84
|
if (variant.material) variantObj.material = variant.material;
|
|
85
85
|
if (variant.weight) variantObj.weight = variant.weight;
|
|
86
86
|
|
|
87
|
-
// Handle
|
|
87
|
+
// Handle non-standard properties as additionalProperty
|
|
88
88
|
const additionalProperties = [];
|
|
89
89
|
|
|
90
90
|
if (variant.amount) {
|
|
@@ -95,16 +95,15 @@ if (hasMultipleVariants) {
|
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
// Handle
|
|
98
|
+
// Handle flavour as additionalProperty since it doesn't exist in schema.org
|
|
99
99
|
let flavorValue = null;
|
|
100
100
|
if (variant.flavor) flavorValue = variant.flavor;
|
|
101
101
|
else if (variant.flavour) flavorValue = variant.flavour;
|
|
102
102
|
else if (variant.taste) flavorValue = variant.taste;
|
|
103
|
-
|
|
104
103
|
if (flavorValue) {
|
|
105
104
|
additionalProperties.push({
|
|
106
105
|
"@type": "PropertyValue",
|
|
107
|
-
"name": "
|
|
106
|
+
"name": "flavour",
|
|
108
107
|
"value": flavorValue
|
|
109
108
|
});
|
|
110
109
|
}
|
|
@@ -205,16 +204,12 @@ if (hasMultipleVariants) {
|
|
|
205
204
|
if (Astro.props.variants.some(v => v && v.color)) variesBy.push("https://schema.org/color");
|
|
206
205
|
if (Astro.props.variants.some(v => v && v.material)) variesBy.push("https://schema.org/material");
|
|
207
206
|
|
|
208
|
-
// For non-standard properties like amount and
|
|
209
|
-
// but still include them in variesBy for semantic meaning
|
|
207
|
+
// For non-standard properties like amount and flavour, we use additionalProperty
|
|
210
208
|
if (Astro.props.variants.some(v => v && v.amount)) variesBy.push("https://schema.org/additionalProperty");
|
|
211
209
|
|
|
212
|
-
// Check for flavor with multiple possible property names
|
|
210
|
+
// Check for flavor with multiple possible property names - treat as additionalProperty
|
|
213
211
|
if (Astro.props.variants.some(v => v && (v.flavor || v.flavour || v.taste))) {
|
|
214
|
-
|
|
215
|
-
if (!variesBy.includes("https://schema.org/additionalProperty")) {
|
|
216
|
-
variesBy.push("https://schema.org/additionalProperty");
|
|
217
|
-
}
|
|
212
|
+
variesBy.push("https://schema.org/additionalProperty");
|
|
218
213
|
}
|
|
219
214
|
}
|
|
220
215
|
|
|
@@ -270,6 +265,27 @@ if (hasMultipleVariants) {
|
|
|
270
265
|
"value": Astro.props.gender
|
|
271
266
|
});
|
|
272
267
|
}
|
|
268
|
+
|
|
269
|
+
// Add flavour as additionalProperty for ProductGroup level
|
|
270
|
+
if (Array.isArray(Astro.props.variants)) {
|
|
271
|
+
const flavourValues = Astro.props.variants.map(v => {
|
|
272
|
+
if (v && typeof v === 'object') {
|
|
273
|
+
return v.flavor || v.flavour || v.taste;
|
|
274
|
+
}
|
|
275
|
+
return null;
|
|
276
|
+
}).filter(Boolean);
|
|
277
|
+
|
|
278
|
+
if (flavourValues.length > 0) {
|
|
279
|
+
// If multiple unique flavours, list them all; if single flavour, just that one
|
|
280
|
+
const uniqueFlavours = [...new Set(flavourValues)];
|
|
281
|
+
additionalProperties.push({
|
|
282
|
+
"@type": "PropertyValue",
|
|
283
|
+
"name": "flavour",
|
|
284
|
+
"value": uniqueFlavours.length === 1 ? uniqueFlavours[0] : uniqueFlavours.join(', ')
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
273
289
|
if (additionalProperties.length > 0) {
|
|
274
290
|
schema.additionalProperty = additionalProperties;
|
|
275
291
|
}
|
|
@@ -327,6 +343,27 @@ if (hasMultipleVariants) {
|
|
|
327
343
|
"value": Astro.props.gender
|
|
328
344
|
});
|
|
329
345
|
}
|
|
346
|
+
|
|
347
|
+
// Add flavour as additionalProperty for single product
|
|
348
|
+
if (Array.isArray(Astro.props.variants)) {
|
|
349
|
+
const flavourValues = Astro.props.variants.map(v => {
|
|
350
|
+
if (v && typeof v === 'object') {
|
|
351
|
+
return v.flavor || v.flavour || v.taste;
|
|
352
|
+
}
|
|
353
|
+
return null;
|
|
354
|
+
}).filter(Boolean);
|
|
355
|
+
|
|
356
|
+
if (flavourValues.length > 0) {
|
|
357
|
+
// If multiple unique flavours, list them all; if single flavour, just that one
|
|
358
|
+
const uniqueFlavours = [...new Set(flavourValues)];
|
|
359
|
+
additionalProperties.push({
|
|
360
|
+
"@type": "PropertyValue",
|
|
361
|
+
"name": "flavour",
|
|
362
|
+
"value": uniqueFlavours.length === 1 ? uniqueFlavours[0] : uniqueFlavours.join(', ')
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
330
367
|
if (additionalProperties.length > 0) {
|
|
331
368
|
schema.additionalProperty = additionalProperties;
|
|
332
369
|
}
|