@vulog/aima-booking 1.1.89 → 1.1.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,26 +1,308 @@
1
1
  # @vulog/aima-booking
2
2
 
3
+ Booking management module for the AIMA platform. This module provides functionality to manage booking requests, stations, and subscription bookings.
4
+
5
+ ## Installation
6
+
3
7
  ```bash
4
- npm i @vulog/aima-client @vulog/aima-core @vulog/aima-booking
8
+ npm install @vulog/aima-client @vulog/aima-core @vulog/aima-booking
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Initialize Client
14
+
15
+ ```javascript
16
+ import { getClient } from '@vulog/aima-client';
17
+ import {
18
+ getBookingRequests,
19
+ getScheduleBookingRequests,
20
+ getSubscriptionBookingRequests,
21
+ getSATBookingRequests,
22
+ getBookingRequestById,
23
+ getBookingRequestByTrip,
24
+ getSubscriptionBookingRequestById,
25
+ getStations,
26
+ getStationById
27
+ } from '@vulog/aima-booking';
28
+
29
+ const client = getClient({
30
+ apiKey: 'your-api-key',
31
+ baseUrl: 'https://your-api-base-url',
32
+ clientId: 'your-client-id',
33
+ clientSecret: 'your-client-secret',
34
+ fleetId: 'your-fleet-id',
35
+ });
36
+ ```
37
+
38
+ ## API Reference
39
+
40
+ ### Booking Requests
41
+
42
+ #### getBookingRequests
43
+
44
+ Retrieve booking requests with optional filtering.
45
+
46
+ ```javascript
47
+ const bookingRequests = await getBookingRequests(client, 'ONGOING', {
48
+ limit: 50,
49
+ offset: 0,
50
+ userId: 'user-uuid-here'
51
+ });
52
+ ```
53
+
54
+ **Parameters:**
55
+ - `client`: AIMA client instance
56
+ - `status`: Booking request status ('ONGOING', 'COMPLETED', 'CANCELLED', 'EXPIRED')
57
+ - `filters`: Optional filter object
58
+ - `limit`: Maximum number of results
59
+ - `offset`: Number of results to skip
60
+ - `userId`: Filter by user ID
61
+ - `vehicleId`: Filter by vehicle ID
62
+ - `stationId`: Filter by station ID
63
+
64
+ #### getScheduleBookingRequests
65
+
66
+ Get scheduled booking requests.
67
+
68
+ ```javascript
69
+ const scheduledRequests = await getScheduleBookingRequests(client, {
70
+ startDate: '2024-01-01T00:00:00Z',
71
+ endDate: '2024-01-31T23:59:59Z'
72
+ });
73
+ ```
74
+
75
+ #### getSubscriptionBookingRequests
76
+
77
+ Get subscription-based booking requests.
78
+
79
+ ```javascript
80
+ const subscriptionRequests = await getSubscriptionBookingRequests(client, {
81
+ status: 'ACTIVE',
82
+ userId: 'user-uuid-here'
83
+ });
84
+ ```
85
+
86
+ #### getSATBookingRequests
87
+
88
+ Get SAT (Scheduled Access Time) booking requests.
89
+
90
+ ```javascript
91
+ const satRequests = await getSATBookingRequests(client, 'PENDING');
92
+ ```
93
+
94
+ ### Individual Booking Requests
95
+
96
+ #### getBookingRequestById
97
+
98
+ Retrieve a specific booking request by ID.
99
+
100
+ ```javascript
101
+ const bookingRequest = await getBookingRequestById(client, 'bb493049-5b4f-43ea-8a65-964a13aec549');
102
+ ```
103
+
104
+ #### getBookingRequestByTrip
105
+
106
+ Get booking request associated with a trip.
107
+
108
+ ```javascript
109
+ const bookingRequest = await getBookingRequestByTrip(client, '33E8E42710144E15A5CC447E4D3524F4');
110
+ ```
111
+
112
+ #### getSubscriptionBookingRequestById
113
+
114
+ Get subscription booking request by ID.
115
+
116
+ ```javascript
117
+ const subscriptionRequest = await getSubscriptionBookingRequestById(client, 'b7faa2a2-e8fc-4a29-8de7-09ce783b9797');
118
+ ```
119
+
120
+ ### Stations
121
+
122
+ #### getStations
123
+
124
+ Retrieve stations with optional includes.
125
+
126
+ ```javascript
127
+ const stations = await getStations(client, ['OPEN_HOUR', 'INFO']);
128
+ ```
129
+
130
+ **Parameters:**
131
+ - `client`: AIMA client instance
132
+ - `includes`: Array of data to include ('OPEN_HOUR', 'INFO', 'VEHICLES', 'ZONES')
133
+
134
+ #### getStationById
135
+
136
+ Get a specific station by ID.
137
+
138
+ ```javascript
139
+ const station = await getStationById(client, 'station-id-here', ['OPEN_HOUR', 'INFO']);
140
+ ```
141
+
142
+ ## Types
143
+
144
+ ### BookingRequest
145
+
146
+ ```typescript
147
+ interface BookingRequest {
148
+ id: string;
149
+ userId: string;
150
+ vehicleId: string;
151
+ stationId: string;
152
+ status: 'PENDING' | 'ONGOING' | 'COMPLETED' | 'CANCELLED' | 'EXPIRED';
153
+ startTime: string;
154
+ endTime: string;
155
+ createdAt: string;
156
+ updatedAt: string;
157
+ }
158
+ ```
159
+
160
+ ### Station
161
+
162
+ ```typescript
163
+ interface Station {
164
+ id: string;
165
+ name: string;
166
+ address: string;
167
+ coordinates: {
168
+ latitude: number;
169
+ longitude: number;
170
+ };
171
+ isActive: boolean;
172
+ openHours: OpenHours[];
173
+ info: StationInfo;
174
+ vehicles: Vehicle[];
175
+ zones: Zone[];
176
+ }
177
+ ```
178
+
179
+ ### BookingRequestStatus
180
+
181
+ ```typescript
182
+ type BookingRequestStatus = 'PENDING' | 'ONGOING' | 'COMPLETED' | 'CANCELLED' | 'EXPIRED';
183
+ ```
184
+
185
+ ### ServiceType
186
+
187
+ ```typescript
188
+ type ServiceType = 'CAR_SHARING' | 'BIKE_SHARING' | 'SCOOTER_SHARING' | 'MULTIMODAL';
5
189
  ```
6
190
 
191
+ ## Error Handling
192
+
193
+ All functions include validation and will throw appropriate errors if:
194
+ - Required parameters are missing
195
+ - Invalid booking request or station IDs are provided
196
+ - Invalid status values are used
197
+ - Network errors occur
198
+
199
+ ## Examples
200
+
201
+ ### Complete Booking Management Workflow
202
+
7
203
  ```javascript
