讨论加特殊图标

This commit is contained in:
DESKTOP-RQ919RC\Pc
2025-03-21 15:55:33 +08:00
parent 7cc2b264d2
commit 27f3bcacbf
272 changed files with 18932 additions and 35894 deletions

View File

@@ -1,637 +1,9 @@
import { createHooks } from 'hookable';
import { DomPlugin } from '@unhead/dom';
import { defineHeadPlugin, tagDedupeKey, tagWeight, HasElementTags, hashCode, NetworkEvents, SortModifiers, processTemplateParams, resolveTitleTemplate, IsBrowser, normaliseEntryTags, composableNames, whitelistSafeInput, unpackMeta } from '@unhead/shared';
export { composableNames } from '@unhead/shared';
const UsesMergeStrategy = ["templateParams", "htmlAttrs", "bodyAttrs"];
const DedupePlugin = defineHeadPlugin({
hooks: {
"tag:normalise": function({ tag }) {
["hid", "vmid", "key"].forEach((key) => {
if (tag.props[key]) {
tag.key = tag.props[key];
delete tag.props[key];
}
});
const generatedKey = tagDedupeKey(tag);
const dedupe = generatedKey || (tag.key ? `${tag.tag}:${tag.key}` : false);
if (dedupe)
tag._d = dedupe;
},
"tags:resolve": function(ctx) {
const deduping = {};
ctx.tags.forEach((tag) => {
const dedupeKey = (tag.key ? `${tag.tag}:${tag.key}` : tag._d) || tag._p;
const dupedTag = deduping[dedupeKey];
if (dupedTag) {
let strategy = tag?.tagDuplicateStrategy;
if (!strategy && UsesMergeStrategy.includes(tag.tag))
strategy = "merge";
if (strategy === "merge") {
const oldProps = dupedTag.props;
["class", "style"].forEach((key) => {
if (tag.props[key] && oldProps[key]) {
if (key === "style" && !oldProps[key].endsWith(";"))
oldProps[key] += ";";
tag.props[key] = `${oldProps[key]} ${tag.props[key]}`;
}
});
deduping[dedupeKey].props = {
...oldProps,
...tag.props
};
return;
} else if (tag._e === dupedTag._e) {
dupedTag._duped = dupedTag._duped || [];
tag._d = `${dupedTag._d}:${dupedTag._duped.length + 1}`;
dupedTag._duped.push(tag);
return;
} else if (tagWeight(tag) > tagWeight(dupedTag)) {
return;
}
}
const propCount = Object.keys(tag.props).length + (tag.innerHTML ? 1 : 0) + (tag.textContent ? 1 : 0);
if (HasElementTags.includes(tag.tag) && propCount === 0) {
delete deduping[dedupeKey];
return;
}
deduping[dedupeKey] = tag;
});
const newTags = [];
Object.values(deduping).forEach((tag) => {
const dupes = tag._duped;
delete tag._duped;
newTags.push(tag);
if (dupes)
newTags.push(...dupes);
});
ctx.tags = newTags;
ctx.tags = ctx.tags.filter((t) => !(t.tag === "meta" && (t.props.name || t.props.property) && !t.props.content));
}
}
});
const PayloadPlugin = defineHeadPlugin({
mode: "server",
hooks: {
"tags:resolve": function(ctx) {
const payload = {};
ctx.tags.filter((tag) => ["titleTemplate", "templateParams", "title"].includes(tag.tag) && tag._m === "server").forEach((tag) => {
payload[tag.tag] = tag.tag.startsWith("title") ? tag.textContent : tag.props;
});
Object.keys(payload).length && ctx.tags.push({
tag: "script",
innerHTML: JSON.stringify(payload),
props: { id: "unhead:payload", type: "application/json" }
});
}
}
});
const ValidEventTags = ["script", "link", "bodyAttrs"];
function stripEventHandlers(tag) {
const props = {};
const eventHandlers = {};
Object.entries(tag.props).forEach(([key, value]) => {
if (key.startsWith("on") && typeof value === "function") {
if (NetworkEvents.includes(key))
props[key] = `this.dataset.${key} = true`;
eventHandlers[key] = value;
} else {
props[key] = value;
}
});
return { props, eventHandlers };
}
const EventHandlersPlugin = defineHeadPlugin((head) => ({
hooks: {
"tags:resolve": function(ctx) {
for (const tag of ctx.tags) {
if (ValidEventTags.includes(tag.tag)) {
const { props, eventHandlers } = stripEventHandlers(tag);
tag.props = props;
if (Object.keys(eventHandlers).length) {
if (tag.props.src || tag.props.href)
tag.key = tag.key || hashCode(tag.props.src || tag.props.href);
tag._eventHandlers = eventHandlers;
}
}
}
},
"dom:renderTag": function(ctx, dom, track) {
if (!ctx.tag._eventHandlers)
return;
const $eventListenerTarget = ctx.tag.tag === "bodyAttrs" ? dom.defaultView : ctx.$el;
Object.entries(ctx.tag._eventHandlers).forEach(([k, value]) => {
const sdeKey = `${ctx.tag._d || ctx.tag._p}:${k}`;
const eventName = k.slice(2).toLowerCase();
const eventDedupeKey = `data-h-${eventName}`;
track(ctx.id, sdeKey, () => {
});
if (ctx.$el.hasAttribute(eventDedupeKey))
return;
ctx.$el.setAttribute(eventDedupeKey, "");
let observer;
const handler = (e) => {
value(e);
observer?.disconnect();
};
if (k in ctx.$el.dataset) {
handler(new Event(k.replace("on", "")));
} else if (NetworkEvents.includes(k) && typeof MutationObserver !== "undefined") {
observer = new MutationObserver((e) => {
const hasAttr = e.some((m) => m.attributeName === `data-${k}`);
if (hasAttr) {
handler(new Event(k.replace("on", "")));
observer?.disconnect();
}
});
observer.observe(ctx.$el, {
attributes: true
});
} else {
$eventListenerTarget.addEventListener(eventName, handler);
}
track(ctx.id, sdeKey, () => {
observer?.disconnect();
$eventListenerTarget.removeEventListener(eventName, handler);
ctx.$el.removeAttribute(eventDedupeKey);
});
});
}
}
}));
const DupeableTags = ["link", "style", "script", "noscript"];
const HashKeyedPlugin = defineHeadPlugin({
hooks: {
"tag:normalise": ({ tag }) => {
if (tag.key && DupeableTags.includes(tag.tag)) {
tag.props["data-hid"] = tag._h = hashCode(tag.key);
}
}
}
});
const SortPlugin = defineHeadPlugin({
hooks: {
"tags:resolve": (ctx) => {
const tagPositionForKey = (key) => ctx.tags.find((tag) => tag._d === key)?._p;
for (const { prefix, offset } of SortModifiers) {
for (const tag of ctx.tags.filter((tag2) => typeof tag2.tagPriority === "string" && tag2.tagPriority.startsWith(prefix))) {
const position = tagPositionForKey(
tag.tagPriority.replace(prefix, "")
);
if (typeof position !== "undefined")
tag._p = position + offset;
}
}
ctx.tags.sort((a, b) => a._p - b._p).sort((a, b) => tagWeight(a) - tagWeight(b));
}
}
});
const SupportedAttrs = {
meta: "content",
link: "href",
htmlAttrs: "lang"
};
const TemplateParamsPlugin = defineHeadPlugin((head) => ({
hooks: {
"tags:resolve": (ctx) => {
const { tags } = ctx;
const title = tags.find((tag) => tag.tag === "title")?.textContent;
const idx = tags.findIndex((tag) => tag.tag === "templateParams");
const params = idx !== -1 ? tags[idx].props : {};
const sep = params.separator || "|";
delete params.separator;
params.pageTitle = processTemplateParams(params.pageTitle || title || "", params, sep);
for (const tag of tags.filter((t) => t.processTemplateParams !== false)) {
const v = SupportedAttrs[tag.tag];
if (v && typeof tag.props[v] === "string") {
tag.props[v] = processTemplateParams(tag.props[v], params, sep);
} else if (tag.processTemplateParams === true || ["titleTemplate", "title"].includes(tag.tag)) {
["innerHTML", "textContent"].forEach((p) => {
if (typeof tag[p] === "string")
tag[p] = processTemplateParams(tag[p], params, sep);
});
}
}
head._templateParams = params;
head._separator = sep;
ctx.tags = tags.filter((tag) => tag.tag !== "templateParams");
}
}
}));
const TitleTemplatePlugin = defineHeadPlugin({
hooks: {
"tags:resolve": (ctx) => {
const { tags } = ctx;
let titleTemplateIdx = tags.findIndex((i) => i.tag === "titleTemplate");
const titleIdx = tags.findIndex((i) => i.tag === "title");
if (titleIdx !== -1 && titleTemplateIdx !== -1) {
const newTitle = resolveTitleTemplate(
tags[titleTemplateIdx].textContent,
tags[titleIdx].textContent
);
if (newTitle !== null) {
tags[titleIdx].textContent = newTitle || tags[titleIdx].textContent;
} else {
delete tags[titleIdx];
}
} else if (titleTemplateIdx !== -1) {
const newTitle = resolveTitleTemplate(
tags[titleTemplateIdx].textContent
);
if (newTitle !== null) {
tags[titleTemplateIdx].textContent = newTitle;
tags[titleTemplateIdx].tag = "title";
titleTemplateIdx = -1;
}
}
if (titleTemplateIdx !== -1) {
delete tags[titleTemplateIdx];
}
ctx.tags = tags.filter(Boolean);
}
}
});
const XSSPlugin = defineHeadPlugin({
hooks: {
"tags:afterResolve": function(ctx) {
for (const tag of ctx.tags) {
if (typeof tag.innerHTML === "string") {
if (tag.innerHTML && ["application/ld+json", "application/json"].includes(tag.props.type)) {
tag.innerHTML = tag.innerHTML.replace(/</g, "\\u003C");
} else {
tag.innerHTML = tag.innerHTML.replace(new RegExp(`</${tag.tag}`, "g"), `<\\/${tag.tag}`);
}
}
}
}
}
});
let activeHead;
// @__NO_SIDE_EFFECTS__
function createHead(options = {}) {
const head = createHeadCore(options);
head.use(DomPlugin());
return activeHead = head;
}
// @__NO_SIDE_EFFECTS__
function createServerHead(options = {}) {
return activeHead = createHeadCore(options);
}
function filterMode(mode, ssr) {
return !mode || mode === "server" && ssr || mode === "client" && !ssr;
}
function createHeadCore(options = {}) {
const hooks = createHooks();
hooks.addHooks(options.hooks || {});
options.document = options.document || (IsBrowser ? document : void 0);
const ssr = !options.document;
const updated = () => {
head.dirty = true;
hooks.callHook("entries:updated", head);
};
let entryCount = 0;
let entries = [];
const plugins = [];
const head = {
plugins,
dirty: false,
resolvedOptions: options,
hooks,
headEntries() {
return entries;
},
use(p) {
const plugin = typeof p === "function" ? p(head) : p;
if (!plugin.key || !plugins.some((p2) => p2.key === plugin.key)) {
plugins.push(plugin);
filterMode(plugin.mode, ssr) && hooks.addHooks(plugin.hooks || {});
}
},
push(input, entryOptions) {
delete entryOptions?.head;
const entry = {
_i: entryCount++,
input,
...entryOptions
};
if (filterMode(entry.mode, ssr)) {
entries.push(entry);
updated();
}
return {
dispose() {
entries = entries.filter((e) => e._i !== entry._i);
hooks.callHook("entries:updated", head);
updated();
},
// a patch is the same as creating a new entry, just a nice DX
patch(input2) {
entries = entries.map((e) => {
if (e._i === entry._i) {
e.input = entry.input = input2;
}
return e;
});
updated();
}
};
},
async resolveTags() {
const resolveCtx = { tags: [], entries: [...entries] };
await hooks.callHook("entries:resolve", resolveCtx);
for (const entry of resolveCtx.entries) {
const resolved = entry.resolvedInput || entry.input;
entry.resolvedInput = await (entry.transform ? entry.transform(resolved) : resolved);
if (entry.resolvedInput) {
for (const tag of await normaliseEntryTags(entry)) {
const tagCtx = { tag, entry, resolvedOptions: head.resolvedOptions };
await hooks.callHook("tag:normalise", tagCtx);
resolveCtx.tags.push(tagCtx.tag);
}
}
}
await hooks.callHook("tags:beforeResolve", resolveCtx);
await hooks.callHook("tags:resolve", resolveCtx);
await hooks.callHook("tags:afterResolve", resolveCtx);
return resolveCtx.tags;
},
ssr
};
[
DedupePlugin,
PayloadPlugin,
EventHandlersPlugin,
HashKeyedPlugin,
SortPlugin,
TemplateParamsPlugin,
TitleTemplatePlugin,
XSSPlugin,
...options?.plugins || []
].forEach((p) => head.use(p));
head.hooks.callHook("init", head);
return head;
}
// @__NO_SIDE_EFFECTS__
function HashHydrationPlugin() {
return defineHeadPlugin({});
}
const importRe = /@import/;
// @__NO_SIDE_EFFECTS__
function CapoPlugin(options) {
return defineHeadPlugin({
hooks: {
"tags:beforeResolve": function({ tags }) {
for (const tag of tags) {
if (tag.tagPosition && tag.tagPosition !== "head")
continue;
tag.tagPriority = tag.tagPriority || tagWeight(tag);
if (tag.tagPriority !== 100)
continue;
const isTruthy = (val) => val === "" || val === true;
const isScript = tag.tag === "script";
const isLink = tag.tag === "link";
if (isScript && isTruthy(tag.props.async)) {
tag.tagPriority = 30;
} else if (tag.tag === "style" && tag.innerHTML && importRe.test(tag.innerHTML)) {
tag.tagPriority = 40;
} else if (isScript && tag.props.src && !isTruthy(tag.props.defer) && !isTruthy(tag.props.async) && tag.props.type !== "module" && !tag.props.type?.endsWith("json")) {
tag.tagPriority = 50;
} else if (isLink && tag.props.rel === "stylesheet" || tag.tag === "style") {
tag.tagPriority = 60;
} else if (isLink && ["preload", "modulepreload"].includes(tag.props.rel)) {
tag.tagPriority = 70;
} else if (isScript && isTruthy(tag.props.defer) && tag.props.src && !isTruthy(tag.props.async)) {
tag.tagPriority = 80;
} else if (isLink && ["prefetch", "dns-prefetch", "prerender"].includes(tag.props.rel)) {
tag.tagPriority = 90;
}
}
options?.track && tags.push({
tag: "htmlAttrs",
props: {
"data-capo": ""
}
});
}
}
});
}
const unheadComposablesImports = [
{
from: "unhead",
imports: composableNames
}
];
function getActiveHead() {
return activeHead;
}
function useHead(input, options = {}) {
const head = options.head || getActiveHead();
return head?.push(input, options);
}
function useHeadSafe(input, options = {}) {
return useHead(input, {
...options || {},
transform: whitelistSafeInput
});
}
function useServerHead(input, options = {}) {
return useHead(input, { ...options, mode: "server" });
}
function useServerHeadSafe(input, options = {}) {
return useHeadSafe(input, { ...options, mode: "server" });
}
function useSeoMeta(input, options) {
const { title, titleTemplate, ...meta } = input;
return useHead({
title,
titleTemplate,
// we need to input the meta so the reactivity will be resolved
// @ts-expect-error runtime type
_flatMeta: meta
}, {
...options,
transform(t) {
const meta2 = unpackMeta({ ...t._flatMeta });
delete t._flatMeta;
return {
// @ts-expect-error runtime type
...t,
meta: meta2
};
}
});
}
function useServerSeoMeta(input, options) {
return useSeoMeta(input, {
...options || {},
mode: "server"
});
}
const UseScriptDefaults = {
defer: true,
fetchpriority: "low"
};
function useScript(input, _options) {
const options = _options || {};
const head = options.head || getActiveHead();
if (!head)
throw new Error("No active head found, please provide a head instance or use the useHead composable");
const id = input.key || hashCode(input.src || (typeof input.innerHTML === "string" ? input.innerHTML : ""));
const key = `use-script.${id}`;
if (head._scripts?.[id])
return head._scripts[id];
async function transform(entry) {
const script2 = await (options.transform || ((input2) => input2))(entry.script[0]);
const ctx = { script: script2 };
await head.hooks.callHook("script:transform", ctx);
return { script: [ctx.script] };
}
function maybeHintEarlyConnection(rel) {
if (
// opt-out
options.skipEarlyConnections || !input.src.includes("//") || !head.ssr
)
return;
const key2 = `use-script.${id}.early-connection`;
head.push({
link: [{ key: key2, rel, href: new URL(input.src).origin }]
}, { mode: "server" });
}
const script = {
id,
status: "awaitingLoad",
loaded: false,
remove() {
if (script.status === "loaded") {
script.entry?.dispose();
script.status = "removed";
head.hooks.callHook(`script:updated`, hookCtx);
delete head._scripts?.[id];
return true;
}
return false;
},
waitForLoad() {
return new Promise((resolve) => {
if (script.status === "loaded")
resolve(options.use());
function watchForScriptLoaded({ script: script2 }) {
if (script2.id === id && script2.status === "loaded") {
resolve(options.use?.());
head.hooks.removeHook("script:updated", watchForScriptLoaded);
}
}
head.hooks.hook("script:updated", watchForScriptLoaded);
});
},
load() {
if (script.status !== "awaitingLoad")
return script.waitForLoad();
script.status = "loading";
head.hooks.callHook(`script:updated`, hookCtx);
script.entry = head.push({
script: [
// async by default
{ ...UseScriptDefaults, ...input, key }
]
}, {
...options,
// @ts-expect-error untyped
transform,
head
});
return script.waitForLoad();
}
};
const hookCtx = { script };
NetworkEvents.forEach((fn) => {
const _fn = typeof input[fn] === "function" ? input[fn].bind({}) : null;
input[fn] = (e) => {
script.status = fn === "onload" ? "loaded" : fn === "onerror" ? "error" : "loading";
head.hooks.callHook(`script:updated`, hookCtx);
_fn && _fn(e);
};
});
let trigger = options.trigger;
if (trigger) {
const isIdle = trigger === "idle";
if (isIdle) {
if (head.ssr)
trigger = "manual";
else
trigger = new Promise((resolve) => requestIdleCallback(() => resolve()));
}
trigger === "manual" && (trigger = new Promise(() => {
}));
trigger instanceof Promise && trigger.then(script.load);
maybeHintEarlyConnection(isIdle ? "preconnect" : "dns-prefetch");
} else {
script.load();
maybeHintEarlyConnection("preconnect");
}
function resolveInnerHtmlLoad(ctx) {
if (ctx.tag.key === key) {
if (ctx.tag.innerHTML) {
setTimeout(
() => {
script.status = "loaded";
head.hooks.callHook("script:updated", hookCtx);
typeof input.onload === "function" && input.onload(new Event("load"));
},
5
/* give inline script a chance to run */
);
}
head.hooks.removeHook("dom:renderTag", resolveInnerHtmlLoad);
}
}
head.hooks.hook("dom:renderTag", resolveInnerHtmlLoad);
const instance = new Proxy({}, {
get(_, fn) {
const stub = options.stub?.({ script, fn });
if (stub)
return stub;
if (fn === "$script")
return script;
return (...args) => {
if (head.ssr || !options.use)
return;
if (script.loaded) {
const api = options.use();
return api[fn](...args);
} else {
return script.waitForLoad().then(
(api) => {
api[fn](...args);
}
);
}
};
}
});
head._scripts = head._scripts || {};
head._scripts[id] = instance;
return instance;
}
export { CapoPlugin, HashHydrationPlugin, createHead, createHeadCore, createServerHead, getActiveHead, unheadComposablesImports, useHead, useHeadSafe, useScript, useSeoMeta, useServerHead, useServerHeadSafe, useServerSeoMeta };
export { u as useHead, a as useHeadSafe, b as useSeoMeta, c as useServerHead, d as useServerHeadSafe, e as useServerSeoMeta } from './shared/unhead.BPM0-cfG.mjs';
export { c as createHeadCore, a as createUnhead } from './shared/unhead.B52g_5xR.mjs';
export { u as useScript } from './shared/unhead.B578PsDV.mjs';
import './shared/unhead.CApf5sj3.mjs';
import './shared/unhead.DQc16pHI.mjs';
import './shared/unhead.yem5I2v_.mjs';
import 'hookable';
import './shared/unhead.BaPU1zLf.mjs';
import './shared/unhead.DZbvapt-.mjs';

