@tsed/engines 8.0.0 → 8.0.2

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 (50) hide show
  1. package/package.json +4 -3
  2. package/src/components/AtplEngine.ts +5 -0
  3. package/src/components/BracketEngine.ts +11 -0
  4. package/src/components/DotEngine.ts +14 -0
  5. package/src/components/DustEngine.ts +55 -0
  6. package/src/components/EctEngine.ts +24 -0
  7. package/src/components/EjsEngine.ts +5 -0
  8. package/src/components/Engine.ts +87 -0
  9. package/src/components/HamlCoffeeEngine.ts +5 -0
  10. package/src/components/HamlEngine.ts +12 -0
  11. package/src/components/HamletEngine.ts +12 -0
  12. package/src/components/HandlebarsEngine.ts +19 -0
  13. package/src/components/HoganEngine.spec.ts +79 -0
  14. package/src/components/HoganEngine.ts +14 -0
  15. package/src/components/HtmlingEngine.ts +11 -0
  16. package/src/components/JazzEngine.ts +10 -0
  17. package/src/components/JqtplEngine.ts +10 -0
  18. package/src/components/JustEngine.ts +24 -0
  19. package/src/components/LiquorEngine.ts +5 -0
  20. package/src/components/LodashEngine.ts +14 -0
  21. package/src/components/MoteEngine.ts +5 -0
  22. package/src/components/MustacheEngine.ts +9 -0
  23. package/src/components/NunjucksEngine.ts +58 -0
  24. package/src/components/PlatesEngine.ts +12 -0
  25. package/src/components/PugEngine.spec.ts +50 -0
  26. package/src/components/PugEngine.ts +15 -0
  27. package/src/components/RactiveEngine.spec.ts +36 -0
  28. package/src/components/RactiveEngine.ts +34 -0
  29. package/src/components/ReactEngine.ts +163 -0
  30. package/src/components/SlmEngine.ts +5 -0
  31. package/src/components/SquirrellyEngine.spec.ts +98 -0
  32. package/src/components/SquirrellyEngine.ts +18 -0
  33. package/src/components/SwigEngine.ts +14 -0
  34. package/src/components/TemplayedEngine.ts +9 -0
  35. package/src/components/TwigEngine.spec.ts +44 -0
  36. package/src/components/TwigEngine.ts +24 -0
  37. package/src/components/TwingEngine.spec.ts +36 -0
  38. package/src/components/TwingEngine.ts +31 -0
  39. package/src/components/UnderscoreEngine.ts +26 -0
  40. package/src/components/VashEngine.ts +33 -0
  41. package/src/components/VelocityEngine.spec.ts +50 -0
  42. package/src/components/VelocityEngine.ts +11 -0
  43. package/src/components/WalrusEngine.ts +11 -0
  44. package/src/decorators/viewEngine.ts +8 -0
  45. package/src/index.ts +42 -0
  46. package/src/registries/EnginesContainer.ts +37 -0
  47. package/src/utils/cache.spec.ts +13 -0
  48. package/src/utils/cache.ts +154 -0
  49. package/src/utils/getEngines.spec.ts +133 -0
  50. package/src/utils/getEngines.ts +58 -0
