arca-sdk 0.4.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,142 @@
1
+ # Changelog
2
+
3
+ Todos los cambios notables de este proyecto se documentan en este archivo.
4
+
5
+ ---
6
+
7
+ ## [1.0.0] — 2026-02-23
8
+
9
+ ### 🔴 Breaking Changes
10
+
11
+ Esta versión establece la API pública definitiva. **Requiere actualizar todos los imports** si venís de v0.x.
12
+
13
+ #### Métodos renombrados en WsfeService
14
+ | v0.x | v1.0.0 |
15
+ |-------|--------|
16
+ | `emitirTicketCSimple()` | `issueSimpleReceipt()` |
17
+ | `emitirTicketC()` | `issueReceipt()` |
18
+ | `emitirFacturaC()` | `issueInvoiceC()` |
19
+ | `emitirFacturaB()` | `issueInvoiceB()` |
20
+ | `emitirFacturaA()` | `issueInvoiceA()` |
21
+ | `emitirComprobante()` | *(privado — ya no accesible)* |
22
+
23
+ #### Método renombrado en PadronService
24
+ | v0.x | v1.0.0 |
25
+ |-------|--------|
26
+ | `getPersona(cuit)` | `getTaxpayer(cuit)` |
27
+
28
+ #### Configuración de WsfeService
29
+ | v0.x | v1.0.0 |
30
+ |-------|--------|
31
+ | `puntoVenta: 4` | `pointOfSale: 4` |
32
+
33
+ #### Tipos renombrados
34
+ | v0.x | v1.0.0 |
35
+ |-------|--------|
36
+ | `TipoComprobante` | `InvoiceType` |
37
+ | `TipoDocumento` | `TaxIdType` |
38
+ | `Concepto` | `BillingConcept` |
39
+ | `FacturaItem` | `InvoiceItem` |
40
+ | `Comprador` | `Buyer` |
41
+ | `EmitirFacturaRequest` | `IssueInvoiceRequest` |
42
+ | `Persona` | `Taxpayer` |
43
+ | `Domicilio` | `Address` |
44
+ | `Actividad` | `Activity` |
45
+ | `Impuesto` | `TaxRecord` |
46
+ | `PadronResponse` | `TaxpayerResponse` |
47
+ | `PadronConfig` | `TaxpayerServiceConfig` |
48
+
49
+ #### Fields renombrados en tipos
50
+ | Tipo | v0.x | v1.0.0 |
51
+ |------|-------|--------|
52
+ | `InvoiceItem` | `descripcion` | `description` |
53
+ | `InvoiceItem` | `cantidad` | `quantity` |
54
+ | `InvoiceItem` | `precioUnitario` | `unitPrice` |
55
+ | `InvoiceItem` | `alicuotaIva` | `vatRate` |
56
+ | `Buyer` | `tipoDocumento` | `docType` |
57
+ | `Buyer` | `nroDocumento` | `docNumber` |
58
+ | `CAEResponse` | `tipoComprobante` | `invoiceType` |
59
+ | `CAEResponse` | `puntoVenta` | `pointOfSale` |
60
+ | `CAEResponse` | `nroComprobante` | `invoiceNumber` |
61
+ | `CAEResponse` | `fecha` | `date` |
62
+ | `CAEResponse` | `vencimientoCae` | `caeExpiry` |
63
+ | `CAEResponse` | `resultado` | `result` |
64
+ | `CAEResponse` | `observaciones` | `observations` |
65
+ | `CAEResponse` | `iva` | `vat` |
66
+ | `CAEResponse` | `urlQr` | `qrUrl` |
67
+ | `ServiceStatus` | `AppServer` | `appServer` |
68
+ | `ServiceStatus` | `DbServer` | `dbServer` |
69
+ | `ServiceStatus` | `AuthServer` | `authServer` |
70
+ | `Taxpayer` | `idPersona` | `taxId` |
71
+ | `Taxpayer` | `tipoPersona` | `personType` |
72
+ | `Taxpayer` | `nombre` | `firstName` |
73
+ | `Taxpayer` | `apellido` | `lastName` |
74
+ | `Taxpayer` | `razonSocial` | `companyName` |
75
+ | `Taxpayer` | `estadoClave` | `status` |
76
+ | `Taxpayer` | `domicilio` | `addresses` |
77
+ | `Taxpayer` | `actividad` | `activities` |
78
+ | `Taxpayer` | `impuesto` | `taxes` |
79
+ | `Taxpayer` | `descripcionActividadPrincipal` | `mainActivity` |
80
+ | `Taxpayer` | `esInscriptoIVA` | `isVATRegistered` |
81
+ | `Taxpayer` | `esMonotributista` | `isMonotax` |
82
+ | `Taxpayer` | `esExento` | `isVATExempt` |
83
+ | `Address` | `direccion` | `street` |
84
+ | `Address` | `localidad` | `city` |
85
+ | `Address` | `codPostal` | `postalCode` |
86
+ | `Address` | `idProvincia` | `provinceId` |
87
+ | `Address` | `descripcionProvincia` | `province` |
88
+ | `Address` | `tipoDomicilio` | `type` |
89
+
90
+ #### Función renombrada en utils
91
+ | v0.x | v1.0.0 |
92
+ |-------|--------|
93
+ | `generarUrlQR()` | `generateQRUrl()` |
94
+
95
+ #### Enums — valores constantes renombrados
96
+ | Enum | v0.x | v1.0.0 |
97
+ |------|-------|--------|
98
+ | `TaxIdType` | `CONSUMIDOR_FINAL` | `FINAL_CONSUMER` |
99
+ | `TaxIdType` | `CI_EXTRANJERA` | `FOREIGN_ID` |
100
+ | `TaxIdType` | `CI_BUENOS_AIRES` | `BUENOS_AIRES_ID` |
101
+ | `TaxIdType` | `CI_POLICIA_FEDERAL` | `NATIONAL_POLICE_ID` |
102
+ | `BillingConcept` | `PRODUCTOS` | `PRODUCTS` |
103
+ | `BillingConcept` | `SERVICIOS` | `SERVICES` |
104
+ | `BillingConcept` | `PRODUCTOS_Y_SERVICIOS` | `PRODUCTS_AND_SERVICES` |
105
+
106
+ ---
107
+
108
+ ### ✅ Nuevas funcionalidades
109
+
110
+ - **`WsfeService.getInvoice(type, number)`**: Consulta un comprobante ya emitido (FECompConsultar).
111
+ - **`WsfeService.getPointsOfSale()`**: Lista los puntos de venta habilitados (FEParamGetPtosVenta).
112
+ - **`ArcaNetworkError`**: Ahora exportado públicamente para manejo de errores de red.
113
+ - **`InvoiceDetails`**: Nuevo tipo para la respuesta de `getInvoice()`.
114
+ - **`PointOfSale`**: Nuevo tipo para la respuesta de `getPointsOfSale()`.
115
+
116
+ ### 🐛 Fixes
117
+
118
+ - `ServiceStatus` ahora tiene campos `camelCase` (`appServer`, `dbServer`, `authServer`) en lugar de `PascalCase`.
119
+ - `emitirComprobante` (ahora `issueDocument`) se volvió privado — ya no es accesible desde fuera del servicio.
120
+ - Diccionario de hints de errores (`ARCA_ERROR_HINTS`) expandido a 15+ códigos documentados.
121
+ - Eliminado `WsaaResponse` (tipo sin uso).
122
+ - Tipado explícito en `PadronService`: eliminados todos los `any` en métodos privados.
123
+
124
+ ### 🧪 Tests
125
+
126
+ - Nuevo suite de tests para `WsfeService` (`wsfe.test.ts`).
127
+ - Tests existentes actualizados a la nueva API.
128
+
129
+ ---
130
+
131
+ ## [0.5.0] — 2026-02-22
132
+
133
+ - Agregado Padrón A13 service (`PadronService`)
134
+ - `ArcaError` con campo `hint` para guiar al desarrollador
135
+ - `checkStatus()` con default seguro en `homologacion`
136
+
137
+ ## [0.4.0] — 2026-02-21
138
+
139
+ - Primera versión pública del SDK
140
+ - `WsaaService` con cache en memoria + persistencia opcional
141
+ - `WsfeService` con Ticket C, Factura A, B, C
142
+ - Generador de QR oficial de ARCA
package/README.md CHANGED
@@ -3,12 +3,13 @@
3
3
  **La SDK moderna de ARCA (ex-AFIP) que no te rompe las bolas.**
