summaryrefslogtreecommitdiff
path: root/node_modules/@11ty/eleventy/src/EleventyExtensionMap.js
diff options
context:
space:
mode:
authorShipwreckt <me@shipwreckt.co.uk>2025-10-31 20:02:14 +0000
committerShipwreckt <me@shipwreckt.co.uk>2025-10-31 20:02:14 +0000
commit7a52ddeba2a68388b544f529d2d92104420f77b0 (patch)
tree15ddd47457a2cb4a96060747437d36474e4f6b4e /node_modules/@11ty/eleventy/src/EleventyExtensionMap.js
parent53d6ae2b5568437afa5e4995580a3fb679b7b91b (diff)
Changed from static to 11ty!
Diffstat (limited to 'node_modules/@11ty/eleventy/src/EleventyExtensionMap.js')
-rw-r--r--node_modules/@11ty/eleventy/src/EleventyExtensionMap.js284
1 files changed, 284 insertions, 0 deletions
diff --git a/node_modules/@11ty/eleventy/src/EleventyExtensionMap.js b/node_modules/@11ty/eleventy/src/EleventyExtensionMap.js
new file mode 100644
index 0000000..8f42640
--- /dev/null
+++ b/node_modules/@11ty/eleventy/src/EleventyExtensionMap.js
@@ -0,0 +1,284 @@
+import { TemplatePath } from "@11ty/eleventy-utils";
+
+class EleventyExtensionMap {
+ #engineManager;
+
+ constructor(config) {
+ this.setTemplateConfig(config);
+ this._spiderJsDepsCache = {};
+
+ /** @type {Array} */
+ this.validTemplateLanguageKeys;
+ }
+
+ setFormats(formatKeys = []) {
+ // raw
+ this.formatKeys = formatKeys;
+
+ this.unfilteredFormatKeys = formatKeys.map(function (key) {
+ return key.trim().toLowerCase();
+ });
+
+ this.validTemplateLanguageKeys = this.unfilteredFormatKeys.filter((key) =>
+ this.hasExtension(key),
+ );
+
+ this.passthroughCopyKeys = this.unfilteredFormatKeys.filter((key) => !this.hasExtension(key));
+ }
+
+ setTemplateConfig(config) {
+ if (!config || config.constructor.name !== "TemplateConfig") {
+ throw new Error("Internal error: Missing or invalid `config` argument.");
+ }
+
+ this.templateConfig = config;
+ }
+
+ get config() {
+ return this.templateConfig.getConfig();
+ }
+
+ get engineManager() {
+ if (!this.#engineManager) {
+ throw new Error("Internal error: Missing `#engineManager` in EleventyExtensionMap.");
+ }
+
+ return this.#engineManager;
+ }
+
+ set engineManager(mgr) {
+ this.#engineManager = mgr;
+ }
+
+ reset() {
+ this.#engineManager.reset();
+ }
+
+ /* Used for layout path resolution */
+ getFileList(path, dir) {
+ if (!path) {
+ return [];
+ }
+
+ let files = [];
+ this.validTemplateLanguageKeys.forEach((key) => {
+ this.getExtensionsFromKey(key).forEach(function (extension) {
+ files.push((dir ? dir + "/" : "") + path + "." + extension);
+ });
+ });
+
+ return files;
+ }
+
+ // Warning: this would false positive on an include, but is only used
+ // on paths found from the file system glob search.
+ // TODO: Method name might just need to be renamed to something more accurate.
+ isFullTemplateFilePath(path) {
+ for (let extension of this.validTemplateLanguageKeys) {
+ if (path.endsWith(`.${extension}`)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ getCustomExtensionEntry(extension) {
+ if (!this.config.extensionMap) {
+ return;
+ }
+
+ for (let entry of this.config.extensionMap) {
+ if (entry.extension === extension) {
+ return entry;
+ }
+ }
+ }
+
+ getValidExtensionsForPath(path) {
+ let extensions = new Set();
+ for (let extension in this.extensionToKeyMap) {
+ if (path.endsWith(`.${extension}`)) {
+ extensions.add(extension);
+ }
+ }
+
+ // if multiple extensions are valid, sort from longest to shortest
+ // e.g. .11ty.js and .js
+ let sorted = Array.from(extensions)
+ .filter((extension) => this.validTemplateLanguageKeys.includes(extension))
+ .sort((a, b) => b.length - a.length);
+
+ return sorted;
+ }
+
+ async shouldSpiderJavaScriptDependencies(path) {
+ let extensions = this.getValidExtensionsForPath(path);
+ for (let extension of extensions) {
+ if (extension in this._spiderJsDepsCache) {
+ return this._spiderJsDepsCache[extension];
+ }
+
+ let cls = await this.engineManager.getEngineClassByExtension(extension);
+ if (cls) {
+ let entry = this.getCustomExtensionEntry(extension);
+ let shouldSpider = cls.shouldSpiderJavaScriptDependencies(entry);
+ this._spiderJsDepsCache[extension] = shouldSpider;
+ return shouldSpider;
+ }
+ }
+
+ return false;
+ }
+
+ getPassthroughCopyGlobs(inputDir) {
+ return this._getGlobs(this.passthroughCopyKeys, inputDir);
+ }
+
+ getValidGlobs(inputDir) {
+ return this._getGlobs(this.validTemplateLanguageKeys, inputDir);
+ }
+
+ getGlobs(inputDir) {
+ return this._getGlobs(this.unfilteredFormatKeys, inputDir);
+ }
+
+ _getGlobs(formatKeys, inputDir = "") {
+ let extensions = new Set();
+
+ for (let key of formatKeys) {
+ if (this.hasExtension(key)) {
+ for (let extension of this.getExtensionsFromKey(key)) {
+ extensions.add(extension);
+ }
+ } else {
+ extensions.add(key);
+ }
+ }
+
+ let dir = TemplatePath.convertToRecursiveGlobSync(inputDir);
+ if (extensions.size === 1) {
+ return [`${dir}/*.${Array.from(extensions)[0]}`];
+ } else if (extensions.size > 1) {
+ return [
+ // extra curly brackets /*.{cjs,txt}
+ `${dir}/*.{${Array.from(extensions).join(",")}}`,
+ ];
+ }
+
+ return [];
+ }
+
+ hasExtension(key) {
+ for (let extension in this.extensionToKeyMap) {
+ if (
+ this.extensionToKeyMap[extension].key === key ||
+ this.extensionToKeyMap[extension].aliasKey === key
+ ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ getExtensionsFromKey(key) {
+ let extensions = new Set();
+ for (let extension in this.extensionToKeyMap) {
+ if (this.extensionToKeyMap[extension].aliasKey) {
+ // only add aliased extension if explicitly referenced in formats
+ // overrides will not have an aliasKey (md => md)
+ if (this.extensionToKeyMap[extension].aliasKey === key) {
+ extensions.add(extension);
+ }
+ } else if (this.extensionToKeyMap[extension].key === key) {
+ extensions.add(extension);
+ }
+ }
+
+ return Array.from(extensions);
+ }
+
+ // Only `addExtension` configuration API extensions
+ getExtensionEntriesFromKey(key) {
+ let entries = new Set();
+ if ("extensionMap" in this.config) {
+ for (let entry of this.config.extensionMap) {
+ if (entry.key === key) {
+ entries.add(entry);
+ }
+ }
+ }
+ return Array.from(entries);
+ }
+
+ // Determines whether a path is a passthrough copy file or a template (via TemplateWriter)
+ hasEngine(pathOrKey) {
+ return !!this.getKey(pathOrKey);
+ }
+
+ getKey(pathOrKey) {
+ pathOrKey = (pathOrKey || "").toLowerCase();
+ for (let extension in this.extensionToKeyMap) {
+ if (pathOrKey === extension || pathOrKey.endsWith("." + extension)) {
+ let key =
+ this.extensionToKeyMap[extension].aliasKey || this.extensionToKeyMap[extension].key;
+ // must be a valid format key passed (e.g. via --formats)
+ if (this.validTemplateLanguageKeys.includes(key)) {
+ return key;
+ }
+ }
+ }
+ }
+
+ getExtensionEntry(pathOrKey) {
+ pathOrKey = (pathOrKey || "").toLowerCase();
+ for (let extension in this.extensionToKeyMap) {
+ if (pathOrKey === extension || pathOrKey.endsWith("." + extension)) {
+ return this.extensionToKeyMap[extension];
+ }
+ }
+ }
+
+ removeTemplateExtension(path) {
+ for (let extension in this.extensionToKeyMap) {
+ if (path === extension || path.endsWith("." + extension)) {
+ return path.slice(
+ 0,
+ path.length - 1 - extension.length < 0 ? 0 : path.length - 1 - extension.length,
+ );
+ }
+ }
+ return path;
+ }
+
+ // keys are file extensions
+ // values are template language keys
+ get extensionToKeyMap() {
+ if (!this._extensionToKeyMap) {
+ this._extensionToKeyMap = {
+ md: { key: "md", extension: "md" },
+ html: { key: "html", extension: "html" },
+ njk: { key: "njk", extension: "njk" },
+ liquid: { key: "liquid", extension: "liquid" },
+ "11ty.js": { key: "11ty.js", extension: "11ty.js" },
+ "11ty.cjs": { key: "11ty.js", extension: "11ty.cjs" },
+ "11ty.mjs": { key: "11ty.js", extension: "11ty.mjs" },
+ };
+
+ if ("extensionMap" in this.config) {
+ for (let entry of this.config.extensionMap) {
+ // extension and key are only different when aliasing.
+ this._extensionToKeyMap[entry.extension] = entry;
+ }
+ }
+ }
+
+ return this._extensionToKeyMap;
+ }
+
+ getReadableFileExtensions() {
+ return Object.keys(this.extensionToKeyMap).join(" ");
+ }
+}
+
+export default EleventyExtensionMap;