bcchapi 2.0.0 → 2.1.0

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/CHANGELOG.md CHANGED
@@ -6,17 +6,64 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
6
6
 
7
7
  ---
8
8
 
9
+ ## [2.1.0] - 2026-03-10
10
+
11
+
12
+ ### Added
13
+
14
+ - Add pluggable caching layer to Client (bcchapi/cache)
15
+
16
+
17
+ ### Changed
18
+
19
+ - Fix formatting
20
+
21
+
22
+ ---
23
+ ## [2.0.1] - 2026-03-10
24
+
25
+
26
+ ### Changed
27
+
28
+ - Release v2.0.1
29
+ - Rewrite CHANGELOG for v2.0.0 initial release
30
+ - Write README for bcchapi v2
31
+
32
+
33
+ ---
34
+ ## [2.0.0] - 2026-03-10
35
+
36
+
37
+ ### Changed
38
+
39
+ - Rename package to bcchapi and bump to v2.0.0
40
+
41
+
42
+ ### Fixed
43
+
44
+ - Update repository URLs to bcchapi after GitHub rename
45
+
46
+
47
+ ---
9
48
  ## [0.1.0] - 2026-03-10
10
49
 
11
50
 
12
51
  ### Added
13
52
 
53
+ - Wire up root src/index.ts re-exports and replace template test
14
54
  - Add date, transform, and stats utility functions
15
55
  - Add SERIES constants with curated well-known series IDs
16
56
  - Add Client, ApiError, and HttpError with full test coverage
17
57
 
18
58
 
19
- ---
59
+ ### Changed
60
+
61
+ - Release v0.1.0
62
+
63
+
64
+ ### Fixed
65
+
66
+ - Set publishConfig access to public for npm provenance
67
+
20
68
 
21
- [0.1.0]: https://github.com/airarrazaval/bcch/compare/v0.0.1...v0.1.0
22
- [Unreleased]: https://github.com/airarrazaval/bcch/compare/v0.1.0...HEAD
69
+ ---
package/README.md CHANGED
@@ -1,116 +1,191 @@
1
- # Node.js Library Template
1
+ # bcchapi
2
2
 
