@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,415 @@
1
+ /**
2
+ * Template renderer
3
+ * Combines parser, evaluator, and loader to render templates
4
+ */
5
+ import { parse } from './parser.js';
6
+ import { Context } from './context.js';
7
+ import { evaluateExpression } from './evaluator.js';
8
+ import { FetchLoader } from './loader-fetch.js';
9
+ /**
10
+ * Transform markdown headings by applying level offset
11
+ * Clamps to valid markdown range (1-6)
12
+ * @param text - Text content to transform
13
+ * @param offset - Level offset to apply
14
+ * @returns Transformed text with adjusted heading levels
15
+ */
16
+ function transformHeadings(text, offset) {
17
+ if (offset === 0) {
18
+ return text;
19
+ }
20
+ // Match markdown headings: # through ######
21
+ return text.replace(/^(#{1,6})(\s+)/gm, (_match, hashes, space) => {
22
+ const currentLevel = hashes.length;
23
+ const newLevel = Math.max(1, Math.min(6, currentLevel + offset));
24
+ return '#'.repeat(newLevel) + space;
25
+ });
26
+ }
27
+ /**
28
+ * Resolve a relative path against a base path
29
+ * @param path - Relative or absolute path
30
+ * @param basePath - Base path to resolve against
31
+ * @returns Resolved path
32
+ */
33
+ function resolvePath(path, basePath) {
34
+ // If path is absolute, return as-is
35
+ if (path.startsWith('/')) {
36
+ return path;
37
+ }
38
+ // Ensure basePath ends with /
39
+ const base = basePath.endsWith('/') ? basePath : basePath + '/';
40
+ // Combine and normalize
41
+ const combined = base + path;
42
+ // Normalize . and .. segments
43
+ const parts = combined.split('/');
44
+ const resolved = [];
45
+ for (const part of parts) {
46
+ if (part === '.' || part === '') {
47
+ continue;
48
+ }
49
+ else if (part === '..') {
50
+ resolved.pop();
51
+ }
52
+ else {
53
+ resolved.push(part);
54
+ }
55
+ }
56
+ // Preserve leading slash if original had one
57
+ const prefix = combined.startsWith('/') ? '/' : '';
58
+ return prefix + resolved.join('/');
59
+ }
60
+ /**
61
+ * Render a template string
62
+ * @param template - Template string to render
63
+ * @param options - Render options
64
+ * @returns Rendered output
65
+ */
66
+ export async function render(template, options = {}) {
67
+ const { loader = new FetchLoader(), context: initialContext = {}, basePath = '', maxIncludeDepth = 10, timeout = 5000, hyphenToUnderscore = false, undefinedBehavior = 'empty', } = options;
68
+ // Create timeout promise
69
+ const timeoutPromise = new Promise((_, reject) => {
70
+ setTimeout(() => reject(new Error('Template rendering timeout')), timeout);
71
+ });
72
+ // Render with timeout
73
+ const renderPromise = renderInternal(template, {
74
+ loader,
75
+ context: Context.from({
76
+ ...initialContext,
77
+ // Built-in variables
78
+ date: new Date().toISOString().split('T')[0],
79
+ timestamp: Date.now(),
80
+ _levelOffset: 0,
81
+ }, { hyphenToUnderscore }),
82
+ includeDepth: 0,
83
+ maxIncludeDepth,
84
+ basePath,
85
+ undefinedBehavior,
86
+ });
87
+ return await Promise.race([renderPromise, timeoutPromise]);
88
+ }
89
+ /**
90
+ * Internal rendering function with depth tracking
91
+ */
92
+ async function renderInternal(template, options) {
93
+ const { includeDepth, maxIncludeDepth } = options;
94
+ // Check recursion depth
95
+ if (includeDepth > maxIncludeDepth) {
96
+ throw new Error(`Maximum include depth (${maxIncludeDepth}) exceeded`);
97
+ }
98
+ // Parse template
99
+ const parseResult = parse(template);
100
+ if (parseResult.errors.length > 0) {
101
+ const errorMessages = parseResult.errors.map((e) => e.message).join(', ');
102
+ throw new Error(`Parse errors: ${errorMessages}`);
103
+ }
104
+ // Render AST
105
+ return await renderNodes(parseResult.ast, options);
106
+ }
107
+ /**
108
+ * Render an array of AST nodes
109
+ */
110
+ async function renderNodes(nodes, options) {
111
+ const parts = [];
112
+ for (const node of nodes) {
113
+ parts.push(await renderNode(node, options));
114
+ }
115
+ return parts.join('');
116
+ }
117
+ /**
118
+ * Render a single AST node
119
+ */
120
+ async function renderNode(node, options) {
121
+ const { loader, context, includeDepth, maxIncludeDepth, basePath } = options;
122
+ switch (node.type) {
123
+ case 'text': {
124
+ // Apply leveloffset if active
125
+ const currentOffset = context.get('_levelOffset') || 0;
126
+ if (currentOffset === 0) {
127
+ return node.value;
128
+ }
129
+ return transformHeadings(node.value, currentOffset);
130
+ }
131
+ case 'variable': {
132
+ const value = context.get(node.name);
133
+ if (value === undefined || value === null) {
134
+ // Apply the undefined-variable policy. See RenderOptions.undefinedBehavior.
135
+ switch (options.undefinedBehavior) {
136
+ case 'throw':
137
+ throw new Error(`Undefined variable: ${node.name}`);
138
+ case 'preserve':
139
+ // Round-trip the source form so downstream tooling (or a
140
+ // second-pass minja run with the value supplied) can pick
141
+ // up where we left off.
142
+ return `{{ ${node.name} }}`;
143
+ case 'empty':
144
+ default:
145
+ return '';
146
+ }
147
+ }
148
+ const str = String(value);
149
+ // If the value contains template syntax, re-process it
150
+ if (str.includes('{{') || str.includes('{%')) {
151
+ return await renderInternal(str, options);
152
+ }
153
+ return str;
154
+ }
155
+ case 'set': {
156
+ const value = evaluateExpression(node.value, context);
157
+ context.set(node.name, value);
158
+ return '';
159
+ }
160
+ case 'comment':
161
+ return '';
162
+ case 'if': {
163
+ // In preserve mode, an `if` whose condition references an
164
+ // undefined identifier can't be evaluated — we don't know
165
+ // which branch to take. Preserve the whole `{% if … %}…{% endif %}`
166
+ // verbatim so a second pass (with the value supplied) can
167
+ // resolve it. See plans/format-asciidoc-import.md.
168
+ if (options.undefinedBehavior === 'preserve') {
169
+ const undefinedRefs = findUndefinedRefs(node.condition, context);
170
+ if (undefinedRefs.length > 0) {
171
+ return ifNodeToSource(node);
172
+ }
173
+ if (node.elifBranches) {
174
+ for (const elif of node.elifBranches) {
175
+ if (findUndefinedRefs(elif.condition, context).length > 0) {
176
+ return ifNodeToSource(node);
177
+ }
178
+ }
179
+ }
180
+ }
181
+ const condition = evaluateExpression(node.condition, context);
182
+ if (isTruthy(condition)) {
183
+ return await renderNodes(node.trueBranch, options);
184
+ }
185
+ // Check elif branches
186
+ if (node.elifBranches) {
187
+ for (const elifBranch of node.elifBranches) {
188
+ const elifCondition = evaluateExpression(elifBranch.condition, context);
189
+ if (isTruthy(elifCondition)) {
190
+ return await renderNodes(elifBranch.body, options);
191
+ }
192
+ }
193
+ }
194
+ // Render else branch if present
195
+ if (node.elseBranch) {
196
+ return await renderNodes(node.elseBranch, options);
197
+ }
198
+ return '';
199
+ }
200
+ case 'include': {
201
+ try {
202
+ // Load the included file
203
+ const includedContent = await loader.load(node.path, basePath);
204
+ // Determine new base path for nested includes
205
+ let newBasePath = basePath;
206
+ // If path looks like a URL, extract base
207
+ if (node.path.includes('://')) {
208
+ const url = new URL(node.path);
209
+ newBasePath = url.href.substring(0, url.href.lastIndexOf('/') + 1);
210
+ }
211
+ else if (basePath) {
212
+ // Relative path - resolve against current base
213
+ if (basePath.includes('://')) {
214
+ const url = new URL(node.path, basePath);
215
+ newBasePath = url.href.substring(0, url.href.lastIndexOf('/') + 1);
216
+ }
217
+ else {
218
+ // File path - resolve relative to current base and extract directory
219
+ const resolvedPath = resolvePath(node.path, basePath);
220
+ const lastSlash = resolvedPath.lastIndexOf('/');
221
+ newBasePath = lastSlash >= 0 ? resolvedPath.substring(0, lastSlash + 1) : basePath;
222
+ }
223
+ }
224
+ else if (node.path.includes('/')) {
225
+ // No base path but include has directory - use that as base
226
+ const lastSlash = node.path.lastIndexOf('/');
227
+ newBasePath = node.path.substring(0, lastSlash + 1);
228
+ }
229
+ // Render the included template (recursive)
230
+ return await renderInternal(includedContent, {
231
+ loader,
232
+ context,
233
+ includeDepth: includeDepth + 1,
234
+ maxIncludeDepth,
235
+ basePath: newBasePath,
236
+ undefinedBehavior: options.undefinedBehavior,
237
+ });
238
+ }
239
+ catch (error) {
240
+ // In `preserve` mode, an unresolvable include is preserved
241
+ // as the original directive so a later renderer pass (with
242
+ // the file in place) can resolve it. Matches the semantic
243
+ // of `preserve` for undefined variables. Without this,
244
+ // multi-stage pipelines (e.g. dogsbay's convert + build
245
+ // preprocessor for AsciiDoc imports) lose the directive at
246
+ // stage 1 because targets only exist after stage 2 has
247
+ // converted sibling files.
248
+ if (options.undefinedBehavior === 'preserve') {
249
+ return `{% include "${node.path}" %}`;
250
+ }
251
+ const message = error instanceof Error ? error.message : String(error);
252
+ console.error(`Failed to include ${node.path}:`, message);
253
+ return `<!-- Include error: ${node.path} -->`;
254
+ }
255
+ }
256
+ case 'switch': {
257
+ const switchValue = evaluateExpression(node.expression, context);
258
+ // Find matching case
259
+ for (const caseItem of node.cases) {
260
+ const caseValue = evaluateExpression(caseItem.value, context);
261
+ // eslint-disable-next-line eqeqeq
262
+ if (switchValue == caseValue) {
263
+ return await renderNodes(caseItem.body, options);
264
+ }
265
+ }
266
+ // No matching case found
267
+ return '';
268
+ }
269
+ case 'leveloffset': {
270
+ // Calculate new offset (relative or absolute)
271
+ const parentOffset = context.get('_levelOffset') || 0;
272
+ const newOffset = node.isRelative ? parentOffset + node.offset : node.offset;
273
+ // Store current offset to restore later
274
+ const previousOffset = parentOffset;
275
+ // Set new offset in context
276
+ context.set('_levelOffset', newOffset);
277
+ try {
278
+ // Render body with offset active
279
+ const result = await renderNodes(node.body, options);
280
+ return result;
281
+ }
282
+ finally {
283
+ // Always restore previous offset
284
+ context.set('_levelOffset', previousOffset);
285
+ }
286
+ }
287
+ default:
288
+ // TypeScript exhaustiveness check
289
+ const _exhaustive = node;
290
+ return _exhaustive;
291
+ }
292
+ }
293
+ /**
294
+ * Determine if a value is truthy
295
+ */
296
+ function isTruthy(value) {
297
+ if (value === undefined || value === null || value === false) {
298
+ return false;
299
+ }
300
+ if (value === 0 || value === '') {
301
+ return false;
302
+ }
303
+ return true;
304
+ }
305
+ // ============================================================================
306
+ // Preserve-mode helpers — round-trip AST back to Jinja source so an
307
+ // undefined-referencing block can survive into the rendered output for
308
+ // a downstream pass to resolve.
309
+ // ============================================================================
310
+ /**
311
+ * Walk an expression AST, return the names of any `variable` references
312
+ * whose context lookup is undefined. Empty array = all refs are bound.
313
+ */
314
+ function findUndefinedRefs(expr, context) {
315
+ const out = [];
316
+ function walk(e) {
317
+ switch (e.type) {
318
+ case 'variable':
319
+ if (context.get(e.name) === undefined)
320
+ out.push(e.name);
321
+ break;
322
+ case 'binary':
323
+ walk(e.left);
324
+ walk(e.right);
325
+ break;
326
+ case 'unary':
327
+ walk(e.operand);
328
+ break;
329
+ case 'literal':
330
+ break;
331
+ }
332
+ }
333
+ walk(expr);
334
+ return out;
335
+ }
336
+ /**
337
+ * Serialize an Expression back to Jinja source. Used by preserve mode
338
+ * to reconstruct `{% if … %}` headers when the condition can't be
339
+ * evaluated. Operator precedence isn't tracked; the output is
340
+ * conservatively parenthesized for binary/unary so a re-parse round-
341
+ * trips to the same AST shape (modulo redundant parens).
342
+ */
343
+ function expressionToSource(expr) {
344
+ switch (expr.type) {
345
+ case 'literal':
346
+ if (typeof expr.value === 'string')
347
+ return JSON.stringify(expr.value);
348
+ if (expr.value === null)
349
+ return 'null';
350
+ return String(expr.value);
351
+ case 'variable':
352
+ return expr.name;
353
+ case 'unary':
354
+ return `not ${expressionToSource(expr.operand)}`;
355
+ case 'binary':
356
+ return `(${expressionToSource(expr.left)} ${expr.operator} ${expressionToSource(expr.right)})`;
357
+ }
358
+ }
359
+ /**
360
+ * Serialize ASTNode[] back to Jinja source. Mirrors the parser's syntax
361
+ * for every node type so a preserved block can be re-rendered later
362
+ * with the missing values supplied.
363
+ *
364
+ * Throws on shapes we don't support (deep nested includes, switch);
365
+ * preserve mode is opt-in and a hard error here beats silent
366
+ * truncation. The shapes covered are everything md2md emits in the
367
+ * AsciiDoc pipeline.
368
+ */
369
+ function nodesToSource(nodes) {
370
+ return nodes.map(nodeToSource).join('');
371
+ }
372
+ function nodeToSource(node) {
373
+ switch (node.type) {
374
+ case 'text':
375
+ return node.value;
376
+ case 'variable':
377
+ return `{{ ${node.name} }}`;
378
+ case 'set':
379
+ return `{% set ${node.name} = ${expressionToSource(node.value)} %}`;
380
+ case 'comment':
381
+ // Parser strips comment content; emit a placeholder so the block
382
+ // structure round-trips even when the prose inside doesn't.
383
+ return '{# … #}';
384
+ case 'if':
385
+ return ifNodeToSource(node);
386
+ case 'include':
387
+ return `{% include "${node.path}" %}`;
388
+ case 'leveloffset': {
389
+ const sign = node.isRelative && node.offset >= 0 ? '+' : '';
390
+ return `{% leveloffset ${sign}${node.offset} %}${nodesToSource(node.body)}{% endleveloffset %}`;
391
+ }
392
+ case 'switch': {
393
+ // Conservative round-trip; switch isn't on the AsciiDoc hot path
394
+ // but we have an AST shape, so emit it.
395
+ const cases = node.cases
396
+ .map((c) => `{% case ${expressionToSource(c.value)} %}${nodesToSource(c.body)}`)
397
+ .join('');
398
+ return `{% switch ${expressionToSource(node.expression)} %}${cases}{% endswitch %}`;
399
+ }
400
+ }
401
+ }
402
+ function ifNodeToSource(node) {
403
+ const parts = [`{% if ${expressionToSource(node.condition)} %}`, nodesToSource(node.trueBranch)];
404
+ if (node.elifBranches) {
405
+ for (const elif of node.elifBranches) {
406
+ parts.push(`{% elif ${expressionToSource(elif.condition)} %}`, nodesToSource(elif.body));
407
+ }
408
+ }
409
+ if (node.elseBranch) {
410
+ parts.push(`{% else %}`, nodesToSource(node.elseBranch));
411
+ }
412
+ parts.push(`{% endif %}`);
413
+ return parts.join('');
414
+ }
415
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Type definitions for minja template engine
3
+ */
4
+ export type ASTNode = TextNode | VariableNode | SetNode | IfNode | IncludeNode | CommentNode | SwitchNode | LeveloffsetNode;
5
+ export interface TextNode {
6
+ type: 'text';
7
+ value: string;
8
+ }
9
+ export interface VariableNode {
10
+ type: 'variable';
11
+ name: string;
12
+ }
13
+ export interface SetNode {
14
+ type: 'set';
15
+ name: string;
16
+ value: Expression;
17
+ }
18
+ export interface IfNode {
19
+ type: 'if';
20
+ condition: Expression;
21
+ trueBranch: ASTNode[];
22
+ elifBranches?: Array<{
23
+ condition: Expression;
24
+ body: ASTNode[];
25
+ }>;
26
+ elseBranch?: ASTNode[];
27
+ }
28
+ export interface IncludeNode {
29
+ type: 'include';
30
+ path: string;
31
+ }
32
+ export interface CommentNode {
33
+ type: 'comment';
34
+ value: string;
35
+ }
36
+ export interface SwitchNode {
37
+ type: 'switch';
38
+ expression: Expression;
39
+ cases: Array<{
40
+ value: Expression;
41
+ body: ASTNode[];
42
+ }>;
43
+ }
44
+ export interface LeveloffsetNode {
45
+ type: 'leveloffset';
46
+ offset: number;
47
+ isRelative: boolean;
48
+ body: ASTNode[];
49
+ }
50
+ export type Expression = LiteralExpression | VariableExpression | BinaryExpression | UnaryExpression;
51
+ export interface LiteralExpression {
52
+ type: 'literal';
53
+ value: string | number | boolean | null;
54
+ }
55
+ export interface VariableExpression {
56
+ type: 'variable';
57
+ name: string;
58
+ }
59
+ export interface BinaryExpression {
60
+ type: 'binary';
61
+ operator: '==' | '!=' | '<' | '>' | '<=' | '>=' | 'and' | 'or';
62
+ left: Expression;
63
+ right: Expression;
64
+ }
65
+ export interface UnaryExpression {
66
+ type: 'unary';
67
+ operator: 'not';
68
+ operand: Expression;
69
+ }
70
+ export interface Loader {
71
+ /**
72
+ * Load a file from the given path.
73
+ * @param path - The path to load (can be relative or absolute)
74
+ * @param basePath - The base path to resolve relative paths against
75
+ * @returns The file contents as a string
76
+ */
77
+ load(path: string, basePath?: string): Promise<string>;
78
+ }
79
+ export interface RenderOptions {
80
+ /**
81
+ * File loader for {% include %} statements
82
+ */
83
+ loader?: Loader;
84
+ /**
85
+ * Initial context (variables)
86
+ */
87
+ context?: Record<string, unknown>;
88
+ /**
89
+ * Base path for resolving relative includes (e.g., current file URL)
90
+ */
91
+ basePath?: string;
92
+ /**
93
+ * Maximum include depth (default: 10)
94
+ */
95
+ maxIncludeDepth?: number;
96
+ /**
97
+ * Timeout in milliseconds (default: 5000)
98
+ */
99
+ timeout?: number;
100
+ /**
101
+ * Convert hyphenated variable names to underscores during lookup.
102
+ * When true, {{ my-var }} will look up 'my_var' in the context.
103
+ * (default: false)
104
+ */
105
+ hyphenToUnderscore?: boolean;
106
+ /**
107
+ * What to do when a `{{ var }}` references an identifier that
108
+ * isn't in the context.
109
+ *
110
+ * - `'empty'` (default) — emit an empty string. Unchanged behaviour
111
+ * for existing callers; matches the standard Nunjucks default.
112
+ * - `'throw'` — throw `Error('Undefined variable: <name>')`. Useful
113
+ * in strict pipelines that want to fail-fast on typos.
114
+ * - `'preserve'` — emit the literal `{{ <name> }}` (or `{% if … %}…`
115
+ * for conditionals whose condition references undefined vars).
116
+ * Used by the AsciiDoc convert pipeline so unresolved attributes
117
+ * survive into the post-render artifact for downstream resolution.
118
+ * See plans/format-asciidoc-import.md.
119
+ */
120
+ undefinedBehavior?: 'empty' | 'throw' | 'preserve';
121
+ }
122
+ export interface IContext {
123
+ /**
124
+ * Get a variable from the context
125
+ */
126
+ get(name: string): unknown;
127
+ /**
128
+ * Set a variable in the context
129
+ */
130
+ set(name: string, value: unknown): void;
131
+ /**
132
+ * Create a child scope
133
+ */
134
+ push(): IContext;
135
+ /**
136
+ * Return to parent scope
137
+ */
138
+ pop(): IContext | null;
139
+ }
140
+ export interface ParseResult {
141
+ ast: ASTNode[];
142
+ errors: ParseError[];
143
+ }
144
+ export interface ParseError {
145
+ message: string;
146
+ position: number;
147
+ line: number;
148
+ column: number;
149
+ }
150
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Type definitions for minja template engine
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@dogsbay/minja",
3
+ "version": "0.2.0-beta.48",
4
+ "description": "Minimal, secure Jinja2/Nunjucks subset for documentation preprocessing with zero code execution",
5
+ "keywords": [
6
+ "template",
7
+ "jinja2",
8
+ "nunjucks",
9
+ "asciidoc",
10
+ "documentation",
11
+ "secure",
12
+ "sandbox",
13
+ "safe"
14
+ ],
15
+ "author": "",
16
+ "license": "MIT",
17
+ "type": "module",
18
+ "main": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
20
+ "exports": {
21
+ ".": {
22
+ "import": {
23
+ "types": "./dist/index.d.ts",
24
+ "default": "./dist/index.js"
25
+ },
26
+ "require": {
27
+ "types": "./dist/index.d.ts",
28
+ "default": "./dist/index.js"
29
+ }
30
+ }
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "bin"
35
+ ],
36
+ "bin": {
37
+ "minja": "./bin/minja.js"
38
+ },
39
+ "sideEffects": false,
40
+ "dependencies": {
41
+ "commander": "^12.0.0",
42
+ "yaml": "^2.3.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^20.0.0",
46
+ "esbuild": "^0.19.0",
47
+ "typescript": "^5.7.3",
48
+ "vitest": "^2.1.9"
49
+ },
50
+ "engines": {
51
+ "node": ">=18.0.0"
52
+ },
53
+ "scripts": {
54
+ "build": "node build.mjs",
55
+ "dev": "node build.mjs --watch",
56
+ "test": "vitest run",
57
+ "test:watch": "vitest",
58
+ "test:coverage": "vitest run --coverage",
59
+ "lint": "tsc --noEmit",
60
+ "format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\""
61
+ }
62
+ }