@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,277 @@
1
+ /**
2
+ * The environment-input declaration — what a running Endora needs, said once.
3
+ *
4
+ * Normative: `specs/117-instance-bring-up/contracts/environment-inputs.md`
5
+ * §1–§2, FR-001 and FR-005.
6
+ *
7
+ * ## Why the shape lives here
8
+ *
9
+ * Three programs read a declaration and none of them may author a second copy
10
+ * of it (D-100): `endora new instance` and `endora new storefront` (which
11
+ * values to resolve and write), `endora doctor` (which values to require and
12
+ * what their absence costs), and the reconciliation check. Four *authors*
13
+ * write one — the platform, each application, and every module in its own
14
+ * manifest — so the shape is a contract before it is anybody's data, which is
15
+ * what `packages/contracts` is for.
16
+ *
17
+ * ## `describes` carries both languages inline, and that is a decision
18
+ *
19
+ * §R1.1 puts this prose in the translation boundary's case 1 — the reader's
20
+ * language is resolvable when the sentence is composed — and says a module's
21
+ * ships in its own bundle. **A bundle is not reachable here.** The first
22
+ * reader is a CLI on a client's machine: it loads no `_i18n` reconciler, has
23
+ * no settings store to ask, and the *platform's* inputs have no owning
24
+ * module whose bundle they could sit in. So the sentence ships as `{ en, pl }`
25
+ * on the declaration itself, which satisfies the owner's translation policy
26
+ * (English by default, a Polish bundle beside it, English as the fallback)
27
+ * with the one mechanism a standalone program can read. The check holds both
28
+ * languages to a non-empty sentence, so a single-language declaration is a
29
+ * finding rather than a silent English-only input.
30
+ *
31
+ * ## There is deliberately no `default` field
32
+ *
33
+ * §R1.3. A declaration that could carry a default would become the seventieth
34
+ * home of an invented value, blessed by a contract — which is the exact thing
35
+ * the provenance line's `defaulted=0` exists to make impossible. The absence
36
+ * is load-bearing, not an omission.
37
+ *
38
+ * ## `consumers` scopes `requirement`; it does not merely describe it
39
+ *
40
+ * `specs/118-instance-member-selection/` establishes that an instance may
41
+ * deliberately omit a member — its admin being the ruled case (D-215). That
42
+ * member is absent when the operator declines it, or when
43
+ * `@endora-commerce/admin-shell` does not **resolve** at the version being
44
+ * installed (`specs/110-instance-repository/contracts/instance-tree.md` §2.4).
45
+ * This comment read *"while `@endora-commerce/admin-shell` does not exist"*
46
+ * until 2026-09-13, by which time `packages/admin-shell` did — a premise about
47
+ * the tree, written into a source file where nothing re-derives it. An input
48
+ * no written member reads is not "required and missing"; it is **not in this
49
+ * run's population at all**, which is what keeps the provenance line to four
50
+ * outcomes instead of five.
51
+ *
52
+ * **Scope by declared consumer, never by name.** Measured on this tree, the
53
+ * name-based rule is wrong on two of the three inputs that mention the admin:
54
+ *
55
+ * * `VITE_API_BASE_URL` — read by `admin/src` alone. Dropped with the
56
+ * member.
57
+ * * `ADMIN_BASE_URL` — read by the **backend** (`mfa`, when it composes the
58
+ * links it mails). Its *value* names the admin; its consumer is the
59
+ * backend, and it matters **more** when the admin is on another host.
60
+ * * `CORS_ALLOWED_ORIGINS` — read by the backend
61
+ * (`packages/platform/src/http/server.ts`), and its value has to name the
62
+ * admin's origin for the admin to work at all.
63
+ *
64
+ * Two of those three would be dropped by any rule keyed on the spelling.
65
+ */
66
+ import { z } from 'zod';
67
+ /**
68
+ * The trees that read an environment value.
69
+ *
70
+ * A value read by more than one is a value those trees must **agree** about,
71
+ * and under D-195 and D-207 two of the three are the client's own
72
+ * repositories — so the agreement cannot be checked from inside any one of
73
+ * them. That is `environment-inputs.md` §5's subject and the derivation is
74
+ * this field, never a table (R5.1, R5.4).
75
+ */
76
+ export const ENVIRONMENT_CONSUMERS = ['backend', 'admin', 'storefront'];
77
+ export const EnvironmentConsumerSchema = z.enum(ENVIRONMENT_CONSUMERS);
78
+ /**
79
+ * A sentence in every language the platform ships, on the declaration itself.
80
+ *
81
+ * See the header for why this is not a bundle key. Both members are required:
82
+ * "ships `en` and `pl`" enforced by the type rather than by anybody
83
+ * remembering, in the idiom the storefront's own `Record<MessageKey, string>`
84
+ * uses.
85
+ */
86
+ export const LocalizedSentenceSchema = z.object({
87
+ en: z.string().min(1),
88
+ pl: z.string().min(1),
89
+ });
90
+ /**
91
+ * Required, conditionally required, or optional — and the middle term is the
92
+ * one that matters (§R1.2).
93
+ *
94
+ * `requiredWhen` is a predicate over **another input**: `MEILISEARCH_URL` is
95
+ * required iff `CATALOG_SEARCH_BACKEND=meilisearch`, and without the predicate
96
+ * a doctor would demand a service two thirds of deployments do not run.
97
+ *
98
+ * `optional` carries **what is lost**, never the word "optional". An operator
99
+ * deciding whether to set `SETTINGS_SECRET_ENCRYPTION_KEY` needs to read
100
+ * *"secret settings cannot be read or written"*, which is the fact; that the
101
+ * boot survives without it is not.
102
+ */
103
+ export const EnvironmentRequirementSchema = z.discriminatedUnion('kind', [
104
+ z.object({ kind: z.literal('required') }),
105
+ z.object({
106
+ kind: z.literal('requiredWhen'),
107
+ /** The input the condition reads. Held to a declared name by the check. */
108
+ input: z.string().min(1),
109
+ /** The value of that input which makes this one required. */
110
+ equals: z.string().min(1),
111
+ }),
112
+ z.object({
113
+ kind: z.literal('optional'),
114
+ /** What the platform loses without it, in the operator's terms. */
115
+ without: LocalizedSentenceSchema,
116
+ }),
117
+ ]);
118
+ /**
119
+ * Who declares the input, which is what `foreign-input` is asked against.
120
+ *
121
+ * A module declaring an input another module owns is two answers to one
122
+ * question waiting to disagree, so ownership is a field rather than an
123
+ * inference from where the file sits.
124
+ */
125
+ export const EnvironmentInputOwnerSchema = z.discriminatedUnion('kind', [
126
+ z.object({ kind: z.literal('platform') }),
127
+ z.object({ kind: z.literal('application'), application: EnvironmentConsumerSchema }),
128
+ z.object({ kind: z.literal('module'), moduleId: z.string().min(1) }),
129
+ ]);
130
+ /** One entry per environment variable a running platform reads (§1). */
131
+ export const EnvironmentInputSchema = z.object({
132
+ /** The variable, verbatim. */
133
+ name: z.string().min(1),
134
+ /** One sentence: what it configures, in the operator's terms, not the code's. */
135
+ describes: LocalizedSentenceSchema,
136
+ requirement: EnvironmentRequirementSchema,
137
+ /** Whether the value must not be printed, logged or committed. */
138
+ secret: z.boolean(),
139
+ /**
140
+ * Whether a command may generate it (`input-resolution.md` §4).
141
+ *
142
+ * Permitted only where `secret` **and** where two correct values are
143
+ * interchangeable — the check refuses `generable` on a non-secret as
144
+ * `generable-without-secret`, and R4.5's judgement test (a URL, a name, a
145
+ * channel code, a hostname are never generable) is the author's.
146
+ */
147
+ generable: z.boolean(),
148
+ owner: EnvironmentInputOwnerSchema,
149
+ /** Which trees read it. Non-empty: an input nothing reads is a finding. */
150
+ consumers: z.array(EnvironmentConsumerSchema).min(1),
151
+ /**
152
+ * Which member of an instance this value is the **address of**, or `null`.
153
+ *
154
+ * Two programs ask *"which of these variables names the backend"* — `endora
155
+ * new storefront`, whose next step tells an author to point them at their
156
+ * backend, and the scaffold acceptance criterion, which points them at the
157
+ * backend it booted. Both used to answer it from the **shape of the value**
158
+ * in `.env.example`: *an absolute `http(s)` URL*. That predicate is only ever
159
+ * accidentally right. It cannot tell the backend's address from the
160
+ * storefront's own, from a CDN's or from an object store's, so the first
161
+ * URL-valued variable that is not a backend joins the set silently — and the
162
+ * next step then tells a client, in a file they own outright, that a variable
163
+ * "names the backend this storefront talks to" when it does not. A confident
164
+ * wrong sentence is worse than the silence it replaces.
165
+ *
166
+ * So it is declared rather than inferred, and the field is **required**: an
167
+ * author must answer it, and `EnvironmentInputSchema` refuses a declaration
168
+ * that does not — at `loadTreeDeclaration`, at `check:env-inputs`' fourth
169
+ * refusal, and in every other reader. An optional field would be forgotten
170
+ * exactly once, by the author of the next backend address, and nothing would
171
+ * say so.
172
+ *
173
+ * `null` is an answer and not an absence: this value is not the address of a
174
+ * member of this instance. A third party's address is `null` — `DATABASE_URL`
175
+ * and `REDIS_URL` are addresses, of a database and a cache, and neither is a
176
+ * member — because the question the two consumers ask is which of an
177
+ * *instance's own* parts a value points at. A list of origins is `null` too:
178
+ * `CORS_ALLOWED_ORIGINS` names several, and "the address of" is singular.
179
+ */
180
+ addressOf: EnvironmentConsumerSchema.nullable(),
181
+ });
182
+ /** A whole declaration, as an application or the platform publishes it. */
183
+ export const EnvironmentInputsSchema = z.array(EnvironmentInputSchema);
184
+ /**
185
+ * Is this input in the population of a run that writes exactly these members?
186
+ *
187
+ * The `specs/118-instance-member-selection/` scoping, as one predicate. An
188
+ * input whose declared consumers are all outside the written set is **out of
189
+ * the population**: not resolved, not prompted for, not counted, not refused.
190
+ *
191
+ * Reading it the other way — "required, and therefore missing" — is what would
192
+ * force a fifth provenance outcome, because such an input can be neither
193
+ * `defaulted` (there is nothing to invent) nor honestly reported as resolved.
194
+ */
195
+ export function isReadByAnyOf(input, members) {
196
+ return input.consumers.some((consumer) => members.includes(consumer));
197
+ }
198
+ /**
199
+ * The declared inputs a run over these members actually has to answer for.
200
+ *
201
+ * Order is the declaration's, which is the order a prompt asks in
202
+ * (`input-resolution.md` §1: "in the declared order"). Sorting here would put
203
+ * the sequence in a comparator rather than in the hands of whoever wrote the
204
+ * declaration, and the first thing an operator is asked would then depend on
205
+ * an alphabet.
206
+ */
207
+ export function scopeToMembers(inputs, members) {
208
+ return inputs.filter((input) => isReadByAnyOf(input, members));
209
+ }
210
+ /**
211
+ * Several authors' declarations, as the one population a reader has to answer.
212
+ *
213
+ * The four authors of `EnvironmentInput` are the platform, each application and
214
+ * every module in its own manifest, and nothing joins them: a scaffolded
215
+ * instance reads the platform's declaration **and** the manifest of every module
216
+ * it installed, and a doctor run against that instance reads the same pair. Two
217
+ * programs computing that join separately is two answers waiting to disagree,
218
+ * which is why the join is here rather than in either of them.
219
+ *
220
+ * **First author wins, and order is the first declaration's.** A name that
221
+ * migrates between authors is the case that happens — feature 121 moved
222
+ * `MEILISEARCH_URL` out of a module and into the platform, and a module may not
223
+ * describe a name the platform declares — so during such a move the platform's
224
+ * sentence is the one an operator reads, and the module's stale copy is shadowed
225
+ * rather than duplicated. Callers therefore pass the platform's declaration
226
+ * first. Across authors a shared name is expected and is **not** a finding;
227
+ * `check:env-inputs` says so, and this function is that rule's consequence
228
+ * rather than a second opinion about it.
229
+ */
230
+ export function unionEnvironmentInputs(declarations) {
231
+ const merged = new Map();
232
+ for (const declaration of declarations) {
233
+ for (const input of declaration) {
234
+ if (!merged.has(input.name))
235
+ merged.set(input.name, input);
236
+ }
237
+ }
238
+ return [...merged.values()];
239
+ }
240
+ /**
241
+ * The variables whose value is the address of `member`, in declaration order.
242
+ *
243
+ * One derivation, because the two programs that ask are `endora new storefront`
244
+ * — telling an author which variables to point at their backend — and the
245
+ * acceptance criterion, which points those same variables at the backend it
246
+ * booted. Deriving it twice is two answers waiting to disagree, and that is not
247
+ * hypothetical: the criterion once configured `PUBLIC_API_BASE_URL`, a name no
248
+ * file in the storefront reads, and its boot assertion measured the compiled-in
249
+ * fallback for a whole investigation.
250
+ *
251
+ * The population is the declaration handed in, so it is the **copy's** answer
252
+ * about the copy — under D-195 a client's storefront is theirs, declaring what
253
+ * it reads — and never a list compiled into either program.
254
+ */
255
+ export function addressVariablesFor(inputs, member) {
256
+ return inputs.filter((input) => input.addressOf === member).map((input) => input.name);
257
+ }
258
+ /**
259
+ * Is this input required, given what the rest of the environment holds?
260
+ *
261
+ * `requiredWhen` is resolved against the **resolved** values rather than
262
+ * against `process.env`, so a condition can be answered by a flag the operator
263
+ * has just supplied — which is the case that happens: a run that sets
264
+ * `CATALOG_SEARCH_BACKEND=meilisearch` on its command line must be asked for
265
+ * `MEILISEARCH_URL` in the same run, not in the next one.
266
+ */
267
+ export function isRequiredGiven(input, values) {
268
+ switch (input.requirement.kind) {
269
+ case 'required':
270
+ return true;
271
+ case 'requiredWhen':
272
+ return values[input.requirement.input] === input.requirement.equals;
273
+ case 'optional':
274
+ return false;
275
+ }
276
+ }
277
+ //# sourceMappingURL=environment-inputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment-inputs.js","sourceRoot":"","sources":["../src/environment-inputs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { z } from 'zod';
2
+ export declare const erpSyncJobStatusSchema: z.ZodEnum<{
3
+ error: "error";
4
+ success: "success";
5
+ pending: "pending";
6
+ in_progress: "in_progress";
7
+ poison: "poison";
8
+ }>;
9
+ export type ErpSyncJobStatus = z.infer<typeof erpSyncJobStatusSchema>;
10
+ export declare const erpSyncJobDirectionSchema: z.ZodEnum<{
11
+ erp_to_shop: "erp_to_shop";
12
+ shop_to_erp: "shop_to_erp";
13
+ }>;
14
+ export type ErpSyncJobDirection = z.infer<typeof erpSyncJobDirectionSchema>;
15
+ export declare const erpSyncIssueSeveritySchema: z.ZodEnum<{
16
+ error: "error";
17
+ info: "info";
18
+ warning: "warning";
19
+ }>;
20
+ export type ErpSyncIssueSeverity = z.infer<typeof erpSyncIssueSeveritySchema>;
21
+ export declare const erpSyncRunSummarySchema: z.ZodObject<{
22
+ considered: z.ZodNumber;
23
+ succeeded: z.ZodNumber;
24
+ failed: z.ZodNumber;
25
+ skipped: z.ZodNumber;
26
+ }, z.core.$strip>;
27
+ export type ErpSyncRunSummary = z.infer<typeof erpSyncRunSummarySchema>;
28
+ export declare const erpIdentityEntityTypeSchema: z.ZodEnum<{
29
+ order: "order";
30
+ quote_request: "quote_request";
31
+ article: "article";
32
+ contractor: "contractor";
33
+ offer: "offer";
34
+ sale_document: "sale_document";
35
+ }>;
36
+ export type ErpIdentityEntityType = z.infer<typeof erpIdentityEntityTypeSchema>;
37
+ export declare const ERP_CONNECTOR_REGISTRY_PORT: "erpConnectorRegistryPort";
38
+ /**
39
+ * Container name: `erpConnectorRegistryPort`. Owner: `erp_connector`.
40
+ *
41
+ * Mutual-exclusion registry among ERP connectors — see
42
+ * `specs/130-comarch-xl-sync/contracts/erp-connector-shared.md`.
43
+ */
44
+ export interface ErpConnectorRegistryPort {
45
+ /** Refuses when another ERP connector's activation Setting is true. */
46
+ assertCanActivate(moduleId: string): Promise<void>;
47
+ recordActive(moduleId: string, adminId: string | null): Promise<void>;
48
+ clearActive(moduleId: string): Promise<void>;
49
+ getActiveModuleId(): Promise<string | null>;
50
+ }
51
+ export declare const ERP_CONNECTOR_ALREADY_ACTIVE: "ERP_CONNECTOR_ALREADY_ACTIVE";
52
+ //# sourceMappingURL=erp-connector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"erp-connector.d.ts","sourceRoot":"","sources":["../src/erp-connector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,sBAAsB;;;;;;EAMjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,yBAAyB;;;EAAyC,CAAC;AAChF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,0BAA0B;;;;EAAuC,CAAC;AAC/E,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,uBAAuB;;;;;iBAKlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,2BAA2B;;;;;;;EAOtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,eAAO,MAAM,2BAA2B,EAAG,0BAAmC,CAAC;AAE/E;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,uEAAuE;IACvE,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,iBAAiB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC7C;AASD,eAAO,MAAM,4BAA4B,EAAG,8BAAuC,CAAC"}
@@ -0,0 +1,34 @@
1
+ // Shared ERP connector vocabulary — feature 119 (`erp_connector` package).
2
+ import { z } from 'zod';
3
+ export const erpSyncJobStatusSchema = z.enum([
4
+ 'pending',
5
+ 'in_progress',
6
+ 'success',
7
+ 'error',
8
+ 'poison',
9
+ ]);
10
+ export const erpSyncJobDirectionSchema = z.enum(['erp_to_shop', 'shop_to_erp']);
11
+ export const erpSyncIssueSeveritySchema = z.enum(['info', 'warning', 'error']);
12
+ export const erpSyncRunSummarySchema = z.object({
13
+ considered: z.number().int().nonnegative(),
14
+ succeeded: z.number().int().nonnegative(),
15
+ failed: z.number().int().nonnegative(),
16
+ skipped: z.number().int().nonnegative(),
17
+ });
18
+ export const erpIdentityEntityTypeSchema = z.enum([
19
+ 'article',
20
+ 'contractor',
21
+ 'order',
22
+ 'quote_request',
23
+ 'offer',
24
+ 'sale_document',
25
+ ]);
26
+ export const ERP_CONNECTOR_REGISTRY_PORT = 'erpConnectorRegistryPort';
27
+ // Feature 132 — `ERP_CONNECTOR_MODULES` is **gone**, and this array is the one whose
28
+ // deletion repairs a live Principle XV violation: a per-deployment **overlay** module
29
+ // had to be written into this core file to join its family, because there was no
30
+ // other way in. The family is declared by its members
31
+ // (`capabilities: ['erp-connector']`) and derived by the platform; `erp_connector`
32
+ // owns the key and mints the refusal code.
33
+ export const ERP_CONNECTOR_ALREADY_ACTIVE = 'ERP_CONNECTOR_ALREADY_ACTIVE';
34
+ //# sourceMappingURL=erp-connector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"erp-connector.js","sourceRoot":"","sources":["../src/erp-connector.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAE3E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,IAAI,CAAC;IAC3C,SAAS;IACT,aAAa;IACb,SAAS;IACT,OAAO;IACP,QAAQ;CACT,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC,CAAC;AAGhF,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;AAG/E,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAC1C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACzC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACtC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;CACxC,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,IAAI,CAAC;IAChD,SAAS;IACT,YAAY;IACZ,OAAO;IACP,eAAe;IACf,OAAO;IACP,eAAe;CAChB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,2BAA2B,GAAG,0BAAmC,CAAC;AAgB/E,qFAAqF;AACrF,sFAAsF;AACtF,iFAAiF;AACjF,sDAAsD;AACtD,mFAAmF;AACnF,2CAA2C;AAE3C,MAAM,CAAC,MAAM,4BAA4B,GAAG,8BAAuC,CAAC"}