@unhead/schema-org 1.8.3 → 1.8.5

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.
@@ -48,7 +48,7 @@ function dedupeMerge(node, field, value) {
48
48
  }
49
49
  function prefixId(url, id) {
50
50
  if (hasProtocol(id))
51
- return url;
51
+ return id;
52
52
  if (!id.startsWith("#"))
53
53
  id = `#${id}`;
54
54
  return joinURL(url, id);
@@ -294,17 +294,34 @@ const organizationResolver = defineSchemaOrgResolver({
294
294
  const isIdentity = resolveAsGraphKey(node["@id"]) === IdentityId;
295
295
  const webPage = ctx.find(PrimaryWebPageId);
296
296
  if (node.logo) {
297
- const logoNode = resolveRelation(node.logo, ctx, imageResolver, {
298
- root: true,
299
- afterResolve(logo) {
300
- if (isIdentity)
301
- logo["@id"] = prefixId(ctx.meta.host, "#logo");
302
- setIfEmpty(logo, "caption", node.name);
303
- }
304
- });
305
- node.logo = resolveRelation(node.logo, ctx, imageResolver, { root: false }).url;
306
- if (webPage && logoNode)
307
- setIfEmpty(webPage, "primaryImageOfPage", idReference(logoNode));
297
+ if (!ctx.find("#organization")) {
298
+ const logoNode = resolveRelation(node.logo, ctx, imageResolver, {
299
+ root: true,
300
+ afterResolve(logo) {
301
+ if (isIdentity)
302
+ logo["@id"] = prefixId(ctx.meta.host, "#logo");
303
+ setIfEmpty(logo, "caption", node.name);
304
+ }
305
+ });
306
+ if (webPage && logoNode)
307
+ setIfEmpty(webPage, "primaryImageOfPage", idReference(logoNode));
308
+ ctx.nodes.push({
309
+ // we want to make a simple node that has the essentials, this will allow parent nodes to inject
310
+ // as well without inserting invalid data (i.e LocalBusiness operatingHours)
311
+ "@type": "Organization",
312
+ "name": node.name,
313
+ "url": node.url,
314
+ "sameAs": node.sameAs,
315
+ // 'image': idReference(logoNode),
316
+ "address": node.address,
317
+ // needs to be a URL
318
+ "logo": resolveRelation(node.logo, ctx, imageResolver, { root: false }).url,
319
+ "_priority": -1,
320
+ "@id": prefixId(ctx.meta.host, "#organization")
321
+ // avoid the id so nothing can link to it
322
+ });
323
+ }
324
+ delete node.logo;
308
325
  }
309
326
  if (isIdentity && webPage)
310
327
  setIfEmpty(webPage, "about", idReference(node));
@@ -645,6 +662,66 @@ const eventResolver = defineSchemaOrgResolver({
645
662
  }
646
663
  });
647
664
 
665
+ const ratingResolver = defineSchemaOrgResolver({
666
+ cast(node) {
667
+ if (node === "number") {
668
+ return {
669
+ ratingValue: node
670
+ };
671
+ }
672
+ return node;
673
+ },
674
+ defaults: {
675
+ "@type": "Rating",
676
+ "bestRating": 5,
677
+ "worstRating": 1
678
+ }
679
+ });
680
+
681
+ const openingHoursResolver = defineSchemaOrgResolver({
682
+ defaults: {
683
+ "@type": "OpeningHoursSpecification",
684
+ "opens": "00:00",
685
+ "closes": "23:59"
686
+ }
687
+ });
688
+
689
+ const localBusinessResolver = defineSchemaOrgResolver({
690
+ defaults: {
691
+ "@type": ["Organization", "LocalBusiness"]
692
+ },
693
+ inheritMeta: [
694
+ { key: "url", meta: "host" },
695
+ { key: "currenciesAccepted", meta: "currency" }
696
+ ],
697
+ idPrefix: ["host", IdentityId],
698
+ resolve(node, ctx) {
699
+ resolveDefaultType(node, ["Organization", "LocalBusiness"]);
700
+ node.address = resolveRelation(node.address, ctx, addressResolver);
701
+ node.openingHoursSpecification = resolveRelation(node.openingHoursSpecification, ctx, openingHoursResolver);
702
+ node = resolveNode({ ...node }, ctx, organizationResolver);
703
+ organizationResolver.resolveRootNode(node, ctx);
704
+ return node;
705
+ }
706
+ });
707
+
708
+ const foodEstablishmentResolver = defineSchemaOrgResolver({
709
+ defaults: {
710
+ "@type": ["Organization", "LocalBusiness", "FoodEstablishment"]
711
+ },
712
+ inheritMeta: [
713
+ { key: "url", meta: "host" },
714
+ { key: "currenciesAccepted", meta: "currency" }
715
+ ],
716
+ idPrefix: ["host", IdentityId],
717
+ resolve(node, ctx) {
718
+ resolveDefaultType(node, ["Organization", "LocalBusiness", "FoodEstablishment"]);
719
+ node.starRating = resolveRelation(node.starRating, ctx, ratingResolver);
720
+ node = resolveNode(node, ctx, localBusinessResolver);
721
+ return node;
722
+ }
723
+ });
724
+
648
725
  const howToStepDirectionResolver = defineSchemaOrgResolver({
649
726
  cast(node) {
650
727
  if (typeof node === "string") {
@@ -745,6 +822,7 @@ const jobPostingResolver = defineSchemaOrgResolver({
745
822
  defaults: {
746
823
  "@type": "JobPosting"
747
824
  },
825
+ idPrefix: ["url", "#job-posting"],
748
826
  resolve(node, ctx) {
749
827
  node.datePosted = resolvableDateToIso(node.datePosted);
750
828
  node.hiringOrganization = resolveRelation(node.hiringOrganization, ctx, organizationResolver);
@@ -752,55 +830,15 @@ const jobPostingResolver = defineSchemaOrgResolver({
752
830
  node.baseSalary = resolveRelation(node.baseSalary, ctx, monetaryAmountResolver);
753
831
  node.validThrough = resolvableDateToIso(node.validThrough);
754
832
  return node;
755
- }
756
- });
757
-
758
- const openingHoursResolver = defineSchemaOrgResolver({
759
- defaults: {
760
- "@type": "OpeningHoursSpecification",
761
- "opens": "00:00",
762
- "closes": "23:59"
763
- }
764
- });
765
-
766
- const localBusinessResolver = defineSchemaOrgResolver({
767
- defaults: {
768
- "@type": ["Organization", "LocalBusiness"]
769
833
  },
770
- inheritMeta: [
771
- { key: "url", meta: "host" },
772
- { key: "currenciesAccepted", meta: "currency" }
773
- ],
774
- idPrefix: ["host", IdentityId],
775
- resolve(node, ctx) {
776
- resolveDefaultType(node, ["Organization", "LocalBusiness"]);
777
- node.address = resolveRelation(node.address, ctx, addressResolver);
778
- node.openingHoursSpecification = resolveRelation(node.openingHoursSpecification, ctx, openingHoursResolver);
779
- node.logo = resolveRelation(node.logo, ctx, imageResolver, {
780
- afterResolve(logo) {
781
- const hasLogo = !!ctx.find("#logo");
782
- if (!hasLogo)
783
- logo["@id"] = prefixId(ctx.meta.host, "#logo");
784
- setIfEmpty(logo, "caption", node.name);
785
- }
786
- });
787
- return node;
788
- }
789
- });
790
-
791
- const ratingResolver = defineSchemaOrgResolver({
792
- cast(node) {
793
- if (node === "number") {
794
- return {
795
- ratingValue: node
796
- };
797
- }
798
- return node;
799
- },
800
- defaults: {
801
- "@type": "Rating",
802
- "bestRating": 5,
803
- "worstRating": 1
834
+ resolveRootNode(jobPosting, { find }) {
835
+ const webPage = find(PrimaryWebPageId);
836
+ const identity = find(IdentityId);
837
+ if (identity)
838
+ setIfEmpty(jobPosting, "hiringOrganization", idReference(identity));
839
+ if (webPage)
840
+ setIfEmpty(jobPosting, "mainEntityOfPage", idReference(webPage));
841
+ return jobPosting;
804
842
  }
805
843
  });
806
844
 
@@ -1608,6 +1646,8 @@ function loadResolver(resolver) {
1608
1646
  return commentResolver;
1609
1647
  case "event":
1610
1648
  return eventResolver;
1649
+ case "foodEstablishment":
1650
+ return foodEstablishmentResolver;
1611
1651
  case "virtualLocation":
1612
1652
  return virtualLocationResolver;
1613
1653
  case "place":
@@ -1742,7 +1782,7 @@ function resolveNodeId(node, ctx, resolver, resolveAsRoot = false) {
1742
1782
  node["@id"] = prefixId(ctx.meta[prefix], node["@id"]);
1743
1783
  return node;
1744
1784
  }
1745
- const rootId = Array.isArray(resolver.idPrefix) ? resolver.idPrefix?.[1] : void 0;
1785
+ const rootId = node["@id"] || (Array.isArray(resolver.idPrefix) ? resolver.idPrefix?.[1] : void 0);
1746
1786
  if (resolveAsRoot && rootId) {
1747
1787
  node["@id"] = prefixId(ctx.meta[prefix], rootId);
1748
1788
  }
@@ -1799,11 +1839,8 @@ function resolveRelation(input, ctx, fallbackResolver, options = {}) {
1799
1839
  return ids;
1800
1840
  }
1801
1841
 
1802
- function isObject(value) {
1803
- return value !== null && typeof value === "object";
1804
- }
1805
1842
  function _defu(baseObject, defaults, namespace = ".", merger) {
1806
- if (!isObject(defaults)) {
1843
+ if (!_isPlainObject(defaults)) {
1807
1844
  return _defu(baseObject, {}, namespace, merger);
1808
1845
  }
1809
1846
  const object = Object.assign({}, defaults);
@@ -1820,7 +1857,7 @@ function _defu(baseObject, defaults, namespace = ".", merger) {
1820
1857
  }
1821
1858
  if (Array.isArray(value) && Array.isArray(object[key])) {
1822
1859
  object[key] = [...value, ...object[key]];
1823
- } else if (isObject(value) && isObject(object[key])) {
1860
+ } else if (_isPlainObject(value) && _isPlainObject(object[key])) {
1824
1861
  object[key] = _defu(
1825
1862
  value,
1826
1863
  object[key],
@@ -1833,6 +1870,13 @@ function _defu(baseObject, defaults, namespace = ".", merger) {
1833
1870
  }
1834
1871
  return object;
1835
1872
  }
1873
+ function _isPlainObject(value) {
1874
+ if (value === null || typeof value !== "object") {
1875
+ return false;
1876
+ }
1877
+ const prototype = Object.getPrototypeOf(value);
1878
+ return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value);
1879
+ }
1836
1880
  function createDefu(merger) {
1837
1881
  return (...arguments_) => (
1838
1882
  // eslint-disable-next-line unicorn/no-array-reduce
@@ -1970,7 +2014,7 @@ function SchemaOrgUnheadPlugin(config, meta, options) {
1970
2014
  };
1971
2015
  graph.push(newNode);
1972
2016
  }
1973
- tag.tagPosition = config.tagPosition === "head" ? "head" : "bodyClose";
2017
+ tag.tagPosition = tag.tagPosition || config.tagPosition === "head" ? "head" : "bodyClose";
1974
2018
  }
1975
2019
  if (tag.tag === "htmlAttrs" && tag.props.lang) {
1976
2020
  resolvedMeta.inLanguage = tag.props.lang;
@@ -2001,14 +2045,14 @@ function SchemaOrgUnheadPlugin(config, meta, options) {
2001
2045
  for (const tag of ctx.tags) {
2002
2046
  if (tag.tag === "script" && tag.key === "schema-org-graph") {
2003
2047
  const minify = options?.minify || process.env.NODE_ENV === "production";
2004
- tag.innerHTML = processTemplateParams(
2005
- JSON.stringify({
2006
- "@context": "https://schema.org",
2007
- "@graph": graph.resolveGraph({ ...await meta?.() || {}, ...config, ...resolvedMeta })
2008
- }, null, minify ? 0 : 2),
2009
- head._templateParams,
2010
- head._separator
2011
- );
2048
+ tag.innerHTML = JSON.stringify({
2049
+ "@context": "https://schema.org",
2050
+ "@graph": graph.resolveGraph({ ...await meta?.() || {}, ...config, ...resolvedMeta })
2051
+ }, (_, value) => {
2052
+ if (typeof value !== "object")
2053
+ return processTemplateParams(value, head._templateParams, head._separator);
2054
+ return value;
2055
+ }, minify ? 0 : 2);
2012
2056
  delete tag.props.nodes;
2013
2057
  return;
2014
2058
  }
@@ -2018,4 +2062,4 @@ function SchemaOrgUnheadPlugin(config, meta, options) {
2018
2062
  }));
2019
2063
  }
2020
2064
 
2021
- export { searchActionResolver as $, imageResolver as A, jobPostingResolver as B, listItemResolver as C, localBusinessResolver as D, movieResolver as E, offerResolver as F, openingHoursResolver as G, HowToId as H, organizationResolver as I, personResolver as J, addressResolver as K, ProductId as L, productResolver as M, questionResolver as N, ratingResolver as O, PrimaryArticleId as P, recipeResolver as Q, RecipeId as R, softwareAppResolver as S, reviewResolver as T, UnheadSchemaOrg as U, videoResolver as V, PrimaryWebPageId as W, webPageResolver as X, readActionResolver as Y, PrimaryWebSiteId as Z, webSiteResolver as _, dedupeNodes as a, PluginSchemaOrg as a0, SchemaOrgUnheadPlugin as a1, resolveNode as b, createSchemaOrgGraph as c, defineSchemaOrgResolver as d, resolveNodeId as e, resolveRelation as f, aggregateOfferResolver as g, aggregateRatingResolver as h, articleResolver as i, bookEditionResolver as j, PrimaryBookId as k, bookResolver as l, PrimaryBreadcrumbId as m, normaliseNodes as n, breadcrumbResolver as o, commentResolver as p, courseResolver as q, resolveMeta as r, PrimaryEventId as s, eventResolver as t, placeResolver as u, virtualLocationResolver as v, howToResolver as w, howToStepResolver as x, howToStepDirectionResolver as y, itemListResolver as z };
2065
+ export { webSiteResolver as $, itemListResolver as A, imageResolver as B, jobPostingResolver as C, listItemResolver as D, localBusinessResolver as E, movieResolver as F, offerResolver as G, HowToId as H, openingHoursResolver as I, organizationResolver as J, personResolver as K, addressResolver as L, ProductId as M, productResolver as N, questionResolver as O, PrimaryArticleId as P, ratingResolver as Q, RecipeId as R, recipeResolver as S, softwareAppResolver as T, UnheadSchemaOrg as U, reviewResolver as V, videoResolver as W, PrimaryWebPageId as X, webPageResolver as Y, readActionResolver as Z, PrimaryWebSiteId as _, dedupeNodes as a, searchActionResolver as a0, PluginSchemaOrg as a1, SchemaOrgUnheadPlugin as a2, resolveNode as b, createSchemaOrgGraph as c, defineSchemaOrgResolver as d, resolveNodeId as e, resolveRelation as f, aggregateOfferResolver as g, aggregateRatingResolver as h, articleResolver as i, bookEditionResolver as j, PrimaryBookId as k, bookResolver as l, PrimaryBreadcrumbId as m, normaliseNodes as n, breadcrumbResolver as o, commentResolver as p, courseResolver as q, resolveMeta as r, PrimaryEventId as s, eventResolver as t, placeResolver as u, virtualLocationResolver as v, foodEstablishmentResolver as w, howToResolver as x, howToStepResolver as y, howToStepDirectionResolver as z };
@@ -50,7 +50,7 @@ function dedupeMerge(node, field, value) {
50
50
  }
51
51
  function prefixId(url, id) {
52
52
  if (ufo.hasProtocol(id))
53
- return url;
53
+ return id;
54
54
  if (!id.startsWith("#"))
55
55
  id = `#${id}`;
56
56
  return ufo.joinURL(url, id);
@@ -296,17 +296,34 @@ const organizationResolver = defineSchemaOrgResolver({
296
296
  const isIdentity = resolveAsGraphKey(node["@id"]) === IdentityId;
297
297
  const webPage = ctx.find(PrimaryWebPageId);
298
298
  if (node.logo) {
299
- const logoNode = resolveRelation(node.logo, ctx, imageResolver, {
300
- root: true,
301
- afterResolve(logo) {
302
- if (isIdentity)
303
- logo["@id"] = prefixId(ctx.meta.host, "#logo");
304
- setIfEmpty(logo, "caption", node.name);
305
- }
306
- });
307
- node.logo = resolveRelation(node.logo, ctx, imageResolver, { root: false }).url;
308
- if (webPage && logoNode)
309
- setIfEmpty(webPage, "primaryImageOfPage", idReference(logoNode));
299
+ if (!ctx.find("#organization")) {
300
+ const logoNode = resolveRelation(node.logo, ctx, imageResolver, {
301
+ root: true,
302
+ afterResolve(logo) {
303
+ if (isIdentity)
304
+ logo["@id"] = prefixId(ctx.meta.host, "#logo");
305
+ setIfEmpty(logo, "caption", node.name);
306
+ }
307
+ });
308
+ if (webPage && logoNode)
309
+ setIfEmpty(webPage, "primaryImageOfPage", idReference(logoNode));
310
+ ctx.nodes.push({
311
+ // we want to make a simple node that has the essentials, this will allow parent nodes to inject
312
+ // as well without inserting invalid data (i.e LocalBusiness operatingHours)
313
+ "@type": "Organization",
314
+ "name": node.name,
315
+ "url": node.url,
316
+ "sameAs": node.sameAs,
317
+ // 'image': idReference(logoNode),
318
+ "address": node.address,
319
+ // needs to be a URL
320
+ "logo": resolveRelation(node.logo, ctx, imageResolver, { root: false }).url,
321
+ "_priority": -1,
322
+ "@id": prefixId(ctx.meta.host, "#organization")
323
+ // avoid the id so nothing can link to it
324
+ });
325
+ }
326
+ delete node.logo;
310
327
  }
311
328
  if (isIdentity && webPage)
312
329
  setIfEmpty(webPage, "about", idReference(node));
@@ -647,6 +664,66 @@ const eventResolver = defineSchemaOrgResolver({
647
664
  }
648
665
  });
649
666
 
667
+ const ratingResolver = defineSchemaOrgResolver({
668
+ cast(node) {
669
+ if (node === "number") {
670
+ return {
671
+ ratingValue: node
672
+ };
673
+ }
674
+ return node;
675
+ },
676
+ defaults: {
677
+ "@type": "Rating",
678
+ "bestRating": 5,
679
+ "worstRating": 1
680
+ }
681
+ });
682
+
683
+ const openingHoursResolver = defineSchemaOrgResolver({
684
+ defaults: {
685
+ "@type": "OpeningHoursSpecification",
686
+ "opens": "00:00",
687
+ "closes": "23:59"
688
+ }
689
+ });
690
+
691
+ const localBusinessResolver = defineSchemaOrgResolver({
692
+ defaults: {
693
+ "@type": ["Organization", "LocalBusiness"]
694
+ },
695
+ inheritMeta: [
696
+ { key: "url", meta: "host" },
697
+ { key: "currenciesAccepted", meta: "currency" }
698
+ ],
699
+ idPrefix: ["host", IdentityId],
700
+ resolve(node, ctx) {
701
+ resolveDefaultType(node, ["Organization", "LocalBusiness"]);
702
+ node.address = resolveRelation(node.address, ctx, addressResolver);
703
+ node.openingHoursSpecification = resolveRelation(node.openingHoursSpecification, ctx, openingHoursResolver);
704
+ node = resolveNode({ ...node }, ctx, organizationResolver);
705
+ organizationResolver.resolveRootNode(node, ctx);
706
+ return node;
707
+ }
708
+ });
709
+
710
+ const foodEstablishmentResolver = defineSchemaOrgResolver({
711
+ defaults: {
712
+ "@type": ["Organization", "LocalBusiness", "FoodEstablishment"]
713
+ },
714
+ inheritMeta: [
715
+ { key: "url", meta: "host" },
716
+ { key: "currenciesAccepted", meta: "currency" }
717
+ ],
718
+ idPrefix: ["host", IdentityId],
719
+ resolve(node, ctx) {
720
+ resolveDefaultType(node, ["Organization", "LocalBusiness", "FoodEstablishment"]);
721
+ node.starRating = resolveRelation(node.starRating, ctx, ratingResolver);
722
+ node = resolveNode(node, ctx, localBusinessResolver);
723
+ return node;
724
+ }
725
+ });
726
+
650
727
  const howToStepDirectionResolver = defineSchemaOrgResolver({
651
728
  cast(node) {
652
729
  if (typeof node === "string") {
@@ -747,6 +824,7 @@ const jobPostingResolver = defineSchemaOrgResolver({
747
824
  defaults: {
748
825
  "@type": "JobPosting"
749
826
  },
827
+ idPrefix: ["url", "#job-posting"],
750
828
  resolve(node, ctx) {
751
829
  node.datePosted = resolvableDateToIso(node.datePosted);
752
830
  node.hiringOrganization = resolveRelation(node.hiringOrganization, ctx, organizationResolver);
@@ -754,55 +832,15 @@ const jobPostingResolver = defineSchemaOrgResolver({
754
832
  node.baseSalary = resolveRelation(node.baseSalary, ctx, monetaryAmountResolver);
755
833
  node.validThrough = resolvableDateToIso(node.validThrough);
756
834
  return node;
757
- }
758
- });
759
-
760
- const openingHoursResolver = defineSchemaOrgResolver({
761
- defaults: {
762
- "@type": "OpeningHoursSpecification",
763
- "opens": "00:00",
764
- "closes": "23:59"
765
- }
766
- });
767
-
768
- const localBusinessResolver = defineSchemaOrgResolver({
769
- defaults: {
770
- "@type": ["Organization", "LocalBusiness"]
771
835
  },
772
- inheritMeta: [
773
- { key: "url", meta: "host" },
774
- { key: "currenciesAccepted", meta: "currency" }
775
- ],
776
- idPrefix: ["host", IdentityId],
777
- resolve(node, ctx) {
778
- resolveDefaultType(node, ["Organization", "LocalBusiness"]);
779
- node.address = resolveRelation(node.address, ctx, addressResolver);
780
- node.openingHoursSpecification = resolveRelation(node.openingHoursSpecification, ctx, openingHoursResolver);
781
- node.logo = resolveRelation(node.logo, ctx, imageResolver, {
782
- afterResolve(logo) {
783
- const hasLogo = !!ctx.find("#logo");
784
- if (!hasLogo)
785
- logo["@id"] = prefixId(ctx.meta.host, "#logo");
786
- setIfEmpty(logo, "caption", node.name);
787
- }
788
- });
789
- return node;
790
- }
791
- });
792
-
793
- const ratingResolver = defineSchemaOrgResolver({
794
- cast(node) {
795
- if (node === "number") {
796
- return {
797
- ratingValue: node
798
- };
799
- }
800
- return node;
801
- },
802
- defaults: {
803
- "@type": "Rating",
804
- "bestRating": 5,
805
- "worstRating": 1
836
+ resolveRootNode(jobPosting, { find }) {
837
+ const webPage = find(PrimaryWebPageId);
838
+ const identity = find(IdentityId);
839
+ if (identity)
840
+ setIfEmpty(jobPosting, "hiringOrganization", idReference(identity));
841
+ if (webPage)
842
+ setIfEmpty(jobPosting, "mainEntityOfPage", idReference(webPage));
843
+ return jobPosting;
806
844
  }
807
845
  });
808
846
 
@@ -1610,6 +1648,8 @@ function loadResolver(resolver) {
1610
1648
  return commentResolver;
1611
1649
  case "event":
1612
1650
  return eventResolver;
1651
+ case "foodEstablishment":
1652
+ return foodEstablishmentResolver;
1613
1653
  case "virtualLocation":
1614
1654
  return virtualLocationResolver;
1615
1655
  case "place":
@@ -1744,7 +1784,7 @@ function resolveNodeId(node, ctx, resolver, resolveAsRoot = false) {
1744
1784
  node["@id"] = prefixId(ctx.meta[prefix], node["@id"]);
1745
1785
  return node;
1746
1786
  }
1747
- const rootId = Array.isArray(resolver.idPrefix) ? resolver.idPrefix?.[1] : void 0;
1787
+ const rootId = node["@id"] || (Array.isArray(resolver.idPrefix) ? resolver.idPrefix?.[1] : void 0);
1748
1788
  if (resolveAsRoot && rootId) {
1749
1789
  node["@id"] = prefixId(ctx.meta[prefix], rootId);
1750
1790
  }
@@ -1801,11 +1841,8 @@ function resolveRelation(input, ctx, fallbackResolver, options = {}) {
1801
1841
  return ids;
1802
1842
  }
1803
1843
 
1804
- function isObject(value) {
1805
- return value !== null && typeof value === "object";
1806
- }
1807
1844
  function _defu(baseObject, defaults, namespace = ".", merger) {
1808
- if (!isObject(defaults)) {
1845
+ if (!_isPlainObject(defaults)) {
1809
1846
  return _defu(baseObject, {}, namespace, merger);
1810
1847
  }
1811
1848
  const object = Object.assign({}, defaults);
@@ -1822,7 +1859,7 @@ function _defu(baseObject, defaults, namespace = ".", merger) {
1822
1859
  }
1823
1860
  if (Array.isArray(value) && Array.isArray(object[key])) {
1824
1861
  object[key] = [...value, ...object[key]];
1825
- } else if (isObject(value) && isObject(object[key])) {
1862
+ } else if (_isPlainObject(value) && _isPlainObject(object[key])) {
1826
1863
  object[key] = _defu(
1827
1864
  value,
1828
1865
  object[key],
@@ -1835,6 +1872,13 @@ function _defu(baseObject, defaults, namespace = ".", merger) {
1835
1872
  }
1836
1873
  return object;
1837
1874
  }
1875
+ function _isPlainObject(value) {
1876
+ if (value === null || typeof value !== "object") {
1877
+ return false;
1878
+ }
1879
+ const prototype = Object.getPrototypeOf(value);
1880
+ return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value);
1881
+ }
1838
1882
  function createDefu(merger) {
1839
1883
  return (...arguments_) => (
1840
1884
  // eslint-disable-next-line unicorn/no-array-reduce
@@ -1972,7 +2016,7 @@ function SchemaOrgUnheadPlugin(config, meta, options) {
1972
2016
  };
1973
2017
  graph.push(newNode);
1974
2018
  }
1975
- tag.tagPosition = config.tagPosition === "head" ? "head" : "bodyClose";
2019
+ tag.tagPosition = tag.tagPosition || config.tagPosition === "head" ? "head" : "bodyClose";
1976
2020
  }
1977
2021
  if (tag.tag === "htmlAttrs" && tag.props.lang) {
1978
2022
  resolvedMeta.inLanguage = tag.props.lang;
@@ -2003,14 +2047,14 @@ function SchemaOrgUnheadPlugin(config, meta, options) {
2003
2047
  for (const tag of ctx.tags) {
2004
2048
  if (tag.tag === "script" && tag.key === "schema-org-graph") {
2005
2049
  const minify = options?.minify || process.env.NODE_ENV === "production";
2006
- tag.innerHTML = shared.processTemplateParams(
2007
- JSON.stringify({
2008
- "@context": "https://schema.org",
2009
- "@graph": graph.resolveGraph({ ...await meta?.() || {}, ...config, ...resolvedMeta })
2010
- }, null, minify ? 0 : 2),
2011
- head._templateParams,
2012
- head._separator
2013
- );
2050
+ tag.innerHTML = JSON.stringify({
2051
+ "@context": "https://schema.org",
2052
+ "@graph": graph.resolveGraph({ ...await meta?.() || {}, ...config, ...resolvedMeta })
2053
+ }, (_, value) => {
2054
+ if (typeof value !== "object")
2055
+ return shared.processTemplateParams(value, head._templateParams, head._separator);
2056
+ return value;
2057
+ }, minify ? 0 : 2);
2014
2058
  delete tag.props.nodes;
2015
2059
  return;
2016
2060
  }
@@ -2045,6 +2089,7 @@ exports.createSchemaOrgGraph = createSchemaOrgGraph;
2045
2089
  exports.dedupeNodes = dedupeNodes;
2046
2090
  exports.defineSchemaOrgResolver = defineSchemaOrgResolver;
2047
2091
  exports.eventResolver = eventResolver;
2092
+ exports.foodEstablishmentResolver = foodEstablishmentResolver;
2048
2093
  exports.howToResolver = howToResolver;
2049
2094
  exports.howToStepDirectionResolver = howToStepDirectionResolver;
2050
2095
  exports.howToStepResolver = howToStepResolver;
package/dist/vue.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const plugin = require('./shared/schema-org.e1b939f4.cjs');
3
+ const plugin = require('./shared/schema-org.f81cbd4d.cjs');
4
4
  const vue = require('@unhead/vue');
5
5
  const vue$1 = require('vue');
6
6
  require('@unhead/shared');
@@ -17,6 +17,7 @@ const schemaAutoImports = [
17
17
  "defineComment",
18
18
  "defineCourse",
19
19
  "defineEvent",
20
+ "defineFoodEstablishment",
20
21
  "defineHowTo",
21
22
  "defineHowToStep",
22
23
  "defineImage",
@@ -55,6 +56,7 @@ const schemaOrgComponents = [
55
56
  "SchemaOrgBreadcrumb",
56
57
  "SchemaOrgComment",
57
58
  "SchemaOrgEvent",
59
+ "SchemaOrgFoodEstablishment",
58
60
  "SchemaOrgHowTo",
59
61
  "SchemaOrgImage",
60
62
  "SchemaOrgJobPosting",
@@ -119,6 +121,9 @@ function defineComment(input) {
119
121
  function defineEvent(input) {
120
122
  return provideResolver(input, "event");
121
123
  }
124
+ function defineFoodEstablishment(input) {
125
+ return provideResolver(input, "foodEstablishment");
126
+ }
122
127
  function defineVirtualLocation(input) {
123
128
  return provideResolver(input, "virtualLocation");
124
129
  }
@@ -277,6 +282,7 @@ const SchemaOrgArticle = /* @__PURE__ */ defineSchemaOrgComponent("SchemaOrgArti
277
282
  const SchemaOrgBreadcrumb = /* @__PURE__ */ defineSchemaOrgComponent("SchemaOrgBreadcrumb", defineBreadcrumb);
278
283
  const SchemaOrgComment = /* @__PURE__ */ defineSchemaOrgComponent("SchemaOrgComment", defineComment);
279
284
  const SchemaOrgEvent = /* @__PURE__ */ defineSchemaOrgComponent("SchemaOrgEvent", defineEvent);
285
+ const SchemaOrgFoodEstablishment = /* @__PURE__ */ defineSchemaOrgComponent("SchemaOrgFoodEstablishment", defineFoodEstablishment);
280
286
  const SchemaOrgHowTo = /* @__PURE__ */ defineSchemaOrgComponent("SchemaOrgHowTo", defineHowTo);
281
287
  const SchemaOrgImage = /* @__PURE__ */ defineSchemaOrgComponent("SchemaOrgImage", defineImage);
282
288
  const SchemaOrgJobPosting = /* @__PURE__ */ defineSchemaOrgComponent("SchemaOrgJobPosting", defineJobPosting);
@@ -304,6 +310,7 @@ exports.SchemaOrgBreadcrumb = SchemaOrgBreadcrumb;
304
310
  exports.SchemaOrgComment = SchemaOrgComment;
305
311
  exports.SchemaOrgCourse = SchemaOrgCourse;
306
312
  exports.SchemaOrgEvent = SchemaOrgEvent;
313
+ exports.SchemaOrgFoodEstablishment = SchemaOrgFoodEstablishment;
307
314
  exports.SchemaOrgHowTo = SchemaOrgHowTo;
308
315
  exports.SchemaOrgImage = SchemaOrgImage;
309
316
  exports.SchemaOrgItemList = SchemaOrgItemList;
@@ -331,6 +338,7 @@ exports.defineBreadcrumb = defineBreadcrumb;
331
338
  exports.defineComment = defineComment;
332
339
  exports.defineCourse = defineCourse;
333
340
  exports.defineEvent = defineEvent;
341
+ exports.defineFoodEstablishment = defineFoodEstablishment;
334
342
  exports.defineHowTo = defineHowTo;
335
343
  exports.defineHowToStep = defineHowToStep;
336
344
  exports.defineImage = defineImage;
package/dist/vue.d.cts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { ComponentResolver } from 'unplugin-vue-components';
2
2
  import * as _unhead_vue from '@unhead/vue';
3
3
  import { MaybeComputedRefOrPromise } from '@unhead/vue';
4
- import { P as PostalAddress, c as AggregateOffer, d as AggregateRating, e as Article, B as BreadcrumbList, C as Comment, E as Event, V as VirtualLocation, f as Place, H as HowTo, g as HowToStep, I as ImageObject, J as JobPosting, L as LocalBusiness, O as Offer, h as OpeningHoursSpecification, i as Organization, j as Person, k as Product, Q as Question, l as Recipe, m as Review, n as VideoObject, W as WebPage, o as WebSite, p as Book, q as Course, r as ItemList, s as ListItem, t as Movie, u as SearchAction, v as ReadAction, w as SoftwareApp, x as BookEdition, A as Arrayable, T as Thing } from './shared/schema-org.248e802f.cjs';
5
- export { M as MetaInput, b9 as PluginSchemaOrg, ba as SchemaOrgUnheadPlugin, bg as UserConfig } from './shared/schema-org.248e802f.cjs';
4
+ import { P as PostalAddress, c as AggregateOffer, d as AggregateRating, e as Article, B as BreadcrumbList, C as Comment, E as Event, F as FoodEstablishment, V as VirtualLocation, f as Place, H as HowTo, g as HowToStep, I as ImageObject, J as JobPosting, L as LocalBusiness, O as Offer, h as OpeningHoursSpecification, i as Organization, j as Person, k as Product, Q as Question, l as Recipe, m as Review, n as VideoObject, W as WebPage, o as WebSite, p as Book, q as Course, r as ItemList, s as ListItem, t as Movie, u as SearchAction, v as ReadAction, w as SoftwareApp, x as BookEdition, A as Arrayable, T as Thing } from './shared/schema-org.320d2e5d.cjs';
5
+ export { M as MetaInput, bc as PluginSchemaOrg, bd as SchemaOrgUnheadPlugin, bj as UserConfig } from './shared/schema-org.320d2e5d.cjs';
6
6
  import { defineComponent } from 'vue';
7
7
  import '@unhead/schema';
8
8
 
@@ -32,6 +32,7 @@ declare function defineArticle<T extends Record<string, any>>(input?: DeepMaybeR
32
32
  declare function defineBreadcrumb<T extends Record<string, any>>(input?: DeepMaybeRef<BreadcrumbList & T>): DeepMaybeRef<BreadcrumbList & T>;
33
33
  declare function defineComment<T extends Record<string, any>>(input?: DeepMaybeRef<Comment & T>): DeepMaybeRef<Comment & T>;
34
34
  declare function defineEvent<T extends Record<string, any>>(input?: DeepMaybeRef<Event & T>): DeepMaybeRef<Event & T>;
35
+ declare function defineFoodEstablishment<T extends Record<string, any>>(input?: DeepMaybeRef<FoodEstablishment & T>): DeepMaybeRef<FoodEstablishment & T>;
35
36
  declare function defineVirtualLocation<T extends Record<string, any>>(input?: DeepMaybeRef<VirtualLocation & T>): DeepMaybeRef<VirtualLocation & T>;
36
37
  declare function definePlace<T extends Record<string, any>>(input?: DeepMaybeRef<Place & T>): DeepMaybeRef<Place & T>;
37
38
  declare function defineHowTo<T extends Record<string, any>>(input?: DeepMaybeRef<HowTo & T>): DeepMaybeRef<HowTo & T>;
@@ -71,6 +72,7 @@ declare const SchemaOrgArticle: any;
71
72
  declare const SchemaOrgBreadcrumb: any;
72
73
  declare const SchemaOrgComment: any;
73
74
  declare const SchemaOrgEvent: any;
75
+ declare const SchemaOrgFoodEstablishment: any;
74
76
  declare const SchemaOrgHowTo: any;
75
77
  declare const SchemaOrgImage: any;
76
78
  declare const SchemaOrgJobPosting: any;
@@ -90,4 +92,4 @@ declare const SchemaOrgItemList: any;
90
92
  declare const SchemaOrgBook: any;
91
93
  declare const SchemaOrgSoftwareApp: any;
92
94
 
93
- export { type DeepMaybeRef, SchemaOrgArticle, SchemaOrgBook, SchemaOrgBreadcrumb, SchemaOrgComment, SchemaOrgCourse, SchemaOrgEvent, SchemaOrgHowTo, SchemaOrgImage, SchemaOrgItemList, SchemaOrgJobPosting, SchemaOrgLocalBusiness, SchemaOrgMovie, SchemaOrgOrganization, SchemaOrgPerson, SchemaOrgProduct, SchemaOrgQuestion, SchemaOrgRecipe, SchemaOrgResolver, type SchemaOrgResolverOptions, SchemaOrgReview, SchemaOrgSoftwareApp, SchemaOrgVideo, SchemaOrgWebPage, SchemaOrgWebSite, type UseSchemaOrgInput, defineAddress, defineAggregateOffer, defineAggregateRating, defineArticle, defineBook, defineBookEdition, defineBreadcrumb, defineComment, defineCourse, defineEvent, defineHowTo, defineHowToStep, defineImage, defineItemList, defineJobPosting, defineListItem, defineLocalBusiness, defineMovie, defineOffer, defineOpeningHours, defineOrganization, definePerson, definePlace, defineProduct, defineQuestion, defineReadAction, defineRecipe, defineReview, defineSchemaOrgComponent, defineSearchAction, defineSoftwareApp, defineVideo, defineVirtualLocation, defineWebPage, defineWebSite, schemaAutoImports, schemaOrgAutoImports, schemaOrgComponents, useSchemaOrg };
95
+ export { type DeepMaybeRef, SchemaOrgArticle, SchemaOrgBook, SchemaOrgBreadcrumb, SchemaOrgComment, SchemaOrgCourse, SchemaOrgEvent, SchemaOrgFoodEstablishment, SchemaOrgHowTo, SchemaOrgImage, SchemaOrgItemList, SchemaOrgJobPosting, SchemaOrgLocalBusiness, SchemaOrgMovie, SchemaOrgOrganization, SchemaOrgPerson, SchemaOrgProduct, SchemaOrgQuestion, SchemaOrgRecipe, SchemaOrgResolver, type SchemaOrgResolverOptions, SchemaOrgReview, SchemaOrgSoftwareApp, SchemaOrgVideo, SchemaOrgWebPage, SchemaOrgWebSite, type UseSchemaOrgInput, defineAddress, defineAggregateOffer, defineAggregateRating, defineArticle, defineBook, defineBookEdition, defineBreadcrumb, defineComment, defineCourse, defineEvent, defineFoodEstablishment, defineHowTo, defineHowToStep, defineImage, defineItemList, defineJobPosting, defineListItem, defineLocalBusiness, defineMovie, defineOffer, defineOpeningHours, defineOrganization, definePerson, definePlace, defineProduct, defineQuestion, defineReadAction, defineRecipe, defineReview, defineSchemaOrgComponent, defineSearchAction, defineSoftwareApp, defineVideo, defineVirtualLocation, defineWebPage, defineWebSite, schemaAutoImports, schemaOrgAutoImports, schemaOrgComponents, useSchemaOrg };