minijinja-js 3.0.0-alpha.2 → 3.0.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 +186 -9
- package/dist/datetime.d.ts +16 -0
- package/dist/datetime.js +516 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +16 -0
- package/dist/init.d.ts +20 -0
- package/dist/init.js +27 -0
- package/dist/node.js +19 -0
- package/dist/shared.js +22 -0
- package/dist/types.d.ts +71 -0
- package/dist/wasm/minijinja_js.d.ts +337 -0
- package/dist/wasm/minijinja_js.js +1628 -0
- package/dist/wasm/minijinja_js_bg.wasm +0 -0
- package/dist/wasm/minijinja_js_bg.wasm.d.ts +58 -0
- package/dist/wasm/snippets/minijinja-js-357581db51780a74/js/support.js +33 -0
- package/package.json +33 -21
- package/dist/bundler/README.md +0 -124
- package/dist/bundler/minijinja_js.d.ts +0 -104
- package/dist/bundler/minijinja_js.js +0 -4
- package/dist/bundler/minijinja_js_bg.js +0 -902
- package/dist/bundler/minijinja_js_bg.wasm +0 -0
- package/dist/bundler/minijinja_js_bg.wasm.d.ts +0 -36
- package/dist/bundler/package.json +0 -22
- package/dist/node/README.md +0 -124
- package/dist/node/minijinja_js.d.ts +0 -104
- package/dist/node/minijinja_js.js +0 -907
- package/dist/node/minijinja_js_bg.wasm +0 -0
- package/dist/node/minijinja_js_bg.wasm.d.ts +0 -36
- package/dist/node/package.json +0 -16
- package/dist/web/README.md +0 -124
- package/dist/web/minijinja_js.d.ts +0 -164
- package/dist/web/minijinja_js.js +0 -942
- package/dist/web/minijinja_js_bg.wasm +0 -0
- package/dist/web/minijinja_js_bg.wasm.d.ts +0 -36
- package/dist/web/package.json +0 -20
package/README.md
CHANGED
|
@@ -88,29 +88,206 @@ const result = env.evalExpr('1 + 1', {});
|
|
|
88
88
|
console.log(result);
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
+
Register filters, tests and functions:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { Environment } from "minijinja-js";
|
|
95
|
+
|
|
96
|
+
const env = new Environment();
|
|
97
|
+
env.addFilter("repeat", (value, times, { sep = "" } = {}) =>
|
|
98
|
+
Array(times).fill(value).join(sep)
|
|
99
|
+
);
|
|
100
|
+
env.addGlobal("double", (x) => x * 2);
|
|
101
|
+
console.log(env.renderStr("{{ 'ab'|repeat(3, sep='-') }} {{ double(21) }}"));
|
|
102
|
+
// -> ab-ab-ab 42
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Keyword arguments are passed to JavaScript callbacks as a trailing object.
|
|
106
|
+
Exceptions thrown by callbacks fail the render with an error whose `cause`
|
|
107
|
+
is the original exception. Throw a `TemplateError` to fail with a specific
|
|
108
|
+
error kind and message:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { TemplateError } from "minijinja-js";
|
|
112
|
+
|
|
113
|
+
env.addFilter("sqrt", (value) => {
|
|
114
|
+
if (value < 0) {
|
|
115
|
+
throw new TemplateError("value must not be negative", { kind: "InvalidOperation" });
|
|
116
|
+
}
|
|
117
|
+
return Math.sqrt(value);
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Callbacks wrapped with `passState` receive the engine state as first
|
|
122
|
+
argument. It gives access to variables (`lookup`), the template name, the
|
|
123
|
+
auto escape mode, and allows applying filters and tests. The state is only
|
|
124
|
+
valid while the callback runs:
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
import { Environment, passState } from "minijinja-js";
|
|
128
|
+
|
|
129
|
+
const env = new Environment();
|
|
130
|
+
env.addFilter(
|
|
131
|
+
"greet",
|
|
132
|
+
passState((state, name) => `${state.lookup("greeting") ?? "Hello"} ${name}!`)
|
|
133
|
+
);
|
|
134
|
+
console.log(env.renderStr("{{ 'World'|greet }}", { greeting: "Hi" }));
|
|
135
|
+
// -> Hi World!
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The `random` filter as well as the `randrange` and `lipsum` functions are
|
|
139
|
+
available. Their output can be made deterministic with the `RAND_SEED` global.
|
|
140
|
+
|
|
141
|
+
## Dates and Times
|
|
142
|
+
|
|
143
|
+
Date and time filters can be enabled from `minijinja-js/datetime`. They
|
|
144
|
+
mirror the `datetimeformat`, `dateformat` and `timeformat` filters and the
|
|
145
|
+
`now()` function from MiniJinja's contrib package but use the time zone
|
|
146
|
+
support of the JavaScript runtime:
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import { Environment } from "minijinja-js";
|
|
150
|
+
import { addDateTimeSupport } from "minijinja-js/datetime";
|
|
151
|
+
|
|
152
|
+
const env = new Environment();
|
|
153
|
+
addDateTimeSupport(env);
|
|
154
|
+
env.addGlobal("TIMEZONE", "Europe/Vienna");
|
|
155
|
+
console.log(env.renderStr("{{ ts|datetimeformat(format='full') }}", { ts: 1687624642 }));
|
|
156
|
+
// -> Saturday, June 24 2023 18:37:22.0
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The filters accept Unix timestamps, ISO 8601 strings (optionally with a time
|
|
160
|
+
zone annotation such as `2023-06-24T16:37:22Z[Europe/Vienna]`) and `Date`
|
|
161
|
+
objects. The format is one of `short`, `medium` (the default), `long`,
|
|
162
|
+
`full`, `iso` and `unix` or a `strftime` style format string. The `format`
|
|
163
|
+
and `tz` keyword arguments default to the `DATETIME_FORMAT`, `DATE_FORMAT`,
|
|
164
|
+
`TIME_FORMAT` and `TIMEZONE` globals.
|
|
165
|
+
|
|
166
|
+
## Values
|
|
167
|
+
|
|
168
|
+
Values passed to templates are converted as follows:
|
|
169
|
+
|
|
170
|
+
* `undefined` is undefined and `null` is none.
|
|
171
|
+
* Numbers that are safe integers become integers, all others floats.
|
|
172
|
+
`BigInt`s become integers.
|
|
173
|
+
* Arrays, `Set`s and typed arrays become sequences, `Uint8Array` and
|
|
174
|
+
`ArrayBuffer` become bytes.
|
|
175
|
+
* Plain objects and `Map`s become maps. Key order is preserved.
|
|
176
|
+
* `Date`s become ISO 8601 strings.
|
|
177
|
+
* Functions become callable.
|
|
178
|
+
* Other objects (for instance class instances) are not copied but accessed
|
|
179
|
+
lazily. This means getters work and methods are invoked with the object
|
|
180
|
+
as `this`.
|
|
181
|
+
|
|
182
|
+
Values returned to JavaScript (from `evalExpr` or as arguments to
|
|
183
|
+
callbacks) are converted back:
|
|
184
|
+
|
|
185
|
+
* undefined becomes `undefined`, none becomes `null`.
|
|
186
|
+
* Integers outside of the safe integer range become `BigInt`s.
|
|
187
|
+
* Sequences become arrays, bytes become `Uint8Array`s.
|
|
188
|
+
* Maps with only string keys become plain objects, other maps become `Map`s.
|
|
189
|
+
* Functions and objects that came from JavaScript are passed back unchanged.
|
|
190
|
+
|
|
91
191
|
MiniJinja tuples retain tuple rendering inside templates. Expression results are
|
|
92
192
|
returned as JavaScript arrays because JavaScript has no distinct tuple type.
|
|
93
193
|
|
|
94
|
-
##
|
|
194
|
+
## Configuration
|
|
95
195
|
|
|
96
|
-
|
|
97
|
-
|
|
196
|
+
```typescript
|
|
197
|
+
import { Environment } from "minijinja-js";
|
|
198
|
+
|
|
199
|
+
const env = new Environment();
|
|
200
|
+
|
|
201
|
+
// whitespace handling and undefined behavior
|
|
202
|
+
env.trimBlocks = true;
|
|
203
|
+
env.lstripBlocks = true;
|
|
204
|
+
env.undefinedBehavior = "strict";
|
|
205
|
+
|
|
206
|
+
// custom delimiters and line statements (unspecified ones use the defaults)
|
|
207
|
+
env.syntax = { variableStart: "${", variableEnd: "}", lineStatementPrefix: "#" };
|
|
208
|
+
|
|
209
|
+
// auto escaping per template name: "html", "json", "none", true or false
|
|
210
|
+
env.setAutoEscapeCallback((name) => name.endsWith(".html"));
|
|
211
|
+
|
|
212
|
+
// customize values before they are rendered (return undefined to keep them)
|
|
213
|
+
env.setFinalizer((value) => (value === null ? "" : undefined));
|
|
214
|
+
|
|
215
|
+
// limit the amount of work a template can do
|
|
216
|
+
env.fuel = 50000;
|
|
217
|
+
|
|
218
|
+
// Python compatible methods such as dict.items()
|
|
219
|
+
env.pycompat = true;
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Find the variables a template needs:
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
env.addTemplate("index.html", "{% set greeting = 'Hello' %}{{ greeting }} {{ user.name }}");
|
|
226
|
+
env.undeclaredVariablesInTemplate("index.html"); // ["user"]
|
|
227
|
+
env.undeclaredVariablesInTemplate("index.html", true); // ["user.name"]
|
|
228
|
+
```
|
|
98
229
|
|
|
230
|
+
## Safe Strings
|
|
231
|
+
|
|
232
|
+
Strings marked as safe are not auto escaped. Safe strings are represented
|
|
233
|
+
by `SafeString` (which extends `String`) and can be created with `markSafe`.
|
|
234
|
+
Callbacks receive safe strings (for instance after the `|safe` filter) as
|
|
235
|
+
`SafeString` objects and can return them to emit markup:
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
import { Environment, markSafe } from "minijinja-js";
|
|
239
|
+
|
|
240
|
+
const env = new Environment();
|
|
241
|
+
env.addFilter("bold", (value) => markSafe(`<b>${value}</b>`));
|
|
242
|
+
env.addTemplate("index.html", "{{ name|bold }} {{ icon }}");
|
|
243
|
+
console.log(env.renderTemplate("index.html", { name: "World", icon: markSafe("<i>*</i>") }));
|
|
244
|
+
// -> <b>World</b> <i>*</i>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Errors
|
|
248
|
+
|
|
249
|
+
Errors are raised as `TemplateError` which extends `Error` and provides
|
|
250
|
+
`kind`, `detail`, `templateName`, `line`, `range` and `templateSource`
|
|
251
|
+
properties. If the error was caused by an exception thrown in a callback,
|
|
252
|
+
the exception is available as `cause`.
|
|
253
|
+
|
|
254
|
+
## Runtimes
|
|
255
|
+
|
|
256
|
+
The package is an ES module and works in Node.js, Deno, Bun, browsers and
|
|
257
|
+
bundlers:
|
|
258
|
+
|
|
259
|
+
* In Node.js the wasm module is loaded synchronously. Recent Node.js versions
|
|
260
|
+
can also load the package with `require()`.
|
|
261
|
+
* In all other environments the wasm module is loaded relative to the package
|
|
262
|
+
(via `import.meta.url`) with top-level await.
|
|
263
|
+
|
|
264
|
+
If you need to control how the wasm module is loaded (for instance on
|
|
265
|
+
Cloudflare Workers or with a custom asset pipeline), use the `minijinja-js/init`
|
|
266
|
+
entry point and initialize the module yourself before use:
|
|
99
267
|
|
|
100
268
|
```javascript
|
|
101
|
-
import init,
|
|
102
|
-
|
|
269
|
+
import { init, initSync, Environment } from "minijinja-js/init";
|
|
270
|
+
|
|
271
|
+
// load from a URL, Response or compiled module
|
|
272
|
+
await init(new URL("minijinja_js_bg.wasm", someBaseUrl));
|
|
273
|
+
|
|
274
|
+
// or synchronously from bytes or a compiled module
|
|
275
|
+
initSync(wasmModule);
|
|
103
276
|
```
|
|
104
277
|
|
|
278
|
+
The wasm file is exported as `minijinja-js/minijinja_js_bg.wasm`.
|
|
279
|
+
|
|
105
280
|
## Known Limitations
|
|
106
281
|
|
|
107
282
|
There are various limitations with the binding today, some of which can be fixed,
|
|
108
283
|
others probably not so much. You might run into the following:
|
|
109
284
|
|
|
110
|
-
*
|
|
111
|
-
* You cannot register a custom auto escape callback or a finalizer
|
|
285
|
+
* Filters, tests and functions cannot be async.
|
|
112
286
|
* The loader is synchronous; use sync I/O in Node etc... (e.g. `fs.readFileSync`)
|
|
113
|
-
*
|
|
287
|
+
* The environment cannot be modified while it renders (for instance from
|
|
288
|
+
within a filter).
|
|
289
|
+
* If the engine panics, the WASM runtime corrupts. This should not happen
|
|
290
|
+
but if it does, please report it as a bug.
|
|
114
291
|
|
|
115
292
|
## Sponsor
|
|
116
293
|
|
|
@@ -120,5 +297,5 @@ sponsor](https://github.com/sponsors/mitsuhiko).
|
|
|
120
297
|
## License and Links
|
|
121
298
|
|
|
122
299
|
- [Issue Tracker](https://github.com/mitsuhiko/minijinja/issues)
|
|
123
|
-
- [MiniJinja Playground](https://mitsuhiko.github.io/minijinja
|
|
300
|
+
- [MiniJinja Playground](https://mitsuhiko.github.io/minijinja/)
|
|
124
301
|
- License: [Apache-2.0](https://github.com/mitsuhiko/minijinja/blob/main/LICENSE)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Environment } from "./types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Registers the date and time filters and functions with an environment.
|
|
5
|
+
*
|
|
6
|
+
* This adds the `datetimeformat`, `dateformat` and `timeformat` filters and
|
|
7
|
+
* the `now` function. They behave like the ones of the `datetime` feature
|
|
8
|
+
* of minijinja-contrib but use the time zone support of the JavaScript
|
|
9
|
+
* runtime (`Intl`).
|
|
10
|
+
*
|
|
11
|
+
* The filters accept Unix timestamps (seconds), ISO 8601 strings
|
|
12
|
+
* (optionally with a time zone annotation such as `[Europe/Vienna]`) and
|
|
13
|
+
* `Date` objects. The `format` and `tz` keyword arguments default to the
|
|
14
|
+
* `DATETIME_FORMAT`, `DATE_FORMAT`, `TIME_FORMAT` and `TIMEZONE` globals.
|
|
15
|
+
*/
|
|
16
|
+
export declare function addDateTimeSupport(env: Environment): void;
|