summaryrefslogtreecommitdiff
path: root/node_modules/@11ty/eleventy/src/Util/HtmlRelativeCopy.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/Util/HtmlRelativeCopy.js
parent53d6ae2b5568437afa5e4995580a3fb679b7b91b (diff)
Changed from static to 11ty!
Diffstat (limited to 'node_modules/@11ty/eleventy/src/Util/HtmlRelativeCopy.js')
-rw-r--r--node_modules/@11ty/eleventy/src/Util/HtmlRelativeCopy.js149
1 files changed, 149 insertions, 0 deletions
diff --git a/node_modules/@11ty/eleventy/src/Util/HtmlRelativeCopy.js b/node_modules/@11ty/eleventy/src/Util/HtmlRelativeCopy.js
new file mode 100644
index 0000000..3059014
--- /dev/null
+++ b/node_modules/@11ty/eleventy/src/Util/HtmlRelativeCopy.js
@@ -0,0 +1,149 @@
+import path from "node:path";
+import { TemplatePath } from "@11ty/eleventy-utils";
+import isValidUrl from "./ValidUrl.js";
+import { isGlobMatch } from "./GlobMatcher.js";
+
+class HtmlRelativeCopy {
+ #userConfig;
+ #matchingGlobs = new Set();
+ #matchingGlobsArray;
+ #dirty = false;
+ #paths = new Set();
+ #failOnError = true;
+ #copyOptions = {
+ dot: false, // differs from standard passthrough copy
+ };
+
+ isEnabled() {
+ return this.#matchingGlobs.size > 0;
+ }
+
+ setFailOnError(failOnError) {
+ this.#failOnError = Boolean(failOnError);
+ }
+
+ setCopyOptions(opts) {
+ if (opts) {
+ Object.assign(this.#copyOptions, opts);
+ }
+ }
+
+ setUserConfig(userConfig) {
+ if (!userConfig || userConfig.constructor.name !== "UserConfig") {
+ throw new Error(
+ "Internal error: Missing `userConfig` or was not an instance of `UserConfig`.",
+ );
+ }
+ this.#userConfig = userConfig;
+ }
+
+ addPaths(paths = []) {
+ for (let path of paths) {
+ this.#paths.add(TemplatePath.getDir(path));
+ }
+ }
+
+ get matchingGlobs() {
+ if (this.#dirty || !this.#matchingGlobsArray) {
+ this.#matchingGlobsArray = Array.from(this.#matchingGlobs);
+ this.#dirty = false;
+ }
+
+ return this.#matchingGlobsArray;
+ }
+
+ addMatchingGlob(glob) {
+ if (glob) {
+ if (Array.isArray(glob)) {
+ for (let g of glob) {
+ this.#matchingGlobs.add(g);
+ }
+ } else {
+ this.#matchingGlobs.add(glob);
+ }
+ this.#dirty = true;
+ }
+ }
+
+ isSkippableHref(rawRef) {
+ if (
+ this.#matchingGlobs.size === 0 ||
+ !rawRef ||
+ path.isAbsolute(rawRef) ||
+ isValidUrl(rawRef)
+ ) {
+ return true;
+ }
+ return false;
+ }
+
+ isCopyableTarget(target) {
+ if (!isGlobMatch(target, this.matchingGlobs)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ exists(filePath) {
+ return this.#userConfig.exists(filePath);
+ }
+
+ getAliasedPath(ref) {
+ for (let dir of this.#paths) {
+ let found = TemplatePath.join(dir, ref);
+ if (this.isCopyableTarget(found) && this.exists(found)) {
+ return found;
+ }
+ }
+ }
+
+ getFilePathRelativeToProjectRoot(ref, contextFilePath) {
+ let dir = TemplatePath.getDirFromFilePath(contextFilePath);
+ return TemplatePath.join(dir, ref);
+ }
+
+ copy(fileRef, tmplInputPath, tmplOutputPath) {
+ // original ref is a full URL or no globs exist
+ if (this.isSkippableHref(fileRef)) {
+ return;
+ }
+
+ // Relative to source file’s input path
+ let source = this.getFilePathRelativeToProjectRoot(fileRef, tmplInputPath);
+ if (!this.isCopyableTarget(source)) {
+ return;
+ }
+
+ if (!this.exists(source)) {
+ // Try to alias using `options.paths`
+ let alias = this.getAliasedPath(fileRef);
+ if (!alias) {
+ if (this.#failOnError) {
+ throw new Error(
+ "Missing input file for `html-relative` Passthrough Copy file: " +
+ TemplatePath.absolutePath(source),
+ );
+ }
+
+ // don’t fail on error
+ return;
+ }
+
+ source = alias;
+ }
+
+ let target = this.getFilePathRelativeToProjectRoot(fileRef, tmplOutputPath);
+
+ // We use a Set here to allow passthrough copy manager to properly error on conflicts upstream
+ // Only errors when different inputs write to the same output
+ // Also errors if attempts to write outside the output folder.
+ this.#userConfig.emit("eleventy#copy", {
+ source,
+ target,
+ options: this.#copyOptions,
+ });
+ }
+}
+
+export { HtmlRelativeCopy };