@neetru/sdk 3.8.0 → 3.9.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 (67) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +4 -1
  3. package/dist/ai.cjs +1 -1
  4. package/dist/ai.d.cts +1 -1
  5. package/dist/ai.d.ts +1 -1
  6. package/dist/ai.mjs +1 -1
  7. package/dist/auth.cjs +1171 -1110
  8. package/dist/auth.d.cts +1 -1
  9. package/dist/auth.d.ts +1 -1
  10. package/dist/auth.mjs +1168 -1107
  11. package/dist/catalog.cjs +1 -1
  12. package/dist/catalog.d.cts +1 -1
  13. package/dist/catalog.d.ts +1 -1
  14. package/dist/catalog.mjs +1 -1
  15. package/dist/checkout.cjs +62 -49
  16. package/dist/checkout.d.cts +1 -1
  17. package/dist/checkout.d.ts +1 -1
  18. package/dist/checkout.mjs +62 -49
  19. package/dist/db-react.d.cts +1 -1
  20. package/dist/db-react.d.ts +1 -1
  21. package/dist/db.cjs +303 -270
  22. package/dist/db.d.cts +1 -1
  23. package/dist/db.d.ts +1 -1
  24. package/dist/db.mjs +322 -289
  25. package/dist/entitlements.d.cts +1 -1
  26. package/dist/entitlements.d.ts +1 -1
  27. package/dist/firestore-compat.d.cts +1 -1
  28. package/dist/firestore-compat.d.ts +1 -1
  29. package/dist/index.cjs +1275 -1214
  30. package/dist/index.d.cts +2 -2
  31. package/dist/index.d.ts +2 -2
  32. package/dist/index.mjs +1390 -1329
  33. package/dist/mobile.cjs +328 -276
  34. package/dist/mobile.d.cts +12 -2
  35. package/dist/mobile.d.ts +12 -2
  36. package/dist/mobile.mjs +328 -276
  37. package/dist/mocks.cjs +5 -5
  38. package/dist/mocks.d.cts +2 -2
  39. package/dist/mocks.d.ts +2 -2
  40. package/dist/mocks.mjs +4 -4
  41. package/dist/notifications.cjs +1 -1
  42. package/dist/notifications.d.cts +1 -1
  43. package/dist/notifications.d.ts +1 -1
  44. package/dist/notifications.mjs +1 -1
  45. package/dist/react.cjs +119 -119
  46. package/dist/react.d.cts +8 -2
  47. package/dist/react.d.ts +8 -2
  48. package/dist/react.mjs +119 -119
  49. package/dist/support.cjs +1 -1
  50. package/dist/support.d.cts +1 -1
  51. package/dist/support.d.ts +1 -1
  52. package/dist/support.mjs +1 -1
  53. package/dist/telemetry.cjs +62 -49
  54. package/dist/telemetry.d.cts +1 -1
  55. package/dist/telemetry.d.ts +1 -1
  56. package/dist/telemetry.mjs +62 -49
  57. package/dist/{types-D-9bjlM0.d.cts → types-Bl_4HROd.d.cts} +118 -19
  58. package/dist/{types-bVztFQTI.d.ts → types-Bqnsqvow.d.ts} +118 -19
  59. package/dist/usage.cjs +1 -1
  60. package/dist/usage.d.cts +1 -1
  61. package/dist/usage.d.ts +1 -1
  62. package/dist/usage.mjs +1 -1
  63. package/dist/webhooks.cjs +1 -1
  64. package/dist/webhooks.d.cts +1 -1
  65. package/dist/webhooks.d.ts +1 -1
  66. package/dist/webhooks.mjs +1 -1
  67. package/package.json +9 -1
