@neuralinnovations/dataisland-sdk 0.0.1-dev1 → 0.0.1-dev2
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/jest.config.ts +5 -5
- package/jest.setup.ts +2 -0
- package/package.json +2 -1
- package/src/appBuilder.ts +20 -1
- package/src/appSdk.ts +28 -9
- package/src/commands/startCommandHandler.ts +14 -0
- package/src/context.ts +31 -0
- package/src/credentials.ts +3 -3
- package/src/disposable.ts +1 -1
- package/src/dto/userInfoResponse.ts +37 -0
- package/src/events.ts +0 -4
- package/src/index.ts +9 -1
- package/src/internal/app.impl.ts +89 -21
- package/src/internal/appBuilder.impl.ts +28 -1
- package/src/middleware.ts +1 -1
- package/src/services/commandService.ts +44 -0
- package/src/services/middlewareService.ts +4 -2
- package/src/services/organizationImpl.ts +51 -0
- package/src/services/organizationService.ts +126 -0
- package/src/services/organizationsImpl.ts +55 -0
- package/src/services/requestBuilder.ts +102 -0
- package/src/services/rpcService.ts +111 -51
- package/src/services/service.ts +1 -1
- package/src/services/userProfileService.ts +86 -0
- package/src/storages/organizations.ts +76 -0
- package/src/storages/userProfile.ts +42 -0
- package/src/types.ts +6 -30
- package/src/unitTest.ts +42 -0
- package/test/commands.test.ts +24 -0
- package/test/index.test.ts +132 -52
- package/test/services.test.ts +56 -0
- package/test/setup.ts +2 -0
- package/test/unitTest.test.ts +21 -0
- package/src/internal/context.ts +0 -13
package/src/types.ts
CHANGED
@@ -1,21 +1,15 @@
|
|
1
|
-
import { type
|
1
|
+
import { type Event } from './events'
|
2
2
|
import { type Disposable } from './disposable'
|
3
|
+
import {
|
4
|
+
Organization,
|
5
|
+
OrganizationEvent,
|
6
|
+
OrganizationId
|
7
|
+
} from './storages/organizations'
|
3
8
|
|
4
|
-
export interface Collection<T> {
|
5
|
-
get collection(): T[]
|
6
|
-
}
|
7
|
-
|
8
|
-
export type OrganizationId = string
|
9
9
|
export type WorkspaceId = string
|
10
10
|
export type ChatId = string
|
11
11
|
export type FileId = string
|
12
12
|
|
13
|
-
export enum OrganizationEvent {
|
14
|
-
ADDED,
|
15
|
-
REMOVED,
|
16
|
-
UPDATED
|
17
|
-
}
|
18
|
-
|
19
13
|
export enum FileEvent {
|
20
14
|
ADDED,
|
21
15
|
REMOVED,
|
@@ -82,17 +76,6 @@ export interface Invites {
|
|
82
76
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
83
77
|
export interface Statistics {}
|
84
78
|
|
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
79
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
97
80
|
export interface Workspace {}
|
98
81
|
|
@@ -101,10 +84,3 @@ export interface Workspaces {
|
|
101
84
|
|
102
85
|
delete: (id: WorkspaceId) => Promise<void>
|
103
86
|
}
|
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
|
-
}
|
package/src/unitTest.ts
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
export enum UnitTest {
|
2
|
+
DO_NOTHING = 0,
|
3
|
+
DO_NOT_START = 1 << 0,
|
4
|
+
DO_NOT_PRINT_INITIALIZED_LOG = 1 << 1,
|
5
|
+
|
6
|
+
DEFAULT = DO_NOT_START | DO_NOT_PRINT_INITIALIZED_LOG
|
7
|
+
}
|
8
|
+
|
9
|
+
export type UnitTestProfileSyncAction = () => void
|
10
|
+
export type UnitTestProfileAsyncAction = () => Promise<void>
|
11
|
+
|
12
|
+
export class AppSdkUnitTest {
|
13
|
+
private static _stack: UnitTest[] = [UnitTest.DO_NOTHING]
|
14
|
+
|
15
|
+
public static get current(): UnitTest {
|
16
|
+
return this._stack[this._stack.length - 1]
|
17
|
+
}
|
18
|
+
|
19
|
+
public static async test(
|
20
|
+
unitTest: UnitTest = UnitTest.DEFAULT,
|
21
|
+
func: UnitTestProfileSyncAction | UnitTestProfileAsyncAction
|
22
|
+
): Promise<void> {
|
23
|
+
this._stack.push(unitTest)
|
24
|
+
if (func) {
|
25
|
+
const result = func()
|
26
|
+
if (result) {
|
27
|
+
await result
|
28
|
+
}
|
29
|
+
AppSdkUnitTest.end()
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
private static end(): void {
|
34
|
+
if (this._stack.length > 1) {
|
35
|
+
this._stack.pop()
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
export const isUnitTest = (mask: UnitTest): boolean => {
|
41
|
+
return (AppSdkUnitTest.current & mask) == mask
|
42
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { Command, CommandHandler } from '../src/services/commandService'
|
2
|
+
import { appSdk } from '../src'
|
3
|
+
import { UnitTest, AppSdkUnitTest } from '../src/unitTest'
|
4
|
+
|
5
|
+
class Cmd extends Command {
|
6
|
+
constructor(public readonly name: string = 'test') {
|
7
|
+
super()
|
8
|
+
}
|
9
|
+
}
|
10
|
+
|
11
|
+
class CmdHandler extends CommandHandler<Cmd> {
|
12
|
+
async execute(message: Cmd): Promise<void> {
|
13
|
+
expect(message.name).toBe('test-command')
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
test('Commands test', async () => {
|
18
|
+
await AppSdkUnitTest.test(UnitTest.DEFAULT, async () => {
|
19
|
+
const app = await appSdk('test-commands', async builder => {
|
20
|
+
builder.registerCommand(Cmd, context => new CmdHandler(context))
|
21
|
+
})
|
22
|
+
expect(app.context.execute(new Cmd('test-command'))).toBeDefined()
|
23
|
+
})
|
24
|
+
})
|
package/test/index.test.ts
CHANGED
@@ -1,15 +1,19 @@
|
|
1
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
|
-
|
8
|
+
BearerCredential
|
8
9
|
} from '../src'
|
9
10
|
import { MiddlewareService } from '../src/services/middlewareService'
|
10
11
|
import { CredentialService } from '../src/services/credentialService'
|
11
|
-
import { RpcService
|
12
|
+
import { RpcService } from '../src/services/rpcService'
|
12
13
|
import { AppBuilder } from '../src/appBuilder'
|
14
|
+
import { UnitTest, AppSdkUnitTest } from '../src/unitTest'
|
15
|
+
import { HOST, TOKEN } from './setup'
|
16
|
+
import { OrganizationImpl } from '../src/services/organizationImpl'
|
13
17
|
|
14
18
|
test('SDK_VERSION', () => {
|
15
19
|
expect(SDK_VERSION).toBe(version)
|
@@ -17,67 +21,143 @@ test('SDK_VERSION', () => {
|
|
17
21
|
|
18
22
|
test('Default SDK', async () => {
|
19
23
|
// default
|
20
|
-
const app = await appSdk()
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
+
const app = await appSdk(DEFAULT_NAME, async (builder: AppBuilder) => {
|
25
|
+
builder.useHost(HOST)
|
26
|
+
builder.useCredential(new BearerCredential(TOKEN))
|
27
|
+
})
|
28
|
+
expect(app).not.toBeUndefined()
|
29
|
+
})
|
30
|
+
|
31
|
+
test('Create and delete organization', async () => {
|
32
|
+
const randomName = `org-test-${Math.random().toString(16)}`
|
33
|
+
const app = await appSdk(randomName, async builder => {
|
34
|
+
builder.useHost(HOST)
|
35
|
+
builder.useCredential(new BearerCredential(TOKEN))
|
36
|
+
})
|
37
|
+
|
38
|
+
const initLength = app.organizations.collection.length
|
39
|
+
|
40
|
+
const org = await app.organizations.create(
|
41
|
+
randomName,
|
42
|
+
'this is a unitTest description'
|
43
|
+
)
|
44
|
+
|
45
|
+
// check organization
|
46
|
+
expect(org).not.toBeUndefined()
|
47
|
+
expect(org).not.toBeNull()
|
48
|
+
expect(org).toBeInstanceOf(OrganizationImpl)
|
49
|
+
|
50
|
+
expect(org.id).not.toBeUndefined()
|
51
|
+
expect(org.id).not.toBeNull()
|
52
|
+
expect(org.id.trim()).not.toBe('')
|
53
|
+
|
54
|
+
// check name
|
55
|
+
expect(org.name).not.toBeUndefined()
|
56
|
+
expect(org.name).not.toBeNull()
|
57
|
+
expect(org.name.trim()).not.toBe('')
|
58
|
+
|
59
|
+
// check description
|
60
|
+
expect(org.description).not.toBeUndefined()
|
61
|
+
expect(org.description).not.toBeNull()
|
62
|
+
expect(org.description.trim()).not.toBe('')
|
63
|
+
|
64
|
+
// check organizations
|
65
|
+
expect(app.organizations.get(org.id)).toBe(org)
|
66
|
+
expect(app.organizations.collection.length).toBe(initLength + 1)
|
67
|
+
|
68
|
+
await expect(app.organizations.delete(org.id)).resolves.not.toThrow()
|
69
|
+
expect((<OrganizationImpl>org).isDisposed).toBe(true)
|
70
|
+
expect(app.organizations.collection.length).toBe(initLength)
|
71
|
+
expect(app.organizations.tryGet(org.id)).toBeUndefined()
|
24
72
|
})
|
25
73
|
|
26
|
-
test('
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
74
|
+
test('SDK, middleware', async () => {
|
75
|
+
await AppSdkUnitTest.test(UnitTest.DEFAULT, async () => {
|
76
|
+
const app = await appSdk('test-settings', async (builder: AppBuilder) => {
|
77
|
+
builder.useHost('https://test.com')
|
78
|
+
builder.useAutomaticDataCollectionEnabled(false)
|
79
|
+
builder.useCredential(new BasicCredential('email', 'password'))
|
80
|
+
builder.registerMiddleware(async (req, next) => {
|
81
|
+
req.headers.set('X-Test', 'test')
|
82
|
+
return await next(req)
|
83
|
+
})
|
34
84
|
})
|
85
|
+
expect(app.name).toBe('test-settings')
|
86
|
+
expect(app.host).toBe('https://test.com')
|
87
|
+
expect(app.automaticDataCollectionEnabled).toBe(false)
|
35
88
|
})
|
36
|
-
expect(app.name).toBe('test')
|
37
|
-
expect(app.host).toBe('https://test.com')
|
38
|
-
expect(app.automaticDataCollectionEnabled).toBe(false)
|
39
89
|
})
|
40
90
|
|
41
91
|
test('SDK, services', async () => {
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
92
|
+
await AppSdkUnitTest.test(UnitTest.DEFAULT, async () => {
|
93
|
+
const app = await appSdk('test-sdk')
|
94
|
+
const middlewareService = app.resolve(MiddlewareService)
|
95
|
+
expect(middlewareService).not.toBeUndefined()
|
96
|
+
expect(app.resolve(MiddlewareService)).toBe(middlewareService)
|
97
|
+
expect(app.resolve(CredentialService)).not.toBeUndefined()
|
98
|
+
expect(app.resolve(RpcService)).not.toBeUndefined()
|
99
|
+
expect(app.resolve(RpcService)).toBeInstanceOf(RpcService)
|
100
|
+
})
|
49
101
|
})
|
50
102
|
|
51
103
|
test('SDK, middleware', async () => {
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
104
|
+
await AppSdkUnitTest.test(UnitTest.DEFAULT, async () => {
|
105
|
+
const app = await appSdk('test-middleware')
|
106
|
+
const middlewareService = app.resolve(MiddlewareService)
|
107
|
+
expect(middlewareService).not.toBeUndefined()
|
108
|
+
expect(app.resolve(MiddlewareService)).toBe(middlewareService)
|
109
|
+
expect(app.resolve(CredentialService)).not.toBeUndefined()
|
110
|
+
|
111
|
+
const response = await middlewareService?.process(
|
112
|
+
new Request('http://localhost:8080'),
|
113
|
+
async (req: Request): Promise<Response> => {
|
114
|
+
const headerXTest = req.headers.get('Custom-Test-Header')
|
115
|
+
expect(headerXTest).toBeNull()
|
116
|
+
return new Response('', { status: 200 })
|
117
|
+
}
|
118
|
+
)
|
119
|
+
expect(response).not.toBeUndefined()
|
120
|
+
expect(response?.status).toBe(200)
|
121
|
+
|
122
|
+
middlewareService?.useMiddleware(async (req, next) => {
|
123
|
+
req.headers.set('X-Test', 'test-value')
|
124
|
+
return await next(req)
|
125
|
+
})
|
68
126
|
|
69
|
-
|
70
|
-
|
71
|
-
|
127
|
+
const response2 = await middlewareService?.process(
|
128
|
+
new Request('https://localhost:8080'),
|
129
|
+
async (req: Request): Promise<Response> => {
|
130
|
+
expect(req.headers.get('X-Test')).toBe('test-value')
|
131
|
+
return new Response('', { status: 400 })
|
132
|
+
}
|
133
|
+
)
|
134
|
+
expect(response2).not.toBeUndefined()
|
135
|
+
expect(response2?.status).toBe(400)
|
72
136
|
})
|
137
|
+
})
|
73
138
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
139
|
+
test('SDK, it is impossible to setup the same application', async () => {
|
140
|
+
await AppSdkUnitTest.test(UnitTest.DEFAULT, async () => {
|
141
|
+
// this test is not stable if you run all tests at once
|
142
|
+
// because the app is cached all app instances
|
143
|
+
// we use a random identifier every time
|
144
|
+
const testId = Math.random().toString(16)
|
145
|
+
const promise = appSdk(`test-setup-${testId}`).then(() => {})
|
146
|
+
await expect(
|
147
|
+
appSdk(`test-setup-${testId}`, async () => {})
|
148
|
+
).rejects.toThrow()
|
149
|
+
await promise
|
150
|
+
})
|
151
|
+
})
|
152
|
+
|
153
|
+
test('SDK, setup and get this app', async () => {
|
154
|
+
await AppSdkUnitTest.test(UnitTest.DEFAULT, async () => {
|
155
|
+
// this test is not stable if you run all tests at once
|
156
|
+
// because the app is cached all app instances
|
157
|
+
// we use a random identifier every time
|
158
|
+
const testId = Math.random().toString(16)
|
159
|
+
const promise = appSdk(`test-get-${testId}`).then(() => {})
|
160
|
+
await expect(appSdk(`test-get-${testId}`)).resolves.toBeInstanceOf(AppSdk)
|
161
|
+
await promise
|
162
|
+
})
|
83
163
|
})
|
@@ -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
|
+
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
|
+
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,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/src/internal/context.ts
DELETED
@@ -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
|
-
}
|