@oxyhq/core 3.18.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/OxyServices.js +3 -2
  3. package/dist/cjs/mixins/OxyServices.accounts.js +480 -0
  4. package/dist/cjs/mixins/OxyServices.connectedApps.js +73 -0
  5. package/dist/cjs/mixins/OxyServices.utility.js +3 -2
  6. package/dist/cjs/mixins/index.js +9 -6
  7. package/dist/esm/.tsbuildinfo +1 -1
  8. package/dist/esm/OxyServices.js +3 -2
  9. package/dist/esm/mixins/OxyServices.accounts.js +477 -0
  10. package/dist/esm/mixins/OxyServices.connectedApps.js +70 -0
  11. package/dist/esm/mixins/OxyServices.utility.js +3 -2
  12. package/dist/esm/mixins/index.js +9 -6
  13. package/dist/types/.tsbuildinfo +1 -1
  14. package/dist/types/OxyServices.d.ts +3 -2
  15. package/dist/types/index.d.ts +2 -3
  16. package/dist/types/mixins/OxyServices.accounts.d.ts +642 -0
  17. package/dist/types/mixins/OxyServices.auth.d.ts +1 -1
  18. package/dist/types/mixins/OxyServices.connectedApps.d.ts +168 -0
  19. package/dist/types/mixins/OxyServices.utility.d.ts +6 -3
  20. package/dist/types/mixins/index.d.ts +3 -4
  21. package/package.json +2 -2
  22. package/src/OxyServices.ts +3 -2
  23. package/src/index.ts +33 -34
  24. package/src/mixins/OxyServices.accounts.ts +1079 -0
  25. package/src/mixins/OxyServices.auth.ts +1 -1
  26. package/src/mixins/OxyServices.connectedApps.ts +165 -0
  27. package/src/mixins/OxyServices.utility.ts +7 -4
  28. package/src/mixins/__tests__/accounts.test.ts +667 -0
  29. package/src/mixins/__tests__/connectedApps.test.ts +1 -1
  30. package/src/mixins/index.ts +11 -9
  31. package/dist/cjs/mixins/OxyServices.applications.js +0 -350
  32. package/dist/cjs/mixins/OxyServices.managedAccounts.js +0 -143
  33. package/dist/cjs/mixins/OxyServices.workspaces.js +0 -181
  34. package/dist/esm/mixins/OxyServices.applications.js +0 -347
  35. package/dist/esm/mixins/OxyServices.managedAccounts.js +0 -140
  36. package/dist/esm/mixins/OxyServices.workspaces.js +0 -178
  37. package/dist/types/mixins/OxyServices.applications.d.ts +0 -496
  38. package/dist/types/mixins/OxyServices.managedAccounts.d.ts +0 -145
  39. package/dist/types/mixins/OxyServices.workspaces.d.ts +0 -219
  40. package/src/mixins/OxyServices.applications.ts +0 -773
  41. package/src/mixins/OxyServices.managedAccounts.ts +0 -173
  42. package/src/mixins/OxyServices.workspaces.ts +0 -351