4
4
 
5
5
  SDK en TypeScript para integración con servicios de ARCA:
6
- - ✅ **Type-safe**: TypeScript strict mode
7
- - ✅ **Simple**: No más XML manual
8
- - ✅ **Automático**: Cache de tokens, retry logic
9
- - ✅ **Fiscal**: Generador de QR oficial AFIP integrado
6
+ - ✅ **Type-safe**: TypeScript strict mode, 100% tipado
7
+ - ✅ **Simple**: API en inglés, sin XML manual, sin magia negra
8
+ - ✅ **Automático**: Cache de tokens + persistencia opcional (God Mode)
9
+ - ✅ **Fiscal**: Generador de QR oficial de ARCA ultra-robusto
10
+ - ✅ **Padrón**: Consulta de CUIT (A13) para autocompletado de datos
10
11
  - ✅ **Resiliente**: Maneja errores SSL ("dh key too small") y timeouts
11
- - ✅ **Moderno**: ESM + CJS nativo, Node.js 18+
12
+ - ✅ **Moderno**: ESM + CJS nativo, Node.js 18+, Bun compatible
12
13
 
13
14
  ---
14
15
 
@@ -23,283 +24,205 @@ bun add arca-sdk
23
24
 
24
25
  ## ⚡ Quick Start