@@ -1412,9 +1412,42 @@ interface RealtimeClientOptions {
1412
1412
  * Alinhado com `DbSqlLease` do Core (`src/lib/db/lease/types.ts`).
1413
1413
  *
1414
1414
  * - `port` sempre 5433 — o lease aponta pro PgBouncer, nunca à porta crua.
1415
- * - `credentialVersion` — bump indica rotação; o `SqlLeaseManager` reabre
1416
- * o pool ao detectar versão diferente.
1415
+ * - `credentialVersion` — hoje é um placeholder fixo do Core (ver o campo).
1417
1416
  * - `expiresAt` — ISO string; o SDK renova aos ~80% do TTL (12 min em TTL=15 min).
1417
+ *
1418
+ * ── TLS / mTLS (estado real) ───────────────────────────────────────────────
1419
+ *
1420
+ * **O mTLS de cliente ESTÁ ativo.** O Core emite os três materiais em TODO
1421
+ * lease SQL (emissão e renovação — `buildLease`, ramo `sql`, em
1422
+ * `src/lib/db/lease/issuer-core.ts` do Core):
1423
+ * - `sslca` — a CA interna do Core (secret `coredb_ca_cert`). A MESMA CA
1424
+ * assina o cert do servidor PgBouncer (365 dias) e os certs de cliente.
1425
+ * - `clientCert` — X.509 de cliente emitido por lease: CN = `leaseId`, EKU
1426
+ * `clientAuth`, validade = TTL do lease (15 min).
1427
+ * - `clientKey` — chave EC P-256 efêmera, nova a cada emissão/renovação.
1428
+ * Não há flag que desligue isso: sem a CA no Secret Manager a emissão FALHA
1429
+ * (HTTP 500), em vez de devolver esses campos `null`.
1430
+ *
1431
+ * O SDK usa os três ao abrir o `pg.Pool` (`createPgPool` e o `createPool` de
1432
+ * `createSqlClientFromConfig`): com `sslca` presente, `ssl = { ca: sslca,
1433
+ * cert: clientCert, key: clientKey, rejectUnauthorized: true }` — verifica o
1434
+ * servidor (CA + hostname) E apresenta o cert de cliente.
1435
+ *
1436
+ * Do lado da VM, o PgBouncer roda com `client_tls_sslmode = verify-full` e
1437
+ * `client_tls_ca_file` = CA do Core (agente, `src/handlers/db-pgbouncer.ts`):
1438
+ * EXIGE cert de cliente válido. E `auth_type = scram-sha-256` — a conexão
1439
+ * precisa do cert E da senha do lease (o CN não é comparado ao usuário).
1440
+ *
1441
+ * Consequências práticas:
1442
+ * - o cert de cliente expira junto com o lease (~15 min). Pool que não troca
1443
+ * de lease passa a levar `certificate expired` (alerta TLS 45 enviado pelo
1444
+ * PgBouncer) — é o que a renovação proativa (`lease.ts`) e o re-lease
1445
+ * reativo (`resilient-pool.ts`) curam;
1446
+ * - se o install da VM não obteve a CA/assinatura, o Core configura o
1447
+ * PgBouncer SEM TLS (fail-open, com aviso no log). Como o SDK sempre liga
1448
+ * TLS quando o lease traz `sslca`, a conexão falha com "The server does
1449
+ * not support SSL connections" — o conserto é reconfigurar o PgBouncer com
1450
+ * TLS, não desligar TLS no SDK.
1418
1451
  */
1419
1452
  interface DbSqlLease {
1420
1453
  leaseId: string;
@@ -1425,31 +1458,38 @@ interface DbSqlLease {
1425
1458
  /** Plaintext — trafega só sobre HTTPS, NUNCA logado/persistido. */
1426
1459
  password: string;
1427
1460
  /**
1428
- * CA do servidor PgBouncer, para **TLS de servidor** (verify-full). Quando
1429
- * presente, o pool valida o certificado do servidor contra esta CA
1430
- * (`rejectUnauthorized: true`). `null` quando o lease não traz TLS.
1461
+ * CA interna do Core (PEM) — a mesma que assina o cert do servidor PgBouncer
1462
+ * e o `clientCert`. O pool valida o servidor contra ela
1463
+ * (`rejectUnauthorized: true`). O Core sempre manda em lease SQL; `null` só
1464
+ * se o campo vier ausente, e aí o SDK conecta SEM TLS (`ssl: false`), mesmo
1465
+ * que `clientCert` exista.
1431
1466
  */
1432
1467
  sslca: string | null;
1433
1468
  /**
1434
- * Certificado de **cliente** para mTLS (o SDK apresentar identidade ao
1435
- * servidor). **mTLS-cliente NÃO está implementado no Core (TODO P0-3):** hoje
1436
- * este campo é SEMPRE `null`, portanto **não há mTLS ativo** — a conexão usa,
1437
- * no máximo, TLS de servidor (verify-full via `sslca`). O SDK já envia este
1438
- * cert ao pool quando/se o lease passar a trazê-lo.
1469
+ * Certificado X.509 de **cliente** (PEM) para mTLS, emitido por lease
1470
+ * (CN = `leaseId`, EKU `clientAuth`, expira com o lease — 15 min). O SDK o
1471
+ * apresenta ao PgBouncer em `ssl.cert`; o PgBouncer o exige
1472
+ * (`client_tls_sslmode = verify-full`). O Core sempre manda em lease SQL —
1473
+ * o `| null` é só tolerância a resposta sem o campo (o pool fica com TLS
1474
+ * só de servidor).
1439
1475
  */
1440
1476
  clientCert: string | null;
1441
1477
  /**
1442
- * Chave privada de **cliente** para mTLS — par de `clientCert`. Mesma
1443
- * condição: `null` até o Core emitir material de cliente (mTLS-cliente
1444
- * pendente, P0-3).
1478
+ * Chave privada de **cliente** (PEM, EC P-256 efêmera, nova a cada
1479
+ * emissão/renovação) — par de `clientCert`, vai em `ssl.key`. Trafega só
1480
+ * sobre HTTPS, NUNCA logada/persistida. Mesma regra de `null` do
1481
+ * `clientCert`.
1445
1482
  */
1446
1483
  clientKey: string | null;
1447
1484
  /**
1448
- * Versão da credencial no Secret Manager. Bump = rotação de senha.
1449
- * O manager fecha o pool antigo e abre um novo quando esta versão muda.
1485
+ * Versão da credencial. HOJE o Core manda sempre o placeholder `1` (TODO de
1486
+ * versionamento no `issuer-core.ts` do Core), então ela NÃO sinaliza
1487
+ * rotação. A troca de pool numa rotação é disparada pela mudança de
1488
+ * `password` (ou de qualquer campo de conexão) — ver `hasConnectionChanged`
1489
+ * em `lease.ts`.
1450
1490
  */
1451
1491
  credentialVersion: number;
1452
- /** Expiração ISO — SDK renova ~2 min antes. */
1492
+ /** Expiração ISO — o SDK renova aos ~80% do TTL (~3 min antes, em 15 min). */
1453
1493
  expiresAt: string;
1454
1494
  }
1455
1495
  /**
@@ -2312,6 +2352,44 @@ interface SignInOptions {
2312
2352
  postLoginRedirect?: string;
2313
2353
  }
2314
2354
  type AuthStateListener = (user: NeetruUser | null) => void;
2355
+ /**
2356
+ * 3.9.0 — desfecho da revogação remota no `signOut`.
2357
+ *
2358
+ * - `accepted` — o `/api/v1/oauth/revoke` respondeu 2xx. É o melhor sinal que
2359
+ * existe, e ainda assim NÃO é prova de que o token foi destruído: a RFC 7009
2360
+ * §2.2 manda responder 200 inclusive pra token desconhecido (não vazar
2361
+ * enumeração). Significa "o servidor aceitou a revogação", não "o token
2362
+ * existia e morreu".
2363
+ * - `skipped` — não havia token revogável no storage (sessão já encerrada,
2364
+ * ou login que nunca gravou `refresh_token`). Nada a fazer.
2365
+ * - `not_configured` — o SDK não conseguiu montar o `client_id` OIDC
2366
+ * (`oidcClientId`/`apiKey` ausentes). NENHUMA requisição foi feita. É defeito
2367
+ * de configuração do produto, não falha de rede — e o efeito prático é o
2368
+ * mesmo de `failed`: a sessão do servidor segue de pé.
2369
+ * - `failed` — a requisição saiu e o servidor recusou (4xx/5xx) ou a rede
2370
+ * caiu nas duas tentativas. O `refresh_token` pode seguir válido até expirar
2371
+ * (30 dias). Em terminal compartilhado isso é falha de segurança: avise.
2372
+ */
2373
+ type RemoteRevocationStatus = 'accepted' | 'skipped' | 'not_configured' | 'failed';
2374
+ /**
2375
+ * 3.9.0 — resultado de `auth.signOut()`.
2376
+ *
2377
+ * Existe porque até a 3.8.x o `signOut` devolvia `void` e engolia a falha de
2378
+ * revogação num `console.warn`: do ponto de vista do produto, sair com o
2379
+ * servidor fora do ar era indistinguível de sair com a sessão de fato
2380
+ * encerrada. O usuário lia "você saiu" e o `refresh_token` de 30 dias seguia
2381
+ * vivo — num PDV de balcão, isso é a próxima pessoa herdando a sessão.
2382
+ */
2383
+ interface SignOutResult {
2384
+ /**
2385
+ * `true` quando todo o material de sessão foi removido do storage local.
2386
+ * Só é `false` se o próprio storage falhou ao apagar (ex.: SecureStore do RN
2387
+ * indisponível) — nesse caso ainda pode haver token NESTE aparelho.
2388
+ */
2389
+ localSessionCleared: boolean;
2390
+ /** Desfecho da revogação no servidor. Ver `RemoteRevocationStatus`. */
2391
+ remoteRevocation: RemoteRevocationStatus;
2392
+ }
2315
2393
  /**
2316
2394
  * 3.1.3 — Resultado de `auth.handleRedirectCallback()`: o material que o **backend
2317
2395
  * do produto** (confidential client) usa pra trocar o code por tokens no
@@ -2416,8 +2494,29 @@ interface AuthNamespace {
2416
2494
  * podem omitir. Usado pelo `client.support` antes de desistir num 401.
2417
2495
  */
2418
2496
  refreshTokens?(): Promise<boolean>;
2419
- /** Limpa session local + revoga refresh token no servidor. */
2420
- signOut(): Promise<void>;
2497
+ /**
2498
+ * Encerra a sessão: limpa o storage local e revoga o `refresh_token` no
2499
+ * `/api/v1/oauth/revoke` do Core.
2500
+ *
2501
+ * A limpeza local acontece SEMPRE — o usuário pediu pra sair, e deixá-lo
2502
+ * logado na tela porque a rede caiu seria o pior dos mundos. Já a revogação
2503
+ * remota pode falhar, e quando falha ela NÃO é silenciosa: o resultado traz
2504
+ * `remoteRevocation: 'failed'`. Não lança nesse caso — lançar ESCONDERIA o
2505
+ * problema, porque todo caller envolve o signOut em try/catch e redireciona
2506
+ * assim mesmo (inclusive o `<AccountBar>` deste próprio SDK).
2507
+ *
2508
+ * Produto em terminal compartilhado (PDV, balcão) DEVE checar o resultado:
2509
+ * `'failed'` significa que o `refresh_token` de 30 dias pode seguir válido
2510
+ * no servidor — a tela de "você saiu" estaria mentindo por omissão.
2511
+ *
2512
+ * ```ts
2513
+ * const r = await client.auth.signOut();
2514
+ * if (r.remoteRevocation === 'failed') {
2515
+ * toast.warn('Saímos deste aparelho, mas não deu pra encerrar a sessão no servidor.');
2516
+ * }
2517
+ * ```
2518
+ */
2519
+ signOut(): Promise<SignOutResult>;
2421
2520
  /** Retorna o user atual (do id_token cached) ou `null` se não logado. */
2422
2521
  getUser(): NeetruUser | null;
2423
2522
  /**
@@ -2768,4 +2867,4 @@ interface CatalogListOptions {
2768
2867
  includeDrafts?: boolean;
2769
2868
  }
2770
2869
 
2771
- export { type NeetruDbEngine as $, type AiChatChoice as A, type DbChangeType as B, type CatalogListOptions as C, DEFAULT_BASE_URL as D, type DbCollectionRef$1 as E, type DbDoc as F, type DbDocRef as G, type DbGetResult as H, type DbListResult as I, type DbNamespace as J, type DbQuery$1 as K, type DbSqlLease as L, type DbWhereFilter as M, type DbWhereFilter$1 as N, type EndUserTokenProvider as O, type EntitlementCheck as P, type FieldSentinel as Q, type IncrementSentinel as R, type ListNotificationsOptions as S, MockCheckout as T, MockNotifications as U, MockWebhooks as V, NEETRU_SENTINEL_KEY as W, type NeetruClient as X, type NeetruClientConfig as Y, type NeetruDb as Z, type NeetruDbDocuments as _, type AiChatMessage as a, NeetruDbError as a0, type NeetruDbErrorCode as a1, type NeetruDbOptions as a2, type NeetruDbTransport as a3, type NeetruEnv as a4, type NeetruSqlClient as a5, type NeetruUser as a6, type NotificationScopeOptions as a7, type NotificationsNamespace as a8, type Product as a9, type VerifyTokenOptions as aA, type VerifyWebhookRequestOptions as aB, type VerifyWebhookRequestResult as aC, type WebhookEndpoint as aD, type WebhookEvent as aE, type WebhookScopeOptions as aF, type WebhookTestResult as aG, type WebhooksNamespace as aH, type WithFieldSentinels as aI, __resetDbIdWarningForTests as aJ, createAiNamespace as aK, createCheckoutNamespace as aL, createNeetruDb as aM, createNotificationsNamespace as aN, createRestSyncTransport as aO, createWebhooksNamespace as aP, getWebSocketRealtimeClient as aQ, increment as aR, isFieldSentinel as aS, isIncrementSentinel as aT, isServerTimestampSentinel as aU, serverTimestamp as aV, verifyWebhookRequest as aW, verifyWebhookSignature as aX, type ProductNotification as aa, type ProductNotificationSeverity as ab, type ProductPlan as ac, type ProductStatus as ad, type RealtimeTransport as ae, type RedirectCallbackResult as af, type RegisterWebhookInput as ag, type ResolvedConfig as ah, type SendNotificationInput as ai, type ServerTimestampSentinel as aj, type SignInOptions as ak, type SqlOptions as al, type SupportNamespace as am, type SupportSeverity as an, type SupportStatus as ao, type SupportTicket as ap, type SyncErrorEvent as aq, type SyncState as ar, type TelemetryEventAck as as, type TelemetryEventInput as at, type TelemetryLogAck as au, type TelemetryLogInput as av, type Unsubscribe as aw, type UsageEventInput as ax, type UsageNamespace as ay, type UsageQuota as az, type AiChatOptions as b, type AiChatResult as c, type AiChatUsage as d, type AiContentPart as e, type AiImageUrlPart as f, type AiNamespace as g, type AiResponseFormat as h, type AiStreamHandle as i, type AiStreamMeta as j, type AiTextPart as k, type AuthNamespace as l, type AuthStateListener as m, type CatalogListResponse as n, type CheckoutAuthOpts as o, type CheckoutIntentInfo as p, type CheckoutIntentStatus as q, type CheckoutNamespace as r, type CheckoutStartInput as s, type CheckoutStartResult as t, type CheckoutTenantType as u, type CompleteSignInResult as v, type ConflictRecord as w, type CreateOfflineDocumentsOptions as x, type CreateTicketInput as y, type DbBatchOp as z };
2870
+ export { type NeetruDbEngine as $, type AiChatChoice as A, type DbChangeType as B, type CatalogListOptions as C, DEFAULT_BASE_URL as D, type DbCollectionRef$1 as E, type DbDoc as F, type DbDocRef as G, type DbGetResult as H, type DbListResult as I, type DbNamespace as J, type DbQuery$1 as K, type DbSqlLease as L, type DbWhereFilter as M, type DbWhereFilter$1 as N, type EndUserTokenProvider as O, type EntitlementCheck as P, type FieldSentinel as Q, type IncrementSentinel as R, type ListNotificationsOptions as S, MockCheckout as T, MockNotifications as U, MockWebhooks as V, NEETRU_SENTINEL_KEY as W, type NeetruClient as X, type NeetruClientConfig as Y, type NeetruDb as Z, type NeetruDbDocuments as _, type AiChatMessage as a, NeetruDbError as a0, type NeetruDbErrorCode as a1, type NeetruDbOptions as a2, type NeetruDbTransport as a3, type NeetruEnv as a4, type NeetruSqlClient as a5, type NeetruUser as a6, type NotificationScopeOptions as a7, type NotificationsNamespace as a8, type Product as a9, type UsageNamespace as aA, type UsageQuota as aB, type VerifyTokenOptions as aC, type VerifyWebhookRequestOptions as aD, type VerifyWebhookRequestResult as aE, type WebhookEndpoint as aF, type WebhookEvent as aG, type WebhookScopeOptions as aH, type WebhookTestResult as aI, type WebhooksNamespace as aJ, type WithFieldSentinels as aK, __resetDbIdWarningForTests as aL, createAiNamespace as aM, createCheckoutNamespace as aN, createNeetruDb as aO, createNotificationsNamespace as aP, createRestSyncTransport as aQ, createWebhooksNamespace as aR, getWebSocketRealtimeClient as aS, increment as aT, isFieldSentinel as aU, isIncrementSentinel as aV, isServerTimestampSentinel as aW, serverTimestamp as aX, verifyWebhookRequest as aY, verifyWebhookSignature as aZ, type ProductNotification as aa, type ProductNotificationSeverity as ab, type ProductPlan as ac, type ProductStatus as ad, type RealtimeTransport as ae, type RedirectCallbackResult as af, type RegisterWebhookInput as ag, type RemoteRevocationStatus as ah, type ResolvedConfig as ai, type SendNotificationInput as aj, type ServerTimestampSentinel as ak, type SignInOptions as al, type SignOutResult as am, type SqlOptions as an, type SupportNamespace as ao, type SupportSeverity as ap, type SupportStatus as aq, type SupportTicket as ar, type SyncErrorEvent as as, type SyncState as at, type TelemetryEventAck as au, type TelemetryEventInput as av, type TelemetryLogAck as aw, type TelemetryLogInput as ax, type Unsubscribe as ay, type UsageEventInput as az, type AiChatOptions as b, type AiChatResult as c, type AiChatUsage as d, type AiContentPart as e, type AiImageUrlPart as f, type AiNamespace as g, type AiResponseFormat as h, type AiStreamHandle as i, type AiStreamMeta as j, type AiTextPart as k, type AuthNamespace as l, type AuthStateListener as m, type CatalogListResponse as n, type CheckoutAuthOpts as o, type CheckoutIntentInfo as p, type CheckoutIntentStatus as q, type CheckoutNamespace as r, type CheckoutStartInput as s, type CheckoutStartResult as t, type CheckoutTenantType as u, type CompleteSignInResult as v, type ConflictRecord as w, type CreateOfflineDocumentsOptions as x, type CreateTicketInput as y, type DbBatchOp as z };
@@ -1412,9 +1412,42 @@ interface RealtimeClientOptions {
1412
1412
  * Alinhado com `DbSqlLease` do Core (`src/lib/db/lease/types.ts`).
1413
1413
  *
1414
1414
  * - `port` sempre 5433 — o lease aponta pro PgBouncer, nunca à porta crua.
1415
- * - `credentialVersion` — bump indica rotação; o `SqlLeaseManager` reabre
1416
- * o pool ao detectar versão diferente.
1415
+ * - `credentialVersion` — hoje é um placeholder fixo do Core (ver o campo).
1417
1416
  * - `expiresAt` — ISO string; o SDK renova aos ~80% do TTL (12 min em TTL=15 min).
1417
+ *
1418
+ * ── TLS / mTLS (estado real) ───────────────────────────────────────────────
1419
+ *
1420
+ * **O mTLS de cliente ESTÁ ativo.** O Core emite os três materiais em TODO
1421
+ * lease SQL (emissão e renovação — `buildLease`, ramo `sql`, em
1422
+ * `src/lib/db/lease/issuer-core.ts` do Core):
1423
+ * - `sslca` — a CA interna do Core (secret `coredb_ca_cert`). A MESMA CA
1424
+ * assina o cert do servidor PgBouncer (365 dias) e os certs de cliente.
1425
+ * - `clientCert` — X.509 de cliente emitido por lease: CN = `leaseId`, EKU
1426
+ * `clientAuth`, validade = TTL do lease (15 min).
1427
+ * - `clientKey` — chave EC P-256 efêmera, nova a cada emissão/renovação.
1428
+ * Não há flag que desligue isso: sem a CA no Secret Manager a emissão FALHA
1429
+ * (HTTP 500), em vez de devolver esses campos `null`.
1430
+ *
1431
+ * O SDK usa os três ao abrir o `pg.Pool` (`createPgPool` e o `createPool` de
1432
+ * `createSqlClientFromConfig`): com `sslca` presente, `ssl = { ca: sslca,
1433
+ * cert: clientCert, key: clientKey, rejectUnauthorized: true }` — verifica o
1434
+ * servidor (CA + hostname) E apresenta o cert de cliente.
1435
+ *
1436
+ * Do lado da VM, o PgBouncer roda com `client_tls_sslmode = verify-full` e
1437
+ * `client_tls_ca_file` = CA do Core (agente, `src/handlers/db-pgbouncer.ts`):
1438
+ * EXIGE cert de cliente válido. E `auth_type = scram-sha-256` — a conexão
1439
+ * precisa do cert E da senha do lease (o CN não é comparado ao usuário).
1440
+ *
1441
+ * Consequências práticas:
1442
+ * - o cert de cliente expira junto com o lease (~15 min). Pool que não troca
1443
+ * de lease passa a levar `certificate expired` (alerta TLS 45 enviado pelo
1444
+ * PgBouncer) — é o que a renovação proativa (`lease.ts`) e o re-lease
1445
+ * reativo (`resilient-pool.ts`) curam;
1446
+ * - se o install da VM não obteve a CA/assinatura, o Core configura o
1447
+ * PgBouncer SEM TLS (fail-open, com aviso no log). Como o SDK sempre liga
1448
+ * TLS quando o lease traz `sslca`, a conexão falha com "The server does
1449
+ * not support SSL connections" — o conserto é reconfigurar o PgBouncer com
1450
+ * TLS, não desligar TLS no SDK.
1418
1451
  */
1419
1452
  interface DbSqlLease {
1420
1453
  leaseId: string;
@@ -1425,31 +1458,38 @@ interface DbSqlLease {
1425
1458
  /** Plaintext — trafega só sobre HTTPS, NUNCA logado/persistido. */
1426
1459
  password: string;
1427
1460
  /**
1428
- * CA do servidor PgBouncer, para **TLS de servidor** (verify-full). Quando
1429
- * presente, o pool valida o certificado do servidor contra esta CA
1430
- * (`rejectUnauthorized: true`). `null` quando o lease não traz TLS.
1461
+ * CA interna do Core (PEM) — a mesma que assina o cert do servidor PgBouncer
1462
+ * e o `clientCert`. O pool valida o servidor contra ela
1463
+ * (`rejectUnauthorized: true`). O Core sempre manda em lease SQL; `null` só
1464
+ * se o campo vier ausente, e aí o SDK conecta SEM TLS (`ssl: false`), mesmo
1465
+ * que `clientCert` exista.
1431
1466
  */
1432
1467
  sslca: string | null;
1433
1468
  /**
1434
- * Certificado de **cliente** para mTLS (o SDK apresentar identidade ao
1435
- * servidor). **mTLS-cliente NÃO está implementado no Core (TODO P0-3):** hoje
1436
- * este campo é SEMPRE `null`, portanto **não há mTLS ativo** — a conexão usa,
1437
- * no máximo, TLS de servidor (verify-full via `sslca`). O SDK já envia este
1438
- * cert ao pool quando/se o lease passar a trazê-lo.
1469
+ * Certificado X.509 de **cliente** (PEM) para mTLS, emitido por lease
1470
+ * (CN = `leaseId`, EKU `clientAuth`, expira com o lease — 15 min). O SDK o
1471
+ * apresenta ao PgBouncer em `ssl.cert`; o PgBouncer o exige
1472
+ * (`client_tls_sslmode = verify-full`). O Core sempre manda em lease SQL —
1473
+ * o `| null` é só tolerância a resposta sem o campo (o pool fica com TLS
1474
+ * só de servidor).
1439
1475
  */
1440
1476
  clientCert: string | null;
1441
1477
  /**
1442
- * Chave privada de **cliente** para mTLS — par de `clientCert`. Mesma
1443
- * condição: `null` até o Core emitir material de cliente (mTLS-cliente
1444
- * pendente, P0-3).
1478
+ * Chave privada de **cliente** (PEM, EC P-256 efêmera, nova a cada
1479
+ * emissão/renovação) — par de `clientCert`, vai em `ssl.key`. Trafega só
1480
+ * sobre HTTPS, NUNCA logada/persistida. Mesma regra de `null` do
1481
+ * `clientCert`.
1445
1482
  */
1446
1483
  clientKey: string | null;
1447
1484
  /**
1448
- * Versão da credencial no Secret Manager. Bump = rotação de senha.
1449
- * O manager fecha o pool antigo e abre um novo quando esta versão muda.
1485
+ * Versão da credencial. HOJE o Core manda sempre o placeholder `1` (TODO de
1486
+ * versionamento no `issuer-core.ts` do Core), então ela NÃO sinaliza
1487
+ * rotação. A troca de pool numa rotação é disparada pela mudança de
1488
+ * `password` (ou de qualquer campo de conexão) — ver `hasConnectionChanged`
1489
+ * em `lease.ts`.
1450
1490
  */
1451
1491
  credentialVersion: number;
1452
- /** Expiração ISO — SDK renova ~2 min antes. */
1492
+ /** Expiração ISO — o SDK renova aos ~80% do TTL (~3 min antes, em 15 min). */
1453
1493
  expiresAt: string;
1454
1494
  }
1455
1495
  /**
@@ -2312,6 +2352,44 @@ interface SignInOptions {
2312
2352
  postLoginRedirect?: string;
2313
2353
  }
2314
2354
  type AuthStateListener = (user: NeetruUser | null) => void;
2355
+ /**
2356
+ * 3.9.0 — desfecho da revogação remota no `signOut`.
2357
+ *
2358
+ * - `accepted` — o `/api/v1/oauth/revoke` respondeu 2xx. É o melhor sinal que
2359
+ * existe, e ainda assim NÃO é prova de que o token foi destruído: a RFC 7009
2360
+ * §2.2 manda responder 200 inclusive pra token desconhecido (não vazar
2361
+ * enumeração). Significa "o servidor aceitou a revogação", não "o token
2362
+ * existia e morreu".
2363
+ * - `skipped` — não havia token revogável no storage (sessão já encerrada,
2364
+ * ou login que nunca gravou `refresh_token`). Nada a fazer.
2365
+ * - `not_configured` — o SDK não conseguiu montar o `client_id` OIDC
2366
+ * (`oidcClientId`/`apiKey` ausentes). NENHUMA requisição foi feita. É defeito
2367
+ * de configuração do produto, não falha de rede — e o efeito prático é o
2368
+ * mesmo de `failed`: a sessão do servidor segue de pé.
2369
+ * - `failed` — a requisição saiu e o servidor recusou (4xx/5xx) ou a rede
2370
+ * caiu nas duas tentativas. O `refresh_token` pode seguir válido até expirar
2371
+ * (30 dias). Em terminal compartilhado isso é falha de segurança: avise.
2372
+ */
2373
+ type RemoteRevocationStatus = 'accepted' | 'skipped' | 'not_configured' | 'failed';
2374
+ /**
2375
+ * 3.9.0 — resultado de `auth.signOut()`.
2376
+ *
2377
+ * Existe porque até a 3.8.x o `signOut` devolvia `void` e engolia a falha de
2378
+ * revogação num `console.warn`: do ponto de vista do produto, sair com o
2379
+ * servidor fora do ar era indistinguível de sair com a sessão de fato
2380
+ * encerrada. O usuário lia "você saiu" e o `refresh_token` de 30 dias seguia
2381
+ * vivo — num PDV de balcão, isso é a próxima pessoa herdando a sessão.
2382
+ */
2383
+ interface SignOutResult {
2384
+ /**
2385
+ * `true` quando todo o material de sessão foi removido do storage local.
2386
+ * Só é `false` se o próprio storage falhou ao apagar (ex.: SecureStore do RN
2387
+ * indisponível) — nesse caso ainda pode haver token NESTE aparelho.
2388
+ */
2389
+ localSessionCleared: boolean;
2390
+ /** Desfecho da revogação no servidor. Ver `RemoteRevocationStatus`. */
2391
+ remoteRevocation: RemoteRevocationStatus;
2392
+ }
2315
2393
  /**
2316
2394
  * 3.1.3 — Resultado de `auth.handleRedirectCallback()`: o material que o **backend
2317
2395
  * do produto** (confidential client) usa pra trocar o code por tokens no
@@ -2416,8 +2494,29 @@ interface AuthNamespace {
2416
2494
  * podem omitir. Usado pelo `client.support` antes de desistir num 401.
2417
2495
  */
2418
2496
  refreshTokens?(): Promise<boolean>;
2419
- /** Limpa session local + revoga refresh token no servidor. */
2420
- signOut(): Promise<void>;
2497
+ /**
2498
+ * Encerra a sessão: limpa o storage local e revoga o `refresh_token` no
2499
+ * `/api/v1/oauth/revoke` do Core.
2500
+ *
2501
+ * A limpeza local acontece SEMPRE — o usuário pediu pra sair, e deixá-lo
2502
+ * logado na tela porque a rede caiu seria o pior dos mundos. Já a revogação
2503
+ * remota pode falhar, e quando falha ela NÃO é silenciosa: o resultado traz
2504
+ * `remoteRevocation: 'failed'`. Não lança nesse caso — lançar ESCONDERIA o
2505
+ * problema, porque todo caller envolve o signOut em try/catch e redireciona
2506
+ * assim mesmo (inclusive o `<AccountBar>` deste próprio SDK).
2507
+ *
2508
+ * Produto em terminal compartilhado (PDV, balcão) DEVE checar o resultado:
2509
+ * `'failed'` significa que o `refresh_token` de 30 dias pode seguir válido
2510
+ * no servidor — a tela de "você saiu" estaria mentindo por omissão.
2511
+ *
2512
+ * ```ts
2513
+ * const r = await client.auth.signOut();
2514
+ * if (r.remoteRevocation === 'failed') {
2515
+ * toast.warn('Saímos deste aparelho, mas não deu pra encerrar a sessão no servidor.');
2516
+ * }
2517
+ * ```
2518
+ */
2519
+ signOut(): Promise<SignOutResult>;
2421
2520
  /** Retorna o user atual (do id_token cached) ou `null` se não logado. */
2422
2521
  getUser(): NeetruUser | null;
2423
2522
  /**
@@ -2768,4 +2867,4 @@ interface CatalogListOptions {
2768
2867
  includeDrafts?: boolean;
2769
2868
  }
2770
2869
 
2771
- export { type NeetruDbEngine as $, type AiChatChoice as A, type DbChangeType as B, type CatalogListOptions as C, DEFAULT_BASE_URL as D, type DbCollectionRef$1 as E, type DbDoc as F, type DbDocRef as G, type DbGetResult as H, type DbListResult as I, type DbNamespace as J, type DbQuery$1 as K, type DbSqlLease as L, type DbWhereFilter as M, type DbWhereFilter$1 as N, type EndUserTokenProvider as O, type EntitlementCheck as P, type FieldSentinel as Q, type IncrementSentinel as R, type ListNotificationsOptions as S, MockCheckout as T, MockNotifications as U, MockWebhooks as V, NEETRU_SENTINEL_KEY as W, type NeetruClient as X, type NeetruClientConfig as Y, type NeetruDb as Z, type NeetruDbDocuments as _, type AiChatMessage as a, NeetruDbError as a0, type NeetruDbErrorCode as a1, type NeetruDbOptions as a2, type NeetruDbTransport as a3, type NeetruEnv as a4, type NeetruSqlClient as a5, type NeetruUser as a6, type NotificationScopeOptions as a7, type NotificationsNamespace as a8, type Product as a9, type VerifyTokenOptions as aA, type VerifyWebhookRequestOptions as aB, type VerifyWebhookRequestResult as aC, type WebhookEndpoint as aD, type WebhookEvent as aE, type WebhookScopeOptions as aF, type WebhookTestResult as aG, type WebhooksNamespace as aH, type WithFieldSentinels as aI, __resetDbIdWarningForTests as aJ, createAiNamespace as aK, createCheckoutNamespace as aL, createNeetruDb as aM, createNotificationsNamespace as aN, createRestSyncTransport as aO, createWebhooksNamespace as aP, getWebSocketRealtimeClient as aQ, increment as aR, isFieldSentinel as aS, isIncrementSentinel as aT, isServerTimestampSentinel as aU, serverTimestamp as aV, verifyWebhookRequest as aW, verifyWebhookSignature as aX, type ProductNotification as aa, type ProductNotificationSeverity as ab, type ProductPlan as ac, type ProductStatus as ad, type RealtimeTransport as ae, type RedirectCallbackResult as af, type RegisterWebhookInput as ag, type ResolvedConfig as ah, type SendNotificationInput as ai, type ServerTimestampSentinel as aj, type SignInOptions as ak, type SqlOptions as al, type SupportNamespace as am, type SupportSeverity as an, type SupportStatus as ao, type SupportTicket as ap, type SyncErrorEvent as aq, type SyncState as ar, type TelemetryEventAck as as, type TelemetryEventInput as at, type TelemetryLogAck as au, type TelemetryLogInput as av, type Unsubscribe as aw, type UsageEventInput as ax, type UsageNamespace as ay, type UsageQuota as az, type AiChatOptions as b, type AiChatResult as c, type AiChatUsage as d, type AiContentPart as e, type AiImageUrlPart as f, type AiNamespace as g, type AiResponseFormat as h, type AiStreamHandle as i, type AiStreamMeta as j, type AiTextPart as k, type AuthNamespace as l, type AuthStateListener as m, type CatalogListResponse as n, type CheckoutAuthOpts as o, type CheckoutIntentInfo as p, type CheckoutIntentStatus as q, type CheckoutNamespace as r, type CheckoutStartInput as s, type CheckoutStartResult as t, type CheckoutTenantType as u, type CompleteSignInResult as v, type ConflictRecord as w, type CreateOfflineDocumentsOptions as x, type CreateTicketInput as y, type DbBatchOp as z };
2870
+ export { type NeetruDbEngine as $, type AiChatChoice as A, type DbChangeType as B, type CatalogListOptions as C, DEFAULT_BASE_URL as D, type DbCollectionRef$1 as E, type DbDoc as F, type DbDocRef as G, type DbGetResult as H, type DbListResult as I, type DbNamespace as J, type DbQuery$1 as K, type DbSqlLease as L, type DbWhereFilter as M, type DbWhereFilter$1 as N, type EndUserTokenProvider as O, type EntitlementCheck as P, type FieldSentinel as Q, type IncrementSentinel as R, type ListNotificationsOptions as S, MockCheckout as T, MockNotifications as U, MockWebhooks as V, NEETRU_SENTINEL_KEY as W, type NeetruClient as X, type NeetruClientConfig as Y, type NeetruDb as Z, type NeetruDbDocuments as _, type AiChatMessage as a, NeetruDbError as a0, type NeetruDbErrorCode as a1, type NeetruDbOptions as a2, type NeetruDbTransport as a3, type NeetruEnv as a4, type NeetruSqlClient as a5, type NeetruUser as a6, type NotificationScopeOptions as a7, type NotificationsNamespace as a8, type Product as a9, type UsageNamespace as aA, type UsageQuota as aB, type VerifyTokenOptions as aC, type VerifyWebhookRequestOptions as aD, type VerifyWebhookRequestResult as aE, type WebhookEndpoint as aF, type WebhookEvent as aG, type WebhookScopeOptions as aH, type WebhookTestResult as aI, type WebhooksNamespace as aJ, type WithFieldSentinels as aK, __resetDbIdWarningForTests as aL, createAiNamespace as aM, createCheckoutNamespace as aN, createNeetruDb as aO, createNotificationsNamespace as aP, createRestSyncTransport as aQ, createWebhooksNamespace as aR, getWebSocketRealtimeClient as aS, increment as aT, isFieldSentinel as aU, isIncrementSentinel as aV, isServerTimestampSentinel as aW, serverTimestamp as aX, verifyWebhookRequest as aY, verifyWebhookSignature as aZ, type ProductNotification as aa, type ProductNotificationSeverity as ab, type ProductPlan as ac, type ProductStatus as ad, type RealtimeTransport as ae, type RedirectCallbackResult as af, type RegisterWebhookInput as ag, type RemoteRevocationStatus as ah, type ResolvedConfig as ai, type SendNotificationInput as aj, type ServerTimestampSentinel as ak, type SignInOptions as al, type SignOutResult as am, type SqlOptions as an, type SupportNamespace as ao, type SupportSeverity as ap, type SupportStatus as aq, type SupportTicket as ar, type SyncErrorEvent as as, type SyncState as at, type TelemetryEventAck as au, type TelemetryEventInput as av, type TelemetryLogAck as aw, type TelemetryLogInput as ax, type Unsubscribe as ay, type UsageEventInput as az, type AiChatOptions as b, type AiChatResult as c, type AiChatUsage as d, type AiContentPart as e, type AiImageUrlPart as f, type AiNamespace as g, type AiResponseFormat as h, type AiStreamHandle as i, type AiStreamMeta as j, type AiTextPart as k, type AuthNamespace as l, type AuthStateListener as m, type CatalogListResponse as n, type CheckoutAuthOpts as o, type CheckoutIntentInfo as p, type CheckoutIntentStatus as q, type CheckoutNamespace as r, type CheckoutStartInput as s, type CheckoutStartResult as t, type CheckoutTenantType as u, type CompleteSignInResult as v, type ConflictRecord as w, type CreateOfflineDocumentsOptions as x, type CreateTicketInput as y, type DbBatchOp as z };
package/dist/usage.cjs CHANGED
@@ -108,7 +108,7 @@ function V(e, t) {
108
108
  }
109
109
  function q() {
110
110
  try {
111
- return "3.8.0";
111
+ return "3.9.0";
112
112
  } catch {
113
113
  return;
114
114
  }
package/dist/usage.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { ah as ResolvedConfig, ay as UsageNamespace } from './types-D-9bjlM0.cjs';
1
+ import { ai as ResolvedConfig, aA as UsageNamespace } from './types-Bl_4HROd.cjs';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.cjs';
4
4
 
package/dist/usage.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ah as ResolvedConfig, ay as UsageNamespace } from './types-bVztFQTI.js';
1
+ import { ai as ResolvedConfig, aA as UsageNamespace } from './types-Bqnsqvow.js';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.js';
4
4
 
package/dist/usage.mjs CHANGED
@@ -106,7 +106,7 @@ function V(e, t) {
106
106
  }
107
107
  function q() {
108
108
  try {
109
- return "3.8.0";
109
+ return "3.9.0";
110
110
  } catch {
111
111
  return;
112
112
  }
package/dist/webhooks.cjs CHANGED
@@ -108,7 +108,7 @@ function X(t, e) {
108
108
  }
109
109
  function $() {
110
110
  try {
111
- return "3.8.0";
111
+ return "3.9.0";
112
112
  } catch {
113
113
  return;
114
114
  }
@@ -1,3 +1,3 @@
1
- export { V as MockWebhooks, ag as RegisterWebhookInput, aB as VerifyWebhookRequestOptions, aC as VerifyWebhookRequestResult, aD as WebhookEndpoint, aE as WebhookEvent, aF as WebhookScopeOptions, aG as WebhookTestResult, aH as WebhooksNamespace, aP as createWebhooksNamespace, aW as verifyWebhookRequest, aX as verifyWebhookSignature } from './types-D-9bjlM0.cjs';
1
+ export { V as MockWebhooks, ag as RegisterWebhookInput, aD as VerifyWebhookRequestOptions, aE as VerifyWebhookRequestResult, aF as WebhookEndpoint, aG as WebhookEvent, aH as WebhookScopeOptions, aI as WebhookTestResult, aJ as WebhooksNamespace, aR as createWebhooksNamespace, aY as verifyWebhookRequest, aZ as verifyWebhookSignature } from './types-Bl_4HROd.cjs';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.cjs';
@@ -1,3 +1,3 @@
1
- export { V as MockWebhooks, ag as RegisterWebhookInput, aB as VerifyWebhookRequestOptions, aC as VerifyWebhookRequestResult, aD as WebhookEndpoint, aE as WebhookEvent, aF as WebhookScopeOptions, aG as WebhookTestResult, aH as WebhooksNamespace, aP as createWebhooksNamespace, aW as verifyWebhookRequest, aX as verifyWebhookSignature } from './types-bVztFQTI.js';
1
+ export { V as MockWebhooks, ag as RegisterWebhookInput, aD as VerifyWebhookRequestOptions, aE as VerifyWebhookRequestResult, aF as WebhookEndpoint, aG as WebhookEvent, aH as WebhookScopeOptions, aI as WebhookTestResult, aJ as WebhooksNamespace, aR as createWebhooksNamespace, aY as verifyWebhookRequest, aZ as verifyWebhookSignature } from './types-Bqnsqvow.js';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.js';
package/dist/webhooks.mjs CHANGED
@@ -106,7 +106,7 @@ function X(t, e) {
106
106
  }
107
107
  function $() {
108
108
  try {
109
- return "3.8.0";
109
+ return "3.9.0";
110
110
  } catch {
111
111
  return;
112
112
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neetru/sdk",
3
- "version": "3.8.0",
3
+ "version": "3.9.0",
4
4
  "description": "Neetru SDK 3.0 — biblioteca runtime universal (browser/Node/Edge) para consumir o ecossistema Neetru. Paths canonical /api/sdk/v1/*, productId obrigatório, Idempotency-Key em mutations, WebCrypto signatures, baseUrl allowlist fail-closed.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -130,6 +130,7 @@
130
130
  "sideEffects": false,
131
131
  "scripts": {
132
132
  "build": "tsup",
133
+ "postbuild": "node scripts/browser-bundle-guard.mjs",
133
134
  "dev": "NEETRU_SDK_DEV=1 tsup --watch --sourcemap",
134
135
  "test": "vitest run",
135
136
  "test:coverage": "vitest run --coverage",
@@ -138,6 +139,13 @@
138
139
  "prepare": "node -e \"try{if(require('fs').existsSync('.git'))require('child_process').execFileSync('git',['config','core.hooksPath','.githooks'],{stdio:'ignore'})}catch{}\"",
139
140
  "prepublishOnly": "npm run build"
140
141
  },
142
+ "neetru": {
143
+ "prePush": [
144
+ "lint",
145
+ "build",
146
+ "test"
147
+ ]
148
+ },
141
149
  "files": [
142
150
  "dist",
143
151
  "README.md",