@ztl-uwu/nuxt-content
Version:
Write your content inside your Nuxt app
45 lines (44 loc) • 1.57 kB
JavaScript
import { pascalCase } from "scule";
import htmlTags from "../utils/html-tags.js";
import { defineTransformer } from "./utils.js";
async function resolveContentComponents(body, meta) {
const components = Array.from(new Set(loadComponents(body, meta)));
const manifest = await import("#build/content-components").catch(() => ({}));
const resolvedComponentsEntries = await Promise.all(components.map(async ([t, c]) => {
const componentImporter = c && manifest[pascalCase(c)];
if (typeof componentImporter === "function") {
return [t, await componentImporter()];
}
return [t, c];
}));
return Object.fromEntries(resolvedComponentsEntries);
function loadComponents(node, tags) {
if (node.type === "text" || node.tag === "binding") {
return [];
}
const renderTag = typeof node.props?.__ignoreMap === "undefined" && tags[node.tag] || node.tag;
const components2 = [];
if (node.type !== "root" && !htmlTags.includes(renderTag)) {
components2.push([node.tag, renderTag]);
}
for (const child of node.children || []) {
components2.push(...loadComponents(child, tags));
}
return components2;
}
}
export default defineTransformer({
name: "component-resolver",
extensions: [".*"],
async transform(content, options = {}) {
if (import.meta.server) {
return content;
}
const _components = await resolveContentComponents(content.body, {
...options?.tags || {},
...content._components || {}
});
content._components = _components;
return content;
}
});