@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.
Files changed (286) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +306 -1
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +3 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/package.json +100 -0
  8. package/dist/src/appBuilder.d.ts +44 -0
  9. package/dist/src/appBuilder.d.ts.map +1 -0
  10. package/dist/src/appBuilder.js +10 -0
  11. package/dist/src/appBuilder.js.map +1 -0
  12. package/dist/src/commands/startCommandHandler.d.ts +7 -0
  13. package/dist/src/commands/startCommandHandler.d.ts.map +1 -0
  14. package/dist/src/commands/startCommandHandler.js +17 -0
  15. package/dist/src/commands/startCommandHandler.js.map +1 -0
  16. package/dist/src/context.d.ts +23 -0
  17. package/dist/src/context.d.ts.map +1 -0
  18. package/dist/src/context.js +31 -0
  19. package/dist/src/context.js.map +1 -0
  20. package/dist/src/credentials.d.ts +28 -0
  21. package/dist/src/credentials.d.ts.map +1 -0
  22. package/dist/src/credentials.js +70 -0
  23. package/dist/src/credentials.js.map +1 -0
  24. package/dist/src/dataIslandApp.d.ts +50 -0
  25. package/dist/src/dataIslandApp.d.ts.map +1 -0
  26. package/dist/src/dataIslandApp.js +10 -0
  27. package/dist/src/dataIslandApp.js.map +1 -0
  28. package/dist/src/disposable.d.ts +84 -0
  29. package/dist/src/disposable.d.ts.map +1 -0
  30. package/dist/src/disposable.js +147 -0
  31. package/dist/src/disposable.js.map +1 -0
  32. package/dist/src/dto/accessGroupResponse.d.ts +27 -0
  33. package/dist/src/dto/accessGroupResponse.d.ts.map +1 -0
  34. package/dist/src/dto/accessGroupResponse.js +3 -0
  35. package/dist/src/dto/accessGroupResponse.js.map +1 -0
  36. package/dist/src/dto/chatResponse.d.ts +78 -0
  37. package/dist/src/dto/chatResponse.d.ts.map +1 -0
  38. package/dist/src/dto/chatResponse.js +45 -0
  39. package/dist/src/dto/chatResponse.js.map +1 -0
  40. package/dist/src/dto/userInfoResponse.d.ts +42 -0
  41. package/dist/src/dto/userInfoResponse.d.ts.map +1 -0
  42. package/dist/src/dto/userInfoResponse.js +3 -0
  43. package/dist/src/dto/userInfoResponse.js.map +1 -0
  44. package/dist/src/dto/workspacesResponse.d.ts +43 -0
  45. package/dist/src/dto/workspacesResponse.d.ts.map +1 -0
  46. package/dist/src/dto/workspacesResponse.js +3 -0
  47. package/dist/src/dto/workspacesResponse.js.map +1 -0
  48. package/dist/src/events.d.ts +17 -0
  49. package/dist/src/events.d.ts.map +1 -0
  50. package/dist/src/events.js +52 -0
  51. package/dist/src/events.js.map +1 -0
  52. package/dist/src/index.d.ts +58 -0
  53. package/dist/src/index.d.ts.map +1 -0
  54. package/dist/src/index.js +91 -0
  55. package/dist/src/index.js.map +1 -0
  56. package/dist/src/internal/app.impl.d.ts +28 -0
  57. package/dist/src/internal/app.impl.d.ts.map +1 -0
  58. package/dist/src/internal/app.impl.js +151 -0
  59. package/dist/src/internal/app.impl.js.map +1 -0
  60. package/dist/src/internal/appBuilder.impl.d.ts +27 -0
  61. package/dist/src/internal/appBuilder.impl.d.ts.map +1 -0
  62. package/dist/src/internal/appBuilder.impl.js +71 -0
  63. package/dist/src/internal/appBuilder.impl.js.map +1 -0
  64. package/dist/src/internal/createApp.impl.d.ts +4 -0
  65. package/dist/src/internal/createApp.impl.d.ts.map +1 -0
  66. package/dist/src/internal/createApp.impl.js +11 -0
  67. package/dist/src/internal/createApp.impl.js.map +1 -0
  68. package/dist/src/internal/registry.d.ts +66 -0
  69. package/dist/src/internal/registry.d.ts.map +1 -0
  70. package/dist/src/internal/registry.js +114 -0
  71. package/dist/src/internal/registry.js.map +1 -0
  72. package/dist/src/middleware.d.ts +5 -0
  73. package/dist/src/middleware.d.ts.map +1 -0
  74. package/dist/src/middleware.js +3 -0
  75. package/dist/src/middleware.js.map +1 -0
  76. package/dist/src/services/commandService.d.ts +18 -0
  77. package/dist/src/services/commandService.d.ts.map +1 -0
  78. package/dist/src/services/commandService.js +40 -0
  79. package/dist/src/services/commandService.js.map +1 -0
  80. package/dist/src/services/credentialService.d.ts +9 -0
  81. package/dist/src/services/credentialService.d.ts.map +1 -0
  82. package/dist/src/services/credentialService.js +26 -0
  83. package/dist/src/services/credentialService.js.map +1 -0
  84. package/dist/src/services/middlewareService.d.ts +9 -0
  85. package/dist/src/services/middlewareService.d.ts.map +1 -0
  86. package/dist/src/services/middlewareService.js +34 -0
  87. package/dist/src/services/middlewareService.js.map +1 -0
  88. package/dist/src/services/organizationService.d.ts +10 -0
  89. package/dist/src/services/organizationService.d.ts.map +1 -0
  90. package/dist/src/services/organizationService.js +19 -0
  91. package/dist/src/services/organizationService.js.map +1 -0
  92. package/dist/src/services/requestBuilder.d.ts +17 -0
  93. package/dist/src/services/requestBuilder.d.ts.map +1 -0
  94. package/dist/src/services/requestBuilder.js +104 -0
  95. package/dist/src/services/requestBuilder.js.map +1 -0
  96. package/dist/src/services/responseUtils.d.ts +6 -0
  97. package/dist/src/services/responseUtils.d.ts.map +1 -0
  98. package/dist/src/services/responseUtils.js +32 -0
  99. package/dist/src/services/responseUtils.js.map +1 -0
  100. package/dist/src/services/rpcService.d.ts +77 -0
  101. package/dist/src/services/rpcService.d.ts.map +1 -0
  102. package/dist/src/services/rpcService.js +125 -0
  103. package/dist/src/services/rpcService.js.map +1 -0
  104. package/dist/src/services/service.d.ts +21 -0
  105. package/dist/src/services/service.d.ts.map +1 -0
  106. package/dist/src/services/service.js +41 -0
  107. package/dist/src/services/service.js.map +1 -0
  108. package/dist/src/services/userProfileService.d.ts +8 -0
  109. package/dist/src/services/userProfileService.d.ts.map +1 -0
  110. package/dist/src/services/userProfileService.js +32 -0
  111. package/dist/src/services/userProfileService.js.map +1 -0
  112. package/dist/src/storages/chats/answer.d.ts +40 -0
  113. package/dist/src/storages/chats/answer.d.ts.map +1 -0
  114. package/dist/src/storages/chats/answer.impl.d.ts +24 -0
  115. package/dist/src/storages/chats/answer.impl.d.ts.map +1 -0
  116. package/dist/src/storages/chats/answer.impl.js +130 -0
  117. package/dist/src/storages/chats/answer.impl.js.map +1 -0
  118. package/dist/src/storages/chats/answer.js +14 -0
  119. package/dist/src/storages/chats/answer.js.map +1 -0
  120. package/dist/src/storages/chats/chat.d.ts +39 -0
  121. package/dist/src/storages/chats/chat.d.ts.map +1 -0
  122. package/dist/src/storages/chats/chat.impl.d.ts +24 -0
  123. package/dist/src/storages/chats/chat.impl.d.ts.map +1 -0
  124. package/dist/src/storages/chats/chat.impl.js +98 -0
  125. package/dist/src/storages/chats/chat.impl.js.map +1 -0
  126. package/dist/src/storages/chats/chat.js +12 -0
  127. package/dist/src/storages/chats/chat.js.map +1 -0
  128. package/dist/src/storages/chats/chats.d.ts +40 -0
  129. package/dist/src/storages/chats/chats.d.ts.map +1 -0
  130. package/dist/src/storages/chats/chats.impl.d.ts +18 -0
  131. package/dist/src/storages/chats/chats.impl.d.ts.map +1 -0
  132. package/dist/src/storages/chats/chats.impl.js +102 -0
  133. package/dist/src/storages/chats/chats.impl.js.map +1 -0
  134. package/dist/src/storages/chats/chats.js +16 -0
  135. package/dist/src/storages/chats/chats.js.map +1 -0
  136. package/dist/src/storages/files/file.d.ts +31 -0
  137. package/dist/src/storages/files/file.d.ts.map +1 -0
  138. package/dist/src/storages/files/file.impl.d.ts +21 -0
  139. package/dist/src/storages/files/file.impl.d.ts.map +1 -0
  140. package/dist/src/storages/files/file.impl.js +64 -0
  141. package/dist/src/storages/files/file.impl.js.map +1 -0
  142. package/dist/src/storages/files/file.js +11 -0
  143. package/dist/src/storages/files/file.js.map +1 -0
  144. package/dist/src/storages/files/files.d.ts +34 -0
  145. package/dist/src/storages/files/files.d.ts.map +1 -0
  146. package/dist/src/storages/files/files.impl.d.ts +22 -0
  147. package/dist/src/storages/files/files.impl.d.ts.map +1 -0
  148. package/dist/src/storages/files/files.impl.js +140 -0
  149. package/dist/src/storages/files/files.impl.js.map +1 -0
  150. package/dist/src/storages/files/files.js +20 -0
  151. package/dist/src/storages/files/files.js.map +1 -0
  152. package/dist/src/storages/files/filesPage.d.ts +28 -0
  153. package/dist/src/storages/files/filesPage.d.ts.map +1 -0
  154. package/dist/src/storages/files/filesPage.impl.d.ts +15 -0
  155. package/dist/src/storages/files/filesPage.impl.d.ts.map +1 -0
  156. package/dist/src/storages/files/filesPage.impl.js +38 -0
  157. package/dist/src/storages/files/filesPage.impl.js.map +1 -0
  158. package/dist/src/storages/files/filesPage.js +10 -0
  159. package/dist/src/storages/files/filesPage.js.map +1 -0
  160. package/dist/src/storages/groups/groups.d.ts +91 -0
  161. package/dist/src/storages/groups/groups.d.ts.map +1 -0
  162. package/dist/src/storages/groups/groups.impl.d.ts +61 -0
  163. package/dist/src/storages/groups/groups.impl.d.ts.map +1 -0
  164. package/dist/src/storages/groups/groups.impl.js +293 -0
  165. package/dist/src/storages/groups/groups.impl.js.map +1 -0
  166. package/dist/src/storages/groups/groups.js +26 -0
  167. package/dist/src/storages/groups/groups.js.map +1 -0
  168. package/dist/src/storages/organizations/organization.d.ts +54 -0
  169. package/dist/src/storages/organizations/organization.d.ts.map +1 -0
  170. package/dist/src/storages/organizations/organization.impl.d.ts +32 -0
  171. package/dist/src/storages/organizations/organization.impl.d.ts.map +1 -0
  172. package/dist/src/storages/organizations/organization.impl.js +120 -0
  173. package/dist/src/storages/organizations/organization.impl.js.map +1 -0
  174. package/dist/src/storages/organizations/organization.js +18 -0
  175. package/dist/src/storages/organizations/organization.js.map +1 -0
  176. package/dist/src/storages/organizations/organizations.d.ts +46 -0
  177. package/dist/src/storages/organizations/organizations.d.ts.map +1 -0
  178. package/dist/src/storages/organizations/organizations.impl.d.ts +38 -0
  179. package/dist/src/storages/organizations/organizations.impl.d.ts.map +1 -0
  180. package/dist/src/storages/organizations/organizations.impl.js +151 -0
  181. package/dist/src/storages/organizations/organizations.impl.js.map +1 -0
  182. package/dist/src/storages/organizations/organizations.js +20 -0
  183. package/dist/src/storages/organizations/organizations.js.map +1 -0
  184. package/dist/src/storages/user/userProfile.d.ts +32 -0
  185. package/dist/src/storages/user/userProfile.d.ts.map +1 -0
  186. package/dist/src/storages/user/userProfile.impl.d.ts +13 -0
  187. package/dist/src/storages/user/userProfile.impl.d.ts.map +1 -0
  188. package/dist/src/storages/user/userProfile.impl.js +51 -0
  189. package/dist/src/storages/user/userProfile.impl.js.map +1 -0
  190. package/dist/src/storages/user/userProfile.js +12 -0
  191. package/dist/src/storages/user/userProfile.js.map +1 -0
  192. package/dist/src/storages/workspaces/workspace.d.ts +44 -0
  193. package/dist/src/storages/workspaces/workspace.d.ts.map +1 -0
  194. package/dist/src/storages/workspaces/workspace.impl.d.ts +23 -0
  195. package/dist/src/storages/workspaces/workspace.impl.d.ts.map +1 -0
  196. package/dist/src/storages/workspaces/workspace.impl.js +98 -0
  197. package/dist/src/storages/workspaces/workspace.impl.js.map +1 -0
  198. package/dist/src/storages/workspaces/workspace.js +18 -0
  199. package/dist/src/storages/workspaces/workspace.js.map +1 -0
  200. package/dist/src/storages/workspaces/workspaces.d.ts +47 -0
  201. package/dist/src/storages/workspaces/workspaces.d.ts.map +1 -0
  202. package/dist/src/storages/workspaces/workspaces.impl.d.ts +33 -0
  203. package/dist/src/storages/workspaces/workspaces.impl.d.ts.map +1 -0
  204. package/dist/src/storages/workspaces/workspaces.impl.js +157 -0
  205. package/dist/src/storages/workspaces/workspaces.impl.js.map +1 -0
  206. package/dist/src/storages/workspaces/workspaces.js +19 -0
  207. package/dist/src/storages/workspaces/workspaces.js.map +1 -0
  208. package/dist/src/unitTest.d.ts +12 -0
  209. package/dist/src/unitTest.d.ts.map +1 -0
  210. package/dist/src/unitTest.js +44 -0
  211. package/dist/src/unitTest.js.map +1 -0
  212. package/index.d.ts +1 -0
  213. package/index.js +1 -0
  214. package/package.json +43 -4
  215. package/src/appBuilder.ts +6 -6
  216. package/src/commands/startCommandHandler.ts +2 -2
  217. package/src/context.ts +5 -4
  218. package/src/credentials.ts +29 -7
  219. package/src/{appSdk.ts → dataIslandApp.ts} +7 -7
  220. package/src/disposable.ts +20 -8
  221. package/src/dto/accessGroupResponse.ts +35 -0
  222. package/src/dto/chatResponse.ts +103 -0
  223. package/src/dto/userInfoResponse.ts +15 -3
  224. package/src/dto/workspacesResponse.ts +49 -0
  225. package/src/events.ts +13 -13
  226. package/src/index.ts +41 -20
  227. package/src/internal/app.impl.ts +28 -31
  228. package/src/internal/appBuilder.impl.ts +16 -16
  229. package/src/internal/createApp.impl.ts +5 -5
  230. package/src/internal/registry.ts +54 -6
  231. package/src/services/commandService.ts +3 -3
  232. package/src/services/credentialService.ts +3 -3
  233. package/src/services/middlewareService.ts +4 -4
  234. package/src/services/organizationService.ts +18 -116
  235. package/src/services/requestBuilder.ts +40 -15
  236. package/src/services/responseUtils.ts +32 -0
  237. package/src/services/rpcService.ts +28 -11
  238. package/src/services/service.ts +10 -8
  239. package/src/services/userProfileService.ts +18 -66
  240. package/src/storages/chats/answer.impl.ts +186 -0
  241. package/src/storages/chats/answer.ts +55 -0
  242. package/src/storages/chats/chat.impl.ts +126 -0
  243. package/src/storages/chats/chat.ts +49 -0
  244. package/src/storages/chats/chats.impl.ts +142 -0
  245. package/src/storages/chats/chats.ts +47 -0
  246. package/src/storages/files/file.impl.ts +87 -0
  247. package/src/storages/files/file.ts +40 -0
  248. package/src/storages/files/files.impl.ts +191 -0
  249. package/src/storages/files/files.ts +39 -0
  250. package/src/storages/files/filesPage.impl.ts +37 -0
  251. package/src/storages/files/filesPage.ts +33 -0
  252. package/src/storages/groups/groups.impl.ts +386 -0
  253. package/src/storages/groups/groups.ts +106 -0
  254. package/src/storages/organizations/organization.impl.ts +163 -0
  255. package/src/storages/organizations/organization.ts +67 -0
  256. package/src/storages/organizations/organizations.impl.ts +197 -0
  257. package/src/storages/{organizations.ts → organizations/organizations.ts} +8 -28
  258. package/src/storages/user/userProfile.impl.ts +56 -0
  259. package/src/storages/{userProfile.ts → user/userProfile.ts} +2 -2
  260. package/src/storages/workspaces/workspace.impl.ts +129 -0
  261. package/src/storages/workspaces/workspace.ts +54 -0
  262. package/src/storages/workspaces/workspaces.impl.ts +212 -0
  263. package/src/storages/workspaces/workspaces.ts +53 -0
  264. package/src/unitTest.ts +12 -1
  265. package/.browserslistrc +0 -5
  266. package/.editorconfig +0 -22
  267. package/.eslintrc.json +0 -44
  268. package/.github/workflows/publish-npm.yml +0 -28
  269. package/.prettierignore +0 -1
  270. package/.prettierrc +0 -11
  271. package/.yarnrc +0 -2
  272. package/babel.config.js +0 -6
  273. package/jest.config.ts +0 -199
  274. package/jest.setup.ts +0 -2
  275. package/src/services/organizationImpl.ts +0 -51
  276. package/src/services/organizationsImpl.ts +0 -55
  277. package/src/types.ts +0 -86
  278. package/test/commands.test.ts +0 -24
  279. package/test/disposable.test.ts +0 -39
  280. package/test/events.test.ts +0 -151
  281. package/test/index.test.ts +0 -163
  282. package/test/registry.test.ts +0 -44
  283. package/test/services.test.ts +0 -56
  284. package/test/setup.ts +0 -2
  285. package/test/unitTest.test.ts +0 -21
  286. 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
+ }