@openlup/platform 0.21.0 → 0.23.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 (349) hide show
  1. package/CHANGELOG.md +432 -146
  2. package/README.md +82 -589
  3. package/dist/composition/composeBundle.d.ts +7 -0
  4. package/dist/composition/composeBundle.js +2 -0
  5. package/dist/composition/fulfillmentContribution.d.ts +21 -0
  6. package/dist/composition/fulfillmentContribution.js +19 -0
  7. package/dist/composition/index.d.ts +1 -0
  8. package/dist/composition/index.js +1 -0
  9. package/dist/fulfillment/adapterConformance.d.ts +3 -0
  10. package/dist/fulfillment/adapterConformance.js +223 -0
  11. package/dist/fulfillment/bindings.d.ts +3 -0
  12. package/dist/fulfillment/bindings.js +29 -0
  13. package/dist/fulfillment/commerceFulfillmentHandlers.d.ts +29 -0
  14. package/dist/fulfillment/commerceFulfillmentHandlers.js +184 -0
  15. package/dist/fulfillment/commerceFulfillmentReadModel.d.ts +86 -0
  16. package/dist/fulfillment/commerceFulfillmentReadModel.js +131 -0
  17. package/dist/fulfillment/contracts/alignment.d.ts +25 -0
  18. package/dist/fulfillment/contracts/alignment.js +1 -0
  19. package/dist/fulfillment/contracts/bindings.d.ts +51 -0
  20. package/dist/fulfillment/contracts/bindings.js +1 -0
  21. package/dist/fulfillment/contracts/capabilities.d.ts +29 -0
  22. package/dist/fulfillment/contracts/capabilities.js +1 -0
  23. package/dist/fulfillment/contracts/conformance.d.ts +95 -0
  24. package/dist/fulfillment/contracts/conformance.js +1 -0
  25. package/dist/fulfillment/contracts/customerAlignment.d.ts +6 -0
  26. package/dist/fulfillment/contracts/customerAlignment.js +1 -0
  27. package/dist/fulfillment/contracts/dispatch.d.ts +143 -0
  28. package/dist/fulfillment/contracts/dispatch.js +1 -0
  29. package/dist/fulfillment/contracts/index.d.ts +18 -0
  30. package/dist/fulfillment/contracts/index.js +1 -0
  31. package/dist/fulfillment/contracts/label.d.ts +35 -0
  32. package/dist/fulfillment/contracts/label.js +1 -0
  33. package/dist/fulfillment/contracts/nativeUnsupported.d.ts +6 -0
  34. package/dist/fulfillment/contracts/nativeUnsupported.js +1 -0
  35. package/dist/fulfillment/contracts/observation.d.ts +72 -0
  36. package/dist/fulfillment/contracts/observation.js +1 -0
  37. package/dist/fulfillment/contracts/operator.d.ts +64 -0
  38. package/dist/fulfillment/contracts/operator.js +1 -0
  39. package/dist/fulfillment/contracts/read.d.ts +110 -0
  40. package/dist/fulfillment/contracts/read.js +1 -0
  41. package/dist/fulfillment/contracts/readback.d.ts +59 -0
  42. package/dist/fulfillment/contracts/readback.js +1 -0
  43. package/dist/fulfillment/contracts/replacement.d.ts +34 -0
  44. package/dist/fulfillment/contracts/replacement.js +1 -0
  45. package/dist/fulfillment/contracts/store.d.ts +89 -0
  46. package/dist/fulfillment/contracts/store.js +1 -0
  47. package/dist/fulfillment/contracts/sync.d.ts +226 -0
  48. package/dist/fulfillment/contracts/sync.js +1 -0
  49. package/dist/fulfillment/currentFulfillmentParcel.d.ts +2 -0
  50. package/dist/fulfillment/currentFulfillmentParcel.js +1 -0
  51. package/dist/fulfillment/delayReadModel.d.ts +11 -0
  52. package/dist/fulfillment/delayReadModel.js +45 -0
  53. package/dist/fulfillment/deliveryAlignmentReadModel.d.ts +4 -0
  54. package/dist/fulfillment/deliveryAlignmentReadModel.js +12 -0
  55. package/dist/fulfillment/dispatchProjection.d.ts +26 -0
  56. package/dist/fulfillment/dispatchProjection.js +107 -0
  57. package/dist/fulfillment/fulfillmentObservationEffects.d.ts +66 -0
  58. package/dist/fulfillment/fulfillmentObservationEffects.js +36 -0
  59. package/dist/fulfillment/handlerSchemas.d.ts +647 -0
  60. package/dist/fulfillment/handlerSchemas.js +213 -0
  61. package/dist/fulfillment/handlerSupport.d.ts +33 -0
  62. package/dist/fulfillment/handlerSupport.js +25 -0
  63. package/dist/fulfillment/index.d.ts +38 -0
  64. package/dist/fulfillment/index.js +37 -0
  65. package/dist/fulfillment/labelLifecycle.d.ts +24 -0
  66. package/dist/fulfillment/labelLifecycle.js +9 -0
  67. package/dist/fulfillment/lowStockEvidenceHandler.d.ts +36 -0
  68. package/dist/fulfillment/lowStockEvidenceHandler.js +46 -0
  69. package/dist/fulfillment/migrations.d.ts +32 -0
  70. package/dist/fulfillment/migrations.js +9 -0
  71. package/dist/fulfillment/nativeUnsupported.d.ts +10 -0
  72. package/dist/fulfillment/nativeUnsupported.js +18 -0
  73. package/dist/fulfillment/normalizedFulfillmentFacts.d.ts +2 -0
  74. package/dist/fulfillment/normalizedFulfillmentFacts.js +1 -0
  75. package/dist/fulfillment/observationProjection.d.ts +32 -0
  76. package/dist/fulfillment/observationProjection.js +90 -0
  77. package/dist/fulfillment/omnipack/capabilities.d.ts +3 -0
  78. package/dist/fulfillment/omnipack/capabilities.js +16 -0
  79. package/dist/fulfillment/omnipack/client.d.ts +39 -0
  80. package/dist/fulfillment/omnipack/client.js +172 -0
  81. package/dist/fulfillment/omnipack/index.d.ts +55 -0
  82. package/dist/fulfillment/omnipack/index.js +408 -0
  83. package/dist/fulfillment/omnipack/mappers.d.ts +79 -0
  84. package/dist/fulfillment/omnipack/mappers.js +199 -0
  85. package/dist/fulfillment/omnipack/observation.d.ts +28 -0
  86. package/dist/fulfillment/omnipack/observation.js +72 -0
  87. package/dist/fulfillment/omnipack/omnipackDispatchPayload.d.ts +36 -0
  88. package/dist/fulfillment/omnipack/omnipackDispatchPayload.js +63 -0
  89. package/dist/fulfillment/omnipack/omnipackOutboundOrderPayload.d.ts +83 -0
  90. package/dist/fulfillment/omnipack/omnipackOutboundOrderPayload.js +113 -0
  91. package/dist/fulfillment/omnipack/omnipackProductPackPayload.d.ts +11 -0
  92. package/dist/fulfillment/omnipack/omnipackProductPackPayload.js +38 -0
  93. package/dist/fulfillment/omnipack/omnipackProductPayload.d.ts +18 -0
  94. package/dist/fulfillment/omnipack/omnipackProductPayload.js +51 -0
  95. package/dist/fulfillment/omnipack/omnipackReconciliationPayload.d.ts +1 -0
  96. package/dist/fulfillment/omnipack/omnipackReconciliationPayload.js +3 -0
  97. package/dist/fulfillment/omnipack/omnipackStatusVocabulary.d.ts +4 -0
  98. package/dist/fulfillment/omnipack/omnipackStatusVocabulary.js +87 -0
  99. package/dist/fulfillment/omnipack/omnipackWebhookPayload.d.ts +9 -0
  100. package/dist/fulfillment/omnipack/omnipackWebhookPayload.js +76 -0
  101. package/dist/fulfillment/omnipack/productSyncMappers.d.ts +18 -0
  102. package/dist/fulfillment/omnipack/productSyncMappers.js +43 -0
  103. package/dist/fulfillment/omnipack/providerError.d.ts +25 -0
  104. package/dist/fulfillment/omnipack/providerError.js +47 -0
  105. package/dist/fulfillment/omnipack/reconciliation.d.ts +15 -0
  106. package/dist/fulfillment/omnipack/reconciliation.js +55 -0
  107. package/dist/fulfillment/omnipack/trackingReferences.d.ts +16 -0
  108. package/dist/fulfillment/omnipack/trackingReferences.js +52 -0
  109. package/dist/fulfillment/paidFulfillmentRecovery.d.ts +67 -0
  110. package/dist/fulfillment/paidFulfillmentRecovery.js +154 -0
  111. package/dist/fulfillment/paidHandoff.d.ts +27 -0
  112. package/dist/fulfillment/paidHandoff.js +86 -0
  113. package/dist/fulfillment/paidHandoffPorts.d.ts +24 -0
  114. package/dist/fulfillment/paidHandoffPorts.js +3 -0
  115. package/dist/fulfillment/postgresDeliveryAlignment.d.ts +4 -0
  116. package/dist/fulfillment/postgresDeliveryAlignment.js +12 -0
  117. package/dist/fulfillment/postgresDispatchStore.d.ts +16 -0
  118. package/dist/fulfillment/postgresDispatchStore.js +44 -0
  119. package/dist/fulfillment/postgresEvidenceReadPort.d.ts +25 -0
  120. package/dist/fulfillment/postgresEvidenceReadPort.js +45 -0
  121. package/dist/fulfillment/postgresPaidFulfillmentRecovery.d.ts +25 -0
  122. package/dist/fulfillment/postgresPaidFulfillmentRecovery.js +26 -0
  123. package/dist/fulfillment/postgresPaidHandoffStore.d.ts +4 -0
  124. package/dist/fulfillment/postgresPaidHandoffStore.js +10 -0
  125. package/dist/fulfillment/postgresShipmentSpine.d.ts +70 -0
  126. package/dist/fulfillment/postgresShipmentSpine.js +246 -0
  127. package/dist/fulfillment/postgresStockSyncPort.d.ts +8 -0
  128. package/dist/fulfillment/postgresStockSyncPort.js +66 -0
  129. package/dist/fulfillment/productReconciliationEvidenceHandler.d.ts +36 -0
  130. package/dist/fulfillment/productReconciliationEvidenceHandler.js +50 -0
  131. package/dist/fulfillment/providerCapabilities.d.ts +9 -0
  132. package/dist/fulfillment/providerCapabilities.js +17 -0
  133. package/dist/fulfillment/providerCommandLedger.d.ts +143 -0
  134. package/dist/fulfillment/providerCommandLedger.js +14 -0
  135. package/dist/fulfillment/providerDispatchAcceptance.d.ts +27 -0
  136. package/dist/fulfillment/providerDispatchAcceptance.js +29 -0
  137. package/dist/fulfillment/providerDispatchError.d.ts +6 -0
  138. package/dist/fulfillment/providerDispatchError.js +5 -0
  139. package/dist/fulfillment/providerDispatchWorker.d.ts +44 -0
  140. package/dist/fulfillment/providerDispatchWorker.js +199 -0
  141. package/dist/fulfillment/providerProductSyncWorker.d.ts +28 -0
  142. package/dist/fulfillment/providerProductSyncWorker.js +122 -0
  143. package/dist/fulfillment/providerReconciliationError.d.ts +9 -0
  144. package/dist/fulfillment/providerReconciliationError.js +17 -0
  145. package/dist/fulfillment/providerReconciliationTerminalSkip.d.ts +2 -0
  146. package/dist/fulfillment/providerReconciliationTerminalSkip.js +6 -0
  147. package/dist/fulfillment/providerReconciliationTimestamp.d.ts +1 -0
  148. package/dist/fulfillment/providerReconciliationTimestamp.js +27 -0
  149. package/dist/fulfillment/providerReconciliationWorker.d.ts +90 -0
  150. package/dist/fulfillment/providerReconciliationWorker.js +207 -0
  151. package/dist/fulfillment/providerStockAvailability.d.ts +13 -0
  152. package/dist/fulfillment/providerStockAvailability.js +51 -0
  153. package/dist/fulfillment/providerStockSyncWorker.d.ts +41 -0
  154. package/dist/fulfillment/providerStockSyncWorker.js +295 -0
  155. package/dist/fulfillment/providerTrackingReferences.d.ts +16 -0
  156. package/dist/fulfillment/providerTrackingReferences.js +23 -0
  157. package/dist/fulfillment/replacementRefusals.d.ts +5 -0
  158. package/dist/fulfillment/replacementRefusals.js +38 -0
  159. package/dist/fulfillment/replacementShipmentHandler.d.ts +5 -0
  160. package/dist/fulfillment/replacementShipmentHandler.js +46 -0
  161. package/dist/fulfillment/schemaCapabilities.d.ts +13 -0
  162. package/dist/fulfillment/schemaCapabilities.js +7 -0
  163. package/dist/fulfillment/shipmentsOverviewHandler.d.ts +16 -0
  164. package/dist/fulfillment/shipmentsOverviewHandler.js +54 -0
  165. package/dist/fulfillment/statusMap.d.ts +2 -0
  166. package/dist/fulfillment/statusMap.js +1 -0
  167. package/dist/fulfillment/trackingProgress.d.ts +1 -0
  168. package/dist/fulfillment/trackingProgress.js +1 -0
  169. package/dist/fulfillment/verifiedIngress.d.ts +79 -0
  170. package/dist/fulfillment/verifiedIngress.js +94 -0
  171. package/dist/invoicing/capabilities.d.ts +11 -0
  172. package/dist/invoicing/capabilities.js +10 -0
  173. package/dist/invoicing/contracts/capabilities.d.ts +40 -0
  174. package/dist/invoicing/contracts/capabilities.js +1 -0
  175. package/dist/invoicing/contracts/companyLookup.d.ts +49 -0
  176. package/dist/invoicing/contracts/companyLookup.js +1 -0
  177. package/dist/invoicing/contracts/delivery.d.ts +74 -0
  178. package/dist/invoicing/contracts/delivery.js +1 -0
  179. package/dist/invoicing/contracts/facts.d.ts +100 -0
  180. package/dist/invoicing/contracts/facts.js +1 -0
  181. package/dist/invoicing/contracts/host.d.ts +246 -0
  182. package/dist/invoicing/contracts/host.js +1 -0
  183. package/dist/invoicing/contracts/index.d.ts +16 -0
  184. package/dist/invoicing/contracts/index.js +1 -0
  185. package/dist/invoicing/contracts/provider.d.ts +126 -0
  186. package/dist/invoicing/contracts/provider.js +1 -0
  187. package/dist/invoicing/contracts/settlement.d.ts +66 -0
  188. package/dist/invoicing/contracts/settlement.js +1 -0
  189. package/dist/invoicing/contracts/store.d.ts +267 -0
  190. package/dist/invoicing/contracts/store.js +1 -0
  191. package/dist/invoicing/index.d.ts +1 -0
  192. package/dist/invoicing/index.js +1 -0
  193. package/dist/payments/stripe/index.d.ts +25 -0
  194. package/dist/payments/stripe/index.js +25 -0
  195. package/dist/payments/tpay/index.d.ts +30 -0
  196. package/dist/payments/tpay/index.js +30 -0
  197. package/dist/subscriptions/automaticRenewal.d.ts +44 -0
  198. package/dist/subscriptions/automaticRenewal.js +81 -0
  199. package/dist/subscriptions/automaticRenewalExecution.d.ts +21 -0
  200. package/dist/subscriptions/automaticRenewalExecution.js +44 -0
  201. package/dist/subscriptions/contracts/commands.d.ts +115 -0
  202. package/dist/subscriptions/contracts/commands.js +1 -0
  203. package/dist/subscriptions/contracts/dunning.d.ts +133 -0
  204. package/dist/subscriptions/contracts/dunning.js +1 -0
  205. package/dist/subscriptions/contracts/index.d.ts +6 -0
  206. package/dist/subscriptions/contracts/index.js +1 -0
  207. package/dist/subscriptions/contracts/messages.d.ts +43 -0
  208. package/dist/subscriptions/contracts/messages.js +1 -0
  209. package/dist/subscriptions/contracts/renewal.d.ts +533 -0
  210. package/dist/subscriptions/contracts/renewal.js +1 -0
  211. package/dist/subscriptions/contracts/stockWait.d.ts +73 -0
  212. package/dist/subscriptions/contracts/stockWait.js +1 -0
  213. package/dist/subscriptions/index.d.ts +39 -0
  214. package/dist/subscriptions/index.js +17 -0
  215. package/dist/subscriptions/paymentOutcomes.d.ts +8 -0
  216. package/dist/subscriptions/paymentOutcomes.js +27 -0
  217. package/dist/subscriptions/postgresRenewalStore.d.ts +20 -0
  218. package/dist/subscriptions/postgresRenewalStore.js +61 -0
  219. package/dist/subscriptions/postgresRetryStore.d.ts +78 -0
  220. package/dist/subscriptions/postgresRetryStore.js +142 -0
  221. package/dist/subscriptions/renewalCycleFailureMechanism.d.ts +34 -0
  222. package/dist/subscriptions/renewalCycleFailureMechanism.js +79 -0
  223. package/dist/subscriptions/renewalCycleMechanism.d.ts +46 -0
  224. package/dist/subscriptions/renewalCycleMechanism.js +157 -0
  225. package/dist/subscriptions/renewalCycleRefusalMechanism.d.ts +41 -0
  226. package/dist/subscriptions/renewalCycleRefusalMechanism.js +160 -0
  227. package/dist/subscriptions/renewalIdentity.d.ts +3 -0
  228. package/dist/subscriptions/renewalIdentity.js +4 -0
  229. package/package.json +37 -2
  230. package/release-gates.json +97 -3
  231. package/sql/20260808210000_fulfillment_shipment_rail.sql +810 -0
  232. package/sql/20260819150000_fulfillment_shipment_sequence.sql +98 -0
  233. package/sql/20261022080000_fulfillment_command_ledger.sql +786 -0
  234. package/sql/20261022090000_fulfillment_delivery_alignment.sql +1106 -0
  235. package/sql/20261022160000_subscription_retry_lifecycle.sql +328 -0
  236. package/sql/20261022165000_fulfillment_stock_evidence_replay_reopen.sql +30 -0
  237. package/src/composition/composeBundle.ts +4 -0
  238. package/src/composition/fulfillmentContribution.ts +28 -0
  239. package/src/composition/index.ts +1 -0
  240. package/src/fulfillment/adapterConformance.ts +195 -0
  241. package/src/fulfillment/bindings.ts +26 -0
  242. package/src/fulfillment/commerceFulfillmentHandlers.ts +263 -0
  243. package/src/fulfillment/commerceFulfillmentReadModel.ts +257 -0
  244. package/src/fulfillment/contracts/alignment.ts +13 -0
  245. package/src/fulfillment/contracts/bindings.ts +30 -0
  246. package/src/fulfillment/contracts/capabilities.ts +15 -0
  247. package/src/fulfillment/contracts/conformance.ts +63 -0
  248. package/src/fulfillment/contracts/customerAlignment.ts +4 -0
  249. package/src/fulfillment/contracts/dispatch.ts +73 -0
  250. package/src/fulfillment/contracts/index.ts +18 -0
  251. package/src/fulfillment/contracts/label.ts +9 -0
  252. package/src/fulfillment/contracts/nativeUnsupported.ts +6 -0
  253. package/src/fulfillment/contracts/observation.ts +26 -0
  254. package/src/fulfillment/contracts/operator.ts +31 -0
  255. package/src/fulfillment/contracts/read.ts +42 -0
  256. package/src/fulfillment/contracts/readback.ts +24 -0
  257. package/src/fulfillment/contracts/replacement.ts +15 -0
  258. package/src/fulfillment/contracts/store.ts +27 -0
  259. package/src/fulfillment/contracts/sync.ts +72 -0
  260. package/src/fulfillment/currentFulfillmentParcel.ts +2 -0
  261. package/src/fulfillment/delayReadModel.ts +60 -0
  262. package/src/fulfillment/deliveryAlignmentReadModel.ts +15 -0
  263. package/src/fulfillment/dispatchProjection.ts +105 -0
  264. package/src/fulfillment/fulfillmentObservationEffects.ts +86 -0
  265. package/src/fulfillment/handlerSchemas.ts +255 -0
  266. package/src/fulfillment/handlerSupport.ts +25 -0
  267. package/src/fulfillment/index.ts +39 -0
  268. package/src/fulfillment/labelLifecycle.ts +11 -0
  269. package/src/fulfillment/lowStockEvidenceHandler.ts +60 -0
  270. package/src/fulfillment/migrations.ts +9 -0
  271. package/src/fulfillment/nativeUnsupported.ts +23 -0
  272. package/src/fulfillment/normalizedFulfillmentFacts.ts +2 -0
  273. package/src/fulfillment/observationProjection.ts +92 -0
  274. package/src/fulfillment/omnipack/capabilities.ts +18 -0
  275. package/src/fulfillment/omnipack/client.ts +270 -0
  276. package/src/fulfillment/omnipack/index.ts +369 -0
  277. package/src/fulfillment/omnipack/mappers.ts +282 -0
  278. package/src/fulfillment/omnipack/observation.ts +79 -0
  279. package/src/fulfillment/omnipack/omnipackDispatchPayload.ts +93 -0
  280. package/src/fulfillment/omnipack/omnipackOutboundOrderPayload.ts +194 -0
  281. package/src/fulfillment/omnipack/omnipackProductPackPayload.ts +47 -0
  282. package/src/fulfillment/omnipack/omnipackProductPayload.ts +67 -0
  283. package/src/fulfillment/omnipack/omnipackReconciliationPayload.ts +7 -0
  284. package/src/fulfillment/omnipack/omnipackStatusVocabulary.ts +103 -0
  285. package/src/fulfillment/omnipack/omnipackWebhookPayload.ts +73 -0
  286. package/src/fulfillment/omnipack/productSyncMappers.ts +74 -0
  287. package/src/fulfillment/omnipack/providerError.ts +64 -0
  288. package/src/fulfillment/omnipack/reconciliation.ts +56 -0
  289. package/src/fulfillment/omnipack/trackingReferences.ts +77 -0
  290. package/src/fulfillment/paidFulfillmentRecovery.ts +252 -0
  291. package/src/fulfillment/paidHandoff.ts +122 -0
  292. package/src/fulfillment/paidHandoffPorts.ts +21 -0
  293. package/src/fulfillment/postgresDeliveryAlignment.ts +14 -0
  294. package/src/fulfillment/postgresDispatchStore.ts +55 -0
  295. package/src/fulfillment/postgresEvidenceReadPort.ts +59 -0
  296. package/src/fulfillment/postgresPaidFulfillmentRecovery.ts +29 -0
  297. package/src/fulfillment/postgresPaidHandoffStore.ts +11 -0
  298. package/src/fulfillment/postgresShipmentSpine.ts +338 -0
  299. package/src/fulfillment/postgresStockSyncPort.ts +68 -0
  300. package/src/fulfillment/productReconciliationEvidenceHandler.ts +64 -0
  301. package/src/fulfillment/providerCapabilities.ts +18 -0
  302. package/src/fulfillment/providerCommandLedger.ts +53 -0
  303. package/src/fulfillment/providerDispatchAcceptance.ts +37 -0
  304. package/src/fulfillment/providerDispatchError.ts +7 -0
  305. package/src/fulfillment/providerDispatchWorker.ts +159 -0
  306. package/src/fulfillment/providerProductSyncWorker.ts +154 -0
  307. package/src/fulfillment/providerReconciliationError.ts +20 -0
  308. package/src/fulfillment/providerReconciliationTerminalSkip.ts +8 -0
  309. package/src/fulfillment/providerReconciliationTimestamp.ts +34 -0
  310. package/src/fulfillment/providerReconciliationWorker.ts +206 -0
  311. package/src/fulfillment/providerStockAvailability.ts +60 -0
  312. package/src/fulfillment/providerStockSyncWorker.ts +318 -0
  313. package/src/fulfillment/providerTrackingReferences.ts +32 -0
  314. package/src/fulfillment/replacementRefusals.ts +43 -0
  315. package/src/fulfillment/replacementShipmentHandler.ts +47 -0
  316. package/src/fulfillment/schemaCapabilities.ts +7 -0
  317. package/src/fulfillment/shipmentsOverviewHandler.ts +73 -0
  318. package/src/fulfillment/statusMap.ts +2 -0
  319. package/src/fulfillment/trackingProgress.ts +1 -0
  320. package/src/fulfillment/verifiedIngress.ts +113 -0
  321. package/src/invoicing/capabilities.ts +9 -0
  322. package/src/invoicing/contracts/capabilities.ts +15 -0
  323. package/src/invoicing/contracts/companyLookup.ts +13 -0
  324. package/src/invoicing/contracts/delivery.ts +24 -0
  325. package/src/invoicing/contracts/facts.ts +60 -0
  326. package/src/invoicing/contracts/host.ts +85 -0
  327. package/src/invoicing/contracts/index.ts +16 -0
  328. package/src/invoicing/contracts/provider.ts +78 -0
  329. package/src/invoicing/contracts/settlement.ts +39 -0
  330. package/src/invoicing/contracts/store.ts +98 -0
  331. package/src/invoicing/index.ts +1 -0
  332. package/src/payments/stripe/index.ts +30 -0
  333. package/src/payments/tpay/index.ts +36 -0
  334. package/src/subscriptions/automaticRenewal.ts +87 -0
  335. package/src/subscriptions/automaticRenewalExecution.ts +39 -0
  336. package/src/subscriptions/contracts/commands.ts +46 -0
  337. package/src/subscriptions/contracts/dunning.ts +48 -0
  338. package/src/subscriptions/contracts/index.ts +6 -0
  339. package/src/subscriptions/contracts/messages.ts +18 -0
  340. package/src/subscriptions/contracts/renewal.ts +325 -0
  341. package/src/subscriptions/contracts/stockWait.ts +34 -0
  342. package/src/subscriptions/index.ts +24 -0
  343. package/src/subscriptions/paymentOutcomes.ts +23 -0
  344. package/src/subscriptions/postgresRenewalStore.ts +76 -0
  345. package/src/subscriptions/postgresRetryStore.ts +174 -0
  346. package/src/subscriptions/renewalCycleFailureMechanism.ts +119 -0
  347. package/src/subscriptions/renewalCycleMechanism.ts +225 -0
  348. package/src/subscriptions/renewalCycleRefusalMechanism.ts +215 -0
  349. package/src/subscriptions/renewalIdentity.ts +5 -0
