@voyantjs/travel-composer 0.55.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 (56) hide show
  1. package/README.md +38 -0
  2. package/dist/catalog-component-adapter.d.ts +16 -0
  3. package/dist/catalog-component-adapter.d.ts.map +1 -0
  4. package/dist/catalog-component-adapter.js +34 -0
  5. package/dist/cruise-extension.d.ts +48 -0
  6. package/dist/cruise-extension.d.ts.map +1 -0
  7. package/dist/cruise-extension.js +66 -0
  8. package/dist/index.d.ts +21 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +29 -0
  11. package/dist/mcp-tools.d.ts +157 -0
  12. package/dist/mcp-tools.d.ts.map +1 -0
  13. package/dist/mcp-tools.js +109 -0
  14. package/dist/routes.d.ts +1988 -0
  15. package/dist/routes.d.ts.map +1 -0
  16. package/dist/routes.js +239 -0
  17. package/dist/schema.d.ts +1228 -0
  18. package/dist/schema.d.ts.map +1 -0
  19. package/dist/schema.js +163 -0
  20. package/dist/service-cancellation.d.ts +6 -0
  21. package/dist/service-cancellation.d.ts.map +1 -0
  22. package/dist/service-cancellation.js +251 -0
  23. package/dist/service-checkout.d.ts +6 -0
  24. package/dist/service-checkout.d.ts.map +1 -0
  25. package/dist/service-checkout.js +328 -0
  26. package/dist/service-drafts.d.ts +13 -0
  27. package/dist/service-drafts.d.ts.map +1 -0
  28. package/dist/service-drafts.js +223 -0
  29. package/dist/service-helpers.d.ts +17 -0
  30. package/dist/service-helpers.d.ts.map +1 -0
  31. package/dist/service-helpers.js +161 -0
  32. package/dist/service-internals.d.ts +11 -0
  33. package/dist/service-internals.d.ts.map +1 -0
  34. package/dist/service-internals.js +72 -0
  35. package/dist/service-pricing.d.ts +8 -0
  36. package/dist/service-pricing.d.ts.map +1 -0
  37. package/dist/service-pricing.js +142 -0
  38. package/dist/service-reservation.d.ts +5 -0
  39. package/dist/service-reservation.d.ts.map +1 -0
  40. package/dist/service-reservation.js +447 -0
  41. package/dist/service-trips.d.ts +14 -0
  42. package/dist/service-trips.d.ts.map +1 -0
  43. package/dist/service-trips.js +377 -0
  44. package/dist/service-types.d.ts +252 -0
  45. package/dist/service-types.d.ts.map +1 -0
  46. package/dist/service-types.js +6 -0
  47. package/dist/service.d.ts +33 -0
  48. package/dist/service.d.ts.map +1 -0
  49. package/dist/service.js +35 -0
  50. package/dist/traveler-party-validation.d.ts +3 -0
  51. package/dist/traveler-party-validation.d.ts.map +1 -0
  52. package/dist/traveler-party-validation.js +68 -0
  53. package/dist/validation.d.ts +363 -0
  54. package/dist/validation.d.ts.map +1 -0
  55. package/dist/validation.js +226 -0
  56. package/package.json +88 -0
