@neetru/sdk 3.4.4 → 3.4.6

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 (76) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/ai.cjs +1 -1
  3. package/dist/ai.cjs.map +1 -1
  4. package/dist/ai.d.cts +1 -1
  5. package/dist/ai.d.ts +1 -1
  6. package/dist/ai.mjs +1 -1
  7. package/dist/ai.mjs.map +1 -1
  8. package/dist/auth.cjs +47 -74
  9. package/dist/auth.cjs.map +1 -1
  10. package/dist/auth.d.cts +53 -2
  11. package/dist/auth.d.ts +53 -2
  12. package/dist/auth.mjs +46 -75
  13. package/dist/auth.mjs.map +1 -1
  14. package/dist/catalog.d.cts +1 -1
  15. package/dist/catalog.d.ts +1 -1
  16. package/dist/checkout.d.cts +1 -1
  17. package/dist/checkout.d.ts +1 -1
  18. package/dist/db-react.d.cts +1 -1
  19. package/dist/db-react.d.ts +1 -1
  20. package/dist/db.d.cts +1 -1
  21. package/dist/db.d.ts +1 -1
  22. package/dist/entitlements.cjs +16 -263
  23. package/dist/entitlements.cjs.map +1 -1
  24. package/dist/entitlements.d.cts +12 -10
  25. package/dist/entitlements.d.ts +12 -10
  26. package/dist/entitlements.mjs +16 -263
  27. package/dist/entitlements.mjs.map +1 -1
  28. package/dist/firestore-compat.d.cts +1 -1
  29. package/dist/firestore-compat.d.ts +1 -1
  30. package/dist/index.cjs +44 -75
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +3 -3
  33. package/dist/index.d.ts +3 -3
  34. package/dist/index.mjs +44 -76
  35. package/dist/index.mjs.map +1 -1
  36. package/dist/mocks.d.cts +1 -1
  37. package/dist/mocks.d.ts +1 -1
  38. package/dist/notifications.cjs +1 -1
  39. package/dist/notifications.cjs.map +1 -1
  40. package/dist/notifications.d.cts +1 -1
  41. package/dist/notifications.d.ts +1 -1
  42. package/dist/notifications.mjs +1 -1
  43. package/dist/notifications.mjs.map +1 -1
  44. package/dist/react.cjs +6 -2
  45. package/dist/react.cjs.map +1 -1
  46. package/dist/react.d.cts +1 -1
  47. package/dist/react.d.ts +1 -1
  48. package/dist/react.mjs +6 -2
  49. package/dist/react.mjs.map +1 -1
  50. package/dist/support.cjs +1 -1
  51. package/dist/support.cjs.map +1 -1
  52. package/dist/support.d.cts +1 -1
  53. package/dist/support.d.ts +1 -1
  54. package/dist/support.mjs +1 -1
  55. package/dist/support.mjs.map +1 -1
  56. package/dist/telemetry.cjs +16 -4
  57. package/dist/telemetry.cjs.map +1 -1
  58. package/dist/telemetry.d.cts +1 -1
  59. package/dist/telemetry.d.ts +1 -1
  60. package/dist/telemetry.mjs +16 -4
  61. package/dist/telemetry.mjs.map +1 -1
  62. package/dist/{types-Dw0fqhHm.d.cts → types-DIVZl7nO.d.cts} +3 -0
  63. package/dist/{types-Bzxb5rlF.d.ts → types-nnztVk7G.d.ts} +3 -0
  64. package/dist/usage.cjs +1 -1
  65. package/dist/usage.cjs.map +1 -1
  66. package/dist/usage.d.cts +1 -1
  67. package/dist/usage.d.ts +1 -1
  68. package/dist/usage.mjs +1 -1
  69. package/dist/usage.mjs.map +1 -1
  70. package/dist/webhooks.cjs +1 -1
  71. package/dist/webhooks.cjs.map +1 -1
  72. package/dist/webhooks.d.cts +1 -1
  73. package/dist/webhooks.d.ts +1 -1
  74. package/dist/webhooks.mjs +1 -1
  75. package/dist/webhooks.mjs.map +1 -1
  76. package/package.json +1 -1
package/dist/auth.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { X as NeetruClientConfig, W as NeetruClient } from './types-Dw0fqhHm.cjs';
1
+ import { X as NeetruClientConfig, W as NeetruClient } from './types-DIVZl7nO.cjs';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.cjs';
4
4
 
