unhead 1.1.9 → 1.1.11

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
@@ -3,7 +3,6 @@
3
3
  const hookable = require('hookable');
4
4
  const dom = require('@unhead/dom');
5
5
  const shared = require('@unhead/shared');
6
- const packrup = require('packrup');
7
6
 
8
7
  const TAG_WEIGHTS = {
9
8
  // aliases
@@ -391,6 +390,102 @@ const useServerHtmlAttrs = (attrs) => useServerHead({ htmlAttrs: attrs });
391
390
  const useServerBodyAttrs = (attrs) => useServerHead({ bodyAttrs: attrs });
392
391
  const useServerTitleTemplate = (titleTemplate) => useServerHead({ titleTemplate });
393
392
 
393
+ function asArray(input) {
394
+ return Array.isArray(input) ? input : [input];
395
+ }
396
+ const InternalKeySymbol = "_$key";
397
+ function packObject(input, options) {
398
+ const keys = Object.keys(input);
399
+ let [k, v] = keys;
400
+ options = options || {};
401
+ options.key = options.key || k;
402
+ options.value = options.value || v;
403
+ options.resolveKey = options.resolveKey || ((k2) => k2);
404
+ const resolveKey = (index) => {
405
+ const arr = asArray(options?.[index]);
406
+ return arr.find((k2) => {
407
+ if (typeof k2 === "string" && k2.includes(".")) {
408
+ return k2;
409
+ }
410
+ return k2 && keys.includes(k2);
411
+ });
412
+ };
413
+ const resolveValue = (k2, input2) => {
414
+ if (k2.includes(".")) {
415
+ const paths = k2.split(".");
416
+ let val = input2;
417
+ for (const path of paths)
418
+ val = val[path];
419
+ return val;
420
+ }
421
+ return input2[k2];
422
+ };
423
+ k = resolveKey("key") || k;
424
+ v = resolveKey("value") || v;
425
+ const dedupeKeyPrefix = input.key ? `${InternalKeySymbol}${input.key}-` : "";
426
+ let keyValue = resolveValue(k, input);
427
+ keyValue = options.resolveKey(keyValue);
428
+ return {
429
+ [`${dedupeKeyPrefix}${keyValue}`]: resolveValue(v, input)
430
+ };
431
+ }
432
+
433
+ function packArray(input, options) {
434
+ const packed = {};
435
+ for (const i of input) {
436
+ const packedObj = packObject(i, options);
437
+ const pKey = Object.keys(packedObj)[0];
438
+ const isDedupeKey = pKey.startsWith(InternalKeySymbol);
439
+ if (!isDedupeKey && packed[pKey]) {
440
+ packed[pKey] = Array.isArray(packed[pKey]) ? packed[pKey] : [packed[pKey]];
441
+ packed[pKey].push(Object.values(packedObj)[0]);
442
+ } else {
443
+ packed[isDedupeKey ? pKey.split("-").slice(1).join("-") || pKey : pKey] = packedObj[pKey];
444
+ }
445
+ }
446
+ return packed;
447
+ }
448
+
449
+ function unpackToArray(input, options) {
450
+ const unpacked = [];
451
+ const kFn = options.resolveKeyData || ((ctx) => ctx.key);
452
+ const vFn = options.resolveValueData || ((ctx) => ctx.value);
453
+ for (const [k, v] of Object.entries(input)) {
454
+ unpacked.push(...(Array.isArray(v) ? v : [v]).map((i) => {
455
+ const ctx = { key: k, value: i };
456
+ const val = vFn(ctx);
457
+ if (typeof val === "object")
458
+ return unpackToArray(val, options);
459
+ if (Array.isArray(val))
460
+ return val;
461
+ return {
462
+ [typeof options.key === "function" ? options.key(ctx) : options.key]: kFn(ctx),
463
+ [typeof options.value === "function" ? options.value(ctx) : options.value]: val
464
+ };
465
+ }).flat());
466
+ }
467
+ return unpacked;
468
+ }
469
+
470
+ function unpackToString(value, options) {
471
+ return Object.entries(value).map(([key, value2]) => {
472
+ if (typeof value2 === "object")
473
+ value2 = unpackToString(value2, options);
474
+ if (options.resolve) {
475
+ const resolved = options.resolve({ key, value: value2 });
476
+ if (resolved)
477
+ return resolved;
478
+ }
479
+ if (typeof value2 === "number")
480
+ value2 = value2.toString();
481
+ if (typeof value2 === "string" && options.wrapValue) {
482
+ value2 = value2.replace(new RegExp(options.wrapValue, "g"), `\\${options.wrapValue}`);
483
+ value2 = `${options.wrapValue}${value2}${options.wrapValue}`;
484
+ }
485
+ return `${key}${options.keyValueSeparator || ""}${value2}`;
486
+ }).join(options.entrySeparator || "");
487
+ }
488
+
394
489
  const MetaPackingSchema = {
395
490
  robots: {
396
491
  unpack: {
@@ -440,13 +535,10 @@ const MetaPackingSchema = {
440
535
  metaKey: "http-equiv"
441
536
  }
442
537
  };
443
- function resolveMetaKeyType(key) {
444
- return PropertyPrefixKeys.test(key) ? "property" : MetaPackingSchema[key]?.metaKey || "name";
445
- }
446
538
 
447
539
  function packMeta(inputs) {
448
540
  const mappedPackingSchema = Object.entries(MetaPackingSchema).map(([key, value]) => [key, value.keyValue]);
449
- return packrup.packArray(inputs, {
541
+ return packArray(inputs, {
450
542
  key: ["name", "property", "httpEquiv", "http-equiv", "charset"],
451
543
  value: ["content", "charset"],
452
544
  resolveKey(k) {
@@ -459,6 +551,32 @@ function packMeta(inputs) {
459
551
  }
460
552
 
461
553
  const ArrayableInputs = ["Image", "Video", "Audio"];
554
+ const ColonPrefixKeys = /^(og|twitter|fb)/;
555
+ const PropertyPrefixKeys = /^(og|fb)/;
556
+ function resolveMetaKeyType(key) {
557
+ return PropertyPrefixKeys.test(key) ? "property" : MetaPackingSchema[key]?.metaKey || "name";
558
+ }
559
+ function resolveMetaKeyValue(key) {
560
+ return MetaPackingSchema[key]?.keyValue || fixKeyCase(key);
561
+ }
562
+ function fixKeyCase(key) {
563
+ key = key.replace(/([A-Z])/g, "-$1").toLowerCase();
564
+ if (ColonPrefixKeys.test(key)) {
565
+ key = key.replace("secure-url", "secure_url").replace(/-/g, ":");
566
+ }
567
+ return key;
568
+ }
569
+ function changeKeyCasingDeep(input) {
570
+ if (Array.isArray(input)) {
571
+ return input.map((entry) => changeKeyCasingDeep(entry));
572
+ }
573
+ if (typeof input !== "object" || Array.isArray(input))
574
+ return input;
575
+ const output = {};
576
+ for (const [key, value] of Object.entries(input))
577
+ output[fixKeyCase(key)] = changeKeyCasingDeep(value);
578
+ return output;
579
+ }
462
580
  function unpackMeta(input) {
463
581
  const extras = [];
464
582
  ArrayableInputs.forEach((key) => {
@@ -469,7 +587,7 @@ function unpackMeta(input) {
469
587
  (Array.isArray(val) ? val : [val]).forEach((entry) => {
470
588
  if (!entry)
471
589
  return;
472
- const unpackedEntry = packrup.unpackToArray(entry, {
590
+ const unpackedEntry = unpackToArray(entry, {
473
591
  key: "property",
474
592
  value: "content",
475
593
  resolveKeyData({ key: key2 }) {
@@ -486,7 +604,7 @@ function unpackMeta(input) {
486
604
  delete input[inputKey];
487
605
  }
488
606
  });
489
- const meta = packrup.unpackToArray(input, {
607
+ const meta = unpackToArray(input, {
490
608
  key({ key }) {
491
609
  return resolveMetaKeyType(key);
492
610
  },
@@ -494,7 +612,7 @@ function unpackMeta(input) {
494
612
  return key === "charset" ? "charset" : "content";
495
613
  },
496
614
  resolveKeyData({ key }) {
497
- return MetaPackingSchema[key]?.keyValue || fixKeyCase(key);
615
+ return resolveMetaKeyValue(key);
498
616
  },
499
617
  resolveValueData({ value, key }) {
500
618
  if (value === null)
@@ -510,7 +628,7 @@ function resolvePackedMetaObjectValue(value, key) {
510
628
  const definition = MetaPackingSchema[key];
511
629
  if (key === "refresh")
512
630
  return `${value.seconds};url=${value.url}`;
513
- return packrup.unpackToString(
631
+ return unpackToString(
514
632
  changeKeyCasingDeep(value),
515
633
  {
516
634
  entrySeparator: ", ",
@@ -609,27 +727,6 @@ async function normaliseEntryTags(e) {
609
727
  });
610
728
  }
611
729
 
612
- const PropertyPrefixKeys = /^(og|fb)/;
613
- const ColonPrefixKeys = /^(og|twitter|fb)/;
614
- function fixKeyCase(key) {
615
- key = key.replace(/([A-Z])/g, "-$1").toLowerCase();
616
- if (ColonPrefixKeys.test(key)) {
617
- key = key.replace("secure-url", "secure_url").replace(/-/g, ":");
618
- }
619
- return key;
620
- }
621
- function changeKeyCasingDeep(input) {
622
- if (Array.isArray(input)) {
623
- return input.map((entry) => changeKeyCasingDeep(entry));
624
- }
625
- if (typeof input !== "object" || Array.isArray(input))
626
- return input;
627
- const output = {};
628
- for (const [key, value] of Object.entries(input))
629
- output[fixKeyCase(key)] = changeKeyCasingDeep(value);
630
- return output;
631
- }
632
-
633
730
  const WhitelistAttributes = {
634
731
  htmlAttrs: ["id", "class", "lang", "dir"],
635
732
  bodyAttrs: ["id", "class"],
@@ -757,6 +854,11 @@ function createHead(options = {}) {
757
854
  setActiveHead(head);
758
855
  return head;
759
856
  }
857
+ function createServerHead(options = {}) {
858
+ const head = createHeadCore(options);
859
+ setActiveHead(head);
860
+ return head;
861
+ }
760
862
  function createHeadCore(options = {}) {
761
863
  let entries = [];
762
864
  let _sde = {};
@@ -886,14 +988,11 @@ const unheadComposablesImports = [
886
988
  }
887
989
  ];
888
990
 
889
- exports.ColonPrefixKeys = ColonPrefixKeys;
890
991
  exports.CorePlugins = CorePlugins;
891
992
  exports.DOMPlugins = DOMPlugins;
892
993
  exports.DedupesTagsPlugin = DedupesTagsPlugin;
893
994
  exports.DeprecatedTagAttrPlugin = DeprecatedTagAttrPlugin;
894
995
  exports.EventHandlersPlugin = EventHandlersPlugin;
895
- exports.MetaPackingSchema = MetaPackingSchema;
896
- exports.PropertyPrefixKeys = PropertyPrefixKeys;
897
996
  exports.ProvideTagHashPlugin = ProvideTagHashPlugin;
898
997
  exports.SortModifiers = SortModifiers;
899
998
  exports.SortTagsPlugin = SortTagsPlugin;
@@ -901,11 +1000,10 @@ exports.TAG_WEIGHTS = TAG_WEIGHTS;
901
1000
  exports.TagEntityBits = TagEntityBits;
902
1001
  exports.TemplateParamsPlugin = TemplateParamsPlugin;
903
1002
  exports.TitleTemplatePlugin = TitleTemplatePlugin;
904
- exports.changeKeyCasingDeep = changeKeyCasingDeep;
905
1003
  exports.composableNames = composableNames;
906
1004
  exports.createHead = createHead;
907
1005
  exports.createHeadCore = createHeadCore;
908
- exports.fixKeyCase = fixKeyCase;
1006
+ exports.createServerHead = createServerHead;
909
1007
  exports.getActiveHead = getActiveHead;
910
1008
  exports.normaliseClassProp = normaliseClassProp;
911
1009
  exports.normaliseEntryTags = normaliseEntryTags;
@@ -914,6 +1012,7 @@ exports.normaliseTag = normaliseTag;
914
1012
  exports.packMeta = packMeta;
915
1013
  exports.renderTitleTemplate = renderTitleTemplate;
916
1014
  exports.resolveMetaKeyType = resolveMetaKeyType;
1015
+ exports.resolveMetaKeyValue = resolveMetaKeyValue;
917
1016
  exports.resolvePackedMetaObjectValue = resolvePackedMetaObjectValue;
918
1017
  exports.setActiveHead = setActiveHead;
919
1018
  exports.tagWeight = tagWeight;
package/dist/index.d.ts CHANGED
@@ -2,7 +2,6 @@ import * as _unhead_schema from '@unhead/schema';
2
2
  import { HeadTag, Head, HeadEntryOptions, ActiveHeadEntry, HeadSafe, MetaFlatInput, Title, TitleTemplate, Base, Meta, Link, Script, Style, Noscript, HtmlAttributes, BodyAttributes, Unhead, HeadPlugin, CreateHeadOptions, HeadEntry, MaybeArray } from '@unhead/schema';
3
3
  import { Arrayable } from '@unhead/shared';
4
4
  export * from '@unhead/shared';
5
- import { TransformValueOptions } from 'packrup';
6
5
 
7
6
  declare const TAG_WEIGHTS: {
8
7
  readonly critical: 2;
@@ -152,6 +151,7 @@ declare const getActiveHead: () => Unhead<any> | undefined;
152
151
  declare const CorePlugins: () => HeadPlugin[];
153
152
  declare const DOMPlugins: (options?: CreateHeadOptions) => HeadPlugin[];
154
153
  declare function createHead<T extends {} = Head>(options?: CreateHeadOptions): Unhead<T>;
154
+ declare function createServerHead<T extends {} = Head>(options?: CreateHeadOptions): Unhead<T>;
155
155
  /**
156
156
  * Creates a core instance of unhead. Does not provide a global ctx for composables to work
157
157
  * and does not register DOM plugins.
@@ -172,6 +172,8 @@ declare const unheadComposablesImports: {
172
172
  */
173
173
  declare function packMeta<T extends Required<Head>['meta']>(inputs: T): MetaFlatInput;
174
174
 
175
+ declare function resolveMetaKeyType(key: string): string;
176
+ declare function resolveMetaKeyValue(key: string): string;
175
177
  /**
176
178
  * Converts a flat meta object into an array of meta entries.
177
179
  * @param input
@@ -179,26 +181,12 @@ declare function packMeta<T extends Required<Head>['meta']>(inputs: T): MetaFlat
179
181
  declare function unpackMeta<T extends MetaFlatInput>(input: T): Required<Head>['meta'];
180
182
  declare function resolvePackedMetaObjectValue(value: string, key: string): string;
181
183
 
182
- type ValidMetaType = 'name' | 'http-equiv' | 'property' | 'charset';
183
- interface PackingDefinition {
184
- metaKey?: ValidMetaType;
185
- keyValue?: string;
186
- unpack?: TransformValueOptions;
187
- }
188
- declare const MetaPackingSchema: Record<string, PackingDefinition>;
189
- declare function resolveMetaKeyType(key: string): ValidMetaType;
190
-
191
184
  declare function normaliseTag<T extends HeadTag>(tagName: T['tag'], input: HeadTag['props'] | string): Promise<T | T[] | false>;
192
185
  declare function normaliseClassProp(v: Required<Required<Head>['htmlAttrs']['class']>): string;
193
186
  declare function normaliseProps<T extends HeadTag>(tagName: T['tag'], props: T['props']): Promise<T['props']>;
194
187
  declare const TagEntityBits = 10;
195
188
  declare function normaliseEntryTags<T extends {} = Head>(e: HeadEntry<T>): Promise<HeadTag[]>;
196
189
 
197
- declare const PropertyPrefixKeys: RegExp;
198
- declare const ColonPrefixKeys: RegExp;
199
- declare function fixKeyCase(key: string): string;
200
- declare function changeKeyCasingDeep<T extends any>(input: T): T;
201
-
202
190
  declare function whitelistSafeInput(input: Record<string, MaybeArray<Record<string, string>>>): HeadSafe;
203
191
 
204
- export { ColonPrefixKeys, CorePlugins, DOMPlugins, DedupesTagsPlugin, DedupesTagsPluginOptions, DeprecatedTagAttrPlugin, EventHandlersPlugin, MetaPackingSchema, PropertyPrefixKeys, ProvideTagHashPlugin, SortModifiers, SortTagsPlugin, TAG_WEIGHTS, TagEntityBits, TemplateParamsPlugin, TitleTemplatePlugin, UseSeoMetaInput, ValidMetaType, activeHead, changeKeyCasingDeep, composableNames, createHead, createHeadCore, fixKeyCase, getActiveHead, normaliseClassProp, normaliseEntryTags, normaliseProps, normaliseTag, packMeta, renderTitleTemplate, resolveMetaKeyType, 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 };
192
+ export { CorePlugins, DOMPlugins, DedupesTagsPlugin, DedupesTagsPluginOptions, DeprecatedTagAttrPlugin, EventHandlersPlugin, ProvideTagHashPlugin, SortModifiers, SortTagsPlugin, TAG_WEIGHTS, TagEntityBits, TemplateParamsPlugin, TitleTemplatePlugin, UseSeoMetaInput, activeHead, composableNames, createHead, createHeadCore, createServerHead, getActiveHead, normaliseClassProp, normaliseEntryTags, normaliseProps, normaliseTag, packMeta, renderTitleTemplate, 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
@@ -1,8 +1,7 @@
1
1
  import { createHooks } from 'hookable';
2
2
  import { PatchDomOnEntryUpdatesPlugin, maybeGetSSRHash } from '@unhead/dom';
3
- import { defineHeadPlugin, hashTag, HasElementTags, tagDedupeKey, asArray, hashCode, TagConfigKeys, TagsWithInnerContent, ValidHeadTags } from '@unhead/shared';
3
+ import { defineHeadPlugin, hashTag, HasElementTags, tagDedupeKey, asArray as asArray$1, hashCode, TagConfigKeys, TagsWithInnerContent, ValidHeadTags } from '@unhead/shared';
4
4
  export * from '@unhead/shared';
5
- import { packArray, unpackToArray, unpackToString } from 'packrup';
6
5
 
7
6
  const TAG_WEIGHTS = {
8
7
  // aliases
@@ -369,27 +368,123 @@ function useServerSeoMeta(input, options) {
369
368
 
370
369
  const useTagTitle = (title) => useHead({ title });
371
370
  const useTagBase = (base) => useHead({ base });
372
- const useTagMeta = (meta) => useHead({ meta: asArray(meta) });
371
+ const useTagMeta = (meta) => useHead({ meta: asArray$1(meta) });
373
372
  const useTagMetaFlat = (meta) => useTagMeta(unpackMeta(meta));
374
- const useTagLink = (link) => useHead({ link: asArray(link) });
375
- const useTagScript = (script) => useHead({ script: asArray(script) });
376
- const useTagStyle = (style) => useHead({ style: asArray(style) });
377
- const useTagNoscript = (noscript) => useHead({ noscript: asArray(noscript) });
373
+ const useTagLink = (link) => useHead({ link: asArray$1(link) });
374
+ const useTagScript = (script) => useHead({ script: asArray$1(script) });
375
+ const useTagStyle = (style) => useHead({ style: asArray$1(style) });
376
+ const useTagNoscript = (noscript) => useHead({ noscript: asArray$1(noscript) });
378
377
  const useHtmlAttrs = (attrs) => useHead({ htmlAttrs: attrs });
379
378
  const useBodyAttrs = (attrs) => useHead({ bodyAttrs: attrs });
380
379
  const useTitleTemplate = (titleTemplate) => useHead({ titleTemplate });
381
380
  const useServerTagTitle = (title) => useServerHead({ title });
382
381
  const useServerTagBase = (base) => useServerHead({ base });
383
- const useServerTagMeta = (meta) => useServerHead({ meta: asArray(meta) });
382
+ const useServerTagMeta = (meta) => useServerHead({ meta: asArray$1(meta) });
384
383
  const useServerTagMetaFlat = (meta) => useServerTagMeta(unpackMeta(meta));
385
- const useServerTagLink = (link) => useServerHead({ link: asArray(link) });
386
- const useServerTagScript = (script) => useServerHead({ script: asArray(script) });
387
- const useServerTagStyle = (style) => useServerHead({ style: asArray(style) });
388
- const useServerTagNoscript = (noscript) => useServerHead({ noscript: asArray(noscript) });
384
+ const useServerTagLink = (link) => useServerHead({ link: asArray$1(link) });
385
+ const useServerTagScript = (script) => useServerHead({ script: asArray$1(script) });
386
+ const useServerTagStyle = (style) => useServerHead({ style: asArray$1(style) });
387
+ const useServerTagNoscript = (noscript) => useServerHead({ noscript: asArray$1(noscript) });
389
388
  const useServerHtmlAttrs = (attrs) => useServerHead({ htmlAttrs: attrs });
390
389
  const useServerBodyAttrs = (attrs) => useServerHead({ bodyAttrs: attrs });
391
390
  const useServerTitleTemplate = (titleTemplate) => useServerHead({ titleTemplate });
392
391
 
392
+ function asArray(input) {
393
+ return Array.isArray(input) ? input : [input];
394
+ }
395
+ const InternalKeySymbol = "_$key";
396
+ function packObject(input, options) {
397
+ const keys = Object.keys(input);
398
+ let [k, v] = keys;
399
+ options = options || {};
400
+ options.key = options.key || k;
401
+ options.value = options.value || v;
402
+ options.resolveKey = options.resolveKey || ((k2) => k2);
403
+ const resolveKey = (index) => {
404
+ const arr = asArray(options?.[index]);
405
+ return arr.find((k2) => {
406
+ if (typeof k2 === "string" && k2.includes(".")) {
407
+ return k2;
408
+ }
409
+ return k2 && keys.includes(k2);
410
+ });
411
+ };
412
+ const resolveValue = (k2, input2) => {
413
+ if (k2.includes(".")) {
414
+ const paths = k2.split(".");
415
+ let val = input2;
416
+ for (const path of paths)
417
+ val = val[path];
418
+ return val;
419
+ }
420
+ return input2[k2];
421
+ };
422
+ k = resolveKey("key") || k;
423
+ v = resolveKey("value") || v;
424
+ const dedupeKeyPrefix = input.key ? `${InternalKeySymbol}${input.key}-` : "";
425
+ let keyValue = resolveValue(k, input);
426
+ keyValue = options.resolveKey(keyValue);
427
+ return {
428
+ [`${dedupeKeyPrefix}${keyValue}`]: resolveValue(v, input)
429
+ };
430
+ }
431
+
432
+ function packArray(input, options) {
433
+ const packed = {};
434
+ for (const i of input) {
435
+ const packedObj = packObject(i, options);
436
+ const pKey = Object.keys(packedObj)[0];
437
+ const isDedupeKey = pKey.startsWith(InternalKeySymbol);
438
+ if (!isDedupeKey && packed[pKey]) {
439
+ packed[pKey] = Array.isArray(packed[pKey]) ? packed[pKey] : [packed[pKey]];
440
+ packed[pKey].push(Object.values(packedObj)[0]);
441
+ } else {
442
+ packed[isDedupeKey ? pKey.split("-").slice(1).join("-") || pKey : pKey] = packedObj[pKey];
443
+ }
444
+ }
445
+ return packed;
446
+ }
447
+
448
+ function unpackToArray(input, options) {
449
+ const unpacked = [];
450
+ const kFn = options.resolveKeyData || ((ctx) => ctx.key);
451
+ const vFn = options.resolveValueData || ((ctx) => ctx.value);
452
+ for (const [k, v] of Object.entries(input)) {
453
+ unpacked.push(...(Array.isArray(v) ? v : [v]).map((i) => {
454
+ const ctx = { key: k, value: i };
455
+ const val = vFn(ctx);
456
+ if (typeof val === "object")
457
+ return unpackToArray(val, options);
458
+ if (Array.isArray(val))
459
+ return val;
460
+ return {
461
+ [typeof options.key === "function" ? options.key(ctx) : options.key]: kFn(ctx),
462
+ [typeof options.value === "function" ? options.value(ctx) : options.value]: val
463
+ };
464
+ }).flat());
465
+ }
466
+ return unpacked;
467
+ }
468
+
469
+ function unpackToString(value, options) {
470
+ return Object.entries(value).map(([key, value2]) => {
471
+ if (typeof value2 === "object")
472
+ value2 = unpackToString(value2, options);
473
+ if (options.resolve) {
474
+ const resolved = options.resolve({ key, value: value2 });
475
+ if (resolved)
476
+ return resolved;
477
+ }
478
+ if (typeof value2 === "number")
479
+ value2 = value2.toString();
480
+ if (typeof value2 === "string" && options.wrapValue) {
481
+ value2 = value2.replace(new RegExp(options.wrapValue, "g"), `\\${options.wrapValue}`);
482
+ value2 = `${options.wrapValue}${value2}${options.wrapValue}`;
483
+ }
484
+ return `${key}${options.keyValueSeparator || ""}${value2}`;
485
+ }).join(options.entrySeparator || "");
486
+ }
487
+
393
488
  const MetaPackingSchema = {
394
489
  robots: {
395
490
  unpack: {
@@ -439,9 +534,6 @@ const MetaPackingSchema = {
439
534
  metaKey: "http-equiv"
440
535
  }
441
536
  };
442
- function resolveMetaKeyType(key) {
443
- return PropertyPrefixKeys.test(key) ? "property" : MetaPackingSchema[key]?.metaKey || "name";
444
- }
445
537
 
446
538
  function packMeta(inputs) {
447
539
  const mappedPackingSchema = Object.entries(MetaPackingSchema).map(([key, value]) => [key, value.keyValue]);
@@ -458,6 +550,32 @@ function packMeta(inputs) {
458
550
  }
459
551
 
460
552
  const ArrayableInputs = ["Image", "Video", "Audio"];
553
+ const ColonPrefixKeys = /^(og|twitter|fb)/;
554
+ const PropertyPrefixKeys = /^(og|fb)/;
555
+ function resolveMetaKeyType(key) {
556
+ return PropertyPrefixKeys.test(key) ? "property" : MetaPackingSchema[key]?.metaKey || "name";
557
+ }
558
+ function resolveMetaKeyValue(key) {
559
+ return MetaPackingSchema[key]?.keyValue || fixKeyCase(key);
560
+ }
561
+ function fixKeyCase(key) {
562
+ key = key.replace(/([A-Z])/g, "-$1").toLowerCase();
563
+ if (ColonPrefixKeys.test(key)) {
564
+ key = key.replace("secure-url", "secure_url").replace(/-/g, ":");
565
+ }
566
+ return key;
567
+ }
568
+ function changeKeyCasingDeep(input) {
569
+ if (Array.isArray(input)) {
570
+ return input.map((entry) => changeKeyCasingDeep(entry));
571
+ }
572
+ if (typeof input !== "object" || Array.isArray(input))
573
+ return input;
574
+ const output = {};
575
+ for (const [key, value] of Object.entries(input))
576
+ output[fixKeyCase(key)] = changeKeyCasingDeep(value);
577
+ return output;
578
+ }
461
579
  function unpackMeta(input) {
462
580
  const extras = [];
463
581
  ArrayableInputs.forEach((key) => {
@@ -493,7 +611,7 @@ function unpackMeta(input) {
493
611
  return key === "charset" ? "charset" : "content";
494
612
  },
495
613
  resolveKeyData({ key }) {
496
- return MetaPackingSchema[key]?.keyValue || fixKeyCase(key);
614
+ return resolveMetaKeyValue(key);
497
615
  },
498
616
  resolveValueData({ value, key }) {
499
617
  if (value === null)
@@ -598,7 +716,7 @@ const TagEntityBits = 10;
598
716
  async function normaliseEntryTags(e) {
599
717
  const tagPromises = [];
600
718
  Object.entries(e.resolvedInput).filter(([k, v]) => typeof v !== "undefined" && ValidHeadTags.includes(k)).forEach(([k, value]) => {
601
- const v = asArray(value);
719
+ const v = asArray$1(value);
602
720
  tagPromises.push(...v.map((props) => normaliseTag(k, props)).flat());
603
721
  });
604
722
  return (await Promise.all(tagPromises)).flat().filter(Boolean).map((t, i) => {
@@ -608,27 +726,6 @@ async function normaliseEntryTags(e) {
608
726
  });
609
727
  }
610
728
 
611
- const PropertyPrefixKeys = /^(og|fb)/;
612
- const ColonPrefixKeys = /^(og|twitter|fb)/;
613
- function fixKeyCase(key) {
614
- key = key.replace(/([A-Z])/g, "-$1").toLowerCase();
615
- if (ColonPrefixKeys.test(key)) {
616
- key = key.replace("secure-url", "secure_url").replace(/-/g, ":");
617
- }
618
- return key;
619
- }
620
- function changeKeyCasingDeep(input) {
621
- if (Array.isArray(input)) {
622
- return input.map((entry) => changeKeyCasingDeep(entry));
623
- }
624
- if (typeof input !== "object" || Array.isArray(input))
625
- return input;
626
- const output = {};
627
- for (const [key, value] of Object.entries(input))
628
- output[fixKeyCase(key)] = changeKeyCasingDeep(value);
629
- return output;
630
- }
631
-
632
729
  const WhitelistAttributes = {
633
730
  htmlAttrs: ["id", "class", "lang", "dir"],
634
731
  bodyAttrs: ["id", "class"],
@@ -756,6 +853,11 @@ function createHead(options = {}) {
756
853
  setActiveHead(head);
757
854
  return head;
758
855
  }
856
+ function createServerHead(options = {}) {
857
+ const head = createHeadCore(options);
858
+ setActiveHead(head);
859
+ return head;
860
+ }
759
861
  function createHeadCore(options = {}) {
760
862
  let entries = [];
761
863
  let _sde = {};
@@ -885,4 +987,4 @@ const unheadComposablesImports = [
885
987
  }
886
988
  ];
887
989
 
888
- export { ColonPrefixKeys, CorePlugins, DOMPlugins, DedupesTagsPlugin, DeprecatedTagAttrPlugin, EventHandlersPlugin, MetaPackingSchema, PropertyPrefixKeys, ProvideTagHashPlugin, SortModifiers, SortTagsPlugin, TAG_WEIGHTS, TagEntityBits, TemplateParamsPlugin, TitleTemplatePlugin, activeHead, changeKeyCasingDeep, composableNames, createHead, createHeadCore, fixKeyCase, getActiveHead, normaliseClassProp, normaliseEntryTags, normaliseProps, normaliseTag, packMeta, renderTitleTemplate, resolveMetaKeyType, 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 };
990
+ 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, renderTitleTemplate, 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,7 +1,7 @@
1
1
  {
2
2
  "name": "unhead",
3
3
  "type": "module",
4
- "version": "1.1.9",
4
+ "version": "1.1.11",
5
5
  "packageManager": "pnpm@7.27.1",
6
6
  "author": "Harlan Wilton <harlan@harlanzw.com>",
7
7
  "license": "MIT",
@@ -31,10 +31,12 @@
31
31
  ],
32
32
  "dependencies": {
33
33
  "hookable": "^5.4.2",
34
- "packrup": "^0.1.0",
35
- "@unhead/dom": "1.1.9",
36
- "@unhead/schema": "1.1.9",
37
- "@unhead/shared": "1.1.9"
34
+ "@unhead/dom": "1.1.11",
35
+ "@unhead/schema": "1.1.11",
36
+ "@unhead/shared": "1.1.11"
37
+ },
38
+ "devDependencies": {
39
+ "packrup": "^0.1.0"
38
40
  },
39
41
  "scripts": {
40
42
  "build": "unbuild .",