@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.
Files changed (68) hide show
  1. package/dist/index.d.mts +4 -4
  2. package/dist/index.d.ts +4 -4
  3. package/dist/index.mjs +2 -44
  4. package/dist/react.d.mts +3 -3
  5. package/dist/react.d.ts +3 -3
  6. package/dist/react.mjs +3 -3
  7. package/dist/shared/schema-org.BS2Q1uTx.d.mts +11 -0
  8. package/dist/shared/{schema-org.UT1u1UYq.d.mts → schema-org.C1OXVKVP.d.ts} +142 -48
  9. package/dist/shared/schema-org.C7IeLKiX.d.ts +11 -0
  10. package/dist/shared/{schema-org.CFcsqFfN.d.mts → schema-org.CX_95Tmq.d.mts} +2 -22
  11. package/dist/shared/{schema-org.CFcsqFfN.d.ts → schema-org.CX_95Tmq.d.ts} +2 -22
  12. package/dist/shared/{schema-org.CAKsqzbX.d.ts → schema-org.Cxijls86.d.mts} +142 -48
  13. package/dist/shared/schema-org.DvWGLdBv.mjs +1932 -0
  14. package/dist/solid-js.d.mts +3 -3
  15. package/dist/solid-js.d.ts +3 -3
  16. package/dist/solid-js.mjs +3 -3
  17. package/dist/svelte.d.mts +3 -3
  18. package/dist/svelte.d.ts +3 -3
  19. package/dist/svelte.mjs +3 -3
  20. package/dist/vue.d.mts +38 -38
  21. package/dist/vue.d.ts +38 -38
  22. package/dist/vue.mjs +47 -43
  23. package/package.json +11 -11
  24. package/dist/chunks/index.mjs +0 -23
  25. package/dist/chunks/index10.mjs +0 -63
  26. package/dist/chunks/index11.mjs +0 -35
  27. package/dist/chunks/index12.mjs +0 -48
  28. package/dist/chunks/index13.mjs +0 -36
  29. package/dist/chunks/index14.mjs +0 -25
  30. package/dist/chunks/index15.mjs +0 -37
  31. package/dist/chunks/index16.mjs +0 -27
  32. package/dist/chunks/index17.mjs +0 -34
  33. package/dist/chunks/index18.mjs +0 -32
  34. package/dist/chunks/index19.mjs +0 -31
  35. package/dist/chunks/index2.mjs +0 -12
  36. package/dist/chunks/index20.mjs +0 -31
  37. package/dist/chunks/index21.mjs +0 -30
  38. package/dist/chunks/index22.mjs +0 -30
  39. package/dist/chunks/index23.mjs +0 -82
  40. package/dist/chunks/index24.mjs +0 -14
  41. package/dist/chunks/index25.mjs +0 -33
  42. package/dist/chunks/index26.mjs +0 -31
  43. package/dist/chunks/index27.mjs +0 -29
  44. package/dist/chunks/index28.mjs +0 -12
  45. package/dist/chunks/index29.mjs +0 -46
  46. package/dist/chunks/index3.mjs +0 -317
  47. package/dist/chunks/index30.mjs +0 -53
  48. package/dist/chunks/index31.mjs +0 -41
  49. package/dist/chunks/index32.mjs +0 -26
  50. package/dist/chunks/index33.mjs +0 -47
  51. package/dist/chunks/index34.mjs +0 -29
  52. package/dist/chunks/index35.mjs +0 -34
  53. package/dist/chunks/index36.mjs +0 -33
  54. package/dist/chunks/index37.mjs +0 -34
  55. package/dist/chunks/index38.mjs +0 -51
  56. package/dist/chunks/index39.mjs +0 -17
  57. package/dist/chunks/index4.mjs +0 -54
  58. package/dist/chunks/index40.mjs +0 -29
  59. package/dist/chunks/index5.mjs +0 -31
  60. package/dist/chunks/index6.mjs +0 -29
  61. package/dist/chunks/index7.mjs +0 -35
  62. package/dist/chunks/index8.mjs +0 -18
  63. package/dist/chunks/index9.mjs +0 -20
  64. package/dist/shared/schema-org.B9Q-o8S0.mjs +0 -877
  65. package/dist/shared/schema-org.BR4WcSqZ.d.ts +0 -21
  66. package/dist/shared/schema-org.CrNDsWck.mjs +0 -19
  67. package/dist/shared/schema-org.oFHFm6my.d.mts +0 -21
  68. 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 };