@neetru/sdk 1.1.0 → 1.2.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 +33 -3
- package/README.md +135 -159
- package/dist/auth.cjs +486 -40
- 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 +486 -40
- package/dist/auth.mjs.map +1 -1
- package/dist/catalog.cjs +64 -21
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +2 -2
- package/dist/catalog.d.ts +2 -2
- package/dist/catalog.mjs +64 -21
- package/dist/catalog.mjs.map +1 -1
- package/dist/checkout.cjs +61 -15
- 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 +61 -15
- package/dist/checkout.mjs.map +1 -1
- package/dist/db.cjs +67 -22
- 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 +67 -22
- package/dist/db.mjs.map +1 -1
- package/dist/entitlements.cjs +102 -21
- package/dist/entitlements.cjs.map +1 -1
- package/dist/entitlements.d.cts +11 -5
- package/dist/entitlements.d.ts +11 -5
- package/dist/entitlements.mjs +102 -21
- package/dist/entitlements.mjs.map +1 -1
- package/dist/index.cjs +491 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +488 -42
- package/dist/index.mjs.map +1 -1
- package/dist/mocks.cjs +3 -2
- package/dist/mocks.cjs.map +1 -1
- package/dist/mocks.d.cts +4 -2
- package/dist/mocks.d.ts +4 -2
- package/dist/mocks.mjs +3 -2
- package/dist/mocks.mjs.map +1 -1
- package/dist/notifications.cjs +296 -0
- package/dist/notifications.cjs.map +1 -0
- package/dist/notifications.d.cts +1 -0
- package/dist/notifications.d.ts +1 -0
- package/dist/notifications.mjs +293 -0
- package/dist/notifications.mjs.map +1 -0
- package/dist/react.cjs +7 -3
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.mjs +7 -3
- package/dist/react.mjs.map +1 -1
- package/dist/support.cjs +61 -15
- 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 +61 -15
- package/dist/support.mjs.map +1 -1
- package/dist/telemetry.cjs +131 -16
- package/dist/telemetry.cjs.map +1 -1
- package/dist/telemetry.d.cts +17 -1
- package/dist/telemetry.d.ts +17 -1
- package/dist/telemetry.mjs +131 -16
- package/dist/telemetry.mjs.map +1 -1
- package/dist/{types-BA53dd8S.d.cts → types-CQAfwqUS.d.cts} +172 -8
- package/dist/{types-BA53dd8S.d.ts → types-CQAfwqUS.d.ts} +172 -8
- package/dist/usage.cjs +61 -15
- 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 +61 -15
- package/dist/usage.mjs.map +1 -1
- package/dist/webhooks.cjs +316 -0
- package/dist/webhooks.cjs.map +1 -0
- package/dist/webhooks.d.cts +1 -0
- package/dist/webhooks.d.ts +1 -0
- package/dist/webhooks.mjs +312 -0
- package/dist/webhooks.mjs.map +1 -0
- package/package.json +22 -6
package/CHANGELOG.md
CHANGED
|
@@ -7,11 +7,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
### Planned (post-1.
|
|
11
|
-
- Telemetry batching + flush on unload.
|
|
12
|
-
- LRU cache em entitlements.check (TTL configurável).
|
|
10
|
+
### Planned (post-1.2)
|
|
13
11
|
- size-limit budget no CI (<12KB gz core com db namespace).
|
|
14
12
|
- CDN distribution (`cdn.neetru.com/sdk/v1/`).
|
|
13
|
+
- Endpoint batch `/api/v1/sdk/telemetry/batch` (substitui drenagem N×1 do `track()` por 1 request).
|
|
14
|
+
|
|
15
|
+
## [1.2.0] - 2026-05-19 — **Webhooks + Notifications + DX (cache, retry, batch)**
|
|
16
|
+
|
|
17
|
+
Release de qualidade fechando 3 CRITICAL + 6 IMPORTANT do code review interno + 4 melhorias de DX. Adiciona `webhooks` + `notifications` no `NeetruClient`.
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- **`client.webhooks`** — `register`/`list`/`unregister`/`test` pra endpoints HTTP do produto receberem eventos do Core (subscription.activated, usage.quota_exceeded, etc).
|
|
21
|
+
- **`verifyWebhookSignature(payload, signature, secret)`** — util pura (HMAC SHA-256 constant-time compare via `node:crypto`) pra consumidor validar payloads recebidos.
|
|
22
|
+
- **`client.notifications`** — `send`/`list`/`markRead`/`dismiss` pra produto integrar com a bandeja in-app do Neetru.
|
|
23
|
+
- **`client.telemetry.track(input)`** + `client.telemetry.flush()` — fire-and-forget batch (500ms debounce). Ideal pra alta frequência (page-views, cliques). `event()` segue como single-shot com `eventId` ack.
|
|
24
|
+
- **`client.entitlements.check(..., { cacheBust })`** — cache LRU em memória (60s TTL, 100 entries). Corta 90%+ requests em renders repetidos do `<EntitlementGate>`. `cacheBust: true` força ida ao servidor.
|
|
25
|
+
- **httpRequest retry/backoff** — 2 retries default em `rate_limited` (429), `server_error` (5xx), `network_error`. Honra `Retry-After` header. Caller opt-out com `opts.retries: 0`.
|
|
26
|
+
- **Subpaths novos**: `@neetru/sdk/webhooks`, `@neetru/sdk/notifications`.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- **`client.catalog.list()` / `get()`** agora consomem `/api/sdk/v1/catalog` (público, sem Bearer) em vez de `/api/v1/cli/catalog` (staff). Consumidor não precisa mais de chave staff só pra ler catálogo. `includeDrafts` é ignorado — rascunhos só via CLI.
|
|
30
|
+
- **`auth.signOut()`** revoga token em `auth.neetru.com/api/v1/oauth/revoke` (canônico), não mais `api.neetru.com/oauth/revoke` (404 em prod).
|
|
31
|
+
- **`<EntitlementGate>`** passa `tenantId` (do `client.config.tenantId`) pra `usage.check`. Sem tenantId, cai pra `entitlements.check` em vez de chamar `usage.check` e travar em `validation_failed` silencioso.
|
|
32
|
+
- **`engines.node`** subiu pra `>=20` (alinha com `target: node20` do tsup; Node 18 EOL).
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
- **CRITICAL** — `webhooks` e `notifications` lançavam `'invalid_input'`, código ausente da union `NeetruErrorCode`. Todas as 17 ocorrências viraram `'validation_failed'`.
|
|
36
|
+
- **CRITICAL** — `telemetry.log()` chamava `/sdk/v1/telemetry/log` (404). Corrigido pra `/api/sdk/v1/telemetry/log`.
|
|
37
|
+
- **CRITICAL** — `db` namespace tinha o mesmo bug em 6 paths (`/sdk/v1/datastore/...`). Corrigido em massa pra `/api/sdk/v1/datastore/...`.
|
|
38
|
+
- **CRITICAL** — 8 `httpRequest` calls em `webhooks` e `notifications` não passavam `requireAuth: true` — todos hits em prod retornavam 401. Corrigido.
|
|
39
|
+
- **`MockSupport.mockTicketSeq`** virou instance field (era module-level, poluía tests entre suites).
|
|
40
|
+
- **`db.list()`** removeu variável `query` dead code (refactor incompleto de pre-1.1).
|
|
41
|
+
|
|
42
|
+
### Internal
|
|
43
|
+
- 51 testes novos (webhooks: 22, notifications: 20, react: 9). Total: 215 testes (16 files), 100% passing. tsc clean.
|
|
44
|
+
- `api-surface-stability.test.ts` agora lock `webhooks` + `notifications` no `NeetruClient`.
|
|
15
45
|
|
|
16
46
|
## [1.1.0] - 2026-05-08 — **Checkout namespace + React helpers**
|
|
17
47
|
|
package/README.md
CHANGED
|
@@ -1,218 +1,194 @@
|
|
|
1
1
|
# @neetru/sdk
|
|
2
2
|
|
|
3
|
-
Biblioteca runtime
|
|
4
|
-
produtos, entitlements de tenant e telemetria — de qualquer
|
|
5
|
-
JavaScript/TypeScript moderno (browser, Node ≥20, Edge runtimes).
|
|
3
|
+
> Biblioteca runtime oficial pra consumir o ecossistema Neetru a partir de produtos SaaS (Next.js, Node, browser, Edge runtimes).
|
|
6
4
|
|
|
7
|
-
>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
<p>
|
|
6
|
+
<img alt="npm" src="https://img.shields.io/npm/v/@neetru/sdk?logo=npm">
|
|
7
|
+
<img alt="downloads" src="https://img.shields.io/npm/dm/@neetru/sdk?logo=npm">
|
|
8
|
+
<img alt="bundle size" src="https://img.shields.io/bundlephobia/minzip/@neetru/sdk">
|
|
9
|
+
<img alt="Node" src="https://img.shields.io/badge/node-%3E%3D18-339933?logo=node.js&logoColor=white">
|
|
10
|
+
<img alt="license" src="https://img.shields.io/badge/license-MIT-22c55e">
|
|
11
|
+
</p>
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
## Princípios
|
|
15
|
-
|
|
16
|
-
- **Vendor-neutral** — apesar do Core usar Firebase, a superfície pública do
|
|
17
|
-
SDK não vaza isso (sem `firebase/app` exposto).
|
|
18
|
-
- **TypeScript-first** — `.d.ts` shipped, JSDoc em toda função pública.
|
|
19
|
-
- **Tree-shakable** — ESM-first, `"sideEffects": false`. Subpath imports
|
|
20
|
-
permitidos (`@neetru/sdk/catalog`, `@neetru/sdk/telemetry`, etc).
|
|
21
|
-
- **Universal** — usa `fetch` global. Sem `node:` builtins no core.
|
|
22
|
-
- **Erros tipados** — todos erros são `NeetruError` com `.code`, `.status`,
|
|
23
|
-
`.requestId`.
|
|
24
|
-
- **Semver estrito** — pós v1.0, breaking changes só em majors.
|
|
25
|
-
|
|
26
|
-
## Install
|
|
13
|
+
## Instalação
|
|
27
14
|
|
|
28
15
|
```bash
|
|
29
16
|
npm install @neetru/sdk
|
|
30
17
|
```
|
|
31
18
|
|
|
32
|
-
|
|
33
|
-
> Reservar é responsabilidade do owner em Sprint 6 do plano.
|
|
34
|
-
|
|
35
|
-
## Quick start
|
|
19
|
+
## Hello world
|
|
36
20
|
|
|
37
21
|
```ts
|
|
38
|
-
import { createNeetruClient
|
|
22
|
+
import { createNeetruClient } from '@neetru/sdk';
|
|
39
23
|
|
|
40
|
-
const
|
|
41
|
-
apiKey: process.env.NEETRU_API_KEY,
|
|
42
|
-
|
|
24
|
+
const neetru = createNeetruClient({
|
|
25
|
+
apiKey: process.env.NEETRU_API_KEY, // nrt_<keyId>_<secret>
|
|
26
|
+
env: 'prod', // 'dev' = mocks in-memory
|
|
43
27
|
});
|
|
44
28
|
|
|
45
|
-
//
|
|
46
|
-
const
|
|
47
|
-
console.log(
|
|
48
|
-
|
|
49
|
-
const product = await client.catalog.get('neetru-pulse');
|
|
50
|
-
|
|
51
|
-
// 2. Entitlements — pode o caller usar a feature `export-pdf` do produto?
|
|
52
|
-
const allowed = await client.entitlements.check('neetru-pulse', 'export-pdf');
|
|
53
|
-
if (!allowed) showUpgradeBanner();
|
|
29
|
+
// Auth
|
|
30
|
+
const user = await neetru.auth.signIn();
|
|
31
|
+
console.log('logado como:', user?.email);
|
|
54
32
|
|
|
55
|
-
//
|
|
56
|
-
await
|
|
57
|
-
|
|
58
|
-
properties: { format: 'pdf', plan: 'pro' },
|
|
59
|
-
});
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Discriminação de erro:
|
|
63
|
-
|
|
64
|
-
```ts
|
|
65
|
-
try {
|
|
66
|
-
await client.catalog.list();
|
|
67
|
-
} catch (err) {
|
|
68
|
-
if (err instanceof NeetruError) {
|
|
69
|
-
if (err.code === 'rate_limited') retry();
|
|
70
|
-
if (err.code === 'unauthorized') promptLogin();
|
|
71
|
-
console.error(err.code, err.message, err.status, err.requestId);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
33
|
+
// Entitlement check
|
|
34
|
+
const canAi = await neetru.entitlements.check('gestovendas', 'ai_recommendations');
|
|
35
|
+
if (canAi) { /* mostrar feature */ }
|
|
74
36
|
```
|
|
75
37
|
|
|
76
|
-
##
|
|
38
|
+
## Princípios
|
|
77
39
|
|
|
78
|
-
|
|
40
|
+
- **Vendor-neutral** — superfície pública NÃO vaza Firebase/Stripe/etc. Backend Neetru pode mudar no futuro sem reescrever produto.
|
|
41
|
+
- **Tree-shakable** — ESM-first, sem side-effects. Importe só os namespaces que usa.
|
|
42
|
+
- **Universal** — browser, Node ≥18, Edge runtimes (Vercel Edge, Cloudflare Workers). Usa `fetch` global.
|
|
43
|
+
- **Tipado** — erros via `NeetruError` com `.code`, `.status`, `.requestId`.
|
|
44
|
+
- **Dev mode** — `NEETRU_ENV=dev` ativa mocks automáticos — zero rede em testes locais.
|
|
79
45
|
|
|
80
|
-
|
|
81
|
-
|---|---|---|
|
|
82
|
-
| `apiKey` | `string?` | Bearer token `nrt_<keyId>_<secret>`. Default lê `process.env.NEETRU_API_KEY` em Node. |
|
|
83
|
-
| `baseUrl` | `string?` | URL base. Default `https://api.neetru.com`. |
|
|
84
|
-
| `fetch` | `typeof fetch?` | Implementação custom. Default `globalThis.fetch`. |
|
|
85
|
-
| `env` | `'dev' \| 'workspace' \| 'prod'?` | Ativa mocks automáticos em `dev`. Default `prod` (lê `NEETRU_ENV`). |
|
|
86
|
-
| `mocks` | `{ auth?, usage?, support?, entitlements? }?` | Override de namespaces — útil em tests do consumer. |
|
|
46
|
+
## Namespaces v1.2
|
|
87
47
|
|
|
88
|
-
|
|
48
|
+
| Namespace | O que oferece |
|
|
49
|
+
|---|---|
|
|
50
|
+
| `auth` | OIDC sign-in / sign-out + dev fixture user |
|
|
51
|
+
| `catalog` | Produtos públicos (`list` / `get`) |
|
|
52
|
+
| `entitlements` | Verificação `(productSlug, feature)` → boolean ou detalhado |
|
|
53
|
+
| `telemetry` | `event(...)` + `log(...)` per-product |
|
|
54
|
+
| `usage` | `track` / `getQuota` / `report` / `check` (metering canônico) |
|
|
55
|
+
| `support` | `createTicket` / `listMyTickets` |
|
|
56
|
+
| `db` | Coleções tenant-scoped (`list` / `get` / `set` / `add` / `update` / `remove`) |
|
|
57
|
+
| `checkout` | Stripe Checkout intent (`start` / `get` / `cancel` + auto-redirect) |
|
|
58
|
+
| `webhooks` ⭐ v1.2 | Produtos registram URL pra receber eventos Core (subscription.activated, usage.quota_exceeded, etc) |
|
|
59
|
+
| `notifications` ⭐ v1.2 | Produto envia notification in-app pros SEUS usuários (distinto das staff-only do Core) |
|
|
89
60
|
|
|
90
|
-
|
|
61
|
+
## Exemplos por namespace
|
|
91
62
|
|
|
92
|
-
|
|
93
|
-
|---|---|
|
|
94
|
-
| `signIn(options?)` | Redireciona pro authorize endpoint (browser) ou retorna fixture user (dev). |
|
|
95
|
-
| `signOut()` | Limpa session local + revoga refresh server-side. |
|
|
96
|
-
| `getUser()` | Retorna `NeetruUser` cached do id_token ou `null`. |
|
|
97
|
-
| `onAuthStateChanged(listener)` | Sub a mudanças. Dispatch sync no subscribe. Retorna unsubscribe. |
|
|
63
|
+
### Webhooks outbound (v1.2)
|
|
98
64
|
|
|
99
|
-
|
|
65
|
+
```ts
|
|
66
|
+
await neetru.webhooks.register({
|
|
67
|
+
url: 'https://meu-produto.com/webhooks/neetru',
|
|
68
|
+
events: ['subscription.activated', 'subscription.cancelled', 'usage.quota_exceeded'],
|
|
69
|
+
secret: 'chave-32-chars-pra-hmac-sha256',
|
|
70
|
+
});
|
|
100
71
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
72
|
+
const endpoints = await neetru.webhooks.list();
|
|
73
|
+
const test = await neetru.webhooks.test(endpoints[0].id);
|
|
74
|
+
console.log(test.statusCode, test.durationMs);
|
|
75
|
+
```
|
|
105
76
|
|
|
106
|
-
|
|
77
|
+
Eventos recebidos no seu endpoint chegam com:
|
|
78
|
+
- `X-Neetru-Signature: sha256=<hmac>` (se `secret` registrado)
|
|
79
|
+
- `X-Neetru-Timestamp: <ms>` (replay protection — rejeitar > 5min skew)
|
|
107
80
|
|
|
108
|
-
|
|
109
|
-
|---|---|
|
|
110
|
-
| `check(slug, feature)` | `boolean`. Atalho do `checkDetailed`. |
|
|
111
|
-
| `checkDetailed(slug, feature)` | `EntitlementCheck` com `allowed`, `reason`. |
|
|
81
|
+
### Notifications produto → user (v1.2)
|
|
112
82
|
|
|
113
|
-
|
|
83
|
+
```ts
|
|
84
|
+
await neetru.notifications.send({
|
|
85
|
+
userId: 'usr_xyz',
|
|
86
|
+
kind: 'order.received',
|
|
87
|
+
severity: 'success',
|
|
88
|
+
title: 'Novo pedido #1234',
|
|
89
|
+
body: 'Pedido de R$ 89,90',
|
|
90
|
+
link: '/orders/1234',
|
|
91
|
+
fingerprint: 'order:1234', // dedup < 24h
|
|
92
|
+
});
|
|
114
93
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
94
|
+
const notifs = await neetru.notifications.list('usr_xyz', { onlyUnread: true });
|
|
95
|
+
await neetru.notifications.markRead(notifs[0].id);
|
|
96
|
+
```
|
|
118
97
|
|
|
119
|
-
###
|
|
98
|
+
### Entitlements
|
|
120
99
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
100
|
+
```ts
|
|
101
|
+
const ok = await neetru.entitlements.check('gestovendas', 'ai_recommendations');
|
|
102
|
+
const detailed = await neetru.entitlements.detailed('gestovendas', 'ai_recommendations');
|
|
103
|
+
// → { allowed, planId, remaining?, limit?, reason }
|
|
104
|
+
```
|
|
125
105
|
|
|
126
|
-
###
|
|
106
|
+
### Usage tracking
|
|
127
107
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
| `createTicket({subject, message, severity?, productSlug?})` | `POST /api/v1/products/{slug}/tickets`. |
|
|
131
|
-
| `listMyTickets()` | `GET /api/v1/products/_default/tickets`. |
|
|
108
|
+
```ts
|
|
109
|
+
await neetru.usage.track('report_generated', { count: 42, format: 'pdf' });
|
|
132
110
|
|
|
133
|
-
|
|
111
|
+
const quota = await neetru.usage.getQuota('reports_per_month');
|
|
112
|
+
// → { used: 15, limit: 100, resetsAt: '...', plan: 'starter' }
|
|
113
|
+
```
|
|
134
114
|
|
|
135
|
-
|
|
115
|
+
### Support
|
|
136
116
|
|
|
137
117
|
```ts
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
auth: new MockAuth({ uid: 'fake', email: 'fake@x.com' }),
|
|
143
|
-
usage: new MockUsage(),
|
|
144
|
-
support: new MockSupport(),
|
|
145
|
-
},
|
|
118
|
+
await neetru.support.createTicket({
|
|
119
|
+
subject: 'Bug ao exportar CSV',
|
|
120
|
+
message: 'Quando seleciono >1000 rows o export falha',
|
|
121
|
+
severity: 'high',
|
|
146
122
|
});
|
|
123
|
+
|
|
124
|
+
const myTickets = await neetru.support.listMyTickets({ status: 'open' });
|
|
147
125
|
```
|
|
148
126
|
|
|
149
|
-
###
|
|
127
|
+
### DB (tenant-scoped, vendor-neutral)
|
|
150
128
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
129
|
+
```ts
|
|
130
|
+
await neetru.db.add('orders', { customerId: 'usr_x', total: 9990 });
|
|
131
|
+
const orders = await neetru.db.list('orders', {
|
|
132
|
+
where: [['customerId', '==', 'usr_x']],
|
|
133
|
+
orderBy: 'createdAt',
|
|
134
|
+
limit: 50,
|
|
135
|
+
});
|
|
136
|
+
```
|
|
154
137
|
|
|
155
|
-
|
|
138
|
+
### Checkout
|
|
156
139
|
|
|
157
140
|
```ts
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
141
|
+
const intent = await neetru.checkout.start({
|
|
142
|
+
productId: 'gestovendas',
|
|
143
|
+
planId: 'pro',
|
|
144
|
+
tenantType: 'company',
|
|
145
|
+
tenantId: 'company_xyz',
|
|
146
|
+
});
|
|
147
|
+
window.location.href = intent.checkoutUrl;
|
|
163
148
|
```
|
|
164
149
|
|
|
165
|
-
##
|
|
150
|
+
## Modo dev (mocks automáticos)
|
|
166
151
|
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
npm run lint # tsc --noEmit
|
|
171
|
-
npm run test # vitest run (Sprint 2+)
|
|
152
|
+
```ts
|
|
153
|
+
const neetru = createNeetruClient({ env: 'dev' });
|
|
154
|
+
// auth retorna DEV_FIXTURE_USER, usage/db/webhooks/notifications são in-memory
|
|
172
155
|
```
|
|
173
156
|
|
|
174
|
-
|
|
175
|
-
auto `.d.ts`).
|
|
157
|
+
Override pra testes determinísticos:
|
|
176
158
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
**Sem breaking changes.** Upgrade direto via `npm install @neetru/sdk@1.0.0`.
|
|
159
|
+
```ts
|
|
160
|
+
import { MockAuth, MockUsage } from '@neetru/sdk';
|
|
180
161
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
162
|
+
const neetru = createNeetruClient({
|
|
163
|
+
apiKey: 'nrt_test',
|
|
164
|
+
env: 'prod',
|
|
165
|
+
mocks: {
|
|
166
|
+
auth: new MockAuth({ user: { uid: 'test', email: 'a@b' } }),
|
|
167
|
+
usage: new MockUsage(),
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
```
|
|
186
171
|
|
|
187
|
-
##
|
|
172
|
+
## Versionamento
|
|
188
173
|
|
|
189
|
-
|
|
190
|
-
-
|
|
191
|
-
-
|
|
192
|
-
|
|
193
|
-
- Tipos nunca ganham campos required em minor (só optional ou via union).
|
|
194
|
-
- `NeetruErrorCode` é union fechado em v1.0 — qualquer novo código bumpa minor.
|
|
174
|
+
- **SemVer estrito** — breaking changes só em major.
|
|
175
|
+
- v1.0 GA (2026-05-06) — superfície estável de 7 namespaces
|
|
176
|
+
- v1.1 (2026-05) — checkout namespace
|
|
177
|
+
- v1.2 (2026-05) — webhooks + notifications namespaces
|
|
195
178
|
|
|
196
|
-
|
|
179
|
+
`initNeetru` (API v0.0.1) está deprecated desde v0.2 — funciona até v2.0.
|
|
197
180
|
|
|
198
|
-
|
|
199
|
-
npm install --include=dev # garante typedoc
|
|
200
|
-
npm run docs:gen # → sdk/docs-html/index.html
|
|
201
|
-
```
|
|
181
|
+
## Stack
|
|
202
182
|
|
|
203
|
-
|
|
183
|
+
- TypeScript 5 ESM-first
|
|
184
|
+
- Zero dependências runtime (usa `fetch` global)
|
|
185
|
+
- Bundle minzip <10KB (todos namespaces somados, tree-shake-friendly)
|
|
204
186
|
|
|
205
|
-
|
|
206
|
-
- **v1.1** — Telemetry batching + flush on unload.
|
|
207
|
-
- **v1.2** — LRU cache em entitlements.check (TTL configurável).
|
|
208
|
-
- **v1.x** — CDN release (`cdn.neetru.com/sdk/v1/`), SRI integrity.json,
|
|
209
|
-
UMD/IIFE bundle.
|
|
187
|
+
## Mais info
|
|
210
188
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
[`docs/PLAN_SDK_CLI_CDN.md`](../docs/PLAN_SDK_CLI_CDN.md).
|
|
189
|
+
- **Repo:** [github.com/Neetru/neetru-core](https://github.com/Neetru/neetru-core)
|
|
190
|
+
- **CLI complementar:** `npm install -g @neetru/cli`
|
|
214
191
|
|
|
215
|
-
##
|
|
192
|
+
## Licença
|
|
216
193
|
|
|
217
|
-
|
|
218
|
-
público (npm publish).
|
|
194
|
+
MIT © Neetru
|