94
.output/server/node_modules/unhead/dist/plugins.mjs generated vendored Normal file
View File

@@ -0,0 +1,94 @@
export { A as AliasSortingPlugin, D as DeprecationsPlugin, P as PromisesPlugin, T as TemplateParamsPlugin } from './shared/unhead.DnNYlT4k.mjs';
import { d as defineHeadPlugin } from './shared/unhead.CApf5sj3.mjs';
export { F as FlatMetaPlugin, S as SafeInputPlugin } from './shared/unhead.CApf5sj3.mjs';
import './shared/unhead.DZbvapt-.mjs';
import './shared/unhead.kVuXtrDW.mjs';
import './shared/unhead.DQc16pHI.mjs';
import './shared/unhead.yem5I2v_.mjs';
function CanonicalPlugin(options) {
return (head) => {
function resolvePath(path) {
if (options?.customResolver) {
return options.customResolver(path);
}
let host = options.canonicalHost || (!head.ssr ? window.location.origin : "");
if (!host.startsWith("http") && !host.startsWith("//")) {
host = `https://${host}`;
}
host = new URL(host).origin;
if (path.startsWith("http") || path.startsWith("//"))
return path;
try {
return new URL(path, host).toString();
} catch {
return path;
}
}
return {
key: "canonical",
hooks: {
"tags:resolve": (ctx) => {
for (const tag of ctx.tags) {
if (tag.tag === "meta") {
if (tag.props.property?.startsWith("og:image") || tag.props.name?.startsWith("twitter:image")) {
tag.props.content = resolvePath(tag.props.content);
} else if (tag.props?.property === "og:url") {
tag.props.content = resolvePath(tag.props.content);
}
} else if (tag.tag === "link" && tag.props.rel === "canonical") {
tag.props.href = resolvePath(tag.props.href);
}
}
}
}
};
};
}
function InferSeoMetaPlugin(options = {}) {
return defineHeadPlugin((head) => {
head.push({
meta: [
{
name: "twitter:card",
content: options.twitterCard || "summary_large_image",
tagPriority: "low"
},
{
"property": "og:title",
"tagPriority": "low",
"data-infer": ""
},
{
"property": "og:description",
"tagPriority": "low",
"data-infer": ""
}
]
});
return {
key: "infer-seo-meta",
hooks: {
"tags:beforeResolve": ({ tagMap }) => {
let title = head._title || "";
const titleTemplate = head._titleTemplate;
const ogTitle = tagMap.get("meta:og:title");
if (typeof ogTitle?.props["data-infer"] !== "undefined") {
if (titleTemplate) {
title = typeof titleTemplate === "function" ? titleTemplate(title) : titleTemplate.replace("%s", title);
}
ogTitle.props.content = options.ogTitle ? options.ogTitle(title) : title || "";
}
const description = tagMap.get("meta:description")?.props?.content;
const ogDescription = tagMap.get("meta:og:description");
if (typeof ogDescription?.props["data-infer"] !== "undefined") {
ogDescription.props.content = options.ogDescription ? options.ogDescription(description) : description || "";
}
}
}
};
});
}
export { CanonicalPlugin, InferSeoMetaPlugin, defineHeadPlugin };

