@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.
Files changed (142) hide show
  1. package/package.json +2 -2
  2. package/src/{index.ts → index.d.ts} +2 -14
  3. package/src/index.d.ts.map +1 -0
  4. package/src/index.js +25 -0
  5. package/src/lib/constant.d.ts +3 -0
  6. package/src/lib/constant.d.ts.map +1 -0
  7. package/src/lib/constant.js +5 -0
  8. package/src/lib/dto/create-template-layout.dto.d.ts +16 -0
  9. package/src/lib/dto/create-template-layout.dto.d.ts.map +1 -0
  10. package/src/lib/dto/create-template-layout.dto.js +86 -0
  11. package/src/lib/dto/create-template.dto.d.ts +18 -0
  12. package/src/lib/dto/create-template.dto.d.ts.map +1 -0
  13. package/src/lib/dto/create-template.dto.js +103 -0
  14. package/src/lib/dto/render-content-template-layout.dto.d.ts +8 -0
  15. package/src/lib/dto/render-content-template-layout.dto.d.ts.map +1 -0
  16. package/src/lib/dto/render-content-template-layout.dto.js +40 -0
  17. package/src/lib/dto/render-content-template.dto.d.ts +9 -0
  18. package/src/lib/dto/render-content-template.dto.d.ts.map +1 -0
  19. package/src/lib/dto/render-content-template.dto.js +46 -0
  20. package/src/lib/dto/render-template-layout.dto.d.ts +11 -0
  21. package/src/lib/dto/render-template-layout.dto.d.ts.map +1 -0
  22. package/src/lib/dto/render-template-layout.dto.js +66 -0
  23. package/src/lib/dto/render-template.dto.d.ts +15 -0
  24. package/src/lib/dto/render-template.dto.d.ts.map +1 -0
  25. package/src/lib/dto/render-template.dto.js +90 -0
  26. package/src/lib/dto/template-filter.dto.d.ts +9 -0
  27. package/src/lib/dto/template-filter.dto.d.ts.map +1 -0
  28. package/src/lib/dto/template-filter.dto.js +61 -0
  29. package/src/lib/dto/template-layout-filter.dto.d.ts +8 -0
  30. package/src/lib/dto/template-layout-filter.dto.d.ts.map +1 -0
  31. package/src/lib/dto/template-layout-filter.dto.js +60 -0
  32. package/src/lib/engines/language/html.engine.d.ts +10 -0
  33. package/src/lib/engines/language/html.engine.d.ts.map +1 -0
  34. package/src/lib/engines/language/html.engine.js +80 -0
  35. package/src/lib/engines/language/{index.ts → index.d.ts} +1 -0
  36. package/src/lib/engines/language/index.d.ts.map +1 -0
  37. package/src/lib/engines/language/index.js +11 -0
  38. package/src/lib/engines/language/markdown.engine.d.ts +10 -0
  39. package/src/lib/engines/language/markdown.engine.d.ts.map +1 -0
  40. package/src/lib/engines/language/markdown.engine.js +39 -0
  41. package/src/lib/engines/language/mjml.engine.d.ts +10 -0
  42. package/src/lib/engines/language/mjml.engine.d.ts.map +1 -0
  43. package/src/lib/engines/language/mjml.engine.js +75 -0
  44. package/src/lib/engines/language/text.engine.d.ts +8 -0
  45. package/src/lib/engines/language/text.engine.d.ts.map +1 -0
  46. package/src/lib/engines/language/text.engine.js +15 -0
  47. package/src/lib/engines/{language-engine.ts → language-engine.d.ts} +2 -7
  48. package/src/lib/engines/language-engine.d.ts.map +1 -0
  49. package/src/lib/engines/language-engine.js +6 -0
  50. package/src/lib/engines/template/ejs.engine.d.ts +11 -0
  51. package/src/lib/engines/template/ejs.engine.d.ts.map +1 -0
  52. package/src/lib/engines/template/ejs.engine.js +65 -0
  53. package/src/lib/engines/template/handlebars.engine.d.ts +11 -0
  54. package/src/lib/engines/template/handlebars.engine.d.ts.map +1 -0
  55. package/src/lib/engines/template/handlebars.engine.js +66 -0
  56. package/src/lib/engines/template/{index.ts → index.d.ts} +1 -0
  57. package/src/lib/engines/template/index.d.ts.map +1 -0
  58. package/src/lib/engines/template/index.js +11 -0
  59. package/src/lib/engines/template/nunjucks.engine.d.ts +17 -0
  60. package/src/lib/engines/template/nunjucks.engine.d.ts.map +1 -0
  61. package/src/lib/engines/template/{nunjucks.engine.ts → nunjucks.engine.js} +24 -30
  62. package/src/lib/engines/template/pug.engine.d.ts +13 -0
  63. package/src/lib/engines/template/pug.engine.d.ts.map +1 -0
  64. package/src/lib/engines/template/pug.engine.js +74 -0
  65. package/src/lib/engines/{template-engine.ts → template-engine.d.ts} +2 -6
  66. package/src/lib/engines/template-engine.d.ts.map +1 -0
  67. package/src/lib/engines/template-engine.js +6 -0
  68. package/src/lib/entities/template-layout.entity.d.ts +21 -0
  69. package/src/lib/entities/template-layout.entity.d.ts.map +1 -0
  70. package/src/lib/entities/template-layout.entity.js +120 -0
  71. package/src/lib/entities/template.entity.d.ts +22 -0
  72. package/src/lib/entities/template.entity.d.ts.map +1 -0
  73. package/src/lib/entities/template.entity.js +127 -0
  74. package/src/lib/errors/template.errors.d.ts +20 -0
  75. package/src/lib/errors/template.errors.d.ts.map +1 -0
  76. package/src/lib/errors/{template.errors.ts → template.errors.js} +22 -20
  77. package/src/lib/interfaces/{module-config.interface.ts → module-config.interface.d.ts} +2 -10
  78. package/src/lib/interfaces/module-config.interface.d.ts.map +1 -0
  79. package/src/lib/interfaces/module-config.interface.js +2 -0
  80. package/src/lib/interfaces/template.types.d.ts +23 -0
  81. package/src/lib/interfaces/template.types.d.ts.map +1 -0
  82. package/src/lib/interfaces/template.types.js +24 -0
  83. package/src/lib/nest-dynamic-templates.module.d.ts +11 -0
  84. package/src/lib/nest-dynamic-templates.module.d.ts.map +1 -0
  85. package/src/lib/nest-dynamic-templates.module.js +131 -0
  86. package/src/lib/services/template-config.service.d.ts +55 -0
  87. package/src/lib/services/template-config.service.d.ts.map +1 -0
  88. package/src/lib/services/{template-config.service.ts → template-config.service.js} +32 -43
  89. package/src/lib/services/template-engine.registry.d.ts +22 -0
  90. package/src/lib/services/template-engine.registry.d.ts.map +1 -0
  91. package/src/lib/services/template-engine.registry.js +93 -0
  92. package/src/lib/services/template-layout.service.d.ts +37 -0
  93. package/src/lib/services/template-layout.service.d.ts.map +1 -0
  94. package/src/lib/services/{template-layout.service.ts → template-layout.service.js} +101 -165
  95. package/src/lib/services/template.service.d.ts +39 -0
  96. package/src/lib/services/template.service.d.ts.map +1 -0
  97. package/src/lib/services/{template.service.ts → template.service.js} +137 -199
  98. package/src/test/helpers.d.ts +5 -0
  99. package/src/test/helpers.d.ts.map +1 -0
  100. package/src/test/{helpers.ts → helpers.js} +7 -5
  101. package/src/test/test-database.config.d.ts +5 -0
  102. package/src/test/test-database.config.d.ts.map +1 -0
  103. package/src/test/test-database.config.js +23 -0
  104. package/src/test/test.setup.d.ts +4 -0
  105. package/src/test/test.setup.d.ts.map +1 -0
  106. package/src/test/test.setup.js +30 -0
  107. package/eslint.config.mjs +0 -22
  108. package/jest.config.ts +0 -10
  109. package/project.json +0 -38
  110. package/src/lib/constant.ts +0 -2
  111. package/src/lib/dto/create-template-layout.dto.ts +0 -65
  112. package/src/lib/dto/create-template.dto.ts +0 -80
  113. package/src/lib/dto/render-content-template-layout.dto.ts +0 -32
  114. package/src/lib/dto/render-content-template.dto.ts +0 -37
  115. package/src/lib/dto/render-template-layout.dto.ts +0 -55
  116. package/src/lib/dto/render-template.dto.ts +0 -74
  117. package/src/lib/dto/template-filter.dto.ts +0 -52
  118. package/src/lib/dto/template-layout-filter.dto.ts +0 -51
  119. package/src/lib/engines/language/html.engine.ts +0 -49
  120. package/src/lib/engines/language/markdown.engine.ts +0 -37
  121. package/src/lib/engines/language/mjml.engine.ts +0 -44
  122. package/src/lib/engines/language/text.engine.ts +0 -15
  123. package/src/lib/engines/template/ejs.engine.ts +0 -33
  124. package/src/lib/engines/template/handlebars.engine.ts +0 -35
  125. package/src/lib/engines/template/pug.engine.ts +0 -43
  126. package/src/lib/entities/template-layout.entity.ts +0 -99
  127. package/src/lib/entities/template.entity.ts +0 -105
  128. package/src/lib/interfaces/template.types.ts +0 -25
  129. package/src/lib/nest-dynamic-templates.module.ts +0 -143
  130. package/src/lib/services/template-engine.registry.ts +0 -109
  131. package/src/test/nunjucks.service.spec.ts +0 -157
  132. package/src/test/pug.service.spec-temp +0 -254
  133. package/src/test/template-layout.service.spec.ts +0 -422
  134. package/src/test/template.service.spec.ts +0 -862
  135. package/src/test/test-database.config.ts +0 -24
  136. package/src/test/test-database.d.ts +0 -6
  137. package/src/test/test.setup.ts +0 -34
  138. package/src/types/ioredis.d.ts +0 -6
  139. package/src/types/mjml.d.ts +0 -5
  140. package/tsconfig.json +0 -17
  141. package/tsconfig.lib.json +0 -14
  142. package/tsconfig.spec.json +0 -15
