npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@delvoux/oplab

v0.1.1

Published

SDK TypeScript independente, completo e tipado para a API REST v3 da OpLab.

Readme

@delvoux/oplab

Biblioteca para integrar aplicações JavaScript e TypeScript à API REST v3 da OpLab. O SDK oferece métodos prontos para consultar dados de mercado e acessar recursos da sua conta, cuidando da autenticação por token, da montagem das requisições HTTP e do tratamento de respostas e erros.

Você pode usá-lo em scripts, serviços e backends que precisam de cotações, cadeias de opções, históricos, portfólios e outros recursos disponibilizados pela OpLab.

  • Mercado: instrumentos, cotações, opções, dados históricos, rankings, taxas de juros e status do mercado.
  • Conta e operações: usuário, portfólios, posições, ordens, estratégias, watchlists e outros recursos do domínio da API.
  • Cobertura do contrato: 115 operações e 65 modelos nomeados, com entradas e respostas tipadas para TypeScript.
  • Transporte: timeout, cancelamento, tratamento de erros e novas tentativas controladas para consultas seguras.
  • Compatibilidade: ESM e CommonJS, fetch nativo e zero dependências em runtime.

Este SDK é independente e não é um produto oficial da OpLab. A cobertura se refere à especificação incluída no projeto; não significa que todos os endpoints tenham sido validados na API real. As correções aplicadas e os limites conhecidos estão em Notas do OpenAPI.

Requisitos

  • Node.js 22 ou superior.
  • Token de acesso à API da OpLab, com permissão para os recursos que sua aplicação utilizará. Consulte Acesso à API OpLab.
  • Execução no servidor ou em um script local. Mantenha o token fora do código enviado ao navegador e não o inclua no repositório.

O SDK é gratuito e distribuído sob MPL-2.0. Ele não fornece token, assinatura ou acesso gratuito à API: os dados e recursos disponíveis dependem da conta, do plano e das condições da OpLab.

Instalação

npm install @delvoux/oplab

O pacote inclui o JavaScript compilado e as declarações de tipos. Não é necessário instalar TypeScript para utilizá-lo em JavaScript.

Primeiro uso em JavaScript

Na pasta da sua aplicação, crie um arquivo .env com seu token e inclua .env no .gitignore:

OPLAB_ACCESS_TOKEN=seu_token_da_oplab

Crie exemplo.mjs na mesma pasta:

import { OplabClient } from "@delvoux/oplab";

const accessToken = process.env.OPLAB_ACCESS_TOKEN;
if (!accessToken) {
  throw new Error("Configure OPLAB_ACCESS_TOKEN antes de iniciar a aplicação.");
}

const oplab = new OplabClient({ accessToken });

const quotes = await oplab.market.instruments.quote({
  query: { tickers: ["PRIO3", "PETR4"] },
});
console.table(quotes ?? []);

const options = await oplab.market.options.list({
  path: { symbol: "PRIO3" },
});

for (const option of (options ?? []).slice(0, 5)) {
  console.log(option.symbol, option.strike, option.bid, option.ask);
}

Execute com o carregamento de variáveis de ambiente do próprio Node.js:

node --env-file=.env exemplo.mjs

O exemplo faz duas consultas de leitura: cotações e opções. O SDK envia o token no header Access-Token. Os símbolos apenas demonstram as chamadas; os resultados vêm da API e dependem do ativo e das permissões da conta.

Se preferir uma função factory, o pacote também exporta createOplabClient(options), que retorna uma instância equivalente. Outros recursos seguem a mesma organização, por exemplo await oplab.domain.portfolios.list() para listar portfólios.

TypeScript

Os parâmetros e as respostas são inferidos automaticamente. O pacote também exporta modelos e tipos de operação para anotar o código da sua aplicação:

import type { OptionInfo } from "@delvoux/oplab";

const options: OptionInfo[] | undefined = await oplab.market.options.list({
  path: { symbol: "PRIO3" },
});

O trecho acima usa a instância oplab criada no exemplo anterior. Veja Tipos e formato das respostas para os detalhes do contrato.

CommonJS

const { OplabClient } = require("@delvoux/oplab");

const oplab = new OplabClient({
  accessToken: process.env.OPLAB_ACCESS_TOKEN,
});

Organização da API

A fachada acompanha as duas categorias da documentação oficial:

| Categoria | Recursos | | --- | --- | | client.domain | Usuário, portfólios, posições, ordens, estratégias, compartilhamentos, corretoras, contas de trade, watchlists, robôs, notificações e dias úteis. | | client.market | Opções, instrumentos, taxas de juros, status de mercado, companhias, ações, rankings, dados históricos e bolsas. |

