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,89 @@
1
+ import * as v from 'valibot';
2
+ /**
3
+ * Valibot schema for SES transport configuration
4
+ */
5
+ export declare const SESTransportConfigSchema: v.ObjectSchema<{
6
+ readonly type: v.LiteralSchema<"ses", undefined>;
7
+ readonly region: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
8
+ readonly configurationSet: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
9
+ readonly endpoint: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
10
+ }, undefined>;
11
+ /**
12
+ * Valibot schema for SMTP transport configuration
13
+ */
14
+ export declare const SMTPTransportConfigSchema: v.ObjectSchema<{
15
+ readonly type: v.LiteralSchema<"smtp", undefined>;
16
+ readonly host: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
17
+ readonly port: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, 65535, undefined>]>;
18
+ readonly secure: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
19
+ readonly auth: v.OptionalSchema<v.ObjectSchema<{
20
+ readonly user: v.StringSchema<undefined>;
21
+ readonly pass: v.StringSchema<undefined>;
22
+ }, undefined>, undefined>;
23
+ }, undefined>;
24
+ /**
25
+ * Valibot schema for mock transport configuration (testing)
26
+ */
27
+ export declare const MockTransportConfigSchema: v.ObjectSchema<{
28
+ readonly type: v.LiteralSchema<"mock", undefined>;
29
+ }, undefined>;
30
+ /**
31
+ * Union of all transport configurations
32
+ */
33
+ export declare const TransportConfigSchema: v.UnionSchema<[v.ObjectSchema<{
34
+ readonly type: v.LiteralSchema<"ses", undefined>;
35
+ readonly region: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
36
+ readonly configurationSet: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
37
+ readonly endpoint: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
38
+ }, undefined>, v.ObjectSchema<{
39
+ readonly type: v.LiteralSchema<"smtp", undefined>;
40
+ readonly host: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
41
+ readonly port: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, 65535, undefined>]>;
42
+ readonly secure: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
43
+ readonly auth: v.OptionalSchema<v.ObjectSchema<{
44
+ readonly user: v.StringSchema<undefined>;
45
+ readonly pass: v.StringSchema<undefined>;
46
+ }, undefined>, undefined>;
47
+ }, undefined>, v.ObjectSchema<{
48
+ readonly type: v.LiteralSchema<"mock", undefined>;
49
+ }, undefined>], undefined>;
50
+ /**
51
+ * Valibot schema for email module configuration
52
+ */
53
+ export declare const EmailConfigSchema: v.ObjectSchema<{
54
+ /** Default sender email address */
55
+ readonly from: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>;
56
+ /** Default reply-to address */
57
+ readonly replyTo: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>, undefined>;
58
+ /** Transport configuration */
59
+ readonly transport: v.UnionSchema<[v.ObjectSchema<{
60
+ readonly type: v.LiteralSchema<"ses", undefined>;
61
+ readonly region: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
62
+ readonly configurationSet: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
63
+ readonly endpoint: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
64
+ }, undefined>, v.ObjectSchema<{
65
+ readonly type: v.LiteralSchema<"smtp", undefined>;
66
+ readonly host: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
67
+ readonly port: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, 65535, undefined>]>;
68
+ readonly secure: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
69
+ readonly auth: v.OptionalSchema<v.ObjectSchema<{
70
+ readonly user: v.StringSchema<undefined>;
71
+ readonly pass: v.StringSchema<undefined>;
72
+ }, undefined>, undefined>;
73
+ }, undefined>, v.ObjectSchema<{
74
+ readonly type: v.LiteralSchema<"mock", undefined>;
75
+ }, undefined>], undefined>;
76
+ }, undefined>;
77
+ /**
78
+ * Inferred types from schemas
79
+ */
80
+ export type SESTransportConfigInput = v.InferInput<typeof SESTransportConfigSchema>;
81
+ export type SMTPTransportConfigInput = v.InferInput<typeof SMTPTransportConfigSchema>;
82
+ export type MockTransportConfigInput = v.InferInput<typeof MockTransportConfigSchema>;
83
+ export type TransportConfigInput = v.InferInput<typeof TransportConfigSchema>;
84
+ export type EmailConfigInput = v.InferInput<typeof EmailConfigSchema>;
85
+ /**
86
+ * Validates email configuration
87
+ */
88
+ export declare function validateEmailConfig(config: unknown): EmailConfigInput;
89
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/email/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAE7B;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;;aAKnC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;aAWpC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,yBAAyB;;aAEpC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;0BAIhC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB;IAC5B,mCAAmC;;IAEnC,+BAA+B;;IAE/B,8BAA8B;;;;;;;;;;;;;;;;;;aAE9B,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC;AACpF,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC;AACtF,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC;AACtF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC9E,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEtE;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,gBAAgB,CAErE"}
@@ -0,0 +1,55 @@
1
+ import * as v from 'valibot';
2
+ /**
3
+ * Valibot schema for SES transport configuration
4
+ */
5
+ export const SESTransportConfigSchema = v.object({
6
+ type: v.literal('ses'),
7
+ region: v.pipe(v.string(), v.minLength(1)),
8
+ configurationSet: v.optional(v.string()),
9
+ endpoint: v.optional(v.string()),
10
+ });
11
+ /**
12
+ * Valibot schema for SMTP transport configuration
13
+ */
14
+ export const SMTPTransportConfigSchema = v.object({
15
+ type: v.literal('smtp'),
16
+ host: v.pipe(v.string(), v.minLength(1)),
17
+ port: v.pipe(v.number(), v.minValue(1), v.maxValue(65535)),
18
+ secure: v.optional(v.boolean()),
19
+ auth: v.optional(v.object({
20
+ user: v.string(),
21
+ pass: v.string(),
22
+ })),
23
+ });
24
+ /**
25
+ * Valibot schema for mock transport configuration (testing)
26
+ */
27
+ export const MockTransportConfigSchema = v.object({
28
+ type: v.literal('mock'),
29
+ });
30
+ /**
31
+ * Union of all transport configurations
32
+ */
33
+ export const TransportConfigSchema = v.union([
34
+ SESTransportConfigSchema,
35
+ SMTPTransportConfigSchema,
36
+ MockTransportConfigSchema,
37
+ ]);
38
+ /**
39
+ * Valibot schema for email module configuration
40
+ */
41
+ export const EmailConfigSchema = v.object({
42
+ /** Default sender email address */
43
+ from: v.pipe(v.string(), v.email()),
44
+ /** Default reply-to address */
45
+ replyTo: v.optional(v.pipe(v.string(), v.email())),
46
+ /** Transport configuration */
47
+ transport: TransportConfigSchema,
48
+ });
49
+ /**
50
+ * Validates email configuration
51
+ */
52
+ export function validateEmailConfig(config) {
53
+ return v.parse(EmailConfigSchema, config);
54
+ }
55
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/email/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAE7B;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACtB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC1C,gBAAgB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACxC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CACjC,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACvB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACxC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1D,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/B,IAAI,EAAE,CAAC,CAAC,QAAQ,CACd,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;KACjB,CAAC,CACH;CACF,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;CACxB,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC;IAC3C,wBAAwB;IACxB,yBAAyB;IACzB,yBAAyB;CAC1B,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,mCAAmC;IACnC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;IACnC,+BAA+B;IAC/B,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IAClD,8BAA8B;IAC9B,SAAS,EAAE,qBAAqB;CACjC,CAAC,CAAC;AAWH;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,OAAO,CAAC,CAAC,KAAK,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,54 @@
1
+ import type { EmailConfig, EmailMessage, EmailResult, OnSentHook } from './types.js';
2
+ /**
3
+ * Options for sending an email
4
+ */
5
+ export interface SendOptions {
6
+ /** Override the default sender */
7
+ from?: string;
8
+ /** Override the default reply-to */
9
+ replyTo?: string;
10
+ }
11
+ /**
12
+ * Email service for sending emails through configured transport
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const emailService = new EmailService({
17
+ * transport: new SESTransport({ region: 'eu-west-1' }),
18
+ * from: 'noreply@example.com',
19
+ * });
20
+ *
21
+ * // Send raw email
22
+ * await emailService.sendRaw({
23
+ * to: 'user@example.com',
24
+ * subject: 'Welcome!',
25
+ * html: '<h1>Welcome to our app!</h1>',
26
+ * });
27
+ * ```
28
+ */
29
+ export declare class EmailService {
30
+ private readonly transport;
31
+ private readonly defaultFrom;
32
+ private readonly defaultReplyTo?;
33
+ private readonly onSent?;
34
+ constructor(config: EmailConfig, onSent?: OnSentHook);
35
+ /**
36
+ * Sends a raw email message
37
+ *
38
+ * @param message - Email message to send
39
+ * @param options - Optional overrides for sender/reply-to
40
+ * @returns The send result with message ID
41
+ */
42
+ sendRaw(message: Omit<EmailMessage, 'from'> & {
43
+ from?: string;
44
+ }, options?: SendOptions): Promise<EmailResult>;
45
+ /**
46
+ * Gets the transport name for debugging
47
+ */
48
+ get transportName(): string;
49
+ /**
50
+ * Converts HTML to plain text for email clients that don't support HTML
51
+ */
52
+ private htmlToText;
53
+ }
54
+ //# sourceMappingURL=email-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-service.d.ts","sourceRoot":"","sources":["../../src/email/email-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EAEX,UAAU,EACX,MAAM,YAAY,CAAC;AAIpB;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAa;gBAEzB,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,UAAU;IAOpD;;;;;;OAMG;IACG,OAAO,CACX,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EACvD,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,WAAW,CAAC;IAuBvB;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED;;OAEG;IACH,OAAO,CAAC,UAAU;CA2BnB"}
@@ -0,0 +1,94 @@
1
+ import { createLogger } from '../utils/logger.js';
2
+ const logger = createLogger('EmailService');
3
+ /**
4
+ * Email service for sending emails through configured transport
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * const emailService = new EmailService({
9
+ * transport: new SESTransport({ region: 'eu-west-1' }),
10
+ * from: 'noreply@example.com',
11
+ * });
12
+ *
13
+ * // Send raw email
14
+ * await emailService.sendRaw({
15
+ * to: 'user@example.com',
16
+ * subject: 'Welcome!',
17
+ * html: '<h1>Welcome to our app!</h1>',
18
+ * });
19
+ * ```
20
+ */
21
+ export class EmailService {
22
+ transport;
23
+ defaultFrom;
24
+ defaultReplyTo;
25
+ onSent;
26
+ constructor(config, onSent) {
27
+ this.transport = config.transport;
28
+ this.defaultFrom = config.from;
29
+ this.defaultReplyTo = config.replyTo;
30
+ this.onSent = onSent;
31
+ }
32
+ /**
33
+ * Sends a raw email message
34
+ *
35
+ * @param message - Email message to send
36
+ * @param options - Optional overrides for sender/reply-to
37
+ * @returns The send result with message ID
38
+ */
39
+ async sendRaw(message, options) {
40
+ const fullMessage = {
41
+ ...message,
42
+ from: options?.from || message.from || this.defaultFrom,
43
+ replyTo: options?.replyTo || message.replyTo || this.defaultReplyTo,
44
+ text: message.text || this.htmlToText(message.html),
45
+ };
46
+ const result = await this.transport.send(fullMessage);
47
+ // Call onSent hook if configured
48
+ if (this.onSent && result.success) {
49
+ try {
50
+ await this.onSent(result, fullMessage);
51
+ }
52
+ catch (error) {
53
+ // Log but don't fail the send
54
+ logger.error('onSent hook failed:', error);
55
+ }
56
+ }
57
+ return result;
58
+ }
59
+ /**
60
+ * Gets the transport name for debugging
61
+ */
62
+ get transportName() {
63
+ return this.transport.name;
64
+ }
65
+ /**
66
+ * Converts HTML to plain text for email clients that don't support HTML
67
+ */
68
+ htmlToText(html) {
69
+ return (html
70
+ // Remove style and script tags with content
71
+ .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
72
+ .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
73
+ // Convert line breaks
74
+ .replace(/<br\s*\/?>/gi, '\n')
75
+ // Convert block elements to newlines
76
+ .replace(/<\/(p|div|tr|h[1-6])>/gi, '\n')
77
+ // Convert list items
78
+ .replace(/<li[^>]*>/gi, '• ')
79
+ .replace(/<\/li>/gi, '\n')
80
+ // Remove remaining HTML tags
81
+ .replace(/<[^>]+>/g, '')
82
+ // Decode common HTML entities
83
+ .replace(/&nbsp;/gi, ' ')
84
+ .replace(/&amp;/gi, '&')
85
+ .replace(/&lt;/gi, '<')
86
+ .replace(/&gt;/gi, '>')
87
+ .replace(/&quot;/gi, '"')
88
+ .replace(/&#39;/gi, "'")
89
+ // Clean up whitespace
90
+ .replace(/\n\s*\n\s*\n/g, '\n\n')
91
+ .trim());
92
+ }
93
+ }
94
+ //# sourceMappingURL=email-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-service.js","sourceRoot":"","sources":["../../src/email/email-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AASlD,MAAM,MAAM,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;AAY5C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,YAAY;IACN,SAAS,CAAiB;IAC1B,WAAW,CAAS;IACpB,cAAc,CAAU;IACxB,MAAM,CAAc;IAErC,YAAY,MAAmB,EAAE,MAAmB;QAClD,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC;QAC/B,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,OAAO,CACX,OAAuD,EACvD,OAAqB;QAErB,MAAM,WAAW,GAAiB;YAChC,GAAG,OAAO;YACV,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW;YACvD,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,cAAc;YACnE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC;SACpD,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAEtD,iCAAiC;QACjC,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YACzC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,8BAA8B;gBAC9B,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED;;OAEG;IACK,UAAU,CAAC,IAAY;QAC7B,OAAO,CACL,IAAI;YACF,4CAA4C;aAC3C,OAAO,CAAC,iCAAiC,EAAE,EAAE,CAAC;aAC9C,OAAO,CAAC,mCAAmC,EAAE,EAAE,CAAC;YACjD,sBAAsB;aACrB,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC;YAC9B,qCAAqC;aACpC,OAAO,CAAC,yBAAyB,EAAE,IAAI,CAAC;YACzC,qBAAqB;aACpB,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC;aAC5B,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC;YAC1B,6BAA6B;aAC5B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;YACxB,8BAA8B;aAC7B,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;aACxB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;aACvB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;aACtB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;aACtB,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;aACxB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;YACxB,sBAAsB;aACrB,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC;aAChC,IAAI,EAAE,CACV,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ export { type CompileOptions, type CompileResult, compileTemplates, } from './compiler/compile-templates.js';
2
+ export type { CompiledTemplate, CompilerOptions, InferredType, Token, TokenType, } from './compiler/index.js';
3
+ export { compile, extractTypes, generateInterface, tokenize } from './compiler/index.js';
4
+ export { type EmailConfigInput, EmailConfigSchema, type MockTransportConfigInput, MockTransportConfigSchema, type SESTransportConfigInput, SESTransportConfigSchema, type SMTPTransportConfigInput, SMTPTransportConfigSchema, type TransportConfigInput, TransportConfigSchema, validateEmailConfig, } from './config.js';
5
+ export { EmailService, type SendOptions } from './email-service.js';
6
+ export { createTemplateRegistry, type TemplateDefinition, TemplateRegistry, type TemplateRenderFn, } from './template-registry.js';
7
+ export { type SendTemplateOptions, TemplatedEmailService, } from './templated-email-service.js';
8
+ export { MockTransport, type StoredEmail } from './transports/mock-transport.js';
9
+ export { SESTransport } from './transports/ses-transport.js';
10
+ export type { EmailAttachment, EmailConfig, EmailMessage, EmailModuleOptions, EmailResult, EmailTransport, OnSentHook, SESTransportConfig, SMTPTransportConfig, } from './types.js';
11
+ export { type BouncedEvent, type ComplaintEvent, type CreateWebhookHandlerOptions, clearCertCache, createSESWebhookHandler, type DeliveredEvent, type HandleSubscriptionOptions, handleSNSSubscription, parseSESNotification, parseSNSMessage, type SESBounceNotification, type SESComplaintNotification, type SESDeliveryNotification, type SESEvent, type SESNotification, type SESWebhookHandlers, type SNSMessage, type VerifySignatureOptions, verifySNSSignature, } from './webhooks/index.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/email/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,gBAAgB,GACjB,MAAM,iCAAiC,CAAC;AACzC,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,KAAK,EACL,SAAS,GACV,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EACL,KAAK,gBAAgB,EACrB,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,yBAAyB,EACzB,KAAK,uBAAuB,EAC5B,wBAAwB,EACxB,KAAK,wBAAwB,EAC7B,yBAAyB,EACzB,KAAK,oBAAoB,EACzB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEpE,OAAO,EACL,sBAAsB,EACtB,KAAK,kBAAkB,EACvB,gBAAgB,EAChB,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,mBAAmB,EACxB,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,YAAY,EACV,eAAe,EACf,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,2BAA2B,EAChC,cAAc,EAEd,uBAAuB,EACvB,KAAK,cAAc,EACnB,KAAK,yBAAyB,EAC9B,qBAAqB,EAErB,oBAAoB,EACpB,eAAe,EACf,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAE5B,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,sBAAsB,EAE3B,kBAAkB,GACnB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,23 @@
1
+ // Email module main exports
2
+ export { compileTemplates, } from './compiler/compile-templates.js';
3
+ // Compiler (for build-time usage)
4
+ export { compile, extractTypes, generateInterface, tokenize } from './compiler/index.js';
5
+ // Configuration
6
+ export { EmailConfigSchema, MockTransportConfigSchema, SESTransportConfigSchema, SMTPTransportConfigSchema, TransportConfigSchema, validateEmailConfig, } from './config.js';
7
+ // Services
8
+ export { EmailService } from './email-service.js';
9
+ // Template registry
10
+ export { createTemplateRegistry, TemplateRegistry, } from './template-registry.js';
11
+ export { TemplatedEmailService, } from './templated-email-service.js';
12
+ export { MockTransport } from './transports/mock-transport.js';
13
+ // Transports
14
+ export { SESTransport } from './transports/ses-transport.js';
15
+ // Webhooks (delivery tracking)
16
+ export { clearCertCache,
17
+ // Handler factory
18
+ createSESWebhookHandler, handleSNSSubscription,
19
+ // Parsers
20
+ parseSESNotification, parseSNSMessage,
21
+ // Middleware
22
+ verifySNSSignature, } from './webhooks/index.js';
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/email/index.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAE5B,OAAO,EAGL,gBAAgB,GACjB,MAAM,iCAAiC,CAAC;AAQzC,kCAAkC;AAClC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACzF,gBAAgB;AAChB,OAAO,EAEL,iBAAiB,EAEjB,yBAAyB,EAEzB,wBAAwB,EAExB,yBAAyB,EAEzB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,WAAW;AACX,OAAO,EAAE,YAAY,EAAoB,MAAM,oBAAoB,CAAC;AACpE,oBAAoB;AACpB,OAAO,EACL,sBAAsB,EAEtB,gBAAgB,GAEjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAEL,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,aAAa,EAAoB,MAAM,gCAAgC,CAAC;AACjF,aAAa;AACb,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAc7D,+BAA+B;AAC/B,OAAO,EAIL,cAAc;AACd,kBAAkB;AAClB,uBAAuB,EAGvB,qBAAqB;AACrB,UAAU;AACV,oBAAoB,EACpB,eAAe;AAUf,aAAa;AACb,kBAAkB,GACnB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Template render function signature
3
+ */
4
+ export type TemplateRenderFn<TContext> = (ctx: TContext) => {
5
+ html: string;
6
+ text: string;
7
+ };
8
+ /**
9
+ * Template definition with metadata
10
+ */
11
+ export interface TemplateDefinition<TContext = unknown> {
12
+ /** Template name/identifier */
13
+ name: string;
14
+ /** The render function generated by the compiler */
15
+ render: TemplateRenderFn<TContext>;
16
+ /** Default subject line (can be overridden) */
17
+ subject?: string;
18
+ }
19
+ /**
20
+ * Registry for compiled email templates
21
+ *
22
+ * Provides type-safe access to templates and their context types.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * // templates.compiled/index.ts
27
+ * import * as welcomeEmail from './welcome-email.js';
28
+ * import * as passwordReset from './password-reset.js';
29
+ *
30
+ * export const templates = new TemplateRegistry()
31
+ * .register('welcome', welcomeEmail.render, { subject: 'Welcome!' })
32
+ * .register('password-reset', passwordReset.render, { subject: 'Reset your password' });
33
+ *
34
+ * // Usage
35
+ * const { html, text } = templates.render('welcome', { name: 'Alice' });
36
+ * ```
37
+ */
38
+ export declare class TemplateRegistry<TTemplates extends Record<string, TemplateDefinition> = Record<string, never>> {
39
+ private readonly templates;
40
+ /**
41
+ * Registers a template with the registry
42
+ *
43
+ * @param name - Unique template identifier
44
+ * @param render - The compiled render function
45
+ * @param options - Optional template metadata
46
+ * @returns A new registry with the template added (for chaining)
47
+ */
48
+ register<TName extends string, TContext>(name: TName, render: TemplateRenderFn<TContext>, options?: {
49
+ subject?: string;
50
+ }): TemplateRegistry<TTemplates & Record<TName, TemplateDefinition<TContext>>>;
51
+ /**
52
+ * Renders a template with the given context
53
+ *
54
+ * @param name - Template name
55
+ * @param context - Template context data
56
+ * @returns The rendered HTML and text
57
+ */
58
+ render<TName extends keyof TTemplates>(name: TName, context: TTemplates[TName] extends TemplateDefinition<infer TContext> ? TContext : never): {
59
+ html: string;
60
+ text: string;
61
+ };
62
+ /**
63
+ * Gets the default subject for a template
64
+ */
65
+ getSubject<TName extends keyof TTemplates>(name: TName): string | undefined;
66
+ /**
67
+ * Checks if a template exists
68
+ */
69
+ has(name: string): boolean;
70
+ /**
71
+ * Gets all registered template names
72
+ */
73
+ get names(): string[];
74
+ /**
75
+ * Gets the number of registered templates
76
+ */
77
+ get size(): number;
78
+ }
79
+ /**
80
+ * Creates a new empty template registry
81
+ */
82
+ export declare function createTemplateRegistry(): TemplateRegistry;
83
+ //# sourceMappingURL=template-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-registry.d.ts","sourceRoot":"","sources":["../../src/email/template-registry.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAAC,QAAQ,IAAI,CAAC,GAAG,EAAE,QAAQ,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3F;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,QAAQ,GAAG,OAAO;IACpD,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACnC,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,gBAAgB,CAC3B,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAE7E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8C;IAExE;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,SAAS,MAAM,EAAE,QAAQ,EACrC,IAAI,EAAE,KAAK,EACX,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EAClC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC7B,gBAAgB,CAAC,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC;IAa7E;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,SAAS,MAAM,UAAU,EACnC,IAAI,EAAE,KAAK,EACX,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,SAAS,kBAAkB,CAAC,MAAM,QAAQ,CAAC,GAAG,QAAQ,GAAG,KAAK,GACvF;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAQjC;;OAEG;IACH,UAAU,CAAC,KAAK,SAAS,MAAM,UAAU,EAAE,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS;IAK3E;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,EAAE,CAEpB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAEzD"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Registry for compiled email templates
3
+ *
4
+ * Provides type-safe access to templates and their context types.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * // templates.compiled/index.ts
9
+ * import * as welcomeEmail from './welcome-email.js';
10
+ * import * as passwordReset from './password-reset.js';
11
+ *
12
+ * export const templates = new TemplateRegistry()
13
+ * .register('welcome', welcomeEmail.render, { subject: 'Welcome!' })
14
+ * .register('password-reset', passwordReset.render, { subject: 'Reset your password' });
15
+ *
16
+ * // Usage
17
+ * const { html, text } = templates.render('welcome', { name: 'Alice' });
18
+ * ```
19
+ */
20
+ export class TemplateRegistry {
21
+ templates = new Map();
22
+ /**
23
+ * Registers a template with the registry
24
+ *
25
+ * @param name - Unique template identifier
26
+ * @param render - The compiled render function
27
+ * @param options - Optional template metadata
28
+ * @returns A new registry with the template added (for chaining)
29
+ */
30
+ register(name, render, options) {
31
+ this.templates.set(name, {
32
+ name,
33
+ render: render,
34
+ subject: options?.subject,
35
+ });
36
+ // Return this for chaining (type-safe)
37
+ return this;
38
+ }
39
+ /**
40
+ * Renders a template with the given context
41
+ *
42
+ * @param name - Template name
43
+ * @param context - Template context data
44
+ * @returns The rendered HTML and text
45
+ */
46
+ render(name, context) {
47
+ const template = this.templates.get(name);
48
+ if (!template) {
49
+ throw new Error(`Template "${String(name)}" not found in registry`);
50
+ }
51
+ return template.render(context);
52
+ }
53
+ /**
54
+ * Gets the default subject for a template
55
+ */
56
+ getSubject(name) {
57
+ const template = this.templates.get(name);
58
+ return template?.subject;
59
+ }
60
+ /**
61
+ * Checks if a template exists
62
+ */
63
+ has(name) {
64
+ return this.templates.has(name);
65
+ }
66
+ /**
67
+ * Gets all registered template names
68
+ */
69
+ get names() {
70
+ return [...this.templates.keys()];
71
+ }
72
+ /**
73
+ * Gets the number of registered templates
74
+ */
75
+ get size() {
76
+ return this.templates.size;
77
+ }
78
+ }
79
+ /**
80
+ * Creates a new empty template registry
81
+ */
82
+ export function createTemplateRegistry() {
83
+ return new TemplateRegistry();
84
+ }
85
+ //# sourceMappingURL=template-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-registry.js","sourceRoot":"","sources":["../../src/email/template-registry.ts"],"names":[],"mappings":"AAiBA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,gBAAgB;IAGV,SAAS,GAAoC,IAAI,GAAG,EAAE,CAAC;IAExE;;;;;;;OAOG;IACH,QAAQ,CACN,IAAW,EACX,MAAkC,EAClC,OAA8B;QAE9B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE;YACvB,IAAI;YACJ,MAAM,EAAE,MAAmC;YAC3C,OAAO,EAAE,OAAO,EAAE,OAAO;SAC1B,CAAC,CAAC;QAEH,uCAAuC;QACvC,OAAO,IAEN,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CACJ,IAAW,EACX,OAAwF;QAExF,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAc,CAAC,CAAC;QACpD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,aAAa,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,UAAU,CAAiC,IAAW;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAc,CAAC,CAAC;QACpD,OAAO,QAAQ,EAAE,OAAO,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,IAAI,KAAK;QACP,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;IAC7B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,gBAAgB,EAAE,CAAC;AAChC,CAAC"}
@@ -0,0 +1,59 @@
1
+ import { EmailService, type SendOptions } from './email-service.js';
2
+ import type { TemplateDefinition, TemplateRegistry } from './template-registry.js';
3
+ import type { EmailConfig, EmailResult, OnSentHook } from './types.js';
4
+ /**
5
+ * Options for sending a templated email
6
+ */
7
+ export interface SendTemplateOptions extends SendOptions {
8
+ /** Recipient email address(es) */
9
+ to: string | string[];
10
+ /** Override the template's default subject */
11
+ subject?: string;
12
+ /** CC recipients */
13
+ cc?: string | string[];
14
+ /** BCC recipients */
15
+ bcc?: string | string[];
16
+ }
17
+ /**
18
+ * Templated email service with type-safe template sending
19
+ *
20
+ * Extends the base EmailService with template-aware sending methods.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // Create service with templates
25
+ * const emailService = new TemplatedEmailService({
26
+ * config: { transport, from: 'noreply@example.com' },
27
+ * templates,
28
+ * });
29
+ *
30
+ * // Send with full type safety
31
+ * await emailService.send('welcome', {
32
+ * to: 'user@example.com',
33
+ * context: { name: 'Alice', verificationLink: '...' },
34
+ * });
35
+ * ```
36
+ */
37
+ export declare class TemplatedEmailService<TTemplates extends Record<string, TemplateDefinition>> extends EmailService {
38
+ private readonly templates;
39
+ constructor(options: {
40
+ config: EmailConfig;
41
+ templates: TemplateRegistry<TTemplates>;
42
+ onSent?: OnSentHook;
43
+ });
44
+ /**
45
+ * Sends a templated email
46
+ *
47
+ * @param template - Template name (type-safe)
48
+ * @param options - Send options including recipient and context
49
+ * @returns The send result with message ID
50
+ */
51
+ send<TName extends keyof TTemplates & string>(template: TName, options: SendTemplateOptions & {
52
+ context: TTemplates[TName] extends TemplateDefinition<infer TContext> ? TContext : never;
53
+ }): Promise<EmailResult>;
54
+ /**
55
+ * Gets the template registry
56
+ */
57
+ getTemplates(): TemplateRegistry<TTemplates>;
58
+ }
59
+ //# sourceMappingURL=templated-email-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templated-email-service.d.ts","sourceRoot":"","sources":["../../src/email/templated-email-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,kCAAkC;IAClC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvB,qBAAqB;IACrB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,qBAAqB,CAChC,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CACrD,SAAQ,YAAY;IACpB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA+B;gBAE7C,OAAO,EAAE;QACnB,MAAM,EAAE,WAAW,CAAC;QACpB,SAAS,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,CAAC,EAAE,UAAU,CAAC;KACrB;IAKD;;;;;;OAMG;IACG,IAAI,CAAC,KAAK,SAAS,MAAM,UAAU,GAAG,MAAM,EAChD,QAAQ,EAAE,KAAK,EACf,OAAO,EAAE,mBAAmB,GAAG;QAC7B,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,SAAS,kBAAkB,CAAC,MAAM,QAAQ,CAAC,GAAG,QAAQ,GAAG,KAAK,CAAC;KAC1F,GACA,OAAO,CAAC,WAAW,CAAC;IA2BvB;;OAEG;IACH,YAAY,IAAI,gBAAgB,CAAC,UAAU,CAAC;CAG7C"}