This commit is contained in:
2024-11-03 17:16:20 +01:00
commit fd6412d6f2
8090 changed files with 778406 additions and 0 deletions

View File

@@ -0,0 +1,177 @@
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 };