@voyant-travel/inventory 0.1.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 (311) hide show
  1. package/LICENSE +201 -0
  2. package/dist/action-ledger-drift.d.ts +29 -0
  3. package/dist/action-ledger-drift.d.ts.map +1 -0
  4. package/dist/action-ledger-drift.js +338 -0
  5. package/dist/action-ledger.d.ts +104 -0
  6. package/dist/action-ledger.d.ts.map +1 -0
  7. package/dist/action-ledger.js +100 -0
  8. package/dist/authoring/builder.d.ts +37 -0
  9. package/dist/authoring/builder.d.ts.map +1 -0
  10. package/dist/authoring/builder.js +248 -0
  11. package/dist/authoring/clone-content.d.ts +38 -0
  12. package/dist/authoring/clone-content.d.ts.map +1 -0
  13. package/dist/authoring/clone-content.js +367 -0
  14. package/dist/authoring/clone-pricing.d.ts +9 -0
  15. package/dist/authoring/clone-pricing.d.ts.map +1 -0
  16. package/dist/authoring/clone-pricing.js +242 -0
  17. package/dist/authoring/clone.d.ts +45 -0
  18. package/dist/authoring/clone.d.ts.map +1 -0
  19. package/dist/authoring/clone.js +142 -0
  20. package/dist/authoring/errors.d.ts +21 -0
  21. package/dist/authoring/errors.d.ts.map +1 -0
  22. package/dist/authoring/errors.js +13 -0
  23. package/dist/authoring/extension.d.ts +248 -0
  24. package/dist/authoring/extension.d.ts.map +1 -0
  25. package/dist/authoring/extension.js +116 -0
  26. package/dist/authoring/index.d.ts +12 -0
  27. package/dist/authoring/index.d.ts.map +1 -0
  28. package/dist/authoring/index.js +11 -0
  29. package/dist/authoring/schema.d.ts +85 -0
  30. package/dist/authoring/schema.d.ts.map +1 -0
  31. package/dist/authoring/schema.js +16 -0
  32. package/dist/authoring/service.d.ts +28 -0
  33. package/dist/authoring/service.d.ts.map +1 -0
  34. package/dist/authoring/service.js +66 -0
  35. package/dist/authoring/spec.d.ts +524 -0
  36. package/dist/authoring/spec.d.ts.map +1 -0
  37. package/dist/authoring/spec.js +167 -0
  38. package/dist/authoring/validate.d.ts +17 -0
  39. package/dist/authoring/validate.d.ts.map +1 -0
  40. package/dist/authoring/validate.js +83 -0
  41. package/dist/authoring.d.ts +2 -0
  42. package/dist/authoring.d.ts.map +1 -0
  43. package/dist/authoring.js +1 -0
  44. package/dist/booking-engine/handler-support.d.ts +91 -0
  45. package/dist/booking-engine/handler-support.d.ts.map +1 -0
  46. package/dist/booking-engine/handler-support.js +355 -0
  47. package/dist/booking-engine/handler.d.ts +404 -0
  48. package/dist/booking-engine/handler.d.ts.map +1 -0
  49. package/dist/booking-engine/handler.js +398 -0
  50. package/dist/booking-engine/index.d.ts +8 -0
  51. package/dist/booking-engine/index.d.ts.map +1 -0
  52. package/dist/booking-engine/index.js +7 -0
  53. package/dist/booking-engine.d.ts +2 -0
  54. package/dist/booking-engine.d.ts.map +1 -0
  55. package/dist/booking-engine.js +1 -0
  56. package/dist/booking-extension.d.ts +278 -0
  57. package/dist/booking-extension.d.ts.map +1 -0
  58. package/dist/booking-extension.js +161 -0
  59. package/dist/catalog-policy-departures.d.ts +52 -0
  60. package/dist/catalog-policy-departures.d.ts.map +1 -0
  61. package/dist/catalog-policy-departures.js +169 -0
  62. package/dist/catalog-policy-destinations.d.ts +43 -0
  63. package/dist/catalog-policy-destinations.d.ts.map +1 -0
  64. package/dist/catalog-policy-destinations.js +165 -0
  65. package/dist/catalog-policy-pricing.d.ts +55 -0
  66. package/dist/catalog-policy-pricing.d.ts.map +1 -0
  67. package/dist/catalog-policy-pricing.js +109 -0
  68. package/dist/catalog-policy-promotions.d.ts +52 -0
  69. package/dist/catalog-policy-promotions.d.ts.map +1 -0
  70. package/dist/catalog-policy-promotions.js +270 -0
  71. package/dist/catalog-policy-taxonomy.d.ts +51 -0
  72. package/dist/catalog-policy-taxonomy.d.ts.map +1 -0
  73. package/dist/catalog-policy-taxonomy.js +191 -0
  74. package/dist/catalog-policy.d.ts +33 -0
  75. package/dist/catalog-policy.d.ts.map +1 -0
  76. package/dist/catalog-policy.js +733 -0
  77. package/dist/content-shape.d.ts +15 -0
  78. package/dist/content-shape.d.ts.map +1 -0
  79. package/dist/content-shape.js +28 -0
  80. package/dist/draft-shape.d.ts +43 -0
  81. package/dist/draft-shape.d.ts.map +1 -0
  82. package/dist/draft-shape.js +48 -0
  83. package/dist/events.d.ts +37 -0
  84. package/dist/events.d.ts.map +1 -0
  85. package/dist/events.js +32 -0
  86. package/dist/extras/catalog-policy.d.ts +30 -0
  87. package/dist/extras/catalog-policy.d.ts.map +1 -0
  88. package/dist/extras/catalog-policy.js +319 -0
  89. package/dist/extras/content-shape.d.ts +5 -0
  90. package/dist/extras/content-shape.d.ts.map +1 -0
  91. package/dist/extras/content-shape.js +13 -0
  92. package/dist/extras/draft-shape.d.ts +34 -0
  93. package/dist/extras/draft-shape.d.ts.map +1 -0
  94. package/dist/extras/draft-shape.js +69 -0
  95. package/dist/extras/routes.d.ts +380 -0
  96. package/dist/extras/routes.d.ts.map +1 -0
  97. package/dist/extras/routes.js +59 -0
  98. package/dist/extras/schema-sourced-content.d.ts +254 -0
  99. package/dist/extras/schema-sourced-content.d.ts.map +1 -0
  100. package/dist/extras/schema-sourced-content.js +45 -0
  101. package/dist/extras/schema.d.ts +628 -0
  102. package/dist/extras/schema.d.ts.map +1 -0
  103. package/dist/extras/schema.js +87 -0
  104. package/dist/extras/service-catalog-plane.d.ts +77 -0
  105. package/dist/extras/service-catalog-plane.d.ts.map +1 -0
  106. package/dist/extras/service-catalog-plane.js +219 -0
  107. package/dist/extras/service-content-synthesizer.d.ts +41 -0
  108. package/dist/extras/service-content-synthesizer.d.ts.map +1 -0
  109. package/dist/extras/service-content-synthesizer.js +138 -0
  110. package/dist/extras/service-content.d.ts +48 -0
  111. package/dist/extras/service-content.d.ts.map +1 -0
  112. package/dist/extras/service-content.js +253 -0
  113. package/dist/extras/service.d.ts +185 -0
  114. package/dist/extras/service.d.ts.map +1 -0
  115. package/dist/extras/service.js +96 -0
  116. package/dist/extras/validation.d.ts +437 -0
  117. package/dist/extras/validation.d.ts.map +1 -0
  118. package/dist/extras/validation.js +149 -0
  119. package/dist/extras.d.ts +267 -0
  120. package/dist/extras.d.ts.map +1 -0
  121. package/dist/extras.js +19 -0
  122. package/dist/index.d.ts +22 -0
  123. package/dist/index.d.ts.map +1 -0
  124. package/dist/index.js +32 -0
  125. package/dist/interface.d.ts +5869 -0
  126. package/dist/interface.d.ts.map +1 -0
  127. package/dist/interface.js +54 -0
  128. package/dist/public-routes.d.ts +2 -0
  129. package/dist/public-routes.d.ts.map +1 -0
  130. package/dist/public-routes.js +1 -0
  131. package/dist/public-validation.d.ts +2 -0
  132. package/dist/public-validation.d.ts.map +1 -0
  133. package/dist/public-validation.js +1 -0
  134. package/dist/read-model.d.ts +25 -0
  135. package/dist/read-model.d.ts.map +1 -0
  136. package/dist/read-model.js +99 -0
  137. package/dist/route-env.d.ts +22 -0
  138. package/dist/route-env.d.ts.map +1 -0
  139. package/dist/route-env.js +1 -0
  140. package/dist/routes-associations.d.ts +164 -0
  141. package/dist/routes-associations.d.ts.map +1 -0
  142. package/dist/routes-associations.js +100 -0
  143. package/dist/routes-catalog.d.ts +436 -0
  144. package/dist/routes-catalog.d.ts.map +1 -0
  145. package/dist/routes-catalog.js +104 -0
  146. package/dist/routes-configuration.d.ts +773 -0
  147. package/dist/routes-configuration.d.ts.map +1 -0
  148. package/dist/routes-configuration.js +364 -0
  149. package/dist/routes-content.d.ts +74 -0
  150. package/dist/routes-content.d.ts.map +1 -0
  151. package/dist/routes-content.js +117 -0
  152. package/dist/routes-core.d.ts +331 -0
  153. package/dist/routes-core.d.ts.map +1 -0
  154. package/dist/routes-core.js +95 -0
  155. package/dist/routes-itinerary.d.ts +759 -0
  156. package/dist/routes-itinerary.d.ts.map +1 -0
  157. package/dist/routes-itinerary.js +387 -0
  158. package/dist/routes-maintenance.d.ts +32 -0
  159. package/dist/routes-maintenance.d.ts.map +1 -0
  160. package/dist/routes-maintenance.js +14 -0
  161. package/dist/routes-media.d.ts +634 -0
  162. package/dist/routes-media.d.ts.map +1 -0
  163. package/dist/routes-media.js +245 -0
  164. package/dist/routes-merchandising.d.ts +1120 -0
  165. package/dist/routes-merchandising.d.ts.map +1 -0
  166. package/dist/routes-merchandising.js +377 -0
  167. package/dist/routes-options.d.ts +363 -0
  168. package/dist/routes-options.d.ts.map +1 -0
  169. package/dist/routes-options.js +173 -0
  170. package/dist/routes-public.d.ts +776 -0
  171. package/dist/routes-public.d.ts.map +1 -0
  172. package/dist/routes-public.js +119 -0
  173. package/dist/routes-translations.d.ts +489 -0
  174. package/dist/routes-translations.d.ts.map +1 -0
  175. package/dist/routes-translations.js +258 -0
  176. package/dist/routes.d.ts +5097 -0
  177. package/dist/routes.d.ts.map +1 -0
  178. package/dist/routes.js +64 -0
  179. package/dist/schema-core.d.ts +1238 -0
  180. package/dist/schema-core.d.ts.map +1 -0
  181. package/dist/schema-core.js +157 -0
  182. package/dist/schema-itinerary.d.ts +1169 -0
  183. package/dist/schema-itinerary.d.ts.map +1 -0
  184. package/dist/schema-itinerary.js +130 -0
  185. package/dist/schema-relations.d.ts +117 -0
  186. package/dist/schema-relations.d.ts.map +1 -0
  187. package/dist/schema-relations.js +192 -0
  188. package/dist/schema-settings.d.ts +1800 -0
  189. package/dist/schema-settings.d.ts.map +1 -0
  190. package/dist/schema-settings.js +220 -0
  191. package/dist/schema-shared.d.ts +15 -0
  192. package/dist/schema-shared.d.ts.map +1 -0
  193. package/dist/schema-shared.js +91 -0
  194. package/dist/schema-sourced-content.d.ts +262 -0
  195. package/dist/schema-sourced-content.d.ts.map +1 -0
  196. package/dist/schema-sourced-content.js +69 -0
  197. package/dist/schema-taxonomy.d.ts +1363 -0
  198. package/dist/schema-taxonomy.d.ts.map +1 -0
  199. package/dist/schema-taxonomy.js +203 -0
  200. package/dist/schema.d.ts +10 -0
  201. package/dist/schema.d.ts.map +1 -0
  202. package/dist/schema.js +9 -0
  203. package/dist/service-aggregates.d.ts +29 -0
  204. package/dist/service-aggregates.d.ts.map +1 -0
  205. package/dist/service-aggregates.js +56 -0
  206. package/dist/service-catalog-plane-destinations.d.ts +30 -0
  207. package/dist/service-catalog-plane-destinations.d.ts.map +1 -0
  208. package/dist/service-catalog-plane-destinations.js +143 -0
  209. package/dist/service-catalog-plane-taxonomy.d.ts +73 -0
  210. package/dist/service-catalog-plane-taxonomy.d.ts.map +1 -0
  211. package/dist/service-catalog-plane-taxonomy.js +242 -0
  212. package/dist/service-catalog-plane.d.ts +179 -0
  213. package/dist/service-catalog-plane.d.ts.map +1 -0
  214. package/dist/service-catalog-plane.js +431 -0
  215. package/dist/service-catalog.d.ts +251 -0
  216. package/dist/service-catalog.d.ts.map +1 -0
  217. package/dist/service-catalog.js +517 -0
  218. package/dist/service-configuration.d.ts +261 -0
  219. package/dist/service-configuration.d.ts.map +1 -0
  220. package/dist/service-configuration.js +343 -0
  221. package/dist/service-content-owned.d.ts +68 -0
  222. package/dist/service-content-owned.d.ts.map +1 -0
  223. package/dist/service-content-owned.js +329 -0
  224. package/dist/service-content-synthesizer.d.ts +90 -0
  225. package/dist/service-content-synthesizer.d.ts.map +1 -0
  226. package/dist/service-content-synthesizer.js +178 -0
  227. package/dist/service-content.d.ts +106 -0
  228. package/dist/service-content.d.ts.map +1 -0
  229. package/dist/service-content.js +388 -0
  230. package/dist/service-core.d.ts +194 -0
  231. package/dist/service-core.d.ts.map +1 -0
  232. package/dist/service-core.js +213 -0
  233. package/dist/service-delivery-formats.d.ts +58 -0
  234. package/dist/service-delivery-formats.d.ts.map +1 -0
  235. package/dist/service-delivery-formats.js +107 -0
  236. package/dist/service-destinations.d.ts +223 -0
  237. package/dist/service-destinations.d.ts.map +1 -0
  238. package/dist/service-destinations.js +310 -0
  239. package/dist/service-itinerary-history.d.ts +457 -0
  240. package/dist/service-itinerary-history.d.ts.map +1 -0
  241. package/dist/service-itinerary-history.js +135 -0
  242. package/dist/service-itinerary.d.ts +1149 -0
  243. package/dist/service-itinerary.d.ts.map +1 -0
  244. package/dist/service-itinerary.js +419 -0
  245. package/dist/service-media.d.ts +272 -0
  246. package/dist/service-media.d.ts.map +1 -0
  247. package/dist/service-media.js +320 -0
  248. package/dist/service-merchandising.d.ts +184 -0
  249. package/dist/service-merchandising.d.ts.map +1 -0
  250. package/dist/service-merchandising.js +181 -0
  251. package/dist/service-option-translations.d.ts +268 -0
  252. package/dist/service-option-translations.d.ts.map +1 -0
  253. package/dist/service-option-translations.js +300 -0
  254. package/dist/service-options.d.ts +181 -0
  255. package/dist/service-options.d.ts.map +1 -0
  256. package/dist/service-options.js +179 -0
  257. package/dist/service-product-destinations.d.ts +37 -0
  258. package/dist/service-product-destinations.d.ts.map +1 -0
  259. package/dist/service-product-destinations.js +94 -0
  260. package/dist/service-public.d.ts +664 -0
  261. package/dist/service-public.d.ts.map +1 -0
  262. package/dist/service-public.js +374 -0
  263. package/dist/service-taxonomy.d.ts +197 -0
  264. package/dist/service-taxonomy.d.ts.map +1 -0
  265. package/dist/service-taxonomy.js +221 -0
  266. package/dist/service.d.ts +3929 -0
  267. package/dist/service.d.ts.map +1 -0
  268. package/dist/service.js +28 -0
  269. package/dist/tasks/brochure-printers.d.ts +31 -0
  270. package/dist/tasks/brochure-printers.d.ts.map +1 -0
  271. package/dist/tasks/brochure-printers.js +149 -0
  272. package/dist/tasks/brochure-templates.d.ts +36 -0
  273. package/dist/tasks/brochure-templates.d.ts.map +1 -0
  274. package/dist/tasks/brochure-templates.js +110 -0
  275. package/dist/tasks/brochures.d.ts +43 -0
  276. package/dist/tasks/brochures.d.ts.map +1 -0
  277. package/dist/tasks/brochures.js +72 -0
  278. package/dist/tasks/generate-pdf.d.ts +8 -0
  279. package/dist/tasks/generate-pdf.d.ts.map +1 -0
  280. package/dist/tasks/generate-pdf.js +106 -0
  281. package/dist/tasks/index.d.ts +5 -0
  282. package/dist/tasks/index.d.ts.map +1 -0
  283. package/dist/tasks/index.js +4 -0
  284. package/dist/tasks/pdf-text.d.ts +2 -0
  285. package/dist/tasks/pdf-text.d.ts.map +1 -0
  286. package/dist/tasks/pdf-text.js +40 -0
  287. package/dist/tasks.d.ts +2 -0
  288. package/dist/tasks.d.ts.map +1 -0
  289. package/dist/tasks.js +1 -0
  290. package/dist/validation-catalog.d.ts +2 -0
  291. package/dist/validation-catalog.d.ts.map +1 -0
  292. package/dist/validation-catalog.js +3 -0
  293. package/dist/validation-config.d.ts +2 -0
  294. package/dist/validation-config.d.ts.map +1 -0
  295. package/dist/validation-config.js +3 -0
  296. package/dist/validation-content.d.ts +2 -0
  297. package/dist/validation-content.d.ts.map +1 -0
  298. package/dist/validation-content.js +3 -0
  299. package/dist/validation-core.d.ts +2 -0
  300. package/dist/validation-core.d.ts.map +1 -0
  301. package/dist/validation-core.js +3 -0
  302. package/dist/validation-public.d.ts +2 -0
  303. package/dist/validation-public.d.ts.map +1 -0
  304. package/dist/validation-public.js +3 -0
  305. package/dist/validation-shared.d.ts +2 -0
  306. package/dist/validation-shared.d.ts.map +1 -0
  307. package/dist/validation-shared.js +3 -0
  308. package/dist/validation.d.ts +2 -0
  309. package/dist/validation.d.ts.map +1 -0
  310. package/dist/validation.js +3 -0
  311. package/package.json +204 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-ledger.d.ts","sourceRoot":"","sources":["../src/action-ledger.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,gCAAgC,EAEtC,MAAM,8CAA8C,CAAA;AAErD,OAAO,EACL,KAAK,8BAA8B,EAGpC,MAAM,uCAAuC,CAAA;AAE9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAG1C,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;GAAwC,CAAA;AAEnF,MAAM,MAAM,+BAA+B,GAAG,8BAA8B,CAAA;AAC5E,MAAM,MAAM,2BAA2B,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAA;AAEtF,wBAAgB,oCAAoC,CAClD,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,GACd,gCAAgC,CAgBlC;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,EACvB,MAAM,EAAE,OAAO,GAAG,IAAI,EACtB,KAAK,EAAE,OAAO,GAAG,IAAI,GACpB,MAAM,EAAE,CAEV;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACtC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GACpC,MAAM,EAAE,CAKV;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,2BAA2B,EACnC,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,SAAY,UASpB;AAED,wBAAsB,gCAAgC,CACpD,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EACf,KAAK,EAAE;IACL,MAAM,EAAE,2BAA2B,CAAA;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,yFAgBF;AAED,wBAAsB,uBAAuB,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oEAmC5D;AAcD,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;CAKpB,CAAA"}
