@oxyhq/core 1.11.12 → 1.11.14

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 (130) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/CrossDomainAuth.js +3 -1
  3. package/dist/cjs/HttpService.js +214 -33
  4. package/dist/cjs/OxyServices.base.js +9 -0
  5. package/dist/cjs/OxyServices.js +8 -3
  6. package/dist/cjs/crypto/index.js +3 -1
  7. package/dist/cjs/crypto/keyManager.js +476 -172
  8. package/dist/cjs/crypto/polyfill.js +14 -65
  9. package/dist/cjs/crypto/recoveryPhrase.js +30 -11
  10. package/dist/cjs/crypto/signatureService.js +25 -60
  11. package/dist/cjs/i18n/locales/en-US.json +46 -1
  12. package/dist/cjs/i18n/locales/es-ES.json +46 -1
  13. package/dist/cjs/i18n/locales/locales/en-US.json +46 -1
  14. package/dist/cjs/i18n/locales/locales/es-ES.json +46 -1
  15. package/dist/cjs/index.js +10 -2
  16. package/dist/cjs/mixins/OxyServices.assets.js +9 -4
  17. package/dist/cjs/mixins/OxyServices.auth.js +147 -14
  18. package/dist/cjs/mixins/OxyServices.contacts.js +50 -0
  19. package/dist/cjs/mixins/OxyServices.features.js +0 -11
  20. package/dist/cjs/mixins/OxyServices.fedcm.js +4 -3
  21. package/dist/cjs/mixins/OxyServices.language.js +5 -36
  22. package/dist/cjs/mixins/OxyServices.redirect.js +6 -2
  23. package/dist/cjs/mixins/OxyServices.security.js +13 -2
  24. package/dist/cjs/mixins/OxyServices.user.js +59 -38
  25. package/dist/cjs/mixins/OxyServices.utility.js +416 -110
  26. package/dist/cjs/mixins/index.js +11 -3
  27. package/dist/cjs/utils/accountUtils.js +71 -2
  28. package/dist/cjs/utils/deviceManager.js +5 -36
  29. package/dist/cjs/utils/languageUtils.js +22 -0
  30. package/dist/cjs/utils/platformCrypto.js +165 -0
  31. package/dist/cjs/utils/platformCrypto.native.js +123 -0
  32. package/dist/esm/.tsbuildinfo +1 -1
  33. package/dist/esm/CrossDomainAuth.js +3 -1
  34. package/dist/esm/HttpService.js +215 -34
  35. package/dist/esm/OxyServices.base.js +9 -0
  36. package/dist/esm/OxyServices.js +8 -3
  37. package/dist/esm/crypto/index.js +1 -1
  38. package/dist/esm/crypto/keyManager.js +473 -138
  39. package/dist/esm/crypto/polyfill.js +14 -32
  40. package/dist/esm/crypto/recoveryPhrase.js +30 -11
  41. package/dist/esm/crypto/signatureService.js +25 -27
  42. package/dist/esm/i18n/locales/en-US.json +46 -1
  43. package/dist/esm/i18n/locales/es-ES.json +46 -1
  44. package/dist/esm/i18n/locales/locales/en-US.json +46 -1
  45. package/dist/esm/i18n/locales/locales/es-ES.json +46 -1
  46. package/dist/esm/index.js +4 -3
  47. package/dist/esm/mixins/OxyServices.assets.js +9 -4
  48. package/dist/esm/mixins/OxyServices.auth.js +145 -14
  49. package/dist/esm/mixins/OxyServices.contacts.js +47 -0
  50. package/dist/esm/mixins/OxyServices.features.js +0 -11
  51. package/dist/esm/mixins/OxyServices.fedcm.js +4 -3
  52. package/dist/esm/mixins/OxyServices.language.js +5 -3
  53. package/dist/esm/mixins/OxyServices.redirect.js +6 -2
  54. package/dist/esm/mixins/OxyServices.security.js +13 -2
  55. package/dist/esm/mixins/OxyServices.user.js +59 -38
  56. package/dist/esm/mixins/OxyServices.utility.js +416 -77
  57. package/dist/esm/mixins/index.js +11 -3
  58. package/dist/esm/utils/accountUtils.js +67 -1
  59. package/dist/esm/utils/deviceManager.js +5 -3
  60. package/dist/esm/utils/languageUtils.js +21 -0
  61. package/dist/esm/utils/platformCrypto.js +125 -0
  62. package/dist/esm/utils/platformCrypto.native.js +80 -0
  63. package/dist/types/.tsbuildinfo +1 -1
  64. package/dist/types/HttpService.d.ts +47 -3
  65. package/dist/types/OxyServices.base.d.ts +7 -0
  66. package/dist/types/OxyServices.d.ts +50 -7
  67. package/dist/types/crypto/index.d.ts +1 -1
  68. package/dist/types/crypto/keyManager.d.ts +110 -9
  69. package/dist/types/crypto/polyfill.d.ts +3 -1
  70. package/dist/types/crypto/recoveryPhrase.d.ts +31 -7
  71. package/dist/types/crypto/signatureService.d.ts +4 -0
  72. package/dist/types/index.d.ts +7 -5
  73. package/dist/types/mixins/OxyServices.analytics.d.ts +1 -0
  74. package/dist/types/mixins/OxyServices.assets.d.ts +6 -10
  75. package/dist/types/mixins/OxyServices.auth.d.ts +82 -5
  76. package/dist/types/mixins/OxyServices.contacts.d.ts +99 -0
  77. package/dist/types/mixins/OxyServices.developer.d.ts +1 -0
  78. package/dist/types/mixins/OxyServices.devices.d.ts +1 -0
  79. package/dist/types/mixins/OxyServices.features.d.ts +2 -7
  80. package/dist/types/mixins/OxyServices.fedcm.d.ts +1 -0
  81. package/dist/types/mixins/OxyServices.karma.d.ts +1 -0
  82. package/dist/types/mixins/OxyServices.language.d.ts +1 -0
  83. package/dist/types/mixins/OxyServices.location.d.ts +1 -0
  84. package/dist/types/mixins/OxyServices.managedAccounts.d.ts +1 -0
  85. package/dist/types/mixins/OxyServices.payment.d.ts +1 -0
  86. package/dist/types/mixins/OxyServices.popup.d.ts +1 -0
  87. package/dist/types/mixins/OxyServices.privacy.d.ts +1 -0
  88. package/dist/types/mixins/OxyServices.redirect.d.ts +1 -0
  89. package/dist/types/mixins/OxyServices.security.d.ts +1 -0
  90. package/dist/types/mixins/OxyServices.topics.d.ts +1 -0
  91. package/dist/types/mixins/OxyServices.user.d.ts +28 -11
  92. package/dist/types/mixins/OxyServices.utility.d.ts +145 -10
  93. package/dist/types/mixins/index.d.ts +52 -4
  94. package/dist/types/models/interfaces.d.ts +62 -3
  95. package/dist/types/utils/accountUtils.d.ts +41 -1
  96. package/dist/types/utils/languageUtils.d.ts +1 -0
  97. package/dist/types/utils/platformCrypto.d.ts +87 -0
  98. package/dist/types/utils/platformCrypto.native.d.ts +54 -0
  99. package/package.json +45 -2
  100. package/src/CrossDomainAuth.ts +12 -10
  101. package/src/HttpService.ts +251 -40
  102. package/src/OxyServices.base.ts +10 -0
  103. package/src/OxyServices.ts +26 -7
  104. package/src/crypto/__tests__/keyManager.test.ts +336 -0
  105. package/src/crypto/index.ts +6 -1
  106. package/src/crypto/keyManager.ts +529 -151
  107. package/src/crypto/polyfill.ts +14 -34
  108. package/src/crypto/recoveryPhrase.ts +56 -17
  109. package/src/crypto/signatureService.ts +25 -30
  110. package/src/i18n/locales/en-US.json +46 -1
  111. package/src/i18n/locales/es-ES.json +46 -1
  112. package/src/index.ts +19 -4
  113. package/src/mixins/OxyServices.assets.ts +15 -11
  114. package/src/mixins/OxyServices.auth.ts +175 -15
  115. package/src/mixins/OxyServices.contacts.ts +73 -0
  116. package/src/mixins/OxyServices.features.ts +2 -12
  117. package/src/mixins/OxyServices.fedcm.ts +4 -3
  118. package/src/mixins/OxyServices.language.ts +6 -4
  119. package/src/mixins/OxyServices.redirect.ts +6 -2
  120. package/src/mixins/OxyServices.security.ts +18 -8
  121. package/src/mixins/OxyServices.user.ts +72 -49
  122. package/src/mixins/OxyServices.utility.ts +562 -89
  123. package/src/mixins/__tests__/serviceAuth.test.ts +623 -0
  124. package/src/mixins/index.ts +58 -7
  125. package/src/models/interfaces.ts +65 -3
  126. package/src/utils/accountUtils.ts +82 -2
  127. package/src/utils/deviceManager.ts +7 -4
  128. package/src/utils/languageUtils.ts +23 -2
  129. package/src/utils/platformCrypto.native.ts +101 -0
  130. package/src/utils/platformCrypto.ts +145 -0
