Initial commit: 11ty website with Fire/Frost branding

This commit is contained in:
The Trinity
2026-04-02 18:39:00 -05:00
commit 40b45dff2e
1646 changed files with 329080 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
import EleventyBaseError from "./EleventyBaseError.js";
class DuplicatePermalinkOutputError extends EleventyBaseError {
get removeDuplicateErrorStringFromOutput() {
return true;
}
}
export default DuplicatePermalinkOutputError;

View File

@@ -0,0 +1,24 @@
/**
* This class serves as basis for all Eleventy-specific errors.
* @ignore
*/
class EleventyBaseError extends Error {
/**
* @param {string} message - The error message to display.
* @param {unknown} [originalError] - The original error caught.
*/
constructor(message, originalError) {
super(message);
this.name = this.constructor.name;
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
if (originalError) {
this.originalError = originalError;
}
}
}
export default EleventyBaseError;

View File

@@ -0,0 +1,152 @@
import util from "node:util";
import debugUtil from "debug";
import ConsoleLogger from "../Util/ConsoleLogger.js";
import EleventyErrorUtil from "./EleventyErrorUtil.js";
const debug = debugUtil("Eleventy:EleventyErrorHandler");
class EleventyErrorHandler {
constructor() {
this._isVerbose = true;
}
get isVerbose() {
return this._isVerbose;
}
set isVerbose(verbose) {
this._isVerbose = !!verbose;
this.logger.isVerbose = !!verbose;
}
get logger() {
if (!this._logger) {
this._logger = new ConsoleLogger();
this._logger.isVerbose = this.isVerbose;
}
return this._logger;
}
set logger(logger) {
this._logger = logger;
}
warn(e, msg) {
if (msg) {
this.initialMessage(msg, "warn", "yellow");
}
this.log(e, "warn");
}
fatal(e, msg) {
this.error(e, msg);
process.exitCode = 1;
}
once(type, e, msg) {
if (e.__errorAlreadyLogged) {
return;
}
this[type || "error"](e, msg);
Object.defineProperty(e, "__errorAlreadyLogged", {
value: true,
});
}
error(e, msg) {
if (msg) {
this.initialMessage(msg, "error", "red", true);
}
this.log(e, "error", undefined, true);
}
static getTotalErrorCount(e) {
let totalErrorCount = 0;
let errorCountRef = e;
while (errorCountRef) {
totalErrorCount++;
errorCountRef = errorCountRef.originalError;
}
return totalErrorCount;
}
//https://nodejs.org/api/process.html
log(e, type = "log", chalkColor = "", forceToConsole = false) {
if (process.env.DEBUG) {
debug("Full error object: %o", util.inspect(e, { showHidden: false, depth: null }));
}
let showStack = true;
if (e.skipOriginalStack) {
// Dont show the full error stack trace
showStack = false;
}
let totalErrorCount = EleventyErrorHandler.getTotalErrorCount(e);
let ref = e;
let index = 1;
while (ref) {
let nextRef = ref.originalError;
// Unwrap cause from error and assign it to what Eleventy expects
if (nextRef?.cause) {
nextRef.originalError = nextRef.cause?.originalError ?? nextRef?.cause;
}
if (!nextRef && EleventyErrorUtil.hasEmbeddedError(ref.message)) {
nextRef = EleventyErrorUtil.deconvertErrorToObject(ref);
}
if (nextRef?.skipOriginalStack) {
showStack = false;
}
this.logger.message(
`${totalErrorCount > 1 ? `${index}. ` : ""}${(
EleventyErrorUtil.cleanMessage(ref.message) || "(No error message provided)"
).trim()}${ref.name !== "Error" ? ` (via ${ref.name})` : ""}`,
type,
chalkColor,
forceToConsole,
);
if (process.env.DEBUG) {
debug(`(${type} stack): ${ref.stack}`);
} else if (!nextRef) {
// last error in the loop
// remove duplicate error messages if the stack contains the original message output above
let stackStr = ref.stack || "";
if (e.removeDuplicateErrorStringFromOutput) {
stackStr = stackStr.replace(
`${ref.name}: ${ref.message}`,
"(Repeated output has been truncated…)",
);
}
if (showStack) {
this.logger.message(
"\nOriginal error stack trace: " + stackStr,
type,
chalkColor,
forceToConsole,
);
}
}
ref = nextRef;
index++;
}
}
initialMessage(message, type = "log", chalkColor = "blue", forceToConsole = false) {
if (message) {
this.logger.message(message + ":", type, chalkColor, forceToConsole);
}
}
}
export { EleventyErrorHandler };

View File

@@ -0,0 +1,70 @@
import TemplateContentPrematureUseError from "./TemplateContentPrematureUseError.js";
/* Hack to workaround the variety of error handling schemes in template languages */
class EleventyErrorUtil {
static get prefix() {
return ">>>>>11ty>>>>>";
}
static get suffix() {
return "<<<<<11ty<<<<<";
}
static hasEmbeddedError(msg) {
if (!msg) {
return false;
}
return msg.includes(EleventyErrorUtil.prefix) && msg.includes(EleventyErrorUtil.suffix);
}
static cleanMessage(msg) {
if (!msg) {
return "";
}
if (!EleventyErrorUtil.hasEmbeddedError(msg)) {
return "" + msg;
}
return msg.slice(0, Math.max(0, msg.indexOf(EleventyErrorUtil.prefix)));
}
static deconvertErrorToObject(error) {
if (!error || !error.message) {
throw new Error(`Could not convert error object from: ${error}`);
}
if (!EleventyErrorUtil.hasEmbeddedError(error.message)) {
return error;
}
let msg = error.message;
let objectString = msg.substring(
msg.indexOf(EleventyErrorUtil.prefix) + EleventyErrorUtil.prefix.length,
msg.lastIndexOf(EleventyErrorUtil.suffix),
);
let obj = JSON.parse(objectString);
obj.name = error.name;
return obj;
}
// pass an error through a random template engines error handling unscathed
static convertErrorToString(error) {
return (
EleventyErrorUtil.prefix +
JSON.stringify({ message: error.message, stack: error.stack }) +
EleventyErrorUtil.suffix
);
}
static isPrematureTemplateContentError(e) {
// TODO the rest of the template engines
return (
e instanceof TemplateContentPrematureUseError ||
e?.cause instanceof TemplateContentPrematureUseError || // Custom (per Node-convention)
["RenderError", "UndefinedVariableError"].includes(e?.originalError?.name) && e?.originalError?.originalError instanceof TemplateContentPrematureUseError || // Liquid
e?.message?.includes("TemplateContentPrematureUseError") // Nunjucks
);
}
}
export default EleventyErrorUtil;

View File

@@ -0,0 +1,5 @@
import EleventyBaseError from "./EleventyBaseError.js";
class TemplateContentPrematureUseError extends EleventyBaseError {}
export default TemplateContentPrematureUseError;

View File

@@ -0,0 +1,5 @@
import EleventyBaseError from "./EleventyBaseError.js";
class TemplateContentUnrenderedTemplateError extends EleventyBaseError {}
export default TemplateContentUnrenderedTemplateError;

View File

@@ -0,0 +1,5 @@
import EleventyBaseError from "./EleventyBaseError.js";
class UsingCircularTemplateContentReferenceError extends EleventyBaseError {}
export default UsingCircularTemplateContentReferenceError;