@neetru/sdk 3.3.0 → 3.4.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 (56) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/ai.d.cts +1 -1
  3. package/dist/ai.d.ts +1 -1
  4. package/dist/auth.cjs +179 -2
  5. package/dist/auth.cjs.map +1 -1
  6. package/dist/auth.d.cts +1 -1
  7. package/dist/auth.d.ts +1 -1
  8. package/dist/auth.mjs +179 -2
  9. package/dist/auth.mjs.map +1 -1
  10. package/dist/catalog.d.cts +1 -1
  11. package/dist/catalog.d.ts +1 -1
  12. package/dist/checkout.d.cts +1 -1
  13. package/dist/checkout.d.ts +1 -1
  14. package/dist/db-react.d.cts +1 -1
  15. package/dist/db-react.d.ts +1 -1
  16. package/dist/db.cjs +17 -0
  17. package/dist/db.cjs.map +1 -1
  18. package/dist/db.d.cts +1 -1
  19. package/dist/db.d.ts +1 -1
  20. package/dist/db.mjs +17 -1
  21. package/dist/db.mjs.map +1 -1
  22. package/dist/entitlements.d.cts +1 -1
  23. package/dist/entitlements.d.ts +1 -1
  24. package/dist/firestore-compat.d.cts +1 -1
  25. package/dist/firestore-compat.d.ts +1 -1
  26. package/dist/index.cjs +180 -3
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +2 -2
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.mjs +180 -3
  31. package/dist/index.mjs.map +1 -1
  32. package/dist/mocks.cjs +68 -1
  33. package/dist/mocks.cjs.map +1 -1
  34. package/dist/mocks.d.cts +17 -1
  35. package/dist/mocks.d.ts +17 -1
  36. package/dist/mocks.mjs +68 -1
  37. package/dist/mocks.mjs.map +1 -1
  38. package/dist/notifications.d.cts +1 -1
  39. package/dist/notifications.d.ts +1 -1
  40. package/dist/react.d.cts +1 -1
  41. package/dist/react.d.ts +1 -1
  42. package/dist/support.cjs +98 -1
  43. package/dist/support.cjs.map +1 -1
  44. package/dist/support.d.cts +1 -1
  45. package/dist/support.d.ts +1 -1
  46. package/dist/support.mjs +98 -1
  47. package/dist/support.mjs.map +1 -1
  48. package/dist/telemetry.d.cts +1 -1
  49. package/dist/telemetry.d.ts +1 -1
  50. package/dist/{types-DQplLXIk.d.cts → types-BoFSCHF_.d.cts} +117 -2
  51. package/dist/{types-DslphKIM.d.ts → types-DdJyqBy-.d.ts} +117 -2
  52. package/dist/usage.d.cts +1 -1
  53. package/dist/usage.d.ts +1 -1
  54. package/dist/webhooks.d.cts +1 -1
  55. package/dist/webhooks.d.ts +1 -1
  56. package/package.json +1 -1
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { createNeetruClient } from './auth.cjs';
2
2
  export { NeetruError, NeetruErrorCode } from './errors.cjs';