30
.output/server/node_modules/unhead/dist/scripts.mjs generated vendored Normal file
View File

@@ -0,0 +1,30 @@
export { r as resolveScriptKey, u as useScript } from './shared/unhead.B578PsDV.mjs';
import './shared/unhead.yem5I2v_.mjs';
function createSpyProxy(target, onApply) {
const stack = [];
let stackIdx = -1;
const handler = (reuseStack = false) => ({
get(_, prop, receiver) {
if (!reuseStack) {
stackIdx++;
stack[stackIdx] = [];
}
const v = Reflect.get(_, prop, receiver);
if (typeof v === "object" || typeof v === "function") {
stack[stackIdx].push({ type: "get", key: prop });
return new Proxy(v, handler(true));
}
stack[stackIdx].push({ type: "get", key: prop, value: v });
return v;
},
apply(_, __, args) {
stack[stackIdx].push({ type: "apply", key: "", args });
onApply(stack);
return Reflect.apply(_, __, args);
}
});
return new Proxy(target, handler());
}
export { createSpyProxy };

214
.output/server/node_modules/unhead/dist/server.mjs generated vendored Normal file
View File

@@ -0,0 +1,214 @@
import { a as createUnhead } from './shared/unhead.B52g_5xR.mjs';
import { T as TagsWithInnerContent, S as SelfClosingTags$1 } from './shared/unhead.yem5I2v_.mjs';
import 'hookable';
import './shared/unhead.BaPU1zLf.mjs';
import './shared/unhead.DZbvapt-.mjs';
function createHead(options = {}) {
const unhead = createUnhead({
...options,
// @ts-expect-error untyped
document: false,
propResolvers: [
...options.propResolvers || [],
(k, v) => {
if (k && k.startsWith("on") && typeof v === "function") {
return `this.dataset.${k}fired = true`;
}
return v;
}
],
init: [
options.disableDefaults ? void 0 : {
htmlAttrs: {
lang: "en"
},
meta: [
{
charset: "utf-8"
},
{
name: "viewport",
content: "width=device-width, initial-scale=1"
}
]
},
...options.init || []
]
});
unhead.use({
key: "server",
hooks: {
"tags:resolve": function(ctx) {
const title = ctx.tagMap.get("title");
const titleTemplate = ctx.tagMap.get("titleTemplate");
const templateParams = ctx.tagMap.get("templateParams");
const payload = {
title: title?.mode === "server" ? unhead._title : void 0,
titleTemplate: titleTemplate?.mode === "server" ? unhead._titleTemplate : void 0,
templateParams: templateParams?.mode === "server" ? unhead._templateParams : void 0
};
if (Object.values(payload).some(Boolean)) {
ctx.tags.push({
tag: "script",
innerHTML: JSON.stringify(payload),
props: { id: "unhead:payload", type: "application/json" }
});
}
}
}
});
return unhead;
}
const Attrs = /(\w+)(?:=["']([^"']*)["'])?/g;
const HtmlTag = /<html[^>]*>/;
const BodyTag = /<body[^>]*>/;
const HeadContent = /<head[^>]*>(.*?)<\/head>/s;
const SelfClosingTags = /<(meta|link|base)[^>]*>/g;
const ClosingTags = /<(title|script|style)[^>]*>[\s\S]*?<\/\1>/g;
const NewLines = /(\n\s*)+/g;
function extractAttributes(tag) {
const inner = tag.match(/<([^>]*)>/)?.[1].split(" ").slice(1).join(" ");
if (!inner)
return {};
const attrs = inner.match(Attrs);
return attrs?.reduce((acc, attr) => {
const sep = attr.indexOf("=");
const key = sep > 0 ? attr.slice(0, sep) : attr;
const val = sep > 0 ? attr.slice(sep + 1).slice(1, -1) : true;
return { ...acc, [key]: val };
}, {}) || {};
}
function extractUnheadInputFromHtml(html) {
const input = {};
input.htmlAttrs = extractAttributes(html.match(HtmlTag)?.[0] || "");
html = html.replace(HtmlTag, "<html>");
input.bodyAttrs = extractAttributes(html.match(BodyTag)?.[0] || "");
html = html.replace(BodyTag, "<body>");
const innerHead = html.match(HeadContent)?.[1] || "";
innerHead.match(SelfClosingTags)?.forEach((s) => {
html = html.replace(s, "");
const tag = s.split(" ")[0].slice(1);
input[tag] = input[tag] || [];
input[tag].push(extractAttributes(s));
});
innerHead.match(ClosingTags)?.map((tag) => tag.trim()).filter(Boolean).forEach((tag) => {
html = html.replace(tag, "");
const type = tag.match(/<([a-z-]+)/)?.[1];
const res = extractAttributes(tag);
const innerContent = tag.match(/>([\s\S]*)</)?.[1];
if (innerContent) {
res[type !== "script" ? "textContent" : "innerHTML"] = innerContent;
}
if (type === "title") {
input.title = res;
} else {
input[type] = input[type] || [];
input[type].push(res);
}
});
html = html.replace(NewLines, "\n");
return { html, input };
}
function encodeAttribute(value) {
return String(value).replace(/"/g, "&quot;");
}
function propsToString(props) {
let attrs = "";
for (const key in props) {
if (!Object.hasOwn(props, key))
continue;
let value = props[key];
if ((key === "class" || key === "style") && typeof value !== "string") {
value = key === "class" ? Array.from(value).join(" ") : Array.from(value).map(([k, v]) => `${k}:${v}`).join(";");
}
if (value !== false && value !== null) {
attrs += value === true ? ` ${key}` : ` ${key}="${encodeAttribute(value)}"`;
}
}
return attrs;
}
function escapeHtml(str) {
return str.replace(/[&<>"'/]/g, (char) => {
switch (char) {
case "&":
return "&amp;";
case "<":
return "&lt;";
case ">":
return "&gt;";
case '"':
return "&quot;";
case "'":
return "&#x27;";
case "/":
return "&#x2F;";
default:
return char;
}
});
}
function tagToString(tag) {
const attrs = propsToString(tag.props);
const openTag = `<${tag.tag}${attrs}>`;
if (!TagsWithInnerContent.has(tag.tag))
return SelfClosingTags$1.has(tag.tag) ? openTag : `${openTag}</${tag.tag}>`;
let content = String(tag.innerHTML || "");
if (tag.textContent)
content = escapeHtml(String(tag.textContent));
return SelfClosingTags$1.has(tag.tag) ? openTag : `${openTag}${content}</${tag.tag}>`;
}
function ssrRenderTags(tags, options) {
const schema = { htmlAttrs: {}, bodyAttrs: {}, tags: { head: "", bodyClose: "", bodyOpen: "" } };
const lineBreaks = !options?.omitLineBreaks ? "\n" : "";
for (const tag of tags) {
if (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs") {
Object.assign(schema[tag.tag], tag.props);
continue;
}
const s = tagToString(tag);
const tagPosition = tag.tagPosition || "head";
schema.tags[tagPosition] += schema.tags[tagPosition] ? `${lineBreaks}${s}` : s;
}
return {
headTags: schema.tags.head,
bodyTags: schema.tags.bodyClose,
bodyTagsOpen: schema.tags.bodyOpen,
htmlAttrs: propsToString(schema.htmlAttrs),
bodyAttrs: propsToString(schema.bodyAttrs)
};
}
async function renderSSRHead(head, options) {
const beforeRenderCtx = { shouldRender: true };
await head.hooks.callHook("ssr:beforeRender", beforeRenderCtx);
if (!beforeRenderCtx.shouldRender) {
return {
headTags: "",
bodyTags: "",
bodyTagsOpen: "",
htmlAttrs: "",
bodyAttrs: ""
};
}
const ctx = { tags: options?.resolvedTags || await head.resolveTags() };
await head.hooks.callHook("ssr:render", ctx);
const html = ssrRenderTags(ctx.tags, options);
const renderCtx = { tags: ctx.tags, html };
await head.hooks.callHook("ssr:rendered", renderCtx);
return renderCtx.html;
}
async function transformHtmlTemplate(head, html, options) {
const { html: parsedHtml, input } = extractUnheadInputFromHtml(html);
head.push(input, { _index: 0 });
const headHtml = await renderSSRHead(head, options);
return parsedHtml.replace("<html>", `<html${headHtml.htmlAttrs}>`).replace("<body>", `<body>${headHtml.bodyTagsOpen ? `
${headHtml.bodyTagsOpen}` : ``}`).replace("<body>", `<body${headHtml.bodyAttrs}>`).replace("</head>", `${headHtml.headTags}</head>`).replace("</body>", `${headHtml.bodyTags}</body>`);
}
export { createHead, escapeHtml, extractUnheadInputFromHtml, propsToString, renderSSRHead, ssrRenderTags, tagToString, transformHtmlTemplate };

View File

@@ -0,0 +1,170 @@
import { createHooks } from 'hookable';
import { n as normalizeEntryToTags, d as dedupeKey, i as isMetaArrayDupeKey } from './unhead.BaPU1zLf.mjs';
import { t as tagWeight, s as sortTags } from './unhead.DZbvapt-.mjs';
import { c as UsesMergeStrategy, V as ValidHeadTags } from './unhead.yem5I2v_.mjs';
function registerPlugin(head, p) {
const plugin = typeof p === "function" ? p(head) : p;
const key = plugin.key || String(head.plugins.size + 1);
const exists = head.plugins.get(key);
if (!exists) {
head.plugins.set(key, plugin);
head.hooks.addHooks(plugin.hooks || {});
}
}
function createHeadCore(resolvedOptions = {}) {
return createUnhead(resolvedOptions);
}
function createUnhead(resolvedOptions = {}) {
const hooks = createHooks();
hooks.addHooks(resolvedOptions.hooks || {});
const ssr = !resolvedOptions.document;
const entries = /* @__PURE__ */ new Map();
const plugins = /* @__PURE__ */ new Map();
const normalizeQueue = [];
const head = {
_entryCount: 1,
// 0 is reserved for internal use
plugins,
dirty: false,
resolvedOptions,
hooks,
ssr,
entries,
headEntries() {
return [...entries.values()];
},
use: (p) => registerPlugin(head, p),
push(input, _options) {
const options = { ..._options || {} };
delete options.head;
const _i = options._index ?? head._entryCount++;
const inst = { _i, input, options };
const _ = {
_poll(rm = false) {
head.dirty = true;
!rm && normalizeQueue.push(_i);
hooks.callHook("entries:updated", head);
},
dispose() {
if (entries.delete(_i)) {
_._poll(true);
}
},
// a patch is the same as creating a new entry, just a nice DX
patch(input2) {
if (!options.mode || options.mode === "server" && ssr || options.mode === "client" && !ssr) {
inst.input = input2;
entries.set(_i, inst);
_._poll();
}
}
};
_.patch(input);
return _;
},
async resolveTags() {
const ctx = {
tagMap: /* @__PURE__ */ new Map(),
tags: [],
entries: [...head.entries.values()]
};
await hooks.callHook("entries:resolve", ctx);
while (normalizeQueue.length) {
const i = normalizeQueue.shift();
const e = entries.get(i);
if (e) {
const normalizeCtx = {
tags: normalizeEntryToTags(e.input, resolvedOptions.propResolvers || []).map((t) => Object.assign(t, e.options)),
entry: e
};
await hooks.callHook("entries:normalize", normalizeCtx);
e._tags = normalizeCtx.tags.map((t, i2) => {
t._w = tagWeight(head, t);
t._p = (e._i << 10) + i2;
t._d = dedupeKey(t);
return t;
});
}
}
let hasFlatMeta = false;
ctx.entries.flatMap((e) => (e._tags || []).map((t) => ({ ...t, props: { ...t.props } }))).sort(sortTags).reduce((acc, next) => {
const k = String(next._d || next._p);
if (!acc.has(k))
return acc.set(k, next);
const prev = acc.get(k);
const strategy = next?.tagDuplicateStrategy || (UsesMergeStrategy.has(next.tag) ? "merge" : null) || (next.key && next.key === prev.key ? "merge" : null);
if (strategy === "merge") {
const newProps = { ...prev.props };
Object.entries(next.props).forEach(([p, v]) => (
// @ts-expect-error untyped
newProps[p] = p === "style" ? new Map([...prev.props.style || /* @__PURE__ */ new Map(), ...v]) : p === "class" ? /* @__PURE__ */ new Set([...prev.props.class || /* @__PURE__ */ new Set(), ...v]) : v
));
acc.set(k, { ...next, props: newProps });
} else if (next._p >> 10 === prev._p >> 10 && isMetaArrayDupeKey(next._d)) {
acc.set(k, Object.assign([...Array.isArray(prev) ? prev : [prev], next], next));
hasFlatMeta = true;
} else if (next._w === prev._w ? next._p > prev._p : next?._w < prev?._w) {
acc.set(k, next);
}
return acc;
}, ctx.tagMap);
const title = ctx.tagMap.get("title");
const titleTemplate = ctx.tagMap.get("titleTemplate");
head._title = title?.textContent;
if (titleTemplate) {
const titleTemplateFn = titleTemplate?.textContent;
head._titleTemplate = typeof titleTemplateFn === "string" ? titleTemplateFn : void 0;
if (titleTemplateFn) {
let newTitle = typeof titleTemplateFn === "function" ? titleTemplateFn(title?.textContent) : titleTemplateFn;
if (typeof newTitle === "string" && !head.plugins.has("template-params")) {
newTitle = newTitle.replace("%s", title?.textContent || "");
}
if (title) {
newTitle === null ? ctx.tagMap.delete("title") : ctx.tagMap.set("title", { ...title, textContent: newTitle });
} else {
titleTemplate.tag = "title";
titleTemplate.textContent = newTitle;
}
}
}
ctx.tags = Array.from(ctx.tagMap.values());
if (hasFlatMeta) {
ctx.tags = ctx.tags.flat().sort(sortTags);
}
await hooks.callHook("tags:beforeResolve", ctx);
await hooks.callHook("tags:resolve", ctx);
await hooks.callHook("tags:afterResolve", ctx);
const finalTags = [];
for (const t of ctx.tags) {
const { innerHTML, tag, props } = t;
if (!ValidHeadTags.has(tag)) {
continue;
}
if (Object.keys(props).length === 0 && !t.innerHTML && !t.textContent) {
continue;
}
if (tag === "meta" && !props.content && !props["http-equiv"] && !props.charset) {
continue;
}
if (tag === "script" && innerHTML) {
if (props.type?.endsWith("json")) {
const v = typeof innerHTML === "string" ? innerHTML : JSON.stringify(innerHTML);
t.innerHTML = v.replace(/</g, "\\u003C");
} else if (typeof innerHTML === "string") {
t.innerHTML = innerHTML.replace(new RegExp(`</${tag}`, "g"), `<\\/${tag}`);
}
t._d = dedupeKey(t);
}
finalTags.push(t);
}
return finalTags;
}
};
(resolvedOptions?.plugins || []).forEach((p) => registerPlugin(head, p));
head.hooks.callHook("init", head);
resolvedOptions.init?.forEach((e) => e && head.push(e));
return head;
}
export { createUnhead as a, createHeadCore as c };

View File

@@ -0,0 +1,266 @@
import { b as ScriptNetworkEvents } from './unhead.yem5I2v_.mjs';
function createNoopedRecordingProxy(instance = {}) {
const stack = [];
let stackIdx = -1;
const handler = (reuseStack = false) => ({
get(_, prop, receiver) {
if (!reuseStack) {
const v = Reflect.get(_, prop, receiver);
if (typeof v !== "undefined") {
return v;
}
stackIdx++;
stack[stackIdx] = [];
}
stack[stackIdx].push({ type: "get", key: prop });
return new Proxy(() => {
}, handler(true));
},
apply(_, __, args) {
stack[stackIdx].push({ type: "apply", key: "", args });
return void 0;
}
});
return {
proxy: new Proxy(instance || {}, handler()),
stack
};
}
function createForwardingProxy(target) {
const handler = {
get(_, prop, receiver) {
const v = Reflect.get(_, prop, receiver);
if (typeof v === "object") {
return new Proxy(v, handler);
}
return v;
},
apply(_, __, args) {
Reflect.apply(_, __, args);
return void 0;
}
};
return new Proxy(target, handler);
}
function replayProxyRecordings(target, stack) {
stack.forEach((recordings) => {
let context = target;
let prevContext = target;
recordings.forEach(({ type, key, args }) => {
if (type === "get") {
prevContext = context;
context = context[key];
} else if (type === "apply") {
context = context.call(prevContext, ...args);
}
});
});
}
function resolveScriptKey(input) {
return input.key || input.src || (typeof input.innerHTML === "string" ? input.innerHTML : "");
}
const PreconnectServerModes = ["preconnect", "dns-prefetch"];
function useScript(head, _input, _options) {
const input = typeof _input === "string" ? { src: _input } : _input;
const options = _options || {};
const id = resolveScriptKey(input);
const prevScript = head._scripts?.[id];
if (prevScript) {
prevScript.setupTriggerHandler(options.trigger);
return prevScript;
}
options.beforeInit?.();
const syncStatus = (s) => {
script.status = s;
head.hooks.callHook(`script:updated`, hookCtx);
};
ScriptNetworkEvents.forEach((fn) => {
const k = fn;
const _fn = typeof input[k] === "function" ? input[k].bind(options.eventContext) : null;
input[k] = (e) => {
syncStatus(fn === "onload" ? "loaded" : fn === "onerror" ? "error" : "loading");
_fn?.(e);
};
});
const _cbs = { loaded: [], error: [] };
const _uniqueCbs = /* @__PURE__ */ new Set();
const _registerCb = (key, cb, options2) => {
if (head.ssr) {
return;
}
if (options2?.key) {
const key2 = `${options2?.key}:${options2.key}`;
if (_uniqueCbs.has(key2)) {
return;
}
_uniqueCbs.add(key2);
}
if (_cbs[key]) {
const i = _cbs[key].push(cb);
return () => _cbs[key]?.splice(i - 1, 1);
}
cb(script.instance);
return () => {
};
};
const loadPromise = new Promise((resolve) => {
if (head.ssr)
return;
const emit = (api) => requestAnimationFrame(() => resolve(api));
const _ = head.hooks.hook("script:updated", ({ script: script2 }) => {
const status = script2.status;
if (script2.id === id && (status === "loaded" || status === "error")) {
if (status === "loaded") {
if (typeof options.use === "function") {
const api = options.use();
if (api) {
emit(api);
}
} else {
emit({});
}
} else if (status === "error") {
resolve(false);
}
_();
}
});
});
const script = {
_loadPromise: loadPromise,
instance: !head.ssr && options?.use?.() || null,
proxy: null,
id,
status: "awaitingLoad",
remove() {
script._triggerAbortController?.abort();
script._triggerPromises = [];
script._warmupEl?.dispose();
if (script.entry) {
script.entry.dispose();
script.entry = void 0;
syncStatus("removed");
delete head._scripts?.[id];
return true;
}
return false;
},
warmup(rel) {
const { src } = input;
const isCrossOrigin = !src.startsWith("/") || src.startsWith("//");
const isPreconnect = rel && PreconnectServerModes.includes(rel);
let href = src;
if (!rel || isPreconnect && !isCrossOrigin) {
return;
}
if (isPreconnect) {
const $url = new URL(src);
href = `${$url.protocol}//${$url.host}`;
}
const link = {
href,
rel,
crossorigin: typeof input.crossorigin !== "undefined" ? input.crossorigin : isCrossOrigin ? "anonymous" : void 0,
referrerpolicy: typeof input.referrerpolicy !== "undefined" ? input.referrerpolicy : isCrossOrigin ? "no-referrer" : void 0,
fetchpriority: typeof input.fetchpriority !== "undefined" ? input.fetchpriority : "low",
integrity: input.integrity,
as: rel === "preload" ? "script" : void 0
};
script._warmupEl = head.push({ link: [link] }, { head, tagPriority: "high" });
return script._warmupEl;
},
load(cb) {
script._triggerAbortController?.abort();
script._triggerPromises = [];
if (!script.entry) {
syncStatus("loading");
const defaults = {
defer: true,
fetchpriority: "low"
};
if (input.src && (input.src.startsWith("http") || input.src.startsWith("//"))) {
defaults.crossorigin = "anonymous";
defaults.referrerpolicy = "no-referrer";
}
script.entry = head.push({
script: [{ ...defaults, ...input }]
}, options);
}
if (cb)
_registerCb("loaded", cb);
return loadPromise;
},
onLoaded(cb, options2) {
return _registerCb("loaded", cb, options2);
},
onError(cb, options2) {
return _registerCb("error", cb, options2);
},
setupTriggerHandler(trigger) {
if (script.status !== "awaitingLoad") {
return;
}
if ((typeof trigger === "undefined" || trigger === "client") && !head.ssr || trigger === "server") {
script.load();
} else if (trigger instanceof Promise) {
if (head.ssr) {
return;
}
if (!script._triggerAbortController) {
script._triggerAbortController = new AbortController();
script._triggerAbortPromise = new Promise((resolve) => {
script._triggerAbortController.signal.addEventListener("abort", () => {
script._triggerAbortController = null;
resolve();
});
});
}
script._triggerPromises = script._triggerPromises || [];
const idx = script._triggerPromises.push(Promise.race([
trigger.then((v) => typeof v === "undefined" || v ? script.load : void 0),
script._triggerAbortPromise
]).catch(() => {
}).then((res) => {
res?.();
}).finally(() => {
script._triggerPromises?.splice(idx, 1);
}));
} else if (typeof trigger === "function") {
trigger(script.load);
}
},
_cbs
};
loadPromise.then((api) => {
if (api !== false) {
script.instance = api;
_cbs.loaded?.forEach((cb) => cb(api));
_cbs.loaded = null;
} else {
_cbs.error?.forEach((cb) => cb());
_cbs.error = null;
}
});
const hookCtx = { script };
script.setupTriggerHandler(options.trigger);
if (options.use) {
const { proxy, stack } = createNoopedRecordingProxy(head.ssr ? {} : options.use() || {});
script.proxy = proxy;
script.onLoaded((instance) => {
replayProxyRecordings(instance, stack);
script.proxy = createForwardingProxy(instance);
});
}
if (!options.warmupStrategy && (typeof options.trigger === "undefined" || options.trigger === "client")) {
options.warmupStrategy = "preload";
}
if (options.warmupStrategy) {
script.warmup(options.warmupStrategy);
}
head._scripts = Object.assign(head._scripts || {}, { [id]: script });
return script;
}
export { resolveScriptKey as r, useScript as u };

View File

@@ -0,0 +1,44 @@
import { S as SafeInputPlugin, F as FlatMetaPlugin } from './unhead.CApf5sj3.mjs';
function useHead(unhead, input, options = {}) {
return unhead.push(input || {}, options);
}
function useHeadSafe(unhead, input = {}, options = {}) {
unhead.use(SafeInputPlugin);
return useHead(unhead, input, Object.assign(options, { _safe: true }));
}
function useSeoMeta(unhead, input = {}, options) {
unhead.use(FlatMetaPlugin);
function normalize(input2) {
if (input2._flatMeta) {
return input2;
}
const { title, titleTemplate, ...meta } = input2 || {};
return {
title,
titleTemplate,
_flatMeta: meta
};
}
const entry = unhead.push(normalize(input), options);
const corePatch = entry.patch;
if (!entry.__patched) {
entry.patch = (input2) => corePatch(normalize(input2));
entry.__patched = true;
}
return entry;
}
function useServerHead(unhead, input = {}, options = {}) {
options.mode = "server";
return unhead.push(input, options);
}
function useServerHeadSafe(unhead, input = {}, options = {}) {
options.mode = "server";
return useHeadSafe(unhead, input, { ...options, mode: "server" });
}
function useServerSeoMeta(unhead, input = {}, options) {
options.mode = "server";
return useSeoMeta(unhead, input, { ...options, mode: "server" });
}
export { useHeadSafe as a, useSeoMeta as b, useServerHead as c, useServerHeadSafe as d, useServerSeoMeta as e, useHead as u };

View File

@@ -0,0 +1,177 @@
import { U as UniqueTags, T as TagsWithInnerContent, M as MetaTagsArrayable, a as TagConfigKeys, D as DupeableTags } from './unhead.yem5I2v_.mjs';
const allowedMetaProperties = ["name", "property", "http-equiv"];
function isMetaArrayDupeKey(v) {
const k = v.split(":")[1];
return MetaTagsArrayable.has(k);
}
function dedupeKey(tag) {
const { props, tag: name } = tag;
if (UniqueTags.has(name))
return name;
if (name === "link" && props.rel === "canonical")
return "canonical";
if (props.charset)
return "charset";
if (tag.tag === "meta") {
for (const n of allowedMetaProperties) {
if (props[n] !== void 0) {
return `${name}:${props[n]}`;
}
}
}
if (tag.key) {
return `${name}:key:${tag.key}`;
}
if (props.id) {
return `${name}:id:${props.id}`;
}
if (TagsWithInnerContent.has(name)) {
const v = tag.textContent || tag.innerHTML;
if (v) {
return `${name}:content:${v}`;
}
}
}
function hashTag(tag) {
const dedupe = tag._h || tag._d;
if (dedupe)
return dedupe;
const inner = tag.textContent || tag.innerHTML;
if (inner)
return inner;
return `${tag.tag}:${Object.entries(tag.props).map(([k, v]) => `${k}:${String(v)}`).join(",")}`;
}
function walkResolver(val, resolve, key) {
const type = typeof val;
if (type === "function") {
if (!key || key !== "titleTemplate" && !(key[0] === "o" && key[1] === "n")) {
val = val();
}
}
let v;
if (resolve) {
v = resolve(key, val);
}
if (Array.isArray(v)) {
return v.map((r) => walkResolver(r, resolve));
}
if (v?.constructor === Object) {
const next = {};
for (const key2 of Object.keys(v)) {
next[key2] = walkResolver(v[key2], resolve, key2);
}
return next;
}
return v;
}
function normalizeStyleClassProps(key, value) {
const store = key === "style" ? /* @__PURE__ */ new Map() : /* @__PURE__ */ new Set();
function processValue(rawValue) {
const value2 = rawValue.trim();
if (!value2)
return;
if (key === "style") {
const [k, ...v] = value2.split(":").map((s) => s.trim());
if (k && v.length)
store.set(k, v.join(":"));
} else {
value2.split(" ").filter(Boolean).forEach((c) => store.add(c));
}
}
if (typeof value === "string") {
key === "style" ? value.split(";").forEach(processValue) : processValue(value);
} else if (Array.isArray(value)) {
value.forEach((item) => processValue(item));
} else if (value && typeof value === "object") {
Object.entries(value).forEach(([k, v]) => {
if (v && v !== "false") {
key === "style" ? store.set(k.trim(), v) : processValue(k);
}
});
}
return store;
}
function normalizeProps(tag, input) {
tag.props = tag.props || {};
if (!input) {
return tag;
}
Object.entries(input).forEach(([key, value]) => {
if (value === null) {
tag.props[key] = null;
return;
}
if (key === "class" || key === "style") {
tag.props[key] = normalizeStyleClassProps(key, value);
return;
}
if (TagConfigKeys.has(key)) {
if (["textContent", "innerHTML"].includes(key) && typeof value === "object") {
let type = input.type;
if (!input.type) {
type = "application/json";
}
if (!type?.endsWith("json") && type !== "speculationrules") {
return;
}
input.type = type;
tag.props.type = type;
tag[key] = JSON.stringify(value);
} else {
tag[key] = value;
}
return;
}
const strValue = String(value);
const isDataKey = key.startsWith("data-");
if (strValue === "true" || strValue === "") {
tag.props[key] = isDataKey ? "true" : true;
} else if (!value && isDataKey && strValue === "false") {
tag.props[key] = "false";
} else if (value !== void 0) {
tag.props[key] = value;
}
});
return tag;
}
function normalizeTag(tagName, _input) {
const input = typeof _input === "object" && typeof _input !== "function" ? _input : { [tagName === "script" || tagName === "noscript" || tagName === "style" ? "innerHTML" : "textContent"]: _input };
const tag = normalizeProps({ tag: tagName, props: {} }, input);
if (tag.key && DupeableTags.has(tag.tag)) {
tag.props["data-hid"] = tag._h = tag.key;
}
if (tag.tag === "script" && typeof tag.innerHTML === "object") {
tag.innerHTML = JSON.stringify(tag.innerHTML);
tag.props.type = tag.props.type || "application/json";
}
return Array.isArray(tag.props.content) ? tag.props.content.map((v) => ({ ...tag, props: { ...tag.props, content: v } })) : tag;
}
function normalizeEntryToTags(input, propResolvers) {
if (!input) {
return [];
}
if (typeof input === "function") {
input = input();
}
const resolvers = (key, val) => {
for (let i = 0; i < propResolvers.length; i++) {
val = propResolvers[i](key, val);
}
return val;
};
input = resolvers(void 0, input);
const tags = [];
input = walkResolver(input, resolvers);
Object.entries(input || {}).forEach(([key, value]) => {
if (value === void 0)
return;
for (const v of Array.isArray(value) ? value : [value])
tags.push(normalizeTag(key, v));
});
return tags.flat();
}
export { normalizeProps as a, dedupeKey as d, hashTag as h, isMetaArrayDupeKey as i, normalizeEntryToTags as n, walkResolver as w };

View File

@@ -0,0 +1,148 @@
import { u as unpackMeta } from './unhead.DQc16pHI.mjs';
function defineHeadPlugin(plugin) {
return plugin;
}
const FlatMetaPlugin = /* @__PURE__ */ defineHeadPlugin({
key: "flatMeta",
hooks: {
"entries:normalize": (ctx) => {
const tagsToAdd = [];
ctx.tags = ctx.tags.map((t) => {
if (t.tag !== "_flatMeta") {
return t;
}
tagsToAdd.push(unpackMeta(t.props).map((p) => ({
...t,
tag: "meta",
props: p
})));
return false;
}).filter(Boolean).concat(...tagsToAdd);
}
}
});
const WhitelistAttributes = {
htmlAttrs: /* @__PURE__ */ new Set(["class", "style", "lang", "dir"]),
bodyAttrs: /* @__PURE__ */ new Set(["class", "style"]),
meta: /* @__PURE__ */ new Set(["name", "property", "charset", "content", "media"]),
noscript: /* @__PURE__ */ new Set(["textContent"]),
style: /* @__PURE__ */ new Set(["media", "textContent", "nonce", "title", "blocking"]),
script: /* @__PURE__ */ new Set(["type", "textContent", "nonce", "blocking"]),
link: /* @__PURE__ */ new Set(["color", "crossorigin", "fetchpriority", "href", "hreflang", "imagesrcset", "imagesizes", "integrity", "media", "referrerpolicy", "rel", "sizes", "type"])
};
function acceptDataAttrs(value) {
return Object.fromEntries(
Object.entries(value || {}).filter(([key]) => key === "id" || key.startsWith("data-"))
);
}
function makeTagSafe(tag) {
let next = {};
const { tag: type, props: prev } = tag;
switch (type) {
// always safe
case "title":
case "titleTemplate":
case "templateParams":
next = prev;
break;
case "htmlAttrs":
case "bodyAttrs":
WhitelistAttributes[type].forEach((attr) => {
if (prev[attr]) {
next[attr] = prev[attr];
}
});
break;
case "style":
next = acceptDataAttrs(prev);
WhitelistAttributes.style.forEach((key) => {
if (prev[key]) {
next[key] = prev[key];
}
});
break;
// meta is safe, except for http-equiv
case "meta":
WhitelistAttributes.meta.forEach((key) => {
if (prev[key]) {
next[key] = prev[key];
}
});
break;
// link tags we don't allow stylesheets, scripts, preloading, prerendering, prefetching, etc
case "link":
WhitelistAttributes.link.forEach((key) => {
const val = prev[key];
if (!val) {
return;
}
if (key === "rel" && (val === "canonical" || val === "modulepreload" || val === "prerender" || val === "preload" || val === "prefetch")) {
return;
}
if (key === "href") {
if (val.includes("javascript:") || val.includes("data:")) {
return;
}
next[key] = val;
} else if (val) {
next[key] = val;
}
});
if (!next.href && !next.imagesrcset || !next.rel) {
return false;
}
break;
case "noscript":
WhitelistAttributes.noscript.forEach((key) => {
if (prev[key]) {
next[key] = prev[key];
}
});
break;
// we only allow JSON in scripts
case "script":
if (!tag.textContent || !prev.type?.endsWith("json")) {
return false;
}
WhitelistAttributes.script.forEach((s) => {
if (prev[s] === "textContent") {
try {
const jsonVal = typeof prev[s] === "string" ? JSON.parse(prev[s]) : prev[s];
next[s] = JSON.stringify(jsonVal, null, 0);
} catch {
}
} else if (prev[s]) {
next[s] = prev[s];
}
});
break;
}
if (!Object.keys(next).length && !tag.tag.endsWith("Attrs")) {
return false;
}
tag.props = { ...acceptDataAttrs(prev), ...next };
return tag;
}
const SafeInputPlugin = (
/* @PURE */
defineHeadPlugin({
key: "safe",
hooks: {
"entries:normalize": (ctx) => {
if (ctx.entry.options?._safe) {
ctx.tags = ctx.tags.reduce((acc, tag) => {
const safeTag = makeTagSafe(tag);
if (safeTag)
acc.push(safeTag);
return acc;
}, []);
}
}
}
})
);
export { FlatMetaPlugin as F, SafeInputPlugin as S, defineHeadPlugin as d };

View File

@@ -0,0 +1,196 @@
import { M as MetaTagsArrayable } from './unhead.yem5I2v_.mjs';
const NAMESPACES = {
META: /* @__PURE__ */ new Set(["twitter"]),
OG: /* @__PURE__ */ new Set(["og", "book", "article", "profile", "fb"]),
MEDIA: /* @__PURE__ */ new Set(["ogImage", "ogVideo", "ogAudio", "twitterImage"]),
HTTP_EQUIV: /* @__PURE__ */ new Set(["contentType", "defaultStyle", "xUaCompatible"])
};
const META_ALIASES = {
articleExpirationTime: "article:expiration_time",
articleModifiedTime: "article:modified_time",
articlePublishedTime: "article:published_time",
bookReleaseDate: "book:release_date",
fbAppId: "fb:app_id",
ogAudioSecureUrl: "og:audio:secure_url",
ogAudioUrl: "og:audio",
ogImageSecureUrl: "og:image:secure_url",
ogImageUrl: "og:image",
ogSiteName: "og:site_name",
ogVideoSecureUrl: "og:video:secure_url",
ogVideoUrl: "og:video",
profileFirstName: "profile:first_name",
profileLastName: "profile:last_name",
profileUsername: "profile:username",
msapplicationConfig: "msapplication-Config",
msapplicationTileColor: "msapplication-TileColor",
msapplicationTileImage: "msapplication-TileImage"
};
const MetaPackingSchema = {
appleItunesApp: {
unpack: {
entrySeparator: ", ",
// @ts-expect-error untyped
resolve: ({ key, value }) => `${fixKeyCase(key)}=${value}`
}
},
refresh: {
metaKey: "http-equiv",
unpack: {
entrySeparator: ";",
// @ts-expect-error untyped
resolve: ({ key, value }) => key === "seconds" ? `${value}` : void 0
}
},
robots: {
unpack: {
entrySeparator: ", ",
// @ts-expect-error untyped
resolve: ({ key, value }) => typeof value === "boolean" ? fixKeyCase(key) : `${fixKeyCase(key)}:${value}`
}
},
contentSecurityPolicy: {
metaKey: "http-equiv",
unpack: {
entrySeparator: "; ",
// @ts-expect-error untyped
resolve: ({ key, value }) => `${fixKeyCase(key)} ${value}`
}
},
charset: {}
};
function fixKeyCase(key) {
const updated = key.replace(/([A-Z])/g, "-$1").toLowerCase();
const prefixIndex = updated.indexOf("-");
return prefixIndex === -1 ? updated : NAMESPACES.META.has(updated.slice(0, prefixIndex)) || NAMESPACES.OG.has(updated.slice(0, prefixIndex)) ? key.replace(/([A-Z])/g, ":$1").toLowerCase() : updated;
}
function sanitizeObject(input) {
return Object.fromEntries(Object.entries(input).filter(([k, v]) => String(v) !== "false" && k));
}
function transformObject(obj) {
return Array.isArray(obj) ? obj.map(transformObject) : !obj || typeof obj !== "object" ? obj : Object.fromEntries(Object.entries(obj).map(([k, v]) => [fixKeyCase(k), transformObject(v)]));
}
function unpackToString(value, options = {}) {
const { entrySeparator = "", keyValueSeparator = "", wrapValue, resolve } = options;
return Object.entries(value).map(([key, val]) => {
if (resolve) {
const resolved = resolve({ key, value: val });
if (resolved !== void 0)
return resolved;
}
const processedVal = typeof val === "object" ? unpackToString(val, options) : typeof val === "number" ? val.toString() : typeof val === "string" && wrapValue ? `${wrapValue}${val.replace(new RegExp(wrapValue, "g"), `\\${wrapValue}`)}${wrapValue}` : val;
return `${key}${keyValueSeparator}${processedVal}`;
}).join(entrySeparator);
}
function handleObjectEntry(key, value) {
const sanitizedValue = sanitizeObject(value);
const fixedKey = fixKeyCase(key);
const attr = resolveMetaKeyType(fixedKey);
if (!MetaTagsArrayable.has(fixedKey)) {
return [{ [attr]: fixedKey, ...sanitizedValue }];
}
const input = Object.fromEntries(
Object.entries(sanitizedValue).map(([k, v]) => [`${key}${k === "url" ? "" : `${k[0].toUpperCase()}${k.slice(1)}`}`, v])
);
return unpackMeta(input || {}).sort((a, b) => (a[attr]?.length || 0) - (b[attr]?.length || 0));
}
function resolveMetaKeyType(key) {
if (MetaPackingSchema[key]?.metaKey === "http-equiv" || NAMESPACES.HTTP_EQUIV.has(key)) {
return "http-equiv";
}
const fixed = fixKeyCase(key);
const colonIndex = fixed.indexOf(":");
return colonIndex === -1 ? "name" : NAMESPACES.OG.has(fixed.slice(0, colonIndex)) ? "property" : "name";
}
function resolveMetaKeyValue(key) {
return META_ALIASES[key] || fixKeyCase(key);
}
function resolvePackedMetaObjectValue(value, key) {
if (key === "refresh")
return `${value.seconds};url=${value.url}`;
return unpackToString(transformObject(value), {
keyValueSeparator: "=",
entrySeparator: ", ",
resolve: ({ value: value2, key: key2 }) => value2 === null ? "" : typeof value2 === "boolean" ? key2 : void 0,
// @ts-expect-error untyped
...MetaPackingSchema[key]?.unpack
});
}
function unpackMeta(input) {
const extras = [];
const primitives = {};
for (const [key, value] of Object.entries(input)) {
if (Array.isArray(value)) {
if (key === "themeColor") {
value.forEach((v) => {
if (typeof v === "object" && v !== null) {
extras.push({ name: "theme-color", ...v });
}
});
continue;
}
for (const v of value) {
if (typeof v === "object" && v !== null) {
const urlProps = [];
const otherProps = [];
for (const [propKey, propValue] of Object.entries(v)) {
const metaKey = `${key}${propKey === "url" ? "" : `:${propKey}`}`;
const meta2 = unpackMeta({ [metaKey]: propValue });
(propKey === "url" ? urlProps : otherProps).push(...meta2);
}
extras.push(...urlProps, ...otherProps);
} else {
extras.push(...typeof v === "string" ? unpackMeta({ [key]: v }) : handleObjectEntry(key, v));
}
}
continue;
}
if (typeof value === "object" && value) {
if (NAMESPACES.MEDIA.has(key)) {
const prefix = key.startsWith("twitter") ? "twitter" : "og";
const type = key.replace(/^(og|twitter)/, "").toLowerCase();
const metaKey = prefix === "twitter" ? "name" : "property";
if (value.url) {
extras.push({
[metaKey]: `${prefix}:${type}`,
content: value.url
});
}
if (value.secureUrl) {
extras.push({
[metaKey]: `${prefix}:${type}:secure_url`,
content: value.secureUrl
});
}
for (const [propKey, propValue] of Object.entries(value)) {
if (propKey !== "url" && propKey !== "secureUrl") {
extras.push({
[metaKey]: `${prefix}:${type}:${propKey}`,
// @ts-expect-error untyped
content: propValue
});
}
}
} else if (MetaTagsArrayable.has(fixKeyCase(key))) {
extras.push(...handleObjectEntry(key, value));
} else {
primitives[key] = sanitizeObject(value);
}
} else {
primitives[key] = value;
}
}
const meta = Object.entries(primitives).map(([key, value]) => {
if (key === "charset")
return { charset: value === null ? "_null" : value };
const metaKey = resolveMetaKeyType(key);
const keyValue = resolveMetaKeyValue(key);
const processedValue = value === null ? "_null" : typeof value === "object" ? resolvePackedMetaObjectValue(value, key) : typeof value === "number" ? value.toString() : value;
return metaKey === "http-equiv" ? { "http-equiv": keyValue, "content": processedValue } : { [metaKey]: keyValue, content: processedValue };
});
return [...extras, ...meta].map(
(m) => !("content" in m) ? m : m.content === "_null" ? { ...m, content: null } : m
);
}
export { resolveMetaKeyValue as a, resolvePackedMetaObjectValue as b, resolveMetaKeyType as r, unpackMeta as u };

View File

@@ -0,0 +1,70 @@
const sortTags = (a, b) => a._w === b._w ? a._p - b._p : a._w - b._w;
const TAG_WEIGHTS = {
base: -10,
title: 10
};
const TAG_ALIASES = {
critical: -8,
high: -1,
low: 2
};
const WEIGHT_MAP = {
meta: {
"content-security-policy": -30,
"charset": -20,
"viewport": -15
},
link: {
"preconnect": 20,
"stylesheet": 60,
"preload": 70,
"modulepreload": 70,
"prefetch": 90,
"dns-prefetch": 90,
"prerender": 90
},
script: {
async: 30,
defer: 80,
sync: 50
},
style: {
imported: 40,
sync: 60
}
};
const ImportStyleRe = /@import/;
const isTruthy = (val) => val === "" || val === true;
function tagWeight(head, tag) {
if (typeof tag.tagPriority === "number")
return tag.tagPriority;
let weight = 100;
const offset = TAG_ALIASES[tag.tagPriority] || 0;
const weightMap = head.resolvedOptions.disableCapoSorting ? {
link: {},
script: {},
style: {}
} : WEIGHT_MAP;
if (tag.tag in TAG_WEIGHTS) {
weight = TAG_WEIGHTS[tag.tag];
} else if (tag.tag === "meta") {
const metaType = tag.props["http-equiv"] === "content-security-policy" ? "content-security-policy" : tag.props.charset ? "charset" : tag.props.name === "viewport" ? "viewport" : null;
if (metaType)
weight = WEIGHT_MAP.meta[metaType];
} else if (tag.tag === "link" && tag.props.rel) {
weight = weightMap.link[tag.props.rel];
} else if (tag.tag === "script") {
if (isTruthy(tag.props.async)) {
weight = weightMap.script.async;
} else if (tag.props.src && !isTruthy(tag.props.defer) && !isTruthy(tag.props.async) && tag.props.type !== "module" && !tag.props.type?.endsWith("json")) {
weight = weightMap.script.sync;
} else if (isTruthy(tag.props.defer) && tag.props.src && !isTruthy(tag.props.async)) {
weight = weightMap.script.defer;
}
} else if (tag.tag === "style") {
weight = tag.innerHTML && ImportStyleRe.test(tag.innerHTML) ? weightMap.style.imported : weightMap.style.sync;
}
return (weight || 100) + offset;
}
export { sortTags as s, tagWeight as t };

View File

@@ -0,0 +1,155 @@
import { d as defineHeadPlugin } from './unhead.CApf5sj3.mjs';
import { s as sortTags } from './unhead.DZbvapt-.mjs';
import { p as processTemplateParams } from './unhead.kVuXtrDW.mjs';
const formatKey = (k) => !k.includes(":key") ? k.split(":").join(":key:") : k;
const AliasSortingPlugin = defineHeadPlugin({
key: "aliasSorting",
hooks: {
"tags:resolve": (ctx) => {
let m = false;
for (const t of ctx.tags) {
const p = t.tagPriority;
if (!p)
continue;
const s = String(p);
if (s.startsWith("before:")) {
const k = formatKey(s.slice(7));
const l = ctx.tagMap.get(k);
if (l) {
if (typeof l.tagPriority === "number")
t.tagPriority = l.tagPriority;
t._p = l._p - 1;
m = true;
}
} else if (s.startsWith("after:")) {
const k = formatKey(s.slice(6));
const l = ctx.tagMap.get(k);
if (l) {
if (typeof l.tagPriority === "number")
t.tagPriority = l.tagPriority;
t._p = l._p + 1;
m = true;
}
}
}
if (m)
ctx.tags = ctx.tags.sort(sortTags);
}
}
});
const DeprecationsPlugin = /* @__PURE__ */ defineHeadPlugin({
key: "deprecations",
hooks: {
"entries:normalize": ({ tags }) => {
for (const tag of tags) {
if (tag.props.children) {
tag.innerHTML = tag.props.children;
delete tag.props.children;
}
if (tag.props.hid) {
tag.key = tag.props.hid;
delete tag.props.hid;
}
if (tag.props.vmid) {
tag.key = tag.props.vmid;
delete tag.props.vmid;
}
if (tag.props.body) {
tag.tagPosition = "bodyClose";
delete tag.props.body;
}
}
}
}
});
async function walkPromises(v) {
const type = typeof v;
if (type === "function") {
return v;
}
if (v instanceof Promise) {
return await v;
}
if (Array.isArray(v)) {
return await Promise.all(v.map((r) => walkPromises(r)));
}
if (v?.constructor === Object) {
const next = {};
for (const key of Object.keys(v)) {
next[key] = await walkPromises(v[key]);
}
return next;
}
return v;
}
const PromisesPlugin = /* @__PURE__ */ defineHeadPlugin({
key: "promises",
hooks: {
"entries:resolve": async (ctx) => {
const promises = [];
for (const k in ctx.entries) {
if (!ctx.entries[k]._promisesProcessed) {
promises.push(
walkPromises(ctx.entries[k].input).then((val) => {
ctx.entries[k].input = val;
ctx.entries[k]._promisesProcessed = true;
})
);
}
}
await Promise.all(promises);
}
}
});
const SupportedAttrs = {
meta: "content",
link: "href",
htmlAttrs: "lang"
};
const contentAttrs = ["innerHTML", "textContent"];
const TemplateParamsPlugin = /* @__PURE__ */ defineHeadPlugin((head) => {
return {
key: "template-params",
hooks: {
"tags:resolve": ({ tagMap, tags }) => {
const params = tagMap.get("templateParams")?.props || {};
const sep = params.separator || "|";
delete params.separator;
params.pageTitle = processTemplateParams(
// find templateParams
params.pageTitle || head._title || "",
params,
sep
);
for (const tag of tags) {
if (tag.processTemplateParams === false) {
continue;
}
const v = SupportedAttrs[tag.tag];
if (v && typeof tag.props[v] === "string") {
tag.props[v] = processTemplateParams(tag.props[v], params, sep);
} else if (tag.processTemplateParams || tag.tag === "titleTemplate" || tag.tag === "title") {
for (const p of contentAttrs) {
if (typeof tag[p] === "string")
tag[p] = processTemplateParams(tag[p], params, sep, tag.tag === "script" && tag.props.type.endsWith("json"));
}
}
}
head._templateParams = params;
head._separator = sep;
},
"tags:afterResolve": ({ tagMap }) => {
const title = tagMap.get("title");
if (title?.textContent && title.processTemplateParams !== false) {
title.textContent = processTemplateParams(title.textContent, head._templateParams, head._separator);
}
}
}
};
});
export { AliasSortingPlugin as A, DeprecationsPlugin as D, PromisesPlugin as P, TemplateParamsPlugin as T };

View File

@@ -0,0 +1,48 @@
const SepSub = "%separator";
const SepSubRE = new RegExp(`${SepSub}(?:\\s*${SepSub})*`, "g");
function sub(p, token, isJson = false) {
let val;
if (token === "s" || token === "pageTitle") {
val = p.pageTitle;
} else if (token.includes(".")) {
const dotIndex = token.indexOf(".");
val = p[token.substring(0, dotIndex)]?.[token.substring(dotIndex + 1)];
} else {
val = p[token];
}
if (val !== void 0) {
return isJson ? (val || "").replace(/</g, "\\u003C").replace(/"/g, '\\"') : val || "";
}
return void 0;
}
function processTemplateParams(s, p, sep, isJson = false) {
if (typeof s !== "string" || !s.includes("%"))
return s;
let decoded = s;
try {
decoded = decodeURI(s);
} catch {
}
const tokens = decoded.match(/%\w+(?:\.\w+)?/g);
if (!tokens) {
return s;
}
const hasSepSub = s.includes(SepSub);
s = s.replace(/%\w+(?:\.\w+)?/g, (token) => {
if (token === SepSub || !tokens.includes(token)) {
return token;
}
const re = sub(p, token.slice(1), isJson);
return re !== void 0 ? re : token;
}).trim();
if (hasSepSub) {
if (s.endsWith(SepSub))
s = s.slice(0, -SepSub.length);
if (s.startsWith(SepSub))
s = s.slice(SepSub.length);
s = s.replace(SepSubRE, sep || "").trim();
}
return s;
}
export { processTemplateParams as p };

View File

@@ -0,0 +1,38 @@
const SelfClosingTags = /* @__PURE__ */ new Set(["meta", "link", "base"]);
const DupeableTags = /* @__PURE__ */ new Set(["link", "style", "script", "noscript"]);
const TagsWithInnerContent = /* @__PURE__ */ new Set(["title", "titleTemplate", "script", "style", "noscript"]);
const HasElementTags = /* @__PURE__ */ new Set([
"base",
"meta",
"link",
"style",
"script",
"noscript"
]);
const ValidHeadTags = /* @__PURE__ */ new Set([
"title",
"base",
"htmlAttrs",
"bodyAttrs",
"meta",
"link",
"style",
"script",
"noscript"
]);
const UniqueTags = /* @__PURE__ */ new Set(["base", "title", "titleTemplate", "bodyAttrs", "htmlAttrs", "templateParams"]);
const TagConfigKeys = /* @__PURE__ */ new Set(["key", "tagPosition", "tagPriority", "tagDuplicateStrategy", "innerHTML", "textContent", "processTemplateParams"]);
const ScriptNetworkEvents = /* @__PURE__ */ new Set(["onload", "onerror"]);
const UsesMergeStrategy = /* @__PURE__ */ new Set(["templateParams", "htmlAttrs", "bodyAttrs"]);
const MetaTagsArrayable = /* @__PURE__ */ new Set([
"theme-color",
"google-site-verification",
"og",
"article",
"book",
"profile",
"twitter",
"author"
]);
export { DupeableTags as D, HasElementTags as H, MetaTagsArrayable as M, SelfClosingTags as S, TagsWithInnerContent as T, UniqueTags as U, ValidHeadTags as V, TagConfigKeys as a, ScriptNetworkEvents as b, UsesMergeStrategy as c };

5
.output/server/node_modules/unhead/dist/utils.mjs generated vendored Normal file
View File

@@ -0,0 +1,5 @@
export { D as DupeableTags, H as HasElementTags, M as MetaTagsArrayable, b as ScriptNetworkEvents, S as SelfClosingTags, a as TagConfigKeys, T as TagsWithInnerContent, U as UniqueTags, c as UsesMergeStrategy, V as ValidHeadTags } from './shared/unhead.yem5I2v_.mjs';
export { d as dedupeKey, h as hashTag, i as isMetaArrayDupeKey, n as normalizeEntryToTags, a as normalizeProps, w as walkResolver } from './shared/unhead.BaPU1zLf.mjs';
export { r as resolveMetaKeyType, a as resolveMetaKeyValue, b as resolvePackedMetaObjectValue, u as unpackMeta } from './shared/unhead.DQc16pHI.mjs';
export { s as sortTags, t as tagWeight } from './shared/unhead.DZbvapt-.mjs';
export { p as processTemplateParams } from './shared/unhead.kVuXtrDW.mjs';

View File

@@ -1,8 +1,17 @@
{
"name": "unhead",
"type": "module",
"version": "1.8.8",
"author": "Harlan Wilton <harlan@harlanzw.com>",
"version": "2.0.0-rc.10",
"description": "Full-stack <head> manager built for any framework.",
"author": {
"name": "Harlan Wilton",
"email": "harlan@harlanzw.com",
"url": "https://harlanzw.com/"
},
"publishConfig": {
"access": "public",
"tag": "next"
},
"license": "MIT",
"funding": "https://github.com/sponsors/harlan-zw",
"homepage": "https://unhead.unjs.io",
@@ -18,25 +27,78 @@
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
"default": "./dist/index.mjs"
},
"./plugins": {
"types": "./dist/plugins.d.ts",
"default": "./dist/plugins.mjs"
},
"./server": {
"types": "./dist/server.d.ts",
"default": "./dist/server.mjs"
},
"./client": {
"types": "./dist/client.d.ts",
"default": "./dist/client.mjs"
},
"./legacy": {
"types": "./dist/legacy.d.ts",
"default": "./dist/legacy.mjs"
},
"./utils": {
"types": "./dist/utils.d.ts",
"default": "./dist/utils.mjs"
},
"./types": {
"types": "./dist/types.d.ts",
"default": "./dist/types.mjs"
},
"./scripts": {
"types": "./dist/scripts.d.ts",
"default": "./dist/scripts.mjs"
}
},
"main": "dist/index.cjs",
"main": "dist/index.mjs",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"optionalPlugins": {
"*": {
"plugins": [
"dist/plugins"
],
"server": [
"dist/server"
],
"client": [
"dist/client"
],
"legacy": [
"dist/legacy"
],
"types": [
"dist/types"
],
"utils": [
"dist/utils"
],
"scripts": [
"dist/scripts"
]
}
},
"files": [
"*.d.ts",
"dist"
],
"dependencies": {
"hookable": "^5.5.3",
"@unhead/shared": "1.8.8",
"@unhead/schema": "1.8.8",
"@unhead/dom": "1.8.8"
"hookable": "^5.5.3"
},
"scripts": {
"build": "unbuild .",
"stub": "unbuild . --stub",
"export:sizes": "npx export-size . -r"
}
"build": "unbuild",
"stub": "unbuild --stub",
"test:attw": "attw --pack"
},
"__npminstall_done": true,
"_from": "unhead@2.0.0-rc.10",
"_resolved": "https://registry.npmmirror.com/unhead/-/unhead-2.0.0-rc.10.tgz"
}