This commit is contained in:
tatianamac
2019-11-26 14:50:43 -08:00
parent 8a55660ed0
commit 6d5445ecc5
13894 changed files with 2233957 additions and 0 deletions

35
node_modules/@11ty/eleventy/src/Benchmark.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
class Benchmark {
constructor() {
this.reset();
}
reset() {
this.timeSpent = 0;
this.beforeDates = [];
}
before() {
this.beforeDates.push(new Date());
}
after() {
if (!this.beforeDates.length) {
throw new Error("You called Benchmark after() without a before().");
}
let before = this.beforeDates.pop();
if (!this.beforeDates.length) {
this.timeSpent += new Date().getTime() - before.getTime();
}
}
getTotal() {
return this.timeSpent;
}
getTotalString() {
return this.timeSpent > 0 ? ` (${this.timeSpent}ms)` : "";
}
}
module.exports = Benchmark;

73
node_modules/@11ty/eleventy/src/BenchmarkGroup.js generated vendored Normal file
View File

@@ -0,0 +1,73 @@
const chalk = require("chalk");
const Benchmark = require("./Benchmark");
const debugWarn = require("debug")("Eleventy:Warnings");
class BenchmarkGroup {
constructor() {
this.benchmarks = {};
this.start = new Date();
this.isVerbose = true;
this.minimumThresholdMs = 0;
}
reset() {
this.start = new Date();
for (var type in this.benchmarks) {
this.benchmarks[type].reset();
}
}
// TODO make this async
add(type, callback) {
let benchmark = (this.benchmarks[type] = new Benchmark());
return function(...args) {
benchmark.before();
let ret = callback.call(this, ...args);
benchmark.after();
return ret;
};
}
setMinimumThresholdMs(minimumThresholdMs) {
let val = parseInt(minimumThresholdMs, 10);
if (isNaN(val)) {
throw new Error("`setMinimumThresholdMs` expects a number argument.");
}
this.minimumThresholdMs = val;
}
get(type) {
this.benchmarks[type] = new Benchmark();
return this.benchmarks[type];
}
finish(label, thresholdPercent, isVerbose) {
let totalTimeSpent = new Date().getTime() - this.start.getTime();
thresholdPercent = thresholdPercent !== undefined ? thresholdPercent : 10;
for (var type in this.benchmarks) {
let bench = this.benchmarks[type];
let totalForBenchmark = bench.getTotal();
let percent = (totalForBenchmark * 100) / totalTimeSpent;
if (
percent > thresholdPercent &&
totalForBenchmark >= this.minimumThresholdMs
) {
let str = chalk.yellow(
`Benchmark (${label}): ${type} took ${bench.getTotal()}ms (${percent.toFixed(
1
)}%)`
);
if (isVerbose) {
console.log(str);
}
debugWarn(str);
}
}
}
}
module.exports = BenchmarkGroup;

47
node_modules/@11ty/eleventy/src/BenchmarkManager.js generated vendored Normal file
View File

@@ -0,0 +1,47 @@
const BenchmarkGroup = require("./BenchmarkGroup");
class BenchmarkManager {
constructor() {
this.benches = {};
this.isVerbose = true;
}
reset() {
for (var j in this.benches) {
this.benches[j].reset();
}
}
setVerboseOutput(isVerbose) {
this.isVerbose = !!isVerbose;
}
getBenchmarkGroup(name) {
if (!this.benches[name]) {
this.benches[name] = new BenchmarkGroup();
}
return this.benches[name];
}
getAll() {
return this.benches;
}
get(name) {
if (name) {
return this.getBenchmarkGroup(name);
}
return this.getAll();
}
finish(thresholdPercent) {
for (var j in this.benches) {
this.benches[j].finish(j, thresholdPercent, this.isVerbose);
}
}
}
let manager = new BenchmarkManager();
module.exports = manager;

7
node_modules/@11ty/eleventy/src/Config.js generated vendored Normal file
View File

@@ -0,0 +1,7 @@
const TemplateConfig = require("./TemplateConfig");
const debug = require("debug")("Eleventy:Config");
debug("Setting up global TemplateConfig.");
let config = new TemplateConfig();
module.exports = config;

451
node_modules/@11ty/eleventy/src/Eleventy.js generated vendored Normal file
View File

@@ -0,0 +1,451 @@
const pkg = require("../package.json");
const TemplatePath = require("./TemplatePath");
const TemplateData = require("./TemplateData");
const TemplateWriter = require("./TemplateWriter");
const EleventyErrorHandler = require("./EleventyErrorHandler");
const EleventyServe = require("./EleventyServe");
const EleventyWatchTargets = require("./EleventyWatchTargets");
const EleventyFiles = require("./EleventyFiles");
const templateCache = require("./TemplateCache");
const simplePlural = require("./Util/Pluralize");
const config = require("./Config");
const bench = require("./BenchmarkManager");
const debug = require("debug")("Eleventy");
class Eleventy {
constructor(input, output) {
this.config = config.getConfig();
this.configPath = null;
this.isVerbose = true;
this.isDebug = false;
this.isDryRun = false;
this.start = new Date();
this.formatsOverride = null;
this.eleventyServe = new EleventyServe();
this.rawInput = input;
this.rawOutput = output;
this.watchTargets = new EleventyWatchTargets();
this.watchTargets.watchJavaScriptDependencies = this.config.watchJavaScriptDependencies;
}
get input() {
return this.rawInput || this.config.dir.input;
}
get inputDir() {
return TemplatePath.getDir(this.input);
}
get outputDir() {
let dir = this.rawOutput || this.config.dir.output;
if (dir !== this._savedOutputDir) {
this.eleventyServe.setOutputDir(dir);
}
this._savedOutputDir = dir;
return dir;
}
setDryRun(isDryRun) {
this.isDryRun = !!isDryRun;
}
setPassthroughAll(isPassthroughAll) {
this.isPassthroughAll = !!isPassthroughAll;
}
setPathPrefix(pathPrefix) {
if (pathPrefix || pathPrefix === "") {
config.setPathPrefix(pathPrefix);
this.config = config.getConfig();
}
}
setWatchTargets(watchTargets) {
this.watchTargets = watchTargets;
}
setConfigPathOverride(configPath) {
if (configPath) {
this.configPath = configPath;
config.setProjectConfigPath(configPath);
this.config = config.getConfig();
}
}
async restart() {
debug("Restarting");
this.start = new Date();
templateCache.clear();
bench.reset();
this.eleventyFiles.restart();
// reload package.json values (if applicable)
// TODO only reset this if it changed
delete require.cache[TemplatePath.absolutePath("package.json")];
await this.init();
}
finish() {
bench.finish();
(this.logger || console).log(this.logFinished());
debug("Finished writing templates.");
}
logFinished() {
if (!this.writer) {
throw new Error(
"Did you call Eleventy.init to create the TemplateWriter instance? Hint: you probably didnt."
);
}
let ret = [];
let writeCount = this.writer.getWriteCount();
let copyCount = this.writer.getCopyCount();
if (this.isDryRun) {
ret.push("Pretended to");
}
if (copyCount) {
ret.push(
`${this.isDryRun ? "Copy" : "Copied"} ${copyCount} ${simplePlural(
copyCount,
"item",
"items"
)} and`
);
}
ret.push(
`${this.isDryRun ? "Process" : "Processed"} ${writeCount} ${simplePlural(
writeCount,
"file",
"files"
)}`
);
let time = ((new Date() - this.start) / 1000).toFixed(2);
ret.push(`in ${time} ${simplePlural(time, "second", "seconds")}`);
if (writeCount >= 10) {
ret.push(
`(${((time * 1000) / writeCount).toFixed(1)}ms each, v${pkg.version})`
);
} else {
ret.push(`(v${pkg.version})`);
}
return ret.join(" ");
}
async init() {
let formats = this.formatsOverride || this.config.templateFormats;
this.eleventyFiles = new EleventyFiles(
this.input,
this.outputDir,
formats,
this.isPassthroughAll
);
this.eleventyFiles.init();
this.templateData = new TemplateData(this.inputDir);
this.eleventyFiles.setTemplateData(this.templateData);
this.writer = new TemplateWriter(
this.input,
this.outputDir,
formats,
this.templateData,
this.isPassthroughAll
);
this.writer.setEleventyFiles(this.eleventyFiles);
// TODO maybe isVerbose -> console.log?
debug(`Directories:
Input: ${this.inputDir}
Data: ${this.templateData.getDataDir()}
Includes: ${this.eleventyFiles.getIncludesDir()}
Layouts: ${this.eleventyFiles.getLayoutsDir()}
Output: ${this.outputDir}
Template Formats: ${formats.join(",")}`);
this.writer.setVerboseOutput(this.isVerbose);
this.writer.setDryRun(this.isDryRun);
return this.templateData.cacheData();
}
setIsDebug(isDebug) {
this.isDebug = !!isDebug;
}
setIsVerbose(isVerbose) {
this.isVerbose = !!isVerbose;
if (this.writer) {
this.writer.setVerboseOutput(this.isVerbose);
}
if (bench) {
bench.setVerboseOutput(this.isVerbose);
}
}
setFormats(formats) {
if (formats && formats !== "*") {
this.formatsOverride = formats.split(",");
}
}
getVersion() {
return require("../package.json").version;
}
getHelp() {
return `usage: eleventy
eleventy --input=. --output=./_site
eleventy --serve
Arguments:
--version
--input=.
Input template files (default: \`.\`)
--output=_site
Write HTML output to this folder (default: \`_site\`)
--serve
Run web server on --port (default 8080) and watch them too
--watch
Wait for files to change and automatically rewrite (no web server)
--formats=liquid,md
Whitelist only certain template types (default: \`*\`)
--quiet
Dont print all written files (off by default)
--config=filename.js
Override the eleventy config file path (default: \`.eleventy.js\`)
--pathprefix='/'
Change all url template filters to use this subdirectory.
--dryrun
Dont write any files. Useful with \`DEBUG=Eleventy* npx eleventy\`
--help`;
}
resetConfig() {
config.reset();
this.config = config.getConfig();
this.eleventyServe.config = this.config;
}
async _watch(path) {
if (path) {
path = TemplatePath.addLeadingDotSlash(path);
}
if (this.active) {
this.queuedToRun = path;
return;
}
this.active = true;
let localProjectConfigPath = config.getLocalProjectConfigFile();
// reset and reload global configuration :O
if (path === localProjectConfigPath) {
this.resetConfig();
}
config.resetOnWatch();
await this.restart();
this.watchTargets.clearDependencyRequireCache();
await this.write();
this.watchTargets.reset();
await this._initWatchDependencies();
// Add new deps to chokidar
this.watcher.add(this.watchTargets.getNewTargetsSinceLastReset());
let isInclude =
path &&
TemplatePath.startsWithSubPath(path, this.eleventyFiles.getIncludesDir());
this.eleventyServe.reload(path, isInclude);
this.active = false;
if (this.queuedToRun) {
console.log("You saved while Eleventy was running, lets run again.");
this.queuedToRun = false;
await this._watch(this.queuedToRun);
} else {
console.log("Watching…");
}
}
get watcherBench() {
return bench.get("Watcher");
}
async initWatch() {
this.watchTargets.add(this.eleventyFiles.getGlobWatcherFiles());
// Watch the local project config file
this.watchTargets.add(config.getLocalProjectConfigFile());
// Template and Directory Data Files
this.watchTargets.add(
await this.eleventyFiles.getGlobWatcherTemplateDataFiles()
);
let benchmark = this.watcherBench.get(
"Watching JavaScript Dependencies (disable with `eleventyConfig.setWatchJavaScriptDependencies(false)`)"
);
benchmark.before();
await this._initWatchDependencies();
benchmark.after();
}
async _initWatchDependencies() {
if (!this.watchTargets.watchJavaScriptDependencies) {
return;
}
let dataDir = this.templateData.getDataDir();
function filterOutGlobalDataFiles(path) {
return !dataDir || path.indexOf(dataDir) === -1;
}
// Template files .11ty.js
this.watchTargets.addDependencies(this.eleventyFiles.getWatchPathCache());
// Config file dependencies
this.watchTargets.addDependencies(
config.getLocalProjectConfigFile(),
filterOutGlobalDataFiles.bind(this)
);
// Deps from Global Data (that arent in the global data directory, everything is watched there)
this.watchTargets.addDependencies(
this.templateData.getWatchPathCache(),
filterOutGlobalDataFiles.bind(this)
);
this.watchTargets.addDependencies(
await this.eleventyFiles.getWatcherTemplateJavaScriptDataFiles()
);
}
async getWatchedFiles() {
return this.watchTargets.getTargets();
}
async watch() {
this.watcherBench.setMinimumThresholdMs(500);
this.watcherBench.reset();
const chokidar = require("chokidar");
this.active = false;
this.queuedToRun = false;
// Note that watching indirectly depends on this for fetching dependencies from JS files
// See: TemplateWriter:pathCache and EleventyWatchTargets
await this.write();
await this.initWatch();
// TODO improve unwatching if JS dependencies are removed (or files are deleted)
let rawFiles = await this.getWatchedFiles();
debug("Watching for changes to: %o", rawFiles);
let ignores = this.eleventyFiles.getGlobWatcherIgnores();
debug("Watching but ignoring changes to: %o", ignores);
let watcher = chokidar.watch(rawFiles, {
ignored: ignores,
ignoreInitial: true
});
this.watcherBench.finish("Initialize --watch", 10, this.isVerbose);
console.log("Watching…");
this.watcher = watcher;
async function watchRun(path) {
try {
await this._watch(path);
} catch (e) {
EleventyErrorHandler.fatal(e, "Eleventy fatal watch error");
watcher.close();
}
}
watcher.on("change", async path => {
console.log("File changed:", path);
await watchRun.call(this, path);
});
watcher.on("add", async path => {
console.log("File added:", path);
await watchRun.call(this, path);
});
process.on(
"SIGINT",
function() {
debug("Cleaning up chokidar and browsersync (if exists) instances.");
this.eleventyServe.close();
this.watcher.close();
process.exit();
}.bind(this)
);
}
serve(port) {
this.eleventyServe.serve(port);
}
/* For testing */
setLogger(logger) {
this.logger = logger;
}
async write() {
let ret;
if (this.logger) {
EleventyErrorHandler.logger = this.logger;
}
try {
let promise = this.writer.write();
ret = await promise;
} catch (e) {
EleventyErrorHandler.initialMessage(
"Problem writing Eleventy templates",
"error",
"red"
);
EleventyErrorHandler.fatal(e);
}
this.finish();
debug(`
Getting frustrated? Have a suggestion/feature request/feedback?
I want to hear it! Open an issue: https://github.com/11ty/eleventy/issues/new`);
// unset the logger
EleventyErrorHandler.logger = undefined;
return ret;
}
}
module.exports = Eleventy;

10
node_modules/@11ty/eleventy/src/EleventyBaseError.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
class EleventyBaseError extends Error {
constructor(message, originalError) {
super(message);
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.originalError = originalError;
}
}
module.exports = EleventyBaseError;

View File

@@ -0,0 +1,82 @@
const EleventyBaseError = require("./EleventyBaseError");
const debug = require("debug")("Eleventy:CommandCheck");
class EleventyCommandCheckError extends EleventyBaseError {}
class EleventyCommandCheck {
constructor(argv) {
this.valueArgs = [
"input",
"output",
"formats",
"config",
"pathprefix",
"port"
];
this.booleanArgs = [
"quiet",
"version",
"watch",
"dryrun",
"help",
"serve",
"passthroughall"
];
this.args = argv;
this.argsMap = this.getArgumentLookupMap();
debug("command: eleventy ", this.toString());
}
toString() {
let cmd = [];
for (let valueArgName of this.valueArgs) {
if (this.args[valueArgName]) {
cmd.push(`--${valueArgName}=${this.args[valueArgName]}`);
}
}
for (let booleanArgName of this.booleanArgs) {
if (this.args[booleanArgName]) {
cmd.push(`--${booleanArgName}`);
}
}
return cmd.join(" ");
}
getArgumentLookupMap() {
let obj = {};
for (let valueArgName of this.valueArgs) {
obj[valueArgName] = true;
}
for (let booleanArgName of this.booleanArgs) {
obj[booleanArgName] = true;
}
return obj;
}
isKnownArgument(name) {
// _ is the default keyless parameter
if (name === "_") {
return true;
}
return !!this.argsMap[name];
}
hasUnknownArguments() {
for (let argName in this.args) {
if (!this.isKnownArgument(argName)) {
throw new EleventyCommandCheckError(
`We dont know what '${argName}' is. Use --help to see the list of supported commands.`
);
}
}
}
}
module.exports = EleventyCommandCheck;

3
node_modules/@11ty/eleventy/src/EleventyConfig.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
const UserConfig = require("./UserConfig");
module.exports = new UserConfig();

View File

@@ -0,0 +1,93 @@
const chalk = require("chalk");
const debug = require("debug")("Eleventy:EleventyErrorHandler");
class EleventyErrorHandler {
static get isChalkEnabled() {
if (this._isChalkEnabled !== undefined) {
return this._isChalkEnabled;
}
return true;
}
static set isChalkEnabled(enabled) {
this._isChalkEnabled = !!enabled;
}
static warn(e, msg) {
if (msg) {
EleventyErrorHandler.initialMessage(msg, "warn", "yellow");
}
EleventyErrorHandler.log(e, "warn");
}
static fatal(e, msg) {
EleventyErrorHandler.error(e, msg);
process.exitCode = 1;
}
static error(e, msg) {
if (msg) {
EleventyErrorHandler.initialMessage(msg, "error", "red");
}
EleventyErrorHandler.log(e, "error");
}
static log(e, type = "log", prefix = ">") {
let ref = e;
while (ref) {
let nextRef = ref.originalError;
EleventyErrorHandler.message(
(process.env.DEBUG ? "" : `${prefix} `) +
`${ref.message.trim()}
\`${ref.name}\` was thrown${!nextRef && ref.stack ? ":" : ""}`,
type
);
if (process.env.DEBUG) {
debug(`(${type} stack): ${ref.stack}`);
} else if (!nextRef) {
// last error in the loop
let prefix = " ";
// 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…)"
);
}
EleventyErrorHandler.message(
prefix + stackStr.split("\n").join("\n" + prefix)
);
}
ref = nextRef;
}
}
static initialMessage(message, type = "log", chalkColor = "blue") {
if (message) {
EleventyErrorHandler.message(
message + ":" + (process.env.DEBUG ? "" : " (more in DEBUG output)"),
type,
chalkColor
);
}
}
static message(message, type = "log", chalkColor) {
if (process.env.DEBUG) {
debug(message);
} else {
let logger = EleventyErrorHandler.logger || console;
if (chalkColor && EleventyErrorHandler.isChalkEnabled) {
logger[type](chalk[chalkColor](message));
} else {
logger[type](message);
}
}
}
}
module.exports = EleventyErrorHandler;

17
node_modules/@11ty/eleventy/src/EleventyErrorUtil.js generated vendored Normal file
View File

@@ -0,0 +1,17 @@
const TemplateContentPrematureUseError = require("./Errors/TemplateContentPrematureUseError");
class EleventyErrorUtil {
static isPrematureTemplateContentError(e) {
// TODO the rest of the template engines
return (
e instanceof TemplateContentPrematureUseError ||
(e.originalError &&
e.originalError.name === "RenderError" &&
e.originalError.originalError instanceof
TemplateContentPrematureUseError) || // Liquid
e.message.indexOf("TemplateContentPrematureUseError") > -1
); // Nunjucks
}
}
module.exports = EleventyErrorUtil;

164
node_modules/@11ty/eleventy/src/EleventyExtensionMap.js generated vendored Normal file
View File

@@ -0,0 +1,164 @@
const TemplatePath = require("./TemplatePath");
const config = require("./Config");
class EleventyExtensionMap {
constructor(formatKeys = []) {
this.unfilteredFormatKeys = formatKeys.map(function(key) {
return key.trim().toLowerCase();
});
this.formatKeys = this.unfilteredFormatKeys.filter(key =>
this.hasExtension(key)
);
this.prunedFormatKeys = this.unfilteredFormatKeys.filter(
key => !this.hasExtension(key)
);
}
get config() {
return this.configOverride || config.getConfig();
}
set config(cfg) {
this.configOverride = cfg;
}
/* Used for layout path resolution */
getFileList(path, dir) {
if (!path) {
return [];
}
let files = [];
this.formatKeys.forEach(
function(key) {
this.getExtensionsFromKey(key).forEach(function(extension) {
files.push((dir ? dir + "/" : "") + path + "." + extension);
});
}.bind(this)
);
return files;
}
getPrunedGlobs(inputDir) {
return this._getGlobs(this.prunedFormatKeys, inputDir);
}
getGlobs(inputDir) {
if (this.config.passthroughFileCopy) {
return this._getGlobs(this.unfilteredFormatKeys, inputDir);
}
return this._getGlobs(this.formatKeys, inputDir);
}
_getGlobs(formatKeys, inputDir) {
let dir = TemplatePath.convertToRecursiveGlob(inputDir);
let globs = [];
formatKeys.forEach(
function(key) {
if (this.hasExtension(key)) {
this.getExtensionsFromKey(key).forEach(function(extension) {
globs.push(dir + "/*." + extension);
});
} else {
globs.push(dir + "/*." + key);
}
}.bind(this)
);
return globs;
}
hasExtension(key) {
for (var extension in EleventyExtensionMap.keyMap) {
if (EleventyExtensionMap.keyMap[extension] === key) {
return true;
}
}
return false;
}
getExtensionsFromKey(key) {
let extensions = [];
for (var extension in this.keyMap) {
if (this.keyMap[extension] === key) {
extensions.push(extension);
}
}
return extensions;
}
getKey(pathOrKey) {
return EleventyExtensionMap._getKey(pathOrKey, this.keyMap);
}
static getKey(pathOrKey) {
return EleventyExtensionMap._getKey(pathOrKey, EleventyExtensionMap.keyMap);
}
static _getKey(pathOrKey, map) {
pathOrKey = pathOrKey.toLowerCase();
for (var extension in map) {
let key = map[extension];
if (pathOrKey === extension) {
return key;
} else if (pathOrKey.endsWith("." + extension)) {
return key;
}
}
}
removeTemplateExtension(path) {
return EleventyExtensionMap._removeTemplateExtension(path, this.keyMap);
}
static removeTemplateExtension(path) {
return EleventyExtensionMap._removeTemplateExtension(
path,
EleventyExtensionMap.keyMap
);
}
static _removeTemplateExtension(path, map) {
for (var extension in map) {
if (path === extension || path.endsWith("." + extension)) {
return path.substr(0, path.length - 1 - extension.length);
}
}
return path;
}
get keyMap() {
return EleventyExtensionMap._getKeyMap(
this.config.templateExtensionAliases || {}
);
}
static get keyMap() {
return EleventyExtensionMap._getKeyMap(
config.getConfig().templateExtensionAliases || {}
);
}
// file extension => key
static _getKeyMap(aliases) {
let fileExtensionToKeyMap = {
ejs: "ejs",
md: "md",
jstl: "jstl",
html: "html",
hbs: "hbs",
mustache: "mustache",
haml: "haml",
pug: "pug",
njk: "njk",
liquid: "liquid",
"11ty.js": "11ty.js"
};
for (let extension in aliases) {
fileExtensionToKeyMap[extension] = aliases[extension];
}
return fileExtensionToKeyMap;
}
}
module.exports = EleventyExtensionMap;

