ventojs 0.8.0 → 0.9.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/README.md +7 -61
- package/esm/deps/deno.land/std@0.201.0/html/entities.d.ts +38 -0
- package/esm/deps/deno.land/std@0.201.0/html/entities.js +76 -0
- package/esm/deps/deno.land/std@0.201.0/html/mod.d.ts +6 -0
- package/esm/deps/deno.land/std@0.201.0/html/mod.js +8 -0
- package/esm/deps.d.ts +1 -0
- package/esm/deps.js +1 -0
- package/esm/mod.d.ts +1 -0
- package/esm/mod.js +1 -0
- package/esm/plugins/escape.js +2 -12
- package/esm/plugins/export.js +5 -4
- package/esm/plugins/import.js +4 -11
- package/esm/plugins/include.js +3 -2
- package/esm/plugins/layout.js +4 -3
- package/esm/plugins/set.js +5 -4
- package/esm/plugins/unescape.js +2 -12
- package/esm/src/environment.d.ts +1 -0
- package/esm/src/environment.js +9 -12
- package/package.json +4 -2
- package/script/_dnt.shims.d.ts +5 -0
- package/script/_dnt.shims.js +65 -0
- package/script/deps/deno.land/std@0.201.0/assert/assert.d.ts +2 -0
- package/script/deps/deno.land/std@0.201.0/assert/assert.js +12 -0
- package/script/deps/deno.land/std@0.201.0/assert/assertion_error.d.ts +4 -0
- package/script/deps/deno.land/std@0.201.0/assert/assertion_error.js +11 -0
- package/script/deps/deno.land/std@0.201.0/html/entities.d.ts +38 -0
- package/script/deps/deno.land/std@0.201.0/html/entities.js +81 -0
- package/script/deps/deno.land/std@0.201.0/html/mod.d.ts +6 -0
- package/script/deps/deno.land/std@0.201.0/html/mod.js +24 -0
- package/script/deps/deno.land/std@0.201.0/path/_basename.d.ts +16 -0
- package/script/deps/deno.land/std@0.201.0/path/_basename.js +83 -0
- package/script/deps/deno.land/std@0.201.0/path/_constants.d.ts +39 -0
- package/script/deps/deno.land/std@0.201.0/path/_constants.js +49 -0
- package/script/deps/deno.land/std@0.201.0/path/_dirname.d.ts +10 -0
- package/script/deps/deno.land/std@0.201.0/path/_dirname.js +137 -0
- package/script/deps/deno.land/std@0.201.0/path/_extname.d.ts +12 -0
- package/script/deps/deno.land/std@0.201.0/path/_extname.js +126 -0
- package/script/deps/deno.land/std@0.201.0/path/_format.d.ts +11 -0
- package/script/deps/deno.land/std@0.201.0/path/_format.js +40 -0
- package/script/deps/deno.land/std@0.201.0/path/_from_file_url.d.ts +25 -0
- package/script/deps/deno.land/std@0.201.0/path/_from_file_url.js +51 -0
- package/script/deps/deno.land/std@0.201.0/path/_interface.d.ts +26 -0
- package/script/deps/deno.land/std@0.201.0/path/_interface.js +4 -0
- package/script/deps/deno.land/std@0.201.0/path/_is_absolute.d.ts +10 -0
- package/script/deps/deno.land/std@0.201.0/path/_is_absolute.js +39 -0
- package/script/deps/deno.land/std@0.201.0/path/_join.d.ts +10 -0
- package/script/deps/deno.land/std@0.201.0/path/_join.js +98 -0
- package/script/deps/deno.land/std@0.201.0/path/_normalize.d.ts +14 -0
- package/script/deps/deno.land/std@0.201.0/path/_normalize.js +158 -0
- package/script/deps/deno.land/std@0.201.0/path/_os.d.ts +4 -0
- package/script/deps/deno.land/std@0.201.0/path/_os.js +44 -0
- package/script/deps/deno.land/std@0.201.0/path/_parse.d.ts +11 -0
- package/script/deps/deno.land/std@0.201.0/path/_parse.js +255 -0
- package/script/deps/deno.land/std@0.201.0/path/_relative.d.ts +19 -0
- package/script/deps/deno.land/std@0.201.0/path/_relative.js +221 -0
- package/script/deps/deno.land/std@0.201.0/path/_resolve.d.ts +10 -0
- package/script/deps/deno.land/std@0.201.0/path/_resolve.js +211 -0
- package/script/deps/deno.land/std@0.201.0/path/_to_file_url.d.ts +25 -0
- package/script/deps/deno.land/std@0.201.0/path/_to_file_url.js +66 -0
- package/script/deps/deno.land/std@0.201.0/path/_to_namespaced_path.d.ts +10 -0
- package/script/deps/deno.land/std@0.201.0/path/_to_namespaced_path.js +51 -0
- package/script/deps/deno.land/std@0.201.0/path/_util.d.ts +6 -0
- package/script/deps/deno.land/std@0.201.0/path/_util.js +116 -0
- package/script/deps/deno.land/std@0.201.0/path/basename.d.ts +8 -0
- package/script/deps/deno.land/std@0.201.0/path/basename.js +20 -0
- package/script/deps/deno.land/std@0.201.0/path/common.d.ts +13 -0
- package/script/deps/deno.land/std@0.201.0/path/common.js +40 -0
- package/script/deps/deno.land/std@0.201.0/path/dirname.d.ts +5 -0
- package/script/deps/deno.land/std@0.201.0/path/dirname.js +15 -0
- package/script/deps/deno.land/std@0.201.0/path/extname.d.ts +6 -0
- package/script/deps/deno.land/std@0.201.0/path/extname.js +16 -0
- package/script/deps/deno.land/std@0.201.0/path/format.d.ts +6 -0
- package/script/deps/deno.land/std@0.201.0/path/format.js +15 -0
- package/script/deps/deno.land/std@0.201.0/path/from_file_url.d.ts +18 -0
- package/script/deps/deno.land/std@0.201.0/path/from_file_url.js +27 -0
- package/script/deps/deno.land/std@0.201.0/path/glob.d.ts +83 -0
- package/script/deps/deno.land/std@0.201.0/path/glob.js +391 -0
- package/script/deps/deno.land/std@0.201.0/path/is_absolute.d.ts +5 -0
- package/script/deps/deno.land/std@0.201.0/path/is_absolute.js +15 -0
- package/script/deps/deno.land/std@0.201.0/path/join.d.ts +5 -0
- package/script/deps/deno.land/std@0.201.0/path/join.js +15 -0
- package/script/deps/deno.land/std@0.201.0/path/mod.d.ts +22 -0
- package/script/deps/deno.land/std@0.201.0/path/mod.js +74 -0
- package/script/deps/deno.land/std@0.201.0/path/normalize.d.ts +7 -0
- package/script/deps/deno.land/std@0.201.0/path/normalize.js +17 -0
- package/script/deps/deno.land/std@0.201.0/path/parse.d.ts +6 -0
- package/script/deps/deno.land/std@0.201.0/path/parse.js +15 -0
- package/script/deps/deno.land/std@0.201.0/path/posix.d.ts +15 -0
- package/script/deps/deno.land/std@0.201.0/path/posix.js +35 -0
- package/script/deps/deno.land/std@0.201.0/path/relative.d.ts +12 -0
- package/script/deps/deno.land/std@0.201.0/path/relative.js +22 -0
- package/script/deps/deno.land/std@0.201.0/path/resolve.d.ts +5 -0
- package/script/deps/deno.land/std@0.201.0/path/resolve.js +17 -0
- package/script/deps/deno.land/std@0.201.0/path/separator.d.ts +2 -0
- package/script/deps/deno.land/std@0.201.0/path/separator.js +8 -0
- package/script/deps/deno.land/std@0.201.0/path/to_file_url.d.ts +18 -0
- package/script/deps/deno.land/std@0.201.0/path/to_file_url.js +27 -0
- package/script/deps/deno.land/std@0.201.0/path/to_namespaced_path.d.ts +5 -0
- package/script/deps/deno.land/std@0.201.0/path/to_namespaced_path.js +17 -0
- package/script/deps/deno.land/std@0.201.0/path/win32.d.ts +15 -0
- package/script/deps/deno.land/std@0.201.0/path/win32.js +35 -0
- package/script/deps.d.ts +2 -0
- package/script/deps.js +28 -0
- package/script/mod.d.ts +9 -0
- package/script/mod.js +69 -0
- package/script/package.json +3 -0
- package/script/plugins/echo.d.ts +2 -0
- package/script/plugins/echo.js +16 -0
- package/script/plugins/escape.d.ts +2 -0
- package/script/plugins/escape.js +9 -0
- package/script/plugins/export.d.ts +2 -0
- package/script/plugins/export.js +50 -0
- package/script/plugins/for.d.ts +2 -0
- package/script/plugins/for.js +51 -0
- package/script/plugins/function.d.ts +2 -0
- package/script/plugins/function.js +40 -0
- package/script/plugins/if.d.ts +2 -0
- package/script/plugins/if.js +35 -0
- package/script/plugins/import.d.ts +2 -0
- package/script/plugins/import.js +20 -0
- package/script/plugins/include.d.ts +2 -0
- package/script/plugins/include.js +26 -0
- package/script/plugins/js.d.ts +2 -0
- package/script/plugins/js.js +14 -0
- package/script/plugins/layout.d.ts +2 -0
- package/script/plugins/layout.js +37 -0
- package/script/plugins/set.d.ts +2 -0
- package/script/plugins/set.js +48 -0
- package/script/plugins/unescape.d.ts +2 -0
- package/script/plugins/unescape.js +9 -0
- package/script/src/environment.d.ts +42 -0
- package/script/src/environment.js +176 -0
- package/script/src/loader.d.ts +14 -0
- package/script/src/loader.js +46 -0
- package/script/src/tokenizer.d.ts +8 -0
- package/script/src/tokenizer.js +190 -0
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Vento
|
|
2
2
|
|
|
3
3
|
This is a minimal template engine inspired by other great engines like Nunjucks,
|
|
4
|
-
Liquid, Mustache
|
|
4
|
+
Liquid, Mustache, and EJS.
|
|
5
5
|
|
|
6
6
|
## Why another template engine?
|
|
7
7
|
|
|
@@ -32,6 +32,7 @@ neither is). The issues I found in existing template engines:
|
|
|
32
32
|
### Liquid
|
|
33
33
|
|
|
34
34
|
- I like:
|
|
35
|
+
|
|
35
36
|
- The support for async evaluation is less hacky than Nunjucks.
|
|
36
37
|
- The variables are not escaped by default, there's an `escape` filter for
|
|
37
38
|
that.
|
|
@@ -91,64 +92,9 @@ First, let's take a look at this syntax example:
|
|
|
91
92
|
|
|
92
93
|
## Getting started
|
|
93
94
|
|
|
94
|
-
|
|
95
|
-
future.~~
|
|
96
|
-
[There's already an NPM version](https://www.npmjs.com/package/ventojs) that you
|
|
97
|
-
can install with `npm install ventojs`.
|
|
98
|
-
|
|
99
|
-
Import the library and create an instance:
|
|
100
|
-
|
|
101
|
-
```ts
|
|
102
|
-
import vento from "https://deno.land/x/vento/mod.ts";
|
|
103
|
-
|
|
104
|
-
const vto = vento({
|
|
105
|
-
// Resolve the non-relative includes paths
|
|
106
|
-
includes: "./path/to/includes",
|
|
107
|
-
});
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Or in Node:
|
|
111
|
-
|
|
112
|
-
```ts
|
|
113
|
-
import vento from "ventojs";
|
|
114
|
-
|
|
115
|
-
const vto = vento({
|
|
116
|
-
// Resolve the non-relative includes paths
|
|
117
|
-
includes: "./path/to/includes",
|
|
118
|
-
});
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
There are different ways to load, compile and run a template. For example, you
|
|
122
|
-
can use `load` to load and compile a template file and return it.
|
|
123
|
-
|
|
124
|
-
```ts
|
|
125
|
-
// Load and return a template
|
|
126
|
-
const template = vto.load("my-template.vto");
|
|
127
|
-
|
|
128
|
-
// Now you can use it passing the data
|
|
129
|
-
const result = template({ title: "Hello world" });
|
|
130
|
-
console.log(result.content);
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
Alternatively, you can load and run the template file in a single call:
|
|
134
|
-
|
|
135
|
-
```ts
|
|
136
|
-
const result = vto.run("my-template.vto", { title: "Hello world" });
|
|
137
|
-
console.log(result.content);
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
If the template code is not a file, you can run it directly:
|
|
141
|
-
|
|
142
|
-
```ts
|
|
143
|
-
const result = vto.runString("<h1>{{ title }}</h1>", { title: "Hello world" });
|
|
144
|
-
console.log(result.content);
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## Visual Studio Code Support
|
|
148
|
-
|
|
149
|
-
[The Vento extension for VS Code](https://marketplace.visualstudio.com/items?itemName=oscarotero.vento-syntax)
|
|
150
|
-
enables syntax highlight and provides some useful snippets.
|
|
95
|
+
See [Getting started](https://vento.js.org/getting-started/) on the docs.
|
|
151
96
|
|
|
152
|
-
##
|
|
97
|
+
## Editor support
|
|
153
98
|
|
|
154
|
-
[
|
|
99
|
+
See [Editor integrations](https://vento.js.org/editor-integrations/) on the
|
|
100
|
+
docs.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export type EntityList = Record<string, string>;
|
|
2
|
+
/**
|
|
3
|
+
* Escapes text for safe interpolation into HTML text content and quoted attributes
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { escape } from "https://deno.land/std@$STD_VERSION/html/entities.ts";
|
|
8
|
+
* import { assertEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_equals.ts";
|
|
9
|
+
*
|
|
10
|
+
* assertEquals(escape("<>'&AA"), "<>'&AA");
|
|
11
|
+
*
|
|
12
|
+
* // characters that don't need to be escaped will be left alone,
|
|
13
|
+
* // even if named HTML entities exist for them
|
|
14
|
+
* assertEquals(escape("þð"), "þð");
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function escape(str: string): string;
|
|
18
|
+
export type UnescapeOptions = {
|
|
19
|
+
entityList: EntityList;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Unescapes HTML entities in text
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { unescape } from "https://deno.land/std@$STD_VERSION/html/entities.ts";
|
|
27
|
+
* import { assertEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_equals.ts";
|
|
28
|
+
*
|
|
29
|
+
* // default options (only handles &<>'" and numeric entities)
|
|
30
|
+
* assertEquals(unescape("<>'&AA"), "<>'&AA");
|
|
31
|
+
* assertEquals(unescape("þð"), "þð");
|
|
32
|
+
*
|
|
33
|
+
* // using the full named entity list from the HTML spec (~47K unminified)
|
|
34
|
+
* import entityList from "https://deno.land/std@$STD_VERSION/html/named_entity_list.json" assert { type: "json" };
|
|
35
|
+
* assertEquals(unescape("þð", { entityList }), "þð");
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function unescape(str: string, options?: Partial<UnescapeOptions>): string;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
const rawToEntityEntries = [
|
|
4
|
+
["&", "&"],
|
|
5
|
+
["<", "<"],
|
|
6
|
+
[">", ">"],
|
|
7
|
+
['"', """],
|
|
8
|
+
["'", "'"],
|
|
9
|
+
];
|
|
10
|
+
const defaultEntityList = Object.fromEntries([
|
|
11
|
+
...rawToEntityEntries.map(([raw, entity]) => [entity, raw]),
|
|
12
|
+
["'", "'"],
|
|
13
|
+
[" ", "\xa0"],
|
|
14
|
+
]);
|
|
15
|
+
const rawToEntity = new Map(rawToEntityEntries);
|
|
16
|
+
const rawRe = new RegExp(`[${[...rawToEntity.keys()].join("")}]`, "g");
|
|
17
|
+
/**
|
|
18
|
+
* Escapes text for safe interpolation into HTML text content and quoted attributes
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { escape } from "https://deno.land/std@$STD_VERSION/html/entities.ts";
|
|
23
|
+
* import { assertEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_equals.ts";
|
|
24
|
+
*
|
|
25
|
+
* assertEquals(escape("<>'&AA"), "<>'&AA");
|
|
26
|
+
*
|
|
27
|
+
* // characters that don't need to be escaped will be left alone,
|
|
28
|
+
* // even if named HTML entities exist for them
|
|
29
|
+
* assertEquals(escape("þð"), "þð");
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function escape(str) {
|
|
33
|
+
return str.replaceAll(rawRe, (m) => rawToEntity.get(m));
|
|
34
|
+
}
|
|
35
|
+
const defaultUnescapeOptions = {
|
|
36
|
+
entityList: defaultEntityList,
|
|
37
|
+
};
|
|
38
|
+
const MAX_CODE_POINT = 0x10ffff;
|
|
39
|
+
const RX_DEC_ENTITY = /&#([0-9]+);/g;
|
|
40
|
+
const RX_HEX_ENTITY = /&#x(\p{AHex}+);/gu;
|
|
41
|
+
const entityListRegexCache = new WeakMap();
|
|
42
|
+
/**
|
|
43
|
+
* Unescapes HTML entities in text
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* import { unescape } from "https://deno.land/std@$STD_VERSION/html/entities.ts";
|
|
48
|
+
* import { assertEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_equals.ts";
|
|
49
|
+
*
|
|
50
|
+
* // default options (only handles &<>'" and numeric entities)
|
|
51
|
+
* assertEquals(unescape("<>'&AA"), "<>'&AA");
|
|
52
|
+
* assertEquals(unescape("þð"), "þð");
|
|
53
|
+
*
|
|
54
|
+
* // using the full named entity list from the HTML spec (~47K unminified)
|
|
55
|
+
* import entityList from "https://deno.land/std@$STD_VERSION/html/named_entity_list.json" assert { type: "json" };
|
|
56
|
+
* assertEquals(unescape("þð", { entityList }), "þð");
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export function unescape(str, options = {}) {
|
|
60
|
+
const { entityList } = { ...defaultUnescapeOptions, ...options };
|
|
61
|
+
let entityRe = entityListRegexCache.get(entityList);
|
|
62
|
+
if (!entityRe) {
|
|
63
|
+
entityRe = new RegExp(`(${Object.keys(entityList)
|
|
64
|
+
.sort((a, b) => b.length - a.length)
|
|
65
|
+
.join("|")})`, "g");
|
|
66
|
+
entityListRegexCache.set(entityList, entityRe);
|
|
67
|
+
}
|
|
68
|
+
return str
|
|
69
|
+
.replaceAll(entityRe, (m) => entityList[m])
|
|
70
|
+
.replaceAll(RX_DEC_ENTITY, (_, dec) => codePointStrToChar(dec, 10))
|
|
71
|
+
.replaceAll(RX_HEX_ENTITY, (_, hex) => codePointStrToChar(hex, 16));
|
|
72
|
+
}
|
|
73
|
+
function codePointStrToChar(codePointStr, radix) {
|
|
74
|
+
const codePoint = parseInt(codePointStr, radix);
|
|
75
|
+
return codePoint > MAX_CODE_POINT ? "�" : String.fromCodePoint(codePoint);
|
|
76
|
+
}
|
package/esm/deps.d.ts
CHANGED
package/esm/deps.js
CHANGED
package/esm/mod.d.ts
CHANGED
package/esm/mod.js
CHANGED
package/esm/plugins/escape.js
CHANGED
|
@@ -1,16 +1,6 @@
|
|
|
1
|
+
import { html } from "../deps.js";
|
|
1
2
|
export default function () {
|
|
2
3
|
return (env) => {
|
|
3
|
-
env.filters.escape = escape;
|
|
4
|
+
env.filters.escape = html.escape;
|
|
4
5
|
};
|
|
5
6
|
}
|
|
6
|
-
const escapeMap = {
|
|
7
|
-
"&": "&",
|
|
8
|
-
"<": "<",
|
|
9
|
-
">": ">",
|
|
10
|
-
'"': """,
|
|
11
|
-
"'": "'",
|
|
12
|
-
"`": "`",
|
|
13
|
-
};
|
|
14
|
-
function escape(str) {
|
|
15
|
-
return str.replace(/[&<>"'`]/g, (match) => escapeMap[match]);
|
|
16
|
-
}
|
package/esm/plugins/export.js
CHANGED
|
@@ -8,6 +8,7 @@ function exportTag(env, code, _output, tokens) {
|
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
10
10
|
const expression = code.replace(/^export\s+/, "");
|
|
11
|
+
const { dataVarname } = env.options;
|
|
11
12
|
// Value is set (e.g. {{ export foo = "bar" }})
|
|
12
13
|
if (expression.includes("=")) {
|
|
13
14
|
const match = code.match(/^export\s+([\w]+)\s*=\s*([\s\S]+)$/);
|
|
@@ -16,19 +17,19 @@ function exportTag(env, code, _output, tokens) {
|
|
|
16
17
|
}
|
|
17
18
|
const [, variable, value] = match;
|
|
18
19
|
const val = env.compileFilters(tokens, value);
|
|
19
|
-
return `if (
|
|
20
|
+
return `if (${dataVarname}.hasOwnProperty("${variable}")) {
|
|
20
21
|
${variable} = ${val};
|
|
21
22
|
} else {
|
|
22
23
|
var ${variable} = ${val};
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
+
${dataVarname}["${variable}"] = ${variable};
|
|
25
26
|
__exports["${variable}"] = ${variable};
|
|
26
27
|
`;
|
|
27
28
|
}
|
|
28
29
|
// Value is captured (eg: {{ export foo }}bar{{ /export }})
|
|
29
30
|
const compiled = [];
|
|
30
31
|
const compiledFilters = env.compileFilters(tokens, expression);
|
|
31
|
-
compiled.push(`if (
|
|
32
|
+
compiled.push(`if (${dataVarname}.hasOwnProperty("${expression}")) {
|
|
32
33
|
${expression} = "";
|
|
33
34
|
} else {
|
|
34
35
|
var ${expression} = "";
|
|
@@ -40,7 +41,7 @@ function exportTag(env, code, _output, tokens) {
|
|
|
40
41
|
}
|
|
41
42
|
tokens.shift();
|
|
42
43
|
compiled.push(`${expression} = ${compiledFilters};`);
|
|
43
|
-
compiled.push(
|
|
44
|
+
compiled.push(`${dataVarname}["${expression.trim()}"] = ${expression};`);
|
|
44
45
|
compiled.push(`__exports["${expression.trim()}"] = ${expression};`);
|
|
45
46
|
return compiled.join("\n");
|
|
46
47
|
}
|
package/esm/plugins/import.js
CHANGED
|
@@ -3,7 +3,7 @@ export default function () {
|
|
|
3
3
|
env.tags.push(importTag);
|
|
4
4
|
};
|
|
5
5
|
}
|
|
6
|
-
function importTag(
|
|
6
|
+
function importTag(env, code) {
|
|
7
7
|
if (!code.startsWith("import ")) {
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
@@ -11,14 +11,7 @@ function importTag(_env, code) {
|
|
|
11
11
|
if (!match) {
|
|
12
12
|
throw new Error(`Invalid import: ${code}`);
|
|
13
13
|
}
|
|
14
|
-
const [
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
if (vars.startsWith("{")) {
|
|
18
|
-
compiled.push(`let ${vars} = __tmp;`);
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
compiled.push(`let ${vars} = __tmp;`);
|
|
22
|
-
}
|
|
23
|
-
return compiled.join("\n");
|
|
14
|
+
const [, vars, file] = match;
|
|
15
|
+
const { dataVarname } = env.options;
|
|
16
|
+
return `let ${vars} = await __env.run(${file}, {...${dataVarname}}, __file);`;
|
|
24
17
|
}
|
package/esm/plugins/include.js
CHANGED
|
@@ -12,9 +12,10 @@ function includeTag(env, code, output, tokens) {
|
|
|
12
12
|
throw new Error(`Invalid include: ${code}`);
|
|
13
13
|
}
|
|
14
14
|
const [_, file, data] = match;
|
|
15
|
+
const { dataVarname } = env.options;
|
|
15
16
|
return `{
|
|
16
|
-
__tmp = await __env.run(${file},
|
|
17
|
-
{
|
|
17
|
+
const __tmp = await __env.run(${file},
|
|
18
|
+
{...${dataVarname}${data ? `, ${data}` : ""}},
|
|
18
19
|
__file
|
|
19
20
|
);
|
|
20
21
|
${output} += ${env.compileFilters(tokens, "__tmp.content")};
|
package/esm/plugins/layout.js
CHANGED
|
@@ -16,15 +16,16 @@ function layoutTag(env, code, output, tokens) {
|
|
|
16
16
|
const compiled = [];
|
|
17
17
|
const compiledFilters = env.compileFilters(tokens, varname);
|
|
18
18
|
compiled.push("{");
|
|
19
|
-
compiled.push(`
|
|
19
|
+
compiled.push(`let ${varname} = "";`);
|
|
20
20
|
compiled.push(...env.compileTokens(tokens, varname, ["/layout"]));
|
|
21
21
|
if (tokens.length && (tokens[0][0] !== "tag" || tokens[0][1] !== "/layout")) {
|
|
22
22
|
throw new Error(`Missing closing tag for layout tag: ${code}`);
|
|
23
23
|
}
|
|
24
24
|
tokens.shift();
|
|
25
25
|
compiled.push(`${varname} = ${compiledFilters};`);
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
const { dataVarname } = env.options;
|
|
27
|
+
compiled.push(`const __tmp = await __env.run(${file},
|
|
28
|
+
{...${dataVarname}${data ? `, ${data}` : ""}, content: ${env.compileFilters(tokens, varname)}},
|
|
28
29
|
__file
|
|
29
30
|
);
|
|
30
31
|
${output} += __tmp.content;`);
|
package/esm/plugins/set.js
CHANGED
|
@@ -8,6 +8,7 @@ function setTag(env, code, _output, tokens) {
|
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
10
10
|
const expression = code.replace(/^set\s+/, "");
|
|
11
|
+
const { dataVarname } = env.options;
|
|
11
12
|
// Value is set (e.g. {{ set foo = "bar" }})
|
|
12
13
|
if (expression.includes("=")) {
|
|
13
14
|
const match = code.match(/^set\s+([\w]+)\s*=\s*([\s\S]+)$/);
|
|
@@ -16,18 +17,18 @@ function setTag(env, code, _output, tokens) {
|
|
|
16
17
|
}
|
|
17
18
|
const [, variable, value] = match;
|
|
18
19
|
const val = env.compileFilters(tokens, value);
|
|
19
|
-
return `if (
|
|
20
|
+
return `if (${dataVarname}.hasOwnProperty("${variable}")) {
|
|
20
21
|
${variable} = ${val};
|
|
21
22
|
} else {
|
|
22
23
|
var ${variable} = ${val};
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
+
${dataVarname}["${variable}"] = ${variable};
|
|
25
26
|
`;
|
|
26
27
|
}
|
|
27
28
|
// Value is captured (eg: {{ set foo }}bar{{ /set }})
|
|
28
29
|
const compiled = [];
|
|
29
30
|
const compiledFilters = env.compileFilters(tokens, expression);
|
|
30
|
-
compiled.push(`if (
|
|
31
|
+
compiled.push(`if (${dataVarname}.hasOwnProperty("${expression}")) {
|
|
31
32
|
${expression} = "";
|
|
32
33
|
} else {
|
|
33
34
|
var ${expression} = "";
|
|
@@ -39,6 +40,6 @@ function setTag(env, code, _output, tokens) {
|
|
|
39
40
|
}
|
|
40
41
|
tokens.shift();
|
|
41
42
|
compiled.push(`${expression} = ${compiledFilters};`);
|
|
42
|
-
compiled.push(
|
|
43
|
+
compiled.push(`${dataVarname}["${expression.trim()}"] = ${expression};`);
|
|
43
44
|
return compiled.join("\n");
|
|
44
45
|
}
|
package/esm/plugins/unescape.js
CHANGED
|
@@ -1,16 +1,6 @@
|
|
|
1
|
+
import { html } from "../deps.js";
|
|
1
2
|
export default function () {
|
|
2
3
|
return (env) => {
|
|
3
|
-
env.filters.unescape = unescape;
|
|
4
|
+
env.filters.unescape = html.unescape;
|
|
4
5
|
};
|
|
5
6
|
}
|
|
6
|
-
const unescapeMap = {
|
|
7
|
-
"&": "&",
|
|
8
|
-
"<": "<",
|
|
9
|
-
">": ">",
|
|
10
|
-
""": '"',
|
|
11
|
-
"'": "'",
|
|
12
|
-
"`": "`",
|
|
13
|
-
};
|
|
14
|
-
function unescape(str) {
|
|
15
|
-
return str.replace(/(&|<|>|"|'|`)/g, (match) => unescapeMap[match]);
|
|
16
|
-
}
|
package/esm/src/environment.d.ts
CHANGED
package/esm/src/environment.js
CHANGED
|
@@ -37,15 +37,12 @@ export class Environment {
|
|
|
37
37
|
try {
|
|
38
38
|
const tokens = tokenize(source);
|
|
39
39
|
const code = this.compileTokens(tokens).join("\n");
|
|
40
|
-
const
|
|
40
|
+
const { dataVarname, useWith } = this.options;
|
|
41
|
+
const constructor = new Function("__file", "__env", "__defaults", `return${sync ? "" : " async"} function (${dataVarname}) {
|
|
41
42
|
try {
|
|
42
|
-
|
|
43
|
-
const ${this.options.dataVarname} = __data;
|
|
44
|
-
let __tmp;
|
|
43
|
+
${dataVarname} = Object.assign({}, __defaults, ${dataVarname});
|
|
45
44
|
const __exports = { content: "" };
|
|
46
|
-
with (
|
|
47
|
-
${code}
|
|
48
|
-
}
|
|
45
|
+
${useWith ? `with (${dataVarname}) {${code}}` : code}
|
|
49
46
|
return __exports;
|
|
50
47
|
} catch (cause) {
|
|
51
48
|
throw new Error(\`Error rendering template: \${__file}\`, { cause });
|
|
@@ -112,8 +109,11 @@ export class Environment {
|
|
|
112
109
|
}
|
|
113
110
|
const [_, isAsync, name, args] = match;
|
|
114
111
|
if (!this.filters[name]) {
|
|
115
|
-
|
|
116
|
-
|
|
112
|
+
if (name === "safe") {
|
|
113
|
+
unescaped = true;
|
|
114
|
+
}
|
|
115
|
+
else if (isGlobal(name)) {
|
|
116
|
+
// If a global function
|
|
117
117
|
output = `${isAsync ? "await " : ""}${name}(${output}${args ? `, ${args}` : ""})`;
|
|
118
118
|
}
|
|
119
119
|
else {
|
|
@@ -122,9 +122,6 @@ export class Environment {
|
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
else {
|
|
125
|
-
if (name === "unescape") {
|
|
126
|
-
unescaped = true;
|
|
127
|
-
}
|
|
128
125
|
// It's a filter (e.g. filters.upper())
|
|
129
126
|
output = `${isAsync ? "await " : ""}__env.filters.${name}(${output}${args ? `, ${args}` : ""})`;
|
|
130
127
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"module": "./esm/mod.js",
|
|
3
|
+
"main": "./script/mod.js",
|
|
3
4
|
"name": "ventojs",
|
|
4
|
-
"version": "0.
|
|
5
|
+
"version": "0.9.0",
|
|
5
6
|
"description": "🌬 A minimal but powerful template engine",
|
|
6
7
|
"license": "MIT",
|
|
7
8
|
"repository": "github:oscarotero/vento",
|
|
@@ -9,7 +10,8 @@
|
|
|
9
10
|
"bugs": "https://github.com/oscarotero/vento/issues",
|
|
10
11
|
"exports": {
|
|
11
12
|
".": {
|
|
12
|
-
"import": "./esm/mod.js"
|
|
13
|
+
"import": "./esm/mod.js",
|
|
14
|
+
"require": "./script/mod.js"
|
|
13
15
|
}
|
|
14
16
|
},
|
|
15
17
|
"scripts": {
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dntGlobalThis = exports.Deno = void 0;
|
|
4
|
+
const shim_deno_1 = require("@deno/shim-deno");
|
|
5
|
+
var shim_deno_2 = require("@deno/shim-deno");
|
|
6
|
+
Object.defineProperty(exports, "Deno", { enumerable: true, get: function () { return shim_deno_2.Deno; } });
|
|
7
|
+
const dntGlobals = {
|
|
8
|
+
Deno: shim_deno_1.Deno,
|
|
9
|
+
};
|
|
10
|
+
exports.dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
|
|
11
|
+
function createMergeProxy(baseObj, extObj) {
|
|
12
|
+
return new Proxy(baseObj, {
|
|
13
|
+
get(_target, prop, _receiver) {
|
|
14
|
+
if (prop in extObj) {
|
|
15
|
+
return extObj[prop];
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
return baseObj[prop];
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
set(_target, prop, value) {
|
|
22
|
+
if (prop in extObj) {
|
|
23
|
+
delete extObj[prop];
|
|
24
|
+
}
|
|
25
|
+
baseObj[prop] = value;
|
|
26
|
+
return true;
|
|
27
|
+
},
|
|
28
|
+
deleteProperty(_target, prop) {
|
|
29
|
+
let success = false;
|
|
30
|
+
if (prop in extObj) {
|
|
31
|
+
delete extObj[prop];
|
|
32
|
+
success = true;
|
|
33
|
+
}
|
|
34
|
+
if (prop in baseObj) {
|
|
35
|
+
delete baseObj[prop];
|
|
36
|
+
success = true;
|
|
37
|
+
}
|
|
38
|
+
return success;
|
|
39
|
+
},
|
|
40
|
+
ownKeys(_target) {
|
|
41
|
+
const baseKeys = Reflect.ownKeys(baseObj);
|
|
42
|
+
const extKeys = Reflect.ownKeys(extObj);
|
|
43
|
+
const extKeysSet = new Set(extKeys);
|
|
44
|
+
return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
|
|
45
|
+
},
|
|
46
|
+
defineProperty(_target, prop, desc) {
|
|
47
|
+
if (prop in extObj) {
|
|
48
|
+
delete extObj[prop];
|
|
49
|
+
}
|
|
50
|
+
Reflect.defineProperty(baseObj, prop, desc);
|
|
51
|
+
return true;
|
|
52
|
+
},
|
|
53
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
54
|
+
if (prop in extObj) {
|
|
55
|
+
return Reflect.getOwnPropertyDescriptor(extObj, prop);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
return Reflect.getOwnPropertyDescriptor(baseObj, prop);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
has(_target, prop) {
|
|
62
|
+
return prop in extObj || prop in baseObj;
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assert = void 0;
|
|
4
|
+
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
5
|
+
const assertion_error_js_1 = require("./assertion_error.js");
|
|
6
|
+
/** Make an assertion, error will be thrown if `expr` does not have truthy value. */
|
|
7
|
+
function assert(expr, msg = "") {
|
|
8
|
+
if (!expr) {
|
|
9
|
+
throw new assertion_error_js_1.AssertionError(msg);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.assert = assert;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AssertionError = void 0;
|
|
4
|
+
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
5
|
+
class AssertionError extends Error {
|
|
6
|
+
name = "AssertionError";
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(message);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.AssertionError = AssertionError;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export type EntityList = Record<string, string>;
|
|
2
|
+
/**
|
|
3
|
+
* Escapes text for safe interpolation into HTML text content and quoted attributes
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { escape } from "https://deno.land/std@$STD_VERSION/html/entities.ts";
|
|
8
|
+
* import { assertEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_equals.ts";
|
|
9
|
+
*
|
|
10
|
+
* assertEquals(escape("<>'&AA"), "<>'&AA");
|
|
11
|
+
*
|
|
12
|
+
* // characters that don't need to be escaped will be left alone,
|
|
13
|
+
* // even if named HTML entities exist for them
|
|
14
|
+
* assertEquals(escape("þð"), "þð");
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function escape(str: string): string;
|
|
18
|
+
export type UnescapeOptions = {
|
|
19
|
+
entityList: EntityList;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Unescapes HTML entities in text
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { unescape } from "https://deno.land/std@$STD_VERSION/html/entities.ts";
|
|
27
|
+
* import { assertEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_equals.ts";
|
|
28
|
+
*
|
|
29
|
+
* // default options (only handles &<>'" and numeric entities)
|
|
30
|
+
* assertEquals(unescape("<>'&AA"), "<>'&AA");
|
|
31
|
+
* assertEquals(unescape("þð"), "þð");
|
|
32
|
+
*
|
|
33
|
+
* // using the full named entity list from the HTML spec (~47K unminified)
|
|
34
|
+
* import entityList from "https://deno.land/std@$STD_VERSION/html/named_entity_list.json" assert { type: "json" };
|
|
35
|
+
* assertEquals(unescape("þð", { entityList }), "þð");
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function unescape(str: string, options?: Partial<UnescapeOptions>): string;
|