summaryrefslogtreecommitdiff
path: root/node_modules/@11ty/eleventy/src/Plugins/InputPathToUrl.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/@11ty/eleventy/src/Plugins/InputPathToUrl.js')
-rw-r--r--node_modules/@11ty/eleventy/src/Plugins/InputPathToUrl.js191
1 files changed, 191 insertions, 0 deletions
diff --git a/node_modules/@11ty/eleventy/src/Plugins/InputPathToUrl.js b/node_modules/@11ty/eleventy/src/Plugins/InputPathToUrl.js
new file mode 100644
index 0000000..aca148b
--- /dev/null
+++ b/node_modules/@11ty/eleventy/src/Plugins/InputPathToUrl.js
@@ -0,0 +1,191 @@
+import path from "node:path";
+import { TemplatePath } from "@11ty/eleventy-utils";
+import isValidUrl from "../Util/ValidUrl.js";
+
+function getValidPath(contentMap, testPath) {
+ // if the path is coming from Markdown, it may be encoded
+ let normalized = TemplatePath.addLeadingDotSlash(decodeURIComponent(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 file’s 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) {
+ if (filepath.startsWith("#") || filepath.startsWith("?")) {
+ return [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 don’t want
+ // URL(`file:#anchor`) gives back a pathname of `/`
+ let u = new URL(`file:${filepath}`);
+ filepath = filepath.replace(u.search, ""); // includes ?
+ filepath = filepath.replace(u.hash, ""); // includes #
+
+ 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);
+ if (targetFilePath) {
+ targetFilePath = normalizeInputPath(
+ targetFilePath,
+ inputDir,
+ // @ts-ignore
+ 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);
+ if (targetFilepathOrUrl) {
+ targetFilepathOrUrl = normalizeInputPath(
+ targetFilepathOrUrl,
+ inputDir,
+ // @ts-ignore
+ this.page.inputPath,
+ contentMap,
+ );
+ }
+
+ let urls = contentMap[targetFilepathOrUrl];
+ if (!targetFilepathOrUrl || !urls || urls.length === 0) {
+ // fallback, transforms don’t 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 };