@mapbox/mcp-server 0.2.0-issue.11.2 → 0.2.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.
Files changed (36) hide show
  1. package/README.md +4 -82
  2. package/dist/index.js +0 -0
  3. package/dist/tools/directions-tool/DirectionsTool.d.ts +32 -7
  4. package/dist/tools/directions-tool/DirectionsTool.d.ts.map +1 -1
  5. package/dist/tools/directions-tool/DirectionsTool.js +61 -37
  6. package/dist/tools/directions-tool/DirectionsTool.js.map +1 -1
  7. package/dist/tools/directions-tool/DirectionsTool.test.js +257 -208
  8. package/dist/tools/directions-tool/DirectionsTool.test.js.map +1 -1
  9. package/dist/utils/requestUtils.d.ts.map +1 -1
  10. package/dist/utils/requestUtils.js +2 -31
  11. package/dist/utils/requestUtils.js.map +1 -1
  12. package/dist/utils/requestUtils.test-helpers.d.ts.map +1 -1
  13. package/dist/utils/requestUtils.test-helpers.js +1 -5
  14. package/dist/utils/requestUtils.test-helpers.js.map +1 -1
  15. package/dist/version.json +4 -4
  16. package/package.json +2 -2
  17. package/dist/tools/directions-tool/cleanResponseData.d.ts +0 -11
  18. package/dist/tools/directions-tool/cleanResponseData.d.ts.map +0 -1
  19. package/dist/tools/directions-tool/cleanResponseData.js +0 -175
  20. package/dist/tools/directions-tool/cleanResponseData.js.map +0 -1
  21. package/dist/tools/directions-tool/cleanResponseData.test.d.ts +0 -2
  22. package/dist/tools/directions-tool/cleanResponseData.test.d.ts.map +0 -1
  23. package/dist/tools/directions-tool/cleanResponseData.test.js +0 -295
  24. package/dist/tools/directions-tool/cleanResponseData.test.js.map +0 -1
  25. package/dist/tools/directions-tool/formatIsoDateTime.d.ts +0 -8
  26. package/dist/tools/directions-tool/formatIsoDateTime.d.ts.map +0 -1
  27. package/dist/tools/directions-tool/formatIsoDateTime.js +0 -17
  28. package/dist/tools/directions-tool/formatIsoDateTime.js.map +0 -1
  29. package/dist/tools/directions-tool/formatIsoDateTime.test.d.ts +0 -2
  30. package/dist/tools/directions-tool/formatIsoDateTime.test.d.ts.map +0 -1
  31. package/dist/tools/directions-tool/formatIsoDateTime.test.js +0 -26
  32. package/dist/tools/directions-tool/formatIsoDateTime.test.js.map +0 -1
  33. package/dist/utils/requestUtils.test.d.ts +0 -2
  34. package/dist/utils/requestUtils.test.d.ts.map +0 -1
  35. package/dist/utils/requestUtils.test.js +0 -115
  36. package/dist/utils/requestUtils.test.js.map +0 -1
@@ -1,18 +1,9 @@
1
- process.env.MAPBOX_ACCESS_TOKEN = 'test.token.signature';
1
+ process.env.MAPBOX_ACCESS_TOKEN =
2
+ 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0In0.signature';
2
3
  import { cleanup } from '../../utils/requestUtils.js';
3
4
  import { setupFetch, assertHeadersSent } from '../../utils/requestUtils.test-helpers.js';
4
5
  import { DirectionsTool } from './DirectionsTool.js';
