@databolsa/sdk 1.0.0 → 1.0.2

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/README.md CHANGED
@@ -1,56 +1,98 @@
1
1
  # @databolsa/sdk
2
2
 
3
- SDK TypeScript tipado sobre a Serving API aberta do DataBolsa. **Casca fina e
4
- agnóstica** — sem React, sem dependências de runtime: o `HttpClient` fala com a
5
- API pelo contrato `api/openapi.yaml` usando o `fetch` nativo, com Bearer
6
- opcional e degradação graciosa (501/404 → `NotInPreviewError`).
3
+ [![npm version](https://img.shields.io/npm/v/@databolsa/sdk?color=cb3837&logo=npm)](https://www.npmjs.com/package/@databolsa/sdk)
4
+ [![license](https://img.shields.io/npm/l/@databolsa/sdk?color=2ea44f)](https://github.com/databolsahq/databolsa/blob/main/LICENSE)
7
5
 
8
- É a mesma "pegada" do `packages/mcp` e do `packages/cli` (dirigido pelo
9
- contrato, sem lógica de negócio), só que aqui a superfície é **tipada em tempo
10
- de compilação**: os tipos vêm do contrato via `openapi-typescript`. Quem
11
- consome monta a própria camada por cima — o app web envolve em hooks React
12
- Query (`apps/web/lib/queries.ts`); um script Node usa direto.
6
+ SDK TypeScript tipado para a Serving API pública do DataBolsa.
13
7
 
14
- ## Uso
8
+ O DataBolsa oferece infraestrutura aberta e reprodutível de dados para o mercado
9
+ financeiro brasileiro: ações, FIIs, índices, séries macro, renda fixa, BDRs,
10
+ opções, cripto e busca. O SDK é uma casca fina sobre o contrato OpenAPI. Ele não
11
+ calcula indicadores financeiros no cliente.
12
+
13
+ ## Instalação
14
+
15
+ ```bash
16
+ npm install @databolsa/sdk
17
+ ```
18
+
19
+ ## Uso Rápido
15
20
 
16
21
  ```ts
17
- import { DataBolsa } from "@databolsa/sdk";
18
- import type { Stock, QuotesResponse } from "@databolsa/sdk";
22
+ import { DataBolsa, NotInPreviewError } from "@databolsa/sdk";
23
+ import type { QuotesResponse, Stock } from "@databolsa/sdk";
24
+
25
+ const db = new DataBolsa("https://api.databolsa.com", {
26
+ apiKey: process.env.DATABOLSA_API_KEY,
27
+ });
28
+
29
+ try {
30
+ const stock: Stock = await db.getStock("PETR4");
31
+ const quotes: QuotesResponse = await db.listQuotes("PETR4", {
32
+ from: "2024-01-01",
33
+ limit: 30,
34
+ });
35
+
36
+ console.log(stock.company?.name, quotes.data.length);
37
+ } catch (err) {
38
+ if (err instanceof NotInPreviewError) {
39
+ console.warn(err.message);
40
+ } else {
41
+ throw err;
42
+ }
43
+ }
44
+ ```
45
+
46
+ `DataBolsa` é um alias de `HttpClient`.
47
+
48
+ ## Configuração
19
49
 
20
- const db = new DataBolsa("http://localhost:8081", { apiKey: process.env.DATABOLSA_API_KEY });
50
+ Use um `baseUrl` absoluto em Node ou no servidor:
21
51
 
22
- const s: Stock = await db.getStock("PETR4");
23
- const q: QuotesResponse = await db.listQuotes("PETR4", { from: "2024-01-01", limit: 30 });
52
+ ```ts
53
+ const db = new DataBolsa("https://api.databolsa.com");
24
54
  ```
25
55
 
26
- `DataBolsa` é um alias de `HttpClient`. O `baseUrl` pode ser:
56
+ Use um `baseUrl` relativo apenas em apps browser que fazem proxy de `/v1` para a
57
+ API a partir da mesma origem:
27
58
 
28
- - **absoluto** (`http://…`) → chamada direta (cross-origin, exige CORS);
29
- - **relativo** (`/`) mesma origem (browser + proxy do Next) — usado pelo web.
59
+ ```ts
60
+ const db = new DataBolsa("/");
61
+ ```
30
62
 
31
- Rotas ainda não servidas lançam `NotInPreviewError` (a mesma exceção que a UI
32
- sabe exibir), em vez de estourar.
63
+ Autenticação é opcional em implantações abertas. Se você usar uma chave de API,
64
+ mantenha a chave no servidor e passe por `apiKey` ou `getToken`.
33
65
 
34
66
  ## Tipos
35
67
 
36
- - Tipos de domínio e de resposta: `Stock`, `Fii`, `QuotesResponse`,
37
- `StockIndicatorsResponse`, `RegimeSnapshot`, (derivados do contrato).
38
- - Crus do OpenAPI: `paths`, `components`, `operations` (de `@databolsa/sdk`).
68
+ O pacote exporta tipos de domínio e de resposta gerados do contrato OpenAPI,
69
+ incluindo `Stock`, `Fii`, `QuotesResponse`, `ScreenStocksResponse`,
70
+ `RegimeSnapshot`, `YieldCurveResponse` e outros.
71
+
72
+ Também exporta os tipos brutos do OpenAPI: `paths`, `components` e `operations`.
39
73
 
40
- Regenerar após mudar o contrato:
74
+ ## Erros
75
+
76
+ `NotInPreviewError` é lançado quando a API retorna 501 para um endpoint ainda não
77
+ servido ou 404 para um recurso ausente. Outros status não-2xx lançam um `Error`
78
+ com o status da API e o detalhe do problema quando disponível.
79
+
80
+ ## Pacotes Relacionados
81
+
82
+ A CLI e o MCP expõem o mesmo contrato da API em formatos diferentes:
41
83
 
42
84
  ```bash
43
- bun run gen:api # da raiz: gera openapi.yaml + schema do SDK
44
- # ou só o schema:
45
- bun run --cwd packages/sdk gen:schema
85
+ npm install -g @databolsa/cli
86
+ npx -y @databolsa/mcp
46
87
  ```
47
88
 
48
- ## Quem consome
89
+ ## Links
90
+
91
+ - OpenAPI: https://api.databolsa.com/openapi.json
92
+ - Fontes e cobertura: https://github.com/databolsahq/databolsa/blob/main/docs/sources.md
93
+ - Metodologia dos indicadores: https://github.com/databolsahq/databolsa/blob/main/docs/indicators.md
94
+ - Limitações conhecidas: https://github.com/databolsahq/databolsa/blob/main/docs/limitations.md
49
95
 
50
- - **apps/web** — `HttpClient` (ao vivo) ao lado do `FixtureClient` (demo);
51
- `getClient()` troca por env. Componentes usam hooks React Query por cima.
52
- - Scripts Node / integrações externas — direto, tipado.
96
+ ## Licença
53
97
 
54
- > O `packages/cli` e o `packages/mcp` **não** usam este SDK: eles são dinâmicos
55
- > em runtime (leem o spec vivo e geram a superfície na hora), enquanto o SDK é
56
- > tipado em tempo de compilação. Mesma filosofia, mecânica oposta.
98
+ Apache-2.0. O DataBolsa é infraestrutura de dados, não recomendação de investimento.
@@ -0,0 +1,111 @@
1
+ import type { CorporateEventsResponse, CryptoQuotesResponse, DividendsResponse, DocumentsResponse, ExpectationsResponse, Fii, FiiDistributionsResponse, FiiIndicatorsResponse, FiiReportsResponse, FiiScreenResponse, HealthResponse, IngestHealthResponse, IndexCompositionResponse, IndexMeta, IndexQuotesResponse, IndicatorHistoryResponse, BdrListResponse, BdrProfile, BdrQuotesResponse, InsiderResponse, MacroGearsResponse, OptionExpiriesResponse, OptionsChainResponse, OptionsQuotesResponse, Query, QuotesResponse, RangeParams, RegimeSnapshot, ScreenStocksResponse, SearchResult, SeriesResponse, Stock, StockIndicatorsResponse, TesouroBondsResponse, YieldCurveResponse } from "./types";
2
+ /** Filtros do screener de ações — derivados de `GET /v1/screener/stocks`. */
3
+ export type ScreenStocksParams = Query<"screenStocks">;
4
+ /**
5
+ * Filtros do listing de FIIs — derivados de `GET /v1/screener/fiis`, com uma
6
+ * ergonomia: `paper` aceita `boolean` (o contrato pede `"true"`/`"false"`; o
7
+ * HttpClient serializa). true = papel, false = tijolo, undefined = todos.
8
+ */
9
+ export type ScreenFiisParams = Omit<Query<"screenFiis">, "paper"> & {
10
+ paper?: boolean;
11
+ };
12
+ /**
13
+ * Interface do cliente DataBolsa — métodos = operationIds do api/openapi.yaml.
14
+ * O SDK público implementa esta interface com HttpClient; apps podem envolver
15
+ * a interface com cache, hooks ou adaptadores próprios sem duplicar contrato.
16
+ */
17
+ export interface DataBolsaClient {
18
+ getHealth(): Promise<HealthResponse>;
19
+ /** Saúde da ingestão: última run + saúde por fonte + histórico (data lake). */
20
+ getIngestHealth(): Promise<IngestHealthResponse>;
21
+ /** Lista/filtra ações por fundamentos (o universo real, não o preview). */
22
+ screenStocks(params?: ScreenStocksParams): Promise<ScreenStocksResponse>;
23
+ getStock(ticker: string): Promise<Stock>;
24
+ listQuotes(ticker: string, params?: RangeParams & {
25
+ adjusted?: boolean;
26
+ limit?: number;
27
+ }): Promise<QuotesResponse>;
28
+ getStockIndicators(ticker: string, params?: {
29
+ at?: string;
30
+ }): Promise<StockIndicatorsResponse>;
31
+ getStockIndicatorHistory(ticker: string, name: string, params?: RangeParams): Promise<IndicatorHistoryResponse>;
32
+ listDividends(ticker: string, params?: RangeParams): Promise<DividendsResponse>;
33
+ listCorporateEvents(ticker: string, params?: RangeParams): Promise<CorporateEventsResponse>;
34
+ listCompanyDocuments(cvmCode: number, params?: RangeParams & {
35
+ category?: string;
36
+ }): Promise<DocumentsResponse>;
37
+ /** PENDÊNCIA DE CONTRATO — ver lib/api/types.ts (InsiderMove) */
38
+ listInsiderMoves(ticker: string, params?: RangeParams): Promise<InsiderResponse>;
39
+ /** Lista o universo real de FIIs (não o preview). */
40
+ screenFiis(params?: ScreenFiisParams): Promise<FiiScreenResponse>;
41
+ getFii(ticker: string): Promise<Fii>;
42
+ getFiiIndicators(ticker: string, params?: {
43
+ at?: string;
44
+ }): Promise<FiiIndicatorsResponse>;
45
+ /** Série mensal de um indicador de FII (mart_fii__reports) — mesmo shape do histórico de ações. */
46
+ getFiiIndicatorHistory(ticker: string, name: string, params?: RangeParams): Promise<IndicatorHistoryResponse>;
47
+ listFiiDistributions(ticker: string, params?: RangeParams): Promise<FiiDistributionsResponse>;
48
+ listFiiReports(ticker: string, params?: RangeParams): Promise<FiiReportsResponse>;
49
+ listIndices(): Promise<IndexMeta[]>;
50
+ listIndexQuotes(code: string, params?: RangeParams & {
51
+ limit?: number;
52
+ }): Promise<IndexQuotesResponse>;
53
+ getIndexComposition(code: string): Promise<IndexCompositionResponse>;
54
+ getSeries(source: string, seriesId: string, params?: RangeParams & {
55
+ accumulated?: "none" | "12m" | "ytd";
56
+ }): Promise<SeriesResponse>;
57
+ getYieldCurve(params?: {
58
+ kind?: "nominal" | "real";
59
+ }): Promise<YieldCurveResponse>;
60
+ listTesouroBonds(params?: {
61
+ type?: string;
62
+ maturity?: string;
63
+ date?: string;
64
+ limit?: number;
65
+ }): Promise<TesouroBondsResponse>;
66
+ getMarketExpectations(indicator: "ipca" | "selic" | "pib" | "cambio", params?: {
67
+ reference?: string;
68
+ } & RangeParams): Promise<ExpectationsResponse>;
69
+ getMacroRegime(params?: {
70
+ at?: string;
71
+ }): Promise<RegimeSnapshot>;
72
+ getMacroGears(params?: {
73
+ gear?: string;
74
+ }): Promise<MacroGearsResponse>;
75
+ listCryptoQuotes(symbol: string, params?: RangeParams & {
76
+ interval?: "1d" | "1h";
77
+ limit?: number;
78
+ }): Promise<CryptoQuotesResponse>;
79
+ /** Cadeia viva de um subjacente (séries não vencidas, mais negociadas). Filtra por vencimento/tipo. */
80
+ listOptionsChain(underlying: string, params?: {
81
+ expiry?: string;
82
+ type?: "call" | "put";
83
+ }): Promise<OptionsChainResponse>;
84
+ /** Vencimentos distintos disponíveis para um subjacente (com contagem de séries). */
85
+ listOptionExpiries(underlying: string): Promise<OptionExpiriesResponse>;
86
+ /** Histórico EOD de UMA série de opção (paginado; só europeu). */
87
+ listOptionQuotes(optionTicker: string, params?: RangeParams & {
88
+ limit?: number;
89
+ cursor?: string;
90
+ }): Promise<OptionsQuotesResponse>;
91
+ /** Catálogo de BDRs (paginado; busca por ticker/nome). */
92
+ listBdrs(params?: {
93
+ search?: string;
94
+ limit?: number;
95
+ cursor?: string;
96
+ }): Promise<BdrListResponse>;
97
+ getBdr(ticker: string): Promise<BdrProfile>;
98
+ /** Histórico EOD de um BDR em BRL (paginado). */
99
+ listBdrQuotes(ticker: string, params?: RangeParams & {
100
+ limit?: number;
101
+ cursor?: string;
102
+ }): Promise<BdrQuotesResponse>;
103
+ /** Busca unificada (ações, FIIs, índices, títulos, séries macro) — backed o Cmd+K. */
104
+ search(q: string, params?: {
105
+ limit?: number;
106
+ }): Promise<SearchResult[]>;
107
+ }
108
+ export declare class NotInPreviewError extends Error {
109
+ readonly entity: string;
110
+ constructor(entity: string);
111
+ }
@@ -0,0 +1,105 @@
1
+ import { type DataBolsaClient, type ScreenFiisParams, type ScreenStocksParams } from "./client";
2
+ import type { CorporateEventsResponse, CryptoQuotesResponse, DividendsResponse, DocumentsResponse, ExpectationsResponse, Fii, FiiDistributionsResponse, FiiIndicatorsResponse, FiiReportsResponse, FiiScreenResponse, HealthResponse, IngestHealthResponse, IndexCompositionResponse, IndexMeta, IndexQuotesResponse, IndicatorHistoryResponse, BdrListResponse, BdrProfile, BdrQuotesResponse, InsiderResponse, MacroGearsResponse, OptionExpiriesResponse, OptionsChainResponse, OptionsQuotesResponse, QuotesResponse, RangeParams, RegimeSnapshot, ScreenStocksResponse, SearchResult, SeriesResponse, Stock, StockIndicatorsResponse, TesouroBondsResponse, YieldCurveResponse } from "./types";
3
+ /**
4
+ * Cliente HTTP da Serving API do DataBolsa. Os métodos públicos espelham os
5
+ * operationIds do OpenAPI e retornam tipos gerados.
6
+ *
7
+ * Degradação graciosa: 501 (endpoint ainda não servido) e 404 (recurso não
8
+ * encontrado) viram {@link NotInPreviewError}; outros status não-2xx lançam
9
+ * Error.
10
+ *
11
+ * `baseUrl` pode ser uma origem absoluta para Node/servidor ou uma base
12
+ * relativa de mesma origem em apps browser que fazem proxy de `/v1` para a API.
13
+ */
14
+ export interface HttpClientOptions {
15
+ /** Token bearer a anexar (opcional). Hoje a API de dev é aberta. */
16
+ getToken?: () => string | null | undefined;
17
+ /** Chave estática (atalho p/ Node/CLI). Ignorada se `getToken` for passada. */
18
+ apiKey?: string | null;
19
+ }
20
+ export declare class HttpClient implements DataBolsaClient {
21
+ private readonly base;
22
+ private readonly getToken?;
23
+ constructor(baseUrl: string, opts?: HttpClientOptions);
24
+ private request;
25
+ /** Extrai `detail`/`title` de um application/problem+json, se houver. */
26
+ private problemDetail;
27
+ getHealth(): Promise<HealthResponse>;
28
+ getIngestHealth(): Promise<IngestHealthResponse>;
29
+ screenStocks(params?: ScreenStocksParams): Promise<ScreenStocksResponse>;
30
+ getStock(ticker: string): Promise<Stock>;
31
+ listQuotes(ticker: string, params?: RangeParams & {
32
+ adjusted?: boolean;
33
+ limit?: number;
34
+ }): Promise<QuotesResponse>;
35
+ getStockIndicators(ticker: string, params?: {
36
+ at?: string;
37
+ }): Promise<StockIndicatorsResponse>;
38
+ getStockIndicatorHistory(ticker: string, name: string, params?: RangeParams): Promise<IndicatorHistoryResponse>;
39
+ listDividends(ticker: string, params?: RangeParams): Promise<DividendsResponse>;
40
+ listCorporateEvents(ticker: string, params?: RangeParams): Promise<CorporateEventsResponse>;
41
+ listCompanyDocuments(cvmCode: number, params?: RangeParams & {
42
+ category?: string;
43
+ }): Promise<DocumentsResponse>;
44
+ listInsiderMoves(ticker: string, params?: RangeParams): Promise<InsiderResponse>;
45
+ screenFiis(params?: ScreenFiisParams): Promise<FiiScreenResponse>;
46
+ getFii(ticker: string): Promise<Fii>;
47
+ getFiiIndicators(ticker: string, params?: {
48
+ at?: string;
49
+ }): Promise<FiiIndicatorsResponse>;
50
+ getFiiIndicatorHistory(ticker: string, name: string, params?: RangeParams): Promise<IndicatorHistoryResponse>;
51
+ listFiiDistributions(ticker: string, params?: RangeParams): Promise<FiiDistributionsResponse>;
52
+ listFiiReports(ticker: string, params?: RangeParams): Promise<FiiReportsResponse>;
53
+ listIndices(): Promise<IndexMeta[]>;
54
+ listIndexQuotes(code: string, params?: RangeParams & {
55
+ limit?: number;
56
+ }): Promise<IndexQuotesResponse>;
57
+ getIndexComposition(code: string): Promise<IndexCompositionResponse>;
58
+ getSeries(source: string, seriesId: string, params?: RangeParams & {
59
+ accumulated?: "none" | "12m" | "ytd";
60
+ }): Promise<SeriesResponse>;
61
+ getYieldCurve(params?: {
62
+ kind?: "nominal" | "real";
63
+ }): Promise<YieldCurveResponse>;
64
+ listTesouroBonds(params?: {
65
+ type?: string;
66
+ maturity?: string;
67
+ date?: string;
68
+ limit?: number;
69
+ }): Promise<TesouroBondsResponse>;
70
+ getMarketExpectations(indicator: "ipca" | "selic" | "pib" | "cambio", params?: {
71
+ reference?: string;
72
+ } & RangeParams): Promise<ExpectationsResponse>;
73
+ getMacroRegime(params?: {
74
+ at?: string;
75
+ }): Promise<RegimeSnapshot>;
76
+ getMacroGears(params?: {
77
+ gear?: string;
78
+ }): Promise<MacroGearsResponse>;
79
+ listCryptoQuotes(symbol: string, params?: RangeParams & {
80
+ interval?: "1d" | "1h";
81
+ limit?: number;
82
+ }): Promise<CryptoQuotesResponse>;
83
+ listOptionsChain(underlying: string, params?: {
84
+ expiry?: string;
85
+ type?: "call" | "put";
86
+ }): Promise<OptionsChainResponse>;
87
+ listOptionExpiries(underlying: string): Promise<OptionExpiriesResponse>;
88
+ listOptionQuotes(optionTicker: string, params?: RangeParams & {
89
+ limit?: number;
90
+ cursor?: string;
91
+ }): Promise<OptionsQuotesResponse>;
92
+ listBdrs(params?: {
93
+ search?: string;
94
+ limit?: number;
95
+ cursor?: string;
96
+ }): Promise<BdrListResponse>;
97
+ getBdr(ticker: string): Promise<BdrProfile>;
98
+ listBdrQuotes(ticker: string, params?: RangeParams & {
99
+ limit?: number;
100
+ cursor?: string;
101
+ }): Promise<BdrQuotesResponse>;
102
+ search(q: string, params?: {
103
+ limit?: number;
104
+ }): Promise<SearchResult[]>;
105
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `@databolsa/sdk` - cliente TypeScript tipado da Serving API pública.
3
+ *
4
+ * Casca fina e agnóstica de runtime: o `HttpClient` implementa
5
+ * {@link DataBolsaClient} sobre o `fetch` nativo, com Bearer opcional e
6
+ * 501/404 mapeados para {@link NotInPreviewError}. Os tipos são gerados do
7
+ * contrato OpenAPI.
8
+ */
9
+ export { HttpClient, HttpClient as DataBolsa } from "./http-client";
10
+ export type { HttpClientOptions } from "./http-client";
11
+ export { NotInPreviewError } from "./client";
12
+ export type { DataBolsaClient, ScreenStocksParams, ScreenFiisParams } from "./client";
13
+ export type * from "./types";
14
+ export type { paths, components, operations } from "./schema";
package/dist/index.js ADDED
@@ -0,0 +1,260 @@
1
+ // src/client.ts
2
+ class NotInPreviewError extends Error {
3
+ entity;
4
+ constructor(entity) {
5
+ super(`"${entity}" não está disponível na API DataBolsa atual.`);
6
+ this.entity = entity;
7
+ this.name = "NotInPreviewError";
8
+ }
9
+ }
10
+
11
+ // src/http-client.ts
12
+ class HttpClient {
13
+ base;
14
+ getToken;
15
+ constructor(baseUrl, opts = {}) {
16
+ const isAbsolute = /^https?:\/\//i.test(baseUrl);
17
+ const loc = globalThis.location;
18
+ const origin = isAbsolute ? baseUrl.replace(/\/+$/, "") : loc?.origin ?? "";
19
+ this.base = `${origin}/v1`;
20
+ this.getToken = opts.getToken ?? (opts.apiKey ? () => opts.apiKey : undefined);
21
+ }
22
+ async request(path, query) {
23
+ const url = new URL(this.base + path);
24
+ if (query) {
25
+ for (const [k, v] of Object.entries(query)) {
26
+ if (v !== undefined && v !== null && v !== "")
27
+ url.searchParams.set(k, String(v));
28
+ }
29
+ }
30
+ const headers = { accept: "application/json" };
31
+ const token = this.getToken?.();
32
+ if (token)
33
+ headers.authorization = `Bearer ${token}`;
34
+ let res;
35
+ try {
36
+ res = await fetch(url, { headers });
37
+ } catch (cause) {
38
+ throw new Error(`Falha de rede ao chamar ${path}`, { cause });
39
+ }
40
+ if (res.ok)
41
+ return await res.json();
42
+ if (res.status === 501 || res.status === 404) {
43
+ throw new NotInPreviewError(decodeURIComponent(path.replace(/^\//, "")));
44
+ }
45
+ const detail = await this.problemDetail(res);
46
+ throw new Error(`API ${res.status} em ${path}${detail ? `: ${detail}` : ""}`);
47
+ }
48
+ async problemDetail(res) {
49
+ try {
50
+ const body = await res.json();
51
+ return body.detail ?? body.title ?? null;
52
+ } catch {
53
+ return null;
54
+ }
55
+ }
56
+ getHealth() {
57
+ return this.request("/health");
58
+ }
59
+ getIngestHealth() {
60
+ return this.request("/ingest");
61
+ }
62
+ screenStocks(params) {
63
+ return this.request("/screener/stocks", {
64
+ sector: params?.sector,
65
+ segment: params?.segment,
66
+ sort: params?.sort,
67
+ limit: params?.limit,
68
+ cursor: params?.cursor,
69
+ pl_min: params?.pl_min,
70
+ pl_max: params?.pl_max,
71
+ pvp_min: params?.pvp_min,
72
+ pvp_max: params?.pvp_max,
73
+ dy_min: params?.dy_min,
74
+ roe_min: params?.roe_min,
75
+ ev_ebitda_max: params?.ev_ebitda_max,
76
+ div_liq_ebitda_max: params?.div_liq_ebitda_max
77
+ });
78
+ }
79
+ getStock(ticker) {
80
+ return this.request(`/stocks/${enc(ticker)}`);
81
+ }
82
+ listQuotes(ticker, params) {
83
+ return this.request(`/stocks/${enc(ticker)}/quotes`, {
84
+ from: params?.from,
85
+ to: params?.to,
86
+ limit: params?.limit,
87
+ adjusted: params?.adjusted === false ? "false" : undefined
88
+ });
89
+ }
90
+ getStockIndicators(ticker, params) {
91
+ return this.request(`/stocks/${enc(ticker)}/indicators`, {
92
+ at: params?.at
93
+ });
94
+ }
95
+ getStockIndicatorHistory(ticker, name, params) {
96
+ return this.request(`/stocks/${enc(ticker)}/indicators/history`, {
97
+ name,
98
+ from: params?.from,
99
+ to: params?.to
100
+ });
101
+ }
102
+ listDividends(ticker, params) {
103
+ return this.request(`/stocks/${enc(ticker)}/dividends`, {
104
+ from: params?.from,
105
+ to: params?.to
106
+ });
107
+ }
108
+ listCorporateEvents(ticker, params) {
109
+ return this.request(`/stocks/${enc(ticker)}/events`, {
110
+ from: params?.from,
111
+ to: params?.to
112
+ });
113
+ }
114
+ listCompanyDocuments(cvmCode, params) {
115
+ return this.request(`/companies/${cvmCode}/documents`, {
116
+ from: params?.from,
117
+ to: params?.to,
118
+ category: params?.category
119
+ });
120
+ }
121
+ listInsiderMoves(ticker, params) {
122
+ return this.request(`/stocks/${enc(ticker)}/insider`, {
123
+ from: params?.from,
124
+ to: params?.to
125
+ });
126
+ }
127
+ screenFiis(params) {
128
+ return this.request("/screener/fiis", {
129
+ segment: params?.segment,
130
+ paper: params?.paper === undefined ? undefined : String(params.paper),
131
+ sort: params?.sort,
132
+ limit: params?.limit,
133
+ cursor: params?.cursor
134
+ });
135
+ }
136
+ getFii(ticker) {
137
+ return this.request(`/fiis/${enc(ticker)}`);
138
+ }
139
+ getFiiIndicators(ticker, params) {
140
+ return this.request(`/fiis/${enc(ticker)}/indicators`, { at: params?.at });
141
+ }
142
+ getFiiIndicatorHistory(ticker, name, params) {
143
+ return this.request(`/fiis/${enc(ticker)}/indicators/history`, {
144
+ name,
145
+ from: params?.from,
146
+ to: params?.to
147
+ });
148
+ }
149
+ listFiiDistributions(ticker, params) {
150
+ return this.request(`/fiis/${enc(ticker)}/distributions`, {
151
+ from: params?.from,
152
+ to: params?.to
153
+ });
154
+ }
155
+ listFiiReports(ticker, params) {
156
+ return this.request(`/fiis/${enc(ticker)}/reports`, {
157
+ from: params?.from,
158
+ to: params?.to
159
+ });
160
+ }
161
+ listIndices() {
162
+ return this.request("/indices");
163
+ }
164
+ listIndexQuotes(code, params) {
165
+ return this.request(`/indices/${enc(code)}/quotes`, {
166
+ from: params?.from,
167
+ to: params?.to,
168
+ limit: params?.limit
169
+ });
170
+ }
171
+ getIndexComposition(code) {
172
+ return this.request(`/indices/${enc(code)}/composition`);
173
+ }
174
+ getSeries(source, seriesId, params) {
175
+ return this.request(`/series/${enc(source)}/${enc(seriesId)}`, {
176
+ from: params?.from,
177
+ to: params?.to,
178
+ accumulated: params?.accumulated
179
+ });
180
+ }
181
+ getYieldCurve(params) {
182
+ return this.request("/bonds/tesouro/yield-curve", { kind: params?.kind });
183
+ }
184
+ listTesouroBonds(params) {
185
+ return this.request("/bonds/tesouro", {
186
+ type: params?.type,
187
+ maturity: params?.maturity,
188
+ date: params?.date,
189
+ limit: params?.limit
190
+ });
191
+ }
192
+ getMarketExpectations(indicator, params) {
193
+ return this.request("/macro/expectations", {
194
+ indicator,
195
+ reference: params?.reference,
196
+ from: params?.from,
197
+ to: params?.to
198
+ });
199
+ }
200
+ getMacroRegime(params) {
201
+ return this.request("/macro/regime", { at: params?.at });
202
+ }
203
+ getMacroGears(params) {
204
+ return this.request("/macro/gears", { gear: params?.gear });
205
+ }
206
+ listCryptoQuotes(symbol, params) {
207
+ return this.request(`/crypto/${enc(symbol)}/quotes`, {
208
+ interval: params?.interval,
209
+ from: params?.from,
210
+ to: params?.to,
211
+ limit: params?.limit
212
+ });
213
+ }
214
+ listOptionsChain(underlying, params) {
215
+ return this.request(`/options/${enc(underlying)}/chain`, {
216
+ expiry: params?.expiry,
217
+ type: params?.type
218
+ });
219
+ }
220
+ listOptionExpiries(underlying) {
221
+ return this.request(`/options/${enc(underlying)}/expiries`);
222
+ }
223
+ listOptionQuotes(optionTicker, params) {
224
+ return this.request(`/options/${enc(optionTicker)}/quotes`, {
225
+ from: params?.from,
226
+ to: params?.to,
227
+ limit: params?.limit,
228
+ cursor: params?.cursor
229
+ });
230
+ }
231
+ listBdrs(params) {
232
+ return this.request("/bdr", {
233
+ search: params?.search,
234
+ limit: params?.limit,
235
+ cursor: params?.cursor
236
+ });
237
+ }
238
+ getBdr(ticker) {
239
+ return this.request(`/bdr/${enc(ticker)}`);
240
+ }
241
+ listBdrQuotes(ticker, params) {
242
+ return this.request(`/bdr/${enc(ticker)}/quotes`, {
243
+ from: params?.from,
244
+ to: params?.to,
245
+ limit: params?.limit,
246
+ cursor: params?.cursor
247
+ });
248
+ }
249
+ search(q, params) {
250
+ return this.request("/search", { q, limit: params?.limit });
251
+ }
252
+ }
253
+ function enc(segment) {
254
+ return encodeURIComponent(segment);
255
+ }
256
+ export {
257
+ NotInPreviewError,
258
+ HttpClient,
259
+ HttpClient as DataBolsa
260
+ };
@@ -2,7 +2,6 @@
2
2
  * This file was auto-generated by openapi-typescript.
3
3
  * Do not make direct changes to the file.
4
4
  */
5
-
6
5
  export interface paths {
7
6
  "/v1/health": {
8
7
  parameters: {
@@ -1,22 +1,21 @@
1
1
  import type { components, operations } from "./schema";
2
-
3
2
  /** Corpo JSON da resposta 200 de uma operação do contrato. */
4
3
  export type Ok<Op extends keyof operations> = operations[Op] extends {
5
- responses: { 200: { content: { "application/json": infer T } } };
6
- }
7
- ? T
8
- : never;
9
-
4
+ responses: {
5
+ 200: {
6
+ content: {
7
+ "application/json": infer T;
8
+ };
9
+ };
10
+ };
11
+ } ? T : never;
10
12
  /** Parâmetros de query de uma operação do contrato (sem o `| undefined`). */
11
13
  export type Query<Op extends keyof operations> = operations[Op] extends {
12
- parameters: { query?: infer Q };
13
- }
14
- ? NonNullable<Q>
15
- : never;
16
-
14
+ parameters: {
15
+ query?: infer Q;
16
+ };
17
+ } ? NonNullable<Q> : never;
17
18
  export type Schemas = components["schemas"];
18
-
19
- // --- objetos de domínio (schemas do contrato) -----------------------------
20
19
  export type Lineage = Schemas["Lineage"];
21
20
  export type Company = Schemas["Company"];
22
21
  export type Stock = Schemas["Stock"];
@@ -48,8 +47,6 @@ export type BdrQuote = Schemas["BdrQuote"];
48
47
  export type IngestSourceStatus = Schemas["IngestSourceHealth"]["status"];
49
48
  export type IngestSourceHealth = Schemas["IngestSourceHealth"];
50
49
  export type IngestRunSummary = Schemas["IngestRunSummary"];
51
-
52
- // --- respostas (corpo 200 de cada operação) -------------------------------
53
50
  export type HealthResponse = Ok<"getHealth">;
54
51
  export type IngestHealthResponse = Ok<"getIngestHealth">;
55
52
  export type ScreenStocksResponse = Ok<"screenStocks">;
@@ -78,13 +75,12 @@ export type OptionExpiriesResponse = Ok<"listOptionExpiries">;
78
75
  export type OptionsQuotesResponse = Ok<"listOptionQuotes">;
79
76
  export type BdrListResponse = Ok<"listBdrs">;
80
77
  export type BdrQuotesResponse = Ok<"listBdrQuotes">;
81
-
82
78
  /**
83
79
  * Agrupamento client-side de `from`/`to` (datas ISO) — não é um schema do
84
80
  * contrato; os endpoints os recebem como query params soltos. Único tipo
85
81
  * mantido à mão de propósito.
86
82
  */
87
83
  export interface RangeParams {
88
- from?: string;
89
- to?: string;
84
+ from?: string;
85
+ to?: string;
90
86
  }
package/package.json CHANGED
@@ -1,15 +1,21 @@
1
1
  {
2
2
  "name": "@databolsa/sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
- "description": "SDK TypeScript tipado sobre a Serving API aberta do DataBolsa cliente agnóstico (fetch nativo), tipos gerados do contrato OpenAPI.",
6
+ "description": "SDK TypeScript tipado para a Serving API pública do DataBolsa, gerado a partir do contrato OpenAPI.",
7
7
  "exports": {
8
- ".": "./src/index.ts"
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ }
9
12
  },
13
+ "types": "./dist/index.d.ts",
10
14
  "scripts": {
11
15
  "gen:schema": "openapi-typescript ../../api/openapi.yaml -o src/schema.ts",
12
- "typecheck": "tsc --noEmit"
16
+ "typecheck": "tsc --noEmit",
17
+ "build": "rm -rf dist && bun build src/index.ts --target browser --format esm --outfile dist/index.js && tsc --declaration --emitDeclarationOnly --outDir dist --noEmit false",
18
+ "prepack": "bun run build"
13
19
  },
14
20
  "devDependencies": {
15
21
  "@types/bun": "latest",
@@ -20,8 +26,11 @@
20
26
  "access": "public"
21
27
  },
22
28
  "files": [
23
- "src"
29
+ "dist"
24
30
  ],
31
+ "engines": {
32
+ "node": ">=18"
33
+ },
25
34
  "author": "Rodrigo Klosowski",
26
35
  "homepage": "https://github.com/databolsahq/databolsa/tree/main/packages/sdk",
27
36
  "repository": {
package/src/client.ts DELETED
@@ -1,148 +0,0 @@
1
- import type {
2
- CorporateEventsResponse,
3
- CryptoQuotesResponse,
4
- DividendsResponse,
5
- DocumentsResponse,
6
- ExpectationsResponse,
7
- Fii,
8
- FiiDistributionsResponse,
9
- FiiIndicatorsResponse,
10
- FiiReportsResponse,
11
- FiiScreenResponse,
12
- HealthResponse,
13
- IngestHealthResponse,
14
- IndexCompositionResponse,
15
- IndexMeta,
16
- IndexQuotesResponse,
17
- IndicatorHistoryResponse,
18
- BdrListResponse,
19
- BdrProfile,
20
- BdrQuotesResponse,
21
- InsiderResponse,
22
- MacroGearsResponse,
23
- OptionExpiriesResponse,
24
- OptionsChainResponse,
25
- OptionsQuotesResponse,
26
- Query,
27
- QuotesResponse,
28
- RangeParams,
29
- RegimeSnapshot,
30
- ScreenStocksResponse,
31
- SearchResult,
32
- SeriesResponse,
33
- Stock,
34
- StockIndicatorsResponse,
35
- TesouroBondsResponse,
36
- YieldCurveResponse,
37
- } from "./types";
38
-
39
- /** Filtros do screener de ações — derivados de `GET /v1/screener/stocks`. */
40
- export type ScreenStocksParams = Query<"screenStocks">;
41
-
42
- /**
43
- * Filtros do listing de FIIs — derivados de `GET /v1/screener/fiis`, com uma
44
- * ergonomia: `paper` aceita `boolean` (o contrato pede `"true"`/`"false"`; o
45
- * HttpClient serializa). true = papel, false = tijolo, undefined = todos.
46
- */
47
- export type ScreenFiisParams = Omit<Query<"screenFiis">, "paper"> & { paper?: boolean };
48
-
49
- /**
50
- * Interface do cliente DataBolsa — métodos = operationIds do api/openapi.yaml.
51
- * Hoje implementada por FixtureClient (dados de demonstração); quando a API
52
- * real existir, um FetchClient implementa a mesma interface e o resto da UI
53
- * não muda.
54
- */
55
- export interface DataBolsaClient {
56
- getHealth(): Promise<HealthResponse>;
57
-
58
- /** Saúde da ingestão: última run + saúde por fonte + histórico (data lake). */
59
- getIngestHealth(): Promise<IngestHealthResponse>;
60
-
61
- /** Lista/filtra ações por fundamentos (o universo real, não o preview). */
62
- screenStocks(params?: ScreenStocksParams): Promise<ScreenStocksResponse>;
63
-
64
- getStock(ticker: string): Promise<Stock>;
65
- listQuotes(
66
- ticker: string,
67
- params?: RangeParams & { adjusted?: boolean; limit?: number },
68
- ): Promise<QuotesResponse>;
69
- getStockIndicators(ticker: string, params?: { at?: string }): Promise<StockIndicatorsResponse>;
70
- getStockIndicatorHistory(ticker: string, name: string, params?: RangeParams): Promise<IndicatorHistoryResponse>;
71
- listDividends(ticker: string, params?: RangeParams): Promise<DividendsResponse>;
72
- listCorporateEvents(ticker: string, params?: RangeParams): Promise<CorporateEventsResponse>;
73
- listCompanyDocuments(cvmCode: number, params?: RangeParams & { category?: string }): Promise<DocumentsResponse>;
74
- /** PENDÊNCIA DE CONTRATO — ver lib/api/types.ts (InsiderMove) */
75
- listInsiderMoves(ticker: string, params?: RangeParams): Promise<InsiderResponse>;
76
-
77
- /** Lista o universo real de FIIs (não o preview). */
78
- screenFiis(params?: ScreenFiisParams): Promise<FiiScreenResponse>;
79
- getFii(ticker: string): Promise<Fii>;
80
- getFiiIndicators(ticker: string, params?: { at?: string }): Promise<FiiIndicatorsResponse>;
81
- /** Série mensal de um indicador de FII (mart_fii__reports) — mesmo shape do histórico de ações. */
82
- getFiiIndicatorHistory(ticker: string, name: string, params?: RangeParams): Promise<IndicatorHistoryResponse>;
83
- listFiiDistributions(ticker: string, params?: RangeParams): Promise<FiiDistributionsResponse>;
84
- listFiiReports(ticker: string, params?: RangeParams): Promise<FiiReportsResponse>;
85
-
86
- listIndices(): Promise<IndexMeta[]>;
87
- listIndexQuotes(code: string, params?: RangeParams & { limit?: number }): Promise<IndexQuotesResponse>;
88
- getIndexComposition(code: string): Promise<IndexCompositionResponse>;
89
-
90
- getSeries(
91
- source: string,
92
- seriesId: string,
93
- params?: RangeParams & { accumulated?: "none" | "12m" | "ytd" },
94
- ): Promise<SeriesResponse>;
95
- getYieldCurve(params?: { kind?: "nominal" | "real" }): Promise<YieldCurveResponse>;
96
- listTesouroBonds(params?: {
97
- type?: string;
98
- maturity?: string;
99
- date?: string;
100
- limit?: number;
101
- }): Promise<TesouroBondsResponse>;
102
- getMarketExpectations(
103
- indicator: "ipca" | "selic" | "pib" | "cambio",
104
- params?: { reference?: string } & RangeParams,
105
- ): Promise<ExpectationsResponse>;
106
- getMacroRegime(params?: { at?: string }): Promise<RegimeSnapshot>;
107
- getMacroGears(params?: { gear?: string }): Promise<MacroGearsResponse>;
108
-
109
- listCryptoQuotes(
110
- symbol: string,
111
- params?: RangeParams & { interval?: "1d" | "1h"; limit?: number },
112
- ): Promise<CryptoQuotesResponse>;
113
-
114
- // --- opções (chain viva + greeks europeus/americanos; histórico por série) ---
115
- /** Cadeia viva de um subjacente (séries não vencidas, mais negociadas). Filtra por vencimento/tipo. */
116
- listOptionsChain(
117
- underlying: string,
118
- params?: { expiry?: string; type?: "call" | "put" },
119
- ): Promise<OptionsChainResponse>;
120
- /** Vencimentos distintos disponíveis para um subjacente (com contagem de séries). */
121
- listOptionExpiries(underlying: string): Promise<OptionExpiriesResponse>;
122
- /** Histórico EOD de UMA série de opção (paginado; só europeu). */
123
- listOptionQuotes(
124
- optionTicker: string,
125
- params?: RangeParams & { limit?: number; cursor?: string },
126
- ): Promise<OptionsQuotesResponse>;
127
-
128
- // --- BDRs (catálogo + cotações em BRL; dolarização via USD/BRL no client) ---
129
- /** Catálogo de BDRs (paginado; busca por ticker/nome). */
130
- listBdrs(params?: { search?: string; limit?: number; cursor?: string }): Promise<BdrListResponse>;
131
- getBdr(ticker: string): Promise<BdrProfile>;
132
- /** Histórico EOD de um BDR em BRL (paginado). */
133
- listBdrQuotes(
134
- ticker: string,
135
- params?: RangeParams & { limit?: number; cursor?: string },
136
- ): Promise<BdrQuotesResponse>;
137
-
138
- /** Busca unificada (ações, FIIs, índices, títulos, séries macro) — backed o Cmd+K. */
139
- search(q: string, params?: { limit?: number }): Promise<SearchResult[]>;
140
- }
141
-
142
- export class NotInPreviewError extends Error {
143
- constructor(public readonly entity: string) {
144
- super(`"${entity}" ainda não está no preview — dados de demonstração cobrem um subconjunto`);
145
- this.name = "NotInPreviewError";
146
- }
147
- }
148
-
@@ -1,412 +0,0 @@
1
- import {
2
- type DataBolsaClient,
3
- NotInPreviewError,
4
- type ScreenFiisParams,
5
- type ScreenStocksParams,
6
- } from "./client";
7
- import type {
8
- CorporateEventsResponse,
9
- CryptoQuotesResponse,
10
- DividendsResponse,
11
- DocumentsResponse,
12
- ExpectationsResponse,
13
- Fii,
14
- FiiDistributionsResponse,
15
- FiiIndicatorsResponse,
16
- FiiReportsResponse,
17
- FiiScreenResponse,
18
- HealthResponse,
19
- IngestHealthResponse,
20
- IndexCompositionResponse,
21
- IndexMeta,
22
- IndexQuotesResponse,
23
- IndicatorHistoryResponse,
24
- BdrListResponse,
25
- BdrProfile,
26
- BdrQuotesResponse,
27
- InsiderResponse,
28
- MacroGearsResponse,
29
- OptionExpiriesResponse,
30
- OptionsChainResponse,
31
- OptionsQuotesResponse,
32
- QuotesResponse,
33
- RangeParams,
34
- RegimeSnapshot,
35
- ScreenStocksResponse,
36
- SearchResult,
37
- SeriesResponse,
38
- Stock,
39
- StockIndicatorsResponse,
40
- TesouroBondsResponse,
41
- YieldCurveResponse,
42
- } from "./types";
43
-
44
- /**
45
- * Cliente HTTP real — fala com a Serving API (`@databolsa/api`) pelo contrato
46
- * `api/openapi.yaml`. Implementa a MESMA interface do FixtureClient, então a UI
47
- * não muda: `getClient()` (lib/api/index.ts) escolhe um ou outro por env.
48
- *
49
- * Princípio de degradação graciosa: a API responde **501** para qualquer rota
50
- * `/v1/*` ainda não servida (notFoundHandler). Tratamos 501 (e 404 de recurso
51
- * inexistente) como {@link NotInPreviewError} — a mesma exceção que a UI já sabe
52
- * exibir. Assim cada método chama o path real do contrato e "acende" sozinho
53
- * quando o endpoint correspondente passar a existir no servidor, sem editar aqui.
54
- *
55
- * A API é a camada ABERTA (sem dados de usuário): a autenticação é só um cheque
56
- * de chave opcional. Quando existir um control-plane à frente (mint/assinatura de
57
- * chave, rate-limit), `baseUrl` aponta para ele e o token vem de `getToken()`.
58
- */
59
- export interface HttpClientOptions {
60
- /** Token bearer a anexar (opcional). Hoje a API de dev é aberta. */
61
- getToken?: () => string | null | undefined;
62
- /** Chave estática (atalho p/ Node/CLI). Ignorada se `getToken` for passada. */
63
- apiKey?: string | null;
64
- }
65
-
66
- type Query = Record<string, string | number | boolean | null | undefined>;
67
-
68
- export class HttpClient implements DataBolsaClient {
69
- private readonly base: string;
70
- private readonly getToken?: () => string | null | undefined;
71
-
72
- constructor(baseUrl: string, opts: HttpClientOptions = {}) {
73
- // baseUrl absoluto (http(s)://…) → chamada direta (cross-origin, precisa CORS).
74
- // baseUrl relativo (ex.: "/") → MESMA ORIGEM: o browser fala com a própria origem
75
- // e o Next faz proxy p/ a API (next.config.ts) — funciona local, tunelado ou atrás
76
- // do gateway, sem o browser saber onde a API mora. As rotas vivem sob /v1.
77
- const isAbsolute = /^https?:\/\//i.test(baseUrl);
78
- // `globalThis.location` em vez do `window` nu: o SDK é agnóstico (sem lib DOM),
79
- // resolve a origem no browser e cai em "" no Node (onde baseUrl deve ser absoluto).
80
- const loc = (globalThis as { location?: { origin?: string } }).location;
81
- const origin = isAbsolute ? baseUrl.replace(/\/+$/, "") : (loc?.origin ?? "");
82
- this.base = `${origin}/v1`;
83
- this.getToken = opts.getToken ?? (opts.apiKey ? () => opts.apiKey : undefined);
84
- }
85
-
86
- private async request<T>(path: string, query?: Query): Promise<T> {
87
- const url = new URL(this.base + path);
88
- if (query) {
89
- for (const [k, v] of Object.entries(query)) {
90
- if (v !== undefined && v !== null && v !== "") url.searchParams.set(k, String(v));
91
- }
92
- }
93
-
94
- const headers: Record<string, string> = { accept: "application/json" };
95
- const token = this.getToken?.();
96
- if (token) headers.authorization = `Bearer ${token}`;
97
-
98
- let res: Response;
99
- try {
100
- res = await fetch(url, { headers });
101
- } catch (cause) {
102
- // Rede indisponível (API fora do ar, CORS, DNS) — erro real, não "preview".
103
- throw new Error(`Falha de rede ao chamar ${path}`, { cause });
104
- }
105
-
106
- if (res.ok) return (await res.json()) as T;
107
-
108
- // 501 (rota não servida nesta versão) e 404 (recurso inexistente) → a UI
109
- // trata como "fora do preview"; demais status são erros de verdade.
110
- if (res.status === 501 || res.status === 404) {
111
- throw new NotInPreviewError(decodeURIComponent(path.replace(/^\//, "")));
112
- }
113
- const detail = await this.problemDetail(res);
114
- throw new Error(`API ${res.status} em ${path}${detail ? `: ${detail}` : ""}`);
115
- }
116
-
117
- /** Extrai `detail`/`title` de um application/problem+json, se houver. */
118
- private async problemDetail(res: Response): Promise<string | null> {
119
- try {
120
- const body = (await res.json()) as { detail?: string; title?: string };
121
- return body.detail ?? body.title ?? null;
122
- } catch {
123
- return null;
124
- }
125
- }
126
-
127
- // --- saúde ---------------------------------------------------------------
128
- getHealth(): Promise<HealthResponse> {
129
- return this.request<HealthResponse>("/health");
130
- }
131
-
132
- getIngestHealth(): Promise<IngestHealthResponse> {
133
- return this.request<IngestHealthResponse>("/ingest");
134
- }
135
-
136
- // --- screener (o universo real de ações) ---------------------------------
137
- screenStocks(params?: ScreenStocksParams): Promise<ScreenStocksResponse> {
138
- return this.request<ScreenStocksResponse>("/screener/stocks", {
139
- sector: params?.sector,
140
- segment: params?.segment,
141
- sort: params?.sort,
142
- limit: params?.limit,
143
- cursor: params?.cursor,
144
- pl_min: params?.pl_min,
145
- pl_max: params?.pl_max,
146
- pvp_min: params?.pvp_min,
147
- pvp_max: params?.pvp_max,
148
- dy_min: params?.dy_min,
149
- roe_min: params?.roe_min,
150
- ev_ebitda_max: params?.ev_ebitda_max,
151
- div_liq_ebitda_max: params?.div_liq_ebitda_max,
152
- });
153
- }
154
-
155
- // --- ações ---------------------------------------------------------------
156
- getStock(ticker: string): Promise<Stock> {
157
- return this.request<Stock>(`/stocks/${enc(ticker)}`);
158
- }
159
-
160
- listQuotes(
161
- ticker: string,
162
- params?: RangeParams & { adjusted?: boolean; limit?: number },
163
- ): Promise<QuotesResponse> {
164
- return this.request<QuotesResponse>(`/stocks/${enc(ticker)}/quotes`, {
165
- from: params?.from,
166
- to: params?.to,
167
- limit: params?.limit,
168
- // só envia quando explicitamente não-ajustado (servidor: adjusted = v !== "false")
169
- adjusted: params?.adjusted === false ? "false" : undefined,
170
- });
171
- }
172
-
173
- getStockIndicators(ticker: string, params?: { at?: string }): Promise<StockIndicatorsResponse> {
174
- return this.request<StockIndicatorsResponse>(`/stocks/${enc(ticker)}/indicators`, {
175
- at: params?.at,
176
- });
177
- }
178
-
179
- getStockIndicatorHistory(
180
- ticker: string,
181
- name: string,
182
- params?: RangeParams,
183
- ): Promise<IndicatorHistoryResponse> {
184
- // Contrato: /stocks/{ticker}/indicators/history?name=… (não /{name}/history).
185
- return this.request<IndicatorHistoryResponse>(`/stocks/${enc(ticker)}/indicators/history`, {
186
- name,
187
- from: params?.from,
188
- to: params?.to,
189
- });
190
- }
191
-
192
- listDividends(ticker: string, params?: RangeParams): Promise<DividendsResponse> {
193
- return this.request<DividendsResponse>(`/stocks/${enc(ticker)}/dividends`, {
194
- from: params?.from,
195
- to: params?.to,
196
- });
197
- }
198
-
199
- listCorporateEvents(ticker: string, params?: RangeParams): Promise<CorporateEventsResponse> {
200
- return this.request<CorporateEventsResponse>(`/stocks/${enc(ticker)}/events`, {
201
- from: params?.from,
202
- to: params?.to,
203
- });
204
- }
205
-
206
- listCompanyDocuments(
207
- cvmCode: number,
208
- params?: RangeParams & { category?: string },
209
- ): Promise<DocumentsResponse> {
210
- return this.request<DocumentsResponse>(`/companies/${cvmCode}/documents`, {
211
- from: params?.from,
212
- to: params?.to,
213
- category: params?.category,
214
- });
215
- }
216
-
217
- listInsiderMoves(ticker: string, params?: RangeParams): Promise<InsiderResponse> {
218
- // Pendência de contrato (sem operationId ainda) — 501 até a rota existir.
219
- return this.request<InsiderResponse>(`/stocks/${enc(ticker)}/insider`, {
220
- from: params?.from,
221
- to: params?.to,
222
- });
223
- }
224
-
225
- // --- FIIs ----------------------------------------------------------------
226
- screenFiis(params?: ScreenFiisParams): Promise<FiiScreenResponse> {
227
- return this.request<FiiScreenResponse>("/screener/fiis", {
228
- segment: params?.segment,
229
- paper: params?.paper === undefined ? undefined : String(params.paper),
230
- sort: params?.sort,
231
- limit: params?.limit,
232
- cursor: params?.cursor,
233
- });
234
- }
235
-
236
- getFii(ticker: string): Promise<Fii> {
237
- return this.request<Fii>(`/fiis/${enc(ticker)}`);
238
- }
239
-
240
- getFiiIndicators(ticker: string, params?: { at?: string }): Promise<FiiIndicatorsResponse> {
241
- return this.request<FiiIndicatorsResponse>(`/fiis/${enc(ticker)}/indicators`, { at: params?.at });
242
- }
243
-
244
- getFiiIndicatorHistory(
245
- ticker: string,
246
- name: string,
247
- params?: RangeParams,
248
- ): Promise<IndicatorHistoryResponse> {
249
- return this.request<IndicatorHistoryResponse>(`/fiis/${enc(ticker)}/indicators/history`, {
250
- name,
251
- from: params?.from,
252
- to: params?.to,
253
- });
254
- }
255
-
256
- listFiiDistributions(ticker: string, params?: RangeParams): Promise<FiiDistributionsResponse> {
257
- return this.request<FiiDistributionsResponse>(`/fiis/${enc(ticker)}/distributions`, {
258
- from: params?.from,
259
- to: params?.to,
260
- });
261
- }
262
-
263
- listFiiReports(ticker: string, params?: RangeParams): Promise<FiiReportsResponse> {
264
- return this.request<FiiReportsResponse>(`/fiis/${enc(ticker)}/reports`, {
265
- from: params?.from,
266
- to: params?.to,
267
- });
268
- }
269
-
270
- // --- índices -------------------------------------------------------------
271
- listIndices(): Promise<IndexMeta[]> {
272
- return this.request<IndexMeta[]>("/indices");
273
- }
274
-
275
- listIndexQuotes(code: string, params?: RangeParams & { limit?: number }): Promise<IndexQuotesResponse> {
276
- return this.request<IndexQuotesResponse>(`/indices/${enc(code)}/quotes`, {
277
- from: params?.from,
278
- to: params?.to,
279
- limit: params?.limit,
280
- });
281
- }
282
-
283
- getIndexComposition(code: string): Promise<IndexCompositionResponse> {
284
- return this.request<IndexCompositionResponse>(`/indices/${enc(code)}/composition`);
285
- }
286
-
287
- // --- séries / renda fixa -------------------------------------------------
288
- getSeries(
289
- source: string,
290
- seriesId: string,
291
- params?: RangeParams & { accumulated?: "none" | "12m" | "ytd" },
292
- ): Promise<SeriesResponse> {
293
- return this.request<SeriesResponse>(`/series/${enc(source)}/${enc(seriesId)}`, {
294
- from: params?.from,
295
- to: params?.to,
296
- accumulated: params?.accumulated,
297
- });
298
- }
299
-
300
- getYieldCurve(params?: { kind?: "nominal" | "real" }): Promise<YieldCurveResponse> {
301
- return this.request<YieldCurveResponse>("/bonds/tesouro/yield-curve", { kind: params?.kind });
302
- }
303
-
304
- listTesouroBonds(params?: {
305
- type?: string;
306
- maturity?: string;
307
- date?: string;
308
- limit?: number;
309
- }): Promise<TesouroBondsResponse> {
310
- return this.request<TesouroBondsResponse>("/bonds/tesouro", {
311
- type: params?.type,
312
- maturity: params?.maturity,
313
- date: params?.date,
314
- limit: params?.limit,
315
- });
316
- }
317
-
318
- // --- macro ---------------------------------------------------------------
319
- getMarketExpectations(
320
- indicator: "ipca" | "selic" | "pib" | "cambio",
321
- params?: { reference?: string } & RangeParams,
322
- ): Promise<ExpectationsResponse> {
323
- return this.request<ExpectationsResponse>("/macro/expectations", {
324
- indicator,
325
- reference: params?.reference,
326
- from: params?.from,
327
- to: params?.to,
328
- });
329
- }
330
-
331
- getMacroRegime(params?: { at?: string }): Promise<RegimeSnapshot> {
332
- return this.request<RegimeSnapshot>("/macro/regime", { at: params?.at });
333
- }
334
-
335
- getMacroGears(params?: { gear?: string }): Promise<MacroGearsResponse> {
336
- return this.request<MacroGearsResponse>("/macro/gears", { gear: params?.gear });
337
- }
338
-
339
- listCryptoQuotes(
340
- symbol: string,
341
- params?: RangeParams & { interval?: "1d" | "1h"; limit?: number },
342
- ): Promise<CryptoQuotesResponse> {
343
- return this.request<CryptoQuotesResponse>(`/crypto/${enc(symbol)}/quotes`, {
344
- interval: params?.interval,
345
- from: params?.from,
346
- to: params?.to,
347
- limit: params?.limit,
348
- });
349
- }
350
-
351
- // --- opções --------------------------------------------------------------
352
- listOptionsChain(
353
- underlying: string,
354
- params?: { expiry?: string; type?: "call" | "put" },
355
- ): Promise<OptionsChainResponse> {
356
- return this.request<OptionsChainResponse>(`/options/${enc(underlying)}/chain`, {
357
- expiry: params?.expiry,
358
- type: params?.type,
359
- });
360
- }
361
-
362
- listOptionExpiries(underlying: string): Promise<OptionExpiriesResponse> {
363
- return this.request<OptionExpiriesResponse>(`/options/${enc(underlying)}/expiries`);
364
- }
365
-
366
- listOptionQuotes(
367
- optionTicker: string,
368
- params?: RangeParams & { limit?: number; cursor?: string },
369
- ): Promise<OptionsQuotesResponse> {
370
- return this.request<OptionsQuotesResponse>(`/options/${enc(optionTicker)}/quotes`, {
371
- from: params?.from,
372
- to: params?.to,
373
- limit: params?.limit,
374
- cursor: params?.cursor,
375
- });
376
- }
377
-
378
- // --- BDRs ----------------------------------------------------------------
379
- listBdrs(params?: { search?: string; limit?: number; cursor?: string }): Promise<BdrListResponse> {
380
- return this.request<BdrListResponse>("/bdr", {
381
- search: params?.search,
382
- limit: params?.limit,
383
- cursor: params?.cursor,
384
- });
385
- }
386
-
387
- getBdr(ticker: string): Promise<BdrProfile> {
388
- return this.request<BdrProfile>(`/bdr/${enc(ticker)}`);
389
- }
390
-
391
- listBdrQuotes(
392
- ticker: string,
393
- params?: RangeParams & { limit?: number; cursor?: string },
394
- ): Promise<BdrQuotesResponse> {
395
- return this.request<BdrQuotesResponse>(`/bdr/${enc(ticker)}/quotes`, {
396
- from: params?.from,
397
- to: params?.to,
398
- limit: params?.limit,
399
- cursor: params?.cursor,
400
- });
401
- }
402
-
403
- // --- busca ---------------------------------------------------------------
404
- search(q: string, params?: { limit?: number }): Promise<SearchResult[]> {
405
- return this.request<SearchResult[]>("/search", { q, limit: params?.limit });
406
- }
407
- }
408
-
409
- /** Segmento de path seguro (tickers/códigos vêm da UI/URL). */
410
- function enc(segment: string): string {
411
- return encodeURIComponent(segment);
412
- }
package/src/index.ts DELETED
@@ -1,26 +0,0 @@
1
- /**
2
- * `@databolsa/sdk` — cliente TypeScript tipado da Serving API aberta.
3
- *
4
- * Casca fina e **agnóstica** (sem React, sem dependências): o `HttpClient`
5
- * implementa a interface {@link DataBolsaClient} sobre o `fetch` nativo, com
6
- * degradação 501/404 → {@link NotInPreviewError} e Bearer opcional. Os tipos
7
- * saem do contrato `api/openapi.yaml` (gerados em `src/schema.ts` via
8
- * `bun run --cwd packages/sdk gen:schema`).
9
- *
10
- * Consumidores montam suas próprias camadas por cima: o app web envolve em
11
- * hooks React Query (apps/web/lib/queries.ts); um script Node usa direto.
12
- */
13
-
14
- // Cliente (valor) + nome amigável p/ uso externo.
15
- export { HttpClient, HttpClient as DataBolsa } from "./http-client";
16
- export type { HttpClientOptions } from "./http-client";
17
-
18
- // Contrato do cliente, params de busca e a exceção de degradação.
19
- export { NotInPreviewError } from "./client";
20
- export type { DataBolsaClient, ScreenStocksParams, ScreenFiisParams } from "./client";
21
-
22
- // Todos os tipos de domínio e de resposta derivados do schema.
23
- export type * from "./types";
24
-
25
- // Tipos crus do contrato (paths/operations/components), p/ quem quiser cavar.
26
- export type { paths, components, operations } from "./schema";