@neuralinnovations/dataisland-sdk 0.0.1-dev1 → 0.0.1-dev3

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 (58) hide show
  1. package/.editorconfig +4 -1
  2. package/.eslintrc.json +1 -1
  3. package/jest.config.ts +4 -4
  4. package/jest.setup.ts +2 -0
  5. package/package.json +4 -2
  6. package/src/appBuilder.ts +24 -5
  7. package/src/appSdk.ts +31 -12
  8. package/src/commands/startCommandHandler.ts +14 -0
  9. package/src/context.ts +31 -0
  10. package/src/credentials.ts +31 -9
  11. package/src/disposable.ts +2 -2
  12. package/src/dto/accessGroupResponse.ts +35 -0
  13. package/src/dto/chatResponse.ts +104 -0
  14. package/src/dto/userInfoResponse.ts +47 -0
  15. package/src/dto/workspacesResponse.ts +49 -0
  16. package/src/events.ts +1 -5
  17. package/src/index.ts +17 -11
  18. package/src/internal/app.impl.ts +98 -30
  19. package/src/internal/appBuilder.impl.ts +39 -12
  20. package/src/internal/createApp.impl.ts +3 -3
  21. package/src/middleware.ts +1 -1
  22. package/src/services/commandService.ts +44 -0
  23. package/src/services/credentialService.ts +3 -3
  24. package/src/services/middlewareService.ts +7 -5
  25. package/src/services/organizationService.ts +28 -0
  26. package/src/services/requestBuilder.ts +102 -0
  27. package/src/services/responseUtils.ts +32 -0
  28. package/src/services/rpcService.ts +113 -53
  29. package/src/services/service.ts +3 -3
  30. package/src/services/userProfileService.ts +38 -0
  31. package/src/storages/chat.ts +37 -0
  32. package/src/storages/file.impl.ts +68 -0
  33. package/src/storages/files.impl.ts +192 -0
  34. package/src/storages/files.ts +67 -0
  35. package/src/storages/groups.impl.ts +337 -0
  36. package/src/storages/groups.ts +43 -0
  37. package/src/storages/organization.impl.ts +68 -0
  38. package/src/storages/organization.ts +33 -0
  39. package/src/storages/organizations.impl.ts +191 -0
  40. package/src/storages/organizations.ts +56 -0
  41. package/src/storages/userProfile.impl.ts +56 -0
  42. package/src/storages/userProfile.ts +42 -0
  43. package/src/storages/workspace.impl.ts +109 -0
  44. package/src/storages/workspace.ts +43 -0
  45. package/src/storages/workspaces.impl.ts +212 -0
  46. package/src/storages/workspaces.ts +53 -0
  47. package/src/unitTest.ts +42 -0
  48. package/test/commands.test.ts +24 -0
  49. package/test/disposable.test.ts +3 -3
  50. package/test/events.test.ts +4 -4
  51. package/test/index.test.ts +204 -62
  52. package/test/registry.test.ts +8 -8
  53. package/test/services.test.ts +56 -0
  54. package/test/setup.ts +2 -0
  55. package/test/unitTest.test.ts +21 -0
  56. package/test_file.pdf +0 -0
  57. package/src/internal/context.ts +0 -13
  58. package/src/types.ts +0 -110
