@neetru/sdk 3.1.6 → 3.1.9

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 (77) hide show
  1. package/dist/auth.cjs +65 -22
  2. package/dist/auth.cjs.map +1 -1
  3. package/dist/auth.d.cts +1 -1
  4. package/dist/auth.d.ts +1 -1
  5. package/dist/auth.mjs +65 -22
  6. package/dist/auth.mjs.map +1 -1
  7. package/dist/catalog.cjs.map +1 -1
  8. package/dist/catalog.d.cts +1 -1
  9. package/dist/catalog.d.ts +1 -1
  10. package/dist/catalog.mjs.map +1 -1
  11. package/dist/checkout.cjs.map +1 -1
  12. package/dist/checkout.d.cts +1 -1
  13. package/dist/checkout.d.ts +1 -1
  14. package/dist/checkout.mjs.map +1 -1
  15. package/dist/db-react.d.cts +1 -1
  16. package/dist/db-react.d.ts +1 -1
  17. package/dist/db.cjs +55 -16
  18. package/dist/db.cjs.map +1 -1
  19. package/dist/db.d.cts +1 -1
  20. package/dist/db.d.ts +1 -1
  21. package/dist/db.mjs +55 -16
  22. package/dist/db.mjs.map +1 -1
  23. package/dist/entitlements.cjs.map +1 -1
  24. package/dist/entitlements.d.cts +1 -1
  25. package/dist/entitlements.d.ts +1 -1
  26. package/dist/entitlements.mjs.map +1 -1
  27. package/dist/errors.cjs.map +1 -1
  28. package/dist/errors.d.cts +8 -8
  29. package/dist/errors.d.ts +8 -8
  30. package/dist/errors.mjs.map +1 -1
  31. package/dist/firestore-compat.cjs +4 -9
  32. package/dist/firestore-compat.cjs.map +1 -1
  33. package/dist/firestore-compat.d.cts +2 -2
  34. package/dist/firestore-compat.d.ts +2 -2
  35. package/dist/firestore-compat.mjs +4 -9
  36. package/dist/firestore-compat.mjs.map +1 -1
  37. package/dist/index.cjs +66 -23
  38. package/dist/index.cjs.map +1 -1
  39. package/dist/index.d.cts +2 -2
  40. package/dist/index.d.ts +2 -2
  41. package/dist/index.mjs +66 -23
  42. package/dist/index.mjs.map +1 -1
  43. package/dist/mocks.cjs.map +1 -1
  44. package/dist/mocks.d.cts +1 -1
  45. package/dist/mocks.d.ts +1 -1
  46. package/dist/mocks.mjs.map +1 -1
  47. package/dist/notifications.cjs.map +1 -1
  48. package/dist/notifications.d.cts +1 -1
  49. package/dist/notifications.d.ts +1 -1
  50. package/dist/notifications.mjs.map +1 -1
  51. package/dist/react.cjs.map +1 -1
  52. package/dist/react.d.cts +1 -1
  53. package/dist/react.d.ts +1 -1
  54. package/dist/react.mjs.map +1 -1
  55. package/dist/support.cjs.map +1 -1
  56. package/dist/support.d.cts +1 -1
  57. package/dist/support.d.ts +1 -1
  58. package/dist/support.mjs.map +1 -1
  59. package/dist/telemetry.cjs +5 -1
  60. package/dist/telemetry.cjs.map +1 -1
  61. package/dist/telemetry.d.cts +1 -1
  62. package/dist/telemetry.d.ts +1 -1
  63. package/dist/telemetry.mjs +5 -1
  64. package/dist/telemetry.mjs.map +1 -1
  65. package/dist/{types-BXvGHppn.d.cts → types-DDiVzgCT.d.cts} +19 -2
  66. package/dist/{types-CQVak2a3.d.ts → types-HWDOUmlC.d.ts} +19 -2
  67. package/dist/usage.cjs +2 -2
  68. package/dist/usage.cjs.map +1 -1
  69. package/dist/usage.d.cts +1 -1
  70. package/dist/usage.d.ts +1 -1
  71. package/dist/usage.mjs +2 -2
  72. package/dist/usage.mjs.map +1 -1
  73. package/dist/webhooks.cjs.map +1 -1
  74. package/dist/webhooks.d.cts +1 -1
  75. package/dist/webhooks.d.ts +1 -1
  76. package/dist/webhooks.mjs.map +1 -1
  77. package/package.json +156 -156
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 AuthNamespace, a as AuthStateListener, C as CatalogListOptions, b as CatalogListResponse, d as CheckoutIntentInfo, e as CheckoutIntentStatus, f as CheckoutNamespace, g as CheckoutStartInput, h as CheckoutStartResult, i as CheckoutTenantType, l as CreateTicketInput, D as DEFAULT_BASE_URL, m as DbBatchOp, n as DbChangeType, o as DbCollectionRef, p as DbDoc, q as DbDocRef, r as DbGetResult, s as DbListResult, t as DbNamespace, u as DbQuery, v as DbSqlLease, w as DbWhereFilter, E as EntitlementCheck, F as FieldSentinel, I as IncrementSentinel, L as ListNotificationsOptions, M as MockCheckout, y as MockNotifications, z as MockWebhooks, N as NEETRU_SENTINEL_KEY, B as NeetruClient, G as NeetruClientConfig, H as NeetruDb, K as NeetruDbEngine, O as NeetruDbError, P as NeetruDbErrorCode, Q as NeetruDbOptions, R as NeetruDbTransport, S as NeetruEnv, T as NeetruSqlClient, U as NeetruUser, V as NotificationScopeOptions, W as NotificationsNamespace, X as Product, Y as ProductNotification, Z as ProductNotificationSeverity, _ as ProductPlan, $ as ProductStatus, a1 as RedirectCallbackResult, a2 as RegisterWebhookInput, a3 as ResolvedConfig, a4 as SendNotificationInput, a5 as ServerTimestampSentinel, a6 as SignInOptions, a8 as SupportNamespace, a9 as SupportSeverity, aa as SupportStatus, ab as SupportTicket, ad as TelemetryEventAck, ae as TelemetryEventInput, ai as UsageEventInput, aj as UsageNamespace, ak as UsageQuota, al as VerifyTokenOptions, am as VerifyWebhookRequestOptions, an as VerifyWebhookRequestResult, ao as WebhookEndpoint, ap as WebhookEvent, aq as WebhookScopeOptions, ar as WebhookTestResult, as as WebhooksNamespace, at as WithFieldSentinels, au as createCheckoutNamespace, av as createNeetruDb, aw as createNotificationsNamespace, ay as createWebhooksNamespace, aA as increment, aB as isFieldSentinel, aC as isIncrementSentinel, aD as isServerTimestampSentinel, aE as serverTimestamp, aF as verifyWebhookRequest, aG as verifyWebhookSignature } from './types-BXvGHppn.cjs';
3
+ export { A as AuthNamespace, a as AuthStateListener, C as CatalogListOptions, b as CatalogListResponse, d as CheckoutIntentInfo, e as CheckoutIntentStatus, f as CheckoutNamespace, g as CheckoutStartInput, h as CheckoutStartResult, i as CheckoutTenantType, l as CreateTicketInput, D as DEFAULT_BASE_URL, m as DbBatchOp, n as DbChangeType, o as DbCollectionRef, p as DbDoc, q as DbDocRef, r as DbGetResult, s as DbListResult, t as DbNamespace, u as DbQuery, v as DbSqlLease, w as DbWhereFilter, E as EntitlementCheck, F as FieldSentinel, I as IncrementSentinel, L as ListNotificationsOptions, M as MockCheckout, y as MockNotifications, z as MockWebhooks, N as NEETRU_SENTINEL_KEY, B as NeetruClient, G as NeetruClientConfig, H as NeetruDb, K as NeetruDbEngine, O as NeetruDbError, P as NeetruDbErrorCode, Q as NeetruDbOptions, R as NeetruDbTransport, S as NeetruEnv, T as NeetruSqlClient, U as NeetruUser, V as NotificationScopeOptions, W as NotificationsNamespace, X as Product, Y as ProductNotification, Z as ProductNotificationSeverity, _ as ProductPlan, $ as ProductStatus, a1 as RedirectCallbackResult, a2 as RegisterWebhookInput, a3 as ResolvedConfig, a4 as SendNotificationInput, a5 as ServerTimestampSentinel, a6 as SignInOptions, a8 as SupportNamespace, a9 as SupportSeverity, aa as SupportStatus, ab as SupportTicket, ad as TelemetryEventAck, ae as TelemetryEventInput, ai as UsageEventInput, aj as UsageNamespace, ak as UsageQuota, al as VerifyTokenOptions, am as VerifyWebhookRequestOptions, an as VerifyWebhookRequestResult, ao as WebhookEndpoint, ap as WebhookEvent, aq as WebhookScopeOptions, ar as WebhookTestResult, as as WebhooksNamespace, at as WithFieldSentinels, au as createCheckoutNamespace, av as createNeetruDb, aw as createNotificationsNamespace, ay as createWebhooksNamespace, aA as increment, aB as isFieldSentinel, aC as isIncrementSentinel, aD as isServerTimestampSentinel, aE as serverTimestamp, aF as verifyWebhookRequest, aG as verifyWebhookSignature } from './types-DDiVzgCT.cjs';
4
4
  export { DEV_FIXTURE_USER, 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.1.6";
45
+ declare const VERSION: "3.1.9";
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 AuthNamespace, a as AuthStateListener, C as CatalogListOptions, b as CatalogListResponse, d as CheckoutIntentInfo, e as CheckoutIntentStatus, f as CheckoutNamespace, g as CheckoutStartInput, h as CheckoutStartResult, i as CheckoutTenantType, l as CreateTicketInput, D as DEFAULT_BASE_URL, m as DbBatchOp, n as DbChangeType, o as DbCollectionRef, p as DbDoc, q as DbDocRef, r as DbGetResult, s as DbListResult, t as DbNamespace, u as DbQuery, v as DbSqlLease, w as DbWhereFilter, E as EntitlementCheck, F as FieldSentinel, I as IncrementSentinel, L as ListNotificationsOptions, M as MockCheckout, y as MockNotifications, z as MockWebhooks, N as NEETRU_SENTINEL_KEY, B as NeetruClient, G as NeetruClientConfig, H as NeetruDb, K as NeetruDbEngine, O as NeetruDbError, P as NeetruDbErrorCode, Q as NeetruDbOptions, R as NeetruDbTransport, S as NeetruEnv, T as NeetruSqlClient, U as NeetruUser, V as NotificationScopeOptions, W as NotificationsNamespace, X as Product, Y as ProductNotification, Z as ProductNotificationSeverity, _ as ProductPlan, $ as ProductStatus, a1 as RedirectCallbackResult, a2 as RegisterWebhookInput, a3 as ResolvedConfig, a4 as SendNotificationInput, a5 as ServerTimestampSentinel, a6 as SignInOptions, a8 as SupportNamespace, a9 as SupportSeverity, aa as SupportStatus, ab as SupportTicket, ad as TelemetryEventAck, ae as TelemetryEventInput, ai as UsageEventInput, aj as UsageNamespace, ak as UsageQuota, al as VerifyTokenOptions, am as VerifyWebhookRequestOptions, an as VerifyWebhookRequestResult, ao as WebhookEndpoint, ap as WebhookEvent, aq as WebhookScopeOptions, ar as WebhookTestResult, as as WebhooksNamespace, at as WithFieldSentinels, au as createCheckoutNamespace, av as createNeetruDb, aw as createNotificationsNamespace, ay as createWebhooksNamespace, aA as increment, aB as isFieldSentinel, aC as isIncrementSentinel, aD as isServerTimestampSentinel, aE as serverTimestamp, aF as verifyWebhookRequest, aG as verifyWebhookSignature } from './types-CQVak2a3.js';
3
+ export { A as AuthNamespace, a as AuthStateListener, C as CatalogListOptions, b as CatalogListResponse, d as CheckoutIntentInfo, e as CheckoutIntentStatus, f as CheckoutNamespace, g as CheckoutStartInput, h as CheckoutStartResult, i as CheckoutTenantType, l as CreateTicketInput, D as DEFAULT_BASE_URL, m as DbBatchOp, n as DbChangeType, o as DbCollectionRef, p as DbDoc, q as DbDocRef, r as DbGetResult, s as DbListResult, t as DbNamespace, u as DbQuery, v as DbSqlLease, w as DbWhereFilter, E as EntitlementCheck, F as FieldSentinel, I as IncrementSentinel, L as ListNotificationsOptions, M as MockCheckout, y as MockNotifications, z as MockWebhooks, N as NEETRU_SENTINEL_KEY, B as NeetruClient, G as NeetruClientConfig, H as NeetruDb, K as NeetruDbEngine, O as NeetruDbError, P as NeetruDbErrorCode, Q as NeetruDbOptions, R as NeetruDbTransport, S as NeetruEnv, T as NeetruSqlClient, U as NeetruUser, V as NotificationScopeOptions, W as NotificationsNamespace, X as Product, Y as ProductNotification, Z as ProductNotificationSeverity, _ as ProductPlan, $ as ProductStatus, a1 as RedirectCallbackResult, a2 as RegisterWebhookInput, a3 as ResolvedConfig, a4 as SendNotificationInput, a5 as ServerTimestampSentinel, a6 as SignInOptions, a8 as SupportNamespace, a9 as SupportSeverity, aa as SupportStatus, ab as SupportTicket, ad as TelemetryEventAck, ae as TelemetryEventInput, ai as UsageEventInput, aj as UsageNamespace, ak as UsageQuota, al as VerifyTokenOptions, am as VerifyWebhookRequestOptions, an as VerifyWebhookRequestResult, ao as WebhookEndpoint, ap as WebhookEvent, aq as WebhookScopeOptions, ar as WebhookTestResult, as as WebhooksNamespace, at as WithFieldSentinels, au as createCheckoutNamespace, av as createNeetruDb, aw as createNotificationsNamespace, ay as createWebhooksNamespace, aA as increment, aB as isFieldSentinel, aC as isIncrementSentinel, aD as isServerTimestampSentinel, aE as serverTimestamp, aF as verifyWebhookRequest, aG as verifyWebhookSignature } from './types-HWDOUmlC.js';
4
4
  export { DEV_FIXTURE_USER, 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.1.6";
45
+ declare const VERSION: "3.1.9";
46
46
 
47
47
  export { VERSION, checkCoreVersionCompat };
package/dist/index.mjs CHANGED
@@ -446,7 +446,7 @@ __export(sql_client_exports, {
446
446
  function mapEnvToCore(sdkEnv) {
447
447
  if (sdkEnv === "workspace") return "staging";
448
448
  if (sdkEnv === "prod") return "production";
449
- return "dev";
449
+ return "dev-local";
450
450
  }
451
451
  function createHttpLeaseFetcher(config) {
452
452
  return async (opts) => {
@@ -955,7 +955,11 @@ function createTelemetryNamespace(config) {
955
955
  path: "/api/sdk/v1/telemetry/event",
956
956
  body,
957
957
  requireAuth: true,
958
- retries: 1
958
+ retries: 1,
959
+ // caça-bruxas: retry sem Idempotency-Key duplicava o evento se o
960
+ // servidor já tinha persistido antes da falha transiente. Mesmo
961
+ // padrão do usage.report (key estável por chamada, reusada no retry).
962
+ idempotencyKey: true
959
963
  });
960
964
  } catch (err) {
961
965
  if (typeof console !== "undefined") {
@@ -1159,8 +1163,8 @@ function createUsageNamespace(config) {
1159
1163
  if (!resource || typeof resource !== "string") {
1160
1164
  throw new NeetruError("validation_failed", "resource is required");
1161
1165
  }
1162
- if (!Number.isFinite(qty) || qty <= 0) {
1163
- throw new NeetruError("validation_failed", "qty must be positive integer");
1166
+ if (!Number.isFinite(qty) || qty <= 0 || !Number.isInteger(qty)) {
1167
+ throw new NeetruError("validation_failed", "qty must be a positive integer");
1164
1168
  }
1165
1169
  const productId = options?.productId ?? config.productId;
1166
1170
  const tenantId = options?.tenantId ?? config.tenantId;
@@ -1409,7 +1413,12 @@ function evaluateFilter(data, filter) {
1409
1413
  if (!Array.isArray(value)) return true;
1410
1414
  return !value.includes(fieldValue);
1411
1415
  default:
1412
- return false;
1416
+ if (op === "array-contains-any") {
1417
+ return Array.isArray(fieldValue) && Array.isArray(value) && value.some((v) => fieldValue.includes(v));
1418
+ }
1419
+ throw new Error(
1420
+ `QueryEngine: operador de filtro '${String(op)}' n\xE3o suportado em leitura offline/cache. Use um operador suportado (==, !=, <, <=, >, >=, array-contains, array-contains-any, in, not-in) ou fa\xE7a a query server-side.`
1421
+ );
1413
1422
  }
1414
1423
  }
1415
1424
  function matchesAllFilters(data, filters) {
@@ -1939,7 +1948,7 @@ var MutationQueue = class {
1939
1948
  * - `{ removed: true }` — a mutação existente deve ser deletada (add+remove)
1940
1949
  * - `null` — não é possível coalescir
1941
1950
  */
1942
- tryCoalesce(existing, newOp, newPayload, newBatchId) {
1951
+ tryCoalesce(existing, newOp, newPayload, newBatchId, newUpsert) {
1943
1952
  if (existing.batchId !== newBatchId) return null;
1944
1953
  if (existing.status === "inflight") return null;
1945
1954
  const existingOp = existing.op;
@@ -1947,10 +1956,12 @@ var MutationQueue = class {
1947
1956
  return { removed: true };
1948
1957
  }
1949
1958
  if (existingOp === "update" && newOp === "update") {
1959
+ const mergedUpsert = existing.upsert || newUpsert;
1950
1960
  return {
1951
1961
  coalesced: {
1952
1962
  ...existing,
1953
- payload: { ...existing.payload ?? {}, ...newPayload ?? {} }
1963
+ payload: { ...existing.payload ?? {}, ...newPayload ?? {} },
1964
+ ...mergedUpsert ? { upsert: true } : {}
1954
1965
  }
1955
1966
  };
1956
1967
  }
@@ -1999,13 +2010,13 @@ var MutationQueue = class {
1999
2010
  * Atômico: a persistência final é uma única operação putMutation.
2000
2011
  */
2001
2012
  async enqueue(params) {
2002
- const { collection, op, payload, baseVersion, batchId } = params;
2013
+ const { collection, op, payload, baseVersion, batchId, upsert } = params;
2003
2014
  const docId = params.docId ?? (op === "add" ? generateUUIDv4() : "");
2004
2015
  await this.syncSeq();
2005
2016
  const existingMutations = await this.store.listMutations({ collection, docId });
2006
2017
  const lastQueued = existingMutations.filter((m) => m.status === "queued").sort((a, b) => b.seq - a.seq)[0];
2007
2018
  if (lastQueued !== void 0) {
2008
- const coalesceResult = this.tryCoalesce(lastQueued, op, payload, batchId);
2019
+ const coalesceResult = this.tryCoalesce(lastQueued, op, payload, batchId, upsert);
2009
2020
  if (coalesceResult !== null) {
2010
2021
  if ("removed" in coalesceResult) {
2011
2022
  await this.store.deleteMutation(lastQueued.mutationId);
@@ -2043,7 +2054,9 @@ var MutationQueue = class {
2043
2054
  attempts: 0,
2044
2055
  lastError: null,
2045
2056
  status: "queued",
2046
- batchId
2057
+ batchId,
2058
+ // bug_0273e4dd: só persiste o flag quando verdadeiro (mantém o doc limpo).
2059
+ ...upsert ? { upsert: true } : {}
2047
2060
  };
2048
2061
  await this.store.putMutation(mutation);
2049
2062
  return mutation;
@@ -2383,10 +2396,15 @@ var SyncEngine = class {
2383
2396
  await this._applyRejected(mut, res, busChanges);
2384
2397
  }
2385
2398
  }
2399
+ const processedIds = new Set(result.results.map((r) => r.mutationId));
2400
+ const unprocessed = mutations.filter((m) => !processedIds.has(m.mutationId));
2401
+ for (const mut of unprocessed) {
2402
+ await this._queue.markRetry(mut.mutationId, "partial_push: muta\xE7\xE3o n\xE3o processada no lote");
2403
+ }
2386
2404
  if (busChanges.length > 0) {
2387
2405
  this._bus.emit(busChanges);
2388
2406
  }
2389
- return true;
2407
+ return unprocessed.length === 0;
2390
2408
  }
2391
2409
  /** Atualiza o cache após confirmação de escrita (outcome=confirmed). */
2392
2410
  async _applySyncedDoc(collection, docId, serverVersion, serverTimestamp2, mut, busChanges) {
@@ -3693,7 +3711,7 @@ var DbCollectionRefImpl = class {
3693
3711
  }]);
3694
3712
  return { ok: true };
3695
3713
  }
3696
- async update(id, data) {
3714
+ async update(id, data, opts) {
3697
3715
  assertValidId(id);
3698
3716
  const existing = await this._store.getDoc(this._collection, id);
3699
3717
  const rawData = data;
@@ -3706,7 +3724,9 @@ var DbCollectionRefImpl = class {
3706
3724
  op: "update",
3707
3725
  payload: rawData,
3708
3726
  baseVersion: existing?.meta.serverVersion ?? null,
3709
- batchId: null
3727
+ batchId: null,
3728
+ // bug_0273e4dd: propaga merge-upsert (setDoc({merge:true}) cria-se-ausente).
3729
+ upsert: opts?.upsert
3710
3730
  });
3711
3731
  await this._store.putDoc({
3712
3732
  collection: this._collection,
@@ -3830,7 +3850,9 @@ var DbCollectionRefImpl = class {
3830
3850
  op: "update",
3831
3851
  payload: data,
3832
3852
  baseVersion: existing?.meta.serverVersion ?? null,
3833
- batchId
3853
+ batchId,
3854
+ // bug_0273e4dd: propaga merge-upsert (writeBatch.set(merge) cria-se-ausente).
3855
+ upsert: op.upsert
3834
3856
  });
3835
3857
  await this._store.putDoc({
3836
3858
  collection,
@@ -4092,6 +4114,10 @@ async function createOfflineDocumentsNamespace(opts) {
4092
4114
  connectivity,
4093
4115
  periodicSyncIntervalMs: opts.periodicSyncIntervalMs ?? 5 * 60 * 1e3
4094
4116
  });
4117
+ connectivity.start();
4118
+ if (!opts.singleTab && tabCoordinatorLike instanceof TabCoordinator) {
4119
+ tabCoordinatorLike.start();
4120
+ }
4095
4121
  return new NeetruDbDocumentsImpl({
4096
4122
  store,
4097
4123
  queue,
@@ -4561,11 +4587,11 @@ function createRestSyncTransport(config) {
4561
4587
  let raw;
4562
4588
  if (m.op === "add") {
4563
4589
  raw = await httpRequest2(config, {
4564
- method: "POST",
4565
- path: DATASTORE_COLLECTION_ENDPOINT(m.collection),
4590
+ method: "PUT",
4591
+ path: DATASTORE_DOC_ENDPOINT(m.collection, m.docId),
4566
4592
  body: { data: m.payload ?? {} },
4567
4593
  requireAuth: true,
4568
- retries: 0,
4594
+ retries: 2,
4569
4595
  headers: tenantHeaders
4570
4596
  });
4571
4597
  } else if (m.op === "set") {
@@ -4581,7 +4607,7 @@ function createRestSyncTransport(config) {
4581
4607
  raw = await httpRequest2(config, {
4582
4608
  method: "PATCH",
4583
4609
  path: DATASTORE_DOC_ENDPOINT(m.collection, m.docId),
4584
- body: { data: m.payload ?? {} },
4610
+ body: { data: m.payload ?? {}, ...m.upsert ? { upsert: true } : {} },
4585
4611
  requireAuth: true,
4586
4612
  retries: 2,
4587
4613
  headers: tenantHeaders
@@ -4604,7 +4630,24 @@ function createRestSyncTransport(config) {
4604
4630
  });
4605
4631
  } catch (err) {
4606
4632
  const msg = err instanceof Error ? err.message : String(err);
4607
- throw new NeetruDbError("db_unavailable", `pushMutations falhou: ${msg}`);
4633
+ const code = err?.code;
4634
+ const status = err?.status;
4635
+ const isPermanent = code === "forbidden" || code === "unauthorized" || code === "not_found" || code === "conflict" || code === "validation_failed" || typeof status === "number" && status >= 400 && status < 500 && status !== 408 && status !== 429;
4636
+ if (isPermanent) {
4637
+ const reason = code === "forbidden" || code === "unauthorized" ? "rejected_permission" : "rejected_validation";
4638
+ results.push({
4639
+ mutationId: m.mutationId,
4640
+ outcome: "rejected",
4641
+ reason,
4642
+ serverVersion: null,
4643
+ serverData: null
4644
+ });
4645
+ continue;
4646
+ }
4647
+ if (results.length === 0) {
4648
+ throw new NeetruDbError("db_unavailable", `pushMutations falhou: ${msg}`);
4649
+ }
4650
+ break;
4608
4651
  }
4609
4652
  }
4610
4653
  return { results };
@@ -6518,15 +6561,15 @@ function createOidcAuthNamespace(config) {
6518
6561
  const overrideAuthUrl = typeof globalThis.NEETRU_AUTH_URL === "string" ? globalThis.NEETRU_AUTH_URL : null;
6519
6562
  const idpOrigin = overrideAuthUrl ?? config.baseUrl.replace(/^https?:\/\/api\./, "https://auth.");
6520
6563
  const issuer = idpOrigin;
6521
- const jwksUrl = `${idpOrigin}/api/v1/oauth/.well-known/jwks.json`;
6564
+ const jwksUrl = `${idpOrigin}/api/v1/oauth/.well-known/jwks`;
6522
6565
  const cacheTtlMs = options?.jwksCacheTtlMs ?? DEFAULT_JWKS_TTL_MS;
6523
6566
  const audienceFromOptions = options?.audience;
6524
6567
  const parsedKey = tryParseApiKey(config.apiKey);
6525
- const audience = audienceFromOptions ?? parsedKey?.keyId;
6568
+ const audience = audienceFromOptions ?? config.oidcClientId ?? parsedKey?.keyId;
6526
6569
  if (!audience) {
6527
6570
  throw new NeetruError(
6528
6571
  "invalid_config",
6529
- "verifyToken requires an audience: provide apiKey on the client or pass options.audience. Calling jwtVerify without an audience allows tokens issued for other OIDC clients to pass."
6572
+ "verifyToken requires an audience: provide oidcClientId/apiKey on the client or pass options.audience. Calling jwtVerify without an audience allows tokens issued for other OIDC clients to pass."
6530
6573
  );
6531
6574
  }
6532
6575
  const jwks = _getJwks(jwksUrl, cacheTtlMs);
@@ -6609,7 +6652,7 @@ function createNeetruClient(config = {}) {
6609
6652
  init_errors();
6610
6653
  init_db_errors();
6611
6654
  init_http();
6612
- var VERSION = "3.1.6";
6655
+ var VERSION = "3.1.9";
6613
6656
 
6614
6657
  export { DEFAULT_BASE_URL, DEV_FIXTURE_USER, MockAuth, MockCheckout, MockDb, MockEntitlements, MockNotifications, MockSupport, MockUsage, MockWebhooks, NEETRU_SENTINEL_KEY, NeetruDbError, NeetruError, VERSION, checkCoreVersionCompat, createCheckoutNamespace, createNeetruClient, createNeetruDb, createNotificationsNamespace, createWebhooksNamespace, increment, isFieldSentinel, isIncrementSentinel, isServerTimestampSentinel, serverTimestamp, verifyWebhookRequest, verifyWebhookSignature };
6615
6658
  //# sourceMappingURL=index.mjs.map