@lexnode/legal-data-sdk 1.29.0 → 1.31.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/README.md +222 -183
- package/dist/client.d.ts +217 -24
- package/dist/client.js +6 -103
- package/dist/errors.d.ts +86 -41
- package/dist/errors.js +1 -49
- package/dist/freshness.d.ts +88 -41
- package/dist/freshness.js +0 -47
- package/dist/index.d.ts +12 -8
- package/dist/index.js +1 -11
- package/dist/lookup.d.ts +130 -37
- package/dist/lookup.js +63 -37
- package/dist/paginate.d.ts +15 -5
- package/dist/paginate.js +0 -30
- package/dist/search.d.ts +57 -23
- package/dist/search.js +0 -17
- package/dist/types.d.ts +77 -68
- package/dist/watch.d.ts +78 -43
- package/dist/watch.js +0 -35
- package/dist/webhooks.d.ts +184 -93
- package/dist/webhooks.js +0 -65
- package/package.json +6 -3
- package/schema.d.ts +558 -518
package/dist/client.d.ts
CHANGED
|
@@ -1,114 +1,307 @@
|
|
|
1
1
|
import type { paths } from "../schema.js";
|
|
2
2
|
import type { Body, CallOptions, LexNodeResult, MethodOf, Query, RequestArgs, RetryPolicy } from "./types.js";
|
|
3
|
+
/** As opções de `createLexNodeClient`. */
|
|
3
4
|
export interface LexNodeClientOptions {
|
|
4
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* Endereço da API, por exemplo `https://api.lexnode.com.br`. Precisa usar
|
|
7
|
+
* https, exceto no host local (`localhost`, `127.0.0.1` ou `::1`).
|
|
8
|
+
*/
|
|
5
9
|
baseUrl: string;
|
|
6
10
|
/**
|
|
7
|
-
* Chave de
|
|
8
|
-
*
|
|
11
|
+
* Chave de API da conta, enviada como `Authorization: Bearer`. Guarde-a só
|
|
12
|
+
* no servidor.
|
|
9
13
|
*/
|
|
10
14
|
apiKey: string;
|
|
11
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Escritório (sub-tenant) atribuído a toda chamada, no cabeçalho
|
|
17
|
+
* `X-Office-Id`. Cada chamada pode trocá-lo ou omiti-lo em
|
|
18
|
+
* `CallOptions.officeId`.
|
|
19
|
+
*/
|
|
12
20
|
officeId?: string;
|
|
13
21
|
/**
|
|
14
|
-
* Prazo de cada chamada, em ms. Padrão: 30
|
|
15
|
-
* processo
|
|
16
|
-
*
|
|
17
|
-
* da API
|
|
22
|
+
* Prazo de cada chamada, em ms. Padrão: 30 000. Na ficha e no retrato de um
|
|
23
|
+
* processo e em `processLookups.create`, o prazo é o maior entre este valor
|
|
24
|
+
* e a espera pela fonte mais 15 s — `waitSeconds` ou, sem ele, os 20 s
|
|
25
|
+
* padrão da API.
|
|
18
26
|
*/
|
|
19
27
|
timeoutMs?: number;
|
|
20
|
-
/**
|
|
28
|
+
/** O `fetch` a usar no lugar do global, por exemplo num teste. */
|
|
21
29
|
fetch?: typeof globalThis.fetch;
|
|
22
|
-
/** Identifica a sua integração no `User-Agent`. */
|
|
30
|
+
/** Identifica a sua integração no cabeçalho `User-Agent`. */
|
|
23
31
|
userAgent?: string;
|
|
24
|
-
/** Política de retentativa
|
|
32
|
+
/** Política de retentativa de toda chamada. Sem ela, nada é repetido. */
|
|
25
33
|
retry?: RetryPolicy;
|
|
26
34
|
}
|
|
27
35
|
/**
|
|
28
|
-
*
|
|
36
|
+
* Cria o cliente da API do LexNode.
|
|
29
37
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* `X-Office-Id`.
|
|
38
|
+
* Toda chamada envia `Authorization: Bearer`, `X-Request-Id`, `X-Trace-Id` e,
|
|
39
|
+
* quando houver, `X-Office-Id`, e devolve `{ data, meta }` tipados pela rota.
|
|
40
|
+
* O `meta` traz, além do que o contrato declara, o código HTTP (`status`) e os
|
|
41
|
+
* cabeçalhos de limite de vazão (`rateLimit`). Toda recusa da API e toda falha
|
|
42
|
+
* de rede ou de prazo é lançada como `LexNodeError`.
|
|
36
43
|
*
|
|
37
|
-
*
|
|
44
|
+
* Use só no servidor: a chave é da conta inteira. Um app com usuários finais
|
|
45
|
+
* chama o próprio backend, e o backend chama a API.
|
|
46
|
+
*
|
|
47
|
+
* Lança `LexNodeError` (`CLIENT_INVALID_REQUEST`) quando `baseUrl` não é uma
|
|
48
|
+
* URL válida ou não usa https fora do host local.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* const lexnode = createLexNodeClient({
|
|
53
|
+
* baseUrl: "https://api.lexnode.com.br",
|
|
54
|
+
* apiKey: process.env.LEXNODE_API_KEY!,
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
* const { data, meta } = await lexnode.processes.get("00012345620268260100", {
|
|
58
|
+
* tribunalAlias: "TJSP",
|
|
59
|
+
* });
|
|
60
|
+
* ```
|
|
38
61
|
*/
|
|
39
62
|
export declare function createLexNodeClient(options: LexNodeClientOptions): {
|
|
63
|
+
/**
|
|
64
|
+
* Chama qualquer rota do contrato, tipada pelo caminho e pelo método.
|
|
65
|
+
*
|
|
66
|
+
* Use para as rotas sem método nomeado neste cliente. Recebe os parâmetros
|
|
67
|
+
* de caminho e de consulta em `params`, o corpo em `body` e as opções de
|
|
68
|
+
* `CallOptions`; devolve `{ data, meta }` e lança `LexNodeError` como os
|
|
69
|
+
* métodos nomeados.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* const { data } = await lexnode.request("/v1/precedents", "get", {
|
|
74
|
+
* params: { query: { query: "dano moral", limit: 20 } },
|
|
75
|
+
* });
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
40
78
|
request: <P extends keyof paths, M extends MethodOf<P>>(path: P, method: M, args: RequestArgs<P, M>) => Promise<LexNodeResult<P, M>>;
|
|
41
79
|
tribunals: {
|
|
80
|
+
/**
|
|
81
|
+
* Lista os tribunais aceitos (`GET /v1/tribunals`). As demais rotas
|
|
82
|
+
* aceitam o tribunal pela sigla (`code`) que vem daqui.
|
|
83
|
+
*/
|
|
42
84
|
list: (query?: Query<"/v1/tribunals", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/tribunals", "get">>;
|
|
43
85
|
};
|
|
44
86
|
processes: {
|
|
87
|
+
/**
|
|
88
|
+
* Busca processos num tribunal (`POST /v1/processes/search`): 200 com o
|
|
89
|
+
* resultado ou 202 com a busca enfileirada. `searchProcesses` diz no
|
|
90
|
+
* tipo qual dos dois chegou.
|
|
91
|
+
*/
|
|
45
92
|
search: (body: Body<"/v1/processes/search", "post">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/processes/search", "post">>;
|
|
93
|
+
/**
|
|
94
|
+
* Lê a ficha de um processo (`GET /v1/processes/{processNumber}`).
|
|
95
|
+
* `waitSeconds` define quanto a API espera pela fonte processual; sem
|
|
96
|
+
* `timeoutMs`, o prazo da chamada acompanha essa espera.
|
|
97
|
+
*/
|
|
46
98
|
get: (processNumber: string, query: Query<"/v1/processes/{processNumber}", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/processes/{processNumber}", "get">>;
|
|
99
|
+
/**
|
|
100
|
+
* Lista as movimentações guardadas de um processo, sem consultar a fonte
|
|
101
|
+
* (`GET /v1/processes/{processNumber}/movements`). `degree` recorta a
|
|
102
|
+
* lista por grau.
|
|
103
|
+
*/
|
|
47
104
|
movements: (processNumber: string, query: Query<"/v1/processes/{processNumber}/movements", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/processes/{processNumber}/movements", "get">>;
|
|
105
|
+
/**
|
|
106
|
+
* Lê o retrato de um processo na fonte processual — o processo, as
|
|
107
|
+
* movimentações e as instâncias do número
|
|
108
|
+
* (`GET /v1/processes/{processNumber}/snapshot`). Como em `get`, o prazo
|
|
109
|
+
* da chamada acompanha `waitSeconds`.
|
|
110
|
+
*/
|
|
48
111
|
snapshot: (processNumber: string, query: Query<"/v1/processes/{processNumber}/snapshot", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/processes/{processNumber}/snapshot", "get">>;
|
|
112
|
+
/**
|
|
113
|
+
* Lista processos relacionados ao consultado: o mesmo número em outro
|
|
114
|
+
* tribunal e números citados nas movimentações
|
|
115
|
+
* (`GET /v1/processes/{processNumber}/related`).
|
|
116
|
+
*/
|
|
49
117
|
related: (processNumber: string, query: Query<"/v1/processes/{processNumber}/related", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/processes/{processNumber}/related", "get">>;
|
|
118
|
+
/**
|
|
119
|
+
* Lê o retrato de vários processos numa chamada
|
|
120
|
+
* (`POST /v1/processes/snapshot-batch`). Cada item traz o próprio
|
|
121
|
+
* resultado ou erro, e só os itens concluídos são cobrados.
|
|
122
|
+
*/
|
|
50
123
|
snapshotBatch: (body: Body<"/v1/processes/snapshot-batch", "post">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/processes/snapshot-batch", "post">>;
|
|
51
124
|
};
|
|
52
125
|
publications: {
|
|
126
|
+
/**
|
|
127
|
+
* Lista as publicações do diário que casam com os filtros
|
|
128
|
+
* (`GET /v1/publications`).
|
|
129
|
+
*/
|
|
53
130
|
list: (query?: Query<"/v1/publications", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/publications", "get">>;
|
|
131
|
+
/**
|
|
132
|
+
* Lê uma publicação completa pela chave que uma busca devolveu
|
|
133
|
+
* (`GET /v1/publications/{publicationKey}`), sem custo.
|
|
134
|
+
*/
|
|
54
135
|
read: (publicationKey: string, opts?: CallOptions) => Promise<LexNodeResult<"/v1/publications/{publicationKey}", "get">>;
|
|
136
|
+
/**
|
|
137
|
+
* Pesquisa jurisprudência por texto e guarda o resultado
|
|
138
|
+
* (`POST /v1/publications/text-searches`). Reenviar com o mesmo
|
|
139
|
+
* `requestId` devolve a busca já feita, sem nova cobrança.
|
|
140
|
+
*/
|
|
55
141
|
textSearch: (body: Body<"/v1/publications/text-searches", "post">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/publications/text-searches", "post">>;
|
|
56
142
|
textAlerts: {
|
|
143
|
+
/**
|
|
144
|
+
* Salva uma vigília de texto (`POST /v1/publications/text-alerts`),
|
|
145
|
+
* que avisa por `PUBLICATION_TEXT_ALERT_MATCHED` quando publicações
|
|
146
|
+
* novas casam com a consulta.
|
|
147
|
+
*/
|
|
57
148
|
create: (body: Body<"/v1/publications/text-alerts", "post">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/publications/text-alerts", "post">>;
|
|
149
|
+
/**
|
|
150
|
+
* Lista as vigílias de texto da conta
|
|
151
|
+
* (`GET /v1/publications/text-alerts`).
|
|
152
|
+
*/
|
|
58
153
|
list: (query?: Query<"/v1/publications/text-alerts", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/publications/text-alerts", "get">>;
|
|
154
|
+
/**
|
|
155
|
+
* Remove uma vigília de texto
|
|
156
|
+
* (`DELETE /v1/publications/text-alerts/{alertId}`).
|
|
157
|
+
*/
|
|
59
158
|
delete: (alertId: string, opts?: CallOptions) => Promise<LexNodeResult<"/v1/publications/text-alerts/{alertId}", "delete">>;
|
|
60
159
|
};
|
|
61
160
|
};
|
|
62
161
|
monitors: {
|
|
162
|
+
/**
|
|
163
|
+
* Cria um monitor (`POST /v1/monitors`). Um alvo já vigiado é recusado
|
|
164
|
+
* com 409 `MONITOR_ALREADY_EXISTS`, e `error.details.monitorId` traz o
|
|
165
|
+
* id do monitor existente.
|
|
166
|
+
*/
|
|
63
167
|
create: (body: Body<"/v1/monitors", "post">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/monitors", "post">>;
|
|
168
|
+
/**
|
|
169
|
+
* Lista os monitores da conta (`GET /v1/monitors`); use `paginate` para
|
|
170
|
+
* percorrer as páginas.
|
|
171
|
+
*/
|
|
64
172
|
list: (query?: Query<"/v1/monitors", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/monitors", "get">>;
|
|
173
|
+
/** Lê um monitor (`GET /v1/monitors/{monitorId}`). */
|
|
65
174
|
get: (monitorId: string, opts?: CallOptions) => Promise<LexNodeResult<"/v1/monitors/{monitorId}", "get">>;
|
|
175
|
+
/**
|
|
176
|
+
* Muda o status de um monitor — `ACTIVE`, `PAUSED` ou `DISABLED`
|
|
177
|
+
* (`PATCH /v1/monitors/{monitorId}`).
|
|
178
|
+
*/
|
|
66
179
|
update: (monitorId: string, body: Body<"/v1/monitors/{monitorId}", "patch">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/monitors/{monitorId}", "patch">>;
|
|
180
|
+
/** Exclui um monitor (`DELETE /v1/monitors/{monitorId}`). */
|
|
67
181
|
delete: (monitorId: string, opts?: CallOptions) => Promise<LexNodeResult<"/v1/monitors/{monitorId}", "delete">>;
|
|
182
|
+
/**
|
|
183
|
+
* Pede uma varredura do monitor sem esperar a agenda
|
|
184
|
+
* (`POST /v1/monitors/{monitorId}/sync`). O resultado chega em
|
|
185
|
+
* `MONITOR_SYNC_SUCCEEDED` ou `MONITOR_SYNC_FAILED`.
|
|
186
|
+
*/
|
|
68
187
|
sync: (monitorId: string, opts?: CallOptions) => Promise<LexNodeResult<"/v1/monitors/{monitorId}/sync", "post">>;
|
|
69
188
|
};
|
|
70
189
|
subscriptions: {
|
|
190
|
+
/**
|
|
191
|
+
* Declara interesse num processo (`POST /v1/subscriptions`). A conta
|
|
192
|
+
* passa a receber `PROCESS_MOVEMENT_CREATED`, com o `externalRef`
|
|
193
|
+
* informado, e `PROCESS_INSTANCE_DISCOVERED`. Repetir com o mesmo
|
|
194
|
+
* `reason` e `externalRef` devolve a mesma assinatura.
|
|
195
|
+
*/
|
|
71
196
|
create: (body: Body<"/v1/subscriptions", "post">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/subscriptions", "post">>;
|
|
197
|
+
/** Lista as assinaturas da conta (`GET /v1/subscriptions`). */
|
|
72
198
|
list: (query?: Query<"/v1/subscriptions", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/subscriptions", "get">>;
|
|
199
|
+
/**
|
|
200
|
+
* Desativa as assinaturas da conta e do escritório da chamada que têm o
|
|
201
|
+
* `reason` e o `externalRef` informados (`DELETE /v1/subscriptions`).
|
|
202
|
+
*/
|
|
73
203
|
delete: (body: Body<"/v1/subscriptions", "delete">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/subscriptions", "delete">>;
|
|
74
204
|
};
|
|
75
205
|
processLookups: {
|
|
76
206
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
207
|
+
* Lê um processo e segue em segundo plano quando a fonte não entrega
|
|
208
|
+
* dentro de `waitSeconds` (`POST /v1/processes/lookups`): 200 com o
|
|
209
|
+
* processo, ou 202 com a consulta aberta. Pedir a mesma leitura de novo
|
|
210
|
+
* devolve a mesma consulta, então a retentativa vale para esta chamada
|
|
211
|
+
* como para uma leitura. `lookupProcess` diz no tipo qual dos dois
|
|
212
|
+
* desfechos chegou.
|
|
82
213
|
*/
|
|
83
214
|
create: (body: Body<"/v1/processes/lookups", "post">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/processes/lookups", "post">>;
|
|
215
|
+
/**
|
|
216
|
+
* Lê uma consulta em segundo plano, sem custo
|
|
217
|
+
* (`GET /v1/processes/lookups/{lookupId}`).
|
|
218
|
+
*/
|
|
84
219
|
get: (lookupId: string, opts?: CallOptions) => Promise<LexNodeResult<"/v1/processes/lookups/{lookupId}", "get">>;
|
|
220
|
+
/** Lista as consultas em segundo plano (`GET /v1/processes/lookups`). */
|
|
85
221
|
list: (query?: Query<"/v1/processes/lookups", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/processes/lookups", "get">>;
|
|
222
|
+
/**
|
|
223
|
+
* Cancela uma consulta aberta e devolve os créditos retidos
|
|
224
|
+
* (`POST /v1/processes/lookups/{lookupId}/cancel`).
|
|
225
|
+
*/
|
|
86
226
|
cancel: (lookupId: string, opts?: CallOptions) => Promise<LexNodeResult<"/v1/processes/lookups/{lookupId}/cancel", "post">>;
|
|
87
227
|
};
|
|
88
228
|
searchJobs: {
|
|
229
|
+
/** Lê uma busca enfileirada (`GET /v1/search-jobs/{jobId}`). */
|
|
89
230
|
get: (jobId: string, opts?: CallOptions) => Promise<LexNodeResult<"/v1/search-jobs/{jobId}", "get">>;
|
|
231
|
+
/** Lista as buscas enfileiradas (`GET /v1/search-jobs`). */
|
|
90
232
|
list: (query?: Query<"/v1/search-jobs", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/search-jobs", "get">>;
|
|
233
|
+
/**
|
|
234
|
+
* Cancela uma busca que ainda não terminou e devolve os créditos
|
|
235
|
+
* retidos (`POST /v1/search-jobs/{jobId}/cancel`).
|
|
236
|
+
*/
|
|
91
237
|
cancel: (jobId: string, opts?: CallOptions) => Promise<LexNodeResult<"/v1/search-jobs/{jobId}/cancel", "post">>;
|
|
92
238
|
};
|
|
93
239
|
events: {
|
|
240
|
+
/**
|
|
241
|
+
* Lista os eventos da conta, do mais recente ao mais antigo, com o
|
|
242
|
+
* estado de entrega de cada um (`GET /v1/events`).
|
|
243
|
+
*/
|
|
94
244
|
list: (query?: Query<"/v1/events", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/events", "get">>;
|
|
245
|
+
/** Lê um evento (`GET /v1/events/{eventId}`). */
|
|
95
246
|
get: (eventId: string, opts?: CallOptions) => Promise<LexNodeResult<"/v1/events/{eventId}", "get">>;
|
|
96
247
|
};
|
|
97
248
|
usage: {
|
|
249
|
+
/**
|
|
250
|
+
* Lê o uso do período: créditos usados e restantes, e o consumo por
|
|
251
|
+
* escritório (`GET /v1/usage`).
|
|
252
|
+
*/
|
|
98
253
|
get: (query?: Query<"/v1/usage", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/usage", "get">>;
|
|
99
254
|
};
|
|
100
255
|
webhooks: {
|
|
101
256
|
endpoints: {
|
|
257
|
+
/** Lista os endpoints de webhook (`GET /v1/webhooks/endpoints`). */
|
|
102
258
|
list: (query?: Query<"/v1/webhooks/endpoints", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/webhooks/endpoints", "get">>;
|
|
259
|
+
/**
|
|
260
|
+
* Cadastra um endpoint de webhook (`POST /v1/webhooks/endpoints`). O
|
|
261
|
+
* segredo de assinatura vem só nesta resposta, em `signingSecret`:
|
|
262
|
+
* guarde-o.
|
|
263
|
+
*/
|
|
103
264
|
create: (body: Body<"/v1/webhooks/endpoints", "post">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/webhooks/endpoints", "post">>;
|
|
265
|
+
/**
|
|
266
|
+
* Altera um endpoint, como a URL ou os eventos assinados
|
|
267
|
+
* (`PATCH /v1/webhooks/endpoints/{endpointId}`).
|
|
268
|
+
*/
|
|
104
269
|
update: (endpointId: string, body: Body<"/v1/webhooks/endpoints/{endpointId}", "patch">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/webhooks/endpoints/{endpointId}", "patch">>;
|
|
270
|
+
/**
|
|
271
|
+
* Exclui um endpoint
|
|
272
|
+
* (`DELETE /v1/webhooks/endpoints/{endpointId}`).
|
|
273
|
+
*/
|
|
105
274
|
delete: (endpointId: string, opts?: CallOptions) => Promise<LexNodeResult<"/v1/webhooks/endpoints/{endpointId}", "delete">>;
|
|
275
|
+
/**
|
|
276
|
+
* Envia na hora uma entrega de teste (`WEBHOOK_TEST`) ao endpoint e
|
|
277
|
+
* devolve o resultado
|
|
278
|
+
* (`POST /v1/webhooks/endpoints/{endpointId}/test`).
|
|
279
|
+
*/
|
|
106
280
|
test: (endpointId: string, opts?: CallOptions) => Promise<LexNodeResult<"/v1/webhooks/endpoints/{endpointId}/test", "post">>;
|
|
281
|
+
/**
|
|
282
|
+
* Gera um novo segredo de assinatura e invalida o anterior na hora
|
|
283
|
+
* (`POST /v1/webhooks/endpoints/{endpointId}/rotate-secret`). Atualize
|
|
284
|
+
* o seu receptor com o segredo novo, que vem só nesta resposta.
|
|
285
|
+
*/
|
|
107
286
|
rotateSecret: (endpointId: string, opts?: CallOptions) => Promise<LexNodeResult<"/v1/webhooks/endpoints/{endpointId}/rotate-secret", "post">>;
|
|
108
287
|
};
|
|
288
|
+
/**
|
|
289
|
+
* Lista as entregas de webhook da conta
|
|
290
|
+
* (`GET /v1/webhooks/deliveries`).
|
|
291
|
+
*/
|
|
109
292
|
deliveries: (query?: Query<"/v1/webhooks/deliveries", "get">, opts?: CallOptions) => Promise<LexNodeResult<"/v1/webhooks/deliveries", "get">>;
|
|
293
|
+
/**
|
|
294
|
+
* Lê a fila e as entregas e falhas das últimas 24 h de cada endpoint
|
|
295
|
+
* (`GET /v1/webhooks/health`).
|
|
296
|
+
*/
|
|
110
297
|
health: (opts?: CallOptions) => Promise<LexNodeResult<"/v1/webhooks/health", "get">>;
|
|
298
|
+
/**
|
|
299
|
+
* Lista os tipos de evento que a conta produziu nos últimos 30 dias e
|
|
300
|
+
* que nenhum endpoint ativo assina
|
|
301
|
+
* (`GET /v1/webhooks/unsubscribed-event-types`).
|
|
302
|
+
*/
|
|
111
303
|
unsubscribedEventTypes: (opts?: CallOptions) => Promise<LexNodeResult<"/v1/webhooks/unsubscribed-event-types", "get">>;
|
|
112
304
|
};
|
|
113
305
|
};
|
|
306
|
+
/** O cliente que `createLexNodeClient` devolve. */
|
|
114
307
|
export type LexNodeClient = ReturnType<typeof createLexNodeClient>;
|
package/dist/client.js
CHANGED
|
@@ -3,49 +3,19 @@ import { LexNodeError } from "./errors.js";
|
|
|
3
3
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
4
4
|
const DEFAULT_RETRY_BASE_DELAY_MS = 500;
|
|
5
5
|
const DEFAULT_RETRY_MAX_DELAY_MS = 8_000;
|
|
6
|
-
/** Métodos cuja repetição não cria nada de novo, por definição do HTTP. */
|
|
7
6
|
const IDEMPOTENT_METHODS = new Set(["get", "delete"]);
|
|
8
|
-
/**
|
|
9
|
-
* As escritas cuja repetição o CONTRATO declara segura, com o `X-Request-Id`
|
|
10
|
-
* fixado pelo chamador.
|
|
11
|
-
*
|
|
12
|
-
* Só uma rota trata esse cabeçalho como chave de replay; nas demais ele é
|
|
13
|
-
* rastreio, e repetir cria um segundo recurso — dois endpoints de webhook para
|
|
14
|
-
* a mesma URL entregam cada evento em dobro, e o segredo do primeiro fica
|
|
15
|
-
* órfão. Por isso a decisão é pela ROTA, nunca pela presença de um id.
|
|
16
|
-
*/
|
|
17
7
|
const REQUEST_ID_IDEMPOTENT_WRITES = new Set([
|
|
18
8
|
"post /v1/publications/text-searches",
|
|
19
9
|
]);
|
|
20
|
-
/**
|
|
21
|
-
* As chamadas em que quem chama escolhe, em `waitSeconds`, quanto o motor
|
|
22
|
-
* espera pela fonte processual, e onde a espera viaja: na consulta das duas
|
|
23
|
-
* leituras de UM processo, no corpo da leitura que segue em segundo plano.
|
|
24
|
-
*/
|
|
25
10
|
const SOURCE_WAIT_ROUTES = new Map([
|
|
26
11
|
["get /v1/processes/{processNumber}", "query"],
|
|
27
12
|
["get /v1/processes/{processNumber}/snapshot", "query"],
|
|
28
13
|
["post /v1/processes/lookups", "body"],
|
|
29
14
|
]);
|
|
30
|
-
/**
|
|
31
|
-
* A espera que o motor aplica a essas leituras quando a chamada não traz
|
|
32
|
-
* `waitSeconds`: o padrão do parâmetro no contrato.
|
|
33
|
-
*/
|
|
34
15
|
const SOURCE_WAIT_API_DEFAULT_SECONDS = 20;
|
|
35
|
-
/**
|
|
36
|
-
* O que a chamada espera além da espera do motor: na ficha, até 10 s de
|
|
37
|
-
* enriquecimento depois da fonte, e a rede.
|
|
38
|
-
*/
|
|
39
16
|
const SOURCE_WAIT_MARGIN_MS = 15_000;
|
|
40
|
-
/** O que um valor de cabeçalho não pode conter: `fetch` recusa montá-lo. */
|
|
41
17
|
const FORBIDDEN_HEADER_CHARS = /[\r\n\0]/u;
|
|
42
|
-
/** Hosts em que falar claro é desenvolvimento, não credencial exposta. */
|
|
43
18
|
const LOCAL_HOSTS = new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
|
|
44
|
-
/**
|
|
45
|
-
* A chave é de CONTA e viaja em todo pedido: sem TLS ela vai em texto claro
|
|
46
|
-
* para quem estiver no caminho. É a mesma recusa que o motor aplica à própria
|
|
47
|
-
* URL de produção — só o host local fica de fora, porque ali não há caminho.
|
|
48
|
-
*/
|
|
49
19
|
function requireSecureBaseUrl(baseUrl) {
|
|
50
20
|
let parsed;
|
|
51
21
|
try {
|
|
@@ -65,12 +35,6 @@ function readHeaderNumber(headers, name) {
|
|
|
65
35
|
const parsed = Number(raw);
|
|
66
36
|
return Number.isFinite(parsed) ? parsed : null;
|
|
67
37
|
}
|
|
68
|
-
/**
|
|
69
|
-
* O teto por minuto sai em TODA resposta autenticada, não só na recusa. Lê-lo
|
|
70
|
-
* no sucesso é o que permite ao consumidor desacelerar ANTES de bater no 429.
|
|
71
|
-
* O `Retry-After` só conta na recusa: no sucesso ele é a espera que a fonte
|
|
72
|
-
* pediu a uma leitura socorrida pelo acervo, e sai em `meta.lakeRescue`.
|
|
73
|
-
*/
|
|
74
38
|
function readRateLimit(headers, succeeded) {
|
|
75
39
|
const limit = readHeaderNumber(headers, "RateLimit-Limit");
|
|
76
40
|
const remaining = readHeaderNumber(headers, "RateLimit-Remaining");
|
|
@@ -111,14 +75,6 @@ function appendQuery(url, query) {
|
|
|
111
75
|
}
|
|
112
76
|
}
|
|
113
77
|
}
|
|
114
|
-
/**
|
|
115
|
-
* O prazo da chamada que não trouxe `timeoutMs` próprio.
|
|
116
|
-
*
|
|
117
|
-
* Numa leitura que espera pela fonte, o motor pode levar a espera inteira
|
|
118
|
-
* antes de responder — a de `waitSeconds` ou, sem ele, a padrão da API: o
|
|
119
|
-
* prazo cobre essa espera mais a margem e nunca fica abaixo do prazo do
|
|
120
|
-
* cliente. Nas outras rotas, vale o prazo do cliente.
|
|
121
|
-
*/
|
|
122
78
|
function defaultCallTimeoutMs(method, path, carriers, clientTimeoutMs) {
|
|
123
79
|
const carrier = SOURCE_WAIT_ROUTES.get(`${method} ${path}`);
|
|
124
80
|
if (!carrier)
|
|
@@ -132,15 +88,6 @@ function defaultCallTimeoutMs(method, path, carriers, clientTimeoutMs) {
|
|
|
132
88
|
: SOURCE_WAIT_API_DEFAULT_SECONDS;
|
|
133
89
|
return Math.max(clientTimeoutMs, waitSeconds * 1_000 + SOURCE_WAIT_MARGIN_MS);
|
|
134
90
|
}
|
|
135
|
-
/**
|
|
136
|
-
* Junta o prazo do cliente ao `signal` de quem chamou.
|
|
137
|
-
*
|
|
138
|
-
* Os dois abortam a mesma requisição, e trocar um pelo outro perde metade do
|
|
139
|
-
* controle: sem o prazo, uma chamada sem resposta fica pendurada; sem o sinal
|
|
140
|
-
* de quem chamou, o cancelamento da requisição de cima não alcança a de baixo.
|
|
141
|
-
* O motivo do aborto é preservado para o prazo virar 504 e o cancelamento de
|
|
142
|
-
* fora continuar sendo cancelamento.
|
|
143
|
-
*/
|
|
144
91
|
function linkAbort(timeoutMs, caller) {
|
|
145
92
|
const controller = new AbortController();
|
|
146
93
|
let timedOut = false;
|
|
@@ -184,19 +131,6 @@ function sleep(ms, signal) {
|
|
|
184
131
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
185
132
|
});
|
|
186
133
|
}
|
|
187
|
-
/**
|
|
188
|
-
* Se vale repetir esta chamada.
|
|
189
|
-
*
|
|
190
|
-
* A classe do erro diz se a condição passa sozinha; o método e a ROTA dizem se
|
|
191
|
-
* repetir é seguro. Uma escrita fora da lista só é repetida quando quem chama
|
|
192
|
-
* declara `idempotent: true` — quem conhece o próprio uso pode afirmar o que o
|
|
193
|
-
* contrato não afirma, mas a afirmação é dele, e explícita.
|
|
194
|
-
*
|
|
195
|
-
* O tempo esgotado da fonte (`UPSTREAM_TIMEOUT`) numa leitura que espera por
|
|
196
|
-
* ela não se repete: o motor já esperou tudo o que a chamada pediu, e repetir
|
|
197
|
-
* na hora dobra a espera diante da mesma fonte lenta. As demais recusas
|
|
198
|
-
* retentáveis dessas leituras seguem a política.
|
|
199
|
-
*/
|
|
200
134
|
function mayRetry(error, method, path, options) {
|
|
201
135
|
if (!(error instanceof LexNodeError) || !error.retryable)
|
|
202
136
|
return false;
|
|
@@ -213,22 +147,11 @@ function mayRetry(error, method, path, options) {
|
|
|
213
147
|
}
|
|
214
148
|
function retryDelayMs(policy, attempt, error) {
|
|
215
149
|
if (error.retryAfterSeconds !== null && error.retryAfterSeconds >= 0) {
|
|
216
|
-
|
|
150
|
+
const asked = error.retryAfterSeconds * 1_000;
|
|
151
|
+
return asked > policy.maxDelayMs ? null : asked;
|
|
217
152
|
}
|
|
218
153
|
return Math.min(policy.baseDelayMs * 2 ** (attempt - 1), policy.maxDelayMs);
|
|
219
154
|
}
|
|
220
|
-
/**
|
|
221
|
-
* O cliente de runtime do motor de dados jurídicos.
|
|
222
|
-
*
|
|
223
|
-
* **Servidor apenas, e só por TLS.** A credencial é de CONTA: uma chave no
|
|
224
|
-
* browser é uma chave publicada, e uma chave em `http://` é uma chave lida por
|
|
225
|
-
* quem estiver no caminho — `baseUrl` sem https é recusada aqui, exceto em
|
|
226
|
-
* host local. Um app com usuários finais fala com o próprio backend, e é o
|
|
227
|
-
* backend que fala com o motor — atribuindo cada chamada ao seu sub-tenant por
|
|
228
|
-
* `X-Office-Id`.
|
|
229
|
-
*
|
|
230
|
-
* Sem dependências de runtime: `fetch` global e `node:crypto`.
|
|
231
|
-
*/
|
|
232
155
|
export function createLexNodeClient(options) {
|
|
233
156
|
requireSecureBaseUrl(options.baseUrl);
|
|
234
157
|
const baseUrl = options.baseUrl.replace(/\/+$/u, "");
|
|
@@ -251,9 +174,6 @@ export function createLexNodeClient(options) {
|
|
|
251
174
|
headers["user-agent"] = options.userAgent;
|
|
252
175
|
if (bag.body !== undefined)
|
|
253
176
|
headers["content-type"] = "application/json";
|
|
254
|
-
// Cabeçalho e corpo são montados ANTES de abrir o socket: o que o
|
|
255
|
-
// transporte recusa montar é defeito do pedido, não falha passageira de
|
|
256
|
-
// rede, e repetir o que nunca saiu só gasta as tentativas.
|
|
257
177
|
for (const [name, value] of Object.entries(headers)) {
|
|
258
178
|
if (FORBIDDEN_HEADER_CHARS.test(value)) {
|
|
259
179
|
throw LexNodeError.invalidRequest(`O cabeçalho ${name} tem quebra de linha ou caractere nulo.`);
|
|
@@ -278,20 +198,14 @@ export function createLexNodeClient(options) {
|
|
|
278
198
|
headers,
|
|
279
199
|
body: payload,
|
|
280
200
|
signal: link.signal,
|
|
281
|
-
// O contrato não redireciona; seguir um 30x entregaria ao consumidor o
|
|
282
|
-
// corpo de outro host como se fosse a resposta do motor.
|
|
283
201
|
redirect: "error",
|
|
284
202
|
});
|
|
285
203
|
rateLimit = readRateLimit(response.headers, response.ok);
|
|
286
|
-
// A leitura do corpo fica DENTRO do prazo: um corpo que trava depois dos
|
|
287
|
-
// cabeçalhos pendura a chamada por tempo indefinido se o vínculo já tiver
|
|
288
|
-
// sido desfeito aqui.
|
|
289
204
|
raw = await response.text();
|
|
290
205
|
}
|
|
291
206
|
catch (error) {
|
|
292
207
|
if (link.timedOut)
|
|
293
208
|
throw LexNodeError.timeout(timeoutMs, error);
|
|
294
|
-
// Cancelamento de quem chamou não é falha da API: sobe como veio.
|
|
295
209
|
if (args.signal?.aborted)
|
|
296
210
|
throw error;
|
|
297
211
|
throw LexNodeError.network(error);
|
|
@@ -324,13 +238,6 @@ export function createLexNodeClient(options) {
|
|
|
324
238
|
},
|
|
325
239
|
};
|
|
326
240
|
}
|
|
327
|
-
/**
|
|
328
|
-
* A chamada genérica, tipada pela rota e pelo método do contrato.
|
|
329
|
-
*
|
|
330
|
-
* Uma função cobre a superfície inteira: rota nova ou campo novo no
|
|
331
|
-
* `openapi.json` chega tipado sem uma linha a mais aqui. Os métodos nomeados
|
|
332
|
-
* abaixo só dão nome ao que um consumidor usa todo dia.
|
|
333
|
-
*/
|
|
334
241
|
async function request(path, method, args) {
|
|
335
242
|
const requestId = args.requestId ?? `req_${randomUUID()}`;
|
|
336
243
|
const traceId = args.traceId ?? `trc_${randomUUID()}`;
|
|
@@ -354,7 +261,10 @@ export function createLexNodeClient(options) {
|
|
|
354
261
|
})) {
|
|
355
262
|
throw error;
|
|
356
263
|
}
|
|
357
|
-
|
|
264
|
+
const delay = retryDelayMs(delays, round, error);
|
|
265
|
+
if (delay === null)
|
|
266
|
+
throw error;
|
|
267
|
+
await sleep(delay, args.signal);
|
|
358
268
|
round += 1;
|
|
359
269
|
}
|
|
360
270
|
}
|
|
@@ -430,13 +340,6 @@ export function createLexNodeClient(options) {
|
|
|
430
340
|
delete: (body, opts = {}) => request("/v1/subscriptions", "delete", { body, ...opts }),
|
|
431
341
|
},
|
|
432
342
|
processLookups: {
|
|
433
|
-
/**
|
|
434
|
-
* A leitura de UM processo que segue em segundo plano quando a fonte não
|
|
435
|
-
* entrega dentro de `waitSeconds`: 200 com o processo, ou 202 com a
|
|
436
|
-
* consulta aberta. Repetir é seguro — o motor devolve a consulta já
|
|
437
|
-
* aberta da mesma leitura em vez de abrir outra —, então a retentativa
|
|
438
|
-
* vale para ela como para uma leitura.
|
|
439
|
-
*/
|
|
440
343
|
create: (body, opts = {}) => request("/v1/processes/lookups", "post", {
|
|
441
344
|
body,
|
|
442
345
|
idempotent: true,
|