@escapenavigator/utils 1.10.145 → 1.10.147

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.
@@ -1,85 +1,20 @@
1
1
  /**
2
- * Конвертер legacy HTML (Quill output, использовавшийся в marketing-
3
- * emails: cross-sale, retargeting, up-sale, early-booking, birthday,
4
- * birthdayChild, custom-client-booking, scenario-emails) в формат
5
- * `EmailContentJsonV2` нового редактора (Maily/TipTap).
6
- *
7
- * Что обрабатывает:
8
- * - Параграфы `<p>` + переносы `<br>`, схлопывает пустые абзацы
9
- * - Inline-форматирование `<strong>`/`<em>`/`<u>`/`<s>` (marks)
10
- * - Ссылки `<a href="…">` → link-mark
11
- * - Изображения `<img>` image-нода
12
- * - Плоские плейсхолдеры `{varName}``variable`-ноды
13
- * - Maily-style плейсхолдеры `{{varName}}` и `{{varName|"fallback"}}`
14
- * тоже превращаются в `variable`-ноды учётом fallback'а)
15
- * - Управляющие конструкции:
16
- * • `{{#if X}}…{{/if}}` → `section` нода с `showIfKey: 'X'`
17
- * • `{{#manageBooking}}текст{{/manageBooking}}` → `button` нода
18
- * c `isUrlVariable: true, url: 'bookingManagementLink'`
19
- * - Блочные HTML-плейсхолдеры (`orderDetailsHtml`) — выносятся в
20
- * отдельный `htmlCodeBlock` (их значение содержит `<div>`/`<table>`,
21
- * нельзя оставить внутри `<p>`). `servicesList` тут не упоминается:
22
- * функция up-sale-листа в письмах выпилена, см. `isServicesListVariableNode`
23
- * - Цвета/фоны/font-size — выкидываются (как `clearQuill stripColors`)
24
- *
25
- * Что НЕ обрабатывает (по дизайну):
26
- * - Списки `<ul>`/`<ol>` — в legacy шаблонах не встречаются (Quill в
27
- * нашей конфигурации их не выставлял). Если попадутся — fallback на
28
- * обычный текст; добавим если потребуется по факту.
29
- * - Таблицы — то же самое.
30
- * - Заголовки `<h1>`-`<h6>` — Quill их не использовал в шаблонах.
31
- *
32
- * Преобразование чистое и идемпотентное: повторный вызов на той же
33
- * строке даёт тот же результат.
2
+ * Нормализатор устаревших block-variable чипов в `EmailContentJsonV2`
3
+ * (Maily/TipTap) документах.
4
+ *
5
+ * Раньше здесь жил полноценный конвертер legacy HTML (`feedbackText`)
6
+ * v2 (`convertLegacyHtmlToEmailContent`). Он удалён: маркетинг мигрирует
7
+ * на `marketing-automation` «как есть» на v1 (legacy `feedbackText`), а
8
+ * переход на v2 идёт через базовый `createDefaultEmailContent`, а НЕ через
9
+ * авто-конвертацию старого HTML.
10
+ *
11
+ * Что осталось `migratePhotosToImage`: идемпотентная нормализация уже
12
+ * сохранённых v2-доков (legacy `{photos}`-chipредактируемая image-нода,
13
+ * выпиленный `{servicesList}` → удаление). Нужна и фронту
14
+ * (`hydrateEmailLocales` при открытии редактора), и бэку
15
+ * (`v2-renderer.util.ts` как последний рубеж перед отправкой).
34
16
  */
35
17
  import { EmailContentJsonV2 } from '@escapenavigator/types/dist/email-builder';