@@ -0,0 +1,226 @@
1
+ import { z } from "zod";
2
+ export const tripEnvelopeStatusSchema = z.enum([
3
+ "draft",
4
+ "priced",
5
+ "reserve_in_progress",
6
+ "reserved",
7
+ "checkout_started",
8
+ "booked",
9
+ "failed",
10
+ "cancelled",
11
+ ]);
12
+ export const tripComponentKindSchema = z.enum([
13
+ "catalog_booking",
14
+ "manual_placeholder",
15
+ "flight_placeholder",
16
+ "flight_order",
17
+ "external_order",
18
+ ]);
19
+ export const tripComponentStatusSchema = z.enum([
20
+ "draft",
21
+ "priced",
22
+ "unavailable",
23
+ "held",
24
+ "booked",
25
+ "checkout_started",
26
+ "failed",
27
+ "cancelled",
28
+ "removed",
29
+ ]);
30
+ export const tripComponentEventTypeSchema = z.enum([
31
+ "created",
32
+ "updated",
33
+ "priced",
34
+ "hold_placed",
35
+ "booked",
36
+ "checkout_started",
37
+ "failed",
38
+ "cancelled",
39
+ "removed",
40
+ "staff_remediation_required",
41
+ ]);
42
+ export const tripComponentTaxLineSchema = z.object({
43
+ code: z.string().min(1),
44
+ label: z.string().min(1),
45
+ amountCents: z.number().int(),
46
+ baseAmountCents: z.number().int(),
47
+ rate: z.number().nonnegative().optional(),
48
+ jurisdiction: z.string().min(1).optional(),
49
+ includedInPrice: z.boolean().optional(),
50
+ source: z.string().min(1).optional(),
51
+ });
52
+ export const tripComponentPricingSnapshotSchema = z.object({
53
+ currency: z.string().length(3),
54
+ subtotalAmountCents: z.number().int(),
55
+ taxAmountCents: z.number().int(),
56
+ totalAmountCents: z.number().int(),
57
+ priceExpiresAt: z.string().datetime().optional(),
58
+ warnings: z.array(z.string()).optional(),
59
+ });
60
+ export const tripEnvelopePricingSnapshotSchema = z.object({
61
+ currency: z.string().length(3),
62
+ subtotalAmountCents: z.number().int(),
63
+ taxAmountCents: z.number().int(),
64
+ totalAmountCents: z.number().int(),
65
+ componentCount: z.number().int().nonnegative(),
66
+ pricedComponentCount: z.number().int().nonnegative(),
67
+ warnings: z.array(z.string()).optional(),
68
+ });
69
+ export const catalogComponentReferenceSchema = z.object({
70
+ entityModule: z.string().min(1),
71
+ entityId: z.string().min(1),
72
+ sourceKind: z.string().min(1),
73
+ sourceConnectionId: z.string().min(1).optional(),
74
+ sourceRef: z.string().min(1).optional(),
75
+ });
76
+ export const committedComponentReferenceSchema = z.object({
77
+ bookingId: z.string().min(1).optional(),
78
+ bookingGroupId: z.string().min(1).optional(),
79
+ orderId: z.string().min(1).optional(),
80
+ paymentSessionId: z.string().min(1).optional(),
81
+ providerRef: z.string().min(1).optional(),
82
+ supplierRef: z.string().min(1).optional(),
83
+ });
84
+ export const createTripEnvelopeSchema = z.object({
85
+ title: z.string().min(1).max(255).optional(),
86
+ description: z.string().optional(),
87
+ travelerParty: z.record(z.string(), z.unknown()).default({}),
88
+ constraints: z.record(z.string(), z.unknown()).default({}),
89
+ createdBy: z.string().min(1).optional(),
90
+ });
91
+ export const tripsListSortFieldSchema = z.enum(["updatedAt", "createdAt", "status", "total"]);
92
+ export const tripsListSortDirSchema = z.enum(["asc", "desc"]);
93
+ export const listTripsQuerySchema = z.object({
94
+ status: tripEnvelopeStatusSchema.optional(),
95
+ search: z.string().trim().min(1).max(255).optional(),
96
+ // Component-driven filters. Match trips that contain *at least one*
97
+ // non-removed component referencing the given entity / vertical.
98
+ productId: z.string().trim().min(1).max(255).optional(),
99
+ hospitalityId: z.string().trim().min(1).max(255).optional(),
100
+ cruiseId: z.string().trim().min(1).max(255).optional(),
101
+ hasFlight: z.coerce.boolean().optional(),
102
+ // Envelope-level numeric / temporal filters.
103
+ totalMinCents: z.coerce.number().int().nonnegative().optional(),
104
+ totalMaxCents: z.coerce.number().int().nonnegative().optional(),
105
+ createdFrom: z.string().trim().min(1).max(35).optional(),
106
+ createdTo: z.string().trim().min(1).max(35).optional(),
107
+ sortBy: tripsListSortFieldSchema.default("updatedAt"),
108
+ sortDir: tripsListSortDirSchema.default("desc"),
109
+ limit: z.coerce.number().int().min(1).max(100).default(50),
110
+ offset: z.coerce.number().int().min(0).default(0),
111
+ });
112
+ export const updateTripEnvelopeSchema = z.object({
113
+ title: z.string().min(1).max(255).nullable().optional(),
114
+ description: z.string().nullable().optional(),
115
+ travelerParty: z.record(z.string(), z.unknown()).optional(),
116
+ constraints: z.record(z.string(), z.unknown()).optional(),
117
+ status: tripEnvelopeStatusSchema.optional(),
118
+ updatedBy: z.string().min(1).nullable().optional(),
119
+ });
120
+ const createTripComponentBaseSchema = z
121
+ .object({
122
+ envelopeId: z.string().min(1),
123
+ sequence: z.number().int().min(0).default(0),
124
+ kind: tripComponentKindSchema,
125
+ description: z.string().optional(),
126
+ catalogRef: catalogComponentReferenceSchema.optional(),
127
+ estimatedPricing: tripComponentPricingSnapshotSchema.optional(),
128
+ metadata: z.record(z.string(), z.unknown()).default({}),
129
+ })
130
+ .strict();
131
+ const createTripComponentBodyBaseSchema = createTripComponentBaseSchema.omit({ envelopeId: true });
132
+ function requireManualServiceName(component, ctx) {
133
+ const metadata = component.metadata;
134
+ if (component.kind !== "manual_placeholder" || metadata.template !== "manual")
135
+ return;
136
+ const name = metadata.manualService?.name;
137
+ if (typeof name !== "string" || name.trim().length === 0) {
138
+ ctx.addIssue({
139
+ code: z.ZodIssueCode.custom,
140
+ path: ["metadata", "manualService", "name"],
141
+ message: "Manual services require metadata.manualService.name",
142
+ });
143
+ }
144
+ }
145
+ export const createTripComponentSchema = createTripComponentBaseSchema.superRefine(requireManualServiceName);
146
+ export const createTripComponentBodySchema = createTripComponentBodyBaseSchema.superRefine(requireManualServiceName);
147
+ export const updateTripComponentSchema = z.object({
148
+ sequence: z.number().int().min(0).optional(),
149
+ status: tripComponentStatusSchema.optional(),
150
+ description: z.string().nullable().optional(),
151
+ catalogRef: catalogComponentReferenceSchema.nullable().optional(),
152
+ metadata: z.record(z.string(), z.unknown()).optional(),
153
+ warningCodes: z.array(z.string().min(1)).optional(),
154
+ });
155
+ export const reorderTripComponentsSchema = z.object({
156
+ envelopeId: z.string().min(1),
157
+ componentIds: z.array(z.string().min(1)).min(1),
158
+ });
159
+ export const updateTripComponentRefsSchema = z.object({
160
+ bookingDraftId: z.string().min(1).optional(),
161
+ catalogQuoteId: z.string().min(1).optional(),
162
+ committedRef: committedComponentReferenceSchema.optional(),
163
+ });
164
+ export const priceTripSchema = z.object({
165
+ envelopeId: z.string().min(1),
166
+ scope: z.object({
167
+ locale: z.string().min(1),
168
+ audience: z.enum(["staff", "customer", "partner", "supplier"]),
169
+ market: z.string().min(1),
170
+ currency: z.string().length(3).optional(),
171
+ }),
172
+ ttlMs: z.number().int().positive().optional(),
173
+ });
174
+ export const reserveTripSchema = z.object({
175
+ envelopeId: z.string().min(1),
176
+ idempotencyKey: z.string().min(1).max(255).optional(),
177
+ refreshScope: priceTripSchema.shape.scope.optional(),
178
+ });
179
+ export const startTripCheckoutSchema = z.object({
180
+ envelopeId: z.string().min(1),
181
+ idempotencyKey: z.string().min(1).max(255).optional(),
182
+ intent: z.enum(["card", "bank_transfer", "hold", "inquiry"]).default("card"),
183
+ request: z.record(z.string(), z.unknown()).default({}),
184
+ });
185
+ export const previewTripCancellationSchema = z.object({
186
+ envelopeId: z.string().min(1),
187
+ componentIds: z.array(z.string().min(1)).min(1).optional(),
188
+ reason: z.string().min(1).max(500).optional(),
189
+ requestedAt: z.string().datetime().optional(),
190
+ request: z.record(z.string(), z.unknown()).default({}),
191
+ });
192
+ export const cancelTripComponentsSchema = previewTripCancellationSchema.extend({
193
+ idempotencyKey: z.string().min(1).max(255).optional(),
194
+ });
195
+ const allowedTripComponentStatusTransitions = {
196
+ draft: ["priced", "unavailable", "failed", "cancelled", "removed"],
197
+ priced: ["priced", "unavailable", "held", "booked", "failed", "cancelled", "removed"],
198
+ unavailable: ["draft", "priced", "failed", "cancelled", "removed"],
199
+ held: ["booked", "checkout_started", "failed", "cancelled"],
200
+ booked: ["checkout_started", "cancelled"],
201
+ checkout_started: ["booked", "failed", "cancelled"],
202
+ failed: ["draft", "priced", "removed"],
203
+ cancelled: [],
204
+ removed: [],
205
+ };
206
+ export function isAllowedTripComponentStatusTransition(from, to) {
207
+ return (from === to ||
208
+ allowedTripComponentStatusTransitions[from].includes(to));
209
+ }
210
+ export const tripComponentStatusTransitionSchema = z
211
+ .object({
212
+ from: tripComponentStatusSchema,
213
+ to: tripComponentStatusSchema,
214
+ })
215
+ .refine(({ from, to }) => isAllowedTripComponentStatusTransition(from, to), {
216
+ message: "Invalid trip component status transition",
217
+ path: ["to"],
218
+ });
219
+ export function isTerminalTripComponentStatus(status) {
220
+ return status === "cancelled" || status === "removed";
221
+ }
222
+ export const travelComposerStatusSchema = z.object({
223
+ module: z.literal("travel-composer"),
224
+ status: z.literal("scaffolded"),
225
+ });
226
+ export const travelComposerHealthCheckSchema = travelComposerStatusSchema;
package/package.json ADDED
@@ -0,0 +1,88 @@
1
+ {
2
+ "name": "@voyantjs/travel-composer",
3
+ "version": "0.55.0",
4
+ "license": "Apache-2.0",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": "./src/index.ts",
8
+ "./schema": "./src/schema.ts",
9
+ "./validation": "./src/validation.ts",
10
+ "./service": "./src/service.ts",
11
+ "./mcp-tools": "./src/mcp-tools.ts",
12
+ "./cruise-extension": "./src/cruise-extension.ts",
13
+ "./routes": "./src/routes.ts"
14
+ },
15
+ "scripts": {
16
+ "typecheck": "tsc --noEmit",
17
+ "lint": "biome check src/ tests/",
18
+ "test": "vitest run",
19
+ "build": "tsc -p tsconfig.json",
20
+ "clean": "rm -rf dist tsconfig.tsbuildinfo",
21
+ "prepack": "pnpm run build"
22
+ },
23
+ "dependencies": {
24
+ "@voyantjs/core": "workspace:*",
25
+ "@voyantjs/catalog": "workspace:*",
26
+ "@voyantjs/catalog-mcp": "workspace:*",
27
+ "@voyantjs/db": "workspace:*",
28
+ "@voyantjs/hono": "workspace:*",
29
+ "drizzle-orm": "^0.45.2",
30
+ "hono": "^4.12.10",
31
+ "zod": "^4.3.6"
32
+ },
33
+ "devDependencies": {
34
+ "@voyantjs/voyant-typescript-config": "workspace:*",
35
+ "typescript": "^6.0.2",
36
+ "vitest": "^4.1.2"
37
+ },
38
+ "files": [
39
+ "dist"
40
+ ],
41
+ "publishConfig": {
42
+ "access": "public",
43
+ "exports": {
44
+ ".": {
45
+ "types": "./dist/index.d.ts",
46
+ "import": "./dist/index.js",
47
+ "default": "./dist/index.js"
48
+ },
49
+ "./schema": {
50
+ "types": "./dist/schema.d.ts",
51
+ "import": "./dist/schema.js",
52
+ "default": "./dist/schema.js"
53
+ },
54
+ "./validation": {
55
+ "types": "./dist/validation.d.ts",
56
+ "import": "./dist/validation.js",
57
+ "default": "./dist/validation.js"
58
+ },
59
+ "./service": {
60
+ "types": "./dist/service.d.ts",
61
+ "import": "./dist/service.js",
62
+ "default": "./dist/service.js"
63
+ },
64
+ "./mcp-tools": {
65
+ "types": "./dist/mcp-tools.d.ts",
66
+ "import": "./dist/mcp-tools.js",
67
+ "default": "./dist/mcp-tools.js"
68
+ },
69
+ "./cruise-extension": {
70
+ "types": "./dist/cruise-extension.d.ts",
71
+ "import": "./dist/cruise-extension.js",
72
+ "default": "./dist/cruise-extension.js"
73
+ },
74
+ "./routes": {
75
+ "types": "./dist/routes.d.ts",
76
+ "import": "./dist/routes.js",
77
+ "default": "./dist/routes.js"
78
+ }
79
+ },
80
+ "main": "./dist/index.js",
81
+ "types": "./dist/index.d.ts"
82
+ },
83
+ "repository": {
84
+ "type": "git",
85
+ "url": "https://github.com/voyantjs/voyant.git",
86
+ "directory": "packages/travel-composer"
87
+ }
88
+ }