@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,258 +1,212 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
@Injectable()
|
|
18
|
-
export class TemplateLayoutService {
|
|
19
|
-
constructor(
|
|
20
|
-
@InjectRepository(NestDynamicTemplateLayout)
|
|
21
|
-
private readonly layoutRepository: Repository<NestDynamicTemplateLayout>,
|
|
22
|
-
private readonly engineRegistry: TemplateEngineRegistryService
|
|
23
|
-
) { }
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
async render(renderDto: RenderTemplateLayoutDto): Promise<RenderTemplateLayoutOutput> {
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TemplateLayoutService = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const typeorm_1 = require("@nestjs/typeorm");
|
|
7
|
+
const typeorm_2 = require("typeorm");
|
|
8
|
+
const template_layout_entity_1 = require("../entities/template-layout.entity");
|
|
9
|
+
const template_engine_registry_1 = require("./template-engine.registry");
|
|
10
|
+
const template_errors_1 = require("../errors/template.errors");
|
|
11
|
+
let TemplateLayoutService = class TemplateLayoutService {
|
|
12
|
+
constructor(layoutRepository, engineRegistry) {
|
|
13
|
+
this.layoutRepository = layoutRepository;
|
|
14
|
+
this.engineRegistry = engineRegistry;
|
|
15
|
+
}
|
|
16
|
+
async render(renderDto) {
|
|
27
17
|
const { name, scope, scopeId, locale, context } = renderDto;
|
|
28
|
-
|
|
29
18
|
try {
|
|
30
19
|
// Find template with fallback
|
|
31
20
|
const templateLayout = await this.findTemplateLayout(name, scope, scopeId, locale);
|
|
32
21
|
if (!templateLayout) {
|
|
33
|
-
throw new NotFoundException(`Template layout not found: ${name} in scope ${scope || 'system'}`);
|
|
22
|
+
throw new common_1.NotFoundException(`Template layout not found: ${name} in scope ${scope || 'system'}`);
|
|
34
23
|
}
|
|
35
|
-
|
|
36
24
|
// Validate content exists
|
|
37
25
|
if (!templateLayout.content) {
|
|
38
|
-
throw new BadRequestException(`Template layout '${name}' has no content to render`);
|
|
26
|
+
throw new common_1.BadRequestException(`Template layout '${name}' has no content to render`);
|
|
39
27
|
}
|
|
40
|
-
|
|
41
28
|
let content = templateLayout.content;
|
|
42
|
-
|
|
43
29
|
// Render content by template engine
|
|
44
30
|
if (templateLayout.engine) {
|
|
45
31
|
try {
|
|
46
32
|
content = await this.renderEngine(templateLayout.engine, content, context || {});
|
|
47
|
-
}
|
|
48
|
-
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
throw new template_errors_1.TemplateEngineError(templateLayout.engine, error);
|
|
49
36
|
}
|
|
50
37
|
}
|
|
51
|
-
|
|
52
38
|
// If template has language format, process with language engine
|
|
53
39
|
if (templateLayout.language) {
|
|
54
40
|
try {
|
|
55
41
|
content = await this.renderLanguage(templateLayout.language, content, context || {});
|
|
56
|
-
}
|
|
57
|
-
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
throw new template_errors_1.TemplateLanguageError(templateLayout.language, error);
|
|
58
45
|
}
|
|
59
46
|
}
|
|
60
|
-
|
|
61
47
|
return {
|
|
62
48
|
content
|
|
63
49
|
};
|
|
64
|
-
}
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
65
52
|
// Re-throw known template errors
|
|
66
|
-
if (error instanceof TemplateEngineError ||
|
|
67
|
-
error instanceof TemplateLanguageError ||
|
|
68
|
-
error instanceof NotFoundException ||
|
|
69
|
-
error instanceof BadRequestException) {
|
|
53
|
+
if (error instanceof template_errors_1.TemplateEngineError ||
|
|
54
|
+
error instanceof template_errors_1.TemplateLanguageError ||
|
|
55
|
+
error instanceof common_1.NotFoundException ||
|
|
56
|
+
error instanceof common_1.BadRequestException) {
|
|
70
57
|
throw error;
|
|
71
58
|
}
|
|
72
|
-
|
|
73
59
|
// Wrap unknown errors
|
|
74
|
-
throw new TemplateRenderError('template layout rendering', error
|
|
60
|
+
throw new template_errors_1.TemplateRenderError('template layout rendering', error, name);
|
|
75
61
|
}
|
|
76
62
|
}
|
|
77
|
-
|
|
78
|
-
async renderContent(input: RenderContentTemplateLayoutDto): Promise<string> {
|
|
63
|
+
async renderContent(input) {
|
|
79
64
|
const { content, language, engine, context } = input;
|
|
80
|
-
|
|
81
65
|
try {
|
|
82
66
|
if (!content) {
|
|
83
|
-
throw new BadRequestException('Content is required for template layout rendering');
|
|
67
|
+
throw new common_1.BadRequestException('Content is required for template layout rendering');
|
|
84
68
|
}
|
|
85
|
-
|
|
86
69
|
let renderContent = content;
|
|
87
|
-
|
|
88
70
|
// Render content by template engine
|
|
89
71
|
if (engine) {
|
|
90
72
|
try {
|
|
91
73
|
renderContent = await this.renderEngine(engine, content, context || {});
|
|
92
|
-
}
|
|
93
|
-
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
throw new template_errors_1.TemplateEngineError(engine, error);
|
|
94
77
|
}
|
|
95
78
|
}
|
|
96
|
-
|
|
97
79
|
// Render content by language engine
|
|
98
80
|
if (language) {
|
|
99
81
|
try {
|
|
100
82
|
renderContent = await this.renderLanguage(language, renderContent, context || {});
|
|
101
|
-
}
|
|
102
|
-
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
throw new template_errors_1.TemplateLanguageError(language, error);
|
|
103
86
|
}
|
|
104
87
|
}
|
|
105
|
-
|
|
106
88
|
return renderContent;
|
|
107
|
-
}
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
108
91
|
// Re-throw known template errors
|
|
109
|
-
if (error instanceof TemplateEngineError ||
|
|
110
|
-
error instanceof TemplateLanguageError ||
|
|
111
|
-
error instanceof BadRequestException) {
|
|
92
|
+
if (error instanceof template_errors_1.TemplateEngineError ||
|
|
93
|
+
error instanceof template_errors_1.TemplateLanguageError ||
|
|
94
|
+
error instanceof common_1.BadRequestException) {
|
|
112
95
|
throw error;
|
|
113
96
|
}
|
|
114
|
-
|
|
115
97
|
// Wrap unknown errors
|
|
116
|
-
throw new TemplateRenderError('template layout content rendering', error
|
|
98
|
+
throw new template_errors_1.TemplateRenderError('template layout content rendering', error);
|
|
117
99
|
}
|
|
118
100
|
}
|
|
119
|
-
|
|
120
|
-
async renderLanguage(language: TemplateLanguageEnum, content: string, context: Record<string, any>): Promise<string> {
|
|
101
|
+
async renderLanguage(language, content, context) {
|
|
121
102
|
try {
|
|
122
103
|
if (!content) {
|
|
123
|
-
throw new BadRequestException('Content is required for language rendering');
|
|
104
|
+
throw new common_1.BadRequestException('Content is required for language rendering');
|
|
124
105
|
}
|
|
125
|
-
|
|
126
106
|
const languageEngine = this.engineRegistry.getLanguageEngine(language);
|
|
127
107
|
if (!languageEngine) {
|
|
128
|
-
throw new BadRequestException(`Language engine not found for: ${language}`);
|
|
108
|
+
throw new common_1.BadRequestException(`Language engine not found for: ${language}`);
|
|
129
109
|
}
|
|
130
|
-
|
|
131
110
|
return await languageEngine.render(content, context);
|
|
132
|
-
}
|
|
133
|
-
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
if (error instanceof common_1.BadRequestException) {
|
|
134
114
|
throw error;
|
|
135
115
|
}
|
|
136
|
-
throw new TemplateLanguageError(language, error
|
|
116
|
+
throw new template_errors_1.TemplateLanguageError(language, error);
|
|
137
117
|
}
|
|
138
118
|
}
|
|
139
|
-
|
|
140
|
-
async renderEngine(engine: TemplateEngineEnum, content: string, context: Record<string, any>): Promise<string> {
|
|
119
|
+
async renderEngine(engine, content, context) {
|
|
141
120
|
try {
|
|
142
121
|
if (!content) {
|
|
143
|
-
throw new BadRequestException('Content is required for engine rendering');
|
|
122
|
+
throw new common_1.BadRequestException('Content is required for engine rendering');
|
|
144
123
|
}
|
|
145
|
-
|
|
146
124
|
const templateEngine = this.engineRegistry.getTemplateEngine(engine);
|
|
147
125
|
if (!templateEngine) {
|
|
148
|
-
throw new BadRequestException(`Template engine not found for: ${engine}`);
|
|
126
|
+
throw new common_1.BadRequestException(`Template engine not found for: ${engine}`);
|
|
149
127
|
}
|
|
150
|
-
|
|
151
128
|
return await templateEngine.render(content, context);
|
|
152
|
-
}
|
|
153
|
-
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
if (error instanceof common_1.BadRequestException) {
|
|
154
132
|
throw error;
|
|
155
133
|
}
|
|
156
|
-
throw new TemplateEngineError(engine, error
|
|
134
|
+
throw new template_errors_1.TemplateEngineError(engine, error);
|
|
157
135
|
}
|
|
158
136
|
}
|
|
159
|
-
|
|
160
137
|
/**
|
|
161
138
|
* Get all templates, with scoped templates taking precedence over system templates
|
|
162
139
|
*/
|
|
163
|
-
async getTemplateLayouts(filter
|
|
164
|
-
const {
|
|
165
|
-
scope,
|
|
166
|
-
scopeId,
|
|
167
|
-
type,
|
|
168
|
-
locale,
|
|
169
|
-
excludeNames = [],
|
|
170
|
-
} = filter;
|
|
171
|
-
|
|
172
|
-
|
|
140
|
+
async getTemplateLayouts(filter = {}) {
|
|
141
|
+
const { scope, scopeId, type, locale, excludeNames = [], } = filter;
|
|
173
142
|
// Build the where clause
|
|
174
|
-
const where
|
|
175
|
-
if (type)
|
|
176
|
-
|
|
177
|
-
if (
|
|
178
|
-
|
|
143
|
+
const where = {};
|
|
144
|
+
if (type)
|
|
145
|
+
where.type = type;
|
|
146
|
+
if (locale)
|
|
147
|
+
where.locale = locale;
|
|
148
|
+
if (excludeNames.length > 0)
|
|
149
|
+
where.name = (0, typeorm_2.Not)((0, typeorm_2.In)(excludeNames));
|
|
179
150
|
const systemTemplates = await this.layoutRepository.find({
|
|
180
151
|
where: {
|
|
181
152
|
...where,
|
|
182
153
|
scope: 'system',
|
|
183
|
-
scopeId: IsNull(),
|
|
154
|
+
scopeId: (0, typeorm_2.IsNull)(),
|
|
184
155
|
},
|
|
185
156
|
});
|
|
186
|
-
|
|
187
157
|
if (scope === 'system') {
|
|
188
158
|
return systemTemplates;
|
|
189
159
|
}
|
|
190
|
-
|
|
191
160
|
// First get all templates matching the filters
|
|
192
161
|
const templates = await this.layoutRepository.find({
|
|
193
162
|
where: {
|
|
194
163
|
...where,
|
|
195
|
-
scope: Equal(scope),
|
|
196
|
-
scopeId: scopeId
|
|
164
|
+
scope: (0, typeorm_2.Equal)(scope),
|
|
165
|
+
scopeId: scopeId,
|
|
197
166
|
},
|
|
198
167
|
order: {
|
|
199
168
|
createdAt: 'DESC',
|
|
200
169
|
},
|
|
201
170
|
});
|
|
202
|
-
|
|
203
171
|
// Create a map to store unique templates by name+type
|
|
204
|
-
const templateMap = new Map
|
|
205
|
-
|
|
172
|
+
const templateMap = new Map();
|
|
206
173
|
for (const template of systemTemplates) {
|
|
207
174
|
const key = `${template.type}/${template.name}/${template.locale}`;
|
|
208
175
|
templateMap.set(key, template);
|
|
209
176
|
}
|
|
210
|
-
|
|
211
177
|
for (const template of templates) {
|
|
212
178
|
const key = `${template.type}/${template.name}/${template.locale}`;
|
|
213
179
|
templateMap.set(key, template);
|
|
214
180
|
}
|
|
215
|
-
|
|
216
181
|
// Convert map values back to array
|
|
217
182
|
return Array.from(templateMap.values());
|
|
218
183
|
}
|
|
219
|
-
|
|
220
|
-
async getTemplateLayoutById(id: string): Promise<NestDynamicTemplateLayout | null> {
|
|
184
|
+
async getTemplateLayoutById(id) {
|
|
221
185
|
return this.layoutRepository.findOne({
|
|
222
186
|
where: { id },
|
|
223
187
|
});
|
|
224
188
|
}
|
|
225
|
-
|
|
226
|
-
async findTemplateLayout(
|
|
227
|
-
name: string,
|
|
228
|
-
scope?: string,
|
|
229
|
-
scopeId?: string,
|
|
230
|
-
locale?: string
|
|
231
|
-
): Promise<NestDynamicTemplateLayout | null> {
|
|
189
|
+
async findTemplateLayout(name, scope, scopeId, locale) {
|
|
232
190
|
// Try to find template in the following order:
|
|
233
191
|
// 1. Scoped template with locale
|
|
234
192
|
// 2. Scoped template without locale
|
|
235
193
|
// 3. System template with locale
|
|
236
194
|
// 4. System template without locale
|
|
237
|
-
|
|
238
195
|
const locales = (locale ? [locale, 'en'] : ['en']).filter(Boolean);
|
|
239
|
-
|
|
240
196
|
// First try to find in the specified scope
|
|
241
197
|
for (const currentLocale of locales) {
|
|
242
198
|
const template = await this.layoutRepository.findOne({
|
|
243
199
|
where: {
|
|
244
200
|
name,
|
|
245
201
|
scope,
|
|
246
|
-
scopeId: scope === 'system' ? IsNull() : Equal(scopeId),
|
|
202
|
+
scopeId: scope === 'system' ? (0, typeorm_2.IsNull)() : (0, typeorm_2.Equal)(scopeId),
|
|
247
203
|
locale: currentLocale,
|
|
248
204
|
}
|
|
249
205
|
});
|
|
250
|
-
|
|
251
206
|
if (template) {
|
|
252
207
|
return template;
|
|
253
208
|
}
|
|
254
209
|
}
|
|
255
|
-
|
|
256
210
|
// If not found and not already in system scope, try system scope
|
|
257
211
|
if (scope !== 'system') {
|
|
258
212
|
for (const currentLocale of locales) {
|
|
@@ -260,79 +214,68 @@ export class TemplateLayoutService {
|
|
|
260
214
|
where: {
|
|
261
215
|
name,
|
|
262
216
|
scope: 'system',
|
|
263
|
-
scopeId: IsNull(),
|
|
217
|
+
scopeId: (0, typeorm_2.IsNull)(),
|
|
264
218
|
locale: currentLocale,
|
|
265
219
|
}
|
|
266
220
|
});
|
|
267
|
-
|
|
268
221
|
if (template) {
|
|
269
222
|
return template;
|
|
270
223
|
}
|
|
271
224
|
}
|
|
272
225
|
}
|
|
273
|
-
|
|
274
226
|
return null;
|
|
275
227
|
}
|
|
276
|
-
|
|
277
228
|
/**
|
|
278
229
|
* Create a system template. Only system templates can be created directly.
|
|
279
230
|
*/
|
|
280
|
-
async createTemplateLayout(data
|
|
231
|
+
async createTemplateLayout(data) {
|
|
281
232
|
// Ensure this is a system template
|
|
282
233
|
if (data.scope !== 'system') {
|
|
283
|
-
throw new ForbiddenException('Only system templates can be created directly');
|
|
234
|
+
throw new common_1.ForbiddenException('Only system templates can be created directly');
|
|
284
235
|
}
|
|
285
|
-
|
|
286
236
|
// Check if template already exists
|
|
287
237
|
const existingTemplate = await this.layoutRepository.findOne({
|
|
288
238
|
where: {
|
|
289
239
|
name: data.name,
|
|
290
240
|
scope: 'system',
|
|
291
|
-
scopeId: IsNull(),
|
|
241
|
+
scopeId: (0, typeorm_2.IsNull)(),
|
|
292
242
|
locale: data.locale,
|
|
293
243
|
},
|
|
294
244
|
});
|
|
295
|
-
|
|
296
245
|
if (existingTemplate) {
|
|
297
|
-
throw new ConflictException(`System template already exists`);
|
|
246
|
+
throw new common_1.ConflictException(`System template already exists`);
|
|
298
247
|
}
|
|
299
|
-
|
|
300
248
|
const template = this.layoutRepository.create({
|
|
301
249
|
...data,
|
|
302
250
|
scopeId: undefined, // Ensure system templates have no scopeId
|
|
303
251
|
});
|
|
304
|
-
|
|
305
252
|
return this.layoutRepository.save(template);
|
|
306
253
|
}
|
|
307
|
-
|
|
308
|
-
async overwriteSystemTemplateLayout(templateId: string, updates: Partial<CreateTemplateLayoutDto>): Promise<NestDynamicTemplateLayout> {
|
|
254
|
+
async overwriteSystemTemplateLayout(templateId, updates) {
|
|
309
255
|
let template = await this.layoutRepository.findOne({
|
|
310
256
|
where: { id: templateId },
|
|
311
257
|
});
|
|
312
|
-
|
|
313
258
|
if (!template) {
|
|
314
|
-
throw new NotFoundException(`Template not found: ${templateId}`);
|
|
259
|
+
throw new common_1.NotFoundException(`Template not found: ${templateId}`);
|
|
315
260
|
}
|
|
316
|
-
|
|
317
261
|
if (template.scope === 'system') {
|
|
318
262
|
if (!updates.scope) {
|
|
319
|
-
throw new BadRequestException('Scope is required when overwriting system template');
|
|
263
|
+
throw new common_1.BadRequestException('Scope is required when overwriting system template');
|
|
320
264
|
}
|
|
321
|
-
|
|
322
265
|
// Check if template already exists in target scope
|
|
323
266
|
const existingTemplate = await this.layoutRepository.findOne({
|
|
324
267
|
where: {
|
|
325
268
|
name: template.name,
|
|
326
269
|
locale: template.locale,
|
|
327
270
|
scope: updates.scope,
|
|
328
|
-
scopeId: updates.scopeId
|
|
271
|
+
scopeId: updates.scopeId,
|
|
329
272
|
},
|
|
330
273
|
});
|
|
331
|
-
|
|
332
274
|
if (existingTemplate) {
|
|
333
275
|
// Update existing template in target scope
|
|
334
276
|
template = existingTemplate;
|
|
335
|
-
}
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
336
279
|
// Create new template in target scope
|
|
337
280
|
const newTemplate = this.layoutRepository.create({
|
|
338
281
|
...template,
|
|
@@ -345,63 +288,56 @@ export class TemplateLayoutService {
|
|
|
345
288
|
template = newTemplate;
|
|
346
289
|
}
|
|
347
290
|
}
|
|
348
|
-
|
|
349
291
|
template = this.layoutRepository.merge(template, updates);
|
|
350
292
|
await this.layoutRepository.save(template);
|
|
351
293
|
return template;
|
|
352
294
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
295
|
/**
|
|
356
296
|
* Update a template
|
|
357
297
|
*/
|
|
358
|
-
async updateTemplateLayout(
|
|
359
|
-
id: string,
|
|
360
|
-
updates: Partial<CreateTemplateLayoutDto>,
|
|
361
|
-
canUpdateSystemTemplate: boolean = false,
|
|
362
|
-
): Promise<NestDynamicTemplateLayout> {
|
|
298
|
+
async updateTemplateLayout(id, updates, canUpdateSystemTemplate = false) {
|
|
363
299
|
// Find the template
|
|
364
300
|
let template = await this.layoutRepository.findOne({
|
|
365
301
|
where: { id },
|
|
366
302
|
});
|
|
367
|
-
|
|
368
303
|
if (!template) {
|
|
369
|
-
throw new NotFoundException(`Template not found: ${id}`);
|
|
304
|
+
throw new common_1.NotFoundException(`Template not found: ${id}`);
|
|
370
305
|
}
|
|
371
|
-
|
|
372
306
|
// If it's a system template and we can't update it, try to overwrite it
|
|
373
307
|
if (template.scope === 'system' && !canUpdateSystemTemplate) {
|
|
374
|
-
|
|
375
308
|
if (updates.scope) {
|
|
376
309
|
// Otherwise, allow overwriting to custom scope
|
|
377
310
|
return this.overwriteSystemTemplateLayout(id, updates);
|
|
378
|
-
}
|
|
379
|
-
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
throw new common_1.ForbiddenException('Cannot update system templates');
|
|
380
314
|
}
|
|
381
315
|
}
|
|
382
|
-
|
|
383
316
|
// For regular updates
|
|
384
317
|
template = this.layoutRepository.merge(template, updates);
|
|
385
318
|
return this.layoutRepository.save(template);
|
|
386
319
|
}
|
|
387
|
-
|
|
388
320
|
/**
|
|
389
321
|
* Delete a scoped template
|
|
390
322
|
*/
|
|
391
|
-
async deleteTemplateLayout(id
|
|
323
|
+
async deleteTemplateLayout(id, canDeleteSystemTemplate = false) {
|
|
392
324
|
const template = await this.layoutRepository.findOne({
|
|
393
325
|
where: { id },
|
|
394
326
|
});
|
|
395
|
-
|
|
396
327
|
if (!template) {
|
|
397
328
|
throw new Error(`Template not found: ${id}`);
|
|
398
329
|
}
|
|
399
|
-
|
|
400
330
|
// Prevent deleting system templates
|
|
401
331
|
if (template.scope === 'system' && !canDeleteSystemTemplate) {
|
|
402
|
-
throw new ForbiddenException('Cannot delete system templates');
|
|
332
|
+
throw new common_1.ForbiddenException('Cannot delete system templates');
|
|
403
333
|
}
|
|
404
|
-
|
|
405
334
|
await this.layoutRepository.remove(template);
|
|
406
335
|
}
|
|
407
|
-
}
|
|
336
|
+
};
|
|
337
|
+
exports.TemplateLayoutService = TemplateLayoutService;
|
|
338
|
+
exports.TemplateLayoutService = TemplateLayoutService = tslib_1.__decorate([
|
|
339
|
+
(0, common_1.Injectable)(),
|
|
340
|
+
tslib_1.__param(0, (0, typeorm_1.InjectRepository)(template_layout_entity_1.NestDynamicTemplateLayout)),
|
|
341
|
+
tslib_1.__metadata("design:paramtypes", [typeorm_2.Repository,
|
|
342
|
+
template_engine_registry_1.TemplateEngineRegistryService])
|
|
343
|
+
], TemplateLayoutService);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Repository } from 'typeorm';
|
|
2
|
+
import { NestDynamicTemplate } from '../entities/template.entity';
|
|
3
|
+
import { TemplateEngineEnum, TemplateLanguageEnum } from '../interfaces/template.types';
|
|
4
|
+
import { RenderTemplateDto, RenderTemplateOutputDTO } from '../dto/render-template.dto';
|
|
5
|
+
import { CreateTemplateDto } from '../dto/create-template.dto';
|
|
6
|
+
import { TemplateFilterDto } from '../dto/template-filter.dto';
|
|
7
|
+
import { TemplateLayoutService } from './template-layout.service';
|
|
8
|
+
import { TemplateEngineRegistryService } from './template-engine.registry';
|
|
9
|
+
import { RenderContentTemplateDto } from '../dto/render-content-template.dto';
|
|
10
|
+
export declare class TemplateService {
|
|
11
|
+
private readonly templateRepository;
|
|
12
|
+
private readonly engineRegistry;
|
|
13
|
+
private readonly templateLayoutService;
|
|
14
|
+
constructor(templateRepository: Repository<NestDynamicTemplate>, engineRegistry: TemplateEngineRegistryService, templateLayoutService: TemplateLayoutService);
|
|
15
|
+
render(renderDto: RenderTemplateDto): Promise<RenderTemplateOutputDTO>;
|
|
16
|
+
renderContent(input: RenderContentTemplateDto): Promise<string>;
|
|
17
|
+
renderLanguage(language: TemplateLanguageEnum, content: string, context: Record<string, any>): Promise<string>;
|
|
18
|
+
renderEngine(engine: TemplateEngineEnum, content: string, context: Record<string, any>): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Get all templates, with scoped templates taking precedence over system templates
|
|
21
|
+
*/
|
|
22
|
+
getTemplates(filter?: TemplateFilterDto): Promise<NestDynamicTemplate[]>;
|
|
23
|
+
getTemplateById(id: string): Promise<NestDynamicTemplate | null>;
|
|
24
|
+
findTemplate(name: string, scope?: string, scopeId?: string, locale?: string): Promise<NestDynamicTemplate | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Create a system template. Only system templates can be created directly.
|
|
27
|
+
*/
|
|
28
|
+
createTemplate(data: CreateTemplateDto): Promise<NestDynamicTemplate>;
|
|
29
|
+
overwriteSystemTemplate(templateId: string, updates: Partial<CreateTemplateDto>): Promise<NestDynamicTemplate>;
|
|
30
|
+
/**
|
|
31
|
+
* Update a template
|
|
32
|
+
*/
|
|
33
|
+
updateTemplate(id: string, updates: Partial<CreateTemplateDto>, canUpdateSystemTemplate?: boolean): Promise<NestDynamicTemplate>;
|
|
34
|
+
/**
|
|
35
|
+
* Delete a scoped template
|
|
36
|
+
*/
|
|
37
|
+
deleteTemplate(id: string, canDeleteSystemTemplate?: boolean): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=template.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.service.d.ts","sourceRoot":"","sources":["../../../../../../packages/nest-dynamic-templates/src/lib/services/template.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAU,UAAU,EAAkB,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAoB,MAAM,8BAA8B,CAAC;AAC1G,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAE3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AAU9E,qBACa,eAAe;IAGpB,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,qBAAqB;gBAFrB,kBAAkB,EAAE,UAAU,CAAC,mBAAmB,CAAC,EACnD,cAAc,EAAE,6BAA6B,EAC7C,qBAAqB,EAAE,qBAAqB;IAG3D,MAAM,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAkFtE,aAAa,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,MAAM,CAAC;IA4E/D,cAAc,CAAC,QAAQ,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB9G,YAAY,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB9G;;OAEG;IACG,YAAY,CAAC,MAAM,GAAE,iBAAsB,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAyD5E,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAMhE,YAAY,CACd,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IA8CtC;;OAEG;IACG,cAAc,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA4BrE,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAgDpH;;OAEG;IACG,cAAc,CAChB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,EACnC,uBAAuB,GAAE,OAAe,GACzC,OAAO,CAAC,mBAAmB,CAAC;IAyB/B;;OAEG;IACG,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,uBAAuB,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAgB5F"}
|