@@ -25,5 +25,56 @@ declare function __resetJwksCacheForTests(): void;
25
25
  * @throws {NeetruError} `invalid_config` se fetch não disponível no runtime.
26
26
  */
27
27
  declare function createNeetruClient(config?: NeetruClientConfig): NeetruClient;
28
+ /**
29
+ * Singleton server-side de `NeetruClient`, cacheado via `globalThis`.
30
+ *
31
+ * bug_d0d4e5bf: `client.db` server-side (Node.js, sem IndexedDB) cai em
32
+ * `MemoryStore` — um store 100% em memória, isolado POR INSTÂNCIA de client.
33
+ * Chamar `createNeetruClient(...)` mais de uma vez (ex.: uma vez por Server
34
+ * Action, outra por Route Handler) cria MemoryStores diferentes e ISOLADOS:
35
+ * um `set()` numa instância nunca fica visível pra um `get()`/`onSnapshot()`
36
+ * noutra, mesmo dentro do MESMO processo Node — não é um bug de rede nem de
37
+ * timing, é ausência de estado compartilhado.
38
+ *
39
+ * Use esta função em vez de `createNeetruClient` direto em qualquer código
40
+ * SERVER-ONLY (Server Actions, Route Handlers, Server Components) que use
41
+ * `client.db`:
42
+ *
43
+ * ```ts
44
+ * import { getServerNeetruClient } from '@neetru/sdk';
45
+ *
46
+ * export async function myServerAction() {
47
+ * const client = getServerNeetruClient({ apiKey: process.env.NEETRU_API_KEY });
48
+ * await client.db.collection('orders').set('123', { status: 'paid' });
49
+ * }
50
+ *
51
+ * export async function GET() {
52
+ * const client = getServerNeetruClient(); // config já cacheada, argumento ignorado
53
+ * const order = await client.db.collection('orders').get('123');
54
+ * // ...
55
+ * }
56
+ * ```
57
+ *
58
+ * `config` só é lida na PRIMEIRA chamada (cria a instância); chamadas
59
+ * subsequentes a ignoram e devolvem a instância já cacheada — o padrão
60
+ * esperado é config ESTÁTICA por processo (lida de env vars no boot), não
61
+ * variável por-request. Se o produto precisa de múltiplos clients com config
62
+ * diferente no mesmo processo (raro), use `createNeetruClient` direto e
63
+ * gerencie o cache você mesmo.
64
+ *
65
+ * NÃO é necessário (nem recomendado) em código client-side (browser): lá o
66
+ * `IndexedDB` real persiste entre chamadas do jeito esperado, e o padrão
67
+ * usual é criar o client uma vez num Provider/Context React.
68
+ *
69
+ * @throws {NeetruError} `invalid_config` se `fetch` não disponível no runtime
70
+ * (mesma validação de `createNeetruClient`, só na primeira chamada).
71
+ */
72
+ declare function getServerNeetruClient(config?: NeetruClientConfig): NeetruClient;
73
+ /**
74
+ * @internal Reseta o singleton server-side cacheado via `globalThis`.
75
+ * Uso exclusivo de testes — evita vazamento de estado entre `it()` blocks
76
+ * que chamam `getServerNeetruClient`.
77
+ */
78
+ declare function __resetServerNeetruClientForTests(): void;
28
79
 
29
- export { __resetJwksCacheForTests, createNeetruClient };
80
+ export { __resetJwksCacheForTests, __resetServerNeetruClientForTests, createNeetruClient, getServerNeetruClient };
package/dist/auth.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { X as NeetruClientConfig, W as NeetruClient } from './types-Bzxb5rlF.js';
1
+ import { X as NeetruClientConfig, W as NeetruClient } from './types-nnztVk7G.js';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.js';
4
4
 
@@ -25,5 +25,56 @@ declare function __resetJwksCacheForTests(): void;
25
25
  * @throws {NeetruError} `invalid_config` se fetch não disponível no runtime.
26
26
  */
27
27
  declare function createNeetruClient(config?: NeetruClientConfig): NeetruClient;
