@ackplus/nest-dynamic-templates 1.1.1 → 1.1.5
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/package.json +2 -2
- package/src/{index.ts → index.d.ts} +2 -14
- package/src/index.d.ts.map +1 -0
- package/src/index.js +25 -0
- package/src/lib/constant.d.ts +3 -0
- package/src/lib/constant.d.ts.map +1 -0
- package/src/lib/constant.js +5 -0
- package/src/lib/dto/create-template-layout.dto.d.ts +16 -0
- package/src/lib/dto/create-template-layout.dto.d.ts.map +1 -0
- package/src/lib/dto/create-template-layout.dto.js +86 -0
- package/src/lib/dto/create-template.dto.d.ts +18 -0
- package/src/lib/dto/create-template.dto.d.ts.map +1 -0
- package/src/lib/dto/create-template.dto.js +103 -0
- package/src/lib/dto/render-content-template-layout.dto.d.ts +8 -0
- package/src/lib/dto/render-content-template-layout.dto.d.ts.map +1 -0
- package/src/lib/dto/render-content-template-layout.dto.js +40 -0
- package/src/lib/dto/render-content-template.dto.d.ts +9 -0
- package/src/lib/dto/render-content-template.dto.d.ts.map +1 -0
- package/src/lib/dto/render-content-template.dto.js +46 -0
- package/src/lib/dto/render-template-layout.dto.d.ts +11 -0
- package/src/lib/dto/render-template-layout.dto.d.ts.map +1 -0
- package/src/lib/dto/render-template-layout.dto.js +66 -0
- package/src/lib/dto/render-template.dto.d.ts +15 -0
- package/src/lib/dto/render-template.dto.d.ts.map +1 -0
- package/src/lib/dto/render-template.dto.js +90 -0
- package/src/lib/dto/template-filter.dto.d.ts +9 -0
- package/src/lib/dto/template-filter.dto.d.ts.map +1 -0
- package/src/lib/dto/template-filter.dto.js +61 -0
- package/src/lib/dto/template-layout-filter.dto.d.ts +8 -0
- package/src/lib/dto/template-layout-filter.dto.d.ts.map +1 -0
- package/src/lib/dto/template-layout-filter.dto.js +60 -0
- package/src/lib/engines/language/html.engine.d.ts +10 -0
- package/src/lib/engines/language/html.engine.d.ts.map +1 -0
- package/src/lib/engines/language/html.engine.js +80 -0
- package/src/lib/engines/language/{index.ts → index.d.ts} +1 -0
- package/src/lib/engines/language/index.d.ts.map +1 -0
- package/src/lib/engines/language/index.js +11 -0
- package/src/lib/engines/language/markdown.engine.d.ts +10 -0
- package/src/lib/engines/language/markdown.engine.d.ts.map +1 -0
- package/src/lib/engines/language/markdown.engine.js +39 -0
- package/src/lib/engines/language/mjml.engine.d.ts +10 -0
- package/src/lib/engines/language/mjml.engine.d.ts.map +1 -0
- package/src/lib/engines/language/mjml.engine.js +75 -0
- package/src/lib/engines/language/text.engine.d.ts +8 -0
- package/src/lib/engines/language/text.engine.d.ts.map +1 -0
- package/src/lib/engines/language/text.engine.js +15 -0
- package/src/lib/engines/{language-engine.ts → language-engine.d.ts} +2 -7
- package/src/lib/engines/language-engine.d.ts.map +1 -0
- package/src/lib/engines/language-engine.js +6 -0
- package/src/lib/engines/template/ejs.engine.d.ts +11 -0
- package/src/lib/engines/template/ejs.engine.d.ts.map +1 -0
- package/src/lib/engines/template/ejs.engine.js +65 -0
- package/src/lib/engines/template/handlebars.engine.d.ts +11 -0
- package/src/lib/engines/template/handlebars.engine.d.ts.map +1 -0
- package/src/lib/engines/template/handlebars.engine.js +66 -0
- package/src/lib/engines/template/{index.ts → index.d.ts} +1 -0
- package/src/lib/engines/template/index.d.ts.map +1 -0
- package/src/lib/engines/template/index.js +11 -0
- package/src/lib/engines/template/nunjucks.engine.d.ts +17 -0
- package/src/lib/engines/template/nunjucks.engine.d.ts.map +1 -0
- package/src/lib/engines/template/{nunjucks.engine.ts → nunjucks.engine.js} +24 -30
- package/src/lib/engines/template/pug.engine.d.ts +13 -0
- package/src/lib/engines/template/pug.engine.d.ts.map +1 -0
- package/src/lib/engines/template/pug.engine.js +74 -0
- package/src/lib/engines/{template-engine.ts → template-engine.d.ts} +2 -6
- package/src/lib/engines/template-engine.d.ts.map +1 -0
- package/src/lib/engines/template-engine.js +6 -0
- package/src/lib/entities/template-layout.entity.d.ts +21 -0
- package/src/lib/entities/template-layout.entity.d.ts.map +1 -0
- package/src/lib/entities/template-layout.entity.js +120 -0
- package/src/lib/entities/template.entity.d.ts +22 -0
- package/src/lib/entities/template.entity.d.ts.map +1 -0
- package/src/lib/entities/template.entity.js +127 -0
- package/src/lib/errors/template.errors.d.ts +20 -0
- package/src/lib/errors/template.errors.d.ts.map +1 -0
- package/src/lib/errors/{template.errors.ts → template.errors.js} +22 -20
- package/src/lib/interfaces/{module-config.interface.ts → module-config.interface.d.ts} +2 -10
- package/src/lib/interfaces/module-config.interface.d.ts.map +1 -0
- package/src/lib/interfaces/module-config.interface.js +2 -0
- package/src/lib/interfaces/template.types.d.ts +23 -0
- package/src/lib/interfaces/template.types.d.ts.map +1 -0
- package/src/lib/interfaces/template.types.js +24 -0
- package/src/lib/nest-dynamic-templates.module.d.ts +11 -0
- package/src/lib/nest-dynamic-templates.module.d.ts.map +1 -0
- package/src/lib/nest-dynamic-templates.module.js +131 -0
- package/src/lib/services/template-config.service.d.ts +55 -0
- package/src/lib/services/template-config.service.d.ts.map +1 -0
- package/src/lib/services/{template-config.service.ts → template-config.service.js} +32 -43
- package/src/lib/services/template-engine.registry.d.ts +22 -0
- package/src/lib/services/template-engine.registry.d.ts.map +1 -0
- package/src/lib/services/template-engine.registry.js +93 -0
- package/src/lib/services/template-layout.service.d.ts +37 -0
- package/src/lib/services/template-layout.service.d.ts.map +1 -0
- package/src/lib/services/{template-layout.service.ts → template-layout.service.js} +101 -165
- package/src/lib/services/template.service.d.ts +39 -0
- package/src/lib/services/template.service.d.ts.map +1 -0
- package/src/lib/services/{template.service.ts → template.service.js} +137 -199
- package/src/test/helpers.d.ts +5 -0
- package/src/test/helpers.d.ts.map +1 -0
- package/src/test/{helpers.ts → helpers.js} +7 -5
- package/src/test/test-database.config.d.ts +5 -0
- package/src/test/test-database.config.d.ts.map +1 -0
- package/src/test/test-database.config.js +23 -0
- package/src/test/test.setup.d.ts +4 -0
- package/src/test/test.setup.d.ts.map +1 -0
- package/src/test/test.setup.js +30 -0
- package/eslint.config.mjs +0 -22
- package/jest.config.ts +0 -10
- package/project.json +0 -38
- package/src/lib/constant.ts +0 -2
- package/src/lib/dto/create-template-layout.dto.ts +0 -65
- package/src/lib/dto/create-template.dto.ts +0 -80
- package/src/lib/dto/render-content-template-layout.dto.ts +0 -32
- package/src/lib/dto/render-content-template.dto.ts +0 -37
- package/src/lib/dto/render-template-layout.dto.ts +0 -55
- package/src/lib/dto/render-template.dto.ts +0 -74
- package/src/lib/dto/template-filter.dto.ts +0 -52
- package/src/lib/dto/template-layout-filter.dto.ts +0 -51
- package/src/lib/engines/language/html.engine.ts +0 -49
- package/src/lib/engines/language/markdown.engine.ts +0 -37
- package/src/lib/engines/language/mjml.engine.ts +0 -44
- package/src/lib/engines/language/text.engine.ts +0 -15
- package/src/lib/engines/template/ejs.engine.ts +0 -33
- package/src/lib/engines/template/handlebars.engine.ts +0 -35
- package/src/lib/engines/template/pug.engine.ts +0 -43
- package/src/lib/entities/template-layout.entity.ts +0 -99
- package/src/lib/entities/template.entity.ts +0 -105
- package/src/lib/interfaces/template.types.ts +0 -25
- package/src/lib/nest-dynamic-templates.module.ts +0 -143
- package/src/lib/services/template-engine.registry.ts +0 -109
- package/src/test/nunjucks.service.spec.ts +0 -157
- package/src/test/pug.service.spec-temp +0 -254
- package/src/test/template-layout.service.spec.ts +0 -422
- package/src/test/template.service.spec.ts +0 -862
- package/src/test/test-database.config.ts +0 -24
- package/src/test/test-database.d.ts +0 -6
- package/src/test/test.setup.ts +0 -34
- package/src/types/ioredis.d.ts +0 -6
- package/src/types/mjml.d.ts +0 -5
- package/tsconfig.json +0 -17
- package/tsconfig.lib.json +0 -14
- package/tsconfig.spec.json +0 -15
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { TemplateLanguageEnum } from '../../interfaces/template.types';
|
|
2
|
-
import { LanguageEngine } from '../language-engine';
|
|
3
|
-
|
|
4
|
-
export class MjmlEngine extends LanguageEngine {
|
|
5
|
-
|
|
6
|
-
static override engineName = TemplateLanguageEnum.MJML;
|
|
7
|
-
|
|
8
|
-
private readonly options: any = {};
|
|
9
|
-
|
|
10
|
-
constructor(options: any = {}) {
|
|
11
|
-
super();
|
|
12
|
-
this.options = options;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async render(content: string): Promise<string> {
|
|
16
|
-
try {
|
|
17
|
-
const mjml2html = (await import('mjml')).default;
|
|
18
|
-
const result = mjml2html(content, {
|
|
19
|
-
...this.options,
|
|
20
|
-
validationLevel: 'strict',
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
if (result.errors && result.errors.length > 0) {
|
|
24
|
-
throw new Error(`MJML validation errors: ${result.errors.join(', ')}`);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return result.html;
|
|
28
|
-
} catch (error: any) {
|
|
29
|
-
throw new Error(`MJML rendering error: ${error?.message || 'Unknown error'}`);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
async validate(content: string): Promise<boolean> {
|
|
34
|
-
try {
|
|
35
|
-
const mjml2html = (await import('mjml')).default;
|
|
36
|
-
const result = mjml2html(content, {
|
|
37
|
-
validationLevel: 'strict',
|
|
38
|
-
});
|
|
39
|
-
return result.errors.length === 0;
|
|
40
|
-
} catch (error) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { TemplateLanguageEnum } from '../../interfaces/template.types';
|
|
2
|
-
import { LanguageEngine } from '../language-engine';
|
|
3
|
-
|
|
4
|
-
export class TextEngine extends LanguageEngine {
|
|
5
|
-
|
|
6
|
-
static override engineName = TemplateLanguageEnum.TEXT;
|
|
7
|
-
|
|
8
|
-
async render(content: string): Promise<string> {
|
|
9
|
-
return content;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
async validate(content: string): Promise<boolean> {
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { TemplateEngine } from '../template-engine';
|
|
2
|
-
import { TemplateEngineEnum } from '../../interfaces/template.types';
|
|
3
|
-
import { EngineOptions } from '../../interfaces/module-config.interface';
|
|
4
|
-
export class EjsEngine extends TemplateEngine {
|
|
5
|
-
|
|
6
|
-
static override engineName = TemplateEngineEnum.EJS;
|
|
7
|
-
|
|
8
|
-
private options: ejs.Options;
|
|
9
|
-
|
|
10
|
-
constructor(options?: EngineOptions<ejs.Options>) {
|
|
11
|
-
super();
|
|
12
|
-
this.options = options || {};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async render(content: string, data?: Record<string, any>): Promise<string> {
|
|
16
|
-
try {
|
|
17
|
-
const ejs = await import('ejs');
|
|
18
|
-
return ejs.render(content, data, this.options);
|
|
19
|
-
} catch (error: any) {
|
|
20
|
-
throw new Error(`Failed to render EJS template: ${error?.message || 'Unknown error'}`);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async validate(content: string): Promise<boolean> {
|
|
25
|
-
try {
|
|
26
|
-
const ejs = await import('ejs');
|
|
27
|
-
ejs.compile(content, this.options);
|
|
28
|
-
return true;
|
|
29
|
-
} catch (error) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { TemplateEngineEnum } from '../../interfaces/template.types';
|
|
2
|
-
import { TemplateEngine } from '../template-engine';
|
|
3
|
-
import { EngineOptions } from '../../interfaces/module-config.interface';
|
|
4
|
-
|
|
5
|
-
export class HandlebarsEngine extends TemplateEngine {
|
|
6
|
-
|
|
7
|
-
static override engineName = TemplateEngineEnum.HANDLEBARS;
|
|
8
|
-
|
|
9
|
-
private options: Handlebars.ParseOptions;
|
|
10
|
-
|
|
11
|
-
constructor(options?: EngineOptions<Handlebars.ParseOptions>) {
|
|
12
|
-
super();
|
|
13
|
-
this.options = options || {};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
async render(content: string, data?: Record<string, any>): Promise<string> {
|
|
17
|
-
try {
|
|
18
|
-
const Handlebars = await import('handlebars');
|
|
19
|
-
const template = Handlebars.compile(content, this.options);
|
|
20
|
-
return template(data);
|
|
21
|
-
} catch (error: any) {
|
|
22
|
-
throw new Error(`Failed to render Handlebars template: ${error?.message || 'Unknown error'}`);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async validate(content: string): Promise<boolean> {
|
|
27
|
-
try {
|
|
28
|
-
const Handlebars = await import('handlebars');
|
|
29
|
-
Handlebars.precompile(content, this.options);
|
|
30
|
-
return true;
|
|
31
|
-
} catch (error) {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { Options } from 'pug';
|
|
2
|
-
import { TemplateEngineEnum } from '../../interfaces/template.types';
|
|
3
|
-
import { TemplateEngine } from '../template-engine';
|
|
4
|
-
import { CustomEngineOptions, EngineOptions } from '../../interfaces/module-config.interface';
|
|
5
|
-
|
|
6
|
-
export class PugEngine extends TemplateEngine {
|
|
7
|
-
|
|
8
|
-
static override engineName = TemplateEngineEnum.PUG;
|
|
9
|
-
|
|
10
|
-
private options: Options;
|
|
11
|
-
|
|
12
|
-
constructor(options?: EngineOptions<Options>, private customOptions?: CustomEngineOptions) {
|
|
13
|
-
super();
|
|
14
|
-
this.options = options || {};
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async render(content: string, data: any): Promise<string> {
|
|
18
|
-
try {
|
|
19
|
-
const pug = await import('pug');
|
|
20
|
-
const template = pug.compile(content, {
|
|
21
|
-
...this.options,
|
|
22
|
-
filters: this.customOptions?.filters
|
|
23
|
-
});
|
|
24
|
-
return template({
|
|
25
|
-
...this.options.filters,
|
|
26
|
-
...data,
|
|
27
|
-
...this.customOptions?.filters
|
|
28
|
-
});
|
|
29
|
-
} catch (error: any) {
|
|
30
|
-
throw new Error(`Failed to render Pug template: ${error?.message || 'Unknown error'}`);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async validate(content: string): Promise<boolean> {
|
|
35
|
-
try {
|
|
36
|
-
const pug = await import('pug');
|
|
37
|
-
pug.compile(content, this.options);
|
|
38
|
-
return true;
|
|
39
|
-
} catch (error) {
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn, Index, BaseEntity } from 'typeorm';
|
|
2
|
-
import { IsBoolean, IsEnum, IsNotEmpty, IsOptional, IsString, Matches } from 'class-validator';
|
|
3
|
-
import { TemplateEngineEnum, TemplateTypeEnum, TemplateLanguageEnum } from '../interfaces/template.types';
|
|
4
|
-
import { ApiProperty } from '@nestjs/swagger';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@Entity('nest_dynamic_template_layouts')
|
|
8
|
-
@Index(['name', 'scope', 'scopeId', 'locale'], { unique: true })
|
|
9
|
-
export class NestDynamicTemplateLayout extends BaseEntity {
|
|
10
|
-
|
|
11
|
-
@ApiProperty({ type: String, format: 'uuid', readOnly: true })
|
|
12
|
-
@PrimaryGeneratedColumn('uuid')
|
|
13
|
-
id: string;
|
|
14
|
-
|
|
15
|
-
@ApiProperty({ type: String })
|
|
16
|
-
@IsString()
|
|
17
|
-
@IsNotEmpty()
|
|
18
|
-
@Matches(/^[a-z0-9\-_]+$/, { message: 'Invalid template name format' })
|
|
19
|
-
@Column()
|
|
20
|
-
name: string;
|
|
21
|
-
|
|
22
|
-
@ApiProperty({ type: String, nullable: true })
|
|
23
|
-
@IsString()
|
|
24
|
-
@IsOptional()
|
|
25
|
-
@Column({ nullable: true })
|
|
26
|
-
displayName?: string;
|
|
27
|
-
|
|
28
|
-
@ApiProperty({ type: String, nullable: true })
|
|
29
|
-
@IsString()
|
|
30
|
-
@IsOptional()
|
|
31
|
-
@Column({ type: 'text', nullable: true })
|
|
32
|
-
description?: string;
|
|
33
|
-
|
|
34
|
-
@ApiProperty({ type: String })
|
|
35
|
-
@IsString()
|
|
36
|
-
@IsOptional()
|
|
37
|
-
@Column({ type: 'text' })
|
|
38
|
-
type?: string;
|
|
39
|
-
|
|
40
|
-
@ApiProperty({ enum: TemplateEngineEnum, type: String })
|
|
41
|
-
@IsEnum(TemplateEngineEnum)
|
|
42
|
-
@Column({
|
|
43
|
-
type: 'text',
|
|
44
|
-
enum: TemplateEngineEnum,
|
|
45
|
-
default: TemplateEngineEnum.NUNJUCKS
|
|
46
|
-
})
|
|
47
|
-
engine: TemplateEngineEnum;
|
|
48
|
-
|
|
49
|
-
@ApiProperty({ enum: TemplateLanguageEnum, type: String, nullable: true })
|
|
50
|
-
@IsEnum(TemplateLanguageEnum)
|
|
51
|
-
@IsOptional()
|
|
52
|
-
@Column({ type: 'text' })
|
|
53
|
-
language?: TemplateLanguageEnum;
|
|
54
|
-
|
|
55
|
-
@ApiProperty({ type: String })
|
|
56
|
-
@IsString()
|
|
57
|
-
@IsOptional()
|
|
58
|
-
@Column('text')
|
|
59
|
-
content: string;
|
|
60
|
-
|
|
61
|
-
@ApiProperty({ type: String, nullable: true })
|
|
62
|
-
@IsString()
|
|
63
|
-
@IsOptional()
|
|
64
|
-
@Column({ nullable: true })
|
|
65
|
-
templateLayoutName?: string;
|
|
66
|
-
|
|
67
|
-
@ApiProperty({ type: String, nullable: true })
|
|
68
|
-
@IsString()
|
|
69
|
-
@Column({ nullable: true, default: 'system' })
|
|
70
|
-
scope?: string;
|
|
71
|
-
|
|
72
|
-
@ApiProperty({ type: String, nullable: true })
|
|
73
|
-
@IsString()
|
|
74
|
-
@Column({ nullable: true })
|
|
75
|
-
scopeId?: string;
|
|
76
|
-
|
|
77
|
-
@ApiProperty({ type: String, nullable: true })
|
|
78
|
-
@IsString()
|
|
79
|
-
@Column({ nullable: true, default: 'en' })
|
|
80
|
-
locale?: string;
|
|
81
|
-
|
|
82
|
-
@ApiProperty({ type: Object, nullable: true })
|
|
83
|
-
@IsOptional()
|
|
84
|
-
@Column('simple-json', { nullable: true })
|
|
85
|
-
previewContext?: Record<string, any>;
|
|
86
|
-
|
|
87
|
-
@ApiProperty({ type: Boolean })
|
|
88
|
-
@IsBoolean()
|
|
89
|
-
@Column({ default: true })
|
|
90
|
-
isActive: boolean;
|
|
91
|
-
|
|
92
|
-
@ApiProperty({ type: Date, readOnly: true })
|
|
93
|
-
@CreateDateColumn()
|
|
94
|
-
createdAt: Date;
|
|
95
|
-
|
|
96
|
-
@ApiProperty({ type: Date, readOnly: true })
|
|
97
|
-
@UpdateDateColumn()
|
|
98
|
-
updatedAt: Date;
|
|
99
|
-
}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn, Index, JoinColumn, ManyToOne, RelationId, BaseEntity } from 'typeorm';
|
|
2
|
-
import { TemplateTypeEnum, TemplateEngineEnum, TemplateLanguageEnum } from '../interfaces/template.types';
|
|
3
|
-
import { IsBoolean, IsEnum, IsNotEmpty, IsOptional, IsString, Matches } from 'class-validator';
|
|
4
|
-
import { ApiProperty } from '@nestjs/swagger';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@Entity('nest_dynamic_templates')
|
|
8
|
-
@Index(['name', 'scope', 'scopeId', 'locale'], { unique: true })
|
|
9
|
-
export class NestDynamicTemplate extends BaseEntity {
|
|
10
|
-
|
|
11
|
-
@ApiProperty({ type: String, format: 'uuid', readOnly: true })
|
|
12
|
-
@PrimaryGeneratedColumn('uuid')
|
|
13
|
-
id: string;
|
|
14
|
-
|
|
15
|
-
@ApiProperty({ type: String })
|
|
16
|
-
@IsString()
|
|
17
|
-
@IsNotEmpty()
|
|
18
|
-
@Matches(/^[a-z0-9\-_]+$/, { message: 'Invalid template name format' })
|
|
19
|
-
@Column()
|
|
20
|
-
name: string;
|
|
21
|
-
|
|
22
|
-
@ApiProperty({ type: String, nullable: true })
|
|
23
|
-
@IsString()
|
|
24
|
-
@IsOptional()
|
|
25
|
-
@Column({ nullable: true })
|
|
26
|
-
displayName?: string;
|
|
27
|
-
|
|
28
|
-
@ApiProperty({ type: String, nullable: true })
|
|
29
|
-
@IsString()
|
|
30
|
-
@IsOptional()
|
|
31
|
-
@Column({ type: 'text', nullable: true })
|
|
32
|
-
description?: string;
|
|
33
|
-
|
|
34
|
-
@ApiProperty({ type: String, nullable: true })
|
|
35
|
-
@IsString()
|
|
36
|
-
@IsOptional()
|
|
37
|
-
@Column({ type: 'text', nullable: true })
|
|
38
|
-
type?: string;
|
|
39
|
-
|
|
40
|
-
@ApiProperty({ enum: TemplateEngineEnum, type: String })
|
|
41
|
-
@IsEnum(TemplateEngineEnum)
|
|
42
|
-
@Column({
|
|
43
|
-
type: 'text',
|
|
44
|
-
enum: TemplateEngineEnum,
|
|
45
|
-
default: TemplateEngineEnum.NUNJUCKS
|
|
46
|
-
})
|
|
47
|
-
engine: TemplateEngineEnum;
|
|
48
|
-
|
|
49
|
-
@ApiProperty({ enum: TemplateLanguageEnum, type: String, nullable: true })
|
|
50
|
-
@IsEnum(TemplateLanguageEnum)
|
|
51
|
-
@IsOptional()
|
|
52
|
-
@Column({ type: 'text' })
|
|
53
|
-
language?: TemplateLanguageEnum;
|
|
54
|
-
|
|
55
|
-
@ApiProperty({ type: String, nullable: true })
|
|
56
|
-
@IsString()
|
|
57
|
-
@IsOptional()
|
|
58
|
-
@Column({ nullable: true })
|
|
59
|
-
subject?: string;
|
|
60
|
-
|
|
61
|
-
@ApiProperty({ type: String })
|
|
62
|
-
@IsString()
|
|
63
|
-
@IsOptional()
|
|
64
|
-
@Column('text')
|
|
65
|
-
content: string;
|
|
66
|
-
|
|
67
|
-
@ApiProperty({ type: String, nullable: true })
|
|
68
|
-
@IsString()
|
|
69
|
-
@IsOptional()
|
|
70
|
-
@Column({ nullable: true })
|
|
71
|
-
templateLayoutName?: string;
|
|
72
|
-
|
|
73
|
-
@ApiProperty({ type: String, nullable: true })
|
|
74
|
-
@IsString()
|
|
75
|
-
@Column({ nullable: true, default: 'system' })
|
|
76
|
-
scope?: string;
|
|
77
|
-
|
|
78
|
-
@ApiProperty({ type: String, nullable: true })
|
|
79
|
-
@IsString()
|
|
80
|
-
@Column({ nullable: true })
|
|
81
|
-
scopeId?: string;
|
|
82
|
-
|
|
83
|
-
@ApiProperty({ type: String, nullable: true })
|
|
84
|
-
@IsString()
|
|
85
|
-
@Column({ nullable: true, default: 'en' })
|
|
86
|
-
locale?: string;
|
|
87
|
-
|
|
88
|
-
@ApiProperty({ type: Object, nullable: true })
|
|
89
|
-
@IsOptional()
|
|
90
|
-
@Column('simple-json', { nullable: true })
|
|
91
|
-
previewContext?: Record<string, any>;
|
|
92
|
-
|
|
93
|
-
@ApiProperty({ type: Boolean })
|
|
94
|
-
@IsBoolean()
|
|
95
|
-
@Column({ default: true })
|
|
96
|
-
isActive: boolean;
|
|
97
|
-
|
|
98
|
-
@ApiProperty({ type: Date, readOnly: true })
|
|
99
|
-
@CreateDateColumn()
|
|
100
|
-
createdAt: Date;
|
|
101
|
-
|
|
102
|
-
@ApiProperty({ type: Date, readOnly: true })
|
|
103
|
-
@UpdateDateColumn()
|
|
104
|
-
updatedAt: Date;
|
|
105
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export enum TemplateTypeEnum {
|
|
2
|
-
EMAIL = 'email',
|
|
3
|
-
SMS = 'sms',
|
|
4
|
-
PUSH = 'push',
|
|
5
|
-
PDF = 'pdf',
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export enum TemplateEngineEnum {
|
|
9
|
-
NUNJUCKS = 'njk',
|
|
10
|
-
HANDLEBARS = 'hbs',
|
|
11
|
-
EJS = 'ejs',
|
|
12
|
-
PUG = 'pug',
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export enum TemplateLanguageEnum {
|
|
16
|
-
MJML = 'mjml',
|
|
17
|
-
HTML = 'html',
|
|
18
|
-
MARKDOWN = 'md',
|
|
19
|
-
TEXT = 'txt',
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface Scope {
|
|
23
|
-
scope: string;
|
|
24
|
-
id: string;
|
|
25
|
-
}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { Module, DynamicModule, Provider } from '@nestjs/common';
|
|
2
|
-
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
3
|
-
import { NestDynamicTemplate } from './entities/template.entity';
|
|
4
|
-
import { NestDynamicTemplateLayout } from './entities/template-layout.entity';
|
|
5
|
-
import {
|
|
6
|
-
NestDynamicTemplatesModuleConfig,
|
|
7
|
-
NestDynamicTemplatesModuleAsyncOptions,
|
|
8
|
-
NestDynamicTemplatesModuleOptionsFactory
|
|
9
|
-
} from './interfaces/module-config.interface';
|
|
10
|
-
import deepmerge from 'deepmerge';
|
|
11
|
-
import { TemplateEngineRegistryService } from './services/template-engine.registry';
|
|
12
|
-
import { TemplateLayoutService } from './services/template-layout.service';
|
|
13
|
-
import { TemplateService } from './services/template.service';
|
|
14
|
-
import { TemplateConfigService } from './services/template-config.service';
|
|
15
|
-
import { NEST_DYNAMIC_TEMPLATES_ASYNC_OPTIONS_PROVIDER } from './constant';
|
|
16
|
-
import { TemplateEngineEnum } from './interfaces/template.types';
|
|
17
|
-
import { TemplateLanguageEnum } from './interfaces/template.types';
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const defaultConfig: NestDynamicTemplatesModuleConfig = {
|
|
21
|
-
engines: {
|
|
22
|
-
template: [TemplateEngineEnum.NUNJUCKS],
|
|
23
|
-
language: [TemplateLanguageEnum.HTML, TemplateLanguageEnum.MJML, TemplateLanguageEnum.TEXT]
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
@Module({
|
|
28
|
-
imports: [TypeOrmModule.forFeature([NestDynamicTemplate, NestDynamicTemplateLayout])],
|
|
29
|
-
providers: [
|
|
30
|
-
TemplateConfigService,
|
|
31
|
-
TemplateEngineRegistryService,
|
|
32
|
-
TemplateLayoutService,
|
|
33
|
-
TemplateService,
|
|
34
|
-
],
|
|
35
|
-
exports: [
|
|
36
|
-
TemplateConfigService,
|
|
37
|
-
TemplateService,
|
|
38
|
-
TemplateLayoutService,
|
|
39
|
-
],
|
|
40
|
-
})
|
|
41
|
-
export class NestDynamicTemplatesModule {
|
|
42
|
-
static moduleDefaultOptions: Partial<NestDynamicTemplatesModuleConfig> = defaultConfig;
|
|
43
|
-
|
|
44
|
-
static forRoot(config: NestDynamicTemplatesModuleConfig = {}): DynamicModule {
|
|
45
|
-
const mergedConfig = this.getOptions(config);
|
|
46
|
-
|
|
47
|
-
// Set options in static service
|
|
48
|
-
TemplateConfigService.setOptions(mergedConfig);
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
module: NestDynamicTemplatesModule,
|
|
52
|
-
global: mergedConfig.isGlobal,
|
|
53
|
-
imports: [
|
|
54
|
-
TypeOrmModule.forFeature([NestDynamicTemplate, NestDynamicTemplateLayout]),
|
|
55
|
-
],
|
|
56
|
-
providers: [
|
|
57
|
-
TemplateConfigService,
|
|
58
|
-
TemplateEngineRegistryService,
|
|
59
|
-
TemplateLayoutService,
|
|
60
|
-
TemplateService,
|
|
61
|
-
],
|
|
62
|
-
exports: [
|
|
63
|
-
TemplateConfigService,
|
|
64
|
-
TemplateService,
|
|
65
|
-
TemplateLayoutService,
|
|
66
|
-
],
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
static forRootAsync(options: NestDynamicTemplatesModuleAsyncOptions): DynamicModule {
|
|
71
|
-
const asyncProviders = this.createAsyncProviders(options);
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
module: NestDynamicTemplatesModule,
|
|
75
|
-
global: options.isGlobal,
|
|
76
|
-
imports: [
|
|
77
|
-
TypeOrmModule.forFeature([NestDynamicTemplate, NestDynamicTemplateLayout]),
|
|
78
|
-
...(options.imports || []),
|
|
79
|
-
],
|
|
80
|
-
providers: [
|
|
81
|
-
...asyncProviders,
|
|
82
|
-
TemplateConfigService,
|
|
83
|
-
TemplateEngineRegistryService,
|
|
84
|
-
TemplateLayoutService,
|
|
85
|
-
TemplateService,
|
|
86
|
-
],
|
|
87
|
-
exports: [
|
|
88
|
-
TemplateConfigService,
|
|
89
|
-
TemplateService,
|
|
90
|
-
TemplateLayoutService,
|
|
91
|
-
],
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
private static createAsyncProviders(options: NestDynamicTemplatesModuleAsyncOptions): Provider[] {
|
|
96
|
-
if (options.useExisting || options.useFactory) {
|
|
97
|
-
return [this.createAsyncOptionsProvider(options)];
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (options.useClass) {
|
|
101
|
-
return [
|
|
102
|
-
this.createAsyncOptionsProvider(options),
|
|
103
|
-
{
|
|
104
|
-
provide: options.useClass,
|
|
105
|
-
useClass: options.useClass,
|
|
106
|
-
},
|
|
107
|
-
];
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return [];
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
private static createAsyncOptionsProvider(options: NestDynamicTemplatesModuleAsyncOptions): Provider {
|
|
114
|
-
if (options.useFactory) {
|
|
115
|
-
return {
|
|
116
|
-
provide: NEST_DYNAMIC_TEMPLATES_ASYNC_OPTIONS_PROVIDER,
|
|
117
|
-
useFactory: async (...args: any[]) => {
|
|
118
|
-
const userOptions = options.useFactory ? await options.useFactory(...args) : {};
|
|
119
|
-
const mergedOptions = this.getOptions(userOptions);
|
|
120
|
-
TemplateConfigService.setOptions(mergedOptions);
|
|
121
|
-
return mergedOptions;
|
|
122
|
-
},
|
|
123
|
-
inject: options.inject || [],
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
provide: NEST_DYNAMIC_TEMPLATES_ASYNC_OPTIONS_PROVIDER,
|
|
129
|
-
useFactory: async (optionsFactory: NestDynamicTemplatesModuleOptionsFactory) => {
|
|
130
|
-
const userOptions = await optionsFactory.createNestDynamicTemplatesModuleOptions();
|
|
131
|
-
const mergedOptions = this.getOptions(userOptions);
|
|
132
|
-
TemplateConfigService.setOptions(mergedOptions);
|
|
133
|
-
return mergedOptions;
|
|
134
|
-
},
|
|
135
|
-
inject: [options.useExisting || options.useClass!],
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
private static getOptions(options: NestDynamicTemplatesModuleConfig): NestDynamicTemplatesModuleConfig {
|
|
140
|
-
return deepmerge(this.moduleDefaultOptions, options);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@nestjs/common';
|
|
2
|
-
import { TemplateEngineEnum, TemplateLanguageEnum } from '../interfaces/template.types';
|
|
3
|
-
import { NunjucksEngine } from '../engines/template/nunjucks.engine';
|
|
4
|
-
import { MjmlEngine } from '../engines/language/mjml.engine';
|
|
5
|
-
import { HtmlEngine } from '../engines/language/html.engine';
|
|
6
|
-
import { MarkdownEngine, TextEngine } from '../engines/language';
|
|
7
|
-
import { EjsEngine } from '../engines/template/ejs.engine';
|
|
8
|
-
import { HandlebarsEngine } from '../engines/template/handlebars.engine';
|
|
9
|
-
import { PugEngine } from '../engines/template/pug.engine';
|
|
10
|
-
import { TemplateConfigService } from './template-config.service';
|
|
11
|
-
import { TemplateEngine } from '../engines/template-engine';
|
|
12
|
-
import { LanguageEngine } from '../engines/language-engine';
|
|
13
|
-
import { NestDynamicTemplatesModuleConfig } from '../interfaces/module-config.interface';
|
|
14
|
-
|
|
15
|
-
type ClassType<T> = new (...args: any[]) => T;
|
|
16
|
-
|
|
17
|
-
@Injectable()
|
|
18
|
-
export class TemplateEngineRegistryService {
|
|
19
|
-
private templateEngines: Map<TemplateEngineEnum, TemplateEngine> = new Map();
|
|
20
|
-
private languageEngines: Map<TemplateLanguageEnum, LanguageEngine> = new Map();
|
|
21
|
-
private config: NestDynamicTemplatesModuleConfig;
|
|
22
|
-
|
|
23
|
-
constructor() {
|
|
24
|
-
this.config = TemplateConfigService.getOptions();
|
|
25
|
-
|
|
26
|
-
this.registerTemplateEngines([
|
|
27
|
-
NunjucksEngine,
|
|
28
|
-
HandlebarsEngine,
|
|
29
|
-
EjsEngine,
|
|
30
|
-
PugEngine
|
|
31
|
-
]);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.registerLanguageEngines([
|
|
35
|
-
MjmlEngine,
|
|
36
|
-
HtmlEngine,
|
|
37
|
-
TextEngine,
|
|
38
|
-
MarkdownEngine
|
|
39
|
-
]);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
registerTemplateEngines(engineClasses: ClassType<TemplateEngine>[]): void {
|
|
43
|
-
engineClasses.forEach(EngineClass => {
|
|
44
|
-
const engineName = (EngineClass as any).engineName;
|
|
45
|
-
if (!engineName) {
|
|
46
|
-
throw new Error(`Engine class ${EngineClass.name} must define static engineName property`);
|
|
47
|
-
}
|
|
48
|
-
const options = (this.config.enginesOptions?.template as any)?.[engineName];
|
|
49
|
-
|
|
50
|
-
const customOptions = {
|
|
51
|
-
filters: this.config.enginesOptions?.filters,
|
|
52
|
-
globalValues: this.config.enginesOptions?.globalValues
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
this.registerTemplateEngine(engineName, new EngineClass(options, customOptions));
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
registerTemplateEngine(format: TemplateEngineEnum, engine: TemplateEngine): void {
|
|
60
|
-
this.templateEngines.set(format, engine);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
registerLanguageEngine(format: TemplateLanguageEnum, engine: LanguageEngine): void {
|
|
64
|
-
this.languageEngines.set(format, engine);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
getTemplateEngine(format: TemplateEngineEnum): TemplateEngine {
|
|
68
|
-
const engine = this.templateEngines.get(format);
|
|
69
|
-
if (!engine) {
|
|
70
|
-
throw new Error(`Template engine not found for format: ${format}`);
|
|
71
|
-
}
|
|
72
|
-
return engine;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
getLanguageEngine(format: TemplateLanguageEnum): LanguageEngine {
|
|
76
|
-
const engine = this.languageEngines.get(format);
|
|
77
|
-
if (!engine) {
|
|
78
|
-
throw new Error(`Language engine not found for format: ${format}`);
|
|
79
|
-
}
|
|
80
|
-
return engine;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
registerLanguageEngines(engineClasses: ClassType<LanguageEngine>[]): void {
|
|
84
|
-
engineClasses.forEach(EngineClass => {
|
|
85
|
-
const engineName = (EngineClass as any).engineName;
|
|
86
|
-
if (!engineName) {
|
|
87
|
-
throw new Error(`Engine class ${EngineClass.name} must define static engineName property`);
|
|
88
|
-
}
|
|
89
|
-
const options = (this.config.enginesOptions?.language as any)?.[engineName];
|
|
90
|
-
this.registerLanguageEngine(engineName, new EngineClass(options));
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
hasTemplateEngine(format: TemplateEngineEnum): boolean {
|
|
95
|
-
return this.templateEngines.has(format);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
hasLanguageEngine(format: TemplateLanguageEnum): boolean {
|
|
99
|
-
return this.languageEngines.has(format);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
getSupportedTemplateFormats(): TemplateEngineEnum[] {
|
|
103
|
-
return Array.from(this.templateEngines.keys());
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
getSupportedLanguageFormats(): TemplateLanguageEnum[] {
|
|
107
|
-
return Array.from(this.languageEngines.keys());
|
|
108
|
-
}
|
|
109
|
-
}
|