glasswork 0.9.2 → 0.11.0

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 (191) hide show
  1. package/dist/core/bootstrap.d.ts +2 -1
  2. package/dist/core/bootstrap.d.ts.map +1 -1
  3. package/dist/core/bootstrap.js +121 -44
  4. package/dist/core/bootstrap.js.map +1 -1
  5. package/dist/core/types.d.ts +53 -3
  6. package/dist/core/types.d.ts.map +1 -1
  7. package/dist/email/compiler/code-generator.d.ts +11 -0
  8. package/dist/email/compiler/code-generator.d.ts.map +1 -0
  9. package/dist/email/compiler/code-generator.js +319 -0
  10. package/dist/email/compiler/code-generator.js.map +1 -0
  11. package/dist/email/compiler/compile-templates.d.ts +68 -0
  12. package/dist/email/compiler/compile-templates.d.ts.map +1 -0
  13. package/dist/email/compiler/compile-templates.js +156 -0
  14. package/dist/email/compiler/compile-templates.js.map +1 -0
  15. package/dist/email/compiler/compiler.d.ts +30 -0
  16. package/dist/email/compiler/compiler.d.ts.map +1 -0
  17. package/dist/email/compiler/compiler.js +510 -0
  18. package/dist/email/compiler/compiler.js.map +1 -0
  19. package/dist/email/compiler/index.d.ts +4 -0
  20. package/dist/email/compiler/index.d.ts.map +1 -0
  21. package/dist/email/compiler/index.js +3 -0
  22. package/dist/email/compiler/index.js.map +1 -0
  23. package/dist/email/compiler/tokenizer.d.ts +7 -0
  24. package/dist/email/compiler/tokenizer.d.ts.map +1 -0
  25. package/dist/email/compiler/tokenizer.js +154 -0
  26. package/dist/email/compiler/tokenizer.js.map +1 -0
  27. package/dist/email/compiler/type-extractor.d.ts +11 -0
  28. package/dist/email/compiler/type-extractor.d.ts.map +1 -0
  29. package/dist/email/compiler/type-extractor.js +296 -0
  30. package/dist/email/compiler/type-extractor.js.map +1 -0
  31. package/dist/email/compiler/types.d.ts +108 -0
  32. package/dist/email/compiler/types.d.ts.map +1 -0
  33. package/dist/email/compiler/types.js.map +1 -0
  34. package/dist/email/config.d.ts +89 -0
  35. package/dist/email/config.d.ts.map +1 -0
  36. package/dist/email/config.js +55 -0
  37. package/dist/email/config.js.map +1 -0
  38. package/dist/email/email-service.d.ts +54 -0
  39. package/dist/email/email-service.d.ts.map +1 -0
  40. package/dist/email/email-service.js +94 -0
  41. package/dist/email/email-service.js.map +1 -0
  42. package/dist/email/index.d.ts +12 -0
  43. package/dist/email/index.d.ts.map +1 -0
  44. package/dist/email/index.js +23 -0
  45. package/dist/email/index.js.map +1 -0
  46. package/dist/email/template-registry.d.ts +83 -0
  47. package/dist/email/template-registry.d.ts.map +1 -0
  48. package/dist/email/template-registry.js +85 -0
  49. package/dist/email/template-registry.js.map +1 -0
  50. package/dist/email/templated-email-service.d.ts +59 -0
  51. package/dist/email/templated-email-service.d.ts.map +1 -0
  52. package/dist/email/templated-email-service.js +63 -0
  53. package/dist/email/templated-email-service.js.map +1 -0
  54. package/dist/email/transports/index.d.ts +3 -0
  55. package/dist/email/transports/index.d.ts.map +1 -0
  56. package/dist/email/transports/index.js +3 -0
  57. package/dist/email/transports/index.js.map +1 -0
  58. package/dist/email/transports/mock-transport.d.ts +74 -0
  59. package/dist/email/transports/mock-transport.d.ts.map +1 -0
  60. package/dist/email/transports/mock-transport.js +102 -0
  61. package/dist/email/transports/mock-transport.js.map +1 -0
  62. package/dist/email/transports/ses-transport.d.ts +65 -0
  63. package/dist/email/transports/ses-transport.d.ts.map +1 -0
  64. package/dist/email/transports/ses-transport.js +290 -0
  65. package/dist/email/transports/ses-transport.js.map +1 -0
  66. package/dist/email/types.d.ts +128 -0
  67. package/dist/email/types.d.ts.map +1 -0
  68. package/dist/email/types.js +2 -0
  69. package/dist/{hooks → email}/types.js.map +1 -1
  70. package/dist/email/webhooks/handler-factory.d.ts +41 -0
  71. package/dist/email/webhooks/handler-factory.d.ts.map +1 -0
  72. package/dist/email/webhooks/handler-factory.js +136 -0
  73. package/dist/email/webhooks/handler-factory.js.map +1 -0
  74. package/dist/email/webhooks/index.d.ts +6 -0
  75. package/dist/email/webhooks/index.d.ts.map +1 -0
  76. package/dist/email/webhooks/index.js +9 -0
  77. package/dist/email/webhooks/index.js.map +1 -0
  78. package/dist/email/webhooks/notification-parser.d.ts +45 -0
  79. package/dist/email/webhooks/notification-parser.d.ts.map +1 -0
  80. package/dist/email/webhooks/notification-parser.js +150 -0
  81. package/dist/email/webhooks/notification-parser.js.map +1 -0
  82. package/dist/email/webhooks/signature-verification.d.ts +38 -0
  83. package/dist/email/webhooks/signature-verification.d.ts.map +1 -0
  84. package/dist/email/webhooks/signature-verification.js +179 -0
  85. package/dist/email/webhooks/signature-verification.js.map +1 -0
  86. package/dist/email/webhooks/subscription-handler.d.ts +37 -0
  87. package/dist/email/webhooks/subscription-handler.d.ts.map +1 -0
  88. package/dist/email/webhooks/subscription-handler.js +99 -0
  89. package/dist/email/webhooks/subscription-handler.js.map +1 -0
  90. package/dist/email/webhooks/types.d.ts +187 -0
  91. package/dist/email/webhooks/types.d.ts.map +1 -0
  92. package/dist/email/webhooks/types.js +5 -0
  93. package/dist/email/webhooks/types.js.map +1 -0
  94. package/dist/http/error-handler.d.ts +28 -3
  95. package/dist/http/error-handler.d.ts.map +1 -1
  96. package/dist/http/error-handler.js +97 -22
  97. package/dist/http/error-handler.js.map +1 -1
  98. package/dist/http/errors.d.ts +52 -22
  99. package/dist/http/errors.d.ts.map +1 -1
  100. package/dist/http/errors.js +62 -42
  101. package/dist/http/errors.js.map +1 -1
  102. package/dist/http/route-helpers.d.ts +13 -0
  103. package/dist/http/route-helpers.d.ts.map +1 -1
  104. package/dist/http/route-helpers.js +15 -3
  105. package/dist/http/route-helpers.js.map +1 -1
  106. package/dist/index.d.ts +14 -2
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +31 -0
  109. package/dist/index.js.map +1 -1
  110. package/dist/list-query/builder.d.ts +5 -0
  111. package/dist/list-query/builder.d.ts.map +1 -1
  112. package/dist/list-query/builder.js +34 -1
  113. package/dist/list-query/builder.js.map +1 -1
  114. package/dist/middleware/rate-limit.d.ts.map +1 -1
  115. package/dist/middleware/rate-limit.js +28 -18
  116. package/dist/middleware/rate-limit.js.map +1 -1
  117. package/dist/observability/exception-tracking.d.ts +214 -0
  118. package/dist/observability/exception-tracking.d.ts.map +1 -0
  119. package/dist/observability/exception-tracking.js +238 -0
  120. package/dist/observability/exception-tracking.js.map +1 -0
  121. package/dist/observability/pino-logger.d.ts +108 -0
  122. package/dist/observability/pino-logger.d.ts.map +1 -0
  123. package/dist/observability/pino-logger.js +158 -0
  124. package/dist/observability/pino-logger.js.map +1 -0
  125. package/dist/observability/request-context.d.ts +105 -0
  126. package/dist/observability/request-context.d.ts.map +1 -0
  127. package/dist/observability/request-context.js +115 -0
  128. package/dist/observability/request-context.js.map +1 -0
  129. package/dist/openapi/openapi.d.ts.map +1 -1
  130. package/dist/openapi/openapi.js +3 -1
  131. package/dist/openapi/openapi.js.map +1 -1
  132. package/dist/utils/environment.d.ts +2 -1
  133. package/dist/utils/environment.d.ts.map +1 -1
  134. package/dist/utils/environment.js +11 -2
  135. package/dist/utils/environment.js.map +1 -1
  136. package/dist/utils/logger.d.ts +43 -9
  137. package/dist/utils/logger.d.ts.map +1 -1
  138. package/dist/utils/logger.js +60 -16
  139. package/dist/utils/logger.js.map +1 -1
  140. package/package.json +15 -2
  141. package/dist/authorization/ability-middleware.d.ts +0 -61
  142. package/dist/authorization/ability-middleware.d.ts.map +0 -1
  143. package/dist/authorization/ability-middleware.js +0 -74
  144. package/dist/authorization/ability-middleware.js.map +0 -1
  145. package/dist/authorization/index.d.ts +0 -46
  146. package/dist/authorization/index.d.ts.map +0 -1
  147. package/dist/authorization/index.js +0 -46
  148. package/dist/authorization/index.js.map +0 -1
  149. package/dist/authorization/route-helpers.d.ts +0 -106
  150. package/dist/authorization/route-helpers.d.ts.map +0 -1
  151. package/dist/authorization/route-helpers.js +0 -136
  152. package/dist/authorization/route-helpers.js.map +0 -1
  153. package/dist/authorization/service-proxy.d.ts +0 -59
  154. package/dist/authorization/service-proxy.d.ts.map +0 -1
  155. package/dist/authorization/service-proxy.js +0 -110
  156. package/dist/authorization/service-proxy.js.map +0 -1
  157. package/dist/authorization/types.d.ts +0 -58
  158. package/dist/authorization/types.d.ts.map +0 -1
  159. package/dist/authorization/types.js +0 -7
  160. package/dist/authorization/types.js.map +0 -1
  161. package/dist/hooks/authorization-hook.d.ts +0 -100
  162. package/dist/hooks/authorization-hook.d.ts.map +0 -1
  163. package/dist/hooks/authorization-hook.js +0 -93
  164. package/dist/hooks/authorization-hook.js.map +0 -1
  165. package/dist/hooks/index.d.ts +0 -54
  166. package/dist/hooks/index.d.ts.map +0 -1
  167. package/dist/hooks/index.js +0 -55
  168. package/dist/hooks/index.js.map +0 -1
  169. package/dist/hooks/service-hooks.d.ts +0 -82
  170. package/dist/hooks/service-hooks.d.ts.map +0 -1
  171. package/dist/hooks/service-hooks.js +0 -158
  172. package/dist/hooks/service-hooks.js.map +0 -1
  173. package/dist/hooks/types.d.ts +0 -151
  174. package/dist/hooks/types.d.ts.map +0 -1
  175. package/dist/openapi/hooks.d.ts +0 -14
  176. package/dist/openapi/hooks.d.ts.map +0 -1
  177. package/dist/openapi/hooks.js +0 -83
  178. package/dist/openapi/hooks.js.map +0 -1
  179. package/dist/openapi/openapi-transformer.d.ts +0 -13
  180. package/dist/openapi/openapi-transformer.d.ts.map +0 -1
  181. package/dist/openapi/openapi-transformer.js +0 -87
  182. package/dist/openapi/openapi-transformer.js.map +0 -1
  183. package/dist/utils/pagination.d.ts +0 -48
  184. package/dist/utils/pagination.d.ts.map +0 -1
  185. package/dist/utils/pagination.js +0 -42
  186. package/dist/utils/pagination.js.map +0 -1
  187. package/dist/utils/serialize-dates.d.ts +0 -27
  188. package/dist/utils/serialize-dates.d.ts.map +0 -1
  189. package/dist/utils/serialize-dates.js +0 -39
  190. package/dist/utils/serialize-dates.js.map +0 -1
  191. /package/dist/{hooks → email/compiler}/types.js +0 -0
