diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 3ce54d182..198559d16 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,10 +1,10 @@
contact_links:
- - name: I have a question about Eleventy
- url: https://github.com/11ty/eleventy/discussions/
- about: General education topics should be filed on our Discussions board e.g. “How do I do this in Eleventy?” or “Can Eleventy do this?” (Please search existing discussions first!)
- - name: I have a feature request for Eleventy
- url: https://github.com/11ty/eleventy/discussions/new?category=enhancement-queue
- about: Enhancement or new Features. e.g. “I wish Eleventy did this.” Suggest an idea! (Please search existing discussions first!)
+ - name: I have a question
+ url: https://github.com/11ty/buildawesome/discussions/
+ about: General education topics should be filed on our Discussions board e.g. “How do I do this?” or “Can I do this?” (Please search existing discussions first!)
+ - name: I have a feature request
+ url: https://github.com/11ty/buildawesome/discussions/new?category=enhancement-queue
+ about: Enhancement or new Features. Suggest an idea! (Please search existing discussions first!)
- name: I wish the docs were different!
url: https://github.com/11ty/11ty-website/issues/new/choose
about: Something missing from the documentation? Something wrong? Something confusing? You want the 11ty-website repo!
diff --git a/.github/ISSUE_TEMPLATE/possible-bug.yml b/.github/ISSUE_TEMPLATE/possible-bug.yml
index bd00a9ffc..5af95c6f7 100644
--- a/.github/ISSUE_TEMPLATE/possible-bug.yml
+++ b/.github/ISSUE_TEMPLATE/possible-bug.yml
@@ -1,4 +1,4 @@
-name: I’m having trouble with Eleventy
+name: I’m having trouble with Build Awesome or Eleventy
description: Have a problem? It might be a bug! Create a report to help us improve.
labels: [needs-triage]
body:
@@ -22,8 +22,8 @@ body:
id: eleventy
attributes:
label: Eleventy
- description: Which version of Eleventy do you use?
- placeholder: eleventy --version or npx @11ty/eleventy --version
+ description: Which version of Build Awesome or Eleventy do you use?
+ placeholder: npx @awesome.me/buildawesome --version or npx @11ty/eleventy --version
validations:
required: true
- type: textarea
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a55ecffdc..ac165fa38 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -33,6 +33,6 @@ jobs:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npx playwright install
- - run: npm run test:client
+ - run: npm run test:browser
env:
YARN_GPG: no
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index b99bf0379..fc6a77e6f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -5,7 +5,7 @@ on:
permissions: read-all
jobs:
release:
- # see https://github.com/11ty/eleventy/settings/environments
+ # see https://github.com/11ty/buildawesome/settings/environments
environment: GitHub Publish
runs-on: ubuntu-latest
permissions:
diff --git a/.gitignore b/.gitignore
index 6b7069445..daacd780e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,7 +17,7 @@ api-docs/
.vscode
.idea
-# Ignore eleventy output when doing manual tests
+# Ignore build output when doing manual tests
_site/
# Ignore test files
diff --git a/.npmignore b/.npmignore
index 7bfc930d2..8f05265bb 100644
--- a/.npmignore
+++ b/.npmignore
@@ -5,4 +5,6 @@ test_node
coverage
eslint.config.js
.*
-packages/client/
+packages/browser/
+scripts
+tsconfig.json
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index 318db5786..6f3ebd5e1 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,4 +1,4 @@
-# Eleventy Community Code of Conduct
+# Build Awesome (Eleventy) Community Code of Conduct
View the [Code of Conduct](https://www.11ty.dev/docs/code-of-conduct/) on 11ty.dev
@@ -36,7 +36,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
## 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.
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at maintainers@11ty.dev. 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.
diff --git a/README.md b/README.md
index 725fdbb33..593dc9c4a 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-
+
-# eleventy 🕚⚡️🎈🐀
+# Build Awesome (Eleventy) 🕚⚡️🎈🐀
A simpler static site generator. An alternative to Jekyll. Written in JavaScript. Transforms a directory of templates (of varying types) into HTML.
@@ -8,7 +8,7 @@ Works with HTML, Markdown, JavaScript, Liquid, Nunjucks, with addons for WebC, S
## ➡ [Documentation](https://www.11ty.dev/docs/)
-- Star [this repo on GitHub](https://github.com/11ty/eleventy/)!
+- Star [this repo on GitHub](https://github.com/11ty/buildawesome/)!
- Follow us [on Mastodon `@11ty@neighborhood.11ty.dev`](https://neighborhood.11ty.dev/@11ty)
- Follow us [on Bluesky `@11ty.dev`](https://bsky.app/profile/11ty.dev)
- Install [from npm](https://www.npmjs.com/org/11ty)
@@ -20,6 +20,9 @@ Works with HTML, Markdown, JavaScript, Liquid, Nunjucks, with addons for WebC, S
## Installation
```
+npm install @awesome.me/buildawesome --save-dev
+
+# Backwards compatible here too:
npm install @11ty/eleventy --save-dev
```
@@ -35,18 +38,18 @@ We have a few test suites, for various reasons:
- [ava JavaScript test runner](https://github.com/avajs/ava) ([assertions docs](https://github.com/avajs/ava/blob/main/docs/03-assertions.md)) (primary test suite in `test/`)
- [Node.js Test runner](https://nodejs.org/api/test.html) (secondary test suite in `test_node/`)
-- [Vitest (in Browser Mode)](https://vitest.dev/guide/browser/) (client tests in `packages/client/test/`)
-- [Benchmark for Performance Regressions](https://github.com/11ty/eleventy-benchmark)
+- [Vitest (in Browser Mode)](https://vitest.dev/guide/browser/) (browser tests in `packages/browser/test/`)
+- [Benchmark for Performance Regressions](https://github.com/11ty/buildbenchmark)
These run in various environments:
-- [Continuous Integration on GitHub Actions](https://github.com/11ty/eleventy/actions/workflows/ci.yml)
-- [Code Coverage Statistics](https://github.com/11ty/eleventy/blob/master/docs/coverage.md)
+- [Continuous Integration on GitHub Actions](https://github.com/11ty/buildawesome/actions/workflows/ci.yml)
+- [Code Coverage Statistics](https://github.com/11ty/buildawesome/blob/master/docs/coverage.md)
## Community Roadmap
-- [Top Feature Requests](https://github.com/11ty/eleventy/discussions/categories/enhancement-queue?discussions_q=is%3Aopen+category%3A%22Enhancement+Queue%22+sort%3Atop) (Vote for your favorites!)
-- [Top Bugs 😱](https://github.com/11ty/eleventy/issues?q=is%3Aissue+is%3Aopen+label%3Abug+sort%3Areactions) (Add your own votes using the 👍 reaction)
+- [Top Feature Requests](https://github.com/11ty/buildawesome/discussions/categories/enhancement-queue?discussions_q=is%3Aopen+category%3A%22Enhancement+Queue%22+sort%3Atop) (Vote for your favorites!)
+- [Top Bugs 😱](https://github.com/11ty/buildawesome/issues?q=is%3Aissue+is%3Aopen+label%3Abug+sort%3Areactions) (Add your own votes using the 👍 reaction)
## Plugins
diff --git a/SECURITY.md b/SECURITY.md
index 0947081a6..670a96d43 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -2,7 +2,7 @@
## Reporting a Vulnerability
-Privately report a security issue by navigating to https://github.com/11ty/eleventy/security and using the “Report a vulnerability” button.
+Privately report a security issue by navigating to https://github.com/11ty/buildawesome/security and using the “Report a vulnerability” button.
Read more at: https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability
diff --git a/cmd.cjs b/cmd.cjs
index 654ecdb50..b45992cf2 100755
--- a/cmd.cjs
+++ b/cmd.cjs
@@ -7,11 +7,11 @@ const pkg = require("./package.json");
require("@11ty/node-version-check")(pkg, {
message: function (requiredVersion) {
return (
- "Eleventy " +
+ "Build Awesome (Eleventy) " +
pkg.version +
" requires Node " +
requiredVersion +
- ". You will need to upgrade Node to use Eleventy!"
+ ". You will need to upgrade Node!"
);
},
});
@@ -26,23 +26,31 @@ class SimpleError extends Error {
}
async function exec() {
- const { createDebug } = await import("obug");
- const debug = createDebug("Eleventy:cmd");
+ const { createDebug } = await import("./src/Util/DebugLogUtil.js");
+ const debug = createDebug("CLI");
- // Notes about friendly error messaging with outdated Node versions: https://github.com/11ty/eleventy/issues/3761
- const { EleventyErrorHandler } = await import("./src/Errors/EleventyErrorHandler.js");
+ // Notes about friendly error messaging with outdated Node versions: https://github.com/11ty/buildawesome/issues/3761
+ const { ErrorHandler } = await import("./src/Errors/ErrorHandler.js");
+ const { getEnvValue } = await import("./src/Util/EnvironmentVars.cjs");
+ const { default: ConsoleLogger } = await import("./src/Util/ConsoleLogger.js");
// Defensive use of Node 22.8+ Module Compile Cache
- if(!process.env?.ELEVENTY_SKIP_NODE_COMPILE_CACHE) {
+ if(!getEnvValue("SKIP_NODE_COMPILE_CACHE")) {
try {
const nodeMod = await import('node:module').then(mod => mod.default);
nodeMod.enableCompileCache?.();
} catch(e) {
- debug("Node compile cache error (optional API) %o", e);
+ debug("Node compile cache error (ignored: optional API) %o", e);
}
}
try {
+ function getFallbackErrorHandler() {
+ let handler = new ErrorHandler();
+ handler.logger = new ConsoleLogger();
+ return handler;
+ }
+
const argv = minimist(process.argv.slice(2), {
string: ["input", "output", "formats", "config", "pathprefix", "port", "to", "incremental", "loader"],
boolean: [
@@ -66,30 +74,30 @@ async function exec() {
},
});
- debug("command: eleventy %o", argv);
- const { Eleventy } = await import("./src/Eleventy.js");
+ debug("Arguments: %o", argv);
+ const { default: Core } = await import("./src/Core.js");
- let ErrorHandler = new EleventyErrorHandler();
+ let handler = getFallbackErrorHandler();
process.on("unhandledRejection", (error, promise) => {
- ErrorHandler.fatal(error, "Unhandled rejection in promise");
+ handler.fatal(error, "Unhandled rejection in promise");
});
process.on("uncaughtException", (error) => {
- ErrorHandler.fatal(error, "Uncaught exception");
+ handler.fatal(error, "Uncaught exception");
});
process.on("rejectionHandled", (promise) => {
- ErrorHandler.warn(promise, "A promise rejection was handled asynchronously");
+ handler.warn(promise, "A promise rejection was handled asynchronously");
});
if (argv.version) {
- console.log(Eleventy.getVersion());
+ console.log(Core.getVersion());
return;
} else if (argv.help) {
- console.log(Eleventy.getHelp());
+ console.log(Core.getHelp());
return;
}
- let elev = new Eleventy(argv.input, argv.output, {
+ let core = new Core(argv.input, argv.output, {
source: "cli",
// --quiet and --quiet=true both resolve to true
quietMode: argv.quiet,
@@ -100,29 +108,29 @@ async function exec() {
loader: argv.loader,
});
- // reuse ErrorHandler instance in Eleventy
- ErrorHandler = elev.errorHandler;
+ // override with ErrorHandler instance in Core
+ handler = core.errorHandler;
// Before init
- elev.setFormats(argv.formats);
+ core.setFormats(argv.formats);
- await elev.init();
+ await core.init();
if (argv.to === "json") {
// override logging output
- elev.setIsVerbose(false);
+ core.setIsVerbose(false);
}
// Only relevant for watch/serve
- elev.setIgnoreInitial(argv["ignore-initial"]);
+ core.setIgnoreInitial(argv["ignore-initial"]);
// v4.0.0-alpha.8 multiple now supported via:
// --incremental=one.md --incremental=two.md => ["one.md", "two.md"]
// --incremental=one.md,two.md => ["one.md", "two.md"]
if(argv.incremental) {
- elev.setIncrementalFiles(argv.incremental);
+ core.setIncrementalFiles(argv.incremental);
} else if(argv.incremental !== undefined) {
- elev.setIncrementalBuild(argv.incremental === "" || argv.incremental);
+ core.setIncrementalBuild(argv.incremental === "" || argv.incremental);
}
if (argv.serve || argv.watch) {
@@ -130,25 +138,25 @@ async function exec() {
throw new SimpleError("--to=json is not compatible with --serve or --watch.");
}
- await elev.watch();
+ await core.watch();
if (argv.serve) {
// TODO await here?
- elev.serve(argv.port);
+ core.serve(argv.port);
}
process.on("SIGINT", async () => {
- elev.interrupt();
+ core.interrupt();
- await elev.stopWatch();
+ await core.stopWatch();
process.exitCode = 0;
});
} else {
// `fs:templates` will skip passthrough copy
if (!argv.to || argv.to === "fs" || argv.to.startsWith("fs:")) {
- await elev.write(argv.to);
+ await core.write(argv.to);
} else if (argv.to === "json") {
- let result = await elev.toJSON()
+ let result = await core.toJSON()
console.log(JSON.stringify(result, null, 2));
} else {
throw new SimpleError(
@@ -157,9 +165,9 @@ async function exec() {
}
}
} catch (error) {
- if(typeof EleventyErrorHandler !== "undefined") {
- let ErrorHandler = new EleventyErrorHandler();
- ErrorHandler.fatal(error, "Eleventy Fatal Error (CLI)");
+ if(typeof ErrorHandler !== "undefined") {
+ let handler = getFallbackErrorHandler();
+ handler.fatal(error, "Fatal Error (CLI)");
} else {
console.error(error);
process.exitCode = 1;
diff --git a/docs/ba-11ty-logo.png b/docs/ba-11ty-logo.png
new file mode 100644
index 000000000..156568d84
Binary files /dev/null and b/docs/ba-11ty-logo.png differ
diff --git a/docs/coverage.njk b/docs/coverage.njk
index f2aa72313..254cd9468 100644
--- a/docs/coverage.njk
+++ b/docs/coverage.njk
@@ -1,7 +1,7 @@
---
permalink: coverage.md
---
-# Code Coverage for Eleventy v{{ pkg.version }}
+# Code Coverage for Build Awesome v{{ pkg.version }}
| Filename | % Lines | % Statements | % Functions | % Branches |
| --- | --- | --- | --- | --- |
diff --git a/docs/eleventy.coverage.js b/docs/eleventy.coverage.js
index ae7cd17a9..0e170b893 100644
--- a/docs/eleventy.coverage.js
+++ b/docs/eleventy.coverage.js
@@ -4,8 +4,8 @@ import { TemplatePath } from "@11ty/eleventy-utils";
const __dirname = dirname(fileURLToPath(import.meta.url));
-export default function (eleventyConfig) {
- eleventyConfig.addFilter("removeDir", function (str) {
+export default function (config) {
+ config.addFilter("removeDir", function (str) {
return TemplatePath.stripLeadingSubPath(str, TemplatePath.join(__dirname, ".."));
});
diff --git a/docs/release-instructions.md b/docs/release-instructions.md
index 88054a3f6..fa9dd1854 100644
--- a/docs/release-instructions.md
+++ b/docs/release-instructions.md
@@ -26,11 +26,11 @@
1. Check it all in and commit
1. Tag new version
1. Wait for GitHub Actions to complete to know that the build did not fail.
-1. Publish a release on GitHub at https://github.com/11ty/eleventy/releases pointing to the tag of the release. Hitting the publish button on this workflow will use GitHub Actions to publish the package to npm on the correct dist-tag and includes npm package provenance for the release.
+1. Publish a release on GitHub at https://github.com/11ty/buildawesome/releases pointing to the tag of the release. Hitting the publish button on this workflow will use GitHub Actions to publish the package to npm on the correct dist-tag and includes npm package provenance for the release.
- Main release: no version suffix publishes to `latest` (default) tag on npm
- Make sure to include OpenCollective usernames for release notes here https://www.11ty.dev/supporters-for-release-notes/
-- Canary release: `-alpha.` version suffix in `package.json` publishes to `canary` tag on npm: https://github.com/11ty/eleventy/issues/2758
+- Canary release: `-alpha.` version suffix in `package.json` publishes to `canary` tag on npm: https://github.com/11ty/buildawesome/issues/2758
- Beta release: `-beta.` version suffix publishes to `beta` tag on npm
Unfortunate note about npm and tags (specifically `canary` here): if you push a 1.0.0-canary.x to `canary` (even though `2.0.0-canary.x` exists), it will use the last pushed tag when you npm install from `@canary` (not the highest version number)
diff --git a/package-lock.json b/package-lock.json
index 69976c333..d9338bf06 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,21 +1,22 @@
{
"name": "@11ty/eleventy",
- "version": "4.0.0-alpha.7",
+ "version": "4.0.0-alpha.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@11ty/eleventy",
- "version": "4.0.0-alpha.7",
+ "version": "4.0.0-alpha.8",
"license": "MIT",
"workspaces": [
- "packages/client"
+ "packages/browser",
+ "packages/build-awesome"
],
"dependencies": {
"@11ty/dependency-tree": "^4.0.2",
"@11ty/dependency-tree-esm": "^2.0.4",
"@11ty/dependency-tree-typescript": "^1.0.0",
- "@11ty/eleventy-dev-server": "^3.0.0-alpha.8",
+ "@11ty/eleventy-dev-server": "^3.0.0-alpha.10",
"@11ty/eleventy-plugin-bundle": "^3.0.7",
"@11ty/eleventy-utils": "^2.0.7",
"@11ty/gray-matter": "^2.0.2",
@@ -42,7 +43,7 @@
"picomatch": "^4.0.4",
"posthtml": "^0.16.7",
"posthtml-match-helper": "^2.0.3",
- "semver": "^7.8.1",
+ "semver": "^7.8.4",
"tinyglobby": "^0.2.17"
},
"bin": {
@@ -57,7 +58,7 @@
"@iarna/toml": "^2.2.5",
"@mdx-js/node-loader": "^3.1.1",
"@stylistic/eslint-plugin": "^5.10.0",
- "@types/node": "^25.9.1",
+ "@types/node": "^25.9.3",
"@vue/server-renderer": "^3.5.35",
"@zachleat/noop": "^1.0.7",
"ava": "^6.4.1",
@@ -72,14 +73,14 @@
"markdown-it-emoji": "^3.0.0",
"marked": "^17.0.6",
"nano-staged": "^0.9.0",
- "prettier": "^3.8.3",
+ "prettier": "^3.8.4",
"pretty": "^2.0.0",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"sass": "^1.100.0",
"simple-git-hooks": "^2.13.1",
"tsx": "^4.22.4",
- "typescript": "6.0.2",
+ "typescript": "6.0.3",
"vue": "^3.5.35",
"zod": "^4.4.3",
"zod-validation-error": "^5.0.0"
@@ -93,7 +94,7 @@
}
},
"node_modules/@11ty/client": {
- "resolved": "packages/client",
+ "resolved": "packages/browser",
"link": true
},
"node_modules/@11ty/dependency-tree": {
@@ -131,10 +132,14 @@
"node": ">=18"
}
},
+ "node_modules/@11ty/eleventy": {
+ "resolved": "",
+ "link": true
+ },
"node_modules/@11ty/eleventy-dev-server": {
- "version": "3.0.0-alpha.8",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-dev-server/-/eleventy-dev-server-3.0.0-alpha.8.tgz",
- "integrity": "sha512-DcMfE8Ca/kAlwFjkpT37PQFmdzzVQnt6eBt3yZzgIadBf7Dt5tAcW3t5uSr2TPYyAEEXh4Aq/dZNPWrEb8JWVQ==",
+ "version": "3.0.0-alpha.10",
+ "resolved": "https://registry.npmjs.org/@11ty/eleventy-dev-server/-/eleventy-dev-server-3.0.0-alpha.10.tgz",
+ "integrity": "sha512-/3bR71s1Wgavp6wmTWPSEmVbNIawnaZiushHIPMuq9vVUKwJtegmY9C1TTPD2Z/Z1IHzuft/QNlZxEnKzXJttw==",
"license": "MIT",
"dependencies": {
"@11ty/eleventy-utils": "^2.0.7",
@@ -146,15 +151,14 @@
"minimist": "^1.2.8",
"morphdom": "^2.7.8",
"send": "^1.2.1",
- "ssri": "^13.0.1",
"urlpattern-polyfill": "^10.1.0",
- "ws": "^8.20.0"
+ "ws": "^8.21.0"
},
"bin": {
"eleventy-dev-server": "cmd.cjs"
},
"engines": {
- "node": ">=20.19"
+ "node": ">=22.15"
},
"funding": {
"type": "opencollective",
@@ -455,6 +459,10 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
+ "node_modules/@awesome.me/buildawesome": {
+ "resolved": "packages/build-awesome",
+ "link": true
+ },
"node_modules/@babel/helper-string-parser": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
@@ -2686,9 +2694,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -2706,9 +2711,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -2726,9 +2728,6 @@
"ppc64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -2746,9 +2745,6 @@
"s390x"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -2766,9 +2762,6 @@
"x64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -2786,9 +2779,6 @@
"x64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -3125,9 +3115,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "25.9.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz",
- "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==",
+ "version": "25.9.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.3.tgz",
+ "integrity": "sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5458,10 +5448,13 @@
}
},
"node_modules/fdir": {
- "version": "6.4.6",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
- "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
"peerDependencies": {
"picomatch": "^3 || ^4"
},
@@ -6854,9 +6847,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -6878,9 +6868,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -6902,9 +6889,6 @@
"x64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -6926,9 +6910,6 @@
"x64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -8226,6 +8207,7 @@
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
"integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
+ "dev": true,
"license": "BlueOak-1.0.0",
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -9060,9 +9042,9 @@
}
},
"node_modules/prettier": {
- "version": "3.8.3",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz",
- "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==",
+ "version": "3.8.4",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.4.tgz",
+ "integrity": "sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==",
"dev": true,
"license": "MIT",
"bin": {
@@ -9544,9 +9526,9 @@
}
},
"node_modules/semver": {
- "version": "7.8.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz",
- "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==",
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz",
+ "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -9795,18 +9777,6 @@
"dev": true,
"license": "BSD-3-Clause"
},
- "node_modules/ssri": {
- "version": "13.0.1",
- "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz",
- "integrity": "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==",
- "license": "ISC",
- "dependencies": {
- "minipass": "^7.0.3"
- },
- "engines": {
- "node": "^20.17.0 || >=22.9.0"
- }
- },
"node_modules/stack-utils": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
@@ -10343,9 +10313,9 @@
}
},
"node_modules/typescript": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz",
- "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==",
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
+ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -11248,7 +11218,7 @@
"url": "https://github.com/sponsors/wooorm"
}
},
- "packages/client": {
+ "packages/browser": {
"name": "@11ty/client",
"version": "PRIVATE",
"license": "MIT",
@@ -11263,6 +11233,21 @@
"type": "opencollective",
"url": "https://opencollective.com/11ty"
}
+ },
+ "packages/build-awesome": {
+ "name": "@awesome.me/buildawesome",
+ "version": "PRIVATE",
+ "license": "MIT",
+ "dependencies": {
+ "@11ty/eleventy": "file:../../"
+ },
+ "bin": {
+ "buildawesome": "cmd.js"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/11ty"
+ }
}
}
}
diff --git a/package.json b/package.json
index 107c724cf..fe3aa319b 100644
--- a/package.json
+++ b/package.json
@@ -1,22 +1,23 @@
{
"name": "@11ty/eleventy",
- "version": "4.0.0-alpha.7",
- "description": "A simpler static site generator.",
+ "version": "4.0.0-alpha.8",
+ "description": "A simpler way to build awesome web sites.",
"publishConfig": {
"access": "public",
"provenance": true
},
"type": "module",
- "main": "./src/Eleventy.js",
+ "main": "./src/Core.js",
"exports": {
".": {
- "import": "./src/Eleventy.js",
- "require": "./src/EleventyCommonJs.cjs"
+ "import": "./src/Core.js",
+ "require": "./src/RequireEsmFeatureTest.cjs"
},
"./UserConfig": {
"types": "./src/UserConfig.js"
},
- "./utils/git": "./src/Util/Git.js"
+ "./utils/git": "./src/Util/Git.js",
+ "./cli": "./cmd.cjs"
},
"bin": {
"eleventy": "cmd.cjs"
@@ -26,7 +27,8 @@
"node": ">=22.15"
},
"workspaces": [
- "packages/client"
+ "packages/browser",
+ "packages/build-awesome"
],
"funding": {
"type": "opencollective",
@@ -52,11 +54,11 @@
],
"scripts": {
"default": "npm run test",
- "test": "npm run test:server && npm run test:client",
+ "test": "npm run test:server && npm run test:browser",
"test:server": "npm run test:node && npm run test:ava",
"test:ava": "ava --verbose --timeout 20s",
"test:node": "node --test 'test_node/**/*test.js'",
- "test:client": "cross-env CI=true npm run test --workspaces",
+ "test:browser": "cross-env CI=true npm run test --workspaces",
"format": "prettier . --write",
"check": "eslint src",
"check-types": "tsc",
@@ -67,9 +69,9 @@
"author": "Zach Leatherman (https://zachleat.com/)",
"repository": {
"type": "git",
- "url": "git+https://github.com/11ty/eleventy.git"
+ "url": "git+https://github.com/11ty/buildawesome.git"
},
- "bugs": "https://github.com/11ty/eleventy/issues",
+ "bugs": "https://github.com/11ty/buildawesome/issues",
"homepage": "https://www.11ty.dev/",
"ava": {
"environmentVariables": {},
@@ -104,7 +106,7 @@
"@iarna/toml": "^2.2.5",
"@mdx-js/node-loader": "^3.1.1",
"@stylistic/eslint-plugin": "^5.10.0",
- "@types/node": "^25.9.1",
+ "@types/node": "^25.9.3",
"@vue/server-renderer": "^3.5.35",
"@zachleat/noop": "^1.0.7",
"ava": "^6.4.1",
@@ -119,14 +121,14 @@
"markdown-it-emoji": "^3.0.0",
"marked": "^17.0.6",
"nano-staged": "^0.9.0",
- "prettier": "^3.8.3",
+ "prettier": "^3.8.4",
"pretty": "^2.0.0",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"sass": "^1.100.0",
"simple-git-hooks": "^2.13.1",
"tsx": "^4.22.4",
- "typescript": "6.0.2",
+ "typescript": "6.0.3",
"vue": "^3.5.35",
"zod": "^4.4.3",
"zod-validation-error": "^5.0.0"
@@ -135,7 +137,7 @@
"@11ty/dependency-tree": "^4.0.2",
"@11ty/dependency-tree-esm": "^2.0.4",
"@11ty/dependency-tree-typescript": "^1.0.0",
- "@11ty/eleventy-dev-server": "^3.0.0-alpha.8",
+ "@11ty/eleventy-dev-server": "^3.0.0-alpha.10",
"@11ty/eleventy-plugin-bundle": "^3.0.7",
"@11ty/eleventy-utils": "^2.0.7",
"@11ty/gray-matter": "^2.0.2",
@@ -162,10 +164,7 @@
"picomatch": "^4.0.4",
"posthtml": "^0.16.7",
"posthtml-match-helper": "^2.0.3",
- "semver": "^7.8.1",
+ "semver": "^7.8.4",
"tinyglobby": "^0.2.17"
- },
- "overrides": {
- "fdir": "6.4.6"
}
}
diff --git a/packages/client/README.md b/packages/browser/README.md
similarity index 94%
rename from packages/client/README.md
rename to packages/browser/README.md
index e8e21c338..b63b484b8 100644
--- a/packages/client/README.md
+++ b/packages/browser/README.md
@@ -6,7 +6,7 @@ The client (browser-friendly) version of `@11ty/eleventy` Eleventy, a simpler st
## ➡ [Documentation](https://www.11ty.dev/docs/)
-- Star [this repo on GitHub](https://github.com/11ty/eleventy/)!
+- Star [this repo on GitHub](https://github.com/11ty/buildawesome/)!
- Follow us [on Mastodon `@11ty@neighborhood.11ty.dev`](https://neighborhood.11ty.dev/@11ty)
- Follow us [on Bluesky `@11ty.dev`](https://bsky.app/profile/11ty.dev)
- Install [from npm](https://www.npmjs.com/org/11ty)
diff --git a/packages/browser/generate-bundle.js b/packages/browser/generate-bundle.js
new file mode 100644
index 000000000..94ca86348
--- /dev/null
+++ b/packages/browser/generate-bundle.js
@@ -0,0 +1,71 @@
+import fs from "node:fs";
+import chalk from "kleur";
+import { default as bundleClient } from "@11ty/package-bundler";
+
+import pkg from "../../package.json" with { type: "json" };
+import { readableFileSize } from "../../src/Util/FileSize.js";
+
+const PREFIX = chalk.dim(`[11ty/bundle/client] `);
+
+function size(filepath) {
+ return readableFileSize(fs.statSync(filepath).size);
+}
+
+await bundleClient("./src/BundleCoreMinimal.js", "./dist/core-minimal.js", {
+ name: `Eleventy (Build Awesome) v${pkg.version} (@11ty/client Bundle)`,
+ moduleRoot: "../../",
+ // No core-bundled plugins, reduced feature set
+ adapterSuffixes: [".client.js", ".core.js", ".core.cjs"],
+ external: ["node:fs", "node:crypto", "@sindresorhus/slugify"],
+ esbuild: {
+ keepNames: false,
+ // minify: true
+ },
+});
+
+console.log(`${PREFIX}Wrote dist/core-minimal.js: ${size("./dist/core-minimal.js")}`);
+
+// Careful, this one is big!
+await bundleClient("./src/BundleCoreFs.js", `./dist/core-fs.js`, {
+ name: `Eleventy (Build Awesome) v${pkg.version} (@11ty/client/core-fs Bundle)`,
+ moduleRoot: "../../",
+ adapterSuffixes: [".core.js", ".core.cjs"],
+ // Adds named export FileSystem for using the file system in other packages
+ fileSystemMode: "publish",
+});
+console.log(`${PREFIX}Wrote dist/core-fs.js: ${size("./dist/core-fs.js")}`);
+
+// fs.mkdirSync("./visualize/", { recursive: true });
+// fs.writeFileSync("./visualize/meta.json", JSON.stringify(result.metafile));
+// npx esbuild-visualizer --metadata ./packages/browser/visualize/meta.json --filename packages/browser/visualize/index.html
+
+await bundleClient(import.meta.resolve("./src/BundleLiquid.js"), `./dist/formats/liquid.js`, {
+ name: `Eleventy (Build Awesome) v${pkg.version} (@11ty/client/liquid Engine Bundle)`,
+ moduleRoot: "../../",
+ adapterSuffixes: [".core.js", ".core.cjs"],
+});
+console.log(`${PREFIX}Wrote dist/formats/liquid.js: ${size("./dist/formats/liquid.js")}`);
+
+await bundleClient(import.meta.resolve("./src/BundleNunjucks.js"), `./dist/formats/nunjucks.js`, {
+ name: `Eleventy (Build Awesome) v${pkg.version} (@11ty/client/njk Engine Bundle)`,
+ moduleRoot: "../../",
+});
+console.log(`${PREFIX}Wrote dist/formats/nunjucks.js: ${size("./dist/formats/nunjucks.js")}`);
+
+await bundleClient(import.meta.resolve("./src/BundleMarkdown.js"), `./dist/formats/markdown.js`, {
+ name: `Eleventy (Build Awesome) v${pkg.version} (@11ty/client/md Engine Bundle)`,
+ moduleRoot: "../../",
+ adapterSuffixes: [".core.js", ".core.cjs"],
+});
+console.log(`${PREFIX}Wrote dist/formats/markdown.js: ${size("./dist/formats/markdown.js")}`);
+
+await bundleClient(
+ import.meta.resolve("./src/BundleI18nPlugin.js"),
+ `./dist/plugins/plugin-i18n.js`,
+ {
+ name: `Eleventy (Build Awesome) v${pkg.version} (i18n Plugin)`,
+ moduleRoot: "../../",
+ adapterSuffixes: [".core.js", ".core.cjs"],
+ },
+);
+console.log(`${PREFIX}Wrote dist/plugins/plugin-i18n.js: ${size("./dist/plugins/plugin-i18n.js")}`);
diff --git a/packages/client/package.json b/packages/browser/package.json
similarity index 63%
rename from packages/client/package.json
rename to packages/browser/package.json
index 19848ac8e..610386eb8 100644
--- a/packages/client/package.json
+++ b/packages/browser/package.json
@@ -1,6 +1,6 @@
{
"name": "@11ty/client",
- "description": "Run Eleventy in your browser.",
+ "description": "Run Build Awesome (Eleventy) in your browser.",
"version": "PRIVATE",
"private": true,
"publishConfig": {
@@ -8,14 +8,14 @@
"provenance": true
},
"type": "module",
- "main": "./dist/eleventy.core.js",
+ "main": "./dist/core-minimal.js",
"exports": {
- ".": "./dist/eleventy.core.js",
- "./eleventy": "./dist/eleventy.js",
- "./liquid": "./dist/formats/eleventy-liquid.js",
- "./njk": "./dist/formats/eleventy-nunjucks.js",
- "./md": "./dist/formats/eleventy-markdown.js",
- "./i18n": "./dist/plugins/eleventy-plugin-i18n.js"
+ ".": "./dist/core-minimal.js",
+ "./core-fs": "./dist/core-fs.js",
+ "./liquid": "./dist/formats/liquid.js",
+ "./njk": "./dist/formats/nunjucks.js",
+ "./md": "./dist/formats/markdown.js",
+ "./i18n": "./dist/plugins/plugin-i18n.js"
},
"files": [
"./dist/**/*.js"
@@ -33,9 +33,9 @@
"author": "Zach Leatherman (https://zachleat.com/)",
"repository": {
"type": "git",
- "url": "git://github.com/11ty/eleventy.git"
+ "url": "git://github.com/11ty/buildawesome.git"
},
- "bugs": "https://github.com/11ty/eleventy/issues",
+ "bugs": "https://github.com/11ty/buildawesome/issues",
"homepage": "https://www.11ty.dev/",
"devDependencies": {
"@11ty/package-bundler": "^0.5.6",
diff --git a/packages/client/src/BundleEleventy.js b/packages/browser/src/BundleCoreFs.js
similarity index 92%
rename from packages/client/src/BundleEleventy.js
rename to packages/browser/src/BundleCoreFs.js
index bce949294..64f20690b 100644
--- a/packages/client/src/BundleEleventy.js
+++ b/packages/browser/src/BundleCoreFs.js
@@ -12,6 +12,6 @@ export { default as RenderPlugin } from "../../../src/Plugins/RenderPlugin.js";
// - Extended configuration was removed from defaultConfig.js
// This saved ~400KB (unmin) from the bundle but the separate bundle was way larger than the savings (> 1MB)
-export { Core as Eleventy } from "../../../src/Core.js";
+export { CoreFs as Eleventy, CoreFs as BuildAwesome } from "../../../src/CoreFs.js";
export { default as FileSystem } from "node:fs";
diff --git a/packages/client/src/BundleCore.js b/packages/browser/src/BundleCoreMinimal.js
similarity index 50%
rename from packages/client/src/BundleCore.js
rename to packages/browser/src/BundleCoreMinimal.js
index 07f3e1324..28944e25f 100644
--- a/packages/client/src/BundleCore.js
+++ b/packages/browser/src/BundleCoreMinimal.js
@@ -1,4 +1,4 @@
// see BundleEleventy.js for Core WITH bundled Eleventy core plugins
import "./shims/shim-core.js";
-export { MinimalCore as Eleventy } from "../../../src/CoreMinimal.js";
+export { CoreMinimal as Eleventy, CoreMinimal as BuildAwesome } from "../../../src/CoreMinimal.js";
diff --git a/packages/client/src/BundleI18nPlugin.js b/packages/browser/src/BundleI18nPlugin.js
similarity index 100%
rename from packages/client/src/BundleI18nPlugin.js
rename to packages/browser/src/BundleI18nPlugin.js
diff --git a/packages/client/src/BundleLiquid.js b/packages/browser/src/BundleLiquid.js
similarity index 100%
rename from packages/client/src/BundleLiquid.js
rename to packages/browser/src/BundleLiquid.js
diff --git a/packages/client/src/BundleMarkdown.js b/packages/browser/src/BundleMarkdown.js
similarity index 100%
rename from packages/client/src/BundleMarkdown.js
rename to packages/browser/src/BundleMarkdown.js
diff --git a/packages/client/src/BundleNunjucks.js b/packages/browser/src/BundleNunjucks.js
similarity index 100%
rename from packages/client/src/BundleNunjucks.js
rename to packages/browser/src/BundleNunjucks.js
diff --git a/packages/client/src/shims/process.cjs b/packages/browser/src/shims/process.cjs
similarity index 100%
rename from packages/client/src/shims/process.cjs
rename to packages/browser/src/shims/process.cjs
diff --git a/packages/client/src/shims/shim-core.js b/packages/browser/src/shims/shim-core.js
similarity index 79%
rename from packages/client/src/shims/shim-core.js
rename to packages/browser/src/shims/shim-core.js
index f4feb1164..705030bde 100644
--- a/packages/client/src/shims/shim-core.js
+++ b/packages/browser/src/shims/shim-core.js
@@ -3,10 +3,10 @@ import * as process from "./process.cjs";
// `path` polyfill needs this
window.process = globalThis.process = process;
-// `recursive-copy` needs this (not necessary for Core.js)
+// `recursive-copy` needs this (not necessary for CoreFs.js)
window.global = globalThis || window;
-// @11ty/eleventy needs this
+// Core needs this
class Buffer {
static [Symbol.hasInstance](instance) {
return this.isBuffer(instance);
diff --git a/packages/browser/test/client-core-fs.test.js b/packages/browser/test/client-core-fs.test.js
new file mode 100644
index 000000000..c42dc3382
--- /dev/null
+++ b/packages/browser/test/client-core-fs.test.js
@@ -0,0 +1,4 @@
+import { BuildAwesome } from "../dist/core-fs.js";
+import sharedTests from "./shared-tests.js";
+
+sharedTests(BuildAwesome);
diff --git a/packages/browser/test/client-core.test.js b/packages/browser/test/client-core.test.js
new file mode 100644
index 000000000..a833590f8
--- /dev/null
+++ b/packages/browser/test/client-core.test.js
@@ -0,0 +1,4 @@
+import { BuildAwesome } from "../dist/core-minimal.js";
+import sharedTests from "./shared-tests.js";
+
+sharedTests(BuildAwesome);
diff --git a/packages/browser/test/shared-tests.js b/packages/browser/test/shared-tests.js
new file mode 100644
index 000000000..aad82b91e
--- /dev/null
+++ b/packages/browser/test/shared-tests.js
@@ -0,0 +1,119 @@
+import { assert, test } from "vitest";
+import { Markdown } from "../dist/formats/markdown.js";
+import { Liquid } from "../dist/formats/liquid.js";
+import { Nunjucks } from "../dist/formats/nunjucks.js";
+import { I18nPlugin } from "../dist/plugins/plugin-i18n.js";
+
+export default function(BuildAwesome) {
+ test("Get version number", async () => {
+ assert.typeOf(BuildAwesome.getVersion(), "string");
+ });
+
+ test("Markdown (no preprocessor) template", async () => {
+ let ba = new BuildAwesome({
+ config(configApi) {
+ configApi.addEngine("md", Markdown);
+ configApi.setMarkdownTemplateEngine(false);
+ configApi.setHtmlTemplateEngine(false);
+ configApi.setTemplateFormats("md");
+ configApi.addTemplate("index.md", `# Heading`);
+
+ }
+ });
+
+ let json = await ba.toJSON();
+ assert.strictEqual(json[0].content.trim(), `Heading `);
+ });
+
+ test("Markdown (via Liquid) template", async () => {
+ let ba = new BuildAwesome({
+ config(configApi) {
+ configApi.addEngine("md", Markdown);
+ configApi.addEngine("liquid", Liquid);
+ configApi.setTemplateFormats("md");
+ configApi.addTemplate("index.md", `# {{ title }}`, {
+ title: "Heading"
+ });
+
+ }
+ });
+
+ let json = await ba.toJSON();
+ assert.strictEqual(json[0].content.trim(), `Heading `);
+ });
+
+ test("Liquid template", async () => {
+ let ba = new BuildAwesome({
+ config(configApi) {
+ configApi.addEngine("liquid", Liquid);
+ configApi.setTemplateFormats("liquid");
+ configApi.addTemplate("index.liquid", `{{ title }} `, { title: "Heading" });
+ }
+ });
+
+ let json = await ba.toJSON();
+ assert.strictEqual(json[0].content.trim(), `Heading `);
+ });
+
+ test("Nunjucks template", async () => {
+ let ba = new BuildAwesome({
+ config(configApi) {
+ configApi.addEngine("njk", Nunjucks);
+ configApi.setTemplateFormats("njk");
+ configApi.addTemplate("index.njk", `{{ title }} `, { title: "Heading" });
+
+ }
+ });
+
+ let json = await ba.toJSON();
+ assert.strictEqual(json[0].content.trim(), `Heading `);
+ });
+
+ test("i18n Plugin Use (with 11ty.js)", async () => {
+ let ba = new BuildAwesome({
+ config(configApi) {
+ configApi.addPlugin(I18nPlugin, {
+ defaultLanguage: "en"
+ });
+ configApi.addTemplate("./en/index.11ty.js", function (data) {
+ return `Home `;
+ });
+ configApi.addTemplate("./es/index.11ty.js", function (data) {
+ return `Home `;
+ });
+ }
+ });
+
+ let json = await ba.toJSON();
+ assert.strictEqual(json[0].content.trim(), `Home `);
+ assert.strictEqual(json[1].content.trim(), `Home `);
+ });
+
+ // Careful, `@11ty/client` will resolve slugify via Vite instead of it bundled with the package
+ test("slugify Filter in Liquid", async () => {
+ let ba = new BuildAwesome({
+ config(configApi) {
+ configApi.addEngine("liquid", Liquid);
+ configApi.setTemplateFormats("liquid");
+ configApi.addTemplate("index.liquid", `{{ title | slugify }}`, { title: "This is a heading" });
+ }
+ });
+
+ let json = await ba.toJSON();
+ assert.strictEqual(json[0].content.trim(), `this-is-a-heading`);
+ });
+
+ // Careful, `@11ty/client` will resolve slugify via Vite instead of it bundled with the package
+ test("slugify Filter in Nunjucks", async () => {
+ let ba = new BuildAwesome({
+ config(configApi) {
+ configApi.addEngine("njk", Nunjucks);
+ configApi.setTemplateFormats("njk");
+ configApi.addTemplate("index.njk", `{{ title | slugify }}`, { title: "This is a heading" });
+ }
+ });
+
+ let json = await ba.toJSON();
+ assert.strictEqual(json[0].content.trim(), `this-is-a-heading`);
+ });
+}
diff --git a/packages/client/update-package-json.js b/packages/browser/update-package-json.js
similarity index 68%
rename from packages/client/update-package-json.js
rename to packages/browser/update-package-json.js
index 60983e0c8..b2d7a0c09 100644
--- a/packages/client/update-package-json.js
+++ b/packages/browser/update-package-json.js
@@ -12,10 +12,12 @@ delete clientPkg.private; // allow publish
if (
corePkg.name !== "@11ty/eleventy" ||
clientPkg.name !== "@11ty/client" ||
- !fs.existsSync("./packages/client/package.json")
+ !fs.existsSync("./packages/browser/package.json")
) {
- throw new Error("Did you run this script from the wrong directory?");
+ throw new Error(
+ "Did you run this script from the wrong directory? (Should be the repository root)",
+ );
}
-fs.writeFileSync("./packages/client/package.json", JSON.stringify(clientPkg, null, 2), "utf8");
+fs.writeFileSync("./packages/browser/package.json", JSON.stringify(clientPkg, null, 2), "utf8");
console.log(`[11ty/bundle/client] Updated @11ty/client package version to ${corePkg.version}`);
diff --git a/packages/client/vitest.config.js b/packages/browser/vitest.config.js
similarity index 100%
rename from packages/client/vitest.config.js
rename to packages/browser/vitest.config.js
diff --git a/packages/build-awesome/cmd.js b/packages/build-awesome/cmd.js
new file mode 100755
index 000000000..2779d3e83
--- /dev/null
+++ b/packages/build-awesome/cmd.js
@@ -0,0 +1,6 @@
+#!/usr/bin/env node
+
+// Influences console and DEBUG log prefixes
+process.env.BUILDAWESOME_PACKAGE = "@awesome.me/buildawesome";
+
+import "@11ty/eleventy/cli";
diff --git a/packages/build-awesome/package.json b/packages/build-awesome/package.json
new file mode 100644
index 000000000..afe22c01d
--- /dev/null
+++ b/packages/build-awesome/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "@awesome.me/buildawesome",
+ "description": "A simpler way to build awesome web sites.",
+ "version": "PRIVATE",
+ "private": true,
+ "publishConfig": {
+ "access": "public",
+ "provenance": true
+ },
+ "type": "module",
+ "exports": {
+ ".": "./src/Core.js",
+ "./UserConfig": {
+ "types": "./src/UserConfig.d.ts"
+ },
+ "./utils/git": "./src/Util/Git.js"
+ },
+ "scripts": {
+ "test": ""
+ },
+ "bin": {
+ "buildawesome": "cmd.js"
+ },
+ "license": "MIT",
+ "author": "Zach Leatherman (https://zachleat.com/)",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/11ty/buildawesome.git"
+ },
+ "bugs": "https://github.com/11ty/buildawesome/issues",
+ "homepage": "https://build.awesome.me/",
+ "dependencies": {
+ "@11ty/eleventy": "file:../../"
+ }
+}
diff --git a/packages/build-awesome/src/Core.js b/packages/build-awesome/src/Core.js
new file mode 100644
index 000000000..d25348ca7
--- /dev/null
+++ b/packages/build-awesome/src/Core.js
@@ -0,0 +1,2 @@
+export * from "@11ty/eleventy";
+export { default } from "@11ty/eleventy";
diff --git a/packages/build-awesome/src/UserConfig.d.ts b/packages/build-awesome/src/UserConfig.d.ts
new file mode 100644
index 000000000..2e9156f3e
--- /dev/null
+++ b/packages/build-awesome/src/UserConfig.d.ts
@@ -0,0 +1,4 @@
+// No named exports
+// export * from "@11ty/eleventy/UserConfig";
+
+export { default } from "@11ty/eleventy/UserConfig";
diff --git a/packages/build-awesome/src/Util/Git.js b/packages/build-awesome/src/Util/Git.js
new file mode 100644
index 000000000..ca8d9d98f
--- /dev/null
+++ b/packages/build-awesome/src/Util/Git.js
@@ -0,0 +1,4 @@
+// Named exports only
+
+export * from "@11ty/eleventy/git";
+// export { default } from "@11ty/eleventy/git";
diff --git a/packages/build-awesome/update-package-json.js b/packages/build-awesome/update-package-json.js
new file mode 100644
index 000000000..b2274922b
--- /dev/null
+++ b/packages/build-awesome/update-package-json.js
@@ -0,0 +1,30 @@
+// Intended to run from repository root in release.sh script
+
+import fs from "node:fs";
+import corePkg from "../../package.json" with { type: "json" };
+
+// assign new version in local package.json from core package.json
+import buildawesomePkg from "./package.json" with { type: "json" };
+
+buildawesomePkg.version = corePkg.version;
+buildawesomePkg.dependencies[corePkg.name] = corePkg.version;
+delete buildawesomePkg.private; // allow publish
+
+if (
+ corePkg.name !== "@11ty/eleventy" ||
+ buildawesomePkg.name !== "@awesome.me/buildawesome" ||
+ !fs.existsSync("./packages/build-awesome/package.json")
+) {
+ throw new Error(
+ "Did you run this script from the wrong directory? (Should be the repository root)",
+ );
+}
+
+fs.writeFileSync(
+ "./packages/build-awesome/package.json",
+ JSON.stringify(buildawesomePkg, null, 2),
+ "utf8",
+);
+console.log(
+ `[awesome.me/buildawesome] Updated @awesome.me/buildawesome package version to ${corePkg.version}`,
+);
diff --git a/packages/client/generate-bundle.js b/packages/client/generate-bundle.js
deleted file mode 100644
index 5d04aefa0..000000000
--- a/packages/client/generate-bundle.js
+++ /dev/null
@@ -1,90 +0,0 @@
-import fs from "node:fs";
-import { default as bundleClient } from "@11ty/package-bundler";
-
-import pkg from "../../package.json" with { type: "json" };
-import { readableFileSize } from "../../src/Util/FileSize.js";
-
-const PREFIX = `[11ty/bundle/client] `;
-
-function size(filepath) {
- return readableFileSize(fs.statSync(filepath).size);
-}
-
-await bundleClient("./src/BundleCore.js", "./dist/eleventy.core.js", {
- name: `Eleventy v${pkg.version} (@11ty/client Bundle)`,
- moduleRoot: "../../",
- // No core-bundled plugins, reduced feature set
- adapterSuffixes: [".client.js", ".core.js", ".core.cjs"],
- external: ["node:fs", "node:crypto", "@sindresorhus/slugify"],
- esbuild: {
- keepNames: false,
- // minify: true
- },
-});
-
-console.log(`${PREFIX}Wrote dist/eleventy.core.js: ${size("./dist/eleventy.core.js")}`);
-
-// Careful, this one is big!
-await bundleClient("./src/BundleEleventy.js", `./dist/eleventy.js`, {
- name: `Eleventy v${pkg.version} (@11ty/client/eleventy Bundle)`,
- moduleRoot: "../../",
- adapterSuffixes: [".core.js", ".core.cjs"],
- // Adds named export FileSystem for using the file system in other packages
- fileSystemMode: "publish",
-});
-console.log(`${PREFIX}Wrote dist/eleventy.js: ${size("./dist/eleventy.js")}`);
-
-// fs.mkdirSync("./visualize/", { recursive: true });
-// fs.writeFileSync("./visualize/meta.json", JSON.stringify(result.metafile));
-// npx esbuild-visualizer --metadata ./packages/client/visualize/meta.json --filename packages/client/visualize/index.html
-
-await bundleClient(
- import.meta.resolve("./src/BundleLiquid.js"),
- `./dist/formats/eleventy-liquid.js`,
- {
- name: `Eleventy v${pkg.version} (@11ty/client/liquid Engine Bundle)`,
- moduleRoot: "../../",
- adapterSuffixes: [".core.js", ".core.cjs"],
- },
-);
-console.log(
- `${PREFIX}Wrote dist/formats/eleventy-liquid.js: ${size("./dist/formats/eleventy-liquid.js")}`,
-);
-
-await bundleClient(
- import.meta.resolve("./src/BundleNunjucks.js"),
- `./dist/formats/eleventy-nunjucks.js`,
- {
- name: `Eleventy v${pkg.version} (@11ty/client/njk Engine Bundle)`,
- moduleRoot: "../../",
- },
-);
-console.log(
- `${PREFIX}Wrote dist/formats/eleventy-nunjucks.js: ${size("./dist/formats/eleventy-nunjucks.js")}`,
-);
-
-await bundleClient(
- import.meta.resolve("./src/BundleMarkdown.js"),
- `./dist/formats/eleventy-markdown.js`,
- {
- name: `Eleventy v${pkg.version} (@11ty/client/md Engine Bundle)`,
- moduleRoot: "../../",
- adapterSuffixes: [".core.js", ".core.cjs"],
- },
-);
-console.log(
- `${PREFIX}Wrote dist/formats/eleventy-markdown.js: ${size("./dist/formats/eleventy-markdown.js")}`,
-);
-
-await bundleClient(
- import.meta.resolve("./src/BundleI18nPlugin.js"),
- `./dist/plugins/eleventy-plugin-i18n.js`,
- {
- name: `Eleventy v${pkg.version} (i18n Plugin)`,
- moduleRoot: "../../",
- adapterSuffixes: [".core.js", ".core.cjs"],
- },
-);
-console.log(
- `${PREFIX}Wrote dist/plugins/eleventy-plugin-i18n.js: ${size("./dist/plugins/eleventy-plugin-i18n.js")}`,
-);
diff --git a/packages/client/test/client-core.test.js b/packages/client/test/client-core.test.js
deleted file mode 100644
index 629a44b31..000000000
--- a/packages/client/test/client-core.test.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import { Eleventy } from "../dist/eleventy.core.js";
-import sharedTests from "./shared-tests.js";
-
-sharedTests(Eleventy);
diff --git a/packages/client/test/client-eleventy.test.js b/packages/client/test/client-eleventy.test.js
deleted file mode 100644
index cf70606f6..000000000
--- a/packages/client/test/client-eleventy.test.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import { Eleventy } from "../dist/eleventy.js";
-import sharedTests from "./shared-tests.js";
-
-sharedTests(Eleventy);
diff --git a/packages/client/test/shared-tests.js b/packages/client/test/shared-tests.js
deleted file mode 100644
index f59a3e9cd..000000000
--- a/packages/client/test/shared-tests.js
+++ /dev/null
@@ -1,119 +0,0 @@
-import { assert, test } from "vitest";
-import { Markdown } from "../dist/formats/eleventy-markdown.js";
-import { Liquid } from "../dist/formats/eleventy-liquid.js";
-import { Nunjucks } from "../dist/formats/eleventy-nunjucks.js";
-import { I18nPlugin } from "../dist/plugins/eleventy-plugin-i18n.js";
-
-export default function(Eleventy) {
- test("Get version number", async () => {
- assert.typeOf(Eleventy.getVersion(), "string");
- });
-
- test("Markdown (no preprocessor) template", async () => {
- let elev = new Eleventy({
- config(eleventyConfig) {
- eleventyConfig.addEngine("md", Markdown);
- eleventyConfig.setMarkdownTemplateEngine(false);
- eleventyConfig.setHtmlTemplateEngine(false);
- eleventyConfig.setTemplateFormats("md");
- eleventyConfig.addTemplate("index.md", `# Heading`);
-
- }
- });
-
- let json = await elev.toJSON();
- assert.strictEqual(json[0].content.trim(), `Heading `);
- });
-
- test("Markdown (via Liquid) template", async () => {
- let elev = new Eleventy({
- config(eleventyConfig) {
- eleventyConfig.addEngine("md", Markdown);
- eleventyConfig.addEngine("liquid", Liquid);
- eleventyConfig.setTemplateFormats("md");
- eleventyConfig.addTemplate("index.md", `# {{ title }}`, {
- title: "Heading"
- });
-
- }
- });
-
- let json = await elev.toJSON();
- assert.strictEqual(json[0].content.trim(), `Heading `);
- });
-
- test("Liquid template", async () => {
- let elev = new Eleventy({
- config(eleventyConfig) {
- eleventyConfig.addEngine("liquid", Liquid);
- eleventyConfig.setTemplateFormats("liquid");
- eleventyConfig.addTemplate("index.liquid", `{{ title }} `, { title: "Heading" });
- }
- });
-
- let json = await elev.toJSON();
- assert.strictEqual(json[0].content.trim(), `Heading `);
- });
-
- test("Nunjucks template", async () => {
- let elev = new Eleventy({
- config(eleventyConfig) {
- eleventyConfig.addEngine("njk", Nunjucks);
- eleventyConfig.setTemplateFormats("njk");
- eleventyConfig.addTemplate("index.njk", `{{ title }} `, { title: "Heading" });
-
- }
- });
-
- let json = await elev.toJSON();
- assert.strictEqual(json[0].content.trim(), `Heading `);
- });
-
- test("i18n Plugin Use (with 11ty.js)", async () => {
- let elev = new Eleventy({
- config(eleventyConfig) {
- eleventyConfig.addPlugin(I18nPlugin, {
- defaultLanguage: "en"
- });
- eleventyConfig.addTemplate("./en/index.11ty.js", function (data) {
- return `Home `;
- });
- eleventyConfig.addTemplate("./es/index.11ty.js", function (data) {
- return `Home `;
- });
- }
- });
-
- let json = await elev.toJSON();
- assert.strictEqual(json[0].content.trim(), `Home `);
- assert.strictEqual(json[1].content.trim(), `Home `);
- });
-
- // Careful, `@11ty/client` will resolve slugify via Vite instead of it bundled with the package
- test("slugify Filter in Liquid", async () => {
- let elev = new Eleventy({
- config(eleventyConfig) {
- eleventyConfig.addEngine("liquid", Liquid);
- eleventyConfig.setTemplateFormats("liquid");
- eleventyConfig.addTemplate("index.liquid", `{{ title | slugify }}`, { title: "This is a heading" });
- }
- });
-
- let json = await elev.toJSON();
- assert.strictEqual(json[0].content.trim(), `this-is-a-heading`);
- });
-
- // Careful, `@11ty/client` will resolve slugify via Vite instead of it bundled with the package
- test("slugify Filter in Nunjucks", async () => {
- let elev = new Eleventy({
- config(eleventyConfig) {
- eleventyConfig.addEngine("njk", Nunjucks);
- eleventyConfig.setTemplateFormats("njk");
- eleventyConfig.addTemplate("index.njk", `{{ title | slugify }}`, { title: "This is a heading" });
- }
- });
-
- let json = await elev.toJSON();
- assert.strictEqual(json[0].content.trim(), `this-is-a-heading`);
- });
-}
diff --git a/scripts/release-dryrun.sh b/scripts/release-dryrun.sh
index ffde53523..98d6ad7f6 100755
--- a/scripts/release-dryrun.sh
+++ b/scripts/release-dryrun.sh
@@ -1,6 +1,6 @@
export NPM_PUBLISH_TAG="canary"
export DRY_RUN="--dry-run" # leave that space as-is
-echo "Running @11ty/eleventy and @11ty/client publish dry run test"
+echo "Publishing: @11ty/eleventy, @11ty/client, @awesome.me/buildawesome publish (dry run)"
./scripts/release.sh
diff --git a/scripts/release.sh b/scripts/release.sh
index 0cc71f859..00acd8993 100755
--- a/scripts/release.sh
+++ b/scripts/release.sh
@@ -19,9 +19,10 @@ if [ -z "$NPM_PUBLISH_TAG" ]; then
exit 1
fi
-node packages/client/update-package-json.js
-# Will skip publishing root if publishing workspaces fails
-if npm publish --workspaces --provenance --access=public --tag=$NPM_PUBLISH_TAG $DRY_RUN; then
- npm publish --provenance --access=public --tag=$NPM_PUBLISH_TAG $DRY_RUN
+# Will skip publishing @11ty/client and @awesome.me/buildawesome if @11ty/eleventy fails
+if npm publish --provenance --access=public --tag=$NPM_PUBLISH_TAG $DRY_RUN; then
+ node packages/browser/update-package-json.js
+ node packages/build-awesome/update-package-json.js
+ npm publish --workspaces --provenance --access=public --tag=$NPM_PUBLISH_TAG $DRY_RUN
fi
diff --git a/src/Benchmark/BenchmarkGroup.js b/src/Benchmark/BenchmarkGroup.js
index eded8756a..fcca92335 100644
--- a/src/Benchmark/BenchmarkGroup.js
+++ b/src/Benchmark/BenchmarkGroup.js
@@ -1,24 +1,25 @@
-import { createDebug } from "obug";
-
-import ConsoleLogger from "../Util/ConsoleLogger.js";
+import { createDebug } from "../Util/DebugLogUtil.js";
import isAsyncFunction from "../Util/IsAsyncFunction.js";
import Benchmark from "./Benchmark.js";
-const debugBenchmark = createDebug("Eleventy:Benchmark");
+const debugBenchmark = createDebug("Benchmark");
class BenchmarkGroup {
constructor() {
this.benchmarks = {};
- // Warning: aggregate benchmarks automatically default to false via BenchmarkManager->getBenchmarkGroup
+
this.isVerbose = true;
- this.logger = new ConsoleLogger();
this.minimumThresholdMs = 50;
this.minimumThresholdPercent = 8;
}
+ setLogger(logger) {
+ this.logger = logger;
+ }
+
+ // This is an override for aggregate benchmarks automatically default to false via BenchmarkManager->getBenchmarkGroup
setIsVerbose(isVerbose) {
this.isVerbose = isVerbose;
- this.logger.isVerbose = isVerbose;
}
reset() {
@@ -118,7 +119,9 @@ class BenchmarkGroup {
totalForBenchmark >= this.minimumThresholdMs &&
percent > this.minimumThresholdPercent
) {
- this.logger.warn(str);
+ if (this.isVerbose) {
+ this.logger.warn(str);
+ }
}
// Opt out of logging if low count (1× or 2×) or 0ms / 1%
diff --git a/src/Benchmark/BenchmarkManager.js b/src/Benchmark/BenchmarkManager.js
index ff937bd6c..61c00334c 100644
--- a/src/Benchmark/BenchmarkManager.js
+++ b/src/Benchmark/BenchmarkManager.js
@@ -1,11 +1,8 @@
import BenchmarkGroup from "./BenchmarkGroup.js";
-// 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();
}
@@ -24,8 +21,16 @@ class BenchmarkManager {
return new Date().getTime();
}
- setVerboseOutput(isVerbose) {
- this.isVerbose = !!isVerbose;
+ setLogger(logger) {
+ if (!logger) {
+ return;
+ }
+
+ this.logger = logger;
+
+ for (let group of Object.values(this.benchmarkGroups)) {
+ group.setLogger(logger);
+ }
}
hasBenchmarkGroup(name) {
@@ -34,15 +39,18 @@ class BenchmarkManager {
getBenchmarkGroup(name) {
if (!this.benchmarkGroups[name]) {
- this.benchmarkGroups[name] = new BenchmarkGroup();
+ let group = new BenchmarkGroup();
+ if (this.logger) {
+ group.setLogger(this.logger);
+ }
// Special behavior for aggregate benchmarks
// so they don’t console.log every time
if (name === "Aggregate") {
- this.benchmarkGroups[name].setIsVerbose(false);
- } else {
- this.benchmarkGroups[name].setIsVerbose(this.isVerbose);
+ group.setIsVerbose(false);
}
+
+ this.benchmarkGroups[name] = group;
}
return this.benchmarkGroups[name];
diff --git a/src/Core.js b/src/Core.js
index fbe146ec7..788f396b8 100644
--- a/src/Core.js
+++ b/src/Core.js
@@ -1,51 +1,625 @@
-import { MinimalCore } from "./CoreMinimal.js";
-import FileSystemSearch from "./FileSystemSearch.js";
-import EleventyFiles from "./EleventyFiles.js";
-import TemplatePassthroughManager from "./TemplatePassthroughManager.js";
+import { relative } from "node:path";
+
+import { TemplatePath } from "@11ty/eleventy-utils";
+
+import { CoreFs } from "./CoreFs.js";
+import Serve from "./Serve.js";
+import { Watch } from "./Watch.js";
+import WatchQueue from "./WatchQueue.js";
+import WatchTargets from "./WatchTargets.js";
+import BaseError from "./Errors/BaseError.js";
+
+// Utils
+import { createDebug } from "./Util/DebugLogUtil.js";
+import checkPassthroughCopyBehavior from "./Util/PassthroughCopyBehaviorCheck.js";
+import PathPrefixer from "./Util/PathPrefixer.js";
+import PathNormalizer from "./Util/PathNormalizer.js";
+import { isGlobMatch } from "./Util/GlobMatcher.js";
+import eventBus from "./EventBus.js";
+
+const debug = createDebug("Core");
+
+export default class Core extends CoreFs {
+ /** @type {boolean} */
+ #isStopping = false;
+
+ /** @type {WatchQueue} */
+ #watchQueue;
+
+ #watchDelay;
+ #interrupted = false;
+
+ get watchQueue() {
+ if (!this.#watchQueue) {
+ this.#watchQueue = new WatchQueue();
+ }
+ return this.#watchQueue;
+ }
-// Core with File System support (but without Dev Server or Chokidar or Bundled Plugins)
-export class Core extends MinimalCore {
async initializeConfig(initOverrides) {
await super.initializeConfig(initOverrides);
+ // Careful to make sure the previous server closes on SIGINT, issue #3873
+ if (!this.eleventyServe) {
+ /** @type {object} */
+ this.eleventyServe = new Serve();
+ }
+
+ this.eleventyServe.logger = this.logger;
+ this.eleventyServe.eleventyConfig = this.eleventyConfig;
+
/** @type {object} */
- this.fileSystemSearch = new FileSystemSearch();
+ this.watchTargets = new WatchTargets(this.eleventyConfig);
+ this.watchTargets.add(this.config.additionalWatchTargets);
}
+ async resetConfig() {
+ await super.resetConfig();
+
+ // TODO set this.eleventyServe with this.getChokidarConfig()
+ if (checkPassthroughCopyBehavior(this.config, this.runMode)) {
+ this.eleventyServe.resetConfig();
+ }
+ }
+
+ /**
+ * Starts Eleventy.
+ */
async init(options = {}) {
await super.init(options);
- this.templateData.setFileSystemSearch(this.fileSystemSearch);
+ // eleventyServe is always available, even when not in --serve mode
+ // TODO directorynorm
+ this.eleventyServe.setOutputDir(this.outputDir);
+
+ if (checkPassthroughCopyBehavior(this.config, this.runMode)) {
+ this.eleventyServe.watchPassthroughCopy(
+ this.eleventyFiles.getGlobWatcherFilesForPassthroughCopy(),
+ );
+ }
+ }
+
+ /**
+ * @param {string} changedFilePath - File that triggered a re-run (added or modified)
+ * @param {boolean} [isResetConfig] - are we doing a config reset
+ */
+ #resetFileInWatchQueue(changedFilePath, isResetConfig) {
+ // v3.1.0: `eleventy.templateModified` is no longer used internally
+ // v4.0.0-alpha.8 `eleventy.templateModified` event removed
+
+ // These listeners are *global*, not cleared even on config reset (v4.0.0-alpha.8 removed some arguments here)
+ eventBus.emit("buildawesome.resourcemodified", changedFilePath);
+
+ this.config.events.emit("buildawesome#templatemodified", changedFilePath);
+ }
+
+ shouldTriggerConfigReset(changedFiles) {
+ // looks for all eligible config files (not just the active one, handles config file rename)
+ let configFilePaths = new Set(this.eleventyConfig.getLocalProjectConfigFiles());
- this.passthroughManager = new TemplatePassthroughManager(this.eleventyConfig);
- this.passthroughManager.setRunMode(this.runMode);
- this.passthroughManager.setDryRun(this.isDryRun);
- this.passthroughManager.extensionMap = this.extensionMap;
- this.passthroughManager.setFileSystemSearch(this.fileSystemSearch);
+ // https://www.11ty.dev/docs/watch-serve/#reset-configuration
+ let resetConfigGlobs = WatchTargets.normalizeToGlobs(
+ Array.from(this.eleventyConfig.userConfig.watchTargetsConfigReset),
+ );
+
+ for (let filePath of changedFiles) {
+ if (configFilePaths.has(filePath)) {
+ return true;
+ }
+ if (isGlobMatch(filePath, resetConfigGlobs)) {
+ return true;
+ }
+ }
+
+ for (let configFilePath of configFilePaths) {
+ // Any dependencies of the config file changed
+ let configFileDependencies = new Set(this.watchTargets.getDependenciesOf(configFilePath));
+
+ for (let filePath of changedFiles) {
+ if (configFileDependencies.has(filePath)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
- let formats = this.templateFormats.getTemplateFormats();
- this.eleventyFiles = new EleventyFiles(formats, this.eleventyConfig);
- this.eleventyFiles.setPassthroughManager(this.passthroughManager);
- this.eleventyFiles.setFileSystemSearch(this.fileSystemSearch);
- this.eleventyFiles.setRunMode(this.runMode);
- this.eleventyFiles.extensionMap = this.extensionMap;
- // This needs to be set before init or it’ll construct a new one
- this.eleventyFiles.templateData = this.templateData;
- this.eleventyFiles.init();
+ // Checks the build queue to see if any configuration related files have changed
+ #shouldResetConfig(activeQueue = []) {
+ if (!activeQueue.length) {
+ return false;
+ }
- this.writer.setPassthroughManager(this.passthroughManager);
- this.writer.setEleventyFiles(this.eleventyFiles);
+ return this.shouldTriggerConfigReset(
+ activeQueue.map((path) => {
+ return PathNormalizer.normalizeSeperator(TemplatePath.addLeadingDotSlash(path));
+ }),
+ );
+ }
+
+ async #rewatch() {
+ if (this.watchQueue.isBuildRunning()) {
+ // this.logger.forceLog("Waiting for previous build to finish…");
+ return;
+ }
+
+ this.watchQueue.startBuild();
+
+ let queue = this.watchQueue.getActiveQueue();
+ let isResetConfig = this.#shouldResetConfig(queue);
+
+ for (let p of queue) {
+ this.#resetFileInWatchQueue(p, isResetConfig);
+ }
+
+ this.logger.forceLog(
+ `Build starting${queue.length > 1 ? ` (${queue.length} queued changes)` : ""}…` +
+ (isResetConfig ? " (configuration reset)" : ""),
+ );
+
+ await this.config.events.emit("buildawesome.beforewatch", queue);
+
+ // Clear `import` cache for all files that triggered the rebuild (sync event)
+ this.watchTargets.clearImportCacheFor(queue);
+
+ // reset and reload global configuration
+ if (isResetConfig) {
+ // important: run this before config resets otherwise the handlers will disappear.
+ await this.config.events.emit("buildawesome.reset");
+ this.resetConfig();
+ }
+
+ await this.restart();
+ await this.init({ viaConfigReset: isResetConfig });
+
+ try {
+ let [passthroughCopyResults, templateResults] = await this.write();
+
+ if (isResetConfig) {
+ // make sure this happens after write()
+ await this.startWatch();
+ }
+
+ this.watchTargets.reset();
+
+ await this.#initWatchDependencies();
+
+ // Add new deps to chokidar
+ let newWatchTargets = this.watchTargets.getNewTargetsSinceLastReset();
+ this.watcher.watchTargets(newWatchTargets);
+
+ // Is a CSS input file and is not in the includes folder
+ // TODO check output path file extension of this template (not input path)
+ // TODO add additional API for this, maybe a config callback?
+ let onlyCssChanges = this.watchQueue.hasAllQueueFiles((path) => {
+ return (
+ path.endsWith(".css") &&
+ // TODO how to make this work with relative includes?
+ !TemplatePath.startsWithSubPath(path, this.eleventyFiles.getIncludesDir())
+ );
+ });
+
+ // Maps passthrough copy files to output URLs for CSS live reload
+ let stylesheetUrls = new Set();
+ for (let entry of passthroughCopyResults) {
+ for (let filepath in entry.map) {
+ if (
+ filepath.endsWith(".css") &&
+ queue.includes(TemplatePath.addLeadingDotSlash(filepath))
+ ) {
+ stylesheetUrls.add(
+ "/" + TemplatePath.stripLeadingSubPath(entry.map[filepath], this.outputDir),
+ );
+ }
+ }
+ }
+
+ let normalizedPathPrefix = PathPrefixer.normalizePathPrefix(this.config.pathPrefix);
+ let matchingTemplates = templateResults
+ .flat()
+ .filter((entry) => Boolean(entry))
+ .map((entry) => {
+ // only `url`, `inputPath`, and `content` are used: https://github.com/11ty/eleventy-dev-server/blob/1c658605f75224fdc76f68aebe7a412eeb4f1bc9/client/reload-client.js#L140
+ entry.url = PathPrefixer.joinUrlParts(normalizedPathPrefix, entry.url);
+ delete entry.rawInput; // Issue #3481
+ return entry;
+ });
+
+ await this.eleventyServe.reload({
+ files: queue,
+ subtype: onlyCssChanges ? "css" : undefined,
+ build: {
+ stylesheets: Array.from(stylesheetUrls),
+ templates: matchingTemplates,
+ },
+ });
+ } catch (error) {
+ this.eleventyServe.sendError({
+ error,
+ });
+ }
+
+ this.watchQueue.finishBuild();
+
+ // Re-fetch
+ let pendingQueue = this.watchQueue.getPendingQueue();
+ if (pendingQueue.length > 0) {
+ await this.#rewatch();
+ } else if (!this.#interrupted) {
+ // also logs in startWatch for initial build
+ this.logger.forceLog(`Waiting…`);
+ }
+ }
+
+ /*
+ * SIGINT
+ */
+ interrupt() {
+ this.#interrupted = true;
+
+ // Clear the queue to prevent additional builds
+ this.watchQueue.reset();
}
/**
- * Restarts Eleventy.
+ * @returns {module:11ty/eleventy/src/Benchmark/BenchmarkGroup~BenchmarkGroup}
*/
- async restart() {
- await super.restart();
+ get watcherBench() {
+ return this.bench.get("Watcher");
+ }
+
+ async waitThrottle() {
+ if (this.#watchDelay) {
+ clearTimeout(this.#watchDelay);
+ }
+
+ if (this.config.watchThrottleWaitTime > 0) {
+ let { promise, resolve } = Promise.withResolvers();
- // TODO
- this.passthroughManager.reset();
- // TODO
- this.eleventyFiles.restart();
+ this.#watchDelay = setTimeout(resolve, this.config.watchThrottleWaitTime);
+
+ return promise;
+ }
}
+
+ // Triggers when files are modified on file system
+ async triggerWatchRunForPath(path) {
+ this.watchQueue.addToPendingQueue(path);
+
+ await this.waitThrottle();
+
+ try {
+ await this.#rewatch();
+ } catch (e) {
+ this.watchQueue.finishBuild();
+
+ if (e instanceof BaseError) {
+ this.errorHandler.error(e, "Eleventy watch error");
+ } else {
+ this.errorHandler.fatal(e, "Eleventy fatal watch error");
+ await this.close();
+ }
+ }
+
+ // Internal event for testing
+ // v4.0.0-alpha.8 swapped to async-friendly
+ await this.config.events.emit("buildawesome.afterwatch");
+ }
+
+ /**
+ * Set up watchers and benchmarks.
+ *
+ * @async
+ * @method
+ */
+ async startWatch() {
+ if (this.projectPackageJsonPath) {
+ this.watchTargets.add([relative(TemplatePath.getWorkingDir(), this.projectPackageJsonPath)]);
+ }
+ this.watchTargets.add(this.eleventyFiles.getGlobWatcherFiles());
+ this.watchTargets.add(this.eleventyFiles.getIgnoreFiles());
+
+ // Watch the local project config file
+ this.watchTargets.add(this.eleventyConfig.getActiveConfigPath());
+
+ // Template and Directory Data Files
+ this.watchTargets.add(this.eleventyFiles.getGlobWatcherTemplateDataFiles());
+
+ let benchmark = this.watcherBench.get(
+ "Watching JavaScript Dependencies (disable with `eleventyConfig.setWatchJavaScriptDependencies(false)`)",
+ );
+ benchmark.before();
+ await this.#initWatchDependencies();
+ benchmark.after();
+
+ // Close previous watcher
+ if (this.watcher) {
+ await this.watcher.close();
+ }
+
+ // TODO improve unwatching if JS dependencies are removed (or files are deleted)
+ let { targets, ignores } = await this.getWatchedTargets();
+ debug("Watching for changes to: %o", targets);
+
+ this.watcher = new Watch(this.eleventyConfig);
+ this.watcher.watchTargets(targets);
+ this.watcher.addIgnores(ignores);
+
+ await this.watcher.start();
+
+ // This logs in #rewatch for rebuilds
+ if (this.buildCount <= 1) {
+ this.logger.forceLog("Waiting…");
+ }
+
+ this.watcher.on("change", async (path) => {
+ // Emulated passthrough copy logs from the server
+ if (!this.eleventyServe.isEmulatedPassthroughCopyMatch(path)) {
+ this.logger.forceLog(
+ `File changed: ${TemplatePath.stripLeadingDotSlash(TemplatePath.standardizeFilePath(path))}${this.watchQueue.isBuildRunning() ? " (queued for next build)" : ""}`,
+ );
+ }
+
+ // don’t await
+ this.triggerWatchRunForPath(path);
+ });
+
+ this.watcher.on("add", async (path) => {
+ // Emulated passthrough copy logs from the server
+ if (!this.eleventyServe.isEmulatedPassthroughCopyMatch(path)) {
+ this.logger.forceLog(
+ `File added: ${TemplatePath.stripLeadingDotSlash(TemplatePath.standardizeFilePath(path))}${this.watchQueue.isBuildRunning() ? " (queued for next build)" : ""}`,
+ );
+ }
+
+ this.fileSystemSearch.add(path);
+ // don’t await
+ this.triggerWatchRunForPath(path);
+ });
+
+ this.watcher.on("unlink", async (path) => {
+ // Emulated passthrough copy logs from the server
+ if (!this.eleventyServe.isEmulatedPassthroughCopyMatch(path)) {
+ this.logger.forceLog(
+ `File deleted: ${TemplatePath.stripLeadingDotSlash(TemplatePath.standardizeFilePath(path))}${this.watchQueue.isBuildRunning() ? " (queued for next build)" : ""}`,
+ );
+ }
+
+ this.fileSystemSearch.delete(path);
+ // don’t await
+ this.triggerWatchRunForPath(path);
+ });
+ }
+
+ /**
+ * Starts watching dependencies.
+ */
+ async #initWatchDependencies() {
+ if (!this.eleventyConfig.shouldSpiderJavaScriptDependencies()) {
+ return;
+ }
+
+ // Lazy resolve isEsm only for --watch
+ this.watchTargets.setProjectUsingEsm(this.isEsm);
+
+ // Template files .11ty.js
+ let templateFiles = await this.eleventyFiles.getWatchPathCache();
+ await this.watchTargets.addDependencies(templateFiles);
+
+ // TODO use DirContains
+ let dataDir = TemplatePath.stripLeadingDotSlash(this.templateData.getDataDir());
+ function filterOutGlobalDataFiles(path) {
+ return !dataDir || !TemplatePath.stripLeadingDotSlash(path).startsWith(dataDir);
+ }
+
+ // Config file dependencies
+ await this.watchTargets.addDependencies(
+ this.eleventyConfig.getActiveConfigPath(),
+ filterOutGlobalDataFiles,
+ );
+
+ // Deps from Global Data (that aren’t in the global data directory, everything is watched there)
+ let globalDataDeps = this.templateData.getWatchPathCache();
+ await this.watchTargets.addDependencies(globalDataDeps, filterOutGlobalDataFiles);
+
+ await this.watchTargets.addDependencies(
+ await this.eleventyFiles.getWatcherTemplateJavaScriptDataFiles(),
+ );
+ }
+
+ /**
+ * Returns all watched paths
+ *
+ * @async
+ * @method
+ * @returns {Object} `targets` file paths, and `ignores` globs Array
+ */
+ async getWatchedTargets() {
+ return {
+ targets: await this.watchTargets.getTargets(),
+ ignores: this.eleventyFiles.getGlobWatcherIgnores(),
+ };
+ }
+
+ /**
+ * Start watching files
+ *
+ * @async
+ * @method
+ */
+ async watch() {
+ this.watcherBench.setMinimumThresholdMs(500);
+ this.watcherBench.reset();
+
+ // Note that watching indirectly depends on this for fetching dependencies from JS files
+ // See: TemplateWriter:pathCache and WatchTargets
+ await this.write();
+
+ let initWatchBench = this.watcherBench.get("Start up --watch");
+ initWatchBench.before();
+
+ await this.startWatch();
+
+ initWatchBench.after();
+
+ this.watcherBench.finish("Watch");
+ }
+
+ // Renamed to close()
+ async stopWatch() {
+ return this.close();
+ }
+
+ async close() {
+ // Prevent multiple invocations.
+ if (this.#isStopping) {
+ return this.#isStopping;
+ }
+
+ debug("Cleaning up chokidar and server instances, if they exist.");
+ this.#isStopping = Promise.all([this.eleventyServe.close(), this.watcher?.close()]).then(() => {
+ this.#isStopping = false;
+ });
+
+ return this.#isStopping;
+ }
+
+ /**
+ * Serve Eleventy on this port.
+ *
+ * @param {Number} port - The HTTP port to serve Eleventy from.
+ */
+ async serve(port) {
+ // Port is optional and in this case likely via --port on the command line
+ // May defer to configuration API options `port` property
+ return this.eleventyServe.serve(port);
+ }
+
+ /**
+ * Shows a help message including usage.
+ *
+ * @static
+ * @returns {string} - The help message.
+ */
+ static getHelp() {
+ return `Usage: eleventy
+ eleventy --input=. --output=./_site
+ eleventy --serve
+
+Arguments:
+
+ --version
+
+ --input=.
+ Input template files (default: \`.\`)
+
+ --output=_site
+ Write HTML output to this folder (default: \`_site\`)
+
+ --serve
+ Run web server on --port (default 8080) and watch them too
+
+ --port
+ Run the --serve web server on this port (default 8080)
+
+ --watch
+ Wait for files to change and automatically rewrite (no web server)
+
+ --incremental
+ Only build the files that have changed. Best with watch/serve.
+
+ --incremental=first.md,second.md
+ --incremental=first.md --incremental=second.md
+ Does not require watch/serve. Run an incremental build targeting one or more files.
+
+ --ignore-initial
+ Start without a build; build when files change. Works best with watch/serve/incremental.
+
+ --formats=liquid,md
+ Allow only certain template types (default: \`*\`)
+
+ --quiet
+ Don’t print all written files (off by default)
+
+ --config=filename.js
+ Override the eleventy config file path (default: \`buildawesome.config.js\`)
+
+ --pathprefix='/'
+ Change all url template filters to use this subdirectory.
+
+ --dryrun
+ Don’t write any files. Useful in DEBUG mode, for example: \`DEBUG=Eleventy* npx @11ty/eleventy --dryrun\`
+
+ --loader
+ Set to "esm" to force ESM mode, "cjs" to force CommonJS mode, or "auto" (default) to infer it from package.json.
+
+ --to=json
+ Change the output to JSON (default: \`fs\`)
+
+ --to=fs:templates
+ Writes templates, skips passthrough copy
+
+ --help`;
+ }
+
+ /**
+ * @deprecated since 1.0.1, use static getHelp() instead
+ */
+ getHelp() {
+ return Core.getHelp();
+ }
+
+ /* Removed methods */
+ initWatch() {
+ throw new Error(
+ "#initWatch() was removed in v4. Use #startWatch() instead (initializes and starts the watcher)",
+ );
+ }
+ getWatchedFiles() {
+ throw new Error(
+ "#getWatchedFiles() was removed in v4. Use #getWatchedTargets().targets instead.",
+ );
+ }
+}
+
+// Named export for backwards compatibility
+export { Core as Eleventy };
+
+/* Utils */
+export { DynamicImport as ImportFile } from "./Util/Require.js";
+
+// TODO(breaking) remove these and recommend folks use package level exports e.g. "@11ty/eleventy/plugins/i18n"
+
+/* Plugins */
+export { default as BundlePlugin } from "@11ty/eleventy-plugin-bundle";
+
+// Eleventy*Plugin names are backwards-compatibility legacy names
+export {
+ default as RenderPlugin,
+ default as EleventyRenderPlugin,
+} from "./Plugins/RenderPlugin.js";
+export { default as I18nPlugin, default as EleventyI18nPlugin } from "./Plugins/I18nPlugin.js";
+export {
+ default as HtmlBasePlugin,
+ default as EleventyHtmlBasePlugin,
+} from "./Plugins/HtmlBasePlugin.js";
+export { TransformPlugin as InputPathToUrlTransformPlugin } from "./Plugins/InputPathToUrl.js";
+export { IdAttributePlugin } from "./Plugins/IdAttributePlugin.js";
+
+export { PreserveClosingTagsPlugin } from "./Plugins/PreserveClosingTagsPlugin.js";
+
+// Error messages for Removed plugins
+export function EleventyServerlessBundlerPlugin() {
+ throw new Error(
+ "Following feedback from our Community Survey, low interest in this plugin prompted its removal from core v3.0 as we refocus on static sites. Learn more: https://v3.11ty.dev/docs/plugins/serverless/",
+ );
+}
+
+export { EleventyServerlessBundlerPlugin as EleventyServerless };
+
+export function EleventyEdgePlugin() {
+ throw new Error(
+ "Following feedback from our Community Survey, low interest in this plugin prompted its removal from core v3.0 as we refocus on static sites. Learn more: https://v3.11ty.dev/docs/plugins/edge/",
+ );
}
diff --git a/src/CoreFs.js b/src/CoreFs.js
new file mode 100644
index 000000000..5bfd43ce2
--- /dev/null
+++ b/src/CoreFs.js
@@ -0,0 +1,51 @@
+import { CoreMinimal } from "./CoreMinimal.js";
+import FileSystemSearch from "./FileSystemSearch.js";
+import { Files } from "./Files.js";
+import TemplatePassthroughManager from "./TemplatePassthroughManager.js";
+
+// Core with File System support (but without Dev Server or Chokidar or Bundled Plugins)
+export class CoreFs extends CoreMinimal {
+ async initializeConfig(initOverrides) {
+ await super.initializeConfig(initOverrides);
+
+ /** @type {object} */
+ this.fileSystemSearch = new FileSystemSearch();
+ }
+
+ async init(options = {}) {
+ await super.init(options);
+
+ this.templateData.setFileSystemSearch(this.fileSystemSearch);
+
+ this.passthroughManager = new TemplatePassthroughManager(this.eleventyConfig);
+ this.passthroughManager.setRunMode(this.runMode);
+ this.passthroughManager.setDryRun(this.isDryRun);
+ this.passthroughManager.extensionMap = this.extensionMap;
+ this.passthroughManager.setFileSystemSearch(this.fileSystemSearch);
+
+ let formats = this.templateFormats.getTemplateFormats();
+ this.eleventyFiles = new Files(formats, this.eleventyConfig);
+ this.eleventyFiles.setPassthroughManager(this.passthroughManager);
+ this.eleventyFiles.setFileSystemSearch(this.fileSystemSearch);
+ this.eleventyFiles.setRunMode(this.runMode);
+ this.eleventyFiles.extensionMap = this.extensionMap;
+ // This needs to be set before init or it’ll construct a new one
+ this.eleventyFiles.templateData = this.templateData;
+ this.eleventyFiles.init();
+
+ this.writer.setPassthroughManager(this.passthroughManager);
+ this.writer.setEleventyFiles(this.eleventyFiles);
+ }
+
+ /**
+ * Restarts Eleventy.
+ */
+ async restart() {
+ await super.restart();
+
+ // TODO
+ this.passthroughManager.reset();
+ // TODO
+ this.eleventyFiles.restart();
+ }
+}
diff --git a/src/CoreMinimal.js b/src/CoreMinimal.js
index fe0aafa61..d081293c6 100644
--- a/src/CoreMinimal.js
+++ b/src/CoreMinimal.js
@@ -1,36 +1,32 @@
-import { createDebug } from "obug";
import { isPlainObject, TemplatePath } from "@11ty/eleventy-utils";
import chalk from "./Adapters/Packages/chalk.js";
import TemplateData from "./Data/TemplateData.js";
import TemplateWriter from "./TemplateWriter.js";
-import EleventyExtensionMap from "./EleventyExtensionMap.js";
-import { EleventyErrorHandler } from "./Errors/EleventyErrorHandler.js";
+import ExtensionMap from "./ExtensionMap.js";
+import { ErrorHandler } from "./Errors/ErrorHandler.js";
import TemplateConfig from "./TemplateConfig.js";
import TemplateEngineManager from "./Engines/TemplateEngineManager.js";
/* Utils */
+import { createDebug } from "./Util/DebugLogUtil.js";
import { readableFileSize } from "./Util/FileSize.js";
import simplePlural from "./Util/Pluralize.js";
import ConsoleLogger from "./Util/ConsoleLogger.js";
import ProjectDirectories from "./Util/ProjectDirectories.js";
import {
- getEleventyPackageJson,
+ getCorePackageJson,
importJsonSync,
getWorkingProjectPackageJsonPath,
} from "./Util/ImportJsonSync.js";
import ProjectTemplateFormats from "./Util/ProjectTemplateFormats.js";
+import { setEnvValue } from "./Util/EnvironmentVars.cjs";
-const pkg = getEleventyPackageJson();
-const debug = createDebug("Eleventy");
+const pkg = getCorePackageJson();
+const debug = createDebug("Core");
-/**
- * Eleventy’s programmatic API
- * @module 11ty/eleventy/Eleventy
- */
-
-export class MinimalCore {
+export class CoreMinimal {
/**
* Userspace package.json file contents
* @type {object|undefined}
@@ -56,7 +52,7 @@ export class MinimalCore {
#needsInit = true;
/** @type {Promise|undefined} */
#initPromise;
- /** @type {EleventyErrorHandler|undefined} */
+ /** @type {ErrorHandler|undefined} */
#errorHandler;
/** @type {Map} */
#privateCaches = new Map();
@@ -93,7 +89,7 @@ export class MinimalCore {
}
/**
- * @typedef {object} EleventyOptions
+ * @typedef {object} BuildAwesomeOptions
* @property {'cli'|'script'=} source
* @property {'build'|'serve'|'watch'=} runMode
* @property {boolean=} dryRun
@@ -105,7 +101,7 @@ export class MinimalCore {
* @param {string} [input] - Directory or filename for input/sources files.
* @param {string} [output] - Directory serving as the target for writing the output files.
- * @param {EleventyOptions} [options={}]
+ * @param {BuildAwesomeOptions} [options={}]
* @param {TemplateConfig} [eleventyConfig]
*/
constructor(...args) {
@@ -135,8 +131,8 @@ export class MinimalCore {
this.eleventyConfig = eleventyConfig;
/**
- * @type {EleventyOptions}
- * @description Options object passed to the Eleventy constructor
+ * @type {BuildAwesomeOptions}
+ * @description Options object passed to the constructor
* @default {}
*/
this.options = options;
@@ -232,10 +228,24 @@ export class MinimalCore {
}
/**
- * @deprecated since 1.0.1, use static Eleventy.getVersion()
+ * @deprecated since 1.0.1, use static getVersion()
*/
getVersion() {
- return MinimalCore.getVersion();
+ return CoreMinimal.getVersion();
+ }
+
+ isUsingBuildAwesome() {
+ if (typeof this.#activeConfigurationPath !== "string") {
+ return;
+ }
+
+ if (
+ process?.env?.BUILDAWESOME_PACKAGE === "@awesome.me/buildawesome" ||
+ this.#activeConfigurationPath.includes("buildawesome.config")
+ ) {
+ return true;
+ }
+ return false;
}
async initializeConfig(initOverrides) {
@@ -248,6 +258,10 @@ export class MinimalCore {
this.#activeConfigurationPath =
this.configPath ?? this.eleventyConfig.getLocalProjectConfigFile();
+ if (this.isUsingBuildAwesome()) {
+ this.logger.setPrefix(`[buildawesome]`);
+ }
+
this.eleventyConfig.setRunMode(this.runMode);
this.eleventyConfig.setProjectUsingEsm(this.isEsm);
this.eleventyConfig.setLogger(this.logger);
@@ -274,7 +288,7 @@ export class MinimalCore {
/* Programmatic API config */
if (this.options.config && typeof this.options.config === "function") {
- debug("Running options.config configuration callback (passed to Eleventy constructor)");
+ debug("Running options.config configuration callback (passed to constructor)");
// TODO use return object here?
await this.options.config(this.eleventyConfig.userConfig);
}
@@ -293,7 +307,7 @@ export class MinimalCore {
/**
* @type {object}
- * @description Initialize Eleventy’s configuration, including the user config file
+ * @description Initialize configuration, including the user config file
*/
this.config = this.eleventyConfig.getConfig();
@@ -302,6 +316,7 @@ export class MinimalCore {
* @description Singleton BenchmarkManager instance
*/
this.bench = this.config.benchmarkManager;
+ this.bench.setLogger(this.logger);
if (performance) {
debug("Eleventy warm up time: %o (ms)", performance.now());
@@ -353,7 +368,7 @@ export class MinimalCore {
// Not used internally, removed in 3.0.
setInputDir() {
throw new Error(
- "Eleventy->setInputDir was removed in 3.0. Use the inputDir option to the constructor",
+ "The setInputDir method was removed in 3.0. Use the inputDir option passed to the constructor.",
);
}
@@ -363,9 +378,9 @@ export class MinimalCore {
}
/**
- * Updates the dry-run mode of Eleventy.
+ * Updates the dry-run mode (whether or not to write files).
*
- * @param {boolean} isDryRun - Shall Eleventy run in dry mode?
+ * @param {boolean} isDryRun - Shall we run in dry mode?
*/
setDryRun(isDryRun) {
this.isDryRun = !!isDryRun;
@@ -374,7 +389,7 @@ export class MinimalCore {
/**
* Sets the incremental build mode.
*
- * @param {boolean} isIncremental - Shall Eleventy run in incremental build mode and only write the files that trigger watch updates
+ * @param {boolean} isIncremental - Shall we run in incremental build mode and only write the files that trigger watch updates
*/
setIncrementalBuild(isIncremental) {
this.isIncremental = Boolean(isIncremental);
@@ -407,9 +422,6 @@ export class MinimalCore {
}
}
- /**
- * Restarts Eleventy.
- */
async restart() {
debug("Restarting.");
this.start = this.getNewTimestamp();
@@ -439,9 +451,6 @@ export class MinimalCore {
}
}
- /**
- * Starts Eleventy.
- */
async init(options = {}) {
let { viaConfigReset } = Object.assign({ viaConfigReset: false }, options);
if (!this.#hasConfigInitialized) {
@@ -451,18 +460,18 @@ export class MinimalCore {
this.config.events.reset();
}
- await this.config.events.emit("eleventy.config", this.eleventyConfig);
+ await this.config.events.emit("buildawesome.config", this.eleventyConfig);
if (this.env) {
- await this.config.events.emit("eleventy.env", this.env);
+ await this.config.events.emit("buildawesome.env", this.env);
}
let formats = this.templateFormats.getTemplateFormats();
let engineManager = new TemplateEngineManager(this.eleventyConfig);
- this.extensionMap = new EleventyExtensionMap(this.eleventyConfig);
+ this.extensionMap = new ExtensionMap(this.eleventyConfig);
this.extensionMap.setFormats(formats);
this.extensionMap.engineManager = engineManager;
- await this.config.events.emit("eleventy.extensionmap", this.extensionMap);
+ await this.config.events.emit("buildawesome.extensionmap", this.extensionMap);
this.templateData = new TemplateData(this.eleventyConfig);
this.templateData.setProjectUsingEsm(this.isEsm);
@@ -472,16 +481,16 @@ export class MinimalCore {
}
// Note these directories are all project root relative
- this.config.events.emit("eleventy.directories", this.directories.getUserspaceInstance());
+ this.config.events.emit("buildawesome.directories", this.directories.getUserspaceInstance());
this.writer = new TemplateWriter(formats, this.templateData, this.eleventyConfig);
+ this.writer.logger = this.logger;
if (!viaConfigReset) {
// set or restore cache
this.#cache("TemplateWriter", this.writer);
}
- this.writer.logger = this.logger;
this.writer.extensionMap = this.extensionMap;
this.writer.setRunInitialBuild(this.isRunInitialBuild);
@@ -498,7 +507,6 @@ Template Formats: ${formats.join(",")}
Verbose Output: ${this.verboseMode}`;
debug(debugStr);
- this.writer.setVerboseOutput(this.verboseMode);
this.writer.setDryRun(this.isDryRun);
this.#needsInit = false;
@@ -538,13 +546,13 @@ Verbose Output: ${this.verboseMode}`;
// Recognize that global data `eleventy.version` is coerced to remove prerelease tags
// and this is the raw version (3.0.0 versus 3.0.0-alpha.6).
// `eleventy.env.version` does not yet exist (unnecessary)
- process.env.ELEVENTY_VERSION = MinimalCore.getVersion();
+ setEnvValue("VERSION", CoreMinimal.getVersion());
- process.env.ELEVENTY_ROOT = env.root;
- debug("Setting process.env.ELEVENTY_ROOT: %o", env.root);
+ setEnvValue("ROOT", env.root);
+ debug("Setting process.env.ELEVENTY_ROOT and BUILDAWESOME_ROOT: %o", env.root);
- process.env.ELEVENTY_SOURCE = env.source;
- process.env.ELEVENTY_RUN_MODE = env.runMode;
+ setEnvValue("SOURCE", env.source);
+ setEnvValue("RUN_MODE", env.runMode);
}
/** @param {boolean} value */
@@ -569,19 +577,18 @@ Verbose Output: ${this.verboseMode}`;
/** @param {ConsoleLogger} logger */
set logger(logger) {
- this.eleventyConfig.setLogger(logger);
this.#logger = logger;
+ this.eleventyConfig.setLogger(logger);
}
disableLogger() {
this.logger.overrideLogger(false);
}
- /** @type {EleventyErrorHandler} */
+ /** @type {ErrorHandler} */
get errorHandler() {
if (!this.#errorHandler) {
- this.#errorHandler = new EleventyErrorHandler();
- this.#errorHandler.isVerbose = this.verboseMode;
+ this.#errorHandler = new ErrorHandler();
this.#errorHandler.logger = this.logger;
}
@@ -589,10 +596,10 @@ Verbose Output: ${this.verboseMode}`;
}
/**
- * Updates the verbose mode of Eleventy.
+ * Updates the verbose mode (logs more detailed information).
*
* @method
- * @param {boolean} isVerbose - Shall Eleventy run in verbose mode?
+ * @param {boolean} isVerbose - Shall we run in verbose mode?
*/
setIsVerbose(isVerbose) {
if (!this.#hasConfigInitialized) {
@@ -609,16 +616,6 @@ Verbose Output: ${this.verboseMode}`;
this.logger.isVerbose = isVerbose;
}
- this.bench.setVerboseOutput(isVerbose);
-
- if (this.writer) {
- this.writer.setVerboseOutput(isVerbose);
- }
-
- if (this.errorHandler) {
- this.errorHandler.isVerbose = isVerbose;
- }
-
// Set verbose mode in config file
this.eleventyConfig.verbose = isVerbose;
}
@@ -633,7 +630,7 @@ Verbose Output: ${this.verboseMode}`;
}
/**
- * Updates the template formats of Eleventy.
+ * Updates the template formats.
*
* @method
* @param {string} formats - The new template formats.
@@ -643,7 +640,7 @@ Verbose Output: ${this.verboseMode}`;
}
/**
- * Updates the run mode of Eleventy.
+ * Updates the run mode (build/watch/serve).
*
* @method
* @param {string} runMode - One of "build", "watch", or "serve"
@@ -691,7 +688,7 @@ Verbose Output: ${this.verboseMode}`;
}
/**
- * Resets the config of Eleventy.
+ * Resets the config
*
* @method
*/
@@ -772,7 +769,7 @@ Verbose Output: ${this.verboseMode}`;
}
toNDJSON() {
- throw new Error("Feature removed in Eleventy v4: https://github.com/11ty/eleventy/issues/3382");
+ throw new Error("Feature removed in v4: https://github.com/11ty/eleventy/issues/3382");
}
/*
@@ -844,8 +841,7 @@ Verbose Output: ${this.verboseMode}`;
incremental: this.isIncremental,
};
- await this.config.events.emit("beforeBuild", eventsArg);
- await this.config.events.emit("eleventy.before", eventsArg);
+ await this.config.events.emit("buildawesome.before", eventsArg);
let promise;
if (to === "fs") {
@@ -862,7 +858,7 @@ Verbose Output: ${this.verboseMode}`;
let resolved = await promise;
- // Passing the processed output to the eleventy.after event (2.0+)
+ // Passing the processed output to the buildawesome.after event (2.0+)
eventsArg.results = resolved.templates;
if (to === "json" || to === "fs:templates") {
@@ -876,11 +872,10 @@ Verbose Output: ${this.verboseMode}`;
// always reset after first build
this.setIgnoreInitial(false);
this.writer.resetIncremental();
- this.config.events.emit("eleventy#previousqueue", incrementalFiles);
+ this.config.events.emit("buildawesome#previousqueue", incrementalFiles);
eventsArg.uses = this.eleventyConfig.usesGraph.map;
- await this.config.events.emit("afterBuild", eventsArg);
- await this.config.events.emit("eleventy.after", eventsArg);
+ await this.config.events.emit("buildawesome.after", eventsArg);
this.buildCount++;
} catch (error) {
@@ -906,21 +901,21 @@ Verbose Output: ${this.verboseMode}`;
debug(`
Have a suggestion/feature request/feedback? Feeling frustrated? I want to hear it!
-Open an issue: https://github.com/11ty/eleventy/issues/new`);
+Open an issue: https://github.com/11ty/buildawesome/issues/new`);
}
return returnObj;
}
/**
- * Logs some statistics after a complete run of Eleventy.
+ * Logs some statistics after a complete run.
*
* @returns {string} ret - The log message.
*/
logFinished() {
if (!this.writer) {
throw new Error(
- "Did you call Eleventy.init to create the TemplateWriter instance? Hint: you probably didn’t.",
+ "Internal error: missing TemplateWriter instance. Make sure you call init() to create it.",
);
}
@@ -969,7 +964,7 @@ Open an issue: https://github.com/11ty/eleventy/issues/new`);
chalk.gray(`(${((time * 1000) / writeCount).toFixed(1)}ms each, v${pkg.version}${cfgStr})`),
);
} else {
- ret.push(chalk.gray(`(v${MinimalCore.getVersion()}${cfgStr})`));
+ ret.push(chalk.gray(`(v${CoreMinimal.getVersion()}${cfgStr})`));
}
return ret.join(" ");
diff --git a/src/Data/ComputedData.js b/src/Data/ComputedData.js
index 22196b7db..cb3bf2993 100644
--- a/src/Data/ComputedData.js
+++ b/src/Data/ComputedData.js
@@ -1,12 +1,12 @@
import lodash from "@11ty/lodash-custom";
-import { createDebug } from "obug";
+import { createDebug } from "../Util/DebugLogUtil.js";
import ComputedDataQueue from "./ComputedDataQueue.js";
import ComputedDataTemplateString from "./ComputedDataTemplateString.js";
import ComputedDataProxy from "./ComputedDataProxy.js";
const { set: lodashSet, get: lodashGet } = lodash;
-const debug = createDebug("Eleventy:ComputedData");
+const debug = createDebug("ComputedData");
class ComputedData {
constructor(config) {
diff --git a/src/Data/ComputedDataTemplateString.js b/src/Data/ComputedDataTemplateString.js
index 9e29f3be3..7cfcfa512 100644
--- a/src/Data/ComputedDataTemplateString.js
+++ b/src/Data/ComputedDataTemplateString.js
@@ -1,8 +1,9 @@
import lodash from "@11ty/lodash-custom";
-import { createDebug } from "obug";
+
+import { createDebug } from "../Util/DebugLogUtil.js";
const { set: lodashSet } = lodash;
-const debug = createDebug("Eleventy:ComputedDataTemplateString");
+const debug = createDebug("ComputedDataTemplateString");
/* Calculates computed data in Template Strings.
* Ideally we would use the Proxy approach but it doesn’t work
diff --git a/src/Data/TemplateDataInitialGlobalData.js b/src/Data/ConfigurationGlobalData.js
similarity index 84%
rename from src/Data/TemplateDataInitialGlobalData.js
rename to src/Data/ConfigurationGlobalData.js
index 8979bfffe..9b86095e9 100644
--- a/src/Data/TemplateDataInitialGlobalData.js
+++ b/src/Data/ConfigurationGlobalData.js
@@ -1,13 +1,13 @@
import lodash from "@11ty/lodash-custom";
import ReservedData from "../Util/ReservedData.js";
-import EleventyBaseError from "../Errors/EleventyBaseError.js";
+import BaseError from "../Errors/BaseError.js";
const { set: lodashSet } = lodash;
-class TemplateDataConfigError extends EleventyBaseError {}
+class TemplateDataConfigError extends BaseError {}
-class TemplateDataInitialGlobalData {
+export default class ConfigurationGlobalData {
constructor(templateConfig) {
if (!templateConfig || templateConfig.constructor.name !== "TemplateConfig") {
throw new TemplateDataConfigError("Missing or invalid `templateConfig` (via Render plugin).");
@@ -42,5 +42,3 @@ class TemplateDataInitialGlobalData {
return globalData;
}
}
-
-export default TemplateDataInitialGlobalData;
diff --git a/src/Data/ResolveConfigurationData.js b/src/Data/ResolveConfigurationData.js
new file mode 100644
index 000000000..05fceef95
--- /dev/null
+++ b/src/Data/ResolveConfigurationData.js
@@ -0,0 +1,62 @@
+import lodash from "@11ty/lodash-custom";
+
+const { set: lodashSet, get: lodashGet } = lodash;
+
+// buildawesomeDataSchema looks for buildawesomeDataSchema and eleventyDataSchema (this is what we use internally)
+// eleventyDataSchema looks for eleventyDataSchema (and not buildawesomeDataSchema)
+export class ResolveConfigurationData {
+ static ELIGIBLE_PROPS = new Set([
+ "buildawesomeComputed",
+ "buildawesomeDataSchema",
+ "buildawesomeExcludeFromCollections",
+ "buildawesomeImport",
+ ]);
+ static BUILDAWESOME_PREFIX = "buildawesome";
+ static ELEVENTY_PREFIX = "eleventy";
+
+ // buildawesomeDataSchema becomes eleventyDataSchema
+ // eleventyDataSchema returned undefined
+ static getAlternatePropertyName(propertyName) {
+ if (typeof propertyName === "string" && this.ELIGIBLE_PROPS.has(propertyName)) {
+ let prefixRemoved = propertyName.slice(ResolveConfigurationData.BUILDAWESOME_PREFIX.length);
+ return this.ELEVENTY_PREFIX + prefixRemoved;
+ }
+ }
+
+ static getEligibleLocations(original) {
+ let eligibleLocations = [original];
+ let alternate = this.getAlternatePropertyName(original);
+ if (alternate !== undefined && alternate !== original) {
+ eligibleLocations.push(alternate);
+ }
+ return eligibleLocations;
+ }
+
+ static resolve(data, location) {
+ let eligible = this.getEligibleLocations(location);
+ for (let loc of eligible) {
+ let val = lodashGet(data, loc, undefined);
+ if (val !== undefined) {
+ return {
+ location: loc,
+ value: val,
+ };
+ }
+ }
+
+ return {
+ location: undefined,
+ };
+ }
+
+ static getValue(data, location) {
+ let eligible = this.getEligibleLocations(location);
+
+ for (let loc of eligible) {
+ let val = lodashGet(data, loc, undefined);
+ if (val !== undefined) {
+ return val;
+ }
+ }
+ }
+}
diff --git a/src/Data/TemplateData.js b/src/Data/TemplateData.js
index a15316839..fedb4707e 100644
--- a/src/Data/TemplateData.js
+++ b/src/Data/TemplateData.js
@@ -1,38 +1,45 @@
import path from "node:path";
import lodash from "@11ty/lodash-custom";
import { Merge, TemplatePath, isPlainObject } from "@11ty/eleventy-utils";
-import { createDebug } from "obug";
import { inspect } from "../Adapters/Packages/inspect.js";
import unique from "../Util/Objects/Unique.js";
import TemplateGlob from "../TemplateGlob.js";
-import EleventyBaseError from "../Errors/EleventyBaseError.js";
-import TemplateDataInitialGlobalData from "./TemplateDataInitialGlobalData.js";
-import { getEleventyPackageJson, getWorkingProjectPackageJson } from "../Util/ImportJsonSync.js";
-import { EleventyImport, EleventyLoadContent } from "../Util/Require.js";
+import BaseError from "../Errors/BaseError.js";
+import ConfigurationGlobalData from "./ConfigurationGlobalData.js";
+import {
+ getCorePackageJson,
+ importJsonSync,
+ getWorkingProjectPackageJsonPath,
+} from "../Util/ImportJsonSync.js";
+import { DynamicImport, LoadContent } from "../Util/Require.js";
import { DeepFreeze } from "../Util/Objects/DeepFreeze.js";
import { coerce } from "../Util/SemverCoerce.js";
+import ProjectDirectories from "../Util/ProjectDirectories.js";
import ReservedData from "../Util/ReservedData.js";
-import { isTypeScriptSupported } from "../Util/FeatureTests.cjs";
+import { isTypeScriptSupported } from "../Util/TypeScriptFeatureTest.cjs";
+import { ResolveConfigurationData } from "../Data/ResolveConfigurationData.js";
+import { createDebug } from "../Util/DebugLogUtil.js";
const { set: lodashSet, get: lodashGet } = lodash;
-const debugWarn = createDebug("Eleventy:Warnings");
-const debug = createDebug("Eleventy:TemplateData");
-const debugDev = createDebug("Dev:Eleventy:TemplateData");
+const debugWarn = createDebug("Warnings");
+const debug = createDebug("TemplateData");
-class TemplateDataParseError extends EleventyBaseError {}
+class TemplateDataParseError extends BaseError {}
class TemplateData {
- // order is important (json not included)
- #eligiblePrioritizedExtensions = [
+ // Would be nice if the priorities here matched (see also FilePathUtil used by config file paths)
+
+ // (json not included) priority is reverse order
+ #eligibleJavaScriptExtensions = [
+ ...(isTypeScriptSupported() ? ["ts", "cts", "mts"] : []),
"js",
"cjs",
"mjs",
- ...(isTypeScriptSupported() ? ["ts", "cts", "mts"] : []),
];
- // order is important
+ // in order of priority
#globalDataOrderedExtensions = [
"json",
"mjs",
@@ -41,6 +48,10 @@ class TemplateData {
...(isTypeScriptSupported() ? ["mts", "cts", "ts"] : []),
];
+ #rawImports;
+ #globalData;
+ #templateDirectoryData = {};
+
constructor(templateConfig) {
if (!templateConfig || templateConfig.constructor.name !== "TemplateConfig") {
throw new Error(
@@ -56,12 +67,8 @@ class TemplateData {
aggregate: this.config.benchmarkManager.get("Aggregate"),
};
- this.rawImports = {};
- this.globalData = null;
- this.templateDirectoryData = {};
this.isEsm = false;
-
- this.initialGlobalData = new TemplateDataInitialGlobalData(this.templateConfig);
+ this.initialGlobalData = new ConfigurationGlobalData(this.templateConfig);
}
get dirs() {
@@ -133,25 +140,34 @@ class TemplateData {
debug(
"Opted-out of package.json assignment for global data with falsy value for `keys.package` configuration.",
);
- return this.rawImports;
- } else if (Object.keys(this.rawImports).length > 0) {
- return this.rawImports;
+ return;
}
- let pkgJson = getWorkingProjectPackageJson();
- this.rawImports[this.config.keys.package] = pkgJson;
+ if (this.#rawImports) {
+ return this.#rawImports;
+ }
+
+ let projectPackageJsonPath = getWorkingProjectPackageJsonPath();
+ let packageJson = {};
+ if (projectPackageJsonPath) {
+ packageJson = importJsonSync(projectPackageJsonPath);
+ }
+
+ this.#rawImports = {
+ [this.config.keys.package]: packageJson,
+ };
if (this.config.freezeReservedData) {
- DeepFreeze(this.rawImports);
+ DeepFreeze(this.#rawImports);
}
- return this.rawImports;
+ return this.#rawImports;
}
clearData() {
- this.globalData = null;
+ this.#globalData = null;
this.configApiGlobalData = null;
- this.templateDirectoryData = {};
+ this.#templateDirectoryData = {};
}
_getGlobalDataGlobByExtension(extension) {
@@ -159,7 +175,7 @@ class TemplateData {
}
// This is a backwards compatibility helper with the old `jsDataFileSuffix` configuration API
- getDataFileSuffixes() {
+ getConfigurationDataFileSuffixes() {
// New API
if (Array.isArray(this.config.dataFileSuffixes)) {
return this.config.dataFileSuffixes;
@@ -168,79 +184,82 @@ class TemplateData {
// Backwards compatibility
if (this.config.jsDataFileSuffix) {
let suffixes = [];
- suffixes.push(this.config.jsDataFileSuffix); // e.g. filename.11tydata.json
+ suffixes.push(this.config.jsDataFileSuffix); // e.g. filename.data.json
suffixes.push(""); // suffix-less for free with old API, e.g. filename.json
return suffixes;
}
+
return []; // if both of these entries are set to false, use no files
}
- // This is used exclusively for --watch and --serve chokidar targets
- async getTemplateDataFileGlob() {
- let suffixes = this.getDataFileSuffixes();
- let globSuffixesWithLeadingDot = new Set();
- globSuffixesWithLeadingDot.add("json"); // covers .11tydata.json too
- let globSuffixesWithoutLeadingDot = new Set();
+ getAllDataFileSuffixes() {
+ let suffixes = this.getConfigurationDataFileSuffixes();
+ let suffixesWithExtensions = new Set();
+ suffixesWithExtensions.add("json"); // covers .data.json too
- // Typically using [ '.11tydata', '' ] suffixes to find data files
+ // Typically using [ '.data', '' ] suffixes to find data files
for (let suffix of suffixes) {
- // TODO the `suffix` truthiness check is purely for backwards compat?
- if (suffix && typeof suffix === "string") {
- if (suffix.startsWith(".")) {
- // .suffix.js
- globSuffixesWithLeadingDot.add(`${suffix.slice(1)}.mjs`);
- globSuffixesWithLeadingDot.add(`${suffix.slice(1)}.cjs`);
- globSuffixesWithLeadingDot.add(`${suffix.slice(1)}.js`);
-
- if (isTypeScriptSupported()) {
- globSuffixesWithLeadingDot.add(`${suffix.slice(1)}.mts`);
- globSuffixesWithLeadingDot.add(`${suffix.slice(1)}.cts`);
- globSuffixesWithLeadingDot.add(`${suffix.slice(1)}.ts`);
- }
- } else {
- // "suffix.js" without leading dot
- globSuffixesWithoutLeadingDot.add(`${suffix || ""}.mjs`);
- globSuffixesWithoutLeadingDot.add(`${suffix || ""}.cjs`);
- globSuffixesWithoutLeadingDot.add(`${suffix || ""}.js`);
-
- if (isTypeScriptSupported()) {
- globSuffixesWithoutLeadingDot.add(`${suffix || ""}.mts`);
- globSuffixesWithoutLeadingDot.add(`${suffix || ""}.cts`);
- globSuffixesWithoutLeadingDot.add(`${suffix || ""}.ts`);
- }
- }
+ if (!suffix || typeof suffix !== "string") {
+ continue;
+ }
+
+ // .suffix.js
+ if (suffix.startsWith(".")) {
+ suffix = suffix.slice(1);
+ }
+
+ suffixesWithExtensions.add(`${suffix || ""}.mjs`);
+ suffixesWithExtensions.add(`${suffix || ""}.cjs`);
+ suffixesWithExtensions.add(`${suffix || ""}.js`);
+
+ if (isTypeScriptSupported()) {
+ suffixesWithExtensions.add(`${suffix || ""}.mts`);
+ suffixesWithExtensions.add(`${suffix || ""}.cts`);
+ suffixesWithExtensions.add(`${suffix || ""}.ts`);
}
}
// Configuration Data Extensions e.g. yaml
if (this.hasUserDataExtensions()) {
for (let extension of this.getUserDataExtensions()) {
- globSuffixesWithLeadingDot.add(extension); // covers .11tydata.{extension} too
+ if (extension.startsWith(".")) {
+ extension = extension.slice(1);
+ }
+
+ suffixesWithExtensions.add(extension); // covers .data.{extension} too
}
}
+ return suffixesWithExtensions;
+ }
+
+ // This is used exclusively for --watch and --serve chokidar targets
+ getTemplateDataFileGlob() {
+ let suffixesSet = this.getAllDataFileSuffixes();
+
let paths = [];
- if (globSuffixesWithLeadingDot.size > 0) {
- paths.push(`${this.inputDir}**/*.{${Array.from(globSuffixesWithLeadingDot).join(",")}}`);
- }
- if (globSuffixesWithoutLeadingDot.size > 0) {
- paths.push(`${this.inputDir}**/*{${Array.from(globSuffixesWithoutLeadingDot).join(",")}}`);
+ if (suffixesSet.size > 0) {
+ paths.push(`${this.inputDir}**/*.{${Array.from(suffixesSet).join(",")}}`);
}
return TemplatePath.addLeadingDotSlashArray(paths);
}
// For spidering dependencies
- // TODO Can we reuse getTemplateDataFileGlob instead? Maybe just filter off the .json files before scanning for dependencies
getTemplateJavaScriptDataFileGlob() {
- let paths = [];
- let suffixes = this.getDataFileSuffixes();
- for (let suffix of suffixes) {
- if (suffix) {
- // TODO this check is purely for backwards compat and I kinda feel like it shouldn’t be here
- // paths.push(`${this.inputDir}/**/*${suffix || ""}.cjs`); // Same as above
- paths.push(`${this.inputDir}**/*${suffix || ""}.js`); // TODO typescript?
+ let suffixes = Array.from(this.getAllDataFileSuffixes()).filter((entry) => {
+ let lastDotIndex = entry.lastIndexOf(".");
+ if (lastDotIndex === -1) {
+ return false;
}
+ let ext = entry.slice(lastDotIndex + 1);
+ // prune out any non-JS extensions
+ return this.#eligibleJavaScriptExtensions.includes(ext);
+ });
+
+ let paths = [];
+ if (suffixes.length > 0) {
+ paths.push(`${this.inputDir}**/*.{${suffixes.join(",")}}`);
}
return TemplatePath.addLeadingDotSlashArray(paths);
@@ -312,15 +331,16 @@ class TemplateData {
async getAllGlobalData() {
let globalData = {};
+
let files = TemplatePath.addLeadingDotSlashArray(await this.getGlobalDataFiles());
- this.config.events.emit("eleventy.globalDataFiles", files);
+ this.config.events.emit("buildawesome.globaldatafiles", files);
let dataFileConflicts = {};
- for (let j = 0, k = files.length; j < k; j++) {
- let data = await this.getDataValue(files[j]);
- let objectPathTarget = this.getObjectPathForDataFile(files[j]);
+ for (let file of Object.values(files)) {
+ let data = await this.getDataValue(file);
+ let objectPathTarget = this.getObjectPathForDataFile(file);
// Since we're joining directory paths and an array is not usable as an objectkey since two identical arrays are not double equal,
// we can just join the array by a forbidden character ("/"" is chosen here, since it works on Linux, Mac and Windows).
@@ -332,58 +352,56 @@ class TemplateData {
// and conflict, let’s merge them.
if (dataFileConflicts[objectPathTargetString]) {
debugWarn(
- `merging global data from ${files[j]} with an already existing global data file (${dataFileConflicts[objectPathTargetString]}). Overriding existing keys.`,
+ `merging global data from ${file} with an already existing global data file (${dataFileConflicts[objectPathTargetString]}). Overriding existing keys.`,
);
let oldData = lodashGet(globalData, objectPathTarget);
data = Merge(oldData, data);
}
- dataFileConflicts[objectPathTargetString] = files[j];
- debug(`Found global data file ${files[j]} and adding as: ${objectPathTarget}`);
+ dataFileConflicts[objectPathTargetString] = file;
+ debug(`Found global data file ${file} and adding as: ${objectPathTarget}`);
+
lodashSet(globalData, objectPathTarget, data);
if (this.config.freezeReservedData) {
- ReservedData.check(globalData, files[j]);
+ ReservedData.check(globalData, file);
}
}
return globalData;
}
- async #getInitialGlobalData() {
- let globalData = await this.initialGlobalData.getData();
-
- if (!("eleventy" in globalData)) {
- globalData.eleventy = {};
- }
-
+ getCoreGlobal() {
// #2293 for meta[name=generator]
- const pkg = getEleventyPackageJson();
- globalData.eleventy.version = coerce(pkg.version).toString();
- globalData.eleventy.generator = `Eleventy v${globalData.eleventy.version}`;
+ const pkg = getCorePackageJson();
+ let version = coerce(pkg.version).toString();
+ let global = {
+ version,
+ generator: `Eleventy (Build Awesome) v${version}`,
+ };
if (this.environmentVariables) {
- if (!("env" in globalData.eleventy)) {
- globalData.eleventy.env = {};
- }
-
- Object.assign(globalData.eleventy.env, this.environmentVariables);
+ global.env = Object.assign({}, this.environmentVariables);
}
-
if (this.dirs) {
- if (!("directories" in globalData.eleventy)) {
- globalData.eleventy.directories = {};
- }
-
- Object.assign(globalData.eleventy.directories, this.dirs.getUserspaceInstance());
+ global.directories = Object.assign({}, this.dirs.getUserspaceInstance());
}
- // Reserved
if (this.config.freezeReservedData) {
- DeepFreeze(globalData.eleventy);
+ DeepFreeze(global);
}
+ return global;
+ }
+
+ async #getInitialGlobalData() {
+ let globalData = await this.initialGlobalData.getData();
+
+ let coreGlobal = this.getCoreGlobal();
+ globalData.eleventy = coreGlobal;
+ globalData.buildawesome = coreGlobal;
+
return globalData;
}
@@ -397,6 +415,8 @@ class TemplateData {
async #getGlobalData() {
let rawImports = this.getRawImports();
+
+ // Data from the configuration API eleventyConfig.addGLobalData and `eleventy` global
let configApiGlobalData = await this.getInitialGlobalData();
let globalJson = await this.getAllGlobalData();
@@ -407,11 +427,11 @@ class TemplateData {
}
async getGlobalData() {
- if (!this.globalData) {
- this.globalData = this.#getGlobalData();
+ if (!this.#globalData) {
+ this.#globalData = this.#getGlobalData();
}
- return this.globalData;
+ return this.#globalData;
}
/* Template and Directory data files */
@@ -422,11 +442,12 @@ class TemplateData {
}
// Filter out files we know don't exist to avoid overhead for checking
+ // June 2026 tested improvement from short-circuiting first match for any file filename.11tydata.cjs would skip remaining filename.11tydata.*
localDataPaths = localDataPaths.filter((path) => {
return this.exists(path);
});
- this.config.events.emit("eleventy.dataFiles", localDataPaths);
+ this.config.events.emit("buildawesome.datafiles", localDataPaths);
if (!localDataPaths.length) {
return localData;
@@ -457,20 +478,23 @@ class TemplateData {
}
dataSource[key] = path;
}
+
Merge(localData, cleanedDataForPath);
}
}
+
return localData;
}
async getTemplateDirectoryData(templatePath) {
- if (!this.templateDirectoryData[templatePath]) {
+ if (!this.#templateDirectoryData[templatePath]) {
let localDataPaths = await this.getLocalDataPaths(templatePath);
let importedData = await this.combineLocalData(localDataPaths);
- this.templateDirectoryData[templatePath] = importedData;
+ this.#templateDirectoryData[templatePath] = importedData;
}
- return this.templateDirectoryData[templatePath];
+
+ return this.#templateDirectoryData[templatePath];
}
getUserDataExtensions() {
@@ -495,12 +519,12 @@ class TemplateData {
return this.config.dataExtensions && this.config.dataExtensions.size > 0;
}
- async _parseDataFile(path, parser, options = {}) {
+ async #parseDataFile(path, parser, options = {}) {
let readFile = !("read" in options) || options.read === true;
let rawInput;
if (readFile) {
- rawInput = EleventyLoadContent(path, options);
+ rawInput = LoadContent(path, options);
}
if (readFile && !rawInput) {
@@ -520,12 +544,10 @@ class TemplateData {
}
}
- // ignoreProcessing = false for global data files
- // ignoreProcessing = true for local data files
async getDataValue(path) {
let extension = TemplatePath.getExtension(path);
- if (this.#eligiblePrioritizedExtensions.includes(extension)) {
+ if (this.#eligibleJavaScriptExtensions.includes(extension)) {
// JS data file or require’d JSON (no preprocessing needed)
if (!this.exists(path)) {
return {};
@@ -547,9 +569,12 @@ class TemplateData {
}
// We always need to use `import()`, as `require` isn’t available in ESM.
- let returnValue = await EleventyImport(path, type);
+ let returnValue = await DynamicImport(path, type);
- // TODO special exception for Global data `permalink.js`
+ // Returning a function is executed immediately (it has always done this for global data)
+
+ // TODO some API to allow returning a function without executing it immediately
+ // (e.g. `permalink.js` or `eleventyDataSchema.js` global data)
// module.exports = (data) => `${data.page.filePathStem}/`; // Does not work
// module.exports = () => ((data) => `${data.page.filePathStem}/`); // Works
if (typeof returnValue === "function") {
@@ -565,11 +590,14 @@ class TemplateData {
// Other extensions
let { parser, options } = this.getUserDataParser(extension);
- return this._parseDataFile(path, parser, options);
+ let returnValue = this.#parseDataFile(path, parser, options);
+
+ return returnValue;
} else if (extension === "json") {
// File to string, parse with JSON (preprocess)
- const parser = (content) => JSON.parse(content);
- return this._parseDataFile(path, parser);
+ let returnValue = this.#parseDataFile(path, (content) => JSON.parse(content));
+
+ return returnValue;
} else {
throw new TemplateDataParseError(
`Could not find an appropriate data parser for ${path}. Do you need to add a plugin to your config file?`,
@@ -584,7 +612,7 @@ class TemplateData {
}
_addBaseToPaths(paths, base, extensions, nonEmptySuffixesOnly = false) {
- let suffixes = this.getDataFileSuffixes();
+ let suffixes = this.getConfigurationDataFileSuffixes();
for (let suffix of suffixes) {
suffix = suffix || "";
@@ -595,11 +623,11 @@ class TemplateData {
// data suffix
if (suffix) {
- for (let extension of this.#eligiblePrioritizedExtensions) {
+ for (let extension of this.#eligibleJavaScriptExtensions) {
paths.push(base + suffix + "." + extension);
}
}
- paths.push(base + suffix + ".json"); // default: .11tydata.json
+ paths.push(base + suffix + ".json"); // default: .data.json
// inject user extensions
this._pushExtensionsToPaths(paths, base + suffix, extensions);
@@ -611,16 +639,13 @@ class TemplateData {
let parsed = path.parse(templatePath);
let inputDir = this.inputDir;
- debugDev("getLocalDataPaths(%o)", templatePath);
- debugDev("parsed.dir: %o", parsed.dir);
-
let userExtensions = this.getUserDataExtensions();
if (parsed.dir) {
let fileNameNoExt = this.extensionMap.removeTemplateExtension(parsed.base);
- // default dataSuffix: .11tydata, is appended in _addBaseToPaths
- debug("Using %o suffixes to find data files.", this.getDataFileSuffixes());
+ // default dataSuffix: .data, is appended in _addBaseToPaths
+ debug("Using %o suffixes to find data files.", this.getConfigurationDataFileSuffixes());
// Template data file paths
let filePathNoExt = parsed.dir + "/" + fileNameNoExt;
@@ -629,14 +654,10 @@ class TemplateData {
// Directory data file paths
let allDirs = TemplatePath.getAllDirs(parsed.dir);
- debugDev("allDirs: %o", allDirs);
for (let dir of allDirs) {
let lastDir = TemplatePath.getLastPathSegment(dir);
let dirPathNoExt = dir + "/" + lastDir;
- if (inputDir) {
- debugDev("dirStr: %o; inputDir: %o", dir, inputDir);
- }
// TODO use DirContains
if (!inputDir || (dir.startsWith(inputDir) && dir !== inputDir)) {
if (this.config.dataFileDirBaseNameOverride) {
@@ -655,7 +676,7 @@ class TemplateData {
TemplatePath.join(inputDir, TemplatePath.getLastPathSegment(inputDir)),
);
- // in root input dir, search for index.11tydata.json et al
+ // in root input dir, search for index.data.json et al
if (this.config.dataFileDirBaseNameOverride) {
let indexDataFile =
TemplatePath.getDirFromFilePath(lastInputDir) +
@@ -705,19 +726,22 @@ class TemplateData {
static getNormalizedExcludedCollections(data) {
let excludes = [];
- let key = "eleventyExcludeFromCollections";
-
- if (data?.[key] !== true) {
- if (Array.isArray(data[key])) {
- excludes = data[key];
- } else if (typeof data[key] === "string") {
- excludes = (data[key] || "").split(",");
+ // TODO move this key to defaultConfig->keys->excludeFromCollections
+ let excludeValue = ResolveConfigurationData.getValue(
+ data,
+ "buildawesomeExcludeFromCollections",
+ );
+ if (excludeValue !== true) {
+ if (Array.isArray(excludeValue)) {
+ excludes = excludeValue;
+ } else if (typeof excludeValue === "string") {
+ excludes = (excludeValue || "").split(",");
}
}
return {
excludes,
- excludeAll: data?.eleventyExcludeFromCollections === true,
+ excludeAll: excludeValue === true,
};
}
diff --git a/src/Eleventy.js b/src/Eleventy.js
deleted file mode 100644
index 48fca0808..000000000
--- a/src/Eleventy.js
+++ /dev/null
@@ -1,627 +0,0 @@
-import { relative } from "node:path";
-import { createDebug } from "obug";
-
-import { TemplatePath } from "@11ty/eleventy-utils";
-
-import { Core } from "./Core.js";
-import EleventyServe from "./EleventyServe.js";
-import { Watch } from "./Watch.js";
-import WatchQueue from "./WatchQueue.js";
-import WatchTargets from "./WatchTargets.js";
-import EleventyBaseError from "./Errors/EleventyBaseError.js";
-
-// Utils
-import checkPassthroughCopyBehavior from "./Util/PassthroughCopyBehaviorCheck.js";
-import PathPrefixer from "./Util/PathPrefixer.js";
-import PathNormalizer from "./Util/PathNormalizer.js";
-import { isGlobMatch } from "./Util/GlobMatcher.js";
-import eventBus from "./EventBus.js";
-
-const debug = createDebug("Eleventy");
-
-export default class Eleventy extends Core {
- /** @type {boolean} */
- #isStopping = false;
-
- /** @type {WatchQueue} */
- #watchQueue;
-
- #watchDelay;
- #interrupted = false;
-
- // constructor(input, output, options = {}, eleventyConfig = null) {
- // super(input, output, options, eleventyConfig);
- // }
-
- get watchQueue() {
- if (!this.#watchQueue) {
- this.#watchQueue = new WatchQueue();
- }
- return this.#watchQueue;
- }
-
- async initializeConfig(initOverrides) {
- await super.initializeConfig(initOverrides);
-
- // Careful to make sure the previous server closes on SIGINT, issue #3873
- if (!this.eleventyServe) {
- /** @type {object} */
- this.eleventyServe = new EleventyServe();
- }
- this.eleventyServe.eleventyConfig = this.eleventyConfig;
-
- /** @type {object} */
- this.watchTargets = new WatchTargets(this.eleventyConfig);
- this.watchTargets.add(this.config.additionalWatchTargets);
- }
-
- async resetConfig() {
- await super.resetConfig();
-
- // TODO set this.eleventyServe with this.getChokidarConfig()
- if (checkPassthroughCopyBehavior(this.config, this.runMode)) {
- this.eleventyServe.resetConfig();
- }
- }
-
- /**
- * Starts Eleventy.
- */
- async init(options = {}) {
- await super.init(options);
-
- // eleventyServe is always available, even when not in --serve mode
- // TODO directorynorm
- this.eleventyServe.setOutputDir(this.outputDir);
-
- if (checkPassthroughCopyBehavior(this.config, this.runMode)) {
- this.eleventyServe.watchPassthroughCopy(
- this.eleventyFiles.getGlobWatcherFilesForPassthroughCopy(),
- );
- }
- }
-
- /**
- * @param {string} changedFilePath - File that triggered a re-run (added or modified)
- * @param {boolean} [isResetConfig] - are we doing a config reset
- */
- #resetFileInWatchQueue(changedFilePath, isResetConfig) {
- // v3.1.0: `eleventy.templateModified` is no longer used internally
- // v4.0.0-alpha.8 `eleventy.templateModified` event removed
-
- // These listeners are *global*, not cleared even on config reset (v4.0.0-alpha.8 removed some arguments here)
- eventBus.emit("eleventy.resourceModified", changedFilePath);
-
- this.config.events.emit("eleventy#templateModified", changedFilePath);
- }
-
- shouldTriggerConfigReset(changedFiles) {
- // looks for all eligible config files (not just the active one, handles config file rename)
- let configFilePaths = new Set(this.eleventyConfig.getLocalProjectConfigFiles());
-
- // https://www.11ty.dev/docs/watch-serve/#reset-configuration
- let resetConfigGlobs = WatchTargets.normalizeToGlobs(
- Array.from(this.eleventyConfig.userConfig.watchTargetsConfigReset),
- );
-
- for (let filePath of changedFiles) {
- if (configFilePaths.has(filePath)) {
- return true;
- }
- if (isGlobMatch(filePath, resetConfigGlobs)) {
- return true;
- }
- }
-
- for (let configFilePath of configFilePaths) {
- // Any dependencies of the config file changed
- let configFileDependencies = new Set(this.watchTargets.getDependenciesOf(configFilePath));
-
- for (let filePath of changedFiles) {
- if (configFileDependencies.has(filePath)) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- // Checks the build queue to see if any configuration related files have changed
- #shouldResetConfig(activeQueue = []) {
- if (!activeQueue.length) {
- return false;
- }
-
- return this.shouldTriggerConfigReset(
- activeQueue.map((path) => {
- return PathNormalizer.normalizeSeperator(TemplatePath.addLeadingDotSlash(path));
- }),
- );
- }
-
- async #rewatch() {
- if (this.watchQueue.isBuildRunning()) {
- // this.logger.forceLog("Waiting for previous build to finish…");
- return;
- }
-
- this.watchQueue.startBuild();
-
- let queue = this.watchQueue.getActiveQueue();
- let isResetConfig = this.#shouldResetConfig(queue);
-
- for (let p of queue) {
- this.#resetFileInWatchQueue(p, isResetConfig);
- }
-
- this.logger.forceLog(
- `Build starting${queue.length > 1 ? ` (${queue.length} queued changes)` : ""}…` +
- (isResetConfig ? " (configuration reset)" : ""),
- );
-
- await this.config.events.emit("beforeWatch", queue);
- await this.config.events.emit("eleventy.beforeWatch", queue);
-
- // Clear `import` cache for all files that triggered the rebuild (sync event)
- this.watchTargets.clearImportCacheFor(queue);
-
- // reset and reload global configuration
- if (isResetConfig) {
- // important: run this before config resets otherwise the handlers will disappear.
- await this.config.events.emit("eleventy.reset");
- this.resetConfig();
- }
-
- await this.restart();
- await this.init({ viaConfigReset: isResetConfig });
-
- try {
- let [passthroughCopyResults, templateResults] = await this.write();
-
- if (isResetConfig) {
- // make sure this happens after write()
- await this.startWatch();
- }
-
- this.watchTargets.reset();
-
- await this.#initWatchDependencies();
-
- // Add new deps to chokidar
- let newWatchTargets = this.watchTargets.getNewTargetsSinceLastReset();
- this.watcher.watchTargets(newWatchTargets);
-
- // Is a CSS input file and is not in the includes folder
- // TODO check output path file extension of this template (not input path)
- // TODO add additional API for this, maybe a config callback?
- let onlyCssChanges = this.watchQueue.hasAllQueueFiles((path) => {
- return (
- path.endsWith(".css") &&
- // TODO how to make this work with relative includes?
- !TemplatePath.startsWithSubPath(path, this.eleventyFiles.getIncludesDir())
- );
- });
-
- // Maps passthrough copy files to output URLs for CSS live reload
- let stylesheetUrls = new Set();
- for (let entry of passthroughCopyResults) {
- for (let filepath in entry.map) {
- if (
- filepath.endsWith(".css") &&
- queue.includes(TemplatePath.addLeadingDotSlash(filepath))
- ) {
- stylesheetUrls.add(
- "/" + TemplatePath.stripLeadingSubPath(entry.map[filepath], this.outputDir),
- );
- }
- }
- }
-
- let normalizedPathPrefix = PathPrefixer.normalizePathPrefix(this.config.pathPrefix);
- let matchingTemplates = templateResults
- .flat()
- .filter((entry) => Boolean(entry))
- .map((entry) => {
- // only `url`, `inputPath`, and `content` are used: https://github.com/11ty/eleventy-dev-server/blob/1c658605f75224fdc76f68aebe7a412eeb4f1bc9/client/reload-client.js#L140
- entry.url = PathPrefixer.joinUrlParts(normalizedPathPrefix, entry.url);
- delete entry.rawInput; // Issue #3481
- return entry;
- });
-
- await this.eleventyServe.reload({
- files: queue,
- subtype: onlyCssChanges ? "css" : undefined,
- build: {
- stylesheets: Array.from(stylesheetUrls),
- templates: matchingTemplates,
- },
- });
- } catch (error) {
- this.eleventyServe.sendError({
- error,
- });
- }
-
- this.watchQueue.finishBuild();
-
- // Re-fetch
- let pendingQueue = this.watchQueue.getPendingQueue();
- if (pendingQueue.length > 0) {
- await this.#rewatch();
- } else if (!this.#interrupted) {
- // also logs in startWatch for initial build
- this.logger.forceLog(`Waiting…`);
- }
- }
-
- /*
- * SIGINT
- */
- interrupt() {
- this.#interrupted = true;
-
- // Clear the queue to prevent additional builds
- this.watchQueue.reset();
- }
-
- /**
- * @returns {module:11ty/eleventy/src/Benchmark/BenchmarkGroup~BenchmarkGroup}
- */
- get watcherBench() {
- return this.bench.get("Watcher");
- }
-
- async waitThrottle() {
- if (this.#watchDelay) {
- clearTimeout(this.#watchDelay);
- }
-
- if (this.config.watchThrottleWaitTime > 0) {
- let { promise, resolve } = Promise.withResolvers();
-
- this.#watchDelay = setTimeout(resolve, this.config.watchThrottleWaitTime);
-
- return promise;
- }
- }
-
- // Triggers when files are modified on file system
- async triggerWatchRunForPath(path) {
- this.watchQueue.addToPendingQueue(path);
-
- await this.waitThrottle();
-
- try {
- await this.#rewatch();
- } catch (e) {
- this.watchQueue.finishBuild();
-
- if (e instanceof EleventyBaseError) {
- this.errorHandler.error(e, "Eleventy watch error");
- } else {
- this.errorHandler.fatal(e, "Eleventy fatal watch error");
- await this.close();
- }
- }
-
- // Internal event for testing
- // v4.0.0-alpha.8 swapped to async-friendly
- await this.config.events.emit("eleventy.afterwatch");
- }
-
- /**
- * Set up watchers and benchmarks.
- *
- * @async
- * @method
- */
- async startWatch() {
- if (this.projectPackageJsonPath) {
- this.watchTargets.add([relative(TemplatePath.getWorkingDir(), this.projectPackageJsonPath)]);
- }
- this.watchTargets.add(this.eleventyFiles.getGlobWatcherFiles());
- this.watchTargets.add(this.eleventyFiles.getIgnoreFiles());
-
- // Watch the local project config file
- this.watchTargets.add(this.eleventyConfig.getActiveConfigPath());
-
- // Template and Directory Data Files
- this.watchTargets.add(await this.eleventyFiles.getGlobWatcherTemplateDataFiles());
-
- let benchmark = this.watcherBench.get(
- "Watching JavaScript Dependencies (disable with `eleventyConfig.setWatchJavaScriptDependencies(false)`)",
- );
- benchmark.before();
- await this.#initWatchDependencies();
- benchmark.after();
-
- // Close previous watcher
- if (this.watcher) {
- await this.watcher.close();
- }
-
- // TODO improve unwatching if JS dependencies are removed (or files are deleted)
- let { targets, ignores } = await this.getWatchedTargets();
- debug("Watching for changes to: %o", targets);
-
- this.watcher = new Watch(this.eleventyConfig);
- this.watcher.watchTargets(targets);
- this.watcher.addIgnores(ignores);
-
- await this.watcher.start();
-
- // This logs in #rewatch for rebuilds
- if (this.buildCount <= 1) {
- this.logger.forceLog("Waiting…");
- }
-
- this.watcher.on("change", async (path) => {
- // Emulated passthrough copy logs from the server
- if (!this.eleventyServe.isEmulatedPassthroughCopyMatch(path)) {
- this.logger.forceLog(
- `File changed: ${TemplatePath.stripLeadingDotSlash(TemplatePath.standardizeFilePath(path))}${this.watchQueue.isBuildRunning() ? " (queued for next build)" : ""}`,
- );
- }
-
- // don’t await
- this.triggerWatchRunForPath(path);
- });
-
- this.watcher.on("add", async (path) => {
- // Emulated passthrough copy logs from the server
- if (!this.eleventyServe.isEmulatedPassthroughCopyMatch(path)) {
- this.logger.forceLog(
- `File added: ${TemplatePath.stripLeadingDotSlash(TemplatePath.standardizeFilePath(path))}${this.watchQueue.isBuildRunning() ? " (queued for next build)" : ""}`,
- );
- }
-
- this.fileSystemSearch.add(path);
- // don’t await
- this.triggerWatchRunForPath(path);
- });
-
- this.watcher.on("unlink", async (path) => {
- // Emulated passthrough copy logs from the server
- if (!this.eleventyServe.isEmulatedPassthroughCopyMatch(path)) {
- this.logger.forceLog(
- `File deleted: ${TemplatePath.stripLeadingDotSlash(TemplatePath.standardizeFilePath(path))}${this.watchQueue.isBuildRunning() ? " (queued for next build)" : ""}`,
- );
- }
-
- this.fileSystemSearch.delete(path);
- // don’t await
- this.triggerWatchRunForPath(path);
- });
- }
-
- /**
- * Starts watching dependencies.
- */
- async #initWatchDependencies() {
- if (!this.eleventyConfig.shouldSpiderJavaScriptDependencies()) {
- return;
- }
-
- // Lazy resolve isEsm only for --watch
- this.watchTargets.setProjectUsingEsm(this.isEsm);
-
- // Template files .11ty.js
- let templateFiles = await this.eleventyFiles.getWatchPathCache();
- await this.watchTargets.addDependencies(templateFiles);
-
- // TODO use DirContains
- let dataDir = TemplatePath.stripLeadingDotSlash(this.templateData.getDataDir());
- function filterOutGlobalDataFiles(path) {
- return !dataDir || !TemplatePath.stripLeadingDotSlash(path).startsWith(dataDir);
- }
-
- // Config file dependencies
- await this.watchTargets.addDependencies(
- this.eleventyConfig.getActiveConfigPath(),
- filterOutGlobalDataFiles,
- );
-
- // Deps from Global Data (that aren’t in the global data directory, everything is watched there)
- let globalDataDeps = this.templateData.getWatchPathCache();
- await this.watchTargets.addDependencies(globalDataDeps, filterOutGlobalDataFiles);
-
- await this.watchTargets.addDependencies(
- await this.eleventyFiles.getWatcherTemplateJavaScriptDataFiles(),
- );
- }
-
- /**
- * Returns all watched paths
- *
- * @async
- * @method
- * @returns {Object} `targets` file paths, and `ignores` globs Array
- */
- async getWatchedTargets() {
- return {
- targets: await this.watchTargets.getTargets(),
- ignores: this.eleventyFiles.getGlobWatcherIgnores(),
- };
- }
-
- /**
- * Start watching files
- *
- * @async
- * @method
- */
- async watch() {
- this.watcherBench.setMinimumThresholdMs(500);
- this.watcherBench.reset();
-
- // Note that watching indirectly depends on this for fetching dependencies from JS files
- // See: TemplateWriter:pathCache and WatchTargets
- await this.write();
-
- let initWatchBench = this.watcherBench.get("Start up --watch");
- initWatchBench.before();
-
- await this.startWatch();
-
- initWatchBench.after();
-
- this.watcherBench.finish("Watch");
- }
-
- // Renamed to close()
- async stopWatch() {
- return this.close();
- }
-
- async close() {
- // Prevent multiple invocations.
- if (this.#isStopping) {
- return this.#isStopping;
- }
-
- debug("Cleaning up chokidar and server instances, if they exist.");
- this.#isStopping = Promise.all([this.eleventyServe.close(), this.watcher?.close()]).then(() => {
- this.#isStopping = false;
- });
-
- return this.#isStopping;
- }
-
- /**
- * Serve Eleventy on this port.
- *
- * @param {Number} port - The HTTP port to serve Eleventy from.
- */
- async serve(port) {
- // Port is optional and in this case likely via --port on the command line
- // May defer to configuration API options `port` property
- return this.eleventyServe.serve(port);
- }
-
- /**
- * Shows a help message including usage.
- *
- * @static
- * @returns {string} - The help message.
- */
- static getHelp() {
- return `Usage: eleventy
- eleventy --input=. --output=./_site
- eleventy --serve
-
-Arguments:
-
- --version
-
- --input=.
- Input template files (default: \`.\`)
-
- --output=_site
- Write HTML output to this folder (default: \`_site\`)
-
- --serve
- Run web server on --port (default 8080) and watch them too
-
- --port
- Run the --serve web server on this port (default 8080)
-
- --watch
- Wait for files to change and automatically rewrite (no web server)
-
- --incremental
- Only build the files that have changed. Best with watch/serve.
-
- --incremental=first.md,second.md
- --incremental=first.md --incremental=second.md
- Does not require watch/serve. Run an incremental build targeting one or more files.
-
- --ignore-initial
- Start without a build; build when files change. Works best with watch/serve/incremental.
-
- --formats=liquid,md
- Allow only certain template types (default: \`*\`)
-
- --quiet
- Don’t print all written files (off by default)
-
- --config=filename.js
- Override the eleventy config file path (default: \`.eleventy.js\`)
-
- --pathprefix='/'
- Change all url template filters to use this subdirectory.
-
- --dryrun
- Don’t write any files. Useful in DEBUG mode, for example: \`DEBUG=Eleventy* npx @11ty/eleventy --dryrun\`
-
- --loader
- Set to "esm" to force ESM mode, "cjs" to force CommonJS mode, or "auto" (default) to infer it from package.json.
-
- --to=json
- Change the output to JSON (default: \`fs\`)
-
- --to=fs:templates
- Writes templates, skips passthrough copy
-
- --help`;
- }
-
- /**
- * @deprecated since 1.0.1, use static Eleventy.getHelp()
- */
- getHelp() {
- return Eleventy.getHelp();
- }
-
- /* Removed methods */
- initWatch() {
- throw new Error(
- "Eleventy#initWatch() was removed in v4. Use Eleventy#startWatch() instead (initializes and starts the watcher)",
- );
- }
- getWatchedFiles() {
- throw new Error(
- "Eleventy#getWatchedFiles() was removed in Eleventy v4. Use Eleventy#getWatchedTargets().targets instead.",
- );
- }
-}
-
-export { Eleventy };
-
-/* Utils */
-export { EleventyImport as ImportFile } from "./Util/Require.js";
-
-// TODO(breaking) remove these and recommend folks use package level exports e.g. "@11ty/eleventy/plugins/i18n"
-
-/* Plugins */
-export { default as BundlePlugin } from "@11ty/eleventy-plugin-bundle";
-
-// Eleventy*Plugin names are legacy names
-export {
- default as RenderPlugin,
- default as EleventyRenderPlugin,
-} from "./Plugins/RenderPlugin.js";
-export { default as I18nPlugin, default as EleventyI18nPlugin } from "./Plugins/I18nPlugin.js";
-export {
- default as HtmlBasePlugin,
- default as EleventyHtmlBasePlugin,
-} from "./Plugins/HtmlBasePlugin.js";
-export { TransformPlugin as InputPathToUrlTransformPlugin } from "./Plugins/InputPathToUrl.js";
-export { IdAttributePlugin } from "./Plugins/IdAttributePlugin.js";
-
-export { PreserveClosingTagsPlugin } from "./Plugins/PreserveClosingTagsPlugin.js";
-
-// Error messages for Removed plugins
-export function EleventyServerlessBundlerPlugin() {
- throw new Error(
- "Following feedback from our Community Survey, low interest in this plugin prompted its removal from Eleventy core in 3.0 as we refocus on static sites. Learn more: https://v3.11ty.dev/docs/plugins/serverless/",
- );
-}
-
-export { EleventyServerlessBundlerPlugin as EleventyServerless };
-
-export function EleventyEdgePlugin() {
- throw new Error(
- "Following feedback from our Community Survey, low interest in this plugin prompted its removal from Eleventy core in 3.0 as we refocus on static sites. Learn more: https://v3.11ty.dev/docs/plugins/edge/",
- );
-}
diff --git a/src/Engines/Custom.js b/src/Engines/Custom.js
index 4d28ac9bb..0bd86d7a7 100644
--- a/src/Engines/Custom.js
+++ b/src/Engines/Custom.js
@@ -11,7 +11,7 @@ export default class CustomEngine extends TemplateEngine {
this.setDefaultEngine(undefined);
this.previousQueue = [];
- this.config.events.on("eleventy#previousqueue", (filePaths) => {
+ this.config.events.on("buildawesome#previousqueue", (filePaths) => {
this.previousQueue = filePaths;
});
}
diff --git a/src/Engines/JavaScript.js b/src/Engines/JavaScript.js
index a8192d4b6..2f9e8e2fd 100644
--- a/src/Engines/JavaScript.js
+++ b/src/Engines/JavaScript.js
@@ -1,19 +1,19 @@
import { TemplatePath, isPlainObject } from "@11ty/eleventy-utils";
import TemplateEngine from "./TemplateEngine.js";
-import EleventyBaseError from "../Errors/EleventyBaseError.js";
+import BaseError from "../Errors/BaseError.js";
import getJavaScriptData from "../Util/GetJavaScriptData.js";
-import { EleventyImport } from "../Util/Require.js";
+import { DynamicImport } from "../Util/Require.js";
import { augmentFunction, augmentObject } from "./Util/ContextAugmenter.js";
-class JavaScriptTemplateNotDefined extends EleventyBaseError {}
+class JavaScriptTemplateNotDefined extends BaseError {}
export default class JavaScript extends TemplateEngine {
constructor(name, templateConfig) {
super(name, templateConfig);
this.instances = {};
- this.config.events.on("eleventy#templateModified", (inputPath, metadata = {}) => {
+ this.config.events.on("buildawesome#templatemodified", (inputPath, metadata = {}) => {
let { usedByDependants, relevantLayouts } = metadata;
// Remove from cached instances when modified
let instancesToDelete = [
@@ -117,7 +117,7 @@ export default class JavaScript extends TemplateEngine {
} else {
let isEsm = this.eleventyConfig.getIsProjectUsingEsm();
let cacheBust = !this.cacheable || !this.config.useTemplateCache;
- mod = await EleventyImport(inputPath, isEsm ? "esm" : "cjs", {
+ mod = await DynamicImport(inputPath, isEsm ? "esm" : "cjs", {
cacheBust,
});
}
@@ -180,6 +180,7 @@ export default class JavaScript extends TemplateEngine {
// Backwards compat
static wrapJavaScriptFunction(inst, fn) {
+ // TODO ArgumentHelper.wrapFilter(fn);
return augmentFunction(fn, {
source: inst,
});
diff --git a/src/Engines/Liquid.js b/src/Engines/Liquid.js
index 369467d6f..8cc0aed35 100644
--- a/src/Engines/Liquid.js
+++ b/src/Engines/Liquid.js
@@ -61,6 +61,8 @@ export default class Liquid extends TemplateEngine {
* @this {object}
*/
return function (...args) {
+ // TODO ArgumentHelper.wrapFilter(fn);
+
// Set this.eleventy and this.page
if (typeof this.context?.get === "function") {
augmentObject(this, {
@@ -327,6 +329,7 @@ export default class Liquid extends TemplateEngine {
{
page: data?.page,
eleventy: data?.eleventy,
+ buildawesome: data?.buildawesome,
collections: data?.collections,
},
liquidOptions?.globals,
diff --git a/src/Engines/Nunjucks.js b/src/Engines/Nunjucks.js
index c8b4fd6be..89c2c4922 100755
--- a/src/Engines/Nunjucks.js
+++ b/src/Engines/Nunjucks.js
@@ -1,4 +1,3 @@
-import { createDebug } from "obug";
import { TemplatePath } from "@11ty/eleventy-utils";
// Direct reference to avoid use of `browser` Nunjucks variant in bundles
@@ -9,12 +8,13 @@ import {
Template,
} from "@11ty/nunjucks/index.js";
import TemplateEngine from "./TemplateEngine.js";
-import EleventyBaseError from "../Errors/EleventyBaseError.js";
+import BaseError from "../Errors/BaseError.js";
import { augmentObject } from "./Util/ContextAugmenter.js";
+import { createDebug } from "../Util/DebugLogUtil.js";
-const debug = createDebug("Eleventy:Nunjucks");
+const debug = createDebug("Nunjucks");
-class EleventyNunjucksError extends EleventyBaseError {}
+class BuildAwesomeNunjucksError extends BaseError {}
export default class Nunjucks extends TemplateEngine {
constructor(name, eleventyConfig) {
@@ -76,7 +76,7 @@ export default class Nunjucks extends TemplateEngine {
this.njkEnv = new Environment(loaders, this.nunjucksEnvironmentOptions);
}
- this.config.events.emit("eleventy.engine.njk", {
+ this.config.events.emit("buildawesome.engine.njk", {
nunjucks: NunjucksLib,
environment: this.njkEnv,
});
@@ -87,7 +87,7 @@ export default class Nunjucks extends TemplateEngine {
// Note that a new Nunjucks engine instance is created for subsequent builds
// Eleventy Nunjucks is set to `cacheable` false above to opt out of Eleventy cache
- this.config.events.on("eleventy#templateModified", (templatePath) => {
+ this.config.events.on("buildawesome#templatemodified", (templatePath) => {
// NunjucksEnvironment:
// loader.pathToNames: {'ABSOLUTE_PATH/src/_includes/components/possum-home.css': 'components/possum-home.css'}
// loader.cache: { 'components/possum-home.css': [Template] }
@@ -152,7 +152,7 @@ export default class Nunjucks extends TemplateEngine {
return fn.call(this, ...args);
} catch (e) {
- throw new EleventyNunjucksError(
+ throw new BuildAwesomeNunjucksError(
`Error in Nunjucks Filter \`${name}\`${this.page ? ` (${this.page.inputPath})` : ""}`,
e,
);
@@ -257,7 +257,7 @@ export default class Nunjucks extends TemplateEngine {
// #3286 error messaging when the shortcode is not a promise
if (!ret?.then) {
resolve(
- new EleventyNunjucksError(
+ new BuildAwesomeNunjucksError(
`Error with Nunjucks shortcode \`${shortcodeName}\`: it was defined as asynchronous but was actually synchronous. This is important for Nunjucks.`,
),
);
@@ -269,7 +269,10 @@ export default class Nunjucks extends TemplateEngine {
},
function (e) {
resolve(
- new EleventyNunjucksError(`Error with Nunjucks shortcode \`${shortcodeName}\``, e),
+ new BuildAwesomeNunjucksError(
+ `Error with Nunjucks shortcode \`${shortcodeName}\``,
+ e,
+ ),
);
},
);
@@ -278,7 +281,7 @@ export default class Nunjucks extends TemplateEngine {
let ret = shortcodeFn.call(Nunjucks.normalizeContext(context), ...argArray);
return new NunjucksLib.runtime.SafeString("" + ret);
} catch (e) {
- throw new EleventyNunjucksError(
+ throw new BuildAwesomeNunjucksError(
`Error with Nunjucks shortcode \`${shortcodeName}\``,
e,
);
@@ -313,7 +316,7 @@ export default class Nunjucks extends TemplateEngine {
body(function (e, bodyContent) {
if (e) {
resolve(
- new EleventyNunjucksError(
+ new BuildAwesomeNunjucksError(
`Error with Nunjucks paired shortcode \`${shortcodeName}\``,
e,
),
@@ -328,7 +331,7 @@ export default class Nunjucks extends TemplateEngine {
// #3286 error messaging when the shortcode is not a promise
if (!ret?.then) {
- throw new EleventyNunjucksError(
+ throw new BuildAwesomeNunjucksError(
`Error with Nunjucks shortcode \`${shortcodeName}\`: it was defined as asynchronous but was actually synchronous. This is important for Nunjucks.`,
);
}
@@ -339,7 +342,7 @@ export default class Nunjucks extends TemplateEngine {
},
function (e) {
resolve(
- new EleventyNunjucksError(
+ new BuildAwesomeNunjucksError(
`Error with Nunjucks paired shortcode \`${shortcodeName}\``,
e,
),
@@ -371,7 +374,7 @@ export default class Nunjucks extends TemplateEngine {
shortcodeFn.call(Nunjucks.normalizeContext(context), bodyContent, ...argArray),
);
} catch (e) {
- throw new EleventyNunjucksError(
+ throw new BuildAwesomeNunjucksError(
`Error with Nunjucks paired shortcode \`${shortcodeName}\``,
e,
);
diff --git a/src/Engines/TemplateEngine.js b/src/Engines/TemplateEngine.js
index 1f72f6ac7..24bb72803 100644
--- a/src/Engines/TemplateEngine.js
+++ b/src/Engines/TemplateEngine.js
@@ -1,9 +1,9 @@
-import { createDebug } from "obug";
-import EleventyBaseError from "../Errors/EleventyBaseError.js";
+import { createDebug } from "../Util/DebugLogUtil.js";
+import BaseError from "../Errors/BaseError.js";
-class TemplateEngineConfigError extends EleventyBaseError {}
+class TemplateEngineConfigError extends BaseError {}
-const debug = createDebug("Eleventy:TemplateEngine");
+const debug = createDebug("TemplateEngine");
const AMENDED_INSTANCES = new Set();
diff --git a/src/Engines/TemplateEngineManager.js b/src/Engines/TemplateEngineManager.js
index 3ff6d0bbe..5deb542f0 100644
--- a/src/Engines/TemplateEngineManager.js
+++ b/src/Engines/TemplateEngineManager.js
@@ -1,14 +1,13 @@
-import { createDebug } from "obug";
-import EleventyBaseError from "../Errors/EleventyBaseError.js";
+import { createDebug } from "../Util/DebugLogUtil.js";
-const debug = createDebug("Eleventy:TemplateEngineManager");
+const debug = createDebug("TemplateEngineManager");
class TemplateEngineManager {
#CustomEngine;
constructor(eleventyConfig) {
if (!eleventyConfig || eleventyConfig.constructor.name !== "TemplateConfig") {
- throw new EleventyBaseError("Missing or invalid `config` argument.");
+ throw new Error("Internal error: missing or invalid `config` argument.");
}
this.eleventyConfig = eleventyConfig;
diff --git a/src/Engines/Util/ContextAugmenter.js b/src/Engines/Util/ContextAugmenter.js
index dd5fbc640..d5706861c 100644
--- a/src/Engines/Util/ContextAugmenter.js
+++ b/src/Engines/Util/ContextAugmenter.js
@@ -1,6 +1,8 @@
const DATA_KEYS = ["page", "eleventy"];
-function augmentFunction(fn, options = {}) {
+export { DATA_KEYS as augmentKeys };
+
+export function augmentFunction(fn, options = {}) {
let t = typeof fn;
if (t !== "function") {
throw new Error(
@@ -11,11 +13,12 @@ function augmentFunction(fn, options = {}) {
/** @this {object} */
return function (...args) {
let context = augmentObject(this || {}, options);
+
return fn.call(context, ...args);
};
}
-function augmentObject(targetObject, options = {}) {
+export function augmentObject(targetObject, options = {}) {
options = Object.assign(
{
source: undefined, // where to copy from
@@ -63,5 +66,3 @@ function augmentObject(targetObject, options = {}) {
return targetObject;
}
-
-export { DATA_KEYS as augmentKeys, augmentFunction, augmentObject };
diff --git a/src/Errors/EleventyBaseError.js b/src/Errors/BaseError.js
similarity index 88%
rename from src/Errors/EleventyBaseError.js
rename to src/Errors/BaseError.js
index daf7f35e9..5e16bc841 100644
--- a/src/Errors/EleventyBaseError.js
+++ b/src/Errors/BaseError.js
@@ -2,7 +2,7 @@
* This class serves as basis for all Eleventy-specific errors.
* @ignore
*/
-class EleventyBaseError extends Error {
+export default class BaseError extends Error {
/**
* @param {string} message - The error message to display.
* @param {unknown} [originalError] - The original error caught.
@@ -26,4 +26,3 @@ class EleventyBaseError extends Error {
}
}
}
-export default EleventyBaseError;
diff --git a/src/Errors/DuplicatePermalinkOutputError.js b/src/Errors/DuplicatePermalinkOutputError.js
index 444195c70..f5ed3493d 100644
--- a/src/Errors/DuplicatePermalinkOutputError.js
+++ b/src/Errors/DuplicatePermalinkOutputError.js
@@ -1,9 +1,7 @@
-import EleventyBaseError from "./EleventyBaseError.js";
+import BaseError from "./BaseError.js";
-class DuplicatePermalinkOutputError extends EleventyBaseError {
+export default class DuplicatePermalinkOutputError extends BaseError {
get removeDuplicateErrorStringFromOutput() {
return true;
}
}
-
-export default DuplicatePermalinkOutputError;
diff --git a/src/Errors/EleventyErrorHandler.js b/src/Errors/ErrorHandler.js
similarity index 73%
rename from src/Errors/EleventyErrorHandler.js
rename to src/Errors/ErrorHandler.js
index c747cba1f..fa59f5afa 100644
--- a/src/Errors/EleventyErrorHandler.js
+++ b/src/Errors/ErrorHandler.js
@@ -1,36 +1,23 @@
-import { createDebug } from "obug";
-
+import { createDebug } from "../Util/DebugLogUtil.js";
import { inspect } from "../Adapters/Packages/inspect.js";
import ConsoleLogger from "../Util/ConsoleLogger.js";
-import EleventyErrorUtil from "./EleventyErrorUtil.js";
-
-const debug = createDebug("Eleventy:EleventyErrorHandler");
+import ErrorUtil from "./ErrorUtil.js";
-class EleventyErrorHandler {
- constructor() {
- this._isVerbose = true;
- }
+const debug = createDebug("ErrorHandler");
- get isVerbose() {
- return this._isVerbose;
- }
-
- set isVerbose(verbose) {
- this._isVerbose = !!verbose;
- this.logger.isVerbose = !!verbose;
- }
+export class ErrorHandler {
+ #logger;
get logger() {
- if (!this._logger) {
- this._logger = new ConsoleLogger();
- this._logger.isVerbose = this.isVerbose;
+ if (!this.#logger) {
+ throw new Error("Internal error: missing logger instance.");
}
- return this._logger;
+ return this.#logger;
}
set logger(logger) {
- this._logger = logger;
+ this.#logger = logger;
}
warn(e, msg) {
@@ -80,7 +67,7 @@ class EleventyErrorHandler {
showStack = false;
}
- let totalErrorCount = EleventyErrorHandler.getTotalErrorCount(e);
+ let totalErrorCount = ErrorHandler.getTotalErrorCount(e);
let ref = e;
let index = 1;
let debugs = [];
@@ -92,8 +79,8 @@ class EleventyErrorHandler {
nextRef.originalError = nextRef.cause?.originalError ?? nextRef?.cause;
}
- if (!nextRef && EleventyErrorUtil.hasEmbeddedError(ref.message)) {
- nextRef = EleventyErrorUtil.deconvertErrorToObject(ref);
+ if (!nextRef && ErrorUtil.hasEmbeddedError(ref.message)) {
+ nextRef = ErrorUtil.deconvertErrorToObject(ref);
}
if (nextRef?.skipOriginalStack) {
@@ -102,7 +89,7 @@ class EleventyErrorHandler {
messages.push(
`${totalErrorCount > 1 ? `${index}. ` : ""}${(
- EleventyErrorUtil.cleanMessage(ref.message) || "(No error message provided)"
+ ErrorUtil.cleanMessage(ref.message) || "(No error message provided)"
).trim()}${ref.name !== "Error" ? ` (via ${ref.name})` : ""}`,
);
@@ -140,5 +127,3 @@ class EleventyErrorHandler {
}
}
}
-
-export { EleventyErrorHandler };
diff --git a/src/Errors/EleventyErrorUtil.js b/src/Errors/ErrorUtil.js
similarity index 65%
rename from src/Errors/EleventyErrorUtil.js
rename to src/Errors/ErrorUtil.js
index 6b374d01a..fa05498a6 100644
--- a/src/Errors/EleventyErrorUtil.js
+++ b/src/Errors/ErrorUtil.js
@@ -1,7 +1,7 @@
import TemplateContentPrematureUseError from "./TemplateContentPrematureUseError.js";
/* Hack to workaround the variety of error handling schemes in template languages */
-class EleventyErrorUtil {
+export default class ErrorUtil {
static get prefix() {
return ">>>>>11ty>>>>>";
}
@@ -14,7 +14,7 @@ class EleventyErrorUtil {
return false;
}
- return msg.includes(EleventyErrorUtil.prefix) && msg.includes(EleventyErrorUtil.suffix);
+ return msg.includes(ErrorUtil.prefix) && msg.includes(ErrorUtil.suffix);
}
static cleanMessage(msg) {
@@ -22,25 +22,25 @@ class EleventyErrorUtil {
return "";
}
- if (!EleventyErrorUtil.hasEmbeddedError(msg)) {
+ if (!ErrorUtil.hasEmbeddedError(msg)) {
return "" + msg;
}
- return msg.slice(0, Math.max(0, msg.indexOf(EleventyErrorUtil.prefix)));
+ return msg.slice(0, Math.max(0, msg.indexOf(ErrorUtil.prefix)));
}
static deconvertErrorToObject(error) {
if (!error || !error.message) {
throw new Error(`Could not convert error object from: ${error}`);
}
- if (!EleventyErrorUtil.hasEmbeddedError(error.message)) {
+ if (!ErrorUtil.hasEmbeddedError(error.message)) {
return error;
}
let msg = error.message;
let objectString = msg.substring(
- msg.indexOf(EleventyErrorUtil.prefix) + EleventyErrorUtil.prefix.length,
- msg.lastIndexOf(EleventyErrorUtil.suffix),
+ msg.indexOf(ErrorUtil.prefix) + ErrorUtil.prefix.length,
+ msg.lastIndexOf(ErrorUtil.suffix),
);
let obj = JSON.parse(objectString);
obj.name = error.name;
@@ -50,9 +50,9 @@ class EleventyErrorUtil {
// pass an error through a random template engine’s error handling unscathed
static convertErrorToString(error) {
return (
- EleventyErrorUtil.prefix +
+ ErrorUtil.prefix +
JSON.stringify({ message: error.message, stack: error.stack }) +
- EleventyErrorUtil.suffix
+ ErrorUtil.suffix
);
}
@@ -61,10 +61,9 @@ class EleventyErrorUtil {
return (
e instanceof TemplateContentPrematureUseError ||
e?.cause instanceof TemplateContentPrematureUseError || // Custom (per Node-convention)
- ["RenderError", "UndefinedVariableError"].includes(e?.originalError?.name) && e?.originalError?.originalError instanceof TemplateContentPrematureUseError || // Liquid
+ (["RenderError", "UndefinedVariableError"].includes(e?.originalError?.name) &&
+ e?.originalError?.originalError instanceof TemplateContentPrematureUseError) || // Liquid
e?.message?.includes("TemplateContentPrematureUseError") // Nunjucks
);
}
}
-
-export default EleventyErrorUtil;
diff --git a/src/Errors/TemplateContentPrematureUseError.js b/src/Errors/TemplateContentPrematureUseError.js
index 5266cd271..11fe2018d 100644
--- a/src/Errors/TemplateContentPrematureUseError.js
+++ b/src/Errors/TemplateContentPrematureUseError.js
@@ -1,5 +1,3 @@
-import EleventyBaseError from "./EleventyBaseError.js";
+import BaseError from "./BaseError.js";
-class TemplateContentPrematureUseError extends EleventyBaseError {}
-
-export default TemplateContentPrematureUseError;
+export default class TemplateContentPrematureUseError extends BaseError {}
diff --git a/src/Errors/TemplateContentUnrenderedTemplateError.js b/src/Errors/TemplateContentUnrenderedTemplateError.js
index ee270d5de..f032cbc52 100644
--- a/src/Errors/TemplateContentUnrenderedTemplateError.js
+++ b/src/Errors/TemplateContentUnrenderedTemplateError.js
@@ -1,5 +1,3 @@
-import EleventyBaseError from "./EleventyBaseError.js";
+import BaseError from "./BaseError.js";
-class TemplateContentUnrenderedTemplateError extends EleventyBaseError {}
-
-export default TemplateContentUnrenderedTemplateError;
+export default class TemplateContentUnrenderedTemplateError extends BaseError {}
diff --git a/src/Errors/UsingCircularTemplateContentReferenceError.js b/src/Errors/UsingCircularTemplateContentReferenceError.js
index 5608febb3..b4660e721 100644
--- a/src/Errors/UsingCircularTemplateContentReferenceError.js
+++ b/src/Errors/UsingCircularTemplateContentReferenceError.js
@@ -1,5 +1,3 @@
-import EleventyBaseError from "./EleventyBaseError.js";
+import BaseError from "./BaseError.js";
-class UsingCircularTemplateContentReferenceError extends EleventyBaseError {}
-
-export default UsingCircularTemplateContentReferenceError;
+export default class UsingCircularTemplateContentReferenceError extends BaseError {}
diff --git a/src/EventBus.js b/src/EventBus.js
index 127f5697d..9edeb70b9 100644
--- a/src/EventBus.js
+++ b/src/EventBus.js
@@ -1,8 +1,7 @@
-import { createDebug } from "obug";
-
+import { createDebug } from "./Util/DebugLogUtil.js";
import EventEmitter from "./Util/AsyncEventEmitter.js";
-const debug = createDebug("Eleventy:EventBus");
+const debug = createDebug("EventBus");
/**
* @module 11ty/eleventy/EventBus
diff --git a/src/EleventyExtensionMap.js b/src/ExtensionMap.js
similarity index 92%
rename from src/EleventyExtensionMap.js
rename to src/ExtensionMap.js
index 051dc7547..0be6b2653 100644
--- a/src/EleventyExtensionMap.js
+++ b/src/ExtensionMap.js
@@ -1,8 +1,8 @@
import { TemplatePath } from "@11ty/eleventy-utils";
-import { isTypeScriptSupported } from "./Util/FeatureTests.cjs";
+import { isTypeScriptSupported } from "./Util/TypeScriptFeatureTest.cjs";
-class EleventyExtensionMap {
+export default class ExtensionMap {
#engineManager;
constructor(config) {
@@ -42,7 +42,7 @@ class EleventyExtensionMap {
get engineManager() {
if (!this.#engineManager) {
- throw new Error("Internal error: Missing `#engineManager` in EleventyExtensionMap.");
+ throw new Error("Internal error: Missing `#engineManager` in ExtensionMap.");
}
return this.#engineManager;
@@ -262,12 +262,21 @@ class EleventyExtensionMap {
html: { key: "html", extension: "html" },
njk: { key: "njk", extension: "njk" },
liquid: { key: "liquid", extension: "liquid" },
+
+ "server.js": { key: "11ty.js", extension: "server.js" },
+ "server.cjs": { key: "11ty.js", extension: "server.cjs" },
+ "server.mjs": { key: "11ty.js", extension: "server.mjs" },
+
"11ty.js": { key: "11ty.js", extension: "11ty.js" },
"11ty.cjs": { key: "11ty.js", extension: "11ty.cjs" },
"11ty.mjs": { key: "11ty.js", extension: "11ty.mjs" },
};
if (isTypeScriptSupported()) {
+ this._extensionToKeyMap["server.ts"] = { key: "11ty.js", extension: "server.ts" };
+ this._extensionToKeyMap["server.cts"] = { key: "11ty.js", extension: "server.cts" };
+ this._extensionToKeyMap["server.mts"] = { key: "11ty.js", extension: "server.mts" };
+
this._extensionToKeyMap["11ty.ts"] = { key: "11ty.js", extension: "11ty.ts" };
this._extensionToKeyMap["11ty.cts"] = { key: "11ty.js", extension: "11ty.cts" };
this._extensionToKeyMap["11ty.mts"] = { key: "11ty.js", extension: "11ty.mts" };
@@ -288,5 +297,3 @@ class EleventyExtensionMap {
return Object.keys(this.extensionToKeyMap).join(" ");
}
}
-
-export default EleventyExtensionMap;
diff --git a/src/FileSystemSearch.js b/src/FileSystemSearch.js
index efc8ea1db..5bda2474e 100644
--- a/src/FileSystemSearch.js
+++ b/src/FileSystemSearch.js
@@ -1,11 +1,11 @@
import { glob } from "tinyglobby";
import { TemplatePath } from "@11ty/eleventy-utils";
-import { createDebug } from "obug";
+import { createDebug } from "./Util/DebugLogUtil.js";
import GlobRemap from "./Util/GlobRemap.js";
import { isGlobMatch } from "./Util/GlobMatcher.js";
-const debug = createDebug("Eleventy:FileSystemSearch");
+const debug = createDebug("FileSystemSearch");
class FileSystemSearch {
constructor() {
diff --git a/src/EleventyFiles.js b/src/Files.js
similarity index 95%
rename from src/EleventyFiles.js
rename to src/Files.js
index 69d438100..99bda06c7 100644
--- a/src/EleventyFiles.js
+++ b/src/Files.js
@@ -1,16 +1,16 @@
import { statSync, readFileSync } from "node:fs";
import { TemplatePath } from "@11ty/eleventy-utils";
-import { createDebug } from "obug";
+import { createDebug } from "./Util/DebugLogUtil.js";
import DirContains from "./Util/DirContains.js";
import TemplateData from "./Data/TemplateData.js";
import TemplateGlob from "./TemplateGlob.js";
import checkPassthroughCopyBehavior from "./Util/PassthroughCopyBehaviorCheck.js";
-const debug = createDebug("Eleventy:EleventyFiles");
+const debug = createDebug("Files");
-class EleventyFiles {
+export class Files {
#extensionMap;
#watcherGlobs;
@@ -158,7 +158,7 @@ class EleventyFiles {
// Conditional added for tests that don’t have a config
if (this.config?.events) {
- this.config.events.emit("eleventy.ignores", this.uniqueIgnores);
+ this.config.events.emit("buildawesome.ignores", this.uniqueIgnores);
}
this.normalizedTemplateGlobs = this.templateGlobs;
@@ -228,7 +228,9 @@ class EleventyFiles {
">>> 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.");
+ debug(
+ "Follow along at https://github.com/11ty/buildawesome/issues/693 to track support.",
+ );
}
// empty lines or comments get filtered out
@@ -401,17 +403,17 @@ class EleventyFiles {
}
/* For `eleventy --watch` */
- async getGlobWatcherTemplateDataFiles() {
- let templateData = this.templateData;
- return await templateData.getTemplateDataFileGlob();
+ getGlobWatcherTemplateDataFiles() {
+ return this.templateData.getTemplateDataFileGlob();
}
/* For `eleventy --watch` */
- // TODO this isn’t great but reduces complexity avoiding using TemplateData:getLocalDataPaths for each template in the cache
+ // Improvement: Move this up the pipeline and feed into the ExistsCache to alleviate TemplateData checks
async getWatcherTemplateJavaScriptDataFiles() {
let globs = 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: [
@@ -423,6 +425,7 @@ class EleventyFiles {
}),
);
bench.after();
+
return results;
}
@@ -459,5 +462,3 @@ class EleventyFiles {
});
}
}
-
-export default EleventyFiles;
diff --git a/src/GlobalDependencyMap.js b/src/GlobalDependencyMap.js
index e6be20ac4..374599b50 100644
--- a/src/GlobalDependencyMap.js
+++ b/src/GlobalDependencyMap.js
@@ -1,11 +1,11 @@
-import { createDebug } from "obug";
import { TemplatePath } from "@11ty/eleventy-utils";
+import { createDebug } from "./Util/DebugLogUtil.js";
import JavaScriptDependencies from "./Util/JavaScriptDependencies.js";
import PathNormalizer from "./Util/PathNormalizer.js";
import { TemplateDepGraph } from "./Util/TemplateDepGraph.js";
-const debug = createDebug("Eleventy:Dependencies");
+const debug = createDebug("Dependencies");
class GlobalDependencyMap {
// dependency-graph requires these keys to be alphabetic strings
diff --git a/src/LayoutCache.js b/src/LayoutCache.js
index 006f502d0..48142e982 100644
--- a/src/LayoutCache.js
+++ b/src/LayoutCache.js
@@ -89,7 +89,7 @@ class LayoutCache {
let layoutCache = new LayoutCache();
-eventBus.on("eleventy.resourceModified", () => {
+eventBus.on("buildawesome.resourceModified", () => {
// https://github.com/11ty/eleventy-plugin-bundle/issues/10
layoutCache.removeAll();
});
diff --git a/src/Plugins/I18nPlugin.js b/src/Plugins/I18nPlugin.js
index 6d48c633a..66c3d56d0 100644
--- a/src/Plugins/I18nPlugin.js
+++ b/src/Plugins/I18nPlugin.js
@@ -174,13 +174,13 @@ function I18nPlugin(eleventyConfig, opts = {}) {
}
let extensionMap;
- eleventyConfig.on("eleventy.extensionmap", (map) => {
+ eleventyConfig.on("buildawesome.extensionmap", (map) => {
extensionMap = map;
});
let bench = eleventyConfig.benchmarkManager.get("Aggregate");
let contentMaps = {};
- eleventyConfig.on("eleventy.contentMap", function ({ urlToInputPath, inputPathToUrl }) {
+ eleventyConfig.on("buildawesome.contentmap", function ({ urlToInputPath, inputPathToUrl }) {
let b = bench.get("(i18n Plugin) Setting up content map.");
b.before();
contentMaps.inputPathToUrl = inputPathToUrl;
diff --git a/src/Plugins/IdAttributePlugin.js b/src/Plugins/IdAttributePlugin.js
index c8d165b17..f525f5cd7 100644
--- a/src/Plugins/IdAttributePlugin.js
+++ b/src/Plugins/IdAttributePlugin.js
@@ -1,12 +1,15 @@
import matchHelper from "posthtml-match-helper";
import { decodeHTML } from "entities";
-const POSTHTML_PLUGIN_NAME = "11ty/eleventy/id-attribute";
+import { resolveAttributeName } from "../Util/PostHtml/Attrs.js";
+
+const POSTHTML_PLUGIN_NAME = "awesome.me/buildawesome/id-attribute";
function getTextNodeContent(node) {
- let ignoredAttr = node.attrs?.["eleventy:id-ignore"];
- if (ignoredAttr === "" || ignoredAttr === true) {
- delete node.attrs["eleventy:id-ignore"];
+ let ignoredAttrName = resolveAttributeName(node.attrs, "buildawesome:id-ignore");
+
+ if (ignoredAttrName !== undefined) {
+ delete node.attrs[ignoredAttrName];
return "";
}
if (!node.content) {
diff --git a/src/Plugins/InputPathToUrl.js b/src/Plugins/InputPathToUrl.js
index 1878a0d6d..4aee918e1 100644
--- a/src/Plugins/InputPathToUrl.js
+++ b/src/Plugins/InputPathToUrl.js
@@ -84,7 +84,7 @@ function parseFilePath(filepath) {
function FilterPlugin(eleventyConfig) {
let contentMap;
- eleventyConfig.on("eleventy.contentMap", function ({ inputPathToUrl }) {
+ eleventyConfig.on("buildawesome.contentmap", function ({ inputPathToUrl }) {
contentMap = inputPathToUrl;
});
@@ -130,7 +130,7 @@ function TransformPlugin(eleventyConfig, defaultOptions = {}) {
);
let contentMap = null;
- eleventyConfig.on("eleventy.contentMap", function ({ inputPathToUrl }) {
+ eleventyConfig.on("buildawesome.contentmap", function ({ inputPathToUrl }) {
contentMap = inputPathToUrl;
});
diff --git a/src/Plugins/Pagination.js b/src/Plugins/Pagination.js
index da2f51fb8..1a217c454 100755
--- a/src/Plugins/Pagination.js
+++ b/src/Plugins/Pagination.js
@@ -2,17 +2,19 @@ import { isPlainObject } from "@11ty/eleventy-utils";
import lodash from "@11ty/lodash-custom";
import { DeepCopy } from "@11ty/eleventy-utils";
-import EleventyBaseError from "../Errors/EleventyBaseError.js";
+import BaseError from "../Errors/BaseError.js";
import { ProxyWrap } from "../Util/Objects/ProxyWrap.js";
// import { DeepFreeze } from "../Util/Objects/DeepFreeze.js";
import TemplateData from "../Data/TemplateData.js";
const { set: lodashSet, get: lodashGet, chunk: lodashChunk } = lodash;
-class PaginationConfigError extends EleventyBaseError {}
-class PaginationError extends EleventyBaseError {}
+class PaginationConfigError extends BaseError {}
+class PaginationError extends BaseError {}
class Pagination {
+ static NOT_FOUND_VALUE = "__NOT_FOUND_ERROR__";
+
constructor(tmpl, data, config) {
if (!config) {
throw new PaginationConfigError("Expected `config` argument to Pagination class.");
@@ -113,15 +115,13 @@ class Pagination {
}
_has(target, key) {
- let notFoundValue = "__NOT_FOUND_ERROR__";
- let data = lodashGet(target, key, notFoundValue);
- return data !== notFoundValue;
+ let data = lodashGet(target, key, Pagination.NOT_FOUND_VALUE);
+ return data !== Pagination.NOT_FOUND_VALUE;
}
_get(target, key) {
- let notFoundValue = "__NOT_FOUND_ERROR__";
- let data = lodashGet(target, key, notFoundValue);
- if (data === notFoundValue) {
+ let data = lodashGet(target, key, Pagination.NOT_FOUND_VALUE);
+ if (data === Pagination.NOT_FOUND_VALUE) {
throw new Error(
`Could not find pagination data${this.inputPathForErrorMessages}, went looking for: ${key}`,
);
@@ -349,7 +349,6 @@ class Pagination {
// page.url and page.outputPath are used to avoid another getOutputLocations call later, see Template->addComputedData
clonedData.page.url = href;
clonedData.page.outputPath = path;
- clonedData.page.dir = dir;
entries.push({
pageNumber,
diff --git a/src/Plugins/RenderPlugin.js b/src/Plugins/RenderPlugin.js
index 3004ccf12..8a2253e58 100644
--- a/src/Plugins/RenderPlugin.js
+++ b/src/Plugins/RenderPlugin.js
@@ -4,16 +4,16 @@ import { Merge, TemplatePath, isPlainObject } from "@11ty/eleventy-utils";
// TODO add a first-class Markdown component to expose this using Markdown-only syntax (will need to be synchronous for markdown-it)
import { ProxyWrap } from "../Util/Objects/ProxyWrap.js";
-import TemplateDataInitialGlobalData from "../Data/TemplateDataInitialGlobalData.js";
-import EleventyBaseError from "../Errors/EleventyBaseError.js";
+import ConfigurationGlobalData from "../Data/ConfigurationGlobalData.js";
+import BaseError from "../Errors/BaseError.js";
import TemplateRender from "../TemplateRender.js";
import ProjectDirectories from "../Util/ProjectDirectories.js";
import TemplateConfig from "../TemplateConfig.js";
-import EleventyExtensionMap from "../EleventyExtensionMap.js";
+import ExtensionMap from "../ExtensionMap.js";
import TemplateEngineManager from "../Engines/TemplateEngineManager.js";
import Liquid from "../Adapters/Engines/Liquid.js";
-class EleventyNunjucksError extends EleventyBaseError {}
+class NunjucksError extends BaseError {}
/** @this {object} */
async function compile(content, templateLang, options = {}) {
@@ -35,7 +35,7 @@ async function compile(content, templateLang, options = {}) {
if (strictMode) {
throw new Error("Internal error: missing `extensionMap` in RenderPlugin->compile.");
}
- extensionMap = new EleventyExtensionMap(templateConfig);
+ extensionMap = new ExtensionMap(templateConfig);
extensionMap.engineManager = new TemplateEngineManager(templateConfig);
}
let tr = new TemplateRender(templateLang, templateConfig);
@@ -99,7 +99,7 @@ async function compileFile(inputPath, options = {}, templateLang) {
throw new Error("Internal error: missing `extensionMap` in RenderPlugin->compileFile.");
}
- extensionMap = new EleventyExtensionMap(templateConfig);
+ extensionMap = new ExtensionMap(templateConfig);
extensionMap.engineManager = new TemplateEngineManager(templateConfig);
}
let tr = new TemplateRender(inputPath, templateConfig);
@@ -144,6 +144,7 @@ async function renderShortcodeFn(fn, data) {
// save `page` and `eleventy` for reuse
data.page = this.page;
data.eleventy = this.eleventy;
+ data.buildawesome = this.buildawesome;
}
return fn(data);
@@ -158,17 +159,17 @@ async function renderShortcodeFn(fn, data) {
* string (or file) inside of another template. {@link https://v3.11ty.dev/docs/plugins/render/}
*
* @since 1.0.0
- * @param {module:11ty/eleventy/UserConfig} eleventyConfig - User-land configuration instance.
+ * @param {module:11ty/eleventy/UserConfig} $config - User-land configuration instance.
* @param {object} options - Plugin options
*/
-function RenderPlugin(eleventyConfig, options = {}) {
+function RenderPlugin($config, options = {}) {
let templateConfig;
- eleventyConfig.on("eleventy.config", (tmplConfigInstance) => {
+ $config.on("buildawesome.config", (tmplConfigInstance) => {
templateConfig = tmplConfigInstance;
});
let extensionMap;
- eleventyConfig.on("eleventy.extensionmap", (map) => {
+ $config.on("buildawesome.extensionmap", (map) => {
extensionMap = map;
});
@@ -193,7 +194,7 @@ function RenderPlugin(eleventyConfig, options = {}) {
parse: function (tagToken, remainTokens) {
this.name = tagToken.name;
- if (eleventyConfig.liquid.parameterParsing === "builtin") {
+ if ($config.liquid.parameterParsing === "builtin") {
this.orderedArgs = Liquid.parseArgumentsBuiltin(tagToken.args);
// note that Liquid does have a Hash class for name-based argument parsing but offers no easy to support both modes in one class
} else {
@@ -224,6 +225,7 @@ function RenderPlugin(eleventyConfig, options = {}) {
normalizedContext.page = ctx.get(["page"]);
normalizedContext.eleventy = ctx.get(["eleventy"]);
+ normalizedContext.buildawesome = ctx.get(["buildawesome"]);
}
let argArray = [];
@@ -324,13 +326,12 @@ function RenderPlugin(eleventyConfig, options = {}) {
normalizedContext.page = context.ctx.page;
normalizedContext.eleventy = context.ctx.eleventy;
+ normalizedContext.buildawesome = context.ctx.buildawesome;
}
body(function (e, bodyContent) {
if (e) {
- resolve(
- new EleventyNunjucksError(`Error with Nunjucks paired shortcode \`${tagName}\``, e),
- );
+ resolve(new NunjucksError(`Error with Nunjucks paired shortcode \`${tagName}\``, e));
}
Promise.resolve(
@@ -346,7 +347,7 @@ function RenderPlugin(eleventyConfig, options = {}) {
},
function (e) {
resolve(
- new EleventyNunjucksError(`Error with Nunjucks paired shortcode \`${tagName}\``, e),
+ new NunjucksError(`Error with Nunjucks paired shortcode \`${tagName}\``, e),
null,
);
},
@@ -388,26 +389,26 @@ function RenderPlugin(eleventyConfig, options = {}) {
// Render strings
if (options.tagName) {
// use falsy to opt-out
- eleventyConfig.addJavaScriptFunction(options.tagName, _renderStringShortcodeFn);
+ $config.addJavaScriptFunction(options.tagName, _renderStringShortcodeFn);
- eleventyConfig.addLiquidTag(options.tagName, function (liquidEngine, extras) {
+ $config.addLiquidTag(options.tagName, function (liquidEngine, extras) {
return liquidTemplateTag(liquidEngine, options.tagName, extras);
});
- eleventyConfig.addNunjucksTag(options.tagName, function (nunjucksLib) {
+ $config.addNunjucksTag(options.tagName, function (nunjucksLib) {
return nunjucksTemplateTag(nunjucksLib, options.tagName);
});
}
// Filter for rendering strings
if (options.filterName) {
- eleventyConfig.addAsyncFilter(options.filterName, _renderStringShortcodeFn);
+ $config.addAsyncFilter(options.filterName, _renderStringShortcodeFn);
}
// Render File
// use `false` to opt-out
if (options.tagNameFile) {
- eleventyConfig.addAsyncShortcode(options.tagNameFile, _renderFileShortcodeFn);
+ $config.addAsyncShortcode(options.tagNameFile, _renderFileShortcodeFn);
}
}
@@ -440,7 +441,7 @@ class RenderManager {
accessGlobalData: true,
});
- this.#extensionMap = new EleventyExtensionMap(this.#templateConfig);
+ this.#extensionMap = new ExtensionMap(this.#templateConfig);
this.#extensionMap.engineManager = new TemplateEngineManager(this.#templateConfig);
}
@@ -459,7 +460,7 @@ class RenderManager {
// `callback` is async-friendly but requires await upstream
config(callback) {
- // run an extra `function(eleventyConfig)` configuration callbacks
+ // run an extra `function($config)` configuration callbacks
if (callback && typeof callback === "function") {
return callback(this.templateConfig.userConfig);
}
@@ -467,7 +468,7 @@ class RenderManager {
get initialGlobalData() {
if (!this._data) {
- this._data = new TemplateDataInitialGlobalData(this.templateConfig);
+ this._data = new ConfigurationGlobalData(this.templateConfig);
}
return this._data;
}
diff --git a/src/EleventyCommonJs.cjs b/src/RequireEsmFeatureTest.cjs
similarity index 97%
rename from src/EleventyCommonJs.cjs
rename to src/RequireEsmFeatureTest.cjs
index 5191bc144..66422f50e 100644
--- a/src/EleventyCommonJs.cjs
+++ b/src/RequireEsmFeatureTest.cjs
@@ -38,6 +38,6 @@ if(!canRequireModules()) {
}
// If we made it here require(ESM) works fine (via --experimental-require-module or newer Node.js defaults)
-let mod = require("./Eleventy.js");
+let mod = require("./Core.js");
module.exports = mod;
diff --git a/src/EleventyServe.js b/src/Serve.js
similarity index 80%
rename from src/EleventyServe.js
rename to src/Serve.js
index 9531af975..3212c0620 100644
--- a/src/EleventyServe.js
+++ b/src/Serve.js
@@ -1,4 +1,3 @@
-import { createDebug } from "obug";
import { Merge, TemplatePath } from "@11ty/eleventy-utils";
import { Watch } from "./Watch.js";
@@ -13,17 +12,18 @@ function stringifyOptions(options) {
});
}
-import EleventyBaseError from "./Errors/EleventyBaseError.js";
+import BaseError from "./Errors/BaseError.js";
+import { createDebug } from "./Util/DebugLogUtil.js";
import ConsoleLogger from "./Util/ConsoleLogger.js";
import PathPrefixer from "./Util/PathPrefixer.js";
import checkPassthroughCopyBehavior from "./Util/PassthroughCopyBehaviorCheck.js";
import { getModulePackageJson } from "./Util/ImportJsonSync.js";
-import { EleventyImport } from "./Util/Require.js";
+import { DynamicImport } from "./Util/Require.js";
import { isGlobMatch } from "./Util/GlobMatcher.js";
-const debug = createDebug("Eleventy:EleventyServe");
+const debug = createDebug("Serve");
-class EleventyServeConfigError extends EleventyBaseError {}
+class ServeConfigError extends BaseError {}
const DEFAULT_SERVER_OPTIONS = {
module: "@11ty/eleventy-dev-server",
@@ -31,10 +31,11 @@ const DEFAULT_SERVER_OPTIONS = {
// pathPrefix: "/",
// setup: function() {},
// ready: function(server) {},
- // logger: { info: function() {}, error: function() {} }
+ // logger: { log: function() {}, info: function() {}, error: function() {} }
};
-class EleventyServe {
+export default class Serve {
+ #options;
#eleventyConfig;
#savedConfigOptions;
#aliases;
@@ -42,23 +43,18 @@ class EleventyServe {
#chokidar;
// these are *not* normalized
#watchTargets = new Set();
-
- constructor() {
- this.logger = new ConsoleLogger();
- }
+ #logger;
get config() {
if (!this.eleventyConfig) {
- throw new EleventyServeConfigError(
- "You need to set the eleventyConfig property on EleventyServe.",
- );
+ throw new ServeConfigError("You need to set the eleventyConfig property on Serve.");
}
return this.eleventyConfig.getConfig();
}
set config(config) {
- throw new Error("It’s not allowed to set config on EleventyServe. Set eleventyConfig instead.");
+ throw new Error("It’s not allowed to set config on Serve. Set eleventyConfig instead.");
}
setAliases(aliases) {
@@ -71,9 +67,7 @@ class EleventyServe {
get eleventyConfig() {
if (!this.#eleventyConfig) {
- throw new EleventyServeConfigError(
- "You need to set the eleventyConfig property on EleventyServe.",
- );
+ throw new ServeConfigError("You need to set the eleventyConfig property on Serve.");
}
return this.#eleventyConfig;
@@ -83,13 +77,25 @@ class EleventyServe {
this.#eleventyConfig = config;
if (checkPassthroughCopyBehavior(this.#eleventyConfig.userConfig, "serve")) {
- this.#eleventyConfig.userConfig.events.on("eleventy.passthrough", ({ map }) => {
+ this.#eleventyConfig.userConfig.events.on("buildawesome.passthrough", ({ map }) => {
// for-free passthrough copy
this.setAliases(map);
});
}
}
+ get logger() {
+ if (!this.#logger) {
+ throw new Error("Internal error: missing ConsoleLogger instance.");
+ }
+
+ return this.#logger;
+ }
+
+ set logger(logger) {
+ this.#logger = logger;
+ }
+
// TODO directorynorm
setOutputDir(outputDir) {
// TODO check if this is different and if so, restart server (if already running)
@@ -106,7 +112,7 @@ class EleventyServe {
async getServerModule(name) {
try {
if (!name || name === DEFAULT_SERVER_OPTIONS.module) {
- return EleventyServe.getDevServer();
+ return Serve.getDevServer();
}
// Look for peer dep in local project
@@ -133,7 +139,7 @@ class EleventyServe {
}
}
- let module = await EleventyImport(serverPath);
+ let module = await DynamicImport(serverPath);
if (!("getServer" in module)) {
throw new Error(
@@ -157,19 +163,40 @@ class EleventyServe {
);
debug("Eleventy server error %o", e);
- return EleventyServe.getDevServer();
+ return Serve.getDevServer();
}
}
+ getForcedOutputLogger() {
+ // Server logging overrides verbose values.
+ return {
+ log: (message) => {
+ return this.logger.logWithOptions({ message, force: true });
+ },
+ info: (message) => {
+ return this.logger.logWithOptions({ message, type: "info", force: true });
+ },
+ warn: (message) => {
+ return this.logger.logWithOptions({ message, type: "warn", force: true });
+ },
+ error: (message) => {
+ return this.logger.logWithOptions({ message, type: "error", force: true });
+ },
+ };
+ }
+
get options() {
- if (this._options) {
- return this._options;
+ if (this.#options) {
+ return this.#options;
}
- this._options = Object.assign(
+ this.#options = Object.assign(
{
pathPrefix: PathPrefixer.normalizePathPrefix(this.config.pathPrefix),
- logger: this.logger,
+ logger: this.getForcedOutputLogger(),
+ onClientMessage: async ({ id, type, data, timestamp }) => {
+ // do nothing
+ },
},
DEFAULT_SERVER_OPTIONS,
this.config.serverOptions,
@@ -183,7 +210,7 @@ class EleventyServe {
);
}
- return this._options;
+ return this.#options;
}
get server() {
@@ -296,7 +323,7 @@ class EleventyServe {
// we can correctly handle a `module` property change (changing the server type)
async restart() {
// Blow away cached options
- delete this._options;
+ this.#options = undefined;
await this.close();
@@ -304,7 +331,7 @@ class EleventyServe {
await this.serve(this._commandLinePort);
}
- // checkPassthroughCopyBehavior check is called upstream in Eleventy.js
+ // checkPassthroughCopyBehavior check is called upstream in Core.js
watchPassthroughCopy(globs = []) {
for (let glob of globs) {
this.#watchTargets.add(glob);
@@ -341,5 +368,3 @@ class EleventyServe {
}
}
}
-
-export default EleventyServe;
diff --git a/src/Template.js b/src/Template.js
index c6e3a1c79..d60d80277 100755
--- a/src/Template.js
+++ b/src/Template.js
@@ -3,10 +3,10 @@ import { statSync } from "node:fs";
import lodash from "@11ty/lodash-custom";
import { Merge, TemplatePath, isPlainObject } from "@11ty/eleventy-utils";
-import { createDebug } from "obug";
import chalk from "./Adapters/Packages/chalk.js";
import ConsoleLogger from "./Util/ConsoleLogger.js";
+import { createDebug } from "./Util/DebugLogUtil.js";
import { getCreatedTimestamp, getUpdatedTimestamp } from "./Util/Git.js";
import TemplateContent from "./TemplateContent.js";
import TemplatePermalink from "./TemplatePermalink.js";
@@ -17,30 +17,32 @@ import Pagination from "./Plugins/Pagination.js";
import TemplateBehavior from "./TemplateBehavior.js";
import TemplateContentPrematureUseError from "./Errors/TemplateContentPrematureUseError.js";
import TemplateContentUnrenderedTemplateError from "./Errors/TemplateContentUnrenderedTemplateError.js";
-import EleventyBaseError from "./Errors/EleventyBaseError.js";
+import BaseError from "./Errors/BaseError.js";
import { fromISOtoDateUTC } from "./Util/DateParse.js";
import ReservedData from "./Util/ReservedData.js";
import TransformsUtil from "./Util/TransformsUtil.js";
-import { FileSystemManager } from "./Util/FileSystemManager.js";
+import { FileSystemUtilities } from "./Util/FileSystemUtilities.js";
import { TemplatePreprocessors } from "./TemplatePreprocessors.js";
-import PathNormalizer from "./Util/PathNormalizer.js";
import { getDirectoryFromUrl } from "./Util/UrlUtil.js";
+import { ResolveConfigurationData } from "./Data/ResolveConfigurationData.js";
const { set: lodashSet, get: lodashGet } = lodash;
-const debug = createDebug("Eleventy:Template");
-const debugDev = createDebug("Dev:Eleventy:Template");
+const debug = createDebug("Template");
class Template extends TemplateContent {
#logger;
#fsManager;
#stats;
#dataCache;
+
+ #cacheRenderedPromise;
+ #cacheRenderedTransformsAndLayoutsPromise;
+ #cacheRenderedDataLocationsTransformsAndLayoutsPromise;
#preprocessors;
#preprocessorCache;
constructor(templatePath, templateData, extensionMap, config) {
- debugDev("new Template(%o)", templatePath);
super(templatePath, config);
this.parsed = parse(templatePath);
@@ -55,7 +57,6 @@ class Template extends TemplateContent {
this.linters = [];
this.transforms = {};
- this.isVerbose = true;
this.isDryRun = false;
this.writeCount = 0;
@@ -86,15 +87,14 @@ class Template extends TemplateContent {
get fsManager() {
if (!this.#fsManager) {
- this.#fsManager = new FileSystemManager(this.eleventyConfig);
+ this.#fsManager = new FileSystemUtilities(this.eleventyConfig);
}
return this.#fsManager;
}
get logger() {
if (!this.#logger) {
- this.#logger = new ConsoleLogger();
- this.#logger.isVerbose = this.isVerbose;
+ throw new Error("Internal error: missing ConsoleLogger instance.");
}
return this.#logger;
}
@@ -140,8 +140,9 @@ class Template extends TemplateContent {
super.resetCaches(types);
if (types.render) {
- delete this._cacheRenderedPromise;
- delete this._cacheRenderedTransformsAndLayoutsPromise;
+ this.#cacheRenderedPromise = undefined;
+ this.#cacheRenderedTransformsAndLayoutsPromise = undefined;
+ this.#cacheRenderedDataLocationsTransformsAndLayoutsPromise = undefined;
}
}
@@ -150,11 +151,6 @@ class Template extends TemplateContent {
this.behavior.setOutputFormat(to);
}
- setIsVerbose(isVerbose) {
- this.isVerbose = isVerbose;
- this.logger.isVerbose = isVerbose;
- }
-
setDryRunViaIncremental(isIncremental) {
this.isDryRun = isIncremental;
this.isIncremental = isIncremental;
@@ -195,7 +191,7 @@ class Template extends TemplateContent {
try {
return TemplateLayout.getTemplate(layoutKey, this.eleventyConfig, this.extensionMap);
} catch (e) {
- throw new EleventyBaseError(
+ throw new BaseError(
`Problem creating an Eleventy Layout for the "${this.inputPath}" template file.`,
e,
);
@@ -211,9 +207,10 @@ class Template extends TemplateContent {
throw new Error("Internal error: data argument missing in Template->_getLink");
}
+ let computedData = ResolveConfigurationData.getValue(data, this.config.keys.computed);
let permalink =
- data[this.config.keys.permalink] ??
- data?.[this.config.keys.computed]?.[this.config.keys.permalink];
+ ResolveConfigurationData.getValue(data, this.config.keys.permalink) ??
+ ResolveConfigurationData.getValue(computedData, this.config.keys.permalink);
let permalinkValue;
let isDynamicPermalinkEnabled =
this.config.dynamicPermalinks && data.dynamicPermalink !== false;
@@ -221,11 +218,9 @@ class Template extends TemplateContent {
// `permalink: false` means render but no file system write, e.g. use in collections only)
// `permalink: true` throws an error
if (typeof permalink === "boolean") {
- debugDev("Using boolean permalink %o", permalink);
permalinkValue = permalink;
} else if (permalink && !isDynamicPermalinkEnabled) {
// Issue #838
- debugDev("Not using dynamic permalinks, using %o", permalink);
permalinkValue = permalink;
} else if (isPlainObject(permalink)) {
// Empty permalink {} object should act as if no permalink was set at all
@@ -264,7 +259,6 @@ class Template extends TemplateContent {
// render variables inside permalink front matter, bypass markdown
permalinkValue = await super.renderPermalink(permalink, data);
debug("Rendering permalink for %o: %s becomes %o", this.inputPath, permalink, permalinkValue);
- debugDev("Permalink rendered with data: %o", data);
}
// Override default permalink behavior. Only do this if permalink was _not_ in the data cascade
@@ -376,14 +370,12 @@ class Template extends TemplateContent {
}
async #getData() {
- debugDev("%o getData", this.inputPath);
let localData = {};
let globalData = {};
if (this.templateData) {
localData = await this.templateData.getTemplateDirectoryData(this.inputPath);
globalData = await this.templateData.getGlobalData();
- debugDev("%o getData getTemplateDirectoryData and getGlobalData", this.inputPath);
}
let { data: frontMatterData } = await this.getFrontMatterData();
@@ -401,7 +393,6 @@ class Template extends TemplateContent {
let layout = this.getLayout(layoutKey);
mergedLayoutData = await layout.getData();
- debugDev("%o getData merged layout chain front matter", this.inputPath);
}
}
@@ -412,9 +403,9 @@ class Template extends TemplateContent {
ReservedData.checkSubset(mergedData);
}
- await this.addPage(mergedData);
+ let pageData = await this.getPageData(mergedData);
- debugDev("%o getData mergedData", this.inputPath);
+ Merge(mergedData, { page: pageData });
return mergedData;
} catch (e) {
@@ -435,30 +426,28 @@ class Template extends TemplateContent {
return this.#dataCache;
}
- async addPage(data) {
- if (!("page" in data)) {
- data.page = {};
- }
-
- // Make sure to keep these keys synchronized in src/Util/ReservedData.js
- data.page.inputPath = this.inputPath;
- // parsed dir never has the trailing slash
- data.page.inputPathDir = PathNormalizer.getDirectoryFromFilePath(this.inputPath);
- data.page.fileSlug = this.fileSlugStr;
- data.page.filePathStem = this.filePathStem;
- data.page.outputFileExtension = this.engine.defaultTemplateFileExtension;
- data.page.templateSyntax = this.getEngineNames(data[this.config.keys.engineOverride]);
+ async getPageData(data) {
+ let page = {
+ // Make sure to keep these keys synchronized in src/Util/ReservedData.js
+ inputPath: this.inputPath,
+ fileSlug: this.fileSlugStr,
+ filePathStem: this.filePathStem,
+ outputFileExtension: this.engine.defaultTemplateFileExtension,
+ templateSyntax: this.templateRender.getEnginesList(data[this.config.keys.engineOverride]),
+ };
- let newDate = await this.getMappedDate(data);
+ let newDate = await this.getMappedDate(data?.date, page);
// Skip date assignment if custom date is falsy.
if (newDate) {
- data.page.date = newDate;
+ page.date = newDate;
}
- // data.page.url
- // data.page.outputPath
- // data.page.excerpt from gray-matter and Front Matter
- // data.page.lang from I18nPlugin
+ // page.url
+ // page.outputPath
+ // page.excerpt from gray-matter and Front Matter
+ // page.lang from I18nPlugin
+
+ return page;
}
// Tests only
@@ -477,18 +466,18 @@ class Template extends TemplateContent {
// see also Eleventy->#resetFileInWatchQueue()
internalTriggerTemplateModifiedPath(changedFilePath) {
- this.config.events.emit("eleventy#templateModified", changedFilePath);
+ this.config.events.emit("buildawesome#templatemodified", changedFilePath);
}
// This is the primary render mechanism, called via TemplateMap->populateContentDataInMap
async renderPageEntryWithoutLayout(pageEntry) {
// @cachedproperty
- if (!this._cacheRenderedPromise) {
- this._cacheRenderedPromise = this.renderDirect(pageEntry.rawInput, pageEntry.data);
+ if (!this.#cacheRenderedPromise) {
+ this.#cacheRenderedPromise = this.renderDirect(pageEntry.rawInput, pageEntry.data);
this.renderCount++;
}
- return this._cacheRenderedPromise;
+ return this.#cacheRenderedPromise;
}
setLinters(linters) {
@@ -591,7 +580,8 @@ class Template extends TemplateContent {
}
async addComputedData(data) {
- if (isPlainObject(data?.[this.config.keys.computed])) {
+ let computedData = ResolveConfigurationData.getValue(data, this.config.keys.computed);
+ if (isPlainObject(computedData)) {
this.computedData = new ComputedData(this.config);
// Note that `permalink` is only a thing that gets consumed—it does not go directly into generated data
@@ -620,12 +610,13 @@ class Template extends TemplateContent {
);
// Check for reserved properties in computed data
+ let computedData = ResolveConfigurationData.getValue(data, this.config.keys.computed);
if (this.config.freezeReservedData) {
- ReservedData.checkSubset(data[this.config.keys.computed]);
+ ReservedData.checkSubset(computedData);
}
// actually add the computed data
- this._addComputedEntry(this.computedData, data[this.config.keys.computed]);
+ this._addComputedEntry(this.computedData, computedData);
// limited run of computed data—save the stuff that relies on collections for later.
debug("First round of computed data for %o", this.inputPath);
@@ -647,10 +638,16 @@ class Template extends TemplateContent {
return;
}
- let { href, path, dir } = await this.getOutputLocations(data);
+ let { href, path } = await this.getOutputLocations(data);
data.page.url = href;
data.page.outputPath = path;
- data.page.dir = dir;
+ }
+
+ if (this.dataCascade) {
+ data.page.mapUrl =
+ this.eleventyConfig.directories.getOutputPathRelativeToOutputDirectory(
+ data.page.outputPath,
+ ) + ".map";
}
}
@@ -873,7 +870,7 @@ class Template extends TemplateContent {
let layoutKey = pageEntry.data[this.config.keys.layout];
if (this.engine.useLayouts() && layoutKey) {
let layout = pageEntry.template.getLayout(layoutKey);
- content = await layout.renderPageEntry(pageEntry);
+ content = await layout.renderLayoutPageEntry(pageEntry);
} else {
content = pageEntry.templateContent;
}
@@ -884,14 +881,15 @@ class Template extends TemplateContent {
return content;
}
+ // This could be `static`
async renderPageEntry(pageEntry) {
// @cachedproperty
- if (!pageEntry.template._cacheRenderedTransformsAndLayoutsPromise) {
- pageEntry.template._cacheRenderedTransformsAndLayoutsPromise =
- this.#renderPageEntryWithLayoutsAndTransforms(pageEntry);
+ if (!pageEntry.template.#cacheRenderedTransformsAndLayoutsPromise) {
+ pageEntry.template.#cacheRenderedTransformsAndLayoutsPromise =
+ pageEntry.template.#renderPageEntryWithLayoutsAndTransforms(pageEntry);
}
- return pageEntry.template._cacheRenderedTransformsAndLayoutsPromise;
+ return pageEntry.template.#cacheRenderedTransformsAndLayoutsPromise;
}
retrieveDataForJsonOutput(data, selectors) {
@@ -926,7 +924,7 @@ class Template extends TemplateContent {
inputPath: page.inputPath,
outputPath: page.outputPath,
rawInput: page.rawInput,
- content: content,
+ content,
};
if (this.config.dataFilterSelectors?.size > 0) {
@@ -962,7 +960,7 @@ class Template extends TemplateContent {
}
async clone() {
- // TODO do we need to even run the constructor here or can we simplify it even more
+ // QUESTION do we need to even run the constructor here or can we simplify it even more
let tmpl = new Template(
this.inputPath,
this.templateData,
@@ -970,8 +968,7 @@ class Template extends TemplateContent {
this.eleventyConfig,
);
- // We use this cheap property setter below instead
- // await tmpl.getTemplateRender();
+ tmpl.logger = this.logger;
// preserves caches too, e.g. _frontMatterDataCache
// Does not yet include .computedData
@@ -1023,15 +1020,13 @@ class Template extends TemplateContent {
return newDate;
}
- async getMappedDate(data) {
- let dateValue = data?.date;
-
+ async getMappedDate(dateValue, pageData) {
// These can return a Date object, or a string.
// Already type checked to be functions in UserConfig
for (let fn of this.config.customDateParsing) {
let ret = fn.call(
{
- page: data.page,
+ page: pageData,
},
dateValue,
);
@@ -1043,7 +1038,7 @@ class Template extends TemplateContent {
}
if (dateValue) {
- debug("getMappedDate: using a date in the data for %o of %o", this.inputPath, data.date);
+ debug("getMappedDate: using a date in the data for %o of %o", this.inputPath, dateValue);
if (dateValue?.constructor?.name === "DateTime") {
// a luxon instance
debug("getMappedDate: found DateTime instance: %o", dateValue);
@@ -1126,8 +1121,6 @@ class Template extends TemplateContent {
// Important reminder: Template data is first generated in TemplateMap
async getTemplateMapEntry(data) {
- debugDev("%o getMapped()", this.inputPath);
-
this.behavior.setRenderViaDataCascade(data);
// does not return outputPath or url, we don’t want to render permalinks yet
diff --git a/src/TemplateBehavior.js b/src/TemplateBehavior.js
index dde513e4c..853cc035b 100644
--- a/src/TemplateBehavior.js
+++ b/src/TemplateBehavior.js
@@ -1,5 +1,7 @@
import { isPlainObject } from "@11ty/eleventy-utils";
+import { ResolveConfigurationData } from "./Data/ResolveConfigurationData.js";
+
class TemplateBehavior {
#isRenderOptional;
@@ -63,9 +65,11 @@ class TemplateBehavior {
}
}
- let computedKey = this.config.keys.computed;
- if (computedKey in data && isPlainObject(data[computedKey]?.permalink)) {
- for (let key of Object.keys(data[computedKey].permalink)) {
+ let computedData = ResolveConfigurationData.getValue(data, this.config.keys.computed);
+ let permalink = ResolveConfigurationData.getValue(computedData, this.config.keys.permalink);
+
+ if (computedData && isPlainObject(permalink)) {
+ for (let key of Object.keys(permalink)) {
keys.add(key);
}
}
diff --git a/src/TemplateConfig.js b/src/TemplateConfig.js
index 05ee5788b..e1ad1006a 100644
--- a/src/TemplateConfig.js
+++ b/src/TemplateConfig.js
@@ -1,19 +1,20 @@
import { Merge, TemplatePath, isPlainObject } from "@11ty/eleventy-utils";
-import { createDebug } from "obug";
+import lodash from "@11ty/lodash-custom";
import chalk from "./Adapters/Packages/chalk.js";
import getDefaultConfig from "./Adapters/getDefaultConfig.js";
-import { EleventyImportRaw } from "./Util/Require.js";
-import EleventyBaseError from "./Errors/EleventyBaseError.js";
+import { createDebug } from "./Util/DebugLogUtil.js";
+import { DynamicImportRaw } from "./Util/Require.js";
+import BaseError from "./Errors/BaseError.js";
import UserConfig from "./UserConfig.js";
import GlobalDependencyMap from "./GlobalDependencyMap.js";
import ExistsCache from "./Util/ExistsCache.js";
import eventBus from "./EventBus.js";
import ProjectTemplateFormats from "./Util/ProjectTemplateFormats.js";
-import { isTypeScriptSupported } from "./Util/FeatureTests.cjs";
+import { expandEligibleJavaScriptFilePaths } from "./Util/FilePathUtil.js";
-const debug = createDebug("Eleventy:TemplateConfig");
-const debugDev = createDebug("Dev:Eleventy:TemplateConfig");
+const { set: lodashSet, get: lodashGet } = lodash;
+const debug = createDebug("TemplateConfig");
/**
* @module 11ty/eleventy/TemplateConfig
@@ -29,13 +30,13 @@ const debugDev = createDebug("Dev:Eleventy:TemplateConfig");
* Errors in eleventy config.
* @ignore
*/
-class EleventyConfigError extends EleventyBaseError {}
+class ConfigError extends BaseError {}
/**
* Errors in eleventy plugins.
* @ignore
*/
-class EleventyPluginError extends EleventyBaseError {}
+class PluginError extends BaseError {}
/**
* Config for a template.
@@ -60,7 +61,7 @@ class TemplateConfig {
/**
* @type {String}
* @description Path to local project config.
- * @default .eleventy.js
+ * @default buildawesome.config.js
*/
if (projectConfigPath !== undefined) {
this.#configManuallyDefined = true;
@@ -73,17 +74,10 @@ class TemplateConfig {
}
} else {
this.projectConfigPaths = [
- ".eleventy.js",
- "eleventy.config.js",
- "eleventy.config.mjs",
- "eleventy.config.cjs",
+ ...expandEligibleJavaScriptFilePaths("buildawesome.config"),
+ ".eleventy.js", // intentionally has never included other JS extensions
+ ...expandEligibleJavaScriptFilePaths("eleventy.config"),
];
-
- if (isTypeScriptSupported()) {
- this.projectConfigPaths.push("eleventy.config.ts");
- this.projectConfigPaths.push("eleventy.config.mts");
- this.projectConfigPaths.push("eleventy.config.cts");
- }
}
if (customRootConfig) {
@@ -105,7 +99,7 @@ class TemplateConfig {
return this.existsCache.exists(filePath);
};
- this.userConfig.events.on("eleventy#templateModified", (inputPath, metadata = {}) => {
+ this.userConfig.events.on("buildawesome#templatemodified", (inputPath, metadata = {}) => {
// Issue #3569, set that this file exists in the cache
this.#existsCache.set(inputPath, true);
});
@@ -203,8 +197,6 @@ class TemplateConfig {
*/
async reset() {
this.#existsCache.reset();
-
- debugDev("Resetting configuration: TemplateConfig and UserConfig.");
this.userConfig.reset();
this.usesGraph.reset(); // needs to be before forceReloadConfig #3711
@@ -212,7 +204,7 @@ class TemplateConfig {
await this.forceReloadConfig();
// Clear the compile cache
- eventBus.emit("eleventy.compileCacheReset");
+ eventBus.emit("buildawesome.compilecachereset");
}
/**
@@ -281,7 +273,6 @@ class TemplateConfig {
if (this.hasConfigMerged) {
// merge it again
- debugDev("Merging in getConfig again after setting the local project config path.");
await this.forceReloadConfig();
}
}
@@ -367,7 +358,7 @@ class TemplateConfig {
namespaceStr = ` (namespace: ${namespaces.join(".")})`;
}
- throw new EleventyPluginError(
+ throw new PluginError(
`Error processing ${name ? `the \`${name}\`` : "a"} plugin${namespaceStr}`,
e,
);
@@ -391,7 +382,7 @@ class TemplateConfig {
let path = this.getActiveConfigPath();
if (this.projectConfigPaths.length > 0 && this.#configManuallyDefined && !path) {
- throw new EleventyConfigError(
+ throw new ConfigError(
"A configuration file was specified but not found: " + this.projectConfigPaths.join(", "),
);
}
@@ -399,8 +390,10 @@ class TemplateConfig {
debug(`Merging default config with ${path}`);
if (path) {
try {
- let { default: configDefaultReturn, config: exportedConfigObject } =
- await EleventyImportRaw(path, this.isEsm ? "esm" : "cjs");
+ let { default: configDefaultReturn, config: exportedConfigObject } = await DynamicImportRaw(
+ path,
+ this.isEsm ? "esm" : "cjs",
+ );
exportedConfig = exportedConfigObject || {};
@@ -425,7 +418,7 @@ class TemplateConfig {
// TODO the error message here is bad and I feel bad (needs more accurate info)
return Promise.reject(
- new EleventyConfigError(
+ new ConfigError(
`Error in your Eleventy config file '${path}'.` +
(isModuleError ? chalk.cyan(" You may need to run `npm install`.") : ""),
err,
@@ -528,7 +521,7 @@ class TemplateConfig {
// But BEFORE the rest of the config options are merged
// this way we can pass directories and other template information to plugins
- await this.userConfig.events.emit("eleventy.beforeConfig", this.userConfig);
+ await this.userConfig.events.emit("buildawesome.beforeconfig", this.userConfig);
let pluginsBench = this.aggregateBenchmark.get("Processing plugins in config");
pluginsBench.before();
diff --git a/src/TemplateContent.js b/src/TemplateContent.js
index 642afcdf6..ada08098d 100644
--- a/src/TemplateContent.js
+++ b/src/TemplateContent.js
@@ -1,24 +1,23 @@
import { readFileSync } from "node:fs";
import matter from "@11ty/gray-matter";
import lodash from "@11ty/lodash-custom";
-import { DeepCopy, TemplatePath } from "@11ty/eleventy-utils";
-import { createDebug } from "obug";
+import { Merge, DeepCopy, TemplatePath } from "@11ty/eleventy-utils";
import JavaScriptFrontMatter from "./Engines/FrontMatter/JavaScript.js";
+import { createDebug } from "./Util/DebugLogUtil.js";
import { EOL } from "./Util/NewLineAdapter.js";
import TemplateData from "./Data/TemplateData.js";
import TemplateRender from "./TemplateRender.js";
-import EleventyBaseError from "./Errors/EleventyBaseError.js";
-import EleventyErrorUtil from "./Errors/EleventyErrorUtil.js";
+import BaseError from "./Errors/BaseError.js";
+import ErrorUtil from "./Errors/ErrorUtil.js";
import eventBus from "./EventBus.js";
const { set: lodashSet } = lodash;
-const debug = createDebug("Eleventy:TemplateContent");
-const debugDev = createDebug("Dev:Eleventy:TemplateContent");
+const debug = createDebug("TemplateContent");
-class TemplateContentFrontMatterError extends EleventyBaseError {}
-class TemplateContentCompileError extends EleventyBaseError {}
-class TemplateContentRenderError extends EleventyBaseError {}
+class TemplateContentFrontMatterError extends BaseError {}
+class TemplateContentCompileError extends BaseError {}
+class TemplateContentRenderError extends BaseError {}
class TemplateContent {
#initialized = false;
@@ -395,27 +394,39 @@ class TemplateContent {
async #getFrontMatterData() {
let fm = await this.read();
+ let virtualTemplateDefinition = this.getVirtualTemplateDefinition();
+ let virtualTemplateData;
+ if (virtualTemplateDefinition) {
+ virtualTemplateData = virtualTemplateDefinition.data;
+
+ TemplateData.cleanupData(virtualTemplateData, {
+ file: this.inputPath,
+ isVirtualTemplate: Boolean(virtualTemplateData),
+ });
+ }
+
// gray-matter isn’t async-friendly but can return a promise from custom front matter
if (fm.data instanceof Promise) {
fm.data = await fm.data;
}
- let tr = await this.getTemplateRender();
- let extraData = await tr.engine.getExtraDataFromFile(this.inputPath);
+ let frontMatterData = Object.assign({}, fm.data);
- let virtualTemplateDefinition = this.getVirtualTemplateDefinition();
- let virtualTemplateData;
- if (virtualTemplateDefinition) {
- virtualTemplateData = virtualTemplateDefinition.data;
- }
+ TemplateData.cleanupData(frontMatterData, {
+ file: this.inputPath,
+ isVirtualTemplate: Boolean(virtualTemplateData),
+ });
- let data = Object.assign({}, fm.data, extraData, virtualTemplateData);
+ let tr = await this.getTemplateRender();
+ let extraData = await tr.engine.getExtraDataFromFile(this.inputPath);
- TemplateData.cleanupData(data, {
+ TemplateData.cleanupData(extraData, {
file: this.inputPath,
isVirtualTemplate: Boolean(virtualTemplateData),
});
+ let data = Object.assign(frontMatterData, extraData, virtualTemplateData);
+
return {
data,
excerpt: fm.excerpt,
@@ -479,7 +490,6 @@ class TemplateContent {
// this.templateRender is guaranteed here
let tr = await this.getTemplateRender();
if (engineOverride !== undefined) {
- debugDev("%o overriding template engine to use %o", this.inputPath, engineOverride);
await tr.setEngineOverride(engineOverride, bypassMarkdown);
} else {
tr.setUseMarkdown(!bypassMarkdown);
@@ -490,8 +500,6 @@ class TemplateContent {
};
}
- debugDev("%o compile() using engine: %o", this.inputPath, tr.engineName);
-
try {
let res;
if (this.config.useTemplateCache) {
@@ -524,7 +532,7 @@ class TemplateContent {
let fn = await tr.getCompiledTemplate(str);
inputPathBenchmark.after();
templateBenchmark.after();
- debugDev("%o getCompiledTemplate function created", this.inputPath);
+
if (this.config.useTemplateCache && res) {
res(fn);
}
@@ -687,10 +695,10 @@ class TemplateContent {
inputPathBenchmark.after();
}
templateBenchmark.after();
- debugDev("%o getCompiledTemplate called, rendered content created", this.inputPath);
+
return rendered;
} catch (e) {
- if (EleventyErrorUtil.isPrematureTemplateContentError(e)) {
+ if (ErrorUtil.isPrematureTemplateContentError(e)) {
return Promise.reject(e);
} else {
let tr = await this.getTemplateRender();
@@ -768,7 +776,7 @@ class TemplateContent {
TemplateContent._inputCache = new Map();
TemplateContent._compileCache = new Map();
-eventBus.on("eleventy.resourceModified", (path) => {
+eventBus.on("buildawesome.resourcemodified", (path) => {
// delete from input cache
TemplateContent.deleteFromInputCache(path);
@@ -781,7 +789,7 @@ eventBus.on("eleventy.resourceModified", (path) => {
});
// Used when the configuration file reset https://github.com/11ty/eleventy/issues/2147
-eventBus.on("eleventy.compileCacheReset", () => {
+eventBus.on("buildawesome.compilecachereset", () => {
TemplateContent._compileCache = new Map();
});
diff --git a/src/TemplateLayout.js b/src/TemplateLayout.js
index db8f46642..91823c772 100644
--- a/src/TemplateLayout.js
+++ b/src/TemplateLayout.js
@@ -1,12 +1,9 @@
import { Merge, TemplatePath } from "@11ty/eleventy-utils";
-import { createDebug } from "obug";
import TemplateLayoutPathResolver from "./TemplateLayoutPathResolver.js";
import TemplateContent from "./TemplateContent.js";
import layoutCache from "./LayoutCache.js";
-const debugDev = createDebug("Dev:Eleventy:TemplateLayout");
-
// https://github.com/11ty/eleventy/issues/3954
class CdataWrapper {
static PREFIX = "renderPageEntry
- async renderPageEntry(pageEntry) {
+ async renderLayoutPageEntry(pageEntry) {
let pageTemplateSyntax = pageEntry.template?.getEngineNames(
pageEntry.data[this.config.keys.engineOverride],
);
@@ -264,7 +261,6 @@ class TemplateLayout extends TemplateContent {
// This should come *after* data, so `content` have override `content` props set in data cascade
content: cdata.wrap(templateContent),
};
-
templateContent = cdata.unwrap(await render(data));
}
diff --git a/src/TemplateMap.js b/src/TemplateMap.js
index b56f40075..e7f3a9a3d 100644
--- a/src/TemplateMap.js
+++ b/src/TemplateMap.js
@@ -1,14 +1,15 @@
import { isPlainObject, TemplatePath } from "@11ty/eleventy-utils";
-import { createDebug } from "obug";
import TemplateCollection from "./TemplateCollection.js";
-import EleventyErrorUtil from "./Errors/EleventyErrorUtil.js";
+import ErrorUtil from "./Errors/ErrorUtil.js";
import UsingCircularTemplateContentReferenceError from "./Errors/UsingCircularTemplateContentReferenceError.js";
import DuplicatePermalinkOutputError from "./Errors/DuplicatePermalinkOutputError.js";
import TemplateData from "./Data/TemplateData.js";
import GlobalDependencyMap from "./GlobalDependencyMap.js";
+import { ResolveConfigurationData } from "./Data/ResolveConfigurationData.js";
+import { createDebug } from "./Util/DebugLogUtil.js";
-const debug = createDebug("Eleventy:TemplateMap");
+const debug = createDebug("TemplateMap");
// These template URL filenames are allowed to exclude file extensions
const EXTENSIONLESS_URL_ALLOWLIST = [
@@ -25,6 +26,7 @@ const SPECIAL_COLLECTION_NAMES = {
class TemplateMap {
#dependencyMapInitialized = false;
+ #templateData;
constructor(eleventyConfig) {
if (!eleventyConfig || eleventyConfig.constructor.name !== "TemplateConfig") {
@@ -35,7 +37,6 @@ class TemplateMap {
this.inputPathMap = new Map(); // NEW: O(1) lookup Map for performance
this.collectionsData = null;
this.cached = false;
- this.verboseOutput = true;
this.collection = new TemplateCollection();
}
@@ -59,6 +60,10 @@ class TemplateMap {
return this._config;
}
+ setTemplateData(templateData) {
+ this.#templateData = templateData;
+ }
+
async add(template) {
if (!template) {
return;
@@ -112,8 +117,9 @@ class TemplateMap {
let consumes = [];
consumes.push(this.getPaginationTagTarget(entry));
- if (Array.isArray(entry.data.eleventyImport?.collections)) {
- for (let tag of entry.data.eleventyImport.collections) {
+ let importData = ResolveConfigurationData.getValue(entry.data, this.config.keys.import);
+ if (Array.isArray(importData?.collections)) {
+ for (let tag of importData.collections) {
consumes.push(tag);
}
}
@@ -224,7 +230,10 @@ class TemplateMap {
}
if (counter === 0 || map.data.pagination?.addAllPagesToCollections) {
- if (map.data.eleventyExcludeFromCollections !== true) {
+ if (
+ ResolveConfigurationData.getValue(map.data, "buildawesomeExcludeFromCollections") !==
+ true
+ ) {
// is in *some* collections
this.collection.add(page);
}
@@ -284,7 +293,7 @@ class TemplateMap {
return this.getMapEntryForInputPath(inputPath);
});
- await this.config.events.emitLazy("eleventy.contentMap", () => {
+ await this.config.events.emitLazy("buildawesome.contentmap", () => {
return {
inputPathToUrl: this.generateInputUrlContentMap(orderedMap),
urlToInputPath: this.generateUrlMap(orderedMap),
@@ -300,7 +309,7 @@ class TemplateMap {
this.checkForDuplicatePermalinks();
this.checkForMissingFileExtensions();
- await this.config.events.emitLazy("eleventy.layouts", () => this.generateLayoutsMap());
+ await this.config.events.emitLazy("buildawesome.layouts", () => this.generateLayoutsMap());
}
generateInputUrlContentMap(orderedMap) {
@@ -346,12 +355,16 @@ class TemplateMap {
for (let pageEntry of map._pages) {
// Data Schema callback #879
- if (typeof pageEntry.data[this.config.keys.dataSchema] === "function") {
+ let { location: dataSchemaLocation, value: dataSchema } = ResolveConfigurationData.resolve(
+ pageEntry.data,
+ this.config.keys.dataSchema,
+ );
+ if (dataSchema !== undefined && typeof dataSchema === "function") {
try {
- await pageEntry.data[this.config.keys.dataSchema](pageEntry.data);
+ await dataSchema(pageEntry.data);
} catch (e) {
throw new Error(
- `Error in the data schema for: ${map.inputPath} (via \`eleventyDataSchema\`)`,
+ `Error in the data schema for: ${map.inputPath} (via \`${dataSchemaLocation}\`)`,
{ cause: e },
);
}
@@ -389,7 +402,7 @@ class TemplateMap {
await pageEntry.template.renderPageEntryWithoutLayout(pageEntry);
}
} catch (e) {
- if (EleventyErrorUtil.isPrematureTemplateContentError(e)) {
+ if (ErrorUtil.isPrematureTemplateContentError(e)) {
// Add to list of templates that need to be processed again
usedTemplateContentTooEarlyMap.push(map);
@@ -414,7 +427,7 @@ class TemplateMap {
await pageEntry.template.renderPageEntryWithoutLayout(pageEntry);
}
} catch (e) {
- if (EleventyErrorUtil.isPrematureTemplateContentError(e)) {
+ if (ErrorUtil.isPrematureTemplateContentError(e)) {
// If we still have template content errors after the second pass,
// it's likely a circular reference
throw new UsingCircularTemplateContentReferenceError(
@@ -495,7 +508,11 @@ class TemplateMap {
let promises = [];
for (let entry of this.map) {
for (let pageEntry of entry._pages) {
- if (this.config.keys.computed in pageEntry.data) {
+ let computedData = ResolveConfigurationData.getValue(
+ pageEntry.data,
+ this.config.keys.computed,
+ );
+ if (computedData !== undefined) {
promises.push(pageEntry.template.resolveRemainingComputedData(pageEntry.data));
}
}
@@ -612,7 +629,7 @@ You *probably* want to add a file extension to your permalink so that hosts will
Learn more: https://v3.11ty.dev/docs/permalinks/#trailing-slashes
-This is usually but not *always* an error so if you’d like to disable this error message, add \`eleventyAllowMissingExtension: true\` somewhere in the data cascade for this template or use \`eleventyConfig.configureErrorReporting({ allowMissingExtensions: true });\` to disable this feature globally.`);
+This is usually but not *always* an error so if you’d like to disable this error message, add \`eleventyAllowMissingExtension: true\` somewhere in the data cascade for this template or use \`$config.configureErrorReporting({ allowMissingExtensions: true });\` to disable this feature globally.`);
e.skipOriginalStack = true;
throw e;
}
diff --git a/src/TemplatePassthrough.js b/src/TemplatePassthrough.js
index 3e5148ab5..96bf4765f 100644
--- a/src/TemplatePassthrough.js
+++ b/src/TemplatePassthrough.js
@@ -2,17 +2,17 @@ import path from "node:path";
import copy from "@11ty/recursive-copy";
import { TemplatePath } from "@11ty/eleventy-utils";
-import { createDebug } from "obug";
import { readableFileSize } from "./Util/FileSize.js";
import { isDynamicPattern } from "./Util/GlobMatcher.js";
-import EleventyBaseError from "./Errors/EleventyBaseError.js";
+import BaseError from "./Errors/BaseError.js";
import checkPassthroughCopyBehavior from "./Util/PassthroughCopyBehaviorCheck.js";
import ProjectDirectories from "./Util/ProjectDirectories.js";
+import { createDebug } from "./Util/DebugLogUtil.js";
-const debug = createDebug("Eleventy:TemplatePassthrough");
+const debug = createDebug("TemplatePassthrough");
-class TemplatePassthroughError extends EleventyBaseError {}
+class TemplatePassthroughError extends BaseError {}
class TemplatePassthrough {
isDryRun = false;
diff --git a/src/TemplatePassthroughManager.js b/src/TemplatePassthroughManager.js
index 8ffbdee66..97cb2d955 100644
--- a/src/TemplatePassthroughManager.js
+++ b/src/TemplatePassthroughManager.js
@@ -1,14 +1,14 @@
import { TemplatePath } from "@11ty/eleventy-utils";
-import { createDebug } from "obug";
-import EleventyBaseError from "./Errors/EleventyBaseError.js";
+import BaseError from "./Errors/BaseError.js";
import TemplatePassthrough from "./TemplatePassthrough.js";
import checkPassthroughCopyBehavior from "./Util/PassthroughCopyBehaviorCheck.js";
import { isGlobMatch, isDynamicPattern } from "./Util/GlobMatcher.js";
+import { createDebug } from "./Util/DebugLogUtil.js";
-const debug = createDebug("Eleventy:TemplatePassthroughManager");
+const debug = createDebug("TemplatePassthroughManager");
-class TemplatePassthroughManagerCopyError extends EleventyBaseError {}
+class TemplatePassthroughManagerCopyError extends BaseError {}
class TemplatePassthroughManager {
#isDryRun = false;
@@ -25,15 +25,15 @@ class TemplatePassthroughManager {
this.config = templateConfig.getConfig();
// eleventy# event listeners are removed on each build
- this.config.events.on("eleventy#copy", ({ source, target, options }) => {
+ this.config.events.on("buildawesome#copy", ({ source, target, options }) => {
this.enqueueCopy(source, target, options);
});
- this.config.events.on("eleventy#beforerender", () => {
+ this.config.events.on("buildawesome#beforerender", () => {
this.#afterBuild = Promise.withResolvers();
});
- this.config.events.on("eleventy#render", () => {
+ this.config.events.on("buildawesome#render", () => {
let { resolve } = this.#afterBuild;
resolve();
});
@@ -376,7 +376,7 @@ class TemplatePassthroughManager {
return Promise.all(promises).then(async (results) => {
let aliases = this.getAliasesFromPassthroughResults(results);
- await this.config.events.emit("eleventy.passthrough", {
+ await this.config.events.emit("buildawesome.passthrough", {
map: aliases,
});
diff --git a/src/TemplateRender.js b/src/TemplateRender.js
index 63dc07042..71ff94a48 100644
--- a/src/TemplateRender.js
+++ b/src/TemplateRender.js
@@ -1,10 +1,10 @@
-import { createDebug } from "obug";
-import EleventyBaseError from "./Errors/EleventyBaseError.js";
+import BaseError from "./Errors/BaseError.js";
import TemplateEngineManager from "./Engines/TemplateEngineManager.js";
+import { createDebug } from "./Util/DebugLogUtil.js";
-const debugConfiguration = createDebug("Eleventy:UserConfig");
+const debugConfiguration = createDebug("UserConfig");
-class TemplateRenderUnknownEngineError extends EleventyBaseError {}
+class TemplateRenderUnknownEngineError extends BaseError {}
// works with full path names or short engine name
export default class TemplateRender {
diff --git a/src/TemplateWriter.js b/src/TemplateWriter.js
index 2b3415e7e..8852c903a 100755
--- a/src/TemplateWriter.js
+++ b/src/TemplateWriter.js
@@ -1,23 +1,24 @@
import { TemplatePath, isPlainObject } from "@11ty/eleventy-utils";
-import { createDebug } from "obug";
import Template from "./Template.js";
import TemplateMap from "./TemplateMap.js";
-import EleventyBaseError from "./Errors/EleventyBaseError.js";
-import { EleventyErrorHandler } from "./Errors/EleventyErrorHandler.js";
-import EleventyErrorUtil from "./Errors/EleventyErrorUtil.js";
+import BaseError from "./Errors/BaseError.js";
+import { ErrorHandler } from "./Errors/ErrorHandler.js";
+import ErrorUtil from "./Errors/ErrorUtil.js";
import ConsoleLogger from "./Util/ConsoleLogger.js";
+import { createDebug } from "./Util/DebugLogUtil.js";
-const debug = createDebug("Eleventy:TemplateWriter");
+const debug = createDebug("TemplateWriter");
-class TemplateWriterMissingConfigArgError extends EleventyBaseError {}
-class EleventyPassthroughCopyError extends EleventyBaseError {}
-class EleventyTemplateError extends EleventyBaseError {}
+class TemplateWriterMissingConfigArgError extends BaseError {}
+class PassthroughCopyError extends BaseError {}
+class TemplateError extends BaseError {}
class TemplateWriter {
#eleventyFiles;
#passthroughManager;
#errorHandler;
+ #logger;
#extensionMap;
#incrementalFiles = [];
@@ -36,7 +37,6 @@ class TemplateWriter {
this.templateFormats = templateFormats;
this.templateData = templateData;
- this.isVerbose = true;
this.isDryRun = false;
this.writeCount = 0;
this.renderCount = 0;
@@ -69,27 +69,22 @@ class TemplateWriter {
/* Getter for error handler */
get errorHandler() {
if (!this.#errorHandler) {
- this.#errorHandler = new EleventyErrorHandler();
- this.#errorHandler.isVerbose = this.verboseMode;
- this.#errorHandler.logger = this.logger;
+ throw new Error("Internal error: missing ErrorHandler instance.");
}
return this.#errorHandler;
}
- /* Getter for Logger */
get logger() {
- if (!this._logger) {
- this._logger = new ConsoleLogger();
- this._logger.isVerbose = this.verboseMode;
+ if (!this.#logger) {
+ throw new Error("Internal error: missing ConsoleLogger instance.");
}
- return this._logger;
+ return this.#logger;
}
- /* Setter for Logger */
set logger(logger) {
- this._logger = logger;
+ this.#logger = logger;
}
/* For testing */
@@ -200,7 +195,6 @@ class TemplateWriter {
tmpl.setPreprocessors(this.config.preprocessors);
tmpl.setLinters(this.config.linters);
tmpl.setDryRun(this.isDryRun);
- tmpl.setIsVerbose(this.isVerbose);
tmpl.reset();
return {
@@ -408,6 +402,9 @@ class TemplateWriter {
async createTemplateMap(paths, to) {
this.templateMap = new TemplateMap(this.templateConfig);
+ if (this.templateData) {
+ this.templateMap.setTemplateData(this.templateData);
+ }
await this.#addToTemplateMap(paths, to);
await this.templateMap.cache();
@@ -433,7 +430,7 @@ class TemplateWriter {
return this.#passthroughManager.copyAll(templateExtensionPaths).catch((e) => {
this.errorHandler.warn(e, "Error with passthrough copy");
- return Promise.reject(new EleventyPassthroughCopyError("Having trouble copying", e));
+ return Promise.reject(new PassthroughCopyError("Having trouble copying", e));
});
}
@@ -449,12 +446,12 @@ class TemplateWriter {
this.#generateTemplate(mapEntry, to).catch(function (e) {
// Premature templateContent in layout render, this also happens in
// TemplateMap.populateContentDataInMap for non-layout content
- if (EleventyErrorUtil.isPrematureTemplateContentError(e)) {
+ if (ErrorUtil.isPrematureTemplateContentError(e)) {
usedTemplateContentTooEarlyMap.push(mapEntry);
} else {
let outputPaths = `"${mapEntry._pages.map((page) => page.outputPath).join(`", "`)}"`;
return Promise.reject(
- new EleventyTemplateError(
+ new TemplateError(
`Having trouble writing to ${outputPaths} from "${mapEntry.inputPath}"`,
e,
),
@@ -468,7 +465,7 @@ class TemplateWriter {
promises.push(
this.#generateTemplate(mapEntry, to).catch(function (e) {
return Promise.reject(
- new EleventyTemplateError(
+ new TemplateError(
`Having trouble writing to (second pass) "${mapEntry.outputPath}" from "${mapEntry.inputPath}"`,
e,
),
@@ -501,12 +498,12 @@ class TemplateWriter {
let paths = await this._getAllPaths();
// This must happen before writePassthroughCopy
- this.templateConfig.userConfig.emit("eleventy#beforerender");
+ this.templateConfig.userConfig.emit("buildawesome#beforerender");
let aggregatePassthroughCopyPromise = this.writePassthroughCopy(paths);
let templatesPromise = Promise.all(await this.generateTemplates(paths)).then((results) => {
- this.templateConfig.userConfig.emit("eleventy#render");
+ this.templateConfig.userConfig.emit("buildawesome#render");
return results;
});
@@ -544,11 +541,6 @@ class TemplateWriter {
);
}
- setVerboseOutput(isVerbose) {
- this.isVerbose = isVerbose;
- this.errorHandler.isVerbose = isVerbose;
- }
-
setDryRun(isDryRun) {
this.isDryRun = Boolean(isDryRun);
}
diff --git a/src/UserConfig.js b/src/UserConfig.js
index 48caf159f..36130efa2 100644
--- a/src/UserConfig.js
+++ b/src/UserConfig.js
@@ -1,26 +1,25 @@
-import { createDebug } from "obug";
-
import { DeepCopy, TemplatePath, isPlainObject } from "@11ty/eleventy-utils";
import chalk from "./Adapters/Packages/chalk.js";
+import { createDebug } from "./Util/DebugLogUtil.js";
import { resolvePlugin } from "./Util/ResolvePlugin.js";
import isAsyncFunction from "./Util/IsAsyncFunction.js";
import objectFilter from "./Util/Objects/ObjectFilter.js";
import EventEmitter from "./Util/AsyncEventEmitter.js";
import EleventyCompatibility from "./Util/Compatibility.js";
-import EleventyBaseError from "./Errors/EleventyBaseError.js";
+import BaseError from "./Errors/BaseError.js";
import BenchmarkManager from "./Benchmark/BenchmarkManager.js";
import { augmentFunction } from "./Engines/Util/ContextAugmenter.js";
-const debug = createDebug("Eleventy:UserConfig");
+const debug = createDebug("UserConfig");
-class UserConfigError extends EleventyBaseError {}
+class UserConfigError extends BaseError {}
/**
* Eleventy’s user-land Configuration API
* @module 11ty/eleventy/UserConfig
*/
-class UserConfig {
+export default class UserConfig {
/** @type {boolean} */
#pluginExecution = false;
/** @type {boolean} */
@@ -30,6 +29,7 @@ class UserConfig {
/** @type {number} */
#concurrency = 1;
// Before using os.availableParallelism(); see https://github.com/11ty/eleventy/issues/3596
+ #experimentalFlags = [];
constructor() {
// These are completely unnecessary lines to satisfy TypeScript
@@ -1185,6 +1185,10 @@ class UserConfig {
return this.#concurrency;
}
+ addExperimentalBehavior(flag) {
+ this.#experimentalFlags.push(flag);
+ }
+
getMergingConfigObject() {
let obj = {
// filters removed in 1.0 (use addTransform instead)
@@ -1257,6 +1261,7 @@ class UserConfig {
freezeReservedData: this.freezeReservedData,
customDateParsing: this.customDateParsingCallbacks,
errorReporting: this.errorReporting,
+ experimentalFlags: this.#experimentalFlags,
};
if (Array.isArray(this.dataFileSuffixesOverride)) {
@@ -1273,8 +1278,9 @@ class UserConfig {
return obj;
}
- // Removed features
+ // Throws an error (no backwards compat)
get DateTime() {
+ // this.DateTime removed in v4
throw new Error(
'Luxon’s DateTime property in configuration was removed in Eleventy v4. Please `import { DateTime } from "luxon"` directly.',
);
@@ -1284,13 +1290,6 @@ class UserConfig {
throw new Error("The internal _normalizeTemplateFormats() method was removed in Eleventy v3");
}
- setBrowserSyncConfig() {
- this._attemptedBrowserSyncUse = true;
- debug(
- "The `setBrowserSyncConfig` method was removed in Eleventy v2. Use `setServerOptions` with the new Eleventy development server or the `@11ty/eleventy-browser-sync` plugin moving forward.",
- );
- }
-
configureTemplateHandling(options = {}) {
// Was used for sync/async swapping on file write operations
throw new Error("Internal configuration API method `configureTemplateHandling` was removed.");
@@ -1314,6 +1313,7 @@ class UserConfig {
// Used by the Upgrade Helper Plugin v1 (no longer relevant)
// https://github.com/11ty/eleventy-upgrade-help/blob/v1.x/src/data-deep-merge.js#L5-L9
isDataDeepMergeModified() {}
-}
-export default UserConfig;
+ // No-op from v2
+ setBrowserSyncConfig() {}
+}
diff --git a/src/Util/AsyncEventEmitter.js b/src/Util/AsyncEventEmitter.js
index 0bc471f9b..4f55d26f6 100644
--- a/src/Util/AsyncEventEmitter.js
+++ b/src/Util/AsyncEventEmitter.js
@@ -10,6 +10,43 @@ import { EventEmitter } from "node:events";
class AsyncEventEmitter extends EventEmitter {
#handlerMode = "parallel";
+ /* Order matters */
+ #emitAliases = {
+ "buildawesome.before": ["beforeBuild", "eleventy.before", "buildawesome.before"],
+ "buildawesome.beforewatch": ["beforeWatch", "eleventy.beforeWatch", "buildawesome.beforewatch"],
+ "buildawesome.beforeconfig": ["eleventy.beforeConfig", "buildawesome.beforeconfig"],
+ "buildawesome.after": ["afterBuild", "eleventy.after", "buildawesome.after"],
+
+ // Internal
+ "buildawesome.engine.njk": ["eleventy.engine.njk", "buildawesome.engine.njk"],
+ "buildawesome.globaldatafiles": ["eleventy.globalDataFiles", "buildawesome.globaldatafiles"],
+ "buildawesome.contentmap": ["eleventy.contentMap", "buildawesome.contentmap"],
+ "buildawesome.layouts": ["eleventy.layouts", "buildawesome.layouts"],
+ "buildawesome.datafiles": ["eleventy.dataFiles", "buildawesome.datafiles"],
+ "buildawesome.passthrough": ["eleventy.passthrough", "buildawesome.passthrough"],
+ "buildawesome.config": ["eleventy.config", "buildawesome.config"],
+ "buildawesome.env": ["eleventy.env", "buildawesome.env"],
+ "buildawesome.extensionmap": ["eleventy.extensionmap", "buildawesome.extensionmap"],
+ "buildawesome.directories": ["eleventy.directories", "buildawesome.directories"],
+ "buildawesome.ignores": ["eleventy.ignores", "buildawesome.ignores"],
+ "buildawesome.reset": ["eleventy.reset", "buildawesome.reset"],
+ "buildawesome.afterwatch": ["eleventy.afterwatch", "buildawesome.afterwatch"],
+ "buildawesome.resourcemodified": ["eleventy.resourceModified", "buildawesome.resourcemodified"],
+ "buildawesome.compilecachereset": [
+ "eleventy.compileCacheReset",
+ "buildawesome.compilecachereset",
+ ],
+ "buildawesome.importcachereset": ["eleventy.importCacheReset", "buildawesome.importcachereset"],
+
+ "buildawesome#templatemodified": ["eleventy#templateModified", "buildawesome#templatemodified"],
+ "buildawesome#copy": ["eleventy#copy", "buildawesome#copy"],
+
+ // Internal but not aliased
+ // "buildawesome#previousqueue"
+ // "buildawesome#beforerender",
+ // "buildawesome#render"
+ };
+
// TypeScript slop
constructor(...args) {
super(...args);
@@ -18,11 +55,25 @@ class AsyncEventEmitter extends EventEmitter {
reset() {
// `eleventy#` event type listeners are removed at the start of each build (singletons)
for (let type of this.eventNames()) {
- if (typeof type === "string" && type.startsWith("eleventy#")) {
+ if (
+ typeof type === "string" &&
+ (type.startsWith("eleventy#") || type.startsWith("buildawesome#"))
+ ) {
this.removeAllListeners(type);
}
}
+ }
+
+ getAliasedListeners(type) {
+ if (this.#emitAliases[type]) {
+ let listeners = [];
+ for (let alias of this.#emitAliases[type]) {
+ listeners.push(...this.listeners(alias));
+ }
+ return listeners;
+ }
+ return this.listeners(type);
}
/**
@@ -32,7 +83,7 @@ class AsyncEventEmitter extends EventEmitter {
*/
/** @ts-expect-error */
async emit(type, ...args) {
- let listeners = this.listeners(type);
+ let listeners = this.getAliasedListeners(type);
if (listeners.length === 0) {
return [];
}
@@ -59,7 +110,7 @@ class AsyncEventEmitter extends EventEmitter {
* @returns {Promise} - Promise resolves once all listeners were invoked
*/
async emitLazy(type, ...args) {
- let listeners = this.listeners(type);
+ let listeners = this.getAliasedListeners(type);
if (listeners.length === 0) {
return [];
}
diff --git a/src/Util/Compatibility.js b/src/Util/Compatibility.js
index aa7fbc411..55279e478 100644
--- a/src/Util/Compatibility.js
+++ b/src/Util/Compatibility.js
@@ -1,7 +1,7 @@
import { satisfies } from "../Adapters/Packages/semver.js";
-import { getEleventyPackageJson, getWorkingProjectPackageJson } from "./ImportJsonSync.js";
+import { getCorePackageJson, getWorkingProjectPackageJson } from "./ImportJsonSync.js";
-const pkg = getEleventyPackageJson();
+const pkg = getCorePackageJson();
// Used in user config versionCheck method.
class Compatibility {
diff --git a/src/Util/ConsoleLogger.js b/src/Util/ConsoleLogger.js
index 7e737a489..dd28bb559 100644
--- a/src/Util/ConsoleLogger.js
+++ b/src/Util/ConsoleLogger.js
@@ -1,7 +1,7 @@
-import { createDebug } from "obug";
+import { createDebug } from "./DebugLogUtil.js";
import chalk from "../Adapters/Packages/chalk.js";
-const debug = createDebug("Eleventy:Logger");
+const debug = createDebug("Logger");
/**
* Logger implementation that logs to STDOUT.
@@ -14,8 +14,14 @@ class ConsoleLogger {
#isChalkEnabled = true;
/** @type {object|boolean|undefined} */
#logger;
-
- constructor() {}
+ /** @type {string} */
+ #logPrefix = "[11ty]";
+ /** @type {object} */
+ #colorFallbacks = {
+ info: "blue",
+ warn: "yellow",
+ error: "red",
+ };
isLoggingEnabled() {
if (!this.isVerbose || process.env.DEBUG) {
@@ -24,6 +30,10 @@ class ConsoleLogger {
return this.#logger !== false;
}
+ setPrefix(prefix) {
+ this.#logPrefix = prefix;
+ }
+
get isVerbose() {
return this.#isVerbose;
}
@@ -73,17 +83,17 @@ class ConsoleLogger {
/** @param {string} msg */
info(msg) {
- this.message(msg, "log", "blue");
+ this.message(msg, "log", this.#colorFallbacks.info);
}
/** @param {string} msg */
warn(msg) {
- this.message(msg, "warn", "yellow");
+ this.message(msg, "warn", this.#colorFallbacks.warn);
}
/** @param {string} msg */
error(msg) {
- this.message(msg, "error", "red");
+ this.message(msg, "error", this.#colorFallbacks.error);
}
/** @param {string} message */
@@ -101,18 +111,29 @@ class ConsoleLogger {
* @param {LogType} [type='log'] - The error level to log.
* @param {string|undefined} [chalkColor=undefined] - Color name or falsy to disable
* @param {boolean} [forceToConsole=false] - Enforce a log on console instead of specified target.
+ * @param {string|undefined} [prefix=undefined] - Dimmed string at the start of each line
*/
message(
message,
type = "log",
chalkColor = undefined,
forceToConsole = false,
- prefix = "[11ty]",
+ prefix = undefined,
) {
if (!forceToConsole && (!this.isVerbose || process.env.DEBUG)) {
debug(message);
} else if (this.#logger !== false) {
- message = `${this.#dim(prefix)} ${message.split("\n").join(`\n${chalk.gray(prefix)} `)}`;
+ if (prefix === undefined) {
+ prefix = this.#logPrefix;
+ }
+
+ let prefixStr = prefix ? `${this.#dim(prefix)} ` : "";
+ message = `${prefixStr}${message.split("\n").join(`\n${prefixStr}`)}`;
+
+ // default color for every type but log
+ if (chalkColor === undefined && type) {
+ chalkColor = this.#colorFallbacks[type];
+ }
if (chalkColor && this.isChalkEnabled) {
this.logger[type](chalk[chalkColor](message));
diff --git a/src/Util/DateParse.js b/src/Util/DateParse.js
index ef0c3e601..51de93b14 100644
--- a/src/Util/DateParse.js
+++ b/src/Util/DateParse.js
@@ -1,7 +1,8 @@
-import { createDebug } from "obug";
import { IsoDate } from "@11ty/parse-date-strings";
-const debug = createDebug("Eleventy:DateTime");
+import { createDebug } from "./DebugLogUtil.js";
+
+const debug = createDebug("DateTime");
export function fromISOtoDateUTC(dateValue, inputPath) {
// This has had a UTC default since the beginnning:
diff --git a/src/Util/DebugLogUtil.js b/src/Util/DebugLogUtil.js
new file mode 100644
index 000000000..7306bd1a7
--- /dev/null
+++ b/src/Util/DebugLogUtil.js
@@ -0,0 +1,8 @@
+import { createDebug as createDebugObug } from "obug";
+
+const PREFIX =
+ process?.env?.BUILDAWESOME_PACKAGE === "@awesome.me/buildawesome" ? "BuildAwesome:" : "Eleventy:";
+
+export function createDebug(name) {
+ return createDebugObug(`${PREFIX}:${name}`);
+}
diff --git a/src/Util/EnvironmentVars.cjs b/src/Util/EnvironmentVars.cjs
new file mode 100644
index 000000000..189a70b7e
--- /dev/null
+++ b/src/Util/EnvironmentVars.cjs
@@ -0,0 +1,18 @@
+// Used by CommonJS upstream (cmd.cjs and TypeScript feature test)
+
+module.exports.getEnvValue = function(key) {
+ if(!process?.env) {
+ return;
+ }
+
+ return process.env[`BUILDAWESOME_${key}`] || process.env[`ELEVENTY_${key}`];
+}
+
+module.exports.setEnvValue = function(key, value) {
+ if(!process?.env) {
+ return;
+ }
+
+ process.env[`BUILDAWESOME_${key}`] = value;
+ process.env[`ELEVENTY_${key}`] = value;
+}
diff --git a/src/Util/EsmResolver.js b/src/Util/EsmResolver.js
index ef49951ae..15a4bedcc 100644
--- a/src/Util/EsmResolver.js
+++ b/src/Util/EsmResolver.js
@@ -1,8 +1,8 @@
-import { createDebug } from "obug";
import { fileURLToPath } from "../Adapters/Packages/url.js";
import PathNormalizer from "./PathNormalizer.js";
+import { createDebug } from "./DebugLogUtil.js";
-const debug = createDebug("Eleventy:EsmResolver");
+const debug = createDebug("EsmResolver");
let lastModifiedPaths = new Map();
diff --git a/src/Util/EsmResolverPortAdapter.js b/src/Util/EsmResolverPortAdapter.js
index 0c47ffdde..a50597ad9 100644
--- a/src/Util/EsmResolverPortAdapter.js
+++ b/src/Util/EsmResolverPortAdapter.js
@@ -2,6 +2,7 @@ import module from "node:module";
import { fileURLToPath } from "../Adapters/Packages/url.js";
import PathNormalizer from "./PathNormalizer.js";
import { resolve, addToModifiedPaths } from "./EsmResolver.js";
+import { getEnvValue } from "./EnvironmentVars.cjs";
// ESM Cache Buster
// - registerHooks requires Node 22.15+ (and is sync only, shipped with v4.0.0-alpha.8)
@@ -10,7 +11,7 @@ import { resolve, addToModifiedPaths } from "./EsmResolver.js";
// Fixes https://github.com/11ty/eleventy/issues/3270
// ENV variable for https://github.com/11ty/eleventy/issues/3371
-if (!process?.env?.ELEVENTY_SKIP_ESM_RESOLVER) {
+if (!getEnvValue("SKIP_ESM_RESOLVER")) {
if ("registerHooks" in module) {
module.registerHooks({
// sync-only
@@ -20,7 +21,7 @@ if (!process?.env?.ELEVENTY_SKIP_ESM_RESOLVER) {
}
export function addModifiedPath(path, date) {
- if (process?.env?.ELEVENTY_SKIP_ESM_RESOLVER) {
+ if (getEnvValue("SKIP_ESM_RESOLVER")) {
return;
}
diff --git a/src/Util/EventBusUtil.js b/src/Util/EventBusUtil.js
index e7ff05d6b..98885dac8 100644
--- a/src/Util/EventBusUtil.js
+++ b/src/Util/EventBusUtil.js
@@ -1,7 +1,7 @@
import eventBus from "../EventBus.js";
-import { createDebug } from "obug";
+import { createDebug } from "./DebugLogUtil.js";
-const debug = createDebug("Eleventy:EventBus");
+const debug = createDebug("EventBus");
class EventBusUtil {
static debugCurrentListenerCounts() {
diff --git a/src/Util/FeatureTests.cjs b/src/Util/FeatureTests.cjs
deleted file mode 100644
index dea947ca6..000000000
--- a/src/Util/FeatureTests.cjs
+++ /dev/null
@@ -1,22 +0,0 @@
-function canRequireTypeScript() {
- try {
- let res = require("./TypeScript/TypeScriptSample.cts");
- return typeof res === "function";
- } catch(e) {
- // Not supported in node_modules, but we know it is supported!
- if(e.code === "ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING") {
- return true;
- }
- return false;
- }
-}
-
-const TYPESCRIPT_ENABLED = canRequireTypeScript();
-
-module.exports.isTypeScriptSupported = function() {
- if (process?.env?.ELEVENTY_SKIP_TYPESCRIPT) {
- return false;
- }
-
- return TYPESCRIPT_ENABLED;
-}
diff --git a/src/Util/FilePathUtil.js b/src/Util/FilePathUtil.js
index 1675e8ecd..9f76b1b25 100644
--- a/src/Util/FilePathUtil.js
+++ b/src/Util/FilePathUtil.js
@@ -1,4 +1,14 @@
-class FilePathUtil {
+import { isTypeScriptSupported } from "./TypeScriptFeatureTest.cjs";
+
+// the order here is important
+const ELIGIBLE_EXTENSIONS = [
+ "js",
+ "mjs",
+ "cjs",
+ ...(isTypeScriptSupported() ? ["ts", "mts", "cts"] : []),
+];
+
+export class FilePathUtil {
static isMatchingExtension(filepath, fileExtension) {
if (!fileExtension) {
return false;
@@ -16,4 +26,15 @@ class FilePathUtil {
}
}
-export { FilePathUtil };
+export function isEligibleJavaScriptFileExtension(ext) {
+ return ELIGIBLE_EXTENSIONS.includes((ext || "").toLowerCase());
+}
+
+// used for Config Paths (not yet for template data)
+export function expandEligibleJavaScriptFilePaths(fileslug) {
+ let results = [];
+ for (let ext of ELIGIBLE_EXTENSIONS) {
+ results.push(`${fileslug}.${ext}`);
+ }
+ return results;
+}
diff --git a/src/Util/FileSystemManager.js b/src/Util/FileSystemUtilities.js
similarity index 93%
rename from src/Util/FileSystemManager.js
rename to src/Util/FileSystemUtilities.js
index fdd58d747..10932d3bc 100644
--- a/src/Util/FileSystemManager.js
+++ b/src/Util/FileSystemUtilities.js
@@ -1,7 +1,7 @@
import path from "node:path";
import { mkdirSync, writeFileSync } from "node:fs";
-class FileSystemManager {
+export class FileSystemUtilities {
constructor(templateConfig) {
if (!templateConfig || templateConfig.constructor.name !== "TemplateConfig") {
throw new Error(
@@ -30,5 +30,3 @@ class FileSystemManager {
writeFileSync(filePath, content);
}
}
-
-export { FileSystemManager };
diff --git a/src/Util/GetJavaScriptData.js b/src/Util/GetJavaScriptData.js
index 7d72a64f8..b29bac413 100644
--- a/src/Util/GetJavaScriptData.js
+++ b/src/Util/GetJavaScriptData.js
@@ -1,6 +1,6 @@
-import EleventyBaseError from "../Errors/EleventyBaseError.js";
+import BaseError from "../Errors/BaseError.js";
-class JavaScriptInvalidDataFormatError extends EleventyBaseError {}
+class JavaScriptInvalidDataFormatError extends BaseError {}
export default async function (inst, inputPath, key = "data", options = {}) {
let { mixins, isObjectRequired } = Object.assign(
diff --git a/src/Util/HtmlRelativeCopy.js b/src/Util/HtmlRelativeCopy.js
index 907b7fbf1..3940896aa 100644
--- a/src/Util/HtmlRelativeCopy.js
+++ b/src/Util/HtmlRelativeCopy.js
@@ -112,6 +112,7 @@ class HtmlRelativeCopy {
}
// Relative to source file’s input path
+ // Maybe use ProjectDirectories.relativeToProjectRoot()
let source = this.getFilePathRelativeToProjectRoot(fileRef, tmplInputPath);
if (!this.isCopyableTarget(source)) {
return;
@@ -140,7 +141,7 @@ class HtmlRelativeCopy {
// We use a Set here to allow passthrough copy manager to properly error on conflicts upstream
// Only errors when different inputs write to the same output
// Also errors if attempts to write outside the output folder.
- this.#userConfig.emit("eleventy#copy", {
+ this.#userConfig.emit("buildawesome#copy", {
source,
target,
options: this.#copyOptions,
diff --git a/src/Util/ImportJsonSync.js b/src/Util/ImportJsonSync.js
index 9b247260d..4a65e64b0 100644
--- a/src/Util/ImportJsonSync.js
+++ b/src/Util/ImportJsonSync.js
@@ -1,10 +1,10 @@
import { existsSync } from "node:fs";
-import { createDebug } from "obug";
import { TemplatePath } from "@11ty/eleventy-utils";
-import { importJsonSync, eleventyPackageJson } from "./RequireUtils.js";
+import { createDebug } from "./DebugLogUtil.js";
+import { importJsonSync, corePackageJson } from "./RequireUtils.js";
-const debug = createDebug("Eleventy:ImportJsonSync");
+const debug = createDebug("ImportJsonSync");
function findFilePathInParentDirs(dir, filename) {
// `package.json` searches look in parent dirs:
@@ -23,11 +23,11 @@ function findFilePathInParentDirs(dir, filename) {
}
}
-function getEleventyPackageJson() {
- return eleventyPackageJson;
+function getCorePackageJson() {
+ return corePackageJson;
}
-// Used by EleventyServe.js for custom servers only
+// Used by Serve.js for custom servers only
function getModulePackageJson(dir) {
let filePath = findFilePathInParentDirs(TemplatePath.absolutePath(dir), "package.json");
@@ -45,8 +45,10 @@ function getWorkingProjectPackageJsonPath() {
return findFilePathInParentDirs(dir, "package.json");
}
-function getWorkingProjectPackageJson() {
- let filePath = getWorkingProjectPackageJsonPath();
+function getWorkingProjectPackageJson(filePath) {
+ if (!filePath) {
+ filePath = getWorkingProjectPackageJsonPath();
+ }
// Fails nicely
if (!filePath) {
@@ -58,7 +60,7 @@ function getWorkingProjectPackageJson() {
export {
importJsonSync,
- getEleventyPackageJson,
+ getCorePackageJson,
getModulePackageJson,
getWorkingProjectPackageJson,
findFilePathInParentDirs,
diff --git a/src/Util/JavaScriptDependencies.js b/src/Util/JavaScriptDependencies.js
index 24d2883fd..471d7acfb 100644
--- a/src/Util/JavaScriptDependencies.js
+++ b/src/Util/JavaScriptDependencies.js
@@ -8,7 +8,7 @@ import { TemplatePath } from "@11ty/eleventy-utils";
import { DepGraph } from "dependency-graph";
import { union } from "./SetUtil.js";
-import EleventyBaseError from "../Errors/EleventyBaseError.js";
+import BaseError from "../Errors/BaseError.js";
class JavaScriptDependencies {
static getErrorMessage(file, type) {
@@ -58,7 +58,7 @@ class JavaScriptDependencies {
depSet.add(dep);
}
} catch (e) {
- throw new EleventyBaseError(this.getErrorMessage(file, "CommonJS"), e);
+ throw new BaseError(this.getErrorMessage(file, "CommonJS"), e);
}
}
@@ -77,7 +77,7 @@ class JavaScriptDependencies {
depSet.add(dep);
}
} catch (e) {
- throw new EleventyBaseError(this.getErrorMessage(file, "ESM"), e);
+ throw new BaseError(this.getErrorMessage(file, "ESM"), e);
}
}
@@ -100,7 +100,7 @@ class JavaScriptDependencies {
mergeGraphs(rootGraph, graph);
} catch (e) {
- throw new EleventyBaseError(this.getErrorMessage(file, "ESM"), e);
+ throw new BaseError(this.getErrorMessage(file, "ESM"), e);
}
}
diff --git a/src/Util/Objects/ProxyWrap.js b/src/Util/Objects/ProxyWrap.js
index 14e168443..43a2343b6 100644
--- a/src/Util/Objects/ProxyWrap.js
+++ b/src/Util/Objects/ProxyWrap.js
@@ -1,7 +1,7 @@
-import { createDebug } from "obug";
import { isPlainObject } from "@11ty/eleventy-utils";
+// import { createDebug } from "../DebugLogUtil.js";
-const debug = createDebug("Dev:Eleventy:Proxy");
+// const debug = createDebug("Dev:Eleventy:Proxy");
const ProxySymbol = Symbol.for("11ty.ProxySymbol");
@@ -46,7 +46,7 @@ function wrapObject(target, fallback) {
return Array.from(s);
},
get(target, prop) {
- debug("handler:get", prop);
+ // debug("handler:get", prop);
if (prop === ProxySymbol) {
return true;
}
@@ -65,11 +65,11 @@ function wrapObject(target, fallback) {
}
let ret = wrapObject(value, Reflect.get(fallback, prop));
- debug("handler:get (primary, object)", prop);
+ // debug("handler:get (primary, object)", prop);
return ret;
}
- debug("handler:get (primary)", prop);
+ // debug("handler:get (primary)", prop);
return value;
}
@@ -86,7 +86,7 @@ function wrapObject(target, fallback) {
return fallbackValue;
}
- debug("handler:get (fallback, object)", prop);
+ // debug("handler:get (fallback, object)", prop);
// set empty object on primary
let emptyObject = {};
Reflect.set(target, prop, emptyObject);
@@ -94,17 +94,17 @@ function wrapObject(target, fallback) {
return wrapObject(emptyObject, fallbackValue);
}
- debug("handler:get (fallback)", prop);
+ // debug("handler:get (fallback)", prop);
return fallbackValue;
}
// primary *and* fallback do _not_ have prop
- debug("handler:get (not on primary or fallback)", prop);
+ // debug("handler:get (not on primary or fallback)", prop);
return value;
},
set(target, prop, value) {
- debug("handler:set", prop);
+ // debug("handler:set", prop);
return Reflect.set(target, prop, value);
},
diff --git a/src/Util/PostHtml/Attrs.js b/src/Util/PostHtml/Attrs.js
new file mode 100644
index 000000000..f76b00647
--- /dev/null
+++ b/src/Util/PostHtml/Attrs.js
@@ -0,0 +1,30 @@
+const PREFIXES = {
+ eleventy: "eleventy:",
+ buildawesome: "buildawesome:",
+};
+
+// Should always cross-map to the attribute name that exists
+// Request for eleventy: should map to buildawesome: if buildawesome: is in attrs (and vice versa)
+export function resolveAttributeName(attrs = {}, attrName = "") {
+ if (typeof attrName !== "string") {
+ return;
+ }
+ let [prefix, name] = attrName.split(":");
+ if (!prefix || !name) {
+ return;
+ }
+ if (prefix && !(prefix in PREFIXES)) {
+ return;
+ }
+ if (PREFIXES.buildawesome + name in attrs) {
+ return PREFIXES.buildawesome + name;
+ }
+ if (PREFIXES.eleventy + name in attrs) {
+ return PREFIXES.eleventy + name;
+ }
+}
+
+export function hasAttribute(attrs = {}, attrName = "") {
+ let resolved = resolveAttributeName(attrName);
+ return attrs[resolved] !== undefined;
+}
diff --git a/src/Util/ProjectDirectories.js b/src/Util/ProjectDirectories.js
index e75c3b9ae..893bdc357 100644
--- a/src/Util/ProjectDirectories.js
+++ b/src/Util/ProjectDirectories.js
@@ -6,7 +6,7 @@ import { isDynamicPattern } from "../Util/GlobMatcher.js";
import DirContains from "./DirContains.js";
/* Directories internally should always use *nix forward slashes */
-class ProjectDirectories {
+export default class ProjectDirectories {
static defaults = {
input: "./",
data: "./_data/", // Relative to input directory
@@ -25,6 +25,10 @@ class ProjectDirectories {
inputFile = undefined;
inputGlob = undefined;
+ static relativeToProjectRoot(fileOrDir) {
+ return this.normalizePath(TemplatePath.relativePath(fileOrDir));
+ }
+
// Add leading dot slash
// Use forward slashes
static normalizePath(fileOrDir) {
@@ -293,6 +297,14 @@ class ProjectDirectories {
return TemplatePath.stripLeadingSubPath(filePathRelativeToInputDir, inputDir);
}
+ // Removes output dir from path
+ getOutputPathRelativeToOutputDirectory(filePathRelativeToRootDir) {
+ let filePath = TemplatePath.addLeadingDotSlash(filePathRelativeToRootDir);
+ let outputDir = TemplatePath.addLeadingDotSlash(TemplatePath.join(this.output));
+
+ return "/" + TemplatePath.stripLeadingSubPath(filePath, outputDir);
+ }
+
// for a hypothetical Eleventy layout file
getLayoutPath(filePathRelativeToLayoutDir) {
return TemplatePath.addLeadingDotSlash(
@@ -371,5 +383,3 @@ class ProjectDirectories {
};
}
}
-
-export default ProjectDirectories;
diff --git a/src/Util/ProjectTemplateFormats.js b/src/Util/ProjectTemplateFormats.js
index 4b958b8c4..254634543 100644
--- a/src/Util/ProjectTemplateFormats.js
+++ b/src/Util/ProjectTemplateFormats.js
@@ -1,5 +1,6 @@
-import { createDebug } from "obug";
-const debug = createDebug("Eleventy:Util:ProjectTemplateFormats");
+import { createDebug } from "./DebugLogUtil.js";
+
+const debug = createDebug("Util:ProjectTemplateFormats");
class ProjectTemplateFormats {
#useAll = {};
diff --git a/src/Util/Require.js b/src/Util/Require.js
index a3fa08227..0424a6664 100644
--- a/src/Util/Require.js
+++ b/src/Util/Require.js
@@ -5,10 +5,10 @@ import { TemplatePath } from "@11ty/eleventy-utils";
import importer from "./importer.js";
import { clearRequireCache, requireCommonJsTypeScript } from "../Util/RequireUtils.js";
import { addModifiedPath } from "./EsmResolverPortAdapter.js";
-import EleventyBaseError from "../Errors/EleventyBaseError.js";
+import BaseError from "../Errors/BaseError.js";
import eventBus from "../EventBus.js";
-class EleventyImportError extends EleventyBaseError {}
+class ImportError extends BaseError {}
const requestPromiseCache = new Map();
@@ -56,7 +56,7 @@ function loadContents(path, options = {}) {
}
let lastModifiedPaths = new Map();
-eventBus.on("eleventy.importCacheReset", (fileQueue) => {
+eventBus.on("buildawesome.importcachereset", (fileQueue) => {
for (let filePath of fileQueue) {
let absolutePath = TemplatePath.absolutePath(filePath);
let newDate = Date.now();
@@ -92,7 +92,7 @@ async function dynamicImportAbsolutePath(absolutePath, options = {}) {
return JSON.parse(rawInput);
} catch (e) {
return Promise.reject(
- new EleventyImportError(getImportErrorMessage(absolutePath, "fs.readFile(json)"), e),
+ new ImportError(getImportErrorMessage(absolutePath, "fs.readFile(json)"), e),
);
}
}
@@ -187,7 +187,7 @@ async function dynamicImportAbsolutePath(absolutePath, options = {}) {
},
(error) => {
return Promise.reject(
- new EleventyImportError(getImportErrorMessage(absolutePath, `import(${type})`), error),
+ new ImportError(getImportErrorMessage(absolutePath, `import(${type})`), error),
);
},
);
@@ -210,7 +210,7 @@ async function dynamicImportRaw(localPath, type) {
}
export {
- loadContents as EleventyLoadContent,
- dynamicImport as EleventyImport,
- dynamicImportRaw as EleventyImportRaw,
+ loadContents as LoadContent,
+ dynamicImport as DynamicImport,
+ dynamicImportRaw as DynamicImportRaw,
};
diff --git a/src/Util/RequireUtils.core.js b/src/Util/RequireUtils.core.js
index 25ad2a973..e3c09a1f0 100644
--- a/src/Util/RequireUtils.core.js
+++ b/src/Util/RequireUtils.core.js
@@ -1,9 +1,9 @@
-import { EleventyLoadContent } from "./Require.js";
+import { LoadContent } from "./Require.js";
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import/with#browser_compatibility
-import eleventyPackageJson from "../../package.json" with { type: "json" };
+import corePackageJson from "../../package.json" with { type: "json" };
// We *could* prune everything but `name`, `version`, and `type` here but esbuild will still bundle the entire package.json
-export { eleventyPackageJson };
+export { corePackageJson };
// noop
export function clearRequireCache() {}
@@ -15,7 +15,7 @@ export function requireCommonJsTypeScript() {
export function importJsonSync(path) {
// should not be a no-op
- let rawInput = EleventyLoadContent(path);
+ let rawInput = LoadContent(path);
if (!rawInput) {
// should not error when file exists but is _empty_
return;
diff --git a/src/Util/RequireUtils.js b/src/Util/RequireUtils.js
index 4a08d850e..9340c3578 100644
--- a/src/Util/RequireUtils.js
+++ b/src/Util/RequireUtils.js
@@ -1,9 +1,12 @@
import { createRequire } from "node:module";
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import/with#browser_compatibility
+import corePackageJson from "../../package.json" with { type: "json" };
+
// important to clear the require.cache in CJS projects
-const require = createRequire(import.meta.url);
+export { corePackageJson };
-export const eleventyPackageJson = require("../../package.json");
+const require = createRequire(import.meta.url);
export function clearRequireCache(absolutePath) {
// ESM Eleventy when using `import()` on a CJS project file still adds to require.cache
diff --git a/src/Util/ReservedData.js b/src/Util/ReservedData.js
index ab7fa8060..8c48c35b7 100644
--- a/src/Util/ReservedData.js
+++ b/src/Util/ReservedData.js
@@ -1,8 +1,9 @@
-class EleventyReservedDataError extends TypeError {}
+class CoreReservedDataError extends TypeError {}
class ReservedData {
static fullProperties = [
"pkg", // Object.freeze’d upstream
+ "buildawesome", // Object.freeze’d upstream
"eleventy", // Object.freeze’d upstream
// "page" is only frozen for specific subproperties below
"content",
@@ -79,8 +80,8 @@ class ReservedData {
reservedNames ??= cause.reservedNames;
}
- let e = new EleventyReservedDataError(
- `You attempted to set one of Eleventy’s reserved data property names${reservedNames ? `: ${reservedNames.join(", ")}` : ""}${sourceLocation ? ` (source: ${sourceLocation})` : ""}. You can opt-out of this behavior with \`eleventyConfig.setFreezeReservedData(false)\` or rename/remove the property in your data cascade that conflicts with Eleventy’s reserved property names (e.g. \`eleventy\`, \`pkg\`, and others). Learn more: https://v3.11ty.dev/docs/data-eleventy-supplied/`,
+ let e = new CoreReservedDataError(
+ `You attempted to set one of Build Awesome’s reserved data property names${reservedNames ? `: ${reservedNames.join(", ")}` : ""}${sourceLocation ? ` (source: ${sourceLocation})` : ""}. You can opt-out of this behavior with \`$config.setFreezeReservedData(false)\` or rename/remove the property in your data cascade that conflicts with reserved property names (e.g. \`buildawesome\`, \`eleventy\`, \`pkg\`, and others). Learn more: https://v3.11ty.dev/docs/data-eleventy-supplied/`,
{ cause },
);
@@ -99,7 +100,7 @@ class ReservedData {
}
static isReservedDataError(e) {
- return e instanceof EleventyReservedDataError;
+ return e instanceof CoreReservedDataError;
}
}
diff --git a/src/Util/TemplateDepGraph.js b/src/Util/TemplateDepGraph.js
index 7752a9146..8212644de 100644
--- a/src/Util/TemplateDepGraph.js
+++ b/src/Util/TemplateDepGraph.js
@@ -1,7 +1,7 @@
import { DepGraph as DependencyGraph } from "dependency-graph";
-import { createDebug } from "obug";
+import { createDebug } from "./DebugLogUtil.js";
-const debug = createDebug("Eleventy:TemplateDepGraph");
+const debug = createDebug("TemplateDepGraph");
const COLLECTION_PREFIX = "__collection:";
diff --git a/src/Util/TransformsUtil.js b/src/Util/TransformsUtil.js
index 8c959e391..159b0b142 100644
--- a/src/Util/TransformsUtil.js
+++ b/src/Util/TransformsUtil.js
@@ -1,10 +1,11 @@
-import EleventyBaseError from "../Errors/EleventyBaseError.js";
import { isPlainObject } from "@11ty/eleventy-utils";
-import { createDebug } from "obug";
-const debug = createDebug("Eleventy:Transforms");
+import BaseError from "../Errors/BaseError.js";
+import { createDebug } from "./DebugLogUtil.js";
-class EleventyTransformError extends EleventyBaseError {}
+const debug = createDebug("Transforms");
+
+class TransformError extends BaseError {}
class TransformsUtil {
static changeTransformsToArray(transformsObj) {
@@ -56,7 +57,7 @@ class TransformsUtil {
);
}
} catch (e) {
- throw new EleventyTransformError(
+ throw new TransformError(
`Transform \`${name}\` encountered an error when transforming ${inputPath}.`,
e,
);
diff --git a/src/Util/TypeScriptFeatureTest.cjs b/src/Util/TypeScriptFeatureTest.cjs
new file mode 100644
index 000000000..17f485427
--- /dev/null
+++ b/src/Util/TypeScriptFeatureTest.cjs
@@ -0,0 +1,30 @@
+const { getEnvValue } = require("./EnvironmentVars.cjs");
+
+/**
+ * Checks whether the current Node.js runtime supports TypeScript type stripping.
+ * @returns {boolean} `true` if the runtime supports TypeScript, `false` otherwise
+ */
+function canRequireTypeScript() {
+ try {
+
+ let res = require("./TypeScript/TypeScriptSample.cts");
+ return typeof res === "function";
+ } catch(e) {
+ // Type stripping is not allowed in node_modules, but the error code tells us that it is supported by the runtime!
+ let code = e && /** @type {{ code?: string }} */ (e).code;
+ if(code === "ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING") {
+ return true;
+ }
+ return false;
+ }
+}
+
+const TYPESCRIPT_ENABLED = canRequireTypeScript();
+
+module.exports.isTypeScriptSupported = function() {
+ if (getEnvValue("SKIP_TYPESCRIPT")) {
+ return false;
+ }
+
+ return TYPESCRIPT_ENABLED;
+}
diff --git a/src/Util/FeatureTests.core.cjs b/src/Util/TypeScriptFeatureTest.core.cjs
similarity index 100%
rename from src/Util/FeatureTests.core.cjs
rename to src/Util/TypeScriptFeatureTest.core.cjs
diff --git a/src/Util/importer.core.js b/src/Util/importer.core.js
index e2cc4c354..1ee824794 100644
--- a/src/Util/importer.core.js
+++ b/src/Util/importer.core.js
@@ -2,13 +2,13 @@ import { existsSync, readFileSync } from "node:fs";
import { importFromString } from "import-module-string";
import { fileURLToPath } from "../Adapters/Packages/url.js";
-import { EleventyLoadContent } from "./Require.js";
+import { LoadContent } from "./Require.js";
export default function importer(relPath) {
let filePath = fileURLToPath(relPath);
// `import-module-string` can now `import()` so we avoid needing to esbuild these
- let code = EleventyLoadContent(filePath);
+ let code = LoadContent(filePath);
return importFromString(code, {
implicitExports: false,
filePath,
diff --git a/src/Watch.js b/src/Watch.js
index 62f35adcb..c1b8bdf41 100644
--- a/src/Watch.js
+++ b/src/Watch.js
@@ -1,11 +1,11 @@
-import { createDebug } from "obug";
import { TemplatePath } from "@11ty/eleventy-utils";
import chokidar from "chokidar";
+import { createDebug } from "./Util/DebugLogUtil.js";
import { isGlobMatch } from "./Util/GlobMatcher.js";
import { GlobStripper } from "./Util/GlobStripper.js";
-const debug = createDebug("Eleventy:Watch");
+const debug = createDebug("Watch");
export class Watch {
/** @type {module:chokidar} */
@@ -14,6 +14,8 @@ export class Watch {
#watchedGlobs = [];
/** @type {Set} */
#ignoredGlobs = [];
+ /** @type {Promise} */
+ #ready;
constructor(config) {
if (!config || config.constructor.name !== "TemplateConfig") {
@@ -107,21 +109,34 @@ export class Watch {
return path;
})
.filter(Boolean);
-
this.#chokidar = chokidar.watch(targets, options);
// Note: if there are no watch targets the `ready` event doesn’t fire so skip it
if (targets.length > 0) {
- await new Promise((resolve) => {
+ this.#ready = await new Promise((resolve) => {
this.#chokidar.on("ready", () => resolve());
});
+ } else {
+ this.#ready = Promise.resolve();
}
}
+ async getWatched() {
+ if (this.#ready) {
+ await this.#ready;
+ }
+
+ return this.#chokidar.getWatched();
+ }
+
on(event, callback) {
this.#chokidar.on(event, callback);
}
+ emit(event, ...args) {
+ this.#chokidar.emit(event, ...args);
+ }
+
async close() {
return this.#chokidar?.close();
}
diff --git a/src/WatchTargets.js b/src/WatchTargets.js
index 77879c689..2c4c7e165 100644
--- a/src/WatchTargets.js
+++ b/src/WatchTargets.js
@@ -162,7 +162,7 @@ export default class WatchTargets {
}
}
- eventBus.emit("eleventy.importCacheReset", paths);
+ eventBus.emit("buildawesome.importcachereset", paths);
}
getNewTargetsSinceLastReset() {
diff --git a/src/defaultConfig.js b/src/defaultConfig.js
index 21225cbd7..daa7f5a11 100644
--- a/src/defaultConfig.js
+++ b/src/defaultConfig.js
@@ -27,15 +27,14 @@ import TransformsUtil from "./Util/TransformsUtil.js";
* @property {string} [markdownTemplateEngine='liquid'] - Template engine to process markdown files with.
* @property {string} [htmlTemplateEngine='liquid'] - Template engine to process html files with.
* @property {boolean} [dataTemplateEngine=false] - Changed in v1.0
- * @property {string} [jsDataFileSuffix='.11tydata'] - File suffix for jsData files.
* @property {object} keys
* @property {string} [keys.package='pkg'] - Global data property for package.json data
* @property {string} [keys.layout='layout']
* @property {string} [keys.permalink='permalink']
* @property {string} [keys.permalinkRoot='permalinkBypassOutputDir']
* @property {string} [keys.engineOverride='templateEngineOverride']
- * @property {string} [keys.computed='eleventyComputed']
- * @property {string} [keys.dataSchema='eleventyDataSchema']
+ * @property {string} [keys.computed='buildawesomeComputed']
+ * @property {string} [keys.dataSchema='buildawesomeDataSchema']
* @property {object} dir
* @property {string} [dir.input='.']
* @property {string} [dir.includes='_includes']
@@ -73,6 +72,7 @@ export default function (config) {
return {
templateFormats: ["liquid", "md", "njk", "html", "11ty.js"],
+
// to add a parent directory structure to URLs (not reflected on the file system), change this
pathPrefix: "/",
markdownTemplateEngine: "liquid",
@@ -80,7 +80,7 @@ export default function (config) {
// Renamed from `jsDataFileSuffix` in 2.0 (and swapped to an Array)
// If you remove "" we won’t look for dir/dir.json or file.json
- dataFileSuffixes: [".11tydata", ""],
+ dataFileSuffixes: [".data", ".11tydata", ""],
// "index" will look for `directory/index.*` directory data files instead of `directory/directory.*`
dataFileDirBaseNameOverride: false,
@@ -92,8 +92,9 @@ export default function (config) {
permalink: "permalink",
permalinkRoot: "permalinkBypassOutputDir",
engineOverride: "templateEngineOverride",
- computed: "eleventyComputed",
- dataSchema: "eleventyDataSchema",
+ computed: "buildawesomeComputed",
+ dataSchema: "buildawesomeDataSchema",
+ import: "buildawesomeImport",
},
// Deprecated, define using `export const directories = {}` instead.
diff --git a/src/defaultConfigExtended.client.js b/src/defaultConfigExtended.client.js
index f4345e974..e7489b41d 100644
--- a/src/defaultConfigExtended.client.js
+++ b/src/defaultConfigExtended.client.js
@@ -1,13 +1,13 @@
export default function (config) {
config.addFilter("url", () => {
throw new Error(
- "The `url` filter is not included with the `@11ty/client` bundle. Use the `@11ty/client/eleventy` bundle.",
+ "The `url` filter is not included with the `@11ty/client` bundle. Use the `@11ty/client/core-fs` bundle.",
);
});
config.addFilter("inputPathToUrl", () => {
throw new Error(
- "The `inputPathToUrl` filter is not included with the `@11ty/client` bundle. Use the larger `@11ty/client/eleventy` bundle.",
+ "The `inputPathToUrl` filter is not included with the `@11ty/client` bundle. Use the larger `@11ty/client/core-fs` bundle.",
);
});
diff --git a/test/BundlePluginTest.js b/test/BundlePluginTest.js
index ca891a329..96a57d318 100644
--- a/test/BundlePluginTest.js
+++ b/test/BundlePluginTest.js
@@ -1,13 +1,13 @@
import test from "ava";
-import Eleventy from "../src/Eleventy.js";
+import Eleventy from "../src/Core.js";
test("addBundle", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPlugin(() => {
- eleventyConfig.addBundle("css")
+ config: $config => {
+ $config.addPlugin(() => {
+ $config.addBundle("css")
});
- eleventyConfig.addTemplate("index.njk", "{% css %}/* Hi */{% endcss %}");
+ $config.addTemplate("index.njk", "{% css %}/* Hi */{% endcss %}");
}
});
@@ -17,12 +17,12 @@ test("addBundle", async (t) => {
test("addBundle (empty css)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPlugin(() => {
- eleventyConfig.addBundle("css");
+ config: $config => {
+ $config.addPlugin(() => {
+ $config.addBundle("css");
});
- eleventyConfig.addTemplate("index.njk", "Hi");
+ $config.addTemplate("index.njk", "Hi");
}
});
@@ -32,12 +32,12 @@ test("addBundle (empty css)", async (t) => {
test("addBundle (empty js)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPlugin(() => {
- eleventyConfig.addBundle("js");
+ config: $config => {
+ $config.addPlugin(() => {
+ $config.addBundle("js");
});
- eleventyConfig.addTemplate("index.njk", "Hi");
+ $config.addTemplate("index.njk", "Hi");
}
});
@@ -47,12 +47,12 @@ test("addBundle (empty js)", async (t) => {
test("Empty script node is removed (not using bundle)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPlugin(() => {
- eleventyConfig.addBundle("js");
+ config: $config => {
+ $config.addPlugin(() => {
+ $config.addBundle("js");
});
- eleventyConfig.addTemplate("index.njk", "Hi");
+ $config.addTemplate("index.njk", "Hi");
}
});
@@ -63,12 +63,12 @@ test("Empty script node is removed (not using bundle)", async (t) => {
test("Empty style node is removed (not using bundle)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPlugin(() => {
- eleventyConfig.addBundle("css");
+ config: $config => {
+ $config.addPlugin(() => {
+ $config.addBundle("css");
});
- eleventyConfig.addTemplate("index.njk", "Hi");
+ $config.addTemplate("index.njk", "Hi");
}
});
@@ -78,12 +78,12 @@ test("Empty style node is removed (not using bundle)", async (t) => {
test("Empty link node is removed (not using bundle)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPlugin(() => {
- eleventyConfig.addBundle("css");
+ config: $config => {
+ $config.addPlugin(() => {
+ $config.addBundle("css");
});
- eleventyConfig.addTemplate("index.njk", "Hi ");
+ $config.addTemplate("index.njk", "Hi ");
}
});
@@ -93,12 +93,12 @@ test("Empty link node is removed (not using bundle)", async (t) => {
test("Empty link node is removed (no href attribute at all, not using bundle)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPlugin(() => {
- eleventyConfig.addBundle("css");
+ config: $config => {
+ $config.addPlugin(() => {
+ $config.addBundle("css");
});
- eleventyConfig.addTemplate("index.njk", "Hi ");
+ $config.addTemplate("index.njk", "Hi ");
}
});
@@ -108,12 +108,12 @@ test("Empty link node is removed (no href attribute at all, not using bundle)",
test("Empty link node is kept (no rel attribute, not using bundle)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPlugin(() => {
- eleventyConfig.addBundle("css");
+ config: $config => {
+ $config.addPlugin(() => {
+ $config.addBundle("css");
});
- eleventyConfig.addTemplate("index.njk", "Hi ");
+ $config.addTemplate("index.njk", "Hi ");
}
});
diff --git a/test/CoreTest-ComputedData.js b/test/CoreTest-ComputedData.js
new file mode 100644
index 000000000..1a65e5960
--- /dev/null
+++ b/test/CoreTest-ComputedData.js
@@ -0,0 +1,74 @@
+import test from "ava";
+import BuildAwesome from "../src/Core.js";
+
+test("Using buildawesomeComputed and eleventyComputed (prefers former)", async (t) => {
+ let elev = new BuildAwesome("./test/stubs-virtual/", undefined, {
+ config: configApi => {
+ // will override
+ configApi.addGlobalData("buildawesomeComputed", () => {
+ return {
+ key1: "value1"
+ }
+ });
+
+ configApi.addGlobalData("eleventyComputed", () => {
+ return {
+ key2: "value2"
+ }
+ });
+
+ configApi.addTemplate("index.njk", "{{ key1 }}", { key1: "original" });
+ }
+ });
+
+ let results = await elev.toJSON();
+ t.is(results.length, 1);
+ t.is(results[0].content, `value1`);
+});
+
+test("Using buildawesomeComputed and eleventyComputed (prefers former, reverse add)", async (t) => {
+ let elev = new BuildAwesome("./test/stubs-virtual/", undefined, {
+ config: configApi => {
+ configApi.addGlobalData("eleventyComputed", () => {
+ return {
+ key2: "value2"
+ }
+ });
+
+ // will override
+ configApi.addGlobalData("buildawesomeComputed", () => {
+ return {
+ key1: "value1"
+ }
+ });
+
+ configApi.addTemplate("index.njk", "{{ key1 }}", { key1: "original" });
+ }
+ });
+
+ let results = await elev.toJSON();
+ t.is(results.length, 1);
+ t.is(results[0].content, `value1`);
+});
+
+test("Using buildawesomeComputed.permalink", async (t) => {
+ let elev = new BuildAwesome("./test/stubs-virtual/", undefined, {
+ config: configApi => {
+ configApi.addGlobalData("permalink", () => {
+ return () => "/rewritten2.html"
+ });
+
+ // will override
+ configApi.addGlobalData("buildawesomeComputed.permalink", () => {
+ return () => "/rewritten1.html"
+ });
+
+ configApi.addTemplate("index.njk", "{{ key1 }}", { key1: "original" });
+ }
+ });
+
+ let results = await elev.toJSON();
+ t.is(results.length, 1);
+ t.is(results[0].content, `original`);
+ t.is(results[0].url, `/rewritten1.html`);
+});
diff --git a/test/EleventyTest-CustomDateParsing.js b/test/CoreTest-CustomDateParsing.js
similarity index 70%
rename from test/EleventyTest-CustomDateParsing.js
rename to test/CoreTest-CustomDateParsing.js
index 02818b334..30ce78ab4 100644
--- a/test/EleventyTest-CustomDateParsing.js
+++ b/test/CoreTest-CustomDateParsing.js
@@ -1,7 +1,7 @@
import { createRequire } from "node:module";
import test from "ava";
import { DateTime } from "luxon";
-import Eleventy from "../src/Eleventy.js";
+import Eleventy from "../src/Core.js";
const require = createRequire(import.meta.url);
@@ -9,11 +9,11 @@ test("Custom date parsing callback (return string), Issue #867", async (t) => {
t.plan(3);
let elev = new Eleventy("./test/stubs-virtual/", "./test/stubs-virtual/", {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("test.html", `# Markdown`);
- eleventyConfig.dataFilterSelectors.add("page.date");
+ config: $config => {
+ $config.addTemplate("test.html", `# Markdown`);
+ $config.dataFilterSelectors.add("page.date");
- eleventyConfig.addDateParsing(function(dateValue) {
+ $config.addDateParsing(function(dateValue) {
t.truthy(this.page.inputPath);
t.is(dateValue, undefined);
return "2001-01-01T12:00:00Z";
@@ -30,14 +30,14 @@ test("Custom date parsing callback (input a non-YAML date format), Issue #867",
t.plan(2);
let elev = new Eleventy("./test/stubs-virtual/", "./test/stubs-virtual/", {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("test.html", `---
+ config: $config => {
+ $config.addTemplate("test.html", `---
date: 2019-08-31 23:59:56 America/New_York
---
# Markdown`);
- eleventyConfig.dataFilterSelectors.add("page.date");
+ $config.dataFilterSelectors.add("page.date");
- eleventyConfig.addDateParsing(function(dateValue) {
+ $config.addDateParsing(function(dateValue) {
t.is(dateValue, "2019-08-31 23:59:56 America/New_York");
// returns DateTime instance from Luxon
return DateTime.fromFormat(dateValue, "yyyy-MM-dd hh:mm:ss z");
@@ -54,11 +54,11 @@ test("Custom date parsing callback (return Date), Issue #867", async (t) => {
t.plan(3);
let elev = new Eleventy("./test/stubs-virtual/", "./test/stubs-virtual/", {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("test.html", `# Markdown`);
- eleventyConfig.dataFilterSelectors.add("page.date");
+ config: $config => {
+ $config.addTemplate("test.html", `# Markdown`);
+ $config.dataFilterSelectors.add("page.date");
- eleventyConfig.addDateParsing(function(dateValue) {
+ $config.addDateParsing(function(dateValue) {
t.truthy(this.page.inputPath);
t.is(dateValue, undefined);
return new Date(Date.UTC(2001,0,1,12));
@@ -75,13 +75,13 @@ test("Custom date parsing callback (using date from data cascade, return string)
t.plan(3);
let elev = new Eleventy("./test/stubs-virtual/", "./test/stubs-virtual/", {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("test.html", `# Markdown`, {
+ config: $config => {
+ $config.addTemplate("test.html", `# Markdown`, {
date: new Date(Date.UTC(2002, 0, 1, 12))
});
- eleventyConfig.dataFilterSelectors.add("page.date");
+ $config.dataFilterSelectors.add("page.date");
- eleventyConfig.addDateParsing(function (dateValue) {
+ $config.addDateParsing(function (dateValue) {
t.truthy(this.page.inputPath);
t.true(dateValue instanceof Date);
return "2001-01-01T12:00:00Z";
@@ -98,19 +98,19 @@ test("Custom date parsing callback (two, return undefined/falsy), Issue #867", a
t.plan(5);
let elev = new Eleventy("./test/stubs-virtual/", "./test/stubs-virtual/", {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("test.html", `# Markdown`, {
+ config: $config => {
+ $config.addTemplate("test.html", `# Markdown`, {
date: new Date(Date.UTC(2003, 0, 1, 12))
});
- eleventyConfig.dataFilterSelectors.add("page.date");
+ $config.dataFilterSelectors.add("page.date");
- eleventyConfig.addDateParsing(function (dateValue) {
+ $config.addDateParsing(function (dateValue) {
t.truthy(this.page.inputPath);
t.deepEqual(dateValue, new Date(Date.UTC(2003,0,1,12)));
// return nothing
});
- eleventyConfig.addDateParsing(function (dateValue) {
+ $config.addDateParsing(function (dateValue) {
t.truthy(this.page.inputPath);
t.deepEqual(dateValue, new Date(Date.UTC(2003,0,1,12)));
// return nothing
@@ -127,13 +127,13 @@ test("Custom date parsing callback (return explicit false), Issue #867", async (
t.plan(2);
let elev = new Eleventy("./test/stubs-virtual/", "./test/stubs-virtual/", {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("test.html", `# Markdown`, {
+ config: $config => {
+ $config.addTemplate("test.html", `# Markdown`, {
date: new Date(Date.UTC(2003, 0, 1, 12))
});
- eleventyConfig.dataFilterSelectors.add("page.date");
+ $config.dataFilterSelectors.add("page.date");
- eleventyConfig.addDateParsing(function (dateValue) {
+ $config.addDateParsing(function (dateValue) {
t.truthy(this.page.inputPath);
return false;
});
@@ -150,17 +150,17 @@ test("Custom date parsing callbacks (two, last wins, return string), Issue #867"
t.plan(5);
let elev = new Eleventy("./test/stubs-virtual/", "./test/stubs-virtual/", {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("test.html", `# Markdown`);
- eleventyConfig.dataFilterSelectors.add("page.date");
+ config: $config => {
+ $config.addTemplate("test.html", `# Markdown`);
+ $config.dataFilterSelectors.add("page.date");
- eleventyConfig.addDateParsing(function (dateValue) {
+ $config.addDateParsing(function (dateValue) {
t.truthy(this.page.inputPath);
t.is(dateValue, undefined);
return "2010-01-01T12:00:00Z";
});
- eleventyConfig.addDateParsing(function (dateValue) {
+ $config.addDateParsing(function (dateValue) {
t.truthy(this.page.inputPath);
t.is(dateValue, "2010-01-01T12:00:00Z");
return "2001-01-01T12:00:00Z";
@@ -179,11 +179,11 @@ test("instanceof DateTime issue, Issue #3674", async (t) => {
// this test *requires* a non-virtual template to repro
let elev = new Eleventy("./test/stubs/index.html", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("test.html", `# Markdown`);
- eleventyConfig.dataFilterSelectors.add("page.date");
+ config: $config => {
+ $config.addTemplate("test.html", `# Markdown`);
+ $config.dataFilterSelectors.add("page.date");
- eleventyConfig.addDateParsing(function (dateValue) {
+ $config.addDateParsing(function (dateValue) {
return DateTime.fromISO("2001-01-01T12:00:00Z");
});
}
diff --git a/test/EleventyTest-PageData.js b/test/CoreTest-PageData.js
similarity index 58%
rename from test/EleventyTest-PageData.js
rename to test/CoreTest-PageData.js
index 8fe703a84..60a7fd687 100644
--- a/test/EleventyTest-PageData.js
+++ b/test/CoreTest-PageData.js
@@ -1,10 +1,10 @@
import test from "ava";
-import Eleventy from "../src/Eleventy.js";
+import Eleventy from "../src/Core.js";
-test("#3794: page.inputPathDir and page.dir", async (t) => {
+test.skip("#3794: page.inputPathDir and page.dir", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function(eleventyConfig) {
- eleventyConfig.addTemplate("test.njk", `{{ page.inputPathDir }} and {{ page.dir }}`, {});
+ config: function($config) {
+ $config.addTemplate("test.njk", `{{ page.inputPathDir }} and {{ page.dir }}`, {});
}
});
@@ -12,10 +12,10 @@ test("#3794: page.inputPathDir and page.dir", async (t) => {
t.is(result.content, "./test/stubs-virtual/ and /test/");
});
-test("#3794: page.inputPathDir and page.dir (index file)", async (t) => {
+test.skip("#3794: page.inputPathDir and page.dir (index file)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function(eleventyConfig) {
- eleventyConfig.addTemplate("index.njk", `{{ page.inputPathDir }} and {{ page.dir }}`, {});
+ config: function($config) {
+ $config.addTemplate("index.njk", `{{ page.inputPathDir }} and {{ page.dir }}`, {});
}
});
@@ -23,10 +23,10 @@ test("#3794: page.inputPathDir and page.dir (index file)", async (t) => {
t.is(result.content, "./test/stubs-virtual/ and /");
});
-test("#3794: page.inputPathDir and page.dir (paginated)", async (t) => {
+test.skip("#3794: page.inputPathDir and page.dir (paginated)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function(eleventyConfig) {
- eleventyConfig.addTemplate("index.njk", `{{ page.inputPathDir }} and {{ page.dir }}`, {
+ config: function($config) {
+ $config.addTemplate("index.njk", `{{ page.inputPathDir }} and {{ page.dir }}`, {
data: [1,2,3],
pagination: {
data: "data",
@@ -45,10 +45,10 @@ test("#3794: page.inputPathDir and page.dir (paginated)", async (t) => {
t.is(page3.content, "./test/stubs-virtual/ and /2/");
});
-test("#3794: page.inputPathDir and page.dir (with file slug and index)", async (t) => {
+test.skip("#3794: page.inputPathDir and page.dir (with file slug and index)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function(eleventyConfig) {
- eleventyConfig.addTemplate("yawn/index.njk", `{{ page.inputPathDir }} and {{ page.dir }}`, {
+ config: function($config) {
+ $config.addTemplate("yawn/index.njk", `{{ page.inputPathDir }} and {{ page.dir }}`, {
permalink: "{{ page.filePathStem }}.{{ page.outputFileExtension }}"
});
}
@@ -61,10 +61,10 @@ test("#3794: page.inputPathDir and page.dir (with file slug and index)", async (
t.is(page1.content, "./test/stubs-virtual/yawn/ and /yawn/");
});
-test("#3794: page.inputPathDir and page.dir (with file slug and not-index)", async (t) => {
+test.skip("#3794: page.inputPathDir and page.dir (with file slug and not-index)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function(eleventyConfig) {
- eleventyConfig.addTemplate("yawn/test.njk", `{{ page.inputPathDir }} and {{ page.dir }}`, {
+ config: function($config) {
+ $config.addTemplate("yawn/test.njk", `{{ page.inputPathDir }} and {{ page.dir }}`, {
permalink: "{{ page.filePathStem }}.{{ page.outputFileExtension }}"
});
}
@@ -77,10 +77,10 @@ test("#3794: page.inputPathDir and page.dir (with file slug and not-index)", asy
t.is(page1.content, "./test/stubs-virtual/yawn/ and /yawn/");
});
-test("#3794: page.inputPathDir and page.dir (paginated with file slug and not-index)", async (t) => {
+test.skip("#3794: page.inputPathDir and page.dir (paginated with file slug and not-index)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function(eleventyConfig) {
- eleventyConfig.addTemplate("yawn/test.njk", `{{ page.inputPathDir }} and {{ page.dir }}`, {
+ config: function($config) {
+ $config.addTemplate("yawn/test.njk", `{{ page.inputPathDir }} and {{ page.dir }}`, {
data: [1,2,3],
pagination: {
data: "data",
@@ -100,10 +100,10 @@ test("#3794: page.inputPathDir and page.dir (paginated with file slug and not-in
t.is(page3.content, "./test/stubs-virtual/yawn/ and /2/yawn/");
});
-test("#3794: page.inputPathDir and page.dir (permalink: false)", async (t) => {
+test.skip("#3794: page.inputPathDir and page.dir (permalink: false)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function(eleventyConfig) {
- eleventyConfig.addTemplate("index.njk", `{{ page.inputPathDir }} and {{ page.dir }}`, { permalink: false });
+ config: function($config) {
+ $config.addTemplate("index.njk", `{{ page.inputPathDir }} and {{ page.dir }}`, { permalink: false });
}
});
diff --git a/test/EleventyTest-Preprocessors.js b/test/CoreTest-Preprocessors.js
similarity index 70%
rename from test/EleventyTest-Preprocessors.js
rename to test/CoreTest-Preprocessors.js
index 3d6a4ad2b..081ff9bdf 100644
--- a/test/EleventyTest-Preprocessors.js
+++ b/test/CoreTest-Preprocessors.js
@@ -1,18 +1,18 @@
import test from "ava";
-import Eleventy from "../src/Eleventy.js";
+import Eleventy from "../src/Core.js";
test("#188: Content preprocessing (dot in file extension)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPreprocessor("drafts", ".njk", (data, content) => {
+ config: $config => {
+ $config.addPreprocessor("drafts", ".njk", (data, content) => {
if(data.draft) {
return false;
}
return `Hello ${content}`;
});
- eleventyConfig.addTemplate("index.njk", "Before");
- eleventyConfig.addTemplate("draft.njk", "Before", { draft: true });
+ $config.addTemplate("index.njk", "Before");
+ $config.addTemplate("draft.njk", "Before", { draft: true });
}
});
@@ -23,16 +23,16 @@ test("#188: Content preprocessing (dot in file extension)", async (t) => {
test("#188: Content preprocessing (no dot in file extension)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPreprocessor("drafts", "njk", (data, content) => {
+ config: $config => {
+ $config.addPreprocessor("drafts", "njk", (data, content) => {
if(data.draft) {
return false;
}
return `Hello ${content}`;
});
- eleventyConfig.addTemplate("index.njk", "Before");
- eleventyConfig.addTemplate("draft.njk", "Before", { draft: true });
+ $config.addTemplate("index.njk", "Before");
+ $config.addTemplate("draft.njk", "Before", { draft: true });
}
});
@@ -44,16 +44,16 @@ test("#188: Content preprocessing (no dot in file extension)", async (t) => {
test("#188: Content preprocessing (array, no dot in file extension)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPreprocessor("drafts", ["njk"], (data, content) => {
+ config: $config => {
+ $config.addPreprocessor("drafts", ["njk"], (data, content) => {
if(data.draft) {
return false;
}
return `Hello ${content}`;
});
- eleventyConfig.addTemplate("index.njk", "Before");
- eleventyConfig.addTemplate("draft.njk", "Before", { draft: true });
+ $config.addTemplate("index.njk", "Before");
+ $config.addTemplate("draft.njk", "Before", { draft: true });
}
});
@@ -64,16 +64,16 @@ test("#188: Content preprocessing (array, no dot in file extension)", async (t)
test("#188: Content preprocessing (array, dot in file extension)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPreprocessor("drafts", [".njk"], (data, content) => {
+ config: $config => {
+ $config.addPreprocessor("drafts", [".njk"], (data, content) => {
if(data.draft) {
return false;
}
return `Hello ${content}`;
});
- eleventyConfig.addTemplate("index.njk", "Before");
- eleventyConfig.addTemplate("draft.njk", "Before", { draft: true });
+ $config.addTemplate("index.njk", "Before");
+ $config.addTemplate("draft.njk", "Before", { draft: true });
}
});
@@ -84,16 +84,16 @@ test("#188: Content preprocessing (array, dot in file extension)", async (t) =>
test("#188: Content preprocessing (wildcard)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPreprocessor("drafts", "*", (data, content) => {
+ config: $config => {
+ $config.addPreprocessor("drafts", "*", (data, content) => {
if(data.draft) {
return false;
}
return `Hello ${content}`;
});
- eleventyConfig.addTemplate("index.njk", "Before");
- eleventyConfig.addTemplate("draft.njk", "Before", { draft: true });
+ $config.addTemplate("index.njk", "Before");
+ $config.addTemplate("draft.njk", "Before", { draft: true });
}
});
@@ -107,8 +107,8 @@ test("addPreprocessor with 11ty.js, Issue #3433", async (t) => {
t.plan(5);
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPreprocessor("testing", "11ty.js", (data, content) => {
+ config: $config => {
+ $config.addPreprocessor("testing", "11ty.js", (data, content) => {
t.is( typeof content, "function" );
t.is(content(), "Hello!");
@@ -119,7 +119,7 @@ test("addPreprocessor with 11ty.js, Issue #3433", async (t) => {
};
});
- eleventyConfig.addTemplate("template.11ty.js", function() {
+ $config.addTemplate("template.11ty.js", function() {
return "Hello!"
});
}
@@ -136,13 +136,13 @@ test("addPreprocessor and addExtension, Issue #3433", async (t) => {
t.plan(5);
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplateFormats("11ty.test");
- eleventyConfig.addExtension("11ty.test", {
+ config: $config => {
+ $config.addTemplateFormats("11ty.test");
+ $config.addExtension("11ty.test", {
key: "11ty.js",
});
- eleventyConfig.addPreprocessor("testing", "11ty.test", (data, content) => {
+ $config.addPreprocessor("testing", "11ty.test", (data, content) => {
t.is( typeof content, "function" );
t.is(content(), "Hello!");
@@ -153,7 +153,7 @@ test("addPreprocessor and addExtension, Issue #3433", async (t) => {
};
});
- eleventyConfig.addTemplate("template.11ty.test", function() {
+ $config.addTemplate("template.11ty.test", function() {
return "Hello!"
});
}
@@ -169,16 +169,16 @@ test("addPreprocessor and addExtension with custom `compile` (defaultRenderer),
t.plan(5);
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplateFormats("11ty.test");
- eleventyConfig.addExtension("11ty.test", {
+ config: $config => {
+ $config.addTemplateFormats("11ty.test");
+ $config.addExtension("11ty.test", {
key: "11ty.js",
compile: function() {
return this.defaultRenderer;
}
});
- eleventyConfig.addPreprocessor("testing", "11ty.test", (data, content) => {
+ $config.addPreprocessor("testing", "11ty.test", (data, content) => {
t.is( typeof content, "function" );
t.is(content(), "Hello!");
@@ -189,7 +189,7 @@ test("addPreprocessor and addExtension with custom `compile` (defaultRenderer),
};
});
- eleventyConfig.addTemplate("template.11ty.test", function() {
+ $config.addTemplate("template.11ty.test", function() {
return "Hello!"
});
}
@@ -205,9 +205,9 @@ test("addPreprocessor and addExtension with custom `compile` (re-use render func
t.plan(5);
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplateFormats("11ty.test");
- eleventyConfig.addExtension("11ty.test", {
+ config: $config => {
+ $config.addTemplateFormats("11ty.test");
+ $config.addExtension("11ty.test", {
key: "11ty.js",
compile: function(content) {
return function() {
@@ -216,7 +216,7 @@ test("addPreprocessor and addExtension with custom `compile` (re-use render func
}
});
- eleventyConfig.addPreprocessor("testing", "11ty.test", (data, content) => {
+ $config.addPreprocessor("testing", "11ty.test", (data, content) => {
t.is( typeof content, "function" );
t.is(content(), "Hello!");
@@ -227,7 +227,7 @@ test("addPreprocessor and addExtension with custom `compile` (re-use render func
};
});
- eleventyConfig.addTemplate("template.11ty.test", function() {
+ $config.addTemplate("template.11ty.test", function() {
return "Hello!"
});
}
@@ -243,9 +243,9 @@ test("addPreprocessor and addExtension with custom `compile` (new render functio
t.plan(7);
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplateFormats("11ty.test");
- eleventyConfig.addExtension("11ty.test", {
+ config: $config => {
+ $config.addTemplateFormats("11ty.test");
+ $config.addExtension("11ty.test", {
key: "11ty.js",
compile: function(content) {
// check preprocessor override
@@ -258,7 +258,7 @@ test("addPreprocessor and addExtension with custom `compile` (new render functio
}
});
- eleventyConfig.addPreprocessor("testing", "11ty.test", (data, content) => {
+ $config.addPreprocessor("testing", "11ty.test", (data, content) => {
// check template content directly
t.is( typeof content, "function" );
t.is(content(), "Original template content");
@@ -270,7 +270,7 @@ test("addPreprocessor and addExtension with custom `compile` (new render functio
};
});
- eleventyConfig.addTemplate("template.11ty.test", function() {
+ $config.addTemplate("template.11ty.test", function() {
return "Original template content"
});
}
@@ -286,8 +286,8 @@ test("addPreprocessor and addExtension with custom `compile` (new render functio
test("Tags in pages excluded with preprocessing should not populate collections props", async (t) => {
let preprocessorRuns = 0;
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPreprocessor("drafts", "njk", (data, content) => {
+ config: $config => {
+ $config.addPreprocessor("drafts", "njk", (data, content) => {
preprocessorRuns++;
if(data.draft) {
return false;
@@ -295,7 +295,7 @@ test("Tags in pages excluded with preprocessing should not populate collections
return `Hello ${content}`;
});
- eleventyConfig.addTemplate("paged.njk", "{{ tag }}", {
+ $config.addTemplate("paged.njk", "{{ tag }}", {
pagination: {
data: "collections",
size: 1,
@@ -304,8 +304,8 @@ test("Tags in pages excluded with preprocessing should not populate collections
},
permalink: "/{{ tag }}/"
});
- eleventyConfig.addTemplate("source.njk", "Before", { tags: ["yep"] });
- eleventyConfig.addTemplate("source-draft.njk", "Before", { draft: true, tags: ["nope"] });
+ $config.addTemplate("source.njk", "Before", { tags: ["yep"] });
+ $config.addTemplate("source-draft.njk", "Before", { draft: true, tags: ["nope"] });
}
});
@@ -325,13 +325,13 @@ test("#4292: Preprocessors should only run once per build (bug running twice dur
let preprocessorRuns = 0;
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPreprocessor("drafts", ".njk", (data, content) => {
+ config: $config => {
+ $config.addPreprocessor("drafts", ".njk", (data, content) => {
preprocessorRuns++;
return `Hello ${content} Suffix`;
});
- eleventyConfig.addTemplate("index.njk", "Before");
+ $config.addTemplate("index.njk", "Before");
}
});
@@ -350,8 +350,8 @@ test("#4292: Preprocessors mutable data", async (t) => {
t.plan(9);
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addPreprocessor("drafts", ".njk", (data, content) => {
+ config: $config => {
+ $config.addPreprocessor("drafts", ".njk", (data, content) => {
t.is(data.title, "Title");
data.title += " (draft)";
t.is(data.title, "Title (draft)");
@@ -360,7 +360,7 @@ test("#4292: Preprocessors mutable data", async (t) => {
return content;
});
- eleventyConfig.addTemplate("index.njk", "Hello {{title}} Suffix", {
+ $config.addTemplate("index.njk", "Hello {{title}} Suffix", {
title: "Title"
});
}
diff --git a/test/EleventyTest-Shortcodes.js b/test/CoreTest-Shortcodes.js
similarity index 56%
rename from test/EleventyTest-Shortcodes.js
rename to test/CoreTest-Shortcodes.js
index 6e610991f..2cb512ed4 100644
--- a/test/EleventyTest-Shortcodes.js
+++ b/test/CoreTest-Shortcodes.js
@@ -1,18 +1,18 @@
import test from "ava";
-import Eleventy from "../src/Eleventy.js";
+import Eleventy from "../src/Core.js";
test.skip("#3400: Both a paired and unpaired shortcode.", async (t) => {
let count = 0;
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function(eleventyConfig) {
- eleventyConfig.addShortcode("single", function() {
+ config: function($config) {
+ $config.addShortcode("single", function() {
count++;
});
- eleventyConfig.addPairedShortcode("single", function() {
+ $config.addPairedShortcode("single", function() {
count++;
});
- eleventyConfig.addTemplate("test.njk", `{% single %}
+ $config.addTemplate("test.njk", `{% single %}
{% single %}{% endsingle %}`, {});
}
});
diff --git a/test/EleventyVirtualTemplatesTest.js b/test/CoreTest-VirtualTemplates.js
similarity index 77%
rename from test/EleventyVirtualTemplatesTest.js
rename to test/CoreTest-VirtualTemplates.js
index c2751f4bb..1e738359f 100644
--- a/test/EleventyVirtualTemplatesTest.js
+++ b/test/CoreTest-VirtualTemplates.js
@@ -2,15 +2,15 @@ import test from "ava";
import fs from "fs";
import { feedPlugin } from "@11ty/eleventy-plugin-rss";
-import Eleventy from "../src/Eleventy.js";
+import Eleventy from "../src/Core.js";
import DuplicatePermalinkOutputError from "../src/Errors/DuplicatePermalinkOutputError.js";
import { deleteDirectory } from "./_testHelpers.js";
test("Virtual templates, issue #1612", async (t) => {
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.md", `# Hello`)
+ config: function ($config) {
+ $config.addTemplate("virtual.md", `# Hello`)
},
});
@@ -23,8 +23,8 @@ test("Virtual templates, issue #1612", async (t) => {
test("Virtual templates with front matter, issue #1612", async (t) => {
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("./virtual.md", `---
+ config: function ($config) {
+ $config.addTemplate("./virtual.md", `---
myKey: myValue
---
# {{ myKey }}`)
@@ -40,8 +40,8 @@ myKey: myValue
test("Virtual templates with supplemental data, issue #1612", async (t) => {
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.md", `# {{ myKey }}`, { myKey: "myValue" })
+ config: function ($config) {
+ $config.addTemplate("virtual.md", `# {{ myKey }}`, { myKey: "myValue" })
},
});
@@ -55,8 +55,8 @@ test("Virtual templates with supplemental data, issue #1612", async (t) => {
// Supplemental data overrides front matter.
test("Virtual templates with front matter and supplemental data, issue #1612", async (t) => {
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.md", `---
+ config: function ($config) {
+ $config.addTemplate("virtual.md", `---
myKey1: myValue1
myKey3: myValueFm
---
@@ -73,8 +73,8 @@ myKey3: myValueFm
test("Virtual template conflicts with file on file system, issue #1612", async (t) => {
let elev = new Eleventy("./test/stubs/stubs-virtual-conflict", "./test/stubs/stubs-virtual-conflict/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.md", `# Virtual template`)
+ config: function ($config) {
+ $config.addTemplate("virtual.md", `# Virtual template`)
},
});
elev.disableLogger();
@@ -86,11 +86,11 @@ test("Virtual template conflicts with file on file system, issue #1612", async (
test("Virtual templates try to output to the same file, issue #1612", async (t) => {
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual-one.md", "", {
+ config: function ($config) {
+ $config.addTemplate("virtual-one.md", "", {
permalink: "/output.html"
})
- eleventyConfig.addTemplate("virtual-two.md", "", {
+ $config.addTemplate("virtual-two.md", "", {
permalink: "/output.html"
})
},
@@ -105,8 +105,8 @@ test("Virtual templates try to output to the same file, issue #1612", async (t)
// Warning: this test writes to the file system
test("Virtual template writes to file system, issue #1612", async (t) => {
let elev = new Eleventy("./test/stubs-virtual", "./test/stubs-virtual/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.md", `# Hello`)
+ config: function ($config) {
+ $config.addTemplate("virtual.md", `# Hello`)
},
});
elev.disableLogger();
@@ -123,9 +123,9 @@ test("Virtual template writes to file system, issue #1612", async (t) => {
test("Virtual templates conflict", async (t) => {
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.md", `# Hello`);
- eleventyConfig.addTemplate("virtual.md", `# Hello`);
+ config: function ($config) {
+ $config.addTemplate("virtual.md", `# Hello`);
+ $config.addTemplate("virtual.md", `# Hello`);
},
});
@@ -139,10 +139,10 @@ test("Virtual templates conflict", async (t) => {
// https://github.com/11ty/eleventy-plugin-rss/issues/50
test("RSS virtual templates plugin", async (t) => {
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.md", `# Hello`, { tag: "posts" })
+ config: function ($config) {
+ $config.addTemplate("virtual.md", `# Hello`, { tag: "posts" })
- eleventyConfig.addPlugin(feedPlugin, {
+ $config.addPlugin(feedPlugin, {
type: "atom", // or "rss", "json"
outputPath: "/feed.xml",
collection: {
@@ -162,13 +162,13 @@ test("RSS virtual templates plugin", async (t) => {
test("Virtual templates as layouts, issue #2307", async (t) => {
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.md", `# Hello`, {
+ config: function ($config) {
+ $config.addTemplate("virtual.md", `# Hello`, {
layout: "virtual.html"
});
- let layoutPath = eleventyConfig.directories.getLayoutPathRelativeToInputDirectory("virtual.html");
- eleventyConfig.addTemplate(layoutPath, `{{ content }}`);
+ let layoutPath = $config.directories.getLayoutPathRelativeToInputDirectory("virtual.html");
+ $config.addTemplate(layoutPath, `{{ content }}`);
},
});
@@ -190,8 +190,8 @@ test("11ty.js Virtual Templates (object), issue #3347", async (t) => {
};
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.11ty.js", templateDefinition);
+ config: function ($config) {
+ $config.addTemplate("virtual.11ty.js", templateDefinition);
}
});
@@ -210,8 +210,8 @@ test("11ty.js Virtual Templates (function), issue #3347", async (t) => {
};
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.11ty.js", templateDefinition);
+ config: function ($config) {
+ $config.addTemplate("virtual.11ty.js", templateDefinition);
}
});
@@ -226,8 +226,8 @@ test("11ty.js Virtual Templates (function), issue #3347", async (t) => {
test("11ty.js class templates with invalid signature, issue #1645", async (t) => {
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.11ty.js", class {});
+ config: function ($config) {
+ $config.addTemplate("virtual.11ty.js", class {});
}
});
elev.disableLogger();
@@ -239,8 +239,8 @@ test("11ty.js class templates with invalid signature, issue #1645", async (t) =>
test("11ty.js class templates with instance properties (data), issue #1645", async (t) => {
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.11ty.js", class { data() { return {} } });
+ config: function ($config) {
+ $config.addTemplate("virtual.11ty.js", class { data() { return {} } });
}
});
@@ -252,8 +252,8 @@ test("11ty.js class templates with instance properties (data), issue #1645", asy
test("11ty.js class templates with instance properties (render), issue #1645", async (t) => {
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.11ty.js", class { render() { return "Hello!" } });
+ config: function ($config) {
+ $config.addTemplate("virtual.11ty.js", class { render() { return "Hello!" } });
}
});
@@ -265,8 +265,8 @@ test("11ty.js class templates with instance properties (render), issue #1645", a
test("11ty.js class templates with instance properties (data and render), issue #1645", async (t) => {
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.11ty.js", class {
+ config: function ($config) {
+ $config.addTemplate("virtual.11ty.js", class {
data() { return { key: "world" }; }
render(data) { return `Hello ${data.key}!` }
});
@@ -281,8 +281,8 @@ test("11ty.js class templates with instance properties (data and render), issue
test("11ty.js class templates with instance properties (data and render arrows), issue #1645", async (t) => {
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.11ty.js", class {
+ config: function ($config) {
+ $config.addTemplate("virtual.11ty.js", class {
data = () => { return { key: "world" }; }
render = (data) => { return `Hello ${data.key}!` }
});
@@ -297,8 +297,8 @@ test("11ty.js class templates with instance properties (data and render arrows),
test("11ty.js class templates with instance properties (data and render arrows, new), issue #1645", async (t) => {
let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("virtual.11ty.js", new class {
+ config: function ($config) {
+ $config.addTemplate("virtual.11ty.js", new class {
data = () => { return { key: "world" }; }
render = (data) => { return `Hello ${data.key}!` }
});
@@ -310,3 +310,25 @@ test("11ty.js class templates with instance properties (data and render arrows,
t.deepEqual(results.length, 1);
t.deepEqual(results[0].content.trim(), `Hello world!`);
});
+
+test("server.js Virtual Templates (object)", async (t) => {
+ let templateDefinition = {
+ data: () => {
+ return { var: 2 };
+ },
+ render: function(data) {
+ return `this is a test ${data.var}.`;
+ }
+ };
+
+ let elev = new Eleventy("./test/stubs-virtual-nowrite", "./test/stubs-virtual-nowrite/_site", {
+ config: function ($config) {
+ $config.addTemplate("virtual.server.js", templateDefinition);
+ }
+ });
+
+ let results = await elev.toJSON();
+
+ t.deepEqual(results.length, 1);
+ t.deepEqual(results[0].content.trim(), `this is a test 2.`);
+});
diff --git a/test/EleventyTest.js b/test/CoreTest.js
similarity index 80%
rename from test/EleventyTest.js
rename to test/CoreTest.js
index ecae5c44f..5c514705d 100644
--- a/test/EleventyTest.js
+++ b/test/CoreTest.js
@@ -8,14 +8,14 @@ import { marked } from "marked";
import nunjucks from "@11ty/nunjucks";
import * as sass from "sass";
-import Eleventy, { HtmlBasePlugin } from "../src/Eleventy.js";
+import Eleventy, { HtmlBasePlugin } from "../src/Core.js";
import TemplateContent from "../src/TemplateContent.js";
import TemplateMap from "../src/TemplateMap.js";
import TemplateConfig from "../src/TemplateConfig.js";
import { getCreatedTimestamp, getUpdatedTimestamp } from "../src/Util/Git.js";
import PathNormalizer from "../src/Util/PathNormalizer.js";
import { normalizeNewLines, localizeNewLines } from "./Util/normalizeNewLines.js";
-import { isTypeScriptSupported } from "../src/Util/FeatureTests.cjs";
+import { isTypeScriptSupported } from "../src/Util/TypeScriptFeatureTest.cjs";
import { deleteDirectory } from "./_testHelpers.js";
const lodashGet = lodash.get;
@@ -23,11 +23,11 @@ const lodashGet = lodash.get;
test("Eleventy, defaults inherit from config", async (t) => {
let elev = new Eleventy();
- let eleventyConfig = new TemplateConfig();
- await eleventyConfig.init();
+ let $config = new TemplateConfig();
+ await $config.init();
await elev.initializeConfig();
- let config = eleventyConfig.getConfig();
+ let config = $config.getConfig();
t.truthy(elev.input);
t.truthy(elev.outputDir);
@@ -40,11 +40,11 @@ test("Eleventy, defaults inherit from config", async (t) => {
test("Eleventy, null output directory should default to _site", async (t) => {
let elev = new Eleventy(".", null);
- let eleventyConfig = new TemplateConfig();
- await eleventyConfig.init();
+ let $config = new TemplateConfig();
+ await $config.init();
await elev.initializeConfig();
- let config = eleventyConfig.getConfig();
+ let config = $config.getConfig();
t.is(config.dir.input, ".");
t.is(elev.input, "./");
@@ -93,7 +93,7 @@ test("Eleventy set input/output", async (t) => {
t.truthy(elev.writer);
});
-test("Eleventy process.ENV", async (t) => {
+test("process.env.ELEVENTY_*", async (t) => {
delete process.env.ELEVENTY_ROOT;
t.falsy(process.env.ELEVENTY_ROOT);
@@ -106,6 +106,19 @@ test("Eleventy process.ENV", async (t) => {
t.truthy(globals.eleventy.env.root);
});
+test("process.env.BUILDAWESOME_*", async (t) => {
+ delete process.env.BUILDAWESOME_ROOT;
+ t.falsy(process.env.BUILDAWESOME_ROOT);
+
+ let elev = new Eleventy("./test/stubs", "./test/stubs/_site");
+ await elev.init();
+ t.truthy(process.env.BUILDAWESOME_ROOT);
+
+ // all BUILDAWESOME_ env variables are also available on eleventy.env
+ let globals = await elev.templateData.getInitialGlobalData();
+ t.truthy(globals.eleventy.env.root);
+});
+
test("Eleventy file watching", async (t) => {
let elev = new Eleventy("./test/stubs", "./test/stubs/_site", {
runMode: "watch" // required to spider deps
@@ -130,7 +143,7 @@ test("Eleventy file watching", async (t) => {
"./.gitignore",
"./.eleventyignore",
"./test/stubs/.eleventyignore",
- `./test/stubs/**/*.{json,11tydata.mjs,11tydata.cjs,11tydata.js${isTypeScriptSupported() ? ",11tydata.mts,11tydata.cts,11tydata.ts" : ""}}`,
+ "./test/stubs/**/*.{json,data.mjs,data.cjs,data.js,data.mts,data.cts,data.ts,11tydata.mjs,11tydata.cjs,11tydata.js,11tydata.mts,11tydata.cts,11tydata.ts}",
"./test/stubs/deps/dep1.cjs",
"./test/stubs/deps/dep2.cjs",
]);
@@ -159,8 +172,8 @@ test("Eleventy file watching (don’t watch deps of passthrough copy .js files)"
test("Eleventy file watching (no JS dependencies)", async (t) => {
let elev = new Eleventy("./test/stubs", "./test/stubs/_site", {
- config: eleventyConfig => {
- eleventyConfig.setWatchJavaScriptDependencies(false);
+ config: $config => {
+ $config.setWatchJavaScriptDependencies(false);
}
});
elev.setFormats("njk");
@@ -181,7 +194,7 @@ test("Eleventy file watching (no JS dependencies)", async (t) => {
"./.gitignore",
"./.eleventyignore",
"./test/stubs/.eleventyignore",
- `./test/stubs/**/*.{json,11tydata.mjs,11tydata.cjs,11tydata.js${isTypeScriptSupported() ? ",11tydata.mts,11tydata.cts,11tydata.ts" : ""}}`,
+ `./test/stubs/**/*.{json,data.mjs,data.cjs,data.js,data.mts,data.cts,data.ts,11tydata.mjs,11tydata.cjs,11tydata.js,11tydata.mts,11tydata.cts,11tydata.ts}`,
]);
t.true(ignores.includes("node_modules/**"));
@@ -450,8 +463,8 @@ test("Pagination over collection using eleventyComputed (liquid)", async (t) =>
"./test/stubs-pagination-computed-quotes/",
"./test/stubs-pagination-computed-quotes/_site",
{
- config: function (eleventyConfig) {
- eleventyConfig.addFilter("selectRandomFromArray", (arr) => {
+ config: function ($config) {
+ $config.addFilter("selectRandomFromArray", (arr) => {
t.true(Array.isArray(arr));
t.deepEqual(arr, ["The person that shared this is awesome"]);
return arr[0];
@@ -473,8 +486,8 @@ test("Pagination over collection using eleventyComputed (njk)", async (t) => {
"./test/stubs-pagination-computed-quotes-njk/",
"./test/stubs-pagination-computed-quotes-njk/_site",
{
- config: function (eleventyConfig) {
- eleventyConfig.addFilter("selectRandomFromArray", (arr) => {
+ config: function ($config) {
+ $config.addFilter("selectRandomFromArray", (arr) => {
t.true(Array.isArray(arr));
t.deepEqual(arr, ["The person that shared this is awesome"]);
return arr[0];
@@ -495,7 +508,7 @@ test("Paginated template uses proxy and global data", async (t) => {
"./test/proxy-pagination-globaldata/",
"./test/proxy-pagination-globaldata/_site",
{
- config: function (eleventyConfig) {},
+ config: function ($config) {},
}
);
@@ -510,8 +523,8 @@ test("Liquid shortcode with multiple arguments(issue #2348)", async (t) => {
// NOTE issue #2348 was only active when you were processing multiple templates at the same time.
let elev = new Eleventy("./test/stubs-2367/", "./test/stubs-2367/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addShortcode("simplelink", function (...args) {
+ config: function ($config) {
+ $config.addShortcode("simplelink", function (...args) {
return JSON.stringify(args);
});
},
@@ -546,7 +559,7 @@ test("git getCreatedTimestamp returns undefined on nonexistent path", async (t)
test("Does pathPrefix affect page URLs", async (t) => {
let elev = new Eleventy("./README.md", "./_site", {
- config: function (eleventyConfig) {
+ config: function ($config) {
return {
pathPrefix: "/testdirectory/",
};
@@ -656,8 +669,8 @@ test("Lodash get (for pagination data target) object key with spaces, issue #285
test("Eleventy tag collection with spaces in the tag name, issue #2851", async (t) => {
let elev = new Eleventy("./test/stubs-2851", "./test/stubs-2851/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.dataFilterSelectors.add("collections");
+ config: function ($config) {
+ $config.dataFilterSelectors.add("collections");
},
});
elev.setIsVerbose(false);
@@ -672,8 +685,8 @@ test("this.eleventy on JavaScript template functions, issue #2790", async (t) =>
t.plan(3);
let elev = new Eleventy("./test/stubs-2790", "./test/stubs-2790/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addJavaScriptFunction("jsfunction", function () {
+ config: function ($config) {
+ $config.addJavaScriptFunction("jsfunction", function () {
t.truthy(this.eleventy);
return this.eleventy.generator.split(" ")[0];
});
@@ -686,7 +699,7 @@ test("this.eleventy on JavaScript template functions, issue #2790", async (t) =>
test("Global data JS files should only execute once, issue #2753", async (t) => {
let elev = new Eleventy("./test/stubs-2753", "./test/stubs-2753/_site", {
- config: function (eleventyConfig) {},
+ config: function ($config) {},
});
let result = await elev.toJSON();
t.deepEqual(result.length, 2);
@@ -708,7 +721,7 @@ function sortResultsBy(results, key = "content") {
test("Access to raw input of file (toJSON), issue #1206", async (t) => {
let elev = new Eleventy("./test/stubs-1206", "./test/stubs-1206/_site", {
- config: function (eleventyConfig) {},
+ config: function ($config) {},
});
let results = await elev.toJSON();
sortResultsBy(results, "content");
@@ -723,7 +736,7 @@ test("Access to raw input of file (toJSON), issue #1206", async (t) => {
// Warning: this test writes to the file system
test("Access to raw input of file (dryRun), issue #1206", async (t) => {
let elev = new Eleventy("./test/stubs-1206", "./test/stubs-1206/_site", {
- config: function (eleventyConfig) {},
+ config: function ($config) {},
});
elev.disableLogger();
@@ -739,16 +752,26 @@ test("Access to raw input of file (dryRun), issue #1206", async (t) => {
deleteDirectory("./test/stubs-1206/_site/");
});
-test("eleventy.before and eleventy.after Event Arguments, directories", async (t) => {
- t.plan(6);
+test("{eleventy,buildawesome}.before and {eleventy,buildawesome}.after Event Arguments, directories", async (t) => {
+ t.plan(12);
let elev = new Eleventy("./test/noop/", "./test/noop/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.on("eleventy.before", arg => {
+ config: function ($config) {
+ $config.on("eleventy.before", arg => {
+ t.is(arg.inputDir, "./test/noop/");
+ t.is(arg.directories.input, "./test/noop/");
+ t.is(arg.directories.includes, "./test/noop/_includes/");
+ })
+ $config.on("buildawesome.before", arg => {
+ t.is(arg.inputDir, "./test/noop/");
+ t.is(arg.directories.input, "./test/noop/");
+ t.is(arg.directories.includes, "./test/noop/_includes/");
+ })
+ $config.on("eleventy.after", arg => {
t.is(arg.inputDir, "./test/noop/");
t.is(arg.directories.input, "./test/noop/");
t.is(arg.directories.includes, "./test/noop/_includes/");
})
- eleventyConfig.on("eleventy.after", arg => {
+ $config.on("buildawesome.after", arg => {
t.is(arg.inputDir, "./test/noop/");
t.is(arg.directories.input, "./test/noop/");
t.is(arg.directories.includes, "./test/noop/_includes/");
@@ -759,20 +782,20 @@ test("eleventy.before and eleventy.after Event Arguments, directories", async (t
let results = await elev.toJSON();
});
-test("eleventy.after fires sequentially setting eventEmitterMode 'sequential'", async (t) => {
+test("buildawesome.after fires sequentially setting eventEmitterMode 'sequential'", async (t) => {
let reachFirst;
const firstReached = new Promise(resolve => reachFirst = resolve)
let next;
const firstResult = new Promise(resolve => next = resolve)
let secondCalled = false;
let elev = new Eleventy("./test/noop/", "./test/noop/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.setEventEmitterMode('sequential')
- eleventyConfig.on("eleventy.after", arg => {
+ config: function (configApi) {
+ configApi.setEventEmitterMode('sequential')
+ configApi.on("buildawesome.after", arg => {
reachFirst()
return firstResult;
})
- eleventyConfig.on("eleventy.after", arg => {
+ configApi.on("buildawesome.after", arg => {
secondCalled = true;
})
},
@@ -789,10 +812,10 @@ test("eleventy.after fires sequentially setting eventEmitterMode 'sequential'",
test("setInputDirectory config method #1503", async (t) => {
t.plan(5);
let elev = new Eleventy("./test/noop/", "./test/noop/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.setInputDirectory("./test/noop2/");
+ config: function ($config) {
+ $config.setInputDirectory("./test/noop2/");
- eleventyConfig.on("eleventy.before", arg => {
+ $config.on("buildawesome.before", arg => {
t.is(arg.directories.input, "./test/noop2/");
t.is(arg.directories.includes, "./test/noop2/_includes/");
t.is(arg.directories.data, "./test/noop2/_data/");
@@ -808,10 +831,10 @@ test("setInputDirectory config method #1503", async (t) => {
test("setIncludesDirectory config method #1503", async (t) => {
t.plan(5);
let elev = new Eleventy("./test/noop/", "./test/noop/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.setIncludesDirectory("myincludes");
+ config: function ($config) {
+ $config.setIncludesDirectory("myincludes");
- eleventyConfig.on("eleventy.before", arg => {
+ $config.on("buildawesome.before", arg => {
t.is(arg.directories.input, "./test/noop/");
t.is(arg.directories.includes, "./test/noop/myincludes/");
t.is(arg.directories.data, "./test/noop/_data/");
@@ -827,10 +850,10 @@ test("setIncludesDirectory config method #1503", async (t) => {
test("setDataDirectory config method #1503", async (t) => {
t.plan(5);
let elev = new Eleventy("./test/noop/", "./test/noop/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.setDataDirectory("data");
+ config: function ($config) {
+ $config.setDataDirectory("data");
- eleventyConfig.on("eleventy.before", arg => {
+ $config.on("buildawesome.before", arg => {
t.is(arg.directories.input, "./test/noop/");
t.is(arg.directories.includes, "./test/noop/_includes/");
t.is(arg.directories.data, "./test/noop/data/");
@@ -846,10 +869,10 @@ test("setDataDirectory config method #1503", async (t) => {
test("setLayoutsDirectory config method #1503", async (t) => {
t.plan(5);
let elev = new Eleventy("./test/noop/", "./test/noop/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.setLayoutsDirectory("layouts");
+ config: function ($config) {
+ $config.setLayoutsDirectory("layouts");
- eleventyConfig.on("eleventy.before", arg => {
+ $config.on("buildawesome.before", arg => {
t.is(arg.directories.input, "./test/noop/");
t.is(arg.directories.includes, "./test/noop/_includes/");
t.is(arg.directories.data, "./test/noop/_data/");
@@ -864,9 +887,9 @@ test("setLayoutsDirectory config method #1503", async (t) => {
test("setInputDirectory config method #1503 in a plugin throws error", async (t) => {
let elev = new Eleventy("./test/noop/", "./test/noop/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addPlugin(() => {
- eleventyConfig.setInputDirectory("./test/noop2/");
+ config: function ($config) {
+ $config.addPlugin(() => {
+ $config.setInputDirectory("./test/noop2/");
});
},
});
@@ -906,8 +929,8 @@ test("Accepts absolute paths urls for input and output and a virtual template, r
let input = path.resolve("./test/noop/");
let output = path.resolve("./test/noop/_site");
let elev = new Eleventy(input, output, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index.md", `# Title`)
+ config: $config => {
+ $config.addTemplate("index.md", `# Title`)
}
});
@@ -919,8 +942,8 @@ test("Eleventy config export (ESM)", async (t) => {
t.plan(5);
let elev = new Eleventy("test/stubs/cfg-directories-export", null, {
configPath: "./test/stubs/cfg-directories-export/eleventy.config.js",
- config: function (eleventyConfig) {
- eleventyConfig.on("eleventy.after", arg => {
+ config: function (configApi) {
+ configApi.on("buildawesome.after", arg => {
t.is(arg.directories.input, "./src/");
t.is(arg.directories.includes, "./src/myincludes/");
t.is(arg.directories.data, "./src/mydata/");
@@ -937,8 +960,8 @@ test("Eleventy config export (CommonJS)", async (t) => {
t.plan(5);
let elev = new Eleventy("test/stubs/cfg-directories-export-cjs", null, {
configPath: "./test/stubs/cfg-directories-export-cjs/eleventy.config.cjs",
- config: function (eleventyConfig) {
- eleventyConfig.on("eleventy.after", arg => {
+ config: function (configApi) {
+ configApi.on("buildawesome.after", arg => {
t.is(arg.directories.input, "./src/");
t.is(arg.directories.includes, "./src/myincludes2/");
t.is(arg.directories.data, "./src/mydata2/");
@@ -953,8 +976,8 @@ test("Eleventy config export (CommonJS)", async (t) => {
test("Eleventy setting reserved data throws error (eleventy)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index.html", `---
+ config: configApi => {
+ configApi.addTemplate("index.html", `---
eleventy:
key1: NOOOOO
---`);
@@ -963,7 +986,7 @@ eleventy:
elev.disableLogger();
let e = await t.throwsAsync(() => elev.toJSON(), {
- message: 'You attempted to set one of Eleventy’s reserved data property names. You can opt-out of this behavior with `eleventyConfig.setFreezeReservedData(false)` or rename/remove the property in your data cascade that conflicts with Eleventy’s reserved property names (e.g. `eleventy`, `pkg`, and others). Learn more: https://v3.11ty.dev/docs/data-eleventy-supplied/'
+ message: 'You attempted to set one of Build Awesome’s reserved data property names. You can opt-out of this behavior with `$config.setFreezeReservedData(false)` or rename/remove the property in your data cascade that conflicts with reserved property names (e.g. `buildawesome`, `eleventy`, `pkg`, and others). Learn more: https://v3.11ty.dev/docs/data-eleventy-supplied/'
});
t.is(e.cause.toString(), "TypeError: Cannot add property key1, object is not extensible");
@@ -971,8 +994,8 @@ eleventy:
test("Eleventy setting reserved data throws error (pkg)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index.html", `---
+ config: configApi => {
+ configApi.addTemplate("index.html", `---
pkg:
myOwn: OVERRIDE
---`);
@@ -981,7 +1004,7 @@ pkg:
elev.disableLogger();
let e = await t.throwsAsync(() => elev.toJSON(), {
- message: 'You attempted to set one of Eleventy’s reserved data property names. You can opt-out of this behavior with `eleventyConfig.setFreezeReservedData(false)` or rename/remove the property in your data cascade that conflicts with Eleventy’s reserved property names (e.g. `eleventy`, `pkg`, and others). Learn more: https://v3.11ty.dev/docs/data-eleventy-supplied/'
+ message: 'You attempted to set one of Build Awesome’s reserved data property names. You can opt-out of this behavior with `$config.setFreezeReservedData(false)` or rename/remove the property in your data cascade that conflicts with reserved property names (e.g. `buildawesome`, `eleventy`, `pkg`, and others). Learn more: https://v3.11ty.dev/docs/data-eleventy-supplied/'
});
t.is(e.cause.toString(), "TypeError: Cannot add property myOwn, object is not extensible");
@@ -989,8 +1012,8 @@ pkg:
test("Eleventy pagination works okay with reserved data throws (eleventy) Issue #3262", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index.html", `---
+ config: configApi => {
+ configApi.addTemplate("index.html", `---
pagination:
data: "test"
size: 1
@@ -1010,8 +1033,8 @@ test:
test("Eleventy setting reserved data throws error (page)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index.html", `---
+ config: configApi => {
+ configApi.addTemplate("index.html", `---
page: "My page value"
---`)
}
@@ -1019,14 +1042,14 @@ page: "My page value"
elev.disableLogger();
let e = await t.throwsAsync(() => elev.toJSON(), {
- message: 'You attempted to set one of Eleventy’s reserved data property names: page. You can opt-out of this behavior with `eleventyConfig.setFreezeReservedData(false)` or rename/remove the property in your data cascade that conflicts with Eleventy’s reserved property names (e.g. `eleventy`, `pkg`, and others). Learn more: https://v3.11ty.dev/docs/data-eleventy-supplied/'
+ message: 'You attempted to set one of Build Awesome’s reserved data property names: page. You can opt-out of this behavior with `$config.setFreezeReservedData(false)` or rename/remove the property in your data cascade that conflicts with reserved property names (e.g. `buildawesome`, `eleventy`, `pkg`, and others). Learn more: https://v3.11ty.dev/docs/data-eleventy-supplied/'
});
});
test("Eleventy setting reserved data throws error (content)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index.html", `---
+ config: configApi => {
+ configApi.addTemplate("index.html", `---
content: "My page value"
---`)
}
@@ -1034,14 +1057,14 @@ content: "My page value"
elev.disableLogger();
await t.throwsAsync(() => elev.toJSON(), {
- message: 'You attempted to set one of Eleventy’s reserved data property names: content. You can opt-out of this behavior with `eleventyConfig.setFreezeReservedData(false)` or rename/remove the property in your data cascade that conflicts with Eleventy’s reserved property names (e.g. `eleventy`, `pkg`, and others). Learn more: https://v3.11ty.dev/docs/data-eleventy-supplied/'
+ message: 'You attempted to set one of Build Awesome’s reserved data property names: content. You can opt-out of this behavior with `$config.setFreezeReservedData(false)` or rename/remove the property in your data cascade that conflicts with reserved property names (e.g. `buildawesome`, `eleventy`, `pkg`, and others). Learn more: https://v3.11ty.dev/docs/data-eleventy-supplied/'
});
});
test("Eleventy setting reserved data throws error (collections)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index.html", `---
+ config: configApi => {
+ configApi.addTemplate("index.html", `---
collections: []
---`)
}
@@ -1049,14 +1072,14 @@ collections: []
elev.disableLogger();
await t.throwsAsync(() => elev.toJSON(), {
- message: 'You attempted to set one of Eleventy’s reserved data property names: collections. You can opt-out of this behavior with `eleventyConfig.setFreezeReservedData(false)` or rename/remove the property in your data cascade that conflicts with Eleventy’s reserved property names (e.g. `eleventy`, `pkg`, and others). Learn more: https://v3.11ty.dev/docs/data-eleventy-supplied/'
+ message: 'You attempted to set one of Build Awesome’s reserved data property names: collections. You can opt-out of this behavior with `$config.setFreezeReservedData(false)` or rename/remove the property in your data cascade that conflicts with reserved property names (e.g. `buildawesome`, `eleventy`, `pkg`, and others). Learn more: https://v3.11ty.dev/docs/data-eleventy-supplied/'
});
});
test("Eleventy setting pkg data is okay when pkg is remapped to parkour", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index.html", `---
+ config: configApi => {
+ configApi.addTemplate("index.html", `---
pkg:
myOwn: OVERRIDE
---`);
@@ -1085,8 +1108,8 @@ pkg:
test("Eleventy setting pkg data is okay when keys.package is false", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index.html", `---
+ config: configApi => {
+ configApi.addTemplate("index.html", `---
pkg:
myOwn: OVERRIDE
---
@@ -1116,8 +1139,8 @@ pkg:
test("Eleventy setting reserved data throws error (pkg remapped to parkour)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index.html", `---
+ config: configApi => {
+ configApi.addTemplate("index.html", `---
parkour:
myOwn: OVERRIDE
---`);
@@ -1135,7 +1158,7 @@ parkour:
t.is(elev.eleventyConfig.config.keys.package, "parkour");
let e = await t.throwsAsync(() => elev.toJSON(), {
- message: 'You attempted to set one of Eleventy’s reserved data property names. You can opt-out of this behavior with `eleventyConfig.setFreezeReservedData(false)` or rename/remove the property in your data cascade that conflicts with Eleventy’s reserved property names (e.g. `eleventy`, `pkg`, and others). Learn more: https://v3.11ty.dev/docs/data-eleventy-supplied/'
+ message: 'You attempted to set one of Build Awesome’s reserved data property names. You can opt-out of this behavior with `$config.setFreezeReservedData(false)` or rename/remove the property in your data cascade that conflicts with reserved property names (e.g. `buildawesome`, `eleventy`, `pkg`, and others). Learn more: https://v3.11ty.dev/docs/data-eleventy-supplied/'
});
t.is(e.cause.toString(), "TypeError: Cannot add property myOwn, object is not extensible");
@@ -1143,8 +1166,8 @@ parkour:
test("Eleventy data schema (success) #879", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index1.html", "", {
+ config: configApi => {
+ configApi.addTemplate("index1.html", "", {
draft: true,
eleventyDataSchema: function(data) {
if(typeof data.draft !== "boolean") {
@@ -1153,7 +1176,7 @@ test("Eleventy data schema (success) #879", async (t) => {
}
});
- eleventyConfig.addTemplate("index2.html", "", {
+ configApi.addTemplate("index2.html", "", {
draft: true,
eleventyDataSchema: function(data) {
if(typeof data.draft !== "boolean") {
@@ -1171,8 +1194,8 @@ test("Eleventy data schema (success) #879", async (t) => {
test("Eleventy data schema (fails) #879", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index1.html", "", {
+ config: configApi => {
+ configApi.addTemplate("index1.html", "", {
draft: 1,
eleventyDataSchema: function(data) {
if(typeof data.draft !== "boolean") {
@@ -1193,8 +1216,8 @@ test("Eleventy data schema (fails) #879", async (t) => {
test("Eleventy data schema (fails, using zod) #879", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index1.html", "", {
+ config: configApi => {
+ configApi.addTemplate("index1.html", "", {
draft: 1,
eleventyDataSchema: function(data) {
let result = z.object({
@@ -1220,12 +1243,12 @@ test("Eleventy data schema (fails, using zod) #879", async (t) => {
test("Eleventy data schema has access to custom collections created via API #879", async (t) => {
t.plan(2);
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addCollection("userCollection", function (collection) {
+ config: configApi => {
+ configApi.addCollection("userCollection", function (collection) {
return collection.getAll();
});
- eleventyConfig.addTemplate("index1.html", "", {
+ configApi.addTemplate("index1.html", "", {
eleventyDataSchema: function(data) {
t.is(data.collections.userCollection.length, 1);
}
@@ -1241,11 +1264,11 @@ test("Eleventy data schema has access to custom collections created via API #879
test("Eleventy transforms filter (using collections and page override data)", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
pathPrefix: "hi",
- config: eleventyConfig => {
- eleventyConfig.addPlugin(HtmlBasePlugin);
+ config: configApi => {
+ configApi.addPlugin(HtmlBasePlugin);
- eleventyConfig.addTemplate("index.html", ` `, { tags: "posts" });
- eleventyConfig.addTemplate("feed.njk", `{% for post in collections.posts %}{{ post.content | renderTransforms(post.page) | safe }}{% endfor %}`, {
+ configApi.addTemplate("index.html", ` `, { tags: "posts" });
+ configApi.addTemplate("feed.njk", `{% for post in collections.posts %}{{ post.content | renderTransforms(post.page) | safe }}{% endfor %}`, {
permalink: "feed.xml"
});
}
@@ -1261,14 +1284,14 @@ test("Eleventy transforms filter (using collections and page override data)", as
test("Custom Markdown Render with permalink, Issue #2780", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addExtension("md", {
+ config: configApi => {
+ configApi.addExtension("md", {
compile: str => {
return data => marked.parse(str);
}
});
- eleventyConfig.addTemplate("template.md", `# Markdown?`, { permalink: "/permalink.html" });
+ configApi.addTemplate("template.md", `# Markdown?`, { permalink: "/permalink.html" });
}
});
@@ -1280,13 +1303,13 @@ test("Custom Markdown Render with permalink, Issue #2780", async (t) => {
test("Custom Markdown Render with permalink, Issue #2780 #3339", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplateFormats("markdown");
- eleventyConfig.addExtension("markdown", {
+ config: configApi => {
+ configApi.addTemplateFormats("markdown");
+ configApi.addExtension("markdown", {
key: "md"
});
- eleventyConfig.addTemplate("filename-hi.markdown", `# Markdown?`, { permalink: "/{{ page.fileSlug }}.html" });
+ configApi.addTemplate("filename-hi.markdown", `# Markdown?`, { permalink: "/{{ page.fileSlug }}.html" });
}
});
@@ -1298,8 +1321,8 @@ test("Custom Markdown Render with permalink, Issue #2780 #3339", async (t) => {
test("Test input/output conflicts (input overwrites output), Issue #3327", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", "./test/stubs-virtual/", {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("test.html", `# Markdown`, { permalink: "test.html" });
+ config: configApi => {
+ configApi.addTemplate("test.html", `# Markdown`, { permalink: "test.html" });
}
});
elev.disableLogger();
@@ -1312,9 +1335,9 @@ test("Test input/output conflicts (input overwrites output), Issue #3327", async
test("Test input/output conflicts (output overwrites another input), Issue #3327", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", "./test/stubs-virtual/", {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("test.html", `# Markdown`);
- eleventyConfig.addTemplate("index.html", `# Markdown`, { permalink: "test.html" });
+ config: configApi => {
+ configApi.addTemplate("test.html", `# Markdown`);
+ configApi.addTemplate("index.html", `# Markdown`, { permalink: "test.html" });
}
});
elev.disableLogger();
@@ -1328,8 +1351,8 @@ test("Test input/output conflicts (output overwrites another input), Issue #3327
test("Eleventy data schema has access to custom collections created via API #613 #3345", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addCollection("userCollection", async function (collection) {
+ config: configApi => {
+ configApi.addCollection("userCollection", async function (collection) {
let c = collection.getFilteredByTag("posts");
for(let item of c) {
const frontMatter = await item.template.read();
@@ -1339,8 +1362,8 @@ test("Eleventy data schema has access to custom collections created via API #613
return c;
});
- eleventyConfig.addTemplate("home.html", "{% for post in collections.userCollection %}{{ post.content }}{% endfor %}");
- eleventyConfig.addTemplate("post.html", "test", { tags: "posts" });
+ configApi.addTemplate("home.html", "{% for post in collections.userCollection %}{{ post.content }}{% endfor %}");
+ configApi.addTemplate("post.html", "test", { tags: "posts" });
}
});
elev.disableLogger();
@@ -1353,8 +1376,8 @@ test("Eleventy data schema has access to custom collections created via API #613
test("Custom Nunjucks syntax has shortcode with access to `this`, Issue #3310", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addShortcode("customized", function(argString) {
+ config: configApi => {
+ configApi.addShortcode("customized", function(argString) {
return `${this.page.url}:${argString}:Custom Shortcode`;
});
@@ -1372,8 +1395,8 @@ test("Custom Nunjucks syntax has shortcode with access to `this`, Issue #3310",
};
this.run = function(context, argString) {
- let fn = eleventyConfig.augmentFunctionContext(
- eleventyConfig.getShortcode("customized"),
+ let fn = configApi.augmentFunctionContext(
+ configApi.getShortcode("customized"),
{
source: context.ctx,
// lazy: false,
@@ -1388,9 +1411,9 @@ test("Custom Nunjucks syntax has shortcode with access to `this`, Issue #3310",
njkEnv.addExtension('CustomExtension', new CustomExtension());
- eleventyConfig.addTemplateFormats("njknew");
+ configApi.addTemplateFormats("njknew");
- eleventyConfig.addExtension("njknew", {
+ configApi.addExtension("njknew", {
compile: (str, inputPath) => {
let tmpl = new nunjucks.Template(str, njkEnv, inputPath, false);
return function(data) {
@@ -1407,7 +1430,7 @@ test("Custom Nunjucks syntax has shortcode with access to `this`, Issue #3310",
}
});
- eleventyConfig.addTemplate("template.njknew", `{{ hello }}:{% customized "passed in" %} `, {
+ configApi.addTemplate("template.njknew", `{{ hello }}:{% customized "passed in" %} `, {
hello: "goodbye"
});
}
@@ -1420,16 +1443,16 @@ test("Custom Nunjucks syntax has shortcode with access to `this`, Issue #3310",
test("Related to issue 3206: Does Nunjucks throwOnUndefined variables require normalizeContext to be a lazy get", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addShortcode("customized", function(argString) {
+ config: $config => {
+ $config.addShortcode("customized", function(argString) {
return `${this.page.url}:Custom Shortcode`;
});
- eleventyConfig.setNunjucksEnvironmentOptions({
+ $config.setNunjucksEnvironmentOptions({
throwOnUndefined: true,
});
- eleventyConfig.addTemplate("index.html", `HELLO{% customized %}:{{ page.url }}`);
+ $config.addTemplate("index.html", `HELLO{% customized %}:{{ page.url }}`);
}
});
@@ -1440,8 +1463,8 @@ test("Related to issue 3206: Does Nunjucks throwOnUndefined variables require no
test("#727: Error messaging when trying to use a missing layout", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index.html", `HELLO {{ page.url }}`, {
+ config: $config => {
+ $config.addTemplate("index.html", `HELLO {{ page.url }}`, {
layout: "does-not-exist.html",
});
}
@@ -1455,9 +1478,9 @@ test("#727: Error messaging when trying to use a missing layout", async (t) => {
test("#1419: Shortcode in a permalink", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: eleventyConfig => {
- eleventyConfig.addShortcode("shortcode", () => "url-slug");
- eleventyConfig.addTemplate("index.njk", "", {
+ config: $config => {
+ $config.addShortcode("shortcode", () => "url-slug");
+ $config.addTemplate("index.njk", "", {
permalink: "/{% shortcode %}/",
});
}
@@ -1495,9 +1518,9 @@ test("Eleventy loader can force CommonJS mode", async (t) => {
test("Truthy outputPath without a file extension now throws an error, issue #3399", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function (eleventyConfig) {
- // eleventyConfig.configureErrorReporting({ allowMissingExtensions: true });
- eleventyConfig.addTemplate("index.html", "", { permalink: "foo" })
+ config: function ($config) {
+ // $config.configureErrorReporting({ allowMissingExtensions: true });
+ $config.addTemplate("index.html", "", { permalink: "foo" })
},
});
elev.disableLogger();
@@ -1510,15 +1533,15 @@ You *probably* want to add a file extension to your permalink so that hosts will
Learn more: https://v3.11ty.dev/docs/permalinks/#trailing-slashes
-This is usually but not *always* an error so if you’d like to disable this error message, add \`eleventyAllowMissingExtension: true\` somewhere in the data cascade for this template or use \`eleventyConfig.configureErrorReporting({ allowMissingExtensions: true });\` to disable this feature globally.`
+This is usually but not *always* an error so if you’d like to disable this error message, add \`eleventyAllowMissingExtension: true\` somewhere in the data cascade for this template or use \`$config.configureErrorReporting({ allowMissingExtensions: true });\` to disable this feature globally.`
});
});
test("Truthy outputPath without a file extension can be ignored, issue #3399", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function (eleventyConfig) {
- // eleventyConfig.configureErrorReporting({ allowMissingExtensions: true });
- eleventyConfig.addTemplate("index.html", "", { permalink: "foo", eleventyAllowMissingExtension: true })
+ config: function ($config) {
+ // $config.configureErrorReporting({ allowMissingExtensions: true });
+ $config.addTemplate("index.html", "", { permalink: "foo", eleventyAllowMissingExtension: true })
},
});
elev.disableLogger();
@@ -1531,8 +1554,8 @@ test("Truthy outputPath without a file extension can be ignored, issue #3399", a
test("Allow list for some file types without a file extension, issue #3399", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("index.html", "", { permalink: "/test/_redirects" })
+ config: function ($config) {
+ $config.addTemplate("index.html", "", { permalink: "/test/_redirects" })
},
});
elev.disableLogger();
@@ -1544,9 +1567,9 @@ test("Allow list for some file types without a file extension, issue #3399", asy
test("Truthy outputPath without a file extension error message is disabled, issue #3399", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function (eleventyConfig) {
- eleventyConfig.configureErrorReporting({ allowMissingExtensions: true });
- eleventyConfig.addTemplate("index.html", "", { permalink: "foo" })
+ config: function ($config) {
+ $config.configureErrorReporting({ allowMissingExtensions: true });
+ $config.addTemplate("index.html", "", { permalink: "foo" })
},
});
elev.disableLogger();
@@ -1557,8 +1580,8 @@ test("Truthy outputPath without a file extension error message is disabled, issu
test("permalink: false outputPath new error message won’t throw an error, issue #3399", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("index.html", "", { permalink: false })
+ config: function ($config) {
+ $config.addTemplate("index.html", "", { permalink: false })
},
});
elev.disableLogger();
@@ -1569,15 +1592,15 @@ test("permalink: false outputPath new error message won’t throw an error, issu
test("permalink on custom template lang, issue #3619", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function (eleventyConfig) {
- eleventyConfig.addGlobalData("permalink", () => {
+ config: function ($config) {
+ $config.addGlobalData("permalink", () => {
return (data) =>
`/rewrite/${data.page.filePathStem}.${data.page.outputFileExtension}`;
});
- eleventyConfig.addTemplateFormats("scss");
+ $config.addTemplateFormats("scss");
- eleventyConfig.addExtension("scss", {
+ $config.addExtension("scss", {
outputFileExtension: "css",
compileOptions: {
permalink(inputContent, inputPath) {
@@ -1608,7 +1631,7 @@ test("permalink on custom template lang, issue #3619", async (t) => {
},
});
- eleventyConfig.addTemplate("index.scss", `html {
+ $config.addTemplate("index.scss", `html {
color: red;
}`)
},
@@ -1624,8 +1647,8 @@ test("permalink on custom template lang, issue #3619", async (t) => {
test("Template data throws error when tags is not an Array or String #1791", async (t) => {
let elev = new Eleventy("./test/noop/", "./test/noop/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplate("index.html", "", {
+ config: function ($config) {
+ $config.addTemplate("index.html", "", {
tags: {"one": 1, "two": 2}
});
},
@@ -1640,10 +1663,10 @@ test("Template data throws error when tags is not an Array or String #1791", asy
test("sass docs on 11ty.dev, issue #408", async (t) => {
let elev = new Eleventy("./test/stubs-408-sass/", undefined, {
- config: function (eleventyConfig) {
- eleventyConfig.addTemplateFormats("scss");
+ config: function ($config) {
+ $config.addTemplateFormats("scss");
- eleventyConfig.addExtension("scss", {
+ $config.addExtension("scss", {
outputFileExtension: "css",
// opt-out of Eleventy Layouts
@@ -1694,9 +1717,9 @@ test("sass docs on 11ty.dev, issue #408", async (t) => {
test("Use a date object for `date`, issue #3022", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function (eleventyConfig) {
- eleventyConfig.dataFilterSelectors.add("page.date");
- eleventyConfig.addTemplate("index.html", "", { date: new Date() })
+ config: function ($config) {
+ $config.dataFilterSelectors.add("page.date");
+ $config.addTemplate("index.html", "", { date: new Date() })
},
});
elev.disableLogger();
@@ -1708,9 +1731,9 @@ test("Use a date object for `date`, issue #3022", async (t) => {
test("Use a date object for `date` (js object front matter), issue #3022", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function (eleventyConfig) {
- eleventyConfig.dataFilterSelectors.add("page.date");
- eleventyConfig.addTemplate("index.html", `---js
+ config: function ($config) {
+ $config.dataFilterSelectors.add("page.date");
+ $config.addTemplate("index.html", `---js
{
date: new Date(),
}
@@ -1726,9 +1749,9 @@ test("Use a date object for `date` (js object front matter), issue #3022", async
test("Use a date object for `date` (js front matter), issue #3022", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function (eleventyConfig) {
- eleventyConfig.dataFilterSelectors.add("page.date");
- eleventyConfig.addTemplate("index.html", `---js
+ config: function ($config) {
+ $config.dataFilterSelectors.add("page.date");
+ $config.addTemplate("index.html", `---js
let date = new Date();
---`);
},
@@ -1743,8 +1766,8 @@ let date = new Date();
test("Cleaner constructor args #3880", async (t) => {
let elev = new Eleventy({
input: "./test/stubs-virtual/",
- config: eleventyConfig => {
- eleventyConfig.addTemplate("index.md", `# Title`)
+ config: $config => {
+ $config.addTemplate("index.md", `# Title`)
}
});
diff --git a/test/EleventyAddGlobalDataTest.js b/test/EleventyAddGlobalDataTest.js
index 9181dfd74..04825c39b 100644
--- a/test/EleventyAddGlobalDataTest.js
+++ b/test/EleventyAddGlobalDataTest.js
@@ -1,11 +1,11 @@
import test from "ava";
-import Eleventy from "../src/Eleventy.js";
+import Eleventy from "../src/Core.js";
test("Eleventy addGlobalData should run once", async (t) => {
let count = 0;
let elev = new Eleventy("./test/stubs-addglobaldata/", "./test/stubs-addglobaldata/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addGlobalData("count", () => {
+ config: function ($config) {
+ $config.addGlobalData("count", () => {
count++;
return count;
});
@@ -22,8 +22,8 @@ test("Eleventy addGlobalData shouldn’t run if no input templates match!", asyn
"./test/stubs-addglobaldata-noop/",
"./test/stubs-addglobaldata-noop/_site",
{
- config: function (eleventyConfig) {
- eleventyConfig.addGlobalData("count", () => {
+ config: function ($config) {
+ $config.addGlobalData("count", () => {
count++;
return count;
});
@@ -37,9 +37,9 @@ test("Eleventy addGlobalData shouldn’t run if no input templates match!", asyn
test("Eleventy addGlobalData can feed layouts to populate data cascade with layout data, issue #1245", async (t) => {
let elev = new Eleventy("./test/stubs-2145/", "./test/stubs-2145/_site", {
- config: function (eleventyConfig) {
- eleventyConfig.addGlobalData("layout", () => "layout.njk");
- eleventyConfig.dataFilterSelectors.add("LayoutData");
+ config: function ($config) {
+ $config.addGlobalData("layout", () => "layout.njk");
+ $config.dataFilterSelectors.add("LayoutData");
},
});
@@ -50,20 +50,20 @@ test("Eleventy addGlobalData can feed layouts to populate data cascade with layo
test("Eleventy addGlobalData merge data #3389", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function (eleventyConfig) {
- eleventyConfig.addGlobalData("eleventyComputed", {
+ config: function ($config) {
+ $config.addGlobalData("eleventyComputed", {
testing(data) {
return `testing:${data.page.url}`;
}
});
- eleventyConfig.addGlobalData("eleventyComputed", {
+ $config.addGlobalData("eleventyComputed", {
other(data) {
return `other:${data.page.url}`;
}
});
- eleventyConfig.addTemplate("computed.njk", "{{ testing }}|{{ other }}", {})
+ $config.addTemplate("computed.njk", "{{ testing }}|{{ other }}", {})
},
});
@@ -74,20 +74,20 @@ test("Eleventy addGlobalData merge data #3389", async (t) => {
test("Eleventy addGlobalData merge data #3389 lodash set", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function (eleventyConfig) {
- eleventyConfig.addGlobalData("eleventyComputed.testing", () => {
+ config: function ($config) {
+ $config.addGlobalData("eleventyComputed.testing", () => {
return (data) => {
return `testing:${data.page.url}`;
}
});
- eleventyConfig.addGlobalData("eleventyComputed.other", () => {
+ $config.addGlobalData("eleventyComputed.other", () => {
return (data) => {
return `other:${data.page.url}`;
}
});
- eleventyConfig.addTemplate("computed.njk", "{{ testing }}|{{ other }}", {})
+ $config.addTemplate("computed.njk", "{{ testing }}|{{ other }}", {})
},
});
@@ -98,16 +98,16 @@ test("Eleventy addGlobalData merge data #3389 lodash set", async (t) => {
test.skip("Eleventy addGlobalData merge data #3389 no nested function", async (t) => {
let elev = new Eleventy("./test/stubs-virtual/", undefined, {
- config: function (eleventyConfig) {
- eleventyConfig.addGlobalData("eleventyComputed.testing", (data) => {
+ config: function ($config) {
+ $config.addGlobalData("eleventyComputed.testing", (data) => {
return `testing:${data.page.url}`;
});
- eleventyConfig.addGlobalData("eleventyComputed.other", (data) => {
+ $config.addGlobalData("eleventyComputed.other", (data) => {
return `other:${data.page.url}`;
});
- eleventyConfig.addTemplate("computed.njk", "{{ testing }}|{{ other }}", {})
+ $config.addTemplate("computed.njk", "{{ testing }}|{{ other }}", {})
},
});
diff --git a/test/EleventyImgTransformTest.js b/test/EleventyImgTransformTest.js
index 9dbc9736f..6e7f99827 100644
--- a/test/EleventyImgTransformTest.js
+++ b/test/EleventyImgTransformTest.js
@@ -1,12 +1,12 @@
import test from "ava";
-import Eleventy from "../src/Eleventy.js";
+import Eleventy from "../src/Core.js";
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
import { normalizeNewLines } from "./Util/normalizeNewLines.js";
test("Default image transform with a single image", async (t) => {
let elev = new Eleventy("./test/stubs-img-transform/single.md", "./test/stubs-img-transform/_site", {
- config: eleventyConfig => {
- eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
+ config: $config => {
+ $config.addPlugin(eleventyImageTransformPlugin, {
extensions: "html",
dryRun: true,
formats: ["auto"],
@@ -24,8 +24,8 @@ test("Default image transform with a single image", async (t) => {
test("Default image transform with multiple images", async (t) => {
let elev = new Eleventy("./test/stubs-img-transform/multiple.md", "./test/stubs-img-transform/_site", {
- config: eleventyConfig => {
- eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
+ config: $config => {
+ $config.addPlugin(eleventyImageTransformPlugin, {
extensions: "html",
dryRun: true,
formats: ["auto"],
@@ -44,8 +44,8 @@ test("Default image transform with multiple images", async (t) => {
test("Default image transform with an ignored image", async (t) => {
let elev = new Eleventy("./test/stubs-img-transform/ignored.md", "./test/stubs-img-transform/_site", {
- config: eleventyConfig => {
- eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
+ config: $config => {
+ $config.addPlugin(eleventyImageTransformPlugin, {
extensions: "html",
dryRun: true,
formats: ["auto"],
@@ -63,8 +63,8 @@ test("Default image transform with an ignored image", async (t) => {
test("Missing alt", async (t) => {
let elev = new Eleventy("./test/stubs-img-transform/missing-alt.md", "./test/stubs-img-transform/_site", {
- config: eleventyConfig => {
- eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
+ config: $config => {
+ $config.addPlugin(eleventyImageTransformPlugin, {
extensions: "html",
dryRun: true,
formats: ["auto"],
diff --git a/test/EleventyMarkdownTest.js b/test/EleventyMarkdownTest.js
index e2f6839fd..512a7a80c 100644
--- a/test/EleventyMarkdownTest.js
+++ b/test/EleventyMarkdownTest.js
@@ -1,12 +1,12 @@
import test from "ava";
-import Eleventy from "../src/Eleventy.js";
+import Eleventy from "../src/Core.js";
test("Markdown in markdown #3954", async (t) => {
let elev = new Eleventy({
input: "./test/stubs-virtual/",
- config: eleventyConfig => {
- eleventyConfig.addTemplate("_includes/layout.md", `{{ content }}`);
- eleventyConfig.addTemplate("index.md", `---
+ config: $config => {
+ $config.addTemplate("_includes/layout.md", `{{ content }}`);
+ $config.addTemplate("index.md", `---
layout: layout.md
---
# Heading
@@ -32,9 +32,9 @@ layout: layout.md
test("Preprocess Markdown with markdown #3925", async (t) => {
let elev = new Eleventy({
input: "./test/stubs-virtual/",
- config: eleventyConfig => {
- eleventyConfig.setMarkdownTemplateEngine("md");
- eleventyConfig.addTemplate("index.md", `# Heading
+ config: $config => {
+ $config.setMarkdownTemplateEngine("md");
+ $config.addTemplate("index.md", `# Heading
\`\`\`
# This is code
diff --git a/test/EleventyNunjucksTest.js b/test/EleventyNunjucksTest.js
index 2cfb01e21..68b74c007 100644
--- a/test/EleventyNunjucksTest.js
+++ b/test/EleventyNunjucksTest.js
@@ -1,5 +1,5 @@
import test from "ava";
-import Eleventy from "../src/Eleventy.js";
+import Eleventy from "../src/Core.js";
test("Paired shortcodes in macros #2261 #1749", async (t) => {
let elev = new Eleventy({
diff --git a/test/EleventyErrorHandlerTest.js b/test/ErrorHandlerTest.js
similarity index 85%
rename from test/EleventyErrorHandlerTest.js
rename to test/ErrorHandlerTest.js
index bc7aab229..c1c905864 100644
--- a/test/EleventyErrorHandlerTest.js
+++ b/test/ErrorHandlerTest.js
@@ -1,8 +1,8 @@
import test from "ava";
-import { EleventyErrorHandler } from "../src/Errors/EleventyErrorHandler.js";
+import { ErrorHandler } from "../src/Errors/ErrorHandler.js";
test("Log a warning, warning", (t) => {
- let errorHandler = new EleventyErrorHandler();
+ let errorHandler = new ErrorHandler();
let output = [];
errorHandler.logger = {
log: function (str) {
@@ -25,7 +25,7 @@ test("Log a warning, warning", (t) => {
});
test("Log a warning, error", (t) => {
- let errorHandler = new EleventyErrorHandler();
+ let errorHandler = new ErrorHandler();
let output = [];
errorHandler.logger = {
diff --git a/test/EleventyErrorUtilTest.js b/test/ErrorUtilTest.js
similarity index 94%
rename from test/EleventyErrorUtilTest.js
rename to test/ErrorUtilTest.js
index 34728abd9..5c4789497 100644
--- a/test/EleventyErrorUtilTest.js
+++ b/test/ErrorUtilTest.js
@@ -1,10 +1,10 @@
import test from "ava";
-import EleventyErrorUtil from "../src/Errors/EleventyErrorUtil.js";
+import ErrorUtil from "../src/Errors/ErrorUtil.js";
const SAMPLE_ERROR = new Error("Nothing to see here");
const { cleanMessage, hasEmbeddedError, convertErrorToString, deconvertErrorToObject } =
- EleventyErrorUtil;
+ ErrorUtil;
test("hasEmbeddedError()", (t) => {
t.false(hasEmbeddedError(""));
diff --git a/test/EleventyExtensionMapTest.js b/test/ExtensionMapTest.js
similarity index 98%
rename from test/EleventyExtensionMapTest.js
rename to test/ExtensionMapTest.js
index 03f2b1ca1..1105de5e9 100644
--- a/test/EleventyExtensionMapTest.js
+++ b/test/ExtensionMapTest.js
@@ -1,5 +1,5 @@
import test from "ava";
-import EleventyExtensionMap from "../src/EleventyExtensionMap.js";
+import ExtensionMap from "../src/ExtensionMap.js";
import TemplateEngineManager from "../src/Engines/TemplateEngineManager.js";
import TemplateConfig from "../src/TemplateConfig.js";
@@ -7,7 +7,7 @@ async function getExtensionMap(formats, config = new TemplateConfig()) {
if (config) {
await config.init();
}
- let map = new EleventyExtensionMap(config);
+ let map = new ExtensionMap(config);
map.setFormats(formats);
map.engineManager = new TemplateEngineManager(config);
return map;
diff --git a/test/EleventyFilesGitIgnoreEleventyIgnoreTest.js b/test/FilesGitIgnoreEleventyIgnoreTest.js
similarity index 77%
rename from test/EleventyFilesGitIgnoreEleventyIgnoreTest.js
rename to test/FilesGitIgnoreEleventyIgnoreTest.js
index f98982823..bbccb9e60 100644
--- a/test/EleventyFilesGitIgnoreEleventyIgnoreTest.js
+++ b/test/FilesGitIgnoreEleventyIgnoreTest.js
@@ -6,14 +6,14 @@ import { getTemplateConfigInstance, getTemplateConfigInstanceCustomCallback, get
/* .eleventyignore and .gitignore combos */
test("Get ignores (no .eleventyignore no .gitignore)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "test/stubs/ignore1",
output: "test/stubs/ignore1/_site"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
evf._setLocalPathRoot("./test/stubs/ignorelocalroot");
t.deepEqual(evf.getIgnores(), [
@@ -28,14 +28,14 @@ test("Get ignores (no .eleventyignore no .gitignore)", async (t) => {
});
test("Get ignores (no .eleventyignore)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "test/stubs/ignore2",
output: "test/stubs/ignore2/_site"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
evf._setLocalPathRoot("./test/stubs/ignorelocalrootgitignore");
t.deepEqual(evf.getIgnores(), [
@@ -51,14 +51,14 @@ test("Get ignores (no .eleventyignore)", async (t) => {
});
test("Get ignores (no .eleventyignore, using setUseGitIgnore(false))", async (t) => {
- let eleventyConfig = await getTemplateConfigInstanceCustomCallback({
+ let $config = await getTemplateConfigInstanceCustomCallback({
input: "test/stubs/ignore2",
output: "test/stubs/ignore2/_site",
- }, function(eleventyConfig) {
- eleventyConfig.setUseGitIgnore(false);
+ }, function($config) {
+ $config.setUseGitIgnore(false);
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
evf._setLocalPathRoot("./test/stubs/ignorelocalroot");
t.deepEqual(evf.getIgnores(), [
@@ -73,14 +73,14 @@ test("Get ignores (no .eleventyignore, using setUseGitIgnore(false))", async (t)
});
test("Get ignores (no .gitignore)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "test/stubs/ignore3",
output: "test/stubs/ignore3/_site"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
evf._setLocalPathRoot("./test/stubs/ignorelocalroot");
t.deepEqual(evf.getIgnores(), [
@@ -97,14 +97,14 @@ test("Get ignores (no .gitignore)", async (t) => {
});
test("Get ignores (project .eleventyignore and root .gitignore)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "test/stubs/ignore4",
output: "test/stubs/ignore4/_site"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
evf._setLocalPathRoot("./test/stubs/ignorelocalrootgitignore");
t.deepEqual(evf.getIgnores(), [
@@ -122,14 +122,14 @@ test("Get ignores (project .eleventyignore and root .gitignore)", async (t) => {
});
test("Get ignores (project .eleventyignore and root .gitignore, using setUseGitIgnore(false))", async (t) => {
- let eleventyConfig = await getTemplateConfigInstanceCustomCallback({
+ let $config = await getTemplateConfigInstanceCustomCallback({
input: "test/stubs/ignore4",
output: "test/stubs/ignore4/_site",
- }, function(eleventyConfig) {
- eleventyConfig.setUseGitIgnore(false);
+ }, function($config) {
+ $config.setUseGitIgnore(false);
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
evf._setLocalPathRoot("./test/stubs/ignorelocalrootgitignore");
@@ -147,14 +147,14 @@ test("Get ignores (project .eleventyignore and root .gitignore, using setUseGitI
});
test("Get ignores (no .eleventyignore .gitignore exists but empty)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "test/stubs/ignore5",
output: "test/stubs/ignore5/_site"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
evf._setLocalPathRoot("./test/stubs/ignorelocalroot");
@@ -170,14 +170,14 @@ test("Get ignores (no .eleventyignore .gitignore exists but empty)", async (t)
});
test("Get ignores (both .eleventyignore and .gitignore exists, but .gitignore is empty)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "test/stubs/ignore6",
output: "test/stubs/ignore6/_site"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
evf._setLocalPathRoot("./test/stubs/ignorelocalroot");
t.deepEqual(evf.getIgnores(), [
@@ -194,16 +194,16 @@ test("Get ignores (both .eleventyignore and .gitignore exists, but .gitignore is
});
test("Bad expected output, this indicates a bug upstream in a dependency (update, was fixed in fast-glob@3.3.3). Input to 'src' and empty includes dir (issue #403, full paths in eleventyignore)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstanceCustomCallback({
+ let $config = await getTemplateConfigInstanceCustomCallback({
input: "test/stubs-403",
output: "_site",
includes: "",
data: false,
- }, function(eleventyConfig) {
- eleventyConfig.setUseGitIgnore(false);
+ }, function($config) {
+ $config.setUseGitIgnore(false);
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid"], $config);
evf._setEleventyIgnoreContent(TemplatePath.absolutePath("test/stubs-403/_includes") + "/**");
evf.init(); // duplicate init
@@ -216,16 +216,16 @@ test("Bad expected output, this indicates a bug upstream in a dependency (update
});
test("Workaround for Bad expected output, this indicates a bug upstream in a dependency. Input to 'src' and empty includes dir (issue #403, full paths in eleventyignore)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstanceCustomCallback({
+ let $config = await getTemplateConfigInstanceCustomCallback({
input: "test/stubs-403",
output: "_site",
includes: "",
data: false,
- }, function(eleventyConfig) {
- eleventyConfig.setUseGitIgnore(false);
+ }, function($config) {
+ $config.setUseGitIgnore(false);
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid"], $config);
evf._setEleventyIgnoreContent("./test/stubs-403/_includes/**");
evf.init(); // duplicate init
@@ -233,16 +233,16 @@ test("Workaround for Bad expected output, this indicates a bug upstream in a dep
});
test("Issue #403: all .eleventyignores should be relative paths not absolute paths", async (t) => {
- let eleventyConfig = await getTemplateConfigInstanceCustomCallback({
+ let $config = await getTemplateConfigInstanceCustomCallback({
input: "test/stubs-403",
output: "_site",
includes: "",
data: false,
- }, function(eleventyConfig) {
- eleventyConfig.setUseGitIgnore(false);
+ }, function($config) {
+ $config.setUseGitIgnore(false);
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid"], $config);
let globs = await evf.getFileGlobs();
t.is(
@@ -254,14 +254,14 @@ test("Issue #403: all .eleventyignores should be relative paths not absolute pat
});
test("Same input and output directories, issues #186 and #1129", async (t) => {
- let eleventyConfig = await getTemplateConfigInstanceCustomCallback({
+ let $config = await getTemplateConfigInstanceCustomCallback({
input: "test/stubs",
output: "",
- }, function(eleventyConfig) {
- eleventyConfig.setUseGitIgnore(false);
+ }, function($config) {
+ $config.setUseGitIgnore(false);
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
t.deepEqual(
evf.getIgnores().filter((entry) => entry.indexOf("_site") > -1),
@@ -270,15 +270,15 @@ test("Same input and output directories, issues #186 and #1129", async (t) => {
});
test("Single input file is in the output directory, issues #186", async (t) => {
- let eleventyConfig = await getTemplateConfigInstanceCustomCallback({
+ let $config = await getTemplateConfigInstanceCustomCallback({
input: "test/stubs",
output: "",
includes: "",
- }, function(eleventyConfig) {
- eleventyConfig.setUseGitIgnore(false);
+ }, function($config) {
+ $config.setUseGitIgnore(false);
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["njk"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["njk"], $config);
t.deepEqual(
evf.getIgnores().filter((entry) => entry.indexOf("_site") > -1),
@@ -287,14 +287,14 @@ test("Single input file is in the output directory, issues #186", async (t) => {
});
test("De-duplicated ignores", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "test/stubs/ignore-dedupe",
output: "test/stubs/ignore-dedupe/_site"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
evf._setLocalPathRoot("./test/stubs/ignore-dedupe");
diff --git a/test/EleventyFilesTest.js b/test/FilesTest.js
similarity index 77%
rename from test/EleventyFilesTest.js
rename to test/FilesTest.js
index fdb71b58b..d47f2c9a5 100644
--- a/test/EleventyFilesTest.js
+++ b/test/FilesTest.js
@@ -1,16 +1,15 @@
import test from "ava";
import { glob } from "tinyglobby";
-import EleventyFiles from "../src/EleventyFiles.js";
import TemplateConfig from "../src/TemplateConfig.js";
import TemplatePassthroughManager from "../src/TemplatePassthroughManager.js";
import ProjectDirectories from "../src/Util/ProjectDirectories.js";
-import { isTypeScriptSupported } from "../src/Util/FeatureTests.cjs";
+import { isTypeScriptSupported } from "../src/Util/TypeScriptFeatureTest.cjs";
import { getTemplateConfigInstance, getTemplateConfigInstanceCustomCallback, getEleventyFilesInstance } from "./_testHelpers.js";
test("Dirs paths", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "src",
includes: "includes",
@@ -19,7 +18,7 @@ test("Dirs paths", async (t) => {
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
t.deepEqual(evf.inputDir, "./src/");
t.deepEqual(evf.includesDir, "./src/includes/");
@@ -28,7 +27,7 @@ test("Dirs paths", async (t) => {
});
test("Dirs paths (relative)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "src",
includes: "../includes",
@@ -37,7 +36,7 @@ test("Dirs paths (relative)", async (t) => {
},
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
t.deepEqual(evf.inputDir, "./src/");
t.deepEqual(evf.includesDir, "./includes/");
@@ -46,49 +45,49 @@ test("Dirs paths (relative)", async (t) => {
});
test("getFiles", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "./test/stubs/writeTest",
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid", "md"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid", "md"], $config);
t.deepEqual(await evf.getFiles(), ["./test/stubs/writeTest/test.md"]);
});
test("getFiles (without 11ty.js)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "./test/stubs/writeTestJS"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid", "md"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid", "md"], $config);
t.deepEqual(await evf.getFiles(), []);
});
test("getFiles (with 11ty.js)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "./test/stubs/writeTestJS",
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid", "md", "11ty.js"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid", "md", "11ty.js"], $config);
t.deepEqual(await evf.getFiles(), ["./test/stubs/writeTestJS/test.11ty.cjs"]);
});
test("getFiles (with js, treated as passthrough copy)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "./test/stubs/writeTestJS-passthrough",
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid", "md", "js", "11ty.js"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid", "md", "js", "11ty.js"], $config);
const files = await evf.getFiles();
t.deepEqual(
@@ -104,13 +103,13 @@ test("getFiles (with js, treated as passthrough copy)", async (t) => {
});
test("getFiles (with case insensitivity)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "./test/stubs/writeTestJS-casesensitive",
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["11ty.js", "JS"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["11ty.js", "JS"], $config);
t.deepEqual(
(await evf.getFiles()).sort(),
@@ -124,13 +123,13 @@ test("getFiles (with case insensitivity)", async (t) => {
});
test("Mutually exclusive Input and Output dirs", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "./test/stubs/writeTest",
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid", "md"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid", "md"], $config);
let files = await glob(evf.getFileGlobs());
t.deepEqual(evf.getRawFiles(), ["./test/stubs/writeTest/**/*.{liquid,md}"]);
@@ -139,13 +138,13 @@ test("Mutually exclusive Input and Output dirs", async (t) => {
});
test("Single File Input (deep path)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "./test/stubs/index.html",
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid", "md"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid", "md"], $config);
let files = await glob(evf.getFileGlobs());
t.is(evf.getRawFiles().length, 1);
@@ -154,13 +153,13 @@ test("Single File Input (deep path)", async (t) => {
});
test("Single File Input (shallow path)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "README.md",
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["md"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["md"], $config);
let globs = evf.getFileGlobs(); //.filter((path) => path !== "./README.md");
let files = await glob(globs, {
@@ -172,12 +171,12 @@ test("Single File Input (shallow path)", async (t) => {
});
test("Glob Input", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "./test/stubs/glob-pages/!(contact.md)",
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["md"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["md"], $config);
let globs = evf.getFileGlobs();
let files = await glob(globs);
@@ -188,12 +187,12 @@ test("Glob Input", async (t) => {
});
test(".eleventyignore parsing", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "./test/stubs/",
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["md"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["md"], $config);
let ignores = evf.getFileIgnores("./test/stubs/.eleventyignore");
t.is(ignores.length, 2);
@@ -202,12 +201,12 @@ test(".eleventyignore parsing", async (t) => {
});
test("Parse multiple .eleventyignores", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "./test/stubs/multiple-ignores/",
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["md"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["md"], $config);
let ignores = evf.getFileIgnores([
"./test/stubs/multiple-ignores/.eleventyignore",
@@ -222,24 +221,24 @@ test("Parse multiple .eleventyignores", async (t) => {
});
test("Passed file name does not exist", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "./",
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["md"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["md"], $config);
let ignores = evf.getFileIgnores(".thisfiledoesnotexist");
t.deepEqual(ignores, []);
});
test(".eleventyignore files", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "test/stubs"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid", "md"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["liquid", "md"], $config);
let ignoredFiles = await glob("test/stubs/ignoredFolder/*.md");
t.is(ignoredFiles.length, 1);
@@ -259,13 +258,13 @@ test(".eleventyignore files", async (t) => {
});
test("getTemplateData caching", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "test/stubs"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
evf.init();
let templateDataFirstCall = evf.templateData;
let templateDataSecondCall = evf.templateData;
@@ -273,36 +272,36 @@ test("getTemplateData caching", async (t) => {
});
test("getDataDir", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "."
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
evf.init();
t.is(evf.getDataDir(), "./_data/");
});
test("getDataDir subdir", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "test/stubs"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
evf.init();
t.is(evf.getDataDir(), "./test/stubs/_data/");
});
test("Include and Data Dirs", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "test/stubs"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
evf.init();
t.deepEqual(evf.getIncludesAndDataDirs(), [
@@ -312,12 +311,12 @@ test("Include and Data Dirs", async (t) => {
});
test("Input to 'src' and empty includes dir (issue #403)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "src"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["md", "liquid", "html"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["md", "liquid", "html"], $config);
evf._setEleventyIgnoreContent("!./src/_includes/**");
evf._setConfig({
useGitIgnore: false,
@@ -339,13 +338,13 @@ test("Input to 'src' and empty includes dir (issue #403)", async (t) => {
});
test("Glob Watcher Files", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "test/stubs"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["njk"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["njk"], $config);
t.deepEqual(evf.getGlobWatcherFiles(), [
"./test/stubs/**/*.njk",
@@ -355,12 +354,12 @@ test("Glob Watcher Files", async (t) => {
});
test("Glob Watcher Files with File Extension Passthroughs", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "test/stubs"
}
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["njk", "png"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["njk", "png"], $config);
t.deepEqual(evf.getGlobWatcherFiles(), [
"./test/stubs/**/*.njk",
@@ -371,16 +370,16 @@ test("Glob Watcher Files with File Extension Passthroughs", async (t) => {
});
test("Glob Watcher Files with File Extension Passthroughs with Dev Server (for free passthrough copy #2456)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstance({
+ let $config = await getTemplateConfigInstance({
dir: {
input: "test/stubs"
}
});
- eleventyConfig.userConfig.setServerPassthroughCopyBehavior("passthrough");
- eleventyConfig.config.serverPassthroughCopyBehavior = "passthrough";
+ $config.userConfig.setServerPassthroughCopyBehavior("passthrough");
+ $config.config.serverPassthroughCopyBehavior = "passthrough";
- let { eleventyFiles: evf } = getEleventyFilesInstance(["njk", "png"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["njk", "png"], $config);
evf.setRunMode("serve");
evf.init(); // duplicate init
@@ -394,7 +393,7 @@ test("Glob Watcher Files with File Extension Passthroughs with Dev Server (for f
});
test("Glob Watcher Files with Config Passthroughs (one template format)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstanceCustomCallback({
+ let $config = await getTemplateConfigInstanceCustomCallback({
input: "test/stubs",
output: "test/stubs/_site"
}, function(cfg) {
@@ -404,7 +403,7 @@ test("Glob Watcher Files with Config Passthroughs (one template format)", async
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["njk"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["njk"], $config);
t.deepEqual(evf.getGlobWatcherFiles(), [
"./test/stubs/**/*.njk",
@@ -415,7 +414,7 @@ test("Glob Watcher Files with Config Passthroughs (one template format)", async
});
test("Glob Watcher Files with Config Passthroughs (one template format) with Dev Server (for free passthrough copy #2456)", async (t) => {
- let eleventyConfig = await getTemplateConfigInstanceCustomCallback({
+ let $config = await getTemplateConfigInstanceCustomCallback({
input: "test/stubs"
}, function(cfg) {
cfg.setServerPassthroughCopyBehavior("passthrough");
@@ -425,11 +424,11 @@ test("Glob Watcher Files with Config Passthroughs (one template format) with Dev
};
});
- let { eleventyFiles: evf } = getEleventyFilesInstance(["njk"], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance(["njk"], $config);
evf.setRunMode("serve");
evf.init(); // duplicate init
- let mgr = new TemplatePassthroughManager(eleventyConfig);
+ let mgr = new TemplatePassthroughManager($config);
evf.setPassthroughManager(mgr);
t.deepEqual(evf.getGlobWatcherFiles(), [
@@ -447,13 +446,13 @@ test("Glob Watcher Files with Config Passthroughs (no template formats)", async
projectDirs.setViaConfigObject({
input: "test/stubs"
});
- let eleventyConfig = await getTemplateConfigInstance(templateConfig, projectDirs);
+ let $config = await getTemplateConfigInstance(templateConfig, projectDirs);
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
evf.init();
t.deepEqual(await evf.getGlobWatcherTemplateDataFiles(), [
- `./test/stubs/**/*.{json,11tydata.mjs,11tydata.cjs,11tydata.js${isTypeScriptSupported() ? ",11tydata.mts,11tydata.cts,11tydata.ts" : ""}}`,
+ `./test/stubs/**/*.{json,data.mjs,data.cjs,data.js,data.mts,data.cts,data.ts,11tydata.mjs,11tydata.cjs,11tydata.js,11tydata.mts,11tydata.cts,11tydata.ts}`,
]);
});
@@ -463,8 +462,8 @@ test("Test that negations are ignored (for now) PR#709, will change when #693 is
projectDirs.setViaConfigObject({
input: "test/stubs"
});
- let eleventyConfig = await getTemplateConfigInstance(templateConfig, projectDirs);
- let { eleventyFiles: evf } = getEleventyFilesInstance([], eleventyConfig);
+ let $config = await getTemplateConfigInstance(templateConfig, projectDirs);
+ let { eleventyFiles: evf } = getEleventyFilesInstance([], $config);
t.deepEqual(
evf.normalizeIgnoreContent(
diff --git a/test/HtmlBasePluginTest.js b/test/HtmlBasePluginTest.js
index d0e02e85d..163676dbb 100644
--- a/test/HtmlBasePluginTest.js
+++ b/test/HtmlBasePluginTest.js
@@ -1,7 +1,7 @@
import test from "ava";
import { default as HtmlBasePlugin, applyBaseToUrl } from "../src/Plugins/HtmlBasePlugin.js";
-import Eleventy from "../src/Eleventy.js";
+import Eleventy from "../src/Core.js";
import { normalizeNewLines } from "./Util/normalizeNewLines.js";
function getContentFor(results, filename) {
@@ -246,9 +246,9 @@ test("Using the filter directly", async (t) => {
test("Using the HTML base plugin (default values)", async (t) => {
let elev = new Eleventy("./test/stubs-base/", "./test/stubs-base/_site", {
configPath: false,
- config: function (eleventyConfig) {
- eleventyConfig.setUseTemplateCache(false);
- eleventyConfig.addPlugin(HtmlBasePlugin);
+ config: function ($config) {
+ $config.setUseTemplateCache(false);
+ $config.addPlugin(HtmlBasePlugin);
},
});
await elev.initializeConfig();
@@ -286,9 +286,9 @@ test("Using the HTML base plugin with pathPrefix: /test/", async (t) => {
pathPrefix: "/test/",
configPath: false,
- config: function (eleventyConfig) {
- eleventyConfig.setUseTemplateCache(false);
- eleventyConfig.addPlugin(HtmlBasePlugin);
+ config: function ($config) {
+ $config.setUseTemplateCache(false);
+ $config.addPlugin(HtmlBasePlugin);
},
});
@@ -327,9 +327,9 @@ test("Using the HTML base plugin with pathPrefix: /test/ and base: http://exampl
pathPrefix: "/test/",
configPath: false,
- config: function (eleventyConfig) {
- eleventyConfig.setUseTemplateCache(false);
- eleventyConfig.addPlugin(HtmlBasePlugin, {
+ config: function ($config) {
+ $config.setUseTemplateCache(false);
+ $config.addPlugin(HtmlBasePlugin, {
baseHref: "http://example.com/",
});
},
@@ -368,9 +368,9 @@ test("Using the HTML base plugin with pathPrefix: /test/ and base: http://exampl
test("Using the HTML base plugin strips extra path in full URL base (default pathPrefix)", async (t) => {
let elev = new Eleventy("./test/stubs-base/", "./test/stubs-base/_site", {
configPath: false,
- config: function (eleventyConfig) {
- eleventyConfig.setUseTemplateCache(false);
- eleventyConfig.addPlugin(HtmlBasePlugin, {
+ config: function ($config) {
+ $config.setUseTemplateCache(false);
+ $config.addPlugin(HtmlBasePlugin, {
baseHref: "http://example.com/hello/", // extra path will be stripped
});
},
@@ -411,9 +411,9 @@ test("Using the HTML base plugin strips extra path in full URL base (pathPrefix:
pathPrefix: "/test/",
configPath: false,
- config: function (eleventyConfig) {
- eleventyConfig.setUseTemplateCache(false);
- eleventyConfig.addPlugin(HtmlBasePlugin, {
+ config: function ($config) {
+ $config.setUseTemplateCache(false);
+ $config.addPlugin(HtmlBasePlugin, {
baseHref: "http://example.com/hello/", // extra path will be stripped
});
},
@@ -454,9 +454,9 @@ test("Opt out of the transform with falsy extensions list", async (t) => {
pathPrefix: "/test/",
configPath: false,
- config: function (eleventyConfig) {
- eleventyConfig.setUseTemplateCache(false);
- eleventyConfig.addPlugin(HtmlBasePlugin, {
+ config: function ($config) {
+ $config.setUseTemplateCache(false);
+ $config.addPlugin(HtmlBasePlugin, {
extensions: false,
});
},
@@ -497,9 +497,9 @@ test("Base plugin with permalink: false, #2602", async (t) => {
pathPrefix: "/test/",
configPath: false,
- config: function (eleventyConfig) {
- eleventyConfig.setUseTemplateCache(false);
- eleventyConfig.addPlugin(HtmlBasePlugin);
+ config: function ($config) {
+ $config.setUseTemplateCache(false);
+ $config.addPlugin(HtmlBasePlugin);
},
});
@@ -537,9 +537,9 @@ test("Using the HTML base plugin with pathPrefix: /test/ and transformed attribu
pathPrefix: "/test/",
configPath: false,
- config: function (eleventyConfig) {
- eleventyConfig.setUseTemplateCache(false);
- eleventyConfig.addPlugin(HtmlBasePlugin);
+ config: function ($config) {
+ $config.setUseTemplateCache(false);
+ $config.addPlugin(HtmlBasePlugin);
},
});
@@ -576,14 +576,14 @@ test("HTML base plugin only adds once (unique)", async (t) => {
t.plan(2);
let elev = new Eleventy("./test/stubs-base/", "./test/stubs-base/_site", {
configPath: false,
- config: function (eleventyConfig) {
+ config: function ($config) {
// Runs before defaultConfig.js
- t.is(eleventyConfig.plugins.length, 0);
- eleventyConfig.addPlugin(HtmlBasePlugin);
- eleventyConfig.addPlugin(HtmlBasePlugin);
- eleventyConfig.addPlugin(HtmlBasePlugin);
- eleventyConfig.addPlugin(HtmlBasePlugin);
- t.is(eleventyConfig.plugins.length, 1);
+ t.is($config.plugins.length, 0);
+ $config.addPlugin(HtmlBasePlugin);
+ $config.addPlugin(HtmlBasePlugin);
+ $config.addPlugin(HtmlBasePlugin);
+ $config.addPlugin(HtmlBasePlugin);
+ t.is($config.plugins.length, 1);
},
});
await elev.init();
@@ -593,21 +593,21 @@ test("HTML base plugin can resolve by name", async (t) => {
t.plan(2);
let elev = new Eleventy("./test/stubs-base/", "./test/stubs-base/_site", {
configPath: false,
- config: async function (eleventyConfig) {
+ config: async function ($config) {
// Runs before defaultConfig.js
- t.is(eleventyConfig.plugins.length, 0);
+ t.is($config.plugins.length, 0);
- let plugin = await eleventyConfig.resolvePlugin("@11ty/eleventy/html-base-plugin");
- eleventyConfig.addPlugin(plugin);
+ let plugin = await $config.resolvePlugin("@11ty/eleventy/html-base-plugin");
+ $config.addPlugin(plugin);
// does not add duplicate
- eleventyConfig.addPlugin(plugin);
+ $config.addPlugin(plugin);
// does not add duplicate even with a different reference
- eleventyConfig.addPlugin(HtmlBasePlugin);
- eleventyConfig.addPlugin(HtmlBasePlugin);
+ $config.addPlugin(HtmlBasePlugin);
+ $config.addPlugin(HtmlBasePlugin);
- t.is(eleventyConfig.plugins.length, 1);
+ t.is($config.plugins.length, 1);
},
});
await elev.init();
@@ -618,9 +618,9 @@ test("Using recognizeNoValueAttribute for boolean attributes without quotes #276
input: "./test/stubs-virtual/",
pathPrefix: "/prefixed/",
configPath: false,
- config: function (eleventyConfig) {
- eleventyConfig.setUseTemplateCache(false);
- eleventyConfig.addTemplate("index.njk", `---
+ config: function ($config) {
+ $config.setUseTemplateCache(false);
+ $config.addTemplate("index.njk", `---
permalink: /deep/
---
@@ -632,7 +632,7 @@ permalink: /deep/