@neetru/sdk 3.6.0 → 3.8.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 (117) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +66 -1
  3. package/dist/ai.cjs +298 -391
  4. package/dist/ai.d.cts +1 -1
  5. package/dist/ai.d.ts +1 -1
  6. package/dist/ai.mjs +298 -391
  7. package/dist/auth.cjs +3717 -5005
  8. package/dist/auth.d.cts +1 -1
  9. package/dist/auth.d.ts +1 -1
  10. package/dist/auth.mjs +3714 -5002
  11. package/dist/build-guard.cjs +101 -119
  12. package/dist/build-guard.mjs +91 -109
  13. package/dist/catalog.cjs +220 -225
  14. package/dist/catalog.d.cts +1 -1
  15. package/dist/catalog.d.ts +1 -1
  16. package/dist/catalog.mjs +220 -225
  17. package/dist/checkout.cjs +307 -323
  18. package/dist/checkout.d.cts +1 -1
  19. package/dist/checkout.d.ts +1 -1
  20. package/dist/checkout.mjs +306 -322
  21. package/dist/db-react.cjs +59 -87
  22. package/dist/db-react.d.cts +1 -1
  23. package/dist/db-react.d.ts +1 -1
  24. package/dist/db-react.mjs +56 -84
  25. package/dist/db.cjs +2128 -3014
  26. package/dist/db.d.cts +1 -1
  27. package/dist/db.d.ts +1 -1
  28. package/dist/db.mjs +2141 -3027
  29. package/dist/entitlements.cjs +19 -20
  30. package/dist/entitlements.d.cts +1 -1
  31. package/dist/entitlements.d.ts +1 -1
  32. package/dist/entitlements.mjs +19 -20
  33. package/dist/errors.cjs +16 -12
  34. package/dist/errors.d.cts +59 -3
  35. package/dist/errors.d.ts +59 -3
  36. package/dist/errors.mjs +15 -12
  37. package/dist/firestore-compat.cjs +241 -297
  38. package/dist/firestore-compat.d.cts +1 -1
  39. package/dist/firestore-compat.d.ts +1 -1
  40. package/dist/firestore-compat.mjs +215 -271
  41. package/dist/index.cjs +3942 -5134
  42. package/dist/index.d.cts +181 -5
  43. package/dist/index.d.ts +181 -5
  44. package/dist/index.mjs +4040 -5239
  45. package/dist/mobile.cjs +459 -344
  46. package/dist/mobile.d.cts +59 -4
  47. package/dist/mobile.d.ts +59 -4
  48. package/dist/mobile.mjs +459 -344
  49. package/dist/mocks.cjs +319 -447
  50. package/dist/mocks.d.cts +1 -1
  51. package/dist/mocks.d.ts +1 -1
  52. package/dist/mocks.mjs +313 -441
  53. package/dist/notifications.cjs +296 -317
  54. package/dist/notifications.d.cts +1 -1
  55. package/dist/notifications.d.ts +1 -1
  56. package/dist/notifications.mjs +295 -316
  57. package/dist/react.cjs +557 -707
  58. package/dist/react.d.cts +1 -1
  59. package/dist/react.d.ts +1 -1
  60. package/dist/react.mjs +547 -697
  61. package/dist/support.cjs +402 -328
  62. package/dist/support.d.cts +29 -3
  63. package/dist/support.d.ts +29 -3
  64. package/dist/support.mjs +401 -328
  65. package/dist/telemetry.cjs +267 -304
  66. package/dist/telemetry.d.cts +1 -1
  67. package/dist/telemetry.d.ts +1 -1
  68. package/dist/telemetry.mjs +267 -304
  69. package/dist/{types-Du_iioJ7.d.cts → types-D-9bjlM0.d.cts} +74 -1
  70. package/dist/{types-BPATkXYu.d.ts → types-bVztFQTI.d.ts} +74 -1
  71. package/dist/usage.cjs +233 -230
  72. package/dist/usage.d.cts +1 -1
  73. package/dist/usage.d.ts +1 -1
  74. package/dist/usage.mjs +233 -230
  75. package/dist/webhooks.cjs +328 -362
  76. package/dist/webhooks.d.cts +1 -1
  77. package/dist/webhooks.d.ts +1 -1
  78. package/dist/webhooks.mjs +325 -359
  79. package/package.json +5 -3
  80. package/dist/ai.cjs.map +0 -1
  81. package/dist/ai.mjs.map +0 -1
  82. package/dist/auth.cjs.map +0 -1
  83. package/dist/auth.mjs.map +0 -1
  84. package/dist/build-guard.cjs.map +0 -1
  85. package/dist/build-guard.mjs.map +0 -1
  86. package/dist/catalog.cjs.map +0 -1
  87. package/dist/catalog.mjs.map +0 -1
  88. package/dist/checkout.cjs.map +0 -1
  89. package/dist/checkout.mjs.map +0 -1
  90. package/dist/db-react.cjs.map +0 -1
  91. package/dist/db-react.mjs.map +0 -1
  92. package/dist/db.cjs.map +0 -1
  93. package/dist/db.mjs.map +0 -1
  94. package/dist/entitlements.cjs.map +0 -1
  95. package/dist/entitlements.mjs.map +0 -1
  96. package/dist/errors.cjs.map +0 -1
  97. package/dist/errors.mjs.map +0 -1
  98. package/dist/firestore-compat.cjs.map +0 -1
  99. package/dist/firestore-compat.mjs.map +0 -1
  100. package/dist/index.cjs.map +0 -1
  101. package/dist/index.mjs.map +0 -1
  102. package/dist/mobile.cjs.map +0 -1
  103. package/dist/mobile.mjs.map +0 -1
  104. package/dist/mocks.cjs.map +0 -1
  105. package/dist/mocks.mjs.map +0 -1
  106. package/dist/notifications.cjs.map +0 -1
  107. package/dist/notifications.mjs.map +0 -1
  108. package/dist/react.cjs.map +0 -1
  109. package/dist/react.mjs.map +0 -1
  110. package/dist/support.cjs.map +0 -1
  111. package/dist/support.mjs.map +0 -1
  112. package/dist/telemetry.cjs.map +0 -1
  113. package/dist/telemetry.mjs.map +0 -1
  114. package/dist/usage.cjs.map +0 -1
  115. package/dist/usage.mjs.map +0 -1
  116. package/dist/webhooks.cjs.map +0 -1
  117. package/dist/webhooks.mjs.map +0 -1