Por exemplo, client.market.options oferece list, get, covered, blackScholes e powders. Todos os métodos recebem um objeto de entrada com path, query e/ou body, conforme a operação. Métodos sem entrada obrigatória podem ser chamados sem argumentos.

O Catálogo da API relaciona cada um dos 115 métodos ao verbo HTTP, à rota e ao operationId original. Os nomes originais das propriedades da API, incluindo snake_case e chaves como "access-token", são preservados.

Acesso por operationId

A interface genérica tem a mesma tipagem da fachada e permite integrar o SDK a serviços, ferramentas ou roteadores que já usam os identificadores do OpenAPI:

const options = await oplab.request("GetInstrumentOptions", {
  path: { symbol: "PRIO3" },
});

const result = await oplab.requestWithResponse("GetInstrumentOptions", {
  path: { symbol: "PRIO3" },
});

console.log(result.status);
console.log(result.headers.get("content-type"));
console.log(result.requestId);
console.log(result.data);

requestWithResponse retorna { data, status, headers, requestId }. Respostas HTTP de erro continuam lançando OplabApiError; esse método acrescenta metadados às respostas de sucesso.

Tipos e formato das respostas

O pacote exporta os 65 modelos, os tipos de entrada e resposta de cada operação, além dos utilitários OperationId, OperationInput<K> e OperationResponse<K>:

import type {
  OptionInfo,
  OperationInput,
  OperationResponse,
} from "@delvoux/oplab";

const input: OperationInput<"GetInstrumentOptions"> = {
  path: { symbol: "PRIO3" },
};

type OptionList = OperationResponse<"GetInstrumentOptions">;
type IndividualOption = OptionInfo;

As garantias de tipagem acompanham o contrato disponível:

  • Propriedades sem required no OpenAPI permanecem opcionais. Ter um campo no exemplo oficial não o torna obrigatório no tipo.
  • Operações que documentam sucesso com JSON e também 204 No Content retornam uma união com undefined. Operações de sucesso sem conteúdo retornam undefined.
  • Datas são strings no formato da API. O SDK não converte automaticamente para Date nem altera unidades ou casas decimais.
  • Objetos e arrays sem estrutura documentada usam unknown, evitando any.
  • Enums documentados são uniões literais. Parâmetros CSV conhecidos aceitam valor único ou array de valores válidos e são serializados com vírgulas.
  • Há validação em runtime da presença de parâmetros de path/query e de corpo exigidos, além da serialização. A estrutura dos campos do corpo é verificada estaticamente pelo TypeScript. Corpos e respostas não passam por validação automática do schema completo em runtime. Adicione a validação de negócio da sua aplicação quando precisar de garantias além da tipagem estática.

O SDK exige explicitamente o argumento body nas 27 operações que declaram corpo, embora o OpenAPI original omita requestBody.required em todas elas. Essa é uma decisão do SDK para tornar as chamadas previsíveis; os campos internos continuam respeitando a obrigatoriedade do schema. Um corpo cujas propriedades são todas opcionais pode ser informado como {}. Veja todas as decisões em Notas do OpenAPI.

Particularidades do contrato

PostUserSettings recebe preferences como string contendo JSON:

await oplab.request("PostUserSettings", {
  body: {
    preferences: JSON.stringify({ interest_rate_type: "SELIC" }),
  },
});

GetRobotLog retorna texto. PostOrdersExport usa GET e retorna 202 sem corpo: ele inicia a geração de um CSV, cujo link é enviado posteriormente por notificação da OpLab. O método não retorna diretamente o arquivo.

Configuração, timeout e novas tentativas

const oplab = new OplabClient({
  accessToken,
  timeoutMs: 30_000,
  retry: {
    maxRetries: 2,
    baseDelayMs: 250,
    maxDelayMs: 5_000,
  },
  headers: {
    "X-Application-Name": "meu-servico",
  },
});

| Configuração | Comportamento | | --- | --- | | accessToken | String ou função que resolve a chave, inclusive de forma assíncrona. | | baseUrl | Base HTTP(S), por padrão https://api.oplab.com.br/v3. Permite apontar para um proxy ou ambiente de testes sob seu controle. | | timeoutMs | Limite total da chamada lógica; padrão de 30 segundos. Abrange resolução do token, requisição, leitura da resposta e espera entre tentativas. Use 0 para desativar. | | retry.maxRetries | Até duas tentativas adicionais por padrão, somente em GETs classificados como seguros. Use 0 para desativar. | | retry.baseDelayMs / maxDelayMs | Controle da espera entre tentativas; padrões de 250 ms e 5.000 ms. | | headers | Headers adicionais do cliente ou da chamada. | | fetch | Implementação de fetch injetável, útil para testes ou transporte customizado compatível. |