@@ -0,0 +1,510 @@
1
+ import { tokenize } from './tokenizer.js';
2
+ import { extractTypes, generateInterface } from './type-extractor.js';
3
+ /**
4
+ * Two-pass MJML template compiler.
5
+ *
6
+ * Pass 1: MJML → HTML (preserving control flow markers in comments)
7
+ * Pass 2: HTML with markers → TypeScript template literal function
8
+ *
9
+ * This approach allows us to:
10
+ * 1. Use the full power of MJML at build time
11
+ * 2. Generate zero-dependency TypeScript render functions
12
+ * 3. Infer TypeScript types from template usage
13
+ */
14
+ /**
15
+ * Compiles an MJML template with control flow syntax to a TypeScript render function.
16
+ *
17
+ * @param source - MJML source with control flow markers
18
+ * @param name - Template name (used for interface naming)
19
+ * @param mjmlCompile - MJML compiler function (injected to avoid bundling MJML)
20
+ * @returns Compiled TypeScript source code
21
+ */
22
+ export function compile(source, name, mjmlCompile) {
23
+ // Pass 1: Compile MJML to HTML (markers are preserved in comments)
24
+ const { html, errors } = mjmlCompile(source);
25
+ if (errors.length > 0) {
26
+ const errorMessages = errors.map((e) => e.message).join('\n');
27
+ throw new Error(`MJML compilation errors:\n${errorMessages}`);
28
+ }
29
+ // Extract subject from <mj-title> in source or <title> in compiled HTML
30
+ const subject = extractSubject(source, html);
31
+ // Tokenize the original source to extract control flow structure and variables
32
+ const tokens = tokenize(source);
33
+ // Extract types from tokens
34
+ const types = extractTypes(tokens);
35
+ // Pass 2: Transform compiled HTML to TypeScript
36
+ const tsSource = generateTypeScriptSource(name, html, tokens, types);
37
+ return {
38
+ source: tsSource,
39
+ contextInterface: generateInterface(`${toPascalCase(name)}Context`, types),
40
+ name,
41
+ subject,
42
+ };
43
+ }
44
+ /**
45
+ * Extracts subject from MJML source (<mj-title>) or compiled HTML (<title>)
46
+ */
47
+ function extractSubject(source, html) {
48
+ // First try to get from <mj-title> in MJML source
49
+ const mjTitleMatch = source.match(/<mj-title>([^<]+)<\/mj-title>/i);
50
+ if (mjTitleMatch) {
51
+ return mjTitleMatch[1].trim();
52
+ }
53
+ // Fall back to <title> in compiled HTML
54
+ const titleMatch = html.match(/<title>([^<]+)<\/title>/i);
55
+ if (titleMatch) {
56
+ return titleMatch[1].trim();
57
+ }
58
+ return undefined;
59
+ }
60
+ /**
61
+ * Generates TypeScript source code for a compiled template.
62
+ */
63
+ function generateTypeScriptSource(name, html, _tokens, types) {
64
+ const interfaceName = `${toPascalCase(name)}Context`;
65
+ const interfaceCode = generateInterface(interfaceName, types);
66
+ // Transform the HTML with control flow markers into template literal
67
+ const transformedHtml = transformHtmlToTemplateLiteral(html);
68
+ return `// This file is auto-generated by @glasswork/email. Do not edit manually.
69
+
70
+ ${interfaceCode}
71
+
72
+ export function render(ctx: ${interfaceName}): { html: string; text: string } {
73
+ const html = \`${escapeTemplateLiteral(transformedHtml)}\`;
74
+
75
+ // Auto-generated plain text version
76
+ const text = htmlToText(html);
77
+
78
+ return { html, text };
79
+ }
80
+
81
+ /**
82
+ * Converts HTML to plain text for email clients that don't support HTML.
83
+ */
84
+ function htmlToText(html: string): string {
85
+ return html
86
+ // Remove style and script tags with content
87
+ .replace(/<style[^>]*>[\\s\\S]*?<\\/style>/gi, '')
88
+ .replace(/<script[^>]*>[\\s\\S]*?<\\/script>/gi, '')
89
+ // Convert line breaks
90
+ .replace(/<br\\s*\\/?>/gi, '\\n')
91
+ // Convert block elements to newlines
92
+ .replace(/<\\/(p|div|tr|h[1-6])>/gi, '\\n')
93
+ // Convert list items
94
+ .replace(/<li[^>]*>/gi, '• ')
95
+ .replace(/<\\/li>/gi, '\\n')
96
+ // Remove remaining HTML tags
97
+ .replace(/<[^>]+>/g, '')
98
+ // Decode common HTML entities
99
+ .replace(/&nbsp;/gi, ' ')
100
+ .replace(/&amp;/gi, '&')
101
+ .replace(/&lt;/gi, '<')
102
+ .replace(/&gt;/gi, '>')
103
+ .replace(/&quot;/gi, '"')
104
+ .replace(/&#39;/gi, "'")
105
+ // Clean up whitespace
106
+ .replace(/\\n\\s*\\n\\s*\\n/g, '\\n\\n')
107
+ .trim();
108
+ }
109
+ `;
110
+ }
111
+ /**
112
+ * Finds all control flow markers in HTML
113
+ */
114
+ function findMarkers(html) {
115
+ const markers = [];
116
+ // Find @if markers
117
+ const ifPattern = /<!--\s*@if\s+([^-]+?)\s*-->/g;
118
+ let match = ifPattern.exec(html);
119
+ while (match !== null) {
120
+ markers.push({
121
+ type: 'if',
122
+ match: match[0],
123
+ index: match.index,
124
+ condition: match[1].trim(),
125
+ });
126
+ match = ifPattern.exec(html);
127
+ }
128
+ // Find @elseif markers
129
+ const elseifPattern = /<!--\s*@elseif\s+([^-]+?)\s*-->/g;
130
+ match = elseifPattern.exec(html);
131
+ while (match !== null) {
132
+ markers.push({
133
+ type: 'elseif',
134
+ match: match[0],
135
+ index: match.index,
136
+ condition: match[1].trim(),
137
+ });
138
+ match = elseifPattern.exec(html);
139
+ }
140
+ // Find @else markers
141
+ const elsePattern = /<!--\s*@else\s*-->/g;
142
+ match = elsePattern.exec(html);
143
+ while (match !== null) {
144
+ markers.push({
145
+ type: 'else',
146
+ match: match[0],
147
+ index: match.index,
148
+ });
149
+ match = elsePattern.exec(html);
150
+ }
151
+ // Find @each markers
152
+ const eachPattern = /<!--\s*@each\s+(\S+)\s+as\s+(\w+)(?:\s*,\s*(\w+))?\s*-->/g;
153
+ match = eachPattern.exec(html);
154
+ while (match !== null) {
155
+ markers.push({
156
+ type: 'each',
157
+ match: match[0],
158
+ index: match.index,
159
+ arrayPath: match[1],
160
+ itemName: match[2],
161
+ indexName: match[3],
162
+ });
163
+ match = eachPattern.exec(html);
164
+ }
165
+ // Find @end markers
166
+ const endPattern = /<!--\s*@end\s*-->/g;
167
+ match = endPattern.exec(html);
168
+ while (match !== null) {
169
+ markers.push({
170
+ type: 'end',
171
+ match: match[0],
172
+ index: match.index,
173
+ });
174
+ match = endPattern.exec(html);
175
+ }
176
+ // Sort markers by position
177
+ markers.sort((a, b) => a.index - b.index);
178
+ return markers;
179
+ }
180
+ /**
181
+ * Builds a map of loop variables at each marker position
182
+ */
183
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Control flow tracking requires nested conditionals
184
+ function buildLoopVarScope(markers) {
185
+ const loopVarsAtPosition = new Map();
186
+ const controlStack = [];
187
+ for (const marker of markers) {
188
+ if (marker.type === 'each') {
189
+ controlStack.push({
190
+ type: 'each',
191
+ loop: { itemName: marker.itemName, indexName: marker.indexName },
192
+ });
193
+ }
194
+ else if (marker.type === 'if') {
195
+ controlStack.push({ type: 'if' });
196
+ }
197
+ else if (marker.type === 'end' && controlStack.length > 0) {
198
+ controlStack.pop();
199
+ }
200
+ const currentLoopVars = new Set();
201
+ for (const ctx of controlStack) {
202
+ if (ctx.type === 'each' && ctx.loop) {
203
+ if (ctx.loop.itemName)
204
+ currentLoopVars.add(ctx.loop.itemName);
205
+ if (ctx.loop.indexName)
206
+ currentLoopVars.add(ctx.loop.indexName);
207
+ }
208
+ }
209
+ loopVarsAtPosition.set(marker.index, currentLoopVars);
210
+ }
211
+ return loopVarsAtPosition;
212
+ }
213
+ /**
214
+ * Creates replacement for if marker
215
+ */
216
+ const EXPR_OPEN = '__GW_EXPR_START__';
217
+ const EXPR_CLOSE = '__GW_EXPR_END__';
218
+ function wrapExpression(expression) {
219
+ return `${EXPR_OPEN}${expression}${EXPR_CLOSE}`;
220
+ }
221
+ function createIfReplacement(marker, loopVars) {
222
+ if (!marker.condition) {
223
+ return null;
224
+ }
225
+ return {
226
+ original: marker.match,
227
+ replacement: wrapExpression(`\${${transformConditionExpr(marker.condition, loopVars)} ? \``),
228
+ index: marker.index,
229
+ };
230
+ }
231
+ /**
232
+ * Creates replacement for elseif marker
233
+ */
234
+ function createElseifReplacement(marker, loopVars) {
235
+ if (!marker.condition) {
236
+ return null;
237
+ }
238
+ return {
239
+ original: marker.match,
240
+ replacement: wrapExpression(`\` : ${transformConditionExpr(marker.condition, loopVars)} ? \``),
241
+ index: marker.index,
242
+ };
243
+ }
244
+ /**
245
+ * Creates replacement for each marker
246
+ */
247
+ function createEachReplacement(marker) {
248
+ const mapParams = marker.indexName
249
+ ? `(${marker.itemName}, ${marker.indexName})`
250
+ : `(${marker.itemName}, __index)`;
251
+ return {
252
+ original: marker.match,
253
+ replacement: wrapExpression(`\${((__array) => __array.map(${mapParams} => \``),
254
+ index: marker.index,
255
+ };
256
+ }
257
+ /**
258
+ * Creates replacement for end marker
259
+ */
260
+ function createEndReplacement(marker, block) {
261
+ if (block?.type === 'if') {
262
+ return {
263
+ original: marker.match,
264
+ replacement: "` : ''}",
265
+ index: marker.index,
266
+ };
267
+ }
268
+ if (block?.type === 'each') {
269
+ return {
270
+ original: marker.match,
271
+ replacement: `\`).join(''))(ctx.${block.arrayPath})}`,
272
+ index: marker.index,
273
+ };
274
+ }
275
+ return null;
276
+ }
277
+ /**
278
+ * Builds replacement array from markers
279
+ */
280
+ function buildReplacements(markers, loopVarsAtPosition) {
281
+ const replacements = [];
282
+ const blockStack = [];
283
+ for (const marker of markers) {
284
+ const loopVars = loopVarsAtPosition.get(marker.index) || new Set();
285
+ switch (marker.type) {
286
+ case 'if':
287
+ blockStack.push({ type: 'if' });
288
+ {
289
+ const replacement = createIfReplacement(marker, loopVars);
290
+ if (replacement) {
291
+ replacements.push(replacement);
292
+ }
293
+ }
294
+ break;
295
+ case 'elseif': {
296
+ const replacement = createElseifReplacement(marker, loopVars);
297
+ if (replacement) {
298
+ replacements.push(replacement);
299
+ }
300
+ break;
301
+ }
302
+ case 'else':
303
+ replacements.push({
304
+ original: marker.match,
305
+ replacement: '` : `',
306
+ index: marker.index,
307
+ });
308
+ break;
309
+ case 'each':
310
+ blockStack.push({
311
+ type: 'each',
312
+ arrayPath: marker.arrayPath,
313
+ });
314
+ replacements.push(createEachReplacement(marker));
315
+ break;
316
+ case 'end': {
317
+ const block = blockStack.pop();
318
+ const replacement = createEndReplacement(marker, block);
319
+ if (replacement) {
320
+ replacements.push(replacement);
321
+ }
322
+ break;
323
+ }
324
+ }
325
+ }
326
+ return replacements;
327
+ }
328
+ /**
329
+ * Applies replacements to HTML string
330
+ */
331
+ function applyReplacements(html, replacements) {
332
+ let result = html;
333
+ // Apply replacements (in reverse order to preserve indices)
334
+ for (let i = replacements.length - 1; i >= 0; i--) {
335
+ const { original, replacement, index } = replacements[i];
336
+ result = result.slice(0, index) + replacement + result.slice(index + original.length);
337
+ }
338
+ return result;
339
+ }
340
+ /**
341
+ * Transforms variable interpolations in HTML
342
+ */
343
+ function transformVariables(html, markers) {
344
+ // Build final loop variable set from all @each markers
345
+ const allLoopVars = new Set();
346
+ for (const marker of markers) {
347
+ if (marker.type === 'each') {
348
+ if (marker.itemName)
349
+ allLoopVars.add(marker.itemName);
350
+ if (marker.indexName)
351
+ allLoopVars.add(marker.indexName);
352
+ }
353
+ }
354
+ // Transform variable interpolations
355
+ return html.replace(/\{\{([^}]+)\}\}/g, (_match, expression) => {
356
+ return transformVariableExpr(expression.trim(), allLoopVars);
357
+ });
358
+ }
359
+ /**
360
+ * Transforms compiled HTML by replacing control flow markers and variables
361
+ * with JavaScript template literal expressions.
362
+ */
363
+ function transformHtmlToTemplateLiteral(html) {
364
+ const markers = findMarkers(html);
365
+ const loopVarsAtPosition = buildLoopVarScope(markers);
366
+ const replacements = buildReplacements(markers, loopVarsAtPosition);
367
+ let result = applyReplacements(html, replacements);
368
+ result = transformVariables(result, markers);
369
+ return result;
370
+ }
371
+ /**
372
+ * Transforms a condition expression, handling loop context variables.
373
+ */
374
+ function transformConditionExpr(condition, loopVars) {
375
+ let result = condition
376
+ .replace(/@index/g, '__index')
377
+ .replace(/@first/g, '(__index === 0)')
378
+ .replace(/@last/g, '(__index === __array.length - 1)')
379
+ .replace(/@length/g, '__array.length');
380
+ // Add ctx. prefix to root-level variables only
381
+ // Match variable paths like "items", "items.length", "user.isAdmin"
382
+ result = result.replace(/\b([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*)\b/g, (match, varPath) => {
383
+ const rootVar = varPath.split('.')[0];
384
+ // Don't prefix JS keywords
385
+ if (['true', 'false', 'null', 'undefined', 'length'].includes(rootVar)) {
386
+ return match;
387
+ }
388
+ // Don't prefix internal loop variables
389
+ if (['__index', '__array'].includes(rootVar)) {
390
+ return match;
391
+ }
392
+ // Don't prefix loop item variables
393
+ if (loopVars.has(rootVar)) {
394
+ return match;
395
+ }
396
+ return `ctx.${match}`;
397
+ });
398
+ return result;
399
+ }
400
+ /**
401
+ * Transforms a variable expression to a template literal expression.
402
+ */
403
+ function prefixContextVariables(expression, loopVars) {
404
+ const reserved = new Set([
405
+ 'true',
406
+ 'false',
407
+ 'null',
408
+ 'undefined',
409
+ 'length',
410
+ 'Math',
411
+ 'Number',
412
+ 'String',
413
+ 'Boolean',
414
+ ]);
415
+ return expression.replace(/\b([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*)\b/g, (match, varPath) => {
416
+ const rootVar = varPath.split('.')[0];
417
+ if (reserved.has(rootVar)) {
418
+ return match;
419
+ }
420
+ if (['__index', '__array'].includes(rootVar)) {
421
+ return match;
422
+ }
423
+ if (loopVars.has(rootVar)) {
424
+ return match;
425
+ }
426
+ return `ctx.${match}`;
427
+ });
428
+ }
429
+ function transformVariableExpr(expression, loopVars) {
430
+ // Check for default value: name ?? 'default'
431
+ const defaultMatch = expression.match(/^(.+?)\s*\?\?\s*['"]([^'"]*)['"]\s*$/);
432
+ if (defaultMatch) {
433
+ const path = defaultMatch[1].trim();
434
+ const defaultValue = defaultMatch[2];
435
+ const rootVar = path.split('.')[0];
436
+ // Check if root is a loop variable
437
+ if (loopVars.has(rootVar)) {
438
+ return wrapExpression(`\${${path} ?? '${defaultValue}'}`);
439
+ }
440
+ return wrapExpression(`\${ctx.${path} ?? '${defaultValue}'}`);
441
+ }
442
+ // Handle loop context variables (@index, @first, @last, @length)
443
+ if (expression.startsWith('@')) {
444
+ const loopVar = expression.slice(1);
445
+ switch (loopVar) {
446
+ case 'index':
447
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Intentional - building template literal string
448
+ return wrapExpression('${__index}');
449
+ case 'first':
450
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Intentional - building template literal string
451
+ return wrapExpression('${__index === 0}');
452
+ case 'last':
453
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Intentional - building template literal string
454
+ return wrapExpression('${__index === __array.length - 1}');
455
+ case 'length':
456
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Intentional - building template literal string
457
+ return wrapExpression('${__array.length}');
458
+ default:
459
+ return wrapExpression(`\${${loopVar}}`);
460
+ }
461
+ }
462
+ // Handle expressions with operators or loop context
463
+ if (expression.includes('@') || expression.includes('+') || expression.includes('-')) {
464
+ const transformed = prefixContextVariables(expression
465
+ .replace(/@index/g, '__index')
466
+ .replace(/@first/g, '(__index === 0)')
467
+ .replace(/@last/g, '(__index === __array.length - 1)')
468
+ .replace(/@length/g, '__array.length'), loopVars);
469
+ return wrapExpression(`\${${transformed}}`);
470
+ }
471
+ // Check if root variable is a loop item variable
472
+ const rootVar = expression.split('.')[0];
473
+ if (loopVars.has(rootVar)) {
474
+ return wrapExpression(`\${${expression}}`);
475
+ }
476
+ // Regular context variable
477
+ return wrapExpression(`\${ctx.${expression}}`);
478
+ }
479
+ function toPascalCase(str) {
480
+ return str
481
+ .split(/[-_\s.]+/)
482
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
483
+ .join('');
484
+ }
485
+ /**
486
+ * Escapes template literal control characters while preserving generated expressions.
487
+ *
488
+ * We temporarily replace protected expressions (wrapped with EXPR_OPEN/EXPR_CLOSE)
489
+ * with placeholders, escape the remaining content, and then restore the expressions.
490
+ */
491
+ function escapeTemplateLiteral(str) {
492
+ const placeholders = new Map();
493
+ let index = 0;
494
+ const protectedStr = str.replace(new RegExp(`${EXPR_OPEN}([\\s\\S]*?)${EXPR_CLOSE}`, 'g'), (_match, expr) => {
495
+ const key = `__GW_EXPR_PLACEHOLDER_${index}__`;
496
+ placeholders.set(index, expr);
497
+ index++;
498
+ return key;
499
+ });
500
+ const escaped = protectedStr.replace(/`/g, '\\`').replace(/\$\{/g, '\\${');
501
+ let restored = escaped;
502
+ for (const [placeholderIndex, expr] of placeholders.entries()) {
503
+ restored = restored.replace(`__GW_EXPR_PLACEHOLDER_${placeholderIndex}__`, expr);
504
+ }
505
+ return restored;
506
+ }
507
+ // Re-export types and utilities
508
+ export { tokenize } from './tokenizer.js';
509
+ export { extractTypes, generateInterface } from './type-extractor.js';
510
+ //# sourceMappingURL=compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../../src/email/compiler/compiler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { type CompiledTemplateInfo, type CompileOptions, type CompileResult, compileTemplates, } from './compile-templates.js';
2
+ export { compile, extractTypes, generateInterface, tokenize } from './compiler.js';
3
+ export type { CompiledTemplate, CompilerOptions, EachToken, ElseIfToken, ElseToken, EndToken, IfToken, InferredType, ParseResult, TextToken, Token, TokenType, VariableToken, } from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/email/compiler/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnF,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,WAAW,EACX,SAAS,EACT,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,WAAW,EACX,SAAS,EACT,KAAK,EACL,SAAS,EACT,aAAa,GACd,MAAM,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { compileTemplates, } from './compile-templates.js';
2
+ export { compile, extractTypes, generateInterface, tokenize } from './compiler.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/email/compiler/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Token } from './types.js';
2
+ /**
3
+ * Tokenizes a template string into a stream of tokens.
4
+ * Handles both control flow markers (<!-- @if -->) and variable interpolation ({{var}}).
5
+ */
6
+ export declare function tokenize(input: string): Token[];
7
+ //# sourceMappingURL=tokenizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../../../src/email/compiler/tokenizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAOV,KAAK,EAEN,MAAM,YAAY,CAAC;AAYpB;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,CA2D/C"}