@ackplus/nest-dynamic-templates 1.1.2 → 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 +1 -1
- package/src/index.js +25 -0
- package/src/lib/constant.js +5 -0
- package/src/lib/dto/create-template-layout.dto.js +86 -0
- package/src/lib/dto/create-template.dto.js +103 -0
- package/src/lib/dto/render-content-template-layout.dto.js +40 -0
- package/src/lib/dto/render-content-template.dto.js +46 -0
- package/src/lib/dto/render-template-layout.dto.js +66 -0
- package/src/lib/dto/render-template.dto.js +90 -0
- package/src/lib/dto/template-filter.dto.js +61 -0
- package/src/lib/dto/template-layout-filter.dto.js +60 -0
- package/src/lib/engines/language/html.engine.js +80 -0
- package/src/lib/engines/language/index.js +11 -0
- package/src/lib/engines/language/markdown.engine.js +39 -0
- package/src/lib/engines/language/mjml.engine.js +75 -0
- package/src/lib/engines/language/text.engine.js +15 -0
- package/src/lib/engines/language-engine.js +6 -0
- package/src/lib/engines/template/ejs.engine.js +65 -0
- package/src/lib/engines/template/handlebars.engine.js +66 -0
- package/src/lib/engines/template/index.js +11 -0
- package/src/lib/engines/template/nunjucks.engine.js +64 -0
- package/src/lib/engines/template/pug.engine.js +74 -0
- package/src/lib/engines/template-engine.js +6 -0
- package/src/lib/entities/template-layout.entity.js +120 -0
- package/src/lib/entities/template.entity.js +127 -0
- package/src/lib/errors/template.errors.js +75 -0
- package/src/lib/interfaces/module-config.interface.js +2 -0
- package/src/lib/interfaces/template.types.js +24 -0
- package/src/lib/nest-dynamic-templates.module.js +131 -0
- package/src/lib/services/template-config.service.js +101 -0
- package/src/lib/services/template-engine.registry.js +93 -0
- package/src/lib/services/template-layout.service.js +343 -0
- package/src/lib/services/template.service.js +414 -0
- package/src/test/helpers.js +33 -0
- package/src/test/test-database.config.js +23 -0
- package/src/test/test.setup.js +30 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NestDynamicTemplate = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const typeorm_1 = require("typeorm");
|
|
6
|
+
const template_types_1 = require("../interfaces/template.types");
|
|
7
|
+
const class_validator_1 = require("class-validator");
|
|
8
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
9
|
+
let NestDynamicTemplate = class NestDynamicTemplate extends typeorm_1.BaseEntity {
|
|
10
|
+
};
|
|
11
|
+
exports.NestDynamicTemplate = NestDynamicTemplate;
|
|
12
|
+
tslib_1.__decorate([
|
|
13
|
+
(0, swagger_1.ApiProperty)({ type: String, format: 'uuid', readOnly: true }),
|
|
14
|
+
(0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
|
|
15
|
+
tslib_1.__metadata("design:type", String)
|
|
16
|
+
], NestDynamicTemplate.prototype, "id", void 0);
|
|
17
|
+
tslib_1.__decorate([
|
|
18
|
+
(0, swagger_1.ApiProperty)({ type: String }),
|
|
19
|
+
(0, class_validator_1.IsString)(),
|
|
20
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
21
|
+
(0, class_validator_1.Matches)(/^[a-z0-9\-_]+$/, { message: 'Invalid template name format' }),
|
|
22
|
+
(0, typeorm_1.Column)(),
|
|
23
|
+
tslib_1.__metadata("design:type", String)
|
|
24
|
+
], NestDynamicTemplate.prototype, "name", void 0);
|
|
25
|
+
tslib_1.__decorate([
|
|
26
|
+
(0, swagger_1.ApiProperty)({ type: String, nullable: true }),
|
|
27
|
+
(0, class_validator_1.IsString)(),
|
|
28
|
+
(0, class_validator_1.IsOptional)(),
|
|
29
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
30
|
+
tslib_1.__metadata("design:type", String)
|
|
31
|
+
], NestDynamicTemplate.prototype, "displayName", void 0);
|
|
32
|
+
tslib_1.__decorate([
|
|
33
|
+
(0, swagger_1.ApiProperty)({ type: String, nullable: true }),
|
|
34
|
+
(0, class_validator_1.IsString)(),
|
|
35
|
+
(0, class_validator_1.IsOptional)(),
|
|
36
|
+
(0, typeorm_1.Column)({ type: 'text', nullable: true }),
|
|
37
|
+
tslib_1.__metadata("design:type", String)
|
|
38
|
+
], NestDynamicTemplate.prototype, "description", void 0);
|
|
39
|
+
tslib_1.__decorate([
|
|
40
|
+
(0, swagger_1.ApiProperty)({ type: String, nullable: true }),
|
|
41
|
+
(0, class_validator_1.IsString)(),
|
|
42
|
+
(0, class_validator_1.IsOptional)(),
|
|
43
|
+
(0, typeorm_1.Column)({ type: 'text', nullable: true }),
|
|
44
|
+
tslib_1.__metadata("design:type", String)
|
|
45
|
+
], NestDynamicTemplate.prototype, "type", void 0);
|
|
46
|
+
tslib_1.__decorate([
|
|
47
|
+
(0, swagger_1.ApiProperty)({ enum: template_types_1.TemplateEngineEnum, type: String }),
|
|
48
|
+
(0, class_validator_1.IsEnum)(template_types_1.TemplateEngineEnum),
|
|
49
|
+
(0, typeorm_1.Column)({
|
|
50
|
+
type: 'text',
|
|
51
|
+
enum: template_types_1.TemplateEngineEnum,
|
|
52
|
+
default: template_types_1.TemplateEngineEnum.NUNJUCKS
|
|
53
|
+
}),
|
|
54
|
+
tslib_1.__metadata("design:type", String)
|
|
55
|
+
], NestDynamicTemplate.prototype, "engine", void 0);
|
|
56
|
+
tslib_1.__decorate([
|
|
57
|
+
(0, swagger_1.ApiProperty)({ enum: template_types_1.TemplateLanguageEnum, type: String, nullable: true }),
|
|
58
|
+
(0, class_validator_1.IsEnum)(template_types_1.TemplateLanguageEnum),
|
|
59
|
+
(0, class_validator_1.IsOptional)(),
|
|
60
|
+
(0, typeorm_1.Column)({ type: 'text' }),
|
|
61
|
+
tslib_1.__metadata("design:type", String)
|
|
62
|
+
], NestDynamicTemplate.prototype, "language", void 0);
|
|
63
|
+
tslib_1.__decorate([
|
|
64
|
+
(0, swagger_1.ApiProperty)({ type: String, nullable: true }),
|
|
65
|
+
(0, class_validator_1.IsString)(),
|
|
66
|
+
(0, class_validator_1.IsOptional)(),
|
|
67
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
68
|
+
tslib_1.__metadata("design:type", String)
|
|
69
|
+
], NestDynamicTemplate.prototype, "subject", void 0);
|
|
70
|
+
tslib_1.__decorate([
|
|
71
|
+
(0, swagger_1.ApiProperty)({ type: String }),
|
|
72
|
+
(0, class_validator_1.IsString)(),
|
|
73
|
+
(0, class_validator_1.IsOptional)(),
|
|
74
|
+
(0, typeorm_1.Column)('text'),
|
|
75
|
+
tslib_1.__metadata("design:type", String)
|
|
76
|
+
], NestDynamicTemplate.prototype, "content", void 0);
|
|
77
|
+
tslib_1.__decorate([
|
|
78
|
+
(0, swagger_1.ApiProperty)({ type: String, nullable: true }),
|
|
79
|
+
(0, class_validator_1.IsString)(),
|
|
80
|
+
(0, class_validator_1.IsOptional)(),
|
|
81
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
82
|
+
tslib_1.__metadata("design:type", String)
|
|
83
|
+
], NestDynamicTemplate.prototype, "templateLayoutName", void 0);
|
|
84
|
+
tslib_1.__decorate([
|
|
85
|
+
(0, swagger_1.ApiProperty)({ type: String, nullable: true }),
|
|
86
|
+
(0, class_validator_1.IsString)(),
|
|
87
|
+
(0, typeorm_1.Column)({ nullable: true, default: 'system' }),
|
|
88
|
+
tslib_1.__metadata("design:type", String)
|
|
89
|
+
], NestDynamicTemplate.prototype, "scope", void 0);
|
|
90
|
+
tslib_1.__decorate([
|
|
91
|
+
(0, swagger_1.ApiProperty)({ type: String, nullable: true }),
|
|
92
|
+
(0, class_validator_1.IsString)(),
|
|
93
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
94
|
+
tslib_1.__metadata("design:type", String)
|
|
95
|
+
], NestDynamicTemplate.prototype, "scopeId", void 0);
|
|
96
|
+
tslib_1.__decorate([
|
|
97
|
+
(0, swagger_1.ApiProperty)({ type: String, nullable: true }),
|
|
98
|
+
(0, class_validator_1.IsString)(),
|
|
99
|
+
(0, typeorm_1.Column)({ nullable: true, default: 'en' }),
|
|
100
|
+
tslib_1.__metadata("design:type", String)
|
|
101
|
+
], NestDynamicTemplate.prototype, "locale", void 0);
|
|
102
|
+
tslib_1.__decorate([
|
|
103
|
+
(0, swagger_1.ApiProperty)({ type: Object, nullable: true }),
|
|
104
|
+
(0, class_validator_1.IsOptional)(),
|
|
105
|
+
(0, typeorm_1.Column)('simple-json', { nullable: true }),
|
|
106
|
+
tslib_1.__metadata("design:type", Object)
|
|
107
|
+
], NestDynamicTemplate.prototype, "previewContext", void 0);
|
|
108
|
+
tslib_1.__decorate([
|
|
109
|
+
(0, swagger_1.ApiProperty)({ type: Boolean }),
|
|
110
|
+
(0, class_validator_1.IsBoolean)(),
|
|
111
|
+
(0, typeorm_1.Column)({ default: true }),
|
|
112
|
+
tslib_1.__metadata("design:type", Boolean)
|
|
113
|
+
], NestDynamicTemplate.prototype, "isActive", void 0);
|
|
114
|
+
tslib_1.__decorate([
|
|
115
|
+
(0, swagger_1.ApiProperty)({ type: Date, readOnly: true }),
|
|
116
|
+
(0, typeorm_1.CreateDateColumn)(),
|
|
117
|
+
tslib_1.__metadata("design:type", Date)
|
|
118
|
+
], NestDynamicTemplate.prototype, "createdAt", void 0);
|
|
119
|
+
tslib_1.__decorate([
|
|
120
|
+
(0, swagger_1.ApiProperty)({ type: Date, readOnly: true }),
|
|
121
|
+
(0, typeorm_1.UpdateDateColumn)(),
|
|
122
|
+
tslib_1.__metadata("design:type", Date)
|
|
123
|
+
], NestDynamicTemplate.prototype, "updatedAt", void 0);
|
|
124
|
+
exports.NestDynamicTemplate = NestDynamicTemplate = tslib_1.__decorate([
|
|
125
|
+
(0, typeorm_1.Entity)('nest_dynamic_templates'),
|
|
126
|
+
(0, typeorm_1.Index)(['name', 'scope', 'scopeId', 'locale'], { unique: true })
|
|
127
|
+
], NestDynamicTemplate);
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TemplateValidationError = exports.TemplateContentError = exports.TemplateLayoutError = exports.TemplateLanguageError = exports.TemplateEngineError = exports.TemplateRenderError = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
class TemplateRenderError extends common_1.InternalServerErrorException {
|
|
6
|
+
constructor(operation, originalError, templateName) {
|
|
7
|
+
const message = templateName
|
|
8
|
+
? `Failed to render template '${templateName}' during ${operation}: ${originalError.message}`
|
|
9
|
+
: `Failed to render content during ${operation}: ${originalError.message}`;
|
|
10
|
+
super({
|
|
11
|
+
message,
|
|
12
|
+
error: 'TEMPLATE_RENDER_ERROR',
|
|
13
|
+
operation,
|
|
14
|
+
templateName,
|
|
15
|
+
originalError: originalError.message,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.TemplateRenderError = TemplateRenderError;
|
|
20
|
+
class TemplateEngineError extends common_1.InternalServerErrorException {
|
|
21
|
+
constructor(engine, originalError) {
|
|
22
|
+
super({
|
|
23
|
+
message: `Template engine '${engine}' failed to render content: ${originalError.message}`,
|
|
24
|
+
error: 'TEMPLATE_ENGINE_ERROR',
|
|
25
|
+
engine,
|
|
26
|
+
originalError: originalError.message,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.TemplateEngineError = TemplateEngineError;
|
|
31
|
+
class TemplateLanguageError extends common_1.InternalServerErrorException {
|
|
32
|
+
constructor(language, originalError) {
|
|
33
|
+
super({
|
|
34
|
+
message: `Language processor '${language}' failed to render content: ${originalError.message}`,
|
|
35
|
+
error: 'TEMPLATE_LANGUAGE_ERROR',
|
|
36
|
+
language,
|
|
37
|
+
originalError: originalError.message,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.TemplateLanguageError = TemplateLanguageError;
|
|
42
|
+
class TemplateLayoutError extends common_1.InternalServerErrorException {
|
|
43
|
+
constructor(layoutName, originalError) {
|
|
44
|
+
super({
|
|
45
|
+
message: `Template layout '${layoutName}' failed to render: ${originalError.message}`,
|
|
46
|
+
error: 'TEMPLATE_LAYOUT_ERROR',
|
|
47
|
+
layoutName,
|
|
48
|
+
originalError: originalError.message,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.TemplateLayoutError = TemplateLayoutError;
|
|
53
|
+
class TemplateContentError extends common_1.InternalServerErrorException {
|
|
54
|
+
constructor(contentType, originalError) {
|
|
55
|
+
super({
|
|
56
|
+
message: `Failed to process ${contentType} content: ${originalError.message}`,
|
|
57
|
+
error: 'TEMPLATE_CONTENT_ERROR',
|
|
58
|
+
contentType,
|
|
59
|
+
originalError: originalError.message,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.TemplateContentError = TemplateContentError;
|
|
64
|
+
class TemplateValidationError extends common_1.BadRequestException {
|
|
65
|
+
constructor(field, value, reason) {
|
|
66
|
+
super({
|
|
67
|
+
message: `Template validation failed for field '${field}': ${reason}`,
|
|
68
|
+
error: 'TEMPLATE_VALIDATION_ERROR',
|
|
69
|
+
field,
|
|
70
|
+
value,
|
|
71
|
+
reason,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.TemplateValidationError = TemplateValidationError;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TemplateLanguageEnum = exports.TemplateEngineEnum = exports.TemplateTypeEnum = void 0;
|
|
4
|
+
var TemplateTypeEnum;
|
|
5
|
+
(function (TemplateTypeEnum) {
|
|
6
|
+
TemplateTypeEnum["EMAIL"] = "email";
|
|
7
|
+
TemplateTypeEnum["SMS"] = "sms";
|
|
8
|
+
TemplateTypeEnum["PUSH"] = "push";
|
|
9
|
+
TemplateTypeEnum["PDF"] = "pdf";
|
|
10
|
+
})(TemplateTypeEnum || (exports.TemplateTypeEnum = TemplateTypeEnum = {}));
|
|
11
|
+
var TemplateEngineEnum;
|
|
12
|
+
(function (TemplateEngineEnum) {
|
|
13
|
+
TemplateEngineEnum["NUNJUCKS"] = "njk";
|
|
14
|
+
TemplateEngineEnum["HANDLEBARS"] = "hbs";
|
|
15
|
+
TemplateEngineEnum["EJS"] = "ejs";
|
|
16
|
+
TemplateEngineEnum["PUG"] = "pug";
|
|
17
|
+
})(TemplateEngineEnum || (exports.TemplateEngineEnum = TemplateEngineEnum = {}));
|
|
18
|
+
var TemplateLanguageEnum;
|
|
19
|
+
(function (TemplateLanguageEnum) {
|
|
20
|
+
TemplateLanguageEnum["MJML"] = "mjml";
|
|
21
|
+
TemplateLanguageEnum["HTML"] = "html";
|
|
22
|
+
TemplateLanguageEnum["MARKDOWN"] = "md";
|
|
23
|
+
TemplateLanguageEnum["TEXT"] = "txt";
|
|
24
|
+
})(TemplateLanguageEnum || (exports.TemplateLanguageEnum = TemplateLanguageEnum = {}));
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var NestDynamicTemplatesModule_1;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.NestDynamicTemplatesModule = void 0;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const common_1 = require("@nestjs/common");
|
|
7
|
+
const typeorm_1 = require("@nestjs/typeorm");
|
|
8
|
+
const template_entity_1 = require("./entities/template.entity");
|
|
9
|
+
const template_layout_entity_1 = require("./entities/template-layout.entity");
|
|
10
|
+
const deepmerge_1 = tslib_1.__importDefault(require("deepmerge"));
|
|
11
|
+
const template_engine_registry_1 = require("./services/template-engine.registry");
|
|
12
|
+
const template_layout_service_1 = require("./services/template-layout.service");
|
|
13
|
+
const template_service_1 = require("./services/template.service");
|
|
14
|
+
const template_config_service_1 = require("./services/template-config.service");
|
|
15
|
+
const constant_1 = require("./constant");
|
|
16
|
+
const template_types_1 = require("./interfaces/template.types");
|
|
17
|
+
const template_types_2 = require("./interfaces/template.types");
|
|
18
|
+
const defaultConfig = {
|
|
19
|
+
engines: {
|
|
20
|
+
template: [template_types_1.TemplateEngineEnum.NUNJUCKS],
|
|
21
|
+
language: [template_types_2.TemplateLanguageEnum.HTML, template_types_2.TemplateLanguageEnum.MJML, template_types_2.TemplateLanguageEnum.TEXT]
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
let NestDynamicTemplatesModule = NestDynamicTemplatesModule_1 = class NestDynamicTemplatesModule {
|
|
25
|
+
static forRoot(config = {}) {
|
|
26
|
+
const mergedConfig = this.getOptions(config);
|
|
27
|
+
// Set options in static service
|
|
28
|
+
template_config_service_1.TemplateConfigService.setOptions(mergedConfig);
|
|
29
|
+
return {
|
|
30
|
+
module: NestDynamicTemplatesModule_1,
|
|
31
|
+
global: mergedConfig.isGlobal,
|
|
32
|
+
imports: [
|
|
33
|
+
typeorm_1.TypeOrmModule.forFeature([template_entity_1.NestDynamicTemplate, template_layout_entity_1.NestDynamicTemplateLayout]),
|
|
34
|
+
],
|
|
35
|
+
providers: [
|
|
36
|
+
template_config_service_1.TemplateConfigService,
|
|
37
|
+
template_engine_registry_1.TemplateEngineRegistryService,
|
|
38
|
+
template_layout_service_1.TemplateLayoutService,
|
|
39
|
+
template_service_1.TemplateService,
|
|
40
|
+
],
|
|
41
|
+
exports: [
|
|
42
|
+
template_config_service_1.TemplateConfigService,
|
|
43
|
+
template_service_1.TemplateService,
|
|
44
|
+
template_layout_service_1.TemplateLayoutService,
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
static forRootAsync(options) {
|
|
49
|
+
const asyncProviders = this.createAsyncProviders(options);
|
|
50
|
+
return {
|
|
51
|
+
module: NestDynamicTemplatesModule_1,
|
|
52
|
+
global: options.isGlobal,
|
|
53
|
+
imports: [
|
|
54
|
+
typeorm_1.TypeOrmModule.forFeature([template_entity_1.NestDynamicTemplate, template_layout_entity_1.NestDynamicTemplateLayout]),
|
|
55
|
+
...(options.imports || []),
|
|
56
|
+
],
|
|
57
|
+
providers: [
|
|
58
|
+
...asyncProviders,
|
|
59
|
+
template_config_service_1.TemplateConfigService,
|
|
60
|
+
template_engine_registry_1.TemplateEngineRegistryService,
|
|
61
|
+
template_layout_service_1.TemplateLayoutService,
|
|
62
|
+
template_service_1.TemplateService,
|
|
63
|
+
],
|
|
64
|
+
exports: [
|
|
65
|
+
template_config_service_1.TemplateConfigService,
|
|
66
|
+
template_service_1.TemplateService,
|
|
67
|
+
template_layout_service_1.TemplateLayoutService,
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
static createAsyncProviders(options) {
|
|
72
|
+
if (options.useExisting || options.useFactory) {
|
|
73
|
+
return [this.createAsyncOptionsProvider(options)];
|
|
74
|
+
}
|
|
75
|
+
if (options.useClass) {
|
|
76
|
+
return [
|
|
77
|
+
this.createAsyncOptionsProvider(options),
|
|
78
|
+
{
|
|
79
|
+
provide: options.useClass,
|
|
80
|
+
useClass: options.useClass,
|
|
81
|
+
},
|
|
82
|
+
];
|
|
83
|
+
}
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
static createAsyncOptionsProvider(options) {
|
|
87
|
+
if (options.useFactory) {
|
|
88
|
+
return {
|
|
89
|
+
provide: constant_1.NEST_DYNAMIC_TEMPLATES_ASYNC_OPTIONS_PROVIDER,
|
|
90
|
+
useFactory: async (...args) => {
|
|
91
|
+
const userOptions = options.useFactory ? await options.useFactory(...args) : {};
|
|
92
|
+
const mergedOptions = this.getOptions(userOptions);
|
|
93
|
+
template_config_service_1.TemplateConfigService.setOptions(mergedOptions);
|
|
94
|
+
return mergedOptions;
|
|
95
|
+
},
|
|
96
|
+
inject: options.inject || [],
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
provide: constant_1.NEST_DYNAMIC_TEMPLATES_ASYNC_OPTIONS_PROVIDER,
|
|
101
|
+
useFactory: async (optionsFactory) => {
|
|
102
|
+
const userOptions = await optionsFactory.createNestDynamicTemplatesModuleOptions();
|
|
103
|
+
const mergedOptions = this.getOptions(userOptions);
|
|
104
|
+
template_config_service_1.TemplateConfigService.setOptions(mergedOptions);
|
|
105
|
+
return mergedOptions;
|
|
106
|
+
},
|
|
107
|
+
inject: [options.useExisting || options.useClass],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
static getOptions(options) {
|
|
111
|
+
return (0, deepmerge_1.default)(this.moduleDefaultOptions, options);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
exports.NestDynamicTemplatesModule = NestDynamicTemplatesModule;
|
|
115
|
+
NestDynamicTemplatesModule.moduleDefaultOptions = defaultConfig;
|
|
116
|
+
exports.NestDynamicTemplatesModule = NestDynamicTemplatesModule = NestDynamicTemplatesModule_1 = tslib_1.__decorate([
|
|
117
|
+
(0, common_1.Module)({
|
|
118
|
+
imports: [typeorm_1.TypeOrmModule.forFeature([template_entity_1.NestDynamicTemplate, template_layout_entity_1.NestDynamicTemplateLayout])],
|
|
119
|
+
providers: [
|
|
120
|
+
template_config_service_1.TemplateConfigService,
|
|
121
|
+
template_engine_registry_1.TemplateEngineRegistryService,
|
|
122
|
+
template_layout_service_1.TemplateLayoutService,
|
|
123
|
+
template_service_1.TemplateService,
|
|
124
|
+
],
|
|
125
|
+
exports: [
|
|
126
|
+
template_config_service_1.TemplateConfigService,
|
|
127
|
+
template_service_1.TemplateService,
|
|
128
|
+
template_layout_service_1.TemplateLayoutService,
|
|
129
|
+
],
|
|
130
|
+
})
|
|
131
|
+
], NestDynamicTemplatesModule);
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TemplateConfigService = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const template_types_1 = require("../interfaces/template.types");
|
|
7
|
+
let TemplateConfigService = class TemplateConfigService {
|
|
8
|
+
/**
|
|
9
|
+
* Set the configuration options
|
|
10
|
+
*/
|
|
11
|
+
static setOptions(config) {
|
|
12
|
+
this.config = { ...this.defaultConfig, ...config };
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Get the current configuration options
|
|
16
|
+
*/
|
|
17
|
+
static getOptions() {
|
|
18
|
+
if (!this.config) {
|
|
19
|
+
return this.defaultConfig;
|
|
20
|
+
}
|
|
21
|
+
return this.config;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Check if configuration has been set
|
|
25
|
+
*/
|
|
26
|
+
static hasConfig() {
|
|
27
|
+
return !!this.config;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Reset configuration to default
|
|
31
|
+
*/
|
|
32
|
+
static reset() {
|
|
33
|
+
this.config = { ...this.defaultConfig };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get a specific configuration value
|
|
37
|
+
*/
|
|
38
|
+
static get(key) {
|
|
39
|
+
const config = this.getOptions();
|
|
40
|
+
return config[key];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Check if a template engine is enabled
|
|
44
|
+
*/
|
|
45
|
+
static isTemplateEngineEnabled(engine) {
|
|
46
|
+
const config = this.getOptions();
|
|
47
|
+
return config.engines?.template?.includes(engine) ?? false;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Check if a language engine is enabled
|
|
51
|
+
*/
|
|
52
|
+
static isLanguageEngineEnabled(language) {
|
|
53
|
+
const config = this.getOptions();
|
|
54
|
+
return config.engines?.language?.includes(language) ?? false;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get enabled template engines
|
|
58
|
+
*/
|
|
59
|
+
static getEnabledTemplateEngines() {
|
|
60
|
+
const config = this.getOptions();
|
|
61
|
+
return config.engines?.template ?? this.defaultConfig.engines.template;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get enabled language engines
|
|
65
|
+
*/
|
|
66
|
+
static getEnabledLanguageEngines() {
|
|
67
|
+
const config = this.getOptions();
|
|
68
|
+
return config.engines?.language ?? this.defaultConfig.engines.language;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get engine options for a specific template engine
|
|
72
|
+
*/
|
|
73
|
+
static getTemplateEngineOptions(engine) {
|
|
74
|
+
const config = this.getOptions();
|
|
75
|
+
return config.enginesOptions?.template?.[engine];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get engine options for a specific language engine
|
|
79
|
+
*/
|
|
80
|
+
static getLanguageEngineOptions(language) {
|
|
81
|
+
const config = this.getOptions();
|
|
82
|
+
return config.enginesOptions?.language?.[language];
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get custom filters
|
|
86
|
+
*/
|
|
87
|
+
static getCustomFilters() {
|
|
88
|
+
const config = this.getOptions();
|
|
89
|
+
return config.enginesOptions?.filters ?? {};
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
exports.TemplateConfigService = TemplateConfigService;
|
|
93
|
+
TemplateConfigService.defaultConfig = {
|
|
94
|
+
engines: {
|
|
95
|
+
template: [template_types_1.TemplateEngineEnum.NUNJUCKS],
|
|
96
|
+
language: [template_types_1.TemplateLanguageEnum.HTML, template_types_1.TemplateLanguageEnum.MJML, template_types_1.TemplateLanguageEnum.TEXT]
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
exports.TemplateConfigService = TemplateConfigService = tslib_1.__decorate([
|
|
100
|
+
(0, common_1.Injectable)()
|
|
101
|
+
], TemplateConfigService);
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TemplateEngineRegistryService = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const nunjucks_engine_1 = require("../engines/template/nunjucks.engine");
|
|
7
|
+
const mjml_engine_1 = require("../engines/language/mjml.engine");
|
|
8
|
+
const html_engine_1 = require("../engines/language/html.engine");
|
|
9
|
+
const language_1 = require("../engines/language");
|
|
10
|
+
const ejs_engine_1 = require("../engines/template/ejs.engine");
|
|
11
|
+
const handlebars_engine_1 = require("../engines/template/handlebars.engine");
|
|
12
|
+
const pug_engine_1 = require("../engines/template/pug.engine");
|
|
13
|
+
const template_config_service_1 = require("./template-config.service");
|
|
14
|
+
let TemplateEngineRegistryService = class TemplateEngineRegistryService {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.templateEngines = new Map();
|
|
17
|
+
this.languageEngines = new Map();
|
|
18
|
+
this.config = template_config_service_1.TemplateConfigService.getOptions();
|
|
19
|
+
this.registerTemplateEngines([
|
|
20
|
+
nunjucks_engine_1.NunjucksEngine,
|
|
21
|
+
handlebars_engine_1.HandlebarsEngine,
|
|
22
|
+
ejs_engine_1.EjsEngine,
|
|
23
|
+
pug_engine_1.PugEngine
|
|
24
|
+
]);
|
|
25
|
+
this.registerLanguageEngines([
|
|
26
|
+
mjml_engine_1.MjmlEngine,
|
|
27
|
+
html_engine_1.HtmlEngine,
|
|
28
|
+
language_1.TextEngine,
|
|
29
|
+
language_1.MarkdownEngine
|
|
30
|
+
]);
|
|
31
|
+
}
|
|
32
|
+
registerTemplateEngines(engineClasses) {
|
|
33
|
+
engineClasses.forEach(EngineClass => {
|
|
34
|
+
const engineName = EngineClass.engineName;
|
|
35
|
+
if (!engineName) {
|
|
36
|
+
throw new Error(`Engine class ${EngineClass.name} must define static engineName property`);
|
|
37
|
+
}
|
|
38
|
+
const options = this.config.enginesOptions?.template?.[engineName];
|
|
39
|
+
const customOptions = {
|
|
40
|
+
filters: this.config.enginesOptions?.filters,
|
|
41
|
+
globalValues: this.config.enginesOptions?.globalValues
|
|
42
|
+
};
|
|
43
|
+
this.registerTemplateEngine(engineName, new EngineClass(options, customOptions));
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
registerTemplateEngine(format, engine) {
|
|
47
|
+
this.templateEngines.set(format, engine);
|
|
48
|
+
}
|
|
49
|
+
registerLanguageEngine(format, engine) {
|
|
50
|
+
this.languageEngines.set(format, engine);
|
|
51
|
+
}
|
|
52
|
+
getTemplateEngine(format) {
|
|
53
|
+
const engine = this.templateEngines.get(format);
|
|
54
|
+
if (!engine) {
|
|
55
|
+
throw new Error(`Template engine not found for format: ${format}`);
|
|
56
|
+
}
|
|
57
|
+
return engine;
|
|
58
|
+
}
|
|
59
|
+
getLanguageEngine(format) {
|
|
60
|
+
const engine = this.languageEngines.get(format);
|
|
61
|
+
if (!engine) {
|
|
62
|
+
throw new Error(`Language engine not found for format: ${format}`);
|
|
63
|
+
}
|
|
64
|
+
return engine;
|
|
65
|
+
}
|
|
66
|
+
registerLanguageEngines(engineClasses) {
|
|
67
|
+
engineClasses.forEach(EngineClass => {
|
|
68
|
+
const engineName = EngineClass.engineName;
|
|
69
|
+
if (!engineName) {
|
|
70
|
+
throw new Error(`Engine class ${EngineClass.name} must define static engineName property`);
|
|
71
|
+
}
|
|
72
|
+
const options = this.config.enginesOptions?.language?.[engineName];
|
|
73
|
+
this.registerLanguageEngine(engineName, new EngineClass(options));
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
hasTemplateEngine(format) {
|
|
77
|
+
return this.templateEngines.has(format);
|
|
78
|
+
}
|
|
79
|
+
hasLanguageEngine(format) {
|
|
80
|
+
return this.languageEngines.has(format);
|
|
81
|
+
}
|
|
82
|
+
getSupportedTemplateFormats() {
|
|
83
|
+
return Array.from(this.templateEngines.keys());
|
|
84
|
+
}
|
|
85
|
+
getSupportedLanguageFormats() {
|
|
86
|
+
return Array.from(this.languageEngines.keys());
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
exports.TemplateEngineRegistryService = TemplateEngineRegistryService;
|
|
90
|
+
exports.TemplateEngineRegistryService = TemplateEngineRegistryService = tslib_1.__decorate([
|
|
91
|
+
(0, common_1.Injectable)(),
|
|
92
|
+
tslib_1.__metadata("design:paramtypes", [])
|
|
93
|
+
], TemplateEngineRegistryService);
|