3
- export { A as AiChatChoice, a as AiChatMessage, b as AiChatOptions, c as AiChatResult, d as AiChatUsage, e as AiContentPart, f as AiImageUrlPart, g as AiNamespace, h as AiResponseFormat, i as AiStreamHandle, j as AiStreamMeta, k as AiTextPart, l as AuthNamespace, m as AuthStateListener, C as CatalogListOptions, n as CatalogListResponse, p as CheckoutIntentInfo, q as CheckoutIntentStatus, r as CheckoutNamespace, s as CheckoutStartInput, t as CheckoutStartResult, u as CheckoutTenantType, v as CompleteSignInResult, y as CreateTicketInput, D as DEFAULT_BASE_URL, z as DbBatchOp, B as DbChangeType, E as DbCollectionRef, F as DbDoc, G as DbDocRef, H as DbGetResult, I as DbListResult, J as DbNamespace, K as DbQuery, L as DbSqlLease, M as DbWhereFilter, O as EntitlementCheck, P as FieldSentinel, Q as IncrementSentinel, R as ListNotificationsOptions, S as MockCheckout, T as MockNotifications, U as MockWebhooks, V as NEETRU_SENTINEL_KEY, W as NeetruClient, X as NeetruClientConfig, Y as NeetruDb, _ as NeetruDbEngine, $ as NeetruDbError, a0 as NeetruDbErrorCode, a1 as NeetruDbOptions, a2 as NeetruDbTransport, a3 as NeetruEnv, a4 as NeetruSqlClient, a5 as NeetruUser, a6 as NotificationScopeOptions, a7 as NotificationsNamespace, a8 as Product, a9 as ProductNotification, aa as ProductNotificationSeverity, ab as ProductPlan, ac as ProductStatus, ae as RedirectCallbackResult, af as RegisterWebhookInput, ag as ResolvedConfig, ah as SendNotificationInput, ai as ServerTimestampSentinel, aj as SignInOptions, al as SupportNamespace, am as SupportSeverity, an as SupportStatus, ao as SupportTicket, aq as TelemetryEventAck, ar as TelemetryEventInput, av as UsageEventInput, aw as UsageNamespace, ax as UsageQuota, ay as VerifyTokenOptions, az as VerifyWebhookRequestOptions, aA as VerifyWebhookRequestResult, aB as WebhookEndpoint, aC as WebhookEvent, aD as WebhookScopeOptions, aE as WebhookTestResult, aF as WebhooksNamespace, aG as WithFieldSentinels, aH as createAiNamespace, aI as createCheckoutNamespace, aJ as createNeetruDb, aK as createNotificationsNamespace, aM as createWebhooksNamespace, aO as increment, aP as isFieldSentinel, aQ as isIncrementSentinel, aR as isServerTimestampSentinel, aS as serverTimestamp, aT as verifyWebhookRequest, aU as verifyWebhookSignature } from './types-DQplLXIk.cjs';
3
+ export { A as AiChatChoice, a as AiChatMessage, b as AiChatOptions, c as AiChatResult, d as AiChatUsage, e as AiContentPart, f as AiImageUrlPart, g as AiNamespace, h as AiResponseFormat, i as AiStreamHandle, j as AiStreamMeta, k as AiTextPart, l as AuthNamespace, m as AuthStateListener, C as CatalogListOptions, n as CatalogListResponse, p as CheckoutIntentInfo, q as CheckoutIntentStatus, r as CheckoutNamespace, s as CheckoutStartInput, t as CheckoutStartResult, u as CheckoutTenantType, v as CompleteSignInResult, y as CreateTicketInput, D as DEFAULT_BASE_URL, z as DbBatchOp, B as DbChangeType, E as DbCollectionRef, F as DbDoc, G as DbDocRef, H as DbGetResult, I as DbListResult, J as DbNamespace, K as DbQuery, L as DbSqlLease, M as DbWhereFilter, O as EntitlementCheck, P as FieldSentinel, Q as IncrementSentinel, R as ListNotificationsOptions, S as MockCheckout, T as MockNotifications, U as MockWebhooks, V as NEETRU_SENTINEL_KEY, W as NeetruClient, X as NeetruClientConfig, Y as NeetruDb, _ as NeetruDbEngine, $ as NeetruDbError, a0 as NeetruDbErrorCode, a1 as NeetruDbOptions, a2 as NeetruDbTransport, a3 as NeetruEnv, a4 as NeetruSqlClient, a5 as NeetruUser, a6 as NotificationScopeOptions, a7 as NotificationsNamespace, a8 as Product, a9 as ProductNotification, aa as ProductNotificationSeverity, ab as ProductPlan, ac as ProductStatus, ae as RedirectCallbackResult, af as RegisterWebhookInput, ag as ResolvedConfig, ah as SendNotificationInput, ai as ServerTimestampSentinel, aj as SignInOptions, al as SupportNamespace, am as SupportSeverity, an as SupportStatus, ao as SupportTicket, aq as TelemetryEventAck, ar as TelemetryEventInput, av as UsageEventInput, aw as UsageNamespace, ax as UsageQuota, ay as VerifyTokenOptions, az as VerifyWebhookRequestOptions, aA as VerifyWebhookRequestResult, aB as WebhookEndpoint, aC as WebhookEvent, aD as WebhookScopeOptions, aE as WebhookTestResult, aF as WebhooksNamespace, aG as WithFieldSentinels, aI as createAiNamespace, aJ as createCheckoutNamespace, aK as createNeetruDb, aL as createNotificationsNamespace, aN as createWebhooksNamespace, aP as increment, aQ as isFieldSentinel, aR as isIncrementSentinel, aS as isServerTimestampSentinel, aT as serverTimestamp, aU as verifyWebhookRequest, aV as verifyWebhookSignature } from './types-BoFSCHF_.cjs';
4
4
  export { DEV_FIXTURE_USER, MockAi, MockAuth, MockAuthOptions, MockDb, MockEntitlements, MockSupport, MockUsage } from './mocks.cjs';
