binja 0.6.1 → 0.7.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/dist/cli.js +0 -105
- package/dist/index.js +542 -109
- package/dist/lexer/index.d.ts +0 -4
- package/dist/lexer/index.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +9 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/package.json +7 -19
- package/native/darwin-arm64/libbinja.dylib +0 -0
- package/native/darwin-x64/libbinja.dylib +0 -0
- package/native/linux-arm64/libbinja.so +0 -0
- package/native/linux-x64/libbinja.so +0 -0
package/dist/cli.js
CHANGED
|
@@ -20,103 +20,6 @@ var KEYWORDS = {
|
|
|
20
20
|
in: "NAME" /* NAME */
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
// src/lexer/hybrid.ts
|
|
24
|
-
var _tokenizeBatchFn = null;
|
|
25
|
-
function checkNative() {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
var NATIVE_TO_TS = {
|
|
29
|
-
0: "TEXT" /* TEXT */,
|
|
30
|
-
1: "VARIABLE_START" /* VARIABLE_START */,
|
|
31
|
-
2: "VARIABLE_END" /* VARIABLE_END */,
|
|
32
|
-
3: "BLOCK_START" /* BLOCK_START */,
|
|
33
|
-
4: "BLOCK_END" /* BLOCK_END */,
|
|
34
|
-
5: "COMMENT_START" /* COMMENT_START */,
|
|
35
|
-
6: "COMMENT_END" /* COMMENT_END */,
|
|
36
|
-
7: "NAME" /* NAME */,
|
|
37
|
-
8: "STRING" /* STRING */,
|
|
38
|
-
9: "NUMBER" /* NUMBER */,
|
|
39
|
-
10: "NAME" /* NAME */,
|
|
40
|
-
11: "DOT" /* DOT */,
|
|
41
|
-
12: "COMMA" /* COMMA */,
|
|
42
|
-
13: "PIPE" /* PIPE */,
|
|
43
|
-
14: "COLON" /* COLON */,
|
|
44
|
-
15: "LPAREN" /* LPAREN */,
|
|
45
|
-
16: "RPAREN" /* RPAREN */,
|
|
46
|
-
17: "LBRACKET" /* LBRACKET */,
|
|
47
|
-
18: "RBRACKET" /* RBRACKET */,
|
|
48
|
-
19: "LBRACE" /* LBRACE */,
|
|
49
|
-
20: "RBRACE" /* RBRACE */,
|
|
50
|
-
21: "ASSIGN" /* ASSIGN */,
|
|
51
|
-
22: "EOF" /* EOF */
|
|
52
|
-
};
|
|
53
|
-
var OPERATOR_TO_TYPE = {
|
|
54
|
-
"==": "EQ" /* EQ */,
|
|
55
|
-
"!=": "NE" /* NE */,
|
|
56
|
-
"<": "LT" /* LT */,
|
|
57
|
-
">": "GT" /* GT */,
|
|
58
|
-
"<=": "LE" /* LE */,
|
|
59
|
-
">=": "GE" /* GE */,
|
|
60
|
-
"+": "ADD" /* ADD */,
|
|
61
|
-
"-": "SUB" /* SUB */,
|
|
62
|
-
"*": "MUL" /* MUL */,
|
|
63
|
-
"/": "DIV" /* DIV */,
|
|
64
|
-
"%": "MOD" /* MOD */,
|
|
65
|
-
"~": "TILDE" /* TILDE */
|
|
66
|
-
};
|
|
67
|
-
var KEYWORD_TO_TYPE = {
|
|
68
|
-
and: "AND" /* AND */,
|
|
69
|
-
or: "OR" /* OR */,
|
|
70
|
-
not: "NOT" /* NOT */
|
|
71
|
-
};
|
|
72
|
-
function isNativeAccelerated() {
|
|
73
|
-
return checkNative();
|
|
74
|
-
}
|
|
75
|
-
function tokenizeNative(source) {
|
|
76
|
-
if (!checkNative() || !_tokenizeBatchFn)
|
|
77
|
-
return null;
|
|
78
|
-
if (source.length === 0) {
|
|
79
|
-
return [{ type: "EOF" /* EOF */, value: "", line: 1, column: 1 }];
|
|
80
|
-
}
|
|
81
|
-
const rawTokens = _tokenizeBatchFn(source);
|
|
82
|
-
const lineStarts = [0];
|
|
83
|
-
for (let i = 0;i < source.length; i++) {
|
|
84
|
-
if (source[i] === `
|
|
85
|
-
`)
|
|
86
|
-
lineStarts.push(i + 1);
|
|
87
|
-
}
|
|
88
|
-
const tokens = new Array(rawTokens.length);
|
|
89
|
-
for (let i = 0;i < rawTokens.length; i++) {
|
|
90
|
-
const [nativeType, start, end] = rawTokens[i];
|
|
91
|
-
let value = source.slice(start, end);
|
|
92
|
-
let lo = 0, hi = lineStarts.length - 1;
|
|
93
|
-
while (lo < hi) {
|
|
94
|
-
const mid = lo + hi + 1 >> 1;
|
|
95
|
-
if (lineStarts[mid] <= start)
|
|
96
|
-
lo = mid;
|
|
97
|
-
else
|
|
98
|
-
hi = mid - 1;
|
|
99
|
-
}
|
|
100
|
-
const line = lo + 1;
|
|
101
|
-
const column = start - lineStarts[lo] + 1;
|
|
102
|
-
let type = NATIVE_TO_TS[nativeType] ?? "NAME" /* NAME */;
|
|
103
|
-
if (nativeType === 10 && OPERATOR_TO_TYPE[value]) {
|
|
104
|
-
type = OPERATOR_TO_TYPE[value];
|
|
105
|
-
} else if (type === "NAME" /* NAME */ && KEYWORD_TO_TYPE[value]) {
|
|
106
|
-
type = KEYWORD_TO_TYPE[value];
|
|
107
|
-
}
|
|
108
|
-
if (type === "STRING" /* STRING */ && value.length >= 2) {
|
|
109
|
-
const first = value[0];
|
|
110
|
-
const last = value[value.length - 1];
|
|
111
|
-
if (first === '"' && last === '"' || first === "'" && last === "'") {
|
|
112
|
-
value = value.slice(1, -1);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
tokens[i] = { type, value, line, column };
|
|
116
|
-
}
|
|
117
|
-
return tokens;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
23
|
// src/errors/index.ts
|
|
121
24
|
var colors = {
|
|
122
25
|
red: "\x1B[31m",
|
|
@@ -202,7 +105,6 @@ class Lexer {
|
|
|
202
105
|
blockEnd;
|
|
203
106
|
commentStart;
|
|
204
107
|
commentEnd;
|
|
205
|
-
useNative;
|
|
206
108
|
constructor(source, options = {}) {
|
|
207
109
|
this.state = {
|
|
208
110
|
source,
|
|
@@ -217,15 +119,8 @@ class Lexer {
|
|
|
217
119
|
this.blockEnd = options.blockEnd ?? "%}";
|
|
218
120
|
this.commentStart = options.commentStart ?? "{#";
|
|
219
121
|
this.commentEnd = options.commentEnd ?? "#}";
|
|
220
|
-
const hasCustomDelimiters = options.variableStart !== undefined || options.variableEnd !== undefined || options.blockStart !== undefined || options.blockEnd !== undefined || options.commentStart !== undefined || options.commentEnd !== undefined;
|
|
221
|
-
this.useNative = !hasCustomDelimiters && isNativeAccelerated();
|
|
222
122
|
}
|
|
223
123
|
tokenize() {
|
|
224
|
-
if (this.useNative) {
|
|
225
|
-
const nativeTokens = tokenizeNative(this.state.source);
|
|
226
|
-
if (nativeTokens)
|
|
227
|
-
return nativeTokens;
|
|
228
|
-
}
|
|
229
124
|
while (!this.isAtEnd()) {
|
|
230
125
|
this.scanToken();
|
|
231
126
|
}
|
package/dist/index.js
CHANGED
|
@@ -56,103 +56,6 @@ var KEYWORDS = {
|
|
|
56
56
|
in: "NAME" /* NAME */
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
// src/lexer/hybrid.ts
|
|
60
|
-
var _tokenizeBatchFn = null;
|
|
61
|
-
function checkNative() {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
var NATIVE_TO_TS = {
|
|
65
|
-
0: "TEXT" /* TEXT */,
|
|
66
|
-
1: "VARIABLE_START" /* VARIABLE_START */,
|
|
67
|
-
2: "VARIABLE_END" /* VARIABLE_END */,
|
|
68
|
-
3: "BLOCK_START" /* BLOCK_START */,
|
|
69
|
-
4: "BLOCK_END" /* BLOCK_END */,
|
|
70
|
-
5: "COMMENT_START" /* COMMENT_START */,
|
|
71
|
-
6: "COMMENT_END" /* COMMENT_END */,
|
|
72
|
-
7: "NAME" /* NAME */,
|
|
73
|
-
8: "STRING" /* STRING */,
|
|
74
|
-
9: "NUMBER" /* NUMBER */,
|
|
75
|
-
10: "NAME" /* NAME */,
|
|
76
|
-
11: "DOT" /* DOT */,
|
|
77
|
-
12: "COMMA" /* COMMA */,
|
|
78
|
-
13: "PIPE" /* PIPE */,
|
|
79
|
-
14: "COLON" /* COLON */,
|
|
80
|
-
15: "LPAREN" /* LPAREN */,
|
|
81
|
-
16: "RPAREN" /* RPAREN */,
|
|
82
|
-
17: "LBRACKET" /* LBRACKET */,
|
|
83
|
-
18: "RBRACKET" /* RBRACKET */,
|
|
84
|
-
19: "LBRACE" /* LBRACE */,
|
|
85
|
-
20: "RBRACE" /* RBRACE */,
|
|
86
|
-
21: "ASSIGN" /* ASSIGN */,
|
|
87
|
-
22: "EOF" /* EOF */
|
|
88
|
-
};
|
|
89
|
-
var OPERATOR_TO_TYPE = {
|
|
90
|
-
"==": "EQ" /* EQ */,
|
|
91
|
-
"!=": "NE" /* NE */,
|
|
92
|
-
"<": "LT" /* LT */,
|
|
93
|
-
">": "GT" /* GT */,
|
|
94
|
-
"<=": "LE" /* LE */,
|
|
95
|
-
">=": "GE" /* GE */,
|
|
96
|
-
"+": "ADD" /* ADD */,
|
|
97
|
-
"-": "SUB" /* SUB */,
|
|
98
|
-
"*": "MUL" /* MUL */,
|
|
99
|
-
"/": "DIV" /* DIV */,
|
|
100
|
-
"%": "MOD" /* MOD */,
|
|
101
|
-
"~": "TILDE" /* TILDE */
|
|
102
|
-
};
|
|
103
|
-
var KEYWORD_TO_TYPE = {
|
|
104
|
-
and: "AND" /* AND */,
|
|
105
|
-
or: "OR" /* OR */,
|
|
106
|
-
not: "NOT" /* NOT */
|
|
107
|
-
};
|
|
108
|
-
function isNativeAccelerated() {
|
|
109
|
-
return checkNative();
|
|
110
|
-
}
|
|
111
|
-
function tokenizeNative(source) {
|
|
112
|
-
if (!checkNative() || !_tokenizeBatchFn)
|
|
113
|
-
return null;
|
|
114
|
-
if (source.length === 0) {
|
|
115
|
-
return [{ type: "EOF" /* EOF */, value: "", line: 1, column: 1 }];
|
|
116
|
-
}
|
|
117
|
-
const rawTokens = _tokenizeBatchFn(source);
|
|
118
|
-
const lineStarts = [0];
|
|
119
|
-
for (let i = 0;i < source.length; i++) {
|
|
120
|
-
if (source[i] === `
|
|
121
|
-
`)
|
|
122
|
-
lineStarts.push(i + 1);
|
|
123
|
-
}
|
|
124
|
-
const tokens = new Array(rawTokens.length);
|
|
125
|
-
for (let i = 0;i < rawTokens.length; i++) {
|
|
126
|
-
const [nativeType, start, end] = rawTokens[i];
|
|
127
|
-
let value = source.slice(start, end);
|
|
128
|
-
let lo = 0, hi = lineStarts.length - 1;
|
|
129
|
-
while (lo < hi) {
|
|
130
|
-
const mid = lo + hi + 1 >> 1;
|
|
131
|
-
if (lineStarts[mid] <= start)
|
|
132
|
-
lo = mid;
|
|
133
|
-
else
|
|
134
|
-
hi = mid - 1;
|
|
135
|
-
}
|
|
136
|
-
const line = lo + 1;
|
|
137
|
-
const column = start - lineStarts[lo] + 1;
|
|
138
|
-
let type = NATIVE_TO_TS[nativeType] ?? "NAME" /* NAME */;
|
|
139
|
-
if (nativeType === 10 && OPERATOR_TO_TYPE[value]) {
|
|
140
|
-
type = OPERATOR_TO_TYPE[value];
|
|
141
|
-
} else if (type === "NAME" /* NAME */ && KEYWORD_TO_TYPE[value]) {
|
|
142
|
-
type = KEYWORD_TO_TYPE[value];
|
|
143
|
-
}
|
|
144
|
-
if (type === "STRING" /* STRING */ && value.length >= 2) {
|
|
145
|
-
const first = value[0];
|
|
146
|
-
const last = value[value.length - 1];
|
|
147
|
-
if (first === '"' && last === '"' || first === "'" && last === "'") {
|
|
148
|
-
value = value.slice(1, -1);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
tokens[i] = { type, value, line, column };
|
|
152
|
-
}
|
|
153
|
-
return tokens;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
59
|
// src/errors/index.ts
|
|
157
60
|
var colors = {
|
|
158
61
|
red: "\x1B[31m",
|
|
@@ -315,7 +218,6 @@ class Lexer {
|
|
|
315
218
|
blockEnd;
|
|
316
219
|
commentStart;
|
|
317
220
|
commentEnd;
|
|
318
|
-
useNative;
|
|
319
221
|
constructor(source, options = {}) {
|
|
320
222
|
this.state = {
|
|
321
223
|
source,
|
|
@@ -330,15 +232,8 @@ class Lexer {
|
|
|
330
232
|
this.blockEnd = options.blockEnd ?? "%}";
|
|
331
233
|
this.commentStart = options.commentStart ?? "{#";
|
|
332
234
|
this.commentEnd = options.commentEnd ?? "#}";
|
|
333
|
-
const hasCustomDelimiters = options.variableStart !== undefined || options.variableEnd !== undefined || options.blockStart !== undefined || options.blockEnd !== undefined || options.commentStart !== undefined || options.commentEnd !== undefined;
|
|
334
|
-
this.useNative = !hasCustomDelimiters && isNativeAccelerated();
|
|
335
235
|
}
|
|
336
236
|
tokenize() {
|
|
337
|
-
if (this.useNative) {
|
|
338
|
-
const nativeTokens = tokenizeNative(this.state.source);
|
|
339
|
-
if (nativeTokens)
|
|
340
|
-
return nativeTokens;
|
|
341
|
-
}
|
|
342
237
|
while (!this.isAtEnd()) {
|
|
343
238
|
this.scanToken();
|
|
344
239
|
}
|
|
@@ -3863,18 +3758,556 @@ class Runtime {
|
|
|
3863
3758
|
return;
|
|
3864
3759
|
return obj[index];
|
|
3865
3760
|
}
|
|
3761
|
+
static TITLE_REGEX = /\b\w/g;
|
|
3762
|
+
static STRIPTAGS_REGEX = /<[^>]*>/g;
|
|
3763
|
+
static SLUGIFY_REGEX1 = /[^\w\s-]/g;
|
|
3764
|
+
static SLUGIFY_REGEX2 = /[\s_-]+/g;
|
|
3765
|
+
static SLUGIFY_REGEX3 = /^-+|-+$/g;
|
|
3766
|
+
static WHITESPACE_REGEX = /\s+/;
|
|
3767
|
+
static URLIZE_REGEX = /(https?:\/\/[^\s]+)/g;
|
|
3768
|
+
static NEWLINE_REGEX = /\n/g;
|
|
3769
|
+
static DOUBLE_NEWLINE_REGEX = /\n\n+/;
|
|
3866
3770
|
evalFilter(node, ctx) {
|
|
3867
3771
|
const value = this.eval(node.node, ctx);
|
|
3772
|
+
const filterName = node.filter;
|
|
3773
|
+
const argsLen = node.args.length;
|
|
3774
|
+
if (argsLen === 0) {
|
|
3775
|
+
switch (filterName) {
|
|
3776
|
+
case "upper":
|
|
3777
|
+
return String(value ?? "").toUpperCase();
|
|
3778
|
+
case "lower":
|
|
3779
|
+
return String(value ?? "").toLowerCase();
|
|
3780
|
+
case "trim":
|
|
3781
|
+
return String(value ?? "").trim();
|
|
3782
|
+
case "capitalize": {
|
|
3783
|
+
const s = String(value ?? "");
|
|
3784
|
+
return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();
|
|
3785
|
+
}
|
|
3786
|
+
case "capfirst": {
|
|
3787
|
+
const s = String(value ?? "");
|
|
3788
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
3789
|
+
}
|
|
3790
|
+
case "title":
|
|
3791
|
+
return String(value ?? "").replace(Runtime.TITLE_REGEX, (c2) => c2.toUpperCase());
|
|
3792
|
+
case "striptags":
|
|
3793
|
+
return String(value ?? "").replace(Runtime.STRIPTAGS_REGEX, "");
|
|
3794
|
+
case "slugify":
|
|
3795
|
+
return String(value ?? "").toLowerCase().replace(Runtime.SLUGIFY_REGEX1, "").replace(Runtime.SLUGIFY_REGEX2, "-").replace(Runtime.SLUGIFY_REGEX3, "");
|
|
3796
|
+
case "wordcount": {
|
|
3797
|
+
const str = String(value ?? "").trim();
|
|
3798
|
+
return str ? str.split(Runtime.WHITESPACE_REGEX).length : 0;
|
|
3799
|
+
}
|
|
3800
|
+
case "escapejs":
|
|
3801
|
+
return JSON.stringify(String(value ?? "")).slice(1, -1);
|
|
3802
|
+
case "linebreaksbr": {
|
|
3803
|
+
const html = String(value ?? "").replace(Runtime.NEWLINE_REGEX, "<br>");
|
|
3804
|
+
const safe2 = new String(html);
|
|
3805
|
+
safe2.__safe__ = true;
|
|
3806
|
+
return safe2;
|
|
3807
|
+
}
|
|
3808
|
+
case "linebreaks": {
|
|
3809
|
+
const paragraphs = String(value ?? "").split(Runtime.DOUBLE_NEWLINE_REGEX);
|
|
3810
|
+
let html = "";
|
|
3811
|
+
for (let i = 0;i < paragraphs.length; i++) {
|
|
3812
|
+
if (i > 0)
|
|
3813
|
+
html += `
|
|
3814
|
+
`;
|
|
3815
|
+
html += `<p>${paragraphs[i].replace(Runtime.NEWLINE_REGEX, "<br>")}</p>`;
|
|
3816
|
+
}
|
|
3817
|
+
const safe2 = new String(html);
|
|
3818
|
+
safe2.__safe__ = true;
|
|
3819
|
+
return safe2;
|
|
3820
|
+
}
|
|
3821
|
+
case "urlencode":
|
|
3822
|
+
return encodeURIComponent(String(value ?? ""));
|
|
3823
|
+
case "safe": {
|
|
3824
|
+
const safeVal = new String(value ?? "");
|
|
3825
|
+
safeVal.__safe__ = true;
|
|
3826
|
+
return safeVal;
|
|
3827
|
+
}
|
|
3828
|
+
case "escape":
|
|
3829
|
+
case "e": {
|
|
3830
|
+
if (value?.__safe__)
|
|
3831
|
+
return value;
|
|
3832
|
+
const escaped = new String(Bun.escapeHTML(String(value ?? "")));
|
|
3833
|
+
escaped.__safe__ = true;
|
|
3834
|
+
return escaped;
|
|
3835
|
+
}
|
|
3836
|
+
case "forceescape": {
|
|
3837
|
+
const escaped = new String(Bun.escapeHTML(String(value ?? "")));
|
|
3838
|
+
escaped.__safe__ = true;
|
|
3839
|
+
return escaped;
|
|
3840
|
+
}
|
|
3841
|
+
case "int":
|
|
3842
|
+
return parseInt(String(value), 10) || 0;
|
|
3843
|
+
case "float":
|
|
3844
|
+
return parseFloat(String(value)) || 0;
|
|
3845
|
+
case "abs":
|
|
3846
|
+
return Math.abs(Number(value) || 0);
|
|
3847
|
+
case "filesizeformat": {
|
|
3848
|
+
const bytes = Number(value) || 0;
|
|
3849
|
+
const units = ["bytes", "KB", "MB", "GB", "TB", "PB"];
|
|
3850
|
+
let i = 0, size = bytes;
|
|
3851
|
+
while (size >= 1024 && i < units.length - 1) {
|
|
3852
|
+
size /= 1024;
|
|
3853
|
+
i++;
|
|
3854
|
+
}
|
|
3855
|
+
return `${size.toFixed(1)} ${units[i]}`;
|
|
3856
|
+
}
|
|
3857
|
+
case "length":
|
|
3858
|
+
if (value == null)
|
|
3859
|
+
return 0;
|
|
3860
|
+
if (typeof value === "string" || Array.isArray(value))
|
|
3861
|
+
return value.length;
|
|
3862
|
+
if (typeof value === "object") {
|
|
3863
|
+
let count = 0;
|
|
3864
|
+
for (const _ in value)
|
|
3865
|
+
count++;
|
|
3866
|
+
return count;
|
|
3867
|
+
}
|
|
3868
|
+
return 0;
|
|
3869
|
+
case "first":
|
|
3870
|
+
if (Array.isArray(value))
|
|
3871
|
+
return value[0];
|
|
3872
|
+
if (typeof value === "string")
|
|
3873
|
+
return value[0];
|
|
3874
|
+
return value;
|
|
3875
|
+
case "last":
|
|
3876
|
+
if (Array.isArray(value))
|
|
3877
|
+
return value[value.length - 1];
|
|
3878
|
+
if (typeof value === "string")
|
|
3879
|
+
return value[value.length - 1];
|
|
3880
|
+
return value;
|
|
3881
|
+
case "reverse":
|
|
3882
|
+
if (Array.isArray(value))
|
|
3883
|
+
return [...value].reverse();
|
|
3884
|
+
if (typeof value === "string")
|
|
3885
|
+
return value.split("").reverse().join("");
|
|
3886
|
+
return value;
|
|
3887
|
+
case "sort":
|
|
3888
|
+
if (Array.isArray(value))
|
|
3889
|
+
return [...value].sort();
|
|
3890
|
+
return value;
|
|
3891
|
+
case "unique":
|
|
3892
|
+
if (Array.isArray(value))
|
|
3893
|
+
return [...new Set(value)];
|
|
3894
|
+
return value;
|
|
3895
|
+
case "list":
|
|
3896
|
+
case "make_list":
|
|
3897
|
+
if (Array.isArray(value))
|
|
3898
|
+
return value;
|
|
3899
|
+
if (typeof value === "string")
|
|
3900
|
+
return value.split("");
|
|
3901
|
+
if (value && typeof value[Symbol.iterator] === "function")
|
|
3902
|
+
return [...value];
|
|
3903
|
+
if (typeof value === "object" && value !== null)
|
|
3904
|
+
return Object.values(value);
|
|
3905
|
+
return [value];
|
|
3906
|
+
case "random":
|
|
3907
|
+
if (Array.isArray(value))
|
|
3908
|
+
return value[Math.floor(Math.random() * value.length)];
|
|
3909
|
+
return value;
|
|
3910
|
+
case "items":
|
|
3911
|
+
if (value == null || typeof value !== "object")
|
|
3912
|
+
return [];
|
|
3913
|
+
return Object.entries(value);
|
|
3914
|
+
case "string":
|
|
3915
|
+
return String(value ?? "");
|
|
3916
|
+
case "json":
|
|
3917
|
+
case "tojson": {
|
|
3918
|
+
try {
|
|
3919
|
+
const jsonStr = new String(JSON.stringify(value));
|
|
3920
|
+
jsonStr.__safe__ = true;
|
|
3921
|
+
return jsonStr;
|
|
3922
|
+
} catch {
|
|
3923
|
+
return "";
|
|
3924
|
+
}
|
|
3925
|
+
}
|
|
3926
|
+
case "pprint": {
|
|
3927
|
+
try {
|
|
3928
|
+
const result = new String(JSON.stringify(value, null, 2));
|
|
3929
|
+
result.__safe__ = true;
|
|
3930
|
+
return result;
|
|
3931
|
+
} catch {
|
|
3932
|
+
return String(value);
|
|
3933
|
+
}
|
|
3934
|
+
}
|
|
3935
|
+
case "urlize": {
|
|
3936
|
+
const html = String(value ?? "").replace(Runtime.URLIZE_REGEX, '<a href="$1">$1</a>');
|
|
3937
|
+
const safe2 = new String(html);
|
|
3938
|
+
safe2.__safe__ = true;
|
|
3939
|
+
return safe2;
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
}
|
|
3943
|
+
if (argsLen === 1) {
|
|
3944
|
+
const arg = this.eval(node.args[0], ctx);
|
|
3945
|
+
switch (filterName) {
|
|
3946
|
+
case "default":
|
|
3947
|
+
case "d":
|
|
3948
|
+
if (value === undefined || value === null || value === "" || value === false) {
|
|
3949
|
+
return arg;
|
|
3950
|
+
}
|
|
3951
|
+
return value;
|
|
3952
|
+
case "default_if_none":
|
|
3953
|
+
return value === null || value === undefined ? arg : value;
|
|
3954
|
+
case "truncatechars": {
|
|
3955
|
+
const str = String(value ?? "");
|
|
3956
|
+
const len = Number(arg) || 30;
|
|
3957
|
+
if (str.length <= len)
|
|
3958
|
+
return str;
|
|
3959
|
+
return str.slice(0, len - 3) + "...";
|
|
3960
|
+
}
|
|
3961
|
+
case "truncatewords": {
|
|
3962
|
+
const words = String(value ?? "").split(Runtime.WHITESPACE_REGEX);
|
|
3963
|
+
const count = Number(arg) || 15;
|
|
3964
|
+
if (words.length <= count)
|
|
3965
|
+
return value;
|
|
3966
|
+
return words.slice(0, count).join(" ") + "...";
|
|
3967
|
+
}
|
|
3968
|
+
case "center": {
|
|
3969
|
+
const str = String(value ?? "");
|
|
3970
|
+
const width = Number(arg) || 80;
|
|
3971
|
+
const padding = Math.max(0, width - str.length);
|
|
3972
|
+
const left = Math.floor(padding / 2);
|
|
3973
|
+
return " ".repeat(left) + str + " ".repeat(padding - left);
|
|
3974
|
+
}
|
|
3975
|
+
case "ljust":
|
|
3976
|
+
return String(value ?? "").padEnd(Number(arg) || 80);
|
|
3977
|
+
case "rjust":
|
|
3978
|
+
return String(value ?? "").padStart(Number(arg) || 80);
|
|
3979
|
+
case "cut":
|
|
3980
|
+
return String(value ?? "").split(String(arg)).join("");
|
|
3981
|
+
case "add": {
|
|
3982
|
+
const numVal = Number(value);
|
|
3983
|
+
const numArg = Number(arg);
|
|
3984
|
+
if (!isNaN(numVal) && !isNaN(numArg))
|
|
3985
|
+
return numVal + numArg;
|
|
3986
|
+
return String(value) + String(arg);
|
|
3987
|
+
}
|
|
3988
|
+
case "divisibleby":
|
|
3989
|
+
return Number(value) % Number(arg) === 0;
|
|
3990
|
+
case "round":
|
|
3991
|
+
return Number(Number(value).toFixed(Number(arg) || 0));
|
|
3992
|
+
case "floatformat": {
|
|
3993
|
+
const num = parseFloat(String(value));
|
|
3994
|
+
if (isNaN(num))
|
|
3995
|
+
return "";
|
|
3996
|
+
const decimals = Number(arg);
|
|
3997
|
+
if (decimals === -1) {
|
|
3998
|
+
const formatted = num.toFixed(1);
|
|
3999
|
+
return formatted.endsWith(".0") ? Math.round(num).toString() : formatted;
|
|
4000
|
+
}
|
|
4001
|
+
return num.toFixed(Math.abs(decimals));
|
|
4002
|
+
}
|
|
4003
|
+
case "get_digit": {
|
|
4004
|
+
const num = parseInt(String(value), 10);
|
|
4005
|
+
if (isNaN(num))
|
|
4006
|
+
return value;
|
|
4007
|
+
const str = String(Math.abs(num));
|
|
4008
|
+
const pos = Number(arg) || 1;
|
|
4009
|
+
if (pos < 1 || pos > str.length)
|
|
4010
|
+
return value;
|
|
4011
|
+
return parseInt(str[str.length - pos], 10);
|
|
4012
|
+
}
|
|
4013
|
+
case "join":
|
|
4014
|
+
if (Array.isArray(value))
|
|
4015
|
+
return value.join(String(arg ?? ""));
|
|
4016
|
+
return String(value);
|
|
4017
|
+
case "slice": {
|
|
4018
|
+
if (!value)
|
|
4019
|
+
return value;
|
|
4020
|
+
const [startStr, endStr] = String(arg).split(":");
|
|
4021
|
+
const start = startStr ? parseInt(startStr, 10) : 0;
|
|
4022
|
+
const end = endStr ? parseInt(endStr, 10) : undefined;
|
|
4023
|
+
if (Array.isArray(value) || typeof value === "string")
|
|
4024
|
+
return value.slice(start, end);
|
|
4025
|
+
return value;
|
|
4026
|
+
}
|
|
4027
|
+
case "batch": {
|
|
4028
|
+
if (!Array.isArray(value))
|
|
4029
|
+
return [[value]];
|
|
4030
|
+
const size = Number(arg) || 1;
|
|
4031
|
+
const result = [];
|
|
4032
|
+
for (let i = 0;i < value.length; i += size) {
|
|
4033
|
+
result.push(value.slice(i, i + size));
|
|
4034
|
+
}
|
|
4035
|
+
return result;
|
|
4036
|
+
}
|
|
4037
|
+
case "columns": {
|
|
4038
|
+
if (!Array.isArray(value))
|
|
4039
|
+
return [[value]];
|
|
4040
|
+
const cols = Number(arg) || 2;
|
|
4041
|
+
const result = [];
|
|
4042
|
+
for (let i = 0;i < value.length; i += cols) {
|
|
4043
|
+
result.push(value.slice(i, i + cols));
|
|
4044
|
+
}
|
|
4045
|
+
return result;
|
|
4046
|
+
}
|
|
4047
|
+
case "length_is":
|
|
4048
|
+
return (value == null ? 0 : value.length ?? Object.keys(value).length ?? 0) === Number(arg);
|
|
4049
|
+
case "attr":
|
|
4050
|
+
return value == null ? undefined : value[arg];
|
|
4051
|
+
case "dictsort":
|
|
4052
|
+
if (!Array.isArray(value))
|
|
4053
|
+
return value;
|
|
4054
|
+
return [...value].sort((a, b) => {
|
|
4055
|
+
const aVal = arg ? a[arg] : a;
|
|
4056
|
+
const bVal = arg ? b[arg] : b;
|
|
4057
|
+
return aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
|
|
4058
|
+
});
|
|
4059
|
+
case "dictsortreversed":
|
|
4060
|
+
if (!Array.isArray(value))
|
|
4061
|
+
return value;
|
|
4062
|
+
return [...value].sort((a, b) => {
|
|
4063
|
+
const aVal = arg ? a[arg] : a;
|
|
4064
|
+
const bVal = arg ? b[arg] : b;
|
|
4065
|
+
return aVal > bVal ? -1 : aVal < bVal ? 1 : 0;
|
|
4066
|
+
});
|
|
4067
|
+
case "map":
|
|
4068
|
+
if (!Array.isArray(value))
|
|
4069
|
+
return [];
|
|
4070
|
+
if (typeof arg === "string")
|
|
4071
|
+
return value.map((item) => item?.[arg]);
|
|
4072
|
+
return value;
|
|
4073
|
+
case "select":
|
|
4074
|
+
if (!Array.isArray(value))
|
|
4075
|
+
return [];
|
|
4076
|
+
if (arg === undefined)
|
|
4077
|
+
return value.filter((item) => !!item);
|
|
4078
|
+
return value.filter((item) => !!item?.[arg]);
|
|
4079
|
+
case "reject":
|
|
4080
|
+
if (!Array.isArray(value))
|
|
4081
|
+
return [];
|
|
4082
|
+
if (arg === undefined)
|
|
4083
|
+
return value.filter((item) => !item);
|
|
4084
|
+
return value.filter((item) => !item?.[arg]);
|
|
4085
|
+
case "groupby": {
|
|
4086
|
+
if (!Array.isArray(value))
|
|
4087
|
+
return [];
|
|
4088
|
+
const groups = {};
|
|
4089
|
+
for (const item of value) {
|
|
4090
|
+
const key = String(arg ? item[arg] : item);
|
|
4091
|
+
if (!(key in groups))
|
|
4092
|
+
groups[key] = [];
|
|
4093
|
+
groups[key].push(item);
|
|
4094
|
+
}
|
|
4095
|
+
const result = [];
|
|
4096
|
+
for (const key in groups) {
|
|
4097
|
+
result.push({ grouper: key, list: groups[key] });
|
|
4098
|
+
}
|
|
4099
|
+
return result;
|
|
4100
|
+
}
|
|
4101
|
+
case "date":
|
|
4102
|
+
case "time": {
|
|
4103
|
+
const d = value instanceof Date ? value : new Date(value);
|
|
4104
|
+
if (isNaN(d.getTime()))
|
|
4105
|
+
return "";
|
|
4106
|
+
return this.formatDate(d, String(arg || (filterName === "time" ? "H:i" : "N j, Y")));
|
|
4107
|
+
}
|
|
4108
|
+
case "pluralize": {
|
|
4109
|
+
const argStr = String(arg ?? "s");
|
|
4110
|
+
const [singular, plural] = argStr.includes(",") ? argStr.split(",") : ["", argStr];
|
|
4111
|
+
return Number(value) === 1 ? singular : plural;
|
|
4112
|
+
}
|
|
4113
|
+
case "yesno": {
|
|
4114
|
+
const [yes, no, maybe] = String(arg ?? "yes,no,maybe").split(",");
|
|
4115
|
+
if (value === true)
|
|
4116
|
+
return yes;
|
|
4117
|
+
if (value === false)
|
|
4118
|
+
return no;
|
|
4119
|
+
return maybe ?? no;
|
|
4120
|
+
}
|
|
4121
|
+
case "json":
|
|
4122
|
+
case "tojson": {
|
|
4123
|
+
try {
|
|
4124
|
+
const jsonStr = new String(JSON.stringify(value, null, arg));
|
|
4125
|
+
jsonStr.__safe__ = true;
|
|
4126
|
+
return jsonStr;
|
|
4127
|
+
} catch {
|
|
4128
|
+
return "";
|
|
4129
|
+
}
|
|
4130
|
+
}
|
|
4131
|
+
case "urlizetrunc": {
|
|
4132
|
+
const maxLen = Number(arg) || 15;
|
|
4133
|
+
const html = String(value ?? "").replace(Runtime.URLIZE_REGEX, (url) => {
|
|
4134
|
+
const displayUrl = url.length > maxLen ? url.slice(0, maxLen) + "..." : url;
|
|
4135
|
+
return `<a href="${url}">${displayUrl}</a>`;
|
|
4136
|
+
});
|
|
4137
|
+
const safe2 = new String(html);
|
|
4138
|
+
safe2.__safe__ = true;
|
|
4139
|
+
return safe2;
|
|
4140
|
+
}
|
|
4141
|
+
case "indent": {
|
|
4142
|
+
const str = String(value ?? "");
|
|
4143
|
+
const indentStr = typeof arg === "string" ? arg : " ".repeat(Number(arg) || 4);
|
|
4144
|
+
const lines = str.split(`
|
|
4145
|
+
`);
|
|
4146
|
+
let result = lines[0];
|
|
4147
|
+
for (let i = 1;i < lines.length; i++) {
|
|
4148
|
+
result += `
|
|
4149
|
+
` + (lines[i].trim() === "" ? lines[i] : indentStr + lines[i]);
|
|
4150
|
+
}
|
|
4151
|
+
return result;
|
|
4152
|
+
}
|
|
4153
|
+
case "stringformat": {
|
|
4154
|
+
const fmt = String(arg);
|
|
4155
|
+
const val = value;
|
|
4156
|
+
if (fmt === "s")
|
|
4157
|
+
return String(val);
|
|
4158
|
+
if (fmt === "d" || fmt === "i")
|
|
4159
|
+
return String(parseInt(String(val), 10) || 0);
|
|
4160
|
+
if (fmt === "f")
|
|
4161
|
+
return String(parseFloat(String(val)) || 0);
|
|
4162
|
+
if (fmt === "x")
|
|
4163
|
+
return (parseInt(String(val), 10) || 0).toString(16);
|
|
4164
|
+
if (fmt === "X")
|
|
4165
|
+
return (parseInt(String(val), 10) || 0).toString(16).toUpperCase();
|
|
4166
|
+
if (fmt === "o")
|
|
4167
|
+
return (parseInt(String(val), 10) || 0).toString(8);
|
|
4168
|
+
if (fmt === "b")
|
|
4169
|
+
return (parseInt(String(val), 10) || 0).toString(2);
|
|
4170
|
+
if (fmt === "e")
|
|
4171
|
+
return (parseFloat(String(val)) || 0).toExponential();
|
|
4172
|
+
const precMatch = fmt.match(/^\.?(\d+)f$/);
|
|
4173
|
+
if (precMatch)
|
|
4174
|
+
return (parseFloat(String(val)) || 0).toFixed(parseInt(precMatch[1], 10));
|
|
4175
|
+
const widthMatch = fmt.match(/^(0?)(\d+)([sd])$/);
|
|
4176
|
+
if (widthMatch) {
|
|
4177
|
+
const [, zero, widthStr, type] = widthMatch;
|
|
4178
|
+
const width = parseInt(widthStr, 10);
|
|
4179
|
+
const strVal = type === "d" ? String(parseInt(String(val), 10) || 0) : String(val);
|
|
4180
|
+
return strVal.padStart(width, zero ? "0" : " ");
|
|
4181
|
+
}
|
|
4182
|
+
return String(val);
|
|
4183
|
+
}
|
|
4184
|
+
case "json_script": {
|
|
4185
|
+
const jsonStr = JSON.stringify(value).replace(/</g, "\\u003C").replace(/>/g, "\\u003E").replace(/&/g, "\\u0026");
|
|
4186
|
+
const id = arg ? ` id="${String(arg)}"` : "";
|
|
4187
|
+
const html = `<script${id} type="application/json">${jsonStr}</script>`;
|
|
4188
|
+
const safe2 = new String(html);
|
|
4189
|
+
safe2.__safe__ = true;
|
|
4190
|
+
return safe2;
|
|
4191
|
+
}
|
|
4192
|
+
}
|
|
4193
|
+
}
|
|
4194
|
+
if (argsLen === 2) {
|
|
4195
|
+
const arg1 = this.eval(node.args[0], ctx);
|
|
4196
|
+
const arg2 = this.eval(node.args[1], ctx);
|
|
4197
|
+
switch (filterName) {
|
|
4198
|
+
case "replace": {
|
|
4199
|
+
const str = String(value ?? "");
|
|
4200
|
+
return str.replaceAll(String(arg1), String(arg2));
|
|
4201
|
+
}
|
|
4202
|
+
case "batch": {
|
|
4203
|
+
if (!Array.isArray(value))
|
|
4204
|
+
return [[value]];
|
|
4205
|
+
const size = Number(arg1) || 1;
|
|
4206
|
+
const fillWith = arg2;
|
|
4207
|
+
const result = [];
|
|
4208
|
+
for (let i = 0;i < value.length; i += size) {
|
|
4209
|
+
const batch2 = value.slice(i, i + size);
|
|
4210
|
+
while (fillWith !== null && batch2.length < size)
|
|
4211
|
+
batch2.push(fillWith);
|
|
4212
|
+
result.push(batch2);
|
|
4213
|
+
}
|
|
4214
|
+
return result;
|
|
4215
|
+
}
|
|
4216
|
+
case "sum": {
|
|
4217
|
+
if (!Array.isArray(value))
|
|
4218
|
+
return Number(arg2) || 0;
|
|
4219
|
+
let total = Number(arg2) || 0;
|
|
4220
|
+
for (let i = 0;i < value.length; i++) {
|
|
4221
|
+
total += Number(arg1 ? value[i][arg1] : value[i]) || 0;
|
|
4222
|
+
}
|
|
4223
|
+
return total;
|
|
4224
|
+
}
|
|
4225
|
+
case "max": {
|
|
4226
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
4227
|
+
return arg2;
|
|
4228
|
+
if (arg1) {
|
|
4229
|
+
let maxItem = value[0];
|
|
4230
|
+
for (let i = 1;i < value.length; i++) {
|
|
4231
|
+
if (value[i][arg1] > maxItem[arg1])
|
|
4232
|
+
maxItem = value[i];
|
|
4233
|
+
}
|
|
4234
|
+
return maxItem;
|
|
4235
|
+
}
|
|
4236
|
+
let maxVal = value[0];
|
|
4237
|
+
for (let i = 1;i < value.length; i++) {
|
|
4238
|
+
if (value[i] > maxVal)
|
|
4239
|
+
maxVal = value[i];
|
|
4240
|
+
}
|
|
4241
|
+
return maxVal;
|
|
4242
|
+
}
|
|
4243
|
+
case "min": {
|
|
4244
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
4245
|
+
return arg2;
|
|
4246
|
+
if (arg1) {
|
|
4247
|
+
let minItem = value[0];
|
|
4248
|
+
for (let i = 1;i < value.length; i++) {
|
|
4249
|
+
if (value[i][arg1] < minItem[arg1])
|
|
4250
|
+
minItem = value[i];
|
|
4251
|
+
}
|
|
4252
|
+
return minItem;
|
|
4253
|
+
}
|
|
4254
|
+
let minVal = value[0];
|
|
4255
|
+
for (let i = 1;i < value.length; i++) {
|
|
4256
|
+
if (value[i] < minVal)
|
|
4257
|
+
minVal = value[i];
|
|
4258
|
+
}
|
|
4259
|
+
return minVal;
|
|
4260
|
+
}
|
|
4261
|
+
case "timesince": {
|
|
4262
|
+
const d = value instanceof Date ? value : new Date(value);
|
|
4263
|
+
const now = arg1 instanceof Date ? arg1 : new Date(arg1 ?? Date.now());
|
|
4264
|
+
const diff = (now.getTime() - d.getTime()) / 1000;
|
|
4265
|
+
const intervals = [
|
|
4266
|
+
[31536000, "year", "years"],
|
|
4267
|
+
[2592000, "month", "months"],
|
|
4268
|
+
[604800, "week", "weeks"],
|
|
4269
|
+
[86400, "day", "days"],
|
|
4270
|
+
[3600, "hour", "hours"],
|
|
4271
|
+
[60, "minute", "minutes"]
|
|
4272
|
+
];
|
|
4273
|
+
for (const [secs, sing, plur] of intervals) {
|
|
4274
|
+
const count = Math.floor(diff / secs);
|
|
4275
|
+
if (count >= 1)
|
|
4276
|
+
return `${count} ${count === 1 ? sing : plur}`;
|
|
4277
|
+
}
|
|
4278
|
+
return "just now";
|
|
4279
|
+
}
|
|
4280
|
+
case "timeuntil": {
|
|
4281
|
+
const d = value instanceof Date ? value : new Date(value);
|
|
4282
|
+
const now = arg1 instanceof Date ? arg1 : new Date(arg1 ?? Date.now());
|
|
4283
|
+
const diff = (d.getTime() - now.getTime()) / 1000;
|
|
4284
|
+
const intervals = [
|
|
4285
|
+
[31536000, "year", "years"],
|
|
4286
|
+
[2592000, "month", "months"],
|
|
4287
|
+
[604800, "week", "weeks"],
|
|
4288
|
+
[86400, "day", "days"],
|
|
4289
|
+
[3600, "hour", "hours"],
|
|
4290
|
+
[60, "minute", "minutes"]
|
|
4291
|
+
];
|
|
4292
|
+
for (const [secs, sing, plur] of intervals) {
|
|
4293
|
+
const count = Math.floor(diff / secs);
|
|
4294
|
+
if (count >= 1)
|
|
4295
|
+
return `${count} ${count === 1 ? sing : plur}`;
|
|
4296
|
+
}
|
|
4297
|
+
return "now";
|
|
4298
|
+
}
|
|
4299
|
+
}
|
|
4300
|
+
}
|
|
3868
4301
|
const args = [];
|
|
3869
|
-
for (let i = 0;i <
|
|
4302
|
+
for (let i = 0;i < argsLen; i++) {
|
|
3870
4303
|
args.push(this.eval(node.args[i], ctx));
|
|
3871
4304
|
}
|
|
3872
4305
|
const kwargs = this.evalObjectSync(node.kwargs, ctx);
|
|
3873
|
-
const filter = this.filters[
|
|
4306
|
+
const filter = this.filters[filterName];
|
|
3874
4307
|
if (!filter) {
|
|
3875
4308
|
const available = Object.keys(this.filters);
|
|
3876
|
-
const suggestion = findSimilar(
|
|
3877
|
-
throw new TemplateRuntimeError(`Unknown filter '${
|
|
4309
|
+
const suggestion = findSimilar(filterName, available);
|
|
4310
|
+
throw new TemplateRuntimeError(`Unknown filter '${filterName}'`, {
|
|
3878
4311
|
line: node.line,
|
|
3879
4312
|
column: node.column,
|
|
3880
4313
|
source: this.source,
|
package/dist/lexer/index.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Jinja2/DTL Lexer - Tokenizes template source into tokens
|
|
3
3
|
* Compatible with both Jinja2 and Django Template Language
|
|
4
|
-
*
|
|
5
|
-
* Automatically uses Zig FFI acceleration when available and using default delimiters.
|
|
6
4
|
*/
|
|
7
5
|
import { Token } from './tokens';
|
|
8
6
|
export declare class Lexer {
|
|
@@ -13,7 +11,6 @@ export declare class Lexer {
|
|
|
13
11
|
private blockEnd;
|
|
14
12
|
private commentStart;
|
|
15
13
|
private commentEnd;
|
|
16
|
-
private useNative;
|
|
17
14
|
constructor(source: string, options?: {
|
|
18
15
|
variableStart?: string;
|
|
19
16
|
variableEnd?: string;
|
|
@@ -49,5 +46,4 @@ export declare class Lexer {
|
|
|
49
46
|
}
|
|
50
47
|
export { TokenType, KEYWORDS } from './tokens';
|
|
51
48
|
export type { Token, LexerState } from './tokens';
|
|
52
|
-
export { isNativeAccelerated } from './hybrid';
|
|
53
49
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lexer/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lexer/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,KAAK,EAAmC,MAAM,UAAU,CAAA;AAGjE,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,UAAU,CAAQ;gBAGxB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;QACP,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,UAAU,CAAC,EAAE,MAAM,CAAA;KACf;IAmBR,QAAQ,IAAI,KAAK,EAAE;IASnB,OAAO,CAAC,SAAS;IAsCjB,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,YAAY;IAuFpB,OAAO,CAAC,QAAQ;IAmChB,OAAO,CAAC,cAAc;IA6BtB,OAAO,CAAC,mBAAmB;IA6B3B,OAAO,CAAC,UAAU;IA8BlB,OAAO,CAAC,UAAU;IAmBlB,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,YAAY;IAgEpB,OAAO,CAAC,WAAW;IAgBnB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,KAAK;IAkBb,OAAO,CAAC,KAAK;IAab,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,QAAQ;CAQjB;AAED,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAC9C,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA"}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -58,6 +58,15 @@ export declare class Runtime {
|
|
|
58
58
|
private eval;
|
|
59
59
|
private evalGetAttr;
|
|
60
60
|
private evalGetItem;
|
|
61
|
+
private static readonly TITLE_REGEX;
|
|
62
|
+
private static readonly STRIPTAGS_REGEX;
|
|
63
|
+
private static readonly SLUGIFY_REGEX1;
|
|
64
|
+
private static readonly SLUGIFY_REGEX2;
|
|
65
|
+
private static readonly SLUGIFY_REGEX3;
|
|
66
|
+
private static readonly WHITESPACE_REGEX;
|
|
67
|
+
private static readonly URLIZE_REGEX;
|
|
68
|
+
private static readonly NEWLINE_REGEX;
|
|
69
|
+
private static readonly DOUBLE_NEWLINE_REGEX;
|
|
61
70
|
private evalFilter;
|
|
62
71
|
private evalBinaryOp;
|
|
63
72
|
private evalUnaryOp;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAkB,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3D,OAAO,EAAgB,YAAY,EAAE,MAAM,UAAU,CAAA;AAErD,OAAO,KAAK,EAEV,YAAY,EAcZ,cAAc,EAwBf,MAAM,iBAAiB,CAAA;AAExB,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC7B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,MAAM,CAAA;IAChF,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;IACzC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IACxD,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,qBAAa,OAAO;IAClB,OAAO,CAAC,OAAO,CAAoE;IACnF,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,MAAM,CAAoC;IAClD,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,MAAM,CAAC,CAAQ;gBAEX,OAAO,GAAE,cAAmB;IAkClC,MAAM,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBnF,OAAO,CAAC,kBAAkB;IA0B1B,OAAO,CAAC,cAAc;IA4BtB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,cAAc;IAuDtB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,aAAa;IAiGrB,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,UAAU,CAAiC;IAEnD,OAAO,CAAC,eAAe;IAsBvB,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,cAAc,CAA8B;IAEpD,OAAO,CAAC,mBAAmB;IAgC3B,OAAO,CAAC,iBAAiB;IA+BzB,OAAO,CAAC,oBAAoB;IAe5B,OAAO,CAAC,eAAe;IA4DvB,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,qBAAqB;IAe7B,OAAO,CAAC,iBAAiB;IA+CzB,OAAO,CAAC,UAAU;IA6ClB,OAAO,CAAC,eAAe;IA6BvB,OAAO,CAAC,IAAI;IAiDZ,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,WAAW;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "binja",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "High-performance Jinja2/Django template engine for Bun",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -15,12 +15,6 @@
|
|
|
15
15
|
"types": "./dist/index.d.ts",
|
|
16
16
|
"bun": "./dist/index.js"
|
|
17
17
|
},
|
|
18
|
-
"./native": {
|
|
19
|
-
"import": "./dist/native/index.js",
|
|
20
|
-
"require": "./dist/native/index.js",
|
|
21
|
-
"types": "./dist/native/index.d.ts",
|
|
22
|
-
"bun": "./dist/native/index.js"
|
|
23
|
-
},
|
|
24
18
|
"./debug": {
|
|
25
19
|
"import": "./dist/debug/index.js",
|
|
26
20
|
"require": "./dist/debug/index.js",
|
|
@@ -30,25 +24,22 @@
|
|
|
30
24
|
},
|
|
31
25
|
"files": [
|
|
32
26
|
"dist",
|
|
33
|
-
"native",
|
|
34
27
|
"README.md",
|
|
35
28
|
"LICENSE"
|
|
36
29
|
],
|
|
37
30
|
"scripts": {
|
|
38
|
-
"build": "bun build ./src/index.ts --outdir ./dist --target bun && bun build ./src/cli.ts --outdir ./dist --target bun && bun build ./src/
|
|
31
|
+
"build": "bun build ./src/index.ts --outdir ./dist --target bun && bun build ./src/cli.ts --outdir ./dist --target bun && bun build ./src/debug/index.ts --outdir ./dist/debug --target bun && bun run build:types",
|
|
39
32
|
"build:types": "tsc --declaration --emitDeclarationOnly --outDir ./dist",
|
|
40
|
-
"build:native": "./scripts/build-native.sh",
|
|
41
|
-
"build:all": "bun run build:native && bun run build",
|
|
42
33
|
"test": "bun test",
|
|
43
34
|
"dev": "bun --watch src/index.ts",
|
|
44
35
|
"typecheck": "tsc --noEmit",
|
|
45
|
-
"prepublishOnly": "bun run build
|
|
36
|
+
"prepublishOnly": "bun run build",
|
|
46
37
|
"version:patch": "npm version patch --no-git-tag-version",
|
|
47
38
|
"version:minor": "npm version minor --no-git-tag-version",
|
|
48
39
|
"version:major": "npm version major --no-git-tag-version",
|
|
49
|
-
"release:patch": "bun run version:patch && bun run build
|
|
50
|
-
"release:minor": "bun run version:minor && bun run build
|
|
51
|
-
"release:major": "bun run version:major && bun run build
|
|
40
|
+
"release:patch": "bun run version:patch && bun run build",
|
|
41
|
+
"release:minor": "bun run version:minor && bun run build",
|
|
42
|
+
"release:major": "bun run version:major && bun run build"
|
|
52
43
|
},
|
|
53
44
|
"repository": {
|
|
54
45
|
"type": "git",
|
|
@@ -67,10 +58,7 @@
|
|
|
67
58
|
"ssr",
|
|
68
59
|
"template-engine",
|
|
69
60
|
"django-templates",
|
|
70
|
-
"typescript"
|
|
71
|
-
"zig",
|
|
72
|
-
"native",
|
|
73
|
-
"ffi"
|
|
61
|
+
"typescript"
|
|
74
62
|
],
|
|
75
63
|
"author": "egeominotti",
|
|
76
64
|
"license": "BSD-3-Clause",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|