5
- import * as cleanResponseModule from './cleanResponseData.js';
6
6
  describe('DirectionsTool', () => {
7
- beforeEach(() => {
8
- // Mock the cleanResponseData function to return data unchanged, this make testing much easier
9
- // There should be separate test suits for `cleanResponseData`
10
- jest
11
- .spyOn(cleanResponseModule, 'cleanResponseData')
12
- .mockImplementation((_, data) => data);
13
- // Enable verbose errors for testing
14
- process.env.VERBOSE_ERRORS = 'true';
15
- });
16
7
  afterEach(() => {
17
8
  jest.restoreAllMocks();
18
9
  cleanup();
@@ -21,8 +12,8 @@ describe('DirectionsTool', () => {
21
12
  const mockFetch = setupFetch();
22
13
  await new DirectionsTool().run({
23
14
  coordinates: [
24
- [-74.102094, 40.692815],
25
- [-74.1022094, 40.792815]
15
+ { longitude: -74.102094, latitude: 40.692815 },
16
+ { longitude: -74.1022094, latitude: 40.792815 }
26
17
  ]
27
18
  });
28
19
  assertHeadersSent(mockFetch);
@@ -31,8 +22,8 @@ describe('DirectionsTool', () => {
31
22
  const mockFetch = setupFetch();
32
23
  await new DirectionsTool().run({
33
24
  coordinates: [
34
- [-73.989, 40.733],
35
- [-73.979, 40.743]
25
+ { longitude: -73.989, latitude: 40.733 },
26
+ { longitude: -73.979, latitude: 40.743 }
36
27
  ]
37
28
  });
38
29
  const calledUrl = mockFetch.mock.calls[0][0];
@@ -45,13 +36,14 @@ describe('DirectionsTool', () => {
45
36
  const mockFetch = setupFetch();
46
37
  await new DirectionsTool().run({
47
38
  coordinates: [
48
- [-122.42, 37.78],
49
- [-122.4, 37.79],
50
- [-122.39, 37.77]
39
+ { longitude: -122.42, latitude: 37.78 },
40
+ { longitude: -122.4, latitude: 37.79 },
41
+ { longitude: -122.39, latitude: 37.77 }
51
42
  ],
52
43
  routing_profile: 'walking',
53
44
  geometries: 'geojson',
54
45
  alternatives: true,
46
+ annotations: ['distance', 'duration', 'speed'],
55
47
  exclude: 'ferry'
56
48
  });
57
49
  const calledUrl = mockFetch.mock.calls[0][0];
@@ -59,7 +51,7 @@ describe('DirectionsTool', () => {
59
51
  expect(calledUrl).toContain('-122.42%2C37.78%3B-122.4%2C37.79%3B-122.39%2C37.77');
60
52
  expect(calledUrl).toContain('geometries=geojson');
61
53
  expect(calledUrl).toContain('alternatives=true');
62
- expect(calledUrl).toContain('annotations=distance%2Cspeed');
54
+ expect(calledUrl).toContain('annotations=distance%2Cduration%2Cspeed');
63
55
  expect(calledUrl).toContain('overview=full');
64
56
  expect(calledUrl).toContain('exclude=ferry');
65
57
  assertHeadersSent(mockFetch);
@@ -68,32 +60,15 @@ describe('DirectionsTool', () => {
68
60
  const mockFetch = setupFetch();
69
61
  await new DirectionsTool().run({
70
62
  coordinates: [
71
- [-118.24, 34.05],
72
- [-118.3, 34.02]
63
+ { longitude: -118.24, latitude: 34.05 },
64
+ { longitude: -118.3, latitude: 34.02 }
73
65
  ]
74
66
  });
75
67
  const calledUrl = mockFetch.mock.calls[0][0];
76
68
  expect(calledUrl).toContain('directions/v5/mapbox/driving-traffic');
77
- expect(calledUrl).not.toContain('geometries=');
78
- expect(calledUrl).toContain('alternatives=false');
79
- expect(calledUrl).toContain('annotations=distance%2Ccongestion%2Cspeed');
80
- expect(calledUrl).not.toContain('exclude=');
81
- assertHeadersSent(mockFetch);
82
- });
83
- it('handles geometries=none', async () => {
84
- const mockFetch = setupFetch();
85
- await new DirectionsTool().run({
86
- coordinates: [
87
- [-118.24, 34.05],
88
- [-118.3, 34.02]
89
- ],
90
- geometries: 'none'
91
- });
92
- const calledUrl = mockFetch.mock.calls[0][0];
93
- expect(calledUrl).toContain('directions/v5/mapbox/driving-traffic');
94
- expect(calledUrl).not.toContain('geometries=');
69
+ expect(calledUrl).toContain('geometries=polyline');
95
70
  expect(calledUrl).toContain('alternatives=false');
96
- expect(calledUrl).toContain('annotations=distance%2Ccongestion%2Cspeed');
71
+ expect(calledUrl).not.toContain('annotations=');
97
72
  expect(calledUrl).not.toContain('exclude=');
98
73
  assertHeadersSent(mockFetch);
99
74
  });
@@ -101,8 +76,8 @@ describe('DirectionsTool', () => {
101
76
  const mockFetch = setupFetch();
102
77
  await new DirectionsTool().run({
103
78
  coordinates: [
104
- [-74.0, 40.7],
105
- [-73.9, 40.8]
79
+ { longitude: -74.0, latitude: 40.7 },
80
+ { longitude: -73.9, latitude: 40.8 }
106
81
  ],
107
82
  exclude: 'toll,point(-73.95 40.75)'
108
83
  });
@@ -122,14 +97,14 @@ describe('DirectionsTool', () => {
122
97
  });
123
98
  const result = await new DirectionsTool().run({
124
99
  coordinates: [
125
- [-73.989, 40.733],
126
- [-73.979, 40.743]
100
+ { longitude: -73.989, latitude: 40.733 },
101
+ { longitude: -73.979, latitude: 40.743 }
127
102
  ]
128
103
  });
129
104
  expect(result.is_error).toBe(true);
130
105
  expect(result.content[0]).toMatchObject({
131
106
  type: 'text',
132
- text: 'Request failed with status 404: Not Found'
107
+ text: 'Internal error has occurred.'
133
108
  });
134
109
  assertHeadersSent(mockFetch);
135
110
  });
@@ -137,7 +112,7 @@ describe('DirectionsTool', () => {
137
112
  const tool = new DirectionsTool();
138
113
  // Test with only one coordinate (invalid)
139
114
  await expect(tool.run({
140
- coordinates: [[-73.989, 40.733]]
115
+ coordinates: [{ longitude: -73.989, latitude: 40.733 }]
141
116
  })).resolves.toMatchObject({
142
117
  is_error: true
143
118
  });
@@ -151,7 +126,10 @@ describe('DirectionsTool', () => {
151
126
  it('validates coordinates constraints - maximum allowed', async () => {
152
127
  const tool = new DirectionsTool();
153
128
  // Create an array of 26 coordinates (one more than allowed)
154
- const tooManyCoords = Array(26).fill([-73.989, 40.733]);
129
+ const tooManyCoords = Array(26).fill({
130
+ longitude: -73.989,
131
+ latitude: 40.733
132
+ });
155
133
  await expect(tool.run({
156
134
  coordinates: tooManyCoords
157
135
  })).resolves.toMatchObject({
@@ -162,8 +140,8 @@ describe('DirectionsTool', () => {
162
140
  const mockFetch = setupFetch();
163
141
  await new DirectionsTool().run({
164
142
  coordinates: [
165
- [-73.989, 40.733],
166
- [-73.979, 40.743]
143
+ { longitude: -73.989, latitude: 40.733 },
144
+ { longitude: -73.979, latitude: 40.743 }
167
145
  ]
168
146
  });
169
147
  const calledUrl = mockFetch.mock.calls[0][0];
@@ -175,20 +153,174 @@ describe('DirectionsTool', () => {
175
153
  // Create an array of exactly 25 coordinates (maximum allowed)
176
154
  const maxCoords = Array(25)
177
155
  .fill(0)
178
- .map((_, i) => [-74 + i * 0.01, 40 + i * 0.01]);
156
+ .map((_, i) => ({ longitude: -74 + i * 0.01, latitude: 40 + i * 0.01 }));
179
157
  await new DirectionsTool().run({
180
158
  coordinates: maxCoords
181
159
  });
182
160
  const calledUrl = mockFetch.mock.calls[0][0];
183
161
  // Check that all coordinates are properly encoded
184
162
  for (let i = 0; i < maxCoords.length; i++) {
185
- const [lng, lat] = maxCoords[i];
163
+ const { longitude: lng, latitude: lat } = maxCoords[i];
186
164
  const semicolon = i < 24 ? '%3B' : '';
187
165
  const expectedCoord = `${lng}%2C${lat}` + semicolon;
188
166
  expect(calledUrl).toContain(expectedCoord);
189
167
  }
190
168
  assertHeadersSent(mockFetch);
191
169
  });
170
+ describe('walking parameters validations', () => {
171
+ it('accepts walking_speed with walking profile', async () => {
172
+ const mockFetch = setupFetch();
173
+ await new DirectionsTool().run({
174
+ coordinates: [
175
+ { longitude: -73.989, latitude: 40.733 },
176
+ { longitude: -73.979, latitude: 40.743 }
177
+ ],
178
+ routing_profile: 'walking',
179
+ walking_speed: 2.5
180
+ });
181
+ const calledUrl = mockFetch.mock.calls[0][0];
182
+ expect(calledUrl).toContain('walking_speed=2.5');
183
+ assertHeadersSent(mockFetch);
184
+ });
185
+ it('accepts walkway_bias with walking profile', async () => {
186
+ const mockFetch = setupFetch();
187
+ await new DirectionsTool().run({
188
+ coordinates: [
189
+ { longitude: -73.989, latitude: 40.733 },
190
+ { longitude: -73.979, latitude: 40.743 }
191
+ ],
192
+ routing_profile: 'walking',
193
+ walkway_bias: 0.8
194
+ });
195
+ const calledUrl = mockFetch.mock.calls[0][0];
196
+ expect(calledUrl).toContain('walkway_bias=0.8');
197
+ assertHeadersSent(mockFetch);
198
+ });
199
+ it('rejects walking_speed with non-walking profiles', async () => {
200
+ const tool = new DirectionsTool();
201
+ // Test with driving profile
202
+ await expect(tool.run({
203
+ coordinates: [
204
+ { longitude: -73.989, latitude: 40.733 },
205
+ { longitude: -73.979, latitude: 40.743 }
206
+ ],
207
+ routing_profile: 'driving',
208
+ walking_speed: 2.0
209
+ })).resolves.toMatchObject({
210
+ is_error: true
211
+ });
212
+ // Test with cycling profile
213
+ await expect(tool.run({
214
+ coordinates: [
215
+ { longitude: -73.989, latitude: 40.733 },
216
+ { longitude: -73.979, latitude: 40.743 }
217
+ ],
218
+ routing_profile: 'cycling',
219
+ walking_speed: 2.0
220
+ })).resolves.toMatchObject({
221
+ is_error: true
222
+ });
223
+ });
224
+ it('rejects walkway_bias with non-walking profiles', async () => {
225
+ const tool = new DirectionsTool();
226
+ // Test with driving-traffic profile
227
+ await expect(tool.run({
228
+ coordinates: [
229
+ { longitude: -73.989, latitude: 40.733 },
230
+ { longitude: -73.979, latitude: 40.743 }
231
+ ],
232
+ routing_profile: 'driving-traffic',
233
+ walkway_bias: 0.5
234
+ })).resolves.toMatchObject({
235
+ is_error: true
236
+ });
237
+ // Test with cycling profile
238
+ await expect(tool.run({
239
+ coordinates: [
240
+ { longitude: -73.989, latitude: 40.733 },
241
+ { longitude: -73.979, latitude: 40.743 }
242
+ ],
243
+ routing_profile: 'cycling',
244
+ walkway_bias: -0.8
245
+ })).resolves.toMatchObject({
246
+ is_error: true
247
+ });
248
+ });
249
+ it('validates walking_speed value ranges', async () => {
250
+ const tool = new DirectionsTool();
251
+ // Test with value below minimum (0.14 m/s)
252
+ await expect(tool.run({
253
+ coordinates: [
254
+ { longitude: -73.989, latitude: 40.733 },
255
+ { longitude: -73.979, latitude: 40.743 }
256
+ ],
257
+ routing_profile: 'walking',
258
+ walking_speed: 0.1
259
+ })).resolves.toMatchObject({
260
+ is_error: true
261
+ });
262
+ // Test with value above maximum (6.94 m/s)
263
+ await expect(tool.run({
264
+ coordinates: [
265
+ { longitude: -73.989, latitude: 40.733 },
266
+ { longitude: -73.979, latitude: 40.743 }
267
+ ],
268
+ routing_profile: 'walking',
269
+ walking_speed: 7.5
270
+ })).resolves.toMatchObject({
271
+ is_error: true
272
+ });
273
+ // Test with valid value
274
+ const mockFetch = setupFetch();
275
+ await tool.run({
276
+ coordinates: [
277
+ { longitude: -73.989, latitude: 40.733 },
278
+ { longitude: -73.979, latitude: 40.743 }
279
+ ],
280
+ routing_profile: 'walking',
281
+ walking_speed: 3.0
282
+ });
283
+ const calledUrl = mockFetch.mock.calls[0][0];
284
+ expect(calledUrl).toContain('walking_speed=3');
285
+ });
286
+ it('validates walkway_bias value ranges', async () => {
287
+ const tool = new DirectionsTool();
288
+ // Test with value below minimum (-1)
289
+ await expect(tool.run({
290
+ coordinates: [
291
+ { longitude: -73.989, latitude: 40.733 },
292
+ { longitude: -73.979, latitude: 40.743 }
293
+ ],
294
+ routing_profile: 'walking',
295
+ walkway_bias: -1.5
296
+ })).resolves.toMatchObject({
297
+ is_error: true
298
+ });
299
+ // Test with value above maximum (1)
300
+ await expect(tool.run({
301
+ coordinates: [
302
+ { longitude: -73.989, latitude: 40.733 },
303
+ { longitude: -73.979, latitude: 40.743 }
304
+ ],
305
+ routing_profile: 'walking',
306
+ walkway_bias: 1.2
307
+ })).resolves.toMatchObject({
308
+ is_error: true
309
+ });
310
+ // Test with valid values
311
+ const mockFetch = setupFetch();
312
+ await tool.run({
313
+ coordinates: [
314
+ { longitude: -73.989, latitude: 40.733 },
315
+ { longitude: -73.979, latitude: 40.743 }
316
+ ],
317
+ routing_profile: 'walking',
318
+ walkway_bias: -0.5
319
+ });
320
+ const calledUrl = mockFetch.mock.calls[0][0];
321
+ expect(calledUrl).toContain('walkway_bias=-0.5');
322
+ });
323
+ });
192
324
  describe('exclude parameter and routing profile validations', () => {
193
325
  it('accepts driving-specific exclusions with driving profiles', async () => {
194
326
  const mockFetch = setupFetch();
@@ -196,8 +328,8 @@ describe('DirectionsTool', () => {
196
328
  // Test with driving profile
197
329
  await expect(tool.run({
198
330
  coordinates: [
199
- [-73.989, 40.733],
200
- [-73.979, 40.743]
331
+ { longitude: -73.989, latitude: 40.733 },
332
+ { longitude: -73.979, latitude: 40.743 }
201
333
  ],
202
334
  routing_profile: 'driving',
203
335
  exclude: 'toll,motorway,unpaved'
@@ -207,8 +339,8 @@ describe('DirectionsTool', () => {
207
339
  // Test with driving-traffic profile
208
340
  await expect(tool.run({
209
341
  coordinates: [
210
- [-73.989, 40.733],
211
- [-73.979, 40.743]
342
+ { longitude: -73.989, latitude: 40.733 },
343
+ { longitude: -73.979, latitude: 40.743 }
212
344
  ],
213
345
  routing_profile: 'driving-traffic',
214
346
  exclude: 'tunnel,country_border,state_border'
@@ -221,8 +353,8 @@ describe('DirectionsTool', () => {
221
353
  // Test with walking profile
222
354
  await expect(tool.run({
223
355
  coordinates: [
224
- [-73.989, 40.733],
225
- [-73.979, 40.743]
356
+ { longitude: -73.989, latitude: 40.733 },
357
+ { longitude: -73.979, latitude: 40.743 }
226
358
  ],
227
359
  routing_profile: 'walking',
228
360
  exclude: 'toll'
@@ -232,8 +364,8 @@ describe('DirectionsTool', () => {
232
364
  // Test with cycling profile
233
365
  await expect(tool.run({
234
366
  coordinates: [
235
- [-73.989, 40.733],
236
- [-73.979, 40.743]
367
+ { longitude: -73.989, latitude: 40.733 },
368
+ { longitude: -73.979, latitude: 40.743 }
237
369
  ],
238
370
  routing_profile: 'cycling',
239
371
  exclude: 'motorway'
@@ -247,8 +379,8 @@ describe('DirectionsTool', () => {
247
379
  // Test with driving profile
248
380
  await expect(tool.run({
249
381
  coordinates: [
250
- [-73.989, 40.733],
251
- [-73.979, 40.743]
382
+ { longitude: -73.989, latitude: 40.733 },
383
+ { longitude: -73.979, latitude: 40.743 }
252
384
  ],
253
385
  routing_profile: 'driving',
254
386
  exclude: 'ferry'
@@ -258,8 +390,8 @@ describe('DirectionsTool', () => {
258
390
  // Test with walking profile
259
391
  await expect(tool.run({
260
392
  coordinates: [
261
- [-73.989, 40.733],
262
- [-73.979, 40.743]
393
+ { longitude: -73.989, latitude: 40.733 },
394
+ { longitude: -73.979, latitude: 40.743 }
263
395
  ],
264
396
  routing_profile: 'walking',
265
397
  exclude: 'ferry'
@@ -269,8 +401,8 @@ describe('DirectionsTool', () => {
269
401
  // Test with cycling profile
270
402
  await expect(tool.run({
271
403
  coordinates: [
272
- [-73.989, 40.733],
273
- [-73.979, 40.743]
404
+ { longitude: -73.989, latitude: 40.733 },
405
+ { longitude: -73.979, latitude: 40.743 }
274
406
  ],
275
407
  routing_profile: 'cycling',
276
408
  exclude: 'cash_only_tolls'
@@ -284,8 +416,8 @@ describe('DirectionsTool', () => {
284
416
  // Test with driving profile - should work
285
417
  await expect(tool.run({
286
418
  coordinates: [
287
- [-73.989, 40.733],
288
- [-73.979, 40.743]
419
+ { longitude: -73.989, latitude: 40.733 },
420
+ { longitude: -73.979, latitude: 40.743 }
289
421
  ],
290
422
  routing_profile: 'driving',
291
423
  exclude: 'point(-73.95 40.75)'
@@ -295,8 +427,8 @@ describe('DirectionsTool', () => {
295
427
  // Test with walking profile - should fail
296
428
  await expect(tool.run({
297
429
  coordinates: [
298
- [-73.989, 40.733],
299
- [-73.979, 40.743]
430
+ { longitude: -73.989, latitude: 40.733 },
431
+ { longitude: -73.979, latitude: 40.743 }
300
432
  ],
301
433
  routing_profile: 'walking',
302
434
  exclude: 'point(-73.95 40.75)'
@@ -306,8 +438,8 @@ describe('DirectionsTool', () => {
306
438
  // Test with cycling profile - should fail
307
439
  await expect(tool.run({
308
440
  coordinates: [
309
- [-73.989, 40.733],
310
- [-73.979, 40.743]
441
+ { longitude: -73.989, latitude: 40.733 },
442
+ { longitude: -73.979, latitude: 40.743 }
311
443
  ],
312
444
  routing_profile: 'cycling',
313
445
  exclude: 'point(-73.95 40.75)'
@@ -321,8 +453,8 @@ describe('DirectionsTool', () => {
321
453
  // All valid exclusions for driving profile
322
454
  await expect(tool.run({
323
455
  coordinates: [
324
- [-73.989, 40.733],
325
- [-73.979, 40.743]
456
+ { longitude: -73.989, latitude: 40.733 },
457
+ { longitude: -73.979, latitude: 40.743 }
326
458
  ],
327
459
  routing_profile: 'driving',
328
460
  exclude: 'toll,motorway,ferry,cash_only_tolls,point(-73.95 40.75)'
@@ -332,8 +464,8 @@ describe('DirectionsTool', () => {
332
464
  // Mixed valid and invalid exclusions (ferry is valid for walking, toll is not)
333
465
  await expect(tool.run({
334
466
  coordinates: [
335
- [-73.989, 40.733],
336
- [-73.979, 40.743]
467
+ { longitude: -73.989, latitude: 40.733 },
468
+ { longitude: -73.979, latitude: 40.743 }
337
469
  ],
338
470
  routing_profile: 'walking',
339
471
  exclude: 'ferry,toll'
@@ -343,8 +475,8 @@ describe('DirectionsTool', () => {
343
475
  // All valid exclusions for cycling profile
344
476
  await expect(tool.run({
345
477
  coordinates: [
346
- [-73.989, 40.733],
347
- [-73.979, 40.743]
478
+ { longitude: -73.989, latitude: 40.733 },
479
+ { longitude: -73.979, latitude: 40.743 }
348
480
  ],
349
481
  routing_profile: 'cycling',
350
482
  exclude: 'ferry,cash_only_tolls'
@@ -361,8 +493,8 @@ describe('DirectionsTool', () => {
361
493
  // Test with driving profile
362
494
  await expect(tool.run({
363
495
  coordinates: [
364
- [-73.989, 40.733],
365
- [-73.979, 40.743]
496
+ { longitude: -73.989, latitude: 40.733 },
497
+ { longitude: -73.979, latitude: 40.743 }
366
498
  ],
367
499
  routing_profile: 'driving',
368
500
  depart_at: validDateTime
@@ -374,8 +506,8 @@ describe('DirectionsTool', () => {
374
506
  // Test with driving-traffic profile
375
507
  await expect(tool.run({
376
508
  coordinates: [
377
- [-73.989, 40.733],
378
- [-73.979, 40.743]
509
+ { longitude: -73.989, latitude: 40.733 },
510
+ { longitude: -73.979, latitude: 40.743 }
379
511
  ],
380
512
  routing_profile: 'driving-traffic',
381
513
  depart_at: validDateTime
@@ -392,8 +524,8 @@ describe('DirectionsTool', () => {
392
524
  // Test with driving profile
393
525
  await expect(tool.run({
394
526
  coordinates: [
395
- [-73.989, 40.733],
396
- [-73.979, 40.743]
527
+ { longitude: -73.989, latitude: 40.733 },
528
+ { longitude: -73.979, latitude: 40.743 }
397
529
  ],
398
530
  routing_profile: 'driving',
399
531
  max_height: 4.5,
@@ -409,8 +541,8 @@ describe('DirectionsTool', () => {
409
541
  // Test with driving-traffic profile
410
542
  await expect(tool.run({
411
543
  coordinates: [
412
- [-73.989, 40.733],
413
- [-73.979, 40.743]
544
+ { longitude: -73.989, latitude: 40.733 },
545
+ { longitude: -73.979, latitude: 40.743 }
414
546
  ],
415
547
  routing_profile: 'driving-traffic',
416
548
  max_height: 3.2
@@ -425,8 +557,8 @@ describe('DirectionsTool', () => {
425
557
  // Test with walking profile
426
558
  await expect(tool.run({
427
559
  coordinates: [
428
- [-73.989, 40.733],
429
- [-73.979, 40.743]
560
+ { longitude: -73.989, latitude: 40.733 },
561
+ { longitude: -73.979, latitude: 40.743 }
430
562
  ],
431
563
  routing_profile: 'walking',
432
564
  max_height: 4.5
@@ -436,8 +568,8 @@ describe('DirectionsTool', () => {
436
568
  // Test with cycling profile
437
569
  await expect(tool.run({
438
570
  coordinates: [
439
- [-73.989, 40.733],
440
- [-73.979, 40.743]
571
+ { longitude: -73.989, latitude: 40.733 },
572
+ { longitude: -73.979, latitude: 40.743 }
441
573
  ],
442
574
  routing_profile: 'cycling',
443
575
  max_width: 2.0
@@ -450,8 +582,8 @@ describe('DirectionsTool', () => {
450
582
  // Test invalid height (too high)
451
583
  await expect(tool.run({
452
584
  coordinates: [
453
- [-73.989, 40.733],
454
- [-73.979, 40.743]
585
+ { longitude: -73.989, latitude: 40.733 },
586
+ { longitude: -73.979, latitude: 40.743 }
455
587
  ],
456
588
  routing_profile: 'driving',
457
589
  max_height: 15.0
@@ -461,8 +593,8 @@ describe('DirectionsTool', () => {
461
593
  // Test invalid width (negative)
462
594
  await expect(tool.run({
463
595
  coordinates: [
464
- [-73.989, 40.733],
465
- [-73.979, 40.743]
596
+ { longitude: -73.989, latitude: 40.733 },
597
+ { longitude: -73.979, latitude: 40.743 }
466
598
  ],
467
599
  routing_profile: 'driving',
468
600
  max_width: -1.0
@@ -472,8 +604,8 @@ describe('DirectionsTool', () => {
472
604
  // Test invalid weight (too heavy)
473
605
  await expect(tool.run({
474
606
  coordinates: [
475
- [-73.989, 40.733],
476
- [-73.979, 40.743]
607
+ { longitude: -73.989, latitude: 40.733 },
608
+ { longitude: -73.979, latitude: 40.743 }
477
609
  ],
478
610
  routing_profile: 'driving',
479
611
  max_weight: 150.0
@@ -488,8 +620,8 @@ describe('DirectionsTool', () => {
488
620
  // Test with walking profile
489
621
  await expect(tool.run({
490
622
  coordinates: [
491
- [-73.989, 40.733],
492
- [-73.979, 40.743]
623
+ { longitude: -73.989, latitude: 40.733 },
624
+ { longitude: -73.979, latitude: 40.743 }
493
625
  ],
494
626
  routing_profile: 'walking',
495
627
  depart_at: validDateTime
@@ -499,8 +631,8 @@ describe('DirectionsTool', () => {
499
631
  // Test with cycling profile
500
632
  await expect(tool.run({
501
633
  coordinates: [
502
- [-73.989, 40.733],
503
- [-73.979, 40.743]
634
+ { longitude: -73.989, latitude: 40.733 },
635
+ { longitude: -73.979, latitude: 40.743 }
504
636
  ],
505
637
  routing_profile: 'cycling',
506
638
  depart_at: validDateTime
@@ -512,8 +644,8 @@ describe('DirectionsTool', () => {
512
644
  const mockFetch = setupFetch();
513
645
  const tool = new DirectionsTool();
514
646
  const baseCoordinates = [
515
- [-73.989, 40.733],
516
- [-73.979, 40.743]
647
+ { longitude: -73.989, latitude: 40.733 },
648
+ { longitude: -73.979, latitude: 40.743 }
517
649
  ];
518
650
  // Format 1: YYYY-MM-DDThh:mm:ssZ
519
651
  await expect(tool.run({
@@ -540,8 +672,8 @@ describe('DirectionsTool', () => {
540
672
  it('rejects invalid date-time formats', async () => {
541
673
  const tool = new DirectionsTool();
542
674
  const baseCoordinates = [
543
- [-73.989, 40.733],
544
- [-73.979, 40.743]
675
+ { longitude: -73.989, latitude: 40.733 },
676
+ { longitude: -73.979, latitude: 40.743 }
545
677
  ];
546
678
  // Invalid format examples
547
679
  const invalidFormats = [
@@ -567,8 +699,8 @@ describe('DirectionsTool', () => {
567
699
  it('rejects dates with invalid components', async () => {
568
700
  const tool = new DirectionsTool();
569
701
  const baseCoordinates = [
570
- [-73.989, 40.733],
571
- [-73.979, 40.743]
702
+ { longitude: -73.989, latitude: 40.733 },
703
+ { longitude: -73.979, latitude: 40.743 }
572
704
  ];
573
705
  // Invalid time components
574
706
  const invalidDates = [
@@ -587,45 +719,6 @@ describe('DirectionsTool', () => {
587
719
  });
588
720
  }
589
721
  });
590
- it('depart_at accepts and converts YYYY-MM-DDThh:mm:ss format (seconds but no timezone)', async () => {
591
- const mockFetch = setupFetch();
592
- const tool = new DirectionsTool();
593
- const dateTimeWithSeconds = '2025-06-05T10:30:45';
594
- const expectedConvertedDateTime = '2025-06-05T10:30'; // Without seconds
595
- await expect(tool.run({
596
- coordinates: [
597
- [-73.989, 40.733],
598
- [-73.979, 40.743]
599
- ],
600
- depart_at: dateTimeWithSeconds
601
- })).resolves.not.toMatchObject({
602
- is_error: true
603
- });
604
- // Verify the seconds were stripped in the API call
605
- const calledUrl = mockFetch.mock.calls[0][0];
606
- expect(calledUrl).toContain(`depart_at=${encodeURIComponent(expectedConvertedDateTime)}`);
607
- expect(calledUrl).not.toContain(`depart_at=${encodeURIComponent(dateTimeWithSeconds)}`);
608
- });
609
- it('arrive_by accepts and converts YYYY-MM-DDThh:mm:ss format (seconds but no timezone)', async () => {
610
- const mockFetch = setupFetch();
611
- const tool = new DirectionsTool();
612
- const dateTimeWithSeconds = '2025-06-05T10:30:45';
613
- const expectedConvertedDateTime = '2025-06-05T10:30'; // Without seconds
614
- await expect(tool.run({
615
- coordinates: [
616
- [-73.989, 40.733],
617
- [-73.979, 40.743]
618
- ],
619
- routing_profile: 'driving',
620
- arrive_by: dateTimeWithSeconds
621
- })).resolves.not.toMatchObject({
622
- is_error: true
623
- });
624
- // Verify the seconds were stripped in the API call
625
- const calledUrl = mockFetch.mock.calls[0][0];
626
- expect(calledUrl).toContain(`arrive_by=${encodeURIComponent(expectedConvertedDateTime)}`);
627
- expect(calledUrl).not.toContain(`arrive_by=${encodeURIComponent(dateTimeWithSeconds)}`);
628
- });
629
722
  });
630
723
  describe('arrive_by parameter validations', () => {
631
724
  it('accepts arrive_by with driving profile only', async () => {
@@ -634,8 +727,8 @@ describe('DirectionsTool', () => {
634
727
  // Test with driving profile - should work
635
728
  await new DirectionsTool().run({
636
729
  coordinates: [
637
- [-74.1, 40.7],
638
- [-74.2, 40.8]
730
+ { longitude: -74.1, latitude: 40.7 },
731
+ { longitude: -74.2, latitude: 40.8 }
639
732
  ],
640
733
  routing_profile: 'driving',
641
734
  arrive_by: validDateTime
@@ -649,8 +742,8 @@ describe('DirectionsTool', () => {
649
742
  // Test with driving-traffic profile
650
743
  const result1 = await new DirectionsTool().run({
651
744
  coordinates: [
652
- [-74.1, 40.7],
653
- [-74.2, 40.8]
745
+ { longitude: -74.1, latitude: 40.7 },
746
+ { longitude: -74.2, latitude: 40.8 }
654
747
  ],
655
748
  routing_profile: 'driving-traffic',
656
749
  arrive_by: validDateTime
@@ -659,8 +752,8 @@ describe('DirectionsTool', () => {
659
752
  // Test with walking profile
660
753
  const result2 = await new DirectionsTool().run({
661
754
  coordinates: [
662
- [-74.1, 40.7],
663
- [-74.2, 40.8]
755
+ { longitude: -74.1, latitude: 40.7 },
756
+ { longitude: -74.2, latitude: 40.8 }
664
757
  ],
665
758
  routing_profile: 'walking',
666
759
  arrive_by: validDateTime
@@ -669,8 +762,8 @@ describe('DirectionsTool', () => {
669
762
  // Test with cycling profile
670
763
  const result3 = await new DirectionsTool().run({
671
764
  coordinates: [
672
- [-74.1, 40.7],
673
- [-74.2, 40.8]
765
+ { longitude: -74.1, latitude: 40.7 },
766
+ { longitude: -74.2, latitude: 40.8 }
674
767
  ],
675
768
  routing_profile: 'cycling',
676
769
  arrive_by: validDateTime
@@ -680,8 +773,8 @@ describe('DirectionsTool', () => {
680
773
  it('rejects when both arrive_by and depart_at are provided', async () => {
681
774
  const result = await new DirectionsTool().run({
682
775
  coordinates: [
683
- [-74.1, 40.7],
684
- [-74.2, 40.8]
776
+ { longitude: -74.1, latitude: 40.7 },
777
+ { longitude: -74.2, latitude: 40.8 }
685
778
  ],
686
779
  routing_profile: 'driving',
687
780
  depart_at: '2025-06-05T09:30:00Z',
@@ -694,8 +787,8 @@ describe('DirectionsTool', () => {
694
787
  // Test with Z format
695
788
  await new DirectionsTool().run({
696
789
  coordinates: [
697
- [-74.1, 40.7],
698
- [-74.2, 40.8]
790
+ { longitude: -74.1, latitude: 40.7 },
791
+ { longitude: -74.2, latitude: 40.8 }
699
792
  ],
700
793
  routing_profile: 'driving',
701
794
  arrive_by: '2025-06-05T10:30:00Z'
@@ -705,8 +798,8 @@ describe('DirectionsTool', () => {
705
798
  // Test with timezone offset format
706
799
  await new DirectionsTool().run({
707
800
  coordinates: [
708
- [-74.1, 40.7],
709
- [-74.2, 40.8]
801
+ { longitude: -74.1, latitude: 40.7 },
802
+ { longitude: -74.2, latitude: 40.8 }
710
803
  ],
711
804
  routing_profile: 'driving',
712
805
  arrive_by: '2025-06-05T10:30:00+02:00'
@@ -716,8 +809,8 @@ describe('DirectionsTool', () => {
716
809
  // Test with simple time format (no seconds, no timezone)
717
810
  await new DirectionsTool().run({
718
811
  coordinates: [
719
- [-74.1, 40.7],
720
- [-74.2, 40.8]
812
+ { longitude: -74.1, latitude: 40.7 },
813
+ { longitude: -74.2, latitude: 40.8 }
721
814
  ],
722
815
  routing_profile: 'driving',
723
816
  arrive_by: '2025-06-05T10:30'
@@ -743,8 +836,8 @@ describe('DirectionsTool', () => {
743
836
  for (const format of invalidFormats) {
744
837
  const result = await new DirectionsTool().run({
745
838
  coordinates: [
746
- [-74.1, 40.7],
747
- [-74.2, 40.8]
839
+ { longitude: -74.1, latitude: 40.7 },
840
+ { longitude: -74.2, latitude: 40.8 }
748
841
  ],
749
842
  routing_profile: 'driving',
750
843
  arrive_by: format
@@ -764,8 +857,8 @@ describe('DirectionsTool', () => {
764
857
  for (const date of invalidDates) {
765
858
  const result = await new DirectionsTool().run({
766
859
  coordinates: [
767
- [-74.1, 40.7],
768
- [-74.2, 40.8]
860
+ { longitude: -74.1, latitude: 40.7 },
861
+ { longitude: -74.2, latitude: 40.8 }
769
862
  ],
770
863
  routing_profile: 'driving',
771
864
  arrive_by: date
@@ -774,49 +867,5 @@ describe('DirectionsTool', () => {
774
867
  }
775
868
  });
776
869
  });
777
- it('validates geometries enum values', async () => {
778
- const tool = new DirectionsTool();
779
- // Valid values: 'none' and 'geojson'
780
- await expect(tool.run({
781
- coordinates: [
782
- [-73.989, 40.733],
783
- [-73.979, 40.743]
784
- ],
785
- geometries: 'none'
786
- })).resolves.not.toMatchObject({
787
- is_error: true
788
- });
789
- await expect(tool.run({
790
- coordinates: [
791
- [-73.989, 40.733],
792
- [-73.979, 40.743]
793
- ],
794
- geometries: 'geojson'
795
- })).resolves.not.toMatchObject({
796
- is_error: true
797
- });
798
- // Invalid values: 'polyline' and 'polyline6' were removed
799
- // Test with invalid string values (runtime validation)
800
- await expect(tool.run({
801
- coordinates: [
802
- [-73.989, 40.733],
803
- [-73.979, 40.743]
804
- ],
805
- // @ts-ignore - Testing with invalid value for runtime validation
806
- geometries: 'polyline'
807
- })).resolves.toMatchObject({
808
- is_error: true
809
- });
810
- await expect(tool.run({
811
- coordinates: [
812
- [-73.989, 40.733],
813
- [-73.979, 40.743]
814
- ],
815
- // @ts-ignore - Testing with invalid value for runtime validation
816
- geometries: 'polyline6'
817
- })).resolves.toMatchObject({
818
- is_error: true
819
- });
820
- });
821
870
  });
822
871
  //# sourceMappingURL=DirectionsTool.test.js.map