package/dist/index.d.cts CHANGED
@@ -1,7 +1,8 @@
1
1
  export { createNeetruClient, getServerNeetruClient } from './auth.cjs';
2
- export { NeetruError, NeetruErrorCode } from './errors.cjs';
3
- export { A as AiChatChoice, a as AiChatMessage, b as AiChatOptions, c as AiChatResult, d as AiChatUsage, e as AiContentPart, f as AiImageUrlPart, g as AiNamespace, h as AiResponseFormat, i as AiStreamHandle, j as AiStreamMeta, k as AiTextPart, l as AuthNamespace, m as AuthStateListener, C as CatalogListOptions, n as CatalogListResponse, p as CheckoutIntentInfo, q as CheckoutIntentStatus, r as CheckoutNamespace, s as CheckoutStartInput, t as CheckoutStartResult, u as CheckoutTenantType, v as CompleteSignInResult, y as CreateTicketInput, D as DEFAULT_BASE_URL, z as DbBatchOp, B as DbChangeType, E as DbCollectionRef, F as DbDoc, G as DbDocRef, H as DbGetResult, I as DbListResult, J as DbNamespace, K as DbQuery, L as DbSqlLease, M as DbWhereFilter, O as EntitlementCheck, P as FieldSentinel, Q as IncrementSentinel, R as ListNotificationsOptions, S as MockCheckout, T as MockNotifications, U as MockWebhooks, V as NEETRU_SENTINEL_KEY, W as NeetruClient, X as NeetruClientConfig, Y as NeetruDb, _ as NeetruDbEngine, $ as NeetruDbError, a0 as NeetruDbErrorCode, a1 as NeetruDbOptions, a2 as NeetruDbTransport, a3 as NeetruEnv, a4 as NeetruSqlClient, a5 as NeetruUser, a6 as NotificationScopeOptions, a7 as NotificationsNamespace, a8 as Product, a9 as ProductNotification, aa as ProductNotificationSeverity, ab as ProductPlan, ac as ProductStatus, ae as RedirectCallbackResult, af as RegisterWebhookInput, ag as ResolvedConfig, ah as SendNotificationInput, ai as ServerTimestampSentinel, aj as SignInOptions, al as SupportNamespace, am as SupportSeverity, an as SupportStatus, ao as SupportTicket, ar as TelemetryEventAck, as as TelemetryEventInput, aw as UsageEventInput, ax as UsageNamespace, ay as UsageQuota, az as VerifyTokenOptions, aA as VerifyWebhookRequestOptions, aB as VerifyWebhookRequestResult, aC as WebhookEndpoint, aD as WebhookEvent, aE as WebhookScopeOptions, aF as WebhookTestResult, aG as WebhooksNamespace, aH as WithFieldSentinels, aJ as createAiNamespace, aK as createCheckoutNamespace, aL as createNeetruDb, aM as createNotificationsNamespace, aO as createWebhooksNamespace, aQ as increment, aR as isFieldSentinel, aS as isIncrementSentinel, aT as isServerTimestampSentinel, aU as serverTimestamp, aV as verifyWebhookRequest, aW as verifyWebhookSignature } from './types-Du_iioJ7.cjs';
2
+ export { NeetruAuthRequiredError, NeetruError, NeetruErrorCode } from './errors.cjs';
3
+ export { A as AiChatChoice, a as AiChatMessage, b as AiChatOptions, c as AiChatResult, d as AiChatUsage, e as AiContentPart, f as AiImageUrlPart, g as AiNamespace, h as AiResponseFormat, i as AiStreamHandle, j as AiStreamMeta, k as AiTextPart, l as AuthNamespace, m as AuthStateListener, C as CatalogListOptions, n as CatalogListResponse, p as CheckoutIntentInfo, q as CheckoutIntentStatus, r as CheckoutNamespace, s as CheckoutStartInput, t as CheckoutStartResult, u as CheckoutTenantType, v as CompleteSignInResult, y as CreateTicketInput, D as DEFAULT_BASE_URL, z as DbBatchOp, B as DbChangeType, E as DbCollectionRef, F as DbDoc, G as DbDocRef, H as DbGetResult, I as DbListResult, J as DbNamespace, K as DbQuery, L as DbSqlLease, M as DbWhereFilter, O as EndUserTokenProvider, P as EntitlementCheck, Q as FieldSentinel, R as IncrementSentinel, S as ListNotificationsOptions, T as MockCheckout, U as MockNotifications, V as MockWebhooks, W as NEETRU_SENTINEL_KEY, X as NeetruClient, Y as NeetruClientConfig, Z as NeetruDb, $ as NeetruDbEngine, a0 as NeetruDbError, a1 as NeetruDbErrorCode, a2 as NeetruDbOptions, a3 as NeetruDbTransport, a4 as NeetruEnv, a5 as NeetruSqlClient, a6 as NeetruUser, a7 as NotificationScopeOptions, a8 as NotificationsNamespace, a9 as Product, aa as ProductNotification, ab as ProductNotificationSeverity, ac as ProductPlan, ad as ProductStatus, af as RedirectCallbackResult, ag as RegisterWebhookInput, ah as ResolvedConfig, ai as SendNotificationInput, aj as ServerTimestampSentinel, ak as SignInOptions, am as SupportNamespace, an as SupportSeverity, ao as SupportStatus, ap as SupportTicket, as as TelemetryEventAck, at as TelemetryEventInput, ax as UsageEventInput, ay as UsageNamespace, az as UsageQuota, aA as VerifyTokenOptions, aB as VerifyWebhookRequestOptions, aC as VerifyWebhookRequestResult, aD as WebhookEndpoint, aE as WebhookEvent, aF as WebhookScopeOptions, aG as WebhookTestResult, aH as WebhooksNamespace, aI as WithFieldSentinels, aK as createAiNamespace, aL as createCheckoutNamespace, aM as createNeetruDb, aN as createNotificationsNamespace, aP as createWebhooksNamespace, aR as increment, aS as isFieldSentinel, aT as isIncrementSentinel, aU as isServerTimestampSentinel, aV as serverTimestamp, aW as verifyWebhookRequest, aX as verifyWebhookSignature } from './types-D-9bjlM0.cjs';
4
4
  export { DEV_FIXTURE_USER, MockAi, MockAuth, MockAuthOptions, MockDb, MockEntitlements, MockSupport, MockUsage } from './mocks.cjs';