3
- A minimal, opinionated template for publishing Node.js libraries written in TypeScript.
3
+ Node.js wrapper for the [Banco Central de Chile REST API](https://si3.bcentral.cl/siete). Features a fully typed HTTP client, curated series ID constants, and utility functions for transforming and analysing macroeconomic observations.
4
4
 
5
- ## Features
5
+ ## Requirements
6
+
7
+ - Node.js >= 24.0.0
8
+
9
+ ## Installation
10
+
11
+ ```sh
12
+ npm install bcchapi
13
+ ```
14
+
15
+ ## Authentication
6
16
 
7
- - **TypeScript** with strict settings and `NodeNext` module resolution
8
- - **ESM-only** output (`"type": "module"`)
9
- - **Node.js 24+** target
10
- - **Testing** via Node.js built-in test runner (`node:test`) with [tsx](https://github.com/privatenumber/tsx) for TypeScript support
11
- - **Linting** with [oxlint](https://oxc.rs/docs/guide/usage/linter)
12
- - **Formatting** with [oxfmt](https://github.com/nicolo-ribaudo/oxfmt)
13
- - **Type declarations** and source maps included in the build output
14
- - **API documentation** generation with [TypeDoc](https://typedoc.org) and TSDoc comments
15
- - **Changelog** generation from [Conventional Commits](https://www.conventionalcommits.org) via [git-cliff](https://git-cliff.org)
16
- - **CI/CD** via GitHub Actions: automated checks on PRs and tag-triggered npm publishing with SLSA provenance
17
+ Register for free at [si3.bcentral.cl](https://si3.bcentral.cl/siete) to obtain API credentials (email + password).
17
18
 
18
- ## Getting Started
19
+ ## Usage
19
20
 
20
- 1. Click **Use this template** on GitHub to create a new repository.
21
- 2. Clone your new repo and install dependencies:
21
+ ### Fetch a time series
22
22
 
23
- ```sh
24
- npm install
25
- ```
23
+ ```ts
24
+ import { Client } from 'bcchapi/client';
25
+ import { SERIES } from 'bcchapi/series';
26
26
 
27
- 3. Replace the contents of [src/index.ts](src/index.ts) with your library code.
28
- 4. Update `name`, `version`, and `description` in [package.json](package.json).
29
- 5. Update the `exports` field in [package.json](package.json) if you need multiple entry points.
30
- 6. Add an `NPM_TOKEN` secret to your repository under **Settings → Secrets and variables → Actions**.
27
+ const client = new Client({ user: 'me@example.com', pass: 'secret' });
31
28
 
32
- ## Project Structure
29
+ const data = await client.getSeries(SERIES.PRICES.UF, {
30
+ firstdate: '2024-01-01',
31
+ lastdate: '2024-12-31',
32
+ });
33
33
 
34
- ```text
35
- src/ # Library source code
36
- tests/ # Test files (*.test.ts)
37
- dist/ # Compiled output (generated, not committed)
38
- tsconfig.json # TypeScript config for type-checking
39
- tsconfig.build.json # TypeScript config for compilation
34
+ console.log(data.descripIng); // "Unidad de Fomento (UF)"
35
+ console.log(data.observations); // [{ indexDateString, value, statusCode }, ...]
40
36
  ```
41
37
 
42
- ## Development
38
+ ### Transform observations
43
39
 
44
- Start the test watcher while you write code:
40
+ ```ts
41
+ import { toNumbers, toArrays, filterValid, mean, rollingMean } from 'bcchapi/utils';
45
42
 
46
- ```sh
47
- npm run dev
43
+ // Parse values to number | null (null for gaps)
44
+ const values = toNumbers(data.observations); // [37000.12, null, 37050.45, ...]
45
+
46
+ // Get parallel Date[] and (number | null)[] arrays
47
+ const { dates, values } = toArrays(data.observations);
48
+
49
+ // Filter out gap observations
50
+ const valid = filterValid(data.observations);
51
+
52
+ // Summary statistics (gaps are ignored)
53
+ const avg = mean(data.observations);
54
+
55
+ // 3-period rolling mean
56
+ const rolling = rollingMean(data.observations, 3);
48
57
  ```
49
58
 
50
- Before opening a pull request, verify everything passes:
59
+ ### Compute variations
51
60
 
52
- ```sh
53
- npm run typecheck && npm run lint && npm run format:check && npm test
61
+ ```ts
62
+ import { periodVariation, annualVariation } from 'bcchapi/utils';
63
+
64
+ // Month-over-month change
65
+ const mom = periodVariation(cpi.observations);
66
+
67
+ // 12-month change for monthly series
68
+ const yoy = annualVariation(cpi.observations, 12);
54
69
  ```
55
70
 
56
- ## Scripts
71
+ ### Search available series
72
+
73
+ ```ts
74
+ const monthlySeries = await client.searchSeries('MONTHLY');
75
+ console.log(monthlySeries.map((s) => s.englishTitle));
76
+ ```
57
77
 
58
- | Command | Description |
59
- | ----------------------- | -------------------------------------------------------------- |
60
- | `npm run dev` | Run tests in watch mode |
61
- | `npm run build` | Compile TypeScript to `dist/` |
62
- | `npm test` | Run tests |
63
- | `npm run test:coverage` | Run tests with coverage report |
64
- | `npm run typecheck` | Type-check without emitting files |
65
- | `npm run lint` | Lint source and tests |
66
- | `npm run lint:fix` | Lint and auto-fix issues |
67
- | `npm run format` | Format all files |
68
- | `npm run format:check` | Check formatting without modifying files |
69
- | `npm run clean` | Remove `dist/` and `docs/` |
70
- | `npm run docs` | Generate API documentation in `docs/` |
71
- | `npm run changelog` | Regenerate `CHANGELOG.md` from commits (used before releasing) |
78
+ ### Error handling
79
+
80
+ ```ts
81
+ import { ApiError, HttpError } from 'bcchapi/client';
82
+
83
+ try {
84
+ await client.getSeries('INVALID_ID');
85
+ } catch (err) {
86
+ if (err instanceof ApiError) {
87
+ // Non-zero Codigo in the API response body
88
+ console.error(`API error ${err.codigo}: ${err.descripcion}`);
89
+ } else if (err instanceof HttpError) {
90
+ // Non-ok HTTP status
91
+ console.error(`HTTP ${err.status}`);
92
+ } else {
93
+ // Network failure — original error available as err.cause
94
+ throw err;
95
+ }
96
+ }
97
+ ```
72
98
 
73
- ## GitHub Actions
99
+ ## API
74
100
 
75
- ### CI (`ci.yml`)
101
+ ### `bcchapi/client`
76
102
 
77
- Runs on every pull request and push to `main`:
103
+ #### `new Client(options)`
78
104
 
79
- 1. Verify package signatures (`npm audit signatures`)
80
- 2. Audit production dependencies for vulnerabilities (`npm audit --omit=dev`)
81
- 3. Typecheck
82
- 4. Lint
83
- 5. Format check
84
- 6. Test
85
- 7. Build
105
+ | Option | Type | Description |
106
+ | ------- | -------------- | ---------------------------------------------------------- |
107
+ | `user` | `string` | BCCH account email |
108
+ | `pass` | `string` | BCCH account password |
109
+ | `fetch` | `typeof fetch` | Custom fetch implementation (optional, useful for testing) |
86
110
 
87
- ### Publish (`publish.yml`)
111
+ #### `client.getSeries(seriesId, options?)`
88
112
 
89
- Runs automatically when a version tag (e.g. `v1.2.3`) is pushed. Runs `prepublishOnly`
90
- (typecheck → lint → clean → build) then publishes to npm with
91
- [SLSA provenance attestation](https://docs.npmjs.com/generating-provenance-statements).
113
+ Fetches observations for a single time series.
92
114
 
93
- **Do not run `npm publish` manually.** Use the release flow below instead.
115
+ | Parameter | Type | Description |
116
+ | ------------------- | -------- | ---------------------------------------------------------- |
117
+ | `seriesId` | `string` | BCCH series identifier |
118
+ | `options.firstdate` | `string` | Start date `"YYYY-MM-DD"` (defaults to earliest available) |
119
+ | `options.lastdate` | `string` | End date `"YYYY-MM-DD"` (defaults to most recent) |
94
120
 
95
- ## Releasing
121
+ Returns `Promise<SeriesData>`.
122
+
123
+ #### `client.searchSeries(frequency)`
124
+
125
+ Returns metadata for all series with the given frequency. `frequency` is one of `'DAILY' | 'MONTHLY' | 'QUARTERLY' | 'ANNUAL'`.
126
+
127
+ Returns `Promise<SeriesInfo[]>`.
128
+
129
+ ### `bcchapi/series`
130
+
131
+ `SERIES` is a nested `as const` object of curated series IDs grouped by domain:
132
+
133
+ | Group | Description |
134
+ | -------------------------- | ---------------------------------------------------- |
135
+ | `SERIES.EXCHANGE_RATE` | USD/CLP and major currency pairs |
136
+ | `SERIES.PRICES` | UF, UTM, IVP, CPI and components |
137
+ | `SERIES.INTEREST_RATES` | MPR, BCP/BCU sovereign bonds, PDBC rates |
138
+ | `SERIES.MONEY` | M1, M2, M3, bank loans by type |
139
+ | `SERIES.NATIONAL_ACCOUNTS` | Imacec and components |
140
+ | `SERIES.EXTERNAL_SECTOR` | Current account, exports, imports, FDI |
141
+ | `SERIES.EMPLOYMENT` | Unemployment rate, labour force, employed/unemployed |
142
+ | `SERIES.PUBLIC_FINANCES` | Government revenue, expenditure, fiscal balance |
143
+ | `SERIES.CAPITAL_MARKET` | IPSA, stock market capitalisation |
144
+
145
+ Use [si3.bcentral.cl](https://si3.bcentral.cl/siete) or `client.searchSeries()` to discover additional series IDs beyond the curated set.
146
+
147
+ ### `bcchapi/utils`
148
+
149
+ #### Transform functions
150
+
151
+ | Function | Description |
152
+ | ---------------------------------- | --------------------------------------------------------------------------- |
153
+ | `parseValue(value)` | Parses a value string to `number \| null` (`null` for empty or non-numeric) |
154
+ | `filterValid(observations)` | Returns only observations with parseable numeric values |
155
+ | `toNumbers(observations)` | Maps observations to `Array<number \| null>` |
156
+ | `toMap(observations)` | Returns a `Map<string, number \| null>` keyed by `indexDateString` |
157
+ | `toArrays(observations)` | Returns `{ dates: Date[], values: Array<number \| null> }` |
158
+ | `parseObservationDate(dateString)` | Parses `"DD-MM-YYYY"` to a UTC `Date` |
159
+ | `formatQueryDate(date)` | Formats a `Date` to `"YYYY-MM-DD"` for use in `getSeries` options |
160
+
161
+ #### Statistics functions
162
+
163
+ All stats functions operate on `Observation[]` and ignore gap values (empty or non-numeric).
164
+
165
+ | Function | Description |
166
+ | ----------------------------------------------- | ------------------------------------------------------------------------ |
167
+ | `mean(observations)` | Arithmetic mean |
168
+ | `stdDev(observations)` | Sample standard deviation (Bessel's correction) |
169
+ | `min(observations)` | Minimum value |
170
+ | `max(observations)` | Maximum value |
171
+ | `periodVariation(observations)` | Period-over-period fractional change (`value[i] / value[i-1] - 1`) |
172
+ | `annualVariation(observations, periodsPerYear)` | Year-over-year fractional change (`value[i] / value[i - n] - 1`) |
173
+ | `rollingMean(observations, window)` | Rolling mean over a fixed window; `null` if any value in window is a gap |
174
+
175
+ ## Releases
96
176
 
97
177
  ```sh
98
- # 1. Regenerate CHANGELOG.md from commits (auto-determines next version)
178
+ # 1. Regenerate CHANGELOG.md (auto-determines next version)
99
179
  npm run changelog
100
180
 
101
- # 2. Review CHANGELOG.md, update comparison links at the bottom, then commit
181
+ # 2. Commit and bump version
102
182
  git add CHANGELOG.md && git commit -m "chore: release vX.Y.Z"
103
-
104
- # 3. Bump version in package.json to match what git-cliff determined
105
183
  npm version patch # or minor / major
106
184
 
107
- # 4. Push — the publish workflow triggers automatically on the version tag
185
+ # 3. Push — the publish workflow triggers automatically on the version tag
108
186
  git push --follow-tags
109
187
  ```
110
188
 
111
- Only `dist/`, `README.md`, `CHANGELOG.md`, and `LICENSE` are included in the published
112
- package (see `files` in [package.json](package.json)).
113
-
114
- ## Requirements
189
+ ## License
115
190
 
116
- - Node.js >= 24.0.0
191
+ MIT
@@ -0,0 +1,4 @@
1
+ export type { Cache } from './types.js';
2
+ export { MemoryCache } from './memory-cache.js';
3
+ export type { MemoryCacheOptions } from './memory-cache.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { MemoryCache } from './memory-cache.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { Cache } from './types.js';
2
+ /**
3
+ * Options for {@link MemoryCache}.
4
+ */
5
+ export interface MemoryCacheOptions {
6
+ /**
7
+ * Default time-to-live in milliseconds applied to every `set` call that
8
+ * does not provide its own `ttlMs`.
9
+ *
10
+ * When omitted, entries never expire unless a per-entry `ttlMs` is passed
11
+ * to `set`.
12
+ *
13
+ * @defaultValue `undefined` (no expiry)
14
+ */
15
+ defaultTtlMs?: number;
16
+ }
17
+ /**
18
+ * In-memory {@link Cache} implementation backed by a `Map`.
19
+ *
20
+ * Expired entries are evicted lazily on `get` — no background timers are
21
+ * created. Suitable for single-process use; does not persist across restarts.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * import { Client } from 'bcchapi/client';
26
+ * import { MemoryCache } from 'bcchapi/cache';
27
+ *
28
+ * const client = new Client({
29
+ * user: 'me@example.com',
30
+ * pass: 'secret',
31
+ * cache: new MemoryCache({ defaultTtlMs: 60 * 60 * 1000 }), // 1 hour
32
+ * });
33
+ * ```
34
+ */
35
+ export declare class MemoryCache implements Cache {
36
+ private readonly store;
37
+ private readonly defaultTtlMs;
38
+ constructor(options?: MemoryCacheOptions);
39
+ get(key: string): unknown;
40
+ set(key: string, value: unknown, ttlMs?: number): void;
41
+ }
42
+ //# sourceMappingURL=memory-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-cache.d.ts","sourceRoot":"","sources":["../../src/cache/memory-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAOxC;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,WAAY,YAAW,KAAK;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA4B;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;gBAEtC,OAAO,CAAC,EAAE,kBAAkB;IAIxC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAYzB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;CAKvD"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * In-memory {@link Cache} implementation backed by a `Map`.
3
+ *
4
+ * Expired entries are evicted lazily on `get` — no background timers are
5
+ * created. Suitable for single-process use; does not persist across restarts.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { Client } from 'bcchapi/client';
10
+ * import { MemoryCache } from 'bcchapi/cache';
11
+ *
12
+ * const client = new Client({
13
+ * user: 'me@example.com',
14
+ * pass: 'secret',
15
+ * cache: new MemoryCache({ defaultTtlMs: 60 * 60 * 1000 }), // 1 hour
16
+ * });
17
+ * ```
18
+ */
19
+ export class MemoryCache {
20
+ store = new Map();
21
+ defaultTtlMs;
22
+ constructor(options) {
23
+ this.defaultTtlMs = options?.defaultTtlMs;
24
+ }
25
+ get(key) {
26
+ const entry = this.store.get(key);
27
+ if (entry === undefined) {
28
+ return undefined;
29
+ }
30
+ if (entry.expiresAt !== null && Date.now() > entry.expiresAt) {
31
+ this.store.delete(key);
32
+ return undefined;
33
+ }
34
+ return entry.value;
35
+ }
36
+ set(key, value, ttlMs) {
37
+ const effectiveTtl = ttlMs ?? this.defaultTtlMs;
38
+ const expiresAt = effectiveTtl !== undefined ? Date.now() + effectiveTtl : null;
39
+ this.store.set(key, { value, expiresAt });
40
+ }
41
+ }
42
+ //# sourceMappingURL=memory-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-cache.js","sourceRoot":"","sources":["../../src/cache/memory-cache.ts"],"names":[],"mappings":"AAuBA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,WAAW;IACL,KAAK,GAAG,IAAI,GAAG,EAAiB,CAAC;IACjC,YAAY,CAAqB;IAElD,YAAY,OAA4B;QACtC,IAAI,CAAC,YAAY,GAAG,OAAO,EAAE,YAAY,CAAC;IAC5C,CAAC;IAED,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YAC7D,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC;IACrB,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAc,EAAE,KAAc;QAC7C,MAAM,YAAY,GAAG,KAAK,IAAI,IAAI,CAAC,YAAY,CAAC;QAChD,MAAM,SAAS,GAAG,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;QAChF,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC5C,CAAC;CACF"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * A minimal cache interface for storing and retrieving API responses.
3
+ *
4
+ * Implement this interface to plug in any caching backend (in-memory, Redis,
5
+ * SQLite, etc.) into {@link https://github.com/airarrazaval/bcchapi | Client}.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import type { Cache } from 'bcchapi/cache';
10
+ * import { createClient } from 'redis';
11
+ *
12
+ * const redis = await createClient().connect();
13
+ *
14
+ * const redisCache: Cache = {
15
+ * get: async (key) => {
16
+ * const raw = await redis.get(key);
17
+ * return raw === null ? undefined : JSON.parse(raw);
18
+ * },
19
+ * set: async (key, value, ttlMs) => {
20
+ * const opts = ttlMs !== undefined ? { PX: ttlMs } : {};
21
+ * await redis.set(key, JSON.stringify(value), opts);
22
+ * },
23
+ * };
24
+ * ```
25
+ */
26
+ export interface Cache {
27
+ /**
28
+ * Returns the cached value for `key`, or `undefined` on a miss.
29
+ *
30
+ * @param key - Cache key.
31
+ * @returns The stored value, or `undefined` if the key is absent or expired.
32
+ */
33
+ get(key: string): unknown;
34
+ /**
35
+ * Stores `value` under `key` with an optional time-to-live.
36
+ *
37
+ * @param key - Cache key.
38
+ * @param value - Value to store.
39
+ * @param ttlMs - Optional time-to-live in milliseconds. Implementations may
40
+ * ignore this if TTL is managed externally (e.g. Redis `EXPIRE`).
41
+ */
42
+ set(key: string, value: unknown, ttlMs?: number): void;
43
+ }
44
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cache/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,WAAW,KAAK;IACpB;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAE1B;;;;;;;OAOG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cache/types.ts"],"names":[],"mappings":""}
@@ -17,6 +17,8 @@ export declare class Client {
17
17
  private readonly user;
18
18
  private readonly pass;
19
19
  private readonly fetch;
20
+ private readonly cache;
21
+ private readonly cacheTtlMs;
20
22
  constructor(options: ClientOptions);
21
23
  /**
22
24
  * Fetches observations for a single time series.
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,gBAAgB,EAEhB,UAAU,EACV,UAAU,EACX,MAAM,YAAY,CAAC;AAyCpB;;;;;;;;;;;;;GAaG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;gBAEpC,OAAO,EAAE,aAAa;IAMlC;;;;;;;;;;;;;;;;;;OAkBG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IA+BlF;;;;;;;;;;;;;;OAcG;IACG,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAuB/D,OAAO,CAAC,UAAU;YAOJ,OAAO;CAgBtB"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,aAAa,EACb,SAAS,EACT,gBAAgB,EAEhB,UAAU,EACV,UAAU,EACX,MAAM,YAAY,CAAC;AAyCpB;;;;;;;;;;;;;GAaG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;gBAEpC,OAAO,EAAE,aAAa;IAQlC;;;;;;;;;;;;;;;;;;OAkBG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IA2ClF;;;;;;;;;;;;;;OAcG;IACG,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAmC/D,OAAO,CAAC,UAAU;YAOJ,OAAO;CAgBtB"}
@@ -18,10 +18,14 @@ export class Client {
18
18
  user;
19
19
  pass;
20
20
  fetch;
21
+ cache;
22
+ cacheTtlMs;
21
23
  constructor(options) {
22
24
  this.user = options.user;
23
25
  this.pass = options.pass;
24
26
  this.fetch = options.fetch ?? globalThis.fetch;
27
+ this.cache = options.cache;
28
+ this.cacheTtlMs = options.cacheTtlMs;
25
29
  }
26
30
  /**
27
31
  * Fetches observations for a single time series.
@@ -43,6 +47,13 @@ export class Client {
43
47
  * ```
44
48
  */
45
49
  async getSeries(seriesId, options) {
50
+ const cacheKey = `getSeries:${seriesId}:${options?.firstdate ?? ''}:${options?.lastdate ?? ''}`;
51
+ if (this.cache !== undefined) {
52
+ const cached = this.cache.get(cacheKey);
53
+ if (cached !== undefined) {
54
+ return cached;
55
+ }
56
+ }
46
57
  const params = this.baseParams();
47
58
  params.set('function', 'GetSeries');
48
59
  params.set('timeseries', seriesId);
@@ -61,12 +72,14 @@ export class Client {
61
72
  value: obs.value,
62
73
  statusCode: obs.statusCode,
63
74
  }));
64
- return {
75
+ const result = {
65
76
  seriesId: raw.Series.seriesId,
66
77
  descripEsp: raw.Series.descripEsp,
67
78
  descripIng: raw.Series.descripIng,
68
79
  observations,
69
80
  };
81
+ this.cache?.set(cacheKey, result, this.cacheTtlMs);
82
+ return result;
70
83
  }
71
84
  /**
72
85
  * Searches for available series filtered by observation frequency.
@@ -84,6 +97,13 @@ export class Client {
84
97
  * ```
85
98
  */
86
99
  async searchSeries(frequency) {
100
+ const cacheKey = `searchSeries:${frequency}`;
101
+ if (this.cache !== undefined) {
102
+ const cached = this.cache.get(cacheKey);
103
+ if (cached !== undefined) {
104
+ return cached;
105
+ }
106
+ }
87
107
  const params = this.baseParams();
88
108
  params.set('function', 'SearchSeries');
89
109
  params.set('frequency', frequency);
@@ -91,7 +111,7 @@ export class Client {
91
111
  if (raw.Codigo !== 0) {
92
112
  throw new ApiError(`BCCH API error: ${raw.Descripcion}`, raw.Codigo, raw.Descripcion);
93
113
  }
94
- return (raw.SeriesInfos ?? []).map((info) => ({
114
+ const result = (raw.SeriesInfos ?? []).map((info) => ({
95
115
  seriesId: info.seriesId,
96
116
  frequencyCode: info.frequencyCode,
97
117
  spanishTitle: info.spanishTitle,
@@ -101,6 +121,8 @@ export class Client {
101
121
  updatedAt: info.updatedAt,
102
122
  createdAt: info.createdAt,
103
123
  }));
124
+ this.cache?.set(cacheKey, result, this.cacheTtlMs);
125
+ return result;
104
126
  }
105
127
  baseParams() {
106
128
  const params = new URLSearchParams();
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  export { Client } from './client.js';
2
2
  export { ApiError, HttpError } from './types.js';
3
- export type { ClientOptions, Frequency, GetSeriesOptions, Observation, SeriesData, SeriesInfo, } from './types.js';
3
+ export type { Cache, ClientOptions, Frequency, GetSeriesOptions, Observation, SeriesData, SeriesInfo, } from './types.js';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACjD,YAAY,EACV,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,UAAU,GACX,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACjD,YAAY,EACV,KAAK,EACL,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,UAAU,GACX,MAAM,YAAY,CAAC"}
@@ -1,3 +1,4 @@
1
+ import type { Cache } from '../cache/types.js';
1
2
  /**
2
3
  * Credentials and configuration for {@link Client}.
3
4
  */
@@ -15,7 +16,32 @@ export interface ClientOptions {
15
16
  * @defaultValue `globalThis.fetch`
16
17
  */
17
18
  fetch?: typeof globalThis.fetch;
19
+ /**
20
+ * Optional cache backend for storing API responses.
21
+ *
22
+ * Any object implementing the {@link Cache} interface is accepted — use
23
+ * `MemoryCache` from `bcchapi/cache` for a zero-config in-memory option,
24
+ * or provide your own adapter (Redis, SQLite, etc.).
25
+ *
26
+ * When omitted, every call makes a fresh HTTP request.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { MemoryCache } from 'bcchapi/cache';
31
+ * const client = new Client({ user, pass, cache: new MemoryCache() });
32
+ * ```
33
+ */
34
+ cache?: Cache;
35
+ /**
36
+ * Time-to-live in milliseconds passed to `cache.set` on every successful
37
+ * response. Applies to both `getSeries` and `searchSeries`.
38
+ *
39
+ * When omitted, `cache.set` is called without a TTL argument and expiry is
40
+ * determined by the cache implementation.
41
+ */
42
+ cacheTtlMs?: number;
18
43
  }
44
+ export type { Cache } from '../cache/types.js';
19
45
  /**
20
46
  * A single observation returned by the BCCH API.
21
47
  *
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IAEb,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,iDAAiD;IACjD,eAAe,EAAE,MAAM,CAAC;IAExB;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IAEjB,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IAEnB,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IAEnB,qDAAqD;IACrD,YAAY,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IAEjB,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;IAEtB,+BAA+B;IAC/B,YAAY,EAAE,MAAM,CAAC;IAErB,+BAA+B;IAC/B,YAAY,EAAE,MAAM,CAAC;IAErB,wEAAwE;IACxE,gBAAgB,EAAE,MAAM,CAAC;IAEzB,uEAAuE;IACvE,eAAe,EAAE,MAAM,CAAC;IAExB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAElB,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAMrE;;;;;;;;;;;;;GAaG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,kDAAkD;IAClD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;CAMjE;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,wBAAwB;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAK5C"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IAEb,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAEhC;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IAEd;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,YAAY,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,iDAAiD;IACjD,eAAe,EAAE,MAAM,CAAC;IAExB;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IAEjB,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IAEnB,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IAEnB,qDAAqD;IACrD,YAAY,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IAEjB,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;IAEtB,+BAA+B;IAC/B,YAAY,EAAE,MAAM,CAAC;IAErB,+BAA+B;IAC/B,YAAY,EAAE,MAAM,CAAC;IAErB,wEAAwE;IACxE,gBAAgB,EAAE,MAAM,CAAC;IAEzB,uEAAuE;IACvE,eAAe,EAAE,MAAM,CAAC;IAExB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAElB,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAMrE;;;;;;;;;;;;;GAaG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,kDAAkD;IAClD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;CAMjE;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,wBAAwB;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAK5C"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"AAoHA,8EAA8E;AAC9E,SAAS;AACT,8EAA8E;AAE9E;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,qDAAqD;IAC5C,MAAM,CAAS;IAExB,kDAAkD;IACzC,WAAW,CAAS;IAE7B,YAAY,OAAe,EAAE,MAAc,EAAE,WAAmB;QAC9D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;CACF;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,wBAAwB;IACf,MAAM,CAAS;IAExB,YAAY,OAAe,EAAE,MAAc;QACzC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"AAkJA,8EAA8E;AAC9E,SAAS;AACT,8EAA8E;AAE9E;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,qDAAqD;IAC5C,MAAM,CAAS;IAExB,kDAAkD;IACzC,WAAW,CAAS;IAE7B,YAAY,OAAe,EAAE,MAAc,EAAE,WAAmB;QAC9D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;CACF;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,wBAAwB;IACf,MAAM,CAAS;IAExB,YAAY,OAAe,EAAE,MAAc;QACzC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export { Client, ApiError, HttpError } from './client/index.js';
2
- export type { ClientOptions, Frequency, GetSeriesOptions, Observation, SeriesData, SeriesInfo, } from './client/index.js';
2
+ export type { Cache, ClientOptions, Frequency, GetSeriesOptions, Observation, SeriesData, SeriesInfo, } from './client/index.js';
3
+ export { MemoryCache } from './cache/index.js';
4
+ export type { MemoryCacheOptions } from './cache/index.js';
3
5
  export { SERIES } from './series/index.js';
4
6
  export { parseObservationDate, formatQueryDate, filterValid, parseValue, toArrays, toMap, toNumbers, annualVariation, max, mean, min, periodVariation, rollingMean, stdDev, } from './utils/index.js';
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAChE,YAAY,EACV,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,UAAU,GACX,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,UAAU,EACV,QAAQ,EACR,KAAK,EACL,SAAS,EACT,eAAe,EACf,GAAG,EACH,IAAI,EACJ,GAAG,EACH,eAAe,EACf,WAAW,EACX,MAAM,GACP,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAChE,YAAY,EACV,KAAK,EACL,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,UAAU,GACX,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,UAAU,EACV,QAAQ,EACR,KAAK,EACL,SAAS,EACT,eAAe,EACf,GAAG,EACH,IAAI,EACJ,GAAG,EACH,eAAe,EACf,WAAW,EACX,MAAM,GACP,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { Client, ApiError, HttpError } from './client/index.js';
2
+ export { MemoryCache } from './cache/index.js';
2
3
  export { SERIES } from './series/index.js';
3
4
  export { parseObservationDate, formatQueryDate, filterValid, parseValue, toArrays, toMap, toNumbers, annualVariation, max, mean, min, periodVariation, rollingMean, stdDev, } from './utils/index.js';
4
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAUhE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,UAAU,EACV,QAAQ,EACR,KAAK,EACL,SAAS,EACT,eAAe,EACf,GAAG,EACH,IAAI,EACJ,GAAG,EACH,eAAe,EACf,WAAW,EACX,MAAM,GACP,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAWhE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,UAAU,EACV,QAAQ,EACR,KAAK,EACL,SAAS,EACT,eAAe,EACf,GAAG,EACH,IAAI,EACJ,GAAG,EACH,eAAe,EACf,WAAW,EACX,MAAM,GACP,MAAM,kBAAkB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bcchapi",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Node.js wrapper for the Banco Central de Chile API. Features a fully typed API client and utility tools to streamline macroeconomic data integration.",
5
5
  "homepage": "https://github.com/airarrazaval/bcchapi#readme",
6
6
  "bugs": {
@@ -19,9 +19,6 @@
19
19
  ],
20
20
  "type": "module",
21
21
  "sideEffects": false,
22
- "publishConfig": {
23
- "access": "public"
24
- },
25
22
  "exports": {
26
23
  ".": {
27
24
  "types": "./dist/index.d.ts",
@@ -42,8 +39,16 @@
42
39
  "types": "./dist/utils/index.d.ts",
43
40
  "import": "./dist/utils/index.js",
44
41
  "default": "./dist/utils/index.js"
42
+ },
43
+ "./cache": {
44
+ "types": "./dist/cache/index.d.ts",
45
+ "import": "./dist/cache/index.js",
46
+ "default": "./dist/cache/index.js"
45
47
  }
46
48
  },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
47
52
  "scripts": {
48
53
  "build": "tsc -p tsconfig.build.json",
49
54
  "dev": "node --import tsx/esm --test --watch \"tests/**/*.test.ts\"",
@@ -62,7 +67,7 @@
62
67
  "devDependencies": {
63
68
  "@types/node": "^24.12.0",
64
69
  "git-cliff": "^2.12.0",
65
- "oxfmt": "^0.36.0",
70
+ "oxfmt": "^0.37.0",
66
71
  "oxlint": "^1.51.0",
67
72
  "tsx": "^4.21.0",
68
73
  "typedoc": "^0.28.17",
@@ -71,4 +76,4 @@
71
76
  "engines": {
72
77
  "node": ">=24.0.0"
73
78
  }
74
- }
79
+ }