Falhas de rede e status 429, 500, 502, 503 e 504 podem receber nova tentativa em GETs seguros. POST, PUT e DELETE não recebem novas tentativas automáticas. A exportação de ordens também não recebe, porque inicia um processamento apesar de usar GET.

Quando a resposta inclui Retry-After válido, o SDK respeita a espera informada. Se ela exceder maxDelayMs, encerra com o erro HTTP original, sem repetir a chamada antes do momento permitido.

Cancelamento e opções por chamada

O segundo argumento dos métodos da fachada aceita { signal, timeoutMs, headers, retry }:

const controller = new AbortController();

const pending = oplab.market.options.list(
  { path: { symbol: "PRIO3" } },
  {
    signal: controller.signal,
    timeoutMs: 10_000,
    retry: { maxRetries: 0 },
  },
);

// O chamador pode executar controller.abort() quando cancelar a operação.
const options = await pending;

Para métodos sem parâmetros, use undefined como primeiro argumento quando quiser fornecer opções:

await oplab.domain.portfolios.list(undefined, {
  timeoutMs: 10_000,
});

Token dinâmico e autenticação

O resolver de token é executado uma vez por chamada lógica, e seu resultado é reutilizado nas tentativas dessa chamada:

const oplab = new OplabClient({
  accessToken: async () => {
    const token = process.env.OPLAB_ACCESS_TOKEN;
    if (!token) throw new Error("Token OpLab indisponível.");
    return token;
  },
});

setAccessToken(token) substitui a chave/resolver configurado; clearAccessToken() remove essa configuração. A chave permanece na memória da instância e não é persistida pelo SDK. Autenticação e recuperação de senha não avaliam o resolver accessToken nem adicionam um token a partir dessa opção, pois o OpenAPI declara essas operações públicas.

Se optar por autenticar com e-mail e senha, confira a presença da chave antes de armazená-la:

const unauthenticated = new OplabClient();

const auth = await unauthenticated.request("PostAuthenticate", {
  body: {
    email: "[email protected]",
    password: "substitua-pela-senha-obtida-com-seguranca",
  },
});

if (
  auth &&
  "access-token" in auth &&
  typeof auth["access-token"] === "string"
) {
  unauthenticated.setAccessToken(auth["access-token"]);
} else {
  throw new Error("A resposta de autenticação não contém um access-token.");
}

O exemplo usa credenciais fictícias. Em uma aplicação, obtenha segredos do ambiente ou do seu gerenciador de segredos e mantenha o cliente autenticado no servidor.

Tratamento de erros

import { OplabClient, isOplabApiError } from "@delvoux/oplab";

const oplab = new OplabClient({ accessToken });

try {
  await oplab.market.options.list({ path: { symbol: "PRIO3" } });
} catch (error) {
  if (isOplabApiError(error)) {
    console.error({
      status: error.status,
      operation: error.operationId,
      requestId: error.requestId,
      message: error.message,
    });
  } else {
    throw error;
  }
}

OplabApiError também é exportada para uso com instanceof. Ela oferece status, body, headers, operationId, method, url e requestId. O corpo de erro não ganha uma estrutura fictícia: faça refinamento antes de acessar propriedades específicas. Use os metadados necessários à observabilidade da sua aplicação e trate timeout, cancelamento e falhas de transporte conforme a política do serviço.

Os helpers isOplabError e isOplabApiError também reconhecem erros que atravessam as entradas ESM e CommonJS do pacote. Prefira esses helpers quando a aplicação mistura os dois formatos, porque o instanceof direto depende da identidade da classe importada.

| Classe exportada | Situação | | --- | --- | | OplabApiError | Resposta HTTP de erro da API. | | OplabAuthError | Token ausente, inválido ou falha ao resolvê-lo. | | OplabValidationError | Entrada/configuração de transporte inválida. | | OplabTimeoutError | Prazo total da chamada excedido. | | OplabAbortError | Cancelamento pelo AbortSignal. | | OplabNetworkError | Falha no transporte ou leitura da resposta. | | OplabDecodeError | JSON inválido ou status de sucesso não documentado. |

Todas derivam de OplabError, também identificável com isOplabError.

Integração com NestJS

O SDK não depende do NestJS. Registre uma instância como provider usando as dependências que sua aplicação já possui:

import { Module } from "@nestjs/common";
import { OplabClient } from "@delvoux/oplab";

