@neuralinnovations/dataisland-sdk 0.0.1-dev2 → 0.0.1-dev21
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/LICENSE +201 -0
- package/README.md +306 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/package.json +100 -0
- package/dist/src/appBuilder.d.ts +44 -0
- package/dist/src/appBuilder.d.ts.map +1 -0
- package/dist/src/appBuilder.js +10 -0
- package/dist/src/appBuilder.js.map +1 -0
- package/dist/src/commands/startCommandHandler.d.ts +7 -0
- package/dist/src/commands/startCommandHandler.d.ts.map +1 -0
- package/dist/src/commands/startCommandHandler.js +17 -0
- package/dist/src/commands/startCommandHandler.js.map +1 -0
- package/dist/src/context.d.ts +23 -0
- package/dist/src/context.d.ts.map +1 -0
- package/dist/src/context.js +31 -0
- package/dist/src/context.js.map +1 -0
- package/dist/src/credentials.d.ts +28 -0
- package/dist/src/credentials.d.ts.map +1 -0
- package/dist/src/credentials.js +70 -0
- package/dist/src/credentials.js.map +1 -0
- package/dist/src/dataIslandApp.d.ts +50 -0
- package/dist/src/dataIslandApp.d.ts.map +1 -0
- package/dist/src/dataIslandApp.js +10 -0
- package/dist/src/dataIslandApp.js.map +1 -0
- package/dist/src/disposable.d.ts +84 -0
- package/dist/src/disposable.d.ts.map +1 -0
- package/dist/src/disposable.js +147 -0
- package/dist/src/disposable.js.map +1 -0
- package/dist/src/dto/accessGroupResponse.d.ts +27 -0
- package/dist/src/dto/accessGroupResponse.d.ts.map +1 -0
- package/dist/src/dto/accessGroupResponse.js +3 -0
- package/dist/src/dto/accessGroupResponse.js.map +1 -0
- package/dist/src/dto/chatResponse.d.ts +78 -0
- package/dist/src/dto/chatResponse.d.ts.map +1 -0
- package/dist/src/dto/chatResponse.js +45 -0
- package/dist/src/dto/chatResponse.js.map +1 -0
- package/dist/src/dto/userInfoResponse.d.ts +42 -0
- package/dist/src/dto/userInfoResponse.d.ts.map +1 -0
- package/dist/src/dto/userInfoResponse.js +3 -0
- package/dist/src/dto/userInfoResponse.js.map +1 -0
- package/dist/src/dto/workspacesResponse.d.ts +43 -0
- package/dist/src/dto/workspacesResponse.d.ts.map +1 -0
- package/dist/src/dto/workspacesResponse.js +3 -0
- package/dist/src/dto/workspacesResponse.js.map +1 -0
- package/dist/src/events.d.ts +17 -0
- package/dist/src/events.d.ts.map +1 -0
- package/dist/src/events.js +52 -0
- package/dist/src/events.js.map +1 -0
- package/dist/src/index.d.ts +58 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +91 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/internal/app.impl.d.ts +28 -0
- package/dist/src/internal/app.impl.d.ts.map +1 -0
- package/dist/src/internal/app.impl.js +151 -0
- package/dist/src/internal/app.impl.js.map +1 -0
- package/dist/src/internal/appBuilder.impl.d.ts +27 -0
- package/dist/src/internal/appBuilder.impl.d.ts.map +1 -0
- package/dist/src/internal/appBuilder.impl.js +71 -0
- package/dist/src/internal/appBuilder.impl.js.map +1 -0
- package/dist/src/internal/createApp.impl.d.ts +4 -0
- package/dist/src/internal/createApp.impl.d.ts.map +1 -0
- package/dist/src/internal/createApp.impl.js +11 -0
- package/dist/src/internal/createApp.impl.js.map +1 -0
- package/dist/src/internal/registry.d.ts +66 -0
- package/dist/src/internal/registry.d.ts.map +1 -0
- package/dist/src/internal/registry.js +114 -0
- package/dist/src/internal/registry.js.map +1 -0
- package/dist/src/middleware.d.ts +5 -0
- package/dist/src/middleware.d.ts.map +1 -0
- package/dist/src/middleware.js +3 -0
- package/dist/src/middleware.js.map +1 -0
- package/dist/src/services/commandService.d.ts +18 -0
- package/dist/src/services/commandService.d.ts.map +1 -0
- package/dist/src/services/commandService.js +40 -0
- package/dist/src/services/commandService.js.map +1 -0
- package/dist/src/services/credentialService.d.ts +9 -0
- package/dist/src/services/credentialService.d.ts.map +1 -0
- package/dist/src/services/credentialService.js +26 -0
- package/dist/src/services/credentialService.js.map +1 -0
- package/dist/src/services/middlewareService.d.ts +9 -0
- package/dist/src/services/middlewareService.d.ts.map +1 -0
- package/dist/src/services/middlewareService.js +34 -0
- package/dist/src/services/middlewareService.js.map +1 -0
- package/dist/src/services/organizationService.d.ts +10 -0
- package/dist/src/services/organizationService.d.ts.map +1 -0
- package/dist/src/services/organizationService.js +19 -0
- package/dist/src/services/organizationService.js.map +1 -0
- package/dist/src/services/requestBuilder.d.ts +17 -0
- package/dist/src/services/requestBuilder.d.ts.map +1 -0
- package/dist/src/services/requestBuilder.js +104 -0
- package/dist/src/services/requestBuilder.js.map +1 -0
- package/dist/src/services/responseUtils.d.ts +6 -0
- package/dist/src/services/responseUtils.d.ts.map +1 -0
- package/dist/src/services/responseUtils.js +32 -0
- package/dist/src/services/responseUtils.js.map +1 -0
- package/dist/src/services/rpcService.d.ts +77 -0
- package/dist/src/services/rpcService.d.ts.map +1 -0
- package/dist/src/services/rpcService.js +125 -0
- package/dist/src/services/rpcService.js.map +1 -0
- package/dist/src/services/service.d.ts +21 -0
- package/dist/src/services/service.d.ts.map +1 -0
- package/dist/src/services/service.js +41 -0
- package/dist/src/services/service.js.map +1 -0
- package/dist/src/services/userProfileService.d.ts +8 -0
- package/dist/src/services/userProfileService.d.ts.map +1 -0
- package/dist/src/services/userProfileService.js +32 -0
- package/dist/src/services/userProfileService.js.map +1 -0
- package/dist/src/storages/chats/answer.d.ts +40 -0
- package/dist/src/storages/chats/answer.d.ts.map +1 -0
- package/dist/src/storages/chats/answer.impl.d.ts +24 -0
- package/dist/src/storages/chats/answer.impl.d.ts.map +1 -0
- package/dist/src/storages/chats/answer.impl.js +130 -0
- package/dist/src/storages/chats/answer.impl.js.map +1 -0
- package/dist/src/storages/chats/answer.js +14 -0
- package/dist/src/storages/chats/answer.js.map +1 -0
- package/dist/src/storages/chats/chat.d.ts +39 -0
- package/dist/src/storages/chats/chat.d.ts.map +1 -0
- package/dist/src/storages/chats/chat.impl.d.ts +24 -0
- package/dist/src/storages/chats/chat.impl.d.ts.map +1 -0
- package/dist/src/storages/chats/chat.impl.js +98 -0
- package/dist/src/storages/chats/chat.impl.js.map +1 -0
- package/dist/src/storages/chats/chat.js +12 -0
- package/dist/src/storages/chats/chat.js.map +1 -0
- package/dist/src/storages/chats/chats.d.ts +40 -0
- package/dist/src/storages/chats/chats.d.ts.map +1 -0
- package/dist/src/storages/chats/chats.impl.d.ts +18 -0
- package/dist/src/storages/chats/chats.impl.d.ts.map +1 -0
- package/dist/src/storages/chats/chats.impl.js +102 -0
- package/dist/src/storages/chats/chats.impl.js.map +1 -0
- package/dist/src/storages/chats/chats.js +16 -0
- package/dist/src/storages/chats/chats.js.map +1 -0
- package/dist/src/storages/files/file.d.ts +31 -0
- package/dist/src/storages/files/file.d.ts.map +1 -0
- package/dist/src/storages/files/file.impl.d.ts +21 -0
- package/dist/src/storages/files/file.impl.d.ts.map +1 -0
- package/dist/src/storages/files/file.impl.js +64 -0
- package/dist/src/storages/files/file.impl.js.map +1 -0
- package/dist/src/storages/files/file.js +11 -0
- package/dist/src/storages/files/file.js.map +1 -0
- package/dist/src/storages/files/files.d.ts +34 -0
- package/dist/src/storages/files/files.d.ts.map +1 -0
- package/dist/src/storages/files/files.impl.d.ts +22 -0
- package/dist/src/storages/files/files.impl.d.ts.map +1 -0
- package/dist/src/storages/files/files.impl.js +140 -0
- package/dist/src/storages/files/files.impl.js.map +1 -0
- package/dist/src/storages/files/files.js +20 -0
- package/dist/src/storages/files/files.js.map +1 -0
- package/dist/src/storages/files/filesPage.d.ts +28 -0
- package/dist/src/storages/files/filesPage.d.ts.map +1 -0
- package/dist/src/storages/files/filesPage.impl.d.ts +15 -0
- package/dist/src/storages/files/filesPage.impl.d.ts.map +1 -0
- package/dist/src/storages/files/filesPage.impl.js +38 -0
- package/dist/src/storages/files/filesPage.impl.js.map +1 -0
- package/dist/src/storages/files/filesPage.js +10 -0
- package/dist/src/storages/files/filesPage.js.map +1 -0
- package/dist/src/storages/groups/groups.d.ts +91 -0
- package/dist/src/storages/groups/groups.d.ts.map +1 -0
- package/dist/src/storages/groups/groups.impl.d.ts +61 -0
- package/dist/src/storages/groups/groups.impl.d.ts.map +1 -0
- package/dist/src/storages/groups/groups.impl.js +293 -0
- package/dist/src/storages/groups/groups.impl.js.map +1 -0
- package/dist/src/storages/groups/groups.js +26 -0
- package/dist/src/storages/groups/groups.js.map +1 -0
- package/dist/src/storages/organizations/organization.d.ts +54 -0
- package/dist/src/storages/organizations/organization.d.ts.map +1 -0
- package/dist/src/storages/organizations/organization.impl.d.ts +32 -0
- package/dist/src/storages/organizations/organization.impl.d.ts.map +1 -0
- package/dist/src/storages/organizations/organization.impl.js +120 -0
- package/dist/src/storages/organizations/organization.impl.js.map +1 -0
- package/dist/src/storages/organizations/organization.js +18 -0
- package/dist/src/storages/organizations/organization.js.map +1 -0
- package/dist/src/storages/organizations/organizations.d.ts +46 -0
- package/dist/src/storages/organizations/organizations.d.ts.map +1 -0
- package/dist/src/storages/organizations/organizations.impl.d.ts +38 -0
- package/dist/src/storages/organizations/organizations.impl.d.ts.map +1 -0
- package/dist/src/storages/organizations/organizations.impl.js +151 -0
- package/dist/src/storages/organizations/organizations.impl.js.map +1 -0
- package/dist/src/storages/organizations/organizations.js +20 -0
- package/dist/src/storages/organizations/organizations.js.map +1 -0
- package/dist/src/storages/user/userProfile.d.ts +32 -0
- package/dist/src/storages/user/userProfile.d.ts.map +1 -0
- package/dist/src/storages/user/userProfile.impl.d.ts +13 -0
- package/dist/src/storages/user/userProfile.impl.d.ts.map +1 -0
- package/dist/src/storages/user/userProfile.impl.js +51 -0
- package/dist/src/storages/user/userProfile.impl.js.map +1 -0
- package/dist/src/storages/user/userProfile.js +12 -0
- package/dist/src/storages/user/userProfile.js.map +1 -0
- package/dist/src/storages/workspaces/workspace.d.ts +44 -0
- package/dist/src/storages/workspaces/workspace.d.ts.map +1 -0
- package/dist/src/storages/workspaces/workspace.impl.d.ts +23 -0
- package/dist/src/storages/workspaces/workspace.impl.d.ts.map +1 -0
- package/dist/src/storages/workspaces/workspace.impl.js +98 -0
- package/dist/src/storages/workspaces/workspace.impl.js.map +1 -0
- package/dist/src/storages/workspaces/workspace.js +18 -0
- package/dist/src/storages/workspaces/workspace.js.map +1 -0
- package/dist/src/storages/workspaces/workspaces.d.ts +47 -0
- package/dist/src/storages/workspaces/workspaces.d.ts.map +1 -0
- package/dist/src/storages/workspaces/workspaces.impl.d.ts +33 -0
- package/dist/src/storages/workspaces/workspaces.impl.d.ts.map +1 -0
- package/dist/src/storages/workspaces/workspaces.impl.js +157 -0
- package/dist/src/storages/workspaces/workspaces.impl.js.map +1 -0
- package/dist/src/storages/workspaces/workspaces.js +19 -0
- package/dist/src/storages/workspaces/workspaces.js.map +1 -0
- package/dist/src/unitTest.d.ts +12 -0
- package/dist/src/unitTest.d.ts.map +1 -0
- package/dist/src/unitTest.js +44 -0
- package/dist/src/unitTest.js.map +1 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +43 -4
- package/src/appBuilder.ts +6 -6
- package/src/commands/startCommandHandler.ts +2 -2
- package/src/context.ts +5 -4
- package/src/credentials.ts +29 -7
- package/src/{appSdk.ts → dataIslandApp.ts} +7 -7
- package/src/disposable.ts +20 -8
- package/src/dto/accessGroupResponse.ts +35 -0
- package/src/dto/chatResponse.ts +103 -0
- package/src/dto/userInfoResponse.ts +15 -3
- package/src/dto/workspacesResponse.ts +49 -0
- package/src/events.ts +13 -13
- package/src/index.ts +41 -20
- package/src/internal/app.impl.ts +28 -31
- package/src/internal/appBuilder.impl.ts +16 -16
- package/src/internal/createApp.impl.ts +5 -5
- package/src/internal/registry.ts +54 -6
- package/src/services/commandService.ts +3 -3
- package/src/services/credentialService.ts +3 -3
- package/src/services/middlewareService.ts +4 -4
- package/src/services/organizationService.ts +18 -116
- package/src/services/requestBuilder.ts +40 -15
- package/src/services/responseUtils.ts +32 -0
- package/src/services/rpcService.ts +28 -11
- package/src/services/service.ts +10 -8
- package/src/services/userProfileService.ts +18 -66
- package/src/storages/chats/answer.impl.ts +186 -0
- package/src/storages/chats/answer.ts +55 -0
- package/src/storages/chats/chat.impl.ts +126 -0
- package/src/storages/chats/chat.ts +49 -0
- package/src/storages/chats/chats.impl.ts +142 -0
- package/src/storages/chats/chats.ts +47 -0
- package/src/storages/files/file.impl.ts +87 -0
- package/src/storages/files/file.ts +40 -0
- package/src/storages/files/files.impl.ts +191 -0
- package/src/storages/files/files.ts +39 -0
- package/src/storages/files/filesPage.impl.ts +37 -0
- package/src/storages/files/filesPage.ts +33 -0
- package/src/storages/groups/groups.impl.ts +386 -0
- package/src/storages/groups/groups.ts +106 -0
- package/src/storages/organizations/organization.impl.ts +163 -0
- package/src/storages/organizations/organization.ts +67 -0
- package/src/storages/organizations/organizations.impl.ts +197 -0
- package/src/storages/{organizations.ts → organizations/organizations.ts} +8 -28
- package/src/storages/user/userProfile.impl.ts +56 -0
- package/src/storages/{userProfile.ts → user/userProfile.ts} +2 -2
- package/src/storages/workspaces/workspace.impl.ts +129 -0
- package/src/storages/workspaces/workspace.ts +54 -0
- package/src/storages/workspaces/workspaces.impl.ts +212 -0
- package/src/storages/workspaces/workspaces.ts +53 -0
- package/src/unitTest.ts +12 -1
- package/.browserslistrc +0 -5
- package/.editorconfig +0 -22
- package/.eslintrc.json +0 -44
- package/.github/workflows/publish-npm.yml +0 -28
- package/.prettierignore +0 -1
- package/.prettierrc +0 -11
- package/.yarnrc +0 -2
- package/babel.config.js +0 -6
- package/jest.config.ts +0 -199
- package/jest.setup.ts +0 -2
- package/src/services/organizationImpl.ts +0 -51
- package/src/services/organizationsImpl.ts +0 -55
- package/src/types.ts +0 -86
- package/test/commands.test.ts +0 -24
- package/test/disposable.test.ts +0 -39
- package/test/events.test.ts +0 -151
- package/test/index.test.ts +0 -163
- package/test/registry.test.ts +0 -44
- package/test/services.test.ts +0 -56
- package/test/setup.ts +0 -2
- package/test/unitTest.test.ts +0 -21
- package/tsconfig.json +0 -31
@@ -0,0 +1,386 @@
|
|
1
|
+
import { Context } from "../../context"
|
2
|
+
import { Disposable } from "../../disposable"
|
3
|
+
import {
|
4
|
+
AccessGroupDto,
|
5
|
+
AccessGroupResponse,
|
6
|
+
AccessGroupsResponse
|
7
|
+
} from "../../dto/accessGroupResponse"
|
8
|
+
import { UserDto } from "../../dto/userInfoResponse"
|
9
|
+
import { WorkspacesResponse } from "../../dto/workspacesResponse"
|
10
|
+
import { RpcService } from "../../services/rpcService"
|
11
|
+
import { Group, GroupEvent, GroupId, Groups } from "./groups"
|
12
|
+
import { OrganizationImpl } from "../organizations/organization.impl"
|
13
|
+
import { ResponseUtils } from "../../services/responseUtils"
|
14
|
+
import { Organization } from "../organizations/organization"
|
15
|
+
import { UserId } from "../user/userProfile"
|
16
|
+
import { Workspace } from "../workspaces/workspace"
|
17
|
+
|
18
|
+
export class GroupImpl extends Group implements Disposable {
|
19
|
+
private _isDisposed: boolean = false
|
20
|
+
private _content?: AccessGroupDto
|
21
|
+
private _members?: UserDto[]
|
22
|
+
private _workspaces: Workspace[] = []
|
23
|
+
|
24
|
+
constructor(
|
25
|
+
private readonly context: Context,
|
26
|
+
public readonly organization: Organization
|
27
|
+
) {
|
28
|
+
super()
|
29
|
+
}
|
30
|
+
|
31
|
+
async initFrom(id: GroupId): Promise<Group> {
|
32
|
+
await this.reloadGroup(id)
|
33
|
+
await this.reloadWorkspaces()
|
34
|
+
return this
|
35
|
+
}
|
36
|
+
|
37
|
+
async reloadGroup(id: GroupId): Promise<void> {
|
38
|
+
// fetch group
|
39
|
+
const response = await this.context.resolve(RpcService)
|
40
|
+
?.requestBuilder("api/v1/AccessGroups")
|
41
|
+
.searchParam("groupId", id)
|
42
|
+
.sendGet()
|
43
|
+
|
44
|
+
// check response status
|
45
|
+
if (ResponseUtils.isFail(response)) {
|
46
|
+
await ResponseUtils.throwError(`Failed to get group: ${id}, organization: ${this.organization.id}`, response)
|
47
|
+
}
|
48
|
+
|
49
|
+
// parse group from the server's response
|
50
|
+
const group = (await response!.json()) as AccessGroupResponse
|
51
|
+
// init group
|
52
|
+
this._content = group.group
|
53
|
+
this._members = group.members
|
54
|
+
}
|
55
|
+
|
56
|
+
async reloadWorkspaces(): Promise<void> {
|
57
|
+
const groupWorkspaces = await this.loadWorkspaces(this.id)
|
58
|
+
this._workspaces.length = 0
|
59
|
+
this._workspaces.push(...groupWorkspaces)
|
60
|
+
}
|
61
|
+
|
62
|
+
async loadWorkspaces(groupId: GroupId): Promise<Workspace[]> {
|
63
|
+
// fetch workspaces
|
64
|
+
const response = await this.context.resolve(RpcService)
|
65
|
+
?.requestBuilder("api/v1/AccessGroups/workspaces")
|
66
|
+
.searchParam("groupId", groupId)
|
67
|
+
.sendGet()
|
68
|
+
|
69
|
+
if (ResponseUtils.isFail(response)) {
|
70
|
+
await ResponseUtils.throwError(`Failed to get workspaces for group: ${this.id}, organization: ${this.organization.id}`, response)
|
71
|
+
}
|
72
|
+
|
73
|
+
// parse workspaces from the server's response
|
74
|
+
const workspaces = (await response!.json()) as WorkspacesResponse
|
75
|
+
|
76
|
+
// get workspaces
|
77
|
+
const result: Workspace[] = []
|
78
|
+
for (const workspaceDto of workspaces.workspaces) {
|
79
|
+
result.push(this.organization.workspaces.get(workspaceDto.id))
|
80
|
+
}
|
81
|
+
|
82
|
+
return result
|
83
|
+
}
|
84
|
+
|
85
|
+
get id(): GroupId {
|
86
|
+
if (this._content) {
|
87
|
+
return this._content.id
|
88
|
+
}
|
89
|
+
throw new Error("Access group is not loaded.")
|
90
|
+
}
|
91
|
+
|
92
|
+
get group(): AccessGroupDto {
|
93
|
+
if (this._content) {
|
94
|
+
return this._content
|
95
|
+
}
|
96
|
+
throw new Error("Access group is not loaded.")
|
97
|
+
}
|
98
|
+
|
99
|
+
get workspaces(): readonly Workspace[] {
|
100
|
+
return this._workspaces
|
101
|
+
}
|
102
|
+
|
103
|
+
get members(): UserDto[] {
|
104
|
+
if (this._members) {
|
105
|
+
return this._members
|
106
|
+
}
|
107
|
+
throw new Error("Access group is not loaded.")
|
108
|
+
}
|
109
|
+
|
110
|
+
async setName(name: string): Promise<void> {
|
111
|
+
if (name === undefined || name === null) {
|
112
|
+
throw new Error("Groups change, name is undefined or null")
|
113
|
+
}
|
114
|
+
if (name.length === 0 || name.trim().length === 0) {
|
115
|
+
throw new Error("Groups change, name is empty")
|
116
|
+
}
|
117
|
+
// send request to the server
|
118
|
+
const response = await this.context
|
119
|
+
.resolve(RpcService)
|
120
|
+
?.requestBuilder("api/v1/AccessGroups/name")
|
121
|
+
.sendPutJson({
|
122
|
+
groupId: this.id,
|
123
|
+
name: name
|
124
|
+
})
|
125
|
+
|
126
|
+
// check response status
|
127
|
+
if (ResponseUtils.isFail(response)) {
|
128
|
+
await ResponseUtils.throwError(`Failed to change group name, group: ${this.id}, organization: ${this.organization.id}`, response)
|
129
|
+
}
|
130
|
+
|
131
|
+
// change name
|
132
|
+
if (this._content) {
|
133
|
+
this._content.name = name
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
async setPermits(permits: { isAdmin: boolean }): Promise<void> {
|
138
|
+
// send request to the server
|
139
|
+
const response = await this.context
|
140
|
+
.resolve(RpcService)
|
141
|
+
?.requestBuilder("api/v1/AccessGroups/permits")
|
142
|
+
.sendPutJson({
|
143
|
+
groupId: this.id,
|
144
|
+
permits: permits
|
145
|
+
})
|
146
|
+
|
147
|
+
if (ResponseUtils.isFail(response)) {
|
148
|
+
await ResponseUtils.throwError(`Failed to change group permits, group: ${this.id}, organization: ${this.organization.id}`, response)
|
149
|
+
}
|
150
|
+
}
|
151
|
+
|
152
|
+
async setWorkspaces(workspaces: string[]): Promise<void> {
|
153
|
+
if (workspaces === null || workspaces === undefined) {
|
154
|
+
throw new Error("Group add workspaces, workspaces is undefined or null")
|
155
|
+
}
|
156
|
+
|
157
|
+
// send request to the server
|
158
|
+
const response = await this.context
|
159
|
+
.resolve(RpcService)
|
160
|
+
?.requestBuilder("api/v1/AccessGroups/workspaces")
|
161
|
+
.sendPutJson({
|
162
|
+
groupId: this.id,
|
163
|
+
actualWorkspaceIds: workspaces
|
164
|
+
})
|
165
|
+
|
166
|
+
if (ResponseUtils.isFail(response)) {
|
167
|
+
await ResponseUtils.throwError(`Failed to set workspaces for group: ${this.id}, organization: ${this.organization.id}`, response)
|
168
|
+
}
|
169
|
+
|
170
|
+
// reload workspaces
|
171
|
+
await this.reloadWorkspaces()
|
172
|
+
}
|
173
|
+
|
174
|
+
async setMembersIds(members: UserId[]) {
|
175
|
+
if (members === null || members === undefined) {
|
176
|
+
throw new Error("Group setMembersIds, members is undefined or null")
|
177
|
+
}
|
178
|
+
|
179
|
+
// send request to the server
|
180
|
+
const response = await this.context
|
181
|
+
.resolve(RpcService)
|
182
|
+
?.requestBuilder("api/v1/AccessGroups/members")
|
183
|
+
.sendPutJson({
|
184
|
+
groupId: this.id,
|
185
|
+
memberIds: members
|
186
|
+
})
|
187
|
+
|
188
|
+
if (ResponseUtils.isFail(response)) {
|
189
|
+
await ResponseUtils.throwError(`Failed to set members for group: ${this.id}, organization: ${this.organization.id}`, response)
|
190
|
+
}
|
191
|
+
|
192
|
+
// reload group
|
193
|
+
await this.reloadGroup(this.id)
|
194
|
+
}
|
195
|
+
|
196
|
+
async removeMembers(members: UserId[]): Promise<void> {
|
197
|
+
// check members
|
198
|
+
if (members === null || members === undefined) {
|
199
|
+
throw new Error("Group removeMembers, members is undefined or null")
|
200
|
+
}
|
201
|
+
|
202
|
+
// make set of members
|
203
|
+
const groupMembers = new Set(this.members.map(m => m.id))
|
204
|
+
|
205
|
+
// check argument
|
206
|
+
if (!members.every(m => groupMembers.has(m))) {
|
207
|
+
const notExistingMembers = members.filter(memberId => !groupMembers.has(memberId))
|
208
|
+
throw new Error(`Group removeMembers, members contains not existing members: ${notExistingMembers}`)
|
209
|
+
}
|
210
|
+
|
211
|
+
// remove members
|
212
|
+
for (const id of members) {
|
213
|
+
groupMembers.delete(id)
|
214
|
+
}
|
215
|
+
|
216
|
+
// send request to the server
|
217
|
+
await this.setMembersIds(Array.from(groupMembers))
|
218
|
+
}
|
219
|
+
|
220
|
+
get isDisposed(): boolean {
|
221
|
+
return this._isDisposed
|
222
|
+
}
|
223
|
+
|
224
|
+
dispose(): void {
|
225
|
+
this._isDisposed = true
|
226
|
+
}
|
227
|
+
}
|
228
|
+
|
229
|
+
export class GroupsImpl extends Groups {
|
230
|
+
|
231
|
+
private _groups: Group[] = []
|
232
|
+
|
233
|
+
constructor(
|
234
|
+
public readonly organization: OrganizationImpl,
|
235
|
+
private readonly context: Context
|
236
|
+
) {
|
237
|
+
super()
|
238
|
+
}
|
239
|
+
|
240
|
+
get collection(): readonly Group[] {
|
241
|
+
return this._groups
|
242
|
+
}
|
243
|
+
|
244
|
+
async initialize() {
|
245
|
+
await this.internalInit()
|
246
|
+
}
|
247
|
+
|
248
|
+
async create(name: string, permits: {
|
249
|
+
isAdmin: boolean
|
250
|
+
}, memberIds: string[]): Promise<Group> {
|
251
|
+
return await this.internalCreate(name, permits, memberIds)
|
252
|
+
}
|
253
|
+
|
254
|
+
get(id: GroupId): Group | undefined {
|
255
|
+
return this._groups.find(group => group.id === id)
|
256
|
+
}
|
257
|
+
|
258
|
+
async delete(id: GroupId): Promise<void> {
|
259
|
+
return await this.internalDeleteGroup(id)
|
260
|
+
}
|
261
|
+
|
262
|
+
//----------------------------------------------------------------------------
|
263
|
+
// INTERNALS
|
264
|
+
//----------------------------------------------------------------------------
|
265
|
+
|
266
|
+
/**
|
267
|
+
* Init access groups.
|
268
|
+
*/
|
269
|
+
async internalInit(): Promise<void> {
|
270
|
+
// fetch groups
|
271
|
+
const response = await this.context.resolve(RpcService)
|
272
|
+
?.requestBuilder("api/v1/Organizations/access_groups")
|
273
|
+
.searchParam("id", this.organization.id)
|
274
|
+
.sendGet()
|
275
|
+
|
276
|
+
// check response status
|
277
|
+
if (ResponseUtils.isFail(response)) {
|
278
|
+
await ResponseUtils.throwError(`Failed to get groups for organization: ${this.organization.id}`, response)
|
279
|
+
}
|
280
|
+
|
281
|
+
// parse groups from the server's response
|
282
|
+
const groups = (await response!.json()) as AccessGroupsResponse
|
283
|
+
|
284
|
+
// init groups
|
285
|
+
for (const gr of groups.groups) {
|
286
|
+
// create group implementation
|
287
|
+
const group = await new GroupImpl(this.context, this.organization).initFrom(gr.id)
|
288
|
+
|
289
|
+
// add group to the collection
|
290
|
+
this._groups.push(group)
|
291
|
+
|
292
|
+
// dispatch event
|
293
|
+
this.dispatch({
|
294
|
+
type: GroupEvent.ADDED,
|
295
|
+
data: group
|
296
|
+
})
|
297
|
+
}
|
298
|
+
}
|
299
|
+
|
300
|
+
async internalCreate(name: string, permits: {
|
301
|
+
isAdmin: boolean
|
302
|
+
}, memberIds: string[]): Promise<Group> {
|
303
|
+
if (name === undefined || name === null) {
|
304
|
+
throw new Error("Group create, name is undefined or null")
|
305
|
+
}
|
306
|
+
if (name.length === 0 || name.trim().length === 0) {
|
307
|
+
throw new Error("Group create, name is empty")
|
308
|
+
}
|
309
|
+
|
310
|
+
// send request to the server
|
311
|
+
const response = await this.context
|
312
|
+
.resolve(RpcService)
|
313
|
+
?.requestBuilder("api/v1/AccessGroups")
|
314
|
+
.sendPostJson({
|
315
|
+
name: name,
|
316
|
+
organizationId: this.organization.id,
|
317
|
+
permits: permits,
|
318
|
+
memberIds: memberIds
|
319
|
+
})
|
320
|
+
|
321
|
+
// check response status
|
322
|
+
if (ResponseUtils.isFail(response)) {
|
323
|
+
await ResponseUtils.throwError(`Failed to create group, organization: ${this.organization.id}`, response)
|
324
|
+
}
|
325
|
+
// parse group from the server's response
|
326
|
+
const content = (await response!.json()) as AccessGroupResponse
|
327
|
+
|
328
|
+
// create group implementation
|
329
|
+
const group = await new GroupImpl(this.context, this.organization).initFrom(content.group.id)
|
330
|
+
|
331
|
+
// add group to the collection
|
332
|
+
this._groups.push(group)
|
333
|
+
|
334
|
+
// dispatch event
|
335
|
+
this.dispatch({
|
336
|
+
type: GroupEvent.ADDED,
|
337
|
+
data: group
|
338
|
+
})
|
339
|
+
|
340
|
+
return group
|
341
|
+
}
|
342
|
+
|
343
|
+
/**
|
344
|
+
* Delete group.
|
345
|
+
* @param id
|
346
|
+
*/
|
347
|
+
async internalDeleteGroup(id: GroupId): Promise<void> {
|
348
|
+
if (id === undefined || id === null) {
|
349
|
+
throw new Error("Group delete, id is undefined or null")
|
350
|
+
}
|
351
|
+
if (id.length === 0 || id.trim().length === 0) {
|
352
|
+
throw new Error("Group delete, id is empty")
|
353
|
+
}
|
354
|
+
|
355
|
+
// send request to the server
|
356
|
+
const response = await this.context
|
357
|
+
.resolve(RpcService)
|
358
|
+
?.requestBuilder("/api/v1/AccessGroups")
|
359
|
+
.searchParam("groupId", id)
|
360
|
+
.sendDelete()
|
361
|
+
|
362
|
+
// check response status
|
363
|
+
if (ResponseUtils.isFail(response)) {
|
364
|
+
await ResponseUtils.throwError(`Failed to delete group: ${id}, organization: ${this.organization.id}`, response)
|
365
|
+
}
|
366
|
+
|
367
|
+
// delete group from collection
|
368
|
+
const group = <GroupImpl>this._groups.find(f => f.id === id)
|
369
|
+
const index = this._groups.indexOf(group)
|
370
|
+
if (index < 0) {
|
371
|
+
throw new Error("Group delete, index is not found")
|
372
|
+
}
|
373
|
+
|
374
|
+
// remove group from collection
|
375
|
+
this._groups.splice(index, 1)
|
376
|
+
|
377
|
+
// dispatch event, group removed
|
378
|
+
this.dispatch({
|
379
|
+
type: GroupEvent.REMOVED,
|
380
|
+
data: group
|
381
|
+
})
|
382
|
+
|
383
|
+
// dispose group
|
384
|
+
group.dispose()
|
385
|
+
}
|
386
|
+
}
|
@@ -0,0 +1,106 @@
|
|
1
|
+
import { AccessGroupDto } from "../../dto/accessGroupResponse"
|
2
|
+
import { UserDto } from "../../dto/userInfoResponse"
|
3
|
+
import { EventDispatcher } from "../../events"
|
4
|
+
import { UserId } from "../user/userProfile"
|
5
|
+
import { WorkspaceId } from "../workspaces/workspaces"
|
6
|
+
import { Workspace } from "../workspaces/workspace"
|
7
|
+
|
8
|
+
/**
|
9
|
+
* Group id.
|
10
|
+
*/
|
11
|
+
export type GroupId = string
|
12
|
+
|
13
|
+
/**
|
14
|
+
* Group event.
|
15
|
+
*/
|
16
|
+
export enum GroupEvent {
|
17
|
+
ADDED = "added",
|
18
|
+
REMOVED = "removed",
|
19
|
+
UPDATED = "updated"
|
20
|
+
}
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Group.
|
24
|
+
*/
|
25
|
+
export abstract class Group extends EventDispatcher<GroupEvent, Group> {
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Group id.
|
29
|
+
*/
|
30
|
+
abstract get id(): GroupId
|
31
|
+
|
32
|
+
/**
|
33
|
+
* Group information.
|
34
|
+
*/
|
35
|
+
abstract get group(): AccessGroupDto
|
36
|
+
|
37
|
+
/**
|
38
|
+
* Group members.
|
39
|
+
*/
|
40
|
+
abstract get members(): UserDto[]
|
41
|
+
|
42
|
+
/**
|
43
|
+
* Group workspaces.
|
44
|
+
*/
|
45
|
+
abstract get workspaces(): readonly Workspace[]
|
46
|
+
|
47
|
+
/**
|
48
|
+
* Set workspaces.
|
49
|
+
*/
|
50
|
+
abstract setWorkspaces(workspaces: WorkspaceId[]): Promise<void>
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Set name.
|
54
|
+
*/
|
55
|
+
abstract setName(name: string): Promise<void>
|
56
|
+
|
57
|
+
/**
|
58
|
+
* Set permits.
|
59
|
+
*/
|
60
|
+
abstract setPermits(permits: { isAdmin: boolean }): Promise<void>
|
61
|
+
|
62
|
+
/**
|
63
|
+
* Set members.
|
64
|
+
*/
|
65
|
+
abstract setMembersIds(members: UserId[]): Promise<void>
|
66
|
+
|
67
|
+
/**
|
68
|
+
* Remove members.
|
69
|
+
* @param members
|
70
|
+
*/
|
71
|
+
abstract removeMembers(members: UserId[]): Promise<void>
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
* Groups storage.
|
76
|
+
*/
|
77
|
+
export abstract class Groups extends EventDispatcher<GroupEvent, Group> {
|
78
|
+
|
79
|
+
/**
|
80
|
+
* Collection.
|
81
|
+
*/
|
82
|
+
abstract get collection(): ReadonlyArray<Group>
|
83
|
+
|
84
|
+
/**
|
85
|
+
* Create new group.
|
86
|
+
* @param name
|
87
|
+
* @param permits
|
88
|
+
* @param memberIds
|
89
|
+
*/
|
90
|
+
abstract create(name: string, permits: {
|
91
|
+
isAdmin: boolean
|
92
|
+
}, memberIds: string[]): Promise<Group>
|
93
|
+
|
94
|
+
/**
|
95
|
+
* Get group by id.
|
96
|
+
* @param id
|
97
|
+
*/
|
98
|
+
abstract get(id: GroupId): Group | undefined
|
99
|
+
|
100
|
+
/**
|
101
|
+
* delete group by id.
|
102
|
+
* @param id
|
103
|
+
*/
|
104
|
+
abstract delete(id: GroupId): Promise<void>
|
105
|
+
|
106
|
+
}
|
@@ -0,0 +1,163 @@
|
|
1
|
+
import { OrganizationId } from "./organizations"
|
2
|
+
import { Disposable } from "../../disposable"
|
3
|
+
import { OrganizationDto, UserDto } from "../../dto/userInfoResponse"
|
4
|
+
import { Workspaces } from "../workspaces/workspaces"
|
5
|
+
import { WorkspacesImpl } from "../workspaces/workspaces.impl"
|
6
|
+
import { Context } from "../../context"
|
7
|
+
import { Organization, OrganizationEvent } from "./organization"
|
8
|
+
import { GroupsImpl } from "../groups/groups.impl"
|
9
|
+
import { Groups } from "../groups/groups"
|
10
|
+
import { ChatsImpl } from "../chats/chats.impl"
|
11
|
+
import { Chats } from "../chats/chats"
|
12
|
+
import { RpcService } from "../../services/rpcService"
|
13
|
+
import { ResponseUtils } from "../../services/responseUtils"
|
14
|
+
|
15
|
+
export class OrganizationImpl extends Organization implements Disposable {
|
16
|
+
private _isDisposed: boolean = false
|
17
|
+
private _isAdmin: boolean = false
|
18
|
+
private _content?: OrganizationDto
|
19
|
+
private readonly _workspaces: WorkspacesImpl
|
20
|
+
private readonly _accessGroups: GroupsImpl
|
21
|
+
private readonly _chats: ChatsImpl
|
22
|
+
|
23
|
+
constructor(private readonly context: Context) {
|
24
|
+
super()
|
25
|
+
this._workspaces = new WorkspacesImpl(this, this.context)
|
26
|
+
this._accessGroups = new GroupsImpl(this, this.context)
|
27
|
+
this._chats = new ChatsImpl(this, this.context)
|
28
|
+
}
|
29
|
+
|
30
|
+
public async initFrom(
|
31
|
+
content: OrganizationDto,
|
32
|
+
isAdmin: boolean
|
33
|
+
): Promise<OrganizationImpl> {
|
34
|
+
this._content = content
|
35
|
+
this._isAdmin = isAdmin
|
36
|
+
|
37
|
+
// init workspaces by organization id
|
38
|
+
await this._workspaces.initFrom(content.id)
|
39
|
+
await this._chats.initFrom(content.id)
|
40
|
+
await this._accessGroups.initialize()
|
41
|
+
|
42
|
+
return this
|
43
|
+
}
|
44
|
+
|
45
|
+
get isAdmin(): boolean {
|
46
|
+
return this._isAdmin
|
47
|
+
}
|
48
|
+
|
49
|
+
get isDisposed(): boolean {
|
50
|
+
return this._isDisposed
|
51
|
+
}
|
52
|
+
|
53
|
+
dispose(): void {
|
54
|
+
this._isDisposed = true
|
55
|
+
}
|
56
|
+
|
57
|
+
get id(): OrganizationId {
|
58
|
+
return <OrganizationId>this._content?.id
|
59
|
+
}
|
60
|
+
|
61
|
+
get name(): string {
|
62
|
+
return <OrganizationId>this._content?.profile.name
|
63
|
+
}
|
64
|
+
|
65
|
+
get description(): string {
|
66
|
+
return <OrganizationId>this._content?.profile.description
|
67
|
+
}
|
68
|
+
|
69
|
+
get workspaces(): Workspaces {
|
70
|
+
return this._workspaces
|
71
|
+
}
|
72
|
+
|
73
|
+
get accessGroups(): Groups {
|
74
|
+
return this._accessGroups
|
75
|
+
}
|
76
|
+
|
77
|
+
get chats(): Chats {
|
78
|
+
return this._chats
|
79
|
+
}
|
80
|
+
|
81
|
+
async members(): Promise<UserDto[]> {
|
82
|
+
// send request to the server
|
83
|
+
const response = await this.context
|
84
|
+
.resolve(RpcService)
|
85
|
+
?.requestBuilder("api/v1/Organizations/members")
|
86
|
+
.searchParam("id", this.id)
|
87
|
+
.sendGet()
|
88
|
+
|
89
|
+
// check response status
|
90
|
+
if (ResponseUtils.isFail(response)) {
|
91
|
+
await ResponseUtils.throwError(
|
92
|
+
`Failed during fetch of organization members ${this.id}`,
|
93
|
+
response
|
94
|
+
)
|
95
|
+
}
|
96
|
+
|
97
|
+
return (await response!.json()).members as UserDto[]
|
98
|
+
}
|
99
|
+
|
100
|
+
async change(name: string, description: string): Promise<void> {
|
101
|
+
if (!this._content) {
|
102
|
+
throw new Error("Organization is not loaded.")
|
103
|
+
}
|
104
|
+
|
105
|
+
if (name === this.name && description === this.description) {
|
106
|
+
return Promise.resolve()
|
107
|
+
}
|
108
|
+
if (name === undefined || name === null || name.trim() === "") {
|
109
|
+
throw new Error("Name is required. Please provide a valid name.")
|
110
|
+
}
|
111
|
+
if (
|
112
|
+
description === undefined ||
|
113
|
+
description === null ||
|
114
|
+
description.trim() === ""
|
115
|
+
) {
|
116
|
+
throw new Error(
|
117
|
+
"Description is required. Please provide a valid description."
|
118
|
+
)
|
119
|
+
}
|
120
|
+
|
121
|
+
const response = await this.context
|
122
|
+
.resolve(RpcService)
|
123
|
+
?.requestBuilder("api/v1/Organizations")
|
124
|
+
.sendPutJson({
|
125
|
+
organizationId: this.id,
|
126
|
+
profile: {
|
127
|
+
name,
|
128
|
+
description
|
129
|
+
}
|
130
|
+
})
|
131
|
+
|
132
|
+
if (ResponseUtils.isFail(response)) {
|
133
|
+
await ResponseUtils.throwError("Failed to change organization", response)
|
134
|
+
}
|
135
|
+
|
136
|
+
if (this._content) {
|
137
|
+
this._content.profile.name = name
|
138
|
+
this._content.profile.description = description
|
139
|
+
}
|
140
|
+
|
141
|
+
this.dispatch({
|
142
|
+
type: OrganizationEvent.CHANGED,
|
143
|
+
data: this
|
144
|
+
})
|
145
|
+
}
|
146
|
+
|
147
|
+
async createInviteLink(emails: string[], accessGroups: string[]): Promise<void> {
|
148
|
+
const response = await this.context
|
149
|
+
.resolve(RpcService)
|
150
|
+
?.requestBuilder("api/v1/Invites")
|
151
|
+
.sendPostJson({
|
152
|
+
organizationId: this.id,
|
153
|
+
emails: emails,
|
154
|
+
accessGroupIds: accessGroups
|
155
|
+
})
|
156
|
+
if (ResponseUtils.isFail(response)) {
|
157
|
+
await ResponseUtils.throwError(
|
158
|
+
`Invite link creation failed for organization ${this.id}`,
|
159
|
+
response
|
160
|
+
)
|
161
|
+
}
|
162
|
+
}
|
163
|
+
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import { Workspaces } from "../workspaces/workspaces"
|
2
|
+
import { OrganizationId } from "./organizations"
|
3
|
+
import { GroupId, Groups } from "../groups/groups"
|
4
|
+
import { Chats } from "../chats/chats"
|
5
|
+
import { EventDispatcher } from "../../events"
|
6
|
+
import { UserDto } from "../../dto/userInfoResponse"
|
7
|
+
|
8
|
+
|
9
|
+
/**
|
10
|
+
* Organization event.
|
11
|
+
*/
|
12
|
+
export enum OrganizationEvent {
|
13
|
+
CHANGED = "changed"
|
14
|
+
}
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Organization.
|
18
|
+
*/
|
19
|
+
export abstract class Organization extends EventDispatcher<
|
20
|
+
OrganizationEvent,
|
21
|
+
Organization
|
22
|
+
> {
|
23
|
+
/**
|
24
|
+
* Organization id.
|
25
|
+
*/
|
26
|
+
abstract get id(): OrganizationId
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Organization name.
|
30
|
+
*/
|
31
|
+
abstract get name(): string
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Organization description.
|
35
|
+
*/
|
36
|
+
abstract get description(): string
|
37
|
+
|
38
|
+
/**
|
39
|
+
* Workspaces.
|
40
|
+
*/
|
41
|
+
abstract get workspaces(): Workspaces
|
42
|
+
|
43
|
+
/**
|
44
|
+
* Chats.
|
45
|
+
*/
|
46
|
+
abstract get chats(): Chats
|
47
|
+
|
48
|
+
/**
|
49
|
+
* Groups.
|
50
|
+
*/
|
51
|
+
abstract get accessGroups(): Groups
|
52
|
+
|
53
|
+
/**
|
54
|
+
* Get organization members
|
55
|
+
*/
|
56
|
+
abstract members(): Promise<UserDto[]>
|
57
|
+
|
58
|
+
/**
|
59
|
+
* Change organization name and description.
|
60
|
+
*/
|
61
|
+
abstract change(name: string, description: string): Promise<void>
|
62
|
+
|
63
|
+
/**
|
64
|
+
* Create invite link
|
65
|
+
*/
|
66
|
+
abstract createInviteLink(emails: string[], accessGroups: GroupId[]): Promise<void>
|
67
|
+
}
|