mapricot 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/dist/index.d.ts +16 -12
- package/dist/index.js +75 -51
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Mapricot for JavaScript and TypeScript
|
|
2
2
|
|
|
3
|
-
The official JavaScript client for the [Mapricot API](https://mapricot.com/): address and place search, reverse geocoding, nearby places, routing, and IP geolocation, with 250,000 free requests every
|
|
3
|
+
The official JavaScript client for the [Mapricot API](https://mapricot.com/): address and place search, reverse geocoding, nearby places, routing, and IP geolocation, with 250,000 free requests every 30 days.
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
6
|
npm install mapricot
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
It uses the built-in `fetch`, so it has no dependencies and runs in Node.js 20 and later, Deno (as `npm:mapricot`), Bun, Cloudflare Workers, and browsers. Types are included.
|
|
9
|
+
It uses the built-in `fetch`, so it has no dependencies and runs in Node.js 20 and later, Deno (as `npm:mapricot`), Bun, Cloudflare Workers, and browsers as old as Chrome 66, Firefox 57, and Safari 12.1. Types are included.
|
|
10
10
|
|
|
11
11
|
## Quick start
|
|
12
12
|
|
|
@@ -46,6 +46,14 @@ const { routes } = await client.route([{ lat: 45.5189, lon: -122.6793 }, { lat:
|
|
|
46
46
|
console.log(routes[0].durationSeconds);
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
To cancel a request, such as an autocomplete request for text that has since changed, pass an `AbortSignal` as `signal` to any method. The request then rejects with an `AbortError`:
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
const controller = new AbortController();
|
|
53
|
+
const request = client.autocomplete("1005 W Burn", { signal: controller.signal });
|
|
54
|
+
controller.abort();
|
|
55
|
+
```
|
|
56
|
+
|
|
49
57
|
A route's `polyline` is encoded with six decimal places. Decode it with precision 6, as [decoding a route polyline](https://mapricot.com/guides/polyline-decoder/) shows.
|
|
50
58
|
|
|
51
59
|
If your app shows results, show the credits in each response's `attribution`.
|
package/dist/index.d.ts
CHANGED
|
@@ -67,23 +67,27 @@ export interface Account {
|
|
|
67
67
|
id: string;
|
|
68
68
|
name: string;
|
|
69
69
|
status: string;
|
|
70
|
-
|
|
70
|
+
createdAt: string;
|
|
71
71
|
}
|
|
72
72
|
export interface Point {
|
|
73
73
|
lat: number;
|
|
74
74
|
lon: number;
|
|
75
75
|
}
|
|
76
|
-
export interface
|
|
76
|
+
export interface RequestOptions {
|
|
77
|
+
/** Cancels the request, such as one for text that has since changed. */
|
|
78
|
+
signal?: AbortSignal;
|
|
79
|
+
}
|
|
80
|
+
export interface SearchOptions extends RequestOptions {
|
|
77
81
|
focus?: Point;
|
|
78
82
|
country?: string | string[];
|
|
79
83
|
limit?: number;
|
|
80
84
|
lang?: string;
|
|
81
85
|
}
|
|
82
|
-
export interface ReverseOptions {
|
|
86
|
+
export interface ReverseOptions extends RequestOptions {
|
|
83
87
|
limit?: number;
|
|
84
88
|
lang?: string;
|
|
85
89
|
}
|
|
86
|
-
export interface NearbyOptions {
|
|
90
|
+
export interface NearbyOptions extends RequestOptions {
|
|
87
91
|
category?: string | string[];
|
|
88
92
|
radius?: number;
|
|
89
93
|
limit?: number;
|
|
@@ -107,23 +111,23 @@ export declare class Mapricot {
|
|
|
107
111
|
#private;
|
|
108
112
|
constructor(options: ClientOptions);
|
|
109
113
|
/** Find addresses and places matching free text. */
|
|
110
|
-
search(q: string, options?: SearchOptions): Promise<Places>;
|
|
114
|
+
search(q: string, { signal, ...options }?: SearchOptions): Promise<Places>;
|
|
111
115
|
/** Suggest addresses and places as someone types. */
|
|
112
|
-
autocomplete(q: string, options?: SearchOptions): Promise<Places>;
|
|
116
|
+
autocomplete(q: string, { signal, ...options }?: SearchOptions): Promise<Places>;
|
|
113
117
|
/** Find the address nearest a coordinate, or the area around it. */
|
|
114
|
-
reverse(lat: number, lon: number, options?: ReverseOptions): Promise<Places>;
|
|
118
|
+
reverse(lat: number, lon: number, { signal, ...options }?: ReverseOptions): Promise<Places>;
|
|
115
119
|
/** List places around a coordinate, optionally by category. */
|
|
116
|
-
nearby(lat: number, lon: number, options?: NearbyOptions): Promise<Places>;
|
|
120
|
+
nearby(lat: number, lon: number, { signal, ...options }?: NearbyOptions): Promise<Places>;
|
|
117
121
|
/** Look up one place by its Mapricot ID. */
|
|
118
|
-
place(id: string, options?: {
|
|
122
|
+
place(id: string, { signal, ...options }?: RequestOptions & {
|
|
119
123
|
lang?: string;
|
|
120
124
|
}): Promise<PlaceResult>;
|
|
121
125
|
/** Find a route through 2 to 20 waypoints. */
|
|
122
|
-
route(waypoints: Point[], options?: {
|
|
126
|
+
route(waypoints: Point[], { signal, ...options }?: RequestOptions & {
|
|
123
127
|
mode?: "drive" | "walk" | "bicycle";
|
|
124
128
|
}): Promise<Routes>;
|
|
125
129
|
/** Approximate location of a public IP address. */
|
|
126
|
-
ip(address: string): Promise<IpLocation>;
|
|
130
|
+
ip(address: string, { signal }?: RequestOptions): Promise<IpLocation>;
|
|
127
131
|
/** The key's account. Not billed, so it checks a key for free. */
|
|
128
|
-
account(): Promise<Account>;
|
|
132
|
+
account({ signal }?: RequestOptions): Promise<Account>;
|
|
129
133
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _Mapricot_instances, _Mapricot_apiKey, _Mapricot_baseUrl, _Mapricot_timeout, _Mapricot_maxRetries, _Mapricot_request;
|
|
1
13
|
export class MapricotError extends Error {
|
|
2
|
-
status;
|
|
3
|
-
code;
|
|
4
|
-
requestId;
|
|
5
14
|
constructor(status, code, message, requestId) {
|
|
6
15
|
super(message);
|
|
7
16
|
this.name = "MapricotError";
|
|
@@ -11,77 +20,92 @@ export class MapricotError extends Error {
|
|
|
11
20
|
}
|
|
12
21
|
}
|
|
13
22
|
export class Mapricot {
|
|
14
|
-
#apiKey;
|
|
15
|
-
#baseUrl;
|
|
16
|
-
#timeout;
|
|
17
|
-
#maxRetries;
|
|
18
23
|
constructor(options) {
|
|
19
|
-
|
|
24
|
+
var _a, _b, _c;
|
|
25
|
+
_Mapricot_instances.add(this);
|
|
26
|
+
_Mapricot_apiKey.set(this, void 0);
|
|
27
|
+
_Mapricot_baseUrl.set(this, void 0);
|
|
28
|
+
_Mapricot_timeout.set(this, void 0);
|
|
29
|
+
_Mapricot_maxRetries.set(this, void 0);
|
|
30
|
+
if (!(options === null || options === void 0 ? void 0 : options.apiKey))
|
|
20
31
|
throw new Error("Pass apiKey, a Mapricot key.");
|
|
21
|
-
this
|
|
22
|
-
this
|
|
23
|
-
this
|
|
24
|
-
this
|
|
32
|
+
__classPrivateFieldSet(this, _Mapricot_apiKey, options.apiKey, "f");
|
|
33
|
+
__classPrivateFieldSet(this, _Mapricot_baseUrl, (_a = options.baseUrl) !== null && _a !== void 0 ? _a : "https://api.mapricot.com", "f");
|
|
34
|
+
__classPrivateFieldSet(this, _Mapricot_timeout, (_b = options.timeout) !== null && _b !== void 0 ? _b : 30000, "f");
|
|
35
|
+
__classPrivateFieldSet(this, _Mapricot_maxRetries, (_c = options.maxRetries) !== null && _c !== void 0 ? _c : 2, "f");
|
|
25
36
|
}
|
|
26
37
|
/** Find addresses and places matching free text. */
|
|
27
|
-
search(q, options = {}) {
|
|
28
|
-
return this
|
|
38
|
+
search(q, { signal, ...options } = {}) {
|
|
39
|
+
return __classPrivateFieldGet(this, _Mapricot_instances, "m", _Mapricot_request).call(this, "GET", "/v1/search", { q, ...options }, signal);
|
|
29
40
|
}
|
|
30
41
|
/** Suggest addresses and places as someone types. */
|
|
31
|
-
autocomplete(q, options = {}) {
|
|
32
|
-
return this
|
|
42
|
+
autocomplete(q, { signal, ...options } = {}) {
|
|
43
|
+
return __classPrivateFieldGet(this, _Mapricot_instances, "m", _Mapricot_request).call(this, "GET", "/v1/autocomplete", { q, ...options }, signal);
|
|
33
44
|
}
|
|
34
45
|
/** Find the address nearest a coordinate, or the area around it. */
|
|
35
|
-
reverse(lat, lon, options = {}) {
|
|
36
|
-
return this
|
|
46
|
+
reverse(lat, lon, { signal, ...options } = {}) {
|
|
47
|
+
return __classPrivateFieldGet(this, _Mapricot_instances, "m", _Mapricot_request).call(this, "GET", "/v1/reverse", { lat, lon, ...options }, signal);
|
|
37
48
|
}
|
|
38
49
|
/** List places around a coordinate, optionally by category. */
|
|
39
|
-
nearby(lat, lon, options = {}) {
|
|
40
|
-
return this
|
|
50
|
+
nearby(lat, lon, { signal, ...options } = {}) {
|
|
51
|
+
return __classPrivateFieldGet(this, _Mapricot_instances, "m", _Mapricot_request).call(this, "GET", "/v1/nearby", { lat, lon, ...options }, signal);
|
|
41
52
|
}
|
|
42
53
|
/** Look up one place by its Mapricot ID. */
|
|
43
|
-
place(id, options = {}) {
|
|
44
|
-
return this
|
|
54
|
+
place(id, { signal, ...options } = {}) {
|
|
55
|
+
return __classPrivateFieldGet(this, _Mapricot_instances, "m", _Mapricot_request).call(this, "GET", `/v1/places/${encodeURIComponent(id)}`, options, signal);
|
|
45
56
|
}
|
|
46
57
|
/** Find a route through 2 to 20 waypoints. */
|
|
47
|
-
route(waypoints, options = {}) {
|
|
48
|
-
return this
|
|
58
|
+
route(waypoints, { signal, ...options } = {}) {
|
|
59
|
+
return __classPrivateFieldGet(this, _Mapricot_instances, "m", _Mapricot_request).call(this, "POST", "/v1/route", {}, signal, { waypoints, ...options });
|
|
49
60
|
}
|
|
50
61
|
/** Approximate location of a public IP address. */
|
|
51
|
-
ip(address) {
|
|
52
|
-
return this
|
|
62
|
+
ip(address, { signal } = {}) {
|
|
63
|
+
return __classPrivateFieldGet(this, _Mapricot_instances, "m", _Mapricot_request).call(this, "GET", `/v1/ip/${encodeURIComponent(address)}`, {}, signal);
|
|
53
64
|
}
|
|
54
65
|
/** The key's account. Not billed, so it checks a key for free. */
|
|
55
|
-
account() {
|
|
56
|
-
return this
|
|
66
|
+
account({ signal } = {}) {
|
|
67
|
+
return __classPrivateFieldGet(this, _Mapricot_instances, "m", _Mapricot_request).call(this, "GET", "/v1/account", {}, signal);
|
|
57
68
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
}
|
|
70
|
+
_Mapricot_apiKey = new WeakMap(), _Mapricot_baseUrl = new WeakMap(), _Mapricot_timeout = new WeakMap(), _Mapricot_maxRetries = new WeakMap(), _Mapricot_instances = new WeakSet(), _Mapricot_request = async function _Mapricot_request(method, path, params, signal, body) {
|
|
71
|
+
const url = new URL(path, __classPrivateFieldGet(this, _Mapricot_baseUrl, "f"));
|
|
72
|
+
for (const [name, value] of Object.entries(params)) {
|
|
73
|
+
if (value === undefined)
|
|
74
|
+
continue;
|
|
75
|
+
url.searchParams.set(name, format(value));
|
|
76
|
+
}
|
|
77
|
+
const headers = { Authorization: `Bearer ${__classPrivateFieldGet(this, _Mapricot_apiKey, "f")}` };
|
|
78
|
+
if (body)
|
|
79
|
+
headers["Content-Type"] = "application/json";
|
|
80
|
+
for (let attempt = 0;; attempt++) {
|
|
81
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted)
|
|
82
|
+
throw abortReason(signal);
|
|
83
|
+
// AbortSignal.timeout and AbortSignal.any would do this, but are missing from browsers before 2022 and 2024.
|
|
84
|
+
const controller = new AbortController();
|
|
85
|
+
const cancel = () => controller.abort(abortReason(signal));
|
|
86
|
+
const timer = setTimeout(() => controller.abort(new DOMException("The request timed out.", "TimeoutError")), __classPrivateFieldGet(this, _Mapricot_timeout, "f"));
|
|
87
|
+
signal === null || signal === void 0 ? void 0 : signal.addEventListener("abort", cancel);
|
|
88
|
+
let error;
|
|
89
|
+
try {
|
|
90
|
+
const response = await fetch(url, { method, headers, body: body && JSON.stringify(body), signal: controller.signal });
|
|
75
91
|
if (response.ok)
|
|
76
92
|
return (await response.json());
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
93
|
+
error = await errorFrom(response);
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
clearTimeout(timer);
|
|
97
|
+
signal === null || signal === void 0 ? void 0 : signal.removeEventListener("abort", cancel);
|
|
98
|
+
}
|
|
99
|
+
if (attempt < __classPrivateFieldGet(this, _Mapricot_maxRetries, "f") && retryable(error)) {
|
|
100
|
+
await new Promise((resolve) => setTimeout(resolve, 500 * 2 ** attempt));
|
|
101
|
+
continue;
|
|
83
102
|
}
|
|
103
|
+
throw error;
|
|
84
104
|
}
|
|
105
|
+
};
|
|
106
|
+
function abortReason(signal) {
|
|
107
|
+
var _a;
|
|
108
|
+
return (_a = signal.reason) !== null && _a !== void 0 ? _a : new DOMException("The request was cancelled.", "AbortError");
|
|
85
109
|
}
|
|
86
110
|
function format(value) {
|
|
87
111
|
if (Array.isArray(value))
|