@neetru/sdk 3.5.0 → 3.7.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.
Files changed (114) hide show
  1. package/CHANGELOG.md +71 -1
  2. package/dist/ai.cjs +254 -391
  3. package/dist/ai.d.cts +1 -1
  4. package/dist/ai.d.ts +1 -1
  5. package/dist/ai.mjs +254 -391
  6. package/dist/auth.cjs +3560 -4993
  7. package/dist/auth.d.cts +1 -1
  8. package/dist/auth.d.ts +1 -1
  9. package/dist/auth.mjs +3557 -4990
  10. package/dist/build-guard.cjs +101 -119
  11. package/dist/build-guard.mjs +91 -109
  12. package/dist/catalog.cjs +152 -224
  13. package/dist/catalog.d.cts +1 -1
  14. package/dist/catalog.d.ts +1 -1
  15. package/dist/catalog.mjs +152 -224
  16. package/dist/checkout.cjs +237 -320
  17. package/dist/checkout.d.cts +1 -1
  18. package/dist/checkout.d.ts +1 -1
  19. package/dist/checkout.mjs +236 -319
  20. package/dist/db-react.cjs +59 -87
  21. package/dist/db-react.d.cts +1 -1
  22. package/dist/db-react.d.ts +1 -1
  23. package/dist/db-react.mjs +56 -84
  24. package/dist/db.cjs +2055 -3013
  25. package/dist/db.d.cts +1 -1
  26. package/dist/db.d.ts +1 -1
  27. package/dist/db.mjs +2068 -3026
  28. package/dist/entitlements.cjs +12 -20
  29. package/dist/entitlements.d.cts +1 -1
  30. package/dist/entitlements.d.ts +1 -1
  31. package/dist/entitlements.mjs +12 -20
  32. package/dist/errors.cjs +9 -12
  33. package/dist/errors.d.cts +37 -2
  34. package/dist/errors.d.ts +37 -2
  35. package/dist/errors.mjs +8 -12
  36. package/dist/firestore-compat.cjs +241 -297
  37. package/dist/firestore-compat.d.cts +1 -1
  38. package/dist/firestore-compat.d.ts +1 -1
  39. package/dist/firestore-compat.mjs +215 -271
  40. package/dist/index.cjs +3627 -5135
  41. package/dist/index.d.cts +6 -4
  42. package/dist/index.d.ts +6 -4
  43. package/dist/index.mjs +3731 -5239
  44. package/dist/mobile.cjs +411 -0
  45. package/dist/mobile.d.cts +89 -0
  46. package/dist/mobile.d.ts +89 -0
  47. package/dist/mobile.mjs +409 -0
  48. package/dist/mocks.cjs +312 -447
  49. package/dist/mocks.d.cts +1 -1
  50. package/dist/mocks.d.ts +1 -1
  51. package/dist/mocks.mjs +306 -441
  52. package/dist/notifications.cjs +226 -314
  53. package/dist/notifications.d.cts +1 -1
  54. package/dist/notifications.d.ts +1 -1
  55. package/dist/notifications.mjs +225 -313
  56. package/dist/react.cjs +522 -693
  57. package/dist/react.d.cts +1 -1
  58. package/dist/react.d.ts +1 -1
  59. package/dist/react.mjs +512 -683
  60. package/dist/support.cjs +329 -325
  61. package/dist/support.d.cts +25 -3
  62. package/dist/support.d.ts +25 -3
  63. package/dist/support.mjs +328 -325
  64. package/dist/telemetry.cjs +197 -301
  65. package/dist/telemetry.d.cts +1 -1
  66. package/dist/telemetry.d.ts +1 -1
  67. package/dist/telemetry.mjs +197 -301
  68. package/dist/{types-Du_iioJ7.d.cts → types-Bx4kTLmk.d.cts} +26 -0
  69. package/dist/{types-BPATkXYu.d.ts → types-Dx0IrOSF.d.ts} +26 -0
  70. package/dist/usage.cjs +163 -227
  71. package/dist/usage.d.cts +1 -1
  72. package/dist/usage.d.ts +1 -1
  73. package/dist/usage.mjs +163 -227
  74. package/dist/webhooks.cjs +258 -359
  75. package/dist/webhooks.d.cts +1 -1
  76. package/dist/webhooks.d.ts +1 -1
  77. package/dist/webhooks.mjs +255 -356
  78. package/package.json +9 -3
  79. package/dist/ai.cjs.map +0 -1
  80. package/dist/ai.mjs.map +0 -1
  81. package/dist/auth.cjs.map +0 -1
  82. package/dist/auth.mjs.map +0 -1
  83. package/dist/build-guard.cjs.map +0 -1
  84. package/dist/build-guard.mjs.map +0 -1
  85. package/dist/catalog.cjs.map +0 -1
  86. package/dist/catalog.mjs.map +0 -1
  87. package/dist/checkout.cjs.map +0 -1
  88. package/dist/checkout.mjs.map +0 -1
  89. package/dist/db-react.cjs.map +0 -1
  90. package/dist/db-react.mjs.map +0 -1
  91. package/dist/db.cjs.map +0 -1
  92. package/dist/db.mjs.map +0 -1
  93. package/dist/entitlements.cjs.map +0 -1
  94. package/dist/entitlements.mjs.map +0 -1
  95. package/dist/errors.cjs.map +0 -1
  96. package/dist/errors.mjs.map +0 -1
  97. package/dist/firestore-compat.cjs.map +0 -1
  98. package/dist/firestore-compat.mjs.map +0 -1
  99. package/dist/index.cjs.map +0 -1
  100. package/dist/index.mjs.map +0 -1
  101. package/dist/mocks.cjs.map +0 -1
  102. package/dist/mocks.mjs.map +0 -1
  103. package/dist/notifications.cjs.map +0 -1
  104. package/dist/notifications.mjs.map +0 -1
  105. package/dist/react.cjs.map +0 -1
  106. package/dist/react.mjs.map +0 -1
  107. package/dist/support.cjs.map +0 -1
  108. package/dist/support.mjs.map +0 -1
  109. package/dist/telemetry.cjs.map +0 -1
  110. package/dist/telemetry.mjs.map +0 -1
  111. package/dist/usage.cjs.map +0 -1
  112. package/dist/usage.mjs.map +0 -1
  113. package/dist/webhooks.cjs.map +0 -1
  114. package/dist/webhooks.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,77 @@ All notable changes to `@neetru/sdk` will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.7.0] - 2026-09-29 — **feat(support): identidade do usuário final (`X-Neetru-End-User-Token`) nos tickets**