@Module({
  providers: [
    {
      provide: OplabClient,
      useFactory: () => {
        const accessToken = process.env.OPLAB_ACCESS_TOKEN;
        if (!accessToken) throw new Error("Configure OPLAB_ACCESS_TOKEN.");
        return new OplabClient({ accessToken });
      },
    },
  ],
  exports: [OplabClient],
})
export class OplabModule {}

Depois, injete OplabClient nos serviços normalmente. Em aplicações com várias contas, crie instâncias por credencial/contexto ou forneça um resolver ligado ao contexto correto; uma mudança de token em uma instância compartilhada afeta suas chamadas futuras.

Desenvolvimento e atualização do contrato

| Comando | Finalidade | | --- | --- | | npm ci | Instalar as versões registradas no lockfile. | | npm run generate | Gerar contrato normalizado, tipos, fachada, metadados e catálogo a partir da especificação original. | | npm run generate:check | Verificar se os arquivos gerados correspondem à especificação e ao gerador. | | npm run typecheck | Verificar o projeto TypeScript sem emitir código. | | npm test | Executar os testes de comportamento e contrato. | | npm run test:types | Verificar os contratos de tipagem, incluindo entradas inválidas esperadas. | | npm run build | Compilar as distribuições ESM e CommonJS e suas declarações. | | npm run test:package | Verificar o pacote distribuível e seu consumo. | | npm run check | Executar a verificação integrada do projeto. | | npm pack --dry-run | Inspecionar o conteúdo previsto para o pacote npm. |

Arquivos centrais:

| Caminho | Conteúdo | | --- | --- | | src/ | Cliente, transporte, erros e código gerado. | | dist/ | Distribuição compilada pronta para consumo. | | spec/openapi.original.json | Cópia preservada da especificação recebida. | | spec/openapi.normalized.json | Contrato utilizado na geração após as correções explícitas. | | spec/normalization-report.json | Registro das decisões de normalização. | | scripts/ | Geração, compilação e verificações reproduzíveis. | | docs/API.md | Catálogo completo de operações. | | docs/OPENAPI-NOTES.md | Inconsistências do contrato e tratamento adotado. |

Para atualizar a API, substitua a especificação original por uma nova versão obtida da OpLab, execute npm run generate, revise o diff e execute npm run check. Não edite os arquivos gerados para introduzir ajustes permanentes: registre a alteração no gerador e nas notas correspondentes.

As verificações automatizadas usam respostas simuladas, checagem de tipos, cobertura do contrato e consumo do pacote. A passagem desses testes não confirma permissões de plano, comportamento atual do servidor nem semântica de operações financeiras em produção. O teste com token real descrito abaixo cobre somente as três consultas que executa.

O registro de validação detalha os testes da versão inicial do projeto.

Uso local a partir do ZIP ou dos fontes

Para desenvolver a biblioteca ou gerar um pacote local, extraia o ZIP ou obtenha os fontes e execute na raiz do projeto:

npm ci
npm run check
npm pack

O comando npm pack informa o nome do arquivo .tgz gerado. Na aplicação que vai consumir o SDK, instale esse arquivo; por exemplo, para a versão 0.1.0:

npm install /caminho/para/delvoux-oplab-0.1.0.tgz

Se você recebeu um ZIP com um .tgz já gerado em artifacts/, também pode instalar esse arquivo diretamente. Para publicar uma versão da biblioteca, consulte Publicação no npm.

Testar com seu token real

Na cópia local deste projeto, preencha OPLAB_ACCESS_TOKEN no .env da raiz e execute:

npm run build
npm run test:api
# Opcional: escolher outro ativo (padrão: PETR4)
npm run test:api -- VALE3

O arquivo JavaScript scripts/test-api.js carrega o .env automaticamente e usa o SDK compilado em dist/ para consultar status do mercado, cotação e opções. Exibe até cinco registros por consulta e um resumo com duração, sem imprimir o token. As três chamadas são GET de leitura, com timeout de 15 segundos cada e sem novas tentativas automáticas.

Também é possível rodar diretamente com node scripts/test-api.js depois de compilar. Falhas encerram o processo com código 1. Respostas vazias aparecem como SEM DADOS; os dados e recursos disponíveis dependem do ativo e das permissões da conta/plano. Este teste valida somente as três consultas executadas.

Licença e atribuição

Distribuído sob Mozilla Public License 2.0, a licença declarada pela especificação fornecida. As fontes e a especificação estão incluídas na distribuição; preserve a licença e as atribuições ao redistribuir o projeto. Consulte NOTICE.md.

A licença do SDK e da especificação é distinta das condições de acesso à API e de uso dos dados de mercado, definidas pela OpLab em sua documentação e nos termos de serviço.