25
26
  ```typescript
26
- import { WsaaService } from 'arca-sdk';
27
- import * as fs from 'node:fs';
27
+ import { WsaaService, WsfeService } from 'arca-sdk';
28
+ import * as fs from 'fs';
28
29
 
29
- // 1. Crear servicio con tus certificados
30
+ // 1. Autenticar con WSAA
30
31
  const wsaa = new WsaaService({
31
- environment: 'homologacion', // 'homologacion' o 'produccion'
32
+ environment: 'homologacion',
32
33
  cuit: '20123456789',
33
- cert: fs.readFileSync('./cert.pem', 'utf-8'),
34
- key: fs.readFileSync('./key.pem', 'utf-8'),
34
+ cert: fs.readFileSync('cert.pem', 'utf-8'),
35
+ key: fs.readFileSync('key.pem', 'utf-8'),
35
36
  service: 'wsfe',
36
37
  });
37
38
 
38
- // 2. Obtener ticket (automático, con cache)
39
39
  const ticket = await wsaa.login();
40
40
 
41
- // 3. Usar token en otros servicios ARCA
42
- console.log('Token:', ticket.token);
43
- ```
41
+ // 2. Crear servicio de facturación
42
+ const wsfe = new WsfeService({
43
+ environment: 'homologacion',
44
+ cuit: '20123456789',
45
+ ticket,
46
+ pointOfSale: 4,
47
+ });
48
+
49
+ // 3. Emitir un Ticket C
50
+ const result = await wsfe.issueSimpleReceipt({ total: 1500 });
44
51
 
45
- **Eso es todo.** No XML. No SOAP. No pain.
52
+ console.log('CAE:', result.cae);
53
+ console.log('QR URL:', result.qrUrl); // ← Ya viene integrado!
54
+ ```
46
55
 
47
56
  ---
48
57
 
49
- ## 📖 Servicios Disponibles
58
+ ## 👑 God Mode: Persistencia Automática
59
+ No manejes tokens manualmente. Pasale un `storage` al SDK y se encargará de guardar, recuperar y renovar el TA solo cuando expire.
50
60
 
51
- ### WSAA - Autenticación
52
61
  ```typescript
53
- import { WsaaService } from 'arca-sdk';
54
-
55
62
  const wsaa = new WsaaService({
56
- environment: 'homologacion',
57
- cuit: '20123456789',
58
- cert: '...certificado PEM...',
59
- key: '...clave privada PEM...',
60
- service: 'wsfe', // o 'wsmtxca', etc
63
+ ...config,
64
+ service: 'wsfe',
65
+ storage: {
66
+ get: async (cuit, env) => await db.token.findUnique({ where: { cuit, env } }),
67
+ save: async (cuit, env, ticket) => await db.token.upsert({ ... }),
68
+ }
61
69
  });
62
70
 
71
+ // El SDK chequea el storage antes de pedir un nuevo ticket a ARCA
63
72
  const ticket = await wsaa.login();
64
- // Ticket válido por ~12 horas
65
- // Se renueva automáticamente
66
- ```
67
-
68
- ### WSFE - Facturación
69
- ```typescript
70
- const wsfe = new WsfeService(config);
71
- const cae = await wsfe.emitirFacturaC({ items });
72
- console.log('CAE:', cae.cae);
73
73
  ```
74
74
 
75
75
  ---
76
76
 
77
- ## 🔑 Certificados
77
+ ## 🔍 Consulta de Padrón (A13)
78
+ Obtené los datos de un contribuyente (nombre, domicilio, condición IVA) solo con su CUIT.
78
79
 
79
- Necesitás certificados de ARCA en formato PEM:
80
- - `cert.pem`: Certificado X.509
81
- - `key.pem`: Clave privada
80
+ ```typescript
81
+ import { PadronService } from 'arca-sdk';
82
82
 
