@ecdt/server-common 1.6.0 → 1.6.1
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 +8 -3
- package/package.json +1 -1
- package/src/index.d.ts +2 -1
- package/src/services/motorEventosService.js +23 -7
- package/test/motorEventosService.test.js +32 -1
package/README.md
CHANGED
|
@@ -176,14 +176,19 @@ publicarEvento({
|
|
|
176
176
|
|---|---|---|
|
|
177
177
|
| `tipo` | — | Nome do evento, em `snake_case` |
|
|
178
178
|
| `autorizacao` | — | Header `Authorization` da requisição que originou o evento |
|
|
179
|
+
| `idVisitante` | — | Identificador anônimo, para quando não há token |
|
|
179
180
|
| `payload` | `{}` | Campos do evento |
|
|
180
181
|
| `url` | `process.env.MOTOR_EVENTOS_URL` | URL completa do coletor; a função não monta caminho nenhum |
|
|
181
182
|
| `timeoutMs` | `2000` | Aborta a requisição |
|
|
182
183
|
| `aoFalhar` | `console.error` | Recebe a mensagem quando a publicação não acontece |
|
|
183
184
|
|
|
184
|
-
A identidade sai do token, nunca do corpo: o coletor resolve
|
|
185
|
-
repassado.
|
|
186
|
-
`
|
|
185
|
+
A identidade do usuário sai do token, nunca do corpo: o coletor a resolve a partir do `Authorization`
|
|
186
|
+
repassado. Quando não há token — rota pública, visitante anônimo — vale o `idVisitante`, que vai no
|
|
187
|
+
corpo como `id_visitante`. Ele não é identidade autenticada, é um identificador de correlação: forjá-lo
|
|
188
|
+
não atribui nada à conta de ninguém, e por isso pode vir do corpo da requisição. Basta um dos dois.
|
|
189
|
+
|
|
190
|
+
Sem `tipo`, ou sem nenhum dos dois identificadores, a função não faz nada; sem `url` ela ainda registra
|
|
191
|
+
um `console.warn`, porque url ausente é configuração faltando e não um evento que não se aplica.
|
|
187
192
|
|
|
188
193
|
**A função nunca lança e nunca devolve promise.** O evento é secundário ao fluxo que o gerou —
|
|
189
194
|
falha de publicação não pode virar erro de quem chamou, e o retorno `undefined` impede que alguém
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -138,7 +138,8 @@ export declare function renderMetrics(
|
|
|
138
138
|
|
|
139
139
|
export interface PublicarEventoOptions {
|
|
140
140
|
tipo: string;
|
|
141
|
-
autorizacao
|
|
141
|
+
autorizacao?: string;
|
|
142
|
+
idVisitante?: string;
|
|
142
143
|
payload?: Record<string, unknown>;
|
|
143
144
|
url?: string;
|
|
144
145
|
timeoutMs?: number;
|
|
@@ -11,9 +11,14 @@ function urlConfigurada(url) {
|
|
|
11
11
|
return configurada.trim();
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
function textoNaoVazio(valor) {
|
|
15
|
+
return typeof valor === "string" && valor.trim() !== "" ? valor.trim() : null;
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
function publicarEvento({
|
|
15
19
|
tipo,
|
|
16
20
|
autorizacao,
|
|
21
|
+
idVisitante,
|
|
17
22
|
payload,
|
|
18
23
|
url,
|
|
19
24
|
timeoutMs = TIMEOUT_PADRAO_MS,
|
|
@@ -21,19 +26,30 @@ function publicarEvento({
|
|
|
21
26
|
} = {}) {
|
|
22
27
|
try {
|
|
23
28
|
const destino = urlConfigurada(url);
|
|
29
|
+
const visitante = textoNaoVazio(idVisitante);
|
|
24
30
|
|
|
25
|
-
if (!destino || !tipo || !autorizacao) {
|
|
31
|
+
if (!destino || !tipo || (!autorizacao && !visitante)) {
|
|
26
32
|
return;
|
|
27
33
|
}
|
|
28
34
|
|
|
35
|
+
const cabecalhos = { "Content-Type": "application/json" };
|
|
36
|
+
if (autorizacao) {
|
|
37
|
+
cabecalhos.Authorization = autorizacao;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const corpo = {
|
|
41
|
+
tipo,
|
|
42
|
+
dt_evento: new Date().toISOString(),
|
|
43
|
+
payload: payload ?? {},
|
|
44
|
+
};
|
|
45
|
+
if (visitante) {
|
|
46
|
+
corpo.id_visitante = visitante;
|
|
47
|
+
}
|
|
48
|
+
|
|
29
49
|
fetch(destino, {
|
|
30
50
|
method: "POST",
|
|
31
|
-
headers:
|
|
32
|
-
body: JSON.stringify(
|
|
33
|
-
tipo,
|
|
34
|
-
dt_evento: new Date().toISOString(),
|
|
35
|
-
payload: payload ?? {},
|
|
36
|
-
}),
|
|
51
|
+
headers: cabecalhos,
|
|
52
|
+
body: JSON.stringify(corpo),
|
|
37
53
|
signal: AbortSignal.timeout(timeoutMs),
|
|
38
54
|
})
|
|
39
55
|
.then((resposta) => {
|
|
@@ -101,9 +101,10 @@ describe('publicarEvento', () => {
|
|
|
101
101
|
assert.equal(avisos.length, 2);
|
|
102
102
|
});
|
|
103
103
|
|
|
104
|
-
test('nao publica sem tipo
|
|
104
|
+
test('nao publica sem tipo, nem sem identidade nenhuma', async () => {
|
|
105
105
|
publicarEvento({ autorizacao: 'Bearer jwt', url: URL, aoFalhar });
|
|
106
106
|
publicarEvento({ tipo: 'meu_evento', url: URL, aoFalhar });
|
|
107
|
+
publicarEvento({ tipo: 'meu_evento', url: URL, idVisitante: ' ', aoFalhar });
|
|
107
108
|
await esperarMicrotasks();
|
|
108
109
|
|
|
109
110
|
assert.equal(chamadas.length, 0);
|
|
@@ -111,6 +112,36 @@ describe('publicarEvento', () => {
|
|
|
111
112
|
assert.deepEqual(avisos, []);
|
|
112
113
|
});
|
|
113
114
|
|
|
115
|
+
test('publica so com idVisitante, sem header de autorizacao', async () => {
|
|
116
|
+
publicarEvento({ tipo: 'meu_evento', idVisitante: 'visitante-1', url: URL, aoFalhar });
|
|
117
|
+
await esperarMicrotasks();
|
|
118
|
+
|
|
119
|
+
assert.equal(chamadas.length, 1);
|
|
120
|
+
assert.equal(chamadas[0].opcoes.headers.Authorization, undefined);
|
|
121
|
+
assert.equal(JSON.parse(chamadas[0].opcoes.body).id_visitante, 'visitante-1');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('manda os dois quando tem token e visitante', async () => {
|
|
125
|
+
publicarEvento({
|
|
126
|
+
tipo: 'meu_evento',
|
|
127
|
+
autorizacao: 'Bearer jwt',
|
|
128
|
+
idVisitante: 'visitante-1',
|
|
129
|
+
url: URL,
|
|
130
|
+
aoFalhar,
|
|
131
|
+
});
|
|
132
|
+
await esperarMicrotasks();
|
|
133
|
+
|
|
134
|
+
assert.equal(chamadas[0].opcoes.headers.Authorization, 'Bearer jwt');
|
|
135
|
+
assert.equal(JSON.parse(chamadas[0].opcoes.body).id_visitante, 'visitante-1');
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test('omite id_visitante do corpo quando nao ha visitante', async () => {
|
|
139
|
+
publicarEvento({ tipo: 'meu_evento', autorizacao: 'Bearer jwt', url: URL, aoFalhar });
|
|
140
|
+
await esperarMicrotasks();
|
|
141
|
+
|
|
142
|
+
assert.ok(!('id_visitante' in JSON.parse(chamadas[0].opcoes.body)));
|
|
143
|
+
});
|
|
144
|
+
|
|
114
145
|
test('nao quebra quando chamado sem argumento nenhum', () => {
|
|
115
146
|
delete process.env.MOTOR_EVENTOS_URL;
|
|
116
147
|
|