@unmap/elevation 0.13.0 → 0.14.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 CHANGED
@@ -12,5 +12,10 @@ const [metres] = await elevation.get([-114.0719, 51.0447]);
12
12
  Heights are metres above the CGVD2013 geoid. `null` means the dataset covers nothing there; it
13
13
  never means sea level.
14
14
 
15
+ An unconfigured terrain archive throws `ElevationError` with status `404` and code `not_found`
16
+ (`terrain archive not configured`). A terrain tile that will not decode is status `502` and code
17
+ `upstream_error` (`elevation sample failed`). That `502` has no `Retry-After`. The client still
18
+ retries it, on its own backoff. A coordinate the archive does not cover stays `null`.
19
+
15
20
  `@unmap/sdk` exposes the same object as `unmap.elevation`. Full documentation:
16
- <https://unmap.dev/docs/elevation-api>.
21
+ <https://unmap.dev/docs/apis/elevation>.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import { RetryPolicy, UnmapError } from '@unmap/core';
2
+ export { RetryPolicy, UnmapError, parseRetryAfter } from '@unmap/core';
3
+
1
4
  /** [longitude, latitude]. Longitude first, everywhere in unmap. Not exported: `@unmap/routing`
2
5
  * already exports a `LngLat` of the same shape, and both packages land in `@unmap/sdk`'s star
3
6
  * exports, where two same-named exports would be a type error. */
@@ -6,6 +9,16 @@ interface ElevationOptions {
6
9
  key: string;
7
10
  gateway?: string;
8
11
  fetch?: typeof fetch;
12
+ /**
13
+ * Retry policy for `429`, `502`, `503` and transport failures. `false` disables it.
14
+ *
15
+ * On by default. `Retry-After` is on a `429` other than `billing_required`, and on a container
16
+ * `503`. A `502` has none: routing uses `routing_failed`, and `/elevation` uses
17
+ * `upstream_error`. With no header the client backs off itself. A wait longer than
18
+ * `maxDelayMs` (10 s) is not slept through; the error carries `retryAfterSeconds` instead.
19
+ * See `RetryPolicy` in `@unmap/core`.
20
+ */
21
+ retry?: RetryPolicy | false;
9
22
  }
10
23
  /** The gateway's own cap. Checked here so an over-long batch fails without spending a call. */
11
24
  declare const MAX_ELEVATION_POINTS = 1000;
@@ -20,13 +33,15 @@ declare const MAX_ELEVATION_POINTS = 1000;
20
33
  * here, against the real encoded URL, and the message says what actually fits.
21
34
  */
22
35
  declare const MAX_REQUEST_URL_BYTES = 16384;
