@neetru/sdk 1.2.0 → 2.1.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 +284 -244
- package/README.md +194 -194
- package/dist/auth.cjs +3740 -345
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +5 -1
- package/dist/auth.d.ts +5 -1
- package/dist/auth.mjs +3740 -345
- package/dist/auth.mjs.map +1 -1
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +5 -1
- package/dist/catalog.d.ts +5 -1
- package/dist/catalog.mjs.map +1 -1
- package/dist/checkout.cjs.map +1 -1
- package/dist/checkout.d.cts +5 -1
- package/dist/checkout.d.ts +5 -1
- package/dist/checkout.mjs.map +1 -1
- package/dist/collection-ref-BBvTTXoG.d.cts +423 -0
- package/dist/collection-ref-BBvTTXoG.d.ts +423 -0
- package/dist/db-react.cjs +136 -0
- package/dist/db-react.cjs.map +1 -0
- package/dist/db-react.d.cts +99 -0
- package/dist/db-react.d.ts +99 -0
- package/dist/db-react.mjs +112 -0
- package/dist/db-react.mjs.map +1 -0
- package/dist/db.cjs +3599 -131
- package/dist/db.cjs.map +1 -1
- package/dist/db.d.cts +5 -8
- package/dist/db.d.ts +5 -8
- package/dist/db.mjs +3596 -131
- package/dist/db.mjs.map +1 -1
- package/dist/entitlements.cjs.map +1 -1
- package/dist/entitlements.d.cts +5 -1
- package/dist/entitlements.d.ts +5 -1
- package/dist/entitlements.mjs.map +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.mjs.map +1 -1
- package/dist/index.cjs +3957 -342
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -6
- package/dist/index.d.ts +13 -6
- package/dist/index.mjs +3877 -263
- package/dist/index.mjs.map +1 -1
- package/dist/mocks.cjs +183 -7
- package/dist/mocks.cjs.map +1 -1
- package/dist/mocks.d.cts +18 -5
- package/dist/mocks.d.ts +18 -5
- package/dist/mocks.mjs +183 -7
- package/dist/mocks.mjs.map +1 -1
- package/dist/notifications.cjs.map +1 -1
- package/dist/notifications.d.cts +5 -1
- package/dist/notifications.d.ts +5 -1
- package/dist/notifications.mjs.map +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +5 -1
- package/dist/react.d.ts +5 -1
- package/dist/react.mjs.map +1 -1
- package/dist/support.cjs.map +1 -1
- package/dist/support.d.cts +5 -1
- package/dist/support.d.ts +5 -1
- package/dist/support.mjs.map +1 -1
- package/dist/telemetry.cjs.map +1 -1
- package/dist/telemetry.d.cts +5 -1
- package/dist/telemetry.d.ts +5 -1
- package/dist/telemetry.mjs.map +1 -1
- package/dist/types-B1jylbMC.d.ts +1364 -0
- package/dist/types-Kmt4y1FQ.d.cts +1364 -0
- package/dist/usage.cjs.map +1 -1
- package/dist/usage.d.cts +5 -1
- package/dist/usage.d.ts +5 -1
- package/dist/usage.mjs.map +1 -1
- package/dist/webhooks.cjs.map +1 -1
- package/dist/webhooks.d.cts +5 -1
- package/dist/webhooks.d.ts +5 -1
- package/dist/webhooks.mjs.map +1 -1
- package/package.json +133 -111
- package/dist/types-CQAfwqUS.d.cts +0 -654
- package/dist/types-CQAfwqUS.d.ts +0 -654
|
@@ -1,654 +0,0 @@
|
|
|
1
|
-
/** Tipo do tenant alvo da subscription (PF=uid, PJ=orgId). */
|
|
2
|
-
type CheckoutTenantType = 'pf' | 'pj';
|
|
3
|
-
/** Status do `checkout_intents/{intentId}` no Core. */
|
|
4
|
-
type CheckoutIntentStatus = 'pending' | 'kyc_in_progress' | 'stripe_redirected' | 'completed' | 'expired' | 'cancelled';
|
|
5
|
-
interface CheckoutStartInput {
|
|
6
|
-
/** Slug do produto no catálogo (ex: `neetru-pulse`). */
|
|
7
|
-
productId: string;
|
|
8
|
-
/** Slug do plano no catálogo do produto (ex: `pro_monthly`). */
|
|
9
|
-
planId: string;
|
|
10
|
-
/** Pra onde o produto SaaS quer voltar pós-checkout. https obrigatório (ou http://localhost em dev). */
|
|
11
|
-
callbackUrl: string;
|
|
12
|
-
/** Override pra checkout em nome de uma org. Default: PF do uid logado. */
|
|
13
|
-
tenantType?: CheckoutTenantType;
|
|
14
|
-
/** Quando `tenantType='pj'`, id da org. Ignorado quando PF. */
|
|
15
|
-
tenantId?: string;
|
|
16
|
-
/**
|
|
17
|
-
* Em browsers, default `true` — SDK faz `window.location.href = redirectUrl`.
|
|
18
|
-
* Passe `false` se quiser controlar o redirect manualmente.
|
|
19
|
-
*/
|
|
20
|
-
autoRedirect?: boolean;
|
|
21
|
-
}
|
|
22
|
-
interface CheckoutStartResult {
|
|
23
|
-
intentId: string;
|
|
24
|
-
redirectUrl: string;
|
|
25
|
-
status: CheckoutIntentStatus;
|
|
26
|
-
expiresAt: string;
|
|
27
|
-
/** True se KYC ainda precisa ser coletado no portal. UI pode mostrar hint. */
|
|
28
|
-
requiresKyc: boolean;
|
|
29
|
-
}
|
|
30
|
-
interface CheckoutIntentInfo {
|
|
31
|
-
intentId: string;
|
|
32
|
-
uid: string;
|
|
33
|
-
targetTenantId: string;
|
|
34
|
-
targetTenantType: CheckoutTenantType;
|
|
35
|
-
productId: string;
|
|
36
|
-
planId: string;
|
|
37
|
-
callbackUrl: string;
|
|
38
|
-
status: CheckoutIntentStatus;
|
|
39
|
-
/** Stripe Checkout Session id quando avançou pra `stripe_redirected`. */
|
|
40
|
-
stripeSessionId?: string | null;
|
|
41
|
-
expiresAt: string;
|
|
42
|
-
/** True se já passou `expiresAt` mas Core ainda não marcou expired. */
|
|
43
|
-
isStale?: boolean;
|
|
44
|
-
}
|
|
45
|
-
interface CheckoutNamespace {
|
|
46
|
-
/**
|
|
47
|
-
* Inicia checkout. Em browser, redireciona automaticamente pro portal.
|
|
48
|
-
* Em Node/SSR, retorna o resultado sem efeitos colaterais — caller decide
|
|
49
|
-
* o que fazer com `redirectUrl`.
|
|
50
|
-
*
|
|
51
|
-
* Dev mode (`NEETRU_ENV=dev`): retorna URL fake `https://localhost:9003/portal/checkout/mock-XXXX`.
|
|
52
|
-
*/
|
|
53
|
-
start(input: CheckoutStartInput): Promise<CheckoutStartResult>;
|
|
54
|
-
/** Lê estado atual do intent (Core). */
|
|
55
|
-
get(intentId: string): Promise<CheckoutIntentInfo>;
|
|
56
|
-
/** Cancela um intent que ainda não virou `stripe_redirected`. */
|
|
57
|
-
cancel(intentId: string): Promise<{
|
|
58
|
-
ok: true;
|
|
59
|
-
alreadyCancelled: boolean;
|
|
60
|
-
}>;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Mock dev — retorna URL fake `https://localhost:9003/portal/checkout/mock-XXXX`
|
|
64
|
-
* sem tocar no Core. Útil pra dev externo SaaS testar UI/redirect sem precisar
|
|
65
|
-
* de Bearer token Neetru.
|
|
66
|
-
*
|
|
67
|
-
* Dev mode persiste intents em mapa in-memory pro `get`/`cancel` retornarem
|
|
68
|
-
* resultado consistente.
|
|
69
|
-
*/
|
|
70
|
-
declare class MockCheckout implements CheckoutNamespace {
|
|
71
|
-
private readonly intents;
|
|
72
|
-
start(input: CheckoutStartInput): Promise<CheckoutStartResult>;
|
|
73
|
-
get(intentId: string): Promise<CheckoutIntentInfo>;
|
|
74
|
-
cancel(intentId: string): Promise<{
|
|
75
|
-
ok: true;
|
|
76
|
-
alreadyCancelled: boolean;
|
|
77
|
-
}>;
|
|
78
|
-
}
|
|
79
|
-
declare function createCheckoutNamespace(config: ResolvedConfig): CheckoutNamespace;
|
|
80
|
-
|
|
81
|
-
type ProductNotificationSeverity = 'info' | 'success' | 'warning' | 'error';
|
|
82
|
-
interface ProductNotification {
|
|
83
|
-
id: string;
|
|
84
|
-
/** UID do usuário final (do produto, não staff Neetru). */
|
|
85
|
-
userId: string;
|
|
86
|
-
/** Identificador semântico do evento (ex: `order.received`). */
|
|
87
|
-
kind: string;
|
|
88
|
-
severity: ProductNotificationSeverity;
|
|
89
|
-
title: string;
|
|
90
|
-
body?: string;
|
|
91
|
-
/** Link opcional pra ação. */
|
|
92
|
-
link?: string;
|
|
93
|
-
/** Metadata livre (serializável). */
|
|
94
|
-
metadata?: Record<string, string | number | boolean | null>;
|
|
95
|
-
createdAt: string;
|
|
96
|
-
/** ISO quando user marcou lida. */
|
|
97
|
-
readAt?: string;
|
|
98
|
-
/** ISO quando user descartou. */
|
|
99
|
-
dismissedAt?: string;
|
|
100
|
-
}
|
|
101
|
-
interface SendNotificationInput {
|
|
102
|
-
userId: string;
|
|
103
|
-
kind: string;
|
|
104
|
-
title: string;
|
|
105
|
-
severity?: ProductNotificationSeverity;
|
|
106
|
-
body?: string;
|
|
107
|
-
link?: string;
|
|
108
|
-
metadata?: Record<string, string | number | boolean | null>;
|
|
109
|
-
/**
|
|
110
|
-
* Dedup — se já existir notificação com mesmo fingerprint dentro de 24h,
|
|
111
|
-
* NÃO cria duplicata. Útil pra evitar spam quando webhook reentrega.
|
|
112
|
-
*/
|
|
113
|
-
fingerprint?: string;
|
|
114
|
-
}
|
|
115
|
-
interface ListNotificationsOptions {
|
|
116
|
-
/** Inclui notificações dismissed (default false). */
|
|
117
|
-
includeDismissed?: boolean;
|
|
118
|
-
/** Filtro por unread. */
|
|
119
|
-
onlyUnread?: boolean;
|
|
120
|
-
/** Máx itens (default 50, máx 200). */
|
|
121
|
-
limit?: number;
|
|
122
|
-
}
|
|
123
|
-
interface NotificationsNamespace {
|
|
124
|
-
/** Produto envia uma notificação pra um usuário do produto. */
|
|
125
|
-
send(input: SendNotificationInput): Promise<ProductNotification>;
|
|
126
|
-
/** Lista notificações de um usuário. */
|
|
127
|
-
list(userId: string, options?: ListNotificationsOptions): Promise<ProductNotification[]>;
|
|
128
|
-
/** Marca como lida. */
|
|
129
|
-
markRead(id: string): Promise<{
|
|
130
|
-
ok: true;
|
|
131
|
-
}>;
|
|
132
|
-
/** Descarta. */
|
|
133
|
-
dismiss(id: string): Promise<{
|
|
134
|
-
ok: true;
|
|
135
|
-
}>;
|
|
136
|
-
}
|
|
137
|
-
declare function createNotificationsNamespace(config: ResolvedConfig): NotificationsNamespace;
|
|
138
|
-
declare class MockNotifications implements NotificationsNamespace {
|
|
139
|
-
private notifications;
|
|
140
|
-
private nextId;
|
|
141
|
-
send(input: SendNotificationInput): Promise<ProductNotification>;
|
|
142
|
-
list(userId: string, options?: ListNotificationsOptions): Promise<ProductNotification[]>;
|
|
143
|
-
markRead(id: string): Promise<{
|
|
144
|
-
ok: true;
|
|
145
|
-
}>;
|
|
146
|
-
dismiss(id: string): Promise<{
|
|
147
|
-
ok: true;
|
|
148
|
-
}>;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/** Eventos Neetru que produtos podem assinar. Lista expansível por minor bump. */
|
|
152
|
-
type WebhookEvent = 'subscription.activated' | 'subscription.cancelled' | 'subscription.payment_failed' | 'subscription.trial_ending' | 'usage.quota_exceeded' | 'account.suspended' | 'account.reactivated' | 'support.ticket_replied';
|
|
153
|
-
interface WebhookEndpoint {
|
|
154
|
-
id: string;
|
|
155
|
-
url: string;
|
|
156
|
-
events: WebhookEvent[];
|
|
157
|
-
/** Quando true, `X-Neetru-Signature` é enviado em cada dispatch. */
|
|
158
|
-
hasSecret: boolean;
|
|
159
|
-
status: 'active' | 'degraded' | 'disabled';
|
|
160
|
-
/** ISO timestamp do último dispatch bem-sucedido. */
|
|
161
|
-
lastDeliveryAt?: string;
|
|
162
|
-
/** Quantos dispatches falharam consecutivos (resetado em sucesso). */
|
|
163
|
-
consecutiveFailures?: number;
|
|
164
|
-
createdAt: string;
|
|
165
|
-
}
|
|
166
|
-
interface RegisterWebhookInput {
|
|
167
|
-
url: string;
|
|
168
|
-
events: WebhookEvent[];
|
|
169
|
-
/**
|
|
170
|
-
* Secret pra HMAC SHA-256 (mín 16 chars). Recomendado.
|
|
171
|
-
* Quando ausente, dispatches vão sem assinatura — produto deve ter
|
|
172
|
-
* IP allowlist ou outra defesa.
|
|
173
|
-
*/
|
|
174
|
-
secret?: string;
|
|
175
|
-
}
|
|
176
|
-
interface WebhookTestResult {
|
|
177
|
-
ok: boolean;
|
|
178
|
-
statusCode?: number;
|
|
179
|
-
durationMs?: number;
|
|
180
|
-
error?: string;
|
|
181
|
-
}
|
|
182
|
-
interface WebhooksNamespace {
|
|
183
|
-
/** Registra um novo endpoint. */
|
|
184
|
-
register(input: RegisterWebhookInput): Promise<WebhookEndpoint>;
|
|
185
|
-
/** Lista endpoints registrados pelo produto. */
|
|
186
|
-
list(): Promise<WebhookEndpoint[]>;
|
|
187
|
-
/** Remove um endpoint. */
|
|
188
|
-
unregister(id: string): Promise<{
|
|
189
|
-
ok: true;
|
|
190
|
-
}>;
|
|
191
|
-
/** Dispara evento de teste pra validar conectividade. */
|
|
192
|
-
test(id: string): Promise<WebhookTestResult>;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Verifica assinatura HMAC SHA-256 de payload de webhook recebido pelo
|
|
196
|
-
* produto consumer. Constant-time compare pra resistir a timing attack.
|
|
197
|
-
*
|
|
198
|
-
* @param payload Corpo cru da request (string ou Buffer). NÃO use o objeto
|
|
199
|
-
* parseado — JSON.stringify pode diferir do que foi assinado.
|
|
200
|
-
* @param signature Header `X-Neetru-Signature` recebido (formato `sha256=<hex>`).
|
|
201
|
-
* @param secret Secret registrado em `webhooks.register({ secret })`.
|
|
202
|
-
* @returns true se assinatura confere, false caso contrário.
|
|
203
|
-
*
|
|
204
|
-
* @example
|
|
205
|
-
* ```ts
|
|
206
|
-
* // Express handler
|
|
207
|
-
* app.post('/webhooks/neetru', express.raw({ type: 'application/json' }), (req, res) => {
|
|
208
|
-
* const sig = req.header('X-Neetru-Signature');
|
|
209
|
-
* if (!verifyWebhookSignature(req.body, sig, process.env.WEBHOOK_SECRET!)) {
|
|
210
|
-
* return res.status(401).end();
|
|
211
|
-
* }
|
|
212
|
-
* const event = JSON.parse(req.body.toString('utf8'));
|
|
213
|
-
* // ... handle event
|
|
214
|
-
* res.json({ ok: true });
|
|
215
|
-
* });
|
|
216
|
-
* ```
|
|
217
|
-
*/
|
|
218
|
-
declare function verifyWebhookSignature(payload: string | Uint8Array, signature: string | null | undefined, secret: string): boolean;
|
|
219
|
-
declare function createWebhooksNamespace(config: ResolvedConfig): WebhooksNamespace;
|
|
220
|
-
declare class MockWebhooks implements WebhooksNamespace {
|
|
221
|
-
private endpoints;
|
|
222
|
-
private nextId;
|
|
223
|
-
register(input: RegisterWebhookInput): Promise<WebhookEndpoint>;
|
|
224
|
-
list(): Promise<WebhookEndpoint[]>;
|
|
225
|
-
unregister(id: string): Promise<{
|
|
226
|
-
ok: true;
|
|
227
|
-
}>;
|
|
228
|
-
test(id: string): Promise<WebhookTestResult>;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Tipos públicos do SDK Neetru.
|
|
233
|
-
*
|
|
234
|
-
* Vendor-neutral: nada aqui referencia `firebase/*`, `stripe`, ou qualquer
|
|
235
|
-
* provider interno. Caller só vê superfície neutra (Product, Entitlement, ...).
|
|
236
|
-
*/
|
|
237
|
-
/** Default base URL pra API pública Neetru. */
|
|
238
|
-
declare const DEFAULT_BASE_URL = "https://api.neetru.com";
|
|
239
|
-
/**
|
|
240
|
-
* Configuração passada pra `createNeetruClient`.
|
|
241
|
-
*/
|
|
242
|
-
interface NeetruClientConfig {
|
|
243
|
-
/**
|
|
244
|
-
* Bearer token Neetru (formato `nrt_<keyId>_<secret>`). Opcional —
|
|
245
|
-
* se ausente, o SDK tenta `process.env.NEETRU_API_KEY` em Node.
|
|
246
|
-
*
|
|
247
|
-
* Endpoints públicos (catalog) funcionam sem apiKey. Endpoints autenticados
|
|
248
|
-
* (entitlements, telemetry) lançam `missing_api_key` se ausente.
|
|
249
|
-
*/
|
|
250
|
-
apiKey?: string;
|
|
251
|
-
/**
|
|
252
|
-
* URL base da API Neetru. Default: `https://api.neetru.com`.
|
|
253
|
-
* Útil em testes apontando pra staging ou mock server.
|
|
254
|
-
*/
|
|
255
|
-
baseUrl?: string;
|
|
256
|
-
/**
|
|
257
|
-
* Implementação de fetch customizada. Default: `globalThis.fetch`.
|
|
258
|
-
* Necessário em runtimes que não exponham fetch global por default.
|
|
259
|
-
*/
|
|
260
|
-
fetch?: typeof globalThis.fetch;
|
|
261
|
-
/**
|
|
262
|
-
* Modo de runtime. `dev` ativa mocks (auth retorna user fixture, usage só
|
|
263
|
-
* loga, support retorna lista fake). `workspace` e `prod` chamam HTTP real.
|
|
264
|
-
*
|
|
265
|
-
* Default: lê `process.env.NEETRU_ENV` (Node) ou `globalThis.NEETRU_ENV`
|
|
266
|
-
* (browser); fallback `prod`.
|
|
267
|
-
*/
|
|
268
|
-
env?: 'dev' | 'workspace' | 'prod';
|
|
269
|
-
/**
|
|
270
|
-
* Override de mocks — útil em tests do consumer pra injetar fixtures
|
|
271
|
-
* determinísticos (sem depender de NEETRU_ENV=dev).
|
|
272
|
-
*/
|
|
273
|
-
mocks?: {
|
|
274
|
-
auth?: AuthNamespace;
|
|
275
|
-
usage?: UsageNamespace;
|
|
276
|
-
support?: SupportNamespace;
|
|
277
|
-
entitlements?: NeetruClient['entitlements'];
|
|
278
|
-
db?: DbNamespace;
|
|
279
|
-
webhooks?: WebhooksNamespace;
|
|
280
|
-
notifications?: NotificationsNamespace;
|
|
281
|
-
};
|
|
282
|
-
/**
|
|
283
|
-
* v0.3 — productId default usado por `usage.report()` / `usage.check()` /
|
|
284
|
-
* `db.collection()` quando não passado explicitamente nas options.
|
|
285
|
-
*/
|
|
286
|
-
productId?: string;
|
|
287
|
-
/**
|
|
288
|
-
* v0.3 — tenantId default usado por `usage.report()` / `usage.check()` /
|
|
289
|
-
* `db.collection()` quando não passado explicitamente nas options.
|
|
290
|
-
*/
|
|
291
|
-
tenantId?: string;
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* Status do produto no catálogo público.
|
|
295
|
-
*/
|
|
296
|
-
type ProductStatus = 'live' | 'soon' | 'beta';
|
|
297
|
-
/**
|
|
298
|
-
* Produto SaaS publicado pelo Neetru Core.
|
|
299
|
-
*
|
|
300
|
-
* Schema neutro — alinhado com `public_products/{slug}` no backend mas
|
|
301
|
-
* nunca expõe campos internos (Firestore Timestamps, draft state, etc).
|
|
302
|
-
*/
|
|
303
|
-
interface Product {
|
|
304
|
-
/** Identificador estável do produto, ex: `neetru-pulse`. */
|
|
305
|
-
slug: string;
|
|
306
|
-
/** Nome de exibição, ex: `Neetru Pulse`. */
|
|
307
|
-
name: string;
|
|
308
|
-
/** Subtítulo curto, ex: `Gestão de operações`. */
|
|
309
|
-
tagline?: string;
|
|
310
|
-
/** Descrição longa em prosa. */
|
|
311
|
-
description?: string;
|
|
312
|
-
/** Status público do produto. */
|
|
313
|
-
status?: ProductStatus;
|
|
314
|
-
/** Hint de ícone (catálogo de keys interno do Core). */
|
|
315
|
-
iconKey?: string;
|
|
316
|
-
/** Link override do CTA principal (default: página do produto). */
|
|
317
|
-
ctaHref?: string;
|
|
318
|
-
/** Label override do CTA. */
|
|
319
|
-
ctaLabel?: string;
|
|
320
|
-
/** Lista opcional de planos cobrados. Pode ser preenchida v0.2+. */
|
|
321
|
-
plans?: ProductPlan[];
|
|
322
|
-
}
|
|
323
|
-
/** Plano cobrado de um produto (placeholder v0.1 — schema final v0.2). */
|
|
324
|
-
interface ProductPlan {
|
|
325
|
-
id: string;
|
|
326
|
-
name: string;
|
|
327
|
-
/** Preço mensal em centavos (BRL). Pode ser undefined em planos custom. */
|
|
328
|
-
amountCents?: number;
|
|
329
|
-
features?: string[];
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* Resposta do `client.catalog.list()`.
|
|
333
|
-
*/
|
|
334
|
-
interface CatalogListResponse {
|
|
335
|
-
products: Product[];
|
|
336
|
-
fetchedAt: string;
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Resposta do `client.entitlements.check(productSlug, feature)`.
|
|
340
|
-
*
|
|
341
|
-
* `allowed` é o sinal forte; `reason` ajuda a debugar (não exibir pro user
|
|
342
|
-
* final).
|
|
343
|
-
*/
|
|
344
|
-
interface EntitlementCheck {
|
|
345
|
-
allowed: boolean;
|
|
346
|
-
productSlug: string;
|
|
347
|
-
feature: string;
|
|
348
|
-
/** Reason code estável: `granted` | `not_subscribed` | `feature_not_in_plan` | `expired`. */
|
|
349
|
-
reason?: string;
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* Payload pra `client.telemetry.event()`.
|
|
353
|
-
*/
|
|
354
|
-
interface TelemetryEventInput {
|
|
355
|
-
/** Nome do evento, ex: `dashboard_opened`, `report_exported`. */
|
|
356
|
-
name: string;
|
|
357
|
-
/** Atributos adicionais (chave → valor primitivo). */
|
|
358
|
-
properties?: Record<string, string | number | boolean | null>;
|
|
359
|
-
/** Timestamp ISO opcional; default = server time. */
|
|
360
|
-
timestamp?: string;
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* Confirmação de aceitação do evento de telemetria.
|
|
364
|
-
*/
|
|
365
|
-
interface TelemetryEventAck {
|
|
366
|
-
ok: true;
|
|
367
|
-
/** ID gerado pelo backend pra evento (`usage_events/{id}`). */
|
|
368
|
-
eventId: string;
|
|
369
|
-
}
|
|
370
|
-
type TelemetryLogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
|
371
|
-
interface TelemetryLogInput {
|
|
372
|
-
level: TelemetryLogLevel;
|
|
373
|
-
message: string;
|
|
374
|
-
metadata?: Record<string, unknown>;
|
|
375
|
-
/** Override correlationId (default: lê dos headers/env automaticamente). */
|
|
376
|
-
correlationId?: string;
|
|
377
|
-
/** Slug do produto referenciado. Backend infere do escopo do token se ausente. */
|
|
378
|
-
productSlug?: string;
|
|
379
|
-
}
|
|
380
|
-
interface TelemetryLogAck {
|
|
381
|
-
ok: true;
|
|
382
|
-
/** ID do log gravado (`logs/{productId}/{yyyymmdd}/{logId}`) — opcional em mocks. */
|
|
383
|
-
logId?: string;
|
|
384
|
-
/** Indicador de modo (mock vs http). */
|
|
385
|
-
mode: 'mock' | 'http';
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Handle imutável retornado por `createNeetruClient`. Carrega namespaces
|
|
389
|
-
* `auth`, `catalog`, `entitlements`, `telemetry`, `usage`, `support`.
|
|
390
|
-
*
|
|
391
|
-
* Cada namespace é exposto como objeto chamável — espelha API Firebase
|
|
392
|
-
* (`auth`, `firestore`) ou Stripe (`paymentIntents`, `customers`).
|
|
393
|
-
*/
|
|
394
|
-
interface NeetruClient {
|
|
395
|
-
/** Configuração resolvida (apiKey, baseUrl, fetch). Read-only. */
|
|
396
|
-
readonly config: ResolvedConfig;
|
|
397
|
-
/** Namespace auth (v0.2 — OIDC + mocks dev). */
|
|
398
|
-
readonly auth: AuthNamespace;
|
|
399
|
-
/** Namespace catálogo público de produtos. */
|
|
400
|
-
readonly catalog: {
|
|
401
|
-
/** Lista produtos publicados. */
|
|
402
|
-
list(opts?: CatalogListOptions): Promise<CatalogListResponse>;
|
|
403
|
-
/** Busca produto único por slug. */
|
|
404
|
-
get(slug: string): Promise<Product>;
|
|
405
|
-
};
|
|
406
|
-
/** Namespace entitlements (v1.2: cache LRU 60s TTL). */
|
|
407
|
-
readonly entitlements: {
|
|
408
|
-
/**
|
|
409
|
-
* Verifica se o portador da apiKey pode usar `feature` do produto `slug`.
|
|
410
|
-
* Cacheado 60s. `{ cacheBust: true }` força ida ao servidor.
|
|
411
|
-
*/
|
|
412
|
-
check(productSlug: string, feature: string, opts?: {
|
|
413
|
-
cacheBust?: boolean;
|
|
414
|
-
}): Promise<boolean>;
|
|
415
|
-
/** Variante que retorna o objeto completo com `reason`. */
|
|
416
|
-
checkDetailed(productSlug: string, feature: string, opts?: {
|
|
417
|
-
cacheBust?: boolean;
|
|
418
|
-
}): Promise<EntitlementCheck>;
|
|
419
|
-
};
|
|
420
|
-
/** Namespace telemetria (v1.2: track fire-and-forget + flush). */
|
|
421
|
-
readonly telemetry: {
|
|
422
|
-
/** Persiste um evento single-shot. await retorna { ok, eventId }. */
|
|
423
|
-
event(input: TelemetryEventInput): Promise<TelemetryEventAck>;
|
|
424
|
-
/** Fire-and-forget: enqueue + flush 500ms debounce. Sem retorno. */
|
|
425
|
-
track(input: TelemetryEventInput): void;
|
|
426
|
-
/** Força flush da queue do track() (chamar antes de unload). */
|
|
427
|
-
flush(): Promise<void>;
|
|
428
|
-
/**
|
|
429
|
-
* Registra um log estruturado per-product (Sprint 6).
|
|
430
|
-
*
|
|
431
|
-
* - Em `NEETRU_ENV=dev`: apenas console.{level} (sem network).
|
|
432
|
-
* - Em `workspace`/`prod`: POST `/api/sdk/v1/telemetry/log` com Bearer + correlationId.
|
|
433
|
-
*/
|
|
434
|
-
log(input: TelemetryLogInput): Promise<TelemetryLogAck>;
|
|
435
|
-
};
|
|
436
|
-
/** Namespace usage (v0.2 — track + quota; v0.3 — report + check). */
|
|
437
|
-
readonly usage: UsageNamespace;
|
|
438
|
-
/** Namespace support (v0.2 — tickets). */
|
|
439
|
-
readonly support: SupportNamespace;
|
|
440
|
-
/** Namespace db (v0.3 — coleções tenant-scoped). */
|
|
441
|
-
readonly db: DbNamespace;
|
|
442
|
-
/** Namespace checkout (v1.1 — start/get/cancel intent + auto-redirect). */
|
|
443
|
-
readonly checkout: CheckoutNamespace;
|
|
444
|
-
/** Namespace webhooks (v1.2 — register/list/unregister/test). */
|
|
445
|
-
readonly webhooks: WebhooksNamespace;
|
|
446
|
-
/** Namespace notifications (v1.2 — send/list/markRead/dismiss). */
|
|
447
|
-
readonly notifications: NotificationsNamespace;
|
|
448
|
-
}
|
|
449
|
-
/**
|
|
450
|
-
* User retornado pelo OIDC ID token. Schema neutro — não vaza Firebase
|
|
451
|
-
* decoded token shape. Subset estável do RFC 7519 + custom claims Neetru.
|
|
452
|
-
*/
|
|
453
|
-
interface NeetruUser {
|
|
454
|
-
/** Subject — uid estável. */
|
|
455
|
-
uid: string;
|
|
456
|
-
email: string;
|
|
457
|
-
emailVerified?: boolean;
|
|
458
|
-
displayName?: string;
|
|
459
|
-
photoURL?: string;
|
|
460
|
-
/** Custom claim Neetru — true quando staff. */
|
|
461
|
-
isStaff?: boolean;
|
|
462
|
-
/** Custom claim Neetru — true quando customer enrolled. */
|
|
463
|
-
isCustomer?: boolean;
|
|
464
|
-
/** Tenant assigned (multi-tenant deployments). */
|
|
465
|
-
tenantId?: string;
|
|
466
|
-
/** Outros claims OIDC (aud, iss, iat, exp). */
|
|
467
|
-
[extra: string]: unknown;
|
|
468
|
-
}
|
|
469
|
-
interface SignInOptions {
|
|
470
|
-
/** OIDC redirect_uri override. Default = window.location origin. */
|
|
471
|
-
redirectUri?: string;
|
|
472
|
-
/** OIDC scope. Default `openid profile email`. */
|
|
473
|
-
scope?: string;
|
|
474
|
-
/** Onde mandar após login completo. Default = window.location.href. */
|
|
475
|
-
postLoginRedirect?: string;
|
|
476
|
-
}
|
|
477
|
-
type AuthStateListener = (user: NeetruUser | null) => void;
|
|
478
|
-
interface AuthNamespace {
|
|
479
|
-
/**
|
|
480
|
-
* Inicia fluxo de login OIDC. Em dev (`NEETRU_ENV=dev`) retorna mock user
|
|
481
|
-
* direto sem redirect. Em prod redireciona pro authorize endpoint.
|
|
482
|
-
*/
|
|
483
|
-
signIn(options?: SignInOptions): Promise<NeetruUser | void>;
|
|
484
|
-
/** Limpa session local + revoga refresh token no servidor. */
|
|
485
|
-
signOut(): Promise<void>;
|
|
486
|
-
/** Retorna o user atual (do id_token cached) ou `null` se não logado. */
|
|
487
|
-
getUser(): NeetruUser | null;
|
|
488
|
-
/**
|
|
489
|
-
* Subscreve a mudanças de estado de auth. Listener é invocado imediatamente
|
|
490
|
-
* com user atual. Retorna função de unsubscribe.
|
|
491
|
-
*/
|
|
492
|
-
onAuthStateChanged(listener: AuthStateListener): () => void;
|
|
493
|
-
}
|
|
494
|
-
interface UsageEventInput {
|
|
495
|
-
/** Nome do evento, ex: `report_generated`, `api_call`. */
|
|
496
|
-
event: string;
|
|
497
|
-
/** Atributos do evento. Valores primitivos serializáveis. */
|
|
498
|
-
properties?: Record<string, string | number | boolean | null>;
|
|
499
|
-
/** Quantidade — default 1 (1 evento). Útil pra batch. */
|
|
500
|
-
quantity?: number;
|
|
501
|
-
}
|
|
502
|
-
interface UsageQuota {
|
|
503
|
-
metric: string;
|
|
504
|
-
/** Quantidade já consumida no período. */
|
|
505
|
-
used: number;
|
|
506
|
-
/** Limite total. -1 = unlimited. */
|
|
507
|
-
limit: number;
|
|
508
|
-
/** ISO timestamp do reset (próximo período). */
|
|
509
|
-
resetsAt?: string;
|
|
510
|
-
/** Plano que define o limite. */
|
|
511
|
-
plan?: string;
|
|
512
|
-
}
|
|
513
|
-
interface UsageNamespace {
|
|
514
|
-
/** Persiste um evento de uso. Mock em dev, POST `/sdk/v1/usage/record` em prod. */
|
|
515
|
-
track(event: string, props?: UsageEventInput['properties']): Promise<{
|
|
516
|
-
ok: true;
|
|
517
|
-
}>;
|
|
518
|
-
/** Lê quota atual de uma métrica. Mock em dev, GET `/sdk/v1/usage/quota` em prod. */
|
|
519
|
-
getQuota(metric: string): Promise<UsageQuota>;
|
|
520
|
-
/**
|
|
521
|
-
* v0.3 — Reporta consumo de um resource metered (POST /sdk/v1/usage/record
|
|
522
|
-
* com `{productId, tenantId, resource, qty}`). Em dev acumula no mock.
|
|
523
|
-
*
|
|
524
|
-
* Diferente de `track()`: usa o endpoint canônico Sprint 7 que incrementa
|
|
525
|
-
* `usage_counters/{tenantId}_{productId}_{resource}_{yyyymm}` atomicamente.
|
|
526
|
-
*
|
|
527
|
-
* `productId`/`tenantId` são lidos do contexto resolvido do client se
|
|
528
|
-
* ausentes nas options.
|
|
529
|
-
*/
|
|
530
|
-
report(resource: string, qty?: number, options?: {
|
|
531
|
-
productId?: string;
|
|
532
|
-
tenantId?: string;
|
|
533
|
-
}): Promise<{
|
|
534
|
-
ok: true;
|
|
535
|
-
counterId?: string;
|
|
536
|
-
value?: number;
|
|
537
|
-
limit?: number;
|
|
538
|
-
remaining?: number;
|
|
539
|
-
status?: string;
|
|
540
|
-
}>;
|
|
541
|
-
/**
|
|
542
|
-
* v0.3 — Verifica entitlement de um resource/feature. Wrapper em
|
|
543
|
-
* GET /sdk/v1/entitlements. Em dev consulta MockEntitlements + MockUsage.
|
|
544
|
-
*/
|
|
545
|
-
check(resource: string, options?: {
|
|
546
|
-
productId?: string;
|
|
547
|
-
tenantId?: string;
|
|
548
|
-
}): Promise<{
|
|
549
|
-
allowed: boolean;
|
|
550
|
-
reason?: string;
|
|
551
|
-
remaining?: number;
|
|
552
|
-
limit?: number;
|
|
553
|
-
planId?: string | null;
|
|
554
|
-
planFeatures?: string[];
|
|
555
|
-
}>;
|
|
556
|
-
}
|
|
557
|
-
/**
|
|
558
|
-
* Namespace `db` (v0.3) — wrapper minimalista para CRUD em coleções tenant-scoped
|
|
559
|
-
* via Core REST. Em dev retorna fixtures in-memory por collection.
|
|
560
|
-
*
|
|
561
|
-
* O Core injeta automaticamente o tenantId no path do Firestore:
|
|
562
|
-
* `tenant_{tid}_{name}/{docId}`.
|
|
563
|
-
*/
|
|
564
|
-
/** Filtro `where` simples — alinhado com endpoint REST `field:op:value`. */
|
|
565
|
-
interface DbWhereFilter {
|
|
566
|
-
field: string;
|
|
567
|
-
op: '==' | '!=' | '<' | '<=' | '>' | '>=' | 'in';
|
|
568
|
-
value: string | number | boolean | null | Array<string | number | boolean>;
|
|
569
|
-
}
|
|
570
|
-
interface DbListOptions {
|
|
571
|
-
limit?: number;
|
|
572
|
-
/** Lista de filtros — máximo 5 (alinhado ao backend). */
|
|
573
|
-
where?: DbWhereFilter[];
|
|
574
|
-
}
|
|
575
|
-
interface DbCollectionRef {
|
|
576
|
-
/** Lista documentos com filtros opcionais. */
|
|
577
|
-
list<T = Record<string, unknown>>(opts?: DbListOptions): Promise<T[]>;
|
|
578
|
-
/** Lê um documento por id. Retorna `null` se não existe. */
|
|
579
|
-
get<T = Record<string, unknown>>(id: string): Promise<T | null>;
|
|
580
|
-
/** Cria/upsert um documento com id explícito. */
|
|
581
|
-
set(id: string, data: Record<string, unknown>): Promise<{
|
|
582
|
-
ok: true;
|
|
583
|
-
}>;
|
|
584
|
-
/**
|
|
585
|
-
* v0.3.1 — Adiciona doc com id auto-gerado pelo backend. Retorna `{id}` do
|
|
586
|
-
* doc criado. Diferente de `set(id, data)` que requer caller fornecer id.
|
|
587
|
-
*/
|
|
588
|
-
add(data: Record<string, unknown>): Promise<{
|
|
589
|
-
ok: true;
|
|
590
|
-
id: string;
|
|
591
|
-
}>;
|
|
592
|
-
/** Atualiza doc com merge — só campos passados em `data`. */
|
|
593
|
-
update(id: string, data: Record<string, unknown>): Promise<{
|
|
594
|
-
ok: true;
|
|
595
|
-
}>;
|
|
596
|
-
/** Deleta um documento. */
|
|
597
|
-
remove(id: string): Promise<{
|
|
598
|
-
ok: true;
|
|
599
|
-
}>;
|
|
600
|
-
}
|
|
601
|
-
interface DbNamespace {
|
|
602
|
-
collection(name: string): DbCollectionRef;
|
|
603
|
-
}
|
|
604
|
-
type SupportSeverity = 'low' | 'normal' | 'high' | 'urgent';
|
|
605
|
-
type SupportStatus = 'open' | 'pending' | 'resolved' | 'closed';
|
|
606
|
-
interface SupportTicket {
|
|
607
|
-
id: string;
|
|
608
|
-
subject: string;
|
|
609
|
-
message: string;
|
|
610
|
-
severity: SupportSeverity;
|
|
611
|
-
status: SupportStatus;
|
|
612
|
-
createdAt: string;
|
|
613
|
-
updatedAt?: string;
|
|
614
|
-
/** Slug do produto referenciado. */
|
|
615
|
-
productSlug?: string;
|
|
616
|
-
}
|
|
617
|
-
interface CreateTicketInput {
|
|
618
|
-
subject: string;
|
|
619
|
-
message: string;
|
|
620
|
-
severity?: SupportSeverity;
|
|
621
|
-
productSlug?: string;
|
|
622
|
-
}
|
|
623
|
-
interface SupportNamespace {
|
|
624
|
-
/** Cria um novo ticket. Mock em dev, POST `/api/v1/products/{slug}/tickets` em prod. */
|
|
625
|
-
createTicket(input: CreateTicketInput): Promise<SupportTicket>;
|
|
626
|
-
/** Lista meus tickets abertos. */
|
|
627
|
-
listMyTickets(): Promise<SupportTicket[]>;
|
|
628
|
-
}
|
|
629
|
-
/**
|
|
630
|
-
* Modo do SDK. `dev` ativa mocks automáticos (úteis pra testes e
|
|
631
|
-
* desenvolvimento sem precisar de backend rodando).
|
|
632
|
-
*/
|
|
633
|
-
type NeetruEnv = 'dev' | 'workspace' | 'prod';
|
|
634
|
-
/**
|
|
635
|
-
* Configuração resolvida (defaults aplicados, fetch garantido).
|
|
636
|
-
*/
|
|
637
|
-
interface ResolvedConfig {
|
|
638
|
-
readonly apiKey?: string;
|
|
639
|
-
readonly baseUrl: string;
|
|
640
|
-
readonly fetch: typeof globalThis.fetch;
|
|
641
|
-
/** Resolved env — `dev` | `workspace` | `prod`. Default `prod`. */
|
|
642
|
-
readonly env: NeetruEnv;
|
|
643
|
-
/** Default productId (v0.3). */
|
|
644
|
-
readonly productId?: string;
|
|
645
|
-
/** Default tenantId (v0.3). */
|
|
646
|
-
readonly tenantId?: string;
|
|
647
|
-
}
|
|
648
|
-
/** Opções pra `catalog.list()`. */
|
|
649
|
-
interface CatalogListOptions {
|
|
650
|
-
/** Inclui rascunhos (apenas com Bearer staff). Default false. */
|
|
651
|
-
includeDrafts?: boolean;
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
export { verifyWebhookSignature as $, type AuthNamespace as A, type SupportSeverity as B, type CatalogListOptions as C, DEFAULT_BASE_URL as D, type EntitlementCheck as E, type SupportStatus as F, type SupportTicket as G, type TelemetryEventInput as H, type UsageNamespace as I, type UsageQuota as J, type WebhookEvent as K, type ListNotificationsOptions as L, MockCheckout as M, type NeetruClientConfig as N, type WebhookTestResult as O, type Product as P, type WebhooksNamespace as Q, type RegisterWebhookInput as R, type SendNotificationInput as S, type TelemetryEventAck as T, type UsageEventInput as U, createCheckoutNamespace as V, type WebhookEndpoint as W, createNotificationsNamespace as X, createWebhooksNamespace as Y, type TelemetryLogInput as Z, type TelemetryLogAck as _, type NeetruClient as a, type AuthStateListener as b, type CatalogListResponse as c, type CheckoutIntentInfo as d, type CheckoutIntentStatus as e, type CheckoutNamespace as f, type CheckoutStartInput as g, type CheckoutStartResult as h, type CheckoutTenantType as i, type CreateTicketInput as j, type DbCollectionRef as k, type DbListOptions as l, type DbNamespace as m, type DbWhereFilter as n, MockNotifications as o, MockWebhooks as p, type NeetruEnv as q, type NeetruUser as r, type NotificationsNamespace as s, type ProductNotification as t, type ProductNotificationSeverity as u, type ProductPlan as v, type ProductStatus as w, type ResolvedConfig as x, type SignInOptions as y, type SupportNamespace as z };
|