Skip to content

Commit

Permalink
Adds support for type option in getShortcodes, getPairedShortcodes,…
Browse files Browse the repository at this point in the history
… and getFilters methods #3310
  • Loading branch information
zachleat committed Jul 10, 2024
1 parent 3f8d4e6 commit 7146c7a
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 9 deletions.
12 changes: 11 additions & 1 deletion src/Benchmark/BenchmarkGroup.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import debugUtil from "debug";

import ConsoleLogger from "../Util/ConsoleLogger.js";
import isAsyncFunction from "../Util/IsAsyncFunction.js";
import Benchmark from "./Benchmark.js";

const debugBenchmark = debugUtil("Eleventy:Benchmark");
Expand Down Expand Up @@ -30,12 +31,21 @@ class BenchmarkGroup {
add(type, callback) {
let benchmark = (this.benchmarks[type] = new Benchmark());

return function (...args) {
let fn = function (...args) {
benchmark.before();
let ret = callback.call(this, ...args);
benchmark.after();
return ret;
};

Object.defineProperty(fn, "__eleventyInternal", {
value: {
type: isAsyncFunction(callback) ? "async" : "sync",
callback,
},
});

return fn;
}

// callback must return a promise
Expand Down
36 changes: 28 additions & 8 deletions src/UserConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import RenderPlugin from "./Plugins/RenderPlugin.js";
import InputPathToUrlPlugin from "./Plugins/InputPathToUrl.js";
// import I18nPlugin from "./Plugins/I18nPlugin.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";
Expand All @@ -22,8 +24,6 @@ const debug = debugUtil("Eleventy:UserConfig");

class UserConfigError extends EleventyBaseError {}

const ComparisonAsyncFunction = (async () => {}).constructor;

/**
* API to expose configuration options in user-land configuration files
* @module 11ty/eleventy/UserConfig
Expand Down Expand Up @@ -197,23 +197,43 @@ class UserConfig {
return this.universal.filters[name];
}

getFilters() {
getFilters(options = {}) {
if (options.type) {
return objectFilter(
this.universal.filters,
(entry) => entry.__eleventyInternal?.type === options.type,
);
}

return this.universal.filters;
}

getShortcode(name) {
return this.universal.shortcodes[name];
}

getShortcodes() {
getShortcodes(options = {}) {
if (options.type) {
return objectFilter(
this.universal.shortcodes,
(entry) => entry.__eleventyInternal?.type === options.type,
);
}

return this.universal.shortcodes;
}

getPairedShortcode(name) {
return this.universal.pairedShortcodes[name];
}

getPairedShortcodes() {
getPairedShortcodes(options = {}) {
if (options.type) {
return objectFilter(
this.universal.pairedShortcodes,
(entry) => entry.__eleventyInternal?.type === options.type,
);
}
return this.universal.pairedShortcodes;
}

Expand Down Expand Up @@ -301,7 +321,7 @@ class UserConfig {

addFilter(name, callback) {
// This method *requires* `async function` and will not work with `function` that returns a promise
if (callback instanceof ComparisonAsyncFunction) {
if (isAsyncFunction(callback)) {
this.addAsyncFilter(name, callback);
return;
}
Expand Down Expand Up @@ -350,7 +370,7 @@ class UserConfig {

addShortcode(name, callback) {
// This method *requires* `async function` and will not work with `function` that returns a promise
if (callback instanceof ComparisonAsyncFunction) {
if (isAsyncFunction(callback)) {
this.addAsyncShortcode(name, callback);
return;
}
Expand Down Expand Up @@ -404,7 +424,7 @@ class UserConfig {

addPairedShortcode(name, callback) {
// This method *requires* `async function` and will not work with `function` that returns a promise
if (callback instanceof ComparisonAsyncFunction) {
if (isAsyncFunction(callback)) {
this.addPairedAsyncShortcode(name, callback);
return;
}
Expand Down
5 changes: 5 additions & 0 deletions src/Util/IsAsyncFunction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const ComparisonAsyncFunction = (async () => {}).constructor;

export default function isAsyncFunction(fn) {
return fn instanceof ComparisonAsyncFunction;
}
9 changes: 9 additions & 0 deletions src/Util/Objects/ObjectFilter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default function objectFilter(obj, callback) {
let newObject = {};
for (let [key, value] of Object.entries(obj)) {
if (callback(value, key)) {
newObject[key] = value;
}
}
return newObject;
}
26 changes: 26 additions & 0 deletions test/TemplateConfigTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,16 @@ test("Test getters #3310", async (t) => {
t.true(filterNames.includes("myAsyncFilter"));
t.true(filterNames.includes("myPluginFilter"));

let filterNamesSync = Object.keys(userCfg.getFilters({ type: "sync" }));
t.true(filterNamesSync.includes("myFilter"));
t.false(filterNamesSync.includes("myAsyncFilter"));
t.true(filterNamesSync.includes("myPluginFilter"));

let filterNamesAsync = Object.keys(userCfg.getFilters({ type: "async" }));
t.false(filterNamesAsync.includes("myFilter"));
t.true(filterNamesAsync.includes("myAsyncFilter"));
t.false(filterNamesAsync.includes("myPluginFilter"));

t.truthy(userCfg.getFilter("myFilter"));
t.truthy(userCfg.getFilter("myAsyncFilter"));
t.truthy(userCfg.getFilter("myPluginFilter"));
Expand All @@ -644,13 +654,29 @@ test("Test getters #3310", async (t) => {
t.true(shortcodeNames.includes("myShortcode"));
t.true(shortcodeNames.includes("myAsyncShortcode"));

let shortcodeNamesSync = Object.keys(userCfg.getShortcodes({ type: "sync" }));
t.true(shortcodeNamesSync.includes("myShortcode"));
t.false(shortcodeNamesSync.includes("myAsyncShortcode"));

let shortcodeNamesAsync = Object.keys(userCfg.getShortcodes({ type: "async" }));
t.false(shortcodeNamesAsync.includes("myShortcode"));
t.true(shortcodeNamesAsync.includes("myAsyncShortcode"));

t.truthy(userCfg.getShortcode("myShortcode"));
t.truthy(userCfg.getShortcode("myAsyncShortcode"));

let pairedShortcodeNames = Object.keys(userCfg.getPairedShortcodes());
t.true(pairedShortcodeNames.includes("myPairedShortcode"));
t.true(pairedShortcodeNames.includes("myPairedAsyncShortcode"));

let pairedShortcodeNamesSync = Object.keys(userCfg.getPairedShortcodes({ type: "sync" }));
t.true(pairedShortcodeNamesSync.includes("myPairedShortcode"));
t.false(pairedShortcodeNamesSync.includes("myPairedAsyncShortcode"));

let pairedShortcodeNamesAsync = Object.keys(userCfg.getPairedShortcodes({ type: "async" }));
t.false(pairedShortcodeNamesAsync.includes("myPairedShortcode"));
t.true(pairedShortcodeNamesAsync.includes("myPairedAsyncShortcode"));

t.truthy(userCfg.getPairedShortcode("myPairedShortcode"));
t.truthy(userCfg.getPairedShortcode("myPairedAsyncShortcode"));
});

0 comments on commit 7146c7a

Please sign in to comment.