23
- declare class ElevationError extends Error {
24
- readonly status: number;
25
- /** The gateway's machine-readable `code`, when the response carried one. */
26
- readonly code?: string | undefined;
27
- constructor(status: number, message: string,
28
- /** The gateway's machine-readable `code`, when the response carried one. */
29
- code?: string | undefined);
36
+ /**
37
+ * An elevation failure.
38
+ *
39
+ * Extends `UnmapError`, so `catch (e) { if (e instanceof UnmapError) }` catches this alongside
40
+ * every other unmap client's errors. `instanceof ElevationError` keeps working, and `status` and `code`
41
+ * are still where they were; `retryAfterSeconds` is new and comes from the header.
42
+ */
43
+ declare class ElevationError extends UnmapError {
44
+ constructor(status: number, message: string, code?: string, retryAfterSeconds?: number);
30
45
  }
31
46
  /**
32
47
  * Typed client for the unmap elevation API (gateway `/elevation`).
@@ -38,6 +53,7 @@ declare class Elevation {
38
53
  private readonly key;
39
54
  private readonly base;
40
55
  private readonly fetchImpl;
56
+ private readonly retry;
41
57
  constructor(opts: ElevationOptions);
42
58
  /**
43
59
  * Ground elevation in metres, one entry per coordinate, in the order asked.
package/dist/index.js CHANGED
@@ -1,23 +1,22 @@
1
1
  // src/index.ts
2
- import { DEFAULT_GATEWAY } from "@unmap/core";
2
+ import { DEFAULT_GATEWAY, UnmapError, fetchWithRetry, parseRetryAfter } from "@unmap/core";
3
+ import { UnmapError as UnmapError2, parseRetryAfter as parseRetryAfter2 } from "@unmap/core";
3
4
  var MAX_ELEVATION_POINTS = 1e3;
4
5
  var MAX_REQUEST_URL_BYTES = 16384;
5
6
  var URL_HEADROOM_BYTES = 256;
6
- var ElevationError = class extends Error {
7
- constructor(status, message, code) {
8
- super(message);
9
- this.status = status;
10
- this.code = code;
7
+ var ElevationError = class extends UnmapError {
8
+ constructor(status, message, code, retryAfterSeconds) {
9
+ super(status, message, code, retryAfterSeconds);
11
10
  this.name = "ElevationError";
12
11
  }
13
- status;
14
- code;
15
12
  };
16
13
  var Elevation = class {
17
14
  key;
18
15
  base;
19
16
  fetchImpl;
17
+ retry;
20
18
  constructor(opts) {
19
+ this.retry = opts.retry;
21
20
  this.key = opts.key;
22
21
  this.base = (opts.gateway ?? DEFAULT_GATEWAY).replace(/\/+$/, "");
23
22
  this.fetchImpl = opts.fetch ?? globalThis.fetch.bind(globalThis);
@@ -54,10 +53,12 @@ var Elevation = class {
54
53
  `elevation.get built a ${bytes} byte request URL; this client sends at most ${budget} bytes, keeping headroom under the edge's ${MAX_REQUEST_URL_BYTES} byte limit. Send at most about ${fits} of these coordinates per request (roughly 700 at six decimal places).`
55
54
  );
56
55
  }
57
- const res = await this.fetchImpl(target, {
58
- signal: opts.signal,
59
- headers: { accept: "application/json" }
60
- });
56
+ const res = await fetchWithRetry(
57
+ this.fetchImpl,
58
+ target,
59
+ { signal: opts.signal, headers: { accept: "application/json" } },
60
+ this.retry
61
+ );
61
62
  if (!res.ok) throw await errorFrom(res);
62
63
  const body = await res.json();
63
64
  return body.elevations;
@@ -76,12 +77,15 @@ async function errorFrom(res) {
76
77
  }
77
78
  const reason = typeof body?.error === "string" ? body.error : void 0;
78
79
  const code = typeof body?.code === "string" ? body.code : void 0;
79
- return new ElevationError(res.status, reason ? `${reason} (${fallback})` : fallback, code);
80
+ const retryAfter = parseRetryAfter(res.headers?.get("retry-after") ?? null) ?? void 0;
81
+ return new ElevationError(res.status, reason ? `${reason} (${fallback})` : fallback, code, retryAfter);
80
82
  }
81
83
  export {
82
84
  Elevation,
83
85
  ElevationError,
84
86
  MAX_ELEVATION_POINTS,
85
- MAX_REQUEST_URL_BYTES
87
+ MAX_REQUEST_URL_BYTES,
88
+ UnmapError2 as UnmapError,
89
+ parseRetryAfter2 as parseRetryAfter
86
90
  };
87
91
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { DEFAULT_GATEWAY } from \"@unmap/core\";\n\n/** [longitude, latitude]. Longitude first, everywhere in unmap. Not exported: `@unmap/routing`\n * already exports a `LngLat` of the same shape, and both packages land in `@unmap/sdk`'s star\n * exports, where two same-named exports would be a type error. */\ntype LngLat = [number, number];\n\nexport interface ElevationOptions {\n key: string;\n gateway?: string;\n fetch?: typeof fetch;\n}\n\n/** The gateway's own cap. Checked here so an over-long batch fails without spending a call. */\nexport const MAX_ELEVATION_POINTS = 1000;\n\n/**\n * Cloudflare refuses a request URL longer than this at the edge, before the Worker runs.\n *\n * It bites well before `MAX_ELEVATION_POINTS` does. `URLSearchParams` percent-encodes both of\n * the batch separators (`,` becomes `%2C`, `|` becomes `%7C`), so a coordinate costs about six\n * bytes more than it reads, and a thousand six-decimal points is roughly 22 KB of URL. Past the\n * limit the request never reaches the gateway: the caller gets an edge 414 with no error\n * envelope to explain it, which is the least legible failure in the system. So the check is\n * here, against the real encoded URL, and the message says what actually fits.\n */\nexport const MAX_REQUEST_URL_BYTES = 16384;\n\n/** Headroom under the edge limit, so a proxy that appends a parameter cannot tip a request over. */\nconst URL_HEADROOM_BYTES = 256;\n\nexport class ElevationError extends Error {\n constructor(\n public readonly status: number,\n message: string,\n /** The gateway's machine-readable `code`, when the response carried one. */\n public readonly code?: string,\n ) {\n super(message);\n this.name = \"ElevationError\";\n }\n}\n\ninterface ElevationResponse {\n elevations: (number | null)[];\n units: \"m\";\n datum: string;\n resolution: number;\n}\n\n/**\n * Typed client for the unmap elevation API (gateway `/elevation`).\n *\n * Heights are metres above CGVD2013. `null` means the dataset covers nothing at that coordinate;\n * it never means sea level, and the client does not substitute a number for it.\n */\nexport class Elevation {\n private readonly key: string;\n private readonly base: string;\n private readonly fetchImpl: typeof fetch;\n\n constructor(opts: ElevationOptions) {\n this.key = opts.key;\n this.base = (opts.gateway ?? DEFAULT_GATEWAY).replace(/\\/+$/, \"\");\n // Bound to globalThis for the same reason Router does it: a bare `fetch` stored on an\n // instance is invoked with that instance as its receiver, which browsers reject.\n this.fetchImpl = opts.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n /**\n * Ground elevation in metres, one entry per coordinate, in the order asked.\n *\n * Always an array, whether you passed one coordinate or a thousand, so the single and batch\n * cases are the same call:\n *\n * const [metres] = await unmap.elevation.get([-114.0719, 51.0447]);\n */\n async get(\n points: LngLat | LngLat[],\n opts: { signal?: AbortSignal } = {},\n ): Promise<(number | null)[]> {\n const list: LngLat[] = isSingle(points) ? [points] : points;\n if (list.length === 0) return [];\n if (list.length > MAX_ELEVATION_POINTS) {\n throw new ElevationError(400, `elevation.get takes at most ${MAX_ELEVATION_POINTS} coordinates`);\n }\n\n const q = new URLSearchParams({ key: this.key });\n if (list.length === 1) {\n // Safe: the length check above guarantees index 0 exists.\n const [lon, lat] = list[0]!;\n q.set(\"lon\", String(lon));\n q.set(\"lat\", String(lat));\n } else {\n q.set(\"points\", list.map(([lng, lat]) => `${lng},${lat}`).join(\"|\"));\n }\n\n const target = `${this.base}/elevation?${q}`;\n const bytes = new TextEncoder().encode(target).length;\n const budget = MAX_REQUEST_URL_BYTES - URL_HEADROOM_BYTES;\n if (bytes > budget) {\n // Scaled from the URL actually built, so the number quoted reflects this caller's own\n // coordinate precision rather than an average of somebody else's.\n const fits = Math.max(1, Math.floor((list.length * budget) / bytes));\n throw new ElevationError(\n 414,\n `elevation.get built a ${bytes} byte request URL; this client sends at most ${budget} ` +\n `bytes, keeping headroom under the edge's ${MAX_REQUEST_URL_BYTES} byte limit. Send ` +\n `at most about ${fits} of these coordinates per request (roughly 700 at six decimal ` +\n `places).`,\n );\n }\n\n const res = await this.fetchImpl(target, {\n signal: opts.signal,\n headers: { accept: \"application/json\" },\n });\n if (!res.ok) throw await errorFrom(res);\n const body = (await res.json()) as ElevationResponse;\n return body.elevations;\n }\n}\n\n/** `[number, number]` is a coordinate; `[[number, number], ...]` is a list of them. */\nfunction isSingle(points: LngLat | LngLat[]): points is LngLat {\n return typeof points[0] === \"number\";\n}\n\nasync function errorFrom(res: { status: number; json(): Promise<unknown> }): Promise<ElevationError> {\n const fallback = `elevation ${res.status}`;\n let body: { error?: unknown; code?: unknown } | undefined;\n try {\n body = (await res.json()) as { error?: unknown; code?: unknown };\n } catch {\n body = undefined;\n }\n const reason = typeof body?.error === \"string\" ? body.error : undefined;\n const code = typeof body?.code === \"string\" ? body.code : undefined;\n return new ElevationError(res.status, reason ? `${reason} (${fallback})` : fallback, code);\n}\n"],"mappings":";AAAA,SAAS,uBAAuB;AAczB,IAAM,uBAAuB;AAY7B,IAAM,wBAAwB;AAGrC,IAAM,qBAAqB;AAEpB,IAAM,iBAAN,cAA6B,MAAM;AAAA,EACxC,YACkB,QAChB,SAEgB,MAChB;AACA,UAAM,OAAO;AALG;AAGA;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EAPkB;AAAA,EAGA;AAKpB;AAeO,IAAM,YAAN,MAAgB;AAAA,EACJ;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,MAAwB;AAClC,SAAK,MAAM,KAAK;AAChB,SAAK,QAAQ,KAAK,WAAW,iBAAiB,QAAQ,QAAQ,EAAE;AAGhE,SAAK,YAAY,KAAK,SAAS,WAAW,MAAM,KAAK,UAAU;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,IACJ,QACA,OAAiC,CAAC,GACN;AAC5B,UAAM,OAAiB,SAAS,MAAM,IAAI,CAAC,MAAM,IAAI;AACrD,QAAI,KAAK,WAAW,EAAG,QAAO,CAAC;AAC/B,QAAI,KAAK,SAAS,sBAAsB;AACtC,YAAM,IAAI,eAAe,KAAK,+BAA+B,oBAAoB,cAAc;AAAA,IACjG;AAEA,UAAM,IAAI,IAAI,gBAAgB,EAAE,KAAK,KAAK,IAAI,CAAC;AAC/C,QAAI,KAAK,WAAW,GAAG;AAErB,YAAM,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC;AACzB,QAAE,IAAI,OAAO,OAAO,GAAG,CAAC;AACxB,QAAE,IAAI,OAAO,OAAO,GAAG,CAAC;AAAA,IAC1B,OAAO;AACL,QAAE,IAAI,UAAU,KAAK,IAAI,CAAC,CAAC,KAAK,GAAG,MAAM,GAAG,GAAG,IAAI,GAAG,EAAE,EAAE,KAAK,GAAG,CAAC;AAAA,IACrE;AAEA,UAAM,SAAS,GAAG,KAAK,IAAI,cAAc,CAAC;AAC1C,UAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,MAAM,EAAE;AAC/C,UAAM,SAAS,wBAAwB;AACvC,QAAI,QAAQ,QAAQ;AAGlB,YAAM,OAAO,KAAK,IAAI,GAAG,KAAK,MAAO,KAAK,SAAS,SAAU,KAAK,CAAC;AACnE,YAAM,IAAI;AAAA,QACR;AAAA,QACA,yBAAyB,KAAK,gDAAgD,MAAM,6CACtC,qBAAqB,mCAChD,IAAI;AAAA,MAEzB;AAAA,IACF;AAEA,UAAM,MAAM,MAAM,KAAK,UAAU,QAAQ;AAAA,MACvC,QAAQ,KAAK;AAAA,MACb,SAAS,EAAE,QAAQ,mBAAmB;AAAA,IACxC,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,OAAM,MAAM,UAAU,GAAG;AACtC,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,WAAO,KAAK;AAAA,EACd;AACF;AAGA,SAAS,SAAS,QAA6C;AAC7D,SAAO,OAAO,OAAO,CAAC,MAAM;AAC9B;AAEA,eAAe,UAAU,KAA4E;AACnG,QAAM,WAAW,aAAa,IAAI,MAAM;AACxC,MAAI;AACJ,MAAI;AACF,WAAQ,MAAM,IAAI,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACA,QAAM,SAAS,OAAO,MAAM,UAAU,WAAW,KAAK,QAAQ;AAC9D,QAAM,OAAO,OAAO,MAAM,SAAS,WAAW,KAAK,OAAO;AAC1D,SAAO,IAAI,eAAe,IAAI,QAAQ,SAAS,GAAG,MAAM,KAAK,QAAQ,MAAM,UAAU,IAAI;AAC3F;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { DEFAULT_GATEWAY, UnmapError, fetchWithRetry, parseRetryAfter, type RetryPolicy } from \"@unmap/core\";\n\n/** [longitude, latitude]. Longitude first, everywhere in unmap. Not exported: `@unmap/routing`\n * already exports a `LngLat` of the same shape, and both packages land in `@unmap/sdk`'s star\n * exports, where two same-named exports would be a type error. */\ntype LngLat = [number, number];\n\nexport interface ElevationOptions {\n key: string;\n gateway?: string;\n fetch?: typeof fetch;\n /**\n * Retry policy for `429`, `502`, `503` and transport failures. `false` disables it.\n *\n * On by default. `Retry-After` is on a `429` other than `billing_required`, and on a container\n * `503`. A `502` has none: routing uses `routing_failed`, and `/elevation` uses\n * `upstream_error`. With no header the client backs off itself. A wait longer than\n * `maxDelayMs` (10 s) is not slept through; the error carries `retryAfterSeconds` instead.\n * See `RetryPolicy` in `@unmap/core`.\n */\n retry?: RetryPolicy | false;\n}\n\n/** The gateway's own cap. Checked here so an over-long batch fails without spending a call. */\nexport const MAX_ELEVATION_POINTS = 1000;\n\n/**\n * Cloudflare refuses a request URL longer than this at the edge, before the Worker runs.\n *\n * It bites well before `MAX_ELEVATION_POINTS` does. `URLSearchParams` percent-encodes both of\n * the batch separators (`,` becomes `%2C`, `|` becomes `%7C`), so a coordinate costs about six\n * bytes more than it reads, and a thousand six-decimal points is roughly 22 KB of URL. Past the\n * limit the request never reaches the gateway: the caller gets an edge 414 with no error\n * envelope to explain it, which is the least legible failure in the system. So the check is\n * here, against the real encoded URL, and the message says what actually fits.\n */\nexport const MAX_REQUEST_URL_BYTES = 16384;\n\n/** Headroom under the edge limit, so a proxy that appends a parameter cannot tip a request over. */\nconst URL_HEADROOM_BYTES = 256;\n\n/**\n * An elevation failure.\n *\n * Extends `UnmapError`, so `catch (e) { if (e instanceof UnmapError) }` catches this alongside\n * every other unmap client's errors. `instanceof ElevationError` keeps working, and `status` and `code`\n * are still where they were; `retryAfterSeconds` is new and comes from the header.\n */\nexport class ElevationError extends UnmapError {\n constructor(status: number, message: string, code?: string, retryAfterSeconds?: number) {\n super(status, message, code, retryAfterSeconds);\n this.name = \"ElevationError\";\n }\n}\n\ninterface ElevationResponse {\n elevations: (number | null)[];\n units: \"m\";\n datum: string;\n resolution: number;\n}\n\n/**\n * Typed client for the unmap elevation API (gateway `/elevation`).\n *\n * Heights are metres above CGVD2013. `null` means the dataset covers nothing at that coordinate;\n * it never means sea level, and the client does not substitute a number for it.\n */\nexport class Elevation {\n private readonly key: string;\n private readonly base: string;\n private readonly fetchImpl: typeof fetch;\n private readonly retry: RetryPolicy | false | undefined;\n\n constructor(opts: ElevationOptions) {\n this.retry = opts.retry;\n this.key = opts.key;\n this.base = (opts.gateway ?? DEFAULT_GATEWAY).replace(/\\/+$/, \"\");\n // Bound to globalThis for the same reason Router does it: a bare `fetch` stored on an\n // instance is invoked with that instance as its receiver, which browsers reject.\n this.fetchImpl = opts.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n /**\n * Ground elevation in metres, one entry per coordinate, in the order asked.\n *\n * Always an array, whether you passed one coordinate or a thousand, so the single and batch\n * cases are the same call:\n *\n * const [metres] = await unmap.elevation.get([-114.0719, 51.0447]);\n */\n async get(\n points: LngLat | LngLat[],\n opts: { signal?: AbortSignal } = {},\n ): Promise<(number | null)[]> {\n const list: LngLat[] = isSingle(points) ? [points] : points;\n if (list.length === 0) return [];\n if (list.length > MAX_ELEVATION_POINTS) {\n throw new ElevationError(400, `elevation.get takes at most ${MAX_ELEVATION_POINTS} coordinates`);\n }\n\n const q = new URLSearchParams({ key: this.key });\n if (list.length === 1) {\n // Safe: the length check above guarantees index 0 exists.\n const [lon, lat] = list[0]!;\n q.set(\"lon\", String(lon));\n q.set(\"lat\", String(lat));\n } else {\n q.set(\"points\", list.map(([lng, lat]) => `${lng},${lat}`).join(\"|\"));\n }\n\n const target = `${this.base}/elevation?${q}`;\n const bytes = new TextEncoder().encode(target).length;\n const budget = MAX_REQUEST_URL_BYTES - URL_HEADROOM_BYTES;\n if (bytes > budget) {\n // Scaled from the URL actually built, so the number quoted reflects this caller's own\n // coordinate precision rather than an average of somebody else's.\n const fits = Math.max(1, Math.floor((list.length * budget) / bytes));\n throw new ElevationError(\n 414,\n `elevation.get built a ${bytes} byte request URL; this client sends at most ${budget} ` +\n `bytes, keeping headroom under the edge's ${MAX_REQUEST_URL_BYTES} byte limit. Send ` +\n `at most about ${fits} of these coordinates per request (roughly 700 at six decimal ` +\n `places).`,\n );\n }\n\n const res = await fetchWithRetry(\n this.fetchImpl,\n target,\n { signal: opts.signal, headers: { accept: \"application/json\" } },\n this.retry,\n );\n if (!res.ok) throw await errorFrom(res);\n const body = (await res.json()) as ElevationResponse;\n return body.elevations;\n }\n}\n\n/** `[number, number]` is a coordinate; `[[number, number], ...]` is a list of them. */\nfunction isSingle(points: LngLat | LngLat[]): points is LngLat {\n return typeof points[0] === \"number\";\n}\n\nasync function errorFrom(res: { status: number; headers?: Headers; json(): Promise<unknown> }): Promise<ElevationError> {\n const fallback = `elevation ${res.status}`;\n let body: { error?: unknown; code?: unknown } | undefined;\n try {\n body = (await res.json()) as { error?: unknown; code?: unknown };\n } catch {\n body = undefined;\n }\n const reason = typeof body?.error === \"string\" ? body.error : undefined;\n const code = typeof body?.code === \"string\" ? body.code : undefined;\n const retryAfter = parseRetryAfter(res.headers?.get(\"retry-after\") ?? null) ?? undefined;\n return new ElevationError(res.status, reason ? `${reason} (${fallback})` : fallback, code, retryAfter);\n}\n\n// The shared error type and retry policy, re-exported so a caller who installed only this\n// package can `catch (e) { if (e instanceof UnmapError) }` without adding @unmap/core.\nexport { UnmapError, parseRetryAfter, type RetryPolicy } from \"@unmap/core\";\n"],"mappings":"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","names":["UnmapError","parseRetryAfter"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unmap/elevation",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Typed client for the unmap elevation API (Canadian ground elevation)",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -10,7 +10,7 @@
10
10
  "terrain",
11
11
  "canada"
12
12
  ],
13
- "homepage": "https://unmap.dev/docs/elevation-api",
13
+ "homepage": "https://unmap.dev/docs/apis/elevation",
14
14
  "repository": {
15
15
  "type": "git",
16
16
  "url": "git+https://github.com/unmap-dev/unmap.git",
@@ -37,7 +37,7 @@
37
37
  "access": "public"
38
38
  },
39
39
  "dependencies": {
40
- "@unmap/core": "0.13.0"
40
+ "@unmap/core": "0.14.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "tsup": "^8.3.0",