This commit is contained in:
abs3nt 2024-07-07 18:49:38 -07:00
parent fa13ba83d7
commit fe70fae95f
Signed by: abs3nt
GPG Key ID: A7BD96A8BAB04C09
4559 changed files with 785618 additions and 12 deletions

1
.yarnrc.yml Normal file
View File

@ -0,0 +1 @@
nodeLinker: node-modules

View File

@ -1 +0,0 @@
<h1>Heading</h1>

View File

@ -1,2 +0,0 @@
<!doctype html><title>abs3nt.dev</title>
<p>hello i am abs3nt</p>

8
eleventy.config.js Normal file
View File

@ -0,0 +1,8 @@
module.exports = function (eleventyConfig) {
return {
dir: {
input: "src",
output: "dist",
},
};
};

View File

@ -1,2 +0,0 @@
<!doctype html><title>abs3nt.dev</title>
<p>hello i am abs3nt</p>

1
node_modules/.bin/acorn generated vendored Symbolic link
View File

@ -0,0 +1 @@
../acorn/bin/acorn

1
node_modules/.bin/cssesc generated vendored Symbolic link
View File

@ -0,0 +1 @@
../cssesc/bin/cssesc

1
node_modules/.bin/dev-ip generated vendored Symbolic link
View File

@ -0,0 +1 @@
../dev-ip/lib/dev-ip.js

1
node_modules/.bin/ejs generated vendored Symbolic link
View File

@ -0,0 +1 @@
../ejs/bin/cli.js

1
node_modules/.bin/eleventy generated vendored Symbolic link
View File

@ -0,0 +1 @@
../@11ty/eleventy/cmd.js

1
node_modules/.bin/eleventy-dev-server generated vendored Symbolic link
View File

@ -0,0 +1 @@
../@11ty/eleventy-dev-server/cmd.js

1
node_modules/.bin/errno generated vendored Symbolic link
View File

@ -0,0 +1 @@
../errno/cli.js

1
node_modules/.bin/esparse generated vendored Symbolic link
View File

@ -0,0 +1 @@
../esprima/bin/esparse.js

1
node_modules/.bin/esvalidate generated vendored Symbolic link
View File

@ -0,0 +1 @@
../esprima/bin/esvalidate.js

1
node_modules/.bin/handlebars generated vendored Symbolic link
View File

@ -0,0 +1 @@
../handlebars/bin/handlebars

1
node_modules/.bin/jake generated vendored Symbolic link
View File

@ -0,0 +1 @@
../jake/bin/cli.js

1
node_modules/.bin/jiti generated vendored Symbolic link
View File

@ -0,0 +1 @@
../jiti/bin/jiti.js

1
node_modules/.bin/js-yaml generated vendored Symbolic link
View File

@ -0,0 +1 @@
../js-yaml/bin/js-yaml.js

1
node_modules/.bin/liquid generated vendored Symbolic link
View File

@ -0,0 +1 @@
../liquidjs/bin/liquid.js

1
node_modules/.bin/liquidjs generated vendored Symbolic link
View File

@ -0,0 +1 @@
../liquidjs/bin/liquid.js

1
node_modules/.bin/markdown-it generated vendored Symbolic link
View File

@ -0,0 +1 @@
../markdown-it/bin/markdown-it.js

1
node_modules/.bin/mime generated vendored Symbolic link
View File

@ -0,0 +1 @@
../mime/cli.js

1
node_modules/.bin/mkdirp generated vendored Symbolic link
View File

@ -0,0 +1 @@
../mkdirp/bin/cmd.js

1
node_modules/.bin/mustache generated vendored Symbolic link
View File

@ -0,0 +1 @@
../mustache/bin/mustache

1
node_modules/.bin/nanoid generated vendored Symbolic link
View File

@ -0,0 +1 @@
../nanoid/bin/nanoid.cjs

1
node_modules/.bin/node-which generated vendored Symbolic link
View File

@ -0,0 +1 @@
../which/bin/node-which

1
node_modules/.bin/nunjucks-precompile generated vendored Symbolic link
View File

@ -0,0 +1 @@
../nunjucks/bin/precompile

1
node_modules/.bin/parser generated vendored Symbolic link
View File

@ -0,0 +1 @@
../@babel/parser/bin/babel-parser.js

1
node_modules/.bin/resolve generated vendored Symbolic link
View File

@ -0,0 +1 @@
../resolve/bin/resolve

1
node_modules/.bin/rimraf generated vendored Symbolic link
View File

@ -0,0 +1 @@
../rimraf/bin.js

1
node_modules/.bin/semver generated vendored Symbolic link
View File

@ -0,0 +1 @@
../semver/bin/semver.js

1
node_modules/.bin/sucrase generated vendored Symbolic link
View File

@ -0,0 +1 @@
../sucrase/bin/sucrase

1
node_modules/.bin/sucrase-node generated vendored Symbolic link
View File

@ -0,0 +1 @@
../sucrase/bin/sucrase-node

1
node_modules/.bin/tailwind generated vendored Symbolic link
View File

@ -0,0 +1 @@
../tailwindcss/lib/cli.js

1
node_modules/.bin/tailwindcss generated vendored Symbolic link
View File

@ -0,0 +1 @@
../tailwindcss/lib/cli.js

1
node_modules/.bin/uglifyjs generated vendored Symbolic link
View File

@ -0,0 +1 @@
../uglify-js/bin/uglifyjs

1
node_modules/.bin/yaml generated vendored Symbolic link
View File

@ -0,0 +1 @@
../yaml/bin.mjs

1169
node_modules/.yarn-state.yml generated vendored Normal file

File diff suppressed because it is too large Load Diff

21
node_modules/@11ty/dependency-tree/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Eleventy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

92
node_modules/@11ty/dependency-tree/README.md generated vendored Normal file
View File