5
+ import { JWTPayload } from 'jose';
5
6
  import 'drizzle-orm/node-postgres';
6
7
 
7
8
  /**
@@ -38,6 +39,179 @@ import 'drizzle-orm/node-postgres';
38
39
  */
39
40
  declare function checkCoreVersionCompat(coreVersion: string): void;
40
41
 
42
+ /**
43
+ * 3.8.0 — `verifyAccessToken`: validação SERVER-SIDE do access_token OIDC do
44
+ * usuário final, para a API do PRODUTO aceitar `Authorization: Bearer
45
+ * <access_token>` (app React Native / SPA) além do cookie de sessão.
46
+ *
47
+ * ## Fluxo canônico (decisão do dono, 2026-10-03)
48
+ *
49
+ * app/site ──Bearer access_token──▶ API do produto ──SDK + nrt_ (servidor)──▶ Core
50
+ *
51
+ * O app nunca carrega a chave `nrt_`. Ele faz login no auth.neetru.com (PKCE,
52
+ * client OIDC público do app) e manda o access_token pra API do produto, que
53
+ * valida aqui — sem ir ao Core por request.
54
+ *
55
+ * ## Formato real do token (conferido no Core, `src/lib/oidc/tokens.ts`)
56
+ *
57
+ * header: `{ alg: 'RS256', kid, typ: 'JWT' }`
58
+ * claims: `iss` = `https://auth.neetru.com` · `sub` = uid do usuário (ou
59
+ * `client:<client_id>` em client_credentials) · `aud` = `client_id`
60
+ * (string) · `client_id` · `scope` (string separada por espaço) ·
61
+ * `iat` · `exp` (15 min) · `jti`.
62
+ * JWKS: `https://auth.neetru.com/api/v1/oauth/.well-known/jwks`.
63
+ *
64
+ * O id_token usa a MESMA chave, `iss` e `aud` — o que o distingue é NÃO ter
65
+ * `jti`/`scope`/`client_id`. Por isso exigimos os três: um id_token (que vai
66
+ * para terceiros como prova de login) não serve de credencial de API.
67
+ *
68
+ * ## Revogação
69
+ *
70
+ * A validação é local (assinatura + claims), sem consulta ao Core. Um access
71
+ * token revogado continua aceito até expirar — no máximo 15 min (TTL do Core).
72
+ * Para encerrar a sessão de verdade, o app revoga o refresh_token no logout
73
+ * (o `@neetru/sdk/mobile` faz isso no `signOut`). O `/introspect` do Core é só
74
+ * para clients confidenciais do mesmo `client_id`, então não serve a uma API
75
+ * que aceita tokens de vários clients (web + iOS + Android).
76
+ */
77
+
78
+ /** Issuer canônico do Core em produção. */
79
+ declare const NEETRU_OIDC_ISSUER = "https://auth.neetru.com";
80
+ interface VerifyAccessTokenOptions {
81
+ /**
82
+ * `client_id` OIDC aceitos como `aud` — tipicamente o client web + o do app
83
+ * iOS + o do app Android DO MESMO PRODUTO. Obrigatório e não-vazio: sem isso
84
+ * um token emitido para o client de OUTRO produto passaria.
85
+ */
86
+ audience: string | readonly string[];
87
+ /** Escopos que o token TEM que ter (todos). Ex.: `['openid']`. Default: nenhum. */
88
+ requiredScopes?: readonly string[];
89
+ /** Issuer esperado. Default `https://auth.neetru.com`. Só mude para staging/emulador. */
90
+ issuer?: string;
91
+ /** URL do JWKS. Default `<issuer>/api/v1/oauth/.well-known/jwks`. */
92
+ jwksUrl?: string;
93
+ /** TTL da instância de JWKS cacheada. Default 1h. */
94
+ jwksCacheTtlMs?: number;
95
+ /** Tolerância de relógio para `exp`/`iat`/`nbf`, em segundos. Default 5, máx 60. */
96
+ clockToleranceSec?: number;
97
+ /**
98
+ * Aceitar token de máquina (`client_credentials`, `sub` = `client:<id>`).
99
+ * Default `false` — a API do produto quer um USUÁRIO.
100
+ */
101
+ allowClientCredentials?: boolean;
102
+ }
103
+ interface VerifiedAccessToken {
104
+ /** uid do usuário final (ou `client:<id>` se `allowClientCredentials`). */
105
+ sub: string;
106
+ /** `client_id` que pediu o token (web, iOS ou Android). */
107
+ clientId: string;
108
+ /** `aud` do token (= `clientId` no Core). */
109
+ audience: string;
110
+ /** Escopos concedidos. */
111
+ scopes: string[];
112
+ /** Id único do token (útil pra log/auditoria; NÃO é segredo). */
113
+ jti: string;
114
+ /** Emitido em (epoch s). */
115
+ issuedAt: number;
116
+ /** Expira em (epoch s). */
117
+ expiresAt: number;
118
+ /** `true` se é token de máquina (`client_credentials`). */
119
+ isClientCredentials: boolean;
120
+ /** Claims crus verificados. */
121
+ claims: JWTPayload;
122
+ }
123
+ /**
124
+ * Valida um access_token OIDC emitido pelo auth.neetru.com.
125
+ *
126
+ * Checa: assinatura RS256 contra o JWKS (cacheado) · `iss` · `exp` (com
127
+ * tolerância curta) · `aud ∈ audience` · formato de access token (`jti`,
128
+ * `scope`, `client_id` === `aud`) · usuário (não máquina) · `requiredScopes`.
129
+ *
130
+ * @throws {NeetruError} `invalid_config` (sem audience) · `token_expired` ·
131
+ * `token_invalid_signature` · `token_invalid_audience` · `token_invalid_issuer` ·
132
+ * `token_invalid` (não é access token / malformado / máquina) ·
133
+ * `insufficient_scope` (status 403).
134
+ */
135
+ declare function verifyAccessToken(token: string, options: VerifyAccessTokenOptions): Promise<VerifiedAccessToken>;
136
+ /** Qualquer coisa com headers: `Request` (fetch/Next), `Headers`, ou objeto Node (`req.headers`). */
137
+ type HeadersSource = Headers | {
138
+ headers: Headers | Record<string, string | string[] | undefined>;
139
+ } | Record<string, string | string[] | undefined>;
140
+ /**
141
+ * Extrai o token de `Authorization: Bearer <token>`. `null` se ausente ou se o
142
+ * esquema não for Bearer.
143
+ */
144
+ declare function readBearerToken(source: HeadersSource): string | null;
145
+ /** Lê um cookie pelo nome do header `Cookie`. */
146
+ declare function readCookie(source: HeadersSource, name: string): string | null;
147
+ interface AuthenticateProductRequestOptions<TSession> extends VerifyAccessTokenOptions {
148
+ /**
149
+ * Sessão por cookie do site (o caminho que o produto JÁ tem). Se a request
150
+ * não trouxer `Authorization: Bearer`, o helper lê o cookie `name` e chama
151
+ * `verify(valor)` — a validação do cookie continua sendo do produto.
152
+ */
153
+ cookie?: {
154
+ name: string;
155
+ verify: (value: string) => Promise<TSession | null> | TSession | null;
156
+ };
157
+ }
158
+ type ProductRequestAuth<TSession> = {
159
+ kind: 'access_token';
160
+ token: VerifiedAccessToken;
161
+ } | {
162
+ kind: 'cookie';
163
+ session: TSession;
164
+ };
165
+ /**
166
+ * Autentica uma request na API do produto aceitando `Authorization: Bearer
167
+ * <access_token>` (app/SPA) **ou** o cookie de sessão do site.
168
+ *
169
+ * - Bearer presente → valida com `verifyAccessToken`. Inválido → LANÇA (não cai
170
+ * pro cookie: credencial ruim explícita nunca é "rebaixada" em silêncio).
171
+ * - Sem Bearer e com `cookie` configurado → `cookie.verify(valor)`.
172
+ * - Nada válido → `null` (o produto responde 401).
173
+ *
174
+ * @example
175
+ * ```ts
176
+ * // app/api/v1/vendas/route.ts (Next.js, servidor)
177
+ * import { authenticateProductRequest, accessTokenErrorToHttp } from '@neetru/sdk';
178
+ * export async function GET(req: Request) {
179
+ * try {
180
+ * const auth = await authenticateProductRequest(req, {
181
+ * audience: [process.env.NEETRU_OIDC_CLIENT_ID_WEB!, process.env.NEETRU_OIDC_CLIENT_ID_IOS!,
182
+ * process.env.NEETRU_OIDC_CLIENT_ID_ANDROID!],
183
+ * requiredScopes: ['openid'],
184
+ * cookie: { name: 'session', verify: verifySessionCookie },
185
+ * });
186
+ * if (!auth) return Response.json({ error: 'unauthorized' }, { status: 401 });
187
+ * // ... usa o SDK com a chave (servidor) em nome de auth.token.sub
188
+ * } catch (err) {
189
+ * const r = accessTokenErrorToHttp(err);
190
+ * return Response.json(r.body, { status: r.status, headers: r.headers });
191
+ * }
192
+ * }
193
+ * ```
194
+ */
195
+ declare function authenticateProductRequest<TSession = unknown>(request: HeadersSource, options: AuthenticateProductRequestOptions<TSession>): Promise<ProductRequestAuth<TSession> | null>;
196
+ /**
197
+ * Converte um erro de `verifyAccessToken`/`authenticateProductRequest` na
198
+ * resposta HTTP padrão (RFC 6750 §3): 401 `invalid_token` ou 403
199
+ * `insufficient_scope`, com `WWW-Authenticate`. Erros que não são de token
200
+ * viram 500 genérico (sem vazar detalhe).
201
+ */
202
+ declare function accessTokenErrorToHttp(err: unknown): {
203
+ status: number;
204
+ headers: Record<string, string>;
205
+ body: {
206
+ error: string;
207
+ error_description: string;
208
+ };
209
+ };
210
+
211
+ type NonServerRuntime = 'browser' | 'react-native';
212
+ /** Detecta se o código está rodando fora de um servidor. `null` = servidor. */
213
+ declare function detectNonServerRuntime(): NonServerRuntime | null;
214
+
41
215
  /**
42
216
  * @neetru/sdk — biblioteca runtime para consumir o ecossistema Neetru.
43
217
  *
@@ -47,7 +221,9 @@ declare function checkCoreVersionCompat(coreVersion: string): void;
47
221
  * Namespaces estáveis (v1.0):
48
222
  * - `auth` — OIDC sign-in / sign-out + dev fixture user.
49
223
  * - `catalog` — produtos públicos (`list` / `get`).
50
- * - `entitlements` — verificação `(productSlug, feature)` → boolean / detalhado.
224
+ * - `entitlements` — **@deprecated (3.x)**: endpoint morto no Core (sempre lançava
225
+ * `not_subscribed`); `check()`/`checkDetailed()` sempre lançam. Use `usage.check`.
226
+ * O subpath `@neetru/sdk/entitlements` só será removido num major futuro.
51
227
  * - `telemetry` — `event(...)` + `log(...)` per-product (Sprint 6).
52
228
  * - `usage` — `track` / `getQuota` / `report` / `check` (Sprint 7 metering canônico).
53
229
  * - `support` — `createTicket` / `listMyTickets`.
@@ -70,6 +246,6 @@ declare function checkCoreVersionCompat(coreVersion: string): void;
70
246
  */
