@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.
Files changed (327) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +34 -0
  3. package/dist/actor.d.ts +79 -0
  4. package/dist/actor.d.ts.map +1 -0
  5. package/dist/actor.js +41 -0
  6. package/dist/actor.js.map +1 -0
  7. package/dist/addresses.d.ts +134 -0
  8. package/dist/addresses.d.ts.map +1 -0
  9. package/dist/addresses.js +16 -0
  10. package/dist/addresses.js.map +1 -0
  11. package/dist/admin-actions.d.ts +367 -0
  12. package/dist/admin-actions.d.ts.map +1 -0
  13. package/dist/admin-actions.js +287 -0
  14. package/dist/admin-actions.js.map +1 -0
  15. package/dist/admin-contributions.d.ts +518 -0
  16. package/dist/admin-contributions.d.ts.map +1 -0
  17. package/dist/admin-contributions.js +495 -0
  18. package/dist/admin-contributions.js.map +1 -0
  19. package/dist/admin-i18n.d.ts +135 -0
  20. package/dist/admin-i18n.d.ts.map +1 -0
  21. package/dist/admin-i18n.js +72 -0
  22. package/dist/admin-i18n.js.map +1 -0
  23. package/dist/admin-notifications.d.ts +55 -0
  24. package/dist/admin-notifications.d.ts.map +1 -0
  25. package/dist/admin-notifications.js +16 -0
  26. package/dist/admin-notifications.js.map +1 -0
  27. package/dist/admin-roles.d.ts +125 -0
  28. package/dist/admin-roles.d.ts.map +1 -0
  29. package/dist/admin-roles.js +2 -0
  30. package/dist/admin-roles.js.map +1 -0
  31. package/dist/admin-users.d.ts +178 -0
  32. package/dist/admin-users.d.ts.map +1 -0
  33. package/dist/admin-users.js +14 -0
  34. package/dist/admin-users.js.map +1 -0
  35. package/dist/admin.d.ts +243 -0
  36. package/dist/admin.d.ts.map +1 -0
  37. package/dist/admin.js +246 -0
  38. package/dist/admin.js.map +1 -0
  39. package/dist/analytics.d.ts +123 -0
  40. package/dist/analytics.d.ts.map +1 -0
  41. package/dist/analytics.js +68 -0
  42. package/dist/analytics.js.map +1 -0
  43. package/dist/api-keys.d.ts +97 -0
  44. package/dist/api-keys.d.ts.map +1 -0
  45. package/dist/api-keys.js +64 -0
  46. package/dist/api-keys.js.map +1 -0
  47. package/dist/assets-library.d.ts +684 -0
  48. package/dist/assets-library.d.ts.map +1 -0
  49. package/dist/assets-library.js +181 -0
  50. package/dist/assets-library.js.map +1 -0
  51. package/dist/audit-logs.d.ts +141 -0
  52. package/dist/audit-logs.d.ts.map +1 -0
  53. package/dist/audit-logs.js +31 -0
  54. package/dist/audit-logs.js.map +1 -0
  55. package/dist/auth.d.ts +174 -0
  56. package/dist/auth.d.ts.map +1 -0
  57. package/dist/auth.js +27 -0
  58. package/dist/auth.js.map +1 -0
  59. package/dist/blog.d.ts +669 -0
  60. package/dist/blog.d.ts.map +1 -0
  61. package/dist/blog.js +360 -0
  62. package/dist/blog.js.map +1 -0
  63. package/dist/capabilities.d.ts +40 -0
  64. package/dist/capabilities.d.ts.map +1 -0
  65. package/dist/capabilities.js +38 -0
  66. package/dist/capabilities.js.map +1 -0
  67. package/dist/carts.d.ts +1367 -0
  68. package/dist/carts.d.ts.map +1 -0
  69. package/dist/carts.js +405 -0
  70. package/dist/carts.js.map +1 -0
  71. package/dist/catalog.d.ts +2855 -0
  72. package/dist/catalog.d.ts.map +1 -0
  73. package/dist/catalog.js +1543 -0
  74. package/dist/catalog.js.map +1 -0
  75. package/dist/cms.d.ts +872 -0
  76. package/dist/cms.d.ts.map +1 -0
  77. package/dist/cms.js +468 -0
  78. package/dist/cms.js.map +1 -0
  79. package/dist/common.d.ts +82 -0
  80. package/dist/common.d.ts.map +1 -0
  81. package/dist/common.js +72 -0
  82. package/dist/common.js.map +1 -0
  83. package/dist/comparisons.d.ts +487 -0
  84. package/dist/comparisons.d.ts.map +1 -0
  85. package/dist/comparisons.js +221 -0
  86. package/dist/comparisons.js.map +1 -0
  87. package/dist/credentials.d.ts +292 -0
  88. package/dist/credentials.d.ts.map +1 -0
  89. package/dist/credentials.js +142 -0
  90. package/dist/credentials.js.map +1 -0
  91. package/dist/credit-limits.d.ts +111 -0
  92. package/dist/credit-limits.d.ts.map +1 -0
  93. package/dist/credit-limits.js +35 -0
  94. package/dist/credit-limits.js.map +1 -0
  95. package/dist/currencies.d.ts +127 -0
  96. package/dist/currencies.d.ts.map +1 -0
  97. package/dist/currencies.js +20 -0
  98. package/dist/currencies.js.map +1 -0
  99. package/dist/custom-fields.d.ts +345 -0
  100. package/dist/custom-fields.d.ts.map +1 -0
  101. package/dist/custom-fields.js +185 -0
  102. package/dist/custom-fields.js.map +1 -0
  103. package/dist/customer-accounts.d.ts +690 -0
  104. package/dist/customer-accounts.d.ts.map +1 -0
  105. package/dist/customer-accounts.js +41 -0
  106. package/dist/customer-accounts.js.map +1 -0
  107. package/dist/customers.d.ts +305 -0
  108. package/dist/customers.d.ts.map +1 -0
  109. package/dist/customers.js +158 -0
  110. package/dist/customers.js.map +1 -0
  111. package/dist/dictionary.d.ts +580 -0
  112. package/dist/dictionary.d.ts.map +1 -0
  113. package/dist/dictionary.js +297 -0
  114. package/dist/dictionary.js.map +1 -0
  115. package/dist/email-address.d.ts +62 -0
  116. package/dist/email-address.d.ts.map +1 -0
  117. package/dist/email-address.js +64 -0
  118. package/dist/email-address.js.map +1 -0
  119. package/dist/email.d.ts +175 -0
  120. package/dist/email.d.ts.map +1 -0
  121. package/dist/email.js +45 -0
  122. package/dist/email.js.map +1 -0
  123. package/dist/envelopes.d.ts +15 -0
  124. package/dist/envelopes.d.ts.map +1 -0
  125. package/dist/envelopes.js +16 -0
  126. package/dist/envelopes.js.map +1 -0
  127. package/dist/environment-inputs.d.ts +306 -0
  128. package/dist/environment-inputs.d.ts.map +1 -0
  129. package/dist/environment-inputs.js +277 -0
  130. package/dist/environment-inputs.js.map +1 -0
  131. package/dist/erp-connector.d.ts +52 -0
  132. package/dist/erp-connector.d.ts.map +1 -0
  133. package/dist/erp-connector.js +34 -0
  134. package/dist/erp-connector.js.map +1 -0
  135. package/dist/errors.d.ts +455 -0
  136. package/dist/errors.d.ts.map +1 -0
  137. package/dist/errors.js +532 -0
  138. package/dist/errors.js.map +1 -0
  139. package/dist/google-analytics.d.ts +181 -0
  140. package/dist/google-analytics.d.ts.map +1 -0
  141. package/dist/google-analytics.js +176 -0
  142. package/dist/google-analytics.js.map +1 -0
  143. package/dist/google-tag-manager.d.ts +111 -0
  144. package/dist/google-tag-manager.d.ts.map +1 -0
  145. package/dist/google-tag-manager.js +129 -0
  146. package/dist/google-tag-manager.js.map +1 -0
  147. package/dist/i18n.d.ts +69 -0
  148. package/dist/i18n.d.ts.map +1 -0
  149. package/dist/i18n.js +59 -0
  150. package/dist/i18n.js.map +1 -0
  151. package/dist/import-export.d.ts +63 -0
  152. package/dist/import-export.d.ts.map +1 -0
  153. package/dist/import-export.js +37 -0
  154. package/dist/import-export.js.map +1 -0
  155. package/dist/index.d.ts +82 -0
  156. package/dist/index.d.ts.map +1 -0
  157. package/dist/index.js +126 -0
  158. package/dist/index.js.map +1 -0
  159. package/dist/inventory.d.ts +673 -0
  160. package/dist/inventory.d.ts.map +1 -0
  161. package/dist/inventory.js +412 -0
  162. package/dist/inventory.js.map +1 -0
  163. package/dist/invoice-ledger.d.ts +366 -0
  164. package/dist/invoice-ledger.d.ts.map +1 -0
  165. package/dist/invoice-ledger.js +114 -0
  166. package/dist/invoice-ledger.js.map +1 -0
  167. package/dist/invoices.d.ts +845 -0
  168. package/dist/invoices.d.ts.map +1 -0
  169. package/dist/invoices.js +314 -0
  170. package/dist/invoices.js.map +1 -0
  171. package/dist/kernel.d.ts +49 -0
  172. package/dist/kernel.d.ts.map +1 -0
  173. package/dist/kernel.js +19 -0
  174. package/dist/kernel.js.map +1 -0
  175. package/dist/languages.d.ts +122 -0
  176. package/dist/languages.d.ts.map +1 -0
  177. package/dist/languages.js +24 -0
  178. package/dist/languages.js.map +1 -0
  179. package/dist/linkedin-ads.d.ts +167 -0
  180. package/dist/linkedin-ads.d.ts.map +1 -0
  181. package/dist/linkedin-ads.js +156 -0
  182. package/dist/linkedin-ads.js.map +1 -0
  183. package/dist/megamenu.d.ts +556 -0
  184. package/dist/megamenu.d.ts.map +1 -0
  185. package/dist/megamenu.js +186 -0
  186. package/dist/megamenu.js.map +1 -0
  187. package/dist/meta-ads.d.ts +126 -0
  188. package/dist/meta-ads.d.ts.map +1 -0
  189. package/dist/meta-ads.js +112 -0
  190. package/dist/meta-ads.js.map +1 -0
  191. package/dist/mfa.d.ts +274 -0
  192. package/dist/mfa.d.ts.map +1 -0
  193. package/dist/mfa.js +187 -0
  194. package/dist/mfa.js.map +1 -0
  195. package/dist/modules.d.ts +1706 -0
  196. package/dist/modules.d.ts.map +1 -0
  197. package/dist/modules.js +1390 -0
  198. package/dist/modules.js.map +1 -0
  199. package/dist/newsletter.d.ts +611 -0
  200. package/dist/newsletter.d.ts.map +1 -0
  201. package/dist/newsletter.js +345 -0
  202. package/dist/newsletter.js.map +1 -0
  203. package/dist/orders.d.ts +1175 -0
  204. package/dist/orders.d.ts.map +1 -0
  205. package/dist/orders.js +630 -0
  206. package/dist/orders.js.map +1 -0
  207. package/dist/organizations.d.ts +938 -0
  208. package/dist/organizations.d.ts.map +1 -0
  209. package/dist/organizations.js +418 -0
  210. package/dist/organizations.js.map +1 -0
  211. package/dist/pagination.d.ts +21 -0
  212. package/dist/pagination.d.ts.map +1 -0
  213. package/dist/pagination.js +22 -0
  214. package/dist/pagination.js.map +1 -0
  215. package/dist/payment-methods.d.ts +472 -0
  216. package/dist/payment-methods.d.ts.map +1 -0
  217. package/dist/payment-methods.js +175 -0
  218. package/dist/payment-methods.js.map +1 -0
  219. package/dist/payment-return-url.d.ts +53 -0
  220. package/dist/payment-return-url.d.ts.map +1 -0
  221. package/dist/payment-return-url.js +35 -0
  222. package/dist/payment-return-url.js.map +1 -0
  223. package/dist/payments.d.ts +386 -0
  224. package/dist/payments.d.ts.map +1 -0
  225. package/dist/payments.js +84 -0
  226. package/dist/payments.js.map +1 -0
  227. package/dist/pim-connector.d.ts +60 -0
  228. package/dist/pim-connector.d.ts.map +1 -0
  229. package/dist/pim-connector.js +43 -0
  230. package/dist/pim-connector.js.map +1 -0
  231. package/dist/pim-field-path.d.ts +6 -0
  232. package/dist/pim-field-path.d.ts.map +1 -0
  233. package/dist/pim-field-path.js +101 -0
  234. package/dist/pim-field-path.js.map +1 -0
  235. package/dist/platform-language.d.ts +20 -0
  236. package/dist/platform-language.d.ts.map +1 -0
  237. package/dist/platform-language.js +22 -0
  238. package/dist/platform-language.js.map +1 -0
  239. package/dist/price-lists.d.ts +685 -0
  240. package/dist/price-lists.d.ts.map +1 -0
  241. package/dist/price-lists.js +330 -0
  242. package/dist/price-lists.js.map +1 -0
  243. package/dist/product-feeds.d.ts +2837 -0
  244. package/dist/product-feeds.d.ts.map +1 -0
  245. package/dist/product-feeds.js +1504 -0
  246. package/dist/product-feeds.js.map +1 -0
  247. package/dist/product-scope-overrides.d.ts +134 -0
  248. package/dist/product-scope-overrides.d.ts.map +1 -0
  249. package/dist/product-scope-overrides.js +82 -0
  250. package/dist/product-scope-overrides.js.map +1 -0
  251. package/dist/product-value-resolver.d.ts +88 -0
  252. package/dist/product-value-resolver.d.ts.map +1 -0
  253. package/dist/product-value-resolver.js +128 -0
  254. package/dist/product-value-resolver.js.map +1 -0
  255. package/dist/promotions.d.ts +678 -0
  256. package/dist/promotions.d.ts.map +1 -0
  257. package/dist/promotions.js +479 -0
  258. package/dist/promotions.js.map +1 -0
  259. package/dist/prompt-actions.d.ts +582 -0
  260. package/dist/prompt-actions.d.ts.map +1 -0
  261. package/dist/prompt-actions.js +221 -0
  262. package/dist/prompt-actions.js.map +1 -0
  263. package/dist/pwa.d.ts +293 -0
  264. package/dist/pwa.d.ts.map +1 -0
  265. package/dist/pwa.js +204 -0
  266. package/dist/pwa.js.map +1 -0
  267. package/dist/quick-order.d.ts +340 -0
  268. package/dist/quick-order.d.ts.map +1 -0
  269. package/dist/quick-order.js +177 -0
  270. package/dist/quick-order.js.map +1 -0
  271. package/dist/quote-requests.d.ts +538 -0
  272. package/dist/quote-requests.d.ts.map +1 -0
  273. package/dist/quote-requests.js +308 -0
  274. package/dist/quote-requests.js.map +1 -0
  275. package/dist/returns.d.ts +774 -0
  276. package/dist/returns.d.ts.map +1 -0
  277. package/dist/returns.js +389 -0
  278. package/dist/returns.js.map +1 -0
  279. package/dist/sales-channels.d.ts +392 -0
  280. package/dist/sales-channels.d.ts.map +1 -0
  281. package/dist/sales-channels.js +285 -0
  282. package/dist/sales-channels.js.map +1 -0
  283. package/dist/scope-notice.d.ts +60 -0
  284. package/dist/scope-notice.d.ts.map +1 -0
  285. package/dist/scope-notice.js +56 -0
  286. package/dist/scope-notice.js.map +1 -0
  287. package/dist/search.d.ts +321 -0
  288. package/dist/search.d.ts.map +1 -0
  289. package/dist/search.js +160 -0
  290. package/dist/search.js.map +1 -0
  291. package/dist/seo.d.ts +113 -0
  292. package/dist/seo.d.ts.map +1 -0
  293. package/dist/seo.js +63 -0
  294. package/dist/seo.js.map +1 -0
  295. package/dist/settings.d.ts +453 -0
  296. package/dist/settings.d.ts.map +1 -0
  297. package/dist/settings.js +337 -0
  298. package/dist/settings.js.map +1 -0
  299. package/dist/shipments.d.ts +140 -0
  300. package/dist/shipments.d.ts.map +1 -0
  301. package/dist/shipments.js +14 -0
  302. package/dist/shipments.js.map +1 -0
  303. package/dist/shipping-methods.d.ts +350 -0
  304. package/dist/shipping-methods.d.ts.map +1 -0
  305. package/dist/shipping-methods.js +99 -0
  306. package/dist/shipping-methods.js.map +1 -0
  307. package/dist/shopping-lists.d.ts +122 -0
  308. package/dist/shopping-lists.d.ts.map +1 -0
  309. package/dist/shopping-lists.js +92 -0
  310. package/dist/shopping-lists.js.map +1 -0
  311. package/dist/taxes.d.ts +106 -0
  312. package/dist/taxes.d.ts.map +1 -0
  313. package/dist/taxes.js +80 -0
  314. package/dist/taxes.js.map +1 -0
  315. package/dist/text-normalization.d.ts +199 -0
  316. package/dist/text-normalization.d.ts.map +1 -0
  317. package/dist/text-normalization.js +205 -0
  318. package/dist/text-normalization.js.map +1 -0
  319. package/dist/transactional-emails.d.ts +459 -0
  320. package/dist/transactional-emails.d.ts.map +1 -0
  321. package/dist/transactional-emails.js +212 -0
  322. package/dist/transactional-emails.js.map +1 -0
  323. package/dist/webhooks.d.ts +69 -0
  324. package/dist/webhooks.d.ts.map +1 -0
  325. package/dist/webhooks.js +53 -0
  326. package/dist/webhooks.js.map +1 -0
  327. 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"}