@neetru/sdk 2.3.2 → 2.3.4
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 +282 -474
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.mjs.map +1 -1
- package/dist/index.cjs +48 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +48 -13
- package/dist/index.mjs.map +1 -1
- package/dist/mocks.cjs +48 -13
- package/dist/mocks.cjs.map +1 -1
- package/dist/mocks.d.cts +14 -10
- package/dist/mocks.d.ts +14 -10
- package/dist/mocks.mjs +48 -13
- package/dist/mocks.mjs.map +1 -1
- package/package.json +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,474 +1,282 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to `@neetru/sdk` will be documented in this file.
|
|
4
|
-
|
|
5
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
-
|
|
8
|
-
## [2.3.
|
|
9
|
-
|
|
10
|
-
### Corrigido
|
|
11
|
-
|
|
12
|
-
- **
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
`
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
`
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
- **`
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
## [
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
]
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
- **`
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
- **`client.
|
|
253
|
-
-
|
|
254
|
-
-
|
|
255
|
-
-
|
|
256
|
-
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
- **`
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
-
|
|
266
|
-
-
|
|
267
|
-
-
|
|
268
|
-
-
|
|
269
|
-
- **`
|
|
270
|
-
- **`db.
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
-
|
|
274
|
-
- `
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
- **`client.checkout.start({productId, planId, callbackUrl, tenantType?, tenantId?})`** — cria
|
|
284
|
-
`checkout_intents/{intentId}` no Core e (em browser) redireciona automaticamente
|
|
285
|
-
pra `minhaconta.neetru.com/portal/checkout/{intentId}`. Em Node/SSR retorna
|
|
286
|
-
`{intentId, redirectUrl}` sem efeito colateral.
|
|
287
|
-
- **`client.checkout.get(intentId)`** — lê estado atual do intent.
|
|
288
|
-
- **`client.checkout.cancel(intentId)`** — marca intent como `cancelled`.
|
|
289
|
-
- **Subpath `@neetru/sdk/react`** — componente `<CheckoutLink>` (wrapper de `<a>`
|
|
290
|
-
que dispara `start()` no click) + `<EntitlementGate mode="block|readonly">`
|
|
291
|
-
+ hook `useEntitlementContext()` pra desabilitar escritas quando free tier
|
|
292
|
-
estoura limite (decisão CEO §5 — read-only sempre, não hard-block).
|
|
293
|
-
- **`MockCheckout`** — implementação dev (`NEETRU_ENV=dev`) sem network. Retorna
|
|
294
|
-
URL fake `https://localhost:9003/portal/checkout/{intentId}` pra dev externo
|
|
295
|
-
testar UI sem provisionar conta Neetru.
|
|
296
|
-
- **Peer dep `react ^18 || ^19`** marcado opcional (só carregado se import `/react`).
|
|
297
|
-
|
|
298
|
-
### Changed
|
|
299
|
-
- `VERSION` const bump `1.0.0 → 1.1.0`.
|
|
300
|
-
- `NeetruClient.checkout` adicionado — backward-compatible (caller que não usa
|
|
301
|
-
o namespace não é afetado).
|
|
302
|
-
|
|
303
|
-
### Notes
|
|
304
|
-
- API stability test (`api-surface-stability.test.ts`) atualizado pra incluir
|
|
305
|
-
`checkout` no inventário canônico.
|
|
306
|
-
|
|
307
|
-
## [1.0.0] - 2026-05-06 — **GA (General Availability)**
|
|
308
|
-
|
|
309
|
-
Marco de estabilidade. A partir desta versão, **a superfície pública do SDK
|
|
310
|
-
está congelada** — breaking changes só em majors (semver estrito).
|
|
311
|
-
|
|
312
|
-
### Added
|
|
313
|
-
- **API stability lock** — todos os contratos (`createNeetruClient`,
|
|
314
|
-
`NeetruClient`, namespaces `auth`/`catalog`/`entitlements`/`telemetry`/
|
|
315
|
-
`usage`/`support`/`db`, `NeetruError`) ficam estáveis em v1.x. Coberto
|
|
316
|
-
por `api-surface-stability.test.ts` que falha o build se algum método
|
|
317
|
-
muda forma.
|
|
318
|
-
- **JSDoc completo** em toda função/método público — base pra `npm run docs:gen`
|
|
319
|
-
(typedoc → `sdk/docs-html/`).
|
|
320
|
-
- **`docs:gen` script** + `scripts/typedoc.config.json` — gera HTML
|
|
321
|
-
navigable das APIs.
|
|
322
|
-
- **`engines.node`** relaxado de `>=20` → `>=18` (suporta runtimes Node 18 LTS
|
|
323
|
-
ainda em uso por consumers).
|
|
324
|
-
|
|
325
|
-
### Changed
|
|
326
|
-
- `VERSION` bump `0.3.0` → `1.0.0`.
|
|
327
|
-
- README atualizado com seção de migração v0.3 → v1.0 (no breaking changes —
|
|
328
|
-
upgrade transparente).
|
|
329
|
-
|
|
330
|
-
### Migration v0.3 → v1.0
|
|
331
|
-
- **Sem breaking changes.** Upgrade direto via `npm install @neetru/sdk@1.0.0`.
|
|
332
|
-
- `initNeetru` continua deprecated mas funcional. **Será removido em v2.0.0.**
|
|
333
|
-
- `NeetruConfig` continua deprecated. Use `NeetruClientConfig`.
|
|
334
|
-
|
|
335
|
-
### Stability promise (v1.x)
|
|
336
|
-
A partir de v1.0:
|
|
337
|
-
- Métodos novos podem ser adicionados a namespaces existentes (minor bump).
|
|
338
|
-
- Métodos podem ser marcados `@deprecated` em qualquer minor — só removidos
|
|
339
|
-
em major.
|
|
340
|
-
- Tipos nunca ganham campos required em minor (só optional ou via union).
|
|
341
|
-
- `NeetruErrorCode` é union fechado em v1.0 — qualquer novo código bumpa minor.
|
|
342
|
-
|
|
343
|
-
### Notes
|
|
344
|
-
- Pacote ainda **privado** (`private: true`). Publicação no npm é
|
|
345
|
-
responsabilidade do owner — gate no CHANGELOG continua trancado até decisão.
|
|
346
|
-
|
|
347
|
-
## [0.3.0] - 2026-05-06
|
|
348
|
-
|
|
349
|
-
### Added
|
|
350
|
-
- Namespace `client.db` (v0.3) — wrapper minimalista pra coleções tenant-scoped:
|
|
351
|
-
- `client.db.collection(name).list({ limit? })`
|
|
352
|
-
- `client.db.collection(name).get(id)` (retorna null em not_found)
|
|
353
|
-
- `client.db.collection(name).set(id, data)` upsert
|
|
354
|
-
- `client.db.collection(name).remove(id)` delete
|
|
355
|
-
- Endpoints: `/sdk/v1/datastore/{collection}/{id?}` (placeholder REST — Sprint 9
|
|
356
|
-
finaliza; SDK já expõe interface estável).
|
|
357
|
-
- `MockDb` (in-memory) ativo em `NEETRU_ENV=dev`.
|
|
358
|
-
- Namespace `client.usage` ganhou `report()` e `check()`:
|
|
359
|
-
- `usage.report(resource, qty?)` → `POST /sdk/v1/usage/record` canônico
|
|
360
|
-
(Sprint 7) — incrementa atomicamente `usage_counters/{tid}_{pid}_{r}_{yyyymm}`.
|
|
361
|
-
- `usage.check(resource)` → `GET /sdk/v1/entitlements?productId&tenantId&feature` —
|
|
362
|
-
retorna `{allowed, reason, remaining, limit, planId, planFeatures}`.
|
|
363
|
-
- `NeetruClientConfig.productId` / `.tenantId` — defaults pra `usage.report` /
|
|
364
|
-
`usage.check` / `db.collection` quando não passado em options.
|
|
365
|
-
- Mock helpers: `MockDb`, `MockUsage.report()`, `MockUsage.check()`.
|
|
366
|
-
|
|
367
|
-
### Changed
|
|
368
|
-
- `VERSION` bump `0.2.0` → `0.3.0`.
|
|
369
|
-
- `NeetruClient` agora expõe `.db` além dos antigos.
|
|
370
|
-
- `ResolvedConfig` ganhou `productId` + `tenantId` opcionais.
|
|
371
|
-
|
|
372
|
-
### Backend (acompanha esta release)
|
|
373
|
-
- Novos endpoints (Sprint 7):
|
|
374
|
-
- `POST /sdk/v1/usage/record` — atomic increment + 80%/100% notifications + audit.
|
|
375
|
-
- `GET /sdk/v1/entitlements` — lookup canônico subscription→plan→counter.
|
|
376
|
-
- `POST /sdk/v1/telemetry/log` — batch logger pra `logs/{productId}/{yyyymmdd}/`.
|
|
377
|
-
|
|
378
|
-
## [0.2.0] - 2026-05-06
|
|
379
|
-
|
|
380
|
-
### Added
|
|
381
|
-
- Namespace `client.auth` (v0.2 — OIDC + dev mocks):
|
|
382
|
-
- `signIn(options?)` — redireciona pra auth.neetru.com authorize endpoint
|
|
383
|
-
(browser) ou retorna mock user em dev (`NEETRU_ENV=dev`).
|
|
384
|
-
- `signOut()` — limpa `localStorage.neetru_id_token` + revoga refresh
|
|
385
|
-
server-side (best-effort).
|
|
386
|
-
- `getUser()` — decodifica id_token cached e retorna `NeetruUser` ou null.
|
|
387
|
-
- `onAuthStateChanged(listener)` — sub a mudanças, dispatcha sync no subscribe.
|
|
388
|
-
- Namespace `client.usage` (v0.2 — meter):
|
|
389
|
-
- `track(event, props?)` → `POST /sdk/v1/usage/record` com Bearer.
|
|
390
|
-
- `getQuota(metric)` → `GET /sdk/v1/usage/quota?metric=` returns
|
|
391
|
-
`{ metric, used, limit, plan, resetsAt? }`.
|
|
392
|
-
- Namespace `client.support` (v0.2 — tickets):
|
|
393
|
-
- `createTicket({subject, message, severity?, productSlug?})` →
|
|
394
|
-
`POST /api/v1/products/{slug}/tickets` (default `_default`).
|
|
395
|
-
- `listMyTickets()` → `GET ...` retorna array (aceita envelope `{tickets:[]}`).
|
|
396
|
-
- `mocks` module (`@neetru/sdk/mocks`):
|
|
397
|
-
- `MockAuth`, `MockUsage`, `MockSupport`, `MockEntitlements` — overridáveis
|
|
398
|
-
via `createNeetruClient({ mocks: { auth: MockAuth(...), ... } })`.
|
|
399
|
-
- `DEV_FIXTURE_USER` constante exportada.
|
|
400
|
-
- `NEETRU_ENV` resolution chain: config arg > `process.env.NEETRU_ENV` >
|
|
401
|
-
`globalThis.NEETRU_ENV` > default `prod`. `dev` ativa mocks automáticos.
|
|
402
|
-
- Subpath exports adicionais: `@neetru/sdk/{auth,usage,support,mocks}`.
|
|
403
|
-
- Tipos novos: `NeetruUser`, `AuthNamespace`, `UsageNamespace`,
|
|
404
|
-
`SupportNamespace`, `SignInOptions`, `SupportTicket`, `UsageQuota`,
|
|
405
|
-
`NeetruEnv`, `CreateTicketInput`.
|
|
406
|
-
|
|
407
|
-
### Changed
|
|
408
|
-
- `VERSION` bump `0.1.0` → `0.2.0`.
|
|
409
|
-
- `NeetruClientConfig` ganhou campos `env` + `mocks`.
|
|
410
|
-
- `ResolvedConfig` ganhou `env` resolved.
|
|
411
|
-
- `NeetruClient` agora expõe `.auth`, `.usage`, `.support` além dos antigos.
|
|
412
|
-
|
|
413
|
-
### Backend (acompanha esta release — endpoints documentados em `docs/SDK_OPENAPI.md`)
|
|
414
|
-
- `POST /sdk/v1/usage/record` — record event meterado.
|
|
415
|
-
- `GET /sdk/v1/usage/quota?metric=` — ler quota atual.
|
|
416
|
-
- `POST /api/v1/products/{slug}/tickets` — criar ticket.
|
|
417
|
-
- `GET /api/v1/products/{slug}/tickets` — listar meus tickets.
|
|
418
|
-
- (auth) `auth.neetru.com/oauth/authorize` — já live (Sprint 1 OIDC).
|
|
419
|
-
- (auth) `auth.neetru.com/oauth/revoke` — revoga refresh token.
|
|
420
|
-
|
|
421
|
-
### Notes
|
|
422
|
-
- Pacote ainda **privado** (`private: true`) — não publicado no npm.
|
|
423
|
-
- Carry-over: integração OIDC live aguarda owner habilitar redirect_uri pro
|
|
424
|
-
domain do consumer (configurar em `oidc_clients/{client_id}.redirect_uris`).
|
|
425
|
-
- TODO: `support.listMyTickets` precisa parametrizar productSlug (fixed
|
|
426
|
-
`_default` na v0.2).
|
|
427
|
-
|
|
428
|
-
## [0.1.0] - 2026-05-05
|
|
429
|
-
|
|
430
|
-
### Added
|
|
431
|
-
- `createNeetruClient(config)` factory — entry point principal.
|
|
432
|
-
- Resolve `apiKey` (arg explícito > `NEETRU_API_KEY` env em Node).
|
|
433
|
-
- Resolve `baseUrl` (default `https://api.neetru.com`).
|
|
434
|
-
- Resolve `fetch` (arg > `globalThis.fetch`).
|
|
435
|
-
- Namespace `client.catalog`:
|
|
436
|
-
- `list(opts?)` → `GET /api/v1/cli/catalog`. Aceita `includeDrafts`.
|
|
437
|
-
- `get(slug)` → `GET /api/v1/cli/catalog/{slug}`.
|
|
438
|
-
- Namespace `client.entitlements`:
|
|
439
|
-
- `check(slug, feature)` → boolean.
|
|
440
|
-
- `checkDetailed(slug, feature)` → `EntitlementCheck` com `reason`.
|
|
441
|
-
- Backed por `GET /api/v1/sdk/entitlements/check`.
|
|
442
|
-
- Namespace `client.telemetry`:
|
|
443
|
-
- `event({ name, properties?, timestamp? })` → `POST /api/v1/sdk/telemetry/event`.
|
|
444
|
-
- Subpath exports map: `@neetru/sdk/{catalog,entitlements,telemetry,errors}`.
|
|
445
|
-
- HTTP transport com mapeamento status → `NeetruError.code` estável.
|
|
446
|
-
- Tipos exportados: `NeetruClient`, `NeetruClientConfig`, `Product`, `ProductPlan`,
|
|
447
|
-
`EntitlementCheck`, `TelemetryEventInput`, `TelemetryEventAck`, `NeetruErrorCode`.
|
|
448
|
-
- Compat alias `initNeetru` (deprecated, será removido em v1.0).
|
|
449
|
-
|
|
450
|
-
### Changed
|
|
451
|
-
- `VERSION` bump `0.0.1` → `0.1.0`.
|
|
452
|
-
- tsup config multi-entry pra subpath imports.
|
|
453
|
-
|
|
454
|
-
### Backend (acompanha esta release)
|
|
455
|
-
- `GET /api/v1/cli/catalog/{slug}` — produto único.
|
|
456
|
-
- `GET /api/v1/sdk/entitlements/check?slug=&feature=` — verificação por user.
|
|
457
|
-
- `POST /api/v1/sdk/telemetry/event` — persiste em `usage_events`.
|
|
458
|
-
|
|
459
|
-
### Notes
|
|
460
|
-
- Pacote ainda **privado** (`private: true`). Publicação no npm é
|
|
461
|
-
responsabilidade do owner em Sprint 6.
|
|
462
|
-
- API instável; pré-1.0 segue regra "breaking allowed em qualquer minor".
|
|
463
|
-
|
|
464
|
-
## [0.0.1] - 2026-05-04
|
|
465
|
-
|
|
466
|
-
### Added
|
|
467
|
-
- Scaffold inicial do pacote `@neetru/sdk` (private, não publicado no npm ainda).
|
|
468
|
-
- `initNeetru(config)` com validação de `apiUrl` e injeção opcional de `fetch`.
|
|
469
|
-
- `NeetruError` com `code`, `status` e `requestId` opcionais.
|
|
470
|
-
- `NeetruConfig` e `NeetruClient` types públicos.
|
|
471
|
-
- `VERSION` const exportada.
|
|
472
|
-
- Build pipeline com tsup (dual ESM + CJS + `.d.ts`).
|
|
473
|
-
- README + CHANGELOG.
|
|
474
|
-
- `tsconfig.json` strict ES2022 ESNext.
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@neetru/sdk` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [2.3.4] - 2026-05-26 — **fix(mocks): MockDb.sql() migra pra pglite + pg-mem fallback — bug_6bae8674 [HIGH]**
|
|
9
|
+
|
|
10
|
+
### Corrigido
|
|
11
|
+
|
|
12
|
+
- **bug_6bae8674461f4600809e2f9de13c6043 (HIGH) — fix anterior (2.3.3) teve efeito INVERSO em `MockDb.sql()`.**
|
|
13
|
+
O fix de 2.3.3 injetava `getTypeParser` em `pool.types` para resolver o erro "Not supported: getTypeParser is not supported".
|
|
14
|
+
Porém `pg-mem` tem um guard interno: `if (query.types?.getTypeParser) throw NotSupported`.
|
|
15
|
+
`drizzle-orm/node-postgres/session.js:113` passa `rawQuery.types = pool.types` em TODA query — ao adicionar
|
|
16
|
+
`getTypeParser` ao pool, drizzle passou-o para o pg-mem que o rejeitou imediatamente.
|
|
17
|
+
Efeito líquido: qualquer `INSERT`/`SELECT`/`UPDATE` continuava quebrando com o mesmo erro.
|
|
18
|
+
|
|
19
|
+
**Fix 2.3.4 — duas soluções em cascata:**
|
|
20
|
+
|
|
21
|
+
1. **Solução A (preferida): `@electric-sql/pglite` + `drizzle-orm/pglite`** — WASM-Postgres nativo
|
|
22
|
+
sem adapter pg-mem. Sem conflito `getTypeParser`, sem monkey-patch. `PGlite.create()` retorna
|
|
23
|
+
instância pronta, DDL via `pglite.query(ddl)`, ORM via `drizzle(pglite, { schema })`. Cast
|
|
24
|
+
`PgliteDatabase → NodePgDatabase` via `unknown` (interfaces Drizzle compatíveis em superfície
|
|
25
|
+
mas com tipos de resultado internos distintos).
|
|
26
|
+
|
|
27
|
+
2. **Solução B (fallback pg-mem)**: strip interceptor — intercepta `pool.query` e deleta
|
|
28
|
+
`types.getTypeParser` do objeto de query ANTES do pg-mem ver. Guard não dispara, query passa
|
|
29
|
+
limpa. Compatível com consumers que só têm pg-mem nas devDeps.
|
|
30
|
+
|
|
31
|
+
**`@electric-sql/pglite` adicionado como `peerDependency` optional** (`^0.4.0`) + `devDependency`
|
|
32
|
+
interno (`^0.4.6`).
|
|
33
|
+
|
|
34
|
+
**8 novos testes** em `src/__tests__/mocks-sql-pglite.test.ts`: criação sem erro, INSERT sem throw,
|
|
35
|
+
SELECT após INSERT, UPDATE, múltiplos INSERTs, sem initSql, close idempotente, transaction().
|
|
36
|
+
Todos passando.
|
|
37
|
+
|
|
38
|
+
**655 testes totais** (era 647 em 2.3.3). `tsc --noEmit` clean. Build clean.
|
|
39
|
+
|
|
40
|
+
## [2.3.3] - 2026-05-26 — **fix(mocks): pool.types.getTypeParser identity parser — bug_44bcc99f [HIGH]**
|
|
41
|
+
|
|
42
|
+
### Corrigido
|
|
43
|
+
|
|
44
|
+
- **bug_44bcc99f9d3140d78abd8f7810d1afa4 (HIGH) — `MockDb.sql()` queries Drizzle falhavam em runtime.**
|
|
45
|
+
Followup do `bug_a7f2ae25` (SDK 2.3.2): `sql()` retornava handle Drizzle, mas qualquer query (`INSERT`, `SELECT`, etc) jogava `Error: Not supported: getTypeParser is not supported`. `pg-mem` não implementa `pool.types.getTypeParser(oid)` que `drizzle-orm/node-postgres/session.js` chama em TODA query.
|
|
46
|
+
Fix: monkey-patch identity parser no Pool retornado por `pg-mem.adapters.createPg()` antes de passar pro Drizzle. Types retornam o valor sem transformação (suficiente pra tests in-memory; produção usa `pg` real com parsers nativos).
|
|
47
|
+
3 linhas. Non-breaking. Tests E2E Drizzle in-memory destravados.
|
|
48
|
+
|
|
49
|
+
## [2.3.2] - 2026-05-26 — **fix(mocks): MockDb.sql() implementado in-memory via pg-mem — bug_a7f2ae25 [HIGH]**
|
|
50
|
+
|
|
51
|
+
### Corrigido
|
|
52
|
+
|
|
53
|
+
- **bug_a7f2ae25fda54129b52b6dd55aaa6050 (HIGH) — `MockDb.sql()` lançava `db_unavailable` em vez de implementar Drizzle in-memory.**
|
|
54
|
+
Bloqueava vitest server-side dos consumers (pdv-agiliza Fase 4 migration). Política do projeto proíbe workaround instalar `pg-mem` no consumer.
|
|
55
|
+
Fix: `MockDb.sql(schema, options)` agora carrega `pg-mem` lazy + cria `NodePgDatabase<TSchema>` Drizzle apontando pra DB in-memory. Suporta `options.initSql: string | string[]` pra rodar DDL no setup (CREATE TABLE etc).
|
|
56
|
+
`pg-mem` adicionado como `peerDependency optional` (com `peerDependenciesMeta.optional=true`) + `devDependency` interno. Consumers que querem mock SQL: `npm install -D pg-mem drizzle-orm pg`.
|
|
57
|
+
**Não-breaking:** signature `sql(schema, options?)` mantida. SqlOptions ganhou `initSql?` opcional (ignorado por lease real em produção). Comportamento default — `sql()` sem `initSql` — funciona em ambos modos.
|
|
58
|
+
|
|
59
|
+
## [2.3.1] - 2026-05-26 — **fix(deps): drizzle-orm + pg como peerDependencies — bug_42ae9f80 [CRITICAL]**
|
|
60
|
+
|
|
61
|
+
### Corrigido
|
|
62
|
+
|
|
63
|
+
- **bug_42ae9f80b2884bd583c5246771f7730c (CRITICAL) — `drizzle-orm` em `dependencies` causava type collision com versão do consumer.**
|
|
64
|
+
Quando o projeto consumer instalava `drizzle-orm` direto e tentava `client.db.sql(schema)`, o TypeScript via 2 cópias diferentes (uma nested em `node_modules/@neetru/sdk/node_modules/drizzle-orm`, outra no consumer) e reclamava: `'Property config is protected but type Column<...> is not a class derived from Column<...>'` + `'shouldInlineParams private'`. Bloqueava Fases 2-8 da migração pdv-agiliza pra `vm-postgres-single`.
|
|
65
|
+
Fix: movidas `drizzle-orm` e `pg` de `dependencies` pra `peerDependencies` (com `peerDependenciesMeta.optional: true`). Consumer instala 1 versão, todos os tipos convergem. Devkit mantém `drizzle-orm` + `pg` em `devDependencies` pra build/test internos.
|
|
66
|
+
**Breaking expected on consumer side:** se o projeto consumer NÃO tinha `drizzle-orm` em deps mas usava `client.db.sql()`, agora precisa `npm install drizzle-orm pg`. Consumers que só usam transport REST/Firestore não são afetados (peerDeps optional).
|
|
67
|
+
|
|
68
|
+
## [2.3.0] - 2026-05-25 — **feat(db-config): renomeia engine→transport com deprecation — bug_ed9da7fd [HIGH]**
|
|
69
|
+
|
|
70
|
+
Fix do bug `bug_ed9da7fd11194eac87f0eb9c75e5fad9` (HIGH) — colisão de terminologia: `engine` no SDK
|
|
71
|
+
configurava o transporte SDK↔Core (REST/Firestore/WebSocket), mas `engine` no admin database (CLI
|
|
72
|
+
`neetru admin database create --engine=...`) configura o storage engine (firestore-instance,
|
|
73
|
+
cloud-sql-postgres, vm-postgres-single…). Devs colocavam `firestore-instance` no SDK e quebravam.
|
|
74
|
+
|
|
75
|
+
### Added
|
|
76
|
+
|
|
77
|
+
- **`NeetruDbTransport`** — novo tipo público canônico para o campo de transporte SDK↔Core.
|
|
78
|
+
Valores: `'rest' | 'firestore' | 'nosql-vm'` (idênticos aos de `NeetruDbEngine`).
|
|
79
|
+
|
|
80
|
+
- **`NeetruDbOptions.transport`** — novo campo canônico que substitui `engine`.
|
|
81
|
+
```ts
|
|
82
|
+
// v2.3+ (preferido):
|
|
83
|
+
createNeetruClient({ db: { transport: 'rest' } });
|
|
84
|
+
createNeetruClient({ db: { transport: 'firestore' } });
|
|
85
|
+
createNeetruClient({ db: { transport: 'nosql-vm', realtimeGatewayUrl: '...' } });
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Deprecated
|
|
89
|
+
|
|
90
|
+
- **`NeetruDbOptions.engine`** — depreciado em v2.3, será removido em v3.0.
|
|
91
|
+
Continua funcionando: se `transport` estiver ausente e `engine` presente, o valor de `engine`
|
|
92
|
+
é usado como transport com `console.warn` de deprecação.
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
// v2.x (depreciado — emite console.warn):
|
|
96
|
+
createNeetruClient({ db: { engine: 'firestore' } });
|
|
97
|
+
// ⚠ [neetru/sdk] NeetruDbOptions.engine está depreciado...
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
- **`NeetruDbEngine`** — depreciado em v2.3, será removido em v3.0.
|
|
101
|
+
Agora é alias de `NeetruDbTransport`. Use `NeetruDbTransport` em código novo.
|
|
102
|
+
|
|
103
|
+
### Behavior
|
|
104
|
+
|
|
105
|
+
- `transport` e `engine` podem coexistir: `transport` sempre prevalece, sem warn.
|
|
106
|
+
- Sem `transport` nem `engine`: default `'rest'`, sem warn (comportamento idêntico ao v2.x).
|
|
107
|
+
- A relação 1:N entre storage engines e transports é documentada no JSDoc de `NeetruDbTransport`:
|
|
108
|
+
qualquer storage engine (cloud-sql-postgres, vm-postgres-single…) pode ser acessado com
|
|
109
|
+
`transport: 'rest'`; `transport: 'firestore'` e `transport: 'nosql-vm'` são para bancos
|
|
110
|
+
documentais com realtime nativo.
|
|
111
|
+
|
|
112
|
+
### Tests
|
|
113
|
+
|
|
114
|
+
- 5 testes novos em `src/__tests__/db-real.test.ts`:
|
|
115
|
+
`transport=firestore`, `transport=nosql-vm`, `transport=rest`, colisão `transport+engine`
|
|
116
|
+
(transport prevalece, sem warn), default sem campos (sem warn).
|
|
117
|
+
- Testes de regressão: `engine=firestore` e `engine=nosql-vm` legados ainda passam + emitem warn.
|
|
118
|
+
|
|
119
|
+
## [2.2.1] - 2026-05-25 — **fix(offline-docs): fallback MemoryStore em Node — bug_ba287a CRITICAL**
|
|
120
|
+
|
|
121
|
+
Fix do bug `bug_ba287aefdf6c4327b026d588a239ad06` (CRITICAL) — `client.db.collection().set/add/update`
|
|
122
|
+
lançava `ReferenceError: indexedDB is not defined` em Node.js (reportado por pdv-agiliza prod).
|
|
123
|
+
|
|
124
|
+
### Fixed
|
|
125
|
+
|
|
126
|
+
- **`createOfflineDocumentsNamespace` — auto-detect Node runtime e usa `MemoryStore`**.
|
|
127
|
+
A função agora verifica `typeof indexedDB === 'undefined' || typeof window === 'undefined'`
|
|
128
|
+
antes de instanciar `LocalStore` (que depende de `idb` / IndexedDB). Em Node/Bun/Edge Workers
|
|
129
|
+
sem IDB, cai automaticamente em `MemoryStore` — implementação in-process com a mesma API,
|
|
130
|
+
sem nenhuma flag explícita necessária. Ops de documentos (`set/add/update/remove/get/list`,
|
|
131
|
+
`batch`, `onSnapshot`, `onDoc`) funcionam normalmente em Node; dados não persistem entre
|
|
132
|
+
reinicializações do processo (comportamento esperado em SSR/server-side).
|
|
133
|
+
|
|
134
|
+
### Added
|
|
135
|
+
|
|
136
|
+
- **`src/db/offline/memory-store.ts`** — `MemoryStore`: implementação in-memory do contrato
|
|
137
|
+
público de `LocalStore`. Cobre todas as 5 stores (documents, mutations, query\_cache,
|
|
138
|
+
sync\_meta, conflict\_log) com Maps/Arrays em memória.
|
|
139
|
+
|
|
140
|
+
### Tests
|
|
141
|
+
|
|
142
|
+
- **`src/__tests__/offline-docs-node-compat.test.ts`** — 5 casos de regressão:
|
|
143
|
+
verifica que a stack offline não lança `ReferenceError` em ambiente sem IDB,
|
|
144
|
+
e que `set/add/update` + `get` roundtrips funcionam in-memory.
|
|
145
|
+
|
|
146
|
+
## [2.2.0] - 2026-05-25 — **auth.verifyToken — validação server-side de id_token via JWKS [feature]**
|
|
147
|
+
|
|
148
|
+
Fix do bug `bug_a7ef1702680044e3994b74bdccecb2ab` — resolve P0-1 audit security pdv-agiliza.
|
|
149
|
+
|
|
150
|
+
### Added
|
|
151
|
+
|
|
152
|
+
- **`client.auth.verifyToken(token, options?): Promise<NeetruUser>`** — valida um id_token JWT
|
|
153
|
+
emitido por `auth.neetru.com` server-side, sem round-trip de rede por request. Usa JWKS local
|
|
154
|
+
cacheado (default TTL 1h, configurável via `options.jwksCacheTtlMs`).
|
|
155
|
+
|
|
156
|
+
Erros tipados novos (`NeetruErrorCode`):
|
|
157
|
+
- `token_expired` — `exp` no passado
|
|
158
|
+
- `token_invalid_signature` — assinatura não verificada pela JWKS
|
|
159
|
+
- `token_invalid_audience` — `aud` não bate com o `clientId` extraído do `apiKey`
|
|
160
|
+
- `token_invalid_issuer` — `iss` não é `https://auth.neetru.com`
|
|
161
|
+
|
|
162
|
+
Dependência nova: `jose` (Vercel/Cloudflare-friendly, sem Node nativo).
|
|
163
|
+
|
|
164
|
+
- **`MockAuth.verifyToken(token)`** — decodifica JWT sem verificar assinatura (útil em testes).
|
|
165
|
+
Aceita `__mockVerifyToken(fn)` pra injetar falhas determinísticas.
|
|
166
|
+
|
|
167
|
+
- **`VerifyTokenOptions`** — exportado em `index.ts` pra consumers tiparem as options.
|
|
168
|
+
|
|
169
|
+
### Usage
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
// Next.js route handler
|
|
173
|
+
import { createNeetruClient } from '@neetru/sdk';
|
|
174
|
+
const client = createNeetruClient({ apiKey: 'nrt_a1b2c3_...', env: 'prod' });
|
|
175
|
+
|
|
176
|
+
export async function POST(req: Request) {
|
|
177
|
+
const token = req.cookies.get('neetru-session')?.value ?? '';
|
|
178
|
+
try {
|
|
179
|
+
const user = await client.auth.verifyToken(token);
|
|
180
|
+
// user.uid, user.email, user.isStaff, user.tenantId disponíveis
|
|
181
|
+
} catch (err) {
|
|
182
|
+
return new Response('Unauthorized', { status: 401 });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## [Unreleased]
|
|
188
|
+
|
|
189
|
+
### Planned (post-2.2)
|
|
190
|
+
- size-limit budget no CI (<12KB gz core com db namespace).
|
|
191
|
+
- CDN distribution (`cdn.neetru.com/sdk/v2/`).
|
|
192
|
+
- Endpoint batch `/api/v1/sdk/telemetry/batch` (substitui drenagem N×1 do `track()` por 1 request).
|
|
193
|
+
|
|
194
|
+
## [2.1.1] - 2026-05-25 — **DbDocRef identity + DbBatchOp discriminated union [patch]**
|
|
195
|
+
|
|
196
|
+
Dois fixes LOW reportados por pdv-agiliza (tickets `bug_97b3f0488d1c49cf8c5f94e5d544289b` + `bug_6aab9adc182640218652a65cdcb71b63`).
|
|
197
|
+
Sem breaking changes — todos os usos de `doc()` existentes continuam funcionando.
|
|
198
|
+
|
|
199
|
+
### Fixed
|
|
200
|
+
|
|
201
|
+
- **`DbDocRef.id / .path / .collection`** (fix #13, ticket `bug_97b3f0488d1c49cf8c5f94e5d544289b`):
|
|
202
|
+
`DbDocRef` agora expõe três propriedades readonly de identidade:
|
|
203
|
+
- `id: string` — ID do documento dentro da coleção.
|
|
204
|
+
- `path: string` — Caminho completo `"colecao/docId"`.
|
|
205
|
+
- `collection: string` — Nome da coleção parent.
|
|
206
|
+
Análogo ao `DocumentReference.id/.path` do Firestore Web SDK. Elimina a necessidade
|
|
207
|
+
de adaptadores externos que reattachavam `collection + id` manualmente.
|
|
208
|
+
Implementado em `DbCollectionRefImpl.doc()` (offline), `createLazyCollectionRef.doc()`
|
|
209
|
+
(client-db) e `MockDb.doc()` (mocks).
|
|
210
|
+
|
|
211
|
+
- **`DbBatchOp` discriminated union** (fix #14, ticket `bug_6aab9adc182640218652a65cdcb71b63`):
|
|
212
|
+
`DbBatchOp` foi convertido de `interface` opaca (campo `op: 'add'|'set'|'update'|'remove'`
|
|
213
|
+
com `id?`/`data?` opcionais) para **discriminated union** pelo campo `kind`:
|
|
214
|
+
```ts
|
|
215
|
+
type DbBatchOp<T = Record<string, unknown>> =
|
|
216
|
+
| { kind: 'add'; data: Omit<T, 'id'> }
|
|
217
|
+
| { kind: 'set'; id: string; data: Omit<T, 'id'> }
|
|
218
|
+
| { kind: 'update'; id: string; data: Partial<Omit<T, 'id'>> }
|
|
219
|
+
| { kind: 'remove'; id: string };
|
|
220
|
+
```
|
|
221
|
+
O `.d.ts` público agora expõe claramente quais campos são obrigatórios por variante.
|
|
222
|
+
O campo `collection` foi removido da operação (sempre opera na coleção do `DbCollectionRef`).
|
|
223
|
+
|
|
224
|
+
### Migration (2.0.0 → 2.1.1)
|
|
225
|
+
|
|
226
|
+
Callers que usavam `batch()` devem trocar `op` por `kind` e remover o campo `collection`:
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
// antes (2.0.0)
|
|
230
|
+
col.batch([
|
|
231
|
+
{ op: 'add', collection: 'orders', data: { total: 10 } },
|
|
232
|
+
{ op: 'set', collection: 'orders', id: 'x', data: { total: 20 } },
|
|
233
|
+
{ op: 'update', collection: 'orders', id: 'y', data: { total: 30 } },
|
|
234
|
+
{ op: 'remove', collection: 'orders', id: 'z' },
|
|
235
|
+
]);
|
|
236
|
+
|
|
237
|
+
// depois (2.1.1)
|
|
238
|
+
col.batch([
|
|
239
|
+
{ kind: 'add', data: { total: 10 } },
|
|
240
|
+
{ kind: 'set', id: 'x', data: { total: 20 } },
|
|
241
|
+
{ kind: 'update', id: 'y', data: { total: 30 } },
|
|
242
|
+
{ kind: 'remove', id: 'z' },
|
|
243
|
+
]);
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## [2.0.0] - 2026-05-22 — **client.db NeetruDb (Documentos engine-aware + SQL) [M2]**
|
|
247
|
+
|
|
248
|
+
Major bump — breaking changes no namespace `db`. Liga todos os building blocks M2 na superfície pública.
|
|
249
|
+
|
|
250
|
+
### Breaking Changes
|
|
251
|
+
|
|
252
|
+
- **`client.db`** troca de `DbNamespace` (v0.3 REST simples) para `NeetruDb` (v2.0 offline-first engine-aware).
|
|
253
|
+
- `collection().list()` agora retorna `DbListResult<T>` (com `docs`, `nextCursor`, `fromCache`, `stale`, `hasPendingWrites`, `changes`) em vez de `T[]`.
|
|
254
|
+
- `collection().get(id)` retorna `DbGetResult<T> | null` em vez de `T | null`.
|
|
255
|
+
- `db_unavailable` não significa mais "sem rede" — só ciclo de vida do banco. Offline é transparente.
|
|
256
|
+
- Novos métodos obrigatórios na superfície: `sql()`, `syncState`, `flush()`, `clearCache()`, `getConflicts()`, `onSyncStateChanged()`, `batch()`, `onDoc()`, `onSnapshot()`, `doc()`.
|
|
257
|
+
- **`db.sql(schema)` lança `NeetruDbError('db_unavailable')` em `NEETRU_ENV=dev`** — sem Postgres local, sem acesso SQL. Use `neetru dev` para subir o container.
|
|
258
|
+
- **`initNeetru`** — mantido como stub funcional mas não mapeia mais `apiUrl → baseUrl`. Remover em v3.0.
|
|
259
|
+
- **`MockDb`** foi atualizado para implementar `NeetruDb` (v2.0) em vez de `DbNamespace` (v0.3).
|
|
260
|
+
|
|
261
|
+
### Added
|
|
262
|
+
|
|
263
|
+
- **`client.db.collection<T>(name)`** — retorna `DbCollectionRef<T>` offline-first, engine-aware. Funciona sem rede. Sync automático quando conectado.
|
|
264
|
+
- CRUD: `add`, `set`, `update`, `remove`, `get`, `list` (com query, cursor, orderBy, where, limit).
|
|
265
|
+
- Batch: `batch(ops)` — operações atômicas (client-side).
|
|
266
|
+
- Realtime: `onSnapshot(query, cb)`, `onDoc(id, cb)` — subscriptions permanentes, delivery imediato do cache.
|
|
267
|
+
- Doc ref: `doc(id).get()`, `.set()`, `.update()`, `.remove()`, `.onSnapshot()`.
|
|
268
|
+
- **`client.db.sql<TSchema>(schema)`** — lease SQL. Retorna `NeetruSqlClient<TSchema>` com `orm` (Drizzle `NodePgDatabase`) + `transaction()` + `close()`.
|
|
269
|
+
- **`client.db.syncState`** — estado de sincronização observável (`status`, `pendingWrites`, `lastSyncedAt`, `isLeaderTab`).
|
|
270
|
+
- **`client.db.onSyncStateChanged(cb)`** — subscrição de mudanças de sync state.
|
|
271
|
+
- **`client.db.flush()`** — força ciclo de sync imediato.
|
|
272
|
+
- **`client.db.clearCache(collections?)`** — limpa o cache local (IndexedDB).
|
|
273
|
+
- **`client.db.getConflicts(collection?)`** — lista conflitos LWW pendentes.
|
|
274
|
+
- **Engine detection** via `NeetruDbOptions.engine`: `'firestore'` | `'nosql-vm'` | `'rest'` (default MVP).
|
|
275
|
+
- **Subpath `@neetru/sdk/db/react`** — hooks React: `useCollection`, `useDoc` (exporta via `dist/db-react.{mjs,cjs}`).
|
|
276
|
+
- **Novos tipos públicos exportados**: `NeetruDb`, `NeetruDbEngine`, `NeetruDbOptions`, `NeetruSqlClient`, `DbSqlLease`, `DbCollectionRef`, `DbDocRef`, `DbQuery`, `DbDoc`, `DbListResult`, `DbGetResult`, `DbBatchOp`, `DbChangeType`, `NeetruDbError`, `NeetruDbErrorCode`.
|
|
277
|
+
- **`createNeetruDb(config, opts)`** — factory async (para uso fora do `createNeetruClient`).
|
|
278
|
+
- **`createNeetruDbSync(config, opts)`** — factory sync com lazy init IndexedDB (usada internamente em `createNeetruClient`).
|
|
279
|
+
|
|
280
|
+
### Changed
|
|
281
|
+
|
|
282
|
+
- **`NeetruClientConfig.db`** — aceita `NeetruDbOptions` (engine, dbId, collections, dbName, etc.).
|