5
5
  import 'drizzle-orm/node-postgres';
6
6
 
@@ -42,6 +42,6 @@ declare function checkCoreVersionCompat(coreVersion: string): void;
42
42
  */
43
43
 
44
44
  /** Versão do SDK — exportada explicitamente pra detecção em runtime. */
45
- declare const VERSION: "3.3.0";
45
+ declare const VERSION: "3.4.0";
46
46
 
47
47
  export { VERSION, checkCoreVersionCompat };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { createNeetruClient } from './auth.js';
2
2
  export { NeetruError, NeetruErrorCode } from './errors.js';
3
- export { A as AiChatChoice, a as AiChatMessage, b as AiChatOptions, c as AiChatResult, d as AiChatUsage, e as AiContentPart, f as AiImageUrlPart, g as AiNamespace, h as AiResponseFormat, i as AiStreamHandle, j as AiStreamMeta, k as AiTextPart, l as AuthNamespace, m as AuthStateListener, C as CatalogListOptions, n as CatalogListResponse, p as CheckoutIntentInfo, q as CheckoutIntentStatus, r as CheckoutNamespace, s as CheckoutStartInput, t as CheckoutStartResult, u as CheckoutTenantType, v as CompleteSignInResult, y as CreateTicketInput, D as DEFAULT_BASE_URL, z as DbBatchOp, B as DbChangeType, E as DbCollectionRef, F as DbDoc, G as DbDocRef, H as DbGetResult, I as DbListResult, J as DbNamespace, K as DbQuery, L as DbSqlLease, M as DbWhereFilter, O as EntitlementCheck, P as FieldSentinel, Q as IncrementSentinel, R as ListNotificationsOptions, S as MockCheckout, T as MockNotifications, U as MockWebhooks, V as NEETRU_SENTINEL_KEY, W as NeetruClient, X as NeetruClientConfig, Y as NeetruDb, _ as NeetruDbEngine, $ as NeetruDbError, a0 as NeetruDbErrorCode, a1 as NeetruDbOptions, a2 as NeetruDbTransport, a3 as NeetruEnv, a4 as NeetruSqlClient, a5 as NeetruUser, a6 as NotificationScopeOptions, a7 as NotificationsNamespace, a8 as Product, a9 as ProductNotification, aa as ProductNotificationSeverity, ab as ProductPlan, ac as ProductStatus, ae as RedirectCallbackResult, af as RegisterWebhookInput, ag as ResolvedConfig, ah as SendNotificationInput, ai as ServerTimestampSentinel, aj as SignInOptions, al as SupportNamespace, am as SupportSeverity, an as SupportStatus, ao as SupportTicket, aq as TelemetryEventAck, ar as TelemetryEventInput, av as UsageEventInput, aw as UsageNamespace, ax as UsageQuota, ay as VerifyTokenOptions, az as VerifyWebhookRequestOptions, aA as VerifyWebhookRequestResult, aB as WebhookEndpoint, aC as WebhookEvent, aD as WebhookScopeOptions, aE as WebhookTestResult, aF as WebhooksNamespace, aG as WithFieldSentinels, aH as createAiNamespace, aI as createCheckoutNamespace, aJ as createNeetruDb, aK as createNotificationsNamespace, aM as createWebhooksNamespace, aO as increment, aP as isFieldSentinel, aQ as isIncrementSentinel, aR as isServerTimestampSentinel, aS as serverTimestamp, aT as verifyWebhookRequest, aU as verifyWebhookSignature } from './types-DslphKIM.js';
3
+ export { A as AiChatChoice, a as AiChatMessage, b as AiChatOptions, c as AiChatResult, d as AiChatUsage, e as AiContentPart, f as AiImageUrlPart, g as AiNamespace, h as AiResponseFormat, i as AiStreamHandle, j as AiStreamMeta, k as AiTextPart, l as AuthNamespace, m as AuthStateListener, C as CatalogListOptions, n as CatalogListResponse, p as CheckoutIntentInfo, q as CheckoutIntentStatus, r as CheckoutNamespace, s as CheckoutStartInput, t as CheckoutStartResult, u as CheckoutTenantType, v as CompleteSignInResult, y as CreateTicketInput, D as DEFAULT_BASE_URL, z as DbBatchOp, B as DbChangeType, E as DbCollectionRef, F as DbDoc, G as DbDocRef, H as DbGetResult, I as DbListResult, J as DbNamespace, K as DbQuery, L as DbSqlLease, M as DbWhereFilter, O as EntitlementCheck, P as FieldSentinel, Q as IncrementSentinel, R as ListNotificationsOptions, S as MockCheckout, T as MockNotifications, U as MockWebhooks, V as NEETRU_SENTINEL_KEY, W as NeetruClient, X as NeetruClientConfig, Y as NeetruDb, _ as NeetruDbEngine, $ as NeetruDbError, a0 as NeetruDbErrorCode, a1 as NeetruDbOptions, a2 as NeetruDbTransport, a3 as NeetruEnv, a4 as NeetruSqlClient, a5 as NeetruUser, a6 as NotificationScopeOptions, a7 as NotificationsNamespace, a8 as Product, a9 as ProductNotification, aa as ProductNotificationSeverity, ab as ProductPlan, ac as ProductStatus, ae as RedirectCallbackResult, af as RegisterWebhookInput, ag as ResolvedConfig, ah as SendNotificationInput, ai as ServerTimestampSentinel, aj as SignInOptions, al as SupportNamespace, am as SupportSeverity, an as SupportStatus, ao as SupportTicket, aq as TelemetryEventAck, ar as TelemetryEventInput, av as UsageEventInput, aw as UsageNamespace, ax as UsageQuota, ay as VerifyTokenOptions, az as VerifyWebhookRequestOptions, aA as VerifyWebhookRequestResult, aB as WebhookEndpoint, aC as WebhookEvent, aD as WebhookScopeOptions, aE as WebhookTestResult, aF as WebhooksNamespace, aG as WithFieldSentinels, aI as createAiNamespace, aJ as createCheckoutNamespace, aK as createNeetruDb, aL as createNotificationsNamespace, aN as createWebhooksNamespace, aP as increment, aQ as isFieldSentinel, aR as isIncrementSentinel, aS as isServerTimestampSentinel, aT as serverTimestamp, aU as verifyWebhookRequest, aV as verifyWebhookSignature } from './types-DdJyqBy-.js';
4
4
  export { DEV_FIXTURE_USER, MockAi, MockAuth, MockAuthOptions, MockDb, MockEntitlements, MockSupport, MockUsage } from './mocks.js';
