1 | import { Client, createClientAsync } from 'soap';
|
2 | import { wsdlUrl, getSoapHeader, wsdlMethodMap } from './config';
|
3 | import './types/index';
|
4 |
|
5 | class NationalRailWrapper {
|
6 | private apiToken: ApiToken;
|
7 |
|
8 | private wsdlUrl: WsdlUrl;
|
9 |
|
10 | private soapHeader: SoapHeader;
|
11 |
|
12 | private soapClient: Client | undefined;
|
13 |
|
14 | public constructor(token: ApiToken) {
|
15 | this.apiToken = token;
|
16 | this.wsdlUrl = wsdlUrl;
|
17 | this.soapHeader = getSoapHeader(this.apiToken);
|
18 | }
|
19 |
|
20 | private async initClient(): Promise<void> {
|
21 | try {
|
22 | const client = await createClientAsync(this.wsdlUrl);
|
23 | client.addSoapHeader(this.soapHeader);
|
24 | this.soapClient = client;
|
25 | } catch (err) {
|
26 | throw new Error('An error occured trying to retrieve Soap Client');
|
27 | }
|
28 | }
|
29 |
|
30 | public async getDepartures(options: StationCallOptions): Promise<StationFormattedResponse> {
|
31 | const methodName = wsdlMethodMap.get('getDepartures');
|
32 | const filter = { ...this.parseStationOptions(options), filterType: 'to' };
|
33 |
|
34 | return this.invoke({ methodName, filter }) as Promise<StationFormattedResponse>;
|
35 | }
|
36 |
|
37 | public getArrivals(options: StationCallOptions): Promise<StationFormattedResponse> {
|
38 | const methodName = wsdlMethodMap.get('getArrivals');
|
39 | const filter = { ...this.parseStationOptions(options), filterType: 'from' };
|
40 |
|
41 | return this.invoke({ methodName, filter }) as Promise<StationFormattedResponse>;
|
42 | }
|
43 |
|
44 | public getAll(options: StationCallOptions): Promise<StationFormattedResponse> {
|
45 | const methodName = wsdlMethodMap.get('getAll');
|
46 | const filter = this.parseStationOptions(options);
|
47 |
|
48 | return this.invoke({ methodName, filter }) as Promise<StationFormattedResponse>;
|
49 | }
|
50 |
|
51 | public getServiceDetails({ serviceId }: ServiceCallInput): Promise<ServiceFormattedResponse> {
|
52 | const methodName = wsdlMethodMap.get('getServiceDetails');
|
53 | const filter = { serviceID: serviceId };
|
54 |
|
55 | return this.invoke({ methodName, filter }) as Promise<ServiceFormattedResponse>;
|
56 | }
|
57 |
|
58 | private parseStationOptions({ station, count = 10 }: StationCallOptions): FilterObject {
|
59 | const filter: FilterObject = {
|
60 | crs: station,
|
61 | };
|
62 |
|
63 | if (count) {
|
64 | filter.numRows = count;
|
65 | }
|
66 |
|
67 | return filter;
|
68 | }
|
69 |
|
70 | private async invoke({ methodName, filter }: InvokeCallInput): Promise<FormattedResponse> {
|
71 | if (!this.soapClient) {
|
72 | await this.initClient();
|
73 | }
|
74 |
|
75 | if (!methodName) {
|
76 | throw new Error(`Method with name '${methodName}' not found in WsdlMap`);
|
77 | }
|
78 |
|
79 | const response = this.soapClient && (await this.soapClient[methodName](filter));
|
80 |
|
81 | return this.formatResult(response);
|
82 | }
|
83 |
|
84 | private formatResult(response: ApiResponse): FormattedResponse {
|
85 | const [data] = response;
|
86 | let res = null;
|
87 |
|
88 | if (Object.prototype.hasOwnProperty.call(data, 'GetServiceDetailsResult')) {
|
89 | const { GetServiceDetailsResult: serviceData } = data as ApiServiceResult;
|
90 | res = serviceData;
|
91 | }
|
92 |
|
93 | if (Object.prototype.hasOwnProperty.call(data, 'GetStationBoardResult')) {
|
94 | const { GetStationBoardResult: stationData } = data as ApiStationResult;
|
95 | res = stationData.trainServices.service;
|
96 | }
|
97 |
|
98 | return {
|
99 | success: res !== null,
|
100 | data: res !== null ? res : [],
|
101 | };
|
102 | }
|
103 | }
|
104 |
|
105 | export { NationalRailWrapper };
|