@pimia/sdk 0.4.0 → 0.5.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 +37 -9
- package/dist/client.js +31 -11
- package/dist/index.d.ts +1 -1
- package/package.json +1 -1
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,13 @@ 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
|
};
|
|
136
149
|
}>;
|
|
137
|
-
get: (id: number | string) => Promise<{
|
|
150
|
+
get: (id: number | string, options?: ReadOptions) => Promise<{
|
|
138
151
|
data: components["schemas"]["InvoiceResource"] & Record<string, never>;
|
|
139
152
|
}>;
|
|
140
153
|
/**
|
|
@@ -314,13 +327,13 @@ export declare class PimiaClient {
|
|
|
314
327
|
}>>;
|
|
315
328
|
};
|
|
316
329
|
get customers(): {
|
|
317
|
-
list: (query?: RequestOptions["query"]) => Promise<{
|
|
330
|
+
list: (query?: RequestOptions["query"], options?: ReadOptions) => Promise<{
|
|
318
331
|
data: components["schemas"]["CustomerResource"][];
|
|
319
332
|
meta: {
|
|
320
333
|
customer_total_count: number;
|
|
321
334
|
};
|
|
322
335
|
}>;
|
|
323
|
-
get: (id: number | string) => Promise<{
|
|
336
|
+
get: (id: number | string, options?: ReadOptions) => Promise<{
|
|
324
337
|
data: components["schemas"]["CustomerResource"];
|
|
325
338
|
}>;
|
|
326
339
|
create: (body: CustomerRequest, options?: WriteOptions) => Promise<{
|
|
@@ -366,13 +379,13 @@ export declare class PimiaClient {
|
|
|
366
379
|
}>>;
|
|
367
380
|
};
|
|
368
381
|
get estimates(): {
|
|
369
|
-
list: (query?: RequestOptions["query"]) => Promise<{
|
|
382
|
+
list: (query?: RequestOptions["query"], options?: ReadOptions) => Promise<{
|
|
370
383
|
data: components["schemas"]["EstimateResource"][];
|
|
371
384
|
meta: {
|
|
372
385
|
estimate_total_count: number;
|
|
373
386
|
};
|
|
374
387
|
}>;
|
|
375
|
-
get: (id: number | string) => Promise<{
|
|
388
|
+
get: (id: number | string, options?: ReadOptions) => Promise<{
|
|
376
389
|
data: components["schemas"]["EstimateResource"];
|
|
377
390
|
}>;
|
|
378
391
|
create: (body: EstimatesRequest, options?: WriteOptions) => Promise<{
|
|
@@ -396,9 +409,24 @@ export declare class PimiaClient {
|
|
|
396
409
|
* `estimate:{id}:invoice`— y el reintento tras un timeout no te creará
|
|
397
410
|
* una segunda factura.
|
|
398
411
|
*
|
|
412
|
+
* Y manda `externalRef` si la venta nació en tu sistema: es lo que hace
|
|
413
|
+
* que `invoice.created` e `invoice.paid` te lleguen con tu referencia en
|
|
414
|
+
* vez de con `null`. **Tiene que ir aquí, en la conversión**; etiquetar
|
|
415
|
+
* después con `PUT /invoices/{id}` llega tarde por dos motivos: para
|
|
416
|
+
* entonces `invoice.created` ya salió con la referencia nula, y entre las
|
|
417
|
+
* dos llamadas hay una ventana en la que la factura existe y no la
|
|
418
|
+
* encuentras por tu referencia.
|
|
419
|
+
*
|
|
420
|
+
* Va como opción y no como segundo parámetro para no romperle la llamada
|
|
421
|
+
* a quien ya hace `convertToInvoice(id, { idempotencyKey })`: el cuerpo lo
|
|
422
|
+
* monta el atajo, y `external_ref` es además el único campo que el
|
|
423
|
+
* endpoint acepta.
|
|
424
|
+
*
|
|
399
425
|
* Exige `estimates:write` **e** `invoices:write`.
|
|
400
426
|
*/
|
|
401
|
-
convertToInvoice: (id: number | string, options?: WriteOptions
|
|
427
|
+
convertToInvoice: (id: number | string, options?: WriteOptions & {
|
|
428
|
+
externalRef?: string | null;
|
|
429
|
+
}) => Promise<ResourceEnvelope<{
|
|
402
430
|
id: string;
|
|
403
431
|
invoice_date: string;
|
|
404
432
|
due_date: string;
|
|
@@ -484,11 +512,11 @@ export declare class PimiaClient {
|
|
|
484
512
|
currency?: components["schemas"]["CurrencyResource"];
|
|
485
513
|
}>>;
|
|
486
514
|
};
|
|
487
|
-
get<T = unknown>(path: string, query?: RequestOptions['query']): Promise<T>;
|
|
515
|
+
get<T = unknown>(path: string, query?: RequestOptions['query'], options?: ReadOptions): Promise<T>;
|
|
488
516
|
post<T = unknown>(path: string, body?: unknown, options?: WriteOptions): Promise<T>;
|
|
489
517
|
put<T = unknown>(path: string, body?: unknown, options?: WriteOptions): Promise<T>;
|
|
490
518
|
patch<T = unknown>(path: string, body?: unknown, options?: WriteOptions): Promise<T>;
|
|
491
|
-
delete<T = unknown>(path: string): Promise<T>;
|
|
519
|
+
delete<T = unknown>(path: string, options?: ReadOptions): Promise<T>;
|
|
492
520
|
/**
|
|
493
521
|
* Petición cruda contra `/api/v1`. `path` puede llevar el prefijo o no:
|
|
494
522
|
* `/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) =>
|
|
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';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pimia/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Cliente TypeScript de la API de Pimia para apps de partner: OAuth con PKCE, rotación de refresh persistida, reintentos de rate limit y tipos generados del OpenAPI.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Pimia (https://pimia.es)",
|