@neetru/sdk 3.4.6 → 3.5.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 (88) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/ai.cjs +17 -13
  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 +17 -13
  7. package/dist/ai.mjs.map +1 -1
  8. package/dist/auth.cjs +57 -23
  9. package/dist/auth.cjs.map +1 -1
  10. package/dist/auth.d.cts +2 -2
  11. package/dist/auth.d.ts +2 -2
  12. package/dist/auth.mjs +57 -23
  13. package/dist/auth.mjs.map +1 -1
  14. package/dist/catalog.cjs +19 -4
  15. package/dist/catalog.cjs.map +1 -1
  16. package/dist/catalog.d.cts +1 -1
  17. package/dist/catalog.d.ts +1 -1
  18. package/dist/catalog.mjs +19 -4
  19. package/dist/catalog.mjs.map +1 -1
  20. package/dist/checkout.cjs +11 -3
  21. package/dist/checkout.cjs.map +1 -1
  22. package/dist/checkout.d.cts +1 -1
  23. package/dist/checkout.d.ts +1 -1
  24. package/dist/checkout.mjs +11 -3
  25. package/dist/checkout.mjs.map +1 -1
  26. package/dist/db-react.d.cts +1 -1
  27. package/dist/db-react.d.ts +1 -1
  28. package/dist/db.cjs +17 -7
  29. package/dist/db.cjs.map +1 -1
  30. package/dist/db.d.cts +1 -1
  31. package/dist/db.d.ts +1 -1
  32. package/dist/db.mjs +17 -7
  33. package/dist/db.mjs.map +1 -1
  34. package/dist/entitlements.d.cts +1 -1
  35. package/dist/entitlements.d.ts +1 -1
  36. package/dist/firestore-compat.d.cts +1 -1
  37. package/dist/firestore-compat.d.ts +1 -1
  38. package/dist/index.cjs +58 -24
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.cts +30 -2
  41. package/dist/index.d.ts +30 -2
  42. package/dist/index.mjs +58 -24
  43. package/dist/index.mjs.map +1 -1
  44. package/dist/mocks.cjs +17 -0
  45. package/dist/mocks.cjs.map +1 -1
  46. package/dist/mocks.d.cts +5 -1
  47. package/dist/mocks.d.ts +5 -1
  48. package/dist/mocks.mjs +17 -0
  49. package/dist/mocks.mjs.map +1 -1
  50. package/dist/notifications.cjs +11 -3
  51. package/dist/notifications.cjs.map +1 -1
  52. package/dist/notifications.d.cts +1 -1
  53. package/dist/notifications.d.ts +1 -1
  54. package/dist/notifications.mjs +11 -3
  55. package/dist/notifications.mjs.map +1 -1
  56. package/dist/react.cjs +52 -2
  57. package/dist/react.cjs.map +1 -1
  58. package/dist/react.d.cts +1 -1
  59. package/dist/react.d.ts +1 -1
  60. package/dist/react.mjs +52 -2
  61. package/dist/react.mjs.map +1 -1
  62. package/dist/support.cjs +15 -4
  63. package/dist/support.cjs.map +1 -1
  64. package/dist/support.d.cts +1 -1
  65. package/dist/support.d.ts +1 -1
  66. package/dist/support.mjs +15 -4
  67. package/dist/support.mjs.map +1 -1
  68. package/dist/telemetry.cjs +11 -3
  69. package/dist/telemetry.cjs.map +1 -1
  70. package/dist/telemetry.d.cts +1 -1
  71. package/dist/telemetry.d.ts +1 -1
  72. package/dist/telemetry.mjs +11 -3
  73. package/dist/telemetry.mjs.map +1 -1
  74. package/dist/{types-nnztVk7G.d.ts → types-BPATkXYu.d.ts} +35 -7
  75. package/dist/{types-DIVZl7nO.d.cts → types-Du_iioJ7.d.cts} +35 -7
  76. package/dist/usage.cjs +11 -3
  77. package/dist/usage.cjs.map +1 -1
  78. package/dist/usage.d.cts +1 -1
  79. package/dist/usage.d.ts +1 -1
  80. package/dist/usage.mjs +11 -3
  81. package/dist/usage.mjs.map +1 -1
  82. package/dist/webhooks.cjs +17 -4
  83. package/dist/webhooks.cjs.map +1 -1
  84. package/dist/webhooks.d.cts +1 -1
  85. package/dist/webhooks.d.ts +1 -1
  86. package/dist/webhooks.mjs +17 -4
  87. package/dist/webhooks.mjs.map +1 -1
  88. package/package.json +4 -1
