bharosa 0.3.3 → 0.5.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.
@@ -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" ||
@@ -141,7 +143,17 @@ async function read(response, max, signal) {
141
143
  reader.releaseLock();
142
144
  }
143
145
  }
144
- function createTransport(config, marketOnly = false) {
146
+ function createTransport(input, marketOnly = false) {
147
+ let config;
148
+ if (input != null && typeof input === "object" && Object.hasOwn(input, "apiKey")) {
149
+ keys(input, ["apiKey", "account", "baseUrl", "allowLocalhostHttp", "maxResponseBytes", "fetch"]);
150
+ const simple = input;
151
+ const { apiKey, account, ...rest } = simple;
152
+ config = { ...rest, account: account === undefined ? "me" : account, auth: { type: "account_key", apiKey } };
153
+ }
154
+ else {
155
+ config = input;
156
+ }
145
157
  const customTransport = config?.transport !== undefined;
146
158
  if (!customTransport)
147
159
  assertServer();
@@ -175,7 +187,7 @@ function createTransport(config, marketOnly = false) {
175
187
  (a.type === "delegated_application" && token(a.userAccessToken)));
176
188
  headers = Object.freeze({
177
189
  Authorization: "Bearer " + a.apiKey,
178
- ...(a.type === "delegated_application"
190
+ ...(a.type === "delegated_application" && !marketOnly
179
191
  ? { "Bharosa-User-Authorization": "Bearer " + a.userAccessToken }
180
192
  : {}),
181
193
  Accept: "application/json",
@@ -196,13 +208,10 @@ function createTransport(config, marketOnly = false) {
196
208
  check(Number.isInteger(max) && max >= 1 && max <= 16777216);
197
209
  const call = async (id, params = {}, body, opts = {}) => {
198
210
  const op = operations[id];
199
- if (marketOnly)
200
- check([
201
- "monthly_nav",
202
- "monthly_expense",
203
- "monthly_portfolio",
204
- "monthly_holdings",
205
- ].includes(id));
211
+ if (marketOnly &&
212
+ !["monthly_nav", "monthly_expense", "monthly_portfolio", "monthly_holdings"].includes(id)) {
213
+ throw Object.assign(new errors_cjs_1.ValidationError(), { code: "market_only_operation" });
214
+ }
206
215
  let o, serialized, url;
207
216
  try {
208
217
  o = options(opts);
@@ -2,4 +2,4 @@ import type { OperationResults } from "./operation-types.cjs";
2
2
  import type { BharosaConfig, RequestOptions } from "./client-types.cjs";
3
3
  export declare function check(v: unknown): asserts v;
4
4
  export declare function keys(v: unknown, allowed: readonly string[]): void;
5
- export declare function createTransport(config: BharosaConfig, marketOnly?: boolean): <K extends keyof OperationResults>(id: K, params?: Record<string, unknown>, body?: unknown, opts?: RequestOptions) => Promise<OperationResults[K]>;
5
+ export declare function createTransport(input: BharosaConfig, marketOnly?: boolean): <K extends keyof OperationResults>(id: K, params?: Record<string, unknown>, body?: unknown, opts?: RequestOptions) => Promise<OperationResults[K]>;
@@ -2,4 +2,4 @@ import type { OperationResults } from "./operation-types.js";
2
2
  import type { BharosaConfig, RequestOptions } from "./client-types.js";
3
3
  export declare function check(v: unknown): asserts v;
4
4
  export declare function keys(v: unknown, allowed: readonly string[]): void;
5
- export declare function createTransport(config: BharosaConfig, marketOnly?: boolean): <K extends keyof OperationResults>(id: K, params?: Record<string, unknown>, body?: unknown, opts?: RequestOptions) => Promise<OperationResults[K]>;
5
+ export declare function createTransport(input: BharosaConfig, marketOnly?: boolean): <K extends keyof OperationResults>(id: K, params?: Record<string, unknown>, body?: unknown, opts?: RequestOptions) => Promise<OperationResults[K]>;
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 !== false));
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
+ The two analytics methods are deployed and published in SDK 0.4.0. This local unified-key successor preserves them. Default origin is https://api.bharosa.finance; 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.
@@ -6,10 +6,10 @@ Use Node.js 22.12 or later in a supported LTS release. The SDK supports ESM and
6
6
 
7
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.5.0 candidate
10
10
 
11
11
  ```sh
12
- npm install bharosa@0.3.3 --ignore-scripts
12
+ npm install /absolute/path/to/bharosa-0.5.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.3",
3
+ "version": "0.5.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",