ventojs 2.3.0 → 2.4.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
@@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
+ ## [2.4.0] - 2026-07-09
8
+ ### Added
9
+ - Support for negative filters [#178].
10
+ Example: `{{ value |> !empty }}`
11
+
12
+ ### Changed
13
+ - `empty` filter returns true for empty objects.
14
+ Example: `{{ {} |> empty }}` returns `true`.
15
+
16
+ ### Fixed
17
+ - Updated benchmarks libraries and added `@11ty/nunjucks`.
18
+
19
+ ## [2.3.1] - 2026-02-21
20
+ ### Fixed
21
+ - Types for Node [#174]
22
+ - `FileSystemDirectoryHandle` types in Deno.
23
+ - Added `strict` option to browser version.
24
+
7
25
  ## [2.3.0] - 2025-12-25
8
26
  ### Added
9
27
  - New `default` tag to assign fallback content to a variable [#164], [#166].
@@ -115,7 +133,11 @@ Vento 2.0 is now dependency-free and compatible with browsers without a build st
115
133
  [#164]: https://github.com/ventojs/vento/issues/164
116
134
  [#166]: https://github.com/ventojs/vento/issues/166
117
135
  [#167]: https://github.com/ventojs/vento/issues/167
136
+ [#174]: https://github.com/ventojs/vento/issues/174
137
+ [#178]: https://github.com/ventojs/vento/issues/178
118
138
 
139
+ [2.4.0]: https://github.com/ventojs/vento/compare/v2.3.1...v2.4.0
140
+ [2.3.1]: https://github.com/ventojs/vento/compare/v2.3.0...v2.3.1
119
141
  [2.3.0]: https://github.com/ventojs/vento/compare/v2.2.0...v2.3.0
120
142
  [2.2.0]: https://github.com/ventojs/vento/compare/v2.1.1...v2.2.0
121
143
  [2.1.1]: https://github.com/ventojs/vento/compare/v2.1.0...v2.1.1
@@ -207,11 +207,11 @@ export class Environment {
207
207
  while (tokens.length > 0 && tokens[0][0] === "filter") {
208
208
  const token = tokens.shift();
209
209
  const [, code, position] = token;
210
- const match = code.match(/^(await\s+)?([\w.]+)(?:\((.*)\))?$/);
210
+ const match = code.match(/^(!)?(await\s+)?([\w.]+)(?:\((.*)\))?$/);
211
211
  if (!match) {
212
212
  throw new SourceError(`Invalid filter: ${code}`, position);
213
213
  }
214
- const [_, isAsync, name, args] = match;
214
+ const [_, isNegative, isAsync, name, args] = match;
215
215
  if (!Object.hasOwn(this.filters, name)) {
216
216
  if (name === "safe") {
217
217
  unescaped = true;
@@ -230,6 +230,10 @@ export class Environment {
230
230
  const { dataVarname } = this.options;
231
231
  output = `${(isAsync || checkAsync(this.filters[name])) ? "await " : ""}__env.filters.${name}.call({data:${dataVarname},env:__env}, ${output}${args ? `, ${args}` : ""})`;
232
232
  }
233
+ // Is negative
234
+ if (isNegative) {
235
+ output = `!${output}`;
236
+ }
233
237
  }
234
238
  // Escape by default
235
239
  if (autoescape && !unescaped) {
@@ -1,3 +1,4 @@
1
+ /// <reference lib="dom" />
1
2
  import { join } from "./utils.js";
2
3
  /**
3
4
  * Vento FileSystem API loader for loading templates.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ventojs",
3
- "version": "2.3.0",
3
+ "version": "2.4.0",
4
4
  "description": "🌬 A minimal but powerful template engine",
5
5
  "type": "module",
6
6
  "repository": {
package/plugins/empty.js CHANGED
@@ -5,13 +5,21 @@ export default function () {
5
5
  if (!value)
6
6
  return true;
7
7
  if (typeof value == "string" || value instanceof SafeString) {
8
- return value.toString().trim() == "";
8
+ return value.toString().trim() === "";
9
9
  }
10
10
  if (typeof value != "object")
11
11
  return false;
12
12
  if (Array.isArray(value))
13
- return value.length == 0;
13
+ return value.length === 0;
14
+ if (isPlainObject(value))
15
+ return Object.keys(value).length === 0;
14
16
  return false;
15
17
  };
16
18
  };
17
19
  }
20
+ const objectConstructor = {}.constructor;
21
+ /** Check if the argument passed is a plain object */
22
+ export function isPlainObject(obj) {
23
+ return typeof obj === "object" && obj !== null &&
24
+ (obj.constructor === objectConstructor || obj.constructor === undefined);
25
+ }
@@ -1,4 +1,4 @@
1
- import { Token } from "./tokenizer.d.ts";
1
+ import type { Token } from "./tokenizer.d.ts";
2
2
  export interface TemplateResult {
3
3
  content: string;
4
4
  [key: string]: unknown;
@@ -20,9 +20,9 @@ export declare class SourceError extends VentoError {
20
20
  getContext(): {
21
21
  type: string;
22
22
  message: string;
23
- position: number;
24
- file: string;
25
- source: string;
23
+ position: number | undefined;
24
+ file: string | undefined;
25
+ source: string | undefined;
26
26
  };
27
27
  }
28
28
  export declare class RuntimeError extends VentoError {
package/types/mod.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Environment, type Loader } from "./core/environment.d.ts";
1
+ import type { Environment, Loader } from "./core/environment.d.ts";
2
2
  export interface Options {
3
3
  includes?: string | Loader;
4
4
  autoDataVarname?: boolean;
@@ -1,2 +1,4 @@
1
1
  import type { Plugin } from "../core/environment.d.ts";
2
2
  export default function (): Plugin;
3
+ /** Check if the argument passed is a plain object */
4
+ export declare function isPlainObject(obj: unknown): obj is Record<string, unknown>;
package/types/web.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { Environment, type Loader } from "./core/environment.d.ts";
1
+ import type { Environment, Loader } from "./core/environment.d.ts";
2
2
  export interface Options {
3
3
  includes: URL | Loader;
4
4
  autoDataVarname?: boolean;
5
5
  dataVarname?: string;
6
6
  autoescape?: boolean;
7
+ strict?: boolean;
7
8
  }
8
9
  export default function (options: Options): Environment;
package/web.js CHANGED
@@ -12,6 +12,7 @@ export default function (options) {
12
12
  dataVarname: options.dataVarname || "it",
13
13
  autoescape: options.autoescape ?? false,
14
14
  autoDataVarname: options.autoDataVarname ?? true,
15
+ strict: options.strict ?? false,
15
16
  });
16
17
  // Register the default plugins
17
18
  env.use(defaultPlugins());