@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
package/.editorconfig CHANGED
@@ -18,5 +18,8 @@ indent_style = space
18
18
  indent_size = 2
19
19
  ij_javascript_use_semicolon_after_statement = false
20
20
  ij_typescript_use_semicolon_after_statement = false
21
+ ij_typescript_use_double_quotes = true
22
+ ij_javascript_use_double_quotes = true
23
+
21
24
  # Not currently supported by vscode, but is supported others, e.g. vim.
22
- max_line_length = 80
25
+ max_line_length = 80
package/.eslintrc.json CHANGED
@@ -34,7 +34,7 @@
34
34
  ],
35
35
  "quotes": [
36
36
  "error",
37
- "single"
37
+ "double"
38
38
  ],
39
39
  "semi": [
40
40
  "error",
package/jest.config.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * https://jestjs.io/docs/configuration
4
4
  */
5
5
 
6
- import type {Config} from 'jest';
6
+ import type { Config } from "jest"
7
7
 
8
8
  const config: Config = {
9
9
  // All imported modules in your tests should be mocked automatically
@@ -134,7 +134,7 @@ const config: Config = {
134
134
  // runner: "jest-runner",
135
135
 
136
136
  // The paths to modules that run some code to configure or set up the testing environment before each test
137
- // setupFiles: [],
137
+ setupFiles: ["./jest.setup.ts"]
138
138
 
139
139
  // A list of paths to modules that run some code to configure or set up the testing framework before each test
140
140
  // setupFilesAfterEnv: [],
@@ -194,6 +194,6 @@ const config: Config = {
194
194
 
195
195
  // Whether to use watchman for file crawling
196
196
  // watchman: true,
197
- };
197
+ }
198
198
 
199
- export default config;
199
+ export default config
package/jest.setup.ts ADDED
@@ -0,0 +1,2 @@
1
+ import * as dotenv from "dotenv"
2
+ dotenv.config({ path: ".env.test" })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neuralinnovations/dataisland-sdk",
3
- "version": "0.0.1-dev1",
3
+ "version": "0.0.1-dev3",
4
4
  "description": "SDK for DataIsland project",
5
5
  "licenses": [
6
6
  {
@@ -14,7 +14,8 @@
14
14
  "scripts": {
15
15
  "build": "tsc",
16
16
  "test": "jest",
17
- "lint": "eslint --ext .ts,.tsx src"
17
+ "lint": "eslint --ext .ts,.tsx src test",
18
+ "lint:fix": "eslint --fix --ext .ts,.tsx src test"
18
19
  },
19
20
  "author": "Neural Innovations LTD",
20
21
  "license": "Apache-2.0",
@@ -55,6 +56,7 @@
55
56
  "yargs": "17.7.2"
56
57
  },
57
58
  "dependencies": {
59
+ "dotenv": "^16.3.2",
58
60
  "jsdom": "^23.2.0"
59
61
  }
60
62
  }
package/src/appBuilder.ts CHANGED
@@ -1,16 +1,23 @@
1
- import type { Middleware } from './middleware'
2
- import type { CredentialBase } from './credentials'
3
- import type { Service, ServiceContext } from './services/service'
4
- import type { Constructor } from './internal/registry'
1
+ import type { Middleware } from "./middleware"
2
+ import type { CredentialBase } from "./credentials"
3
+ import type { Service, ServiceContext } from "./services/service"
4
+ import type { Constructor } from "./internal/registry"
5
+ import { CommandHandler, Command } from "./services/commandService"
6
+ import { Context } from "./context"
5
7
 
6
8
  /**
7
9
  * DataIsland App builder.
8
10
  */
9
11
  export abstract class AppBuilder {
12
+ /**
13
+ * Set custom data.
14
+ */
15
+ abstract get env(): Record<string, any>
16
+
10
17
  /**
11
18
  * Add a middleware to the app.
12
19
  */
13
- abstract addMiddleware(middleware: Middleware): AppBuilder
20
+ abstract registerMiddleware(middleware: Middleware): AppBuilder
14
21
 
15
22
  /**
16
23
  * Host of the app.
@@ -36,4 +43,16 @@ export abstract class AppBuilder {
36
43
  type: Constructor<T>,
37
44
  factory: (context: ServiceContext) => T
38
45
  ): AppBuilder
46
+
47
+ /**
48
+ * Register a command to the app.
49
+ * @param messageType
50
+ * @param commandFactory
51
+ */
52
+ abstract registerCommand<T extends Command>(
53
+ messageType: Constructor<T>,
54
+ commandFactory:
55
+ | ((context: Context) => CommandHandler<T>)
56
+ | ((context: Context) => (context: Context) => Promise<void>)
57
+ ): AppBuilder
39
58
  }
package/src/appSdk.ts CHANGED
@@ -1,40 +1,59 @@
1
- import type { Lifetime } from './disposable'
2
- import type { CredentialBase } from './credentials'
3
- import type { Constructor } from './internal/registry'
1
+ import type { Lifetime } from "./disposable"
2
+ import type { CredentialBase } from "./credentials"
3
+ import { Context } from "./context"
4
+ import type { Constructor } from "./internal/registry"
5
+ import { Organizations } from "./storages/organizations"
6
+ import { UserProfile } from "./storages/userProfile"
4
7
 
5
8
  /**
6
9
  * DataIsland App instance.
7
10
  */
8
- export interface AppSdk {
11
+ export abstract class AppSdk {
9
12
  /**
10
13
  * The name of this app.
11
14
  */
12
- get name(): string
15
+ abstract get name(): string
13
16
 
14
17
  /**
15
18
  * The host of this app.
16
19
  */
17
- get host(): string
20
+ abstract get host(): string
18
21
 
19
22
  /**
20
23
  * The automaticDataCollectionEnabled of this app.
21
24
  */
22
- get automaticDataCollectionEnabled(): boolean
25
+ abstract get automaticDataCollectionEnabled(): boolean
23
26
 
24
27
  /**
25
28
  * The lifetime of this app.
26
29
  */
27
- get lifetime(): Lifetime
30
+ abstract get lifetime(): Lifetime
28
31
 
29
32
  /**
30
33
  * The credential of this app.
31
34
  */
32
- get credential(): CredentialBase | undefined
35
+ abstract get credential(): CredentialBase | undefined
33
36
 
34
- set credential(value: CredentialBase)
37
+ abstract set credential(value: CredentialBase)
35
38
 
36
39
  /**
37
- * Gets the service registered with the given type.
40
+ * The context of this app.
38
41
  */
39
- resolve: <T>(type: Constructor<T>) => T | undefined
42
+ abstract get context(): Context
43
+
44
+ /**
45
+ * User's organizations.
46
+ */
47
+ abstract get organizations(): Organizations
48
+
49
+ /**
50
+ * User's profile.
51
+ */
52
+ abstract get userProfile(): UserProfile
53
+
54
+ /**
55
+ * Resolve a service from the app.
56
+ * @param type
57
+ */
58
+ abstract resolve<T>(type: Constructor<T>): T | undefined
40
59
  }
@@ -0,0 +1,14 @@
1
+ import { CommandHandler, Command } from "../services/commandService"
2
+ import { UserProfileService } from "../services/userProfileService"
3
+
4
+ export class StartCommand extends Command {}
5
+
6
+ export class StartCommandHandler extends CommandHandler<StartCommand> {
7
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
8
+ async execute(message: StartCommand): Promise<void> {
9
+ const service = this.context.resolve(
10
+ UserProfileService
11
+ ) as UserProfileService
12
+ await service.fetch()
13
+ }
14
+ }
package/src/context.ts ADDED
@@ -0,0 +1,31 @@
1
+ import { type Constructor, type Registry } from "./internal/registry"
2
+ import { type Lifetime } from "./disposable"
3
+ import { Command, CommandService } from "./services/commandService"
4
+
5
+ /**
6
+ * DataIsland App context.
7
+ */
8
+ export class Context {
9
+ constructor(
10
+ private readonly registry: Registry,
11
+ public readonly lifetime: Lifetime,
12
+ public readonly appName: string
13
+ ) {}
14
+
15
+ /**
16
+ * Resolve a service from the context.
17
+ * @param type of the service
18
+ */
19
+ resolve<T>(type: Constructor<T>): T | undefined {
20
+ return this.registry.get(type)
21
+ }
22
+
23
+ /**
24
+ * Execute a command.
25
+ * @param command to execute
26
+ */
27
+ async execute<T extends Command>(command: T): Promise<void> {
28
+ const service = this.resolve(CommandService) as CommandService
29
+ await service.execute(command)
30
+ }
31
+ }
@@ -1,6 +1,6 @@
1
- import { MiddlewareService } from './services/middlewareService'
2
- import { type Lifetime } from './disposable'
3
- import { type Context } from './internal/context'
1
+ import { MiddlewareService } from "./services/middlewareService"
2
+ import { type Lifetime } from "./disposable"
3
+ import { type Context } from "./context"
4
4
 
5
5
  /**
6
6
  * DataIsland App credential.
@@ -29,12 +29,34 @@ export class BasicCredential extends CredentialBase {
29
29
  onRegister(lifetime: Lifetime, context: Context): void {
30
30
  const service = context.resolve(MiddlewareService)
31
31
  if (service === undefined) {
32
- throw new Error('MiddlewareService is not registered.')
32
+ throw new Error("MiddlewareService is not registered.")
33
33
  }
34
34
  lifetime.add(
35
35
  service.useMiddleware(async (req, next) => {
36
- req.headers.set('Authorization', `Basic ${this.email}:${this.password}`)
37
- await next(req)
36
+ req.headers.set("Authorization", `Basic ${this.email}:${this.password}`)
37
+ return await next(req)
38
+ })
39
+ )
40
+ }
41
+ }
42
+
43
+ export class DebugCredential extends CredentialBase {
44
+ readonly token: string
45
+
46
+ constructor(token: string) {
47
+ super()
48
+ this.token = token
49
+ }
50
+
51
+ onRegister(lifetime: Lifetime, context: Context): void {
52
+ const service = context.resolve(MiddlewareService)
53
+ if (service === undefined) {
54
+ throw new Error("MiddlewareService is not registered.")
55
+ }
56
+ lifetime.add(
57
+ service.useMiddleware(async (req, next) => {
58
+ req.headers.set("Authorization", `Debug ${this.token}`)
59
+ return await next(req)
38
60
  })
39
61
  )
40
62
  }
@@ -51,12 +73,12 @@ export class BearerCredential extends CredentialBase {
51
73
  onRegister(lifetime: Lifetime, context: Context): void {
52
74
  const service = context.resolve(MiddlewareService)
53
75
  if (service === undefined) {
54
- throw new Error('MiddlewareService is not registered.')
76
+ throw new Error("MiddlewareService is not registered.")
55
77
  }
56
78
  lifetime.add(
57
79
  service.useMiddleware(async (req, next) => {
58
- req.headers.set('Authorization', `Bearer ${this.token}`)
59
- await next(req)
80
+ req.headers.set("Authorization", `Bearer ${this.token}`)
81
+ return await next(req)
60
82
  })
61
83
  )
62
84
  }
package/src/disposable.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Represents an object that can be disposed.
3
3
  */
4
4
  export interface Disposable {
5
- dispose: () => void
5
+ dispose(): void
6
6
  }
7
7
 
8
8
  /**
@@ -131,7 +131,7 @@ export class DisposableContainer implements Disposable {
131
131
  */
132
132
  private _throwIfDisposed(): void {
133
133
  if (this._isDisposed) {
134
- throw new Error('Object disposed')
134
+ throw new Error("Object disposed")
135
135
  }
136
136
  }
137
137
  }
@@ -0,0 +1,35 @@
1
+ import { UserDto } from "./userInfoResponse"
2
+
3
+
4
+ export interface PermitsDto {
5
+ isAdmin: boolean;
6
+ }
7
+
8
+ export interface RegulationDto {
9
+ isRegulateOrganization: boolean;
10
+ regulateWorkspaceIds: string[];
11
+ }
12
+
13
+ export interface AccessGroupDto {
14
+ id: string;
15
+ name: string;
16
+ type: number;
17
+ createdAt: number;
18
+ modifiedAt: number;
19
+ organizationId: string;
20
+ permits: PermitsDto;
21
+ regulation: RegulationDto;
22
+ membersCount: number;
23
+ }
24
+
25
+ export interface AccessGroupResponse {
26
+ group: AccessGroupDto;
27
+ members: UserDto[];
28
+ }
29
+
30
+ export interface AccessGroupsResponse {
31
+ groups: AccessGroupDto[];
32
+ }
33
+
34
+
35
+
@@ -0,0 +1,104 @@
1
+
2
+ export interface SourceDto {
3
+ id: string;
4
+ name: string;
5
+ url: string;
6
+ content: string;
7
+ page: number;
8
+ }
9
+
10
+ export interface AnswerDto {
11
+ id: string;
12
+ chatId: string;
13
+ question: string;
14
+ context: string;
15
+ sources: SourceDto[];
16
+ timestamp: number;
17
+ }
18
+
19
+ export interface ChatDto {
20
+ id: string;
21
+ name: string;
22
+ createdAt: number;
23
+ modifiedAt: number;
24
+ userId: string;
25
+ organizationId: string;
26
+ workspaceId: string;
27
+ answers: AnswerDto[];
28
+ }
29
+
30
+ export interface ChatListResponse {
31
+ chats: ChatDto[]
32
+ }
33
+
34
+ export enum AnswerStatus {
35
+ RUNNING = 0,
36
+ SUCCESS = 1,
37
+ CANCELED = 2,
38
+ FAIL = 3,
39
+ }
40
+
41
+ export interface AnswerStepDto{
42
+ id: string;
43
+ type: StepType;
44
+ status: StepStatus;
45
+ start_at: string;
46
+ end_at: string;
47
+ tokens: string[];
48
+ sources: SourceDto[];
49
+ }
50
+
51
+ export interface FetchAnswerResponse {
52
+ id: string;
53
+ status: AnswerStatus;
54
+ steps: AnswerStepDto[];
55
+ }
56
+
57
+ export interface FetchTokensResponse {
58
+ id: string;
59
+ step_id: string;
60
+ step_status: number;
61
+ step_tokens: string[];
62
+ }
63
+
64
+ export interface AnswerSourcesResponse {
65
+ chat_uid: string;
66
+ uid: string;
67
+ step_id: string;
68
+ sources: SourceDto[];
69
+ }
70
+
71
+ export enum StepStatus {
72
+ RUNNING = 0,
73
+ SUCCESS = 1,
74
+ FAIL = 2,
75
+ CANCELED = 3,
76
+ }
77
+
78
+ export enum StepType {
79
+ PREPARE = 0,
80
+ SOURCES = 1,
81
+ GENERATE_ANSWER = 6,
82
+ FINALIZE_RESULT = 9,
83
+ DONE = 10,
84
+ }
85
+
86
+ export class StepTypeInfo {
87
+ public static hasTokens(type: StepType): boolean {
88
+ switch (type) {
89
+ case StepType.GENERATE_ANSWER:
90
+ case StepType.DONE:
91
+ case StepType.FINALIZE_RESULT:
92
+ return true
93
+ }
94
+ return false
95
+ }
96
+
97
+ public static hasSources(type: StepType): boolean {
98
+ switch (type) {
99
+ case StepType.SOURCES:
100
+ return true
101
+ }
102
+ return false
103
+ }
104
+ }
@@ -0,0 +1,47 @@
1
+ import { WorkspaceDto } from "./workspacesResponse"
2
+
3
+ export interface UserInfoResponse {
4
+ adminInOrganization: string[]
5
+ organizations: OrganizationDto[]
6
+ user: UserDto
7
+ }
8
+
9
+ export interface UserDto {
10
+ id: string
11
+ isDeleted: boolean
12
+ created_at: number
13
+ modified_at: number
14
+ profile: ProfileDto
15
+ settings?: UserSettings | null
16
+ }
17
+
18
+ export interface ProfileDto {
19
+ name: string
20
+ email: string
21
+ }
22
+
23
+ export interface UserSettings {
24
+ activeOrganizationId: string
25
+ activeWorkspaceId: string
26
+ }
27
+
28
+ export interface OrganizationProfileDto {
29
+ name: string
30
+ description: string
31
+ }
32
+
33
+ export interface OrganizationDto {
34
+ id: string
35
+ createdAt: number
36
+ modifiedAt: number
37
+ membersCount: number
38
+ profile: OrganizationProfileDto
39
+ }
40
+
41
+ export interface OrganizationWorkspaces extends OrganizationDto {
42
+ workspaces: WorkspaceDto[]
43
+ }
44
+
45
+ export interface MembersResponse {
46
+ members: UserDto
47
+ }
@@ -0,0 +1,49 @@
1
+ import { WorkspaceId } from "../storages/workspaces"
2
+ import { FileId } from "../storages/files"
3
+
4
+ export interface WorkspaceProfileDto {
5
+ name: string
6
+ description: string
7
+ }
8
+
9
+ export interface WorkspaceDto {
10
+ id: WorkspaceId
11
+ createdAt: number
12
+ modifiedAt: number
13
+ profile: WorkspaceProfileDto
14
+ }
15
+
16
+ export interface WorkspacesResponse {
17
+ workspaces: WorkspaceDto[]
18
+ }
19
+
20
+ export interface FileUrlDto {
21
+ url: string
22
+ }
23
+
24
+ export interface FileProgressDto {
25
+ file_id: FileId
26
+ file_parts_count: number
27
+ completed_parts_count: number
28
+ success: boolean
29
+ error: string
30
+ }
31
+
32
+ export interface FileDto {
33
+ id: string
34
+ createdAt: number
35
+ modifiedAt: number
36
+ name: string
37
+ description: string
38
+ url: string
39
+ hash: string
40
+ organizationId: string
41
+ workspaceId: string
42
+ isProcessedSuccessfully: boolean
43
+ }
44
+
45
+ export interface FileListResponse {
46
+ files: FileDto[]
47
+ totalFilesCount: number
48
+ filesPerPage: number
49
+ }
package/src/events.ts CHANGED
@@ -1,8 +1,4 @@
1
- import { type Disposable, DisposableContainer } from './disposable'
2
-
3
- export interface Events<TE, TD> {
4
- get events(): EventDispatcher<TE, TD>
5
- }
1
+ import { type Disposable, DisposableContainer } from "./disposable"
6
2
 
7
3
  export interface Input<ET, DT> {
8
4
  type?: ET
package/src/index.ts CHANGED
@@ -1,13 +1,12 @@
1
- import { version } from '../package.json'
2
- import { _createApp } from './internal/createApp.impl'
3
- import { type AppBuilder } from './appBuilder'
4
- import { type AppSdk } from './appSdk'
1
+ import { version } from "../package.json"
2
+ import { _createApp } from "./internal/createApp.impl"
3
+ import { type AppBuilder } from "./appBuilder"
4
+ import { type AppSdk } from "./appSdk"
5
5
 
6
- export * from './events'
7
- export * from './types'
8
- export * from './disposable'
9
- export * from './types'
10
- export * from './credentials'
6
+ export * from "./events"
7
+ export * from "./disposable"
8
+ export * from "./credentials"
9
+ export * from "./appSdk"
11
10
 
12
11
  const _appsNotReady = new Map<string, Promise<AppSdk>>()
13
12
  const _appsReady = new Map<string, AppSdk>()
@@ -20,12 +19,12 @@ export const SDK_VERSION = version
20
19
  /**
21
20
  * Default DataIsland App name.
22
21
  */
23
- export const DEFAULT_NAME = '[DEFAULT]'
22
+ export const DEFAULT_NAME = "[DEFAULT]"
24
23
 
25
24
  /**
26
25
  * Default DataIsland App host.
27
26
  */
28
- export const DEFAULT_HOST = 'https://dataisland.com.ua'
27
+ export const DEFAULT_HOST = "https://api.dataisland.com.ua"
29
28
 
30
29
  export function sdks(): AppSdk[] {
31
30
  return Array.from(_appsReady.values())
@@ -62,8 +61,15 @@ export async function appSdk(
62
61
  })
63
62
  .catch(reason => {
64
63
  console.error(`Error: ${reason}`)
64
+ _appsNotReady.delete(name ?? DEFAULT_NAME)
65
65
  })
66
66
  _appsNotReady.set(name, appPromise)
67
+ } else {
68
+ if (setup !== undefined) {
69
+ throw new Error(
70
+ `App ${name} is initializing. You can't setup the same again.`
71
+ )
72
+ }
67
73
  }
68
74
  return await appPromise
69
75
  }