@@ -1,157 +0,0 @@
1
- import { DataSource, Repository } from 'typeorm';
2
- import { createTestModule } from './test.setup';
3
- import { TemplateService } from '../lib/services/template.service';
4
- import { NestDynamicTemplate } from '../lib/entities/template.entity';
5
- import { TemplateTypeEnum, TemplateEngineEnum, TemplateLanguageEnum } from '../lib/interfaces/template.types';
6
- import { CreateTemplateDto } from '../lib/dto/create-template.dto';
7
- import { engineFilters } from './helpers';
8
-
9
- describe('Nunjucks Engine', () => {
10
- let service: TemplateService;
11
- let dataSource: DataSource;
12
- let templateRepository: Repository<NestDynamicTemplate>;
13
-
14
- const testTemplate: CreateTemplateDto = {
15
- name: 'test-template',
16
- displayName: 'Test Template',
17
- content: 'Hello {{name}}!',
18
- type: TemplateTypeEnum.EMAIL,
19
- engine: TemplateEngineEnum.NUNJUCKS,
20
- language: TemplateLanguageEnum.HTML,
21
- scope: 'system',
22
- scopeId: null,
23
- locale: 'en',
24
- isActive: true
25
- };
26
-
27
- beforeEach(async () => {
28
- const moduleRef = await createTestModule({
29
- enginesOptions: {
30
- filters: engineFilters
31
- }
32
- });
33
-
34
- service = moduleRef.get<TemplateService>(TemplateService);
35
- dataSource = moduleRef.get<DataSource>(DataSource);
36
- templateRepository = dataSource.getRepository(NestDynamicTemplate);
37
- });
38
-
39
- afterEach(async () => {
40
- // Clean up templates
41
- await templateRepository.delete('1 = 1');
42
-
43
- // Clean up database after each test
44
- await dataSource.synchronize(true);
45
- });
46
-
47
- afterAll(async () => {
48
- // Close the connection after all tests
49
- await dataSource.destroy();
50
- });
51
-
52
- describe('Nunjucks Custom Filters', () => {
53
- it('should format date using custom date filter', async () => {
54
- // Create template with date filter
55
- const template = await service.createTemplate({
56
- ...testTemplate,
57
- name: 'date-template',
58
- content: 'Today is {{ date | formatDate("YYYY-MM-DD") }}',
59
- });
60
-
61
- const today = new Date();
62
- const expectedDate = today.toISOString().split('T')[0]; // YYYY-MM-DD format
63
-
64
- const result = await service.render({
65
- name: 'date-template',
66
- scope: 'system',
67
- context: {
68
- date: today
69
- }
70
- });
71
-
72
- expect(result.content).toBe(`Today is ${expectedDate}`);
73
- });
74
-
75
- it('should format currency using custom currency filter', async () => {
76
- // Create template with currency filter
77
- const template = await service.createTemplate({
78
- ...testTemplate,
79
- name: 'currency-template',
80
- content: 'Price: {{ amount | formatCurrency("USD") }}',
81
- });
82
-
83
- const result = await service.render({
84
- name: 'currency-template',
85
- scope: 'system',
86
- context: {
87
- amount: 1234.56
88
- }
89
- });
90
-
91
- expect(result.content).toBe('Price: $1,234.56');
92
- });
93
-
94
- it('should handle multiple filters in the same template', async () => {
95
- // Create template with multiple filters
96
- const template = await service.createTemplate({
97
- ...testTemplate,
98
- name: 'multi-filter-template',
99
- content: 'Order placed on {{ date | formatDate("YYYY-MM-DD") }} for {{ amount | formatCurrency("USD") }}',
100
- });
101
-
102
- const today = new Date();
103
- const expectedDate = today.toISOString().split('T')[0];
104
-
105
- const result = await service.render({
106
- name: 'multi-filter-template',
107
- scope: 'system',
108
- context: {
109
- date: today,
110
- amount: 1234.56
111
- }
112
- });
113
-
114
- expect(result.content).toBe(`Order placed on ${expectedDate} for $1,234.56`);
115
- });
116
-
117
- it('should handle different currency formats', async () => {
118
- // Create template with different currency formats
119
- const template = await service.createTemplate({
120
- ...testTemplate,
121
- name: 'currency-formats-template',
122
- content: 'USD: {{ usd | formatCurrency("USD") }}, EUR: {{ eur | formatCurrency("EUR") }}',
123
- });
124
-
125
- const result = await service.render({
126
- name: 'currency-formats-template',
127
- scope: 'system',
128
- context: {
129
- usd: 1234.56,
130
- eur: 1234.56,
131
- }
132
- });
133
-
134
- expect(result.content).toBe('USD: $1,234.56, EUR: €1,234.56');
135
- });
136
-
137
- it('should handle different date formats', async () => {
138
- // Create template with different date formats
139
- const template = await service.createTemplate({
140
- ...testTemplate,
141
- name: 'date-formats-template',
142
- content: 'Short: {{ date | formatDate("MM/DD/YY") }}, Long: {{ date | formatDate("MMMM D, YYYY") }}, ISO: {{ date | formatDate("YYYY-MM-DD") }}',
143
- });
144
-
145
- const date = new Date('2024-03-15');
146
- const result = await service.render({
147
- name: 'date-formats-template',
148
- scope: 'system',
149
- context: {
150
- date: date
151
- }
152
- });
153
-
154
- expect(result.content).toBe('Short: 03/15/24, Long: March 15, 2024, ISO: 2024-03-15');
155
- });
156
- });
157
- });
@@ -1,254 +0,0 @@
1
- import { DataSource, Repository } from 'typeorm';
2
- import { createTestModule } from './test.setup';
3
- import { TemplateService } from '../lib/services/template.service';
4
- import { NestDynamicTemplate } from '../lib/entities/template.entity';
5
- import { TemplateTypeEnum, TemplateEngineEnum, TemplateLanguageEnum } from '../lib/interfaces/template.types';
6
- import { CreateTemplateDto } from '../lib/dto/create-template.dto';
7
- import { engineFilters } from './helpers';
8
-
9
- describe('Pug Engine', () => {
10
- let service: TemplateService;
11
- let dataSource: DataSource;
12
- let templateRepository: Repository<NestDynamicTemplate>;
13
-
14
- const testTemplate: CreateTemplateDto = {
15
- name: 'test-template',
16
- displayName: 'Test Template',
17
- content: 'p Hello #{name}!',
18
- type: TemplateTypeEnum.EMAIL,
19
- engine: TemplateEngineEnum.PUG,
20
- language: TemplateLanguageEnum.HTML,
21
- scope: 'system',
22
- scopeId: null,
23
- locale: 'en',
24
- isActive: true
25
- };
26
-
27
- beforeEach(async () => {
28
- const moduleRef = await createTestModule({
29
- engines: {
30
- template: [TemplateEngineEnum.PUG],
31
- },
32
- enginesOptions: {
33
- filters: engineFilters,
34
- template: {
35
- [TemplateEngineEnum.PUG]: {
36
- pretty: true,
37
- compileDebug: true
38
- }
39
- }
40
- }
41
- });
42
-
43
- service = moduleRef.get<TemplateService>(TemplateService);
44
- dataSource = moduleRef.get<DataSource>(DataSource);
45
- templateRepository = dataSource.getRepository(NestDynamicTemplate);
46
- });
47
-
48
- afterEach(async () => {
49
- // Clean up templates
50
- await templateRepository.delete('1 = 1');
51
-
52
- // Clean up database after each test
53
- await dataSource.synchronize(true);
54
- });
55
-
56
- afterAll(async () => {
57
- // Close the connection after all tests
58
- await dataSource.destroy();
59
- });
60
-
61
- describe('Pug Custom Filters', () => {
62
- it('should format date using custom date filter', async () => {
63
- const template = await service.createTemplate({
64
- ...testTemplate,
65
- name: 'date-template',
66
- content: 'p Today is #{formatDate(date, "YYYY-MM-DD")}',
67
- });
68
-
69
- const today = new Date();
70
- const expectedDate = today.toISOString().split('T')[0];
71
-
72
- const result = await service.render({
73
- type: TemplateTypeEnum.EMAIL,
74
- name: 'date-template',
75
- scope: 'system',
76
- context: {
77
- date: today
78
- }
79
- });
80
-
81
- expect(result.content).toBe(`<p>Today is ${expectedDate}</p>`);
82
- });
83
-
84
- it('should format currency using custom currency filter', async () => {
85
- const template = await service.createTemplate({
86
- ...testTemplate,
87
- name: 'currency-template',
88
- content: 'p Price: #{formatCurrency(amount, "USD")}',
89
- });
90
-
91
- const result = await service.render({
92
- type: TemplateTypeEnum.EMAIL,
93
- name: 'currency-template',
94
- scope: 'system',
95
- context: {
96
- amount: 1234.56
97
- }
98
- });
99
-
100
- expect(result.content).toBe('<p>Price: $1,234.56</p>');
101
- });
102
-
103
- it('should handle multiple filters in the same template', async () => {
104
- const template = await service.createTemplate({
105
- ...testTemplate,
106
- name: 'multi-filter-template',
107
- content: 'p Order placed on #{formatDate(date, "YYYY-MM-DD")} for #{formatCurrency(amount, "USD")}',
108
- });
109
-
110
- const today = new Date();
111
- const expectedDate = today.toISOString().split('T')[0];
112
-
113
- const result = await service.render({
114
- type: TemplateTypeEnum.EMAIL,
115
- name: 'multi-filter-template',
116
- scope: 'system',
117
- context: {
118
- date: today,
119
- amount: 1234.56
120
- }
121
- });
122
-
123
- expect(result.content).toBe(`<p>Order placed on ${expectedDate} for $1,234.56</p>`);
124
- });
125
-
126
- it('should handle different currency formats', async () => {
127
- const template = await service.createTemplate({
128
- ...testTemplate,
129
- name: 'currency-formats-template',
130
- content: 'p USD: #{formatCurrency(usd, "USD")}, EUR: #{formatCurrency(eur, "EUR")}',
131
- });
132
-
133
- const result = await service.render({
134
- type: TemplateTypeEnum.EMAIL,
135
- name: 'currency-formats-template',
136
- scope: 'system',
137
- context: {
138
- usd: 1234.56,
139
- eur: 1234.56
140
- }
141
- });
142
-
143
- expect(result.content).toBe('<p>USD: $1,234.56, EUR: €1,234.56</p>');
144
- });
145
-
146
- it('should handle different date formats', async () => {
147
- const template = await service.createTemplate({
148
- ...testTemplate,
149
- name: 'date-formats-template',
150
- content: 'p Short: #{formatDate(date, "MM/DD/YY")}, Long: #{formatDate(date, "MMMM D, YYYY")}, ISO: #{formatDate(date, "YYYY-MM-DD")}',
151
- });
152
-
153
- const date = new Date('2024-03-15');
154
- const result = await service.render({
155
- type: TemplateTypeEnum.EMAIL,
156
- name: 'date-formats-template',
157
- scope: 'system',
158
- context: {
159
- date: date
160
- }
161
- });
162
-
163
- expect(result.content).toBe('<p>Short: 03/15/24, Long: March 15, 2024, ISO: 2024-03-15</p>');
164
- });
165
- });
166
-
167
- describe('Pug HTML Features', () => {
168
- // Custom matcher to check HTML structure
169
- const expectHtmlStructure = (received: string, expected: string) => {
170
- const normalizeHtml = (html: string) => {
171
- return html
172
- .replace(/\s+/g, ' ')
173
- .replace(/>\s+</g, '><')
174
- .trim();
175
- };
176
-
177
- const receivedNormalized = normalizeHtml(received);
178
- const expectedNormalized = normalizeHtml(expected);
179
-
180
- // Extract attributes and compare them regardless of order
181
- const getAttributes = (html: string) => {
182
- const match = html.match(/<[^>]+>/);
183
- if (!match) return [];
184
- return match[0]
185
- .replace(/<[^\s>]+/, '')
186
- .replace(/>$/, '')
187
- .trim()
188
- .split(/\s+/)
189
- .sort();
190
- };
191
-
192
- const receivedAttrs = getAttributes(receivedNormalized);
193
- const expectedAttrs = getAttributes(expectedNormalized);
194
-
195
- expect(receivedAttrs).toEqual(expectedAttrs);
196
- expect(receivedNormalized.replace(/<[^>]+>/, '')).toBe(expectedNormalized.replace(/<[^>]+>/, ''));
197
- };
198
-
199
- it('should render nested HTML tags', async () => {
200
- const template = await service.createTemplate({
201
- ...testTemplate,
202
- name: 'nested-html-template',
203
- content: 'div\n h1 Title\n p This is a paragraph.'
204
- });
205
-
206
- const result = await service.render({
207
- type: TemplateTypeEnum.EMAIL,
208
- name: 'nested-html-template',
209
- scope: 'system',
210
- context: {}
211
- });
212
-
213
- expect(result.content.replace(/\n/g, ''))
214
- .toBe('<div><h1>Title</h1><p>This is a paragraph.</p></div>');
215
- });
216
-
217
- it('should render HTML with attributes', async () => {
218
- const template = await service.createTemplate({
219
- ...testTemplate,
220
- name: 'attributes-html-template',
221
- content: 'a(href="https://example.com" target="_blank") Example Link'
222
- });
223
-
224
- const result = await service.render({
225
- type: TemplateTypeEnum.EMAIL,
226
- name: 'attributes-html-template',
227
- scope: 'system',
228
- context: {}
229
- });
230
-
231
- expect(result.content).toBe('<a href="https://example.com" target="_blank">Example Link</a>');
232
- });
233
-
234
- it('should render HTML with classes and ids', async () => {
235
- const template = await service.createTemplate({
236
- ...testTemplate,
237
- name: 'class-id-html-template',
238
- content: 'div#main.container Main content'
239
- });
240
-
241
- const result = await service.render({
242
- type: TemplateTypeEnum.EMAIL,
243
- name: 'class-id-html-template',
244
- scope: 'system',
245
- context: {}
246
- });
247
-
248
- expectHtmlStructure(
249
- result.content,
250
- '<div class="container" id="main">Main content</div>'
251
- );
252
- });
253
- });
254
- });