@databolsa/sdk 1.0.10 → 1.0.12

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/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { CorporateEventsResponse, CryptoQuotesResponse, DividendsResponse, DocumentsResponse, EtfListResponse, EtfProfile, ExpectationsResponse, Fii, FiiDistributionsResponse, FiiIndicatorsResponse, FiiReportsResponse, FiiScreenResponse, FundHoldersResponse, FundHoldingsResponse, FundListResponse, FundProfile, FundQuotesResponse, FundScreenerResponse, HealthResponse, IngestHealthResponse, IndexCompositionResponse, IndexMeta, IndexQuotesResponse, IndicatorHistoryResponse, IntradaySeriesResponse, LiveQuotesResponse, BdrListResponse, BdrProfile, BdrQuotesResponse, InsiderResponse, InvestorFlowMonthlyResponse, InvestorFlowResponse, MacroGearsResponse, OfferingsResponse, OptionExpiriesResponse, OptionsChainResponse, OptionsQuotesResponse, DocumentSearchResponse, PortfolioResponse, CommunityBotsResponse, CommunityBotPostInput, CommunityBotPostResponse, CommunityBotReplyResponse, CommunityFeedParams, CommunityFeedResponse, CommunityPostResponse, RegisterCommunityBotInput, RegisterCommunityBotResponse, Query, QuotesResponse, RangeParams, RegimeSnapshot, ScreenStocksResponse, SearchDocumentsParams, SearchResult, SeriesResponse, Stock, StockIndicatorsResponse, SuitabilityResponse, TesouroBondsResponse, TradeStatsResponse, YieldCurveResponse } from "./types";
1
+ import type { CorporateEventsResponse, CryptoAsset, CryptoListResponse, CryptoLiveResponse, CryptoQuotesResponse, UsAssetsResponse, UsAssetDetail, UsQuotesResponse, UsFilingsResponse, DividendsResponse, DocumentsResponse, EtfListResponse, EtfProfile, ExpectationsResponse, Fii, FiiDistributionsResponse, FiiIndicatorsResponse, FiiReportsResponse, FiiScreenResponse, FundHoldersResponse, FundHoldingsResponse, FundListResponse, FundProfile, FundQuotesResponse, FundScreenerResponse, HealthResponse, IngestHealthResponse, IndexCompositionResponse, IndexMeta, IndexQuotesResponse, IndicatorHistoryResponse, IntradaySeriesResponse, LiveQuotesResponse, BdrListResponse, BdrProfile, BdrQuotesResponse, InsiderResponse, InvestorFlowMonthlyResponse, InvestorFlowResponse, MacroGearsResponse, OfferingsResponse, OptionExpiriesResponse, OptionsChainResponse, OptionsQuotesResponse, DocumentSearchResponse, PortfolioResponse, CommunityBotsResponse, CommunityBotPostInput, CommunityBotPostResponse, CommunityBotReplyResponse, CommunityFeedParams, CommunityFeedResponse, CommunityPostResponse, RegisterCommunityBotInput, RegisterCommunityBotResponse, Query, QuotesResponse, RangeParams, RegimeSnapshot, ScreenStocksResponse, SearchDocumentsParams, SearchResult, SeriesResponse, Stock, StockIndicatorsResponse, SuitabilityResponse, TesouroBondsResponse, TradeStatsResponse, YieldCurveResponse, AddPortfolioTransactionResponse, CreatePortfolioResponse, PortfolioAssetRef, PortfolioDetail, PortfolioHistoryResponse, PortfolioImportInput, PortfolioImportRowsResponse, PortfolioImportsResponse, PortfolioImportSummary, PortfolioPatch, PortfolioRfContract, PortfolioTransaction, PortfolioTransactionInput, PortfolioTransactionPatch, PortfoliosResponse, PortfolioTransactionsResponse } from "./types";
2
2
  /** Filtros do screener de ações — derivados de `GET /v1/screener/stocks`. */
3
3
  export type ScreenStocksParams = Query<"screenStocks">;
