@alijunior/acbr-api-sdk-node 2.3.4

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 ADDED
@@ -0,0 +1,295 @@
1
+ <h1 align="center">@alijunior/acbr-api-sdk-node</h1>
2
+
3
+ <p align="center">
4
+ <a href="https://www.npmjs.com/package/@alijunior/acbr-api-sdk-node">
5
+ <img alt="npm version" src="https://img.shields.io/npm/v/@alijunior/acbr-api-sdk-node.svg">
6
+ </a>
7
+ <a href="https://www.npmjs.com/package/@alijunior/acbr-api-sdk-node">
8
+ <img alt="npm downloads" src="https://img.shields.io/npm/dw/@alijunior/acbr-api-sdk-node.svg">
9
+ </a>
10
+ <img alt="license" src="https://img.shields.io/npm/l/@alijunior/acbr-api-sdk-node.svg">
11
+
12
+ </p>
13
+
14
+ SDK em **TypeScript/Node.js** para integração com a **Acbr API**, com tipos gerados a partir do OpenAPI e client HTTP enxuto (fetch/axios).
15
+
16
+ > ✅ Destaques
17
+ >
18
+ > - Tipagem forte (params, body e response) **direto do OpenAPI**
19
+ > - Client simples: `AcbrApiClient`
20
+ > - Adapters: `FetchHttpClient` (nativo) e `AxiosHttpClient` (opcional)
21
+ > - **Novos helpers de token**:
22
+ > - `getClientCredentialsToken` (objeto completo do token)
23
+ > - `getAccessTokenString` (só a string do token; wrapper)
24
+ > - `getAcbrApiTokenForBrowser` (para **testes no browser** — não usar em produção)
25
+
26
+ ---
27
+
28
+ ## Instalação
29
+
30
+ ```bash
31
+ pnpm add @alijunior/acbr-api-sdk-node
32
+ ```
33
+
34
+ ou
35
+
36
+ ```bash
37
+ npm i @alijunior/acbr-api-sdk-node
38
+ ```
39
+
40
+ ou
41
+
42
+ ```bash
43
+ yarn add @alijunior/acbr-api-sdk-node
44
+ ```
45
+
46
+ ### Requisitos
47
+
48
+ - Node **>= 18** (fetch nativo)
49
+ - TypeScript **>= 5** (recomendado)
50
+
51
+ ---
52
+
53
+ ## Variáveis de ambiente (para exemplos)
54
+
55
+ Crie um `.env` na raiz do seu projeto:
56
+
57
+ ```dotenv
58
+ TOKEN_URL=https://auth.acbr.api.br/realms/ACBrAPI/protocol/openid-connect/token
59
+ CLIENT_ID=SEU_CLIENT_ID
60
+ CLIENT_SECRET=SEU_CLIENT_SECRET
61
+ API_BASE=https://prod.acbr.api.br/
62
+ SCOPE=empresa conta cnpj cep nfce nfe
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Helpers de Token
68
+
69
+ ### 1) `getClientCredentialsToken` (Node – objeto completo)
70
+
71
+ Fluxo **OAuth2 Client Credentials**. Retorna `{ access_token, expires_in, ... }`.
72
+ Suporta `authStyle`: `"basic" | "body" | "both" | "auto"` (padrão: `"auto"`).
73
+
74
+ ```ts
75
+ import {
76
+ getClientCredentialsToken,
77
+ type ClientCredentialsInput,
78
+ } from "@alijunior/acbr-api-sdk-node";
79
+
80
+ const input: ClientCredentialsInput = {
81
+ tokenUrl: process.env.TOKEN_URL!,
82
+ clientId: process.env.CLIENT_ID!,
83
+ clientSecret: process.env.CLIENT_SECRET!,
84
+ scope: process.env.SCOPE,
85
+ authStyle: "auto", // tenta basic e cai para Body em 400/401
86
+ };
87
+
88
+ const token = await getClientCredentialsToken(input);
89
+ console.log("access_token:", token.access_token, "exp:", token.expires_in);
90
+ ```
91
+
92
+ ### 2) `getAccessTokenString` (Node – apenas a string)
93
+
94
+ Wrap prático quando você só precisa do `access_token`.
95
+
96
+ ```ts
97
+ import { getAccessTokenString } from "@alijunior/acbr-api-sdk-node";
98
+
99
+ const accessToken = await getAccessTokenString({
100
+ tokenUrl: process.env.TOKEN_URL!,
101
+ clientId: process.env.CLIENT_ID!,
102
+ clientSecret: process.env.CLIENT_SECRET!,
103
+ scope: process.env.SCOPE!,
104
+ });
105
+ ```
106
+
107
+ ### 3) `getAcbrApiTokenForBrowser` (Browser – **somente testes**)
108
+
109
+ Útil para provar fluxo no front **localmente**. **Não use em produção** (expõe o `client_secret`).
110
+
111
+ ```ts
112
+ import { getAcbrApiTokenForBrowser } from "@alijunior/acbr-api-sdk-node";
113
+
114
+ const accessToken = await getAcbrApiTokenForBrowser(
115
+ "CLIENT_ID",
116
+ "CLIENT_SECRET",
117
+ "https://auth.acbr.api.br/oauth/token", // default
118
+ "empresa conta cnpj cep nfce nfe" // default
119
+ );
120
+ ```
121
+
122
+ ---
123
+
124
+ ## Usando o Client com o Token
125
+
126
+ ### Com `fetch` (nativo Node 18+)
127
+
128
+ ```ts
129
+ import {
130
+ AcbrApiClient,
131
+ FetchHttpClient,
132
+ getAccessTokenString,
133
+ } from "@alijunior/acbr-api-sdk-node";
134
+
135
+ const accessToken = await getAccessTokenString({
136
+ tokenUrl: process.env.TOKEN_URL!,
137
+ clientId: process.env.CLIENT_ID!,
138
+ clientSecret: process.env.CLIENT_SECRET!,
139
+ scope: process.env.SCOPE!,
140
+ });
141
+
142
+ const http = new FetchHttpClient({
143
+ headers: { Authorization: `Bearer ${accessToken}` },
144
+ });
145
+
146
+ const api = new AcbrApiClient(http, process.env.API_BASE!);
147
+
148
+ // CEP
149
+ const cep = await api.consultarCep({ Cep: "04513010" });
150
+ console.log("CEP:", cep);
151
+
152
+ // CNPJ (exemplo)
153
+ const cnpjList = await api.listarCnpj({
154
+ cnae_principal: "6201501",
155
+ municipio: "3550308",
156
+ natureza_juridica: "2062",
157
+ $top: 5,
158
+ $skip: 0,
159
+ $inlinecount: false,
160
+ });
161
+ console.log("CNPJ:", cnpjList);
162
+ ```
163
+
164
+ ### Com `axios` (opcional)
165
+
166
+ ```ts
167
+ import axios from "axios";
168
+ import {
169
+ AcbrApiClient,
170
+ AxiosHttpClient,
171
+ getAccessTokenString,
172
+ } from "@alijunior/acbr-api-sdk-node";
173
+
174
+ const accessToken = await getAccessTokenString({
175
+ tokenUrl: process.env.TOKEN_URL!,
176
+ clientId: process.env.CLIENT_ID!,
177
+ clientSecret: process.env.CLIENT_SECRET!,
178
+ });
179
+
180
+ const axiosInstance = axios.create({
181
+ headers: { Authorization: `Bearer ${accessToken}` },
182
+ });
183
+
184
+ const http = new AxiosHttpClient(axiosInstance);
185
+ const api = new AcbrApiClient(http, process.env.API_BASE!);
186
+
187
+ // exemplo
188
+ const cep = await api.consultarCep({ Cep: "01001000" });
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Tratamento de erros (exemplo)
194
+
195
+ Os adapters levantam `Error` com `status` e, se presente, `body`.
196
+
197
+ ```ts
198
+ function printHttpError(e: unknown, ctx?: string) {
199
+ const status = (e as any)?.status;
200
+ const msg =
201
+ (e as any)?.body?.error?.message ??
202
+ (e as any)?.body?.message ??
203
+ (e as Error)?.message ??
204
+ String(e);
205
+
206
+ console.error(
207
+ `${ctx ? ctx + ": " : ""}${status ? status + " - " : ""}${msg}`
208
+ );
209
+ }
210
+
211
+ try {
212
+ const res = await api.listarCnpj({
213
+ /* ... */
214
+ });
215
+ } catch (e) {
216
+ printHttpError(e, "Falha ao listar CNPJ");
217
+ }
218
+ ```
219
+
220
+ ---
221
+
222
+ ## Tipos úteis (reexportados)
223
+
224
+ ```ts
225
+ import type {
226
+ CepEndereco,
227
+ CnpjListagem,
228
+ CnpjEmpresa,
229
+ ContaCotaListagem,
230
+ ContaCota,
231
+ EmpresaListagem,
232
+ Empresa,
233
+ EmpresaCertificado,
234
+ NfePedidoEmissao,
235
+ Dfe,
236
+ NfePedidoCancelamento,
237
+ DfeCancelamento,
238
+ EmpresaPedidoCadastroCertificado,
239
+ } from "@alijunior/acbr-api-sdk-node";
240
+ ```
241
+
242
+ > Os tipos de **params/query/body/response** dos métodos são inferidos das **operations**/**paths** do OpenAPI. Se o contrato mudar, o TypeScript aponta onde ajustar.
243
+
244
+ ---
245
+
246
+ ## Download de binarios
247
+
248
+ ```typescript
249
+ import { writeFile } from "node:fs/promises";
250
+ import { arrayBufferToNodeBuffer } from "../types/acbr-api.httpclient";
251
+
252
+ // Node: para salvar o arquivo
253
+
254
+ const pdf = await api.baixarPdfNfe({ id: "..." });
255
+ await writeFile("nota.pdf", arrayBufferToNodeBuffer(pdf));
256
+ ```
257
+
258
+ ```typescript
259
+ // Browser: para baixar
260
+
261
+ const ab = await api.baixarPdfNfe({ id: "..." });
262
+ const blob = new Blob([ab], { type: "application/pdf" });
263
+ const url = URL.createObjectURL(blob);
264
+ const a = document.createElement("a");
265
+ a.href = url;
266
+ a.download = "nota.pdf";
267
+ a.click();
268
+ URL.revokeObjectURL(url);
269
+ ```
270
+
271
+ ---
272
+
273
+ ## Desenvolvimento
274
+
275
+ ```bash
276
+ # exemplos locais (usando .env)
277
+ pnpm test
278
+
279
+ # build da lib
280
+ pnpm build
281
+ ```
282
+
283
+ ---
284
+
285
+ ## Segurança
286
+
287
+ - **Nunca** exponha `CLIENT_SECRET` no front em produção.
288
+ - Faça a emissão de token **no backend** e envie apenas o `access_token` ao cliente.
289
+ - Rotacione/Revogue credenciais comprometidas.
290
+
291
+ ---
292
+
293
+ ## Licença
294
+
295
+ [MIT](./LICENSE)