36
- import { BLOCK_HTML_PLACEHOLDERS, isBlockHtmlPlaceholder, isKnownPlaceholder, KNOWN_PLACEHOLDERS, LEGACY_TO_NAMESPACED_ID_MAP, normalizePlaceholderId } from './placeholders';
37
- /**
38
- * Опции конвертера. Все необязательны — поведение «без аргументов»
39
- * выдаёт корректный `EmailContentJsonV2` с дефолтной темой и без
40
- * логотипа сверху (минимальный набор).
41
- */
42
- export type ConvertLegacyHtmlOptions = {
43
- /**
44
- * URL логотипа. Если задан — первой нодой в `doc.content` идёт
45
- * `image` с точно теми же параметрами, что и `createLogoNode`
46
- * (alignment/size/alt). Это нужно, чтобы после миграции v2-доки
47
- * визуально совпадали с seed'ом `createDefaultEmailContent` —
48
- * пользователь не должен заметить, что шаблон конвертился из
49
- * старого формата.
50
- */
51
- logo?: string | null;
52
- /**
53
- * Карта человекочитаемых лейблов для `variable.label`. Если для
54
- * ключа лейбла нет — будет использоваться сам ID. На бэке миграции
55
- * сюда удобно прокидывать резолверовские `declare()` лейблы; на
56
- * фронте — `t('crm-crosssales:emailConstructor.<key>.title')`.
57
- *
58
- * NB: лейблы ищутся по **уже отнормализованному** id (после
59
- * `idMap`), так как этот id и попадёт в JSON.
60
- */
61
- labels?: Readonly<Record<string, string>>;
62
- /**
63
- * Маппинг flat-id'ов → namespaced. По умолчанию используется
64
- * `LEGACY_TO_NAMESPACED_ID_MAP`. Передать `null` чтобы выключить
65
- * маппинг (полезно для тестов или ad-hoc конверсий вне marketing-
66
- * email пайплайна).
67
- */
68
- idMap?: Readonly<Record<string, string>> | null;
69
- /**
70
- * «Зашить» значения некоторых плейсхолдеров прямо в текст вместо
71
- * `variable`-ноды. Ключи проверяются **до** маппинга через `idMap`
72
- * (по исходному legacy-id, т.к. inline-замена нужна для legacy-
73
- * понятий вроде `profileTitle`, у которых больше нет резолвера).
74
- *
75
- * Пример: `{ profileTitle: 'Escape Quest' }` превратит
76
- * `{{profileTitle}}` в обычную текстовую ноду «Escape Quest».
77
- * Полезно для бекфилла, когда переменная упразднена, но в шаблонах
78
- * она встречается миллион раз — пользователь не должен видеть
79
- * пустую дыру или технический id после конверсии.
80
- */
81
- inlineValues?: Readonly<Record<string, string>>;
82
- };
83
18
  /**
84
19
  * Идемпотентный нормализатор устаревших variable-чипов, у которых
85
20
  * есть выделенное block-представление в Maily:
@@ -89,9 +24,7 @@ export type ConvertLegacyHtmlOptions = {
89
24
  * выпилена; см. `isServicesListVariableNode` и factory `() => []`
90
25
  * в `LEGACY_BLOCK_VARIABLE_REPLACERS`).
91
26
  *
92
- * Используется во всех трёх каналах:
93
- * - финальный шаг `convertLegacyHtmlToEmailContent` — гарантия для
94
- * свежих конверсий из legacy HTML;
27
+ * Используется в двух каналах:
95
28
  * - `hydrateEmailLocales` на фронте — лечит уже-сохранённые
96
29
  * contentJson при открытии формы;
97
30
  * - `renderEmailV2Local` на бэке — последний рубеж перед send,
@@ -104,11 +37,11 @@ export type ConvertLegacyHtmlOptions = {
104
37
  *
105
38
  * Правила обхода:
106
39
  * 1. Top-level `variable[id ∈ matchLegacyBlockVariable]` или
107
- * `htmlCodeBlock` с такой variable внутри (артефакт `promoteBlockHtmlVariables`)
108
- * — заменяются полностью на соответствующий block-узел.
40
+ * `htmlCodeBlock` с такой variable внутри заменяются полностью
41
+ * на соответствующий block-узел.
109
42
  * 2. `paragraph` с единственным непустым ребёнком-legacy-variable —
110
- * целиком заменяется на block-узел (image/repeat — block-level,
111
- * жить inline в параграфе не могут).
43
+ * целиком заменяется на block-узел (image — block-level, жить
44
+ * inline в параграфе не может).
112
45
  * 3. Variable посреди смешанного параграфа — оставляем как есть:
113
46
  * это пользовательский кейс, безопаснее не ломать layout.
114
47
  * 4. Внутрь `section`/`repeat`/`for`/`show` и т.п. block-контейнеров
@@ -119,31 +52,5 @@ export type ConvertLegacyHtmlOptions = {
119
52
  * с такими id уже не остаётся).
120
53
  */
121
54
  export declare function migratePhotosToImage(content: EmailContentJsonV2): EmailContentJsonV2;
122
- /**
123
- * Главная точка входа конвертера. Принимает legacy HTML (Quill-style
124
- * с плоскими плейсхолдерами и handlebars-блоками) и возвращает готовый
125
- * `EmailContentJsonV2`, готовый к сохранению в БД и открытию в
126
- * EmailBuilder.
127
- *
128
- * Идемпотентен: пустой/null/whitespace вход даёт минимальный валидный
129
- * `doc` (с логотипом если указан, иначе пустой массив content).
130
- *
131
- * Шаги обработки (в порядке выполнения):
132
- * 1. `preprocessHtml` — text-level замены (`{{#if}}`, `{var}`, ...)
133
- * 2. parse через node-html-parser
134
- * 3. `walk` — построение TipTap-нод верхнего уровня
135
- * 4. `promoteBlockHtmlVariables` — вынос block-payload плейсхолдеров
136
- * 5. `normalizeVariableIds` — flat → namespaced id (если включено)
137
- * 6. оборачивание в `EmailContentJsonV2` с логотипом и темой
138
- */
139
- export declare function convertLegacyHtmlToEmailContent(html: string | null | undefined, options?: ConvertLegacyHtmlOptions): EmailContentJsonV2;
140
- /**
141
- * Подсчёт неизвестных плейсхолдеров в legacy HTML. Возвращает уникальные
142
- * имена `{X}` и `{{X}}`, которые **не входят** в `KNOWN_PLACEHOLDERS`.
143
- * Используется до миграции, чтобы найти ручные/опечатанные токены в
144
- * шаблонах клиентов и решить, что с ними делать (исправить → конвертим,
145
- * проигнорить → оставляем как литеральный текст).
146
- */
147
- export declare function findUnknownPlaceholders(html: string | null | undefined): string[];
148
55
  export type { KnownPlaceholder } from './placeholders';
149
- export { BLOCK_HTML_PLACEHOLDERS, isBlockHtmlPlaceholder, isKnownPlaceholder, KNOWN_PLACEHOLDERS, LEGACY_TO_NAMESPACED_ID_MAP, normalizePlaceholderId, };
56
+ export { BLOCK_HTML_PLACEHOLDERS, isBlockHtmlPlaceholder, isKnownPlaceholder, KNOWN_PLACEHOLDERS, LEGACY_TO_NAMESPACED_ID_MAP, normalizePlaceholderId, } from './placeholders';