unhead 1.1.26 → 1.1.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -5,29 +5,33 @@ const dom = require('@unhead/dom');
5
5
  const shared = require('@unhead/shared');
6
6
 
7
7
  const TAG_WEIGHTS = {
8
- // aliases
9
- critical: 2,
10
- high: 9,
11
- low: 12,
12
8
  // tags
13
9
  base: -1,
14
- title: 1,
15
- meta: 10
10
+ title: 1
11
+ };
12
+ const TAG_ALIASES = {
13
+ // relative scores to their default values
14
+ critical: -8,
15
+ high: -1,
16
+ low: 2
16
17
  };
17
18
  function tagWeight(tag) {
18
- if (typeof tag.tagPriority === "number")
19
- return tag.tagPriority;
19
+ let weight = 10;
20
+ const priority = tag.tagPriority;
21
+ if (typeof priority === "number")
22
+ return priority;
20
23
  if (tag.tag === "meta") {
21
24
  if (tag.props.charset)
22
- return -2;
25
+ weight = -2;
23
26
  if (tag.props["http-equiv"] === "content-security-policy")
24
- return 0;
27
+ weight = 0;
28
+ } else if (tag.tag in TAG_WEIGHTS) {
29
+ weight = TAG_WEIGHTS[tag.tag];
25
30
  }
26
- const key = tag.tagPriority || tag.tag;
27
- if (key in TAG_WEIGHTS) {
28
- return TAG_WEIGHTS[key];
31
+ if (typeof priority === "string" && priority in TAG_ALIASES) {
32
+ return weight + TAG_ALIASES[priority];
29
33
  }
30
- return 10;
34
+ return weight;
31
35
  }
32
36
  const SortModifiers = [{ prefix: "before:", offset: -1 }, { prefix: "after:", offset: 1 }];
33
37
  function SortTagsPlugin() {
@@ -233,6 +237,8 @@ function DedupesTagsPlugin() {
233
237
  tag._d = `${dupedTag._d}:${dupedTag._duped.length + 1}`;
234
238
  dupedTag._duped.push(tag);
235
239
  return;
240
+ } else if (tagWeight(tag) > tagWeight(dupedTag)) {
241
+ return;
236
242
  }
237
243
  }
238
244
  const propCount = Object.keys(tag.props).length + (tag.innerHTML ? 1 : 0) + (tag.textContent ? 1 : 0);
@@ -277,7 +283,7 @@ function processTemplateParams(s, config) {
277
283
  tokens.forEach((token) => {
278
284
  const re = sub(token.slice(1));
279
285
  if (typeof re === "string") {
280
- s = s.replaceAll(new RegExp(`\\${token}(\\W|$)`, "g"), `${re}$1`).trim();
286
+ s = s.replace(new RegExp(`\\${token}(\\W|$)`, "g"), `${re}$1`).trim();
281
287
  }
282
288
  });
283
289
  if (config.separator) {
@@ -603,7 +609,8 @@ function packMeta(inputs) {
603
609
  });
604
610
  }
605
611
 
606
- const ArrayableInputs = ["Image", "Video", "Audio"];
612
+ const OpenGraphInputs = ["Image", "Video", "Audio"];
613
+ const SimpleArrayUnpackMetas = ["themeColor"];
607
614
  const ColonPrefixKeys = /^(og|twitter|fb)/;
608
615
  const PropertyPrefixKeys = /^(og|fb)/;
609
616
  function resolveMetaKeyType(key) {
@@ -632,7 +639,7 @@ function changeKeyCasingDeep(input) {
632
639
  }
633
640
  function unpackMeta(input) {
634
641
  const extras = [];
635
- ArrayableInputs.forEach((key) => {
642
+ OpenGraphInputs.forEach((key) => {
636
643
  const ogKey = `og:${key.toLowerCase()}`;
637
644
  const inputKey = `og${key}`;
638
645
  const val = input[inputKey];
@@ -657,6 +664,18 @@ function unpackMeta(input) {
657
664
  delete input[inputKey];
658
665
  }
659
666
  });
667
+ SimpleArrayUnpackMetas.forEach((meta2) => {
668
+ if (input[meta2]) {
669
+ const val = Array.isArray(input[meta2]) ? input[meta2] : [input[meta2]];
670
+ delete input[meta2];
671
+ val.forEach((entry) => {
672
+ extras.push({
673
+ name: fixKeyCase(meta2),
674
+ ...entry
675
+ });
676
+ });
677
+ }
678
+ });
660
679
  const meta = unpackToArray(input, {
661
680
  key({ key }) {
662
681
  return resolveMetaKeyType(key);
@@ -699,12 +718,20 @@ function resolvePackedMetaObjectValue(value, key) {
699
718
 
700
719
  async function normaliseTag(tagName, input) {
701
720
  const tag = { tag: tagName, props: {} };
721
+ if (input instanceof Promise)
722
+ input = await input;
702
723
  if (tagName === "templateParams") {
703
724
  tag.props = input;
704
725
  return tag;
705
726
  }
706
727
  if (["title", "titleTemplate"].includes(tagName)) {
707
- tag.textContent = input instanceof Promise ? await input : input;
728
+ if (input && typeof input === "object") {
729
+ tag.textContent = input.textContent;
730
+ if (input.tagPriority)
731
+ tag.tagPriority = input.tagPriority;
732
+ } else {
733
+ tag.textContent = input;
734
+ }
708
735
  return tag;
709
736
  }
710
737
  if (typeof input === "string") {
@@ -830,18 +857,15 @@ function whitelistSafeInput(input) {
830
857
  filtered[key] = tagValue.map((meta) => {
831
858
  const link = {};
832
859
  WhitelistAttributes.link.forEach((key2) => {
833
- if (key2 === "rel" && ["stylesheet", "canonical", "modulepreload", "prerender", "preload", "prefetch"].includes(meta[key2]))
860
+ const val = meta[key2];
861
+ if (key2 === "rel" && ["stylesheet", "canonical", "modulepreload", "prerender", "preload", "prefetch"].includes(val))
834
862
  return;
835
863
  if (key2 === "href") {
836
- try {
837
- const url = new URL(meta[key2]);
838
- if (["javascript:", "data:"].includes(url.protocol))
839
- return;
840
- link[key2] = meta[key2];
841
- } catch (e) {
842
- }
843
- } else if (meta[key2] || key2.startsWith("data-")) {
844
- link[key2] = meta[key2];
864
+ if (val.includes("javascript:") || val.includes("data:"))
865
+ return;
866
+ link[key2] = val;
867
+ } else if (val || key2.startsWith("data-")) {
868
+ link[key2] = val;
845
869
  }
846
870
  });
847
871
  return link;
@@ -1057,6 +1081,7 @@ exports.EventHandlersPlugin = EventHandlersPlugin;
1057
1081
  exports.ProvideTagHashPlugin = ProvideTagHashPlugin;
1058
1082
  exports.SortModifiers = SortModifiers;
1059
1083
  exports.SortTagsPlugin = SortTagsPlugin;
1084
+ exports.TAG_ALIASES = TAG_ALIASES;
1060
1085
  exports.TAG_WEIGHTS = TAG_WEIGHTS;
1061
1086
  exports.TagEntityBits = TagEntityBits;
1062
1087
  exports.TemplateParamsPlugin = TemplateParamsPlugin;
package/dist/index.d.ts CHANGED
@@ -3,12 +3,13 @@ import { HeadTag, TemplateParams, Head, HeadEntryOptions, ActiveHeadEntry, HeadS
3
3
  import { Arrayable } from '@unhead/shared';
4
4
 
5
5
  declare const TAG_WEIGHTS: {
6
- readonly critical: 2;
7
- readonly high: 9;
8
- readonly low: 12;
9
6
  readonly base: -1;
10
7
  readonly title: 1;
11
- readonly meta: 10;
8
+ };
9
+ declare const TAG_ALIASES: {
10
+ readonly critical: -8;
11
+ readonly high: -1;
12
+ readonly low: 2;
12
13
  };
13
14
  declare function tagWeight<T extends HeadTag>(tag: T): any;
14
15
  declare const SortModifiers: {
@@ -185,4 +186,4 @@ declare function normaliseEntryTags<T extends {} = Head>(e: HeadEntry<T>): Promi
185
186
 
186
187
  declare function whitelistSafeInput(input: Record<string, MaybeArray<Record<string, string>>>): HeadSafe;
187
188
 
188
- export { CorePlugins, DOMPlugins, DedupesTagsPlugin, DeprecatedTagAttrPlugin, EventHandlersPlugin, ProvideTagHashPlugin, SortModifiers, SortTagsPlugin, TAG_WEIGHTS, TagEntityBits, TemplateParamsPlugin, TitleTemplatePlugin, UseSeoMetaInput, activeHead, composableNames, createHead, createHeadCore, createServerHead, getActiveHead, normaliseClassProp, normaliseEntryTags, normaliseProps, normaliseTag, packMeta, processTemplateParams, resolveMetaKeyType, resolveMetaKeyValue, resolvePackedMetaObjectValue, setActiveHead, tagWeight, unheadComposablesImports, unpackMeta, useBodyAttrs, useHead, useHeadSafe, useHtmlAttrs, useSeoMeta, useServerBodyAttrs, useServerHead, useServerHeadSafe, useServerHtmlAttrs, useServerSeoMeta, useServerTagBase, useServerTagLink, useServerTagMeta, useServerTagMetaFlat, useServerTagNoscript, useServerTagScript, useServerTagStyle, useServerTagTitle, useServerTitleTemplate, useTagBase, useTagLink, useTagMeta, useTagMetaFlat, useTagNoscript, useTagScript, useTagStyle, useTagTitle, useTitleTemplate, whitelistSafeInput };
189
+ export { CorePlugins, DOMPlugins, DedupesTagsPlugin, DeprecatedTagAttrPlugin, EventHandlersPlugin, ProvideTagHashPlugin, SortModifiers, SortTagsPlugin, TAG_ALIASES, TAG_WEIGHTS, TagEntityBits, TemplateParamsPlugin, TitleTemplatePlugin, UseSeoMetaInput, activeHead, composableNames, createHead, createHeadCore, createServerHead, getActiveHead, normaliseClassProp, normaliseEntryTags, normaliseProps, normaliseTag, packMeta, processTemplateParams, resolveMetaKeyType, resolveMetaKeyValue, resolvePackedMetaObjectValue, setActiveHead, tagWeight, unheadComposablesImports, unpackMeta, useBodyAttrs, useHead, useHeadSafe, useHtmlAttrs, useSeoMeta, useServerBodyAttrs, useServerHead, useServerHeadSafe, useServerHtmlAttrs, useServerSeoMeta, useServerTagBase, useServerTagLink, useServerTagMeta, useServerTagMetaFlat, useServerTagNoscript, useServerTagScript, useServerTagStyle, useServerTagTitle, useServerTitleTemplate, useTagBase, useTagLink, useTagMeta, useTagMetaFlat, useTagNoscript, useTagScript, useTagStyle, useTagTitle, useTitleTemplate, whitelistSafeInput };
package/dist/index.mjs CHANGED
@@ -3,29 +3,33 @@ import { PatchDomOnEntryUpdatesPlugin, maybeGetSSRHash } from '@unhead/dom';
3
3
  import { defineHeadPlugin, resolveTitleTemplate, hashTag, hashCode, tagDedupeKey, HasElementTags, asArray as asArray$1, TagConfigKeys, TagsWithInnerContent, ValidHeadTags } from '@unhead/shared';
4
4
 
5
5
  const TAG_WEIGHTS = {
6
- // aliases
7
- critical: 2,
8
- high: 9,
9
- low: 12,
10
6
  // tags
11
7
  base: -1,
12
- title: 1,
13
- meta: 10
8
+ title: 1
9
+ };
10
+ const TAG_ALIASES = {
11
+ // relative scores to their default values
12
+ critical: -8,
13
+ high: -1,
14
+ low: 2
14
15
  };
15
16
  function tagWeight(tag) {
16
- if (typeof tag.tagPriority === "number")
17
- return tag.tagPriority;
17
+ let weight = 10;
18
+ const priority = tag.tagPriority;
19
+ if (typeof priority === "number")
20
+ return priority;
18
21
  if (tag.tag === "meta") {
19
22
  if (tag.props.charset)
20
- return -2;
23
+ weight = -2;
21
24
  if (tag.props["http-equiv"] === "content-security-policy")
22
- return 0;
25
+ weight = 0;
26
+ } else if (tag.tag in TAG_WEIGHTS) {
27
+ weight = TAG_WEIGHTS[tag.tag];
23
28
  }
24
- const key = tag.tagPriority || tag.tag;
25
- if (key in TAG_WEIGHTS) {
26
- return TAG_WEIGHTS[key];
29
+ if (typeof priority === "string" && priority in TAG_ALIASES) {
30
+ return weight + TAG_ALIASES[priority];
27
31
  }
28
- return 10;
32
+ return weight;
29
33
  }
30
34
  const SortModifiers = [{ prefix: "before:", offset: -1 }, { prefix: "after:", offset: 1 }];
31
35
  function SortTagsPlugin() {
@@ -231,6 +235,8 @@ function DedupesTagsPlugin() {
231
235
  tag._d = `${dupedTag._d}:${dupedTag._duped.length + 1}`;
232
236
  dupedTag._duped.push(tag);
233
237
  return;
238
+ } else if (tagWeight(tag) > tagWeight(dupedTag)) {
239
+ return;
234
240
  }
235
241
  }
236
242
  const propCount = Object.keys(tag.props).length + (tag.innerHTML ? 1 : 0) + (tag.textContent ? 1 : 0);
@@ -275,7 +281,7 @@ function processTemplateParams(s, config) {
275
281
  tokens.forEach((token) => {
276
282
  const re = sub(token.slice(1));
277
283
  if (typeof re === "string") {
278
- s = s.replaceAll(new RegExp(`\\${token}(\\W|$)`, "g"), `${re}$1`).trim();
284
+ s = s.replace(new RegExp(`\\${token}(\\W|$)`, "g"), `${re}$1`).trim();
279
285
  }
280
286
  });
281
287
  if (config.separator) {
@@ -601,7 +607,8 @@ function packMeta(inputs) {
601
607
  });
602
608
  }
603
609
 
604
- const ArrayableInputs = ["Image", "Video", "Audio"];
610
+ const OpenGraphInputs = ["Image", "Video", "Audio"];
611
+ const SimpleArrayUnpackMetas = ["themeColor"];
605
612
  const ColonPrefixKeys = /^(og|twitter|fb)/;
606
613
  const PropertyPrefixKeys = /^(og|fb)/;
607
614
  function resolveMetaKeyType(key) {
@@ -630,7 +637,7 @@ function changeKeyCasingDeep(input) {
630
637
  }
631
638
  function unpackMeta(input) {
632
639
  const extras = [];
633
- ArrayableInputs.forEach((key) => {
640
+ OpenGraphInputs.forEach((key) => {
634
641
  const ogKey = `og:${key.toLowerCase()}`;
635
642
  const inputKey = `og${key}`;
636
643
  const val = input[inputKey];
@@ -655,6 +662,18 @@ function unpackMeta(input) {
655
662
  delete input[inputKey];
656
663
  }
657
664
  });
665
+ SimpleArrayUnpackMetas.forEach((meta2) => {
666
+ if (input[meta2]) {
667
+ const val = Array.isArray(input[meta2]) ? input[meta2] : [input[meta2]];
668
+ delete input[meta2];
669
+ val.forEach((entry) => {
670
+ extras.push({
671
+ name: fixKeyCase(meta2),
672
+ ...entry
673
+ });
674
+ });
675
+ }
676
+ });
658
677
  const meta = unpackToArray(input, {
659
678
  key({ key }) {
660
679
  return resolveMetaKeyType(key);
@@ -697,12 +716,20 @@ function resolvePackedMetaObjectValue(value, key) {
697
716
 
698
717
  async function normaliseTag(tagName, input) {
699
718
  const tag = { tag: tagName, props: {} };
719
+ if (input instanceof Promise)
720
+ input = await input;
700
721
  if (tagName === "templateParams") {
701
722
  tag.props = input;
702
723
  return tag;
703
724
  }
704
725
  if (["title", "titleTemplate"].includes(tagName)) {
705
- tag.textContent = input instanceof Promise ? await input : input;
726
+ if (input && typeof input === "object") {
727
+ tag.textContent = input.textContent;
728
+ if (input.tagPriority)
729
+ tag.tagPriority = input.tagPriority;
730
+ } else {
731
+ tag.textContent = input;
732
+ }
706
733
  return tag;
707
734
  }
708
735
  if (typeof input === "string") {
@@ -828,18 +855,15 @@ function whitelistSafeInput(input) {
828
855
  filtered[key] = tagValue.map((meta) => {
829
856
  const link = {};
830
857
  WhitelistAttributes.link.forEach((key2) => {
831
- if (key2 === "rel" && ["stylesheet", "canonical", "modulepreload", "prerender", "preload", "prefetch"].includes(meta[key2]))
858
+ const val = meta[key2];
859
+ if (key2 === "rel" && ["stylesheet", "canonical", "modulepreload", "prerender", "preload", "prefetch"].includes(val))
832
860
  return;
833
861
  if (key2 === "href") {
834
- try {
835
- const url = new URL(meta[key2]);
836
- if (["javascript:", "data:"].includes(url.protocol))
837
- return;
838
- link[key2] = meta[key2];
839
- } catch (e) {
840
- }
841
- } else if (meta[key2] || key2.startsWith("data-")) {
842
- link[key2] = meta[key2];
862
+ if (val.includes("javascript:") || val.includes("data:"))
863
+ return;
864
+ link[key2] = val;
865
+ } else if (val || key2.startsWith("data-")) {
866
+ link[key2] = val;
843
867
  }
844
868
  });
845
869
  return link;
@@ -1047,4 +1071,4 @@ const unheadComposablesImports = [
1047
1071
  }
1048
1072
  ];
1049
1073
 
1050
- export { CorePlugins, DOMPlugins, DedupesTagsPlugin, DeprecatedTagAttrPlugin, EventHandlersPlugin, ProvideTagHashPlugin, SortModifiers, SortTagsPlugin, TAG_WEIGHTS, TagEntityBits, TemplateParamsPlugin, TitleTemplatePlugin, activeHead, composableNames, createHead, createHeadCore, createServerHead, getActiveHead, normaliseClassProp, normaliseEntryTags, normaliseProps, normaliseTag, packMeta, processTemplateParams, resolveMetaKeyType, resolveMetaKeyValue, resolvePackedMetaObjectValue, setActiveHead, tagWeight, unheadComposablesImports, unpackMeta, useBodyAttrs, useHead, useHeadSafe, useHtmlAttrs, useSeoMeta, useServerBodyAttrs, useServerHead, useServerHeadSafe, useServerHtmlAttrs, useServerSeoMeta, useServerTagBase, useServerTagLink, useServerTagMeta, useServerTagMetaFlat, useServerTagNoscript, useServerTagScript, useServerTagStyle, useServerTagTitle, useServerTitleTemplate, useTagBase, useTagLink, useTagMeta, useTagMetaFlat, useTagNoscript, useTagScript, useTagStyle, useTagTitle, useTitleTemplate, whitelistSafeInput };
1074
+ export { CorePlugins, DOMPlugins, DedupesTagsPlugin, DeprecatedTagAttrPlugin, EventHandlersPlugin, ProvideTagHashPlugin, SortModifiers, SortTagsPlugin, TAG_ALIASES, TAG_WEIGHTS, TagEntityBits, TemplateParamsPlugin, TitleTemplatePlugin, activeHead, composableNames, createHead, createHeadCore, createServerHead, getActiveHead, normaliseClassProp, normaliseEntryTags, normaliseProps, normaliseTag, packMeta, processTemplateParams, resolveMetaKeyType, resolveMetaKeyValue, resolvePackedMetaObjectValue, setActiveHead, tagWeight, unheadComposablesImports, unpackMeta, useBodyAttrs, useHead, useHeadSafe, useHtmlAttrs, useSeoMeta, useServerBodyAttrs, useServerHead, useServerHeadSafe, useServerHtmlAttrs, useServerSeoMeta, useServerTagBase, useServerTagLink, useServerTagMeta, useServerTagMetaFlat, useServerTagNoscript, useServerTagScript, useServerTagStyle, useServerTagTitle, useServerTitleTemplate, useTagBase, useTagLink, useTagMeta, useTagMetaFlat, useTagNoscript, useTagScript, useTagStyle, useTagTitle, useTitleTemplate, whitelistSafeInput };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "unhead",
3
3
  "type": "module",
4
- "version": "1.1.26",
5
- "packageManager": "pnpm@7.32.0",
4
+ "version": "1.1.28",
5
+ "packageManager": "pnpm@8.6.2",
6
6
  "author": "Harlan Wilton <harlan@harlanzw.com>",
7
7
  "license": "MIT",
8
8
  "funding": "https://github.com/sponsors/harlan-zw",
@@ -31,9 +31,9 @@
31
31
  ],
32
32
  "dependencies": {
33
33
  "hookable": "^5.5.3",
34
- "@unhead/dom": "1.1.26",
35
- "@unhead/schema": "1.1.26",
36
- "@unhead/shared": "1.1.26"
34
+ "@unhead/dom": "1.1.28",
35
+ "@unhead/schema": "1.1.28",
36
+ "@unhead/shared": "1.1.28"
37
37
  },
38
38
  "devDependencies": {
39
39
  "packrup": "^0.1.0"