diff --git a/.eleventy.js b/.eleventy.js index efcdedb7ab..1583f13b9b 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -7,7 +7,7 @@ const slugify = require("slugify"); const lodashGet = require("lodash/get"); const shortHash = require("short-hash"); -const { EleventyServerlessBundlerPlugin, EleventyEdgePlugin, EleventyRenderPlugin } = require("@11ty/eleventy"); +const { EleventyRenderPlugin } = require("@11ty/eleventy"); const syntaxHighlightPlugin = require("@11ty/eleventy-plugin-syntaxhighlight"); const navigationPlugin = require("@11ty/eleventy-navigation"); const rssPlugin = require("@11ty/eleventy-plugin-rss"); @@ -227,7 +227,6 @@ module.exports = function(eleventyConfig) { eleventyConfig.addPlugin(monthDiffPlugin); eleventyConfig.addPlugin(minificationLocalPlugin); eleventyConfig.addPlugin(EleventyRenderPlugin); - eleventyConfig.addPlugin(EleventyEdgePlugin); eleventyConfig.addPlugin(javascriptFrontMatter); eleventyConfig.addPlugin(pluginWebc, { components: [ @@ -246,21 +245,6 @@ module.exports = function(eleventyConfig) { } }); - if(process.env.NODE_ENV === "production") { - eleventyConfig.addPlugin(EleventyServerlessBundlerPlugin, { - name: "serverless", - functionsDir: "./netlify/functions/", - redirects: "netlify-toml-builders", - copy: [ - "config/", - "avatars/", - "src/img/logo.svg", - "src/img/possum-geri.png", - ".cache/eleventy-fetch/", - ] - }); - } - eleventyConfig.addCollection("sidebarNav", function(collection) { // filter out excludeFromSidebar options return collection.getAll() diff --git a/.gitignore b/.gitignore index a96b3f2f75..7cfe87e077 100644 --- a/.gitignore +++ b/.gitignore @@ -24,5 +24,7 @@ src/_data/builtwith/ netlify/edge-functions/_generated # Serverless +netlify/functions/dynamic/* +!netlify/functions/dynamic/index.js netlify/functions/serverless/* !netlify/functions/serverless/index.js \ No newline at end of file diff --git a/.nvmrc b/.nvmrc index 25bf17fc5a..8fdd954df9 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18 \ No newline at end of file +22 \ No newline at end of file diff --git a/netlify-email/email-change.html b/netlify-email/email-change.html deleted file mode 100644 index a5c9d107cb..0000000000 --- a/netlify-email/email-change.html +++ /dev/null @@ -1,4 +0,0 @@ -

Confirm Change of Email

- -

Follow this link to confirm the update of your email from {{ .Email }} to {{ .NewEmail }}:

-

Change Email

diff --git a/netlify-email/invitation-migration.html b/netlify-email/invitation-migration.html deleted file mode 100644 index 61133f7cb3..0000000000 --- a/netlify-email/invitation-migration.html +++ /dev/null @@ -1,9 +0,0 @@ -

Thank you for being an Eleventy Supporter!

- -

A few weeks ago we started sending invitations to all of our contributors to Eleventy on Open Collective to create Eleventy Contributors accounts. Eleventy Contributor Accounts have special access to premium features, like enhanced on-site documentation search.

- -

We have since moved our site from 11ty.io to 11ty.dev (follow @eleven_ty on Twitter for the why) and this move requires a password reset. Please reset your password on your account.

- -

Or copy and paste this link into your web browser: https://www.11ty.dev/docs/account/#invite_token={{ .Token }}

- -

If you have any questions, please contact @zachleat or @eleven_ty on Twitter. You can also email eleventy@zachleat.com. Thank you!

\ No newline at end of file diff --git a/netlify-email/invitation.html b/netlify-email/invitation.html deleted file mode 100644 index 818b5698c9..0000000000 --- a/netlify-email/invitation.html +++ /dev/null @@ -1,9 +0,0 @@ -

Thank you for being an Eleventy Contributor!

- -

As a way to say thank you for being a contributor to Eleventy on Open Collective, you have been invited to create an Eleventy Contributors account on 11ty.dev. Eleventy Contributor Accounts have special access to premium features, like on-site documentation search.

- -

Follow this link to accept the invite: Accept the invite

- -

Or copy and paste this link into your web browser: https://www.11ty.dev/docs/account/#invite_token={{ .Token }}

- -

If you have any questions, please contact @zachleat or @eleven_ty on Twitter. You can also email eleventy@zachleat.com. Thank you!

\ No newline at end of file diff --git a/netlify-email/password-reset.html b/netlify-email/password-reset.html deleted file mode 100644 index d6de75052e..0000000000 --- a/netlify-email/password-reset.html +++ /dev/null @@ -1,4 +0,0 @@ -

Reset Password

- -

Follow this link to reset the password for your Eleventy Contributors account:

-

Reset Password

diff --git a/netlify.toml b/netlify.toml deleted file mode 100644 index b25c59f533..0000000000 --- a/netlify.toml +++ /dev/null @@ -1,135 +0,0 @@ -[build] -publish = "_site" -command = "npm run build-production" - -[dev] -framework = "#static" -command = "npm start" - -[[plugins]] -# https://github.com/netlify/netlify-plugin-lighthouse -package = "@netlify/plugin-lighthouse" - -# Fails build when a category is below a threshold -[plugins.inputs.thresholds] -performance = 1.0 -accessibility = 1.0 -best-practices = 1.0 -seo = 1.0 - -[plugins.inputs] -output_path = "reports/lighthouse/index.html" - -[functions] -directory = "netlify/functions/" - -# [[edge_functions]] -# function = "user-preferences" -# path = "/account/preferences/" - -[[redirects]] -from = "/authors/:name/" -to = "/.netlify/builders/serverless" -status = 200 -force = true -_generated_by_eleventy_serverless = "serverless" - -[[redirects]] -# Web redirect -from = "/activity/" -to = "/firehose/" -status = 302 -force = true - -[[redirects]] -# Feed redirect -from = "/follow/" -to = "/firehose/firehose.rss" -status = 302 -force = true - -[[redirects]] -# Feed redirect -from = "/follow/follow.rss" -to = "/firehose/firehose.rss" -status = 302 -force = true - -[[redirects]] -from = "/speedlify/*" -to = "https://built-with-eleventy.netlify.app/speedlify/:splat" -status = 200 -force = true - -[[redirects]] -from = "/mastodon" -to = "https://fosstodon.org/@eleventy" -status = 301 -force = true - -[[redirects]] -from = "/youtube" -to = "https://www.youtube.com/c/EleventyVideo" -status = 301 -force = true - -[[redirects]] -from = "/twitter" -to = "https://twitter.com/eleven_ty" -status = 301 -force = true - -[[redirects]] -from = "/docs/sites/" -to = "/speedlify/" -status = 301 -force = true - -[[redirects]] -from = "/docs/performance-leaderboard/" -to = "/speedlify/" -status = 301 -force = true - -[[redirects]] -from = "/docs/accessibility-leaderboard/" -to = "/speedlify/" -status = 301 -force = true - -[[redirects]] -from = "/leaderboard/*" -to = "/speedlify/" -status = 301 -force = true - -[[redirects]] -from = "/news/*" -to = "/blog/:splat" -status = 301 -force = true - -[[redirects]] -from = "/docs/how-to-support/" -to = "/docs/community/" -status = 301 -force = true - -[[redirects]] -from = "/docs/plugins/cache/" -to = "/docs/plugins/fetch/" -status = 301 -force = true - -[[headers]] -for = "/api/*" - - [headers.values] - Access-Control-Allow-Origin = "*" - -[[headers]] -for = "/blog/feed.xml" - - [headers.values] - Content-Type = "application/xml; charset=utf-8" - x-content-type-options = "nosniff" diff --git a/netlify/edge-functions/eleventy-edge.js b/netlify/edge-functions/eleventy-edge.js deleted file mode 100644 index d349191ef0..0000000000 --- a/netlify/edge-functions/eleventy-edge.js +++ /dev/null @@ -1,25 +0,0 @@ -import { EleventyEdge, precompiledAppData } from "./_generated/eleventy-edge-app.js"; - -export default async (request, context) => { - try { - let edge = new EleventyEdge("edge", { - request, - context, - precompiled: precompiledAppData, - - // default is [], add more keys to opt-in e.g. ["appearance", "username"] - cookies: ["syntax"], - }); - - edge.config((eleventyConfig) => { - // Add some custom Edge-specific configuration - // e.g. Fancier json output - // eleventyConfig.addFilter("json", obj => JSON.stringify(obj, null, 2)); - }); - - return await edge.handleResponse(); - } catch (e) { - console.log("ERROR", { e }); - return context.next(e); - } -}; diff --git a/netlify/edge-functions/user-preferences.js b/netlify/edge-functions/user-preferences.js deleted file mode 100644 index a6f69df83d..0000000000 --- a/netlify/edge-functions/user-preferences.js +++ /dev/null @@ -1,34 +0,0 @@ -function setCookie(context, name, value) { - context.cookies.set({ - name, - value, - path: "/", - // want this in JS too, maybe for later - // httpOnly: true, - secure: true, - sameSite: "Lax", - }); -} - -export default async (request, context) => { - let url = new URL(request.url); - - // Save to cookie, redirect back to form - if(url.pathname === "/account/preferences/" && request.method === "POST") { - if(request.headers.get("content-type") === "application/x-www-form-urlencoded") { - let body = await request.text(); - let postData = Object.fromEntries(new URLSearchParams(body)); - // setCookie(context, "appearance", postData.appearance); - setCookie(context, "syntax", postData.syntax); - - return new Response(null, { - status: 302, - headers: { - location: postData.returnlocation || "/docs/" - } - }); - } - } - - return context.next(); -}; diff --git a/netlify/functions/image.js b/netlify/functions/image.js deleted file mode 100644 index 07e3f356e5..0000000000 --- a/netlify/functions/image.js +++ /dev/null @@ -1,77 +0,0 @@ -const { builder } = require("@netlify/functions"); -const eleventyImage = require("@11ty/eleventy-img"); - -/* Works with _redirects (:width and :format are optional) - -/api/image/:url/ /.netlify/functions/image 200! -/api/image/:url/:width/ /.netlify/functions/image 200! -/api/image/:url/:width/:format/ /.netlify/functions/image 200! - -*/ - -function isFullUrl(url) { - try { - new URL(url); - return true; - } catch(e) { - // invalid url OR local path - return false; - } -} - -// Based on https://github.com/DavidWells/netlify-functions-workshop/blob/master/lessons-code-complete/use-cases/13-returning-dynamic-images/functions/return-image.js -async function handler(event, context) { - // Links have the format /api/image/:url/:width/:format/ - // Where :dimensions are the viewport dimensions of the browser doing the screenshot - // e.g. /api/image/https%3A%2F%2Fwww.11ty.dev%2F/420x580/ - let pathSplit = event.path.split("/").filter(entry => !!entry); - let [,, url, width, format] = pathSplit; - - url = decodeURIComponent(url); - width = parseInt(width, 10); - - try { - if(!isFullUrl(url)) { - // it’s a path instead - url = `https://www.11ty.dev${url}`; - } - - let metadata = await eleventyImage(url, { - formats: [format || "auto"], - widths: [width || "auto"], - dryRun: true, - cacheOptions: { - dryRun: true, - } - }); - - if(!format) { - format = Object.keys(metadata).pop(); - } - - let sources = metadata[format]; - if(!Array.isArray(sources) || sources.length === 0) { - throw new Error(`Invalid \`format\`: ${format}`); - } - - return { - statusCode: 200, - headers: { - "content-type": sources[0].sourceType - }, - body: sources[0].buffer.toString('base64'), - isBase64Encoded: true - } - } catch (error) { - console.log("Error", error); - - return { - statusCode: 500, - body: JSON.stringify({ - error: error.message - }) - } - } -} - -exports.handler = builder(handler); diff --git a/netlify/functions/serverless/index.js b/netlify/functions/serverless/index.js deleted file mode 100644 index fc3767a850..0000000000 --- a/netlify/functions/serverless/index.js +++ /dev/null @@ -1,58 +0,0 @@ -const { EleventyServerless } = require("@11ty/eleventy"); - -// Explicit dependencies for the bundler from config file and global data. -// The file is generated by the Eleventy Serverless Bundler Plugin. -require("./eleventy-bundler-modules.js"); - -async function handler(event) { - let elev = new EleventyServerless("serverless", { - path: new URL(event.rawUrl).pathname, - singleTemplateScope: false, - query: event.multiValueQueryStringParameters || event.queryStringParameters, - functionsDir: "./netlify/functions/", - }); - - try { - let [page] = await elev.getOutput(); - - // If you want some of the data cascade available in `page.data`, use `eleventyConfig.dataFilterSelectors`. - // Read more: https://www.11ty.dev/docs/config/#data-filter-selectors - - return { - statusCode: 200, - headers: { - "Content-Type": "text/html; charset=UTF-8", - }, - body: page.content, - }; - } catch (error) { - // Only console log for matching serverless paths - // (otherwise you’ll see a bunch of BrowserSync 404s for non-dynamic URLs during --serve) - if (elev.isServerlessUrl(event.path)) { - console.log("Serverless Error:", error); - } - - return { - statusCode: error.httpStatusCode || 500, - body: JSON.stringify( - { - error: error.message, - }, - null, - 2 - ), - }; - } -} - -// Choose one: -// * Runs on each request: AWS Lambda, Netlify Function -// * Runs on first request only: Netlify On-demand Builder -// 1. Don’t forget to `npm install @netlify/functions` -// 2. Also use `redirects: "netlify-toml-builders"` in your config file’s serverless bundler options: -// https://www.11ty.dev/docs/plugins/serverless/#bundler-options - -// exports.handler = handler; - -const { builder } = require("@netlify/functions"); -exports.handler = builder(handler); diff --git a/netlify/functions/user.js b/netlify/functions/user.js deleted file mode 100644 index 73d9036587..0000000000 --- a/netlify/functions/user.js +++ /dev/null @@ -1,87 +0,0 @@ -const fetch = require("node-fetch"); -const slugify = require("slugify"); - -exports.handler = async (event, context, callback) => { - let query = ` -query eleventyBackers { - collective(slug: "11ty") { - members(limit: 9999) { - nodes { - account { - name, - imageUrl, - ... on Individual { - email - } - } - } - } - } -} -`; - - if(!process.env.OPENCOLLECT_API_KEY) { - return callback(null, { - statusCode: 500, - body: `{ "error": "Missing OpenCollective API KEY" }` - }); - } else { - let url = "https://api.opencollective.com/graphql/v2"; - let opts = { - method: "POST", - headers: { - "Content-Type": "application/json", - "Api-Key": process.env.OPENCOLLECT_API_KEY - }, - body: JSON.stringify({ query }) - }; - - let jsonError; - let result = await fetch(url, opts) - .then(res => res.json()) - .catch(function(error) { - jsonError = error; - }); - - if(jsonError) { - return callback(null, { - statusCode: 500, - body: `{ "error": "${jsonError}" }` - }); - } - - const {user} = context.clientContext; - if(user) { - if(user.email) { - console.log( `Log in from ${user.email}` ); - for(let supporter of result.data.collective.members.nodes) { - if(supporter.account.email === user.email) { - let slug = slugify(supporter.account.name).toLowerCase(); - console.log( `Match found for ${supporter.account.email}!` ); - - return callback(null, { - statusCode: 200, - body: `{ - "name": "${supporter.account.name}", - "image": "${supporter.account.imageUrl}", - "slug": "${slug}" -}` - }); - } - } - } - - return callback(null, { - statusCode: 404, - body: `{ - "error": "User not found." -}` - }); - } else { - return callback(null, { - statusCode: 401, - body: `{"error": "You must be signed in to call this function"}` - }); - } - } -}; diff --git a/package.json b/package.json index 8b860e5484..8795e760dd 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,9 @@ "check-links": "npx check-html-links _site", "build": "npx @11ty/eleventy --quiet && npm run create-search-index", "build-production": "npm run get-new-data && NODE_ENV=production npx @11ty/eleventy && npm run create-search-index", + "create-search-index": "npx pagefind --site _site --glob \"{docs,blog}/**/*.html\"", "start": "npx @11ty/eleventy --serve --quiet --port=8091 --incremental", "start-production": "NODE_ENV=production npx @11ty/eleventy --serve --quiet --port=8091", - "clean-serverless": "mv netlify/functions/serverless/index.js netlify/functions/tmp.index.js && rm -rf netlify/functions/serverless/ && mkdir netlify/functions/serverless && mv netlify/functions/tmp.index.js netlify/functions/serverless/index.js", - "create-search-index": "npx pagefind --source _site --glob \"{docs,blog}/**/*.html\"", "get-new-data": "rm -rf ./src/_data/builtwith/ && npx degit github:11ty/11ty-community/built-with-eleventy src/_data/builtwith/", "get-new-supporters": "eleventy && node node-supporters", "format": "prettier --write '**/*.{js,css,html,md}'" @@ -45,47 +44,44 @@ "devDependencies": { "@11ty/eleventy": "^2.0.1", "@11ty/eleventy-activity-feed": "^1.0.9", - "@11ty/eleventy-fetch": "^4.0.0", - "@11ty/eleventy-img": "^3.0.0", + "@11ty/eleventy-fetch": "^4.0.1", + "@11ty/eleventy-img": "^3.1.8", "@11ty/eleventy-navigation": "^0.3.5", "@11ty/eleventy-plugin-rss": "^1.2.0", "@11ty/eleventy-plugin-syntaxhighlight": "^4.2.0", - "@11ty/eleventy-plugin-webc": "^0.10.0", + "@11ty/eleventy-plugin-webc": "^0.10.1", "@11ty/webc": "^0.9.2", - "@netlify/functions": "^1.4.0", - "@netlify/plugin-lighthouse": "^4.0.7", - "@tweetback/canonical": "^2.0.29", - "clean-css": "^5.3.2", + "@tweetback/canonical": "^2.0.48", + "clean-css": "^5.3.3", "comma-number": "^2.1.0", "degit": "^2.8.4", - "dotenv": "^16.0.3", - "entities": "^4.4.0", - "fast-glob": "^3.2.12", - "fs-extra": "^11.1.0", + "dotenv": "^16.6.1", + "entities": "^4.5.0", + "fast-glob": "^3.3.3", + "fs-extra": "^11.3.2", "human-readable-numbers": "0.9.5", "lodash": "^4.17.21", - "luxon": "^3.2.1", - "markdown-it": "^13.0.1", + "luxon": "^3.7.2", + "markdown-it": "^13.0.2", "markdown-it-anchor": "^8.6.7", - "markdown-it-table-of-contents": "^0.6.0", - "netlify-plugin-cache": "^1.0.3", - "node-fetch": "^2.6.8", - "node-retrieve-globals": "^2.0.6", - "pagefind": "^0.12.0", - "prettier": "^2.8.4", - "semver": "^7.3.8", + "markdown-it-table-of-contents": "^0.9.0", + "node-fetch": "^2.7.0", + "node-retrieve-globals": "^2.0.8", + "pagefind": "^1.4.0", + "prettier": "^2.8.8", + "semver": "^7.7.3", "short-hash": "^1.0.0", - "slugify": "^1.6.5", - "terser": "^5.16.6" + "slugify": "^1.6.6", + "terser": "^5.44.1" }, "dependencies": { - "@11ty/is-land": "^4.0.0", + "@11ty/is-land": "^4.0.1", "@11ty/logo": "^2.0.6", "@zachleat/details-utils": "^2.0.2", "@zachleat/filter-container": "^3.0.4", "@zachleat/flex-luthor": "^4.0.2", - "@zachleat/seven-minute-tabs": "^2.0.0", - "lite-youtube-embed": "^0.2.0", + "@zachleat/seven-minute-tabs": "^2.0.4", + "lite-youtube-embed": "^0.3.4", "speedlify-score": "^2.0.2" } } diff --git a/src/_data/bannerlinks.js b/src/_data/bannerlinks.js index 1c9368ef98..e0a30c5dfa 100644 --- a/src/_data/bannerlinks.js +++ b/src/_data/bannerlinks.js @@ -1,26 +1 @@ -module.exports = [ - { - label: "Black Lives Matter", - url: "https://blacklivesmatter.com/", - }, - { - label: "The Equal Justice Initiative", - url: "https://eji.org/", - }, - { - label: "We The Protesters", - url: "http://www.wetheprotesters.org/", - }, - { - label: "The Trevor Project — Saving Young LGBTQ Lives", - url: "https://www.thetrevorproject.org/", - }, - { - label: "Asian Americans Advancing Justice — Stand Against Hatred", - url: "https://www.standagainsthatred.org/" - }, - { - label: "Stand with Ukraine 🇺🇦", - url: "https://war.ukraine.ua/" - } -]; +module.exports = []; diff --git a/src/_data/config.js b/src/_data/config.js index 329e6e74da..4813f008b5 100644 --- a/src/_data/config.js +++ b/src/_data/config.js @@ -1,5 +1,5 @@ module.exports = { - outdated: false, + outdated: true, prerelease: false, githubEdit: "https://github.com/11ty/11ty-website/blob/master/", now: new Date(), diff --git a/src/_data/versions.js b/src/_data/versions.js index 89341626bf..48c64958bd 100644 --- a/src/_data/versions.js +++ b/src/_data/versions.js @@ -9,7 +9,7 @@ module.exports = [ tag: "v2.0.1", docs_url: "https://v2-0-1.11ty.dev/docs/", minimumNodeVersion: 14, - }{ + },{ tag: "v2.0.0", docs_url: "https://v2-0-0.11ty.dev/docs/", minimumNodeVersion: 14, diff --git a/src/_includes/components/node-minimum.webc b/src/_includes/components/node-minimum.webc index 20c74ffd28..e1d121fc02 100644 --- a/src/_includes/components/node-minimum.webc +++ b/src/_includes/components/node-minimum.webc @@ -1,5 +1,5 @@ ---