@ -0,0 +1,92 @@
# dependency-tree
Returns an unordered array of local paths to dependencies of a node JavaScript file (everything it or any of its dependencies `require`s).
Reduced feature (faster) alternative to the [`dependency-tree` package](https://www.npmjs.com/package/dependency-tree) that only works with stock node JS. This is used by Eleventy to find dependencies of a JavaScript file to watch for changes to re-run Eleventys build.
## Big Huge Caveat
⚠ A big caveat to this plugin is that it will require the file in order to build a dependency tree. So if your module has side effects and you dont want it to execute—do not use this!
## Installation
```
npm install --save-dev @11ty/dependency-tree
```
## Features
* Ignores `node_modules`
* Or, use `nodeModuleNamesOnly` to return a list of node_modules packages (added in v2.0.0)
* Ignores Nodes built-ins (e.g. `path`)
* Handles circular dependencies (Node does this too)
## Usage
```js
// my-file.js
// if my-local-dependency.js has dependencies, it will include those too
const test = require("./my-local-dependency.js");
// ignored, is a built-in
const path = require("path");
```
```js
const DependencyTree = require("@11ty/dependency-tree");
DependencyTree("./my-file.js");
// returns ["./my-local-dependency.js"]
```
### `allowNotFound`
```js
const DependencyTree = require("@11ty/dependency-tree");
DependencyTree("./this-does-not-exist.js"); // throws an error
DependencyTree("./this-does-not-exist.js", { allowNotFound: true });
// returns []
```
### `nodeModuleNames`
(Added in v2.0.1) Controls whether or not node package names are included in the list of dependencies.
* `nodeModuleNames: "include"`: included alongside the local JS files.
* `nodeModuleNames: "exclude"` (default): node module package names are excluded.
* `nodeModuleNames: "only"`: only node module package names are returned.
```js
// my-file.js:
require("./my-local-dependency.js");
require("@11ty/eleventy");
```
```js
const DependencyTree = require("@11ty/dependency-tree");
DependencyTree("./my-file.js");
// returns ["./my-local-dependency.js"]
DependencyTree("./my-file.js", { nodeModuleNames: "exclude" });
// returns ["./my-local-dependency.js"]
DependencyTree("./my-file.js", { nodeModuleNames: "include" });
// returns ["./my-local-dependency.js", "@11ty/eleventy"]
DependencyTree("./my-file.js", { nodeModuleNames: "only" });
// returns ["@11ty/eleventy"]
```
#### (Deprecated) `nodeModuleNamesOnly`
(Added in v2.0.0) Changed to use `nodeModuleNames` option instead. Backwards compatibility is maintained automatically.
* `nodeModuleNamesOnly: false` is mapped to `nodeModuleNames: "exclude"`
* `nodeModuleNamesOnly: true` is mapped to `nodeModuleNames: "only"`
If both `nodeModuleNamesOnly` and `nodeModuleNames` are included in options, `nodeModuleNames` takes precedence.

120
node_modules/@11ty/dependency-tree/main.js generated vendored Normal file
View File

@ -0,0 +1,120 @@
const path = require("path");
function getAbsolutePath(filename) {
let normalizedFilename = path.normalize(filename); // removes dot slash
let hasDotSlash = filename.startsWith("./");
return hasDotSlash ? path.join(path.resolve("."), normalizedFilename) : normalizedFilename;
}
function getRelativePath(filename) {
let normalizedFilename = path.normalize(filename); // removes dot slash
let workingDirectory = path.resolve(".");
let result = "./" + (normalizedFilename.startsWith(workingDirectory) ? normalizedFilename.substr(workingDirectory.length + 1) : normalizedFilename);
return result;
}
function getNodeModuleName(filename) {
let foundNodeModules = false;
let moduleName = [];
let s = filename.split(path.sep);
for(let entry of s) {
if(foundNodeModules) {
moduleName.push(entry);
if(!entry.startsWith("@")) {
return moduleName.join("/");
}
}
if(entry === "node_modules") {
foundNodeModules = true;
}
}
return false;
}
/* unordered */
function getDependenciesFor(filename, avoidCircular, optionsArg = {}) {
// backwards compatibility with `nodeModuleNamesOnly` boolean option
// Using `nodeModuleNames` property moving forward
if(("nodeModuleNamesOnly" in optionsArg) && !("nodeModuleNames" in optionsArg)) {
if(optionsArg.nodeModuleNamesOnly === true) {
optionsArg.nodeModuleNames = "only";
}
if(optionsArg.nodeModuleNamesOnly === false) {
optionsArg.nodeModuleNames = "exclude";
}
}
let options = Object.assign({
allowNotFound: false,
nodeModuleNames: "exclude", // also "include" or "only"
}, optionsArg);
let absoluteFilename = getAbsolutePath(filename)
try {
require(absoluteFilename);
} catch(e) {
if(e.code === "MODULE_NOT_FOUND" && options.allowNotFound) {
// do nothing
} else {
throw e;
}
}
let mod;
for(let entry in require.cache) {
if(entry === absoluteFilename) {
mod = require.cache[entry];
break;
}
}
let dependencies = new Set();
if(!mod) {
if(!options.allowNotFound) {
throw new Error(`Could not find ${filename} in @11ty/dependency-tree`);
}
} else {
let relativeFilename = getRelativePath(mod.filename);
if(!avoidCircular) {
avoidCircular = {};
} else if(options.nodeModuleNames !== "only") {
dependencies.add(relativeFilename);
}
avoidCircular[relativeFilename] = true;
if(mod.children) {
for(let child of mod.children) {
let relativeChildFilename = getRelativePath(child.filename);
let nodeModuleName = getNodeModuleName(child.filename);
if(options.nodeModuleNames !== "exclude" && nodeModuleName) {
dependencies.add(nodeModuleName);
}
// Add dependencies of this dependency (not top level node_modules)
if(nodeModuleName === false) {
if(!dependencies.has(relativeChildFilename) && // avoid infinite looping with circular deps
!avoidCircular[relativeChildFilename] ) {
for(let dependency of getDependenciesFor(relativeChildFilename, avoidCircular, options)) {
dependencies.add(dependency);
}
}
}
}
}
}
return dependencies;
}
function getCleanDependencyListFor(filename, options = {}) {
return Array.from( getDependenciesFor(filename, null, options) );
}
module.exports = getCleanDependencyListFor;
module.exports.getNodeModuleName = getNodeModuleName;

30
node_modules/@11ty/dependency-tree/package.json generated vendored Normal file
View File

@ -0,0 +1,30 @@
{
"name": "@11ty/dependency-tree",
"version": "2.0.1",
"description": "Finds all JavaScript require dependencies from a filename.",
"main": "main.js",
"scripts": {
"test": "npx ava"
},
"repository": {
"type": "git",
"url": "git+https://github.com/11ty/eleventy-dependency-tree.git"
},
"author": {
"name": "Zach Leatherman",
"email": "zach@zachleat.com",
"url": "https://zachleat.com/"
},
"license": "MIT",
"devDependencies": {
"ava": "^3.15.0"
},
"ava": {
"files": [
"./test/*.js"
],
"ignoredByWatcher": [
"./test/stubs/**"
]
}
}

92
node_modules/@11ty/dependency-tree/test/mainTest.js generated vendored Normal file
View File

@ -0,0 +1,92 @@
const test = require("ava");
const DependencyTree = require("../main.js");
test("Nonexistent", t => {
t.throws(() => {
DependencyTree("./test/stubs/thisdoesnotexist.js");
});
});
test("Allow not Found", t => {
DependencyTree("./test/stubs/thisdoesnotexist.js", { allowNotFound: true });
t.true(true);
});
test("Not require()d before calling", t => {
DependencyTree("./test/stubs/parent/parent.js");
t.true(true);
});
test("simple.js", t => {
t.deepEqual(DependencyTree("./test/stubs/simple.js"), ["./test/stubs/simple2.js"]);
});
test("parent.js", t => {
t.deepEqual(DependencyTree("./test/stubs/parent/parent.js").sort(), [
"./test/stubs/parent/child1.js",
"./test/stubs/parent/child2.js",
"./test/stubs/parent/grandchild.js",
"./test/stubs/parent/greatgrandchild.js"
]);
t.deepEqual(DependencyTree("./test/stubs/parent/child1.js").sort(), [
"./test/stubs/parent/grandchild.js",
"./test/stubs/parent/greatgrandchild.js"
]);
t.deepEqual(DependencyTree("./test/stubs/parent/child2.js").sort(), [
"./test/stubs/parent/grandchild.js",
"./test/stubs/parent/greatgrandchild.js"
]);
t.deepEqual(DependencyTree("./test/stubs/parent/grandchild.js"), [
"./test/stubs/parent/greatgrandchild.js"
]);
t.deepEqual(DependencyTree("./test/stubs/parent/greatgrandchild.js"), []);
});
test("circular", t => {
t.deepEqual(DependencyTree("./test/stubs/circular/circle-a.js").sort(), [
"./test/stubs/circular/circle-b.js",
"./test/stubs/circular/circle-c.js"]);
});
test("another circular", t => {
t.deepEqual(DependencyTree("./test/stubs/circular2/circle-a.js").sort(), [
"./test/stubs/circular2/circle-b.js",
"./test/stubs/circular2/circle-c.js"
]);
});
test("dot dot (dependency is up a directory)", t => {
t.deepEqual(DependencyTree("./test/stubs/dotdot/dotdot.js").sort(), [
"./test/stubs/simple2.js"
]);
});
test("only node_modules", t => {
t.deepEqual(DependencyTree("./test/stubs/uses_node_modules.js", {
nodeModuleNamesOnly: true
}).sort(), [
"@sindresorhus/is",
"lodash",
]);
});
test("getNodeModuleName", t => {
t.is(DependencyTree.getNodeModuleName("./eleventy-dependency-tree/node_modules/lodash/lodash.js"), "lodash");
t.is(DependencyTree.getNodeModuleName("./eleventy-dependency-tree/node_modules/@sindresorhus/is/dist/index.js"), "@sindresorhus/is");
});
test("both files and node_modules", t => {
t.deepEqual(DependencyTree("./test/stubs/uses_node_modules.js", {
nodeModuleNames: "include"
}).sort(), [
"./test/stubs/parent/child1.js",
"./test/stubs/parent/grandchild.js",
"./test/stubs/parent/greatgrandchild.js",
"@sindresorhus/is",
"lodash",
]);
});

View File

@ -0,0 +1 @@
const circleB = require("./circle-b");

View File

@ -0,0 +1 @@
const circleC = require("./circle-c");

View File

@ -0,0 +1 @@
const circleA = require("./circle-a");

View File

@ -0,0 +1 @@
const circleB = require("./circle-b");

View File

@ -0,0 +1 @@
const circleC = require("./circle-c");

View File

@ -0,0 +1 @@
const circleA = require("./circle-b");

View File

@ -0,0 +1 @@
const test = require("../simple2")

View File

@ -0,0 +1,4 @@
const test2 = require("./grandchild");
const lodash = require("lodash");
module.exports = {};

View File

@ -0,0 +1,3 @@
const test = require("./grandchild");
module.exports = {};

View File

@ -0,0 +1,2 @@
const test = require("./greatgrandchild.js");
module.exports = {};

View File

@ -0,0 +1,5 @@
const path = require("path");
const test = require("./child1");
const test2 = require("./child2");
module.exports = {};

View File

@ -0,0 +1 @@
const test = require("./simple2");

View File

View File

@ -0,0 +1,4 @@
const is = require("@sindresorhus/is");
const child1 = require("./parent/child1.js");
module.exports = {};

56
node_modules/@11ty/eleventy-dev-server/README.md generated vendored Normal file
View File

@ -0,0 +1,56 @@
<p align="center"><img src="https://www.11ty.dev/img/logo-github.svg" width="200" height="200" alt="11ty Logo"></p>
# eleventy-dev-server 🕚⚡️🎈🐀
A minimal, modern, generic, hot-reloading local web server to help web developers.
## ➡ [Documentation](https://www.11ty.dev/docs/watch-serve/#eleventy-dev-server)
- Please star [Eleventy on GitHub](https://github.com/11ty/eleventy/)!
- Follow us on Twitter [@eleven_ty](https://twitter.com/eleven_ty)
- Support [11ty on Open Collective](https://opencollective.com/11ty)
- [11ty on npm](https://www.npmjs.com/org/11ty)
- [11ty on GitHub](https://github.com/11ty)
[![npm Version](https://img.shields.io/npm/v/@11ty/eleventy-dev-server.svg?style=for-the-badge)](https://www.npmjs.com/package/@11ty/eleventy-dev-server)
## Installation
This is bundled with `@11ty/eleventy` (and you do not need to install it separately) in Eleventy v2.0.
## CLI
Eleventy Dev Server now also includes a CLI. The CLI is for **standalone** (non-Eleventy) use only: separate installation is unnecessary if youre using this server with `@11ty/eleventy`.
```sh
npm install -g @11ty/eleventy-dev-server
# Alternatively, install locally into your project
npm install @11ty/eleventy-dev-server
```
This package requires Node 14 or newer.
### CLI Usage
```sh
# Serve the current directory
npx @11ty/eleventy-dev-server
# Serve a different subdirectory (also aliased as --input)
npx @11ty/eleventy-dev-server --dir=_site
# Disable the `domdiff` feature
npx @11ty/eleventy-dev-server --domdiff=false
# Full command list in the Help
npx @11ty/eleventy-dev-server --help
```
## Tests
```
npm run test
```
- We use the [ava JavaScript test runner](https://github.com/avajs/ava) ([Assertions documentation](https://github.com/avajs/ava/blob/master/docs/03-assertions.md))

92
node_modules/@11ty/eleventy-dev-server/cli.js generated vendored Normal file
View File

@ -0,0 +1,92 @@
const chokidar = require("chokidar");
const fs = require("fs");
const pkg = require("./package.json");
const EleventyDevServer = require("./server.js");
const Logger = {
info: function(...args) {
console.log( "[11ty/eleventy-dev-server]", ...args );
},
error: function(...args) {
console.error( "[11ty/eleventy-dev-server]", ...args );
},
fatal: function(...args) {
Logger.error(...args);
process.exitCode = 1;
}
};
Logger.log = Logger.info;
class Cli {
static getVersion() {
return pkg.version;
}
static getHelp() {
return `Usage:
eleventy-dev-server
eleventy-dev-server --dir=_site
eleventy-dev-server --port=3000
Arguments:
--version
--dir=.
Directory to serve (default: \`.\`)
--input (alias for --dir)
--port=8080
Run the web server on this port (default: \`8080\`)
Will autoincrement if already in use.
--domdiff (enabled, default)
--domdiff=false (disabled)
Apply HTML changes without a full page reload.
--help`;
}
static getDefaultOptions() {
return {
port: "8080",
input: ".",
domDiff: true,
}
}
async serve(options = {}) {
this.options = Object.assign(Cli.getDefaultOptions(), options);
this.server = EleventyDevServer.getServer("eleventy-dev-server-cli", this.options.input, {
// TODO allow server configuration extensions
showVersion: true,
logger: Logger,
domDiff: this.options.domDiff,
// CLI watches all files in the folder by default
// this is different from Eleventy usage!
watch: [ this.options.input ],
});
this.server.serve(this.options.port);
// TODO? send any errors here to the server too
// with server.sendError({ error });
}
close() {
if(this.server) {
this.server.close();
}
}
}
module.exports = {
Logger,
Cli
}

View File

@ -0,0 +1,259 @@
class Util {
static pad(num, digits = 2) {
let zeroes = new Array(digits + 1).join(0);
return `${zeroes}${num}`.slice(-1 * digits);
}
static log(message) {
Util.output("log", message);
}
static error(message, error) {
Util.output("error", message, error);
}
static output(type, ...messages) {
let now = new Date();
let date = `${Util.pad(now.getUTCHours())}:${Util.pad(
now.getUTCMinutes()
)}:${Util.pad(now.getUTCSeconds())}.${Util.pad(
now.getUTCMilliseconds(),
3
)}`;
console[type](`[11ty][${date} UTC]`, ...messages);
}
static capitalize(word) {
return word.substr(0, 1).toUpperCase() + word.substr(1);
}
static matchRootAttributes(htmlContent) {
// Workaround for morphdom bug with attributes on <html> https://github.com/11ty/eleventy-dev-server/issues/6
// Note also `childrenOnly: true` above
const parser = new DOMParser();
let parsed = parser.parseFromString(htmlContent, "text/html");
let parsedDoc = parsed.documentElement;
let newAttrs = parsedDoc.getAttributeNames();
let docEl = document.documentElement;
// Remove old
let removedAttrs = docEl.getAttributeNames().filter(name => !newAttrs.includes(name));
for(let attr of removedAttrs) {
docEl.removeAttribute(attr);
}
// Add new
for(let attr of newAttrs) {
docEl.setAttribute(attr, parsedDoc.getAttribute(attr));
}
}
static isEleventyLinkNodeMatch(from, to) {
// Issue #18 https://github.com/11ty/eleventy-dev-server/issues/18
// Dont update a <link> if the _11ty searchParam is the only thing thats different
if(from.tagName !== "LINK" || to.tagName !== "LINK") {
return false;
}
let oldWithoutHref = from.cloneNode();
let newWithoutHref = to.cloneNode();
oldWithoutHref.removeAttribute("href");
newWithoutHref.removeAttribute("href");
// if all other attributes besides href match
if(!oldWithoutHref.isEqualNode(newWithoutHref)) {
return false;
}
let oldUrl = new URL(from.href);
let newUrl = new URL(to.href);
// morphdom wants to force href="style.css?_11ty" => href="style.css"
let isErasing = oldUrl.searchParams.has("_11ty") && !newUrl.searchParams.has("_11ty");
if(!isErasing) {
// not a match if _11ty has a new value (not being erased)
return false;
}
oldUrl.searchParams.set("_11ty", "");
newUrl.searchParams.set("_11ty", "");
// is a match if erasing and the rest of the href matches too
return oldUrl.toString() === newUrl.toString();
}
// https://github.com/patrick-steele-idem/morphdom/issues/178#issuecomment-652562769
static runScript(source, target) {
let script = document.createElement('script');
//copy over the attributes
for(let attr of [...source.attributes]) {
script.setAttribute(attr.nodeName ,attr.nodeValue);
}
script.innerHTML = source.innerHTML;
(target || source).replaceWith(script);
}
}
class EleventyReload {
constructor() {
this.connectionMessageShown = false;
this.reconnectEventCallback = this.reconnect.bind(this);
}
init(options = {}) {
if (!("WebSocket" in window)) {
return;
}
let { protocol, host } = new URL(document.location.href);
// works with http (ws) and https (wss)
let websocketProtocol = protocol.replace("http", "ws");
let socket = new WebSocket(`${websocketProtocol}//${host}`);
socket.addEventListener("message", async (event) => {
try {
let data = JSON.parse(event.data);
// Util.log( JSON.stringify(data, null, 2) );
let { type } = data;
if (type === "eleventy.reload") {
await this.onreload(data);
} else if (type === "eleventy.msg") {
Util.log(`${data.message}`);
} else if (type === "eleventy.error") {
// Log Eleventy build errors
// Extra parsing for Node Error objects
let e = JSON.parse(data.error);
Util.error(`Build error: ${e.message}`, e);
} else if (type === "eleventy.status") {
// Full page reload on initial reconnect
if (data.status === "connected" && options.mode === "reconnect") {
window.location.reload();
}
if(data.status === "connected") {
// With multiple windows, only show one connection message
if(!this.isConnected) {
Util.log(Util.capitalize(data.status));
}
this.connectionMessageShown = true;
} else {
if(data.status === "disconnected") {
this.addReconnectListeners();
}
Util.log(Util.capitalize(data.status));
}
} else {
Util.log("Unknown event type", data);
}
} catch (e) {
Util.error(`Error parsing ${event.data}: ${e.message}`, e);
}
});
socket.addEventListener("open", () => {
// no reconnection when the connect is already open
this.removeReconnectListeners();
});
socket.addEventListener("close", () => {
this.connectionMessageShown = false;
this.addReconnectListeners();
});
}
reconnect() {
Util.log( "Reconnecting…" );
this.init({ mode: "reconnect" });
}
async onreload({ subtype, files, build }) {
if (subtype === "css") {
for (let link of document.querySelectorAll(`link[rel="stylesheet"]`)) {
let url = new URL(link.href);
url.searchParams.set("_11ty", Date.now());
link.href = url.toString();
}
Util.log(`CSS updated without page reload.`);
} else {
let morphed = false;
try {
if((build.templates || []).length > 0) {
// Important: using `./` in `./morphdom.js` allows the special `.11ty` folder to be changed upstream
const { default: morphdom } = await import(`./morphdom.js`);
// { url, inputPath, content }
for (let template of build.templates || []) {
if (template.url === document.location.pathname) {
// Importantly, if this does not match but is still relevant (layout/include/etc), a full reload happens below. This could be improved.
if ((files || []).includes(template.inputPath)) {
// Notable limitation: this wont re-run script elements or JavaScript page lifecycle events (load/DOMContentLoaded)
morphed = true;
morphdom(document.documentElement, template.content, {
childrenOnly: true,
onBeforeElUpdated: function (fromEl, toEl) {
if (fromEl.nodeName === "SCRIPT" && toEl.nodeName === "SCRIPT") {
Util.runScript(toEl, fromEl);
return false;
}
// Speed-up trick from morphdom docs
// https://dom.spec.whatwg.org/#concept-node-equals
if (fromEl.isEqualNode(toEl)) {
return false;
}
if(Util.isEleventyLinkNodeMatch(fromEl, toEl)) {
return false;
}
return true;
},
onNodeAdded: function (node) {
if (node.nodeName === 'SCRIPT') {
Util.runScript(node);
}
},
});
Util.matchRootAttributes(template.content);
Util.log(`HTML delta applied without page reload.`);
}
break;
}
}
}
} catch(e) {
Util.error( "Morphdom error", e );
}
if (!morphed) {
Util.log(`Page reload initiated.`);
window.location.reload();
}
}
}
addReconnectListeners() {
this.removeReconnectListeners();
window.addEventListener("focus", this.reconnectEventCallback);
window.addEventListener("visibilitychange", this.reconnectEventCallback);
}
removeReconnectListeners() {
window.removeEventListener("focus", this.reconnectEventCallback);
window.removeEventListener("visibilitychange", this.reconnectEventCallback);
}
}
let reloader = new EleventyReload();
reloader.init();

69
node_modules/@11ty/eleventy-dev-server/cmd.js generated vendored Executable file
View File

@ -0,0 +1,69 @@
#!/usr/bin/env node
const pkg = require("./package.json");
// Node check
require("please-upgrade-node")(pkg, {
message: function (requiredVersion) {
return (
"eleventy-dev-server requires Node " +
requiredVersion +
". You will need to upgrade Node!"
);
},
});
const { Logger, Cli } = require("./cli.js");
const debug = require("debug")("EleventyDevServer:cmd");
try {
const argv = require("minimist")(process.argv.slice(2), {
string: [
"dir",
"input", // alias for dir
"port",
],
boolean: [
"version",
"help",
"domdiff",
],
default: Cli.getDefaultOptions(),
unknown: function (unknownArgument) {
throw new Error(
`We dont know what '${unknownArgument}' is. Use --help to see the list of supported commands.`
);
},
});
debug("command: eleventy-dev-server %o", argv);
process.on("unhandledRejection", (error, promise) => {
Logger.fatal("Unhandled rejection in promise:", promise, error);
});
process.on("uncaughtException", (error) => {
Logger.fatal("Uncaught exception:", error);
});
if (argv.version) {
console.log(Cli.getVersion());
} else if (argv.help) {
console.log(Cli.getHelp());
} else {
let cli = new Cli();
cli.serve({
input: argv.dir || argv.input,
port: argv.port,
domDiff: argv.domdiff,
});
process.on("SIGINT", () => {
cli.close();
process.exit();
});
}
} catch (e) {
Logger.fatal("Fatal Error:", e)
}

56
node_modules/@11ty/eleventy-dev-server/package.json generated vendored Normal file
View File

@ -0,0 +1,56 @@
{
"name": "@11ty/eleventy-dev-server",
"version": "1.0.4",
"description": "A minimal, modern, generic, hot-reloading local web server to help web developers.",
"main": "server.js",
"scripts": {
"test": "npx ava --verbose",
"sample": "node cmd.js --input=test/stubs"
},
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/11ty"
},
"bin": {
"eleventy-dev-server": "./cmd.js"
},
"keywords": [
"eleventy",
"server",
"cli"
],
"publishConfig": {
"access": "public"
},
"author": {
"name": "Zach Leatherman",
"email": "zachleatherman@gmail.com",
"url": "https://zachleat.com/"
},
"repository": {
"type": "git",
"url": "git://github.com/11ty/eleventy-dev-server.git"
},
"bugs": "https://github.com/11ty/eleventy-dev-server/issues",
"homepage": "https://github.com/11ty/eleventy-dev-server/",
"dependencies": {
"@11ty/eleventy-utils": "^1.0.1",
"chokidar": "^3.5.3",
"debug": "^4.3.4",
"dev-ip": "^1.0.1",
"finalhandler": "^1.2.0",
"mime": "^3.0.0",
"minimist": "^1.2.8",
"morphdom": "^2.7.0",
"please-upgrade-node": "^3.2.0",
"ssri": "^8.0.1",
"ws": "^8.13.0"
},
"devDependencies": {
"ava": "^5.2.0"
}
}

807
node_modules/@11ty/eleventy-dev-server/server.js generated vendored Normal file
View File

@ -0,0 +1,807 @@
const pkg = require("./package.json");
const path = require("path");
const fs = require("fs");
const finalhandler = require("finalhandler");
const WebSocket = require("ws");
const { WebSocketServer } = WebSocket;
const mime = require("mime");
const ssri = require("ssri");
const devip = require("dev-ip");
const chokidar = require("chokidar");
const { TemplatePath } = require("@11ty/eleventy-utils");
const debug = require("debug")("EleventyDevServer");
const wrapResponse = require("./server/wrapResponse.js");
const DEFAULT_OPTIONS = {
port: 8080,
liveReload: true, // Enable live reload at all
showAllHosts: false, // IP address based hosts (other than localhost)
injectedScriptsFolder: ".11ty", // Change the name of the special folder used for injected scripts
portReassignmentRetryCount: 10, // number of times to increment the port if in use
https: {}, // `key` and `cert`, required for http/2 and https
domDiff: true, // Use morphdom to apply DOM diffing delta updates to HTML
showVersion: false, // Whether or not to show the server version on the command line.
encoding: "utf-8", // Default file encoding
pathPrefix: "/", // May be overridden by Eleventy, adds a virtual base directory to your project
watch: [], // Globs to pass to separate dev server chokidar for watching
aliases: {}, // Aliasing feature
// Logger (fancier one is injected by Eleventy)
logger: {
info: console.log,
log: console.log,
error: console.error,
}
}
class EleventyDevServer {
static getServer(...args) {
return new EleventyDevServer(...args);
}
constructor(name, dir, options = {}) {
debug("Creating new Dev Server instance.")
this.name = name;
this.normalizeOptions(options);
this.fileCache = {};
// Directory to serve
if(!dir) {
throw new Error("Missing `dir` to serve.");
}
this.dir = dir;
this.logger = this.options.logger;
if(this.options.watch.length > 0) {
this.getWatcher();
}
}
normalizeOptions(options = {}) {
this.options = Object.assign({}, DEFAULT_OPTIONS, options);
// better names for options https://github.com/11ty/eleventy-dev-server/issues/41
if(options.folder !== undefined) {
this.options.injectedScriptsFolder = options.folder;
delete this.options.folder;
}
if(options.domdiff !== undefined) {
this.options.domDiff = options.domdiff;
delete this.options.domdiff;
}
if(options.enabled !== undefined) {
this.options.liveReload = options.enabled;
delete this.options.enabled;
}
this.options.pathPrefix = this.cleanupPathPrefix(this.options.pathPrefix);
}
get watcher() {
if(!this._watcher) {
debug("Watching %O", this.options.watch);
// TODO if using Eleventy and `watch` option includes output folder (_site) this will trigger two update events!
this._watcher = chokidar.watch(this.options.watch, {
// TODO allow chokidar configuration extensions (or re-use the ones in Eleventy)
ignored: ["**/node_modules/**", ".git"],
ignoreInitial: true,
// same values as Eleventy
awaitWriteFinish: {
stabilityThreshold: 150,
pollInterval: 25,
},
});
this._watcher.on("change", (path) => {
this.logger.log( `File changed: ${path} (skips build)` );
this.reloadFiles([path]);
});
this._watcher.on("add", (path) => {
this.logger.log( `File added: ${path} (skips build)` );
this.reloadFiles([path]);
});
}
return this._watcher;
}
getWatcher() {
return this.watcher;
}
watchFiles(files) {
if(Array.isArray(files)) {
files = files.map(entry => TemplatePath.stripLeadingDotSlash(entry));
debug("Also watching %O", files);
this.watcher.add(files);
}
}
cleanupPathPrefix(pathPrefix) {
if(!pathPrefix || pathPrefix === "/") {
return "/";
}
if(!pathPrefix.startsWith("/")) {
pathPrefix = `/${pathPrefix}`
}
if(!pathPrefix.endsWith("/")) {
pathPrefix = `${pathPrefix}/`;
}
return pathPrefix;
}
// Allowed list of files that can be served from outside `dir`
setAliases(aliases) {
if(aliases) {
this.passthroughAliases = aliases;
debug( "Setting aliases (emulated passthrough copy) %O", aliases );
}
}
matchPassthroughAlias(url) {
let aliases = Object.assign({}, this.options.aliases, this.passthroughAliases);
for(let targetUrl in aliases) {
if(!targetUrl) {
continue;
}
let file = aliases[targetUrl];
if(url.startsWith(targetUrl)) {
let inputDirectoryPath = file + url.slice(targetUrl.length);
// e.g. addPassthroughCopy("img/") but <img src="/img/built/IdthKOzqFA-350.png">
// generated by the image plugin (written to the output folder)
// If they do not exist in the input directory, this will fallback to the output directory.
if(fs.existsSync(inputDirectoryPath)) {
return inputDirectoryPath;
}
}
}
return false;
}
isFileInDirectory(dir, file) {
let absoluteDir = TemplatePath.absolutePath(dir);
let absoluteFile = TemplatePath.absolutePath(file);
return absoluteFile.startsWith(absoluteDir);
}
getOutputDirFilePath(filepath, filename = "") {
let computedPath;
if(filename === ".html") {
// avoid trailing slash for filepath/.html requests
let prefix = path.join(this.dir, filepath);
if(prefix.endsWith(path.sep)) {
prefix = prefix.substring(0, prefix.length - path.sep.length);
}
computedPath = prefix + filename;
} else {
computedPath = path.join(this.dir, filepath, filename);
}
computedPath = decodeURIComponent(computedPath);
if(!filename) { // is a direct URL request (not an implicit .html or index.html add)
let alias = this.matchPassthroughAlias(filepath);
if(alias) {
if(!this.isFileInDirectory(path.resolve("."), alias)) {
throw new Error("Invalid path");
}
return alias;
}
}
// Check that the file is in the output path (error if folks try use `..` in the filepath)
if(!this.isFileInDirectory(this.dir, computedPath)) {
throw new Error("Invalid path");
}
return computedPath;
}
isOutputFilePathExists(rawPath) {
return fs.existsSync(rawPath) && !TemplatePath.isDirectorySync(rawPath);
}
/* Use conventions documented here https://www.zachleat.com/web/trailing-slash/
* resource.html exists:
* /resource matches
* /resource/ redirects to /resource
* resource/index.html exists:
* /resource redirects to /resource/
* /resource/ matches
* both resource.html and resource/index.html exists:
* /resource matches /resource.html
* /resource/ matches /resource/index.html
*/
mapUrlToFilePath(url) {
// Note: `localhost` is not important here, any host would work
let u = new URL(url, "http://localhost/");
url = u.pathname;
// Remove PathPrefix from start of URL
if (this.options.pathPrefix !== "/") {
// Requests to root should redirect to new pathPrefix
if(url === "/") {
return {
statusCode: 302,
url: this.options.pathPrefix,
}
}
// Requests to anything outside of root should fail with 404
if (!url.startsWith(this.options.pathPrefix)) {
return {
statusCode: 404,
};
}
url = url.slice(this.options.pathPrefix.length - 1);
}
let rawPath = this.getOutputDirFilePath(url);
if (this.isOutputFilePathExists(rawPath)) {
return {
statusCode: 200,
filepath: rawPath,
};
}
let indexHtmlPath = this.getOutputDirFilePath(url, "index.html");
let indexHtmlExists = fs.existsSync(indexHtmlPath);
let htmlPath = this.getOutputDirFilePath(url, ".html");
let htmlExists = fs.existsSync(htmlPath);
// /resource/ => /resource/index.html
if (indexHtmlExists && url.endsWith("/")) {
return {
statusCode: 200,
filepath: indexHtmlPath,
};
}
// /resource => resource.html
if (htmlExists && !url.endsWith("/")) {
return {
statusCode: 200,
filepath: htmlPath,
};
}
// /resource => redirect to /resource/
if (indexHtmlExists && !url.endsWith("/")) {
return {
statusCode: 301,
url: url + "/",
};
}
// /resource/ => redirect to /resource
if (htmlExists && url.endsWith("/")) {
return {
statusCode: 301,
url: url.substring(0, url.length - 1),
};
}
return {
statusCode: 404,
};
}
_getFileContents(localpath, rootDir, useCache = true) {
if(this.fileCache[localpath]) {
return this.fileCache[localpath];
}
let filepath;
let searchLocations = [];
if(rootDir) {
searchLocations.push(TemplatePath.absolutePath(rootDir, localpath));
}
// fallbacks for file:../ installations
searchLocations.push(TemplatePath.absolutePath(__dirname, localpath));
searchLocations.push(TemplatePath.absolutePath(__dirname, "../../../", localpath));
for(let loc of searchLocations) {
if(fs.existsSync(loc)) {
filepath = loc;
break;
}
}
let contents = fs.readFileSync(filepath, {
encoding: this.options.encoding,
});
if(useCache) {
this.fileCache[localpath] = contents;
}
return contents;
}
augmentContentWithNotifier(content, inlineContents = false, options = {}) {
let { integrityHash, scriptContents } = options;
if(!scriptContents) {
scriptContents = this._getFileContents("./client/reload-client.js");
}
if(!integrityHash) {
integrityHash = ssri.fromData(scriptContents);
}
// This isnt super necessary because its a local file, but its included anyway
let script = `<script type="module" integrity="${integrityHash}"${inlineContents ? `>${scriptContents}` : ` src="/${this.options.injectedScriptsFolder}/reload-client.js">`}</script>`;
if (content.includes("</head>")) {
return content.replace("</head>", `${script}</head>`);
}
// If the HTML document contains an importmap, insert the module script after the importmap element
let importMapRegEx = /<script type=\\?importmap\\?[^>]*>(\n|.)*?<\/script>/gmi;
let importMapMatch = content.match(importMapRegEx)?.[0];
if (importMapMatch) {
return content.replace(importMapMatch, `${importMapMatch}${script}`);
}
// <title> is the only *required* element in an HTML document
if (content.includes("</title>")) {
return content.replace("</title>", `</title>${script}`);
}
// If youve reached this section, your HTML is invalid!
// We want to be super forgiving here, because folks might be in-progress editing the document!
if (content.includes("</body>")) {
return content.replace("</body>", `${script}</body>`);
}
if (content.includes("</html>")) {
return content.replace("</html>", `${script}</html>`);
}
if (content.includes("<!doctype html>")) {
return content.replace("<!doctype html>", `<!doctype html>${script}`);
}
// Notably, works without content at all!!
return (content || "") + script;
}
getFileContentType(filepath, res) {
let contentType = res.getHeader("Content-Type");
// Content-Type might be already set via middleware
if (contentType) {
return contentType;
}
let mimeType = mime.getType(filepath);
if (!mimeType) {
return;
}
contentType = mimeType;
// We only want to append charset if the header is not already set
if (contentType === "text/html") {
contentType = `text/html; charset=${this.options.encoding}`;
}
return contentType;
}
renderFile(filepath, res) {
let contents = fs.readFileSync(filepath);
let contentType = this.getFileContentType(filepath, res);
if (!contentType) {
return res.end(contents);
}
res.setHeader("Content-Type", contentType);
if (contentType.startsWith("text/html")) {
// the string is important here, wrapResponse expects strings internally for HTML content (for now)
return res.end(contents.toString());
}
return res.end(contents);
}
eleventyDevServerMiddleware(req, res, next) {
if(req.url === `/${this.options.injectedScriptsFolder}/reload-client.js`) {
if(this.options.liveReload) {
res.setHeader("Content-Type", mime.getType("js"));
return res.end(this._getFileContents("./client/reload-client.js"));
}
} else if(req.url === `/${this.options.injectedScriptsFolder}/morphdom.js`) {
if(this.options.domDiff) {
res.setHeader("Content-Type", mime.getType("js"));
return res.end(this._getFileContents("./node_modules/morphdom/dist/morphdom-esm.js", path.resolve(".")));
}
}
next();
}
// This runs at the end of the middleware chain
eleventyProjectMiddleware(req, res) {
// Known issue with `finalhandler` and HTTP/2:
// UnsupportedWarning: Status message is not supported by HTTP/2 (RFC7540 8.1.2.4)
// https://github.com/pillarjs/finalhandler/pull/34
let lastNext = finalhandler(req, res, {
onerror: (e) => {
if (e.statusCode === 404) {
let localPath = TemplatePath.stripLeadingSubPath(
e.path,
TemplatePath.absolutePath(this.dir)
);
this.logger.error(
`HTTP ${e.statusCode}: Template not found in output directory (${this.dir}): ${localPath}`
);
} else {
this.logger.error(`HTTP ${e.statusCode}: ${e.message}`);
}
},
});
// middleware (maybe a serverless request) already set a body upstream, skip this part
if(!res._shouldForceEnd) {
let match = this.mapUrlToFilePath(req.url);
debug( req.url, match );
if (match) {
if (match.statusCode === 200 && match.filepath) {
return this.renderFile(match.filepath, res);
}
// Redirects, usually for trailing slash to .html stuff
if (match.url) {
res.statusCode = match.statusCode;
res.setHeader("Location", match.url);
return res.end();
}
let raw404Path = this.getOutputDirFilePath("404.html");
if(match.statusCode === 404 && this.isOutputFilePathExists(raw404Path)) {
res.statusCode = match.statusCode;
res.isCustomErrorPage = true;
return this.renderFile(raw404Path, res);
}
}
}
if(res.body && !res.bodyUsed) {
if(res._shouldForceEnd) {
res.end();
} else {
let err = new Error("A response was never written to the stream. Are you missing a server middleware with `res.end()`?");
err.statusCode = 500;
lastNext(err);
return;
}
}
lastNext();
}
async onRequestHandler (req, res) {
res = wrapResponse(res, content => {
// check to see if this is a client fetch and not a navigation
let isXHR = req.headers["sec-fetch-mode"] && req.headers["sec-fetch-mode"] != "navigate";
if(this.options.liveReload !== false && !isXHR) {
let scriptContents = this._getFileContents("./client/reload-client.js");
let integrityHash = ssri.fromData(scriptContents);
// Bare (not-custom) finalhandler error pages have a Content-Security-Policy `default-src 'none'` that
// prevents the client script from executing, so we override it
if(res.statusCode !== 200 && !res.isCustomErrorPage) {
res.setHeader("Content-Security-Policy", `script-src '${integrityHash}'`);
}
return this.augmentContentWithNotifier(content, res.statusCode !== 200, {
scriptContents,
integrityHash
});
}
return content;
});
let middlewares = this.options.middleware || [];
middlewares = middlewares.slice();
// TODO because this runs at the very end of the middleware chain,
// if we move the static stuff up in the order we could use middleware to modify
// the static content in middleware!
middlewares.push(this.eleventyProjectMiddleware);
middlewares.reverse();
// Runs very first in the middleware chain
middlewares.push(this.eleventyDevServerMiddleware);
let bound = [];
let next;
for(let ware of middlewares) {
let fn;
if(next) {
fn = ware.bind(this, req, res, next);
} else {
fn = ware.bind(this, req, res);
}
bound.push(fn);
next = fn;
}
bound.reverse();
let [first] = bound;
await first();
}
get server() {
if (this._server) {
return this._server;
}
this.start = Date.now();
// Check for secure server requirements, otherwise use HTTP
let { key, cert } = this.options.https;
if(key && cert) {
const { createSecureServer } = require("http2");
let options = {
allowHTTP1: true,
// Credentials
key: fs.readFileSync(key),
cert: fs.readFileSync(cert),
};
this._server = createSecureServer(options, this.onRequestHandler.bind(this));
this._serverProtocol = "https:";
} else {
const { createServer } = require("http");
this._server = createServer(this.onRequestHandler.bind(this));
this._serverProtocol = "http:";
}
this.portRetryCount = 0;
this._server.on("error", (err) => {
if (err.code == "EADDRINUSE") {
if (this.portRetryCount < this.options.portReassignmentRetryCount) {
this.portRetryCount++;
debug(
"Server already using port %o, trying the next port %o. Retry number %o of %o",
err.port,
err.port + 1,
this.portRetryCount,
this.options.portReassignmentRetryCount
);
this._serverListen(err.port + 1);
} else {
throw new Error(
`Tried ${this.options.portReassignmentRetryCount} different ports but they were all in use. You can a different starter port using --port on the command line.`
);
}
} else {
this._serverErrorHandler(err);
}
});
this._server.on("listening", (e) => {
this.setupReloadNotifier();
let { port } = this._server.address();
let hostsStr = "";
if(this.options.showAllHosts) {
// TODO what happens when the cert doesnt cover non-localhost hosts?
let hosts = devip().map(host => `${this._serverProtocol}//${host}:${port}${this.options.pathPrefix} or`);
hostsStr = hosts.join(" ") + " ";
}
let startBenchmark = ""; // this.start ? ` ready in ${Date.now() - this.start}ms` : "";
this.logger.info(`Server at ${hostsStr}${this._serverProtocol}//localhost:${port}${this.options.pathPrefix}${this.options.showVersion ? ` (v${pkg.version})` : ""}${startBenchmark}`);
});
return this._server;
}
_serverListen(port) {
this.server.listen({
port,
});
}
async getPort() {
return new Promise(resolve => {
this.server.on("listening", (e) => {
let { port } = this._server.address();
resolve(port);
});
})
}
serve(port) {
this.getWatcher();
this._serverListen(port);
}
_serverErrorHandler(err) {
if (err.code == "EADDRINUSE") {
this.logger.error(`Server error: Port in use ${err.port}`);
} else {
this.logger.error(`Server error: ${err.message}`);
}
}
// Websocket Notifications
setupReloadNotifier() {
let updateServer = new WebSocketServer({
// includes the port
server: this.server,
});
updateServer.on("connection", (ws) => {
this.sendUpdateNotification({
type: "eleventy.status",
status: "connected",
});
});
updateServer.on("error", (err) => {
this._serverErrorHandler(err);
});
this.updateServer = updateServer;
}
// Broadcasts to all open browser windows
sendUpdateNotification(obj) {
if(!this.updateServer?.clients) {
return;
}
for(let client of this.updateServer.clients) {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(obj));
}
}
}
close() {
// TODO would be awesome to set a delayed redirect when port changed to redirect to new _server_
this.sendUpdateNotification({
type: "eleventy.status",
status: "disconnected",
});
if(this.server) {
this.server.close();
}
if(this.updateServer) {
this.updateServer.close();
}
if(this._watcher) {
this._watcher.close();
delete this._watcher;
}
}
sendError({ error }) {
this.sendUpdateNotification({
type: "eleventy.error",
// Thanks https://stackoverflow.com/questions/18391212/is-it-not-possible-to-stringify-an-error-using-json-stringify
error: JSON.stringify(error, Object.getOwnPropertyNames(error)),
});
}
// reverse of mapUrlToFilePath
// /resource/ <= /resource/index.html
// /resource <= resource.html
getUrlsFromFilePath(path) {
if(this.dir === ".") {
path = `/${path}`
} else {
path = path.slice(this.dir.length);
}
let urls = [];
urls.push(path);
if(path.endsWith("/index.html")) {
urls.push(path.slice(0, -1 * "index.html".length));
} else if(path.endsWith(".html")) {
urls.push(path.slice(0, -1 * ".html".length));
}
return urls;
}
// [{ url, inputPath, content }]
getBuildTemplatesFromFilePath(path) {
// We can skip this for non-html files, dom-diffing will not apply
if(!path.endsWith(".html")) {
return [];
}
let urls = this.getUrlsFromFilePath(path);
let obj = {
inputPath: path,
content: fs.readFileSync(path, "utf8"),
}
return urls.map(url => {
return Object.assign({ url }, obj);
});
}
reloadFiles(files, useDomDiffingForHtml = true) {
if(!Array.isArray(files)) {
throw new Error("reloadFiles method requires an array of file paths.");
}
let subtype;
if(!files.some((entry) => !entry.endsWith(".css"))) {
// all css changes
subtype = "css";
}
let templates = [];
if(useDomDiffingForHtml && this.options.domDiff) {
for(let filePath of files) {
if(!filePath.endsWith(".html")) {
continue;
}
for(let templateEntry of this.getBuildTemplatesFromFilePath(filePath)) {
templates.push(templateEntry);
}
}
}
this.reload({
files,
subtype,
build: {
templates
}
});
}
reload(event) {
let { subtype, files, build } = event;
if (build?.templates) {
build.templates = build.templates
.filter(entry => {
if(!this.options.domDiff) {
// Dont include any files if the dom diffing option is disabled
return false;
}
// Filter to only include watched templates that were updated
return (files || []).includes(entry.inputPath);
});
}
this.sendUpdateNotification({
type: "eleventy.reload",
subtype,
files,
build,
});
}
}
module.exports = EleventyDevServer;

View File

@ -0,0 +1,129 @@
function getContentType(headers) {
if(!headers) {
return;
}
for(let key in headers) {
if(key.toLowerCase() === "content-type") {
return headers[key];
}
}
}
// Inspired by `resp-modifier` https://github.com/shakyShane/resp-modifier/blob/4a000203c9db630bcfc3b6bb8ea2abc090ae0139/index.js
function wrapResponse(resp, transformHtml) {
resp._wrappedOriginalWrite = resp.write;
resp._wrappedOriginalWriteHead = resp.writeHead;
resp._wrappedOriginalEnd = resp.end;
resp._wrappedHeaders = [];
resp._wrappedTransformHtml = transformHtml;
resp._hasEnded = false;
resp._shouldForceEnd = false;
// Compatibility with web standards Response()
Object.defineProperty(resp, "body", {
// Returns write cache
get: function() {
if(typeof this._writeCache === "string") {
return this._writeCache;
}
},
// Usage:
// res.body = ""; // overwrite existing content
// res.body += ""; // append to existing content, can also res.write("") to append
set: function(data) {
if(typeof data === "string") {
this._writeCache = data;
}
}
});
// Compatibility with web standards Response()
Object.defineProperty(resp, "bodyUsed", {
get: function() {
return this._hasEnded;
}
})
// Original signature writeHead(statusCode[, statusMessage][, headers])
resp.writeHead = function(statusCode, ...args) {
let headers = args[args.length - 1];
// statusMessage is a string
if(typeof headers !== "string") {
this._contentType = getContentType(headers);
}
if((this._contentType || "").startsWith("text/html")) {
this._wrappedHeaders.push([statusCode, ...args]);
} else {
return this._wrappedOriginalWriteHead(statusCode, ...args);
}
return this;
}
// data can be a String or Buffer
resp.write = function(data, ...args) {
if(typeof data === "string") {
if(!this._writeCache) {
this._writeCache = "";
}
// TODO encoding and callback args
this._writeCache += data;
} else {
// Buffers
return this._wrappedOriginalWrite(data, ...args);
}
return this;
}
// data can be a String or Buffer
resp.end = function(data, encoding, callback) {
resp._hasEnded = true;
if(typeof this._writeCache === "string" || typeof data === "string") {
// Strings
if(!this._writeCache) {
this._writeCache = "";
}
if(typeof data === "string") {
this._writeCache += data;
}
let result = this._writeCache;
// Only transform HTML
// Note the “setHeader versus writeHead” note on https://nodejs.org/api/http.html#responsewriteheadstatuscode-statusmessage-headers
let contentType = this._contentType || getContentType(this.getHeaders());
if(contentType && contentType.startsWith("text/html")) {
if(this._wrappedTransformHtml && typeof this._wrappedTransformHtml === "function") {
result = this._wrappedTransformHtml(result);
this.setHeader("Content-Length", Buffer.byteLength(result));
}
}
for(let headers of this._wrappedHeaders) {
this._wrappedOriginalWriteHead(...headers);
}
this._writeCache = [];
this._wrappedOriginalWrite(result, encoding)
return this._wrappedOriginalEnd(callback);
} else {
// Buffers
for(let headers of this._wrappedHeaders) {
this._wrappedOriginalWriteHead(...headers);
}
if(data) {
this._wrappedOriginalWrite(data, encoding);
}
return this._wrappedOriginalEnd(callback);
}
}
return resp;
}
module.exports = wrapResponse;

21
node_modules/@11ty/eleventy-utils/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Zach Leatherman @zachleat
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

29
node_modules/@11ty/eleventy-utils/README.md generated vendored Normal file
View File

@ -0,0 +1,29 @@
<p align="center"><img src="https://www.11ty.dev/img/logo-github.png" alt="eleventy Logo"></p>
# eleventy-utils 🕚⚡️🎈🐀
Low level internal utilities to be shared amongst Eleventy projects.
## ➡ [Documentation](https://www.11ty.dev/docs/)
- Please star [Eleventy on GitHub](https://github.com/11ty/eleventy/)!
- Follow us on Twitter [@eleven_ty](https://twitter.com/eleven_ty)
- Support [11ty on Open Collective](https://opencollective.com/11ty)
- [11ty on npm](https://www.npmjs.com/org/11ty)
- [11ty on GitHub](https://github.com/11ty)
[![npm Version](https://img.shields.io/npm/v/@11ty/eleventy-utils.svg?style=for-the-badge)](https://www.npmjs.com/package/@11ty/eleventy-utils)
## Installation
```
npm install @11ty/eleventy-utils
```
## Tests
```
npm run test
```
- We use the [ava JavaScript test runner](https://github.com/avajs/ava) ([Assertions documentation](https://github.com/avajs/ava/blob/master/docs/03-assertions.md))

11
node_modules/@11ty/eleventy-utils/index.js generated vendored Normal file
View File

@ -0,0 +1,11 @@
const TemplatePath = require("./src/TemplatePath.js");
const isPlainObject = require("./src/IsPlainObject.js");
const Merge = require("./src/Merge.js");
const { DeepCopy } = Merge;
module.exports = {
TemplatePath,
isPlainObject,
Merge,
DeepCopy,
};

47
node_modules/@11ty/eleventy-utils/package.json generated vendored Normal file
View File

@ -0,0 +1,47 @@
{
"name": "@11ty/eleventy-utils",
"version": "1.0.3",
"description": "Low level internal utilities to be shared amongst Eleventy projects",
"main": "index.js",
"files": [
"src",
"src/**",
"index.js",
"!test",
"!test/**"
],
"scripts": {
"test": "npx ava --verbose"
},
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/11ty"
},
"keywords": [
"eleventy"
],
"publishConfig": {
"access": "public"
},
"author": {
"name": "Zach Leatherman",
"email": "zachleatherman@gmail.com",
"url": "https://zachleat.com/"
},
"repository": {
"type": "git",
"url": "git://github.com/11ty/eleventy-utils.git"
},
"bugs": "https://github.com/11ty/eleventy-utils/issues",
"homepage": "https://github.com/11ty/eleventy-utils/",
"dependencies": {
"normalize-path": "^3.0.0"
},
"devDependencies": {
"ava": "^6.1.3"
}
}

24
node_modules/@11ty/eleventy-utils/src/IsPlainObject.js generated vendored Normal file
View File

@ -0,0 +1,24 @@
/* Prior art: this utility was created for https://github.com/11ty/eleventy/issues/2214
* Inspired by implementations from `is-what`, `typechecker`, `jQuery`, and `lodash`
* `is-what`
* More reading at https://www.npmjs.com/package/is-what#user-content-isplainobject-vs-isanyobject
* if (Object.prototype.toString.call(value).slice(8, -1) !== 'Object') return false;
* return value.constructor === Object && Object.getPrototypeOf(value) === Object.prototype;
* `typechecker`
* return value !== null && typeof value === 'object' && value.__proto__ === Object.prototype;
* Notably jQuery and lodash have very similar implementations.
* For later, remember the `value === Object(value)` trick
*/
module.exports = function (value) {
if (value === null || typeof value !== "object") {
return false;
}
let proto = Object.getPrototypeOf(value);
return !proto || proto === Object.prototype;
};

84
node_modules/@11ty/eleventy-utils/src/Merge.js generated vendored Normal file
View File

@ -0,0 +1,84 @@
"use strict";
// above is required for Object.freeze to fail correctly.
const isPlainObject = require("./IsPlainObject.js");
const OVERRIDE_PREFIX = "override:";
function cleanKey(key, prefix) {
if (prefix && key.startsWith(prefix)) {
return key.slice(prefix.length);
}
return key;
}
function getMergedItem(target, source, prefixes = {}) {
let { override } = prefixes;
// Shortcut for frozen source (if target does not exist)
if (!target && isPlainObject(source) && Object.isFrozen(source)) {
return source;
}
let sourcePlainObjectShortcut;
if (!target && isPlainObject(source)) {
// deep copy objects to avoid sharing and to effect key renaming
target = {};
sourcePlainObjectShortcut = true;
}
if (Array.isArray(target) && Array.isArray(source)) {
return target.concat(source);
} else if (isPlainObject(target)) {
if (sourcePlainObjectShortcut || isPlainObject(source)) {
for (let key in source) {
let overrideKey = cleanKey(key, override);
// An error happens here if the target is frozen
target[overrideKey] = getMergedItem(target[key], source[key], prefixes);
}
}
return target;
}
// number, string, class instance, etc
return source;
}
// The same as Merge but without override prefixes
function DeepCopy(targetObject, ...sources) {
for (let source of sources) {
if (!source) {
continue;
}
targetObject = getMergedItem(targetObject, source);
}
return targetObject;
}
function Merge(target, ...sources) {
// Remove override prefixes from root target.
if (isPlainObject(target)) {
for (let key in target) {
if (key.indexOf(OVERRIDE_PREFIX) === 0) {
target[key.slice(OVERRIDE_PREFIX.length)] = target[key];
delete target[key];
}
}
}
for (let source of sources) {
if (!source) {
continue;
}
target = getMergedItem(target, source, {
override: OVERRIDE_PREFIX,
});
}
return target;
}
module.exports = Merge;
module.exports.DeepCopy = DeepCopy;

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

@ -0,0 +1,368 @@
const path = require("path");
const normalize = require("normalize-path");
const fs = require("fs");
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 [`path.parse`][1] works.
*
* [1]: https://nodejs.org/api/path.html#path_path_parse_path
*
* @param {String} path A path
* @returns {String} the directory portion of a path.
*/
TemplatePath.getDirFromFilePath = function (filePath) {
return path.parse(filePath).dir || ".";
};
/**
* Returns the last path segment in a path (no leading/trailing slashes).
*
* Assumes [`path.parse`][1] was called on `path` before.
*
* [1]: https://nodejs.org/api/path.html#path_path_parse_path
*
* @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 a single trailing slash if the last URL path argument
* had at least 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) {
let i = 0;
// check all the paths before we short circuit from the first index
for (let p of paths) {
if (path.isAbsolute(p) && i > 0) {
throw new Error(
`Only the first parameter to Template.absolutePath can be an absolute path. Received: ${p} from ${paths}`
);
}
i++;
}
let j = 0;
for (let p of paths) {
if (j === 0 && path.isAbsolute(p)) {
return TemplatePath.join(...paths);
}
j++;
}
return TemplatePath.join(TemplatePath.getWorkingDir(), ...paths);
};
/**
* Turns an absolute path into a path relative to the 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 (pathArg) {
if (pathArg === "." || pathArg === "..") {
return pathArg + "/";
}
if (
path.isAbsolute(pathArg) ||
pathArg.startsWith("./") ||
pathArg.startsWith("../")
) {
return pathArg;
}
return "./" + pathArg;
};
/**
* 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();
};
/**
* @param {String} path A path
* @returns {Boolean} whether `path` points to an existing directory.
*/
TemplatePath.isDirectory = async function (path) {
return new Promise((resolve) => {
fs.stat(path, (err, stats) => {
if (stats) {
resolve(stats.isDirectory());
}
resolve(false);
});
});
};
/**
* 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.convertToRecursiveGlobSync = function (path) {
if (path === "") {
return "./**";
}
path = TemplatePath.addLeadingDotSlash(path);
if (TemplatePath.isDirectorySync(path)) {
return path + (!path.endsWith("/") ? "/" : "") + "**";
}
return path;
};
/**
* 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 = async function (path) {
if (path === "") {
return "./**";
}
path = TemplatePath.addLeadingDotSlash(path);
if (await TemplatePath.isDirectory(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;
};
/**
* Accepts a relative file path that is using a standard directory separator and
* normalizes it using the local operating system separator.
* e.g. `./my/dir/` stays `./my/dir/` on *nix and becomes `.\\my\\dir\\` on Windows
*
* @param {String} filePath
* @returns {String} a file path with the correct local directory separator.
*/
TemplatePath.normalizeOperatingSystemFilePath = function (filePath, sep = "/") {
return filePath.split(sep).join(path.sep);
};
/**
* Accepts a relative file path with the local operating system directory separator and
* normalizes it using a forward slash directory separator. (Leaves trailing slash as-is)
* e.g. `./my/dir/` stays `./my/dir/` on *nix and becomes `.\\my\\dir\\` on Windows
*
* @param {String} filePath
* @returns {String} a file path with the correct local directory separator.
*/
TemplatePath.standardizeFilePath = function (filePath, sep = "/") {
return TemplatePath.addLeadingDotSlash(filePath.split(path.sep).join(sep));
};
module.exports = TemplatePath;

48
node_modules/@11ty/eleventy/CODE_OF_CONDUCT.md generated vendored Normal file
View File

@ -0,0 +1,48 @@
# Eleventy Community Code of Conduct
View the [Code of Conduct](https://www.11ty.dev/docs/code-of-conduct/) on 11ty.dev
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, chat messages, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at eleventy@zachleat.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

21
node_modules/@11ty/eleventy/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 20172023 Zach Leatherman @zachleat
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

49
node_modules/@11ty/eleventy/README.md generated vendored Normal file
View File

@ -0,0 +1,49 @@
<p align="center"><img src="https://www.11ty.dev/img/logo-github.svg" width="200" height="200" alt="eleventy Logo"></p>
# eleventy 🕚⚡️🎈🐀
A simpler static site generator. An alternative to Jekyll. Written in JavaScript. Transforms a directory of templates (of varying types) into HTML.
Works with HTML, Markdown, JavaScript, Liquid, Nunjucks, Handlebars, Mustache, EJS, Haml, and Pug.
## ➡ [Documentation](https://www.11ty.dev/docs/)
- Please star [this repo on GitHub](https://github.com/11ty/eleventy/)!
- Follow us on Twitter [@eleven_ty](https://twitter.com/eleven_ty)
- Support [11ty on Open Collective](https://opencollective.com/11ty)
- [11ty on npm](https://www.npmjs.com/org/11ty)
- [11ty on GitHub](https://github.com/11ty)
- Continuous Integration:
- [GitHub Actions](https://github.com/11ty/eleventy/actions?query=workflow%3A.github%2Fworkflows%2Fci.yml)
[![npm Version](https://img.shields.io/npm/v/@11ty/eleventy.svg?style=for-the-badge)](https://www.npmjs.com/package/@11ty/eleventy) [![GitHub issues](https://img.shields.io/github/issues/11ty/eleventy.svg?style=for-the-badge)](https://github.com/11ty/eleventy/issues) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=for-the-badge)](https://github.com/prettier/prettier) [![npm Downloads](https://img.shields.io/npm/dt/@11ty/eleventy.svg?style=for-the-badge)](https://www.npmjs.com/package/@11ty/eleventy)
## Installation
```
npm install @11ty/eleventy --save-dev
```
Read our [Getting Started guide](https://www.11ty.dev/docs/getting-started/).
## Tests
```
npm run test
```
- We use the [ava JavaScript test runner](https://github.com/avajs/ava) ([Assertions documentation](https://github.com/avajs/ava/blob/master/docs/03-assertions.md))
- To keep tests fast, thou shalt try to avoid writing files in tests.
- [Code Coverage Statistics](https://github.com/11ty/eleventy/blob/master/docs/coverage.md)
- [Benchmark for Performance Regressions](https://github.com/11ty/eleventy-benchmark)
## Community Roadmap
- [Top Feature Requests](https://github.com/11ty/eleventy/issues?q=label%3Aneeds-votes+sort%3Areactions-%2B1-desc+label%3Aenhancement) (Add your own votes using the 👍 reaction)
- [Documentation Requests](https://github.com/11ty/eleventy/issues?q=is%3Aissue+label%3Adocumentation+label%3Aneeds-votes+sort%3Areactions-%2B1-desc) (Add your own votes using the 👍 reaction)
- [Top Bugs 😱](https://github.com/11ty/eleventy/issues?q=is%3Aissue+is%3Aopen+label%3Abug+sort%3Areactions-%2B1-desc) (Add your own votes using the 👍 reaction)
- [Newest Bugs 🙀](https://github.com/11ty/eleventy/issues?q=is%3Aopen+is%3Aissue+label%3Abug)
## Plugins
See the [official docs on plugins](https://www.11ty.dev/docs/plugins/).

5
node_modules/@11ty/eleventy/SECURITY.md generated vendored Normal file
View File

@ -0,0 +1,5 @@
# Security Policy
## Reporting a Vulnerability
Please report security issues to `zach@zachleat.com`

132
node_modules/@11ty/eleventy/cmd.js generated vendored Executable file
View File

@ -0,0 +1,132 @@
#!/usr/bin/env node
const pkg = require("./package.json");
require("please-upgrade-node")(pkg, {
message: function (requiredVersion) {
return (
"Eleventy requires Node " +
requiredVersion +
". You will need to upgrade Node to use Eleventy!"
);
},
});
const debug = require("debug")("Eleventy:cmd");
const EleventyErrorHandler = require("./src/EleventyErrorHandler");
try {
let errorHandler = new EleventyErrorHandler();
const EleventyCommandCheckError = require("./src/EleventyCommandCheckError");
const argv = require("minimist")(process.argv.slice(2), {
string: ["input", "output", "formats", "config", "pathprefix", "port", "to"],
boolean: [
"quiet",
"version",
"watch",
"dryrun",
"help",
"serve",
"incremental",
"ignore-initial",
],
default: {
quiet: null,
"ignore-initial": false,
},
unknown: function (unknownArgument) {
throw new EleventyCommandCheckError(
`We dont know what '${unknownArgument}' is. Use --help to see the list of supported commands.`
);
},
});
debug("command: eleventy %o", argv);
const Eleventy = require("./src/Eleventy");
process.on("unhandledRejection", (error, promise) => {
errorHandler.fatal(error, "Unhandled rejection in promise");
});
process.on("uncaughtException", (error) => {
errorHandler.fatal(error, "Uncaught exception");
});
process.on("rejectionHandled", (promise) => {
errorHandler.warn(promise, "A promise rejection was handled asynchronously");
});
if (argv.version) {
console.log(Eleventy.getVersion());
} else if (argv.help) {
console.log(Eleventy.getHelp());
} else {
let elev = new Eleventy(argv.input, argv.output, {
source: "cli",
// --quiet and --quiet=true both resolve to true
quietMode: argv.quiet,
configPath: argv.config,
pathPrefix: argv.pathprefix,
runMode: argv.serve ? "serve" : argv.watch ? "watch" : "build",
});
// reuse ErrorHandler instance in Eleventy
errorHandler = elev.errorHandler;
if (argv.to === "json" || argv.to === "ndjson") {
// override logging output
elev.setIsVerbose(false);
}
elev.setDryRun(argv.dryrun);
elev.setIgnoreInitial(argv["ignore-initial"]);
elev.setIncrementalBuild(argv.incremental);
elev.setFormats(argv.formats);
// careful, we cant use async/await here to error properly
// with old node versions in `please-upgrade-node` above.
elev
.init()
.then(function () {
try {
if (argv.serve) {
let shouldStartServer = true;
elev
.watch()
.catch((e) => {
// Build failed but error message already displayed.
shouldStartServer = false;
// A build error occurred and we arent going to --serve
})
.then(function () {
if (shouldStartServer) {
elev.serve(argv.port);
}
});
} else if (argv.watch) {
elev.watch().catch((e) => {
// A build error occurred and we arent going to --watch
});
} else {
if (argv.to === "json") {
elev.toJSON().then(function (result) {
console.log(JSON.stringify(result, null, 2));
});
} else if (argv.to === "ndjson") {
elev.toNDJSON().then(function (stream) {
stream.pipe(process.stdout);
});
} else if (!argv.to || argv.to === "fs") {
elev.write();
} else {
throw new EleventyCommandCheckError(
`Invalid --to value: ${argv.to}. Supported values: \`fs\` (default), \`json\`, and \`ndjson\`.`
);
}
}
} catch (e) {
errorHandler.fatal(e, "Eleventy CLI Error");
}
})
.catch(errorHandler.fatal.bind(errorHandler));
}
} catch (e) {
let errorHandler = new EleventyErrorHandler();
errorHandler.fatal(e, "Eleventy CLI Fatal Error");
}

137
node_modules/@11ty/eleventy/package.json generated vendored Executable file
View File

@ -0,0 +1,137 @@
{
"name": "@11ty/eleventy",
"version": "2.0.1",
"description": "A simpler (static) site generator.",
"publishConfig": {
"access": "public"
},
"main": "src/Eleventy.js",
"types": "src/index.d.ts",
"bin": {
"eleventy": "./cmd.js"
},
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/11ty"
},
"keywords": [
"static-site-generator",
"static-site",
"ssg",
"documentation",
"website",
"jekyll",
"blog",
"templates",
"generator",
"framework",
"eleventy",
"11ty",
"html",
"markdown",
"liquid",
"nunjucks",
"pug",
"handlebars",
"mustache",
"ejs",
"haml"
],
"scripts": {
"default": "npm run test",
"format": "prettier src/ --write",
"test": "npx ava --verbose",
"lint-staged": "lint-staged",
"coverage": "npx nyc ava && npx nyc report --reporter=json-summary && cp coverage/coverage-summary.json docs-src/_data/coverage.json && node cmd.js --config=docs-src/.eleventy.docs.js",
"prepare": "husky install"
},
"author": {
"name": "Zach Leatherman",
"email": "zachleatherman@gmail.com",
"url": "https://zachleat.com/"
},
"repository": {
"type": "git",
"url": "git://github.com/11ty/eleventy.git"
},
"bugs": "https://github.com/11ty/eleventy/issues",
"homepage": "https://www.11ty.dev/",
"ava": {
"environmentVariables": {},
"failFast": true,
"files": [
"./test/*.js",
"./test/_issues/**/*test.js"
],
"ignoredByWatcher": [
"./test/stubs*/**/*",
".cache"
]
},
"lint-staged": {
"*.{js,css,md}": [
"prettier --write"
]
},
"devDependencies": {
"@11ty/eleventy-plugin-syntaxhighlight": "^4.2.0",
"@11ty/eleventy-plugin-vue": "1.0.0-canary.8",
"@vue/server-renderer": "^3.2.47",
"ava": "^5.2.0",
"husky": "^8.0.3",
"js-yaml": "^4.1.0",
"lint-staged": "^13.2.0",
"markdown-it-emoji": "^2.0.2",
"marked": "^4.3.0",
"nyc": "^15.1.0",
"prettier": "^2.8.7",
"pretty": "^2.0.0",
"rimraf": "^4.4.1",
"sass": "^1.60.0",
"vue": "^3.2.47"
},
"dependencies": {
"@11ty/dependency-tree": "^2.0.1",
"@11ty/eleventy-dev-server": "^1.0.4",
"@11ty/eleventy-utils": "^1.0.1",
"@11ty/lodash-custom": "^4.17.21",
"@iarna/toml": "^2.2.5",
"@sindresorhus/slugify": "^1.1.2",
"bcp-47-normalize": "^1.1.1",
"chokidar": "^3.5.3",
"cross-spawn": "^7.0.3",
"debug": "^4.3.4",
"dependency-graph": "^0.11.0",
"ejs": "^3.1.9",
"fast-glob": "^3.2.12",
"graceful-fs": "^4.2.11",
"gray-matter": "^4.0.3",
"hamljs": "^0.6.2",
"handlebars": "^4.7.7",
"is-glob": "^4.0.3",
"iso-639-1": "^2.1.15",
"kleur": "^4.1.5",
"liquidjs": "^10.7.0",
"luxon": "^3.3.0",
"markdown-it": "^13.0.1",
"micromatch": "^4.0.5",
"minimist": "^1.2.8",
"moo": "^0.5.2",
"multimatch": "^5.0.0",
"mustache": "^4.2.0",
"normalize-path": "^3.0.0",
"nunjucks": "^3.2.3",
"path-to-regexp": "^6.2.1",
"please-upgrade-node": "^3.2.0",
"posthtml": "^0.16.6",
"posthtml-urls": "^1.0.0",
"pug": "^3.0.2",
"recursive-copy": "^2.0.14",
"semver": "^7.3.8",
"slugify": "^1.6.6"
}
}

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

@ -0,0 +1,52 @@
const { performance } = require("perf_hooks");
class Benchmark {
constructor() {
this.reset();
}
getNewTimestamp() {
if (performance) {
return performance.now();
}
return new Date().getTime();
}
reset() {
this.timeSpent = 0;
this.timesCalled = 0;
this.beforeTimers = [];
}
incrementCount() {
this.timesCalled++;
}
// TODO(slightlyoff):
// disable all of these hrtime requests when not benchmarking
before() {
this.timesCalled++;
this.beforeTimers.push(this.getNewTimestamp());
}
after() {
if (!this.beforeTimers.length) {
throw new Error("You called Benchmark after() without a before().");
}
let before = this.beforeTimers.pop();
if (!this.beforeTimers.length) {
this.timeSpent += this.getNewTimestamp() - before;
}
}
getTimesCalled() {
return this.timesCalled;
}
getTotal() {
return this.timeSpent;
}
}
module.exports = Benchmark;

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

@ -0,0 +1,124 @@
const ConsoleLogger = require("./Util/ConsoleLogger");
const Benchmark = require("./Benchmark");
const debugBenchmark = require("debug")("Eleventy:Benchmark");
class BenchmarkGroup {
constructor() {
this.benchmarks = {};
// Warning: aggregate benchmarks automatically default to false via BenchmarkManager->getBenchmarkGroup
this.isVerbose = true;
this.logger = new ConsoleLogger(this.isVerbose);
this.minimumThresholdMs = 0;
this.minimumThresholdPercent = 8;
}
setIsVerbose(isVerbose) {
this.isVerbose = isVerbose;
this.logger.isVerbose = isVerbose;
}
reset() {
for (var type in this.benchmarks) {
this.benchmarks[type].reset();
}
}
// TODO use addAsync everywhere instead
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;
};
}
// callback must return a promise
// async addAsync(type, callback) {
// let benchmark = (this.benchmarks[type] = new Benchmark());
// benchmark.before();
// // dont await here.
// let promise = callback.call(this);
// promise.then(function() {
// benchmark.after();
// });
// return promise;
// }
setMinimumThresholdMs(minimumThresholdMs) {
let val = parseInt(minimumThresholdMs, 10);
if (isNaN(val)) {
throw new Error("`setMinimumThresholdMs` expects a number argument.");
}
this.minimumThresholdMs = val;
}
setMinimumThresholdPercent(minimumThresholdPercent) {
let val = parseInt(minimumThresholdPercent, 10);
if (isNaN(val)) {
throw new Error(
"`setMinimumThresholdPercent` expects a number argument."
);
}
this.minimumThresholdPercent = val;
}
has(type) {
return !!this.benchmarks[type];
}
get(type) {
if (!this.benchmarks[type]) {
this.benchmarks[type] = new Benchmark();
}
return this.benchmarks[type];
}
padNumber(num, length) {
if (("" + num).length >= length) {
return num;
}
let prefix = new Array(length + 1).join(" ");
return (prefix + num).substr(-1 * length);
}
finish(label, totalTimeSpent) {
for (var type in this.benchmarks) {
let bench = this.benchmarks[type];
let isAbsoluteMinimumComparison = this.minimumThresholdMs > 0;
let totalForBenchmark = bench.getTotal();
let percent = Math.round((totalForBenchmark * 100) / totalTimeSpent);
let callCount = bench.getTimesCalled();
let output = {
ms: this.padNumber(totalForBenchmark.toFixed(0), 6),
percent: this.padNumber(percent, 3),
calls: this.padNumber(callCount, 5),
};
let str = `Benchmark ${output.ms}ms ${output.percent}% ${output.calls}× (${label}) ${type}`;
if (
(isAbsoluteMinimumComparison &&
totalForBenchmark >= this.minimumThresholdMs) ||
percent > this.minimumThresholdPercent
) {
this.logger.warn(str);
}
// Opt out of logging if low count (1× or 2×) or 0ms / 1%
if (
totalForBenchmark.toFixed(0) > 1 || // more than 1ms
callCount > 2 || // more than 2×
percent > 1 // more than 1%
) {
debugBenchmark(str);
}
}
}
}
module.exports = BenchmarkGroup;

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

@ -0,0 +1,72 @@
const BenchmarkGroup = require("./BenchmarkGroup");
const { performance } = require("perf_hooks");
// TODO this should not be a singleton, it belongs in the config or somewhere on the Eleventy instance.
class BenchmarkManager {
constructor() {
this.benchmarkGroups = {};
this.isVerbose = true;
this.start = this.getNewTimestamp();
}
reset() {
this.start = this.getNewTimestamp();
for (var j in this.benchmarkGroups) {
this.benchmarkGroups[j].reset();
}
}
getNewTimestamp() {
if (performance) {
return performance.now();
}
return new Date().getTime();
}
setVerboseOutput(isVerbose) {
this.isVerbose = !!isVerbose;
}
hasBenchmarkGroup(name) {
return name in this.benchmarkGroups;
}
getBenchmarkGroup(name) {
if (!this.benchmarkGroups[name]) {
this.benchmarkGroups[name] = new BenchmarkGroup();
// Special behavior for aggregate benchmarks
// so they dont console.log every time
if (name === "Aggregate") {
this.benchmarkGroups[name].setIsVerbose(false);
} else {
this.benchmarkGroups[name].setIsVerbose(this.isVerbose);
}
}
return this.benchmarkGroups[name];
}
getAll() {
return this.benchmarkGroups;
}
get(name) {
if (name) {
return this.getBenchmarkGroup(name);
}
return this.getAll();
}
finish() {
let totalTimeSpentBenchmarking = this.getNewTimestamp() - this.start;
for (var j in this.benchmarkGroups) {
this.benchmarkGroups[j].finish(j, totalTimeSpentBenchmarking);
}
}
}
module.exports = BenchmarkManager;

116
node_modules/@11ty/eleventy/src/ComputedData.js generated vendored Normal file
View File

@ -0,0 +1,116 @@
const { set: lodashSet, get: lodashGet } = require("@11ty/lodash-custom");
const ComputedDataQueue = require("./ComputedDataQueue");
const ComputedDataTemplateString = require("./ComputedDataTemplateString");
const ComputedDataProxy = require("./ComputedDataProxy");
const debug = require("debug")("Eleventy:ComputedData");
class ComputedData {
constructor(config) {
this.computed = {};
this.symbolParseFunctions = {};
this.templateStringKeyLookup = {};
this.computedKeys = new Set();
this.declaredDependencies = {};
this.queue = new ComputedDataQueue();
this.config = config;
}
add(key, renderFn, declaredDependencies = [], symbolParseFn = undefined) {
this.computedKeys.add(key);
this.declaredDependencies[key] = declaredDependencies;
// bind config filters/JS functions
if (typeof renderFn === "function") {
let fns = {};
// TODO bug? no access to non-universal config things?
if (this.config) {
fns = this.config.javascriptFunctions;
}
renderFn = renderFn.bind(fns);
}
lodashSet(this.computed, key, renderFn);
if (symbolParseFn) {
lodashSet(this.symbolParseFunctions, key, symbolParseFn);
}
}
addTemplateString(key, renderFn, declaredDependencies = [], symbolParseFn = undefined) {
this.add(key, renderFn, declaredDependencies, symbolParseFn);
this.templateStringKeyLookup[key] = true;
}
async resolveVarOrder(data) {
let proxyByTemplateString = new ComputedDataTemplateString(this.computedKeys);
let proxyByProxy = new ComputedDataProxy(this.computedKeys);
for (let key of this.computedKeys) {
let computed = lodashGet(this.computed, key);
if (typeof computed !== "function") {
// add nodes for non functions (primitives like booleans, etc)
// This will not handle template strings, as they are normalized to functions
this.queue.addNode(key);
} else {
this.queue.uses(key, this.declaredDependencies[key]);
let symbolParseFn = lodashGet(this.symbolParseFunctions, key);
let varsUsed = [];
if (symbolParseFn) {
// use the parseForSymbols function in the TemplateEngine
varsUsed = symbolParseFn();
} else if (symbolParseFn !== false) {
// skip resolution is this is false (just use declaredDependencies)
let isTemplateString = !!this.templateStringKeyLookup[key];
let proxy = isTemplateString ? proxyByTemplateString : proxyByProxy;
varsUsed = await proxy.findVarsUsed(computed, data);
}
debug("%o accesses %o variables", key, varsUsed);
let filteredVarsUsed = varsUsed.filter((varUsed) => {
return (
(varUsed !== key && this.computedKeys.has(varUsed)) ||
varUsed.startsWith("collections.")
);
});
this.queue.uses(key, filteredVarsUsed);
}
}
}
async _setupDataEntry(data, order) {
debug("Computed data order of execution: %o", order);
for (let key of order) {
let computed = lodashGet(this.computed, key);
if (typeof computed === "function") {
let ret = await computed(data);
lodashSet(data, key, ret);
} else if (computed !== undefined) {
lodashSet(data, key, computed);
}
}
}
async setupData(data, orderFilter) {
await this.resolveVarOrder(data);
await this.processRemainingData(data, orderFilter);
}
async processRemainingData(data, orderFilter) {
// process all variables
let order = this.queue.getOrder();
if (orderFilter && typeof orderFilter === "function") {
order = order.filter(orderFilter.bind(this.queue));
}
await this._setupDataEntry(data, order);
this.queue.markComputed(order);
}
}
module.exports = ComputedData;

129
node_modules/@11ty/eleventy/src/ComputedDataProxy.js generated vendored Normal file
View File

@ -0,0 +1,129 @@
const { set: lodashSet, get: lodashGet } = require("@11ty/lodash-custom");
const { isPlainObject } = require("@11ty/eleventy-utils");
/* Calculates computed data using Proxies */
class ComputedDataProxy {
constructor(computedKeys) {
if (Array.isArray(computedKeys)) {
this.computedKeys = new Set(computedKeys);
} else {
this.computedKeys = computedKeys;
}
}
isArrayOrPlainObject(data) {
return Array.isArray(data) || isPlainObject(data);
}
getProxyData(data, keyRef) {
// WARNING: SIDE EFFECTS
// Set defaults for keys not already set on parent data
// TODO should make another effort to get rid of this,
// See the ProxyWrap util for more proxy handlers that will likely fix this
let undefinedValue = "__11TY_UNDEFINED__";
if (this.computedKeys) {
for (let key of this.computedKeys) {
if (lodashGet(data, key, undefinedValue) === undefinedValue) {
lodashSet(data, key, "");
}
}
}
let proxyData = this._getProxyData(data, keyRef);
return proxyData;
}
_getProxyForObject(dataObj, keyRef, parentKey = "") {
return new Proxy(
{},
{
get: (obj, key) => {
if (typeof key !== "string") {
return obj[key];
}
let newKey = `${parentKey ? `${parentKey}.` : ""}${key}`;
// Issue #1137
// Special case for Collections, always return an Array for collection keys
// so they it works fine with Array methods like `filter`, `map`, etc
if (newKey === "collections") {
keyRef.add(newKey);
return new Proxy(
{},
{
get: (target, key) => {
if (typeof key === "string") {
keyRef.add(`collections.${key}`);
return [];
}
return target[key];
},
}
);
}
let newData = this._getProxyData(dataObj[key], keyRef, newKey);
if (!this.isArrayOrPlainObject(newData)) {
keyRef.add(newKey);
}
return newData;
},
}
);
}
_getProxyForArray(dataArr, keyRef, parentKey = "") {
return new Proxy(new Array(dataArr.length), {
get: (obj, key) => {
if (Array.prototype.hasOwnProperty(key)) {
// remove `filter`, `constructor`, `map`, etc
keyRef.add(parentKey);
return obj[key];
}
// Hm, this needs to be better
if (key === "then") {
keyRef.add(parentKey);
return;
}
let newKey = `${parentKey}[${key}]`;
let newData = this._getProxyData(dataArr[key], keyRef, newKey);
if (!this.isArrayOrPlainObject(newData)) {
keyRef.add(newKey);
}
return newData;
},
});
}
_getProxyData(data, keyRef, parentKey = "") {
if (isPlainObject(data)) {
return this._getProxyForObject(data, keyRef, parentKey);
} else if (Array.isArray(data)) {
return this._getProxyForArray(data, keyRef, parentKey);
}
// everything else!
return data;
}
async findVarsUsed(fn, data = {}) {
let keyRef = new Set();
// careful, logging proxyData will mess with test results!
let proxyData = this.getProxyData(data, keyRef);
// squelch console logs for this fake proxy data pass 😅
// let savedLog = console.log;
// console.log = () => {};
await fn(proxyData);
// console.log = savedLog;
return Array.from(keyRef);
}
}
module.exports = ComputedDataProxy;

64
node_modules/@11ty/eleventy/src/ComputedDataQueue.js generated vendored Normal file
View File

@ -0,0 +1,64 @@
const DependencyGraph = require("dependency-graph").DepGraph;
/* Keeps track of the dependency graph between computed data variables
* Removes keys from the graph when they are computed.
*/
class ComputedDataQueue {
constructor() {
this.graph = new DependencyGraph();
}
getOrder() {
return this.graph.overallOrder();
}
getOrderFor(name) {
return this.graph.dependenciesOf(name);
}
getDependsOn(name) {
return this.graph.dependantsOf(name);
}
isUsesStartsWith(name, prefix) {
if (name.startsWith(prefix)) {
return true;
}
return (
this.graph.dependenciesOf(name).filter((entry) => {
return entry.startsWith(prefix);
}).length > 0
);
}
addNode(name) {
if (!this.graph.hasNode(name)) {
this.graph.addNode(name);
}
}
_uses(graph, name, varsUsed = []) {
if (!graph.hasNode(name)) {
graph.addNode(name);
}
for (let varUsed of varsUsed) {
if (!graph.hasNode(varUsed)) {
graph.addNode(varUsed);
}
graph.addDependency(name, varUsed);
}
}
uses(name, varsUsed = []) {
this._uses(this.graph, name, varsUsed);
}
markComputed(varsComputed = []) {
for (let varComputed of varsComputed) {
this.graph.removeNode(varComputed);
}
}
}
module.exports = ComputedDataQueue;

View File

@ -0,0 +1,68 @@
const { set: lodashSet } = require("@11ty/lodash-custom");
const debug = require("debug")("Eleventy:ComputedDataTemplateString");
/* Calculates computed data in Template Strings.
* Ideally we would use the Proxy approach but it doesnt work
* in some template languages that visit all available data even if
* it isnt used in the template (Nunjucks)
*/
class ComputedDataTemplateString {
constructor(computedKeys) {
if (Array.isArray(computedKeys)) {
this.computedKeys = new Set(computedKeys);
} else {
this.computedKeys = computedKeys;
}
// is this ¯\_(lisp)_/¯
// must be strings that wont be escaped by template languages
this.prefix = "(((11ty(((";
this.suffix = ")))11ty)))";
}
getProxyData() {
let proxyData = {};
// use these special strings as a workaround to check the rendered output
// cant use proxies here as some template languages trigger proxy for all
// keys in data
for (let key of this.computedKeys) {
// TODO dont allow to set eleventyComputed.page? other disallowed computed things?
lodashSet(proxyData, key, this.prefix + key + this.suffix);
}
return proxyData;
}
findVarsInOutput(output = "") {
let vars = new Set();
let splits = output.split(this.prefix);
for (let split of splits) {
let varName = split.slice(0, split.indexOf(this.suffix) < 0 ? 0 : split.indexOf(this.suffix));
if (varName) {
vars.add(varName);
}
}
return Array.from(vars);
}
async findVarsUsed(fn) {
let proxyData = this.getProxyData();
let output;
// Mitigation for #1061, errors with filters in the first pass shouldnt fail the whole thing.
try {
output = await fn(proxyData);
} catch (e) {
debug("Computed Data first pass data resolution error: %o", e);
}
// page.outputPath on serverless urls returns false.
if (typeof output === "string") {
return this.findVarsInOutput(output);
}
return [];
}
}
module.exports = ComputedDataTemplateString;

1245
node_modules/@11ty/eleventy/src/Eleventy.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

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

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

View File

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

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

@ -0,0 +1,121 @@
const ConsoleLogger = require("./Util/ConsoleLogger");
const EleventyErrorUtil = require("./EleventyErrorUtil");
const debug = require("debug")("Eleventy:EleventyErrorHandler");
class EleventyErrorHandler {
constructor() {
this._isVerbose = true;
}
get isVerbose() {
return this._isVerbose;
}
set isVerbose(verbose) {
this._isVerbose = !!verbose;
this.logger.isVerbose = !!verbose;
}
get logger() {
if (!this._logger) {
this._logger = new ConsoleLogger();
this._logger.isVerbose = this.isVerbose;
}
return this._logger;
}
set logger(logger) {
this._logger = logger;
}
warn(e, msg) {
if (msg) {
this.initialMessage(msg, "warn", "yellow");
}
this.log(e, "warn");
}
fatal(e, msg) {
this.error(e, msg);
process.exitCode = 1;
}
error(e, msg) {
if (msg) {
this.initialMessage(msg, "error", "red", true);
}
this.log(e, "error", undefined, true);
}
//https://nodejs.org/api/process.html
log(e, type = "log", chalkColor = "", forceToConsole = false) {
let errorCount = 0;
let errorCountRef = e;
while (errorCountRef) {
errorCount++;
errorCountRef = errorCountRef.originalError;
}
let ref = e;
let index = 1;
while (ref) {
let nextRef = ref.originalError;
if (!nextRef && EleventyErrorUtil.hasEmbeddedError(ref.message)) {
nextRef = EleventyErrorUtil.deconvertErrorToObject(ref);
}
this.logger.message(
`${errorCount > 1 ? `${index}. ` : ""}${(
EleventyErrorUtil.cleanMessage(ref.message) ||
"(No error message provided)"
).trim()} (via ${ref.name})`,
type,
chalkColor,
forceToConsole
);
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…)"
);
}
this.logger.message(
"\nOriginal error stack trace: " + stackStr,
type,
chalkColor,
forceToConsole
);
}
ref = nextRef;
index++;
}
}
initialMessage(
message,
type = "log",
chalkColor = "blue",
forceToConsole = false
) {
if (message) {
this.logger.message(
message + ":" + (process.env.DEBUG ? "" : " (more in DEBUG output)"),
type,
chalkColor,
forceToConsole
);
}
}
}
module.exports = EleventyErrorHandler;

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

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

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

@ -0,0 +1,268 @@
const { TemplatePath } = require("@11ty/eleventy-utils");
const TemplateEngineManager = require("./TemplateEngineManager");
const TemplateConfig = require("./TemplateConfig");
const EleventyBaseError = require("./EleventyBaseError");
class EleventyExtensionMapConfigError extends EleventyBaseError {}
class EleventyExtensionMap {
constructor(formatKeys, config) {
if (!config) {
throw new EleventyExtensionMapConfigError("Missing `config` argument.");
}
if (config instanceof TemplateConfig) {
this.eleventyConfig = config;
}
this._config = config;
this.formatKeys = formatKeys;
this.setFormats(formatKeys);
this._spiderJsDepsCache = {};
}
setFormats(formatKeys = []) {
this.unfilteredFormatKeys = formatKeys.map(function (key) {
return key.trim().toLowerCase();
});
this.validTemplateLanguageKeys = this.unfilteredFormatKeys.filter((key) =>
this.hasExtension(key)
);
this.passthroughCopyKeys = this.unfilteredFormatKeys.filter((key) => !this.hasExtension(key));
}
set config(cfg) {
this._config = cfg;
}
get config() {
if (this._config instanceof TemplateConfig) {
return this._config.getConfig();
}
return this._config;
}
get engineManager() {
if (!this._engineManager) {
this._engineManager = new TemplateEngineManager(this.eleventyConfig);
}
return this._engineManager;
}
reset() {
this.engineManager.reset();
}
/* Used for layout path resolution */
getFileList(path, dir) {
if (!path) {
return [];
}
let files = [];
this.validTemplateLanguageKeys.forEach(
function (key) {
this.getExtensionsFromKey(key).forEach(function (extension) {
files.push((dir ? dir + "/" : "") + path + "." + extension);
});
}.bind(this)
);
return files;
}
// Warning: this would false positive on an include, but is only used
// on paths found from the file system glob search.
// TODO: Method name might just need to be renamed to something more accurate.
isFullTemplateFilePath(path) {
for (let extension of this.validTemplateLanguageKeys) {
if (path.endsWith(`.${extension}`)) {
return true;
}
}
return false;
}
getCustomExtensionEntry(extension) {
if (!this.config.extensionMap) {
return;
}
for (let entry of this.config.extensionMap) {
if (entry.extension === extension) {
return entry;
}
}
}
getValidExtensionsForPath(path) {
let extensions = new Set();
for (let extension in this.extensionToKeyMap) {
if (path.endsWith(`.${extension}`)) {
extensions.add(extension);
}
}
// if multiple extensions are valid, sort from longest to shortest
// e.g. .11ty.js and .js
let sorted = Array.from(extensions)
.filter((extension) => this.validTemplateLanguageKeys.includes(extension))
.sort((a, b) => b.length - a.length);
return sorted;
}
shouldSpiderJavaScriptDependencies(path) {
let extensions = this.getValidExtensionsForPath(path);
for (let extension of extensions) {
if (extension in this._spiderJsDepsCache) {
return this._spiderJsDepsCache[extension];
}
let cls = this.engineManager.getEngineClassByExtension(extension);
if (cls) {
let entry = this.getCustomExtensionEntry(extension);
let shouldSpider = cls.shouldSpiderJavaScriptDependencies(entry);
this._spiderJsDepsCache[extension] = shouldSpider;
return shouldSpider;
}
}
return false;
}
getPassthroughCopyGlobs(inputDir) {
return this._getGlobs(this.passthroughCopyKeys, inputDir);
}
getValidGlobs(inputDir) {
return this._getGlobs(this.validTemplateLanguageKeys, inputDir);
}
getGlobs(inputDir) {
return this._getGlobs(this.unfilteredFormatKeys, inputDir);
}
_getGlobs(formatKeys, inputDir) {
let dir = TemplatePath.convertToRecursiveGlobSync(inputDir);
let extensions = [];
for (let key of formatKeys) {
if (this.hasExtension(key)) {
for (let extension of this.getExtensionsFromKey(key)) {
extensions.push(extension);
}
} else {
extensions.push(key);
}
}
let globs = [];
if (extensions.length === 1) {
globs.push(`${dir}/*.${extensions[0]}`);
} else if (extensions.length > 1) {
globs.push(`${dir}/*.{${extensions.join(",")}}`);
}
return globs;
}
hasExtension(key) {
for (var extension in this.extensionToKeyMap) {
if (this.extensionToKeyMap[extension] === key) {
return true;
}
}
return false;
}
getExtensionsFromKey(key) {
let extensions = [];
for (var extension in this.extensionToKeyMap) {
if (this.extensionToKeyMap[extension] === key) {
extensions.push(extension);
}
}
return extensions;
}
// Only `addExtension` configuration API extensions
getExtensionEntriesFromKey(key) {
let entries = [];
if ("extensionMap" in this.config) {
for (let entry of this.config.extensionMap) {
if (entry.key === key) {
entries.push(entry);
}
}
}
return entries;
}
hasEngine(pathOrKey) {
return !!this.getKey(pathOrKey);
}
getKey(pathOrKey) {
pathOrKey = (pathOrKey || "").toLowerCase();
for (var extension in this.extensionToKeyMap) {
let key = this.extensionToKeyMap[extension];
if (pathOrKey === extension) {
return key;
} else if (pathOrKey.endsWith("." + extension)) {
return key;
}
}
}
removeTemplateExtension(path) {
for (var extension in this.extensionToKeyMap) {
if (path === extension || path.endsWith("." + extension)) {
return path.slice(
0,
path.length - 1 - extension.length < 0 ? 0 : path.length - 1 - extension.length
);
}
}
return path;
}
// keys are file extensions
// values are template language keys
get extensionToKeyMap() {
if (!this._extensionToKeyMap) {
this._extensionToKeyMap = {
ejs: "ejs",
md: "md",
html: "html",
hbs: "hbs",
mustache: "mustache",
haml: "haml",
pug: "pug",
njk: "njk",
liquid: "liquid",
"11ty.js": "11ty.js",
"11ty.cjs": "11ty.js",
};
if ("extensionMap" in this.config) {
for (let entry of this.config.extensionMap) {
this._extensionToKeyMap[entry.extension] = entry.key;
}
}
}
return this._extensionToKeyMap;
}
getReadableFileExtensions() {
return Object.keys(this.extensionToKeyMap).join(" ");
}
}
module.exports = EleventyExtensionMap;

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

@ -0,0 +1,463 @@
const fs = require("fs");
const { TemplatePath } = require("@11ty/eleventy-utils");
const EleventyExtensionMap = require("./EleventyExtensionMap");
const TemplateData = require("./TemplateData");
const TemplateGlob = require("./TemplateGlob");
const TemplatePassthroughManager = require("./TemplatePassthroughManager");
const EleventyBaseError = require("./EleventyBaseError");
const checkPassthroughCopyBehavior = require("./Util/PassthroughCopyBehaviorCheck");
class EleventyFilesError extends EleventyBaseError {}
const debug = require("debug")("Eleventy:EleventyFiles");
// const debugDev = require("debug")("Dev:Eleventy:EleventyFiles");
class EleventyFiles {
constructor(input, outputDir, formats, eleventyConfig) {
if (!eleventyConfig) {
throw new EleventyFilesError("Missing `eleventyConfig`` argument.");
}
this.eleventyConfig = eleventyConfig;
this.config = eleventyConfig.getConfig();
this.aggregateBench = this.config.benchmarkManager.get("Aggregate");
this.input = input;
this.inputDir = TemplatePath.getDir(this.input);
this.outputDir = outputDir;
this.initConfig();
this.formats = formats;
this.eleventyIgnoreContent = false;
// init has not yet been called()
this.alreadyInit = false;
}
setFileSystemSearch(fileSystemSearch) {
this.fileSystemSearch = fileSystemSearch;
}
/* Overrides this.input and this.inputDir,
* Useful when input is a file and inputDir is not its direct parent */
setInput(inputDir, input) {
this.inputDir = inputDir;
this.input = input;
this.initConfig();
if (this.alreadyInit) {
this.init();
}
}
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.alreadyInit = true;
// Input is a directory
if (this.input === this.inputDir) {
this.templateGlobs = this.extensionMap.getGlobs(this.inputDir);
} else {
// input is not a directory
this.templateGlobs = TemplateGlob.map([this.input]);
}
this.initPassthroughManager();
this.setupGlobs();
}
get validTemplateGlobs() {
if (!this._validTemplateGlobs) {
let globs;
// Input is a directory
if (this.input === this.inputDir) {
globs = this.extensionMap.getValidGlobs(this.inputDir);
} else {
globs = this.templateGlobs;
}
this._validTemplateGlobs = globs;
}
return this._validTemplateGlobs;
}
get passthroughGlobs() {
let paths = new Set();
// stuff added in addPassthroughCopy()
for (let path of this.passthroughManager.getConfigPathGlobs()) {
paths.add(path);
}
// non-template language extensions
for (let path of this.extensionMap.getPassthroughCopyGlobs(this.inputDir)) {
paths.add(path);
}
return Array.from(paths);
}
restart() {
this.passthroughManager.reset();
this.setupGlobs();
this._glob = null;
}
/* For testing */
_setConfig(config) {
if (!config.ignores) {
config.ignores = new Set();
config.ignores.add("**/node_modules/**");
}
this.config = config;
this.initConfig();
}
/* Set command root for local project paths */
// This is only used by tests
_setLocalPathRoot(dir) {
this.localPathRoot = dir;
}
set extensionMap(extensionMap) {
this._extensionMap = extensionMap;
}
get extensionMap() {
// for tests
if (!this._extensionMap) {
this._extensionMap = new EleventyExtensionMap(this.formats, this.eleventyConfig);
this._extensionMap.config = this.config;
}
return this._extensionMap;
}
setRunMode(runMode) {
this.runMode = runMode;
}
initPassthroughManager() {
let mgr = new TemplatePassthroughManager(this.eleventyConfig);
mgr.setInputDir(this.inputDir);
mgr.setOutputDir(this.outputDir);
mgr.setRunMode(this.runMode);
mgr.extensionMap = this.extensionMap;
mgr.setFileSystemSearch(this.fileSystemSearch);
this.passthroughManager = mgr;
}
getPassthroughManager() {
return this.passthroughManager;
}
setPassthroughManager(mgr) {
mgr.extensionMap = this.extensionMap;
this.passthroughManager = mgr;
}
set templateData(templateData) {
this._templateData = templateData;
}
get templateData() {
if (!this._templateData) {
this._templateData = new TemplateData(this.inputDir, this.eleventyConfig);
}
return this._templateData;
}
getDataDir() {
let data = this.templateData;
return data.getDataDir();
}
setupGlobs() {
this.fileIgnores = this.getIgnores();
this.extraIgnores = this._getIncludesAndDataDirs();
this.uniqueIgnores = this.getIgnoreGlobs();
// Conditional added for tests that dont have a config
if (this.config && this.config.events) {
this.config.events.emit("eleventy.ignores", this.uniqueIgnores);
}
this.normalizedTemplateGlobs = this.templateGlobs;
}
getIgnoreGlobs() {
let uniqueIgnores = new Set();
for (let ignore of this.fileIgnores) {
uniqueIgnores.add(ignore);
}
for (let ignore of this.extraIgnores) {
uniqueIgnores.add(ignore);
}
// Placing the config ignores last here is important to the tests
for (let ignore of this.config.ignores) {
uniqueIgnores.add(TemplateGlob.normalizePath(this.localPathRoot || ".", ignore));
}
return Array.from(uniqueIgnores);
}
static getFileIgnores(ignoreFiles) {
if (!Array.isArray(ignoreFiles)) {
ignoreFiles = [ignoreFiles];
}
let ignores = [];
for (let ignorePath of ignoreFiles) {
ignorePath = TemplatePath.normalize(ignorePath);
let dir = TemplatePath.getDirFromFilePath(ignorePath);
if (fs.existsSync(ignorePath) && fs.statSync(ignorePath).size > 0) {
let ignoreContent = fs.readFileSync(ignorePath, "utf8");
ignores = ignores.concat(EleventyFiles.normalizeIgnoreContent(dir, ignoreContent));
}
}
ignores.forEach((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) => {
if (line.charAt(0) === "!") {
debug(
">>> When processing .gitignore/.eleventyignore, Eleventy does not currently support negative patterns but encountered one:"
);
debug(">>>", line);
debug("Follow along at https://github.com/11ty/eleventy/issues/693 to track support.");
}
// empty lines or comments get filtered out
return line.length > 0 && line.charAt(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;
}
setEleventyIgnoreContent(content) {
this.eleventyIgnoreContent = content;
}
getIgnores() {
let files = new Set();
for (let ignore of EleventyFiles.getFileIgnores(this.getIgnoreFiles())) {
files.add(ignore);
}
// testing API
if (this.eleventyIgnoreContent !== false) {
files.add(this.eleventyIgnoreContent);
}
// ignore output dir unless that would exclude all input
if (!TemplatePath.startsWithSubPath(this.inputDir, this.outputDir)) {
files.add(TemplateGlob.map(this.outputDir + "/**"));
}
return Array.from(files);
}
getIgnoreFiles() {
let ignoreFiles = [];
let rootDirectory = this.localPathRoot || ".";
if (this.config.useGitIgnore) {
ignoreFiles.push(TemplatePath.join(rootDirectory, ".gitignore"));
}
if (this.eleventyIgnoreContent === false) {
let absoluteInputDir = TemplatePath.absolutePath(this.inputDir);
ignoreFiles.push(TemplatePath.join(rootDirectory, ".eleventyignore"));
if (rootDirectory !== absoluteInputDir) {
ignoreFiles.push(TemplatePath.join(this.inputDir, ".eleventyignore"));
}
}
return ignoreFiles;
}
getIncludesDir() {
return this.includesDir;
}
getLayoutsDir() {
return this.layoutsDir;
}
getFileGlobs() {
return this.normalizedTemplateGlobs;
}
getRawFiles() {
return this.templateGlobs;
}
getWatchPathCache() {
// Issue #1325: make sure passthrough copy files are not included here
if (!this.pathCache) {
throw new Error("Watching requires `.getFiles()` to be called first in EleventyFiles");
}
// Filter out the passthrough copy paths.
return this.pathCache.filter((path) => {
return (
this.extensionMap.isFullTemplateFilePath(path) &&
this.extensionMap.shouldSpiderJavaScriptDependencies(path)
);
});
}
_globSearch() {
let globs = this.getFileGlobs();
// returns a promise
debug("Searching for: %o", globs);
return this.fileSystemSearch.search("templates", globs, {
ignore: this.uniqueIgnores,
});
}
async getFiles() {
let bench = this.aggregateBench.get("Searching the file system (templates)");
bench.before();
let globResults = await this._globSearch();
let paths = TemplatePath.addLeadingDotSlashArray(globResults);
bench.after();
// Note 2.0.0-canary.19 removed a `filter` option for custom template syntax here that was unpublished and unused.
this.pathCache = paths;
return paths;
}
// Assumption here that filePath is not a passthrough copy file
isFullTemplateFile(paths, filePath) {
if (!filePath) {
return false;
}
for (let path of paths) {
if (path === filePath) {
return true;
}
}
return false;
}
/* For `eleventy --watch` */
getGlobWatcherFiles() {
// TODO improvement: tie the includes and data to specific file extensions (currently using `**`)
let directoryGlobs = this._getIncludesAndDataDirs();
if (checkPassthroughCopyBehavior(this.config, this.runMode)) {
return this.validTemplateGlobs.concat(directoryGlobs);
}
// Revert to old passthroughcopy copy files behavior
return this.validTemplateGlobs.concat(this.passthroughGlobs).concat(directoryGlobs);
}
/* For `eleventy --watch` */
getGlobWatcherFilesForPassthroughCopy() {
return this.passthroughGlobs;
}
/* For `eleventy --watch` */
async getGlobWatcherTemplateDataFiles() {
let templateData = this.templateData;
return await templateData.getTemplateDataFileGlob();
}
/* For `eleventy --watch` */
// TODO this isnt great but reduces complexity avoiding using TemplateData:getLocalDataPaths for each template in the cache
async getWatcherTemplateJavaScriptDataFiles() {
let globs = await this.templateData.getTemplateJavaScriptDataFileGlob();
let bench = this.aggregateBench.get("Searching the file system (watching)");
bench.before();
let results = TemplatePath.addLeadingDotSlashArray(
await this.fileSystemSearch.search("js-dependencies", globs, {
ignore: ["**/node_modules/**"],
})
);
bench.after();
return results;
}
/* Ignored by `eleventy --watch` */
getGlobWatcherIgnores() {
// convert to format without ! since they are passed in as a separate argument to glob watcher
let entries = new Set(
this.fileIgnores.map((ignore) => TemplatePath.stripLeadingDotSlash(ignore))
);
for (let ignore of this.config.watchIgnores) {
entries.add(TemplateGlob.normalizePath(this.localPathRoot || ".", ignore));
}
// de-duplicated
return Array.from(entries);
}
_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;
}
}
module.exports = EleventyFiles;

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

@ -0,0 +1,259 @@
const { TemplatePath } = require("@11ty/eleventy-utils");
const EleventyBaseError = require("./EleventyBaseError");
const ConsoleLogger = require("./Util/ConsoleLogger");
const PathPrefixer = require("./Util/PathPrefixer");
const merge = require("./Util/Merge");
const checkPassthroughCopyBehavior = require("./Util/PassthroughCopyBehaviorCheck");
const debug = require("debug")("EleventyServe");
class EleventyServeConfigError extends EleventyBaseError {}
const DEFAULT_SERVER_OPTIONS = {
module: "@11ty/eleventy-dev-server",
port: 8080,
// pathPrefix: "/",
// setup: function() {},
// logger: { info: function() {}, error: function() {} }
};
class EleventyServe {
constructor() {
this.logger = new ConsoleLogger(true);
this._initOptionsFetched = false;
this._aliases = undefined;
this._watchedFiles = new Set();
}
get config() {
if (!this._config) {
throw new EleventyServeConfigError("You need to set the config property on EleventyServe.");
}
return this._config;
}
set config(config) {
this._options = null;
this._config = config;
}
setAliases(aliases) {
this._aliases = aliases;
if (this._server && "setAliases" in this._server) {
this._server.setAliases(aliases);
}
}
get eleventyConfig() {
if (!this._eleventyConfig) {
throw new EleventyServeConfigError(
"You need to set the eleventyConfig property on EleventyServe."
);
}
return this._eleventyConfig;
}
set eleventyConfig(config) {
this._eleventyConfig = config;
if (checkPassthroughCopyBehavior(this._eleventyConfig.userConfig, "serve")) {
this._eleventyConfig.userConfig.events.on("eleventy.passthrough", ({ map }) => {
// for-free passthrough copy
this.setAliases(map);
});
}
}
async setOutputDir(outputDir) {
// TODO check if this is different and if so, restart server (if already running)
// This applies if you change the output directory in your config file during watch/serve
this.outputDir = outputDir;
}
getServerModule(name) {
try {
if (!name || name === DEFAULT_SERVER_OPTIONS.module) {
return require(DEFAULT_SERVER_OPTIONS.module);
}
// Look for peer dep in local project
let projectNodeModulesPath = TemplatePath.absolutePath("./node_modules/");
let serverPath = TemplatePath.absolutePath(projectNodeModulesPath, name);
// No references outside of the project node_modules are allowed
if (!serverPath.startsWith(projectNodeModulesPath)) {
throw new Error("Invalid node_modules name for Eleventy server instance, received:" + name);
}
let module = require(serverPath);
if (!("getServer" in module)) {
throw new Error(
`Eleventy server module requires a \`getServer\` static method. Could not find one on module: \`${name}\``
);
}
let serverPackageJsonPath = TemplatePath.absolutePath(serverPath, "package.json");
let serverPackageJson = require(serverPackageJsonPath);
if (serverPackageJson["11ty"] && serverPackageJson["11ty"].compatibility) {
try {
this.eleventyConfig.userConfig.versionCheck(serverPackageJson["11ty"].compatibility);
} catch (e) {
this.logger.warn(`Warning: \`${name}\` Plugin Compatibility: ${e.message}`);
}
}
return module;
} catch (e) {
this.logger.error(
"There was an error with your custom Eleventy server. Were using the default server instead.\n" +
e.message
);
debug("Eleventy server error %o", e);
return require(DEFAULT_SERVER_OPTIONS.module);
}
}
get options() {
if (this._options) {
return this._options;
}
this._options = Object.assign(
{
pathPrefix: PathPrefixer.normalizePathPrefix(this.config.pathPrefix),
logger: this.logger,
},
DEFAULT_SERVER_OPTIONS,
this.config.serverOptions
);
// TODO improve by sorting keys here
this._savedConfigOptions = JSON.stringify(this.config.serverOptions);
if (!this._initOptionsFetched && this.getSetupCallback()) {
throw new Error(
"Init options have not yet been fetched in the setup callback. This probably means that `init()` has not yet been called."
);
}
return this._options;
}
get server() {
if (this._server) {
return this._server;
}
let serverModule = this.getServerModule(this.options.module);
// Static method `getServer` was already checked in `getServerModule`
this._server = serverModule.getServer("eleventy-server", this.outputDir, this.options);
this.setAliases(this._aliases);
return this._server;
}
set server(val) {
this._server = val;
}
getSetupCallback() {
let setupCallback = this.config.serverOptions.setup;
if (setupCallback && typeof setupCallback === "function") {
return setupCallback;
}
}
async init() {
if (!this._initPromise) {
this._initPromise = new Promise(async (resolve) => {
let setupCallback = this.getSetupCallback();
if (setupCallback) {
let opts = await setupCallback();
this._initOptionsFetched = true;
if (opts) {
merge(this.options, opts);
}
}
resolve();
});
}
return this._initPromise;
}
// Port comes in here from --port on the command line
async serve(port) {
this._commandLinePort = port;
await this.init();
this.server.serve(port || this.options.port);
}
async close() {
if (this._server) {
await this.server.close();
this.server = undefined;
}
}
async sendError({ error }) {
if (this._server) {
await this.server.sendError({
error,
});
}
}
// Restart the server entirely
// We dont want to use a native `restart` method (e.g. restart() in Vite) so that
// we can correctly handle a `module` property change (changing the server type)
async restart() {
await this.close();
// saved --port in `serve()`
await this.serve(this._commandLinePort);
// rewatch the saved watched files (passthrough copy)
if ("watchFiles" in this.server) {
this.server.watchFiles(this._watchedFiles);
}
}
// checkPassthroughCopyBehavior check is called upstream in Eleventy.js
// TODO globs are not removed from watcher
watchPassthroughCopy(globs) {
this._watchedFiles = globs;
if ("watchFiles" in this.server) {
this.server.watchFiles(globs);
}
}
// Live reload the server
async reload(reloadEvent = {}) {
if (!this._server) {
return;
}
// Restart the server if the options have changed
if (JSON.stringify(this.config.serverOptions) !== this._savedConfigOptions) {
debug("Server options changed, were restarting the server");
await this.restart();
} else {
await this.server.reload(reloadEvent);
}
}
}
module.exports = EleventyServe;

View File

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

128
node_modules/@11ty/eleventy/src/EleventyWatch.js generated vendored Executable file
View File

@ -0,0 +1,128 @@
const { TemplatePath } = require("@11ty/eleventy-utils");
const PathNormalizer = require("./Util/PathNormalizer.js");
/* Decides when to watch and in what mode to watch
* Incremental builds dont batch changes, they queue.
* Nonincremental builds batch.
*/
class EleventyWatch {
constructor() {
this.incremental = false;
this.isActive = false;
this.activeQueue = [];
}
isBuildRunning() {
return this.isActive;
}
setBuildRunning() {
this.isActive = true;
// pop waiting queue into the active queue
this.activeQueue = this.popNextActiveQueue();
}
setBuildFinished() {
this.isActive = false;
this.activeQueue = [];
}
getIncrementalFile() {
if (this.incremental) {
return this.activeQueue.length ? this.activeQueue[0] : false;
}
return false;
}
/* Returns the changed files currently being operated on in the current `watch` build
* Works with or without incremental (though in incremental only one file per time will be processed)
*/
getActiveQueue() {
if (!this.isActive) {
return [];
} else if (this.incremental) {
return [this.activeQueue[0]];
}
return this.activeQueue;
}
_queueMatches(file) {
let filterCallback;
if (typeof file === "function") {
filterCallback = file;
} else {
filterCallback = (path) => path === file;
}
return this.activeQueue.filter(filterCallback);
}
hasAllQueueFiles(file) {
return (
this.activeQueue.length > 0 && this.activeQueue.length === this._queueMatches(file).length
);
}
hasQueuedFile(file) {
if (file) {
return this._queueMatches(file).length > 0;
}
return false;
}
hasQueuedFiles(files) {
for (const file of files) {
if (this.hasQueuedFile(file)) {
return true;
}
}
return false;
}
get pendingQueue() {
if (!this._queue) {
this._queue = [];
}
return this._queue;
}
set pendingQueue(value) {
this._queue = value;
}
addToPendingQueue(path) {
if (path) {
path = PathNormalizer.normalizeSeperator(TemplatePath.addLeadingDotSlash(path));
this.pendingQueue.push(path);
}
}
getPendingQueueSize() {
return this.pendingQueue.length;
}
getPendingQueue() {
return this.pendingQueue;
}
getActiveQueueSize() {
return this.activeQueue.length;
}
// returns array
popNextActiveQueue() {
if (this.incremental) {
return this.pendingQueue.length ? [this.pendingQueue.shift()] : [];
}
let ret = this.pendingQueue.slice();
this.pendingQueue = [];
return ret;
}
}
module.exports = EleventyWatch;

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

@ -0,0 +1,155 @@
const { TemplatePath } = require("@11ty/eleventy-utils");
const { DepGraph } = require("dependency-graph");
const deleteRequireCache = require("./Util/DeleteRequireCache");
const JavaScriptDependencies = require("./Util/JavaScriptDependencies");
class EleventyWatchTargets {
constructor() {
this.targets = new Set();
this.dependencies = new Set();
this.newTargets = new Set();
this._watchJavaScriptDependencies = true;
this.graph = new DepGraph();
}
set watchJavaScriptDependencies(watch) {
this._watchJavaScriptDependencies = !!watch;
}
get watchJavaScriptDependencies() {
return this._watchJavaScriptDependencies;
}
isJavaScriptDependency(path) {
return this.dependencies.has(path);
}
reset() {
this.newTargets = new Set();
}
isWatched(target) {
return this.targets.has(target);
}
addToDependencyGraph(parent, deps) {
if (!this.graph.hasNode(parent)) {
this.graph.addNode(parent);
}
for (let dep of deps) {
if (!this.graph.hasNode(dep)) {
this.graph.addNode(dep);
}
this.graph.addDependency(parent, dep);
}
}
uses(parent, dep) {
return this.getDependenciesOf(parent).includes(dep);
}
getDependenciesOf(parent) {
if (!this.graph.hasNode(parent)) {
return [];
}
return this.graph.dependenciesOf(parent);
}
getDependantsOf(child) {
if (!this.graph.hasNode(child)) {
return [];
}
return this.graph.dependantsOf(child);
}
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);
}
}
}
static normalize(targets) {
if (!targets) {
return [];
} else if (Array.isArray(targets)) {
return targets;
}
return [targets];
}
// add only a target
add(targets) {
this.addRaw(EleventyWatchTargets.normalize(targets));
}
static normalizeToGlobs(targets) {
return EleventyWatchTargets.normalize(targets).map((entry) =>
TemplatePath.convertToRecursiveGlobSync(entry)
);
}
addAndMakeGlob(targets) {
this.addRaw(EleventyWatchTargets.normalizeToGlobs(targets));
}
// add only a targets dependencies
addDependencies(targets, filterCallback) {
if (!this.watchJavaScriptDependencies) {
return;
}
targets = EleventyWatchTargets.normalize(targets);
let deps = JavaScriptDependencies.getDependencies(targets);
if (filterCallback) {
deps = deps.filter(filterCallback);
}
for (let target of targets) {
this.addToDependencyGraph(target, deps);
}
this.addRaw(deps, true);
}
setWriter(templateWriter) {
this.writer = templateWriter;
}
clearRequireCacheFor(filePathArray) {
for (const filePath of filePathArray) {
deleteRequireCache(filePath);
// Delete from require cache so that updates to the module are re-required
let importsTheChangedFile = this.getDependantsOf(filePath);
for (let dep of importsTheChangedFile) {
deleteRequireCache(dep);
}
let isImportedInTheChangedFile = this.getDependenciesOf(filePath);
for (let dep of isImportedInTheChangedFile) {
deleteRequireCache(dep);
}
}
}
getNewTargetsSinceLastReset() {
return Array.from(this.newTargets);
}
getTargets() {
return Array.from(this.targets);
}
}
module.exports = EleventyWatchTargets;

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

@ -0,0 +1,299 @@
const TemplateEngine = require("./TemplateEngine");
const getJavaScriptData = require("../Util/GetJavaScriptData");
const eventBus = require("../EventBus.js");
let lastModifiedFile = undefined;
eventBus.on("eleventy.resourceModified", (path) => {
lastModifiedFile = path;
});
class CustomEngine extends TemplateEngine {
constructor(name, dirs, config) {
super(name, dirs, config);
this.entry = this.getExtensionMapEntry();
this.needsInit =
"init" in this.entry && typeof this.entry.init === "function";
this._defaultEngine = undefined;
// Enable cacheability for this template
if (this.entry.compileOptions && "cache" in this.entry.compileOptions) {
this.cacheable = this.entry.compileOptions.cache;
} else if (this.needsToReadFileContents()) {
this.cacheable = true;
}
}
getExtensionMapEntry() {
if ("extensionMap" in this.config) {
// Iterates over only the user config `addExtension` entries
for (let entry of this.config.extensionMap) {
if (entry.key.toLowerCase() === this.name.toLowerCase()) {
return entry;
}
}
}
throw Error(
`Could not find a custom extension for ${this.name}. Did you add it to your config file?`
);
}
setDefaultEngine(defaultEngine) {
this._defaultEngine = defaultEngine;
}
/**
* @override
*/
needsToReadFileContents() {
if ("read" in this.entry) {
return this.entry.read;
}
// Handle aliases to `11ty.js` templates, avoid reading files in the alias, see #2279
// Here, we are short circuiting fallback to defaultRenderer, does not account for compile
// functions that call defaultRenderer explicitly
if (
this._defaultEngine &&
"needsToReadFileContents" in this._defaultEngine
) {
return this._defaultEngine.needsToReadFileContents();
}
return true;
}
// If we init from multiple places, wait for the first init to finish before continuing on.
async _runningInit() {
if (this.needsInit) {
if (!this._initing) {
this._initBench = this.benchmarks.aggregate.get(
`Engine (${this.name}) Init`
);
this._initBench.before();
this._initing = this.entry.init.bind({
config: this.config,
bench: this.benchmarks.aggregate,
})();
}
await this._initing;
this.needsInit = false;
if (this._initBench) {
this._initBench.after();
this._initBench = undefined;
}
}
}
async getExtraDataFromFile(inputPath) {
if (this.entry.getData === false) {
return;
}
if (!("getData" in this.entry)) {
// Handle aliases to `11ty.js` templates, use upstream default engine data fetch, see #2279
if (
this._defaultEngine &&
"getExtraDataFromFile" in this._defaultEngine
) {
return this._defaultEngine.getExtraDataFromFile(inputPath);
}
return;
}
await this._runningInit();
if (typeof this.entry.getData === "function") {
let dataBench = this.benchmarks.aggregate.get(
`Engine (${this.name}) Get Data From File (Function)`
);
dataBench.before();
let data = this.entry.getData(inputPath);
dataBench.after();
return data;
}
// if getData is not false or a function then `getInstanceFromInputPath` must exist
if (!("getInstanceFromInputPath" in this.entry)) {
return Promise.reject(
new Error(
`getInstanceFromInputPath callback missing from ${this.name} template engine plugin.`
)
);
}
let keys = new Set();
if (this.entry.getData === true) {
keys.add("data");
} else if (Array.isArray(this.entry.getData)) {
for (let key of this.entry.getData) {
keys.add(key);
}
}
let dataBench = this.benchmarks.aggregate.get(
`Engine (${this.name}) Get Data From File`
);
dataBench.before();
let inst = await this.entry.getInstanceFromInputPath(inputPath);
// override keys set at the plugin level in the individual template
if (inst.eleventyDataKey) {
keys = new Set(inst.eleventyDataKey);
}
let mixins;
if (this.config) {
// Object.assign usage: see TemplateRenderCustomTest.js: `JavaScript functions should not be mutable but not *that* mutable`
mixins = Object.assign({}, this.config.javascriptFunctions);
}
let promises = [];
for (let key of keys) {
promises.push(
getJavaScriptData(inst, inputPath, key, {
mixins,
isObjectRequired: key === "data",
})
);
}
let results = await Promise.all(promises);
let data = {};
for (let result of results) {
Object.assign(data, result);
}
dataBench.after();
return data;
}
async compile(str, inputPath, ...args) {
await this._runningInit();
let defaultRenderer;
if (this._defaultEngine) {
defaultRenderer = async (data) => {
const render = await this._defaultEngine.compile(
str,
inputPath,
...args
);
return render(data);
};
}
// Fall back to default compiler if the user does not provide their own
if (!this.entry.compile && defaultRenderer) {
return defaultRenderer;
}
// TODO generalize this (look at JavaScript.js)
let fn = this.entry.compile.bind({
config: this.config,
addDependencies: (from, toArray = []) => {
this.config.uses.addDependency(from, toArray);
},
defaultRenderer, // bind defaultRenderer to compile function
})(str, inputPath);
// Support `undefined` to skip compile/render
if (fn) {
// Bind defaultRenderer to render function
if ("then" in fn && typeof fn.then === "function") {
// Promise, wait to bind
return fn.then((fn) => {
if (typeof fn === "function") {
return fn.bind({ defaultRenderer });
}
return fn;
});
} else if ("bind" in fn && typeof fn.bind === "function") {
return fn.bind({ defaultRenderer });
}
}
return fn;
}
get defaultTemplateFileExtension() {
return this.entry.outputFileExtension;
}
hasDependencies(inputPath) {
if (this.config.uses.getDependencies(inputPath) === false) {
return false;
}
return true;
}
isFileRelevantTo(inputPath, comparisonFile, includeLayouts) {
return this.config.uses.isFileRelevantTo(
inputPath,
comparisonFile,
includeLayouts
);
}
getCompileCacheKey(str, inputPath) {
// Return this separately so we know whether or not to use the cached version
// but still return a key to cache this new render for next time
let useCache = !this.isFileRelevantTo(inputPath, lastModifiedFile, false);
if (
this.entry.compileOptions &&
"getCacheKey" in this.entry.compileOptions
) {
if (typeof this.entry.compileOptions.getCacheKey !== "function") {
throw new Error(
`\`compileOptions.getCacheKey\` must be a function in addExtension for the ${this.name} type`
);
}
return {
useCache,
key: this.entry.compileOptions.getCacheKey(str, inputPath),
};
}
let { key } = super.getCompileCacheKey(str, inputPath);
return {
useCache,
key,
};
}
permalinkNeedsCompilation(str) {
if (this.entry.compileOptions && "permalink" in this.entry.compileOptions) {
let p = this.entry.compileOptions.permalink;
if (p === "raw") {
return false;
}
// permalink: false is aliased to permalink: () => false
if (p === false) {
return () => false;
}
return this.entry.compileOptions.permalink;
}
return true;
}
static shouldSpiderJavaScriptDependencies(entry) {
if (
entry.compileOptions &&
"spiderJavaScriptDependencies" in entry.compileOptions
) {
return entry.compileOptions.spiderJavaScriptDependencies;
}
return false;
}
}
module.exports = CustomEngine;

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

@ -0,0 +1,55 @@
const ejsLib = require("ejs");
const TemplateEngine = require("./TemplateEngine");
class Ejs extends TemplateEngine {
constructor(name, dirs, config) {
super(name, dirs, config);
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") {
options.filename = inputPath;
}
let fn = this.ejsLib.compile(str, options);
return function (data) {
return fn(data);
};
}
}
module.exports = Ejs;

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

@ -0,0 +1,21 @@
const HamlLib = require("hamljs");
const TemplateEngine = require("./TemplateEngine");
class Haml extends TemplateEngine {
constructor(name, dirs, config) {
super(name, dirs, config);
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;

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

@ -0,0 +1,73 @@
const HandlebarsLib = require("handlebars");
const TemplateEngine = require("./TemplateEngine");
class Handlebars extends TemplateEngine {
constructor(name, dirs, config) {
super(name, dirs, config);
this.setLibrary(this.config.libraryOverrides.hbs);
}
setLibrary(lib) {
this.handlebarsLib = lib || HandlebarsLib;
this.setEngineLib(this.handlebarsLib);
// 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) {
// We dont need to wrap helpers for `page` or `eleventy`, this is provided for free by Handlebars
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.call(this, content, ...args);
});
}
}
/**
* @override
*/
async cachePartialFiles() {
let ret = await super.cachePartialFiles();
this.handlebarsLib.registerPartial(ret.partials);
return ret;
}
async compile(str) {
// Ensure partials are cached and registered.
await this.getPartials();
let fn = this.handlebarsLib.compile(str);
return function (data) {
return fn(data);
};
}
}
module.exports = Handlebars;

Some files were not shown because too many files have changed in this diff Show More