@deenruv/email-plugin 1.0.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/LICENSE +23 -0
- package/README.md +85 -0
- package/dev-mailbox.html +218 -0
- package/lib/index.d.ts +13 -0
- package/lib/index.js +30 -0
- package/lib/index.js.map +1 -0
- package/lib/src/attachment-utils.d.ts +3 -0
- package/lib/src/attachment-utils.js +66 -0
- package/lib/src/attachment-utils.js.map +1 -0
- package/lib/src/common.d.ts +4 -0
- package/lib/src/common.js +17 -0
- package/lib/src/common.js.map +1 -0
- package/lib/src/constants.d.ts +2 -0
- package/lib/src/constants.js +6 -0
- package/lib/src/constants.js.map +1 -0
- package/lib/src/dev-mailbox.d.ts +14 -0
- package/lib/src/dev-mailbox.js +116 -0
- package/lib/src/dev-mailbox.js.map +1 -0
- package/lib/src/email-processor.d.ts +21 -0
- package/lib/src/email-processor.js +109 -0
- package/lib/src/email-processor.js.map +1 -0
- package/lib/src/email-send-event.d.ts +18 -0
- package/lib/src/email-send-event.js +24 -0
- package/lib/src/email-send-event.js.map +1 -0
- package/lib/src/event-listener.d.ts +19 -0
- package/lib/src/event-listener.js +25 -0
- package/lib/src/event-listener.js.map +1 -0
- package/lib/src/generator/email-generator.d.ts +25 -0
- package/lib/src/generator/email-generator.js +3 -0
- package/lib/src/generator/email-generator.js.map +1 -0
- package/lib/src/generator/handlebars-mjml-generator.d.ts +19 -0
- package/lib/src/generator/handlebars-mjml-generator.js +78 -0
- package/lib/src/generator/handlebars-mjml-generator.js.map +1 -0
- package/lib/src/generator/noop-email-generator.d.ts +11 -0
- package/lib/src/generator/noop-email-generator.js +13 -0
- package/lib/src/generator/noop-email-generator.js.map +1 -0
- package/lib/src/generator/react-email-generator.d.ts +7 -0
- package/lib/src/generator/react-email-generator.js +40 -0
- package/lib/src/generator/react-email-generator.js.map +1 -0
- package/lib/src/handler/default-email-handlers.d.ts +32 -0
- package/lib/src/handler/default-email-handlers.js +111 -0
- package/lib/src/handler/default-email-handlers.js.map +1 -0
- package/lib/src/handler/event-handler.d.ts +276 -0
- package/lib/src/handler/event-handler.js +396 -0
- package/lib/src/handler/event-handler.js.map +1 -0
- package/lib/src/handler/mock-events.d.ts +5 -0
- package/lib/src/handler/mock-events.js +119 -0
- package/lib/src/handler/mock-events.js.map +1 -0
- package/lib/src/plugin.d.ts +301 -0
- package/lib/src/plugin.js +428 -0
- package/lib/src/plugin.js.map +1 -0
- package/lib/src/sender/email-sender.d.ts +45 -0
- package/lib/src/sender/email-sender.js +3 -0
- package/lib/src/sender/email-sender.js.map +1 -0
- package/lib/src/sender/nodemailer-email-sender.d.ts +37 -0
- package/lib/src/sender/nodemailer-email-sender.js +151 -0
- package/lib/src/sender/nodemailer-email-sender.js.map +1 -0
- package/lib/src/template-loader/file-based-template-loader.d.ts +17 -0
- package/lib/src/template-loader/file-based-template-loader.js +37 -0
- package/lib/src/template-loader/file-based-template-loader.js.map +1 -0
- package/lib/src/template-loader/react-email-template-loader.d.ts +6 -0
- package/lib/src/template-loader/react-email-template-loader.js +14 -0
- package/lib/src/template-loader/react-email-template-loader.js.map +1 -0
- package/lib/src/template-loader/template-loader.d.ts +42 -0
- package/lib/src/template-loader/template-loader.js +3 -0
- package/lib/src/template-loader/template-loader.js.map +1 -0
- package/lib/src/types.d.ts +453 -0
- package/lib/src/types.js +3 -0
- package/lib/src/types.js.map +1 -0
- package/package.json +51 -0
- package/templates/email-address-change/body.hbs +20 -0
- package/templates/email-verification/body.hbs +20 -0
- package/templates/order-confirmation/body.hbs +133 -0
- package/templates/partials/footer.hbs +10 -0
- package/templates/partials/header.hbs +18 -0
- package/templates/password-reset/body.hbs +24 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { LanguageCode } from "@deenruv/common/lib/generated-types";
|
|
2
|
+
import { Type } from "@deenruv/common/lib/shared-types";
|
|
3
|
+
import { Injector } from "@deenruv/core";
|
|
4
|
+
import { EmailEventListener } from "../event-listener";
|
|
5
|
+
import { EmailTemplateConfig, EventWithAsyncData, EventWithContext, IntermediateEmailDetails, LoadDataFn, SetAttachmentsFn, SetOptionalAddressFieldsFn, SetSubjectFn, SetTemplateVarsFn } from "../types";
|
|
6
|
+
/**
|
|
7
|
+
* @description
|
|
8
|
+
* The EmailEventHandler defines how the EmailPlugin will respond to a given event.
|
|
9
|
+
*
|
|
10
|
+
* A handler is created by creating a new {@link EmailEventListener} and calling the `.on()` method
|
|
11
|
+
* to specify which event to respond to.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const confirmationHandler = new EmailEventListener('order-confirmation')
|
|
16
|
+
* .on(OrderStateTransitionEvent)
|
|
17
|
+
* .filter(event => event.toState === 'PaymentSettled')
|
|
18
|
+
* .setRecipient(event => event.order.customer.emailAddress)
|
|
19
|
+
* .setFrom('{{ fromAddress }}')
|
|
20
|
+
* .setSubject(`Order confirmation for #{{ order.code }}`)
|
|
21
|
+
* .setTemplateVars(event => ({ order: event.order }));
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* This example creates a handler which listens for the `OrderStateTransitionEvent` and if the Order has
|
|
25
|
+
* transitioned to the `'PaymentSettled'` state, it will generate and send an email.
|
|
26
|
+
*
|
|
27
|
+
* The string argument passed into the `EmailEventListener` constructor is used to identify the handler, and
|
|
28
|
+
* also to locate the directory of the email template files. So in the example above, there should be a directory
|
|
29
|
+
* `<app root>/static/email/templates/order-confirmation` which contains a Handlebars template named `body.hbs`.
|
|
30
|
+
*
|
|
31
|
+
* ## Handling other languages
|
|
32
|
+
*
|
|
33
|
+
* By default, the handler will respond to all events on all channels and use the same subject ("Order confirmation for #12345" above)
|
|
34
|
+
* and body template. Where the server is intended to support multiple languages, the `.addTemplate()` method may be used
|
|
35
|
+
* to define the subject and body template for specific language and channel combinations.
|
|
36
|
+
*
|
|
37
|
+
* The language is determined by looking at the `languageCode` property of the event's `ctx` ({@link RequestContext}) object.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const extendedConfirmationHandler = confirmationHandler
|
|
42
|
+
* .addTemplate({
|
|
43
|
+
* channelCode: 'default',
|
|
44
|
+
* languageCode: LanguageCode.de,
|
|
45
|
+
* templateFile: 'body.de.hbs',
|
|
46
|
+
* subject: 'Bestellbestätigung für #{{ order.code }}',
|
|
47
|
+
* })
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* ## Defining a custom handler
|
|
51
|
+
*
|
|
52
|
+
* Let's say you have a plugin which defines a new event type, `QuoteRequestedEvent`. In your plugin you have defined a mutation
|
|
53
|
+
* which is executed when the customer requests a quote in your storefront, and in your resolver, you use the {@link EventBus} to publish a
|
|
54
|
+
* new `QuoteRequestedEvent`.
|
|
55
|
+
*
|
|
56
|
+
* You now want to email the customer with their quote. Here are the steps you would take to set this up:
|
|
57
|
+
*
|
|
58
|
+
* ### 1. Create a new handler
|
|
59
|
+
*
|
|
60
|
+
* ```ts
|
|
61
|
+
* import { EmailEventListener } from `\@deenruv/email-plugin`;
|
|
62
|
+
* import { QuoteRequestedEvent } from `./events`;
|
|
63
|
+
*
|
|
64
|
+
* const quoteRequestedHandler = new EmailEventListener('quote-requested')
|
|
65
|
+
* .on(QuoteRequestedEvent)
|
|
66
|
+
* .setRecipient(event => event.customer.emailAddress)
|
|
67
|
+
* .setSubject(`Here's the quote you requested`)
|
|
68
|
+
* .setFrom('{{ fromAddress }}')
|
|
69
|
+
* .setTemplateVars(event => ({ details: event.details }));
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* ### 2. Create the email template
|
|
73
|
+
*
|
|
74
|
+
* Next you need to make sure there is a template defined at `<app root>/static/email/templates/quote-requested/body.hbs`. The path
|
|
75
|
+
* segment `quote-requested` must match the string passed to the `EmailEventListener` constructor.
|
|
76
|
+
*
|
|
77
|
+
* The template would look something like this:
|
|
78
|
+
*
|
|
79
|
+
* ```handlebars
|
|
80
|
+
* {{> header title="Here's the quote you requested" }}
|
|
81
|
+
*
|
|
82
|
+
* <mj-section background-color="#fafafa">
|
|
83
|
+
* <mj-column>
|
|
84
|
+
* <mj-text color="#525252">
|
|
85
|
+
* Thank you for your interest in our products! Here's the details
|
|
86
|
+
* of the quote you recently requested:
|
|
87
|
+
* </mj-text>
|
|
88
|
+
*
|
|
89
|
+
* <--! your custom email layout goes here -->
|
|
90
|
+
* </mj-column>
|
|
91
|
+
* </mj-section>
|
|
92
|
+
*
|
|
93
|
+
*
|
|
94
|
+
* {{> footer }}
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* You can find pre-made templates on the [MJML website](https://mjml.io/templates/).
|
|
98
|
+
*
|
|
99
|
+
* ### 3. Register the handler
|
|
100
|
+
*
|
|
101
|
+
* Finally, you need to register the handler with the EmailPlugin:
|
|
102
|
+
*
|
|
103
|
+
* ```ts {hl_lines=[8]}
|
|
104
|
+
* import { defaultEmailHandlers, EmailPlugin } from '\@deenruv/email-plugin';
|
|
105
|
+
* import { quoteRequestedHandler } from './plugins/quote-plugin';
|
|
106
|
+
*
|
|
107
|
+
* const config: DeenruvConfig = {
|
|
108
|
+
* // Add an instance of the plugin to the plugins array
|
|
109
|
+
* plugins: [
|
|
110
|
+
* EmailPlugin.init({
|
|
111
|
+
* handler: [...defaultEmailHandlers, quoteRequestedHandler],
|
|
112
|
+
* templatePath: path.join(__dirname, 'deenruv/email/templates'),
|
|
113
|
+
* // ... etc
|
|
114
|
+
* }),
|
|
115
|
+
* ],
|
|
116
|
+
* };
|
|
117
|
+
* ```
|
|
118
|
+
*
|
|
119
|
+
* @docsCategory core plugins/EmailPlugin
|
|
120
|
+
*/
|
|
121
|
+
export declare class EmailEventHandler<T extends string = string, Event extends EventWithContext = EventWithContext> {
|
|
122
|
+
listener: EmailEventListener<T>;
|
|
123
|
+
event: Type<Event>;
|
|
124
|
+
private setRecipientFn;
|
|
125
|
+
private setLanguageCodeFn;
|
|
126
|
+
private setSubjectFn?;
|
|
127
|
+
private setTemplateVarsFn;
|
|
128
|
+
private setAttachmentsFn?;
|
|
129
|
+
private setOptionalAddressFieldsFn?;
|
|
130
|
+
private filterFns;
|
|
131
|
+
private configurations;
|
|
132
|
+
private defaultSubject;
|
|
133
|
+
private from;
|
|
134
|
+
private optionalAddressFields;
|
|
135
|
+
private _mockEvent;
|
|
136
|
+
constructor(listener: EmailEventListener<T>, event: Type<Event>);
|
|
137
|
+
/** @internal */
|
|
138
|
+
get type(): T;
|
|
139
|
+
/** @internal */
|
|
140
|
+
get mockEvent(): Omit<Event, "ctx" | "data"> | undefined;
|
|
141
|
+
/**
|
|
142
|
+
* @description
|
|
143
|
+
* Defines a predicate function which is used to determine whether the event will trigger an email.
|
|
144
|
+
* Multiple filter functions may be defined.
|
|
145
|
+
*/
|
|
146
|
+
filter(filterFn: (event: Event) => boolean): EmailEventHandler<T, Event>;
|
|
147
|
+
/**
|
|
148
|
+
* @description
|
|
149
|
+
* A function which defines how the recipient email address should be extracted from the incoming event.
|
|
150
|
+
*
|
|
151
|
+
* The recipient can be a plain email address: `'foobar@example.com'`
|
|
152
|
+
* Or with a formatted name (includes unicode support): `'Ноде Майлер <foobar@example.com>'`
|
|
153
|
+
* Or a comma-separated list of addresses: `'foobar@example.com, "Ноде Майлер" <bar@example.com>'`
|
|
154
|
+
*/
|
|
155
|
+
setRecipient(setRecipientFn: (event: Event) => string): EmailEventHandler<T, Event>;
|
|
156
|
+
/**
|
|
157
|
+
* @description
|
|
158
|
+
* A function which allows to override the language of the email. If not defined, the language from the context will be used.
|
|
159
|
+
*
|
|
160
|
+
* @since 1.8.0
|
|
161
|
+
*/
|
|
162
|
+
setLanguageCode(setLanguageCodeFn: (event: Event) => LanguageCode | undefined): EmailEventHandler<T, Event>;
|
|
163
|
+
/**
|
|
164
|
+
* @description
|
|
165
|
+
* A function which returns an object hash of variables which will be made available to the Handlebars template
|
|
166
|
+
* and subject line for interpolation.
|
|
167
|
+
*/
|
|
168
|
+
setTemplateVars(templateVarsFn: SetTemplateVarsFn<Event>): EmailEventHandler<T, Event>;
|
|
169
|
+
/**
|
|
170
|
+
* @description
|
|
171
|
+
* Sets the default subject of the email. The subject string may use Handlebars variables defined by the
|
|
172
|
+
* setTemplateVars() method.
|
|
173
|
+
*/
|
|
174
|
+
setSubject(defaultSubject: string | SetSubjectFn<Event>): EmailEventHandler<T, Event>;
|
|
175
|
+
/**
|
|
176
|
+
* @description
|
|
177
|
+
* Sets the default from field of the email. The from string may use Handlebars variables defined by the
|
|
178
|
+
* setTemplateVars() method.
|
|
179
|
+
*/
|
|
180
|
+
setFrom(from: string): EmailEventHandler<T, Event>;
|
|
181
|
+
/**
|
|
182
|
+
* @description
|
|
183
|
+
* A function which allows {@link OptionalAddressFields} to be specified such as "cc" and "bcc".
|
|
184
|
+
*
|
|
185
|
+
* @since 1.1.0
|
|
186
|
+
*/
|
|
187
|
+
setOptionalAddressFields(optionalAddressFieldsFn: SetOptionalAddressFieldsFn<Event>): this;
|
|
188
|
+
/**
|
|
189
|
+
* @description
|
|
190
|
+
* Defines one or more files to be attached to the email. An attachment can be specified
|
|
191
|
+
* as either a `path` (to a file or URL) or as `content` which can be a string, Buffer or Stream.
|
|
192
|
+
*
|
|
193
|
+
* **Note:** When using the `content` to pass a Buffer or Stream, the raw data will get serialized
|
|
194
|
+
* into the job queue. For this reason the total size of all attachments passed as `content` should kept to
|
|
195
|
+
* **less than ~50k**. If the attachments are greater than that limit, a warning will be logged and
|
|
196
|
+
* errors may result if using the DefaultJobQueuePlugin with certain DBs such as MySQL/MariaDB.
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```ts
|
|
200
|
+
* const testAttachmentHandler = new EmailEventListener('activate-voucher')
|
|
201
|
+
* .on(ActivateVoucherEvent)
|
|
202
|
+
* // ... omitted some steps for brevity
|
|
203
|
+
* .setAttachments(async (event) => {
|
|
204
|
+
* const { imageUrl, voucherCode } = await getVoucherDataForUser(event.user.id);
|
|
205
|
+
* return [
|
|
206
|
+
* {
|
|
207
|
+
* filename: `voucher-${voucherCode}.jpg`,
|
|
208
|
+
* path: imageUrl,
|
|
209
|
+
* },
|
|
210
|
+
* ];
|
|
211
|
+
* });
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
setAttachments(setAttachmentsFn: SetAttachmentsFn<Event>): this;
|
|
215
|
+
/**
|
|
216
|
+
* @description
|
|
217
|
+
* Add configuration for another template other than the default `"body.hbs"`. Use this method to define specific
|
|
218
|
+
* templates for channels or languageCodes other than the default.
|
|
219
|
+
*
|
|
220
|
+
* @deprecated Define a custom TemplateLoader on plugin initalization to define templates based on the RequestContext.
|
|
221
|
+
* E.g. `EmailPlugin.init({ templateLoader: new CustomTemplateLoader() })`
|
|
222
|
+
*/
|
|
223
|
+
addTemplate(config: EmailTemplateConfig): EmailEventHandler<T, Event>;
|
|
224
|
+
/**
|
|
225
|
+
* @description
|
|
226
|
+
* Allows data to be loaded asynchronously which can then be used as template variables.
|
|
227
|
+
* The `loadDataFn` has access to the event, the TypeORM `Connection` object, and an
|
|
228
|
+
* `inject()` function which can be used to inject any of the providers exported
|
|
229
|
+
* by the {@link PluginCommonModule}. The return value of the `loadDataFn` will be
|
|
230
|
+
* added to the `event` as the `data` property.
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* ```ts
|
|
234
|
+
* new EmailEventListener('order-confirmation')
|
|
235
|
+
* .on(OrderStateTransitionEvent)
|
|
236
|
+
* .filter(event => event.toState === 'PaymentSettled' && !!event.order.customer)
|
|
237
|
+
* .loadData(({ event, injector }) => {
|
|
238
|
+
* const orderService = injector.get(OrderService);
|
|
239
|
+
* return orderService.getOrderPayments(event.order.id);
|
|
240
|
+
* })
|
|
241
|
+
* .setTemplateVars(event => ({
|
|
242
|
+
* order: event.order,
|
|
243
|
+
* payments: event.data,
|
|
244
|
+
* }))
|
|
245
|
+
* // ...
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
loadData<R>(loadDataFn: LoadDataFn<Event, R>): EmailEventHandlerWithAsyncData<R, T, Event, EventWithAsyncData<Event, R>>;
|
|
249
|
+
/**
|
|
250
|
+
* @description
|
|
251
|
+
* Used internally by the EmailPlugin to handle incoming events.
|
|
252
|
+
*
|
|
253
|
+
* @internal
|
|
254
|
+
*/
|
|
255
|
+
handle(event: Event, globals: {
|
|
256
|
+
[key: string]: any;
|
|
257
|
+
} | undefined, injector: Injector): Promise<IntermediateEmailDetails | undefined>;
|
|
258
|
+
/**
|
|
259
|
+
* @description
|
|
260
|
+
* Optionally define a mock Event which is used by the dev mode mailbox app for generating mock emails
|
|
261
|
+
* from this handler, which is useful when developing the email templates.
|
|
262
|
+
*/
|
|
263
|
+
setMockEvent(event: Omit<Event, "ctx" | "data">): EmailEventHandler<T, Event>;
|
|
264
|
+
private getBestConfiguration;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* @description
|
|
268
|
+
* Identical to the {@link EmailEventHandler} but with a `data` property added to the `event` based on the result
|
|
269
|
+
* of the `.loadData()` function.
|
|
270
|
+
*
|
|
271
|
+
* @docsCategory core plugins/EmailPlugin
|
|
272
|
+
*/
|
|
273
|
+
export declare class EmailEventHandlerWithAsyncData<Data, T extends string = string, InputEvent extends EventWithContext = EventWithContext, Event extends EventWithAsyncData<InputEvent, Data> = EventWithAsyncData<InputEvent, Data>> extends EmailEventHandler<T, Event> {
|
|
274
|
+
_loadDataFn: LoadDataFn<InputEvent, Data>;
|
|
275
|
+
constructor(_loadDataFn: LoadDataFn<InputEvent, Data>, listener: EmailEventListener<T>, event: Type<InputEvent>);
|
|
276
|
+
}
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EmailEventHandlerWithAsyncData = exports.EmailEventHandler = void 0;
|
|
4
|
+
const core_1 = require("@deenruv/core");
|
|
5
|
+
const attachment_utils_1 = require("../attachment-utils");
|
|
6
|
+
const constants_1 = require("../constants");
|
|
7
|
+
/**
|
|
8
|
+
* @description
|
|
9
|
+
* The EmailEventHandler defines how the EmailPlugin will respond to a given event.
|
|
10
|
+
*
|
|
11
|
+
* A handler is created by creating a new {@link EmailEventListener} and calling the `.on()` method
|
|
12
|
+
* to specify which event to respond to.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const confirmationHandler = new EmailEventListener('order-confirmation')
|
|
17
|
+
* .on(OrderStateTransitionEvent)
|
|
18
|
+
* .filter(event => event.toState === 'PaymentSettled')
|
|
19
|
+
* .setRecipient(event => event.order.customer.emailAddress)
|
|
20
|
+
* .setFrom('{{ fromAddress }}')
|
|
21
|
+
* .setSubject(`Order confirmation for #{{ order.code }}`)
|
|
22
|
+
* .setTemplateVars(event => ({ order: event.order }));
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* This example creates a handler which listens for the `OrderStateTransitionEvent` and if the Order has
|
|
26
|
+
* transitioned to the `'PaymentSettled'` state, it will generate and send an email.
|
|
27
|
+
*
|
|
28
|
+
* The string argument passed into the `EmailEventListener` constructor is used to identify the handler, and
|
|
29
|
+
* also to locate the directory of the email template files. So in the example above, there should be a directory
|
|
30
|
+
* `<app root>/static/email/templates/order-confirmation` which contains a Handlebars template named `body.hbs`.
|
|
31
|
+
*
|
|
32
|
+
* ## Handling other languages
|
|
33
|
+
*
|
|
34
|
+
* By default, the handler will respond to all events on all channels and use the same subject ("Order confirmation for #12345" above)
|
|
35
|
+
* and body template. Where the server is intended to support multiple languages, the `.addTemplate()` method may be used
|
|
36
|
+
* to define the subject and body template for specific language and channel combinations.
|
|
37
|
+
*
|
|
38
|
+
* The language is determined by looking at the `languageCode` property of the event's `ctx` ({@link RequestContext}) object.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* const extendedConfirmationHandler = confirmationHandler
|
|
43
|
+
* .addTemplate({
|
|
44
|
+
* channelCode: 'default',
|
|
45
|
+
* languageCode: LanguageCode.de,
|
|
46
|
+
* templateFile: 'body.de.hbs',
|
|
47
|
+
* subject: 'Bestellbestätigung für #{{ order.code }}',
|
|
48
|
+
* })
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* ## Defining a custom handler
|
|
52
|
+
*
|
|
53
|
+
* Let's say you have a plugin which defines a new event type, `QuoteRequestedEvent`. In your plugin you have defined a mutation
|
|
54
|
+
* which is executed when the customer requests a quote in your storefront, and in your resolver, you use the {@link EventBus} to publish a
|
|
55
|
+
* new `QuoteRequestedEvent`.
|
|
56
|
+
*
|
|
57
|
+
* You now want to email the customer with their quote. Here are the steps you would take to set this up:
|
|
58
|
+
*
|
|
59
|
+
* ### 1. Create a new handler
|
|
60
|
+
*
|
|
61
|
+
* ```ts
|
|
62
|
+
* import { EmailEventListener } from `\@deenruv/email-plugin`;
|
|
63
|
+
* import { QuoteRequestedEvent } from `./events`;
|
|
64
|
+
*
|
|
65
|
+
* const quoteRequestedHandler = new EmailEventListener('quote-requested')
|
|
66
|
+
* .on(QuoteRequestedEvent)
|
|
67
|
+
* .setRecipient(event => event.customer.emailAddress)
|
|
68
|
+
* .setSubject(`Here's the quote you requested`)
|
|
69
|
+
* .setFrom('{{ fromAddress }}')
|
|
70
|
+
* .setTemplateVars(event => ({ details: event.details }));
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* ### 2. Create the email template
|
|
74
|
+
*
|
|
75
|
+
* Next you need to make sure there is a template defined at `<app root>/static/email/templates/quote-requested/body.hbs`. The path
|
|
76
|
+
* segment `quote-requested` must match the string passed to the `EmailEventListener` constructor.
|
|
77
|
+
*
|
|
78
|
+
* The template would look something like this:
|
|
79
|
+
*
|
|
80
|
+
* ```handlebars
|
|
81
|
+
* {{> header title="Here's the quote you requested" }}
|
|
82
|
+
*
|
|
83
|
+
* <mj-section background-color="#fafafa">
|
|
84
|
+
* <mj-column>
|
|
85
|
+
* <mj-text color="#525252">
|
|
86
|
+
* Thank you for your interest in our products! Here's the details
|
|
87
|
+
* of the quote you recently requested:
|
|
88
|
+
* </mj-text>
|
|
89
|
+
*
|
|
90
|
+
* <--! your custom email layout goes here -->
|
|
91
|
+
* </mj-column>
|
|
92
|
+
* </mj-section>
|
|
93
|
+
*
|
|
94
|
+
*
|
|
95
|
+
* {{> footer }}
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* You can find pre-made templates on the [MJML website](https://mjml.io/templates/).
|
|
99
|
+
*
|
|
100
|
+
* ### 3. Register the handler
|
|
101
|
+
*
|
|
102
|
+
* Finally, you need to register the handler with the EmailPlugin:
|
|
103
|
+
*
|
|
104
|
+
* ```ts {hl_lines=[8]}
|
|
105
|
+
* import { defaultEmailHandlers, EmailPlugin } from '\@deenruv/email-plugin';
|
|
106
|
+
* import { quoteRequestedHandler } from './plugins/quote-plugin';
|
|
107
|
+
*
|
|
108
|
+
* const config: DeenruvConfig = {
|
|
109
|
+
* // Add an instance of the plugin to the plugins array
|
|
110
|
+
* plugins: [
|
|
111
|
+
* EmailPlugin.init({
|
|
112
|
+
* handler: [...defaultEmailHandlers, quoteRequestedHandler],
|
|
113
|
+
* templatePath: path.join(__dirname, 'deenruv/email/templates'),
|
|
114
|
+
* // ... etc
|
|
115
|
+
* }),
|
|
116
|
+
* ],
|
|
117
|
+
* };
|
|
118
|
+
* ```
|
|
119
|
+
*
|
|
120
|
+
* @docsCategory core plugins/EmailPlugin
|
|
121
|
+
*/
|
|
122
|
+
class EmailEventHandler {
|
|
123
|
+
constructor(listener, event) {
|
|
124
|
+
this.listener = listener;
|
|
125
|
+
this.event = event;
|
|
126
|
+
this.filterFns = [];
|
|
127
|
+
this.configurations = [];
|
|
128
|
+
}
|
|
129
|
+
/** @internal */
|
|
130
|
+
get type() {
|
|
131
|
+
return this.listener.type;
|
|
132
|
+
}
|
|
133
|
+
/** @internal */
|
|
134
|
+
get mockEvent() {
|
|
135
|
+
return this._mockEvent;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* @description
|
|
139
|
+
* Defines a predicate function which is used to determine whether the event will trigger an email.
|
|
140
|
+
* Multiple filter functions may be defined.
|
|
141
|
+
*/
|
|
142
|
+
filter(filterFn) {
|
|
143
|
+
this.filterFns.push(filterFn);
|
|
144
|
+
return this;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* @description
|
|
148
|
+
* A function which defines how the recipient email address should be extracted from the incoming event.
|
|
149
|
+
*
|
|
150
|
+
* The recipient can be a plain email address: `'foobar@example.com'`
|
|
151
|
+
* Or with a formatted name (includes unicode support): `'Ноде Майлер <foobar@example.com>'`
|
|
152
|
+
* Or a comma-separated list of addresses: `'foobar@example.com, "Ноде Майлер" <bar@example.com>'`
|
|
153
|
+
*/
|
|
154
|
+
setRecipient(setRecipientFn) {
|
|
155
|
+
this.setRecipientFn = setRecipientFn;
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* @description
|
|
160
|
+
* A function which allows to override the language of the email. If not defined, the language from the context will be used.
|
|
161
|
+
*
|
|
162
|
+
* @since 1.8.0
|
|
163
|
+
*/
|
|
164
|
+
setLanguageCode(setLanguageCodeFn) {
|
|
165
|
+
this.setLanguageCodeFn = setLanguageCodeFn;
|
|
166
|
+
return this;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* @description
|
|
170
|
+
* A function which returns an object hash of variables which will be made available to the Handlebars template
|
|
171
|
+
* and subject line for interpolation.
|
|
172
|
+
*/
|
|
173
|
+
setTemplateVars(templateVarsFn) {
|
|
174
|
+
this.setTemplateVarsFn = templateVarsFn;
|
|
175
|
+
return this;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* @description
|
|
179
|
+
* Sets the default subject of the email. The subject string may use Handlebars variables defined by the
|
|
180
|
+
* setTemplateVars() method.
|
|
181
|
+
*/
|
|
182
|
+
setSubject(defaultSubject) {
|
|
183
|
+
if (typeof defaultSubject === "string") {
|
|
184
|
+
this.defaultSubject = defaultSubject;
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
this.setSubjectFn = defaultSubject;
|
|
188
|
+
}
|
|
189
|
+
return this;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* @description
|
|
193
|
+
* Sets the default from field of the email. The from string may use Handlebars variables defined by the
|
|
194
|
+
* setTemplateVars() method.
|
|
195
|
+
*/
|
|
196
|
+
setFrom(from) {
|
|
197
|
+
this.from = from;
|
|
198
|
+
return this;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* @description
|
|
202
|
+
* A function which allows {@link OptionalAddressFields} to be specified such as "cc" and "bcc".
|
|
203
|
+
*
|
|
204
|
+
* @since 1.1.0
|
|
205
|
+
*/
|
|
206
|
+
setOptionalAddressFields(optionalAddressFieldsFn) {
|
|
207
|
+
this.setOptionalAddressFieldsFn = optionalAddressFieldsFn;
|
|
208
|
+
return this;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* @description
|
|
212
|
+
* Defines one or more files to be attached to the email. An attachment can be specified
|
|
213
|
+
* as either a `path` (to a file or URL) or as `content` which can be a string, Buffer or Stream.
|
|
214
|
+
*
|
|
215
|
+
* **Note:** When using the `content` to pass a Buffer or Stream, the raw data will get serialized
|
|
216
|
+
* into the job queue. For this reason the total size of all attachments passed as `content` should kept to
|
|
217
|
+
* **less than ~50k**. If the attachments are greater than that limit, a warning will be logged and
|
|
218
|
+
* errors may result if using the DefaultJobQueuePlugin with certain DBs such as MySQL/MariaDB.
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```ts
|
|
222
|
+
* const testAttachmentHandler = new EmailEventListener('activate-voucher')
|
|
223
|
+
* .on(ActivateVoucherEvent)
|
|
224
|
+
* // ... omitted some steps for brevity
|
|
225
|
+
* .setAttachments(async (event) => {
|
|
226
|
+
* const { imageUrl, voucherCode } = await getVoucherDataForUser(event.user.id);
|
|
227
|
+
* return [
|
|
228
|
+
* {
|
|
229
|
+
* filename: `voucher-${voucherCode}.jpg`,
|
|
230
|
+
* path: imageUrl,
|
|
231
|
+
* },
|
|
232
|
+
* ];
|
|
233
|
+
* });
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
setAttachments(setAttachmentsFn) {
|
|
237
|
+
this.setAttachmentsFn = setAttachmentsFn;
|
|
238
|
+
return this;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* @description
|
|
242
|
+
* Add configuration for another template other than the default `"body.hbs"`. Use this method to define specific
|
|
243
|
+
* templates for channels or languageCodes other than the default.
|
|
244
|
+
*
|
|
245
|
+
* @deprecated Define a custom TemplateLoader on plugin initalization to define templates based on the RequestContext.
|
|
246
|
+
* E.g. `EmailPlugin.init({ templateLoader: new CustomTemplateLoader() })`
|
|
247
|
+
*/
|
|
248
|
+
addTemplate(config) {
|
|
249
|
+
this.configurations.push(config);
|
|
250
|
+
return this;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* @description
|
|
254
|
+
* Allows data to be loaded asynchronously which can then be used as template variables.
|
|
255
|
+
* The `loadDataFn` has access to the event, the TypeORM `Connection` object, and an
|
|
256
|
+
* `inject()` function which can be used to inject any of the providers exported
|
|
257
|
+
* by the {@link PluginCommonModule}. The return value of the `loadDataFn` will be
|
|
258
|
+
* added to the `event` as the `data` property.
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```ts
|
|
262
|
+
* new EmailEventListener('order-confirmation')
|
|
263
|
+
* .on(OrderStateTransitionEvent)
|
|
264
|
+
* .filter(event => event.toState === 'PaymentSettled' && !!event.order.customer)
|
|
265
|
+
* .loadData(({ event, injector }) => {
|
|
266
|
+
* const orderService = injector.get(OrderService);
|
|
267
|
+
* return orderService.getOrderPayments(event.order.id);
|
|
268
|
+
* })
|
|
269
|
+
* .setTemplateVars(event => ({
|
|
270
|
+
* order: event.order,
|
|
271
|
+
* payments: event.data,
|
|
272
|
+
* }))
|
|
273
|
+
* // ...
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
loadData(loadDataFn) {
|
|
277
|
+
const asyncHandler = new EmailEventHandlerWithAsyncData(loadDataFn, this.listener, this.event);
|
|
278
|
+
asyncHandler.setRecipientFn = this.setRecipientFn;
|
|
279
|
+
asyncHandler.setTemplateVarsFn = this.setTemplateVarsFn;
|
|
280
|
+
asyncHandler.setAttachmentsFn = this.setAttachmentsFn;
|
|
281
|
+
asyncHandler.setOptionalAddressFieldsFn = this.setOptionalAddressFieldsFn;
|
|
282
|
+
asyncHandler.filterFns = this.filterFns;
|
|
283
|
+
asyncHandler.configurations = this.configurations;
|
|
284
|
+
asyncHandler.defaultSubject = this.defaultSubject;
|
|
285
|
+
asyncHandler.from = this.from;
|
|
286
|
+
asyncHandler._mockEvent = this._mockEvent;
|
|
287
|
+
return asyncHandler;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* @description
|
|
291
|
+
* Used internally by the EmailPlugin to handle incoming events.
|
|
292
|
+
*
|
|
293
|
+
* @internal
|
|
294
|
+
*/
|
|
295
|
+
async handle(event, globals = {}, injector) {
|
|
296
|
+
var _a, _b, _c, _d, _e;
|
|
297
|
+
for (const filterFn of this.filterFns) {
|
|
298
|
+
if (!filterFn(event)) {
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (this instanceof EmailEventHandlerWithAsyncData) {
|
|
303
|
+
try {
|
|
304
|
+
event.data = await this._loadDataFn({
|
|
305
|
+
event,
|
|
306
|
+
injector,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
if (err instanceof Error) {
|
|
311
|
+
core_1.Logger.error(err.message, constants_1.loggerCtx, err.stack);
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
core_1.Logger.error(String(err), constants_1.loggerCtx);
|
|
315
|
+
}
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (!this.setRecipientFn) {
|
|
320
|
+
throw new Error(`No setRecipientFn has been defined. ` +
|
|
321
|
+
`Remember to call ".setRecipient()" when setting up the EmailEventHandler for ${this.type}`);
|
|
322
|
+
}
|
|
323
|
+
if (this.from === undefined) {
|
|
324
|
+
throw new Error(`No from field has been defined. ` +
|
|
325
|
+
`Remember to call ".setFrom()" when setting up the EmailEventHandler for ${this.type}`);
|
|
326
|
+
}
|
|
327
|
+
const { ctx } = event;
|
|
328
|
+
const languageCode = ((_a = this.setLanguageCodeFn) === null || _a === void 0 ? void 0 : _a.call(this, event)) || ctx.languageCode;
|
|
329
|
+
const configuration = this.getBestConfiguration(ctx.channel.code, languageCode);
|
|
330
|
+
const subject = configuration
|
|
331
|
+
? configuration.subject
|
|
332
|
+
: this.setSubjectFn
|
|
333
|
+
? await this.setSubjectFn(event, ctx, injector)
|
|
334
|
+
: this.defaultSubject;
|
|
335
|
+
if (subject == null) {
|
|
336
|
+
throw new Error(`No subject field has been defined. ` +
|
|
337
|
+
`Remember to call ".setSubject()" when setting up the EmailEventHandler for ${this.type}`);
|
|
338
|
+
}
|
|
339
|
+
const recipient = this.setRecipientFn(event);
|
|
340
|
+
const templateVars = this.setTemplateVarsFn
|
|
341
|
+
? this.setTemplateVarsFn(event, globals)
|
|
342
|
+
: {};
|
|
343
|
+
let attachmentsArray = [];
|
|
344
|
+
try {
|
|
345
|
+
attachmentsArray = (_c = (await ((_b = this.setAttachmentsFn) === null || _b === void 0 ? void 0 : _b.call(this, event)))) !== null && _c !== void 0 ? _c : [];
|
|
346
|
+
}
|
|
347
|
+
catch (e) {
|
|
348
|
+
core_1.Logger.error(e, constants_1.loggerCtx, e.stack);
|
|
349
|
+
}
|
|
350
|
+
const attachments = await (0, attachment_utils_1.serializeAttachments)(attachmentsArray);
|
|
351
|
+
const optionalAddressFields = (_e = (await ((_d = this.setOptionalAddressFieldsFn) === null || _d === void 0 ? void 0 : _d.call(this, event)))) !== null && _e !== void 0 ? _e : {};
|
|
352
|
+
return Object.assign({ ctx: event.ctx.serialize(), type: this.type, recipient, from: this.from, templateVars: Object.assign(Object.assign({}, globals), templateVars), subject, templateFile: configuration ? configuration.templateFile : "body.hbs", attachments }, optionalAddressFields);
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* @description
|
|
356
|
+
* Optionally define a mock Event which is used by the dev mode mailbox app for generating mock emails
|
|
357
|
+
* from this handler, which is useful when developing the email templates.
|
|
358
|
+
*/
|
|
359
|
+
setMockEvent(event) {
|
|
360
|
+
this._mockEvent = event;
|
|
361
|
+
return this;
|
|
362
|
+
}
|
|
363
|
+
getBestConfiguration(channelCode, languageCode) {
|
|
364
|
+
if (this.configurations.length === 0) {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
const exactMatch = this.configurations.find((c) => {
|
|
368
|
+
return ((c.channelCode === channelCode || c.channelCode === "default") &&
|
|
369
|
+
c.languageCode === languageCode);
|
|
370
|
+
});
|
|
371
|
+
if (exactMatch) {
|
|
372
|
+
return exactMatch;
|
|
373
|
+
}
|
|
374
|
+
const channelMatch = this.configurations.find((c) => c.channelCode === channelCode && c.languageCode === "default");
|
|
375
|
+
if (channelMatch) {
|
|
376
|
+
return channelMatch;
|
|
377
|
+
}
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
exports.EmailEventHandler = EmailEventHandler;
|
|
382
|
+
/**
|
|
383
|
+
* @description
|
|
384
|
+
* Identical to the {@link EmailEventHandler} but with a `data` property added to the `event` based on the result
|
|
385
|
+
* of the `.loadData()` function.
|
|
386
|
+
*
|
|
387
|
+
* @docsCategory core plugins/EmailPlugin
|
|
388
|
+
*/
|
|
389
|
+
class EmailEventHandlerWithAsyncData extends EmailEventHandler {
|
|
390
|
+
constructor(_loadDataFn, listener, event) {
|
|
391
|
+
super(listener, event);
|
|
392
|
+
this._loadDataFn = _loadDataFn;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
exports.EmailEventHandlerWithAsyncData = EmailEventHandlerWithAsyncData;
|
|
396
|
+
//# sourceMappingURL=event-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-handler.js","sourceRoot":"","sources":["../../../src/handler/event-handler.ts"],"names":[],"mappings":";;;AAEA,wCAAiD;AAEjD,0DAA2D;AAC3D,4CAAyC;AAezC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkHG;AACH,MAAa,iBAAiB;IAoB5B,YACS,QAA+B,EAC/B,KAAkB;QADlB,aAAQ,GAAR,QAAQ,CAAuB;QAC/B,UAAK,GAAL,KAAK,CAAa;QAZnB,cAAS,GAAqC,EAAE,CAAC;QACjD,mBAAc,GAA0B,EAAE,CAAC;IAYhD,CAAC;IAEJ,gBAAgB;IAChB,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED,gBAAgB;IAChB,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,QAAmC;QACxC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CACV,cAAwC;QAExC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,eAAe,CACb,iBAA6D;QAE7D,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,eAAe,CACb,cAAwC;QAExC,IAAI,CAAC,iBAAiB,GAAG,cAAc,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,UAAU,CACR,cAA4C;QAE5C,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE,CAAC;YACvC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,YAAY,GAAG,cAAc,CAAC;QACrC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,OAAO,CAAC,IAAY;QAClB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,wBAAwB,CACtB,uBAA0D;QAE1D,IAAI,CAAC,0BAA0B,GAAG,uBAAuB,CAAC;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,cAAc,CAAC,gBAAyC;QACtD,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACH,WAAW,CAAC,MAA2B;QACrC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,QAAQ,CACN,UAAgC;QAEhC,MAAM,YAAY,GAAG,IAAI,8BAA8B,CACrD,UAAU,EACV,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,KAAK,CACX,CAAC;QACF,YAAY,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAClD,YAAY,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACxD,YAAY,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC;QACtD,YAAY,CAAC,0BAA0B,GAAG,IAAI,CAAC,0BAA0B,CAAC;QAC1E,YAAY,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACxC,YAAY,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAClD,YAAY,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAClD,YAAY,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QAC9B,YAAY,CAAC,UAAU,GAAG,IAAI,CAAC,UAAiB,CAAC;QACjD,OAAO,YAAY,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CACV,KAAY,EACZ,UAAkC,EAAE,EACpC,QAAkB;;QAElB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrB,OAAO;YACT,CAAC;QACH,CAAC;QACD,IAAI,IAAI,YAAY,8BAA8B,EAAE,CAAC;YACnD,IAAI,CAAC;gBACF,KAAwC,CAAC,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CACrE;oBACE,KAAK;oBACL,QAAQ;iBACT,CACF,CAAC;YACJ,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACtB,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;oBACzB,aAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,qBAAS,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;gBAClD,CAAC;qBAAM,CAAC;oBACN,aAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,qBAAS,CAAC,CAAC;gBACvC,CAAC;gBACD,OAAO;YACT,CAAC;QACH,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACb,sCAAsC;gBACpC,gFAAgF,IAAI,CAAC,IAAI,EAAE,CAC9F,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CACb,kCAAkC;gBAChC,2EAA2E,IAAI,CAAC,IAAI,EAAE,CACzF,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QACtB,MAAM,YAAY,GAAG,CAAA,MAAA,IAAI,CAAC,iBAAiB,qDAAG,KAAK,CAAC,KAAI,GAAG,CAAC,YAAY,CAAC;QACzE,MAAM,aAAa,GAAG,IAAI,CAAC,oBAAoB,CAC7C,GAAG,CAAC,OAAO,CAAC,IAAI,EAChB,YAAY,CACb,CAAC;QACF,MAAM,OAAO,GAAG,aAAa;YAC3B,CAAC,CAAC,aAAa,CAAC,OAAO;YACvB,CAAC,CAAC,IAAI,CAAC,YAAY;gBACjB,CAAC,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC;gBAC/C,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;QAC1B,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACb,qCAAqC;gBACnC,8EAA8E,IAAI,CAAC,IAAI,EAAE,CAC5F,CAAC;QACJ,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB;YACzC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC;YACxC,CAAC,CAAC,EAAE,CAAC;QACP,IAAI,gBAAgB,GAAsB,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,gBAAgB,GAAG,MAAA,CAAC,MAAM,CAAA,MAAA,IAAI,CAAC,gBAAgB,qDAAG,KAAK,CAAC,CAAA,CAAC,mCAAI,EAAE,CAAC;QAClE,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,aAAM,CAAC,KAAK,CAAC,CAAC,EAAE,qBAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC;QACD,MAAM,WAAW,GAAG,MAAM,IAAA,uCAAoB,EAAC,gBAAgB,CAAC,CAAC;QACjE,MAAM,qBAAqB,GACzB,MAAA,CAAC,MAAM,CAAA,MAAA,IAAI,CAAC,0BAA0B,qDAAG,KAAK,CAAC,CAAA,CAAC,mCAAI,EAAE,CAAC;QACzD,uBACE,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,EAC1B,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,SAAS,EACT,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,YAAY,kCAAO,OAAO,GAAK,YAAY,GAC3C,OAAO,EACP,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,EACrE,WAAW,IACR,qBAAqB,EACxB;IACJ,CAAC;IAED;;;;OAIG;IACH,YAAY,CACV,KAAkC;QAElC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,oBAAoB,CAC1B,WAAmB,EACnB,YAA0B;QAE1B,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrC,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;YAChD,OAAO,CACL,CAAC,CAAC,CAAC,WAAW,KAAK,WAAW,IAAI,CAAC,CAAC,WAAW,KAAK,SAAS,CAAC;gBAC9D,CAAC,CAAC,YAAY,KAAK,YAAY,CAChC,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,WAAW,IAAI,CAAC,CAAC,YAAY,KAAK,SAAS,CACrE,CAAC;QACF,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,YAAY,CAAC;QACtB,CAAC;QACD,OAAO;IACT,CAAC;CACF;AAhVD,8CAgVC;AAED;;;;;;GAMG;AACH,MAAa,8BAQX,SAAQ,iBAA2B;IACnC,YACS,WAAyC,EAChD,QAA+B,EAC/B,KAAuB;QAEvB,KAAK,CAAC,QAAQ,EAAE,KAAY,CAAC,CAAC;QAJvB,gBAAW,GAAX,WAAW,CAA8B;IAKlD,CAAC;CACF;AAhBD,wEAgBC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { AccountRegistrationEvent, IdentifierChangeRequestEvent, OrderStateTransitionEvent, PasswordResetEvent } from "@deenruv/core";
|
|
2
|
+
export declare const mockOrderStateTransitionEvent: OrderStateTransitionEvent;
|
|
3
|
+
export declare const mockAccountRegistrationEvent: AccountRegistrationEvent;
|
|
4
|
+
export declare const mockPasswordResetEvent: PasswordResetEvent;
|
|
5
|
+
export declare const mockEmailAddressChangeEvent: IdentifierChangeRequestEvent;
|