@neetru/sdk 1.1.1 → 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.
Files changed (95) hide show
  1. package/CHANGELOG.md +284 -214
  2. package/README.md +194 -218
  3. package/dist/auth.cjs +4181 -346
  4. package/dist/auth.cjs.map +1 -1
  5. package/dist/auth.d.cts +5 -1
  6. package/dist/auth.d.ts +5 -1
  7. package/dist/auth.mjs +4181 -346
  8. package/dist/auth.mjs.map +1 -1
  9. package/dist/catalog.cjs +63 -24
  10. package/dist/catalog.cjs.map +1 -1
  11. package/dist/catalog.d.cts +6 -2
  12. package/dist/catalog.d.ts +6 -2
  13. package/dist/catalog.mjs +63 -24
  14. package/dist/catalog.mjs.map +1 -1
  15. package/dist/checkout.cjs +60 -18
  16. package/dist/checkout.cjs.map +1 -1
  17. package/dist/checkout.d.cts +5 -1
  18. package/dist/checkout.d.ts +5 -1
  19. package/dist/checkout.mjs +60 -18
  20. package/dist/checkout.mjs.map +1 -1
  21. package/dist/collection-ref-BBvTTXoG.d.cts +423 -0
  22. package/dist/collection-ref-BBvTTXoG.d.ts +423 -0
  23. package/dist/db-react.cjs +136 -0
  24. package/dist/db-react.cjs.map +1 -0
  25. package/dist/db-react.d.cts +99 -0
  26. package/dist/db-react.d.ts +99 -0
  27. package/dist/db-react.mjs +112 -0
  28. package/dist/db-react.mjs.map +1 -0
  29. package/dist/db.cjs +3652 -143
  30. package/dist/db.cjs.map +1 -1
  31. package/dist/db.d.cts +5 -8
  32. package/dist/db.d.ts +5 -8
  33. package/dist/db.mjs +3649 -143
  34. package/dist/db.mjs.map +1 -1
  35. package/dist/entitlements.cjs +101 -24
  36. package/dist/entitlements.cjs.map +1 -1
  37. package/dist/entitlements.d.cts +15 -5
  38. package/dist/entitlements.d.ts +15 -5
  39. package/dist/entitlements.mjs +101 -24
  40. package/dist/entitlements.mjs.map +1 -1
  41. package/dist/errors.cjs.map +1 -1
  42. package/dist/errors.mjs.map +1 -1
  43. package/dist/index.cjs +4341 -282
  44. package/dist/index.cjs.map +1 -1
  45. package/dist/index.d.cts +13 -6
  46. package/dist/index.d.ts +13 -6
  47. package/dist/index.mjs +4243 -189
  48. package/dist/index.mjs.map +1 -1
  49. package/dist/mocks.cjs +186 -9
  50. package/dist/mocks.cjs.map +1 -1
  51. package/dist/mocks.d.cts +21 -6
  52. package/dist/mocks.d.ts +21 -6
  53. package/dist/mocks.mjs +186 -9
  54. package/dist/mocks.mjs.map +1 -1
  55. package/dist/notifications.cjs +296 -0
  56. package/dist/notifications.cjs.map +1 -0
  57. package/dist/notifications.d.cts +5 -0
  58. package/dist/notifications.d.ts +5 -0
  59. package/dist/notifications.mjs +293 -0
  60. package/dist/notifications.mjs.map +1 -0
  61. package/dist/react.cjs +7 -3
  62. package/dist/react.cjs.map +1 -1
  63. package/dist/react.d.cts +5 -1
  64. package/dist/react.d.ts +5 -1
  65. package/dist/react.mjs +7 -3
  66. package/dist/react.mjs.map +1 -1
  67. package/dist/support.cjs +60 -18
  68. package/dist/support.cjs.map +1 -1
  69. package/dist/support.d.cts +5 -1
  70. package/dist/support.d.ts +5 -1
  71. package/dist/support.mjs +60 -18
  72. package/dist/support.mjs.map +1 -1
  73. package/dist/telemetry.cjs +130 -19
  74. package/dist/telemetry.cjs.map +1 -1
  75. package/dist/telemetry.d.cts +21 -1
  76. package/dist/telemetry.d.ts +21 -1
  77. package/dist/telemetry.mjs +130 -19
  78. package/dist/telemetry.mjs.map +1 -1
  79. package/dist/types-B1jylbMC.d.ts +1364 -0
  80. package/dist/types-Kmt4y1FQ.d.cts +1364 -0
  81. package/dist/usage.cjs +60 -18
  82. package/dist/usage.cjs.map +1 -1
  83. package/dist/usage.d.cts +5 -1
  84. package/dist/usage.d.ts +5 -1
  85. package/dist/usage.mjs +60 -18
  86. package/dist/usage.mjs.map +1 -1
  87. package/dist/webhooks.cjs +316 -0
  88. package/dist/webhooks.cjs.map +1 -0
  89. package/dist/webhooks.d.cts +5 -0
  90. package/dist/webhooks.d.ts +5 -0
  91. package/dist/webhooks.mjs +312 -0
  92. package/dist/webhooks.mjs.map +1 -0
  93. package/package.json +133 -101
  94. package/dist/types-BA53dd8S.d.cts +0 -490
  95. package/dist/types-BA53dd8S.d.ts +0 -490