@@ -0,0 +1,408 @@
1
+ import { z } from "zod";
2
+ import { publicTrackingUrl } from "../observationProjection.js";
3
+ import { createOmnipackClient, OmnipackProviderError } from "./client.js";
4
+ import { omnipackFulfillmentCapabilities } from "./capabilities.js";
5
+ import { buildOmnipackDispatchCommand, serializeOmnipackDispatchPayload, stableDispatchHash } from "./omnipackDispatchPayload.js";
6
+ import { mapOmnipackWebhookPayload } from "./mappers.js";
7
+ import { verifyOmnipackWebhookToken } from "./omnipackWebhookPayload.js";
8
+ import { createReconciliationPagePort, reconciliationObservation } from "./reconciliation.js";
9
+ import { dispatchEvidence, operationError } from "../dispatchProjection.js";
10
+ import { correlationReference, digest, eventKind, observation, reference, refusal, timestamp } from "./observation.js";
11
+ export { omnipackFulfillmentCapabilities } from "./capabilities.js";
12
+ // Internal error projection: retain diagnostics without exposing a provider payload or cause.
13
+ class OmnipackSyncError extends Error {
14
+ reason;
15
+ phase = "sync";
16
+ retryable;
17
+ providerFailure;
18
+ status;
19
+ code;
20
+ constructor(reason, operation, error) {
21
+ super(reason === "io_failure" ? `OmniPack request failed: ${operation}` : `OmniPack sync refused: ${reason}`);
22
+ this.reason = reason;
23
+ this.name = "OmnipackSyncError";
24
+ this.providerFailure = reason === "io_failure";
25
+ this.retryable = error instanceof OmnipackProviderError ? error.retryable : false;
26
+ this.status = error instanceof OmnipackProviderError ? error.status : null;
27
+ this.code = error instanceof OmnipackProviderError ? error.code : null;
28
+ }
29
+ }
30
+ function syncFailure(operation, error) {
31
+ return error instanceof OmnipackSyncError ? error : new OmnipackSyncError("io_failure", operation, error);
32
+ }
33
+ function requireProductSku(sku) {
34
+ // URL resolution collapses dot segments; encodeURIComponent rejects lone surrogates.
35
+ // Keep these SKUs in the listing so the worker counts a visible per-SKU failure.
36
+ try {
37
+ if (!sku.trim() || sku === "." || sku === "..")
38
+ throw Error();
39
+ encodeURIComponent(sku);
40
+ }
41
+ catch {
42
+ throw new OmnipackSyncError("malformed", "getProduct");
43
+ }
44
+ }
45
+ /** No route, schedule, environment reader or default binding is installed. */
46
+ export function createOmnipackFulfillmentAdapter(config) {
47
+ const maxRetainedSubmissions = config.maxRetainedSubmissions === undefined ? 10_000 : config.maxRetainedSubmissions;
48
+ const base = new URL(config.http.baseUrl);
49
+ if (base.protocol !== "https:" || base.username || base.password || base.search || base.hash
50
+ || !Number.isSafeInteger(maxRetainedSubmissions) || maxRetainedSubmissions <= 0
51
+ || typeof config.http.fetchImpl !== "function" || typeof config.http.credentials !== "function"
52
+ || !Number.isSafeInteger(config.http.timeoutMs) || config.http.timeoutMs <= 0
53
+ || !Number.isSafeInteger(config.http.safeReadRetries) || config.http.safeReadRetries < 0
54
+ || !/^\/[A-Za-z0-9_-]+(?:\/[A-Za-z0-9_-]+)*\/?$/u.test(config.http.productPath)
55
+ || !eventKind(config.notification.expectedEvent))
56
+ throw new Error("Invalid fulfillment configuration");
57
+ const client = createOmnipackClient({ ...config.http }, config.http.fetchImpl);
58
+ // Copy the profile so host selection never mutates the exported default-off descriptor.
59
+ const capabilities = structuredClone(omnipackFulfillmentCapabilities);
60
+ capabilities.selected = config.selected === true;
61
+ capabilities.readiness = config.readiness?.ready === true ? { ready: true }
62
+ : { ready: false, refusal: refusal("not_ready", "selection") };
63
+ const submissions = new Map();
64
+ const evictCompleted = () => {
65
+ for (const [fingerprint, submission] of submissions) {
66
+ if (submissions.size <= maxRetainedSubmissions)
67
+ break;
68
+ if (submission.completed)
69
+ submissions.delete(fingerprint);
70
+ }
71
+ };
72
+ const selectionFailure = (request) => {
73
+ if (!request.selection?.providerRef?.trim())
74
+ return refusal("selection_required", "selection");
75
+ if (request.selection.providerRef !== capabilities.providerRef)
76
+ return refusal("provider_mismatch", "selection");
77
+ if (!reference(request.selection.carrierRef) || !reference(request.selection.serviceRef))
78
+ return refusal("carrier_service_required", "selection");
79
+ if (!capabilities.selected)
80
+ return refusal("disabled", "selection");
81
+ if (!capabilities.readiness.ready)
82
+ return refusal("not_ready", "selection");
83
+ return null;
84
+ };
85
+ const requireSync = () => {
86
+ if (!capabilities.selected || !capabilities.readiness.ready)
87
+ throw new OmnipackSyncError(capabilities.selected ? "not_ready" : "disabled", "selection");
88
+ };
89
+ const syncIdentity = () => {
90
+ const syncRunId = reference(config.mintSyncRunId());
91
+ const collectedAt = timestamp(config.clock());
92
+ if (!syncRunId || !collectedAt)
93
+ throw new OmnipackSyncError("malformed", "sync");
94
+ return { providerRef: capabilities.providerRef, syncRunId, collectedAt, sourceRevision: null, revisionSource: "collection" };
95
+ };
96
+ // Shared computation: host metadata and serialized bytes live only for this call.
97
+ const buildCommand = async (request) => {
98
+ const requestDigest = stableDispatchHash(request);
99
+ if (!Number.isSafeInteger(request.contactRevision.schemaVersion) || request.contactRevision.schemaVersion < 1
100
+ || !reference(request.contactRevision.source) || !Number.isSafeInteger(request.contactRevision.revision)
101
+ || request.contactRevision.revision < 0)
102
+ throw Error();
103
+ const lines = [];
104
+ for (const line of request.lines) {
105
+ const metadata = await config.resolveProduct(line);
106
+ if (!metadata)
107
+ throw Error();
108
+ lines.push({ sku: line.skuRef, quantity: line.quantity, productSnapshot: { lotNumber: metadata.lotNumber, expirationDate: metadata.expirationDate } });
109
+ }
110
+ if (stableDispatchHash(request) !== requestDigest)
111
+ throw Error();
112
+ const command = buildOmnipackDispatchCommand({
113
+ orderId: request.orderRef, orderNumber: request.orderNumber,
114
+ deliveryContact: { revision: request.contactRevision.revision, recipientName: request.recipient.name,
115
+ contactEmail: request.recipient.email, contactPhone: request.recipient.phone, line1: request.recipient.line1,
116
+ city: request.recipient.city, postalCode: request.recipient.postalCode, country: request.recipient.country,
117
+ selectedDelivery: { providerKind: capabilities.providerRef, carrierKind: request.selection.carrierRef,
118
+ serviceCode: request.selection.serviceRef, deliveryKind: request.selection.deliveryKind, pickupPoint: request.selection.pickupPoint } }, lines,
119
+ });
120
+ const evidence = dispatchEvidence({ commandFingerprint: command.requestFingerprint,
121
+ contactRevision: { schemaVersion: request.contactRevision.schemaVersion, source: request.contactRevision.source, revision: request.contactRevision.revision },
122
+ providerRef: capabilities.providerRef, carrierRef: request.selection.carrierRef, serviceRef: request.selection.serviceRef,
123
+ transcript: { itemCount: command.providerPayload.items.length,
124
+ items: command.providerPayload.items.map(item => ({ skuRef: item.sku, quantity: item.quantity, lotRef: item.lotNumber ?? null, expirationDate: item.expirationDate ?? null })),
125
+ deliveryKind: request.selection.deliveryKind, pickupPointRef: request.selection.pickupPoint?.id ?? null } });
126
+ return { body: command.body, evidence };
127
+ };
128
+ return {
129
+ capabilities,
130
+ dispatch: {
131
+ async prepare(request) {
132
+ const failed = selectionFailure(request);
133
+ if (failed)
134
+ return { kind: "refused", refusal: failed };
135
+ try {
136
+ return { kind: "prepared", evidence: (await buildCommand(request)).evidence };
137
+ }
138
+ catch {
139
+ return { kind: "refused", refusal: refusal("not_dispatchable", "prepare") };
140
+ }
141
+ },
142
+ async dispatch(request, evidence) {
143
+ let commandRequest;
144
+ let fingerprint;
145
+ let evidenceKey;
146
+ let requestCommandDigest;
147
+ try {
148
+ // Validate the closed evidence and its request-bound values without consulting preparation state.
149
+ if (Object.keys(evidence).length !== 6 || Object.keys(evidence.contactRevision).length !== 3
150
+ || typeof evidence.commandFingerprint !== "string" || !/^[a-f0-9]{64}$/u.test(evidence.commandFingerprint)
151
+ || !reference(evidence.providerRef)
152
+ || !reference(evidence.carrierRef) || !reference(evidence.serviceRef)
153
+ || !Number.isSafeInteger(evidence.contactRevision.schemaVersion) || evidence.contactRevision.schemaVersion < 1
154
+ || !reference(evidence.contactRevision.source) || !Number.isSafeInteger(evidence.contactRevision.revision)
155
+ || evidence.contactRevision.revision < 0
156
+ || evidence.contactRevision.schemaVersion !== request.contactRevision.schemaVersion
157
+ || evidence.contactRevision.source !== request.contactRevision.source
158
+ || evidence.contactRevision.revision !== request.contactRevision.revision
159
+ || evidence.providerRef !== request.selection.providerRef
160
+ || evidence.carrierRef !== request.selection.carrierRef || evidence.serviceRef !== request.selection.serviceRef)
161
+ throw Error();
162
+ evidenceKey = serializeOmnipackDispatchPayload(evidence).body;
163
+ if (serializeOmnipackDispatchPayload(dispatchEvidence(evidence)).body !== evidenceKey)
164
+ throw Error();
165
+ requestCommandDigest = commandDigest(request);
166
+ const submitted = submissions.get(evidence.commandFingerprint);
167
+ if (submitted) {
168
+ // Replay is bound to this submission's evidence and command, never replaceable preparation.
169
+ if (submitted.evidenceKey !== evidenceKey || submitted.commandDigest !== requestCommandDigest)
170
+ throw Error();
171
+ return structuredClone(await submitted.result);
172
+ }
173
+ if (selectionFailure(request))
174
+ throw Error();
175
+ commandRequest = structuredClone(request);
176
+ fingerprint = evidence.commandFingerprint;
177
+ }
178
+ catch {
179
+ return { kind: "not_dispatched", effectMayHaveSucceeded: false, refusal: refusal("not_dispatchable", "dispatch") };
180
+ }
181
+ // Reserve before host resolution too, so concurrent dispatches join the rebuild.
182
+ const result = Promise.resolve().then(async () => {
183
+ let command;
184
+ try {
185
+ command = await buildCommand(commandRequest);
186
+ if (command.evidence.commandFingerprint !== fingerprint || serializeOmnipackDispatchPayload(command.evidence).body !== evidenceKey)
187
+ throw Error();
188
+ }
189
+ catch {
190
+ // A stale or unresolved command has never reached credentials or HTTP.
191
+ submissions.delete(fingerprint);
192
+ return { kind: "not_dispatched", effectMayHaveSucceeded: false, refusal: refusal("not_dispatchable", "dispatch") };
193
+ }
194
+ try {
195
+ const result = await client.createOrder(command.body);
196
+ const externalRef = reference(result.providerOrderId);
197
+ if (!externalRef)
198
+ return { kind: "unknown", effectMayHaveSucceeded: true, refusal: refusal("malformed", "acknowledge") };
199
+ // Opaque provider proof; the worker replaces these with authoritative host keys.
200
+ const proof = digest(JSON.stringify([externalRef, command.evidence.commandFingerprint]));
201
+ return { kind: "accepted", externalRef, evidence: structuredClone(command.evidence),
202
+ providerAttemptKey: `attempt:${proof}`, labelKey: `label:${proof}` };
203
+ }
204
+ catch (error) {
205
+ const detail = operationError(error instanceof OmnipackProviderError ? error : { code: "provider_dispatch_failed", status: null, retryable: true, mayHaveSucceeded: true });
206
+ return !detail.mayHaveSucceeded
207
+ ? { kind: "not_dispatched", effectMayHaveSucceeded: false, refusal: refusal("io_failure", "dispatch", detail.retryable), error: detail }
208
+ : { kind: "unknown", effectMayHaveSucceeded: true, refusal: refusal("io_failure", "dispatch", detail.retryable), error: detail };
209
+ }
210
+ finally {
211
+ command.body = "";
212
+ submissions.get(fingerprint).completed = true;
213
+ evictCompleted();
214
+ }
215
+ });
216
+ submissions.set(fingerprint, { evidenceKey, commandDigest: requestCommandDigest, completed: false, result });
217
+ evictCompleted();
218
+ return structuredClone(await result);
219
+ },
220
+ },
221
+ label: {
222
+ async create() { return { kind: "refused", refusal: refusal("unsupported", "dispatch") }; },
223
+ async read() { return { kind: "refused", refusal: refusal("unsupported", "dispatch") }; },
224
+ async void() { return { providerDeletion: "unconfirmed", labelDeleted: false, canProceed: false, refusal: refusal("unsupported", "dispatch") }; },
225
+ },
226
+ observation: {
227
+ async verifyAndNormalize(input) {
228
+ // Token check precedes every read of rawBody and every parse.
229
+ try {
230
+ if (!verifyOmnipackWebhookToken({ headers: { ...input.headers } }, await config.notification.token()))
231
+ return { kind: "refused", refusal: refusal("untrusted", "verify") };
232
+ }
233
+ catch {
234
+ return { kind: "refused", refusal: refusal("untrusted", "verify") };
235
+ }
236
+ try {
237
+ const rawBody = Buffer.from(input.rawBody);
238
+ const payload = JSON.parse(rawBody.toString("utf8"));
239
+ if (!payload || typeof payload !== "object" || Array.isArray(payload))
240
+ return { kind: "refused", refusal: refusal("malformed", "normalize") };
241
+ if ("event" in payload && (typeof payload.event !== "string" || !eventKind(payload.event)))
242
+ return { kind: "refused", refusal: refusal("unsupported_event", "normalize") };
243
+ const original = payload;
244
+ // Validate calendar fields here only; keep compact offsets and local
245
+ // timestamps accepted by the base parser, without rewriting key bytes.
246
+ if (original.occurredAt !== undefined && original.occurredAt !== null
247
+ && (typeof original.occurredAt !== "string" || !timestamp(original.occurredAt)
248
+ || !z.iso.datetime({ offset: true, local: true }).safeParse(original.occurredAt.replace(/([+-]\d{2})(\d{2})$/u, "$1:$2")).success))
249
+ return { kind: "refused", refusal: refusal("malformed", "normalize"), diagnostics: { invalidTimestamp: true } };
250
+ const rejectedCorrelationRefs = [original.orderId, original.providerOrderId, original.orderNumber, original.fulfilmentNumber]
251
+ .filter(value => value !== undefined && value !== null && (typeof value !== "string" || !correlationReference(value, config.observationCodecs))).length;
252
+ if (rejectedCorrelationRefs)
253
+ return { kind: "refused", refusal: refusal("missing_correlation", "normalize"), diagnostics: { rejectedCorrelationRefs } };
254
+ const evidence = mapOmnipackWebhookPayload(payload, config.notification.expectedEvent, value => correlationReference(value, config.observationCodecs) !== null, {
255
+ service: value => correlationReference(value, config.observationCodecs) !== null,
256
+ url: value => publicTrackingUrl(value, config.approveTrackingUrl, config.observationCodecs?.trackingUrl) !== null,
257
+ });
258
+ const event = eventKind(evidence.event);
259
+ if (!event || event !== config.notification.expectedEvent)
260
+ return { kind: "refused", refusal: refusal("unsupported_event", "normalize") };
261
+ if (![evidence.providerOrderId, evidence.orderNumber, evidence.fulfilmentNumber].some(value => correlationReference(value, config.observationCodecs)))
262
+ return { kind: "refused", refusal: refusal("missing_correlation", "normalize") };
263
+ return { kind: "verified", observation: observation({ evidence, event, receivedAt: input.receivedAt,
264
+ rawDigest: digest(rawBody), evidenceRef: config.mintEvidenceReference(), source: "provider_webhook", approveTrackingUrl: config.approveTrackingUrl, observationCodecs: config.observationCodecs }) };
265
+ }
266
+ catch {
267
+ return { kind: "refused", refusal: refusal("malformed", "normalize") };
268
+ }
269
+ },
270
+ },
271
+ readback: {
272
+ async read(input) {
273
+ if (input.providerRef !== capabilities.providerRef)
274
+ return { kind: "unsupported", refusal: refusal("provider_mismatch", "readback") };
275
+ if (!capabilities.selected || !capabilities.readiness.ready)
276
+ return { kind: "unsupported", refusal: refusal(capabilities.selected ? "not_ready" : "disabled", "readback") };
277
+ if (!reference(input.externalRef))
278
+ return { kind: "unsupported", refusal: refusal("unsupported", "readback") };
279
+ try {
280
+ const collection = await client.getFulfilmentsPage({ page: 0, size: 100 });
281
+ if (!collection.complete)
282
+ return { kind: "unknown", refusal: refusal("local_missing", "readback") };
283
+ const matches = collection.rows.filter(row => input.mode === "parcel"
284
+ ? row.fulfilmentNumber === input.externalRef : row.providerOrderId === input.externalRef);
285
+ if (matches.length !== 1)
286
+ return { kind: "unknown", refusal: refusal("local_missing", "readback") };
287
+ const mapped = reconciliationObservation(matches[0], config, input.fulfillmentRef);
288
+ return mapped.kind === "unmapped" ? { kind: "unknown", refusal: refusal("unsupported_event", "readback") } : { ...mapped, externalRef: input.externalRef };
289
+ }
290
+ catch {
291
+ return { kind: "unknown", refusal: refusal("io_failure", "readback") };
292
+ }
293
+ },
294
+ },
295
+ reconciliation: createReconciliationPagePort(client, config, () => !capabilities.selected || !capabilities.readiness.ready
296
+ ? refusal(capabilities.selected ? "not_ready" : "disabled", "readback") : null),
297
+ stockSync: {
298
+ async getStock() {
299
+ requireSync();
300
+ try {
301
+ const identity = syncIdentity();
302
+ return (await client.getStock({ refuseRedirectRetry: true })).map((row, itemIndex) => {
303
+ const skuRef = reference(row.sku);
304
+ if (!skuRef)
305
+ return { kind: "rejected", itemIndex, reason: "invalid_sku_ref" };
306
+ return { ...identity, skuRef, quantityKind: "snapshot", totalQuantity: row.totalQuantity,
307
+ forSaleQuantity: row.forSaleQuantity, reservedOrUnavailableQuantity: row.reservedOrUnavailableQuantity };
308
+ });
309
+ }
310
+ catch (error) {
311
+ throw stockFailure(error, "get_stock");
312
+ }
313
+ },
314
+ async getStockMovements(input) {
315
+ requireSync();
316
+ try {
317
+ const identity = syncIdentity();
318
+ return (await client.getStockMovements(input)).map((row, itemIndex) => {
319
+ const skuRef = reference(row.sku);
320
+ if (!skuRef)
321
+ return { kind: "rejected", itemIndex, reason: "invalid_sku_ref" };
322
+ return { ...identity, skuRef, quantityKind: "movement", quantity: row.quantity, occurredAt: timestamp(row.occurredAt),
323
+ operationType: reference(row.operationType), documentRef: reference(row.warehouseDocumentNumber), lotRef: reference(row.lotNumber), expirationDate: /^\d{4}-\d\d-\d\d$/u.test(row.expirationDate ?? "") ? row.expirationDate : null };
324
+ });
325
+ }
326
+ catch (error) {
327
+ throw stockFailure(error, "get_stock_movements");
328
+ }
329
+ },
330
+ },
331
+ productSync: {
332
+ async ensureProduct(sku) {
333
+ requireSync();
334
+ try {
335
+ const metadata = await config.product?.resolvePushMetadata(sku);
336
+ if (!metadata)
337
+ return null;
338
+ await client.createProduct(metadata, sku);
339
+ return { replayed: false };
340
+ }
341
+ catch (error) {
342
+ throw syncFailure("createProduct", error);
343
+ }
344
+ },
345
+ async getProductPacks(sku) {
346
+ requireSync();
347
+ requireProductSku(sku);
348
+ try {
349
+ return (await client.getProduct(sku)).packs.map(pack => ({ ean: pack.ean, quantity: pack.quantity }));
350
+ }
351
+ catch (error) {
352
+ throw syncFailure("getProduct", error);
353
+ }
354
+ },
355
+ async addProductPack(sku, pack) {
356
+ requireSync();
357
+ if (!/^\d{8,14}$/u.test(pack.ean) || !Number.isSafeInteger(pack.quantity) || pack.quantity <= 0)
358
+ throw new OmnipackSyncError("malformed", "sync");
359
+ try {
360
+ await client.createProductPack(sku, { ean: pack.ean, quantity: pack.quantity }, pack.ean);
361
+ }
362
+ catch (error) {
363
+ throw syncFailure("createProductPack", error);
364
+ }
365
+ },
366
+ async listStockedSkus() {
367
+ requireSync();
368
+ try {
369
+ return [...new Set((await client.getStock()).flatMap(row => row.sku.trim() ? [row.sku] : []))];
370
+ }
371
+ catch (error) {
372
+ throw syncFailure("getStock", error);
373
+ }
374
+ },
375
+ },
376
+ };
377
+ }
378
+ // buildOmnipackDispatchPayloadFromCandidate forwards only name/email/phone and
379
+ // line1/city/postalCode/country to buildOmnipackOutboundOrderPayload; neither
380
+ // codec reads line titles, recipient line2/deliveryInstructions/courierInstructions,
381
+ // or pickup-point provider/name/address (readPickUpPoint reads only its id).
382
+ // Exclude those descriptions; retain host request/order/fulfillment/parcel and
383
+ // product/pack identities as well as all wire/evidence-bearing request values.
384
+ // The submission retains only this SHA-256 hash in memory, never the raw values.
385
+ function commandDigest(request) {
386
+ return stableDispatchHash({
387
+ requestKey: request.requestKey, fulfillmentRef: request.fulfillmentRef,
388
+ orderRef: request.orderRef, orderNumber: request.orderNumber, parcelRef: request.parcelRef,
389
+ contactRevision: { schemaVersion: request.contactRevision.schemaVersion,
390
+ source: request.contactRevision.source, revision: request.contactRevision.revision },
391
+ recipient: { name: request.recipient.name, email: request.recipient.email, phone: request.recipient.phone,
392
+ line1: request.recipient.line1, city: request.recipient.city, postalCode: request.recipient.postalCode, country: request.recipient.country },
393
+ lines: request.lines.map(line => ({ skuRef: line.skuRef, productRef: line.productRef, packRef: line.packRef, quantity: line.quantity })),
394
+ selection: { providerRef: request.selection.providerRef, carrierRef: request.selection.carrierRef,
395
+ serviceRef: request.selection.serviceRef, deliveryKind: request.selection.deliveryKind,
396
+ pickupPointId: request.selection.pickupPoint?.id ?? null },
397
+ });
398
+ }
399
+ /** Translate only the contributed client's typed error; never copy a message or payload. */
400
+ function stockFailure(error, operation) {
401
+ const failure = syncFailure(operation === "get_stock" ? "getStock" : "getStockMovements", error);
402
+ if (!(error instanceof OmnipackProviderError))
403
+ return failure;
404
+ const retryable = error.code !== "redirect_refused" && (error.retryable || error.code === "network_error");
405
+ return Object.assign(failure, { retryable, providerError: {
406
+ operation, status: error.status, code: error.code, retryable,
407
+ } });
408
+ }
@@ -0,0 +1,79 @@
1
+ import { type OmnipackTrackingReferenceEvidence } from "./trackingReferences.js";
2
+ export interface OmnipackOrderCreatedEvidence {
3
+ provider: "omnipack";
4
+ providerOrderId: string;
5
+ raw: Record<string, unknown>;
6
+ }
7
+ export interface OmnipackProductCreatedEvidence {
8
+ provider: "omnipack";
9
+ sku: string;
10
+ raw: Record<string, unknown>;
11
+ }
12
+ export interface OmnipackStockEvidence {
13
+ provider: "omnipack";
14
+ sku: string;
15
+ totalQuantity: number;
16
+ forSaleQuantity: number;
17
+ reservedOrUnavailableQuantity: number;
18
+ stockTruth: "external_stock_master_with_local_reservations";
19
+ }
20
+ export interface OmnipackStockMovementEvidence {
21
+ provider: "omnipack";
22
+ sku: string;
23
+ occurredAt: string | null;
24
+ quantity: number;
25
+ operationType: string | null;
26
+ warehouseDocumentNumber: string | null;
27
+ lotNumber: string | null;
28
+ expirationDate: string | null;
29
+ }
30
+ export interface OmnipackFulfilmentEvidence {
31
+ provider: "omnipack";
32
+ providerOrderId: string | null;
33
+ fulfilmentNumber: string;
34
+ externalNumber: string | null;
35
+ orderNumber: string | null;
36
+ createdAt: string | null;
37
+ updatedAt: string | null;
38
+ status: string | null;
39
+ subStatus: string | null;
40
+ trackingNumbers: string[];
41
+ trackingReferences: OmnipackTrackingReferenceEvidence[];
42
+ items: Array<{
43
+ sku: string;
44
+ quantity: number;
45
+ lotNumber: string | null;
46
+ expirationDate: string | null;
47
+ }>;
48
+ }
49
+ export interface OmnipackFulfilmentRequestEvidence {
50
+ provider: "omnipack";
51
+ warehouseDocumentNumber: string;
52
+ warehouseName: string | null;
53
+ state: string | null;
54
+ }
55
+ export interface OmnipackWebhookEvidence {
56
+ rejectedTrackingRefs?: number;
57
+ rejectedServices?: number;
58
+ rejectedTrackingUrls?: number;
59
+ provider: "omnipack";
60
+ event: string;
61
+ providerOrderId: string | null;
62
+ orderNumber: string | null;
63
+ fulfilmentNumber: string | null;
64
+ occurredAt: string | null;
65
+ trackingNumbers: string[];
66
+ trackingReferences: OmnipackTrackingReferenceEvidence[];
67
+ shippingMethods: string[];
68
+ }
69
+ export declare function mapOmnipackOrderCreatedResponse(body: unknown): OmnipackOrderCreatedEvidence;
70
+ export declare function mapOmnipackProductCreatedResponse(body: unknown, requestSku: string): OmnipackProductCreatedEvidence;
71
+ export declare function mapOmnipackStockResponse(body: unknown): OmnipackStockEvidence[];
72
+ export declare function mapOmnipackStockMovementsResponse(body: unknown): OmnipackStockMovementEvidence[];
73
+ export declare function mapOmnipackFulfilmentsResponse(body: unknown): OmnipackFulfilmentEvidence[];
74
+ export declare function mapOmnipackFulfilmentRequestsResponse(body: unknown): OmnipackFulfilmentRequestEvidence[];
75
+ export declare function mapOmnipackWebhookPayload(body: unknown, fallbackEvent?: string, admitTrackingNumber?: (value: string) => boolean, admitMetadata?: {
76
+ service(value: string): boolean;
77
+ url(value: string): boolean;
78
+ }): OmnipackWebhookEvidence;
79
+ export declare function sanitizeOmnipackPayload(input: Record<string, unknown>): Record<string, unknown>;