5
5
  import 'drizzle-orm/node-postgres';
6
6
 
@@ -42,6 +42,6 @@ declare function checkCoreVersionCompat(coreVersion: string): void;
42
42
  */
43
43
 
44
44
  /** Versão do SDK — exportada explicitamente pra detecção em runtime. */
45
- declare const VERSION: "3.3.0";
45
+ declare const VERSION: "3.4.0";
46
46
 
47
47
  export { VERSION, checkCoreVersionCompat };
package/dist/index.mjs CHANGED
@@ -1582,6 +1582,7 @@ function toTicket(raw) {
1582
1582
  if (typeof r.id !== "string") {
1583
1583
  throw new NeetruError("invalid_response", "Ticket missing id");
1584
1584
  }
1585
+ const firstAttachment = Array.isArray(r.attachments) && typeof r.attachments[0] === "string" ? r.attachments[0] : void 0;
1585
1586
  return {
1586
1587
  id: r.id,
1587
1588
  subject: typeof r.subject === "string" ? r.subject : "",
@@ -1590,9 +1591,28 @@ function toTicket(raw) {
1590
1591
  status: VALID_STATUSES.includes(r.status) ? r.status : "open",
1591
1592
  createdAt: typeof r.createdAt === "string" ? r.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
1592
1593
  updatedAt: typeof r.updatedAt === "string" ? r.updatedAt : void 0,
1593
- productSlug: typeof r.productId === "string" ? r.productId : typeof r.productSlug === "string" ? r.productSlug : void 0
1594
+ productSlug: typeof r.productId === "string" ? r.productId : typeof r.productSlug === "string" ? r.productSlug : void 0,
1595
+ pageUrl: typeof r.pageUrl === "string" ? r.pageUrl : null,
1596
+ screenshotUrl: typeof r.screenshotUrl === "string" ? r.screenshotUrl : firstAttachment ?? null,
1597
+ resolvedAt: typeof r.resolvedAt === "string" ? r.resolvedAt : null,
1598
+ resolvedNotifiedAt: typeof r.resolvedNotifiedAt === "string" ? r.resolvedNotifiedAt : null,
1599
+ satisfactionAttempts: typeof r.satisfactionAttempts === "number" && Number.isFinite(r.satisfactionAttempts) ? r.satisfactionAttempts : 0,
1600
+ lastSatisfactionAttemptAt: typeof r.lastSatisfactionAttemptAt === "string" ? r.lastSatisfactionAttemptAt : null,
1601
+ satisfiedAt: typeof r.satisfiedAt === "string" ? r.satisfiedAt : null,
1602
+ rating: typeof r.rating === "number" && Number.isFinite(r.rating) ? r.rating : null,
1603
+ satisfactionComment: typeof r.satisfactionComment === "string" ? r.satisfactionComment : null
1594
1604
  };
1595
1605
  }
1606
+ function assertTicketId(ticketId) {
1607
+ if (!ticketId || typeof ticketId !== "string") {
1608
+ throw new NeetruError("validation_failed", "ticketId is required");
1609
+ }
1610
+ }
1611
+ function assertValidComment(comment) {
1612
+ if (typeof comment === "string" && comment.length > 2e3) {
1613
+ throw new NeetruError("validation_failed", "comment max 2000 chars");
1614
+ }
1615
+ }
1596
1616
  function resolveProductId(config, ...candidates) {
1597
1617
  for (const c of candidates) {
1598
1618
  if (typeof c === "string" && c.length > 0) {
@@ -1649,6 +1669,15 @@ function createSupportNamespace(config) {
1649
1669
  if (input.metadata && typeof input.metadata === "object") {
1650
1670
  body.metadata = input.metadata;
1651
1671
  }
1672
+ if (typeof input.pageUrl === "string") {
1673
+ body.pageUrl = input.pageUrl;
1674
+ }
1675
+ if (typeof input.screenshotBase64 === "string") {
1676
+ body.screenshotBase64 = input.screenshotBase64;
1677
+ }
1678
+ if (typeof input.consoleLogs === "string") {
1679
+ body.consoleLogs = input.consoleLogs;
1680
+ }
1652
1681
  const raw = await httpRequest(config, {
1653
1682
  method: "POST",
1654
1683
  path: "/api/sdk/v1/support/tickets",
@@ -1674,6 +1703,74 @@ function createSupportNamespace(config) {
1674
1703
  });
1675
1704
  const list = Array.isArray(raw) ? raw : raw && typeof raw === "object" && "tickets" in raw ? raw.tickets ?? [] : [];
1676
1705
  return list.map(toTicket);
1706
+ },
1707
+ /**
1708
+ * 3.4: marca a notificação de resolução como vista (`resolvedNotifiedAt`,
1709
+ * idempotente no Core). Endpoint canonical:
1710
+ * `POST /api/sdk/v1/support/tickets/{id}/resolved-seen`.
1711
+ */
1712
+ async markResolvedSeen(ticketId) {
1713
+ assertTicketId(ticketId);
1714
+ await httpRequest(config, {
1715
+ method: "POST",
1716
+ path: `/api/sdk/v1/support/tickets/${encodeURIComponent(ticketId)}/resolved-seen`,
1717
+ requireAuth: true
1718
+ });
1719
+ },
1720
+ /**
1721
+ * 3.4: registra uma tentativa de exibição do modal de satisfação
1722
+ * (`satisfactionAttempts += 1`). Chamar no SHOW do modal, não na
1723
+ * resposta. Endpoint canonical:
1724
+ * `POST /api/sdk/v1/support/tickets/{id}/satisfaction-attempt`.
1725
+ */
1726
+ async recordSatisfactionAttempt(ticketId) {
1727
+ assertTicketId(ticketId);
1728
+ await httpRequest(config, {
1729
+ method: "POST",
1730
+ path: `/api/sdk/v1/support/tickets/${encodeURIComponent(ticketId)}/satisfaction-attempt`,
1731
+ requireAuth: true
1732
+ });
1733
+ },
1734
+ /**
1735
+ * 3.4: envia (ou pula) a avaliação de satisfação (CSAT 1-5). Endpoint
1736
+ * canonical: `POST /api/sdk/v1/support/tickets/{id}/satisfaction`.
1737
+ */
1738
+ async submitSatisfaction(input) {
1739
+ if (!input || typeof input !== "object") {
1740
+ throw new NeetruError("validation_failed", "input is required");
1741
+ }
1742
+ assertTicketId(input.ticketId);
1743
+ if (input.rating !== null && input.rating !== void 0) {
1744
+ if (!Number.isInteger(input.rating) || input.rating < 1 || input.rating > 5) {
1745
+ throw new NeetruError("validation_failed", "rating must be an integer 1-5 or null");
1746
+ }
1747
+ }
1748
+ assertValidComment(input.comment);
1749
+ await httpRequest(config, {
1750
+ method: "POST",
1751
+ path: `/api/sdk/v1/support/tickets/${encodeURIComponent(input.ticketId)}/satisfaction`,
1752
+ body: {
1753
+ rating: input.rating ?? null,
1754
+ comment: input.comment ?? null,
1755
+ skipped: input.skipped
1756
+ },
1757
+ requireAuth: true
1758
+ });
1759
+ },
1760
+ /**
1761
+ * 3.4: contesta um ticket resolvido — reabre e zera o ciclo de
1762
+ * satisfação/notificação. Endpoint canonical:
1763
+ * `POST /api/sdk/v1/support/tickets/{id}/contest`.
1764
+ */
1765
+ async contestTicket(ticketId, opts) {
1766
+ assertTicketId(ticketId);
1767
+ assertValidComment(opts?.comment);
1768
+ await httpRequest(config, {
1769
+ method: "POST",
1770
+ path: `/api/sdk/v1/support/tickets/${encodeURIComponent(ticketId)}/contest`,
1771
+ body: { comment: opts?.comment ?? void 0 },
1772
+ requireAuth: true
1773
+ });
1677
1774
  }
1678
1775
  };
1679
1776
  }
@@ -5105,7 +5202,20 @@ function buildTicketProvider(config, opts) {
5105
5202
  return ticket;
5106
5203
  };
5107
5204
  }
5205
+ var _hasWarnedMissingDbId = false;
5206
+ function warnMissingDbIdOnce(config, dbOpts) {
5207
+ if (_hasWarnedMissingDbId) return;
5208
+ if (dbOpts.dbId) return;
5209
+ if (config.env === "prod") return;
5210
+ if (typeof window === "undefined") return;
5211
+ if (typeof console === "undefined" || typeof console.warn !== "function") return;
5212
+ _hasWarnedMissingDbId = true;
5213
+ console.warn(
5214
+ "[neetru/sdk] client.db sem `dbId` expl\xEDcito: escritas client-side (add/set/update/remove/list) caem no datastore gen\xE9rico do Core, escopado por tenant/produto (header x-neetru-tenant) \u2014 `dbId` s\xF3 nomeia o cache offline LOCAL (IndexedDB), n\xE3o roteia nem escopa nada no servidor. Veja o JSDoc de NeetruDbOptions.dbId."
5215
+ );
5216
+ }
5108
5217
  function createNeetruDb(config, dbOpts = {}) {
5218
+ warnMissingDbIdOnce(config, dbOpts);
5109
5219
  let resolvedTransport;
5110
5220
  if (dbOpts.transport !== void 0) {
5111
5221
  resolvedTransport = dbOpts.transport;
@@ -6615,7 +6725,18 @@ var MockSupport = class {
6615
6725
  severity: input.severity ?? "normal",
6616
6726
  status: "open",
6617
6727
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
6618
- productSlug: input.productSlug
6728
+ productSlug: input.productSlug,
6729
+ // 3.4 (product-feedback): espelha o contrato — campos novos nullable,
6730
+ // populados a partir do input quando fornecidos.
6731
+ pageUrl: typeof input.pageUrl === "string" ? input.pageUrl : null,
6732
+ screenshotUrl: typeof input.screenshotBase64 === "string" ? input.screenshotBase64 : null,
6733
+ resolvedAt: null,
6734
+ resolvedNotifiedAt: null,
6735
+ satisfactionAttempts: 0,
6736
+ lastSatisfactionAttemptAt: null,
6737
+ satisfiedAt: null,
6738
+ rating: null,
6739
+ satisfactionComment: null
6619
6740
  };
6620
6741
  this._tickets.push(ticket);
6621
6742
  return ticket;
@@ -6626,6 +6747,62 @@ var MockSupport = class {
6626
6747
  }
6627
6748
  return [...this._tickets];
6628
6749
  }
6750
+ _find(ticketId) {
6751
+ if (!ticketId || typeof ticketId !== "string") {
6752
+ throw new NeetruError("validation_failed", "ticketId is required");
6753
+ }
6754
+ const ticket = this._tickets.find((t) => t.id === ticketId);
6755
+ if (!ticket) {
6756
+ throw new NeetruError("not_found", `ticket ${ticketId} not found`);
6757
+ }
6758
+ return ticket;
6759
+ }
6760
+ /** 3.4: espelha `markResolvedSeen` — idempotente (só seta se ainda null). */
6761
+ async markResolvedSeen(ticketId) {
6762
+ const ticket = this._find(ticketId);
6763
+ if (ticket.resolvedNotifiedAt === null) {
6764
+ ticket.resolvedNotifiedAt = (/* @__PURE__ */ new Date()).toISOString();
6765
+ }
6766
+ }
6767
+ /** 3.4: espelha `recordSatisfactionAttempt` — incrementa contador. */
6768
+ async recordSatisfactionAttempt(ticketId) {
6769
+ const ticket = this._find(ticketId);
6770
+ ticket.satisfactionAttempts += 1;
6771
+ ticket.lastSatisfactionAttemptAt = (/* @__PURE__ */ new Date()).toISOString();
6772
+ }
6773
+ /** 3.4: espelha `submitSatisfaction` — terminal, seta `satisfiedAt`. */
6774
+ async submitSatisfaction(input) {
6775
+ if (!input || typeof input !== "object") {
6776
+ throw new NeetruError("validation_failed", "input is required");
6777
+ }
6778
+ if (input.rating !== null && input.rating !== void 0) {
6779
+ if (!Number.isInteger(input.rating) || input.rating < 1 || input.rating > 5) {
6780
+ throw new NeetruError("validation_failed", "rating must be an integer 1-5 or null");
6781
+ }
6782
+ }
6783
+ if (typeof input.comment === "string" && input.comment.length > 2e3) {
6784
+ throw new NeetruError("validation_failed", "comment max 2000 chars");
6785
+ }
6786
+ const ticket = this._find(input.ticketId);
6787
+ ticket.satisfiedAt = (/* @__PURE__ */ new Date()).toISOString();
6788
+ ticket.rating = input.rating ?? null;
6789
+ ticket.satisfactionComment = input.comment ?? null;
6790
+ }
6791
+ /** 3.4: espelha `contestTicket` — reabre e zera o ciclo de satisfação. */
6792
+ async contestTicket(ticketId, opts) {
6793
+ if (typeof opts?.comment === "string" && opts.comment.length > 2e3) {
6794
+ throw new NeetruError("validation_failed", "comment max 2000 chars");
6795
+ }
6796
+ const ticket = this._find(ticketId);
6797
+ ticket.status = "open";
6798
+ ticket.resolvedAt = null;
6799
+ ticket.resolvedNotifiedAt = null;
6800
+ ticket.satisfactionAttempts = 0;
6801
+ ticket.lastSatisfactionAttemptAt = null;
6802
+ ticket.satisfiedAt = null;
6803
+ ticket.rating = null;
6804
+ ticket.satisfactionComment = null;
6805
+ }
6629
6806
  /** Test helper. */
6630
6807
  __reset() {
6631
6808
  this._tickets = [];
@@ -7662,7 +7839,7 @@ function createNeetruClient(config = {}) {
7662
7839
  init_errors();
7663
7840
  init_db_errors();
7664
7841
  init_http();
7665
- var VERSION = "3.3.0";
7842
+ var VERSION = "3.4.0";
7666
7843
 
7667
7844
  export { DEFAULT_BASE_URL, DEV_FIXTURE_USER, MockAi, MockAuth, MockCheckout, MockDb, MockEntitlements, MockNotifications, MockSupport, MockUsage, MockWebhooks, NEETRU_SENTINEL_KEY, NeetruDbError, NeetruError, VERSION, checkCoreVersionCompat, createAiNamespace, createCheckoutNamespace, createNeetruClient, createNeetruDb, createNotificationsNamespace, createWebhooksNamespace, increment, isFieldSentinel, isIncrementSentinel, isServerTimestampSentinel, serverTimestamp, verifyWebhookRequest, verifyWebhookSignature };
7668
7845
  //# sourceMappingURL=index.mjs.map