@oxyhq/core 3.1.0 → 3.4.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.
- package/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/AuthManager.js +14 -3
- package/dist/cjs/HttpService.js +89 -0
- package/dist/cjs/OxyServices.js +2 -1
- package/dist/cjs/constants/version.js +1 -1
- package/dist/cjs/i18n/locales/en-US.json +44 -44
- package/dist/cjs/i18n/locales/es-ES.json +44 -44
- package/dist/cjs/i18n/locales/locales/en-US.json +44 -44
- package/dist/cjs/i18n/locales/locales/es-ES.json +44 -44
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/mixins/OxyServices.applications.js +33 -3
- package/dist/cjs/mixins/OxyServices.reputation.js +244 -0
- package/dist/cjs/mixins/OxyServices.workspaces.js +146 -0
- package/dist/cjs/mixins/index.js +4 -2
- package/dist/cjs/utils/accountUtils.js +12 -5
- package/dist/cjs/utils/ssoReturn.js +80 -33
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/AuthManager.js +14 -3
- package/dist/esm/HttpService.js +89 -0
- package/dist/esm/OxyServices.js +2 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/i18n/locales/en-US.json +44 -44
- package/dist/esm/i18n/locales/es-ES.json +44 -44
- package/dist/esm/i18n/locales/locales/en-US.json +44 -44
- package/dist/esm/i18n/locales/locales/es-ES.json +44 -44
- package/dist/esm/index.js +4 -0
- package/dist/esm/mixins/OxyServices.applications.js +33 -3
- package/dist/esm/mixins/OxyServices.reputation.js +241 -0
- package/dist/esm/mixins/OxyServices.workspaces.js +143 -0
- package/dist/esm/mixins/index.js +4 -2
- package/dist/esm/utils/accountUtils.js +12 -5
- package/dist/esm/utils/ssoReturn.js +80 -33
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/HttpService.d.ts +57 -0
- package/dist/types/OxyServices.d.ts +2 -1
- package/dist/types/constants/version.d.ts +2 -2
- package/dist/types/index.d.ts +4 -2
- package/dist/types/mixins/OxyServices.applications.d.ts +86 -10
- package/dist/types/mixins/OxyServices.features.d.ts +0 -1
- package/dist/types/mixins/OxyServices.reputation.d.ts +436 -0
- package/dist/types/mixins/OxyServices.workspaces.d.ts +205 -0
- package/dist/types/mixins/index.d.ts +3 -2
- package/dist/types/models/interfaces.d.ts +24 -26
- package/dist/types/utils/accountUtils.d.ts +17 -4
- package/dist/types/utils/ssoReturn.d.ts +30 -9
- package/package.json +2 -1
- package/src/AuthManager.ts +14 -3
- package/src/HttpService.ts +91 -0
- package/src/OxyServices.ts +2 -1
- package/src/__tests__/authManager.cookiePath.test.ts +49 -0
- package/src/__tests__/httpServiceCache.test.ts +198 -0
- package/src/constants/version.ts +1 -1
- package/src/i18n/locales/en-US.json +44 -44
- package/src/i18n/locales/es-ES.json +44 -44
- package/src/index.ts +51 -4
- package/src/mixins/OxyServices.applications.ts +103 -5
- package/src/mixins/OxyServices.auth.ts +2 -1
- package/src/mixins/OxyServices.features.ts +0 -1
- package/src/mixins/OxyServices.reputation.ts +674 -0
- package/src/mixins/OxyServices.workspaces.ts +315 -0
- package/src/mixins/__tests__/reputation.test.ts +408 -0
- package/src/mixins/index.ts +6 -3
- package/src/models/interfaces.ts +25 -32
- package/src/utils/__tests__/accountUtils.test.ts +142 -0
- package/src/utils/__tests__/consumeSsoReturn.test.ts +229 -37
- package/src/utils/accountUtils.ts +20 -5
- package/src/utils/ssoReturn.ts +98 -37
- package/dist/cjs/mixins/OxyServices.developer.js +0 -97
- package/dist/cjs/mixins/OxyServices.karma.js +0 -108
- package/dist/esm/mixins/OxyServices.developer.js +0 -94
- package/dist/esm/mixins/OxyServices.karma.js +0 -105
- package/dist/types/mixins/OxyServices.developer.d.ts +0 -106
- package/dist/types/mixins/OxyServices.karma.d.ts +0 -92
- package/src/mixins/OxyServices.karma.ts +0 -111
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspaces Methods Mixin
|
|
3
|
+
*
|
|
4
|
+
* Provides methods for managing Oxy workspaces and their members via the
|
|
5
|
+
* `/workspaces` API. A workspace is a multi-user container that owns
|
|
6
|
+
* applications and other resources: membership (with a role) grants
|
|
7
|
+
* permissions. A `personal` workspace is created implicitly for every user;
|
|
8
|
+
* `team` workspaces are created explicitly and can invite additional members.
|
|
9
|
+
*
|
|
10
|
+
* Reference workspaces by their Mongo `_id` and members by their member `_id`.
|
|
11
|
+
* Never by name or slug.
|
|
12
|
+
*/
|
|
13
|
+
import type { OxyServicesBase } from '../OxyServices.base';
|
|
14
|
+
import { CACHE_TIMES } from './mixinHelpers';
|
|
15
|
+
|
|
16
|
+
/** Role a member holds within a workspace. */
|
|
17
|
+
export type WorkspaceRole = 'owner' | 'admin' | 'member' | 'viewer';
|
|
18
|
+
|
|
19
|
+
/** Workspace classification. A `personal` workspace is implicit per user. */
|
|
20
|
+
export type WorkspaceType = 'personal' | 'team';
|
|
21
|
+
|
|
22
|
+
/** Lifecycle status of a workspace. */
|
|
23
|
+
export type WorkspaceStatus = 'active' | 'deleted';
|
|
24
|
+
|
|
25
|
+
/** Membership lifecycle status. */
|
|
26
|
+
export type WorkspaceMemberStatus = 'active' | 'invited' | 'removed';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Client-facing WorkspaceMember shape. `permissions` is derived from `role`
|
|
30
|
+
* on the server at write time.
|
|
31
|
+
*/
|
|
32
|
+
export interface WorkspaceMember {
|
|
33
|
+
_id: string;
|
|
34
|
+
workspaceId: string;
|
|
35
|
+
userId: string;
|
|
36
|
+
role: WorkspaceRole;
|
|
37
|
+
permissions: string[];
|
|
38
|
+
invitedByUserId?: string | null;
|
|
39
|
+
joinedAt?: string | null;
|
|
40
|
+
status: WorkspaceMemberStatus;
|
|
41
|
+
createdAt: string;
|
|
42
|
+
updatedAt: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Client-facing Workspace shape returned by the `/workspaces` API. Mirrors the
|
|
47
|
+
* server `Workspace` model with `_id` as a string and dates serialized to ISO
|
|
48
|
+
* strings.
|
|
49
|
+
*/
|
|
50
|
+
export interface Workspace {
|
|
51
|
+
_id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
slug: string;
|
|
54
|
+
type: WorkspaceType;
|
|
55
|
+
description?: string | null;
|
|
56
|
+
icon?: string | null;
|
|
57
|
+
ownerId: string;
|
|
58
|
+
status: WorkspaceStatus;
|
|
59
|
+
createdAt: string;
|
|
60
|
+
updatedAt: string;
|
|
61
|
+
/**
|
|
62
|
+
* The calling user's own membership in this workspace, embedded by the API
|
|
63
|
+
* on list (`GET /workspaces`) and detail (`GET /workspaces/:id`) responses.
|
|
64
|
+
* Use `callerMembership.permissions` to gate UI affordances.
|
|
65
|
+
*/
|
|
66
|
+
callerMembership?: WorkspaceMember | null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Input accepted by `createWorkspace`. */
|
|
70
|
+
export interface CreateWorkspaceInput {
|
|
71
|
+
name: string;
|
|
72
|
+
description?: string;
|
|
73
|
+
icon?: string;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Input accepted by `updateWorkspace`. */
|
|
77
|
+
export interface UpdateWorkspaceInput {
|
|
78
|
+
name?: string;
|
|
79
|
+
description?: string | null;
|
|
80
|
+
icon?: string | null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Input accepted by `inviteWorkspaceMember`. The owner role cannot be invited. */
|
|
84
|
+
export interface InviteWorkspaceMemberInput {
|
|
85
|
+
/**
|
|
86
|
+
* The username or email of the user to invite. Resolved to a user server-side;
|
|
87
|
+
* an unknown value yields a 404 "User not found".
|
|
88
|
+
*/
|
|
89
|
+
usernameOrEmail: string;
|
|
90
|
+
role: Exclude<WorkspaceRole, 'owner'>;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Input accepted by `updateWorkspaceMember`. The owner role cannot be assigned. */
|
|
94
|
+
export interface UpdateWorkspaceMemberInput {
|
|
95
|
+
role: Exclude<WorkspaceRole, 'owner'>;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Input accepted by `transferWorkspaceOwnership`. */
|
|
99
|
+
export interface TransferWorkspaceOwnershipInput {
|
|
100
|
+
userId: string;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Result of a delete/remove/transfer operation. */
|
|
104
|
+
export interface WorkspaceSuccessResult {
|
|
105
|
+
success: boolean;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function OxyServicesWorkspacesMixin<T extends typeof OxyServicesBase>(Base: T) {
|
|
109
|
+
return class extends Base {
|
|
110
|
+
constructor(...args: any[]) {
|
|
111
|
+
super(...(args as [any]));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* List workspaces the current user is an active member of.
|
|
116
|
+
*/
|
|
117
|
+
async getWorkspaces(): Promise<Workspace[]> {
|
|
118
|
+
try {
|
|
119
|
+
const res = await this.makeRequest<{ workspaces?: Workspace[] }>(
|
|
120
|
+
'GET',
|
|
121
|
+
'/workspaces',
|
|
122
|
+
undefined,
|
|
123
|
+
{ cache: true, cacheTTL: CACHE_TIMES.MEDIUM },
|
|
124
|
+
);
|
|
125
|
+
return res.workspaces ?? [];
|
|
126
|
+
} catch (error) {
|
|
127
|
+
throw this.handleError(error);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Create a new team workspace. The caller becomes its `owner`.
|
|
133
|
+
* @param data - Workspace configuration.
|
|
134
|
+
*/
|
|
135
|
+
async createWorkspace(data: CreateWorkspaceInput): Promise<Workspace> {
|
|
136
|
+
try {
|
|
137
|
+
const res = await this.makeRequest<{ workspace: Workspace }>(
|
|
138
|
+
'POST',
|
|
139
|
+
'/workspaces',
|
|
140
|
+
data,
|
|
141
|
+
{ cache: false },
|
|
142
|
+
);
|
|
143
|
+
return res.workspace;
|
|
144
|
+
} catch (error) {
|
|
145
|
+
throw this.handleError(error);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Fetch a single workspace by id.
|
|
151
|
+
* @param workspaceId - The workspace's Mongo `_id`.
|
|
152
|
+
*/
|
|
153
|
+
async getWorkspace(workspaceId: string): Promise<Workspace> {
|
|
154
|
+
try {
|
|
155
|
+
const res = await this.makeRequest<{ workspace: Workspace }>(
|
|
156
|
+
'GET',
|
|
157
|
+
`/workspaces/${encodeURIComponent(workspaceId)}`,
|
|
158
|
+
undefined,
|
|
159
|
+
{ cache: true, cacheTTL: CACHE_TIMES.LONG },
|
|
160
|
+
);
|
|
161
|
+
return res.workspace;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
throw this.handleError(error);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Update a workspace's mutable fields.
|
|
169
|
+
* @param workspaceId - The workspace's Mongo `_id`.
|
|
170
|
+
* @param data - Subset of updatable fields.
|
|
171
|
+
*/
|
|
172
|
+
async updateWorkspace(
|
|
173
|
+
workspaceId: string,
|
|
174
|
+
data: UpdateWorkspaceInput,
|
|
175
|
+
): Promise<Workspace> {
|
|
176
|
+
try {
|
|
177
|
+
const res = await this.makeRequest<{ workspace: Workspace }>(
|
|
178
|
+
'PATCH',
|
|
179
|
+
`/workspaces/${encodeURIComponent(workspaceId)}`,
|
|
180
|
+
data,
|
|
181
|
+
{ cache: false },
|
|
182
|
+
);
|
|
183
|
+
return res.workspace;
|
|
184
|
+
} catch (error) {
|
|
185
|
+
throw this.handleError(error);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Soft-delete a workspace (owner only).
|
|
191
|
+
* @param workspaceId - The workspace's Mongo `_id`.
|
|
192
|
+
*/
|
|
193
|
+
async deleteWorkspace(workspaceId: string): Promise<WorkspaceSuccessResult> {
|
|
194
|
+
try {
|
|
195
|
+
return await this.makeRequest<WorkspaceSuccessResult>(
|
|
196
|
+
'DELETE',
|
|
197
|
+
`/workspaces/${encodeURIComponent(workspaceId)}`,
|
|
198
|
+
undefined,
|
|
199
|
+
{ cache: false },
|
|
200
|
+
);
|
|
201
|
+
} catch (error) {
|
|
202
|
+
throw this.handleError(error);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* List members of a workspace.
|
|
208
|
+
* @param workspaceId - The workspace's Mongo `_id`.
|
|
209
|
+
*/
|
|
210
|
+
async getWorkspaceMembers(workspaceId: string): Promise<WorkspaceMember[]> {
|
|
211
|
+
try {
|
|
212
|
+
const res = await this.makeRequest<{ members?: WorkspaceMember[] }>(
|
|
213
|
+
'GET',
|
|
214
|
+
`/workspaces/${encodeURIComponent(workspaceId)}/members`,
|
|
215
|
+
undefined,
|
|
216
|
+
{ cache: true, cacheTTL: CACHE_TIMES.MEDIUM },
|
|
217
|
+
);
|
|
218
|
+
return res.members ?? [];
|
|
219
|
+
} catch (error) {
|
|
220
|
+
throw this.handleError(error);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Add a member to a workspace.
|
|
226
|
+
* @param workspaceId - The workspace's Mongo `_id`.
|
|
227
|
+
* @param data - Target user's username or email and role (never `owner`).
|
|
228
|
+
* The server resolves `usernameOrEmail` to a user; an unknown value yields
|
|
229
|
+
* a 404 "User not found".
|
|
230
|
+
*/
|
|
231
|
+
async inviteWorkspaceMember(
|
|
232
|
+
workspaceId: string,
|
|
233
|
+
data: InviteWorkspaceMemberInput,
|
|
234
|
+
): Promise<WorkspaceMember> {
|
|
235
|
+
try {
|
|
236
|
+
const res = await this.makeRequest<{ member: WorkspaceMember }>(
|
|
237
|
+
'POST',
|
|
238
|
+
`/workspaces/${encodeURIComponent(workspaceId)}/members`,
|
|
239
|
+
data,
|
|
240
|
+
{ cache: false },
|
|
241
|
+
);
|
|
242
|
+
return res.member;
|
|
243
|
+
} catch (error) {
|
|
244
|
+
throw this.handleError(error);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Change a member's role.
|
|
250
|
+
* @param workspaceId - The workspace's Mongo `_id`.
|
|
251
|
+
* @param memberId - The member's Mongo `_id`.
|
|
252
|
+
* @param data - New role (never `owner`).
|
|
253
|
+
*/
|
|
254
|
+
async updateWorkspaceMember(
|
|
255
|
+
workspaceId: string,
|
|
256
|
+
memberId: string,
|
|
257
|
+
data: UpdateWorkspaceMemberInput,
|
|
258
|
+
): Promise<WorkspaceMember> {
|
|
259
|
+
try {
|
|
260
|
+
const res = await this.makeRequest<{ member: WorkspaceMember }>(
|
|
261
|
+
'PATCH',
|
|
262
|
+
`/workspaces/${encodeURIComponent(workspaceId)}/members/${encodeURIComponent(memberId)}`,
|
|
263
|
+
data,
|
|
264
|
+
{ cache: false },
|
|
265
|
+
);
|
|
266
|
+
return res.member;
|
|
267
|
+
} catch (error) {
|
|
268
|
+
throw this.handleError(error);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Remove a member from a workspace.
|
|
274
|
+
* @param workspaceId - The workspace's Mongo `_id`.
|
|
275
|
+
* @param memberId - The member's Mongo `_id`.
|
|
276
|
+
*/
|
|
277
|
+
async removeWorkspaceMember(
|
|
278
|
+
workspaceId: string,
|
|
279
|
+
memberId: string,
|
|
280
|
+
): Promise<WorkspaceSuccessResult> {
|
|
281
|
+
try {
|
|
282
|
+
return await this.makeRequest<WorkspaceSuccessResult>(
|
|
283
|
+
'DELETE',
|
|
284
|
+
`/workspaces/${encodeURIComponent(workspaceId)}/members/${encodeURIComponent(memberId)}`,
|
|
285
|
+
undefined,
|
|
286
|
+
{ cache: false },
|
|
287
|
+
);
|
|
288
|
+
} catch (error) {
|
|
289
|
+
throw this.handleError(error);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Transfer ownership of a workspace to another member (owner only).
|
|
295
|
+
* Demotes the current owner and promotes the target to `owner`.
|
|
296
|
+
* @param workspaceId - The workspace's Mongo `_id`.
|
|
297
|
+
* @param data - Target user id.
|
|
298
|
+
*/
|
|
299
|
+
async transferWorkspaceOwnership(
|
|
300
|
+
workspaceId: string,
|
|
301
|
+
data: TransferWorkspaceOwnershipInput,
|
|
302
|
+
): Promise<WorkspaceSuccessResult> {
|
|
303
|
+
try {
|
|
304
|
+
return await this.makeRequest<WorkspaceSuccessResult>(
|
|
305
|
+
'POST',
|
|
306
|
+
`/workspaces/${encodeURIComponent(workspaceId)}/transfer-ownership`,
|
|
307
|
+
data,
|
|
308
|
+
{ cache: false },
|
|
309
|
+
);
|
|
310
|
+
} catch (error) {
|
|
311
|
+
throw this.handleError(error);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
}
|