@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,337 @@
1
+ // Settings module — feature 004 contract surface.
2
+ // Holds three logical sections in one file (matching the convention used by
3
+ // every other module in @endora-commerce/contracts):
4
+ // (1) Setting value-type Zod registry.
5
+ // (2) Module manifest schemas — the cross-module registration contract that
6
+ // any backend module may use to declare its setting groups and settings
7
+ // (see specs/004-settings-module/contracts/settings-004.contract.md, A).
8
+ // (3) Admin HTTP request/response schemas (section C).
9
+ import { z } from 'zod';
10
+ // ---------------------------------------------------------------------------
11
+ // (1) Value types
12
+ // ---------------------------------------------------------------------------
13
+ export const SettingValueTypeSchema = z.enum([
14
+ 'string',
15
+ 'number',
16
+ 'boolean',
17
+ 'json',
18
+ 'string_list',
19
+ 'secret',
20
+ // Feature 058 — references a saved credential configuration by its code,
21
+ // constrained to one configuration type (see `configurationType` below).
22
+ 'credential_ref',
23
+ ]);
24
+ /**
25
+ * Returns the Zod schema corresponding to a setting's declared `valueType`.
26
+ * Callers supplying their own narrower schema to `SettingsService.get<T>()`
27
+ * still get the looser per-type validation through this helper at write time.
28
+ *
29
+ * `secret` accepts a plain string on write (the backend encrypts before
30
+ * persisting — feature 043 / FR-021); read endpoints never return it.
31
+ */
32
+ export function valueSchemaForType(t) {
33
+ switch (t) {
34
+ case 'string':
35
+ return z.string();
36
+ case 'number':
37
+ return z.number();
38
+ case 'boolean':
39
+ return z.boolean();
40
+ case 'json':
41
+ return z.unknown();
42
+ case 'string_list':
43
+ return z.array(z.string());
44
+ case 'secret':
45
+ return z.string();
46
+ case 'credential_ref':
47
+ // The stored value is a configuration code (or '' when not configured).
48
+ return z.string();
49
+ }
50
+ }
51
+ // ---------------------------------------------------------------------------
52
+ // (2) Module manifest
53
+ // ---------------------------------------------------------------------------
54
+ const groupCodeRe = /^[a-z][a-z0-9_]{0,118}[a-z0-9]$/;
55
+ /**
56
+ * Setting code shape. Exported because feature 073's module activation block
57
+ * (`ModuleActivationSchema` in `modules.ts`) declares the code of an ordinary
58
+ * Setting row and must validate it identically.
59
+ */
60
+ export const settingCodeRe = /^[a-z][a-z0-9_][a-z0-9_.]*[a-z0-9]$/;
61
+ const moduleCodeRe = /^[a-z][a-z0-9_]{0,118}[a-z0-9]$/;
62
+ export const GroupManifestEntrySchema = z.object({
63
+ code: z.string().regex(groupCodeRe),
64
+ name: z.string().min(1).max(200),
65
+ /**
66
+ * Sales-channel scope by `sales_channels.code`. Omit (or empty) to mean
67
+ * "applies to all channels" (R-5 / FR-004).
68
+ */
69
+ salesChannelCodes: z.array(z.string()).optional(),
70
+ /**
71
+ * Reserved for the built-in `general` group only — other modules MUST NOT
72
+ * set this to `true`. The reconciler refuses such manifests at boot.
73
+ */
74
+ isSystemProtected: z.boolean().optional(),
75
+ });
76
+ export const SettingManifestEntrySchema = z
77
+ .object({
78
+ code: z.string().regex(settingCodeRe),
79
+ name: z.string().min(1).max(200),
80
+ description: z.string().max(2000).optional(),
81
+ /** Defaults to `'general'` when omitted. */
82
+ groupCode: z.string().optional(),
83
+ valueType: SettingValueTypeSchema,
84
+ defaultValue: z.unknown(),
85
+ /**
86
+ * Stored `default_value`s this manifest's current `defaultValue`
87
+ * supersedes (feature 078, D-95.3).
88
+ *
89
+ * `ManifestReconciler` refuses a `defaultValue` change as breaking, because
90
+ * a silent default change alters behaviour for every deployment that never
91
+ * overrode it. Declaring the prior value is how a module says which change
92
+ * is intended and bounded: a stored default equal to one of these is
93
+ * updated to the new one at boot, and anything else still throws
94
+ * `BreakingChangeRejected`. Same shape, and the same self-healing argument,
95
+ * as the sanctioned `string` → `secret` valueType upgrade.
96
+ */
97
+ previousDefaultValues: z.array(z.unknown()).optional(),
98
+ salesChannelCodes: z.array(z.string()).optional(),
99
+ /**
100
+ * Closed list of allowed values for a `string` setting. When present the
101
+ * setting behaves like an enum: the admin renders a dropdown instead of a
102
+ * free-text input and the backend rejects any value outside the list. Only
103
+ * valid for `valueType: 'string'`; the `defaultValue` must be one of the
104
+ * options.
105
+ */
106
+ enumOptions: z.array(z.string().min(1)).min(1).optional(),
107
+ /**
108
+ * Feature 058 — the configuration type a `credential_ref` setting is
109
+ * constrained to (e.g. `'llm'`). REQUIRED when `valueType === 'credential_ref'`
110
+ * and forbidden otherwise. The admin renders a picker of matching
111
+ * configurations; the backend never interprets provider meaning.
112
+ */
113
+ configurationType: z.string().min(1).optional(),
114
+ /**
115
+ * When true, the setting is registered and remains fully readable/writable
116
+ * through its owning module's dedicated surface (e.g. the PWA settings
117
+ * page), but is excluded from the generic admin Settings screen so it is
118
+ * managed in exactly one place. A group whose settings are all hidden does
119
+ * not appear in the generic Settings list at all.
120
+ */
121
+ hidden: z.boolean().optional(),
122
+ })
123
+ .refine((s) => s.valueType !== 'secret' || s.defaultValue === '', {
124
+ message: "A 'secret' setting's defaultValue must be the empty string — manifests can never ship a real credential.",
125
+ path: ['defaultValue'],
126
+ })
127
+ .refine((s) => s.enumOptions === undefined || s.valueType === 'string', {
128
+ message: "enumOptions is only supported for valueType 'string'.",
129
+ path: ['enumOptions'],
130
+ })
131
+ .refine((s) => (s.valueType === 'credential_ref') === (s.configurationType !== undefined), {
132
+ message: "configurationType is required for valueType 'credential_ref' and forbidden otherwise.",
133
+ path: ['configurationType'],
134
+ })
135
+ .refine((s) => s.enumOptions === undefined ||
136
+ (typeof s.defaultValue === 'string' && s.enumOptions.includes(s.defaultValue)), {
137
+ message: 'An enum setting defaultValue must be one of its enumOptions.',
138
+ path: ['defaultValue'],
139
+ });
140
+ export const ModuleSettingsManifestSchema = z.object({
141
+ moduleCode: z.string().regex(moduleCodeRe),
142
+ groups: z.array(GroupManifestEntrySchema).default([]),
143
+ settings: z.array(SettingManifestEntrySchema).default([]),
144
+ });
145
+ /**
146
+ * Identity-with-validation helper for module authors. Modules export a single
147
+ * constant with `defineModuleSettingsManifest({...})`; this gives them full
148
+ * TypeScript inference and the reconciler can ingest the value directly.
149
+ */
150
+ export function defineModuleSettingsManifest(m) {
151
+ return ModuleSettingsManifestSchema.parse(m);
152
+ }
153
+ // ---------------------------------------------------------------------------
154
+ // (3) Admin HTTP
155
+ // ---------------------------------------------------------------------------
156
+ export const SettingValueByChannelSchema = z.object({
157
+ salesChannelId: z.uuid(),
158
+ salesChannelCode: z.string(),
159
+ value: z.unknown(),
160
+ /**
161
+ * Secret settings only (feature 043 / FR-021): `value` is redacted to
162
+ * `null` on every read; `isSet` tells the UI whether a value exists.
163
+ * Absent for non-secret settings.
164
+ */
165
+ isSet: z.boolean().optional(),
166
+ updatedAt: z.iso.datetime(),
167
+ });
168
+ export const SettingDtoSchema = z.object({
169
+ id: z.uuid(),
170
+ code: z.string(),
171
+ name: z.string(),
172
+ description: z.string().nullable(),
173
+ valueType: SettingValueTypeSchema,
174
+ ownerModule: z.string(),
175
+ salesChannelCodes: z.array(z.string()),
176
+ /**
177
+ * Closed list of allowed values for an enum-style `string` setting (manifest
178
+ * `enumOptions`). Empty/absent for ordinary free-text settings; when present
179
+ * the admin renders a dropdown bound to these values.
180
+ */
181
+ enumOptions: z.array(z.string()).nullish(),
182
+ /**
183
+ * Feature 058 — for a `credential_ref` setting, the configuration type the
184
+ * reference is constrained to (e.g. `'llm'`); the admin filters the config
185
+ * picker by this. Null/absent for every other value type.
186
+ */
187
+ configurationType: z.string().nullish(),
188
+ /**
189
+ * Manifest-declared default value (immutable; surfaces in `defaultValue`).
190
+ */
191
+ defaultValue: z.unknown(),
192
+ /**
193
+ * Platform-wide global override the admin has set, or `null` when the
194
+ * admin has not customised it. Resolver chain when reading a value:
195
+ * per-channel SettingValue row → globalValue (when non-null) → defaultValue.
196
+ * "All channels" admin writes update this field only and leave per-channel
197
+ * rows untouched.
198
+ */
199
+ globalValue: z.unknown().nullable(),
200
+ /**
201
+ * Secret settings only (feature 043 / FR-021): `defaultValue` and
202
+ * `globalValue` are redacted to `null` on every read; this flag tells the
203
+ * UI whether a global override exists. Absent for non-secret settings.
204
+ */
205
+ globalValueIsSet: z.boolean().optional(),
206
+ valuesByChannel: z.array(SettingValueByChannelSchema),
207
+ /**
208
+ * Server-computed effective version (= `max(setting.updatedAt,
209
+ * max(values.updatedAt))`). Echo back as `expectedVersion` on PUT
210
+ * /:code/value to detect concurrent edits — matches the ETag header
211
+ * returned by the detail endpoint.
212
+ */
213
+ version: z.iso.datetime(),
214
+ /**
215
+ * Feature 073 — `false` when the owning module is not effectively present.
216
+ * The value is still read (off is not uninstall: the stored configuration
217
+ * survives), but every write against it is refused (FR-033). Classified per
218
+ * setting rather than per group because the module's own activation control
219
+ * stays writable while it is off, so a group-level filter would either hide
220
+ * the control or render the whole group.
221
+ */
222
+ editable: z.boolean().optional(),
223
+ /**
224
+ * Feature 073 — this setting **is** its module's activation control: the
225
+ * single exception that stays writable while the module is off, and the one
226
+ * setting the ordinary write path refuses (the audited Command owns it).
227
+ */
228
+ activationControl: z.boolean().optional(),
229
+ });
230
+ export const SettingGroupDtoSchema = z.object({
231
+ id: z.uuid(),
232
+ code: z.string(),
233
+ name: z.string(),
234
+ isSystemProtected: z.boolean(),
235
+ ownerModule: z.string(),
236
+ salesChannelCodes: z.array(z.string()),
237
+ settings: z.array(SettingDtoSchema),
238
+ });
239
+ export const SettingsListResponseSchema = z.object({
240
+ groups: z.array(SettingGroupDtoSchema),
241
+ });
242
+ export const SettingsListQuerySchema = z.object({
243
+ groupCode: z.string().optional(),
244
+ });
245
+ export const SetValueAllRequestSchema = z.object({
246
+ scope: z.literal('all'),
247
+ value: z.unknown(),
248
+ });
249
+ export const SetValueSubsetRequestSchema = z.object({
250
+ scope: z.literal('subset'),
251
+ salesChannelCodes: z.array(z.string()).min(1),
252
+ value: z.unknown(),
253
+ });
254
+ export const SetValueRequestSchema = z.discriminatedUnion('scope', [
255
+ SetValueAllRequestSchema,
256
+ SetValueSubsetRequestSchema,
257
+ ]);
258
+ export const ResetValueQuerySchema = z.object({
259
+ /** Comma-separated list; omit to reset for every channel. */
260
+ salesChannelCodes: z.string().optional(),
261
+ });
262
+ export const GroupCreateRequestSchema = z.object({
263
+ code: z.string().regex(groupCodeRe),
264
+ name: z.string().min(1).max(200),
265
+ salesChannelCodes: z.array(z.string()).optional(),
266
+ });
267
+ export const GroupUpdateRequestSchema = z.object({
268
+ name: z.string().min(1).max(200).optional(),
269
+ salesChannelCodes: z.array(z.string()).optional(),
270
+ });
271
+ export const SettingDetailResponseSchema = SettingDtoSchema;
272
+ // ---------------------------------------------------------------------------
273
+ // (4) Storefront shop-information surface
274
+ // ---------------------------------------------------------------------------
275
+ /**
276
+ * Public shop / company contact information resolved for the active sales
277
+ * channel. Backs the storefront footer, the 404 "need help?" block and the
278
+ * contact form. Every field is a string; an unset (or not-yet-registered)
279
+ * setting resolves to an empty string so the storefront can decide what to
280
+ * render. The contact-form recipient list is intentionally omitted — it is
281
+ * an internal routing concern, not public information.
282
+ */
283
+ export const ShopInfoSchema = z.object({
284
+ name: z.string(),
285
+ address: z.string(),
286
+ contactEmail: z.string(),
287
+ supportEmail: z.string(),
288
+ phone: z.string(),
289
+ });
290
+ export const ShopInfoResponseSchema = z.object({ data: ShopInfoSchema });
291
+ // ---------------------------------------------------------------------------
292
+ // (5) Cache administration (maintenance)
293
+ // ---------------------------------------------------------------------------
294
+ /**
295
+ * A clearable cache namespace surfaced in the admin "Clear cache" page. `key`
296
+ * is the stable identifier the client sends back to clear it; `label` and
297
+ * `description` are human-readable (English defaults — the admin localises via
298
+ * the `settings.cache.namespace.<key>.*` i18n keys).
299
+ */
300
+ export const CacheNamespaceDtoSchema = z.object({
301
+ key: z.string(),
302
+ label: z.string(),
303
+ description: z.string(),
304
+ });
305
+ export const CacheNamespacesResponseSchema = z.object({
306
+ data: z.array(CacheNamespaceDtoSchema),
307
+ /** False when no Redis cache is wired (clearing is a no-op). */
308
+ cacheEnabled: z.boolean(),
309
+ });
310
+ export const ClearCacheRequestSchema = z.object({
311
+ /** Namespace keys to clear, or the literal `"all"` for every namespace. */
312
+ namespaces: z.union([z.literal('all'), z.array(z.string()).min(1)]),
313
+ });
314
+ export const ClearedCacheNamespaceSchema = z.object({
315
+ key: z.string(),
316
+ deletedKeysCount: z.number().int().nonnegative(),
317
+ });
318
+ export const ClearCacheResultSchema = z.object({
319
+ data: z.object({
320
+ cleared: z.array(ClearedCacheNamespaceSchema),
321
+ totalDeletedKeys: z.number().int().nonnegative(),
322
+ }),
323
+ });
324
+ // ---------------------------------------------------------------------------
325
+ // (6) Storefront home-page configuration
326
+ // ---------------------------------------------------------------------------
327
+ /**
328
+ * Resolved storefront home-page configuration for the active sales channel.
329
+ * `cmsPageSlug` is the CMS page slug an operator chose as the home page, or
330
+ * null when none is configured (the storefront then renders its built-in
331
+ * landing page).
332
+ */
333
+ export const HomepageConfigSchema = z.object({
334
+ cmsPageSlug: z.string().nullable(),
335
+ });
336
+ export const HomepageConfigResponseSchema = z.object({ data: HomepageConfigSchema });
337
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * `shipments` module contracts — the in-process port surface (feature 075,
3
+ * Phase P).
4
+ *
5
+ * One inbound site, and it is the delivery-side twin of the one `payments`
6
+ * published in wave 1: the order-confirmation e-mail renders a shipping line,
7
+ * and `orders` reaches this module's renderer registry for it.
8
+ *
9
+ * Plain TypeScript rather than Zod: this describes an in-process call. The
10
+ * module's HTTP shapes live in `shipping-methods.ts`, which is
11
+ * `delivery_methods`' contracts file and covers the shipment record too.
12
+ */
13
+ import type { ShipmentStatus } from './shipping-methods.js';
14
+ /** What the order-confirmation e-mail knows about the shipping method. */
15
+ export interface ShippingEmailContext {
16
+ /** Resolved display name of the shipping method. */
17
+ name: string;
18
+ /** Flat surcharge (`price`) applied for this method, in the order currency. */
19
+ cost: number;
20
+ currency: string;
21
+ }
22
+ /**
23
+ * Container name: `shippingEmailRendererPort`. Owner: `shipments`.
24
+ *
25
+ * A shipping adapter may register a custom renderer under a key (feature 035,
26
+ * FR-016/FR-017); when none is registered the platform default is used, so the
27
+ * shipping section always renders.
28
+ *
29
+ * `orders` reaches the resolver today and then calls the function it gets
30
+ * back. The port collapses those two steps for the reason its payment twin
31
+ * gives: a consumer that resolved a renderer and got `undefined` would have to
32
+ * hold a copy of the default text, and two copies of a default are how a
33
+ * default stops being one.
34
+ *
35
+ * Bodies are plain text (see `EmailMailerSendInput.text`), so a renderer is a
36
+ * `(ctx) => string` builder rather than a component.
37
+ *
38
+ * **Owner off:** the seam fails closed — resolving this port throws
39
+ * `ModuleDisabledError` and the call answers 503 `MODULE_DISABLED`, so nothing
40
+ * half-executes. Whether `shipments` has an off state at all is its manifest's
41
+ * `activation` to say, not this line's: a module declaring
42
+ * `nonDeactivatable` never enters one.
43
+ */
44
+ export interface ShippingEmailRendererPort {
45
+ render(rendererKey: string | null, ctx: ShippingEmailContext): string;
46
+ }
47
+ /**
48
+ * Container name: `shipmentUsagePort`. Owner: `shipments`.
49
+ *
50
+ * "Has this delivery method ever shipped anything?" — the one question
51
+ * `delivery_methods` has to ask before it deletes a method row (feature 035,
52
+ * FR-003; feature 077, D-87).
53
+ *
54
+ * It asked it in raw SQL until feature 075 drained the shard:
55
+ * `select count(*) from "shipments" where "delivery_method_id" = ?`, inside the
56
+ * delete Command's own transaction. The statement named no import specifier, so
57
+ * the boundary it crossed compiled and returned rows.
58
+ *
59
+ * **`shipments.delivery_method_id` carries no foreign key** — the table was
60
+ * created without one — so this count is the only thing standing between a
61
+ * delete and permanently orphaned shipment history. That is why the answer is
62
+ * asked of the owner rather than approximated, and why the caller refuses the
63
+ * delete when it cannot get one.
64
+ *
65
+ * The count runs on this module's own `EntityManager`, so it is outside any
66
+ * transaction the caller has open. That costs nothing here: `shipments` is a
67
+ * table the delete transaction never writes, so there is no write of its own
68
+ * for the read to be blind to, and the race a cross-module read cannot close —
69
+ * a shipment created between the count and the commit — was equally open to the
70
+ * in-transaction statement this replaced, which took no lock either.
71
+ *
72
+ * **Owner off:** `delivery_methods` decides this module's presence *before* it
73
+ * resolves the port and refuses the delete with a sentence naming this module,
74
+ * rather than resolving a gate and catching it — see its manifest's
75
+ * `nonBindingDependencies` entry. The edge is non-binding because `shipments`
76
+ * declares `delivery_methods`, so declaring it back closes a cycle, and
77
+ * acknowledging it would make `shipments` unswitchable for as long as delivery
78
+ * methods are present.
79
+ */
80
+ export interface ShipmentUsagePort {
81
+ /** How many shipment rows — of any status — reference this delivery method. */
82
+ countForDeliveryMethod(deliveryMethodId: string): Promise<number>;
83
+ }
84
+ /**
85
+ * One shipment attempt as it crosses a module boundary — a plain shape, never
86
+ * the ORM entity (FR-011).
87
+ *
88
+ * `providerDetails` is the carrier envelope the adapter deposited. It stays
89
+ * opaque here for the reason the order's `shippingAdapterData` does: only the
90
+ * adapter that wrote it knows its shape, and the reader that needs it is that
91
+ * same adapter reading back what it wrote.
92
+ */
93
+ export interface ShipmentRecord {
94
+ id: string;
95
+ orderId: string;
96
+ deliveryMethodId: string;
97
+ status: ShipmentStatus;
98
+ externalReference: string | null;
99
+ providerDetails: Record<string, unknown> | null;
100
+ failureReason: string | null;
101
+ attemptNo: number;
102
+ createdAt: Date;
103
+ updatedAt: Date;
104
+ }
105
+ /**
106
+ * Container name: `shipmentReadPort`. Owner: `shipments`.
107
+ *
108
+ * "What state is this shipment in, and which carrier reference does it carry?"
109
+ * — the question a carrier module asks twice: when an inbound webhook names
110
+ * only the carrier's own id, and when an admin asks for the label of an
111
+ * attempt it opened.
112
+ *
113
+ * Published for feature 068. `inpost` answered both by loading this module's
114
+ * `Shipment` entity directly, which its cross-module ledger recorded as debt
115
+ * with exactly this port as the retiring condition. It is a **read**, so it is
116
+ * a method here and not an `EntityManager`-taking apply port: handing a read a
117
+ * transaction handle re-opens a write seam to serve it.
118
+ *
119
+ * `findByExternalReference` is not a duplicate of `findById`. A carrier that
120
+ * signs nothing and names only its own id has to be correlated, and until the
121
+ * first `receive_shipment` lands, `externalReference` is where the adapter put
122
+ * that id — after it, a tracking number replaces it. The lookup is an indexed
123
+ * equality read, and the caller is expected to have its own correlation table
124
+ * for everything after the first event.
125
+ *
126
+ * **Owner off:** the seam fails closed — resolving this port throws
127
+ * `ModuleDisabledError` and the call answers 503 `MODULE_DISABLED`. That is the
128
+ * right answer for both callers: a label for a shipment the platform will not
129
+ * read, and a carrier callback the platform cannot apply, are both operations
130
+ * that must not half-execute.
131
+ */
132
+ export interface ShipmentReadPort {
133
+ findById(id: string): Promise<ShipmentRecord | null>;
134
+ /**
135
+ * The most recent attempt carrying `reference`, or null. Newest first, so a
136
+ * reference re-used across attempts answers with the live one.
137
+ */
138
+ findByExternalReference(reference: string): Promise<ShipmentRecord | null>;
139
+ }
140
+ //# sourceMappingURL=shipments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shipments.d.ts","sourceRoot":"","sources":["../src/shipments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,0EAA0E;AAC1E,MAAM,WAAW,oBAAoB;IACnC,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,yBAAyB;IACxC,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,oBAAoB,GAAG,MAAM,CAAC;CACvE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACnE;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,cAAc,CAAC;IACvB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAChD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACrD;;;OAGG;IACH,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CAC5E"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `shipments` module contracts — the in-process port surface (feature 075,
3
+ * Phase P).
4
+ *
5
+ * One inbound site, and it is the delivery-side twin of the one `payments`
6
+ * published in wave 1: the order-confirmation e-mail renders a shipping line,
7
+ * and `orders` reaches this module's renderer registry for it.
8
+ *
9
+ * Plain TypeScript rather than Zod: this describes an in-process call. The
10
+ * module's HTTP shapes live in `shipping-methods.ts`, which is
11
+ * `delivery_methods`' contracts file and covers the shipment record too.
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=shipments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shipments.js","sourceRoot":"","sources":["../src/shipments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}