349
node_modules/@11ty/eleventy/src/EleventyFiles.js generated vendored Normal file
View File

@@ -0,0 +1,349 @@
const fs = require("fs-extra");
const fastglob = require("fast-glob");
const EleventyExtensionMap = require("./EleventyExtensionMap");
const TemplateData = require("./TemplateData");
const TemplateGlob = require("./TemplateGlob");
const TemplatePath = require("./TemplatePath");
const TemplatePassthroughManager = require("./TemplatePassthroughManager");
const config = require("./Config");
const debug = require("debug")("Eleventy:EleventyFiles");
// const debugDev = require("debug")("Dev:Eleventy:EleventyFiles");
class EleventyFiles {
constructor(input, outputDir, formats, passthroughAll) {
this.config = config.getConfig();
this.input = input;
this.inputDir = TemplatePath.getDir(this.input);
this.outputDir = outputDir;
this.initConfig();
this.passthroughAll = !!passthroughAll;
this.formats = formats;
this.extensionMap = new EleventyExtensionMap(formats);
}
initConfig() {
this.includesDir = TemplatePath.join(
this.inputDir,
this.config.dir.includes
);
if ("layouts" in this.config.dir) {
this.layoutsDir = TemplatePath.join(
this.inputDir,
this.config.dir.layouts
);
}
}
init() {
this.initFormatsGlobs();
this.setPassthroughManager();
this.setupGlobs();
}
restart() {
this.passthroughManager.reset();
this.setupGlobs();
}
/* For testing */
_setConfig(config) {
this.config = config;
this.initConfig();
}
/* For testing */
_setExtensionMap(map) {
this.extensionMap = map;
}
/* Set command root for local project paths */
_setLocalPathRoot(dir) {
this.localPathRoot = dir;
}
setPassthroughAll(passthroughAll) {
this.passthroughAll = !!passthroughAll;
}
initFormatsGlobs() {
// Input was a directory
if (this.input === this.inputDir) {
this.templateGlobs = TemplateGlob.map(
this.extensionMap.getGlobs(this.inputDir)
);
} else {
this.templateGlobs = TemplateGlob.map([this.input]);
}
}
getPassthroughManager() {
return this.passthroughManager;
}
setPassthroughManager(mgr) {
if (!mgr) {
mgr = new TemplatePassthroughManager();
mgr.setInputDir(this.inputDir);
mgr.setOutputDir(this.outputDir);
}
this.passthroughManager = mgr;
}
setTemplateData(templateData) {
this.templateData = templateData;
}
// TODO make this a getter
getTemplateData() {
if (!this.templateData) {
this.templateData = new TemplateData(this.inputDir);
}
return this.templateData;
}
getDataDir() {
let data = this.getTemplateData();
return data.getDataDir();
}
setupGlobs() {
this.ignores = this.getIgnores();
if (this.passthroughAll) {
this.watchedGlobs = TemplateGlob.map([
TemplateGlob.normalizePath(this.input, "/**")
]).concat(this.ignores);
} else {
this.watchedGlobs = this.templateGlobs.concat(this.ignores);
}
this.templateGlobsWithIgnores = this.watchedGlobs.concat(
this.getTemplateIgnores()
);
}
static getFileIgnores(ignoreFiles, defaultIfFileDoesNotExist) {
if (!Array.isArray(ignoreFiles)) {
ignoreFiles = [ignoreFiles];
}
let ignores = [];
let fileFound = false;
let dirs = [];
for (let ignorePath of ignoreFiles) {
ignorePath = TemplatePath.normalize(ignorePath);
let dir = TemplatePath.getDirFromFilePath(ignorePath);
dirs.push(dir);
if (fs.existsSync(ignorePath) && fs.statSync(ignorePath).size > 0) {
fileFound = true;
let ignoreContent = fs.readFileSync(ignorePath, "utf-8");
// make sure that empty .gitignore with spaces takes default ignore.
if (ignoreContent.trim().length === 0) {
fileFound = false;
} else {
ignores = ignores.concat(
EleventyFiles.normalizeIgnoreContent(dir, ignoreContent)
);
}
}
}
if (!fileFound && defaultIfFileDoesNotExist) {
ignores.push("!" + TemplateGlob.normalizePath(defaultIfFileDoesNotExist));
for (let dir of dirs) {
ignores.push(
"!" + TemplateGlob.normalizePath(dir, defaultIfFileDoesNotExist)
);
}
}
ignores.forEach(function(path) {
debug(`${ignoreFiles} ignoring: ${path}`);
});
return ignores;
}
static normalizeIgnoreContent(dir, ignoreContent) {
let ignores = [];
if (ignoreContent) {
ignores = ignoreContent
.split("\n")
.map(line => {
return line.trim();
})
.filter(line => {
// empty lines or comments get filtered out
return line.length > 0 && line.charAt(0) !== "#";
})
.map(line => {
let path = TemplateGlob.normalizePath(dir, "/", line);
path = TemplatePath.addLeadingDotSlash(
TemplatePath.relativePath(path)
);
try {
// Note these folders must exist to get /** suffix
let stat = fs.statSync(path);
if (stat.isDirectory()) {
return "!" + path + "/**";
}
return "!" + path;
} catch (e) {
return "!" + path;
}
});
}
return ignores;
}
getIgnores() {
let files = [];
if (this.config.useGitIgnore) {
files = files.concat(
EleventyFiles.getFileIgnores(
[
TemplatePath.join(
this.localPathRoot || TemplatePath.getWorkingDir(),
".gitignore"
),
TemplatePath.join(this.inputDir, ".gitignore")
],
"node_modules/**"
)
);
}
if (this.config.eleventyignoreOverride !== false) {
let eleventyIgnores = [
TemplatePath.join(
this.localPathRoot || TemplatePath.getWorkingDir(),
".eleventyignore"
),
TemplatePath.join(this.inputDir, ".eleventyignore")
];
files = files.concat(
this.config.eleventyignoreOverride ||
EleventyFiles.getFileIgnores(eleventyIgnores)
);
}
files = files.concat(TemplateGlob.map("!" + this.outputDir + "/**"));
return files;
}
getIncludesDir() {
return this.includesDir;
}
getLayoutsDir() {
return this.layoutsDir;
}
getFileGlobs() {
return this.templateGlobsWithIgnores;
}
getRawFiles() {
return this.templateGlobs;
}
getWatchPathCache() {
return this.pathCache;
}
async getFiles() {
let globs = this.getFileGlobs();
debug("Searching for: %o", globs);
let paths = TemplatePath.addLeadingDotSlashArray(
await fastglob(globs, {
caseSensitiveMatch: false,
dot: true
})
);
this.pathCache = paths;
return paths;
}
getGlobWatcherFiles() {
// TODO is it better to tie the includes and data to specific file extensions or keep the **?
return this.templateGlobs
.concat(this.getIncludesAndDataDirs())
.concat(this.getPassthroughManager().getConfigPathGlobs());
}
async getGlobWatcherTemplateDataFiles() {
let templateData = this.getTemplateData();
return await templateData.getTemplateDataFileGlob();
}
// TODO this isnt great but reduces complexity avoiding using TemplateData:getLocalDataPaths for each template in the cache
async getWatcherTemplateJavaScriptDataFiles() {
let globs = await this.getTemplateData().getTemplateJavaScriptDataFileGlob();
return TemplatePath.addLeadingDotSlashArray(
await fastglob(globs, {
ignore: ["**/node_modules/**"],
caseSensitiveMatch: false,
dot: true
})
);
}
getGlobWatcherIgnores() {
// convert to format without ! since they are passed in as a separate argument to glob watcher
return this.ignores.map(ignore =>
TemplatePath.stripLeadingDotSlash(ignore.substr(1))
);
}
getPassthroughPaths() {
let paths = [];
paths = paths.concat(this.passthroughManager.getConfigPaths());
// These are already added in the root templateGlobs
// paths = paths.concat(this.extensionMap.getPrunedGlobs(this.inputDir));
return paths;
}
getIncludesAndDataDirs() {
let files = [];
// we want this to fail on "" because we dont want to ignore the
// entire input directory when using ""
if (this.config.dir.includes) {
files = files.concat(TemplateGlob.map(this.includesDir + "/**"));
}
// we want this to fail on "" because we dont want to ignore the
// entire input directory when using ""
if (this.config.dir.layouts) {
files = files.concat(TemplateGlob.map(this.layoutsDir + "/**"));
}
if (this.config.dir.data && this.config.dir.data !== ".") {
let dataDir = this.getDataDir();
files = files.concat(TemplateGlob.map(dataDir + "/**"));
}
return files;
}
getTemplateIgnores() {
return this.getIncludesAndDataDirs().map(function(dir) {
return "!" + dir;
});
}
}
module.exports = EleventyFiles;

176
node_modules/@11ty/eleventy/src/EleventyServe.js generated vendored Normal file
View File

@@ -0,0 +1,176 @@
const fs = require("fs-extra");
const TemplatePath = require("./TemplatePath");
const config = require("./Config");
const debug = require("debug")("EleventyServe");
class EleventyServe {
constructor() {}
get config() {
return this.configOverride || config.getConfig();
}
set config(config) {
this.configOverride = config;
}
setOutputDir(outputDir) {
this.outputDir = outputDir;
}
getPathPrefix() {
return this.config.pathPrefix || "/";
}
getRedirectDir(dirName) {
return TemplatePath.join(this.outputDir, dirName);
}
getRedirectDirOverride() {
// has a pathPrefix, add a /index.html template to redirect to /pathPrefix/
if (this.getPathPrefix() !== "/") {
return "_eleventy_redirect";
}
}
getRedirectFilename(dirName) {
return TemplatePath.join(this.getRedirectDir(dirName), "index.html");
}
getOptions(port) {
let pathPrefix = this.getPathPrefix();
// TODO customize this in Configuration API?
let serverConfig = {
baseDir: this.outputDir
};
let redirectDirName = this.getRedirectDirOverride();
// has a pathPrefix, add a /index.html template to redirect to /pathPrefix/
if (redirectDirName) {
serverConfig.baseDir = this.getRedirectDir(redirectDirName);
serverConfig.routes = {};
serverConfig.routes[pathPrefix] = this.outputDir;
// if has a savedPathPrefix, use the /savedPathPrefix/index.html template to redirect to /pathPrefix/
if (this.savedPathPrefix) {
serverConfig.routes[this.savedPathPrefix] = TemplatePath.join(
this.outputDir,
this.savedPathPrefix
);
}
}
return Object.assign(
{
server: serverConfig,
port: port || 8080,
ignore: ["node_modules"],
watch: false,
open: false,
notify: false,
index: "index.html"
},
this.config.browserSyncConfig
);
}
cleanupRedirect(dirName) {
if (dirName && dirName !== "/") {
let savedPathFilename = this.getRedirectFilename(dirName);
setTimeout(function() {
if (!fs.existsSync(savedPathFilename)) {
debug(`Cleanup redirect: Could not find ${savedPathFilename}`);
return;
}
let savedPathContent = fs.readFileSync(savedPathFilename, "utf-8");
if (
savedPathContent.indexOf("Browsersync pathPrefix Redirect") === -1
) {
debug(
`Cleanup redirect: Found ${savedPathFilename} but it wasnt an eleventy redirect.`
);
return;
}
fs.unlink(savedPathFilename, err => {
if (!err) {
debug(`Cleanup redirect: Deleted ${savedPathFilename}`);
}
});
}, 2000);
}
}
serveRedirect(dirName) {
fs.outputFile(
this.getRedirectFilename(dirName),
`<!doctype html>
<meta http-equiv="refresh" content="0; url=${this.config.pathPrefix}">
<title>Browsersync pathPrefix Redirect</title>
<a href="${this.config.pathPrefix}">Go to ${this.config.pathPrefix}</a>`
);
}
serve(port) {
// only load on serve—this is pretty expensive
const browserSync = require("browser-sync");
this.server = browserSync.create();
let pathPrefix = this.getPathPrefix();
if (this.savedPathPrefix && pathPrefix !== this.savedPathPrefix) {
let redirectFilename = this.getRedirectFilename(this.savedPathPrefix);
if (!fs.existsSync(redirectFilename)) {
debug(
`Redirecting BrowserSync from ${
this.savedPathPrefix
} to ${pathPrefix}`
);
this.serveRedirect(this.savedPathPrefix);
} else {
debug(
`Config updated with a new pathPrefix. Tried to set up a transparent redirect but found a template already existing at ${redirectFilename}. Youll have to navigate manually.`
);
}
}
let redirectDirName = this.getRedirectDirOverride();
// has a pathPrefix, add a /index.html template to redirect to /pathPrefix/
if (redirectDirName) {
this.serveRedirect(redirectDirName);
}
this.cleanupRedirect(this.savedPathPrefix);
this.server.init(this.getOptions(port));
// this needs to happen after `.getOptions`
this.savedPathPrefix = pathPrefix;
}
close() {
if (this.server) {
this.server.exit();
}
}
reload(path, isInclude) {
if (this.server) {
if (this.getPathPrefix() !== this.savedPathPrefix) {
this.server.exit();
this.serve();
} else {
// Is a CSS input file and is not in the includes folder
// TODO check output path file extension of this template (not input path)
if (path && path.split(".").pop() === "css" && !isInclude) {
this.server.reload("*.css");
} else {
this.server.reload();
}
}
}
}
}
module.exports = EleventyServe;

125
node_modules/@11ty/eleventy/src/EleventyWatchTargets.js generated vendored Normal file
View File

@@ -0,0 +1,125 @@
const dependencyTree = require("dependency-tree");
const TemplatePath = require("./TemplatePath");
class EleventyWatchTargets {
constructor() {
this.targets = new Set();
this.dependencies = new Set();
this.newTargets = new Set();
this._watchJavaScriptDependencies = true;
}
set watchJavaScriptDependencies(watch) {
this._watchJavaScriptDependencies = !!watch;
}
get watchJavaScriptDependencies() {
return this._watchJavaScriptDependencies;
}
_normalizeTargets(targets) {
if (!targets) {
return [];
} else if (Array.isArray(targets)) {
return targets;
}
return [targets];
}
reset() {
this.newTargets = new Set();
}
isWatched(target) {
return this.targets.has(target);
}
addRaw(targets, isDependency) {
for (let target of targets) {
let path = TemplatePath.addLeadingDotSlash(target);
if (!this.isWatched(path)) {
this.newTargets.add(path);
}
this.targets.add(path);
if (isDependency) {
this.dependencies.add(path);
}
}
}
// add only a target
add(targets) {
targets = this._normalizeTargets(targets);
this.addRaw(targets);
}
// add only a targets dependencies
addDependencies(targets, filterCallback) {
if (!this.watchJavaScriptDependencies) {
return;
}
targets = this._normalizeTargets(targets);
let deps = this.getJavaScriptDependenciesFromList(targets);
if (filterCallback) {
deps = deps.filter(filterCallback);
}
this.addRaw(deps, true);
}
setWriter(templateWriter) {
this.writer = templateWriter;
}
getJavaScriptDependenciesFromList(files = []) {
let depSet = new Set();
files
.filter(file => file.endsWith(".js")) // TODO does this need to work with aliasing? what other JS extensions will have deps?
.forEach(file => {
dependencyTree
.toList({
filename: file,
directory: TemplatePath.absolutePath(),
filter: function(path) {
return path.indexOf("node_modules") === -1;
}
})
.map(dependency => {
return TemplatePath.addLeadingDotSlash(
TemplatePath.relativePath(dependency)
);
})
.filter(dependency => {
return (
dependency !== file && dependency.indexOf("node_modules") === -1
);
})
.forEach(dependency => {
depSet.add(dependency);
});
});
return Array.from(depSet);
}
clearDependencyRequireCache() {
for (let path of this.dependencies) {
delete require.cache[TemplatePath.absolutePath(path)];
}
}
getNewTargetsSinceLastReset() {
return Array.from(this.newTargets);
}
getTargets() {
return Array.from(this.targets);
}
}
module.exports = EleventyWatchTargets;

57
node_modules/@11ty/eleventy/src/Engines/Ejs.js generated vendored Normal file
View File

@@ -0,0 +1,57 @@
const ejsLib = require("ejs");
const TemplateEngine = require("./TemplateEngine");
const config = require("../Config");
class Ejs extends TemplateEngine {
constructor(name, includesDir) {
super(name, includesDir);
this.ejsOptions = {};
this.setLibrary(this.config.libraryOverrides.ejs);
this.setEjsOptions(this.config.ejsOptions);
}
setLibrary(lib) {
this.ejsLib = lib || ejsLib;
this.setEngineLib(this.ejsLib);
}
getEngine() {
return this.ejsLib;
}
setEjsOptions(options) {
this.ejsOptions = options;
}
getEjsOptions() {
let includesDir = super.getIncludesDir();
return Object.assign(
{
root: "./" + includesDir,
compileDebug: true,
filename: "./" + includesDir
},
this.ejsOptions || {}
);
}
async compile(str, inputPath) {
let options = this.getEjsOptions();
if (!inputPath || inputPath === "ejs" || inputPath === "md") {
// do nothing
} else {
options.filename = inputPath;
}
let fn = this.ejsLib.compile(str, options);
return function(data) {
return fn(data);
};
}
}
module.exports = Ejs;

22
node_modules/@11ty/eleventy/src/Engines/Haml.js generated vendored Normal file
View File

@@ -0,0 +1,22 @@
const HamlLib = require("hamljs");
const TemplateEngine = require("./TemplateEngine");
const config = require("../Config");
class Haml extends TemplateEngine {
constructor(name, includesDir) {
super(name, includesDir);
this.setLibrary(this.config.libraryOverrides.haml);
}
setLibrary(lib) {
this.hamlLib = lib || HamlLib;
this.setEngineLib(lib);
}
async compile(str) {
return this.hamlLib.compile(str);
}
}
module.exports = Haml;

66
node_modules/@11ty/eleventy/src/Engines/Handlebars.js generated vendored Normal file
View File

@@ -0,0 +1,66 @@
const HandlebarsLib = require("handlebars");
const TemplateEngine = require("./TemplateEngine");
const config = require("../Config");
class Handlebars extends TemplateEngine {
constructor(name, includesDir) {
super(name, includesDir);
this.setLibrary(this.config.libraryOverrides.hbs);
}
setLibrary(lib) {
this.handlebarsLib = lib || HandlebarsLib;
this.setEngineLib(this.handlebarsLib);
let partials = super.getPartials();
for (let name in partials) {
this.handlebarsLib.registerPartial(name, partials[name]);
}
// TODO these all go to the same place (addHelper), add warnings for overwrites
this.addHelpers(this.config.handlebarsHelpers);
this.addShortcodes(this.config.handlebarsShortcodes);
this.addPairedShortcodes(this.config.handlebarsPairedShortcodes);
}
addHelper(name, callback) {
this.handlebarsLib.registerHelper(name, callback);
}
addHelpers(helpers) {
for (let name in helpers) {
this.addHelper(name, helpers[name]);
}
}
addShortcodes(shortcodes) {
for (let name in shortcodes) {
this.addHelper(name, shortcodes[name]);
}
}
addPairedShortcodes(shortcodes) {
for (let name in shortcodes) {
let callback = shortcodes[name];
this.addHelper(name, function(...args) {
let options = args[args.length - 1];
let content = "";
if (options && options.fn) {
content = options.fn(this);
}
return callback.apply(this, [content, ...args]);
});
}
}
async compile(str, inputPath) {
let fn = this.handlebarsLib.compile(str);
return function(data) {
return fn(data);
};
}
}
module.exports = Handlebars;

24
node_modules/@11ty/eleventy/src/Engines/Html.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
const TemplateEngine = require("./TemplateEngine");
class Html extends TemplateEngine {
async compile(str, inputPath, preTemplateEngine) {
if (preTemplateEngine) {
let engine = TemplateEngine.getEngine(
preTemplateEngine,
super.getIncludesDir()
);
let fn = await engine.compile(str, inputPath);
return async function(data) {
return fn(data);
};
} else {
return function(data) {
// do nothing with data if parseHtmlWith is falsy
return str;
};
}
}
}
module.exports = Html;

121
node_modules/@11ty/eleventy/src/Engines/JavaScript.js generated vendored Normal file
View File