28
+ /**
29
+ * Singleton server-side de `NeetruClient`, cacheado via `globalThis`.
30
+ *
31
+ * bug_d0d4e5bf: `client.db` server-side (Node.js, sem IndexedDB) cai em
32
+ * `MemoryStore` — um store 100% em memória, isolado POR INSTÂNCIA de client.
33
+ * Chamar `createNeetruClient(...)` mais de uma vez (ex.: uma vez por Server
34
+ * Action, outra por Route Handler) cria MemoryStores diferentes e ISOLADOS:
35
+ * um `set()` numa instância nunca fica visível pra um `get()`/`onSnapshot()`
36
+ * noutra, mesmo dentro do MESMO processo Node — não é um bug de rede nem de
37
+ * timing, é ausência de estado compartilhado.
38
+ *
39
+ * Use esta função em vez de `createNeetruClient` direto em qualquer código
40
+ * SERVER-ONLY (Server Actions, Route Handlers, Server Components) que use
41
+ * `client.db`:
42
+ *
43
+ * ```ts
44
+ * import { getServerNeetruClient } from '@neetru/sdk';
45
+ *
46
+ * export async function myServerAction() {
47
+ * const client = getServerNeetruClient({ apiKey: process.env.NEETRU_API_KEY });
48
+ * await client.db.collection('orders').set('123', { status: 'paid' });
49
+ * }
50
+ *
51
+ * export async function GET() {
52
+ * const client = getServerNeetruClient(); // config já cacheada, argumento ignorado
53
+ * const order = await client.db.collection('orders').get('123');
54
+ * // ...
55
+ * }
56
+ * ```
57
+ *
58
+ * `config` só é lida na PRIMEIRA chamada (cria a instância); chamadas
59
+ * subsequentes a ignoram e devolvem a instância já cacheada — o padrão
60
+ * esperado é config ESTÁTICA por processo (lida de env vars no boot), não
61
+ * variável por-request. Se o produto precisa de múltiplos clients com config
62
+ * diferente no mesmo processo (raro), use `createNeetruClient` direto e
63
+ * gerencie o cache você mesmo.
64
+ *
65
+ * NÃO é necessário (nem recomendado) em código client-side (browser): lá o
66
+ * `IndexedDB` real persiste entre chamadas do jeito esperado, e o padrão
67
+ * usual é criar o client uma vez num Provider/Context React.
68
+ *
69
+ * @throws {NeetruError} `invalid_config` se `fetch` não disponível no runtime
70
+ * (mesma validação de `createNeetruClient`, só na primeira chamada).
71
+ */
72
+ declare function getServerNeetruClient(config?: NeetruClientConfig): NeetruClient;
73
+ /**
74
+ * @internal Reseta o singleton server-side cacheado via `globalThis`.
75
+ * Uso exclusivo de testes — evita vazamento de estado entre `it()` blocks
76
+ * que chamam `getServerNeetruClient`.
77
+ */
78
+ declare function __resetServerNeetruClientForTests(): void;
28
79
 