@@ -0,0 +1,100 @@
1
+ import { appendActionLedgerMutation, } from "@voyant-travel/action-ledger/request-context";
2
+ import { actionLedgerService } from "@voyant-travel/action-ledger/service";
3
+ import { actionLedgerTargetTimelineQuerySchema, buildActionLedgerTargetTimelinePage, } from "@voyant-travel/action-ledger/timeline";
4
+ import { parseQuery } from "@voyant-travel/hono";
5
+ import { productsService } from "./service.js";
6
+ export const productActionLedgerQuerySchema = actionLedgerTargetTimelineQuerySchema;
7
+ export function getProductActionLedgerRequestContext(c) {
8
+ return {
9
+ userId: c.get("userId") ?? null,
10
+ agentId: c.get("agentId") ?? null,
11
+ workflowPrincipalId: c.get("workflowPrincipalId") ?? null,
12
+ principalSubtype: c.get("principalSubtype") ?? null,
13
+ sessionId: c.get("sessionId") ?? null,
14
+ apiTokenId: c.get("apiTokenId") ?? c.get("apiKeyId") ?? null,
15
+ callerType: c.get("callerType") ?? null,
16
+ actor: c.get("actor") ?? null,
17
+ isInternalRequest: c.get("isInternalRequest") ?? false,
18
+ organizationId: c.get("organizationId") ?? null,
19
+ workflowRunId: c.get("workflowRunId") ?? null,
20
+ workflowStepId: c.get("workflowStepId") ?? null,
21
+ correlationId: c.req.header("x-correlation-id") ?? c.req.header("x-request-id") ?? null,
22
+ };
23
+ }
24
+ export function changedProductFields(input, before, after) {
25
+ return changedMutationFields(input, before, after);
26
+ }
27
+ export function changedMutationFields(input, before, after) {
28
+ const fields = Object.keys(input).filter((field) => !ignoredMutationFields.has(field));
29
+ if (!before || !after)
30
+ return fields.sort();
31
+ return fields.filter((field) => !productValuesEqual(before[field], after[field])).sort();
32
+ }
33
+ export function productMutationSummary(action, fields, subject = "product") {
34
+ const formattedSubject = subject.trim() || "product";
35
+ if (action === "delete")
36
+ return `Deleted ${formattedSubject}`;
37
+ if (action === "duplicate")
38
+ return `Duplicated ${formattedSubject}`;
39
+ if (fields.length === 0)
40
+ return action === "create" ? `Created ${formattedSubject}` : `Updated ${formattedSubject}`;
41
+ const verb = action === "create" ? "Created" : "Updated";
42
+ return `${verb} ${formattedSubject} fields: ${fields.join(", ")}`;
43
+ }
44
+ export async function appendProductMutationLedgerEntry(c, input) {
45
+ return appendActionLedgerMutation(c.get("db"), {
46
+ context: getProductActionLedgerRequestContext(c),
47
+ actionName: input.actionName ?? `product.${input.action}`,
48
+ actionKind: input.action === "duplicate" ? "create" : input.action,
49
+ evaluatedRisk: "medium",
50
+ targetType: "product",
51
+ targetId: input.productId,
52
+ routeOrToolName: input.routeOrToolName ?? `products.${input.action}`,
53
+ mutationDetail: {
54
+ summary: input.summary ?? productMutationSummary(input.action, input.changedFields, input.subject),
55
+ reversalKind: "none",
56
+ },
57
+ });
58
+ }
59
+ export async function listProductActionLedger(c) {
60
+ const productId = c.req.param("id");
61
+ if (!productId)
62
+ return c.json({ error: "Product not found" }, 404);
63
+ const product = await productsService.getProductById(c.get("db"), productId);
64
+ if (!product)
65
+ return c.json({ error: "Product not found" }, 404);
66
+ const query = parseQuery(c, productActionLedgerQuerySchema);
67
+ const limit = query.limit ?? 50;
68
+ const result = await actionLedgerService.listEntries(c.get("db"), {
69
+ targetType: "product",
70
+ targetId: product.id,
71
+ cursor: query.cursor,
72
+ limit: limit + 1,
73
+ });
74
+ const page = buildActionLedgerTargetTimelinePage({
75
+ entries: result.entries,
76
+ limit,
77
+ });
78
+ const details = await Promise.all(page.data.map((entry) => actionLedgerService.getEntry(c.get("db"), entry.id)));
79
+ const summariesByActionId = new Map(details.flatMap((detail) => detail ? [[detail.entry.id, detail.mutationDetail?.summary ?? null]] : []));
80
+ return c.json(buildActionLedgerTargetTimelinePage({
81
+ entries: result.entries,
82
+ limit,
83
+ mutationSummariesByActionId: summariesByActionId,
84
+ }));
85
+ }
86
+ function productValuesEqual(left, right) {
87
+ if (left instanceof Date || right instanceof Date) {
88
+ const leftTime = left instanceof Date ? left.getTime() : new Date(String(left)).getTime();
89
+ const rightTime = right instanceof Date ? right.getTime() : new Date(String(right)).getTime();
90
+ return leftTime === rightTime;
91
+ }
92
+ return JSON.stringify(left) === JSON.stringify(right);
93
+ }
94
+ const ignoredMutationFields = new Set(["updatedAt", "createdAt"]);
95
+ export const __test__ = {
96
+ changedMutationFields,
97
+ changedProductFields,
98
+ productMutationSummary,
99
+ productActionLedgerQuerySchema,
100
+ };
@@ -0,0 +1,37 @@
1
+ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
2
+ import type { ProductGraphSpec } from "./spec.js";
3
+ export interface BuildProductGraphOptions {
4
+ /** Author of the initial `product_versions` snapshot. When omitted, no snapshot is taken. */
5
+ userId?: string;
6
+ /**
7
+ * Catalog every option price rule resolves to when the spec rule omits its own
8
+ * `priceCatalogId`. Clone leaves rule catalogs populated (so this is unused);
9
+ * compose passes the operator's default. A rule with neither errors.
10
+ */
11
+ defaultCatalogId?: string;
12
+ }
13
+ export interface BuiltOptionUnit {
14
+ ref: string;
15
+ id: string;
16
+ }
17
+ export interface BuiltOption {
18
+ ref: string;
19
+ id: string;
20
+ units: BuiltOptionUnit[];
21
+ }
22
+ export interface BuildProductGraphResult {
23
+ productId: string;
24
+ options: BuiltOption[];
25
+ }
26
+ /**
27
+ * Writes a {@link ProductGraphSpec} as a fresh product graph. MUST run inside a
28
+ * transaction (`db.transaction(async (tx) => buildProductGraph(tx, …))`) so a
29
+ * mid-build failure leaves nothing behind — the half-built-product problem this
30
+ * whole effort exists to kill.
31
+ *
32
+ * Never writes `availability_slots`: departures are date-specific and added
33
+ * separately. Local `ref`/`unitRef` keys in the spec are resolved to the
34
+ * freshly-minted ids here and never touch the database.
35
+ */
36
+ export declare function buildProductGraph(tx: PostgresJsDatabase, spec: ProductGraphSpec, options?: BuildProductGraphOptions): Promise<BuildProductGraphResult>;
37
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/authoring/builder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAYjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAEjD,MAAM,WAAW,wBAAwB;IACvC,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,eAAe,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,WAAW,EAAE,CAAA;CACvB;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,kBAAkB,EACtB,IAAI,EAAE,gBAAgB,EACtB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,uBAAuB,CAAC,CA+PlC"}
@@ -0,0 +1,248 @@
1
+ import { optionPriceRules, optionUnitPriceRules, optionUnitTiers } from "@voyant-travel/commerce";
2
+ import { optionUnits, productDayServices, productDays, productItineraries, productOptions, productPaxPricingTiers, products, } from "../schema.js";
3
+ import { productsService } from "../service.js";
4
+ import { AuthoringValidationError } from "./errors.js";
5
+ /**
6
+ * Writes a {@link ProductGraphSpec} as a fresh product graph. MUST run inside a
7
+ * transaction (`db.transaction(async (tx) => buildProductGraph(tx, …))`) so a
8
+ * mid-build failure leaves nothing behind — the half-built-product problem this
9
+ * whole effort exists to kill.
10
+ *
11
+ * Never writes `availability_slots`: departures are date-specific and added
12
+ * separately. Local `ref`/`unitRef` keys in the spec are resolved to the
13
+ * freshly-minted ids here and never touch the database.
14
+ */
15
+ export async function buildProductGraph(tx, spec, options = {}) {
16
+ const { userId, defaultCatalogId } = options;
17
+ // --- product row -----------------------------------------------------------
18
+ const [productRow] = await tx
19
+ .insert(products)
20
+ .values({
21
+ name: spec.product.name,
22
+ status: spec.product.status,
23
+ description: spec.product.description,
24
+ inclusionsHtml: spec.product.inclusionsHtml,
25
+ exclusionsHtml: spec.product.exclusionsHtml,
26
+ termsHtml: spec.product.termsHtml,
27
+ termsShowOnContract: spec.product.termsShowOnContract,
28
+ bookingMode: spec.product.bookingMode,
29
+ capacityMode: spec.product.capacityMode,
30
+ timezone: spec.product.timezone,
31
+ defaultLanguageTag: spec.product.defaultLanguageTag,
32
+ visibility: spec.product.visibility,
33
+ sellCurrency: spec.product.sellCurrency,
34
+ sellAmountCents: spec.product.sellAmountCents,
35
+ costAmountCents: spec.product.costAmountCents,
36
+ marginPercent: spec.product.marginPercent,
37
+ reservationTimeoutMinutes: spec.product.reservationTimeoutMinutes,
38
+ facilityId: spec.product.facilityId,
39
+ supplierId: spec.product.supplierId,
40
+ startDate: spec.product.startDate,
41
+ endDate: spec.product.endDate,
42
+ pax: spec.product.pax,
43
+ productTypeId: spec.product.productTypeId,
44
+ contractTemplateId: spec.product.contractTemplateId,
45
+ taxClassId: spec.product.taxClassId,
46
+ customerPaymentPolicy: spec.product.customerPaymentPolicy,
47
+ tags: spec.product.tags,
48
+ })
49
+ .returning({ id: products.id });
50
+ if (!productRow)
51
+ throw new Error("Failed to insert product");
52
+ const productId = productRow.id;
53
+ // Global ref → new-id maps. Refs are unique across the whole spec (clone uses
54
+ // source ids; compose uses caller-chosen keys), so unit refs from any option
55
+ // resolve here — covering both unit-price-rule unitRef and pax-tier unitRef.
56
+ const unitIdByRef = new Map();
57
+ const builtOptions = [];
58
+ // --- options + units -------------------------------------------------------
59
+ for (const option of spec.options) {
60
+ const [optionRow] = await tx
61
+ .insert(productOptions)
62
+ .values({
63
+ productId,
64
+ name: option.name,
65
+ code: option.code,
66
+ description: option.description,
67
+ status: option.status,
68
+ isDefault: option.isDefault,
69
+ sortOrder: option.sortOrder,
70
+ availableFrom: option.availableFrom,
71
+ availableTo: option.availableTo,
72
+ })
73
+ .returning({ id: productOptions.id });
74
+ if (!optionRow)
75
+ throw new Error("Failed to insert product option");
76
+ const optionId = optionRow.id;
77
+ const builtUnits = [];
78
+ for (const unit of option.units) {
79
+ const [unitRow] = await tx
80
+ .insert(optionUnits)
81
+ .values({
82
+ optionId,
83
+ name: unit.name,
84
+ code: unit.code,
85
+ description: unit.description,
86
+ unitType: unit.unitType,
87
+ minQuantity: unit.minQuantity,
88
+ maxQuantity: unit.maxQuantity,
89
+ minAge: unit.minAge,
90
+ maxAge: unit.maxAge,
91
+ occupancyMin: unit.occupancyMin,
92
+ occupancyMax: unit.occupancyMax,
93
+ isRequired: unit.isRequired,
94
+ isHidden: unit.isHidden,
95
+ sortOrder: unit.sortOrder,
96
+ })
97
+ .returning({ id: optionUnits.id });
98
+ if (!unitRow)
99
+ throw new Error("Failed to insert option unit");
100
+ unitIdByRef.set(unit.ref, unitRow.id);
101
+ builtUnits.push({ ref: unit.ref, id: unitRow.id });
102
+ }
103
+ // --- pricing: option rules → unit rules → tiers --------------------------
104
+ for (const rule of option.priceRules) {
105
+ const priceCatalogId = rule.priceCatalogId ?? defaultCatalogId;
106
+ if (!priceCatalogId) {
107
+ throw new AuthoringValidationError([
108
+ {
109
+ code: "no_price_catalog",
110
+ field: `options[].priceRules[].priceCatalogId`,
111
+ message: `Price rule "${rule.name}" has no priceCatalogId and no default catalog was resolved.`,
112
+ fix: "Supply priceCatalogId on the rule, or ensure a default price catalog exists.",
113
+ },
114
+ ]);
115
+ }
116
+ const [ruleRow] = await tx
117
+ .insert(optionPriceRules)
118
+ .values({
119
+ productId,
120
+ optionId,
121
+ priceCatalogId,
122
+ priceScheduleId: rule.priceScheduleId,
123
+ cancellationPolicyId: rule.cancellationPolicyId,
124
+ code: rule.code,
125
+ name: rule.name,
126
+ description: rule.description,
127
+ pricingMode: rule.pricingMode,
128
+ baseSellAmountCents: rule.baseSellAmountCents,
129
+ baseCostAmountCents: rule.baseCostAmountCents,
130
+ minPerBooking: rule.minPerBooking,
131
+ maxPerBooking: rule.maxPerBooking,
132
+ allPricingCategories: rule.allPricingCategories,
133
+ isDefault: rule.isDefault,
134
+ active: rule.active,
135
+ notes: rule.notes,
136
+ metadata: rule.metadata,
137
+ })
138
+ .returning({ id: optionPriceRules.id });
139
+ if (!ruleRow)
140
+ throw new Error("Failed to insert option price rule");
141
+ for (const unitRule of rule.unitPriceRules) {
142
+ const unitId = unitIdByRef.get(unitRule.unitRef);
143
+ if (!unitId) {
144
+ throw new AuthoringValidationError([
145
+ {
146
+ code: "unknown_unit_ref",
147
+ field: "options[].priceRules[].unitPriceRules[].unitRef",
148
+ message: `Unit price rule references unit "${unitRule.unitRef}", which is not defined in the spec.`,
149
+ fix: "Point unitRef at a unit declared under one of the options.",
150
+ },
151
+ ]);
152
+ }
153
+ const [unitRuleRow] = await tx
154
+ .insert(optionUnitPriceRules)
155
+ .values({
156
+ optionPriceRuleId: ruleRow.id,
157
+ optionId,
158
+ unitId,
159
+ pricingCategoryId: unitRule.pricingCategoryId,
160
+ pricingMode: unitRule.pricingMode,
161
+ sellAmountCents: unitRule.sellAmountCents,
162
+ costAmountCents: unitRule.costAmountCents,
163
+ minQuantity: unitRule.minQuantity,
164
+ maxQuantity: unitRule.maxQuantity,
165
+ active: unitRule.active,
166
+ sortOrder: unitRule.sortOrder,
167
+ notes: unitRule.notes,
168
+ metadata: unitRule.metadata,
169
+ })
170
+ .returning({ id: optionUnitPriceRules.id });
171
+ if (!unitRuleRow)
172
+ throw new Error("Failed to insert option unit price rule");
173
+ if (unitRule.tiers.length) {
174
+ await tx.insert(optionUnitTiers).values(unitRule.tiers.map((tier) => ({
175
+ optionUnitPriceRuleId: unitRuleRow.id,
176
+ minQuantity: tier.minQuantity,
177
+ maxQuantity: tier.maxQuantity,
178
+ sellAmountCents: tier.sellAmountCents,
179
+ costAmountCents: tier.costAmountCents,
180
+ active: tier.active,
181
+ sortOrder: tier.sortOrder,
182
+ })));
183
+ }
184
+ }
185
+ }
186
+ builtOptions.push({ ref: option.ref, id: optionId, units: builtUnits });
187
+ }
188
+ // --- pax pricing tiers -----------------------------------------------------
189
+ if (spec.paxPricingTiers.length) {
190
+ await tx.insert(productPaxPricingTiers).values(spec.paxPricingTiers.map((tier) => ({
191
+ productId,
192
+ optionUnitId: tier.unitRef ? (unitIdByRef.get(tier.unitRef) ?? null) : null,
193
+ tierPax: tier.tierPax,
194
+ pricePerPaxCents: tier.pricePerPaxCents,
195
+ promoPricePerPaxCents: tier.promoPricePerPaxCents,
196
+ effectiveFrom: tier.effectiveFrom,
197
+ effectiveTo: tier.effectiveTo,
198
+ })));
199
+ }
200
+ // --- itineraries → days → services -----------------------------------------
201
+ for (const itinerary of spec.itineraries) {
202
+ const [itineraryRow] = await tx
203
+ .insert(productItineraries)
204
+ .values({
205
+ productId,
206
+ name: itinerary.name,
207
+ isDefault: itinerary.isDefault,
208
+ sortOrder: itinerary.sortOrder,
209
+ })
210
+ .returning({ id: productItineraries.id });
211
+ if (!itineraryRow)
212
+ throw new Error("Failed to insert product itinerary");
213
+ for (const day of itinerary.days) {
214
+ const [dayRow] = await tx
215
+ .insert(productDays)
216
+ .values({
217
+ itineraryId: itineraryRow.id,
218
+ dayNumber: day.dayNumber,
219
+ title: day.title,
220
+ description: day.description,
221
+ location: day.location,
222
+ })
223
+ .returning({ id: productDays.id });
224
+ if (!dayRow)
225
+ throw new Error("Failed to insert product day");
226
+ if (day.services.length) {
227
+ await tx.insert(productDayServices).values(day.services.map((service) => ({
228
+ dayId: dayRow.id,
229
+ supplierServiceId: service.supplierServiceId,
230
+ serviceType: service.serviceType,
231
+ name: service.name,
232
+ description: service.description,
233
+ countryCode: service.countryCode,
234
+ costCurrency: service.costCurrency,
235
+ costAmountCents: service.costAmountCents,
236
+ quantity: service.quantity,
237
+ sortOrder: service.sortOrder,
238
+ notes: service.notes,
239
+ })));
240
+ }
241
+ }
242
+ }
243
+ // --- initial version snapshot ----------------------------------------------
244
+ if (userId) {
245
+ await productsService.createVersion(tx, productId, userId, {});
246
+ }
247
+ return { productId, options: builtOptions };
248
+ }
@@ -0,0 +1,38 @@
1
+ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
2
+ /** Shared, mutable state threaded across the clone copy phases (id remaps). */
3
+ export interface CloneContext {
4
+ tx: PostgresJsDatabase;
5
+ sourceId: string;
6
+ targetId: string;
7
+ copyDepartures: boolean;
8
+ optionIdMap: Map<string, string>;
9
+ unitIdMap: Map<string, string>;
10
+ unitsByNewOption: Map<string, {
11
+ id: string;
12
+ }[]>;
13
+ itineraryIdMap: Map<string, string>;
14
+ dayIdMap: Map<string, string>;
15
+ startTimeIdMap: Map<string, string>;
16
+ ruleIdMap: Map<string, string>;
17
+ slotIdMap: Map<string, string>;
18
+ optionPriceRuleIdMap: Map<string, string>;
19
+ optionUnitPriceRuleIdMap: Map<string, string>;
20
+ pricingCategoryIdMap: Map<string, string>;
21
+ productExtraIdMap: Map<string, string>;
22
+ optionExtraConfigIdMap: Map<string, string>;
23
+ }
24
+ type SystemColumns = {
25
+ id?: unknown;
26
+ createdAt?: unknown;
27
+ updatedAt?: unknown;
28
+ };
29
+ export declare function withoutSystemColumns<T extends SystemColumns>(row: T): Omit<T, "id" | "createdAt" | "updatedAt">;
30
+ /**
31
+ * Copies the product's content graph: per-product settings, options + units
32
+ * (with translations + resource templates), pricing categories (+ dependencies,
33
+ * remapped), itineraries/days/services, media, and extras. Populates the id
34
+ * remaps in {@link CloneContext} for the pricing/operations phase.
35
+ */
36
+ export declare function copyProductContent(ctx: CloneContext): Promise<void>;
37
+ export {};
38
+ //# sourceMappingURL=clone-content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clone-content.d.ts","sourceRoot":"","sources":["../../src/authoring/clone-content.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AA0BjE,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,kBAAkB,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,OAAO,CAAA;IACvB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAAA;IAC/C,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzC,wBAAwB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7C,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACtC,sBAAsB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC5C;AAED,KAAK,aAAa,GAAG;IACnB,EAAE,CAAC,EAAE,OAAO,CAAA;IACZ,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,aAAa,EAAE,GAAG,EAAE,CAAC,6CAGnE;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA6HzE"}