@@ -168,7 +168,9 @@ class CrossDomainAuth {
168
168
  * Check if FedCM is supported in current browser
169
169
  */
170
170
  isFedCMSupported() {
171
- return this.oxyServices.constructor.isFedCMSupported?.() || false;
171
+ // FedCM support is exposed both as a static and an instance method on
172
+ // OxyServices; the instance method is reliable across mixin composition.
173
+ return this.oxyServices.isFedCMSupported?.() || false;
172
174
  }
173
175
  /**
174
176
  * Get recommended authentication method for current environment
@@ -26,6 +26,32 @@ const platform_1 = require("./utils/platform");
26
26
  * This is used to determine CSRF handling mode
27
27
  */
28
28
  const isNativeApp = (0, platform_1.isNative)();
29
+ /**
30
+ * FNV-1a 32-bit non-cryptographic hash.
31
+ *
32
+ * Used by the cache-key generator for large payloads where full JSON
33
+ * inclusion would balloon the cache map keys. Content-addressed: every
34
+ * byte of the input contributes to the digest, so two payloads with the
35
+ * same top-level shape but different field values produce different keys
36
+ * (the previous `keys + length` heuristic collided on these).
37
+ *
38
+ * Trade-offs:
39
+ * - 32 bits is ample for an in-process cache (collision risk negligible
40
+ * at our key counts; we also prefix with method + url which further
41
+ * partitions the keyspace).
42
+ * - Not cryptographically secure — never use for security decisions.
43
+ * - Zero dependencies, branch-free hot loop, ~1 GiB/s on V8.
44
+ */
45
+ function fnv1a32(str) {
46
+ let h = 0x811c9dc5;
47
+ for (let i = 0; i < str.length; i++) {
48
+ h ^= str.charCodeAt(i);
49
+ // h * 16777619 mod 2^32, written as shift-and-add for portability and
50
+ // to avoid 53-bit JS number truncation in the intermediate multiply.
51
+ h = (h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24))) >>> 0;
52
+ }
53
+ return h.toString(16).padStart(8, '0');
54
+ }
29
55
  /**
30
56
  * Token store for authentication (instance-based)
31
57
  * Each HttpService gets its own TokenStore to prevent conflicts
@@ -105,31 +131,53 @@ class HttpService {
105
131
  this.requestQueue = new requestUtils_1.RequestQueue(config.maxConcurrentRequests || 10, config.requestQueueSize || 100);
106
132
  }
107
133
  /**
108
- * Robust FormData detection that works in browser and Node.js environments
109
- * Checks multiple conditions to handle different FormData implementations
134
+ * Robust FormData detection that works in browser, React Native, and
135
+ * Node.js polyfill environments.
136
+ *
137
+ * Why we don't use `instanceof FormData` alone:
138
+ * - React Native's FormData is a separate class, not the browser one —
139
+ * `instanceof FormData` is true only inside the JS runtime that
140
+ * instantiated the value (browser-side polyfills also have their own).
141
+ * - The Node.js `form-data` polyfill ships its own constructor.
142
+ *
143
+ * Why we explicitly reject `URLSearchParams`:
144
+ * - `URLSearchParams` ALSO exposes `append` / `get` / `has`, so the
145
+ * duck-type fallback below would have misidentified it as FormData.
146
+ * - We want urlencoded payloads to take the JSON-stringify path so the
147
+ * server receives them as `application/x-www-form-urlencoded` instead
148
+ * of an empty multipart body.
110
149
  */