29
- export { __resetJwksCacheForTests, createNeetruClient };
80
+ export { __resetJwksCacheForTests, __resetServerNeetruClientForTests, createNeetruClient, getServerNeetruClient };
package/dist/auth.mjs CHANGED
@@ -1189,80 +1189,28 @@ function createCatalogNamespace(config) {
1189
1189
 
1190
1190
  // src/entitlements.ts
1191
1191
  init_errors();
1192
- init_http();
1193
- function toEntitlementCheck(raw) {
1194
- if (!raw || typeof raw !== "object") {
1195
- throw new NeetruError("invalid_response", "Entitlement response is not an object");
1196
- }
1197
- const r = raw;
1198
- if (typeof r.allowed !== "boolean") {
1199
- throw new NeetruError("invalid_response", "Entitlement response missing `allowed` boolean");
1200
- }
1201
- return {
1202
- allowed: r.allowed,
1203
- productSlug: typeof r.productSlug === "string" ? r.productSlug : "",
1204
- feature: typeof r.feature === "string" ? r.feature : "",
1205
- reason: typeof r.reason === "string" ? r.reason : void 0
1206
- };
1192
+ var DEPRECATION_MESSAGE = "client.entitlements.check()/checkDetailed() est\xE3o DEPRECADOS \u2014 apontavam para GET /api/v1/sdk/entitlements/check, um endpoint que o Core nunca escreve (sempre retornava not_subscribed). Use client.usage.check(resource, { productId, tenantId }) no lugar \u2014 mesmo resultado (allowed/reason/remaining/limit/behavior), endpoint real.";
1193
+ function throwDeprecated() {
1194
+ throw new NeetruError("validation_failed", DEPRECATION_MESSAGE);
1207
1195
  }
1208
- var CACHE_TTL_MS = 6e4;
1209
- var CACHE_MAX = 100;
1210
- function createEntitlementsNamespace(config) {
1211
- const cache = /* @__PURE__ */ new Map();
1212
- function cacheKey(productSlug, feature) {
1213
- return `${productSlug}::${feature}`;
1214
- }
1215
- function readCache(key) {
1216
- const entry = cache.get(key);
1217
- if (!entry) return null;
1218
- if (entry.expiresAt < Date.now()) {
1219
- cache.delete(key);
1220
- return null;
1221
- }
1222
- cache.delete(key);
1223
- cache.set(key, entry);
1224
- return entry.value;
1225
- }
1226
- function writeCache(key, value) {
1227
- if (cache.size >= CACHE_MAX) {
1228
- const oldest = cache.keys().next().value;
1229
- if (oldest !== void 0) cache.delete(oldest);
1230
- }
1231
- cache.set(key, { value, expiresAt: Date.now() + CACHE_TTL_MS });
1232
- }
1233
- async function checkDetailed(productSlug, feature, opts = {}) {
1234
- if (!productSlug) throw new NeetruError("validation_failed", "productSlug is required");
1235
- if (!feature) throw new NeetruError("validation_failed", "feature is required");
1236
- const key = cacheKey(productSlug, feature);
1237
- if (!opts.cacheBust) {
1238
- const cached = readCache(key);
1239
- if (cached) return cached;
1240
- }
1241
- const raw = await httpRequest(config, {
1242
- method: "GET",
1243
- path: "/api/v1/sdk/entitlements/check",
1244
- query: { slug: productSlug, feature },
1245
- requireAuth: true
1246
- });
1247
- const result = toEntitlementCheck(raw);
1248
- writeCache(key, result);
1249
- return result;
1250
- }
1196
+ function createEntitlementsNamespace(_config) {
1251
1197
  return {
1252
1198
  /**
1253
- * Verifica se o caller pode usar `feature` no produto `productSlug`.
1254
- * Retorno simples: `true` libera, `false` bloqueia. Cache 60s automático.
1255
- *
1256
- * Use `checkDetailed` se precisar do `reason` pra mensagem de upgrade.
1199
+ * @deprecated Endpoint morto no Core — sempre retornava `not_subscribed`.
1200
+ * Lança `NeetruError`. Use `client.usage.check(resource, {productId, tenantId})`.
1201
+ */
1202
+ async check(_productSlug, _feature, _opts) {
1203
+ throwDeprecated();
1204
+ },
1205
+ /**
1206
+ * @deprecated Endpoint morto no Core — sempre retornava `not_subscribed`.
1207
+ * Lança `NeetruError`. Use `client.usage.check(resource, {productId, tenantId})`.
1257
1208
  */
1258
- async check(productSlug, feature, opts) {
1259
- const result = await checkDetailed(productSlug, feature, opts);
1260
- return result.allowed;
1209
+ async checkDetailed(_productSlug, _feature, _opts) {
1210
+ throwDeprecated();
1261
1211
  },
1262
- checkDetailed,
1263
- /** Test helper: limpa o cache LRU. */
1212
+ /** Test helper legado — no-op (não há mais cache). Mantido por compat. */
1264
1213
  __resetCache() {
1265
- cache.clear();
1266
1214
  }
1267
1215
  };
1268
1216
  }
@@ -1271,6 +1219,12 @@ function createEntitlementsNamespace(config) {
1271
1219
  init_errors();
1272
1220
  init_http();
1273
1221
  var VALID_LOG_LEVELS = ["debug", "info", "warn", "error", "fatal"];
1222
+ function isBrowserContext() {
1223
+ return typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
1224
+ }
1225
+ function resolveEventTransport() {
1226
+ return isBrowserContext() ? { path: "/api/sdk/v1/telemetry/event/public", requireAuth: false } : { path: "/api/sdk/v1/telemetry/event", requireAuth: true };
1227
+ }
1274
1228
  function consoleFor(level) {
1275
1229
  switch (level) {
1276
1230
  case "debug":
@@ -1300,15 +1254,18 @@ function createTelemetryNamespace(config) {
1300
1254
  batch.map(async (ev) => {
1301
1255
  try {
1302
1256
  const body = { name: ev.name };
1257
+ const productSlug = ev.productSlug ?? config.productId;
1258
+ if (productSlug) body.productSlug = productSlug;
1303
1259
  if (ev.properties && typeof ev.properties === "object") {
1304
1260
  body.properties = ev.properties;
1305
1261
  }
1306
1262
  if (ev.timestamp) body.timestamp = ev.timestamp;
1263
+ const transport = resolveEventTransport();
1307
1264
  await httpRequest(config, {
1308
1265
  method: "POST",
1309
- path: "/api/sdk/v1/telemetry/event",
1266
+ path: transport.path,
1310
1267
  body,
1311
- requireAuth: true,
1268
+ requireAuth: transport.requireAuth,
1312
1269
  retries: 1,
1313
1270
  // caça-bruxas: retry sem Idempotency-Key duplicava o evento se o
1314
1271
  // servidor já tinha persistido antes da falha transiente. Mesmo
@@ -1361,15 +1318,18 @@ function createTelemetryNamespace(config) {
1361
1318
  throw new NeetruError("validation_failed", "event.name max 128 chars");
1362
1319
  }
1363
1320
  const body = { name: input.name };
1321
+ const productSlug = input.productSlug ?? config.productId;
1322
+ if (productSlug) body.productSlug = productSlug;
1364
1323
  if (input.properties && typeof input.properties === "object") {
1365
1324
  body.properties = input.properties;
1366
1325
  }
1367
1326
  if (input.timestamp) body.timestamp = input.timestamp;
1327
+ const transport = resolveEventTransport();
1368
1328
  const raw = await httpRequest(config, {
1369
1329
  method: "POST",
1370
- path: "/api/sdk/v1/telemetry/event",
1330
+ path: transport.path,
1371
1331
  body,
1372
- requireAuth: true
1332
+ requireAuth: transport.requireAuth
1373
1333
  });
1374
1334
  if (!raw || raw.ok !== true || typeof raw.eventId !== "string") {
1375
1335
  throw new NeetruError("invalid_response", "Telemetry response missing eventId");
@@ -1488,7 +1448,7 @@ init_http();
1488
1448
 
1489
1449
  // src/validators.ts
1490
1450
  init_errors();
1491
- var SDK_ID_RE = /^[a-z0-9][a-z0-9_-]{0,62}$/;
1451
+ var SDK_ID_RE = /^[a-z0-9][a-z0-9_-]{0,62}$/i;
1492
1452
  function assertValidSdkId(field, value) {
1493
1453
  if (typeof value !== "string" || !SDK_ID_RE.test(value)) {
1494
1454
  throw new NeetruError(
@@ -7606,7 +7566,7 @@ function createNeetruClient(config = {}) {
7606
7566
  const auth = config.mocks?.auth ?? (isDev ? new MockAuth({ ...DEV_FIXTURE_USER }) : createOidcAuthNamespace(resolved));
7607
7567
  const usage = config.mocks?.usage ?? (isDev ? new MockUsage() : createUsageNamespace(resolved));
7608
7568
  const support = config.mocks?.support ?? (isDev ? new MockSupport() : createSupportNamespace(resolved));
7609
- const entitlements = config.mocks?.entitlements ?? (isDev ? new MockEntitlements() : createEntitlementsNamespace(resolved));
7569
+ const entitlements = config.mocks?.entitlements ?? (isDev ? new MockEntitlements() : createEntitlementsNamespace());
7610
7570
  const db = config.mocks?.db ?? createNeetruDb(resolved, config.db);
7611
7571
  const webhooks = config.mocks?.webhooks ?? (isDev ? new MockWebhooks() : createWebhooksNamespace(resolved));
7612
7572
  const notifications = config.mocks?.notifications ?? (isDev ? new MockNotifications() : createNotificationsNamespace(resolved));
@@ -7627,7 +7587,18 @@ function createNeetruClient(config = {}) {
7627
7587
  });
7628
7588
  return client;
7629
7589
  }
7590
+ var NEETRU_SERVER_CLIENT_KEY = /* @__PURE__ */ Symbol.for("@neetru/sdk:serverClient");
7591
+ function getServerNeetruClient(config = {}) {
7592
+ const g = globalThis;
7593
+ if (!g[NEETRU_SERVER_CLIENT_KEY]) {
7594
+ g[NEETRU_SERVER_CLIENT_KEY] = createNeetruClient(config);
7595
+ }
7596
+ return g[NEETRU_SERVER_CLIENT_KEY];
7597
+ }
7598
+ function __resetServerNeetruClientForTests() {
7599
+ delete globalThis[NEETRU_SERVER_CLIENT_KEY];
7600
+ }
7630
7601
 
7631
- export { __resetJwksCacheForTests, createNeetruClient };
7602
+ export { __resetJwksCacheForTests, __resetServerNeetruClientForTests, createNeetruClient, getServerNeetruClient };
7632
7603
  //# sourceMappingURL=auth.mjs.map
7633
7604
  //# sourceMappingURL=auth.mjs.map