4
4
  /**
@@ -155,10 +155,40 @@ export interface DataBolsaClient {
155
155
  getMacroGears(params?: {
156
156
  gear?: string;
157
157
  }): Promise<MacroGearsResponse>;
158
+ /** Catálogo de criptoativos (paginado; busca por símbolo/nome). */
159
+ listCrypto(params?: {
160
+ search?: string;
161
+ limit?: number;
162
+ cursor?: string;
163
+ }): Promise<CryptoListResponse>;
164
+ getCrypto(symbol: string): Promise<CryptoAsset>;
165
+ /** Snapshot quase-live (~1 min, 24/7) de todo o universo de cripto. */
166
+ listCryptoLive(): Promise<CryptoLiveResponse>;
158
167
  listCryptoQuotes(symbol: string, params?: RangeParams & {
159
168
  interval?: "1d" | "1h";
160
169
  limit?: number;
161
170
  }): Promise<CryptoQuotesResponse>;
171
+ /** Catálogo de ativos dos EUA (paginado; filtra por tipo, busca por ticker/nome). */
172
+ listUsAssets(params?: {
173
+ search?: string;
174
+ type?: "stock" | "etf";
175
+ bdr?: string;
176
+ limit?: number;
177
+ cursor?: string;
178
+ }): Promise<UsAssetsResponse>;
179
+ /** Perfil de um ativo dos EUA com fundamentos SEC inline. */
180
+ getUsAsset(ticker: string): Promise<UsAssetDetail>;
181
+ /** Cotações EOD em USD (ajustadas por desdobramento na fonte). */
182
+ listUsAssetQuotes(ticker: string, params?: RangeParams & {
183
+ limit?: number;
184
+ cursor?: string;
185
+ }): Promise<UsQuotesResponse>;
186
+ /** Filings SEC (10-K/10-Q/8-K…) com link do documento no EDGAR. */
187
+ listUsFilings(ticker: string, params?: {
188
+ form?: string;
189
+ limit?: number;
190
+ cursor?: string;
191
+ }): Promise<UsFilingsResponse>;
162
192
  /** Cadeia viva de um subjacente (séries não vencidas, mais negociadas). Filtra por vencimento/tipo. */
