Files
homepage/node_modules/@11ty/eleventy/src/Plugins/InputPathToUrl.js
2024-11-03 17:16:20 +01:00

178 lines
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import path from "node:path";
import { TemplatePath } from "@11ty/eleventy-utils";
import isValidUrl from "../Util/ValidUrl.js";
function getValidPath(contentMap, testPath) {
let normalized = TemplatePath.addLeadingDotSlash(testPath);
// it must exist in the content map to be valid
if (contentMap[normalized]) {
return normalized;
}
}
function normalizeInputPath(targetInputPath, inputDir, sourceInputPath, contentMap) {
// inputDir is optional at the beginning of the developer supplied-path
// Input directory already on the input path
if (TemplatePath.join(targetInputPath).startsWith(TemplatePath.join(inputDir))) {
let absolutePath = getValidPath(contentMap, targetInputPath);
if (absolutePath) {
return absolutePath;
}
}
// Relative to project input directory
let relativeToInputDir = getValidPath(contentMap, TemplatePath.join(inputDir, targetInputPath));
if (relativeToInputDir) {
return relativeToInputDir;
}
if (targetInputPath && !path.isAbsolute(targetInputPath)) {
// Relative to source files input path
let sourceInputDir = TemplatePath.getDirFromFilePath(sourceInputPath);
let relativeToSourceFile = getValidPath(
contentMap,
TemplatePath.join(sourceInputDir, targetInputPath),
);
if (relativeToSourceFile) {
return relativeToSourceFile;
}
}
// the transform may have sent in a URL so we just return it as-is
return targetInputPath;
}
function parseFilePath(filepath) {
try {
/* u: URL {
href: 'file:///tmpl.njk#anchor',
origin: 'null',
protocol: 'file:',
username: '',
password: '',
host: '',
hostname: '',
port: '',
pathname: '/tmpl.njk',
search: '',
searchParams: URLSearchParams {},
hash: '#anchor'
} */
// Note that `node:url` -> pathToFileURL creates an absolute path, which we dont want
// URL(`file:#anchor`) gives back a pathname of `/`
let u = new URL(`file:${filepath}`);
filepath = filepath.replace(u.search, "");
filepath = filepath.replace(u.hash, "");
return [
// search includes ?, hash includes #
u.search + u.hash,
filepath,
];
} catch (e) {
return ["", filepath];
}
}
function FilterPlugin(eleventyConfig) {
let contentMap;
eleventyConfig.on("eleventy.contentMap", function ({ inputPathToUrl }) {
contentMap = inputPathToUrl;
});
eleventyConfig.addFilter("inputPathToUrl", function (targetFilePath) {
if (!contentMap) {
throw new Error("Internal error: contentMap not available for `inputPathToUrl` filter.");
}
if (isValidUrl(targetFilePath)) {
return targetFilePath;
}
let inputDir = eleventyConfig.directories.input;
let suffix = "";
[suffix, targetFilePath] = parseFilePath(targetFilePath);
// @ts-ignore
targetFilePath = normalizeInputPath(targetFilePath, inputDir, this.page.inputPath, contentMap);
let urls = contentMap[targetFilePath];
if (!urls || urls.length === 0) {
throw new Error(
"`inputPathToUrl` filter could not find a matching target for " + targetFilePath,
);
}
return `${urls[0]}${suffix}`;
});
}
function TransformPlugin(eleventyConfig, defaultOptions = {}) {
let opts = Object.assign(
{
extensions: "html",
},
defaultOptions,
);
let contentMap = null;
eleventyConfig.on("eleventy.contentMap", function ({ inputPathToUrl }) {
contentMap = inputPathToUrl;
});
eleventyConfig.htmlTransformer.addUrlTransform(opts.extensions, function (targetFilepathOrUrl) {
if (!contentMap) {
throw new Error("Internal error: contentMap not available for the `pathToUrl` Transform.");
}
if (isValidUrl(targetFilepathOrUrl)) {
return targetFilepathOrUrl;
}
let inputDir = eleventyConfig.directories.input;
let suffix = "";
[suffix, targetFilepathOrUrl] = parseFilePath(targetFilepathOrUrl);
targetFilepathOrUrl = normalizeInputPath(
targetFilepathOrUrl,
inputDir,
// @ts-ignore
this.page.inputPath,
contentMap,
);
let urls = contentMap[targetFilepathOrUrl];
if (!targetFilepathOrUrl || !urls || urls.length === 0) {
// fallback, transforms dont error on missing paths (though the pathToUrl filter does)
return `${targetFilepathOrUrl}${suffix}`;
}
return `${urls[0]}${suffix}`;
});
}
Object.defineProperty(FilterPlugin, "eleventyPackage", {
value: "@11ty/eleventy/inputpath-to-url-filter-plugin",
});
Object.defineProperty(FilterPlugin, "eleventyPluginOptions", {
value: {
unique: true,
},
});
Object.defineProperty(TransformPlugin, "eleventyPackage", {
value: "@11ty/eleventy/inputpath-to-url-transform-plugin",
});
Object.defineProperty(TransformPlugin, "eleventyPluginOptions", {
value: {
unique: true,
},
});
export default TransformPlugin;
export { FilterPlugin, TransformPlugin };