@@ -0,0 +1,34 @@
1
+ import {ViewEngine} from "../decorators/viewEngine.js";
2
+ import {Engine, EngineOptions} from "./Engine.js";
3
+
4
+ @ViewEngine("ractive")
5
+ export class RactiveEngine extends Engine {
6
+ protected $compile(template: string, options: EngineOptions) {
7
+ const Engine = this.engine;
8
+ const compile = this.engine.parse(template);
9
+ Engine.DEBUG = false;
10
+ return (options: EngineOptions) => {
11
+ options.template = compile;
12
+ return new Engine(this.clean(options)).toHTML();
13
+ };
14
+ }
15
+
16
+ protected clean(options: any) {
17
+ if (options.data === null || options.data === undefined) {
18
+ // Shallow clone the options object
19
+ options.data = Object.assign({}, options);
20
+
21
+ // Remove consolidate-specific properties from the clone
22
+ let i;
23
+ let length;
24
+ let properties = ["template", "filename", "cache", "partials"];
25
+
26
+ for (i = 0, length = properties.length; i < length; i++) {
27
+ const property = properties[i];
28
+ delete options.data[property];
29
+ }
30
+ }
31
+
32
+ return options;
33
+ }
34
+ }
@@ -0,0 +1,163 @@
1
+ import {readFileSync} from "fs";
2
+ import {resolve} from "path";
3
+
4
+ import {ViewEngine} from "../decorators/viewEngine.js";
5
+ import {getCachedEngine, getFromCache, importEngine, setToCache} from "../utils/cache.js";
6
+ import {Engine, EngineOptions, ViewEngineOptions} from "./Engine.js";
7
+
8
+ @ViewEngine("react", {
9
+ requires: ["react"]
10
+ })
11
+ export class ReactEngine extends Engine {
12
+ constructor(name: string, options: ViewEngineOptions) {
13
+ super(name, options);
14
+ this.patchRequire();
15
+ }
16
+
17
+ async $onInit() {
18
+ await super.$onInit();
19
+ await importEngine("react-dom/server", "ReactDOM");
20
+ await importEngine("@babel/core", "babel");
21
+ }
22
+
23
+ get babel() {
24
+ return getCachedEngine("babel");
25
+ }
26
+
27
+ get reactDOM() {
28
+ return getCachedEngine("ReactDOM");
29
+ }
30
+
31
+ protected patchRequire() {
32
+ if (require.extensions) {
33
+ // Ensure JSX is transformed on require
34
+ if (!require.extensions[".jsx"]) {
35
+ require.extensions[".jsx"] = this.requireReact.bind(this);
36
+ }
37
+
38
+ // Supporting .react extension as well as test cases
39
+ // Using .react extension is not recommended.
40
+ if (!require.extensions[".react"]) {
41
+ require.extensions[".react"] = this.requireReact.bind(this);
42
+ }
43
+ }
44
+ }
45
+
46
+ protected configure(options: EngineOptions) {
47
+ const base = options.base;
48
+ delete options.base;
49
+
50
+ const enableCache = options.cache;
51
+ delete options.cache;
52
+
53
+ const isNonStatic = options.isNonStatic;
54
+ delete options.isNonStatic;
55
+ return {base, enableCache, isNonStatic};
56
+ }
57
+
58
+ protected $compile(template: string, options: EngineOptions) {
59
+ // Assign HTML Base
60
+ const {base, enableCache, isNonStatic} = this.configure(options);
61
+
62
+ // Start Conversion
63
+ const Code = this.requireReactString(template);
64
+ const Factory = this.engine.createFactory(Code);
65
+
66
+ return () => {
67
+ const parsed = new Factory(options);
68
+ const content = isNonStatic ? this.reactDOM.renderToString(parsed) : this.reactDOM.renderToStaticMarkup(parsed);
69
+
70
+ if (base) {
71
+ options.content = content;
72
+
73
+ return this.renderWithBase(template, base, enableCache, options);
74
+ }
75
+
76
+ return content;
77
+ };
78
+ }
79
+
80
+ protected async $compileFile(file: string, options: EngineOptions) {
81
+ // Assign HTML Base
82
+ const {base, enableCache, isNonStatic} = this.configure(options);
83
+
84
+ let path = resolve(file);
85
+ delete require.cache[path];
86
+
87
+ const ReactDOM = await importEngine("react-dom/server", "ReactDOM");
88
+
89
+ const {default: Code} = await import(path);
90
+ const Factory = this.engine.createFactory(Code);
91
+
92
+ return () => {
93
+ const parsed = new Factory(options);
94
+ const content = isNonStatic ? ReactDOM.renderToString(parsed) : ReactDOM.renderToStaticMarkup(parsed);
95
+
96
+ if (base) {
97
+ options.content = content;
98
+
99
+ return this.renderWithBase(file, base, enableCache, options);
100
+ }
101
+
102
+ return content;
103
+ };
104
+ }
105
+
106
+ protected renderWithBase(key: string, base: any, enableCache: undefined | boolean, options: EngineOptions) {
107
+ const baseStr = getFromCache(key) || readFileSync(resolve(base), "utf8");
108
+
109
+ if (enableCache) {
110
+ setToCache(key, baseStr);
111
+ }
112
+
113
+ return this.reactBaseTmpl(baseStr, options);
114
+ }
115
+
116
+ protected transformFileSync(filename: string) {
117
+ return this.babel.transformFileSync(filename, {presets: ["@babel/preset-react"]}).code;
118
+ }
119
+
120
+ protected transform(src: string) {
121
+ return this.babel.transform(src, {presets: ["@babel/preset-react"]}).code;
122
+ }
123
+
124
+ protected requireReact(module: any, filename: string) {
125
+ const compiled = this.transformFileSync(filename);
126
+ return module._compile(compiled, filename);
127
+ }
128
+
129
+ protected requireReactString(src: string, filename?: string) {
130
+ if (!filename) filename = "";
131
+ // @ts-ignore
132
+ const m = new module.constructor();
133
+ filename = filename || "";
134
+
135
+ // Compile Using React
136
+ const compiled = this.transform(src);
137
+
138
+ // Compile as a module
139
+ m.paths = module.paths;
140
+ m._compile(compiled, filename);
141
+
142
+ return m.exports;
143
+ }
144
+
145
+ protected reactBaseTmpl(data: any, options: any) {
146
+ let exp: any;
147
+ let regex: any;
148
+
149
+ // Iterates through the keys in file object
150
+ // and interpolate / replace {{key}} with it's value
151
+ for (const k in options) {
152
+ if (options.hasOwnProperty(k)) {
153
+ exp = `{{${k}}}`;
154
+ regex = new RegExp(exp, "g");
155
+ if (data.match(regex)) {
156
+ data = data.replace(regex, options[k]);
157
+ }
158
+ }
159
+ }
160
+
161
+ return data;
162
+ }
163
+ }
@@ -0,0 +1,5 @@
1
+ import {ViewEngine} from "../decorators/viewEngine.js";
2
+ import {Engine} from "./Engine.js";
3
+
4
+ @ViewEngine("slm")
5
+ export class SlmEngine extends Engine {}
@@ -0,0 +1,98 @@
1
+ import {join} from "path";
2
+
3
+ import {getEngineFixture} from "../../test/getEngineFixture.js";
4
+ import {requires} from "../utils/cache.js";
5
+ import {SquirrellyEngine} from "./SquirrellyEngine.js";
6
+
7
+ describe("SquirrellyEngine", () => {
8
+ it("should render the given content (by string - no cache)", async () => {
9
+ const {render, locals, $compile, template} = await getEngineFixture({token: SquirrellyEngine});
10
+ await render();
11
+
12
+ expect(await render()).toEqual("<p>Tobi</p>");
13
+ expect($compile()).toHaveBeenCalledTimes(2);
14
+ expect($compile()).toHaveBeenCalledWith(template, {...locals, cache: false});
15
+ });
16
+ it("should render the given content (by string - with cache)", async () => {
17
+ const {render, locals, $compile, template} = await getEngineFixture({token: SquirrellyEngine, cache: true});
18
+ await render();
19
+
20
+ expect(await render()).toEqual("<p>Tobi</p>");
21
+ expect($compile()).toHaveBeenCalledTimes(2);
22
+ expect($compile()).toHaveBeenCalledWith(template, {...locals, cache: true});
23
+ });
24
+ it("should render the given content (by file - no cache)", async () => {
25
+ const {renderFile, locals, $compile, path, template} = await getEngineFixture({token: SquirrellyEngine});
26
+ await renderFile();
27
+ const content = await renderFile();
28
+
29
+ expect(content).toEqual("<p>Tobi</p>");
30
+ expect($compile()).toHaveBeenCalledTimes(2);
31
+ expect($compile()).toHaveBeenCalledWith(template, {
32
+ ...locals,
33
+ partials: undefined,
34
+ filename: path,
35
+ cache: false
36
+ });
37
+ });
38
+ it("should render the given content (by file - with cache)", async () => {
39
+ const {renderFile, locals, $compile, path, template} = await getEngineFixture({
40
+ token: SquirrellyEngine,
41
+ cache: true
42
+ });
43
+
44
+ await renderFile();
45
+ const content = await renderFile();
46
+
47
+ expect(content).toEqual("<p>Tobi</p>");
48
+ expect($compile()).toHaveBeenCalledTimes(1);
49
+ expect($compile()).toHaveBeenCalledWith(template, {
50
+ ...locals,
51
+ partials: undefined,
52
+ filename: path,
53
+ cache: true
54
+ });
55
+ });
56
+
57
+ // Use case: return safe HTML that won’t be escaped in the final render.
58
+ it("should support helpers", async () => {
59
+ const Sqrl = requires.get("squirrelly");
60
+ const user = {name: "<strong>Tobi</strong>"};
61
+
62
+ Sqrl.defineHelper("myhelper", (args: string[], content: any, blocks: any) => {
63
+ return args[0].slice(1, -1);
64
+ });
65
+
66
+ const {render} = await getEngineFixture({token: SquirrellyEngine, templateName: "helpers"});
67
+
68
+ const html = await render({user: user});
69
+ expect(html).toEqual("strong>Tobi</strong");
70
+ });
71
+
72
+ // partials
73
+ it("should support partials", async () => {
74
+ const {renderFile} = await getEngineFixture({token: SquirrellyEngine, templateName: "partials"});
75
+ const locals = {
76
+ partials: {
77
+ partial: "user"
78
+ }
79
+ };
80
+ const html = await renderFile(locals);
81
+
82
+ expect(html).toEqual("<p>Tobi</p>");
83
+ });
84
+ it("should support absolute path partial", async () => {
85
+ const {renderFile, rootDir, name} = await getEngineFixture({token: SquirrellyEngine, templateName: "partials"});
86
+ const locals = {partials: {partial: join(rootDir, "fixtures", name, "user")}};
87
+ const html = await renderFile(locals);
88
+
89
+ expect(html).toEqual("<p>Tobi</p>");
90
+ });
91
+ it("should support relative path partial", async () => {
92
+ const {renderFile, name} = await getEngineFixture({token: SquirrellyEngine, templateName: "partials"});
93
+
94
+ const locals = {partials: {partial: `../${name}/user`}};
95
+ const html = await renderFile(locals);
96
+ expect(html).toEqual("<p>Tobi</p>");
97
+ });
98
+ });
@@ -0,0 +1,18 @@
1
+ import {ViewEngine} from "../decorators/viewEngine.js";
2
+ import {Engine, EngineOptions} from "./Engine.js";
3
+
4
+ @ViewEngine("squirrelly")
5
+ export class SquirrellyEngine extends Engine {
6
+ protected $compile(template: string, options: EngineOptions) {
7
+ for (const partial in options.partials) {
8
+ this.engine.definePartial(partial, options.partials[partial]);
9
+ }
10
+ for (const helper in options.helpers) {
11
+ this.engine.defineHelper(helper, options.helpers[helper]);
12
+ }
13
+
14
+ const compile = this.engine.Compile(template, options);
15
+
16
+ return (options: EngineOptions) => compile(options, this.engine);
17
+ }
18
+ }
@@ -0,0 +1,14 @@
1
+ import {ViewEngine} from "../decorators/viewEngine.js";
2
+ import {Engine} from "./Engine.js";
3
+
4
+ @ViewEngine("swig", {
5
+ requires: ["swig", "swig-templates"]
6
+ })
7
+ export class SwigEngine extends Engine {
8
+ protected $compile(template: string, options: any): (options: any) => Promise<string> {
9
+ if (options.cache === true) options.cache = "memory";
10
+ this.engine.setDefaults({cache: options.cache});
11
+
12
+ return this.engine.compile(template, options);
13
+ }
14
+ }
@@ -0,0 +1,9 @@
1
+ import {ViewEngine} from "../decorators/viewEngine.js";
2
+ import {Engine} from "./Engine.js";
3
+
4
+ @ViewEngine("templayed")
5
+ export class TemplayedEngine extends Engine {
6
+ protected $compile(template: string, options: any) {
7
+ return this.engine(template);
8
+ }
9
+ }
@@ -0,0 +1,44 @@
1
+ import {getEngineFixture} from "../../test/getEngineFixture.js";
2
+ import {TwigEngine} from "./TwigEngine.js";
3
+
4
+ describe("TwigEngine", () => {
5
+ it("should render the given content (by string - no cache)", async () => {
6
+ const {render, $compile, template} = await getEngineFixture({token: TwigEngine});
7
+ await render();
8
+
9
+ expect(await render()).toEqual("<p>Tobi</p>");
10
+ expect($compile()).toHaveBeenCalledTimes(2);
11
+ expect($compile()).toHaveBeenCalledWith(template, {
12
+ allowInlineIncludes: undefined,
13
+ cache: false,
14
+ data: "<p>{{ user.name }}</p>",
15
+ namespaces: undefined,
16
+ path: undefined,
17
+ user: {name: "Tobi"}
18
+ });
19
+ });
20
+ it("should render the given content (by string - with cache)", async () => {
21
+ const {render, $compile} = await getEngineFixture({token: TwigEngine, cache: true});
22
+ await render();
23
+
24
+ expect(await render()).toEqual("<p>Tobi</p>");
25
+ expect($compile()).toHaveBeenCalledTimes(2);
26
+ });
27
+ it("should render the given content (by file - no cache)", async () => {
28
+ const {renderFile, $compileFile, path} = await getEngineFixture({token: TwigEngine});
29
+ await renderFile();
30
+ const content = await renderFile();
31
+
32
+ expect(content).toEqual("<p>Tobi</p>");
33
+ expect($compileFile()).toHaveBeenCalledTimes(2);
34
+ });
35
+ it("should render the given content (by file - with cache)", async () => {
36
+ const {renderFile, $compileFile} = await getEngineFixture({token: TwigEngine, cache: true});
37
+
38
+ await renderFile();
39
+ const content = await renderFile();
40
+
41
+ expect(content).toEqual("<p>Tobi</p>");
42
+ expect($compileFile()).toHaveBeenCalledTimes(1);
43
+ });
44
+ });
@@ -0,0 +1,24 @@
1
+ import {ViewEngine} from "../decorators/viewEngine.js";
2
+ import {Engine, EngineOptions} from "./Engine.js";
3
+
4
+ @ViewEngine("twig")
5
+ export class TwigEngine extends Engine {
6
+ protected $cacheOptions(template: string, options: any) {
7
+ return {
8
+ ...options,
9
+ data: template,
10
+ allowInlineIncludes: options.allowInlineIncludes,
11
+ namespaces: options.namespaces,
12
+ path: options.path
13
+ };
14
+ }
15
+
16
+ protected $compile(template: string, options: EngineOptions) {
17
+ const {twig: engine} = this.engine;
18
+ options.data = template;
19
+
20
+ const compile = engine(options);
21
+
22
+ return (options: EngineOptions) => compile.render(options);
23
+ }
24
+ }
@@ -0,0 +1,36 @@
1
+ import {getEngineFixture} from "../../test/getEngineFixture.js";
2
+ import {TwingEngine} from "./TwingEngine.js";
3
+
4
+ describe("TwingEngine", () => {
5
+ it("should render the given content (by string - no cache)", async () => {
6
+ const {render, $compile} = await getEngineFixture({token: TwingEngine});
7
+ await render();
8
+
9
+ expect(await render()).toEqual("<p>Tobi</p>");
10
+ expect($compile()).toHaveBeenCalledTimes(2);
11
+ });
12
+ it("should render the given content (by string - with cache)", async () => {
13
+ const {render, $compile} = await getEngineFixture({token: TwingEngine, cache: true});
14
+ await render();
15
+
16
+ expect(await render()).toEqual("<p>Tobi</p>");
17
+ expect($compile()).toHaveBeenCalledTimes(2);
18
+ });
19
+ it("should render the given content (by file - no cache)", async () => {
20
+ const {renderFile, $compileFile} = await getEngineFixture({token: TwingEngine});
21
+ await renderFile();
22
+ const content = await renderFile();
23
+
24
+ expect(content).toEqual("<p>Tobi</p>");
25
+ expect($compileFile()).toHaveBeenCalledTimes(2);
26
+ });
27
+ it("should render the given content (by file - with cache)", async () => {
28
+ const {renderFile, $compileFile, path} = await getEngineFixture({token: TwingEngine, cache: true});
29
+
30
+ await renderFile();
31
+ const content = await renderFile();
32
+
33
+ expect(content).toEqual("<p>Tobi</p>");
34
+ expect($compileFile()).toHaveBeenCalledTimes(1);
35
+ });
36
+ });
@@ -0,0 +1,31 @@
1
+ import {existsSync} from "fs";
2
+
3
+ import {ViewEngine} from "../decorators/viewEngine.js";
4
+ import {Engine} from "./Engine.js";
5
+
6
+ @ViewEngine("twing")
7
+ export class TwingEngine extends Engine {
8
+ private instance: any;
9
+
10
+ protected $compile(template: string, options: any): (options: any) => Promise<string> {
11
+ const engine = this.engine;
12
+
13
+ if (!this.instance) {
14
+ let loader = new engine.TwingLoaderNull();
15
+
16
+ if (options.settings && options.settings.views && existsSync(options.settings.views)) {
17
+ loader = new engine.TwingLoaderFilesystem(options.settings.views);
18
+ }
19
+
20
+ this.instance = new engine.TwingEnvironment(loader);
21
+ }
22
+
23
+ const $cmp = this.instance.createTemplate(template);
24
+
25
+ return async (options: any) => {
26
+ const compile = await $cmp;
27
+
28
+ return compile.render(options);
29
+ };
30
+ }
31
+ }
@@ -0,0 +1,26 @@
1
+ import {ViewEngine} from "../decorators/viewEngine.js";
2
+ import {Engine} from "./Engine.js";
3
+
4
+ @ViewEngine("underscore")
5
+ export class UnderscoreEngine extends Engine {
6
+ async render(template: string, options: any) {
7
+ const tpl: string = await this.compile(template, options)(options);
8
+ return tpl.replace(/\n$/, "");
9
+ }
10
+
11
+ protected $cacheOptions(template: string, options: any): any {
12
+ const partials: any = {};
13
+
14
+ for (const partial in options.partials) {
15
+ partials[partial] = this.engine.template(options.partials[partial]);
16
+ }
17
+
18
+ options.partials = partials;
19
+
20
+ return options;
21
+ }
22
+
23
+ protected $compile(template: string, options: any): (options: any) => Promise<string> {
24
+ return this.engine.template(template, null, options);
25
+ }
26
+ }
@@ -0,0 +1,33 @@
1
+ import {promisify} from "util";
2
+
3
+ import {ViewEngine} from "../decorators/viewEngine.js";
4
+ import {Engine} from "./Engine.js";
5
+
6
+ @ViewEngine("vash")
7
+ export class VashEngine extends Engine {
8
+ compile(template: string, options: any): (options: any) => Promise<string> {
9
+ if (options.helpers) {
10
+ for (const key in options.helpers) {
11
+ if (!options.helpers.hasOwnProperty(key) || typeof options.helpers[key] !== "function") {
12
+ continue;
13
+ }
14
+ this.engine.helpers[key] = options.helpers[key];
15
+ }
16
+ }
17
+
18
+ const compile = promisify(this.engine.compile(template, options));
19
+
20
+ return async (options: any) => {
21
+ const ctx = await compile(options);
22
+ ctx.finishLayout();
23
+ return ctx.toString();
24
+ };
25
+ }
26
+
27
+ async render(template: string, options: any) {
28
+ const compile = this.compile(template, options);
29
+
30
+ const tpl = await compile(options);
31
+ return tpl.replace(/\n$/, "");
32
+ }
33
+ }
@@ -0,0 +1,50 @@
1
+ import {getEngineFixture} from "../../test/getEngineFixture.js";
2
+ import {VelocityEngine} from "./VelocityEngine.js";
3
+
4
+ describe("VelocityEngine", () => {
5
+ it("should render the given content (by string - no cache)", async () => {
6
+ const {render, locals, $compile} = await getEngineFixture({token: "velocityjs"});
7
+ await render();
8
+
9
+ expect(await render()).toEqual("<p>Tobi</p>\n");
10
+ expect($compile()).toHaveBeenCalledTimes(2);
11
+ expect($compile()).toHaveBeenCalledWith("<p>$user.name</p>\n", {...locals, cache: false});
12
+ });
13
+ it("should render the given content (by string - with cache)", async () => {
14
+ const {render, locals, $compile} = await getEngineFixture({token: VelocityEngine, cache: true});
15
+ await render();
16
+
17
+ expect(await render()).toEqual("<p>Tobi</p>\n");
18
+ expect($compile()).toHaveBeenCalledTimes(2);
19
+ expect($compile()).toHaveBeenCalledWith("<p>$user.name</p>\n", {...locals, cache: true});
20
+ });
21
+ it("should render the given content (by file - no cache)", async () => {
22
+ const {renderFile, locals, $compile, path, template} = await getEngineFixture({token: VelocityEngine});
23
+ await renderFile();
24
+ const content = await renderFile();
25
+
26
+ expect(content).toEqual("<p>Tobi</p>\n");
27
+ expect($compile()).toHaveBeenCalledTimes(2);
28
+ expect($compile()).toHaveBeenCalledWith(template, {
29
+ ...locals,
30
+ partials: undefined,
31
+ filename: path,
32
+ cache: false
33
+ });
34
+ });
35
+ it("should render the given content (by file - with cache)", async () => {
36
+ const {renderFile, locals, $compile, path, template} = await getEngineFixture({token: VelocityEngine, cache: true});
37
+
38
+ await renderFile();
39
+ const content = await renderFile();
40
+
41
+ expect(content).toEqual("<p>Tobi</p>\n");
42
+ expect($compile()).toHaveBeenCalledTimes(1);
43
+ expect($compile()).toHaveBeenCalledWith(template, {
44
+ ...locals,
45
+ partials: undefined,
46
+ filename: path,
47
+ cache: true
48
+ });
49
+ });
50
+ });
@@ -0,0 +1,11 @@
1
+ import {ViewEngine} from "../decorators/viewEngine.js";
2
+ import {Engine, EngineOptions} from "./Engine.js";
3
+
4
+ @ViewEngine("velocityjs")
5
+ export class VelocityEngine extends Engine {
6
+ protected $compile(template: string, options: EngineOptions) {
7
+ return (options: EngineOptions) => {
8
+ return Promise.resolve(this.engine.render(template, options).trimLeft());
9
+ };
10
+ }
11
+ }
@@ -0,0 +1,11 @@
1
+ import {ViewEngine} from "../decorators/viewEngine.js";
2
+ import {Engine} from "./Engine.js";
3
+
4
+ @ViewEngine("walrus")
5
+ export class WalrusEngine extends Engine {
6
+ protected $compile(template: string, options: any) {
7
+ const compile = this.engine.parse(template);
8
+
9
+ return (options: any) => compile.compile(options);
10
+ }
11
+ }
@@ -0,0 +1,8 @@
1
+ import {ViewEngineOptions} from "../components/Engine.js";
2
+ import {engines} from "../registries/EnginesContainer.js";
3
+
4
+ export function ViewEngine(name: string, options: ViewEngineOptions = {}): ClassDecorator {
5
+ return (target: any) => {
6
+ engines.set(target, {name, useClass: target, options});
7
+ };
8
+ }
package/src/index.ts ADDED
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @file Automatically generated by @tsed/barrels.
3
+ */
4
+ export * from "./components/AtplEngine.js";
5
+ export * from "./components/BracketEngine.js";
6
+ export * from "./components/DotEngine.js";
7
+ export * from "./components/DustEngine.js";
8
+ export * from "./components/EctEngine.js";
9
+ export * from "./components/EjsEngine.js";
10
+ export * from "./components/Engine.js";
11
+ export * from "./components/HamlCoffeeEngine.js";
12
+ export * from "./components/HamlEngine.js";
13
+ export * from "./components/HamletEngine.js";
14
+ export * from "./components/HandlebarsEngine.js";
15
+ export * from "./components/HoganEngine.js";
16
+ export * from "./components/HtmlingEngine.js";
17
+ export * from "./components/JazzEngine.js";
18
+ export * from "./components/JqtplEngine.js";
19
+ export * from "./components/JustEngine.js";
20
+ export * from "./components/LiquorEngine.js";
21
+ export * from "./components/LodashEngine.js";
22
+ export * from "./components/MoteEngine.js";
23
+ export * from "./components/MustacheEngine.js";
24
+ export * from "./components/NunjucksEngine.js";
25
+ export * from "./components/PlatesEngine.js";
26
+ export * from "./components/PugEngine.js";
27
+ export * from "./components/RactiveEngine.js";
28
+ export * from "./components/ReactEngine.js";
29
+ export * from "./components/SlmEngine.js";
30
+ export * from "./components/SquirrellyEngine.js";
31
+ export * from "./components/SwigEngine.js";
32
+ export * from "./components/TemplayedEngine.js";
33
+ export * from "./components/TwigEngine.js";
34
+ export * from "./components/TwingEngine.js";
35
+ export * from "./components/UnderscoreEngine.js";
36
+ export * from "./components/VashEngine.js";
37
+ export * from "./components/VelocityEngine.js";
38
+ export * from "./components/WalrusEngine.js";
39
+ export * from "./decorators/viewEngine.js";
40
+ export * from "./registries/EnginesContainer.js";
41
+ export * from "./utils/cache.js";
42
+ export * from "./utils/getEngines.js";