@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,16 @@
1
+ import { index, pgTable, text, timestamp } from "drizzle-orm/pg-core";
2
+ /**
3
+ * Dedup ledger for clone/compose. A clone or compose has no natural key
4
+ * (product names may collide), so we cannot reuse the booking-create
5
+ * advisory-lock-on-natural-key guard. Instead, callers (agent tool runtimes)
6
+ * pass an `Idempotency-Key`; a retried/double-tapped request with the same key
7
+ * returns the originally-created product id instead of building a second graph.
8
+ */
9
+ export const productAuthoringRequests = pgTable("product_authoring_requests", {
10
+ idempotencyKey: text("idempotency_key").primaryKey(),
11
+ /** The product produced by the first request with this key. */
12
+ productId: text("product_id").notNull(),
13
+ /** `duplicate` | `compose` — for observability only. */
14
+ operation: text("operation").notNull(),
15
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
16
+ }, (t) => [index("idx_par_product").on(t.productId)]);
@@ -0,0 +1,28 @@
1
+ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
2
+ import { type BuildProductGraphResult } from "./builder.js";
3
+ import { type AuthoringIssue } from "./errors.js";
4
+ import type { ProductGraphSpec } from "./spec.js";
5
+ export interface AuthoringRunOptions {
6
+ userId?: string;
7
+ /** Dedup key; a retried request with the same key returns the first result. */
8
+ idempotencyKey?: string;
9
+ }
10
+ export type ComposeProductOutcome = {
11
+ status: "ok";
12
+ result: BuildProductGraphResult;
13
+ reused: boolean;
14
+ } | {
15
+ status: "invalid";
16
+ issues: AuthoringIssue[];
17
+ };
18
+ /**
19
+ * Compose a brand-new product graph from a caller-supplied spec (#1495). Runs the
20
+ * category validator first; an invalid spec is returned (never built) so the
21
+ * caller can self-correct. Rules without a catalog fall back to the operator
22
+ * default.
23
+ *
24
+ * Cloning an existing product lives in `clone.ts` (`cloneProduct`); this module
25
+ * is the from-scratch path. See #1493 / #1495.
26
+ */
27
+ export declare function composeProduct(db: PostgresJsDatabase, spec: ProductGraphSpec, options?: AuthoringRunOptions): Promise<ComposeProductOutcome>;
28
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/authoring/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,KAAK,uBAAuB,EAAqB,MAAM,cAAc,CAAA;AAC9E,OAAO,EAAE,KAAK,cAAc,EAA4B,MAAM,aAAa,CAAA;AAE3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAGjD,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,uBAAuB,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAClE;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,cAAc,EAAE,CAAA;CAAE,CAAA;AAiDnD;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,kBAAkB,EACtB,IAAI,EAAE,gBAAgB,EACtB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,qBAAqB,CAAC,CAmBhC"}
@@ -0,0 +1,66 @@
1
+ import { priceCatalogs } from "@voyant-travel/commerce";
2
+ import { and, eq, sql } from "drizzle-orm";
3
+ import { buildProductGraph } from "./builder.js";
4
+ import { AuthoringValidationError } from "./errors.js";
5
+ import { productAuthoringRequests } from "./schema.js";
6
+ import { validateProductGraph } from "./validate.js";
7
+ /** Resolves the operator's default price catalog id, if one exists. */
8
+ async function getDefaultCatalogId(db) {
9
+ const [row] = await db
10
+ .select({ id: priceCatalogs.id })
11
+ .from(priceCatalogs)
12
+ .where(and(eq(priceCatalogs.isDefault, true), eq(priceCatalogs.active, true)))
13
+ .limit(1);
14
+ return row?.id;
15
+ }
16
+ /**
17
+ * Resolves an idempotency key inside an open transaction. Returns the previously
18
+ * created product id when the key has been seen, else runs `build`, records the
19
+ * key, and returns the fresh result. The advisory lock serializes concurrent
20
+ * requests sharing a key (the booking-create guard pattern).
21
+ */
22
+ async function withIdempotency(tx, key, operation, build) {
23
+ if (!key) {
24
+ return { result: await build(), reused: false };
25
+ }
26
+ // agent-quality: raw-sql reviewed -- owner: catalog-authoring; dynamic SQL interpolation uses Drizzle parameter binding or vetted SQL identifiers.
27
+ await tx.execute(sql `SELECT pg_advisory_xact_lock(hashtextextended(${key}, 0))`);
28
+ const [existing] = await tx
29
+ .select({ productId: productAuthoringRequests.productId })
30
+ .from(productAuthoringRequests)
31
+ .where(eq(productAuthoringRequests.idempotencyKey, key))
32
+ .limit(1);
33
+ if (existing) {
34
+ return { result: { productId: existing.productId, options: [] }, reused: true };
35
+ }
36
+ const result = await build();
37
+ await tx
38
+ .insert(productAuthoringRequests)
39
+ .values({ idempotencyKey: key, productId: result.productId, operation });
40
+ return { result, reused: false };
41
+ }
42
+ /**
43
+ * Compose a brand-new product graph from a caller-supplied spec (#1495). Runs the
44
+ * category validator first; an invalid spec is returned (never built) so the
45
+ * caller can self-correct. Rules without a catalog fall back to the operator
46
+ * default.
47
+ *
48
+ * Cloning an existing product lives in `clone.ts` (`cloneProduct`); this module
49
+ * is the from-scratch path. See #1493 / #1495.
50
+ */
51
+ export async function composeProduct(db, spec, options = {}) {
52
+ const issues = validateProductGraph(spec);
53
+ if (issues.length)
54
+ return { status: "invalid", issues };
55
+ const defaultCatalogId = await getDefaultCatalogId(db);
56
+ try {
57
+ const { result, reused } = await db.transaction((tx) => withIdempotency(tx, options.idempotencyKey, "compose", () => buildProductGraph(tx, spec, { userId: options.userId, defaultCatalogId })));
58
+ return { status: "ok", result, reused };
59
+ }
60
+ catch (error) {
61
+ if (error instanceof AuthoringValidationError) {
62
+ return { status: "invalid", issues: error.issues };
63
+ }
64
+ throw error;
65
+ }
66
+ }
@@ -0,0 +1,524 @@
1
+ import { z } from "zod";
2
+ export declare const unitSpecSchema: z.ZodObject<{
3
+ ref: z.ZodString;
4
+ name: z.ZodString;
5
+ code: z.ZodOptional<z.ZodNullable<z.ZodString>>;
6
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
7
+ unitType: z.ZodDefault<z.ZodEnum<{
8
+ other: "other";
9
+ person: "person";
10
+ group: "group";
11
+ room: "room";
12
+ vehicle: "vehicle";
13
+ service: "service";
14
+ }>>;
15
+ minQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
16
+ maxQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
17
+ minAge: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
18
+ maxAge: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
19
+ occupancyMin: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
20
+ occupancyMax: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
21
+ isRequired: z.ZodDefault<z.ZodBoolean>;
22
+ isHidden: z.ZodDefault<z.ZodBoolean>;
23
+ sortOrder: z.ZodDefault<z.ZodNumber>;
24
+ }, z.core.$strip>;
25
+ export declare const unitTierSpecSchema: z.ZodObject<{
26
+ minQuantity: z.ZodNumber;
27
+ maxQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
28
+ sellAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
29
+ costAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
30
+ active: z.ZodDefault<z.ZodBoolean>;
31
+ sortOrder: z.ZodDefault<z.ZodNumber>;
32
+ }, z.core.$strip>;
33
+ export declare const unitPriceRuleSpecSchema: z.ZodObject<{
34
+ unitRef: z.ZodString;
35
+ pricingCategoryId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
36
+ pricingMode: z.ZodDefault<z.ZodEnum<{
37
+ on_request: "on_request";
38
+ per_booking: "per_booking";
39
+ per_person: "per_person";
40
+ free: "free";
41
+ per_unit: "per_unit";
42
+ included: "included";
43
+ }>>;
44
+ sellAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
45
+ costAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
46
+ minQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
47
+ maxQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
48
+ active: z.ZodDefault<z.ZodBoolean>;
49
+ sortOrder: z.ZodDefault<z.ZodNumber>;
50
+ notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
51
+ metadata: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
52
+ tiers: z.ZodDefault<z.ZodArray<z.ZodObject<{
53
+ minQuantity: z.ZodNumber;
54
+ maxQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
55
+ sellAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
56
+ costAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
57
+ active: z.ZodDefault<z.ZodBoolean>;
58
+ sortOrder: z.ZodDefault<z.ZodNumber>;
59
+ }, z.core.$strip>>>;
60
+ }, z.core.$strip>;
61
+ export declare const optionPriceRuleSpecSchema: z.ZodObject<{
62
+ priceCatalogId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
63
+ priceScheduleId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
64
+ cancellationPolicyId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
65
+ code: z.ZodOptional<z.ZodNullable<z.ZodString>>;
66
+ name: z.ZodString;
67
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
68
+ pricingMode: z.ZodDefault<z.ZodEnum<{
69
+ on_request: "on_request";
70
+ per_booking: "per_booking";
71
+ per_person: "per_person";
72
+ starting_from: "starting_from";
73
+ free: "free";
74
+ }>>;
75
+ baseSellAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
76
+ baseCostAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
77
+ minPerBooking: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
78
+ maxPerBooking: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
79
+ allPricingCategories: z.ZodDefault<z.ZodBoolean>;
80
+ isDefault: z.ZodDefault<z.ZodBoolean>;
81
+ active: z.ZodDefault<z.ZodBoolean>;
82
+ notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
83
+ metadata: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
84
+ unitPriceRules: z.ZodDefault<z.ZodArray<z.ZodObject<{
85
+ unitRef: z.ZodString;
86
+ pricingCategoryId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
87
+ pricingMode: z.ZodDefault<z.ZodEnum<{
88
+ on_request: "on_request";
89
+ per_booking: "per_booking";
90
+ per_person: "per_person";
91
+ free: "free";
92
+ per_unit: "per_unit";
93
+ included: "included";
94
+ }>>;
95
+ sellAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
96
+ costAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
97
+ minQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
98
+ maxQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
99
+ active: z.ZodDefault<z.ZodBoolean>;
100
+ sortOrder: z.ZodDefault<z.ZodNumber>;
101
+ notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
102
+ metadata: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
103
+ tiers: z.ZodDefault<z.ZodArray<z.ZodObject<{
104
+ minQuantity: z.ZodNumber;
105
+ maxQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
106
+ sellAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
107
+ costAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
108
+ active: z.ZodDefault<z.ZodBoolean>;
109
+ sortOrder: z.ZodDefault<z.ZodNumber>;
110
+ }, z.core.$strip>>>;
111
+ }, z.core.$strip>>>;
112
+ }, z.core.$strip>;
113
+ export declare const optionSpecSchema: z.ZodObject<{
114
+ ref: z.ZodString;
115
+ name: z.ZodString;
116
+ code: z.ZodOptional<z.ZodNullable<z.ZodString>>;
117
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
118
+ status: z.ZodDefault<z.ZodEnum<{
119
+ draft: "draft";
120
+ active: "active";
121
+ archived: "archived";
122
+ }>>;
123
+ isDefault: z.ZodDefault<z.ZodBoolean>;
124
+ sortOrder: z.ZodDefault<z.ZodNumber>;
125
+ availableFrom: z.ZodOptional<z.ZodNullable<z.ZodString>>;
126
+ availableTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
127
+ units: z.ZodDefault<z.ZodArray<z.ZodObject<{
128
+ ref: z.ZodString;
129
+ name: z.ZodString;
130
+ code: z.ZodOptional<z.ZodNullable<z.ZodString>>;
131
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
132
+ unitType: z.ZodDefault<z.ZodEnum<{
133
+ other: "other";
134
+ person: "person";
135
+ group: "group";
136
+ room: "room";
137
+ vehicle: "vehicle";
138
+ service: "service";
139
+ }>>;
140
+ minQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
141
+ maxQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
142
+ minAge: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
143
+ maxAge: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
144
+ occupancyMin: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
145
+ occupancyMax: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
146
+ isRequired: z.ZodDefault<z.ZodBoolean>;
147
+ isHidden: z.ZodDefault<z.ZodBoolean>;
148
+ sortOrder: z.ZodDefault<z.ZodNumber>;
149
+ }, z.core.$strip>>>;
150
+ priceRules: z.ZodDefault<z.ZodArray<z.ZodObject<{
151
+ priceCatalogId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
152
+ priceScheduleId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
153
+ cancellationPolicyId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
154
+ code: z.ZodOptional<z.ZodNullable<z.ZodString>>;
155
+ name: z.ZodString;
156
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
157
+ pricingMode: z.ZodDefault<z.ZodEnum<{
158
+ on_request: "on_request";
159
+ per_booking: "per_booking";
160
+ per_person: "per_person";
161
+ starting_from: "starting_from";
162
+ free: "free";
163
+ }>>;
164
+ baseSellAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
165
+ baseCostAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
166
+ minPerBooking: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
167
+ maxPerBooking: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
168
+ allPricingCategories: z.ZodDefault<z.ZodBoolean>;
169
+ isDefault: z.ZodDefault<z.ZodBoolean>;
170
+ active: z.ZodDefault<z.ZodBoolean>;
171
+ notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
172
+ metadata: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
173
+ unitPriceRules: z.ZodDefault<z.ZodArray<z.ZodObject<{
174
+ unitRef: z.ZodString;
175
+ pricingCategoryId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
176
+ pricingMode: z.ZodDefault<z.ZodEnum<{
177
+ on_request: "on_request";
178
+ per_booking: "per_booking";
179
+ per_person: "per_person";
180
+ free: "free";
181
+ per_unit: "per_unit";
182
+ included: "included";
183
+ }>>;
184
+ sellAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
185
+ costAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
186
+ minQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
187
+ maxQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
188
+ active: z.ZodDefault<z.ZodBoolean>;
189
+ sortOrder: z.ZodDefault<z.ZodNumber>;
190
+ notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
191
+ metadata: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
192
+ tiers: z.ZodDefault<z.ZodArray<z.ZodObject<{
193
+ minQuantity: z.ZodNumber;
194
+ maxQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
195
+ sellAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
196
+ costAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
197
+ active: z.ZodDefault<z.ZodBoolean>;
198
+ sortOrder: z.ZodDefault<z.ZodNumber>;
199
+ }, z.core.$strip>>>;
200
+ }, z.core.$strip>>>;
201
+ }, z.core.$strip>>>;
202
+ }, z.core.$strip>;
203
+ export declare const paxPricingTierSpecSchema: z.ZodObject<{
204
+ unitRef: z.ZodOptional<z.ZodNullable<z.ZodString>>;
205
+ tierPax: z.ZodNumber;
206
+ pricePerPaxCents: z.ZodNumber;
207
+ promoPricePerPaxCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
208
+ effectiveFrom: z.ZodOptional<z.ZodNullable<z.ZodString>>;
209
+ effectiveTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
210
+ }, z.core.$strip>;
211
+ export declare const dayServiceSpecSchema: z.ZodObject<{
212
+ supplierServiceId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
213
+ serviceType: z.ZodEnum<{
214
+ transfer: "transfer";
215
+ other: "other";
216
+ accommodation: "accommodation";
217
+ experience: "experience";
218
+ guide: "guide";
219
+ meal: "meal";
220
+ }>;
221
+ name: z.ZodString;
222
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
223
+ countryCode: z.ZodOptional<z.ZodNullable<z.ZodString>>;
224
+ costCurrency: z.ZodString;
225
+ costAmountCents: z.ZodNumber;
226
+ quantity: z.ZodDefault<z.ZodNumber>;
227
+ sortOrder: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
228
+ notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
229
+ }, z.core.$strip>;
230
+ export declare const daySpecSchema: z.ZodObject<{
231
+ dayNumber: z.ZodNumber;
232
+ title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
233
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
234
+ location: z.ZodOptional<z.ZodNullable<z.ZodString>>;
235
+ services: z.ZodDefault<z.ZodArray<z.ZodObject<{
236
+ supplierServiceId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
237
+ serviceType: z.ZodEnum<{
238
+ transfer: "transfer";
239
+ other: "other";
240
+ accommodation: "accommodation";
241
+ experience: "experience";
242
+ guide: "guide";
243
+ meal: "meal";
244
+ }>;
245
+ name: z.ZodString;
246
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
247
+ countryCode: z.ZodOptional<z.ZodNullable<z.ZodString>>;
248
+ costCurrency: z.ZodString;
249
+ costAmountCents: z.ZodNumber;
250
+ quantity: z.ZodDefault<z.ZodNumber>;
251
+ sortOrder: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
252
+ notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
253
+ }, z.core.$strip>>>;
254
+ }, z.core.$strip>;
255
+ export declare const itinerarySpecSchema: z.ZodObject<{
256
+ name: z.ZodString;
257
+ isDefault: z.ZodDefault<z.ZodBoolean>;
258
+ sortOrder: z.ZodDefault<z.ZodNumber>;
259
+ days: z.ZodDefault<z.ZodArray<z.ZodObject<{
260
+ dayNumber: z.ZodNumber;
261
+ title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
262
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
263
+ location: z.ZodOptional<z.ZodNullable<z.ZodString>>;
264
+ services: z.ZodDefault<z.ZodArray<z.ZodObject<{
265
+ supplierServiceId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
266
+ serviceType: z.ZodEnum<{
267
+ transfer: "transfer";
268
+ other: "other";
269
+ accommodation: "accommodation";
270
+ experience: "experience";
271
+ guide: "guide";
272
+ meal: "meal";
273
+ }>;
274
+ name: z.ZodString;
275
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
276
+ countryCode: z.ZodOptional<z.ZodNullable<z.ZodString>>;
277
+ costCurrency: z.ZodString;
278
+ costAmountCents: z.ZodNumber;
279
+ quantity: z.ZodDefault<z.ZodNumber>;
280
+ sortOrder: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
281
+ notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
282
+ }, z.core.$strip>>>;
283
+ }, z.core.$strip>>>;
284
+ }, z.core.$strip>;
285
+ export declare const productRowSpecSchema: z.ZodObject<{
286
+ name: z.ZodString;
287
+ status: z.ZodDefault<z.ZodEnum<{
288
+ draft: "draft";
289
+ active: "active";
290
+ archived: "archived";
291
+ }>>;
292
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
293
+ inclusionsHtml: z.ZodOptional<z.ZodNullable<z.ZodString>>;
294
+ exclusionsHtml: z.ZodOptional<z.ZodNullable<z.ZodString>>;
295
+ termsHtml: z.ZodOptional<z.ZodNullable<z.ZodString>>;
296
+ termsShowOnContract: z.ZodDefault<z.ZodBoolean>;
297
+ bookingMode: z.ZodDefault<z.ZodEnum<{
298
+ date: "date";
299
+ date_time: "date_time";
300
+ open: "open";
301
+ stay: "stay";
302
+ transfer: "transfer";
303
+ itinerary: "itinerary";
304
+ other: "other";
305
+ }>>;
306
+ capacityMode: z.ZodDefault<z.ZodEnum<{
307
+ free_sale: "free_sale";
308
+ limited: "limited";
309
+ on_request: "on_request";
310
+ }>>;
311
+ timezone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
312
+ defaultLanguageTag: z.ZodOptional<z.ZodNullable<z.ZodString>>;
313
+ visibility: z.ZodDefault<z.ZodEnum<{
314
+ public: "public";
315
+ private: "private";
316
+ hidden: "hidden";
317
+ }>>;
318
+ sellCurrency: z.ZodString;
319
+ sellAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
320
+ costAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
321
+ marginPercent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
322
+ reservationTimeoutMinutes: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
323
+ facilityId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
324
+ supplierId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
325
+ startDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
326
+ endDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
327
+ pax: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
328
+ productTypeId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
329
+ contractTemplateId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
330
+ taxClassId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
331
+ customerPaymentPolicy: z.ZodOptional<z.ZodNullable<z.ZodUnknown>>;
332
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
333
+ }, z.core.$strip>;
334
+ export declare const productGraphSpecSchema: z.ZodObject<{
335
+ product: z.ZodObject<{
336
+ name: z.ZodString;
337
+ status: z.ZodDefault<z.ZodEnum<{
338
+ draft: "draft";
339
+ active: "active";
340
+ archived: "archived";
341
+ }>>;
342
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
343
+ inclusionsHtml: z.ZodOptional<z.ZodNullable<z.ZodString>>;
344
+ exclusionsHtml: z.ZodOptional<z.ZodNullable<z.ZodString>>;
345
+ termsHtml: z.ZodOptional<z.ZodNullable<z.ZodString>>;
346
+ termsShowOnContract: z.ZodDefault<z.ZodBoolean>;
347
+ bookingMode: z.ZodDefault<z.ZodEnum<{
348
+ date: "date";
349
+ date_time: "date_time";
350
+ open: "open";
351
+ stay: "stay";
352
+ transfer: "transfer";
353
+ itinerary: "itinerary";
354
+ other: "other";
355
+ }>>;
356
+ capacityMode: z.ZodDefault<z.ZodEnum<{
357
+ free_sale: "free_sale";
358
+ limited: "limited";
359
+ on_request: "on_request";
360
+ }>>;
361
+ timezone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
362
+ defaultLanguageTag: z.ZodOptional<z.ZodNullable<z.ZodString>>;
363
+ visibility: z.ZodDefault<z.ZodEnum<{
364
+ public: "public";
365
+ private: "private";
366
+ hidden: "hidden";
367
+ }>>;
368
+ sellCurrency: z.ZodString;
369
+ sellAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
370
+ costAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
371
+ marginPercent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
372
+ reservationTimeoutMinutes: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
373
+ facilityId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
374
+ supplierId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
375
+ startDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
376
+ endDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
377
+ pax: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
378
+ productTypeId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
379
+ contractTemplateId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
380
+ taxClassId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
381
+ customerPaymentPolicy: z.ZodOptional<z.ZodNullable<z.ZodUnknown>>;
382
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
383
+ }, z.core.$strip>;
384
+ options: z.ZodDefault<z.ZodArray<z.ZodObject<{
385
+ ref: z.ZodString;
386
+ name: z.ZodString;
387
+ code: z.ZodOptional<z.ZodNullable<z.ZodString>>;
388
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
389
+ status: z.ZodDefault<z.ZodEnum<{
390
+ draft: "draft";
391
+ active: "active";
392
+ archived: "archived";
393
+ }>>;
394
+ isDefault: z.ZodDefault<z.ZodBoolean>;
395
+ sortOrder: z.ZodDefault<z.ZodNumber>;
396
+ availableFrom: z.ZodOptional<z.ZodNullable<z.ZodString>>;
397
+ availableTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
398
+ units: z.ZodDefault<z.ZodArray<z.ZodObject<{
399
+ ref: z.ZodString;
400
+ name: z.ZodString;
401
+ code: z.ZodOptional<z.ZodNullable<z.ZodString>>;
402
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
403
+ unitType: z.ZodDefault<z.ZodEnum<{
404
+ other: "other";
405
+ person: "person";
406
+ group: "group";
407
+ room: "room";
408
+ vehicle: "vehicle";
409
+ service: "service";
410
+ }>>;
411
+ minQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
412
+ maxQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
413
+ minAge: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
414
+ maxAge: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
415
+ occupancyMin: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
416
+ occupancyMax: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
417
+ isRequired: z.ZodDefault<z.ZodBoolean>;
418
+ isHidden: z.ZodDefault<z.ZodBoolean>;
419
+ sortOrder: z.ZodDefault<z.ZodNumber>;
420
+ }, z.core.$strip>>>;
421
+ priceRules: z.ZodDefault<z.ZodArray<z.ZodObject<{
422
+ priceCatalogId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
423
+ priceScheduleId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
424
+ cancellationPolicyId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
425
+ code: z.ZodOptional<z.ZodNullable<z.ZodString>>;
426
+ name: z.ZodString;
427
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
428
+ pricingMode: z.ZodDefault<z.ZodEnum<{
429
+ on_request: "on_request";
430
+ per_booking: "per_booking";
431
+ per_person: "per_person";
432
+ starting_from: "starting_from";
433
+ free: "free";
434
+ }>>;
435
+ baseSellAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
436
+ baseCostAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
437
+ minPerBooking: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
438
+ maxPerBooking: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
439
+ allPricingCategories: z.ZodDefault<z.ZodBoolean>;
440
+ isDefault: z.ZodDefault<z.ZodBoolean>;
441
+ active: z.ZodDefault<z.ZodBoolean>;
442
+ notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
443
+ metadata: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
444
+ unitPriceRules: z.ZodDefault<z.ZodArray<z.ZodObject<{
445
+ unitRef: z.ZodString;
446
+ pricingCategoryId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
447
+ pricingMode: z.ZodDefault<z.ZodEnum<{
448
+ on_request: "on_request";
449
+ per_booking: "per_booking";
450
+ per_person: "per_person";
451
+ free: "free";
452
+ per_unit: "per_unit";
453
+ included: "included";
454
+ }>>;
455
+ sellAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
456
+ costAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
457
+ minQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
458
+ maxQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
459
+ active: z.ZodDefault<z.ZodBoolean>;
460
+ sortOrder: z.ZodDefault<z.ZodNumber>;
461
+ notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
462
+ metadata: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
463
+ tiers: z.ZodDefault<z.ZodArray<z.ZodObject<{
464
+ minQuantity: z.ZodNumber;
465
+ maxQuantity: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
466
+ sellAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
467
+ costAmountCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
468
+ active: z.ZodDefault<z.ZodBoolean>;
469
+ sortOrder: z.ZodDefault<z.ZodNumber>;
470
+ }, z.core.$strip>>>;
471
+ }, z.core.$strip>>>;
472
+ }, z.core.$strip>>>;
473
+ }, z.core.$strip>>>;
474
+ paxPricingTiers: z.ZodDefault<z.ZodArray<z.ZodObject<{
475
+ unitRef: z.ZodOptional<z.ZodNullable<z.ZodString>>;
476
+ tierPax: z.ZodNumber;
477
+ pricePerPaxCents: z.ZodNumber;
478
+ promoPricePerPaxCents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
479
+ effectiveFrom: z.ZodOptional<z.ZodNullable<z.ZodString>>;
480
+ effectiveTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
481
+ }, z.core.$strip>>>;
482
+ itineraries: z.ZodDefault<z.ZodArray<z.ZodObject<{
483
+ name: z.ZodString;
484
+ isDefault: z.ZodDefault<z.ZodBoolean>;
485
+ sortOrder: z.ZodDefault<z.ZodNumber>;
486
+ days: z.ZodDefault<z.ZodArray<z.ZodObject<{
487
+ dayNumber: z.ZodNumber;
488
+ title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
489
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
490
+ location: z.ZodOptional<z.ZodNullable<z.ZodString>>;
491
+ services: z.ZodDefault<z.ZodArray<z.ZodObject<{
492
+ supplierServiceId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
493
+ serviceType: z.ZodEnum<{
494
+ transfer: "transfer";
495
+ other: "other";
496
+ accommodation: "accommodation";
497
+ experience: "experience";
498
+ guide: "guide";
499
+ meal: "meal";
500
+ }>;
501
+ name: z.ZodString;
502
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
503
+ countryCode: z.ZodOptional<z.ZodNullable<z.ZodString>>;
504
+ costCurrency: z.ZodString;
505
+ costAmountCents: z.ZodNumber;
506
+ quantity: z.ZodDefault<z.ZodNumber>;
507
+ sortOrder: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
508
+ notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
509
+ }, z.core.$strip>>>;
510
+ }, z.core.$strip>>>;
511
+ }, z.core.$strip>>>;
512
+ }, z.core.$strip>;
513
+ export type UnitSpec = z.infer<typeof unitSpecSchema>;
514
+ export type UnitTierSpec = z.infer<typeof unitTierSpecSchema>;
515
+ export type UnitPriceRuleSpec = z.infer<typeof unitPriceRuleSpecSchema>;
516
+ export type OptionPriceRuleSpec = z.infer<typeof optionPriceRuleSpecSchema>;
517
+ export type OptionSpec = z.infer<typeof optionSpecSchema>;
518
+ export type PaxPricingTierSpec = z.infer<typeof paxPricingTierSpecSchema>;
519
+ export type DayServiceSpec = z.infer<typeof dayServiceSpecSchema>;
520
+ export type DaySpec = z.infer<typeof daySpecSchema>;
521
+ export type ItinerarySpec = z.infer<typeof itinerarySpecSchema>;
522
+ export type ProductRowSpec = z.infer<typeof productRowSpecSchema>;
523
+ export type ProductGraphSpec = z.infer<typeof productGraphSpecSchema>;
524
+ //# sourceMappingURL=spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../src/authoring/spec.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAiCvB,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;iBAezB,CAAA;AAEF,eAAO,MAAM,kBAAkB;;;;;;;iBAO7B,CAAA;AAEF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAclC,CAAA;AAEF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsBpC,CAAA;AAEF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAY3B,CAAA;AAEF,eAAO,MAAM,wBAAwB;;;;;;;iBAQnC,CAAA;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;iBAW/B,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;iBAMxB,CAAA;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAK9B,CAAA;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4B/B,CAAA;AAEF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAKjC,CAAA;AAEF,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AACrD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAC7D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA;AACvE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAC3E,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AACzD,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAA;AACzE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACjE,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AACnD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAC/D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACjE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA"}