@lexnode/legal-data-sdk 1.30.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 +197 -191
- 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 +10 -6
- package/dist/index.js +0 -10
- package/dist/lookup.d.ts +105 -39
- package/dist/lookup.js +0 -40
- 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/lookup.d.ts
CHANGED
|
@@ -1,24 +1,32 @@
|
|
|
1
1
|
import type { LexNodeClient } from "./client.js";
|
|
2
2
|
import type { Body, CallOptions, Data, Meta, MetaExtras } from "./types.js";
|
|
3
|
-
/**
|
|
4
|
-
* A leitura de UM processo que segue em segundo plano responde de dois jeitos
|
|
5
|
-
* na MESMA operação: 200 com o processo, quando ele coube na espera, ou 202
|
|
6
|
-
* com a consulta que segue tentando a fonte sozinha. O discriminador é o
|
|
7
|
-
* código HTTP, como na busca: a consulta aberta também tem `status`, mas quem
|
|
8
|
-
* afirma o desfecho da chamada é o 200 ou o 202.
|
|
9
|
-
*/
|
|
10
3
|
type CreateData = Data<"/v1/processes/lookups", "post">;
|
|
11
4
|
type CreateMeta = Meta<"/v1/processes/lookups", "post"> & MetaExtras;
|
|
12
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* A consulta em segundo plano, como `GET /v1/processes/lookups/{lookupId}` a
|
|
7
|
+
* devolve.
|
|
8
|
+
*/
|
|
13
9
|
export type ProcessLookup = Data<"/v1/processes/lookups/{lookupId}", "get">;
|
|
10
|
+
/** O estado da consulta em segundo plano. */
|
|
14
11
|
export type ProcessLookupState = ProcessLookup["status"];
|
|
12
|
+
/** A visão pedida: `PROCESS` (a ficha) ou `SNAPSHOT` (o retrato). */
|
|
15
13
|
export type ProcessLookupView = ProcessLookup["view"];
|
|
16
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* O pedido de `POST /v1/processes/lookups`: o tribunal, o número, a visão, a
|
|
16
|
+
* espera pela fonte e se a cópia guardada serve na falha dela.
|
|
17
|
+
*/
|
|
17
18
|
export type ProcessLookupInput = Body<"/v1/processes/lookups", "post">;
|
|
18
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* A cópia guardada, com a data, que a resposta 202 traz quando o pedido tem
|
|
21
|
+
* `staleOnFailure: true`.
|
|
22
|
+
*/
|
|
19
23
|
export type StaleProcessCopy = NonNullable<CreateData["stale"]>;
|
|
20
|
-
/** O processo
|
|
24
|
+
/** O processo na visão pedida: a ficha ou o retrato. */
|
|
21
25
|
export type ProcessLookupRead<V extends ProcessLookupView> = V extends "SNAPSHOT" ? NonNullable<CreateData["snapshot"]> : NonNullable<CreateData["process"]>;
|
|
26
|
+
/**
|
|
27
|
+
* O desfecho de `lookupProcess`: `ready` com o processo em `data`, ou
|
|
28
|
+
* `pending` com a consulta aberta em `lookup`.
|
|
29
|
+
*/
|
|
22
30
|
export type ProcessLookupOutcome<V extends ProcessLookupView = ProcessLookupView> = {
|
|
23
31
|
kind: "ready";
|
|
24
32
|
/** A ficha ou o retrato, como a leitura direta os devolveria. */
|
|
@@ -27,56 +35,84 @@ export type ProcessLookupOutcome<V extends ProcessLookupView = ProcessLookupView
|
|
|
27
35
|
meta: CreateMeta;
|
|
28
36
|
} | {
|
|
29
37
|
kind: "pending";
|
|
30
|
-
/** A consulta aberta
|
|
38
|
+
/** A consulta aberta; acompanhe-a com `waitForProcessLookup`. */
|
|
31
39
|
lookup: CreateData;
|
|
32
40
|
/** A cópia guardada, com a data, quando pedida em `staleOnFailure`. */
|
|
33
41
|
stale: StaleProcessCopy | null;
|
|
34
42
|
meta: CreateMeta;
|
|
35
43
|
};
|
|
36
44
|
/**
|
|
37
|
-
* Lê um processo e diz
|
|
45
|
+
* Lê um processo e diz no tipo se ele veio na hora ou se a leitura seguiu em
|
|
46
|
+
* segundo plano.
|
|
38
47
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
48
|
+
* Chama `POST /v1/processes/lookups`. Com 200, devolve `kind: "ready"` e o
|
|
49
|
+
* processo em `data`, como a leitura direta o devolveria; com 202, devolve
|
|
50
|
+
* `kind: "pending"` e a consulta aberta em `lookup`, para acompanhar com
|
|
51
|
+
* `waitForProcessLookup` ou pelo evento `PROCESS_LOOKUP_COMPLETED`. Uma
|
|
52
|
+
* consulta aberta não é um processo sem dados. Pedir a mesma leitura de novo
|
|
53
|
+
* devolve a mesma consulta, então repetir é seguro, e a política de
|
|
54
|
+
* retentativa, quando ligada, repete esta chamada.
|
|
55
|
+
*
|
|
56
|
+
* Lança `LexNodeError` nas recusas da API e `INVALID_RESPONSE` quando o 200
|
|
57
|
+
* vem sem o processo da visão pedida.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const desfecho = await lookupProcess(lexnode, {
|
|
62
|
+
* tribunalAlias: "TJSP",
|
|
63
|
+
* processNumber: numero,
|
|
64
|
+
* view: "SNAPSHOT",
|
|
65
|
+
* });
|
|
66
|
+
* if (desfecho.kind === "ready") desfecho.data.movements;
|
|
67
|
+
* else guardarConsulta(desfecho.lookup.lookupId);
|
|
68
|
+
* ```
|
|
43
69
|
*/
|
|
44
70
|
export declare function lookupProcess<V extends ProcessLookupView>(client: LexNodeClient, input: ProcessLookupInput & {
|
|
45
71
|
view: V;
|
|
46
72
|
}, opts?: CallOptions): Promise<ProcessLookupOutcome<V>>;
|
|
73
|
+
/** As opções de `waitForProcessLookup`. */
|
|
47
74
|
export interface WaitForProcessLookupOptions {
|
|
48
75
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* ambiente serverless esperando uma fonte fora do ar.
|
|
76
|
+
* O tempo máximo de espera, em ms, contando as leituras e as retentativas.
|
|
77
|
+
* Padrão: 60 000. A consulta pode seguir tentando por horas; num ambiente
|
|
78
|
+
* serverless, escolha um valor que caiba no prazo da sua função.
|
|
53
79
|
*/
|
|
54
80
|
budgetMs?: number;
|
|
81
|
+
/** Cancela a espera; a consulta continua. */
|
|
55
82
|
signal?: AbortSignal;
|
|
56
|
-
/**
|
|
83
|
+
/**
|
|
84
|
+
* Chamada a cada leitura, com o estado, a consulta e o `meta`, por exemplo
|
|
85
|
+
* para mostrar o progresso.
|
|
86
|
+
*/
|
|
57
87
|
onState?: (state: ProcessLookupState, lookup: ProcessLookup, meta: Meta<"/v1/processes/lookups/{lookupId}", "get"> & MetaExtras) => void;
|
|
88
|
+
/** O escritório (sub-tenant) das leituras; veja `CallOptions.officeId`. */
|
|
58
89
|
officeId?: string | null;
|
|
59
90
|
}
|
|
60
91
|
/**
|
|
61
|
-
* Espera a consulta terminar
|
|
92
|
+
* Espera a consulta em segundo plano terminar e devolve a consulta terminada:
|
|
93
|
+
* `SUCCEEDED`, com o processo enquanto o resultado vale; `FAILED`, com
|
|
94
|
+
* `error`; ou `CANCELED`.
|
|
62
95
|
*
|
|
63
|
-
* Lê a consulta
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* cobra, mas conta no teto por minuto da chave.
|
|
96
|
+
* Lê a consulta na hora da próxima tentativa (`nextAttemptAt`), a cada 10 s
|
|
97
|
+
* enquanto uma tentativa está em curso ou na fila e, quando a leitura é
|
|
98
|
+
* recusada por vazão, depois do `Retry-After`. Ler a consulta não custa
|
|
99
|
+
* créditos, mas conta no limite de vazão da chave.
|
|
68
100
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* hora: esperar até o fim dele não mudaria nada. Devolve a consulta
|
|
75
|
-
* terminada: `SUCCEEDED`, com o processo enquanto o resultado vale; `FAILED`,
|
|
76
|
-
* com `error`; ou `CANCELED`.
|
|
101
|
+
* Lança `LexNodeError` `PROCESS_LOOKUP_BUDGET_EXCEEDED` (retentável) quando
|
|
102
|
+
* `budgetMs` acaba antes do fim, ou assim que a próxima leitura útil cairia
|
|
103
|
+
* depois dele. A consulta continua: `details.nextReadAt` diz quando vale ler
|
|
104
|
+
* de novo, e o evento `PROCESS_LOOKUP_COMPLETED` avisa o fim. Repassa as
|
|
105
|
+
* demais falhas das leituras.
|
|
77
106
|
*/
|
|
78
107
|
export declare function waitForProcessLookup(client: LexNodeClient, lookupId: string, options?: WaitForProcessLookupOptions): Promise<ProcessLookup>;
|
|
79
108
|
type ProcessRecoveryMeta = CreateMeta | (Meta<"/v1/processes/lookups/{lookupId}", "get"> & MetaExtras);
|
|
109
|
+
/**
|
|
110
|
+
* O desfecho de `readProcessWithRecovery`: `ready` com o processo; `pending`
|
|
111
|
+
* com a consulta aberta, a cópia guardada quando houver e a próxima leitura
|
|
112
|
+
* útil em `nextReadAt`; ou `failed`, `canceled` e `expired`, com a consulta
|
|
113
|
+
* terminada sem o processo. Nenhum desses três afirma que o processo não
|
|
114
|
+
* existe.
|
|
115
|
+
*/
|
|
80
116
|
export type ProcessRecoveryOutcome<V extends ProcessLookupView> = {
|
|
81
117
|
kind: "ready";
|
|
82
118
|
data: ProcessLookupRead<V>;
|
|
@@ -92,9 +128,39 @@ export type ProcessRecoveryOutcome<V extends ProcessLookupView> = {
|
|
|
92
128
|
lookup: ProcessLookup;
|
|
93
129
|
};
|
|
94
130
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
131
|
+
* Lê um processo com recuperação: abre a consulta e, quando ela segue em
|
|
132
|
+
* segundo plano, acompanha-a por até `completionBudgetMs`.
|
|
133
|
+
*
|
|
134
|
+
* `staleOnFailure` é obrigatório: com `true`, você aceita receber, na falha da
|
|
135
|
+
* fonte, uma cópia guardada anterior a ela — confira a data em
|
|
136
|
+
* `sourceFetchedAt`. Sem `completionBudgetMs`, ou com 0, devolve na hora o
|
|
137
|
+
* desfecho da abertura. Ao esgotar o orçamento, devolve `pending` com a mesma
|
|
138
|
+
* consulta, sem abrir outra nem cancelá-la; continue com
|
|
139
|
+
* `processLookups.get(lookupId)` ou pelo evento `PROCESS_LOOKUP_COMPLETED`.
|
|
140
|
+
* Abortar o `signal` interrompe a espera com o motivo do aborto e também não
|
|
141
|
+
* cancela a consulta.
|
|
142
|
+
*
|
|
143
|
+
* Lança `RangeError` quando `completionBudgetMs` é negativo ou não finito, e
|
|
144
|
+
* `LexNodeError` nas recusas da API.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```ts
|
|
148
|
+
* const leitura = await readProcessWithRecovery(
|
|
149
|
+
* lexnode,
|
|
150
|
+
* {
|
|
151
|
+
* tribunalAlias: "TJSP",
|
|
152
|
+
* processNumber,
|
|
153
|
+
* view: "PROCESS",
|
|
154
|
+
* staleOnFailure: true,
|
|
155
|
+
* },
|
|
156
|
+
* { completionBudgetMs: 30_000 },
|
|
157
|
+
* );
|
|
158
|
+
* if (leitura.kind === "ready") {
|
|
159
|
+
* usarProcesso(leitura.data);
|
|
160
|
+
* } else if (leitura.kind === "pending") {
|
|
161
|
+
* guardarConsulta(leitura.lookup.lookupId, leitura.nextReadAt);
|
|
162
|
+
* }
|
|
163
|
+
* ```
|
|
98
164
|
*/
|
|
99
165
|
export declare function readProcessWithRecovery<V extends ProcessLookupView>(client: LexNodeClient, input: ProcessLookupInput & {
|
|
100
166
|
view: V;
|
package/dist/lookup.js
CHANGED
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
import { LexNodeError, isLexNodeError } from "./errors.js";
|
|
2
|
-
/** O processo que a consulta entregou, na visão dela, ou nulo. */
|
|
3
2
|
function readOf(lookup, view) {
|
|
4
3
|
const read = view === "SNAPSHOT" ? lookup.snapshot : lookup.process;
|
|
5
4
|
return (read ?? null);
|
|
6
5
|
}
|
|
7
|
-
/**
|
|
8
|
-
* Lê um processo e diz, no tipo, qual dos dois desfechos aconteceu.
|
|
9
|
-
*
|
|
10
|
-
* Sem isto, o consumidor lê `data.process` num corpo que é uma consulta
|
|
11
|
-
* aberta e chama de "sem dados" o que é "ainda estou buscando". A mesma
|
|
12
|
-
* leitura pedida de novo devolve a mesma consulta — repetir é seguro, e o
|
|
13
|
-
* cliente repete sozinho quando a política de retentativa estiver ligada.
|
|
14
|
-
*/
|
|
15
6
|
export async function lookupProcess(client, input, opts = {}) {
|
|
16
7
|
const { data, meta } = await client.processLookups.create(input, opts);
|
|
17
8
|
if (meta.status === 202) {
|
|
@@ -30,17 +21,9 @@ export async function lookupProcess(client, input, opts = {}) {
|
|
|
30
21
|
}
|
|
31
22
|
return { kind: "ready", data: read, lookup: data, meta };
|
|
32
23
|
}
|
|
33
|
-
/** Estados em que a consulta não avança mais. */
|
|
34
24
|
const TERMINAL_STATES = new Set(["SUCCEEDED", "FAILED", "CANCELED"]);
|
|
35
25
|
const DEFAULT_BUDGET_MS = 60_000;
|
|
36
|
-
/** A menor espera entre duas leituras, para a próxima tentativa que está perto. */
|
|
37
26
|
const MIN_POLL_INTERVAL_MS = 2_000;
|
|
38
|
-
/**
|
|
39
|
-
* A espera entre leituras da consulta sem hora futura: a tentativa em curso
|
|
40
|
-
* (`nextAttemptAt` nulo) ou a vencida que espera a vez na fila. O desfecho
|
|
41
|
-
* dela sai em até um minuto, e ler a cada poucos segundos só gastaria o teto
|
|
42
|
-
* por minuto da chave.
|
|
43
|
-
*/
|
|
44
27
|
const IN_FLIGHT_POLL_INTERVAL_MS = 10_000;
|
|
45
28
|
function wait(ms, signal) {
|
|
46
29
|
return new Promise((resolve, reject) => {
|
|
@@ -75,24 +58,6 @@ function budgetExceeded(lookupId, budgetMs, state, nextReadAt) {
|
|
|
75
58
|
},
|
|
76
59
|
});
|
|
77
60
|
}
|
|
78
|
-
/**
|
|
79
|
-
* Espera a consulta terminar, dentro do orçamento.
|
|
80
|
-
*
|
|
81
|
-
* Lê a consulta de novo só quando há o que mudar: na hora da próxima tentativa
|
|
82
|
-
* (`nextAttemptAt`) — antes dela, a leitura devolve o mesmo estado —, a cada
|
|
83
|
-
* 10 s enquanto uma tentativa está em curso ou espera a vez na fila, e depois
|
|
84
|
-
* do `Retry-After` quando a própria leitura é recusada por vazão. Leitura não
|
|
85
|
-
* cobra, mas conta no teto por minuto da chave.
|
|
86
|
-
*
|
|
87
|
-
* O estouro do orçamento é um erro PRÓPRIO e retentável
|
|
88
|
-
* (`PROCESS_LOOKUP_BUDGET_EXCEEDED`): a consulta continua no motor, e quem
|
|
89
|
-
* espera pode voltar a lê-la depois — `details.nextReadAt` diz quando vale a
|
|
90
|
-
* pena — ou receber o `PROCESS_LOOKUP_COMPLETED` por webhook e não esperar
|
|
91
|
-
* nada. Quando a próxima leitura útil cai depois do orçamento, o erro sai na
|
|
92
|
-
* hora: esperar até o fim dele não mudaria nada. Devolve a consulta
|
|
93
|
-
* terminada: `SUCCEEDED`, com o processo enquanto o resultado vale; `FAILED`,
|
|
94
|
-
* com `error`; ou `CANCELED`.
|
|
95
|
-
*/
|
|
96
61
|
export async function waitForProcessLookup(client, lookupId, options = {}) {
|
|
97
62
|
const budgetMs = options.budgetMs ?? DEFAULT_BUDGET_MS;
|
|
98
63
|
const deadline = Date.now() + budgetMs;
|
|
@@ -156,11 +121,6 @@ export async function waitForProcessLookup(client, lookupId, options = {}) {
|
|
|
156
121
|
options.signal?.removeEventListener("abort", onCallerAbort);
|
|
157
122
|
}
|
|
158
123
|
}
|
|
159
|
-
/**
|
|
160
|
-
* Abre uma consulta recuperável e acompanha somente dentro do orçamento.
|
|
161
|
-
* A aceitação de cópia antiga é explícita. Ao esgotar a espera, devolve a
|
|
162
|
-
* consulta pendente, sem novo POST nem cancelamento do trabalho no motor.
|
|
163
|
-
*/
|
|
164
124
|
export async function readProcessWithRecovery(client, input, options = {}) {
|
|
165
125
|
const budgetMs = options.completionBudgetMs ?? 0;
|
|
166
126
|
options.signal?.throwIfAborted();
|
package/dist/paginate.d.ts
CHANGED
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
import type { paths } from "../schema.js";
|
|
2
2
|
import type { LexNodeClient } from "./client.js";
|
|
3
3
|
import type { Data, MethodOf, RequestArgs } from "./types.js";
|
|
4
|
+
/** As opções de `paginate`. */
|
|
4
5
|
export interface PaginateOptions {
|
|
5
6
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* antes de alguém perceber.
|
|
7
|
+
* O máximo de páginas lidas. Padrão: 100. Cada página é uma chamada, que
|
|
8
|
+
* conta no limite de vazão e, nas rotas que cobram, nos créditos.
|
|
9
9
|
*/
|
|
10
10
|
maxPages?: number;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Percorre uma rota paginada
|
|
13
|
+
* Percorre uma rota paginada e entrega o `data` de uma página por vez.
|
|
14
14
|
*
|
|
15
|
+
* Funciona com as três formas de paginação da API: o cursor em `meta`, o
|
|
16
|
+
* cursor em `data` e as consultas por página (`page` e `pageSize`) ou por
|
|
17
|
+
* deslocamento (`offset` e `limit`). Termina na última página ou quando o
|
|
18
|
+
* cursor se repete.
|
|
19
|
+
*
|
|
20
|
+
* Lança `LexNodeError` `PAGINATION_LIMIT_REACHED` (não retentável) ao passar
|
|
21
|
+
* de `maxPages` — aumente o limite ou restrinja a consulta — e repassa o erro
|
|
22
|
+
* de qualquer página.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
15
25
|
* ```ts
|
|
16
|
-
* for await (const page of paginate(
|
|
26
|
+
* for await (const page of paginate(lexnode, "/v1/monitors", "get", {})) {
|
|
17
27
|
* for (const monitor of page) console.log(monitor.id);
|
|
18
28
|
* }
|
|
19
29
|
* ```
|
package/dist/paginate.js
CHANGED
|
@@ -1,17 +1,4 @@
|
|
|
1
1
|
import { LexNodeError } from "./errors.js";
|
|
2
|
-
/**
|
|
3
|
-
* O laço de páginas, escrito uma vez.
|
|
4
|
-
*
|
|
5
|
-
* O motor pagina de três jeitos, herdados do que cada superfície precisava: o
|
|
6
|
-
* cursor no `meta` do envelope (rotas cujo `data` é um array), o cursor dentro
|
|
7
|
-
* do `data` (rotas com `items`), e o par página/tamanho ou deslocamento/teto da
|
|
8
|
-
* consulta de acervo. Sem isto, cada consumidor reescreve o mesmo laço três
|
|
9
|
-
* vezes — e o que ele erra é sempre o mesmo: para na primeira página, ou anda
|
|
10
|
-
* para sempre porque o cursor deixou de avançar.
|
|
11
|
-
*
|
|
12
|
-
* O cursor do `meta` não é declarado no contrato gerado (o `meta` daquelas
|
|
13
|
-
* rotas é aberto), então é lido aqui com conferência de tipo em runtime.
|
|
14
|
-
*/
|
|
15
2
|
const DEFAULT_MAX_PAGES = 100;
|
|
16
3
|
function asRecord(value) {
|
|
17
4
|
return value && typeof value === "object" && !Array.isArray(value)
|
|
@@ -26,19 +13,12 @@ function readNumber(bag, key) {
|
|
|
26
13
|
const value = bag?.[key];
|
|
27
14
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
28
15
|
}
|
|
29
|
-
/** Quantos itens a página trouxe, para o deslocamento andar pelo que veio. */
|
|
30
16
|
function pageLength(data, payload) {
|
|
31
17
|
if (Array.isArray(data))
|
|
32
18
|
return data.length;
|
|
33
19
|
const items = payload?.items;
|
|
34
20
|
return Array.isArray(items) ? items.length : 0;
|
|
35
21
|
}
|
|
36
|
-
/**
|
|
37
|
-
* A consulta da próxima página, ou `null` quando a última chegou.
|
|
38
|
-
*
|
|
39
|
-
* As três formas são decididas aqui, uma vez, na ordem em que o motor as usa —
|
|
40
|
-
* cursor primeiro, porque é a única que não depende de um `total`.
|
|
41
|
-
*/
|
|
42
22
|
function nextQuery(data, meta, query) {
|
|
43
23
|
const payload = asRecord(data);
|
|
44
24
|
const cursor = readCursor(asRecord(meta)) ?? readCursor(payload);
|
|
@@ -64,15 +44,6 @@ function nextQuery(data, meta, query) {
|
|
|
64
44
|
}
|
|
65
45
|
return null;
|
|
66
46
|
}
|
|
67
|
-
/**
|
|
68
|
-
* Percorre uma rota paginada página a página, na forma que ela usa.
|
|
69
|
-
*
|
|
70
|
-
* ```ts
|
|
71
|
-
* for await (const page of paginate(client, "/v1/monitors", "get", {})) {
|
|
72
|
-
* for (const monitor of page) console.log(monitor.id);
|
|
73
|
-
* }
|
|
74
|
-
* ```
|
|
75
|
-
*/
|
|
76
47
|
export async function* paginate(client, path, method, args, options = {}) {
|
|
77
48
|
const maxPages = options.maxPages ?? DEFAULT_MAX_PAGES;
|
|
78
49
|
let query = {
|
|
@@ -87,7 +58,6 @@ export async function* paginate(client, path, method, args, options = {}) {
|
|
|
87
58
|
});
|
|
88
59
|
yield data;
|
|
89
60
|
const proxima = nextQuery(data, meta, query);
|
|
90
|
-
// Cursor que não anda é laço infinito disfarçado de paginação.
|
|
91
61
|
if (!proxima ||
|
|
92
62
|
(proxima.cursor !== undefined && proxima.cursor === visto)) {
|
|
93
63
|
return;
|
package/dist/search.d.ts
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import type { LexNodeClient } from "./client.js";
|
|
2
2
|
import type { Body, CallOptions, Data, Meta, MetaExtras } from "./types.js";
|
|
3
|
-
/**
|
|
4
|
-
* A busca de processos responde de dois jeitos na MESMA operação: 200 com o
|
|
5
|
-
* resultado pronto, 202 com um trabalho enfileirado. O discriminador é o
|
|
6
|
-
* código HTTP — o corpo do 202 traz `jobId` e nenhum `items`, mas farejar
|
|
7
|
-
* campos é conclusão por ausência, e o status é a afirmação.
|
|
8
|
-
*/
|
|
9
3
|
type SearchData = Data<"/v1/processes/search", "post">;
|
|
10
4
|
type SearchMeta = Meta<"/v1/processes/search", "post"> & MetaExtras;
|
|
11
|
-
/** O resultado
|
|
5
|
+
/** O resultado pronto, que a busca devolve com 200. */
|
|
12
6
|
export type ProcessSearchResult = Extract<SearchData, {
|
|
13
7
|
items: unknown;
|
|
14
8
|
}>;
|
|
15
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* A busca enfileirada, que a busca devolve com 202; acompanhe-a com
|
|
11
|
+
* `waitForSearchJob`.
|
|
12
|
+
*/
|
|
16
13
|
export type QueuedSearchJob = Extract<SearchData, {
|
|
17
14
|
jobId: unknown;
|
|
18
15
|
}>;
|
|
16
|
+
/**
|
|
17
|
+
* O desfecho de `searchProcesses`: `sync` com o resultado em `result`, ou
|
|
18
|
+
* `async` com a busca enfileirada em `job`.
|
|
19
|
+
*/
|
|
19
20
|
export type ProcessSearchOutcome = {
|
|
20
21
|
kind: "sync";
|
|
21
22
|
result: ProcessSearchResult;
|
|
@@ -25,40 +26,73 @@ export type ProcessSearchOutcome = {
|
|
|
25
26
|
job: QueuedSearchJob;
|
|
26
27
|
meta: SearchMeta;
|
|
27
28
|
};
|
|
28
|
-
/**
|
|
29
|
+
/** A busca enfileirada, como `GET /v1/search-jobs/{jobId}` a devolve. */
|
|
29
30
|
export type SearchJob = Data<"/v1/search-jobs/{jobId}", "get">;
|
|
31
|
+
/** O estado da busca enfileirada. */
|
|
30
32
|
export type SearchJobState = SearchJob["status"];
|
|
33
|
+
/** As opções de `waitForSearchJob`. */
|
|
31
34
|
export interface WaitForSearchJobOptions {
|
|
32
35
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* requisição inteira antes de o trabalho concluir.
|
|
36
|
+
* O tempo máximo de espera, em ms. Padrão: 45 000. Num ambiente serverless,
|
|
37
|
+
* escolha um valor que caiba no prazo da sua função.
|
|
36
38
|
*/
|
|
37
39
|
budgetMs?: number;
|
|
38
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* A primeira espera entre leituras, em ms. Padrão: 1 500. Dobra a cada
|
|
42
|
+
* leitura, até `maxPollIntervalMs`.
|
|
43
|
+
*/
|
|
39
44
|
pollIntervalMs?: number;
|
|
45
|
+
/** A maior espera entre leituras, em ms. Padrão: 8 000. */
|
|
40
46
|
maxPollIntervalMs?: number;
|
|
47
|
+
/** Cancela a espera; a busca continua na fila. */
|
|
41
48
|
signal?: AbortSignal;
|
|
42
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Chamada a cada leitura, com o estado e a busca, por exemplo para mostrar
|
|
51
|
+
* o progresso.
|
|
52
|
+
*/
|
|
43
53
|
onState?: (state: SearchJobState, job: SearchJob) => void;
|
|
54
|
+
/** O escritório (sub-tenant) das leituras; veja `CallOptions.officeId`. */
|
|
44
55
|
officeId?: string | null;
|
|
45
56
|
}
|
|
46
57
|
/**
|
|
47
|
-
* Busca processos e diz
|
|
58
|
+
* Busca processos e diz no tipo se o resultado veio pronto ou se a busca foi
|
|
59
|
+
* enfileirada.
|
|
60
|
+
*
|
|
61
|
+
* `POST /v1/processes/search` responde 200 com o resultado ou 202 com a busca
|
|
62
|
+
* enfileirada. O desfecho `sync` traz o resultado em `result`; o `async` traz
|
|
63
|
+
* a busca em `job`, para acompanhar com `waitForSearchJob` ou pelo evento
|
|
64
|
+
* `SEARCH_JOB_COMPLETED`. Uma busca enfileirada não é um resultado vazio.
|
|
65
|
+
* Lança `LexNodeError` nas recusas da API.
|
|
48
66
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* const desfecho = await searchProcesses(lexnode, {
|
|
70
|
+
* tribunalAlias: "TJSP",
|
|
71
|
+
* number,
|
|
72
|
+
* });
|
|
73
|
+
* if (desfecho.kind === "sync") {
|
|
74
|
+
* desfecho.result.items;
|
|
75
|
+
* } else {
|
|
76
|
+
* const job = await waitForSearchJob(lexnode, desfecho.job.jobId, {
|
|
77
|
+
* budgetMs: 20_000,
|
|
78
|
+
* });
|
|
79
|
+
* job.status; // "SUCCEEDED" | "FAILED" | "CANCELED"
|
|
80
|
+
* }
|
|
81
|
+
* ```
|
|
51
82
|
*/
|
|
52
83
|
export declare function searchProcesses(client: LexNodeClient, body: Body<"/v1/processes/search", "post">, opts?: CallOptions): Promise<ProcessSearchOutcome>;
|
|
53
84
|
/**
|
|
54
|
-
* Espera
|
|
85
|
+
* Espera uma busca enfileirada terminar e devolve a busca em `SUCCEEDED`,
|
|
86
|
+
* `FAILED` ou `CANCELED`.
|
|
55
87
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
88
|
+
* Lê a busca de tempos em tempos, com espera crescente entre as leituras.
|
|
89
|
+
* Lança `LexNodeError` `SEARCH_JOB_BUDGET_EXCEEDED` (retentável) quando
|
|
90
|
+
* `budgetMs` acaba antes do fim: a busca continua na fila, e você pode voltar
|
|
91
|
+
* a lê-la depois ou receber o evento `SEARCH_JOB_COMPLETED`. Repassa os erros
|
|
92
|
+
* das leituras.
|
|
59
93
|
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
94
|
+
* Com a chave de teste (`lapi_test_`) não há busca a esperar: a busca
|
|
95
|
+
* assíncrona responde 403 `SANDBOX_UPSTREAM_DISABLED`.
|
|
62
96
|
*/
|
|
63
97
|
export declare function waitForSearchJob(client: LexNodeClient, jobId: string, options?: WaitForSearchJobOptions): Promise<SearchJob>;
|
|
64
98
|
export {};
|
package/dist/search.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { LexNodeError } from "./errors.js";
|
|
2
|
-
/** Estados em que o trabalho não avança mais. */
|
|
3
2
|
const TERMINAL_STATES = new Set(["SUCCEEDED", "FAILED", "CANCELED"]);
|
|
4
3
|
const DEFAULT_BUDGET_MS = 45_000;
|
|
5
4
|
const DEFAULT_POLL_INTERVAL_MS = 1_500;
|
|
@@ -22,12 +21,6 @@ function wait(ms, signal) {
|
|
|
22
21
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
23
22
|
});
|
|
24
23
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Busca processos e diz, no tipo, qual dos dois desfechos aconteceu.
|
|
27
|
-
*
|
|
28
|
-
* Sem isto, o consumidor lê `data.items` num corpo que só tem `jobId` e chama
|
|
29
|
-
* de "nenhum resultado" o que é "ainda estou buscando".
|
|
30
|
-
*/
|
|
31
24
|
export async function searchProcesses(client, body, opts = {}) {
|
|
32
25
|
const { data, meta } = await client.processes.search(body, opts);
|
|
33
26
|
if (meta.status === 202) {
|
|
@@ -35,16 +28,6 @@ export async function searchProcesses(client, body, opts = {}) {
|
|
|
35
28
|
}
|
|
36
29
|
return { kind: "sync", result: data, meta };
|
|
37
30
|
}
|
|
38
|
-
/**
|
|
39
|
-
* Espera um trabalho de busca chegar ao fim, com recuo e orçamento.
|
|
40
|
-
*
|
|
41
|
-
* O estouro do orçamento é um erro PRÓPRIO e retentável: o trabalho continua
|
|
42
|
-
* na fila do motor, e quem espera pode voltar a acompanhá-lo depois — ou
|
|
43
|
-
* receber o `SEARCH_JOB_COMPLETED` por webhook e não esperar nada.
|
|
44
|
-
*
|
|
45
|
-
* Não há o que esperar com chave de teste (`lapi_test_`): ela não enfileira
|
|
46
|
-
* trabalho, e a submissão assíncrona responde 403 `SANDBOX_UPSTREAM_DISABLED`.
|
|
47
|
-
*/
|
|
48
31
|
export async function waitForSearchJob(client, jobId, options = {}) {
|
|
49
32
|
const budgetMs = options.budgetMs ?? DEFAULT_BUDGET_MS;
|
|
50
33
|
const maxIntervalMs = options.maxPollIntervalMs ?? DEFAULT_MAX_POLL_INTERVAL_MS;
|