This commit is contained in:
2026-03-31 16:38:22 -07:00
commit 38940436a7
2112 changed files with 376929 additions and 0 deletions

258
node_modules/@11ty/eleventy/src/Util/Require.js generated vendored Normal file
View File

@ -0,0 +1,258 @@
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import module from "node:module";
import { MessageChannel } from "node:worker_threads";
import { TemplatePath } from "@11ty/eleventy-utils";
import EleventyBaseError from "../Errors/EleventyBaseError.js";
import eventBus from "../EventBus.js";
class EleventyImportError extends EleventyBaseError {}
const { port1, port2 } = new MessageChannel();
// ESM Cache Buster is an enhancement that works in Node 18.19+
// https://nodejs.org/docs/latest/api/module.html#moduleregisterspecifier-parenturl-options
// Fixes https://github.com/11ty/eleventy/issues/3270
// ENV variable for https://github.com/11ty/eleventy/issues/3371
if ("register" in module && !process?.env?.ELEVENTY_SKIP_ESM_RESOLVER) {
module.register("./EsmResolver.js", import.meta.url, {
parentURL: import.meta.url,
data: {
port: port2,
},
transferList: [port2],
});
}
// important to clear the require.cache in CJS projects
const require = module.createRequire(import.meta.url);
const requestPromiseCache = new Map();
function getImportErrorMessage(filePath, type) {
return `There was a problem importing '${path.relative(".", filePath)}' via ${type}`;
}
// Used for JSON imports, suffering from Node warning that import assertions experimental but also
// throwing an error if you try to import() a JSON file without an import assertion.
/**
*
* @returns {string|undefined}
*/
function loadContents(path, options = {}) {
let rawInput;
/** @type {string} */
let encoding = "utf8"; // JSON is utf8
if (options?.encoding || options?.encoding === null) {
encoding = options.encoding;
}
try {
// @ts-expect-error This is an error in the upstream types
rawInput = fs.readFileSync(path, encoding);
} catch (error) {
// @ts-expect-error Temporary
if (error?.code === "ENOENT") {
// if file does not exist, return nothing
return;
}
throw error;
}
// Can return a buffer, string, etc
if (typeof rawInput === "string") {
rawInput = rawInput.trim();
}
return rawInput;
}
let lastModifiedPaths = new Map();
eventBus.on("eleventy.importCacheReset", (fileQueue) => {
for (let filePath of fileQueue) {
let absolutePath = TemplatePath.absolutePath(filePath);
let newDate = Date.now();
lastModifiedPaths.set(absolutePath, newDate);
// post to EsmResolver worker thread
if (port1) {
port1.postMessage({ path: absolutePath, newDate });
}
// ESM Eleventy when using `import()` on a CJS project file still adds to require.cache
if (absolutePath in (require?.cache || {})) {
delete require.cache[absolutePath];
}
}
});
// raw means we dont normalize away the `default` export
async function dynamicImportAbsolutePath(absolutePath, options = {}) {
let { type, returnRaw, cacheBust } = Object.assign(
{
type: undefined,
returnRaw: false,
cacheBust: false, // force cache bust
},
options,
);
// Short circuit for JSON files (that are optional and can be empty)
if (absolutePath.endsWith(".json") || type === "json") {
try {
// https://v8.dev/features/import-assertions#dynamic-import() is still experimental in Node 20
let rawInput = loadContents(absolutePath);
if (!rawInput) {
// should not error when file exists but is _empty_
return;
}
return JSON.parse(rawInput);
} catch (e) {
return Promise.reject(
new EleventyImportError(getImportErrorMessage(absolutePath, "fs.readFile(json)"), e),
);
}
}
// Removed a `require` short circuit from this piece originally added
// in https://github.com/11ty/eleventy/pull/3493 Was a bit faster but
// error messaging was worse for require(esm)
let urlPath;
try {
let u = new URL(`file:${absolutePath}`);
// Bust the import cache if this is the last modified file (or cache busting is forced)
if (cacheBust) {
lastModifiedPaths.set(absolutePath, Date.now());
}
if (cacheBust || lastModifiedPaths.has(absolutePath)) {
u.searchParams.set("_cache_bust", lastModifiedPaths.get(absolutePath));
}
urlPath = u.toString();
} catch (e) {
urlPath = absolutePath;
}
let promise;
if (requestPromiseCache.has(urlPath)) {
promise = requestPromiseCache.get(urlPath);
} else {
promise = import(urlPath);
requestPromiseCache.set(urlPath, promise);
}
return promise.then(
(target) => {
if (returnRaw) {
return target;
}
// If the only export is `default`, elevate to top (for ESM and CJS)
if (Object.keys(target).length === 1 && "default" in target) {
return target.default;
}
// When using import() on a CommonJS file that exports an object sometimes it
// returns duplicated values in `default` key, e.g. `{ default: {key: value}, key: value }`
// A few examples:
// module.exports = { key: false };
// returns `{ default: {key: false}, key: false }` as not expected.
// module.exports = { key: true };
// module.exports = { key: null };
// module.exports = { key: undefined };
// module.exports = { key: class {} };
// A few examples where it does not duplicate:
// module.exports = { key: 1 };
// returns `{ default: {key: 1} }` as expected.
// module.exports = { key: "value" };
// module.exports = { key: {} };
// module.exports = { key: [] };
if (type === "cjs" && "default" in target) {
let match = true;
for (let key in target) {
if (key === "default") {
continue;
}
if (key === "module.exports") {
continue;
}
if (target[key] !== target.default[key]) {
match = false;
}
}
if (match) {
return target.default;
}
}
// Otherwise return { default: value, named: value }
// Object.assign here so we can add things to it in JavaScript.js
return Object.assign({}, target);
},
(error) => {
return Promise.reject(
new EleventyImportError(getImportErrorMessage(absolutePath, `import(${type})`), error),
);
},
);
}
function normalizeFilePathInEleventyPackage(file) {
// Back up relative paths from ./src/Util/Require.js
return path.resolve(fileURLToPath(import.meta.url), "../../../", file);
}
async function dynamicImportFromEleventyPackage(file) {
// points to files relative to the top level Eleventy directory
let filePath = normalizeFilePathInEleventyPackage(file);
// Returns promise
return dynamicImportAbsolutePath(filePath, { type: "esm" });
}
async function dynamicImport(localPath, type, options = {}) {
let absolutePath = TemplatePath.absolutePath(localPath);
options.type = type;
// Returns promise
return dynamicImportAbsolutePath(absolutePath, options);
}
/* Used to import default Eleventy configuration file, raw means we dont normalize away the `default` export */
async function dynamicImportRawFromEleventyPackage(file) {
// points to files relative to the top level Eleventy directory
let filePath = normalizeFilePathInEleventyPackage(file);
// Returns promise
return dynamicImportAbsolutePath(filePath, { type: "esm", returnRaw: true });
}
/* Used to import app configuration files, raw means we dont normalize away the `default` export */
async function dynamicImportRaw(localPath, type) {
let absolutePath = TemplatePath.absolutePath(localPath);
// Returns promise
return dynamicImportAbsolutePath(absolutePath, { type, returnRaw: true });
}
export {
loadContents as EleventyLoadContent,
dynamicImport as EleventyImport,
dynamicImportRaw as EleventyImportRaw,
normalizeFilePathInEleventyPackage,
// no longer used in core
dynamicImportFromEleventyPackage as EleventyImportFromEleventy,
dynamicImportRawFromEleventyPackage as EleventyImportRawFromEleventy,
};