diff --git a/.gitignore b/.gitignore index 307bb5e..016ca54 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ .nuxt .nitro .cache -dist +/dist # Node dependencies /node_modules diff --git a/.output/server/node_modules/@unhead/dom/dist/index.mjs b/.output/server/node_modules/@unhead/dom/dist/index.mjs new file mode 100644 index 0000000..5fd97f6 --- /dev/null +++ b/.output/server/node_modules/@unhead/dom/dist/index.mjs @@ -0,0 +1,133 @@ +import { HasElementTags, hashTag, normaliseProps, tagDedupeKey, defineHeadPlugin } from '@unhead/shared'; + +async function elementToTag($el) { + const tag = { + tag: $el.tagName.toLowerCase(), + props: await normaliseProps( + $el.getAttributeNames().reduce((props, name) => ({ ...props, [name]: $el.getAttribute(name) }), {}) + ), + innerHTML: $el.innerHTML + }; + tag._d = tagDedupeKey(tag); + return tag; +} +async function renderDOMHead(head, options = {}) { + const dom = options.document || head.resolvedOptions.document; + if (!dom) + return; + const beforeRenderCtx = { shouldRender: head.dirty, tags: [] }; + await head.hooks.callHook("dom:beforeRender", beforeRenderCtx); + if (!beforeRenderCtx.shouldRender) + return; + const tags = (await head.resolveTags()).map((tag) => ({ + tag, + id: HasElementTags.includes(tag.tag) ? hashTag(tag) : tag.tag, + shouldRender: true + })); + let state = head._dom; + if (!state) { + state = { + elMap: { htmlAttrs: dom.documentElement, bodyAttrs: dom.body } + }; + for (const key of ["body", "head"]) { + const children = dom?.[key]?.children; + for (const c of [...children].filter((c2) => HasElementTags.includes(c2.tagName.toLowerCase()))) + state.elMap[c.getAttribute("data-hid") || hashTag(await elementToTag(c))] = c; + } + } + state.pendingSideEffects = { ...state.sideEffects || {} }; + state.sideEffects = {}; + function track(id, scope, fn) { + const k = `${id}:${scope}`; + state.sideEffects[k] = fn; + delete state.pendingSideEffects[k]; + } + function trackCtx({ id, $el, tag }) { + const isAttrTag = tag.tag.endsWith("Attrs"); + state.elMap[id] = $el; + if (!isAttrTag) { + ["textContent", "innerHTML"].forEach((k) => { + tag[k] && tag[k] !== $el[k] && ($el[k] = tag[k]); + }); + track(id, "el", () => { + state.elMap[id].remove(); + delete state.elMap[id]; + }); + } + Object.entries(tag.props).forEach(([k, value]) => { + const ck = `attr:${k}`; + if (k === "class") { + for (const c of (value || "").split(" ").filter(Boolean)) { + isAttrTag && track(id, `${ck}:${c}`, () => $el.classList.remove(c)); + !$el.classList.contains(c) && $el.classList.add(c); + } + } else { + $el.getAttribute(k) !== value && $el.setAttribute(k, value === true ? "" : String(value)); + isAttrTag && track(id, ck, () => $el.removeAttribute(k)); + } + }); + } + const pending = []; + const frag = { + bodyClose: void 0, + bodyOpen: void 0, + head: void 0 + }; + for (const ctx of tags) { + const { tag, shouldRender, id } = ctx; + if (!shouldRender) + continue; + if (tag.tag === "title") { + dom.title = tag.textContent; + continue; + } + ctx.$el = ctx.$el || state.elMap[id]; + if (ctx.$el) + trackCtx(ctx); + else + HasElementTags.includes(tag.tag) && pending.push(ctx); + } + for (const ctx of pending) { + const pos = ctx.tag.tagPosition || "head"; + ctx.$el = dom.createElement(ctx.tag.tag); + trackCtx(ctx); + frag[pos] = frag[pos] || dom.createDocumentFragment(); + frag[pos].appendChild(ctx.$el); + } + for (const ctx of tags) + await head.hooks.callHook("dom:renderTag", ctx, dom, track); + frag.head && dom.head.appendChild(frag.head); + frag.bodyOpen && dom.body.insertBefore(frag.bodyOpen, dom.body.firstChild); + frag.bodyClose && dom.body.appendChild(frag.bodyClose); + Object.values(state.pendingSideEffects).forEach((fn) => fn()); + head._dom = state; + head.dirty = false; + await head.hooks.callHook("dom:rendered", { renders: tags }); +} + +async function debouncedRenderDOMHead(head, options = {}) { + const fn = options.delayFn || ((fn2) => setTimeout(fn2, 10)); + return head._domUpdatePromise = head._domUpdatePromise || new Promise((resolve) => fn(async () => { + await renderDOMHead(head, options); + delete head._domUpdatePromise; + resolve(); + })); +} + +// @__NO_SIDE_EFFECTS__ +function DomPlugin(options) { + return defineHeadPlugin((head) => { + const initialPayload = head.resolvedOptions.document?.head.querySelector('script[id="unhead:payload"]')?.innerHTML || false; + initialPayload && head.push(JSON.parse(initialPayload)); + return { + mode: "client", + hooks: { + "entries:updated": function(head2) { + debouncedRenderDOMHead(head2, options); + } + } + }; + }); +} + +export { DomPlugin, debouncedRenderDOMHead, renderDOMHead }; diff --git a/.output/server/node_modules/@unhead/shared/dist/index.mjs b/.output/server/node_modules/@unhead/shared/dist/index.mjs new file mode 100644 index 0000000..1485155 --- /dev/null +++ b/.output/server/node_modules/@unhead/shared/dist/index.mjs @@ -0,0 +1,640 @@ +function asArray$1(value) { + return Array.isArray(value) ? value : [value]; +} + +const SelfClosingTags = ["meta", "link", "base"]; +const TagsWithInnerContent = ["title", "titleTemplate", "script", "style", "noscript"]; +const HasElementTags = [ + "base", + "meta", + "link", + "style", + "script", + "noscript" +]; +const ValidHeadTags = [ + "title", + "titleTemplate", + "templateParams", + "base", + "htmlAttrs", + "bodyAttrs", + "meta", + "link", + "style", + "script", + "noscript" +]; +const UniqueTags = ["base", "title", "titleTemplate", "bodyAttrs", "htmlAttrs", "templateParams"]; +const TagConfigKeys = ["tagPosition", "tagPriority", "tagDuplicateStrategy", "children", "innerHTML", "textContent", "processTemplateParams"]; +const IsBrowser = typeof window !== "undefined"; +const composableNames = [ + "getActiveHead", + "useHead", + "useSeoMeta", + "useHeadSafe", + "useServerHead", + "useServerSeoMeta", + "useServerHeadSafe" +]; + +function defineHeadPlugin(plugin) { + return plugin; +} + +function hashCode(s) { + let h = 9; + for (let i = 0; i < s.length; ) + h = Math.imul(h ^ s.charCodeAt(i++), 9 ** 9); + return ((h ^ h >>> 9) + 65536).toString(16).substring(1, 8).toLowerCase(); +} +function hashTag(tag) { + return tag._h || hashCode(tag._d ? tag._d : `${tag.tag}:${tag.textContent || tag.innerHTML || ""}:${Object.entries(tag.props).map(([key, value]) => `${key}:${String(value)}`).join(",")}`); +} + +function tagDedupeKey(tag, fn) { + const { props, tag: tagName } = tag; + if (UniqueTags.includes(tagName)) + return tagName; + if (tagName === "link" && props.rel === "canonical") + return "canonical"; + if (props.charset) + return "charset"; + const name = ["id"]; + if (tagName === "meta") + name.push(...["name", "property", "http-equiv"]); + for (const n of name) { + if (typeof props[n] !== "undefined") { + const val = String(props[n]); + if (fn && !fn(val)) + return false; + return `${tagName}:${n}:${val}`; + } + } + return false; +} + +function resolveTitleTemplate(template, title) { + if (template == null) + return title || null; + if (typeof template === "function") + return template(title); + return template; +} + +function asArray(input) { + return Array.isArray(input) ? input : [input]; +} +const InternalKeySymbol = "_$key"; +function packObject(input, options) { + const keys = Object.keys(input); + let [k, v] = keys; + options = options || {}; + options.key = options.key || k; + options.value = options.value || v; + options.resolveKey = options.resolveKey || ((k2) => k2); + const resolveKey = (index) => { + const arr = asArray(options?.[index]); + return arr.find((k2) => { + if (typeof k2 === "string" && k2.includes(".")) { + return k2; + } + return k2 && keys.includes(k2); + }); + }; + const resolveValue = (k2, input2) => { + if (k2.includes(".")) { + const paths = k2.split("."); + let val = input2; + for (const path of paths) + val = val[path]; + return val; + } + return input2[k2]; + }; + k = resolveKey("key") || k; + v = resolveKey("value") || v; + const dedupeKeyPrefix = input.key ? `${InternalKeySymbol}${input.key}-` : ""; + let keyValue = resolveValue(k, input); + keyValue = options.resolveKey(keyValue); + return { + [`${dedupeKeyPrefix}${keyValue}`]: resolveValue(v, input) + }; +} + +function packArray(input, options) { + const packed = {}; + for (const i of input) { + const packedObj = packObject(i, options); + const pKey = Object.keys(packedObj)[0]; + const isDedupeKey = pKey.startsWith(InternalKeySymbol); + if (!isDedupeKey && packed[pKey]) { + packed[pKey] = Array.isArray(packed[pKey]) ? packed[pKey] : [packed[pKey]]; + packed[pKey].push(Object.values(packedObj)[0]); + } else { + packed[isDedupeKey ? pKey.split("-").slice(1).join("-") || pKey : pKey] = packedObj[pKey]; + } + } + return packed; +} + +function unpackToArray(input, options) { + const unpacked = []; + const kFn = options.resolveKeyData || ((ctx) => ctx.key); + const vFn = options.resolveValueData || ((ctx) => ctx.value); + for (const [k, v] of Object.entries(input)) { + unpacked.push(...(Array.isArray(v) ? v : [v]).map((i) => { + const ctx = { key: k, value: i }; + const val = vFn(ctx); + if (typeof val === "object") + return unpackToArray(val, options); + if (Array.isArray(val)) + return val; + return { + [typeof options.key === "function" ? options.key(ctx) : options.key]: kFn(ctx), + [typeof options.value === "function" ? options.value(ctx) : options.value]: val + }; + }).flat()); + } + return unpacked; +} + +function unpackToString(value, options) { + return Object.entries(value).map(([key, value2]) => { + if (typeof value2 === "object") + value2 = unpackToString(value2, options); + if (options.resolve) { + const resolved = options.resolve({ key, value: value2 }); + if (resolved) + return resolved; + } + if (typeof value2 === "number") + value2 = value2.toString(); + if (typeof value2 === "string" && options.wrapValue) { + value2 = value2.replace(new RegExp(options.wrapValue, "g"), `\\${options.wrapValue}`); + value2 = `${options.wrapValue}${value2}${options.wrapValue}`; + } + return `${key}${options.keyValueSeparator || ""}${value2}`; + }).join(options.entrySeparator || ""); +} + +const p = (p2) => ({ keyValue: p2, metaKey: "property" }); +const k = (p2) => ({ keyValue: p2 }); +const MetaPackingSchema = { + appleItunesApp: { + unpack: { + entrySeparator: ", ", + resolve({ key, value }) { + return `${fixKeyCase(key)}=${value}`; + } + } + }, + articleExpirationTime: p("article:expiration_time"), + articleModifiedTime: p("article:modified_time"), + articlePublishedTime: p("article:published_time"), + bookReleaseDate: p("book:release_date"), + charset: { + metaKey: "charset" + }, + contentSecurityPolicy: { + unpack: { + entrySeparator: "; ", + resolve({ key, value }) { + return `${fixKeyCase(key)} ${value}`; + } + }, + metaKey: "http-equiv" + }, + contentType: { + metaKey: "http-equiv" + }, + defaultStyle: { + metaKey: "http-equiv" + }, + fbAppId: p("fb:app_id"), + msapplicationConfig: k("msapplication-Config"), + msapplicationTileColor: k("msapplication-TileColor"), + msapplicationTileImage: k("msapplication-TileImage"), + ogAudioSecureUrl: p("og:audio:secure_url"), + ogAudioUrl: p("og:audio"), + ogImageSecureUrl: p("og:image:secure_url"), + ogImageUrl: p("og:image"), + ogSiteName: p("og:site_name"), + ogVideoSecureUrl: p("og:video:secure_url"), + ogVideoUrl: p("og:video"), + profileFirstName: p("profile:first_name"), + profileLastName: p("profile:last_name"), + profileUsername: p("profile:username"), + refresh: { + metaKey: "http-equiv", + unpack: { + entrySeparator: ";", + resolve({ key, value }) { + if (key === "seconds") + return `${value}`; + } + } + }, + robots: { + unpack: { + entrySeparator: ", ", + resolve({ key, value }) { + if (typeof value === "boolean") + return `${fixKeyCase(key)}`; + else + return `${fixKeyCase(key)}:${value}`; + } + } + }, + xUaCompatible: { + metaKey: "http-equiv" + } +}; +const openGraphNamespaces = [ + "og", + "book", + "article", + "profile" +]; +function resolveMetaKeyType(key) { + const fKey = fixKeyCase(key).split(":")[0]; + if (openGraphNamespaces.includes(fKey)) + return "property"; + return MetaPackingSchema[key]?.metaKey || "name"; +} +function resolveMetaKeyValue(key) { + return MetaPackingSchema[key]?.keyValue || fixKeyCase(key); +} +function fixKeyCase(key) { + const updated = key.replace(/([A-Z])/g, "-$1").toLowerCase(); + const fKey = updated.split("-")[0]; + if (openGraphNamespaces.includes(fKey) || fKey === "twitter") + return key.replace(/([A-Z])/g, ":$1").toLowerCase(); + return updated; +} +function changeKeyCasingDeep(input) { + if (Array.isArray(input)) { + return input.map((entry) => changeKeyCasingDeep(entry)); + } + if (typeof input !== "object" || Array.isArray(input)) + return input; + const output = {}; + for (const [key, value] of Object.entries(input)) + output[fixKeyCase(key)] = changeKeyCasingDeep(value); + return output; +} +function resolvePackedMetaObjectValue(value, key) { + const definition = MetaPackingSchema[key]; + if (key === "refresh") + return `${value.seconds};url=${value.url}`; + return unpackToString( + changeKeyCasingDeep(value), + { + keyValueSeparator: "=", + entrySeparator: ", ", + resolve({ value: value2, key: key2 }) { + if (value2 === null) + return ""; + if (typeof value2 === "boolean") + return `${key2}`; + }, + ...definition?.unpack + } + ); +} +const ObjectArrayEntries = ["og:image", "og:video", "og:audio", "twitter:image"]; +function sanitize(input) { + const out = {}; + Object.entries(input).forEach(([k2, v]) => { + if (String(v) !== "false" && k2) + out[k2] = v; + }); + return out; +} +function handleObjectEntry(key, v) { + const value = sanitize(v); + const fKey = fixKeyCase(key); + const attr = resolveMetaKeyType(fKey); + if (ObjectArrayEntries.includes(fKey)) { + const input = {}; + Object.entries(value).forEach(([k2, v2]) => { + input[`${key}${k2 === "url" ? "" : `${k2.charAt(0).toUpperCase()}${k2.slice(1)}`}`] = v2; + }); + return unpackMeta(input).sort((a, b) => (a[attr]?.length || 0) - (b[attr]?.length || 0)); + } + return [{ [attr]: fKey, ...value }]; +} +function unpackMeta(input) { + const extras = []; + const primitives = {}; + Object.entries(input).forEach(([key, value]) => { + if (!Array.isArray(value)) { + if (typeof value === "object" && value) { + if (ObjectArrayEntries.includes(fixKeyCase(key))) { + extras.push(...handleObjectEntry(key, value)); + return; + } + primitives[key] = sanitize(value); + } else { + primitives[key] = value; + } + return; + } + value.forEach((v) => { + extras.push(...typeof v === "string" ? unpackMeta({ [key]: v }) : handleObjectEntry(key, v)); + }); + }); + const meta = unpackToArray(primitives, { + key({ key }) { + return resolveMetaKeyType(key); + }, + value({ key }) { + return key === "charset" ? "charset" : "content"; + }, + resolveKeyData({ key }) { + return resolveMetaKeyValue(key); + }, + resolveValueData({ value, key }) { + if (value === null) + return "_null"; + if (typeof value === "object") + return resolvePackedMetaObjectValue(value, key); + return typeof value === "number" ? value.toString() : value; + } + }); + return [...extras, ...meta].map((m) => { + if (m.content === "_null") + m.content = null; + return m; + }); +} +function packMeta(inputs) { + const mappedPackingSchema = Object.entries(MetaPackingSchema).map(([key, value]) => [key, value.keyValue]); + return packArray(inputs, { + key: ["name", "property", "httpEquiv", "http-equiv", "charset"], + value: ["content", "charset"], + resolveKey(k2) { + let key = mappedPackingSchema.filter((sk) => sk[1] === k2)?.[0]?.[0] || k2; + const replacer = (_, letter) => letter?.toUpperCase(); + key = key.replace(/:([a-z])/g, replacer).replace(/-([a-z])/g, replacer); + return key; + } + }); +} + +const WhitelistAttributes = { + htmlAttrs: ["id", "class", "lang", "dir"], + bodyAttrs: ["id", "class"], + meta: ["id", "name", "property", "charset", "content"], + noscript: ["id", "textContent"], + script: ["id", "type", "textContent"], + link: ["id", "color", "crossorigin", "fetchpriority", "href", "hreflang", "imagesrcset", "imagesizes", "integrity", "media", "referrerpolicy", "rel", "sizes", "type"] +}; +function acceptDataAttrs(value) { + const filtered = {}; + Object.keys(value || {}).filter((a) => a.startsWith("data-")).forEach((a) => { + filtered[a] = value[a]; + }); + return filtered; +} +function whitelistSafeInput(input) { + const filtered = {}; + Object.keys(input).forEach((key) => { + const tagValue = input[key]; + if (!tagValue) + return; + switch (key) { + case "title": + case "titleTemplate": + case "templateParams": + filtered[key] = tagValue; + break; + case "htmlAttrs": + case "bodyAttrs": + filtered[key] = acceptDataAttrs(tagValue); + WhitelistAttributes[key].forEach((a) => { + if (tagValue[a]) + filtered[key][a] = tagValue[a]; + }); + break; + case "meta": + if (Array.isArray(tagValue)) { + filtered[key] = tagValue.map((meta) => { + const safeMeta = acceptDataAttrs(meta); + WhitelistAttributes.meta.forEach((key2) => { + if (meta[key2]) + safeMeta[key2] = meta[key2]; + }); + return safeMeta; + }).filter((meta) => Object.keys(meta).length > 0); + } + break; + case "link": + if (Array.isArray(tagValue)) { + filtered[key] = tagValue.map((meta) => { + const link = acceptDataAttrs(meta); + WhitelistAttributes.link.forEach((key2) => { + const val = meta[key2]; + if (key2 === "rel" && ["stylesheet", "canonical", "modulepreload", "prerender", "preload", "prefetch"].includes(val)) + return; + if (key2 === "href") { + if (val.includes("javascript:") || val.includes("data:")) + return; + link[key2] = val; + } else if (val) { + link[key2] = val; + } + }); + return link; + }).filter((link) => Object.keys(link).length > 1 && !!link.rel); + } + break; + case "noscript": + if (Array.isArray(tagValue)) { + filtered[key] = tagValue.map((meta) => { + const noscript = acceptDataAttrs(meta); + WhitelistAttributes.noscript.forEach((key2) => { + if (meta[key2]) + noscript[key2] = meta[key2]; + }); + return noscript; + }).filter((meta) => Object.keys(meta).length > 0); + } + break; + case "script": + if (Array.isArray(tagValue)) { + filtered[key] = tagValue.map((script) => { + const safeScript = acceptDataAttrs(script); + WhitelistAttributes.script.forEach((s) => { + if (script[s]) { + if (s === "textContent") { + try { + const jsonVal = typeof script[s] === "string" ? JSON.parse(script[s]) : script[s]; + safeScript[s] = JSON.stringify(jsonVal, null, 0); + } catch (e) { + } + } else { + safeScript[s] = script[s]; + } + } + }); + return safeScript; + }).filter((meta) => Object.keys(meta).length > 0); + } + break; + } + }); + return filtered; +} + +async function normaliseTag(tagName, input, e) { + const tag = { + tag: tagName, + props: await normaliseProps( + // explicitly check for an object + // @ts-expect-error untyped + typeof input === "object" && typeof input !== "function" && !(input instanceof Promise) ? { ...input } : { [["script", "noscript", "style"].includes(tagName) ? "innerHTML" : "textContent"]: input }, + ["templateParams", "titleTemplate"].includes(tagName) + ) + }; + TagConfigKeys.forEach((k) => { + const val = typeof tag.props[k] !== "undefined" ? tag.props[k] : e[k]; + if (typeof val !== "undefined") { + if (!["innerHTML", "textContent", "children"].includes(k) || TagsWithInnerContent.includes(tag.tag)) { + tag[k === "children" ? "innerHTML" : k] = val; + } + delete tag.props[k]; + } + }); + if (tag.props.body) { + tag.tagPosition = "bodyClose"; + delete tag.props.body; + } + if (tag.tag === "script") { + if (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 normaliseClassProp(v) { + if (typeof v === "object" && !Array.isArray(v)) { + v = Object.keys(v).filter((k) => v[k]); + } + return (Array.isArray(v) ? v.join(" ") : v).split(" ").filter((c) => c.trim()).filter(Boolean).join(" "); +} +async function normaliseProps(props, virtual) { + for (const k of Object.keys(props)) { + if (k === "class") { + props[k] = normaliseClassProp(props[k]); + continue; + } + if (props[k] instanceof Promise) + props[k] = await props[k]; + if (!virtual && !TagConfigKeys.includes(k)) { + const v = String(props[k]); + const isDataKey = k.startsWith("data-"); + if (v === "true" || v === "") { + props[k] = isDataKey ? "true" : true; + } else if (!props[k]) { + if (isDataKey && v === "false") + props[k] = "false"; + else + delete props[k]; + } + } + } + return props; +} +const TagEntityBits = 10; +async function normaliseEntryTags(e) { + const tagPromises = []; + Object.entries(e.resolvedInput).filter(([k, v]) => typeof v !== "undefined" && ValidHeadTags.includes(k)).forEach(([k, value]) => { + const v = asArray$1(value); + tagPromises.push(...v.map((props) => normaliseTag(k, props, e)).flat()); + }); + return (await Promise.all(tagPromises)).flat().filter(Boolean).map((t, i) => { + t._e = e._i; + e.mode && (t._m = e.mode); + t._p = (e._i << TagEntityBits) + i; + return t; + }); +} + +const TAG_WEIGHTS = { + // tags + base: -10, + title: 10 +}; +const TAG_ALIASES = { + // relative scores to their default values + critical: -80, + high: -10, + low: 20 +}; +function tagWeight(tag) { + let weight = 100; + const priority = tag.tagPriority; + if (typeof priority === "number") + return priority; + if (tag.tag === "meta") { + if (tag.props["http-equiv"] === "content-security-policy") + weight = -30; + if (tag.props.charset) + weight = -20; + if (tag.props.name === "viewport") + weight = -15; + } else if (tag.tag === "link" && tag.props.rel === "preconnect") { + weight = 20; + } else if (tag.tag in TAG_WEIGHTS) { + weight = TAG_WEIGHTS[tag.tag]; + } + if (typeof priority === "string" && priority in TAG_ALIASES) { + return weight + TAG_ALIASES[priority]; + } + return weight; +} +const SortModifiers = [{ prefix: "before:", offset: -1 }, { prefix: "after:", offset: 1 }]; + +const NetworkEvents = ["onload", "onerror", "onabort", "onprogress", "onloadstart"]; + +const sepSub = "%separator"; +function processTemplateParams(s, p, sep) { + if (typeof s !== "string" || !s.includes("%")) + return s; + function sub(token) { + let val; + if (["s", "pageTitle"].includes(token)) { + val = p.pageTitle; + } else if (token.includes(".")) { + val = token.split(".").reduce((acc, key) => acc ? acc[key] || void 0 : void 0, p); + } else { + val = p[token]; + } + return typeof val !== "undefined" ? (val || "").replace(/"/g, '\\"') : false; + } + let decoded = s; + try { + decoded = decodeURI(s); + } catch { + } + const tokens = (decoded.match(/%(\w+\.+\w+)|%(\w+)/g) || []).sort().reverse(); + tokens.forEach((token) => { + const re = sub(token.slice(1)); + if (typeof re === "string") { + s = s.replace(new RegExp(`\\${token}(\\W|$)`, "g"), (_, args) => `${re}${args}`).trim(); + } + }); + if (s.includes(sepSub)) { + if (s.endsWith(sepSub)) + s = s.slice(0, -sepSub.length).trim(); + if (s.startsWith(sepSub)) + s = s.slice(sepSub.length).trim(); + s = s.replace(new RegExp(`\\${sepSub}\\s*\\${sepSub}`, "g"), sepSub); + s = processTemplateParams(s, { separator: sep }, sep); + } + return s; +} + +export { HasElementTags, IsBrowser, NetworkEvents, SelfClosingTags, SortModifiers, TAG_ALIASES, TAG_WEIGHTS, TagConfigKeys, TagEntityBits, TagsWithInnerContent, UniqueTags, ValidHeadTags, asArray$1 as asArray, composableNames, defineHeadPlugin, hashCode, hashTag, normaliseClassProp, normaliseEntryTags, normaliseProps, normaliseTag, packMeta, processTemplateParams, resolveMetaKeyType, resolveMetaKeyValue, resolvePackedMetaObjectValue, resolveTitleTemplate, tagDedupeKey, tagWeight, unpackMeta, whitelistSafeInput }; diff --git a/.output/server/node_modules/@unhead/ssr/dist/index.mjs b/.output/server/node_modules/@unhead/ssr/dist/index.mjs new file mode 100644 index 0000000..732a57c --- /dev/null +++ b/.output/server/node_modules/@unhead/ssr/dist/index.mjs @@ -0,0 +1,84 @@ +import { TagsWithInnerContent, SelfClosingTags } from '@unhead/shared'; + +function encodeAttribute(value) { + return String(value).replace(/"/g, """); +} +function propsToString(props) { + const attrs = []; + for (const [key, value] of Object.entries(props)) { + if (value !== false && value !== null) + attrs.push(value === true ? key : `${key}="${encodeAttribute(value)}"`); + } + return `${attrs.length > 0 ? " " : ""}${attrs.join(" ")}`; +} + +function escapeHtml(str) { + return str.replace(/[&<>"'/]/g, (char) => { + switch (char) { + case "&": + return "&"; + case "<": + return "<"; + case ">": + return ">"; + case '"': + return """; + case "'": + return "'"; + case "/": + return "/"; + default: + return char; + } + }); +} +function tagToString(tag) { + const attrs = propsToString(tag.props); + const openTag = `<${tag.tag}${attrs}>`; + if (!TagsWithInnerContent.includes(tag.tag)) + return SelfClosingTags.includes(tag.tag) ? openTag : `${openTag}`; + let content = String(tag.innerHTML || ""); + if (tag.textContent) + content = escapeHtml(String(tag.textContent)); + return SelfClosingTags.includes(tag.tag) ? openTag : `${openTag}${content}`; +} + +function ssrRenderTags(tags) { + const schema = { htmlAttrs: {}, bodyAttrs: {}, tags: { head: [], bodyClose: [], bodyOpen: [] } }; + for (const tag of tags) { + if (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs") { + schema[tag.tag] = { ...schema[tag.tag], ...tag.props }; + continue; + } + schema.tags[tag.tagPosition || "head"].push(tagToString(tag)); + } + return { + headTags: schema.tags.head.join("\n"), + bodyTags: schema.tags.bodyClose.join("\n"), + bodyTagsOpen: schema.tags.bodyOpen.join("\n"), + htmlAttrs: propsToString(schema.htmlAttrs), + bodyAttrs: propsToString(schema.bodyAttrs) + }; +} + +async function renderSSRHead(head) { + const beforeRenderCtx = { shouldRender: true }; + await head.hooks.callHook("ssr:beforeRender", beforeRenderCtx); + if (!beforeRenderCtx.shouldRender) { + return { + headTags: "", + bodyTags: "", + bodyTagsOpen: "", + htmlAttrs: "", + bodyAttrs: "" + }; + } + const ctx = { tags: await head.resolveTags() }; + await head.hooks.callHook("ssr:render", ctx); + const html = ssrRenderTags(ctx.tags); + const renderCtx = { tags: ctx.tags, html }; + await head.hooks.callHook("ssr:rendered", renderCtx); + return renderCtx.html; +} + +export { escapeHtml, propsToString, renderSSRHead, ssrRenderTags, tagToString }; diff --git a/.output/server/node_modules/@vue/compiler-core/dist/compiler-core.cjs.js b/.output/server/node_modules/@vue/compiler-core/dist/compiler-core.cjs.js new file mode 100644 index 0000000..e3dd2ab --- /dev/null +++ b/.output/server/node_modules/@vue/compiler-core/dist/compiler-core.cjs.js @@ -0,0 +1,5505 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var shared = require('@vue/shared'); +var parser = require('@babel/parser'); +var sourceMapJs = require('source-map-js'); +var estreeWalker = require('estree-walker'); + +function defaultOnError(error) { + throw error; +} +function defaultOnWarn(msg) { + console.warn(`[Vue warn] ${msg.message}`); +} +function createCompilerError(code, loc, messages, additionalMessage) { + const msg = (messages || errorMessages)[code] + (additionalMessage || ``) ; + const error = new SyntaxError(String(msg)); + error.code = code; + error.loc = loc; + return error; +} +const errorMessages = { + // parse errors + [0]: "Illegal comment.", + [1]: "CDATA section is allowed only in XML context.", + [2]: "Duplicate attribute.", + [3]: "End tag cannot have attributes.", + [4]: "Illegal '/' in tags.", + [5]: "Unexpected EOF in tag.", + [6]: "Unexpected EOF in CDATA section.", + [7]: "Unexpected EOF in comment.", + [8]: "Unexpected EOF in script.", + [9]: "Unexpected EOF in tag.", + [10]: "Incorrectly closed comment.", + [11]: "Incorrectly opened comment.", + [12]: "Illegal tag name. Use '<' to print '<'.", + [13]: "Attribute value was expected.", + [14]: "End tag name was expected.", + [15]: "Whitespace was expected.", + [16]: "Unexpected '`; + case 5: + return shared.escapeHtml(shared.toDisplayString(evaluateConstant(node.content))); + case 8: + return shared.escapeHtml(evaluateConstant(node)); + case 12: + return stringifyNode(node.content, context); + default: + return ""; + } +} +function stringifyElement(node, context) { + let res = `<${node.tag}`; + let innerHTML = ""; + for (let i = 0; i < node.props.length; i++) { + const p = node.props[i]; + if (p.type === 6) { + res += ` ${p.name}`; + if (p.value) { + res += `="${shared.escapeHtml(p.value.content)}"`; + } + } else if (p.type === 7) { + if (p.name === "bind") { + const exp = p.exp; + if (exp.content[0] === "_") { + res += ` ${p.arg.content}="__VUE_EXP_START__${exp.content}__VUE_EXP_END__"`; + continue; + } + if (shared.isBooleanAttr(p.arg.content) && exp.content === "false") { + continue; + } + let evaluated = evaluateConstant(exp); + if (evaluated != null) { + const arg = p.arg && p.arg.content; + if (arg === "class") { + evaluated = shared.normalizeClass(evaluated); + } else if (arg === "style") { + evaluated = shared.stringifyStyle(shared.normalizeStyle(evaluated)); + } + res += ` ${p.arg.content}="${shared.escapeHtml( + evaluated + )}"`; + } + } else if (p.name === "html") { + innerHTML = evaluateConstant(p.exp); + } else if (p.name === "text") { + innerHTML = shared.escapeHtml( + shared.toDisplayString(evaluateConstant(p.exp)) + ); + } + } + } + if (context.scopeId) { + res += ` ${context.scopeId}`; + } + res += `>`; + if (innerHTML) { + res += innerHTML; + } else { + for (let i = 0; i < node.children.length; i++) { + res += stringifyNode(node.children[i], context); + } + } + if (!shared.isVoidTag(node.tag)) { + res += ``; + } + return res; +} +function evaluateConstant(exp) { + if (exp.type === 4) { + return new Function(`return (${exp.content})`)(); + } else { + let res = ``; + exp.children.forEach((c) => { + if (shared.isString(c) || shared.isSymbol(c)) { + return; + } + if (c.type === 2) { + res += c.content; + } else if (c.type === 5) { + res += shared.toDisplayString(evaluateConstant(c.content)); + } else { + res += evaluateConstant(c); + } + }); + return res; + } +} + +const ignoreSideEffectTags = (node, context) => { + if (node.type === 1 && node.tagType === 0 && (node.tag === "script" || node.tag === "style")) { + context.onError( + createDOMCompilerError( + 63, + node.loc + ) + ); + context.removeNode(); + } +}; + +const DOMNodeTransforms = [ + transformStyle, + ...[transformTransition] +]; +const DOMDirectiveTransforms = { + cloak: compilerCore.noopDirectiveTransform, + html: transformVHtml, + text: transformVText, + model: transformModel, + // override compiler-core + on: transformOn, + // override compiler-core + show: transformShow +}; +function compile(template, options = {}) { + return compilerCore.baseCompile( + template, + shared.extend({}, parserOptions, options, { + nodeTransforms: [ + // ignore