@@ -1,181 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OxyServicesWorkspacesMixin = OxyServicesWorkspacesMixin;
4
- const mixinHelpers_1 = require("./mixinHelpers");
5
- function OxyServicesWorkspacesMixin(Base) {
6
- return class extends Base {
7
- constructor(...args) {
8
- super(...args);
9
- }
10
- /**
11
- * List workspaces the current user is an active member of.
12
- */
13
- async getWorkspaces() {
14
- try {
15
- const res = await this.makeRequest('GET', '/workspaces', undefined, { cache: true, cacheTTL: mixinHelpers_1.CACHE_TIMES.MEDIUM });
16
- return res.workspaces ?? [];
17
- }
18
- catch (error) {
19
- throw this.handleError(error);
20
- }
21
- }
22
- /**
23
- * Create a new team workspace. The caller becomes its `owner`.
24
- * @param data - Workspace configuration.
25
- */
26
- async createWorkspace(data) {
27
- try {
28
- const res = await this.makeRequest('POST', '/workspaces', data, { cache: false });
29
- // Bust the cached workspace list so the new workspace appears on the
30
- // next `getWorkspaces()` read within the TTL window.
31
- this.clearCacheEntry('GET:/workspaces');
32
- return res.workspace;
33
- }
34
- catch (error) {
35
- throw this.handleError(error);
36
- }
37
- }
38
- /**
39
- * Fetch a single workspace by id.
40
- * @param workspaceId - The workspace's Mongo `_id`.
41
- */
42
- async getWorkspace(workspaceId) {
43
- try {
44
- const res = await this.makeRequest('GET', `/workspaces/${encodeURIComponent(workspaceId)}`, undefined, { cache: true, cacheTTL: mixinHelpers_1.CACHE_TIMES.LONG });
45
- return res.workspace;
46
- }
47
- catch (error) {
48
- throw this.handleError(error);
49
- }
50
- }
51
- /**
52
- * Update a workspace's mutable fields.
53
- * @param workspaceId - The workspace's Mongo `_id`.
54
- * @param data - Subset of updatable fields.
55
- */
56
- async updateWorkspace(workspaceId, data) {
57
- try {
58
- const res = await this.makeRequest('PATCH', `/workspaces/${encodeURIComponent(workspaceId)}`, data, { cache: false });
59
- // Bust the cached detail and list — both surface workspace fields.
60
- this.clearCacheEntry(`GET:/workspaces/${encodeURIComponent(workspaceId)}`);
61
- this.clearCacheEntry('GET:/workspaces');
62
- return res.workspace;
63
- }
64
- catch (error) {
65
- throw this.handleError(error);
66
- }
67
- }
68
- /**
69
- * Soft-delete a workspace (owner only).
70
- * @param workspaceId - The workspace's Mongo `_id`.
71
- */
72
- async deleteWorkspace(workspaceId) {
73
- try {
74
- const result = await this.makeRequest('DELETE', `/workspaces/${encodeURIComponent(workspaceId)}`, undefined, { cache: false });
75
- // Bust every cached representation of the deleted workspace.
76
- this.clearCacheEntry(`GET:/workspaces/${encodeURIComponent(workspaceId)}`);
77
- this.clearCacheEntry(`GET:/workspaces/${encodeURIComponent(workspaceId)}/members`);
78
- this.clearCacheEntry('GET:/workspaces');
79
- return result;
80
- }
81
- catch (error) {
82
- throw this.handleError(error);
83
- }
84
- }
85
- /**
86
- * List members of a workspace.
87
- * @param workspaceId - The workspace's Mongo `_id`.
88
- */
89
- async getWorkspaceMembers(workspaceId) {
90
- try {
91
- const res = await this.makeRequest('GET', `/workspaces/${encodeURIComponent(workspaceId)}/members`, undefined, { cache: true, cacheTTL: mixinHelpers_1.CACHE_TIMES.MEDIUM });
92
- return res.members ?? [];
93
- }
94
- catch (error) {
95
- throw this.handleError(error);
96
- }
97
- }
98
- /**
99
- * Add a member to a workspace.
100
- * @param workspaceId - The workspace's Mongo `_id`.
101
- * @param data - Target user's username or email and role (never `owner`).
102
- * The server resolves `usernameOrEmail` to a user; an unknown value yields
103
- * a 404 "User not found".
104
- */
105
- async inviteWorkspaceMember(workspaceId, data) {
106
- try {
107
- const res = await this.makeRequest('POST', `/workspaces/${encodeURIComponent(workspaceId)}/members`, data, { cache: false });
108
- this._invalidateWorkspaceMembership(workspaceId);
109
- return res.member;
110
- }
111
- catch (error) {
112
- throw this.handleError(error);
113
- }
114
- }
115
- /**
116
- * Change a member's role.
117
- * @param workspaceId - The workspace's Mongo `_id`.
118
- * @param memberId - The member's Mongo `_id`.
119
- * @param data - New role (never `owner`).
120
- */
121
- async updateWorkspaceMember(workspaceId, memberId, data) {
122
- try {
123
- const res = await this.makeRequest('PATCH', `/workspaces/${encodeURIComponent(workspaceId)}/members/${encodeURIComponent(memberId)}`, data, { cache: false });
124
- this._invalidateWorkspaceMembership(workspaceId);
125
- return res.member;
126
- }
127
- catch (error) {
128
- throw this.handleError(error);
129
- }
130
- }
131
- /**
132
- * Remove a member from a workspace.
133
- * @param workspaceId - The workspace's Mongo `_id`.
134
- * @param memberId - The member's Mongo `_id`.
135
- */
136
- async removeWorkspaceMember(workspaceId, memberId) {
137
- try {
138
- const result = await this.makeRequest('DELETE', `/workspaces/${encodeURIComponent(workspaceId)}/members/${encodeURIComponent(memberId)}`, undefined, { cache: false });
139
- this._invalidateWorkspaceMembership(workspaceId);
140
- return result;
141
- }
142
- catch (error) {
143
- throw this.handleError(error);
144
- }
145
- }
146
- /**
147
- * Transfer ownership of a workspace to another member (owner only).
148
- * Demotes the current owner and promotes the target to `owner`.
149
- * @param workspaceId - The workspace's Mongo `_id`.
150
- * @param data - Target user id.
151
- */
152
- async transferWorkspaceOwnership(workspaceId, data) {
153
- try {
154
- const result = await this.makeRequest('POST', `/workspaces/${encodeURIComponent(workspaceId)}/transfer-ownership`, data, { cache: false });
155
- // Ownership change alters roles in the member list AND the detail, and
156
- // can change which workspaces the caller "owns" in the list view.
157
- this._invalidateWorkspaceMembership(workspaceId);
158
- this.clearCacheEntry('GET:/workspaces');
159
- return result;
160
- }
161
- catch (error) {
162
- throw this.handleError(error);
163
- }
164
- }
165
- /**
166
- * Bust the cached member list and detail for a workspace after a membership
167
- * mutation. The member list (`getWorkspaceMembers`) and the detail
168
- * (`getWorkspace`, which can embed member counts) both go stale when the
169
- * member set or a member's role changes.
170
- *
171
- * Internal helper (leading underscore); not part of the supported public
172
- * surface. Public rather than `private` because mixins compose into an
173
- * exported anonymous class, where TypeScript cannot represent a private
174
- * member in the emitted declaration file (TS4094).
175
- */
176
- _invalidateWorkspaceMembership(workspaceId) {
177
- this.clearCacheEntry(`GET:/workspaces/${encodeURIComponent(workspaceId)}/members`);
178
- this.clearCacheEntry(`GET:/workspaces/${encodeURIComponent(workspaceId)}`);
179
- }
180
- };
181
- }
@@ -1,347 +0,0 @@
1
- import { CACHE_TIMES } from './mixinHelpers.js';
2
- export function OxyServicesApplicationsMixin(Base) {
3
- return class extends Base {
4
- constructor(...args) {
5
- super(...args);
6
- }
7
- /**
8
- * Resolve an OAuth client identifier to the owning application's PUBLIC
9
- * identity. No authentication required — the API returns only sanitized,
10
- * display-safe metadata ({@link PublicApplication}). Use this to render the
11
- * requesting application's name/icon in consent, authorize, and device-flow
12
- * approval UIs before any session exists.
13
- *
14
- * @param clientId - The OAuth `client_id` (an active credential's public
15
- * key). URL-encoded before being placed in the path.
16
- */
17
- async getPublicApplication(clientId) {
18
- try {
19
- const res = await this.makeRequest('GET', `/auth/oauth/client/${encodeURIComponent(clientId)}`, undefined, { cache: true, cacheTTL: CACHE_TIMES.MEDIUM });
20
- return res.application;
21
- }
22
- catch (error) {
23
- throw this.handleError(error);
24
- }
25
- }
26
- /**
27
- * List the OAuth-authorized applications the current user has connected —
28
- * the third-party apps the user granted access to via the consent flow.
29
- * Each entry is a {@link ConnectedApp} carrying the application's display
30
- * identity, the granted scopes, and when the grant was first made and last
31
- * exercised. Requires an authenticated session.
32
- *
33
- * Backed by `GET /auth/grants`. The response is briefly cached
34
- * (identity-scoped); {@link revokeAppGrant} busts that cache so a revoke is
35
- * reflected on the next read.
36
- */
37
- async listConnectedApps() {
38
- try {
39
- return await this.makeRequest('GET', '/auth/grants', undefined, { cache: true, cacheTTL: CACHE_TIMES.SHORT });
40
- }
41
- catch (error) {
42
- throw this.handleError(error);
43
- }
44
- }
45
- /**
46
- * Revoke the current user's grant for a connected application, identified by
47
- * its application `_id` (a {@link ConnectedApp.applicationId}, NOT a
48
- * credential/client id — keyed by application so the revocation survives
49
- * credential rotation). After this the application can no longer act on the
50
- * user's behalf until it is re-authorized.
51
- *
52
- * Backed by `DELETE /auth/grants/:applicationId`. On success the cached
53
- * connected-apps list (`GET:/auth/grants`) is invalidated so the next
54
- * {@link listConnectedApps} read reflects the removal.
55
- *
56
- * @param applicationId - The connected application's Mongo `_id`.
57
- */
58
- async revokeAppGrant(applicationId) {
59
- try {
60
- await this.makeRequest('DELETE', `/auth/grants/${applicationId}`, undefined, { cache: false });
61
- // A revoke removes an entry from the user's connected-apps list; bust
62
- // the cached `GET /auth/grants` so the next read re-fetches.
63
- this.clearCacheEntry('GET:/auth/grants');
64
- }
65
- catch (error) {
66
- throw this.handleError(error);
67
- }
68
- }
69
- /**
70
- * List applications the current user is an active member of.
71
- *
72
- * @param workspaceId - Optional workspace `_id` to scope the listing to
73
- * applications belonging to that workspace. When provided it is appended
74
- * as a `workspaceId` query parameter (URL-encoded). The query string is
75
- * part of the request path, so the response cache keys on it
76
- * automatically — scoped and unscoped lists never collide.
77
- */
78
- async getApplications(workspaceId) {
79
- try {
80
- const path = workspaceId
81
- ? `/applications?workspaceId=${encodeURIComponent(workspaceId)}`
82
- : '/applications';
83
- const res = await this.makeRequest('GET', path, undefined, { cache: true, cacheTTL: CACHE_TIMES.MEDIUM });
84
- return res.applications ?? [];
85
- }
86
- catch (error) {
87
- throw this.handleError(error);
88
- }
89
- }
90
- /**
91
- * Create a new application. The caller becomes its `owner`.
92
- * @param data - Application configuration. Staff-only fields are ignored.
93
- */
94
- async createApplication(data) {
95
- try {
96
- const res = await this.makeRequest('POST', '/applications', data, { cache: false });
97
- // Bust every cached application list (unscoped + per-workspace) so the
98
- // new application appears on the next `getApplications()` read.
99
- this._invalidateApplicationLists();
100
- return res.application;
101
- }
102
- catch (error) {
103
- throw this.handleError(error);
104
- }
105
- }
106
- /**
107
- * Fetch a single application by id.
108
- * @param applicationId - The application's Mongo `_id`.
109
- */
110
- async getApplication(applicationId) {
111
- try {
112
- const res = await this.makeRequest('GET', `/applications/${applicationId}`, undefined, { cache: true, cacheTTL: CACHE_TIMES.LONG });
113
- return res.application;
114
- }
115
- catch (error) {
116
- throw this.handleError(error);
117
- }
118
- }
119
- /**
120
- * Update an application's mutable fields.
121
- * @param applicationId - The application's Mongo `_id`.
122
- * @param data - Subset of updatable fields. Staff-only fields are ignored.
123
- */
124
- async updateApplication(applicationId, data) {
125
- try {
126
- const res = await this.makeRequest('PATCH', `/applications/${applicationId}`, data, { cache: false });
127
- // Bust the cached detail and every list (which embeds application
128
- // fields) so neither serves the pre-update snapshot.
129
- this.clearCacheEntry(`GET:/applications/${applicationId}`);
130
- this._invalidateApplicationLists();
131
- return res.application;
132
- }
133
- catch (error) {
134
- throw this.handleError(error);
135
- }
136
- }
137
- /**
138
- * Soft-delete an application (owner only).
139
- * @param applicationId - The application's Mongo `_id`.
140
- */
141
- async deleteApplication(applicationId) {
142
- try {
143
- const result = await this.makeRequest('DELETE', `/applications/${applicationId}`, undefined, { cache: false });
144
- // Bust every cached representation of the deleted application.
145
- this.clearCacheEntry(`GET:/applications/${applicationId}`);
146
- this.clearCacheEntry(`GET:/applications/${applicationId}/members`);
147
- this.clearCacheEntry(`GET:/applications/${applicationId}/credentials`);
148
- this._invalidateApplicationLists();
149
- return result;
150
- }
151
- catch (error) {
152
- throw this.handleError(error);
153
- }
154
- }
155
- /**
156
- * List members of an application.
157
- * @param applicationId - The application's Mongo `_id`.
158
- */
159
- async getApplicationMembers(applicationId) {
160
- try {
161
- const res = await this.makeRequest('GET', `/applications/${applicationId}/members`, undefined, { cache: true, cacheTTL: CACHE_TIMES.MEDIUM });
162
- return res.members ?? [];
163
- }
164
- catch (error) {
165
- throw this.handleError(error);
166
- }
167
- }
168
- /**
169
- * Add a member to an application.
170
- * @param applicationId - The application's Mongo `_id`.
171
- * @param data - Target user's username or email and role (never `owner`).
172
- * The server resolves `usernameOrEmail` to a user; an unknown value yields
173
- * a 404 "User not found".
174
- */
175
- async inviteApplicationMember(applicationId, data) {
176
- try {
177
- const res = await this.makeRequest('POST', `/applications/${applicationId}/members`, data, { cache: false });
178
- this._invalidateApplicationMembership(applicationId);
179
- return res.member;
180
- }
181
- catch (error) {
182
- throw this.handleError(error);
183
- }
184
- }
185
- /**
186
- * Change a member's role.
187
- * @param applicationId - The application's Mongo `_id`.
188
- * @param memberId - The member's Mongo `_id`.
189
- * @param data - New role.
190
- */
191
- async updateApplicationMember(applicationId, memberId, data) {
192
- try {
193
- const res = await this.makeRequest('PATCH', `/applications/${applicationId}/members/${memberId}`, data, { cache: false });
194
- this._invalidateApplicationMembership(applicationId);
195
- return res.member;
196
- }
197
- catch (error) {
198
- throw this.handleError(error);
199
- }
200
- }
201
- /**
202
- * Remove a member from an application.
203
- * @param applicationId - The application's Mongo `_id`.
204
- * @param memberId - The member's Mongo `_id`.
205
- */
206
- async removeApplicationMember(applicationId, memberId) {
207
- try {
208
- const result = await this.makeRequest('DELETE', `/applications/${applicationId}/members/${memberId}`, undefined, { cache: false });
209
- this._invalidateApplicationMembership(applicationId);
210
- return result;
211
- }
212
- catch (error) {
213
- throw this.handleError(error);
214
- }
215
- }
216
- /**
217
- * Transfer ownership of an application to another member (owner only).
218
- * Demotes the current owner to `admin` and promotes the target to `owner`.
219
- * @param applicationId - The application's Mongo `_id`.
220
- * @param data - Target user id.
221
- */
222
- async transferApplicationOwnership(applicationId, data) {
223
- try {
224
- const result = await this.makeRequest('POST', `/applications/${applicationId}/transfer-ownership`, data, { cache: false });
225
- // Ownership change alters roles in the member list AND the detail, and
226
- // can change which applications the caller "owns" in the list view.
227
- this._invalidateApplicationMembership(applicationId);
228
- this._invalidateApplicationLists();
229
- return result;
230
- }
231
- catch (error) {
232
- throw this.handleError(error);
233
- }
234
- }
235
- /**
236
- * List an application's credentials. The response NEVER includes secrets.
237
- * @param applicationId - The application's Mongo `_id`.
238
- */
239
- async getApplicationCredentials(applicationId) {
240
- try {
241
- const res = await this.makeRequest('GET', `/applications/${applicationId}/credentials`, undefined, { cache: true, cacheTTL: CACHE_TIMES.MEDIUM });
242
- return res.credentials ?? [];
243
- }
244
- catch (error) {
245
- throw this.handleError(error);
246
- }
247
- }
248
- /**
249
- * Create a credential. The plaintext `secret` is returned exactly ONCE;
250
- * the server stores only a hash and will never return it again.
251
- * @param applicationId - The application's Mongo `_id`.
252
- * @param data - Credential configuration.
253
- */
254
- async createApplicationCredential(applicationId, data) {
255
- try {
256
- const result = await this.makeRequest('POST', `/applications/${applicationId}/credentials`, data, { cache: false });
257
- this.clearCacheEntry(`GET:/applications/${applicationId}/credentials`);
258
- return result;
259
- }
260
- catch (error) {
261
- throw this.handleError(error);
262
- }
263
- }
264
- /**
265
- * Rotate a credential's secret. The new plaintext `secret` is returned
266
- * exactly ONCE, along with audit fields: `rotatedFrom` (the previous
267
- * credentialId) and `graceExpiresAt` (ISO string for the grace window during
268
- * which the old credential is still honoured).
269
- * @param applicationId - The application's Mongo `_id`.
270
- * @param credentialId - The credential's Mongo `_id`.
271
- */
272
- async rotateApplicationCredential(applicationId, credentialId) {
273
- try {
274
- const result = await this.makeRequest('POST', `/applications/${applicationId}/credentials/${credentialId}/rotate`, undefined, { cache: false });
275
- // Rotation changes credential status/audit fields surfaced by the
276
- // credentials list (`rotatedFrom`, grace window, new active credential).
277
- this.clearCacheEntry(`GET:/applications/${applicationId}/credentials`);
278
- return result;
279
- }
280
- catch (error) {
281
- throw this.handleError(error);
282
- }
283
- }
284
- /**
285
- * Revoke a credential (`status='revoked'`). Revoked credentials can no
286
- * longer authenticate.
287
- * @param applicationId - The application's Mongo `_id`.
288
- * @param credentialId - The credential's Mongo `_id`.
289
- */
290
- async revokeApplicationCredential(applicationId, credentialId) {
291
- try {
292
- const result = await this.makeRequest('DELETE', `/applications/${applicationId}/credentials/${credentialId}`, undefined, { cache: false });
293
- // Revocation flips the credential's status in the cached list.
294
- this.clearCacheEntry(`GET:/applications/${applicationId}/credentials`);
295
- return result;
296
- }
297
- catch (error) {
298
- throw this.handleError(error);
299
- }
300
- }
301
- /**
302
- * Fetch usage statistics for an application.
303
- * @param applicationId - The application's Mongo `_id`.
304
- * @param period - Time window (defaults to the server default).
305
- */
306
- async getApplicationUsage(applicationId, period) {
307
- try {
308
- return await this.makeRequest('GET', `/applications/${applicationId}/usage`, period ? { period } : undefined, { cache: true, cacheTTL: CACHE_TIMES.SHORT });
309
- }
310
- catch (error) {
311
- throw this.handleError(error);
312
- }
313
- }
314
- /**
315
- * Bust every cached application list. `getApplications(workspaceId?)` keys
316
- * the unscoped list as `GET:/applications` and each workspace-scoped list as
317
- * `GET:/applications?workspaceId=<id>` (the query string is part of the URL
318
- * path). A change to list membership (create/delete/ownership transfer)
319
- * invalidates all of them, so we clear the unscoped entry plus every
320
- * `?workspaceId=` variant via a prefix sweep. The prefix `GET:/applications?`
321
- * matches only the query-string list variants, never the `GET:/applications/<id>…`
322
- * detail/sub-resource keys.
323
- *
324
- * Internal helper (leading underscore); not part of the supported public
325
- * surface. Public rather than `private` because mixins compose into an
326
- * exported anonymous class, where TypeScript cannot represent a private
327
- * member in the emitted declaration file (TS4094).
328
- */
329
- _invalidateApplicationLists() {
330
- this.clearCacheEntry('GET:/applications');
331
- this.clearCacheByPrefix('GET:/applications?');
332
- }
333
- /**
334
- * Bust the cached member list and detail for an application after a
335
- * membership mutation. The member list (`getApplicationMembers`) and the
336
- * detail (`getApplication`, which can embed member counts) both go stale
337
- * when the member set or a member's role changes.
338
- *
339
- * Internal helper (leading underscore); see `_invalidateApplicationLists`
340
- * for why this is public rather than `private`.
341
- */
342
- _invalidateApplicationMembership(applicationId) {
343
- this.clearCacheEntry(`GET:/applications/${applicationId}/members`);
344
- this.clearCacheEntry(`GET:/applications/${applicationId}`);
345
- }
346
- };
347
- }
@@ -1,140 +0,0 @@
1
- export function OxyServicesManagedAccountsMixin(Base) {
2
- return class extends Base {
3
- constructor(...args) {
4
- super(...args);
5
- }
6
- /**
7
- * Create a new managed account (sub-account).
8
- *
9
- * The server creates a User document with `isManagedAccount: true` and links
10
- * it to the authenticated user as owner. Invalidates the cached
11
- * `GET /managed-accounts` list (~2-minute TTL, identity-scoped) so the next
12
- * read includes the newly created account.
13
- */
14
- async createManagedAccount(data) {
15
- try {
16
- const result = await this.makeRequest('POST', '/managed-accounts', data, {
17
- cache: false,
18
- });
19
- this.clearCacheEntry('GET:/managed-accounts');
20
- return result;
21
- }
22
- catch (error) {
23
- throw this.handleError(error);
24
- }
25
- }
26
- /**
27
- * List all accounts the authenticated user manages.
28
- */
29
- async getManagedAccounts() {
30
- try {
31
- return await this.makeRequest('GET', '/managed-accounts', undefined, {
32
- cache: true,
33
- cacheTTL: 2 * 60 * 1000, // 2 minutes cache
34
- });
35
- }
36
- catch (error) {
37
- throw this.handleError(error);
38
- }
39
- }
40
- /**
41
- * Get details for a specific managed account.
42
- */
43
- async getManagedAccountDetails(accountId) {
44
- try {
45
- return await this.makeRequest('GET', `/managed-accounts/${accountId}`, undefined, {
46
- cache: true,
47
- cacheTTL: 2 * 60 * 1000,
48
- });
49
- }
50
- catch (error) {
51
- throw this.handleError(error);
52
- }
53
- }
54
- /**
55
- * Update a managed account's profile data.
56
- * Requires owner or admin role.
57
- *
58
- * Invalidates both the cached detail (`GET /managed-accounts/<id>`) and the
59
- * cached list (`GET /managed-accounts`, which embeds account profile data)
60
- * so neither serves the pre-update snapshot within their ~2-minute TTL.
61
- */
62
- async updateManagedAccount(accountId, data) {
63
- try {
64
- const result = await this.makeRequest('PUT', `/managed-accounts/${accountId}`, data, {
65
- cache: false,
66
- });
67
- this.clearCacheEntry(`GET:/managed-accounts/${accountId}`);
68
- this.clearCacheEntry('GET:/managed-accounts');
69
- return result;
70
- }
71
- catch (error) {
72
- throw this.handleError(error);
73
- }
74
- }
75
- /**
76
- * Delete a managed account permanently.
77
- * Requires owner role.
78
- *
79
- * Invalidates the cached detail and list responses so the deleted account
80
- * is not served from cache.
81
- */
82
- async deleteManagedAccount(accountId) {
83
- try {
84
- await this.makeRequest('DELETE', `/managed-accounts/${accountId}`, undefined, {
85
- cache: false,
86
- });
87
- this.clearCacheEntry(`GET:/managed-accounts/${accountId}`);
88
- this.clearCacheEntry('GET:/managed-accounts');
89
- }
90
- catch (error) {
91
- throw this.handleError(error);
92
- }
93
- }
94
- /**
95
- * Add a manager to a managed account.
96
- * Requires owner or admin role on the account.
97
- *
98
- * Mutates the account's `managers[]`, which is returned by the detail and
99
- * list reads — invalidate both so they re-fetch the updated manager set.
100
- *
101
- * @param accountId - The managed account to add the manager to
102
- * @param userId - The user to grant management access
103
- * @param role - The role to assign: 'admin' or 'editor'
104
- */
105
- async addManager(accountId, userId, role) {
106
- try {
107
- await this.makeRequest('POST', `/managed-accounts/${accountId}/managers`, { userId, role }, {
108
- cache: false,
109
- });
110
- this.clearCacheEntry(`GET:/managed-accounts/${accountId}`);
111
- this.clearCacheEntry('GET:/managed-accounts');
112
- }
113
- catch (error) {
114
- throw this.handleError(error);
115
- }
116
- }
117
- /**
118
- * Remove a manager from a managed account.
119
- * Requires owner role.
120
- *
121
- * Invalidates the detail and list responses so the updated `managers[]`
122
- * is observed on the next read (see `addManager`).
123
- *
124
- * @param accountId - The managed account
125
- * @param userId - The manager to remove
126
- */
127
- async removeManager(accountId, userId) {
128
- try {
129
- await this.makeRequest('DELETE', `/managed-accounts/${accountId}/managers/${userId}`, undefined, {
130
- cache: false,
131
- });
132
- this.clearCacheEntry(`GET:/managed-accounts/${accountId}`);
133
- this.clearCacheEntry('GET:/managed-accounts');
134
- }
135
- catch (error) {
136
- throw this.handleError(error);
137
- }
138
- }
139
- };
140
- }