@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,495 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a module package's `./admin` layer declares (feature 091, Principle II).
|
|
3
|
+
*
|
|
4
|
+
* These are **declarations, not components**, and the distinction is the whole
|
|
5
|
+
* design. Three consumers need a contribution to be enumerable without being
|
|
6
|
+
* executed: the registry generator, which writes an artefact naming every
|
|
7
|
+
* contribution and must not import a React tree to do it; the bundler, which
|
|
8
|
+
* has to see a `() => import('…')` factory as a split point and cannot follow a
|
|
9
|
+
* computed specifier; and the gating predicate, which decides visibility from
|
|
10
|
+
* `{ module, requiredPermission }` before anything renders. So a contribution
|
|
11
|
+
* is a plain object whose only function-valued field is a dynamic-import
|
|
12
|
+
* factory — the shape a `manifest.ts`'s `actions` array already has one layer
|
|
13
|
+
* up, and the reason the ⌘K palette is the one admin extension mechanism that
|
|
14
|
+
* needs no host edit today.
|
|
15
|
+
*
|
|
16
|
+
* They live here rather than in a types-only package because they cross a
|
|
17
|
+
* package boundary and Principle II puts a shape that does in
|
|
18
|
+
* `packages/contracts/`, beside `ModuleManifest` and `ModuleActionSchema`.
|
|
19
|
+
*
|
|
20
|
+
* **The component factory is a TypeScript type and not a Zod schema, and the
|
|
21
|
+
* split is deliberate.** Everything a generator, a check or a server can
|
|
22
|
+
* validate is a schema below; the factory is `unknown` to Zod because a
|
|
23
|
+
* function value carries nothing to validate beyond its arity, and pretending
|
|
24
|
+
* otherwise would put a `z.function()` in a package `admin` and `storefront`
|
|
25
|
+
* both compile while telling a reader it was checked. The data half is
|
|
26
|
+
* `AdminRouteDeclarationSchema`; the whole declaration, factory included, is
|
|
27
|
+
* the `AdminRouteDeclaration` interface.
|
|
28
|
+
*/
|
|
29
|
+
import { z } from 'zod';
|
|
30
|
+
import { KnownIconNameSchema } from './admin-actions.js';
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Field-level patterns
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
/**
|
|
35
|
+
* An admin route path, as `react-router` reads it.
|
|
36
|
+
*
|
|
37
|
+
* The manifest action's `targetRoute` pattern plus `:` — a palette entry points
|
|
38
|
+
* at a landing screen and may not carry a parameter, while a route table is
|
|
39
|
+
* mostly parametric (`/orders/:id`). No query string, in both.
|
|
40
|
+
*/
|
|
41
|
+
const adminRoutePathRe = /^\/[A-Za-z0-9/_:-]*$/;
|
|
42
|
+
/**
|
|
43
|
+
* A module-relative translation key: `nav.crm.label`, never
|
|
44
|
+
* `crm.nav.crm.label`.
|
|
45
|
+
*
|
|
46
|
+
* The same rule a palette action's `labelKey` follows, and the same silent
|
|
47
|
+
* failure if it is broken: the module's bundle is a flat
|
|
48
|
+
* `{"a.b.c": "text"}` map, a nested object fails
|
|
49
|
+
* `TranslationBundleEntriesSchema`, the boot reconciler logs and skips it, and
|
|
50
|
+
* the entry renders its raw key.
|
|
51
|
+
*/
|
|
52
|
+
const translationKeyRe = /^[a-z][a-zA-Z0-9_]*(\.[a-z][a-zA-Z0-9_]*)*$/;
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Permission requirement
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
/**
|
|
57
|
+
* A permission code, or a set of codes any one of which suffices.
|
|
58
|
+
*
|
|
59
|
+
* The array form exists because the routes have it: `requireAdminAny([…])` is
|
|
60
|
+
* satisfied by either member, and naming only the first in the UI hides the
|
|
61
|
+
* screen from a role that holds the second. It is the shape
|
|
62
|
+
* `admin/src/lib/surface-visibility.ts` already defines, published here so a
|
|
63
|
+
* module package declares it without reaching into the admin for the type.
|
|
64
|
+
*/
|
|
65
|
+
export const PermissionRequirementSchema = z.union([
|
|
66
|
+
z.string().min(1).max(128),
|
|
67
|
+
z.array(z.string().min(1).max(128)).min(1),
|
|
68
|
+
]);
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Nav sections
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
/**
|
|
73
|
+
* The sidebar sections a module may join — closed, and derived from the ones
|
|
74
|
+
* `admin/src/components/AppShell.tsx` already declares.
|
|
75
|
+
*
|
|
76
|
+
* A module may not invent a section, for D-23's reason: an invented section is
|
|
77
|
+
* a heading nobody else can join, so two modules that belong together end up in
|
|
78
|
+
* two headings of one each and the operator reads it as two features.
|
|
79
|
+
*/
|
|
80
|
+
export const AdminNavSectionNameSchema = z.enum([
|
|
81
|
+
'main',
|
|
82
|
+
'sales',
|
|
83
|
+
'catalog',
|
|
84
|
+
'inventory',
|
|
85
|
+
'pricing',
|
|
86
|
+
'customers',
|
|
87
|
+
'channels',
|
|
88
|
+
'content',
|
|
89
|
+
'messaging',
|
|
90
|
+
'newsletter',
|
|
91
|
+
'analyticsAds',
|
|
92
|
+
'system',
|
|
93
|
+
]);
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// Zones
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
/**
|
|
98
|
+
* The places in a screen one module owns where another module's contribution
|
|
99
|
+
* may appear — closed, hierarchical, dot-separated, and the platform's.
|
|
100
|
+
*
|
|
101
|
+
* **A member exists when a host renders it, and not before.** The four members
|
|
102
|
+
* this enum opened with were derived from the places module additions had
|
|
103
|
+
* reached into by editing another module's file, which was the right derivation
|
|
104
|
+
* and produced a set nothing rendered and nothing contributed to — four names
|
|
105
|
+
* that had been silent since the enum landed. `check:admin-zones` reports every
|
|
106
|
+
* one of those as `unrendered-zone`, and it carries **no ledger**, deliberately:
|
|
107
|
+
* the remedy is always available in the same merge request, and it is either to
|
|
108
|
+
* render the place or to remove the name. So the set grows with the batch that
|
|
109
|
+
* mounts it, one member per place a host screen actually renders.
|
|
110
|
+
*
|
|
111
|
+
* `payment_method.row.actions` is the member that shows why. Measured, nothing
|
|
112
|
+
* under the payment-methods admin surface names a gateway id at all — the five
|
|
113
|
+
* gateways were given their own routes and settings screens — so there was
|
|
114
|
+
* nothing waiting to contribute and inventing a host for it would have been
|
|
115
|
+
* inventing a host.
|
|
116
|
+
*
|
|
117
|
+
* **Closed and unparameterised, and that is load-bearing.** A parameter in the
|
|
118
|
+
* name (`product.editor.field:<fieldPath>`, or a `z.templateLiteral`) was
|
|
119
|
+
* rejected: the refusal below compares declared names to rendered ones, and a
|
|
120
|
+
* name computed from a field path compares to nothing. The parameter is a prop
|
|
121
|
+
* — see {@link AdminZonePropsMap} — and one member may be mounted many times on
|
|
122
|
+
* one screen, each mount carrying its own.
|
|
123
|
+
*
|
|
124
|
+
* Both directions refuse: a contribution to a zone nobody declares is a build
|
|
125
|
+
* refusal, and a zone the platform declares that no host screen renders is one
|
|
126
|
+
* too. A contribution that silently renders nowhere is worse than one that
|
|
127
|
+
* fails.
|
|
128
|
+
*/
|
|
129
|
+
export const AdminZoneNameSchema = z.enum([
|
|
130
|
+
/**
|
|
131
|
+
* Above the product editor's Details tab, before the platform's own fields.
|
|
132
|
+
*
|
|
133
|
+
* Mounted **once** per editor. Props: {@link ProductEditorZoneProps}.
|
|
134
|
+
*/
|
|
135
|
+
'product.editor.details.before',
|
|
136
|
+
/**
|
|
137
|
+
* Above the product editor's Pricing tab.
|
|
138
|
+
*
|
|
139
|
+
* Mounted **once** per editor. Props: {@link ProductEditorZoneProps}.
|
|
140
|
+
*/
|
|
141
|
+
'product.editor.pricing.before',
|
|
142
|
+
/**
|
|
143
|
+
* Beside one editable field of the product editor.
|
|
144
|
+
*
|
|
145
|
+
* Mounted **once per field** — `name`, `description`, `categories`,
|
|
146
|
+
* `gallery`, `attachments`, and once per attribute row — each mount carrying
|
|
147
|
+
* that field's own {@link ProductEditorFieldZoneProps}. One member, twelve
|
|
148
|
+
* mount points, and a contributor that renders on all of them declares one
|
|
149
|
+
* contribution: the fan-out is the mount's, not the name's.
|
|
150
|
+
*/
|
|
151
|
+
'product.editor.field.after',
|
|
152
|
+
/**
|
|
153
|
+
* The integrations card on the delivery-methods list — one entry per shipping
|
|
154
|
+
* integration a module supplies, each linking to that module's own
|
|
155
|
+
* configuration screen.
|
|
156
|
+
*
|
|
157
|
+
* Mounted **once** per list screen and carrying no props, so its entry in
|
|
158
|
+
* {@link AdminZonePropsMap} is the empty object. That is not a placeholder
|
|
159
|
+
* for a parameter nobody has thought of yet: the host has no identifier to
|
|
160
|
+
* pass — the contributions *are* the integrations, and a contributor renders
|
|
161
|
+
* a card describing itself.
|
|
162
|
+
*
|
|
163
|
+
* It is the first member whose host is not `catalog`'s product editor, and
|
|
164
|
+
* the first whose contributors are the modules that used to be **named** by
|
|
165
|
+
* the host: `delivery_methods` hard-coded a `dhl_parcel` block and an
|
|
166
|
+
* `inpost` block, each with the other module's title, description, route and
|
|
167
|
+
* permission code, which
|
|
168
|
+
* `backend/scripts/ledgers/foreign-module-ids.ts` recorded as two
|
|
169
|
+
* `visibility-gate` couplings with this conversion as their retiring
|
|
170
|
+
* condition. Props: {@link DeliveryMethodIntegrationsZoneProps}.
|
|
171
|
+
*/
|
|
172
|
+
'delivery_method.list.integrations',
|
|
173
|
+
/**
|
|
174
|
+
* The integrations card on the payment-methods list — one entry per online
|
|
175
|
+
* payment adapter a module supplies, each linking to that module's own
|
|
176
|
+
* configuration screen.
|
|
177
|
+
*
|
|
178
|
+
* Mounted once per list screen and carrying no props. The free host owns the
|
|
179
|
+
* place and its heading; separately shipped gateway modules own the cards.
|
|
180
|
+
* Props: {@link PaymentMethodIntegrationsZoneProps}.
|
|
181
|
+
*/
|
|
182
|
+
'payment_method.list.integrations',
|
|
183
|
+
/**
|
|
184
|
+
* Below the invoice detail's totals column, at the end of the right-hand
|
|
185
|
+
* stack.
|
|
186
|
+
*
|
|
187
|
+
* Mounted **once** per invoice detail screen. Props:
|
|
188
|
+
* {@link InvoiceDetailZoneProps}.
|
|
189
|
+
*
|
|
190
|
+
* The first member whose host is `invoices` and whose contributor is `ksef`.
|
|
191
|
+
* `invoices`' invoice detail imported `ksef`'s `InvoiceKsefPanel` by path —
|
|
192
|
+
* the single key in
|
|
193
|
+
* `backend/scripts/ledgers/cross-module-imports/invoices.ts`, whose recorded
|
|
194
|
+
* retiring condition is this member existing. Z1 question 1 is answered from
|
|
195
|
+
* the panel's own signature: `(invoiceId, kind, ksefReferenceNumber)` — three
|
|
196
|
+
* values in, nothing out, no `onChange` — so it is question 2's case, an
|
|
197
|
+
* addition the owner makes because the owner is installed.
|
|
198
|
+
*
|
|
199
|
+
* **Per-host and not a shared `invoice.detail.after` twin of some general
|
|
200
|
+
* member** (§10 Z13): a member shared by two hosts lets one host's mount
|
|
201
|
+
* cover the other host's absence, which is the failure `unrendered-zone`
|
|
202
|
+
* exists to refuse.
|
|
203
|
+
*/
|
|
204
|
+
'invoice.detail.after',
|
|
205
|
+
/**
|
|
206
|
+
* The end of the category editor's form, after its save/cancel row.
|
|
207
|
+
*
|
|
208
|
+
* Mounted **once** per open category, and named from the host's own word for
|
|
209
|
+
* the place (Z14): `catalog`'s `CategoriesTree.tsx` is the editor, and the
|
|
210
|
+
* place is *after* everything the editor itself offers. Props:
|
|
211
|
+
* {@link CategoryEditorZoneProps}.
|
|
212
|
+
*
|
|
213
|
+
* The first member whose contributor is `price_lists`. `catalog` imported
|
|
214
|
+
* `DisplayModeOverrideRow` by path and handed it its own label and its own
|
|
215
|
+
* hint — one of the three admin keys in
|
|
216
|
+
* `backend/scripts/ledgers/cross-module-imports/catalog.ts`. A host cannot
|
|
217
|
+
* hand copy to a contributor it does not know, so the two `catalog` strings
|
|
218
|
+
* go with the import and the control renders `price_lists`' own.
|
|
219
|
+
*/
|
|
220
|
+
'category.editor.after',
|
|
221
|
+
/**
|
|
222
|
+
* The end of the product editor's Pricing tab.
|
|
223
|
+
*
|
|
224
|
+
* Mounted **once** per editor, and the twin of
|
|
225
|
+
* `product.editor.pricing.before`: two places in one editor, one before the
|
|
226
|
+
* platform's own pricing fields and one after them. Props:
|
|
227
|
+
* {@link ProductEditorZoneProps}, reused rather than aliased — a props type
|
|
228
|
+
* is the *shape* the mount carries, and both places carry a product id.
|
|
229
|
+
*/
|
|
230
|
+
'product.editor.pricing.after',
|
|
231
|
+
/**
|
|
232
|
+
* The **body** of the product editor's Channels tab.
|
|
233
|
+
*
|
|
234
|
+
* Mounted **once** per editor. Props: {@link ProductEditorZoneProps}.
|
|
235
|
+
*
|
|
236
|
+
* The host keeps the tab strip and the label — `channels` is `catalog`'s own
|
|
237
|
+
* tab id — and stops knowing which module fills it: the button is shown by
|
|
238
|
+
* `useAdminZone(name, props).length > 0` (Z15), which has already applied
|
|
239
|
+
* both presence axes and the contributor's permission. A strip zone that
|
|
240
|
+
* contributed the button too was rejected: one contributor, one host, and the
|
|
241
|
+
* label is the host's own vocabulary.
|
|
242
|
+
*/
|
|
243
|
+
'product.editor.channels',
|
|
244
|
+
/**
|
|
245
|
+
* Below the sales-channel editor's identity form.
|
|
246
|
+
*
|
|
247
|
+
* Mounted **once** per channel, and only for a channel that already exists —
|
|
248
|
+
* the create form has no id to pass. Props:
|
|
249
|
+
* {@link SalesChannelEditorZoneProps}.
|
|
250
|
+
*
|
|
251
|
+
* The first member whose host is `sales_channels` and whose contributor is
|
|
252
|
+
* `inventory`. The panel behind it is warehouse↔channel routing, which is a
|
|
253
|
+
* fact about fulfilment rather than about the channel's identity, and its
|
|
254
|
+
* four routes take `inventory:read` / `inventory:write`.
|
|
255
|
+
*/
|
|
256
|
+
'sales_channel.editor.after',
|
|
257
|
+
/**
|
|
258
|
+
* The stack of panels an organization's detail screen ends with.
|
|
259
|
+
*
|
|
260
|
+
* Mounted **once** per organization, and the "once" is a rule rather than a
|
|
261
|
+
* layout choice (§10.1): two mounts of this member on one screen, with no
|
|
262
|
+
* prop to tell them apart, render **every** contribution twice and nothing in
|
|
263
|
+
* the renderer can distinguish them. Props:
|
|
264
|
+
* {@link OrganizationDetailZoneProps}.
|
|
265
|
+
*
|
|
266
|
+
* The first member with four contributors, and the first whose conversion
|
|
267
|
+
* makes scattered panels contiguous: `sales_channels`' channel membership,
|
|
268
|
+
* `price_lists`' display-mode override and `quick_order`'s ordering defaults
|
|
269
|
+
* sat at three different depths of
|
|
270
|
+
* `admin/src/modules/organizations/OrganizationDetail.tsx`, each imported by
|
|
271
|
+
* path — the three keys of
|
|
272
|
+
* `backend/scripts/ledgers/cross-module-imports/organizations.ts`, whose
|
|
273
|
+
* shard this member deletes. `carts` joins them with the cart-approval
|
|
274
|
+
* policy, whose panel this host owned and nothing rendered (§10.5).
|
|
275
|
+
*
|
|
276
|
+
* **Per-host and not a shared `entity.detail.after`** (§10 Z13): the
|
|
277
|
+
* `unrendered-zone` refusal is computed per member, so one host's mount would
|
|
278
|
+
* cover another host's absence. `customer.detail.after` is the twin, and the
|
|
279
|
+
* cost of keeping them apart is one four-line wrapper in `quick_order`.
|
|
280
|
+
*/
|
|
281
|
+
'organization.detail.after',
|
|
282
|
+
/**
|
|
283
|
+
* The stack of panels a customer's detail screen ends with.
|
|
284
|
+
*
|
|
285
|
+
* Mounted **once** per customer, on `organization.detail.after`'s terms and
|
|
286
|
+
* for its reasons. Props: {@link CustomerDetailZoneProps}.
|
|
287
|
+
*
|
|
288
|
+
* One contributor: `quick_order`'s ordering defaults, which
|
|
289
|
+
* `admin/src/modules/customers/CustomerDetail.tsx` imported by path — the
|
|
290
|
+
* single key of `backend/scripts/ledgers/cross-module-imports/customers.ts`,
|
|
291
|
+
* whose shard this member deletes.
|
|
292
|
+
*/
|
|
293
|
+
'customer.detail.after',
|
|
294
|
+
/**
|
|
295
|
+
* The **body** of the order detail's Payment tab.
|
|
296
|
+
*
|
|
297
|
+
* Mounted **once** per order, and named from the host's own word for the
|
|
298
|
+
* place (Z14): `orders`' `OrderDetail.tsx` calls the tab `payment` and its
|
|
299
|
+
* label `orderDetail.tabs.payment`. Props: {@link OrderDetailZoneProps}.
|
|
300
|
+
*
|
|
301
|
+
* The host keeps the tab strip and the label and stops knowing which module
|
|
302
|
+
* fills it: the button is shown by `useAdminZone(name, props).length > 0`
|
|
303
|
+
* (Z15), which has already applied both presence axes and the contributor's
|
|
304
|
+
* permission. `orders` used to render `payments`' tab itself, gated on
|
|
305
|
+
* `isVisible({ module: 'payments', requiredPermission: 'payments:read' })` —
|
|
306
|
+
* the `visibility-gate` key of `backend/scripts/ledgers/foreign-module-ids.ts`
|
|
307
|
+
* whose recorded retiring condition is this member.
|
|
308
|
+
*/
|
|
309
|
+
'order.detail.payment',
|
|
310
|
+
/**
|
|
311
|
+
* The per-row action cell of the order detail's Delivery tab.
|
|
312
|
+
*
|
|
313
|
+
* Mounted **once per shipment attempt**, each mount carrying that attempt's
|
|
314
|
+
* own {@link OrderShipmentRowZoneProps} — the first member in this enum whose
|
|
315
|
+
* contributions narrow themselves with `match` rather than by returning
|
|
316
|
+
* `null`, which is the population Z13 reserves for it: one host, one place,
|
|
317
|
+
* many mounts.
|
|
318
|
+
*
|
|
319
|
+
* `providerCode` and `status` are props **because** they are matched on. A
|
|
320
|
+
* key the mount's props do not carry never agrees (fail-closed), so a
|
|
321
|
+
* contribution matching a prop this interface omits renders nowhere and
|
|
322
|
+
* nothing reports it — which is why the two are declared here and not left
|
|
323
|
+
* for the contributor to read out of a payload.
|
|
324
|
+
*
|
|
325
|
+
* `orders` used to write `inpost`'s knowledge into its own JSX —
|
|
326
|
+
* `providerDetails?.['provider'] === 'inpost' && status === 'success'`, under
|
|
327
|
+
* an `isVisible({ module: 'inpost', … })` gate and an `inpost` translation
|
|
328
|
+
* namespace, which is two of the three `foreign-module-ids` keys this member
|
|
329
|
+
* retires.
|
|
330
|
+
*/
|
|
331
|
+
'order.shipment.row.actions',
|
|
332
|
+
/**
|
|
333
|
+
* The footer action bar of the order detail's Delivery tab.
|
|
334
|
+
*
|
|
335
|
+
* Mounted **once** per tab, below the attempts table and beside the host's
|
|
336
|
+
* own "generate again" button. Props:
|
|
337
|
+
* {@link OrderShipmentsActionsZoneProps}.
|
|
338
|
+
*
|
|
339
|
+
* Its contributor is the carrier the ledgers could not see: `dhl_parcel` was
|
|
340
|
+
* named by **delivery-method code** (`'dhl_parcel_courier'`,
|
|
341
|
+
* `'dhl_parcel_pickup'`) rather than by module id, so
|
|
342
|
+
* `check:admin-zones`' `foreign-module-id` predicate — which reads module ids
|
|
343
|
+
* out of strings — never had it in its population and never will. The three
|
|
344
|
+
* buttons behind those codes carried **no permission gate at all** while the
|
|
345
|
+
* routes behind them enforce `dhl_parcel:read` and `dhl_parcel:write`; a
|
|
346
|
+
* contribution declares one code, so the conversion closes that
|
|
347
|
+
* over-exposure by construction.
|
|
348
|
+
*/
|
|
349
|
+
'order.shipments.tab.actions',
|
|
350
|
+
/**
|
|
351
|
+
* The switch between the two ways of entering an order, above the entry form.
|
|
352
|
+
*
|
|
353
|
+
* **A tab strip rather than a stack**, and the only member so far whose
|
|
354
|
+
* renderer is `<RouteTabsZone>`: the contributions are the tabs, the host
|
|
355
|
+
* supplies the strip, and *"fewer than two tabs is not a choice"* is the
|
|
356
|
+
* strip counting what `useAdminZone` already filtered rather than a rule any
|
|
357
|
+
* module states. Props: {@link OrderEntryTabsZoneProps}, which carries
|
|
358
|
+
* nothing — the mount has no identifier to pass, exactly as
|
|
359
|
+
* `delivery_method.list.integrations` has none.
|
|
360
|
+
*
|
|
361
|
+
* **Two hosts and one place, which is the one exception Z13 leaves open and
|
|
362
|
+
* is stated here rather than discovered.** Z13 refuses a member shared by
|
|
363
|
+
* hosts that each have *a place of their own*, because one host's mount then
|
|
364
|
+
* covers another's absence. This is not that: the place is a single
|
|
365
|
+
* navigational switch, and it appears on **both** of the pages it switches
|
|
366
|
+
* between — `orders`' order-create screen and `quick_order`'s on-behalf
|
|
367
|
+
* screen — because a switch visible from only one side is not a switch. The
|
|
368
|
+
* cost is real and is the one Z13 names: deleting the mount from one of the
|
|
369
|
+
* two screens leaves the member rendered, so `unrendered-zone` would not
|
|
370
|
+
* report it. What does report it is
|
|
371
|
+
* `admin/test/modules/orders/order-entry-tabs-zone.test.tsx`, which asserts
|
|
372
|
+
* both mounts by name.
|
|
373
|
+
*
|
|
374
|
+
* The contributors are the two modules the strip used to be filtered *by*:
|
|
375
|
+
* `admin/src/components/OrderEntryTabs.tsx` held a two-element array naming
|
|
376
|
+
* `orders` and `quick_order`, each with the other module's route and the
|
|
377
|
+
* other module's label out of the `core` bundle — the last two keys of
|
|
378
|
+
* `backend/scripts/ledgers/admin-surface.ts`, which this member empties. Each
|
|
379
|
+
* module now contributes its own tab, with its own label in its own bundle.
|
|
380
|
+
*/
|
|
381
|
+
'order.entry.tabs',
|
|
382
|
+
/**
|
|
383
|
+
* The switch between invoice-ledger deliveries, routing, and vendor adapter
|
|
384
|
+
* connection screens.
|
|
385
|
+
*
|
|
386
|
+
* **A tab strip**, same renderer as `order.entry.tabs`: `<RouteTabsZone>`.
|
|
387
|
+
* `invoice_ledger` contributes Deliveries and Routing, and asks a vendor
|
|
388
|
+
* adapter's connection tab to weigh more than its own two so that it sorts
|
|
389
|
+
* after the screens it is a vendor of. The sidebar keeps one **Invoice
|
|
390
|
+
* ledger** row. Props: {@link LedgerSectionTabsZoneProps}.
|
|
391
|
+
*
|
|
392
|
+
* **No vendor is named here.** One was until 2026-09-22, and the vendors are
|
|
393
|
+
* what feature 134's wave 4 takes out of this repository — a free package's
|
|
394
|
+
* source naming a paid module id is the reach that sweep exists to remove
|
|
395
|
+
* (and a string literal is the spelling no instrument sees).
|
|
396
|
+
*
|
|
397
|
+
* The name is `ledger.section.tabs` and not `invoice_ledger.section.tabs`
|
|
398
|
+
* so an adapter file that mounts the strip does not spell a sibling module
|
|
399
|
+
* id (`check:admin-zones` `foreign-module-id`).
|
|
400
|
+
*
|
|
401
|
+
* **Many hosts and one place**, the same Z13 exception `order.entry.tabs`
|
|
402
|
+
* records: the switch must appear on every page it switches between or it
|
|
403
|
+
* is not a switch. `unrendered-zone` is per zone rather than per host, so
|
|
404
|
+
* that is asserted **per contributing package**, in each one's own
|
|
405
|
+
* `src/admin/index.test.ts` over a relative read of its own screens — which
|
|
406
|
+
* is where it keeps working once the vendors are installed from tarballs
|
|
407
|
+
* rather than resolved in this workspace (feature 134 W2.2, D-262 clause 3).
|
|
408
|
+
* The strip's own mechanism is driven in
|
|
409
|
+
* `admin/test/modules/invoice_ledger/ledger-section-tabs-zone.test.tsx`.
|
|
410
|
+
*/
|
|
411
|
+
'ledger.section.tabs',
|
|
412
|
+
]);
|
|
413
|
+
// ---------------------------------------------------------------------------
|
|
414
|
+
// Declarations
|
|
415
|
+
// ---------------------------------------------------------------------------
|
|
416
|
+
/**
|
|
417
|
+
* The data half of a route declaration — everything a generator or a check can
|
|
418
|
+
* read without evaluating the module's UI code.
|
|
419
|
+
*
|
|
420
|
+
* **Owner attribution is not a field.** The module id is the registry entry's
|
|
421
|
+
* key, so a declaration cannot claim to belong to a module other than the one
|
|
422
|
+
* that shipped it — the same reason a packaged migration is attributed to
|
|
423
|
+
* `endora.id` and never to a path segment (D-142). An attribution a module can
|
|
424
|
+
* write is an attribution a module can get wrong.
|
|
425
|
+
*/
|
|
426
|
+
export const AdminRouteDeclarationSchema = z.object({
|
|
427
|
+
path: z
|
|
428
|
+
.string()
|
|
429
|
+
.min(1)
|
|
430
|
+
.max(255)
|
|
431
|
+
.regex(adminRoutePathRe, 'Admin route must be a leading-slash ASCII path with no query string'),
|
|
432
|
+
requiredPermission: PermissionRequirementSchema.optional(),
|
|
433
|
+
/** Marks the module's landing route, so a nav entry can default to it. */
|
|
434
|
+
index: z.boolean().optional(),
|
|
435
|
+
});
|
|
436
|
+
/**
|
|
437
|
+
* The data half of a sidebar entry.
|
|
438
|
+
*
|
|
439
|
+
* Deliberately the same five fields `NAV` already carries in
|
|
440
|
+
* `admin/src/components/AppShell.tsx`, so the sidebar renders
|
|
441
|
+
* `[...hostNav, ...registryNav]` through the one existing predicate with no
|
|
442
|
+
* second gate. Issue #230's finding — three surfaces answering the visibility
|
|
443
|
+
* question three ways — does not get a fourth chance.
|
|
444
|
+
*/
|
|
445
|
+
export const AdminNavDeclarationSchema = z.object({
|
|
446
|
+
to: z
|
|
447
|
+
.string()
|
|
448
|
+
.min(1)
|
|
449
|
+
.max(255)
|
|
450
|
+
.regex(adminRoutePathRe, 'Admin route must be a leading-slash ASCII path with no query string'),
|
|
451
|
+
labelKey: z
|
|
452
|
+
.string()
|
|
453
|
+
.min(1)
|
|
454
|
+
.max(255)
|
|
455
|
+
.regex(translationKeyRe, 'Translation key must be dot-separated camelCase namespaces'),
|
|
456
|
+
icon: KnownIconNameSchema,
|
|
457
|
+
section: AdminNavSectionNameSchema,
|
|
458
|
+
/** Order within the section. Ties are broken by module id, so it is stable. */
|
|
459
|
+
weight: z.number().int(),
|
|
460
|
+
requiredPermission: PermissionRequirementSchema.optional(),
|
|
461
|
+
});
|
|
462
|
+
/**
|
|
463
|
+
* The data half of a contribution into another module's screen.
|
|
464
|
+
*
|
|
465
|
+
* A contribution declares **one** zone, so a component appearing in two zones
|
|
466
|
+
* is two contributions — and only the one that needs narrowing carries a
|
|
467
|
+
* {@link AdminZoneContributionSchema.shape.match}.
|
|
468
|
+
*/
|
|
469
|
+
export const AdminZoneContributionSchema = z.object({
|
|
470
|
+
zone: AdminZoneNameSchema,
|
|
471
|
+
weight: z.number().int(),
|
|
472
|
+
requiredPermission: PermissionRequirementSchema.optional(),
|
|
473
|
+
/**
|
|
474
|
+
* Narrow this contribution to the mounts whose props agree with every key.
|
|
475
|
+
*
|
|
476
|
+
* The renderer includes the contribution when, for each key, the zone's props
|
|
477
|
+
* carry that key with that value — or with a member of that array. Data only,
|
|
478
|
+
* enumerable, and readable by a check.
|
|
479
|
+
*
|
|
480
|
+
* **It exists for FR-013 and not for tidiness.** One zone is mounted on many
|
|
481
|
+
* screens; without `match` a contributor narrows by returning `null` for the
|
|
482
|
+
* mounts it does not serve, which means its chunk is fetched and evaluated on
|
|
483
|
+
* every one of them. `match` is decided **before** `React.lazy` is touched,
|
|
484
|
+
* so the chunk is never requested. The alternative — a near-identical enum
|
|
485
|
+
* member per case — is the openness the closed enum exists to refuse, wearing
|
|
486
|
+
* a different hat.
|
|
487
|
+
*
|
|
488
|
+
* A key the zone's props do not carry never agrees, so a `match` naming a
|
|
489
|
+
* prop that does not exist hides the contribution rather than widening it.
|
|
490
|
+
*/
|
|
491
|
+
match: z
|
|
492
|
+
.record(z.string(), z.union([z.string(), z.array(z.string()).readonly()]))
|
|
493
|
+
.optional(),
|
|
494
|
+
});
|
|
495
|
+
//# sourceMappingURL=admin-contributions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-contributions.js","sourceRoot":"","sources":["../src/admin-contributions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type SupportedLanguage } from './platform-language.js';
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Use `SupportedLanguageSchema` from `platform-language.ts`. The set
|
|
5
|
+
* is the platform's, not the Admin UI's — a buyer is answered out of the same
|
|
6
|
+
* enum (feature 083, D-136). Draining task: `specs/083-buyer-language-resolution`
|
|
7
|
+
* T021.
|
|
8
|
+
*/
|
|
9
|
+
export declare const SupportedAdminLanguageSchema: z.ZodEnum<{
|
|
10
|
+
en: "en";
|
|
11
|
+
pl: "pl";
|
|
12
|
+
}>;
|
|
13
|
+
/**
|
|
14
|
+
* @deprecated Use `SupportedLanguage` from `platform-language.ts`. Draining
|
|
15
|
+
* task: `specs/083-buyer-language-resolution` T021.
|
|
16
|
+
*/
|
|
17
|
+
export type SupportedAdminLanguage = SupportedLanguage;
|
|
18
|
+
/**
|
|
19
|
+
* On-disk bundle JSON shape and the row payload persisted to
|
|
20
|
+
* `translation_bundles.entries`. Flat string→string only at v1; nested
|
|
21
|
+
* objects, arrays, and non-string values are rejected.
|
|
22
|
+
*/
|
|
23
|
+
export declare const TranslationBundleEntriesSchema: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
24
|
+
export type TranslationBundleEntries = z.infer<typeof TranslationBundleEntriesSchema>;
|
|
25
|
+
/** Admin SPA boot fetch — `GET /api/v1/admin/i18n/bundles?language=…` response. */
|
|
26
|
+
export declare const GetBundlesResponseSchema: z.ZodObject<{
|
|
27
|
+
language: z.ZodEnum<{
|
|
28
|
+
en: "en";
|
|
29
|
+
pl: "pl";
|
|
30
|
+
}>;
|
|
31
|
+
version: z.ZodNumber;
|
|
32
|
+
bundles: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
33
|
+
}, z.core.$strip>;
|
|
34
|
+
export type GetBundlesResponse = z.infer<typeof GetBundlesResponseSchema>;
|
|
35
|
+
/** `PATCH /api/v1/admin/me/preferred-language` body. `null` reverts to the platform default. */
|
|
36
|
+
export declare const PatchPreferredLanguageBodySchema: z.ZodObject<{
|
|
37
|
+
preferredLanguage: z.ZodNullable<z.ZodEnum<{
|
|
38
|
+
en: "en";
|
|
39
|
+
pl: "pl";
|
|
40
|
+
}>>;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
export type PatchPreferredLanguageBody = z.infer<typeof PatchPreferredLanguageBodySchema>;
|
|
43
|
+
/** Standard 400 envelope when an unsupported language is requested. */
|
|
44
|
+
export declare const UnsupportedLanguageErrorSchema: z.ZodObject<{
|
|
45
|
+
error: z.ZodLiteral<"unsupported-language">;
|
|
46
|
+
supported: z.ZodArray<z.ZodEnum<{
|
|
47
|
+
en: "en";
|
|
48
|
+
pl: "pl";
|
|
49
|
+
}>>;
|
|
50
|
+
}, z.core.$strip>;
|
|
51
|
+
export type UnsupportedLanguageError = z.infer<typeof UnsupportedLanguageErrorSchema>;
|
|
52
|
+
export declare const I18nCoverageLanguageSchema: z.ZodObject<{
|
|
53
|
+
languageCode: z.ZodEnum<{
|
|
54
|
+
en: "en";
|
|
55
|
+
pl: "pl";
|
|
56
|
+
}>;
|
|
57
|
+
totalKeysSeen: z.ZodNumber;
|
|
58
|
+
missingCount: z.ZodNumber;
|
|
59
|
+
missingKeys: z.ZodArray<z.ZodString>;
|
|
60
|
+
fellBackToEnCount: z.ZodNumber;
|
|
61
|
+
fellBackToEnKeys: z.ZodArray<z.ZodString>;
|
|
62
|
+
}, z.core.$strip>;
|
|
63
|
+
export type I18nCoverageLanguage = z.infer<typeof I18nCoverageLanguageSchema>;
|
|
64
|
+
export declare const I18nCoverageModuleSchema: z.ZodObject<{
|
|
65
|
+
moduleId: z.ZodString;
|
|
66
|
+
languages: z.ZodArray<z.ZodObject<{
|
|
67
|
+
languageCode: z.ZodEnum<{
|
|
68
|
+
en: "en";
|
|
69
|
+
pl: "pl";
|
|
70
|
+
}>;
|
|
71
|
+
totalKeysSeen: z.ZodNumber;
|
|
72
|
+
missingCount: z.ZodNumber;
|
|
73
|
+
missingKeys: z.ZodArray<z.ZodString>;
|
|
74
|
+
fellBackToEnCount: z.ZodNumber;
|
|
75
|
+
fellBackToEnKeys: z.ZodArray<z.ZodString>;
|
|
76
|
+
}, z.core.$strip>>;
|
|
77
|
+
}, z.core.$strip>;
|
|
78
|
+
export type I18nCoverageModule = z.infer<typeof I18nCoverageModuleSchema>;
|
|
79
|
+
export declare const I18nCoverageResponseSchema: z.ZodObject<{
|
|
80
|
+
capturedAt: z.ZodISODateTime;
|
|
81
|
+
modules: z.ZodArray<z.ZodObject<{
|
|
82
|
+
moduleId: z.ZodString;
|
|
83
|
+
languages: z.ZodArray<z.ZodObject<{
|
|
84
|
+
languageCode: z.ZodEnum<{
|
|
85
|
+
en: "en";
|
|
86
|
+
pl: "pl";
|
|
87
|
+
}>;
|
|
88
|
+
totalKeysSeen: z.ZodNumber;
|
|
89
|
+
missingCount: z.ZodNumber;
|
|
90
|
+
missingKeys: z.ZodArray<z.ZodString>;
|
|
91
|
+
fellBackToEnCount: z.ZodNumber;
|
|
92
|
+
fellBackToEnKeys: z.ZodArray<z.ZodString>;
|
|
93
|
+
}, z.core.$strip>>;
|
|
94
|
+
}, z.core.$strip>>;
|
|
95
|
+
}, z.core.$strip>;
|
|
96
|
+
export type I18nCoverageResponse = z.infer<typeof I18nCoverageResponseSchema>;
|
|
97
|
+
export declare const I18nCoverageQuerySchema: z.ZodObject<{
|
|
98
|
+
module: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
99
|
+
language: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
|
|
100
|
+
en: "en";
|
|
101
|
+
pl: "pl";
|
|
102
|
+
}>, z.ZodArray<z.ZodEnum<{
|
|
103
|
+
en: "en";
|
|
104
|
+
pl: "pl";
|
|
105
|
+
}>>]>>;
|
|
106
|
+
includeKeys: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
107
|
+
missing: "missing";
|
|
108
|
+
all: "all";
|
|
109
|
+
}>>>;
|
|
110
|
+
}, z.core.$strip>;
|
|
111
|
+
export type I18nCoverageQuery = z.infer<typeof I18nCoverageQuerySchema>;
|
|
112
|
+
/**
|
|
113
|
+
* Container name: `adminI18nService`. Owner: `_i18n`.
|
|
114
|
+
*
|
|
115
|
+
* The backend-side string resolver: a module id, a key inside that module's
|
|
116
|
+
* bundle and the operator's language in, the rendered sentence out. The
|
|
117
|
+
* resolver falls back to English and, failing that, returns `moduleId.key`
|
|
118
|
+
* verbatim — a caller that wants to detect a missing key compares against that
|
|
119
|
+
* placeholder rather than against `null`.
|
|
120
|
+
*
|
|
121
|
+
* This is the one method the resolver's cross-module callers use. The bundle
|
|
122
|
+
* install, removal and coverage surfaces of `_i18n`'s service stay inside
|
|
123
|
+
* `_i18n`: they are the reconciler's business, not a consumer's.
|
|
124
|
+
*
|
|
125
|
+
* When `_i18n` is off the port fails closed. That is the right answer for a
|
|
126
|
+
* caller rendering an operator-facing string: a screen labelled with raw keys
|
|
127
|
+
* is worse than a screen that says the platform will not answer.
|
|
128
|
+
*
|
|
129
|
+
* Whether `_i18n` has an off state at all is its manifest's `activation` to
|
|
130
|
+
* say, not this line's: a module declaring `nonDeactivatable` never enters one.
|
|
131
|
+
*/
|
|
132
|
+
export interface AdminI18nTranslatePort {
|
|
133
|
+
translate(moduleId: string, key: string, language: SupportedAdminLanguage, params?: Record<string, string | number>): Promise<string>;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=admin-i18n.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-i18n.d.ts","sourceRoot":"","sources":["../src/admin-i18n.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAA2B,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEzF;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B;;;EAA0B,CAAC;AACpE;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,uCAG1C,CAAC;AACF,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF,mFAAmF;AACnF,eAAO,MAAM,wBAAwB;;;;;;;iBAMnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,gGAAgG;AAChG,eAAO,MAAM,gCAAgC;;;;;iBAE3C,CAAC;AACH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F,uEAAuE;AACvE,eAAO,MAAM,8BAA8B;;;;;;iBAGzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAMtF,eAAO,MAAM,0BAA0B;;;;;;;;;;iBAOrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;iBAGnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;iBAGrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;iBAMlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAIxE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,sBAAsB;IACrC,SAAS,CACP,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,sBAAsB,EAChC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GACvC,OAAO,CAAC,MAAM,CAAC,CAAC;CACpB"}
|