83
- **Homologación (testing):**
84
- 1. Ir a [ARCA Homologación](https://www.afip.gob.ar/ws/documentacion/certificados.asp)
85
- 2. Generar certificado de prueba
86
- 3. Descargar cert + key
83
+ const padron = new PadronService(config);
84
+ const { taxpayer, error } = await padron.getTaxpayer('30111111118');
87
85
 
88
- **Producción:**
89
- 1. Generar CSR con tu CUIT
90
- 2. Subir a ARCA
91
- 3. Descargar certificado firmado
86
+ if (taxpayer) {
87
+ const name = taxpayer.companyName || `${taxpayer.firstName} ${taxpayer.lastName}`;
88
+ console.log('Nombre:', name);
89
+ console.log('Provincia:', taxpayer.addresses[0].province);
90
+ console.log('¿Inscripto IVA?:', taxpayer.isVATRegistered);
91
+ console.log('¿Monotributista?:', taxpayer.isMonotax);
92
+ }
93
+ ```
92
94
 
93
95
  ---
94
96
 
95
- ## 🛠️ Ejemplos
97
+ ## 📱 Comprobantes soportados
96
98
 
97
- Ver carpeta [`/examples`](./examples):
98
- - [`autenticacion.ts`](./examples/autenticacion.ts) - Obtener ticket WSAA
99
- - [`quick-start.ts`](./examples/quick-start.ts) - Inicio rápido
99
+ ```typescript
100
+ // Ticket C Consumidor Final (solo total)
101
+ const cae = await wsfe.issueSimpleReceipt({ total: 1500 });
100
102
 
101
- ---
103
+ // Ticket C — con detalle de items (los items se guardan localmente, no van a ARCA)
104
+ const cae = await wsfe.issueReceipt({
105
+ items: [
106
+ { description: 'Café con leche', quantity: 2, unitPrice: 750 },
107
+ { description: 'Medialunas x3', quantity: 1, unitPrice: 500 },
108
+ ],
109
+ });
102
110
 
103
- ## 🧪 Testing
104
- ```bash
105
- # Tests unitarios
106
- bun test
111
+ // Factura C — Consumidor Final con items
112
+ const cae = await wsfe.issueInvoiceC({ items: [...] });
107
113
 
108
- # Build
109
- bun run build
114
+ // Factura B — con IVA discriminado (requiere vatRate en cada item)
115
+ const cae = await wsfe.issueInvoiceB({
116
+ items: [
117
+ { description: 'Servicio de diseño', quantity: 10, unitPrice: 1000, vatRate: 21 },
118
+ ],
119
+ buyer: { docType: TaxIdType.CUIT, docNumber: '20987654321' },
120
+ });
121
+
122
+ // Factura A — entre Responsables Inscriptos
123
+ const cae = await wsfe.issueInvoiceA({
124
+ items: [...],
125
+ buyer: { docType: TaxIdType.CUIT, docNumber: '30123456789' },
126
+ });
110
127
  ```
111
128
 
112
129
  ---
113
130
 
114
- ## 📝 TypeScript
131
+ ## 🔎 Consultar un comprobante ya emitido
115
132
 
116
- La SDK exporta todos los tipos:
117
133
  ```typescript
118
- import type {
119
- LoginTicket,
120
- WsaaConfig,
121
- Environment
122
- } from 'arca-sdk';
134
+ const invoice = await wsfe.getInvoice(InvoiceType.TICKET_C, 42);
135
+ console.log('Total:', invoice.total);
136
+ console.log('CAE:', invoice.cae);
123
137
  ```
124
138
 
125
- Autocomplete completo en tu IDE. ✨
126
-
127
139
  ---
128
140
 
129
- ## ⚠️ Manejo de Errores
130
- ```typescript
131
- import { ArcaAuthError, ArcaValidationError } from 'arca-sdk';
132
-
133
- try {
134
- const ticket = await wsaa.login();
135
- } catch (error) {
136
- if (error instanceof ArcaAuthError) {
137
- console.error('Error de autenticación:', error.message);
138
- }
139
-
140
- if (error instanceof ArcaValidationError) {
141
- console.error('Configuración inválida:', error.message);
142
- }
143
- }
144
- ```
141
+ ## 🏪 Listar puntos de venta
145
142
 
146
- Los errores incluyen contexto útil en `error.details`.
147
-
148
- #### Timeouts
149
- Por defecto, las peticiones tienen un timeout de **15 segundos**. Podés ajustarlo en la configuración:
150
143
  ```typescript
151
- const wsfe = new WsfeService({
152
- ...config,
153
- timeout: 30000 // 30 segundos
144
+ const points = await wsfe.getPointsOfSale();
145
+ points.forEach(p => {
146
+ console.log(`PdV ${p.number}: ${p.type} ${p.isBlocked ? '🔴 Bloqueado' : '✅ Activo'}`);
154
147
  });
155
148
  ```
156
149
 
157
150
  ---
158
151
 
159
- ### WSFE - Facturación Electrónica
152
+ ## 📱 QR Oficial de ARCA
160
153
 
161
- #### Ticket C Simple (solo total)
162
154
  ```typescript
163
- import { WsaaService, WsfeService } from 'arca-sdk';
164
-
165
- // 1. Autenticar
166
- const wsaa = new WsaaService({ ... });
167
- const ticket = await wsaa.login();
155
+ // 1. Integrado automáticamente en todos los métodos de emisión
156
+ const result = await wsfe.issueSimpleReceipt({ total: 1500 });
157
+ console.log(result.qrUrl);
168
158
 
169
- // 2. Crear servicio WSFE
170
- const wsfe = new WsfeService({
171
- environment: 'homologacion',
172
- cuit: '20123456789',
173
- ticket,
174
- puntoVenta: 4,
175
- });
176
-
177
- // 3. Emitir ticket (modo simple)
178
- const cae = await wsfe.emitirTicketCSimple({
179
- total: 3500
180
- });
181
-
182
- console.log('CAE:', cae.cae);
159
+ // 2. O generalo manualmente
160
+ import { generateQRUrl } from 'arca-sdk';
161
+ const url = generateQRUrl(caeResponse, '20123456789', 1500);
183
162
  ```
184
163
 
185
- #### Ticket C con Items
186
- ```typescript
187
- // Modo completo: con detalle de items
188
- const cae = await wsfe.emitirTicketC({
189
- items: [
190
- { descripcion: 'Producto 1', cantidad: 2, precioUnitario: 500 },
191
- { descripcion: 'Producto 2', cantidad: 1, precioUnitario: 1000 },
192
- ],
193
- });
164
+ ---
194
165
 
195
- // Los items NO se envían a ARCA
196
- // Pero se retornan en la respuesta para que los guardes
197
- console.log('Items:', cae.items);
198
- ```
166
+ ## 🩺 Estado de los servidores
199
167
 
200
- #### Factura B (IVA discriminado)
201
168
  ```typescript
202
- import { TipoDocumento } from 'arca-sdk';
203
-
204
- const cae = await wsfe.emitirFacturaB({
205
- items: [
206
- {
207
- descripcion: 'Servicio',
208
- cantidad: 10,
209
- precioUnitario: 1000,
210
- alicuotaIva: 21, // ← OBLIGATORIO
211
- },
212
- ],
213
- comprador: {
214
- tipoDocumento: TipoDocumento.CUIT,
215
- nroDocumento: '20987654321',
216
- },
217
- });
218
-
219
- console.log('CAE:', cae.cae);
220
- console.log('IVA:', cae.iva);
169
+ // Sin necesidad de autenticación
170
+ const status = await WsfeService.checkStatus('produccion');
171
+ console.log('AppServer:', status.appServer); // 'OK'
172
+ console.log('DbServer:', status.dbServer);
173
+ console.log('AuthServer:', status.authServer);
221
174
  ```
222
175
 
223
- #### Factura A (RI a RI)
224
- ```typescript
225
- const cae = await wsfe.emitirFacturaA({
226
- items: [
227
- { descripcion: 'Producto', cantidad: 5, precioUnitario: 2000, alicuotaIva: 21 },
228
- ],
229
- comprador: {
230
- tipoDocumento: TipoDocumento.CUIT,
231
- nroDocumento: '20111111119',
232
- },
233
- });
234
- ```
176
+ ---
235
177
 
236
- #### Precios con IVA Incluido
237
- Si tus precios ya tienen el IVA (típico en venta minorista/POS), podés usar el flag `incluyeIva`:
238
- ```typescript
239
- const cae = await wsfe.emitirFacturaB({
240
- incluyeIva: true, // ← El SDK calculará el neto y el IVA automáticamente
241
- items: [
242
- { descripcion: 'Producto', cantidad: 1, precioUnitario: 1210, alicuotaIva: 21 },
243
- ],
244
- // ... comprador
245
- });
246
- // Internamente enviará: Subtotal: 1000, IVA: 210, Total: 1210
247
- ```
178
+ ## 📝 Referencia de Servicios
248
179
 
249
- ---
180
+ | Clase | Servicio ARCA | Descripción |
181
+ |-------|---------------|-------------|
182
+ | `WsaaService` | `wsaa` | Autenticación y Autorización |
183
+ | `WsfeService` | `wsfev1` | Facturación Electrónica (A, B, C) |
184
+ | `PadronService` | `ws_sr_padron_a13` | Consulta de datos de contribuyentes |
250
185
 
251
- ## 📱 Generador de QR Oficial
252
- AFIP exige que los comprobantes impresos tengan un código QR con los datos fiscales. La SDK lo genera por vos:
186
+ ### Enums disponibles
253
187
 
254
188
  ```typescript
255
- import { generarUrlQR } from 'arca-sdk';
256
-
257
- // Usá la respuesta del CAE para generar la URL del QR
258
- const urlQr = generarUrlQR(cae);
189
+ import { InvoiceType, BillingConcept, TaxIdType } from 'arca-sdk';
259
190
 
260
- console.log('URL para QR:', urlQr);
261
- // Output: https://www.afip.gob.ar/fe/qr/?p=eyJ2ZXIiOjEsImZlY2hh...
262
- ```
191
+ InvoiceType.FACTURA_A // 1
192
+ InvoiceType.FACTURA_B // 6
193
+ InvoiceType.FACTURA_C // 11
194
+ InvoiceType.TICKET_C // 83
263
195
 
264
- Esta URL la podés pasar a cualquier librería de generación de imágenes QR.
196
+ BillingConcept.PRODUCTS // 1
197
+ BillingConcept.SERVICES // 2
198
+ BillingConcept.PRODUCTS_AND_SERVICES // 3
265
199
 
266
- ---
200
+ TaxIdType.CUIT // 80
201
+ TaxIdType.DNI // 96
202
+ TaxIdType.FINAL_CONSUMER // 99
203
+ ```
267
204
 
268
205
  ---
269
206
 
270
- ## 🎯 Tipos de Comprobante
271
-
272
- | Tipo | Uso | IVA Discriminado | Items requeridos |
273
- |------|-----|------------------|------------------|
274
- | **Ticket C** | Consumidor final | No | Opcional (solo local) |
275
- | **Factura C** | Consumidor final | No | Opcional |
276
- | **Factura B** | Monotributo → RI | Sí | **Obligatorio** |
277
- | **Factura A** | RI → RI | Sí | **Obligatorio** |
207
+ ## 🛠️ Desarrollo y Tests
278
208
 
279
- **Importante:** Factura B y A requieren `alicuotaIva` en cada item.
280
-
281
- ---
209
+ ```bash
210
+ # Correr tests (unit + mocks de ARCA)
211
+ bun test
282
212
 
283
- ## 🤝 Contribuir
213
+ # Verificar tipos TypeScript
214
+ bun run lint
284
215
 
285
- Contribuciones bienvenidas! Ver [CONTRIBUTING.md](./CONTRIBUTING.md)
216
+ # Build para producción (CJS + ESM + .d.ts)
217
+ bun run build
218
+ ```
286
219
 
287
220
  ---
288
221
 
289
222
  ## 📄 Licencia
290
-
291
223
  MIT © [Marcela Borgarello](https://github.com/marcelaborgarello)
292
224
 
293
225
  ---
294
226
 
295
- ## 🔗 Links
296
-
297
- - [Documentación ARCA](https://www.afip.gob.ar/ws/)
298
- - [Issues](https://github.com/marcelaborgarello/arca-sdk/issues)
299
- - [NPM](https://www.npmjs.com/package/arca-sdk)
300
-
301
- ---
302
-
303
227
  **Hecho con ❤️ en Argentina 🇦🇷**
304
-
305
228
  *Porque integrar con ARCA no tiene por qué ser un infierno.*