@unhead/schema-org 2.1.9 → 3.0.0-beta.10
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 +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.mjs +2 -44
- package/dist/react.d.mts +3 -3
- package/dist/react.d.ts +3 -3
- package/dist/react.mjs +3 -3
- package/dist/shared/schema-org.BS2Q1uTx.d.mts +11 -0
- package/dist/shared/{schema-org.UT1u1UYq.d.mts → schema-org.C1OXVKVP.d.ts} +142 -48
- package/dist/shared/schema-org.C7IeLKiX.d.ts +11 -0
- package/dist/shared/{schema-org.CFcsqFfN.d.mts → schema-org.CX_95Tmq.d.mts} +2 -22
- package/dist/shared/{schema-org.CFcsqFfN.d.ts → schema-org.CX_95Tmq.d.ts} +2 -22
- package/dist/shared/{schema-org.CAKsqzbX.d.ts → schema-org.Cxijls86.d.mts} +142 -48
- package/dist/shared/schema-org.DvWGLdBv.mjs +1932 -0
- package/dist/solid-js.d.mts +3 -3
- package/dist/solid-js.d.ts +3 -3
- package/dist/solid-js.mjs +3 -3
- package/dist/svelte.d.mts +3 -3
- package/dist/svelte.d.ts +3 -3
- package/dist/svelte.mjs +3 -3
- package/dist/vue.d.mts +38 -38
- package/dist/vue.d.ts +38 -38
- package/dist/vue.mjs +47 -43
- package/package.json +11 -11
- package/dist/chunks/index.mjs +0 -23
- package/dist/chunks/index10.mjs +0 -63
- package/dist/chunks/index11.mjs +0 -35
- package/dist/chunks/index12.mjs +0 -48
- package/dist/chunks/index13.mjs +0 -36
- package/dist/chunks/index14.mjs +0 -25
- package/dist/chunks/index15.mjs +0 -37
- package/dist/chunks/index16.mjs +0 -27
- package/dist/chunks/index17.mjs +0 -34
- package/dist/chunks/index18.mjs +0 -32
- package/dist/chunks/index19.mjs +0 -31
- package/dist/chunks/index2.mjs +0 -12
- package/dist/chunks/index20.mjs +0 -31
- package/dist/chunks/index21.mjs +0 -30
- package/dist/chunks/index22.mjs +0 -30
- package/dist/chunks/index23.mjs +0 -82
- package/dist/chunks/index24.mjs +0 -14
- package/dist/chunks/index25.mjs +0 -33
- package/dist/chunks/index26.mjs +0 -31
- package/dist/chunks/index27.mjs +0 -29
- package/dist/chunks/index28.mjs +0 -12
- package/dist/chunks/index29.mjs +0 -46
- package/dist/chunks/index3.mjs +0 -317
- package/dist/chunks/index30.mjs +0 -53
- package/dist/chunks/index31.mjs +0 -41
- package/dist/chunks/index32.mjs +0 -26
- package/dist/chunks/index33.mjs +0 -47
- package/dist/chunks/index34.mjs +0 -29
- package/dist/chunks/index35.mjs +0 -34
- package/dist/chunks/index36.mjs +0 -33
- package/dist/chunks/index37.mjs +0 -34
- package/dist/chunks/index38.mjs +0 -51
- package/dist/chunks/index39.mjs +0 -17
- package/dist/chunks/index4.mjs +0 -54
- package/dist/chunks/index40.mjs +0 -29
- package/dist/chunks/index5.mjs +0 -31
- package/dist/chunks/index6.mjs +0 -29
- package/dist/chunks/index7.mjs +0 -35
- package/dist/chunks/index8.mjs +0 -18
- package/dist/chunks/index9.mjs +0 -20
- package/dist/shared/schema-org.B9Q-o8S0.mjs +0 -877
- package/dist/shared/schema-org.BR4WcSqZ.d.ts +0 -21
- package/dist/shared/schema-org.CrNDsWck.mjs +0 -19
- package/dist/shared/schema-org.oFHFm6my.d.mts +0 -21
- package/dist/shared/schema-org.zHUqdMMo.mjs +0 -27
|
@@ -0,0 +1,1932 @@
|
|
|
1
|
+
import { hasProtocol, withBase, withoutTrailingSlash, hasTrailingSlash, withTrailingSlash, joinURL } from 'ufo';
|
|
2
|
+
import { defineHeadPlugin, TemplateParamsPlugin } from 'unhead/plugins';
|
|
3
|
+
import { processTemplateParams } from 'unhead/utils';
|
|
4
|
+
|
|
5
|
+
function defineSchemaOrgResolver(schema) {
|
|
6
|
+
return schema;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function idReference(node) {
|
|
10
|
+
return {
|
|
11
|
+
"@id": typeof node !== "string" ? node["@id"] : node
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function resolvableDateToDate(val) {
|
|
15
|
+
try {
|
|
16
|
+
const date = val instanceof Date ? val : new Date(Date.parse(val));
|
|
17
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
18
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
19
|
+
return `${date.getFullYear()}-${month}-${day}`;
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
return typeof val === "string" ? val : val.toString();
|
|
23
|
+
}
|
|
24
|
+
const IS_VALID_W3C_DATE = [
|
|
25
|
+
/(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/,
|
|
26
|
+
/^\d{4}-[01]\d-[0-3]\d$/,
|
|
27
|
+
/^\d{4}-[01]\d$/,
|
|
28
|
+
/^\d{4}$/
|
|
29
|
+
];
|
|
30
|
+
function isValidW3CDate(d) {
|
|
31
|
+
return IS_VALID_W3C_DATE.some((r) => r.test(d));
|
|
32
|
+
}
|
|
33
|
+
function resolvableDateToIso(val) {
|
|
34
|
+
if (!val)
|
|
35
|
+
return val;
|
|
36
|
+
try {
|
|
37
|
+
if (val instanceof Date)
|
|
38
|
+
return val.toISOString();
|
|
39
|
+
else if (isValidW3CDate(val))
|
|
40
|
+
return val;
|
|
41
|
+
else
|
|
42
|
+
return new Date(Date.parse(val)).toISOString();
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
return typeof val === "string" ? val : val.toString();
|
|
46
|
+
}
|
|
47
|
+
const IdentityId = "#identity";
|
|
48
|
+
function setIfEmpty(node, field, value) {
|
|
49
|
+
if (!node?.[field] && value)
|
|
50
|
+
node[field] = value;
|
|
51
|
+
}
|
|
52
|
+
function asArray(input) {
|
|
53
|
+
return Array.isArray(input) ? input : [input];
|
|
54
|
+
}
|
|
55
|
+
function dedupeMerge(node, field, value) {
|
|
56
|
+
const data = new Set(asArray(node[field]));
|
|
57
|
+
data.add(value);
|
|
58
|
+
node[field] = [...data].filter(Boolean);
|
|
59
|
+
}
|
|
60
|
+
function prefixId(url, id) {
|
|
61
|
+
if (hasProtocol(id))
|
|
62
|
+
return id;
|
|
63
|
+
if (!id.includes("#"))
|
|
64
|
+
id = `#${id}`;
|
|
65
|
+
return `${url || ""}${id}`;
|
|
66
|
+
}
|
|
67
|
+
function trimLength(val, length) {
|
|
68
|
+
if (!val)
|
|
69
|
+
return val;
|
|
70
|
+
if (val.length > length) {
|
|
71
|
+
const trimmedString = val.substring(0, length);
|
|
72
|
+
return trimmedString.substring(0, Math.min(trimmedString.length, trimmedString.lastIndexOf(" ")));
|
|
73
|
+
}
|
|
74
|
+
return val;
|
|
75
|
+
}
|
|
76
|
+
function resolveDefaultType(node, defaultType) {
|
|
77
|
+
const val = node["@type"];
|
|
78
|
+
if (val === defaultType)
|
|
79
|
+
return;
|
|
80
|
+
if (typeof val === "string" && typeof defaultType === "string") {
|
|
81
|
+
if (val !== defaultType)
|
|
82
|
+
node["@type"] = [defaultType, val];
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const types = new Set(asArray(defaultType));
|
|
86
|
+
for (const t of asArray(val))
|
|
87
|
+
types.add(t);
|
|
88
|
+
node["@type"] = types.size === 1 ? val : [...types];
|
|
89
|
+
}
|
|
90
|
+
function resolveWithBase(base, urlOrPath) {
|
|
91
|
+
if (!urlOrPath || hasProtocol(urlOrPath) || urlOrPath[0] !== "/" && urlOrPath[0] !== "#")
|
|
92
|
+
return urlOrPath;
|
|
93
|
+
return withBase(urlOrPath, base);
|
|
94
|
+
}
|
|
95
|
+
function resolveAsGraphKey(key) {
|
|
96
|
+
if (!key)
|
|
97
|
+
return key;
|
|
98
|
+
return key.substring(key.lastIndexOf("#"));
|
|
99
|
+
}
|
|
100
|
+
function stripEmptyProperties(obj) {
|
|
101
|
+
for (const k in obj) {
|
|
102
|
+
if (!Object.hasOwn(obj, k))
|
|
103
|
+
continue;
|
|
104
|
+
const v = obj[k];
|
|
105
|
+
if (v === "" || v === null || v === void 0) {
|
|
106
|
+
delete obj[k];
|
|
107
|
+
} else if (typeof v === "object" && v !== null) {
|
|
108
|
+
if (v.__v_isReadonly || v.__v_isRef)
|
|
109
|
+
continue;
|
|
110
|
+
stripEmptyProperties(v);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return obj;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const quantitativeValueResolver = defineSchemaOrgResolver({
|
|
117
|
+
cast(node) {
|
|
118
|
+
if (typeof node === "number") {
|
|
119
|
+
return {
|
|
120
|
+
value: node
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return node;
|
|
124
|
+
},
|
|
125
|
+
defaults: {
|
|
126
|
+
"@type": "QuantitativeValue"
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
const monetaryAmountResolver = defineSchemaOrgResolver({
|
|
130
|
+
defaults: {
|
|
131
|
+
"@type": "MonetaryAmount"
|
|
132
|
+
},
|
|
133
|
+
resolve(node, ctx) {
|
|
134
|
+
if (typeof node.value !== "number")
|
|
135
|
+
node.value = resolveRelation(node.value, ctx, quantitativeValueResolver);
|
|
136
|
+
return node;
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const merchantReturnPolicyResolver = defineSchemaOrgResolver({
|
|
141
|
+
defaults: {
|
|
142
|
+
"@type": "MerchantReturnPolicy"
|
|
143
|
+
},
|
|
144
|
+
resolve(node, ctx) {
|
|
145
|
+
if (node.returnPolicyCategory)
|
|
146
|
+
node.returnPolicyCategory = withBase(node.returnPolicyCategory, "https://schema.org/");
|
|
147
|
+
if (node.returnFees)
|
|
148
|
+
node.returnFees = withBase(node.returnFees, "https://schema.org/");
|
|
149
|
+
if (node.returnMethod)
|
|
150
|
+
node.returnMethod = withBase(node.returnMethod, "https://schema.org/");
|
|
151
|
+
node.returnShippingFeesAmount = resolveRelation(node.returnShippingFeesAmount, ctx, monetaryAmountResolver);
|
|
152
|
+
return node;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const definedRegionResolver = defineSchemaOrgResolver({
|
|
157
|
+
defaults: {
|
|
158
|
+
"@type": "DefinedRegion"
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const shippingDeliveryTimeResolver = defineSchemaOrgResolver({
|
|
163
|
+
defaults: {
|
|
164
|
+
"@type": "ShippingDeliveryTime"
|
|
165
|
+
},
|
|
166
|
+
resolve(node, ctx) {
|
|
167
|
+
node.handlingTime = resolveRelation(node.handlingTime, ctx, quantitativeValueResolver);
|
|
168
|
+
node.transitTime = resolveRelation(node.transitTime, ctx, quantitativeValueResolver);
|
|
169
|
+
return node;
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const offerShippingDetailsResolver = defineSchemaOrgResolver({
|
|
174
|
+
defaults: {
|
|
175
|
+
"@type": "OfferShippingDetails"
|
|
176
|
+
},
|
|
177
|
+
resolve(node, ctx) {
|
|
178
|
+
node.deliveryTime = resolveRelation(node.deliveryTime, ctx, shippingDeliveryTimeResolver);
|
|
179
|
+
node.shippingDestination = resolveRelation(node.shippingDestination, ctx, definedRegionResolver);
|
|
180
|
+
node.shippingRate = resolveRelation(node.shippingRate, ctx, monetaryAmountResolver);
|
|
181
|
+
return node;
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const offerResolver = defineSchemaOrgResolver({
|
|
186
|
+
cast(node) {
|
|
187
|
+
if (typeof node === "number" || typeof node === "string") {
|
|
188
|
+
return {
|
|
189
|
+
price: node
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
return node;
|
|
193
|
+
},
|
|
194
|
+
defaults: {
|
|
195
|
+
"@type": "Offer",
|
|
196
|
+
"availability": "InStock"
|
|
197
|
+
},
|
|
198
|
+
resolve(node, ctx) {
|
|
199
|
+
setIfEmpty(node, "priceCurrency", ctx.meta.currency);
|
|
200
|
+
setIfEmpty(node, "priceValidUntil", new Date(Date.UTC((/* @__PURE__ */ new Date()).getFullYear() + 1, 12, -1, 0, 0, 0)));
|
|
201
|
+
if (node.url)
|
|
202
|
+
resolveWithBase(ctx.meta.host, node.url);
|
|
203
|
+
if (node.availability)
|
|
204
|
+
node.availability = withBase(node.availability, "https://schema.org/");
|
|
205
|
+
if (node.itemCondition)
|
|
206
|
+
node.itemCondition = withBase(node.itemCondition, "https://schema.org/");
|
|
207
|
+
if (node.priceValidUntil)
|
|
208
|
+
node.priceValidUntil = resolvableDateToIso(node.priceValidUntil);
|
|
209
|
+
node.hasMerchantReturnPolicy = resolveRelation(node.hasMerchantReturnPolicy, ctx, merchantReturnPolicyResolver);
|
|
210
|
+
node.shippingDetails = resolveRelation(node.shippingDetails, ctx, offerShippingDetailsResolver);
|
|
211
|
+
return node;
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
const aggregateOfferResolver = defineSchemaOrgResolver({
|
|
216
|
+
defaults: {
|
|
217
|
+
"@type": "AggregateOffer"
|
|
218
|
+
},
|
|
219
|
+
inheritMeta: [
|
|
220
|
+
{ meta: "currency", key: "priceCurrency" }
|
|
221
|
+
],
|
|
222
|
+
resolve(node, ctx) {
|
|
223
|
+
node.offers = resolveRelation(node.offers, ctx, offerResolver);
|
|
224
|
+
if (node.offers)
|
|
225
|
+
setIfEmpty(node, "offerCount", asArray(node.offers).length);
|
|
226
|
+
return node;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
const aggregateRatingResolver = defineSchemaOrgResolver({
|
|
231
|
+
defaults: {
|
|
232
|
+
"@type": "AggregateRating"
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
const listItemResolver = defineSchemaOrgResolver({
|
|
237
|
+
cast(node) {
|
|
238
|
+
if (typeof node === "string") {
|
|
239
|
+
node = {
|
|
240
|
+
name: node
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
return node;
|
|
244
|
+
},
|
|
245
|
+
defaults: {
|
|
246
|
+
"@type": "ListItem"
|
|
247
|
+
},
|
|
248
|
+
resolve(node, ctx) {
|
|
249
|
+
if (typeof node.item === "string")
|
|
250
|
+
node.item = resolveWithBase(ctx.meta.host, node.item);
|
|
251
|
+
else if (typeof node.item === "object")
|
|
252
|
+
node.item = resolveRelation(node.item, ctx);
|
|
253
|
+
return node;
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
const PrimaryBreadcrumbId = "#breadcrumb";
|
|
258
|
+
const breadcrumbResolver = defineSchemaOrgResolver({
|
|
259
|
+
defaults: {
|
|
260
|
+
"@type": "BreadcrumbList"
|
|
261
|
+
},
|
|
262
|
+
idPrefix: ["url", PrimaryBreadcrumbId],
|
|
263
|
+
resolve(breadcrumb, ctx) {
|
|
264
|
+
if (breadcrumb.itemListElement) {
|
|
265
|
+
let index = 1;
|
|
266
|
+
breadcrumb.itemListElement = resolveRelation(breadcrumb.itemListElement, ctx, listItemResolver, {
|
|
267
|
+
array: true,
|
|
268
|
+
afterResolve(node) {
|
|
269
|
+
setIfEmpty(node, "position", index++);
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
return breadcrumb;
|
|
274
|
+
},
|
|
275
|
+
resolveRootNode(node, { find }) {
|
|
276
|
+
const webPage = find(PrimaryWebPageId);
|
|
277
|
+
if (webPage)
|
|
278
|
+
setIfEmpty(webPage, "breadcrumb", idReference(node));
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
const imageResolver = defineSchemaOrgResolver({
|
|
283
|
+
alias: "image",
|
|
284
|
+
cast(input) {
|
|
285
|
+
if (typeof input === "string") {
|
|
286
|
+
input = {
|
|
287
|
+
url: input
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
return input;
|
|
291
|
+
},
|
|
292
|
+
defaults: {
|
|
293
|
+
"@type": "ImageObject"
|
|
294
|
+
},
|
|
295
|
+
inheritMeta: [
|
|
296
|
+
// @todo possibly only do if there's a caption
|
|
297
|
+
"inLanguage"
|
|
298
|
+
],
|
|
299
|
+
idPrefix: "host",
|
|
300
|
+
resolve(image, { meta }) {
|
|
301
|
+
image.url = resolveWithBase(meta.host, image.url);
|
|
302
|
+
setIfEmpty(image, "contentUrl", image.url);
|
|
303
|
+
if (image.height && !image.width)
|
|
304
|
+
delete image.height;
|
|
305
|
+
if (image.width && !image.height)
|
|
306
|
+
delete image.width;
|
|
307
|
+
return image;
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
const addressResolver = defineSchemaOrgResolver({
|
|
312
|
+
defaults: {
|
|
313
|
+
"@type": "PostalAddress"
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
const searchActionResolver = defineSchemaOrgResolver({
|
|
318
|
+
defaults: {
|
|
319
|
+
"@type": "SearchAction",
|
|
320
|
+
"target": {
|
|
321
|
+
"@type": "EntryPoint"
|
|
322
|
+
},
|
|
323
|
+
"query-input": {
|
|
324
|
+
"@type": "PropertyValueSpecification",
|
|
325
|
+
"valueRequired": true,
|
|
326
|
+
"valueName": "search_term_string"
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
resolve(node, ctx) {
|
|
330
|
+
if (typeof node.target === "string") {
|
|
331
|
+
node.target = {
|
|
332
|
+
"@type": "EntryPoint",
|
|
333
|
+
"urlTemplate": resolveWithBase(ctx.meta.host, node.target)
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
return node;
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
const PrimaryWebSiteId = "#website";
|
|
341
|
+
const webSiteResolver = defineSchemaOrgResolver({
|
|
342
|
+
defaults: {
|
|
343
|
+
"@type": "WebSite"
|
|
344
|
+
},
|
|
345
|
+
inheritMeta: [
|
|
346
|
+
"inLanguage",
|
|
347
|
+
{ meta: "host", key: "url" }
|
|
348
|
+
],
|
|
349
|
+
idPrefix: ["host", PrimaryWebSiteId],
|
|
350
|
+
resolve(node, ctx) {
|
|
351
|
+
node.potentialAction = resolveRelation(node.potentialAction, ctx, searchActionResolver, {
|
|
352
|
+
array: true
|
|
353
|
+
});
|
|
354
|
+
node.publisher = resolveRelation(node.publisher, ctx);
|
|
355
|
+
node.dateModified = resolvableDateToIso(node.dateModified);
|
|
356
|
+
node.datePublished = resolvableDateToIso(node.datePublished);
|
|
357
|
+
return node;
|
|
358
|
+
},
|
|
359
|
+
resolveRootNode(node, { find }) {
|
|
360
|
+
if (resolveAsGraphKey(node["@id"]) === PrimaryWebSiteId) {
|
|
361
|
+
const identity = find(IdentityId);
|
|
362
|
+
if (identity)
|
|
363
|
+
setIfEmpty(node, "publisher", idReference(identity));
|
|
364
|
+
const webPage = find(PrimaryWebPageId);
|
|
365
|
+
if (webPage)
|
|
366
|
+
setIfEmpty(webPage, "isPartOf", idReference(node));
|
|
367
|
+
}
|
|
368
|
+
return node;
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
const organizationResolver = defineSchemaOrgResolver({
|
|
373
|
+
defaults: {
|
|
374
|
+
"@type": "Organization"
|
|
375
|
+
},
|
|
376
|
+
idPrefix: ["host", IdentityId],
|
|
377
|
+
inheritMeta: [
|
|
378
|
+
{ meta: "host", key: "url" }
|
|
379
|
+
],
|
|
380
|
+
resolve(node, ctx) {
|
|
381
|
+
resolveDefaultType(node, "Organization");
|
|
382
|
+
node.address = resolveRelation(node.address, ctx, addressResolver);
|
|
383
|
+
return node;
|
|
384
|
+
},
|
|
385
|
+
resolveRootNode(node, ctx) {
|
|
386
|
+
const isIdentity = resolveAsGraphKey(node["@id"]) === IdentityId;
|
|
387
|
+
const webPage = ctx.find(PrimaryWebPageId);
|
|
388
|
+
if (node.logo && isIdentity) {
|
|
389
|
+
if (!ctx.find("#organization")) {
|
|
390
|
+
const logoNode = resolveRelation(node.logo, ctx, imageResolver, {
|
|
391
|
+
root: true,
|
|
392
|
+
afterResolve(logo) {
|
|
393
|
+
logo["@id"] = prefixId(ctx.meta.host, "#logo");
|
|
394
|
+
setIfEmpty(logo, "caption", node.name);
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
if (webPage && logoNode)
|
|
398
|
+
setIfEmpty(webPage, "primaryImageOfPage", idReference(logoNode));
|
|
399
|
+
ctx.nodes.push({
|
|
400
|
+
// we want to make a simple node that has the essentials, this will allow parent nodes to inject
|
|
401
|
+
// as well without inserting invalid data (i.e LocalBusiness operatingHours)
|
|
402
|
+
"@type": "Organization",
|
|
403
|
+
"name": node.name,
|
|
404
|
+
"url": node.url,
|
|
405
|
+
"sameAs": node.sameAs,
|
|
406
|
+
// 'image': idReference(logoNode),
|
|
407
|
+
"address": node.address,
|
|
408
|
+
// needs to be a URL
|
|
409
|
+
"logo": resolveRelation(node.logo, ctx, imageResolver, { root: false }).url,
|
|
410
|
+
"_priority": -1,
|
|
411
|
+
"@id": prefixId(ctx.meta.host, "#organization")
|
|
412
|
+
// avoid the id so nothing can link to it
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
delete node.logo;
|
|
416
|
+
}
|
|
417
|
+
if (isIdentity && webPage)
|
|
418
|
+
setIfEmpty(webPage, "about", idReference(node));
|
|
419
|
+
const webSite = ctx.find(PrimaryWebSiteId);
|
|
420
|
+
if (webSite)
|
|
421
|
+
setIfEmpty(webSite, "publisher", idReference(node));
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
const readActionResolver = defineSchemaOrgResolver({
|
|
426
|
+
defaults: {
|
|
427
|
+
"@type": "ReadAction"
|
|
428
|
+
},
|
|
429
|
+
resolve(node, ctx) {
|
|
430
|
+
if (!node.target.includes(ctx.meta.url))
|
|
431
|
+
node.target.unshift(ctx.meta.url);
|
|
432
|
+
return node;
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
const PrimaryWebPageId = "#webpage";
|
|
437
|
+
const webPageResolver = defineSchemaOrgResolver({
|
|
438
|
+
defaults({ meta }) {
|
|
439
|
+
const endPath = withoutTrailingSlash(meta.url.substring(meta.url.lastIndexOf("/") + 1));
|
|
440
|
+
let type = "WebPage";
|
|
441
|
+
switch (endPath) {
|
|
442
|
+
case "about":
|
|
443
|
+
case "about-us":
|
|
444
|
+
type = "AboutPage";
|
|
445
|
+
break;
|
|
446
|
+
case "search":
|
|
447
|
+
type = "SearchResultsPage";
|
|
448
|
+
break;
|
|
449
|
+
case "checkout":
|
|
450
|
+
type = "CheckoutPage";
|
|
451
|
+
break;
|
|
452
|
+
case "contact":
|
|
453
|
+
case "get-in-touch":
|
|
454
|
+
case "contact-us":
|
|
455
|
+
type = "ContactPage";
|
|
456
|
+
break;
|
|
457
|
+
case "faq":
|
|
458
|
+
type = "FAQPage";
|
|
459
|
+
break;
|
|
460
|
+
}
|
|
461
|
+
const defaults = {
|
|
462
|
+
"@type": type
|
|
463
|
+
};
|
|
464
|
+
return defaults;
|
|
465
|
+
},
|
|
466
|
+
idPrefix: ["url", PrimaryWebPageId],
|
|
467
|
+
inheritMeta: [
|
|
468
|
+
{ meta: "title", key: "name" },
|
|
469
|
+
"description",
|
|
470
|
+
"datePublished",
|
|
471
|
+
"dateModified",
|
|
472
|
+
"url"
|
|
473
|
+
],
|
|
474
|
+
resolve(node, ctx) {
|
|
475
|
+
node.dateModified = resolvableDateToIso(node.dateModified);
|
|
476
|
+
node.datePublished = resolvableDateToIso(node.datePublished);
|
|
477
|
+
resolveDefaultType(node, "WebPage");
|
|
478
|
+
node.about = resolveRelation(node.about, ctx, organizationResolver);
|
|
479
|
+
node.breadcrumb = resolveRelation(node.breadcrumb, ctx, breadcrumbResolver);
|
|
480
|
+
node.author = resolveRelation(node.author, ctx, personResolver);
|
|
481
|
+
node.primaryImageOfPage = resolveRelation(node.primaryImageOfPage, ctx, imageResolver);
|
|
482
|
+
node.potentialAction = resolveRelation(node.potentialAction, ctx, readActionResolver);
|
|
483
|
+
if (node["@type"] === "WebPage" && ctx.meta.url) {
|
|
484
|
+
setIfEmpty(node, "potentialAction", [
|
|
485
|
+
{
|
|
486
|
+
"@type": "ReadAction",
|
|
487
|
+
"target": [ctx.meta.url]
|
|
488
|
+
}
|
|
489
|
+
]);
|
|
490
|
+
}
|
|
491
|
+
return node;
|
|
492
|
+
},
|
|
493
|
+
resolveRootNode(webPage, { find, meta }) {
|
|
494
|
+
const identity = find(IdentityId);
|
|
495
|
+
const webSite = find(PrimaryWebSiteId);
|
|
496
|
+
const logo = find("#logo");
|
|
497
|
+
if (identity && meta.url === meta.host)
|
|
498
|
+
setIfEmpty(webPage, "about", idReference(identity));
|
|
499
|
+
if (logo)
|
|
500
|
+
setIfEmpty(webPage, "primaryImageOfPage", idReference(logo));
|
|
501
|
+
if (webSite)
|
|
502
|
+
setIfEmpty(webPage, "isPartOf", idReference(webSite));
|
|
503
|
+
const breadcrumb = find(PrimaryBreadcrumbId);
|
|
504
|
+
if (breadcrumb)
|
|
505
|
+
setIfEmpty(webPage, "breadcrumb", idReference(breadcrumb));
|
|
506
|
+
return webPage;
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
const personResolver = defineSchemaOrgResolver({
|
|
511
|
+
cast(node) {
|
|
512
|
+
if (typeof node === "string") {
|
|
513
|
+
return {
|
|
514
|
+
name: node
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
return node;
|
|
518
|
+
},
|
|
519
|
+
defaults: {
|
|
520
|
+
"@type": "Person"
|
|
521
|
+
},
|
|
522
|
+
idPrefix: ["host", IdentityId],
|
|
523
|
+
resolve(node, ctx) {
|
|
524
|
+
if (node.url)
|
|
525
|
+
node.url = resolveWithBase(ctx.meta.host, node.url);
|
|
526
|
+
return node;
|
|
527
|
+
},
|
|
528
|
+
resolveRootNode(node, { find, meta }) {
|
|
529
|
+
if (resolveAsGraphKey(node["@id"]) === IdentityId) {
|
|
530
|
+
setIfEmpty(node, "url", meta.host);
|
|
531
|
+
const webPage = find(PrimaryWebPageId);
|
|
532
|
+
if (webPage)
|
|
533
|
+
setIfEmpty(webPage, "about", idReference(node));
|
|
534
|
+
const webSite = find(PrimaryWebSiteId);
|
|
535
|
+
if (webSite)
|
|
536
|
+
setIfEmpty(webSite, "publisher", idReference(node));
|
|
537
|
+
}
|
|
538
|
+
const article = find(PrimaryArticleId);
|
|
539
|
+
if (article)
|
|
540
|
+
setIfEmpty(article, "author", idReference(node));
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
const PrimaryArticleId = "#article";
|
|
545
|
+
const articleResolver = defineSchemaOrgResolver({
|
|
546
|
+
defaults: {
|
|
547
|
+
"@type": "Article"
|
|
548
|
+
},
|
|
549
|
+
inheritMeta: [
|
|
550
|
+
"inLanguage",
|
|
551
|
+
"description",
|
|
552
|
+
"image",
|
|
553
|
+
"dateModified",
|
|
554
|
+
"datePublished",
|
|
555
|
+
{ meta: "title", key: "headline" }
|
|
556
|
+
],
|
|
557
|
+
idPrefix: ["url", PrimaryArticleId],
|
|
558
|
+
resolve(node, ctx) {
|
|
559
|
+
node.author = resolveRelation(node.author, ctx, personResolver, {
|
|
560
|
+
root: true
|
|
561
|
+
});
|
|
562
|
+
node.publisher = resolveRelation(node.publisher, ctx);
|
|
563
|
+
node.dateModified = resolvableDateToIso(node.dateModified);
|
|
564
|
+
node.datePublished = resolvableDateToIso(node.datePublished);
|
|
565
|
+
resolveDefaultType(node, "Article");
|
|
566
|
+
node.headline = trimLength(node.headline, 110);
|
|
567
|
+
return node;
|
|
568
|
+
},
|
|
569
|
+
resolveRootNode(node, { find, meta }) {
|
|
570
|
+
const webPage = find(PrimaryWebPageId);
|
|
571
|
+
const identity = find(IdentityId);
|
|
572
|
+
if (node.image && !node.thumbnailUrl) {
|
|
573
|
+
const firstImage = asArray(node.image)[0];
|
|
574
|
+
if (typeof firstImage === "string")
|
|
575
|
+
setIfEmpty(node, "thumbnailUrl", resolveWithBase(meta.host, firstImage));
|
|
576
|
+
else if (firstImage?.["@id"])
|
|
577
|
+
setIfEmpty(node, "thumbnailUrl", find(firstImage["@id"])?.url);
|
|
578
|
+
}
|
|
579
|
+
if (identity) {
|
|
580
|
+
setIfEmpty(node, "publisher", idReference(identity));
|
|
581
|
+
setIfEmpty(node, "author", idReference(identity));
|
|
582
|
+
}
|
|
583
|
+
if (webPage) {
|
|
584
|
+
setIfEmpty(node, "isPartOf", idReference(webPage));
|
|
585
|
+
setIfEmpty(node, "mainEntityOfPage", idReference(webPage));
|
|
586
|
+
setIfEmpty(webPage, "potentialAction", [
|
|
587
|
+
{
|
|
588
|
+
"@type": "ReadAction",
|
|
589
|
+
"target": [meta.url]
|
|
590
|
+
}
|
|
591
|
+
]);
|
|
592
|
+
setIfEmpty(webPage, "dateModified", node.dateModified);
|
|
593
|
+
setIfEmpty(webPage, "datePublished", node.datePublished);
|
|
594
|
+
}
|
|
595
|
+
return node;
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
const bookEditionResolver = defineSchemaOrgResolver({
|
|
600
|
+
defaults: {
|
|
601
|
+
"@type": "Book"
|
|
602
|
+
},
|
|
603
|
+
inheritMeta: [
|
|
604
|
+
"inLanguage"
|
|
605
|
+
],
|
|
606
|
+
resolve(node, ctx) {
|
|
607
|
+
if (node.bookFormat)
|
|
608
|
+
node.bookFormat = withBase(node.bookFormat, "https://schema.org/");
|
|
609
|
+
if (node.datePublished)
|
|
610
|
+
node.datePublished = resolvableDateToDate(node.datePublished);
|
|
611
|
+
node.author = resolveRelation(node.author, ctx);
|
|
612
|
+
return node;
|
|
613
|
+
},
|
|
614
|
+
resolveRootNode(node, { find }) {
|
|
615
|
+
const identity = find(IdentityId);
|
|
616
|
+
if (identity)
|
|
617
|
+
setIfEmpty(node, "provider", idReference(identity));
|
|
618
|
+
return node;
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
const PrimaryBookId = "#book";
|
|
622
|
+
const bookResolver = defineSchemaOrgResolver({
|
|
623
|
+
defaults: {
|
|
624
|
+
"@type": "Book"
|
|
625
|
+
},
|
|
626
|
+
inheritMeta: [
|
|
627
|
+
"description",
|
|
628
|
+
"url",
|
|
629
|
+
{ meta: "title", key: "name" }
|
|
630
|
+
],
|
|
631
|
+
idPrefix: ["url", PrimaryBookId],
|
|
632
|
+
resolve(node, ctx) {
|
|
633
|
+
node.workExample = resolveRelation(node.workExample, ctx, bookEditionResolver);
|
|
634
|
+
node.author = resolveRelation(node.author, ctx);
|
|
635
|
+
if (node.url)
|
|
636
|
+
withBase(node.url, ctx.meta.host);
|
|
637
|
+
return node;
|
|
638
|
+
},
|
|
639
|
+
resolveRootNode(node, { find }) {
|
|
640
|
+
const identity = find(IdentityId);
|
|
641
|
+
if (identity)
|
|
642
|
+
setIfEmpty(node, "author", idReference(identity));
|
|
643
|
+
return node;
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
const commentResolver = defineSchemaOrgResolver({
|
|
648
|
+
defaults: {
|
|
649
|
+
"@type": "Comment"
|
|
650
|
+
},
|
|
651
|
+
idPrefix: "url",
|
|
652
|
+
resolve(node, ctx) {
|
|
653
|
+
node.author = resolveRelation(node.author, ctx, personResolver, {
|
|
654
|
+
root: true
|
|
655
|
+
});
|
|
656
|
+
node.dateCreated = resolvableDateToIso(node.dateCreated);
|
|
657
|
+
node.dateModified = resolvableDateToIso(node.dateModified);
|
|
658
|
+
return node;
|
|
659
|
+
},
|
|
660
|
+
resolveRootNode(node, { find }) {
|
|
661
|
+
const article = find(PrimaryArticleId);
|
|
662
|
+
if (article)
|
|
663
|
+
setIfEmpty(node, "about", idReference(article));
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
const courseResolver = defineSchemaOrgResolver({
|
|
668
|
+
defaults: {
|
|
669
|
+
"@type": "Course"
|
|
670
|
+
},
|
|
671
|
+
resolve(node, ctx) {
|
|
672
|
+
node.provider = resolveRelation(node.provider, ctx, organizationResolver, {
|
|
673
|
+
root: true
|
|
674
|
+
});
|
|
675
|
+
return node;
|
|
676
|
+
},
|
|
677
|
+
resolveRootNode(node, { find }) {
|
|
678
|
+
const identity = find(IdentityId);
|
|
679
|
+
if (identity)
|
|
680
|
+
setIfEmpty(node, "provider", idReference(identity));
|
|
681
|
+
return node;
|
|
682
|
+
}
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
const PrimaryDatasetId = "#dataset";
|
|
686
|
+
const datasetResolver = defineSchemaOrgResolver({
|
|
687
|
+
defaults: {
|
|
688
|
+
"@type": "Dataset"
|
|
689
|
+
},
|
|
690
|
+
inheritMeta: [
|
|
691
|
+
"description",
|
|
692
|
+
"url",
|
|
693
|
+
"dateModified",
|
|
694
|
+
"datePublished",
|
|
695
|
+
{ meta: "title", key: "name" }
|
|
696
|
+
],
|
|
697
|
+
idPrefix: ["url", PrimaryDatasetId],
|
|
698
|
+
resolve(node, ctx) {
|
|
699
|
+
resolveDefaultType(node, "Dataset");
|
|
700
|
+
node.creator = resolveRelation(node.creator, ctx, personResolver, {
|
|
701
|
+
root: true
|
|
702
|
+
});
|
|
703
|
+
node.dateModified = resolvableDateToIso(node.dateModified);
|
|
704
|
+
node.datePublished = resolvableDateToIso(node.datePublished);
|
|
705
|
+
return node;
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
const placeResolver = defineSchemaOrgResolver({
|
|
710
|
+
defaults: {
|
|
711
|
+
"@type": "Place"
|
|
712
|
+
},
|
|
713
|
+
resolve(node, ctx) {
|
|
714
|
+
if (typeof node.address !== "string")
|
|
715
|
+
node.address = resolveRelation(node.address, ctx, addressResolver);
|
|
716
|
+
return node;
|
|
717
|
+
}
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
const virtualLocationResolver = defineSchemaOrgResolver({
|
|
721
|
+
cast(node) {
|
|
722
|
+
if (typeof node === "string") {
|
|
723
|
+
return {
|
|
724
|
+
url: node
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
return node;
|
|
728
|
+
},
|
|
729
|
+
defaults: {
|
|
730
|
+
"@type": "VirtualLocation"
|
|
731
|
+
}
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
const PrimaryEventId = "#event";
|
|
735
|
+
const eventResolver = defineSchemaOrgResolver({
|
|
736
|
+
defaults: {
|
|
737
|
+
"@type": "Event"
|
|
738
|
+
},
|
|
739
|
+
inheritMeta: [
|
|
740
|
+
"inLanguage",
|
|
741
|
+
"description",
|
|
742
|
+
"image",
|
|
743
|
+
{ meta: "title", key: "name" }
|
|
744
|
+
],
|
|
745
|
+
idPrefix: ["url", PrimaryEventId],
|
|
746
|
+
resolve(node, ctx) {
|
|
747
|
+
if (node.location) {
|
|
748
|
+
const isVirtual = node.location === "string" || node.location?.url !== "undefined";
|
|
749
|
+
node.location = resolveRelation(node.location, ctx, isVirtual ? virtualLocationResolver : placeResolver);
|
|
750
|
+
}
|
|
751
|
+
node.performer = resolveRelation(node.performer, ctx, personResolver, {
|
|
752
|
+
root: true
|
|
753
|
+
});
|
|
754
|
+
node.organizer = resolveRelation(node.organizer, ctx, organizationResolver, {
|
|
755
|
+
root: true
|
|
756
|
+
});
|
|
757
|
+
node.offers = resolveRelation(node.offers, ctx, offerResolver);
|
|
758
|
+
if (node.eventAttendanceMode)
|
|
759
|
+
node.eventAttendanceMode = withBase(node.eventAttendanceMode, "https://schema.org/");
|
|
760
|
+
if (node.eventStatus)
|
|
761
|
+
node.eventStatus = withBase(node.eventStatus, "https://schema.org/");
|
|
762
|
+
const isOnline = node.eventStatus === "https://schema.org/EventMovedOnline";
|
|
763
|
+
const dates = ["startDate", "previousStartDate", "endDate"];
|
|
764
|
+
dates.forEach((date) => {
|
|
765
|
+
if (!isOnline) {
|
|
766
|
+
if (node[date] instanceof Date && node[date].getHours() === 0 && node[date].getMinutes() === 0)
|
|
767
|
+
node[date] = resolvableDateToDate(node[date]);
|
|
768
|
+
} else {
|
|
769
|
+
node[date] = resolvableDateToIso(node[date]);
|
|
770
|
+
}
|
|
771
|
+
});
|
|
772
|
+
setIfEmpty(node, "endDate", node.startDate);
|
|
773
|
+
return node;
|
|
774
|
+
},
|
|
775
|
+
resolveRootNode(node, { find }) {
|
|
776
|
+
const identity = find(IdentityId);
|
|
777
|
+
if (identity)
|
|
778
|
+
setIfEmpty(node, "organizer", idReference(identity));
|
|
779
|
+
}
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
const openingHoursResolver = defineSchemaOrgResolver({
|
|
783
|
+
defaults: {
|
|
784
|
+
"@type": "OpeningHoursSpecification",
|
|
785
|
+
"opens": "00:00",
|
|
786
|
+
"closes": "23:59"
|
|
787
|
+
}
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
const localBusinessResolver = defineSchemaOrgResolver({
|
|
791
|
+
defaults: {
|
|
792
|
+
"@type": ["Organization", "LocalBusiness"]
|
|
793
|
+
},
|
|
794
|
+
inheritMeta: [
|
|
795
|
+
{ key: "url", meta: "host" },
|
|
796
|
+
{ key: "currenciesAccepted", meta: "currency" }
|
|
797
|
+
],
|
|
798
|
+
idPrefix: ["host", IdentityId],
|
|
799
|
+
resolve(node, ctx) {
|
|
800
|
+
resolveDefaultType(node, ["Organization", "LocalBusiness"]);
|
|
801
|
+
node.address = resolveRelation(node.address, ctx, addressResolver);
|
|
802
|
+
node.openingHoursSpecification = resolveRelation(node.openingHoursSpecification, ctx, openingHoursResolver);
|
|
803
|
+
node = resolveNode({ ...node }, ctx, organizationResolver);
|
|
804
|
+
return node;
|
|
805
|
+
},
|
|
806
|
+
resolveRootNode(node, ctx) {
|
|
807
|
+
organizationResolver.resolveRootNode(node, ctx);
|
|
808
|
+
return node;
|
|
809
|
+
}
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
const ratingResolver = defineSchemaOrgResolver({
|
|
813
|
+
cast(node) {
|
|
814
|
+
if (node === "number") {
|
|
815
|
+
return {
|
|
816
|
+
ratingValue: node
|
|
817
|
+
};
|
|
818
|
+
}
|
|
819
|
+
return node;
|
|
820
|
+
},
|
|
821
|
+
defaults: {
|
|
822
|
+
"@type": "Rating",
|
|
823
|
+
"bestRating": 5,
|
|
824
|
+
"worstRating": 1
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
const foodEstablishmentResolver = defineSchemaOrgResolver({
|
|
829
|
+
defaults: {
|
|
830
|
+
"@type": ["Organization", "LocalBusiness", "FoodEstablishment"]
|
|
831
|
+
},
|
|
832
|
+
inheritMeta: [
|
|
833
|
+
{ key: "url", meta: "host" },
|
|
834
|
+
{ key: "currenciesAccepted", meta: "currency" }
|
|
835
|
+
],
|
|
836
|
+
idPrefix: ["host", IdentityId],
|
|
837
|
+
resolve(node, ctx) {
|
|
838
|
+
resolveDefaultType(node, ["Organization", "LocalBusiness", "FoodEstablishment"]);
|
|
839
|
+
node.starRating = resolveRelation(node.starRating, ctx, ratingResolver);
|
|
840
|
+
node = resolveNode(node, ctx, localBusinessResolver);
|
|
841
|
+
return node;
|
|
842
|
+
},
|
|
843
|
+
resolveRootNode(node, ctx) {
|
|
844
|
+
localBusinessResolver.resolveRootNode(node, ctx);
|
|
845
|
+
return node;
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
|
|
849
|
+
const howToStepDirectionResolver = defineSchemaOrgResolver({
|
|
850
|
+
cast(node) {
|
|
851
|
+
if (typeof node === "string") {
|
|
852
|
+
return {
|
|
853
|
+
text: node
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
return node;
|
|
857
|
+
},
|
|
858
|
+
defaults: {
|
|
859
|
+
"@type": "HowToDirection"
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
|
|
863
|
+
const howToStepResolver = defineSchemaOrgResolver({
|
|
864
|
+
cast(node) {
|
|
865
|
+
if (typeof node === "string") {
|
|
866
|
+
return {
|
|
867
|
+
text: node
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
return node;
|
|
871
|
+
},
|
|
872
|
+
defaults: {
|
|
873
|
+
"@type": "HowToStep"
|
|
874
|
+
},
|
|
875
|
+
resolve(step, ctx) {
|
|
876
|
+
if (step.url)
|
|
877
|
+
step.url = resolveWithBase(ctx.meta.url, step.url);
|
|
878
|
+
if (step.image) {
|
|
879
|
+
step.image = resolveRelation(step.image, ctx, imageResolver, {
|
|
880
|
+
root: true
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
if (step.itemListElement)
|
|
884
|
+
step.itemListElement = resolveRelation(step.itemListElement, ctx, howToStepDirectionResolver);
|
|
885
|
+
return step;
|
|
886
|
+
}
|
|
887
|
+
});
|
|
888
|
+
|
|
889
|
+
const HowToId = "#howto";
|
|
890
|
+
const howToResolver = defineSchemaOrgResolver({
|
|
891
|
+
defaults: {
|
|
892
|
+
"@type": "HowTo"
|
|
893
|
+
},
|
|
894
|
+
inheritMeta: [
|
|
895
|
+
"description",
|
|
896
|
+
"image",
|
|
897
|
+
"inLanguage",
|
|
898
|
+
{ meta: "title", key: "name" }
|
|
899
|
+
],
|
|
900
|
+
idPrefix: ["url", HowToId],
|
|
901
|
+
resolve(node, ctx) {
|
|
902
|
+
node.step = resolveRelation(node.step, ctx, howToStepResolver);
|
|
903
|
+
return node;
|
|
904
|
+
},
|
|
905
|
+
resolveRootNode(node, { find }) {
|
|
906
|
+
const webPage = find(PrimaryWebPageId);
|
|
907
|
+
if (webPage)
|
|
908
|
+
setIfEmpty(node, "mainEntityOfPage", idReference(webPage));
|
|
909
|
+
}
|
|
910
|
+
});
|
|
911
|
+
|
|
912
|
+
const itemListResolver = defineSchemaOrgResolver({
|
|
913
|
+
defaults: {
|
|
914
|
+
"@type": "ItemList"
|
|
915
|
+
},
|
|
916
|
+
resolve(node, ctx) {
|
|
917
|
+
if (node.itemListElement) {
|
|
918
|
+
let index = 1;
|
|
919
|
+
node.itemListElement = resolveRelation(node.itemListElement, ctx, listItemResolver, {
|
|
920
|
+
array: true,
|
|
921
|
+
afterResolve(node2) {
|
|
922
|
+
setIfEmpty(node2, "position", index++);
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
return node;
|
|
927
|
+
}
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
const jobPostingResolver = defineSchemaOrgResolver({
|
|
931
|
+
defaults: {
|
|
932
|
+
"@type": "JobPosting"
|
|
933
|
+
},
|
|
934
|
+
idPrefix: ["url", "#job-posting"],
|
|
935
|
+
resolve(node, ctx) {
|
|
936
|
+
node.datePosted = resolvableDateToIso(node.datePosted);
|
|
937
|
+
node.hiringOrganization = resolveRelation(node.hiringOrganization, ctx, organizationResolver);
|
|
938
|
+
node.jobLocation = resolveRelation(node.jobLocation, ctx, placeResolver);
|
|
939
|
+
node.baseSalary = resolveRelation(node.baseSalary, ctx, monetaryAmountResolver);
|
|
940
|
+
node.validThrough = resolvableDateToIso(node.validThrough);
|
|
941
|
+
return node;
|
|
942
|
+
},
|
|
943
|
+
resolveRootNode(jobPosting, { find }) {
|
|
944
|
+
const webPage = find(PrimaryWebPageId);
|
|
945
|
+
const identity = find(IdentityId);
|
|
946
|
+
if (identity)
|
|
947
|
+
setIfEmpty(jobPosting, "hiringOrganization", idReference(identity));
|
|
948
|
+
if (webPage)
|
|
949
|
+
setIfEmpty(jobPosting, "mainEntityOfPage", idReference(webPage));
|
|
950
|
+
return jobPosting;
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
const reviewResolver = defineSchemaOrgResolver({
|
|
955
|
+
defaults: {
|
|
956
|
+
"@type": "Review"
|
|
957
|
+
},
|
|
958
|
+
inheritMeta: [
|
|
959
|
+
"inLanguage"
|
|
960
|
+
],
|
|
961
|
+
resolve(review, ctx) {
|
|
962
|
+
review.reviewRating = resolveRelation(review.reviewRating, ctx, ratingResolver);
|
|
963
|
+
review.author = resolveRelation(review.author, ctx, personResolver);
|
|
964
|
+
return review;
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
|
|
968
|
+
const videoResolver = defineSchemaOrgResolver({
|
|
969
|
+
cast(input) {
|
|
970
|
+
if (typeof input === "string") {
|
|
971
|
+
input = {
|
|
972
|
+
url: input
|
|
973
|
+
};
|
|
974
|
+
}
|
|
975
|
+
return input;
|
|
976
|
+
},
|
|
977
|
+
alias: "video",
|
|
978
|
+
defaults: {
|
|
979
|
+
"@type": "VideoObject"
|
|
980
|
+
},
|
|
981
|
+
inheritMeta: [
|
|
982
|
+
{ meta: "title", key: "name" },
|
|
983
|
+
"description",
|
|
984
|
+
"image",
|
|
985
|
+
"inLanguage",
|
|
986
|
+
{ meta: "datePublished", key: "uploadDate" }
|
|
987
|
+
],
|
|
988
|
+
idPrefix: "host",
|
|
989
|
+
resolve(video, ctx) {
|
|
990
|
+
if (video.uploadDate)
|
|
991
|
+
video.uploadDate = resolvableDateToIso(video.uploadDate);
|
|
992
|
+
video.url = resolveWithBase(ctx.meta.host, video.url);
|
|
993
|
+
if (video.caption && !video.description)
|
|
994
|
+
video.description = video.caption;
|
|
995
|
+
if (!video.description)
|
|
996
|
+
video.description = "No description";
|
|
997
|
+
if (video.thumbnailUrl && (typeof video.thumbnailUrl === "string" || Array.isArray(video.thumbnailUrl))) {
|
|
998
|
+
const images = asArray(video.thumbnailUrl).map((image) => resolveWithBase(ctx.meta.host, image));
|
|
999
|
+
video.thumbnailUrl = images.length > 1 ? images : images[0];
|
|
1000
|
+
}
|
|
1001
|
+
if (video.thumbnail)
|
|
1002
|
+
video.thumbnail = resolveRelation(video.thumbnailUrl, ctx, imageResolver);
|
|
1003
|
+
return video;
|
|
1004
|
+
},
|
|
1005
|
+
resolveRootNode(video, { find }) {
|
|
1006
|
+
if (video.image && !video.thumbnail) {
|
|
1007
|
+
const firstImage = asArray(video.image)[0];
|
|
1008
|
+
setIfEmpty(video, "thumbnail", find(firstImage["@id"])?.url);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
});
|
|
1012
|
+
|
|
1013
|
+
const movieResolver = defineSchemaOrgResolver({
|
|
1014
|
+
defaults: {
|
|
1015
|
+
"@type": "Movie"
|
|
1016
|
+
},
|
|
1017
|
+
resolve(node, ctx) {
|
|
1018
|
+
node.aggregateRating = resolveRelation(node.aggregateRating, ctx, aggregateRatingResolver);
|
|
1019
|
+
node.review = resolveRelation(node.review, ctx, reviewResolver);
|
|
1020
|
+
node.director = resolveRelation(node.director, ctx, personResolver);
|
|
1021
|
+
node.actor = resolveRelation(node.actor, ctx, personResolver);
|
|
1022
|
+
node.trailer = resolveRelation(node.trailer, ctx, videoResolver);
|
|
1023
|
+
node.productionCompany = resolveRelation(node.productionCompany, ctx, organizationResolver);
|
|
1024
|
+
if (node.dateCreated)
|
|
1025
|
+
node.dateCreated = resolvableDateToDate(node.dateCreated);
|
|
1026
|
+
return node;
|
|
1027
|
+
}
|
|
1028
|
+
});
|
|
1029
|
+
|
|
1030
|
+
const musicAlbumResolver = defineSchemaOrgResolver({
|
|
1031
|
+
defaults: {
|
|
1032
|
+
"@type": "MusicAlbum"
|
|
1033
|
+
},
|
|
1034
|
+
idPrefix: "host",
|
|
1035
|
+
resolve(node, ctx) {
|
|
1036
|
+
if (node.datePublished)
|
|
1037
|
+
node.datePublished = resolvableDateToIso(node.datePublished);
|
|
1038
|
+
if (node.url)
|
|
1039
|
+
node.url = resolveWithBase(ctx.meta.host, node.url);
|
|
1040
|
+
node.byArtist = resolveRelation(node.byArtist, ctx, personResolver);
|
|
1041
|
+
node.aggregateRating = resolveRelation(node.aggregateRating, ctx, aggregateRatingResolver);
|
|
1042
|
+
node.review = resolveRelation(node.review, ctx, reviewResolver);
|
|
1043
|
+
return node;
|
|
1044
|
+
}
|
|
1045
|
+
});
|
|
1046
|
+
|
|
1047
|
+
const musicGroupResolver = defineSchemaOrgResolver({
|
|
1048
|
+
defaults: {
|
|
1049
|
+
"@type": "MusicGroup"
|
|
1050
|
+
},
|
|
1051
|
+
idPrefix: "host",
|
|
1052
|
+
inheritMeta: [
|
|
1053
|
+
{ meta: "host", key: "url" }
|
|
1054
|
+
],
|
|
1055
|
+
resolve(node, ctx) {
|
|
1056
|
+
if (node.foundingDate)
|
|
1057
|
+
node.foundingDate = resolvableDateToDate(node.foundingDate);
|
|
1058
|
+
if (node.dissolutionDate)
|
|
1059
|
+
node.dissolutionDate = resolvableDateToDate(node.dissolutionDate);
|
|
1060
|
+
if (node.url)
|
|
1061
|
+
node.url = resolveWithBase(ctx.meta.host, node.url);
|
|
1062
|
+
node.member = resolveRelation(node.member, ctx, personResolver);
|
|
1063
|
+
return node;
|
|
1064
|
+
}
|
|
1065
|
+
});
|
|
1066
|
+
|
|
1067
|
+
const musicPlaylistResolver = defineSchemaOrgResolver({
|
|
1068
|
+
defaults: {
|
|
1069
|
+
"@type": "MusicPlaylist"
|
|
1070
|
+
},
|
|
1071
|
+
idPrefix: "host",
|
|
1072
|
+
resolve(node, ctx) {
|
|
1073
|
+
if (node.datePublished)
|
|
1074
|
+
node.datePublished = resolvableDateToIso(node.datePublished);
|
|
1075
|
+
if (node.dateModified)
|
|
1076
|
+
node.dateModified = resolvableDateToIso(node.dateModified);
|
|
1077
|
+
if (node.url)
|
|
1078
|
+
node.url = resolveWithBase(ctx.meta.host, node.url);
|
|
1079
|
+
node.creator = resolveRelation(node.creator, ctx, personResolver);
|
|
1080
|
+
node.aggregateRating = resolveRelation(node.aggregateRating, ctx, aggregateRatingResolver);
|
|
1081
|
+
return node;
|
|
1082
|
+
}
|
|
1083
|
+
});
|
|
1084
|
+
|
|
1085
|
+
const musicRecordingResolver = defineSchemaOrgResolver({
|
|
1086
|
+
defaults: {
|
|
1087
|
+
"@type": "MusicRecording"
|
|
1088
|
+
},
|
|
1089
|
+
idPrefix: "host",
|
|
1090
|
+
resolve(node, ctx) {
|
|
1091
|
+
if (node.datePublished)
|
|
1092
|
+
node.datePublished = resolvableDateToIso(node.datePublished);
|
|
1093
|
+
if (node.url)
|
|
1094
|
+
node.url = resolveWithBase(ctx.meta.host, node.url);
|
|
1095
|
+
if (node.audio)
|
|
1096
|
+
node.audio = resolveWithBase(ctx.meta.host, node.audio);
|
|
1097
|
+
node.byArtist = resolveRelation(node.byArtist, ctx, personResolver);
|
|
1098
|
+
node.aggregateRating = resolveRelation(node.aggregateRating, ctx, aggregateRatingResolver);
|
|
1099
|
+
return node;
|
|
1100
|
+
}
|
|
1101
|
+
});
|
|
1102
|
+
|
|
1103
|
+
const podcastEpisodeResolver = defineSchemaOrgResolver({
|
|
1104
|
+
defaults: {
|
|
1105
|
+
"@type": "PodcastEpisode"
|
|
1106
|
+
},
|
|
1107
|
+
inheritMeta: [
|
|
1108
|
+
"inLanguage"
|
|
1109
|
+
],
|
|
1110
|
+
resolve(node, ctx) {
|
|
1111
|
+
node.author = resolveRelation(node.author, ctx, personResolver);
|
|
1112
|
+
node.aggregateRating = resolveRelation(node.aggregateRating, ctx, aggregateRatingResolver);
|
|
1113
|
+
node.review = resolveRelation(node.review, ctx, reviewResolver);
|
|
1114
|
+
if (node.datePublished)
|
|
1115
|
+
node.datePublished = resolvableDateToIso(node.datePublished);
|
|
1116
|
+
if (node.uploadDate)
|
|
1117
|
+
node.uploadDate = resolvableDateToIso(node.uploadDate);
|
|
1118
|
+
return node;
|
|
1119
|
+
}
|
|
1120
|
+
});
|
|
1121
|
+
|
|
1122
|
+
const podcastSeasonResolver = defineSchemaOrgResolver({
|
|
1123
|
+
defaults: {
|
|
1124
|
+
"@type": "PodcastSeason"
|
|
1125
|
+
},
|
|
1126
|
+
resolve(node, ctx) {
|
|
1127
|
+
node.actor = resolveRelation(node.actor, ctx, personResolver);
|
|
1128
|
+
node.director = resolveRelation(node.director, ctx, personResolver);
|
|
1129
|
+
node.productionCompany = resolveRelation(node.productionCompany, ctx, organizationResolver);
|
|
1130
|
+
node.aggregateRating = resolveRelation(node.aggregateRating, ctx, aggregateRatingResolver);
|
|
1131
|
+
if (node.datePublished)
|
|
1132
|
+
node.datePublished = resolvableDateToIso(node.datePublished);
|
|
1133
|
+
if (node.startDate)
|
|
1134
|
+
node.startDate = resolvableDateToIso(node.startDate);
|
|
1135
|
+
if (node.endDate)
|
|
1136
|
+
node.endDate = resolvableDateToIso(node.endDate);
|
|
1137
|
+
return node;
|
|
1138
|
+
}
|
|
1139
|
+
});
|
|
1140
|
+
|
|
1141
|
+
const podcastSeriesResolver = defineSchemaOrgResolver({
|
|
1142
|
+
defaults: {
|
|
1143
|
+
"@type": "PodcastSeries"
|
|
1144
|
+
},
|
|
1145
|
+
resolve(node, ctx) {
|
|
1146
|
+
node.author = resolveRelation(node.author, ctx, personResolver);
|
|
1147
|
+
node.aggregateRating = resolveRelation(node.aggregateRating, ctx, aggregateRatingResolver);
|
|
1148
|
+
if (node.datePublished)
|
|
1149
|
+
node.datePublished = resolvableDateToIso(node.datePublished);
|
|
1150
|
+
if (node.startDate)
|
|
1151
|
+
node.startDate = resolvableDateToIso(node.startDate);
|
|
1152
|
+
if (node.endDate)
|
|
1153
|
+
node.endDate = resolvableDateToIso(node.endDate);
|
|
1154
|
+
return node;
|
|
1155
|
+
}
|
|
1156
|
+
});
|
|
1157
|
+
|
|
1158
|
+
const ProductId = "#product";
|
|
1159
|
+
const productResolver = defineSchemaOrgResolver({
|
|
1160
|
+
defaults: {
|
|
1161
|
+
"@type": "Product"
|
|
1162
|
+
},
|
|
1163
|
+
inheritMeta: [
|
|
1164
|
+
"description",
|
|
1165
|
+
"image",
|
|
1166
|
+
{ meta: "title", key: "name" }
|
|
1167
|
+
],
|
|
1168
|
+
idPrefix: ["url", ProductId],
|
|
1169
|
+
resolve(node, ctx) {
|
|
1170
|
+
node.aggregateOffer = resolveRelation(node.aggregateOffer, ctx, aggregateOfferResolver);
|
|
1171
|
+
node.aggregateRating = resolveRelation(node.aggregateRating, ctx, aggregateRatingResolver);
|
|
1172
|
+
node.offers = resolveRelation(node.offers, ctx, offerResolver);
|
|
1173
|
+
node.review = resolveRelation(node.review, ctx, reviewResolver);
|
|
1174
|
+
return node;
|
|
1175
|
+
},
|
|
1176
|
+
resolveRootNode(product, { find }) {
|
|
1177
|
+
const webPage = find(PrimaryWebPageId);
|
|
1178
|
+
const identity = find(IdentityId);
|
|
1179
|
+
if (identity)
|
|
1180
|
+
setIfEmpty(product, "brand", idReference(identity));
|
|
1181
|
+
if (webPage)
|
|
1182
|
+
setIfEmpty(product, "mainEntityOfPage", idReference(webPage));
|
|
1183
|
+
return product;
|
|
1184
|
+
}
|
|
1185
|
+
});
|
|
1186
|
+
|
|
1187
|
+
const answerResolver = defineSchemaOrgResolver({
|
|
1188
|
+
cast(node) {
|
|
1189
|
+
if (typeof node === "string") {
|
|
1190
|
+
return {
|
|
1191
|
+
text: node
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
return node;
|
|
1195
|
+
},
|
|
1196
|
+
defaults: {
|
|
1197
|
+
"@type": "Answer"
|
|
1198
|
+
}
|
|
1199
|
+
});
|
|
1200
|
+
|
|
1201
|
+
const questionResolver = defineSchemaOrgResolver({
|
|
1202
|
+
defaults: {
|
|
1203
|
+
"@type": "Question"
|
|
1204
|
+
},
|
|
1205
|
+
inheritMeta: [
|
|
1206
|
+
"inLanguage"
|
|
1207
|
+
],
|
|
1208
|
+
idPrefix: "url",
|
|
1209
|
+
resolve(question, ctx) {
|
|
1210
|
+
if (question.question) {
|
|
1211
|
+
question.name = question.question;
|
|
1212
|
+
delete question.question;
|
|
1213
|
+
}
|
|
1214
|
+
if (question.answer) {
|
|
1215
|
+
question.acceptedAnswer = question.answer;
|
|
1216
|
+
delete question.answer;
|
|
1217
|
+
}
|
|
1218
|
+
question.acceptedAnswer = resolveRelation(question.acceptedAnswer, ctx, answerResolver);
|
|
1219
|
+
question.dateCreated = resolvableDateToIso(question.dateCreated);
|
|
1220
|
+
return question;
|
|
1221
|
+
},
|
|
1222
|
+
resolveRootNode(question, { find }) {
|
|
1223
|
+
const webPage = find(PrimaryWebPageId);
|
|
1224
|
+
if (webPage && asArray(webPage["@type"]).includes("FAQPage"))
|
|
1225
|
+
dedupeMerge(webPage, "mainEntity", idReference(question));
|
|
1226
|
+
}
|
|
1227
|
+
});
|
|
1228
|
+
|
|
1229
|
+
const RecipeId = "#recipe";
|
|
1230
|
+
const recipeResolver = defineSchemaOrgResolver({
|
|
1231
|
+
defaults: {
|
|
1232
|
+
"@type": "Recipe"
|
|
1233
|
+
},
|
|
1234
|
+
inheritMeta: [
|
|
1235
|
+
{ meta: "title", key: "name" },
|
|
1236
|
+
"description",
|
|
1237
|
+
"image",
|
|
1238
|
+
"datePublished"
|
|
1239
|
+
],
|
|
1240
|
+
idPrefix: ["url", RecipeId],
|
|
1241
|
+
resolve(node, ctx) {
|
|
1242
|
+
node.recipeInstructions = resolveRelation(node.recipeInstructions, ctx, howToStepResolver);
|
|
1243
|
+
return node;
|
|
1244
|
+
},
|
|
1245
|
+
resolveRootNode(node, { find }) {
|
|
1246
|
+
const article = find(PrimaryArticleId);
|
|
1247
|
+
const webPage = find(PrimaryWebPageId);
|
|
1248
|
+
if (article)
|
|
1249
|
+
setIfEmpty(node, "mainEntityOfPage", idReference(article));
|
|
1250
|
+
else if (webPage)
|
|
1251
|
+
setIfEmpty(node, "mainEntityOfPage", idReference(webPage));
|
|
1252
|
+
if (article?.author)
|
|
1253
|
+
setIfEmpty(node, "author", article.author);
|
|
1254
|
+
return node;
|
|
1255
|
+
}
|
|
1256
|
+
});
|
|
1257
|
+
|
|
1258
|
+
const ServiceId = "#service";
|
|
1259
|
+
const serviceResolver = defineSchemaOrgResolver({
|
|
1260
|
+
defaults: {
|
|
1261
|
+
"@type": "Service"
|
|
1262
|
+
},
|
|
1263
|
+
inheritMeta: [
|
|
1264
|
+
"description",
|
|
1265
|
+
"image",
|
|
1266
|
+
{ meta: "title", key: "name" }
|
|
1267
|
+
],
|
|
1268
|
+
idPrefix: ["url", ServiceId],
|
|
1269
|
+
resolve(node, ctx) {
|
|
1270
|
+
resolveDefaultType(node, "Service");
|
|
1271
|
+
node.offers = resolveRelation(node.offers, ctx, offerResolver);
|
|
1272
|
+
node.aggregateRating = resolveRelation(node.aggregateRating, ctx, aggregateRatingResolver);
|
|
1273
|
+
node.review = resolveRelation(node.review, ctx, reviewResolver);
|
|
1274
|
+
return node;
|
|
1275
|
+
},
|
|
1276
|
+
resolveRootNode(service, { find }) {
|
|
1277
|
+
const webPage = find(PrimaryWebPageId);
|
|
1278
|
+
const identity = find(IdentityId);
|
|
1279
|
+
if (identity)
|
|
1280
|
+
setIfEmpty(service, "provider", idReference(identity));
|
|
1281
|
+
if (identity)
|
|
1282
|
+
setIfEmpty(service, "brand", idReference(identity));
|
|
1283
|
+
if (webPage)
|
|
1284
|
+
setIfEmpty(service, "mainEntityOfPage", idReference(webPage));
|
|
1285
|
+
return service;
|
|
1286
|
+
}
|
|
1287
|
+
});
|
|
1288
|
+
|
|
1289
|
+
const softwareAppResolver = defineSchemaOrgResolver({
|
|
1290
|
+
defaults: {
|
|
1291
|
+
"@type": "SoftwareApplication"
|
|
1292
|
+
},
|
|
1293
|
+
resolve(node, ctx) {
|
|
1294
|
+
resolveDefaultType(node, "SoftwareApplication");
|
|
1295
|
+
node.offers = resolveRelation(node.offers, ctx, offerResolver);
|
|
1296
|
+
node.aggregateRating = resolveRelation(node.aggregateRating, ctx, aggregateRatingResolver);
|
|
1297
|
+
node.review = resolveRelation(node.review, ctx, reviewResolver);
|
|
1298
|
+
return node;
|
|
1299
|
+
}
|
|
1300
|
+
});
|
|
1301
|
+
|
|
1302
|
+
const tvEpisodeResolver = defineSchemaOrgResolver({
|
|
1303
|
+
defaults: {
|
|
1304
|
+
"@type": "TVEpisode"
|
|
1305
|
+
},
|
|
1306
|
+
resolve(node, ctx) {
|
|
1307
|
+
node.actor = resolveRelation(node.actor, ctx, personResolver);
|
|
1308
|
+
node.director = resolveRelation(node.director, ctx, personResolver);
|
|
1309
|
+
node.musicBy = resolveRelation(node.musicBy, ctx, personResolver);
|
|
1310
|
+
node.video = resolveRelation(node.video, ctx, videoResolver);
|
|
1311
|
+
node.aggregateRating = resolveRelation(node.aggregateRating, ctx, aggregateRatingResolver);
|
|
1312
|
+
node.review = resolveRelation(node.review, ctx, reviewResolver);
|
|
1313
|
+
if (node.datePublished)
|
|
1314
|
+
node.datePublished = resolvableDateToIso(node.datePublished);
|
|
1315
|
+
if (node.uploadDate)
|
|
1316
|
+
node.uploadDate = resolvableDateToIso(node.uploadDate);
|
|
1317
|
+
return node;
|
|
1318
|
+
}
|
|
1319
|
+
});
|
|
1320
|
+
|
|
1321
|
+
const tvSeasonResolver = defineSchemaOrgResolver({
|
|
1322
|
+
defaults: {
|
|
1323
|
+
"@type": "TVSeason"
|
|
1324
|
+
},
|
|
1325
|
+
resolve(node, ctx) {
|
|
1326
|
+
node.actor = resolveRelation(node.actor, ctx, personResolver);
|
|
1327
|
+
node.director = resolveRelation(node.director, ctx, personResolver);
|
|
1328
|
+
node.productionCompany = resolveRelation(node.productionCompany, ctx, organizationResolver);
|
|
1329
|
+
node.aggregateRating = resolveRelation(node.aggregateRating, ctx, aggregateRatingResolver);
|
|
1330
|
+
node.trailer = resolveRelation(node.trailer, ctx, videoResolver);
|
|
1331
|
+
if (node.datePublished)
|
|
1332
|
+
node.datePublished = resolvableDateToIso(node.datePublished);
|
|
1333
|
+
if (node.startDate)
|
|
1334
|
+
node.startDate = resolvableDateToIso(node.startDate);
|
|
1335
|
+
if (node.endDate)
|
|
1336
|
+
node.endDate = resolvableDateToIso(node.endDate);
|
|
1337
|
+
return node;
|
|
1338
|
+
}
|
|
1339
|
+
});
|
|
1340
|
+
|
|
1341
|
+
const tvSeriesResolver = defineSchemaOrgResolver({
|
|
1342
|
+
defaults: {
|
|
1343
|
+
"@type": "TVSeries"
|
|
1344
|
+
},
|
|
1345
|
+
resolve(node, ctx) {
|
|
1346
|
+
node.actor = resolveRelation(node.actor, ctx, personResolver);
|
|
1347
|
+
node.director = resolveRelation(node.director, ctx, personResolver);
|
|
1348
|
+
node.creator = resolveRelation(node.creator, ctx, personResolver);
|
|
1349
|
+
node.productionCompany = resolveRelation(node.productionCompany, ctx, organizationResolver);
|
|
1350
|
+
node.aggregateRating = resolveRelation(node.aggregateRating, ctx, aggregateRatingResolver);
|
|
1351
|
+
node.trailer = resolveRelation(node.trailer, ctx, videoResolver);
|
|
1352
|
+
if (node.datePublished)
|
|
1353
|
+
node.datePublished = resolvableDateToIso(node.datePublished);
|
|
1354
|
+
if (node.startDate)
|
|
1355
|
+
node.startDate = resolvableDateToIso(node.startDate);
|
|
1356
|
+
if (node.endDate)
|
|
1357
|
+
node.endDate = resolvableDateToIso(node.endDate);
|
|
1358
|
+
return node;
|
|
1359
|
+
}
|
|
1360
|
+
});
|
|
1361
|
+
|
|
1362
|
+
function nextNodeId(ctx, alias) {
|
|
1363
|
+
ctx.nodeIdCounters[alias] = (ctx.nodeIdCounters[alias] || 0) + 1;
|
|
1364
|
+
return ctx.nodeIdCounters[alias].toString();
|
|
1365
|
+
}
|
|
1366
|
+
function resolveMeta(meta) {
|
|
1367
|
+
if (!meta.path)
|
|
1368
|
+
meta.path = "/";
|
|
1369
|
+
if (!meta.host && typeof document !== "undefined")
|
|
1370
|
+
meta.host = document.location.host;
|
|
1371
|
+
if (meta.path !== "/") {
|
|
1372
|
+
if (meta.trailingSlash && !hasTrailingSlash(meta.path))
|
|
1373
|
+
meta.path = withTrailingSlash(meta.path);
|
|
1374
|
+
else if (!meta.trailingSlash && hasTrailingSlash(meta.path))
|
|
1375
|
+
meta.path = withoutTrailingSlash(meta.path);
|
|
1376
|
+
}
|
|
1377
|
+
meta.url = joinURL(meta.host || "", meta.path);
|
|
1378
|
+
return {
|
|
1379
|
+
...meta,
|
|
1380
|
+
host: meta.host,
|
|
1381
|
+
url: meta.url,
|
|
1382
|
+
currency: meta.currency,
|
|
1383
|
+
image: meta.image,
|
|
1384
|
+
inLanguage: meta.inLanguage,
|
|
1385
|
+
title: meta.title,
|
|
1386
|
+
description: meta.description,
|
|
1387
|
+
datePublished: meta.datePublished,
|
|
1388
|
+
dateModified: meta.dateModified
|
|
1389
|
+
};
|
|
1390
|
+
}
|
|
1391
|
+
function resolveNode(node, ctx, resolver) {
|
|
1392
|
+
if (resolver?.cast)
|
|
1393
|
+
node = resolver.cast(node, ctx);
|
|
1394
|
+
if (resolver?.defaults) {
|
|
1395
|
+
let defaults = resolver.defaults;
|
|
1396
|
+
if (typeof defaults === "function")
|
|
1397
|
+
defaults = defaults(ctx);
|
|
1398
|
+
node = { ...defaults, ...node };
|
|
1399
|
+
}
|
|
1400
|
+
const inheritMeta = resolver?.inheritMeta;
|
|
1401
|
+
if (inheritMeta) {
|
|
1402
|
+
for (let i = 0; i < inheritMeta.length; i++) {
|
|
1403
|
+
const entry = inheritMeta[i];
|
|
1404
|
+
if (typeof entry === "string")
|
|
1405
|
+
setIfEmpty(node, entry, ctx.meta[entry]);
|
|
1406
|
+
else
|
|
1407
|
+
setIfEmpty(node, entry.key, ctx.meta[entry.meta]);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
if (resolver?.resolve)
|
|
1411
|
+
node = resolver.resolve(node, ctx);
|
|
1412
|
+
for (const k in node) {
|
|
1413
|
+
const v = node[k];
|
|
1414
|
+
if (Array.isArray(v)) {
|
|
1415
|
+
for (let i = 0; i < v.length; i++) {
|
|
1416
|
+
const item = v[i];
|
|
1417
|
+
if (typeof item === "object" && item?._resolver)
|
|
1418
|
+
node[k][i] = resolveRelation(item, ctx, item._resolver);
|
|
1419
|
+
}
|
|
1420
|
+
} else if (typeof v === "object" && v?._resolver) {
|
|
1421
|
+
node[k] = resolveRelation(v, ctx, v._resolver);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
stripEmptyProperties(node);
|
|
1425
|
+
return node;
|
|
1426
|
+
}
|
|
1427
|
+
function resolveNodeId(node, ctx, resolver, resolveAsRoot = false) {
|
|
1428
|
+
if (node["@id"] && node["@id"].startsWith("http"))
|
|
1429
|
+
return node;
|
|
1430
|
+
const prefix = resolver ? (Array.isArray(resolver.idPrefix) ? resolver.idPrefix[0] : resolver.idPrefix) || "url" : "url";
|
|
1431
|
+
const rootId = node["@id"] || (resolver ? Array.isArray(resolver.idPrefix) ? resolver.idPrefix?.[1] : void 0 : "");
|
|
1432
|
+
if (!node["@id"] && resolveAsRoot && rootId) {
|
|
1433
|
+
node["@id"] = prefixId(ctx.meta[prefix], rootId);
|
|
1434
|
+
return node;
|
|
1435
|
+
}
|
|
1436
|
+
if (node["@id"]?.startsWith("#/schema/") || node["@id"]?.startsWith("/")) {
|
|
1437
|
+
node["@id"] = prefixId(ctx.meta[prefix], node["@id"]);
|
|
1438
|
+
return node;
|
|
1439
|
+
}
|
|
1440
|
+
let alias = resolver?.alias;
|
|
1441
|
+
if (!alias) {
|
|
1442
|
+
const type = asArray(node["@type"])?.[0] || "";
|
|
1443
|
+
alias = type.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
1444
|
+
}
|
|
1445
|
+
node["@id"] = prefixId(ctx.meta[prefix], `#/schema/${alias}/${node["@id"] || nextNodeId(ctx, alias)}`);
|
|
1446
|
+
return node;
|
|
1447
|
+
}
|
|
1448
|
+
function resolveRelation(input, ctx, fallbackResolver, options = {}) {
|
|
1449
|
+
if (!input)
|
|
1450
|
+
return input;
|
|
1451
|
+
const items = asArray(input);
|
|
1452
|
+
const ids = [];
|
|
1453
|
+
for (let i = 0; i < items.length; i++) {
|
|
1454
|
+
const a = items[i];
|
|
1455
|
+
let keyCount = 0;
|
|
1456
|
+
for (const _ in a) keyCount++;
|
|
1457
|
+
if (keyCount === 1 && a["@id"] || keyCount === 2 && a["@id"] && a["@type"]) {
|
|
1458
|
+
ids.push(resolveNodeId({
|
|
1459
|
+
"@id": ctx.find(a["@id"])?.["@id"] || a["@id"]
|
|
1460
|
+
}, ctx));
|
|
1461
|
+
continue;
|
|
1462
|
+
}
|
|
1463
|
+
let resolver = fallbackResolver;
|
|
1464
|
+
if (a._resolver && typeof a._resolver !== "string") {
|
|
1465
|
+
resolver = a._resolver;
|
|
1466
|
+
delete a._resolver;
|
|
1467
|
+
}
|
|
1468
|
+
if (!resolver) {
|
|
1469
|
+
ids.push(a);
|
|
1470
|
+
continue;
|
|
1471
|
+
}
|
|
1472
|
+
let node = resolveNode(a, ctx, resolver);
|
|
1473
|
+
if (options.afterResolve)
|
|
1474
|
+
options.afterResolve(node);
|
|
1475
|
+
if (options.generateId || options.root)
|
|
1476
|
+
node = resolveNodeId(node, ctx, resolver, false);
|
|
1477
|
+
if (options.root) {
|
|
1478
|
+
if (resolver.resolveRootNode)
|
|
1479
|
+
resolver.resolveRootNode(node, ctx);
|
|
1480
|
+
ctx.push(node);
|
|
1481
|
+
ids.push(idReference(node["@id"]));
|
|
1482
|
+
continue;
|
|
1483
|
+
}
|
|
1484
|
+
ids.push(node);
|
|
1485
|
+
}
|
|
1486
|
+
return !options.array && ids.length === 1 ? ids[0] : ids;
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
function merge(target, source) {
|
|
1490
|
+
if (!source)
|
|
1491
|
+
return target;
|
|
1492
|
+
for (const key in source) {
|
|
1493
|
+
if (!Object.prototype.hasOwnProperty.call(source, key))
|
|
1494
|
+
continue;
|
|
1495
|
+
const value = source[key];
|
|
1496
|
+
if (value === void 0)
|
|
1497
|
+
continue;
|
|
1498
|
+
if (Array.isArray(target[key])) {
|
|
1499
|
+
if (Array.isArray(value)) {
|
|
1500
|
+
const merged = [...target[key], ...value];
|
|
1501
|
+
if (key === "@type") {
|
|
1502
|
+
target[key] = [...new Set(merged)];
|
|
1503
|
+
} else if (key === "itemListElement") {
|
|
1504
|
+
merged.sort((a, b) => (a.position || 0) - (b.position || 0));
|
|
1505
|
+
for (let i = 0; i < merged.length; i++)
|
|
1506
|
+
merged[i].position = i + 1;
|
|
1507
|
+
target[key] = merged;
|
|
1508
|
+
} else if (key === "potentialAction") {
|
|
1509
|
+
const byType = {};
|
|
1510
|
+
for (const action of merged) {
|
|
1511
|
+
const type = action["@type"];
|
|
1512
|
+
if (byType[type]) {
|
|
1513
|
+
if (action.target && byType[type].target)
|
|
1514
|
+
byType[type].target = [.../* @__PURE__ */ new Set([...byType[type].target, ...action.target])];
|
|
1515
|
+
} else {
|
|
1516
|
+
byType[type] = { ...action };
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
target[key] = Object.values(byType);
|
|
1520
|
+
} else {
|
|
1521
|
+
target[key] = merged;
|
|
1522
|
+
}
|
|
1523
|
+
} else {
|
|
1524
|
+
target[key] = merge(target[key], [value]);
|
|
1525
|
+
}
|
|
1526
|
+
} else if (target[key] && typeof target[key] === "object" && typeof value === "object" && !Array.isArray(value)) {
|
|
1527
|
+
target[key] = merge({ ...target[key] }, value);
|
|
1528
|
+
} else {
|
|
1529
|
+
target[key] = value;
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
return target;
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
function indexNode(index, node) {
|
|
1536
|
+
if (!node["@id"])
|
|
1537
|
+
return;
|
|
1538
|
+
const nodeId = node["@id"];
|
|
1539
|
+
const fragmentKey = resolveAsGraphKey(nodeId);
|
|
1540
|
+
index.set(fragmentKey, node);
|
|
1541
|
+
index.set(nodeId, node);
|
|
1542
|
+
const domainKey = nodeId.replace(/(https?:)?\/\//, "").split("/")[0];
|
|
1543
|
+
index.set(domainKey, node);
|
|
1544
|
+
}
|
|
1545
|
+
function createSchemaOrgGraph() {
|
|
1546
|
+
const ctx = {
|
|
1547
|
+
find(id) {
|
|
1548
|
+
let resolver = (s) => s;
|
|
1549
|
+
if (id[0] === "#") {
|
|
1550
|
+
resolver = resolveAsGraphKey;
|
|
1551
|
+
} else if (id[0] === "/") {
|
|
1552
|
+
resolver = (s) => s.replace(/(https?:)?\/\//, "").split("/")[0];
|
|
1553
|
+
}
|
|
1554
|
+
const key = resolver(id);
|
|
1555
|
+
if (ctx.nodeIndex.size > 0) {
|
|
1556
|
+
return ctx.nodeIndex.get(key) || null;
|
|
1557
|
+
}
|
|
1558
|
+
return ctx.nodes.filter((n) => !!n["@id"]).find((n) => resolver(n["@id"]) === key);
|
|
1559
|
+
},
|
|
1560
|
+
push(input) {
|
|
1561
|
+
asArray(input).forEach((node) => {
|
|
1562
|
+
const registeredNode = node;
|
|
1563
|
+
ctx.nodes.push(registeredNode);
|
|
1564
|
+
if (ctx.nodeIndex.size > 0)
|
|
1565
|
+
indexNode(ctx.nodeIndex, registeredNode);
|
|
1566
|
+
});
|
|
1567
|
+
},
|
|
1568
|
+
resolveGraph(meta) {
|
|
1569
|
+
for (const k in ctx.nodeIdCounters) delete ctx.nodeIdCounters[k];
|
|
1570
|
+
ctx.meta = resolveMeta({ ...meta });
|
|
1571
|
+
const len = ctx.nodes.length;
|
|
1572
|
+
for (let i = 0; i < len; i++) {
|
|
1573
|
+
let node = ctx.nodes[i];
|
|
1574
|
+
const resolver = node._resolver;
|
|
1575
|
+
node = resolveNode(node, ctx, resolver);
|
|
1576
|
+
node = resolveNodeId(node, ctx, resolver, true);
|
|
1577
|
+
ctx.nodes[i] = node;
|
|
1578
|
+
}
|
|
1579
|
+
const dedupedNodes = {};
|
|
1580
|
+
ctx.nodeIndex = /* @__PURE__ */ new Map();
|
|
1581
|
+
for (let i = 0; i < ctx.nodes.length; i++) {
|
|
1582
|
+
const n = ctx.nodes[i];
|
|
1583
|
+
const nodeKey = resolveAsGraphKey(n["@id"]);
|
|
1584
|
+
if (dedupedNodes[nodeKey]) {
|
|
1585
|
+
if (n._dedupeStrategy !== "replace")
|
|
1586
|
+
dedupedNodes[nodeKey] = merge(dedupedNodes[nodeKey], n);
|
|
1587
|
+
else
|
|
1588
|
+
dedupedNodes[nodeKey] = n;
|
|
1589
|
+
} else {
|
|
1590
|
+
dedupedNodes[nodeKey] = n;
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
ctx.nodes = Object.values(dedupedNodes);
|
|
1594
|
+
for (let i = 0; i < ctx.nodes.length; i++)
|
|
1595
|
+
indexNode(ctx.nodeIndex, ctx.nodes[i]);
|
|
1596
|
+
const countBeforeRelations = ctx.nodes.length;
|
|
1597
|
+
for (let i = 0; i < ctx.nodes.length; i++) {
|
|
1598
|
+
const node = ctx.nodes[i];
|
|
1599
|
+
if (node.image && typeof node.image === "string") {
|
|
1600
|
+
node.image = resolveRelation(node.image, ctx, imageResolver, {
|
|
1601
|
+
root: true
|
|
1602
|
+
});
|
|
1603
|
+
}
|
|
1604
|
+
node.translationOfWork = resolveRelation(node.translationOfWork, ctx);
|
|
1605
|
+
node.workTranslation = resolveRelation(node.workTranslation, ctx);
|
|
1606
|
+
if (node._resolver?.resolveRootNode)
|
|
1607
|
+
node._resolver.resolveRootNode(node, ctx);
|
|
1608
|
+
delete node._resolver;
|
|
1609
|
+
}
|
|
1610
|
+
const needsDedupe = ctx.nodes.length > countBeforeRelations;
|
|
1611
|
+
const normalizedNodes = needsDedupe ? {} : null;
|
|
1612
|
+
const result = needsDedupe ? null : [];
|
|
1613
|
+
for (let i = 0; i < ctx.nodes.length; i++) {
|
|
1614
|
+
const n = ctx.nodes[i];
|
|
1615
|
+
const nodeKey = resolveAsGraphKey(n["@id"]);
|
|
1616
|
+
const keys = Object.keys(n);
|
|
1617
|
+
const primitives = [];
|
|
1618
|
+
const relations = [];
|
|
1619
|
+
for (let j = 0; j < keys.length; j++) {
|
|
1620
|
+
const k = keys[j];
|
|
1621
|
+
if (k[0] === "_")
|
|
1622
|
+
continue;
|
|
1623
|
+
const v = n[k];
|
|
1624
|
+
if (v !== null && (Array.isArray(v) || typeof v === "object"))
|
|
1625
|
+
relations.push(k);
|
|
1626
|
+
else
|
|
1627
|
+
primitives.push(k);
|
|
1628
|
+
}
|
|
1629
|
+
primitives.sort();
|
|
1630
|
+
relations.sort();
|
|
1631
|
+
const newNode = {};
|
|
1632
|
+
for (let j = 0; j < primitives.length; j++)
|
|
1633
|
+
newNode[primitives[j]] = n[primitives[j]];
|
|
1634
|
+
for (let j = 0; j < relations.length; j++)
|
|
1635
|
+
newNode[relations[j]] = n[relations[j]];
|
|
1636
|
+
if (needsDedupe) {
|
|
1637
|
+
normalizedNodes[nodeKey] = normalizedNodes[nodeKey] ? merge(normalizedNodes[nodeKey], newNode) : newNode;
|
|
1638
|
+
} else {
|
|
1639
|
+
result.push(newNode);
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
return needsDedupe ? Object.values(normalizedNodes) : result;
|
|
1643
|
+
},
|
|
1644
|
+
nodes: [],
|
|
1645
|
+
nodeIndex: /* @__PURE__ */ new Map(),
|
|
1646
|
+
nodeIdCounters: {},
|
|
1647
|
+
meta: {}
|
|
1648
|
+
};
|
|
1649
|
+
return ctx;
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
function mergeObjects(target, source) {
|
|
1653
|
+
const result = { ...target };
|
|
1654
|
+
for (const key in source) {
|
|
1655
|
+
if (!Object.prototype.hasOwnProperty.call(source, key) || source[key] === void 0)
|
|
1656
|
+
continue;
|
|
1657
|
+
const isNestedObject = result[key] && typeof result[key] === "object" && typeof source[key] === "object" && !Array.isArray(result[key]) && !Array.isArray(source[key]);
|
|
1658
|
+
if (isNestedObject)
|
|
1659
|
+
result[key] = mergeObjects(result[key], source[key]);
|
|
1660
|
+
else if (!result[key])
|
|
1661
|
+
result[key] = source[key];
|
|
1662
|
+
}
|
|
1663
|
+
return result;
|
|
1664
|
+
}
|
|
1665
|
+
function UnheadSchemaOrg(config = {}, meta = () => ({}), options) {
|
|
1666
|
+
config = resolveMeta({ ...config });
|
|
1667
|
+
let graph;
|
|
1668
|
+
let resolvedMeta = {};
|
|
1669
|
+
return defineHeadPlugin((head) => {
|
|
1670
|
+
head.use(TemplateParamsPlugin);
|
|
1671
|
+
return {
|
|
1672
|
+
key: "schema-org",
|
|
1673
|
+
hooks: {
|
|
1674
|
+
"entries:normalize": ({ tags }) => {
|
|
1675
|
+
graph = graph || createSchemaOrgGraph();
|
|
1676
|
+
for (const tag of tags) {
|
|
1677
|
+
if (tag.tag === "script" && tag.props.type === "application/ld+json" && tag.props.nodes) {
|
|
1678
|
+
const nodes = tag.props.nodes;
|
|
1679
|
+
for (const node of Array.isArray(nodes) ? nodes : [nodes]) {
|
|
1680
|
+
if (typeof node !== "object" || node === null) {
|
|
1681
|
+
continue;
|
|
1682
|
+
}
|
|
1683
|
+
const newNode = {
|
|
1684
|
+
...node,
|
|
1685
|
+
_dedupeStrategy: tag.tagDuplicateStrategy
|
|
1686
|
+
};
|
|
1687
|
+
graph.push(newNode);
|
|
1688
|
+
}
|
|
1689
|
+
tag.tagPosition = tag.tagPosition || config.tagPosition === "head" ? "head" : "bodyClose";
|
|
1690
|
+
}
|
|
1691
|
+
if (tag.tag === "htmlAttrs" && tag.props.lang) {
|
|
1692
|
+
resolvedMeta.inLanguage = tag.props.lang;
|
|
1693
|
+
} else if (tag.tag === "title") {
|
|
1694
|
+
resolvedMeta.title = tag.textContent;
|
|
1695
|
+
} else if (tag.tag === "meta" && tag.props.name === "description") {
|
|
1696
|
+
resolvedMeta.description = tag.props.content;
|
|
1697
|
+
} else if (tag.tag === "link" && tag.props.rel === "canonical") {
|
|
1698
|
+
resolvedMeta.url = tag.props.href;
|
|
1699
|
+
if (resolvedMeta.url && !resolvedMeta.host) {
|
|
1700
|
+
try {
|
|
1701
|
+
resolvedMeta.host = new URL(resolvedMeta.url).origin;
|
|
1702
|
+
} catch {
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
} else if (tag.tag === "meta" && tag.props.property === "og:image") {
|
|
1706
|
+
resolvedMeta.image = tag.props.content;
|
|
1707
|
+
} else if (tag.tag === "templateParams" && tag.props.schemaOrg) {
|
|
1708
|
+
resolvedMeta = {
|
|
1709
|
+
...resolvedMeta,
|
|
1710
|
+
...tag.props.schemaOrg
|
|
1711
|
+
};
|
|
1712
|
+
delete tag.props.schemaOrg;
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
},
|
|
1716
|
+
"tags:resolve": async (ctx) => {
|
|
1717
|
+
for (const k in ctx.tags) {
|
|
1718
|
+
const tag = ctx.tags[k];
|
|
1719
|
+
if (tag.tag === "script" && tag.props.type === "application/ld+json" && tag.props.nodes) {
|
|
1720
|
+
delete tag.props.nodes;
|
|
1721
|
+
const resolvedGraph = graph.resolveGraph({ ...meta?.() || {}, ...config, ...resolvedMeta });
|
|
1722
|
+
if (!resolvedGraph.length) {
|
|
1723
|
+
tag.props = {};
|
|
1724
|
+
return;
|
|
1725
|
+
}
|
|
1726
|
+
const minify = options?.minify || process.env.NODE_ENV === "production";
|
|
1727
|
+
tag.innerHTML = JSON.stringify({
|
|
1728
|
+
"@context": "https://schema.org",
|
|
1729
|
+
"@graph": resolvedGraph
|
|
1730
|
+
}, (_, value) => {
|
|
1731
|
+
if (typeof value !== "object")
|
|
1732
|
+
return processTemplateParams(value, head._templateParams, head._separator);
|
|
1733
|
+
return value;
|
|
1734
|
+
}, minify ? 0 : 2);
|
|
1735
|
+
return;
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
},
|
|
1739
|
+
"tags:afterResolve": (ctx) => {
|
|
1740
|
+
let firstNodeIdx;
|
|
1741
|
+
const toRemove = /* @__PURE__ */ new Set();
|
|
1742
|
+
for (let i = 0; i < ctx.tags.length; i++) {
|
|
1743
|
+
const tag = ctx.tags[i];
|
|
1744
|
+
if (!tag)
|
|
1745
|
+
continue;
|
|
1746
|
+
if (tag.props.type === "application/ld+json" && tag.props.nodes || tag.key === "schema-org-graph") {
|
|
1747
|
+
delete tag.props.nodes;
|
|
1748
|
+
if (typeof firstNodeIdx === "undefined") {
|
|
1749
|
+
firstNodeIdx = i;
|
|
1750
|
+
continue;
|
|
1751
|
+
}
|
|
1752
|
+
ctx.tags[firstNodeIdx].props = mergeObjects(ctx.tags[firstNodeIdx].props, tag.props);
|
|
1753
|
+
delete ctx.tags[firstNodeIdx].props.nodes;
|
|
1754
|
+
toRemove.add(i);
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
ctx.tags = ctx.tags.filter((_, i) => !toRemove.has(i));
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
};
|
|
1761
|
+
});
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
function provideResolver(input, resolver) {
|
|
1765
|
+
if (!input)
|
|
1766
|
+
input = {};
|
|
1767
|
+
return { ...input, _resolver: resolver };
|
|
1768
|
+
}
|
|
1769
|
+
function defineAddress(input) {
|
|
1770
|
+
return provideResolver(input, addressResolver);
|
|
1771
|
+
}
|
|
1772
|
+
function defineAggregateOffer(input) {
|
|
1773
|
+
return provideResolver(input, aggregateOfferResolver);
|
|
1774
|
+
}
|
|
1775
|
+
function defineAggregateRating(input) {
|
|
1776
|
+
return provideResolver(input, aggregateRatingResolver);
|
|
1777
|
+
}
|
|
1778
|
+
function defineArticle(input) {
|
|
1779
|
+
return provideResolver(input, articleResolver);
|
|
1780
|
+
}
|
|
1781
|
+
function defineBreadcrumb(input) {
|
|
1782
|
+
return provideResolver(input, breadcrumbResolver);
|
|
1783
|
+
}
|
|
1784
|
+
function defineComment(input) {
|
|
1785
|
+
return provideResolver(input, commentResolver);
|
|
1786
|
+
}
|
|
1787
|
+
function defineEvent(input) {
|
|
1788
|
+
return provideResolver(input, eventResolver);
|
|
1789
|
+
}
|
|
1790
|
+
function defineFoodEstablishment(input) {
|
|
1791
|
+
return provideResolver(input, foodEstablishmentResolver);
|
|
1792
|
+
}
|
|
1793
|
+
function defineVirtualLocation(input) {
|
|
1794
|
+
return provideResolver(input, virtualLocationResolver);
|
|
1795
|
+
}
|
|
1796
|
+
function definePlace(input) {
|
|
1797
|
+
return provideResolver(input, placeResolver);
|
|
1798
|
+
}
|
|
1799
|
+
function defineHowTo(input) {
|
|
1800
|
+
return provideResolver(input, howToResolver);
|
|
1801
|
+
}
|
|
1802
|
+
function defineHowToStep(input) {
|
|
1803
|
+
return provideResolver(input, howToStepResolver);
|
|
1804
|
+
}
|
|
1805
|
+
function defineImage(input) {
|
|
1806
|
+
return provideResolver(input, imageResolver);
|
|
1807
|
+
}
|
|
1808
|
+
function defineJobPosting(input) {
|
|
1809
|
+
return provideResolver(input, jobPostingResolver);
|
|
1810
|
+
}
|
|
1811
|
+
function defineLocalBusiness(input) {
|
|
1812
|
+
return provideResolver(input, localBusinessResolver);
|
|
1813
|
+
}
|
|
1814
|
+
function defineOffer(input) {
|
|
1815
|
+
return provideResolver(input, offerResolver);
|
|
1816
|
+
}
|
|
1817
|
+
function defineOpeningHours(input) {
|
|
1818
|
+
return provideResolver(input, openingHoursResolver);
|
|
1819
|
+
}
|
|
1820
|
+
function defineOrganization(input) {
|
|
1821
|
+
return provideResolver(input, organizationResolver);
|
|
1822
|
+
}
|
|
1823
|
+
function definePerson(input) {
|
|
1824
|
+
return provideResolver(input, personResolver);
|
|
1825
|
+
}
|
|
1826
|
+
function defineProduct(input) {
|
|
1827
|
+
return provideResolver(input, productResolver);
|
|
1828
|
+
}
|
|
1829
|
+
function defineQuestion(input) {
|
|
1830
|
+
return provideResolver(input, questionResolver);
|
|
1831
|
+
}
|
|
1832
|
+
function defineRecipe(input) {
|
|
1833
|
+
return provideResolver(input, recipeResolver);
|
|
1834
|
+
}
|
|
1835
|
+
function defineReview(input) {
|
|
1836
|
+
return provideResolver(input, reviewResolver);
|
|
1837
|
+
}
|
|
1838
|
+
function defineVideo(input) {
|
|
1839
|
+
return provideResolver(input, videoResolver);
|
|
1840
|
+
}
|
|
1841
|
+
function defineWebPage(input) {
|
|
1842
|
+
return provideResolver(input, webPageResolver);
|
|
1843
|
+
}
|
|
1844
|
+
function defineWebSite(input) {
|
|
1845
|
+
return provideResolver(input, webSiteResolver);
|
|
1846
|
+
}
|
|
1847
|
+
function defineBook(input) {
|
|
1848
|
+
return provideResolver(input, bookResolver);
|
|
1849
|
+
}
|
|
1850
|
+
function defineCourse(input) {
|
|
1851
|
+
return provideResolver(input, courseResolver);
|
|
1852
|
+
}
|
|
1853
|
+
function defineItemList(input) {
|
|
1854
|
+
return provideResolver(input, itemListResolver);
|
|
1855
|
+
}
|
|
1856
|
+
function defineListItem(input) {
|
|
1857
|
+
return provideResolver(input, listItemResolver);
|
|
1858
|
+
}
|
|
1859
|
+
function defineMovie(input) {
|
|
1860
|
+
return provideResolver(input, movieResolver);
|
|
1861
|
+
}
|
|
1862
|
+
function defineSearchAction(input) {
|
|
1863
|
+
return provideResolver(input, searchActionResolver);
|
|
1864
|
+
}
|
|
1865
|
+
function defineReadAction(input) {
|
|
1866
|
+
return provideResolver(input, readActionResolver);
|
|
1867
|
+
}
|
|
1868
|
+
function defineDataset(input) {
|
|
1869
|
+
return provideResolver(input, datasetResolver);
|
|
1870
|
+
}
|
|
1871
|
+
function defineMusicRecording(input) {
|
|
1872
|
+
return provideResolver(input, musicRecordingResolver);
|
|
1873
|
+
}
|
|
1874
|
+
function defineMusicAlbum(input) {
|
|
1875
|
+
return provideResolver(input, musicAlbumResolver);
|
|
1876
|
+
}
|
|
1877
|
+
function defineMusicGroup(input) {
|
|
1878
|
+
return provideResolver(input, musicGroupResolver);
|
|
1879
|
+
}
|
|
1880
|
+
function defineMusicPlaylist(input) {
|
|
1881
|
+
return provideResolver(input, musicPlaylistResolver);
|
|
1882
|
+
}
|
|
1883
|
+
function definePodcastSeries(input) {
|
|
1884
|
+
return provideResolver(input, podcastSeriesResolver);
|
|
1885
|
+
}
|
|
1886
|
+
function definePodcastEpisode(input) {
|
|
1887
|
+
return provideResolver(input, podcastEpisodeResolver);
|
|
1888
|
+
}
|
|
1889
|
+
function definePodcastSeason(input) {
|
|
1890
|
+
return provideResolver(input, podcastSeasonResolver);
|
|
1891
|
+
}
|
|
1892
|
+
function defineTVSeries(input) {
|
|
1893
|
+
return provideResolver(input, tvSeriesResolver);
|
|
1894
|
+
}
|
|
1895
|
+
function defineTVSeason(input) {
|
|
1896
|
+
return provideResolver(input, tvSeasonResolver);
|
|
1897
|
+
}
|
|
1898
|
+
function defineTVEpisode(input) {
|
|
1899
|
+
return provideResolver(input, tvEpisodeResolver);
|
|
1900
|
+
}
|
|
1901
|
+
function defineService(input) {
|
|
1902
|
+
return provideResolver(input, serviceResolver);
|
|
1903
|
+
}
|
|
1904
|
+
function defineSoftwareApp(input) {
|
|
1905
|
+
return provideResolver(input, softwareAppResolver);
|
|
1906
|
+
}
|
|
1907
|
+
function defineBookEdition(input) {
|
|
1908
|
+
return provideResolver(input, bookEditionResolver);
|
|
1909
|
+
}
|
|
1910
|
+
function normalizeSchemaOrgInput(input) {
|
|
1911
|
+
if (input.script) {
|
|
1912
|
+
return input;
|
|
1913
|
+
}
|
|
1914
|
+
return {
|
|
1915
|
+
script: [
|
|
1916
|
+
{
|
|
1917
|
+
type: "application/ld+json",
|
|
1918
|
+
key: "schema-org-graph",
|
|
1919
|
+
nodes: input
|
|
1920
|
+
}
|
|
1921
|
+
]
|
|
1922
|
+
};
|
|
1923
|
+
}
|
|
1924
|
+
function useSchemaOrg(unhead, input = [], options = {}) {
|
|
1925
|
+
unhead.use(UnheadSchemaOrg());
|
|
1926
|
+
const entry = unhead.push(normalizeSchemaOrgInput(input), options);
|
|
1927
|
+
const corePatch = entry.patch;
|
|
1928
|
+
entry.patch = (input2) => corePatch(normalizeSchemaOrgInput(input2));
|
|
1929
|
+
return entry;
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
export { defineWebPage as $, defineMovie as A, defineMusicAlbum as B, defineMusicGroup as C, defineMusicPlaylist as D, defineMusicRecording as E, defineOffer as F, defineOpeningHours as G, defineOrganization as H, definePerson as I, definePlace as J, definePodcastEpisode as K, definePodcastSeason as L, definePodcastSeries as M, defineProduct as N, defineQuestion as O, defineReadAction as P, defineRecipe as Q, defineReview as R, defineSearchAction as S, defineService as T, UnheadSchemaOrg as U, defineSoftwareApp as V, defineTVEpisode as W, defineTVSeason as X, defineTVSeries as Y, defineVideo as Z, defineVirtualLocation as _, resolveNode as a, defineWebSite as a0, normalizeSchemaOrgInput as a1, useSchemaOrg as a2, aggregateOfferResolver as a3, aggregateRatingResolver as a4, PrimaryArticleId as a5, articleResolver as a6, bookEditionResolver as a7, PrimaryBookId as a8, bookResolver as a9, openingHoursResolver as aA, organizationResolver as aB, personResolver as aC, podcastEpisodeResolver as aD, podcastSeasonResolver as aE, podcastSeriesResolver as aF, addressResolver as aG, ProductId as aH, productResolver as aI, questionResolver as aJ, ratingResolver as aK, RecipeId as aL, recipeResolver as aM, reviewResolver as aN, ServiceId as aO, serviceResolver as aP, softwareAppResolver as aQ, tvEpisodeResolver as aR, tvSeasonResolver as aS, tvSeriesResolver as aT, videoResolver as aU, PrimaryWebPageId as aV, webPageResolver as aW, readActionResolver as aX, PrimaryWebSiteId as aY, webSiteResolver as aZ, searchActionResolver as a_, PrimaryBreadcrumbId as aa, breadcrumbResolver as ab, commentResolver as ac, courseResolver as ad, PrimaryDatasetId as ae, datasetResolver as af, PrimaryEventId as ag, eventResolver as ah, placeResolver as ai, virtualLocationResolver as aj, foodEstablishmentResolver as ak, HowToId as al, howToResolver as am, howToStepResolver as an, howToStepDirectionResolver as ao, imageResolver as ap, itemListResolver as aq, jobPostingResolver as ar, listItemResolver as as, localBusinessResolver as at, movieResolver as au, musicAlbumResolver as av, musicGroupResolver as aw, musicPlaylistResolver as ax, musicRecordingResolver as ay, offerResolver as az, resolveNodeId as b, createSchemaOrgGraph as c, defineSchemaOrgResolver as d, resolveRelation as e, defineAddress as f, defineAggregateOffer as g, defineAggregateRating as h, defineArticle as i, defineBook as j, defineBookEdition as k, defineBreadcrumb as l, merge as m, defineComment as n, defineCourse as o, defineDataset as p, defineEvent as q, resolveMeta as r, defineFoodEstablishment as s, defineHowTo as t, defineHowToStep as u, defineImage as v, defineItemList as w, defineJobPosting as x, defineListItem as y, defineLocalBusiness as z };
|