@voyantjs/hospitality 0.32.3 → 0.34.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.
- package/dist/catalog-policy.d.ts.map +1 -1
- package/dist/catalog-policy.js +14 -0
- package/dist/routes-accommodation.d.ts +1 -1
- package/dist/routes-operations.d.ts +1 -1
- package/dist/routes-stays.d.ts +1 -1
- package/dist/routes.d.ts +2 -2
- package/dist/service-catalog-plane.d.ts.map +1 -1
- package/dist/service-catalog-plane.js +65 -3
- package/dist/service.d.ts +2 -2
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-policy.d.ts","sourceRoot":"","sources":["../src/catalog-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAErF,QAAA,MAAM,wBAAwB,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"catalog-policy.d.ts","sourceRoot":"","sources":["../src/catalog-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAErF,QAAA,MAAM,wBAAwB,EAAE,gBAAgB,EAsZ/C,CAAA;AAED,eAAO,MAAM,wBAAwB,2CAA8C,CAAA;AAEnF,OAAO,EAAE,wBAAwB,EAAE,CAAA"}
|
package/dist/catalog-policy.js
CHANGED
|
@@ -191,6 +191,20 @@ const HOSPITALITY_FIELD_POLICY = [
|
|
|
191
191
|
overrideFriction: "confirm",
|
|
192
192
|
sourceFreshness: "sync",
|
|
193
193
|
},
|
|
194
|
+
{
|
|
195
|
+
path: "thumbnailUrl",
|
|
196
|
+
class: "merchandisable",
|
|
197
|
+
merge: "source-only",
|
|
198
|
+
drift: "low",
|
|
199
|
+
reindex: "entry",
|
|
200
|
+
snapshot: "on-book",
|
|
201
|
+
query: "indexed-column",
|
|
202
|
+
localized: false,
|
|
203
|
+
visibility: ["staff", "customer", "partner"],
|
|
204
|
+
editRole: "none",
|
|
205
|
+
overrideFriction: "none",
|
|
206
|
+
sourceFreshness: "sync",
|
|
207
|
+
},
|
|
194
208
|
// ── Structural / facet-affecting ───────────────────────────────────────
|
|
195
209
|
{
|
|
196
210
|
path: "inventoryMode",
|
|
@@ -931,9 +931,9 @@ export declare const hospitalityAccommodationRoutes: import("hono/hono-base").Ho
|
|
|
931
931
|
active: boolean;
|
|
932
932
|
sortOrder: number;
|
|
933
933
|
ratePlanId: string;
|
|
934
|
+
roomTypeId: string;
|
|
934
935
|
productId: string | null;
|
|
935
936
|
optionId: string | null;
|
|
936
|
-
roomTypeId: string;
|
|
937
937
|
unitId: string | null;
|
|
938
938
|
} | null;
|
|
939
939
|
};
|
|
@@ -1230,8 +1230,8 @@ export declare const hospitalityOperationsRoutes: import("hono/hono-base").HonoB
|
|
|
1230
1230
|
} | null;
|
|
1231
1231
|
notes: string | null;
|
|
1232
1232
|
ratePlanId: string;
|
|
1233
|
-
bookingItemId: string;
|
|
1234
1233
|
roomTypeId: string;
|
|
1234
|
+
bookingItemId: string;
|
|
1235
1235
|
mealPlanId: string | null;
|
|
1236
1236
|
roomUnitId: string | null;
|
|
1237
1237
|
checkInDate: string;
|
package/dist/routes-stays.d.ts
CHANGED
|
@@ -252,8 +252,8 @@ export declare const hospitalityStayRoutes: import("hono/hono-base").HonoBase<En
|
|
|
252
252
|
} | null;
|
|
253
253
|
notes: string | null;
|
|
254
254
|
ratePlanId: string;
|
|
255
|
-
bookingItemId: string;
|
|
256
255
|
roomTypeId: string;
|
|
256
|
+
bookingItemId: string;
|
|
257
257
|
mealPlanId: string | null;
|
|
258
258
|
roomUnitId: string | null;
|
|
259
259
|
checkInDate: string;
|
package/dist/routes.d.ts
CHANGED
|
@@ -931,9 +931,9 @@ export declare const hospitalityRoutes: import("hono/hono-base").HonoBase<Env, i
|
|
|
931
931
|
active: boolean;
|
|
932
932
|
sortOrder: number;
|
|
933
933
|
ratePlanId: string;
|
|
934
|
+
roomTypeId: string;
|
|
934
935
|
productId: string | null;
|
|
935
936
|
optionId: string | null;
|
|
936
|
-
roomTypeId: string;
|
|
937
937
|
unitId: string | null;
|
|
938
938
|
} | null;
|
|
939
939
|
};
|
|
@@ -2431,8 +2431,8 @@ export declare const hospitalityRoutes: import("hono/hono-base").HonoBase<Env, i
|
|
|
2431
2431
|
} | null;
|
|
2432
2432
|
notes: string | null;
|
|
2433
2433
|
ratePlanId: string;
|
|
2434
|
-
bookingItemId: string;
|
|
2435
2434
|
roomTypeId: string;
|
|
2435
|
+
bookingItemId: string;
|
|
2436
2436
|
mealPlanId: string | null;
|
|
2437
2437
|
roomUnitId: string | null;
|
|
2438
2438
|
checkInDate: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-catalog-plane.d.ts","sourceRoot":"","sources":["../src/service-catalog-plane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAGL,KAAK,oBAAoB,EAEzB,KAAK,eAAe,EACpB,KAAK,eAAe,EAEpB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,aAAa,EAEnB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAIhD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"service-catalog-plane.d.ts","sourceRoot":"","sources":["../src/service-catalog-plane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAGL,KAAK,oBAAoB,EAEzB,KAAK,eAAe,EACpB,KAAK,eAAe,EAEpB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,aAAa,EAEnB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAIhD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAcjD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,OAAO,SAAS,CAAC,YAAY,EAClC,OAAO,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7E,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CA4C9B;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,OAAO,SAAS,CAAC,YAAY,EACnC,OAAO,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7E,UAAU,CAMZ;AAED,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,EAAE,MAAM,CAAA;IACxB,KAAK,EAAE,aAAa,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,YAAY,EAChB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAkB9B;AAED,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE,aAAa,CAAC,OAAO,SAAS,CAAC,YAAY,CAAC,EAClD,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,YAAY,EAAE,CAAC,CAoBzB;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,EAAE,EAAE,YAAY,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,sBAAsB,GAAG;IAAE,YAAY,CAAC,EAAE,YAAY,CAAA;CAAE,GAChE,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,WAAW,CAAC,GAAG,IAAI,CAAC,CAUzD;AAMD,wBAAgB,6BAA6B,CAAC,OAAO,EAAE;IACrD,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GAAG,eAAe,CAAC,OAAO,SAAS,CAAC,YAAY,CAAC,CAajD;AAED,wBAAgB,6BAA6B,CAC3C,EAAE,EAAE,YAAY,EAChB,OAAO,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7E,eAAe,CAmBjB;AA0ED,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,aAAa,GACd,CAAA"}
|
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
* See `docs/architecture/catalog-architecture.md` §9.1.
|
|
11
11
|
*/
|
|
12
12
|
import { buildIndexerDocument, buildSnapshotInputFromView, createFieldPolicyRegistry, resolveEntityView, } from "@voyantjs/catalog";
|
|
13
|
-
import { eq } from "drizzle-orm";
|
|
13
|
+
import { and, eq } from "drizzle-orm";
|
|
14
14
|
import { hospitalityCatalogPolicy } from "./catalog-policy.js";
|
|
15
15
|
import { roomTypes } from "./schema-inventory.js";
|
|
16
|
+
import { HOSPITALITY_CONTENT_MARKET_ANY, hospitalitySourcedContentTable, } from "./schema-sourced-content.js";
|
|
16
17
|
let _registry;
|
|
17
18
|
function getHospitalityRegistry() {
|
|
18
19
|
if (!_registry) {
|
|
@@ -43,6 +44,7 @@ export function roomTypeRowToProjection(row, context) {
|
|
|
43
44
|
["name", row.name],
|
|
44
45
|
["description", row.description],
|
|
45
46
|
["accessibilityNotes", row.accessibilityNotes],
|
|
47
|
+
["thumbnailUrl", pickThumbnailUrl(row.metadata)],
|
|
46
48
|
// Structural / facets
|
|
47
49
|
["inventoryMode", row.inventoryMode],
|
|
48
50
|
["roomClass", row.roomClass],
|
|
@@ -130,12 +132,72 @@ export function createRoomTypeDocumentEmitter(context) {
|
|
|
130
132
|
};
|
|
131
133
|
}
|
|
132
134
|
export function createRoomTypeDocumentBuilder(db, context) {
|
|
133
|
-
const
|
|
135
|
+
const registry = getHospitalityRegistry();
|
|
134
136
|
return async (entityId, slice) => {
|
|
135
137
|
const rows = await db.select().from(roomTypes).where(eq(roomTypes.id, entityId)).limit(1);
|
|
136
138
|
const row = rows[0];
|
|
137
139
|
if (!row)
|
|
138
140
|
return null;
|
|
139
|
-
|
|
141
|
+
const projection = new Map(roomTypeRowToProjection(row, {
|
|
142
|
+
sellerOperatorId: context.sellerOperatorId,
|
|
143
|
+
sourceKind: context.sourceKind,
|
|
144
|
+
sourceRef: context.sourceRef,
|
|
145
|
+
}));
|
|
146
|
+
const sourcedThumbnailUrl = await fetchSourcedContentThumbnailUrl(db, entityId, slice);
|
|
147
|
+
if (sourcedThumbnailUrl) {
|
|
148
|
+
projection.set("thumbnailUrl", sourcedThumbnailUrl);
|
|
149
|
+
}
|
|
150
|
+
return buildIndexerDocument(registry, projection, slice, entityId);
|
|
140
151
|
};
|
|
141
152
|
}
|
|
153
|
+
async function fetchSourcedContentThumbnailUrl(db, entityId, slice) {
|
|
154
|
+
const rows = await db
|
|
155
|
+
.select({
|
|
156
|
+
market: hospitalitySourcedContentTable.market,
|
|
157
|
+
payload: hospitalitySourcedContentTable.payload,
|
|
158
|
+
})
|
|
159
|
+
.from(hospitalitySourcedContentTable)
|
|
160
|
+
.where(and(eq(hospitalitySourcedContentTable.entity_id, entityId), eq(hospitalitySourcedContentTable.locale, slice.locale)));
|
|
161
|
+
const row = rows.find((candidate) => candidate.market === slice.market) ??
|
|
162
|
+
rows.find((candidate) => candidate.market === HOSPITALITY_CONTENT_MARKET_ANY) ??
|
|
163
|
+
rows[0];
|
|
164
|
+
return pickThumbnailUrl(row?.payload);
|
|
165
|
+
}
|
|
166
|
+
function pickThumbnailUrl(value) {
|
|
167
|
+
const record = asRecord(value);
|
|
168
|
+
if (!record)
|
|
169
|
+
return null;
|
|
170
|
+
return (firstString(record.thumbnailUrl, record.heroImageUrl, record.hero_image_url, record.imageUrl, record.image_url) ??
|
|
171
|
+
firstMediaUrl(record.media) ??
|
|
172
|
+
firstStringFromArray(record.images) ??
|
|
173
|
+
firstStringFromArray(record.galleryUrls));
|
|
174
|
+
}
|
|
175
|
+
function firstMediaUrl(value) {
|
|
176
|
+
if (!Array.isArray(value))
|
|
177
|
+
return null;
|
|
178
|
+
for (const item of value) {
|
|
179
|
+
const media = asRecord(item);
|
|
180
|
+
if (!media)
|
|
181
|
+
continue;
|
|
182
|
+
const type = typeof media.type === "string" ? media.type : null;
|
|
183
|
+
if (type && type !== "image")
|
|
184
|
+
continue;
|
|
185
|
+
const url = firstString(media.url, media.src);
|
|
186
|
+
if (url)
|
|
187
|
+
return url;
|
|
188
|
+
}
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
function firstStringFromArray(value) {
|
|
192
|
+
if (!Array.isArray(value))
|
|
193
|
+
return null;
|
|
194
|
+
return value.find((item) => typeof item === "string" && item.length > 0) ?? null;
|
|
195
|
+
}
|
|
196
|
+
function firstString(...values) {
|
|
197
|
+
return (values.find((value) => typeof value === "string" && value.length > 0) ?? null);
|
|
198
|
+
}
|
|
199
|
+
function asRecord(value) {
|
|
200
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
201
|
+
? value
|
|
202
|
+
: null;
|
|
203
|
+
}
|
package/dist/service.d.ts
CHANGED
|
@@ -682,9 +682,9 @@ export declare const hospitalityService: {
|
|
|
682
682
|
active: boolean;
|
|
683
683
|
sortOrder: number;
|
|
684
684
|
ratePlanId: string;
|
|
685
|
+
roomTypeId: string;
|
|
685
686
|
productId: string | null;
|
|
686
687
|
optionId: string | null;
|
|
687
|
-
roomTypeId: string;
|
|
688
688
|
unitId: string | null;
|
|
689
689
|
} | null>;
|
|
690
690
|
updateRatePlanRoomType(db: PostgresJsDatabase, id: string, data: UpdateRatePlanRoomTypeInput): Promise<{
|
|
@@ -1066,8 +1066,8 @@ export declare const hospitalityService: {
|
|
|
1066
1066
|
metadata: Record<string, unknown> | null;
|
|
1067
1067
|
notes: string | null;
|
|
1068
1068
|
ratePlanId: string;
|
|
1069
|
-
bookingItemId: string;
|
|
1070
1069
|
roomTypeId: string;
|
|
1070
|
+
bookingItemId: string;
|
|
1071
1071
|
mealPlanId: string | null;
|
|
1072
1072
|
roomUnitId: string | null;
|
|
1073
1073
|
checkInDate: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyantjs/hospitality",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -64,16 +64,16 @@
|
|
|
64
64
|
"drizzle-orm": "^0.45.2",
|
|
65
65
|
"hono": "^4.12.10",
|
|
66
66
|
"zod": "^4.3.6",
|
|
67
|
-
"@voyantjs/bookings": "0.
|
|
68
|
-
"@voyantjs/core": "0.
|
|
69
|
-
"@voyantjs/db": "0.
|
|
70
|
-
"@voyantjs/facilities": "0.
|
|
71
|
-
"@voyantjs/hono": "0.
|
|
72
|
-
"@voyantjs/catalog": "0.
|
|
67
|
+
"@voyantjs/bookings": "0.34.0",
|
|
68
|
+
"@voyantjs/core": "0.34.0",
|
|
69
|
+
"@voyantjs/db": "0.34.0",
|
|
70
|
+
"@voyantjs/facilities": "0.34.0",
|
|
71
|
+
"@voyantjs/hono": "0.34.0",
|
|
72
|
+
"@voyantjs/catalog": "0.34.0"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"typescript": "^6.0.2",
|
|
76
|
-
"@voyantjs/pricing": "0.
|
|
76
|
+
"@voyantjs/pricing": "0.34.0",
|
|
77
77
|
"@voyantjs/voyant-typescript-config": "0.1.0"
|
|
78
78
|
},
|
|
79
79
|
"files": [
|