8
204
  import { getClient } from '@vulog/aima-client';
9
- import { getBookingRequests } from '@vulog/aima-booking';
205
+ import {
206
+ getBookingRequests,
207
+ getStations,
208
+ getBookingRequestById
209
+ } from '@vulog/aima-booking';
10
210
 
11
211
  const client = getClient({
12
- apiKey: '...',
13
- baseUrl: '...',
14
- clientId: '...',
15
- clientSecret: '...',
16
- fleetId: '...',
212
+ apiKey: 'your-api-key',
213
+ baseUrl: 'https://your-api-base-url',
214
+ clientId: 'your-client-id',
215
+ clientSecret: 'your-client-secret',
216
+ fleetId: 'your-fleet-id',
17
217
  });
18
218
 
19
- const response = await getBookingRequests(client, 'ONGOING');
219
+ async function bookingWorkflow() {
220
+ try {
221
+ // Get all ongoing booking requests
222
+ const ongoingRequests = await getBookingRequests(client, 'ONGOING');
223
+ console.log(`Found ${ongoingRequests.length} ongoing booking requests`);
224
+
225
+ // Get stations with full information
226
+ const stations = await getStations(client, ['OPEN_HOUR', 'INFO', 'VEHICLES']);
227
+ console.log(`Found ${stations.length} stations`);
228
+
229
+ // Get specific booking request
230
+ const bookingRequest = await getBookingRequestById(client, 'bb493049-5b4f-43ea-8a65-964a13aec549');
231
+ console.log('Booking request details:', bookingRequest);
232
+
233
+ return { ongoingRequests, stations, bookingRequest };
234
+ } catch (error) {
235
+ console.error('Booking workflow error:', error);
236
+ throw error;
237
+ }
238
+ }
239
+ ```
20
240
 
21
- const station = await getStations(client, ['OPEN_HOUR', 'INFO']);
241
+ ### Station Analysis
22
242
 
23
- const br1 = await getBookingRequestById(client, 'bb493049-5b4f-43ea-8a65-964a13aec549');
24
- const br2 = await getBookingRequestByTrip(client, '33E8E42710144E15A5CC447E4D3524F4');
25
- const sub = await getSubscriptionBookingRequestById(client, 'b7faa2a2-e8fc-4a29-8de7-09ce783b9797');
243
+ ```javascript
244
+ async function analyzeStations(client) {
245
+ try {
246
+ const stations = await getStations(client, ['OPEN_HOUR', 'INFO', 'VEHICLES']);
247
+
248
+ const analysis = {
249
+ totalStations: stations.length,
250
+ activeStations: stations.filter(s => s.isActive).length,
251
+ stationsWithVehicles: stations.filter(s => s.vehicles && s.vehicles.length > 0).length,
252
+ averageVehiclesPerStation: stations.reduce((sum, s) => sum + (s.vehicles?.length || 0), 0) / stations.length,
253
+ stationsByZone: stations.reduce((acc, station) => {
254
+ station.zones?.forEach(zone => {
255
+ acc[zone.name] = (acc[zone.name] || 0) + 1;
256
+ });
257
+ return acc;
258
+ }, {})
259
+ };
260
+
261
+ console.log('Station Analysis:');
262
+ console.log(`Total Stations: ${analysis.totalStations}`);
263
+ console.log(`Active Stations: ${analysis.activeStations}`);
264
+ console.log(`Stations with Vehicles: ${analysis.stationsWithVehicles}`);
265
+ console.log(`Average Vehicles per Station: ${analysis.averageVehiclesPerStation.toFixed(2)}`);
266
+ console.log('Stations by Zone:', analysis.stationsByZone);
267
+
268
+ return analysis;
269
+ } catch (error) {
270
+ console.error('Station analysis error:', error);
271
+ throw error;
272
+ }
273
+ }
274
+ ```
275
+
276
+ ### Booking Request Monitoring
277
+
278
+ ```javascript
279
+ async function monitorBookingRequests(client) {
280
+ try {
281
+ const [ongoing, completed, cancelled] = await Promise.all([
282
+ getBookingRequests(client, 'ONGOING'),
283
+ getBookingRequests(client, 'COMPLETED'),
284
+ getBookingRequests(client, 'CANCELLED')
285
+ ]);
286
+
287
+ const monitoring = {
288
+ ongoing: ongoing.length,
289
+ completed: completed.length,
290
+ cancelled: cancelled.length,
291
+ total: ongoing.length + completed.length + cancelled.length,
292
+ completionRate: completed.length / (completed.length + cancelled.length) * 100
293
+ };
294
+
295
+ console.log('Booking Request Monitoring:');
296
+ console.log(`Ongoing: ${monitoring.ongoing}`);
297
+ console.log(`Completed: ${monitoring.completed}`);
298
+ console.log(`Cancelled: ${monitoring.cancelled}`);
299
+ console.log(`Total: ${monitoring.total}`);
300
+ console.log(`Completion Rate: ${monitoring.completionRate.toFixed(2)}%`);
301
+
302
+ return monitoring;
303
+ } catch (error) {
304
+ console.error('Booking monitoring error:', error);
305
+ throw error;
306
+ }
307
+ }
26
308
  ```
package/dist/index.d.mts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Client } from '@vulog/aima-client';
2
2
  import { PaginableOptions, PaginableResponse } from '@vulog/aima-core';
3
3
  import { z } from 'zod';
4
+ import { UUID } from 'crypto';
4
5
 
5
6
  type PaymentReceipts = {
6
7
  id: string;
@@ -195,4 +196,8 @@ declare const IncludeSchema: z.ZodEnum<["INFO", "SERVICES"]>;
195
196
  type IncludeStation = z.infer<typeof IncludeSchema>;
196
197
  declare const getStationById: (client: Client, id: string, includes?: IncludeStation[]) => Promise<Station | null>;
197
198
 
198
- export { type BaseBookingRequest, type BookingRequest, type BookingRequestFilters, type BookingRequestStatus, type CustomPrice, type DayOpeningHours, type Days, type GeoInfo, type Include, type IncludeStation, type OpeningHours, type PaymentReceipts, type SATBookingRequest, type SATBookingRequestStatus, type Service, type ServiceInfo, type ServiceType, type Station, type Timetable, getBookingRequestById, getBookingRequestByTrip, getBookingRequests, getSATBookingRequests, getScheduleBookingRequests, getStationById, getStations, getSubscriptionBookingRequestById, getSubscriptionBookingRequests };
199
+ declare const allocateVehicle: (client: Client, bookingRequestId: UUID, vehicleId: UUID, serviceId: UUID) => Promise<SATBookingRequest>;
200
+
201
+ declare const deallocateVehicle: (client: Client, bookingRequestId: UUID, vehicleId: UUID) => Promise<SATBookingRequest>;
202
+
203
+ export { type BaseBookingRequest, type BookingRequest, type BookingRequestFilters, type BookingRequestStatus, type CustomPrice, type DayOpeningHours, type Days, type GeoInfo, type Include, type IncludeStation, type OpeningHours, type PaymentReceipts, type SATBookingRequest, type SATBookingRequestStatus, type Service, type ServiceInfo, type ServiceType, type Station, type Timetable, allocateVehicle, deallocateVehicle, getBookingRequestById, getBookingRequestByTrip, getBookingRequests, getSATBookingRequests, getScheduleBookingRequests, getStationById, getStations, getSubscriptionBookingRequestById, getSubscriptionBookingRequests };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Client } from '@vulog/aima-client';
2
2
  import { PaginableOptions, PaginableResponse } from '@vulog/aima-core';
3
3
  import { z } from 'zod';
4
+ import { UUID } from 'crypto';
4
5
 
5
6
  type PaymentReceipts = {
6
7
  id: string;
@@ -195,4 +196,8 @@ declare const IncludeSchema: z.ZodEnum<["INFO", "SERVICES"]>;
195
196
  type IncludeStation = z.infer<typeof IncludeSchema>;
196
197
  declare const getStationById: (client: Client, id: string, includes?: IncludeStation[]) => Promise<Station | null>;
197
198
 
198
- export { type BaseBookingRequest, type BookingRequest, type BookingRequestFilters, type BookingRequestStatus, type CustomPrice, type DayOpeningHours, type Days, type GeoInfo, type Include, type IncludeStation, type OpeningHours, type PaymentReceipts, type SATBookingRequest, type SATBookingRequestStatus, type Service, type ServiceInfo, type ServiceType, type Station, type Timetable, getBookingRequestById, getBookingRequestByTrip, getBookingRequests, getSATBookingRequests, getScheduleBookingRequests, getStationById, getStations, getSubscriptionBookingRequestById, getSubscriptionBookingRequests };
199
+ declare const allocateVehicle: (client: Client, bookingRequestId: UUID, vehicleId: UUID, serviceId: UUID) => Promise<SATBookingRequest>;
200
+
201
+ declare const deallocateVehicle: (client: Client, bookingRequestId: UUID, vehicleId: UUID) => Promise<SATBookingRequest>;
202
+
203
+ export { type BaseBookingRequest, type BookingRequest, type BookingRequestFilters, type BookingRequestStatus, type CustomPrice, type DayOpeningHours, type Days, type GeoInfo, type Include, type IncludeStation, type OpeningHours, type PaymentReceipts, type SATBookingRequest, type SATBookingRequestStatus, type Service, type ServiceInfo, type ServiceType, type Station, type Timetable, allocateVehicle, deallocateVehicle, getBookingRequestById, getBookingRequestByTrip, getBookingRequests, getSATBookingRequests, getScheduleBookingRequests, getStationById, getStations, getSubscriptionBookingRequestById, getSubscriptionBookingRequests };
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,11 +17,21 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
21
31
  var index_exports = {};
22
32
  __export(index_exports, {
33
+ allocateVehicle: () => allocateVehicle,
34
+ deallocateVehicle: () => deallocateVehicle,
23
35
  getBookingRequestById: () => getBookingRequestById,
24
36
  getBookingRequestByTrip: () => getBookingRequestByTrip,
25
37
  getBookingRequests: () => getBookingRequests,
@@ -358,7 +370,7 @@ var getStationById = async (client, id, includes = []) => {
358
370
  });
359
371
  if (station && includes.includes("INFO")) {
360
372
  const poi = await client.get(
361
- `/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/poi/${station.poiId}`,
373
+ `/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/pois/${station.poiId}`,
362
374
  {
363
375
  headers: { accept: "application/vnd.geo+json" }
364
376
  }
@@ -409,8 +421,47 @@ var getStationById = async (client, id, includes = []) => {
409
421
  }
410
422
  return station;
411
423
  };
424
+
425
+ // src/allocateVehicle.ts
426
+ var import_zod6 = __toESM(require("zod"));
427
+ var allocateVehicleSchema = import_zod6.default.object({
428
+ bookingRequestId: import_zod6.default.string().uuid(),
429
+ vehicleId: import_zod6.default.string().uuid(),
430
+ serviceId: import_zod6.default.string().uuid()
431
+ });
432
+ var allocateVehicle = async (client, bookingRequestId, vehicleId, serviceId) => {
433
+ const resultPayload = allocateVehicleSchema.safeParse({ bookingRequestId, vehicleId, serviceId });
434
+ if (!resultPayload.success) {
435
+ throw new TypeError("Invalid args", {
436
+ cause: resultPayload.error.issues
437
+ });
438
+ }
439
+ return client.post(
440
+ `boapi/proxy/user/scheduleATrip/fleets/${client.clientOptions.fleetId}/bookingrequests/${bookingRequestId}/allocate/${vehicleId}?serviceId=${serviceId}`
441
+ ).then(({ data }) => data);
442
+ };
443
+
444
+ // src/deallocateVehicle.ts
445
+ var import_zod7 = __toESM(require("zod"));
446
+ var deallocateVehicleSchema = import_zod7.default.object({
447
+ bookingRequestId: import_zod7.default.string().uuid(),
448
+ vehicleId: import_zod7.default.string().uuid()
449
+ });
450
+ var deallocateVehicle = async (client, bookingRequestId, vehicleId) => {
451
+ const resultPayload = deallocateVehicleSchema.safeParse({ bookingRequestId, vehicleId });
452
+ if (!resultPayload.success) {
453
+ throw new TypeError("Invalid args", {
454
+ cause: resultPayload.error.issues
455
+ });
456
+ }
457
+ return client.delete(
458
+ `boapi/proxy/user/scheduledBooking/fleets/${client.clientOptions.fleetId}/bookingrequests/${bookingRequestId}/vehicles/${vehicleId}`
459
+ ).then(({ data }) => data);
460
+ };
412
461
  // Annotate the CommonJS export names for ESM import in node:
413
462
  0 && (module.exports = {
463
+ allocateVehicle,
464
+ deallocateVehicle,
414
465
  getBookingRequestById,
415
466
  getBookingRequestByTrip,
416
467
  getBookingRequests,
package/dist/index.mjs CHANGED
@@ -324,7 +324,7 @@ var getStationById = async (client, id, includes = []) => {
324
324
  });
325
325
  if (station && includes.includes("INFO")) {
326
326
  const poi = await client.get(
327
- `/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/poi/${station.poiId}`,
327
+ `/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/pois/${station.poiId}`,
328
328
  {
329
329
  headers: { accept: "application/vnd.geo+json" }
330
330
  }
@@ -375,7 +375,46 @@ var getStationById = async (client, id, includes = []) => {
375
375
  }
376
376
  return station;
377
377
  };
378
+
379
+ // src/allocateVehicle.ts
380
+ import z6 from "zod";
381
+ var allocateVehicleSchema = z6.object({
382
+ bookingRequestId: z6.string().uuid(),
383
+ vehicleId: z6.string().uuid(),
384
+ serviceId: z6.string().uuid()
385
+ });
386
+ var allocateVehicle = async (client, bookingRequestId, vehicleId, serviceId) => {
387
+ const resultPayload = allocateVehicleSchema.safeParse({ bookingRequestId, vehicleId, serviceId });
388
+ if (!resultPayload.success) {
389
+ throw new TypeError("Invalid args", {
390
+ cause: resultPayload.error.issues
391
+ });
392
+ }
393
+ return client.post(
394
+ `boapi/proxy/user/scheduleATrip/fleets/${client.clientOptions.fleetId}/bookingrequests/${bookingRequestId}/allocate/${vehicleId}?serviceId=${serviceId}`
395
+ ).then(({ data }) => data);
396
+ };
397
+
398
+ // src/deallocateVehicle.ts
399
+ import z7 from "zod";
400
+ var deallocateVehicleSchema = z7.object({
401
+ bookingRequestId: z7.string().uuid(),
402
+ vehicleId: z7.string().uuid()
403
+ });
404
+ var deallocateVehicle = async (client, bookingRequestId, vehicleId) => {
405
+ const resultPayload = deallocateVehicleSchema.safeParse({ bookingRequestId, vehicleId });
406
+ if (!resultPayload.success) {
407
+ throw new TypeError("Invalid args", {
408
+ cause: resultPayload.error.issues
409
+ });
410
+ }
411
+ return client.delete(
412
+ `boapi/proxy/user/scheduledBooking/fleets/${client.clientOptions.fleetId}/bookingrequests/${bookingRequestId}/vehicles/${vehicleId}`
413
+ ).then(({ data }) => data);
414
+ };
378
415
  export {
416
+ allocateVehicle,
417
+ deallocateVehicle,
379
418
  getBookingRequestById,
380
419
  getBookingRequestByTrip,
381
420
  getBookingRequests,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vulog/aima-booking",
3
- "version": "1.1.89",
3
+ "version": "1.1.92",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -19,8 +19,8 @@
19
19
  "author": "Vulog",
20
20
  "license": "MIT",
21
21
  "dependencies": {
22
- "@vulog/aima-client": "1.1.89",
23
- "@vulog/aima-core": "1.1.89"
22
+ "@vulog/aima-client": "1.1.92",
23
+ "@vulog/aima-core": "1.1.92"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "es-toolkit": "^1.39.9",
@@ -0,0 +1,49 @@
1
+ import { describe, test, vi, expect, beforeEach } from 'vitest';
2
+
3
+ import { Client } from '@vulog/aima-client';
4
+ import { allocateVehicle } from './allocateVehicle';
5
+ import { UUID } from 'crypto';
6
+
7
+ describe('allocateVehicle', () => {
8
+ const postMock = vi.fn();
9
+ const client = {
10
+ post: postMock,
11
+ clientOptions: {
12
+ fleetId: 'FLEET_ID',
13
+ },
14
+ } as unknown as Client;
15
+
16
+ beforeEach(() => {
17
+ vi.clearAllMocks();
18
+ });
19
+
20
+ test('should return invalid args', async () => {
21
+ const bookingRequestId = 'BOOKING_REQUEST_ID';
22
+ const vehicleId = 'VEHICLE_ID';
23
+ const serviceId = 'SERVICE_ID';
24
+
25
+ // expect to throw error if invalid UUIDs are provided
26
+ await expect(
27
+ allocateVehicle(client, bookingRequestId as UUID, vehicleId as UUID, serviceId as UUID)
28
+ ).rejects.toThrow('Invalid args');
29
+ });
30
+
31
+ test('should allocate vehicle successfully', async () => {
32
+ const bookingRequestId = '550e8400-e29b-41d4-a716-446655440000';
33
+ const vehicleId = '550e8400-e29b-41d4-a716-446655440001';
34
+ const serviceId = '550e8400-e29b-41d4-a716-446655440002';
35
+
36
+ const mockResponse = {
37
+ id: 'some-id',
38
+ status: 'ALLOCATED',
39
+ // other properties of SATBookingRequest
40
+ };
41
+
42
+ postMock.mockResolvedValueOnce({
43
+ data: mockResponse,
44
+ });
45
+
46
+ const result = await allocateVehicle(client, bookingRequestId, vehicleId, serviceId);
47
+ expect(result).toEqual(mockResponse);
48
+ });
49
+ });
@@ -0,0 +1,32 @@
1
+ import { UUID } from 'crypto';
2
+
3
+ import { Client } from '@vulog/aima-client';
4
+
5
+ import z from 'zod';
6
+
7
+ import { SATBookingRequest } from './types';
8
+
9
+ const allocateVehicleSchema = z.object({
10
+ bookingRequestId: z.string().uuid(),
11
+ vehicleId: z.string().uuid(),
12
+ serviceId: z.string().uuid(),
13
+ });
14
+
15
+ export const allocateVehicle = async (
16
+ client: Client,
17
+ bookingRequestId: UUID,
18
+ vehicleId: UUID,
19
+ serviceId: UUID
20
+ ): Promise<SATBookingRequest> => {
21
+ const resultPayload = allocateVehicleSchema.safeParse({ bookingRequestId, vehicleId, serviceId });
22
+ if (!resultPayload.success) {
23
+ throw new TypeError('Invalid args', {
24
+ cause: resultPayload.error.issues,
25
+ });
26
+ }
27
+ return client
28
+ .post<SATBookingRequest>(
29
+ `boapi/proxy/user/scheduleATrip/fleets/${client.clientOptions.fleetId}/bookingrequests/${bookingRequestId}/allocate/${vehicleId}?serviceId=${serviceId}`
30
+ )
31
+ .then(({ data }) => data);
32
+ };
@@ -0,0 +1,47 @@
1
+ import { describe, test, vi, expect, beforeEach } from 'vitest';
2
+
3
+ import { Client } from '@vulog/aima-client';
4
+ import { deallocateVehicle } from './deallocateVehicle';
5
+ import { UUID } from 'crypto';
6
+
7
+ describe('deallocateVehicle', () => {
8
+ const deleteMock = vi.fn();
9
+ const client = {
10
+ delete: deleteMock,
11
+ clientOptions: {
12
+ fleetId: 'FLEET_ID',
13
+ },
14
+ } as unknown as Client;
15
+
16
+ beforeEach(() => {
17
+ vi.clearAllMocks();
18
+ });
19
+
20
+ test('should return invalid args', async () => {
21
+ const bookingRequestId = 'BOOKING_REQUEST_ID';
22
+ const vehicleId = 'VEHICLE_ID';
23
+
24
+ // expect to throw error if invalid UUIDs are provided
25
+ await expect(deallocateVehicle(client, bookingRequestId as UUID, vehicleId as UUID)).rejects.toThrow(
26
+ 'Invalid args'
27
+ );
28
+ });
29
+
30
+ test('should deallocate vehicle successfully', async () => {
31
+ const bookingRequestId = '550e8400-e29b-41d4-a716-446655440000';
32
+ const vehicleId = '550e8400-e29b-41d4-a716-446655440001';
33
+
34
+ const mockResponse = {
35
+ id: 'some-id',
36
+ vehicleId: null,
37
+ // other properties of SATBookingRequest
38
+ };
39
+
40
+ deleteMock.mockResolvedValueOnce({
41
+ data: mockResponse,
42
+ });
43
+
44
+ const result = await deallocateVehicle(client, bookingRequestId, vehicleId);
45
+ expect(result).toEqual(mockResponse);
46
+ });
47
+ });
@@ -0,0 +1,32 @@
1
+ // https://java-sta.vulog.com/boapi/proxy/user/scheduledBooking/fleets/LEO-CAMTR/bookingrequests/2e603670-9684-4df1-9ff5-7f380ce6b8dc/vehicles/2e15c6f2-0b75-47ca-b885-b60f6ac35b12
2
+
3
+ import { UUID } from 'crypto';
4
+
5
+ import { Client } from '@vulog/aima-client';
6
+
7
+ import z from 'zod';
8
+
9
+ import { SATBookingRequest } from './types';
10
+
11
+ const deallocateVehicleSchema = z.object({
12
+ bookingRequestId: z.string().uuid(),
13
+ vehicleId: z.string().uuid(),
14
+ });
15
+
16
+ export const deallocateVehicle = async (
17
+ client: Client,
18
+ bookingRequestId: UUID,
19
+ vehicleId: UUID
20
+ ): Promise<SATBookingRequest> => {
21
+ const resultPayload = deallocateVehicleSchema.safeParse({ bookingRequestId, vehicleId });
22
+ if (!resultPayload.success) {
23
+ throw new TypeError('Invalid args', {
24
+ cause: resultPayload.error.issues,
25
+ });
26
+ }
27
+ return client
28
+ .delete<SATBookingRequest>(
29
+ `boapi/proxy/user/scheduledBooking/fleets/${client.clientOptions.fleetId}/bookingrequests/${bookingRequestId}/vehicles/${vehicleId}`
30
+ )
31
+ .then(({ data }) => data);
32
+ };
@@ -227,7 +227,7 @@ describe('getStationById', () => {
227
227
  config: {}
228
228
  });
229
229
  }
230
- if (url === `/boapi/proxy/geoloc/fleets/${FLEET_ID}/poi/${POI_ID}` ) {
230
+ if (url === `/boapi/proxy/geoloc/fleets/${FLEET_ID}/pois/${POI_ID}` ) {
231
231
  return Promise.resolve({
232
232
  data: {
233
233
  type: 'FeatureCollection',
@@ -262,7 +262,7 @@ describe('getStationById', () => {
262
262
  config: {}
263
263
  });
264
264
  }
265
- if (url.startsWith(`/boapi/proxy/geoloc/fleets/${FLEET_ID}/poi/`)) {
265
+ if (url.startsWith(`/boapi/proxy/geoloc/fleets/${FLEET_ID}/pois/`)) {
266
266
  return Promise.resolve({
267
267
  data: {
268
268
  type: 'FeatureCollection',
@@ -369,7 +369,7 @@ describe('getStationById', () => {
369
369
  expect(getMock).toBeCalledTimes(2);
370
370
  expect(getMock).toBeCalledWith(`/boapi/proxy/user/scheduledBooking/fleets/${FLEET_ID}/stations/${STATION_ID}`);
371
371
  expect(getMock).toBeCalledWith(
372
- `/boapi/proxy/geoloc/fleets/${FLEET_ID}/poi/${POI_ID}`,
372
+ `/boapi/proxy/geoloc/fleets/${FLEET_ID}/pois/${POI_ID}`,
373
373
  { headers: { accept: 'application/vnd.geo+json' } }
374
374
  );
375
375
  expectStation(station, STATION);
@@ -400,7 +400,7 @@ describe('getStationById', () => {
400
400
  expect(getMock).toBeCalledTimes(3);
401
401
  expect(getMock).toBeCalledWith(`/boapi/proxy/user/scheduledBooking/fleets/${FLEET_ID}/stations/${STATION_ID}`);
402
402
  expect(getMock).toBeCalledWith(
403
- `/boapi/proxy/geoloc/fleets/${FLEET_ID}/poi/${POI_ID}`,
403
+ `/boapi/proxy/geoloc/fleets/${FLEET_ID}/pois/${POI_ID}`,
404
404
  { headers: { accept: 'application/vnd.geo+json' } }
405
405
  );
406
406
  expect(getMock).toBeCalledWith(`/boapi/proxy/user/fleets/${FLEET_ID}/stations/details?showTimetable=false`);
package/src/getStation.ts CHANGED
@@ -66,7 +66,7 @@ export const getStationById = async (
66
66
  if (station && includes.includes('INFO')) {
67
67
  const poi = await client
68
68
  .get<{ features: any[] }>(
69
- `/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/poi/${station.poiId}`,
69
+ `/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/pois/${station.poiId}`,
70
70
  {
71
71
  headers: { accept: 'application/vnd.geo+json' },
72
72
  }
package/src/index.ts CHANGED
@@ -8,3 +8,5 @@ export { getStations } from './getStations';
8
8
  export type { Include } from './getStations';
9
9
  export { getStationById } from './getStation';
10
10
  export type { IncludeStation } from './getStation';
11
+ export { allocateVehicle } from './allocateVehicle';
12
+ export { deallocateVehicle } from './deallocateVehicle';