nextbillion-mcp 0.1.6 → 0.1.7
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/index.js +21391 -38
- package/package.json +6 -7
- package/dist/config.d.ts +0 -17
- package/dist/config.js +0 -32
- package/dist/config.js.map +0 -1
- package/dist/core/server.d.ts +0 -13
- package/dist/core/server.js +0 -62
- package/dist/core/server.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js.map +0 -1
- package/dist/log.d.ts +0 -7
- package/dist/log.js +0 -13
- package/dist/log.js.map +0 -1
- package/dist/nbclient/client.d.ts +0 -39
- package/dist/nbclient/client.js +0 -124
- package/dist/nbclient/client.js.map +0 -1
- package/dist/nbclient/errors.d.ts +0 -13
- package/dist/nbclient/errors.js +0 -36
- package/dist/nbclient/errors.js.map +0 -1
- package/dist/tools/index.d.ts +0 -7
- package/dist/tools/index.js +0 -35
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/maps/polyline.d.ts +0 -16
- package/dist/tools/maps/polyline.js +0 -117
- package/dist/tools/maps/polyline.js.map +0 -1
- package/dist/tools/maps/static-map-image.d.ts +0 -25
- package/dist/tools/maps/static-map-image.js +0 -31
- package/dist/tools/maps/static-map-image.js.map +0 -1
- package/dist/tools/maps/static-route-map.d.ts +0 -28
- package/dist/tools/maps/static-route-map.js +0 -101
- package/dist/tools/maps/static-route-map.js.map +0 -1
- package/dist/tools/maps/static-shared.d.ts +0 -35
- package/dist/tools/maps/static-shared.js +0 -91
- package/dist/tools/maps/static-shared.js.map +0 -1
- package/dist/tools/places/geocode-batch.d.ts +0 -43
- package/dist/tools/places/geocode-batch.js +0 -54
- package/dist/tools/places/geocode-batch.js.map +0 -1
- package/dist/tools/places/geocode-reverse.d.ts +0 -30
- package/dist/tools/places/geocode-reverse.js +0 -33
- package/dist/tools/places/geocode-reverse.js.map +0 -1
- package/dist/tools/places/geocode-structured.d.ts +0 -40
- package/dist/tools/places/geocode-structured.js +0 -61
- package/dist/tools/places/geocode-structured.js.map +0 -1
- package/dist/tools/places/place-lookup.d.ts +0 -19
- package/dist/tools/places/place-lookup.js +0 -24
- package/dist/tools/places/place-lookup.js.map +0 -1
- package/dist/tools/places/postcode-lookup.d.ts +0 -13
- package/dist/tools/places/postcode-lookup.js +0 -56
- package/dist/tools/places/postcode-lookup.js.map +0 -1
- package/dist/tools/places/text-search.d.ts +0 -128
- package/dist/tools/places/text-search.js +0 -80
- package/dist/tools/places/text-search.js.map +0 -1
- package/dist/tools/routing/directions.d.ts +0 -59
- package/dist/tools/routing/directions.js +0 -116
- package/dist/tools/routing/directions.js.map +0 -1
- package/dist/tools/routing/distance-matrix.d.ts +0 -43
- package/dist/tools/routing/distance-matrix.js +0 -82
- package/dist/tools/routing/distance-matrix.js.map +0 -1
- package/dist/tools/routing/isochrone.d.ts +0 -22
- package/dist/tools/routing/isochrone.js +0 -67
- package/dist/tools/routing/isochrone.js.map +0 -1
- package/dist/tools/routing/search-along-route.d.ts +0 -17
- package/dist/tools/routing/search-along-route.js +0 -58
- package/dist/tools/routing/search-along-route.js.map +0 -1
- package/dist/tools/shared/geo.d.ts +0 -89
- package/dist/tools/shared/geo.js +0 -100
- package/dist/tools/shared/geo.js.map +0 -1
- package/dist/tools/types.d.ts +0 -46
- package/dist/tools/types.js +0 -23
- package/dist/tools/types.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nextbillion-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "MCP server exposing NextBillion.ai location APIs (geocoding, places, routing, maps) as tools for AI agents",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -29,21 +29,20 @@
|
|
|
29
29
|
],
|
|
30
30
|
"scripts": {
|
|
31
31
|
"prepublishOnly": "npm run typecheck && npm run test && npm run build",
|
|
32
|
-
"build": "
|
|
32
|
+
"build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && esbuild src/index.ts --bundle --platform=node --format=esm --target=node20 --outfile=dist/index.js --log-level=warning && node -e \"require('fs').chmodSync('dist/index.js', 0o755)\"",
|
|
33
33
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
34
34
|
"test": "vitest run tests/unit tests/conformance",
|
|
35
35
|
"test:e2e": "vitest run tests/e2e",
|
|
36
36
|
"dev": "tsx src/index.ts"
|
|
37
37
|
},
|
|
38
|
-
"dependencies": {
|
|
39
|
-
"@modelcontextprotocol/server": "^2.0.0",
|
|
40
|
-
"zod": "^4.2.0"
|
|
41
|
-
},
|
|
42
38
|
"devDependencies": {
|
|
43
39
|
"@modelcontextprotocol/client": "^2.0.0",
|
|
40
|
+
"@modelcontextprotocol/server": "^2.0.0",
|
|
44
41
|
"@types/node": "^24.0.0",
|
|
42
|
+
"esbuild": "^0.28.2",
|
|
45
43
|
"tsx": "^4.23.0",
|
|
46
44
|
"typescript": "^7.0.0",
|
|
47
|
-
"vitest": "^4.1.0"
|
|
45
|
+
"vitest": "^4.1.0",
|
|
46
|
+
"zod": "^4.2.0"
|
|
48
47
|
}
|
|
49
48
|
}
|
package/dist/config.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export interface ServerConfig {
|
|
2
|
-
apiKey: string;
|
|
3
|
-
baseUrl: string;
|
|
4
|
-
timeoutMs: number;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Directory where rendered map images are saved (in addition to being returned inline).
|
|
8
|
-
* Terminal-based MCP clients such as the Codex CLI cannot display image content, so a
|
|
9
|
-
* local file path in the result text is the only way for those users to see the map.
|
|
10
|
-
*/
|
|
11
|
-
export declare function imageOutputDir(env?: NodeJS.ProcessEnv): string;
|
|
12
|
-
export declare const DEFAULT_BASE_URL = "https://api.nextbillion.io";
|
|
13
|
-
export declare const DEFAULT_TIMEOUT_MS = 30000;
|
|
14
|
-
export declare class ConfigError extends Error {
|
|
15
|
-
}
|
|
16
|
-
/** Read configuration from environment variables. Throws ConfigError when the API key is missing. */
|
|
17
|
-
export declare function loadConfig(env?: NodeJS.ProcessEnv): ServerConfig;
|
package/dist/config.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { tmpdir } from 'node:os';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
/**
|
|
4
|
-
* Directory where rendered map images are saved (in addition to being returned inline).
|
|
5
|
-
* Terminal-based MCP clients such as the Codex CLI cannot display image content, so a
|
|
6
|
-
* local file path in the result text is the only way for those users to see the map.
|
|
7
|
-
*/
|
|
8
|
-
export function imageOutputDir(env = process.env) {
|
|
9
|
-
return env.NBAI_IMAGE_DIR?.trim() || join(tmpdir(), 'nextbillion-mcp');
|
|
10
|
-
}
|
|
11
|
-
export const DEFAULT_BASE_URL = 'https://api.nextbillion.io';
|
|
12
|
-
export const DEFAULT_TIMEOUT_MS = 30_000;
|
|
13
|
-
export class ConfigError extends Error {
|
|
14
|
-
}
|
|
15
|
-
/** Read configuration from environment variables. Throws ConfigError when the API key is missing. */
|
|
16
|
-
export function loadConfig(env = process.env) {
|
|
17
|
-
const apiKey = env.NBAI_API_KEY?.trim();
|
|
18
|
-
if (!apiKey) {
|
|
19
|
-
throw new ConfigError('NBAI_API_KEY is not set. Get an API key at https://console.nextbillion.ai and ' +
|
|
20
|
-
'expose it to the server, e.g. NBAI_API_KEY=<your key> npx nextbillion-mcp');
|
|
21
|
-
}
|
|
22
|
-
const timeoutMs = env.NBAI_TIMEOUT_MS ? Number(env.NBAI_TIMEOUT_MS) : DEFAULT_TIMEOUT_MS;
|
|
23
|
-
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
24
|
-
throw new ConfigError(`NBAI_TIMEOUT_MS must be a positive number, got: ${env.NBAI_TIMEOUT_MS}`);
|
|
25
|
-
}
|
|
26
|
-
return {
|
|
27
|
-
apiKey,
|
|
28
|
-
baseUrl: (env.NBAI_BASE_URL?.trim() || DEFAULT_BASE_URL).replace(/\/+$/, ''),
|
|
29
|
-
timeoutMs,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAQjC;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG;IACjE,OAAO,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,4BAA4B,CAAC;AAC7D,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAEzC,MAAM,OAAO,WAAY,SAAQ,KAAK;CAAG;AAEzC,qGAAqG;AACrG,MAAM,UAAU,UAAU,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG;IAC7D,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC;IACxC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,WAAW,CACnB,gFAAgF;YAC9E,2EAA2E,CAC9E,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACzF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,WAAW,CAAC,mDAAmD,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;IAClG,CAAC;IACD,OAAO;QACL,MAAM;QACN,OAAO,EAAE,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC5E,SAAS;KACV,CAAC;AACJ,CAAC"}
|
package/dist/core/server.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { McpServer } from '@modelcontextprotocol/server';
|
|
2
|
-
import type { NbClient } from '../nbclient/client.js';
|
|
3
|
-
export declare const SERVER_NAME = "nextbillion-mcp";
|
|
4
|
-
/**
|
|
5
|
-
* Build one McpServer instance wired to the given NextBillion API client.
|
|
6
|
-
* Used as the per-connection factory for serveStdio (and later HTTP serving).
|
|
7
|
-
*
|
|
8
|
-
* 2026-07-28 spec notes: the SDK provides server/discover, per-request _meta
|
|
9
|
-
* validation, and resultType stamping. The deprecated Roots/Sampling/Logging
|
|
10
|
-
* features are intentionally not implemented. The tool list is static, so
|
|
11
|
-
* tools/list advertises a 24h public cache hint.
|
|
12
|
-
*/
|
|
13
|
-
export declare function buildServer(nb: NbClient, version: string): McpServer;
|
package/dist/core/server.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { McpServer } from '@modelcontextprotocol/server';
|
|
2
|
-
import { NbApiError } from '../nbclient/errors.js';
|
|
3
|
-
import { ALL_TOOLS } from '../tools/index.js';
|
|
4
|
-
import { ToolInputError } from '../tools/types.js';
|
|
5
|
-
import { logError } from '../log.js';
|
|
6
|
-
export const SERVER_NAME = 'nextbillion-mcp';
|
|
7
|
-
/**
|
|
8
|
-
* Build one McpServer instance wired to the given NextBillion API client.
|
|
9
|
-
* Used as the per-connection factory for serveStdio (and later HTTP serving).
|
|
10
|
-
*
|
|
11
|
-
* 2026-07-28 spec notes: the SDK provides server/discover, per-request _meta
|
|
12
|
-
* validation, and resultType stamping. The deprecated Roots/Sampling/Logging
|
|
13
|
-
* features are intentionally not implemented. The tool list is static, so
|
|
14
|
-
* tools/list advertises a 24h public cache hint.
|
|
15
|
-
*/
|
|
16
|
-
export function buildServer(nb, version) {
|
|
17
|
-
const server = new McpServer({ name: SERVER_NAME, version }, {
|
|
18
|
-
capabilities: { tools: {} },
|
|
19
|
-
cacheHints: {
|
|
20
|
-
'tools/list': { ttlMs: 86_400_000, cacheScope: 'public' },
|
|
21
|
-
},
|
|
22
|
-
});
|
|
23
|
-
for (const tool of ALL_TOOLS) {
|
|
24
|
-
server.registerTool(tool.name, {
|
|
25
|
-
title: tool.title,
|
|
26
|
-
description: tool.description,
|
|
27
|
-
inputSchema: tool.inputSchema,
|
|
28
|
-
annotations: tool.annotations,
|
|
29
|
-
}, async (args) => {
|
|
30
|
-
try {
|
|
31
|
-
return await tool.run(args, nb);
|
|
32
|
-
}
|
|
33
|
-
catch (error) {
|
|
34
|
-
return toToolError(tool.name, error);
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
return server;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Upstream API failures and input validation problems come back as ordinary tool
|
|
42
|
-
* results with isError, so the model can read the message and correct its call.
|
|
43
|
-
*/
|
|
44
|
-
function toToolError(toolName, error) {
|
|
45
|
-
if (error instanceof ToolInputError) {
|
|
46
|
-
return { content: [{ type: 'text', text: `Invalid input: ${error.message}` }], isError: true };
|
|
47
|
-
}
|
|
48
|
-
if (error instanceof NbApiError) {
|
|
49
|
-
return { content: [{ type: 'text', text: error.message }], isError: true };
|
|
50
|
-
}
|
|
51
|
-
logError(`Unexpected error in tool ${toolName}`, error);
|
|
52
|
-
return {
|
|
53
|
-
content: [
|
|
54
|
-
{
|
|
55
|
-
type: 'text',
|
|
56
|
-
text: `Unexpected error in ${toolName}: ${error instanceof Error ? error.message : String(error)}`,
|
|
57
|
-
},
|
|
58
|
-
],
|
|
59
|
-
isError: true,
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
//# sourceMappingURL=server.js.map
|
package/dist/core/server.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/core/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAmB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,CAAC,MAAM,WAAW,GAAG,iBAAiB,CAAC;AAE7C;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,EAAY,EAAE,OAAe;IACvD,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,EAC9B;QACE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAC3B,UAAU,EAAE;YACV,YAAY,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE;SAC1D;KACF,CACF,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,CAAC,YAAY,CACjB,IAAI,CAAC,IAAI,EACT;YACE,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,EACD,KAAK,EAAE,IAAa,EAAuB,EAAE;YAC3C,IAAI,CAAC;gBACH,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,IAAa,EAAE,EAAE,CAAC,CAAC;YAC3C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACvC,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAAC,QAAgB,EAAE,KAAc;IACnD,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;QACpC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACjG,CAAC;IACD,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7E,CAAC;IACD,QAAQ,CAAC,4BAA4B,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC;IACxD,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,uBAAuB,QAAQ,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;aACnG;SACF;QACD,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
DELETED
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAwB,CAAC;AAErF,SAAS,IAAI;IACX,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzB,OAAO;IACT,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CACT,GAAG,WAAW,IAAI,GAAG,CAAC,OAAO,oDAAoD;YAC/E,gFAAgF;YAChF,0BAA0B;YAC1B,yDAAyD;YACzD,mFAAmF;YACnF,qEAAqE;YACrE,gGAAgG,CACnG,CAAC;QACF,OAAO;IACT,CAAC;IAED,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,UAAU,EAAE,CAAC;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;YACjC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACxB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,WAAW,IAAI,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC;IAE5D,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC"}
|
package/dist/log.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* stdout is the JSON-RPC channel on stdio transports, so all logging goes to stderr.
|
|
3
|
-
* The MCP `logging` capability is deprecated in the 2026-07-28 revision; stderr is
|
|
4
|
-
* the recommended channel for locally-spawned servers.
|
|
5
|
-
*/
|
|
6
|
-
export declare function logError(message: string, error?: unknown): void;
|
|
7
|
-
export declare function logInfo(message: string): void;
|
package/dist/log.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* stdout is the JSON-RPC channel on stdio transports, so all logging goes to stderr.
|
|
3
|
-
* The MCP `logging` capability is deprecated in the 2026-07-28 revision; stderr is
|
|
4
|
-
* the recommended channel for locally-spawned servers.
|
|
5
|
-
*/
|
|
6
|
-
export function logError(message, error) {
|
|
7
|
-
const detail = error instanceof Error ? `: ${error.message}` : error ? `: ${String(error)}` : '';
|
|
8
|
-
console.error(`[nextbillion-mcp] ${message}${detail}`);
|
|
9
|
-
}
|
|
10
|
-
export function logInfo(message) {
|
|
11
|
-
console.error(`[nextbillion-mcp] ${message}`);
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=log.js.map
|
package/dist/log.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,KAAe;IACvD,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACjG,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,GAAG,MAAM,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
export type QueryValue = string | number | boolean | undefined;
|
|
2
|
-
/** Arrays produce repeated query parameters (e.g. several `path=` entries). */
|
|
3
|
-
export type Query = Record<string, QueryValue | QueryValue[]>;
|
|
4
|
-
export interface NbClientOptions {
|
|
5
|
-
apiKey: string;
|
|
6
|
-
baseUrl?: string;
|
|
7
|
-
timeoutMs?: number;
|
|
8
|
-
/** Injectable for tests. Defaults to global fetch. */
|
|
9
|
-
fetchFn?: typeof fetch;
|
|
10
|
-
/** Max retries for 429/5xx/network failures on idempotent requests. */
|
|
11
|
-
maxRetries?: number;
|
|
12
|
-
/** Injectable for tests. Defaults to a real delay. */
|
|
13
|
-
sleepFn?: (ms: number) => Promise<void>;
|
|
14
|
-
}
|
|
15
|
-
export interface BinaryResponse {
|
|
16
|
-
data: Uint8Array;
|
|
17
|
-
contentType: string;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Single HTTP client shared by every tool: injects the API key, applies timeouts,
|
|
21
|
-
* retries transient failures with backoff, and normalizes errors. All NextBillion
|
|
22
|
-
* endpoints authenticate via the `key` query parameter.
|
|
23
|
-
*/
|
|
24
|
-
export declare class NbClient {
|
|
25
|
-
private readonly apiKey;
|
|
26
|
-
private readonly baseUrl;
|
|
27
|
-
private readonly timeoutMs;
|
|
28
|
-
private readonly fetchFn;
|
|
29
|
-
private readonly maxRetries;
|
|
30
|
-
private readonly sleepFn;
|
|
31
|
-
constructor(options: NbClientOptions);
|
|
32
|
-
buildUrl(path: string, query?: Query): string;
|
|
33
|
-
getJson<T = unknown>(path: string, query?: Query): Promise<T>;
|
|
34
|
-
postJson<T = unknown>(path: string, query: Query, body: unknown): Promise<T>;
|
|
35
|
-
getBinary(path: string, query?: Query): Promise<BinaryResponse>;
|
|
36
|
-
private request;
|
|
37
|
-
private backoffMs;
|
|
38
|
-
private parseJson;
|
|
39
|
-
}
|
package/dist/nbclient/client.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { NbApiError, redactKey } from './errors.js';
|
|
2
|
-
const RETRIABLE_STATUSES = new Set([429, 502, 503, 504]);
|
|
3
|
-
function sleep(ms) {
|
|
4
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Single HTTP client shared by every tool: injects the API key, applies timeouts,
|
|
8
|
-
* retries transient failures with backoff, and normalizes errors. All NextBillion
|
|
9
|
-
* endpoints authenticate via the `key` query parameter.
|
|
10
|
-
*/
|
|
11
|
-
export class NbClient {
|
|
12
|
-
apiKey;
|
|
13
|
-
baseUrl;
|
|
14
|
-
timeoutMs;
|
|
15
|
-
fetchFn;
|
|
16
|
-
maxRetries;
|
|
17
|
-
sleepFn;
|
|
18
|
-
constructor(options) {
|
|
19
|
-
this.apiKey = options.apiKey;
|
|
20
|
-
this.baseUrl = (options.baseUrl ?? 'https://api.nextbillion.io').replace(/\/+$/, '');
|
|
21
|
-
this.timeoutMs = options.timeoutMs ?? 30_000;
|
|
22
|
-
this.fetchFn = options.fetchFn ?? fetch;
|
|
23
|
-
this.maxRetries = options.maxRetries ?? 2;
|
|
24
|
-
this.sleepFn = options.sleepFn ?? sleep;
|
|
25
|
-
}
|
|
26
|
-
buildUrl(path, query = {}) {
|
|
27
|
-
const url = new URL(this.baseUrl + path);
|
|
28
|
-
url.searchParams.set('key', this.apiKey);
|
|
29
|
-
for (const [name, value] of Object.entries(query)) {
|
|
30
|
-
for (const entry of Array.isArray(value) ? value : [value]) {
|
|
31
|
-
if (entry !== undefined)
|
|
32
|
-
url.searchParams.append(name, String(entry));
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return url.toString();
|
|
36
|
-
}
|
|
37
|
-
async getJson(path, query = {}) {
|
|
38
|
-
const response = await this.request('GET', this.buildUrl(path, query));
|
|
39
|
-
return this.parseJson(response);
|
|
40
|
-
}
|
|
41
|
-
async postJson(path, query, body) {
|
|
42
|
-
const response = await this.request('POST', this.buildUrl(path, query), body);
|
|
43
|
-
return this.parseJson(response);
|
|
44
|
-
}
|
|
45
|
-
async getBinary(path, query = {}) {
|
|
46
|
-
const response = await this.request('GET', this.buildUrl(path, query));
|
|
47
|
-
return {
|
|
48
|
-
data: new Uint8Array(await response.arrayBuffer()),
|
|
49
|
-
contentType: response.headers.get('content-type') ?? 'application/octet-stream',
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
async request(method, url, body) {
|
|
53
|
-
// POST bodies here are all idempotent queries (search/matrix/geocode), so retrying is safe.
|
|
54
|
-
let lastError;
|
|
55
|
-
for (let attempt = 0;; attempt++) {
|
|
56
|
-
let response;
|
|
57
|
-
try {
|
|
58
|
-
response = await this.fetchFn(url, {
|
|
59
|
-
method,
|
|
60
|
-
headers: body !== undefined ? { 'Content-Type': 'application/json' } : undefined,
|
|
61
|
-
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
62
|
-
signal: AbortSignal.timeout(this.timeoutMs),
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
catch (error) {
|
|
66
|
-
const timedOut = error instanceof DOMException && error.name === 'TimeoutError';
|
|
67
|
-
lastError = new NbApiError({
|
|
68
|
-
url,
|
|
69
|
-
message: timedOut
|
|
70
|
-
? `Request timed out after ${this.timeoutMs} ms`
|
|
71
|
-
: `Network error: ${error instanceof Error ? error.message : String(error)}`,
|
|
72
|
-
});
|
|
73
|
-
if (attempt < this.maxRetries && !timedOut) {
|
|
74
|
-
await this.sleepFn(this.backoffMs(attempt));
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
throw lastError;
|
|
78
|
-
}
|
|
79
|
-
if (response.ok)
|
|
80
|
-
return response;
|
|
81
|
-
const errorBody = await response.text().catch(() => '');
|
|
82
|
-
lastError = new NbApiError({
|
|
83
|
-
status: response.status,
|
|
84
|
-
url,
|
|
85
|
-
body: errorBody,
|
|
86
|
-
message: extractApiMessage(errorBody),
|
|
87
|
-
});
|
|
88
|
-
if (RETRIABLE_STATUSES.has(response.status) && attempt < this.maxRetries) {
|
|
89
|
-
await this.sleepFn(this.backoffMs(attempt));
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
throw lastError;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
backoffMs(attempt) {
|
|
96
|
-
return 300 * 2 ** attempt + Math.floor(Math.random() * 100);
|
|
97
|
-
}
|
|
98
|
-
async parseJson(response) {
|
|
99
|
-
const text = await response.text();
|
|
100
|
-
try {
|
|
101
|
-
return JSON.parse(text);
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
throw new NbApiError({
|
|
105
|
-
status: response.status,
|
|
106
|
-
url: response.url ?? '',
|
|
107
|
-
body: text,
|
|
108
|
-
message: `Expected JSON response but got: ${redactKey(text.slice(0, 200))}`,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
/** NextBillion error bodies vary: some use {status, msg}, others {code, message}. */
|
|
114
|
-
function extractApiMessage(bodyText) {
|
|
115
|
-
try {
|
|
116
|
-
const parsed = JSON.parse(bodyText);
|
|
117
|
-
const message = parsed.msg ?? parsed.message ?? parsed.error;
|
|
118
|
-
return typeof message === 'string' && message.length > 0 ? message : undefined;
|
|
119
|
-
}
|
|
120
|
-
catch {
|
|
121
|
-
return bodyText.length > 0 && bodyText.length <= 300 ? bodyText : undefined;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
//# sourceMappingURL=client.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/nbclient/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/** Replace the API key value in any URL or message so it never leaks into tool results or logs. */
|
|
2
|
-
export declare function redactKey(text: string): string;
|
|
3
|
-
export declare class NbApiError extends Error {
|
|
4
|
-
readonly status: number | undefined;
|
|
5
|
-
readonly url: string;
|
|
6
|
-
readonly body: unknown;
|
|
7
|
-
constructor(options: {
|
|
8
|
-
status?: number;
|
|
9
|
-
url: string;
|
|
10
|
-
body?: unknown;
|
|
11
|
-
message?: string;
|
|
12
|
-
});
|
|
13
|
-
}
|
package/dist/nbclient/errors.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/** Replace the API key value in any URL or message so it never leaks into tool results or logs. */
|
|
2
|
-
export function redactKey(text) {
|
|
3
|
-
return text.replace(/([?&]key=)[^&\s'"]+/gi, '$1***');
|
|
4
|
-
}
|
|
5
|
-
const STATUS_HINTS = {
|
|
6
|
-
400: 'Input validation failed — a parameter is missing, malformed, or has an invalid value.',
|
|
7
|
-
401: 'API key is missing or invalid.',
|
|
8
|
-
403: 'API key is valid but has no access to this service or geographic region.',
|
|
9
|
-
404: 'Endpoint not found.',
|
|
10
|
-
413: 'Request URL or body is too large.',
|
|
11
|
-
414: 'Request URL is too long (max 8192 bytes) — use an encoded polyline or fewer points.',
|
|
12
|
-
422: 'The request is valid but no result could be produced (e.g. unroutable coordinates or no matching places).',
|
|
13
|
-
429: 'Rate limit or usage quota exceeded. Retry later or batch requests.',
|
|
14
|
-
500: 'NextBillion API internal error.',
|
|
15
|
-
};
|
|
16
|
-
export class NbApiError extends Error {
|
|
17
|
-
status;
|
|
18
|
-
url;
|
|
19
|
-
body;
|
|
20
|
-
constructor(options) {
|
|
21
|
-
const hint = options.status !== undefined ? STATUS_HINTS[options.status] : undefined;
|
|
22
|
-
const parts = [
|
|
23
|
-
options.status !== undefined
|
|
24
|
-
? `NextBillion API error (HTTP ${options.status})`
|
|
25
|
-
: 'NextBillion API request failed',
|
|
26
|
-
options.message,
|
|
27
|
-
hint,
|
|
28
|
-
].filter(Boolean);
|
|
29
|
-
super(redactKey(parts.join(': ')));
|
|
30
|
-
this.name = 'NbApiError';
|
|
31
|
-
this.status = options.status;
|
|
32
|
-
this.url = redactKey(options.url);
|
|
33
|
-
this.body = options.body;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
//# sourceMappingURL=errors.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/nbclient/errors.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,IAAI,CAAC,OAAO,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,YAAY,GAA2B;IAC3C,GAAG,EAAE,uFAAuF;IAC5F,GAAG,EAAE,gCAAgC;IACrC,GAAG,EAAE,0EAA0E;IAC/E,GAAG,EAAE,qBAAqB;IAC1B,GAAG,EAAE,mCAAmC;IACxC,GAAG,EAAE,qFAAqF;IAC1F,GAAG,EAAE,2GAA2G;IAChH,GAAG,EAAE,oEAAoE;IACzE,GAAG,EAAE,iCAAiC;CACvC,CAAC;AAEF,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,MAAM,CAAqB;IAC3B,GAAG,CAAS;IACZ,IAAI,CAAU;IAEvB,YAAY,OAA2E;QACrF,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACrF,MAAM,KAAK,GAAG;YACZ,OAAO,CAAC,MAAM,KAAK,SAAS;gBAC1B,CAAC,CAAC,+BAA+B,OAAO,CAAC,MAAM,GAAG;gBAClD,CAAC,CAAC,gCAAgC;YACpC,OAAO,CAAC,OAAO;YACf,IAAI;SACL,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAClB,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;CACF"}
|
package/dist/tools/index.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { NbTool } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Every tool served by this MCP server, sorted by name. The order is deliberately
|
|
4
|
-
* deterministic: the 2026-07-28 revision requires list results not to vary per
|
|
5
|
-
* connection, and a stable order improves client-side prompt-cache hits.
|
|
6
|
-
*/
|
|
7
|
-
export declare const ALL_TOOLS: ReadonlyArray<NbTool>;
|
package/dist/tools/index.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { autocomplete, autosuggest, geocodeForward, placeSearch } from './places/text-search.js';
|
|
2
|
-
import { geocodeBatch } from './places/geocode-batch.js';
|
|
3
|
-
import { geocodeReverse } from './places/geocode-reverse.js';
|
|
4
|
-
import { geocodeStructured } from './places/geocode-structured.js';
|
|
5
|
-
import { placeLookup } from './places/place-lookup.js';
|
|
6
|
-
import { postcodeLookup } from './places/postcode-lookup.js';
|
|
7
|
-
import { directions } from './routing/directions.js';
|
|
8
|
-
import { distanceMatrix } from './routing/distance-matrix.js';
|
|
9
|
-
import { isochrone } from './routing/isochrone.js';
|
|
10
|
-
import { searchAlongRoute } from './routing/search-along-route.js';
|
|
11
|
-
import { staticMapImage } from './maps/static-map-image.js';
|
|
12
|
-
import { staticRouteMap } from './maps/static-route-map.js';
|
|
13
|
-
/**
|
|
14
|
-
* Every tool served by this MCP server, sorted by name. The order is deliberately
|
|
15
|
-
* deterministic: the 2026-07-28 revision requires list results not to vary per
|
|
16
|
-
* connection, and a stable order improves client-side prompt-cache hits.
|
|
17
|
-
*/
|
|
18
|
-
export const ALL_TOOLS = [
|
|
19
|
-
autocomplete,
|
|
20
|
-
autosuggest,
|
|
21
|
-
directions,
|
|
22
|
-
distanceMatrix,
|
|
23
|
-
geocodeBatch,
|
|
24
|
-
geocodeForward,
|
|
25
|
-
geocodeReverse,
|
|
26
|
-
geocodeStructured,
|
|
27
|
-
isochrone,
|
|
28
|
-
placeLookup,
|
|
29
|
-
placeSearch,
|
|
30
|
-
postcodeLookup,
|
|
31
|
-
searchAlongRoute,
|
|
32
|
-
staticMapImage,
|
|
33
|
-
staticRouteMap,
|
|
34
|
-
].sort((a, b) => a.name.localeCompare(b.name));
|
|
35
|
-
//# sourceMappingURL=index.js.map
|
package/dist/tools/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACjG,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAA0B;IAC9C,YAAY;IACZ,WAAW;IACX,UAAU;IACV,cAAc;IACd,YAAY;IACZ,cAAc;IACd,cAAc;IACd,iBAAiB;IACjB,SAAS;IACT,WAAW;IACX,WAAW;IACX,cAAc;IACd,gBAAgB;IAChB,cAAc;IACd,cAAc;CACf,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { Coordinate } from '../shared/geo.js';
|
|
2
|
-
export declare function decodePolyline(encoded: string): Coordinate[];
|
|
3
|
-
export declare function encodePolyline(points: Coordinate[]): string;
|
|
4
|
-
/** Douglas-Peucker simplification with the tolerance in approximate meters. */
|
|
5
|
-
export declare function simplifyPoints(points: Coordinate[], toleranceMeters: number): Coordinate[];
|
|
6
|
-
export interface FittedGeometry {
|
|
7
|
-
encoded: string;
|
|
8
|
-
originalPointCount: number;
|
|
9
|
-
pointCount: number;
|
|
10
|
-
simplified: boolean;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Return an encoded polyline whose length is at most `maxEncodedChars`, simplifying
|
|
14
|
-
* with progressively coarser tolerances until it fits (or only endpoints remain).
|
|
15
|
-
*/
|
|
16
|
-
export declare function fitPolylineToBudget(points: Coordinate[], maxEncodedChars: number): FittedGeometry;
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Google encoded polyline codec (precision 5) plus Douglas-Peucker simplification.
|
|
3
|
-
* Used to shrink long route geometries so the static-image GET URL stays within
|
|
4
|
-
* the API's 8192-byte limit: a 600 km route encodes to ~30k characters (~50 kB
|
|
5
|
-
* URL-encoded), far beyond what the endpoint accepts.
|
|
6
|
-
*/
|
|
7
|
-
const PRECISION = 1e5;
|
|
8
|
-
export function decodePolyline(encoded) {
|
|
9
|
-
const points = [];
|
|
10
|
-
let index = 0;
|
|
11
|
-
let lat = 0;
|
|
12
|
-
let lng = 0;
|
|
13
|
-
while (index < encoded.length) {
|
|
14
|
-
lat += readVarint();
|
|
15
|
-
lng += readVarint();
|
|
16
|
-
points.push({ latitude: lat / PRECISION, longitude: lng / PRECISION });
|
|
17
|
-
}
|
|
18
|
-
return points;
|
|
19
|
-
function readVarint() {
|
|
20
|
-
let result = 0;
|
|
21
|
-
let shift = 0;
|
|
22
|
-
let byte;
|
|
23
|
-
do {
|
|
24
|
-
byte = encoded.charCodeAt(index++) - 63;
|
|
25
|
-
result |= (byte & 0x1f) << shift;
|
|
26
|
-
shift += 5;
|
|
27
|
-
} while (byte >= 0x20);
|
|
28
|
-
return result & 1 ? ~(result >> 1) : result >> 1;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
export function encodePolyline(points) {
|
|
32
|
-
let output = '';
|
|
33
|
-
let prevLat = 0;
|
|
34
|
-
let prevLng = 0;
|
|
35
|
-
for (const point of points) {
|
|
36
|
-
const lat = Math.round(point.latitude * PRECISION);
|
|
37
|
-
const lng = Math.round(point.longitude * PRECISION);
|
|
38
|
-
output += encodeValue(lat - prevLat) + encodeValue(lng - prevLng);
|
|
39
|
-
prevLat = lat;
|
|
40
|
-
prevLng = lng;
|
|
41
|
-
}
|
|
42
|
-
return output;
|
|
43
|
-
function encodeValue(value) {
|
|
44
|
-
let v = value < 0 ? ~(value << 1) : value << 1;
|
|
45
|
-
let chunk = '';
|
|
46
|
-
while (v >= 0x20) {
|
|
47
|
-
chunk += String.fromCharCode((0x20 | (v & 0x1f)) + 63);
|
|
48
|
-
v >>= 5;
|
|
49
|
-
}
|
|
50
|
-
return chunk + String.fromCharCode(v + 63);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
/** Douglas-Peucker simplification with the tolerance in approximate meters. */
|
|
54
|
-
export function simplifyPoints(points, toleranceMeters) {
|
|
55
|
-
if (points.length <= 2 || toleranceMeters <= 0)
|
|
56
|
-
return points;
|
|
57
|
-
const keep = new Array(points.length).fill(false);
|
|
58
|
-
keep[0] = keep[points.length - 1] = true;
|
|
59
|
-
const stack = [[0, points.length - 1]];
|
|
60
|
-
while (stack.length > 0) {
|
|
61
|
-
const [start, end] = stack.pop();
|
|
62
|
-
let maxDistance = 0;
|
|
63
|
-
let maxIndex = -1;
|
|
64
|
-
for (let i = start + 1; i < end; i++) {
|
|
65
|
-
const distance = perpendicularDistanceMeters(points[i], points[start], points[end]);
|
|
66
|
-
if (distance > maxDistance) {
|
|
67
|
-
maxDistance = distance;
|
|
68
|
-
maxIndex = i;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
if (maxIndex !== -1 && maxDistance > toleranceMeters) {
|
|
72
|
-
keep[maxIndex] = true;
|
|
73
|
-
stack.push([start, maxIndex], [maxIndex, end]);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return points.filter((_, i) => keep[i]);
|
|
77
|
-
}
|
|
78
|
-
/** Planar approximation (equirectangular) — accurate enough for display-level simplification. */
|
|
79
|
-
function perpendicularDistanceMeters(p, a, b) {
|
|
80
|
-
const metersPerDegLat = 111_320;
|
|
81
|
-
const cosLat = Math.cos((a.latitude * Math.PI) / 180);
|
|
82
|
-
const toXY = (c) => ({
|
|
83
|
-
x: c.longitude * metersPerDegLat * cosLat,
|
|
84
|
-
y: c.latitude * metersPerDegLat,
|
|
85
|
-
});
|
|
86
|
-
const P = toXY(p);
|
|
87
|
-
const A = toXY(a);
|
|
88
|
-
const B = toXY(b);
|
|
89
|
-
const dx = B.x - A.x;
|
|
90
|
-
const dy = B.y - A.y;
|
|
91
|
-
const lengthSquared = dx * dx + dy * dy;
|
|
92
|
-
if (lengthSquared === 0)
|
|
93
|
-
return Math.hypot(P.x - A.x, P.y - A.y);
|
|
94
|
-
const t = Math.max(0, Math.min(1, ((P.x - A.x) * dx + (P.y - A.y) * dy) / lengthSquared));
|
|
95
|
-
return Math.hypot(P.x - (A.x + t * dx), P.y - (A.y + t * dy));
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Return an encoded polyline whose length is at most `maxEncodedChars`, simplifying
|
|
99
|
-
* with progressively coarser tolerances until it fits (or only endpoints remain).
|
|
100
|
-
*/
|
|
101
|
-
export function fitPolylineToBudget(points, maxEncodedChars) {
|
|
102
|
-
let current = points;
|
|
103
|
-
let encoded = encodePolyline(current);
|
|
104
|
-
let tolerance = 5; // meters
|
|
105
|
-
while (encoded.length > maxEncodedChars && current.length > 2) {
|
|
106
|
-
current = simplifyPoints(points, tolerance);
|
|
107
|
-
encoded = encodePolyline(current);
|
|
108
|
-
tolerance *= 2;
|
|
109
|
-
}
|
|
110
|
-
return {
|
|
111
|
-
encoded,
|
|
112
|
-
originalPointCount: points.length,
|
|
113
|
-
pointCount: current.length,
|
|
114
|
-
simplified: current.length < points.length,
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
//# sourceMappingURL=polyline.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"polyline.js","sourceRoot":"","sources":["../../../src/tools/maps/polyline.ts"],"names":[],"mappings":"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"}
|