Skip to content

Commit d9e8b9a

Browse files
committed
feat(core): add has output visitor to check wether the template has any valid output
1 parent 79d4e1f commit d9e8b9a

File tree

6 files changed

+89
-1
lines changed

6 files changed

+89
-1
lines changed

packages/core/src/lib/template-engine/compiler.ts

+1
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ export interface CompileResult {
2626
export interface Compiler {
2727
name: string;
2828
compile(template: string): CompileResult;
29+
execute<T extends object>(template: string, data: T): Promise<any>;
2930
render<T extends object>(templateName: string, data: T): Promise<string>;
3031
}

packages/core/src/lib/template-engine/nunjucksCompiler.ts

+20-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
ErrorsVisitor,
1515
FiltersVisitor,
1616
BuilderValueVisitor,
17+
HasOutputValueVisitor,
1718
} from './visitors';
1819
import { inject, injectable, multiInject, optional } from 'inversify';
1920
import { TYPES } from '@vulcan/core/containers';
@@ -53,6 +54,16 @@ export class NunjucksCompiler implements Compiler {
5354
return { ast: preProcessedAst, metadata };
5455
}
5556

57+
public async execute<T extends object>(
58+
templateName: string,
59+
data: T
60+
): Promise<any> {
61+
const template = this.env.getTemplate(templateName, true);
62+
63+
// const query = await this.render(template, data);
64+
// console.log(data);
65+
}
66+
5667
public async render<T extends object>(
5768
templateName: string,
5869
data: T
@@ -93,10 +104,18 @@ export class NunjucksCompiler implements Compiler {
93104
const errors = new ErrorsVisitor();
94105
const filters = new FiltersVisitor({ env: this.env });
95106
const builderValueVisitor = new BuilderValueVisitor();
96-
walkAst(ast, [parameters, errors, filters, builderValueVisitor]);
107+
const hasOutputVisitor = new HasOutputValueVisitor();
108+
walkAst(ast, [
109+
parameters,
110+
errors,
111+
filters,
112+
builderValueVisitor,
113+
hasOutputVisitor,
114+
]);
97115
return {
98116
parameters: parameters.getParameters(),
99117
errors: errors.getErrors(),
118+
hasOutput: hasOutputVisitor.getHasOutput(),
100119
};
101120
}
102121

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Visitor } from './visitor';
2+
import * as nunjucks from 'nunjucks';
3+
4+
// Check whether the given tree has any output.
5+
6+
export class HasOutputValueVisitor implements Visitor {
7+
private hasOutput = false;
8+
9+
public visit(node: nunjucks.nodes.Node) {
10+
// If there is an output, we can stop visiting the tree.
11+
if (this.hasOutput) return;
12+
13+
if (
14+
node instanceof nunjucks.nodes.TemplateData &&
15+
this.trimOutput(node.value).length > 0
16+
) {
17+
this.hasOutput = true;
18+
}
19+
}
20+
21+
public getHasOutput(): boolean {
22+
return this.hasOutput;
23+
}
24+
25+
private trimOutput(output: string) {
26+
return output.replace(/[\r\n ]/g, '');
27+
}
28+
}

packages/core/src/lib/template-engine/visitors/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export * from './errorsVisitor';
44
export * from './filtersVisitor';
55
export * from './astWalker';
66
export * from './builderValueVisitor';
7+
export * from './hasOutputVisitor';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { HasOutputValueVisitor, walkAst } from '@vulcan/core/template-engine';
2+
import * as nunjucks from 'nunjucks';
3+
4+
const test = (template: string, expected: boolean) => {
5+
// Arrange
6+
const ast = nunjucks.parser.parse(template, [], {});
7+
const visitor = new HasOutputValueVisitor();
8+
// Act
9+
walkAst(ast, [visitor]);
10+
const hasOutput = visitor.getHasOutput();
11+
// Assert
12+
expect(hasOutput).toBe(expected);
13+
};
14+
15+
it('Should return false if there is no valid output', async () => {
16+
test(
17+
`
18+
{{ params.a }}
19+
{% if params.b %}
20+
{{ params.c }}
21+
{% endif %}
22+
`,
23+
false
24+
);
25+
});
26+
27+
it('Should return true if there are simple outputs', async () => {
28+
test(`select * from users;`, true);
29+
});
30+
31+
it('Should return true if there are outputs inside statements', async () => {
32+
test(`{% if 1 == 2 %}select * from users;{% endif %}`, true);
33+
});
34+
35+
it('(Known issue)Should return false if the output is looked from variables', async () => {
36+
test(`{% set query = "select * from users;" %}{{ query }}`, false);
37+
});

types/nunjucks.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,8 @@ declare module 'nunjucks' {
342342
body: Node | null;
343343
targets: Node[];
344344
}
345+
346+
class TemplateData extends Literal {}
345347
}
346348

347349
namespace lexer {

0 commit comments

Comments
 (0)