@pimia/sdk 0.4.0 → 0.6.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/dist/client.d.ts CHANGED
@@ -112,6 +112,19 @@ export interface ResponseWithMeta<T> {
112
112
  }
113
113
  /** Lo que se puede afinar en una escritura (`post`/`put`/`patch`). */
114
114
  export type WriteOptions = Pick<RequestOptions, 'headers' | 'query' | 'signal' | 'idempotencyKey'>;
115
+ /**
116
+ * Lo que se puede afinar en una lectura (`get`/`delete` y los atajos de
117
+ * recurso).
118
+ *
119
+ * Sin `idempotencyKey`, que no significa nada en una lectura, y sin `query`,
120
+ * que en `get()` ya es un parámetro propio.
121
+ *
122
+ * Existe sobre todo por `signal`: hasta la 0.4 los atajos de lectura no
123
+ * aceptaban opciones, así que ponerle un timeout a un GET obligaba a bajar a
124
+ * `request()` — o a quedarse sin él, que es lo que pasa de verdad. Un cliente
125
+ * que sondea y se cuelga en una lectura deja de sondear sin dar un solo error.
126
+ */
127
+ export type ReadOptions = Pick<RequestOptions, 'headers' | 'signal'>;
115
128
  export declare class PimiaClient {
116
129
  readonly oauth: OAuth;
117
130
  private readonly baseUrl;
@@ -128,13 +141,18 @@ export declare class PimiaClient {
128
141
  /** Cabeceras `X-RateLimit-*` de la última respuesta. */
129
142
  get rateLimit(): RateLimit;
130
143
  get invoices(): {
131
- list: (query?: RequestOptions["query"]) => Promise<{
144
+ list: (query?: RequestOptions["query"], options?: ReadOptions) => Promise<{
132
145
  data: components["schemas"]["InvoiceResource"][];
133
146
  meta: {
134
147
  invoice_total_count: number;
135
148
  };
149
+ } | {
150
+ data: components["schemas"]["InvoiceSummaryResource"][];
151
+ meta: {
152
+ invoice_total_count: number;
153
+ };
136
154
  }>;
137
- get: (id: number | string) => Promise<{
155
+ get: (id: number | string, options?: ReadOptions) => Promise<{
138
156
  data: components["schemas"]["InvoiceResource"] & Record<string, never>;
139
157
  }>;
140
158
  /**
@@ -142,185 +160,192 @@ export declare class PimiaClient {
142
160
  * `200` de `invoices.store` está vacío ahí (ver {@link ResourceEnvelope}).
143
161
  */
144
162
  create: (body: InvoicesRequest, options?: WriteOptions) => Promise<ResourceEnvelope<{
145
- id: string;
163
+ id: number;
146
164
  invoice_date: string;
147
- due_date: string;
148
- invoice_number: string;
165
+ due_date: string | null;
166
+ invoice_number: string | null;
149
167
  reference_number: string;
150
168
  status: string;
151
169
  paid_status: string;
152
170
  tax_per_item: string;
153
171
  tax_included: string;
154
172
  discount_per_item: string;
155
- notes: string;
156
- discount_type: string;
157
- discount: string;
158
- discount_val: string;
159
- sub_total: string;
160
- total: string;
173
+ notes: string | null;
174
+ discount_type: string | null;
175
+ discount: number;
176
+ discount_val: number;
177
+ sub_total: number;
178
+ total: number;
161
179
  effective_total: string;
162
- tax: string;
180
+ tax: number;
163
181
  due_amount: string;
164
182
  effective_due_amount: string;
165
183
  sent: string;
166
184
  viewed: string;
167
- unique_hash: string;
168
- template_name: string;
185
+ sent_at: string;
186
+ viewed_at: string;
187
+ unique_hash: string | null;
188
+ template_name: string | null;
169
189
  invoice_series_id: string;
170
- customer_id: string;
190
+ customer_id: number | null;
171
191
  external_ref: string | null;
172
192
  payment_method_id: string;
173
193
  recurring_invoice_id: string;
174
- sequence_number: string;
175
- exchange_rate: string;
176
- base_discount_val: string;
177
- base_sub_total: string;
178
- base_total: string;
179
- creator_id: string;
180
- base_tax: string;
181
- base_due_amount: string;
194
+ sequence_number: number | null;
195
+ exchange_rate: number | null;
196
+ base_discount_val: string | null;
197
+ base_sub_total: string | null;
198
+ base_total: string | null;
199
+ creator_id: number | null;
200
+ base_tax: string | null;
201
+ base_due_amount: string | null;
182
202
  effective_base_total: string;
183
203
  effective_base_due_amount: string;
184
204
  credited_total: string;
185
205
  credited_base_total: string;
186
- currency_id: string;
206
+ currency_id: number | null;
187
207
  formatted_created_at: string;
188
208
  invoice_pdf_url: string;
189
209
  formatted_invoice_date: string;
190
210
  formatted_due_date: string;
191
211
  allow_edit: string;
192
212
  payment_module_enabled: string;
193
- sales_tax_type: string;
194
- sales_tax_address_type: string;
195
213
  overdue: string;
196
214
  effective_paid_status: string;
197
215
  effective_overdue: string;
198
216
  aeat_status: string;
199
- qr_data: string;
200
- hash: string;
201
- aeat_csv: string;
202
- is_credit_note: string | boolean;
203
- rectified_invoice_id: string;
217
+ qr_data: string | null;
218
+ hash: string | null;
219
+ aeat_csv: string | null;
220
+ is_credit_note: boolean;
221
+ rectified_invoice_id: number | null;
204
222
  rectified_invoice_number?: string | null;
205
223
  rectified_invoice?: {
206
- id: string;
207
- invoice_number: string;
224
+ id: number;
225
+ invoice_number: string | null;
208
226
  tax_per_item: string;
209
227
  tax_included: string;
210
- sub_total: string;
211
- discount_val: string;
212
- tax: string;
213
- total: string;
228
+ sub_total: number;
229
+ discount_val: number;
230
+ tax: number;
231
+ total: number;
214
232
  items: components["schemas"]["InvoiceItemResource"][];
215
233
  taxes: components["schemas"]["TaxResource"][];
216
234
  };
217
- credit_notes_count: number;
235
+ credit_notes_count: string | number;
218
236
  items?: components["schemas"]["InvoiceItemResource"][];
219
237
  payments?: components["schemas"]["PaymentResource"][];
220
- customer?: components["schemas"]["CustomerResource"];
238
+ email_logs?: components["schemas"]["EmailLogResource"][];
239
+ customer?: components["schemas"]["CustomerResource"] | null;
221
240
  invoice_series?: components["schemas"]["InvoiceSeriesResource"];
222
241
  payment_method?: components["schemas"]["PaymentMethodResource"];
223
- creator?: components["schemas"]["UserResource"];
242
+ creator?: components["schemas"]["UserResource"] | null;
224
243
  taxes: components["schemas"]["TaxResource"][];
225
244
  fields?: components["schemas"]["CustomFieldValueResource"][];
226
- company?: components["schemas"]["CompanyResource"];
227
- currency?: components["schemas"]["CurrencyResource"];
245
+ company?: components["schemas"]["CompanyResource"] | null;
246
+ currency?: components["schemas"]["CurrencyResource"] | null;
228
247
  }>>;
229
248
  /** Mismo caso que `create`: el `200` de `invoices.update` no está tipado en el spec. */
230
249
  update: (id: number | string, body: InvoicesRequest, options?: WriteOptions) => Promise<ResourceEnvelope<{
231
- id: string;
250
+ id: number;
232
251
  invoice_date: string;
233
- due_date: string;
234
- invoice_number: string;
252
+ due_date: string | null;
253
+ invoice_number: string | null;
235
254
  reference_number: string;
236
255
  status: string;
237
256
  paid_status: string;
238
257
  tax_per_item: string;
239
258
  tax_included: string;
240
259
  discount_per_item: string;
241
- notes: string;
242
- discount_type: string;
243
- discount: string;
244
- discount_val: string;
245
- sub_total: string;
246
- total: string;
260
+ notes: string | null;
261
+ discount_type: string | null;
262
+ discount: number;
263
+ discount_val: number;
264
+ sub_total: number;
265
+ total: number;
247
266
  effective_total: string;
248
- tax: string;
267
+ tax: number;
249
268
  due_amount: string;
250
269
  effective_due_amount: string;
251
270
  sent: string;
252
271
  viewed: string;
253
- unique_hash: string;
254
- template_name: string;
272
+ sent_at: string;
273
+ viewed_at: string;
274
+ unique_hash: string | null;
275
+ template_name: string | null;
255
276
  invoice_series_id: string;
256
- customer_id: string;
277
+ customer_id: number | null;
257
278
  external_ref: string | null;
258
279
  payment_method_id: string;
259
280
  recurring_invoice_id: string;
260
- sequence_number: string;
261
- exchange_rate: string;
262
- base_discount_val: string;
263
- base_sub_total: string;
264
- base_total: string;
265
- creator_id: string;
266
- base_tax: string;
267
- base_due_amount: string;
281
+ sequence_number: number | null;
282
+ exchange_rate: number | null;
283
+ base_discount_val: string | null;
284
+ base_sub_total: string | null;
285
+ base_total: string | null;
286
+ creator_id: number | null;
287
+ base_tax: string | null;
288
+ base_due_amount: string | null;
268
289
  effective_base_total: string;
269
290
  effective_base_due_amount: string;
270
291
  credited_total: string;
271
292
  credited_base_total: string;
272
- currency_id: string;
293
+ currency_id: number | null;
273
294
  formatted_created_at: string;
274
295
  invoice_pdf_url: string;
275
296
  formatted_invoice_date: string;
276
297
  formatted_due_date: string;
277
298
  allow_edit: string;
278
299
  payment_module_enabled: string;
279
- sales_tax_type: string;
280
- sales_tax_address_type: string;
281
300
  overdue: string;
282
301
  effective_paid_status: string;
283
302
  effective_overdue: string;
284
303
  aeat_status: string;
285
- qr_data: string;
286
- hash: string;
287
- aeat_csv: string;
288
- is_credit_note: string | boolean;
289
- rectified_invoice_id: string;
304
+ qr_data: string | null;
305
+ hash: string | null;
306
+ aeat_csv: string | null;
307
+ is_credit_note: boolean;
308
+ rectified_invoice_id: number | null;
290
309
  rectified_invoice_number?: string | null;
291
310
  rectified_invoice?: {
292
- id: string;
293
- invoice_number: string;
311
+ id: number;
312
+ invoice_number: string | null;
294
313
  tax_per_item: string;
295
314
  tax_included: string;
296
- sub_total: string;
297
- discount_val: string;
298
- tax: string;
299
- total: string;
315
+ sub_total: number;
316
+ discount_val: number;
317
+ tax: number;
318
+ total: number;
300
319
  items: components["schemas"]["InvoiceItemResource"][];
301
320
  taxes: components["schemas"]["TaxResource"][];
302
321
  };
303
- credit_notes_count: number;
322
+ credit_notes_count: string | number;
304
323
  items?: components["schemas"]["InvoiceItemResource"][];
305
324
  payments?: components["schemas"]["PaymentResource"][];
306
- customer?: components["schemas"]["CustomerResource"];
325
+ email_logs?: components["schemas"]["EmailLogResource"][];
326
+ customer?: components["schemas"]["CustomerResource"] | null;
307
327
  invoice_series?: components["schemas"]["InvoiceSeriesResource"];
308
328
  payment_method?: components["schemas"]["PaymentMethodResource"];
309
- creator?: components["schemas"]["UserResource"];
329
+ creator?: components["schemas"]["UserResource"] | null;
310
330
  taxes: components["schemas"]["TaxResource"][];
311
331
  fields?: components["schemas"]["CustomFieldValueResource"][];
312
- company?: components["schemas"]["CompanyResource"];
313
- currency?: components["schemas"]["CurrencyResource"];
332
+ company?: components["schemas"]["CompanyResource"] | null;
333
+ currency?: components["schemas"]["CurrencyResource"] | null;
314
334
  }>>;
315
335
  };
316
336
  get customers(): {
317
- list: (query?: RequestOptions["query"]) => Promise<{
337
+ list: (query?: RequestOptions["query"], options?: ReadOptions) => Promise<{
318
338
  data: components["schemas"]["CustomerResource"][];
319
339
  meta: {
320
340
  customer_total_count: number;
321
341
  };
342
+ } | {
343
+ data: components["schemas"]["CustomerSummaryResource"][];
344
+ meta: {
345
+ customer_total_count: number;
346
+ };
322
347
  }>;
323
- get: (id: number | string) => Promise<{
348
+ get: (id: number | string, options?: ReadOptions) => Promise<{
324
349
  data: components["schemas"]["CustomerResource"];
325
350
  }>;
326
351
  create: (body: CustomerRequest, options?: WriteOptions) => Promise<{
@@ -328,52 +353,53 @@ export declare class PimiaClient {
328
353
  }>;
329
354
  /** El `200` de `customers.update` no está tipado en el spec. */
330
355
  update: (id: number | string, body: CustomerRequest, options?: WriteOptions) => Promise<ResourceEnvelope<{
331
- id: string;
356
+ id: number;
332
357
  name: string;
333
- email: string;
334
- phone: string;
335
- contact_name: string;
336
- company_name: string;
337
- website: string;
338
- enable_portal: string;
358
+ email: string | null;
359
+ phone: string | null;
360
+ contact_name: string | null;
361
+ website: string | null;
362
+ enable_portal: boolean;
339
363
  password_added: boolean;
340
- currency_id: string;
364
+ currency_id: number | null;
341
365
  payment_method_id: string;
342
- company_id: string;
343
- facebook_id: string;
344
- google_id: string;
345
- github_id: string;
346
- created_at: string;
366
+ company_id: number | null;
367
+ created_at: string | null;
347
368
  formatted_created_at: string;
348
- updated_at: string;
369
+ updated_at: string | null;
349
370
  avatar: string;
350
371
  due_amount: string;
351
372
  base_due_amount: string;
352
- prefix: string;
373
+ prefix: string | null;
353
374
  tax_id: string;
354
375
  notes: string;
355
376
  external_ref: string | null;
356
- iban: string;
357
- bic: string;
358
- sepa_mandate_id: string;
359
- sepa_mandate_date: string;
360
- billing?: components["schemas"]["AddressResource"];
361
- shipping?: components["schemas"]["AddressResource"];
377
+ iban: string | null;
378
+ bic: string | null;
379
+ sepa_mandate_id: string | null;
380
+ sepa_mandate_date: string | null;
381
+ billing?: components["schemas"]["AddressResource"] | null;
382
+ shipping?: components["schemas"]["AddressResource"] | null;
362
383
  fields?: components["schemas"]["CustomFieldValueResource"][];
363
- company?: components["schemas"]["CompanyResource"];
364
- currency?: components["schemas"]["CurrencyResource"];
384
+ company?: components["schemas"]["CompanyResource"] | null;
385
+ currency?: components["schemas"]["CurrencyResource"] | null;
365
386
  payment_method?: components["schemas"]["PaymentMethodResource"];
366
387
  }>>;
367
388
  };
368
389
  get estimates(): {
369
- list: (query?: RequestOptions["query"]) => Promise<{
390
+ list: (query?: RequestOptions["query"], options?: ReadOptions) => Promise<{
370
391
  data: components["schemas"]["EstimateResource"][];
371
392
  meta: {
372
393
  estimate_total_count: number;
373
394
  };
395
+ } | {
396
+ data: components["schemas"]["EstimateSummaryResource"][];
397
+ meta: {
398
+ estimate_total_count: number;
399
+ };
374
400
  }>;
375
- get: (id: number | string) => Promise<{
376
- data: components["schemas"]["EstimateResource"];
401
+ get: (id: number | string, options?: ReadOptions) => Promise<{
402
+ data: components["schemas"]["EstimateResource"] & Record<string, never>;
377
403
  }>;
378
404
  create: (body: EstimatesRequest, options?: WriteOptions) => Promise<{
379
405
  data: components["schemas"]["EstimateResource"];
@@ -396,99 +422,115 @@ export declare class PimiaClient {
396
422
  * `estimate:{id}:invoice`— y el reintento tras un timeout no te creará
397
423
  * una segunda factura.
398
424
  *
425
+ * Y manda `externalRef` si la venta nació en tu sistema: es lo que hace
426
+ * que `invoice.created` e `invoice.paid` te lleguen con tu referencia en
427
+ * vez de con `null`. **Tiene que ir aquí, en la conversión**; etiquetar
428
+ * después con `PUT /invoices/{id}` llega tarde por dos motivos: para
429
+ * entonces `invoice.created` ya salió con la referencia nula, y entre las
430
+ * dos llamadas hay una ventana en la que la factura existe y no la
431
+ * encuentras por tu referencia.
432
+ *
433
+ * Va como opción y no como segundo parámetro para no romperle la llamada
434
+ * a quien ya hace `convertToInvoice(id, { idempotencyKey })`: el cuerpo lo
435
+ * monta el atajo, y `external_ref` es además el único campo que el
436
+ * endpoint acepta.
437
+ *
399
438
  * Exige `estimates:write` **e** `invoices:write`.
400
439
  */
401
- convertToInvoice: (id: number | string, options?: WriteOptions) => Promise<ResourceEnvelope<{
402
- id: string;
440
+ convertToInvoice: (id: number | string, options?: WriteOptions & {
441
+ externalRef?: string | null;
442
+ }) => Promise<ResourceEnvelope<{
443
+ id: number;
403
444
  invoice_date: string;
404
- due_date: string;
405
- invoice_number: string;
445
+ due_date: string | null;
446
+ invoice_number: string | null;
406
447
  reference_number: string;
407
448
  status: string;
408
449
  paid_status: string;
409
450
  tax_per_item: string;
410
451
  tax_included: string;
411
452
  discount_per_item: string;
412
- notes: string;
413
- discount_type: string;
414
- discount: string;
415
- discount_val: string;
416
- sub_total: string;
417
- total: string;
453
+ notes: string | null;
454
+ discount_type: string | null;
455
+ discount: number;
456
+ discount_val: number;
457
+ sub_total: number;
458
+ total: number;
418
459
  effective_total: string;
419
- tax: string;
460
+ tax: number;
420
461
  due_amount: string;
421
462
  effective_due_amount: string;
422
463
  sent: string;
423
464
  viewed: string;
424
- unique_hash: string;
425
- template_name: string;
465
+ sent_at: string;
466
+ viewed_at: string;
467
+ unique_hash: string | null;
468
+ template_name: string | null;
426
469
  invoice_series_id: string;
427
- customer_id: string;
470
+ customer_id: number | null;
428
471
  external_ref: string | null;
429
472
  payment_method_id: string;
430
473
  recurring_invoice_id: string;
431
- sequence_number: string;
432
- exchange_rate: string;
433
- base_discount_val: string;
434
- base_sub_total: string;
435
- base_total: string;
436
- creator_id: string;
437
- base_tax: string;
438
- base_due_amount: string;
474
+ sequence_number: number | null;
475
+ exchange_rate: number | null;
476
+ base_discount_val: string | null;
477
+ base_sub_total: string | null;
478
+ base_total: string | null;
479
+ creator_id: number | null;
480
+ base_tax: string | null;
481
+ base_due_amount: string | null;
439
482
  effective_base_total: string;
440
483
  effective_base_due_amount: string;
441
484
  credited_total: string;
442
485
  credited_base_total: string;
443
- currency_id: string;
486
+ currency_id: number | null;
444
487
  formatted_created_at: string;
445
488
  invoice_pdf_url: string;
446
489
  formatted_invoice_date: string;
447
490
  formatted_due_date: string;
448
491
  allow_edit: string;
449
492
  payment_module_enabled: string;
450
- sales_tax_type: string;
451
- sales_tax_address_type: string;
452
493
  overdue: string;
453
494
  effective_paid_status: string;
454
495
  effective_overdue: string;
455
496
  aeat_status: string;
456
- qr_data: string;
457
- hash: string;
458
- aeat_csv: string;
459
- is_credit_note: string | boolean;
460
- rectified_invoice_id: string;
497
+ qr_data: string | null;
498
+ hash: string | null;
499
+ aeat_csv: string | null;
500
+ is_credit_note: boolean;
501
+ rectified_invoice_id: number | null;
461
502
  rectified_invoice_number?: string | null;
462
503
  rectified_invoice?: {
463
- id: string;
464
- invoice_number: string;
504
+ id: number;
505
+ invoice_number: string | null;
465
506
  tax_per_item: string;
466
507
  tax_included: string;
467
- sub_total: string;
468
- discount_val: string;
469
- tax: string;
470
- total: string;
508
+ sub_total: number;
509
+ discount_val: number;
510
+ tax: number;
511
+ total: number;
471
512
  items: components["schemas"]["InvoiceItemResource"][];
472
513
  taxes: components["schemas"]["TaxResource"][];
473
514
  };
474
- credit_notes_count: number;
515
+ credit_notes_count: string | number;
475
516
  items?: components["schemas"]["InvoiceItemResource"][];
476
517
  payments?: components["schemas"]["PaymentResource"][];
477
- customer?: components["schemas"]["CustomerResource"];
518
+ email_logs?: components["schemas"]["EmailLogResource"][];
519
+ customer?: components["schemas"]["CustomerResource"] | null;
478
520
  invoice_series?: components["schemas"]["InvoiceSeriesResource"];
479
521
  payment_method?: components["schemas"]["PaymentMethodResource"];
480
- creator?: components["schemas"]["UserResource"];
522
+ creator?: components["schemas"]["UserResource"] | null;
481
523
  taxes: components["schemas"]["TaxResource"][];
482
524
  fields?: components["schemas"]["CustomFieldValueResource"][];
483
- company?: components["schemas"]["CompanyResource"];
484
- currency?: components["schemas"]["CurrencyResource"];
525
+ company?: components["schemas"]["CompanyResource"] | null;
526
+ currency?: components["schemas"]["CurrencyResource"] | null;
485
527
  }>>;
486
528
  };
487
- get<T = unknown>(path: string, query?: RequestOptions['query']): Promise<T>;
529
+ get<T = unknown>(path: string, query?: RequestOptions['query'], options?: ReadOptions): Promise<T>;
488
530
  post<T = unknown>(path: string, body?: unknown, options?: WriteOptions): Promise<T>;
489
531
  put<T = unknown>(path: string, body?: unknown, options?: WriteOptions): Promise<T>;
490
532
  patch<T = unknown>(path: string, body?: unknown, options?: WriteOptions): Promise<T>;
491
- delete<T = unknown>(path: string): Promise<T>;
533
+ delete<T = unknown>(path: string, options?: ReadOptions): Promise<T>;
492
534
  /**
493
535
  * Petición cruda contra `/api/v1`. `path` puede llevar el prefijo o no:
494
536
  * `/invoices` y `/api/v1/invoices` son lo mismo.
package/dist/client.js CHANGED
@@ -44,8 +44,8 @@ export class PimiaClient {
44
44
  }
45
45
  get invoices() {
46
46
  return {
47
- list: (query) => this.get('/invoices', query),
48
- get: (id) => this.get(`/invoices/${id}`),
47
+ list: (query, options) => this.get('/invoices', query, options),
48
+ get: (id, options) => this.get(`/invoices/${id}`, undefined, options),
49
49
  /**
50
50
  * Devuelve `{ data: InvoiceResource }`. El tipo NO sale del spec: el
51
51
  * `200` de `invoices.store` está vacío ahí (ver {@link ResourceEnvelope}).
@@ -57,8 +57,8 @@ export class PimiaClient {
57
57
  }
58
58
  get customers() {
59
59
  return {
60
- list: (query) => this.get('/customers', query),
61
- get: (id) => this.get(`/customers/${id}`),
60
+ list: (query, options) => this.get('/customers', query, options),
61
+ get: (id, options) => this.get(`/customers/${id}`, undefined, options),
62
62
  create: (body, options) => this.post('/customers', body, options),
63
63
  /** El `200` de `customers.update` no está tipado en el spec. */
64
64
  update: (id, body, options) => this.put(`/customers/${id}`, body, options),
@@ -66,8 +66,8 @@ export class PimiaClient {
66
66
  }
67
67
  get estimates() {
68
68
  return {
69
- list: (query) => this.get('/estimates', query),
70
- get: (id) => this.get(`/estimates/${id}`),
69
+ list: (query, options) => this.get('/estimates', query, options),
70
+ get: (id, options) => this.get(`/estimates/${id}`, undefined, options),
71
71
  create: (body, options) => this.post('/estimates', body, options),
72
72
  /**
73
73
  * Convierte un presupuesto aceptado en factura.
@@ -87,13 +87,33 @@ export class PimiaClient {
87
87
  * `estimate:{id}:invoice`— y el reintento tras un timeout no te creará
88
88
  * una segunda factura.
89
89
  *
90
+ * Y manda `externalRef` si la venta nació en tu sistema: es lo que hace
91
+ * que `invoice.created` e `invoice.paid` te lleguen con tu referencia en
92
+ * vez de con `null`. **Tiene que ir aquí, en la conversión**; etiquetar
93
+ * después con `PUT /invoices/{id}` llega tarde por dos motivos: para
94
+ * entonces `invoice.created` ya salió con la referencia nula, y entre las
95
+ * dos llamadas hay una ventana en la que la factura existe y no la
96
+ * encuentras por tu referencia.
97
+ *
98
+ * Va como opción y no como segundo parámetro para no romperle la llamada
99
+ * a quien ya hace `convertToInvoice(id, { idempotencyKey })`: el cuerpo lo
100
+ * monta el atajo, y `external_ref` es además el único campo que el
101
+ * endpoint acepta.
102
+ *
90
103
  * Exige `estimates:write` **e** `invoices:write`.
91
104
  */
92
- convertToInvoice: (id, options) => this.post(`/estimates/${id}/convert-to-invoice`, {}, options),
105
+ convertToInvoice: (id, options) => {
106
+ const { externalRef, ...resto } = options ?? {};
107
+ return this.post(`/estimates/${id}/convert-to-invoice`,
108
+ // Cuerpo vacío si no se pide, y no `external_ref: null`: mandar el
109
+ // null explícito DESVINCULA la referencia, que no es lo mismo que no
110
+ // tocarla.
111
+ externalRef === undefined ? {} : { external_ref: externalRef }, resto);
112
+ },
93
113
  };
94
114
  }
95
- get(path, query) {
96
- return this.request(path, { method: 'GET', query });
115
+ get(path, query, options) {
116
+ return this.request(path, { ...options, method: 'GET', query });
97
117
  }
98
118
  post(path, body, options) {
99
119
  return this.request(path, { ...options, method: 'POST', body });
@@ -104,8 +124,8 @@ export class PimiaClient {
104
124
  patch(path, body, options) {
105
125
  return this.request(path, { ...options, method: 'PATCH', body });
106
126
  }
107
- delete(path) {
108
- return this.request(path, { method: 'DELETE' });
127
+ delete(path, options) {
128
+ return this.request(path, { ...options, method: 'DELETE' });
109
129
  }
110
130
  /**
111
131
  * Petición cruda contra `/api/v1`. `path` puede llevar el prefijo o no:
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  * salen los tipos de `./api`.
7
7
  */
8
8
  export { PimiaClient } from './client.js';
9
- export type { CustomerRequest, CustomerResource, EstimateResource, EstimatesRequest, InvoiceResource, InvoicesRequest, PimiaClientOptions, RateLimit, RequestOptions, ResourceEnvelope, ResponseMeta, ResponseWithMeta, WriteOptions, } from './client.js';
9
+ export type { CustomerRequest, CustomerResource, EstimateResource, EstimatesRequest, InvoiceResource, InvoicesRequest, PimiaClientOptions, RateLimit, ReadOptions, RequestOptions, ResourceEnvelope, ResponseMeta, ResponseWithMeta, WriteOptions, } from './client.js';
10
10
  export { OAuth, createPkceChallenge, createState } from './oauth.js';
11
11
  export type { AuthorizationServerMetadata, AuthorizeUrlOptions, OAuthConfig, PkceChallenge, } from './oauth.js';
12
12
  export { MemoryTokenStore, isExpired, tokenSetFromResponse } from './tokens.js';
@@ -35,6 +35,16 @@ export declare const SCOPES: {
35
35
  readonly agendaRead: "agenda:read";
36
36
  readonly agendaWrite: "agenda:write";
37
37
  readonly reportsRead: "reports:read";
38
+ /** Leer la configuración de la empresa (impuestos, preferencias, series). */
39
+ readonly settingsRead: "settings:read";
40
+ /** Ver la tienda de módulos y qué tiene contratado el tenant. */
41
+ readonly storeRead: "store:read";
42
+ /** Leer la gestión de personal: empleados, ausencias, fichajes, calendarios. */
43
+ readonly hrRead: "hr:read";
44
+ /** Gestionar el personal: altas, ausencias, correcciones de fichaje, horarios. */
45
+ readonly hrWrite: "hr:write";
46
+ /** Gestionar los avisos (webhooks) que recibe tu app. */
47
+ readonly webhooksWrite: "webhooks:write";
38
48
  /**
39
49
  * Proponer cambios que el dueño del tenant aprueba antes de aplicarse.
40
50
  * `approvalsSubmit` es un alias del mismo permiso, aceptado por el