bharosa 0.3.2 → 0.4.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/ANALYTICS-CONTRACT-SHA256 +1 -0
- package/CHANGELOG.md +4 -0
- package/MONTHLY-MARKET-CONTRACT-SHA256 +1 -1
- package/README.md +9 -5
- package/dist/analytics-contract.cjs +665 -0
- package/dist/analytics-contract.d.cts +2 -0
- package/dist/analytics-contract.d.ts +2 -0
- package/dist/analytics-types.cjs +2 -0
- package/dist/analytics-types.d.cts +103 -0
- package/dist/analytics-types.d.ts +103 -0
- package/dist/client-types.d.cts +6 -1
- package/dist/client-types.d.ts +6 -1
- package/dist/index.cjs +41 -0
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/operation-types.d.cts +3 -0
- package/dist/operation-types.d.ts +3 -0
- package/dist/response-checks.cjs +67 -0
- package/dist/transport.cjs +7 -8
- package/dist/validate.cjs +3 -1
- package/docs/analytics.md +26 -0
- package/docs/getting-started.md +3 -3
- package/package.json +6 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ebab801a241565a3b115993b6ae8470d144f8d69f79cdb8acc274ff8c200cf3e
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
# 0.4.0 — unpublished release candidate
|
|
2
|
+
|
|
3
|
+
Add account-scoped Growth scheme performance and category return statistics. Change the default origin from published 0.3.2’s app.bharosa.finance to api.bharosa.finance, preserving explicit overrides. The reviewed host-default delta is included directly; no intermediate 0.3.3 publication is required. No investor monetary-performance, fund-AUM or stated-TER methods. API deployment and SDK publication are separate.
|
|
4
|
+
|
|
1
5
|
# Changelog
|
|
2
6
|
|
|
3
7
|
## 0.3.2 — 30 October 2026
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
29463b6a150e368a47ac11e2f8f841e3808d94d3ff9b70221fe3804c93b91004
|
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
A TypeScript client for Bharosa accounts, investors, portfolios, and mutual funds. Use one resource interface from TypeScript, ESM, or CommonJS, with no runtime dependencies.
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**Local release candidate (unpublished):** `bharosa@0.4.0`. Both clients use the production API at `https://api.bharosa.finance` by default. Account access and credentials are still required; installing the SDK does not grant access.
|
|
6
6
|
|
|
7
7
|
## Start here
|
|
8
8
|
|
|
9
|
-
Use Node.js 22.12+ in a supported LTS release. Install the
|
|
9
|
+
Use Node.js 22.12+ in a supported LTS release. Install the reviewed local candidate in your backend application:
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
|
-
npm install bharosa
|
|
12
|
+
npm install /absolute/path/to/bharosa-0.4.0.tgz --ignore-scripts
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Source contributors can build and pack a local archive using the commands in CONTRIBUTING.md.
|
|
@@ -119,8 +119,12 @@ After installing the archive, run `node node_modules/bharosa/examples/offline-sm
|
|
|
119
119
|
|
|
120
120
|
### Registered-app monthly data
|
|
121
121
|
|
|
122
|
-
Available in SDK 0.3.0 and activated at `https://
|
|
122
|
+
Available in SDK 0.3.0 and activated at `https://api.bharosa.finance`. Server applications can use `new BharosaMarket({apiKey})` with an owner-issued `market_key` scoped only to `market:read`. `client.schemes.nav(id,{asOf:'2026-08-01'})`, `schemes.expenseRatio`, `funds.portfolio` and `funds.holdings` use account-independent monthly snapshot routes. These keys cannot read private accounts or portfolios and require no investor OAuth token. Keep secrets server-side; never bundle them into browser code. Existing account-key and delegated-user clients remain unchanged. The production control-plane environment is `production`. General third-party OAuth provisioning is separate and is not enabled by this feature.
|
|
123
123
|
|
|
124
124
|
### Optional API origin override
|
|
125
125
|
|
|
126
|
-
Set `baseUrl` only for another deployment or tests. Omitted or `undefined` uses `https://
|
|
126
|
+
Set `baseUrl` only for another deployment or tests. Omitted or `undefined` uses `https://api.bharosa.finance`; invalid explicit values fail validation and never fall back. Overrides must be HTTPS origins without credentials, paths, queries or fragments. Local HTTP also requires `allowLocalhostHttp: true`. The SDK does not read `BHAROSA_API_BASE_URL` automatically.
|
|
127
|
+
|
|
128
|
+
## Growth performance and category returns
|
|
129
|
+
|
|
130
|
+
Adds `mutualFundSchemes.performance.retrieve` and `fundCategories.statistics.retrieve` for authenticated account access. See [analytics methods, coverage and limitations](docs/analytics.md). These API routes are deployed; this SDK candidate is not yet published. `BharosaMarket` retains its four monthly operations and cannot call account analytics.
|
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Generated from the reviewed analytics OpenAPI snapshot. Transport only.
|
|
3
|
+
module.exports = {
|
|
4
|
+
"operations": {
|
|
5
|
+
"analytics_scheme": {
|
|
6
|
+
"path": "/v1/accounts/{account}/market-data/schemes/{id}/performance",
|
|
7
|
+
"method": "GET",
|
|
8
|
+
"status": 200,
|
|
9
|
+
"marketData": true,
|
|
10
|
+
"readOnly": true,
|
|
11
|
+
"parameters": [
|
|
12
|
+
{
|
|
13
|
+
"name": "account",
|
|
14
|
+
"in": "path",
|
|
15
|
+
"required": true,
|
|
16
|
+
"schema": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"pattern": "^(me|acct_[a-f0-9]{32})$"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "id",
|
|
23
|
+
"in": "path",
|
|
24
|
+
"required": true,
|
|
25
|
+
"schema": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"pattern": "^[1-9][0-9]{0,18}$"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "as_of",
|
|
32
|
+
"in": "query",
|
|
33
|
+
"required": true,
|
|
34
|
+
"schema": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"format": "date",
|
|
37
|
+
"pattern": "^\\d{4}-\\d{2}-01$"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "periods",
|
|
42
|
+
"in": "query",
|
|
43
|
+
"required": false,
|
|
44
|
+
"schema": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"pattern": "^(1y|3y|5y|since_inception)(,(1y|3y|5y|since_inception)){0,3}$"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"response": {
|
|
51
|
+
"type": "object",
|
|
52
|
+
"properties": {
|
|
53
|
+
"methodology_version": {
|
|
54
|
+
"const": "ts-analytics-v1"
|
|
55
|
+
},
|
|
56
|
+
"requested_as_of": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"format": "date",
|
|
59
|
+
"pattern": "^\\d{4}-\\d{2}-01$"
|
|
60
|
+
},
|
|
61
|
+
"currency": {
|
|
62
|
+
"const": "INR"
|
|
63
|
+
},
|
|
64
|
+
"source_cutoff": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"format": "date",
|
|
67
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
|
|
68
|
+
},
|
|
69
|
+
"source_version": {
|
|
70
|
+
"type": "string"
|
|
71
|
+
},
|
|
72
|
+
"warnings": {
|
|
73
|
+
"type": "array",
|
|
74
|
+
"items": {
|
|
75
|
+
"type": "string"
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"object": {
|
|
79
|
+
"const": "scheme_performance"
|
|
80
|
+
},
|
|
81
|
+
"scheme_id": {
|
|
82
|
+
"type": "string"
|
|
83
|
+
},
|
|
84
|
+
"fund_id": {
|
|
85
|
+
"type": "string"
|
|
86
|
+
},
|
|
87
|
+
"plan": {
|
|
88
|
+
"type": "string"
|
|
89
|
+
},
|
|
90
|
+
"option": {
|
|
91
|
+
"type": "string"
|
|
92
|
+
},
|
|
93
|
+
"basis": {
|
|
94
|
+
"type": "string"
|
|
95
|
+
},
|
|
96
|
+
"periods": {
|
|
97
|
+
"type": "array",
|
|
98
|
+
"items": {
|
|
99
|
+
"type": "object",
|
|
100
|
+
"properties": {
|
|
101
|
+
"period": {
|
|
102
|
+
"enum": [
|
|
103
|
+
"1y",
|
|
104
|
+
"3y",
|
|
105
|
+
"5y",
|
|
106
|
+
"since_inception"
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
"requested_start": {
|
|
110
|
+
"anyOf": [
|
|
111
|
+
{
|
|
112
|
+
"type": "string",
|
|
113
|
+
"format": "date",
|
|
114
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"type": "null"
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
"requested_end": {
|
|
122
|
+
"type": "string",
|
|
123
|
+
"format": "date",
|
|
124
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
|
|
125
|
+
},
|
|
126
|
+
"status": {
|
|
127
|
+
"enum": [
|
|
128
|
+
"available",
|
|
129
|
+
"unavailable"
|
|
130
|
+
]
|
|
131
|
+
},
|
|
132
|
+
"reason": {
|
|
133
|
+
"anyOf": [
|
|
134
|
+
{
|
|
135
|
+
"type": "string"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"type": "null"
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
},
|
|
142
|
+
"total_return_pct": {
|
|
143
|
+
"anyOf": [
|
|
144
|
+
{
|
|
145
|
+
"type": "object",
|
|
146
|
+
"properties": {
|
|
147
|
+
"status": {
|
|
148
|
+
"const": "available"
|
|
149
|
+
},
|
|
150
|
+
"value": {
|
|
151
|
+
"type": "string",
|
|
152
|
+
"pattern": "^-?\\d+(\\.\\d{1,8})?$"
|
|
153
|
+
},
|
|
154
|
+
"reason": {
|
|
155
|
+
"type": "null"
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
"required": [
|
|
159
|
+
"status",
|
|
160
|
+
"value",
|
|
161
|
+
"reason"
|
|
162
|
+
],
|
|
163
|
+
"additionalProperties": true
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"type": "object",
|
|
167
|
+
"properties": {
|
|
168
|
+
"status": {
|
|
169
|
+
"const": "unavailable"
|
|
170
|
+
},
|
|
171
|
+
"value": {
|
|
172
|
+
"type": "null"
|
|
173
|
+
},
|
|
174
|
+
"reason": {
|
|
175
|
+
"type": "string"
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
"required": [
|
|
179
|
+
"status",
|
|
180
|
+
"value",
|
|
181
|
+
"reason"
|
|
182
|
+
],
|
|
183
|
+
"additionalProperties": true
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
},
|
|
187
|
+
"cagr_pct": {
|
|
188
|
+
"anyOf": [
|
|
189
|
+
{
|
|
190
|
+
"type": "object",
|
|
191
|
+
"properties": {
|
|
192
|
+
"status": {
|
|
193
|
+
"const": "available"
|
|
194
|
+
},
|
|
195
|
+
"value": {
|
|
196
|
+
"type": "string",
|
|
197
|
+
"pattern": "^-?\\d+(\\.\\d{1,8})?$"
|
|
198
|
+
},
|
|
199
|
+
"reason": {
|
|
200
|
+
"type": "null"
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
"required": [
|
|
204
|
+
"status",
|
|
205
|
+
"value",
|
|
206
|
+
"reason"
|
|
207
|
+
],
|
|
208
|
+
"additionalProperties": true
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"type": "object",
|
|
212
|
+
"properties": {
|
|
213
|
+
"status": {
|
|
214
|
+
"const": "unavailable"
|
|
215
|
+
},
|
|
216
|
+
"value": {
|
|
217
|
+
"type": "null"
|
|
218
|
+
},
|
|
219
|
+
"reason": {
|
|
220
|
+
"type": "string"
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
"required": [
|
|
224
|
+
"status",
|
|
225
|
+
"value",
|
|
226
|
+
"reason"
|
|
227
|
+
],
|
|
228
|
+
"additionalProperties": true
|
|
229
|
+
}
|
|
230
|
+
]
|
|
231
|
+
},
|
|
232
|
+
"start_observation_date": {
|
|
233
|
+
"anyOf": [
|
|
234
|
+
{
|
|
235
|
+
"type": "string",
|
|
236
|
+
"format": "date",
|
|
237
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"type": "null"
|
|
241
|
+
}
|
|
242
|
+
]
|
|
243
|
+
},
|
|
244
|
+
"end_observation_date": {
|
|
245
|
+
"anyOf": [
|
|
246
|
+
{
|
|
247
|
+
"type": "string",
|
|
248
|
+
"format": "date",
|
|
249
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"type": "null"
|
|
253
|
+
}
|
|
254
|
+
]
|
|
255
|
+
},
|
|
256
|
+
"start_nav": {
|
|
257
|
+
"anyOf": [
|
|
258
|
+
{
|
|
259
|
+
"type": "string"
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"type": "null"
|
|
263
|
+
}
|
|
264
|
+
]
|
|
265
|
+
},
|
|
266
|
+
"end_nav": {
|
|
267
|
+
"anyOf": [
|
|
268
|
+
{
|
|
269
|
+
"type": "string"
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"type": "null"
|
|
273
|
+
}
|
|
274
|
+
]
|
|
275
|
+
},
|
|
276
|
+
"start_lag_days": {
|
|
277
|
+
"anyOf": [
|
|
278
|
+
{
|
|
279
|
+
"type": "integer",
|
|
280
|
+
"minimum": 0
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"type": "null"
|
|
284
|
+
}
|
|
285
|
+
]
|
|
286
|
+
},
|
|
287
|
+
"end_lag_days": {
|
|
288
|
+
"anyOf": [
|
|
289
|
+
{
|
|
290
|
+
"type": "integer",
|
|
291
|
+
"minimum": 0
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
"type": "null"
|
|
295
|
+
}
|
|
296
|
+
]
|
|
297
|
+
},
|
|
298
|
+
"elapsed_days": {
|
|
299
|
+
"anyOf": [
|
|
300
|
+
{
|
|
301
|
+
"type": "number"
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
"type": "null"
|
|
305
|
+
}
|
|
306
|
+
]
|
|
307
|
+
},
|
|
308
|
+
"annualization_basis": {
|
|
309
|
+
"const": "observed_nav_dates_365_25"
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
"required": [
|
|
313
|
+
"period",
|
|
314
|
+
"requested_start",
|
|
315
|
+
"requested_end",
|
|
316
|
+
"status",
|
|
317
|
+
"reason",
|
|
318
|
+
"total_return_pct",
|
|
319
|
+
"cagr_pct",
|
|
320
|
+
"start_observation_date",
|
|
321
|
+
"end_observation_date",
|
|
322
|
+
"start_nav",
|
|
323
|
+
"end_nav",
|
|
324
|
+
"start_lag_days",
|
|
325
|
+
"end_lag_days",
|
|
326
|
+
"elapsed_days",
|
|
327
|
+
"annualization_basis"
|
|
328
|
+
],
|
|
329
|
+
"additionalProperties": true
|
|
330
|
+
},
|
|
331
|
+
"minItems": 1,
|
|
332
|
+
"maxItems": 4
|
|
333
|
+
}
|
|
334
|
+
},
|
|
335
|
+
"required": [
|
|
336
|
+
"methodology_version",
|
|
337
|
+
"requested_as_of",
|
|
338
|
+
"currency",
|
|
339
|
+
"source_cutoff",
|
|
340
|
+
"source_version",
|
|
341
|
+
"warnings",
|
|
342
|
+
"object",
|
|
343
|
+
"scheme_id",
|
|
344
|
+
"fund_id",
|
|
345
|
+
"plan",
|
|
346
|
+
"option",
|
|
347
|
+
"basis",
|
|
348
|
+
"periods"
|
|
349
|
+
],
|
|
350
|
+
"additionalProperties": true
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
"analytics_category": {
|
|
354
|
+
"path": "/v1/accounts/{account}/market-data/categories/{id}/statistics",
|
|
355
|
+
"method": "GET",
|
|
356
|
+
"status": 200,
|
|
357
|
+
"marketData": true,
|
|
358
|
+
"readOnly": true,
|
|
359
|
+
"parameters": [
|
|
360
|
+
{
|
|
361
|
+
"name": "account",
|
|
362
|
+
"in": "path",
|
|
363
|
+
"required": true,
|
|
364
|
+
"schema": {
|
|
365
|
+
"type": "string",
|
|
366
|
+
"pattern": "^(me|acct_[a-f0-9]{32})$"
|
|
367
|
+
}
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
"name": "id",
|
|
371
|
+
"in": "path",
|
|
372
|
+
"required": true,
|
|
373
|
+
"schema": {
|
|
374
|
+
"type": "string",
|
|
375
|
+
"minLength": 1,
|
|
376
|
+
"maxLength": 100
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
"name": "as_of",
|
|
381
|
+
"in": "query",
|
|
382
|
+
"required": true,
|
|
383
|
+
"schema": {
|
|
384
|
+
"type": "string",
|
|
385
|
+
"format": "date",
|
|
386
|
+
"pattern": "^\\d{4}-\\d{2}-01$"
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
"name": "periods",
|
|
391
|
+
"in": "query",
|
|
392
|
+
"required": false,
|
|
393
|
+
"schema": {
|
|
394
|
+
"type": "string",
|
|
395
|
+
"pattern": "^(1y|3y|5y|since_inception)(,(1y|3y|5y|since_inception)){0,3}$"
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
"name": "metrics",
|
|
400
|
+
"in": "query",
|
|
401
|
+
"required": false,
|
|
402
|
+
"schema": {
|
|
403
|
+
"type": "string",
|
|
404
|
+
"const": "return",
|
|
405
|
+
"default": "return"
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
"name": "plan",
|
|
410
|
+
"in": "query",
|
|
411
|
+
"required": false,
|
|
412
|
+
"schema": {
|
|
413
|
+
"enum": [
|
|
414
|
+
"direct",
|
|
415
|
+
"regular"
|
|
416
|
+
]
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
"name": "option",
|
|
421
|
+
"in": "query",
|
|
422
|
+
"required": false,
|
|
423
|
+
"schema": {
|
|
424
|
+
"const": "growth"
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
],
|
|
428
|
+
"response": {
|
|
429
|
+
"type": "object",
|
|
430
|
+
"properties": {
|
|
431
|
+
"methodology_version": {
|
|
432
|
+
"const": "ts-analytics-v1"
|
|
433
|
+
},
|
|
434
|
+
"requested_as_of": {
|
|
435
|
+
"type": "string",
|
|
436
|
+
"format": "date",
|
|
437
|
+
"pattern": "^\\d{4}-\\d{2}-01$"
|
|
438
|
+
},
|
|
439
|
+
"currency": {
|
|
440
|
+
"const": "INR"
|
|
441
|
+
},
|
|
442
|
+
"source_cutoff": {
|
|
443
|
+
"type": "string",
|
|
444
|
+
"format": "date",
|
|
445
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
|
|
446
|
+
},
|
|
447
|
+
"source_version": {
|
|
448
|
+
"type": "string"
|
|
449
|
+
},
|
|
450
|
+
"warnings": {
|
|
451
|
+
"type": "array",
|
|
452
|
+
"items": {
|
|
453
|
+
"type": "string"
|
|
454
|
+
}
|
|
455
|
+
},
|
|
456
|
+
"object": {
|
|
457
|
+
"const": "category_statistics"
|
|
458
|
+
},
|
|
459
|
+
"category": {
|
|
460
|
+
"type": "string"
|
|
461
|
+
},
|
|
462
|
+
"cohort": {
|
|
463
|
+
"type": "object",
|
|
464
|
+
"properties": {
|
|
465
|
+
"policy": {
|
|
466
|
+
"const": "current_classification_as_of_prices"
|
|
467
|
+
},
|
|
468
|
+
"plan": {
|
|
469
|
+
"enum": [
|
|
470
|
+
"direct",
|
|
471
|
+
"regular"
|
|
472
|
+
]
|
|
473
|
+
},
|
|
474
|
+
"option": {
|
|
475
|
+
"const": "growth"
|
|
476
|
+
},
|
|
477
|
+
"fund_count": {
|
|
478
|
+
"type": "integer",
|
|
479
|
+
"minimum": 0
|
|
480
|
+
},
|
|
481
|
+
"selected_scheme_count": {
|
|
482
|
+
"type": "integer",
|
|
483
|
+
"minimum": 0
|
|
484
|
+
},
|
|
485
|
+
"classification_date": {
|
|
486
|
+
"anyOf": [
|
|
487
|
+
{
|
|
488
|
+
"type": "string",
|
|
489
|
+
"format": "date",
|
|
490
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
"type": "null"
|
|
494
|
+
}
|
|
495
|
+
]
|
|
496
|
+
}
|
|
497
|
+
},
|
|
498
|
+
"required": [
|
|
499
|
+
"policy",
|
|
500
|
+
"plan",
|
|
501
|
+
"option",
|
|
502
|
+
"fund_count",
|
|
503
|
+
"selected_scheme_count",
|
|
504
|
+
"classification_date"
|
|
505
|
+
],
|
|
506
|
+
"additionalProperties": true
|
|
507
|
+
},
|
|
508
|
+
"metrics": {
|
|
509
|
+
"type": "object",
|
|
510
|
+
"additionalProperties": {
|
|
511
|
+
"anyOf": [
|
|
512
|
+
{
|
|
513
|
+
"type": "object",
|
|
514
|
+
"properties": {
|
|
515
|
+
"status": {
|
|
516
|
+
"const": "available"
|
|
517
|
+
},
|
|
518
|
+
"value": {
|
|
519
|
+
"type": "string",
|
|
520
|
+
"pattern": "^-?\\d+(\\.\\d{1,8})?$"
|
|
521
|
+
},
|
|
522
|
+
"reason": {
|
|
523
|
+
"type": "null"
|
|
524
|
+
},
|
|
525
|
+
"method": {
|
|
526
|
+
"const": "equal_weighted_arithmetic_mean"
|
|
527
|
+
},
|
|
528
|
+
"unit": {
|
|
529
|
+
"type": "string"
|
|
530
|
+
},
|
|
531
|
+
"eligible_count": {
|
|
532
|
+
"type": "integer",
|
|
533
|
+
"minimum": 0
|
|
534
|
+
},
|
|
535
|
+
"valid_count": {
|
|
536
|
+
"type": "integer",
|
|
537
|
+
"minimum": 0
|
|
538
|
+
},
|
|
539
|
+
"stale_count": {
|
|
540
|
+
"type": "integer",
|
|
541
|
+
"minimum": 0
|
|
542
|
+
},
|
|
543
|
+
"invalid_count": {
|
|
544
|
+
"type": "integer",
|
|
545
|
+
"minimum": 0
|
|
546
|
+
},
|
|
547
|
+
"missing_count": {
|
|
548
|
+
"type": "integer",
|
|
549
|
+
"minimum": 0
|
|
550
|
+
},
|
|
551
|
+
"coverage_pct": {
|
|
552
|
+
"type": "string",
|
|
553
|
+
"pattern": "^\\d+(\\.\\d+)?$"
|
|
554
|
+
},
|
|
555
|
+
"exclusions": {
|
|
556
|
+
"type": "object",
|
|
557
|
+
"additionalProperties": {
|
|
558
|
+
"type": "integer",
|
|
559
|
+
"minimum": 0
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
},
|
|
563
|
+
"required": [
|
|
564
|
+
"status",
|
|
565
|
+
"value",
|
|
566
|
+
"reason",
|
|
567
|
+
"method",
|
|
568
|
+
"unit",
|
|
569
|
+
"eligible_count",
|
|
570
|
+
"valid_count",
|
|
571
|
+
"stale_count",
|
|
572
|
+
"invalid_count",
|
|
573
|
+
"missing_count",
|
|
574
|
+
"coverage_pct",
|
|
575
|
+
"exclusions"
|
|
576
|
+
],
|
|
577
|
+
"additionalProperties": true
|
|
578
|
+
},
|
|
579
|
+
{
|
|
580
|
+
"type": "object",
|
|
581
|
+
"properties": {
|
|
582
|
+
"status": {
|
|
583
|
+
"const": "unavailable"
|
|
584
|
+
},
|
|
585
|
+
"value": {
|
|
586
|
+
"type": "null"
|
|
587
|
+
},
|
|
588
|
+
"reason": {
|
|
589
|
+
"type": "string"
|
|
590
|
+
},
|
|
591
|
+
"method": {
|
|
592
|
+
"const": "equal_weighted_arithmetic_mean"
|
|
593
|
+
},
|
|
594
|
+
"unit": {
|
|
595
|
+
"type": "string"
|
|
596
|
+
},
|
|
597
|
+
"eligible_count": {
|
|
598
|
+
"type": "integer",
|
|
599
|
+
"minimum": 0
|
|
600
|
+
},
|
|
601
|
+
"valid_count": {
|
|
602
|
+
"type": "integer",
|
|
603
|
+
"minimum": 0
|
|
604
|
+
},
|
|
605
|
+
"stale_count": {
|
|
606
|
+
"type": "integer",
|
|
607
|
+
"minimum": 0
|
|
608
|
+
},
|
|
609
|
+
"invalid_count": {
|
|
610
|
+
"type": "integer",
|
|
611
|
+
"minimum": 0
|
|
612
|
+
},
|
|
613
|
+
"missing_count": {
|
|
614
|
+
"type": "integer",
|
|
615
|
+
"minimum": 0
|
|
616
|
+
},
|
|
617
|
+
"coverage_pct": {
|
|
618
|
+
"type": "string",
|
|
619
|
+
"pattern": "^\\d+(\\.\\d+)?$"
|
|
620
|
+
},
|
|
621
|
+
"exclusions": {
|
|
622
|
+
"type": "object",
|
|
623
|
+
"additionalProperties": {
|
|
624
|
+
"type": "integer",
|
|
625
|
+
"minimum": 0
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
},
|
|
629
|
+
"required": [
|
|
630
|
+
"status",
|
|
631
|
+
"value",
|
|
632
|
+
"reason",
|
|
633
|
+
"method",
|
|
634
|
+
"unit",
|
|
635
|
+
"eligible_count",
|
|
636
|
+
"valid_count",
|
|
637
|
+
"stale_count",
|
|
638
|
+
"invalid_count",
|
|
639
|
+
"missing_count",
|
|
640
|
+
"coverage_pct",
|
|
641
|
+
"exclusions"
|
|
642
|
+
],
|
|
643
|
+
"additionalProperties": true
|
|
644
|
+
}
|
|
645
|
+
]
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
},
|
|
649
|
+
"required": [
|
|
650
|
+
"methodology_version",
|
|
651
|
+
"requested_as_of",
|
|
652
|
+
"currency",
|
|
653
|
+
"source_cutoff",
|
|
654
|
+
"source_version",
|
|
655
|
+
"warnings",
|
|
656
|
+
"object",
|
|
657
|
+
"category",
|
|
658
|
+
"cohort",
|
|
659
|
+
"metrics"
|
|
660
|
+
],
|
|
661
|
+
"additionalProperties": true
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { RequestOptions } from "./client-types.cjs";
|
|
2
|
+
export type AnalyticsPeriod = "1y" | "3y" | "5y" | "since_inception";
|
|
3
|
+
export type AnalyticsMetric = {
|
|
4
|
+
status: "available";
|
|
5
|
+
value: string;
|
|
6
|
+
reason: null;
|
|
7
|
+
} | {
|
|
8
|
+
status: "unavailable";
|
|
9
|
+
value: null;
|
|
10
|
+
reason: string;
|
|
11
|
+
};
|
|
12
|
+
export interface PerformanceSelection {
|
|
13
|
+
asOf: string;
|
|
14
|
+
periods?: AnalyticsPeriod[];
|
|
15
|
+
}
|
|
16
|
+
export interface AnalyticsEnvelope {
|
|
17
|
+
methodology_version: "ts-analytics-v1";
|
|
18
|
+
requested_as_of: string;
|
|
19
|
+
currency: "INR";
|
|
20
|
+
source_cutoff: string;
|
|
21
|
+
source_version: string;
|
|
22
|
+
warnings: string[];
|
|
23
|
+
}
|
|
24
|
+
export interface PerformancePeriod {
|
|
25
|
+
period: AnalyticsPeriod;
|
|
26
|
+
requested_start: string | null;
|
|
27
|
+
requested_end: string;
|
|
28
|
+
status: "available" | "unavailable";
|
|
29
|
+
reason: string | null;
|
|
30
|
+
total_return_pct: AnalyticsMetric;
|
|
31
|
+
cagr_pct: AnalyticsMetric;
|
|
32
|
+
}
|
|
33
|
+
export interface AnalyticsFreshnessPolicy {
|
|
34
|
+
nav_days: number;
|
|
35
|
+
aum_days: number;
|
|
36
|
+
ter_days: number;
|
|
37
|
+
category_min_funds: number;
|
|
38
|
+
category_min_coverage_pct: number;
|
|
39
|
+
}
|
|
40
|
+
export interface SchemePerformance extends AnalyticsEnvelope {
|
|
41
|
+
calculation_precision: "decimal_inputs_float64_returns";
|
|
42
|
+
freshness_policy: AnalyticsFreshnessPolicy;
|
|
43
|
+
available_history_start: string | null;
|
|
44
|
+
inception_basis: "verified_first_scheme_nav" | null;
|
|
45
|
+
scheme_nav_inception_date: string | null;
|
|
46
|
+
object: "scheme_performance";
|
|
47
|
+
scheme_id: string;
|
|
48
|
+
fund_id: string;
|
|
49
|
+
plan: string;
|
|
50
|
+
option: string;
|
|
51
|
+
basis: string;
|
|
52
|
+
periods: (PerformancePeriod & {
|
|
53
|
+
start_observation_date: string | null;
|
|
54
|
+
end_observation_date: string | null;
|
|
55
|
+
start_nav: string | null;
|
|
56
|
+
end_nav: string | null;
|
|
57
|
+
start_lag_days: number | null;
|
|
58
|
+
end_lag_days: number | null;
|
|
59
|
+
elapsed_days: number | null;
|
|
60
|
+
annualization_basis: "observed_nav_dates_365_25";
|
|
61
|
+
})[];
|
|
62
|
+
}
|
|
63
|
+
export interface CategorySelection {
|
|
64
|
+
asOf: string;
|
|
65
|
+
periods?: Exclude<AnalyticsPeriod, "since_inception">[];
|
|
66
|
+
metrics?: "return"[];
|
|
67
|
+
plan?: "direct" | "regular";
|
|
68
|
+
option?: "growth";
|
|
69
|
+
}
|
|
70
|
+
export interface CategoryStatistics extends AnalyticsEnvelope {
|
|
71
|
+
freshness_policy: AnalyticsFreshnessPolicy;
|
|
72
|
+
object: "category_statistics";
|
|
73
|
+
category: string;
|
|
74
|
+
cohort: {
|
|
75
|
+
policy: "current_classification_as_of_prices";
|
|
76
|
+
plan: "direct" | "regular";
|
|
77
|
+
option: "growth";
|
|
78
|
+
fund_count: number;
|
|
79
|
+
selected_scheme_count: number;
|
|
80
|
+
classification_date: string | null;
|
|
81
|
+
};
|
|
82
|
+
metrics: Record<string, AnalyticsMetric & {
|
|
83
|
+
method: "equal_weighted_arithmetic_mean";
|
|
84
|
+
return_type: "total_return" | "cagr" | null;
|
|
85
|
+
observation_date_min: string | null;
|
|
86
|
+
observation_date_max: string | null;
|
|
87
|
+
observed_elapsed_days_min: number | null;
|
|
88
|
+
observed_elapsed_days_max: number | null;
|
|
89
|
+
start_lag_days_max: number | null;
|
|
90
|
+
end_lag_days_max: number | null;
|
|
91
|
+
unit: string;
|
|
92
|
+
eligible_count: number;
|
|
93
|
+
valid_count: number;
|
|
94
|
+
missing_count: number;
|
|
95
|
+
stale_count: number;
|
|
96
|
+
invalid_count: number;
|
|
97
|
+
coverage_pct: string;
|
|
98
|
+
exclusions: Record<string, number>;
|
|
99
|
+
}>;
|
|
100
|
+
}
|
|
101
|
+
export interface AnalyticsResource<P, R> {
|
|
102
|
+
retrieve(id: string, params: P, options?: RequestOptions): Promise<R>;
|
|
103
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { RequestOptions } from "./client-types.js";
|
|
2
|
+
export type AnalyticsPeriod = "1y" | "3y" | "5y" | "since_inception";
|
|
3
|
+
export type AnalyticsMetric = {
|
|
4
|
+
status: "available";
|
|
5
|
+
value: string;
|
|
6
|
+
reason: null;
|
|
7
|
+
} | {
|
|
8
|
+
status: "unavailable";
|
|
9
|
+
value: null;
|
|
10
|
+
reason: string;
|
|
11
|
+
};
|
|
12
|
+
export interface PerformanceSelection {
|
|
13
|
+
asOf: string;
|
|
14
|
+
periods?: AnalyticsPeriod[];
|
|
15
|
+
}
|
|
16
|
+
export interface AnalyticsEnvelope {
|
|
17
|
+
methodology_version: "ts-analytics-v1";
|
|
18
|
+
requested_as_of: string;
|
|
19
|
+
currency: "INR";
|
|
20
|
+
source_cutoff: string;
|
|
21
|
+
source_version: string;
|
|
22
|
+
warnings: string[];
|
|
23
|
+
}
|
|
24
|
+
export interface PerformancePeriod {
|
|
25
|
+
period: AnalyticsPeriod;
|
|
26
|
+
requested_start: string | null;
|
|
27
|
+
requested_end: string;
|
|
28
|
+
status: "available" | "unavailable";
|
|
29
|
+
reason: string | null;
|
|
30
|
+
total_return_pct: AnalyticsMetric;
|
|
31
|
+
cagr_pct: AnalyticsMetric;
|
|
32
|
+
}
|
|
33
|
+
export interface AnalyticsFreshnessPolicy {
|
|
34
|
+
nav_days: number;
|
|
35
|
+
aum_days: number;
|
|
36
|
+
ter_days: number;
|
|
37
|
+
category_min_funds: number;
|
|
38
|
+
category_min_coverage_pct: number;
|
|
39
|
+
}
|
|
40
|
+
export interface SchemePerformance extends AnalyticsEnvelope {
|
|
41
|
+
calculation_precision: "decimal_inputs_float64_returns";
|
|
42
|
+
freshness_policy: AnalyticsFreshnessPolicy;
|
|
43
|
+
available_history_start: string | null;
|
|
44
|
+
inception_basis: "verified_first_scheme_nav" | null;
|
|
45
|
+
scheme_nav_inception_date: string | null;
|
|
46
|
+
object: "scheme_performance";
|
|
47
|
+
scheme_id: string;
|
|
48
|
+
fund_id: string;
|
|
49
|
+
plan: string;
|
|
50
|
+
option: string;
|
|
51
|
+
basis: string;
|
|
52
|
+
periods: (PerformancePeriod & {
|
|
53
|
+
start_observation_date: string | null;
|
|
54
|
+
end_observation_date: string | null;
|
|
55
|
+
start_nav: string | null;
|
|
56
|
+
end_nav: string | null;
|
|
57
|
+
start_lag_days: number | null;
|
|
58
|
+
end_lag_days: number | null;
|
|
59
|
+
elapsed_days: number | null;
|
|
60
|
+
annualization_basis: "observed_nav_dates_365_25";
|
|
61
|
+
})[];
|
|
62
|
+
}
|
|
63
|
+
export interface CategorySelection {
|
|
64
|
+
asOf: string;
|
|
65
|
+
periods?: Exclude<AnalyticsPeriod, "since_inception">[];
|
|
66
|
+
metrics?: "return"[];
|
|
67
|
+
plan?: "direct" | "regular";
|
|
68
|
+
option?: "growth";
|
|
69
|
+
}
|
|
70
|
+
export interface CategoryStatistics extends AnalyticsEnvelope {
|
|
71
|
+
freshness_policy: AnalyticsFreshnessPolicy;
|
|
72
|
+
object: "category_statistics";
|
|
73
|
+
category: string;
|
|
74
|
+
cohort: {
|
|
75
|
+
policy: "current_classification_as_of_prices";
|
|
76
|
+
plan: "direct" | "regular";
|
|
77
|
+
option: "growth";
|
|
78
|
+
fund_count: number;
|
|
79
|
+
selected_scheme_count: number;
|
|
80
|
+
classification_date: string | null;
|
|
81
|
+
};
|
|
82
|
+
metrics: Record<string, AnalyticsMetric & {
|
|
83
|
+
method: "equal_weighted_arithmetic_mean";
|
|
84
|
+
return_type: "total_return" | "cagr" | null;
|
|
85
|
+
observation_date_min: string | null;
|
|
86
|
+
observation_date_max: string | null;
|
|
87
|
+
observed_elapsed_days_min: number | null;
|
|
88
|
+
observed_elapsed_days_max: number | null;
|
|
89
|
+
start_lag_days_max: number | null;
|
|
90
|
+
end_lag_days_max: number | null;
|
|
91
|
+
unit: string;
|
|
92
|
+
eligible_count: number;
|
|
93
|
+
valid_count: number;
|
|
94
|
+
missing_count: number;
|
|
95
|
+
stale_count: number;
|
|
96
|
+
invalid_count: number;
|
|
97
|
+
coverage_pct: string;
|
|
98
|
+
exclusions: Record<string, number>;
|
|
99
|
+
}>;
|
|
100
|
+
}
|
|
101
|
+
export interface AnalyticsResource<P, R> {
|
|
102
|
+
retrieve(id: string, params: P, options?: RequestOptions): Promise<R>;
|
|
103
|
+
}
|
package/dist/client-types.d.cts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type * as A from "./analytics-types.cjs";
|
|
1
2
|
import type { MonthlyMarketClient } from "./monthly-types.cjs";
|
|
2
3
|
import type { MarketDataClient, CurrentHoldingsInput, CurrentHoldingsResult } from "./market-types.cjs";
|
|
3
4
|
export type * from "./market-types.cjs";
|
|
@@ -17,7 +18,7 @@ export interface BharosaTransport {
|
|
|
17
18
|
send(url: string, request: RequestInit): Promise<Response>;
|
|
18
19
|
}
|
|
19
20
|
interface BharosaBaseConfig {
|
|
20
|
-
/** Defaults to https://
|
|
21
|
+
/** Defaults to https://api.bharosa.finance. Explicit overrides must be valid origins. */
|
|
21
22
|
readonly baseUrl?: string;
|
|
22
23
|
readonly account: string;
|
|
23
24
|
readonly allowLocalhostHttp?: boolean;
|
|
@@ -175,7 +176,11 @@ export type FundObjectReferences = Omit<Fields<FundReferences>, "data"> & {
|
|
|
175
176
|
};
|
|
176
177
|
export interface ClientSurface {
|
|
177
178
|
readonly marketSnapshots: MonthlyMarketClient;
|
|
179
|
+
readonly fundCategories: {
|
|
180
|
+
readonly statistics: A.AnalyticsResource<A.CategorySelection, A.CategoryStatistics>;
|
|
181
|
+
};
|
|
178
182
|
readonly mutualFundSchemes: {
|
|
183
|
+
readonly performance: A.AnalyticsResource<A.PerformanceSelection, A.SchemePerformance>;
|
|
179
184
|
readonly navs: {
|
|
180
185
|
readonly retrieve: MonthlyMarketClient["schemes"]["nav"];
|
|
181
186
|
};
|
package/dist/client-types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type * as A from "./analytics-types.js";
|
|
1
2
|
import type { MonthlyMarketClient } from "./monthly-types.js";
|
|
2
3
|
import type { MarketDataClient, CurrentHoldingsInput, CurrentHoldingsResult } from "./market-types.js";
|
|
3
4
|
export type * from "./market-types.js";
|
|
@@ -17,7 +18,7 @@ export interface BharosaTransport {
|
|
|
17
18
|
send(url: string, request: RequestInit): Promise<Response>;
|
|
18
19
|
}
|
|
19
20
|
interface BharosaBaseConfig {
|
|
20
|
-
/** Defaults to https://
|
|
21
|
+
/** Defaults to https://api.bharosa.finance. Explicit overrides must be valid origins. */
|
|
21
22
|
readonly baseUrl?: string;
|
|
22
23
|
readonly account: string;
|
|
23
24
|
readonly allowLocalhostHttp?: boolean;
|
|
@@ -175,7 +176,11 @@ export type FundObjectReferences = Omit<Fields<FundReferences>, "data"> & {
|
|
|
175
176
|
};
|
|
176
177
|
export interface ClientSurface {
|
|
177
178
|
readonly marketSnapshots: MonthlyMarketClient;
|
|
179
|
+
readonly fundCategories: {
|
|
180
|
+
readonly statistics: A.AnalyticsResource<A.CategorySelection, A.CategoryStatistics>;
|
|
181
|
+
};
|
|
178
182
|
readonly mutualFundSchemes: {
|
|
183
|
+
readonly performance: A.AnalyticsResource<A.PerformanceSelection, A.SchemePerformance>;
|
|
179
184
|
readonly navs: {
|
|
180
185
|
readonly retrieve: MonthlyMarketClient["schemes"]["nav"];
|
|
181
186
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -42,12 +42,50 @@ class Bharosa {
|
|
|
42
42
|
clients;
|
|
43
43
|
investors;
|
|
44
44
|
portfolios;
|
|
45
|
+
fundCategories;
|
|
45
46
|
mutualFunds;
|
|
46
47
|
mutualFundSchemes;
|
|
47
48
|
marketSnapshots;
|
|
48
49
|
marketData;
|
|
49
50
|
constructor(config) {
|
|
50
51
|
const call = (0, transport_cjs_1.createTransport)(config);
|
|
52
|
+
const analyticsQuery = (q, extra = []) => {
|
|
53
|
+
(0, transport_cjs_1.keys)(q, ["asOf", "periods", ...extra]);
|
|
54
|
+
checkedDate(q.asOf);
|
|
55
|
+
(0, transport_cjs_1.check)(q.asOf.endsWith("-01"));
|
|
56
|
+
if (q.periods !== undefined)
|
|
57
|
+
(0, transport_cjs_1.check)(Array.isArray(q.periods) &&
|
|
58
|
+
q.periods.length > 0 &&
|
|
59
|
+
q.periods.length <= 4 &&
|
|
60
|
+
new Set(q.periods).size === q.periods.length &&
|
|
61
|
+
q.periods.every((p) => ["1y", "3y", "5y", "since_inception"].includes(p)));
|
|
62
|
+
return {
|
|
63
|
+
as_of: q.asOf,
|
|
64
|
+
...(q.periods === undefined ? {} : { periods: q.periods.join(",") }),
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
this.fundCategories = Object.freeze({
|
|
68
|
+
statistics: Object.freeze({
|
|
69
|
+
retrieve: (id, q, o) => {
|
|
70
|
+
const query = analyticsQuery(q, ["metrics", "plan", "option"]);
|
|
71
|
+
if (q.metrics !== undefined)
|
|
72
|
+
(0, transport_cjs_1.check)(Array.isArray(q.metrics) &&
|
|
73
|
+
q.metrics.length > 0 &&
|
|
74
|
+
q.metrics.length <= 3 &&
|
|
75
|
+
new Set(q.metrics).size === q.metrics.length &&
|
|
76
|
+
q.metrics.every((m) => m === "return"));
|
|
77
|
+
(0, transport_cjs_1.check)(!q.periods?.includes("since_inception"));
|
|
78
|
+
(0, transport_cjs_1.check)(!(q.metrics && !q.metrics.includes("return") && q.periods));
|
|
79
|
+
return call("analytics_category", {
|
|
80
|
+
id,
|
|
81
|
+
...query,
|
|
82
|
+
...(q.metrics ? { metrics: q.metrics.join(",") } : {}),
|
|
83
|
+
...(q.plan ? { plan: q.plan } : {}),
|
|
84
|
+
...(q.option ? { option: q.option } : {}),
|
|
85
|
+
}, undefined, o);
|
|
86
|
+
},
|
|
87
|
+
}),
|
|
88
|
+
});
|
|
51
89
|
const list = (p) => {
|
|
52
90
|
(0, transport_cjs_1.keys)(p, ["limit", "startingAfter", "client"]);
|
|
53
91
|
return Object.fromEntries(Object.entries(p)
|
|
@@ -299,6 +337,9 @@ class Bharosa {
|
|
|
299
337
|
},
|
|
300
338
|
};
|
|
301
339
|
this.mutualFundSchemes = Object.freeze({
|
|
340
|
+
performance: Object.freeze({
|
|
341
|
+
retrieve: (id, q, o) => call("analytics_scheme", { id, ...analyticsQuery(q) }, undefined, o),
|
|
342
|
+
}),
|
|
302
343
|
navs: Object.freeze({ retrieve: this.marketSnapshots.schemes.nav }),
|
|
303
344
|
expenseRatios: Object.freeze({
|
|
304
345
|
retrieve: this.marketSnapshots.schemes.expenseRatio,
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type * from "./analytics-types.cjs";
|
|
1
2
|
import type { MonthlyMarketClient } from "./monthly-types.cjs";
|
|
2
3
|
export type * from "./monthly-types.cjs";
|
|
3
4
|
import type * as T from "./client-types.cjs";
|
|
@@ -9,6 +10,7 @@ export declare class Bharosa implements T.ClientSurface {
|
|
|
9
10
|
readonly clients: T.ClientSurface["clients"];
|
|
10
11
|
readonly investors: T.ClientSurface["investors"];
|
|
11
12
|
readonly portfolios: T.ClientSurface["portfolios"];
|
|
13
|
+
readonly fundCategories: T.ClientSurface["fundCategories"];
|
|
12
14
|
readonly mutualFunds: T.ClientSurface["mutualFunds"];
|
|
13
15
|
readonly mutualFundSchemes: T.ClientSurface["mutualFundSchemes"];
|
|
14
16
|
readonly marketSnapshots: MonthlyMarketClient;
|
|
@@ -16,7 +18,7 @@ export declare class Bharosa implements T.ClientSurface {
|
|
|
16
18
|
constructor(config: T.BharosaConfig);
|
|
17
19
|
}
|
|
18
20
|
export interface BharosaMarketConfig {
|
|
19
|
-
/** Defaults to https://
|
|
21
|
+
/** Defaults to https://api.bharosa.finance. */
|
|
20
22
|
baseUrl?: string;
|
|
21
23
|
apiKey: string;
|
|
22
24
|
allowLocalhostHttp?: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type * from "./analytics-types.js";
|
|
1
2
|
import type { MonthlyMarketClient } from "./monthly-types.js";
|
|
2
3
|
export type * from "./monthly-types.js";
|
|
3
4
|
import type * as T from "./client-types.js";
|
|
@@ -9,6 +10,7 @@ export declare class Bharosa implements T.ClientSurface {
|
|
|
9
10
|
readonly clients: T.ClientSurface["clients"];
|
|
10
11
|
readonly investors: T.ClientSurface["investors"];
|
|
11
12
|
readonly portfolios: T.ClientSurface["portfolios"];
|
|
13
|
+
readonly fundCategories: T.ClientSurface["fundCategories"];
|
|
12
14
|
readonly mutualFunds: T.ClientSurface["mutualFunds"];
|
|
13
15
|
readonly mutualFundSchemes: T.ClientSurface["mutualFundSchemes"];
|
|
14
16
|
readonly marketSnapshots: MonthlyMarketClient;
|
|
@@ -16,7 +18,7 @@ export declare class Bharosa implements T.ClientSurface {
|
|
|
16
18
|
constructor(config: T.BharosaConfig);
|
|
17
19
|
}
|
|
18
20
|
export interface BharosaMarketConfig {
|
|
19
|
-
/** Defaults to https://
|
|
21
|
+
/** Defaults to https://api.bharosa.finance. */
|
|
20
22
|
baseUrl?: string;
|
|
21
23
|
apiKey: string;
|
|
22
24
|
allowLocalhostHttp?: boolean;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import type * as A from "./analytics-types.cjs";
|
|
1
2
|
import type * as S from "./monthly-types.cjs";
|
|
2
3
|
import type * as M from "./models.cjs";
|
|
3
4
|
import type * as D from "./market-types.cjs";
|
|
4
5
|
import type { CurrentMixEvidence } from "./client-types.cjs";
|
|
5
6
|
/** Each entry is the decoded response of the corresponding generated operation. */
|
|
6
7
|
export interface OperationResults {
|
|
8
|
+
analytics_scheme: A.SchemePerformance;
|
|
9
|
+
analytics_category: A.CategoryStatistics;
|
|
7
10
|
monthly_nav: S.MarketSnapshot<D.NavObservation>;
|
|
8
11
|
monthly_expense: S.MarketSnapshot<D.ExpenseObservation>;
|
|
9
12
|
monthly_portfolio: S.MarketSnapshot<D.FundPortfolio>;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import type * as A from "./analytics-types.js";
|
|
1
2
|
import type * as S from "./monthly-types.js";
|
|
2
3
|
import type * as M from "./models.js";
|
|
3
4
|
import type * as D from "./market-types.js";
|
|
4
5
|
import type { CurrentMixEvidence } from "./client-types.js";
|
|
5
6
|
/** Each entry is the decoded response of the corresponding generated operation. */
|
|
6
7
|
export interface OperationResults {
|
|
8
|
+
analytics_scheme: A.SchemePerformance;
|
|
9
|
+
analytics_category: A.CategoryStatistics;
|
|
7
10
|
monthly_nav: S.MarketSnapshot<D.NavObservation>;
|
|
8
11
|
monthly_expense: S.MarketSnapshot<D.ExpenseObservation>;
|
|
9
12
|
monthly_portfolio: S.MarketSnapshot<D.FundPortfolio>;
|
package/dist/response-checks.cjs
CHANGED
|
@@ -121,6 +121,73 @@ function responseMatches(id, op, data, params, body, account) {
|
|
|
121
121
|
b("valuation_date") !== undefined &&
|
|
122
122
|
d("valuation_date") !== b("valuation_date")))
|
|
123
123
|
return false;
|
|
124
|
+
if (id.startsWith("analytics_")) {
|
|
125
|
+
if (id === "analytics_aum") {
|
|
126
|
+
if (d("requested_date") !== params.as_of ||
|
|
127
|
+
(d("observation_date") !== null &&
|
|
128
|
+
String(d("observation_date")) > String(params.as_of)))
|
|
129
|
+
return false;
|
|
130
|
+
if (d("status") === "available" &&
|
|
131
|
+
field(d("data"), "basis") === "reported_fund_total" &&
|
|
132
|
+
field(field(d("data"), "source"), "date") !== d("observation_date"))
|
|
133
|
+
return false;
|
|
134
|
+
if (d("status") === "available" &&
|
|
135
|
+
(field(d("data"), "fund_id") !== params.id ||
|
|
136
|
+
field(d("data"), "date") !== d("observation_date") ||
|
|
137
|
+
String(d("observation_date")) > String(params.as_of)))
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
if (d("requested_as_of") !== params.as_of)
|
|
142
|
+
return false;
|
|
143
|
+
const identity = id === "analytics_scheme"
|
|
144
|
+
? "scheme_id"
|
|
145
|
+
: id === "analytics_portfolio"
|
|
146
|
+
? "portfolio_id"
|
|
147
|
+
: "category";
|
|
148
|
+
if (d(identity) !== params.id)
|
|
149
|
+
return false;
|
|
150
|
+
if (id === "analytics_category") {
|
|
151
|
+
if (d("cohort", "plan") !== (params.plan ?? "direct") ||
|
|
152
|
+
d("cohort", "option") !== (params.option ?? "growth"))
|
|
153
|
+
return false;
|
|
154
|
+
const requested = String(params.metrics ?? "return").split(",");
|
|
155
|
+
const expected = requested.flatMap((m) => m === "return"
|
|
156
|
+
? String(params.periods ?? "1y,3y,5y")
|
|
157
|
+
.split(",")
|
|
158
|
+
.map((p) => "return_" + p)
|
|
159
|
+
: [m]);
|
|
160
|
+
for (const key of expected) {
|
|
161
|
+
const metric = d("metrics", key);
|
|
162
|
+
if (!(0, schema_cjs_1.record)(metric))
|
|
163
|
+
return false;
|
|
164
|
+
const eligible = Number(field(metric, "eligible_count")), valid = Number(field(metric, "valid_count"));
|
|
165
|
+
const excluded = [
|
|
166
|
+
"missing_count",
|
|
167
|
+
"stale_count",
|
|
168
|
+
"invalid_count",
|
|
169
|
+
].reduce((n, k) => n + Number(field(metric, k)), 0);
|
|
170
|
+
if (eligible !== d("cohort", "fund_count") ||
|
|
171
|
+
valid + excluded !== eligible)
|
|
172
|
+
return false;
|
|
173
|
+
if (field(metric, "status") === "available" &&
|
|
174
|
+
(valid < 3 || valid * 100 < eligible * 80))
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (id !== "analytics_category") {
|
|
179
|
+
const expected = String(params.periods ?? "1y,3y,5y").split(",");
|
|
180
|
+
const got = rows(d("periods"));
|
|
181
|
+
if (got.length !== expected.length ||
|
|
182
|
+
got.some((p, i) => field(p, "period") !== expected[i] ||
|
|
183
|
+
field(p, "requested_end") !== params.as_of ||
|
|
184
|
+
(id === "analytics_scheme" &&
|
|
185
|
+
(later(field(p, "start_observation_date"), field(p, "requested_start")) ||
|
|
186
|
+
later(field(p, "end_observation_date"), params.as_of)))))
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
124
191
|
if (id.startsWith("monthly_") && id !== "monthly_valuation") {
|
|
125
192
|
const observation = d("observation_date"), requested = d("requested_date"), data = d("data");
|
|
126
193
|
if (requested !== params.as_of)
|
package/dist/transport.cjs
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.check = check;
|
|
4
4
|
exports.keys = keys;
|
|
5
5
|
exports.createTransport = createTransport;
|
|
6
|
+
const analytics_contract_cjs_1 = require("./analytics-contract.cjs");
|
|
6
7
|
const monthly_market_data_cjs_1 = require("./monthly-market-data.cjs");
|
|
7
8
|
const contract_cjs_1 = require("./contract.cjs");
|
|
8
9
|
const market_data_cjs_1 = require("./market-data.cjs");
|
|
@@ -13,6 +14,7 @@ const operations = {
|
|
|
13
14
|
...contract_cjs_1.operations,
|
|
14
15
|
...market_data_cjs_1.operations,
|
|
15
16
|
...monthly_market_data_cjs_1.operations,
|
|
17
|
+
...analytics_contract_cjs_1.operations,
|
|
16
18
|
};
|
|
17
19
|
function assertServer() {
|
|
18
20
|
if (typeof window !== "undefined" ||
|
|
@@ -156,7 +158,7 @@ function createTransport(config, marketOnly = false) {
|
|
|
156
158
|
]);
|
|
157
159
|
check(config.allowLocalhostHttp === undefined ||
|
|
158
160
|
typeof config.allowLocalhostHttp === "boolean");
|
|
159
|
-
const base = origin(config.baseUrl === undefined ? "https://
|
|
161
|
+
const base = origin(config.baseUrl === undefined ? "https://api.bharosa.finance" : config.baseUrl, config.allowLocalhostHttp);
|
|
160
162
|
check((0, validate_cjs_1.valid)(operations.retrieve_account.parameters[0].schema, config.account));
|
|
161
163
|
const account = config.account;
|
|
162
164
|
let headers, secrets;
|
|
@@ -196,13 +198,10 @@ function createTransport(config, marketOnly = false) {
|
|
|
196
198
|
check(Number.isInteger(max) && max >= 1 && max <= 16777216);
|
|
197
199
|
const call = async (id, params = {}, body, opts = {}) => {
|
|
198
200
|
const op = operations[id];
|
|
199
|
-
if (marketOnly
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
"monthly_portfolio",
|
|
204
|
-
"monthly_holdings",
|
|
205
|
-
].includes(id));
|
|
201
|
+
if (marketOnly &&
|
|
202
|
+
!["monthly_nav", "monthly_expense", "monthly_portfolio", "monthly_holdings"].includes(id)) {
|
|
203
|
+
throw Object.assign(new errors_cjs_1.ValidationError(), { code: "market_only_operation" });
|
|
204
|
+
}
|
|
206
205
|
let o, serialized, url;
|
|
207
206
|
try {
|
|
208
207
|
o = options(opts);
|
package/dist/validate.cjs
CHANGED
|
@@ -62,7 +62,9 @@ function valid(s, v, depth = 0) {
|
|
|
62
62
|
(s.required ?? []).every((k) => Object.hasOwn(v, k)) &&
|
|
63
63
|
keys.every((k) => Object.hasOwn(s.properties ?? {}, k)
|
|
64
64
|
? valid(s.properties?.[k], v[k], depth + 1)
|
|
65
|
-
: s.additionalProperties
|
|
65
|
+
: typeof s.additionalProperties === "object"
|
|
66
|
+
? valid(s.additionalProperties, v[k], depth + 1)
|
|
67
|
+
: s.additionalProperties !== false));
|
|
66
68
|
}
|
|
67
69
|
default:
|
|
68
70
|
return true;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Growth scheme performance and category returns
|
|
2
|
+
|
|
3
|
+
SDK0.4.0 candidate, unpublished. The two API methods are deployed. Default origin is https://api.bharosa.finance, incorporating the reviewed host-default delta directly on published0.3.2; explicit baseUrl overrides remain supported. Account authorization with accounts:read is required. BharosaMarket does not expose these methods.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { Bharosa } from "bharosa";
|
|
7
|
+
const client = new Bharosa({
|
|
8
|
+
account: "me",
|
|
9
|
+
auth: { type: "account_key", apiKey: process.env.BHAROSA_SECRET_KEY! },
|
|
10
|
+
});
|
|
11
|
+
const scheme = await client.mutualFundSchemes.performance.retrieve("45139", {
|
|
12
|
+
asOf: "2026-10-01", periods: ["1y", "3y"],
|
|
13
|
+
});
|
|
14
|
+
const category = await client.fundCategories.statistics.retrieve("index_fund", {
|
|
15
|
+
asOf: "2026-10-01", periods: ["1y"], metrics: ["return"],
|
|
16
|
+
plan: "direct", option: "growth",
|
|
17
|
+
});
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Use an exact first-of-month asOf. Discover category identifiers through marketData.categories.list; index_fund is a real category, equity was only a local fixture label. Category metrics accepts only return and defaults to return. Category returns are equal-weight means with fund deduplication, minimum3valid funds and80%coverage; inspect status/reason and eligible/valid/missing/invalid/stale counts. An HTTP200 can correctly contain an unavailable metric. Current classification is applied to historical prices, with survivorship/reclassification bias; this is not an investable index return.
|
|
21
|
+
|
|
22
|
+
Scheme responses report exact NAV observations and boundary lags, total return, and annualization over observed dates using365.25days. CAGR is unavailable for periods not longer than one year. IDCW and unverified inception remain explicitly unavailable. NAV freshness limits and missing data must be checked before using a value.
|
|
23
|
+
|
|
24
|
+
There are no investor-performance or fund-AUM methods or public types in this release. Stated-TER comparisons remain deferred; existing expense-ratio methods retain their prior behavior. Future AUM belongs to mutualFunds, not schemes. Shared response freshness metadata includes aum_days/ter_days because the deployed envelope contains those fields; their presence does not expose AUM/TER methods.
|
|
25
|
+
|
|
26
|
+
Hosted scheme/category verification used the app-origin compatibility path with synthetic account access and real market data. Authenticated verification on the new api hostname remains a final-trial requirement; do not claim that journey has passed. No SDK example should create credentials or mutate a portfolio.
|
package/docs/getting-started.md
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
Use Node.js 22.12 or later in a supported LTS release. The SDK supports ESM and CommonJS. Key-based authentication is server-only; keep credentials in your backend or server that handles browser sessions. Browser applications can supply a generic transport whose private host implementation manages sessions, origin restrictions and CSRF. Bun and Deno are unsupported.
|
|
6
6
|
|
|
7
|
-
Obtain your authorized account ID and account key. Bharosa and BharosaMarket default to the production origin `https://
|
|
7
|
+
Obtain your authorized account ID and account key. Bharosa and BharosaMarket default to the production origin `https://api.bharosa.finance`; no API URL environment variable is required. The SDK neither provisions accounts nor runs an OAuth consent flow.
|
|
8
8
|
|
|
9
|
-
## Install
|
|
9
|
+
## Install the unpublished 0.4.0 candidate
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
|
-
npm install bharosa
|
|
12
|
+
npm install /absolute/path/to/bharosa-0.4.0.tgz --ignore-scripts
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Source contributors can build and pack a local archive as described in CONTRIBUTING.md.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bharosa",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Typed Bharosa resource SDK with server credentials or caller-owned transport.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
"SECURITY.md",
|
|
45
45
|
"CHANGELOG.md",
|
|
46
46
|
"FIRST-PARTY-CONTRACT-SHA256",
|
|
47
|
-
"MONTHLY-MARKET-CONTRACT-SHA256"
|
|
47
|
+
"MONTHLY-MARKET-CONTRACT-SHA256",
|
|
48
|
+
"ANALYTICS-CONTRACT-SHA256"
|
|
48
49
|
],
|
|
49
50
|
"scripts": {
|
|
50
51
|
"build": "node scripts/build.mjs",
|
|
@@ -58,7 +59,9 @@
|
|
|
58
59
|
"check:first-party": "node scripts/generate-first-party.mjs --check",
|
|
59
60
|
"typecheck": "node tooling/node_modules/typescript/bin/tsc --noEmit && node tooling/node_modules/typescript/bin/tsc -p tsconfig.test.json --noEmit && node tooling/node_modules/typescript/bin/tsc --noEmit --strict --target ES2022 --module NodeNext --moduleResolution NodeNext --typeRoots tooling/node_modules/@types test/api-compatibility.ts",
|
|
60
61
|
"generate:monthly": "node scripts/generate-monthly.mjs",
|
|
61
|
-
"check:monthly": "node scripts/generate-monthly.mjs --check"
|
|
62
|
+
"check:monthly": "node scripts/generate-monthly.mjs --check",
|
|
63
|
+
"generate:analytics": "node scripts/generate-analytics.mjs",
|
|
64
|
+
"check:analytics": "node scripts/generate-analytics.mjs --check"
|
|
62
65
|
},
|
|
63
66
|
"publishConfig": {
|
|
64
67
|
"access": "public",
|