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.
- package/dist/core/bootstrap.d.ts +2 -1
- package/dist/core/bootstrap.d.ts.map +1 -1
- package/dist/core/bootstrap.js +121 -44
- package/dist/core/bootstrap.js.map +1 -1
- package/dist/core/types.d.ts +53 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/email/compiler/code-generator.d.ts +11 -0
- package/dist/email/compiler/code-generator.d.ts.map +1 -0
- package/dist/email/compiler/code-generator.js +319 -0
- package/dist/email/compiler/code-generator.js.map +1 -0
- package/dist/email/compiler/compile-templates.d.ts +68 -0
- package/dist/email/compiler/compile-templates.d.ts.map +1 -0
- package/dist/email/compiler/compile-templates.js +156 -0
- package/dist/email/compiler/compile-templates.js.map +1 -0
- package/dist/email/compiler/compiler.d.ts +30 -0
- package/dist/email/compiler/compiler.d.ts.map +1 -0
- package/dist/email/compiler/compiler.js +510 -0
- package/dist/email/compiler/compiler.js.map +1 -0
- package/dist/email/compiler/index.d.ts +4 -0
- package/dist/email/compiler/index.d.ts.map +1 -0
- package/dist/email/compiler/index.js +3 -0
- package/dist/email/compiler/index.js.map +1 -0
- package/dist/email/compiler/tokenizer.d.ts +7 -0
- package/dist/email/compiler/tokenizer.d.ts.map +1 -0
- package/dist/email/compiler/tokenizer.js +154 -0
- package/dist/email/compiler/tokenizer.js.map +1 -0
- package/dist/email/compiler/type-extractor.d.ts +11 -0
- package/dist/email/compiler/type-extractor.d.ts.map +1 -0
- package/dist/email/compiler/type-extractor.js +296 -0
- package/dist/email/compiler/type-extractor.js.map +1 -0
- package/dist/email/compiler/types.d.ts +108 -0
- package/dist/email/compiler/types.d.ts.map +1 -0
- package/dist/email/compiler/types.js.map +1 -0
- package/dist/email/config.d.ts +89 -0
- package/dist/email/config.d.ts.map +1 -0
- package/dist/email/config.js +55 -0
- package/dist/email/config.js.map +1 -0
- package/dist/email/email-service.d.ts +54 -0
- package/dist/email/email-service.d.ts.map +1 -0
- package/dist/email/email-service.js +94 -0
- package/dist/email/email-service.js.map +1 -0
- package/dist/email/index.d.ts +12 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/email/index.js +23 -0
- package/dist/email/index.js.map +1 -0
- package/dist/email/template-registry.d.ts +83 -0
- package/dist/email/template-registry.d.ts.map +1 -0
- package/dist/email/template-registry.js +85 -0
- package/dist/email/template-registry.js.map +1 -0
- package/dist/email/templated-email-service.d.ts +59 -0
- package/dist/email/templated-email-service.d.ts.map +1 -0
- package/dist/email/templated-email-service.js +63 -0
- package/dist/email/templated-email-service.js.map +1 -0
- package/dist/email/transports/index.d.ts +3 -0
- package/dist/email/transports/index.d.ts.map +1 -0
- package/dist/email/transports/index.js +3 -0
- package/dist/email/transports/index.js.map +1 -0
- package/dist/email/transports/mock-transport.d.ts +74 -0
- package/dist/email/transports/mock-transport.d.ts.map +1 -0
- package/dist/email/transports/mock-transport.js +102 -0
- package/dist/email/transports/mock-transport.js.map +1 -0
- package/dist/email/transports/ses-transport.d.ts +65 -0
- package/dist/email/transports/ses-transport.d.ts.map +1 -0
- package/dist/email/transports/ses-transport.js +290 -0
- package/dist/email/transports/ses-transport.js.map +1 -0
- package/dist/email/types.d.ts +128 -0
- package/dist/email/types.d.ts.map +1 -0
- package/dist/email/types.js +2 -0
- package/dist/{hooks → email}/types.js.map +1 -1
- package/dist/email/webhooks/handler-factory.d.ts +41 -0
- package/dist/email/webhooks/handler-factory.d.ts.map +1 -0
- package/dist/email/webhooks/handler-factory.js +136 -0
- package/dist/email/webhooks/handler-factory.js.map +1 -0
- package/dist/email/webhooks/index.d.ts +6 -0
- package/dist/email/webhooks/index.d.ts.map +1 -0
- package/dist/email/webhooks/index.js +9 -0
- package/dist/email/webhooks/index.js.map +1 -0
- package/dist/email/webhooks/notification-parser.d.ts +45 -0
- package/dist/email/webhooks/notification-parser.d.ts.map +1 -0
- package/dist/email/webhooks/notification-parser.js +150 -0
- package/dist/email/webhooks/notification-parser.js.map +1 -0
- package/dist/email/webhooks/signature-verification.d.ts +38 -0
- package/dist/email/webhooks/signature-verification.d.ts.map +1 -0
- package/dist/email/webhooks/signature-verification.js +179 -0
- package/dist/email/webhooks/signature-verification.js.map +1 -0
- package/dist/email/webhooks/subscription-handler.d.ts +37 -0
- package/dist/email/webhooks/subscription-handler.d.ts.map +1 -0
- package/dist/email/webhooks/subscription-handler.js +99 -0
- package/dist/email/webhooks/subscription-handler.js.map +1 -0
- package/dist/email/webhooks/types.d.ts +187 -0
- package/dist/email/webhooks/types.d.ts.map +1 -0
- package/dist/email/webhooks/types.js +5 -0
- package/dist/email/webhooks/types.js.map +1 -0
- package/dist/http/error-handler.d.ts +28 -3
- package/dist/http/error-handler.d.ts.map +1 -1
- package/dist/http/error-handler.js +97 -22
- package/dist/http/error-handler.js.map +1 -1
- package/dist/http/errors.d.ts +52 -22
- package/dist/http/errors.d.ts.map +1 -1
- package/dist/http/errors.js +62 -42
- package/dist/http/errors.js.map +1 -1
- package/dist/http/route-helpers.d.ts +13 -0
- package/dist/http/route-helpers.d.ts.map +1 -1
- package/dist/http/route-helpers.js +15 -3
- package/dist/http/route-helpers.js.map +1 -1
- package/dist/index.d.ts +14 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -1
- package/dist/list-query/builder.d.ts +5 -0
- package/dist/list-query/builder.d.ts.map +1 -1
- package/dist/list-query/builder.js +34 -1
- package/dist/list-query/builder.js.map +1 -1
- package/dist/middleware/rate-limit.d.ts.map +1 -1
- package/dist/middleware/rate-limit.js +28 -18
- package/dist/middleware/rate-limit.js.map +1 -1
- package/dist/observability/exception-tracking.d.ts +214 -0
- package/dist/observability/exception-tracking.d.ts.map +1 -0
- package/dist/observability/exception-tracking.js +238 -0
- package/dist/observability/exception-tracking.js.map +1 -0
- package/dist/observability/pino-logger.d.ts +108 -0
- package/dist/observability/pino-logger.d.ts.map +1 -0
- package/dist/observability/pino-logger.js +158 -0
- package/dist/observability/pino-logger.js.map +1 -0
- package/dist/observability/request-context.d.ts +105 -0
- package/dist/observability/request-context.d.ts.map +1 -0
- package/dist/observability/request-context.js +115 -0
- package/dist/observability/request-context.js.map +1 -0
- package/dist/openapi/openapi.d.ts.map +1 -1
- package/dist/openapi/openapi.js +3 -1
- package/dist/openapi/openapi.js.map +1 -1
- package/dist/utils/environment.d.ts +2 -1
- package/dist/utils/environment.d.ts.map +1 -1
- package/dist/utils/environment.js +11 -2
- package/dist/utils/environment.js.map +1 -1
- package/dist/utils/logger.d.ts +43 -9
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +60 -16
- package/dist/utils/logger.js.map +1 -1
- package/package.json +15 -2
- package/dist/authorization/ability-middleware.d.ts +0 -61
- package/dist/authorization/ability-middleware.d.ts.map +0 -1
- package/dist/authorization/ability-middleware.js +0 -74
- package/dist/authorization/ability-middleware.js.map +0 -1
- package/dist/authorization/index.d.ts +0 -46
- package/dist/authorization/index.d.ts.map +0 -1
- package/dist/authorization/index.js +0 -46
- package/dist/authorization/index.js.map +0 -1
- package/dist/authorization/route-helpers.d.ts +0 -106
- package/dist/authorization/route-helpers.d.ts.map +0 -1
- package/dist/authorization/route-helpers.js +0 -136
- package/dist/authorization/route-helpers.js.map +0 -1
- package/dist/authorization/service-proxy.d.ts +0 -59
- package/dist/authorization/service-proxy.d.ts.map +0 -1
- package/dist/authorization/service-proxy.js +0 -110
- package/dist/authorization/service-proxy.js.map +0 -1
- package/dist/authorization/types.d.ts +0 -58
- package/dist/authorization/types.d.ts.map +0 -1
- package/dist/authorization/types.js +0 -7
- package/dist/authorization/types.js.map +0 -1
- package/dist/hooks/authorization-hook.d.ts +0 -100
- package/dist/hooks/authorization-hook.d.ts.map +0 -1
- package/dist/hooks/authorization-hook.js +0 -93
- package/dist/hooks/authorization-hook.js.map +0 -1
- package/dist/hooks/index.d.ts +0 -54
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js +0 -55
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/service-hooks.d.ts +0 -82
- package/dist/hooks/service-hooks.d.ts.map +0 -1
- package/dist/hooks/service-hooks.js +0 -158
- package/dist/hooks/service-hooks.js.map +0 -1
- package/dist/hooks/types.d.ts +0 -151
- package/dist/hooks/types.d.ts.map +0 -1
- package/dist/openapi/hooks.d.ts +0 -14
- package/dist/openapi/hooks.d.ts.map +0 -1
- package/dist/openapi/hooks.js +0 -83
- package/dist/openapi/hooks.js.map +0 -1
- package/dist/openapi/openapi-transformer.d.ts +0 -13
- package/dist/openapi/openapi-transformer.d.ts.map +0 -1
- package/dist/openapi/openapi-transformer.js +0 -87
- package/dist/openapi/openapi-transformer.js.map +0 -1
- package/dist/utils/pagination.d.ts +0 -48
- package/dist/utils/pagination.d.ts.map +0 -1
- package/dist/utils/pagination.js +0 -42
- package/dist/utils/pagination.js.map +0 -1
- package/dist/utils/serialize-dates.d.ts +0 -27
- package/dist/utils/serialize-dates.d.ts.map +0 -1
- package/dist/utils/serialize-dates.js +0 -39
- package/dist/utils/serialize-dates.js.map +0 -1
- /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(/ /gi, ' ')
|
|
84
|
+
.replace(/&/gi, '&')
|
|
85
|
+
.replace(/</gi, '<')
|
|
86
|
+
.replace(/>/gi, '>')
|
|
87
|
+
.replace(/"/gi, '"')
|
|
88
|
+
.replace(/'/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"}
|