@carlonicora/nestjs-neo4jsonapi 8.8.0 → 8.10.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/agents/graph/services/graph.search.service.d.ts +14 -1
- package/dist/agents/graph/services/graph.search.service.d.ts.map +1 -1
- package/dist/agents/graph/services/graph.search.service.js +15 -4
- package/dist/agents/graph/services/graph.search.service.js.map +1 -1
- package/dist/agents/graph/tools/read-entity.tool.d.ts.map +1 -1
- package/dist/agents/graph/tools/read-entity.tool.js +19 -7
- package/dist/agents/graph/tools/read-entity.tool.js.map +1 -1
- package/dist/agents/graph/tools/tool.factory.d.ts +7 -0
- package/dist/agents/graph/tools/tool.factory.d.ts.map +1 -1
- package/dist/agents/graph/tools/tool.factory.js +12 -0
- package/dist/agents/graph/tools/tool.factory.js.map +1 -1
- package/dist/common/constants/core-module.ids.d.ts +1 -0
- package/dist/common/constants/core-module.ids.d.ts.map +1 -1
- package/dist/common/constants/core-module.ids.js +1 -0
- package/dist/common/constants/core-module.ids.js.map +1 -1
- package/dist/common/interfaces/external.entity.source.interface.d.ts +28 -0
- package/dist/common/interfaces/external.entity.source.interface.d.ts.map +1 -1
- package/dist/common/interfaces/external.entity.source.interface.js +35 -0
- package/dist/common/interfaces/external.entity.source.interface.js.map +1 -1
- package/dist/config/enums/queue.id.d.ts +1 -0
- package/dist/config/enums/queue.id.d.ts.map +1 -1
- package/dist/config/enums/queue.id.js +1 -0
- package/dist/config/enums/queue.id.js.map +1 -1
- package/dist/core/email/templates/en/emailBlast.hbs +24 -0
- package/dist/foundations/account-deletion/repositories/account-deletion.wipe.repository.d.ts.map +1 -1
- package/dist/foundations/account-deletion/repositories/account-deletion.wipe.repository.js +1 -0
- package/dist/foundations/account-deletion/repositories/account-deletion.wipe.repository.js.map +1 -1
- package/dist/foundations/assistant/services/assistant-mention.extractor.d.ts +6 -0
- package/dist/foundations/assistant/services/assistant-mention.extractor.d.ts.map +1 -1
- package/dist/foundations/assistant/services/assistant-mention.extractor.js +18 -1
- package/dist/foundations/assistant/services/assistant-mention.extractor.js.map +1 -1
- package/dist/foundations/email-automation/index.d.ts +1 -0
- package/dist/foundations/email-automation/index.d.ts.map +1 -1
- package/dist/foundations/email-automation/index.js +2 -0
- package/dist/foundations/email-automation/index.js.map +1 -1
- package/dist/foundations/email-automation/services/email-automation-renderer.service.d.ts.map +1 -1
- package/dist/foundations/email-automation/services/email-automation-renderer.service.js +2 -12
- package/dist/foundations/email-automation/services/email-automation-renderer.service.js.map +1 -1
- package/dist/foundations/email-automation/utils/email-markdown.renderer.d.ts +20 -0
- package/dist/foundations/email-automation/utils/email-markdown.renderer.d.ts.map +1 -0
- package/dist/foundations/email-automation/utils/email-markdown.renderer.js +63 -0
- package/dist/foundations/email-automation/utils/email-markdown.renderer.js.map +1 -0
- package/dist/foundations/email-blast/controllers/email-blast.controller.d.ts +30 -0
- package/dist/foundations/email-blast/controllers/email-blast.controller.d.ts.map +1 -0
- package/dist/foundations/email-blast/controllers/email-blast.controller.js +171 -0
- package/dist/foundations/email-blast/controllers/email-blast.controller.js.map +1 -0
- package/dist/foundations/email-blast/controllers/email-blast.public.controller.d.ts +24 -0
- package/dist/foundations/email-blast/controllers/email-blast.public.controller.d.ts.map +1 -0
- package/dist/foundations/email-blast/controllers/email-blast.public.controller.js +61 -0
- package/dist/foundations/email-blast/controllers/email-blast.public.controller.js.map +1 -0
- package/dist/foundations/email-blast/cron/email-blast-recovery.cron.d.ts +15 -0
- package/dist/foundations/email-blast/cron/email-blast-recovery.cron.d.ts.map +1 -0
- package/dist/foundations/email-blast/cron/email-blast-recovery.cron.js +50 -0
- package/dist/foundations/email-blast/cron/email-blast-recovery.cron.js.map +1 -0
- package/dist/foundations/email-blast/dtos/email-blast-unsubscribe.dto.d.ts +7 -0
- package/dist/foundations/email-blast/dtos/email-blast-unsubscribe.dto.d.ts.map +1 -0
- package/dist/foundations/email-blast/dtos/email-blast-unsubscribe.dto.js +35 -0
- package/dist/foundations/email-blast/dtos/email-blast-unsubscribe.dto.js.map +1 -0
- package/dist/foundations/email-blast/dtos/email-blast.patch.dto.d.ts +14 -0
- package/dist/foundations/email-blast/dtos/email-blast.patch.dto.d.ts.map +1 -0
- package/dist/foundations/email-blast/dtos/email-blast.patch.dto.js +63 -0
- package/dist/foundations/email-blast/dtos/email-blast.patch.dto.js.map +1 -0
- package/dist/foundations/email-blast/dtos/email-blast.post.dto.d.ts +14 -0
- package/dist/foundations/email-blast/dtos/email-blast.post.dto.d.ts.map +1 -0
- package/dist/foundations/email-blast/dtos/email-blast.post.dto.js +63 -0
- package/dist/foundations/email-blast/dtos/email-blast.post.dto.js.map +1 -0
- package/dist/foundations/email-blast/email-blast.constants.d.ts +34 -0
- package/dist/foundations/email-blast/email-blast.constants.d.ts.map +1 -0
- package/dist/foundations/email-blast/email-blast.constants.js +49 -0
- package/dist/foundations/email-blast/email-blast.constants.js.map +1 -0
- package/dist/foundations/email-blast/email-blast.module.d.ts +21 -0
- package/dist/foundations/email-blast/email-blast.module.d.ts.map +1 -0
- package/dist/foundations/email-blast/email-blast.module.js +101 -0
- package/dist/foundations/email-blast/email-blast.module.js.map +1 -0
- package/dist/foundations/email-blast/entities/email-blast-audience.d.ts +10 -0
- package/dist/foundations/email-blast/entities/email-blast-audience.d.ts.map +1 -0
- package/dist/foundations/email-blast/entities/email-blast-audience.js +15 -0
- package/dist/foundations/email-blast/entities/email-blast-audience.js.map +1 -0
- package/dist/foundations/email-blast/entities/email-blast-audience.meta.d.ts +6 -0
- package/dist/foundations/email-blast/entities/email-blast-audience.meta.d.ts.map +1 -0
- package/dist/foundations/email-blast/entities/email-blast-audience.meta.js +13 -0
- package/dist/foundations/email-blast/entities/email-blast-audience.meta.js.map +1 -0
- package/dist/foundations/email-blast/entities/email-blast-delivery.d.ts +31 -0
- package/dist/foundations/email-blast/entities/email-blast-delivery.d.ts.map +1 -0
- package/dist/foundations/email-blast/entities/email-blast-delivery.js +34 -0
- package/dist/foundations/email-blast/entities/email-blast-delivery.js.map +1 -0
- package/dist/foundations/email-blast/entities/email-blast-delivery.meta.d.ts +3 -0
- package/dist/foundations/email-blast/entities/email-blast-delivery.meta.d.ts.map +1 -0
- package/dist/foundations/email-blast/entities/email-blast-delivery.meta.js +10 -0
- package/dist/foundations/email-blast/entities/email-blast-delivery.meta.js.map +1 -0
- package/dist/foundations/email-blast/entities/email-blast.d.ts +16 -0
- package/dist/foundations/email-blast/entities/email-blast.d.ts.map +1 -0
- package/dist/foundations/email-blast/entities/email-blast.js +25 -0
- package/dist/foundations/email-blast/entities/email-blast.js.map +1 -0
- package/dist/foundations/email-blast/entities/email-blast.meta.d.ts +13 -0
- package/dist/foundations/email-blast/entities/email-blast.meta.d.ts.map +1 -0
- package/dist/foundations/email-blast/entities/email-blast.meta.js +20 -0
- package/dist/foundations/email-blast/entities/email-blast.meta.js.map +1 -0
- package/dist/foundations/email-blast/index.d.ts +20 -0
- package/dist/foundations/email-blast/index.d.ts.map +1 -0
- package/dist/foundations/email-blast/index.js +44 -0
- package/dist/foundations/email-blast/index.js.map +1 -0
- package/dist/foundations/email-blast/processors/email-blast.processor.d.ts +23 -0
- package/dist/foundations/email-blast/processors/email-blast.processor.d.ts.map +1 -0
- package/dist/foundations/email-blast/processors/email-blast.processor.js +80 -0
- package/dist/foundations/email-blast/processors/email-blast.processor.js.map +1 -0
- package/dist/foundations/email-blast/repositories/email-blast-delivery.repository.d.ts +98 -0
- package/dist/foundations/email-blast/repositories/email-blast-delivery.repository.d.ts.map +1 -0
- package/dist/foundations/email-blast/repositories/email-blast-delivery.repository.js +273 -0
- package/dist/foundations/email-blast/repositories/email-blast-delivery.repository.js.map +1 -0
- package/dist/foundations/email-blast/repositories/email-blast.admin.repository.d.ts +19 -0
- package/dist/foundations/email-blast/repositories/email-blast.admin.repository.d.ts.map +1 -0
- package/dist/foundations/email-blast/repositories/email-blast.admin.repository.js +63 -0
- package/dist/foundations/email-blast/repositories/email-blast.admin.repository.js.map +1 -0
- package/dist/foundations/email-blast/repositories/email-blast.repository.d.ts +29 -0
- package/dist/foundations/email-blast/repositories/email-blast.repository.d.ts.map +1 -0
- package/dist/foundations/email-blast/repositories/email-blast.repository.js +97 -0
- package/dist/foundations/email-blast/repositories/email-blast.repository.js.map +1 -0
- package/dist/foundations/email-blast/services/email-blast-delivery.service.d.ts +79 -0
- package/dist/foundations/email-blast/services/email-blast-delivery.service.d.ts.map +1 -0
- package/dist/foundations/email-blast/services/email-blast-delivery.service.js +206 -0
- package/dist/foundations/email-blast/services/email-blast-delivery.service.js.map +1 -0
- package/dist/foundations/email-blast/services/email-blast.service.d.ts +57 -0
- package/dist/foundations/email-blast/services/email-blast.service.d.ts.map +1 -0
- package/dist/foundations/email-blast/services/email-blast.service.js +134 -0
- package/dist/foundations/email-blast/services/email-blast.service.js.map +1 -0
- package/dist/foundations/email-blast/utils/email-blast.renderer.d.ts +29 -0
- package/dist/foundations/email-blast/utils/email-blast.renderer.d.ts.map +1 -0
- package/dist/foundations/email-blast/utils/email-blast.renderer.js +70 -0
- package/dist/foundations/email-blast/utils/email-blast.renderer.js.map +1 -0
- package/dist/foundations/foundations.modules.d.ts.map +1 -1
- package/dist/foundations/foundations.modules.js +3 -0
- package/dist/foundations/foundations.modules.js.map +1 -1
- package/dist/foundations/index.d.ts +1 -0
- package/dist/foundations/index.d.ts.map +1 -1
- package/dist/foundations/index.js +1 -0
- package/dist/foundations/index.js.map +1 -1
- package/dist/mcp/services/mcp.entity.write.service.d.ts +11 -0
- package/dist/mcp/services/mcp.entity.write.service.d.ts.map +1 -1
- package/dist/mcp/services/mcp.entity.write.service.js +15 -0
- package/dist/mcp/services/mcp.entity.write.service.js.map +1 -1
- package/dist/mcp/services/mcp.errors.d.ts +6 -1
- package/dist/mcp/services/mcp.errors.d.ts.map +1 -1
- package/dist/mcp/services/mcp.errors.js +12 -3
- package/dist/mcp/services/mcp.errors.js.map +1 -1
- package/dist/mcp/services/mcp.generic.tools.service.d.ts +6 -2
- package/dist/mcp/services/mcp.generic.tools.service.d.ts.map +1 -1
- package/dist/mcp/services/mcp.generic.tools.service.js +18 -5
- package/dist/mcp/services/mcp.generic.tools.service.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.EmailBlastDeliveryService = void 0;
|
|
16
|
+
const bullmq_1 = require("@nestjs/bullmq");
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const config_1 = require("@nestjs/config");
|
|
19
|
+
const bullmq_2 = require("bullmq");
|
|
20
|
+
const crypto_1 = require("crypto");
|
|
21
|
+
const nestjs_cls_1 = require("nestjs-cls");
|
|
22
|
+
const queue_id_1 = require("../../../config/enums/queue.id");
|
|
23
|
+
const cache_service_1 = require("../../../core/cache/services/cache.service");
|
|
24
|
+
const email_service_1 = require("../../../core/email/services/email.service");
|
|
25
|
+
const jsonapi_service_1 = require("../../../core/jsonapi/services/jsonapi.service");
|
|
26
|
+
const logging_service_1 = require("../../../core/logging/services/logging.service");
|
|
27
|
+
const abstract_service_1 = require("../../../core/neo4j/abstracts/abstract.service");
|
|
28
|
+
const email_automation_enrollment_repository_1 = require("../../email-automation/repositories/email-automation-enrollment.repository");
|
|
29
|
+
const email_opt_out_repository_1 = require("../../email-automation/repositories/email-opt-out.repository");
|
|
30
|
+
const response_language_service_1 = require("../../user/services/response-language.service");
|
|
31
|
+
const email_blast_constants_1 = require("../email-blast.constants");
|
|
32
|
+
const email_blast_delivery_1 = require("../entities/email-blast-delivery");
|
|
33
|
+
const email_blast_meta_1 = require("../entities/email-blast.meta");
|
|
34
|
+
const email_blast_delivery_repository_1 = require("../repositories/email-blast-delivery.repository");
|
|
35
|
+
const email_blast_repository_1 = require("../repositories/email-blast.repository");
|
|
36
|
+
const email_blast_renderer_1 = require("../utils/email-blast.renderer");
|
|
37
|
+
const MINUTE_MS = 60 * 1000;
|
|
38
|
+
/**
|
|
39
|
+
* The whole delivery lifecycle of a blast: the worker send run, the recovery of stuck
|
|
40
|
+
* deliveries and the public unsubscribe.
|
|
41
|
+
*
|
|
42
|
+
* Never twice beats never missing anyone: a delivery is claimed (`pending` → `sending`)
|
|
43
|
+
* before the provider call; a send error marks it `failed` and it is never retried; a
|
|
44
|
+
* delivery left in `sending` by a dead worker is failed by `recoverStuck`, never resent.
|
|
45
|
+
*
|
|
46
|
+
* The worker has no route for `@CacheInvalidate`, so the send run and the recovery
|
|
47
|
+
* invalidate the `email-blasts` cache by hand (owner decision D-7).
|
|
48
|
+
*/
|
|
49
|
+
let EmailBlastDeliveryService = class EmailBlastDeliveryService extends abstract_service_1.AbstractService {
|
|
50
|
+
constructor(jsonApiService, deliveryRepository, clsService, blastRepository, optOutRepository, enrollmentRepository, emailService, responseLanguage, configService, cacheService, queue, logger) {
|
|
51
|
+
super(jsonApiService, deliveryRepository, clsService, email_blast_delivery_1.EmailBlastDeliveryDescriptor.model);
|
|
52
|
+
this.deliveryRepository = deliveryRepository;
|
|
53
|
+
this.blastRepository = blastRepository;
|
|
54
|
+
this.optOutRepository = optOutRepository;
|
|
55
|
+
this.enrollmentRepository = enrollmentRepository;
|
|
56
|
+
this.emailService = emailService;
|
|
57
|
+
this.responseLanguage = responseLanguage;
|
|
58
|
+
this.configService = configService;
|
|
59
|
+
this.cacheService = cacheService;
|
|
60
|
+
this.queue = queue;
|
|
61
|
+
this.logger = logger;
|
|
62
|
+
this.descriptor = email_blast_delivery_1.EmailBlastDeliveryDescriptor;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Snapshots the recipients (once per blast) and sends every pending delivery in batches.
|
|
66
|
+
* Safe to run again after a crash: claimed deliveries are never claimed twice.
|
|
67
|
+
*/
|
|
68
|
+
async processBlast(params) {
|
|
69
|
+
const counts = { sent: 0, skipped: 0, failed: 0 };
|
|
70
|
+
const blast = await this.blastRepository.findById({ id: params.blastId });
|
|
71
|
+
if (!blast || blast.status !== "sending")
|
|
72
|
+
return counts;
|
|
73
|
+
await this.deliveryRepository.createSnapshot({ blastId: params.blastId });
|
|
74
|
+
await this.invalidateCache();
|
|
75
|
+
const appUrl = this.configService.get("app").url;
|
|
76
|
+
const apiUrl = this.configService.get("api").url;
|
|
77
|
+
for (;;) {
|
|
78
|
+
const batch = await this.deliveryRepository.claimBatch({
|
|
79
|
+
blastId: params.blastId,
|
|
80
|
+
limit: email_blast_constants_1.EMAIL_BLAST_BATCH_SIZE,
|
|
81
|
+
claimedAt: new Date(),
|
|
82
|
+
});
|
|
83
|
+
if (batch.length === 0)
|
|
84
|
+
break;
|
|
85
|
+
for (const delivery of batch) {
|
|
86
|
+
try {
|
|
87
|
+
const outcome = await this.deliverOne({ blast, delivery, appUrl, apiUrl });
|
|
88
|
+
counts[outcome]++;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
// A database error: the delivery stays in `sending` and recoverStuck fails it later.
|
|
92
|
+
counts.failed++;
|
|
93
|
+
this.logger.error(`Failed to process email blast delivery ${delivery.id}: ${error.message}`, "EmailBlastDeliveryService");
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
await this.invalidateCache();
|
|
97
|
+
}
|
|
98
|
+
await this.blastRepository.markSentIfDone({ id: params.blastId });
|
|
99
|
+
await this.invalidateCache();
|
|
100
|
+
return counts;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Fails every delivery claimed more than EMAIL_BLAST_STUCK_MINUTES ago (never resent),
|
|
104
|
+
* then queues the send job again for every blast still `sending`, so a crashed run ends.
|
|
105
|
+
*/
|
|
106
|
+
async recoverStuck(params) {
|
|
107
|
+
await this.deliveryRepository.failStuck({
|
|
108
|
+
claimedBefore: new Date(params.now.getTime() - email_blast_constants_1.EMAIL_BLAST_STUCK_MINUTES * MINUTE_MS),
|
|
109
|
+
});
|
|
110
|
+
const sending = await this.blastRepository.findSending();
|
|
111
|
+
for (const blast of sending) {
|
|
112
|
+
const jobId = (0, email_blast_constants_1.emailBlastJobId)(blast.id);
|
|
113
|
+
try {
|
|
114
|
+
const existing = await this.queue.getJob(jobId);
|
|
115
|
+
if (existing && (await existing.isFailed()))
|
|
116
|
+
await existing.remove();
|
|
117
|
+
const data = { blastId: blast.id };
|
|
118
|
+
await this.queue.add(email_blast_constants_1.EMAIL_BLAST_JOB_NAMES.sendBlast, data, { ...email_blast_constants_1.EMAIL_BLAST_JOB_OPTIONS, jobId });
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
this.logger.error(`Failed to queue email blast ${blast.id}: ${error.message}`, "EmailBlastDeliveryService");
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
await this.invalidateCache();
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Stops every marketing email to the delivery's address: counts the unsubscribe on the
|
|
128
|
+
* blast once, finishes the address's active automation enrolments and writes the shared
|
|
129
|
+
* opt-out. Idempotent. Answers nothing, so a token holder never learns the email or user.
|
|
130
|
+
*/
|
|
131
|
+
async unsubscribe(params) {
|
|
132
|
+
const delivery = await this.deliveryRepository.findByUnsubscribeToken({ token: params.token });
|
|
133
|
+
if (!delivery)
|
|
134
|
+
throw new common_1.NotFoundException("Invalid unsubscribe token");
|
|
135
|
+
const now = new Date();
|
|
136
|
+
await this.deliveryRepository.markUnsubscribed({ id: delivery.id, unsubscribedAt: now });
|
|
137
|
+
const activeEnrollments = await this.enrollmentRepository.findActiveByEmail({ email: delivery.email });
|
|
138
|
+
for (const enrollment of activeEnrollments) {
|
|
139
|
+
await this.enrollmentRepository.finish({ enrollmentId: enrollment.id, status: "unsubscribed", finishedAt: now });
|
|
140
|
+
}
|
|
141
|
+
await this.optOutRepository.createOptOut({
|
|
142
|
+
id: (0, crypto_1.randomUUID)(),
|
|
143
|
+
email: delivery.email,
|
|
144
|
+
optedOutAt: now,
|
|
145
|
+
source: params.source,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
async deliverOne(params) {
|
|
149
|
+
const { blast, delivery, appUrl, apiUrl } = params;
|
|
150
|
+
// The address may have opted out after the snapshot.
|
|
151
|
+
const optOut = await this.optOutRepository.findByEmail({ email: delivery.email });
|
|
152
|
+
if (optOut) {
|
|
153
|
+
await this.deliveryRepository.markSkipped({ id: delivery.id });
|
|
154
|
+
return "skipped";
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
const locale = (await this.responseLanguage.resolveForEmail({ email: delivery.email })) ?? "en";
|
|
158
|
+
const rendered = await (0, email_blast_renderer_1.renderEmailBlast)({
|
|
159
|
+
blast,
|
|
160
|
+
recipient: { email: delivery.email, name: delivery.name },
|
|
161
|
+
unsubscribeToken: delivery.unsubscribeToken,
|
|
162
|
+
locale,
|
|
163
|
+
appUrl,
|
|
164
|
+
apiUrl,
|
|
165
|
+
});
|
|
166
|
+
await this.emailService.sendEmail("emailBlast", {
|
|
167
|
+
to: delivery.email,
|
|
168
|
+
subject: rendered.subject,
|
|
169
|
+
content: rendered.content,
|
|
170
|
+
replyTo: rendered.replyTo,
|
|
171
|
+
headers: rendered.headers,
|
|
172
|
+
unsubscribeAllUrl: rendered.unsubscribeAllUrl,
|
|
173
|
+
}, locale);
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
const message = error.message;
|
|
177
|
+
this.logger.error(`Failed to send email blast ${blast.id} delivery ${delivery.id}: ${message}`, "EmailBlastDeliveryService");
|
|
178
|
+
await this.deliveryRepository.markFailed({ id: delivery.id, error: message });
|
|
179
|
+
return "failed";
|
|
180
|
+
}
|
|
181
|
+
// Outside the send try: a database error here must never count a delivered email as failed.
|
|
182
|
+
await this.deliveryRepository.markSent({ id: delivery.id, sentAt: new Date() });
|
|
183
|
+
return "sent";
|
|
184
|
+
}
|
|
185
|
+
async invalidateCache() {
|
|
186
|
+
await this.cacheService.invalidateByType(email_blast_meta_1.emailBlastMeta.endpoint);
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
exports.EmailBlastDeliveryService = EmailBlastDeliveryService;
|
|
190
|
+
exports.EmailBlastDeliveryService = EmailBlastDeliveryService = __decorate([
|
|
191
|
+
(0, common_1.Injectable)(),
|
|
192
|
+
__param(10, (0, bullmq_1.InjectQueue)(queue_id_1.QueueId.EMAIL_BLAST)),
|
|
193
|
+
__metadata("design:paramtypes", [jsonapi_service_1.JsonApiService,
|
|
194
|
+
email_blast_delivery_repository_1.EmailBlastDeliveryRepository,
|
|
195
|
+
nestjs_cls_1.ClsService,
|
|
196
|
+
email_blast_repository_1.EmailBlastRepository,
|
|
197
|
+
email_opt_out_repository_1.EmailOptOutRepository,
|
|
198
|
+
email_automation_enrollment_repository_1.EmailAutomationEnrollmentRepository,
|
|
199
|
+
email_service_1.EmailService,
|
|
200
|
+
response_language_service_1.ResponseLanguageService,
|
|
201
|
+
config_1.ConfigService,
|
|
202
|
+
cache_service_1.CacheService,
|
|
203
|
+
bullmq_2.Queue,
|
|
204
|
+
logging_service_1.AppLoggingService])
|
|
205
|
+
], EmailBlastDeliveryService);
|
|
206
|
+
//# sourceMappingURL=email-blast-delivery.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-blast-delivery.service.js","sourceRoot":"","sources":["../../../../src/foundations/email-blast/services/email-blast-delivery.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ConfigService } from "@nestjs/config";
|
|
2
|
+
import { Queue } from "bullmq";
|
|
3
|
+
import { ClsService } from "nestjs-cls";
|
|
4
|
+
import { BaseConfigInterface } from "../../../config/interfaces";
|
|
5
|
+
import { EmailService } from "../../../core/email/services/email.service";
|
|
6
|
+
import { JsonApiSingleDocument } from "../../../core/jsonapi/interfaces/jsonapi.document.interface";
|
|
7
|
+
import { JsonApiService } from "../../../core/jsonapi/services/jsonapi.service";
|
|
8
|
+
import { AbstractService, JsonApiDTOData } from "../../../core/neo4j/abstracts/abstract.service";
|
|
9
|
+
import { UserRepository } from "../../user/repositories/user.repository";
|
|
10
|
+
import { ResponseLanguageService } from "../../user/services/response-language.service";
|
|
11
|
+
import { EmailBlast, EmailBlastDescriptor } from "../entities/email-blast";
|
|
12
|
+
import { EmailBlastAdminRepository } from "../repositories/email-blast.admin.repository";
|
|
13
|
+
import { EmailBlastRepository } from "../repositories/email-blast.repository";
|
|
14
|
+
/**
|
|
15
|
+
* Administrator operations on a blast: CRUD (inherited), the recipient count, the test send
|
|
16
|
+
* and Send. Only a `draft` can be changed, deleted, test-sent or sent.
|
|
17
|
+
*/
|
|
18
|
+
export declare class EmailBlastService extends AbstractService<EmailBlast, typeof EmailBlastDescriptor.relationships> {
|
|
19
|
+
private readonly emailBlastRepository;
|
|
20
|
+
private readonly adminRepository;
|
|
21
|
+
private readonly userRepository;
|
|
22
|
+
private readonly responseLanguage;
|
|
23
|
+
private readonly emailService;
|
|
24
|
+
private readonly configService;
|
|
25
|
+
private readonly queue;
|
|
26
|
+
protected readonly descriptor: import("../../..").EntityDescriptor<EmailBlast, {}>;
|
|
27
|
+
constructor(jsonApiService: JsonApiService, emailBlastRepository: EmailBlastRepository, clsService: ClsService, adminRepository: EmailBlastAdminRepository, userRepository: UserRepository, responseLanguage: ResponseLanguageService, emailService: EmailService, configService: ConfigService<BaseConfigInterface>, queue: Queue);
|
|
28
|
+
patchFromDTO(params: {
|
|
29
|
+
data: JsonApiDTOData;
|
|
30
|
+
}): Promise<JsonApiSingleDocument>;
|
|
31
|
+
delete(params: {
|
|
32
|
+
id: string;
|
|
33
|
+
}): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* How many people the blast would reach now, as a synthetic `email-blast-audiences` resource.
|
|
36
|
+
*/
|
|
37
|
+
findAudience(params: {
|
|
38
|
+
id: string;
|
|
39
|
+
}): Promise<JsonApiSingleDocument>;
|
|
40
|
+
/**
|
|
41
|
+
* Sends the draft to the calling administrator only: subject prefixed `[TEST] `, an
|
|
42
|
+
* unsubscribe token that matches nothing, and no delivery created.
|
|
43
|
+
*/
|
|
44
|
+
sendTest(params: {
|
|
45
|
+
id: string;
|
|
46
|
+
}): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Moves the draft to `sending` and queues the worker job that snapshots the recipients
|
|
49
|
+
* and sends. `markSending` only matches a draft, so a second press (or a second
|
|
50
|
+
* administrator) gets a 400 and never queues a second run.
|
|
51
|
+
*/
|
|
52
|
+
send(params: {
|
|
53
|
+
id: string;
|
|
54
|
+
}): Promise<JsonApiSingleDocument>;
|
|
55
|
+
private loadDraft;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=email-blast.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-blast.service.d.ts","sourceRoot":"","sources":["../../../../src/foundations/email-blast/services/email-blast.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAA0C,MAAM,4BAA4B,CAAC;AAEzG,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,6DAA6D,CAAC;AACpG,OAAO,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AACjG,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AASxF,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE3E,OAAO,EAAE,yBAAyB,EAAE,MAAM,8CAA8C,CAAC;AACzF,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAG9E;;;GAGG;AACH,qBACa,iBAAkB,SAAQ,eAAe,CAAC,UAAU,EAAE,OAAO,oBAAoB,CAAC,aAAa,CAAC;IAKzG,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IAErC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,aAAa;IACI,OAAO,CAAC,QAAQ,CAAC,KAAK;IAX1D,SAAS,CAAC,QAAQ,CAAC,UAAU,sDAAwB;gBAGnD,cAAc,EAAE,cAAc,EACb,oBAAoB,EAAE,oBAAoB,EAC3D,UAAU,EAAE,UAAU,EACL,eAAe,EAAE,yBAAyB,EAC1C,cAAc,EAAE,cAAc,EAC9B,gBAAgB,EAAE,uBAAuB,EACzC,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,CAAC,mBAAmB,CAAC,EACf,KAAK,EAAE,KAAK;IAK3D,YAAY,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,cAAc,CAAA;KAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAK9E,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAO1E;;;OAGG;IACG,QAAQ,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCrD;;;;OAIG;IACG,IAAI,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC;YAgBpD,SAAS;CAMxB"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.EmailBlastService = void 0;
|
|
16
|
+
const bullmq_1 = require("@nestjs/bullmq");
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const config_1 = require("@nestjs/config");
|
|
19
|
+
const bullmq_2 = require("bullmq");
|
|
20
|
+
const nestjs_cls_1 = require("nestjs-cls");
|
|
21
|
+
const queue_id_1 = require("../../../config/enums/queue.id");
|
|
22
|
+
const email_service_1 = require("../../../core/email/services/email.service");
|
|
23
|
+
const jsonapi_service_1 = require("../../../core/jsonapi/services/jsonapi.service");
|
|
24
|
+
const abstract_service_1 = require("../../../core/neo4j/abstracts/abstract.service");
|
|
25
|
+
const user_repository_1 = require("../../user/repositories/user.repository");
|
|
26
|
+
const response_language_service_1 = require("../../user/services/response-language.service");
|
|
27
|
+
const email_blast_constants_1 = require("../email-blast.constants");
|
|
28
|
+
const email_blast_1 = require("../entities/email-blast");
|
|
29
|
+
const email_blast_audience_1 = require("../entities/email-blast-audience");
|
|
30
|
+
const email_blast_admin_repository_1 = require("../repositories/email-blast.admin.repository");
|
|
31
|
+
const email_blast_repository_1 = require("../repositories/email-blast.repository");
|
|
32
|
+
const email_blast_renderer_1 = require("../utils/email-blast.renderer");
|
|
33
|
+
/**
|
|
34
|
+
* Administrator operations on a blast: CRUD (inherited), the recipient count, the test send
|
|
35
|
+
* and Send. Only a `draft` can be changed, deleted, test-sent or sent.
|
|
36
|
+
*/
|
|
37
|
+
let EmailBlastService = class EmailBlastService extends abstract_service_1.AbstractService {
|
|
38
|
+
constructor(jsonApiService, emailBlastRepository, clsService, adminRepository, userRepository, responseLanguage, emailService, configService, queue) {
|
|
39
|
+
super(jsonApiService, emailBlastRepository, clsService, email_blast_1.EmailBlastDescriptor.model);
|
|
40
|
+
this.emailBlastRepository = emailBlastRepository;
|
|
41
|
+
this.adminRepository = adminRepository;
|
|
42
|
+
this.userRepository = userRepository;
|
|
43
|
+
this.responseLanguage = responseLanguage;
|
|
44
|
+
this.emailService = emailService;
|
|
45
|
+
this.configService = configService;
|
|
46
|
+
this.queue = queue;
|
|
47
|
+
this.descriptor = email_blast_1.EmailBlastDescriptor;
|
|
48
|
+
}
|
|
49
|
+
async patchFromDTO(params) {
|
|
50
|
+
await this.loadDraft({ id: params.data.id });
|
|
51
|
+
return super.patchFromDTO(params);
|
|
52
|
+
}
|
|
53
|
+
async delete(params) {
|
|
54
|
+
await this.loadDraft({ id: params.id });
|
|
55
|
+
return super.delete(params);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* How many people the blast would reach now, as a synthetic `email-blast-audiences` resource.
|
|
59
|
+
*/
|
|
60
|
+
async findAudience(params) {
|
|
61
|
+
return this.jsonApiService.buildSingle(email_blast_audience_1.EmailBlastAudienceDescriptor.model, await this.adminRepository.countEligibleRecipients({ blastId: params.id }));
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Sends the draft to the calling administrator only: subject prefixed `[TEST] `, an
|
|
65
|
+
* unsubscribe token that matches nothing, and no delivery created.
|
|
66
|
+
*/
|
|
67
|
+
async sendTest(params) {
|
|
68
|
+
const blast = await this.loadDraft({ id: params.id });
|
|
69
|
+
// A platform administrator belongs to no company, so the company-scoped findByUserId
|
|
70
|
+
// finds nothing; the route is administrator-only, so the unscoped admin read is safe.
|
|
71
|
+
const user = await this.userRepository.findOneForAdmin({ userId: this.clsService.get("userId") });
|
|
72
|
+
if (!user?.email)
|
|
73
|
+
throw new common_1.NotFoundException("User not found");
|
|
74
|
+
const locale = (await this.responseLanguage.resolveForEmail({ email: user.email })) ?? "en";
|
|
75
|
+
const rendered = await (0, email_blast_renderer_1.renderEmailBlast)({
|
|
76
|
+
blast,
|
|
77
|
+
recipient: { email: user.email, name: user.name },
|
|
78
|
+
unsubscribeToken: email_blast_constants_1.EMAIL_BLAST_TEST_TOKEN,
|
|
79
|
+
locale,
|
|
80
|
+
appUrl: this.configService.get("app").url,
|
|
81
|
+
apiUrl: this.configService.get("api").url,
|
|
82
|
+
});
|
|
83
|
+
await this.emailService.sendEmail("emailBlast", {
|
|
84
|
+
to: user.email,
|
|
85
|
+
subject: `${email_blast_constants_1.EMAIL_BLAST_TEST_SUBJECT_PREFIX}${rendered.subject}`,
|
|
86
|
+
content: rendered.content,
|
|
87
|
+
replyTo: rendered.replyTo,
|
|
88
|
+
headers: rendered.headers,
|
|
89
|
+
unsubscribeAllUrl: rendered.unsubscribeAllUrl,
|
|
90
|
+
}, locale);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Moves the draft to `sending` and queues the worker job that snapshots the recipients
|
|
94
|
+
* and sends. `markSending` only matches a draft, so a second press (or a second
|
|
95
|
+
* administrator) gets a 400 and never queues a second run.
|
|
96
|
+
*/
|
|
97
|
+
async send(params) {
|
|
98
|
+
const audience = await this.adminRepository.countEligibleRecipients({ blastId: params.id });
|
|
99
|
+
if (audience.recipientCount === 0)
|
|
100
|
+
throw new common_1.BadRequestException("Nobody can receive this blast");
|
|
101
|
+
const blast = await this.emailBlastRepository.markSending({ id: params.id, sentAt: new Date() });
|
|
102
|
+
if (!blast)
|
|
103
|
+
throw new common_1.BadRequestException("This blast has already been sent");
|
|
104
|
+
const data = { blastId: params.id };
|
|
105
|
+
await this.queue.add(email_blast_constants_1.EMAIL_BLAST_JOB_NAMES.sendBlast, data, {
|
|
106
|
+
...email_blast_constants_1.EMAIL_BLAST_JOB_OPTIONS,
|
|
107
|
+
jobId: (0, email_blast_constants_1.emailBlastJobId)(params.id),
|
|
108
|
+
});
|
|
109
|
+
return this.jsonApiService.buildSingle(email_blast_1.EmailBlastDescriptor.model, blast);
|
|
110
|
+
}
|
|
111
|
+
async loadDraft(params) {
|
|
112
|
+
const blast = await this.emailBlastRepository.findById({ id: params.id });
|
|
113
|
+
if (!blast)
|
|
114
|
+
throw new common_1.NotFoundException();
|
|
115
|
+
if (blast.status !== "draft")
|
|
116
|
+
throw new common_1.BadRequestException("Only a draft blast can be changed");
|
|
117
|
+
return blast;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
exports.EmailBlastService = EmailBlastService;
|
|
121
|
+
exports.EmailBlastService = EmailBlastService = __decorate([
|
|
122
|
+
(0, common_1.Injectable)(),
|
|
123
|
+
__param(8, (0, bullmq_1.InjectQueue)(queue_id_1.QueueId.EMAIL_BLAST)),
|
|
124
|
+
__metadata("design:paramtypes", [jsonapi_service_1.JsonApiService,
|
|
125
|
+
email_blast_repository_1.EmailBlastRepository,
|
|
126
|
+
nestjs_cls_1.ClsService,
|
|
127
|
+
email_blast_admin_repository_1.EmailBlastAdminRepository,
|
|
128
|
+
user_repository_1.UserRepository,
|
|
129
|
+
response_language_service_1.ResponseLanguageService,
|
|
130
|
+
email_service_1.EmailService,
|
|
131
|
+
config_1.ConfigService,
|
|
132
|
+
bullmq_2.Queue])
|
|
133
|
+
], EmailBlastService);
|
|
134
|
+
//# sourceMappingURL=email-blast.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-blast.service.js","sourceRoot":"","sources":["../../../../src/foundations/email-blast/services/email-blast.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA6C;AAC7C,2CAAoF;AACpF,2CAA+C;AAC/C,mCAA+B;AAC/B,2CAAwC;AAExC,6DAAyD;AACzD,8EAA0E;AAE1E,oFAAgF;AAChF,qFAAiG;AACjG,6EAAyE;AACzE,6FAAwF;AACxF,oEAOkC;AAClC,yDAA2E;AAC3E,2EAAgF;AAChF,+FAAyF;AACzF,mFAA8E;AAC9E,wEAAiE;AAEjE;;;GAGG;AAEI,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,kCAAsE;IAG3G,YACE,cAA8B,EACb,oBAA0C,EAC3D,UAAsB,EACL,eAA0C,EAC1C,cAA8B,EAC9B,gBAAyC,EACzC,YAA0B,EAC1B,aAAiD,EAChC,KAA6B;QAE/D,KAAK,CAAC,cAAc,EAAE,oBAAoB,EAAE,UAAU,EAAE,kCAAoB,CAAC,KAAK,CAAC,CAAC;QATnE,yBAAoB,GAApB,oBAAoB,CAAsB;QAE1C,oBAAe,GAAf,eAAe,CAA2B;QAC1C,mBAAc,GAAd,cAAc,CAAgB;QAC9B,qBAAgB,GAAhB,gBAAgB,CAAyB;QACzC,iBAAY,GAAZ,YAAY,CAAc;QAC1B,kBAAa,GAAb,aAAa,CAAoC;QACf,UAAK,GAAL,KAAK,CAAO;QAX9C,eAAU,GAAG,kCAAoB,CAAC;IAcrD,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAAgC;QACjD,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7C,OAAO,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAsB;QACjC,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,MAAsB;QACvC,OAAO,IAAI,CAAC,cAAc,CAAC,WAAW,CACpC,mDAA4B,CAAC,KAAK,EAClC,MAAM,IAAI,CAAC,eAAe,CAAC,uBAAuB,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAC3E,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,QAAQ,CAAC,MAAsB;QACnC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QAEtD,qFAAqF;QACrF,sFAAsF;QACtF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAClG,IAAI,CAAC,IAAI,EAAE,KAAK;YAAE,MAAM,IAAI,0BAAiB,CAAC,gBAAgB,CAAC,CAAC;QAEhE,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC;QAC5F,MAAM,QAAQ,GAAG,MAAM,IAAA,uCAAgB,EAAC;YACtC,KAAK;YACL,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;YACjD,gBAAgB,EAAE,8CAAsB;YACxC,MAAM;YACN,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAqB,KAAK,CAAC,CAAC,GAAG;YAC7D,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAqB,KAAK,CAAC,CAAC,GAAG;SAC9D,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,YAAY,CAAC,SAAS,CAC/B,YAAY,EACZ;YACE,EAAE,EAAE,IAAI,CAAC,KAAK;YACd,OAAO,EAAE,GAAG,uDAA+B,GAAG,QAAQ,CAAC,OAAO,EAAE;YAChE,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;SAC9C,EACD,MAAM,CACP,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAI,CAAC,MAAsB;QAC/B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,uBAAuB,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5F,IAAI,QAAQ,CAAC,cAAc,KAAK,CAAC;YAAE,MAAM,IAAI,4BAAmB,CAAC,+BAA+B,CAAC,CAAC;QAElG,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QACjG,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,4BAAmB,CAAC,kCAAkC,CAAC,CAAC;QAE9E,MAAM,IAAI,GAAsB,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;QACvD,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,6CAAqB,CAAC,SAAS,EAAE,IAAI,EAAE;YAC1D,GAAG,+CAAuB;YAC1B,KAAK,EAAE,IAAA,uCAAe,EAAC,MAAM,CAAC,EAAE,CAAC;SAClC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,kCAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC5E,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,MAAsB;QAC5C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1E,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,0BAAiB,EAAE,CAAC;QAC1C,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO;YAAE,MAAM,IAAI,4BAAmB,CAAC,mCAAmC,CAAC,CAAC;QACjG,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAA;AApGY,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,mBAAU,GAAE;IAaR,WAAA,IAAA,oBAAW,EAAC,kBAAO,CAAC,WAAW,CAAC,CAAA;qCARjB,gCAAc;QACS,6CAAoB;QAC/C,uBAAU;QACY,wDAAyB;QAC1B,gCAAc;QACZ,mDAAuB;QAC3B,4BAAY;QACX,sBAAa;QACa,cAAK;GAZtD,iBAAiB,CAoG7B"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { EmailBlast } from "../entities/email-blast";
|
|
2
|
+
export type EmailBlastRendered = {
|
|
3
|
+
subject: string;
|
|
4
|
+
content: string;
|
|
5
|
+
headers: Record<string, string>;
|
|
6
|
+
replyTo?: string;
|
|
7
|
+
unsubscribeAllUrl: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Renders a blast for one recipient: the subject and the HTML body fragment (`content`)
|
|
11
|
+
* that the `emailBlast` template wraps with the app's header, the unsubscribe link and
|
|
12
|
+
* the footer.
|
|
13
|
+
*
|
|
14
|
+
* Variables: `{{name}}`, `{{email}}`, `{{url}}`, `{{unsubscribeAllUrl}}`.
|
|
15
|
+
* `name` and `email` are HTML-escaped; the two URLs are built from config and a UUID
|
|
16
|
+
* token, so they are passed unescaped. The caller reads `appUrl` / `apiUrl` from config.
|
|
17
|
+
*/
|
|
18
|
+
export declare function renderEmailBlast(params: {
|
|
19
|
+
blast: EmailBlast;
|
|
20
|
+
recipient: {
|
|
21
|
+
email: string;
|
|
22
|
+
name?: string;
|
|
23
|
+
};
|
|
24
|
+
unsubscribeToken: string;
|
|
25
|
+
locale: string;
|
|
26
|
+
appUrl: string;
|
|
27
|
+
apiUrl: string;
|
|
28
|
+
}): Promise<EmailBlastRendered>;
|
|
29
|
+
//# sourceMappingURL=email-blast.renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-blast.renderer.d.ts","sourceRoot":"","sources":["../../../../src/foundations/email-blast/utils/email-blast.renderer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAGrD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAwB9B"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.renderEmailBlast = renderEmailBlast;
|
|
37
|
+
const Handlebars = __importStar(require("handlebars"));
|
|
38
|
+
const email_markdown_renderer_1 = require("../../email-automation/utils/email-markdown.renderer");
|
|
39
|
+
const email_blast_meta_1 = require("../entities/email-blast.meta");
|
|
40
|
+
/**
|
|
41
|
+
* Renders a blast for one recipient: the subject and the HTML body fragment (`content`)
|
|
42
|
+
* that the `emailBlast` template wraps with the app's header, the unsubscribe link and
|
|
43
|
+
* the footer.
|
|
44
|
+
*
|
|
45
|
+
* Variables: `{{name}}`, `{{email}}`, `{{url}}`, `{{unsubscribeAllUrl}}`.
|
|
46
|
+
* `name` and `email` are HTML-escaped; the two URLs are built from config and a UUID
|
|
47
|
+
* token, so they are passed unescaped. The caller reads `appUrl` / `apiUrl` from config.
|
|
48
|
+
*/
|
|
49
|
+
async function renderEmailBlast(params) {
|
|
50
|
+
const { blast, recipient, unsubscribeToken, locale, appUrl, apiUrl } = params;
|
|
51
|
+
const unsubscribeAllUrl = `${appUrl}${locale}/unsubscribe/blast/${unsubscribeToken}`;
|
|
52
|
+
const vars = {
|
|
53
|
+
name: recipient.name ?? recipient.email.split("@")[0],
|
|
54
|
+
email: recipient.email,
|
|
55
|
+
url: new Handlebars.SafeString(appUrl),
|
|
56
|
+
unsubscribeAllUrl: new Handlebars.SafeString(unsubscribeAllUrl),
|
|
57
|
+
};
|
|
58
|
+
const { subject, content } = await (0, email_markdown_renderer_1.renderMarkdownEmail)({ subject: blast.subject, body: blast.body, vars });
|
|
59
|
+
return {
|
|
60
|
+
subject,
|
|
61
|
+
content,
|
|
62
|
+
headers: {
|
|
63
|
+
"List-Unsubscribe": `<${apiUrl}${email_blast_meta_1.emailBlastMeta.endpoint}/${email_blast_meta_1.EMAIL_BLAST_UNSUBSCRIBE_SEGMENT}/${unsubscribeToken}>`,
|
|
64
|
+
"List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
|
|
65
|
+
},
|
|
66
|
+
...(blast.replyTo ? { replyTo: blast.replyTo } : {}),
|
|
67
|
+
unsubscribeAllUrl,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=email-blast.renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-blast.renderer.js","sourceRoot":"","sources":["../../../../src/foundations/email-blast/utils/email-blast.renderer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,4CA+BC;AArDD,uDAAyC;AACzC,kGAA2F;AAE3F,mEAA+F;AAU/F;;;;;;;;GAQG;AACI,KAAK,UAAU,gBAAgB,CAAC,MAOtC;IACC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAE9E,MAAM,iBAAiB,GAAG,GAAG,MAAM,GAAG,MAAM,sBAAsB,gBAAgB,EAAE,CAAC;IAErF,MAAM,IAAI,GAAG;QACX,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACrD,KAAK,EAAE,SAAS,CAAC,KAAK;QACtB,GAAG,EAAE,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC;QACtC,iBAAiB,EAAE,IAAI,UAAU,CAAC,UAAU,CAAC,iBAAiB,CAAC;KAChE,CAAC;IAEF,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,IAAA,6CAAmB,EAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3G,OAAO;QACL,OAAO;QACP,OAAO;QACP,OAAO,EAAE;YACP,kBAAkB,EAAE,IAAI,MAAM,GAAG,iCAAc,CAAC,QAAQ,IAAI,kDAA+B,IAAI,gBAAgB,GAAG;YAClH,uBAAuB,EAAE,4BAA4B;SACtD;QACD,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,iBAAiB;KAClB,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"foundations.modules.d.ts","sourceRoot":"","sources":["../../src/foundations/foundations.modules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,4CAA4C,CAAC;AAGzF,OAAO,EAAE,qBAAqB,EAAE,MAAM,mDAAmD,CAAC;AAM1F,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AAEpF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAK3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,kDAAkD,CAAC;AAE1F,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAC;AAGvF,OAAO,EAAE,2BAA2B,EAAE,MAAM,iEAAiE,CAAC;
|
|
1
|
+
{"version":3,"file":"foundations.modules.d.ts","sourceRoot":"","sources":["../../src/foundations/foundations.modules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,4CAA4C,CAAC;AAGzF,OAAO,EAAE,qBAAqB,EAAE,MAAM,mDAAmD,CAAC;AAM1F,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AAEpF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAK3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,kDAAkD,CAAC;AAE1F,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAC;AAGvF,OAAO,EAAE,2BAA2B,EAAE,MAAM,iEAAiE,CAAC;AAI9G,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAC;AAEvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AA0BhF,OAAO,EAAE,wBAAwB,EAAE,MAAM,2DAA2D,CAAC;AAGrG;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,kEAAkE;IAClE,YAAY,CAAC,EAAE,wBAAwB,CAAC;IACxC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,kFAAkF;IAClF,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB;;;;OAIG;IACH,eAAe,CAAC,EAAE,2BAA2B,CAAC;IAC9C,qGAAqG;IACrG,eAAe,CAAC,EAAE,2BAA2B,CAAC;IAC9C,4GAA4G;IAC5G,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,oGAAoG;IACpG,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;CACvB;AA4DD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBACa,iBAAiB;IAC5B;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,uBAAuB,GAAG,aAAa;CAmChE"}
|
|
@@ -25,6 +25,7 @@ const content_module_1 = require("./content/content.module");
|
|
|
25
25
|
const referral_module_1 = require("./referral/referral.module");
|
|
26
26
|
const discord_user_module_1 = require("./discord-user/discord-user.module");
|
|
27
27
|
const email_automation_module_1 = require("./email-automation/email-automation.module");
|
|
28
|
+
const email_blast_module_1 = require("./email-blast/email-blast.module");
|
|
28
29
|
const feature_module_1 = require("./feature/feature.module");
|
|
29
30
|
const handbook_module_1 = require("./handbook/handbook.module");
|
|
30
31
|
const how_to_module_1 = require("./how-to/how-to.module");
|
|
@@ -57,6 +58,7 @@ const waitlist_module_1 = require("./waitlist/waitlist.module");
|
|
|
57
58
|
/**
|
|
58
59
|
* All static foundation modules. The dynamic ones (ContentModule,
|
|
59
60
|
* UserActivityModule, ReferralModule, HandbookModule, HowToModule, BlogModule (opt-in), EmailAutomationModule,
|
|
61
|
+
* EmailBlastModule,
|
|
60
62
|
* AnalyticsModule, BillingModule) are
|
|
61
63
|
* assembled inside forRoot().
|
|
62
64
|
*
|
|
@@ -161,6 +163,7 @@ let FoundationsModule = FoundationsModule_1 = class FoundationsModule {
|
|
|
161
163
|
classRef: email_automation_module_1.EmailAutomationModule,
|
|
162
164
|
factory: () => email_automation_module_1.EmailAutomationModule.forRoot(config?.emailAutomation),
|
|
163
165
|
},
|
|
166
|
+
{ classRef: email_blast_module_1.EmailBlastModule, factory: () => email_blast_module_1.EmailBlastModule.forRoot() },
|
|
164
167
|
{ classRef: analytics_module_1.AnalyticsModule, factory: () => analytics_module_1.AnalyticsModule.forRoot(config?.analytics) },
|
|
165
168
|
{ classRef: billing_module_1.BillingModule, factory: () => billing_module_1.BillingModule.forRoot(config?.billing) },
|
|
166
169
|
// Opt-in: mounted only when the app passes a `blog` config.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"foundations.modules.js","sourceRoot":"","sources":["../../src/foundations/foundations.modules.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA6D;AAC7D,wFAAmF;AAEnF,+EAA0E;AAC1E,mEAA+D;AAE/D,mEAA+D;AAC/D,sEAAkE;AAClE,uDAAmD;AACnD,oDAAgD;AAChD,6DAAyD;AAEzD,oDAAgD;AAEhD,uDAAmD;AACnD,6DAAyD;AACzD,6DAAyD;AACzD,6DAAyD;AAEzD,gEAA4D;AAE5D,4EAAuE;AACvE,wFAAmF;AAEnF,6DAAyD;AACzD,gEAA4D;AAE5D,0DAAqD;AAErD,sEAAkE;AAClE,sEAAkE;AAClE,0DAAsD;AACtD,4EAAwE;AACxE,uDAAmD;AACnD,oDAAgD;AAChD,mEAA+D;AAC/D,oDAAgD;AAChD,8CAA0C;AAC1C,qFAAgF;AAChF,kFAA6E;AAC7E,iDAAmD;AACnD,qDAAuD;AACvD,+EAA0E;AAC1E,mEAAoE;AACpE,+DAAiE;AACjE,4EAAuE;AACvE,kFAA6E;AAC7E,0DAAsD;AACtD,4EAAuE;AACvE,sEAAkE;AAClE,sEAAiE;AACjE,8EAAyE;AACzE,oDAAgD;AAChD,+EAA0E;AAE1E,gEAA4D;AA6C5D
|
|
1
|
+
{"version":3,"file":"foundations.modules.js","sourceRoot":"","sources":["../../src/foundations/foundations.modules.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/foundations/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,cAAc,uBAAuB,CAAC;AAGtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/foundations/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,cAAc,uBAAuB,CAAC;AAGtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC"}
|
|
@@ -38,6 +38,7 @@ __exportStar(require("./content"), exports);
|
|
|
38
38
|
__exportStar(require("./discord"), exports);
|
|
39
39
|
__exportStar(require("./discord-user"), exports);
|
|
40
40
|
__exportStar(require("./email-automation"), exports);
|
|
41
|
+
__exportStar(require("./email-blast"), exports);
|
|
41
42
|
__exportStar(require("./feature"), exports);
|
|
42
43
|
__exportStar(require("./google-user"), exports);
|
|
43
44
|
__exportStar(require("./handbook"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/foundations/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,sFAAsF;AACtF,wDAAsC;AAEtC,iFAAiF;AACjF,qDAAmC;AACnC,kDAAgC;AAChC,8CAA4B;AAC5B,qDAAmC;AACnC,sDAAoC;AACpC,+CAA6B;AAC7B,0CAAwB;AACxB,yCAAuB;AACvB,4CAA0B;AAC1B,yCAAuB;AACvB,0CAAwB;AACxB,4CAA0B;AAC1B,4CAA0B;AAC1B,8CAA4B;AAC5B,4CAA0B;AAC1B,4CAA0B;AAC1B,iDAA+B;AAC/B,qDAAmC;AACnC,4CAA0B;AAC1B,gDAA8B;AAC9B,6CAA2B;AAC3B,2CAAyB;AACzB,+CAA6B;AAC7B,+CAA6B;AAC7B,2CAAyB;AACzB,iDAA+B;AAC/B,0CAAwB;AACxB,yCAAuB;AACvB,6CAA2B;AAC3B,8CAA4B;AAC5B,yCAAuB;AACvB,uCAAqB;AACrB,2CAAyB;AACzB,+CAA6B;AAC7B,+CAA6B;AAC7B,yCAAuB;AACvB,kDAAgC;AAChC,8CAA4B;AAC5B,6CAA2B;AAC3B,yCAAuB"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/foundations/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,sFAAsF;AACtF,wDAAsC;AAEtC,iFAAiF;AACjF,qDAAmC;AACnC,kDAAgC;AAChC,8CAA4B;AAC5B,qDAAmC;AACnC,sDAAoC;AACpC,+CAA6B;AAC7B,0CAAwB;AACxB,yCAAuB;AACvB,4CAA0B;AAC1B,yCAAuB;AACvB,0CAAwB;AACxB,4CAA0B;AAC1B,4CAA0B;AAC1B,8CAA4B;AAC5B,4CAA0B;AAC1B,4CAA0B;AAC1B,iDAA+B;AAC/B,qDAAmC;AACnC,gDAA8B;AAC9B,4CAA0B;AAC1B,gDAA8B;AAC9B,6CAA2B;AAC3B,2CAAyB;AACzB,+CAA6B;AAC7B,+CAA6B;AAC7B,2CAAyB;AACzB,iDAA+B;AAC/B,0CAAwB;AACxB,yCAAuB;AACvB,6CAA2B;AAC3B,8CAA4B;AAC5B,yCAAuB;AACvB,uCAAqB;AACrB,2CAAyB;AACzB,+CAA6B;AAC7B,+CAA6B;AAC7B,yCAAuB;AACvB,kDAAgC;AAChC,8CAA4B;AAC5B,6CAA2B;AAC3B,yCAAuB"}
|