eleventy-plugin-vento 4.1.0 → 4.1.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # eleventy-plugin-vento
2
2
 
3
+ ## 4.1.1-beta.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 335f21e: Select type updates (shouldn't affect compilation, however should improve DX)
8
+
9
+ Changes are:
10
+
11
+ - split types into separate files
12
+ - namespace `ventojs` type imports
13
+ - make `PluginOptions` optional by default
14
+ - make Eleventy types more readable
15
+ - declare a special (`EleventyVentoEnvironment`) for this plugin to replace Vento's own `Environment`
16
+
17
+ - 9eaa059: Update `debug` to v4.4.0
18
+ - f387b5e: Update `ventojs` to v1.12.13
19
+ - 070109a: Refactored files and functions internally that shouldn't have any impact on usage or performance:
20
+
21
+ - Split `debug` functions into separate exports, renamed `runCompatiblityCheck -> compatibilityCheck` (dd4c379b)
22
+ - Utilities are now split into separate files (e06a83ab)
23
+ - Main file renamed from `index.ts` to `plugin.ts` (1b122d2a)
24
+
3
25
  ## 4.1.0
4
26
 
5
27
  ### Minor Changes
@@ -1,13 +1,13 @@
1
1
  import { UserConfig } from '@11ty/eleventy';
2
- import { Options } from 'ventojs';
2
+ import { LiteralUnion } from 'type-fest';
3
+ import * as ventojs from 'ventojs';
3
4
  import { Plugin } from 'ventojs/src/environment.js';
4
5
 
