@escapenavigator/types 2.0.37 → 2.0.39
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/client/query-client.dto.d.ts +6 -0
- package/dist/email-builder/email-content.dto.d.ts +26 -0
- package/dist/email-builder/email-content.dto.js +62 -0
- package/dist/email-builder/index.d.ts +81 -0
- package/dist/email-builder/index.js +89 -1
- package/dist/emails/index.d.ts +25 -2
- package/dist/openapi/shared/openapi-questroom.ro.d.ts +2 -0
- package/dist/openapi/shared/openapi-questroom.ro.js +14 -5
- package/dist/openapi/upsellings/openapi-upselling.ro.d.ts +1 -0
- package/dist/openapi/upsellings/openapi-upselling.ro.js +4 -0
- package/dist/profile/birthday-marketing/birthday-marketing.dto.d.ts +2 -2
- package/dist/profile/birthday-marketing/birthday-marketing.dto.js +3 -1
- package/dist/profile/cross-sale/cross-sale.dto.d.ts +2 -2
- package/dist/profile/cross-sale/cross-sale.dto.js +3 -1
- package/dist/profile/cross-sale/cross-sale.ro.d.ts +2 -2
- package/dist/profile/custom-client-booking-email/custom-client-booking-email.dto.d.ts +2 -2
- package/dist/profile/custom-client-booking-email/custom-client-booking-email.dto.js +3 -1
- package/dist/profile/custom-client-booking-email/custom-client-booking-email.ro.d.ts +2 -2
- package/dist/profile/marketing-automation/marketing-automation.dto.d.ts +2 -2
- package/dist/profile/marketing-automation/marketing-automation.dto.js +3 -1
- package/dist/profile/marketing-automation/marketing-automation.ro.d.ts +2 -2
- package/dist/profile/marketing-email/create-profile-marketing-email-campaign.dto.d.ts +14 -13
- package/dist/profile/marketing-email/create-profile-marketing-email-campaign.dto.js +19 -28
- package/dist/profile/marketing-email/preflight-issue.ro.d.ts +31 -1
- package/dist/profile/marketing-email/preflight-issue.ro.js +30 -0
- package/dist/profile/marketing-email/preview-campaign-v2.dto.d.ts +2 -2
- package/dist/profile/marketing-email/preview-campaign-v2.dto.js +2 -2
- package/dist/profile/marketing-email/preview-profile-marketing-segment.dto.d.ts +6 -0
- package/dist/profile/marketing-email/preview-profile-marketing-segment.dto.js +8 -0
- package/dist/profile/marketing-email/preview-profile-marketing-segment.ro.d.ts +6 -1
- package/dist/profile/marketing-email/preview-profile-marketing-segment.ro.js +9 -1
- package/dist/profile/marketing-email/profile-marketing-email-campaign.ro.d.ts +11 -2
- package/dist/profile/marketing-email/profile-marketing-email-campaign.ro.js +12 -0
- package/dist/profile/marketing-email/profile-marketing-email-recipient-status.enum.d.ts +6 -0
- package/dist/profile/marketing-email/profile-marketing-email-recipient-status.enum.js +6 -0
- package/dist/profile/marketing-email/test-send-email-v2.dto.d.ts +2 -2
- package/dist/profile/marketing-email/test-send-email-v2.dto.js +2 -2
- package/dist/promocode/promocode.ro.d.ts +18 -0
- package/dist/promocode/promocode.ro.js +51 -1
- package/dist/questroom/questroom-ai-context.d.ts +9 -0
- package/dist/questroom-scenario-email/create-questroom-scenario-email.dto.d.ts +2 -2
- package/dist/questroom-scenario-email/create-questroom-scenario-email.dto.js +3 -1
- package/dist/questroom-scenario-email/questroom-scenario-email.ro.d.ts +2 -2
- package/dist/slot/slot-discount-range.validator.js +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/upselling/create-upselling.dto.d.ts +5 -0
- package/dist/upselling/create-upselling.dto.js +8 -0
- package/dist/upselling/upselling.ro.d.ts +1 -0
- package/dist/upselling/upselling.ro.js +4 -0
- package/package.json +2 -2
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
export declare class QueryClientDto {
|
|
2
2
|
parentId?: number;
|
|
3
3
|
lastGame?: [string, string];
|
|
4
|
+
/**
|
|
5
|
+
* Recurring birthday window as `MM-DD` (year is ignored).
|
|
6
|
+
* Legacy `yyyy-mm-dd` values from saved segments are accepted and
|
|
7
|
+
* reduced to month+day on the backend.
|
|
8
|
+
*/
|
|
4
9
|
birthday?: [string, string];
|
|
5
10
|
gamesCount?: string[];
|
|
6
11
|
visitsCount?: 'exactly_1' | 'exactly_2' | 'more_2' | 'more_3' | 'more_4' | 'not_visited';
|
|
12
|
+
/** Calendar month 1–12; matches birthday in that month of any year. */
|
|
7
13
|
selectedMonth?: string | number;
|
|
8
14
|
blockedClient?: 'blocked' | 'not_blocked';
|
|
9
15
|
alowedToAds?: 'allowed' | 'not_allowed';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { EMAIL_CONTENT_VERSION_RAW_HTML, EMAIL_CONTENT_VERSION_V2, EmailThemeV2, TipTapJSONDoc } from './index';
|
|
2
|
+
/**
|
|
3
|
+
* Тело письма из редактора: либо блочный документ (`v2`), либо готовая
|
|
4
|
+
* вёрстка компании (`raw-html`). Один и тот же класс используют массовые
|
|
5
|
+
* рассылки, все автоматизации и сценарные письма — режим контента везде
|
|
6
|
+
* один и тот же, и расходиться валидации не должны.
|
|
7
|
+
*
|
|
8
|
+
* Один класс на оба режима, а не два с дискриминированным union'ом,
|
|
9
|
+
* потому что `class-validator` не умеет выбирать схему по значению поля
|
|
10
|
+
* без кастомного трансформера: `@Type` c `discriminator` работает лишь
|
|
11
|
+
* для массивов полиморфных объектов. Поэтому обязательность полей задаём
|
|
12
|
+
* через `@ValidateIf` по `version` — эффект тот же (нельзя прислать v2
|
|
13
|
+
* без `doc` или raw-html без `html`), а читать проще.
|
|
14
|
+
*/
|
|
15
|
+
export declare class EmailContentDto {
|
|
16
|
+
version: typeof EMAIL_CONTENT_VERSION_V2 | typeof EMAIL_CONTENT_VERSION_RAW_HTML;
|
|
17
|
+
doc?: TipTapJSONDoc;
|
|
18
|
+
theme?: EmailThemeV2;
|
|
19
|
+
/**
|
|
20
|
+
* Вёрстка письма. Санитизируется на бэкенде перед каждым рендером
|
|
21
|
+
* (`sanitizeEmailHtml`), здесь только ограничение размера — иначе
|
|
22
|
+
* многомегабайтная вставка забьёт jsonb-колонку.
|
|
23
|
+
*/
|
|
24
|
+
html?: string;
|
|
25
|
+
fileName?: string | null;
|
|
26
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.EmailContentDto = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const index_1 = require("./index");
|
|
16
|
+
/**
|
|
17
|
+
* Тело письма из редактора: либо блочный документ (`v2`), либо готовая
|
|
18
|
+
* вёрстка компании (`raw-html`). Один и тот же класс используют массовые
|
|
19
|
+
* рассылки, все автоматизации и сценарные письма — режим контента везде
|
|
20
|
+
* один и тот же, и расходиться валидации не должны.
|
|
21
|
+
*
|
|
22
|
+
* Один класс на оба режима, а не два с дискриминированным union'ом,
|
|
23
|
+
* потому что `class-validator` не умеет выбирать схему по значению поля
|
|
24
|
+
* без кастомного трансформера: `@Type` c `discriminator` работает лишь
|
|
25
|
+
* для массивов полиморфных объектов. Поэтому обязательность полей задаём
|
|
26
|
+
* через `@ValidateIf` по `version` — эффект тот же (нельзя прислать v2
|
|
27
|
+
* без `doc` или raw-html без `html`), а читать проще.
|
|
28
|
+
*/
|
|
29
|
+
class EmailContentDto {
|
|
30
|
+
}
|
|
31
|
+
exports.EmailContentDto = EmailContentDto;
|
|
32
|
+
__decorate([
|
|
33
|
+
(0, class_validator_1.IsIn)([index_1.EMAIL_CONTENT_VERSION_V2, index_1.EMAIL_CONTENT_VERSION_RAW_HTML]),
|
|
34
|
+
(0, class_transformer_1.Expose)(),
|
|
35
|
+
__metadata("design:type", Object)
|
|
36
|
+
], EmailContentDto.prototype, "version", void 0);
|
|
37
|
+
__decorate([
|
|
38
|
+
(0, class_validator_1.ValidateIf)((o) => o.version === index_1.EMAIL_CONTENT_VERSION_V2),
|
|
39
|
+
(0, class_validator_1.IsObject)(),
|
|
40
|
+
(0, class_transformer_1.Expose)(),
|
|
41
|
+
__metadata("design:type", Object)
|
|
42
|
+
], EmailContentDto.prototype, "doc", void 0);
|
|
43
|
+
__decorate([
|
|
44
|
+
(0, class_validator_1.IsOptional)(),
|
|
45
|
+
(0, class_validator_1.IsObject)(),
|
|
46
|
+
(0, class_transformer_1.Expose)(),
|
|
47
|
+
__metadata("design:type", Object)
|
|
48
|
+
], EmailContentDto.prototype, "theme", void 0);
|
|
49
|
+
__decorate([
|
|
50
|
+
(0, class_validator_1.ValidateIf)((o) => o.version === index_1.EMAIL_CONTENT_VERSION_RAW_HTML),
|
|
51
|
+
(0, class_validator_1.IsString)(),
|
|
52
|
+
(0, class_validator_1.MaxLength)(index_1.RAW_HTML_MAX_LENGTH),
|
|
53
|
+
(0, class_transformer_1.Expose)(),
|
|
54
|
+
__metadata("design:type", String)
|
|
55
|
+
], EmailContentDto.prototype, "html", void 0);
|
|
56
|
+
__decorate([
|
|
57
|
+
(0, class_validator_1.IsOptional)(),
|
|
58
|
+
(0, class_validator_1.IsString)(),
|
|
59
|
+
(0, class_validator_1.MaxLength)(255),
|
|
60
|
+
(0, class_transformer_1.Expose)(),
|
|
61
|
+
__metadata("design:type", String)
|
|
62
|
+
], EmailContentDto.prototype, "fileName", void 0);
|
|
@@ -10,6 +10,18 @@
|
|
|
10
10
|
* for transactional emails that are NOT user-editable.
|
|
11
11
|
*/
|
|
12
12
|
export declare const EMAIL_CONTENT_VERSION_V2: "v2";
|
|
13
|
+
/**
|
|
14
|
+
* Версия «сырой HTML»: тело письма — готовая вёрстка, которую компания
|
|
15
|
+
* принесла из внешнего редактора (Stripo, Unlayer, вручную свёрстанный
|
|
16
|
+
* шаблон агентства). Блочный редактор в этом режиме отключён: править
|
|
17
|
+
* такую вёрстку по нодам нельзя без потери разметки.
|
|
18
|
+
*
|
|
19
|
+
* Хранится в том же `contentJson`-поле, что и v2, — поэтому у типов
|
|
20
|
+
* общий дискриминант `version`, а все консьюмеры уже обязаны сверяться
|
|
21
|
+
* с ним через guard'ы (`isEmailContentJsonV2`), а не полагаться на
|
|
22
|
+
* форму объекта.
|
|
23
|
+
*/
|
|
24
|
+
export declare const EMAIL_CONTENT_VERSION_RAW_HTML: "raw-html";
|
|
13
25
|
/**
|
|
14
26
|
* TipTap JSON document. We keep `content` loose to avoid forcing every
|
|
15
27
|
* consumer to install TipTap types. The structure is whatever
|
|
@@ -125,6 +137,75 @@ export type EmailContentJsonV2 = {
|
|
|
125
137
|
theme?: EmailThemeV2;
|
|
126
138
|
};
|
|
127
139
|
export declare const isEmailContentJsonV2: (raw: unknown) => raw is EmailContentJsonV2;
|
|
140
|
+
/**
|
|
141
|
+
* Тело письма — готовый HTML вместо блочного документа.
|
|
142
|
+
*
|
|
143
|
+
* Темы (`theme`) здесь нет намеренно: вся типографика и цвета уже
|
|
144
|
+
* зашиты во внешнюю вёрстку, и наложение нашей темы поверх неё дало бы
|
|
145
|
+
* непредсказуемый результат. Переменные (`{{client.firstName}}`),
|
|
146
|
+
* preheader, UTM-разметка и обязательный футер применяются одинаково в
|
|
147
|
+
* обоих режимах — они работают по отрендеренному HTML, а не по нодам.
|
|
148
|
+
*/
|
|
149
|
+
export type EmailContentRawHtml = {
|
|
150
|
+
version: typeof EMAIL_CONTENT_VERSION_RAW_HTML;
|
|
151
|
+
/**
|
|
152
|
+
* Вёрстка письма как есть, из внешнего редактора. Санитизируется
|
|
153
|
+
* на бэкенде перед каждым рендером (`sanitizeEmailHtml`), а не при
|
|
154
|
+
* сохранении: правила фильтрации со временем ужесточаются, и
|
|
155
|
+
* пропущенное однажды не должно оставаться в проде навсегда.
|
|
156
|
+
*/
|
|
157
|
+
html: string;
|
|
158
|
+
/**
|
|
159
|
+
* Имя загруженного файла — чтобы в UI показать «promo-july.html»
|
|
160
|
+
* вместо безымянного блока. Ни на что в рендере не влияет.
|
|
161
|
+
*/
|
|
162
|
+
fileName?: string | null;
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Максимальный размер «сырого» HTML.
|
|
166
|
+
*
|
|
167
|
+
* Gmail обрезает письмо («просмотреть всё сообщение») примерно на 102 КБ,
|
|
168
|
+
* и в обрезанный хвост попадает как раз футер с отпиской — поэтому про
|
|
169
|
+
* приближение к этому порогу preflight предупреждает отдельно. Здесь
|
|
170
|
+
* лимит намеренно на порядок выше: это защита не от «крупного письма», а
|
|
171
|
+
* от многомегабайтной вставки (обычно это вёрстка с картинками в base64),
|
|
172
|
+
* которая забьёт jsonb-колонку и положит рендер всей очереди.
|
|
173
|
+
*/
|
|
174
|
+
export declare const RAW_HTML_MAX_LENGTH = 1000000;
|
|
175
|
+
/**
|
|
176
|
+
* Порог, после которого Gmail начинает обрезать письмо. Используется в
|
|
177
|
+
* preflight как предупреждение (не блокер).
|
|
178
|
+
*/
|
|
179
|
+
export declare const GMAIL_CLIP_THRESHOLD_BYTES: number;
|
|
180
|
+
export declare const isEmailContentRawHtml: (raw: unknown) => raw is EmailContentRawHtml;
|
|
181
|
+
/**
|
|
182
|
+
* Любое поддерживаемое тело письма из редактора. Дискриминант —
|
|
183
|
+
* `version`, поэтому `switch`/guard'ы дают исчерпывающую проверку.
|
|
184
|
+
*/
|
|
185
|
+
export type EmailContent = EmailContentJsonV2 | EmailContentRawHtml;
|
|
186
|
+
export declare const isEmailContent: (raw: unknown) => raw is EmailContent;
|
|
187
|
+
/**
|
|
188
|
+
* Свести входящий контент к строгому `EmailContent`, отбросив лишние
|
|
189
|
+
* поля. Нужно на границе HTTP: DTO (`EmailContentDto`) — это один класс
|
|
190
|
+
* на оба режима, поэтому у него одновременно опциональны и `doc`, и
|
|
191
|
+
* `html`, и TypeScript не может сузить его до нужного варианта union'а.
|
|
192
|
+
*
|
|
193
|
+
* Возвращает `null` для нераспознанного контента, чтобы вызывающий
|
|
194
|
+
* ответил 400, а не записал в базу мусор.
|
|
195
|
+
*/
|
|
196
|
+
export declare const normalizeEmailContent: (raw: unknown) => EmailContent | null;
|
|
197
|
+
export declare const createEmptyRawHtmlContent: () => EmailContentRawHtml;
|
|
198
|
+
/**
|
|
199
|
+
* Есть ли у письма непустое тело для рендера. Отдельно от
|
|
200
|
+
* `isEmailContentJsonV2`/`isEmailContentRawHtml`, потому что те
|
|
201
|
+
* проверяют только форму конверта: `createEmptyEmailContent()` —
|
|
202
|
+
* валидный v2 с пустым `doc.content`, а `createEmptyRawHtmlContent()` —
|
|
203
|
+
* валидный raw-html с пустой строкой; отправлять такое нельзя.
|
|
204
|
+
*
|
|
205
|
+
* Используется в preflight кампаний. Возвращает `false` для любого
|
|
206
|
+
* нераспознанного значения, поэтому вызывающему не нужен отдельный guard.
|
|
207
|
+
*/
|
|
208
|
+
export declare const hasEmailContentBody: (raw: unknown) => boolean;
|
|
128
209
|
/**
|
|
129
210
|
* Дефолтная тема для seed'а пустого шаблона и для конверсии legacy
|
|
130
211
|
* HTML в v2. Экспортирована, чтобы конвертеры/миграции могли собирать
|
|
@@ -11,8 +11,20 @@
|
|
|
11
11
|
* for transactional emails that are NOT user-editable.
|
|
12
12
|
*/
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.EmailScope = exports.normalizeEmailTheme = exports.createDefaultEmailContent = exports.createLogoNode = exports.DEFAULT_EMAIL_TEXTS = exports.createEmptyEmailContent = exports.DEFAULT_EMAIL_THEME = exports.isEmailContentJsonV2 = exports.resolveEmailThemeColors = exports.deriveEmailTextColors = exports.EMAIL_CONTENT_VERSION_V2 = void 0;
|
|
14
|
+
exports.EmailScope = exports.normalizeEmailTheme = exports.createDefaultEmailContent = exports.createLogoNode = exports.DEFAULT_EMAIL_TEXTS = exports.createEmptyEmailContent = exports.DEFAULT_EMAIL_THEME = exports.hasEmailContentBody = exports.createEmptyRawHtmlContent = exports.normalizeEmailContent = exports.isEmailContent = exports.isEmailContentRawHtml = exports.GMAIL_CLIP_THRESHOLD_BYTES = exports.RAW_HTML_MAX_LENGTH = exports.isEmailContentJsonV2 = exports.resolveEmailThemeColors = exports.deriveEmailTextColors = exports.EMAIL_CONTENT_VERSION_RAW_HTML = exports.EMAIL_CONTENT_VERSION_V2 = void 0;
|
|
15
15
|
exports.EMAIL_CONTENT_VERSION_V2 = 'v2';
|
|
16
|
+
/**
|
|
17
|
+
* Версия «сырой HTML»: тело письма — готовая вёрстка, которую компания
|
|
18
|
+
* принесла из внешнего редактора (Stripo, Unlayer, вручную свёрстанный
|
|
19
|
+
* шаблон агентства). Блочный редактор в этом режиме отключён: править
|
|
20
|
+
* такую вёрстку по нодам нельзя без потери разметки.
|
|
21
|
+
*
|
|
22
|
+
* Хранится в том же `contentJson`-поле, что и v2, — поэтому у типов
|
|
23
|
+
* общий дискриминант `version`, а все консьюмеры уже обязаны сверяться
|
|
24
|
+
* с ним через guard'ы (`isEmailContentJsonV2`), а не полагаться на
|
|
25
|
+
* форму объекта.
|
|
26
|
+
*/
|
|
27
|
+
exports.EMAIL_CONTENT_VERSION_RAW_HTML = 'raw-html';
|
|
16
28
|
/**
|
|
17
29
|
* Compute the relative luminance of an opaque hex color in [0, 1].
|
|
18
30
|
* Uses the perceptual weights from the ITU-R BT.601 standard (which
|
|
@@ -104,6 +116,82 @@ const isEmailContentJsonV2 = (raw) => {
|
|
|
104
116
|
((_a = raw.doc) === null || _a === void 0 ? void 0 : _a.type) === 'doc';
|
|
105
117
|
};
|
|
106
118
|
exports.isEmailContentJsonV2 = isEmailContentJsonV2;
|
|
119
|
+
/**
|
|
120
|
+
* Максимальный размер «сырого» HTML.
|
|
121
|
+
*
|
|
122
|
+
* Gmail обрезает письмо («просмотреть всё сообщение») примерно на 102 КБ,
|
|
123
|
+
* и в обрезанный хвост попадает как раз футер с отпиской — поэтому про
|
|
124
|
+
* приближение к этому порогу preflight предупреждает отдельно. Здесь
|
|
125
|
+
* лимит намеренно на порядок выше: это защита не от «крупного письма», а
|
|
126
|
+
* от многомегабайтной вставки (обычно это вёрстка с картинками в base64),
|
|
127
|
+
* которая забьёт jsonb-колонку и положит рендер всей очереди.
|
|
128
|
+
*/
|
|
129
|
+
exports.RAW_HTML_MAX_LENGTH = 1000000;
|
|
130
|
+
/**
|
|
131
|
+
* Порог, после которого Gmail начинает обрезать письмо. Используется в
|
|
132
|
+
* preflight как предупреждение (не блокер).
|
|
133
|
+
*/
|
|
134
|
+
exports.GMAIL_CLIP_THRESHOLD_BYTES = 102 * 1024;
|
|
135
|
+
const isEmailContentRawHtml = (raw) => !!raw &&
|
|
136
|
+
typeof raw === 'object' &&
|
|
137
|
+
raw.version === exports.EMAIL_CONTENT_VERSION_RAW_HTML &&
|
|
138
|
+
typeof raw.html === 'string';
|
|
139
|
+
exports.isEmailContentRawHtml = isEmailContentRawHtml;
|
|
140
|
+
const isEmailContent = (raw) => (0, exports.isEmailContentJsonV2)(raw) || (0, exports.isEmailContentRawHtml)(raw);
|
|
141
|
+
exports.isEmailContent = isEmailContent;
|
|
142
|
+
/**
|
|
143
|
+
* Свести входящий контент к строгому `EmailContent`, отбросив лишние
|
|
144
|
+
* поля. Нужно на границе HTTP: DTO (`EmailContentDto`) — это один класс
|
|
145
|
+
* на оба режима, поэтому у него одновременно опциональны и `doc`, и
|
|
146
|
+
* `html`, и TypeScript не может сузить его до нужного варианта union'а.
|
|
147
|
+
*
|
|
148
|
+
* Возвращает `null` для нераспознанного контента, чтобы вызывающий
|
|
149
|
+
* ответил 400, а не записал в базу мусор.
|
|
150
|
+
*/
|
|
151
|
+
const normalizeEmailContent = (raw) => {
|
|
152
|
+
var _a;
|
|
153
|
+
if ((0, exports.isEmailContentRawHtml)(raw)) {
|
|
154
|
+
return {
|
|
155
|
+
version: exports.EMAIL_CONTENT_VERSION_RAW_HTML,
|
|
156
|
+
html: raw.html,
|
|
157
|
+
fileName: (_a = raw.fileName) !== null && _a !== void 0 ? _a : null,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if ((0, exports.isEmailContentJsonV2)(raw)) {
|
|
161
|
+
return {
|
|
162
|
+
version: exports.EMAIL_CONTENT_VERSION_V2,
|
|
163
|
+
doc: raw.doc,
|
|
164
|
+
theme: raw.theme,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
};
|
|
169
|
+
exports.normalizeEmailContent = normalizeEmailContent;
|
|
170
|
+
const createEmptyRawHtmlContent = () => ({
|
|
171
|
+
version: exports.EMAIL_CONTENT_VERSION_RAW_HTML,
|
|
172
|
+
html: '',
|
|
173
|
+
fileName: null,
|
|
174
|
+
});
|
|
175
|
+
exports.createEmptyRawHtmlContent = createEmptyRawHtmlContent;
|
|
176
|
+
/**
|
|
177
|
+
* Есть ли у письма непустое тело для рендера. Отдельно от
|
|
178
|
+
* `isEmailContentJsonV2`/`isEmailContentRawHtml`, потому что те
|
|
179
|
+
* проверяют только форму конверта: `createEmptyEmailContent()` —
|
|
180
|
+
* валидный v2 с пустым `doc.content`, а `createEmptyRawHtmlContent()` —
|
|
181
|
+
* валидный raw-html с пустой строкой; отправлять такое нельзя.
|
|
182
|
+
*
|
|
183
|
+
* Используется в preflight кампаний. Возвращает `false` для любого
|
|
184
|
+
* нераспознанного значения, поэтому вызывающему не нужен отдельный guard.
|
|
185
|
+
*/
|
|
186
|
+
const hasEmailContentBody = (raw) => {
|
|
187
|
+
var _a;
|
|
188
|
+
if ((0, exports.isEmailContentRawHtml)(raw))
|
|
189
|
+
return raw.html.trim().length > 0;
|
|
190
|
+
if (!(0, exports.isEmailContentJsonV2)(raw))
|
|
191
|
+
return false;
|
|
192
|
+
return (((_a = raw.doc.content) === null || _a === void 0 ? void 0 : _a.length) || 0) > 0;
|
|
193
|
+
};
|
|
194
|
+
exports.hasEmailContentBody = hasEmailContentBody;
|
|
107
195
|
/**
|
|
108
196
|
* Дефолтная тема для seed'а пустого шаблона и для конверсии legacy
|
|
109
197
|
* HTML в v2. Экспортирована, чтобы конвертеры/миграции могли собирать
|
package/dist/emails/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EmailContentJsonV2 } from '../email-builder';
|
|
1
|
+
import { EmailContentJsonV2, EmailContentRawHtml } from '../email-builder';
|
|
2
2
|
import { EmailSenderEnum } from './enum/email.senders';
|
|
3
3
|
/**
|
|
4
4
|
* Email paragraph block.
|
|
@@ -81,6 +81,13 @@ export type EmailDataV2 = EmailContentJsonV2 & {
|
|
|
81
81
|
* this map but honours `{{id|"fallback"}}` if the key is missing.
|
|
82
82
|
*/
|
|
83
83
|
variables: Record<string, string>;
|
|
84
|
+
/**
|
|
85
|
+
* Текст превью в списке писем (рядом с темой). Рендерится скрытым
|
|
86
|
+
* блоком первым узлом `<body>`; поддерживает те же `{{var}}`-токены,
|
|
87
|
+
* что и тело. Пусто/не задано — почтовый клиент возьмёт превью из
|
|
88
|
+
* начала письма, как и раньше.
|
|
89
|
+
*/
|
|
90
|
+
preheader?: string | null;
|
|
84
91
|
/**
|
|
85
92
|
* Mandatory v2 footer. alfa-mailer always renders this even if the
|
|
86
93
|
* user did not include a Footer block in the doc.
|
|
@@ -137,7 +144,23 @@ export type EmailDataV2 = EmailContentJsonV2 & {
|
|
|
137
144
|
*/
|
|
138
145
|
blockPayloads?: Record<string, string>;
|
|
139
146
|
};
|
|
140
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Payload письма, тело которого — готовый HTML из внешнего редактора
|
|
149
|
+
* (`EmailContentRawHtml`). Обвязка та же, что у v2: резолвленные
|
|
150
|
+
* переменные, preheader, обязательный футер и UTM-разметка применяются к
|
|
151
|
+
* HTML одинаково в обоих режимах.
|
|
152
|
+
*
|
|
153
|
+
* Отсутствуют по сравнению с v2:
|
|
154
|
+
* - `theme` — типографика уже внутри чужой вёрстки;
|
|
155
|
+
* - `blockPayloads` — канал завязан на `htmlCodeBlock`-ноды TipTap-doc'а.
|
|
156
|
+
*/
|
|
157
|
+
export type EmailDataRawHtml = EmailContentRawHtml & {
|
|
158
|
+
variables: Record<string, string>;
|
|
159
|
+
preheader?: string | null;
|
|
160
|
+
footer: EmailDataV2['footer'];
|
|
161
|
+
utm?: EmailDataV2['utm'];
|
|
162
|
+
};
|
|
163
|
+
export type SendEmailData = EmailDataV1 | EmailDataV2 | EmailDataRawHtml;
|
|
141
164
|
export type SendEmailRequestParams = {
|
|
142
165
|
from: EmailSenderEnum;
|
|
143
166
|
to: string;
|
|
@@ -29,14 +29,15 @@ const questroom_type_enum_1 = require("../../questroom/enum/questroom-type.enum"
|
|
|
29
29
|
const languages_enum_1 = require("../../shared/enum/languages.enum");
|
|
30
30
|
const openapi_slot_tariff_ro_1 = require("../slots/openapi-slot-tariff.ro");
|
|
31
31
|
const transformQuestroom = ({ value, language, }) => {
|
|
32
|
-
var _a, _b
|
|
32
|
+
var _a, _b;
|
|
33
33
|
if (!value)
|
|
34
34
|
return value;
|
|
35
35
|
const { locales, location } = value, questroom = __rest(value, ["locales", "location"]);
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
const _c = location || {}, { locales: locationLocales } = _c, locationRest = __rest(_c, ["locales"]);
|
|
37
|
+
const locale = locales === null || locales === void 0 ? void 0 : locales.find((l) => l.language === language);
|
|
38
|
+
return Object.assign(Object.assign({}, questroom), { title: (locale === null || locale === void 0 ? void 0 : locale.title) || questroom.title, legend: (locale === null || locale === void 0 ? void 0 : locale.legend) || questroom.legend, importantInfo: (locale === null || locale === void 0 ? void 0 : locale.importantInfo) || questroom.importantInfo, photos: questroom.photos || [], location: location
|
|
39
|
+
? Object.assign(Object.assign({}, locationRest), { howToFind: ((_a = locationLocales === null || locationLocales === void 0 ? void 0 : locationLocales.find((l) => l.language === language)) === null || _a === void 0 ? void 0 : _a.howToFind) ||
|
|
40
|
+
locationRest.howToFind, prepareText: ((_b = locationLocales === null || locationLocales === void 0 ? void 0 : locationLocales.find((l) => l.language === language)) === null || _b === void 0 ? void 0 : _b.prepareText) ||
|
|
40
41
|
locationRest.prepareText }) : location });
|
|
41
42
|
};
|
|
42
43
|
exports.transformQuestroom = transformQuestroom;
|
|
@@ -159,6 +160,14 @@ __decorate([
|
|
|
159
160
|
(0, class_transformer_1.Expose)(),
|
|
160
161
|
__metadata("design:type", String)
|
|
161
162
|
], OpenapiQuestroomRO.prototype, "photo", void 0);
|
|
163
|
+
__decorate([
|
|
164
|
+
(0, class_transformer_1.Expose)(),
|
|
165
|
+
__metadata("design:type", Array)
|
|
166
|
+
], OpenapiQuestroomRO.prototype, "photos", void 0);
|
|
167
|
+
__decorate([
|
|
168
|
+
(0, class_transformer_1.Expose)(),
|
|
169
|
+
__metadata("design:type", String)
|
|
170
|
+
], OpenapiQuestroomRO.prototype, "legend", void 0);
|
|
162
171
|
__decorate([
|
|
163
172
|
(0, class_transformer_1.Expose)(),
|
|
164
173
|
__metadata("design:type", Number)
|
|
@@ -62,6 +62,10 @@ __decorate([
|
|
|
62
62
|
(0, class_transformer_1.Expose)(),
|
|
63
63
|
__metadata("design:type", Array)
|
|
64
64
|
], OpenapiUpsellingRO.prototype, "availableDays", void 0);
|
|
65
|
+
__decorate([
|
|
66
|
+
(0, class_transformer_1.Expose)(),
|
|
67
|
+
__metadata("design:type", Number)
|
|
68
|
+
], OpenapiUpsellingRO.prototype, "minMinutesBeforeStart", void 0);
|
|
65
69
|
__decorate([
|
|
66
70
|
(0, class_transformer_1.Expose)(),
|
|
67
71
|
__metadata("design:type", Boolean)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EmailContent } from '../../email-builder';
|
|
2
2
|
import { Languages } from '../../shared/enum/languages.enum';
|
|
3
3
|
import { CrossSaleStatusEnum } from '../cross-sale/cross-sale-status.enum';
|
|
4
4
|
import { CrossSaleDiscountTypeEnum } from '../cross-sale/crossale-discount-type.enum';
|
|
@@ -11,7 +11,7 @@ export declare class BirthdayMarketingLocaleDto {
|
|
|
11
11
|
* Maily/TipTap v2-документ. Опционально — старый Quill-редактор
|
|
12
12
|
* присылает только `feedbackText`. См. `CustomClientBookingEmailLocaleDto.contentJson`.
|
|
13
13
|
*/
|
|
14
|
-
contentJson?:
|
|
14
|
+
contentJson?: EmailContent | null;
|
|
15
15
|
}
|
|
16
16
|
export declare class BirthdayMarketingDto {
|
|
17
17
|
/**
|
|
@@ -13,6 +13,7 @@ exports.BirthdayMarketingDto = exports.BirthdayMarketingLocaleDto = void 0;
|
|
|
13
13
|
/* eslint-disable max-classes-per-file */
|
|
14
14
|
const class_transformer_1 = require("class-transformer");
|
|
15
15
|
const class_validator_1 = require("class-validator");
|
|
16
|
+
const email_content_dto_1 = require("../../email-builder/email-content.dto");
|
|
16
17
|
const languages_enum_1 = require("../../shared/enum/languages.enum");
|
|
17
18
|
const is_not_blank_1 = require("../../shared/is-not-blank");
|
|
18
19
|
const cross_sale_status_enum_1 = require("../cross-sale/cross-sale-status.enum");
|
|
@@ -42,7 +43,8 @@ __decorate([
|
|
|
42
43
|
], BirthdayMarketingLocaleDto.prototype, "title", void 0);
|
|
43
44
|
__decorate([
|
|
44
45
|
(0, class_validator_1.IsOptional)(),
|
|
45
|
-
(0, class_validator_1.
|
|
46
|
+
(0, class_validator_1.ValidateNested)(),
|
|
47
|
+
(0, class_transformer_1.Type)(() => email_content_dto_1.EmailContentDto),
|
|
46
48
|
(0, class_transformer_1.Expose)(),
|
|
47
49
|
__metadata("design:type", Object)
|
|
48
50
|
], BirthdayMarketingLocaleDto.prototype, "contentJson", void 0);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EmailContent } from '../../email-builder';
|
|
2
2
|
import { Languages } from '../../shared/enum/languages.enum';
|
|
3
3
|
import { CrossSaleStatusEnum } from './cross-sale-status.enum';
|
|
4
4
|
import { CrossSaleDiscountTypeEnum } from './crossale-discount-type.enum';
|
|
@@ -12,7 +12,7 @@ export declare class CrossSaleLocaleDto {
|
|
|
12
12
|
* присылать `contentJson` параллельно. См. подробности в
|
|
13
13
|
* `CustomClientBookingEmailLocaleDto.contentJson`.
|
|
14
14
|
*/
|
|
15
|
-
contentJson?:
|
|
15
|
+
contentJson?: EmailContent | null;
|
|
16
16
|
}
|
|
17
17
|
export declare class CrossSaleDto {
|
|
18
18
|
status: CrossSaleStatusEnum;
|
|
@@ -13,6 +13,7 @@ exports.CrossSaleDto = exports.CrossSaleLocaleDto = void 0;
|
|
|
13
13
|
/* eslint-disable max-classes-per-file */
|
|
14
14
|
const class_transformer_1 = require("class-transformer");
|
|
15
15
|
const class_validator_1 = require("class-validator");
|
|
16
|
+
const email_content_dto_1 = require("../../email-builder/email-content.dto");
|
|
16
17
|
const languages_enum_1 = require("../../shared/enum/languages.enum");
|
|
17
18
|
const feedback_validators_1 = require("../../shared/feedback-validators");
|
|
18
19
|
const is_not_blank_1 = require("../../shared/is-not-blank");
|
|
@@ -43,7 +44,8 @@ __decorate([
|
|
|
43
44
|
], CrossSaleLocaleDto.prototype, "title", void 0);
|
|
44
45
|
__decorate([
|
|
45
46
|
(0, class_validator_1.IsOptional)(),
|
|
46
|
-
(0, class_validator_1.
|
|
47
|
+
(0, class_validator_1.ValidateNested)(),
|
|
48
|
+
(0, class_transformer_1.Type)(() => email_content_dto_1.EmailContentDto),
|
|
47
49
|
(0, class_transformer_1.Expose)(),
|
|
48
50
|
__metadata("design:type", Object)
|
|
49
51
|
], CrossSaleLocaleDto.prototype, "contentJson", void 0);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EmailContent } from '../../email-builder';
|
|
2
2
|
import { Languages } from '../../shared/enum/languages.enum';
|
|
3
3
|
import { RO } from '../../shared/ro-class';
|
|
4
4
|
import { CrossSaleStatusEnum } from './cross-sale-status.enum';
|
|
@@ -7,7 +7,7 @@ export declare class CrossSaleLocaleRO {
|
|
|
7
7
|
language: Languages;
|
|
8
8
|
feedbackText: string;
|
|
9
9
|
title: string;
|
|
10
|
-
contentJson?:
|
|
10
|
+
contentJson?: EmailContent | null;
|
|
11
11
|
}
|
|
12
12
|
export declare class CrossSaleRO extends RO {
|
|
13
13
|
sendAfter: number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EmailContent } from '../../email-builder';
|
|
2
2
|
import { Languages } from '../../shared/enum/languages.enum';
|
|
3
3
|
import { CrossSaleStatusEnum } from '../cross-sale/cross-sale-status.enum';
|
|
4
4
|
export declare class CustomClientBookingEmailLocaleDto {
|
|
@@ -14,7 +14,7 @@ export declare class CustomClientBookingEmailLocaleDto {
|
|
|
14
14
|
* откатится на legacy-рендер `feedbackText` (см. договорённость
|
|
15
15
|
* по soft-fallback'у).
|
|
16
16
|
*/
|
|
17
|
-
contentJson?:
|
|
17
|
+
contentJson?: EmailContent | null;
|
|
18
18
|
}
|
|
19
19
|
export declare class CustomClientBookingEmailDto {
|
|
20
20
|
status: CrossSaleStatusEnum;
|
|
@@ -13,6 +13,7 @@ exports.CustomClientBookingEmailDto = exports.CustomClientBookingEmailLocaleDto
|
|
|
13
13
|
/* eslint-disable max-classes-per-file */
|
|
14
14
|
const class_transformer_1 = require("class-transformer");
|
|
15
15
|
const class_validator_1 = require("class-validator");
|
|
16
|
+
const email_content_dto_1 = require("../../email-builder/email-content.dto");
|
|
16
17
|
const languages_enum_1 = require("../../shared/enum/languages.enum");
|
|
17
18
|
const is_not_blank_1 = require("../../shared/is-not-blank");
|
|
18
19
|
const cross_sale_status_enum_1 = require("../cross-sale/cross-sale-status.enum");
|
|
@@ -40,7 +41,8 @@ __decorate([
|
|
|
40
41
|
], CustomClientBookingEmailLocaleDto.prototype, "title", void 0);
|
|
41
42
|
__decorate([
|
|
42
43
|
(0, class_validator_1.IsOptional)(),
|
|
43
|
-
(0, class_validator_1.
|
|
44
|
+
(0, class_validator_1.ValidateNested)(),
|
|
45
|
+
(0, class_transformer_1.Type)(() => email_content_dto_1.EmailContentDto),
|
|
44
46
|
(0, class_transformer_1.Expose)(),
|
|
45
47
|
__metadata("design:type", Object)
|
|
46
48
|
], CustomClientBookingEmailLocaleDto.prototype, "contentJson", void 0);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EmailContent } from '../../email-builder';
|
|
2
2
|
import { Languages } from '../../shared/enum/languages.enum';
|
|
3
3
|
import { RO } from '../../shared/ro-class';
|
|
4
4
|
import { CrossSaleStatusEnum } from '../cross-sale/cross-sale-status.enum';
|
|
@@ -13,7 +13,7 @@ export declare class CustomClientBookingEmailLocaleRO {
|
|
|
13
13
|
*/
|
|
14
14
|
feedbackText: string;
|
|
15
15
|
title: string;
|
|
16
|
-
contentJson?:
|
|
16
|
+
contentJson?: EmailContent | null;
|
|
17
17
|
}
|
|
18
18
|
export declare class CustomClientBookingEmailRO extends RO {
|
|
19
19
|
status: CrossSaleStatusEnum;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EmailContent } from '../../email-builder';
|
|
2
2
|
import { Languages } from '../../shared/enum/languages.enum';
|
|
3
3
|
import { MarketingAutomationConfigDto } from './marketing-automation-config.dto';
|
|
4
4
|
import { MarketingAutomationDiscountTypeEnum } from './marketing-automation-discount-type.enum';
|
|
@@ -16,7 +16,7 @@ export declare class MarketingAutomationLocaleDto {
|
|
|
16
16
|
feedbackText?: string;
|
|
17
17
|
title?: string;
|
|
18
18
|
/** v2-документ Maily/TipTap. Используется при `isV2 === true`. */
|
|
19
|
-
contentJson?:
|
|
19
|
+
contentJson?: EmailContent | null;
|
|
20
20
|
}
|
|
21
21
|
export declare class MarketingAutomationDto {
|
|
22
22
|
type: MarketingAutomationTypeEnum;
|
|
@@ -13,6 +13,7 @@ exports.MarketingAutomationDto = exports.MarketingAutomationLocaleDto = void 0;
|
|
|
13
13
|
/* eslint-disable max-classes-per-file */
|
|
14
14
|
const class_transformer_1 = require("class-transformer");
|
|
15
15
|
const class_validator_1 = require("class-validator");
|
|
16
|
+
const email_content_dto_1 = require("../../email-builder/email-content.dto");
|
|
16
17
|
const languages_enum_1 = require("../../shared/enum/languages.enum");
|
|
17
18
|
const marketing_automation_config_dto_1 = require("./marketing-automation-config.dto");
|
|
18
19
|
const marketing_automation_discount_type_enum_1 = require("./marketing-automation-discount-type.enum");
|
|
@@ -48,7 +49,8 @@ __decorate([
|
|
|
48
49
|
], MarketingAutomationLocaleDto.prototype, "title", void 0);
|
|
49
50
|
__decorate([
|
|
50
51
|
(0, class_validator_1.IsOptional)(),
|
|
51
|
-
(0, class_validator_1.
|
|
52
|
+
(0, class_validator_1.ValidateNested)(),
|
|
53
|
+
(0, class_transformer_1.Type)(() => email_content_dto_1.EmailContentDto),
|
|
52
54
|
(0, class_transformer_1.Expose)(),
|
|
53
55
|
__metadata("design:type", Object)
|
|
54
56
|
], MarketingAutomationLocaleDto.prototype, "contentJson", void 0);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EmailContent } from '../../email-builder';
|
|
2
2
|
import { Languages } from '../../shared/enum/languages.enum';
|
|
3
3
|
import { RO } from '../../shared/ro-class';
|
|
4
4
|
import { MarketingAutomationConfigDto } from './marketing-automation-config.dto';
|
|
@@ -9,7 +9,7 @@ export declare class MarketingAutomationLocaleRO {
|
|
|
9
9
|
language: Languages;
|
|
10
10
|
feedbackText: string;
|
|
11
11
|
title: string;
|
|
12
|
-
contentJson?:
|
|
12
|
+
contentJson?: EmailContent | null;
|
|
13
13
|
}
|
|
14
14
|
export declare class MarketingAutomationRO extends RO {
|
|
15
15
|
type: MarketingAutomationTypeEnum;
|