store-scrapper-js-common 1.0.200 → 1.0.201

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.
@@ -0,0 +1,7 @@
1
+ export declare const categoriesEnEsMap: {
2
+ [key: string]: string;
3
+ };
4
+ export declare const getCategoryFacetLabel: ({ key, lang }: {
5
+ key: string;
6
+ lang?: string;
7
+ }) => string | null;
@@ -0,0 +1,273 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCategoryFacetLabel = exports.categoriesEnEsMap = void 0;
4
+ exports.categoriesEnEsMap = {
5
+ grocery: 'Supermercado',
6
+ 'grocery/coffee': 'Café',
7
+ 'grocery/cooking oils': 'Aceites para cocinar',
8
+ 'grocery/beverages': 'Bebestibles',
9
+ 'grocery/dairy and eggs': 'Lácteos y huevos',
10
+ 'grocery/breakfast and cereal': 'Desayuno y cereales',
11
+ 'grocery/bakery and bread': 'Panadería y pan',
12
+ 'grocery/baking': 'Repostería',
13
+ 'grocery/snacks': 'Snacks',
14
+ 'grocery/fresh produce': 'Frutas y verduras frescas',
15
+ 'grocery/frozen': 'Congelados',
16
+ 'grocery/pantry': 'Despensa',
17
+ 'grocery/desserts': 'Postres',
18
+ 'grocery/spreads': 'Untables',
19
+ 'grocery/condiments and sauces': 'Condimentos y salsas',
20
+ 'grocery/salt': 'Sal',
21
+ 'grocery/sugars and sweeteners': 'Azúcares y edulcorantes',
22
+ 'grocery/candy': 'Dulces',
23
+ 'grocery/grains and pasta': 'Granos y pasta',
24
+ 'grocery/specialty foods': 'Alimentos especiales',
25
+ 'grocery/meat': 'Carnes',
26
+ 'grocery/seafood': 'Mariscos',
27
+ 'grocery/canned goods': 'Conservas',
28
+ 'grocery/soups': 'Sopas',
29
+ 'grocery/deli': 'Charcutería',
30
+ pharmacy: 'Farmacia',
31
+ 'pharmacy/diet and nutrition': 'Dieta y nutrición',
32
+ 'pharmacy/senior health': 'Salud para adultos mayores',
33
+ 'pharmacy/hygiene': 'Higiene',
34
+ 'pharmacy/medications and treatments': 'Medicamentos y tratamientos',
35
+ 'pharmacy/personal care': 'Cuidado personal',
36
+ 'pharmacy/skin care': 'Cuidado de la piel',
37
+ 'pharmacy/face care': 'Cuidado facial',
38
+ 'pharmacy/foot care': 'Cuidado de los pies',
39
+ 'pharmacy/hair care': 'Cuidado del cabello',
40
+ 'pharmacy/oral care': 'Cuidado bucal',
41
+ 'pharmacy/hand and nail care': 'Cuidado de manos y uñas',
42
+ 'pharmacy/eye care': 'Cuidado de los ojos',
43
+ 'pharmacy/health and wellness': 'Salud y bienestar',
44
+ electronics: 'Electrónica',
45
+ 'electronics/gps and navigation': 'GPS y navegación',
46
+ 'electronics/electronics components': 'Componentes electrónicos',
47
+ 'electronics/diy electronics': 'Electrónica DIY',
48
+ 'electronics/electronics kits': 'Kits electrónicos',
49
+ 'electronics/cryptocurrency': 'Criptomonedas',
50
+ 'electronics/drones': 'Drones',
51
+ 'electronics/vr devices': 'Dispositivos de realidad virtual',
52
+ 'electronics/power supplies': 'Fuentes de alimentación',
53
+ 'electronics/networking': 'Redes',
54
+ 'electronics/portable fans': 'Ventiladores portátiles',
55
+ 'electronics/remote controls': 'Controles remotos',
56
+ 'electronics/universal remotes': 'Controles remotos universales',
57
+ 'electronics/smart home': 'Hogar inteligente',
58
+ 'electronics/telephones': 'Teléfonos',
59
+ 'electronics/mobile phones': 'Teléfonos móviles',
60
+ 'electronics/photography': 'Fotografía',
61
+ 'electronics/wearable technology': 'Tecnología vestible',
62
+ 'electronics/computers': 'Computadoras',
63
+ 'electronics/data storage': 'Almacenamiento de datos',
64
+ 'electronics/scanners': 'Escáneres',
65
+ 'electronics/printers': 'Impresoras',
66
+ 'electronics/video games': 'Videojuegos',
67
+ 'electronics/televisions': 'Televisores',
68
+ 'electronics/audio': 'Audio',
69
+ 'electronics/projectors': 'Proyectores',
70
+ 'electronics/outdoor electronics and gadgets': 'Electrónica y gadgets para exteriores',
71
+ appliances: 'Electrodomésticos',
72
+ 'appliances/appliance parts': 'Repuestos de electrodomésticos',
73
+ 'appliances/consumer electronics': 'Electrónica de consumo',
74
+ 'appliances/small appliances': 'Electrodomésticos pequeños',
75
+ 'appliances/specialty appliances': 'Electrodomésticos especiales',
76
+ 'appliances/kitchen appliances': 'Electrodomésticos de cocina',
77
+ 'appliances/heaters': 'Calefactores',
78
+ 'appliances/white goods': 'Línea blanca',
79
+ 'appliances/cooling appliances': 'Electrodomésticos de refrigeración',
80
+ 'appliances/cleaning appliances': 'Electrodomésticos de limpieza',
81
+ 'appliances/personal care appliances': 'Electrodomésticos de cuidado personal',
82
+ beauty: 'Belleza',
83
+ 'beauty/sun care and tanning': 'Cuidado solar y bronceado',
84
+ 'beauty/fragrance': 'Fragancias',
85
+ 'beauty/skin care': 'Cuidado de la piel',
86
+ 'beauty/face care': 'Cuidado facial',
87
+ 'beauty/eye care': 'Cuidado de los ojos',
88
+ 'beauty/foot care': 'Cuidado de los pies',
89
+ 'beauty/hair care': 'Cuidado del cabello',
90
+ 'beauty/bath and body': 'Baño y cuerpo',
91
+ 'beauty/hand and nail care': 'Cuidado de manos y uñas',
92
+ 'beauty/oral care': 'Cuidado bucal',
93
+ 'beauty/makeup': 'Maquillaje',
94
+ 'beauty/shaving and grooming': 'Afeitado y aseo personal',
95
+ fashion: 'Moda',
96
+ 'fashion/fashion accessories': 'Accesorios de moda',
97
+ 'fashion/eyewear': 'Gafas',
98
+ 'fashion/clothing': 'Ropa',
99
+ 'fashion/shoes': 'Calzado',
100
+ sports: 'Deportes',
101
+ 'sports/water sports': 'Deportes acuáticos',
102
+ 'sports/winter sports': 'Deportes de invierno',
103
+ 'sports/outdoor sports': 'Deportes al aire libre',
104
+ 'sports/table tennis': 'Tenis de mesa',
105
+ 'sports/tennis': 'Tenis',
106
+ 'sports/padel': 'Pádel',
107
+ 'sports/basketball': 'Baloncesto',
108
+ 'sports/soccer': 'Fútbol',
109
+ 'sports/scooters': 'Patinetes',
110
+ 'sports/roller skates': 'Patines',
111
+ 'sports/inline skates': 'Patines en línea',
112
+ 'sports/skateboarding': 'Skateboarding',
113
+ 'sports/bowling': 'Bolos',
114
+ 'sports/handball': 'Balonmano',
115
+ 'sports/martial arts': 'Artes marciales',
116
+ 'sports/boxing': 'Boxeo',
117
+ 'sports/cycling': 'Ciclismo',
118
+ 'sports/fitness': 'Fitness',
119
+ 'sports/camping and hiking': 'Camping y senderismo',
120
+ home: 'Hogar',
121
+ 'home/home decor': 'Decoración del hogar',
122
+ 'home/home improvement': 'Mejoras para el hogar',
123
+ 'home/furniture': 'Muebles',
124
+ 'home/bedroom': 'Dormitorio',
125
+ 'home/household supplies': 'Artículos para el hogar',
126
+ 'home/luggage and travel': 'Equipaje y viajes',
127
+ 'home/bathroom': 'Baño',
128
+ 'home/laundry': 'Lavandería',
129
+ 'home/kitchen': 'Cocina',
130
+ 'home/patio and garden': 'Patio y jardín',
131
+ outdoor: 'Exterior',
132
+ 'outdoor/camping and hiking': 'Camping y senderismo',
133
+ 'outdoor/outdoor clothing': 'Ropa para exteriores',
134
+ 'outdoor/outdoor electronics and gadgets': 'Electrónica y gadgets para exteriores',
135
+ 'outdoor/outdoor sports': 'Deportes al aire libre',
136
+ 'outdoor/outdoor lighting': 'Iluminación exterior',
137
+ 'outdoor/outdoor heating': 'Calefacción exterior',
138
+ 'outdoor/swimming pools': 'Piscinas',
139
+ 'outdoor/outdoor furniture': 'Muebles de exterior',
140
+ 'outdoor/awnings and canopies': 'Toldos y marquesinas',
141
+ music: 'Música',
142
+ 'music/vinyl': 'Vinilos',
143
+ 'music/microphones': 'Micrófonos',
144
+ 'music/musical instruments': 'Instrumentos musicales',
145
+ books: 'Libros',
146
+ 'books/user guides and manuals': 'Guías de usuario y manuales',
147
+ 'books/technology books': 'Libros de tecnología',
148
+ 'books/spiritual books': 'Libros espirituales',
149
+ "books/children's books": 'Libros infantiles',
150
+ 'books/non-fiction books': 'Libros de no ficción',
151
+ 'books/fiction books': 'Libros de ficción',
152
+ 'books/academic books': 'Libros académicos',
153
+ 'books/specialty books': 'Libros especializados',
154
+ 'books/crime and thriller books': 'Libros de crimen y suspense',
155
+ 'books/horror books': 'Libros de terror',
156
+ 'books/comedy books': 'Libros de comedia',
157
+ 'books/romance books': 'Libros de romance',
158
+ 'books/reference books': 'Libros de referencia',
159
+ 'books/textbooks': 'Libros de texto',
160
+ 'books/study guides': 'Guías de estudio',
161
+ 'books/educational magazines': 'Revistas educativas',
162
+ 'books/history books': 'Libros de historia',
163
+ 'books/self-help books': 'Libros de autoayuda',
164
+ 'books/politics books': 'Libros de política',
165
+ 'books/health and wellness books': 'Libros de salud y bienestar',
166
+ 'books/business and economics books': 'Libros de negocios y economía',
167
+ 'books/comics and graphics novels': 'Cómics y novelas gráficas',
168
+ 'books/book accessories': 'Accesorios para libros',
169
+ kids: 'Niños',
170
+ 'kids/kids clothing': 'Ropa infantil',
171
+ 'kids/kids shoes': 'Calzado infantil',
172
+ 'kids/kids accessories': 'Accesorios infantiles',
173
+ 'kids/toys and games': 'Juguetes y juegos',
174
+ 'kids/party decorations': 'Decoraciones para fiestas infantiles',
175
+ 'kids/party supplies': 'Artículos para fiestas infantiles',
176
+ 'kids/school': 'Escuela',
177
+ 'kids/baby': 'Bebé',
178
+ pets: 'Mascotas',
179
+ 'pets/pet supplies': 'Artículos para mascotas',
180
+ 'pets/pet care': 'Cuidado de mascotas',
181
+ 'pets/pet accessories': 'Accesorios para mascotas',
182
+ 'pets/pet toys': 'Juguetes para mascotas',
183
+ 'pets/pet furniture': 'Muebles para mascotas',
184
+ 'pets/aquariums': 'Acuarios',
185
+ 'pets/pet habitats and pet cages': 'Hábitats y jaulas para mascotas',
186
+ office: 'Oficina',
187
+ 'office/office technology': 'Tecnología de oficina',
188
+ 'office/office lighting': 'Iluminación de oficina',
189
+ 'office/office decor': 'Decoración de oficina',
190
+ 'office/office furniture': 'Muebles de oficina',
191
+ 'office/office cleaning and office maintenance': 'Mantenimiento de oficina',
192
+ 'office/office meeting and presentation': 'Reuniones y presentaciones de oficina',
193
+ 'office/safety and security': 'Seguridad de oficina',
194
+ 'office/office supplies': 'Artículos de oficina',
195
+ 'office/office breakroom': 'Sala de descanso de oficina',
196
+ automotive: 'Automotriz',
197
+ 'automotive/vehicles': 'Vehículos',
198
+ 'party and entertainment': 'Fiestas y entretenimiento',
199
+ 'party and entertainment/party supplies': 'Artículos para fiestas',
200
+ 'party and entertainment/entertainment supplies': 'Artículos de entretenimiento',
201
+ 'party and entertainment/party electronics': 'Electrónica para fiestas',
202
+ 'party and entertainment/party planning': 'Planificación de fiestas',
203
+ services: 'Servicios',
204
+ 'services/installation and maintenance services': 'Servicios de instalación y mantenimiento',
205
+ 'services/warranties and protection plans': 'Garantías y planes de protección',
206
+ 'services/travel services': 'Servicios de viajes',
207
+ 'grocery/beverages/alcoholic beverages': 'Bebidas alcohólicas',
208
+ 'grocery/beverages/alcoholic beverages/beer': 'Cervezas',
209
+ 'grocery/beverages/alcoholic beverages/wine': 'Vinos',
210
+ 'grocery/beverages/alcoholic beverages/sparkling wine': 'Espumantes',
211
+ 'grocery/beverages/alcoholic beverages/whisky': 'Whisky',
212
+ 'grocery/beverages/alcoholic beverages/vodka': 'Vodka',
213
+ 'grocery/beverages/alcoholic beverages/gin': 'Gin',
214
+ 'grocery/beverages/alcoholic beverages/tequila': 'Tequila',
215
+ 'grocery/beverages/alcoholic beverages/cognac': 'Cognac',
216
+ 'grocery/beverages/alcoholic beverages/rum': 'Ron',
217
+ 'grocery/beverages/alcoholic beverages/brandy': 'Brandy',
218
+ 'grocery/beverages/alcoholic beverages/cocktails': 'Cocktails',
219
+ 'grocery/beverages/alcoholic beverages/cider': 'Sidra',
220
+ 'grocery/beverages/alcoholic beverages/pisco': 'Pisco',
221
+ 'grocery/beverages/alcoholic beverages/liqueurs': 'Licores',
222
+ 'electronics/video games/nintendo': 'Nintendo',
223
+ 'electronics/video games/xbox': 'Xbox',
224
+ 'electronics/video games/playstation': 'Playstation',
225
+ 'home/kitchen/kitchen appliances/coffee machines': 'Cafeteras',
226
+ 'appliances/white goods/refrigeration appliances/refrigerators': 'Refrigeradores',
227
+ 'appliances/white goods/refrigeration appliances/freezers': 'Congeladores',
228
+ 'appliances/white goods/dishwashing appliances/dishwashers': 'Lavavajillas',
229
+ 'home/laundry/laundry appliances/washing machines': 'Lavadoras',
230
+ 'home/laundry/laundry appliances/dryers machines': 'Secadoras',
231
+ 'home/laundry/laundry appliances/washer-dryer combos': 'Lavadora-secadora combo',
232
+ 'home/kitchen/kitchen appliances/ranges': 'Cocinas',
233
+ 'home/kitchen/kitchen appliances/ovens': 'Hornos',
234
+ 'home/kitchen/kitchen appliances/cooktops': 'Encimeras',
235
+ 'outdoor/swimming pools/hot tubs and spa': 'Jacuzzis y spas',
236
+ 'home/home decor/seasonal decor/holiday decorations/christmas decorations': 'Decoraciones navideñas',
237
+ 'home/home decor/seasonal decor/holiday decorations/christmas decorations/christmas trees': 'Árboles de Navidad',
238
+ 'electronics/photography/cameras': 'Cámaras',
239
+ 'electronics/audio/speakers': 'Parlantes',
240
+ 'appliances/heaters/electric heaters': 'Calefactores eléctricos',
241
+ 'sports/fitness/cardio equipment': 'Equipos de cardio',
242
+ 'sports/fitness/strength training': 'Equipos de entrenamiento de fuerza',
243
+ 'pharmacy/health and wellness/vitamins and supplements': 'Vitaminas y suplementos',
244
+ 'pharmacy/health and wellness/vitamins and supplements/sports nutrition': 'Nutrición deportiva',
245
+ 'fashion/fashion accessories/sunglasses': 'Gafas de sol',
246
+ 'beauty/sun care and tanning/sunscreen': 'Protector solar',
247
+ 'sports/cycling/bicycles': 'Bicicletas',
248
+ 'home/home improvement/building materials': 'Materiales de construcción',
249
+ 'home/home improvement/tools and equipment': 'Herramientas y equipos',
250
+ 'home/home improvement/tools and equipment/power tools': 'Herramientas eléctricas',
251
+ 'home/home improvement/tools and equipment/electrical tools/soldering and welding tools': 'Herramientas de soldadura',
252
+ 'appliances/cooling appliances/air conditioners': 'Aire acondicionado',
253
+ 'electronics/mobile phones/smartphones': 'Smartphones',
254
+ 'electronics/televisions/smart tv': 'Smart TV',
255
+ 'electronics/computers/laptops': 'Notebooks',
256
+ 'electronics/computers/laptops/gaming laptops': 'Notebooks gamer',
257
+ 'electronics/computers/e-reader': 'E-Readers',
258
+ 'electronics/wearable technology/smartwatches': 'Smartwatches',
259
+ 'electronics/audio/headphones': 'Auriculares',
260
+ 'home/furniture/bedroom furniture/beds': 'Camas',
261
+ 'home/furniture/bedroom furniture/mattresses': 'Colchones',
262
+ };
263
+ const getCategoryFacetLabel = ({ key, lang }) => {
264
+ const language = lang || 'es-CL';
265
+ if (key) {
266
+ if (language === 'es-CL') {
267
+ return exports.categoriesEnEsMap[key];
268
+ }
269
+ }
270
+ return null;
271
+ };
272
+ exports.getCategoryFacetLabel = getCategoryFacetLabel;
273
+ //# sourceMappingURL=facet-categories-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facet-categories-map.js","sourceRoot":"/","sources":["utils/facet-categories-map.ts"],"names":[],"mappings":"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","sourcesContent":["export const categoriesEnEsMap: { [key: string]: string } = {\n grocery: 'Supermercado',\n 'grocery/coffee': 'Café',\n 'grocery/cooking oils': 'Aceites para cocinar',\n 'grocery/beverages': 'Bebestibles',\n 'grocery/dairy and eggs': 'Lácteos y huevos',\n 'grocery/breakfast and cereal': 'Desayuno y cereales',\n 'grocery/bakery and bread': 'Panadería y pan',\n 'grocery/baking': 'Repostería',\n 'grocery/snacks': 'Snacks',\n 'grocery/fresh produce': 'Frutas y verduras frescas',\n 'grocery/frozen': 'Congelados',\n 'grocery/pantry': 'Despensa',\n 'grocery/desserts': 'Postres',\n 'grocery/spreads': 'Untables',\n 'grocery/condiments and sauces': 'Condimentos y salsas',\n 'grocery/salt': 'Sal',\n 'grocery/sugars and sweeteners': 'Azúcares y edulcorantes',\n 'grocery/candy': 'Dulces',\n 'grocery/grains and pasta': 'Granos y pasta',\n 'grocery/specialty foods': 'Alimentos especiales',\n 'grocery/meat': 'Carnes',\n 'grocery/seafood': 'Mariscos',\n 'grocery/canned goods': 'Conservas',\n 'grocery/soups': 'Sopas',\n 'grocery/deli': 'Charcutería',\n pharmacy: 'Farmacia',\n 'pharmacy/diet and nutrition': 'Dieta y nutrición',\n 'pharmacy/senior health': 'Salud para adultos mayores',\n 'pharmacy/hygiene': 'Higiene',\n 'pharmacy/medications and treatments': 'Medicamentos y tratamientos',\n 'pharmacy/personal care': 'Cuidado personal',\n 'pharmacy/skin care': 'Cuidado de la piel',\n 'pharmacy/face care': 'Cuidado facial',\n 'pharmacy/foot care': 'Cuidado de los pies',\n 'pharmacy/hair care': 'Cuidado del cabello',\n 'pharmacy/oral care': 'Cuidado bucal',\n 'pharmacy/hand and nail care': 'Cuidado de manos y uñas',\n 'pharmacy/eye care': 'Cuidado de los ojos',\n 'pharmacy/health and wellness': 'Salud y bienestar',\n electronics: 'Electrónica',\n 'electronics/gps and navigation': 'GPS y navegación',\n 'electronics/electronics components': 'Componentes electrónicos',\n 'electronics/diy electronics': 'Electrónica DIY',\n 'electronics/electronics kits': 'Kits electrónicos',\n 'electronics/cryptocurrency': 'Criptomonedas',\n 'electronics/drones': 'Drones',\n 'electronics/vr devices': 'Dispositivos de realidad virtual',\n 'electronics/power supplies': 'Fuentes de alimentación',\n 'electronics/networking': 'Redes',\n 'electronics/portable fans': 'Ventiladores portátiles',\n 'electronics/remote controls': 'Controles remotos',\n 'electronics/universal remotes': 'Controles remotos universales',\n 'electronics/smart home': 'Hogar inteligente',\n 'electronics/telephones': 'Teléfonos',\n 'electronics/mobile phones': 'Teléfonos móviles',\n 'electronics/photography': 'Fotografía',\n 'electronics/wearable technology': 'Tecnología vestible',\n 'electronics/computers': 'Computadoras',\n 'electronics/data storage': 'Almacenamiento de datos',\n 'electronics/scanners': 'Escáneres',\n 'electronics/printers': 'Impresoras',\n 'electronics/video games': 'Videojuegos',\n 'electronics/televisions': 'Televisores',\n 'electronics/audio': 'Audio',\n 'electronics/projectors': 'Proyectores',\n 'electronics/outdoor electronics and gadgets': 'Electrónica y gadgets para exteriores',\n appliances: 'Electrodomésticos',\n 'appliances/appliance parts': 'Repuestos de electrodomésticos',\n 'appliances/consumer electronics': 'Electrónica de consumo',\n 'appliances/small appliances': 'Electrodomésticos pequeños',\n 'appliances/specialty appliances': 'Electrodomésticos especiales',\n 'appliances/kitchen appliances': 'Electrodomésticos de cocina',\n 'appliances/heaters': 'Calefactores',\n 'appliances/white goods': 'Línea blanca',\n 'appliances/cooling appliances': 'Electrodomésticos de refrigeración',\n 'appliances/cleaning appliances': 'Electrodomésticos de limpieza',\n 'appliances/personal care appliances': 'Electrodomésticos de cuidado personal',\n beauty: 'Belleza',\n 'beauty/sun care and tanning': 'Cuidado solar y bronceado',\n 'beauty/fragrance': 'Fragancias',\n 'beauty/skin care': 'Cuidado de la piel',\n 'beauty/face care': 'Cuidado facial',\n 'beauty/eye care': 'Cuidado de los ojos',\n 'beauty/foot care': 'Cuidado de los pies',\n 'beauty/hair care': 'Cuidado del cabello',\n 'beauty/bath and body': 'Baño y cuerpo',\n 'beauty/hand and nail care': 'Cuidado de manos y uñas',\n 'beauty/oral care': 'Cuidado bucal',\n 'beauty/makeup': 'Maquillaje',\n 'beauty/shaving and grooming': 'Afeitado y aseo personal',\n fashion: 'Moda',\n 'fashion/fashion accessories': 'Accesorios de moda',\n 'fashion/eyewear': 'Gafas',\n 'fashion/clothing': 'Ropa',\n 'fashion/shoes': 'Calzado',\n sports: 'Deportes',\n 'sports/water sports': 'Deportes acuáticos',\n 'sports/winter sports': 'Deportes de invierno',\n 'sports/outdoor sports': 'Deportes al aire libre',\n 'sports/table tennis': 'Tenis de mesa',\n 'sports/tennis': 'Tenis',\n 'sports/padel': 'Pádel',\n 'sports/basketball': 'Baloncesto',\n 'sports/soccer': 'Fútbol',\n 'sports/scooters': 'Patinetes',\n 'sports/roller skates': 'Patines',\n 'sports/inline skates': 'Patines en línea',\n 'sports/skateboarding': 'Skateboarding',\n 'sports/bowling': 'Bolos',\n 'sports/handball': 'Balonmano',\n 'sports/martial arts': 'Artes marciales',\n 'sports/boxing': 'Boxeo',\n 'sports/cycling': 'Ciclismo',\n 'sports/fitness': 'Fitness',\n 'sports/camping and hiking': 'Camping y senderismo',\n home: 'Hogar',\n 'home/home decor': 'Decoración del hogar',\n 'home/home improvement': 'Mejoras para el hogar',\n 'home/furniture': 'Muebles',\n 'home/bedroom': 'Dormitorio',\n 'home/household supplies': 'Artículos para el hogar',\n 'home/luggage and travel': 'Equipaje y viajes',\n 'home/bathroom': 'Baño',\n 'home/laundry': 'Lavandería',\n 'home/kitchen': 'Cocina',\n 'home/patio and garden': 'Patio y jardín',\n outdoor: 'Exterior',\n 'outdoor/camping and hiking': 'Camping y senderismo',\n 'outdoor/outdoor clothing': 'Ropa para exteriores',\n 'outdoor/outdoor electronics and gadgets': 'Electrónica y gadgets para exteriores',\n 'outdoor/outdoor sports': 'Deportes al aire libre',\n 'outdoor/outdoor lighting': 'Iluminación exterior',\n 'outdoor/outdoor heating': 'Calefacción exterior',\n 'outdoor/swimming pools': 'Piscinas',\n 'outdoor/outdoor furniture': 'Muebles de exterior',\n 'outdoor/awnings and canopies': 'Toldos y marquesinas',\n music: 'Música',\n 'music/vinyl': 'Vinilos',\n 'music/microphones': 'Micrófonos',\n 'music/musical instruments': 'Instrumentos musicales',\n books: 'Libros',\n 'books/user guides and manuals': 'Guías de usuario y manuales',\n 'books/technology books': 'Libros de tecnología',\n 'books/spiritual books': 'Libros espirituales',\n \"books/children's books\": 'Libros infantiles',\n 'books/non-fiction books': 'Libros de no ficción',\n 'books/fiction books': 'Libros de ficción',\n 'books/academic books': 'Libros académicos',\n 'books/specialty books': 'Libros especializados',\n 'books/crime and thriller books': 'Libros de crimen y suspense',\n 'books/horror books': 'Libros de terror',\n 'books/comedy books': 'Libros de comedia',\n 'books/romance books': 'Libros de romance',\n 'books/reference books': 'Libros de referencia',\n 'books/textbooks': 'Libros de texto',\n 'books/study guides': 'Guías de estudio',\n 'books/educational magazines': 'Revistas educativas',\n 'books/history books': 'Libros de historia',\n 'books/self-help books': 'Libros de autoayuda',\n 'books/politics books': 'Libros de política',\n 'books/health and wellness books': 'Libros de salud y bienestar',\n 'books/business and economics books': 'Libros de negocios y economía',\n 'books/comics and graphics novels': 'Cómics y novelas gráficas',\n 'books/book accessories': 'Accesorios para libros',\n kids: 'Niños',\n 'kids/kids clothing': 'Ropa infantil',\n 'kids/kids shoes': 'Calzado infantil',\n 'kids/kids accessories': 'Accesorios infantiles',\n 'kids/toys and games': 'Juguetes y juegos',\n 'kids/party decorations': 'Decoraciones para fiestas infantiles',\n 'kids/party supplies': 'Artículos para fiestas infantiles',\n 'kids/school': 'Escuela',\n 'kids/baby': 'Bebé',\n pets: 'Mascotas',\n 'pets/pet supplies': 'Artículos para mascotas',\n 'pets/pet care': 'Cuidado de mascotas',\n 'pets/pet accessories': 'Accesorios para mascotas',\n 'pets/pet toys': 'Juguetes para mascotas',\n 'pets/pet furniture': 'Muebles para mascotas',\n 'pets/aquariums': 'Acuarios',\n 'pets/pet habitats and pet cages': 'Hábitats y jaulas para mascotas',\n office: 'Oficina',\n 'office/office technology': 'Tecnología de oficina',\n 'office/office lighting': 'Iluminación de oficina',\n 'office/office decor': 'Decoración de oficina',\n 'office/office furniture': 'Muebles de oficina',\n 'office/office cleaning and office maintenance': 'Mantenimiento de oficina',\n 'office/office meeting and presentation': 'Reuniones y presentaciones de oficina',\n 'office/safety and security': 'Seguridad de oficina',\n 'office/office supplies': 'Artículos de oficina',\n 'office/office breakroom': 'Sala de descanso de oficina',\n automotive: 'Automotriz',\n 'automotive/vehicles': 'Vehículos',\n 'party and entertainment': 'Fiestas y entretenimiento',\n 'party and entertainment/party supplies': 'Artículos para fiestas',\n 'party and entertainment/entertainment supplies': 'Artículos de entretenimiento',\n 'party and entertainment/party electronics': 'Electrónica para fiestas',\n 'party and entertainment/party planning': 'Planificación de fiestas',\n services: 'Servicios',\n 'services/installation and maintenance services': 'Servicios de instalación y mantenimiento',\n 'services/warranties and protection plans': 'Garantías y planes de protección',\n 'services/travel services': 'Servicios de viajes',\n\n 'grocery/beverages/alcoholic beverages': 'Bebidas alcohólicas',\n 'grocery/beverages/alcoholic beverages/beer': 'Cervezas',\n 'grocery/beverages/alcoholic beverages/wine': 'Vinos',\n 'grocery/beverages/alcoholic beverages/sparkling wine': 'Espumantes',\n 'grocery/beverages/alcoholic beverages/whisky': 'Whisky',\n 'grocery/beverages/alcoholic beverages/vodka': 'Vodka',\n 'grocery/beverages/alcoholic beverages/gin': 'Gin',\n 'grocery/beverages/alcoholic beverages/tequila': 'Tequila',\n 'grocery/beverages/alcoholic beverages/cognac': 'Cognac',\n 'grocery/beverages/alcoholic beverages/rum': 'Ron',\n 'grocery/beverages/alcoholic beverages/brandy': 'Brandy',\n 'grocery/beverages/alcoholic beverages/cocktails': 'Cocktails',\n 'grocery/beverages/alcoholic beverages/cider': 'Sidra',\n 'grocery/beverages/alcoholic beverages/pisco': 'Pisco',\n 'grocery/beverages/alcoholic beverages/liqueurs': 'Licores',\n\n 'electronics/video games/nintendo': 'Nintendo',\n 'electronics/video games/xbox': 'Xbox',\n 'electronics/video games/playstation': 'Playstation',\n 'home/kitchen/kitchen appliances/coffee machines': 'Cafeteras',\n 'appliances/white goods/refrigeration appliances/refrigerators': 'Refrigeradores',\n 'appliances/white goods/refrigeration appliances/freezers': 'Congeladores',\n 'appliances/white goods/dishwashing appliances/dishwashers': 'Lavavajillas',\n 'home/laundry/laundry appliances/washing machines': 'Lavadoras',\n 'home/laundry/laundry appliances/dryers machines': 'Secadoras',\n 'home/laundry/laundry appliances/washer-dryer combos': 'Lavadora-secadora combo',\n 'home/kitchen/kitchen appliances/ranges': 'Cocinas',\n 'home/kitchen/kitchen appliances/ovens': 'Hornos',\n 'home/kitchen/kitchen appliances/cooktops': 'Encimeras',\n 'outdoor/swimming pools/hot tubs and spa': 'Jacuzzis y spas',\n 'home/home decor/seasonal decor/holiday decorations/christmas decorations': 'Decoraciones navideñas',\n 'home/home decor/seasonal decor/holiday decorations/christmas decorations/christmas trees': 'Árboles de Navidad',\n 'electronics/photography/cameras': 'Cámaras',\n 'electronics/audio/speakers': 'Parlantes',\n 'appliances/heaters/electric heaters': 'Calefactores eléctricos',\n 'sports/fitness/cardio equipment': 'Equipos de cardio',\n 'sports/fitness/strength training': 'Equipos de entrenamiento de fuerza',\n 'pharmacy/health and wellness/vitamins and supplements': 'Vitaminas y suplementos',\n 'pharmacy/health and wellness/vitamins and supplements/sports nutrition': 'Nutrición deportiva',\n 'fashion/fashion accessories/sunglasses': 'Gafas de sol',\n 'beauty/sun care and tanning/sunscreen': 'Protector solar',\n 'sports/cycling/bicycles': 'Bicicletas',\n 'home/home improvement/building materials': 'Materiales de construcción',\n 'home/home improvement/tools and equipment': 'Herramientas y equipos',\n 'home/home improvement/tools and equipment/power tools': 'Herramientas eléctricas',\n 'home/home improvement/tools and equipment/electrical tools/soldering and welding tools': 'Herramientas de soldadura',\n 'appliances/cooling appliances/air conditioners': 'Aire acondicionado',\n 'electronics/mobile phones/smartphones': 'Smartphones',\n 'electronics/televisions/smart tv': 'Smart TV',\n 'electronics/computers/laptops': 'Notebooks',\n 'electronics/computers/laptops/gaming laptops': 'Notebooks gamer',\n 'electronics/computers/e-reader': 'E-Readers',\n 'electronics/wearable technology/smartwatches': 'Smartwatches',\n 'electronics/audio/headphones': 'Auriculares',\n 'home/furniture/bedroom furniture/beds': 'Camas',\n 'home/furniture/bedroom furniture/mattresses': 'Colchones',\n};\n\nexport const getCategoryFacetLabel = ({ key, lang }: { key: string; lang?: string }): string | null => {\n const language = lang || 'es-CL';\n\n if (key) {\n if (language === 'es-CL') {\n return categoriesEnEsMap[key];\n }\n }\n\n return null;\n};\n"]}
@@ -4,6 +4,6 @@ import { reverseString, removeNewLines, includesStringArray, getLastAfter, repla
4
4
  import { isUrl, getHostname, getParam, getPathname } from './url-utils';
5
5
  import { calculateAverage, roundNumber, getRandomNumber, getRandomNumbers, getPercentageDiff } from './number-utils';
6
6
  import { hasElementInArray, isArrayEmpty, stringToArray, getRandomItem } from './array-utils';
7
- import { hasUpdateReason, getStoreName } from './product.utils';
7
+ import { hasUpdateReason, getStoreName, parseProductDtoToTypesenseDocument } from './product.utils';
8
8
  import { formatDate, formatMoney, formatPct } from './string-formatter';
9
- export { checkIfSamePrices, findLastQuery, replaceMultipleSpacesByOne, hasMeasurementUnitMultiplier, getPriceByMeasurementUnitMultiplier, removeIfEndsWith, getLastAfter, includesStringArray, removeNewLines, reverseString, getParam, getPathname, getHostname, isUrl, isValidPrice, getMinPrice, isCheaper, getMaxPrice, getPriceOperation, getAvgPrice, calculateAverage, roundNumber, removeZeroPrices, isArrayEmpty, hasElementInArray, stringToArray, hasUpdateReason, getStoreName, formatPct, formatDate, formatMoney, getRandomNumber, getRandomNumbers, getPercentageDiff, getRandomItem, };
9
+ export { checkIfSamePrices, findLastQuery, replaceMultipleSpacesByOne, hasMeasurementUnitMultiplier, getPriceByMeasurementUnitMultiplier, removeIfEndsWith, getLastAfter, includesStringArray, removeNewLines, reverseString, getParam, getPathname, getHostname, isUrl, isValidPrice, getMinPrice, isCheaper, getMaxPrice, getPriceOperation, getAvgPrice, calculateAverage, roundNumber, removeZeroPrices, isArrayEmpty, hasElementInArray, stringToArray, hasUpdateReason, getStoreName, parseProductDtoToTypesenseDocument, formatPct, formatDate, formatMoney, getRandomNumber, getRandomNumbers, getPercentageDiff, getRandomItem, };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRandomItem = exports.getPercentageDiff = exports.getRandomNumbers = exports.getRandomNumber = exports.formatMoney = exports.formatDate = exports.formatPct = exports.getStoreName = exports.hasUpdateReason = exports.stringToArray = exports.hasElementInArray = exports.isArrayEmpty = exports.removeZeroPrices = exports.roundNumber = exports.calculateAverage = exports.getAvgPrice = exports.getPriceOperation = exports.getMaxPrice = exports.isCheaper = exports.getMinPrice = exports.isValidPrice = exports.isUrl = exports.getHostname = exports.getPathname = exports.getParam = exports.reverseString = exports.removeNewLines = exports.includesStringArray = exports.getLastAfter = exports.removeIfEndsWith = exports.getPriceByMeasurementUnitMultiplier = exports.hasMeasurementUnitMultiplier = exports.replaceMultipleSpacesByOne = exports.findLastQuery = exports.checkIfSamePrices = void 0;
3
+ exports.getRandomItem = exports.getPercentageDiff = exports.getRandomNumbers = exports.getRandomNumber = exports.formatMoney = exports.formatDate = exports.formatPct = exports.parseProductDtoToTypesenseDocument = exports.getStoreName = exports.hasUpdateReason = exports.stringToArray = exports.hasElementInArray = exports.isArrayEmpty = exports.removeZeroPrices = exports.roundNumber = exports.calculateAverage = exports.getAvgPrice = exports.getPriceOperation = exports.getMaxPrice = exports.isCheaper = exports.getMinPrice = exports.isValidPrice = exports.isUrl = exports.getHostname = exports.getPathname = exports.getParam = exports.reverseString = exports.removeNewLines = exports.includesStringArray = exports.getLastAfter = exports.removeIfEndsWith = exports.getPriceByMeasurementUnitMultiplier = exports.hasMeasurementUnitMultiplier = exports.replaceMultipleSpacesByOne = exports.findLastQuery = exports.checkIfSamePrices = void 0;
4
4
  const price_utils_1 = require("./price-utils");
5
5
  Object.defineProperty(exports, "checkIfSamePrices", { enumerable: true, get: function () { return price_utils_1.checkIfSamePrices; } });
6
6
  Object.defineProperty(exports, "isCheaper", { enumerable: true, get: function () { return price_utils_1.isCheaper; } });
@@ -40,6 +40,7 @@ Object.defineProperty(exports, "getRandomItem", { enumerable: true, get: functio
40
40
  const product_utils_1 = require("./product.utils");
41
41
  Object.defineProperty(exports, "hasUpdateReason", { enumerable: true, get: function () { return product_utils_1.hasUpdateReason; } });
42
42
  Object.defineProperty(exports, "getStoreName", { enumerable: true, get: function () { return product_utils_1.getStoreName; } });
43
+ Object.defineProperty(exports, "parseProductDtoToTypesenseDocument", { enumerable: true, get: function () { return product_utils_1.parseProductDtoToTypesenseDocument; } });
43
44
  const string_formatter_1 = require("./string-formatter");
44
45
  Object.defineProperty(exports, "formatDate", { enumerable: true, get: function () { return string_formatter_1.formatDate; } });
45
46
  Object.defineProperty(exports, "formatMoney", { enumerable: true, get: function () { return string_formatter_1.formatMoney; } });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"/","sources":["utils/index.ts"],"names":[],"mappings":";;;AAAA,+CAGuB;AAmBrB,kGArBA,+BAAiB,OAqBA;AAE8B,0FAvB5B,uBAAS,OAuB4B;AAAtB,4FAvBJ,yBAAW,OAuBI;AAAzB,6FAvBuB,0BAAY,OAuBvB;AAA0D,4FAvBjC,yBAAW,OAuBiC;AAA3C,4FAvBY,yBAAW,OAuBZ;AAAE,kGAvBY,+BAAiB,OAuBZ;AAC3E,iGAxByF,8BAAgB,OAwBzF;AAHiC,6GApB9D,0CAA4B,OAoB8D;AAAE,oHApB9D,iDAAmC,OAoB8D;AAlBjI,iEAAuD;AAkBlC,8FAlBZ,oCAAa,OAkBY;AAjBlC,iDAGwB;AAe+C,8FAjBrE,4BAAa,OAiBqE;AAA7B,+FAjBtC,6BAAc,OAiBsC;AAAnC,oGAjBD,kCAAmB,OAiBC;AAAjC,6FAjBkC,2BAAY,OAiBlC;AADI,2GAhBgC,yCAA0B,OAgBhC;AAC5D,iGAjB8F,+BAAgB,OAiB9F;AAdlB,2CAEqB;AAaN,sFAdb,iBAAK,OAca;AAAlB,4FAdO,uBAAW,OAcP;AADyE,yFAbhE,oBAAQ,OAagE;AAAE,4FAbhE,uBAAW,OAagE;AAX3G,iDAEwB;AAUiF,iGAXvG,+BAAgB,OAWuG;AACvH,4FAZkB,0BAAW,OAYlB;AACyB,gGAbL,8BAAe,OAaK;AAAE,iGAbL,+BAAgB,OAaK;AAAE,kGAbL,gCAAiB,OAaK;AAX1F,+CAEuB;AAQwB,kGAT7C,+BAAiB,OAS6C;AAA/B,6FATZ,0BAAY,OASY;AAAqB,8FAT/B,2BAAa,OAS+B;AACa,8FAV1C,2BAAa,OAU0C;AARzG,mDAAgE;AAOiB,gGAPxE,+BAAe,OAOwE;AAAE,6FAPxE,4BAAY,OAOwE;AAN9G,yDAAwE;AAO3D,2FAPJ,6BAAU,OAOI;AAAE,4FAPJ,8BAAW,OAOI;AAAlC,0FAPgC,4BAAS,OAOhC","sourcesContent":["import {\n checkIfSamePrices, isCheaper, getMinPrice, isValidPrice, getAvgPrice, getMaxPrice, getPriceOperation, removeZeroPrices,\n hasMeasurementUnitMultiplier, getPriceByMeasurementUnitMultiplier,\n} from './price-utils';\nimport { findLastQuery } from './entity-queries-utils';\nimport {\n reverseString, removeNewLines, includesStringArray, getLastAfter, replaceMultipleSpacesByOne, removeIfEndsWith,\n}\n from './string-utils';\nimport {\n isUrl, getHostname, getParam, getPathname,\n} from './url-utils';\nimport {\n calculateAverage, roundNumber, getRandomNumber, getRandomNumbers, getPercentageDiff,\n} from './number-utils';\nimport {\n hasElementInArray, isArrayEmpty, stringToArray, getRandomItem,\n} from './array-utils';\nimport { hasUpdateReason, getStoreName } from './product.utils';\nimport { formatDate, formatMoney, formatPct } from './string-formatter';\n\nexport {\n checkIfSamePrices, findLastQuery, replaceMultipleSpacesByOne, hasMeasurementUnitMultiplier, getPriceByMeasurementUnitMultiplier,\n removeIfEndsWith, getLastAfter, includesStringArray, removeNewLines, reverseString, getParam, getPathname,\n getHostname, isUrl, isValidPrice, getMinPrice, isCheaper, getMaxPrice, getPriceOperation, getAvgPrice, calculateAverage,\n roundNumber, removeZeroPrices, isArrayEmpty, hasElementInArray, stringToArray, hasUpdateReason, getStoreName,\n formatPct, formatDate, formatMoney, getRandomNumber, getRandomNumbers, getPercentageDiff, getRandomItem,\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"/","sources":["utils/index.ts"],"names":[],"mappings":";;;AAAA,+CAGuB;AAmBrB,kGArBA,+BAAiB,OAqBA;AAE8B,0FAvB5B,uBAAS,OAuB4B;AAAtB,4FAvBJ,yBAAW,OAuBI;AAAzB,6FAvBuB,0BAAY,OAuBvB;AAA0D,4FAvBjC,yBAAW,OAuBiC;AAA3C,4FAvBY,yBAAW,OAuBZ;AAAE,kGAvBY,+BAAiB,OAuBZ;AAC3E,iGAxByF,8BAAgB,OAwBzF;AAHiC,6GApB9D,0CAA4B,OAoB8D;AAAE,oHApB9D,iDAAmC,OAoB8D;AAlBjI,iEAAuD;AAkBlC,8FAlBZ,oCAAa,OAkBY;AAjBlC,iDAGwB;AAe+C,8FAjBrE,4BAAa,OAiBqE;AAA7B,+FAjBtC,6BAAc,OAiBsC;AAAnC,oGAjBD,kCAAmB,OAiBC;AAAjC,6FAjBkC,2BAAY,OAiBlC;AADI,2GAhBgC,yCAA0B,OAgBhC;AAC5D,iGAjB8F,+BAAgB,OAiB9F;AAdlB,2CAEqB;AAaN,sFAdb,iBAAK,OAca;AAAlB,4FAdO,uBAAW,OAcP;AADyE,yFAbhE,oBAAQ,OAagE;AAAE,4FAbhE,uBAAW,OAagE;AAX3G,iDAEwB;AAUiF,iGAXvG,+BAAgB,OAWuG;AACvH,4FAZkB,0BAAW,OAYlB;AACyB,gGAbL,8BAAe,OAaK;AAAE,iGAbL,+BAAgB,OAaK;AAAE,kGAbL,gCAAiB,OAaK;AAX1F,+CAEuB;AAQwB,kGAT7C,+BAAiB,OAS6C;AAA/B,6FATZ,0BAAY,OASY;AAAqB,8FAT/B,2BAAa,OAS+B;AACa,8FAV1C,2BAAa,OAU0C;AARzG,mDAAoG;AAOnB,gGAPxE,+BAAe,OAOwE;AAAE,6FAPxE,4BAAY,OAOwE;AAAE,mHAPxE,kDAAkC,OAOwE;AANlJ,yDAAwE;AAO3D,2FAPJ,6BAAU,OAOI;AAAE,4FAPJ,8BAAW,OAOI;AAAlC,0FAPgC,4BAAS,OAOhC","sourcesContent":["import {\n checkIfSamePrices, isCheaper, getMinPrice, isValidPrice, getAvgPrice, getMaxPrice, getPriceOperation, removeZeroPrices,\n hasMeasurementUnitMultiplier, getPriceByMeasurementUnitMultiplier,\n} from './price-utils';\nimport { findLastQuery } from './entity-queries-utils';\nimport {\n reverseString, removeNewLines, includesStringArray, getLastAfter, replaceMultipleSpacesByOne, removeIfEndsWith,\n}\n from './string-utils';\nimport {\n isUrl, getHostname, getParam, getPathname,\n} from './url-utils';\nimport {\n calculateAverage, roundNumber, getRandomNumber, getRandomNumbers, getPercentageDiff,\n} from './number-utils';\nimport {\n hasElementInArray, isArrayEmpty, stringToArray, getRandomItem,\n} from './array-utils';\nimport { hasUpdateReason, getStoreName, parseProductDtoToTypesenseDocument } from './product.utils';\nimport { formatDate, formatMoney, formatPct } from './string-formatter';\n\nexport {\n checkIfSamePrices, findLastQuery, replaceMultipleSpacesByOne, hasMeasurementUnitMultiplier, getPriceByMeasurementUnitMultiplier,\n removeIfEndsWith, getLastAfter, includesStringArray, removeNewLines, reverseString, getParam, getPathname,\n getHostname, isUrl, isValidPrice, getMinPrice, isCheaper, getMaxPrice, getPriceOperation, getAvgPrice, calculateAverage,\n roundNumber, removeZeroPrices, isArrayEmpty, hasElementInArray, stringToArray, hasUpdateReason, getStoreName, parseProductDtoToTypesenseDocument,\n formatPct, formatDate, formatMoney, getRandomNumber, getRandomNumbers, getPercentageDiff, getRandomItem,\n};\n"]}
@@ -1,3 +1,5 @@
1
1
  import { Product, Store, UpdateReasonEnum } from '../entities';
2
+ import { ObjectLiteral } from "../classes";
2
3
  export declare const getStoreName: (product: Product, stores: Store[]) => string;
3
4
  export declare const hasUpdateReason: (enums: UpdateReasonEnum[], search: UpdateReasonEnum[]) => boolean;
5
+ export declare const parseProductDtoToTypesenseDocument: (product: Product) => ObjectLiteral;
@@ -1,7 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasUpdateReason = exports.getStoreName = void 0;
3
+ exports.parseProductDtoToTypesenseDocument = exports.hasUpdateReason = exports.getStoreName = void 0;
4
4
  const array_utils_1 = require("./array-utils");
5
+ const entities_1 = require("../entities");
6
+ const price_utils_1 = require("./price-utils");
7
+ const facet_categories_map_1 = require("./facet-categories-map");
8
+ const time_utils_1 = require("./time-utils");
9
+ const string_utils_1 = require("./string-utils");
5
10
  const getStoreName = (product, stores) => {
6
11
  if ((!stores || stores.length === 0) && product) {
7
12
  return product.storeName;
@@ -15,4 +20,83 @@ const getStoreName = (product, stores) => {
15
20
  exports.getStoreName = getStoreName;
16
21
  const hasUpdateReason = (enums, search) => (0, array_utils_1.hasElementInArray)(enums, search);
17
22
  exports.hasUpdateReason = hasUpdateReason;
23
+ const parseProductDtoToTypesenseDocument = (product) => {
24
+ if (!product) {
25
+ return null;
26
+ }
27
+ const ref = JSON.parse(JSON.stringify(product));
28
+ let priceStats = null;
29
+ let priceUpdatedAt = new Date(ref.price.updatedAt || ref.price.createdAt || ref.extractedAt || ref.updatedAt).getTime();
30
+ if (ref.priceStats) {
31
+ const pivotPrices = (ref.priceStats.pivotPrices || []).slice(0, 3);
32
+ let maxDiscount = 0;
33
+ if (ref.priceStats.currentMinPriceMaxPriceDiffPct > 0) {
34
+ maxDiscount = ref.priceStats.currentMinPriceMaxPriceDiffPct;
35
+ }
36
+ if (ref.priceStats.conditionalPriceMinPriceDiffPct) {
37
+ if (maxDiscount === 0 ||
38
+ ref.priceStats.conditionalPriceMinPriceDiffPct > ref.priceStats.currentMinPriceMaxPriceDiffPct) {
39
+ maxDiscount = ref.priceStats.conditionalPriceMinPriceDiffPct;
40
+ const useDate = ref.conditionalPrice && ref.conditionalPrice.createdAt ? ref.conditionalPrice.createdAt : ref.extractedAt;
41
+ if (useDate) {
42
+ priceUpdatedAt = new Date(useDate).getTime();
43
+ }
44
+ }
45
+ }
46
+ if (maxDiscount === 0 && ref.priceStats.currentPricePrevPriceDiffPct > 0) {
47
+ let hasFakePrevPrice = false;
48
+ if (product.storeRef === '634b4c2ebf4c49e4b3672aba') {
49
+ hasFakePrevPrice = true;
50
+ }
51
+ if (!hasFakePrevPrice && (!product.currency || product.currency === entities_1.CurrencyEnum.CLP)) {
52
+ const minPrevPrice = (0, price_utils_1.getMinPrice)(ref.previousPrice);
53
+ const minPrevPriceStr = minPrevPrice.toString();
54
+ if (minPrevPrice > 0) {
55
+ if (product.isMarketplace && minPrevPriceStr.endsWith('000')) {
56
+ hasFakePrevPrice = true;
57
+ }
58
+ if (minPrevPrice === 9999999 || minPrevPrice === 10000000) {
59
+ hasFakePrevPrice = true;
60
+ }
61
+ }
62
+ else {
63
+ hasFakePrevPrice = true;
64
+ }
65
+ }
66
+ if (!hasFakePrevPrice) {
67
+ maxDiscount = ref.priceStats.currentPricePrevPriceDiffPct;
68
+ }
69
+ }
70
+ priceStats = {
71
+ priceStats_pricesCount: ref.priceStats.pricesCount,
72
+ priceStats_avgMinPrice: ref.priceStats.avgMinPrice,
73
+ priceStats_currentMinPrice: ref.priceStats.currentMinPrice,
74
+ priceStats_currentMaxPrice: ref.priceStats.currentMaxPrice,
75
+ priceStats_currentPriceBestPriceDiffPct: ref.priceStats.currentPriceBestPriceDiffPct,
76
+ priceStats_currentPricePrevPriceDiffPct: ref.priceStats.currentPricePrevPriceDiffPct,
77
+ priceStats_currentMinPriceMaxPriceDiffPct: ref.priceStats.currentMinPriceMaxPriceDiffPct,
78
+ priceStats_conditionalPriceMinPriceDiffPct: ref.priceStats.conditionalPriceMinPriceDiffPct || 0,
79
+ priceStats_currentPriceAvgMinPriceDiffPct: ref.priceStats.currentPriceAvgMinPriceDiffPct,
80
+ priceStats_maxDiscountPct: maxDiscount,
81
+ priceStats_pivotPrices: pivotPrices,
82
+ };
83
+ }
84
+ let customBucketTimeDate = null;
85
+ if (!(0, exports.hasUpdateReason)([entities_1.UpdateReasonEnum.PRICE_DOWN, entities_1.UpdateReasonEnum.RE_LISTING, entities_1.UpdateReasonEnum.NEW_LISTING], product.updateReason)) {
86
+ customBucketTimeDate = new Date(Date.now() - 1000 * 60 * 30);
87
+ }
88
+ let foundCategories = [...(ref.categoryKeywordNames || [])];
89
+ if (!(0, array_utils_1.isArrayEmpty)(ref.inferredCategories)) {
90
+ ref.inferredCategories.forEach((inferredCategory) => {
91
+ if ((0, facet_categories_map_1.getCategoryFacetLabel)({ key: inferredCategory })) {
92
+ foundCategories.push(inferredCategory);
93
+ }
94
+ });
95
+ foundCategories = foundCategories.filter((category) => category !== entities_1.CATEGORY_ENUM.CATEGORY_NOT_FOUND);
96
+ }
97
+ const updatedAtDate = new Date(ref.updatedAt || ref.extractedAt || Date.now());
98
+ const bucketData = (0, time_utils_1.getBucketTime)(customBucketTimeDate || updatedAtDate);
99
+ return Object.assign(Object.assign({ id: ref._id }, priceStats), { storeRef: ref.storeRef, storeName: ref.storeName || 'no store name', isMarketplace: ref.isMarketplace === true, name: ref.name || 'no name', sku: ref.sku, ean: ref.ean, url: ref.url, image: ref.image, brandName: ref.brandName ? (0, string_utils_1.normalizeString)(ref.brandName) : undefined, sellerName: ref.sellerName, category: ref.category, categoryPath: ref.categoryPath, price: ref.price, bestPrice: ref.bestPrice, conditionalPrice: ref.conditionalPrice, priceHistory: ref.priceHistory, currency: ref.currency || entities_1.CurrencyEnum.CLP, enabled: ref.enabled === true || typeof ref.enabled === 'undefined' || ref.enabled === null, categoryKeywordNames: foundCategories, updateReasons: (ref.updateReason || []).filter((e) => e), updatedAt: updatedAtDate.getTime(), priceUpdatedAt: priceUpdatedAt, bucketTime: bucketData && bucketData.bucketTime ? bucketData.bucketTime : undefined, bucketDate: bucketData && bucketData.bucketDate ? bucketData.bucketDate : undefined });
100
+ };
101
+ exports.parseProductDtoToTypesenseDocument = parseProductDtoToTypesenseDocument;
18
102
  //# sourceMappingURL=product.utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"product.utils.js","sourceRoot":"/","sources":["utils/product.utils.ts"],"names":[],"mappings":";;;AAAA,+CAAkD;AAG3C,MAAM,YAAY,GAAG,CAAC,OAAgB,EAAE,MAAe,EAAU,EAAE;IACxE,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC;QAChD,OAAO,OAAO,CAAC,SAAS,CAAC;IAC3B,CAAC;IAGD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9F,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC;IACzC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAZW,QAAA,YAAY,gBAYvB;AAEK,MAAM,eAAe,GAAG,CAAC,KAAyB,EAAE,MAA0B,EAAW,EAAE,CAAC,IAAA,+BAAiB,EAAmB,KAAK,EAAE,MAAM,CAAC,CAAC;AAAzI,QAAA,eAAe,mBAA0H","sourcesContent":["import { hasElementInArray } from './array-utils';\nimport { Product, Store, UpdateReasonEnum } from '../entities';\n\nexport const getStoreName = (product: Product, stores: Store[]): string => {\n if ((!stores || stores.length === 0) && product) {\n return product.storeName;\n }\n\n // eslint-disable-next-line no-underscore-dangle\n const store = stores.find((storeElement) => storeElement._id.toString() === product.storeRef);\n if (store) {\n return store.displayName || store.name;\n }\n\n return null;\n};\n\nexport const hasUpdateReason = (enums: UpdateReasonEnum[], search: UpdateReasonEnum[]): boolean => hasElementInArray<UpdateReasonEnum>(enums, search);\n"]}
1
+ {"version":3,"file":"product.utils.js","sourceRoot":"/","sources":["utils/product.utils.ts"],"names":[],"mappings":";;;AAAA,+CAA8D;AAC9D,0CAA0F;AAE1F,+CAA0C;AAC1C,iEAA6D;AAC7D,6CAA2C;AAC3C,iDAA+C;AAExC,MAAM,YAAY,GAAG,CAAC,OAAgB,EAAE,MAAe,EAAU,EAAE;IACxE,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC;QAChD,OAAO,OAAO,CAAC,SAAS,CAAC;IAC3B,CAAC;IAGD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9F,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC;IACzC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAZW,QAAA,YAAY,gBAYvB;AAEK,MAAM,eAAe,GAAG,CAAC,KAAyB,EAAE,MAA0B,EAAW,EAAE,CAAC,IAAA,+BAAiB,EAAmB,KAAK,EAAE,MAAM,CAAC,CAAC;AAAzI,QAAA,eAAe,mBAA0H;AAE/I,MAAM,kCAAkC,GAAG,CAAC,OAAgB,EAAiB,EAAE;IACpF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IAEzD,IAAI,UAAU,GAAG,IAAI,CAAC;IAEtB,IAAI,cAAc,GAAG,IAAI,IAAI,CACzB,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,SAAS,CACjF,CAAC,OAAO,EAAE,CAAC;IAEZ,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QAGnB,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAKnE,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,IAAI,GAAG,CAAC,UAAU,CAAC,8BAA8B,GAAG,CAAC,EAAE,CAAC;YACtD,WAAW,GAAG,GAAG,CAAC,UAAU,CAAC,8BAA8B,CAAC;QAC9D,CAAC;QAGD,IAAI,GAAG,CAAC,UAAU,CAAC,+BAA+B,EAAE,CAAC;YACnD,IACI,WAAW,KAAK,CAAC;gBACjB,GAAG,CAAC,UAAU,CAAC,+BAA+B,GAAG,GAAG,CAAC,UAAU,CAAC,8BAA8B,EAChG,CAAC;gBACD,WAAW,GAAG,GAAG,CAAC,UAAU,CAAC,+BAA+B,CAAC;gBAC7D,MAAM,OAAO,GACT,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;gBAC9G,IAAI,OAAO,EAAE,CAAC;oBACZ,cAAc,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC/C,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,WAAW,KAAK,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,4BAA4B,GAAG,CAAC,EAAE,CAAC;YACzE,IAAI,gBAAgB,GAAG,KAAK,CAAC;YAG7B,IAAI,OAAO,CAAC,QAAQ,KAAK,0BAA0B,EAAE,CAAC;gBACpD,gBAAgB,GAAG,IAAI,CAAC;YAC1B,CAAC;YAED,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,KAAK,uBAAY,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtF,MAAM,YAAY,GAAG,IAAA,yBAAW,EAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBACpD,MAAM,eAAe,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAC;gBAChD,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;oBACrB,IAAI,OAAO,CAAC,aAAa,IAAI,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;wBAC7D,gBAAgB,GAAG,IAAI,CAAC;oBAC1B,CAAC;oBAED,IAAI,YAAY,KAAK,OAAO,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;wBAC1D,gBAAgB,GAAG,IAAI,CAAC;oBAC1B,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,gBAAgB,GAAG,IAAI,CAAC;gBAC1B,CAAC;YACH,CAAC;YAED,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACtB,WAAW,GAAG,GAAG,CAAC,UAAU,CAAC,4BAA4B,CAAC;YAC5D,CAAC;QACH,CAAC;QAED,UAAU,GAAG;YACX,sBAAsB,EAAE,GAAG,CAAC,UAAU,CAAC,WAAW;YAClD,sBAAsB,EAAE,GAAG,CAAC,UAAU,CAAC,WAAW;YAClD,0BAA0B,EAAE,GAAG,CAAC,UAAU,CAAC,eAAe;YAC1D,0BAA0B,EAAE,GAAG,CAAC,UAAU,CAAC,eAAe;YAC1D,uCAAuC,EAAE,GAAG,CAAC,UAAU,CAAC,4BAA4B;YACpF,uCAAuC,EAAE,GAAG,CAAC,UAAU,CAAC,4BAA4B;YACpF,yCAAyC,EAAE,GAAG,CAAC,UAAU,CAAC,8BAA8B;YACxF,0CAA0C,EAAE,GAAG,CAAC,UAAU,CAAC,+BAA+B,IAAI,CAAC;YAC/F,yCAAyC,EAAE,GAAG,CAAC,UAAU,CAAC,8BAA8B;YACxF,yBAAyB,EAAE,WAAW;YACtC,sBAAsB,EAAE,WAAW;SACpC,CAAC;IACJ,CAAC;IAGD,IAAI,oBAAoB,GAAgB,IAAI,CAAC;IAC7C,IACI,CAAC,IAAA,uBAAe,EACZ,CAAC,2BAAgB,CAAC,UAAU,EAAE,2BAAgB,CAAC,UAAU,EAAE,2BAAgB,CAAC,WAAW,CAAC,EACxF,OAAO,CAAC,YAAY,CACvB,EACH,CAAC;QACD,oBAAoB,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/D,CAAC;IAID,IAAI,eAAe,GAAa,CAAC,GAAG,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC,CAAC;IACtE,IAAI,CAAC,IAAA,0BAAY,EAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC1C,GAAG,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,gBAAgB,EAAE,EAAE;YAClD,IAAI,IAAA,4CAAqB,EAAC,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC;gBACrD,eAAe,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACzC,CAAC;QACH,CAAC,CAAC,CAAC;QAIH,eAAe,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,wBAAa,CAAC,kBAAkB,CAAC,CAAC;IACxG,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/E,MAAM,UAAU,GAAG,IAAA,0BAAa,EAAC,oBAAoB,IAAI,aAAa,CAAC,CAAC;IAExE,OAAO,8BACL,EAAE,EAAE,GAAG,CAAC,GAAG,IACR,UAAU,KACb,QAAQ,EAAE,GAAG,CAAC,QAAQ,EACtB,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,eAAe,EAC3C,aAAa,EAAE,GAAG,CAAC,aAAa,KAAK,IAAI,EACzC,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,SAAS,EAC3B,GAAG,EAAE,GAAG,CAAC,GAAG,EACZ,GAAG,EAAE,GAAG,CAAC,GAAG,EACZ,GAAG,EAAE,GAAG,CAAC,GAAG,EACZ,KAAK,EAAE,GAAG,CAAC,KAAK,EAChB,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAA,8BAAe,EAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,EACrE,UAAU,EAAE,GAAG,CAAC,UAAU,EAE1B,QAAQ,EAAE,GAAG,CAAC,QAAQ,EACtB,YAAY,EAAE,GAAG,CAAC,YAAY,EAC9B,KAAK,EAAE,GAAG,CAAC,KAAK,EAChB,SAAS,EAAE,GAAG,CAAC,SAAS,EACxB,gBAAgB,EAAE,GAAG,CAAC,gBAAgB,EACtC,YAAY,EAAE,GAAG,CAAC,YAAY,EAC9B,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,uBAAY,CAAC,GAAG,EAC1C,OAAO,EAAE,GAAG,CAAC,OAAO,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,WAAW,IAAI,GAAG,CAAC,OAAO,KAAK,IAAI,EAC3F,oBAAoB,EAAE,eAAe,EACrC,aAAa,EAAE,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EACxD,SAAS,EAAE,aAAa,CAAC,OAAO,EAAE,EAClC,cAAc,EAAE,cAAc,EAC9B,UAAU,EAAE,UAAU,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EACnF,UAAU,EAAE,UAAU,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,GACpF,CAAC;AACJ,CAAC,CAAC;AA/IW,QAAA,kCAAkC,sCA+I7C","sourcesContent":["import {hasElementInArray, isArrayEmpty} from './array-utils';\nimport {CATEGORY_ENUM, CurrencyEnum, Product, Store, UpdateReasonEnum} from '../entities';\nimport {ObjectLiteral} from \"../classes\";\nimport {getMinPrice} from \"./price-utils\";\nimport {getCategoryFacetLabel} from \"./facet-categories-map\";\nimport {getBucketTime} from \"./time-utils\";\nimport {normalizeString} from \"./string-utils\";\n\nexport const getStoreName = (product: Product, stores: Store[]): string => {\n if ((!stores || stores.length === 0) && product) {\n return product.storeName;\n }\n\n // eslint-disable-next-line no-underscore-dangle\n const store = stores.find((storeElement) => storeElement._id.toString() === product.storeRef);\n if (store) {\n return store.displayName || store.name;\n }\n\n return null;\n};\n\nexport const hasUpdateReason = (enums: UpdateReasonEnum[], search: UpdateReasonEnum[]): boolean => hasElementInArray<UpdateReasonEnum>(enums, search);\n\nexport const parseProductDtoToTypesenseDocument = (product: Product): ObjectLiteral => {\n if (!product) {\n return null;\n }\n\n const ref: Product = JSON.parse(JSON.stringify(product));\n\n let priceStats = null;\n\n let priceUpdatedAt = new Date(\n ref.price.updatedAt || ref.price.createdAt || ref.extractedAt || ref.updatedAt,\n ).getTime();\n\n if (ref.priceStats) {\n // TODO: Search how to look for specific pivot prices in Typesense search\n // Slice 3 pivot prices\n const pivotPrices = (ref.priceStats.pivotPrices || []).slice(0, 3);\n\n // Add max discount single field\n // Prioritize Current Offer and Conditional Price\n // If neither of those exists then use previous price\n let maxDiscount = 0;\n if (ref.priceStats.currentMinPriceMaxPriceDiffPct > 0) {\n maxDiscount = ref.priceStats.currentMinPriceMaxPriceDiffPct;\n }\n\n // TODO: Was updated to use currentMaxPrice, update or create a new field\n if (ref.priceStats.conditionalPriceMinPriceDiffPct) {\n if (\n maxDiscount === 0 ||\n ref.priceStats.conditionalPriceMinPriceDiffPct > ref.priceStats.currentMinPriceMaxPriceDiffPct\n ) {\n maxDiscount = ref.priceStats.conditionalPriceMinPriceDiffPct;\n const useDate =\n ref.conditionalPrice && ref.conditionalPrice.createdAt ? ref.conditionalPrice.createdAt : ref.extractedAt;\n if (useDate) {\n priceUpdatedAt = new Date(useDate).getTime();\n }\n }\n }\n\n if (maxDiscount === 0 && ref.priceStats.currentPricePrevPriceDiffPct > 0) {\n let hasFakePrevPrice = false;\n\n // Pedidos Ya CL set to only use current price\n if (product.storeRef === '634b4c2ebf4c49e4b3672aba') {\n hasFakePrevPrice = true;\n }\n\n if (!hasFakePrevPrice && (!product.currency || product.currency === CurrencyEnum.CLP)) {\n const minPrevPrice = getMinPrice(ref.previousPrice);\n const minPrevPriceStr = minPrevPrice.toString();\n if (minPrevPrice > 0) {\n if (product.isMarketplace && minPrevPriceStr.endsWith('000')) {\n hasFakePrevPrice = true;\n }\n\n if (minPrevPrice === 9999999 || minPrevPrice === 10000000) {\n hasFakePrevPrice = true;\n }\n } else {\n hasFakePrevPrice = true;\n }\n }\n\n if (!hasFakePrevPrice) {\n maxDiscount = ref.priceStats.currentPricePrevPriceDiffPct;\n }\n }\n\n priceStats = {\n priceStats_pricesCount: ref.priceStats.pricesCount,\n priceStats_avgMinPrice: ref.priceStats.avgMinPrice,\n priceStats_currentMinPrice: ref.priceStats.currentMinPrice,\n priceStats_currentMaxPrice: ref.priceStats.currentMaxPrice,\n priceStats_currentPriceBestPriceDiffPct: ref.priceStats.currentPriceBestPriceDiffPct,\n priceStats_currentPricePrevPriceDiffPct: ref.priceStats.currentPricePrevPriceDiffPct,\n priceStats_currentMinPriceMaxPriceDiffPct: ref.priceStats.currentMinPriceMaxPriceDiffPct,\n priceStats_conditionalPriceMinPriceDiffPct: ref.priceStats.conditionalPriceMinPriceDiffPct || 0,\n priceStats_currentPriceAvgMinPriceDiffPct: ref.priceStats.currentPriceAvgMinPriceDiffPct,\n priceStats_maxDiscountPct: maxDiscount,\n priceStats_pivotPrices: pivotPrices,\n };\n }\n\n // If it doesn't have a price down or relisted or new listing then use current time - 30m to show to all users in web\n let customBucketTimeDate: Date | null = null;\n if (\n !hasUpdateReason(\n [UpdateReasonEnum.PRICE_DOWN, UpdateReasonEnum.RE_LISTING, UpdateReasonEnum.NEW_LISTING],\n product.updateReason,\n )\n ) {\n customBucketTimeDate = new Date(Date.now() - 1000 * 60 * 30);\n }\n\n // TODO: Append inferred categories to ref.categoryKeywordNames\n // TODO: Only append categories found in categoriesEnEsMap\n let foundCategories: string[] = [...(ref.categoryKeywordNames || [])];\n if (!isArrayEmpty(ref.inferredCategories)) {\n ref.inferredCategories.forEach((inferredCategory) => {\n if (getCategoryFacetLabel({ key: inferredCategory })) {\n foundCategories.push(inferredCategory);\n }\n });\n\n // remove CATEGORY_NOT_FOUND\n // as it found inferred categories\n foundCategories = foundCategories.filter((category) => category !== CATEGORY_ENUM.CATEGORY_NOT_FOUND);\n }\n\n const updatedAtDate = new Date(ref.updatedAt || ref.extractedAt || Date.now());\n const bucketData = getBucketTime(customBucketTimeDate || updatedAtDate);\n\n return <ObjectLiteral>{\n id: ref._id,\n ...priceStats,\n storeRef: ref.storeRef,\n storeName: ref.storeName || 'no store name',\n isMarketplace: ref.isMarketplace === true,\n name: ref.name || 'no name',\n sku: ref.sku,\n ean: ref.ean,\n url: ref.url,\n image: ref.image,\n brandName: ref.brandName ? normalizeString(ref.brandName) : undefined,\n sellerName: ref.sellerName,\n // priceStats: priceStats,\n category: ref.category,\n categoryPath: ref.categoryPath,\n price: ref.price,\n bestPrice: ref.bestPrice,\n conditionalPrice: ref.conditionalPrice,\n priceHistory: ref.priceHistory,\n currency: ref.currency || CurrencyEnum.CLP,\n enabled: ref.enabled === true || typeof ref.enabled === 'undefined' || ref.enabled === null,\n categoryKeywordNames: foundCategories, // ref.categoryKeywordNames,\n updateReasons: (ref.updateReason || []).filter((e) => e),\n updatedAt: updatedAtDate.getTime(),\n priceUpdatedAt: priceUpdatedAt,\n bucketTime: bucketData && bucketData.bucketTime ? bucketData.bucketTime : undefined,\n bucketDate: bucketData && bucketData.bucketDate ? bucketData.bucketDate : undefined,\n };\n};\n"]}
@@ -12,3 +12,5 @@ export declare const compareNormalizedText: (str: string, str2: string, options?
12
12
  trim: boolean;
13
13
  lowerCase: boolean;
14
14
  }) => boolean;
15
+ export declare const capitalize: (s: string) => string;
16
+ export declare const normalizeString: (s: string) => string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.compareNormalizedText = exports.normalizeText = exports.includesStringArray = exports.removeIfEndsWith = exports.replaceMultipleSpacesByOne = exports.removeNewLines = exports.getLastAfter = exports.reverseString = void 0;
3
+ exports.normalizeString = exports.capitalize = exports.compareNormalizedText = exports.normalizeText = exports.includesStringArray = exports.removeIfEndsWith = exports.replaceMultipleSpacesByOne = exports.removeNewLines = exports.getLastAfter = exports.reverseString = void 0;
4
4
  const reverseString = (str) => {
5
5
  if (!str) {
6
6
  return null;
@@ -72,4 +72,17 @@ const compareNormalizedText = (str, str2, options = {
72
72
  lowerCase: true,
73
73
  }) => (0, exports.normalizeText)(str, options) === (0, exports.normalizeText)(str2, options);
74
74
  exports.compareNormalizedText = compareNormalizedText;
75
+ const capitalize = (s) => s && String(s[0]).toUpperCase() + String(s.toLowerCase()).slice(1);
76
+ exports.capitalize = capitalize;
77
+ const normalizeString = (s) => {
78
+ if (s) {
79
+ const normalized = (0, exports.capitalize)((0, exports.normalizeText)(s));
80
+ if (normalized === 'Generica') {
81
+ return 'Generico';
82
+ }
83
+ return normalized;
84
+ }
85
+ return s;
86
+ };
87
+ exports.normalizeString = normalizeString;
75
88
  //# sourceMappingURL=string-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"string-utils.js","sourceRoot":"/","sources":["utils/string-utils.ts"],"names":[],"mappings":"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","sourcesContent":["export const reverseString = (str: string): string => {\n if (!str) {\n return null;\n }\n\n return str.split('').reverse().join('');\n};\n\nexport const getLastAfter = (str: string, after: string): string => {\n if (!str) {\n return null;\n }\n\n const reverseSplit = reverseString(str).split(after);\n if (reverseSplit && reverseSplit.length > 0) {\n return reverseString(reverseSplit[0]);\n }\n\n return null;\n};\n\nexport const removeNewLines = (str: string): string => {\n if (!str) {\n return null;\n }\n return str.replace(/\\r?\\n|\\r/g, '');\n};\n\nexport const replaceMultipleSpacesByOne = (str: string): string => {\n if (!str) {\n return null;\n }\n\n return str.replace(/\\s\\s+/g, ' ');\n};\n\nexport const removeIfEndsWith = (str: string, search: string): string => {\n const removedNewLines = removeNewLines(str);\n const trimmed = removedNewLines ? removedNewLines.trim() : null;\n if (trimmed && trimmed.endsWith(search) && trimmed !== search) {\n const reversed = reverseString(str);\n const substr = reversed.substr(reversed.indexOf(search) + 1, reversed.length);\n return reverseString(substr);\n }\n\n return str;\n};\n\nexport const includesStringArray = (str: string, search: string[]): boolean => {\n if (!str || !search) {\n return false;\n }\n\n return !!search.find((s) => str.toLowerCase().includes(s.toLowerCase()));\n};\n\nexport const normalizeText = (str: string, options = { trim: false, lowerCase: false }): string => {\n if (!str) {\n return null;\n }\n\n let normalized = str.normalize('NFD')\n .replace(/([aeio])\\u0301|(u)[\\u0301\\u0308]/gi, '$1$2')\n .normalize();\n\n if (options.trim) {\n normalized = normalized.trim();\n }\n\n if (options.lowerCase) {\n normalized = normalized.toLowerCase();\n }\n\n return normalized;\n};\n\nexport const compareNormalizedText = (str: string, str2: string, options = {\n trim: true,\n lowerCase: true,\n}): boolean => normalizeText(str, options) === normalizeText(str2, options);\n"]}
1
+ {"version":3,"file":"string-utils.js","sourceRoot":"/","sources":["utils/string-utils.ts"],"names":[],"mappings":"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","sourcesContent":["export const reverseString = (str: string): string => {\n if (!str) {\n return null;\n }\n\n return str.split('').reverse().join('');\n};\n\nexport const getLastAfter = (str: string, after: string): string => {\n if (!str) {\n return null;\n }\n\n const reverseSplit = reverseString(str).split(after);\n if (reverseSplit && reverseSplit.length > 0) {\n return reverseString(reverseSplit[0]);\n }\n\n return null;\n};\n\nexport const removeNewLines = (str: string): string => {\n if (!str) {\n return null;\n }\n return str.replace(/\\r?\\n|\\r/g, '');\n};\n\nexport const replaceMultipleSpacesByOne = (str: string): string => {\n if (!str) {\n return null;\n }\n\n return str.replace(/\\s\\s+/g, ' ');\n};\n\nexport const removeIfEndsWith = (str: string, search: string): string => {\n const removedNewLines = removeNewLines(str);\n const trimmed = removedNewLines ? removedNewLines.trim() : null;\n if (trimmed && trimmed.endsWith(search) && trimmed !== search) {\n const reversed = reverseString(str);\n const substr = reversed.substr(reversed.indexOf(search) + 1, reversed.length);\n return reverseString(substr);\n }\n\n return str;\n};\n\nexport const includesStringArray = (str: string, search: string[]): boolean => {\n if (!str || !search) {\n return false;\n }\n\n return !!search.find((s) => str.toLowerCase().includes(s.toLowerCase()));\n};\n\nexport const normalizeText = (str: string, options = { trim: false, lowerCase: false }): string => {\n if (!str) {\n return null;\n }\n\n let normalized = str.normalize('NFD')\n .replace(/([aeio])\\u0301|(u)[\\u0301\\u0308]/gi, '$1$2')\n .normalize();\n\n if (options.trim) {\n normalized = normalized.trim();\n }\n\n if (options.lowerCase) {\n normalized = normalized.toLowerCase();\n }\n\n return normalized;\n};\n\nexport const compareNormalizedText = (str: string, str2: string, options = {\n trim: true,\n lowerCase: true,\n}): boolean => normalizeText(str, options) === normalizeText(str2, options);\n\n\nexport const capitalize = (s: string) => s && String(s[0]).toUpperCase() + String(s.toLowerCase()).slice(1);\n\n// Used in ts parse\nexport const normalizeString = (s: string) => {\n if (s) {\n const normalized = capitalize(normalizeText(s));\n if (normalized === 'Generica') {\n return 'Generico';\n }\n\n return normalized;\n }\n\n return s;\n};\n"]}
@@ -0,0 +1,5 @@
1
+ export declare const getMinutesDiff: (from: number, to: number) => number;
2
+ export declare const getBucketTime: (date: Date) => {
3
+ bucketDate: string;
4
+ bucketTime: string;
5
+ } | null;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getBucketTime = exports.getMinutesDiff = void 0;
4
+ const getMinutesDiff = (from, to) => {
5
+ if (!from || !to) {
6
+ return null;
7
+ }
8
+ const diff = to - from;
9
+ return Math.floor(diff / 1000 / 60);
10
+ };
11
+ exports.getMinutesDiff = getMinutesDiff;
12
+ const MS_5_MINUTES = 1000 * 60 * 5;
13
+ const getBucketTime = (date) => {
14
+ if (!date) {
15
+ return null;
16
+ }
17
+ const strDate = date.toISOString();
18
+ const split = strDate.split('T');
19
+ const d = split[0];
20
+ const roundedDown = new Date(Math.floor(date.getTime() / MS_5_MINUTES) * MS_5_MINUTES);
21
+ const time = roundedDown.toISOString().split('T')[1];
22
+ const timeSplit = time.split(':');
23
+ const bucketTime = `${timeSplit[0]}${timeSplit[1]}`;
24
+ const bucketDate = d.replace(/-/g, '');
25
+ return {
26
+ bucketDate: bucketDate,
27
+ bucketTime: bucketTime,
28
+ };
29
+ };
30
+ exports.getBucketTime = getBucketTime;
31
+ //# sourceMappingURL=time-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time-utils.js","sourceRoot":"/","sources":["utils/time-utils.ts"],"names":[],"mappings":";;;AAAO,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,EAAU,EAAE,EAAE;IACvD,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IAChB,CAAC;IAGD,MAAM,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC;IACvB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC;AACxC,CAAC,CAAC;AARW,QAAA,cAAc,kBAQzB;AAEF,MAAM,YAAY,GAAG,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC;AAC5B,MAAM,aAAa,GAAG,CAAC,IAAU,EAAqD,EAAE;IAC3F,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEjC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnB,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,YAAY,CAAC,GAAG,YAAY,CAAC,CAAC;IACvF,MAAM,IAAI,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAElC,MAAM,UAAU,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,MAAM,UAAU,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAEvC,OAAO;QACH,UAAU,EAAE,UAAU;QACtB,UAAU,EAAE,UAAU;KACzB,CAAC;AACN,CAAC,CAAC;AArBW,QAAA,aAAa,iBAqBxB","sourcesContent":["export const getMinutesDiff = (from: number, to: number) => {\n if (!from || !to) {\n return null;\n }\n\n //const diff = new Date(to).getTime() - new Date(from).getTime();\n const diff = to - from;\n return Math.floor(diff / 1000 / 60);\n};\n\nconst MS_5_MINUTES = 1000 * 60 * 5;\nexport const getBucketTime = (date: Date): { bucketDate: string; bucketTime: string } | null => {\n if (!date) {\n return null;\n }\n\n const strDate = date.toISOString();\n const split = strDate.split('T');\n\n const d = split[0];\n\n const roundedDown = new Date(Math.floor(date.getTime() / MS_5_MINUTES) * MS_5_MINUTES);\n const time = roundedDown.toISOString().split('T')[1];\n const timeSplit = time.split(':');\n\n const bucketTime = `${timeSplit[0]}${timeSplit[1]}`;\n const bucketDate = d.replace(/-/g, '');\n\n return {\n bucketDate: bucketDate,\n bucketTime: bucketTime,\n };\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "store-scrapper-js-common",
3
- "version": "1.0.200",
3
+ "version": "1.0.201",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -16,19 +16,19 @@
16
16
  "dependencies": {
17
17
  "class-validator": "^0.14.1",
18
18
  "lodash": "^4.17.21",
19
- "moment-timezone": "^0.5.46",
19
+ "moment-timezone": "^0.5.47",
20
20
  "rimraf": "^6.0.1",
21
21
  "typeorm": "^0.3.20"
22
22
  },
23
23
  "devDependencies": {
24
- "@eslint/compat": "^1.2.4",
24
+ "@eslint/compat": "^1.2.6",
25
25
  "@eslint/eslintrc": "^3.2.0",
26
- "@eslint/js": "^9.17.0",
26
+ "@eslint/js": "^9.20.0",
27
27
  "@types/jest": "^29.5.14",
28
- "@types/node": "^22.10.2",
28
+ "@types/node": "^22.13.1",
29
29
  "jest": "^29.7.0",
30
- "prettier": "^3.4.2",
30
+ "prettier": "^3.5.0",
31
31
  "ts-jest": "^29.2.5",
32
- "typescript": "^5.7.2"
32
+ "typescript": "^5.7.3"
33
33
  }
34
34
  }
@@ -0,0 +1,273 @@
1
+ export const categoriesEnEsMap: { [key: string]: string } = {
2
+ grocery: 'Supermercado',
3
+ 'grocery/coffee': 'Café',
4
+ 'grocery/cooking oils': 'Aceites para cocinar',
5
+ 'grocery/beverages': 'Bebestibles',
6
+ 'grocery/dairy and eggs': 'Lácteos y huevos',
7
+ 'grocery/breakfast and cereal': 'Desayuno y cereales',
8
+ 'grocery/bakery and bread': 'Panadería y pan',
9
+ 'grocery/baking': 'Repostería',
10
+ 'grocery/snacks': 'Snacks',
11
+ 'grocery/fresh produce': 'Frutas y verduras frescas',
12
+ 'grocery/frozen': 'Congelados',
13
+ 'grocery/pantry': 'Despensa',
14
+ 'grocery/desserts': 'Postres',
15
+ 'grocery/spreads': 'Untables',
16
+ 'grocery/condiments and sauces': 'Condimentos y salsas',
17
+ 'grocery/salt': 'Sal',
18
+ 'grocery/sugars and sweeteners': 'Azúcares y edulcorantes',
19
+ 'grocery/candy': 'Dulces',
20
+ 'grocery/grains and pasta': 'Granos y pasta',
21
+ 'grocery/specialty foods': 'Alimentos especiales',
22
+ 'grocery/meat': 'Carnes',
23
+ 'grocery/seafood': 'Mariscos',
24
+ 'grocery/canned goods': 'Conservas',
25
+ 'grocery/soups': 'Sopas',
26
+ 'grocery/deli': 'Charcutería',
27
+ pharmacy: 'Farmacia',
28
+ 'pharmacy/diet and nutrition': 'Dieta y nutrición',
29
+ 'pharmacy/senior health': 'Salud para adultos mayores',
30
+ 'pharmacy/hygiene': 'Higiene',
31
+ 'pharmacy/medications and treatments': 'Medicamentos y tratamientos',
32
+ 'pharmacy/personal care': 'Cuidado personal',
33
+ 'pharmacy/skin care': 'Cuidado de la piel',
34
+ 'pharmacy/face care': 'Cuidado facial',
35
+ 'pharmacy/foot care': 'Cuidado de los pies',
36
+ 'pharmacy/hair care': 'Cuidado del cabello',
37
+ 'pharmacy/oral care': 'Cuidado bucal',
38
+ 'pharmacy/hand and nail care': 'Cuidado de manos y uñas',
39
+ 'pharmacy/eye care': 'Cuidado de los ojos',
40
+ 'pharmacy/health and wellness': 'Salud y bienestar',
41
+ electronics: 'Electrónica',
42
+ 'electronics/gps and navigation': 'GPS y navegación',
43
+ 'electronics/electronics components': 'Componentes electrónicos',
44
+ 'electronics/diy electronics': 'Electrónica DIY',
45
+ 'electronics/electronics kits': 'Kits electrónicos',
46
+ 'electronics/cryptocurrency': 'Criptomonedas',
47
+ 'electronics/drones': 'Drones',
48
+ 'electronics/vr devices': 'Dispositivos de realidad virtual',
49
+ 'electronics/power supplies': 'Fuentes de alimentación',
50
+ 'electronics/networking': 'Redes',
51
+ 'electronics/portable fans': 'Ventiladores portátiles',
52
+ 'electronics/remote controls': 'Controles remotos',
53
+ 'electronics/universal remotes': 'Controles remotos universales',
54
+ 'electronics/smart home': 'Hogar inteligente',
55
+ 'electronics/telephones': 'Teléfonos',
56
+ 'electronics/mobile phones': 'Teléfonos móviles',
57
+ 'electronics/photography': 'Fotografía',
58
+ 'electronics/wearable technology': 'Tecnología vestible',
59
+ 'electronics/computers': 'Computadoras',
60
+ 'electronics/data storage': 'Almacenamiento de datos',
61
+ 'electronics/scanners': 'Escáneres',
62
+ 'electronics/printers': 'Impresoras',
63
+ 'electronics/video games': 'Videojuegos',
64
+ 'electronics/televisions': 'Televisores',
65
+ 'electronics/audio': 'Audio',
66
+ 'electronics/projectors': 'Proyectores',
67
+ 'electronics/outdoor electronics and gadgets': 'Electrónica y gadgets para exteriores',
68
+ appliances: 'Electrodomésticos',
69
+ 'appliances/appliance parts': 'Repuestos de electrodomésticos',
70
+ 'appliances/consumer electronics': 'Electrónica de consumo',
71
+ 'appliances/small appliances': 'Electrodomésticos pequeños',
72
+ 'appliances/specialty appliances': 'Electrodomésticos especiales',
73
+ 'appliances/kitchen appliances': 'Electrodomésticos de cocina',
74
+ 'appliances/heaters': 'Calefactores',
75
+ 'appliances/white goods': 'Línea blanca',
76
+ 'appliances/cooling appliances': 'Electrodomésticos de refrigeración',
77
+ 'appliances/cleaning appliances': 'Electrodomésticos de limpieza',
78
+ 'appliances/personal care appliances': 'Electrodomésticos de cuidado personal',
79
+ beauty: 'Belleza',
80
+ 'beauty/sun care and tanning': 'Cuidado solar y bronceado',
81
+ 'beauty/fragrance': 'Fragancias',
82
+ 'beauty/skin care': 'Cuidado de la piel',
83
+ 'beauty/face care': 'Cuidado facial',
84
+ 'beauty/eye care': 'Cuidado de los ojos',
85
+ 'beauty/foot care': 'Cuidado de los pies',
86
+ 'beauty/hair care': 'Cuidado del cabello',
87
+ 'beauty/bath and body': 'Baño y cuerpo',
88
+ 'beauty/hand and nail care': 'Cuidado de manos y uñas',
89
+ 'beauty/oral care': 'Cuidado bucal',
90
+ 'beauty/makeup': 'Maquillaje',
91
+ 'beauty/shaving and grooming': 'Afeitado y aseo personal',
92
+ fashion: 'Moda',
93
+ 'fashion/fashion accessories': 'Accesorios de moda',
94
+ 'fashion/eyewear': 'Gafas',
95
+ 'fashion/clothing': 'Ropa',
96
+ 'fashion/shoes': 'Calzado',
97
+ sports: 'Deportes',
98
+ 'sports/water sports': 'Deportes acuáticos',
99
+ 'sports/winter sports': 'Deportes de invierno',
100
+ 'sports/outdoor sports': 'Deportes al aire libre',
101
+ 'sports/table tennis': 'Tenis de mesa',
102
+ 'sports/tennis': 'Tenis',
103
+ 'sports/padel': 'Pádel',
104
+ 'sports/basketball': 'Baloncesto',
105
+ 'sports/soccer': 'Fútbol',
106
+ 'sports/scooters': 'Patinetes',
107
+ 'sports/roller skates': 'Patines',
108
+ 'sports/inline skates': 'Patines en línea',
109
+ 'sports/skateboarding': 'Skateboarding',
110
+ 'sports/bowling': 'Bolos',
111
+ 'sports/handball': 'Balonmano',
112
+ 'sports/martial arts': 'Artes marciales',
113
+ 'sports/boxing': 'Boxeo',
114
+ 'sports/cycling': 'Ciclismo',
115
+ 'sports/fitness': 'Fitness',
116
+ 'sports/camping and hiking': 'Camping y senderismo',
117
+ home: 'Hogar',
118
+ 'home/home decor': 'Decoración del hogar',
119
+ 'home/home improvement': 'Mejoras para el hogar',
120
+ 'home/furniture': 'Muebles',
121
+ 'home/bedroom': 'Dormitorio',
122
+ 'home/household supplies': 'Artículos para el hogar',
123
+ 'home/luggage and travel': 'Equipaje y viajes',
124
+ 'home/bathroom': 'Baño',
125
+ 'home/laundry': 'Lavandería',
126
+ 'home/kitchen': 'Cocina',
127
+ 'home/patio and garden': 'Patio y jardín',
128
+ outdoor: 'Exterior',
129
+ 'outdoor/camping and hiking': 'Camping y senderismo',
130
+ 'outdoor/outdoor clothing': 'Ropa para exteriores',
131
+ 'outdoor/outdoor electronics and gadgets': 'Electrónica y gadgets para exteriores',
132
+ 'outdoor/outdoor sports': 'Deportes al aire libre',
133
+ 'outdoor/outdoor lighting': 'Iluminación exterior',
134
+ 'outdoor/outdoor heating': 'Calefacción exterior',
135
+ 'outdoor/swimming pools': 'Piscinas',
136
+ 'outdoor/outdoor furniture': 'Muebles de exterior',
137
+ 'outdoor/awnings and canopies': 'Toldos y marquesinas',
138
+ music: 'Música',
139
+ 'music/vinyl': 'Vinilos',
140
+ 'music/microphones': 'Micrófonos',
141
+ 'music/musical instruments': 'Instrumentos musicales',
142
+ books: 'Libros',
143
+ 'books/user guides and manuals': 'Guías de usuario y manuales',
144
+ 'books/technology books': 'Libros de tecnología',
145
+ 'books/spiritual books': 'Libros espirituales',
146
+ "books/children's books": 'Libros infantiles',
147
+ 'books/non-fiction books': 'Libros de no ficción',
148
+ 'books/fiction books': 'Libros de ficción',
149
+ 'books/academic books': 'Libros académicos',
150
+ 'books/specialty books': 'Libros especializados',
151
+ 'books/crime and thriller books': 'Libros de crimen y suspense',
152
+ 'books/horror books': 'Libros de terror',
153
+ 'books/comedy books': 'Libros de comedia',
154
+ 'books/romance books': 'Libros de romance',
155
+ 'books/reference books': 'Libros de referencia',
156
+ 'books/textbooks': 'Libros de texto',
157
+ 'books/study guides': 'Guías de estudio',
158
+ 'books/educational magazines': 'Revistas educativas',
159
+ 'books/history books': 'Libros de historia',
160
+ 'books/self-help books': 'Libros de autoayuda',
161
+ 'books/politics books': 'Libros de política',
162
+ 'books/health and wellness books': 'Libros de salud y bienestar',
163
+ 'books/business and economics books': 'Libros de negocios y economía',
164
+ 'books/comics and graphics novels': 'Cómics y novelas gráficas',
165
+ 'books/book accessories': 'Accesorios para libros',
166
+ kids: 'Niños',
167
+ 'kids/kids clothing': 'Ropa infantil',
168
+ 'kids/kids shoes': 'Calzado infantil',
169
+ 'kids/kids accessories': 'Accesorios infantiles',
170
+ 'kids/toys and games': 'Juguetes y juegos',
171
+ 'kids/party decorations': 'Decoraciones para fiestas infantiles',
172
+ 'kids/party supplies': 'Artículos para fiestas infantiles',
173
+ 'kids/school': 'Escuela',
174
+ 'kids/baby': 'Bebé',
175
+ pets: 'Mascotas',
176
+ 'pets/pet supplies': 'Artículos para mascotas',
177
+ 'pets/pet care': 'Cuidado de mascotas',
178
+ 'pets/pet accessories': 'Accesorios para mascotas',
179
+ 'pets/pet toys': 'Juguetes para mascotas',
180
+ 'pets/pet furniture': 'Muebles para mascotas',
181
+ 'pets/aquariums': 'Acuarios',
182
+ 'pets/pet habitats and pet cages': 'Hábitats y jaulas para mascotas',
183
+ office: 'Oficina',
184
+ 'office/office technology': 'Tecnología de oficina',
185
+ 'office/office lighting': 'Iluminación de oficina',
186
+ 'office/office decor': 'Decoración de oficina',
187
+ 'office/office furniture': 'Muebles de oficina',
188
+ 'office/office cleaning and office maintenance': 'Mantenimiento de oficina',
189
+ 'office/office meeting and presentation': 'Reuniones y presentaciones de oficina',
190
+ 'office/safety and security': 'Seguridad de oficina',
191
+ 'office/office supplies': 'Artículos de oficina',
192
+ 'office/office breakroom': 'Sala de descanso de oficina',
193
+ automotive: 'Automotriz',
194
+ 'automotive/vehicles': 'Vehículos',
195
+ 'party and entertainment': 'Fiestas y entretenimiento',
196
+ 'party and entertainment/party supplies': 'Artículos para fiestas',
197
+ 'party and entertainment/entertainment supplies': 'Artículos de entretenimiento',
198
+ 'party and entertainment/party electronics': 'Electrónica para fiestas',
199
+ 'party and entertainment/party planning': 'Planificación de fiestas',
200
+ services: 'Servicios',
201
+ 'services/installation and maintenance services': 'Servicios de instalación y mantenimiento',
202
+ 'services/warranties and protection plans': 'Garantías y planes de protección',
203
+ 'services/travel services': 'Servicios de viajes',
204
+
205
+ 'grocery/beverages/alcoholic beverages': 'Bebidas alcohólicas',
206
+ 'grocery/beverages/alcoholic beverages/beer': 'Cervezas',
207
+ 'grocery/beverages/alcoholic beverages/wine': 'Vinos',
208
+ 'grocery/beverages/alcoholic beverages/sparkling wine': 'Espumantes',
209
+ 'grocery/beverages/alcoholic beverages/whisky': 'Whisky',
210
+ 'grocery/beverages/alcoholic beverages/vodka': 'Vodka',
211
+ 'grocery/beverages/alcoholic beverages/gin': 'Gin',
212
+ 'grocery/beverages/alcoholic beverages/tequila': 'Tequila',
213
+ 'grocery/beverages/alcoholic beverages/cognac': 'Cognac',
214
+ 'grocery/beverages/alcoholic beverages/rum': 'Ron',
215
+ 'grocery/beverages/alcoholic beverages/brandy': 'Brandy',
216
+ 'grocery/beverages/alcoholic beverages/cocktails': 'Cocktails',
217
+ 'grocery/beverages/alcoholic beverages/cider': 'Sidra',
218
+ 'grocery/beverages/alcoholic beverages/pisco': 'Pisco',
219
+ 'grocery/beverages/alcoholic beverages/liqueurs': 'Licores',
220
+
221
+ 'electronics/video games/nintendo': 'Nintendo',
222
+ 'electronics/video games/xbox': 'Xbox',
223
+ 'electronics/video games/playstation': 'Playstation',
224
+ 'home/kitchen/kitchen appliances/coffee machines': 'Cafeteras',
225
+ 'appliances/white goods/refrigeration appliances/refrigerators': 'Refrigeradores',
226
+ 'appliances/white goods/refrigeration appliances/freezers': 'Congeladores',
227
+ 'appliances/white goods/dishwashing appliances/dishwashers': 'Lavavajillas',
228
+ 'home/laundry/laundry appliances/washing machines': 'Lavadoras',
229
+ 'home/laundry/laundry appliances/dryers machines': 'Secadoras',
230
+ 'home/laundry/laundry appliances/washer-dryer combos': 'Lavadora-secadora combo',
231
+ 'home/kitchen/kitchen appliances/ranges': 'Cocinas',
232
+ 'home/kitchen/kitchen appliances/ovens': 'Hornos',
233
+ 'home/kitchen/kitchen appliances/cooktops': 'Encimeras',
234
+ 'outdoor/swimming pools/hot tubs and spa': 'Jacuzzis y spas',
235
+ 'home/home decor/seasonal decor/holiday decorations/christmas decorations': 'Decoraciones navideñas',
236
+ 'home/home decor/seasonal decor/holiday decorations/christmas decorations/christmas trees': 'Árboles de Navidad',
237
+ 'electronics/photography/cameras': 'Cámaras',
238
+ 'electronics/audio/speakers': 'Parlantes',
239
+ 'appliances/heaters/electric heaters': 'Calefactores eléctricos',
240
+ 'sports/fitness/cardio equipment': 'Equipos de cardio',
241
+ 'sports/fitness/strength training': 'Equipos de entrenamiento de fuerza',
242
+ 'pharmacy/health and wellness/vitamins and supplements': 'Vitaminas y suplementos',
243
+ 'pharmacy/health and wellness/vitamins and supplements/sports nutrition': 'Nutrición deportiva',
244
+ 'fashion/fashion accessories/sunglasses': 'Gafas de sol',
245
+ 'beauty/sun care and tanning/sunscreen': 'Protector solar',
246
+ 'sports/cycling/bicycles': 'Bicicletas',
247
+ 'home/home improvement/building materials': 'Materiales de construcción',
248
+ 'home/home improvement/tools and equipment': 'Herramientas y equipos',
249
+ 'home/home improvement/tools and equipment/power tools': 'Herramientas eléctricas',
250
+ 'home/home improvement/tools and equipment/electrical tools/soldering and welding tools': 'Herramientas de soldadura',
251
+ 'appliances/cooling appliances/air conditioners': 'Aire acondicionado',
252
+ 'electronics/mobile phones/smartphones': 'Smartphones',
253
+ 'electronics/televisions/smart tv': 'Smart TV',
254
+ 'electronics/computers/laptops': 'Notebooks',
255
+ 'electronics/computers/laptops/gaming laptops': 'Notebooks gamer',
256
+ 'electronics/computers/e-reader': 'E-Readers',
257
+ 'electronics/wearable technology/smartwatches': 'Smartwatches',
258
+ 'electronics/audio/headphones': 'Auriculares',
259
+ 'home/furniture/bedroom furniture/beds': 'Camas',
260
+ 'home/furniture/bedroom furniture/mattresses': 'Colchones',
261
+ };
262
+
263
+ export const getCategoryFacetLabel = ({ key, lang }: { key: string; lang?: string }): string | null => {
264
+ const language = lang || 'es-CL';
265
+
266
+ if (key) {
267
+ if (language === 'es-CL') {
268
+ return categoriesEnEsMap[key];
269
+ }
270
+ }
271
+
272
+ return null;
273
+ };
@@ -16,13 +16,13 @@ import {
16
16
  import {
17
17
  hasElementInArray, isArrayEmpty, stringToArray, getRandomItem,
18
18
  } from './array-utils';
19
- import { hasUpdateReason, getStoreName } from './product.utils';
19
+ import { hasUpdateReason, getStoreName, parseProductDtoToTypesenseDocument } from './product.utils';
20
20
  import { formatDate, formatMoney, formatPct } from './string-formatter';
21
21
 
22
22
  export {
23
23
  checkIfSamePrices, findLastQuery, replaceMultipleSpacesByOne, hasMeasurementUnitMultiplier, getPriceByMeasurementUnitMultiplier,
24
24
  removeIfEndsWith, getLastAfter, includesStringArray, removeNewLines, reverseString, getParam, getPathname,
25
25
  getHostname, isUrl, isValidPrice, getMinPrice, isCheaper, getMaxPrice, getPriceOperation, getAvgPrice, calculateAverage,
26
- roundNumber, removeZeroPrices, isArrayEmpty, hasElementInArray, stringToArray, hasUpdateReason, getStoreName,
26
+ roundNumber, removeZeroPrices, isArrayEmpty, hasElementInArray, stringToArray, hasUpdateReason, getStoreName, parseProductDtoToTypesenseDocument,
27
27
  formatPct, formatDate, formatMoney, getRandomNumber, getRandomNumbers, getPercentageDiff, getRandomItem,
28
28
  };
@@ -1,5 +1,10 @@
1
- import { hasElementInArray } from './array-utils';
2
- import { Product, Store, UpdateReasonEnum } from '../entities';
1
+ import {hasElementInArray, isArrayEmpty} from './array-utils';
2
+ import {CATEGORY_ENUM, CurrencyEnum, Product, Store, UpdateReasonEnum} from '../entities';
3
+ import {ObjectLiteral} from "../classes";
4
+ import {getMinPrice} from "./price-utils";
5
+ import {getCategoryFacetLabel} from "./facet-categories-map";
6
+ import {getBucketTime} from "./time-utils";
7
+ import {normalizeString} from "./string-utils";
3
8
 
4
9
  export const getStoreName = (product: Product, stores: Store[]): string => {
5
10
  if ((!stores || stores.length === 0) && product) {
@@ -16,3 +21,148 @@ export const getStoreName = (product: Product, stores: Store[]): string => {
16
21
  };
17
22
 
18
23
  export const hasUpdateReason = (enums: UpdateReasonEnum[], search: UpdateReasonEnum[]): boolean => hasElementInArray<UpdateReasonEnum>(enums, search);
24
+
25
+ export const parseProductDtoToTypesenseDocument = (product: Product): ObjectLiteral => {
26
+ if (!product) {
27
+ return null;
28
+ }
29
+
30
+ const ref: Product = JSON.parse(JSON.stringify(product));
31
+
32
+ let priceStats = null;
33
+
34
+ let priceUpdatedAt = new Date(
35
+ ref.price.updatedAt || ref.price.createdAt || ref.extractedAt || ref.updatedAt,
36
+ ).getTime();
37
+
38
+ if (ref.priceStats) {
39
+ // TODO: Search how to look for specific pivot prices in Typesense search
40
+ // Slice 3 pivot prices
41
+ const pivotPrices = (ref.priceStats.pivotPrices || []).slice(0, 3);
42
+
43
+ // Add max discount single field
44
+ // Prioritize Current Offer and Conditional Price
45
+ // If neither of those exists then use previous price
46
+ let maxDiscount = 0;
47
+ if (ref.priceStats.currentMinPriceMaxPriceDiffPct > 0) {
48
+ maxDiscount = ref.priceStats.currentMinPriceMaxPriceDiffPct;
49
+ }
50
+
51
+ // TODO: Was updated to use currentMaxPrice, update or create a new field
52
+ if (ref.priceStats.conditionalPriceMinPriceDiffPct) {
53
+ if (
54
+ maxDiscount === 0 ||
55
+ ref.priceStats.conditionalPriceMinPriceDiffPct > ref.priceStats.currentMinPriceMaxPriceDiffPct
56
+ ) {
57
+ maxDiscount = ref.priceStats.conditionalPriceMinPriceDiffPct;
58
+ const useDate =
59
+ ref.conditionalPrice && ref.conditionalPrice.createdAt ? ref.conditionalPrice.createdAt : ref.extractedAt;
60
+ if (useDate) {
61
+ priceUpdatedAt = new Date(useDate).getTime();
62
+ }
63
+ }
64
+ }
65
+
66
+ if (maxDiscount === 0 && ref.priceStats.currentPricePrevPriceDiffPct > 0) {
67
+ let hasFakePrevPrice = false;
68
+
69
+ // Pedidos Ya CL set to only use current price
70
+ if (product.storeRef === '634b4c2ebf4c49e4b3672aba') {
71
+ hasFakePrevPrice = true;
72
+ }
73
+
74
+ if (!hasFakePrevPrice && (!product.currency || product.currency === CurrencyEnum.CLP)) {
75
+ const minPrevPrice = getMinPrice(ref.previousPrice);
76
+ const minPrevPriceStr = minPrevPrice.toString();
77
+ if (minPrevPrice > 0) {
78
+ if (product.isMarketplace && minPrevPriceStr.endsWith('000')) {
79
+ hasFakePrevPrice = true;
80
+ }
81
+
82
+ if (minPrevPrice === 9999999 || minPrevPrice === 10000000) {
83
+ hasFakePrevPrice = true;
84
+ }
85
+ } else {
86
+ hasFakePrevPrice = true;
87
+ }
88
+ }
89
+
90
+ if (!hasFakePrevPrice) {
91
+ maxDiscount = ref.priceStats.currentPricePrevPriceDiffPct;
92
+ }
93
+ }
94
+
95
+ priceStats = {
96
+ priceStats_pricesCount: ref.priceStats.pricesCount,
97
+ priceStats_avgMinPrice: ref.priceStats.avgMinPrice,
98
+ priceStats_currentMinPrice: ref.priceStats.currentMinPrice,
99
+ priceStats_currentMaxPrice: ref.priceStats.currentMaxPrice,
100
+ priceStats_currentPriceBestPriceDiffPct: ref.priceStats.currentPriceBestPriceDiffPct,
101
+ priceStats_currentPricePrevPriceDiffPct: ref.priceStats.currentPricePrevPriceDiffPct,
102
+ priceStats_currentMinPriceMaxPriceDiffPct: ref.priceStats.currentMinPriceMaxPriceDiffPct,
103
+ priceStats_conditionalPriceMinPriceDiffPct: ref.priceStats.conditionalPriceMinPriceDiffPct || 0,
104
+ priceStats_currentPriceAvgMinPriceDiffPct: ref.priceStats.currentPriceAvgMinPriceDiffPct,
105
+ priceStats_maxDiscountPct: maxDiscount,
106
+ priceStats_pivotPrices: pivotPrices,
107
+ };
108
+ }
109
+
110
+ // If it doesn't have a price down or relisted or new listing then use current time - 30m to show to all users in web
111
+ let customBucketTimeDate: Date | null = null;
112
+ if (
113
+ !hasUpdateReason(
114
+ [UpdateReasonEnum.PRICE_DOWN, UpdateReasonEnum.RE_LISTING, UpdateReasonEnum.NEW_LISTING],
115
+ product.updateReason,
116
+ )
117
+ ) {
118
+ customBucketTimeDate = new Date(Date.now() - 1000 * 60 * 30);
119
+ }
120
+
121
+ // TODO: Append inferred categories to ref.categoryKeywordNames
122
+ // TODO: Only append categories found in categoriesEnEsMap
123
+ let foundCategories: string[] = [...(ref.categoryKeywordNames || [])];
124
+ if (!isArrayEmpty(ref.inferredCategories)) {
125
+ ref.inferredCategories.forEach((inferredCategory) => {
126
+ if (getCategoryFacetLabel({ key: inferredCategory })) {
127
+ foundCategories.push(inferredCategory);
128
+ }
129
+ });
130
+
131
+ // remove CATEGORY_NOT_FOUND
132
+ // as it found inferred categories
133
+ foundCategories = foundCategories.filter((category) => category !== CATEGORY_ENUM.CATEGORY_NOT_FOUND);
134
+ }
135
+
136
+ const updatedAtDate = new Date(ref.updatedAt || ref.extractedAt || Date.now());
137
+ const bucketData = getBucketTime(customBucketTimeDate || updatedAtDate);
138
+
139
+ return <ObjectLiteral>{
140
+ id: ref._id,
141
+ ...priceStats,
142
+ storeRef: ref.storeRef,
143
+ storeName: ref.storeName || 'no store name',
144
+ isMarketplace: ref.isMarketplace === true,
145
+ name: ref.name || 'no name',
146
+ sku: ref.sku,
147
+ ean: ref.ean,
148
+ url: ref.url,
149
+ image: ref.image,
150
+ brandName: ref.brandName ? normalizeString(ref.brandName) : undefined,
151
+ sellerName: ref.sellerName,
152
+ // priceStats: priceStats,
153
+ category: ref.category,
154
+ categoryPath: ref.categoryPath,
155
+ price: ref.price,
156
+ bestPrice: ref.bestPrice,
157
+ conditionalPrice: ref.conditionalPrice,
158
+ priceHistory: ref.priceHistory,
159
+ currency: ref.currency || CurrencyEnum.CLP,
160
+ enabled: ref.enabled === true || typeof ref.enabled === 'undefined' || ref.enabled === null,
161
+ categoryKeywordNames: foundCategories, // ref.categoryKeywordNames,
162
+ updateReasons: (ref.updateReason || []).filter((e) => e),
163
+ updatedAt: updatedAtDate.getTime(),
164
+ priceUpdatedAt: priceUpdatedAt,
165
+ bucketTime: bucketData && bucketData.bucketTime ? bucketData.bucketTime : undefined,
166
+ bucketDate: bucketData && bucketData.bucketDate ? bucketData.bucketDate : undefined,
167
+ };
168
+ };
@@ -78,3 +78,20 @@ export const compareNormalizedText = (str: string, str2: string, options = {
78
78
  trim: true,
79
79
  lowerCase: true,
80
80
  }): boolean => normalizeText(str, options) === normalizeText(str2, options);
81
+
82
+
83
+ export const capitalize = (s: string) => s && String(s[0]).toUpperCase() + String(s.toLowerCase()).slice(1);
84
+
85
+ // Used in ts parse
86
+ export const normalizeString = (s: string) => {
87
+ if (s) {
88
+ const normalized = capitalize(normalizeText(s));
89
+ if (normalized === 'Generica') {
90
+ return 'Generico';
91
+ }
92
+
93
+ return normalized;
94
+ }
95
+
96
+ return s;
97
+ };
@@ -0,0 +1,33 @@
1
+ export const getMinutesDiff = (from: number, to: number) => {
2
+ if (!from || !to) {
3
+ return null;
4
+ }
5
+
6
+ //const diff = new Date(to).getTime() - new Date(from).getTime();
7
+ const diff = to - from;
8
+ return Math.floor(diff / 1000 / 60);
9
+ };
10
+
11
+ const MS_5_MINUTES = 1000 * 60 * 5;
12
+ export const getBucketTime = (date: Date): { bucketDate: string; bucketTime: string } | null => {
13
+ if (!date) {
14
+ return null;
15
+ }
16
+
17
+ const strDate = date.toISOString();
18
+ const split = strDate.split('T');
19
+
20
+ const d = split[0];
21
+
22
+ const roundedDown = new Date(Math.floor(date.getTime() / MS_5_MINUTES) * MS_5_MINUTES);
23
+ const time = roundedDown.toISOString().split('T')[1];
24
+ const timeSplit = time.split(':');
25
+
26
+ const bucketTime = `${timeSplit[0]}${timeSplit[1]}`;
27
+ const bucketDate = d.replace(/-/g, '');
28
+
29
+ return {
30
+ bucketDate: bucketDate,
31
+ bucketTime: bucketTime,
32
+ };
33
+ };
@@ -18,4 +18,5 @@ describe('product utils spec', () => {
18
18
  ),
19
19
  ).toStrictEqual(true);
20
20
  });
21
+
21
22
  });