@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.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +603 -0
  3. package/bin/minja.js +1062 -0
  4. package/dist/browser.d.ts +11 -0
  5. package/dist/browser.d.ts.map +1 -0
  6. package/dist/browser.js +10 -0
  7. package/dist/browser.js.map +1 -0
  8. package/dist/cli.d.ts +5 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +97 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/context.d.ts +47 -0
  13. package/dist/context.d.ts.map +1 -0
  14. package/dist/context.js +112 -0
  15. package/dist/context.js.map +1 -0
  16. package/dist/evaluator.d.ts +20 -0
  17. package/dist/evaluator.d.ts.map +1 -0
  18. package/dist/evaluator.js +207 -0
  19. package/dist/evaluator.js.map +1 -0
  20. package/dist/index.d.ts +18 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +17 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/index.umd.js +1026 -0
  25. package/dist/index.umd.js.map +7 -0
  26. package/dist/index.umd.min.js +9 -0
  27. package/dist/index.umd.min.js.map +7 -0
  28. package/dist/loader-fetch.d.ts +8 -0
  29. package/dist/loader-fetch.d.ts.map +1 -0
  30. package/dist/loader-fetch.js +15 -0
  31. package/dist/loader-fetch.js.map +1 -0
  32. package/dist/loader-memory.d.ts +11 -0
  33. package/dist/loader-memory.d.ts.map +1 -0
  34. package/dist/loader-memory.js +36 -0
  35. package/dist/loader-memory.js.map +1 -0
  36. package/dist/loader.d.ts +54 -0
  37. package/dist/loader.d.ts.map +1 -0
  38. package/dist/loader.js +91 -0
  39. package/dist/loader.js.map +1 -0
  40. package/dist/parser.d.ts +12 -0
  41. package/dist/parser.d.ts.map +1 -0
  42. package/dist/parser.js +501 -0
  43. package/dist/parser.js.map +1 -0
  44. package/dist/renderer.d.ts +13 -0
  45. package/dist/renderer.d.ts.map +1 -0
  46. package/dist/renderer.js +415 -0
  47. package/dist/renderer.js.map +1 -0
  48. package/dist/types.d.ts +150 -0
  49. package/dist/types.d.ts.map +1 -0
  50. package/dist/types.js +5 -0
  51. package/dist/types.js.map +1 -0
  52. 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"}
@@ -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,5 @@
1
+ /**
2
+ * Minja CLI - Command-line interface for template rendering
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=cli.d.ts.map
@@ -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
@@ -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"}
@@ -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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"}
@@ -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"}