bharosa 0.0.0-stage → 0.3.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 +38 -0
- package/CONTRACT-SHA256 +1 -0
- package/CONTRIBUTING.md +40 -0
- package/FIRST-PARTY-CONTRACT-SHA256 +1 -0
- package/LICENSE +21 -0
- package/MONTHLY-MARKET-CONTRACT-SHA256 +1 -0
- package/README.md +128 -2
- package/SECURITY.md +11 -0
- package/dist/browser.cjs +26 -0
- package/dist/browser.d.cts +2 -0
- package/dist/browser.d.ts +2 -0
- package/dist/client-types.cjs +2 -0
- package/dist/client-types.d.cts +229 -0
- package/dist/client-types.d.ts +229 -0
- package/dist/contract.cjs +2 -0
- package/dist/contract.d.cts +3 -0
- package/dist/contract.d.ts +3 -0
- package/dist/errors.cjs +73 -0
- package/dist/errors.d.cts +48 -0
- package/dist/errors.d.ts +48 -0
- package/dist/index.cjs +390 -0
- package/dist/index.d.cts +30 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.mjs +1 -0
- package/dist/market-data.cjs +3799 -0
- package/dist/market-data.d.cts +2 -0
- package/dist/market-data.d.ts +2 -0
- package/dist/market-types.cjs +2 -0
- package/dist/market-types.d.cts +194 -0
- package/dist/market-types.d.ts +194 -0
- package/dist/models.cjs +2 -0
- package/dist/models.d.cts +511 -0
- package/dist/models.d.ts +511 -0
- package/dist/monthly-market-data.cjs +967 -0
- package/dist/monthly-market-data.d.cts +2 -0
- package/dist/monthly-market-data.d.ts +2 -0
- package/dist/monthly-types.cjs +2 -0
- package/dist/monthly-types.d.cts +32 -0
- package/dist/monthly-types.d.ts +32 -0
- package/dist/operation-types.cjs +2 -0
- package/dist/operation-types.d.cts +54 -0
- package/dist/operation-types.d.ts +54 -0
- package/dist/response-checks.cjs +163 -0
- package/dist/response-checks.d.cts +3 -0
- package/dist/response-checks.d.ts +3 -0
- package/dist/schema.cjs +6 -0
- package/dist/schema.d.cts +38 -0
- package/dist/schema.d.ts +38 -0
- package/dist/testing.cjs +132 -0
- package/dist/testing.d.cts +82 -0
- package/dist/testing.d.ts +82 -0
- package/dist/transport.cjs +425 -0
- package/dist/transport.d.cts +5 -0
- package/dist/transport.d.ts +5 -0
- package/dist/validate.cjs +167 -0
- package/dist/validate.d.cts +4 -0
- package/dist/validate.d.ts +4 -0
- package/docs/getting-started.md +88 -0
- package/docs/index.md +14 -0
- package/docs/monthly-market-data.md +39 -0
- package/docs/portfolios.md +106 -0
- package/docs/provenance.md +9 -0
- package/docs/releasing.md +23 -0
- package/docs/reliability.md +34 -0
- package/docs/testing.md +21 -0
- package/examples/README.md +27 -0
- package/examples/create-investor.ts +12 -0
- package/examples/offline-smoke.mjs +31 -0
- package/examples/portfolio-mixes.ts +99 -0
- package/examples/read-account.ts +12 -0
- package/package.json +69 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# 0.3.0 — local keys-only release candidate (unpublished)
|
|
2
|
+
|
|
3
|
+
Adds server-side BharosaMarket for four registered-app monthly snapshot operations, with no investor token/account argument. Requires separately activated API market_key support. Includes lifecycle0.2.0 changes; no unpublished analytics methods. Version0.3.0 was absent from npm at preparation, not reserved there.
|
|
4
|
+
|
|
5
|
+
# Changelog
|
|
6
|
+
|
|
7
|
+
## 0.2.0 — 30 October 2026
|
|
8
|
+
|
|
9
|
+
- Add `portfolios.update(id, { name, expected_name }, { idempotencyKey })` for account-scoped, name-only updates, with optimistic name comparison and validated response identity. Holdings and snapshots remain unchanged.
|
|
10
|
+
- Accept `positions: []` when creating a saved portfolio. Empty portfolio analysis remains unavailable until holdings exist.
|
|
11
|
+
- Clarify that monthly market reads require authenticated account-read access without a separate market-data approval.
|
|
12
|
+
- Preserve existing methods, exports, authentication, quantity precision, and analytics implementation. Requires a companion API with portfolio lifecycle support; package preparation does not establish production availability.
|
|
13
|
+
|
|
14
|
+
The entries below retain historical preparation notes from the published 0.1.0 package. They are not additional changes in 0.2.0.
|
|
15
|
+
|
|
16
|
+
## 0.1.0 — release candidate
|
|
17
|
+
|
|
18
|
+
Prepared for the first npm release; publication is pending registry authentication and verification. API deployment and external consent activation are separate.
|
|
19
|
+
|
|
20
|
+
- Typed Node.js client with ESM/CommonJS exports, account-scoped direct/delegated authentication, and 17 public resource operations.
|
|
21
|
+
- Portfolio asset, sector, and issuer mix methods for saved and in-memory targets, with MutualFund conveniences delegated to their underlying Portfolio.
|
|
22
|
+
- Object conveniences: `portfolios.build`, immutable readable in-memory positions, and saved `Portfolio.currentSnapshot`; `fromPositions` remains compatible. No additional HTTP endpoints.
|
|
23
|
+
- Typed errors, explicit mutation outcomes, bounded opt-in retries, total request deadlines, response validation, and browser rejection.
|
|
24
|
+
- MIT license for the SDK, standalone guides, synthetic examples, contributor tooling, and CI configuration. The API and analytics implementation remain separate and closed source.
|
|
25
|
+
|
|
26
|
+
## Unreleased — TypeScript source migration
|
|
27
|
+
|
|
28
|
+
- Author the client and behavioral tests in strict TypeScript and emit declarations from implementation.
|
|
29
|
+
- Preserve resource methods, runtime validation, caller-owned transport and CommonJS/ESM package entry points.
|
|
30
|
+
- Keep runtime dependencies empty; TypeScript and Node definitions are development-only tooling.
|
|
31
|
+
|
|
32
|
+
Units-first portfolio creation (local, unreleased): `portfolios.create` accepts an initial position with either `current_value` or positive `quantity`, never both, using the supplied `as_of` date. Existing amount requests and amount-only responses remain unchanged. Supplied units are stored atomically without requiring a NAV. Snapshot `quantity` can now be a decimal string and `valuation` can be null; `total_current_value` is null when any snapshot position lacks a reported amount, and `valuation_basis` is `supplied_quantity`. Consumers of general snapshot reads must handle these new nullable values; this is an intentional prelaunch type widening. Older SDKs cannot read units-only snapshots. Snapshot replacement and in-memory analytics remain amount-only. No public package release or availability change is implied.
|
|
33
|
+
|
|
34
|
+
Unit precision follow-up (local, unreleased): supplied units accept at most four fractional digits; additional digits are rejected, never truncated. Dated amount conversion rounds once to four places using decimal half-even arithmetic; a positive amount rounding to zero returns `units_below_precision`. Currency and NAV precision are unchanged. Exact historical quantities and provenance remain in stored evidence and read responses; the web marks rounded displays with ≈, shows tiny positive values as <0.0001, and makes a rounded edit draft an explicit correction. Existing zero-unit closure remains supported; initial quantities must be positive. No portfolio reset or data rewrite is required. Canonical marketing reconciliation is coordinated through the parent, with deployment pending.
|
|
35
|
+
|
|
36
|
+
Local readiness: reject inconsistent resource pagination responses and discard late custom-transport bodies after cancellation. No operation shapes, credentials, access or availability changed.
|
|
37
|
+
|
|
38
|
+
Local attendee readiness: browser-condition ESM now selects the explicit ESM entry point; packed tests exercise both browser ESM and CJS. The installed archive includes a credential-free offline smoke script. README startup checks identify missing environment variable names without exposing values. No live endpoint, access or publication is implied.
|
package/CONTRACT-SHA256
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3b791799bf705fd36a257e27a2520257f135e772d617b03bb22063ccea4d04e2 marketing/contracts/openapi.json
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
This is an unpublished SDK under local preparation. Keep changes limited to the client, public contracts, documentation, and synthetic tests. Do not copy API implementation, analytics code, provider data, credentials, or internal operational notes into this repository.
|
|
4
|
+
|
|
5
|
+
## Development
|
|
6
|
+
|
|
7
|
+
Use supported Node.js 22.12+ or 24 LTS. Runtime dependencies remain empty. Contributor TypeScript tooling lives in `tooling/` and is separate from the distributable package.
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm --prefix tooling ci --ignore-scripts
|
|
11
|
+
node scripts/check-generated.mjs
|
|
12
|
+
npm run build
|
|
13
|
+
npm test
|
|
14
|
+
node scripts/check-local-examples.mjs
|
|
15
|
+
node scripts/verify-package.mjs
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The unit suite uses synthetic responses. One HTTP regression opens ephemeral loopback ports to verify redirect protection. It does not use live credentials or a live Bharosa service. Packed-consumer verification writes to temporary directories and installs only the local tarball.
|
|
19
|
+
|
|
20
|
+
`node scripts/verify-package.mjs` uses the pinned tooling compiler by default. `BHAROSA_TSC` can select an already-installed compiler for compatibility checks. `npm test` builds, strictly typechecks runtime and tests, checks compatibility with the previous public declarations, then runs the compiled tests against `dist/`.
|
|
21
|
+
|
|
22
|
+
## Contracts and generated files
|
|
23
|
+
|
|
24
|
+
`test/openapi.json` is the public contract snapshot; `scripts/generate.mjs` derives runtime schemas, model type source, and the contract digest. Change the canonical public contract with its owner first, then update the snapshot and regenerate. Review generated changes; never copy private service source to recreate them.
|
|
25
|
+
|
|
26
|
+
For a behavior change, add a regression that demonstrates the user's observable outcome. Check both JavaScript and TypeScript consumers. Update the relevant guide and examples. In the Bharosa workspace, coordinate corresponding marketing guides, capability/endpoint registry, examples, changelog, and reviewed source hashes with the marketing owner. Local verification does not establish deployed availability.
|
|
27
|
+
|
|
28
|
+
## Review hygiene
|
|
29
|
+
|
|
30
|
+
Use small, logical commits with accurate author attribution. Keep unrelated changes separate. Review staged files and package contents for credentials, personal data, and private source. Internal handoff notes and build archives should stay local and untracked. Preserve third-party notices and document any new dependency's license and purpose.
|
|
31
|
+
|
|
32
|
+
Report security concerns privately using the process in [SECURITY.md](SECURITY.md).
|
|
33
|
+
|
|
34
|
+
## TypeScript implementation
|
|
35
|
+
|
|
36
|
+
Authored runtime modules are in `src/*.cts`; the ESM entry point is `src/index.mts`. `npm run build` compiles them with strict TypeScript and emits JavaScript plus declarations into ignored `dist/`. Public declarations come from this source, not a separately maintained client declaration file. CommonJS, ESM and browser-condition consumers use the same runtime.
|
|
37
|
+
|
|
38
|
+
Behavioral tests in `test/*.test.ts` are strictly compiled before execution. Synthetic JSON fixtures remain data. Tests deliberately exercising malformed JavaScript calls use checked reflective helpers; valid consumer examples and the frozen pre-migration API surface are checked separately. Do not use blanket `any` or disable compiler checks to make a migration pass.
|
|
39
|
+
|
|
40
|
+
The contract generators continue to own runtime schema data. TypeScript compilation does not replace network response validation. All credentials, session handling and first-party authorization remain the responsibility of the caller's transport and the server. No private service implementation belongs here.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1df18aec81ec3a525dda9cc25190f2db5fee7776e7422d2a456688ee12656d9f
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Bharosa Technoserve Private Limited
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ad8f930964df34c3a28e3309302d19ba76ab9d48190c024a26b0795422f0b648
|
package/README.md
CHANGED
|
@@ -1,3 +1,129 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Bharosa SDK
|
|
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
|
+
|
|
5
|
+
**Release target:** `bharosa@0.1.0`. Registry publication is pending; use the reviewed local archive until publication is confirmed. You also need an API URL and credentials from the operator of your Bharosa service; installing the SDK does not create an account or grant access.
|
|
6
|
+
|
|
7
|
+
## Start here
|
|
8
|
+
|
|
9
|
+
Use Node.js 22.12+ in a supported LTS release. If you have the source checkout, build and pack it:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm --prefix tooling ci --ignore-scripts
|
|
13
|
+
npm run build
|
|
14
|
+
npm pack --pack-destination /absolute/path/to/artifacts
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
If the operator supplied a reviewed archive, skip the source build. Install that archive in your backend application:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
npm install /absolute/path/to/artifacts/bharosa-0.1.0.tgz
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Configure your application's API origin, account ID, and account key through its secret manager. Then:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { Bharosa } from "bharosa";
|
|
27
|
+
|
|
28
|
+
function required(name: string): string {
|
|
29
|
+
const value = process.env[name];
|
|
30
|
+
if (!value) throw new Error(`Missing ${name}`);
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
const bharosa = new Bharosa({
|
|
34
|
+
baseUrl: required("BHAROSA_API_BASE_URL"),
|
|
35
|
+
account: required("BHAROSA_ACCOUNT_ID"),
|
|
36
|
+
auth: { type: "account_key", apiKey: required("BHAROSA_SECRET_KEY") },
|
|
37
|
+
});
|
|
38
|
+
const account = await bharosa.accounts.retrieve();
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The startup check names missing environment variables without printing their values. See the [complete setup guide](docs/getting-started.md) for explicit checks and delegated authentication. CommonJS uses `const { Bharosa } = require("bharosa")`.
|
|
42
|
+
|
|
43
|
+
## Calculate a saved portfolio's mix
|
|
44
|
+
|
|
45
|
+
A client is a person or family group, such as the Rao family. An investor is one
|
|
46
|
+
member of that group. Each investor can have several saved portfolios; there is
|
|
47
|
+
no automatic "current portfolio" selection.
|
|
48
|
+
|
|
49
|
+
List families with `bharosa.clients.list()`, then list their members with
|
|
50
|
+
`bharosa.investors.list({ client: family.id })`. List portfolios with
|
|
51
|
+
`bharosa.portfolios.list({ client: family.id })` and keep those whose `investor`
|
|
52
|
+
field matches the selected member's ID. Let the user choose a portfolio, and
|
|
53
|
+
pass its returned ID to this function:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
async function savedPortfolioMix(portfolioId: string) {
|
|
57
|
+
const portfolio = await bharosa.portfolios.retrieve(portfolioId);
|
|
58
|
+
const snapshot = await portfolio.currentSnapshot();
|
|
59
|
+
const asset = await portfolio.assetMix();
|
|
60
|
+
return { snapshot, asset };
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Follow `has_more` and `startingAfter` when listing resources. Do not select the
|
|
65
|
+
first result or match only by a family name: names need not be unique. See the
|
|
66
|
+
[complete selection example](examples/portfolio-mixes.ts).
|
|
67
|
+
|
|
68
|
+
The saved mix uses the values and date in the portfolio's current saved snapshot.
|
|
69
|
+
It does not automatically reprice later holding-unit observations using today's
|
|
70
|
+
NAV. `asOf` changes the date used to look up the funds' underlying holdings; it
|
|
71
|
+
does not change the investor's positions or their valuation date.
|
|
72
|
+
|
|
73
|
+
For a fund, search first and let the user select the matching share class:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
const matches = await bharosa.mutualFunds.search({ query: "equity" });
|
|
77
|
+
// Display matches.data and let the user choose the intended fund/plan.
|
|
78
|
+
// The returned instrument exposes assetMix(), sectorMix() and issuerMix().
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Use returned IDs rather than inventing them. The API calculates each mix; the SDK
|
|
82
|
+
makes the request. Asset percentages can be negative or above 100. Sector and
|
|
83
|
+
issuer mixes cover equities only. Keep the response's dates, warnings and
|
|
84
|
+
availability status alongside the numbers.
|
|
85
|
+
|
|
86
|
+
Read the [portfolio guide](docs/portfolios.md), or run the
|
|
87
|
+
[examples with simulated responses](examples/README.md) without live credentials.
|
|
88
|
+
|
|
89
|
+
## Read and build resources
|
|
90
|
+
|
|
91
|
+
`portfolios.build(...)` creates an in-memory calculation handle with a readable, immutable `positions` collection. It defensively copies supplied positions; changes to your original input cannot change future requests. `fromPositions(...)` remains an equivalent alias. Use `portfolios.create(...)` when you intend to persist a portfolio.
|
|
92
|
+
|
|
93
|
+
A saved portfolio has `currentSnapshot()` to retrieve its current snapshot using the existing snapshot API. A fund's `portfolio` is a calculation handle, not a downloaded holdings collection. Sector and issuer methods cover equity-only allocation.
|
|
94
|
+
|
|
95
|
+
The SDK also supports account reads, client lists, investor creation/updates, snapshot replacement, and mutual-fund discovery. Body and response fields use snake_case. Monetary values remain decimal strings. Lists use `limit` and `startingAfter`; investor/portfolio lists can filter by `client`. Root exports include TypeScript models and typed error classes.
|
|
96
|
+
|
|
97
|
+
Saved portfolios also expose scoped `holdings` and declared `history`. Use `holding.positionOn(date)` for dated evidence and `portfolio.on(date).assetMix({ valuationDate, asOf })` for strict server-side historical calculation. See [dated positions and declared history](docs/portfolios.md#dated-positions-and-declared-history) for completeness, exact-date valuation and supported-event limits. These methods do not move calculation code into the SDK.
|
|
98
|
+
|
|
99
|
+
## Reliability and security
|
|
100
|
+
|
|
101
|
+
Keep credentials in a backend or a server that handles browser sessions. Account-key and delegated authentication are server-only. Browser applications can use a caller-owned transport; the host application owns session handling, same-origin enforcement and CSRF. Bun and Deno are unsupported. Clients are immutable and account-scoped. The SDK does not provision access, start consent, or refresh tokens.
|
|
102
|
+
|
|
103
|
+
Requests have a total 30-second timeout by default and zero retries unless requested. Creates require an idempotency key. A failed mutation can have an `unknown` outcome even if the server committed it. Use the [reliability guide](docs/reliability.md) to handle retries, cancellation, and reconciliation correctly.
|
|
104
|
+
|
|
105
|
+
Report vulnerabilities privately using [SECURITY.md](SECURITY.md).
|
|
106
|
+
|
|
107
|
+
## Develop and contribute
|
|
108
|
+
|
|
109
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for reproducible tooling, synthetic tests, and packed-consumer verification. The [release checklist](docs/releasing.md) separates source publication from npm publication. The package is configured to prevent accidental npm publication.
|
|
110
|
+
|
|
111
|
+
## License and scope
|
|
112
|
+
|
|
113
|
+
[MIT](LICENSE) — Copyright (c) 2026 Bharosa Technoserve Private Limited.
|
|
114
|
+
|
|
115
|
+
The license covers this SDK. The Bharosa API service, analytics implementation, ingestion adapters, and provider datasets are separate and are not included or licensed by this repository.
|
|
116
|
+
|
|
117
|
+
### Monthly market history and synthetic samples
|
|
118
|
+
|
|
119
|
+
`client.marketSnapshots` exposes month-start historical market observations and latest NAV valuation without a separate market-data approval step, using authenticated credentials with the required account-read scope. All external credentials, including direct account keys, use monthly historical market dates; investor transaction and position history retains its full dates. See [monthly snapshots](docs/monthly-market-data.md) for actual observation dates, missing data and availability. This local implementation does not activate live access.
|
|
120
|
+
|
|
121
|
+
The optional `bharosa/testing` entrypoint supplies fresh, deterministic synthetic portfolios and fictional fund compositions without credentials or network requests. Its seed helper writes only when explicitly called with an authenticated client, confirmed test account, stable run ID and resolved instrument mapping. See [testing samples](docs/testing.md).
|
|
122
|
+
|
|
123
|
+
Unit precision follow-up (local, unreleased): supplied units accept at most four fractional digits; additional digits are rejected, never truncated. Dated amount conversion rounds once to four places using decimal half-even arithmetic; a positive amount rounding to zero returns `units_below_precision`. Currency and NAV precision are unchanged. Exact historical quantities and provenance remain in stored evidence and read responses; the web marks rounded displays with ≈, shows tiny positive values as <0.0001, and makes a rounded edit draft an explicit correction. Existing zero-unit closure remains supported; initial quantities must be positive. No portfolio reset or data rewrite is required. Canonical marketing reconciliation is coordinated through the parent, with deployment pending.
|
|
124
|
+
|
|
125
|
+
After installing the archive, run `node node_modules/bharosa/examples/offline-smoke.mjs` for a credential-free synthetic read. This checks installed imports and the transport path without contacting Bharosa or creating data. It does not prove live access. Source-checkout verification commands require contributor files that are intentionally excluded from the runtime archive.
|
|
126
|
+
|
|
127
|
+
### Local candidate: registered-app monthly data
|
|
128
|
+
|
|
129
|
+
Not published or activated. Server applications can use `new BharosaMarket({baseUrl, 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. A separately versioned release and explicit API activation are required.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Security reporting
|
|
2
|
+
|
|
3
|
+
Do not include credentials, customer records, financial account data, or exploit details in a public issue or pull request.
|
|
4
|
+
|
|
5
|
+
Before opening this repository to the public, maintainers must enable private vulnerability reporting through the repository's Security advisories and verify that reports reach the responsible maintainer. A verified private reporting channel is a release prerequisite. No reporting email or response-time commitment is established here.
|
|
6
|
+
|
|
7
|
+
Once enabled, use **Security → Report a vulnerability** for a private report. If that option is absent, do not post sensitive details publicly; ask the repository maintainer to enable private reporting first.
|
|
8
|
+
|
|
9
|
+
Include the affected SDK version/runtime, a minimal synthetic reproduction, expected and observed behavior, and impact. Redact tokens, keys, account identifiers, and customer data. No live service access is required to demonstrate most SDK issues.
|
|
10
|
+
|
|
11
|
+
There are no publicly released supported SDK versions yet. Version support and a security maintenance policy must be established before the first public package release.
|
package/dist/browser.cjs
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
const sdk = __importStar(require("./index.cjs"));
|
|
26
|
+
module.exports = sdk;
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import type { MonthlyMarketClient } from "./monthly-types.cjs";
|
|
2
|
+
import type { MarketDataClient, CurrentHoldingsInput, CurrentHoldingsResult } from "./market-types.cjs";
|
|
3
|
+
export type * from "./market-types.cjs";
|
|
4
|
+
import type { Holding, HoldingPosition, HistoryCapability, HistoryView, HistoryImport, HistoryImportResult, HoldingsList, AssetMix, SectorMix, IssuerMix, PositionInput, Account, Client, ClientsList, Investor, InvestorsList, InvestorCreate, InvestorUpdate, Portfolio, PortfoliosList, PortfolioCreate, PortfolioUpdate, SnapshotCreate, SnapshotView, FundsList, FundReferences } from "./models.cjs";
|
|
5
|
+
export type * from "./models.cjs";
|
|
6
|
+
export type Auth = {
|
|
7
|
+
readonly type: "account_key";
|
|
8
|
+
readonly apiKey: string;
|
|
9
|
+
readonly userAccessToken?: never;
|
|
10
|
+
} | {
|
|
11
|
+
readonly type: "delegated_application";
|
|
12
|
+
readonly apiKey: string;
|
|
13
|
+
readonly userAccessToken: string;
|
|
14
|
+
};
|
|
15
|
+
/** Trusted caller-owned transport. Authentication, session handling and origin policy belong to the host application. */
|
|
16
|
+
export interface BharosaTransport {
|
|
17
|
+
send(url: string, request: RequestInit): Promise<Response>;
|
|
18
|
+
}
|
|
19
|
+
interface BharosaBaseConfig {
|
|
20
|
+
readonly baseUrl: string;
|
|
21
|
+
readonly account: string;
|
|
22
|
+
readonly allowLocalhostHttp?: boolean;
|
|
23
|
+
readonly maxResponseBytes?: number;
|
|
24
|
+
}
|
|
25
|
+
export type BharosaConfig = BharosaBaseConfig & ({
|
|
26
|
+
readonly auth: Auth;
|
|
27
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
28
|
+
readonly transport?: never;
|
|
29
|
+
} | {
|
|
30
|
+
readonly transport: BharosaTransport;
|
|
31
|
+
readonly auth?: never;
|
|
32
|
+
readonly fetch?: never;
|
|
33
|
+
});
|
|
34
|
+
export interface RequestOptions {
|
|
35
|
+
idempotencyKey?: string;
|
|
36
|
+
signal?: AbortSignal;
|
|
37
|
+
timeoutMs?: number;
|
|
38
|
+
maxRetries?: 0 | 1 | 2;
|
|
39
|
+
}
|
|
40
|
+
export interface IdempotentOptions extends RequestOptions {
|
|
41
|
+
idempotencyKey: string;
|
|
42
|
+
}
|
|
43
|
+
export interface ListOptions {
|
|
44
|
+
limit?: number;
|
|
45
|
+
startingAfter?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface FilteredListOptions extends ListOptions {
|
|
48
|
+
client?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface PortfolioListOptions extends ListOptions {
|
|
51
|
+
/** Compatibility alias; cannot be combined with plural filters. */
|
|
52
|
+
client?: string;
|
|
53
|
+
client_ids?: string[];
|
|
54
|
+
investor_ids?: string[];
|
|
55
|
+
}
|
|
56
|
+
export type MutationOutcome = "not_applicable" | "not_sent" | "rejected" | "unknown";
|
|
57
|
+
export interface MixOptions {
|
|
58
|
+
asOf?: string;
|
|
59
|
+
}
|
|
60
|
+
export interface PortfolioMethods {
|
|
61
|
+
assetMix(params?: MixOptions, options?: RequestOptions): Promise<AssetMix>;
|
|
62
|
+
sectorMix(params?: MixOptions, options?: RequestOptions): Promise<SectorMix>;
|
|
63
|
+
issuerMix(params?: MixOptions, options?: RequestOptions): Promise<IssuerMix>;
|
|
64
|
+
}
|
|
65
|
+
export interface InMemoryPortfolioInput {
|
|
66
|
+
valuationDate: string;
|
|
67
|
+
currency?: "INR";
|
|
68
|
+
positions: ReadonlyArray<Readonly<PositionInput>>;
|
|
69
|
+
}
|
|
70
|
+
export interface DatedPortfolioMethods {
|
|
71
|
+
assetMix(params?: MixOptions & {
|
|
72
|
+
valuationDate?: string;
|
|
73
|
+
}, options?: RequestOptions): Promise<AssetMix>;
|
|
74
|
+
sectorMix(params?: MixOptions & {
|
|
75
|
+
valuationDate?: string;
|
|
76
|
+
}, options?: RequestOptions): Promise<SectorMix>;
|
|
77
|
+
issuerMix(params?: MixOptions & {
|
|
78
|
+
valuationDate?: string;
|
|
79
|
+
}, options?: RequestOptions): Promise<IssuerMix>;
|
|
80
|
+
on(date: string): DatedPortfolioMethods;
|
|
81
|
+
}
|
|
82
|
+
export type HoldingObject = Holding & {
|
|
83
|
+
positionOn(date: string, options?: RequestOptions): Promise<HoldingPosition>;
|
|
84
|
+
};
|
|
85
|
+
export interface InMemoryPortfolio extends PortfolioMethods {
|
|
86
|
+
on(date: string): DatedPortfolioMethods;
|
|
87
|
+
readonly positions: ReadonlyArray<Readonly<PositionInput>>;
|
|
88
|
+
}
|
|
89
|
+
export interface CurrentPortfolioMethods {
|
|
90
|
+
assetMix(params?: Record<string, never>, options?: RequestOptions): Promise<AssetMix & CurrentMixEvidence>;
|
|
91
|
+
sectorMix(params?: Record<string, never>, options?: RequestOptions): Promise<SectorMix & CurrentMixEvidence>;
|
|
92
|
+
issuerMix(params?: Record<string, never>, options?: RequestOptions): Promise<IssuerMix & CurrentMixEvidence>;
|
|
93
|
+
}
|
|
94
|
+
export interface CurrentMixEvidence {
|
|
95
|
+
current_valuation: {
|
|
96
|
+
valuation_date: string;
|
|
97
|
+
holdings: Array<{
|
|
98
|
+
holding: string;
|
|
99
|
+
investment_account: string;
|
|
100
|
+
instrument: string;
|
|
101
|
+
scheme_id: string;
|
|
102
|
+
status: "available";
|
|
103
|
+
units: string;
|
|
104
|
+
as_of: string;
|
|
105
|
+
position_date: string;
|
|
106
|
+
value: {
|
|
107
|
+
amount: string;
|
|
108
|
+
currency: "INR";
|
|
109
|
+
};
|
|
110
|
+
nav: {
|
|
111
|
+
amount: string;
|
|
112
|
+
currency: "INR";
|
|
113
|
+
date: string;
|
|
114
|
+
};
|
|
115
|
+
freshness: {
|
|
116
|
+
status: "recent" | "stale";
|
|
117
|
+
age_days: number;
|
|
118
|
+
recent_within_days: 3;
|
|
119
|
+
time_zone: "Asia/Kolkata";
|
|
120
|
+
};
|
|
121
|
+
ownership_status: "user_supplied_not_verified";
|
|
122
|
+
valuation_basis: "units_times_latest_nav";
|
|
123
|
+
revision: number | null;
|
|
124
|
+
source: {
|
|
125
|
+
kind: "user" | "statement";
|
|
126
|
+
reference: string;
|
|
127
|
+
};
|
|
128
|
+
derivation: import("./market-types.cjs").CurrentHoldingsResult["holdings"][number]["derivation"] | null;
|
|
129
|
+
}>;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
export type PortfolioObject = Portfolio & PortfolioMethods & {
|
|
133
|
+
current(): CurrentPortfolioMethods;
|
|
134
|
+
currentSnapshot(options?: RequestOptions): Promise<SnapshotPortfolioView>;
|
|
135
|
+
on(date: string): DatedPortfolioMethods;
|
|
136
|
+
readonly history: {
|
|
137
|
+
retrieve(options?: RequestOptions): Promise<HistoryView>;
|
|
138
|
+
import(body: HistoryImport, options: IdempotentOptions): Promise<HistoryImportResult>;
|
|
139
|
+
canReconstruct(date: string, options?: RequestOptions): Promise<HistoryCapability>;
|
|
140
|
+
};
|
|
141
|
+
readonly holdings: {
|
|
142
|
+
setCurrent(body: CurrentHoldingsInput, options: IdempotentOptions): Promise<CurrentHoldingsResult>;
|
|
143
|
+
retrieve(holding: string, options?: RequestOptions): Promise<HoldingObject>;
|
|
144
|
+
list(params?: {
|
|
145
|
+
date?: string;
|
|
146
|
+
}, options?: RequestOptions): Promise<Omit<HoldingsList, "data"> & {
|
|
147
|
+
data: HoldingObject[];
|
|
148
|
+
}>;
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
type Fields<T> = {
|
|
152
|
+
[K in keyof T as string extends K ? never : K]: T[K];
|
|
153
|
+
};
|
|
154
|
+
export type SnapshotPortfolioView = Omit<Fields<SnapshotView>, "portfolio"> & {
|
|
155
|
+
portfolio: PortfolioObject;
|
|
156
|
+
};
|
|
157
|
+
export type PortfolioObjectsList = Omit<Fields<PortfoliosList>, "data"> & {
|
|
158
|
+
data: PortfolioObject[];
|
|
159
|
+
};
|
|
160
|
+
export interface MutualFundObject extends PortfolioMethods {
|
|
161
|
+
readonly portfolio: PortfolioMethods;
|
|
162
|
+
readonly mutual_fund_id?: string;
|
|
163
|
+
readonly instrument?: string;
|
|
164
|
+
}
|
|
165
|
+
export type FundObjectsList = Omit<Fields<FundsList>, "data"> & {
|
|
166
|
+
data: Array<FundsList["data"][number] & {
|
|
167
|
+
instrument: FundsList["data"][number]["instrument"] & MutualFundObject;
|
|
168
|
+
}>;
|
|
169
|
+
};
|
|
170
|
+
export type FundObjectReferences = Omit<Fields<FundReferences>, "data"> & {
|
|
171
|
+
data: Array<FundReferences["data"][number] & {
|
|
172
|
+
instrument: FundReferences["data"][number]["instrument"] & MutualFundObject;
|
|
173
|
+
}>;
|
|
174
|
+
};
|
|
175
|
+
export interface ClientSurface {
|
|
176
|
+
readonly marketSnapshots: MonthlyMarketClient;
|
|
177
|
+
readonly mutualFundSchemes: {
|
|
178
|
+
readonly navs: {
|
|
179
|
+
readonly retrieve: MonthlyMarketClient["schemes"]["nav"];
|
|
180
|
+
};
|
|
181
|
+
readonly expenseRatios: {
|
|
182
|
+
readonly retrieve: MonthlyMarketClient["schemes"]["expenseRatio"];
|
|
183
|
+
};
|
|
184
|
+
readonly valuation: MonthlyMarketClient["schemes"]["valuation"];
|
|
185
|
+
};
|
|
186
|
+
readonly marketData: MarketDataClient;
|
|
187
|
+
readonly accounts: {
|
|
188
|
+
readonly retrieve: (options?: RequestOptions) => Promise<Account>;
|
|
189
|
+
};
|
|
190
|
+
readonly clients: {
|
|
191
|
+
readonly list: (params?: ListOptions, options?: RequestOptions) => Promise<ClientsList>;
|
|
192
|
+
readonly retrieve: (id: string, options?: RequestOptions) => Promise<Client>;
|
|
193
|
+
};
|
|
194
|
+
readonly investors: {
|
|
195
|
+
readonly list: (params?: FilteredListOptions, options?: RequestOptions) => Promise<InvestorsList>;
|
|
196
|
+
readonly retrieve: (id: string, options?: RequestOptions) => Promise<Investor>;
|
|
197
|
+
readonly create: (body: InvestorCreate, options: IdempotentOptions) => Promise<Investor>;
|
|
198
|
+
readonly update: (id: string, body: InvestorUpdate, options?: RequestOptions) => Promise<Investor>;
|
|
199
|
+
};
|
|
200
|
+
readonly portfolios: {
|
|
201
|
+
readonly update: (id: string, body: PortfolioUpdate, options: IdempotentOptions) => Promise<PortfolioObject>;
|
|
202
|
+
readonly build: (input: InMemoryPortfolioInput) => InMemoryPortfolio;
|
|
203
|
+
readonly fromPositions: (input: InMemoryPortfolioInput) => InMemoryPortfolio;
|
|
204
|
+
readonly list: (params?: PortfolioListOptions, options?: RequestOptions) => Promise<PortfolioObjectsList>;
|
|
205
|
+
readonly retrieve: (id: string, options?: RequestOptions) => Promise<PortfolioObject>;
|
|
206
|
+
readonly create: (body: PortfolioCreate, options: IdempotentOptions) => Promise<SnapshotPortfolioView>;
|
|
207
|
+
readonly snapshots: {
|
|
208
|
+
readonly retrieveCurrent: (id: string, options?: RequestOptions) => Promise<SnapshotPortfolioView>;
|
|
209
|
+
readonly create: (id: string, body: SnapshotCreate, options: IdempotentOptions) => Promise<SnapshotPortfolioView>;
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
readonly mutualFunds: {
|
|
213
|
+
readonly portfolios: {
|
|
214
|
+
readonly retrieve: MonthlyMarketClient["funds"]["portfolio"];
|
|
215
|
+
readonly holdings: {
|
|
216
|
+
readonly list: MonthlyMarketClient["funds"]["holdings"];
|
|
217
|
+
};
|
|
218
|
+
};
|
|
219
|
+
readonly fromId: (mutualFundId: string) => MutualFundObject;
|
|
220
|
+
readonly fromInstrument: (instrument: string) => MutualFundObject;
|
|
221
|
+
readonly search: (params: {
|
|
222
|
+
query: string;
|
|
223
|
+
limit?: number;
|
|
224
|
+
}, options?: RequestOptions) => Promise<FundObjectsList>;
|
|
225
|
+
readonly references: (params: {
|
|
226
|
+
instruments: string[];
|
|
227
|
+
}, options?: RequestOptions) => Promise<FundObjectReferences>;
|
|
228
|
+
};
|
|
229
|
+
}
|