nuxt-schema-org 6.1.2 → 6.2.0

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