9
+
10
+ Release **minor** (capacidade nova; nenhuma API pública removida ou renomeada — ver "Mudança de comportamento" abaixo).
11
+
12
+ ### Contexto
13
+
14
+ Auditoria das APIs públicas do Core (2026-09-29, HIGH-2): a chave `nrt_` do produto identifica o **produto**, não a pessoa — e roda no browser. Os tickets de suporte eram "possuídos" pelo dono da chave, igual pra todos os usuários finais, e `GET /api/sdk/v1/support/tickets` listava os tickets de **todo mundo** do produto (screenshots, console logs, URLs). Contrato final do Core (Neetru/neetru-core#513):
15
+
16
+ - `X-Neetru-End-User-Token: <id_token>` (aceita também `Bearer <id_token>`), sempre junto do `Authorization` da chave do produto. **Só id_token**: token com `jti` (access token) → `401 invalid_end_user_token`.
17
+ - **Obrigatório** em `GET /api/sdk/v1/support/tickets` (sem header → `403 end_user_token_required`) e nas mutações `/{id}/contest|satisfaction|satisfaction-attempt|resolved-seen`.
18
+ - **Opcional** no `POST` de criação: com header o ticket fica amarrado ao `endUserId` (= `sub`); sem header nasce sem dono e **não aceita** contest/satisfaction.
19
+ - id_token de client OIDC de **outro produto** → `403 end_user_token_product_mismatch`.
20
+ - Token expirado / usuário inativo → `401 invalid_end_user_token`.
21
+ - A listagem não traz mais `attachments`/`consoleLogs`: `screenshotUrl` vem `null` na lista e `screenshotAttached` diz se há print. `limit` padrão 20, máximo 50.
22
+
23
+ **Dependência de deploy:** esta versão precisa estar publicada **junto/antes** do deploy do Core #513; senão a aba "Meus tickets" dos produtos (ex.: pdv) passa a receber 403.
24
+
25
+ ### Adicionado
26
+
27
+ - `client.support.*` envia **automaticamente** `X-Neetru-End-User-Token` com o **id_token** do usuário logado (`client.auth.getIdToken()`, lido a cada chamada — nunca o access token). Login feito depois de criar o client já vale; `getIdToken` que lança é tratado como "sem usuário".
28
+ - **Renovação automática 1x:** num `401 invalid_end_user_token`, o SDK chama `client.auth.refreshTokens()` (refresh_token rotation) UMA vez e repete a chamada com o id_token novo; se não renovar (ou falhar de novo), lança `NeetruAuthRequiredError`. Numa operação obrigatória sem id_token (expirado localmente), também tenta o refresh 1x antes de desistir.
29
+ - `AuthNamespace.refreshTokens?(): Promise<boolean>` — agora exposto pelo auth OIDC web (já existia internamente e no `@neetru/sdk/mobile`). Opcional no tipo: mocks/implementações próprias podem omitir.
30
+ - **`NeetruAuthRequiredError`** (exportado de `@neetru/sdk`, subclasse de `NeetruError`, `code: 'auth_required'`), com `reason`:
31
+ - `no_signed_in_user` — `listMyTickets`, `contestTicket`, `submitSatisfaction`, `recordSatisfactionAttempt` e `markResolvedSeen` **sem usuário logado** falham ANTES do request, com mensagem clara (em vez do 403 opaco do Core);
32
+ - `end_user_token_required` — o Core respondeu 403 exigindo a identidade;
33
+ - `invalid_end_user_token` — o Core recusou o token e o refresh não resolveu → refazer login.
34
+ - `403 end_user_token_product_mismatch` → `NeetruError` com `code: 'forbidden'` e `reason: 'end_user_token_product_mismatch'`, mensagem explicando que o login é de outro produto (config: `oidcClientId` × `apiKey`/`productId`). Não tenta refresh.
35
+ - `SupportTicket.screenshotAttached?: boolean` (da listagem do Core; fallback: há `screenshotUrl`). `listMyTickets({ limit })` — inteiro 1-50 (omitido = 20 do Core); fora disso `validation_failed` sem request.
36
+ - Novos códigos em `NeetruErrorCode`: `auth_required` e `gone`.
37
+ - **HTTP 410** (`statusToCode(410) === 'gone'`): mensagem útil ("endpoint removido do Core") + o substituto do header `X-Neetru-Replacement` — cobre o legado `/api/v1/sdk/entitlements/check`, que o Core agora responde 410. (O `client.entitlements.check()` do SDK já lançava localmente desde a 3.4.x; o 410 protege quem ainda chama a rota direto.)
38
+
39
+ ### Mudança de comportamento (ler antes de atualizar)
40
+
41
+ - **Mutações de ticket exigem usuário logado no SDK.** `contestTicket`/`submitSatisfaction`/`recordSatisfactionAttempt`/`markResolvedSeen` sem id_token lançam `NeetruAuthRequiredError` sem chamar o Core. Quem chamava isso **server-side só com a chave do produto** (sem usuário final) passa a receber o erro.
42
+ - **Tickets legados sem dono** (criados antes do corte de 2026-09-29, sem `endUserId`): o Core mantém a regra antiga pra eles (posse pela chave do produto) e ignora o header nesse caso — então **continuam mutáveis pelo SDK desde que haja QUALQUER usuário logado** no app (o id_token vai, o Core aplica a regra legada). Não há caminho no SDK pra mutá-los sem usuário logado.
43
+ - **Tickets criados a partir de 2026-09-29 sem header** (sem dono) não aceitam contest/satisfaction no Core — pra o usuário acompanhar o ticket, crie-o com o usuário logado.
44
+ - `listMyTickets()` passa a devolver `screenshotUrl: null` (a lista do Core não traz mais o anexo); use `screenshotAttached`.
45
+
46
+ ### Mantido (compatível)
47
+
48
+ - `createTicket` **sem** usuário logado continua funcionando, sem o header e sem tentar refresh (fluxo de report anônimo / server-side).
49
+ - Outros 403 (`forbidden_product`, `forbidden` de ticket de outro usuário) seguem como `NeetruError` comum.
50
+ - `MockSupport` (env `dev`) mantém o comportamento (ganha `screenshotAttached`).
51
+
52
+ ### Também entra nesta versão (mesclado no #34, ainda não publicado)
53
+
54
+ - Batch de quick-wins do Labs: bundle publicado minificado e sem sourcemap (~6x menor), `@deprecated` do namespace `entitlements` no index, e opt-in `deadlineMs` em `httpRequest` (orçamento total de tempo com retries).
55
+ - **Corrigido junto (regressão do #34, nunca publicada):** o `minify: true` apagava os magic comments `/* webpackIgnore: true */` dos `import("pg")`/`import("drizzle-orm/node-postgres")` dinâmicos → o webpack/Next do produto voltaria a tentar empacotar `pg` no bundle do browser (bug_0f836014; o teste `no-node-deps-in-browser-bundle` falhava 4/13 com `dist/` presente, inclusive na `main`). Agora minifica identificadores+sintaxe sem apagar whitespace/comentários: dist ~2,1 MB (vs 1,5 MB full; 8,5 MB antes do #34).
56
+
57
+ ## [3.6.0] - 2026-09-24 — **feat(mobile): `@neetru/sdk/mobile` — namespace de auth OIDC+PKCE para React Native/Expo**
58
+
59
+ Release **minor** (capacidade nova, aditiva — subpath novo, nenhuma API existente muda).
60
+
61
+ ### Contexto
62
+
63
+ O namespace `auth` existente (`createNeetruClient(...).auth`) é hardcoded em três APIs que não existem em React Native: `globalThis.location.assign(url)` pra iniciar o redirect do `signIn`, e `sessionStorage`/`localStorage` pra persistir a transação PKCE e os tokens. Não havia seam de injeção pra nenhum dos três, então nenhum app RN conseguia usar login Neetru via o SDK — cada squad de app mobile reimplementaria PKCE do zero (risco de bug criptográfico duplicado).
64
+
65
+ ### Adicionado (aditivo, novo subpath — não muda nada em `.`/`./auth`)
66
+
67
+ - **`@neetru/sdk/mobile`** — `createMobileAuthNamespace(config)`, com `config.storage` (`MobileAuthStorage` assíncrono — o app injeta `expo-secure-store`/Keychain/etc) e `config.openAuthUrl` (o app injeta `expo-web-browser`/`Linking.openURL` — **browser externo, nunca WebView embutida**, requisito de segurança RFC 8252 §8.12, documentado no JSDoc do módulo).
68
+ - Namespace expõe `signIn(options)`, `completeSignIn(callbackUrl)` (recebe a URL do deep link explicitamente — mobile não tem `location.href` implícito), `getIdToken()`/`getUser()` (**assíncronos** — contrato diferente do `auth` web, porque `config.storage` é sempre `Promise`), `onAuthStateChanged(listener)`, `refreshTokens()`, `signOut()`.
69
+ - **`src/auth-pkce-shared.ts`** (interno, não exportado publicamente) — a lógica criptográfica PKCE (WebCrypto, geração `state`/`nonce`/`code_verifier`/`code_challenge` S256, parsing/validação de `id_token`) foi extraída do `auth.ts` web pra ser reaproveitada 1:1 por `mobile.ts`, em vez de duplicada por copy-paste. `auth.ts` foi refatorado pra importar dali — comportamento idêntico, coberto pelos 78 testes pré-existentes de `client.auth`, que continuam verdes sem alteração.
70
+
71
+ ### Requisitos do app consumidor (documentados no JSDoc do módulo)
72
+
73
+ - Polyfill de WebCrypto (`react-native-get-random-values` + `react-native-quick-crypto` ou equivalente) — Hermes não tem `crypto.subtle` nativo. Sem o polyfill, `signIn`/`completeSignIn` lançam `NeetruError('runtime_unsupported', ...)` com mensagem clara — o SDK não tenta poliflar sozinho nem gera PKCE fraco.
74
+ - `config.openAuthUrl` deve abrir um browser externo (`ASWebAuthenticationSession`/Custom Tabs via `expo-web-browser`, ou `Linking.openURL`) — nunca uma WebView in-app.
75
+ - `client.db` (offline-first, IndexedDB) **não tem storage persistente equivalente em React Native ainda** — cai no `MemoryStore` in-memory (não sobrevive a restart do app). Limitação conhecida e aceita de v1, não resolvida por este subpath.
76
+
77
+ Nenhuma remoção de API, nenhuma mudança de wire nos namespaces existentes.
78
+
8
79
  ## [3.5.0] - 2026-09-19 — **feat(http): header `X-Neetru-Sdk-Version` em toda request**
9
80
 
10
81
  Release **minor** (capacidade nova, sem quebra de contrato existente).
@@ -28,7 +99,6 @@ Nenhuma remoção de API, nenhuma mudança de wire nos endpoints existentes —
28
99
  - **Remoção de código morto** — deletado `src/db.ts` legado (namespace v0.3.1 Sprint 8, sem nenhum import; o namespace `db` público vive em `src/db/client-db.ts`).
29
100
  - Doc: exemplo do JSDoc em `auth.ts` corrigido de `usage.track(...)` (API inexistente) para `usage.report(...)`.
30
101
  - Tooling: script `test:coverage` + devDeps `@testing-library/dom` e `@vitest/coverage-v8`.
31
-
32
102
  ## [3.4.7] - 2026-09-19 — **fix(a11y): NeetruLoginButton — foco de teclado visível (bug_62edcfb0)**
33
103
 
34
104
  Release **patch** (correção de bug de acessibilidade — publica o fix já mesclado no PR #28).