bcchapi 1.0.1 → 1.0.3

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/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright 2024 Alfredo Irarrazaval
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -6,7 +6,7 @@ The Central Bank of Chile provides a web service that allows searching and extra
6
6
 
7
7
  The API currently supports only to functions: `GetSeries` (default) used for retrieveng historical data on a specific series, and `SearchSeries` used for searching series by frequency code (ie: daily, monthly, quearterly or yearly).
8
8
 
9
- For further information on how to use the API directly, please refer to the [official documentation](https://si3.bcentral.cl/estadisticas/Principal1/Web_Services/doc_en.htm).
9
+ For further information on how to use the API directly, please refer to the [official documentation](https://si3.bcentral.cl/estadisticas/Principal1/Web_Services/doc_en.htm). Usage of the API is subject to the restrictions defined in the [Terms and Conditions](https://si3.bcentral.cl/estadisticas/Principal1/Web_Services/index_BDE_TC.htm) of the Statistical Data Base API of the Central Bank of Chile. As of January of 2024, **the API allows up to 5 requests per second per user**.
10
10
 
11
11
  ## Installation
12
12
 
@@ -18,10 +18,10 @@ npm i -S bcchapi
18
18
 
19
19
  ```javascript
20
20
  // ESM
21
- import Client from 'bcchapi';
21
+ import { Client } from 'bcchapi';
22
22
 
23
23
  // CommonJS
24
- const Client = require('bcchapi');
24
+ const { Client } = require('bcchapi');
25
25
  ```
26
26
 
27
27
  ### Authentication
@@ -35,20 +35,20 @@ const client = new Client({
35
35
  });
36
36
  ```
37
37
 
38
-
39
38
  ### GetSeries
40
39
 
41
40
  Allows you to retrieve historic data series.
42
41
 
42
+ - Series Catalogue: [EN](https://si3.bcentral.cl/estadisticas/Principal1/Web_Services/Webservices/series_EN.xlsx) | [ES](https://si3.bcentral.cl/estadisticas/Principal1/Web_Services/Webservices/series.xlsx)
43
+
43
44
  #### Parameters
44
45
 
45
46
  | name | type | required | description | example |
46
- |--------|--------------------|----------|---------------------------------|------------------------|
47
+ | ------ | ------------------ | -------- | ------------------------------- | ---------------------- |
47
48
  | series | `string` | Yes | The series identifier | `'F072.EUR.USD.N.O.D'` |
48
49
  | since | `string` or `Date` | No | The starting date of the series | `'2020-12-01'` |
49
50
  | until | `string` or `Date` | No | The ending date of the series | `'2020-12-02'` |
50
51
 
51
-
52
52
  > **NOTE**: The API does not implements pagination, so if you need to retrieve a large amount of data, you should use the `since` and `until` parameters to split the request into smaller chunks.
53
53
 
54
54
  #### Example
@@ -63,7 +63,8 @@ const series = await client.getSeries({
63
63
  console.log(series);
64
64
  ```
65
65
 
66
- *Output*
66
+ _Output_
67
+
67
68
  ```js
68
69
  {
69
70
  seriesId: 'F072.EUR.USD.N.O.D',
@@ -77,26 +78,26 @@ console.log(series);
77
78
 
78
79
  ### SearchSeries
79
80
 
80
- Allows you to search for series by their frequency code (ie: daily, weekly, monthly, yearly).
81
+ Allows you to search for series by their frequency code (ie: daily, monthly, quarterly, yearly).
81
82
 
82
83
  #### Parameters
83
84
 
84
85
  | name | type | required | description | example |
85
- |-----------|----------|----------|--------------------------------------------------------------------------|-----------|
86
+ | --------- | -------- | -------- | ------------------------------------------------------------------------ | --------- |
86
87
  | frequency | `string` | Yes | The frequency code to search (`DAILY`, `MONTHLY`, `QUARTERLY`, `ANNUAL`) | `'DAILY'` |
87
88
 
88
-
89
89
  #### Example
90
90
 
91
91
  ```js
92
- import { Frequency } from 'bcchapi';
92
+ import { Frequency } from 'bcchapi';
93
93
 
94
94
  const result = await client.searchSeries({ frequency: Frequency.DAILY });
95
95
 
96
96
  console.log(result);
97
97
  ```
98
98
 
99
- *Output*
99
+ _Output_
100
+
100
101
  ```js
101
102
  [
102
103
  ...
@@ -121,4 +122,3 @@ console.log(result);
121
122
  ...
122
123
  ]
123
124
  ```
124
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bcchapi",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "API para acceder al Web Service del Banco Central de Chile.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/client.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import * as querystring from 'node:querystring';
2
2
  import * as assert from 'node:assert/strict';
3
3
  import { GetSeriesResponse, SearchSeriesResponse, ApiResponse } from './types';
4
- import { parseGetSeriesResponse, parseSearchSeriesResponse } from './helpers/parsers';
5
- import isValidDate from './helpers/is-valid-date';
4
+ import { isValidDate, parseGetSeriesResponse, parseSearchSeriesResponse } from './utils';
6
5
 
7
6
  export interface ClientConfig {
8
7
  /**
package/src/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- interface SeriesValue {
1
+ export interface SeriesObservation {
2
2
  /**
3
3
  * Series observed date in DD-MM-YYYY format.
4
4
  */
@@ -13,7 +13,7 @@ interface SeriesValue {
13
13
  statusCode: 'OK' | 'ND';
14
14
  }
15
15
 
16
- interface SeriesHistory {
16
+ export interface SeriesHistory {
17
17
  /**
18
18
  * Series identifier.
19
19
  */
@@ -29,14 +29,14 @@ interface SeriesHistory {
29
29
  /**
30
30
  * List of series observed values.
31
31
  */
32
- Obs: SeriesValue[];
32
+ Obs: SeriesObservation[];
33
33
  }
34
34
 
35
- type NullSeries = {
35
+ export type NullSeries = {
36
36
  [key in keyof SeriesHistory]: null;
37
37
  };
38
38
 
39
- interface SeriesMetadata {
39
+ export interface SeriesMetadata {
40
40
  /**
41
41
  * Series identifier.
42
42
  */
@@ -1,20 +1,49 @@
1
- import reverseDate from './reverse-date';
2
1
  import {
3
2
  ErrorCodes,
4
3
  InvalidFrequencyError,
5
4
  InvalidCredentialsError,
6
5
  InvalidSeriesError,
7
6
  WebServiceError,
8
- } from '../errors';
9
- import { ApiResponse, ErrorResponse, GetSeriesResponse, SearchSeriesResponse } from '../types';
7
+ } from './errors';
8
+ import {
9
+ ApiResponse,
10
+ SeriesObservation,
11
+ SeriesMetadata,
12
+ ErrorResponse,
13
+ GetSeriesResponse,
14
+ SearchSeriesResponse,
15
+ } from './types';
16
+
17
+ /**
18
+ * Determines wether a given value can be parsed to a valid date.
19
+ */
20
+ export function isValidDate(date: unknown): boolean {
21
+ if (typeof date === 'string') {
22
+ return !Number.isNaN(Date.parse(date));
23
+ }
24
+ if (date instanceof Date) {
25
+ return !Number.isNaN(date.getTime());
26
+ }
27
+ return false;
28
+ }
29
+
30
+ /**
31
+ * Reverses a date string from DD-MM-YYYY to YYYY-MM-DD format.
32
+ */
33
+ export function reverseDate(date: string): string {
34
+ return date.split('-').reverse().join('-');
35
+ }
10
36
 
37
+ /**
38
+ * Parses the GetSeries function API response.
39
+ */
11
40
  export function parseGetSeriesResponse<T extends ApiResponse>(response: T): GetSeriesResponse {
12
41
  if (response.Codigo !== 0) {
13
42
  switch (response.Codigo) {
14
43
  case ErrorCodes.InvalidCredentials:
15
- throw new InvalidCredentialsError();
44
+ throw new InvalidCredentialsError(response as ApiResponse as ErrorResponse);
16
45
  case ErrorCodes.InvalidSeries:
17
- throw new InvalidSeriesError();
46
+ throw new InvalidSeriesError(response as ApiResponse as ErrorResponse);
18
47
  default:
19
48
  throw new WebServiceError(response as ApiResponse as ErrorResponse);
20
49
  }
@@ -23,28 +52,31 @@ export function parseGetSeriesResponse<T extends ApiResponse>(response: T): GetS
23
52
  return {
24
53
  seriesId: response.Series.seriesId || '',
25
54
  description: response.Series.descripIng || '',
26
- data: (response.Series.Obs || []).map((obs) => ({
55
+ data: (response.Series.Obs || []).map((obs: SeriesObservation) => ({
27
56
  date: reverseDate(obs.indexDateString),
28
57
  value: parseFloat(obs.value),
29
58
  })),
30
59
  };
31
60
  }
32
61
 
62
+ /**
63
+ * Parses the SearchSeries function API response.
64
+ */
33
65
  export function parseSearchSeriesResponse<T extends ApiResponse>(
34
66
  response: T,
35
67
  ): SearchSeriesResponse {
36
68
  if (response.Codigo !== 0) {
37
69
  switch (response.Codigo) {
38
70
  case ErrorCodes.InvalidCredentials:
39
- throw new InvalidCredentialsError();
71
+ throw new InvalidCredentialsError(response as ApiResponse as ErrorResponse);
40
72
  case ErrorCodes.InvalidFrequency:
41
- throw new InvalidFrequencyError();
73
+ throw new InvalidFrequencyError(response as ApiResponse as ErrorResponse);
42
74
  default:
43
75
  throw new WebServiceError(response as ApiResponse as ErrorResponse);
44
76
  }
45
77
  }
46
78
 
47
- return response.SeriesInfos.map((series) => ({
79
+ return response.SeriesInfos.map((series: SeriesMetadata) => ({
48
80
  seriesId: series.seriesId,
49
81
  frequency: series.frequencyCode,
50
82
  title: series.englishTitle,
@@ -6,9 +6,9 @@ import {
6
6
  InvalidSeriesError,
7
7
  InvalidFrequencyError,
8
8
  } from '../src';
9
+ import { reverseDate } from '../src/utils';
9
10
  import fetchMock from './mocks/fetch.mock';
10
11
  import fixtures from './fixtures';
11
- import reverseDate from '../src/helpers/reverse-date';
12
12
 
13
13
  const fetchSpy = vi.spyOn(global, 'fetch').mockImplementation(fetchMock);
14
14
 
@@ -1,5 +1,5 @@
1
1
  import { Frequency } from '../../src/client';
2
- import reverseDate from '../../src/helpers/reverse-date';
2
+ import { reverseDate } from '../../src/utils';
3
3
  import fixtures from '../fixtures';
4
4
 
5
5
  export default (input: string | URL | Request) => {
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import isValidDate from '../../src/helpers/is-valid-date';
2
+ import { isValidDate } from '../../src/utils';
3
3
 
4
4
  describe('isValidDate', () => {
5
5
  it('should return true if the date is valid', () => {
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect } from 'vitest';
2
2
  import * as Errors from '../../src/errors';
3
- import { parseGetSeriesResponse } from '../../src/helpers/parsers';
3
+ import { parseGetSeriesResponse } from '../../src/utils';
4
4
  import { ApiResponse } from '../../src/types';
5
5
  import fixtures from '../fixtures';
6
6
 
@@ -1,7 +1,7 @@
1
1
  import { describe, it, expect } from 'vitest';
2
2
  import * as Errors from '../../src/errors';
3
3
  import { ApiResponse } from '../../src/types';
4
- import { parseSearchSeriesResponse } from '../../src/helpers/parsers';
4
+ import { parseSearchSeriesResponse } from '../../src/utils';
5
5
  import fixtures from '../fixtures';
6
6
 
7
7
  describe('parseSearchSeriesResponse', () => {
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import reverseDate from '../../src/helpers/reverse-date';
2
+ import { reverseDate } from '../../src/utils';
3
3
 
4
4
  describe('reverseDate', () => {
5
5
  it('should reverse correctly a date in DD-MM-YYYY format', () => {
@@ -1,9 +0,0 @@
1
- export default function isValidDate(date: unknown): boolean {
2
- if (typeof date === 'string') {
3
- return !Number.isNaN(Date.parse(date));
4
- }
5
- if (date instanceof Date) {
6
- return !Number.isNaN(date.getTime());
7
- }
8
- return false;
9
- }
@@ -1,3 +0,0 @@
1
- export default function reverseDate(date: string): string {
2
- return date.split('-').reverse().join('-');
3
- }