package/dist/auth.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { X as NeetruClientConfig, W as NeetruClient } from './types-DIVZl7nO.cjs';
1
+ import { X as NeetruClientConfig, W as NeetruClient } from './types-Du_iioJ7.cjs';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.cjs';
4
4
 
@@ -18,7 +18,7 @@ declare function __resetJwksCacheForTests(): void;
18
18
  * const { products } = await client.catalog.list();
19
19
  * const can = await client.entitlements.check('neetru-pulse', 'export-pdf');
20
20
  * await client.telemetry.event({ name: 'report_exported' });
21
- * await client.usage.track('api_call', { route: '/x' });
21
+ * await client.usage.report('api_call', 1);
22
22
  * await client.support.createTicket({ subject: 'help', message: '...' });
23
23
  * ```
24
24
  *
package/dist/auth.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { X as NeetruClientConfig, W as NeetruClient } from './types-nnztVk7G.js';
1
+ import { X as NeetruClientConfig, W as NeetruClient } from './types-BPATkXYu.js';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.js';
4
4
 
@@ -18,7 +18,7 @@ declare function __resetJwksCacheForTests(): void;
18
18
  * const { products } = await client.catalog.list();
19
19
  * const can = await client.entitlements.check('neetru-pulse', 'export-pdf');
20
20
  * await client.telemetry.event({ name: 'report_exported' });
21
- * await client.usage.track('api_call', { route: '/x' });
21
+ * await client.usage.report('api_call', 1);
22
22
  * await client.support.createTicket({ subject: 'help', message: '...' });
23
23
  * ```
24
24
  *
