bcchapi 1.0.0 → 1.0.1
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/.eslintignore +3 -0
- package/.eslintrc.json +21 -0
- package/.prettierrc.json +17 -0
- package/.vscode/extensions.json +3 -0
- package/.vscode/settings.json +4 -0
- package/dist/client.d.ts +50 -0
- package/dist/client.js +93 -0
- package/dist/errors.d.ts +21 -0
- package/dist/errors.js +37 -0
- package/dist/helpers/is-valid-date.d.ts +1 -0
- package/dist/helpers/is-valid-date.js +12 -0
- package/dist/helpers/parsers.d.ts +3 -0
- package/dist/helpers/parsers.js +51 -0
- package/dist/helpers/reverse-date.d.ts +1 -0
- package/dist/helpers/reverse-date.js +6 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +11 -0
- package/dist/types.d.ts +109 -0
- package/dist/types.js +2 -0
- package/package.json +10 -2
- package/src/client.ts +51 -52
- package/src/errors.ts +2 -2
- package/src/helpers/is-valid-date.ts +9 -0
- package/src/helpers/parsers.ts +56 -0
- package/src/helpers/reverse-date.ts +3 -0
- package/src/index.ts +8 -3
- package/src/types.ts +113 -0
- package/test/client.test.ts +89 -59
- package/test/fixtures/index.ts +1 -1
- package/test/fixtures/responses/credentials.invalid.json +1 -1
- package/test/fixtures/responses/getseries.invalid.json +1 -1
- package/test/fixtures/responses/getseries.success.json +1 -1
- package/test/fixtures/responses/searchseries.invalid.json +1 -1
- package/test/fixtures/responses/searchseries.success.json +13 -11
- package/test/{helpers.test.ts → helpers/is-valid-date.test.ts} +3 -12
- package/test/helpers/parse-get-series.test.ts +45 -0
- package/test/helpers/parse-search-series.test.ts +48 -0
- package/test/helpers/reverse-date.test.ts +11 -0
- package/test/mocks/fetch.mock.ts +18 -13
- package/tsconfig.eslint.json +5 -0
- package/tsconfig.json +1 -1
- package/src/helpers.ts +0 -13
- package/src/response.ts +0 -175
- package/test/response.test.ts +0 -71
package/test/mocks/fetch.mock.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Frequency } from '../../src/
|
|
2
|
-
import
|
|
1
|
+
import { Frequency } from '../../src/client';
|
|
2
|
+
import reverseDate from '../../src/helpers/reverse-date';
|
|
3
3
|
import fixtures from '../fixtures';
|
|
4
4
|
|
|
5
5
|
export default (input: string | URL | Request) => {
|
|
@@ -11,7 +11,7 @@ export default (input: string | URL | Request) => {
|
|
|
11
11
|
json: () => Promise.resolve(fixtures.response.credentialsInvalid),
|
|
12
12
|
} as Response);
|
|
13
13
|
}
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
if (func === 'GetSeries') {
|
|
16
16
|
if (fixtures.response.getSeriesSuccess.Series.seriesId !== params.get('timeseries')) {
|
|
17
17
|
return Promise.resolve({
|
|
@@ -21,15 +21,17 @@ export default (input: string | URL | Request) => {
|
|
|
21
21
|
|
|
22
22
|
const firstDate = params.get('firstdate');
|
|
23
23
|
const lastDate = params.get('lastdate');
|
|
24
|
-
const obs = fixtures.response.getSeriesSuccess.Series.Obs.filter((
|
|
24
|
+
const obs = fixtures.response.getSeriesSuccess.Series.Obs.filter((o) => {
|
|
25
25
|
if (firstDate && lastDate) {
|
|
26
|
-
return
|
|
26
|
+
return (
|
|
27
|
+
reverseDate(o.indexDateString) >= firstDate && reverseDate(o.indexDateString) <= lastDate
|
|
28
|
+
);
|
|
27
29
|
}
|
|
28
30
|
if (firstDate) {
|
|
29
|
-
return reverseDate(
|
|
31
|
+
return reverseDate(o.indexDateString) >= firstDate;
|
|
30
32
|
}
|
|
31
33
|
if (lastDate) {
|
|
32
|
-
return reverseDate(
|
|
34
|
+
return reverseDate(o.indexDateString) <= lastDate;
|
|
33
35
|
}
|
|
34
36
|
return true;
|
|
35
37
|
});
|
|
@@ -39,10 +41,11 @@ export default (input: string | URL | Request) => {
|
|
|
39
41
|
};
|
|
40
42
|
|
|
41
43
|
return Promise.resolve({
|
|
42
|
-
json: () =>
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
json: () =>
|
|
45
|
+
Promise.resolve({
|
|
46
|
+
...fixtures.response.getSeriesSuccess,
|
|
47
|
+
Series: series,
|
|
48
|
+
}),
|
|
46
49
|
} as Response);
|
|
47
50
|
}
|
|
48
51
|
|
|
@@ -57,7 +60,9 @@ export default (input: string | URL | Request) => {
|
|
|
57
60
|
|
|
58
61
|
const response = {
|
|
59
62
|
...fixtures.response.searchSeriesSuccess,
|
|
60
|
-
SeriesInfo: fixtures.response.searchSeriesSuccess.SeriesInfos.filter(
|
|
63
|
+
SeriesInfo: fixtures.response.searchSeriesSuccess.SeriesInfos.filter(
|
|
64
|
+
(series) => series.frequencyCode === frequency,
|
|
65
|
+
),
|
|
61
66
|
};
|
|
62
67
|
|
|
63
68
|
return Promise.resolve({
|
|
@@ -68,4 +73,4 @@ export default (input: string | URL | Request) => {
|
|
|
68
73
|
return Promise.resolve({
|
|
69
74
|
json: () => Promise.resolve({}),
|
|
70
75
|
} as Response);
|
|
71
|
-
}
|
|
76
|
+
};
|
package/tsconfig.json
CHANGED
package/src/helpers.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export function reverseDate(date: string): string {
|
|
2
|
-
return date.split('-').reverse().join('-');
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export function isValidDate(date: unknown): boolean {
|
|
6
|
-
if (typeof date === 'string') {
|
|
7
|
-
return !isNaN(Date.parse(date));
|
|
8
|
-
}
|
|
9
|
-
if (date instanceof Date) {
|
|
10
|
-
return !isNaN(date.getTime());
|
|
11
|
-
}
|
|
12
|
-
return false;
|
|
13
|
-
}
|
package/src/response.ts
DELETED
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ErrorCodes,
|
|
3
|
-
InvalidFrequencyError,
|
|
4
|
-
InvalidCredentialsError,
|
|
5
|
-
InvalidSeriesError,
|
|
6
|
-
WebServiceError,
|
|
7
|
-
} from './errors';
|
|
8
|
-
import { reverseDate } from './helpers';
|
|
9
|
-
|
|
10
|
-
export enum Frequency {
|
|
11
|
-
Daily = 'DAILY',
|
|
12
|
-
Monthly = 'MONTHLY',
|
|
13
|
-
Quarterly = 'QUARTERLY',
|
|
14
|
-
Annual = 'ANNUAL',
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface SeriesValue {
|
|
18
|
-
/**
|
|
19
|
-
* Series observed date in DD-MM-YYYY format.
|
|
20
|
-
*/
|
|
21
|
-
indexDateString: string;
|
|
22
|
-
/**
|
|
23
|
-
* Series observed value.
|
|
24
|
-
*/
|
|
25
|
-
value: string;
|
|
26
|
-
/**
|
|
27
|
-
* Series observed value status code (ND = no data recorded).
|
|
28
|
-
*/
|
|
29
|
-
statusCode: 'OK' | 'ND';
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
interface SeriesHistory {
|
|
33
|
-
/**
|
|
34
|
-
* Series identifier.
|
|
35
|
-
*/
|
|
36
|
-
seriesId: string;
|
|
37
|
-
/**
|
|
38
|
-
* Series name in Spanish.
|
|
39
|
-
*/
|
|
40
|
-
descripEsp: string;
|
|
41
|
-
/**
|
|
42
|
-
* Series name in English.
|
|
43
|
-
*/
|
|
44
|
-
descripIng: string;
|
|
45
|
-
/**
|
|
46
|
-
* List of series observed values.
|
|
47
|
-
*/
|
|
48
|
-
Obs: SeriesValue[];
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
interface SeriesMetadata {
|
|
52
|
-
/**
|
|
53
|
-
* Series identifier.
|
|
54
|
-
*/
|
|
55
|
-
seriesId: string;
|
|
56
|
-
/**
|
|
57
|
-
* Series frequency (DAILY, MONTHLY, QUARTERLY, ANNUAL).
|
|
58
|
-
*/
|
|
59
|
-
frequencyCode: Frequency;
|
|
60
|
-
/**
|
|
61
|
-
* Series name in Spanish.
|
|
62
|
-
*/
|
|
63
|
-
spanishTitle: string;
|
|
64
|
-
/**
|
|
65
|
-
* Series name in English.
|
|
66
|
-
*/
|
|
67
|
-
englishTitle: string;
|
|
68
|
-
/**
|
|
69
|
-
* Date of first observation in DD-MM-YYYY format.
|
|
70
|
-
*/
|
|
71
|
-
firstObservation: string;
|
|
72
|
-
/**
|
|
73
|
-
* Date of last observation in DD-MM-YYYY format.
|
|
74
|
-
*/
|
|
75
|
-
lastObservation: string;
|
|
76
|
-
/**
|
|
77
|
-
* Date of last update in DD-MM-YYYY format.
|
|
78
|
-
*/
|
|
79
|
-
updatedAt: string;
|
|
80
|
-
/**
|
|
81
|
-
* Date of creation in DD-MM-YYYY format.
|
|
82
|
-
*/
|
|
83
|
-
createdAt: string;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export interface ApiResponse {
|
|
87
|
-
/**
|
|
88
|
-
* Response status code.
|
|
89
|
-
*/
|
|
90
|
-
Codigo: number;
|
|
91
|
-
/**
|
|
92
|
-
* Response status message.
|
|
93
|
-
*/
|
|
94
|
-
Descripcion: string;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Series historic information.
|
|
98
|
-
*/
|
|
99
|
-
Series: SeriesHistory | {
|
|
100
|
-
[key in keyof SeriesHistory]: null;
|
|
101
|
-
};
|
|
102
|
-
/**
|
|
103
|
-
* Series metadata information.
|
|
104
|
-
*/
|
|
105
|
-
SeriesInfos: SeriesMetadata[];
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export interface ErrorResponse extends ApiResponse {
|
|
109
|
-
Series: {
|
|
110
|
-
[key in keyof SeriesHistory]: null;
|
|
111
|
-
};
|
|
112
|
-
SeriesInfos: never[];
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export type GetSeriesResponse = {
|
|
116
|
-
seriesId: string;
|
|
117
|
-
description: string;
|
|
118
|
-
data: ReadonlyArray<{ date: string; value: number; }>;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export type SearchSeriesResponse = ReadonlyArray<{
|
|
122
|
-
seriesId: string;
|
|
123
|
-
frequency: Frequency;
|
|
124
|
-
title: string;
|
|
125
|
-
firstObservedAt: string;
|
|
126
|
-
lastObservedAt: string;
|
|
127
|
-
updatedAt: string;
|
|
128
|
-
createdAt: string;
|
|
129
|
-
}>;
|
|
130
|
-
|
|
131
|
-
export function parseGetSeriesResponse<T extends ApiResponse>(response: T): GetSeriesResponse {
|
|
132
|
-
if (response.Codigo !== 0) {
|
|
133
|
-
switch (response.Codigo) {
|
|
134
|
-
case ErrorCodes.InvalidCredentials:
|
|
135
|
-
throw new InvalidCredentialsError();
|
|
136
|
-
case ErrorCodes.InvalidSeries:
|
|
137
|
-
throw new InvalidSeriesError();
|
|
138
|
-
default:
|
|
139
|
-
throw new WebServiceError(response as ApiResponse as ErrorResponse);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
seriesId: response.Series.seriesId || '',
|
|
145
|
-
description: response.Series.descripIng || '',
|
|
146
|
-
data: (response.Series.Obs || []).map((obs) => ({
|
|
147
|
-
date: reverseDate(obs.indexDateString),
|
|
148
|
-
value: parseFloat(obs.value),
|
|
149
|
-
})),
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export function parseSearchSeriesResponse<T extends ApiResponse>(response: T): SearchSeriesResponse {
|
|
154
|
-
if (response.Codigo !== 0) {
|
|
155
|
-
switch (response.Codigo) {
|
|
156
|
-
case ErrorCodes.InvalidCredentials:
|
|
157
|
-
throw new InvalidCredentialsError();
|
|
158
|
-
case ErrorCodes.InvalidFrequency:
|
|
159
|
-
throw new InvalidFrequencyError();
|
|
160
|
-
default:
|
|
161
|
-
throw new WebServiceError(response as ApiResponse as ErrorResponse);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
console.log(response);
|
|
165
|
-
|
|
166
|
-
return response.SeriesInfos.map((series) => ({
|
|
167
|
-
seriesId: series.seriesId,
|
|
168
|
-
frequency: series.frequencyCode,
|
|
169
|
-
title: series.englishTitle,
|
|
170
|
-
firstObservedAt: reverseDate(series.firstObservation),
|
|
171
|
-
lastObservedAt: reverseDate(series.lastObservation),
|
|
172
|
-
updatedAt: reverseDate(series.updatedAt),
|
|
173
|
-
createdAt: reverseDate(series.createdAt),
|
|
174
|
-
}));
|
|
175
|
-
}
|
package/test/response.test.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import * as Errors from '../src/errors';
|
|
3
|
-
import {
|
|
4
|
-
ApiResponse,
|
|
5
|
-
parseGetSeriesResponse,
|
|
6
|
-
parseSearchSeriesResponse,
|
|
7
|
-
} from '../src/response';
|
|
8
|
-
import fixtures from './fixtures';
|
|
9
|
-
|
|
10
|
-
describe('parseGetSeriesResponse', () => {
|
|
11
|
-
it('should parse correctly a valid response', () => {
|
|
12
|
-
const parsed = parseGetSeriesResponse(fixtures.response.getSeriesSuccess as unknown as ApiResponse);
|
|
13
|
-
|
|
14
|
-
expect(parsed).toBeDefined();
|
|
15
|
-
expect(parsed.seriesId).toBe(fixtures.response.getSeriesSuccess.Series.seriesId);
|
|
16
|
-
expect(parsed.description).toBe(fixtures.response.getSeriesSuccess.Series.descripIng);
|
|
17
|
-
expect(parsed.data).toHaveLength(fixtures.response.getSeriesSuccess.Series.Obs.length);
|
|
18
|
-
|
|
19
|
-
for (let i = 0; i < parsed.data.length; i += 1) {
|
|
20
|
-
expect(parsed.data[i].date).toMatch(/^\d{4}-\d{2}-\d{2}$/);
|
|
21
|
-
expect(parsed.data[i].value.toFixed(2)).toBe(fixtures.response.getSeriesSuccess.Series.Obs[i].value);
|
|
22
|
-
|
|
23
|
-
if (Number.isNaN(parsed.data[i].value)) {
|
|
24
|
-
expect(fixtures.response.getSeriesSuccess.Series.Obs[i].statusCode).toBe('ND');
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('should throw an InvalidCredentialsError if the response code is -5', () => {
|
|
30
|
-
expect(() => parseGetSeriesResponse(fixtures.response.credentialsInvalid as unknown as ApiResponse)).toThrow(Errors.InvalidCredentialsError);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('should throw an InvalidSeriesError if the response code is -50', () => {
|
|
34
|
-
expect(() => parseGetSeriesResponse(fixtures.response.getSeriesInvalid as unknown as ApiResponse)).toThrow(Errors.InvalidSeriesError);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('should throw a ResponseError if the response code is unknown', () => {
|
|
38
|
-
expect(() => parseGetSeriesResponse({} as ApiResponse)).toThrow(Errors.WebServiceError);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
describe('parseSearchSeriesResponse', () => {
|
|
43
|
-
it('should parse correctly a valid response', () => {
|
|
44
|
-
const parsed = parseSearchSeriesResponse(fixtures.response.searchSeriesSuccess as unknown as ApiResponse);
|
|
45
|
-
|
|
46
|
-
expect(parsed).toBeInstanceOf(Array);
|
|
47
|
-
expect(parsed).toHaveLength(fixtures.response.searchSeriesSuccess.SeriesInfos.length);
|
|
48
|
-
|
|
49
|
-
for (let i = 0; i < parsed.length; i += 1) {
|
|
50
|
-
expect(parsed[i].seriesId).toBe(fixtures.response.searchSeriesSuccess.SeriesInfos[i].seriesId);
|
|
51
|
-
expect(parsed[i].frequency).toBe(fixtures.response.searchSeriesSuccess.SeriesInfos[i].frequencyCode);
|
|
52
|
-
expect(parsed[i].title).toBe(fixtures.response.searchSeriesSuccess.SeriesInfos[i].englishTitle);
|
|
53
|
-
expect(parsed[i].firstObservedAt).toMatch(/^\d{4}-\d{2}-\d{2}$/);
|
|
54
|
-
expect(parsed[i].lastObservedAt).toMatch(/^\d{4}-\d{2}-\d{2}$/);
|
|
55
|
-
expect(parsed[i].updatedAt).toMatch(/^\d{4}-\d{2}-\d{2}$/);
|
|
56
|
-
expect(parsed[i].createdAt).toMatch(/^\d{4}-\d{2}-\d{2}$/);
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('should throw an InvalidCredentialsError if the response code is -5', () => {
|
|
61
|
-
expect(() => parseSearchSeriesResponse(fixtures.response.credentialsInvalid as unknown as ApiResponse)).toThrow(Errors.InvalidCredentialsError);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('should throw an InvalidFrequencyError if the response code is -1', () => {
|
|
65
|
-
expect(() => parseSearchSeriesResponse(fixtures.response.searchSeriesInvalid as unknown as ApiResponse)).toThrow(Errors.InvalidFrequencyError);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('should throw a ResponseError if the response code is unknown', () => {
|
|
69
|
-
expect(() => parseSearchSeriesResponse({} as ApiResponse)).toThrow(Errors.WebServiceError);
|
|
70
|
-
});
|
|
71
|
-
});
|