@oxyhq/services 5.13.15 → 5.13.16

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 (138) hide show
  1. package/README.md +10 -0
  2. package/lib/commonjs/core/OxyServices.base.js +271 -0
  3. package/lib/commonjs/core/OxyServices.base.js.map +1 -0
  4. package/lib/commonjs/core/OxyServices.errors.js +26 -0
  5. package/lib/commonjs/core/OxyServices.errors.js.map +1 -0
  6. package/lib/commonjs/core/OxyServices.js +58 -2168
  7. package/lib/commonjs/core/OxyServices.js.map +1 -1
  8. package/lib/commonjs/core/mixins/OxyServices.analytics.js +60 -0
  9. package/lib/commonjs/core/mixins/OxyServices.analytics.js.map +1 -0
  10. package/lib/commonjs/core/mixins/OxyServices.assets.js +406 -0
  11. package/lib/commonjs/core/mixins/OxyServices.assets.js.map +1 -0
  12. package/lib/commonjs/core/mixins/OxyServices.auth.js +303 -0
  13. package/lib/commonjs/core/mixins/OxyServices.auth.js.map +1 -0
  14. package/lib/commonjs/core/mixins/OxyServices.developer.js +115 -0
  15. package/lib/commonjs/core/mixins/OxyServices.developer.js.map +1 -0
  16. package/lib/commonjs/core/mixins/OxyServices.devices.js +119 -0
  17. package/lib/commonjs/core/mixins/OxyServices.devices.js.map +1 -0
  18. package/lib/commonjs/core/mixins/OxyServices.karma.js +117 -0
  19. package/lib/commonjs/core/mixins/OxyServices.karma.js.map +1 -0
  20. package/lib/commonjs/core/mixins/OxyServices.language.js +124 -0
  21. package/lib/commonjs/core/mixins/OxyServices.language.js.map +1 -0
  22. package/lib/commonjs/core/mixins/OxyServices.location.js +55 -0
  23. package/lib/commonjs/core/mixins/OxyServices.location.js.map +1 -0
  24. package/lib/commonjs/core/mixins/OxyServices.payment.js +66 -0
  25. package/lib/commonjs/core/mixins/OxyServices.payment.js.map +1 -0
  26. package/lib/commonjs/core/mixins/OxyServices.privacy.js +174 -0
  27. package/lib/commonjs/core/mixins/OxyServices.privacy.js.map +1 -0
  28. package/lib/commonjs/core/mixins/OxyServices.totp.js +53 -0
  29. package/lib/commonjs/core/mixins/OxyServices.totp.js.map +1 -0
  30. package/lib/commonjs/core/mixins/OxyServices.user.js +389 -0
  31. package/lib/commonjs/core/mixins/OxyServices.user.js.map +1 -0
  32. package/lib/commonjs/core/mixins/OxyServices.utility.js +161 -0
  33. package/lib/commonjs/core/mixins/OxyServices.utility.js.map +1 -0
  34. package/lib/commonjs/core/mixins/index.js +39 -0
  35. package/lib/commonjs/core/mixins/index.js.map +1 -0
  36. package/lib/commonjs/core/mixins/mixinHelpers.js +62 -0
  37. package/lib/commonjs/core/mixins/mixinHelpers.js.map +1 -0
  38. package/lib/commonjs/ui/context/OxyContext.js +27 -2
  39. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  40. package/lib/module/core/OxyServices.base.js +265 -0
  41. package/lib/module/core/OxyServices.base.js.map +1 -0
  42. package/lib/module/core/OxyServices.errors.js +20 -0
  43. package/lib/module/core/OxyServices.errors.js.map +1 -0
  44. package/lib/module/core/OxyServices.js +43 -2164
  45. package/lib/module/core/OxyServices.js.map +1 -1
  46. package/lib/module/core/mixins/OxyServices.analytics.js +56 -0
  47. package/lib/module/core/mixins/OxyServices.analytics.js.map +1 -0
  48. package/lib/module/core/mixins/OxyServices.assets.js +402 -0
  49. package/lib/module/core/mixins/OxyServices.assets.js.map +1 -0
  50. package/lib/module/core/mixins/OxyServices.auth.js +299 -0
  51. package/lib/module/core/mixins/OxyServices.auth.js.map +1 -0
  52. package/lib/module/core/mixins/OxyServices.developer.js +111 -0
  53. package/lib/module/core/mixins/OxyServices.developer.js.map +1 -0
  54. package/lib/module/core/mixins/OxyServices.devices.js +115 -0
  55. package/lib/module/core/mixins/OxyServices.devices.js.map +1 -0
  56. package/lib/module/core/mixins/OxyServices.karma.js +113 -0
  57. package/lib/module/core/mixins/OxyServices.karma.js.map +1 -0
  58. package/lib/module/core/mixins/OxyServices.language.js +120 -0
  59. package/lib/module/core/mixins/OxyServices.language.js.map +1 -0
  60. package/lib/module/core/mixins/OxyServices.location.js +51 -0
  61. package/lib/module/core/mixins/OxyServices.location.js.map +1 -0
  62. package/lib/module/core/mixins/OxyServices.payment.js +62 -0
  63. package/lib/module/core/mixins/OxyServices.payment.js.map +1 -0
  64. package/lib/module/core/mixins/OxyServices.privacy.js +170 -0
  65. package/lib/module/core/mixins/OxyServices.privacy.js.map +1 -0
  66. package/lib/module/core/mixins/OxyServices.totp.js +49 -0
  67. package/lib/module/core/mixins/OxyServices.totp.js.map +1 -0
  68. package/lib/module/core/mixins/OxyServices.user.js +385 -0
  69. package/lib/module/core/mixins/OxyServices.user.js.map +1 -0
  70. package/lib/module/core/mixins/OxyServices.utility.js +156 -0
  71. package/lib/module/core/mixins/OxyServices.utility.js.map +1 -0
  72. package/lib/module/core/mixins/index.js +36 -0
  73. package/lib/module/core/mixins/index.js.map +1 -0
  74. package/lib/module/core/mixins/mixinHelpers.js +56 -0
  75. package/lib/module/core/mixins/mixinHelpers.js.map +1 -0
  76. package/lib/module/ui/context/OxyContext.js +27 -2
  77. package/lib/module/ui/context/OxyContext.js.map +1 -1
  78. package/lib/typescript/core/OxyServices.base.d.ts +123 -0
  79. package/lib/typescript/core/OxyServices.base.d.ts.map +1 -0
  80. package/lib/typescript/core/OxyServices.d.ts +969 -746
  81. package/lib/typescript/core/OxyServices.d.ts.map +1 -1
  82. package/lib/typescript/core/OxyServices.errors.d.ts +12 -0
  83. package/lib/typescript/core/OxyServices.errors.d.ts.map +1 -0
  84. package/lib/typescript/core/mixins/OxyServices.analytics.d.ts +70 -0
  85. package/lib/typescript/core/mixins/OxyServices.analytics.d.ts.map +1 -0
  86. package/lib/typescript/core/mixins/OxyServices.assets.d.ts +159 -0
  87. package/lib/typescript/core/mixins/OxyServices.assets.d.ts.map +1 -0
  88. package/lib/typescript/core/mixins/OxyServices.auth.d.ts +168 -0
  89. package/lib/typescript/core/mixins/OxyServices.auth.d.ts.map +1 -0
  90. package/lib/typescript/core/mixins/OxyServices.developer.d.ts +103 -0
  91. package/lib/typescript/core/mixins/OxyServices.developer.d.ts.map +1 -0
  92. package/lib/typescript/core/mixins/OxyServices.devices.d.ts +93 -0
  93. package/lib/typescript/core/mixins/OxyServices.devices.d.ts.map +1 -0
  94. package/lib/typescript/core/mixins/OxyServices.karma.d.ts +89 -0
  95. package/lib/typescript/core/mixins/OxyServices.karma.d.ts.map +1 -0
  96. package/lib/typescript/core/mixins/OxyServices.language.d.ts +85 -0
  97. package/lib/typescript/core/mixins/OxyServices.language.d.ts.map +1 -0
  98. package/lib/typescript/core/mixins/OxyServices.location.d.ts +68 -0
  99. package/lib/typescript/core/mixins/OxyServices.location.d.ts.map +1 -0
  100. package/lib/typescript/core/mixins/OxyServices.payment.d.ts +74 -0
  101. package/lib/typescript/core/mixins/OxyServices.payment.d.ts.map +1 -0
  102. package/lib/typescript/core/mixins/OxyServices.privacy.d.ts +126 -0
  103. package/lib/typescript/core/mixins/OxyServices.privacy.d.ts.map +1 -0
  104. package/lib/typescript/core/mixins/OxyServices.totp.d.ts +69 -0
  105. package/lib/typescript/core/mixins/OxyServices.totp.d.ts.map +1 -0
  106. package/lib/typescript/core/mixins/OxyServices.user.d.ts +189 -0
  107. package/lib/typescript/core/mixins/OxyServices.user.d.ts.map +1 -0
  108. package/lib/typescript/core/mixins/OxyServices.utility.d.ts +97 -0
  109. package/lib/typescript/core/mixins/OxyServices.utility.d.ts.map +1 -0
  110. package/lib/typescript/core/mixins/index.d.ts +898 -0
  111. package/lib/typescript/core/mixins/index.d.ts.map +1 -0
  112. package/lib/typescript/core/mixins/mixinHelpers.d.ts +32 -0
  113. package/lib/typescript/core/mixins/mixinHelpers.d.ts.map +1 -0
  114. package/lib/typescript/models/interfaces.d.ts +10 -0
  115. package/lib/typescript/models/interfaces.d.ts.map +1 -1
  116. package/lib/typescript/ui/context/OxyContext.d.ts +2 -0
  117. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  118. package/package.json +1 -1
  119. package/src/core/OxyServices.base.ts +311 -0
  120. package/src/core/OxyServices.errors.ts +26 -0
  121. package/src/core/OxyServices.ts +43 -2199
  122. package/src/core/mixins/OxyServices.analytics.ts +53 -0
  123. package/src/core/mixins/OxyServices.assets.ts +390 -0
  124. package/src/core/mixins/OxyServices.auth.ts +275 -0
  125. package/src/core/mixins/OxyServices.developer.ts +114 -0
  126. package/src/core/mixins/OxyServices.devices.ts +103 -0
  127. package/src/core/mixins/OxyServices.karma.ts +111 -0
  128. package/src/core/mixins/OxyServices.language.ts +127 -0
  129. package/src/core/mixins/OxyServices.location.ts +46 -0
  130. package/src/core/mixins/OxyServices.payment.ts +59 -0
  131. package/src/core/mixins/OxyServices.privacy.ts +182 -0
  132. package/src/core/mixins/OxyServices.totp.ts +36 -0
  133. package/src/core/mixins/OxyServices.user.ts +380 -0
  134. package/src/core/mixins/OxyServices.utility.ts +187 -0
  135. package/src/core/mixins/index.ts +58 -0
  136. package/src/core/mixins/mixinHelpers.ts +69 -0
  137. package/src/models/interfaces.ts +12 -0
  138. package/src/ui/context/OxyContext.tsx +36 -0
