rendezvous-kit 1.20.1 → 1.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engines/graphhopper.d.ts +5 -0
- package/dist/engines/graphhopper.d.ts.map +1 -1
- package/dist/engines/graphhopper.js +15 -6
- package/dist/engines/graphhopper.js.map +1 -1
- package/dist/engines/openrouteservice.d.ts +3 -0
- package/dist/engines/openrouteservice.d.ts.map +1 -1
- package/dist/engines/openrouteservice.js +14 -7
- package/dist/engines/openrouteservice.js.map +1 -1
- package/dist/engines/osrm.d.ts +2 -0
- package/dist/engines/osrm.d.ts.map +1 -1
- package/dist/engines/osrm.js +7 -4
- package/dist/engines/osrm.js.map +1 -1
- package/dist/engines/valhalla.d.ts.map +1 -1
- package/dist/engines/valhalla.js +8 -7
- package/dist/engines/valhalla.js.map +1 -1
- package/dist/rendezvous.d.ts.map +1 -1
- package/dist/rendezvous.js +23 -30
- package/dist/rendezvous.js.map +1 -1
- package/dist/validate.d.ts +7 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +28 -0
- package/dist/validate.js.map +1 -0
- package/dist/venues.d.ts +1 -1
- package/dist/venues.d.ts.map +1 -1
- package/dist/venues.js +14 -4
- package/dist/venues.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,6 +6,9 @@ import type { RoutingEngine, Isochrone, RouteMatrix, RouteGeometry, TransportMod
|
|
|
6
6
|
* API key is optional for self-hosted deployments.
|
|
7
7
|
* Note: GraphHopper does not natively support `public_transit` — falls back to driving.
|
|
8
8
|
*
|
|
9
|
+
* Note: When using the cloud API, the API key is sent as a query parameter (`key=...`)
|
|
10
|
+
* as required by the GraphHopper API. Be aware this may appear in server access logs.
|
|
11
|
+
*
|
|
9
12
|
* @example
|
|
10
13
|
* ```typescript
|
|
11
14
|
* const engine = new GraphHopperEngine({ baseUrl: 'http://localhost:8989' })
|
|
@@ -15,9 +18,11 @@ export declare class GraphHopperEngine implements RoutingEngine {
|
|
|
15
18
|
readonly name = "GraphHopper";
|
|
16
19
|
private readonly baseUrl;
|
|
17
20
|
private readonly apiKey?;
|
|
21
|
+
private readonly timeoutMs;
|
|
18
22
|
constructor(config: {
|
|
19
23
|
baseUrl: string;
|
|
20
24
|
apiKey?: string;
|
|
25
|
+
timeoutMs?: number;
|
|
21
26
|
});
|
|
22
27
|
private params;
|
|
23
28
|
computeIsochrone(origin: LatLon, mode: TransportMode, timeMinutes: number): Promise<Isochrone>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphhopper.d.ts","sourceRoot":"","sources":["../../src/engines/graphhopper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EACpD,aAAa,EAAE,MAAM,EACtB,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"graphhopper.d.ts","sourceRoot":"","sources":["../../src/engines/graphhopper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EACpD,aAAa,EAAE,MAAM,EACtB,MAAM,aAAa,CAAA;AAUpB;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iBAAkB,YAAW,aAAa;IACrD,QAAQ,CAAC,IAAI,iBAAgB;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;gBAEtB,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;IAM5E,OAAO,CAAC,MAAM;IAMR,gBAAgB,CACpB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,aAAa,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,SAAS,CAAC;IAqBf,kBAAkB,CACtB,OAAO,EAAE,MAAM,EAAE,EACjB,YAAY,EAAE,MAAM,EAAE,EACtB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC;IAyCjB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CAGxG"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { validateHttpUrl, safeJson, truncateBody } from '../validate.js';
|
|
1
2
|
const PROFILE = {
|
|
2
3
|
drive: 'car',
|
|
3
4
|
cycle: 'bike',
|
|
@@ -11,6 +12,9 @@ const PROFILE = {
|
|
|
11
12
|
* API key is optional for self-hosted deployments.
|
|
12
13
|
* Note: GraphHopper does not natively support `public_transit` — falls back to driving.
|
|
13
14
|
*
|
|
15
|
+
* Note: When using the cloud API, the API key is sent as a query parameter (`key=...`)
|
|
16
|
+
* as required by the GraphHopper API. Be aware this may appear in server access logs.
|
|
17
|
+
*
|
|
14
18
|
* @example
|
|
15
19
|
* ```typescript
|
|
16
20
|
* const engine = new GraphHopperEngine({ baseUrl: 'http://localhost:8989' })
|
|
@@ -20,9 +24,11 @@ export class GraphHopperEngine {
|
|
|
20
24
|
name = 'GraphHopper';
|
|
21
25
|
baseUrl;
|
|
22
26
|
apiKey;
|
|
27
|
+
timeoutMs;
|
|
23
28
|
constructor(config) {
|
|
24
|
-
this.baseUrl = config.baseUrl
|
|
29
|
+
this.baseUrl = validateHttpUrl(config.baseUrl, 'GraphHopperEngine baseUrl');
|
|
25
30
|
this.apiKey = config.apiKey;
|
|
31
|
+
this.timeoutMs = config.timeoutMs ?? 30_000;
|
|
26
32
|
}
|
|
27
33
|
params(extra) {
|
|
28
34
|
const p = new URLSearchParams(extra);
|
|
@@ -36,12 +42,14 @@ export class GraphHopperEngine {
|
|
|
36
42
|
time_limit: String(timeMinutes * 60),
|
|
37
43
|
profile: PROFILE[mode],
|
|
38
44
|
});
|
|
39
|
-
const res = await fetch(`${this.baseUrl}/isochrone?${qs}
|
|
45
|
+
const res = await fetch(`${this.baseUrl}/isochrone?${qs}`, {
|
|
46
|
+
signal: AbortSignal.timeout(this.timeoutMs),
|
|
47
|
+
});
|
|
40
48
|
if (!res.ok) {
|
|
41
49
|
const text = await res.text().catch(() => '');
|
|
42
|
-
throw new Error(`GraphHopper isochrone error: ${res.status} — ${text}`);
|
|
50
|
+
throw new Error(`GraphHopper isochrone error: ${res.status} — ${truncateBody(text)}`);
|
|
43
51
|
}
|
|
44
|
-
const data =
|
|
52
|
+
const data = await safeJson(res, 'GraphHopper isochrone');
|
|
45
53
|
if (!data.polygons?.length)
|
|
46
54
|
throw new Error('GraphHopper returned no polygons');
|
|
47
55
|
return { origin, mode, timeMinutes, polygon: data.polygons[0].geometry };
|
|
@@ -59,13 +67,14 @@ export class GraphHopperEngine {
|
|
|
59
67
|
method: 'POST',
|
|
60
68
|
headers: { 'Content-Type': 'application/json' },
|
|
61
69
|
body: JSON.stringify(body),
|
|
70
|
+
signal: AbortSignal.timeout(this.timeoutMs),
|
|
62
71
|
});
|
|
63
72
|
if (!res.ok) {
|
|
64
73
|
const text = await res.text().catch(() => '');
|
|
65
|
-
throw new Error(`GraphHopper matrix error: ${res.status} — ${text}`);
|
|
74
|
+
throw new Error(`GraphHopper matrix error: ${res.status} — ${truncateBody(text)}`);
|
|
66
75
|
}
|
|
67
76
|
// GraphHopper returns times in seconds, distances in metres
|
|
68
|
-
const data =
|
|
77
|
+
const data = await safeJson(res, 'GraphHopper matrix');
|
|
69
78
|
const entries = [];
|
|
70
79
|
for (let oi = 0; oi < origins.length; oi++) {
|
|
71
80
|
for (let di = 0; di < destinations.length; di++) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphhopper.js","sourceRoot":"","sources":["../../src/engines/graphhopper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"graphhopper.js","sourceRoot":"","sources":["../../src/engines/graphhopper.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,8 @@ export interface OpenRouteServiceOptions {
|
|
|
5
5
|
apiKey: string;
|
|
6
6
|
/** Base URL override. Defaults to the public ORS API (`https://api.openrouteservice.org`). */
|
|
7
7
|
baseUrl?: string;
|
|
8
|
+
/** Request timeout in milliseconds (default 30 000). */
|
|
9
|
+
timeoutMs?: number;
|
|
8
10
|
}
|
|
9
11
|
/**
|
|
10
12
|
* OpenRouteService routing engine adapter.
|
|
@@ -22,6 +24,7 @@ export declare class OpenRouteServiceEngine implements RoutingEngine {
|
|
|
22
24
|
readonly name = "OpenRouteService";
|
|
23
25
|
private readonly apiKey;
|
|
24
26
|
private readonly baseUrl;
|
|
27
|
+
private readonly timeoutMs;
|
|
25
28
|
constructor(options: OpenRouteServiceOptions);
|
|
26
29
|
computeIsochrone(origin: LatLon, mode: TransportMode, timeMinutes: number): Promise<Isochrone>;
|
|
27
30
|
computeRouteMatrix(origins: LatLon[], destinations: LatLon[], mode: TransportMode): Promise<RouteMatrix>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openrouteservice.d.ts","sourceRoot":"","sources":["../../src/engines/openrouteservice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"openrouteservice.d.ts","sourceRoot":"","sources":["../../src/engines/openrouteservice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAY9G,mEAAmE;AACnE,MAAM,WAAW,uBAAuB;IACtC,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAA;IACd,8FAA8F;IAC9F,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,sBAAuB,YAAW,aAAa;IAC1D,QAAQ,CAAC,IAAI,sBAAqB;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;gBAEtB,OAAO,EAAE,uBAAuB;IAQtC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAuC9F,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC;IA+CxG,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CAGxG"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { validateHttpUrl, safeJson, truncateBody } from '../validate.js';
|
|
1
2
|
const ORS_BASE = 'https://api.openrouteservice.org';
|
|
2
3
|
const MODE_MAP = {
|
|
3
4
|
drive: 'driving-car',
|
|
@@ -21,9 +22,13 @@ export class OpenRouteServiceEngine {
|
|
|
21
22
|
name = 'OpenRouteService';
|
|
22
23
|
apiKey;
|
|
23
24
|
baseUrl;
|
|
25
|
+
timeoutMs;
|
|
24
26
|
constructor(options) {
|
|
25
27
|
this.apiKey = options.apiKey;
|
|
26
|
-
this.baseUrl = options.baseUrl
|
|
28
|
+
this.baseUrl = options.baseUrl
|
|
29
|
+
? validateHttpUrl(options.baseUrl, 'OpenRouteServiceEngine baseUrl')
|
|
30
|
+
: ORS_BASE;
|
|
31
|
+
this.timeoutMs = options.timeoutMs ?? 30_000;
|
|
27
32
|
}
|
|
28
33
|
async computeIsochrone(origin, mode, timeMinutes) {
|
|
29
34
|
const profile = MODE_MAP[mode];
|
|
@@ -39,12 +44,13 @@ export class OpenRouteServiceEngine {
|
|
|
39
44
|
'Content-Type': 'application/json',
|
|
40
45
|
},
|
|
41
46
|
body: JSON.stringify(body),
|
|
47
|
+
signal: AbortSignal.timeout(this.timeoutMs),
|
|
42
48
|
});
|
|
43
49
|
if (!response.ok) {
|
|
44
|
-
const text = await response.text();
|
|
45
|
-
throw new Error(`ORS isochrone API error ${response.status}: ${text}`);
|
|
50
|
+
const text = await response.text().catch(() => '');
|
|
51
|
+
throw new Error(`ORS isochrone API error ${response.status}: ${truncateBody(text)}`);
|
|
46
52
|
}
|
|
47
|
-
const data = await response
|
|
53
|
+
const data = await safeJson(response, 'ORS isochrone');
|
|
48
54
|
if (!data.features?.length) {
|
|
49
55
|
throw new Error('ORS returned no isochrone features');
|
|
50
56
|
}
|
|
@@ -71,12 +77,13 @@ export class OpenRouteServiceEngine {
|
|
|
71
77
|
'Content-Type': 'application/json',
|
|
72
78
|
},
|
|
73
79
|
body: JSON.stringify(body),
|
|
80
|
+
signal: AbortSignal.timeout(this.timeoutMs),
|
|
74
81
|
});
|
|
75
82
|
if (!response.ok) {
|
|
76
|
-
const text = await response.text();
|
|
77
|
-
throw new Error(`ORS matrix API error ${response.status}: ${text}`);
|
|
83
|
+
const text = await response.text().catch(() => '');
|
|
84
|
+
throw new Error(`ORS matrix API error ${response.status}: ${truncateBody(text)}`);
|
|
78
85
|
}
|
|
79
|
-
const data = await response
|
|
86
|
+
const data = await safeJson(response, 'ORS matrix');
|
|
80
87
|
const entries = [];
|
|
81
88
|
for (let oi = 0; oi < origins.length; oi++) {
|
|
82
89
|
for (let di = 0; di < destinations.length; di++) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openrouteservice.js","sourceRoot":"","sources":["../../src/engines/openrouteservice.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"openrouteservice.js","sourceRoot":"","sources":["../../src/engines/openrouteservice.ts"],"names":[],"mappings":"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"}
|
package/dist/engines/osrm.d.ts
CHANGED
|
@@ -16,8 +16,10 @@ import type { RoutingEngine, Isochrone, RouteMatrix, RouteGeometry, TransportMod
|
|
|
16
16
|
export declare class OsrmEngine implements RoutingEngine {
|
|
17
17
|
readonly name = "OSRM";
|
|
18
18
|
private readonly baseUrl;
|
|
19
|
+
private readonly timeoutMs;
|
|
19
20
|
constructor(config: {
|
|
20
21
|
baseUrl: string;
|
|
22
|
+
timeoutMs?: number;
|
|
21
23
|
});
|
|
22
24
|
computeIsochrone(_origin: LatLon, _mode: TransportMode, _timeMinutes: number): Promise<Isochrone>;
|
|
23
25
|
computeRouteMatrix(origins: LatLon[], destinations: LatLon[], mode: TransportMode): Promise<RouteMatrix>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"osrm.d.ts","sourceRoot":"","sources":["../../src/engines/osrm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EACpD,aAAa,EAAE,MAAM,EACtB,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"osrm.d.ts","sourceRoot":"","sources":["../../src/engines/osrm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EACpD,aAAa,EAAE,MAAM,EACtB,MAAM,aAAa,CAAA;AAUpB;;;;;;;;;;;;;GAaG;AACH,qBAAa,UAAW,YAAW,aAAa;IAC9C,QAAQ,CAAC,IAAI,UAAS;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;gBAEtB,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;IAK3D,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAM3F,kBAAkB,CACtB,OAAO,EAAE,MAAM,EAAE,EACjB,YAAY,EAAE,MAAM,EAAE,EACtB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC;IA2CjB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CAGxG"}
|
package/dist/engines/osrm.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { validateHttpUrl, safeJson, truncateBody } from '../validate.js';
|
|
1
2
|
const PROFILE = {
|
|
2
3
|
drive: 'car',
|
|
3
4
|
cycle: 'bike',
|
|
@@ -21,8 +22,10 @@ const PROFILE = {
|
|
|
21
22
|
export class OsrmEngine {
|
|
22
23
|
name = 'OSRM';
|
|
23
24
|
baseUrl;
|
|
25
|
+
timeoutMs;
|
|
24
26
|
constructor(config) {
|
|
25
|
-
this.baseUrl = config.baseUrl
|
|
27
|
+
this.baseUrl = validateHttpUrl(config.baseUrl, 'OsrmEngine baseUrl');
|
|
28
|
+
this.timeoutMs = config.timeoutMs ?? 30_000;
|
|
26
29
|
}
|
|
27
30
|
computeIsochrone(_origin, _mode, _timeMinutes) {
|
|
28
31
|
throw new Error('OSRM does not support isochrone computation. Use Valhalla, ORS, or GraphHopper instead.');
|
|
@@ -34,13 +37,13 @@ export class OsrmEngine {
|
|
|
34
37
|
.join(';');
|
|
35
38
|
const sources = origins.map((_, i) => i).join(';');
|
|
36
39
|
const dests = destinations.map((_, i) => origins.length + i).join(';');
|
|
37
|
-
const res = await fetch(`${this.baseUrl}/table/v1/${profile}/${allCoords}?sources=${sources}&destinations=${dests}&annotations=duration,distance
|
|
40
|
+
const res = await fetch(`${this.baseUrl}/table/v1/${profile}/${allCoords}?sources=${sources}&destinations=${dests}&annotations=duration,distance`, { signal: AbortSignal.timeout(this.timeoutMs) });
|
|
38
41
|
if (!res.ok) {
|
|
39
42
|
const text = await res.text().catch(() => '');
|
|
40
|
-
throw new Error(`OSRM matrix error: ${res.status} — ${text}`);
|
|
43
|
+
throw new Error(`OSRM matrix error: ${res.status} — ${truncateBody(text)}`);
|
|
41
44
|
}
|
|
42
45
|
// OSRM returns durations in seconds, distances in metres
|
|
43
|
-
const data =
|
|
46
|
+
const data = await safeJson(res, 'OSRM matrix');
|
|
44
47
|
const entries = [];
|
|
45
48
|
for (let oi = 0; oi < origins.length; oi++) {
|
|
46
49
|
for (let di = 0; di < destinations.length; di++) {
|
package/dist/engines/osrm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"osrm.js","sourceRoot":"","sources":["../../src/engines/osrm.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"osrm.js","sourceRoot":"","sources":["../../src/engines/osrm.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"valhalla.d.ts","sourceRoot":"","sources":["../../src/engines/valhalla.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EACpD,aAAa,EAAE,MAAM,EACtB,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"valhalla.d.ts","sourceRoot":"","sources":["../../src/engines/valhalla.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EACpD,aAAa,EAAE,MAAM,EACtB,MAAM,aAAa,CAAA;AAGpB;;;;GAIG;AACH,qBAAa,aAAc,SAAQ,KAAK;aAGpB,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;gBAF5B,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM;CAK/B;AA6CD;;;;;;;;;;GAUG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,IAAI,cAAa;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwB;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;gBAEtB,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;IAMvF,gBAAgB,CACpB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,aAAa,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,SAAS,CAAC;IAoCf,kBAAkB,CACtB,OAAO,EAAE,MAAM,EAAE,EACjB,YAAY,EAAE,MAAM,EAAE,EACtB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC;IAwCjB,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,aAAa,CAAC;CAsF1B"}
|
package/dist/engines/valhalla.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { validateHttpUrl, safeJson, truncateBody } from '../validate.js';
|
|
1
2
|
/**
|
|
2
3
|
* Error thrown by ValhallaEngine when the server returns a non-200 response.
|
|
3
4
|
* Includes the HTTP status code and response body for error handling
|
|
@@ -65,7 +66,7 @@ export class ValhallaEngine {
|
|
|
65
66
|
extraHeaders;
|
|
66
67
|
timeoutMs;
|
|
67
68
|
constructor(config) {
|
|
68
|
-
this.baseUrl = config.baseUrl
|
|
69
|
+
this.baseUrl = validateHttpUrl(config.baseUrl, 'ValhallaEngine baseUrl');
|
|
69
70
|
this.extraHeaders = config.headers ?? {};
|
|
70
71
|
this.timeoutMs = config.timeoutMs ?? 30_000;
|
|
71
72
|
}
|
|
@@ -84,9 +85,9 @@ export class ValhallaEngine {
|
|
|
84
85
|
});
|
|
85
86
|
if (!res.ok) {
|
|
86
87
|
const text = await res.text().catch(() => '');
|
|
87
|
-
throw new ValhallaError(`Valhalla isochrone error: ${res.status} ${res.statusText} — ${text}`, res.status, text);
|
|
88
|
+
throw new ValhallaError(`Valhalla isochrone error: ${res.status} ${res.statusText} — ${truncateBody(text)}`, res.status, text);
|
|
88
89
|
}
|
|
89
|
-
const data =
|
|
90
|
+
const data = await safeJson(res, 'Valhalla isochrone');
|
|
90
91
|
if (!data.features?.length) {
|
|
91
92
|
throw new Error('Valhalla returned no isochrone features');
|
|
92
93
|
}
|
|
@@ -111,9 +112,9 @@ export class ValhallaEngine {
|
|
|
111
112
|
});
|
|
112
113
|
if (!res.ok) {
|
|
113
114
|
const text = await res.text().catch(() => '');
|
|
114
|
-
throw new ValhallaError(`Valhalla matrix error: ${res.status} ${res.statusText} — ${text}`, res.status, text);
|
|
115
|
+
throw new ValhallaError(`Valhalla matrix error: ${res.status} ${res.statusText} — ${truncateBody(text)}`, res.status, text);
|
|
115
116
|
}
|
|
116
|
-
const data =
|
|
117
|
+
const data = await safeJson(res, 'Valhalla matrix');
|
|
117
118
|
const entries = [];
|
|
118
119
|
for (let oi = 0; oi < origins.length; oi++) {
|
|
119
120
|
for (let di = 0; di < destinations.length; di++) {
|
|
@@ -148,9 +149,9 @@ export class ValhallaEngine {
|
|
|
148
149
|
});
|
|
149
150
|
if (!res.ok) {
|
|
150
151
|
const text = await res.text().catch(() => '');
|
|
151
|
-
throw new ValhallaError(`Valhalla route error: ${res.status} ${res.statusText} — ${text}`, res.status, text);
|
|
152
|
+
throw new ValhallaError(`Valhalla route error: ${res.status} ${res.statusText} — ${truncateBody(text)}`, res.status, text);
|
|
152
153
|
}
|
|
153
|
-
const data =
|
|
154
|
+
const data = await safeJson(res, 'Valhalla route');
|
|
154
155
|
const tripLeg = data.trip.legs[0];
|
|
155
156
|
const coordinates = decodePolyline6(tripLeg.shape);
|
|
156
157
|
const legs = tripLeg.maneuvers.map((m) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"valhalla.js","sourceRoot":"","sources":["../../src/engines/valhalla.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"valhalla.js","sourceRoot":"","sources":["../../src/engines/valhalla.ts"],"names":[],"mappings":"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"}
|
package/dist/rendezvous.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rendezvous.d.ts","sourceRoot":"","sources":["../src/rendezvous.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"rendezvous.d.ts","sourceRoot":"","sources":["../src/rendezvous.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,oBAAoB,EAAuG,MAAM,YAAY,CAAA;AAK7L;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CA8CjC"}
|
package/dist/rendezvous.js
CHANGED
|
@@ -46,32 +46,8 @@ export async function findRendezvous(engine, options) {
|
|
|
46
46
|
// Step 4: Compute route matrix from participants to candidate venues
|
|
47
47
|
const venuePoints = venues.map(v => ({ lat: v.lat, lon: v.lon }));
|
|
48
48
|
const matrix = await engine.computeRouteMatrix(participants, venuePoints, mode);
|
|
49
|
-
// Step 5: Score
|
|
50
|
-
|
|
51
|
-
for (let vi = 0; vi < venues.length; vi++) {
|
|
52
|
-
const venue = venues[vi];
|
|
53
|
-
const travelTimes = {};
|
|
54
|
-
const times = [];
|
|
55
|
-
let reachable = true;
|
|
56
|
-
for (let pi = 0; pi < participants.length; pi++) {
|
|
57
|
-
const entry = matrix.entries.find(e => e.originIndex === pi && e.destinationIndex === vi);
|
|
58
|
-
const duration = entry?.durationMinutes ?? -1;
|
|
59
|
-
if (duration < 0 || duration > maxTimeMinutes) {
|
|
60
|
-
reachable = false;
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
const label = participants[pi].label ?? `participant_${pi}`;
|
|
64
|
-
travelTimes[label] = Math.round(duration * 10) / 10;
|
|
65
|
-
times.push(duration);
|
|
66
|
-
}
|
|
67
|
-
if (!reachable)
|
|
68
|
-
continue;
|
|
69
|
-
const fairnessScore = computeFairnessScore(times, fairness);
|
|
70
|
-
suggestions.push({ venue, travelTimes, fairnessScore, metadata: { strategy: 'isochrone' } });
|
|
71
|
-
}
|
|
72
|
-
// Step 6: Sort by fairness score and return top N
|
|
73
|
-
suggestions.sort((a, b) => a.fairnessScore - b.fairnessScore);
|
|
74
|
-
return suggestions.slice(0, limit);
|
|
49
|
+
// Step 5–6: Score, sort, and return
|
|
50
|
+
return scoreVenues(venues, participants, matrix, maxTimeMinutes, fairness, 'isochrone', limit);
|
|
75
51
|
}
|
|
76
52
|
async function findRendezvousHull(engine, participants, mode, maxTimeMinutes, venueTypes, fairness, limit) {
|
|
77
53
|
// 1. Compute buffered hull
|
|
@@ -101,14 +77,21 @@ async function findRendezvousHull(engine, participants, mode, maxTimeMinutes, ve
|
|
|
101
77
|
// 3. Route matrix
|
|
102
78
|
const venuePoints = venues.map(v => ({ lat: v.lat, lon: v.lon }));
|
|
103
79
|
const matrix = await engine.computeRouteMatrix(participants, venuePoints, mode);
|
|
104
|
-
// 4.
|
|
80
|
+
// 4. Score, sort, and return
|
|
81
|
+
return scoreVenues(venues, participants, matrix, maxTimeMinutes, fairness, 'hull', limit);
|
|
82
|
+
}
|
|
83
|
+
function scoreVenues(venues, participants, matrix, maxTimeMinutes, fairness, strategy, limit) {
|
|
84
|
+
// Pre-index matrix for O(1) lookup instead of O(n) scan per venue×participant
|
|
85
|
+
const indexed = new Map();
|
|
86
|
+
for (const e of matrix.entries)
|
|
87
|
+
indexed.set(`${e.originIndex}:${e.destinationIndex}`, e);
|
|
105
88
|
const suggestions = [];
|
|
106
89
|
for (let vi = 0; vi < venues.length; vi++) {
|
|
107
90
|
const travelTimes = {};
|
|
108
91
|
const times = [];
|
|
109
92
|
let reachable = true;
|
|
110
93
|
for (let pi = 0; pi < participants.length; pi++) {
|
|
111
|
-
const entry =
|
|
94
|
+
const entry = indexed.get(`${pi}:${vi}`);
|
|
112
95
|
const duration = entry?.durationMinutes ?? -1;
|
|
113
96
|
if (duration < 0 || duration > maxTimeMinutes) {
|
|
114
97
|
reachable = false;
|
|
@@ -124,7 +107,7 @@ async function findRendezvousHull(engine, participants, mode, maxTimeMinutes, ve
|
|
|
124
107
|
venue: venues[vi],
|
|
125
108
|
travelTimes,
|
|
126
109
|
fairnessScore: computeFairnessScore(times, fairness),
|
|
127
|
-
metadata: { strategy
|
|
110
|
+
metadata: { strategy },
|
|
128
111
|
});
|
|
129
112
|
}
|
|
130
113
|
suggestions.sort((a, b) => a.fairnessScore - b.fairnessScore);
|
|
@@ -150,6 +133,8 @@ function envelopePolygon(polygons) {
|
|
|
150
133
|
};
|
|
151
134
|
}
|
|
152
135
|
function weightedCentroid(polygons) {
|
|
136
|
+
if (polygons.length === 0)
|
|
137
|
+
return { lat: 0, lon: 0 };
|
|
153
138
|
let totalArea = 0;
|
|
154
139
|
let sumLon = 0;
|
|
155
140
|
let sumLat = 0;
|
|
@@ -157,6 +142,8 @@ function weightedCentroid(polygons) {
|
|
|
157
142
|
const area = polygonArea(p);
|
|
158
143
|
const ring = p.coordinates[0];
|
|
159
144
|
const n = ring.length - 1;
|
|
145
|
+
if (n <= 0)
|
|
146
|
+
continue;
|
|
160
147
|
let cLon = 0, cLat = 0;
|
|
161
148
|
for (let i = 0; i < n; i++) {
|
|
162
149
|
cLon += ring[i][0];
|
|
@@ -169,9 +156,12 @@ function weightedCentroid(polygons) {
|
|
|
169
156
|
if (totalArea === 0) {
|
|
170
157
|
// Fallback: unweighted average of centroids
|
|
171
158
|
let lon = 0, lat = 0;
|
|
159
|
+
let count = 0;
|
|
172
160
|
for (const p of polygons) {
|
|
173
161
|
const ring = p.coordinates[0];
|
|
174
162
|
const n = ring.length - 1;
|
|
163
|
+
if (n <= 0)
|
|
164
|
+
continue;
|
|
175
165
|
let cLon = 0, cLat = 0;
|
|
176
166
|
for (let i = 0; i < n; i++) {
|
|
177
167
|
cLon += ring[i][0];
|
|
@@ -179,8 +169,11 @@ function weightedCentroid(polygons) {
|
|
|
179
169
|
}
|
|
180
170
|
lon += cLon / n;
|
|
181
171
|
lat += cLat / n;
|
|
172
|
+
count++;
|
|
182
173
|
}
|
|
183
|
-
|
|
174
|
+
if (count === 0)
|
|
175
|
+
return { lat: 0, lon: 0 };
|
|
176
|
+
return { lon: lon / count, lat: lat / count };
|
|
184
177
|
}
|
|
185
178
|
return { lon: sumLon / totalArea, lat: sumLat / totalArea };
|
|
186
179
|
}
|
package/dist/rendezvous.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rendezvous.js","sourceRoot":"","sources":["../src/rendezvous.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACzE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAE7D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAqB,EACrB,OAA0B;IAE1B,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,GAAG,SAAS,EAAE,KAAK,GAAG,CAAC,EAAE,QAAQ,EAAE,iBAAiB,GAAG,MAAM,EAAE,GAAG,OAAO,CAAA;IAEzI,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAAC,iDAAiD,CAAC,CAAA;IACzE,CAAC;IAED,4BAA4B;IAC5B,MAAM,QAAQ,GAAG,iBAAiB,KAAK,MAAM;QAC3C,CAAC,CAAC,cAAc,CAAC,YAAY,EAAE,IAAI,EAAE,cAAc,CAAC;QACpD,CAAC,CAAC,iBAAiB,CAAA;IAErB,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,OAAO,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAA;IACpG,CAAC;IAED,kDAAkD;IAClD,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAClC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CACxE,CAAA;IAED,gFAAgF;IAChF,MAAM,UAAU,GAAG,oBAAoB,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IAC3E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAA,CAAC,8CAA8C;IAC1D,CAAC;IAED,+DAA+D;IAC/D,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC,CAAA;IAC1F,IAAI,MAAM,GAAG,MAAM,YAAY,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IACzD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAA;QACtC,MAAM,GAAG,CAAC;gBACR,IAAI,EAAE,eAAe;gBACrB,GAAG,EAAE,CAAC,CAAC,GAAG;gBACV,GAAG,EAAE,CAAC,CAAC,GAAG;gBACV,SAAS,EAAE,UAAU;aACtB,CAAC,CAAA;IACJ,CAAC;IAED,qEAAqE;IACrE,MAAM,WAAW,GAAa,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IAC3E,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,YAAY,EAAE,WAAW,EAAE,IAAI,CAAC,CAAA;IAE/E,
|
|
1
|
+
{"version":3,"file":"rendezvous.js","sourceRoot":"","sources":["../src/rendezvous.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Validate that a string is an HTTP(S) URL. Returns the URL with trailing slash stripped. */
|
|
2
|
+
export declare function validateHttpUrl(url: string, label: string): string;
|
|
3
|
+
/** Truncate a string for use in error messages. */
|
|
4
|
+
export declare function truncateBody(text: string, maxLen?: number): string;
|
|
5
|
+
/** Parse JSON from a Response, throwing a descriptive error on failure. */
|
|
6
|
+
export declare function safeJson<T>(res: Response, context: string): Promise<T>;
|
|
7
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAWlE;AAED,mDAAmD;AACnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAM,GAAG,MAAM,CAE/D;AAED,2EAA2E;AAC3E,wBAAsB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAM5E"}
|
package/dist/validate.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Validate that a string is an HTTP(S) URL. Returns the URL with trailing slash stripped. */
|
|
2
|
+
export function validateHttpUrl(url, label) {
|
|
3
|
+
let parsed;
|
|
4
|
+
try {
|
|
5
|
+
parsed = new URL(url);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
throw new TypeError(`${label}: invalid URL "${url}"`);
|
|
9
|
+
}
|
|
10
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
11
|
+
throw new TypeError(`${label}: must use http or https, got "${parsed.protocol}"`);
|
|
12
|
+
}
|
|
13
|
+
return url.replace(/\/$/, '');
|
|
14
|
+
}
|
|
15
|
+
/** Truncate a string for use in error messages. */
|
|
16
|
+
export function truncateBody(text, maxLen = 200) {
|
|
17
|
+
return text.length > maxLen ? text.slice(0, maxLen) + '…' : text;
|
|
18
|
+
}
|
|
19
|
+
/** Parse JSON from a Response, throwing a descriptive error on failure. */
|
|
20
|
+
export async function safeJson(res, context) {
|
|
21
|
+
try {
|
|
22
|
+
return await res.json();
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
throw new Error(`${context}: response body is not valid JSON`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,MAAM,UAAU,eAAe,CAAC,GAAW,EAAE,KAAa;IACxD,IAAI,MAAW,CAAA;IACf,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,kBAAkB,GAAG,GAAG,CAAC,CAAA;IACvD,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChE,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,kCAAkC,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAA;IACnF,CAAC;IACD,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;AAC/B,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,MAAM,GAAG,GAAG;IACrD,OAAO,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAA;AAClE,CAAC;AAED,2EAA2E;AAC3E,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAI,GAAa,EAAE,OAAe;IAC9D,IAAI,CAAC;QACH,OAAO,MAAM,GAAG,CAAC,IAAI,EAAO,CAAA;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,mCAAmC,CAAC,CAAA;IAChE,CAAC;AACH,CAAC"}
|
package/dist/venues.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ import type { GeoJSONPolygon, Venue, VenueType } from './types.js';
|
|
|
3
3
|
* Search for venues within a polygon using the Overpass API.
|
|
4
4
|
* Uses the bounding box of the polygon for the query.
|
|
5
5
|
*/
|
|
6
|
-
export declare function searchVenues(polygon: GeoJSONPolygon, venueTypes: VenueType[], overpassUrl?: string): Promise<Venue[]>;
|
|
6
|
+
export declare function searchVenues(polygon: GeoJSONPolygon, venueTypes: VenueType[], overpassUrl?: string, resultLimit?: number): Promise<Venue[]>;
|
|
7
7
|
//# sourceMappingURL=venues.d.ts.map
|
package/dist/venues.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"venues.d.ts","sourceRoot":"","sources":["../src/venues.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"venues.d.ts","sourceRoot":"","sources":["../src/venues.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AA4ClE;;;GAGG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,SAAS,EAAE,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,WAAW,SAAM,GAChB,OAAO,CAAC,KAAK,EAAE,CAAC,CA2ElB"}
|
package/dist/venues.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { safeJson } from './validate.js';
|
|
1
2
|
const OVERPASS_ENDPOINTS = [
|
|
2
3
|
'https://overpass-api.de/api/interpreter',
|
|
3
4
|
'https://overpass.kumi.systems/api/interpreter',
|
|
4
5
|
];
|
|
6
|
+
/** Pattern for safe Overpass tag values (alphanumeric + underscore). */
|
|
7
|
+
const SAFE_TAG_VALUE = /^[a-zA-Z][a-zA-Z0-9_]*$/;
|
|
5
8
|
/** Map VenueType to Overpass tag queries. */
|
|
6
9
|
const VENUE_TAG_MAP = {
|
|
7
10
|
park: 'leisure=park',
|
|
@@ -41,11 +44,18 @@ function polygonBBox(polygon) {
|
|
|
41
44
|
* Search for venues within a polygon using the Overpass API.
|
|
42
45
|
* Uses the bounding box of the polygon for the query.
|
|
43
46
|
*/
|
|
44
|
-
export async function searchVenues(polygon, venueTypes, overpassUrl) {
|
|
47
|
+
export async function searchVenues(polygon, venueTypes, overpassUrl, resultLimit = 200) {
|
|
45
48
|
const bbox = polygonBBox(polygon);
|
|
46
49
|
const bboxStr = `${bbox.south},${bbox.west},${bbox.north},${bbox.east}`;
|
|
47
50
|
const tagQueries = venueTypes
|
|
48
|
-
.map(vt =>
|
|
51
|
+
.map(vt => {
|
|
52
|
+
if (VENUE_TAG_MAP[vt])
|
|
53
|
+
return VENUE_TAG_MAP[vt];
|
|
54
|
+
if (!SAFE_TAG_VALUE.test(vt)) {
|
|
55
|
+
throw new TypeError(`Invalid venue type: "${vt}" — must be a known type or match ${SAFE_TAG_VALUE}`);
|
|
56
|
+
}
|
|
57
|
+
return `amenity=${vt}`;
|
|
58
|
+
})
|
|
49
59
|
.flatMap(tag => {
|
|
50
60
|
const [key, value] = tag.split('=');
|
|
51
61
|
return [
|
|
@@ -55,7 +65,7 @@ export async function searchVenues(polygon, venueTypes, overpassUrl) {
|
|
|
55
65
|
];
|
|
56
66
|
})
|
|
57
67
|
.join('\n');
|
|
58
|
-
const query =
|
|
68
|
+
const query = `[out:json][timeout:25];(\n${tagQueries}\n);out center ${resultLimit};`;
|
|
59
69
|
const body = `data=${encodeURIComponent(query)}`;
|
|
60
70
|
const endpoints = overpassUrl ? [overpassUrl] : OVERPASS_ENDPOINTS;
|
|
61
71
|
let lastError;
|
|
@@ -68,7 +78,7 @@ export async function searchVenues(polygon, venueTypes, overpassUrl) {
|
|
|
68
78
|
signal: AbortSignal.timeout(30_000),
|
|
69
79
|
});
|
|
70
80
|
if (response.ok) {
|
|
71
|
-
const data = await response
|
|
81
|
+
const data = await safeJson(response, 'Overpass API');
|
|
72
82
|
return data.elements
|
|
73
83
|
.filter(el => el.tags?.name)
|
|
74
84
|
.map(el => {
|
package/dist/venues.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"venues.js","sourceRoot":"","sources":["../src/venues.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"venues.js","sourceRoot":"","sources":["../src/venues.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED