/
re.places.algolia.sw.js
106 lines (91 loc) · 2.64 KB
/
re.places.algolia.sw.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
const coreUrl = 'https://cdn.jsdelivr.net/npm/re.places.js@0.1.3/src/re.places.core.js';
self.importScripts(coreUrl);
const errorResponse = message =>
JSON.stringify({
message,
status: 403,
});
self.addEventListener('activate', (event) => {
self.clients.claim()
});
self.addEventListener('fetch', async (e) => {
const is_algolia_places_request = e.request.url.includes('algolia')
&& (e.request.url.includes('places/query') || e.request.url.includes('indexes/places'));
if (!is_algolia_places_request) {
return e.respondWith(fetch(e.request));
}
const response = e.request.json().then(({ params }) => {
const queryParams = Object.fromEntries(new URLSearchParams(params));
const paramsKeys = [
'countries',
'aroundLatLngViaIP',
'aroundLatLng',
'aroundRadius',
'insideBoundingBox',
'insidePolygon',
'hitsPerPage',
];
for (const key of paramsKeys) {
// only let truthy values through
if (queryParams[key]) {
let val = queryParams[key];
if (key === 'countries') {
val = JSON.parse(val);
} else if (key === 'aroundLatLngViaIP') {
val = val === 'true';
} else if (!isNaN(val)) {
val = +val;
}
queryParams[key] = val;
}
}
// run the search
// second parameter advises not to return null responses
return replaces.search(queryParams, true);
})
.then((response) => {
// remove non-algolia fields
delete response.fetchTimeMS;
delete response.paramsData;
// add missing fields
response.degradedQuery = false;
for (const hit of response.hits) {
Object.assign(hit, {
objectID: hit.id,
_tags: [
'city',
`country/${hit.iso2}`,
'place/city',
'source/simplemaps.com',
],
country_code: hit.iso2,
is_city: true,
administrative: [hit.admin],
locale_names: [hit.city],
_geoloc: {
lat: hit.lat,
lng: hit.lng,
},
_highlightResult: {
country: hit._highlightResult.country,
administrative: hit._highlightResult.admin,
locale_names: hit._highlightResult.city,
},
});
// remove non-algolia fields
delete hit.admin;
delete hit.city;
delete hit.lat;
delete hit.lng;
delete hit.score;
delete hit.match;
delete hit.iso2;
delete hit.boost;
delete hit.terms;
delete hit.id;
}
return new Response(JSON.stringify(response));
})
.catch(error => new Response(errorResponse(error.message)));
e.respondWith(response);
});