@@ -0,0 +1,275 @@
1
+ /**
2
+ * Authentication Methods Mixin
3
+ */
4
+ import type { User } from '../../models/interfaces';
5
+ import type { SessionLoginResponse } from '../../models/session';
6
+ import type { OxyServicesBase } from '../OxyServices.base';
7
+ import { OxyAuthenticationError } from '../OxyServices.errors';
8
+
9
+ export function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(Base: T) {
10
+ return class extends Base {
11
+ constructor(...args: any[]) {
12
+ super(...(args as [any]));
13
+ }
14
+ /**
15
+ * Sign up a new user
16
+ */
17
+ async signUp(username: string, email: string, password: string): Promise<{ message: string; token: string; user: User }> {
18
+ try {
19
+ const res = await this.makeRequest<{ message: string; token: string; user: User }>('POST', '/api/auth/signup', {
20
+ username,
21
+ email,
22
+ password
23
+ }, { cache: false });
24
+ if (!res || (typeof res === 'object' && Object.keys(res).length === 0)) {
25
+ throw new OxyAuthenticationError('Sign up failed', 'SIGNUP_FAILED', 400);
26
+ }
27
+ return res;
28
+ } catch (error) {
29
+ throw this.handleError(error);
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Request account recovery (send verification code)
35
+ */
36
+ async requestRecovery(identifier: string): Promise<{ delivery?: string; destination?: string }> {
37
+ try {
38
+ return await this.makeRequest('POST', '/api/auth/recover/request', { identifier }, { cache: false });
39
+ } catch (error: any) {
40
+ throw this.handleError(error);
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Verify recovery code
46
+ */
47
+ async verifyRecoveryCode(identifier: string, code: string): Promise<{ verified: boolean }> {
48
+ try {
49
+ return await this.makeRequest('POST', '/api/auth/recover/verify', { identifier, code }, { cache: false });
50
+ } catch (error: any) {
51
+ throw this.handleError(error);
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Reset password using verified code
57
+ */
58
+ async resetPassword(identifier: string, code: string, newPassword: string): Promise<{ success: boolean }> {
59
+ try {
60
+ return await this.makeRequest('POST', '/api/auth/recover/reset', { identifier, code, newPassword }, { cache: false });
61
+ } catch (error: any) {
62
+ throw this.handleError(error);
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Reset password using TOTP code (recommended recovery)
68
+ */
69
+ async resetPasswordWithTotp(identifier: string, code: string, newPassword: string): Promise<{ success: boolean }> {
70
+ try {
71
+ return await this.makeRequest('POST', '/api/auth/recover/totp/reset', { identifier, code, newPassword }, { cache: false });
72
+ } catch (error: any) {
73
+ throw this.handleError(error);
74
+ }
75
+ }
76
+
77
+ async resetPasswordWithBackupCode(identifier: string, backupCode: string, newPassword: string): Promise<{ success: boolean }> {
78
+ try {
79
+ return await this.makeRequest('POST', '/api/auth/recover/backup/reset', { identifier, backupCode, newPassword }, { cache: false });
80
+ } catch (error: any) {
81
+ throw this.handleError(error);
82
+ }
83
+ }
84
+
85
+ async resetPasswordWithRecoveryKey(identifier: string, recoveryKey: string, newPassword: string): Promise<{ success: boolean; nextRecoveryKey?: string }> {
86
+ try {
87
+ return await this.makeRequest('POST', '/api/auth/recover/recovery-key/reset', { identifier, recoveryKey, newPassword }, { cache: false });
88
+ } catch (error: any) {
89
+ throw this.handleError(error);
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Sign in with device management
95
+ */
96
+ async signIn(
97
+ username: string,
98
+ password: string,
99
+ deviceName?: string,
100
+ deviceFingerprint?: any
101
+ ): Promise<SessionLoginResponse | { mfaRequired: true; mfaToken: string; expiresAt: string }> {
102
+ try {
103
+ return await this.makeRequest<SessionLoginResponse | { mfaRequired: true; mfaToken: string; expiresAt: string }>('POST', '/api/auth/login', {
104
+ username,
105
+ password,
106
+ deviceName,
107
+ deviceFingerprint
108
+ }, { cache: false });
109
+ } catch (error) {
110
+ throw this.handleError(error);
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Complete login by verifying TOTP with MFA token
116
+ */
117
+ async verifyTotpLogin(mfaToken: string, code: string): Promise<SessionLoginResponse> {
118
+ try {
119
+ return await this.makeRequest<SessionLoginResponse>('POST', '/api/auth/totp/verify-login', { mfaToken, code }, { cache: false });
120
+ } catch (error) {
121
+ throw this.handleError(error);
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Get user by session ID
127
+ */
128
+ async getUserBySession(sessionId: string): Promise<User> {
129
+ try {
130
+ return await this.makeRequest<User>('GET', `/api/session/user/${sessionId}`, undefined, {
131
+ cache: true,
132
+ cacheTTL: 2 * 60 * 1000, // 2 minutes cache for user data
133
+ });
134
+ } catch (error) {
135
+ throw this.handleError(error);
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Batch get multiple user profiles by session IDs (optimized for account switching)
141
+ * Returns array of { sessionId, user } objects
142
+ */
143
+ async getUsersBySessions(sessionIds: string[]): Promise<Array<{ sessionId: string; user: User | null }>> {
144
+ try {
145
+ if (!Array.isArray(sessionIds) || sessionIds.length === 0) {
146
+ return [];
147
+ }
148
+
149
+ // Deduplicate and sort sessionIds for consistent cache keys
150
+ const uniqueSessionIds = Array.from(new Set(sessionIds)).sort();
151
+
152
+ return await this.makeRequest<Array<{ sessionId: string; user: User | null }>>(
153
+ 'POST',
154
+ '/api/session/users/batch',
155
+ { sessionIds: uniqueSessionIds },
156
+ {
157
+ cache: true,
158
+ cacheTTL: 2 * 60 * 1000, // 2 minutes cache
159
+ deduplicate: true, // Important for batch requests
160
+ }
161
+ );
162
+ } catch (error) {
163
+ throw this.handleError(error);
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Get access token by session ID and set it in the token store
169
+ */
170
+ async getTokenBySession(sessionId: string): Promise<{ accessToken: string; expiresAt: string }> {
171
+ try {
172
+ const res = await this.makeRequest<{ accessToken: string; expiresAt: string }>('GET', `/api/session/token/${sessionId}`, undefined, {
173
+ cache: false,
174
+ retry: false,
175
+ });
176
+
177
+ // Set the token in the centralized token store
178
+ this.setTokens(res.accessToken);
179
+
180
+ return res;
181
+ } catch (error) {
182
+ throw this.handleError(error);
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Get sessions by session ID
188
+ */
189
+ async getSessionsBySessionId(sessionId: string): Promise<any[]> {
190
+ try {
191
+ return await this.makeRequest('GET', `/api/session/sessions/${sessionId}`, undefined, {
192
+ cache: false,
193
+ });
194
+ } catch (error) {
195
+ throw this.handleError(error);
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Logout from a specific session
201
+ */
202
+ async logoutSession(sessionId: string, targetSessionId?: string): Promise<void> {
203
+ try {
204
+ const url = targetSessionId
205
+ ? `/api/session/logout/${sessionId}/${targetSessionId}`
206
+ : `/api/session/logout/${sessionId}`;
207
+
208
+ await this.makeRequest('POST', url, undefined, { cache: false });
209
+ } catch (error) {
210
+ throw this.handleError(error);
211
+ }
212
+ }
213
+
214
+ /**
215
+ * Logout from all sessions
216
+ */
217
+ async logoutAllSessions(sessionId: string): Promise<void> {
218
+ try {
219
+ await this.makeRequest('POST', `/api/session/logout-all/${sessionId}`, undefined, { cache: false });
220
+ } catch (error) {
221
+ throw this.handleError(error);
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Validate session
227
+ */
228
+ async validateSession(
229
+ sessionId: string,
230
+ options: {
231
+ deviceFingerprint?: string;
232
+ useHeaderValidation?: boolean;
233
+ } = {}
234
+ ): Promise<{
235
+ valid: boolean;
236
+ expiresAt: string;
237
+ lastActivity: string;
238
+ user: User;
239
+ sessionId?: string;
240
+ source?: string;
241
+ }> {
242
+ try {
243
+ const urlParams: any = {};
244
+ if (options.deviceFingerprint) urlParams.deviceFingerprint = options.deviceFingerprint;
245
+ if (options.useHeaderValidation) urlParams.useHeaderValidation = 'true';
246
+ return await this.makeRequest('GET', `/api/session/validate/${sessionId}`, urlParams, { cache: false });
247
+ } catch (error) {
248
+ throw this.handleError(error);
249
+ }
250
+ }
251
+
252
+ /**
253
+ * Check username availability
254
+ */
255
+ async checkUsernameAvailability(username: string): Promise<{ available: boolean; message: string }> {
256
+ try {
257
+ return await this.makeRequest('GET', `/api/auth/check-username/${username}`, undefined, { cache: false });
258
+ } catch (error) {
259
+ throw this.handleError(error);
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Check email availability
265
+ */
266
+ async checkEmailAvailability(email: string): Promise<{ available: boolean; message: string }> {
267
+ try {
268
+ return await this.makeRequest('GET', `/api/auth/check-email/${email}`, undefined, { cache: false });
269
+ } catch (error) {
270
+ throw this.handleError(error);
271
+ }
272
+ }
273
+ };
274
+ }
275
+
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Developer API Methods Mixin
3
+ *
4
+ * Provides methods for managing developer applications and API keys
5
+ */
6
+ import type { OxyServicesBase } from '../OxyServices.base';
7
+ import { CACHE_TIMES } from './mixinHelpers';
8
+
9
+ export function OxyServicesDeveloperMixin<T extends typeof OxyServicesBase>(Base: T) {
10
+ return class extends Base {
11
+ constructor(...args: any[]) {
12
+ super(...(args as [any]));
13
+ }
14
+
15
+ /**
16
+ * Get developer apps for the current user
17
+ * @returns Array of developer apps
18
+ */
19
+ async getDeveloperApps(): Promise<any[]> {
20
+ try {
21
+ const res = await this.makeRequest<{ apps?: any[] }>('GET', '/api/developer/apps', undefined, {
22
+ cache: true,
23
+ cacheTTL: CACHE_TIMES.MEDIUM,
24
+ });
25
+ return res.apps || [];
26
+ } catch (error) {
27
+ throw this.handleError(error);
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Create a new developer app
33
+ * @param data - Developer app configuration
34
+ * @returns Created developer app
35
+ */
36
+ async createDeveloperApp(data: {
37
+ name: string;
38
+ description?: string;
39
+ webhookUrl: string;
40
+ devWebhookUrl?: string;
41
+ scopes?: string[];
42
+ }): Promise<any> {
43
+ try {
44
+ const res = await this.makeRequest<{ app: any }>('POST', '/api/developer/apps', data, { cache: false });
45
+ return res.app;
46
+ } catch (error) {
47
+ throw this.handleError(error);
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Get a specific developer app
53
+ */
54
+ async getDeveloperApp(appId: string): Promise<any> {
55
+ try {
56
+ const res = await this.makeRequest<{ app: any }>('GET', `/api/developer/apps/${appId}`, undefined, {
57
+ cache: true,
58
+ cacheTTL: CACHE_TIMES.LONG,
59
+ });
60
+ return res.app;
61
+ } catch (error) {
62
+ throw this.handleError(error);
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Update a developer app
68
+ * @param appId - The developer app ID
69
+ * @param data - Updated app configuration
70
+ * @returns Updated developer app
71
+ */
72
+ async updateDeveloperApp(appId: string, data: {
73
+ name?: string;
74
+ description?: string;
75
+ webhookUrl?: string;
76
+ devWebhookUrl?: string;
77
+ scopes?: string[];
78
+ }): Promise<any> {
79
+ try {
80
+ const res = await this.makeRequest<{ app: any }>('PATCH', `/api/developer/apps/${appId}`, data, { cache: false });
81
+ return res.app;
82
+ } catch (error) {
83
+ throw this.handleError(error);
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Regenerate API secret for a developer app
89
+ * @param appId - The developer app ID
90
+ * @returns App with new secret
91
+ */
92
+ async regenerateDeveloperAppSecret(appId: string): Promise<any> {
93
+ try {
94
+ return await this.makeRequest('POST', `/api/developer/apps/${appId}/regenerate-secret`, undefined, { cache: false });
95
+ } catch (error) {
96
+ throw this.handleError(error);
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Delete a developer app
102
+ * @param appId - The developer app ID
103
+ * @returns Deletion result
104
+ */
105
+ async deleteDeveloperApp(appId: string): Promise<any> {
106
+ try {
107
+ return await this.makeRequest('DELETE', `/api/developer/apps/${appId}`, undefined, { cache: false });
108
+ } catch (error) {
109
+ throw this.handleError(error);
110
+ }
111
+ }
112
+ };
113
+ }
114
+
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Device Methods Mixin
3
+ */
4
+ import type { OxyServicesBase } from '../OxyServices.base';
5
+
6
+ export function OxyServicesDevicesMixin<T extends typeof OxyServicesBase>(Base: T) {
7
+ return class extends Base {
8
+ constructor(...args: any[]) {
9
+ super(...(args as [any]));
10
+ }
11
+
12
+ /**
13
+ * Register a new device
14
+ * @param deviceData - Device information
15
+ * @returns Registered device object
16
+ */
17
+ async registerDevice(deviceData: any): Promise<any> {
18
+ try {
19
+ return await this.makeRequest('POST', '/api/devices', deviceData, { cache: false });
20
+ } catch (error) {
21
+ throw this.handleError(error);
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Get all devices for the current user
27
+ * @returns Array of user devices
28
+ */
29
+ async getUserDevices(): Promise<any[]> {
30
+ try {
31
+ return await this.makeRequest('GET', '/api/devices', undefined, {
32
+ cache: false, // Don't cache device list - always get fresh data
33
+ });
34
+ } catch (error) {
35
+ throw this.handleError(error);
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Remove a device
41
+ * @param deviceId - The device ID to remove
42
+ */
43
+ async removeDevice(deviceId: string): Promise<void> {
44
+ try {
45
+ await this.makeRequest('DELETE', `/api/devices/${deviceId}`, undefined, { cache: false });
46
+ } catch (error) {
47
+ throw this.handleError(error);
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Get device sessions for a given session ID
53
+ * Note: Not cached by default to ensure fresh data
54
+ * @param sessionId - The session ID
55
+ * @returns Array of device sessions
56
+ */
57
+ async getDeviceSessions(sessionId: string): Promise<any[]> {
58
+ try {
59
+ // Use makeRequest for consistent error handling and optional caching
60
+ // Cache disabled by default to ensure fresh session data
61
+ return await this.makeRequest<any[]>('GET', `/api/session/device/sessions/${sessionId}`, undefined, {
62
+ cache: false, // Don't cache sessions - always get fresh data
63
+ deduplicate: true, // Deduplicate concurrent requests for same sessionId
64
+ });
65
+ } catch (error) {
66
+ throw this.handleError(error);
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Logout all device sessions
72
+ * @param sessionId - The session ID
73
+ * @param deviceId - Optional device ID to target
74
+ * @param excludeCurrent - Whether to exclude the current session
75
+ * @returns Logout result
76
+ */
77
+ async logoutAllDeviceSessions(sessionId: string, deviceId?: string, excludeCurrent?: boolean): Promise<any> {
78
+ try {
79
+ const urlParams: any = {};
80
+ if (deviceId) urlParams.deviceId = deviceId;
81
+ if (excludeCurrent) urlParams.excludeCurrent = 'true';
82
+ return await this.makeRequest('POST', `/api/session/device/logout-all/${sessionId}`, urlParams, { cache: false });
83
+ } catch (error) {
84
+ throw this.handleError(error);
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Update device name
90
+ * @param sessionId - The session ID
91
+ * @param deviceName - New device name
92
+ * @returns Updated device object
93
+ */
94
+ async updateDeviceName(sessionId: string, deviceName: string): Promise<any> {
95
+ try {
96
+ return await this.makeRequest('PUT', `/api/session/device/name/${sessionId}`, { deviceName }, { cache: false });
97
+ } catch (error) {
98
+ throw this.handleError(error);
99
+ }
100
+ }
101
+ };
102
+ }
103
+
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Karma Methods Mixin
3
+ *
4
+ * Provides methods for karma system management
5
+ */
6
+ import type { OxyServicesBase } from '../OxyServices.base';
7
+ import { CACHE_TIMES } from './mixinHelpers';
8
+
9
+ export function OxyServicesKarmaMixin<T extends typeof OxyServicesBase>(Base: T) {
10
+ return class extends Base {
11
+ constructor(...args: any[]) {
12
+ super(...(args as [any]));
13
+ }
14
+ /**
15
+ * Get user karma
16
+ */
17
+ async getUserKarma(userId: string): Promise<any> {
18
+ try {
19
+ return await this.makeRequest('GET', `/api/karma/${userId}`, undefined, {
20
+ cache: true,
21
+ cacheTTL: 2 * 60 * 1000, // 2 minutes cache
22
+ });
23
+ } catch (error) {
24
+ throw this.handleError(error);
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Give karma to user
30
+ */
31
+ async giveKarma(userId: string, amount: number, reason?: string): Promise<any> {
32
+ try {
33
+ return await this.makeRequest('POST', `/api/karma/${userId}/give`, {
34
+ amount,
35
+ reason
36
+ }, { cache: false });
37
+ } catch (error) {
38
+ throw this.handleError(error);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Get user karma total
44
+ * @param userId - The user ID
45
+ * @returns User karma total
46
+ */
47
+ async getUserKarmaTotal(userId: string): Promise<any> {
48
+ try {
49
+ return await this.makeRequest('GET', `/api/karma/${userId}/total`, undefined, {
50
+ cache: true,
51
+ cacheTTL: CACHE_TIMES.MEDIUM,
52
+ });
53
+ } catch (error) {
54
+ throw this.handleError(error);
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Get user karma history
60
+ * @param userId - The user ID
61
+ * @param limit - Optional limit for results
62
+ * @param offset - Optional offset for pagination
63
+ * @returns User karma history
64
+ */
65
+ async getUserKarmaHistory(userId: string, limit?: number, offset?: number): Promise<any> {
66
+ try {
67
+ const params: any = {};
68
+ if (limit) params.limit = limit;
69
+ if (offset) params.offset = offset;
70
+
71
+ return await this.makeRequest('GET', `/api/karma/${userId}/history`, params, {
72
+ cache: true,
73
+ cacheTTL: CACHE_TIMES.MEDIUM,
74
+ });
75
+ } catch (error) {
76
+ throw this.handleError(error);
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Get karma leaderboard
82
+ * @returns Karma leaderboard
83
+ */
84
+ async getKarmaLeaderboard(): Promise<any> {
85
+ try {
86
+ return await this.makeRequest('GET', '/api/karma/leaderboard', undefined, {
87
+ cache: true,
88
+ cacheTTL: CACHE_TIMES.LONG,
89
+ });
90
+ } catch (error) {
91
+ throw this.handleError(error);
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Get karma rules
97
+ * @returns Karma rules
98
+ */
99
+ async getKarmaRules(): Promise<any> {
100
+ try {
101
+ return await this.makeRequest('GET', '/api/karma/rules', undefined, {
102
+ cache: true,
103
+ cacheTTL: CACHE_TIMES.EXTRA_LONG, // Rules don't change often
104
+ });
105
+ } catch (error) {
106
+ throw this.handleError(error);
107
+ }
108
+ }
109
+ };
110
+ }
111
+