@neetru/sdk 2.3.5 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +184 -0
- package/README.md +59 -22
- package/dist/auth.cjs +368 -142
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.mjs +368 -142
- package/dist/auth.mjs.map +1 -1
- package/dist/catalog.cjs +21 -2
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.mjs +21 -2
- package/dist/catalog.mjs.map +1 -1
- package/dist/checkout.cjs +21 -2
- package/dist/checkout.cjs.map +1 -1
- package/dist/checkout.d.cts +1 -1
- package/dist/checkout.d.ts +1 -1
- package/dist/checkout.mjs +21 -2
- package/dist/checkout.mjs.map +1 -1
- package/dist/db.cjs +36 -5
- package/dist/db.cjs.map +1 -1
- package/dist/db.d.cts +1 -1
- package/dist/db.d.ts +1 -1
- package/dist/db.mjs +36 -5
- package/dist/db.mjs.map +1 -1
- package/dist/entitlements.cjs +21 -2
- package/dist/entitlements.cjs.map +1 -1
- package/dist/entitlements.d.cts +1 -1
- package/dist/entitlements.d.ts +1 -1
- package/dist/entitlements.mjs +21 -2
- package/dist/entitlements.mjs.map +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +3 -1
- package/dist/errors.d.ts +3 -1
- package/dist/errors.mjs.map +1 -1
- package/dist/index.cjs +432 -152
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -19
- package/dist/index.d.ts +31 -19
- package/dist/index.mjs +432 -152
- package/dist/index.mjs.map +1 -1
- package/dist/mocks.cjs +49 -37
- package/dist/mocks.cjs.map +1 -1
- package/dist/mocks.d.cts +23 -19
- package/dist/mocks.d.ts +23 -19
- package/dist/mocks.mjs +49 -37
- package/dist/mocks.mjs.map +1 -1
- package/dist/notifications.cjs +80 -14
- package/dist/notifications.cjs.map +1 -1
- package/dist/notifications.d.cts +1 -1
- package/dist/notifications.d.ts +1 -1
- package/dist/notifications.mjs +80 -14
- package/dist/notifications.mjs.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/support.cjs +72 -12
- package/dist/support.cjs.map +1 -1
- package/dist/support.d.cts +1 -1
- package/dist/support.d.ts +1 -1
- package/dist/support.mjs +72 -12
- package/dist/support.mjs.map +1 -1
- package/dist/telemetry.cjs +23 -4
- package/dist/telemetry.cjs.map +1 -1
- package/dist/telemetry.d.cts +1 -1
- package/dist/telemetry.d.ts +1 -1
- package/dist/telemetry.mjs +23 -4
- package/dist/telemetry.mjs.map +1 -1
- package/dist/{types-sGGN1vkg.d.cts → types-DLOvkeAP.d.cts} +110 -49
- package/dist/{types-CSC-RIdS.d.ts → types-dw19bdID.d.ts} +110 -49
- package/dist/usage.cjs +57 -63
- package/dist/usage.cjs.map +1 -1
- package/dist/usage.d.cts +1 -1
- package/dist/usage.d.ts +1 -1
- package/dist/usage.mjs +57 -63
- package/dist/usage.mjs.map +1 -1
- package/dist/webhooks.cjs +110 -33
- package/dist/webhooks.cjs.map +1 -1
- package/dist/webhooks.d.cts +1 -1
- package/dist/webhooks.d.ts +1 -1
- package/dist/webhooks.mjs +110 -33
- package/dist/webhooks.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -104,6 +104,11 @@ interface ProductNotification {
|
|
|
104
104
|
dismissedAt?: string;
|
|
105
105
|
}
|
|
106
106
|
interface SendNotificationInput {
|
|
107
|
+
/**
|
|
108
|
+
* **3.0 (breaking):** productId é obrigatório (Core valida via Zod). Default
|
|
109
|
+
* resolve do `config.productId`; lança `validation_failed` se ausente.
|
|
110
|
+
*/
|
|
111
|
+
productId?: string;
|
|
107
112
|
userId: string;
|
|
108
113
|
kind: string;
|
|
109
114
|
title: string;
|
|
@@ -118,6 +123,11 @@ interface SendNotificationInput {
|
|
|
118
123
|
fingerprint?: string;
|
|
119
124
|
}
|
|
120
125
|
interface ListNotificationsOptions {
|
|
126
|
+
/**
|
|
127
|
+
* **3.0 (breaking):** productId é obrigatório no Core. Default resolve do
|
|
128
|
+
* `config.productId`.
|
|
129
|
+
*/
|
|
130
|
+
productId?: string;
|
|
121
131
|
/** Inclui notificações dismissed (default false). */
|
|
122
132
|
includeDismissed?: boolean;
|
|
123
133
|
/** Filtro por unread. */
|
|
@@ -125,17 +135,21 @@ interface ListNotificationsOptions {
|
|
|
125
135
|
/** Máx itens (default 50, máx 200). */
|
|
126
136
|
limit?: number;
|
|
127
137
|
}
|
|
138
|
+
/** 3.0: scope option pra markRead/dismiss (productId obrigatório no Core). */
|
|
139
|
+
interface NotificationScopeOptions {
|
|
140
|
+
productId?: string;
|
|
141
|
+
}
|
|
128
142
|
interface NotificationsNamespace {
|
|
129
143
|
/** Produto envia uma notificação pra um usuário do produto. */
|
|
130
144
|
send(input: SendNotificationInput): Promise<ProductNotification>;
|
|
131
145
|
/** Lista notificações de um usuário. */
|
|
132
146
|
list(userId: string, options?: ListNotificationsOptions): Promise<ProductNotification[]>;
|
|
133
147
|
/** Marca como lida. */
|
|
134
|
-
markRead(id: string): Promise<{
|
|
148
|
+
markRead(id: string, options?: NotificationScopeOptions): Promise<{
|
|
135
149
|
ok: true;
|
|
136
150
|
}>;
|
|
137
151
|
/** Descarta. */
|
|
138
|
-
dismiss(id: string): Promise<{
|
|
152
|
+
dismiss(id: string, options?: NotificationScopeOptions): Promise<{
|
|
139
153
|
ok: true;
|
|
140
154
|
}>;
|
|
141
155
|
}
|
|
@@ -145,10 +159,10 @@ declare class MockNotifications implements NotificationsNamespace {
|
|
|
145
159
|
private nextId;
|
|
146
160
|
send(input: SendNotificationInput): Promise<ProductNotification>;
|
|
147
161
|
list(userId: string, options?: ListNotificationsOptions): Promise<ProductNotification[]>;
|
|
148
|
-
markRead(id: string): Promise<{
|
|
162
|
+
markRead(id: string, _options?: NotificationScopeOptions): Promise<{
|
|
149
163
|
ok: true;
|
|
150
164
|
}>;
|
|
151
|
-
dismiss(id: string): Promise<{
|
|
165
|
+
dismiss(id: string, _options?: NotificationScopeOptions): Promise<{
|
|
152
166
|
ok: true;
|
|
153
167
|
}>;
|
|
154
168
|
}
|
|
@@ -169,6 +183,12 @@ interface WebhookEndpoint {
|
|
|
169
183
|
createdAt: string;
|
|
170
184
|
}
|
|
171
185
|
interface RegisterWebhookInput {
|
|
186
|
+
/**
|
|
187
|
+
* **3.0 (breaking):** `productId` é obrigatório no body. Se ausente,
|
|
188
|
+
* SDK tenta resolver do `config.productId` (default no `createNeetruClient`);
|
|
189
|
+
* lança `validation_failed` se ambos faltarem.
|
|
190
|
+
*/
|
|
191
|
+
productId?: string;
|
|
172
192
|
url: string;
|
|
173
193
|
events: WebhookEvent[];
|
|
174
194
|
/**
|
|
@@ -184,53 +204,67 @@ interface WebhookTestResult {
|
|
|
184
204
|
durationMs?: number;
|
|
185
205
|
error?: string;
|
|
186
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* 3.0: opções de scoping — todos os verbos exigem `productId` (default do
|
|
209
|
+
* `config.productId` se ausente).
|
|
210
|
+
*/
|
|
211
|
+
interface WebhookScopeOptions {
|
|
212
|
+
productId?: string;
|
|
213
|
+
}
|
|
187
214
|
interface WebhooksNamespace {
|
|
188
215
|
/** Registra um novo endpoint. */
|
|
189
216
|
register(input: RegisterWebhookInput): Promise<WebhookEndpoint>;
|
|
190
217
|
/** Lista endpoints registrados pelo produto. */
|
|
191
|
-
list(): Promise<WebhookEndpoint[]>;
|
|
218
|
+
list(options?: WebhookScopeOptions): Promise<WebhookEndpoint[]>;
|
|
192
219
|
/** Remove um endpoint. */
|
|
193
|
-
unregister(id: string): Promise<{
|
|
220
|
+
unregister(id: string, options?: WebhookScopeOptions): Promise<{
|
|
194
221
|
ok: true;
|
|
195
222
|
}>;
|
|
196
223
|
/** Dispara evento de teste pra validar conectividade. */
|
|
197
|
-
test(id: string): Promise<WebhookTestResult>;
|
|
224
|
+
test(id: string, options?: WebhookScopeOptions): Promise<WebhookTestResult>;
|
|
198
225
|
}
|
|
199
226
|
/**
|
|
200
227
|
* Verifica assinatura HMAC SHA-256 de payload de webhook recebido pelo
|
|
201
|
-
* produto consumer.
|
|
228
|
+
* produto consumer. **3.0**: Universal (browser/Node/Edge) via WebCrypto.subtle.
|
|
229
|
+
*
|
|
230
|
+
* Constant-time compare via byte-level XOR accumulator (não usa
|
|
231
|
+
* `timingSafeEqual` do Node porque WebCrypto não tem equivalente direto).
|
|
202
232
|
*
|
|
203
|
-
* @param payload Corpo cru da request (string ou
|
|
233
|
+
* @param payload Corpo cru da request (string ou Uint8Array). NÃO use o objeto
|
|
204
234
|
* parseado — JSON.stringify pode diferir do que foi assinado.
|
|
205
235
|
* @param signature Header `X-Neetru-Signature` recebido (formato `sha256=<hex>`).
|
|
206
236
|
* @param secret Secret registrado em `webhooks.register({ secret })`.
|
|
207
|
-
* @returns true se assinatura confere, false caso contrário.
|
|
237
|
+
* @returns Promise<boolean> — true se assinatura confere, false caso contrário.
|
|
208
238
|
*
|
|
209
239
|
* @example
|
|
210
240
|
* ```ts
|
|
211
|
-
* //
|
|
212
|
-
*
|
|
213
|
-
* const
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
* }
|
|
217
|
-
* const event = JSON.parse(
|
|
241
|
+
* // Next.js Route Handler (Edge ou Node runtime — funciona em ambos)
|
|
242
|
+
* export async function POST(req: Request) {
|
|
243
|
+
* const raw = await req.text();
|
|
244
|
+
* const sig = req.headers.get('X-Neetru-Signature');
|
|
245
|
+
* const ok = await verifyWebhookSignature(raw, sig, process.env.NEETRU_WEBHOOK_SECRET!);
|
|
246
|
+
* if (!ok) return new Response('unauthorized', { status: 401 });
|
|
247
|
+
* const event = JSON.parse(raw);
|
|
218
248
|
* // ... handle event
|
|
219
|
-
*
|
|
220
|
-
* }
|
|
249
|
+
* return Response.json({ ok: true });
|
|
250
|
+
* }
|
|
221
251
|
* ```
|
|
252
|
+
*
|
|
253
|
+
* @throws NeetruError('runtime_unsupported') se runtime não expõe WebCrypto.
|
|
254
|
+
* Não retorna `false` silencioso — caller precisa distinguir "assinatura
|
|
255
|
+
* inválida" (return false) de "ambiente não suporta" (throw).
|
|
222
256
|
*/
|
|
223
|
-
declare function verifyWebhookSignature(payload: string | Uint8Array, signature: string | null | undefined, secret: string): boolean
|
|
257
|
+
declare function verifyWebhookSignature(payload: string | Uint8Array, signature: string | null | undefined, secret: string): Promise<boolean>;
|
|
224
258
|
declare function createWebhooksNamespace(config: ResolvedConfig): WebhooksNamespace;
|
|
225
259
|
declare class MockWebhooks implements WebhooksNamespace {
|
|
226
260
|
private endpoints;
|
|
227
261
|
private nextId;
|
|
228
262
|
register(input: RegisterWebhookInput): Promise<WebhookEndpoint>;
|
|
229
|
-
list(): Promise<WebhookEndpoint[]>;
|
|
230
|
-
unregister(id: string): Promise<{
|
|
263
|
+
list(_options?: WebhookScopeOptions): Promise<WebhookEndpoint[]>;
|
|
264
|
+
unregister(id: string, _options?: WebhookScopeOptions): Promise<{
|
|
231
265
|
ok: true;
|
|
232
266
|
}>;
|
|
233
|
-
test(id: string): Promise<WebhookTestResult>;
|
|
267
|
+
test(id: string, _options?: WebhookScopeOptions): Promise<WebhookTestResult>;
|
|
234
268
|
}
|
|
235
269
|
|
|
236
270
|
/**
|
|
@@ -1043,6 +1077,14 @@ interface NeetruClientConfig {
|
|
|
1043
1077
|
* Valores: `'rest'` | `'firestore'` | `'nosql-vm'`.
|
|
1044
1078
|
*/
|
|
1045
1079
|
db?: NeetruDbOptions;
|
|
1080
|
+
/**
|
|
1081
|
+
* 3.0 — hosts adicionais permitidos para `baseUrl`. Por default, SDK aceita
|
|
1082
|
+
* `*.neetru.com` HTTPS + localhost. Para apontar pra staging/proxy custom em
|
|
1083
|
+
* `https://meu-proxy.empresa.com`, adicione `['empresa.com']`.
|
|
1084
|
+
*
|
|
1085
|
+
* Bypass total: `NEETRU_ALLOW_INSECURE_BASEURL=1` no env.
|
|
1086
|
+
*/
|
|
1087
|
+
allowedHosts?: string[];
|
|
1046
1088
|
}
|
|
1047
1089
|
/**
|
|
1048
1090
|
* Status do produto no catálogo público.
|
|
@@ -1299,41 +1341,41 @@ interface VerifyTokenOptions {
|
|
|
1299
1341
|
*/
|
|
1300
1342
|
jwksCacheTtlMs?: number;
|
|
1301
1343
|
}
|
|
1344
|
+
/**
|
|
1345
|
+
* 3.0 BREAKING: `UsageEventInput` mantido só como tipo para tests/legacy
|
|
1346
|
+
* imports — não é mais retorno de método. `usage.track`/`usage.getQuota`
|
|
1347
|
+
* **REMOVIDOS** em 3.0. Use `usage.report(resource, qty, options)`.
|
|
1348
|
+
*/
|
|
1302
1349
|
interface UsageEventInput {
|
|
1303
|
-
/** Nome do evento, ex: `report_generated`, `api_call`. */
|
|
1304
1350
|
event: string;
|
|
1305
|
-
/** Atributos do evento. Valores primitivos serializáveis. */
|
|
1306
1351
|
properties?: Record<string, string | number | boolean | null>;
|
|
1307
|
-
/** Quantidade — default 1 (1 evento). Útil pra batch. */
|
|
1308
1352
|
quantity?: number;
|
|
1309
1353
|
}
|
|
1354
|
+
/**
|
|
1355
|
+
* 3.0 BREAKING: `UsageQuota` mantido só para compat de imports. Não é mais
|
|
1356
|
+
* retorno de método ativo. `usage.report()` devolve `{value, limit, remaining}`
|
|
1357
|
+
* inline; `usage.check()` devolve detalhes do entitlement.
|
|
1358
|
+
*/
|
|
1310
1359
|
interface UsageQuota {
|
|
1311
1360
|
metric: string;
|
|
1312
|
-
/** Quantidade já consumida no período. */
|
|
1313
1361
|
used: number;
|
|
1314
|
-
/** Limite total. -1 = unlimited. */
|
|
1315
1362
|
limit: number;
|
|
1316
|
-
/** ISO timestamp do reset (próximo período). */
|
|
1317
1363
|
resetsAt?: string;
|
|
1318
|
-
/** Plano que define o limite. */
|
|
1319
1364
|
plan?: string;
|
|
1320
1365
|
}
|
|
1366
|
+
/**
|
|
1367
|
+
* 3.0 — superfície limpa: `report` (POST metered) + `check` (GET entitlement).
|
|
1368
|
+
*
|
|
1369
|
+
* Métodos removidos vs 2.x:
|
|
1370
|
+
* - `track(event, props)` — vaporware contra Core. Use `report()`.
|
|
1371
|
+
* - `getQuota(metric)` — endpoint nunca existiu. `report()` devolve quota.
|
|
1372
|
+
*/
|
|
1321
1373
|
interface UsageNamespace {
|
|
1322
|
-
/** Persiste um evento de uso. Mock em dev, POST `/sdk/v1/usage/record` em prod. */
|
|
1323
|
-
track(event: string, props?: UsageEventInput['properties']): Promise<{
|
|
1324
|
-
ok: true;
|
|
1325
|
-
}>;
|
|
1326
|
-
/** Lê quota atual de uma métrica. Mock em dev, GET `/sdk/v1/usage/quota` em prod. */
|
|
1327
|
-
getQuota(metric: string): Promise<UsageQuota>;
|
|
1328
1374
|
/**
|
|
1329
|
-
*
|
|
1330
|
-
*
|
|
1331
|
-
*
|
|
1332
|
-
* Diferente de `track()`: usa o endpoint canônico Sprint 7 que incrementa
|
|
1333
|
-
* `usage_counters/{tenantId}_{productId}_{resource}_{yyyymm}` atomicamente.
|
|
1375
|
+
* Reporta consumo metered. Incrementa `usage_counters` no Core atomicamente.
|
|
1376
|
+
* Idempotency-Key gerado por chamada (defesa anti-dup em retry transient).
|
|
1334
1377
|
*
|
|
1335
|
-
* `productId`/`tenantId`
|
|
1336
|
-
* ausentes nas options.
|
|
1378
|
+
* `productId`/`tenantId` lidos do contexto do client se ausentes nas options.
|
|
1337
1379
|
*/
|
|
1338
1380
|
report(resource: string, qty?: number, options?: {
|
|
1339
1381
|
productId?: string;
|
|
@@ -1347,8 +1389,9 @@ interface UsageNamespace {
|
|
|
1347
1389
|
status?: string;
|
|
1348
1390
|
}>;
|
|
1349
1391
|
/**
|
|
1350
|
-
*
|
|
1351
|
-
*
|
|
1392
|
+
* Verifica entitlement de um resource/feature. GET cacheável (HTTP 60s).
|
|
1393
|
+
* Resposta inclui `allowed`, `reason`, `remaining`, `limit`, `planId`,
|
|
1394
|
+
* `planFeatures` e `behavior` ('readonly' quando limit_exceeded).
|
|
1352
1395
|
*/
|
|
1353
1396
|
check(resource: string, options?: {
|
|
1354
1397
|
productId?: string;
|
|
@@ -1360,6 +1403,7 @@ interface UsageNamespace {
|
|
|
1360
1403
|
limit?: number;
|
|
1361
1404
|
planId?: string | null;
|
|
1362
1405
|
planFeatures?: string[];
|
|
1406
|
+
behavior?: 'readonly' | null;
|
|
1363
1407
|
}>;
|
|
1364
1408
|
}
|
|
1365
1409
|
/**
|
|
@@ -1427,12 +1471,29 @@ interface CreateTicketInput {
|
|
|
1427
1471
|
message: string;
|
|
1428
1472
|
severity?: SupportSeverity;
|
|
1429
1473
|
productSlug?: string;
|
|
1474
|
+
/**
|
|
1475
|
+
* **L-05 fix (Opus review 2026-05-27):** metadata opcional (Core já aceita
|
|
1476
|
+
* via `metadata: z.record(...)` no Zod). Útil pra anexar contexto como
|
|
1477
|
+
* `{ orderId, userAgent, route, sessionId }` sem inflar subject/message.
|
|
1478
|
+
*
|
|
1479
|
+
* Chaves limitadas a 64 chars; valores primitive (string/number/boolean/null).
|
|
1480
|
+
*/
|
|
1481
|
+
metadata?: Record<string, string | number | boolean | null>;
|
|
1430
1482
|
}
|
|
1431
1483
|
interface SupportNamespace {
|
|
1432
|
-
/**
|
|
1484
|
+
/**
|
|
1485
|
+
* Cria um novo ticket. **3.0**: POST `/api/sdk/v1/support/tickets`
|
|
1486
|
+
* (canonical, requer `productId` no body — default `config.productId`).
|
|
1487
|
+
* Mock em dev.
|
|
1488
|
+
*/
|
|
1433
1489
|
createTicket(input: CreateTicketInput): Promise<SupportTicket>;
|
|
1434
|
-
/**
|
|
1435
|
-
|
|
1490
|
+
/**
|
|
1491
|
+
* Lista meus tickets abertos. **3.0**: GET `/api/sdk/v1/support/tickets?productId=...`
|
|
1492
|
+
* (canonical). `options.productSlug` override do `config.productId` default.
|
|
1493
|
+
*/
|
|
1494
|
+
listMyTickets(options?: {
|
|
1495
|
+
productSlug?: string;
|
|
1496
|
+
}): Promise<SupportTicket[]>;
|
|
1436
1497
|
}
|
|
1437
1498
|
/**
|
|
1438
1499
|
* Modo do SDK. `dev` ativa mocks automáticos (úteis pra testes e
|
|
@@ -1459,4 +1520,4 @@ interface CatalogListOptions {
|
|
|
1459
1520
|
includeDrafts?: boolean;
|
|
1460
1521
|
}
|
|
1461
1522
|
|
|
1462
|
-
export { type
|
|
1523
|
+
export { type UsageQuota as $, type AuthNamespace as A, type ProductNotification as B, type CatalogListOptions as C, DEFAULT_BASE_URL as D, type EntitlementCheck as E, type ProductNotificationSeverity as F, type ProductPlan as G, type ProductStatus as H, type ResolvedConfig as I, type SignInOptions as J, type SqlOptions as K, type ListNotificationsOptions as L, MockCheckout as M, type NeetruClient as N, type SupportNamespace as O, type Product as P, type SupportSeverity as Q, type RegisterWebhookInput as R, type SendNotificationInput as S, type SupportStatus as T, type SupportTicket as U, type TelemetryEventAck as V, type TelemetryEventInput as W, type TelemetryLogAck as X, type TelemetryLogInput as Y, type UsageEventInput as Z, type UsageNamespace as _, type AuthStateListener as a, type VerifyTokenOptions as a0, type WebhookEndpoint as a1, type WebhookEvent as a2, type WebhookScopeOptions as a3, type WebhookTestResult as a4, type WebhooksNamespace as a5, createCheckoutNamespace as a6, createNeetruDb as a7, createNotificationsNamespace as a8, createRestSyncTransport as a9, createWebhooksNamespace as aa, getWebSocketRealtimeClient as ab, verifyWebhookSignature as ac, type CatalogListResponse as b, type CheckoutIntentInfo as c, type CheckoutIntentStatus as d, type CheckoutNamespace as e, type CheckoutStartInput as f, type CheckoutStartResult as g, type CheckoutTenantType as h, type CreateTicketInput as i, type DbNamespace as j, type DbSqlLease as k, type DbWhereFilter as l, MockNotifications as m, MockWebhooks as n, type NeetruClientConfig as o, type NeetruDb as p, type NeetruDbEngine as q, NeetruDbError as r, type NeetruDbErrorCode as s, type NeetruDbOptions as t, type NeetruDbTransport as u, type NeetruEnv as v, type NeetruSqlClient as w, type NeetruUser as x, type NotificationScopeOptions as y, type NotificationsNamespace as z };
|
|
@@ -104,6 +104,11 @@ interface ProductNotification {
|
|
|
104
104
|
dismissedAt?: string;
|
|
105
105
|
}
|
|
106
106
|
interface SendNotificationInput {
|
|
107
|
+
/**
|
|
108
|
+
* **3.0 (breaking):** productId é obrigatório (Core valida via Zod). Default
|
|
109
|
+
* resolve do `config.productId`; lança `validation_failed` se ausente.
|
|
110
|
+
*/
|
|
111
|
+
productId?: string;
|
|
107
112
|
userId: string;
|
|
108
113
|
kind: string;
|
|
109
114
|
title: string;
|
|
@@ -118,6 +123,11 @@ interface SendNotificationInput {
|
|
|
118
123
|
fingerprint?: string;
|
|
119
124
|
}
|
|
120
125
|
interface ListNotificationsOptions {
|
|
126
|
+
/**
|
|
127
|
+
* **3.0 (breaking):** productId é obrigatório no Core. Default resolve do
|
|
128
|
+
* `config.productId`.
|
|
129
|
+
*/
|
|
130
|
+
productId?: string;
|
|
121
131
|
/** Inclui notificações dismissed (default false). */
|
|
122
132
|
includeDismissed?: boolean;
|
|
123
133
|
/** Filtro por unread. */
|
|
@@ -125,17 +135,21 @@ interface ListNotificationsOptions {
|
|
|
125
135
|
/** Máx itens (default 50, máx 200). */
|
|
126
136
|
limit?: number;
|
|
127
137
|
}
|
|
138
|
+
/** 3.0: scope option pra markRead/dismiss (productId obrigatório no Core). */
|
|
139
|
+
interface NotificationScopeOptions {
|
|
140
|
+
productId?: string;
|
|
141
|
+
}
|
|
128
142
|
interface NotificationsNamespace {
|
|
129
143
|
/** Produto envia uma notificação pra um usuário do produto. */
|
|
130
144
|
send(input: SendNotificationInput): Promise<ProductNotification>;
|
|
131
145
|
/** Lista notificações de um usuário. */
|
|
132
146
|
list(userId: string, options?: ListNotificationsOptions): Promise<ProductNotification[]>;
|
|
133
147
|
/** Marca como lida. */
|
|
134
|
-
markRead(id: string): Promise<{
|
|
148
|
+
markRead(id: string, options?: NotificationScopeOptions): Promise<{
|
|
135
149
|
ok: true;
|
|
136
150
|
}>;
|
|
137
151
|
/** Descarta. */
|
|
138
|
-
dismiss(id: string): Promise<{
|
|
152
|
+
dismiss(id: string, options?: NotificationScopeOptions): Promise<{
|
|
139
153
|
ok: true;
|
|
140
154
|
}>;
|
|
141
155
|
}
|
|
@@ -145,10 +159,10 @@ declare class MockNotifications implements NotificationsNamespace {
|
|
|
145
159
|
private nextId;
|
|
146
160
|
send(input: SendNotificationInput): Promise<ProductNotification>;
|
|
147
161
|
list(userId: string, options?: ListNotificationsOptions): Promise<ProductNotification[]>;
|
|
148
|
-
markRead(id: string): Promise<{
|
|
162
|
+
markRead(id: string, _options?: NotificationScopeOptions): Promise<{
|
|
149
163
|
ok: true;
|
|
150
164
|
}>;
|
|
151
|
-
dismiss(id: string): Promise<{
|
|
165
|
+
dismiss(id: string, _options?: NotificationScopeOptions): Promise<{
|
|
152
166
|
ok: true;
|
|
153
167
|
}>;
|
|
154
168
|
}
|
|
@@ -169,6 +183,12 @@ interface WebhookEndpoint {
|
|
|
169
183
|
createdAt: string;
|
|
170
184
|
}
|
|
171
185
|
interface RegisterWebhookInput {
|
|
186
|
+
/**
|
|
187
|
+
* **3.0 (breaking):** `productId` é obrigatório no body. Se ausente,
|
|
188
|
+
* SDK tenta resolver do `config.productId` (default no `createNeetruClient`);
|
|
189
|
+
* lança `validation_failed` se ambos faltarem.
|
|
190
|
+
*/
|
|
191
|
+
productId?: string;
|
|
172
192
|
url: string;
|
|
173
193
|
events: WebhookEvent[];
|
|
174
194
|
/**
|
|
@@ -184,53 +204,67 @@ interface WebhookTestResult {
|
|
|
184
204
|
durationMs?: number;
|
|
185
205
|
error?: string;
|
|
186
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* 3.0: opções de scoping — todos os verbos exigem `productId` (default do
|
|
209
|
+
* `config.productId` se ausente).
|
|
210
|
+
*/
|
|
211
|
+
interface WebhookScopeOptions {
|
|
212
|
+
productId?: string;
|
|
213
|
+
}
|
|
187
214
|
interface WebhooksNamespace {
|
|
188
215
|
/** Registra um novo endpoint. */
|
|
189
216
|
register(input: RegisterWebhookInput): Promise<WebhookEndpoint>;
|
|
190
217
|
/** Lista endpoints registrados pelo produto. */
|
|
191
|
-
list(): Promise<WebhookEndpoint[]>;
|
|
218
|
+
list(options?: WebhookScopeOptions): Promise<WebhookEndpoint[]>;
|
|
192
219
|
/** Remove um endpoint. */
|
|
193
|
-
unregister(id: string): Promise<{
|
|
220
|
+
unregister(id: string, options?: WebhookScopeOptions): Promise<{
|
|
194
221
|
ok: true;
|
|
195
222
|
}>;
|
|
196
223
|
/** Dispara evento de teste pra validar conectividade. */
|
|
197
|
-
test(id: string): Promise<WebhookTestResult>;
|
|
224
|
+
test(id: string, options?: WebhookScopeOptions): Promise<WebhookTestResult>;
|
|
198
225
|
}
|
|
199
226
|
/**
|
|
200
227
|
* Verifica assinatura HMAC SHA-256 de payload de webhook recebido pelo
|
|
201
|
-
* produto consumer.
|
|
228
|
+
* produto consumer. **3.0**: Universal (browser/Node/Edge) via WebCrypto.subtle.
|
|
229
|
+
*
|
|
230
|
+
* Constant-time compare via byte-level XOR accumulator (não usa
|
|
231
|
+
* `timingSafeEqual` do Node porque WebCrypto não tem equivalente direto).
|
|
202
232
|
*
|
|
203
|
-
* @param payload Corpo cru da request (string ou
|
|
233
|
+
* @param payload Corpo cru da request (string ou Uint8Array). NÃO use o objeto
|
|
204
234
|
* parseado — JSON.stringify pode diferir do que foi assinado.
|
|
205
235
|
* @param signature Header `X-Neetru-Signature` recebido (formato `sha256=<hex>`).
|
|
206
236
|
* @param secret Secret registrado em `webhooks.register({ secret })`.
|
|
207
|
-
* @returns true se assinatura confere, false caso contrário.
|
|
237
|
+
* @returns Promise<boolean> — true se assinatura confere, false caso contrário.
|
|
208
238
|
*
|
|
209
239
|
* @example
|
|
210
240
|
* ```ts
|
|
211
|
-
* //
|
|
212
|
-
*
|
|
213
|
-
* const
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
* }
|
|
217
|
-
* const event = JSON.parse(
|
|
241
|
+
* // Next.js Route Handler (Edge ou Node runtime — funciona em ambos)
|
|
242
|
+
* export async function POST(req: Request) {
|
|
243
|
+
* const raw = await req.text();
|
|
244
|
+
* const sig = req.headers.get('X-Neetru-Signature');
|
|
245
|
+
* const ok = await verifyWebhookSignature(raw, sig, process.env.NEETRU_WEBHOOK_SECRET!);
|
|
246
|
+
* if (!ok) return new Response('unauthorized', { status: 401 });
|
|
247
|
+
* const event = JSON.parse(raw);
|
|
218
248
|
* // ... handle event
|
|
219
|
-
*
|
|
220
|
-
* }
|
|
249
|
+
* return Response.json({ ok: true });
|
|
250
|
+
* }
|
|
221
251
|
* ```
|
|
252
|
+
*
|
|
253
|
+
* @throws NeetruError('runtime_unsupported') se runtime não expõe WebCrypto.
|
|
254
|
+
* Não retorna `false` silencioso — caller precisa distinguir "assinatura
|
|
255
|
+
* inválida" (return false) de "ambiente não suporta" (throw).
|
|
222
256
|
*/
|
|
223
|
-
declare function verifyWebhookSignature(payload: string | Uint8Array, signature: string | null | undefined, secret: string): boolean
|
|
257
|
+
declare function verifyWebhookSignature(payload: string | Uint8Array, signature: string | null | undefined, secret: string): Promise<boolean>;
|
|
224
258
|
declare function createWebhooksNamespace(config: ResolvedConfig): WebhooksNamespace;
|
|
225
259
|
declare class MockWebhooks implements WebhooksNamespace {
|
|
226
260
|
private endpoints;
|
|
227
261
|
private nextId;
|
|
228
262
|
register(input: RegisterWebhookInput): Promise<WebhookEndpoint>;
|
|
229
|
-
list(): Promise<WebhookEndpoint[]>;
|
|
230
|
-
unregister(id: string): Promise<{
|
|
263
|
+
list(_options?: WebhookScopeOptions): Promise<WebhookEndpoint[]>;
|
|
264
|
+
unregister(id: string, _options?: WebhookScopeOptions): Promise<{
|
|
231
265
|
ok: true;
|
|
232
266
|
}>;
|
|
233
|
-
test(id: string): Promise<WebhookTestResult>;
|
|
267
|
+
test(id: string, _options?: WebhookScopeOptions): Promise<WebhookTestResult>;
|
|
234
268
|
}
|
|
235
269
|
|
|
236
270
|
/**
|
|
@@ -1043,6 +1077,14 @@ interface NeetruClientConfig {
|
|
|
1043
1077
|
* Valores: `'rest'` | `'firestore'` | `'nosql-vm'`.
|
|
1044
1078
|
*/
|
|
1045
1079
|
db?: NeetruDbOptions;
|
|
1080
|
+
/**
|
|
1081
|
+
* 3.0 — hosts adicionais permitidos para `baseUrl`. Por default, SDK aceita
|
|
1082
|
+
* `*.neetru.com` HTTPS + localhost. Para apontar pra staging/proxy custom em
|
|
1083
|
+
* `https://meu-proxy.empresa.com`, adicione `['empresa.com']`.
|
|
1084
|
+
*
|
|
1085
|
+
* Bypass total: `NEETRU_ALLOW_INSECURE_BASEURL=1` no env.
|
|
1086
|
+
*/
|
|
1087
|
+
allowedHosts?: string[];
|
|
1046
1088
|
}
|
|
1047
1089
|
/**
|
|
1048
1090
|
* Status do produto no catálogo público.
|
|
@@ -1299,41 +1341,41 @@ interface VerifyTokenOptions {
|
|
|
1299
1341
|
*/
|
|
1300
1342
|
jwksCacheTtlMs?: number;
|
|
1301
1343
|
}
|
|
1344
|
+
/**
|
|
1345
|
+
* 3.0 BREAKING: `UsageEventInput` mantido só como tipo para tests/legacy
|
|
1346
|
+
* imports — não é mais retorno de método. `usage.track`/`usage.getQuota`
|
|
1347
|
+
* **REMOVIDOS** em 3.0. Use `usage.report(resource, qty, options)`.
|
|
1348
|
+
*/
|
|
1302
1349
|
interface UsageEventInput {
|
|
1303
|
-
/** Nome do evento, ex: `report_generated`, `api_call`. */
|
|
1304
1350
|
event: string;
|
|
1305
|
-
/** Atributos do evento. Valores primitivos serializáveis. */
|
|
1306
1351
|
properties?: Record<string, string | number | boolean | null>;
|
|
1307
|
-
/** Quantidade — default 1 (1 evento). Útil pra batch. */
|
|
1308
1352
|
quantity?: number;
|
|
1309
1353
|
}
|
|
1354
|
+
/**
|
|
1355
|
+
* 3.0 BREAKING: `UsageQuota` mantido só para compat de imports. Não é mais
|
|
1356
|
+
* retorno de método ativo. `usage.report()` devolve `{value, limit, remaining}`
|
|
1357
|
+
* inline; `usage.check()` devolve detalhes do entitlement.
|
|
1358
|
+
*/
|
|
1310
1359
|
interface UsageQuota {
|
|
1311
1360
|
metric: string;
|
|
1312
|
-
/** Quantidade já consumida no período. */
|
|
1313
1361
|
used: number;
|
|
1314
|
-
/** Limite total. -1 = unlimited. */
|
|
1315
1362
|
limit: number;
|
|
1316
|
-
/** ISO timestamp do reset (próximo período). */
|
|
1317
1363
|
resetsAt?: string;
|
|
1318
|
-
/** Plano que define o limite. */
|
|
1319
1364
|
plan?: string;
|
|
1320
1365
|
}
|
|
1366
|
+
/**
|
|
1367
|
+
* 3.0 — superfície limpa: `report` (POST metered) + `check` (GET entitlement).
|
|
1368
|
+
*
|
|
1369
|
+
* Métodos removidos vs 2.x:
|
|
1370
|
+
* - `track(event, props)` — vaporware contra Core. Use `report()`.
|
|
1371
|
+
* - `getQuota(metric)` — endpoint nunca existiu. `report()` devolve quota.
|
|
1372
|
+
*/
|
|
1321
1373
|
interface UsageNamespace {
|
|
1322
|
-
/** Persiste um evento de uso. Mock em dev, POST `/sdk/v1/usage/record` em prod. */
|
|
1323
|
-
track(event: string, props?: UsageEventInput['properties']): Promise<{
|
|
1324
|
-
ok: true;
|
|
1325
|
-
}>;
|
|
1326
|
-
/** Lê quota atual de uma métrica. Mock em dev, GET `/sdk/v1/usage/quota` em prod. */
|
|
1327
|
-
getQuota(metric: string): Promise<UsageQuota>;
|
|
1328
1374
|
/**
|
|
1329
|
-
*
|
|
1330
|
-
*
|
|
1331
|
-
*
|
|
1332
|
-
* Diferente de `track()`: usa o endpoint canônico Sprint 7 que incrementa
|
|
1333
|
-
* `usage_counters/{tenantId}_{productId}_{resource}_{yyyymm}` atomicamente.
|
|
1375
|
+
* Reporta consumo metered. Incrementa `usage_counters` no Core atomicamente.
|
|
1376
|
+
* Idempotency-Key gerado por chamada (defesa anti-dup em retry transient).
|
|
1334
1377
|
*
|
|
1335
|
-
* `productId`/`tenantId`
|
|
1336
|
-
* ausentes nas options.
|
|
1378
|
+
* `productId`/`tenantId` lidos do contexto do client se ausentes nas options.
|
|
1337
1379
|
*/
|
|
1338
1380
|
report(resource: string, qty?: number, options?: {
|
|
1339
1381
|
productId?: string;
|
|
@@ -1347,8 +1389,9 @@ interface UsageNamespace {
|
|
|
1347
1389
|
status?: string;
|
|
1348
1390
|
}>;
|
|
1349
1391
|
/**
|
|
1350
|
-
*
|
|
1351
|
-
*
|
|
1392
|
+
* Verifica entitlement de um resource/feature. GET cacheável (HTTP 60s).
|
|
1393
|
+
* Resposta inclui `allowed`, `reason`, `remaining`, `limit`, `planId`,
|
|
1394
|
+
* `planFeatures` e `behavior` ('readonly' quando limit_exceeded).
|
|
1352
1395
|
*/
|
|
1353
1396
|
check(resource: string, options?: {
|
|
1354
1397
|
productId?: string;
|
|
@@ -1360,6 +1403,7 @@ interface UsageNamespace {
|
|
|
1360
1403
|
limit?: number;
|
|
1361
1404
|
planId?: string | null;
|
|
1362
1405
|
planFeatures?: string[];
|
|
1406
|
+
behavior?: 'readonly' | null;
|
|
1363
1407
|
}>;
|
|
1364
1408
|
}
|
|
1365
1409
|
/**
|
|
@@ -1427,12 +1471,29 @@ interface CreateTicketInput {
|
|
|
1427
1471
|
message: string;
|
|
1428
1472
|
severity?: SupportSeverity;
|
|
1429
1473
|
productSlug?: string;
|
|
1474
|
+
/**
|
|
1475
|
+
* **L-05 fix (Opus review 2026-05-27):** metadata opcional (Core já aceita
|
|
1476
|
+
* via `metadata: z.record(...)` no Zod). Útil pra anexar contexto como
|
|
1477
|
+
* `{ orderId, userAgent, route, sessionId }` sem inflar subject/message.
|
|
1478
|
+
*
|
|
1479
|
+
* Chaves limitadas a 64 chars; valores primitive (string/number/boolean/null).
|
|
1480
|
+
*/
|
|
1481
|
+
metadata?: Record<string, string | number | boolean | null>;
|
|
1430
1482
|
}
|
|
1431
1483
|
interface SupportNamespace {
|
|
1432
|
-
/**
|
|
1484
|
+
/**
|
|
1485
|
+
* Cria um novo ticket. **3.0**: POST `/api/sdk/v1/support/tickets`
|
|
1486
|
+
* (canonical, requer `productId` no body — default `config.productId`).
|
|
1487
|
+
* Mock em dev.
|
|
1488
|
+
*/
|
|
1433
1489
|
createTicket(input: CreateTicketInput): Promise<SupportTicket>;
|
|
1434
|
-
/**
|
|
1435
|
-
|
|
1490
|
+
/**
|
|
1491
|
+
* Lista meus tickets abertos. **3.0**: GET `/api/sdk/v1/support/tickets?productId=...`
|
|
1492
|
+
* (canonical). `options.productSlug` override do `config.productId` default.
|
|
1493
|
+
*/
|
|
1494
|
+
listMyTickets(options?: {
|
|
1495
|
+
productSlug?: string;
|
|
1496
|
+
}): Promise<SupportTicket[]>;
|
|
1436
1497
|
}
|
|
1437
1498
|
/**
|
|
1438
1499
|
* Modo do SDK. `dev` ativa mocks automáticos (úteis pra testes e
|
|
@@ -1459,4 +1520,4 @@ interface CatalogListOptions {
|
|
|
1459
1520
|
includeDrafts?: boolean;
|
|
1460
1521
|
}
|
|
1461
1522
|
|
|
1462
|
-
export { type
|
|
1523
|
+
export { type UsageQuota as $, type AuthNamespace as A, type ProductNotification as B, type CatalogListOptions as C, DEFAULT_BASE_URL as D, type EntitlementCheck as E, type ProductNotificationSeverity as F, type ProductPlan as G, type ProductStatus as H, type ResolvedConfig as I, type SignInOptions as J, type SqlOptions as K, type ListNotificationsOptions as L, MockCheckout as M, type NeetruClient as N, type SupportNamespace as O, type Product as P, type SupportSeverity as Q, type RegisterWebhookInput as R, type SendNotificationInput as S, type SupportStatus as T, type SupportTicket as U, type TelemetryEventAck as V, type TelemetryEventInput as W, type TelemetryLogAck as X, type TelemetryLogInput as Y, type UsageEventInput as Z, type UsageNamespace as _, type AuthStateListener as a, type VerifyTokenOptions as a0, type WebhookEndpoint as a1, type WebhookEvent as a2, type WebhookScopeOptions as a3, type WebhookTestResult as a4, type WebhooksNamespace as a5, createCheckoutNamespace as a6, createNeetruDb as a7, createNotificationsNamespace as a8, createRestSyncTransport as a9, createWebhooksNamespace as aa, getWebSocketRealtimeClient as ab, verifyWebhookSignature as ac, type CatalogListResponse as b, type CheckoutIntentInfo as c, type CheckoutIntentStatus as d, type CheckoutNamespace as e, type CheckoutStartInput as f, type CheckoutStartResult as g, type CheckoutTenantType as h, type CreateTicketInput as i, type DbNamespace as j, type DbSqlLease as k, type DbWhereFilter as l, MockNotifications as m, MockWebhooks as n, type NeetruClientConfig as o, type NeetruDb as p, type NeetruDbEngine as q, NeetruDbError as r, type NeetruDbErrorCode as s, type NeetruDbOptions as t, type NeetruDbTransport as u, type NeetruEnv as v, type NeetruSqlClient as w, type NeetruUser as x, type NotificationScopeOptions as y, type NotificationsNamespace as z };
|