163
193
  listOptionsChain(underlying: string, params?: {
164
194
  expiry?: string;
@@ -192,8 +222,58 @@ export interface DataBolsaClient {
192
222
  * Escopada ao dono da chave de API (a mesma da conta) — passe sua chave por usuário.
193
223
  */
194
224
  getPortfolio(): Promise<PortfolioResponse>;
225
+ /** Histórico mensal consolidado da carteira (patrimônio × aporte × proventos × realizado). */
226
+ getPortfolioHistory(): Promise<PortfolioHistoryResponse>;
195
227
  /** Seu perfil de investidor (suitability). `profile` é nulo se ainda não definido. */
196
228
  getSuitability(): Promise<SuitabilityResponse>;
229
+ /** Lista as suas carteiras (id, nome, nº de ativos). */
230
+ listPortfolios(): Promise<PortfoliosResponse>;
231
+ /** Cria uma carteira. O número de carteiras depende do plano (erro 402 no teto). */
232
+ createPortfolio(name: string, visibility?: "private" | "unlisted" | "public"): Promise<CreatePortfolioResponse>;
233
+ /** Uma carteira computada: posições, preço médio, P&L, alocação. */
234
+ getPortfolioDetail(id: string): Promise<PortfolioDetail>;
235
+ /** Renomeia, muda visibilidade e/ou marca como simulação. */
236
+ updatePortfolio(id: string, patch: PortfolioPatch): Promise<unknown>;
237
+ /** APAGA a carteira com todos os ativos e transações (irreversível). */
238
+ deletePortfolio(id: string): Promise<{
239
+ deleted?: boolean;
240
+ }>;
241
+ /** Histórico mensal de UMA carteira. */
242
+ getPortfolioHistoryById(id: string): Promise<PortfolioHistoryResponse>;
243
+ /** Adiciona um ativo à carteira (idempotente; sem transações = watchlist). */
244
+ addPortfolioAsset(id: string, asset: PortfolioAssetRef): Promise<unknown>;
245
+ /** Remove um ativo da carteira, APAGANDO o ledger dele nela (irreversível). */
246
+ removePortfolioAsset(id: string, asset: PortfolioAssetRef): Promise<unknown>;
247
+ /** Define a taxa contratada de uma posição de renda fixa (indexer "none" limpa). */
248
+ updatePortfolioAsset(id: string, asset: PortfolioAssetRef, rf: PortfolioRfContract): Promise<unknown>;
249
+ /** Ledger (transações) de um ativo da carteira. */
250
+ listPortfolioTransactions(id: string, asset: PortfolioAssetRef): Promise<PortfolioTransactionsResponse>;
251
+ /** Lança uma transação; o ativo é adicionado automaticamente se preciso. */
252
+ addPortfolioTransaction(id: string, asset: PortfolioAssetRef, tx: PortfolioTransactionInput): Promise<AddPortfolioTransactionResponse>;
253
+ /** Edita uma transação (patch parcial). */
254
+ updatePortfolioTransaction(id: string, txId: string, patch: PortfolioTransactionPatch): Promise<PortfolioTransaction>;
255
+ /** Remove uma transação do ledger (irreversível). */
256
+ deletePortfolioTransaction(id: string, txId: string): Promise<{
257
+ deleted?: boolean;
258
+ }>;
259
+ /**
260
+ * Importa uma planilha (Negociação/Movimentação da B3 em .xlsx, ou o template
261
+ * manual em .csv/.xlsx) para a carteira. Idempotente: reenviar o mesmo arquivo
262
+ * não duplica lançamentos. Retorna o resumo (importadas/duplicadas/avisos).
263
+ */
264
+ importPortfolioFile(id: string, input: PortfolioImportInput): Promise<PortfolioImportSummary>;
265
+ /** Histórico de imports da carteira. */
266
+ listPortfolioImports(id: string): Promise<PortfolioImportsResponse>;
267
+ /** Linhas de um import, com status (imported/ignored/duplicate/error) e motivo. */
268
+ listPortfolioImportRows(id: string, importId: string, params?: {
269
+ status?: "imported" | "ignored" | "duplicate" | "error";
270
+ limit?: number;
271
+ offset?: number;
272
+ }): Promise<PortfolioImportRowsResponse>;
273
+ /** Template CSV do import manual (texto). */
274
+ getPortfolioImportTemplate(): Promise<string>;
275
+ /** Reconcilia a posição de um ativo à quantidade declarada pela B3 (ajuste idempotente). */
276
+ reconcilePortfolioAsset(id: string, asset: PortfolioAssetRef, targetQty: number, asOf: string): Promise<unknown>;
197
277
  /**
198
278
  * Busca semântica no texto de documentos CVM/B3 (fatos relevantes, releases,
199
279
  * balanços, relatórios de FII, atas). Filtre por papel/categoria/ano quando souber.
@@ -1,5 +1,5 @@
1
1
  import { type DataBolsaClient, type LiveQuotesParams, type ScreenFiisParams, type ScreenFundsParams, type ScreenStocksParams } from "./client";
2
- import type { CorporateEventsResponse, CryptoQuotesResponse, DividendsResponse, DocumentSearchResponse, DocumentsResponse, EtfListResponse, EtfProfile, ExpectationsResponse, Fii, FiiDistributionsResponse, FiiIndicatorsResponse, FiiReportsResponse, FiiScreenResponse, FundHoldersResponse, FundHoldingsResponse, FundListResponse, FundProfile, FundQuotesResponse, FundScreenerResponse, HealthResponse, IngestHealthResponse, IndexCompositionResponse, IndexMeta, IndexQuotesResponse, IndicatorHistoryResponse, IntradaySeriesResponse, LiveQuotesResponse, BdrListResponse, BdrProfile, BdrQuotesResponse, InsiderResponse, InvestorFlowMonthlyResponse, InvestorFlowResponse, MacroGearsResponse, OfferingsResponse, OptionExpiriesResponse, OptionsChainResponse, OptionsQuotesResponse, PortfolioResponse, CommunityBotsResponse, CommunityBotPostInput, CommunityBotPostResponse, CommunityBotReplyResponse, CommunityFeedParams, CommunityFeedResponse, CommunityPostResponse, RegisterCommunityBotInput, RegisterCommunityBotResponse, QuotesResponse, RangeParams, RegimeSnapshot, ScreenStocksResponse, SearchDocumentsParams, SearchResult, SeriesResponse, Stock, StockIndicatorsResponse, SuitabilityResponse, TesouroBondsResponse, TradeStatsResponse, YieldCurveResponse } from "./types";
2
+ import type { AddPortfolioTransactionResponse, CreatePortfolioResponse, PortfolioAssetRef, PortfolioDetail, PortfolioHistoryResponse, PortfolioImportInput, PortfolioImportRowsResponse, PortfolioImportsResponse, PortfolioImportSummary, PortfolioPatch, PortfolioRfContract, PortfolioTransaction, PortfolioTransactionInput, PortfolioTransactionPatch, PortfoliosResponse, PortfolioTransactionsResponse, CorporateEventsResponse, CryptoAsset, CryptoListResponse, CryptoLiveResponse, CryptoQuotesResponse, UsAssetsResponse, UsAssetDetail, UsQuotesResponse, UsFilingsResponse, DividendsResponse, DocumentSearchResponse, DocumentsResponse, EtfListResponse, EtfProfile, ExpectationsResponse, Fii, FiiDistributionsResponse, FiiIndicatorsResponse, FiiReportsResponse, FiiScreenResponse, FundHoldersResponse, FundHoldingsResponse, FundListResponse, FundProfile, FundQuotesResponse, FundScreenerResponse, HealthResponse, IngestHealthResponse, IndexCompositionResponse, IndexMeta, IndexQuotesResponse, IndicatorHistoryResponse, IntradaySeriesResponse, LiveQuotesResponse, BdrListResponse, BdrProfile, BdrQuotesResponse, InsiderResponse, InvestorFlowMonthlyResponse, InvestorFlowResponse, MacroGearsResponse, OfferingsResponse, OptionExpiriesResponse, OptionsChainResponse, OptionsQuotesResponse, PortfolioResponse, CommunityBotsResponse, CommunityBotPostInput, CommunityBotPostResponse, CommunityBotReplyResponse, CommunityFeedParams, CommunityFeedResponse, CommunityPostResponse, RegisterCommunityBotInput, RegisterCommunityBotResponse, QuotesResponse, RangeParams, RegimeSnapshot, ScreenStocksResponse, SearchDocumentsParams, SearchResult, SeriesResponse, Stock, StockIndicatorsResponse, SuitabilityResponse, TesouroBondsResponse, TradeStatsResponse, YieldCurveResponse } from "./types";
3
3
  /**
4
4
  * Cliente HTTP da Serving API do DataBolsa. Os métodos públicos espelham os
5
5
  * operationIds do OpenAPI e retornam tipos gerados.
@@ -22,6 +22,8 @@ export declare class HttpClient implements DataBolsaClient {
22
22
  private readonly getToken?;
23
23
  constructor(baseUrl: string, opts?: HttpClientOptions);
24
24
  private request;
25
+ /** Como `request`, mas p/ respostas de TEXTO (ex.: o template CSV de import). */
26
+ private requestText;
25
27
  /** Extrai `detail`/`title` de um application/problem+json, se houver. */
26
28
  private problemDetail;
27
29
  getHealth(): Promise<HealthResponse>;
@@ -135,10 +137,34 @@ export declare class HttpClient implements DataBolsaClient {
135
137
  getMacroGears(params?: {
136
138
  gear?: string;
137
139
  }): Promise<MacroGearsResponse>;
140
+ listCrypto(params?: {
141
+ search?: string;
142
+ limit?: number;
143
+ cursor?: string;
144
+ }): Promise<CryptoListResponse>;
145
+ getCrypto(symbol: string): Promise<CryptoAsset>;
146
+ listCryptoLive(): Promise<CryptoLiveResponse>;
138
147
  listCryptoQuotes(symbol: string, params?: RangeParams & {
139
148
  interval?: "1d" | "1h";
140
149
  limit?: number;
141
150
  }): Promise<CryptoQuotesResponse>;
151
+ listUsAssets(params?: {
152
+ search?: string;
153
+ type?: "stock" | "etf";
154
+ bdr?: string;
155
+ limit?: number;
156
+ cursor?: string;
157
+ }): Promise<UsAssetsResponse>;
158
+ getUsAsset(ticker: string): Promise<UsAssetDetail>;
159
+ listUsAssetQuotes(ticker: string, params?: RangeParams & {
160
+ limit?: number;
161
+ cursor?: string;
162
+ }): Promise<UsQuotesResponse>;
163
+ listUsFilings(ticker: string, params?: {
164
+ form?: string;
165
+ limit?: number;
166
+ cursor?: string;
167
+ }): Promise<UsFilingsResponse>;
142
168
  listOptionsChain(underlying: string, params?: {
143
169
  expiry?: string;
144
170
  type?: "call" | "put";
@@ -173,4 +199,31 @@ export declare class HttpClient implements DataBolsaClient {
173
199
  createCommunityBotReply(handle: string, postId: string, body: string): Promise<CommunityBotReplyResponse>;
174
200
  getCommunityFeed(params?: CommunityFeedParams): Promise<CommunityFeedResponse>;
175
201
  getCommunityPost(id: string): Promise<CommunityPostResponse>;
202
+ getPortfolioHistory(): Promise<PortfolioHistoryResponse>;
203
+ listPortfolios(): Promise<PortfoliosResponse>;
204
+ createPortfolio(name: string, visibility?: "private" | "unlisted" | "public"): Promise<CreatePortfolioResponse>;
205
+ getPortfolioDetail(id: string): Promise<PortfolioDetail>;
206
+ updatePortfolio(id: string, patch: PortfolioPatch): Promise<unknown>;
207
+ deletePortfolio(id: string): Promise<{
208
+ deleted?: boolean;
209
+ }>;
210
+ getPortfolioHistoryById(id: string): Promise<PortfolioHistoryResponse>;
211
+ addPortfolioAsset(id: string, asset: PortfolioAssetRef): Promise<unknown>;
212
+ removePortfolioAsset(id: string, asset: PortfolioAssetRef): Promise<unknown>;
213
+ updatePortfolioAsset(id: string, asset: PortfolioAssetRef, rf: PortfolioRfContract): Promise<unknown>;
214
+ listPortfolioTransactions(id: string, asset: PortfolioAssetRef): Promise<PortfolioTransactionsResponse>;
215
+ addPortfolioTransaction(id: string, asset: PortfolioAssetRef, tx: PortfolioTransactionInput): Promise<AddPortfolioTransactionResponse>;
216
+ updatePortfolioTransaction(id: string, txId: string, patch: PortfolioTransactionPatch): Promise<PortfolioTransaction>;
217
+ deletePortfolioTransaction(id: string, txId: string): Promise<{
218
+ deleted?: boolean;
219
+ }>;
220
+ importPortfolioFile(id: string, input: PortfolioImportInput): Promise<PortfolioImportSummary>;
221
+ listPortfolioImports(id: string): Promise<PortfolioImportsResponse>;
222
+ listPortfolioImportRows(id: string, importId: string, params?: {
223
+ status?: "imported" | "ignored" | "duplicate" | "error";
224
+ limit?: number;
225
+ offset?: number;
226
+ }): Promise<PortfolioImportRowsResponse>;
227
+ getPortfolioImportTemplate(): Promise<string>;
228
+ reconcilePortfolioAsset(id: string, asset: PortfolioAssetRef, targetQty: number, asOf: string): Promise<unknown>;
176
229
  }
package/dist/index.js CHANGED
@@ -51,6 +51,26 @@ class HttpClient {
51
51
  const detail = await this.problemDetail(res);
52
52
  throw new Error(`API ${res.status} em ${path}${detail ? `: ${detail}` : ""}`);
53
53
  }
54
+ async requestText(path) {
55
+ const url = new URL(this.base + path);
56
+ const headers = { accept: "text/csv, text/plain" };
57
+ const token = this.getToken?.();
58
+ if (token)
59
+ headers.authorization = `Bearer ${token}`;
60
+ let res;
61
+ try {
62
+ res = await fetch(url, { headers });
63
+ } catch (cause) {
64
+ throw new Error(`Falha de rede ao chamar ${path}`, { cause });
65
+ }
66
+ if (res.ok)
67
+ return res.text();
68
+ if (res.status === 501 || res.status === 404) {
69
+ throw new NotInPreviewError(decodeURIComponent(path.replace(/^\//, "")));
70
+ }
71
+ const detail = await this.problemDetail(res);
72
+ throw new Error(`API ${res.status} em ${path}${detail ? `: ${detail}` : ""}`);
73
+ }
54
74
  async problemDetail(res) {
55
75
  try {
56
76
  const body = await res.json();
@@ -316,6 +336,19 @@ class HttpClient {
316
336
  getMacroGears(params) {
317
337
  return this.request("/macro/gears", { gear: params?.gear });
318
338
  }
339
+ listCrypto(params) {
340
+ return this.request("/crypto", {
341
+ search: params?.search,
342
+ limit: params?.limit,
343
+ cursor: params?.cursor
344
+ });
345
+ }
346
+ getCrypto(symbol) {
347
+ return this.request(`/crypto/${enc(symbol)}`);
348
+ }
349
+ listCryptoLive() {
350
+ return this.request("/crypto/live");
351
+ }
319
352
  listCryptoQuotes(symbol, params) {
320
353
  return this.request(`/crypto/${enc(symbol)}/quotes`, {
321
354
  interval: params?.interval,
@@ -324,6 +357,33 @@ class HttpClient {
324
357
  limit: params?.limit
325
358
  });
326
359
  }
360
+ listUsAssets(params) {
361
+ return this.request("/us/assets", {
362
+ search: params?.search,
363
+ type: params?.type,
364
+ bdr: params?.bdr,
365
+ limit: params?.limit,
366
+ cursor: params?.cursor
367
+ });
368
+ }
369
+ getUsAsset(ticker) {
370
+ return this.request(`/us/assets/${enc(ticker)}`);
371
+ }
372
+ listUsAssetQuotes(ticker, params) {
373
+ return this.request(`/us/assets/${enc(ticker)}/quotes`, {
374
+ from: params?.from,
375
+ to: params?.to,
376
+ limit: params?.limit,
377
+ cursor: params?.cursor
378
+ });
379
+ }
380
+ listUsFilings(ticker, params) {
381
+ return this.request(`/us/assets/${enc(ticker)}/filings`, {
382
+ form: params?.form,
383
+ limit: params?.limit,
384
+ cursor: params?.cursor
385
+ });
386
+ }
327
387
  listOptionsChain(underlying, params) {
328
388
  return this.request(`/options/${enc(underlying)}/chain`, {
329
389
  expiry: params?.expiry,
@@ -413,6 +473,108 @@ class HttpClient {
413
473
  getCommunityPost(id) {
414
474
  return this.request(`/community/posts/${enc(id)}`);
415
475
  }
476
+ getPortfolioHistory() {
477
+ return this.request("/portfolio/history");
478
+ }
479
+ listPortfolios() {
480
+ return this.request("/portfolios");
481
+ }
482
+ createPortfolio(name, visibility) {
483
+ return this.request("/portfolios", undefined, { method: "POST", body: { name, visibility } });
484
+ }
485
+ getPortfolioDetail(id) {
486
+ return this.request(`/portfolios/${enc(id)}`);
487
+ }
488
+ updatePortfolio(id, patch) {
489
+ return this.request(`/portfolios/${enc(id)}`, undefined, {
490
+ method: "PATCH",
491
+ body: { name: patch.name, visibility: patch.visibility, exclude_from_consolidated: patch.excludeFromConsolidated }
492
+ });
493
+ }
494
+ deletePortfolio(id) {
495
+ return this.request(`/portfolios/${enc(id)}`, undefined, { method: "DELETE" });
496
+ }
497
+ getPortfolioHistoryById(id) {
498
+ return this.request(`/portfolios/${enc(id)}/history`);
499
+ }
500
+ addPortfolioAsset(id, asset) {
501
+ return this.request(`/portfolios/${enc(id)}/assets`, undefined, {
502
+ method: "POST",
503
+ body: { asset_type: asset.assetType, symbol: asset.symbol }
504
+ });
505
+ }
506
+ removePortfolioAsset(id, asset) {
507
+ return this.request(`/portfolios/${enc(id)}/assets`, { asset_type: asset.assetType, symbol: asset.symbol }, { method: "DELETE" });
508
+ }
509
+ updatePortfolioAsset(id, asset, rf) {
510
+ return this.request(`/portfolios/${enc(id)}/assets`, { asset_type: asset.assetType, symbol: asset.symbol }, { method: "PATCH", body: { rf_indexer: rf.indexer, rf_rate: rf.rate } });
511
+ }
512
+ listPortfolioTransactions(id, asset) {
513
+ return this.request(`/portfolios/${enc(id)}/transactions`, {
514
+ asset_type: asset.assetType,
515
+ symbol: asset.symbol
516
+ });
517
+ }
518
+ addPortfolioTransaction(id, asset, tx) {
519
+ return this.request(`/portfolios/${enc(id)}/transactions`, undefined, {
520
+ method: "POST",
521
+ body: {
522
+ asset_type: asset.assetType,
523
+ symbol: asset.symbol,
524
+ kind: tx.kind,
525
+ trade_date: tx.tradeDate,
526
+ quantity: tx.quantity,
527
+ price: tx.price,
528
+ fees: tx.fees,
529
+ ratio: tx.ratio,
530
+ note: tx.note
531
+ }
532
+ });
533
+ }
534
+ updatePortfolioTransaction(id, txId, patch) {
535
+ return this.request(`/portfolios/${enc(id)}/transactions/${enc(txId)}`, undefined, {
536
+ method: "PATCH",
537
+ body: {
538
+ kind: patch.kind,
539
+ trade_date: patch.tradeDate,
540
+ quantity: patch.quantity,
541
+ price: patch.price,
542
+ fees: patch.fees,
543
+ ratio: patch.ratio,
544
+ note: patch.note
545
+ }
546
+ });
547
+ }
548
+ deletePortfolioTransaction(id, txId) {
549
+ return this.request(`/portfolios/${enc(id)}/transactions/${enc(txId)}`, undefined, {
550
+ method: "DELETE"
551
+ });
552
+ }
553
+ importPortfolioFile(id, input) {
554
+ return this.request(`/portfolios/${enc(id)}/imports`, undefined, {
555
+ method: "POST",
556
+ body: { content_base64: input.contentBase64, filename: input.filename }
557
+ });
558
+ }
559
+ listPortfolioImports(id) {
560
+ return this.request(`/portfolios/${enc(id)}/imports`);
561
+ }
562
+ listPortfolioImportRows(id, importId, params) {
563
+ return this.request(`/portfolios/${enc(id)}/imports/${enc(importId)}/rows`, {
564
+ status: params?.status,
565
+ limit: params?.limit,
566
+ offset: params?.offset
567
+ });
568
+ }
569
+ getPortfolioImportTemplate() {
570
+ return this.requestText("/portfolios/import-template");
571
+ }
572
+ reconcilePortfolioAsset(id, asset, targetQty, asOf) {
573
+ return this.request(`/portfolios/${enc(id)}/reconcile`, undefined, {
574
+ method: "POST",
575
+ body: { asset_type: asset.assetType, symbol: asset.symbol, target_qty: targetQty, as_of: asOf }
576
+ });
577
+ }
416
578
  }
417
579
  function enc(segment) {
418
580
  return encodeURIComponent(segment);