111
150
  isFormData(data) {
112
- if (!data) {
151
+ if (!data || typeof data !== 'object') {
113
152
  return false;
114
153
  }
115
- // Primary check: instanceof FormData (works in browser and Node.js with proper polyfills)
116
- if (data instanceof FormData) {
154
+ // Reject URLSearchParams up front: it shares the duck-typed surface
155
+ // (append / get / has) but is a fundamentally different content type.
156
+ // The caller routes URLSearchParams through the regular body path.
157
+ if (typeof URLSearchParams !== 'undefined' && data instanceof URLSearchParams) {
158
+ return false;
159
+ }
160
+ // Primary check: instanceof FormData. Works whenever the value was
161
+ // constructed by the same runtime/realm that exposes `FormData`.
162
+ if (typeof FormData !== 'undefined' && data instanceof FormData) {
117
163
  return true;
118
164
  }
119
- // Fallback: Check constructor name (handles Node.js polyfills like form-data)
120
- if (typeof data === 'object' && data !== null) {
121
- const constructorName = data.constructor?.name;
122
- if (constructorName === 'FormData' || constructorName === 'FormDataImpl') {
123
- return true;
124
- }
125
- // Additional check: Look for FormData-like methods
126
- if (typeof data.append === 'function' &&
127
- typeof data.get === 'function' &&
128
- typeof data.has === 'function') {
129
- return true;
130
- }
165
+ // Fallback: detect Node / RN polyfills by constructor name. Limited to
166
+ // the small handful of known names so we don't accept arbitrary
167
+ // user-supplied objects with a coincidental `name`.
168
+ const constructorName = data.constructor?.name;
169
+ if (constructorName === 'FormData' || constructorName === 'FormDataImpl') {
170
+ return true;
131
171
  }
132
- return false;
172
+ // Last-resort duck typing — require the full FormData write surface
173
+ // (`append`, `get`, `has`, `getAll`, `delete`) so plain objects with
174
+ // an `append` method don't accidentally match.
175
+ const candidate = data;
176
+ return (typeof candidate.append === 'function' &&
177
+ typeof candidate.get === 'function' &&
178
+ typeof candidate.has === 'function' &&
179
+ typeof candidate.getAll === 'function' &&
180
+ typeof candidate.delete === 'function');
133
181
  }
134
182
  /**
135
183
  * Main request method - handles everything in one place
@@ -223,13 +271,22 @@ class HttpService {
223
271
  const bodyValue = method !== 'GET' && data
224
272
  ? (isFormData ? data : JSON.stringify(data))
225
273
  : undefined;
226
- const response = await fetch(fullUrl, {
227
- method,
228
- headers,
229
- body: bodyValue,
230
- signal: controller.signal,
231
- credentials: 'include', // Include cookies for cross-origin requests (CSRF, session)
232
- });
274
+ // React Native FormData workaround:
275
+ // Expo SDK 56's "winter fetch" rejects RN file descriptors `{uri, type, name}`
276
+ // in FormDataPart conversion (`Unsupported FormDataPart implementation`).
277
+ // RN's native XMLHttpRequest handles those descriptors correctly, so we
278
+ // route multipart uploads through XHR on RN only. JSON, text, etc. still
279
+ // use fetch on every platform.
280
+ const useXhrForUpload = isFormData && (0, platform_1.isReactNative)() && typeof XMLHttpRequest !== 'undefined';
281
+ const response = useXhrForUpload
282
+ ? await this.uploadViaXHR(fullUrl, method, headers, bodyValue, controller.signal, timeout)
283
+ : await fetch(fullUrl, {
284
+ method,
285
+ headers,
286
+ body: bodyValue,
287
+ signal: controller.signal,
288
+ credentials: 'include', // Include cookies for cross-origin requests (CSRF, session)
289
+ });
233
290
  if (timeoutId)
234
291
  clearTimeout(timeoutId);
235
292
  // Handle response
@@ -369,25 +426,131 @@ class HttpService {
369
426
  }
370
427
  return result;
371
428
  }
429
+ /**
430
+ * Upload via XMLHttpRequest (React Native FormData workaround).
431
+ *
432
+ * Expo SDK 56's "winter fetch" cannot serialize RN file descriptors
433
+ * (`{uri, type, name}`) — `convertFormDataAsync` rejects them as
434
+ * `Unsupported FormDataPart implementation`. RN's native XHR streams
435
+ * the file from disk correctly, so multipart uploads go through XHR
436
+ * on RN only.
437
+ *
438
+ * Returns a standard `Response` so downstream parsing in `request()`
439
+ * (status checks, 401/403 retries, JSON/blob/text parsing) is identical
440
+ * to the fetch path.
441
+ */
442
+ uploadViaXHR(url, method, headers, body, abortSignal, timeout) {
443
+ return new Promise((resolve, reject) => {
444
+ const xhr = new XMLHttpRequest();
445
+ xhr.open(method, url, true);
446
+ // withCredentials mirrors fetch's `credentials: 'include'` so the
447
+ // session cookie and CSRF cookie continue to flow.
448
+ xhr.withCredentials = true;
449
+ // Forward headers but skip Content-Type — XHR sets the multipart
450
+ // boundary automatically and overriding it breaks the upload.
451
+ for (const [key, value] of Object.entries(headers)) {
452
+ if (key.toLowerCase() === 'content-type')
453
+ continue;
454
+ try {
455
+ xhr.setRequestHeader(key, value);
456
+ }
457
+ catch (headerError) {
458
+ // Some headers (e.g. forbidden header names) cannot be set —
459
+ // log and continue rather than failing the whole upload.
460
+ this.logger.warn('XHR setRequestHeader failed:', key, headerError);
461
+ }
462
+ }
463
+ xhr.responseType = 'text';
464
+ if (timeout > 0) {
465
+ xhr.timeout = timeout;
466
+ }
467
+ const onAbort = () => {
468
+ try {
469
+ xhr.abort();
470
+ }
471
+ catch { /* xhr already finished */ }
472
+ };
473
+ if (abortSignal.aborted) {
474
+ reject(new DOMException('The user aborted a request.', 'AbortError'));
475
+ return;
476
+ }
477
+ abortSignal.addEventListener('abort', onAbort);
478
+ const cleanup = () => {
479
+ abortSignal.removeEventListener('abort', onAbort);
480
+ };
481
+ xhr.onload = () => {
482
+ cleanup();
483
+ const responseHeaders = HttpService.parseXHRHeaders(xhr.getAllResponseHeaders());
484
+ resolve(new Response(xhr.responseText, {
485
+ status: xhr.status,
486
+ statusText: xhr.statusText,
487
+ headers: responseHeaders,
488
+ }));
489
+ };
490
+ xhr.onerror = () => {
491
+ cleanup();
492
+ reject(new TypeError('Network request failed'));
493
+ };
494
+ xhr.ontimeout = () => {
495
+ cleanup();
496
+ reject(new DOMException('The request timed out.', 'TimeoutError'));
497
+ };
498
+ xhr.onabort = () => {
499
+ cleanup();
500
+ reject(new DOMException('The user aborted a request.', 'AbortError'));
501
+ };
502
+ xhr.send(body);
503
+ });
504
+ }
505
+ /**
506
+ * Parse raw header string from `XMLHttpRequest.getAllResponseHeaders()`
507
+ * into a `Headers`-compatible object.
508
+ */
509
+ static parseXHRHeaders(rawHeaders) {
510
+ const headers = new Headers();
511
+ if (!rawHeaders)
512
+ return headers;
513
+ // RFC 7230 line terminator is CRLF; some XHR implementations use LF only.
514
+ const lines = rawHeaders.trim().split(/\r?\n/);
515
+ for (const line of lines) {
516
+ const colonIndex = line.indexOf(':');
517
+ if (colonIndex <= 0)
518
+ continue;
519
+ const key = line.slice(0, colonIndex).trim();
520
+ const value = line.slice(colonIndex + 1).trim();
521
+ if (key) {
522
+ try {
523
+ headers.append(key, value);
524
+ }
525
+ catch {
526
+ // Invalid header name/value — skip.
527
+ }
528
+ }
529
+ }
530
+ return headers;
531
+ }
372
532
  /**
373
533
  * Generate cache key efficiently
374
- * Uses simple hash for large objects to avoid expensive JSON.stringify
534
+ * Uses a content-addressed hash for large payloads so two requests with
535
+ * the same shape but different values never collide on the same key
536
+ * (which would silently serve stale data — e.g. paginated search results,
537
+ * large object updates).
375
538
  */
376
539
  generateCacheKey(method, url, data) {
377
540
  if (!data || (typeof data === 'object' && Object.keys(data).length === 0)) {
378
541
  return `${method}:${url}`;
379
542
  }
380
- // For small objects, use JSON.stringify
543
+ // For small objects, the full serialization IS the key — fastest and
544
+ // guaranteed to be content-addressed.
381
545
  const dataStr = JSON.stringify(data);
382
546
  if (dataStr.length < 1000) {
383
547
  return `${method}:${url}:${dataStr}`;
384
548
  }
385
- // For large objects, use a simple hash based on keys and values length
386
- // This avoids expensive serialization while still being unique enough
387
- const hash = typeof data === 'object' && data !== null
388
- ? Object.keys(data).sort().join(',') + ':' + dataStr.length
389
- : String(data).substring(0, 100);
390
- return `${method}:${url}:${hash}`;
549
+ // For large payloads, hash the full serialized string so the key remains
550
+ // content-addressed (any byte change yields a different hash). Previous
551
+ // implementation hashed `keys + length` which collided for any two
552
+ // payloads with the same top-level keys and serialized length.
553
+ return `${method}:${url}:${fnv1a32(dataStr)}`;
391
554
  }
392
555
  /**
393
556
  * Build full URL with query params
@@ -617,6 +780,24 @@ class HttpService {
617
780
  clearCacheEntry(key) {
618
781
  this.cache.delete(key);
619
782
  }
783
+ /**
784
+ * Delete every cache entry whose key starts with `prefix`.
785
+ *
786
+ * Used by mutations that don't know the exact downstream cache keys —
787
+ * e.g. `updateProfile` invalidating all `GET:/session/user/*` entries
788
+ * without having to track every active session ID. Returns the number of
789
+ * deleted entries (for observability in tests).
790
+ */
791
+ clearCacheByPrefix(prefix) {
792
+ let removed = 0;
793
+ for (const key of this.cache.keys()) {
794
+ if (key.startsWith(prefix)) {
795
+ this.cache.delete(key);
796
+ removed++;
797
+ }
798
+ }
799
+ return removed;
800
+ }
620
801
  getCacheStats() {
621
802
  const cacheStats = this.cache.getStats();
622
803
  const total = this.requestMetrics.cacheHits + this.requestMetrics.cacheMisses;
@@ -78,6 +78,15 @@ class OxyServicesBase {
78
78
  clearCacheEntry(key) {
79
79
  this.httpService.clearCacheEntry(key);
80
80
  }
81
+ /**
82
+ * Clear every cache entry whose key starts with `prefix`.
83
+ * Useful for mutations that invalidate a family of GET responses
84
+ * without enumerating each one (e.g. all session-user lookups after
85
+ * a profile update).
86
+ */
87
+ clearCacheByPrefix(prefix) {
88
+ return this.httpService.clearCacheByPrefix(prefix);
89
+ }
81
90
  /**
82
91
  * Get cache statistics
83
92
  */
@@ -39,9 +39,14 @@ const mixins_1 = require("./mixins");
39
39
  * });
40
40
  * ```
41
41
  */
42
- // Compose all mixins into the final OxyServices class
42
+ // Compose all mixins into the final OxyServices class. The composed runtime
43
+ // class augments OxyServicesBase with every mixin's methods (see mixins/index.ts).
44
+ // Statically, TypeScript sees this as a constructor producing OxyServicesBase;
45
+ // the additional methods are exposed via interface merging on `OxyServices` below.
43
46
  const OxyServicesComposed = (0, mixins_1.composeOxyServices)();
44
- // Export as a named class to avoid TypeScript issues with anonymous class types
47
+ // Export as a named class to avoid TypeScript issues with anonymous class types.
48
+ // We extend the composed constructor directly — its public surface is broadened
49
+ // to the full mixin set via the interface declaration that follows.
45
50
  class OxyServices extends OxyServicesComposed {
46
51
  constructor(config) {
47
52
  super(config);
@@ -49,7 +54,7 @@ class OxyServices extends OxyServicesComposed {
49
54
  }
50
55
  exports.OxyServices = OxyServices;
51
56
  /**
52
- * Export the default Oxy Cloud URL (for backward compatibility)
57
+ * Default Oxy Cloud URL used when no `cloudURL` is provided to OxyServices.
53
58
  */
54
59
  exports.OXY_CLOUD_URL = 'https://cloud.oxy.so';
55
60
  /**
@@ -6,11 +6,13 @@
6
6
  * Handles key generation, secure storage, digital signatures, and recovery phrases.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.default = exports.RecoveryPhraseService = exports.SignatureService = exports.KeyManager = void 0;
9
+ exports.default = exports.RecoveryPhraseService = exports.SignatureService = exports.IdentityPersistError = exports.IdentityAlreadyExistsError = exports.KeyManager = void 0;
10
10
  // Import polyfills first - this ensures Buffer is available for bip39 and other libraries
11
11
  require("./polyfill");
12
12
  var keyManager_1 = require("./keyManager");
13
13
  Object.defineProperty(exports, "KeyManager", { enumerable: true, get: function () { return keyManager_1.KeyManager; } });
14
+ Object.defineProperty(exports, "IdentityAlreadyExistsError", { enumerable: true, get: function () { return keyManager_1.IdentityAlreadyExistsError; } });
15
+ Object.defineProperty(exports, "IdentityPersistError", { enumerable: true, get: function () { return keyManager_1.IdentityPersistError; } });
14
16
  var signatureService_1 = require("./signatureService");
15
17
  Object.defineProperty(exports, "SignatureService", { enumerable: true, get: function () { return signatureService_1.SignatureService; } });
16
18
  var recoveryPhrase_1 = require("./recoveryPhrase");