5
- type AutotrimConfig = boolean | ('@11ty' | '@vento' | (string & Record<never, never>))[];
6
- interface VentoPluginOptions {
6
+ interface PluginOptions {
7
7
  /**
8
8
  * An array of Vento plugins
9
9
  */
10
- plugins: Plugin[];
10
+ plugins?: Plugin[];
11
11
  /**
12
12
  * Enables Vento's autotrim plugin.
13
13
  * ```js
@@ -20,13 +20,13 @@ interface VentoPluginOptions {
20
20
  * autotrim: true
21
21
  * ```
22
22
  */
23
- autotrim: AutotrimConfig;
23
+ autotrim?: LiteralUnion<'@11ty' | '@vento', string>[] | boolean;
24
24
  /** Enable use of Eleventy filters */
25
- filters: boolean;
25
+ filters?: boolean;
26
26
  /** Enable use of Eleventy shortcodes */
27
- shortcodes: boolean;
27
+ shortcodes?: boolean;
28
28
  /** Enable use of Eleventy paired shortcodes */
29
- pairedShortcodes: boolean;
29
+ pairedShortcodes?: boolean;
30
30
  /**
31
31
  * A Vento configuration object.
32
32
  *
@@ -34,13 +34,9 @@ interface VentoPluginOptions {
34
34
  * Eleventy's own `dir.includes` location.**
35
35
  * @see {@link https://vento.js.org/configuration/}
36
36
  */
37
- ventoOptions: Options;
37
+ ventoOptions?: ventojs.Options;
38
38
  }
39
39
 
40
- /**
41
- * @file Main plugin declaration
42
- */
43
-
44
- declare function VentoPlugin(eleventyConfig: UserConfig, userOptions: Partial<VentoPluginOptions>): void;
40
+ declare function VentoPlugin(eleventyConfig: UserConfig, userOptions: PluginOptions): void;
45
41
 
46
42
  export { VentoPlugin };
@@ -1,88 +1,65 @@
1
- // src/index.ts
1
+ // src/plugin.ts
2
2
  import path from "node:path";
3
3
  import autotrimPlugin, { defaultTags as autotrimDefaultTags } from "ventojs/plugins/auto_trim.js";
4
4
 
5
5
  // src/engine.ts
6
- import { default as ventojs } from "ventojs";
6
+ import createVentoEnv from "ventojs";
7
7
 
8
- // src/create-vento-tag.ts
9
- function createVentoTag(spec) {
10
- const IS_PAIRED = spec.group === "pairedShortcodes";
8
+ // src/utils/create-vento-tag.ts
9
+ function createVentoTag(tagInfo) {
10
+ const IS_PAIRED = tagInfo.group === "pairedShortcodes";
11
+ let INT = 0;
11
12
  const tag = (env, code, output, tokens) => {
12
- if (!code.startsWith(spec.name)) return;
13
+ if (!code.startsWith(tagInfo.name)) return;
13
14
  const { dataVarname } = env.options;
14
15
  const thisArg = `{
15
16
  page: ${dataVarname}.page,
16
17
  eleventy: ${dataVarname}.eleventy
17
18
  }`;
18
- const fn = `__env.utils.eleventyFunctions.${spec.group}.${spec.name}`;
19
- const args = [code.replace(spec.name, "").trim()];
20
- const varname = output.startsWith("__shortcode_content") ? `${output}_precomp` : "__shortcode_content";
19
+ const fn = `__env.utils.eleventyFunctions.${tagInfo.group}.${tagInfo.name}`;
20
+ const args = [code.replace(tagInfo.name, "").trim()];
21
21
  const compiled = [];
22
22
  if (IS_PAIRED) {
23
- args.unshift(env.compileFilters(tokens, varname, env.options.autoescape));
23
+ const nestedVarname = `__arg${INT++}`;
24
+ args.unshift(env.compileFilters(tokens, nestedVarname, env.options.autoescape));
24
25
  compiled.push(
25
26
  "{",
26
- `let ${varname} = "";`,
27
- ...env.compileTokens(tokens, varname, [`/${spec.name}`])
27
+ `let ${nestedVarname} = "";`,
28
+ ...env.compileTokens(tokens, nestedVarname, [`/${tagInfo.name}`])
28
29
  );
29
- if (tokens.length > 0 && (tokens[0][0] !== "tag" || tokens[0][1] !== `/${spec.name}`)) {
30
- throw new Error(`Vento: Missing closing tag for ${spec.name} tag: ${code}`);
30
+ if (tokens.length > 0 && (tokens[0][0] !== "tag" || tokens[0][1] !== `/${tagInfo.name}`)) {
31
+ throw new Error(`Vento: Missing closing tag for ${tagInfo.name} tag: ${code}`);
31
32
  }
32
33
  tokens.shift();
33
34
  }
34
35
  args.unshift(thisArg);
35
36
  compiled.push(
36
37
  "{",
37
- `const __shortcode_result = await ${fn}.call(${args.filter(Boolean).join(", ")});`,
38
- `${output} += ${env.compileFilters(tokens, "__shortcode_result", env.options.autoescape)}`,
38
+ `const __result = await ${fn}.call(${args.filter(Boolean).join(", ")});`,
39
+ `${output} += ${env.compileFilters(tokens, "__result", env.options.autoescape)}`,
39
40
  "}"
40
41
  );
41
42
  if (IS_PAIRED) {
42
43
  compiled.push("}");
43
44
  }
44
- const compiledTag = compiled.join("\n");
45
- return compiledTag;
45
+ return compiled.join("\n");
46
46
  };
47
47
  return Object.defineProperty(tag, "name", {
48
- value: spec.name + IS_PAIRED ? `PairedTag` : `Tag`
48
+ value: tagInfo.name + IS_PAIRED ? `PairedTag` : `Tag`
49
49
  });
50
50
  }
51
51
 
52
- // src/utils.ts
52
+ // src/utils/debuggers.ts
53
53
  import createDebugger from "debug";
54
54
  var debugBaseNamespace = "Eleventy:Vento";
55
- var DEBUG = {
56
- main: createDebugger(debugBaseNamespace),
57
- cache: createDebugger(`${debugBaseNamespace}:Cache`),
58
- render: createDebugger(`${debugBaseNamespace}:Render`)
59
- };
60
- var REQUIRED_API_METHODS = [
61
- ["getShortcodes", "v3.0.0-alpha.15"],
62
- ["getPairedShortcodes", "v3.0.0-alpha.15"],
63
- ["getFilters", "v3.0.0-alpha.15"],
64
- ["addExtension", "v1.0.0"]
65
- ];
66
- function runCompatibilityCheck(config) {
67
- DEBUG.main("Run compatibility check");
68
- for (const [method, version] of REQUIRED_API_METHODS) {
69
- if (!(method in config)) {
70
- console.error(
71
- "[eleventy-plugin-vento] Plugin compatibility error:",
72
- `\`${method}\``,
73
- "not found. Please use Eleventy",
74
- version,
75
- "or later."
76
- );
77
- }
78
- }
79
- }
55
+ var debugMain = createDebugger(debugBaseNamespace);
56
+ var debugCache = createDebugger(`${debugBaseNamespace}:Cache`);
57
+ var debugRender = createDebugger(`${debugBaseNamespace}:Render`);
80
58
 
81
59
  // src/engine.ts
82
60
  function createVentoEngine(options) {
83
- const env = ventojs(options);
61
+ const env = createVentoEnv(options);
84
62
  env.utils.eleventyFunctions = { shortcodes: {}, pairedShortcodes: {} };
85
- env.utils._11tyCtx = {};
86
63
  function loadPlugins(plugins) {
87
64
  for (const plugin of plugins) {
88
65
  env.use(plugin);
@@ -91,30 +68,33 @@ function createVentoEngine(options) {
91
68
  function loadFilters(filters) {
92
69
  for (const [name, fn] of Object.entries(filters)) {
93
70
  env.filters[name] = async function(...args) {
94
- Object.assign(this, { page: this.data.page, eleventy: this.data.eleventy });
95
- return await fn.apply(this, args);
71
+ const { page, eleventy } = this.data;
72
+ const filterResult = await fn.apply({ ...this, page, eleventy }, args);
73
+ return filterResult;
96
74
  };
97
75
  }
98
76
  }
99
77
  function loadShortcodes(shortcodes) {
100
78
  for (const [name, fn] of Object.entries(shortcodes)) {
101
79
  env.utils.eleventyFunctions.shortcodes[name] = fn;
102
- env.tags.push(createVentoTag({ name, group: "shortcodes" }));
80
+ const shortcodeTag = createVentoTag({ name, group: "shortcodes" });
81
+ env.tags.push(shortcodeTag);
103
82
  }
104
83
  }
105
84
  function loadPairedShortcodes(pairedShortcodes) {
106
85
  for (const [name, fn] of Object.entries(pairedShortcodes)) {
107
86
  env.utils.eleventyFunctions.pairedShortcodes[name] = fn;
108
- env.tags.push(createVentoTag({ name, group: "pairedShortcodes" }));
87
+ const shortcodeTag = createVentoTag({ name, group: "pairedShortcodes" });
88
+ env.tags.push(shortcodeTag);
109
89
  }
110
90
  }
111
91
  function getTemplateFunction(source, file, useVentoCache = true) {
112
92
  let template = env.cache.get(file);
113
- if (template?.source === source) {
114
- DEBUG.cache("Cache HIT for `%s`, used precompiled template", file);
93
+ if ((template == null ? void 0 : template.source) === source) {
94
+ debugCache("Cache HIT for `%s`, used precompiled template", file);
115
95
  } else {
116
96
  template = env.compile(source, file);
117
- DEBUG.cache(
97
+ debugCache(
118
98
  `Cache MISS for \`%s\`, compiled new template:
119
99
  Use Vento cache: %o
120
100
 
@@ -138,15 +118,37 @@ ${template}`,
138
118
  };
139
119
  }
140
120
  async function renderVentoTemplate(template, data, from) {
141
- DEBUG.render("Rendering `%s`", from);
121
+ debugRender("Rendering `%s`", from);
142
122
  const { content } = await template(data);
143
123
  return content;
144
124
  }
145
125
 
146
- // src/index.ts
126
+ // src/utils/compat-check.ts
127
+ var REQUIRED_API_METHODS = [
128
+ ["getShortcodes", "v3.0.0-alpha.15"],
129
+ ["getPairedShortcodes", "v3.0.0-alpha.15"],
130
+ ["getFilters", "v3.0.0-alpha.15"],
131
+ ["addExtension", "v1.0.0"]
132
+ ];
133
+ function compatibilityCheck(config) {
134
+ debugMain("Run compatibility check");
135
+ for (const [method, version] of REQUIRED_API_METHODS) {
136
+ if (!(method in config)) {
137
+ console.error(
138
+ "[eleventy-plugin-vento] Plugin compatibility error:",
139
+ `\`${method}\``,
140
+ "not found. Please use Eleventy",
141
+ version,
142
+ "or later."
143
+ );
144
+ }
145
+ }
146
+ }
147
+
148
+ // src/plugin.ts
147
149
  function VentoPlugin(eleventyConfig, userOptions) {
148
- DEBUG.main("Initializing eleventy-plugin-vento");
149
- runCompatibilityCheck(eleventyConfig);
150
+ debugMain("Initializing eleventy-plugin-vento");
151
+ compatibilityCheck(eleventyConfig);
150
152
  const options = {
151
153
  // Define defaults
152
154
  autotrim: false,
@@ -160,13 +162,13 @@ function VentoPlugin(eleventyConfig, userOptions) {
160
162
  // Merge in user-provided options
161
163
  ...userOptions
162
164
  };
163
- DEBUG.main("Merged default and user config: %O", options);
165
+ debugMain("Merged default and user config: %O", options);
164
166
  const filters = eleventyConfig.getFilters();
165
- DEBUG.main("Reading filters from Eleventy: %o", filters);
167
+ debugMain("Reading filters from Eleventy: %o", filters);
166
168
  const shortcodes = eleventyConfig.getShortcodes();
167
- DEBUG.main("Reading shortcodes from Eleventy: %o", shortcodes);
169
+ debugMain("Reading shortcodes from Eleventy: %o", shortcodes);
168
170
  const pairedShortcodes = eleventyConfig.getPairedShortcodes();
169
- DEBUG.main("Reading paired shortcodes from Eleventy: %o", pairedShortcodes);
171
+ debugMain("Reading paired shortcodes from Eleventy: %o", pairedShortcodes);
170
172
  if (options.autotrim) {
171
173
  const defaults = ["@vento", "@11ty"];
172
174
  const tagSet = new Set(options.autotrim === true ? defaults : options.autotrim);
@@ -182,42 +184,42 @@ function VentoPlugin(eleventyConfig, userOptions) {
182
184
  tagSet.add(name);
183
185
  }
184
186
  }
185
- DEBUG.main("Enabled autotrim for tags: %o", tagSet);
187
+ debugMain("Enabled autotrim for tags: %o", tagSet);
186
188
  options.plugins.push(autotrimPlugin({ tags: [...tagSet] }));
187
189
  }
188
- DEBUG.main("Initializing Vento environment");
190
+ debugMain("Initializing Vento environment");
189
191
  const engine = createVentoEngine(options.ventoOptions);
190
- DEBUG.main("Loading plugins: %o", options.plugins);
192
+ debugMain("Loading plugins: %o", options.plugins);
191
193
  engine.loadPlugins(options.plugins);
192
194
  if (options.filters) {
193
- DEBUG.main("Loading filters: %o", filters);
195
+ debugMain("Loading filters: %o", filters);
194
196
  engine.loadFilters(filters);
195
197
  }
196
198
  if (options.shortcodes) {
197
- DEBUG.main("Loading shortcodes: %o", shortcodes);
199
+ debugMain("Loading shortcodes: %o", shortcodes);
198
200
  engine.loadShortcodes(shortcodes);
199
201
  }
200
202
  if (options.pairedShortcodes) {
201
- DEBUG.main("Loading paired shortcodes: %o", pairedShortcodes);
203
+ debugMain("Loading paired shortcodes: %o", pairedShortcodes);
202
204
  engine.loadPairedShortcodes(pairedShortcodes);
203
205
  }
204
- DEBUG.main("Registering Vento cache handler on eleventy.beforeWatch event");
206
+ debugMain("Registering Vento cache handler on eleventy.beforeWatch event");
205
207
  eleventyConfig.on("eleventy.beforeWatch", async (updatedFiles) => {
206
208
  for (let file of updatedFiles) {
207
209
  file = path.normalize(file);
208
- DEBUG.cache("Delete cache entry for %s", file);
210
+ debugCache("Delete cache entry for %s", file);
209
211
  engine.cache.delete(file);
210
212
  }
211
213
  });
212
- DEBUG.main("Registering .vto as a template format");
214
+ debugMain("Registering .vto as a template format");
213
215
  eleventyConfig.addTemplateFormats("vto");
214
- DEBUG.main("Registering .vto extension with eleventy");
216
+ debugMain("Registering .vto extension with eleventy");
215
217
  eleventyConfig.addExtension("vto", {
216
218
  outputFileExtension: "html",
217
219
  read: true,
218
220
  compile(inputContent, inputPath) {
219
221
  inputPath = path.normalize(inputPath);
220
- DEBUG.main("Getting template function for `%s`", inputPath);
222
+ debugMain("Getting template function for `%s`", inputPath);
221
223
  const template = engine.getTemplateFunction(inputContent, inputPath, false);
222
224
  return async (data) => await renderVentoTemplate(template, data, inputPath);
223
225
  },
@@ -228,13 +230,13 @@ function VentoPlugin(eleventyConfig, userOptions) {
228
230
  return permalinkContent;
229
231
  }
230
232
  inputPath = "Permalink::" + path.normalize(inputPath);
231
- DEBUG.main("Getting template function for `%s`", inputPath);
233
+ debugMain("Getting template function for `%s`", inputPath);
232
234
  const template = engine.getTemplateFunction(permalinkContent, inputPath);
233
235
  return async (data) => await renderVentoTemplate(template, data, inputPath);
234
236
  }
235
237
  }
236
238
  });
237
- DEBUG.main("eleventy-plugin-vento initialized");
239
+ debugMain("eleventy-plugin-vento initialized");
238
240
  }
239
241
  export {
240
242
  VentoPlugin
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "eleventy-plugin-vento",
3
- "version": "4.1.0",
3
+ "version": "4.1.1-beta.0",
4
4
  "description": "Adds support for the Vento templating language to Eleventy.",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": ">=18"
8
8
  },
9
- "types": "./dist/index.d.ts",
9
+ "types": "./dist/plugin.d.ts",
10
10
  "exports": {
11
11
  ".": {
12
- "import": "./dist/index.js",
13
- "types": "./dist/index.d.ts"
12
+ "import": "./dist/plugin.js",
13
+ "types": "./dist/plugin.d.ts"
14
14
  }
15
15
  },
16
16
  "files": [
@@ -36,25 +36,27 @@
36
36
  },
37
37
  "license": "MIT",
38
38
  "dependencies": {
39
- "debug": "4.3.7",
40
- "ventojs": "1.12.12"
39
+ "debug": "4.4.0",
40
+ "ventojs": "1.12.13"
41
41
  },
42
42
  "devDependencies": {
43
43
  "11ty.ts": "0.0.5",
44
44
  "@11ty/eleventy": "3.0.0",
45
45
  "@changesets/cli": "2.27.10",
46
- "@eslint/js": "9.15.0",
46
+ "@eslint/js": "9.16.0",
47
47
  "@types/debug": "4.1.12",
48
48
  "@types/eslint-config-prettier": "6.11.3",
49
49
  "@types/eslint__js": "8.42.3",
50
- "@types/node": "22.9.3",
51
- "eslint": "9.15.0",
50
+ "@types/node": "22.10.1",
51
+ "eslint": "9.16.0",
52
52
  "eslint-config-prettier": "9.1.0",
53
53
  "eslint-plugin-unicorn": "56.0.1",
54
+ "globals": "15.13.0",
54
55
  "tsup": "8.3.5",
56
+ "type-fest": "4.30.0",
55
57
  "typescript": "5.7.2",
56
- "typescript-eslint": "8.15.0",
57
- "vitest": "2.1.5"
58
+ "typescript-eslint": "8.18.0",
59
+ "vitest": "2.1.8"
58
60
  },
59
61
  "prettier": {
60
62
  "bracketSameLine": true,
@@ -64,14 +66,13 @@
64
66
  },
65
67
  "scripts": {
66
68
  "test": "vitest --run",
67
- "check": "pnpm --color run '/ts-check|lint/'",
68
- "lint": "eslint '.'",
69
- "ts-check": "tsc --noEmit",
69
+ "check": "pnpm --color run '/^check:/'",
70
+ "check:lint": "eslint '.'",
71
+ "check:types": "tsc --noEmit",
70
72
  "build": "tsup",
71
73
  "dev": "tsup --watch ./src",
72
74
  "ci:version": "changeset version && pnpm install --no-frozen-lockfile",
73
75
  "ci:publish": "changeset publish",
74
- "ci:generate-changesets": "node ./scripts/generate-changesets.js",
75
76
  "format": "pnpm dlx prettier --config ./package.json --write ."
76
77
  }
77
78
  }
package/readme.md CHANGED
@@ -62,9 +62,6 @@ export default function (eleventyConfig) {
62
62
  // to trim the default tags (see section on Auto-trimming)
63
63
  autotrim: false,
64
64
 
65
- // Enable/disable ignore tag syntax (see section on ignoring tags)
66
- ignoreTag: false,
67
-
68
65
  // A Vento configuration object
69
66
  ventoOptions: {
70
67
  includes: eleventyConfig.directories.includes,
@@ -92,27 +89,9 @@ If you'd prefer to set filters yourself (via a plugin or other method) or preven
92
89
 
93
90
  ### Filters and `this`
94
91
 
95
- This plugin merges the keys normally expected from `this` with the `FilterThis` object Vento provides to filters. The final bound `this` object for filters is as follows:
96
-
97
- ```ts
98
- {
99
- env, // Vento environment
100
- data, // all template global data
101
- page, // this.page
102
- eleventy, // this.eleventy
103
- }
104
- ```
105
-
106
- This feature enables re-use of the Vento environment this plugin provides, within Eleventy filters. As an example use case, you could create a filter that compiles dynamic data and cache it with Vento's own cache:
107
-
108
- ```js
109
- eleventyConfig.addFilter('vento', function (content) {
110
- const res = this.env.runString(content, this.data);
111
- return res.content;
112
- });
113
- ```
92
+ Eleventy provides filters with scoped data via the `this.page` and `this.eleventy` objects (see [Filters#Scoped data in Filters](https://www.11ty.dev/docs/filters/#scoped-data-in-filters) in Eleventy's docs for more details). Likewise, Vento provides filters with `this.env` and `this.data` representing the Vento environment and the current template data. This plugin merges both objects together to make `this.page` (and `eleventy`/`env`/`data`) available on all filters processed by Vento.
114
93
 
115
- Because re-compilation introduces some overhead, you may want to cache your template strings compiled via a filter. With access to `this.env` you can use Vento's own cache:
94
+ This feature enables re-use of the Vento environment this plugin provides, within Eleventy filters. As an example use case, you could create a filter that compiles dynamic data and cache it with Vento's own cache to improve performance:
116
95
 
117
96
  ```js
118
97
  import 'hash' from 'node:crypto'; // since Node v20.12.0
@@ -180,7 +159,8 @@ Eleventy: See [Shortcodes](https://www.11ty.dev/docs/shortcodes/) and the sub-se
180
159
 
181
160
  ## Vento Plugins
182
161
 
183
- _Note: The `auto_trim` plugin that ships with Vento has a specific implementation in the scope of this plugin. See [Auto-Trimming Tags](#auto-trimming-tags) for more details._
162
+ > [!NOTE]
163
+ > The `auto_trim` plugin that ships with Vento has a specific implementation in the scope of this plugin. See [Auto-Trimming Tags](#auto-trimming-tags) for more details.\_
184
164
 
185
165
  If you'd like to extend the Vento library with any plugins, include them in an array passed to the `plugins` option.
186
166