package/README.md CHANGED
@@ -1,218 +1,194 @@
1
- # @neetru/sdk
2
-
3
- Biblioteca runtime para consumir o ecossistema Neetru catálogo público de
4
- produtos, entitlements de tenant e telemetria — de qualquer
5
- JavaScript/TypeScript moderno (browser, Node ≥20, Edge runtimes).
6
-
7
- > **Status:** `1.0.0` GA — superfície pública estabilizada (2026-05-06).
8
- > Namespaces `auth`/`catalog`/`entitlements`/`telemetry`/`usage`/`support`/`db`.
9
- > A partir de v1.0, breaking changes só em majors. CDN distribution segue
10
- > roadmap pós-1.0 — vide [`docs/PLAN_SDK_NEETRU.md`](../docs/PLAN_SDK_NEETRU.md).
11
-
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
27
-
28
- ```bash
29
- npm install @neetru/sdk
30
- ```
31
-
32
- > Pacote ainda **privado** (`private: true`) e não publicado no npm.
33
- > Reservar é responsabilidade do owner em Sprint 6 do plano.
34
-
35
- ## Quick start
36
-
37
- ```ts
38
- import { createNeetruClient, NeetruError } from '@neetru/sdk';
39
-
40
- const client = createNeetruClient({
41
- apiKey: process.env.NEETRU_API_KEY, // ou deixe undefined que ele do env
42
- baseUrl: 'https://api.neetru.com', // default
43
- });
44
-
45
- // 1. Catálogo público de produtos
46
- const { products } = await client.catalog.list();
47
- console.log(products.map((p) => p.slug));
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();
54
-
55
- // 3. Telemetria emite evento de uso
56
- await client.telemetry.event({
57
- name: 'report_exported',
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
- }
74
- ```
75
-
76
- ## API reference (v0.2)
77
-
78
- ### `createNeetruClient(config?)`
79
-
80
- | Campo | Tipo | Descrição |
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. |
87
-
88
- Retorna `NeetruClient` com `.config`, `.auth`, `.catalog`, `.entitlements`, `.telemetry`, `.usage`, `.support`.
89
-
90
- ### `client.auth` (v0.2)
91
-
92
- | Método | Descrição |
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. |
98
-
99
- ### `client.catalog`
100
-
101
- | Método | Descrição |
102
- |---|---|
103
- | `list(opts?)` | `GET /api/v1/cli/catalog`. Retorna `{ products, fetchedAt }`. |
104
- | `get(slug)` | `GET /api/v1/cli/catalog/{slug}`. Retorna `Product` ou lança `not_found`. |
105
-
106
- ### `client.entitlements`
107
-
108
- | Método | Descrição |
109
- |---|---|
110
- | `check(slug, feature)` | `boolean`. Atalho do `checkDetailed`. |
111
- | `checkDetailed(slug, feature)` | `EntitlementCheck` com `allowed`, `reason`. |
112
-
113
- ### `client.telemetry`
114
-
115
- | Método | Descrição |
116
- |---|---|
117
- | `event({ name, properties?, timestamp? })` | `POST /api/v1/sdk/telemetry/event`. Retorna `{ ok, eventId }`. |
118
-
119
- ### `client.usage` (v0.2)
120
-
121
- | Método | Descrição |
122
- |---|---|
123
- | `track(event, props?)` | `POST /sdk/v1/usage/record`. Persiste consumo. |
124
- | `getQuota(metric)` | `GET /sdk/v1/usage/quota?metric=`. Retorna `{ used, limit, plan, resetsAt? }`. |
125
-
126
- ### `client.support` (v0.2)
127
-
128
- | Método | Descrição |
129
- |---|---|
130
- | `createTicket({subject, message, severity?, productSlug?})` | `POST /api/v1/products/{slug}/tickets`. |
131
- | `listMyTickets()` | `GET /api/v1/products/_default/tickets`. |
132
-
133
- ### Mocks (`@neetru/sdk/mocks`)
134
-
135
- Use em tests do consumer ou ative globalmente com `NEETRU_ENV=dev`:
136
-
137
- ```ts
138
- import { createNeetruClient, MockAuth, MockUsage, MockSupport } from '@neetru/sdk';
139
-
140
- const client = createNeetruClient({
141
- mocks: {
142
- auth: new MockAuth({ uid: 'fake', email: 'fake@x.com' }),
143
- usage: new MockUsage(),
144
- support: new MockSupport(),
145
- },
146
- });
147
- ```
148
-
149
- ### Códigos de erro estáveis (`NeetruError.code`)
150
-
151
- `invalid_config` · `missing_api_key` · `unauthorized` · `forbidden` ·
152
- `not_found` · `rate_limited` · `validation_failed` · `network_error` ·
153
- `invalid_response` · `server_error` · `unknown`.
154
-
155
- ## Subpath imports (tree-shaking)
156
-
157
- ```ts
158
- // Importa só o tipo de erro (zero deps de transport)
159
- import { NeetruError } from '@neetru/sdk/errors';
160
-
161
- // Bundlers podem fazer code-split por namespace
162
- import { createCatalogNamespace } from '@neetru/sdk/catalog';
163
- ```
164
-
165
- ## Build
166
-
167
- ```bash
168
- npm run build # tsup → dist/{index,catalog,entitlements,telemetry,errors}.{mjs,cjs,d.ts}
169
- npm run dev # watch mode
170
- npm run lint # tsc --noEmit
171
- npm run test # vitest run (Sprint 2+)
172
- ```
173
-
174
- Tooling: [tsup](https://tsup.egoist.dev) (esbuild backend, dual ESM+CJS,
175
- auto `.d.ts`).
176
-
177
- ## Migration v0.3 v1.0
178
-
179
- **Sem breaking changes.** Upgrade direto via `npm install @neetru/sdk@1.0.0`.
180
-
181
- - `initNeetru` continua deprecated mas funcional. **Será removido em v2.0.0.**
182
- Use `createNeetruClient` em código novo.
183
- - `NeetruConfig` continua deprecated — use `NeetruClientConfig`.
184
- - Tipos exportados continuam idênticos.
185
- - Comportamento runtime idêntico apenas estabilização de contratos.
186
-
187
- ## Stability promise (v1.x)
188
-
189
- A partir de v1.0:
190
- - Métodos novos podem ser adicionados a namespaces existentes (minor bump).
191
- - Métodos podem ser marcados `@deprecated` em qualquer minor — só removidos
192
- em major.
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.
195
-
196
- ## Generate API docs
197
-
198
- ```bash
199
- npm install --include=dev # garante typedoc
200
- npm run docs:gen # → sdk/docs-html/index.html
201
- ```
202
-
203
- ## Roadmap
204
-
205
- - ✅ **v1.0** — API stability + GA. JSDoc completo + typedoc.
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.
210
-
211
- Detalhes em
212
- [`docs/PLAN_SDK_NEETRU.md`](../docs/PLAN_SDK_NEETRU.md) +
213
- [`docs/PLAN_SDK_CLI_CDN.md`](../docs/PLAN_SDK_CLI_CDN.md).
214
-
215
- ## License
216
-
217
- UNLICENSED — uso interno Neetru. License pública será definida em release
218
- público (npm publish).
1
+ # @neetru/sdk
2
+
3
+ > Biblioteca runtime oficial pra consumir o ecossistema Neetru a partir de produtos SaaS (Next.js, Node, browser, Edge runtimes).
4
+
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>
12
+
13
+ ## Instalação
14
+
15
+ ```bash
16
+ npm install @neetru/sdk
17
+ ```
18
+
19
+ ## Hello world
20
+
21
+ ```ts
22
+ import { createNeetruClient } from '@neetru/sdk';
23
+
24
+ const neetru = createNeetruClient({
25
+ apiKey: process.env.NEETRU_API_KEY, // nrt_<keyId>_<secret>
26
+ env: 'prod', // 'dev' = mocks in-memory
27
+ });
28
+
29
+ // Auth
30
+ const user = await neetru.auth.signIn();
31
+ console.log('logado como:', user?.email);
32
+
33
+ // Entitlement check
34
+ const canAi = await neetru.entitlements.check('gestovendas', 'ai_recommendations');
35
+ if (canAi) { /* mostrar feature */ }
36
+ ```
37
+
38
+ ## Princípios
39
+
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 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.
45
+
46
+ ## Namespaces v1.2
47
+
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) |
60
+
61
+ ## Exemplos por namespace
62
+
63
+ ### Webhooks outbound (v1.2)
64
+
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
+ });
71
+
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
+ ```
76
+
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)
80
+
81
+ ### Notifications produto → user (v1.2)
82
+
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
+ });
93
+
94
+ const notifs = await neetru.notifications.list('usr_xyz', { onlyUnread: true });
95
+ await neetru.notifications.markRead(notifs[0].id);
96
+ ```
97
+
98
+ ### Entitlements
99
+
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
+ ```
105
+
106
+ ### Usage tracking
107
+
108
+ ```ts
109
+ await neetru.usage.track('report_generated', { count: 42, format: 'pdf' });
110
+
111
+ const quota = await neetru.usage.getQuota('reports_per_month');
112
+ // → { used: 15, limit: 100, resetsAt: '...', plan: 'starter' }
113
+ ```
114
+
115
+ ### Support
116
+
117
+ ```ts
118
+ await neetru.support.createTicket({
119
+ subject: 'Bug ao exportar CSV',
120
+ message: 'Quando seleciono >1000 rows o export falha',
121
+ severity: 'high',
122
+ });
123
+
124
+ const myTickets = await neetru.support.listMyTickets({ status: 'open' });
125
+ ```
126
+
127
+ ### DB (tenant-scoped, vendor-neutral)
128
+
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
+ ```
137
+
138
+ ### Checkout
139
+
140
+ ```ts
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;
148
+ ```
149
+
150
+ ## Modo dev (mocks automáticos)
151
+
152
+ ```ts
153
+ const neetru = createNeetruClient({ env: 'dev' });
154
+ // auth retorna DEV_FIXTURE_USER, usage/db/webhooks/notifications são in-memory
155
+ ```
156
+
157
+ Override pra testes determinísticos:
158
+
159
+ ```ts
160
+ import { MockAuth, MockUsage } from '@neetru/sdk';
161
+
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
+ ```
171
+
172
+ ## Versionamento
173
+
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
178
+
179
+ `initNeetru` (API v0.0.1) está deprecated desde v0.2 funciona até v2.0.
180
+
181
+ ## Stack
182
+
183
+ - TypeScript 5 ESM-first
184
+ - Zero dependências runtime (usa `fetch` global)
185
+ - Bundle minzip <10KB (todos namespaces somados, tree-shake-friendly)
186
+
187
+ ## Mais info
188
+
189
+ - **Repo:** [github.com/Neetru/neetru-core](https://github.com/Neetru/neetru-core)
190
+ - **CLI complementar:** `npm install -g @neetru/cli`
191
+
192
+ ## Licença
193
+
194
+ MIT © Neetru