@voyantjs/availability 0.52.0 → 0.52.1
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-allocation-automation.d.ts","sourceRoot":"","sources":["../src/service-allocation-automation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAQ5B,OAAO,EACL,KAAK,kBAAkB,EAIxB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,KAAK,yBAAyB,EAK/B,MAAM,yBAAyB,CAAA;AAChC,OAAO,KAAK,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"service-allocation-automation.d.ts","sourceRoot":"","sources":["../src/service-allocation-automation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAQ5B,OAAO,EACL,KAAK,kBAAkB,EAIxB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,KAAK,yBAAyB,EAK/B,MAAM,yBAAyB,CAAA;AAChC,OAAO,KAAK,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAA;AAe/F,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AACtF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAA;AAMlF,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,eAAe,EAAE,MAAM,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,8BAA8B;IAC7C,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,gBAAgB,EAAE,CAAA;CAC9B;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,kBAAkB,EAAE,CAAA;CACjC;AAED,wBAAsB,kCAAkC,CACtD,EAAE,EAAE,kBAAkB,EACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,8BAA8B,EAAE,CAAC,CAyC3C;AAED,wBAAsB,mCAAmC,CACvD,EAAE,EAAE,kBAAkB,EACtB,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,2BAA2B,GACjC,OAAO,CAAC,gBAAgB,CAAC,CA8C3B;AAED,wBAAsB,mCAAmC,CACvD,EAAE,EAAE,kBAAkB,EACtB,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,IAAI,EAAE,MAAM;;;UAeb;AAqBD,wBAAsB,kCAAkC,CACtD,EAAE,EAAE,kBAAkB,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,yBAAyB,EAChC,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,0BAA0B,CAAC,CA+GrC;AAED,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,kBAAkB,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,yBAAyB,EAChC,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,0BAA0B,CAAC,CAkDrC;AAED,MAAM,WAAW,4CAA4C;IAC3D;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,4CAA4C,CAChE,EAAE,EAAE,kBAAkB,EACtB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,4CAAiD,GACtD,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,kBAAkB,EAAE,CAAA;CAAE,CAAC,CA6D/D"}
|
|
@@ -2,6 +2,16 @@ import { and, eq, sql } from "drizzle-orm";
|
|
|
2
2
|
import { planRoomAllocation, planVehicleSeatAllocation, } from "./auto-allocator.js";
|
|
3
3
|
import { allocationResources, availabilitySlots, productOptionResourceTemplates, } from "./schema.js";
|
|
4
4
|
import { AllocationServiceError, getSlotAllocationManifest, recordAllocationAudit, } from "./service-allocation.js";
|
|
5
|
+
/**
|
|
6
|
+
* Emit `ARRAY[$1, $2, …]::text[]` so Postgres doesn't try to cast a
|
|
7
|
+
* tuple to `text[]`. See `sqlTextArray` in service-allocation.ts and
|
|
8
|
+
* issue #952.
|
|
9
|
+
*/
|
|
10
|
+
function sqlTextArray(values) {
|
|
11
|
+
if (values.length === 0)
|
|
12
|
+
return sql `ARRAY[]::text[]`;
|
|
13
|
+
return sql `ARRAY[${sql.join(values.map((value) => sql `${value}`), sql.raw(", "))}]::text[]`;
|
|
14
|
+
}
|
|
5
15
|
export async function listProductOptionResourceTemplates(db, productId) {
|
|
6
16
|
const optionRows = await executeRows(db, sql `
|
|
7
17
|
SELECT id, name, code, description, status, is_default, sort_order
|
|
@@ -15,7 +25,7 @@ export async function listProductOptionResourceTemplates(db, productId) {
|
|
|
15
25
|
const templateRows = await executeRows(db, sql `
|
|
16
26
|
SELECT id, product_option_id, kind, ref_type, ref_id, capacity, name_pattern, layout, default_count, flags, created_at, updated_at
|
|
17
27
|
FROM product_option_resource_templates
|
|
18
|
-
WHERE product_option_id = ANY(${optionIds}
|
|
28
|
+
WHERE product_option_id = ANY(${sqlTextArray(optionIds)})
|
|
19
29
|
ORDER BY kind, created_at
|
|
20
30
|
`);
|
|
21
31
|
const byOption = new Map();
|
|
@@ -231,7 +241,7 @@ export async function autoAllocateSlotResources(db, slotId, input, options = {})
|
|
|
231
241
|
SELECT
|
|
232
242
|
row.traveler_id,
|
|
233
243
|
jsonb_build_object(${kind}::text, row.resource_id::text)
|
|
234
|
-
FROM unnest(${travelerIds}
|
|
244
|
+
FROM unnest(${sqlTextArray(travelerIds)}, ${sqlTextArray(resourceIds)}) AS row(traveler_id, resource_id)
|
|
235
245
|
ON CONFLICT (traveler_id) DO UPDATE SET
|
|
236
246
|
allocations =
|
|
237
247
|
COALESCE(booking_traveler_travel_details.allocations, '{}'::jsonb)
|
|
@@ -143,7 +143,7 @@ export async function getSlotsResourceAvailability(db, slotIds) {
|
|
|
143
143
|
AND b.status IN ('draft', 'on_hold', 'confirmed', 'in_progress', 'completed')
|
|
144
144
|
AND ba.status IN ('held', 'confirmed', 'fulfilled')
|
|
145
145
|
) usage ON true
|
|
146
|
-
WHERE ar.slot_id = ANY(${uniqueIds}
|
|
146
|
+
WHERE ar.slot_id = ANY(${sqlTextArray(uniqueIds)})
|
|
147
147
|
ORDER BY ar.slot_id, ar.kind, ar.sort_order, ar.created_at
|
|
148
148
|
`);
|
|
149
149
|
const out = new Map();
|
|
@@ -206,7 +206,7 @@ export async function validateSlotAllocationCapacity(db, slotId, planned) {
|
|
|
206
206
|
const resources = await executeRows(db, sql `
|
|
207
207
|
SELECT id, kind, capacity, slot_id
|
|
208
208
|
FROM allocation_resources
|
|
209
|
-
WHERE slot_id = ${slotId} AND id = ANY(${resourceIds}
|
|
209
|
+
WHERE slot_id = ${slotId} AND id = ANY(${sqlTextArray(resourceIds)})
|
|
210
210
|
FOR UPDATE
|
|
211
211
|
`);
|
|
212
212
|
const resourceById = new Map(resources.map((r) => [r.id, r]));
|
|
@@ -246,7 +246,7 @@ export async function validateSlotAllocationCapacity(db, slotId, planned) {
|
|
|
246
246
|
AND ba.availability_slot_id = ${slotId}
|
|
247
247
|
AND b.status IN ('draft', 'on_hold', 'confirmed', 'in_progress', 'completed')
|
|
248
248
|
AND ba.status IN ('held', 'confirmed', 'fulfilled')
|
|
249
|
-
AND btd.traveler_id <> ALL(${travelerIdsArr}
|
|
249
|
+
AND btd.traveler_id <> ALL(${sqlTextArray(travelerIdsArr)})
|
|
250
250
|
`);
|
|
251
251
|
const existingAssigned = existingRows[0]?.count ?? 0;
|
|
252
252
|
const total = existingAssigned + plan.travelerIds.size;
|
|
@@ -462,7 +462,7 @@ export async function pairSharingGroup(db, slotId, input, options = {}) {
|
|
|
462
462
|
await db.execute(sql `
|
|
463
463
|
INSERT INTO booking_traveler_travel_details (traveler_id, sharing_group_id)
|
|
464
464
|
SELECT id, ${sharingGroupId}
|
|
465
|
-
FROM unnest(${input.travelerIds}
|
|
465
|
+
FROM unnest(${sqlTextArray(input.travelerIds)}) AS u(id)
|
|
466
466
|
ON CONFLICT (traveler_id) DO UPDATE SET
|
|
467
467
|
sharing_group_id = EXCLUDED.sharing_group_id,
|
|
468
468
|
updated_at = now()
|
|
@@ -642,13 +642,25 @@ async function loadSharingGroupLabelMap(db, groupIds) {
|
|
|
642
642
|
label: sharingGroupLabels.label,
|
|
643
643
|
})
|
|
644
644
|
.from(sharingGroupLabels)
|
|
645
|
-
.where(sql `${sharingGroupLabels.groupId} = ANY(${uniqueIds}
|
|
645
|
+
.where(sql `${sharingGroupLabels.groupId} = ANY(${sqlTextArray(uniqueIds)})`);
|
|
646
646
|
return Object.fromEntries(rows.map((row) => [row.groupId, row.label]));
|
|
647
647
|
}
|
|
648
648
|
async function executeRows(db, query) {
|
|
649
649
|
const rows = await db.execute(query);
|
|
650
650
|
return Array.isArray(rows) ? rows : [];
|
|
651
651
|
}
|
|
652
|
+
/**
|
|
653
|
+
* Emit a Postgres `ARRAY[$1, $2, …]::text[]` literal instead of the
|
|
654
|
+
* naive `${jsArray}::text[]` form. drizzle's `sql` template spreads
|
|
655
|
+
* JS arrays into a row constructor (`($1, $2)`) which Postgres
|
|
656
|
+
* refuses to cast to `text[]` — see issue #952. Empty input returns
|
|
657
|
+
* `ARRAY[]::text[]` which Postgres accepts.
|
|
658
|
+
*/
|
|
659
|
+
function sqlTextArray(values) {
|
|
660
|
+
if (values.length === 0)
|
|
661
|
+
return sql `ARRAY[]::text[]`;
|
|
662
|
+
return sql `ARRAY[${sql.join(values.map((value) => sql `${value}`), sql.raw(", "))}]::text[]`;
|
|
663
|
+
}
|
|
652
664
|
function serializeSlot(slot) {
|
|
653
665
|
return {
|
|
654
666
|
id: slot.id,
|
|
@@ -698,7 +710,7 @@ async function loadSlotTravelerRows(db, bookingIds) {
|
|
|
698
710
|
(btd.dietary_encrypted IS NOT NULL) AS has_dietary_requirements
|
|
699
711
|
FROM booking_travelers bt
|
|
700
712
|
LEFT JOIN booking_traveler_travel_details btd ON btd.traveler_id = bt.id
|
|
701
|
-
WHERE bt.booking_id = ANY(${bookingIds}
|
|
713
|
+
WHERE bt.booking_id = ANY(${sqlTextArray(bookingIds)})
|
|
702
714
|
ORDER BY bt.booking_id, bt.is_primary DESC, bt.created_at
|
|
703
715
|
`);
|
|
704
716
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyantjs/availability",
|
|
3
|
-
"version": "0.52.
|
|
3
|
+
"version": "0.52.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -44,13 +44,13 @@
|
|
|
44
44
|
"drizzle-orm": "^0.45.2",
|
|
45
45
|
"hono": "^4.12.10",
|
|
46
46
|
"zod": "^4.3.6",
|
|
47
|
-
"@voyantjs/core": "0.52.
|
|
48
|
-
"@voyantjs/db": "0.52.
|
|
49
|
-
"@voyantjs/hono": "0.52.
|
|
47
|
+
"@voyantjs/core": "0.52.1",
|
|
48
|
+
"@voyantjs/db": "0.52.1",
|
|
49
|
+
"@voyantjs/hono": "0.52.1"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"typescript": "^6.0.2",
|
|
53
|
-
"@voyantjs/products": "0.52.
|
|
53
|
+
"@voyantjs/products": "0.52.1",
|
|
54
54
|
"@voyantjs/voyant-typescript-config": "0.1.0"
|
|
55
55
|
},
|
|
56
56
|
"files": [
|