ventojs 2.3.1 → 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 +14 -0
- package/core/environment.js +6 -2
- package/package.json +1 -1
- package/plugins/empty.js +10 -2
- package/types/core/errors.d.ts +3 -3
- package/types/plugins/empty.d.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ 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
|
+
|
|
7
19
|
## [2.3.1] - 2026-02-21
|
|
8
20
|
### Fixed
|
|
9
21
|
- Types for Node [#174]
|
|
@@ -122,7 +134,9 @@ Vento 2.0 is now dependency-free and compatible with browsers without a build st
|
|
|
122
134
|
[#166]: https://github.com/ventojs/vento/issues/166
|
|
123
135
|
[#167]: https://github.com/ventojs/vento/issues/167
|
|
124
136
|
[#174]: https://github.com/ventojs/vento/issues/174
|
|
137
|
+
[#178]: https://github.com/ventojs/vento/issues/178
|
|
125
138
|
|
|
139
|
+
[2.4.0]: https://github.com/ventojs/vento/compare/v2.3.1...v2.4.0
|
|
126
140
|
[2.3.1]: https://github.com/ventojs/vento/compare/v2.3.0...v2.3.1
|
|
127
141
|
[2.3.0]: https://github.com/ventojs/vento/compare/v2.2.0...v2.3.0
|
|
128
142
|
[2.2.0]: https://github.com/ventojs/vento/compare/v2.1.1...v2.2.0
|
package/core/environment.js
CHANGED
|
@@ -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) {
|
package/package.json
CHANGED
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
|
|
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
|
+
}
|
package/types/core/errors.d.ts
CHANGED
|
@@ -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/plugins/empty.d.ts
CHANGED