@ztl-uwu/nuxt-content
Version:
Write your content inside your Nuxt app
60 lines (59 loc) • 2.29 kB
JavaScript
import { pascalCase } from "scule";
import slugify from "slugify";
import { withoutTrailingSlash, withLeadingSlash } from "ufo";
import { defineTransformer } from "./utils.js";
const SEMVER_REGEX = /^(\d+)(\.\d+)*(\.x)?$/;
export const describeId = (id) => {
const [_source, ...parts] = id.split(":");
const [, basename, _extension] = parts[parts.length - 1]?.match(/(.*)\.([^.]+)$/) || [];
if (basename) {
parts[parts.length - 1] = basename;
}
const _path = (parts || []).join("/");
return {
_source,
_path,
_extension,
_file: _extension ? `${_path}.${_extension}` : _path,
_basename: basename || ""
};
};
export default defineTransformer({
name: "path-meta",
extensions: [".*"],
transform(content, options = {}) {
const { locales = [], defaultLocale = "en", respectPathCase = false } = options;
const { _source, _file, _path, _extension, _basename } = describeId(content._id);
const parts = _path.split("/");
const _locale = locales.includes(parts[0]) ? parts.shift() : defaultLocale;
const filePath = generatePath(parts.join("/"), { respectPathCase });
return {
_path: filePath,
_dir: filePath.split("/").slice(-2)[0],
_draft: content._draft || content.draft || isDraft(_path),
_partial: isPartial(_path),
_locale,
...content,
// TODO: move title to Markdown parser
title: content.title || generateTitle(refineUrlPart(_basename)),
_source,
_file,
_stem: _path,
_extension
};
}
});
const isDraft = (path) => !!path.match(/\.draft(\/|\.|$)/);
const isPartial = (path) => path.split(/[:/]/).some((part) => part.match(/^_.*/));
export const generatePath = (path, { forceLeadingSlash = true, respectPathCase = false } = {}) => {
path = path.split("/").map((part) => slugify(refineUrlPart(part), { lower: !respectPathCase })).join("/");
return forceLeadingSlash ? withLeadingSlash(withoutTrailingSlash(path)) : path;
};
export const generateTitle = (path) => path.split(/[\s-]/g).map(pascalCase).join(" ");
export function refineUrlPart(name) {
name = name.split(/[/:]/).pop();
if (SEMVER_REGEX.test(name)) {
return name;
}
return name.replace(/(\d+\.)?(.*)/, "$2").replace(/^index(\.draft)?$/, "").replace(/\.draft$/, "");
}