mapnests-browser-sdk 1.0.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 ADDED
@@ -0,0 +1,273 @@
1
+ <a name="readme-top"></a>
2
+
3
+ ##### Readme Top
4
+
5
+
6
+ <br />
7
+ <div align="center">
8
+ <a href="#">
9
+ <img src="//cdn.pixabay.com/photo/2015/06/23/11/13/globe-818583_1280.png" alt="Mapnests Logo" width="100">
10
+ </a>
11
+
12
+ <h1 align="center">Mapnests TypeScript SDK</h1>
13
+
14
+ <p align="center">
15
+ Map Nests
16
+ </p>
17
+ </div>
18
+
19
+
20
+ A secure and efficient TS SDK for the **Mapnests Platform**, enabling powerful geospatial capabilities such as **Search (Geocoding)**, **Reverse (Reverse Geocoding)**, and **Distance Matrix**.
21
+
22
+
23
+ ---
24
+
25
+ ## 📚 Table of Contents
26
+
27
+ * [Installation](#installation)
28
+ * [Quick Start](#quick-start)
29
+ * [Core Features](#core-features)
30
+
31
+ * [Distance Matrix](#distance-matrix)
32
+ * [Pairwise Route Summary](#pairwise-route-summary)
33
+ * [Distance Matrix Details](#distance-matrix-details)
34
+ * [Search (Geocoding)](#search-geocoding)
35
+ * [Reverse Geocoding](#reverse-geocoding)
36
+ * [License](#license)
37
+ * [Contact](#contact)
38
+
39
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
40
+
41
+ ---
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ npm install mapnests-sdk
47
+ ```
48
+
49
+ Import into your project:
50
+
51
+ ```ts
52
+ import { Client, Mode } from 'mapnests-sdk';
53
+ ```
54
+
55
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
56
+
57
+ ---
58
+
59
+ ## Quick Start
60
+
61
+ ```ts
62
+ import { Client, Mode } from 'mapnests-sdk';
63
+
64
+ (async function () {
65
+ const client = new Client("YOUR_API_KEY", "your.package.name");
66
+
67
+ const result = await client.search({ Query: "Dhaka" });
68
+ console.log("Search result:", result);
69
+ })();
70
+ ```
71
+
72
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
73
+
74
+ ---
75
+
76
+ ## Core Features
77
+
78
+ ### Distance Matrix
79
+
80
+ > Calculates the distance and estimated time of arrival (ETA) between origin and destination points.
81
+
82
+ **Example Input:**
83
+
84
+ ```ts
85
+ const res = await client.distanceMatrix({
86
+ OriginLat: 23.8103,
87
+ OriginLon: 90.4125,
88
+ DestLat: 23.7500,
89
+ DestLon: 90.4200,
90
+ Mode: Mode.Walking,
91
+ });
92
+ console.log(res);
93
+ ```
94
+
95
+ **Example Output:**
96
+
97
+ ```json
98
+ {
99
+ "data": {
100
+ "distanceInMetres": 8900,
101
+ "etaInSeconds": 1300
102
+ }
103
+ }
104
+ ```
105
+
106
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
107
+
108
+ ### Pairwise Route Summary
109
+
110
+ > Computes distances, ETAs and geometries for multiple source-destination pairs in a single request. This is ideal for optimizing batch operations and comparing route statistics efficiently.
111
+
112
+ **Example Input:**
113
+
114
+ ```ts
115
+ const summary = await client.pairwiseRouteSummary({
116
+ pairs: [
117
+ {
118
+ id: 1,
119
+ src: { lat: 23.8103, lon: 90.4125 },
120
+ dest: { lat: 23.7500, lon: 90.4200 },
121
+ mode: Mode.Walking,
122
+ },
123
+ {
124
+ id: 2,
125
+ src: { lat: 23.7806, lon: 90.3984 },
126
+ dest: { lat: 23.7740, lon: 90.3681 },
127
+ mode: Mode.Car,
128
+ },
129
+ ]
130
+ });
131
+ console.log(summary);
132
+
133
+ ```
134
+
135
+ **Example Output:**
136
+
137
+ ```json
138
+ {
139
+ "status": true,
140
+ "message": "success",
141
+ "data": [
142
+ {
143
+ "id": 1,
144
+ "distanceInMeters": 8900,
145
+ "etaInSeconds": 1300,
146
+ "geometry": "encoded_polyline_string"
147
+ },
148
+ {
149
+ "id": 2,
150
+ "distanceInMeters": 4800,
151
+ "etaInSeconds": 700,
152
+ "geometry": "another_encoded_polyline"
153
+ }
154
+ ]
155
+ }
156
+ ```
157
+
158
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
159
+
160
+ ### Distance Matrix Details
161
+
162
+ > Returns step-by-step routing metadata, including geometry, waypoints, and navigation instructions.
163
+
164
+ **Example Input:**
165
+
166
+ ```ts
167
+ const details = await client.distanceMatrixDetails({
168
+ OriginLat: 23.7806,
169
+ OriginLon: 90.3984,
170
+ DestLat: 23.7740,
171
+ DestLon: 90.3681,
172
+ Mode: Mode.Car,
173
+ });
174
+ console.log(details);
175
+ ```
176
+
177
+ **Example Output (simplified):**
178
+
179
+ ```json
180
+ {
181
+ "status": true,
182
+ "message": "success",
183
+ "data": {
184
+ "routeResponse": {
185
+ "routes": [
186
+ {
187
+ "distance": 4800,
188
+ "duration": 700,
189
+ "geometry": "encoded_polyline",
190
+ "legs": [ ... ]
191
+ }
192
+ ]
193
+ }
194
+ }
195
+ }
196
+ ```
197
+
198
+ 📘 **For detailed documentation on all response fields (e.g., `routes`, `legs`, `steps`, `maneuver`, etc.), check the [Distance Matrix Response Reference](docs/distance_matrix_details.md).**
199
+
200
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
201
+
202
+ ### Search (Geocoding)
203
+
204
+ > Finds places, streets, and landmarks by text query.
205
+
206
+ **Example Input:**
207
+
208
+ ```ts
209
+ const searchRes = await client.search({ Query: "Bashundhara Residential Area, Dhaka" });
210
+ console.log(searchRes);
211
+ ```
212
+
213
+ **Example Output:**
214
+
215
+ ```json
216
+ {
217
+ "data": [
218
+ {
219
+ "place_id": "123456",
220
+ "lat": "23.8156",
221
+ "lon": "90.4287",
222
+ "display_name": "Bashundhara Residential Area, Dhaka, Bangladesh"
223
+ }
224
+ ],
225
+ "status": true,
226
+ "message": "success"
227
+ }
228
+ ```
229
+
230
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
231
+
232
+ ### Reverse Geocoding
233
+
234
+ > Converts GPS coordinates into a readable address.
235
+
236
+ **Example Input:**
237
+
238
+ ```ts
239
+ const revRes = await client.reverse({ Lat: 23.7806, Lon: 90.3984 });
240
+ console.log(revRes);
241
+ ```
242
+
243
+ **Example Output:**
244
+
245
+ ```json
246
+ {
247
+ "data": {
248
+ "displayName": "Farmgate, Tejgaon, Dhaka, Bangladesh",
249
+ "address": {
250
+ "country": "Bangladesh",
251
+ "state": "Dhaka Division",
252
+ "city": "Dhaka"
253
+ }
254
+ },
255
+ "status": true,
256
+ "message": "success"
257
+ }
258
+ ```
259
+
260
+ ---
261
+
262
+ ## License
263
+
264
+ This project is licensed under the [MIT License](LICENSE).
265
+
266
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
267
+
268
+ ---
269
+
270
+ ## Contact
271
+
272
+ 📧 [support@example.com](mailto:support@example.com)
273
+ Explain
@@ -0,0 +1 @@
1
+ export declare function buildURLFromJSON(label: string, baseUrl: string, jsonStr: string): string;
@@ -0,0 +1,34 @@
1
+ const BASE_URL = 'https://engine.mapnests.com';
2
+ export function buildURLFromJSON(label, baseUrl, jsonStr) {
3
+ const data = JSON.parse(jsonStr);
4
+ switch (label) {
5
+ case 'geocode': {
6
+ const query = encodeURIComponent(data.Query);
7
+ const lang = encodeURIComponent(data.Language);
8
+ const limit = data.Limit;
9
+ return `${baseUrl}/geomap/api/v1/geocode?q=${query}&language=${lang}&limit=${limit}`;
10
+ }
11
+ case 'reverseGeocode': {
12
+ return `${baseUrl}/geomap/api/v1/reverse?lat=${data.Lat}&lon=${data.Lon}`;
13
+ }
14
+ case 'distanceMatrix':
15
+ case 'distanceMatrixDetails': {
16
+ const fromLat = data.OriginLat;
17
+ const fromLon = data.OriginLon;
18
+ const toLat = data.DestLat;
19
+ const toLon = data.DestLon;
20
+ const mode = encodeURIComponent(data.Mode);
21
+ const path = label === 'distanceMatrixDetails' ? 'distancematrixdetails' : 'distancematrix';
22
+ return `${baseUrl}/routemap/api/v1/routes/${path}?fromLat=${fromLat}&fromLong=${fromLon}&toLat=${toLat}&toLong=${toLon}&mode=${mode}`;
23
+ }
24
+ case 'pairwiseRouteSummary': {
25
+ return `${baseUrl}/routemap/api/v1/routes/pairwise-summary`;
26
+ }
27
+ case 'search': {
28
+ const query = encodeURIComponent(data.Query);
29
+ return `${baseUrl}/geomap/api/v1/search?q=${query}`;
30
+ }
31
+ default:
32
+ throw new Error(`unsupported label: ${label}`);
33
+ }
34
+ }
@@ -0,0 +1,23 @@
1
+ import { SearchRequest, SearchResponse } from './modules/search';
2
+ import { ReverseRequest, ReverseResponse } from './modules/reverse';
3
+ import { DistanceMatrixRequest, DistanceMatrixResponse } from './modules/distance_matrix';
4
+ import { PairwiseRouteSummaryRequest, PairwiseRouteSummaryResponse } from './modules/pairwise_summary';
5
+ import { DistanceMatrixDetailsRequest, DistanceMatrixDetailsResponse } from './modules/distance_matrix_details';
6
+ export interface IClient {
7
+ distanceMatrix(request: DistanceMatrixRequest): Promise<DistanceMatrixResponse>;
8
+ pairwiseRouteSummary(request: PairwiseRouteSummaryRequest): Promise<PairwiseRouteSummaryResponse>;
9
+ distanceMatrixDetails(request: DistanceMatrixDetailsRequest): Promise<DistanceMatrixDetailsResponse>;
10
+ reverse(request: ReverseRequest): Promise<ReverseResponse>;
11
+ search(request: SearchRequest): Promise<SearchResponse>;
12
+ }
13
+ export declare class Client implements IClient {
14
+ private apiKey;
15
+ private packageName;
16
+ constructor(apiKey: string, packageName: string);
17
+ private makeRequest;
18
+ distanceMatrix(request: DistanceMatrixRequest): Promise<DistanceMatrixResponse>;
19
+ pairwiseRouteSummary(request: PairwiseRouteSummaryRequest): Promise<PairwiseRouteSummaryResponse>;
20
+ distanceMatrixDetails(request: DistanceMatrixDetailsRequest): Promise<DistanceMatrixDetailsResponse>;
21
+ reverse(request: ReverseRequest): Promise<ReverseResponse>;
22
+ search(request: SearchRequest): Promise<SearchResponse>;
23
+ }
package/dist/client.js ADDED
@@ -0,0 +1,45 @@
1
+ import { callSecureRequest } from './secure_req';
2
+ export class Client {
3
+ constructor(apiKey, packageName) {
4
+ this.apiKey = apiKey;
5
+ this.packageName = packageName;
6
+ }
7
+ async makeRequest(label, request) {
8
+ const { statusCode, response, errorMessage } = await callSecureRequest(label, this.apiKey, this.packageName, request);
9
+ if (errorMessage) {
10
+ throw new Error(`[${label}] native error: ${errorMessage}`);
11
+ }
12
+ if (statusCode !== 200) {
13
+ throw new Error(`[${label}] unexpected status code ${statusCode}`);
14
+ }
15
+ return response;
16
+ }
17
+ async distanceMatrix(request) {
18
+ console.log('📍 DistanceMatrix request:', request);
19
+ const response = await this.makeRequest('distanceMatrix', request);
20
+ console.log('📍 DistanceMatrix response:', response);
21
+ return response;
22
+ }
23
+ async pairwiseRouteSummary(request) {
24
+ console.log('📍 PairwiseRouteSummary request:', request);
25
+ return this.makeRequest('pairwiseRouteSummary', request);
26
+ }
27
+ async distanceMatrixDetails(request) {
28
+ console.log('📍 DistanceMatrixDetails request:', request);
29
+ const response = await this.makeRequest('distanceMatrixDetails', request);
30
+ console.log('📍 DistanceMatrixDetails response:', response);
31
+ return response;
32
+ }
33
+ async reverse(request) {
34
+ console.log('📍 Reverse request:', request);
35
+ const response = await this.makeRequest('reverseGeocode', request);
36
+ console.log('📍 Reverse response:', response);
37
+ return response;
38
+ }
39
+ async search(request) {
40
+ console.log('📍 Search request:', request);
41
+ const response = await this.makeRequest('search', request);
42
+ console.log('📍 Search response:', response);
43
+ return response;
44
+ }
45
+ }
@@ -0,0 +1 @@
1
+ export declare function generateToken(apiKey: string): Promise<string>;
@@ -0,0 +1,20 @@
1
+ export async function generateToken(apiKey) {
2
+ const randInt = Math.floor(Math.random() * 1000000);
3
+ const expires = Math.floor(Date.now() / 1000) + 30;
4
+ const input = `${expires}:${randInt}:${apiKey}`;
5
+ // Browser-only: Web Crypto API
6
+ const encoder = new TextEncoder();
7
+ const data = encoder.encode(input);
8
+ const hashBuffer = await crypto.subtle.digest('SHA-256', data);
9
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
10
+ const hash = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
11
+ const jsonPayload = {
12
+ random: randInt,
13
+ expires,
14
+ sign: hash,
15
+ };
16
+ const jsonStr = JSON.stringify(jsonPayload);
17
+ // Browser: use btoa for Base64 encoding
18
+ const base64 = btoa(jsonStr);
19
+ return base64;
20
+ }
@@ -0,0 +1,6 @@
1
+ export * from './modules/distance_matrix';
2
+ export * from './modules/pairwise_summary';
3
+ export * from './modules/distance_matrix_details';
4
+ export * from './modules/reverse';
5
+ export * from './modules/search';
6
+ export { Client } from './client';
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export * from './modules/distance_matrix';
2
+ export * from './modules/pairwise_summary';
3
+ export * from './modules/distance_matrix_details';
4
+ export * from './modules/reverse';
5
+ export * from './modules/search';
6
+ export { Client } from './client';
package/dist/main.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/main.js ADDED
@@ -0,0 +1,46 @@
1
+ import { Client, Mode } from './index';
2
+ (async function () {
3
+ try {
4
+ const cl = new Client("", "");
5
+ const res = await cl.distanceMatrix({
6
+ OriginLat: 23.8103,
7
+ OriginLon: 90.4125,
8
+ DestLat: 23.7805,
9
+ DestLon: 90.4113,
10
+ Mode: Mode.Walking
11
+ });
12
+ console.log("============================> ", res);
13
+ const pairwiseSummaryRes = await cl.pairwiseRouteSummary({
14
+ pairs: [
15
+ {
16
+ id: 1,
17
+ src: { lat: 23.8103, lon: 90.4125 },
18
+ dest: { lat: 23.7805, lon: 90.4113 },
19
+ mode: Mode.Bicycle,
20
+ },
21
+ {
22
+ id: 2,
23
+ src: { lat: 23.8120, lon: 90.4140 },
24
+ dest: { lat: 23.7820, lon: 90.4170 },
25
+ mode: Mode.Bicycle,
26
+ },
27
+ ],
28
+ });
29
+ console.log("==================================> ", JSON.stringify(pairwiseSummaryRes));
30
+ const deRes = await cl.distanceMatrixDetails({
31
+ OriginLat: 23.8103,
32
+ OriginLon: 90.4125,
33
+ DestLat: 23.7805,
34
+ DestLon: 90.4113,
35
+ Mode: Mode.Walking
36
+ });
37
+ console.log("============================> ", deRes);
38
+ const searchRes = await cl.search({ Query: "uttara" });
39
+ console.log("============================> ", searchRes);
40
+ const revRes = await cl.reverse({ Lat: 23.8103, Lon: 90.4125 });
41
+ console.log("============================> ", revRes);
42
+ }
43
+ catch (err) {
44
+ console.log(err);
45
+ }
46
+ })();
@@ -0,0 +1,19 @@
1
+ export declare enum Mode {
2
+ Walking = "walking",
3
+ Bicycle = "bicycle",
4
+ Car = "car"
5
+ }
6
+ export interface DistanceMatrixRequest {
7
+ OriginLat: number;
8
+ OriginLon: number;
9
+ DestLat: number;
10
+ DestLon: number;
11
+ Mode: Mode;
12
+ }
13
+ export interface DistanceMatrixData {
14
+ distanceInMetres: number;
15
+ etaInSeconds: number;
16
+ }
17
+ export interface DistanceMatrixResponse {
18
+ data: DistanceMatrixData;
19
+ }
@@ -0,0 +1,6 @@
1
+ export var Mode;
2
+ (function (Mode) {
3
+ Mode["Walking"] = "walking";
4
+ Mode["Bicycle"] = "bicycle";
5
+ Mode["Car"] = "car";
6
+ })(Mode || (Mode = {}));
@@ -0,0 +1,69 @@
1
+ import { Mode } from './distance_matrix';
2
+ export interface DistanceMatrixDetailsRequest {
3
+ OriginLat: number;
4
+ OriginLon: number;
5
+ DestLat: number;
6
+ DestLon: number;
7
+ Mode: Mode;
8
+ }
9
+ export interface DistanceMatrixDetailsResponse {
10
+ status: boolean;
11
+ message: string;
12
+ data: RouteData;
13
+ }
14
+ export interface RouteData {
15
+ routeResponse: RouteResponse;
16
+ }
17
+ export interface RouteResponse {
18
+ code: string;
19
+ message: string;
20
+ data_version: string;
21
+ routes: Route[];
22
+ waypoints: Waypoint[];
23
+ }
24
+ export interface Route {
25
+ distance: number;
26
+ duration: number;
27
+ weight_name: string;
28
+ weight: number;
29
+ geometry: string;
30
+ legs: Leg[];
31
+ }
32
+ export interface Leg {
33
+ distance: number;
34
+ duration: number;
35
+ summary: string;
36
+ weight: number;
37
+ steps: Step[];
38
+ }
39
+ export interface Step {
40
+ distance: number;
41
+ duration: number;
42
+ geometry: string;
43
+ name: string;
44
+ mode: string;
45
+ driving_side: string;
46
+ weight: number;
47
+ maneuver: Maneuver;
48
+ intersections: Intersection[];
49
+ }
50
+ export interface Maneuver {
51
+ location: number[];
52
+ bearing_before: number;
53
+ bearing_after: number;
54
+ type: string;
55
+ modifier: string;
56
+ }
57
+ export interface Intersection {
58
+ location: number[];
59
+ bearings: number[];
60
+ entry: boolean[];
61
+ in: number;
62
+ out: number;
63
+ }
64
+ export interface Waypoint {
65
+ name: string;
66
+ location: number[];
67
+ distance: number;
68
+ hint: string;
69
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,26 @@
1
+ import { Mode } from './distance_matrix';
2
+ export interface Coordinate {
3
+ lat: number;
4
+ lon: number;
5
+ }
6
+ export interface PairwiseRoute {
7
+ id: number;
8
+ src: Coordinate;
9
+ dest: Coordinate;
10
+ mode: Mode;
11
+ }
12
+ export interface PairwiseRouteSummaryRequest {
13
+ pairs: PairwiseRoute[];
14
+ }
15
+ export interface RouteSummary {
16
+ id: number;
17
+ distanceInMeters?: number;
18
+ etaInSeconds?: number;
19
+ geometry?: string;
20
+ error?: string;
21
+ }
22
+ export interface PairwiseRouteSummaryResponse {
23
+ status: boolean;
24
+ message: string;
25
+ data: RouteSummary[];
26
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ export interface ReverseRequest {
2
+ Lat: number;
3
+ Lon: number;
4
+ }
5
+ export interface ReverseResponse {
6
+ data: ReverseData;
7
+ message: string;
8
+ status: boolean;
9
+ }
10
+ export interface ReverseData {
11
+ placeRank: number;
12
+ importance: number;
13
+ name: string;
14
+ addresstype: string;
15
+ lon: string;
16
+ lat: string;
17
+ category: string;
18
+ type: string;
19
+ displayName: string;
20
+ placeid: number;
21
+ address: Address;
22
+ }
23
+ export interface Address {
24
+ country: string;
25
+ countryCode: string;
26
+ city: string;
27
+ road: string;
28
+ stateDistrict: string;
29
+ iso31662Lvl4: string;
30
+ iso31662Lvl5: string;
31
+ municipality: string;
32
+ postcode: string;
33
+ suburb: string;
34
+ borough: string;
35
+ state: string;
36
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ export interface SearchRequest {
2
+ Query: string;
3
+ }
4
+ export interface SearchResponse {
5
+ data: SearchData[];
6
+ message: string;
7
+ status: boolean;
8
+ }
9
+ export interface SearchData {
10
+ place_id: string;
11
+ lat: string;
12
+ lon: string;
13
+ addresstypes: string[];
14
+ display_name: string;
15
+ display_address: string;
16
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ export declare class Client {
2
+ private apiKey;
3
+ private packageName;
4
+ constructor(apiKey: string, packageName: string);
5
+ request(label: string, request: object): Promise<Uint8Array>;
6
+ }
@@ -0,0 +1,17 @@
1
+ import { callSecureRequest } from './secure_req';
2
+ export class Client {
3
+ constructor(apiKey, packageName) {
4
+ this.apiKey = apiKey;
5
+ this.packageName = packageName;
6
+ }
7
+ async request(label, request) {
8
+ const { statusCode, response, errorMessage } = await callSecureRequest(label, this.apiKey, this.packageName, request);
9
+ if (errorMessage) {
10
+ throw new Error(`[${label}] native error: ${errorMessage}`);
11
+ }
12
+ if (statusCode !== 200) {
13
+ throw new Error(`[${label}] unexpected status code ${statusCode}`);
14
+ }
15
+ return new TextEncoder().encode(response); // Similar to []byte in Go
16
+ }
17
+ }
@@ -0,0 +1,5 @@
1
+ export declare function callSecureRequest(label: string, apiKey: string, origin: string, request: object): Promise<{
2
+ statusCode: number;
3
+ response: string;
4
+ errorMessage?: string;
5
+ }>;
@@ -0,0 +1,25 @@
1
+ import { performSecureRequest } from './secure_request';
2
+ export async function callSecureRequest(label, apiKey, origin, request) {
3
+ try {
4
+ const jsonRequest = JSON.stringify(request);
5
+ const result = await performSecureRequest(label, apiKey, origin, jsonRequest);
6
+ if (!result.success) {
7
+ return {
8
+ statusCode: result.statusCode,
9
+ response: '',
10
+ errorMessage: result.errorMessage || 'secure request failed',
11
+ };
12
+ }
13
+ return {
14
+ statusCode: result.statusCode,
15
+ response: result.response,
16
+ };
17
+ }
18
+ catch (err) {
19
+ return {
20
+ statusCode: 0,
21
+ response: '',
22
+ errorMessage: err.message,
23
+ };
24
+ }
25
+ }
@@ -0,0 +1,7 @@
1
+ export interface SecureResult {
2
+ success: boolean;
3
+ statusCode: number;
4
+ response: string;
5
+ errorMessage?: string;
6
+ }
7
+ export declare function performSecureRequest(label: string, apiKey: string, origin: string, jsonRequest: string): Promise<SecureResult>;
@@ -0,0 +1,73 @@
1
+ import axios from 'axios';
2
+ import { generateToken } from './generate_token';
3
+ import { buildURLFromJSON } from './build_url';
4
+ const BASE_URL = 'https://engine.mapnests.com';
5
+ const HTTP_METHOD_MAP = {
6
+ geocode: 'GET',
7
+ reverseGeocode: 'GET',
8
+ search: 'GET',
9
+ distanceMatrix: 'GET',
10
+ distanceMatrixDetails: 'GET',
11
+ pairwiseRouteSummary: 'POST',
12
+ };
13
+ export async function performSecureRequest(label, apiKey, origin, jsonRequest) {
14
+ let urlStr;
15
+ try {
16
+ urlStr = buildURLFromJSON(label, BASE_URL, jsonRequest);
17
+ }
18
+ catch (err) {
19
+ return { success: false, statusCode: 0, response: '', errorMessage: err.message };
20
+ }
21
+ let tokenHeader = await generateToken(apiKey);
22
+ const method = HTTP_METHOD_MAP[label] || 'GET';
23
+ const headers = {
24
+ 'X-API-KEY': apiKey,
25
+ 'Origin': origin,
26
+ 'fxsrf': tokenHeader,
27
+ 'Content-Type': 'application/json',
28
+ };
29
+ const axiosConfig = {
30
+ headers,
31
+ timeout: 30000,
32
+ };
33
+ try {
34
+ const response = method === 'POST'
35
+ ? await axios.post(urlStr, JSON.parse(jsonRequest), axiosConfig)
36
+ : await axios.get(urlStr, axiosConfig);
37
+ return {
38
+ success: response.status >= 200 && response.status < 300,
39
+ statusCode: response.status,
40
+ response: response.data,
41
+ };
42
+ }
43
+ catch (err) {
44
+ if (err.response?.status === 401 && err.response.headers['cf-ray-status-id-tn']) {
45
+ tokenHeader = await generateToken(apiKey);
46
+ headers.fxsrf = tokenHeader;
47
+ try {
48
+ const retryResponse = method === 'POST'
49
+ ? await axios.post(urlStr, JSON.parse(jsonRequest), axiosConfig)
50
+ : await axios.get(urlStr, axiosConfig);
51
+ return {
52
+ success: retryResponse.status >= 200 && retryResponse.status < 300,
53
+ statusCode: retryResponse.status,
54
+ response: retryResponse.data,
55
+ };
56
+ }
57
+ catch (retryErr) {
58
+ return {
59
+ success: false,
60
+ statusCode: retryErr.response?.status || 0,
61
+ response: '',
62
+ errorMessage: retryErr.message,
63
+ };
64
+ }
65
+ }
66
+ return {
67
+ success: false,
68
+ statusCode: err.response?.status || 0,
69
+ response: '',
70
+ errorMessage: err.message,
71
+ };
72
+ }
73
+ }
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "mapnests-browser-sdk",
3
+ "description": "TypeScript SDK for Mapnests API integration (Distance Matrix, Distance Matrix Details, Geocode, Reverse Geocode)",
4
+ "version": "1.0.0",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "require": "./dist/index.js",
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "dev": "tsc --watch",
19
+ "test": "jest",
20
+ "prepare": "npm run build",
21
+ "prebuild": "rimraf dist",
22
+ "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
23
+ "build": "npm run prebuild && tsc",
24
+ "publish-pkg": "echo 'Publishing package...' && npm run build && npm publish --force",
25
+ "release": "git add . && git commit -m \"Updates\" && npm version patch && npm publish"
26
+ },
27
+ "keywords": [
28
+ "mapnests",
29
+ "typescript",
30
+ "sdk",
31
+ "geocode",
32
+ "reverse-geocode",
33
+ "distance-matrix",
34
+ "distance-matrix-details"
35
+ ],
36
+ "license": "MIT",
37
+ "devDependencies": {
38
+ "@types/jest": "^29.0.0",
39
+ "@types/node": "^24.0.13",
40
+ "axios": "^1.10.0",
41
+ "jest": "^29.0.0",
42
+ "rimraf": "^5.0.1",
43
+ "tsx": "^4.20.3",
44
+ "typescript": "^5.8.3"
45
+ },
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "git@vcs.technonext.com:mapnests/map-libraries/tn-map-js-library.git"
49
+ }
50
+ }