@@ -0,0 +1,121 @@
const TemplateEngine = require("./TemplateEngine");
const TemplatePath = require("../TemplatePath");
const EleventyBaseError = require("../EleventyBaseError");
class JavaScriptTemplateInvalidDataFormatError extends EleventyBaseError {}
class JavaScript extends TemplateEngine {
constructor(name, includesDir) {
super(name, includesDir);
this.instances = {};
}
normalize(result) {
if (Buffer.isBuffer(result)) {
return result.toString();
}
return result;
}
// String, Buffer, Promise
// Function, Class
// Object
_getInstance(mod) {
let noop = function() {
return "";
};
if (typeof mod === "string" || mod instanceof Buffer || mod.then) {
return { render: () => mod };
} else if (typeof mod === "function") {
if (
mod.prototype &&
("data" in mod.prototype || "render" in mod.prototype)
) {
if (!("render" in mod.prototype)) {
mod.prototype.render = noop;
}
return new mod();
} else {
return { render: mod };
}
} else if ("data" in mod || "render" in mod) {
if (!("render" in mod)) {
mod.render = noop;
}
return mod;
}
}
getInstanceFromInputPath(inputPath) {
if (this.instances[inputPath]) {
return this.instances[inputPath];
}
const mod = this._getRequire(inputPath);
let inst = this._getInstance(mod);
this.instances[inputPath] = inst;
return inst;
}
_getRequire(inputPath) {
let requirePath = TemplatePath.absolutePath(inputPath);
return require(requirePath);
}
needsToReadFileContents() {
return false;
}
// only remove from cache once on startup (if it already exists)
initRequireCache(inputPath) {
let requirePath = TemplatePath.absolutePath(inputPath);
if (requirePath in require.cache) {
delete require.cache[requirePath];
}
if (inputPath in this.instances) {
delete this.instances[inputPath];
}
}
async getExtraDataFromFile(inputPath) {
let inst = this.getInstanceFromInputPath(inputPath);
if (inst && "data" in inst) {
// get extra data from `data` method,
// either as a function or getter or object literal
let result = await (typeof inst.data === "function"
? inst.data()
: inst.data);
if (typeof result !== "object") {
throw new JavaScriptTemplateInvalidDataFormatError(
`Invalid data format returned from ${inputPath}: typeof ${typeof result}`
);
}
return result;
}
}
async compile(str, inputPath) {
let inst;
if (str) {
// When str has a value, it's being used for permalinks in data
inst = this._getInstance(str);
} else {
// For normal templates, str will be falsy.
inst = this.getInstanceFromInputPath(inputPath);
}
if (inst && "render" in inst) {
Object.assign(inst, this.config.javascriptFunctions);
return function(data) {
return this.normalize(inst.render.call(inst, data));
}.bind(this);
}
}
}
module.exports = JavaScript;

View File

