@oxyhq/core 1.11.11 → 1.11.13
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.
- package/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/CrossDomainAuth.js +3 -1
- package/dist/cjs/HttpService.js +227 -51
- package/dist/cjs/OxyServices.base.js +9 -0
- package/dist/cjs/OxyServices.js +8 -3
- package/dist/cjs/crypto/index.js +3 -1
- package/dist/cjs/crypto/keyManager.js +476 -172
- package/dist/cjs/crypto/polyfill.js +14 -65
- package/dist/cjs/crypto/recoveryPhrase.js +30 -11
- package/dist/cjs/crypto/signatureService.js +25 -60
- package/dist/cjs/i18n/locales/en-US.json +46 -1
- package/dist/cjs/i18n/locales/es-ES.json +46 -1
- package/dist/cjs/i18n/locales/locales/en-US.json +46 -1
- package/dist/cjs/i18n/locales/locales/es-ES.json +46 -1
- package/dist/cjs/index.js +7 -2
- package/dist/cjs/mixins/OxyServices.assets.js +9 -4
- package/dist/cjs/mixins/OxyServices.auth.js +27 -0
- package/dist/cjs/mixins/OxyServices.contacts.js +50 -0
- package/dist/cjs/mixins/OxyServices.features.js +0 -11
- package/dist/cjs/mixins/OxyServices.fedcm.js +4 -3
- package/dist/cjs/mixins/OxyServices.language.js +5 -36
- package/dist/cjs/mixins/OxyServices.redirect.js +6 -2
- package/dist/cjs/mixins/OxyServices.security.js +13 -2
- package/dist/cjs/mixins/OxyServices.user.js +70 -38
- package/dist/cjs/mixins/OxyServices.utility.js +19 -43
- package/dist/cjs/mixins/index.js +11 -3
- package/dist/cjs/utils/accountUtils.js +71 -2
- package/dist/cjs/utils/asyncUtils.js +34 -5
- package/dist/cjs/utils/deviceManager.js +5 -36
- package/dist/cjs/utils/platformCrypto.js +165 -0
- package/dist/cjs/utils/platformCrypto.native.js +123 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/CrossDomainAuth.js +3 -1
- package/dist/esm/HttpService.js +228 -52
- package/dist/esm/OxyServices.base.js +9 -0
- package/dist/esm/OxyServices.js +8 -3
- package/dist/esm/crypto/index.js +1 -1
- package/dist/esm/crypto/keyManager.js +473 -138
- package/dist/esm/crypto/polyfill.js +14 -32
- package/dist/esm/crypto/recoveryPhrase.js +30 -11
- package/dist/esm/crypto/signatureService.js +25 -27
- package/dist/esm/i18n/locales/en-US.json +46 -1
- package/dist/esm/i18n/locales/es-ES.json +46 -1
- package/dist/esm/i18n/locales/locales/en-US.json +46 -1
- package/dist/esm/i18n/locales/locales/es-ES.json +46 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/mixins/OxyServices.assets.js +9 -4
- package/dist/esm/mixins/OxyServices.auth.js +27 -0
- package/dist/esm/mixins/OxyServices.contacts.js +47 -0
- package/dist/esm/mixins/OxyServices.features.js +0 -11
- package/dist/esm/mixins/OxyServices.fedcm.js +4 -3
- package/dist/esm/mixins/OxyServices.language.js +5 -3
- package/dist/esm/mixins/OxyServices.redirect.js +6 -2
- package/dist/esm/mixins/OxyServices.security.js +13 -2
- package/dist/esm/mixins/OxyServices.user.js +70 -38
- package/dist/esm/mixins/OxyServices.utility.js +19 -10
- package/dist/esm/mixins/index.js +11 -3
- package/dist/esm/utils/accountUtils.js +67 -1
- package/dist/esm/utils/asyncUtils.js +34 -5
- package/dist/esm/utils/deviceManager.js +5 -3
- package/dist/esm/utils/platformCrypto.js +125 -0
- package/dist/esm/utils/platformCrypto.native.js +80 -0
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/HttpService.d.ts +47 -3
- package/dist/types/OxyServices.base.d.ts +7 -0
- package/dist/types/OxyServices.d.ts +36 -3
- package/dist/types/crypto/index.d.ts +1 -1
- package/dist/types/crypto/keyManager.d.ts +110 -9
- package/dist/types/crypto/polyfill.d.ts +3 -1
- package/dist/types/crypto/recoveryPhrase.d.ts +31 -7
- package/dist/types/crypto/signatureService.d.ts +4 -0
- package/dist/types/index.d.ts +4 -3
- package/dist/types/mixins/OxyServices.analytics.d.ts +1 -0
- package/dist/types/mixins/OxyServices.assets.d.ts +6 -10
- package/dist/types/mixins/OxyServices.auth.d.ts +16 -0
- package/dist/types/mixins/OxyServices.contacts.d.ts +99 -0
- package/dist/types/mixins/OxyServices.developer.d.ts +1 -0
- package/dist/types/mixins/OxyServices.devices.d.ts +1 -0
- package/dist/types/mixins/OxyServices.features.d.ts +2 -7
- package/dist/types/mixins/OxyServices.fedcm.d.ts +1 -0
- package/dist/types/mixins/OxyServices.karma.d.ts +1 -0
- package/dist/types/mixins/OxyServices.language.d.ts +1 -0
- package/dist/types/mixins/OxyServices.location.d.ts +1 -0
- package/dist/types/mixins/OxyServices.managedAccounts.d.ts +1 -0
- package/dist/types/mixins/OxyServices.payment.d.ts +1 -0
- package/dist/types/mixins/OxyServices.popup.d.ts +1 -0
- package/dist/types/mixins/OxyServices.privacy.d.ts +1 -0
- package/dist/types/mixins/OxyServices.redirect.d.ts +1 -0
- package/dist/types/mixins/OxyServices.security.d.ts +1 -0
- package/dist/types/mixins/OxyServices.topics.d.ts +1 -0
- package/dist/types/mixins/OxyServices.user.d.ts +40 -11
- package/dist/types/mixins/OxyServices.utility.d.ts +1 -0
- package/dist/types/mixins/index.d.ts +52 -4
- package/dist/types/models/interfaces.d.ts +62 -3
- package/dist/types/utils/accountUtils.d.ts +41 -1
- package/dist/types/utils/asyncUtils.d.ts +6 -2
- package/dist/types/utils/platformCrypto.d.ts +87 -0
- package/dist/types/utils/platformCrypto.native.d.ts +54 -0
- package/package.json +28 -1
- package/src/CrossDomainAuth.ts +12 -10
- package/src/HttpService.ts +264 -51
- package/src/OxyServices.base.ts +10 -0
- package/src/OxyServices.ts +9 -4
- package/src/crypto/__tests__/keyManager.test.ts +336 -0
- package/src/crypto/index.ts +6 -1
- package/src/crypto/keyManager.ts +529 -151
- package/src/crypto/polyfill.ts +14 -34
- package/src/crypto/recoveryPhrase.ts +56 -17
- package/src/crypto/signatureService.ts +25 -29
- package/src/i18n/locales/en-US.json +46 -1
- package/src/i18n/locales/es-ES.json +46 -1
- package/src/index.ts +16 -3
- package/src/mixins/OxyServices.assets.ts +15 -11
- package/src/mixins/OxyServices.auth.ts +28 -0
- package/src/mixins/OxyServices.contacts.ts +73 -0
- package/src/mixins/OxyServices.features.ts +2 -12
- package/src/mixins/OxyServices.fedcm.ts +4 -3
- package/src/mixins/OxyServices.language.ts +6 -4
- package/src/mixins/OxyServices.redirect.ts +6 -2
- package/src/mixins/OxyServices.security.ts +18 -8
- package/src/mixins/OxyServices.user.ts +90 -49
- package/src/mixins/OxyServices.utility.ts +19 -10
- package/src/mixins/index.ts +58 -7
- package/src/models/interfaces.ts +65 -3
- package/src/utils/__tests__/asyncUtils.test.ts +187 -0
- package/src/utils/accountUtils.ts +82 -2
- package/src/utils/asyncUtils.ts +39 -9
- package/src/utils/deviceManager.ts +7 -4
- package/src/utils/platformCrypto.native.ts +101 -0
- package/src/utils/platformCrypto.ts +145 -0
|
@@ -174,6 +174,7 @@ export declare function OxyServicesFedCMMixin<T extends typeof OxyServicesBase>(
|
|
|
174
174
|
};
|
|
175
175
|
clearCache(): void;
|
|
176
176
|
clearCacheEntry(key: string): void;
|
|
177
|
+
clearCacheByPrefix(prefix: string): number;
|
|
177
178
|
getCacheStats(): {
|
|
178
179
|
size: number;
|
|
179
180
|
hits: number;
|
|
@@ -171,6 +171,7 @@ export declare function OxyServicesPopupAuthMixin<T extends typeof OxyServicesBa
|
|
|
171
171
|
};
|
|
172
172
|
clearCache(): void;
|
|
173
173
|
clearCacheEntry(key: string): void;
|
|
174
|
+
clearCacheByPrefix(prefix: string): number;
|
|
174
175
|
getCacheStats(): {
|
|
175
176
|
size: number;
|
|
176
177
|
hits: number;
|
|
@@ -208,6 +208,7 @@ export declare function OxyServicesRedirectAuthMixin<T extends typeof OxyService
|
|
|
208
208
|
};
|
|
209
209
|
clearCache(): void;
|
|
210
210
|
clearCacheEntry(key: string): void;
|
|
211
|
+
clearCacheByPrefix(prefix: string): number;
|
|
211
212
|
getCacheStats(): {
|
|
212
213
|
size: number;
|
|
213
214
|
hits: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* User Management Methods Mixin
|
|
3
3
|
*/
|
|
4
|
-
import type { User, Notification, SearchProfilesResponse } from '../models/interfaces';
|
|
4
|
+
import type { User, Notification, SearchProfilesResponse, PrivacySettings } from '../models/interfaces';
|
|
5
5
|
import type { OxyServicesBase } from '../OxyServices.base';
|
|
6
6
|
import { type PaginationParams } from '../utils/apiUtils';
|
|
7
7
|
export declare function OxyServicesUserMixin<T extends typeof OxyServicesBase>(Base: T): {
|
|
@@ -10,6 +10,18 @@ export declare function OxyServicesUserMixin<T extends typeof OxyServicesBase>(B
|
|
|
10
10
|
* Get profile by username
|
|
11
11
|
*/
|
|
12
12
|
getProfileByUsername(username: string): Promise<User>;
|
|
13
|
+
/**
|
|
14
|
+
* Lightweight username lookup for login flows.
|
|
15
|
+
* Returns minimal public info: exists, color, avatar, displayName.
|
|
16
|
+
* Faster than getProfileByUsername — no stats, no formatting.
|
|
17
|
+
*/
|
|
18
|
+
lookupUsername(username: string): Promise<{
|
|
19
|
+
exists: boolean;
|
|
20
|
+
username: string;
|
|
21
|
+
color: string | null;
|
|
22
|
+
avatar: string | null;
|
|
23
|
+
displayName: string;
|
|
24
|
+
}>;
|
|
13
25
|
/**
|
|
14
26
|
* Search user profiles
|
|
15
27
|
*/
|
|
@@ -80,21 +92,30 @@ export declare function OxyServicesUserMixin<T extends typeof OxyServicesBase>(B
|
|
|
80
92
|
*/
|
|
81
93
|
getCurrentUser(): Promise<User>;
|
|
82
94
|
/**
|
|
83
|
-
* Update user profile
|
|
84
|
-
*
|
|
95
|
+
* Update user profile.
|
|
96
|
+
*
|
|
97
|
+
* Invalidates the SDK-side response cache for every endpoint that
|
|
98
|
+
* returns the current user (`GET /users/me`, `GET /session/user/*`,
|
|
99
|
+
* `GET /users/<id>`, `GET /profiles/username/*`) so the next read
|
|
100
|
+
* doesn't return a stale snapshot. Without this, a follow-up
|
|
101
|
+
* `getUserBySession` call inside the 2-minute cache window can return
|
|
102
|
+
* the pre-update user — most visibly during onboarding, where it
|
|
103
|
+
* causes the username step to flicker back as if nothing was saved.
|
|
104
|
+
*
|
|
105
|
+
* TanStack Query handles offline queuing automatically.
|
|
85
106
|
*/
|
|
86
|
-
updateProfile(updates:
|
|
107
|
+
updateProfile(updates: Partial<User>): Promise<User>;
|
|
87
108
|
/**
|
|
88
109
|
* Get privacy settings for a user
|
|
89
110
|
* @param userId - The user ID (defaults to current user)
|
|
90
111
|
*/
|
|
91
|
-
getPrivacySettings(userId?: string): Promise<
|
|
112
|
+
getPrivacySettings(userId?: string): Promise<PrivacySettings>;
|
|
92
113
|
/**
|
|
93
114
|
* Update privacy settings
|
|
94
115
|
* @param settings - Partial privacy settings object
|
|
95
116
|
* @param userId - The user ID (defaults to current user)
|
|
96
117
|
*/
|
|
97
|
-
updatePrivacySettings(settings:
|
|
118
|
+
updatePrivacySettings(settings: Partial<PrivacySettings>, userId?: string): Promise<PrivacySettings>;
|
|
98
119
|
/**
|
|
99
120
|
* Request account verification
|
|
100
121
|
*/
|
|
@@ -107,11 +128,18 @@ export declare function OxyServicesUserMixin<T extends typeof OxyServicesBase>(B
|
|
|
107
128
|
*/
|
|
108
129
|
downloadAccountData(format?: "json" | "csv"): Promise<Blob>;
|
|
109
130
|
/**
|
|
110
|
-
* Delete account permanently
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
|
|
114
|
-
|
|
131
|
+
* Delete account permanently.
|
|
132
|
+
*
|
|
133
|
+
* Signs `delete:{publicKey}:{timestamp}` with the locally-stored identity
|
|
134
|
+
* private key and submits the signature alongside the confirmation text
|
|
135
|
+
* (must equal the user's username). The signature is the cryptographic
|
|
136
|
+
* proof of ownership — only the device holding the private key can issue
|
|
137
|
+
* a valid signature, so no password is required.
|
|
138
|
+
*
|
|
139
|
+
* @param confirmText - Must equal the user's username (verified server-side)
|
|
140
|
+
* @throws If no identity is stored on this device, or signing fails
|
|
141
|
+
*/
|
|
142
|
+
deleteAccount(confirmText: string): Promise<{
|
|
115
143
|
message: string;
|
|
116
144
|
}>;
|
|
117
145
|
/**
|
|
@@ -191,6 +219,7 @@ export declare function OxyServicesUserMixin<T extends typeof OxyServicesBase>(B
|
|
|
191
219
|
};
|
|
192
220
|
clearCache(): void;
|
|
193
221
|
clearCacheEntry(key: string): void;
|
|
222
|
+
clearCacheByPrefix(prefix: string): number;
|
|
194
223
|
getCacheStats(): {
|
|
195
224
|
size: number;
|
|
196
225
|
hits: number;
|
|
@@ -163,6 +163,7 @@ export declare function OxyServicesUtilityMixin<T extends typeof OxyServicesBase
|
|
|
163
163
|
};
|
|
164
164
|
clearCache(): void;
|
|
165
165
|
clearCacheEntry(key: string): void;
|
|
166
|
+
clearCacheByPrefix(prefix: string): number;
|
|
166
167
|
getCacheStats(): {
|
|
167
168
|
size: number;
|
|
168
169
|
hits: number;
|
|
@@ -4,7 +4,50 @@
|
|
|
4
4
|
* This module provides a clean way to compose all mixins
|
|
5
5
|
* and ensures consistent ordering for better maintainability
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
import { OxyServicesBase } from '../OxyServices.base';
|
|
8
|
+
import { OxyServicesAuthMixin } from './OxyServices.auth';
|
|
9
|
+
import { OxyServicesFedCMMixin } from './OxyServices.fedcm';
|
|
10
|
+
import { OxyServicesPopupAuthMixin } from './OxyServices.popup';
|
|
11
|
+
import { OxyServicesRedirectAuthMixin } from './OxyServices.redirect';
|
|
12
|
+
import { OxyServicesUserMixin } from './OxyServices.user';
|
|
13
|
+
import { OxyServicesPrivacyMixin } from './OxyServices.privacy';
|
|
14
|
+
import { OxyServicesLanguageMixin } from './OxyServices.language';
|
|
15
|
+
import { OxyServicesPaymentMixin } from './OxyServices.payment';
|
|
16
|
+
import { OxyServicesKarmaMixin } from './OxyServices.karma';
|
|
17
|
+
import { OxyServicesAssetsMixin } from './OxyServices.assets';
|
|
18
|
+
import { OxyServicesDeveloperMixin } from './OxyServices.developer';
|
|
19
|
+
import { OxyServicesLocationMixin } from './OxyServices.location';
|
|
20
|
+
import { OxyServicesAnalyticsMixin } from './OxyServices.analytics';
|
|
21
|
+
import { OxyServicesDevicesMixin } from './OxyServices.devices';
|
|
22
|
+
import { OxyServicesSecurityMixin } from './OxyServices.security';
|
|
23
|
+
import { OxyServicesUtilityMixin } from './OxyServices.utility';
|
|
24
|
+
import { OxyServicesFeaturesMixin } from './OxyServices.features';
|
|
25
|
+
import { OxyServicesTopicsMixin } from './OxyServices.topics';
|
|
26
|
+
import { OxyServicesManagedAccountsMixin } from './OxyServices.managedAccounts';
|
|
27
|
+
import { OxyServicesContactsMixin } from './OxyServices.contacts';
|
|
28
|
+
/**
|
|
29
|
+
* Instance shape of every mixin in the pipeline, intersected. The runtime
|
|
30
|
+
* `composeOxyServices()` produces a class whose instances expose all of
|
|
31
|
+
* these methods; we surface that to TypeScript via this intersection so the
|
|
32
|
+
* `extends` site in `OxyServices.ts` can avoid an `as any` cast.
|
|
33
|
+
*
|
|
34
|
+
* If you add a new mixin to `MIXIN_PIPELINE`, add it here too so its methods
|
|
35
|
+
* are visible without a cast.
|
|
36
|
+
*/
|
|
37
|
+
type AllMixinInstances = InstanceType<ReturnType<typeof OxyServicesAuthMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesFedCMMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesPopupAuthMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesRedirectAuthMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesUserMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesPrivacyMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesLanguageMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesPaymentMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesKarmaMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesAssetsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesDeveloperMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesLocationMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesAnalyticsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesDevicesMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesSecurityMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesFeaturesMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesTopicsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesManagedAccountsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesContactsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesUtilityMixin<typeof OxyServicesBase>>>;
|
|
38
|
+
/**
|
|
39
|
+
* Constructor type for the fully composed mixin pipeline. Each mixin returns
|
|
40
|
+
* a new constructor that augments its input; reducing across the pipeline
|
|
41
|
+
* yields an instance with every mixin's methods.
|
|
42
|
+
*/
|
|
43
|
+
export type ComposedOxyServicesConstructor = new (config: import('../OxyServices.base').OxyConfig) => AllMixinInstances;
|
|
44
|
+
/**
|
|
45
|
+
* A mixin function: takes a constructor and returns an augmented constructor.
|
|
46
|
+
* Each individual mixin uses a `<T extends typeof OxyServicesBase>` generic
|
|
47
|
+
* to preserve its specific augmentations, but those refinements are
|
|
48
|
+
* intentionally collapsed across the `reduce` call below.
|
|
49
|
+
*/
|
|
50
|
+
type MixinFunction = (Base: new (...args: unknown[]) => OxyServicesBase) => new (...args: unknown[]) => OxyServicesBase;
|
|
8
51
|
/**
|
|
9
52
|
* Mixin pipeline - applied in order from first to last.
|
|
10
53
|
*
|
|
@@ -22,9 +65,14 @@ declare const MIXIN_PIPELINE: MixinFunction[];
|
|
|
22
65
|
* Composes all OxyServices mixins using a pipeline pattern.
|
|
23
66
|
*
|
|
24
67
|
* This is equivalent to the nested calls but more readable and maintainable.
|
|
25
|
-
* Adding a new mixin:
|
|
68
|
+
* Adding a new mixin: add it to MIXIN_PIPELINE at the appropriate position
|
|
69
|
+
* AND extend `AllMixinInstances` so its methods are visible to consumers.
|
|
70
|
+
*
|
|
71
|
+
* The cast through `unknown` carries the runtime augmentation chain into the
|
|
72
|
+
* static type system. `Array.reduce` cannot track each mixin's generic
|
|
73
|
+
* refinement, so we assert the final shape exposed by all mixins together.
|
|
26
74
|
*
|
|
27
|
-
* @returns The fully composed OxyServices
|
|
75
|
+
* @returns The fully composed OxyServices constructor with all mixins applied
|
|
28
76
|
*/
|
|
29
|
-
export declare function composeOxyServices():
|
|
77
|
+
export declare function composeOxyServices(): ComposedOxyServicesConstructor;
|
|
30
78
|
export { MIXIN_PIPELINE };
|
|
@@ -18,6 +18,40 @@ export interface OxyConfig {
|
|
|
18
18
|
onRequestEnd?: (url: string, method: string, duration: number, success: boolean) => void;
|
|
19
19
|
onRequestError?: (url: string, method: string, error: Error) => void;
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Privacy settings for a user account.
|
|
23
|
+
*
|
|
24
|
+
* All fields are optional because:
|
|
25
|
+
* - Updates are dot-path partial PATCHes — clients send only changed keys.
|
|
26
|
+
* - The server may return a partial subdocument depending on the API
|
|
27
|
+
* build (older builds returned only the field that changed).
|
|
28
|
+
* - User accounts created before a new toggle was introduced won't
|
|
29
|
+
* have that key persisted yet.
|
|
30
|
+
*
|
|
31
|
+
* Mirrors `IPrivacySettings` from `packages/api/src/types/privacy.types.ts`,
|
|
32
|
+
* but with every field marked optional.
|
|
33
|
+
*/
|
|
34
|
+
export interface PrivacySettings {
|
|
35
|
+
isPrivateAccount?: boolean;
|
|
36
|
+
hideOnlineStatus?: boolean;
|
|
37
|
+
hideLastSeen?: boolean;
|
|
38
|
+
profileVisibility?: boolean;
|
|
39
|
+
loginAlerts?: boolean;
|
|
40
|
+
blockScreenshots?: boolean;
|
|
41
|
+
login?: boolean;
|
|
42
|
+
biometricLogin?: boolean;
|
|
43
|
+
showActivity?: boolean;
|
|
44
|
+
allowTagging?: boolean;
|
|
45
|
+
allowMentions?: boolean;
|
|
46
|
+
hideReadReceipts?: boolean;
|
|
47
|
+
allowDirectMessages?: boolean;
|
|
48
|
+
dataSharing?: boolean;
|
|
49
|
+
locationSharing?: boolean;
|
|
50
|
+
analyticsSharing?: boolean;
|
|
51
|
+
sensitiveContent?: boolean;
|
|
52
|
+
autoFilter?: boolean;
|
|
53
|
+
muteKeywords?: boolean;
|
|
54
|
+
}
|
|
21
55
|
export interface User {
|
|
22
56
|
id: string;
|
|
23
57
|
publicKey: string;
|
|
@@ -25,9 +59,7 @@ export interface User {
|
|
|
25
59
|
email?: string;
|
|
26
60
|
avatar?: string;
|
|
27
61
|
color?: string;
|
|
28
|
-
privacySettings?:
|
|
29
|
-
[key: string]: unknown;
|
|
30
|
-
};
|
|
62
|
+
privacySettings?: PrivacySettings;
|
|
31
63
|
name?: {
|
|
32
64
|
first?: string;
|
|
33
65
|
last?: string;
|
|
@@ -240,6 +272,33 @@ export interface FileDeleteResponse {
|
|
|
240
272
|
message: string;
|
|
241
273
|
fileId: string;
|
|
242
274
|
}
|
|
275
|
+
/**
|
|
276
|
+
* React Native file descriptor accepted by FormData.
|
|
277
|
+
*
|
|
278
|
+
* On React Native, the multipart upload reads the file from disk via the URI
|
|
279
|
+
* during the network request — no in-JS Blob construction is required (and
|
|
280
|
+
* doing so would fail on Hermes since RN's BlobManager cannot wrap an
|
|
281
|
+
* ArrayBuffer/ArrayBufferView).
|
|
282
|
+
*
|
|
283
|
+
* This shape matches what `expo-document-picker` and `expo-image-picker`
|
|
284
|
+
* return for selected assets, and is what `OxyServices.assetUpload` accepts
|
|
285
|
+
* on native platforms.
|
|
286
|
+
*/
|
|
287
|
+
export interface RNFileDescriptor {
|
|
288
|
+
uri: string;
|
|
289
|
+
type?: string;
|
|
290
|
+
name?: string;
|
|
291
|
+
size?: number;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Asset upload input — accepted by `OxyServices.assetUpload` and `uploadRawFile`.
|
|
295
|
+
*
|
|
296
|
+
* - `File` / `Blob`: standard web browser path. `assetUpload` appends the
|
|
297
|
+
* Blob to FormData directly.
|
|
298
|
+
* - {@link RNFileDescriptor}: React Native path. FormData reads the file from
|
|
299
|
+
* disk via the URI during the multipart request.
|
|
300
|
+
*/
|
|
301
|
+
export type AssetUploadInput = File | Blob | RNFileDescriptor;
|
|
243
302
|
/**
|
|
244
303
|
* Central Asset Service interfaces
|
|
245
304
|
*/
|
|
@@ -10,6 +10,44 @@ export interface QuickAccount {
|
|
|
10
10
|
avatar?: string;
|
|
11
11
|
avatarUrl?: string;
|
|
12
12
|
}
|
|
13
|
+
/** Minimal user shape accepted by display-name helpers. Avoids importing the full User type. */
|
|
14
|
+
export interface DisplayNameUserShape {
|
|
15
|
+
name?: string | {
|
|
16
|
+
first?: string;
|
|
17
|
+
last?: string;
|
|
18
|
+
full?: string;
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
};
|
|
21
|
+
username?: string;
|
|
22
|
+
publicKey?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Truncate a long public key for display, e.g. `0x12345678…`.
|
|
26
|
+
* Falls back to the raw key if it's too short to truncate.
|
|
27
|
+
*/
|
|
28
|
+
export declare const formatPublicKeyHandle: (publicKey: string) => string;
|
|
29
|
+
/**
|
|
30
|
+
* Resolve a friendly display name for a user.
|
|
31
|
+
*
|
|
32
|
+
* Order of preference:
|
|
33
|
+
* 1. `name.full`, or composed `name.first name.last`
|
|
34
|
+
* 2. `name` (when stored as a plain string)
|
|
35
|
+
* 3. `username`
|
|
36
|
+
* 4. `Account 0x12345678…` (derived from publicKey, when present)
|
|
37
|
+
* 5. Translated fallback (e.g. "Unnamed")
|
|
38
|
+
*
|
|
39
|
+
* The translation key `common.unnamed` is used for the final fallback. If the
|
|
40
|
+
* caller does not pass a locale, the default English translation is used.
|
|
41
|
+
*/
|
|
42
|
+
export declare const getAccountDisplayName: (user: DisplayNameUserShape | null | undefined, locale?: string) => string;
|
|
43
|
+
/**
|
|
44
|
+
* Resolve a `@handle` style identifier for a user.
|
|
45
|
+
*
|
|
46
|
+
* Returns the bare username when present (without the `@`), otherwise a
|
|
47
|
+
* truncated public-key handle (`0x12345678…`), or `undefined` when neither is
|
|
48
|
+
* available — callers can decide whether to hide the line entirely.
|
|
49
|
+
*/
|
|
50
|
+
export declare const getAccountFallbackHandle: (user: DisplayNameUserShape | null | undefined) => string | undefined;
|
|
13
51
|
/**
|
|
14
52
|
* Build an ordered array of QuickAccounts from a map and order list.
|
|
15
53
|
*/
|
|
@@ -23,11 +61,13 @@ export declare const buildAccountsArray: (accounts: Record<string, QuickAccount>
|
|
|
23
61
|
* @param getFileDownloadUrl - Function to generate avatar download URL from file ID
|
|
24
62
|
*/
|
|
25
63
|
export declare const createQuickAccount: (sessionId: string, userData: {
|
|
26
|
-
name?: {
|
|
64
|
+
name?: string | {
|
|
27
65
|
full?: string;
|
|
28
66
|
first?: string;
|
|
67
|
+
last?: string;
|
|
29
68
|
};
|
|
30
69
|
username?: string;
|
|
70
|
+
publicKey?: string;
|
|
31
71
|
id?: string;
|
|
32
72
|
_id?: {
|
|
33
73
|
toString(): string;
|
|
@@ -13,8 +13,12 @@ export declare function parallelWithErrorHandling<T>(operations: (() => Promise<
|
|
|
13
13
|
/**
|
|
14
14
|
* Retry an async operation with exponential backoff
|
|
15
15
|
*
|
|
16
|
-
* By default, does not retry on 4xx errors (client errors).
|
|
17
|
-
*
|
|
16
|
+
* By default, does not retry on 4xx errors (client errors). The default
|
|
17
|
+
* predicate accepts both the axios-style `error.response.status` and the
|
|
18
|
+
* flat `error.status` shape produced by {@link handleHttpError}, so callers
|
|
19
|
+
* never accidentally retry a deterministic client failure.
|
|
20
|
+
*
|
|
21
|
+
* Use the `shouldRetry` callback to customize retry behavior.
|
|
18
22
|
*/
|
|
19
23
|
export declare function retryAsync<T>(operation: () => Promise<T>, maxRetries?: number, baseDelay?: number, shouldRetry?: (error: any) => boolean): Promise<T>;
|
|
20
24
|
/**
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform Crypto / Storage — Default Variant (Node.js, Browser, generic bundlers)
|
|
3
|
+
*
|
|
4
|
+
* Provides lazy access to platform-specific crypto and storage modules.
|
|
5
|
+
*
|
|
6
|
+
* # Variants
|
|
7
|
+
*
|
|
8
|
+
* This module ships in two physical variants on disk, selected per consumer
|
|
9
|
+
* by the bundler / runtime:
|
|
10
|
+
*
|
|
11
|
+
* - `platformCrypto.js` — this file. Used by Node.js, Vite, webpack,
|
|
12
|
+
* Rollup, esbuild, and anything that does
|
|
13
|
+
* not match Metro's `*.native.js`
|
|
14
|
+
* source-extension preference.
|
|
15
|
+
* - `platformCrypto.native.js` — sibling file. Picked up automatically by
|
|
16
|
+
* Metro's resolver (which prefers
|
|
17
|
+
* `*.<platform>.js` and `*.native.js` over
|
|
18
|
+
* plain `*.js` when `preferNativePlatform`
|
|
19
|
+
* is true — Expo sets this for all non-web
|
|
20
|
+
* builds).
|
|
21
|
+
*
|
|
22
|
+
* The `package.json#exports` map also declares a `"react-native"` condition
|
|
23
|
+
* pointing at the same `dist/esm/index.js` entry — that entry transitively
|
|
24
|
+
* imports `./platformCrypto`, and Metro's per-file source-extension lookup
|
|
25
|
+
* substitutes the `.native.js` sibling automatically inside `dist/`. This
|
|
26
|
+
* means consumers never have to add resolver shims; Metro Just Works.
|
|
27
|
+
*
|
|
28
|
+
* Both variants expose the EXACT same public API; importers don't need to know
|
|
29
|
+
* which one they got. The variant difference is purely about which underlying
|
|
30
|
+
* native modules each one references:
|
|
31
|
+
*
|
|
32
|
+
* ┌──────────────────┬───────────────────────┬───────────────────────────────┐
|
|
33
|
+
* │ Function │ Default variant │ React Native variant │
|
|
34
|
+
* ├──────────────────┼───────────────────────┼───────────────────────────────┤
|
|
35
|
+
* │ loadNodeCrypto │ `await import('crypto')` (Node built-in) │
|
|
36
|
+
* │ │ │ throws — Node crypto is not │
|
|
37
|
+
* │ │ │ available on Hermes/RN │
|
|
38
|
+
* ├──────────────────┼───────────────────────┼───────────────────────────────┤
|
|
39
|
+
* │ loadExpoCrypto │ throws — expo-crypto │ static `import 'expo-crypto'` │
|
|
40
|
+
* │ │ is not part of a │ │
|
|
41
|
+
* │ │ Node/Vite bundle │ │
|
|
42
|
+
* ├──────────────────┼───────────────────────┼───────────────────────────────┤
|
|
43
|
+
* │ loadSecureStore │ throws (web/Node have │ static `import 'expo-secure-` │
|
|
44
|
+
* │ │ their own storage) │ store' │
|
|
45
|
+
* ├──────────────────┼───────────────────────┼───────────────────────────────┤
|
|
46
|
+
* │ loadAsyncStorage │ throws (web/Node have │ static `import '@react- │
|
|
47
|
+
* │ │ their own storage) │ native-async-storage/...' │
|
|
48
|
+
* ├──────────────────┼───────────────────────┼───────────────────────────────┤
|
|
49
|
+
* │ getRandomBytesRN │ throws (RN-only) │ direct call into expo-crypto │
|
|
50
|
+
* └──────────────────┴───────────────────────┴───────────────────────────────┘
|
|
51
|
+
*
|
|
52
|
+
* Crucially, the default variant references ONLY Node's `'crypto'`. It never
|
|
53
|
+
* mentions `expo-*` or `@react-native-async-storage/*` — so Vite, webpack,
|
|
54
|
+
* esbuild, Rollup, and Node itself can bundle / require it without ever
|
|
55
|
+
* attempting to resolve those RN-only packages.
|
|
56
|
+
*
|
|
57
|
+
* The React Native variant references ONLY the RN packages. It never
|
|
58
|
+
* mentions `'crypto'` — so Metro and Hermes have nothing to choke on.
|
|
59
|
+
*
|
|
60
|
+
* # Why not a single file with dynamic import?
|
|
61
|
+
*
|
|
62
|
+
* A previous iteration used a "bundler-opaque" `new Function('s', 'return
|
|
63
|
+
* import(s)')` trick so a single file could service every platform. It
|
|
64
|
+
* bundled cleanly on Metro but Hermes refused to PARSE the resulting
|
|
65
|
+
* `import()` expression inside a Function-constructor body
|
|
66
|
+
* (`SyntaxError: Invalid expression encountered` at the `(` of `import(`).
|
|
67
|
+
* The platform-extension split is the only approach that lets each runtime
|
|
68
|
+
* see a file containing only specifiers it can understand — no tricks, no
|
|
69
|
+
* runtime parsing risks.
|
|
70
|
+
*/
|
|
71
|
+
export declare function loadNodeCrypto(): Promise<typeof import('crypto')>;
|
|
72
|
+
export declare function loadExpoCrypto(): Promise<typeof import('expo-crypto')>;
|
|
73
|
+
export declare function loadSecureStore(): Promise<typeof import('expo-secure-store')>;
|
|
74
|
+
export declare function loadAsyncStorage(): Promise<{
|
|
75
|
+
default: {
|
|
76
|
+
getItem: (key: string) => Promise<string | null>;
|
|
77
|
+
setItem: (key: string, value: string) => Promise<void>;
|
|
78
|
+
removeItem: (key: string) => Promise<void>;
|
|
79
|
+
};
|
|
80
|
+
}>;
|
|
81
|
+
/**
|
|
82
|
+
* Synchronous random-bytes via `expo-crypto.getRandomBytes`. Only available
|
|
83
|
+
* in the React Native variant. The default variant throws because Node and
|
|
84
|
+
* browsers have their own native CSPRNGs (`crypto.randomBytes` and
|
|
85
|
+
* `crypto.getRandomValues` respectively) — callers should use those.
|
|
86
|
+
*/
|
|
87
|
+
export declare function getRandomBytesRN(_byteCount: number): Uint8Array;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform Crypto / Storage — React Native Variant
|
|
3
|
+
*
|
|
4
|
+
* Companion to `./platformCrypto.ts`. See the doc-comment at the top of that
|
|
5
|
+
* file for the full design.
|
|
6
|
+
*
|
|
7
|
+
* Metro auto-selects this file in any non-web build (`preferNativePlatform`
|
|
8
|
+
* is `true` for iOS / Android, so `*.native.js` shadows `*.js` during
|
|
9
|
+
* source-extension resolution inside `node_modules/@oxyhq/core/dist/`). On
|
|
10
|
+
* iOS / Android `<base>.ios.js` / `<base>.android.js` would shadow this file
|
|
11
|
+
* if they existed, but they don't — `.native.js` is the shared RN variant.
|
|
12
|
+
*
|
|
13
|
+
* - The default variant references Node's `'crypto'` and would crash Metro
|
|
14
|
+
* if bundled into an RN app.
|
|
15
|
+
* - This variant references the RN-only modules (`expo-crypto`,
|
|
16
|
+
* `expo-secure-store`, `@react-native-async-storage/async-storage`)
|
|
17
|
+
* as static imports, so Metro and Hermes both resolve and parse them
|
|
18
|
+
* cleanly.
|
|
19
|
+
*
|
|
20
|
+
* Both variants expose the same surface; importers don't care which one
|
|
21
|
+
* they got.
|
|
22
|
+
*
|
|
23
|
+
* # Why static imports?
|
|
24
|
+
*
|
|
25
|
+
* Every RN consumer of `@oxyhq/core` already lists or transitively pulls
|
|
26
|
+
* in `expo-crypto`, `expo-secure-store`, and
|
|
27
|
+
* `@react-native-async-storage/async-storage` (they're stable Expo modules
|
|
28
|
+
* present in `services`, `accounts`, `inbox`, and `test-app`). A static
|
|
29
|
+
* import is what Metro wants to see anyway, and Hermes parses it like any
|
|
30
|
+
* other ES module — no `Function`-constructor parser exotic-mode involved.
|
|
31
|
+
*
|
|
32
|
+
* This is also clearer to debug: Metro fails up-front with a normal
|
|
33
|
+
* unresolved-module error if a consumer is missing a peer dep, instead of
|
|
34
|
+
* a confusing runtime throw the first time a code path that needs the
|
|
35
|
+
* module is exercised.
|
|
36
|
+
*/
|
|
37
|
+
export declare function loadNodeCrypto(): Promise<typeof import('crypto')>;
|
|
38
|
+
export declare function loadExpoCrypto(): Promise<typeof import('expo-crypto')>;
|
|
39
|
+
export declare function loadSecureStore(): Promise<typeof import('expo-secure-store')>;
|
|
40
|
+
type AsyncStorageLike = {
|
|
41
|
+
getItem: (key: string) => Promise<string | null>;
|
|
42
|
+
setItem: (key: string, value: string) => Promise<void>;
|
|
43
|
+
removeItem: (key: string) => Promise<void>;
|
|
44
|
+
};
|
|
45
|
+
export declare function loadAsyncStorage(): Promise<{
|
|
46
|
+
default: AsyncStorageLike;
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* Synchronous random-bytes via `expo-crypto.getRandomBytes`. Available
|
|
50
|
+
* synchronously because `expo-crypto` is statically imported by this file
|
|
51
|
+
* — no async initialization race.
|
|
52
|
+
*/
|
|
53
|
+
export declare function getRandomBytesRN(byteCount: number): Uint8Array;
|
|
54
|
+
export {};
|