package/dist/auth.mjs CHANGED
@@ -62,7 +62,8 @@ var init_idempotency = __esm({
62
62
  var http_exports = {};
63
63
  __export(http_exports, {
64
64
  checkCoreVersionCompat: () => checkCoreVersionCompat,
65
- httpRequest: () => httpRequest
65
+ httpRequest: () => httpRequest,
66
+ statusToCode: () => statusToCode
66
67
  });
67
68
  function stripRevision(v) {
68
69
  return v.split("+")[0] ?? v;
@@ -78,12 +79,16 @@ function compareCalVer(a, b) {
78
79
  }
79
80
  return 0;
80
81
  }
81
- function getSdkMajor() {
82
+ function readInjectedSdkVersion() {
82
83
  try {
83
- const ver = globalThis.__NEETRU_SDK_VERSION__;
84
- if (ver) return parseInt(ver.split(".")[0] ?? "3", 10);
84
+ return "3.5.0";
85
85
  } catch {
86
+ return void 0;
86
87
  }
88
+ }
89
+ function getSdkMajor() {
90
+ const ver = readInjectedSdkVersion();
91
+ if (ver) return parseInt(ver.split(".")[0] ?? "3", 10);
87
92
  return 3;
88
93
  }
89
94
  function checkCoreVersionCompat(coreVersion) {
@@ -161,6 +166,10 @@ async function httpRequest(config, opts) {
161
166
  accept: "application/json",
162
167
  ...opts.headers
163
168
  };
169
+ const sdkVersion = readInjectedSdkVersion();
170
+ if (sdkVersion) {
171
+ headers["x-neetru-sdk-version"] = sdkVersion;
172
+ }
164
173
  if (opts.requireAuth) {
165
174
  if (!config.apiKey) {
166
175
  throw new NeetruError(
@@ -525,7 +534,7 @@ var init_lease = __esm({
525
534
  void this._doRenew();
526
535
  }, MIN_RENEWAL_DELAY_MS);
527
536
  console.warn(
528
- `[SqlLeaseManager] renova\xE7\xE3o E emiss\xE3o de lease novo falharam; re-tentando em ${MIN_RENEWAL_DELAY_MS}ms (cert mTLS expira ~15min ap\xF3s o \xFAltimo swap):`,
537
+ `[SqlLeaseManager] renova\xE7\xE3o E emiss\xE3o de lease novo falharam; re-tentando em ${MIN_RENEWAL_DELAY_MS}ms (cert TLS ef\xEAmero do servidor expira ~15min ap\xF3s o \xFAltimo swap):`,
529
538
  err instanceof Error ? err.message : err
530
539
  );
531
540
  return;
@@ -536,8 +545,9 @@ var init_lease = __esm({
536
545
  /**
537
546
  * Recuperação REATIVA: chamado pelo wrapper resiliente (`resilient-pool.ts`)
538
547
  * quando uma query plana falha num erro de ESTABELECIMENTO de conexão (cert
539
- * mTLS expirado no meio de uma request, ou timer de renovação que não
540
- * disparou). Emite um lease NOVO e faz o swap do pool interno do wrapper com
548
+ * TLS efêmero do servidor expirado no meio de uma request, ou timer de
549
+ * renovação que não disparou). Emite um lease NOVO e faz o swap do pool interno
550
+ * do wrapper com
541
551
  * o certificado fresco; o wrapper então re-tenta a query 1x no pool novo.
542
552
  *
543
553
  * Vai DIRETO ao lease novo (sem `leaseId`) — a conexão falhou porque o
@@ -1137,7 +1147,14 @@ function toProduct(raw) {
1137
1147
  if (Array.isArray(r.plans)) {
1138
1148
  product.plans = r.plans.filter(
1139
1149
  (p) => typeof p === "object" && p !== null && typeof p.id === "string" && typeof p.name === "string"
1140
- );
1150
+ ).map((p) => {
1151
+ const plan = { id: p.id, name: p.name };
1152
+ if (typeof p.amountCents === "number") plan.amountCents = p.amountCents;
1153
+ if (Array.isArray(p.features) && p.features.every((f) => typeof f === "string")) {
1154
+ plan.features = p.features;
1155
+ }
1156
+ return plan;
1157
+ });
1141
1158
  }
1142
1159
  return product;
1143
1160
  }
@@ -1717,7 +1734,10 @@ function createSupportNamespace(config) {
1717
1734
  await httpRequest(config, {
1718
1735
  method: "POST",
1719
1736
  path: `/api/sdk/v1/support/tickets/${encodeURIComponent(ticketId)}/satisfaction-attempt`,
1720
- requireAuth: true
1737
+ requireAuth: true,
1738
+ // Incrementa satisfactionAttempts += 1 no Core — sem idempotencyKey,
1739
+ // um retry de rede infla o contador (mesmo padrão de createTicket acima).
1740
+ idempotencyKey: true
1721
1741
  });
1722
1742
  },
1723
1743
  /**
@@ -5822,7 +5842,12 @@ function createWebhooksNamespace(config) {
5822
5842
  events: input.events,
5823
5843
  ...input.secret ? { secret: input.secret } : {}
5824
5844
  },
5825
- requireAuth: true
5845
+ requireAuth: true,
5846
+ // Sem isso, um retry de rede (app-level; SDK default é 0 retries em
5847
+ // POST) podia registrar o MESMO webhook duas vezes → entrega
5848
+ // duplicada de todo evento futuro pro endpoint do cliente. Core
5849
+ // dedup TTL 24h (mesmo padrão de usage.report/support.createTicket).
5850
+ idempotencyKey: true
5826
5851
  });
5827
5852
  return toEndpoint(raw);
5828
5853
  },
@@ -6375,16 +6400,6 @@ async function safeJson2(res) {
6375
6400
  return void 0;
6376
6401
  }
6377
6402
  }
6378
- function statusToCode2(status) {
6379
- if (status === 401) return "unauthorized";
6380
- if (status === 403) return "forbidden";
6381
- if (status === 404) return "not_found";
6382
- if (status === 409) return "conflict";
6383
- if (status === 422 || status === 400) return "validation_failed";
6384
- if (status === 429) return "rate_limited";
6385
- if (status >= 500) return "server_error";
6386
- return "unknown";
6387
- }
6388
6403
  function joinUrl(baseUrl, path) {
6389
6404
  const base = baseUrl.replace(/\/+$/, "");
6390
6405
  const p = path.startsWith("/") ? path : `/${path}`;
@@ -6419,7 +6434,7 @@ async function aiFetch(config, body, signal, stream) {
6419
6434
  const requestId = res.headers.get("x-request-id") ?? res.headers.get("x-correlation-id") ?? void 0;
6420
6435
  if (!res.ok) {
6421
6436
  const parsed = await safeJson2(res);
6422
- let code = statusToCode2(res.status);
6437
+ let code = statusToCode(res.status);
6423
6438
  let message = `HTTP ${res.status}`;
6424
6439
  if (parsed && typeof parsed === "object" && "error" in parsed) {
6425
6440
  const errField = parsed.error;
@@ -6537,6 +6552,19 @@ function createAiNamespace(config) {
6537
6552
 
6538
6553
  // src/mocks.ts
6539
6554
  init_errors();
6555
+
6556
+ // src/runtime-env.ts
6557
+ function isProductionRuntime() {
6558
+ try {
6559
+ if (typeof process !== "undefined" && process.env) {
6560
+ return process.env.NODE_ENV === "production";
6561
+ }
6562
+ } catch {
6563
+ }
6564
+ return false;
6565
+ }
6566
+
6567
+ // src/mocks.ts
6540
6568
  var DEV_FIXTURE_USER = Object.freeze({
6541
6569
  uid: "dev-fixture-uid-0001",
6542
6570
  email: "dev@neetru.local",
@@ -6553,6 +6581,12 @@ var MockAuth = class {
6553
6581
  this._user = initialUser;
6554
6582
  this._listeners = /* @__PURE__ */ new Set();
6555
6583
  this._allowUnsignedDecode = options?.allowUnsignedDecode ?? false;
6584
+ if (this._allowUnsignedDecode && isProductionRuntime()) {
6585
+ throw new NeetruError(
6586
+ "invalid_config",
6587
+ "MockAuth com allowUnsignedDecode=true \xE9 PROIBIDO em produ\xE7\xE3o (NODE_ENV=production): decodificar JWT sem verificar assinatura \xE9 bypass de autentica\xE7\xE3o. Este modo existe exclusivamente para testes."
6588
+ );
6589
+ }
6556
6590
  if (this._allowUnsignedDecode) {
6557
6591
  const isTestEnv = typeof process !== "undefined" && (process.env?.NODE_ENV === "test" || process.env?.VITEST === "true" || process.env?.VITEST != null);
6558
6592
  if (!isTestEnv && typeof console !== "undefined") {
@@ -6974,7 +7008,7 @@ function resolveEnv(configEnv) {
6974
7008
  }
6975
7009
  try {
6976
7010
  const g = globalThis.NEETRU_ENV;
6977
- if (g === "dev" || g === "workspace" || g === "prod") return g;
7011
+ if (g === "workspace" || g === "prod") return g;
6978
7012
  } catch {
6979
7013
  }
6980
7014
  return "prod";
@@ -7562,7 +7596,7 @@ function createNeetruClient(config = {}) {
7562
7596
  productId: config.productId,
7563
7597
  tenantId: config.tenantId
7564
7598
  });
7565
- const isDev = env === "dev";
7599
+ const isDev = env === "dev" && !isProductionRuntime();
7566
7600
  const auth = config.mocks?.auth ?? (isDev ? new MockAuth({ ...DEV_FIXTURE_USER }) : createOidcAuthNamespace(resolved));
7567
7601
  const usage = config.mocks?.usage ?? (isDev ? new MockUsage() : createUsageNamespace(resolved));
7568
7602
  const support = config.mocks?.support ?? (isDev ? new MockSupport() : createSupportNamespace(resolved));