@@ -0,0 +1,63 @@
const javascriptStringify = require("javascript-stringify");
const TemplateEngine = require("./TemplateEngine");
const EleventyBaseError = require("../EleventyBaseError");
class JavaScriptTemplateLiteralCompileError extends EleventyBaseError {}
class JavaScriptTemplateLiteral extends TemplateEngine {
// add ` around template if it doesnt exist.
static normalizeTicks(str) {
// TODO make this work with tagged templates html``
let trimmedStr = str.trim();
if (
trimmedStr.charAt(0) === "`" &&
trimmedStr.charAt(trimmedStr.length - 1) === "`"
) {
str =
"`" +
trimmedStr.substr(1, trimmedStr.length - 2).replace(/`/g, "\\`") +
"`";
} else {
str =
"`" +
str.replace(/`/g, "\\`") +
(trimmedStr.charAt(trimmedStr.length - 1) === "`" ? "\n" : "") +
"`";
}
return str;
}
async compile(str, inputPath) {
return function(data) {
// avoid `with`
let dataStr = "";
for (let j in data) {
dataStr += `let ${j} = ${javascriptStringify.stringify(
data[j],
null,
null,
{
references: true
}
)};\n`;
}
let evalStr = `${dataStr}\n${JavaScriptTemplateLiteral.normalizeTicks(
str
)};`;
try {
// TODO switch to https://www.npmjs.com/package/es6-template-strings
let val = eval(evalStr);
return val;
} catch (e) {
throw new JavaScriptTemplateLiteralCompileError(
`Broken ES6 template:\n${evalStr}`,
e
);
}
};
}
}
module.exports = JavaScriptTemplateLiteral;

199
node_modules/@11ty/eleventy/src/Engines/Liquid.js generated vendored Normal file
View File

@@ -0,0 +1,199 @@
const moo = require("moo");
const LiquidLib = require("liquidjs");
const TemplateEngine = require("./TemplateEngine");
const TemplatePath = require("../TemplatePath");
// const debug = require("debug")("Eleventy:Liquid");
class Liquid extends TemplateEngine {
constructor(name, includesDir) {
super(name, includesDir);
this.liquidOptions = {};
this.setLibrary(this.config.libraryOverrides.liquid);
this.setLiquidOptions(this.config.liquidOptions);
this.argLexer = moo.compile({
number: /[0-9]+\.*[0-9]*/,
doubleQuoteString: /"(?:\\["\\]|[^\n"\\])*"/,
singleQuoteString: /'(?:\\['\\]|[^\n'\\])*'/,
keyword: /[a-zA-Z0-9\.\-\_]+/,
"ignore:whitespace": /[, \t]+/ // includes comma separator
});
}
setLibrary(lib) {
this.liquidLibOverride = lib;
// warning, the include syntax supported here does not exactly match what Jekyll uses.
this.liquidLib = lib || LiquidLib(this.getLiquidOptions());
this.setEngineLib(this.liquidLib);
this.addFilters(this.config.liquidFilters);
// TODO these all go to the same place (addTag), add warnings for overwrites
this.addCustomTags(this.config.liquidTags);
this.addAllShortcodes(this.config.liquidShortcodes);
this.addAllPairedShortcodes(this.config.liquidPairedShortcodes);
}
setLiquidOptions(options) {
this.liquidOptions = options;
this.setLibrary(this.liquidLibOverride);
}
getLiquidOptions() {
let defaults = {
root: [super.getIncludesDir()], // overrides in compile with inputPath below
extname: ".liquid",
dynamicPartials: false,
strict_filters: false
};
let options = Object.assign(defaults, this.liquidOptions || {});
// debug("Liquid constructor options: %o", options);
return options;
}
addCustomTags(tags) {
for (let name in tags) {
this.addTag(name, tags[name]);
}
}
addFilters(filters) {
for (let name in filters) {
this.addFilter(name, filters[name]);
}
}
addFilter(name, filter) {
this.liquidLib.registerFilter(name, filter);
}
addTag(name, tagFn) {
let tagObj;
if (typeof tagFn === "function") {
tagObj = tagFn(this.liquidLib);
} else {
throw new Error(
"Liquid.addTag expects a callback function to be passed in: addTag(name, function(liquidEngine) { return { parse: …, render: … } })"
);
}
this.liquidLib.registerTag(name, tagObj);
}
addAllShortcodes(shortcodes) {
for (let name in shortcodes) {
this.addShortcode(name, shortcodes[name]);
}
}
addAllPairedShortcodes(shortcodes) {
for (let name in shortcodes) {
this.addPairedShortcode(name, shortcodes[name]);
}
}
static parseArguments(lexer, str, scope) {
let argArray = [];
if (typeof str === "string") {
// TODO key=value key2=value
// TODO JSON?
lexer.reset(str);
let arg = lexer.next();
while (arg) {
/*{
type: 'doubleQuoteString',
value: '"test 2"',
text: '"test 2"',
toString: [Function: tokenToString],
offset: 0,
lineBreaks: 0,
line: 1,
col: 1 }*/
if (arg.type.indexOf("ignore:") === -1) {
argArray.push(LiquidLib.evalExp(arg.value, scope)); // or evalValue
}
arg = lexer.next();
}
}
return argArray;
}
addShortcode(shortcodeName, shortcodeFn) {
let _t = this;
this.addTag(shortcodeName, function(liquidEngine) {
return {
parse: function(tagToken, remainTokens) {
this.name = tagToken.name;
this.args = tagToken.args;
},
render: function(scope, hash) {
let argArray = Liquid.parseArguments(_t.argLexer, this.args, scope);
return Promise.resolve(shortcodeFn(...argArray));
}
};
});
}
addPairedShortcode(shortcodeName, shortcodeFn) {
let _t = this;
this.addTag(shortcodeName, function(liquidEngine) {
return {
parse: function(tagToken, remainTokens) {
this.name = tagToken.name;
this.args = tagToken.args;
this.templates = [];
var stream = liquidEngine.parser
.parseStream(remainTokens)
.on("template", tpl => this.templates.push(tpl))
.on("tag:end" + shortcodeName, token => stream.stop())
.on("end", x => {
throw new Error(`tag ${tagToken.raw} not closed`);
});
stream.start();
},
render: function(scope, hash) {
let argArray = Liquid.parseArguments(_t.argLexer, this.args, scope);
return new Promise((resolve, reject) => {
liquidEngine.renderer
.renderTemplates(this.templates, scope)
.then(function(html) {
resolve(shortcodeFn(html, ...argArray));
});
});
}
};
});
}
async compile(str, inputPath) {
let engine = this.liquidLib;
let tmpl = await engine.parse(str, inputPath);
// Required for relative includes
let options = {};
if (!inputPath || inputPath === "njk" || inputPath === "md") {
// do nothing
} else {
options.root = [
super.getIncludesDir(),
TemplatePath.getDirFromFilePath(inputPath)
];
}
return async function(data) {
return engine.render(tmpl, data, options);
};
}
}
module.exports = Liquid;

91
node_modules/@11ty/eleventy/src/Engines/Markdown.js generated vendored Normal file
View File

@@ -0,0 +1,91 @@
const markdownIt = require("markdown-it");
const TemplateEngine = require("./TemplateEngine");
const config = require("../Config");
// const debug = require("debug")("Eleventy:Markdown");
class Markdown extends TemplateEngine {
constructor(name, includesDir) {
super(name, includesDir);
this.markdownOptions = {};
this.setLibrary(this.config.libraryOverrides.md);
}
setLibrary(mdLib) {
this.mdLib = mdLib || markdownIt(this.getMarkdownOptions());
// Overrides a highlighter set in `markdownOptions`
// This is separate so devs can pass in a new mdLib and still use the official eleventy plugin for markdown highlighting
if (this.config.markdownHighlighter) {
this.mdLib.set({
highlight: this.config.markdownHighlighter
});
}
this.setEngineLib(this.mdLib);
}
setMarkdownOptions(options) {
this.markdownOptions = options;
}
getMarkdownOptions() {
// work with "mode" presets https://github.com/markdown-it/markdown-it#init-with-presets-and-options
if (typeof this.markdownOptions === "string") {
return this.markdownOptions;
}
return Object.assign(
{
html: true
},
this.markdownOptions || {}
);
}
async compile(str, inputPath, preTemplateEngine, bypassMarkdown) {
let mdlib = this.mdLib;
if (preTemplateEngine) {
let fn;
let engine;
if (typeof preTemplateEngine === "string") {
engine = TemplateEngine.getEngine(
preTemplateEngine,
super.getIncludesDir()
);
} else {
engine = preTemplateEngine;
}
fn = await engine.compile(str, inputPath);
if (bypassMarkdown) {
return async function(data) {
return fn(data);
};
} else {
return async function(data) {
let preTemplateEngineRender = await fn(data);
let finishedRender = mdlib.render(preTemplateEngineRender);
return finishedRender;
};
}
} else {
if (bypassMarkdown) {
return function() {
return str;
};
} else {
return function() {
// throw away data if preTemplateEngine is falsy
return mdlib.render(str);
};
}
}
}
}
module.exports = Markdown;

25
node_modules/@11ty/eleventy/src/Engines/Mustache.js generated vendored Normal file
View File

@@ -0,0 +1,25 @@
const MustacheLib = require("mustache");
const TemplateEngine = require("./TemplateEngine");
class Mustache extends TemplateEngine {
constructor(name, includesDir) {
super(name, includesDir);
this.setLibrary(this.config.libraryOverrides.mustache);
}
setLibrary(lib) {
this.mustacheLib = lib || MustacheLib;
this.setEngineLib(this.mustacheLib);
}
async compile(str, inputPath) {
let partials = super.getPartials();
return function(data) {
return this.render(str, data, partials).trim();
}.bind(this.mustacheLib);
}
}
module.exports = Mustache;

157
node_modules/@11ty/eleventy/src/Engines/Nunjucks.js generated vendored Normal file
View File

@@ -0,0 +1,157 @@
const NunjucksLib = require("nunjucks");
const TemplateEngine = require("./TemplateEngine");
const TemplatePath = require("../TemplatePath");
class Nunjucks extends TemplateEngine {
constructor(name, includesDir) {
super(name, includesDir);
this.setLibrary(this.config.libraryOverrides.njk);
}
setLibrary(env) {
this.njkEnv =
env ||
new NunjucksLib.Environment(
new NunjucksLib.FileSystemLoader([
super.getIncludesDir(),
TemplatePath.getWorkingDir()
])
);
this.setEngineLib(this.njkEnv);
this.addFilters(this.config.nunjucksFilters);
this.addFilters(this.config.nunjucksAsyncFilters, true);
// TODO these all go to the same place (addTag), add warnings for overwrites
this.addCustomTags(this.config.nunjucksTags);
this.addAllShortcodes(this.config.nunjucksShortcodes);
this.addAllPairedShortcodes(this.config.nunjucksPairedShortcodes);
}
addFilters(helpers, isAsync) {
for (let name in helpers) {
this.njkEnv.addFilter(name, helpers[name], isAsync);
}
}
addCustomTags(tags) {
for (let name in tags) {
this.addTag(name, tags[name]);
}
}
addTag(name, tagFn) {
let tagObj;
if (typeof tagFn === "function") {
tagObj = tagFn(NunjucksLib, this.njkEnv);
} else {
throw new Error(
"Nunjucks.addTag expects a callback function to be passed in: addTag(name, function(nunjucksEngine) {})"
);
}
this.njkEnv.addExtension(name, tagObj);
}
addAllShortcodes(shortcodes) {
for (let name in shortcodes) {
this.addShortcode(name, shortcodes[name]);
}
}
addAllPairedShortcodes(shortcodes) {
for (let name in shortcodes) {
this.addPairedShortcode(name, shortcodes[name]);
}
}
addShortcode(shortcodeName, shortcodeFn) {
function ShortcodeFunction() {
this.tags = [shortcodeName];
this.parse = function(parser, nodes, lexer) {
let args;
let tok = parser.nextToken();
args = parser.parseSignature(true, true);
// Nunjucks bug with non-paired custom tags bug still exists even
// though this issue is closed. Works fine for paired.
// https://github.com/mozilla/nunjucks/issues/158
if (args.children.length === 0) {
args.addChild(new nodes.Literal(0, 0, ""));
}
parser.advanceAfterBlockEnd(tok.value);
// return new nodes.CallExtensionAsync(this, "run", args);
return new nodes.CallExtension(this, "run", args);
};
this.run = function(...args) {
// let callback = args.pop();
let [context, ...argArray] = args;
let ret = new NunjucksLib.runtime.SafeString(shortcodeFn(...argArray));
// callback(null, ret);
return ret;
};
}
this.njkEnv.addExtension(shortcodeName, new ShortcodeFunction());
}
addPairedShortcode(shortcodeName, shortcodeFn) {
function PairedShortcodeFunction() {
this.tags = [shortcodeName];
this.parse = function(parser, nodes, lexer) {
var tok = parser.nextToken();
var args = parser.parseSignature(true, true);
parser.advanceAfterBlockEnd(tok.value);
var body = parser.parseUntilBlocks("end" + shortcodeName);
parser.advanceAfterBlockEnd();
// return new nodes.CallExtensionAsync(this, "run", args, [body]);
return new nodes.CallExtension(this, "run", args, [body]);
};
this.run = function(...args) {
// let callback = args.pop();
let body = args.pop();
let [context, ...argArray] = args;
let ret = new NunjucksLib.runtime.SafeString(
shortcodeFn(body(), ...argArray)
);
// callback(null, ret);
return ret;
};
}
this.njkEnv.addExtension(shortcodeName, new PairedShortcodeFunction());
}
async compile(str, inputPath) {
let tmpl;
if (!inputPath || inputPath === "njk" || inputPath === "md") {
tmpl = NunjucksLib.compile(str, this.njkEnv);
} else {
tmpl = NunjucksLib.compile(str, this.njkEnv, inputPath);
}
return async function(data) {
return new Promise(function(resolve, reject) {
tmpl.render(data, function(err, res) {
if (err) {
reject(err);
} else {
resolve(res);
}
});
});
};
}
}
module.exports = Nunjucks;

48
node_modules/@11ty/eleventy/src/Engines/Pug.js generated vendored Normal file
View File

@@ -0,0 +1,48 @@
const PugLib = require("pug");
const TemplateEngine = require("./TemplateEngine");
const TemplatePath = require("../TemplatePath");
class Pug extends TemplateEngine {
constructor(name, includesDir) {
super(name, includesDir);
this.pugOptions = {};
this.setLibrary(this.config.libraryOverrides.pug);
this.setPugOptions(this.config.pugOptions);
}
setLibrary(lib) {
this.pugLib = lib || PugLib;
this.setEngineLib(this.pugLib);
}
setPugOptions(options) {
this.pugOptions = options;
}
getPugOptions() {
let includesDir = super.getIncludesDir();
return Object.assign(
{
basedir: includesDir,
filename: includesDir
},
this.pugOptions || {}
);
}
async compile(str, inputPath) {
let options = this.getPugOptions();
if (!inputPath || inputPath === "pug" || inputPath === "md") {
// do nothing
} else {
options.filename = inputPath;
}
return this.pugLib.compile(str, options);
}
}
module.exports = Pug;

View File

@@ -0,0 +1,151 @@
const fastglob = require("fast-glob");
const fs = require("fs-extra");
const TemplatePath = require("../TemplatePath");
const EleventyExtensionMap = require("../EleventyExtensionMap");
const config = require("../Config");
const debug = require("debug")("Eleventy:TemplateEngine");
class TemplateEngine {
constructor(name, includesDir) {
this.name = name;
this.extensionMap = new EleventyExtensionMap();
this.extensions = this.extensionMap.getExtensionsFromKey(name);
this.includesDir = includesDir;
this.partialsHaveBeenCached = false;
this.partials = [];
this.engineLib = null;
}
get config() {
if (!this._config) {
this._config = config.getConfig();
}
return this._config;
}
set config(config) {
this._config = config;
}
getName() {
return this.name;
}
getIncludesDir() {
return this.includesDir;
}
// TODO make async
getPartials() {
if (!this.partialsHaveBeenCached) {
this.partials = this.cachePartialFiles();
}
return this.partials;
}
// TODO make async
cachePartialFiles() {
// This only runs if getPartials() is called, which is only for Mustache/Handlebars
this.partialsHaveBeenCached = true;
let partials = {};
let prefix = this.includesDir + "/**/*.";
// TODO: reuse mustache partials in handlebars?
let partialFiles = [];
if (this.includesDir) {
this.extensions.forEach(function(extension) {
partialFiles = partialFiles.concat(
fastglob.sync(prefix + extension, {
caseSensitiveMatch: false,
dot: true
})
);
});
}
partialFiles = TemplatePath.addLeadingDotSlashArray(partialFiles);
for (let j = 0, k = partialFiles.length; j < k; j++) {
let partialPath = TemplatePath.stripLeadingSubPath(
partialFiles[j],
this.includesDir
);
let partialPathNoExt = partialPath;
this.extensions.forEach(function(extension) {
partialPathNoExt = TemplatePath.removeExtension(
partialPathNoExt,
"." + extension
);
});
partials[partialPathNoExt] = fs.readFileSync(partialFiles[j], "utf-8");
}
debug(
`${this.includesDir}/*.{${this.extensions}} found partials for: %o`,
Object.keys(partials)
);
return partials;
}
setEngineLib(engineLib) {
this.engineLib = engineLib;
}
getEngineLib() {
return this.engineLib;
}
async render(str, data) {
/* TODO compile needs to pass in inputPath? */
let fn = await this.compile(str);
return fn(data);
}
// JavaScript files defer to the module loader rather than read the files to strings
needsToReadFileContents() {
return true;
}
getExtraDataFromFile(inputPath) {
return {};
}
initRequireCache(inputPath) {
// do nothing
}
static get templateKeyMapToClassName() {
return {
ejs: "Ejs",
md: "Markdown",
jstl: "JavaScriptTemplateLiteral",
html: "Html",
hbs: "Handlebars",
mustache: "Mustache",
haml: "Haml",
pug: "Pug",
njk: "Nunjucks",
liquid: "Liquid",
"11ty.js": "JavaScript"
};
}
static hasEngine(name) {
return name in TemplateEngine.templateKeyMapToClassName;
}
static getEngine(name, includesDir) {
if (!this.hasEngine(name)) {
throw new Error(
`Template Engine ${name} does not exist in getEngine (includes dir: ${includesDir})`
);
}
const cls = require("./" + TemplateEngine.templateKeyMapToClassName[name]);
return new cls(name, includesDir);
}
}
module.exports = TemplateEngine;

View File

@@ -0,0 +1,4 @@
const EleventyBaseError = require("../EleventyBaseError");
class TemplateContentPrematureUseError extends EleventyBaseError {}
module.exports = TemplateContentPrematureUseError;

View File

@@ -0,0 +1,5 @@
const EleventyBaseError = require("../EleventyBaseError");
class UsingCircularTemplateContentReferenceError extends EleventyBaseError {}
module.exports = UsingCircularTemplateContentReferenceError;

8
node_modules/@11ty/eleventy/src/Filters/Slug.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
const slugify = require("slugify");
module.exports = function(str) {
return slugify(str, {
replacement: "-",
lower: true
});
};

36
node_modules/@11ty/eleventy/src/Filters/Url.js generated vendored Normal file
View File

@@ -0,0 +1,36 @@
const validUrl = require("valid-url");
const TemplatePath = require("../TemplatePath");
module.exports = function(url, pathPrefix) {
// work with undefined
url = url || "";
if (
validUrl.isUri(url) ||
url.indexOf("http://") === 0 ||
url.indexOf("https://") === 0
) {
return url;
}
if (pathPrefix === undefined || typeof pathPrefix !== "string") {
let projectConfig = require("../Config").getConfig();
pathPrefix = projectConfig.pathPrefix;
}
let normUrl = TemplatePath.normalizeUrlPath(url);
let normRootDir = TemplatePath.normalizeUrlPath("/", pathPrefix);
let normFull = TemplatePath.normalizeUrlPath("/", pathPrefix, url);
let isRootDirTrailingSlash =
normRootDir.length && normRootDir.charAt(normRootDir.length - 1) === "/";
// minor difference with straight `normalize`, "" resolves to root dir and not "."
// minor difference with straight `normalize`, "/" resolves to root dir
if (normUrl === "/" || normUrl === normRootDir) {
return normRootDir + (!isRootDirTrailingSlash ? "/" : "");
} else if (normUrl.indexOf("/") === 0) {
return normFull;
}
return normUrl;
};

253
node_modules/@11ty/eleventy/src/Plugins/Pagination.js generated vendored Normal file
View File

@@ -0,0 +1,253 @@
const lodashChunk = require("lodash/chunk");
const lodashGet = require("lodash/get");
const lodashSet = require("lodash/set");
const EleventyBaseError = require("../EleventyBaseError");
const config = require("../Config");
class PaginationError extends EleventyBaseError {}
class Pagination {
constructor(data) {
this.config = config.getConfig();
this.setData(data);
}
static hasPagination(data) {
return "pagination" in data;
}
hasPagination() {
if (!this.data) {
throw new Error("Missing `setData` call for Pagination object.");
}
return Pagination.hasPagination(this.data);
}
circularReferenceCheck(data) {
if (data.eleventyExcludeFromCollections) {
return;
}
let key = data.pagination.data;
let tags = data.tags || [];
for (let tag of tags) {
if (`collections.${tag}` === key) {
throw new PaginationError(
`Pagination circular reference${
this.template ? ` on ${this.template.inputPath}` : ""
}, data:\`${key}\` iterates over both the \`${tag}\` tag and also supplies pages to that tag.`
);
}
}
}
setData(data) {
this.data = data || {};
this.target = [];
if (!this.hasPagination()) {
return;
}
if (!data.pagination) {
throw new Error(
"Misconfigured pagination data in template front matter (YAML front matter precaution: did you use tabs and not spaces for indentation?)."
);
} else if (!("size" in data.pagination)) {
throw new Error("Missing pagination size in front matter data.");
}
this.circularReferenceCheck(data);
this.size = data.pagination.size;
this.alias = data.pagination.alias;
this.target = this._resolveItems();
this.items = this.getPagedItems();
}
setTemplate(tmpl) {
this.template = tmpl;
}
_getDataKey() {
return this.data.pagination.data;
}
resolveObjectToValues() {
if ("resolve" in this.data.pagination) {
return this.data.pagination.resolve === "values";
}
return false;
}
isFiltered(value) {
if ("filter" in this.data.pagination) {
let filtered = this.data.pagination.filter;
if (Array.isArray(filtered)) {
return filtered.indexOf(value) > -1;
}
return filtered === value;
}
return false;
}
_resolveItems() {
let notFoundValue = "__NOT_FOUND_ERROR__";
let key = this._getDataKey();
let ret = lodashGet(this.data, key, notFoundValue);
if (ret === notFoundValue) {
throw new Error(
`Could not resolve pagination key in template data: ${key}`
);
}
if (!Array.isArray(ret)) {
if (this.resolveObjectToValues()) {
ret = Object.values(ret);
} else {
ret = Object.keys(ret);
}
}
let result = ret.filter(
function(value) {
return !this.isFiltered(value);
}.bind(this)
);
if (this.data.pagination.reverse === true) {
return result.reverse();
}
return result;
}
getPagedItems() {
// TODO switch to a getter
if (!this.data) {
throw new Error("Missing `setData` call for Pagination object.");
}
return lodashChunk(this.target, this.size);
}
// TODO this name is not good
// “To cancel” means to not write the original root template
cancel() {
return this.hasPagination();
}
getPageCount() {
if (!this.hasPagination()) {
return 0;
}
return this.items.length;
}
async getPageTemplates() {
if (!this.data) {
throw new Error("Missing `setData` call for Pagination object.");
}
if (!this.hasPagination()) {
return [];
}
if (this.pagesCache) {
return this.pagesCache;
}
let pages = [];
let items = this.items;
let tmpl = this.template;
let templates = [];
let links = [];
let hrefs = [];
let overrides = [];
for (let pageNumber = 0, k = items.length; pageNumber < k; pageNumber++) {
let cloned = tmpl.clone();
// TODO maybe also move this permalink additions up into the pagination class
if (pageNumber > 0 && !this.data[this.config.keys.permalink]) {
cloned.setExtraOutputSubdirectory(pageNumber);
}
templates.push(cloned);
let override = {
pagination: {
data: this.data.pagination.data,
size: this.data.pagination.size,
items: items[pageNumber],
pageNumber: pageNumber
}
};
if (this.alias) {
lodashSet(
override,
this.alias,
this.size === 1 ? items[pageNumber][0] : items[pageNumber]
);
}
overrides.push(override);
cloned.setPaginationData(override);
// TO DO subdirectory to links if the site doesnt live at /
links.push("/" + (await cloned.getOutputLink()));
hrefs.push(await cloned.getOutputHref());
}
// we loop twice to pass in the appropriate prev/next links (already full generated now)
templates.forEach(
function(cloned, pageNumber) {
// links
overrides[pageNumber].pagination.previousPageLink =
pageNumber > 0 ? links[pageNumber - 1] : null;
overrides[pageNumber].pagination.previous =
overrides[pageNumber].pagination.previousPageLink;
overrides[pageNumber].pagination.nextPageLink =
pageNumber < templates.length - 1 ? links[pageNumber + 1] : null;
overrides[pageNumber].pagination.next =
overrides[pageNumber].pagination.nextPageLink;
overrides[pageNumber].pagination.firstPageLink =
links.length > 0 ? links[0] : null;
overrides[pageNumber].pagination.lastPageLink =
links.length > 0 ? links[links.length - 1] : null;
overrides[pageNumber].pagination.links = links;
// todo deprecated, consistency with collections and use links instead
overrides[pageNumber].pagination.pageLinks = links;
// hrefs
overrides[pageNumber].pagination.previousPageHref =
pageNumber > 0 ? hrefs[pageNumber - 1] : null;
overrides[pageNumber].pagination.nextPageHref =
pageNumber < templates.length - 1 ? hrefs[pageNumber + 1] : null;
overrides[pageNumber].pagination.firstPageHref =
hrefs.length > 0 ? hrefs[0] : null;
overrides[pageNumber].pagination.lastPageHref =
hrefs.length > 0 ? hrefs[hrefs.length - 1] : null;
overrides[pageNumber].pagination.hrefs = hrefs;
cloned.setPaginationData(overrides[pageNumber]);
pages.push(cloned);
}.bind(this)
);
this.pagesCache = pages;
return pages;
}
}
module.exports = Pagination;

698
node_modules/@11ty/eleventy/src/Template.js generated vendored Normal file
View File

@@ -0,0 +1,698 @@
const fs = require("fs-extra");
const parsePath = require("parse-filepath");
const normalize = require("normalize-path");
const lodashIsObject = require("lodash/isObject");
const { DateTime } = require("luxon");
const EleventyExtensionMap = require("./EleventyExtensionMap");
const TemplateData = require("./TemplateData");
const TemplateContent = require("./TemplateContent");
const TemplatePath = require("./TemplatePath");
const TemplatePermalink = require("./TemplatePermalink");
const TemplatePermalinkNoWrite = require("./TemplatePermalinkNoWrite");
const TemplateLayout = require("./TemplateLayout");
const TemplateFileSlug = require("./TemplateFileSlug");
const Pagination = require("./Plugins/Pagination");
const TemplateContentPrematureUseError = require("./Errors/TemplateContentPrematureUseError");
const debug = require("debug")("Eleventy:Template");
const debugDev = require("debug")("Dev:Eleventy:Template");
class Template extends TemplateContent {
constructor(path, inputDir, outputDir, templateData) {
debugDev("new Template(%o)", path);
super(path, inputDir);
this.parsed = parsePath(path);
// for pagination
this.extraOutputSubdirectory = "";
if (outputDir) {
this.outputDir = normalize(outputDir);
} else {
this.outputDir = false;
}
this.linters = [];
this.transforms = [];
this.plugins = {};
this.templateData = templateData;
if (this.templateData) {
this.templateData.setInputDir(this.inputDir);
}
this.paginationData = {};
this.isVerbose = true;
this.isDryRun = false;
this.writeCount = 0;
this.wrapWithLayouts = true;
this.fileSlug = new TemplateFileSlug(this.inputPath, this.inputDir);
this.fileSlugStr = this.fileSlug.getSlug();
this.filePathStem = this.fileSlug.getFullPathWithoutExtension();
}
setIsVerbose(isVerbose) {
this.isVerbose = isVerbose;
}
setDryRun(isDryRun) {
this.isDryRun = !!isDryRun;
}
setWrapWithLayouts(wrap) {
this.wrapWithLayouts = wrap;
}
setExtraOutputSubdirectory(dir) {
this.extraOutputSubdirectory = dir + "/";
}
getTemplateSubfolder() {
return TemplatePath.stripLeadingSubPath(this.parsed.dir, this.inputDir);
}
get baseFile() {
return (this._extensionMap || EleventyExtensionMap).removeTemplateExtension(
this.parsed.base
);
}
get htmlIOException() {
// HTML output cant overwrite the HTML input file.
return (
this.inputDir === this.outputDir &&
this.templateRender.isEngine("html") &&
this.baseFile === "index"
);
}
async _getLink(data) {
if (!data) {
data = await this.getData();
}
let permalink = data[this.config.keys.permalink];
if (permalink) {
// render variables inside permalink front matter, bypass markdown
let permalinkValue;
if (!this.config.dynamicPermalinks || data.dynamicPermalink === false) {
debugDev("Not using dynamicPermalinks, using %o", permalink);
permalinkValue = permalink;
} else {
permalinkValue = await super.render(permalink, data, true);
debug(
"Rendering permalink for %o: %s becomes %o",
this.inputPath,
permalink,
permalinkValue
);
debugDev("Permalink rendered with data: %o", data);
}
let perm = new TemplatePermalink(
permalinkValue,
this.extraOutputSubdirectory
);
return perm;
} else if (permalink === false) {
return new TemplatePermalinkNoWrite();
}
return TemplatePermalink.generate(
this.getTemplateSubfolder(),
this.baseFile,
this.extraOutputSubdirectory,
this.htmlIOException ? this.config.htmlOutputSuffix : ""
);
}
// TODO instead of htmlIOException, do a global search to check if output path = input path and then add extra suffix
async getOutputLink(data) {
let link = await this._getLink(data);
return link.toString();
}
async getOutputHref(data) {
let link = await this._getLink(data);
return link.toHref();
}
// TODO check for conflicts, see if file already exists?
async getOutputPath(data) {
let uri = await this.getOutputLink(data);
if (uri === false) {
return false;
} else if (
(await this.getFrontMatterData())[this.config.keys.permalinkRoot]
) {
// TODO this only works with immediate front matter and not data files
return normalize(uri);
} else {
return normalize(this.outputDir + "/" + uri);
}
}
setPaginationData(paginationData) {
this.paginationData = paginationData;
}
async mapDataAsRenderedTemplates(data, templateData) {
// function supported in JavaScript type
if (typeof data === "string" || typeof data === "function") {
debug("rendering data.renderData for %o", this.inputPath);
// bypassMarkdown
let str = await super.render(data, templateData, true);
return str;
} else if (Array.isArray(data)) {
let arr = [];
for (let j = 0, k = data.length; j < k; j++) {
arr.push(await this.mapDataAsRenderedTemplates(data[j], templateData));
}
return arr;
} else if (lodashIsObject(data)) {
let obj = {};
for (let value in data) {
obj[value] = await this.mapDataAsRenderedTemplates(
data[value],
templateData
);
}
return obj;
}
return data;
}
async _testGetAllLayoutFrontMatterData() {
let frontMatterData = await this.getFrontMatterData();
if (frontMatterData[this.config.keys.layout]) {
let layout = TemplateLayout.getTemplate(
frontMatterData[this.config.keys.layout],
this.getInputDir(),
this.config
);
return await layout.getData();
}
return {};
}
async getData() {
if (!this.dataCache) {
debugDev("%o getData()", this.inputPath);
let localData = {};
if (this.templateData) {
localData = await this.templateData.getLocalData(this.inputPath);
debugDev("%o getData() getLocalData", this.inputPath);
}
let frontMatterData = await this.getFrontMatterData();
let foundLayout =
frontMatterData[this.config.keys.layout] ||
localData[this.config.keys.layout];
let mergedLayoutData = {};
if (foundLayout) {
let layout = TemplateLayout.getTemplate(
foundLayout,
this.getInputDir(),
this.config
);
mergedLayoutData = await layout.getData();
debugDev(
"%o getData() get merged layout chain front matter",
this.inputPath
);
}
let mergedData = TemplateData.mergeDeep(
this.config,
{},
mergedLayoutData,
localData,
frontMatterData
);
mergedData = await this.addPageDate(mergedData);
mergedData = this.addPageData(mergedData);
debugDev("%o getData() mergedData", this.inputPath);
this.dataCache = mergedData;
}
// Dont deep merge pagination data! See https://github.com/11ty/eleventy/issues/147#issuecomment-440802454
return Object.assign(
TemplateData.mergeDeep(this.config, {}, this.dataCache),
this.paginationData
);
}
async addPageDate(data) {
if (!("page" in data)) {
data.page = {};
}
let newDate = await this.getMappedDate(data);
if ("page" in data && "date" in data.page) {
debug(
"Warning: data.page.date is in use (%o) will be overwritten with: %o",
data.page.date,
newDate
);
}
data.page.date = newDate;
return data;
}
addPageData(data) {
if (!("page" in data)) {
data.page = {};
}
data.page.inputPath = this.inputPath;
data.page.fileSlug = this.fileSlugStr;
data.page.filePathStem = this.filePathStem;
return data;
}
async addPageRenderedData(data) {
if (!("page" in data)) {
data.page = {};
}
let newUrl = await this.getOutputHref(data);
if ("page" in data && "url" in data.page) {
if (data.page.url !== newUrl) {
debug(
"Warning: data.page.url is in use (%o) will be overwritten with: %o",
data.page.url,
newUrl
);
}
}
data.page.url = newUrl;
data.page.outputPath = await this.getOutputPath(data);
return data;
}
// getData (with renderData and page.url added)
async getRenderedData() {
let data = await this.getData();
data = await this.addPageRenderedData(data);
if (data.renderData) {
data.renderData = await this.mapDataAsRenderedTemplates(
data.renderData,
data
);
}
return data;
}
async renderLayout(tmpl, tmplData) {
let layoutKey = tmplData[tmpl.config.keys.layout];
let layout = TemplateLayout.getTemplate(
layoutKey,
this.getInputDir(),
this.config
);
debug("%o is using layout %o", this.inputPath, layoutKey);
// TODO reuse templateContent from templateMap
let templateContent = await super.render(
await this.getPreRender(),
tmplData
);
return layout.render(tmplData, templateContent);
}
async _testRenderWithoutLayouts(data) {
this.setWrapWithLayouts(false);
let ret = await this.render(data);
this.setWrapWithLayouts(true);
return ret;
}
async renderContent(str, data, bypassMarkdown) {
return super.render(str, data, bypassMarkdown);
}
async render(data) {
debugDev("%o render()", this.inputPath);
if (!data) {
data = await this.getRenderedData();
}
if (!this.wrapWithLayouts && data[this.config.keys.layout]) {
debugDev("Template.render is bypassing layouts for %o.", this.inputPath);
}
if (this.wrapWithLayouts && data[this.config.keys.layout]) {
debugDev(
"Template.render found layout: %o",
data[this.config.keys.layout]
);
return this.renderLayout(this, data);
} else {
debugDev("Template.render renderContent for %o", this.inputPath);
return super.render(await this.getPreRender(), data);
}
}
addLinter(callback) {
this.linters.push(callback);
}
async runLinters(str, inputPath, outputPath) {
this.linters.forEach(function(linter) {
// these can be asynchronous but no guarantee of order when they run
linter.call(this, str, inputPath, outputPath);
});
}
addTransform(callback) {
this.transforms.push(callback);
}
async runTransforms(str, outputPath, inputPath) {
for (let transform of this.transforms) {
str = await transform.call(this, str, outputPath, inputPath);
}
return str;
}
async getTemplates(data) {
// TODO cache this
let results = [];
if (!Pagination.hasPagination(data)) {
data.page.url = await this.getOutputHref(data);
data.page.outputPath = await this.getOutputPath(data);
results.push({
template: this,
inputPath: this.inputPath,
fileSlug: this.fileSlugStr,
filePathStem: this.filePathStem,
data: data,
date: data.page.date,
outputPath: data.page.outputPath,
url: data.page.url,
set templateContent(content) {
this._templateContent = content;
},
get templateContent() {
if (this._templateContent === undefined) {
// should at least warn here
throw new TemplateContentPrematureUseError(
`Tried to use templateContent too early (${this.inputPath})`
);
}
return this._templateContent;
}
});
} else {
// needs collections for pagination items
// but individual pagination entries wont be part of a collection
this.paging = new Pagination(data);
this.paging.setTemplate(this);
let templates = await this.paging.getPageTemplates();
let pageNumber = 0;
for (let page of templates) {
// TODO try to reuse data instead of a new copy
let pageData = await page.getRenderedData();
// Issue #115
if (data.collections) {
pageData.collections = data.collections;
}
pageData.page.url = await page.getOutputHref(pageData);
pageData.page.outputPath = await page.getOutputPath(pageData);
results.push({
template: page,
inputPath: this.inputPath,
fileSlug: this.fileSlugStr,
filePathStem: this.filePathStem,
data: pageData,
date: pageData.page.date,
pageNumber: pageNumber++,
outputPath: pageData.page.outputPath,
url: pageData.page.url,
set templateContent(content) {
this._templateContent = content;
},
get templateContent() {
if (this._templateContent === undefined) {
throw new TemplateContentPrematureUseError(
`Tried to use templateContent too early (${this.inputPath} page ${this.pageNumber})`
);
}
return this._templateContent;
}
});
}
}
return results;
}
async getRenderedTemplates(data) {
let pages = await this.getTemplates(data);
for (let page of pages) {
let content = await page.template._getContent(page.outputPath, page.data);
page.templateContent = content;
}
return pages;
}
async _getContent(outputPath, data) {
return await this.render(data);
}
async _write(outputPath, finalContent) {
if (outputPath === false) {
debug(
"Ignored %o from %o (permalink: false).",
outputPath,
this.inputPath
);
return;
}
this.writeCount++;
let lang = {
start: "Writing",
finished: "written."
};
if (this.isDryRun) {
lang = {
start: "Pretending to write",
finished: "" // not used
};
}
if (this.isVerbose) {
console.log(`${lang.start} ${outputPath} from ${this.inputPath}.`);
} else {
debug(`${lang.start} %o from %o.`, outputPath, this.inputPath);
}
if (!this.isDryRun) {
return fs.outputFile(outputPath, finalContent).then(() => {
debug(`${outputPath} ${lang.finished}.`);
});
}
}
async renderPageEntry(mapEntry, page) {
let content;
let layoutKey = mapEntry.data[this.config.keys.layout];
if (layoutKey) {
let layout = TemplateLayout.getTemplate(
layoutKey,
this.getInputDir(),
this.config
);
content = await layout.render(page.data, page.templateContent);
await this.runLinters(content, page.inputPath, page.outputPath);
content = await this.runTransforms(content, page.outputPath); // pass in page.inputPath?
return content;
} else {
content = page.templateContent;
await this.runLinters(
page.templateContent,
page.inputPath,
page.outputPath
);
content = await this.runTransforms(content, page.outputPath); // pass in page.inputPath?
}
return content;
}
async writeMapEntry(mapEntry) {
let promises = [];
for (let page of mapEntry._pages) {
let content = await this.renderPageEntry(mapEntry, page);
promises.push(this._write(page.outputPath, content));
}
return Promise.all(promises);
}
async write(outputPath, data) {
let templates = await this.getRenderedTemplates(data);
let promises = [];
for (let tmpl of templates) {
promises.push(this._write(tmpl.outputPath, tmpl.templateContent));
}
return Promise.all(promises);
}
// TODO this but better
clone() {
let tmpl = new Template(
this.inputPath,
this.inputDir,
this.outputDir,
this.templateData
);
tmpl.config = this.config;
for (let transform of this.transforms) {
tmpl.addTransform(transform);
}
for (let linter of this.linters) {
tmpl.addLinter(linter);
}
tmpl.setIsVerbose(this.isVerbose);
tmpl.setDryRun(this.isDryRun);
return tmpl;
}
getWriteCount() {
return this.writeCount;
}
async getMappedDate(data) {
// should we use Luxon dates everywhere? Right now using built-in `Date`
if ("date" in data) {
debug(
"getMappedDate: using a date in the data for %o of %o",
this.inputPath,
data.date
);
if (data.date instanceof Date) {
// YAML does its own date parsing
debug("getMappedDate: YAML parsed it: %o", data.date);
return data.date;
} else {
let stat = await fs.stat(this.inputPath);
// string
if (data.date.toLowerCase() === "last modified") {
return new Date(stat.ctimeMs);
} else if (data.date.toLowerCase() === "created") {
return new Date(stat.birthtimeMs);
} else {
// try to parse with Luxon
let date = DateTime.fromISO(data.date, { zone: "utc" });
if (!date.isValid) {
throw new Error(
`date front matter value (${data.date}) is invalid for ${this.inputPath}`
);
}
debug(
"getMappedDate: Luxon parsed %o: %o and %o",
data.date,
date,
date.toJSDate()
);
return date.toJSDate();
}
}
} else {
let filenameRegex = this.inputPath.match(/(\d{4}-\d{2}-\d{2})/);
if (filenameRegex !== null) {
let dateObj = DateTime.fromISO(filenameRegex[1]).toJSDate();
debug(
"getMappedDate: using filename regex time for %o of %o: %o",
this.inputPath,
filenameRegex[1],
dateObj
);
return dateObj;
}
let stat = await fs.stat(this.inputPath);
let createdDate = new Date(stat.birthtimeMs);
debug(
"getMappedDate: using file created time for %o of %o (from %o)",
this.inputPath,
createdDate,
stat.birthtimeMs
);
// CREATED
return createdDate;
}
}
async getTemplateMapContent(pageMapEntry) {
pageMapEntry.template.setWrapWithLayouts(false);
let content = await pageMapEntry.template._getContent(
pageMapEntry.outputPath,
pageMapEntry.data
);
pageMapEntry.template.setWrapWithLayouts(true);
return content;
}
async getTemplateMapEntries() {
debugDev("%o getMapped()", this.inputPath);
let data = await this.getData();
let entries = [];
// does not return outputPath or url, we dont want to render permalinks yet
entries.push({
template: this,
inputPath: this.inputPath,
data: data
});
return entries;
}
async _testCompleteRender() {
let entries = await this.getTemplateMapEntries();
let contents = [];
for (let entry of entries) {
entry._pages = await entry.template.getTemplates(entry.data);
let page;
for (page of entry._pages) {
page.templateContent = await entry.template.getTemplateMapContent(page);
}
for (page of entry._pages) {
contents.push(await this.renderPageEntry(entry, page));
}
}
return contents;
}
}
module.exports = Template;

35
node_modules/@11ty/eleventy/src/TemplateCache.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
// Note: this is only used for TemplateLayout right now but could be used for more
// Just be careful because right now the TemplateLayout cache keys are not directly mapped to paths
// So you may get collisions if you use this for other things.
class TemplateCache {
constructor() {
this.cache = {};
}
clear() {
this.cache = {};
}
size() {
return Object.keys(this.cache).length;
}
add(key, template) {
this.cache[key] = template;
}
has(key) {
return key in this.cache;
}
get(key) {
if (!this.has(key)) {
throw new Error(`Could not find ${key} in TemplateCache.`);
}
return this.cache[key];
}
}
// singleton
module.exports = new TemplateCache();

69
node_modules/@11ty/eleventy/src/TemplateCollection.js generated vendored Normal file
View File

@@ -0,0 +1,69 @@
const multimatch = require("multimatch");
const Sortable = require("./Util/Sortable");
const TemplatePath = require("./TemplatePath");
class TemplateCollection extends Sortable {
constructor() {
super();
}
// right now this is only used by the tests
async _testAddTemplate(template) {
let data = await template.getData();
for (let map of await template.getTemplates(data)) {
this.add(map);
}
}
getAll() {
return this.items.filter(() => true);
}
getAllSorted() {
return this.sort(Sortable.sortFunctionDateInputPath);
}
getSortedByDate() {
return this.sort(Sortable.sortFunctionDate);
}
getGlobs(globs) {
if (typeof globs === "string") {
globs = [globs];
}
globs = globs.map(glob => TemplatePath.addLeadingDotSlash(glob));
return globs;
}
getFilteredByGlob(globs) {
globs = this.getGlobs(globs);
return this.getAllSorted().filter(item => {
if (multimatch([item.inputPath], globs).length) {
return true;
}
return false;
});
}
getFilteredByTag(tagName) {
return this.getAllSorted().filter(function(item) {
let match = false;
if (!tagName) {
return true;
} else if (Array.isArray(item.data.tags)) {
item.data.tags.forEach(tag => {
if (tag === tagName) {
match = true;
}
});
}
return match;
});
}
}
module.exports = TemplateCollection;

140
node_modules/@11ty/eleventy/src/TemplateConfig.js generated vendored Normal file
View File

@@ -0,0 +1,140 @@
const fs = require("fs-extra");
const chalk = require("chalk");
const lodashMerge = require("lodash/merge");
const TemplatePath = require("./TemplatePath");
const EleventyBaseError = require("./EleventyBaseError");
const dependencyTree = require("dependency-tree");
const eleventyConfig = require("./EleventyConfig");
const debug = require("debug")("Eleventy:TemplateConfig");
class EleventyConfigError extends EleventyBaseError {}
class TemplateConfig {
constructor(customRootConfig, localProjectConfigPath) {
this.overrides = {};
this.localProjectConfigPath = localProjectConfigPath || ".eleventy.js";
if (customRootConfig) {
this.customRootConfig = customRootConfig;
debug("Warning: Using custom root config!");
} else {
this.customRootConfig = null;
}
this.initializeRootConfig();
this.config = this.mergeConfig(this.localProjectConfigPath);
}
getLocalProjectConfigFile() {
return TemplatePath.addLeadingDotSlash(this.localProjectConfigPath);
}
reset() {
eleventyConfig.reset();
this.initializeRootConfig();
this.config = this.mergeConfig(this.localProjectConfigPath);
}
resetOnWatch() {
// nothing yet
}
getConfig() {
return this.config;
}
setProjectConfigPath(path) {
this.localProjectConfigPath = path;
this.config = this.mergeConfig(path);
}
setPathPrefix(pathPrefix) {
debug("Setting pathPrefix to %o", pathPrefix);
this.overrides.pathPrefix = pathPrefix;
this.config.pathPrefix = pathPrefix;
}
initializeRootConfig() {
this.rootConfig = this.customRootConfig || require("../config.js");
if (typeof this.rootConfig === "function") {
this.rootConfig = this.rootConfig(eleventyConfig);
// debug( "rootConfig is a function, after calling, eleventyConfig is %o", eleventyConfig );
}
debug("rootConfig %o", this.rootConfig);
}
mergeConfig(localProjectConfigPath) {
let overrides = ["templateFormats"];
let localConfig = {};
let path = TemplatePath.join(
TemplatePath.getWorkingDir(),
localProjectConfigPath
);
debug(`Merging config with ${path}`);
if (fs.existsSync(path)) {
try {
// remove from require cache so it will grab a fresh copy
if (path in require.cache) {
delete require.cache[path];
}
localConfig = require(path);
// debug( "localConfig require return value: %o", localConfig );
} catch (err) {
throw new EleventyConfigError(
`Error in your Eleventy config file '${path}'.` +
(err.message.includes("Cannot find module")
? chalk.blueBright(" You may need to run `npm install`.")
: ""),
err
);
}
} else {
debug("Eleventy local project config file not found, skipping.");
}
if (typeof localConfig === "function") {
localConfig = localConfig(eleventyConfig);
// debug( "localConfig is a function, after calling, eleventyConfig is %o", eleventyConfig );
if (
typeof localConfig === "object" &&
typeof localConfig.then === "function"
) {
throw new EleventyConfigError(
`Error in your Eleventy config file '${path}': Returning a promise is not supported`
);
}
}
let eleventyConfigApiMergingObject = eleventyConfig.getMergingConfigObject();
localConfig = lodashMerge(localConfig, eleventyConfigApiMergingObject);
// blow away any templateFormats set in config return object and prefer those set in config API.
for (let localConfigKey of overrides) {
localConfig[localConfigKey] =
eleventyConfigApiMergingObject[localConfigKey] ||
localConfig[localConfigKey];
}
// debug("eleventyConfig.getMergingConfigObject: %o", eleventyConfig.getMergingConfigObject());
debug("localConfig: %o", localConfig);
debug("overrides: %o", this.overrides);
// Object assign overrides original values (good only for templateFormats) but not good for anything else
let merged = lodashMerge({}, this.rootConfig, localConfig, this.overrides);
// blow away any templateFormats upstream (dont merge)
for (let key of overrides) {
merged[key] = localConfig[key] || this.rootConfig[key];
}
debug("Current configuration: %o", merged);
return merged;
}
}
module.exports = TemplateConfig;

206
node_modules/@11ty/eleventy/src/TemplateContent.js generated vendored Normal file
View File

@@ -0,0 +1,206 @@
const os = require("os");
const fs = require("fs-extra");
const normalize = require("normalize-path");
const matter = require("gray-matter");
const lodashSet = require("lodash/set");
const TemplateData = require("./TemplateData");
const TemplateRender = require("./TemplateRender");
const EleventyBaseError = require("./EleventyBaseError");
const EleventyErrorUtil = require("./EleventyErrorUtil");
const config = require("./Config");
const debug = require("debug")("Eleventy:TemplateContent");
const debugDev = require("debug")("Dev:Eleventy:TemplateContent");
class TemplateContentCompileError extends EleventyBaseError {}
class TemplateContentRenderError extends EleventyBaseError {}
class TemplateContent {
constructor(inputPath, inputDir) {
this.inputPath = inputPath;
if (inputDir) {
this.inputDir = normalize(inputDir);
} else {
this.inputDir = false;
}
}
/* Used by tests */
_setExtensionMap(map) {
this._extensionMap = map;
}
set config(config) {
this._config = config;
}
get config() {
if (!this._config) {
this._config = config.getConfig();
}
return this._config;
}
get engine() {
return this.templateRender.engine;
}
get templateRender() {
if (!this._templateRender) {
this._templateRender = new TemplateRender(
this.inputPath,
this.inputDir,
this._extensionMap
);
}
return this._templateRender;
}
getInputPath() {
return this.inputPath;
}
getInputDir() {
return this.inputDir;
}
async read() {
this.inputContent = await this.getInputContent();
if (this.inputContent) {
let options = this.config.frontMatterParsingOptions || {};
let fm = matter(this.inputContent, options);
if (options.excerpt && fm.excerpt) {
let excerptString = fm.excerpt + (options.excerpt_separator || "---");
if (fm.content.startsWith(excerptString + os.EOL)) {
// with a newline after excerpt separator
fm.content =
fm.excerpt.trim() +
"\n" +
fm.content.substr((excerptString + os.EOL).length);
} else if (fm.content.startsWith(excerptString)) {
// no newline after excerpt separator
fm.content = fm.excerpt + fm.content.substr(excerptString.length);
}
// alias, defaults to page.excerpt
let alias = options.excerpt_alias || "page.excerpt";
lodashSet(fm.data, alias, fm.excerpt);
}
this.frontMatter = fm;
} else {
this.frontMatter = {
data: {},
content: "",
excerpt: ""
};
}
}
async getInputContent() {
if (this.engine.needsToReadFileContents()) {
return fs.readFile(this.inputPath, "utf-8");
}
return "";
}
async getFrontMatter() {
if (!this.frontMatter) {
await this.read();
}
return this.frontMatter;
}
async getPreRender() {
if (!this.frontMatter) {
await this.read();
}
return this.frontMatter.content;
}
async getFrontMatterData() {
if (!this.frontMatter) {
await this.read();
}
let extraData = await this.engine.getExtraDataFromFile(this.inputPath);
let data = TemplateData.mergeDeep({}, this.frontMatter.data, extraData);
return TemplateData.cleanupData(data);
}
async getEngineOverride() {
let frontMatterData = await this.getFrontMatterData();
return frontMatterData[this.config.keys.engineOverride];
}
async setupTemplateRender(bypassMarkdown) {
let engineOverride = await this.getEngineOverride();
if (engineOverride !== undefined) {
debugDev(
"%o overriding template engine to use %o",
this.inputPath,
engineOverride
);
this.templateRender.setEngineOverride(engineOverride, bypassMarkdown);
} else {
this.templateRender.setUseMarkdown(!bypassMarkdown);
}
}
async compile(str, bypassMarkdown) {
await this.setupTemplateRender(bypassMarkdown);
debugDev(
"%o compile() using engine: %o",
this.inputPath,
this.templateRender.engineName
);
try {
let fn = await this.templateRender.getCompiledTemplate(str);
debugDev("%o getCompiledTemplate function created", this.inputPath);
return fn;
} catch (e) {
debug(`Having trouble compiling template ${this.inputPath}: %O`, str);
throw new TemplateContentCompileError(
`Having trouble compiling template ${this.inputPath}`,
e
);
}
}
async render(str, data, bypassMarkdown) {
try {
let fn = await this.compile(str, bypassMarkdown);
let rendered = await fn(data);
debugDev(
"%o getCompiledTemplate called, rendered content created",
this.inputPath
);
return rendered;
} catch (e) {
if (EleventyErrorUtil.isPrematureTemplateContentError(e)) {
throw e;
} else {
let engine = this.templateRender.getEnginesStr();
debug(
`Having trouble rendering ${engine} template ${this.inputPath}: %O`,
str
);
throw new TemplateContentRenderError(
`Having trouble rendering ${engine} template ${this.inputPath}`,
e
);
}
}
}
}
module.exports = TemplateContent;

352
node_modules/@11ty/eleventy/src/TemplateData.js generated vendored Normal file
View File

@@ -0,0 +1,352 @@
const fs = require("fs-extra");
const fastglob = require("fast-glob");
const parsePath = require("parse-filepath");
const lodashset = require("lodash/set");
const lodashUniq = require("lodash/uniq");
const merge = require("./Util/Merge");
const TemplateRender = require("./TemplateRender");
const TemplatePath = require("./TemplatePath");
const TemplateGlob = require("./TemplateGlob");
const EleventyExtensionMap = require("./EleventyExtensionMap");
const EleventyBaseError = require("./EleventyBaseError");
const bench = require("./BenchmarkManager").get("Data");
const config = require("./Config");
const debugWarn = require("debug")("Eleventy:Warnings");
const debug = require("debug")("Eleventy:TemplateData");
const debugDev = require("debug")("Dev:Eleventy:TemplateData");
class TemplateDataParseError extends EleventyBaseError {}
class TemplateData {
constructor(inputDir) {
this.config = config.getConfig();
this.dataTemplateEngine = this.config.dataTemplateEngine;
this.inputDirNeedsCheck = false;
this.setInputDir(inputDir);
this.rawImports = {};
this.globalData = null;
}
/* Used by tests */
_setConfig(config) {
this.config = config;
this.dataTemplateEngine = this.config.dataTemplateEngine;
}
setInputDir(inputDir) {
this.inputDirNeedsCheck = true;
this.inputDir = inputDir;
this.dataDir = this.config.dir.data
? TemplatePath.join(inputDir, this.config.dir.data)
: inputDir;
}
setDataTemplateEngine(engineName) {
this.dataTemplateEngine = engineName;
}
getRawImports() {
let pkgPath = TemplatePath.absolutePath("package.json");
try {
this.rawImports[this.config.keys.package] = require(pkgPath);
} catch (e) {
debug(
"Could not find and/or require package.json for data preprocessing at %o",
pkgPath
);
}
return this.rawImports;
}
getDataDir() {
return this.dataDir;
}
clearData() {
this.globalData = null;
}
async cacheData() {
this.clearData();
return this.getData();
}
_getGlobalDataGlobByExtension(dir, extension) {
return TemplateGlob.normalizePath(
dir,
"/",
this.config.dir.data !== "." ? this.config.dir.data : "",
`/**/*.${extension}`
);
}
async _checkInputDir() {
if (this.inputDirNeedsCheck) {
let globalPathStat = await fs.stat(this.inputDir);
if (!globalPathStat.isDirectory()) {
throw new Error("Could not find data path directory: " + this.inputDir);
}
this.inputDirNeedsCheck = false;
}
}
async getInputDir() {
let dir = ".";
if (this.inputDir) {
await this._checkInputDir();
dir = this.inputDir;
}
return dir;
}
async getTemplateDataFileGlob() {
let dir = await this.getInputDir();
return TemplatePath.addLeadingDotSlashArray([
`${dir}/**/*.json`, // covers .11tydata.json too
`${dir}/**/*${this.config.jsDataFileSuffix}.js`
]);
}
async getTemplateJavaScriptDataFileGlob() {
let dir = await this.getInputDir();
return TemplatePath.addLeadingDotSlashArray([
`${dir}/**/*${this.config.jsDataFileSuffix}.js`
]);
}
async getGlobalDataGlob() {
let dir = await this.getInputDir();
return [this._getGlobalDataGlobByExtension(dir, "(json|js)")];
}
getWatchPathCache() {
return this.pathCache;
}
async getGlobalDataFiles() {
let paths = await fastglob(await this.getGlobalDataGlob(), {
caseSensitiveMatch: false,
dot: true
});
this.pathCache = paths;
return paths;
}
getObjectPathForDataFile(path) {
let reducedPath = TemplatePath.stripLeadingSubPath(path, this.dataDir);
let parsed = parsePath(reducedPath);
let folders = parsed.dir ? parsed.dir.split("/") : [];
folders.push(parsed.name);
return folders.join(".");
}
async getAllGlobalData() {
let rawImports = this.getRawImports();
let globalData = {};
let files = TemplatePath.addLeadingDotSlashArray(
await this.getGlobalDataFiles()
);
let dataFileConflicts = {};
for (let j = 0, k = files.length; j < k; j++) {
let folders = await this.getObjectPathForDataFile(files[j]);
// TODO maybe merge these two? (if both valid objects)
if (dataFileConflicts[folders]) {
debugWarn(
`Warning: the key for a global data file (${files[j]}) will overwrite data from an already existing global data file (${dataFileConflicts[folders]})`
);
}
dataFileConflicts[folders] = files[j];
debug(`Found global data file ${files[j]} and adding as: ${folders}`);
let data = await this.getDataValue(files[j], rawImports);
lodashset(globalData, folders, data);
}
return globalData;
}
async getData() {
let rawImports = this.getRawImports();
if (!this.globalData) {
let globalJson = await this.getAllGlobalData();
// OK: Shallow merge when combining rawImports (pkg) with global data files
this.globalData = Object.assign({}, globalJson, rawImports);
}
return this.globalData;
}
/* Template and Directory data files */
async combineLocalData(localDataPaths) {
let localData = {};
if (!Array.isArray(localDataPaths)) {
localDataPaths = [localDataPaths];
}
for (let path of localDataPaths) {
// clean up data for template/directory data files only.
let dataForPath = await this.getDataValue(path, null, true);
let cleanedDataForPath = TemplateData.cleanupData(dataForPath);
TemplateData.mergeDeep(this.config, localData, cleanedDataForPath);
// debug("`combineLocalData` (iterating) for %o: %O", path, localData);
}
return localData;
}
async getLocalData(templatePath) {
let localDataPaths = await this.getLocalDataPaths(templatePath);
let importedData = await this.combineLocalData(localDataPaths);
let globalData = await this.getData();
// OK-ish: shallow merge when combining template/data dir files with global data files
let localData = Object.assign({}, globalData, importedData);
// debug("`getLocalData` for %o: %O", templatePath, localData);
return localData;
}
async _getLocalJsonString(path) {
let rawInput;
try {
rawInput = await fs.readFile(path, "utf-8");
} catch (e) {
// if file does not exist, return nothing
}
return rawInput;
}
async getDataValue(path, rawImports, ignoreProcessing) {
if (ignoreProcessing || TemplatePath.getExtension(path) === "js") {
let localPath = TemplatePath.absolutePath(path);
if (await fs.pathExists(localPath)) {
let dataBench = bench.get(`\`${path}\``);
dataBench.before();
delete require.cache[localPath];
let returnValue = require(localPath);
if (typeof returnValue === "function") {
returnValue = await returnValue();
}
dataBench.after();
return returnValue;
} else {
return {};
}
} else {
let rawInput = await this._getLocalJsonString(path);
let engineName = this.dataTemplateEngine;
if (rawInput) {
if (ignoreProcessing || engineName === false) {
try {
return JSON.parse(rawInput);
} catch (e) {
throw new TemplateDataParseError(
`Having trouble parsing data file ${path}`,
e
);
}
} else {
let fn = await new TemplateRender(engineName).getCompiledTemplate(
rawInput
);
try {
// pass in rawImports, dont pass in global data, thats what were parsing
return JSON.parse(await fn(rawImports));
} catch (e) {
throw new TemplateDataParseError(
`Having trouble parsing data file ${path}`,
e
);
}
}
}
}
return {};
}
async getLocalDataPaths(templatePath) {
let paths = [];
let parsed = parsePath(templatePath);
let inputDir = TemplatePath.addLeadingDotSlash(
TemplatePath.normalize(this.inputDir)
);
debugDev("getLocalDataPaths(%o)", templatePath);
debugDev("parsed.dir: %o", parsed.dir);
if (parsed.dir) {
let fileNameNoExt = EleventyExtensionMap.removeTemplateExtension(
parsed.base
);
let filePathNoExt = parsed.dir + "/" + fileNameNoExt;
let dataSuffix = this.config.jsDataFileSuffix;
debug("Using %o to find data files.", dataSuffix);
paths.push(filePathNoExt + dataSuffix + ".js");
paths.push(filePathNoExt + dataSuffix + ".json");
paths.push(filePathNoExt + ".json");
let allDirs = TemplatePath.getAllDirs(parsed.dir);
debugDev("allDirs: %o", allDirs);
for (let dir of allDirs) {
let lastDir = TemplatePath.getLastPathSegment(dir);
let dirPathNoExt = dir + "/" + lastDir;
if (!inputDir) {
paths.push(dirPathNoExt + dataSuffix + ".js");
paths.push(dirPathNoExt + dataSuffix + ".json");
paths.push(dirPathNoExt + ".json");
} else {
debugDev("dirStr: %o; inputDir: %o", dir, inputDir);
if (dir.indexOf(inputDir) === 0 && dir !== inputDir) {
paths.push(dirPathNoExt + dataSuffix + ".js");
paths.push(dirPathNoExt + dataSuffix + ".json");
paths.push(dirPathNoExt + ".json");
}
}
}
}
debug("getLocalDataPaths(%o): %o", templatePath, paths);
return lodashUniq(paths).reverse();
}
static mergeDeep(config, target, ...source) {
if (config.dataDeepMerge) {
return TemplateData.merge(target, ...source);
} else {
return Object.assign(target, ...source);
}
}
static merge(target, ...source) {
return merge(target, ...source);
}
static cleanupData(data) {
if ("tags" in data) {
if (typeof data.tags === "string") {
data.tags = data.tags ? [data.tags] : [];
} else if (data.tags === null) {
data.tags = [];
}
}
return data;
}
}
module.exports = TemplateData;

49
node_modules/@11ty/eleventy/src/TemplateFileSlug.js generated vendored Normal file
View File

@@ -0,0 +1,49 @@
const parsePath = require("parse-filepath");
const TemplatePath = require("./TemplatePath");
const EleventyExtensionMap = require("./EleventyExtensionMap");
class TemplateFileSlug {
constructor(inputPath, inputDir) {
if (inputDir) {
inputPath = TemplatePath.stripLeadingSubPath(inputPath, inputDir);
}
this.inputPath = inputPath;
this.cleanInputPath = inputPath.replace(/^.\//, "");
let dirs = this.cleanInputPath.split("/");
this.dirs = dirs;
this.dirs.pop();
this.parsed = parsePath(inputPath);
// TODO update this after the fix for issue #117 merges
this.filenameNoExt = EleventyExtensionMap.removeTemplateExtension(
this.parsed.base
);
}
getFullPathWithoutExtension() {
return "/" + TemplatePath.join(...this.dirs, this._getRawSlug());
}
_getRawSlug() {
let slug = this.filenameNoExt;
let reg = slug.match(/\d{4}-\d{2}-\d{2}-(.*)/);
if (reg) {
return reg[1];
}
return slug;
}
getSlug() {
let rawSlug = this._getRawSlug();
if (rawSlug === "index") {
return this.dirs.length ? this.dirs[this.dirs.length - 1] : "";
}
return rawSlug;
}
}
module.exports = TemplateFileSlug;

37
node_modules/@11ty/eleventy/src/TemplateGlob.js generated vendored Normal file
View File

@@ -0,0 +1,37 @@
const TemplatePath = require("./TemplatePath");
class TemplateGlob {
static normalizePath(...paths) {
if (paths[0].charAt(0) === "!") {
throw new Error(
`TemplateGlob.normalizePath does not accept ! glob paths like: ${paths.join(
""
)}`
);
}
return TemplatePath.addLeadingDotSlash(TemplatePath.join(...paths));
}
static normalize(path) {
path = path.trim();
if (path.charAt(0) === "!") {
return "!" + TemplateGlob.normalizePath(path.substr(1));
} else {
return TemplateGlob.normalizePath(path);
}
}
static map(files) {
if (typeof files === "string") {
return TemplateGlob.normalize(files);
} else if (Array.isArray(files)) {
return files.map(function(path) {
return TemplateGlob.normalize(path);
});
} else {
return files;
}
}
}
module.exports = TemplateGlob;

143
node_modules/@11ty/eleventy/src/TemplateLayout.js generated vendored Normal file
View File

@@ -0,0 +1,143 @@
const TemplateLayoutPathResolver = require("./TemplateLayoutPathResolver");
const TemplateContent = require("./TemplateContent");
const TemplateData = require("./TemplateData");
const TemplatePath = require("./TemplatePath");
const templateCache = require("./TemplateCache");
const config = require("./Config");
const debug = require("debug")("Eleventy:TemplateLayout");
const debugDev = require("debug")("Dev:Eleventy:TemplateLayout");
class TemplateLayout extends TemplateContent {
constructor(key, inputDir) {
// TODO getConfig() is duplicated in TemplateContent (super)
let cfg = config.getConfig();
let resolvedPath = new TemplateLayoutPathResolver(
key,
inputDir
).getFullPath();
super(resolvedPath, inputDir);
this.dataKeyLayoutPath = key;
this.inputPath = resolvedPath;
this.inputDir = inputDir;
this.config = cfg;
}
static resolveFullKey(key, inputDir) {
return TemplatePath.join(inputDir, key);
}
static getTemplate(key, inputDir, config) {
let fullKey = TemplateLayout.resolveFullKey(key, inputDir);
if (templateCache.has(fullKey)) {
debugDev("Found %o in TemplateCache", key);
return templateCache.get(fullKey);
}
let tmpl = new TemplateLayout(key, inputDir);
tmpl.config = config;
templateCache.add(fullKey, tmpl);
return tmpl;
}
async getTemplateLayoutMapEntry() {
return {
key: this.dataKeyLayoutPath,
template: this,
frontMatterData: await this.getFrontMatterData()
};
}
async getTemplateLayoutMap() {
if (this.mapCache) {
return this.mapCache;
}
let cfgKey = this.config.keys.layout;
let map = [];
let mapEntry = await this.getTemplateLayoutMapEntry();
map.push(mapEntry);
while (mapEntry.frontMatterData && cfgKey in mapEntry.frontMatterData) {
let layout = TemplateLayout.getTemplate(
mapEntry.frontMatterData[cfgKey],
this.inputDir,
this.config
);
mapEntry = await layout.getTemplateLayoutMapEntry();
map.push(mapEntry);
}
this.mapCache = map;
return map;
}
async getData() {
if (this.dataCache) {
return this.dataCache;
}
let map = await this.getTemplateLayoutMap();
let dataToMerge = [];
for (let j = map.length - 1; j >= 0; j--) {
dataToMerge.push(map[j].frontMatterData);
}
// Deep merge of layout front matter
let data = TemplateData.mergeDeep(this.config, {}, ...dataToMerge);
delete data[this.config.keys.layout];
this.dataCache = data;
return data;
}
async getCompiledLayoutFunctions() {
if (this.compileCache) {
return this.compileCache;
}
let map = await this.getTemplateLayoutMap();
let fns = [];
for (let layoutMap of map) {
fns.push(
await layoutMap.template.compile(
await layoutMap.template.getPreRender()
)
);
}
this.compileCache = fns;
return fns;
}
static augmentDataWithContent(data, templateContent) {
data = data || {};
if (templateContent !== undefined) {
data.content = templateContent;
data.layoutContent = templateContent;
// deprecated
data._layoutContent = templateContent;
}
return data;
}
// Inefficient? We want to compile all the templatelayouts into a single reusable callback?
// Trouble: layouts may need data variables present downstream/upstream
async render(data, templateContent) {
data = TemplateLayout.augmentDataWithContent(data, templateContent);
let fns = await this.getCompiledLayoutFunctions();
for (let fn of fns) {
templateContent = await fn(data);
data = TemplateLayout.augmentDataWithContent(data, templateContent);
}
return templateContent;
}
}
module.exports = TemplateLayout;

View File

@@ -0,0 +1,128 @@
const fs = require("fs-extra");
const config = require("./Config");
const EleventyExtensionMap = require("./EleventyExtensionMap");
const TemplatePath = require("./TemplatePath");
const debug = require("debug")("Eleventy:TemplateLayoutPathResolver");
class TemplateLayoutPathResolver {
constructor(path, inputDir) {
this._config = config.getConfig();
this.inputDir = inputDir;
this.originalPath = path;
this.path = path;
this.aliases = {};
this.init();
}
set inputDir(dir) {
this._inputDir = dir;
this.dir = this.getLayoutsDir();
}
get inputDir() {
return this._inputDir;
}
// for testing
set config(cfg) {
this._config = cfg;
this.dir = this.getLayoutsDir();
this.init();
}
get config() {
return this._config;
}
init() {
// we might be able to move this into the constructor?
this.aliases = Object.assign({}, this.config.layoutAliases, this.aliases);
// debug("Current layout aliases: %o", this.aliases);
if (this.path in this.aliases) {
// debug(
// "Substituting layout: %o maps to %o",
// this.path,
// this.aliases[this.path]
// );
this.path = this.aliases[this.path];
}
this.pathAlreadyHasExtension = this.dir + "/" + this.path;
if (
this.path.split(".").length > 0 &&
fs.existsSync(this.pathAlreadyHasExtension)
) {
this.filename = this.path;
this.fullPath = this.pathAlreadyHasExtension;
} else {
this.filename = this.findFileName();
this.fullPath = this.dir + "/" + this.filename;
}
}
addLayoutAlias(from, to) {
this.aliases[from] = to;
}
getFileName() {
if (!this.filename) {
throw new Error(
`Youre trying to use a layout that does not exist: ${
this.originalPath
} (${this.filename})`
);
}
return this.filename;
}
getFullPath() {
if (!this.filename) {
throw new Error(
`Youre trying to use a layout that does not exist: ${
this.originalPath
} (${this.filename})`
);
}
return this.fullPath;
}
findFileName() {
if (!fs.existsSync(this.dir)) {
throw Error(
"TemplateLayoutPathResolver directory does not exist for " +
this.path +
": " +
this.dir
);
}
let extensionMap = new EleventyExtensionMap(this.config.templateFormats);
for (let filename of extensionMap.getFileList(this.path)) {
// TODO async
if (fs.existsSync(this.dir + "/" + filename)) {
return filename;
}
}
}
getLayoutsDir() {
let layoutsDir;
if ("layouts" in this.config.dir) {
layoutsDir = this.config.dir.layouts;
} else if ("includes" in this.config.dir) {
layoutsDir = this.config.dir.includes;
} else {
// Should this have a default?
layoutsDir = "_includes";
}
return TemplatePath.join(this.inputDir, layoutsDir);
}
}
module.exports = TemplateLayoutPathResolver;

546
node_modules/@11ty/eleventy/src/TemplateMap.js generated vendored Normal file
View File

@@ -0,0 +1,546 @@
const isPlainObject = require("lodash/isPlainObject");
const DependencyGraph = require("dependency-graph").DepGraph;
const TemplateCollection = require("./TemplateCollection");
const EleventyErrorUtil = require("./EleventyErrorUtil");
const UsingCircularTemplateContentReferenceError = require("./Errors/UsingCircularTemplateContentReferenceError");
const eleventyConfig = require("./EleventyConfig");
const debug = require("debug")("Eleventy:TemplateMap");
const debugDev = require("debug")("Dev:Eleventy:TemplateMap");
const EleventyBaseError = require("./EleventyBaseError");
class DuplicatePermalinkOutputError extends EleventyBaseError {
get removeDuplicateErrorStringFromOutput() {
return true;
}
}
class TemplateMap {
constructor() {
this.map = [];
this.graph = new DependencyGraph();
this.collectionsData = null;
this.cached = false;
this.configCollections = null;
this.verboseOutput = true;
}
get tagPrefix() {
return "___TAG___";
}
async add(template) {
for (let map of await template.getTemplateMapEntries()) {
this.map.push(map);
}
}
getMap() {
return this.map;
}
get collection() {
if (!this._collection) {
this._collection = new TemplateCollection();
}
return this._collection;
}
getTagTarget(str) {
if (str.startsWith("collections.")) {
return str.substr("collections.".length);
}
}
/* ---
* pagination:
* data: collections
* ---
*/
isPaginationOverAllCollections(entry) {
if (entry.data.pagination && entry.data.pagination.data) {
return (
entry.data.pagination.data === "collections" ||
entry.data.pagination.data === "collections.all"
);
}
}
getPaginationTagTarget(entry) {
if (entry.data.pagination && entry.data.pagination.data) {
return this.getTagTarget(entry.data.pagination.data);
}
}
getMappedDependencies() {
let graph = new DependencyGraph();
let tagPrefix = this.tagPrefix;
graph.addNode(tagPrefix + "all");
for (let entry of this.map) {
if (this.isPaginationOverAllCollections(entry)) {
continue;
}
// using Pagination (but not targeting a user config collection)
let paginationTagTarget = this.getPaginationTagTarget(entry);
if (paginationTagTarget) {
if (this.isUserConfigCollectionName(paginationTagTarget)) {
// delay this one to the second stage
continue;
} else {
// using pagination but over a tagged collection
graph.addNode(entry.inputPath);
if (!graph.hasNode(tagPrefix + paginationTagTarget)) {
graph.addNode(tagPrefix + paginationTagTarget);
}
graph.addDependency(entry.inputPath, tagPrefix + paginationTagTarget);
}
} else {
// not using pagination
graph.addNode(entry.inputPath);
}
if (!entry.data.eleventyExcludeFromCollections) {
// collections.all
graph.addDependency(tagPrefix + "all", entry.inputPath);
if (entry.data.tags) {
for (let tag of entry.data.tags) {
if (!graph.hasNode(tagPrefix + tag)) {
graph.addNode(tagPrefix + tag);
}
// collections.tagName
// Dependency from tag to inputPath
graph.addDependency(tagPrefix + tag, entry.inputPath);
}
}
}
}
return graph.overallOrder();
}
getDelayedMappedDependencies() {
let graph = new DependencyGraph();
let tagPrefix = this.tagPrefix;
graph.addNode(tagPrefix + "all");
let userConfigCollections = this.getUserConfigCollectionNames();
// Add tags from named user config collections
for (let tag of userConfigCollections) {
graph.addNode(tagPrefix + tag);
// graph.addDependency( tagPrefix + tag, tagPrefix + "all" );
}
for (let entry of this.map) {
if (this.isPaginationOverAllCollections(entry)) {
continue;
}
let paginationTagTarget = this.getPaginationTagTarget(entry);
if (
paginationTagTarget &&
this.isUserConfigCollectionName(paginationTagTarget)
) {
if (!graph.hasNode(entry.inputPath)) {
graph.addNode(entry.inputPath);
}
graph.addDependency(entry.inputPath, tagPrefix + paginationTagTarget);
if (!entry.data.eleventyExcludeFromCollections) {
// collections.all
graph.addDependency(tagPrefix + "all", entry.inputPath);
if (entry.data.tags) {
for (let tag of entry.data.tags) {
if (!graph.hasNode(tagPrefix + tag)) {
graph.addNode(tagPrefix + tag);
}
// collections.tagName
// Dependency from tag to inputPath
graph.addDependency(tagPrefix + tag, entry.inputPath);
}
}
}
}
}
return graph.overallOrder();
}
getPaginatedOverCollectionsMappedDependencies() {
let graph = new DependencyGraph();
let tagPrefix = this.tagPrefix;
let allNodeAdded = false;
for (let entry of this.map) {
if (
this.isPaginationOverAllCollections(entry) &&
!this.getPaginationTagTarget(entry)
) {
if (!allNodeAdded) {
graph.addNode(tagPrefix + "all");
allNodeAdded = true;
}
if (!graph.hasNode(entry.inputPath)) {
graph.addNode(entry.inputPath);
}
if (!entry.data.eleventyExcludeFromCollections) {
// collections.all
graph.addDependency(tagPrefix + "all", entry.inputPath);
}
}
}
return graph.overallOrder();
}
getPaginatedOverAllCollectionMappedDependencies() {
let graph = new DependencyGraph();
let tagPrefix = this.tagPrefix;
let allNodeAdded = false;
for (let entry of this.map) {
if (
this.isPaginationOverAllCollections(entry) &&
this.getPaginationTagTarget(entry) === "all"
) {
if (!allNodeAdded) {
graph.addNode(tagPrefix + "all");
allNodeAdded = true;
}
if (!graph.hasNode(entry.inputPath)) {
graph.addNode(entry.inputPath);
}
if (!entry.data.eleventyExcludeFromCollections) {
// collections.all
graph.addDependency(tagPrefix + "all", entry.inputPath);
}
}
}
return graph.overallOrder();
}
async initDependencyMap(dependencyMap) {
let tagPrefix = this.tagPrefix;
for (let depEntry of dependencyMap) {
if (depEntry.startsWith(tagPrefix)) {
let tagName = depEntry.substr(tagPrefix.length);
if (this.isUserConfigCollectionName(tagName)) {
// async
this.collectionsData[tagName] = await this.getUserConfigCollection(
tagName
);
} else {
this.collectionsData[tagName] = this.getTaggedCollection(tagName);
}
} else {
let map = this.getMapEntryForInputPath(depEntry);
map._pages = await map.template.getTemplates(map.data);
let counter = 0;
for (let page of map._pages) {
// TODO do we need this in map entries?
if (!map.outputPath) {
map.outputPath = page.outputPath;
}
if (
counter === 0 ||
(map.data.pagination &&
map.data.pagination.addAllPagesToCollections)
) {
if (!map.data.eleventyExcludeFromCollections) {
// TODO do we need .template in collection entries?
this.collection.add(page);
}
}
counter++;
}
}
}
}
async cache() {
debug("Caching collections objects.");
this.collectionsData = {};
for (let entry of this.map) {
entry.data.collections = this.collectionsData;
}
let dependencyMap = this.getMappedDependencies();
await this.initDependencyMap(dependencyMap);
let delayedDependencyMap = this.getDelayedMappedDependencies();
await this.initDependencyMap(delayedDependencyMap);
let firstPaginatedDepMap = this.getPaginatedOverCollectionsMappedDependencies();
await this.initDependencyMap(firstPaginatedDepMap);
let secondPaginatedDepMap = this.getPaginatedOverAllCollectionMappedDependencies();
await this.initDependencyMap(secondPaginatedDepMap);
let orderedPaths = this.getOrderedInputPaths(
dependencyMap,
delayedDependencyMap,
firstPaginatedDepMap,
secondPaginatedDepMap
);
let orderedMap = orderedPaths.map(
function(inputPath) {
return this.getMapEntryForInputPath(inputPath);
}.bind(this)
);
await this.populateContentDataInMap(orderedMap);
this.populateCollectionsWithContent();
this.cached = true;
this.checkForDuplicatePermalinks();
}
getMapEntryForInputPath(inputPath) {
for (let map of this.map) {
if (map.inputPath === inputPath) {
return map;
}
}
}
getOrderedInputPaths(
dependencyMap,
delayedDependencyMap,
firstPaginatedDepMap,
secondPaginatedDepMap
) {
let orderedMap = [];
let tagPrefix = this.tagPrefix;
for (let dep of dependencyMap) {
if (!dep.startsWith(tagPrefix)) {
orderedMap.push(dep);
}
}
for (let dep of delayedDependencyMap) {
if (!dep.startsWith(tagPrefix)) {
orderedMap.push(dep);
}
}
for (let dep of firstPaginatedDepMap) {
if (!dep.startsWith(tagPrefix)) {
orderedMap.push(dep);
}
}
for (let dep of secondPaginatedDepMap) {
if (!dep.startsWith(tagPrefix)) {
orderedMap.push(dep);
}
}
return orderedMap;
}
async populateContentDataInMap(orderedMap) {
let usedTemplateContentTooEarlyMap = [];
for (let map of orderedMap) {
if (!map._pages) {
throw new Error(`Content pages not found for ${map.inputPath}`);
}
try {
for (let pageEntry of map._pages) {
pageEntry.templateContent = await map.template.getTemplateMapContent(
pageEntry
);
}
} catch (e) {
if (EleventyErrorUtil.isPrematureTemplateContentError(e)) {
usedTemplateContentTooEarlyMap.push(map);
} else {
throw e;
}
}
debugDev(
"Added this.map[...].templateContent, outputPath, et al for one map entry"
);
}
for (let map of usedTemplateContentTooEarlyMap) {
try {
for (let pageEntry of map._pages) {
pageEntry.templateContent = await map.template.getTemplateMapContent(
pageEntry
);
}
} catch (e) {
if (EleventyErrorUtil.isPrematureTemplateContentError(e)) {
throw new UsingCircularTemplateContentReferenceError(
`${map.inputPath} contains a circular reference (using collections) to its own templateContent.`
);
} else {
// rethrow?
throw e;
}
}
}
}
_testGetAllTags() {
let allTags = {};
for (let map of this.map) {
let tags = map.data.tags;
if (Array.isArray(tags)) {
for (let tag of tags) {
allTags[tag] = true;
}
}
}
return Object.keys(allTags);
}
getTaggedCollection(tag) {
let result;
if (!tag || tag === "all") {
result = this.collection.getAllSorted();
} else {
result = this.collection.getFilteredByTag(tag);
}
debug(`Collection: collections.${tag || "all"} size: ${result.length}`);
return result;
}
async _testGetTaggedCollectionsData() {
let collections = {};
collections.all = this.collection.getAllSorted();
debug(`Collection: collections.all size: ${collections.all.length}`);
let tags = this._testGetAllTags();
for (let tag of tags) {
collections[tag] = this.collection.getFilteredByTag(tag);
debug(`Collection: collections.${tag} size: ${collections[tag].length}`);
}
return collections;
}
setUserConfigCollections(configCollections) {
return (this.configCollections = configCollections);
}
isUserConfigCollectionName(name) {
let collections = this.configCollections || eleventyConfig.getCollections();
return name && !!collections[name];
}
getUserConfigCollectionNames() {
return Object.keys(
this.configCollections || eleventyConfig.getCollections()
);
}
async getUserConfigCollection(name) {
let configCollections =
this.configCollections || eleventyConfig.getCollections();
// This works with async now
let result = await configCollections[name](this.collection);
debug(`Collection: collections.${name} size: ${result.length}`);
return result;
}
async _testGetUserConfigCollectionsData() {
let collections = {};
let configCollections =
this.configCollections || eleventyConfig.getCollections();
for (let name in configCollections) {
collections[name] = configCollections[name](this.collection);
debug(
`Collection: collections.${name} size: ${collections[name].length}`
);
}
return collections;
}
async _testGetAllCollectionsData() {
let collections = {};
let taggedCollections = await this._testGetTaggedCollectionsData();
Object.assign(collections, taggedCollections);
let userConfigCollections = await this._testGetUserConfigCollectionsData();
Object.assign(collections, userConfigCollections);
return collections;
}
populateCollectionsWithContent() {
for (let collectionName in this.collectionsData) {
if (!Array.isArray(this.collectionsData[collectionName])) {
continue;
}
for (let item of this.collectionsData[collectionName]) {
if (!isPlainObject(item) || !("inputPath" in item)) {
continue;
}
let entry = this.getMapEntryForInputPath(item.inputPath);
let index = item.pageNumber || 0;
item.templateContent = entry._pages[index]._templateContent;
}
}
}
checkForDuplicatePermalinks() {
let permalinks = {};
let warnings = {};
for (let entry of this.map) {
for (let page of entry._pages) {
if (page.url === false) {
// do nothing
} else if (!permalinks[page.url]) {
permalinks[page.url] = [entry.inputPath];
} else {
warnings[
page.outputPath
] = `Output conflict: multiple input files are writing to \`${
page.outputPath
}\`. Use distinct \`permalink\` values to resolve this conflict.
1. ${entry.inputPath}
${permalinks[page.url]
.map(function(inputPath, index) {
return ` ${index + 2}. ${inputPath}\n`;
})
.join("")}
`;
permalinks[page.url].push(entry.inputPath);
}
}
}
let warningList = Object.values(warnings);
if (warningList.length) {
// throw one at a time
throw new DuplicatePermalinkOutputError(warningList[0]);
}
}
async getCollectionsData() {
if (!this.cached) {
await this.cache();
}
return this.collectionsData;
}
}
module.exports = TemplateMap;

118
node_modules/@11ty/eleventy/src/TemplatePassthrough.js generated vendored Normal file
View File

@@ -0,0 +1,118 @@
const copy = require("recursive-copy");
const fs = require("fs");
const TemplatePath = require("./TemplatePath");
const debug = require("debug")("Eleventy:TemplatePassthrough");
const fastglob = require("fast-glob");
const EleventyBaseError = require("./EleventyBaseError");
class TemplatePassthroughError extends EleventyBaseError {}
class TemplatePassthrough {
constructor(path, outputDir, inputDir) {
// inputPath is relative to the root of your project and not your Eleventy input directory.
this.inputPath = path.inputPath;
// inputDir is only used when stripping from output path in `getOutputPath`
this.inputDir = inputDir;
this.outputPath = path.outputPath;
this.outputDir = outputDir;
this.isDryRun = false;
}
getOutputPath(inputFileFromGlob) {
const { inputDir, outputDir, outputPath, inputPath } = this;
if (outputPath === true) {
return TemplatePath.normalize(
TemplatePath.join(
outputDir,
TemplatePath.stripLeadingSubPath(
inputFileFromGlob || inputPath,
inputDir
)
)
);
}
if (inputFileFromGlob) {
return this.getOutputPathForGlobFile(inputFileFromGlob);
}
return TemplatePath.normalize(TemplatePath.join(outputDir, outputPath));
}
getOutputPathForGlobFile(inputFileFromGlob) {
return TemplatePath.join(
this.getOutputPath(),
TemplatePath.getLastPathSegment(inputFileFromGlob)
);
}
setDryRun(isDryRun) {
this.isDryRun = !!isDryRun;
}
async getFiles(glob) {
debug("Searching for: %o", glob);
const files = TemplatePath.addLeadingDotSlashArray(
await fastglob(glob, {
caseSensitiveMatch: false,
dot: true
})
);
return files;
}
copy(src, dest, copyOptions) {
if (
TemplatePath.stripLeadingDotSlash(dest).includes(
TemplatePath.stripLeadingDotSlash(this.outputDir)
)
) {
return copy(src, dest, copyOptions);
}
return Promise.reject(
new TemplatePassthroughError(
"Destination is not in the site output directory. Check your passthrough paths."
)
);
}
async write() {
const copyOptions = {
overwrite: true,
dot: true,
junk: false,
results: false
};
if (!this.isDryRun) {
debug("Copying %o", this.inputPath);
const isDirectory = TemplatePath.isDirectorySync(this.inputPath);
const isFile = fs.existsSync(this.inputPath);
// If directory or file, recursive copy
if (isDirectory || isFile) {
// IMPORTANT: this returns a promise, does not await for promise to finish
return this.copy(this.inputPath, this.getOutputPath(), copyOptions);
}
// If not directory or file, attempt to get globs
const files = await this.getFiles(this.inputPath);
const promises = files.map(inputFile =>
this.copy(inputFile, this.getOutputPath(inputFile), copyOptions)
);
return Promise.all(promises).catch(err => {
throw new TemplatePassthroughError(
`Error copying passthrough files: ${err.message}`,
err
);
});
}
}
}
module.exports = TemplatePassthrough;

View File

@@ -0,0 +1,141 @@
const config = require("./Config");
const EleventyBaseError = require("./EleventyBaseError");
const TemplatePassthrough = require("./TemplatePassthrough");
const TemplateRender = require("./TemplateRender");
const TemplatePath = require("./TemplatePath");
const debug = require("debug")("Eleventy:TemplatePassthroughManager");
class TemplatePassthroughManagerCopyError extends EleventyBaseError {}
class TemplatePassthroughManager {
constructor() {
this.config = config.getConfig();
this.reset();
}
reset() {
this.count = 0;
debug("Resetting counts to 0");
}
setConfig(configOverride) {
this.config = configOverride || {};
}
setOutputDir(outputDir) {
this.outputDir = outputDir;
}
setInputDir(inputDir) {
this.inputDir = inputDir;
}
setDryRun(isDryRun) {
this.isDryRun = !!isDryRun;
}
_normalizePaths(path, outputPath) {
return {
inputPath: TemplatePath.addLeadingDotSlash(path),
outputPath: outputPath
? TemplatePath.stripLeadingDotSlash(outputPath)
: true
};
}
getConfigPaths() {
if (!this.config.passthroughFileCopy) {
debug("`passthroughFileCopy` is disabled in config, bypassing.");
return [];
}
let paths = [];
let target = this.config.passthroughCopies || {};
debug("`passthroughFileCopy` config paths: %o", target);
for (let path in target) {
paths.push(this._normalizePaths(path, target[path]));
}
debug("`passthroughFileCopy` config normalized paths: %o", paths);
return paths;
}
getConfigPathGlobs() {
return this.getConfigPaths().map(path => {
return TemplatePath.convertToRecursiveGlob(path.inputPath);
});
}
getFilePaths(paths) {
if (!this.config.passthroughFileCopy) {
debug("`passthroughFileCopy` is disabled in config, bypassing.");
return [];
}
let matches = [];
for (let path of paths) {
if (!TemplateRender.hasEngine(path)) {
matches.push(path);
}
}
return matches;
}
getCopyCount() {
return this.count;
}
async copyPath(path) {
let pass = new TemplatePassthrough(path, this.outputDir, this.inputDir);
pass.setDryRun(this.isDryRun);
return pass
.write()
.then(
function() {
this.count++;
debug("Copied %o", path.inputPath);
}.bind(this)
)
.catch(function(e) {
return Promise.reject(
new TemplatePassthroughManagerCopyError(
`Having trouble copying '${path.inputPath}'`,
e
)
);
});
}
// Performance note: these can actually take a fair bit of time, but arent a
// bottleneck to eleventy. The copies are performed asynchronously and dont affect eleventy
// write times in a significant way.
async copyAll(paths) {
if (!this.config.passthroughFileCopy) {
debug("`passthroughFileCopy` is disabled in config, bypassing.");
return;
}
let promises = [];
debug("TemplatePassthrough copy started.");
for (let path of this.getConfigPaths()) {
debug(`TemplatePassthrough copying from config: ${path}`);
promises.push(this.copyPath(path));
}
let passthroughPaths = this.getFilePaths(paths);
for (let path of passthroughPaths) {
let normalizedPath = this._normalizePaths(path);
debug(
`TemplatePassthrough copying from non-matching file extension: ${normalizedPath}`
);
promises.push(this.copyPath(normalizedPath));
}
return Promise.all(promises).then(() => {
debug(`TemplatePassthrough copy finished. Current count: ${this.count}`);
});
}
}
module.exports = TemplatePassthroughManager;

285
node_modules/@11ty/eleventy/src/TemplatePath.js generated vendored Normal file
View File

@@ -0,0 +1,285 @@
const path = require("path");
const normalize = require("normalize-path");
const parsePath = require("parse-filepath");
const fs = require("fs-extra");
function TemplatePath() {}
/**
* @returns {String} the absolute path to Eleventys project directory.
*/
TemplatePath.getWorkingDir = function() {
return TemplatePath.normalize(path.resolve("."));
};
/**
* Returns the directory portion of a path.
* Works for directory and file paths and paths ending in a glob pattern.
*
* @param {String} path A path
* @returns {String} the directory portion of a path.
*/
TemplatePath.getDir = function(path) {
if (TemplatePath.isDirectorySync(path)) {
return path;
}
return TemplatePath.getDirFromFilePath(path);
};
/**
* Returns the directory portion of a path that either points to a file
* or ends in a glob pattern. If `path` points to a directory,
* the returned value will have its last path segment stripped
* due to how [`parsePath`][1] works.
*
* [1]: https://www.npmjs.com/package/parse-filepath
*
* @param {String} path A path
* @returns {String} the directory portion of a path.
*/
TemplatePath.getDirFromFilePath = function(path) {
return parsePath(path).dir || ".";
};
/**
* Returns the last path segment in a path (no leading/trailing slashes).
*
* Assumes [`parsePath`][1] was called on `path` before.
*
* [1]: https://www.npmjs.com/package/parse-filepath
*
* @param {String} path A path
* @returns {String} the last path segment in a path
*/
TemplatePath.getLastPathSegment = function(path) {
if (!path.includes("/")) {
return path;
}
// Trim a trailing slash if there is one
path = path.replace(/\/$/, "");
return path.substr(path.lastIndexOf("/") + 1);
};
/**
* @param {String} path A path
* @returns {String[]} an array of paths pointing to each path segment of the
* provided `path`.
*/
TemplatePath.getAllDirs = function(path) {
// Trim a trailing slash if there is one
path = path.replace(/\/$/, "");
if (!path.includes("/")) {
return [path];
}
return path
.split("/")
.map((segment, index, array) => array.slice(0, index + 1).join("/"))
.filter(path => path !== ".")
.reverse();
};
/**
* Normalizes a path, resolving single-dot and double-dot segments.
*
* Node.js [`path.normalize`][1] is called to strip a possible leading `"./"` segment.
*
* [1]: https://nodejs.org/api/path.html#path_path_normalize_path
*
* @param {String} thePath The path that should be normalized.
* @returns {String} the normalized path.
*/
TemplatePath.normalize = function(thePath) {
return normalize(path.normalize(thePath));
};
/**
* Joins all given path segments together.
*
* It uses Node.js [`path.join`][1] method and the [normalize-path][2] package.
*
* [1]: https://nodejs.org/api/path.html#path_path_join_paths
* [2]: https://www.npmjs.com/package/normalize-path
*
* @param {String[]} paths An arbitrary amount of path segments.
* @returns {String} the normalized and joined path.
*/
TemplatePath.join = function(...paths) {
return normalize(path.join(...paths));
};
/**
* Joins the given URL path segments and normalizes the resulting path.
* Maintains traling a single trailing slash if the last URL path argument
* had atleast one.
*
* @param {String[]} urlPaths
* @returns {String} a normalized URL path described by the given URL path segments.
*/
TemplatePath.normalizeUrlPath = function(...urlPaths) {
const urlPath = path.posix.join(...urlPaths);
return urlPath.replace(/\/+$/, "/");
};
/**
* Joins the given path segments. Since the first path is absolute,
* the resulting path will be absolute as well.
*
* @param {String[]} paths
* @returns {String} the absolute path described by the given path segments.
*/
TemplatePath.absolutePath = function(...paths) {
return TemplatePath.join(TemplatePath.getWorkingDir(), ...paths);
};
/**
* Turns an absolute path into a path relative Eleventys project directory.
*
* @param {String} absolutePath
* @returns {String} the relative path.
*/
TemplatePath.relativePath = function(absolutePath) {
return TemplatePath.stripLeadingSubPath(
absolutePath,
TemplatePath.getWorkingDir()
);
};
/**
* Adds a leading dot-slash segment to each path in the `paths` array.
*
* @param {String[]} paths
* @returns {String[]}
*/
TemplatePath.addLeadingDotSlashArray = function(paths) {
return paths.map(path => TemplatePath.addLeadingDotSlash(path));
};
/**
* Adds a leading dot-slash segment to `path`.
*
* @param {String} path
* @returns {String}
*/
TemplatePath.addLeadingDotSlash = function(path) {
if (path === "." || path === "..") {
return path + "/";
}
if (path.startsWith("/") || path.startsWith("./") || path.startsWith("../")) {
return path;
}
return "./" + path;
};
/**
* Removes a leading dot-slash segment.
*
* @param {String} path
* @returns {String} the `path` without a leading dot-slash segment.
*/
TemplatePath.stripLeadingDotSlash = function(path) {
return typeof path === "string" ? path.replace(/^\.\//, "") : path;
};
/**
* Determines whether a path starts with a given sub path.
*
* @param {String} path A path
* @param {String} subPath A path
* @returns {Boolean} whether `path` starts with `subPath`.
*/
TemplatePath.startsWithSubPath = function(path, subPath) {
path = TemplatePath.normalize(path);
subPath = TemplatePath.normalize(subPath);
return path.startsWith(subPath);
};
/**
* Removes the `subPath` at the start of `path` if present
* and returns the remainding path.
*
* @param {String} path A path
* @param {String} subPath A path
* @returns {String} the `path` without `subPath` at the start of it.
*/
TemplatePath.stripLeadingSubPath = function(path, subPath) {
path = TemplatePath.normalize(path);
subPath = TemplatePath.normalize(subPath);
if (subPath !== "." && path.startsWith(subPath)) {
return path.substr(subPath.length + 1);
}
return path;
};
/**
* @param {String} path A path
* @returns {Boolean} whether `path` points to an existing directory.
*/
TemplatePath.isDirectorySync = function(path) {
return fs.existsSync(path) && fs.statSync(path).isDirectory();
};
/**
* Appends a recursive wildcard glob pattern to `path`
* unless `path` is not a directory; then, `path` is assumed to be a file path
* and is left unchaged.
*
* @param {String} path
* @returns {String}
*/
TemplatePath.convertToRecursiveGlob = function(path) {
if (path === "") {
return "./**";
}
path = TemplatePath.addLeadingDotSlash(path);
if (TemplatePath.isDirectorySync(path)) {
return path + (!path.endsWith("/") ? "/" : "") + "**";
}
return path;
};
/**
* Returns the extension of the path without the leading dot.
* If the path has no extensions, the empty string is returned.
*
* @param {String} thePath
* @returns {String} the paths extension if it exists;
* otherwise, the empty string.
*/
TemplatePath.getExtension = function(thePath) {
return path.extname(thePath).replace(/^\./, "");
};
/**
* Removes the extension from a path.
*
* @param {String} path
* @param {String} extension
* @returns {String}
*/
TemplatePath.removeExtension = function(path, extension = undefined) {
if (extension === undefined) {
return path;
}
const pathExtension = TemplatePath.getExtension(path);
if (pathExtension !== "" && extension.endsWith(pathExtension)) {
return path.substring(0, path.lastIndexOf(pathExtension) - 1);
}
return path;
};
module.exports = TemplatePath;

58
node_modules/@11ty/eleventy/src/TemplatePermalink.js generated vendored Normal file
View File

@@ -0,0 +1,58 @@
const parsePath = require("parse-filepath");
const TemplatePath = require("./TemplatePath");
function TemplatePermalink(link, extraSubdir) {
this.link = this._cleanLink(link);
this.extraSubdir = extraSubdir || "";
}
TemplatePermalink.prototype._cleanLink = function(link) {
return link + (link.substr(-1) === "/" ? "index.html" : "");
};
TemplatePermalink.prototype.resolve = function() {
let parsed = parsePath(this.link);
return TemplatePath.join(parsed.dir, this.extraSubdir, parsed.base);
};
TemplatePermalink.prototype.toString = function() {
return this.resolve();
};
// remove all index.htmls from links
// index.html becomes /
// test/index.html becomes test/
TemplatePermalink.prototype.toHref = function() {
let str = this.toString();
let original = (str.charAt(0) !== "/" ? "/" : "") + this.toString();
let needle = "/index.html";
if (original === needle) {
return "/";
} else if (original.substr(-1 * needle.length) === needle) {
return original.substr(0, original.length - needle.length) + "/";
}
return original;
};
TemplatePermalink._hasDuplicateFolder = function(dir, base) {
let folders = dir.split("/");
if (!folders[folders.length - 1]) {
folders.pop();
}
return folders[folders.length - 1] === base;
};
TemplatePermalink.generate = function(dir, filenameNoExt, extraSubdir, suffix) {
let hasDupeFolder = TemplatePermalink._hasDuplicateFolder(dir, filenameNoExt);
let path =
(dir ? dir + "/" : "") +
(filenameNoExt !== "index" && !hasDupeFolder ? filenameNoExt + "/" : "") +
"index" +
(suffix || "") +
".html";
return new TemplatePermalink(path, extraSubdir);
};
module.exports = TemplatePermalink;

View File

@@ -0,0 +1,11 @@
class TemplatePermalinkNoWrite {
toString() {
return false;
}
toHref() {
return false;
}
}
module.exports = TemplatePermalinkNoWrite;

206
node_modules/@11ty/eleventy/src/TemplateRender.js generated vendored Normal file
View File

@@ -0,0 +1,206 @@
const TemplatePath = require("./TemplatePath");
const TemplateEngine = require("./Engines/TemplateEngine");
const EleventyBaseError = require("./EleventyBaseError");
const EleventyExtensionMap = require("./EleventyExtensionMap");
const config = require("./Config");
// const debug = require("debug")("Eleventy:TemplateRender");
class TemplateRenderUnknownEngineError extends EleventyBaseError {}
// works with full path names or short engine name
class TemplateRender {
constructor(tmplPath, inputDir, extensionMap) {
if (!tmplPath) {
throw new Error(
`TemplateRender requires a tmplPath argument, instead of ${tmplPath}`
);
}
this.path = tmplPath;
this.extensionMap = extensionMap;
// optional
this.includesDir = this._normalizeIncludesDir(inputDir);
this.parseMarkdownWith = this.config.markdownTemplateEngine;
this.parseHtmlWith = this.config.htmlTemplateEngine;
this.init(tmplPath);
this.useMarkdown = this.engineName === "md";
}
get config() {
if (!this._config) {
this._config = config.getConfig();
}
return this._config;
}
set config(config) {
this._config = config;
if (this.engine) {
this.engine.config = config;
}
}
init(engineNameOrPath) {
this.engineName = this.cleanupEngineName(engineNameOrPath);
if (!this.engineName) {
throw new TemplateRenderUnknownEngineError(
`Unknown engine for ${engineNameOrPath}`
);
}
this.engine = TemplateEngine.getEngine(this.engineName, this.includesDir);
this.engine.initRequireCache(this.path);
}
cleanupEngineName(tmplPath) {
return TemplateRender._cleanupEngineName(
tmplPath,
this.extensionMap || EleventyExtensionMap
);
}
static cleanupEngineName(tmplPath) {
return TemplateRender._cleanupEngineName(tmplPath, EleventyExtensionMap);
}
static _cleanupEngineName(tmplPath, extensionMapRef) {
return extensionMapRef.getKey(tmplPath);
}
static hasEngine(tmplPath) {
let name = TemplateRender.cleanupEngineName(tmplPath);
return TemplateEngine.hasEngine(name);
}
static parseEngineOverrides(engineName) {
let overlappingEngineWarningCount = 0;
let engines = [];
let uniqueLookup = {};
let usingMarkdown = false;
(engineName || "")
.split(",")
.map(name => {
return name.toLowerCase().trim();
})
.forEach(name => {
// html is assumed (treated as plaintext by the system)
if (!name || name === "html") {
return;
}
if (name === "md") {
usingMarkdown = true;
return;
}
if (!uniqueLookup[name]) {
engines.push(name);
uniqueLookup[name] = true;
// we already short circuit md and html types above
overlappingEngineWarningCount++;
}
});
if (overlappingEngineWarningCount > 1) {
throw new Error(
`Dont mix multiple templating engines in your front matter overrides (exceptions for HTML and Markdown). You used: ${engineName}`
);
}
// markdown should always be first
if (usingMarkdown) {
// todo use unshift or something (no wifi here to look up docs :D)
engines = ["md"].concat(engines);
}
return engines;
}
// used for error logging.
getEnginesStr() {
if (this.engineName === "md" && this.useMarkdown) {
return this.parseMarkdownWith + " (and markdown)";
}
return this.engineName;
}
setEngineOverride(engineName, bypassMarkdown) {
let engines = TemplateRender.parseEngineOverrides(engineName);
// when overriding, Template Engines with HTML will instead use the Template Engine as primary and output HTML
// So any HTML engine usage here will never use a preprocessor templating engine.
this.setHtmlEngine(false);
if (!engines.length) {
this.init("html");
return;
}
this.init(engines[0]);
let usingMarkdown = engines[0] === "md" && !bypassMarkdown;
this.setUseMarkdown(usingMarkdown);
if (usingMarkdown) {
// false means only parse markdown and not with a preprocessor template engine
this.setMarkdownEngine(engines.length > 1 ? engines[1] : false);
}
}
getEngineName() {
return this.engineName;
}
getIncludesDir() {
return this.includesDir;
}
_normalizeIncludesDir(dir) {
return TemplatePath.join(
dir ? dir : this.config.dir.input,
this.config.dir.includes
);
}
isEngine(engine) {
return this.engineName === engine;
}
setUseMarkdown(useMarkdown) {
this.useMarkdown = !!useMarkdown;
}
setMarkdownEngine(markdownEngine) {
this.parseMarkdownWith = markdownEngine;
}
setHtmlEngine(htmlEngineName) {
this.parseHtmlWith = htmlEngineName;
}
async render(str, data) {
return this.engine.render(str, data);
}
async getCompiledTemplate(str) {
// TODO refactor better, move into TemplateEngine logic
if (this.engineName === "md") {
return this.engine.compile(
str,
this.path,
this.parseMarkdownWith,
!this.useMarkdown
);
} else if (this.engineName === "html") {
return this.engine.compile(str, this.path, this.parseHtmlWith);
} else {
return this.engine.compile(str, this.path);
}
}
}
module.exports = TemplateRender;

220
node_modules/@11ty/eleventy/src/TemplateWriter.js generated vendored Normal file
View File

@@ -0,0 +1,220 @@
const Template = require("./Template");
const TemplatePath = require("./TemplatePath");
const TemplateMap = require("./TemplateMap");
const TemplateRender = require("./TemplateRender");
const EleventyFiles = require("./EleventyFiles");
const EleventyBaseError = require("./EleventyBaseError");
const EleventyErrorHandler = require("./EleventyErrorHandler");
const EleventyErrorUtil = require("./EleventyErrorUtil");
const config = require("./Config");
const debug = require("debug")("Eleventy:TemplateWriter");
const debugDev = require("debug")("Dev:Eleventy:TemplateWriter");
class TemplateWriterWriteError extends EleventyBaseError {}
function TemplateWriter(
inputPath,
outputDir,
templateFormats, // TODO remove this, see `.getFileManager()` first
templateData,
isPassthroughAll
) {
this.config = config.getConfig();
this.input = inputPath;
this.inputDir = TemplatePath.getDir(inputPath);
this.outputDir = outputDir;
this.templateFormats = templateFormats;
this.templateData = templateData;
this.isVerbose = true;
this.isDryRun = false;
this.writeCount = 0;
// TODO can we get rid of this? Its only used for tests in getFileManager()
this.passthroughAll = isPassthroughAll;
}
/* For testing */
TemplateWriter.prototype.overrideConfig = function(config) {
this.config = config;
};
TemplateWriter.prototype.restart = function() {
this.writeCount = 0;
debugDev("Resetting counts to 0");
};
TemplateWriter.prototype.setEleventyFiles = function(eleventyFiles) {
this.eleventyFiles = eleventyFiles;
};
TemplateWriter.prototype.getFileManager = function() {
// usually Eleventy.js will setEleventyFiles with the EleventyFiles manager
if (!this.eleventyFiles) {
// if not, we can create one (used only by tests)
this.eleventyFiles = new EleventyFiles(
this.input,
this.outputDir,
this.templateFormats,
this.passthroughAll
);
this.eleventyFiles.init();
}
return this.eleventyFiles;
};
TemplateWriter.prototype._getAllPaths = async function() {
return await this.getFileManager().getFiles();
};
TemplateWriter.prototype._createTemplate = function(path) {
let tmpl = new Template(
path,
this.inputDir,
this.outputDir,
this.templateData
);
tmpl.setIsVerbose(this.isVerbose);
tmpl.setDryRun(this.isDryRun);
/*
* Sample filter: arg str, return pretty HTML string
* function(str) {
* return pretty(str, { ocd: true });
* }
*/
for (let transformName in this.config.filters) {
let transform = this.config.filters[transformName];
if (typeof transform === "function") {
tmpl.addTransform(transform);
}
}
for (let linterName in this.config.linters) {
let linter = this.config.linters[linterName];
if (typeof linter === "function") {
tmpl.addLinter(linter);
}
}
return tmpl;
};
TemplateWriter.prototype._addToTemplateMap = async function(paths) {
let promises = [];
for (let path of paths) {
if (TemplateRender.hasEngine(path)) {
promises.push(
this.templateMap.add(this._createTemplate(path)).then(() => {
debug(`${path} added to map.`);
})
);
}
}
return Promise.all(promises);
};
TemplateWriter.prototype._createTemplateMap = async function(paths) {
this.templateMap = new TemplateMap();
await this._addToTemplateMap(paths);
await this.templateMap.cache();
debugDev("TemplateMap cache complete.");
return this.templateMap;
};
TemplateWriter.prototype._writeTemplate = async function(mapEntry) {
let tmpl = mapEntry.template;
// we dont re-use the map templateContent because it doesnt include layouts
return tmpl.writeMapEntry(mapEntry).then(() => {
this.writeCount += tmpl.getWriteCount();
});
};
TemplateWriter.prototype.write = async function() {
let promises = [];
let paths = await this._getAllPaths();
debug("Found: %o", paths);
promises.push(
this.getFileManager()
.getPassthroughManager()
.copyAll(paths)
.catch(e => {
EleventyErrorHandler.warn(e, "Error with passthrough copy");
return Promise.reject(
new TemplateWriterWriteError(`Having trouble copying`, e)
);
})
);
// TODO optimize await here
await this._createTemplateMap(paths);
debug("Template map created.");
let mapEntry;
let usedTemplateContentTooEarlyMap = [];
for (mapEntry of this.templateMap.getMap()) {
promises.push(
this._writeTemplate(mapEntry).catch(function(e) {
// Premature templateContent in layout render, this also happens in
// TemplateMap.populateContentDataInMap for non-layout content
if (EleventyErrorUtil.isPrematureTemplateContentError(e)) {
usedTemplateContentTooEarlyMap.push(mapEntry);
} else {
return Promise.reject(
new TemplateWriterWriteError(
`Having trouble writing template: ${mapEntry.outputPath}`,
e
)
);
}
})
);
}
for (mapEntry of usedTemplateContentTooEarlyMap) {
promises.push(
this._writeTemplate(mapEntry).catch(function(e) {
return Promise.reject(
new TemplateWriterWriteError(
`Having trouble writing template (second pass): ${mapEntry.outputPath}`,
e
)
);
})
);
}
return Promise.all(promises).catch(e => {
EleventyErrorHandler.error(e, "Error writing templates");
throw e;
});
};
TemplateWriter.prototype.setVerboseOutput = function(isVerbose) {
this.isVerbose = isVerbose;
};
TemplateWriter.prototype.setDryRun = function(isDryRun) {
this.isDryRun = !!isDryRun;
this.getFileManager()
.getPassthroughManager()
.setDryRun(this.isDryRun);
};
TemplateWriter.prototype.getCopyCount = function() {
return this.getFileManager()
.getPassthroughManager()
.getCopyCount();
};
TemplateWriter.prototype.getWriteCount = function() {
return this.writeCount;
};
module.exports = TemplateWriter;

545
node_modules/@11ty/eleventy/src/UserConfig.js generated vendored Normal file
View File

@@ -0,0 +1,545 @@
const EventEmitter = require("events");
const chalk = require("chalk");
const semver = require("semver");
const { DateTime } = require("luxon");
const EleventyBaseError = require("./EleventyBaseError");
const bench = require("./BenchmarkManager").get("Configuration");
const debug = require("debug")("Eleventy:UserConfig");
const pkg = require("../package.json");
class UserConfigError extends EleventyBaseError {}
// API to expose configuration options in config file
class UserConfig {
constructor() {
this.reset();
}
reset() {
debug("Resetting EleventyConfig to initial values.");
this.events = new EventEmitter();
this.collections = {};
this.liquidOptions = {};
this.liquidTags = {};
this.liquidFilters = {};
this.liquidShortcodes = {};
this.liquidPairedShortcodes = {};
this.nunjucksFilters = {};
this.nunjucksAsyncFilters = {};
this.nunjucksTags = {};
this.nunjucksShortcodes = {};
this.nunjucksPairedShortcodes = {};
this.handlebarsHelpers = {};
this.handlebarsShortcodes = {};
this.handlebarsPairedShortcodes = {};
this.javascriptFunctions = {};
this.pugOptions = {};
this.ejsOptions = {};
this.markdownHighlighter = null;
this.libraryOverrides = {};
this.passthroughCopies = {};
this.layoutAliases = {};
this.linters = {};
// now named `transforms` in API
this.filters = {};
this.activeNamespace = "";
this.DateTime = DateTime;
this.dynamicPermalinks = true;
this.useGitIgnore = true;
this.dataDeepMerge = false;
this.experiments = new Set();
// this.userExtensionMap = {};
// this.templateExtensionAliases = {};
this.watchJavaScriptDependencies = true;
this.browserSyncConfig = {};
}
versionCheck(expected) {
if (!semver.satisfies(pkg.version, expected)) {
throw new UserConfigError(
`This project requires the eleventy version to match '${expected}' but found ${pkg.version}. Use \`npm update @11ty/eleventy -g\` to upgrade the eleventy global or \`npm update @11ty/eleventy --save\` to upgrade your local project version.`
);
}
}
on(eventName, callback) {
return this.events.on(eventName, callback);
}
emit(eventName, ...args) {
return this.events.emit(eventName, ...args);
}
// This is a method for plugins, probably shouldnt use this in projects.
// Projects should use `setLibrary` as documented here:
// https://github.com/11ty/eleventy/blob/master/docs/engines/markdown.md#use-your-own-options
addMarkdownHighlighter(highlightFn) {
this.markdownHighlighter = highlightFn;
}
// tagCallback: function(liquidEngine) { return { parse: …, render: … }} };
addLiquidTag(name, tagFn) {
name = this.getNamespacedName(name);
if (typeof tagFn !== "function") {
throw new UserConfigError(
`EleventyConfig.addLiquidTag expects a callback function to be passed in for ${name}: addLiquidTag(name, function(liquidEngine) { return { parse: …, render: … } })`
);
}
if (this.liquidTags[name]) {
debug(
chalk.yellow(
"Warning, overwriting a Liquid tag with `addLiquidTag(%o)`"
),
name
);
}
this.liquidTags[name] = bench.add(`"${name}" Liquid Custom Tag`, tagFn);
}
addLiquidFilter(name, callback) {
name = this.getNamespacedName(name);
if (this.liquidFilters[name]) {
debug(
chalk.yellow(
"Warning, overwriting a Liquid filter with `addLiquidFilter(%o)`"
),
name
);
}
this.liquidFilters[name] = bench.add(`"${name}" Liquid Filter`, callback);
}
addNunjucksAsyncFilter(name, callback) {
name = this.getNamespacedName(name);
if (this.nunjucksAsyncFilters[name]) {
debug(
chalk.yellow(
"Warning, overwriting a Nunjucks filter with `addNunjucksAsyncFilter(%o)`"
),
name
);
}
this.nunjucksAsyncFilters[name] = bench.add(
`"${name}" Nunjucks Async Filter`,
callback
);
}
// Support the nunjucks style syntax for asynchronous filter add
addNunjucksFilter(name, callback, isAsync) {
if (isAsync) {
// namespacing happens downstream
this.addNunjucksAsyncFilter(name, callback);
} else {
name = this.getNamespacedName(name);
if (this.nunjucksFilters[name]) {
debug(
chalk.yellow(
"Warning, overwriting a Nunjucks filter with `addNunjucksFilter(%o)`"
),
name
);
}
this.nunjucksFilters[name] = bench.add(
`"${name}" Nunjucks Filter`,
callback
);
}
}
addHandlebarsHelper(name, callback) {
name = this.getNamespacedName(name);
if (this.handlebarsHelpers[name]) {
debug(
chalk.yellow(
"Warning, overwriting a Handlebars helper with `addHandlebarsHelper(%o)`."
),
name
);
}
this.handlebarsHelpers[name] = bench.add(
`"${name}" Handlebars Helper`,
callback
);
}
addFilter(name, callback) {
debug("Adding universal filter %o", this.getNamespacedName(name));
// namespacing happens downstream
this.addLiquidFilter(name, callback);
this.addNunjucksFilter(name, callback);
this.addJavaScriptFunction(name, callback);
// TODO remove Handlebars helpers in Universal Filters. Use shortcodes instead (the Handlebars template syntax is the same).
this.addHandlebarsHelper(name, callback);
}
addNunjucksTag(name, tagFn) {
name = this.getNamespacedName(name);
if (typeof tagFn !== "function") {
throw new UserConfigError(
`EleventyConfig.addNunjucksTag expects a callback function to be passed in for ${name}: addNunjucksTag(name, function(nunjucksEngine) {})`
);
}
if (this.nunjucksTags[name]) {
debug(
chalk.yellow(
"Warning, overwriting a Nunjucks tag with `addNunjucksTag(%o)`"
),
name
);
}
this.nunjucksTags[name] = bench.add(`"${name}" Nunjucks Custom Tag`, tagFn);
}
addTransform(name, callback) {
name = this.getNamespacedName(name);
// these are now called transforms
// this naming is kept here for backwards compatibility
// TODO major version change
this.filters[name] = callback;
}
addLinter(name, callback) {
name = this.getNamespacedName(name);
this.linters[name] = callback;
}
addLayoutAlias(from, to) {
this.layoutAliases[from] = to;
}
// get config defined collections
getCollections() {
return this.collections;
}
addCollection(name, callback) {
name = this.getNamespacedName(name);
if (this.collections[name]) {
throw new UserConfigError(
`config.addCollection(${name}) already exists. Try a different name for your collection.`
);
}
this.collections[name] = callback;
}
addPlugin(plugin, options) {
debug("Adding plugin (unknown name: check your config file).");
if (typeof plugin === "function") {
plugin(this);
} else if (plugin && plugin.configFunction) {
if (options && typeof options.init === "function") {
options.init.call(this, plugin.initArguments || {});
}
plugin.configFunction(this, options);
} else {
throw new UserConfigError(
"Invalid EleventyConfig.addPlugin signature. Should be a function or a valid Eleventy plugin object."
);
}
}
getNamespacedName(name) {
return this.activeNamespace + name;
}
namespace(pluginNamespace, callback) {
let validNamespace = pluginNamespace && typeof pluginNamespace === "string";
if (validNamespace) {
this.activeNamespace = pluginNamespace || "";
}
callback();
if (validNamespace) {
this.activeNamespace = "";
}
}
/**
* Adds a path to a file or directory to the list of pass-through copies
* which are copied as-is to the output.
*
* @param {string|object} fileOrDir The path to the file or directory that should
* be copied. OR an object where the key is the input glob and the property is the output directory
* @returns {any} a reference to the `EleventyConfig` object.
* @memberof EleventyConfig
*/
addPassthroughCopy(fileOrDir) {
if (typeof fileOrDir === "string") {
this.passthroughCopies[fileOrDir] = true;
} else {
Object.assign(this.passthroughCopies, fileOrDir);
}
return this;
}
setTemplateFormats(templateFormats) {
if (typeof templateFormats === "string") {
templateFormats = templateFormats.split(",").map(format => format.trim());
}
this.templateFormats = templateFormats;
}
setLibrary(engineName, libraryInstance) {
// Pug options are passed to `compile` and not in the library constructor so we dont need to warn
if (engineName === "liquid" && this.mdOptions) {
debug(
"WARNING: using `eleventyConfig.setLibrary` will override any configuration set using `.setLiquidOptions` or with the `liquidOptions` key in the config object. Youll need to pass these options to the library yourself."
);
}
this.libraryOverrides[engineName.toLowerCase()] = libraryInstance;
}
setPugOptions(options) {
this.pugOptions = options;
}
setLiquidOptions(options) {
this.liquidOptions = options;
}
setEjsOptions(options) {
this.ejsOptions = options;
}
setDynamicPermalinks(enabled) {
this.dynamicPermalinks = !!enabled;
}
setUseGitIgnore(enabled) {
this.useGitIgnore = !!enabled;
}
addShortcode(name, callback) {
debug("Adding universal shortcode %o", this.getNamespacedName(name));
this.addNunjucksShortcode(name, callback);
this.addLiquidShortcode(name, callback);
this.addHandlebarsShortcode(name, callback);
this.addJavaScriptFunction(name, callback);
}
addNunjucksShortcode(name, callback) {
name = this.getNamespacedName(name);
if (this.nunjucksShortcodes[name]) {
debug(
chalk.yellow(
"Warning, overwriting a Nunjucks Shortcode with `addNunjucksShortcode(%o)`"
),
name
);
}
this.nunjucksShortcodes[name] = bench.add(
`"${name}" Nunjucks Shortcode`,
callback
);
}
addLiquidShortcode(name, callback) {
name = this.getNamespacedName(name);
if (this.liquidShortcodes[name]) {
debug(
chalk.yellow(
"Warning, overwriting a Liquid Shortcode with `addLiquidShortcode(%o)`"
),
name
);
}
this.liquidShortcodes[name] = bench.add(
`"${name}" Liquid Shortcode`,
callback
);
}
addHandlebarsShortcode(name, callback) {
name = this.getNamespacedName(name);
if (this.handlebarsShortcodes[name]) {
debug(
chalk.yellow(
"Warning, overwriting a Handlebars Shortcode with `addHandlebarsShortcode(%o)`"
),
name
);
}
this.handlebarsShortcodes[name] = bench.add(
`"${name}" Handlebars Shortcode`,
callback
);
}
addPairedShortcode(name, callback) {
this.addPairedNunjucksShortcode(name, callback);
this.addPairedLiquidShortcode(name, callback);
this.addPairedHandlebarsShortcode(name, callback);
this.addJavaScriptFunction(name, callback);
}
addPairedNunjucksShortcode(name, callback) {
name = this.getNamespacedName(name);
if (this.nunjucksPairedShortcodes[name]) {
debug(
chalk.yellow(
"Warning, overwriting a Nunjucks Paired Shortcode with `addPairedNunjucksShortcode(%o)`"
),
name
);
}
this.nunjucksPairedShortcodes[name] = bench.add(
`"${name}" Nunjucks Paired Shortcode`,
callback
);
}
addPairedLiquidShortcode(name, callback) {
name = this.getNamespacedName(name);
if (this.liquidPairedShortcodes[name]) {
debug(
chalk.yellow(
"Warning, overwriting a Liquid Paired Shortcode with `addPairedLiquidShortcode(%o)`"
),
name
);
}
this.liquidPairedShortcodes[name] = bench.add(
`"${name}" Liquid Paired Shortcode`,
callback
);
}
addPairedHandlebarsShortcode(name, callback) {
name = this.getNamespacedName(name);
if (this.handlebarsPairedShortcodes[name]) {
debug(
chalk.yellow(
"Warning, overwriting a Handlebars Paired Shortcode with `addPairedHandlebarsShortcode(%o)`"
),
name
);
}
this.handlebarsPairedShortcodes[name] = bench.add(
`"${name}" Handlebars Paired Shortcode`,
callback
);
}
addJavaScriptFunction(name, callback) {
name = this.getNamespacedName(name);
if (this.javascriptFunctions[name]) {
debug(
chalk.yellow(
"Warning, overwriting a JavaScript template function with `addJavaScriptFunction(%o)`"
),
name
);
}
this.javascriptFunctions[name] = bench.add(
`"${name}" JavaScript Function`,
callback
);
}
addExperiment(key) {
this.experiments.add(key);
}
setDataDeepMerge(deepMerge) {
this.dataDeepMerge = !!deepMerge;
}
// addTemplateExtensionAlias(targetKey, extension) {
// this.templateExtensionAliases[extension] = targetKey;
// }
setWatchJavaScriptDependencies(watchEnabled) {
this.watchJavaScriptDependencies = !!watchEnabled;
}
setBrowserSyncConfig(options = {}) {
this.browserSyncConfig = options;
}
setFrontMatterParsingOptions(options = {}) {
this.frontMatterParsingOptions = options;
}
getMergingConfigObject() {
return {
templateFormats: this.templateFormats,
filters: this.filters, // now called transforms
linters: this.linters,
layoutAliases: this.layoutAliases,
passthroughCopies: this.passthroughCopies,
liquidOptions: this.liquidOptions,
liquidTags: this.liquidTags,
liquidFilters: this.liquidFilters,
liquidShortcodes: this.liquidShortcodes,
liquidPairedShortcodes: this.liquidPairedShortcodes,
nunjucksFilters: this.nunjucksFilters,
nunjucksAsyncFilters: this.nunjucksAsyncFilters,
nunjucksTags: this.nunjucksTags,
nunjucksShortcodes: this.nunjucksShortcodes,
nunjucksPairedShortcodes: this.nunjucksPairedShortcodes,
handlebarsHelpers: this.handlebarsHelpers,
handlebarsShortcodes: this.handlebarsShortcodes,
handlebarsPairedShortcodes: this.handlebarsPairedShortcodes,
javascriptFunctions: this.javascriptFunctions,
pugOptions: this.pugOptions,
ejsOptions: this.ejsOptions,
markdownHighlighter: this.markdownHighlighter,
libraryOverrides: this.libraryOverrides,
dynamicPermalinks: this.dynamicPermalinks,
useGitIgnore: this.useGitIgnore,
dataDeepMerge: this.dataDeepMerge,
experiments: this.experiments,
// templateExtensionAliases: this.templateExtensionAliases,
watchJavaScriptDependencies: this.watchJavaScriptDependencies,
browserSyncConfig: this.browserSyncConfig,
frontMatterParsingOptions: this.frontMatterParsingOptions
};
}
// addExtension(fileExtension, userClass) {
// this.userExtensionMap[ fileExtension ] = userClass;
// }
}
module.exports = UserConfig;

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

@@ -0,0 +1,20 @@
module.exports = function(str, options) {
options = Object.assign(
{
lowercaseRestOfWord: false
},
options
);
return str
.split(" ")
.map(function(word) {
return (
word.substr(0, 1).toUpperCase() +
(options.lowercaseRestOfWord
? word.substr(1).toLowerCase()
: word.substr(1))
);
})
.join(" ");
};

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

@@ -0,0 +1,51 @@
const isPlainObject = require("lodash/isPlainObject");
const OVERRIDE_PREFIX = "override:";
function getMergedItem(target, source, parentKey) {
// if key is prefixed with OVERRIDE_PREFIX, it just keeps the new source value (no merging)
if (parentKey && parentKey.indexOf(OVERRIDE_PREFIX) === 0) {
return source;
}
if (!target) {
return source;
} else if (Array.isArray(target) && Array.isArray(source)) {
return target.concat(source);
} else if (isPlainObject(target)) {
if (isPlainObject(source)) {
for (var key in source) {
let newKey = key;
if (key.indexOf(OVERRIDE_PREFIX) === 0) {
newKey = key.substr(OVERRIDE_PREFIX.length);
}
target[newKey] = getMergedItem(target[key], source[key], newKey);
}
}
return target;
} else {
// number, string, class instance, etc
return source;
}
}
function Merge(target, ...sources) {
// Remove override prefixes from root target.
if (isPlainObject(target)) {
for (var key in target) {
if (key.indexOf(OVERRIDE_PREFIX) === 0) {
target[key.substr(OVERRIDE_PREFIX.length)] = target[key];
delete target[key];
}
}
}
for (var source of sources) {
if (!source) {
continue;
}
target = getMergedItem(target, source);
}
return target;
}
module.exports = Merge;

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

@@ -0,0 +1,3 @@
module.exports = function(count, singleWord, pluralWord) {
return count === 1 ? singleWord : pluralWord;
};

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

@@ -0,0 +1,144 @@
const capitalize = require("./Capitalize");
class Sortable {
constructor() {
this.sortAscending = true;
this.sortNumeric = false;
this.items = [];
this.sortFunctionStringMap = {
"A-Z": "Ascending",
"Z-A": "Descending",
"0-9": "NumericAscending",
"9-0": "NumericDescending"
};
}
get length() {
return this.items.length;
}
add(item) {
this.items.push(item);
}
sort(sortFunction) {
if (!sortFunction) {
sortFunction = this.getSortFunction();
} else if (typeof sortFunction === "string") {
if (sortFunction in this.sortFunctionStringMap) {
sortFunction = this.sortFunctionStringMap[sortFunction];
}
sortFunction = Sortable["sortFunction" + capitalize(sortFunction)];
}
return this.items.filter(() => true).sort(sortFunction);
}
sortAscending() {
return this.sort(this.getSortFunctionAscending);
}
sortDescending() {
return this.sort(this.getSortFunctionDescending);
}
isSortAscending() {
return this.sortAscending;
}
isSortNumeric() {
return this.sortNumeric;
}
setSortDescending() {
this.sortAscending = false;
}
setSortAscending(isAscending) {
this.sortAscending = isAscending;
}
setSortNumeric(isNumeric) {
this.sortNumeric = isNumeric;
}
/* Sort functions */
static sortFunctionNumericAscending(a, b) {
return a - b;
}
static sortFunctionNumericDescending(a, b) {
return b - a;
}
static sortFunctionAscending(a, b) {
if (a > b) {
return 1;
} else if (a < b) {
return -1;
}
return 0;
}
static sortFunctionDescending(a, b) {
return Sortable.sortFunctionAscending(b, a);
}
static sortFunctionAlphabeticAscending(a, b) {
return Sortable.sortFunctionAscending(a, b);
}
static sortFunctionAlphabeticDescending(a, b) {
return Sortable.sortFunctionAscending(b, a);
}
static sortFunctionDate(mapA, mapB) {
return Sortable.sortFunctionNumericAscending(
mapA.date.getTime(),
mapB.date.getTime()
);
}
static sortFunctionDateInputPath(mapA, mapB) {
let sortDate = Sortable.sortFunctionNumericAscending(
mapA.date.getTime(),
mapB.date.getTime()
);
if (sortDate === 0) {
return Sortable.sortFunctionAlphabeticAscending(
mapA.inputPath,
mapB.inputPath
);
}
return sortDate;
}
/* End sort functions */
getSortFunction() {
if (this.sortAscending) {
return this.getSortFunctionAscending();
} else {
return this.getSortFunctionDescending();
}
}
getSortFunctionAscending() {
if (this.sortNumeric) {
return Sortable.sortFunctionNumericAscending;
} else {
return Sortable.sortFunctionAlphabeticAscending;
}
}
getSortFunctionDescending() {
if (this.sortNumeric) {
return Sortable.sortFunctionNumericDescending;
} else {
return Sortable.sortFunctionAlphabeticDescending;
}
}
}
module.exports = Sortable;