@@ -1,83 +1,225 @@
1
- import { version } from '../package.json'
1
+ import { version } from "../package.json"
2
2
  import {
3
+ AppSdk,
3
4
  BasicCredential,
4
5
  appSdk,
5
6
  SDK_VERSION,
6
7
  DEFAULT_NAME,
7
- DEFAULT_HOST
8
- } from '../src'
9
- import { MiddlewareService } from '../src/services/middlewareService'
10
- import { CredentialService } from '../src/services/credentialService'
11
- import { RpcService, RpcServiceImpl } from '../src/services/rpcService'
12
- import { AppBuilder } from '../src/appBuilder'
13
-
14
- test('SDK_VERSION', () => {
8
+ DebugCredential
9
+ } from "../src"
10
+ import { MiddlewareService } from "../src/services/middlewareService"
11
+ import { CredentialService } from "../src/services/credentialService"
12
+ import { RpcService } from "../src/services/rpcService"
13
+ import { AppBuilder } from "../src/appBuilder"
14
+ import { UnitTest, AppSdkUnitTest } from "../src/unitTest"
15
+ import { HOST, TOKEN } from "./setup"
16
+ import { OrganizationImpl } from "../src/storages/organization.impl"
17
+ import * as fs from "fs"
18
+
19
+ test("SDK_VERSION", () => {
15
20
  expect(SDK_VERSION).toBe(version)
16
21
  })
17
22
 
18
- test('Default SDK', async () => {
23
+ test("Default SDK", async () => {
19
24
  // default
20
- const app = await appSdk()
21
- expect(app.name).toBe(DEFAULT_NAME)
22
- expect(app.host).toBe(DEFAULT_HOST)
23
- expect(app.automaticDataCollectionEnabled).toBe(true)
25
+ const app = await appSdk(DEFAULT_NAME, async (builder: AppBuilder) => {
26
+ builder.useHost(HOST)
27
+ builder.useCredential(new DebugCredential(TOKEN))
28
+ })
29
+ expect(app).not.toBeUndefined()
24
30
  })
25
31
 
26
- test('Custom SDK settings', async () => {
27
- const app = await appSdk('test', async (builder: AppBuilder) => {
28
- builder.useHost('https://test.com')
29
- builder.useAutomaticDataCollectionEnabled(false)
30
- builder.useCredential(new BasicCredential('email', 'password'))
31
- builder.addMiddleware(async (req, next) => {
32
- req.headers.set('X-Test', 'test')
33
- await next(req)
32
+ test("Create and delete organization, create and delete workspace", async () => {
33
+ const randomName = `org-test-${Math.random().toString(16)}`
34
+ const app = await appSdk(randomName, async builder => {
35
+ builder.useHost(HOST)
36
+ builder.useCredential(new DebugCredential(TOKEN))
37
+ })
38
+
39
+ const initLength = app.organizations.collection.length
40
+
41
+ const org = await app.organizations.create(
42
+ randomName,
43
+ "this is a unitTest description"
44
+ )
45
+
46
+ // check organization
47
+ expect(org).not.toBeUndefined()
48
+ expect(org).not.toBeNull()
49
+ expect(org).toBeInstanceOf(OrganizationImpl)
50
+
51
+ expect(org.id).not.toBeUndefined()
52
+ expect(org.id).not.toBeNull()
53
+ expect(org.id.trim()).not.toBe("")
54
+
55
+ // check name
56
+ expect(org.name).not.toBeUndefined()
57
+ expect(org.name).not.toBeNull()
58
+ expect(org.name.trim()).not.toBe("")
59
+
60
+ // check description
61
+ expect(org.description).not.toBeUndefined()
62
+ expect(org.description).not.toBeNull()
63
+ expect(org.description.trim()).not.toBe("")
64
+
65
+ // check organizations
66
+ expect(app.organizations.get(org.id)).toBe(org)
67
+ expect(app.organizations.tryGet(org.id)).toBe(org)
68
+ expect(app.organizations.collection.length).toBe(initLength + 1)
69
+
70
+ const initWorkspacesLength = org.workspaces.collection.length
71
+
72
+ const wsPromise = org.workspaces.create(
73
+ "test-workspace",
74
+ "test-workspace-description"
75
+ )
76
+ await expect(wsPromise).resolves.not.toThrow()
77
+ const ws = await wsPromise
78
+ expect(ws).not.toBeUndefined()
79
+ expect(ws).not.toBeNull()
80
+ expect(ws.name).toBe("test-workspace")
81
+ expect(ws.description).toBe("test-workspace-description")
82
+ expect(app.organizations.get(org.id).workspaces.collection.length).toBe(
83
+ initWorkspacesLength + 1
84
+ )
85
+ expect(org.workspaces.collection.length).toBe(initWorkspacesLength + 1)
86
+ expect(org.workspaces.get(ws.id)).toBe(ws)
87
+ expect(org.workspaces.tryGet(ws.id)).toBe(ws)
88
+ expect(org.workspaces.contains(ws.id)).toBe(true)
89
+
90
+ const buffer = fs.readFileSync("test_file.pdf")
91
+ const file_obj = new File([new Uint8Array(buffer)], "test_file.pdf", {
92
+ type: "text/plain"
93
+ })
94
+
95
+ const filePromise = ws.files.upload(file_obj)
96
+ await expect(filePromise).resolves.not.toThrow()
97
+ const file = await filePromise
98
+
99
+ expect(file).not.toBeUndefined()
100
+ expect(file).not.toBeNull()
101
+ expect(file.name).toBe("test_file.pdf")
102
+
103
+ let status = await file.status()
104
+
105
+ expect(status).not.toBeUndefined()
106
+ expect(status).not.toBeNull()
107
+ expect(status.file_id).toBe(file.id)
108
+ expect(status.file_parts_count).toBeGreaterThan(status.completed_parts_count)
109
+
110
+ while (
111
+ status.success == true &&
112
+ status.completed_parts_count !== status.file_parts_count
113
+ ) {
114
+ await new Promise(r => setTimeout(r, 1000))
115
+ status = await file.status()
116
+ }
117
+
118
+ const queryPromise = ws.files.query("", 0, 20)
119
+ await expect(queryPromise).resolves.not.toThrow()
120
+ const filePage = await queryPromise
121
+ expect(filePage).not.toBeUndefined()
122
+ expect(filePage).not.toBeNull()
123
+ expect(filePage.files.length).toBe(1)
124
+ expect(filePage.pages).toBe(1)
125
+
126
+ await expect(ws.files.delete(file.id)).resolves.not.toThrow()
127
+
128
+ await expect(org.workspaces.delete(ws.id)).resolves.not.toThrow()
129
+
130
+ await expect(app.organizations.delete(org.id)).resolves.not.toThrow()
131
+ expect((<OrganizationImpl>org).isDisposed).toBe(true)
132
+ expect(app.organizations.collection.length).toBe(initLength)
133
+ expect(app.organizations.tryGet(org.id)).toBeUndefined()
134
+ })
135
+
136
+ test("SDK, middleware", async () => {
137
+ await AppSdkUnitTest.test(UnitTest.DEFAULT, async () => {
138
+ const app = await appSdk("test-settings", async (builder: AppBuilder) => {
139
+ builder.useHost("https://test.com")
140
+ builder.useAutomaticDataCollectionEnabled(false)
141
+ builder.useCredential(new BasicCredential("email", "password"))
142
+ builder.registerMiddleware(async (req, next) => {
143
+ req.headers.set("X-Test", "test")
144
+ return await next(req)
145
+ })
34
146
  })
147
+ expect(app.name).toBe("test-settings")
148
+ expect(app.host).toBe("https://test.com")
149
+ expect(app.automaticDataCollectionEnabled).toBe(false)
35
150
  })
36
- expect(app.name).toBe('test')
37
- expect(app.host).toBe('https://test.com')
38
- expect(app.automaticDataCollectionEnabled).toBe(false)
39
151
  })
40
152
 
41
- test('SDK, services', async () => {
42
- const app = await appSdk('test')
43
- const middlewareService = app.resolve(MiddlewareService)
44
- expect(middlewareService).not.toBeUndefined()
45
- expect(app.resolve(MiddlewareService)).toBe(middlewareService)
46
- expect(app.resolve(CredentialService)).not.toBeUndefined()
47
- expect(app.resolve(RpcService)).not.toBeUndefined()
48
- expect(app.resolve(RpcService)).toBeInstanceOf(RpcServiceImpl)
153
+ test("SDK, services", async () => {
154
+ await AppSdkUnitTest.test(UnitTest.DEFAULT, async () => {
155
+ const app = await appSdk("test-sdk")
156
+ const middlewareService = app.resolve(MiddlewareService)
157
+ expect(middlewareService).not.toBeUndefined()
158
+ expect(app.resolve(MiddlewareService)).toBe(middlewareService)
159
+ expect(app.resolve(CredentialService)).not.toBeUndefined()
160
+ expect(app.resolve(RpcService)).not.toBeUndefined()
161
+ expect(app.resolve(RpcService)).toBeInstanceOf(RpcService)
162
+ })
49
163
  })
50
164
 
51
- test('SDK, middleware', async () => {
52
- const app = await appSdk('test')
53
- const middlewareService = app.resolve(MiddlewareService)
54
- expect(middlewareService).not.toBeUndefined()
55
- expect(app.resolve(MiddlewareService)).toBe(middlewareService)
56
- expect(app.resolve(CredentialService)).not.toBeUndefined()
57
-
58
- const response = await middlewareService?.process(
59
- new Request('http://localhost:8080'),
60
- async (req: Request): Promise<Response> => {
61
- const headerXTest = req.headers.get('Custom-Test-Header')
62
- expect(headerXTest).toBeNull()
63
- return new Response('', { status: 200 })
64
- }
65
- )
66
- expect(response).not.toBeUndefined()
67
- expect(response?.status).toBe(200)
165
+ test("SDK, middleware", async () => {
166
+ await AppSdkUnitTest.test(UnitTest.DEFAULT, async () => {
167
+ const app = await appSdk("test-middleware")
168
+ const middlewareService = app.resolve(MiddlewareService)
169
+ expect(middlewareService).not.toBeUndefined()
170
+ expect(app.resolve(MiddlewareService)).toBe(middlewareService)
171
+ expect(app.resolve(CredentialService)).not.toBeUndefined()
68
172
 
69
- middlewareService?.useMiddleware(async (req, next) => {
70
- req.headers.set('X-Test', 'test-value')
71
- await next(req)
173
+ const response = await middlewareService?.process(
174
+ new Request("http://localhost:8080"),
175
+ async (req: Request): Promise<Response> => {
176
+ const headerXTest = req.headers.get("Custom-Test-Header")
177
+ expect(headerXTest).toBeNull()
178
+ return new Response("", { status: 200 })
179
+ }
180
+ )
181
+ expect(response).not.toBeUndefined()
182
+ expect(response?.status).toBe(200)
183
+
184
+ middlewareService?.useMiddleware(async (req, next) => {
185
+ req.headers.set("X-Test", "test-value")
186
+ return await next(req)
187
+ })
188
+
189
+ const response2 = await middlewareService?.process(
190
+ new Request("https://localhost:8080"),
191
+ async (req: Request): Promise<Response> => {
192
+ expect(req.headers.get("X-Test")).toBe("test-value")
193
+ return new Response("", { status: 400 })
194
+ }
195
+ )
196
+ expect(response2).not.toBeUndefined()
197
+ expect(response2?.status).toBe(400)
72
198
  })
199
+ })
73
200
 
74
- const response2 = await middlewareService?.process(
75
- new Request('https://localhost:8080'),
76
- async (req: Request): Promise<Response> => {
77
- expect(req.headers.get('X-Test')).toBe('test-value')
78
- return new Response('', { status: 400 })
79
- }
80
- )
81
- expect(response2).not.toBeUndefined()
82
- expect(response2?.status).toBe(400)
201
+ test("SDK, it is impossible to setup the same application", async () => {
202
+ await AppSdkUnitTest.test(UnitTest.DEFAULT, async () => {
203
+ // this test is not stable if you run all tests at once
204
+ // because the app is cached all app instances
205
+ // we use a random identifier every time
206
+ const testId = Math.random().toString(16)
207
+ const promise = appSdk(`test-setup-${testId}`).then(() => {})
208
+ await expect(
209
+ appSdk(`test-setup-${testId}`, async () => {})
210
+ ).rejects.toThrow()
211
+ await promise
212
+ })
213
+ })
214
+
215
+ test("SDK, setup and get this app", async () => {
216
+ await AppSdkUnitTest.test(UnitTest.DEFAULT, async () => {
217
+ // this test is not stable if you run all tests at once
218
+ // because the app is cached all app instances
219
+ // we use a random identifier every time
220
+ const testId = Math.random().toString(16)
221
+ const promise = appSdk(`test-get-${testId}`).then(() => {})
222
+ await expect(appSdk(`test-get-${testId}`)).resolves.toBeInstanceOf(AppSdk)
223
+ await promise
224
+ })
83
225
  })
@@ -1,13 +1,13 @@
1
- import { Registry } from '../src/internal/registry'
1
+ import { Registry } from "../src/internal/registry"
2
2
 
3
3
  class TestClass {
4
4
  constructor(public readonly value: string) {}
5
5
  }
6
6
 
7
- test('Registry, test factory', () => {
7
+ test("Registry, test factory", () => {
8
8
  const registry = new Registry()
9
9
 
10
- const item = new TestClass('test1')
10
+ const item = new TestClass("test1")
11
11
  registry.map(TestClass).asValue(item)
12
12
  expect(registry.get(TestClass)).toBe(item)
13
13
 
@@ -22,22 +22,22 @@ test('Registry, test factory', () => {
22
22
  expect(registry.get(TestClass)).not.toBe(item)
23
23
  expect(registry.get(TestClass)).not.toBe(registry.get(TestClass))
24
24
 
25
- expect(registry.get(TestClass)?.value).toBe('test_5')
25
+ expect(registry.get(TestClass)?.value).toBe("test_5")
26
26
  })
27
27
 
28
- test('Registry, test value', () => {
28
+ test("Registry, test value", () => {
29
29
  const registry = new Registry()
30
30
 
31
- const item = new TestClass('test1')
31
+ const item = new TestClass("test1")
32
32
  registry.map(TestClass).asValue(item)
33
33
  expect(registry.get(TestClass)).toBeInstanceOf(TestClass)
34
34
  expect(registry.get(TestClass)).toBe(item)
35
35
  })
36
36
 
37
- test('Registry, test singleton', () => {
37
+ test("Registry, test singleton", () => {
38
38
  const registry = new Registry()
39
39
 
40
- registry.map(TestClass).asSingleton(() => new TestClass('test1'))
40
+ registry.map(TestClass).asSingleton(() => new TestClass("test1"))
41
41
  const singleton = registry.get(TestClass)
42
42
  expect(singleton).toBeInstanceOf(TestClass)
43
43
  expect(singleton).toBe(registry.get(TestClass))
@@ -0,0 +1,56 @@
1
+ import { appSdk, BasicCredential, DefaultCredential } from "../src"
2
+ import { CredentialService } from "../src/services/credentialService"
3
+ import { MiddlewareService } from "../src/services/middlewareService"
4
+ import { UnitTest, AppSdkUnitTest } from "../src/unitTest"
5
+
6
+ test("CredentialService", async () => {
7
+ await AppSdkUnitTest.test(UnitTest.DEFAULT, async () => {
8
+ const app = await appSdk("test-services", async builder => {
9
+ builder.env.unitTest = UnitTest.DO_NOT_START
10
+ })
11
+ const credentialService = app.resolve(CredentialService)
12
+ expect(credentialService).not.toBeUndefined()
13
+ expect(app.resolve(CredentialService)).toBe(credentialService)
14
+ expect(app.resolve(CredentialService)).toBeInstanceOf(CredentialService)
15
+ expect(app.credential).not.toBeUndefined()
16
+
17
+ const credential = new BasicCredential("email", "password")
18
+ app.credential = credential
19
+ expect(app.credential).toBe(credential)
20
+ expect(credentialService?.credential).toBe(credential)
21
+
22
+ const middleware = app.resolve(MiddlewareService) as MiddlewareService
23
+ const emailPasswordDisposable = middleware.useMiddleware(
24
+ async (req, next) => {
25
+ expect(req.headers.get("Authorization")).toBe("Basic email:password")
26
+ return await next(req)
27
+ }
28
+ )
29
+ expect(emailPasswordDisposable).not.toBeUndefined()
30
+ await middleware.process(
31
+ new Request("https://localhost:8080"),
32
+ async () => {
33
+ return new Response("", { status: 200 })
34
+ }
35
+ )
36
+ emailPasswordDisposable?.dispose()
37
+
38
+ const credential2 = new DefaultCredential()
39
+ app.credential = credential2
40
+ expect(app.credential).toBe(credential2)
41
+ expect(credentialService?.credential).toBe(credential2)
42
+
43
+ const defaultDisposable = middleware.useMiddleware(async (req, next) => {
44
+ expect(req.headers.get("Authorization")).toBeNull()
45
+ return await next(req)
46
+ })
47
+ expect(defaultDisposable).not.toBeUndefined()
48
+ await middleware.process(
49
+ new Request("https://localhost:8080"),
50
+ async () => {
51
+ return new Response("", { status: 200 })
52
+ }
53
+ )
54
+ defaultDisposable?.dispose()
55
+ })
56
+ })
package/test/setup.ts ADDED
@@ -0,0 +1,2 @@
1
+ export const HOST = <string>process.env.HOST
2
+ export const TOKEN = <string>process.env.TOKEN
@@ -0,0 +1,21 @@
1
+ import { AppSdkUnitTest, UnitTest } from "../src/unitTest"
2
+
3
+ test("SDK, unitTest", async () => {
4
+ expect(AppSdkUnitTest.current).toBe(UnitTest.DO_NOTHING)
5
+ expect(
6
+ await AppSdkUnitTest.test(UnitTest.DO_NOT_PRINT_INITIALIZED_LOG, () => {
7
+ expect(AppSdkUnitTest.current).toBe(UnitTest.DO_NOT_PRINT_INITIALIZED_LOG)
8
+ })
9
+ )
10
+ expect(
11
+ await AppSdkUnitTest.test(
12
+ UnitTest.DO_NOT_PRINT_INITIALIZED_LOG,
13
+ async () => {
14
+ expect(AppSdkUnitTest.current).toBe(
15
+ UnitTest.DO_NOT_PRINT_INITIALIZED_LOG
16
+ )
17
+ }
18
+ )
19
+ )
20
+ expect(AppSdkUnitTest.current).toBe(UnitTest.DO_NOTHING)
21
+ })
package/test_file.pdf ADDED
Binary file
@@ -1,13 +0,0 @@
1
- import { type Constructor, type Registry } from './registry'
2
- import { type Lifetime } from '../disposable'
3
-
4
- export class Context {
5
- constructor(
6
- private readonly registry: Registry,
7
- public readonly lifetime: Lifetime
8
- ) {}
9
-
10
- resolve<T>(type: Constructor<T>): T | undefined {
11
- return this.registry.get(type)
12
- }
13
- }
package/src/types.ts DELETED
@@ -1,110 +0,0 @@
1
- import { type Events, type Event } from './events'
2
- import { type Disposable } from './disposable'
3
-
4
- export interface Collection<T> {
5
- get collection(): T[]
6
- }
7
-
8
- export type OrganizationId = string
9
- export type WorkspaceId = string
10
- export type ChatId = string
11
- export type FileId = string
12
-
13
- export enum OrganizationEvent {
14
- ADDED,
15
- REMOVED,
16
- UPDATED
17
- }
18
-
19
- export enum FileEvent {
20
- ADDED,
21
- REMOVED,
22
- UPDATED
23
- }
24
-
25
- export enum ChatEvent {
26
- ADDED,
27
- REMOVED,
28
- UPDATED
29
- }
30
-
31
- export enum ChatMessageEvent {
32
- ADDED,
33
- REMOVED,
34
- UPDATED
35
- }
36
-
37
- export interface File {
38
- id: FileId
39
- name: string
40
-
41
- download: () => Promise<void>
42
- }
43
-
44
- export interface Files {
45
- files: File[]
46
- on: (callback: (event: Event<FileEvent, File>) => void) => Disposable
47
- fetch: () => Promise<void>
48
- upload: (path: string, name: string) => Promise<File>
49
- }
50
-
51
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
52
- export interface ChatMessage {}
53
-
54
- export interface Chat {
55
- id: ChatId
56
- name: string
57
- on: (
58
- callback: (event: Event<ChatMessageEvent, ChatMessage>) => void
59
- ) => Disposable
60
- messages: ChatMessage[]
61
- fetch: () => Promise<void>
62
- subscribe: () => void
63
- unsubscribe: () => void
64
- }
65
-
66
- export interface Chats {
67
- chats: Chat[]
68
- newChat: (name: string) => Promise<Chat>
69
- on: (callback: (event: Event<ChatEvent, Chat>) => void) => Disposable
70
- fetch: () => Promise<void>
71
- }
72
-
73
- export interface Invites {
74
- invite: (email: string) => Promise<void>
75
- accept: (id: OrganizationId) => Promise<void>
76
- decline: (id: OrganizationId) => Promise<void>
77
- on: (
78
- callback: (organization: Event<OrganizationEvent, Organization>) => void
79
- ) => Disposable
80
- }
81
-
82
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
83
- export interface Statistics {}
84
-
85
- export interface Organization {
86
- name: string
87
- description: string
88
- id: OrganizationId
89
- chats: Chats
90
- files: Files
91
- invites: Invites
92
- statistics: Statistics
93
- workspaces: Workspaces
94
- }
95
-
96
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
97
- export interface Workspace {}
98
-
99
- export interface Workspaces {
100
- newWorkspace: (name: string) => Promise<Workspace>
101
-
102
- delete: (id: WorkspaceId) => Promise<void>
103
- }
104
-
105
- export interface Organizations
106
- extends Events<OrganizationEvent, Organization>,
107
- Collection<Organization> {
108
- create: (name: string) => Promise<Organization>
109
- delete: (id: OrganizationId) => Promise<void>
110
- }