@vulog/aima-booking 1.1.87 → 1.1.89
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.d.mts +48 -44
- package/dist/index.d.ts +48 -44
- package/dist/index.js +106 -0
- package/dist/index.mjs +105 -0
- package/package.json +3 -3
- package/src/getStation.test.ts +411 -0
- package/src/getStation.ts +128 -0
- package/src/getStations.ts +2 -53
- package/src/index.ts +4 -2
- package/src/types.ts +54 -0
package/dist/index.d.mts
CHANGED
|
@@ -104,6 +104,47 @@ type SATBookingRequest = BaseBookingRequest & {
|
|
|
104
104
|
trip: any | null;
|
|
105
105
|
warning: string | null;
|
|
106
106
|
};
|
|
107
|
+
type GeoInfo = {
|
|
108
|
+
name: string;
|
|
109
|
+
coordinates: {
|
|
110
|
+
latitude: number;
|
|
111
|
+
longitude: number;
|
|
112
|
+
};
|
|
113
|
+
geoProperties: {
|
|
114
|
+
[key: string]: any;
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
type Service = {
|
|
118
|
+
id: string;
|
|
119
|
+
models: {
|
|
120
|
+
id: number;
|
|
121
|
+
vehicles: string[];
|
|
122
|
+
}[];
|
|
123
|
+
};
|
|
124
|
+
type ServiceInfo = {
|
|
125
|
+
services: Service[];
|
|
126
|
+
};
|
|
127
|
+
type Days = 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY' | 'SUNDAY';
|
|
128
|
+
type DayOpeningHours = {
|
|
129
|
+
id: number;
|
|
130
|
+
closed: boolean;
|
|
131
|
+
openAt: string;
|
|
132
|
+
closeAt: string;
|
|
133
|
+
};
|
|
134
|
+
type Timetable = Record<Days, DayOpeningHours[]>;
|
|
135
|
+
type OpeningHours = {
|
|
136
|
+
alwaysOpen: boolean;
|
|
137
|
+
timetable: Timetable;
|
|
138
|
+
};
|
|
139
|
+
type Station = Partial<GeoInfo> & Partial<ServiceInfo> & {
|
|
140
|
+
id: string;
|
|
141
|
+
zoneId: string;
|
|
142
|
+
poiId: string;
|
|
143
|
+
modificationDate: string;
|
|
144
|
+
fleetId: string;
|
|
145
|
+
openingHours?: OpeningHours;
|
|
146
|
+
[key: string]: any;
|
|
147
|
+
};
|
|
107
148
|
|
|
108
149
|
declare const BookingRequestStatusSchema: z.ZodEnum<["ALERT", "UPCOMING", "ONGOING", "COMPLETED", "CANCELLED", "PENDING_APPROVAL"]>;
|
|
109
150
|
type BookingRequestStatus = z.infer<typeof BookingRequestStatusSchema>;
|
|
@@ -146,49 +187,12 @@ declare const getBookingRequestById: (client: Client, id: string) => Promise<Boo
|
|
|
146
187
|
declare const getBookingRequestByTrip: (client: Client, tripId: string) => Promise<BookingRequest>;
|
|
147
188
|
declare const getSubscriptionBookingRequestById: (client: Client, id: string) => Promise<BookingRequest>;
|
|
148
189
|
|
|
149
|
-
declare const IncludeSchema: z.ZodEnum<["INFO", "OPEN_HOUR", "SERVICES"]>;
|
|
150
|
-
type Include = z.infer<typeof IncludeSchema>;
|
|
151
|
-
type Days = 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY' | 'SUNDAY';
|
|
152
|
-
type DayOpeningHours = {
|
|
153
|
-
id: number;
|
|
154
|
-
closed: boolean;
|
|
155
|
-
openAt: string;
|
|
156
|
-
closeAt: string;
|
|
157
|
-
};
|
|
158
|
-
type Timetable = Record<Days, DayOpeningHours[]>;
|
|
159
|
-
type OpeningHours = {
|
|
160
|
-
alwaysOpen: boolean;
|
|
161
|
-
timetable: Timetable;
|
|
162
|
-
};
|
|
163
|
-
type GeoInfo = {
|
|
164
|
-
name: string;
|
|
165
|
-
coordinates: {
|
|
166
|
-
latitude: number;
|
|
167
|
-
longitude: number;
|
|
168
|
-
};
|
|
169
|
-
geoProperties: {
|
|
170
|
-
[key: string]: any;
|
|
171
|
-
};
|
|
172
|
-
};
|
|
173
|
-
type Service = {
|
|
174
|
-
id: string;
|
|
175
|
-
models: {
|
|
176
|
-
id: number;
|
|
177
|
-
vehicles: string[];
|
|
178
|
-
}[];
|
|
179
|
-
};
|
|
180
|
-
type ServiceInfo = {
|
|
181
|
-
services: Service[];
|
|
182
|
-
};
|
|
183
|
-
type Station = Partial<GeoInfo> & Partial<ServiceInfo> & {
|
|
184
|
-
id: string;
|
|
185
|
-
zoneId: string;
|
|
186
|
-
poiId: string;
|
|
187
|
-
modificationDate: string;
|
|
188
|
-
fleetId: string;
|
|
189
|
-
openingHours?: OpeningHours;
|
|
190
|
-
[key: string]: any;
|
|
191
|
-
};
|
|
190
|
+
declare const IncludeSchema$1: z.ZodEnum<["INFO", "OPEN_HOUR", "SERVICES"]>;
|
|
191
|
+
type Include = z.infer<typeof IncludeSchema$1>;
|
|
192
192
|
declare const getStations: (client: Client, includes?: Include[]) => Promise<Station[]>;
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
declare const IncludeSchema: z.ZodEnum<["INFO", "SERVICES"]>;
|
|
195
|
+
type IncludeStation = z.infer<typeof IncludeSchema>;
|
|
196
|
+
declare const getStationById: (client: Client, id: string, includes?: IncludeStation[]) => Promise<Station | null>;
|
|
197
|
+
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -104,6 +104,47 @@ type SATBookingRequest = BaseBookingRequest & {
|
|
|
104
104
|
trip: any | null;
|
|
105
105
|
warning: string | null;
|
|
106
106
|
};
|
|
107
|
+
type GeoInfo = {
|
|
108
|
+
name: string;
|
|
109
|
+
coordinates: {
|
|
110
|
+
latitude: number;
|
|
111
|
+
longitude: number;
|
|
112
|
+
};
|
|
113
|
+
geoProperties: {
|
|
114
|
+
[key: string]: any;
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
type Service = {
|
|
118
|
+
id: string;
|
|
119
|
+
models: {
|
|
120
|
+
id: number;
|
|
121
|
+
vehicles: string[];
|
|
122
|
+
}[];
|
|
123
|
+
};
|
|
124
|
+
type ServiceInfo = {
|
|
125
|
+
services: Service[];
|
|
126
|
+
};
|
|
127
|
+
type Days = 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY' | 'SUNDAY';
|
|
128
|
+
type DayOpeningHours = {
|
|
129
|
+
id: number;
|
|
130
|
+
closed: boolean;
|
|
131
|
+
openAt: string;
|
|
132
|
+
closeAt: string;
|
|
133
|
+
};
|
|
134
|
+
type Timetable = Record<Days, DayOpeningHours[]>;
|
|
135
|
+
type OpeningHours = {
|
|
136
|
+
alwaysOpen: boolean;
|
|
137
|
+
timetable: Timetable;
|
|
138
|
+
};
|
|
139
|
+
type Station = Partial<GeoInfo> & Partial<ServiceInfo> & {
|
|
140
|
+
id: string;
|
|
141
|
+
zoneId: string;
|
|
142
|
+
poiId: string;
|
|
143
|
+
modificationDate: string;
|
|
144
|
+
fleetId: string;
|
|
145
|
+
openingHours?: OpeningHours;
|
|
146
|
+
[key: string]: any;
|
|
147
|
+
};
|
|
107
148
|
|
|
108
149
|
declare const BookingRequestStatusSchema: z.ZodEnum<["ALERT", "UPCOMING", "ONGOING", "COMPLETED", "CANCELLED", "PENDING_APPROVAL"]>;
|
|
109
150
|
type BookingRequestStatus = z.infer<typeof BookingRequestStatusSchema>;
|
|
@@ -146,49 +187,12 @@ declare const getBookingRequestById: (client: Client, id: string) => Promise<Boo
|
|
|
146
187
|
declare const getBookingRequestByTrip: (client: Client, tripId: string) => Promise<BookingRequest>;
|
|
147
188
|
declare const getSubscriptionBookingRequestById: (client: Client, id: string) => Promise<BookingRequest>;
|
|
148
189
|
|
|
149
|
-
declare const IncludeSchema: z.ZodEnum<["INFO", "OPEN_HOUR", "SERVICES"]>;
|
|
150
|
-
type Include = z.infer<typeof IncludeSchema>;
|
|
151
|
-
type Days = 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY' | 'SUNDAY';
|
|
152
|
-
type DayOpeningHours = {
|
|
153
|
-
id: number;
|
|
154
|
-
closed: boolean;
|
|
155
|
-
openAt: string;
|
|
156
|
-
closeAt: string;
|
|
157
|
-
};
|
|
158
|
-
type Timetable = Record<Days, DayOpeningHours[]>;
|
|
159
|
-
type OpeningHours = {
|
|
160
|
-
alwaysOpen: boolean;
|
|
161
|
-
timetable: Timetable;
|
|
162
|
-
};
|
|
163
|
-
type GeoInfo = {
|
|
164
|
-
name: string;
|
|
165
|
-
coordinates: {
|
|
166
|
-
latitude: number;
|
|
167
|
-
longitude: number;
|
|
168
|
-
};
|
|
169
|
-
geoProperties: {
|
|
170
|
-
[key: string]: any;
|
|
171
|
-
};
|
|
172
|
-
};
|
|
173
|
-
type Service = {
|
|
174
|
-
id: string;
|
|
175
|
-
models: {
|
|
176
|
-
id: number;
|
|
177
|
-
vehicles: string[];
|
|
178
|
-
}[];
|
|
179
|
-
};
|
|
180
|
-
type ServiceInfo = {
|
|
181
|
-
services: Service[];
|
|
182
|
-
};
|
|
183
|
-
type Station = Partial<GeoInfo> & Partial<ServiceInfo> & {
|
|
184
|
-
id: string;
|
|
185
|
-
zoneId: string;
|
|
186
|
-
poiId: string;
|
|
187
|
-
modificationDate: string;
|
|
188
|
-
fleetId: string;
|
|
189
|
-
openingHours?: OpeningHours;
|
|
190
|
-
[key: string]: any;
|
|
191
|
-
};
|
|
190
|
+
declare const IncludeSchema$1: z.ZodEnum<["INFO", "OPEN_HOUR", "SERVICES"]>;
|
|
191
|
+
type Include = z.infer<typeof IncludeSchema$1>;
|
|
192
192
|
declare const getStations: (client: Client, includes?: Include[]) => Promise<Station[]>;
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
declare const IncludeSchema: z.ZodEnum<["INFO", "SERVICES"]>;
|
|
195
|
+
type IncludeStation = z.infer<typeof IncludeSchema>;
|
|
196
|
+
declare const getStationById: (client: Client, id: string, includes?: IncludeStation[]) => Promise<Station | null>;
|
|
197
|
+
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ __export(index_exports, {
|
|
|
25
25
|
getBookingRequests: () => getBookingRequests,
|
|
26
26
|
getSATBookingRequests: () => getSATBookingRequests,
|
|
27
27
|
getScheduleBookingRequests: () => getScheduleBookingRequests,
|
|
28
|
+
getStationById: () => getStationById,
|
|
28
29
|
getStations: () => getStations,
|
|
29
30
|
getSubscriptionBookingRequestById: () => getSubscriptionBookingRequestById,
|
|
30
31
|
getSubscriptionBookingRequests: () => getSubscriptionBookingRequests
|
|
@@ -304,6 +305,110 @@ var getStations = async (client, includes = []) => {
|
|
|
304
305
|
}
|
|
305
306
|
return stations;
|
|
306
307
|
};
|
|
308
|
+
|
|
309
|
+
// src/getStation.ts
|
|
310
|
+
var import_zod5 = require("zod");
|
|
311
|
+
var IncludeSchema2 = import_zod5.z.enum(["INFO", "SERVICES"]);
|
|
312
|
+
var IncludesSchema2 = import_zod5.z.array(IncludeSchema2);
|
|
313
|
+
var getStationById = async (client, id, includes = []) => {
|
|
314
|
+
const resultIncludes = IncludesSchema2.safeParse(includes);
|
|
315
|
+
if (!resultIncludes.success) {
|
|
316
|
+
throw new TypeError("Invalid includes", {
|
|
317
|
+
cause: resultIncludes.error.issues
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
const station = await client.get(`/boapi/proxy/user/scheduledBooking/fleets/${client.clientOptions.fleetId}/stations/${id}`).then(({ data, status }) => {
|
|
321
|
+
if (status === 200) {
|
|
322
|
+
return Object.keys(data).reduce((acc, key) => {
|
|
323
|
+
if (key === "stationTimetableDTO") {
|
|
324
|
+
if (data.stationTimetableDTO?.stationId) {
|
|
325
|
+
acc.openingHours = {
|
|
326
|
+
alwaysOpen: data.stationTimetableDTO.alwaysOpen,
|
|
327
|
+
timetable: Object.keys(data.stationTimetableDTO.timetable).reduce(
|
|
328
|
+
(timetable, val) => {
|
|
329
|
+
timetable[val] = data.stationTimetableDTO.timetable[val].map(
|
|
330
|
+
(day) => ({
|
|
331
|
+
id: day.id,
|
|
332
|
+
closed: day.closed,
|
|
333
|
+
openAt: day.openAt,
|
|
334
|
+
closeAt: day.closeAt
|
|
335
|
+
})
|
|
336
|
+
);
|
|
337
|
+
return timetable;
|
|
338
|
+
},
|
|
339
|
+
{}
|
|
340
|
+
)
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
return acc;
|
|
344
|
+
}
|
|
345
|
+
acc[key] = data[key];
|
|
346
|
+
return acc;
|
|
347
|
+
}, {});
|
|
348
|
+
}
|
|
349
|
+
if (status === 400) {
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
return null;
|
|
353
|
+
}).catch((error) => {
|
|
354
|
+
if (error.formattedError?.status === 400) {
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
throw error;
|
|
358
|
+
});
|
|
359
|
+
if (station && includes.includes("INFO")) {
|
|
360
|
+
const poi = await client.get(
|
|
361
|
+
`/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/poi/${station.poiId}`,
|
|
362
|
+
{
|
|
363
|
+
headers: { accept: "application/vnd.geo+json" }
|
|
364
|
+
}
|
|
365
|
+
).then(
|
|
366
|
+
({ data }) => data.features.reduce(
|
|
367
|
+
(max, current) => {
|
|
368
|
+
if (current.properties.Version > max.version) {
|
|
369
|
+
const {
|
|
370
|
+
geometry: {
|
|
371
|
+
coordinates: [longitude, latitude]
|
|
372
|
+
},
|
|
373
|
+
properties
|
|
374
|
+
} = current;
|
|
375
|
+
return {
|
|
376
|
+
version: current.properties.Version,
|
|
377
|
+
name: properties.name,
|
|
378
|
+
coordinates: { latitude, longitude },
|
|
379
|
+
geoProperties: properties
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
return max;
|
|
383
|
+
},
|
|
384
|
+
{ version: -1 }
|
|
385
|
+
)
|
|
386
|
+
);
|
|
387
|
+
if (station.poiId && poi) {
|
|
388
|
+
poi.version = void 0;
|
|
389
|
+
Object.assign(station, poi);
|
|
390
|
+
station.name = station.geoProperties?.name;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
if (station && includes.includes("SERVICES")) {
|
|
394
|
+
const services = await client.get(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/stations/details?showTimetable=false`).then(
|
|
395
|
+
({ data }) => data.stations.reduce((acc, service) => {
|
|
396
|
+
if (!acc[service.station.id]) {
|
|
397
|
+
acc[service.station.id] = { services: [] };
|
|
398
|
+
}
|
|
399
|
+
acc[service.station.id].services.push({
|
|
400
|
+
id: service.serviceId,
|
|
401
|
+
models: service.station.models
|
|
402
|
+
});
|
|
403
|
+
return acc;
|
|
404
|
+
}, {})
|
|
405
|
+
);
|
|
406
|
+
if (services[station.id]) {
|
|
407
|
+
Object.assign(station, services[station.id]);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return station;
|
|
411
|
+
};
|
|
307
412
|
// Annotate the CommonJS export names for ESM import in node:
|
|
308
413
|
0 && (module.exports = {
|
|
309
414
|
getBookingRequestById,
|
|
@@ -311,6 +416,7 @@ var getStations = async (client, includes = []) => {
|
|
|
311
416
|
getBookingRequests,
|
|
312
417
|
getSATBookingRequests,
|
|
313
418
|
getScheduleBookingRequests,
|
|
419
|
+
getStationById,
|
|
314
420
|
getStations,
|
|
315
421
|
getSubscriptionBookingRequestById,
|
|
316
422
|
getSubscriptionBookingRequests
|
package/dist/index.mjs
CHANGED
|
@@ -271,12 +271,117 @@ var getStations = async (client, includes = []) => {
|
|
|
271
271
|
}
|
|
272
272
|
return stations;
|
|
273
273
|
};
|
|
274
|
+
|
|
275
|
+
// src/getStation.ts
|
|
276
|
+
import { z as z5 } from "zod";
|
|
277
|
+
var IncludeSchema2 = z5.enum(["INFO", "SERVICES"]);
|
|
278
|
+
var IncludesSchema2 = z5.array(IncludeSchema2);
|
|
279
|
+
var getStationById = async (client, id, includes = []) => {
|
|
280
|
+
const resultIncludes = IncludesSchema2.safeParse(includes);
|
|
281
|
+
if (!resultIncludes.success) {
|
|
282
|
+
throw new TypeError("Invalid includes", {
|
|
283
|
+
cause: resultIncludes.error.issues
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
const station = await client.get(`/boapi/proxy/user/scheduledBooking/fleets/${client.clientOptions.fleetId}/stations/${id}`).then(({ data, status }) => {
|
|
287
|
+
if (status === 200) {
|
|
288
|
+
return Object.keys(data).reduce((acc, key) => {
|
|
289
|
+
if (key === "stationTimetableDTO") {
|
|
290
|
+
if (data.stationTimetableDTO?.stationId) {
|
|
291
|
+
acc.openingHours = {
|
|
292
|
+
alwaysOpen: data.stationTimetableDTO.alwaysOpen,
|
|
293
|
+
timetable: Object.keys(data.stationTimetableDTO.timetable).reduce(
|
|
294
|
+
(timetable, val) => {
|
|
295
|
+
timetable[val] = data.stationTimetableDTO.timetable[val].map(
|
|
296
|
+
(day) => ({
|
|
297
|
+
id: day.id,
|
|
298
|
+
closed: day.closed,
|
|
299
|
+
openAt: day.openAt,
|
|
300
|
+
closeAt: day.closeAt
|
|
301
|
+
})
|
|
302
|
+
);
|
|
303
|
+
return timetable;
|
|
304
|
+
},
|
|
305
|
+
{}
|
|
306
|
+
)
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
return acc;
|
|
310
|
+
}
|
|
311
|
+
acc[key] = data[key];
|
|
312
|
+
return acc;
|
|
313
|
+
}, {});
|
|
314
|
+
}
|
|
315
|
+
if (status === 400) {
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
return null;
|
|
319
|
+
}).catch((error) => {
|
|
320
|
+
if (error.formattedError?.status === 400) {
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
throw error;
|
|
324
|
+
});
|
|
325
|
+
if (station && includes.includes("INFO")) {
|
|
326
|
+
const poi = await client.get(
|
|
327
|
+
`/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/poi/${station.poiId}`,
|
|
328
|
+
{
|
|
329
|
+
headers: { accept: "application/vnd.geo+json" }
|
|
330
|
+
}
|
|
331
|
+
).then(
|
|
332
|
+
({ data }) => data.features.reduce(
|
|
333
|
+
(max, current) => {
|
|
334
|
+
if (current.properties.Version > max.version) {
|
|
335
|
+
const {
|
|
336
|
+
geometry: {
|
|
337
|
+
coordinates: [longitude, latitude]
|
|
338
|
+
},
|
|
339
|
+
properties
|
|
340
|
+
} = current;
|
|
341
|
+
return {
|
|
342
|
+
version: current.properties.Version,
|
|
343
|
+
name: properties.name,
|
|
344
|
+
coordinates: { latitude, longitude },
|
|
345
|
+
geoProperties: properties
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
return max;
|
|
349
|
+
},
|
|
350
|
+
{ version: -1 }
|
|
351
|
+
)
|
|
352
|
+
);
|
|
353
|
+
if (station.poiId && poi) {
|
|
354
|
+
poi.version = void 0;
|
|
355
|
+
Object.assign(station, poi);
|
|
356
|
+
station.name = station.geoProperties?.name;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
if (station && includes.includes("SERVICES")) {
|
|
360
|
+
const services = await client.get(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/stations/details?showTimetable=false`).then(
|
|
361
|
+
({ data }) => data.stations.reduce((acc, service) => {
|
|
362
|
+
if (!acc[service.station.id]) {
|
|
363
|
+
acc[service.station.id] = { services: [] };
|
|
364
|
+
}
|
|
365
|
+
acc[service.station.id].services.push({
|
|
366
|
+
id: service.serviceId,
|
|
367
|
+
models: service.station.models
|
|
368
|
+
});
|
|
369
|
+
return acc;
|
|
370
|
+
}, {})
|
|
371
|
+
);
|
|
372
|
+
if (services[station.id]) {
|
|
373
|
+
Object.assign(station, services[station.id]);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return station;
|
|
377
|
+
};
|
|
274
378
|
export {
|
|
275
379
|
getBookingRequestById,
|
|
276
380
|
getBookingRequestByTrip,
|
|
277
381
|
getBookingRequests,
|
|
278
382
|
getSATBookingRequests,
|
|
279
383
|
getScheduleBookingRequests,
|
|
384
|
+
getStationById,
|
|
280
385
|
getStations,
|
|
281
386
|
getSubscriptionBookingRequestById,
|
|
282
387
|
getSubscriptionBookingRequests
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vulog/aima-booking",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.89",
|
|
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.
|
|
23
|
-
"@vulog/aima-core": "1.1.
|
|
22
|
+
"@vulog/aima-client": "1.1.89",
|
|
23
|
+
"@vulog/aima-core": "1.1.89"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"es-toolkit": "^1.39.9",
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { Client } from '@vulog/aima-client';
|
|
3
|
+
import { getStationById } from './getStation';
|
|
4
|
+
import { features } from 'process';
|
|
5
|
+
import { DayOpeningHours, Service, Station } from './types';
|
|
6
|
+
|
|
7
|
+
const FLEET_ID = 'FLEET_ID';
|
|
8
|
+
const STATION_ID: string = 'd7d70752-8cf5-4352-a420-33170785976e';
|
|
9
|
+
const POI_ID = '9967b01d3a46469896888b458904669e'
|
|
10
|
+
const STATION = {
|
|
11
|
+
id: STATION_ID,
|
|
12
|
+
zoneId: 'f40b8255b4b24e7cb7e5f28553e79c7e',
|
|
13
|
+
taxZoneId: null,
|
|
14
|
+
poiId: POI_ID,
|
|
15
|
+
modificationDate: '2024-09-23T07:19:12Z',
|
|
16
|
+
fleetId: FLEET_ID,
|
|
17
|
+
openTime: '00:00:00',
|
|
18
|
+
closeTime: '23:59:00',
|
|
19
|
+
stationTimetableDTO: {
|
|
20
|
+
stationId: STATION_ID,
|
|
21
|
+
fleetId: FLEET_ID,
|
|
22
|
+
alwaysOpen: false,
|
|
23
|
+
timetable: {
|
|
24
|
+
MONDAY: [
|
|
25
|
+
{
|
|
26
|
+
id: 10863,
|
|
27
|
+
openAt: '00:00',
|
|
28
|
+
closeAt: '23:59',
|
|
29
|
+
closed: false,
|
|
30
|
+
weekDay: 'MONDAY',
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
TUESDAY: [
|
|
34
|
+
{
|
|
35
|
+
id: 10866,
|
|
36
|
+
openAt: '00:00',
|
|
37
|
+
closeAt: '23:59',
|
|
38
|
+
closed: false,
|
|
39
|
+
weekDay: 'TUESDAY',
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
WEDNESDAY: [
|
|
43
|
+
{
|
|
44
|
+
id: 10869,
|
|
45
|
+
openAt: '00:00',
|
|
46
|
+
closeAt: '23:59',
|
|
47
|
+
closed: false,
|
|
48
|
+
weekDay: 'WEDNESDAY',
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
THURSDAY: [
|
|
52
|
+
{
|
|
53
|
+
id: 10872,
|
|
54
|
+
openAt: '00:00',
|
|
55
|
+
closeAt: '23:59',
|
|
56
|
+
closed: false,
|
|
57
|
+
weekDay: 'THURSDAY',
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
FRIDAY: [
|
|
61
|
+
{
|
|
62
|
+
id: 10875,
|
|
63
|
+
openAt: '00:00',
|
|
64
|
+
closeAt: '23:59',
|
|
65
|
+
closed: false,
|
|
66
|
+
weekDay: 'FRIDAY',
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
SATURDAY: [
|
|
70
|
+
{
|
|
71
|
+
id: 10878,
|
|
72
|
+
openAt: '00:00',
|
|
73
|
+
closeAt: '23:59',
|
|
74
|
+
closed: false,
|
|
75
|
+
weekDay: 'SATURDAY',
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
SUNDAY: [
|
|
79
|
+
{
|
|
80
|
+
id: 10881,
|
|
81
|
+
openAt: '00:00',
|
|
82
|
+
closeAt: '23:59',
|
|
83
|
+
closed: false,
|
|
84
|
+
weekDay: 'SUNDAY',
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
description: null,
|
|
90
|
+
maxAvailableSpots: 0,
|
|
91
|
+
};
|
|
92
|
+
const POI = {
|
|
93
|
+
type: 'Feature',
|
|
94
|
+
properties: {
|
|
95
|
+
name: 'Vulog HQ',
|
|
96
|
+
Version: 12,
|
|
97
|
+
type: 'scheduled_booking_station',
|
|
98
|
+
description: '',
|
|
99
|
+
address: 'av Simone Veil',
|
|
100
|
+
postal_code: '06000',
|
|
101
|
+
city: 'Nice',
|
|
102
|
+
capacity: 0
|
|
103
|
+
},
|
|
104
|
+
geometry: {
|
|
105
|
+
type: 'Point',
|
|
106
|
+
coordinates: [
|
|
107
|
+
-7.852491,
|
|
108
|
+
42.282294
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
const STATION_MODELS = {
|
|
113
|
+
station: {
|
|
114
|
+
id: STATION.id,
|
|
115
|
+
models: [
|
|
116
|
+
{ id: 1950, vehicles: [ '52d8c237-03a8-4b2d-bc66-f52a5d5c5119' ] },
|
|
117
|
+
{ id: 1981, vehicles: [ 'c20bc631-9943-444d-b025-b5cf78b68084' ] },
|
|
118
|
+
],
|
|
119
|
+
openTime: STATION.openTime,
|
|
120
|
+
closeTime: STATION.closeTime,
|
|
121
|
+
maxAvailableSpots: 0
|
|
122
|
+
},
|
|
123
|
+
serviceId: '55160733-334d-40fb-b80f-bad7080f90de',
|
|
124
|
+
stationTimetableDTO: {
|
|
125
|
+
stationId: null,
|
|
126
|
+
fleetId: null,
|
|
127
|
+
alwaysOpen: false,
|
|
128
|
+
timetable: null
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const expectStationTimeTableDay = (value: DayOpeningHours[] | undefined, expected: DayOpeningHours[]) => {
|
|
133
|
+
expect(value).not.toBeNull();
|
|
134
|
+
expect(value).not.toBeUndefined();
|
|
135
|
+
expect(value?.length).toEqual(expected.length);
|
|
136
|
+
if (value) {
|
|
137
|
+
expect(value[0]?.id).toEqual(expected[0].id);
|
|
138
|
+
expect(value[0].closed).toEqual(expected[0].closed);
|
|
139
|
+
expect(value[0].openAt).toEqual(expected[0].openAt);
|
|
140
|
+
expect(value[0].closeAt).toEqual(expected[0].closeAt);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const expectStation = (value: Station | null, expected: Station) => {
|
|
145
|
+
|
|
146
|
+
expect(value).not.toBeNull();
|
|
147
|
+
expect(value).not.toBeUndefined();
|
|
148
|
+
expect(value?.id).toEqual(expected.id);
|
|
149
|
+
expect(value?.zoneId).toEqual(expected.zoneId);
|
|
150
|
+
expect(value?.poiId).toEqual(expected.poiId);
|
|
151
|
+
expect(value?.modificationDate).toEqual(expected.modificationDate);
|
|
152
|
+
expect(value?.fleetId).toEqual(expected.fleetId);
|
|
153
|
+
expect(value?.openingHours).not.toBeNull();
|
|
154
|
+
expect(value?.openingHours?.alwaysOpen).toEqual(expected.stationTimetableDTO.alwaysOpen);
|
|
155
|
+
expect(value?.openingHours?.timetable).not.toBeNull();
|
|
156
|
+
expect(value?.openingHours?.timetable?.MONDAY).not.toBeNull();
|
|
157
|
+
expect(value?.openingHours?.timetable?.MONDAY.length).toEqual(expected.stationTimetableDTO.timetable.MONDAY.length);
|
|
158
|
+
expect(value?.openingHours?.timetable?.MONDAY[0].id).toEqual(expected.stationTimetableDTO.timetable.MONDAY[0].id);
|
|
159
|
+
expect(value?.openingHours?.timetable?.MONDAY[0].closed).toEqual(expected.stationTimetableDTO.timetable.MONDAY[0].closed);
|
|
160
|
+
expect(value?.openingHours?.timetable?.MONDAY[0].openAt).toEqual(expected.stationTimetableDTO.timetable.MONDAY[0].openAt);
|
|
161
|
+
expect(value?.openingHours?.timetable?.MONDAY[0].closeAt).toEqual(expected.stationTimetableDTO.timetable.MONDAY[0].closeAt);
|
|
162
|
+
expectStationTimeTableDay(value?.openingHours?.timetable?.TUESDAY, expected.stationTimetableDTO.timetable.TUESDAY);
|
|
163
|
+
expectStationTimeTableDay(value?.openingHours?.timetable?.WEDNESDAY, expected.stationTimetableDTO.timetable.WEDNESDAY);
|
|
164
|
+
expectStationTimeTableDay(value?.openingHours?.timetable?.THURSDAY, expected.stationTimetableDTO.timetable.THURSDAY);
|
|
165
|
+
expectStationTimeTableDay(value?.openingHours?.timetable?.FRIDAY, expected.stationTimetableDTO.timetable.FRIDAY);
|
|
166
|
+
expectStationTimeTableDay(value?.openingHours?.timetable?.SATURDAY, expected.stationTimetableDTO.timetable.SATURDAY);
|
|
167
|
+
expectStationTimeTableDay(value?.openingHours?.timetable?.SUNDAY, expected.stationTimetableDTO.timetable.SUNDAY);
|
|
168
|
+
}
|
|
169
|
+
const expectStationInfo = (value: Station | null, expectedPoi: any) => {
|
|
170
|
+
expect(value?.name).toEqual(expectedPoi.properties.name);
|
|
171
|
+
expect(value?.coordinates?.latitude).toEqual(expectedPoi.geometry.coordinates[1]);
|
|
172
|
+
expect(value?.coordinates?.longitude).toEqual(expectedPoi.geometry.coordinates[0]);
|
|
173
|
+
expect(value?.geoProperties?.Version).toEqual(expectedPoi.properties.Version);
|
|
174
|
+
expect(value?.geoProperties?.type).toEqual(expectedPoi.properties.type);
|
|
175
|
+
expect(value?.geoProperties?.description).toEqual(expectedPoi.properties.description);
|
|
176
|
+
expect(value?.geoProperties?.address).toEqual(expectedPoi.properties.address);
|
|
177
|
+
expect(value?.geoProperties?.postal_code).toEqual(expectedPoi.properties.postal_code);
|
|
178
|
+
expect(value?.geoProperties?.city).toEqual(expectedPoi.properties.city);
|
|
179
|
+
}
|
|
180
|
+
const expectStationServices = (value: Service[] | undefined, expectedStationModels: any) => {
|
|
181
|
+
expect(value).not.toBeUndefined();
|
|
182
|
+
expect(value?.length).toEqual(1);// 1 service for station ?
|
|
183
|
+
if (value) {
|
|
184
|
+
expect(value[0].id).toEqual(expectedStationModels.serviceId);
|
|
185
|
+
expect(value[0].models.length).toEqual(expectedStationModels.station.models.length);
|
|
186
|
+
expect(value[0].models[0].id).toEqual(expectedStationModels.station.models[0].id);
|
|
187
|
+
expect(value[0].models[0].vehicles.length).toEqual(expectedStationModels.station.models[0].vehicles.length);
|
|
188
|
+
expect(value[0].models[0].vehicles[0]).toEqual(expectedStationModels.station.models[0].vehicles[0]);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
describe('getStationById', () => {
|
|
193
|
+
const getMock = vi.fn();
|
|
194
|
+
const client = {
|
|
195
|
+
get: getMock,
|
|
196
|
+
clientOptions: {
|
|
197
|
+
fleetId: 'FLEET_ID',
|
|
198
|
+
},
|
|
199
|
+
} as unknown as Client;
|
|
200
|
+
|
|
201
|
+
beforeEach(() => {
|
|
202
|
+
getMock.mockReset();
|
|
203
|
+
vi.useFakeTimers({ now: new Date('2025-01-12T13:35:50.123Z') });
|
|
204
|
+
|
|
205
|
+
getMock.mockImplementation((url: string): Promise<any> => {
|
|
206
|
+
if (url === `/boapi/proxy/user/scheduledBooking/fleets/${FLEET_ID}/stations/${STATION_ID}`) {
|
|
207
|
+
return Promise.resolve({
|
|
208
|
+
data: STATION,
|
|
209
|
+
status: 200,
|
|
210
|
+
statusText: 'OK',
|
|
211
|
+
headers: {},
|
|
212
|
+
config: {}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
if (url.startsWith(`/boapi/proxy/user/scheduledBooking/fleets/${FLEET_ID}/stations/`)) {
|
|
216
|
+
return Promise.resolve({
|
|
217
|
+
data: {
|
|
218
|
+
status: 'BAD_REQUEST',
|
|
219
|
+
errorCode: 'BAD_REQUEST',
|
|
220
|
+
message: 'The provided input is not valid',
|
|
221
|
+
detail: null,
|
|
222
|
+
transactionId: '8c97dc753afc43098933a73bee34c327'
|
|
223
|
+
},
|
|
224
|
+
status: 400,
|
|
225
|
+
statusText: 'BAD REQUEST',
|
|
226
|
+
headers: {},
|
|
227
|
+
config: {}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
if (url === `/boapi/proxy/geoloc/fleets/${FLEET_ID}/poi/${POI_ID}` ) {
|
|
231
|
+
return Promise.resolve({
|
|
232
|
+
data: {
|
|
233
|
+
type: 'FeatureCollection',
|
|
234
|
+
features: [
|
|
235
|
+
{
|
|
236
|
+
type: 'Feature',
|
|
237
|
+
properties: {
|
|
238
|
+
name: 'Vulog Silo',
|
|
239
|
+
Version: 1,
|
|
240
|
+
type: 'scheduled_booking_station',
|
|
241
|
+
description: '',
|
|
242
|
+
address: '42 av Simone Veil',
|
|
243
|
+
postal_code: '06200',
|
|
244
|
+
city: 'NICE',
|
|
245
|
+
capacity: 0
|
|
246
|
+
},
|
|
247
|
+
geometry: {
|
|
248
|
+
type: 'Point',
|
|
249
|
+
coordinates: [
|
|
250
|
+
-7.85794,
|
|
251
|
+
42.28325
|
|
252
|
+
]
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
// more than 2 ... but it's OK for this test
|
|
256
|
+
POI,
|
|
257
|
+
]
|
|
258
|
+
},
|
|
259
|
+
status: 200,
|
|
260
|
+
statusText: 'OK',
|
|
261
|
+
headers: {},
|
|
262
|
+
config: {}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
if (url.startsWith(`/boapi/proxy/geoloc/fleets/${FLEET_ID}/poi/`)) {
|
|
266
|
+
return Promise.resolve({
|
|
267
|
+
data: {
|
|
268
|
+
type: 'FeatureCollection',
|
|
269
|
+
features: []
|
|
270
|
+
},
|
|
271
|
+
status: 200,
|
|
272
|
+
statusText: 'OK',
|
|
273
|
+
headers: {},
|
|
274
|
+
config: {}
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
if (url.startsWith(`/boapi/proxy/user/fleets/${FLEET_ID}/stations/details`)) {
|
|
278
|
+
return Promise.resolve({
|
|
279
|
+
data: {
|
|
280
|
+
stations:[
|
|
281
|
+
{
|
|
282
|
+
station: {
|
|
283
|
+
id: '404b6ea4-2004-421c-9304-84796b018975',
|
|
284
|
+
models: [],
|
|
285
|
+
openTime: '00:00:00',
|
|
286
|
+
closeTime: '23:59:00',
|
|
287
|
+
maxAvailableSpots: 0
|
|
288
|
+
},
|
|
289
|
+
serviceId: '66a91a3a-12dc-40bc-8750-440f0ea14fee',
|
|
290
|
+
stationTimetableDTO: {
|
|
291
|
+
stationId: null,
|
|
292
|
+
fleetId: null,
|
|
293
|
+
alwaysOpen: false,
|
|
294
|
+
timetable: null
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
STATION_MODELS,
|
|
298
|
+
{
|
|
299
|
+
station: {
|
|
300
|
+
id: '95095a04-afb7-49e7-b039-5da9750c8911',
|
|
301
|
+
models: [],
|
|
302
|
+
openTime: '07:00:00',
|
|
303
|
+
closeTime: '19:00:00',
|
|
304
|
+
maxAvailableSpots: 0
|
|
305
|
+
},
|
|
306
|
+
serviceId: '5f53f2ab-5af0-4ef5-8138-6a5b7698397d',
|
|
307
|
+
stationTimetableDTO: {
|
|
308
|
+
stationId: null,
|
|
309
|
+
fleetId: null,
|
|
310
|
+
alwaysOpen: false,
|
|
311
|
+
timetable: null
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
],
|
|
315
|
+
},
|
|
316
|
+
status: 200,
|
|
317
|
+
statusText: 'OK',
|
|
318
|
+
headers: {},
|
|
319
|
+
config: {}
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Pour les autres URLs, rejetez la promesse
|
|
325
|
+
return Promise.reject(new Error('404 Not Found'));
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
afterEach(() => {
|
|
330
|
+
vi.useRealTimers();
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
test('Fake includes', async () => {
|
|
334
|
+
const rejects = expect(() => getStationById(client, STATION_ID, ['FAKE'] as any)).rejects;
|
|
335
|
+
await rejects.toThrowError('Invalid includes');
|
|
336
|
+
await rejects.toSatisfy((error: any) => {
|
|
337
|
+
expect(error).toHaveProperty('cause');
|
|
338
|
+
expect(error.cause).toHaveLength(1);
|
|
339
|
+
expect(error.cause[0]).toHaveProperty('code');
|
|
340
|
+
expect(error.cause[0].code).toBe('invalid_enum_value');
|
|
341
|
+
return true;
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
test('station not found', async () => {
|
|
346
|
+
const station = await getStationById(client, 'FAKE_ID');
|
|
347
|
+
expect(getMock).toBeCalled();
|
|
348
|
+
expect(getMock).toBeCalledWith(`/boapi/proxy/user/scheduledBooking/fleets/${FLEET_ID}/stations/FAKE_ID`);
|
|
349
|
+
expect(station).toBeNull();
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
test('all OK', async () => {
|
|
353
|
+
const station: Station | null = await getStationById(client, STATION_ID, []);
|
|
354
|
+
expectStation(station, STATION);
|
|
355
|
+
expect(station?.name).toBeUndefined();
|
|
356
|
+
expect(station?.coordinates?.latitude).toBeUndefined();
|
|
357
|
+
expect(station?.coordinates?.longitude).toBeUndefined();
|
|
358
|
+
expect(station?.geoProperties?.Version).toBeUndefined();
|
|
359
|
+
expect(station?.geoProperties?.type).toBeUndefined();
|
|
360
|
+
expect(station?.geoProperties?.description).toBeUndefined();
|
|
361
|
+
expect(station?.geoProperties?.address).toBeUndefined();
|
|
362
|
+
expect(station?.geoProperties?.postal_code).toBeUndefined();
|
|
363
|
+
expect(station?.geoProperties?.city).toBeUndefined();
|
|
364
|
+
expect(station?.services).toBeUndefined();
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
test('all OK with INFO', async () => {
|
|
368
|
+
const station: Station | null = await getStationById(client, STATION_ID, ['INFO']);
|
|
369
|
+
expect(getMock).toBeCalledTimes(2);
|
|
370
|
+
expect(getMock).toBeCalledWith(`/boapi/proxy/user/scheduledBooking/fleets/${FLEET_ID}/stations/${STATION_ID}`);
|
|
371
|
+
expect(getMock).toBeCalledWith(
|
|
372
|
+
`/boapi/proxy/geoloc/fleets/${FLEET_ID}/poi/${POI_ID}`,
|
|
373
|
+
{ headers: { accept: 'application/vnd.geo+json' } }
|
|
374
|
+
);
|
|
375
|
+
expectStation(station, STATION);
|
|
376
|
+
expectStationInfo(station, POI);
|
|
377
|
+
expect(station?.services).toBeUndefined();
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
test('all OK with SERVICES', async () => {
|
|
381
|
+
const station: Station | null = await getStationById(client, STATION_ID, ['SERVICES']);
|
|
382
|
+
expect(getMock).toBeCalledTimes(2);
|
|
383
|
+
expect(getMock).toBeCalledWith(`/boapi/proxy/user/scheduledBooking/fleets/${FLEET_ID}/stations/${STATION_ID}`);
|
|
384
|
+
expect(getMock).toBeCalledWith(`/boapi/proxy/user/fleets/${FLEET_ID}/stations/details?showTimetable=false`);
|
|
385
|
+
expectStation(station, STATION);
|
|
386
|
+
expect(station?.name).toBeUndefined();
|
|
387
|
+
expect(station?.coordinates?.latitude).toBeUndefined();
|
|
388
|
+
expect(station?.coordinates?.longitude).toBeUndefined();
|
|
389
|
+
expect(station?.geoProperties?.Version).toBeUndefined();
|
|
390
|
+
expect(station?.geoProperties?.type).toBeUndefined();
|
|
391
|
+
expect(station?.geoProperties?.description).toBeUndefined();
|
|
392
|
+
expect(station?.geoProperties?.address).toBeUndefined();
|
|
393
|
+
expect(station?.geoProperties?.postal_code).toBeUndefined();
|
|
394
|
+
expect(station?.geoProperties?.city).toBeUndefined();
|
|
395
|
+
expectStationServices(station?.services, STATION_MODELS);
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
test('all OK with INFO SERVICE', async () => {
|
|
399
|
+
const station: Station | null = await getStationById(client, STATION_ID, ['INFO', 'SERVICES']);
|
|
400
|
+
expect(getMock).toBeCalledTimes(3);
|
|
401
|
+
expect(getMock).toBeCalledWith(`/boapi/proxy/user/scheduledBooking/fleets/${FLEET_ID}/stations/${STATION_ID}`);
|
|
402
|
+
expect(getMock).toBeCalledWith(
|
|
403
|
+
`/boapi/proxy/geoloc/fleets/${FLEET_ID}/poi/${POI_ID}`,
|
|
404
|
+
{ headers: { accept: 'application/vnd.geo+json' } }
|
|
405
|
+
);
|
|
406
|
+
expect(getMock).toBeCalledWith(`/boapi/proxy/user/fleets/${FLEET_ID}/stations/details?showTimetable=false`);
|
|
407
|
+
expectStation(station, STATION);
|
|
408
|
+
expectStationInfo(station, POI);
|
|
409
|
+
expectStationServices(station?.services, STATION_MODELS);
|
|
410
|
+
});
|
|
411
|
+
});
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Client } from '@vulog/aima-client';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
import { Days, ServiceInfo, Station, Timetable } from './types';
|
|
5
|
+
|
|
6
|
+
const IncludeSchema = z.enum(['INFO', 'SERVICES']);
|
|
7
|
+
const IncludesSchema = z.array(IncludeSchema);
|
|
8
|
+
export type IncludeStation = z.infer<typeof IncludeSchema>;
|
|
9
|
+
|
|
10
|
+
export const getStationById = async (
|
|
11
|
+
client: Client,
|
|
12
|
+
id: string,
|
|
13
|
+
includes: IncludeStation[] = []
|
|
14
|
+
): Promise<Station | null> => {
|
|
15
|
+
const resultIncludes = IncludesSchema.safeParse(includes);
|
|
16
|
+
if (!resultIncludes.success) {
|
|
17
|
+
throw new TypeError('Invalid includes', {
|
|
18
|
+
cause: resultIncludes.error.issues,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const station: Station | null = await client
|
|
23
|
+
.get<any>(`/boapi/proxy/user/scheduledBooking/fleets/${client.clientOptions.fleetId}/stations/${id}`)
|
|
24
|
+
.then(({ data, status }) => {
|
|
25
|
+
if (status === 200) {
|
|
26
|
+
return Object.keys(data).reduce<{ [key: string]: any }>((acc, key) => {
|
|
27
|
+
if (key === 'stationTimetableDTO') {
|
|
28
|
+
if (data.stationTimetableDTO?.stationId) {
|
|
29
|
+
acc.openingHours = {
|
|
30
|
+
alwaysOpen: data.stationTimetableDTO.alwaysOpen,
|
|
31
|
+
timetable: Object.keys(data.stationTimetableDTO.timetable).reduce<Timetable>(
|
|
32
|
+
(timetable, val) => {
|
|
33
|
+
// eslint-disable-next-line no-param-reassign
|
|
34
|
+
timetable[val as Days] = data.stationTimetableDTO.timetable[val].map(
|
|
35
|
+
(day: any) => ({
|
|
36
|
+
id: day.id,
|
|
37
|
+
closed: day.closed,
|
|
38
|
+
openAt: day.openAt,
|
|
39
|
+
closeAt: day.closeAt,
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
return timetable;
|
|
43
|
+
},
|
|
44
|
+
{} as Timetable
|
|
45
|
+
),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return acc;
|
|
49
|
+
}
|
|
50
|
+
acc[key] = data[key];
|
|
51
|
+
return acc;
|
|
52
|
+
}, {}) as Station;
|
|
53
|
+
}
|
|
54
|
+
if (status === 400) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
})
|
|
59
|
+
.catch((error) => {
|
|
60
|
+
if (error.formattedError?.status === 400) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
throw error;
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
if (station && includes.includes('INFO')) {
|
|
67
|
+
const poi = await client
|
|
68
|
+
.get<{ features: any[] }>(
|
|
69
|
+
`/boapi/proxy/geoloc/fleets/${client.clientOptions.fleetId}/poi/${station.poiId}`,
|
|
70
|
+
{
|
|
71
|
+
headers: { accept: 'application/vnd.geo+json' },
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
.then(({ data }) =>
|
|
75
|
+
data.features.reduce(
|
|
76
|
+
(max, current) => {
|
|
77
|
+
if (current.properties.Version > max.version) {
|
|
78
|
+
const {
|
|
79
|
+
geometry: {
|
|
80
|
+
coordinates: [longitude, latitude],
|
|
81
|
+
},
|
|
82
|
+
properties,
|
|
83
|
+
} = current;
|
|
84
|
+
return {
|
|
85
|
+
version: current.properties.Version,
|
|
86
|
+
name: properties.name,
|
|
87
|
+
coordinates: { latitude, longitude },
|
|
88
|
+
geoProperties: properties,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return max;
|
|
92
|
+
},
|
|
93
|
+
{ version: -1 }
|
|
94
|
+
)
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
if (station.poiId && poi) {
|
|
98
|
+
poi.version = undefined;
|
|
99
|
+
Object.assign(station, poi);
|
|
100
|
+
station.name = station.geoProperties?.name;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (station && includes.includes('SERVICES')) {
|
|
105
|
+
const services = await client
|
|
106
|
+
.get<{
|
|
107
|
+
stations: any[];
|
|
108
|
+
}>(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/stations/details?showTimetable=false`)
|
|
109
|
+
.then(({ data }) =>
|
|
110
|
+
data.stations.reduce<{ [key: string]: ServiceInfo }>((acc, service) => {
|
|
111
|
+
if (!acc[service.station.id]) {
|
|
112
|
+
acc[service.station.id] = { services: [] };
|
|
113
|
+
}
|
|
114
|
+
acc[service.station.id].services.push({
|
|
115
|
+
id: service.serviceId,
|
|
116
|
+
models: service.station.models,
|
|
117
|
+
});
|
|
118
|
+
return acc;
|
|
119
|
+
}, {})
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
if (services[station.id]) {
|
|
123
|
+
Object.assign(station, services[station.id]);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return station;
|
|
128
|
+
};
|
package/src/getStations.ts
CHANGED
|
@@ -1,63 +1,12 @@
|
|
|
1
1
|
import { Client } from '@vulog/aima-client';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
|
+
import { Days, GeoInfo, ServiceInfo, Station, Timetable } from './types';
|
|
5
|
+
|
|
4
6
|
const IncludeSchema = z.enum(['INFO', 'OPEN_HOUR', 'SERVICES']);
|
|
5
7
|
const IncludesSchema = z.array(IncludeSchema);
|
|
6
8
|
export type Include = z.infer<typeof IncludeSchema>;
|
|
7
9
|
|
|
8
|
-
export type Days = 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY' | 'SUNDAY';
|
|
9
|
-
|
|
10
|
-
export type DayOpeningHours = {
|
|
11
|
-
id: number;
|
|
12
|
-
closed: boolean;
|
|
13
|
-
openAt: string;
|
|
14
|
-
closeAt: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export type Timetable = Record<Days, DayOpeningHours[]>;
|
|
18
|
-
|
|
19
|
-
export type OpeningHours = {
|
|
20
|
-
alwaysOpen: boolean;
|
|
21
|
-
timetable: Timetable;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
type GeoInfo = {
|
|
25
|
-
name: string;
|
|
26
|
-
coordinates: {
|
|
27
|
-
latitude: number;
|
|
28
|
-
longitude: number;
|
|
29
|
-
};
|
|
30
|
-
geoProperties: { [key: string]: any };
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
type Service = {
|
|
34
|
-
id: string;
|
|
35
|
-
models: {
|
|
36
|
-
id: number;
|
|
37
|
-
vehicles: string[];
|
|
38
|
-
}[];
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
type ServiceInfo = {
|
|
42
|
-
services: Service[];
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export type Station = Partial<GeoInfo> &
|
|
46
|
-
Partial<ServiceInfo> & {
|
|
47
|
-
id: string;
|
|
48
|
-
zoneId: string;
|
|
49
|
-
poiId: string;
|
|
50
|
-
modificationDate: string;
|
|
51
|
-
fleetId: string;
|
|
52
|
-
openingHours?: OpeningHours;
|
|
53
|
-
// description: {
|
|
54
|
-
// fleetId: null;
|
|
55
|
-
// stationId: null;
|
|
56
|
-
// infos: [];
|
|
57
|
-
// };
|
|
58
|
-
[key: string]: any;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
10
|
export const getStations = async (client: Client, includes: Include[] = []): Promise<Station[]> => {
|
|
62
11
|
const resultIncludes = IncludesSchema.safeParse(includes);
|
|
63
12
|
if (!resultIncludes.success) {
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export { getBookingRequests, getScheduleBookingRequests, getSubscriptionBookingRequests } from './getBookingRequests';
|
|
2
2
|
export { getSATBookingRequests } from './getSATBookingRequests';
|
|
3
3
|
export { getBookingRequestById, getBookingRequestByTrip, getSubscriptionBookingRequestById } from './getBookingRequest';
|
|
4
|
-
export
|
|
4
|
+
export * from './types';
|
|
5
5
|
export type { BookingRequestStatus, ServiceType, BookingRequestFilters } from './getBookingRequests';
|
|
6
6
|
export type { SATBookingRequestStatus } from './getSATBookingRequests';
|
|
7
7
|
export { getStations } from './getStations';
|
|
8
|
-
export type {
|
|
8
|
+
export type { Include } from './getStations';
|
|
9
|
+
export { getStationById } from './getStation';
|
|
10
|
+
export type { IncludeStation } from './getStation';
|
package/src/types.ts
CHANGED
|
@@ -103,3 +103,57 @@ export type SATBookingRequest = BaseBookingRequest & {
|
|
|
103
103
|
trip: any | null;
|
|
104
104
|
warning: string | null;
|
|
105
105
|
};
|
|
106
|
+
|
|
107
|
+
// Station types
|
|
108
|
+
export type GeoInfo = {
|
|
109
|
+
name: string;
|
|
110
|
+
coordinates: {
|
|
111
|
+
latitude: number;
|
|
112
|
+
longitude: number;
|
|
113
|
+
};
|
|
114
|
+
geoProperties: { [key: string]: any };
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export type Service = {
|
|
118
|
+
id: string;
|
|
119
|
+
models: {
|
|
120
|
+
id: number;
|
|
121
|
+
vehicles: string[];
|
|
122
|
+
}[];
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export type ServiceInfo = {
|
|
126
|
+
services: Service[];
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export type Days = 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY' | 'SUNDAY';
|
|
130
|
+
|
|
131
|
+
export type DayOpeningHours = {
|
|
132
|
+
id: number;
|
|
133
|
+
closed: boolean;
|
|
134
|
+
openAt: string;
|
|
135
|
+
closeAt: string;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export type Timetable = Record<Days, DayOpeningHours[]>;
|
|
139
|
+
|
|
140
|
+
export type OpeningHours = {
|
|
141
|
+
alwaysOpen: boolean;
|
|
142
|
+
timetable: Timetable;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export type Station = Partial<GeoInfo> &
|
|
146
|
+
Partial<ServiceInfo> & {
|
|
147
|
+
id: string;
|
|
148
|
+
zoneId: string;
|
|
149
|
+
poiId: string;
|
|
150
|
+
modificationDate: string;
|
|
151
|
+
fleetId: string;
|
|
152
|
+
openingHours?: OpeningHours;
|
|
153
|
+
// description: {
|
|
154
|
+
// fleetId: null;
|
|
155
|
+
// stationId: null;
|
|
156
|
+
// infos: [];
|
|
157
|
+
// };
|
|
158
|
+
[key: string]: any;
|
|
159
|
+
};
|