@dogsbay/minja 0.2.0-beta.48
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/LICENSE +21 -0
- package/README.md +603 -0
- package/bin/minja.js +1062 -0
- package/dist/browser.d.ts +11 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +10 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +97 -0
- package/dist/cli.js.map +1 -0
- package/dist/context.d.ts +47 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +112 -0
- package/dist/context.js.map +1 -0
- package/dist/evaluator.d.ts +20 -0
- package/dist/evaluator.d.ts.map +1 -0
- package/dist/evaluator.js +207 -0
- package/dist/evaluator.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +1026 -0
- package/dist/index.umd.js.map +7 -0
- package/dist/index.umd.min.js +9 -0
- package/dist/index.umd.min.js.map +7 -0
- package/dist/loader-fetch.d.ts +8 -0
- package/dist/loader-fetch.d.ts.map +1 -0
- package/dist/loader-fetch.js +15 -0
- package/dist/loader-fetch.js.map +1 -0
- package/dist/loader-memory.d.ts +11 -0
- package/dist/loader-memory.d.ts.map +1 -0
- package/dist/loader-memory.js +36 -0
- package/dist/loader-memory.js.map +1 -0
- package/dist/loader.d.ts +54 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +91 -0
- package/dist/loader.js.map +1 -0
- package/dist/parser.d.ts +12 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +501 -0
- package/dist/parser.js.map +1 -0
- package/dist/renderer.d.ts +13 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +415 -0
- package/dist/renderer.js.map +1 -0
- package/dist/types.d.ts +150 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-only entry point (excludes FileSystemLoader)
|
|
3
|
+
*/
|
|
4
|
+
export { render } from './renderer.js';
|
|
5
|
+
export { parse } from './parser.js';
|
|
6
|
+
export { parseExpression, evaluateExpression } from './evaluator.js';
|
|
7
|
+
export { Context } from './context.js';
|
|
8
|
+
export { FetchLoader } from './loader-fetch.js';
|
|
9
|
+
export { MemoryLoader } from './loader-memory.js';
|
|
10
|
+
export type { ASTNode, TextNode, VariableNode, SetNode, IfNode, IncludeNode, CommentNode, Expression, LiteralExpression, VariableExpression, BinaryExpression, UnaryExpression, RenderOptions, Loader, IContext, ParseResult, ParseError, } from './types.js';
|
|
11
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,YAAY,EAEV,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,MAAM,EACN,WAAW,EACX,WAAW,EAGX,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EAGf,aAAa,EACb,MAAM,EACN,QAAQ,EACR,WAAW,EACX,UAAU,GACX,MAAM,YAAY,CAAA"}
|
package/dist/browser.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-only entry point (excludes FileSystemLoader)
|
|
3
|
+
*/
|
|
4
|
+
export { render } from './renderer.js';
|
|
5
|
+
export { parse } from './parser.js';
|
|
6
|
+
export { parseExpression, evaluateExpression } from './evaluator.js';
|
|
7
|
+
export { Context } from './context.js';
|
|
8
|
+
export { FetchLoader } from './loader-fetch.js';
|
|
9
|
+
export { MemoryLoader } from './loader-memory.js';
|
|
10
|
+
//# sourceMappingURL=browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minja CLI - Command-line interface for template rendering
|
|
3
|
+
*/
|
|
4
|
+
import { readFile, writeFile } from 'fs/promises';
|
|
5
|
+
import { resolve, dirname } from 'path';
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
import { parse as parseYAML } from 'yaml';
|
|
8
|
+
import { render } from './renderer.js';
|
|
9
|
+
import { FileSystemLoader } from './loader.js';
|
|
10
|
+
const program = new Command();
|
|
11
|
+
program
|
|
12
|
+
.name('minja')
|
|
13
|
+
.description('Minimal, secure Jinja2/Nunjucks subset for documentation preprocessing')
|
|
14
|
+
.version('0.1.0')
|
|
15
|
+
.argument('[template]', 'Template file to render (or read from stdin)')
|
|
16
|
+
.option('-c, --context <file>', 'Context file (JSON or YAML)')
|
|
17
|
+
.option('-o, --output <file>', 'Output file (default: stdout)')
|
|
18
|
+
.option('-d, --max-depth <number>', 'Maximum include depth', '10')
|
|
19
|
+
.option('-t, --timeout <ms>', 'Rendering timeout in milliseconds', '5000')
|
|
20
|
+
.option('-v, --vars <json>', 'Inline context variables as JSON')
|
|
21
|
+
.action(async (templatePath, options) => {
|
|
22
|
+
try {
|
|
23
|
+
// Read template from file or stdin
|
|
24
|
+
let template;
|
|
25
|
+
let baseDir = process.cwd();
|
|
26
|
+
if (templatePath) {
|
|
27
|
+
const fullPath = resolve(templatePath);
|
|
28
|
+
template = await readFile(fullPath, 'utf-8');
|
|
29
|
+
baseDir = dirname(fullPath);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
// Read from stdin
|
|
33
|
+
template = await readStdin();
|
|
34
|
+
}
|
|
35
|
+
// Load context from file or inline vars
|
|
36
|
+
let context = {};
|
|
37
|
+
if (options.context) {
|
|
38
|
+
const contextPath = resolve(options.context);
|
|
39
|
+
const contextContent = await readFile(contextPath, 'utf-8');
|
|
40
|
+
if (contextPath.endsWith('.json')) {
|
|
41
|
+
context = JSON.parse(contextContent);
|
|
42
|
+
}
|
|
43
|
+
else if (contextPath.endsWith('.yaml') || contextPath.endsWith('.yml')) {
|
|
44
|
+
context = parseYAML(contextContent);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
throw new Error('Context file must be .json, .yaml, or .yml');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Merge inline vars if provided
|
|
51
|
+
if (options.vars) {
|
|
52
|
+
const inlineVars = JSON.parse(options.vars);
|
|
53
|
+
context = { ...context, ...inlineVars };
|
|
54
|
+
}
|
|
55
|
+
// Render template
|
|
56
|
+
const loader = new FileSystemLoader(baseDir);
|
|
57
|
+
const result = await render(template, {
|
|
58
|
+
loader,
|
|
59
|
+
basePath: baseDir,
|
|
60
|
+
context,
|
|
61
|
+
maxIncludeDepth: parseInt(options.maxDepth || '10'),
|
|
62
|
+
timeout: parseInt(options.timeout || '5000'),
|
|
63
|
+
});
|
|
64
|
+
// Output to file or stdout
|
|
65
|
+
if (options.output) {
|
|
66
|
+
const outputPath = resolve(options.output);
|
|
67
|
+
await writeFile(outputPath, result, 'utf-8');
|
|
68
|
+
console.error(`✓ Rendered to ${outputPath}`);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
process.stdout.write(result);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.error('Error:', error instanceof Error ? error.message : String(error));
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
program.parse();
|
|
80
|
+
/**
|
|
81
|
+
* Read from stdin
|
|
82
|
+
*/
|
|
83
|
+
async function readStdin() {
|
|
84
|
+
return new Promise((resolve, reject) => {
|
|
85
|
+
const chunks = [];
|
|
86
|
+
process.stdin.on('data', (chunk) => {
|
|
87
|
+
chunks.push(chunk);
|
|
88
|
+
});
|
|
89
|
+
process.stdin.on('end', () => {
|
|
90
|
+
resolve(Buffer.concat(chunks).toString('utf-8'));
|
|
91
|
+
});
|
|
92
|
+
process.stdin.on('error', (error) => {
|
|
93
|
+
reject(error);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context management for variable scoping
|
|
3
|
+
* Supports nested scopes with inheritance
|
|
4
|
+
*/
|
|
5
|
+
import type { IContext } from './types.js';
|
|
6
|
+
export interface ContextOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Convert hyphenated variable names to underscores during lookup.
|
|
9
|
+
*/
|
|
10
|
+
hyphenToUnderscore?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare class Context implements IContext {
|
|
13
|
+
private variables;
|
|
14
|
+
private parent;
|
|
15
|
+
private options;
|
|
16
|
+
constructor(parent?: Context, options?: ContextOptions);
|
|
17
|
+
/**
|
|
18
|
+
* Get a variable from the context (supports dot notation)
|
|
19
|
+
* @param name - Variable name (can use dot notation like "obj.prop.subprop")
|
|
20
|
+
* @returns The variable value or undefined
|
|
21
|
+
*/
|
|
22
|
+
get(name: string): unknown;
|
|
23
|
+
/**
|
|
24
|
+
* Set a variable in the current context
|
|
25
|
+
* @param name - Variable name (can use dot notation)
|
|
26
|
+
* @param value - Value to set
|
|
27
|
+
*/
|
|
28
|
+
set(name: string, value: unknown): void;
|
|
29
|
+
/**
|
|
30
|
+
* Create a child scope
|
|
31
|
+
* @returns A new Context with this context as parent
|
|
32
|
+
*/
|
|
33
|
+
push(): Context;
|
|
34
|
+
/**
|
|
35
|
+
* Return to parent scope
|
|
36
|
+
* @returns The parent context or null if at root
|
|
37
|
+
*/
|
|
38
|
+
pop(): Context | null;
|
|
39
|
+
/**
|
|
40
|
+
* Create a context from a plain object
|
|
41
|
+
* @param data - Plain object to convert to context
|
|
42
|
+
* @param options - Context options
|
|
43
|
+
* @returns New Context instance
|
|
44
|
+
*/
|
|
45
|
+
static from(data: Record<string, unknown>, options?: ContextOptions): Context;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1C,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED,qBAAa,OAAQ,YAAW,QAAQ;IACtC,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,OAAO,CAAgB;gBAEnB,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc;IAMtD;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAyC1B;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAsCvC;;;OAGG;IACH,IAAI,IAAI,OAAO;IAIf;;;OAGG;IACH,GAAG,IAAI,OAAO,GAAG,IAAI;IAIrB;;;;;OAKG;IACH,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO;CAO9E"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context management for variable scoping
|
|
3
|
+
* Supports nested scopes with inheritance
|
|
4
|
+
*/
|
|
5
|
+
export class Context {
|
|
6
|
+
constructor(parent, options) {
|
|
7
|
+
this.variables = new Map();
|
|
8
|
+
this.parent = parent || null;
|
|
9
|
+
this.options = options || parent?.options || {};
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get a variable from the context (supports dot notation)
|
|
13
|
+
* @param name - Variable name (can use dot notation like "obj.prop.subprop")
|
|
14
|
+
* @returns The variable value or undefined
|
|
15
|
+
*/
|
|
16
|
+
get(name) {
|
|
17
|
+
// Convert hyphens to underscores if option is enabled
|
|
18
|
+
const normalizedName = this.options.hyphenToUnderscore
|
|
19
|
+
? name.replace(/-/g, '_')
|
|
20
|
+
: name;
|
|
21
|
+
const parts = normalizedName.split('.');
|
|
22
|
+
const rootName = parts[0];
|
|
23
|
+
// Look up the root variable in current scope or parent scopes
|
|
24
|
+
let value;
|
|
25
|
+
if (this.variables.has(rootName)) {
|
|
26
|
+
value = this.variables.get(rootName);
|
|
27
|
+
}
|
|
28
|
+
else if (this.parent) {
|
|
29
|
+
value = this.parent.get(rootName);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
// Navigate nested properties
|
|
35
|
+
for (let i = 1; i < parts.length; i++) {
|
|
36
|
+
if (value === null || value === undefined) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
// Only allow property access on plain objects (prevent prototype pollution)
|
|
40
|
+
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
// Prevent access to prototype chain
|
|
44
|
+
if (!Object.prototype.hasOwnProperty.call(value, parts[i])) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
value = value[parts[i]];
|
|
48
|
+
}
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Set a variable in the current context
|
|
53
|
+
* @param name - Variable name (can use dot notation)
|
|
54
|
+
* @param value - Value to set
|
|
55
|
+
*/
|
|
56
|
+
set(name, value) {
|
|
57
|
+
const parts = name.split('.');
|
|
58
|
+
if (parts.length === 1) {
|
|
59
|
+
// Simple assignment
|
|
60
|
+
this.variables.set(name, value);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Nested assignment - navigate to parent object
|
|
64
|
+
const rootName = parts[0];
|
|
65
|
+
let target = this.variables.get(rootName);
|
|
66
|
+
if (!target || typeof target !== 'object' || Array.isArray(target)) {
|
|
67
|
+
// Create new object if root doesn't exist or isn't an object
|
|
68
|
+
target = {};
|
|
69
|
+
this.variables.set(rootName, target);
|
|
70
|
+
}
|
|
71
|
+
// Navigate to the parent of the target property
|
|
72
|
+
for (let i = 1; i < parts.length - 1; i++) {
|
|
73
|
+
const key = parts[i];
|
|
74
|
+
if (!target[key] ||
|
|
75
|
+
typeof target[key] !== 'object' ||
|
|
76
|
+
Array.isArray(target[key])) {
|
|
77
|
+
target[key] = {};
|
|
78
|
+
}
|
|
79
|
+
target = target[key];
|
|
80
|
+
}
|
|
81
|
+
// Set the final property
|
|
82
|
+
target[parts[parts.length - 1]] = value;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Create a child scope
|
|
86
|
+
* @returns A new Context with this context as parent
|
|
87
|
+
*/
|
|
88
|
+
push() {
|
|
89
|
+
return new Context(this, this.options);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Return to parent scope
|
|
93
|
+
* @returns The parent context or null if at root
|
|
94
|
+
*/
|
|
95
|
+
pop() {
|
|
96
|
+
return this.parent;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Create a context from a plain object
|
|
100
|
+
* @param data - Plain object to convert to context
|
|
101
|
+
* @param options - Context options
|
|
102
|
+
* @returns New Context instance
|
|
103
|
+
*/
|
|
104
|
+
static from(data, options) {
|
|
105
|
+
const ctx = new Context(undefined, options);
|
|
106
|
+
for (const [key, value] of Object.entries(data)) {
|
|
107
|
+
ctx.set(key, value);
|
|
108
|
+
}
|
|
109
|
+
return ctx;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe expression evaluator
|
|
3
|
+
* Evaluates expressions WITHOUT using eval() or new Function()
|
|
4
|
+
* Only allows whitelisted operations
|
|
5
|
+
*/
|
|
6
|
+
import type { Expression, IContext } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Parse an expression string into an Expression AST
|
|
9
|
+
* @param expr - Expression string to parse
|
|
10
|
+
* @returns Expression AST
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseExpression(expr: string): Expression;
|
|
13
|
+
/**
|
|
14
|
+
* Evaluate an expression in a given context
|
|
15
|
+
* @param expr - Expression to evaluate
|
|
16
|
+
* @param context - Variable context
|
|
17
|
+
* @returns Evaluated value
|
|
18
|
+
*/
|
|
19
|
+
export declare function evaluateExpression(expr: Expression, context: IContext): unknown;
|
|
20
|
+
//# sourceMappingURL=evaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../src/evaluator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEtD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CA2GxD;AA6CD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,CA+C/E"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe expression evaluator
|
|
3
|
+
* Evaluates expressions WITHOUT using eval() or new Function()
|
|
4
|
+
* Only allows whitelisted operations
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Parse an expression string into an Expression AST
|
|
8
|
+
* @param expr - Expression string to parse
|
|
9
|
+
* @returns Expression AST
|
|
10
|
+
*/
|
|
11
|
+
export function parseExpression(expr) {
|
|
12
|
+
expr = expr.trim();
|
|
13
|
+
// Handle boolean literals
|
|
14
|
+
if (expr === 'true') {
|
|
15
|
+
return { type: 'literal', value: true };
|
|
16
|
+
}
|
|
17
|
+
if (expr === 'false') {
|
|
18
|
+
return { type: 'literal', value: false };
|
|
19
|
+
}
|
|
20
|
+
if (expr === 'null') {
|
|
21
|
+
return { type: 'literal', value: null };
|
|
22
|
+
}
|
|
23
|
+
// Handle string literals (double quotes)
|
|
24
|
+
if (expr.startsWith('"') && expr.endsWith('"')) {
|
|
25
|
+
return { type: 'literal', value: expr.slice(1, -1) };
|
|
26
|
+
}
|
|
27
|
+
// Handle string literals (single quotes)
|
|
28
|
+
if (expr.startsWith("'") && expr.endsWith("'")) {
|
|
29
|
+
return { type: 'literal', value: expr.slice(1, -1) };
|
|
30
|
+
}
|
|
31
|
+
// Handle number literals
|
|
32
|
+
if (/^-?\d+(\.\d+)?$/.test(expr)) {
|
|
33
|
+
return { type: 'literal', value: parseFloat(expr) };
|
|
34
|
+
}
|
|
35
|
+
// Handle parenthesized expressions
|
|
36
|
+
if (expr.startsWith('(') && expr.endsWith(')')) {
|
|
37
|
+
// Check if parentheses are balanced for the entire expression
|
|
38
|
+
let depth = 0;
|
|
39
|
+
let balanced = true;
|
|
40
|
+
for (let i = 0; i < expr.length; i++) {
|
|
41
|
+
if (expr[i] === '(') {
|
|
42
|
+
depth++;
|
|
43
|
+
}
|
|
44
|
+
else if (expr[i] === ')') {
|
|
45
|
+
depth--;
|
|
46
|
+
}
|
|
47
|
+
// If depth hits 0 before the end, the outer parens aren't wrapping everything
|
|
48
|
+
if (depth === 0 && i < expr.length - 1) {
|
|
49
|
+
balanced = false;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// If balanced, unwrap and recursively parse
|
|
54
|
+
if (balanced && depth === 0) {
|
|
55
|
+
return parseExpression(expr.slice(1, -1));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Handle logical NOT
|
|
59
|
+
if (expr.startsWith('not ')) {
|
|
60
|
+
return {
|
|
61
|
+
type: 'unary',
|
|
62
|
+
operator: 'not',
|
|
63
|
+
operand: parseExpression(expr.substring(4))
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// Handle logical OR (lowest precedence)
|
|
67
|
+
const orMatch = findOperator(expr, ' or ');
|
|
68
|
+
if (orMatch !== -1) {
|
|
69
|
+
return {
|
|
70
|
+
type: 'binary',
|
|
71
|
+
operator: 'or',
|
|
72
|
+
left: parseExpression(expr.substring(0, orMatch)),
|
|
73
|
+
right: parseExpression(expr.substring(orMatch + 4))
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// Handle logical AND
|
|
77
|
+
const andMatch = findOperator(expr, ' and ');
|
|
78
|
+
if (andMatch !== -1) {
|
|
79
|
+
return {
|
|
80
|
+
type: 'binary',
|
|
81
|
+
operator: 'and',
|
|
82
|
+
left: parseExpression(expr.substring(0, andMatch)),
|
|
83
|
+
right: parseExpression(expr.substring(andMatch + 5))
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// Handle comparison operators
|
|
87
|
+
const comparisonOps = ['==', '!=', '<=', '>=', '<', '>'];
|
|
88
|
+
for (const op of comparisonOps) {
|
|
89
|
+
const opMatch = findOperator(expr, ` ${op} `);
|
|
90
|
+
if (opMatch !== -1) {
|
|
91
|
+
return {
|
|
92
|
+
type: 'binary',
|
|
93
|
+
operator: op,
|
|
94
|
+
left: parseExpression(expr.substring(0, opMatch)),
|
|
95
|
+
right: parseExpression(expr.substring(opMatch + op.length + 2))
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Handle simple variable lookup (with dot notation)
|
|
100
|
+
if (/^[\w.]+$/.test(expr)) {
|
|
101
|
+
return { type: 'variable', name: expr };
|
|
102
|
+
}
|
|
103
|
+
// If we can't parse it, throw an error
|
|
104
|
+
throw new Error(`Invalid expression: ${expr}`);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Find the position of an operator, respecting string literals
|
|
108
|
+
* @param expr - Expression string
|
|
109
|
+
* @param operator - Operator to find
|
|
110
|
+
* @returns Position of operator or -1 if not found
|
|
111
|
+
*/
|
|
112
|
+
function findOperator(expr, operator) {
|
|
113
|
+
let inString = null;
|
|
114
|
+
let depth = 0;
|
|
115
|
+
for (let i = 0; i < expr.length; i++) {
|
|
116
|
+
const char = expr[i];
|
|
117
|
+
// Track string literals
|
|
118
|
+
if ((char === '"' || char === "'") && (i === 0 || expr[i - 1] !== '\\')) {
|
|
119
|
+
if (inString === char) {
|
|
120
|
+
inString = null;
|
|
121
|
+
}
|
|
122
|
+
else if (inString === null) {
|
|
123
|
+
inString = char;
|
|
124
|
+
}
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
// Track parentheses depth
|
|
128
|
+
if (!inString) {
|
|
129
|
+
if (char === '(') {
|
|
130
|
+
depth++;
|
|
131
|
+
}
|
|
132
|
+
else if (char === ')') {
|
|
133
|
+
depth--;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Look for operator at depth 0, outside strings
|
|
137
|
+
if (!inString && depth === 0) {
|
|
138
|
+
if (expr.substring(i, i + operator.length) === operator) {
|
|
139
|
+
return i;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return -1;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Evaluate an expression in a given context
|
|
147
|
+
* @param expr - Expression to evaluate
|
|
148
|
+
* @param context - Variable context
|
|
149
|
+
* @returns Evaluated value
|
|
150
|
+
*/
|
|
151
|
+
export function evaluateExpression(expr, context) {
|
|
152
|
+
switch (expr.type) {
|
|
153
|
+
case 'literal':
|
|
154
|
+
return expr.value;
|
|
155
|
+
case 'variable':
|
|
156
|
+
return context.get(expr.name);
|
|
157
|
+
case 'binary': {
|
|
158
|
+
const left = evaluateExpression(expr.left, context);
|
|
159
|
+
const right = evaluateExpression(expr.right, context);
|
|
160
|
+
switch (expr.operator) {
|
|
161
|
+
case '==':
|
|
162
|
+
// eslint-disable-next-line eqeqeq
|
|
163
|
+
return left == right;
|
|
164
|
+
case '!=':
|
|
165
|
+
// eslint-disable-next-line eqeqeq
|
|
166
|
+
return left != right;
|
|
167
|
+
case '<':
|
|
168
|
+
return left < right;
|
|
169
|
+
case '>':
|
|
170
|
+
return left > right;
|
|
171
|
+
case '<=':
|
|
172
|
+
return left <= right;
|
|
173
|
+
case '>=':
|
|
174
|
+
return left >= right;
|
|
175
|
+
case 'and':
|
|
176
|
+
return isTruthy(left) && isTruthy(right);
|
|
177
|
+
case 'or':
|
|
178
|
+
return isTruthy(left) || isTruthy(right);
|
|
179
|
+
}
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
case 'unary': {
|
|
183
|
+
const operand = evaluateExpression(expr.operand, context);
|
|
184
|
+
switch (expr.operator) {
|
|
185
|
+
case 'not':
|
|
186
|
+
return !isTruthy(operand);
|
|
187
|
+
}
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return undefined;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Determine if a value is truthy in template context
|
|
195
|
+
* @param value - Value to check
|
|
196
|
+
* @returns true if truthy
|
|
197
|
+
*/
|
|
198
|
+
function isTruthy(value) {
|
|
199
|
+
if (value === undefined || value === null || value === false) {
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
if (value === 0 || value === '') {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=evaluator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluator.js","sourceRoot":"","sources":["../src/evaluator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* minja - Minimal, secure Jinja2/Nunjucks subset
|
|
3
|
+
*
|
|
4
|
+
* A template engine designed for documentation preprocessing with:
|
|
5
|
+
* - Zero arbitrary code execution
|
|
6
|
+
* - Safe variable substitution and conditionals
|
|
7
|
+
* - Nested includes support
|
|
8
|
+
* - Standard Jinja2/Nunjucks syntax
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
export { render } from './renderer.js';
|
|
13
|
+
export { parse } from './parser.js';
|
|
14
|
+
export { parseExpression, evaluateExpression } from './evaluator.js';
|
|
15
|
+
export { Context, type ContextOptions } from './context.js';
|
|
16
|
+
export { FetchLoader, FileSystemLoader, MemoryLoader } from './loader.js';
|
|
17
|
+
export type { ASTNode, TextNode, VariableNode, SetNode, IfNode, IncludeNode, CommentNode, Expression, LiteralExpression, VariableExpression, BinaryExpression, UnaryExpression, RenderOptions, Loader, IContext, ParseResult, ParseError, } from './types.js';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACpE,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEzE,YAAY,EAEV,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,MAAM,EACN,WAAW,EACX,WAAW,EAGX,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EAGf,aAAa,EACb,MAAM,EACN,QAAQ,EACR,WAAW,EACX,UAAU,GACX,MAAM,YAAY,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* minja - Minimal, secure Jinja2/Nunjucks subset
|
|
3
|
+
*
|
|
4
|
+
* A template engine designed for documentation preprocessing with:
|
|
5
|
+
* - Zero arbitrary code execution
|
|
6
|
+
* - Safe variable substitution and conditionals
|
|
7
|
+
* - Nested includes support
|
|
8
|
+
* - Standard Jinja2/Nunjucks syntax
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
export { render } from './renderer.js';
|
|
13
|
+
export { parse } from './parser.js';
|
|
14
|
+
export { parseExpression, evaluateExpression } from './evaluator.js';
|
|
15
|
+
export { Context } from './context.js';
|
|
16
|
+
export { FetchLoader, FileSystemLoader, MemoryLoader } from './loader.js';
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACpE,OAAO,EAAE,OAAO,EAAuB,MAAM,cAAc,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA"}
|