71
247
 
72
248
  /** Versão do SDK — exportada explicitamente pra detecção em runtime. */
73
- declare const VERSION: "3.6.0";
249
+ declare const VERSION: "3.8.0";
74
250
 
75
- export { VERSION, checkCoreVersionCompat };
251
+ export { type AuthenticateProductRequestOptions, type HeadersSource, NEETRU_OIDC_ISSUER, type NonServerRuntime, type ProductRequestAuth, VERSION, type VerifiedAccessToken, type VerifyAccessTokenOptions, accessTokenErrorToHttp, authenticateProductRequest, checkCoreVersionCompat, detectNonServerRuntime, readBearerToken, readCookie, verifyAccessToken };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  export { createNeetruClient, getServerNeetruClient } from './auth.js';
2
- export { NeetruError, NeetruErrorCode } from './errors.js';
3
- export { A as AiChatChoice, a as AiChatMessage, b as AiChatOptions, c as AiChatResult, d as AiChatUsage, e as AiContentPart, f as AiImageUrlPart, g as AiNamespace, h as AiResponseFormat, i as AiStreamHandle, j as AiStreamMeta, k as AiTextPart, l as AuthNamespace, m as AuthStateListener, C as CatalogListOptions, n as CatalogListResponse, p as CheckoutIntentInfo, q as CheckoutIntentStatus, r as CheckoutNamespace, s as CheckoutStartInput, t as CheckoutStartResult, u as CheckoutTenantType, v as CompleteSignInResult, y as CreateTicketInput, D as DEFAULT_BASE_URL, z as DbBatchOp, B as DbChangeType, E as DbCollectionRef, F as DbDoc, G as DbDocRef, H as DbGetResult, I as DbListResult, J as DbNamespace, K as DbQuery, L as DbSqlLease, M as DbWhereFilter, O as EntitlementCheck, P as FieldSentinel, Q as IncrementSentinel, R as ListNotificationsOptions, S as MockCheckout, T as MockNotifications, U as MockWebhooks, V as NEETRU_SENTINEL_KEY, W as NeetruClient, X as NeetruClientConfig, Y as NeetruDb, _ as NeetruDbEngine, $ as NeetruDbError, a0 as NeetruDbErrorCode, a1 as NeetruDbOptions, a2 as NeetruDbTransport, a3 as NeetruEnv, a4 as NeetruSqlClient, a5 as NeetruUser, a6 as NotificationScopeOptions, a7 as NotificationsNamespace, a8 as Product, a9 as ProductNotification, aa as ProductNotificationSeverity, ab as ProductPlan, ac as ProductStatus, ae as RedirectCallbackResult, af as RegisterWebhookInput, ag as ResolvedConfig, ah as SendNotificationInput, ai as ServerTimestampSentinel, aj as SignInOptions, al as SupportNamespace, am as SupportSeverity, an as SupportStatus, ao as SupportTicket, ar as TelemetryEventAck, as as TelemetryEventInput, aw as UsageEventInput, ax as UsageNamespace, ay as UsageQuota, az as VerifyTokenOptions, aA as VerifyWebhookRequestOptions, aB as VerifyWebhookRequestResult, aC as WebhookEndpoint, aD as WebhookEvent, aE as WebhookScopeOptions, aF as WebhookTestResult, aG as WebhooksNamespace, aH as WithFieldSentinels, aJ as createAiNamespace, aK as createCheckoutNamespace, aL as createNeetruDb, aM as createNotificationsNamespace, aO as createWebhooksNamespace, aQ as increment, aR as isFieldSentinel, aS as isIncrementSentinel, aT as isServerTimestampSentinel, aU as serverTimestamp, aV as verifyWebhookRequest, aW as verifyWebhookSignature } from './types-BPATkXYu.js';
2
+ export { NeetruAuthRequiredError, NeetruError, NeetruErrorCode } from './errors.js';
3
+ export { A as AiChatChoice, a as AiChatMessage, b as AiChatOptions, c as AiChatResult, d as AiChatUsage, e as AiContentPart, f as AiImageUrlPart, g as AiNamespace, h as AiResponseFormat, i as AiStreamHandle, j as AiStreamMeta, k as AiTextPart, l as AuthNamespace, m as AuthStateListener, C as CatalogListOptions, n as CatalogListResponse, p as CheckoutIntentInfo, q as CheckoutIntentStatus, r as CheckoutNamespace, s as CheckoutStartInput, t as CheckoutStartResult, u as CheckoutTenantType, v as CompleteSignInResult, y as CreateTicketInput, D as DEFAULT_BASE_URL, z as DbBatchOp, B as DbChangeType, E as DbCollectionRef, F as DbDoc, G as DbDocRef, H as DbGetResult, I as DbListResult, J as DbNamespace, K as DbQuery, L as DbSqlLease, M as DbWhereFilter, O as EndUserTokenProvider, P as EntitlementCheck, Q as FieldSentinel, R as IncrementSentinel, S as ListNotificationsOptions, T as MockCheckout, U as MockNotifications, V as MockWebhooks, W as NEETRU_SENTINEL_KEY, X as NeetruClient, Y as NeetruClientConfig, Z as NeetruDb, $ as NeetruDbEngine, a0 as NeetruDbError, a1 as NeetruDbErrorCode, a2 as NeetruDbOptions, a3 as NeetruDbTransport, a4 as NeetruEnv, a5 as NeetruSqlClient, a6 as NeetruUser, a7 as NotificationScopeOptions, a8 as NotificationsNamespace, a9 as Product, aa as ProductNotification, ab as ProductNotificationSeverity, ac as ProductPlan, ad as ProductStatus, af as RedirectCallbackResult, ag as RegisterWebhookInput, ah as ResolvedConfig, ai as SendNotificationInput, aj as ServerTimestampSentinel, ak as SignInOptions, am as SupportNamespace, an as SupportSeverity, ao as SupportStatus, ap as SupportTicket, as as TelemetryEventAck, at as TelemetryEventInput, ax as UsageEventInput, ay as UsageNamespace, az as UsageQuota, aA as VerifyTokenOptions, aB as VerifyWebhookRequestOptions, aC as VerifyWebhookRequestResult, aD as WebhookEndpoint, aE as WebhookEvent, aF as WebhookScopeOptions, aG as WebhookTestResult, aH as WebhooksNamespace, aI as WithFieldSentinels, aK as createAiNamespace, aL as createCheckoutNamespace, aM as createNeetruDb, aN as createNotificationsNamespace, aP as createWebhooksNamespace, aR as increment, aS as isFieldSentinel, aT as isIncrementSentinel, aU as isServerTimestampSentinel, aV as serverTimestamp, aW as verifyWebhookRequest, aX as verifyWebhookSignature } from './types-bVztFQTI.js';
4
4
  export { DEV_FIXTURE_USER, MockAi, MockAuth, MockAuthOptions, MockDb, MockEntitlements, MockSupport, MockUsage } from './mocks.js';
