@endora-commerce/contracts 0.100.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +34 -0
- package/dist/actor.d.ts +79 -0
- package/dist/actor.d.ts.map +1 -0
- package/dist/actor.js +41 -0
- package/dist/actor.js.map +1 -0
- package/dist/addresses.d.ts +134 -0
- package/dist/addresses.d.ts.map +1 -0
- package/dist/addresses.js +16 -0
- package/dist/addresses.js.map +1 -0
- package/dist/admin-actions.d.ts +367 -0
- package/dist/admin-actions.d.ts.map +1 -0
- package/dist/admin-actions.js +287 -0
- package/dist/admin-actions.js.map +1 -0
- package/dist/admin-contributions.d.ts +518 -0
- package/dist/admin-contributions.d.ts.map +1 -0
- package/dist/admin-contributions.js +495 -0
- package/dist/admin-contributions.js.map +1 -0
- package/dist/admin-i18n.d.ts +135 -0
- package/dist/admin-i18n.d.ts.map +1 -0
- package/dist/admin-i18n.js +72 -0
- package/dist/admin-i18n.js.map +1 -0
- package/dist/admin-notifications.d.ts +55 -0
- package/dist/admin-notifications.d.ts.map +1 -0
- package/dist/admin-notifications.js +16 -0
- package/dist/admin-notifications.js.map +1 -0
- package/dist/admin-roles.d.ts +125 -0
- package/dist/admin-roles.d.ts.map +1 -0
- package/dist/admin-roles.js +2 -0
- package/dist/admin-roles.js.map +1 -0
- package/dist/admin-users.d.ts +178 -0
- package/dist/admin-users.d.ts.map +1 -0
- package/dist/admin-users.js +14 -0
- package/dist/admin-users.js.map +1 -0
- package/dist/admin.d.ts +243 -0
- package/dist/admin.d.ts.map +1 -0
- package/dist/admin.js +246 -0
- package/dist/admin.js.map +1 -0
- package/dist/analytics.d.ts +123 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +68 -0
- package/dist/analytics.js.map +1 -0
- package/dist/api-keys.d.ts +97 -0
- package/dist/api-keys.d.ts.map +1 -0
- package/dist/api-keys.js +64 -0
- package/dist/api-keys.js.map +1 -0
- package/dist/assets-library.d.ts +684 -0
- package/dist/assets-library.d.ts.map +1 -0
- package/dist/assets-library.js +181 -0
- package/dist/assets-library.js.map +1 -0
- package/dist/audit-logs.d.ts +141 -0
- package/dist/audit-logs.d.ts.map +1 -0
- package/dist/audit-logs.js +31 -0
- package/dist/audit-logs.js.map +1 -0
- package/dist/auth.d.ts +174 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +27 -0
- package/dist/auth.js.map +1 -0
- package/dist/blog.d.ts +669 -0
- package/dist/blog.d.ts.map +1 -0
- package/dist/blog.js +360 -0
- package/dist/blog.js.map +1 -0
- package/dist/capabilities.d.ts +40 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +38 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/carts.d.ts +1367 -0
- package/dist/carts.d.ts.map +1 -0
- package/dist/carts.js +405 -0
- package/dist/carts.js.map +1 -0
- package/dist/catalog.d.ts +2855 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +1543 -0
- package/dist/catalog.js.map +1 -0
- package/dist/cms.d.ts +872 -0
- package/dist/cms.d.ts.map +1 -0
- package/dist/cms.js +468 -0
- package/dist/cms.js.map +1 -0
- package/dist/common.d.ts +82 -0
- package/dist/common.d.ts.map +1 -0
- package/dist/common.js +72 -0
- package/dist/common.js.map +1 -0
- package/dist/comparisons.d.ts +487 -0
- package/dist/comparisons.d.ts.map +1 -0
- package/dist/comparisons.js +221 -0
- package/dist/comparisons.js.map +1 -0
- package/dist/credentials.d.ts +292 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +142 -0
- package/dist/credentials.js.map +1 -0
- package/dist/credit-limits.d.ts +111 -0
- package/dist/credit-limits.d.ts.map +1 -0
- package/dist/credit-limits.js +35 -0
- package/dist/credit-limits.js.map +1 -0
- package/dist/currencies.d.ts +127 -0
- package/dist/currencies.d.ts.map +1 -0
- package/dist/currencies.js +20 -0
- package/dist/currencies.js.map +1 -0
- package/dist/custom-fields.d.ts +345 -0
- package/dist/custom-fields.d.ts.map +1 -0
- package/dist/custom-fields.js +185 -0
- package/dist/custom-fields.js.map +1 -0
- package/dist/customer-accounts.d.ts +690 -0
- package/dist/customer-accounts.d.ts.map +1 -0
- package/dist/customer-accounts.js +41 -0
- package/dist/customer-accounts.js.map +1 -0
- package/dist/customers.d.ts +305 -0
- package/dist/customers.d.ts.map +1 -0
- package/dist/customers.js +158 -0
- package/dist/customers.js.map +1 -0
- package/dist/dictionary.d.ts +580 -0
- package/dist/dictionary.d.ts.map +1 -0
- package/dist/dictionary.js +297 -0
- package/dist/dictionary.js.map +1 -0
- package/dist/email-address.d.ts +62 -0
- package/dist/email-address.d.ts.map +1 -0
- package/dist/email-address.js +64 -0
- package/dist/email-address.js.map +1 -0
- package/dist/email.d.ts +175 -0
- package/dist/email.d.ts.map +1 -0
- package/dist/email.js +45 -0
- package/dist/email.js.map +1 -0
- package/dist/envelopes.d.ts +15 -0
- package/dist/envelopes.d.ts.map +1 -0
- package/dist/envelopes.js +16 -0
- package/dist/envelopes.js.map +1 -0
- package/dist/environment-inputs.d.ts +306 -0
- package/dist/environment-inputs.d.ts.map +1 -0
- package/dist/environment-inputs.js +277 -0
- package/dist/environment-inputs.js.map +1 -0
- package/dist/erp-connector.d.ts +52 -0
- package/dist/erp-connector.d.ts.map +1 -0
- package/dist/erp-connector.js +34 -0
- package/dist/erp-connector.js.map +1 -0
- package/dist/errors.d.ts +455 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +532 -0
- package/dist/errors.js.map +1 -0
- package/dist/google-analytics.d.ts +181 -0
- package/dist/google-analytics.d.ts.map +1 -0
- package/dist/google-analytics.js +176 -0
- package/dist/google-analytics.js.map +1 -0
- package/dist/google-tag-manager.d.ts +111 -0
- package/dist/google-tag-manager.d.ts.map +1 -0
- package/dist/google-tag-manager.js +129 -0
- package/dist/google-tag-manager.js.map +1 -0
- package/dist/i18n.d.ts +69 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +59 -0
- package/dist/i18n.js.map +1 -0
- package/dist/import-export.d.ts +63 -0
- package/dist/import-export.d.ts.map +1 -0
- package/dist/import-export.js +37 -0
- package/dist/import-export.js.map +1 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +126 -0
- package/dist/index.js.map +1 -0
- package/dist/inventory.d.ts +673 -0
- package/dist/inventory.d.ts.map +1 -0
- package/dist/inventory.js +412 -0
- package/dist/inventory.js.map +1 -0
- package/dist/invoice-ledger.d.ts +366 -0
- package/dist/invoice-ledger.d.ts.map +1 -0
- package/dist/invoice-ledger.js +114 -0
- package/dist/invoice-ledger.js.map +1 -0
- package/dist/invoices.d.ts +845 -0
- package/dist/invoices.d.ts.map +1 -0
- package/dist/invoices.js +314 -0
- package/dist/invoices.js.map +1 -0
- package/dist/kernel.d.ts +49 -0
- package/dist/kernel.d.ts.map +1 -0
- package/dist/kernel.js +19 -0
- package/dist/kernel.js.map +1 -0
- package/dist/languages.d.ts +122 -0
- package/dist/languages.d.ts.map +1 -0
- package/dist/languages.js +24 -0
- package/dist/languages.js.map +1 -0
- package/dist/linkedin-ads.d.ts +167 -0
- package/dist/linkedin-ads.d.ts.map +1 -0
- package/dist/linkedin-ads.js +156 -0
- package/dist/linkedin-ads.js.map +1 -0
- package/dist/megamenu.d.ts +556 -0
- package/dist/megamenu.d.ts.map +1 -0
- package/dist/megamenu.js +186 -0
- package/dist/megamenu.js.map +1 -0
- package/dist/meta-ads.d.ts +126 -0
- package/dist/meta-ads.d.ts.map +1 -0
- package/dist/meta-ads.js +112 -0
- package/dist/meta-ads.js.map +1 -0
- package/dist/mfa.d.ts +274 -0
- package/dist/mfa.d.ts.map +1 -0
- package/dist/mfa.js +187 -0
- package/dist/mfa.js.map +1 -0
- package/dist/modules.d.ts +1706 -0
- package/dist/modules.d.ts.map +1 -0
- package/dist/modules.js +1390 -0
- package/dist/modules.js.map +1 -0
- package/dist/newsletter.d.ts +611 -0
- package/dist/newsletter.d.ts.map +1 -0
- package/dist/newsletter.js +345 -0
- package/dist/newsletter.js.map +1 -0
- package/dist/orders.d.ts +1175 -0
- package/dist/orders.d.ts.map +1 -0
- package/dist/orders.js +630 -0
- package/dist/orders.js.map +1 -0
- package/dist/organizations.d.ts +938 -0
- package/dist/organizations.d.ts.map +1 -0
- package/dist/organizations.js +418 -0
- package/dist/organizations.js.map +1 -0
- package/dist/pagination.d.ts +21 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +22 -0
- package/dist/pagination.js.map +1 -0
- package/dist/payment-methods.d.ts +472 -0
- package/dist/payment-methods.d.ts.map +1 -0
- package/dist/payment-methods.js +175 -0
- package/dist/payment-methods.js.map +1 -0
- package/dist/payment-return-url.d.ts +53 -0
- package/dist/payment-return-url.d.ts.map +1 -0
- package/dist/payment-return-url.js +35 -0
- package/dist/payment-return-url.js.map +1 -0
- package/dist/payments.d.ts +386 -0
- package/dist/payments.d.ts.map +1 -0
- package/dist/payments.js +84 -0
- package/dist/payments.js.map +1 -0
- package/dist/pim-connector.d.ts +60 -0
- package/dist/pim-connector.d.ts.map +1 -0
- package/dist/pim-connector.js +43 -0
- package/dist/pim-connector.js.map +1 -0
- package/dist/pim-field-path.d.ts +6 -0
- package/dist/pim-field-path.d.ts.map +1 -0
- package/dist/pim-field-path.js +101 -0
- package/dist/pim-field-path.js.map +1 -0
- package/dist/platform-language.d.ts +20 -0
- package/dist/platform-language.d.ts.map +1 -0
- package/dist/platform-language.js +22 -0
- package/dist/platform-language.js.map +1 -0
- package/dist/price-lists.d.ts +685 -0
- package/dist/price-lists.d.ts.map +1 -0
- package/dist/price-lists.js +330 -0
- package/dist/price-lists.js.map +1 -0
- package/dist/product-feeds.d.ts +2837 -0
- package/dist/product-feeds.d.ts.map +1 -0
- package/dist/product-feeds.js +1504 -0
- package/dist/product-feeds.js.map +1 -0
- package/dist/product-scope-overrides.d.ts +134 -0
- package/dist/product-scope-overrides.d.ts.map +1 -0
- package/dist/product-scope-overrides.js +82 -0
- package/dist/product-scope-overrides.js.map +1 -0
- package/dist/product-value-resolver.d.ts +88 -0
- package/dist/product-value-resolver.d.ts.map +1 -0
- package/dist/product-value-resolver.js +128 -0
- package/dist/product-value-resolver.js.map +1 -0
- package/dist/promotions.d.ts +678 -0
- package/dist/promotions.d.ts.map +1 -0
- package/dist/promotions.js +479 -0
- package/dist/promotions.js.map +1 -0
- package/dist/prompt-actions.d.ts +582 -0
- package/dist/prompt-actions.d.ts.map +1 -0
- package/dist/prompt-actions.js +221 -0
- package/dist/prompt-actions.js.map +1 -0
- package/dist/pwa.d.ts +293 -0
- package/dist/pwa.d.ts.map +1 -0
- package/dist/pwa.js +204 -0
- package/dist/pwa.js.map +1 -0
- package/dist/quick-order.d.ts +340 -0
- package/dist/quick-order.d.ts.map +1 -0
- package/dist/quick-order.js +177 -0
- package/dist/quick-order.js.map +1 -0
- package/dist/quote-requests.d.ts +538 -0
- package/dist/quote-requests.d.ts.map +1 -0
- package/dist/quote-requests.js +308 -0
- package/dist/quote-requests.js.map +1 -0
- package/dist/returns.d.ts +774 -0
- package/dist/returns.d.ts.map +1 -0
- package/dist/returns.js +389 -0
- package/dist/returns.js.map +1 -0
- package/dist/sales-channels.d.ts +392 -0
- package/dist/sales-channels.d.ts.map +1 -0
- package/dist/sales-channels.js +285 -0
- package/dist/sales-channels.js.map +1 -0
- package/dist/scope-notice.d.ts +60 -0
- package/dist/scope-notice.d.ts.map +1 -0
- package/dist/scope-notice.js +56 -0
- package/dist/scope-notice.js.map +1 -0
- package/dist/search.d.ts +321 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +160 -0
- package/dist/search.js.map +1 -0
- package/dist/seo.d.ts +113 -0
- package/dist/seo.d.ts.map +1 -0
- package/dist/seo.js +63 -0
- package/dist/seo.js.map +1 -0
- package/dist/settings.d.ts +453 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +337 -0
- package/dist/settings.js.map +1 -0
- package/dist/shipments.d.ts +140 -0
- package/dist/shipments.d.ts.map +1 -0
- package/dist/shipments.js +14 -0
- package/dist/shipments.js.map +1 -0
- package/dist/shipping-methods.d.ts +350 -0
- package/dist/shipping-methods.d.ts.map +1 -0
- package/dist/shipping-methods.js +99 -0
- package/dist/shipping-methods.js.map +1 -0
- package/dist/shopping-lists.d.ts +122 -0
- package/dist/shopping-lists.d.ts.map +1 -0
- package/dist/shopping-lists.js +92 -0
- package/dist/shopping-lists.js.map +1 -0
- package/dist/taxes.d.ts +106 -0
- package/dist/taxes.d.ts.map +1 -0
- package/dist/taxes.js +80 -0
- package/dist/taxes.js.map +1 -0
- package/dist/text-normalization.d.ts +199 -0
- package/dist/text-normalization.d.ts.map +1 -0
- package/dist/text-normalization.js +205 -0
- package/dist/text-normalization.js.map +1 -0
- package/dist/transactional-emails.d.ts +459 -0
- package/dist/transactional-emails.d.ts.map +1 -0
- package/dist/transactional-emails.js +212 -0
- package/dist/transactional-emails.js.map +1 -0
- package/dist/webhooks.d.ts +69 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +53 -0
- package/dist/webhooks.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One diacritic fold — and, since issue #245, one slug generator — for every
|
|
3
|
+
* package that has to compare or key two spellings of the same word.
|
|
4
|
+
*
|
|
5
|
+
* `foldDiacritics` is the fold (issue #240). `slugify` is the generator built
|
|
6
|
+
* on it, and it replaced **eight** private copies; its own doc block carries
|
|
7
|
+
* the reasons that are specific to slugs. Everything below is about the fold.
|
|
8
|
+
*
|
|
9
|
+
* ## Why this file exists rather than a helper inside one consumer
|
|
10
|
+
*
|
|
11
|
+
* The fold was correct and unreachable. It lived inside
|
|
12
|
+
* `normalizeOrganizationName` in `organizations.ts` — published from
|
|
13
|
+
* `@endora-commerce/contracts`, so importable from `backend/`, `admin/` and `storefront/`
|
|
14
|
+
* alike, but named after **one caller**. Nobody looking for "how do I compare
|
|
15
|
+
* `Łatwy` with `latwy`" searches for an organisation helper, so within a year
|
|
16
|
+
* four private copies had grown in `admin/` (repaired by !745) and two more
|
|
17
|
+
* stand in `backend/` today. Every one of them was the same one-liner and every
|
|
18
|
+
* one of them shipped the same bug.
|
|
19
|
+
*
|
|
20
|
+
* ## The bug the one-liner has
|
|
21
|
+
*
|
|
22
|
+
* ```
|
|
23
|
+
* input.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLowerCase()
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* reads as complete and is not. `ł` is U+0142: a single indivisible code point
|
|
27
|
+
* with **no canonical decomposition**, so NFD leaves it exactly where it was,
|
|
28
|
+
* the strip finds no combining mark to remove, and the `[^a-z0-9]+` pass a
|
|
29
|
+
* slugifier runs next deletes the letter outright — `Łatwy szablon` becomes
|
|
30
|
+
* `atwy-szablon`. The same holds for `Ø ø Đ đ Ð ð Þ þ ß Æ æ Œ œ`. The fix is one
|
|
31
|
+
* extra step, and it is the only reason this is longer than a line: map those
|
|
32
|
+
* letters explicitly.
|
|
33
|
+
*
|
|
34
|
+
* ## A function, not a port
|
|
35
|
+
*
|
|
36
|
+
* It is pure over its argument, so it cannot answer differently depending on
|
|
37
|
+
* which modules are switched on, and a gated port answering 503 `MODULE_DISABLED`
|
|
38
|
+
* to "fold these diacritics" would be a bug rather than a safety property.
|
|
39
|
+
* Node natives only (Principle IV) — a full Unicode-folding library is not worth
|
|
40
|
+
* a dependency for fifteen letters.
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* Latin letters NFD does not decompose, and their ASCII approximations.
|
|
44
|
+
*
|
|
45
|
+
* Every entry is a **single code point** whose Unicode decomposition is empty:
|
|
46
|
+
* a stroked, hooked or ligated letter rather than a base plus a combining mark.
|
|
47
|
+
* That is precisely the set NFD cannot help with, which is why it is hand-written.
|
|
48
|
+
*
|
|
49
|
+
* Exported so a test can enumerate it and a reader can see the whole set at
|
|
50
|
+
* once — not as an invitation to write a second fold around it. Reach for
|
|
51
|
+
* `foldDiacritics` instead; a copy of the map without the decomposition step
|
|
52
|
+
* is half a fold, and half a fold is what this file exists to end.
|
|
53
|
+
*/
|
|
54
|
+
export const NON_DECOMPOSING_LATIN = {
|
|
55
|
+
Ł: 'L',
|
|
56
|
+
ł: 'l',
|
|
57
|
+
Ø: 'O',
|
|
58
|
+
ø: 'o',
|
|
59
|
+
Đ: 'D',
|
|
60
|
+
đ: 'd',
|
|
61
|
+
Ð: 'D',
|
|
62
|
+
ð: 'd',
|
|
63
|
+
Þ: 'Th',
|
|
64
|
+
þ: 'th',
|
|
65
|
+
ß: 'ss',
|
|
66
|
+
Æ: 'AE',
|
|
67
|
+
æ: 'ae',
|
|
68
|
+
Œ: 'OE',
|
|
69
|
+
œ: 'oe',
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Fold a string so two spellings of the same word compare equal: diacritics
|
|
73
|
+
* removed, non-decomposing Latin letters mapped to ASCII, lowercased.
|
|
74
|
+
*
|
|
75
|
+
* In order:
|
|
76
|
+
*
|
|
77
|
+
* 1. **Decompose (NFD)** — separate every base character from its combining
|
|
78
|
+
* marks, so `ó` becomes `o` + U+0301.
|
|
79
|
+
* 2. **Strip the combining marks** via `\p{Diacritic}`.
|
|
80
|
+
* 3. **Map what NFD could not decompose**, per `NON_DECOMPOSING_LATIN`. This
|
|
81
|
+
* step runs **after** the decomposition on purpose: `Ǿ` (U+01FE) decomposes
|
|
82
|
+
* to `Ø` + U+0301, so a map applied first would not see the `Ø` that step 1
|
|
83
|
+
* is about to expose. Mapping first — as `admin/`'s copy did until issue
|
|
84
|
+
* #240 — folds `Ǿ` to `ø` instead of `o`.
|
|
85
|
+
* 4. **Lowercase.** Callers compare case-insensitively without exception, and
|
|
86
|
+
* the ASCII expansions above (`Th`, `AE`, `OE`) have to be lowered anyway.
|
|
87
|
+
*
|
|
88
|
+
* Whitespace is deliberately **not** touched: what counts as one space is the
|
|
89
|
+
* caller's policy, not the fold's. `normalizeOrganizationName` collapses runs
|
|
90
|
+
* and trims because it writes a search column; `admin`'s `normalize` only
|
|
91
|
+
* trims. Both compose it here rather than each folding its own way.
|
|
92
|
+
*
|
|
93
|
+
* Not a case-folding routine in the Unicode sense: it lowercases, it does not
|
|
94
|
+
* apply full case folding, and anything outside Latin (Cyrillic, CJK, Greek)
|
|
95
|
+
* passes through with its case lowered and nothing else changed.
|
|
96
|
+
*/
|
|
97
|
+
export function foldDiacritics(input) {
|
|
98
|
+
const stripped = input.normalize('NFD').replace(/\p{Diacritic}/gu, '');
|
|
99
|
+
let mapped = '';
|
|
100
|
+
for (const character of stripped) {
|
|
101
|
+
mapped += NON_DECOMPOSING_LATIN[character] ?? character;
|
|
102
|
+
}
|
|
103
|
+
return mapped.toLowerCase();
|
|
104
|
+
}
|
|
105
|
+
/** Escape a separator so it can sit inside a character class. */
|
|
106
|
+
function escapeForRegExp(literal) {
|
|
107
|
+
return literal.replace(/[.*+?^${}()|[\]\\-]/g, '\\$&');
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The repository's one slug generator (issue #245).
|
|
111
|
+
*
|
|
112
|
+
* There were **eight**: three in `backend/`, five in `admin/`, each a private
|
|
113
|
+
* four-line chain that read as obviously right. Two of them
|
|
114
|
+
* (`cms-template-layout.ts`, `pim_ergonode`'s `slugFromSourceCode`) had no fold
|
|
115
|
+
* step at all — `Żółw` produced `w` and `Świeże Ćwikła` produced `wie-e-wik-a`
|
|
116
|
+
* — and `check:diacritic-folds` was structurally blind to both, because it
|
|
117
|
+
* counts folds written *outside* the shared helper and a site that folds
|
|
118
|
+
* nothing writes none. A shared generator is what makes "does this slug fold?"
|
|
119
|
+
* a question with one answer.
|
|
120
|
+
*
|
|
121
|
+
* The steps, in order:
|
|
122
|
+
*
|
|
123
|
+
* 1. **Fold** via `foldDiacritics` — decompose, strip the combining marks, map
|
|
124
|
+
* the letters NFD leaves standing, lowercase.
|
|
125
|
+
* 2. **Collapse** every run of `[^a-z0-9]` — minus whatever `preserve` adds to
|
|
126
|
+
* the usable set — to the separator.
|
|
127
|
+
* 3. **Strip a leading separator**, before the slice — a leading separator can
|
|
128
|
+
* never survive, so it must not spend a character of the caller's budget.
|
|
129
|
+
* 4. **Slice** to `maxLength`, when the caller has one.
|
|
130
|
+
* 5. **Strip trailing separators**, after the slice — the cut can *create* one,
|
|
131
|
+
* which is the whole point (see below).
|
|
132
|
+
* 6. **Fall back** when nothing survived.
|
|
133
|
+
*
|
|
134
|
+
* ## NFD, not NFKD, and that is a decision
|
|
135
|
+
*
|
|
136
|
+
* Three of the eight normalised with `NFKD`, which additionally maps the
|
|
137
|
+
* compatibility characters: `fi` to `fi`, `²` to `2`, the full-width forms to
|
|
138
|
+
* their ASCII. Those mappings reach a slug **only** through characters that map
|
|
139
|
+
* *into* `[a-z0-9]`, and none of them is typed into a product name, a feed
|
|
140
|
+
* template name or a CMS page title. Where one does appear it now collapses to
|
|
141
|
+
* the separator rather than to a letter, so the slug stays legal and merely
|
|
142
|
+
* loses a character nobody could see in it. Against that, `ł` was being deleted
|
|
143
|
+
* out of every Polish name those three touched. The trade was taken for the
|
|
144
|
+
* admin pair in !753 and holds identically here.
|
|
145
|
+
*
|
|
146
|
+
* It has one consequence worth naming: two inputs `NFKD` kept apart can now
|
|
147
|
+
* fold together (`Kabel²` and `Kabel³` both become `kabel`). Every caller whose
|
|
148
|
+
* slug is unique-constrained already allocates against the live table —
|
|
149
|
+
* `CatalogAdminService.allocateUniqueSlug`, `pim_ergonode`'s
|
|
150
|
+
* `createWithFreeSlug` — so the second one is suffixed rather than rejected,
|
|
151
|
+
* exactly as two products sharing a plain name already are.
|
|
152
|
+
*
|
|
153
|
+
* ## The trailing strip runs after the slice, which is a change for six sites
|
|
154
|
+
*
|
|
155
|
+
* Six of the eight stripped **both** edge separators before cutting to length,
|
|
156
|
+
* so a cut landing on a separator left the slug ending in one:
|
|
157
|
+
* `...w-wersji-rozszerzona-`. Only `BlockEditor` and `PageEditor` had it right.
|
|
158
|
+
* This is the one change here that is not about diacritics; it shows only on an
|
|
159
|
+
* input long enough to be truncated, and it makes the result satisfy the kebab
|
|
160
|
+
* grammar (`^[a-z0-9]+(?:-[a-z0-9]+)*$`) that `pim_ergonode`'s own doc block
|
|
161
|
+
* already claimed for it.
|
|
162
|
+
*
|
|
163
|
+
* The **leading** strip stays where all eight had it — before the slice — for a
|
|
164
|
+
* reason that is not symmetry: a leading separator is never part of the answer,
|
|
165
|
+
* so letting it consume a character of `maxLength` would shorten every slug
|
|
166
|
+
* whose input begins with punctuation by one, in six sites at once, for no
|
|
167
|
+
* gain. Only the trailing edge can be *created* by the cut, so only the
|
|
168
|
+
* trailing strip has to run after it.
|
|
169
|
+
*
|
|
170
|
+
* Historical values are **not** migrated (owner's ruling, 2026-08-19,
|
|
171
|
+
* originally for the admin pair in !753 and extended to the rest): only two
|
|
172
|
+
* developer environments exist, so re-slugging live rows buys nobody anything,
|
|
173
|
+
* and every one of these values is computed fresh at create time rather than
|
|
174
|
+
* re-derived to look an existing row up. New values are correct from here on.
|
|
175
|
+
*
|
|
176
|
+
* **`pim_ergonode` is the exception the ruling names, and it is the reason
|
|
177
|
+
* `preserve` exists.** Its two derivations are re-derived on every import run
|
|
178
|
+
* *to find the row a previous run created*, so a changed derivation orphans the
|
|
179
|
+
* row rather than improving it. Those values are migrated (issue #260), and the
|
|
180
|
+
* migration is only affordable because the derivation change is confined to the
|
|
181
|
+
* fold — which is what `preserve` buys.
|
|
182
|
+
*
|
|
183
|
+
* `normalizeOrganizationName` is **not** a caller and must not become one: it
|
|
184
|
+
* writes the persisted `organizations.name_search` column, which is a folded
|
|
185
|
+
* name rather than a slug.
|
|
186
|
+
*/
|
|
187
|
+
export function slugify(input, options = {}) {
|
|
188
|
+
const separator = options.separator ?? '-';
|
|
189
|
+
const escaped = escapeForRegExp(separator);
|
|
190
|
+
const usable = escapeForRegExp(options.preserve ?? '');
|
|
191
|
+
const folded = foldDiacritics(input);
|
|
192
|
+
// Two spellings of one step, and the branch is not a micro-optimisation. The
|
|
193
|
+
// default has to stay a **literal** `.replace(/[^a-z0-9]+/g, …)`, because
|
|
194
|
+
// that expression is what `check:diacritic-folds` reads to know this file is
|
|
195
|
+
// still the slug generator it exempts: its vacuous-pass guard cannot read a
|
|
196
|
+
// pattern built from a template, and a guard that cannot see the owner
|
|
197
|
+
// reports every private copy of it as fine (issue #244's whole point).
|
|
198
|
+
const collapsed = (usable.length === 0
|
|
199
|
+
? folded.replace(/[^a-z0-9]+/g, separator)
|
|
200
|
+
: folded.replace(new RegExp(`[^a-z0-9${usable}]+`, 'g'), separator)).replace(new RegExp(`^(?:${escaped})+`), '');
|
|
201
|
+
const sliced = options.maxLength === undefined ? collapsed : collapsed.slice(0, options.maxLength);
|
|
202
|
+
const trimmed = sliced.replace(new RegExp(`(?:${escaped})+$`), '');
|
|
203
|
+
return trimmed.length > 0 ? trimmed : (options.fallback ?? '');
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=text-normalization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-normalization.js","sourceRoot":"","sources":["../src/text-normalization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAqC;IACrE,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;CACR,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;IACvE,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,MAAM,SAAS,IAAI,QAAQ,EAAE,CAAC;QACjC,MAAM,IAAI,qBAAqB,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC;IAC1D,CAAC;IACD,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC;AAC9B,CAAC;AAyCD,iEAAiE;AACjE,SAAS,eAAe,CAAC,OAAe;IACtC,OAAO,OAAO,CAAC,OAAO,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6EG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa,EAAE,UAA0B,EAAE;IACjE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,GAAG,CAAC;IAC3C,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACrC,6EAA6E;IAC7E,0EAA0E;IAC1E,6EAA6E;IAC7E,4EAA4E;IAC5E,uEAAuE;IACvE,uEAAuE;IACvE,MAAM,SAAS,GAAG,CAChB,MAAM,CAAC,MAAM,KAAK,CAAC;QACjB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC;QAC1C,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,WAAW,MAAM,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,CAAC,CACtE,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,OAAO,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACnG,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,MAAM,OAAO,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IACnE,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** Opaque Puck data tree for one language. */
|
|
3
|
+
export declare const puckDataTreeSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
4
|
+
export type PuckDataTreeDto = z.infer<typeof puckDataTreeSchema>;
|
|
5
|
+
export declare const transactionalEmailCodeRe: RegExp;
|
|
6
|
+
/** A variable an email declares for substitution + preview sample data. */
|
|
7
|
+
export declare const emailVariableDescriptorSchema: z.ZodObject<{
|
|
8
|
+
key: z.ZodString;
|
|
9
|
+
label: z.ZodString;
|
|
10
|
+
sampleValue: z.ZodOptional<z.ZodString>;
|
|
11
|
+
description: z.ZodOptional<z.ZodString>;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
export type EmailVariableDescriptor = z.infer<typeof emailVariableDescriptorSchema>;
|
|
14
|
+
export declare const transactionalEmailManifestEntrySchema: z.ZodObject<{
|
|
15
|
+
code: z.ZodString;
|
|
16
|
+
name: z.ZodString;
|
|
17
|
+
description: z.ZodOptional<z.ZodString>;
|
|
18
|
+
group: z.ZodOptional<z.ZodString>;
|
|
19
|
+
variables: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
20
|
+
key: z.ZodString;
|
|
21
|
+
label: z.ZodString;
|
|
22
|
+
sampleValue: z.ZodOptional<z.ZodString>;
|
|
23
|
+
description: z.ZodOptional<z.ZodString>;
|
|
24
|
+
}, z.core.$strip>>>;
|
|
25
|
+
}, z.core.$strip>;
|
|
26
|
+
export type TransactionalEmailManifestEntry = z.infer<typeof transactionalEmailManifestEntrySchema>;
|
|
27
|
+
/**
|
|
28
|
+
* Whether an operator may switch this one email off, and why not (issue #89).
|
|
29
|
+
*
|
|
30
|
+
* Deliberately the same pair of field names `ModulePresenceSchema` uses for the
|
|
31
|
+
* module axis: the two refusals are the same statement at two granularities,
|
|
32
|
+
* and an admin that renders one can render the other without learning a second
|
|
33
|
+
* vocabulary. The reason is the owning module's own sentence, carried from the
|
|
34
|
+
* `EmailDefaultsRegistry` — no frontend holds a list of protected codes.
|
|
35
|
+
*/
|
|
36
|
+
export declare const transactionalEmailProtectionSchema: z.ZodObject<{
|
|
37
|
+
deactivatable: z.ZodBoolean;
|
|
38
|
+
nonDeactivatableReason: z.ZodNullable<z.ZodString>;
|
|
39
|
+
}, z.core.$strip>;
|
|
40
|
+
export declare const transactionalEmailSummarySchema: z.ZodObject<{
|
|
41
|
+
code: z.ZodString;
|
|
42
|
+
name: z.ZodString;
|
|
43
|
+
ownerModule: z.ZodString;
|
|
44
|
+
group: z.ZodNullable<z.ZodString>;
|
|
45
|
+
active: z.ZodBoolean;
|
|
46
|
+
languages: z.ZodArray<z.ZodString>;
|
|
47
|
+
hasGlobalOverride: z.ZodBoolean;
|
|
48
|
+
hasChannelOverride: z.ZodBoolean;
|
|
49
|
+
deactivatable: z.ZodBoolean;
|
|
50
|
+
nonDeactivatableReason: z.ZodNullable<z.ZodString>;
|
|
51
|
+
}, z.core.$strip>;
|
|
52
|
+
export type TransactionalEmailSummary = z.infer<typeof transactionalEmailSummarySchema>;
|
|
53
|
+
export declare const transactionalEmailListResponseSchema: z.ZodObject<{
|
|
54
|
+
items: z.ZodArray<z.ZodObject<{
|
|
55
|
+
code: z.ZodString;
|
|
56
|
+
name: z.ZodString;
|
|
57
|
+
ownerModule: z.ZodString;
|
|
58
|
+
group: z.ZodNullable<z.ZodString>;
|
|
59
|
+
active: z.ZodBoolean;
|
|
60
|
+
languages: z.ZodArray<z.ZodString>;
|
|
61
|
+
hasGlobalOverride: z.ZodBoolean;
|
|
62
|
+
hasChannelOverride: z.ZodBoolean;
|
|
63
|
+
deactivatable: z.ZodBoolean;
|
|
64
|
+
nonDeactivatableReason: z.ZodNullable<z.ZodString>;
|
|
65
|
+
}, z.core.$strip>>;
|
|
66
|
+
}, z.core.$strip>;
|
|
67
|
+
export type TransactionalEmailListResponse = z.infer<typeof transactionalEmailListResponseSchema>;
|
|
68
|
+
export declare const resolvedEmailContentSchema: z.ZodObject<{
|
|
69
|
+
subject: z.ZodString;
|
|
70
|
+
content: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
71
|
+
source: z.ZodEnum<{
|
|
72
|
+
default: "default";
|
|
73
|
+
channel: "channel";
|
|
74
|
+
global: "global";
|
|
75
|
+
}>;
|
|
76
|
+
version: z.ZodNullable<z.ZodNumber>;
|
|
77
|
+
}, z.core.$strip>;
|
|
78
|
+
export type ResolvedEmailContent = z.infer<typeof resolvedEmailContentSchema>;
|
|
79
|
+
export declare const transactionalEmailDetailSchema: z.ZodObject<{
|
|
80
|
+
code: z.ZodString;
|
|
81
|
+
name: z.ZodString;
|
|
82
|
+
ownerModule: z.ZodString;
|
|
83
|
+
group: z.ZodNullable<z.ZodString>;
|
|
84
|
+
description: z.ZodNullable<z.ZodString>;
|
|
85
|
+
active: z.ZodBoolean;
|
|
86
|
+
languages: z.ZodArray<z.ZodString>;
|
|
87
|
+
variables: z.ZodArray<z.ZodObject<{
|
|
88
|
+
key: z.ZodString;
|
|
89
|
+
label: z.ZodString;
|
|
90
|
+
sampleValue: z.ZodOptional<z.ZodString>;
|
|
91
|
+
description: z.ZodOptional<z.ZodString>;
|
|
92
|
+
}, z.core.$strip>>;
|
|
93
|
+
scope: z.ZodObject<{
|
|
94
|
+
salesChannelId: z.ZodNullable<z.ZodString>;
|
|
95
|
+
language: z.ZodString;
|
|
96
|
+
}, z.core.$strip>;
|
|
97
|
+
effective: z.ZodObject<{
|
|
98
|
+
subject: z.ZodString;
|
|
99
|
+
content: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
100
|
+
source: z.ZodEnum<{
|
|
101
|
+
default: "default";
|
|
102
|
+
channel: "channel";
|
|
103
|
+
global: "global";
|
|
104
|
+
}>;
|
|
105
|
+
version: z.ZodNullable<z.ZodNumber>;
|
|
106
|
+
}, z.core.$strip>;
|
|
107
|
+
default: z.ZodObject<{
|
|
108
|
+
subject: z.ZodString;
|
|
109
|
+
content: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
110
|
+
}, z.core.$strip>;
|
|
111
|
+
hasGlobalOverride: z.ZodBoolean;
|
|
112
|
+
hasChannelOverride: z.ZodBoolean;
|
|
113
|
+
deactivatable: z.ZodBoolean;
|
|
114
|
+
nonDeactivatableReason: z.ZodNullable<z.ZodString>;
|
|
115
|
+
}, z.core.$strip>;
|
|
116
|
+
export type TransactionalEmailDetail = z.infer<typeof transactionalEmailDetailSchema>;
|
|
117
|
+
export declare const transactionalEmailDetailQuerySchema: z.ZodObject<{
|
|
118
|
+
salesChannelId: z.ZodOptional<z.ZodString>;
|
|
119
|
+
language: z.ZodOptional<z.ZodString>;
|
|
120
|
+
}, z.core.$strip>;
|
|
121
|
+
export type TransactionalEmailDetailQuery = z.infer<typeof transactionalEmailDetailQuerySchema>;
|
|
122
|
+
export declare const putEmailContentQuerySchema: z.ZodObject<{
|
|
123
|
+
salesChannelId: z.ZodOptional<z.ZodString>;
|
|
124
|
+
language: z.ZodString;
|
|
125
|
+
}, z.core.$strip>;
|
|
126
|
+
export type PutEmailContentQuery = z.infer<typeof putEmailContentQuerySchema>;
|
|
127
|
+
export declare const putEmailContentRequestSchema: z.ZodObject<{
|
|
128
|
+
subject: z.ZodString;
|
|
129
|
+
content: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
130
|
+
expectedVersion: z.ZodOptional<z.ZodNumber>;
|
|
131
|
+
}, z.core.$strip>;
|
|
132
|
+
export type PutEmailContentRequest = z.infer<typeof putEmailContentRequestSchema>;
|
|
133
|
+
/**
|
|
134
|
+
* The operator's per-email on/off switch.
|
|
135
|
+
*
|
|
136
|
+
* The module that owns this surface is non-deactivatable (issue #88), because
|
|
137
|
+
* the granularity the business wants is this one: an operator silences the
|
|
138
|
+
* back-in-stock notice without silencing account verification. The read side
|
|
139
|
+
* has honoured `active` since feature 047; this is the write side.
|
|
140
|
+
*
|
|
141
|
+
* Shaped like `ModuleActivationRequestSchema` — one boolean, stated rather than
|
|
142
|
+
* toggled, so a retry lands on the state the operator asked for instead of the
|
|
143
|
+
* opposite one.
|
|
144
|
+
*/
|
|
145
|
+
export declare const setTransactionalEmailActiveRequestSchema: z.ZodObject<{
|
|
146
|
+
active: z.ZodBoolean;
|
|
147
|
+
}, z.core.$strip>;
|
|
148
|
+
export type SetTransactionalEmailActiveRequest = z.infer<typeof setTransactionalEmailActiveRequestSchema>;
|
|
149
|
+
/** The recomputed summary, so the list re-reads what the server resolved. */
|
|
150
|
+
export declare const setTransactionalEmailActiveResponseSchema: z.ZodObject<{
|
|
151
|
+
code: z.ZodString;
|
|
152
|
+
name: z.ZodString;
|
|
153
|
+
ownerModule: z.ZodString;
|
|
154
|
+
group: z.ZodNullable<z.ZodString>;
|
|
155
|
+
active: z.ZodBoolean;
|
|
156
|
+
languages: z.ZodArray<z.ZodString>;
|
|
157
|
+
hasGlobalOverride: z.ZodBoolean;
|
|
158
|
+
hasChannelOverride: z.ZodBoolean;
|
|
159
|
+
deactivatable: z.ZodBoolean;
|
|
160
|
+
nonDeactivatableReason: z.ZodNullable<z.ZodString>;
|
|
161
|
+
}, z.core.$strip>;
|
|
162
|
+
export type SetTransactionalEmailActiveResponse = z.infer<typeof setTransactionalEmailActiveResponseSchema>;
|
|
163
|
+
export declare const previewEmailRequestSchema: z.ZodObject<{
|
|
164
|
+
salesChannelId: z.ZodOptional<z.ZodString>;
|
|
165
|
+
language: z.ZodOptional<z.ZodString>;
|
|
166
|
+
draftSubject: z.ZodOptional<z.ZodString>;
|
|
167
|
+
draftContent: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
168
|
+
}, z.core.$strip>;
|
|
169
|
+
export type PreviewEmailRequest = z.infer<typeof previewEmailRequestSchema>;
|
|
170
|
+
export declare const previewEmailResponseSchema: z.ZodObject<{
|
|
171
|
+
subject: z.ZodString;
|
|
172
|
+
html: z.ZodString;
|
|
173
|
+
text: z.ZodString;
|
|
174
|
+
}, z.core.$strip>;
|
|
175
|
+
export type PreviewEmailResponse = z.infer<typeof previewEmailResponseSchema>;
|
|
176
|
+
export declare const emailBlockSummarySchema: z.ZodObject<{
|
|
177
|
+
id: z.ZodString;
|
|
178
|
+
code: z.ZodString;
|
|
179
|
+
name: z.ZodString;
|
|
180
|
+
active: z.ZodBoolean;
|
|
181
|
+
isSystem: z.ZodBoolean;
|
|
182
|
+
scope: z.ZodEnum<{
|
|
183
|
+
channel: "channel";
|
|
184
|
+
global: "global";
|
|
185
|
+
}>;
|
|
186
|
+
languages: z.ZodArray<z.ZodString>;
|
|
187
|
+
version: z.ZodNumber;
|
|
188
|
+
}, z.core.$strip>;
|
|
189
|
+
export type EmailBlockSummary = z.infer<typeof emailBlockSummarySchema>;
|
|
190
|
+
export declare const emailBlockDetailSchema: z.ZodObject<{
|
|
191
|
+
id: z.ZodString;
|
|
192
|
+
code: z.ZodString;
|
|
193
|
+
name: z.ZodString;
|
|
194
|
+
active: z.ZodBoolean;
|
|
195
|
+
isSystem: z.ZodBoolean;
|
|
196
|
+
scope: z.ZodEnum<{
|
|
197
|
+
channel: "channel";
|
|
198
|
+
global: "global";
|
|
199
|
+
}>;
|
|
200
|
+
languages: z.ZodArray<z.ZodString>;
|
|
201
|
+
version: z.ZodNumber;
|
|
202
|
+
description: z.ZodNullable<z.ZodString>;
|
|
203
|
+
content: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
204
|
+
salesChannelIds: z.ZodArray<z.ZodString>;
|
|
205
|
+
}, z.core.$strip>;
|
|
206
|
+
export type EmailBlockDetail = z.infer<typeof emailBlockDetailSchema>;
|
|
207
|
+
export declare const createEmailBlockRequestSchema: z.ZodObject<{
|
|
208
|
+
code: z.ZodString;
|
|
209
|
+
name: z.ZodString;
|
|
210
|
+
description: z.ZodOptional<z.ZodString>;
|
|
211
|
+
active: z.ZodOptional<z.ZodBoolean>;
|
|
212
|
+
salesChannelIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
213
|
+
languages: z.ZodArray<z.ZodString>;
|
|
214
|
+
}, z.core.$strip>;
|
|
215
|
+
export type CreateEmailBlockRequest = z.infer<typeof createEmailBlockRequestSchema>;
|
|
216
|
+
export declare const patchEmailBlockRequestSchema: z.ZodObject<{
|
|
217
|
+
name: z.ZodOptional<z.ZodString>;
|
|
218
|
+
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
219
|
+
active: z.ZodOptional<z.ZodBoolean>;
|
|
220
|
+
salesChannelIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
221
|
+
expectedVersion: z.ZodOptional<z.ZodNumber>;
|
|
222
|
+
}, z.core.$strip>;
|
|
223
|
+
export type PatchEmailBlockRequest = z.infer<typeof patchEmailBlockRequestSchema>;
|
|
224
|
+
export declare const putEmailBlockContentRequestSchema: z.ZodObject<{
|
|
225
|
+
content: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
226
|
+
expectedVersion: z.ZodNumber;
|
|
227
|
+
}, z.core.$strip>;
|
|
228
|
+
export type PutEmailBlockContentRequest = z.infer<typeof putEmailBlockContentRequestSchema>;
|
|
229
|
+
export declare const emailTemplateSummarySchema: z.ZodObject<{
|
|
230
|
+
version: z.ZodNumber;
|
|
231
|
+
languages: z.ZodArray<z.ZodString>;
|
|
232
|
+
id: z.ZodString;
|
|
233
|
+
code: z.ZodString;
|
|
234
|
+
name: z.ZodString;
|
|
235
|
+
isSystem: z.ZodBoolean;
|
|
236
|
+
scope: z.ZodEnum<{
|
|
237
|
+
channel: "channel";
|
|
238
|
+
global: "global";
|
|
239
|
+
}>;
|
|
240
|
+
}, z.core.$strip>;
|
|
241
|
+
export type EmailTemplateSummary = z.infer<typeof emailTemplateSummarySchema>;
|
|
242
|
+
export declare const emailTemplateDetailSchema: z.ZodObject<{
|
|
243
|
+
version: z.ZodNumber;
|
|
244
|
+
languages: z.ZodArray<z.ZodString>;
|
|
245
|
+
id: z.ZodString;
|
|
246
|
+
description: z.ZodNullable<z.ZodString>;
|
|
247
|
+
code: z.ZodString;
|
|
248
|
+
name: z.ZodString;
|
|
249
|
+
isSystem: z.ZodBoolean;
|
|
250
|
+
scope: z.ZodEnum<{
|
|
251
|
+
channel: "channel";
|
|
252
|
+
global: "global";
|
|
253
|
+
}>;
|
|
254
|
+
content: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
255
|
+
salesChannelIds: z.ZodArray<z.ZodString>;
|
|
256
|
+
}, z.core.$strip>;
|
|
257
|
+
export type EmailTemplateDetail = z.infer<typeof emailTemplateDetailSchema>;
|
|
258
|
+
export declare const createEmailTemplateRequestSchema: z.ZodObject<{
|
|
259
|
+
languages: z.ZodArray<z.ZodString>;
|
|
260
|
+
description: z.ZodOptional<z.ZodString>;
|
|
261
|
+
code: z.ZodString;
|
|
262
|
+
name: z.ZodString;
|
|
263
|
+
salesChannelIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
264
|
+
}, z.core.$strip>;
|
|
265
|
+
export type CreateEmailTemplateRequest = z.infer<typeof createEmailTemplateRequestSchema>;
|
|
266
|
+
export declare const patchEmailTemplateRequestSchema: z.ZodObject<{
|
|
267
|
+
name: z.ZodOptional<z.ZodString>;
|
|
268
|
+
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
269
|
+
salesChannelIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
270
|
+
expectedVersion: z.ZodOptional<z.ZodNumber>;
|
|
271
|
+
}, z.core.$strip>;
|
|
272
|
+
export type PatchEmailTemplateRequest = z.infer<typeof patchEmailTemplateRequestSchema>;
|
|
273
|
+
export declare const emailBrandingSchema: z.ZodObject<{
|
|
274
|
+
salesChannelId: z.ZodNullable<z.ZodString>;
|
|
275
|
+
logoAssetId: z.ZodString;
|
|
276
|
+
logoUrl: z.ZodString;
|
|
277
|
+
accentColor: z.ZodString;
|
|
278
|
+
headerBlockCode: z.ZodString;
|
|
279
|
+
footerBlockCode: z.ZodString;
|
|
280
|
+
source: z.ZodEnum<{
|
|
281
|
+
default: "default";
|
|
282
|
+
channel: "channel";
|
|
283
|
+
global: "global";
|
|
284
|
+
}>;
|
|
285
|
+
}, z.core.$strip>;
|
|
286
|
+
export type EmailBranding = z.infer<typeof emailBrandingSchema>;
|
|
287
|
+
export declare const putEmailBrandingRequestSchema: z.ZodObject<{
|
|
288
|
+
logoAssetId: z.ZodOptional<z.ZodString>;
|
|
289
|
+
accentColor: z.ZodOptional<z.ZodString>;
|
|
290
|
+
headerBlockCode: z.ZodOptional<z.ZodString>;
|
|
291
|
+
footerBlockCode: z.ZodOptional<z.ZodString>;
|
|
292
|
+
}, z.core.$strip>;
|
|
293
|
+
export type PutEmailBrandingRequest = z.infer<typeof putEmailBrandingRequestSchema>;
|
|
294
|
+
export declare const emailScopeQuerySchema: z.ZodObject<{
|
|
295
|
+
salesChannelId: z.ZodOptional<z.ZodString>;
|
|
296
|
+
}, z.core.$strip>;
|
|
297
|
+
export type EmailScopeQuery = z.infer<typeof emailScopeQuerySchema>;
|
|
298
|
+
export declare const emailPageBuilderDescriptorSchema: z.ZodObject<{
|
|
299
|
+
schemaVersion: z.ZodNumber;
|
|
300
|
+
components: z.ZodArray<z.ZodObject<{
|
|
301
|
+
name: z.ZodString;
|
|
302
|
+
previewIcon: z.ZodOptional<z.ZodString>;
|
|
303
|
+
}, z.core.$strip>>;
|
|
304
|
+
}, z.core.$strip>;
|
|
305
|
+
export type EmailPageBuilderDescriptor = z.infer<typeof emailPageBuilderDescriptorSchema>;
|
|
306
|
+
export interface TransactionalEmailSendInput {
|
|
307
|
+
code: string;
|
|
308
|
+
/**
|
|
309
|
+
* The channel whose content, branding and embeds apply, or `null` for the
|
|
310
|
+
* platform-wide ones.
|
|
311
|
+
*
|
|
312
|
+
* Widened from `string` (issue #103). The sender's own resolution chain has
|
|
313
|
+
* always been channel → global → default and has always spelled "global" as
|
|
314
|
+
* `null`; only this input type could not say it, so `invoices` passed `''`,
|
|
315
|
+
* which the settings seam guard rejects — the branding read threw, the
|
|
316
|
+
* dispatcher's `catch` absorbed it, and the invoice e-mail vanished.
|
|
317
|
+
*/
|
|
318
|
+
salesChannelId: string | null;
|
|
319
|
+
language: string;
|
|
320
|
+
to: string;
|
|
321
|
+
variables: Record<string, unknown>;
|
|
322
|
+
/** Idempotency key — preserve the per-email message id used today. */
|
|
323
|
+
messageId: string;
|
|
324
|
+
/**
|
|
325
|
+
* Optional binary attachments (feature 047 invoices — PDF delivery). Uses
|
|
326
|
+
* `Uint8Array` (not Node's `Buffer`) so this shared contract stays
|
|
327
|
+
* browser-safe for the api-client; a backend `Buffer` satisfies it.
|
|
328
|
+
*/
|
|
329
|
+
attachments?: Array<{
|
|
330
|
+
filename: string;
|
|
331
|
+
content: Uint8Array;
|
|
332
|
+
contentType?: string;
|
|
333
|
+
}>;
|
|
334
|
+
/**
|
|
335
|
+
* The business document this message delivers, when it delivers one (D-59).
|
|
336
|
+
* Forwarded to the transport so the delivery record is findable by the
|
|
337
|
+
* document an operator is asked about — an invoice, in the case the ruling
|
|
338
|
+
* was written for — rather than only by a recipient and a message id.
|
|
339
|
+
*/
|
|
340
|
+
document?: {
|
|
341
|
+
type: string;
|
|
342
|
+
id: string;
|
|
343
|
+
};
|
|
344
|
+
meta?: Record<string, unknown>;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Why a send did — or did not — reach the transport.
|
|
348
|
+
*
|
|
349
|
+
* `send` used to answer `Promise<void>` for four unrelated situations, so a
|
|
350
|
+
* caller could not tell "the operator switched this email off" from "no
|
|
351
|
+
* template exists for this code yet". Only the latter justifies falling back to
|
|
352
|
+
* a caller's legacy in-code builder; the others mean the platform deliberately
|
|
353
|
+
* sent nothing and a fallback would send mail the operator did not ask for.
|
|
354
|
+
*/
|
|
355
|
+
export type TransactionalSendOutcome =
|
|
356
|
+
/** Handed to the transport. */
|
|
357
|
+
{
|
|
358
|
+
status: 'sent';
|
|
359
|
+
}
|
|
360
|
+
/** The definition exists and an operator set `active = false`. */
|
|
361
|
+
| {
|
|
362
|
+
status: 'deactivated';
|
|
363
|
+
}
|
|
364
|
+
/** No mailer is wired in this composition — nothing can be delivered. */
|
|
365
|
+
| {
|
|
366
|
+
status: 'no_transport';
|
|
367
|
+
}
|
|
368
|
+
/** No definition for this code: the caller may use its own builder. */
|
|
369
|
+
| {
|
|
370
|
+
status: 'no_definition';
|
|
371
|
+
};
|
|
372
|
+
export interface TransactionalEmailSender {
|
|
373
|
+
/**
|
|
374
|
+
* An implementor must say which of the four happened — reporting nothing
|
|
375
|
+
* while delivering nothing is the defect this type exists to close. A
|
|
376
|
+
* deployment decoration that still answers `void` stops compiling against
|
|
377
|
+
* this interface, and that compile break is the intended signal.
|
|
378
|
+
*/
|
|
379
|
+
send(input: TransactionalEmailSendInput): Promise<TransactionalSendOutcome>;
|
|
380
|
+
}
|
|
381
|
+
/** The subject and body a module ships for one of its own e-mails. */
|
|
382
|
+
export interface EmailDefaults {
|
|
383
|
+
/** Per-language subject: `{ lang: string }`. */
|
|
384
|
+
defaultSubject: Record<string, string>;
|
|
385
|
+
/** Content envelope: `{ schema_version, languages: { lang: tree } }`. */
|
|
386
|
+
defaultContent: Record<string, unknown>;
|
|
387
|
+
/**
|
|
388
|
+
* Declared exactly when this individual e-mail may never be switched off
|
|
389
|
+
* (issue #89) — the per-e-mail twin of a manifest's
|
|
390
|
+
* `activation.nonDeactivatable`, and named after it on purpose.
|
|
391
|
+
*
|
|
392
|
+
* It lives **here**, on the contribution the owning module already pushes,
|
|
393
|
+
* rather than as a list in `transactional_emails` or in the admin app: only
|
|
394
|
+
* the module that sends the e-mail knows whether its flow survives silence,
|
|
395
|
+
* and a list anywhere else is a second source of truth that drifts the first
|
|
396
|
+
* time a module adds one.
|
|
397
|
+
*
|
|
398
|
+
* Presence carries the "true": a shape with a separate boolean and a reason
|
|
399
|
+
* has a state where the two contradict each other, and this one does not.
|
|
400
|
+
*/
|
|
401
|
+
nonDeactivatable?: {
|
|
402
|
+
reason: string;
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Container name: `emailDefaultsPort`. Owner: `transactional_emails`.
|
|
407
|
+
*
|
|
408
|
+
* A **contribution seam**, and the most-contributed-to one in the tree: seven
|
|
409
|
+
* modules push the defaults for their own e-mails from `ctx.onBoot`, and this
|
|
410
|
+
* module's boot reconciler reads the table once.
|
|
411
|
+
*
|
|
412
|
+
* The ordering is by construction rather than by luck — boot hooks run during
|
|
413
|
+
* composition and plugin bodies only when the Fastify app is built, so every
|
|
414
|
+
* contribution lands before the read. Publishing the shape must not change
|
|
415
|
+
* that, and must not gate it: a gate would throw during composition, exactly
|
|
416
|
+
* as `assetReferenceRegistry`'s did before it was un-gated.
|
|
417
|
+
*
|
|
418
|
+
* **Owner off:** nothing throws here. This is a **contribution seam**, a plain
|
|
419
|
+
* `di.register` rather than a `providePort`, so a push still lands and
|
|
420
|
+
* `transactional_emails` filters by contributor when it enumerates. Converting it to
|
|
421
|
+
* `providePort` would move every edge into it from `contributes` to
|
|
422
|
+
* `fails-closed` in the deactivation-consequence ledger, and change the
|
|
423
|
+
* sentence the operator's confirmation dialog renders.
|
|
424
|
+
*/
|
|
425
|
+
export interface EmailDefaultsRegistryPort {
|
|
426
|
+
register(code: string, defaults: EmailDefaults, ownerModuleId: string): void;
|
|
427
|
+
get(code: string): EmailDefaults | undefined;
|
|
428
|
+
has(code: string): boolean;
|
|
429
|
+
/** Which module contributed the code, or `undefined` when nobody did. */
|
|
430
|
+
ownerOf(code: string): string | undefined;
|
|
431
|
+
/** Every code and its contributor. */
|
|
432
|
+
owners(): ReadonlyMap<string, string>;
|
|
433
|
+
/**
|
|
434
|
+
* The reason this e-mail may never be switched off, or `null` when it may.
|
|
435
|
+
* The write path and the admin projection both read it, so the two never
|
|
436
|
+
* disagree.
|
|
437
|
+
*/
|
|
438
|
+
nonDeactivatableReasonOf(code: string): string | null;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Container name: `templateEmailPort`. Owner: `transactional_emails`.
|
|
442
|
+
*
|
|
443
|
+
* `organizations` is the only cross-module consumer. `true` means "handled —
|
|
444
|
+
* do not use your legacy in-code builder", and it covers three outcomes: a
|
|
445
|
+
* delivered e-mail, one an operator deactivated, and a composition with no
|
|
446
|
+
* transport. In all three the platform decided what to send, and a fallback
|
|
447
|
+
* would either send mail the operator switched off or fail the same way. Only
|
|
448
|
+
* a code with no definition at all answers `false`.
|
|
449
|
+
*/
|
|
450
|
+
export interface TemplateEmailPort {
|
|
451
|
+
trySend(input: {
|
|
452
|
+
code: string;
|
|
453
|
+
to: string;
|
|
454
|
+
messageId: string;
|
|
455
|
+
variables: Record<string, unknown>;
|
|
456
|
+
meta?: Record<string, unknown> | undefined;
|
|
457
|
+
}): Promise<boolean>;
|
|
458
|
+
}
|
|
459
|
+
//# sourceMappingURL=transactional-emails.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transactional-emails.d.ts","sourceRoot":"","sources":["../src/transactional-emails.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,8CAA8C;AAC9C,eAAO,MAAM,kBAAkB,wCAAoC,CAAC;AACpE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEjE,eAAO,MAAM,wBAAwB,QAAsB,CAAC;AAE5D,2EAA2E;AAC3E,eAAO,MAAM,6BAA6B;;;;;iBAKxC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAMpF,eAAO,MAAM,qCAAqC;;;;;;;;;;;iBAMhD,CAAC;AACH,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AAMpG;;;;;;;;GAQG;AACH,eAAO,MAAM,kCAAkC;;;iBAG7C,CAAC;AAEH,eAAO,MAAM,+BAA+B;;;;;;;;;;;iBASO,CAAC;AACpD,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAExF,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;iBAE/C,CAAC;AACH,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oCAAoC,CAAC,CAAC;AAElG,eAAO,MAAM,0BAA0B;;;;;;;;;iBAKrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAcQ,CAAC;AACpD,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF,eAAO,MAAM,mCAAmC;;;iBAG9C,CAAC;AACH,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAMhG,eAAO,MAAM,0BAA0B;;;iBAGrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,4BAA4B;;;;iBAIvC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAMlF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wCAAwC;;iBAAoC,CAAC;AAC1F,MAAM,MAAM,kCAAkC,GAAG,CAAC,CAAC,KAAK,CACtD,OAAO,wCAAwC,CAChD,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,yCAAyC;;;;;;;;;;;iBAAkC,CAAC;AACzF,MAAM,MAAM,mCAAmC,GAAG,CAAC,CAAC,KAAK,CACvD,OAAO,yCAAyC,CACjD,CAAC;AAMF,eAAO,MAAM,yBAAyB;;;;;iBAKpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,0BAA0B;;;;iBAIrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAM9E,eAAO,MAAM,uBAAuB;;;;;;;;;;;;iBASlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;iBAIjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,6BAA6B;;;;;;;iBAOxC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,4BAA4B;;;;;;iBAQ8C,CAAC;AACxF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF,eAAO,MAAM,iCAAiC;;;iBAG5C,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAG5F,eAAO,MAAM,0BAA0B;;;;;;;;;;;iBAAiD,CAAC;AACzF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;iBAAgD,CAAC;AACvF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,gCAAgC;;;;;;iBAAuD,CAAC;AACrG,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F,eAAO,MAAM,+BAA+B;;;;;iBAO2C,CAAC;AACxF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAMxF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;iBAQ9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,6BAA6B;;;;;iBAO6C,CAAC;AACxF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,qBAAqB;;iBAEhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAMpE,eAAO,MAAM,gCAAgC;;;;;;iBAQ3C,CAAC;AACH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAO1F,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;;OASG;IACH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,UAAU,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrF;;;;;OAKG;IACH,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,wBAAwB;AAClC,+BAA+B;AAC7B;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE;AACpB,kEAAkE;GAChE;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE;AAC3B,yEAAyE;GACvE;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE;AAC5B,uEAAuE;GACrE;IAAE,MAAM,EAAE,eAAe,CAAA;CAAE,CAAC;AAEhC,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,IAAI,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;CAC7E;AAUD,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,yEAAyE;IACzE,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC;;;;;;;;;;;;;OAaG;IACH,gBAAgB,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7E,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAAC;IAC7C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,yEAAyE;IACzE,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1C,sCAAsC;IACtC,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC;;;;OAIG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CACvD;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,KAAK,EAAE;QACb,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;KAC5C,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtB"}
|