tripstorekrabi-shared 1.25.8 → 1.25.9

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 (2) hide show
  1. package/package.json +1 -1
  2. package/product.js +72 -28
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tripstorekrabi-shared",
3
- "version": "1.25.8",
3
+ "version": "1.25.9",
4
4
  "description": "Shared library for Trip Store Krabi",
5
5
  "author": "Stefan Sommer <tonprince@gmail.com>",
6
6
  "repository": {
package/product.js CHANGED
@@ -2,55 +2,99 @@ import { calculateProductSellingPrice, countMinPeople } from "./price.js";
2
2
 
3
3
  const MATCH_HTML_REGEXP = /(<([^>]+)>)/ig;
4
4
 
5
+ function toIsoDateString(val) {
6
+ if (!val) return null;
7
+ if (typeof val.toDate === 'function') return val.toDate().toISOString();
8
+ if (val instanceof Date) return val.toISOString();
9
+ if (typeof val === 'string') return val;
10
+ return null;
11
+ }
12
+
13
+ function stripHTML(html) {
14
+ if (!html) return '';
15
+ return String(html).replace(MATCH_HTML_REGEXP, '');
16
+ }
17
+
5
18
  export function buildIndex(id, product) {
6
- const lightweightRevisions = (product.pricing?.revisions || []).map(rev => ({
19
+ if (!product) return null;
20
+
21
+ const lightweightRevisions = (product.pricing?.revisions || []).map((rev) => ({
7
22
  id: rev.id,
8
- startDate: rev.startDate.toDate(),
9
- promotion: rev.promotion ? {
10
- startDate: rev.promotion.startDate.toDate(),
11
- endDate: rev.promotion.endDate.toDate()
12
- } : null
23
+ startDate: toIsoDateString(rev.startDate),
24
+ promotion: rev.promotion
25
+ ? {
26
+ startDate: toIsoDateString(rev.promotion.startDate),
27
+ endDate: toIsoDateString(rev.promotion.endDate)
28
+ }
29
+ : null
13
30
  }));
14
31
 
32
+ const minPeople = countMinPeople(product.pricing);
33
+ const rawPrice =
34
+ minPeople > 0
35
+ ? calculateProductSellingPrice(
36
+ { adults: minPeople, children: 0, infants: 0 },
37
+ product.pricing
38
+ ) / minPeople
39
+ : 0;
40
+
41
+ const safeIntPrice = isNaN(rawPrice) || !isFinite(rawPrice) ? 0 : Math.round(rawPrice);
42
+
15
43
  let document = {
16
44
  id,
17
- title: product.title,
18
- subtitle: product.subtitle,
19
- summary: product.summary,
20
- description: product.description.map((item) => stripHTML(item)).join(" "),
21
- heroPhoto: product.heroPhoto,
22
- operator: product.operator.default.name,
23
- url: product.url,
24
- price: calculateProductSellingPrice({ adults: countMinPeople(product.pricing), children: 0, infants: 0 }, product.pricing) / countMinPeople(product.pricing),
25
- priceType: product.pricing.type,
26
- availability: product.availability,
27
- live: product.live,
45
+ title: String(product.title || '').trim(),
46
+ subtitle: String(product.subtitle || '').trim(),
47
+ summary: String(product.summary || '').trim(),
48
+ description: Array.isArray(product.description)
49
+ ? product.description.map((item) => stripHTML(item)).join(' ')
50
+ : stripHTML(product.description || ''),
51
+ heroPhoto: product.heroPhoto || '',
52
+ operator: String(
53
+ product.operator?.default?.name || product.operator?.name || product.operator || 'General'
54
+ ).trim(),
55
+ url: product.url || '',
56
+ price: safeIntPrice,
57
+ priceType: product.pricing?.type || 'per_person',
58
+ availability: product.availability || 'available',
59
+ live: Boolean(product.live),
60
+ totalPassengers: Math.max(0, Math.round(Number(product.totalPassengers || 0))),
28
61
  revisions: JSON.stringify(lightweightRevisions)
29
62
  };
30
63
 
31
64
  if (product.shortName) {
32
- document.shortName = product.shortName;
65
+ document.shortName = String(product.shortName).trim();
33
66
  }
34
67
 
35
- if (product.destinations) {
68
+ if (Array.isArray(product.destinations) && product.destinations.length > 0) {
36
69
  document.destinations = product.destinations;
70
+ } else if (product.destination) {
71
+ document.destinations = [product.destination];
37
72
  }
38
- if (product.tags) {
73
+
74
+ if (Array.isArray(product.tags)) {
39
75
  document.tags = product.tags;
76
+ } else {
77
+ document.tags = [];
40
78
  }
41
79
 
42
80
  if (product.from && product.to) {
43
81
  document.from = product.from;
44
- document.to = product.to
45
- document.start = [product.waypoints[0].latLng.lat, product.waypoints[0].latLng.lng];
46
- document.end = [product.waypoints[product.waypoints.length - 1].latLng.lat, product.waypoints[product.waypoints.length - 1].latLng.lng];
82
+ document.to = product.to;
83
+
84
+ if (Array.isArray(product.waypoints) && product.waypoints.length > 0) {
85
+ const startWp = product.waypoints[0]?.latLng;
86
+ const endWp = product.waypoints[product.waypoints.length - 1]?.latLng;
87
+
88
+ if (startWp && typeof startWp.lat === 'number' && typeof startWp.lng === 'number') {
89
+ document.start = [startWp.lat, startWp.lng];
90
+ }
91
+ if (endWp && typeof endWp.lat === 'number' && typeof endWp.lng === 'number') {
92
+ document.end = [endWp.lat, endWp.lng];
93
+ }
94
+ }
47
95
  }
48
96
 
49
- document.type = product.from ? "transfer" : "activity";
97
+ document.type = product.from ? 'transfer' : 'activity';
50
98
 
51
99
  return document;
52
- }
53
-
54
- function stripHTML(html) {
55
- return html.replace(MATCH_HTML_REGEXP, "");
56
100
  }