5
+ import { JWTPayload } from 'jose';
5
6
  import 'drizzle-orm/node-postgres';
6
7
 
7
8
  /**
@@ -38,6 +39,179 @@ import 'drizzle-orm/node-postgres';
38
39
  */
39
40
  declare function checkCoreVersionCompat(coreVersion: string): void;
40
41
 
42
+ /**
43
+ * 3.8.0 — `verifyAccessToken`: validação SERVER-SIDE do access_token OIDC do
44
+ * usuário final, para a API do PRODUTO aceitar `Authorization: Bearer
45
+ * <access_token>` (app React Native / SPA) além do cookie de sessão.
46
+ *
47
+ * ## Fluxo canônico (decisão do dono, 2026-10-03)
48
+ *
49
+ * app/site ──Bearer access_token──▶ API do produto ──SDK + nrt_ (servidor)──▶ Core
50
+ *
51
+ * O app nunca carrega a chave `nrt_`. Ele faz login no auth.neetru.com (PKCE,
52
+ * client OIDC público do app) e manda o access_token pra API do produto, que
53
+ * valida aqui — sem ir ao Core por request.
54
+ *
55
+ * ## Formato real do token (conferido no Core, `src/lib/oidc/tokens.ts`)
56
+ *
57
+ * header: `{ alg: 'RS256', kid, typ: 'JWT' }`
58
+ * claims: `iss` = `https://auth.neetru.com` · `sub` = uid do usuário (ou
59
+ * `client:<client_id>` em client_credentials) · `aud` = `client_id`
60
+ * (string) · `client_id` · `scope` (string separada por espaço) ·
61
+ * `iat` · `exp` (15 min) · `jti`.
62
+ * JWKS: `https://auth.neetru.com/api/v1/oauth/.well-known/jwks`.
63
+ *
64
+ * O id_token usa a MESMA chave, `iss` e `aud` — o que o distingue é NÃO ter
65
+ * `jti`/`scope`/`client_id`. Por isso exigimos os três: um id_token (que vai
66
+ * para terceiros como prova de login) não serve de credencial de API.
67
+ *
68
+ * ## Revogação
69
+ *
70
+ * A validação é local (assinatura + claims), sem consulta ao Core. Um access
71
+ * token revogado continua aceito até expirar — no máximo 15 min (TTL do Core).
72
+ * Para encerrar a sessão de verdade, o app revoga o refresh_token no logout
73
+ * (o `@neetru/sdk/mobile` faz isso no `signOut`). O `/introspect` do Core é só
74
+ * para clients confidenciais do mesmo `client_id`, então não serve a uma API
75
+ * que aceita tokens de vários clients (web + iOS + Android).
76
+ */
77
+
78
+ /** Issuer canônico do Core em produção. */
79
+ declare const NEETRU_OIDC_ISSUER = "https://auth.neetru.com";
80
+ interface VerifyAccessTokenOptions {
81
+ /**
82
+ * `client_id` OIDC aceitos como `aud` — tipicamente o client web + o do app
83
+ * iOS + o do app Android DO MESMO PRODUTO. Obrigatório e não-vazio: sem isso
84
+ * um token emitido para o client de OUTRO produto passaria.
85
+ */
86
+ audience: string | readonly string[];
87
+ /** Escopos que o token TEM que ter (todos). Ex.: `['openid']`. Default: nenhum. */
88
+ requiredScopes?: readonly string[];
89
+ /** Issuer esperado. Default `https://auth.neetru.com`. Só mude para staging/emulador. */
90
+ issuer?: string;
91
+ /** URL do JWKS. Default `<issuer>/api/v1/oauth/.well-known/jwks`. */
92
+ jwksUrl?: string;
93
+ /** TTL da instância de JWKS cacheada. Default 1h. */
94
+ jwksCacheTtlMs?: number;
95
+ /** Tolerância de relógio para `exp`/`iat`/`nbf`, em segundos. Default 5, máx 60. */
96
+ clockToleranceSec?: number;
97
+ /**
98
+ * Aceitar token de máquina (`client_credentials`, `sub` = `client:<id>`).
99
+ * Default `false` — a API do produto quer um USUÁRIO.
100
+ */
101
+ allowClientCredentials?: boolean;
102
+ }
103
+ interface VerifiedAccessToken {
104
+ /** uid do usuário final (ou `client:<id>` se `allowClientCredentials`). */
105
+ sub: string;
106
+ /** `client_id` que pediu o token (web, iOS ou Android). */
107
+ clientId: string;
108
+ /** `aud` do token (= `clientId` no Core). */
109
+ audience: string;
110
+ /** Escopos concedidos. */
111
+ scopes: string[];
112
+ /** Id único do token (útil pra log/auditoria; NÃO é segredo). */
113
+ jti: string;
114
+ /** Emitido em (epoch s). */
115
+ issuedAt: number;
116
+ /** Expira em (epoch s). */
117
+ expiresAt: number;
118
+ /** `true` se é token de máquina (`client_credentials`). */
119
+ isClientCredentials: boolean;
120
+ /** Claims crus verificados. */
121
+ claims: JWTPayload;
122
+ }
123
+ /**
124
+ * Valida um access_token OIDC emitido pelo auth.neetru.com.
125
+ *
126
+ * Checa: assinatura RS256 contra o JWKS (cacheado) · `iss` · `exp` (com
127
+ * tolerância curta) · `aud ∈ audience` · formato de access token (`jti`,
128
+ * `scope`, `client_id` === `aud`) · usuário (não máquina) · `requiredScopes`.
129
+ *
130
+ * @throws {NeetruError} `invalid_config` (sem audience) · `token_expired` ·
131
+ * `token_invalid_signature` · `token_invalid_audience` · `token_invalid_issuer` ·
132
+ * `token_invalid` (não é access token / malformado / máquina) ·
133
+ * `insufficient_scope` (status 403).
134
+ */
135
+ declare function verifyAccessToken(token: string, options: VerifyAccessTokenOptions): Promise<VerifiedAccessToken>;
136
+ /** Qualquer coisa com headers: `Request` (fetch/Next), `Headers`, ou objeto Node (`req.headers`). */
137
+ type HeadersSource = Headers | {
138
+ headers: Headers | Record<string, string | string[] | undefined>;
139
+ } | Record<string, string | string[] | undefined>;
140
+ /**
141
+ * Extrai o token de `Authorization: Bearer <token>`. `null` se ausente ou se o
142
+ * esquema não for Bearer.
143
+ */
144
+ declare function readBearerToken(source: HeadersSource): string | null;
145
+ /** Lê um cookie pelo nome do header `Cookie`. */
146
+ declare function readCookie(source: HeadersSource, name: string): string | null;
147
+ interface AuthenticateProductRequestOptions<TSession> extends VerifyAccessTokenOptions {
148
+ /**
149
+ * Sessão por cookie do site (o caminho que o produto JÁ tem). Se a request
150
+ * não trouxer `Authorization: Bearer`, o helper lê o cookie `name` e chama
151
+ * `verify(valor)` — a validação do cookie continua sendo do produto.
152
+ */
153
+ cookie?: {
154
+ name: string;
155
+ verify: (value: string) => Promise<TSession | null> | TSession | null;
156
+ };
157
+ }
158
+ type ProductRequestAuth<TSession> = {
159
+ kind: 'access_token';
160
+ token: VerifiedAccessToken;
161
+ } | {
162
+ kind: 'cookie';
163
+ session: TSession;
164
+ };
165
+ /**
166
+ * Autentica uma request na API do produto aceitando `Authorization: Bearer
167
+ * <access_token>` (app/SPA) **ou** o cookie de sessão do site.
168
+ *
169
+ * - Bearer presente → valida com `verifyAccessToken`. Inválido → LANÇA (não cai
170
+ * pro cookie: credencial ruim explícita nunca é "rebaixada" em silêncio).
171
+ * - Sem Bearer e com `cookie` configurado → `cookie.verify(valor)`.
172
+ * - Nada válido → `null` (o produto responde 401).
173
+ *
174
+ * @example
175
+ * ```ts
176
+ * // app/api/v1/vendas/route.ts (Next.js, servidor)
177
+ * import { authenticateProductRequest, accessTokenErrorToHttp } from '@neetru/sdk';
178
+ * export async function GET(req: Request) {
179
+ * try {
180
+ * const auth = await authenticateProductRequest(req, {
181
+ * audience: [process.env.NEETRU_OIDC_CLIENT_ID_WEB!, process.env.NEETRU_OIDC_CLIENT_ID_IOS!,
182
+ * process.env.NEETRU_OIDC_CLIENT_ID_ANDROID!],
183
+ * requiredScopes: ['openid'],
184
+ * cookie: { name: 'session', verify: verifySessionCookie },
185
+ * });
186
+ * if (!auth) return Response.json({ error: 'unauthorized' }, { status: 401 });
187
+ * // ... usa o SDK com a chave (servidor) em nome de auth.token.sub
188
+ * } catch (err) {
189
+ * const r = accessTokenErrorToHttp(err);
190
+ * return Response.json(r.body, { status: r.status, headers: r.headers });
191
+ * }
192
+ * }
193
+ * ```
194
+ */
195
+ declare function authenticateProductRequest<TSession = unknown>(request: HeadersSource, options: AuthenticateProductRequestOptions<TSession>): Promise<ProductRequestAuth<TSession> | null>;
196
+ /**
197
+ * Converte um erro de `verifyAccessToken`/`authenticateProductRequest` na
198
+ * resposta HTTP padrão (RFC 6750 §3): 401 `invalid_token` ou 403
199
+ * `insufficient_scope`, com `WWW-Authenticate`. Erros que não são de token
200
+ * viram 500 genérico (sem vazar detalhe).
201
+ */
202
+ declare function accessTokenErrorToHttp(err: unknown): {
203
+ status: number;
204
+ headers: Record<string, string>;
205
+ body: {
206
+ error: string;
207
+ error_description: string;
208
+ };
209
+ };
210
+
211
+ type NonServerRuntime = 'browser' | 'react-native';
212
+ /** Detecta se o código está rodando fora de um servidor. `null` = servidor. */
213
+ declare function detectNonServerRuntime(): NonServerRuntime | null;
214
+
41
215
  /**
42
216
  * @neetru/sdk — biblioteca runtime para consumir o ecossistema Neetru.
43
217
  *
@@ -47,7 +221,9 @@ declare function checkCoreVersionCompat(coreVersion: string): void;
47
221
  * Namespaces estáveis (v1.0):
48
222
  * - `auth` — OIDC sign-in / sign-out + dev fixture user.
49
223
  * - `catalog` — produtos públicos (`list` / `get`).
50
- * - `entitlements` — verificação `(productSlug, feature)` → boolean / detalhado.
224
+ * - `entitlements` — **@deprecated (3.x)**: endpoint morto no Core (sempre lançava
225
+ * `not_subscribed`); `check()`/`checkDetailed()` sempre lançam. Use `usage.check`.
226
+ * O subpath `@neetru/sdk/entitlements` só será removido num major futuro.
51
227
  * - `telemetry` — `event(...)` + `log(...)` per-product (Sprint 6).
52
228
  * - `usage` — `track` / `getQuota` / `report` / `check` (Sprint 7 metering canônico).
53
229
  * - `support` — `createTicket` / `listMyTickets`.
@@ -70,6 +246,6 @@ declare function checkCoreVersionCompat(coreVersion: string): void;
70
246
  */
71
247
 
72
248
  /** Versão do SDK — exportada explicitamente pra detecção em runtime. */
73
- declare const VERSION: "3.6.0";
249
+ declare const VERSION: "3.8.0";
74
250
 
75
- export { VERSION, checkCoreVersionCompat };
251
+ export { type AuthenticateProductRequestOptions, type HeadersSource, NEETRU_OIDC_ISSUER, type NonServerRuntime, type ProductRequestAuth, VERSION, type VerifiedAccessToken, type VerifyAccessTokenOptions, accessTokenErrorToHttp, authenticateProductRequest, checkCoreVersionCompat, detectNonServerRuntime, readBearerToken, readCookie, verifyAccessToken };