diff --git a/.eslintrc.js b/.eslintrc.js index 4237059a..a483ef12 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -164,7 +164,7 @@ module.exports = { 'no-useless-call': 'error', 'no-useless-computed-key': 'error', 'no-useless-concat': 'error', - 'no-useless-constructor': 'warn', + 'no-useless-constructor': 'off', 'no-useless-escape': 'off', 'no-useless-rename': 'error', 'no-useless-return': 'error', diff --git a/.prettierrc b/.prettierrc index c5ccf868..f5e77c5f 100644 --- a/.prettierrc +++ b/.prettierrc @@ -3,5 +3,6 @@ "arrowParens": "always", "trailingComma": "es5", "bracketSpacing": true, - "singleQuote": true + "singleQuote": true, + "printWidth": 110 } diff --git a/examples/embedded/index.ts b/examples/embedded/index.ts index 34478729..044bdd2d 100644 --- a/examples/embedded/index.ts +++ b/examples/embedded/index.ts @@ -1,15 +1,13 @@ -import weaviate from 'weaviate-ts-client'; +import weaviate, { EmbeddedOptions } from 'weaviate-ts-client'; if (process.platform !== 'linux') { - throw new Error( - 'EmbeddedDB only supports Linux at the moment. Try me in a Docker container!' - ); + throw new Error('EmbeddedDB only supports Linux at the moment. Try me in a Docker container!'); } const client = weaviate.client({ scheme: 'http', host: 'localhost:9898', - embedded: new weaviate.EmbeddedOptions({ + embedded: new EmbeddedOptions({ port: 9898, }), }); diff --git a/examples/javascript/index.js b/examples/javascript/index.js index 094d547e..a2c60471 100644 --- a/examples/javascript/index.js +++ b/examples/javascript/index.js @@ -33,12 +33,6 @@ console.log( console.log(JSON.stringify(new weaviate.ApiKey('abcd1234'))); -console.log(weaviate.backup.Backend.GCS); -console.log(weaviate.batch.DeleteOutput.MINIMAL); -console.log(weaviate.cluster.NodeStatus.HEALTHY); -console.log(weaviate.filters.Operator.AND); -console.log(weaviate.replication.ConsistencyLevel.QUORUM); - client.misc .metaGetter() .do() diff --git a/examples/typescript/index.ts b/examples/typescript/index.ts index e1dde730..e5b71891 100644 --- a/examples/typescript/index.ts +++ b/examples/typescript/index.ts @@ -1,4 +1,9 @@ -import weaviate from 'weaviate-ts-client'; +import weaviate, { + AuthClientCredentials, + AuthUserPasswordCredentials, + ApiKey, + AuthAccessTokenCredentials, +} from 'weaviate-ts-client'; const client = weaviate.client({ scheme: 'http', @@ -7,7 +12,7 @@ const client = weaviate.client({ console.log( JSON.stringify( - new weaviate.AuthAccessTokenCredentials({ + new AuthAccessTokenCredentials({ accessToken: 'token123', expiresIn: 123, }) @@ -16,7 +21,7 @@ console.log( console.log( JSON.stringify( - new weaviate.AuthUserPasswordCredentials({ + new AuthUserPasswordCredentials({ username: 'user123', password: 'password', }) @@ -25,19 +30,13 @@ console.log( console.log( JSON.stringify( - new weaviate.AuthClientCredentials({ + new AuthClientCredentials({ clientSecret: 'secret123', }) ) ); -console.log(JSON.stringify(new weaviate.ApiKey('abcd1234'))); - -console.log(weaviate.backup.Backend.GCS); -console.log(weaviate.batch.DeleteOutput.MINIMAL); -console.log(weaviate.cluster.NodeStatus.HEALTHY); -console.log(weaviate.filters.Operator.AND); -console.log(weaviate.replication.ConsistencyLevel.QUORUM); +console.log(JSON.stringify(new ApiKey('abcd1234'))); client.misc .metaGetter() diff --git a/src/backup/backupCreateStatusGetter.ts b/src/backup/backupCreateStatusGetter.ts index 7caaa171..0379f21f 100644 --- a/src/backup/backupCreateStatusGetter.ts +++ b/src/backup/backupCreateStatusGetter.ts @@ -1,16 +1,18 @@ import Connection from '../connection'; import { validateBackupId, validateBackend } from './validation'; import { CommandBase } from '../validation/commandBase'; +import { BackupCreateStatusResponse } from '../openapi/types'; +import { Backend } from '.'; export default class BackupCreateStatusGetter extends CommandBase { - private backend?: string; + private backend?: Backend; private backupId?: string; constructor(client: Connection) { super(client); } - withBackend(backend: string) { + withBackend(backend: Backend) { this.backend = backend; return this; } @@ -20,24 +22,19 @@ export default class BackupCreateStatusGetter extends CommandBase { return this; } - validate() { - this.addErrors([ - ...validateBackend(this.backend), - ...validateBackupId(this.backupId), - ]); - } + validate = (): void => { + this.addErrors([...validateBackend(this.backend), ...validateBackupId(this.backupId)]); + }; - do() { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } - return this.client.get(this._path()); - } + return this.client.get(this._path()) as Promise; + }; - _path() { + private _path = (): string => { return `/backups/${this.backend}/${this.backupId}`; - } + }; } diff --git a/src/backup/backupCreator.ts b/src/backup/backupCreator.ts index ab72b273..d9773a5a 100644 --- a/src/backup/backupCreator.ts +++ b/src/backup/backupCreator.ts @@ -1,4 +1,3 @@ -import { CreateStatus } from './consts'; import { validateBackend, validateBackupId, @@ -8,12 +7,14 @@ import { import BackupCreateStatusGetter from './backupCreateStatusGetter'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { BackupCreateRequest, BackupCreateResponse, BackupCreateStatusResponse } from '../openapi/types'; +import { Backend } from '.'; const WAIT_INTERVAL = 1000; export default class BackupCreator extends CommandBase { - private backend?: string; - private backupId?: string; + private backend!: Backend; + private backupId!: string; private excludeClassNames?: string[]; private includeClassNames?: string[]; private statusGetter: BackupCreateStatusGetter; @@ -42,7 +43,7 @@ export default class BackupCreator extends CommandBase { return this; } - withBackend(backend: string) { + withBackend(backend: Backend) { this.backend = backend; return this; } @@ -57,21 +58,19 @@ export default class BackupCreator extends CommandBase { return this; } - validate() { + validate = (): void => { this.addErrors([ ...validateIncludeClassNames(this.includeClassNames), ...validateExcludeClassNames(this.excludeClassNames), ...validateBackend(this.backend), ...validateBackupId(this.backupId), ]); - } + }; - do() { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const payload = { @@ -79,34 +78,29 @@ export default class BackupCreator extends CommandBase { config: {}, include: this.includeClassNames, exclude: this.excludeClassNames, - }; + } as BackupCreateRequest; if (this.waitForCompletion) { return this._createAndWaitForCompletion(payload); } return this._create(payload); - } + }; - _create(payload: any) { - return this.client.post(this._path(), payload); - } + _create = (payload: BackupCreateRequest): Promise => { + return this.client.post(this._path(), payload) as Promise; + }; - _createAndWaitForCompletion(payload: any) { - return new Promise((resolve, reject) => { + _createAndWaitForCompletion = (payload: BackupCreateRequest): Promise => { + return new Promise((resolve, reject) => { this._create(payload) .then((createResponse: any) => { - this.statusGetter - .withBackend(this.backend!) - .withBackupId(this.backupId!); + this.statusGetter.withBackend(this.backend).withBackupId(this.backupId); const loop = () => { this.statusGetter .do() .then((createStatusResponse: any) => { - if ( - createStatusResponse.status == CreateStatus.SUCCESS || - createStatusResponse.status == CreateStatus.FAILED - ) { + if (createStatusResponse.status == 'SUCCESS' || createStatusResponse.status == 'FAILED') { resolve(this._merge(createStatusResponse, createResponse)); } else { setTimeout(loop, WAIT_INTERVAL); @@ -119,14 +113,17 @@ export default class BackupCreator extends CommandBase { }) .catch(reject); }); - } + }; - _path() { + private _path = (): string => { return `/backups/${this.backend}`; - } + }; - _merge(createStatusResponse: any, createResponse: any) { - const merged: any = {}; + _merge = ( + createStatusResponse: BackupCreateStatusResponse, + createResponse: BackupCreateResponse + ): BackupCreateResponse => { + const merged: BackupCreateResponse = {}; if ('id' in createStatusResponse) { merged.id = createStatusResponse.id; } @@ -146,5 +143,5 @@ export default class BackupCreator extends CommandBase { merged.classes = createResponse.classes; } return merged; - } + }; } diff --git a/src/backup/backupGetter.ts b/src/backup/backupGetter.ts index e79c6e04..0da885f2 100644 --- a/src/backup/backupGetter.ts +++ b/src/backup/backupGetter.ts @@ -1,35 +1,35 @@ import { validateBackend } from './validation'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { BackupCreateResponse } from '../openapi/types'; +import { Backend } from '.'; export default class BackupGetter extends CommandBase { - private backend?: string; + private backend?: Backend; constructor(client: Connection) { super(client); } - withBackend(backend: string) { + withBackend(backend: Backend) { this.backend = backend; return this; } - validate() { + validate = (): void => { this.addErrors(validateBackend(this.backend)); - } + }; - do() { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } return this.client.get(this._path()); - } + }; - _path() { + private _path = (): string => { return `/backups/${this.backend}`; - } + }; } diff --git a/src/backup/backupRestoreStatusGetter.ts b/src/backup/backupRestoreStatusGetter.ts index 90c2d3ba..caa147c5 100644 --- a/src/backup/backupRestoreStatusGetter.ts +++ b/src/backup/backupRestoreStatusGetter.ts @@ -1,16 +1,18 @@ import { validateBackupId, validateBackend } from './validation'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { BackupRestoreStatusResponse } from '../openapi/types'; +import { Backend } from '.'; export default class BackupRestoreStatusGetter extends CommandBase { - private backend?: string; + private backend?: Backend; private backupId?: string; constructor(client: Connection) { super(client); } - withBackend(backend: string) { + withBackend(backend: Backend) { this.backend = backend; return this; } @@ -20,25 +22,20 @@ export default class BackupRestoreStatusGetter extends CommandBase { return this; } - validate() { - this.addErrors([ - ...validateBackend(this.backend), - ...validateBackupId(this.backupId), - ]); - } + validate = (): void => { + this.addErrors([...validateBackend(this.backend), ...validateBackupId(this.backupId)]); + }; - do() { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } return this.client.get(this._path()); - } + }; - _path() { + private _path = (): string => { return `/backups/${this.backend}/${this.backupId}/restore`; - } + }; } diff --git a/src/backup/backupRestorer.ts b/src/backup/backupRestorer.ts index ffb81842..27c3e8ec 100644 --- a/src/backup/backupRestorer.ts +++ b/src/backup/backupRestorer.ts @@ -1,4 +1,3 @@ -import { RestoreStatus } from './consts'; import { validateBackend, validateBackupId, @@ -8,12 +7,14 @@ import { import Connection from '../connection'; import BackupRestoreStatusGetter from './backupRestoreStatusGetter'; import { CommandBase } from '../validation/commandBase'; +import { BackupRestoreRequest, BackupRestoreResponse, BackupRestoreStatusResponse } from '../openapi/types'; +import { Backend } from '.'; const WAIT_INTERVAL = 1000; export default class BackupRestorer extends CommandBase { - private backend?: string; - private backupId?: string; + private backend!: Backend; + private backupId!: string; private excludeClassNames?: string[]; private includeClassNames?: string[]; private statusGetter: BackupRestoreStatusGetter; @@ -42,7 +43,7 @@ export default class BackupRestorer extends CommandBase { return this; } - withBackend(backend: string) { + withBackend(backend: Backend) { this.backend = backend; return this; } @@ -57,55 +58,48 @@ export default class BackupRestorer extends CommandBase { return this; } - validate() { + validate = (): void => { this.addErrors([ ...validateIncludeClassNames(this.includeClassNames || []), ...validateExcludeClassNames(this.excludeClassNames || []), ...validateBackend(this.backend), ...validateBackupId(this.backupId), ]); - } + }; - do() { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const payload = { config: {}, include: this.includeClassNames, exclude: this.excludeClassNames, - }; + } as BackupRestoreRequest; if (this.waitForCompletion) { return this._restoreAndWaitForCompletion(payload); } return this._restore(payload); - } + }; - _restore(payload: any) { + _restore = (payload: BackupRestoreRequest): Promise => { return this.client.post(this._path(), payload); - } + }; - _restoreAndWaitForCompletion(payload: any) { - return new Promise((resolve, reject) => { + _restoreAndWaitForCompletion = (payload: BackupRestoreRequest): Promise => { + return new Promise((resolve, reject) => { this._restore(payload) .then((restoreResponse: any) => { - this.statusGetter - .withBackend(this.backend!) - .withBackupId(this.backupId!); + this.statusGetter.withBackend(this.backend).withBackupId(this.backupId); const loop = () => { this.statusGetter .do() .then((restoreStatusResponse: any) => { - if ( - restoreStatusResponse.status == RestoreStatus.SUCCESS || - restoreStatusResponse.status == RestoreStatus.FAILED - ) { + if (restoreStatusResponse.status == 'SUCCESS' || restoreStatusResponse.status == 'FAILED') { resolve(this._merge(restoreStatusResponse, restoreResponse)); } else { setTimeout(loop, WAIT_INTERVAL); @@ -118,14 +112,17 @@ export default class BackupRestorer extends CommandBase { }) .catch(reject); }); - } + }; - _path() { + private _path = (): string => { return `/backups/${this.backend}/${this.backupId}/restore`; - } + }; - _merge(restoreStatusResponse: any, restoreResponse: any) { - const merged: any = {}; + _merge = ( + restoreStatusResponse: BackupRestoreStatusResponse, + restoreResponse: BackupRestoreResponse + ): BackupRestoreResponse => { + const merged: BackupRestoreResponse = {}; if ('id' in restoreStatusResponse) { merged.id = restoreStatusResponse.id; } @@ -145,5 +142,5 @@ export default class BackupRestorer extends CommandBase { merged.classes = restoreResponse.classes; } return merged; - } + }; } diff --git a/src/backup/consts.ts b/src/backup/consts.ts deleted file mode 100644 index 8b25bbef..00000000 --- a/src/backup/consts.ts +++ /dev/null @@ -1,30 +0,0 @@ -export const Backend = { - FILESYSTEM: 'filesystem', - S3: 's3', - GCS: 'gcs', - AZURE: 'azure', -}; - -export const CreateStatus = { - STARTED: 'STARTED', - TRANSFERRING: 'TRANSFERRING', - TRANSFERRED: 'TRANSFERRED', - SUCCESS: 'SUCCESS', - FAILED: 'FAILED', -}; - -export const RestoreStatus = { - STARTED: 'STARTED', - TRANSFERRING: 'TRANSFERRING', - TRANSFERRED: 'TRANSFERRED', - SUCCESS: 'SUCCESS', - FAILED: 'FAILED', -}; - -const backupConsts = { - Backend, - CreateStatus, - RestoreStatus, -}; - -export default backupConsts; diff --git a/src/backup/index.ts b/src/backup/index.ts index bafcea9f..4735e9c1 100644 --- a/src/backup/index.ts +++ b/src/backup/index.ts @@ -4,6 +4,9 @@ import BackupRestorer from './backupRestorer'; import BackupRestoreStatusGetter from './backupRestoreStatusGetter'; import Connection from '../connection'; +export type Backend = 'filesystem' | 's3' | 'gcs' | 'azure'; +export type BackupStatus = 'STARTED' | 'TRANSFERRING' | 'TRANSFERRED' | 'SUCCESS' | 'FAILED'; + export interface Backup { creator: () => BackupCreator; createStatusGetter: () => BackupCreateStatusGetter; @@ -13,11 +16,9 @@ export interface Backup { const backup = (client: Connection): Backup => { return { - creator: () => - new BackupCreator(client, new BackupCreateStatusGetter(client)), + creator: () => new BackupCreator(client, new BackupCreateStatusGetter(client)), createStatusGetter: () => new BackupCreateStatusGetter(client), - restorer: () => - new BackupRestorer(client, new BackupRestoreStatusGetter(client)), + restorer: () => new BackupRestorer(client, new BackupRestoreStatusGetter(client)), restoreStatusGetter: () => new BackupRestoreStatusGetter(client), }; }; diff --git a/src/backup/journey.test.ts b/src/backup/journey.test.ts index 4eccd9c6..7c1885f5 100644 --- a/src/backup/journey.test.ts +++ b/src/backup/journey.test.ts @@ -1,4 +1,11 @@ -import weaviate, { WeaviateClient } from '../index'; +import { Backend } from '.'; +import weaviate, { WeaviateClient } from '..'; +import { + BackupCreateResponse, + BackupCreateStatusResponse, + BackupRestoreResponse, + BackupRestoreStatusResponse, +} from '../openapi/types'; const { createTestFoodSchemaAndData, @@ -10,7 +17,7 @@ const { const DOCKER_COMPOSE_BACKUPS_DIR = '/tmp/backups'; describe('create and restore backup with waiting', () => { - const BACKEND = weaviate.backup.Backend.FILESYSTEM; + const BACKEND: Backend = 'filesystem'; const BACKUP_ID = randomBackupId(); const client = weaviate.client({ @@ -30,17 +37,13 @@ describe('create and restore backup with waiting', () => { .withBackupId(BACKUP_ID) .withWaitForCompletion(true) .do() - .then((createResponse: any) => { + .then((createResponse: BackupCreateResponse) => { expect(createResponse.id).toBe(BACKUP_ID); expect(createResponse.classes).toHaveLength(1); expect(createResponse.classes).toContain(PIZZA_CLASS_NAME); - expect(createResponse.path).toBe( - `${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}` - ); + expect(createResponse.path).toBe(`${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}`); expect(createResponse.backend).toBe(BACKEND); - expect(createResponse.status).toBe( - weaviate.backup.CreateStatus.SUCCESS - ); + expect(createResponse.status).toBe('SUCCESS'); expect(createResponse.error).toBeUndefined(); }) .catch((err: any) => { @@ -56,18 +59,14 @@ describe('create and restore backup with waiting', () => { .withBackend(BACKEND) .withBackupId(BACKUP_ID) .do() - .then((createStatusResponse: any) => { + .then((createStatusResponse: BackupCreateStatusResponse) => { expect(createStatusResponse.id).toBe(BACKUP_ID); - expect(createStatusResponse.path).toBe( - `${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}` - ); + expect(createStatusResponse.path).toBe(`${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}`); expect(createStatusResponse.backend).toBe(BACKEND); - expect(createStatusResponse.status).toBe( - weaviate.backup.CreateStatus.SUCCESS - ); + expect(createStatusResponse.status).toBe('SUCCESS'); expect(createStatusResponse.error).toBeUndefined(); }) - .catch((err: any) => { + .catch((err: Error) => { throw new Error('should not fail on create status: ' + err); }); }); @@ -90,20 +89,16 @@ describe('create and restore backup with waiting', () => { .withBackupId(BACKUP_ID) .withWaitForCompletion(true) .do() - .then((restoreResponse: any) => { + .then((restoreResponse: BackupRestoreResponse) => { expect(restoreResponse.id).toBe(BACKUP_ID); expect(restoreResponse.classes).toHaveLength(1); expect(restoreResponse.classes).toContain(PIZZA_CLASS_NAME); - expect(restoreResponse.path).toBe( - `${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}` - ); + expect(restoreResponse.path).toBe(`${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}`); expect(restoreResponse.backend).toBe(BACKEND); - expect(restoreResponse.status).toBe( - weaviate.backup.RestoreStatus.SUCCESS - ); + expect(restoreResponse.status).toBe('SUCCESS'); expect(restoreResponse.error).toBeUndefined(); }) - .catch((err: any) => { + .catch((err: Error) => { throw new Error('should not fail on restore backup: ' + err); }); }); @@ -116,18 +111,14 @@ describe('create and restore backup with waiting', () => { .withBackend(BACKEND) .withBackupId(BACKUP_ID) .do() - .then((restoreStatusResponse: any) => { + .then((restoreStatusResponse: BackupRestoreStatusResponse) => { expect(restoreStatusResponse.id).toBe(BACKUP_ID); - expect(restoreStatusResponse.path).toBe( - `${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}` - ); + expect(restoreStatusResponse.path).toBe(`${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}`); expect(restoreStatusResponse.backend).toBe(BACKEND); - expect(restoreStatusResponse.status).toBe( - weaviate.backup.RestoreStatus.SUCCESS - ); + expect(restoreStatusResponse.status).toBe('SUCCESS'); expect(restoreStatusResponse.error).toBeUndefined(); }) - .catch((err: any) => { + .catch((err: Error) => { throw new Error('should not fail on restore status: ' + err); }); }); @@ -136,7 +127,7 @@ describe('create and restore backup with waiting', () => { }); describe('create and restore backup without waiting', () => { - const BACKEND = weaviate.backup.Backend.FILESYSTEM; + const BACKEND: Backend = 'filesystem'; const BACKUP_ID = randomBackupId(); const client = weaviate.client({ @@ -155,39 +146,28 @@ describe('create and restore backup without waiting', () => { .withBackend(BACKEND) .withBackupId(BACKUP_ID) .do() - .then((createResponse: any) => { + .then((createResponse: BackupCreateResponse) => { expect(createResponse.id).toBe(BACKUP_ID); expect(createResponse.classes).toHaveLength(1); expect(createResponse.classes).toContain(PIZZA_CLASS_NAME); - expect(createResponse.path).toBe( - `${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}` - ); + expect(createResponse.path).toBe(`${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}`); expect(createResponse.backend).toBe(BACKEND); - expect(createResponse.status).toBe( - weaviate.backup.CreateStatus.STARTED - ); + expect(createResponse.status).toBe('STARTED'); expect(createResponse.error).toBeUndefined(); }) - .catch((err: any) => { + .catch((err: Error) => { throw new Error('should not fail on create backup: ' + err); }); }); it('waits until created', () => { return new Promise((resolve, reject) => { - const statusGetter = client.backup - .createStatusGetter() - .withBackend(BACKEND) - .withBackupId(BACKUP_ID); + const statusGetter = client.backup.createStatusGetter().withBackend(BACKEND).withBackupId(BACKUP_ID); const loop = () => { statusGetter .do() - .then((createStatusResponse: any) => { - if ( - createStatusResponse.status == - weaviate.backup.CreateStatus.SUCCESS || - createStatusResponse.status == weaviate.backup.CreateStatus.FAILED - ) { + .then((createStatusResponse: BackupCreateStatusResponse) => { + if (createStatusResponse.status == 'SUCCESS' || createStatusResponse.status == 'FAILED') { resolve(createStatusResponse); } else { setTimeout(loop, 100); @@ -199,13 +179,9 @@ describe('create and restore backup without waiting', () => { }) .then((createStatusResponse: any) => { expect(createStatusResponse.id).toBe(BACKUP_ID); - expect(createStatusResponse.path).toBe( - `${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}` - ); + expect(createStatusResponse.path).toBe(`${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}`); expect(createStatusResponse.backend).toBe(BACKEND); - expect(createStatusResponse.status).toBe( - weaviate.backup.CreateStatus.SUCCESS - ); + expect(createStatusResponse.status).toBe('SUCCESS'); expect(createStatusResponse.error).toBeUndefined(); }) .catch((err: any) => { @@ -232,40 +208,28 @@ describe('create and restore backup without waiting', () => { .withBackend(BACKEND) .withBackupId(BACKUP_ID) .do() - .then((restoreResponse: any) => { + .then((restoreResponse: BackupRestoreResponse) => { expect(restoreResponse.id).toBe(BACKUP_ID); expect(restoreResponse.classes).toHaveLength(1); expect(restoreResponse.classes).toContain(PIZZA_CLASS_NAME); - expect(restoreResponse.path).toBe( - `${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}` - ); + expect(restoreResponse.path).toBe(`${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}`); expect(restoreResponse.backend).toBe(BACKEND); - expect(restoreResponse.status).toBe( - weaviate.backup.RestoreStatus.STARTED - ); + expect(restoreResponse.status).toBe('STARTED'); expect(restoreResponse.error).toBeUndefined(); }) - .catch((err: any) => { + .catch((err: Error) => { throw new Error('should not fail on restore backup: ' + err); }); }); it('waits until restored', () => { return new Promise((resolve, reject) => { - const statusGetter = client.backup - .restoreStatusGetter() - .withBackend(BACKEND) - .withBackupId(BACKUP_ID); + const statusGetter = client.backup.restoreStatusGetter().withBackend(BACKEND).withBackupId(BACKUP_ID); const loop = () => { statusGetter .do() - .then((restoreStatusResponse: any) => { - if ( - restoreStatusResponse.status == - weaviate.backup.RestoreStatus.SUCCESS || - restoreStatusResponse.status == - weaviate.backup.RestoreStatus.FAILED - ) { + .then((restoreStatusResponse: BackupRestoreStatusResponse) => { + if (restoreStatusResponse.status == 'SUCCESS' || restoreStatusResponse.status == 'FAILED') { resolve(restoreStatusResponse); } else { setTimeout(loop, 100); @@ -277,13 +241,9 @@ describe('create and restore backup without waiting', () => { }) .then((restoreStatusResponse: any) => { expect(restoreStatusResponse.id).toBe(BACKUP_ID); - expect(restoreStatusResponse.path).toBe( - `${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}` - ); + expect(restoreStatusResponse.path).toBe(`${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}`); expect(restoreStatusResponse.backend).toBe(BACKEND); - expect(restoreStatusResponse.status).toBe( - weaviate.backup.RestoreStatus.SUCCESS - ); + expect(restoreStatusResponse.status).toBe('SUCCESS'); expect(restoreStatusResponse.error).toBeUndefined(); }) .catch((err: any) => { @@ -297,7 +257,7 @@ describe('create and restore backup without waiting', () => { }); describe('create and restore 1 of 2 classes', () => { - const BACKEND = weaviate.backup.Backend.FILESYSTEM; + const BACKEND: Backend = 'filesystem'; const BACKUP_ID = randomBackupId(); const client = weaviate.client({ @@ -308,10 +268,7 @@ describe('create and restore 1 of 2 classes', () => { it('sets up', () => createTestFoodSchemaAndData(client)); it('asserts data exist', () => - Promise.all([ - assertThatAllPizzasExist(client), - assertThatAllSoupsExist(client), - ])); + Promise.all([assertThatAllPizzasExist(client), assertThatAllSoupsExist(client)])); it('creates backup', () => { return client.backup @@ -320,30 +277,23 @@ describe('create and restore 1 of 2 classes', () => { .withBackupId(BACKUP_ID) .withWaitForCompletion(true) .do() - .then((createResponse: any) => { + .then((createResponse: BackupCreateResponse) => { expect(createResponse.id).toBe(BACKUP_ID); expect(createResponse.classes).toHaveLength(2); expect(createResponse.classes).toContain(PIZZA_CLASS_NAME); expect(createResponse.classes).toContain(SOUP_CLASS_NAME); - expect(createResponse.path).toBe( - `${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}` - ); + expect(createResponse.path).toBe(`${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}`); expect(createResponse.backend).toBe(BACKEND); - expect(createResponse.status).toBe( - weaviate.backup.CreateStatus.SUCCESS - ); + expect(createResponse.status).toBe('SUCCESS'); expect(createResponse.error).toBeUndefined(); }) - .catch((err: any) => { + .catch((err: Error) => { throw new Error('should not fail on create backup: ' + err); }); }); it('asserts data still exist', () => - Promise.all([ - assertThatAllPizzasExist(client), - assertThatAllSoupsExist(client), - ])); + Promise.all([assertThatAllPizzasExist(client), assertThatAllSoupsExist(client)])); it('checks create status', () => { return client.backup @@ -351,18 +301,14 @@ describe('create and restore 1 of 2 classes', () => { .withBackend(BACKEND) .withBackupId(BACKUP_ID) .do() - .then((createStatusResponse: any) => { + .then((createStatusResponse: BackupCreateStatusResponse) => { expect(createStatusResponse.id).toBe(BACKUP_ID); - expect(createStatusResponse.path).toBe( - `${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}` - ); + expect(createStatusResponse.path).toBe(`${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}`); expect(createStatusResponse.backend).toBe(BACKEND); - expect(createStatusResponse.status).toBe( - weaviate.backup.CreateStatus.SUCCESS - ); + expect(createStatusResponse.status).toBe('SUCCESS'); expect(createStatusResponse.error).toBeUndefined(); }) - .catch((err: any) => { + .catch((err: Error) => { throw new Error('should not fail on create status: ' + err); }); }); @@ -385,17 +331,13 @@ describe('create and restore 1 of 2 classes', () => { .withBackupId(BACKUP_ID) .withWaitForCompletion(true) .do() - .then((restoreResponse: any) => { + .then((restoreResponse: BackupRestoreResponse) => { expect(restoreResponse.id).toBe(BACKUP_ID); expect(restoreResponse.classes).toHaveLength(1); expect(restoreResponse.classes).toContain(PIZZA_CLASS_NAME); - expect(restoreResponse.path).toBe( - `${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}` - ); + expect(restoreResponse.path).toBe(`${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}`); expect(restoreResponse.backend).toBe(BACKEND); - expect(restoreResponse.status).toBe( - weaviate.backup.RestoreStatus.SUCCESS - ); + expect(restoreResponse.status).toBe('SUCCESS'); expect(restoreResponse.error).toBeUndefined(); }) .catch((err: any) => { @@ -404,10 +346,7 @@ describe('create and restore 1 of 2 classes', () => { }); it('asserts data again exist', () => - Promise.all([ - assertThatAllPizzasExist(client), - assertThatAllSoupsExist(client), - ])); + Promise.all([assertThatAllPizzasExist(client), assertThatAllSoupsExist(client)])); it('checks restore status', () => { return client.backup @@ -415,113 +354,15 @@ describe('create and restore 1 of 2 classes', () => { .withBackend(BACKEND) .withBackupId(BACKUP_ID) .do() - .then((restoreStatusResponse: any) => { + .then((restoreStatusResponse: BackupRestoreStatusResponse) => { expect(restoreStatusResponse.id).toBe(BACKUP_ID); - expect(restoreStatusResponse.path).toBe( - `${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}` - ); + expect(restoreStatusResponse.path).toBe(`${DOCKER_COMPOSE_BACKUPS_DIR}/${BACKUP_ID}`); expect(restoreStatusResponse.backend).toBe(BACKEND); - expect(restoreStatusResponse.status).toBe( - weaviate.backup.RestoreStatus.SUCCESS - ); + expect(restoreStatusResponse.status).toBe('SUCCESS'); expect(restoreStatusResponse.error).toBeUndefined(); }) - .catch((err: any) => { - throw new Error('should not fail on restore status: ' + err); - }); - }); - - it('cleans up', () => cleanupTestFood(client)); -}); - -describe('fail creating backup on not existing backend', () => { - const BACKEND = 'not-existing-backend'; - const BACKUP_ID = randomBackupId(); - - const client = weaviate.client({ - scheme: 'http', - host: 'localhost:8080', - }); - - beforeEach(() => { - return createTestFoodSchemaAndData(client); - }); - - afterEach(() => { - return cleanupTestFood(client); - }); - - it('fails creating', () => { - return client.backup - .creator() - .withIncludeClassNames(PIZZA_CLASS_NAME) - .withBackend(BACKEND) - .withBackupId(BACKUP_ID) - .do() - .then(() => { - throw new Error('should fail on create backup'); - }) .catch((err: Error) => { - expect(err.message).toContain('422'); - expect(err.message).toContain(BACKEND); - }); - }); -}); - -describe('fail checking create status on not existing backend', () => { - const BACKEND = 'not-existing-backend'; - const BACKUP_ID = randomBackupId(); - - const client = weaviate.client({ - scheme: 'http', - host: 'localhost:8080', - }); - - it('sets up', () => createTestFoodSchemaAndData(client)); - - it('fails checking create status', () => { - return client.backup - .createStatusGetter() - .withBackend(BACKEND) - .withBackupId(BACKUP_ID) - .do() - .then(() => { - throw new Error('should fail on create status'); - }) - .catch((err: Error) => { - expect(err.message).toContain('422'); - expect(err.message).toContain(BACKEND); - }); - }); - - it('cleans up', () => cleanupTestFood(client)); -}); - -describe('fail restoring backup on not existing backend', () => { - const CLASS_NAME = 'not-existing-class'; - const BACKEND = 'not-existing-backend'; - const BACKUP_ID = randomBackupId(); - - const client = weaviate.client({ - scheme: 'http', - host: 'localhost:8080', - }); - - it('sets up', () => createTestFoodSchemaAndData(client)); - - it('fails restoring', () => { - return client.backup - .restorer() - .withIncludeClassNames(CLASS_NAME) - .withBackend(BACKEND) - .withBackupId(BACKUP_ID) - .do() - .then(() => { - throw new Error('should fail on restore backup'); - }) - .catch((err: Error) => { - expect(err.message).toContain('422'); - expect(err.message).toContain(BACKEND); + throw new Error('should not fail on restore status: ' + err); }); }); @@ -530,7 +371,7 @@ describe('fail restoring backup on not existing backend', () => { describe('fail creating backup for not existing class', () => { const CLASS_NAME = 'not-existing-class'; - const BACKEND = weaviate.backup.Backend.FILESYSTEM; + const BACKEND: Backend = 'filesystem'; const BACKUP_ID = randomBackupId(); const client = weaviate.client({ @@ -560,7 +401,7 @@ describe('fail creating backup for not existing class', () => { }); describe('fail restoring backup for existing class', () => { - const BACKEND = weaviate.backup.Backend.FILESYSTEM; + const BACKEND: Backend = 'filesystem'; const BACKUP_ID = randomBackupId(); const client = weaviate.client({ @@ -578,7 +419,7 @@ describe('fail restoring backup for existing class', () => { .withBackupId(BACKUP_ID) .withWaitForCompletion(true) .do() - .catch((err: any) => { + .catch((err: Error) => { throw new Error('should not fail on create backup: ' + err); }); }); @@ -591,10 +432,10 @@ describe('fail restoring backup for existing class', () => { .withBackupId(BACKUP_ID) .withWaitForCompletion(true) .do() - .then((resp: any) => { + .then((resp: BackupRestoreResponse) => { expect(resp.error).toContain('already exists'); expect(resp.error).toContain(PIZZA_CLASS_NAME); - expect(resp.status).toBe(weaviate.backup.RestoreStatus.FAILED); + expect(resp.status).toBe('FAILED'); }); }); @@ -602,7 +443,7 @@ describe('fail restoring backup for existing class', () => { }); describe('fail creating existing backup', () => { - const BACKEND = weaviate.backup.Backend.FILESYSTEM; + const BACKEND: Backend = 'filesystem'; const BACKUP_ID = randomBackupId(); const client = weaviate.client({ @@ -620,7 +461,7 @@ describe('fail creating existing backup', () => { .withBackupId(BACKUP_ID) .withWaitForCompletion(true) .do() - .catch((err: any) => { + .catch((err: Error) => { throw new Error('should not fail on create backup: ' + err); }); }); @@ -645,7 +486,7 @@ describe('fail creating existing backup', () => { }); describe('fail checking create status for not existing backup', () => { - const BACKEND = weaviate.backup.Backend.FILESYSTEM; + const BACKEND: Backend = 'filesystem'; const BACKUP_ID = randomBackupId(); const client = weaviate.client({ @@ -674,7 +515,7 @@ describe('fail checking create status for not existing backup', () => { }); describe('fail restoring not existing backup', () => { - const BACKEND = weaviate.backup.Backend.FILESYSTEM; + const BACKEND: Backend = 'filesystem'; const BACKUP_ID = randomBackupId(); const client = weaviate.client({ @@ -704,7 +545,7 @@ describe('fail restoring not existing backup', () => { }); describe('fail checking restore status for not started restore', () => { - const BACKEND = weaviate.backup.Backend.FILESYSTEM; + const BACKEND: Backend = 'filesystem'; const BACKUP_ID = randomBackupId(); const client = weaviate.client({ @@ -722,7 +563,7 @@ describe('fail checking restore status for not started restore', () => { .withBackupId(BACKUP_ID) .withWaitForCompletion(true) .do() - .catch((err: any) => { + .catch((err: Error) => { throw new Error('should not fail on create backup: ' + err); }); }); @@ -746,7 +587,7 @@ describe('fail checking restore status for not started restore', () => { }); describe('fail creating backup for both include and exclude classes', () => { - const BACKEND = weaviate.backup.Backend.FILESYSTEM; + const BACKEND: Backend = 'filesystem'; const BACKUP_ID = randomBackupId(); const client = weaviate.client({ @@ -779,7 +620,7 @@ describe('fail creating backup for both include and exclude classes', () => { }); describe('fail restoring backup for both include and exclude classes', () => { - const BACKEND = weaviate.backup.Backend.FILESYSTEM; + const BACKEND: Backend = 'filesystem'; const BACKUP_ID = randomBackupId(); const client = weaviate.client({ @@ -797,7 +638,7 @@ describe('fail restoring backup for both include and exclude classes', () => { .withBackupId(BACKUP_ID) .withWaitForCompletion(true) .do() - .catch((err: any) => { + .catch((err: Error) => { throw new Error('should not fail on create backup: ' + err); }); }); @@ -807,7 +648,7 @@ describe('fail restoring backup for both include and exclude classes', () => { .classDeleter() .withClassName(PIZZA_CLASS_NAME) .do() - .catch((err: any) => { + .catch((err: Error) => { throw new Error('should not fail on class delete: ' + err); }); }); @@ -830,14 +671,11 @@ describe('fail restoring backup for both include and exclude classes', () => { }); }); - it('cleans up', () => - cleanupTestFood(client).catch(() => - Promise.resolve('ignore not exising Pizza') - )); + it('cleans up', () => cleanupTestFood(client).catch(() => Promise.resolve('ignore not exising Pizza'))); }); // describe("get all exising backups", () => { -// const BACKEND = weaviate.backup.Backend.FILESYSTEM; +// const BACKEND: Backend = 'filesystem'; // const BACKUP_ID = randomBackupId() // const BACKUP_ID_PIZZA = BACKUP_ID + "-pizza"; // const BACKUP_ID_SOUP = BACKUP_ID + "-soup"; @@ -894,11 +732,7 @@ function assertThatAllSoupsExist(client: WeaviateClient) { return assertThatAllFoodObjectsExist(client, 'Soup', 2); } -function assertThatAllFoodObjectsExist( - client: WeaviateClient, - className: string, - number: number -) { +function assertThatAllFoodObjectsExist(client: WeaviateClient, className: string, number: number) { return client.graphql .get() .withClassName(className) diff --git a/src/backup/validation.ts b/src/backup/validation.ts index dce08af2..aae0210b 100644 --- a/src/backup/validation.ts +++ b/src/backup/validation.ts @@ -5,17 +5,13 @@ export function validateIncludeClassNames(classNames?: string[]) { const errors: any[] = []; classNames.forEach((className) => { if (!isValidStringProperty(className)) { - errors.push( - 'string className invalid - set with .withIncludeClassNames(...classNames)' - ); + errors.push('string className invalid - set with .withIncludeClassNames(...classNames)'); } }); return errors; } if (classNames !== null && classNames !== undefined) { - return [ - 'strings classNames invalid - set with .withIncludeClassNames(...classNames)', - ]; + return ['strings classNames invalid - set with .withIncludeClassNames(...classNames)']; } return []; } @@ -25,17 +21,13 @@ export function validateExcludeClassNames(classNames?: string[]) { const errors: any[] = []; classNames.forEach((className) => { if (!isValidStringProperty(className)) { - errors.push( - 'string className invalid - set with .withExcludeClassNames(...classNames)' - ); + errors.push('string className invalid - set with .withExcludeClassNames(...classNames)'); } }); return errors; } if (classNames !== null && classNames !== undefined) { - return [ - 'strings classNames invalid - set with .withExcludeClassNames(...classNames)', - ]; + return ['strings classNames invalid - set with .withExcludeClassNames(...classNames)']; } return []; } diff --git a/src/batch/consts.ts b/src/batch/consts.ts deleted file mode 100644 index 06ce20d9..00000000 --- a/src/batch/consts.ts +++ /dev/null @@ -1,17 +0,0 @@ -export const DeleteOutput = { - VERBOSE: 'verbose', - MINIMAL: 'minimal', -}; - -export const DeleteResultStatus = { - SUCCESS: 'SUCCESS', - FAILED: 'FAILED', - DRYRUN: 'DRYRUN', -}; - -const batchConsts = { - DeleteOutput, - DeleteResultStatus, -}; - -export default batchConsts; diff --git a/src/batch/index.ts b/src/batch/index.ts index 250e41ef..ac1a5f90 100644 --- a/src/batch/index.ts +++ b/src/batch/index.ts @@ -6,6 +6,9 @@ import { BeaconPath } from '../utils/beaconPath'; import { DbVersionSupport } from '../utils/dbVersion'; import Connection from '../connection'; +export type DeleteOutput = 'verbose' | 'minimal'; +export type DeleteResultStatus = 'SUCCESS' | 'FAILED' | 'DRYRUN'; + export interface Batch { objectsBatcher: () => ObjectsBatcher; objectsBatchDeleter: () => ObjectsBatchDeleter; @@ -13,10 +16,7 @@ export interface Batch { referencePayloadBuilder: () => ReferencePayloadBuilder; } -const batch = ( - client: Connection, - dbVersionSupport: DbVersionSupport -): Batch => { +const batch = (client: Connection, dbVersionSupport: DbVersionSupport): Batch => { const beaconPath = new BeaconPath(dbVersionSupport); return { diff --git a/src/batch/journey.test.ts b/src/batch/journey.test.ts index 12cce5ef..bf68c3c1 100644 --- a/src/batch/journey.test.ts +++ b/src/batch/journey.test.ts @@ -1,4 +1,12 @@ -import weaviate, { WeaviateClient } from '../index'; +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import weaviate, { WeaviateClient } from '..'; +import { + BatchReference, + BatchReferenceResponse, + WeaviateObject, + BatchDeleteResponse, + WhereFilter, +} from '../openapi/types'; const thingClassName = 'BatchJourneyTestThing'; const otherThingClassName = 'BatchJourneyTestOtherThing'; @@ -10,12 +18,9 @@ const thingIds = [ '5f4b0aa2-0704-4529-919f-c1f614e685f4', ]; -const otherThingIds = [ - '5b354a0f-fe66-4fe7-ad62-4db72ddab815', - '8727fa2b-610a-4a5c-af26-e558943f71c7', -]; +const otherThingIds = ['5b354a0f-fe66-4fe7-ad62-4db72ddab815', '8727fa2b-610a-4a5c-af26-e558943f71c7']; -const someObjects = [ +const someObjects: WeaviateObject[] = [ { class: thingClassName, id: thingIds[0], @@ -79,10 +84,10 @@ describe('batch importing', () => { .withObject(someObjects[0]) .withObjects(someObjects[1]) .withObjects(someObjects[2], someObjects[3]) - .withObjects([someObjects[4], someObjects[5]]); + .withObjects(...[someObjects[4], someObjects[5]]); expect(batcher.objects).toHaveLength(someObjects.length); - batcher.objects.forEach((obj: any, i: number) => { + batcher.objects.forEach((obj: WeaviateObject, i: number) => { expect(obj.class).toBe(someObjects[i].class); expect(obj.id).toBe(someObjects[i].id); }); @@ -112,7 +117,7 @@ describe('batch importing', () => { .withObject(toImport[1]) .do() .then() - .catch((e: any) => { + .catch((e: Error) => { throw new Error('it should not have errord ' + e); }); }); @@ -123,17 +128,9 @@ describe('batch importing', () => { it('verifies they are now queryable', () => { return Promise.all([ - client.data - .getterById() - .withId(thingIds[0]) - .withClassName(thingClassName) - .do(), - client.data - .getterById() - .withId(thingIds[1]) - .withClassName(thingClassName) - .do(), - ]).catch((e: any) => { + client.data.getterById().withId(thingIds[0]).withClassName(thingClassName).do(), + client.data.getterById().withId(thingIds[1]).withClassName(thingClassName).do(), + ]).catch((e: Error) => { throw new Error('it should not have errord ' + e); }); }); @@ -172,16 +169,8 @@ describe('batch importing', () => { it('verifies they are now queryable', () => { return Promise.all([ - client.data - .getterById() - .withId(thingIds[2]) - .withClassName(thingClassName) - .do(), - client.data - .getterById() - .withId(thingIds[3]) - .withClassName(thingClassName) - .do(), + client.data.getterById().withId(thingIds[2]).withClassName(thingClassName).do(), + client.data.getterById().withId(thingIds[3]).withClassName(thingClassName).do(), ]).catch((e: any) => { throw new Error('it should not have errord ' + e); }); @@ -207,8 +196,8 @@ describe('batch importing', () => { it('imports them with consistency level', () => { client.batch .objectsBatcher() - .withConsistencyLevel(weaviate.replication.ConsistencyLevel.ONE) - .withObjects([toImport[0], toImport[1]]) + .withConsistencyLevel('ONE') + .withObjects(...[toImport[0], toImport[1]]) .do() .then() .catch((e: any) => { @@ -222,16 +211,8 @@ describe('batch importing', () => { it('verifies they are now queryable', () => { return Promise.all([ - client.data - .getterById() - .withId(toImport[0].id) - .withClassName(toImport[0].class) - .do(), - client.data - .getterById() - .withId(toImport[1].id) - .withClassName(toImport[1].class) - .do(), + client.data.getterById().withId(toImport[0].id).withClassName(toImport[0].class).do(), + client.data.getterById().withId(toImport[1].id).withClassName(toImport[1].class).do(), ]).catch((e: any) => { throw new Error('it should not have errord ' + e); }); @@ -245,10 +226,10 @@ describe('batch importing', () => { .referencesBatcher() .withReference(someReferences[0]) .withReferences(someReferences[1], someReferences[2]) - .withReferences([someReferences[3]]); + .withReferences(...[someReferences[3]]); expect(batcher.references).toHaveLength(someReferences.length); - batcher.references.forEach((ref: any, i: number) => { + batcher.references.forEach((ref: BatchReference, i: number) => { expect(ref.from).toBe(someReferences[i].from); expect(ref.to).toBe(someReferences[i].to); }); @@ -265,11 +246,11 @@ describe('batch importing', () => { from: `weaviate://localhost/${thingClassName}/${thingIds[1]}/refProp`, to: `weaviate://localhost/${otherThingClassName}/${otherThingIds[1]}`, }) - .withConsistencyLevel(weaviate.replication.ConsistencyLevel.ALL) + .withConsistencyLevel('ALL') .do() - .then((res: any) => { - res.forEach((elem: any) => { - expect(elem.result.errors).toBeUndefined(); + .then((res: BatchReferenceResponse[]) => { + res.forEach((elem: BatchReferenceResponse) => { + expect(elem.result!.errors).toBeUndefined(); }); }) .catch((e: any) => { @@ -298,9 +279,9 @@ describe('batch importing', () => { .referencesBatcher() .withReferences(reference1, reference2) .do() - .then((res: any[]) => { - res.forEach((elem: any) => { - expect(elem.result.errors).toBeUndefined(); + .then((res: BatchReferenceResponse[]) => { + res.forEach((elem: BatchReferenceResponse) => { + expect(elem.result!.errors).toBeUndefined(); }); }) .catch((e: any) => { @@ -377,21 +358,21 @@ describe('batch deleting', () => { .objectsBatchDeleter() .withClassName(thingClassName) .withWhere({ - operator: weaviate.filters.Operator.EQUAL, + operator: 'Equal', valueString: 'bar1', path: ['stringProp'], }) .withDryRun(true) - .withOutput(weaviate.batch.DeleteOutput.VERBOSE) + .withOutput('verbose') .do() .then((result: any) => { expect(result.dryRun).toBe(true); - expect(result.output).toBe(weaviate.batch.DeleteOutput.VERBOSE); + expect(result.output).toBe('verbose'); expect(result.match).toEqual({ class: thingClassName, where: { - operands: null, // FIXME should not be received - operator: weaviate.filters.Operator.EQUAL, + operands: null, + operator: 'Equal', valueString: 'bar1', path: ['stringProp'], }, @@ -404,7 +385,7 @@ describe('batch deleting', () => { objects: [ { id: thingIds[1], - status: weaviate.batch.DeleteResultStatus.DRYRUN, + status: 'DRYRUN', }, ], }); @@ -415,21 +396,21 @@ describe('batch deleting', () => { .objectsBatchDeleter() .withClassName(otherThingClassName) .withWhere({ - operator: weaviate.filters.Operator.LIKE, + operator: 'Like', valueString: 'foo3', path: ['stringProp'], }) .withDryRun(true) - .withOutput(weaviate.batch.DeleteOutput.MINIMAL) + .withOutput('minimal') .do() - .then((result: any) => { + .then((result: BatchDeleteResponse) => { expect(result.dryRun).toBe(true); - expect(result.output).toBe(weaviate.batch.DeleteOutput.MINIMAL); + expect(result.output).toBe('minimal'); expect(result.match).toEqual({ class: otherThingClassName, where: { - operands: null, // FIXME should not be received - operator: weaviate.filters.Operator.LIKE, + operands: null, + operator: 'Like', valueString: 'foo3', path: ['stringProp'], }, @@ -448,19 +429,19 @@ describe('batch deleting', () => { .objectsBatchDeleter() .withClassName(otherThingClassName) .withWhere({ - operator: weaviate.filters.Operator.EQUAL, + operator: 'Equal', valueString: 'doesNotExist', path: ['stringProp'], }) .do() .then((result: any) => { expect(result.dryRun).toBe(false); - expect(result.output).toBe(weaviate.batch.DeleteOutput.MINIMAL); + expect(result.output).toBe('minimal'); expect(result.match).toEqual({ class: otherThingClassName, where: { - operands: null, // FIXME should not be received - operator: weaviate.filters.Operator.EQUAL, + operands: null, + operator: 'Equal', valueString: 'doesNotExist', path: ['stringProp'], }, @@ -480,21 +461,21 @@ describe('batch deleting', () => { .objectsBatchDeleter() .withClassName(otherThingClassName) .withWhere({ - operator: weaviate.filters.Operator.LESS_THAN, + operator: 'LessThan', valueString: inAMinute, path: ['_creationTimeUnix'], }) - .withOutput(weaviate.batch.DeleteOutput.VERBOSE) - .withConsistencyLevel(weaviate.replication.ConsistencyLevel.QUORUM) + .withOutput('verbose') + .withConsistencyLevel('QUORUM') .do() .then((result: any) => { expect(result.dryRun).toBe(false); - expect(result.output).toBe(weaviate.batch.DeleteOutput.VERBOSE); + expect(result.output).toBe('verbose'); expect(result.match).toEqual({ class: otherThingClassName, where: { - operands: null, // FIXME should not be received - operator: weaviate.filters.Operator.LESS_THAN, + operands: null, + operator: 'LessThan', valueString: inAMinute, path: ['_creationTimeUnix'], }, @@ -506,27 +487,15 @@ describe('batch deleting', () => { expect(result.results.objects).toHaveLength(2); expect(result.results.objects).toContainEqual({ id: otherThingIds[0], - status: weaviate.batch.DeleteResultStatus.SUCCESS, + status: 'SUCCESS', }); expect(result.results.objects).toContainEqual({ id: otherThingIds[1], - status: weaviate.batch.DeleteResultStatus.SUCCESS, + status: 'SUCCESS', }); }); }); - it('batch deletes fails due to validation', () => - client.batch - .objectsBatchDeleter() - .withClassName('') - .withWhere('shouldBeObject') - .do() - .catch((err: Error) => - expect(err.message).toBe( - 'invalid usage: string className must be set - set with .withClassName(className), object where must be set - set with .withWhere(whereFilter)' - ) - )); - it('tears down and cleans up', () => cleanup(client)); }); @@ -573,7 +542,10 @@ const setup = async (client: WeaviateClient) => { }; const setupData = (client: WeaviateClient) => { - return client.batch.objectsBatcher().withObjects(someObjects).do(); + return client.batch + .objectsBatcher() + .withObjects(...someObjects) + .do(); }; const cleanup = (client: WeaviateClient) => diff --git a/src/batch/objectsBatchDeleter.ts b/src/batch/objectsBatchDeleter.ts index b080db8d..21623cad 100644 --- a/src/batch/objectsBatchDeleter.ts +++ b/src/batch/objectsBatchDeleter.ts @@ -2,13 +2,16 @@ import { isValidStringProperty } from '../validation/string'; import { buildObjectsPath } from './path'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { BatchDelete, BatchDeleteResponse, WhereFilter } from '../openapi/types'; +import { ConsistencyLevel } from '../data/replication'; +import { DeleteOutput } from '.'; export default class ObjectsBatchDeleter extends CommandBase { private className?: string; - private consistencyLevel?: string; + private consistencyLevel?: ConsistencyLevel; private dryRun?: boolean; - private output?: any; - private whereFilter?: any; + private output?: DeleteOutput; + private whereFilter?: WhereFilter; constructor(client: Connection) { super(client); @@ -19,12 +22,12 @@ export default class ObjectsBatchDeleter extends CommandBase { return this; } - withWhere(whereFilter: any) { + withWhere(whereFilter: WhereFilter) { this.whereFilter = whereFilter; return this; } - withOutput(output: any) { + withOutput(output: DeleteOutput) { this.output = output; return this; } @@ -34,12 +37,12 @@ export default class ObjectsBatchDeleter extends CommandBase { return this; } - withConsistencyLevel = (cl: string) => { + withConsistencyLevel = (cl: ConsistencyLevel) => { this.consistencyLevel = cl; return this; }; - payload() { + payload = (): BatchDelete => { return { match: { class: this.className, @@ -48,35 +51,29 @@ export default class ObjectsBatchDeleter extends CommandBase { output: this.output, dryRun: this.dryRun, }; - } + }; - validateClassName() { + validateClassName = (): void => { if (!isValidStringProperty(this.className)) { - this.addError( - 'string className must be set - set with .withClassName(className)' - ); + this.addError('string className must be set - set with .withClassName(className)'); } - } + }; - validateWhereFilter() { + validateWhereFilter = (): void => { if (typeof this.whereFilter != 'object') { - this.addError( - 'object where must be set - set with .withWhere(whereFilter)' - ); + this.addError('object where must be set - set with .withWhere(whereFilter)'); } - } + }; - validate() { + validate = (): void => { this.validateClassName(); this.validateWhereFilter(); - } + }; - do() { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const params = new URLSearchParams(); if (this.consistencyLevel) { @@ -84,5 +81,5 @@ export default class ObjectsBatchDeleter extends CommandBase { } const path = buildObjectsPath(params); return this.client.delete(path, this.payload(), true); - } + }; } diff --git a/src/batch/objectsBatcher.ts b/src/batch/objectsBatcher.ts index c1ebcb6e..c6d42a48 100644 --- a/src/batch/objectsBatcher.ts +++ b/src/batch/objectsBatcher.ts @@ -1,10 +1,12 @@ import { buildObjectsPath } from './path'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { BatchRequest, WeaviateObject, WeaviateObjectsGet } from '../openapi/types'; +import { ConsistencyLevel } from '../data/replication'; export default class ObjectsBatcher extends CommandBase { - private consistencyLevel?: string; - public objects: any[]; + private consistencyLevel?: ConsistencyLevel; + public objects: WeaviateObject[]; constructor(client: Connection) { super(client); @@ -13,12 +15,12 @@ export default class ObjectsBatcher extends CommandBase { /** * can be called as: - * - withObjects([obj1, obj2, obj3]) + * - withObjects(...[obj1, obj2, obj3]) * - withObjects(obj1, obj2, obj3) * - withObjects(obj1) - * @param {...any} objects + * @param {...WeaviateObject[]} objects */ - withObjects(...objects: any) { + withObjects(...objects: WeaviateObject[]) { let objs = objects; if (objects.length && Array.isArray(objects[0])) { objs = objects[0]; @@ -27,37 +29,33 @@ export default class ObjectsBatcher extends CommandBase { return this; } - withObject(object: any) { + withObject(object: WeaviateObject) { return this.withObjects(object); } - withConsistencyLevel = (cl: any) => { + withConsistencyLevel = (cl: ConsistencyLevel) => { this.consistencyLevel = cl; return this; }; - payload = () => ({ + payload = (): BatchRequest => ({ objects: this.objects, }); - validateObjectCount = () => { + validateObjectCount = (): void => { if (this.objects.length == 0) { - this.addError( - 'need at least one object to send a request, add one with .withObject(obj)' - ); + this.addError('need at least one object to send a request, add one with .withObject(obj)'); } }; - validate = () => { + validate = (): void => { this.validateObjectCount(); }; - do = () => { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const params = new URLSearchParams(); if (this.consistencyLevel) { diff --git a/src/batch/path.ts b/src/batch/path.ts index 2555896f..ac2809f2 100644 --- a/src/batch/path.ts +++ b/src/batch/path.ts @@ -1,14 +1,14 @@ -export function buildObjectsPath(queryParams: any) { +export function buildObjectsPath(queryParams: any): string { const path = '/batch/objects'; return buildPath(path, queryParams); } -export function buildRefsPath(queryParams: any) { +export function buildRefsPath(queryParams: any): string { const path = '/batch/references'; return buildPath(path, queryParams); } -function buildPath(path: string, queryParams: any) { +function buildPath(path: string, queryParams: any): string { if (queryParams && queryParams.toString() != '') { path = `${path}?${queryParams.toString()}`; } diff --git a/src/batch/referencePayloadBuilder.ts b/src/batch/referencePayloadBuilder.ts index e207d283..e7d2af1b 100644 --- a/src/batch/referencePayloadBuilder.ts +++ b/src/batch/referencePayloadBuilder.ts @@ -1,6 +1,7 @@ import { isValidStringProperty } from '../validation/string'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { BatchReference } from '../openapi/types'; export default class ReferencesBatcher extends CommandBase { private fromClassName?: string; @@ -38,32 +39,20 @@ export default class ReferencesBatcher extends CommandBase { return this; } - validateIsSet = ( - prop: string | undefined | null, - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null, name: string, setter: string): void => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } }; - validate = () => { + validate = (): void => { this.validateIsSet(this.fromId, 'fromId', '.withFromId(id)'); this.validateIsSet(this.toId, 'toId', '.withToId(id)'); - this.validateIsSet( - this.fromClassName, - 'fromClassName', - '.withFromClassName(className)' - ); - this.validateIsSet( - this.fromRefProp, - 'fromRefProp', - '.withFromRefProp(refProp)' - ); + this.validateIsSet(this.fromClassName, 'fromClassName', '.withFromClassName(className)'); + this.validateIsSet(this.fromRefProp, 'fromRefProp', '.withFromRefProp(refProp)'); }; - payload = () => { + payload = (): BatchReference => { this.validate(); if (this.errors.length > 0) { throw new Error(this.errors.join(', ')); @@ -75,14 +64,12 @@ export default class ReferencesBatcher extends CommandBase { } return { - from: - `weaviate://localhost/${this.fromClassName}` + - `/${this.fromId}/${this.fromRefProp}`, + from: `weaviate://localhost/${this.fromClassName}/${this.fromId}/${this.fromRefProp}`, to: `${beaconTo}/${this.toId}`, }; }; - do(): Promise { + do = (): Promise => { return Promise.reject(new Error('Should never be called')); - } + }; } diff --git a/src/batch/referencesBatcher.ts b/src/batch/referencesBatcher.ts index 0e96c30e..550c2c0a 100644 --- a/src/batch/referencesBatcher.ts +++ b/src/batch/referencesBatcher.ts @@ -2,11 +2,13 @@ import { buildRefsPath } from './path'; import { BeaconPath } from '../utils/beaconPath'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { BatchReference, BatchReferenceResponse } from '../openapi/types'; +import { ConsistencyLevel } from '../data/replication'; export default class ReferencesBatcher extends CommandBase { private beaconPath: BeaconPath; - private consistencyLevel?: string; - public references: any[]; + private consistencyLevel?: ConsistencyLevel; + public references: BatchReference[]; constructor(client: Connection, beaconPath: BeaconPath) { super(client); @@ -16,12 +18,12 @@ export default class ReferencesBatcher extends CommandBase { /** * can be called as: - * - withReferences([ref1, ref2, ref3]) + * - withReferences(...[ref1, ref2, ref3]) * - withReferences(ref1, ref2, ref3) * - withReferences(ref1) - * @param {...any} references + * @param {...BatchReference[]} references */ - withReferences(...references: any) { + withReferences(...references: BatchReference[]) { let refs = references; if (references.length && Array.isArray(references[0])) { refs = references[0]; @@ -30,22 +32,20 @@ export default class ReferencesBatcher extends CommandBase { return this; } - withReference(reference: any) { + withReference(reference: BatchReference) { return this.withReferences(reference); } - withConsistencyLevel = (cl: any) => { + withConsistencyLevel = (cl: ConsistencyLevel) => { this.consistencyLevel = cl; return this; }; - payload = () => this.references; + payload = (): BatchReference[] => this.references; - validateReferenceCount = () => { + validateReferenceCount = (): void => { if (this.references.length == 0) { - this.addError( - 'need at least one reference to send a request, add one with .withReference(obj)' - ); + this.addError('need at least one reference to send a request, add one with .withReference(obj)'); } }; @@ -53,29 +53,26 @@ export default class ReferencesBatcher extends CommandBase { this.validateReferenceCount(); }; - do = () => { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const params = new URLSearchParams(); if (this.consistencyLevel) { params.set('consistency_level', this.consistencyLevel); } const path = buildRefsPath(params); - const payloadPromise = Promise.all( - this.references.map((ref) => this.rebuildReferencePromise(ref)) - ); + const payloadPromise = Promise.all(this.references.map((ref) => this.rebuildReferencePromise(ref))); return payloadPromise.then((payload) => this.client.post(path, payload)); }; - rebuildReferencePromise(reference: any) { - return this.beaconPath.rebuild(reference.to).then((beaconTo: any) => ({ + rebuildReferencePromise = (reference: BatchReference): Promise => { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return this.beaconPath.rebuild(reference.to!).then((beaconTo: any) => ({ from: reference.from, to: beaconTo, })); - } + }; } diff --git a/src/c11y/conceptsGetter.ts b/src/c11y/conceptsGetter.ts index 055eebf6..64275fbd 100644 --- a/src/c11y/conceptsGetter.ts +++ b/src/c11y/conceptsGetter.ts @@ -1,5 +1,6 @@ import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { C11yWordsResponse } from '../openapi/types'; export default class ConceptsGetter extends CommandBase { private concept?: string; @@ -8,11 +9,7 @@ export default class ConceptsGetter extends CommandBase { super(client); } - validateIsSet = ( - prop: string | undefined | null, - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null, name: string, setter: string) => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } @@ -23,16 +20,14 @@ export default class ConceptsGetter extends CommandBase { return this; }; - validate = () => { + validate = (): void => { this.validateIsSet(this.concept, 'concept', 'withConcept(concept)'); }; - do = () => { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const path = `/modules/text2vec-contextionary/concepts/${this.concept}`; diff --git a/src/c11y/extensionCreator.ts b/src/c11y/extensionCreator.ts index 3b0f5087..b5a1bd6c 100644 --- a/src/c11y/extensionCreator.ts +++ b/src/c11y/extensionCreator.ts @@ -1,5 +1,6 @@ import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { C11yExtension } from '../openapi/types'; export default class ExtensionCreator extends CommandBase { private concept?: string; @@ -25,42 +26,28 @@ export default class ExtensionCreator extends CommandBase { return this; }; - validateIsSet = ( - prop: string | undefined | null, - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null, name: string, setter: string): void => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } }; - validate = () => { + validate = (): void => { this.validateIsSet(this.concept, 'concept', 'withConcept(concept)'); - this.validateIsSet( - this.definition, - 'definition', - 'withDefinition(definition)' - ); - this.validateIsSet( - this.weight?.toString() || '', - 'weight', - 'withWeight(weight)' - ); + this.validateIsSet(this.definition, 'definition', 'withDefinition(definition)'); + this.validateIsSet(this.weight?.toString() || '', 'weight', 'withWeight(weight)'); }; - payload = () => ({ + payload = (): C11yExtension => ({ concept: this.concept, definition: this.definition, weight: this.weight, }); - do = () => { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const path = `/modules/text2vec-contextionary/extensions`; diff --git a/src/c11y/journey.test.ts b/src/c11y/journey.test.ts index 46b9d0bc..1525d5bb 100644 --- a/src/c11y/journey.test.ts +++ b/src/c11y/journey.test.ts @@ -1,4 +1,6 @@ -import weaviate from '../index'; +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import weaviate from '..'; +import { C11yWordsResponse, C11yExtension } from '../openapi/types'; describe('c11y endpoints', () => { const client = weaviate.client({ @@ -11,8 +13,8 @@ describe('c11y endpoints', () => { .conceptsGetter() .withConcept('car') .do() - .then((res: any) => { - expect(res.individualWords[0].word).toEqual('car'); + .then((res: C11yWordsResponse) => { + expect(res.individualWords![0].word!).toEqual('car'); }); }); @@ -26,7 +28,7 @@ describe('c11y endpoints', () => { ) .withWeight(1) .do() - .then((res: any) => { + .then((res: C11yExtension) => { expect(res).toEqual({ concept: 'clientalmostdonehappyness', definition: diff --git a/src/classifications/contextual.journey.test.ts b/src/classifications/contextual.journey.test.ts index 669df9cf..ceb1f4a7 100644 --- a/src/classifications/contextual.journey.test.ts +++ b/src/classifications/contextual.journey.test.ts @@ -1,4 +1,5 @@ -import weaviate from '../index'; +import weaviate from '..'; +import { Classification } from '../openapi/types'; const targetDessertId = '9f399d3e-45a4-44f4-b0fd-fa291abfb211'; const targetSavoryId = 'b7a64fbd-7c22-44ac-afbb-8d1432b8061b'; @@ -32,12 +33,12 @@ describe('a classification journey', () => { .withWaitForCompletion() .withWaitTimeout(60 * 1000) .do() - .then((res: any) => { + .then((res: Classification) => { expect(res.status).toEqual('completed'); expect(res.type).toEqual('text2vec-contextionary-contextual'); id = res.id; }) - .catch((e: any) => { + .catch((e: Error) => { throw new Error('it should not have errord: ' + e); }); }, @@ -116,14 +117,8 @@ const setup = async (client: any) => { const cleanup = (client: any) => { return Promise.all([ - client.schema - .classDeleter() - .withClassName('ContextualClassificationJourneySource') - .do(), - client.schema - .classDeleter() - .withClassName('ContextualClassificationJourneyTarget') - .do(), + client.schema.classDeleter().withClassName('ContextualClassificationJourneySource').do(), + client.schema.classDeleter().withClassName('ContextualClassificationJourneyTarget').do(), ]); }; diff --git a/src/classifications/getter.ts b/src/classifications/getter.ts index d1067471..bbc2e6b4 100644 --- a/src/classifications/getter.ts +++ b/src/classifications/getter.ts @@ -1,5 +1,6 @@ import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { Classification } from '../openapi/types'; export default class Getter extends CommandBase { private id?: string; @@ -13,30 +14,24 @@ export default class Getter extends CommandBase { return this; }; - validateIsSet = ( - prop: string | undefined | null, - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null, name: string, setter: string): void => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } }; - validateId = () => { + validateId = (): void => { this.validateIsSet(this.id, 'id', '.withId(id)'); }; - validate = () => { + validate = (): void => { this.validateId(); }; - do = () => { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const path = `/classifications/${this.id}`; diff --git a/src/classifications/knn.journey.test.ts b/src/classifications/knn.journey.test.ts index 621e15d4..0c05b6fb 100644 --- a/src/classifications/knn.journey.test.ts +++ b/src/classifications/knn.journey.test.ts @@ -1,5 +1,6 @@ -import weaviate, { WeaviateClient } from '../index'; +import weaviate, { WeaviateClient } from '..'; import Connection from '../connection'; +import { Classification } from '../openapi/types'; const targetDessertId = 'cd54852a-209d-423b-bf1c-884468215237'; const targetSavoryId = 'e5da0127-327e-4184-85b8-7b9d1af4a850'; @@ -26,7 +27,7 @@ describe('a classification journey', () => { .withClassifyProperties(['toTarget']) .withBasedOnProperties(['description']) .do() - .then((res: any) => { + .then((res: Classification) => { expect(res.id).toBeDefined(); id = res.id; }) @@ -40,7 +41,7 @@ describe('a classification journey', () => { .getter() .withId(id) .do() - .then((res: any) => { + .then((res: Classification) => { expect(res.status).toEqual('completed'); }); }); @@ -55,7 +56,7 @@ describe('a classification journey', () => { .getter() .withId(id) .do() - .then((res: any) => { + .then((res: Classification) => { clearInterval(backgroundWork); clearTimeout(timeout); if (res.status === 'completed') resolve(undefined); @@ -122,11 +123,11 @@ describe('a classification journey', () => { .withWaitForCompletion() .withWaitTimeout(60 * 1000) .do() - .then((res: any) => { + .then((res: Classification) => { expect(res.status).toEqual('completed'); id = res.id; }) - .catch((e: any) => { + .catch((e: Error) => { throw new Error('it should not have errord: ' + e); }); }); @@ -184,10 +185,10 @@ describe('a classification journey', () => { .withWaitForCompletion() .withWaitTimeout(1) // that's going to be difficult ;-) .do() - .then((res: any) => { + .then((res: Classification) => { fail('it should have errord'); }) - .catch((e: any) => { + .catch((e: Error) => { expect(e).toEqual( new Error( "classification didn't finish within configured timeout, " + @@ -288,14 +289,8 @@ const setup = async (client: WeaviateClient) => { const cleanup = (client: WeaviateClient) => { return Promise.all([ - client.schema - .classDeleter() - .withClassName('ClassificationJourneySource') - .do(), - client.schema - .classDeleter() - .withClassName('ClassificationJourneyTarget') - .do(), + client.schema.classDeleter().withClassName('ClassificationJourneySource').do(), + client.schema.classDeleter().withClassName('ClassificationJourneyTarget').do(), ]); }; diff --git a/src/classifications/scheduler.ts b/src/classifications/scheduler.ts index 68ac02d5..ae9ab2ea 100644 --- a/src/classifications/scheduler.ts +++ b/src/classifications/scheduler.ts @@ -1,6 +1,7 @@ import Getter from './getter'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { Classification } from '../openapi/types'; export default class Scheduler extends CommandBase { private basedOnProperties?: string[]; @@ -52,25 +53,17 @@ export default class Scheduler extends CommandBase { return this; }; - validateIsSet = ( - prop: string | undefined | null | any[], - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null | any[], name: string, setter: string): void => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } }; - validateClassName = () => { - this.validateIsSet( - this.className, - 'className', - '.withClassName(className)' - ); + validateClassName = (): void => { + this.validateIsSet(this.className, 'className', '.withClassName(className)'); }; - validateBasedOnProperties = () => { + validateBasedOnProperties = (): void => { this.validateIsSet( this.basedOnProperties, 'basedOnProperties', @@ -78,7 +71,7 @@ export default class Scheduler extends CommandBase { ); }; - validateClassifyProperties = () => { + validateClassifyProperties = (): void => { this.validateIsSet( this.classifyProperties, 'classifyProperties', @@ -86,13 +79,13 @@ export default class Scheduler extends CommandBase { ); }; - validate = () => { + validate = (): void => { this.validateClassName(); this.validateClassifyProperties(); this.validateBasedOnProperties(); }; - payload = () => ({ + payload = (): Classification => ({ type: this.type, settings: this.settings, class: this.className, @@ -100,7 +93,7 @@ export default class Scheduler extends CommandBase { basedOnProperties: this.basedOnProperties, }); - pollForCompletion = (id: any) => { + pollForCompletion = (id: any): Promise => { return new Promise((resolve, reject) => { setTimeout( () => @@ -117,18 +110,16 @@ export default class Scheduler extends CommandBase { new Getter(this.client) .withId(id) .do() - .then((res: any) => { + .then((res: Classification) => { if (res.status === 'completed') resolve(res); }); }, 500); }); }; - do = () => { + do = (): Promise => { if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } this.validate(); diff --git a/src/cluster/consts.ts b/src/cluster/consts.ts deleted file mode 100644 index 146f544d..00000000 --- a/src/cluster/consts.ts +++ /dev/null @@ -1,11 +0,0 @@ -export const NodeStatus = { - HEALTHY: 'HEALTHY', - UNHEALTHY: 'UNHEALTHY', - UNAVAILABLE: 'UNAVAILABLE', -}; - -const clusterConsts = { - NodeStatus, -}; - -export default clusterConsts; diff --git a/src/cluster/index.ts b/src/cluster/index.ts index c354a9a0..76d55078 100644 --- a/src/cluster/index.ts +++ b/src/cluster/index.ts @@ -1,6 +1,8 @@ import NodesStatusGetter from './nodesStatusGetter'; import Connection from '../connection'; +export type NodeStatus = 'HEALTHY' | 'UNHEALTHY' | 'UNAVAILABLE'; + export interface Cluster { nodesStatusGetter: () => NodesStatusGetter; } diff --git a/src/cluster/journey.test.ts b/src/cluster/journey.test.ts index 9273dabb..da4c7b4c 100644 --- a/src/cluster/journey.test.ts +++ b/src/cluster/journey.test.ts @@ -1,4 +1,4 @@ -import weaviate from '../index'; +import weaviate from '..'; const { createTestFoodSchemaAndData, @@ -26,7 +26,7 @@ describe('cluster nodes endpoint', () => { expect(node.name).toMatch(/.+/); expect(node.version).toEqual(EXPECTED_WEAVIATE_VERSION); expect(node.gitHash).toEqual(EXPECTED_WEAVIATE_GIT_HASH); - expect(node.status).toEqual(weaviate.cluster.NodeStatus.HEALTHY); + expect(node.status).toEqual('HEALTHY'); expect(node.stats.objectCount).toEqual(0); expect(node.stats.shardCount).toEqual(0); expect(node.shards).toHaveLength(0); @@ -48,7 +48,7 @@ describe('cluster nodes endpoint', () => { expect(node.name).toMatch(/.+/); expect(node.version).toEqual(EXPECTED_WEAVIATE_VERSION); expect(node.gitHash).toEqual(EXPECTED_WEAVIATE_GIT_HASH); - expect(node.status).toEqual(weaviate.cluster.NodeStatus.HEALTHY); + expect(node.status).toEqual('HEALTHY'); expect(node.stats.objectCount).toEqual(6); expect(node.stats.shardCount).toEqual(2); expect(node.shards).toHaveLength(2); diff --git a/src/connection/auth.ts b/src/connection/auth.ts index 71101844..71bcf2a5 100644 --- a/src/connection/auth.ts +++ b/src/connection/auth.ts @@ -41,25 +41,13 @@ export class OidcAuthenticator { let authenticator: OidcAuthFlow; switch (this.creds.constructor) { case AuthUserPasswordCredentials: - authenticator = new UserPasswordAuthenticator( - this.http, - this.creds, - config - ); + authenticator = new UserPasswordAuthenticator(this.http, this.creds, config); break; case AuthAccessTokenCredentials: - authenticator = new AccessTokenAuthenticator( - this.http, - this.creds, - config - ); + authenticator = new AccessTokenAuthenticator(this.http, this.creds, config); break; case AuthClientCredentials: - authenticator = new ClientCredentialsAuthenticator( - this.http, - this.creds, - config - ); + authenticator = new ClientCredentialsAuthenticator(this.http, this.creds, config); break; default: throw new Error('unsupported credential type'); @@ -77,16 +65,14 @@ export class OidcAuthenticator { }; getOpenidConfig = (localConfig: any) => { - return this.http - .externalGet(localConfig.href) - .then((openidProviderConfig: any) => { - const scopes = localConfig.scopes || []; - return { - clientId: localConfig.clientId, - provider: openidProviderConfig, - scopes: scopes, - }; - }); + return this.http.externalGet(localConfig.href).then((openidProviderConfig: any) => { + const scopes = localConfig.scopes || []; + return { + clientId: localConfig.clientId, + provider: openidProviderConfig, + scopes: scopes, + }; + }); }; runBackgroundTokenRefresh = (authenticator: { refresh: () => any }) => { @@ -166,9 +152,7 @@ class UserPasswordAuthenticator implements OidcAuthFlow { }; }) .catch((err: any) => { - return Promise.reject( - new Error(`failed to refresh access token: ${err}`) - ); + return Promise.reject(new Error(`failed to refresh access token: ${err}`)); }); }; @@ -179,11 +163,7 @@ class UserPasswordAuthenticator implements OidcAuthFlow { ) { throw new Error('grant_type password not supported'); } - if ( - this.openidConfig.provider.token_endpoint.includes( - 'https://login.microsoftonline.com' - ) - ) { + if (this.openidConfig.provider.token_endpoint.includes('https://login.microsoftonline.com')) { throw new Error( 'microsoft/azure recommends to avoid authentication using ' + 'username and password, so this method is not supported by this client' @@ -245,13 +225,8 @@ class AccessTokenAuthenticator implements OidcAuthFlow { } refresh = () => { - if ( - this.creds.refreshToken === undefined || - this.creds.refreshToken == '' - ) { - console.warn( - 'AuthAccessTokenCredentials not provided with refreshToken, cannot refresh' - ); + if (this.creds.refreshToken === undefined || this.creds.refreshToken == '') { + console.warn('AuthAccessTokenCredentials not provided with refreshToken, cannot refresh'); return Promise.resolve({ accessToken: this.creds.accessToken, expiresAt: this.creds.expiresAt, @@ -267,18 +242,14 @@ class AccessTokenAuthenticator implements OidcAuthFlow { }; }) .catch((err: any) => { - return Promise.reject( - new Error(`failed to refresh access token: ${err}`) - ); + return Promise.reject(new Error(`failed to refresh access token: ${err}`)); }); }; validateOpenidConfig = () => { if ( this.openidConfig.provider.grant_types_supported === undefined || - !this.openidConfig.provider.grant_types_supported.includes( - 'refresh_token' - ) + !this.openidConfig.provider.grant_types_supported.includes('refresh_token') ) { throw new Error('grant_type refresh_token not supported'); } @@ -336,9 +307,7 @@ class ClientCredentialsAuthenticator implements OidcAuthFlow { }; }) .catch((err: any) => { - return Promise.reject( - new Error(`failed to refresh access token: ${err}`) - ); + return Promise.reject(new Error(`failed to refresh access token: ${err}`)); }); }; @@ -346,11 +315,7 @@ class ClientCredentialsAuthenticator implements OidcAuthFlow { if (this.openidConfig.scopes.length > 0) { return; } - if ( - this.openidConfig.provider.token_endpoint.includes( - 'https://login.microsoftonline.com' - ) - ) { + if (this.openidConfig.provider.token_endpoint.includes('https://login.microsoftonline.com')) { this.openidConfig.scopes.push(this.openidConfig.clientId + '/.default'); } }; diff --git a/src/connection/gqlClient.ts b/src/connection/gqlClient.ts index edc9f0f7..84ae7dd4 100644 --- a/src/connection/gqlClient.ts +++ b/src/connection/gqlClient.ts @@ -1,9 +1,9 @@ -import { GraphQLClient as Client } from 'graphql-request'; -import { ConnectionParams } from '../index'; +import { GraphQLClient as Client, Variables } from 'graphql-request'; +import { ConnectionParams } from '..'; export type TQuery = any; export interface GraphQLClient { - query: (query: TQuery, headers?: HeadersInit) => Promise<{ data: any }>; + query: (query: TQuery, variables?: Variables, headers?: HeadersInit) => Promise<{ data: any }>; } export const gqlClient = (config: ConnectionParams): GraphQLClient => { @@ -13,14 +13,14 @@ export const gqlClient = (config: ConnectionParams): GraphQLClient => { return { // for backward compatibility with replaced graphql-client lib, // results are wrapped into { data: data } - query: (query: TQuery, headers?: HeadersInit) => { + query: (query: TQuery, variables?: Variables, headers?: HeadersInit) => { return new Client(`${scheme}://${host}/v1/graphql`, { headers: { ...defaultHeaders, ...headers, }, }) - .request(query) + .request(query, variables, headers) .then((data) => ({ data })); }, }; diff --git a/src/connection/httpClient.ts b/src/connection/httpClient.ts index a8310b4f..8b4d3817 100644 --- a/src/connection/httpClient.ts +++ b/src/connection/httpClient.ts @@ -1,34 +1,15 @@ import fetch from 'isomorphic-fetch'; -import { ConnectionParams } from '../index'; +import { ConnectionParams } from '..'; export interface HttpClient { patch: (path: string, payload: any, bearerToken?: string) => any; head: (path: string, payload: any, bearerToken?: string) => any; - post: ( - path: string, - payload: any, - expectReturnContent?: boolean, - bearerToken?: string - ) => any; - get: ( - path: string, - expectReturnContent?: boolean, - bearerToken?: string - ) => any; + post: (path: string, payload: any, expectReturnContent?: boolean, bearerToken?: string) => any; + get: (path: string, expectReturnContent?: boolean, bearerToken?: string) => any; externalPost: (externalUrl: string, body: any, contentType: any) => any; getRaw: (path: string, bearerToken?: string) => any; - delete: ( - path: string, - payload: any, - expectReturnContent?: boolean, - bearerToken?: string - ) => any; - put: ( - path: string, - payload: any, - expectReturnContent?: boolean, - bearerToken?: string - ) => any; + delete: (path: string, payload: any, expectReturnContent?: boolean, bearerToken?: string) => any; + put: (path: string, payload: any, expectReturnContent?: boolean, bearerToken?: string) => any; externalGet: (externalUrl: string) => Promise; } @@ -37,12 +18,7 @@ export const httpClient = (config: ConnectionParams): HttpClient => { const url = makeUrl(baseUri); return { - post: ( - path: string, - payload: any, - expectReturnContent = true, - bearerToken = '' - ) => { + post: (path: string, payload: any, expectReturnContent = true, bearerToken = '') => { const request = { method: 'POST', headers: { @@ -52,16 +28,9 @@ export const httpClient = (config: ConnectionParams): HttpClient => { body: JSON.stringify(payload), }; addAuthHeaderIfNeeded(request, bearerToken); - return fetch(url(path), request).then( - makeCheckStatus(expectReturnContent) - ); + return fetch(url(path), request).then(makeCheckStatus(expectReturnContent)); }, - put: ( - path: string, - payload: any, - expectReturnContent = true, - bearerToken = '' - ) => { + put: (path: string, payload: any, expectReturnContent = true, bearerToken = '') => { const request = { method: 'PUT', headers: { @@ -71,9 +40,7 @@ export const httpClient = (config: ConnectionParams): HttpClient => { body: JSON.stringify(payload), }; addAuthHeaderIfNeeded(request, bearerToken); - return fetch(url(path), request).then( - makeCheckStatus(expectReturnContent) - ); + return fetch(url(path), request).then(makeCheckStatus(expectReturnContent)); }, patch: (path: string, payload: any, bearerToken = '') => { const request = { @@ -87,12 +54,7 @@ export const httpClient = (config: ConnectionParams): HttpClient => { addAuthHeaderIfNeeded(request, bearerToken); return fetch(url(path), request).then(makeCheckStatus(false)); }, - delete: ( - path: string, - payload: any, - expectReturnContent = false, - bearerToken = '' - ) => { + delete: (path: string, payload: any, expectReturnContent = false, bearerToken = '') => { const request = { method: 'DELETE', headers: { @@ -102,9 +64,7 @@ export const httpClient = (config: ConnectionParams): HttpClient => { body: payload ? JSON.stringify(payload) : undefined, }; addAuthHeaderIfNeeded(request, bearerToken); - return fetch(url(path), request).then( - makeCheckStatus(expectReturnContent) - ); + return fetch(url(path), request).then(makeCheckStatus(expectReturnContent)); }, head: (path: string, payload: any, bearerToken = '') => { const request = { @@ -116,9 +76,7 @@ export const httpClient = (config: ConnectionParams): HttpClient => { body: payload ? JSON.stringify(payload) : undefined, }; addAuthHeaderIfNeeded(request, bearerToken); - return fetch(url(path), request).then( - handleHeadResponse(false /* , true*/) - ); // FIXME 1 extra param + return fetch(url(path), request).then(handleHeadResponse(false)); }, get: (path: string, expectReturnContent = true, bearerToken = '') => { const request = { @@ -128,9 +86,7 @@ export const httpClient = (config: ConnectionParams): HttpClient => { }, }; addAuthHeaderIfNeeded(request, bearerToken); - return fetch(url(path), request).then( - makeCheckStatus(expectReturnContent) - ); + return fetch(url(path), request).then(makeCheckStatus(expectReturnContent)); }, getRaw: (path: string, bearerToken = '') => { // getRaw does not handle the status leaving this to the caller diff --git a/src/connection/index.ts b/src/connection/index.ts index d08c883f..732b86f5 100644 --- a/src/connection/index.ts +++ b/src/connection/index.ts @@ -3,7 +3,8 @@ import OpenidConfigurationGetter from '../misc/openidConfigurationGetter'; import httpClient, { HttpClient } from './httpClient'; import gqlClient, { GraphQLClient } from './gqlClient'; -import { ConnectionParams } from '../index'; +import { ConnectionParams } from '..'; +import { Variables } from 'graphql-request'; export default class Connection { private apiKey?: string; @@ -21,9 +22,7 @@ export default class Connection { private parseAuthParams(params: ConnectionParams): boolean { if (params.authClientSecret && params.apiKey) { - throw new Error( - 'must provide one of authClientSecret (OIDC) or apiKey, cannot provide both' - ); + throw new Error('must provide one of authClientSecret (OIDC) or apiKey, cannot provide both'); } if (params.authClientSecret) { this.oidcAuth = new OidcAuthenticator(this.http, params.authClientSecret); @@ -46,36 +45,28 @@ export default class Connection { post = (path: string, payload: any, expectReturnContent = true) => { if (this.authEnabled) { - return this.login().then((token) => - this.http.post(path, payload, expectReturnContent, token) - ); + return this.login().then((token) => this.http.post(path, payload, expectReturnContent, token)); } return this.http.post(path, payload, expectReturnContent); }; put = (path: string, payload: any, expectReturnContent = true) => { if (this.authEnabled) { - return this.login().then((token) => - this.http.put(path, payload, expectReturnContent, token) - ); + return this.login().then((token) => this.http.put(path, payload, expectReturnContent, token)); } return this.http.put(path, payload, expectReturnContent); }; patch = (path: string, payload: any) => { if (this.authEnabled) { - return this.login().then((token) => - this.http.patch(path, payload, token) - ); + return this.login().then((token) => this.http.patch(path, payload, token)); } return this.http.patch(path, payload); }; delete = (path: string, payload: any, expectReturnContent = false) => { if (this.authEnabled) { - return this.login().then((token) => - this.http.delete(path, payload, expectReturnContent, token) - ); + return this.login().then((token) => this.http.delete(path, payload, expectReturnContent, token)); } return this.http.delete(path, payload, expectReturnContent); }; @@ -89,21 +80,19 @@ export default class Connection { get = (path: string, expectReturnContent = true) => { if (this.authEnabled) { - return this.login().then((token) => - this.http.get(path, expectReturnContent, token) - ); + return this.login().then((token) => this.http.get(path, expectReturnContent, token)); } return this.http.get(path, expectReturnContent); }; - query = (query: any) => { + query = (query: any, variables?: Variables) => { if (this.authEnabled) { return this.login().then((token) => { const headers = { Authorization: `Bearer ${token}` }; - return this.gql.query(query, headers); + return this.gql.query(query, variables, headers); }); } - return this.gql.query(query); + return this.gql.query(query, variables); }; login = async () => { @@ -118,9 +107,7 @@ export default class Connection { const localConfig = await new OpenidConfigurationGetter(this.http).do(); if (localConfig === undefined) { - console.warn( - 'client is configured for authentication, but server is not' - ); + console.warn('client is configured for authentication, but server is not'); return ''; } @@ -130,3 +117,5 @@ export default class Connection { return this.oidcAuth.getAccessToken(); }; } + +export * from './auth'; diff --git a/src/connection/journey.test.ts b/src/connection/journey.test.ts index 599ffec3..9d56e068 100644 --- a/src/connection/journey.test.ts +++ b/src/connection/journey.test.ts @@ -4,16 +4,13 @@ import { AuthClientCredentials, AuthUserPasswordCredentials, } from './auth'; -import Connection from './index'; +import Connection from '.'; -import weaviate from '../index'; +import weaviate from '..'; describe('connection', () => { it('makes a logged-in request when client host param has trailing slashes', () => { - if ( - process.env.WCS_DUMMY_CI_PW == undefined || - process.env.WCS_DUMMY_CI_PW == '' - ) { + if (process.env.WCS_DUMMY_CI_PW == undefined || process.env.WCS_DUMMY_CI_PW == '') { console.warn('Skipping because `WCS_DUMMY_CI_PW` is not set'); return; } @@ -39,10 +36,7 @@ describe('connection', () => { }); it('makes an Azure logged-in request with client credentials', () => { - if ( - process.env.AZURE_CLIENT_SECRET == undefined || - process.env.AZURE_CLIENT_SECRET == '' - ) { + if (process.env.AZURE_CLIENT_SECRET == undefined || process.env.AZURE_CLIENT_SECRET == '') { console.warn('Skipping because `AZURE_CLIENT_SECRET` is not set'); return; } @@ -67,10 +61,7 @@ describe('connection', () => { }); it('makes an Okta logged-in request with client credentials', () => { - if ( - process.env.OKTA_CLIENT_SECRET == undefined || - process.env.OKTA_CLIENT_SECRET == '' - ) { + if (process.env.OKTA_CLIENT_SECRET == undefined || process.env.OKTA_CLIENT_SECRET == '') { console.warn('Skipping because `OKTA_CLIENT_SECRET` is not set'); return; } @@ -96,10 +87,7 @@ describe('connection', () => { }); it('makes an Okta logged-in request with username/password', () => { - if ( - process.env.OKTA_DUMMY_CI_PW == undefined || - process.env.OKTA_DUMMY_CI_PW == '' - ) { + if (process.env.OKTA_DUMMY_CI_PW == undefined || process.env.OKTA_DUMMY_CI_PW == '') { console.warn('Skipping because `OKTA_DUMMY_CI_PW` is not set'); return; } @@ -125,10 +113,7 @@ describe('connection', () => { }); it('makes a WCS logged-in request with username/password', () => { - if ( - process.env.WCS_DUMMY_CI_PW == undefined || - process.env.WCS_DUMMY_CI_PW == '' - ) { + if (process.env.WCS_DUMMY_CI_PW == undefined || process.env.WCS_DUMMY_CI_PW == '') { console.warn('Skipping because `WCS_DUMMY_CI_PW` is not set'); return; } @@ -154,10 +139,7 @@ describe('connection', () => { }); it('makes a scopeless WCS logged-in request with username/password', () => { - if ( - process.env.WCS_DUMMY_CI_PW == undefined || - process.env.WCS_DUMMY_CI_PW == '' - ) { + if (process.env.WCS_DUMMY_CI_PW == undefined || process.env.WCS_DUMMY_CI_PW == '') { console.warn('Skipping because `WCS_DUMMY_CI_PW` is not set'); return; } @@ -200,10 +182,7 @@ describe('connection', () => { }); it('makes a logged-in request with access token', async () => { - if ( - process.env.WCS_DUMMY_CI_PW == undefined || - process.env.WCS_DUMMY_CI_PW == '' - ) { + if (process.env.WCS_DUMMY_CI_PW == undefined || process.env.WCS_DUMMY_CI_PW == '') { console.warn('Skipping because `WCS_DUMMY_CI_PW` is not set'); return; } @@ -242,10 +221,7 @@ describe('connection', () => { }); it('uses refresh token to fetch new access token', async () => { - if ( - process.env.WCS_DUMMY_CI_PW == undefined || - process.env.WCS_DUMMY_CI_PW == '' - ) { + if (process.env.WCS_DUMMY_CI_PW == undefined || process.env.WCS_DUMMY_CI_PW == '') { console.warn('Skipping because `WCS_DUMMY_CI_PW` is not set'); return; } @@ -326,9 +302,7 @@ describe('connection', () => { throw new Error('it should not have errord: ' + e); }); - expect(logSpy).toHaveBeenCalledWith( - 'client is configured for authentication, but server is not' - ); + expect(logSpy).toHaveBeenCalledWith('client is configured for authentication, but server is not'); }); it('warns when client access token expires, no refresh token provided', async () => { @@ -372,8 +346,6 @@ describe('connection', () => { }), apiKey: new ApiKey('some-key'), }); - }).toThrow( - 'must provide one of authClientSecret (OIDC) or apiKey, cannot provide both' - ); + }).toThrow('must provide one of authClientSecret (OIDC) or apiKey, cannot provide both'); }); }); diff --git a/src/connection/unit.test.ts b/src/connection/unit.test.ts index 2735d0c1..09268eac 100644 --- a/src/connection/unit.test.ts +++ b/src/connection/unit.test.ts @@ -5,7 +5,7 @@ import { AuthAccessTokenCredentials, ApiKey, } from './auth'; -import Connection from './index'; +import Connection from '.'; describe('mock server auth tests', () => { const server = testServer(); @@ -24,9 +24,7 @@ describe('mock server auth tests', () => { .login() .then((token) => { expect(token).toEqual('access_token_000'); - expect((conn as any).oidcAuth?.refreshToken).toEqual( - 'refresh_token_000' - ); + expect((conn as any).oidcAuth?.refreshToken).toEqual('refresh_token_000'); expect((conn as any).oidcAuth?.expiresAt).toBeGreaterThan(Date.now()); }) .catch((e) => { @@ -58,9 +56,7 @@ describe('mock server auth tests', () => { .login() .then((token) => { expect(token).toEqual('access_token_000'); - expect((conn as any).oidcAuth?.refreshToken).toEqual( - 'refresh_token_000' - ); + expect((conn as any).oidcAuth?.refreshToken).toEqual('refresh_token_000'); expect((conn as any).oidcAuth?.expiresAt).toBeGreaterThan(Date.now()); }) .catch((e) => { @@ -96,9 +92,7 @@ describe('mock server auth tests', () => { .login() .then((token) => { expect(token).toEqual('access_token_000'); - expect((conn as any).oidcAuth?.refreshToken).toEqual( - 'refresh_token_000' - ); + expect((conn as any).oidcAuth?.refreshToken).toEqual('refresh_token_000'); expect((conn as any).oidcAuth?.expiresAt).toBeGreaterThan(Date.now()); }) .catch((e) => { diff --git a/src/data/checker.ts b/src/data/checker.ts index 67c3768c..b573d691 100644 --- a/src/data/checker.ts +++ b/src/data/checker.ts @@ -1,12 +1,13 @@ import Connection from '../connection'; +import { ObjectsPath } from './path'; import { CommandBase } from '../validation/commandBase'; export default class Checker extends CommandBase { - private className?: string; - private id?: string; - private objectsPath: any; + private className!: string; + private id!: string; + private objectsPath: ObjectsPath; - constructor(client: Connection, objectsPath: any) { + constructor(client: Connection, objectsPath: ObjectsPath) { super(client); this.objectsPath = objectsPath; } @@ -21,11 +22,7 @@ export default class Checker extends CommandBase { return this; }; - validateIsSet = ( - prop: string | undefined | null, - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null, name: string, setter: string) => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } @@ -41,16 +38,12 @@ export default class Checker extends CommandBase { do = () => { if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } this.validate(); - return this.objectsPath - .buildCheck(this.id!, this.className!) - .then((path: string) => { - return this.client.head(path, undefined); - }); + return this.objectsPath.buildCheck(this.id, this.className).then((path: string) => { + return this.client.head(path, undefined); + }); }; } diff --git a/src/data/creator.ts b/src/data/creator.ts index 3afddd0d..65b06e7a 100644 --- a/src/data/creator.ts +++ b/src/data/creator.ts @@ -2,21 +2,23 @@ import { isValidStringProperty } from '../validation/string'; import Connection from '../connection'; import { ObjectsPath } from './path'; import { CommandBase } from '../validation/commandBase'; +import { Properties, WeaviateObject } from '../openapi/types'; +import { ConsistencyLevel } from './replication'; export default class Creator extends CommandBase { private className?: string; - private consistencyLevel?: string; + private consistencyLevel?: ConsistencyLevel; private id?: string; private objectsPath: ObjectsPath; - private properties?: any; - private vector: any; + private properties?: Properties; + private vector?: number[]; constructor(client: Connection, objectsPath: ObjectsPath) { super(client); this.objectsPath = objectsPath; } - withVector = (vector: any) => { + withVector = (vector: number[]) => { this.vector = vector; return this; }; @@ -26,7 +28,7 @@ export default class Creator extends CommandBase { return this; }; - withProperties = (properties: any) => { + withProperties = (properties: Properties) => { this.properties = properties; return this; }; @@ -36,16 +38,14 @@ export default class Creator extends CommandBase { return this; }; - withConsistencyLevel = (cl: string) => { + withConsistencyLevel = (cl: ConsistencyLevel) => { this.consistencyLevel = cl; return this; }; validateClassName = () => { if (!isValidStringProperty(this.className)) { - this.addError( - 'className must be set - set with .withClassName(className)' - ); + this.addError('className must be set - set with .withClassName(className)'); } }; @@ -60,12 +60,10 @@ export default class Creator extends CommandBase { this.validateClassName(); }; - do = () => { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } return this.objectsPath diff --git a/src/data/deleter.ts b/src/data/deleter.ts index f124063d..b7f2e961 100644 --- a/src/data/deleter.ts +++ b/src/data/deleter.ts @@ -1,13 +1,15 @@ import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { ObjectsPath } from './path'; +import { ConsistencyLevel } from './replication'; export default class Deleter extends CommandBase { - private className?: string; - private consistencyLevel?: string; - private id?: string; - private objectsPath: any; + private className!: string; + private consistencyLevel?: ConsistencyLevel; + private id!: string; + private objectsPath: ObjectsPath; - constructor(client: Connection, objectsPath: any) { + constructor(client: Connection, objectsPath: ObjectsPath) { super(client); this.objectsPath = objectsPath; } @@ -22,16 +24,12 @@ export default class Deleter extends CommandBase { return this; }; - withConsistencyLevel = (cl: string) => { + withConsistencyLevel = (cl: ConsistencyLevel) => { this.consistencyLevel = cl; return this; }; - validateIsSet = ( - prop: string | undefined | null, - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null, name: string, setter: string) => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } @@ -47,14 +45,12 @@ export default class Deleter extends CommandBase { do = () => { if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } this.validate(); return this.objectsPath - .buildDelete(this.id!, this.className!, this.consistencyLevel!) + .buildDelete(this.id, this.className, this.consistencyLevel) .then((path: string) => { return this.client.delete(path, undefined, false); }); diff --git a/src/data/getter.ts b/src/data/getter.ts index b6bbcd67..71d5fcaa 100644 --- a/src/data/getter.ts +++ b/src/data/getter.ts @@ -1,10 +1,11 @@ import Connection from '../connection'; import { ObjectsPath } from './path'; import { CommandBase } from '../validation/commandBase'; +import { WeaviateObjectsList } from '../openapi/types'; export default class Getter extends CommandBase { - private additionals: any[]; - private after?: string; + private additional: string[]; + private after!: string; private className?: string; private limit?: number; private objectsPath: ObjectsPath; @@ -12,7 +13,7 @@ export default class Getter extends CommandBase { constructor(client: Connection, objectsPath: ObjectsPath) { super(client); this.objectsPath = objectsPath; - this.additionals = []; + this.additional = []; } withClassName = (className: string) => { @@ -30,29 +31,26 @@ export default class Getter extends CommandBase { return this; }; - extendAdditionals = (prop: any) => { - this.additionals = [...this.additionals, prop]; + extendAdditional = (prop: string) => { + this.additional = [...this.additional, prop]; return this; }; - withAdditional = (additionalFlag: any) => - this.extendAdditionals(additionalFlag); + withAdditional = (additionalFlag: any) => this.extendAdditional(additionalFlag); - withVector = () => this.extendAdditionals('vector'); + withVector = () => this.extendAdditional('vector'); validate() { // nothing to validate } - do = () => { + do = (): Promise => { if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } return this.objectsPath - .buildGet(this.className, this.limit, this.additionals!, this.after!) + .buildGet(this.className, this.limit, this.additional, this.after) .then((path: string) => { return this.client.get(path); }); diff --git a/src/data/getterById.ts b/src/data/getterById.ts index 44e1cde4..34319a54 100644 --- a/src/data/getterById.ts +++ b/src/data/getterById.ts @@ -1,18 +1,21 @@ import Connection from '../connection'; +import { WeaviateObject } from '../openapi/types'; import { CommandBase } from '../validation/commandBase'; +import { ObjectsPath } from './path'; +import { ConsistencyLevel } from './replication'; export default class GetterById extends CommandBase { - private additionals: any[]; - private className?: string; - private consistencyLevel?: string; - private id?: string; - private nodeName: any; - private objectsPath: any; + private additional: string[]; + private className!: string; + private id!: string; + private consistencyLevel?: ConsistencyLevel; + private nodeName?: string; + private objectsPath: ObjectsPath; - constructor(client: Connection, objectsPath: any) { + constructor(client: Connection, objectsPath: ObjectsPath) { super(client); this.objectsPath = objectsPath; - this.additionals = []; + this.additional = []; } withId = (id: string) => { @@ -25,22 +28,21 @@ export default class GetterById extends CommandBase { return this; }; - extendAdditionals = (prop: any) => { - this.additionals = [...this.additionals, prop]; + extendAdditional = (prop: string) => { + this.additional = [...this.additional, prop]; return this; }; - withAdditional = (additionalFlag: any) => - this.extendAdditionals(additionalFlag); + withAdditional = (additionalFlag: string) => this.extendAdditional(additionalFlag); - withVector = () => this.extendAdditionals('vector'); + withVector = () => this.extendAdditional('vector'); - withConsistencyLevel = (cl: any) => { + withConsistencyLevel = (cl: ConsistencyLevel) => { this.consistencyLevel = cl; return this; }; - withNodeName = (nodeName: any) => { + withNodeName = (nodeName: string) => { this.nodeName = nodeName; return this; }; @@ -57,20 +59,18 @@ export default class GetterById extends CommandBase { buildPath = (): Promise => { return this.objectsPath.buildGetOne( - this.id!, - this.className!, - this.additionals, + this.id, + this.className, + this.additional, this.consistencyLevel, this.nodeName ); }; - do = () => { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } return this.buildPath().then((path) => { diff --git a/src/data/index.ts b/src/data/index.ts index 34073a4b..dfeb19f4 100644 --- a/src/data/index.ts +++ b/src/data/index.ts @@ -14,7 +14,6 @@ import { ObjectsPath, ReferencesPath } from './path'; import { BeaconPath } from '../utils/beaconPath'; import { DbVersionSupport } from '../utils/dbVersion'; import Connection from '../connection'; -import { WeaviateClient } from '../index'; export interface Data { creator: () => Creator; @@ -45,12 +44,9 @@ const data = (client: Connection, dbVersionSupport: DbVersionSupport): Data => { getterById: () => new GetterById(client, objectsPath), deleter: () => new Deleter(client, objectsPath), checker: () => new Checker(client, objectsPath), - referenceCreator: () => - new ReferenceCreator(client, referencesPath, beaconPath), - referenceReplacer: () => - new ReferenceReplacer(client, referencesPath, beaconPath), - referenceDeleter: () => - new ReferenceDeleter(client, referencesPath, beaconPath), + referenceCreator: () => new ReferenceCreator(client, referencesPath, beaconPath), + referenceReplacer: () => new ReferenceReplacer(client, referencesPath, beaconPath), + referenceDeleter: () => new ReferenceDeleter(client, referencesPath, beaconPath), referencePayloadBuilder: () => new ReferencePayloadBuilder(client), }; }; diff --git a/src/data/journey.test.ts b/src/data/journey.test.ts index fb7eee38..ac3ab2c7 100644 --- a/src/data/journey.test.ts +++ b/src/data/journey.test.ts @@ -1,4 +1,6 @@ -import weaviate, { WeaviateClient } from '../index'; +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import weaviate, { WeaviateClient } from '..'; +import { WeaviateObject, WeaviateObjectsList, WeaviateError, Properties } from '../openapi/types'; const thingClassName = 'DataJourneyTestThing'; const refSourceClassName = 'DataJourneyTestRefSource'; @@ -24,10 +26,10 @@ describe('data', () => { .withClassName(thingClassName) .withProperties(properties) .do() - .then((res: any) => { + .then((res: boolean) => { expect(res).toEqual(true); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -48,7 +50,7 @@ describe('data', () => { }); }); - let implicitThingId: any; + let implicitThingId: string | undefined; it('creates a new thing object without an explicit id', () => { const properties = { stringProp: 'without-id' }; @@ -58,11 +60,11 @@ describe('data', () => { .withClassName(thingClassName) .withProperties(properties) .do() - .then((res: any) => { + .then((res: WeaviateObject) => { expect(res.properties).toEqual(properties); implicitThingId = res.id; }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -82,11 +84,11 @@ describe('data', () => { .withProperties(properties) .withId(id) .do() - .then((res: any) => { + .then((res: WeaviateObject) => { expect(res.properties).toEqual(properties); expect(res.id).toEqual(id); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -102,22 +104,15 @@ describe('data', () => { .withProperties(properties) .withId(id) .do() - .then((res: any) => { + .then((res: WeaviateObject) => { expect(res.properties).toEqual(properties); expect(res.id).toEqual(id); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); - it('waits for es index updates', () => { - return new Promise((resolve, reject) => { - // TODO: remove in 1.0.0 - setTimeout(resolve, 1000); - }); - }); - it('errors without a className', () => { return client.data .creator() @@ -136,7 +131,7 @@ describe('data', () => { return client.data .getter() .do() - .then((res: any) => { + .then((res: WeaviateObjectsList) => { expect(res.objects).toHaveLength(3); expect(res.objects).toEqual( expect.arrayContaining([ @@ -150,7 +145,7 @@ describe('data', () => { ]) ); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -160,7 +155,7 @@ describe('data', () => { .getter() .withClassName(thingClassName) .do() - .then((res: any) => { + .then((res: WeaviateObjectsList) => { expect(res.objects).toHaveLength(2); expect(res.objects).toEqual( expect.arrayContaining([ @@ -174,7 +169,7 @@ describe('data', () => { ]) ); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -186,7 +181,7 @@ describe('data', () => { .withLimit(100) .withAfter('00000000-0000-0000-0000-000000000000') .do() - .then((res) => { + .then((res: WeaviateObjectsList) => { expect(res.objects).toHaveLength(1); expect(res.objects).toEqual( expect.arrayContaining([ @@ -209,16 +204,19 @@ describe('data', () => { .withVector() .withLimit(2) .do() - .then((res: any) => { + .then((res: WeaviateObjectsList) => { + if (!res.objects) { + throw new Error(`response should have objects: ${JSON.stringify(res)}`); + } expect(res.objects).toHaveLength(2); - expect(res.objects[0].vector.length).toBeGreaterThan(10); - expect(res.objects[0].additional.interpretation).toBeDefined(); - expect(res.objects[0].additional.featureProjection).toBeDefined(); - expect(res.objects[0].additional.nearestNeighbors).toBeDefined(); + expect(res.objects[0].vector?.length).toBeGreaterThan(10); + expect(res.objects[0].additional?.interpretation).toBeDefined(); + expect(res.objects[0].additional?.featureProjection).toBeDefined(); + expect(res.objects[0].additional?.nearestNeighbors).toBeDefined(); // not testing for classification as that's only set if the object was // actually classified, this one wasn't }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -233,14 +231,17 @@ describe('data', () => { .withAdditional('featureProjection') .withVector() .do() - .then((res: any) => { + .then((res: WeaviateObjectsList) => { + if (!res.objects) { + throw new Error(`response should have objects: ${JSON.stringify(res)}`); + } expect(res.objects).toHaveLength(2); - expect(res.objects[0].vector.length).toBeGreaterThan(10); - expect(res.objects[0].additional.interpretation).toBeDefined(); - expect(res.objects[0].additional.featureProjection).toBeDefined(); - expect(res.objects[0].additional.nearestNeighbors).toBeDefined(); + expect(res.objects[0].vector?.length).toBeGreaterThan(10); + expect(res.objects[0].additional?.interpretation).toBeDefined(); + expect(res.objects[0].additional?.featureProjection).toBeDefined(); + expect(res.objects[0].additional?.nearestNeighbors).toBeDefined(); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -250,7 +251,7 @@ describe('data', () => { .getterById() .withId('00000000-0000-0000-0000-000000000000') .do() - .then((res: any) => { + .then((res: WeaviateObject) => { expect(res).toEqual( expect.objectContaining({ id: '00000000-0000-0000-0000-000000000000', @@ -258,7 +259,7 @@ describe('data', () => { }) ); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -269,7 +270,7 @@ describe('data', () => { .withClassName(thingClassName) .withId('00000000-0000-0000-0000-000000000000') .do() - .then((res: any) => { + .then((res: WeaviateObject) => { expect(res).toEqual( expect.objectContaining({ id: '00000000-0000-0000-0000-000000000000', @@ -277,7 +278,7 @@ describe('data', () => { }) ); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -302,14 +303,14 @@ describe('data', () => { .withAdditional('nearestNeighbors') .withVector() .do() - .then((res: any) => { - expect(res.vector.length).toBeGreaterThan(10); - expect(res.additional.interpretation).toBeDefined(); - expect(res.additional.nearestNeighbors).toBeDefined(); + .then((res: WeaviateObject) => { + expect(res.vector?.length).toBeGreaterThan(10); + expect(res.additional?.interpretation).toBeDefined(); + expect(res.additional?.nearestNeighbors).toBeDefined(); // not testing for classification as that's only set if the object was // actually classified, this one wasn't }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -321,12 +322,8 @@ describe('data', () => { .then(() => { throw new Error('it should have errord'); }) - .catch((e: any) => { - expect(e).toEqual( - new Error( - 'invalid usage: id must be set - initialize with getterById(id)' - ) - ); + .catch((e: WeaviateError) => { + expect(e).toEqual(new Error('invalid usage: id must be set - initialize with getterById(id)')); }); }); @@ -336,23 +333,18 @@ describe('data', () => { .getterById() .withId(id) .do() - .then((res: any) => { + .then((res: WeaviateObject) => { // alter the schema - const properties = res.properties; - properties.stringProp = 'thing-updated'; - return client.data - .updater() - .withId(id) - .withClassName(thingClassName) - .withProperties(properties) - .do(); + const properties: Properties = res.properties!; + properties!.stringProp = 'thing-updated'; + return client.data.updater().withId(id).withClassName(thingClassName).withProperties(properties).do(); }) - .then((res: any) => { + .then((res: WeaviateObject) => { expect(res.properties).toEqual({ stringProp: 'thing-updated', }); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -364,22 +356,17 @@ describe('data', () => { .withId(id) .withClassName(thingClassName) .do() - .then((res: any) => { - const properties = res.properties; - properties.stringProp = 'thing-updated-with-class-name'; - return client.data - .updater() - .withId(id) - .withClassName(thingClassName) - .withProperties(properties) - .do(); + .then((res: WeaviateObject) => { + const properties: Properties = res.properties!; + properties!.stringProp = 'thing-updated-with-class-name'; + return client.data.updater().withId(id).withClassName(thingClassName).withProperties(properties).do(); }) - .then((res: any) => { + .then((res: WeaviateObject) => { expect(res.properties).toEqual({ stringProp: 'thing-updated-with-class-name', }); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -390,18 +377,13 @@ describe('data', () => { .getterById() .withId(id) .do() - .then((res: any) => { + .then((res: WeaviateObject) => { // alter the schema - const properties = res.properties; - properties.intProp = 7; - return client.data - .merger() - .withId(id) - .withClassName(thingClassName) - .withProperties(properties) - .do(); + const properties: Properties = res.properties!; + properties!.intProp = 7; + return client.data.merger().withId(id).withClassName(thingClassName).withProperties(properties).do(); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -414,45 +396,39 @@ describe('data', () => { .referenceCreator() .withId(sourceId) .withReferenceProperty('refProp') - .withReference( - client.data.referencePayloadBuilder().withId(targetId).payload() - ) + .withReference(client.data.referencePayloadBuilder().withId(targetId).payload()) .do() - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); it('replaces all references of a thing by id only', () => { const sourceId = '599a0c64-5ed5-4d30-978b-6c9c45516db1'; - const targetId: any = implicitThingId; + const targetId: string | undefined = implicitThingId; return client.data .referenceReplacer() .withId(sourceId) .withReferenceProperty('refProp') - .withReferences([ - client.data.referencePayloadBuilder().withId(targetId).payload(), - ]) + .withReferences([client.data.referencePayloadBuilder().withId(targetId!).payload()]) .do() - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); it('deletes a single reference of a thing by id only', () => { const sourceId = '599a0c64-5ed5-4d30-978b-6c9c45516db1'; - const targetId: any = implicitThingId; + const targetId: string | undefined = implicitThingId; return client.data .referenceDeleter() .withId(sourceId) .withReferenceProperty('refProp') - .withReference( - client.data.referencePayloadBuilder().withId(targetId).payload() - ) + .withReference(client.data.referencePayloadBuilder().withId(targetId!).payload()) .do() - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -467,21 +443,17 @@ describe('data', () => { .withClassName(refSourceClassName) .withReferenceProperty('refProp') .withReference( - client.data - .referencePayloadBuilder() - .withId(targetId) - .withClassName(thingClassName) - .payload() + client.data.referencePayloadBuilder().withId(targetId).withClassName(thingClassName).payload() ) .do() - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); it('replaces all references of a thing by id and class name', () => { const sourceId = '599a0c64-5ed5-4d30-978b-6c9c45516db1'; - const targetId: any = implicitThingId; + const targetId: string | undefined = implicitThingId; return client.data .referenceReplacer() @@ -489,21 +461,17 @@ describe('data', () => { .withClassName(refSourceClassName) .withReferenceProperty('refProp') .withReferences([ - client.data - .referencePayloadBuilder() - .withId(targetId) - .withClassName(thingClassName) - .payload(), + client.data.referencePayloadBuilder().withId(targetId!).withClassName(thingClassName).payload(), ]) .do() - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); it('deletes a single reference of a thing by id and class name', () => { const sourceId = '599a0c64-5ed5-4d30-978b-6c9c45516db1'; - const targetId: any = implicitThingId; + const targetId: string | undefined = implicitThingId; return client.data .referenceDeleter() @@ -511,14 +479,10 @@ describe('data', () => { .withClassName(refSourceClassName) .withReferenceProperty('refProp') .withReference( - client.data - .referencePayloadBuilder() - .withId(targetId) - .withClassName(thingClassName) - .payload() + client.data.referencePayloadBuilder().withId(targetId!).withClassName(thingClassName).payload() ) .do() - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -533,7 +497,7 @@ describe('data', () => { fail('it should exist in DB'); } }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -549,7 +513,7 @@ describe('data', () => { fail('it should exist in DB'); } }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -559,7 +523,7 @@ describe('data', () => { .deleter() .withId('00000000-0000-0000-0000-000000000000') .do() - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -574,7 +538,7 @@ describe('data', () => { fail('it should not exist in DB'); } }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -589,11 +553,11 @@ describe('data', () => { .withProperties(properties) .withId(id) .do() - .then((res: any) => { + .then((res: WeaviateObject) => { expect(res.properties).toEqual(properties); expect(res.id).toEqual(id); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); @@ -602,7 +566,7 @@ describe('data', () => { .withId(id) .withClassName(thingClassName) .do() - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -617,7 +581,7 @@ describe('data', () => { fail('it should not exist in DB'); } }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -627,10 +591,10 @@ describe('data', () => { client.data .getter() .do() - .then((res: any) => { + .then((res: WeaviateObjectsList) => { expect(res.objects).toHaveLength(2); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }), ]); @@ -640,8 +604,7 @@ describe('data', () => { const properties = { foo: 'bar' }; const id = 'aaaac06c-463f-466c-9092-5930dbac3887'; const vector = [ - -0.26736435, -0.112380296, 0.29648793, 0.39212644, 0.0033650293, - -0.07112332, 0.07513781, 0.22459874, + -0.26736435, -0.112380296, 0.29648793, 0.39212644, 0.0033650293, -0.07112332, 0.07513781, 0.22459874, ]; return client.data @@ -651,12 +614,12 @@ describe('data', () => { .withVector(vector) .withId(id) .do() - .then((res: any) => { + .then((res: WeaviateObject) => { expect(res.properties).toEqual(properties); expect(res.vector).toEqual(vector); expect(res.id).toEqual(id); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -664,8 +627,7 @@ describe('data', () => { it('verifies that class with custom vector has been created', () => { const id = 'aaaac06c-463f-466c-9092-5930dbac3887'; const vector = [ - -0.26736435, -0.112380296, 0.29648793, 0.39212644, 0.0033650293, - -0.07112332, 0.07513781, 0.22459874, + -0.26736435, -0.112380296, 0.29648793, 0.39212644, 0.0033650293, -0.07112332, 0.07513781, 0.22459874, ]; return client.data @@ -673,10 +635,10 @@ describe('data', () => { .withId(id) .withVector() .do() - .then((res: any) => { + .then((res: WeaviateObject) => { expect(res.vector).toEqual(vector); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -686,7 +648,7 @@ describe('data', () => { .deleter() .withId('aaaac06c-463f-466c-9092-5930dbac3887') .do() - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -705,7 +667,7 @@ describe('data', () => { expect(path).toContain('?include=vector'); expect(path).toContain('&node_name=node1'); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -718,13 +680,13 @@ describe('data', () => { .withClassName(thingClassName) .withId(id) .withVector() - .withConsistencyLevel(weaviate.replication.ConsistencyLevel.QUORUM) + .withConsistencyLevel('QUORUM') .buildPath() .then((path: string) => { expect(path).toContain('?include=vector'); expect(path).toContain('consistency_level=QUORUM'); }) - .catch((e: any) => { + .catch((e: WeaviateError) => { throw new Error('it should not have errord: ' + e); }); }); @@ -733,8 +695,7 @@ describe('data', () => { const id = '144d1944-3ab4-4aa1-8095-92429d6cbaba'; const properties = { foo: 'bar' }; const vector = [ - -0.26736435, -0.112380296, 0.29648793, 0.39212644, 0.0033650293, - -0.07112332, 0.07513781, 0.22459874, + -0.26736435, -0.112380296, 0.29648793, 0.39212644, 0.0033650293, -0.07112332, 0.07513781, 0.22459874, ]; await client.data @@ -743,7 +704,7 @@ describe('data', () => { .withProperties(properties) .withVector(vector) .withId(id) - .withConsistencyLevel(weaviate.replication.ConsistencyLevel.ALL) + .withConsistencyLevel('ALL') .do() .then((res) => { expect(res.properties).toEqual(properties); @@ -772,8 +733,7 @@ describe('data', () => { const id = '7a78b029-e7b4-499f-9bd8-70ea11b12345'; const properties = { foo: 'bar' }; const vector = [ - -0.26736435, -0.112380296, 0.29648793, 0.39212644, 0.0033650293, - -0.07112332, 0.07513781, 0.22459874, + -0.26736435, -0.112380296, 0.29648793, 0.39212644, 0.0033650293, -0.07112332, 0.07513781, 0.22459874, ]; await client.data @@ -788,7 +748,7 @@ describe('data', () => { expect(res.vector).toEqual(vector); expect(res.id).toEqual(id); }) - .catch((e: any) => fail('it should not have errord: ' + e)); + .catch((e: WeaviateError) => fail('it should not have errord: ' + e)); await client.data .getterById() @@ -803,24 +763,23 @@ describe('data', () => { }) ); }) - .catch((e: any) => fail('it should not have errord: ' + e)); + .catch((e: WeaviateError) => fail('it should not have errord: ' + e)); return client.data .deleter() .withClassName(classCustomVectorClassName) .withId(id) - .withConsistencyLevel(weaviate.replication.ConsistencyLevel.QUORUM) + .withConsistencyLevel('QUORUM') .do() .then() - .catch((e: any) => fail('it should not have errord: ' + e)); + .catch((e: WeaviateError) => fail('it should not have errord: ' + e)); }); it('patches object with consistency_level set', async () => { const id = '7a78b029-e7b4-499f-9bd8-70ea11b12345'; - const properties: any = { foo: 'bar' }; + const properties: Properties = { foo: 'bar' }; const vector = [ - -0.26736435, -0.112380296, 0.29648793, 0.39212644, 0.0033650293, - -0.07112332, 0.07513781, 0.22459874, + -0.26736435, -0.112380296, 0.29648793, 0.39212644, 0.0033650293, -0.07112332, 0.07513781, 0.22459874, ]; await client.data @@ -835,7 +794,7 @@ describe('data', () => { expect(res.vector).toEqual(vector); expect(res.id).toEqual(id); }) - .catch((e: any) => fail('it should not have errord: ' + e)); + .catch((e: WeaviateError) => fail('it should not have errord: ' + e)); await client.data .getterById() @@ -850,16 +809,16 @@ describe('data', () => { }) ); }) - .catch((e: any) => fail('it should not have errord: ' + e)); + .catch((e: WeaviateError) => fail('it should not have errord: ' + e)); - const newProperties: any = { foo: 'baz' }; + const newProperties: Properties = { foo: 'baz' }; await client.data .merger() .withClassName(classCustomVectorClassName) .withId(id) .withProperties(newProperties) - .withConsistencyLevel(weaviate.replication.ConsistencyLevel.QUORUM) + .withConsistencyLevel('QUORUM') .do() .then() .catch((e) => fail('it should not have errord: ' + e)); @@ -882,10 +841,9 @@ describe('data', () => { it('updates object with consistency_level set', async () => { const id = '55eaf761-11fd-48a9-bf21-60e2048db188'; - const properties: any = { foo: 'bar' }; + const properties: Properties = { foo: 'bar' }; const vector = [ - -0.26736435, -0.112380296, 0.29648793, 0.39212644, 0.0033650293, - -0.07112332, 0.07513781, 0.22459874, + -0.26736435, -0.112380296, 0.29648793, 0.39212644, 0.0033650293, -0.07112332, 0.07513781, 0.22459874, ]; await client.data @@ -900,7 +858,7 @@ describe('data', () => { expect(res.vector).toEqual(vector); expect(res.id).toEqual(id); }) - .catch((e: any) => fail('it should not have errord: ' + e)); + .catch((e: WeaviateError) => fail('it should not have errord: ' + e)); await client.data .getterById() @@ -915,16 +873,16 @@ describe('data', () => { }) ); }) - .catch((e: any) => fail('it should not have errord: ' + e)); + .catch((e: WeaviateError) => fail('it should not have errord: ' + e)); - const newProperties: any = { foo: 'baz' }; + const newProperties: Properties = { foo: 'baz' }; await client.data .updater() .withClassName(classCustomVectorClassName) .withId(id) .withProperties(newProperties) - .withConsistencyLevel(weaviate.replication.ConsistencyLevel.QUORUM) + .withConsistencyLevel('QUORUM') .do() .then() .catch((e) => fail('it should not have errord: ' + e)); @@ -942,7 +900,7 @@ describe('data', () => { }) ); }) - .catch((e: any) => fail('it should not have errord: ' + e)); + .catch((e: WeaviateError) => fail('it should not have errord: ' + e)); }); it('creates reference with consistency_level set', async () => { @@ -977,10 +935,8 @@ describe('data', () => { .referenceCreator() .withId(id2) .withReferenceProperty('refProp') - .withConsistencyLevel(weaviate.replication.ConsistencyLevel.ONE) - .withReference( - client.data.referencePayloadBuilder().withId(id1).payload() - ) + .withConsistencyLevel('ONE') + .withReference(client.data.referencePayloadBuilder().withId(id1).payload()) .do() .catch((e) => fail('it should not have errord: ' + e)); @@ -1039,10 +995,8 @@ describe('data', () => { .referenceReplacer() .withId(id2) .withReferenceProperty('refProp') - .withConsistencyLevel(weaviate.replication.ConsistencyLevel.ONE) - .withReferences( - client.data.referencePayloadBuilder().withId(id1).payload() - ) + .withConsistencyLevel('ONE') + .withReferences(client.data.referencePayloadBuilder().withId(id1).payload()) .do() .catch((e) => fail('it should not have errord: ' + e)); }); @@ -1079,10 +1033,8 @@ describe('data', () => { .referenceCreator() .withId(id2) .withReferenceProperty('refProp') - .withConsistencyLevel(weaviate.replication.ConsistencyLevel.ONE) - .withReference( - client.data.referencePayloadBuilder().withId(id1).payload() - ) + .withConsistencyLevel('ONE') + .withReference(client.data.referencePayloadBuilder().withId(id1).payload()) .do() .catch((e) => fail('it should not have errord: ' + e)); @@ -1112,10 +1064,8 @@ describe('data', () => { .referenceDeleter() .withId(id2) .withReferenceProperty('refProp') - .withConsistencyLevel(weaviate.replication.ConsistencyLevel.ONE) - .withReference( - client.data.referencePayloadBuilder().withId(id1).payload() - ) + .withConsistencyLevel('ONE') + .withReference(client.data.referencePayloadBuilder().withId(id1).payload()) .do() .catch((e) => fail('it should not have errord: ' + e)); }); @@ -1124,10 +1074,7 @@ describe('data', () => { return Promise.all([ client.schema.classDeleter().withClassName(thingClassName).do(), client.schema.classDeleter().withClassName(refSourceClassName).do(), - client.schema - .classDeleter() - .withClassName(classCustomVectorClassName) - .do(), + client.schema.classDeleter().withClassName(classCustomVectorClassName).do(), ]); }); }); @@ -1160,9 +1107,7 @@ const setup = async (client: WeaviateClient) => { ], }; - await Promise.all([ - client.schema.classCreator().withClass(classCustomVector).do(), - ]); + await Promise.all([client.schema.classCreator().withClass(classCustomVector).do()]); const refSource = { class: refSourceClassName, diff --git a/src/data/merger.ts b/src/data/merger.ts index 02a3deaf..6d8c4ab7 100644 --- a/src/data/merger.ts +++ b/src/data/merger.ts @@ -2,20 +2,22 @@ import Connection from '../connection'; import { isValidStringProperty } from '../validation/string'; import { ObjectsPath } from './path'; import { CommandBase } from '../validation/commandBase'; +import { Properties } from '../openapi/types'; +import { ConsistencyLevel } from './replication'; export default class Merger extends CommandBase { - private className?: string; - private consistencyLevel?: string; - private id?: string; + private className!: string; + private consistencyLevel?: ConsistencyLevel; + private id!: string; private objectsPath: ObjectsPath; - private properties?: any[]; + private properties?: Properties; constructor(client: Connection, objectsPath: ObjectsPath) { super(client); this.objectsPath = objectsPath; } - withProperties = (properties: any[]) => { + withProperties = (properties: Properties) => { this.properties = properties; return this; }; @@ -30,16 +32,14 @@ export default class Merger extends CommandBase { return this; }; - withConsistencyLevel = (cl: string) => { + withConsistencyLevel = (cl: ConsistencyLevel) => { this.consistencyLevel = cl; return this; }; validateClassName = () => { if (!isValidStringProperty(this.className)) { - this.addError( - 'className must be set - set with withClassName(className)' - ); + this.addError('className must be set - set with withClassName(className)'); } }; @@ -64,13 +64,11 @@ export default class Merger extends CommandBase { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } return this.objectsPath - .buildMerge(this.id!, this.className!, this.consistencyLevel!) + .buildMerge(this.id, this.className, this.consistencyLevel) .then((path: string) => this.client.patch(path, this.payload())); }; } diff --git a/src/data/path.test.ts b/src/data/path.test.ts index 112cbe4d..d8d3cb8b 100644 --- a/src/data/path.test.ts +++ b/src/data/path.test.ts @@ -6,13 +6,9 @@ import { ObjectsPath, ReferencesPath } from './path'; // The actual value is not used for anything else const version = '1.18.0'; -const objectsPathBuilder = new ObjectsPath( - new DbVersionSupport(new TestDbVersionProvider(version)) -); +const objectsPathBuilder = new ObjectsPath(new DbVersionSupport(new TestDbVersionProvider(version))); -const refsPathBuilder = new ReferencesPath( - new DbVersionSupport(new TestDbVersionProvider(version)) -); +const refsPathBuilder = new ReferencesPath(new DbVersionSupport(new TestDbVersionProvider(version))); describe('paths', () => { it('builds object create', () => { @@ -25,29 +21,21 @@ describe('paths', () => { it('builds object delete', () => { return objectsPathBuilder .buildDelete('123456', 'SomeClass', 'ALL') - .then((path) => - expect(path).toEqual('/objects/SomeClass/123456?consistency_level=ALL') - ) + .then((path) => expect(path).toEqual('/objects/SomeClass/123456?consistency_level=ALL')) .catch((e) => fail(`unexpected error: ${e}`)); }); it('builds object merge', () => { return objectsPathBuilder .buildMerge('123456', 'SomeClass', 'QUORUM') - .then((path) => - expect(path).toEqual( - '/objects/SomeClass/123456?consistency_level=QUORUM' - ) - ) + .then((path) => expect(path).toEqual('/objects/SomeClass/123456?consistency_level=QUORUM')) .catch((e) => fail(`unexpected error: ${e}`)); }); it('builds object update', () => { return objectsPathBuilder .buildUpdate('123456', 'SomeClass', 'ONE') - .then((path) => - expect(path).toEqual('/objects/SomeClass/123456?consistency_level=ONE') - ) + .then((path) => expect(path).toEqual('/objects/SomeClass/123456?consistency_level=ONE')) .catch((e) => fail(`unexpected error: ${e}`)); }); @@ -55,9 +43,7 @@ describe('paths', () => { return refsPathBuilder .build('123456', 'SomeClass', 'SomeProp', 'ALL') .then((path) => - expect(path).toEqual( - '/objects/SomeClass/123456/references/SomeProp?consistency_level=ALL' - ) + expect(path).toEqual('/objects/SomeClass/123456/references/SomeProp?consistency_level=ALL') ) .catch((e) => fail(`unexpected error: ${e}`)); }); diff --git a/src/data/path.ts b/src/data/path.ts index 3c3aacf5..4e3c3ec8 100644 --- a/src/data/path.ts +++ b/src/data/path.ts @@ -1,5 +1,6 @@ import { isValidStringProperty } from '../validation/string'; import { DbVersionSupport } from '../utils/dbVersion'; +import { ConsistencyLevel } from './replication'; const objectsPathPrefix = '/objects'; @@ -13,11 +14,7 @@ export class ObjectsPath { buildCreate(consistencyLevel: string | undefined): Promise { return this.build({ consistencyLevel }, [this.addQueryParams]); } - buildDelete( - id: string, - className: string, - consistencyLevel: string | undefined - ): Promise { + buildDelete(id: string, className: string, consistencyLevel: string | undefined): Promise { return this.build({ id, className, consistencyLevel }, [ this.addClassNameDeprecatedNotSupportedCheck, this.addId, @@ -25,53 +22,32 @@ export class ObjectsPath { ]); } buildCheck(id: string, className: string): Promise { - return this.build({ id, className }, [ - this.addClassNameDeprecatedNotSupportedCheck, - this.addId, - ]); + return this.build({ id, className }, [this.addClassNameDeprecatedNotSupportedCheck, this.addId]); } buildGetOne( id: string, className: string, - additionals: any, - consistencyLevel: string | undefined, - nodeName: any - ): Promise { - return this.build( - { id, className, additionals, consistencyLevel, nodeName }, - [ - this.addClassNameDeprecatedNotSupportedCheck, - this.addId, - this.addQueryParams, - ] - ); - } - buildGet( - className: string | undefined, - limit: any, - additionals: any, - after: string + additional: string[], + consistencyLevel?: ConsistencyLevel, + nodeName?: string ): Promise { - return this.build({ className, limit, additionals, after }, [ - this.addQueryParamsForGet, + return this.build({ id, className, additional: additional, consistencyLevel, nodeName }, [ + this.addClassNameDeprecatedNotSupportedCheck, + this.addId, + this.addQueryParams, ]); } - buildUpdate( - id: string, - className: string, - consistencyLevel: string | undefined - ): Promise { + buildGet(className?: string, limit?: number, additional?: string[], after?: string): Promise { + return this.build({ className, limit, additional, after }, [this.addQueryParamsForGet]); + } + buildUpdate(id: string, className: string, consistencyLevel: string | undefined): Promise { return this.build({ id, className, consistencyLevel }, [ this.addClassNameDeprecatedCheck, this.addId, this.addQueryParams, ]); } - buildMerge( - id: string, - className: string, - consistencyLevel: string | undefined - ): Promise { + buildMerge(id: string, className: string, consistencyLevel: string | undefined): Promise { return this.build({ id, className, consistencyLevel }, [ this.addClassNameDeprecatedCheck, this.addId, @@ -80,22 +56,16 @@ export class ObjectsPath { } build(params: any, modifiers: any): Promise { - return this.dbVersionSupport - .supportsClassNameNamespacedEndpointsPromise() - .then((support: any) => { - let path = objectsPathPrefix; - modifiers.forEach((modifier: any) => { - path = modifier(params, path, support); - }); - return path; + return this.dbVersionSupport.supportsClassNameNamespacedEndpointsPromise().then((support: any) => { + let path = objectsPathPrefix; + modifiers.forEach((modifier: any) => { + path = modifier(params, path, support); }); + return path; + }); } - addClassNameDeprecatedNotSupportedCheck( - params: any, - path: string, - support: any - ) { + addClassNameDeprecatedNotSupportedCheck(params: any, path: string, support: any) { if (support.supports) { if (isValidStringProperty(params.className)) { return `${path}/${params.className}`; @@ -125,8 +95,8 @@ export class ObjectsPath { } addQueryParams(params: any, path: string) { const queryParams = []; - if (Array.isArray(params.additionals) && params.additionals.length > 0) { - queryParams.push(`include=${params.additionals.join(',')}`); + if (Array.isArray(params.additional) && params.additional.length > 0) { + queryParams.push(`include=${params.additional.join(',')}`); } if (isValidStringProperty(params.nodeName)) { queryParams.push(`node_name=${params.nodeName}`); @@ -141,8 +111,8 @@ export class ObjectsPath { } addQueryParamsForGet(params: any, path: string, support: any) { const queryParams = []; - if (Array.isArray(params.additionals) && params.additionals.length > 0) { - queryParams.push(`include=${params.additionals.join(',')}`); + if (Array.isArray(params.additional) && params.additional.length > 0) { + queryParams.push(`include=${params.additional.join(',')}`); } if (typeof params.limit == 'number' && params.limit > 0) { queryParams.push(`limit=${params.limit}`); @@ -175,32 +145,30 @@ export class ReferencesPath { id: string, className: string, property: string, - consistencyLevel: string + consistencyLevel?: ConsistencyLevel ): Promise { - return this.dbVersionSupport - .supportsClassNameNamespacedEndpointsPromise() - .then((support: any) => { - let path = objectsPathPrefix; - if (support.supports) { - if (isValidStringProperty(className)) { - path = `${path}/${className}`; - } else { - support.warns.deprecatedNonClassNameNamespacedEndpointsForReferences(); - } + return this.dbVersionSupport.supportsClassNameNamespacedEndpointsPromise().then((support: any) => { + let path = objectsPathPrefix; + if (support.supports) { + if (isValidStringProperty(className)) { + path = `${path}/${className}`; } else { - support.warns.notSupportedClassNamespacedEndpointsForReferences(); - } - if (isValidStringProperty(id)) { - path = `${path}/${id}`; - } - path = `${path}/references`; - if (isValidStringProperty(property)) { - path = `${path}/${property}`; - } - if (isValidStringProperty(consistencyLevel)) { - path = `${path}?consistency_level=${consistencyLevel}`; + support.warns.deprecatedNonClassNameNamespacedEndpointsForReferences(); } - return path; - }); + } else { + support.warns.notSupportedClassNamespacedEndpointsForReferences(); + } + if (isValidStringProperty(id)) { + path = `${path}/${id}`; + } + path = `${path}/references`; + if (isValidStringProperty(property)) { + path = `${path}/${property}`; + } + if (isValidStringProperty(consistencyLevel)) { + path = `${path}?consistency_level=${consistencyLevel}`; + } + return path; + }); } } diff --git a/src/data/referenceCreator.ts b/src/data/referenceCreator.ts index 26878a08..b2f913e3 100644 --- a/src/data/referenceCreator.ts +++ b/src/data/referenceCreator.ts @@ -2,21 +2,19 @@ import { BeaconPath } from '../utils/beaconPath'; import { ReferencesPath } from './path'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { Reference } from '../openapi/types'; +import { ConsistencyLevel } from './replication'; export default class ReferenceCreator extends CommandBase { private beaconPath: BeaconPath; - private className?: string; - private consistencyLevel?: string; - private id?: string; - private reference: any; + private className!: string; + private consistencyLevel?: ConsistencyLevel; + private id!: string; + private reference!: Reference; private referencesPath: ReferencesPath; - private refProp?: string; + private refProp!: string; - constructor( - client: Connection, - referencesPath: ReferencesPath, - beaconPath: BeaconPath - ) { + constructor(client: Connection, referencesPath: ReferencesPath, beaconPath: BeaconPath) { super(client); this.referencesPath = referencesPath; this.beaconPath = beaconPath; @@ -32,7 +30,7 @@ export default class ReferenceCreator extends CommandBase { return this; } - withReference = (ref: any) => { + withReference = (ref: Reference) => { this.reference = ref; return this; }; @@ -42,16 +40,12 @@ export default class ReferenceCreator extends CommandBase { return this; }; - withConsistencyLevel = (cl: string) => { + withConsistencyLevel = (cl: ConsistencyLevel) => { this.consistencyLevel = cl; return this; }; - validateIsSet = ( - prop: string | undefined | null, - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null, name: string, setter: string) => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } @@ -59,12 +53,7 @@ export default class ReferenceCreator extends CommandBase { validate = () => { this.validateIsSet(this.id, 'id', '.withId(id)'); - this.validateIsSet(this.reference, 'reference', '.withReference(ref)'); - this.validateIsSet( - this.refProp, - 'referenceProperty', - '.withReferenceProperty(refProp)' - ); + this.validateIsSet(this.refProp, 'referenceProperty', '.withReferenceProperty(refProp)'); }; payload = () => this.reference; @@ -72,18 +61,15 @@ export default class ReferenceCreator extends CommandBase { do = () => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); + } + + if (!this.reference.beacon) { + throw new Error('reference beacon must be set'); } return Promise.all([ - this.referencesPath.build( - this.id!, - this.className!, - this.refProp!, - this.consistencyLevel! - ), + this.referencesPath.build(this.id, this.className, this.refProp, this.consistencyLevel), this.beaconPath.rebuild(this.reference.beacon), ]).then((results) => { const path = results[0]; diff --git a/src/data/referenceDeleter.ts b/src/data/referenceDeleter.ts index be6809d9..dc374826 100644 --- a/src/data/referenceDeleter.ts +++ b/src/data/referenceDeleter.ts @@ -2,21 +2,19 @@ import { BeaconPath } from '../utils/beaconPath'; import { ReferencesPath } from './path'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { Reference } from '../openapi/types'; +import { ConsistencyLevel } from './replication'; export default class ReferenceDeleter extends CommandBase { private beaconPath: BeaconPath; - private className?: string; - private consistencyLevel?: string; - private id?: string; - private reference: any; + private className!: string; + private consistencyLevel?: ConsistencyLevel; + private id!: string; + private reference!: Reference; private referencesPath: ReferencesPath; - private refProp?: any; + private refProp!: string; - constructor( - client: Connection, - referencesPath: ReferencesPath, - beaconPath: BeaconPath - ) { + constructor(client: Connection, referencesPath: ReferencesPath, beaconPath: BeaconPath) { super(client); this.referencesPath = referencesPath; this.beaconPath = beaconPath; @@ -32,26 +30,22 @@ export default class ReferenceDeleter extends CommandBase { return this; } - withReference = (ref: any) => { + withReference = (ref: Reference) => { this.reference = ref; return this; }; - withReferenceProperty = (refProp: any) => { + withReferenceProperty = (refProp: string) => { this.refProp = refProp; return this; }; - withConsistencyLevel = (cl: string) => { + withConsistencyLevel = (cl: ConsistencyLevel) => { this.consistencyLevel = cl; return this; }; - validateIsSet = ( - prop: string | undefined | null, - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null, name: string, setter: string) => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } @@ -59,12 +53,7 @@ export default class ReferenceDeleter extends CommandBase { validate = () => { this.validateIsSet(this.id, 'id', '.withId(id)'); - this.validateIsSet(this.reference, 'reference', '.withReference(ref)'); - this.validateIsSet( - this.refProp, - 'referenceProperty', - '.withReferenceProperty(refProp)' - ); + this.validateIsSet(this.refProp, 'referenceProperty', '.withReferenceProperty(refProp)'); }; payload = () => this.reference; @@ -72,18 +61,15 @@ export default class ReferenceDeleter extends CommandBase { do = () => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); + } + + if (!this.reference.beacon) { + throw new Error('reference beacon must be set'); } return Promise.all([ - this.referencesPath.build( - this.id!, - this.className!, - this.refProp!, - this.consistencyLevel! - ), + this.referencesPath.build(this.id, this.className, this.refProp, this.consistencyLevel), this.beaconPath.rebuild(this.reference.beacon), ]).then((results) => { const path = results[0]; diff --git a/src/data/referencePayloadBuilder.ts b/src/data/referencePayloadBuilder.ts index 627b43ec..f554f9c8 100644 --- a/src/data/referencePayloadBuilder.ts +++ b/src/data/referencePayloadBuilder.ts @@ -1,6 +1,7 @@ import { isValidStringProperty } from '../validation/string'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { Reference } from '../openapi/types'; export default class ReferencePayloadBuilder extends CommandBase { private className?: string; @@ -20,11 +21,7 @@ export default class ReferencePayloadBuilder extends CommandBase { return this; } - validateIsSet = ( - prop: string | undefined | null, - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null, name: string, setter: string) => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } @@ -34,7 +31,7 @@ export default class ReferencePayloadBuilder extends CommandBase { this.validateIsSet(this.id, 'id', '.withId(id)'); }; - payload = () => { + payload = (): Reference => { this.validate(); if (this.errors.length > 0) { throw new Error(this.errors.join(', ')); diff --git a/src/data/referenceReplacer.ts b/src/data/referenceReplacer.ts index e77ceb4d..f2ee3bcc 100644 --- a/src/data/referenceReplacer.ts +++ b/src/data/referenceReplacer.ts @@ -2,21 +2,19 @@ import Connection from '../connection'; import { BeaconPath } from '../utils/beaconPath'; import { ReferencesPath } from './path'; import { CommandBase } from '../validation/commandBase'; +import { Reference } from '../openapi/types'; +import { ConsistencyLevel } from './replication'; export default class ReferenceReplacer extends CommandBase { private beaconPath: BeaconPath; - private className?: string; - private consistencyLevel?: string; - private id?: string; - private references?: any[]; + private className!: string; + private consistencyLevel?: ConsistencyLevel; + private id!: string; + private references!: Reference[]; private referencesPath: ReferencesPath; - private refProp?: string; + private refProp!: string; - constructor( - client: Connection, - referencesPath: ReferencesPath, - beaconPath: BeaconPath - ) { + constructor(client: Connection, referencesPath: ReferencesPath, beaconPath: BeaconPath) { super(client); this.beaconPath = beaconPath; this.referencesPath = referencesPath; @@ -42,16 +40,12 @@ export default class ReferenceReplacer extends CommandBase { return this; }; - withConsistencyLevel = (cl: string) => { + withConsistencyLevel = (cl: ConsistencyLevel) => { this.consistencyLevel = cl; return this; }; - validateIsSet = ( - prop: string | undefined | null, - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null, name: string, setter: string) => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } @@ -59,11 +53,7 @@ export default class ReferenceReplacer extends CommandBase { validate = () => { this.validateIsSet(this.id, 'id', '.withId(id)'); - this.validateIsSet( - this.refProp, - 'referenceProperty', - '.withReferenceProperty(refProp)' - ); + this.validateIsSet(this.refProp, 'referenceProperty', '.withReferenceProperty(refProp)'); }; payload = () => this.references; @@ -71,24 +61,15 @@ export default class ReferenceReplacer extends CommandBase { do = () => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const payloadPromise = Array.isArray(this.references) - ? Promise.all( - this.references.map((ref) => this.rebuildReferencePromise(ref)) - ) + ? Promise.all(this.references.map((ref) => this.rebuildReferencePromise(ref))) : Promise.resolve([]); return Promise.all([ - this.referencesPath.build( - this.id!, - this.className!, - this.refProp!, - this.consistencyLevel! - ), + this.referencesPath.build(this.id, this.className, this.refProp, this.consistencyLevel), payloadPromise, ]).then((results) => { const path = results[0]; @@ -98,8 +79,6 @@ export default class ReferenceReplacer extends CommandBase { }; rebuildReferencePromise(reference: any) { - return this.beaconPath - .rebuild(reference.beacon) - .then((beacon: any) => ({ beacon })); + return this.beaconPath.rebuild(reference.beacon).then((beacon: any) => ({ beacon })); } } diff --git a/src/data/replication.ts b/src/data/replication.ts new file mode 100644 index 00000000..67600eb6 --- /dev/null +++ b/src/data/replication.ts @@ -0,0 +1 @@ +export type ConsistencyLevel = 'ALL' | 'ONE' | 'QUORUM'; diff --git a/src/data/replication/consts.ts b/src/data/replication/consts.ts deleted file mode 100644 index 2265f8a3..00000000 --- a/src/data/replication/consts.ts +++ /dev/null @@ -1,11 +0,0 @@ -export const ConsistencyLevel = { - ONE: 'ONE', - QUORUM: 'QUORUM', - ALL: 'ALL', -}; - -const replicationConsts = { - ConsistencyLevel, -}; - -export default replicationConsts; diff --git a/src/data/updater.ts b/src/data/updater.ts index 0fcd0d71..01a52d00 100644 --- a/src/data/updater.ts +++ b/src/data/updater.ts @@ -2,20 +2,22 @@ import { isValidStringProperty } from '../validation/string'; import { ObjectsPath } from './path'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { Properties } from '../openapi/types'; +import { ConsistencyLevel } from './replication'; export default class Updater extends CommandBase { - private className?: string; - private consistencyLevel?: string; - private id?: string; + private className!: string; + private consistencyLevel?: ConsistencyLevel; + private id!: string; private objectsPath: ObjectsPath; - private properties?: any[]; + private properties?: Properties; constructor(client: Connection, objectsPath: ObjectsPath) { super(client); this.objectsPath = objectsPath; } - withProperties = (properties: any[]) => { + withProperties = (properties: Properties) => { this.properties = properties; return this; }; @@ -42,7 +44,7 @@ export default class Updater extends CommandBase { } }; - withConsistencyLevel = (cl: string) => { + withConsistencyLevel = (cl: ConsistencyLevel) => { this.consistencyLevel = cl; return this; }; @@ -62,13 +64,11 @@ export default class Updater extends CommandBase { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } return this.objectsPath - .buildUpdate(this.id!, this.className!, this.consistencyLevel!) + .buildUpdate(this.id, this.className, this.consistencyLevel) .then((path: string) => this.client.put(path, this.payload())); }; } diff --git a/src/data/validator.ts b/src/data/validator.ts index cdcd95f3..8a72e256 100644 --- a/src/data/validator.ts +++ b/src/data/validator.ts @@ -1,11 +1,12 @@ import { isValidStringProperty } from '../validation/string'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { Properties } from '../openapi/types'; export default class Validator extends CommandBase { private className?: string; private id?: string; - private properties?: any; + private properties?: Properties; constructor(client: Connection) { super(client); @@ -16,7 +17,7 @@ export default class Validator extends CommandBase { return this; }; - withProperties = (properties: any) => { + withProperties = (properties: Properties) => { this.properties = properties; return this; }; @@ -28,9 +29,7 @@ export default class Validator extends CommandBase { validateClassName = () => { if (!isValidStringProperty(this.className)) { - this.addError( - 'className must be set - set with .withClassName(className)' - ); + this.addError('className must be set - set with .withClassName(className)'); } }; @@ -47,9 +46,7 @@ export default class Validator extends CommandBase { do = () => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const path = `/objects/validate`; return this.client.post(path, this.payload(), false).then(() => true); diff --git a/src/embedded/index.ts b/src/embedded/index.ts index 52dd754d..43a96e28 100644 --- a/src/embedded/index.ts +++ b/src/embedded/index.ts @@ -70,9 +70,7 @@ export class EmbeddedOptions { if (cfg.version.match(/[1-9]\.[1-9]{2}\..*/g)) { return cfg.version; } else { - throw new Error( - `invalid version: ${cfg.version}. version must resemble '{major}.{minor}.{patch}'` - ); + throw new Error(`invalid version: ${cfg.version}. version must resemble '{major}.{minor}.{patch}'`); } } @@ -109,9 +107,7 @@ export class EmbeddedDB { async start() { if (await isListening(this.options)) { - console.log( - `Embedded db already listening @ ${this.options.host}:${this.options.port}` - ); + console.log(`Embedded db already listening @ ${this.options.host}:${this.options.port}`); } await ensureWeaviateBinaryExists(this.options); @@ -122,14 +118,7 @@ export class EmbeddedDB { const childProc = spawn( this.options.binaryPath, - [ - '--host', - this.options.host, - '--port', - `${this.options.port}`, - '--scheme', - 'http', - ], + ['--host', this.options.host, '--port', `${this.options.port}`, '--scheme', 'http'], { env: this.options.env } ); @@ -153,10 +142,7 @@ export class EmbeddedDB { process.kill(this.pid, 'SIGTERM'); console.log(`Embedded db @ PID ${this.pid} successfully stopped`); } catch (err) { - console.log( - `Tried to stop embedded db @ PID ${this.pid}.`, - `PID not found, so nothing will be done` - ); + console.log(`Tried to stop embedded db @ PID ${this.pid}.`, `PID not found, so nothing will be done`); } } } @@ -176,13 +162,8 @@ function checkSupportedPlatform() { async function ensureWeaviateBinaryExists(opt: EmbeddedOptions) { if (!fs.existsSync(`${opt.binaryPath}`)) { - console.log( - `Binary ${opt.binaryPath} does not exist.`, - `Downloading binary for version ${opt.version}` - ); - await downloadBinary(opt).then((tarballPath) => - untarBinary(opt, tarballPath) - ); + console.log(`Binary ${opt.binaryPath} does not exist.`, `Downloading binary for version ${opt.version}`); + await downloadBinary(opt).then((tarballPath) => untarBinary(opt, tarballPath)); } } @@ -211,11 +192,7 @@ function downloadBinary(opt: EmbeddedOptions): Promise { ) ); } else { - reject( - new Error( - `failed to download binary: unexpected status code: ${resp.statusCode}` - ) - ); + reject(new Error(`failed to download binary: unexpected status code: ${resp.statusCode}`)); } }).on('error', function (err) { fs.unlinkSync(tarballPath); @@ -234,10 +211,7 @@ function untarBinary(opt: EmbeddedOptions, tarballPath: string): Promise { }) .on('finish', () => { tarball.close(); - fs.renameSync( - join(dirname(opt.binaryPath), 'weaviate'), - opt.binaryPath - ); + fs.renameSync(join(dirname(opt.binaryPath), 'weaviate'), opt.binaryPath); resolve(null); }) .on('error', function (err) { @@ -266,9 +240,7 @@ function waitTillListening(opt: EmbeddedOptions): Promise { const timeout = setTimeout(() => { clearTimeout(timeout); clearInterval(interval); - reject( - new Error(`failed to connect to embedded db @ ${opt.host}:${opt.port}`) - ); + reject(new Error(`failed to connect to embedded db @ ${opt.host}:${opt.port}`)); }, 30000); const interval = setInterval(() => { diff --git a/src/embedded/journey.test.ts b/src/embedded/journey.test.ts index 55684b5d..4da2767b 100644 --- a/src/embedded/journey.test.ts +++ b/src/embedded/journey.test.ts @@ -1,6 +1,6 @@ import { homedir } from 'os'; import { join } from 'path'; -import { EmbeddedDB, EmbeddedOptions } from './index'; +import { EmbeddedDB, EmbeddedOptions } from '.'; describe('embedded', () => { jest.setTimeout(60 * 1000); @@ -8,12 +8,8 @@ describe('embedded', () => { it('creates EmbeddedOptions with defaults', () => { const opt = new EmbeddedOptions(); - expect(opt.binaryPath).toEqual( - join(homedir(), '.cache/weaviate-embedded-1.18.0') - ); - expect(opt.persistenceDataPath).toEqual( - join(homedir(), '.local/share/weaviate') - ); + expect(opt.binaryPath).toEqual(join(homedir(), '.cache/weaviate-embedded-1.18.0')); + expect(opt.persistenceDataPath).toEqual(join(homedir(), '.local/share/weaviate')); expect(opt.host).toEqual('127.0.0.1'); expect(opt.port).toEqual(6666); expect(opt.clusterHostname).toEqual('embedded'); @@ -33,10 +29,7 @@ describe('embedded', () => { }); // eslint-disable-next-line prettier/prettier - expect(opt.env).toHaveProperty( - 'DEFAULT_VECTORIZER_MODULE', - 'text2vec-contextionary' - ); + expect(opt.env).toHaveProperty('DEFAULT_VECTORIZER_MODULE', 'text2vec-contextionary'); expect(opt.env).toHaveProperty('ENABLE_MODULES', 'text2vec-contextionary'); expect(opt.env).toHaveProperty('CONTEXTIONARY_URL', 'contextionary:9999'); expect(opt.env).toHaveProperty('QUERY_DEFAULTS_LIMIT', 100); @@ -49,9 +42,7 @@ describe('embedded', () => { const opt = new EmbeddedOptions({ version: '123', }); - }).toThrow( - "invalid version: 123. version must resemble '{major}.{minor}.{patch}'" - ); + }).toThrow("invalid version: 123. version must resemble '{major}.{minor}.{patch}'"); }); if (process.platform == 'linux') { @@ -76,8 +67,6 @@ describe('embedded', () => { db.stop(); }); } else { - console.warn( - `Skipping because EmbeddedDB does not support ${process.platform}` - ); + console.warn(`Skipping because EmbeddedDB does not support ${process.platform}`); } }); diff --git a/src/graphql/aggregator.ts b/src/graphql/aggregator.ts index cd37e394..c1b16b40 100644 --- a/src/graphql/aggregator.ts +++ b/src/graphql/aggregator.ts @@ -1,10 +1,11 @@ import Where from './where'; -import NearText from './nearText'; -import NearVector from './nearVector'; -import NearObject from './nearObject'; +import NearText, { NearTextArgs } from './nearText'; +import NearVector, { NearVectorArgs } from './nearVector'; +import NearObject, { NearObjectArgs } from './nearObject'; import { isValidPositiveIntProperty } from '../validation/number'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { WhereFilter } from '../openapi/types'; export default class Aggregator extends CommandBase { private className?: string; @@ -33,24 +34,22 @@ export default class Aggregator extends CommandBase { return this; }; - withWhere = (whereObj: any) => { + withWhere = (where: WhereFilter) => { try { - this.whereString = new Where(whereObj).toString(); + this.whereString = new Where(where).toString(); } catch (e: any) { this.addError(e as string); } return this; }; - withNearText = (nearTextObj: any) => { + withNearText = (args: NearTextArgs) => { if (this.includesNearMediaFilter) { - throw new Error( - 'cannot use multiple near filters in a single query' - ); + throw new Error('cannot use multiple near filters in a single query'); } try { - this.nearTextString = new NearText(nearTextObj).toString(); + this.nearTextString = new NearText(args).toString(); this.includesNearMediaFilter = true; } catch (e: any) { this.addError(e.toString()); @@ -59,15 +58,13 @@ export default class Aggregator extends CommandBase { return this; }; - withNearObject = (nearObjectObj: any) => { + withNearObject = (args: NearObjectArgs) => { if (this.includesNearMediaFilter) { - throw new Error( - 'cannot use multiple near filters in a single query' - ); + throw new Error('cannot use multiple near filters in a single query'); } try { - this.nearObjectString = new NearObject(nearObjectObj).toString(); + this.nearObjectString = new NearObject(args).toString(); this.includesNearMediaFilter = true; } catch (e: any) { this.addError(e.toString()); @@ -76,15 +73,13 @@ export default class Aggregator extends CommandBase { return this; }; - withNearVector = (nearVectorObj: any) => { + withNearVector = (args: NearVectorArgs) => { if (this.includesNearMediaFilter) { - throw new Error( - 'cannot use multiple near filters in a single query' - ); + throw new Error('cannot use multiple near filters in a single query'); } try { - this.nearVectorString = new NearVector(nearVectorObj).toString(); + this.nearVectorString = new NearVector(args).toString(); this.includesNearMediaFilter = true; } catch (e: any) { this.addError(e.toString()); @@ -123,11 +118,7 @@ export default class Aggregator extends CommandBase { } }; - validateIsSet = ( - prop: string | undefined | null, - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null, name: string, setter: string) => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } @@ -135,11 +126,7 @@ export default class Aggregator extends CommandBase { validate = () => { this.validateGroup(); - this.validateIsSet( - this.className, - 'className', - '.withClassName(className)' - ); + this.validateIsSet(this.className, 'className', '.withClassName(className)'); this.validateIsSet(this.fields, 'fields', '.withFields(fields)'); }; @@ -148,9 +135,7 @@ export default class Aggregator extends CommandBase { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } if ( @@ -161,7 +146,7 @@ export default class Aggregator extends CommandBase { this.limit || this.groupBy ) { - let args: any[] = []; + let args: string[] = []; if (this.whereString) { args = [...args, `where:${this.whereString}`]; @@ -194,8 +179,6 @@ export default class Aggregator extends CommandBase { params = `(${args.join(',')})`; } - return this.client.query( - `{Aggregate{${this.className}${params}{${this.fields}}}}` - ); + return this.client.query(`{Aggregate{${this.className}${params}{${this.fields}}}}`); }; } diff --git a/src/graphql/ask.ts b/src/graphql/ask.ts index 9ae7b461..fce881e1 100644 --- a/src/graphql/ask.ts +++ b/src/graphql/ask.ts @@ -1,3 +1,12 @@ +export interface AskArgs { + autocorrect?: boolean; + certainty?: number; + distance?: number; + properties?: string[]; + question?: string; + rerank?: boolean; +} + export default class GraphQLAsk { private autocorrect?: boolean; private certainty?: number; @@ -5,14 +14,17 @@ export default class GraphQLAsk { private properties?: string[]; private question?: string; private rerank?: boolean; - private source: any; - constructor(askObj: any) { - this.source = askObj; + constructor(args: AskArgs) { + this.autocorrect = args.autocorrect; + this.certainty = args.certainty; + this.distance = args.distance; + this.properties = args.properties; + this.question = args.question; + this.rerank = args.rerank; } toString(wrap = true) { - this.parse(); this.validate(); let args: any[] = []; @@ -52,79 +64,4 @@ export default class GraphQLAsk { throw new Error('ask filter: question needs to be set'); } } - - parse() { - for (const key in this.source) { - switch (key) { - case 'question': - this.parseQuestion(this.source[key]); - break; - case 'properties': - this.parseProperties(this.source[key]); - break; - case 'certainty': - this.parseCertainty(this.source[key]); - break; - case 'distance': - this.parseDistance(this.source[key]); - break; - case 'autocorrect': - this.parseAutocorrect(this.source[key]); - break; - case 'rerank': - this.parseRerank(this.source[key]); - break; - default: - throw new Error("ask filter: unrecognized key '" + key + "'"); - } - } - } - - parseQuestion(question: string) { - if (typeof question !== 'string') { - throw new Error('ask filter: question must be a string'); - } - - this.question = question; - } - - parseProperties(properties: any[]) { - if (!Array.isArray(properties)) { - throw new Error('ask filter: properties must be an array'); - } - - this.properties = properties; - } - - parseCertainty(cert: number) { - if (typeof cert !== 'number') { - throw new Error('ask filter: certainty must be a number'); - } - - this.certainty = cert; - } - - parseDistance(dist: number) { - if (typeof dist !== 'number') { - throw new Error('ask filter: distance must be a number'); - } - - this.distance = dist; - } - - parseAutocorrect(autocorrect: boolean) { - if (typeof autocorrect !== 'boolean') { - throw new Error('ask filter: autocorrect must be a boolean'); - } - - this.autocorrect = autocorrect; - } - - parseRerank(rerank: boolean) { - if (typeof rerank !== 'boolean') { - throw new Error('ask filter: rerank must be a boolean'); - } - - this.rerank = rerank; - } } diff --git a/src/graphql/bm25.ts b/src/graphql/bm25.ts index 4b1c8dcf..b9a77ad7 100644 --- a/src/graphql/bm25.ts +++ b/src/graphql/bm25.ts @@ -1,21 +1,20 @@ -import { - isValidStringArray, - isValidStringProperty, -} from '../validation/string'; +import { isValidStringArray, isValidStringProperty } from '../validation/string'; + +export interface Bm25Args { + properties?: string[]; + query: string; +} export default class GraphQLBm25 { private properties?: string[]; - private query?: string; - private source: any; + private query: string; - constructor(bm25Obj: any) { - this.source = bm25Obj; + constructor(args: Bm25Args) { + this.properties = args.properties; + this.query = args.query; } toString() { - this.parse(); - this.validate(); - let args = [`query:${JSON.stringify(this.query)}`]; // query must always be set if (this.properties !== undefined) { @@ -24,41 +23,4 @@ export default class GraphQLBm25 { return `{${args.join(',')}}`; } - - parse() { - for (const key in this.source) { - switch (key) { - case 'query': - this.parseQuery(this.source[key]); - break; - case 'properties': - this.parseProperties(this.source[key]); - break; - default: - throw new Error(`bm25 filter: unrecognized key '${key}'`); - } - } - } - - parseQuery(query: string) { - if (!isValidStringProperty(query)) { - throw new Error('bm25 filter: query must be a string'); - } - - this.query = query; - } - - parseProperties(properties: string[]) { - if (!isValidStringArray(properties)) { - throw new Error('bm25 filter: properties must be an array of strings'); - } - - this.properties = properties; - } - - validate() { - if (!this.query) { - throw new Error('bm25 filter: query cannot be empty'); - } - } } diff --git a/src/graphql/explorer.ts b/src/graphql/explorer.ts index 3299fdd6..95ced188 100644 --- a/src/graphql/explorer.ts +++ b/src/graphql/explorer.ts @@ -1,8 +1,8 @@ -import NearText from './nearText'; -import NearVector from './nearVector'; -import NearObject from './nearObject'; -import NearImage from './nearImage'; -import Ask from './ask'; +import NearText, { NearTextArgs } from './nearText'; +import NearVector, { NearVectorArgs } from './nearVector'; +import NearObject, { NearObjectArgs } from './nearObject'; +import NearImage, { NearImageArgs } from './nearImage'; +import Ask, { AskArgs } from './ask'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; @@ -32,45 +32,45 @@ export default class Explorer extends CommandBase { return this; }; - withNearText = (nearTextObj: any) => { + withNearText = (args: NearTextArgs) => { try { - this.nearTextString = new NearText(nearTextObj).toString(); + this.nearTextString = new NearText(args).toString(); } catch (e: any) { this.addError(e.toString()); } return this; }; - withNearObject = (nearObjectObj: any) => { + withNearObject = (args: NearObjectArgs) => { try { - this.nearObjectString = new NearObject(nearObjectObj).toString(); + this.nearObjectString = new NearObject(args).toString(); } catch (e: any) { this.addError(e.toString()); } return this; }; - withAsk = (askObj: any) => { + withAsk = (args: AskArgs) => { try { - this.askString = new Ask(askObj).toString(); + this.askString = new Ask(args).toString(); } catch (e: any) { this.addError(e.toString()); } return this; }; - withNearImage = (nearImageObj: any) => { + withNearImage = (args: NearImageArgs) => { try { - this.nearImageString = new NearImage(nearImageObj).toString(); + this.nearImageString = new NearImage(args).toString(); } catch (e: any) { this.addError(e.toString()); } return this; }; - withNearVector = (nearVectorObj: any) => { + withNearVector = (args: NearVectorArgs) => { try { - this.nearVectorString = new NearVector(nearVectorObj).toString(); + this.nearVectorString = new NearVector(args).toString(); } catch (e: any) { this.addError(e.toString()); } @@ -88,11 +88,7 @@ export default class Explorer extends CommandBase { } }; - validateIsSet = ( - prop: string | undefined | null, - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null, name: string, setter: string) => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } @@ -107,12 +103,10 @@ export default class Explorer extends CommandBase { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } - let args: any[] = []; + let args: string[] = []; if (this.nearTextString) { args = [...args, `nearText:${this.nearTextString}`]; diff --git a/src/graphql/getter.test.ts b/src/graphql/getter.test.ts index 801e38fd..86d2e211 100644 --- a/src/graphql/getter.test.ts +++ b/src/graphql/getter.test.ts @@ -1,5 +1,10 @@ import Getter from './getter'; -import { Operator } from '../filters/consts'; +import { WhereFilter } from '../openapi/types'; +import { NearObjectArgs } from './nearObject'; +import { AskArgs } from './ask'; +import { NearImageArgs } from './nearImage'; +import { SortArgs } from './sort'; +import { NearTextArgs } from './nearText'; test('a simple query without params', () => { const mockClient: any = { @@ -20,11 +25,7 @@ test('a simple query with a limit', () => { const expectedQuery = `{Get{Person(limit:7){name}}}`; - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withLimit(7) - .do(); + new Getter(mockClient).withClassName('Person').withFields('name').withLimit(7).do(); expect(mockClient.query).toHaveBeenCalledWith(expectedQuery); }); @@ -36,12 +37,7 @@ test('a simple query with a limit and offset', () => { const expectedQuery = `{Get{Person(limit:7,offset:2){name}}}`; - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withOffset(2) - .withLimit(7) - .do(); + new Getter(mockClient).withClassName('Person').withFields('name').withOffset(2).withLimit(7).do(); expect(mockClient.query).toHaveBeenCalledWith(expectedQuery); }); @@ -85,20 +81,14 @@ describe('where filters', () => { query: jest.fn(), }; - const expectedQuery = - `{Get{Person` + - `(where:{operator:Equal,valueString:"John Doe",path:["name"]})` + - `{name}}}`; + const expectedQuery = `{Get{Person(where:{operator:Equal,valueString:"John Doe",path:["name"]}){name}}}`; + const where: WhereFilter = { + operator: 'Equal', + valueString: 'John Doe', + path: ['name'], + }; - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withWhere({ - operator: Operator.EQUAL, - valueString: 'John Doe', - path: ['name'], - }) - .do(); + new Getter(mockClient).withClassName('Person').withFields('name').withWhere(where).do(); expect(mockClient.query).toHaveBeenCalledWith(expectedQuery); }); @@ -116,24 +106,21 @@ describe('where filters', () => { `{geoCoordinates:{latitude:51.51,longitude:-0.09},distance:{max:2000}}` + `,path:["name"]})` + `{name}}}`; - - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withWhere({ - operator: Operator.WITHIN_GEO_RANGE, - valueGeoRange: { - geoCoordinates: { - latitude: 51.51, - longitude: -0.09, - }, - distance: { - max: 2000, - }, + const where: WhereFilter = { + operator: 'WithinGeoRange', + valueGeoRange: { + geoCoordinates: { + latitude: 51.51, + longitude: -0.09, }, - path: ['name'], - }) - .do(); + distance: { + max: 2000, + }, + }, + path: ['name'], + }; + + new Getter(mockClient).withClassName('Person').withFields('name').withWhere(where).do(); expect(mockClient.query).toHaveBeenCalledWith(expectedQuery); }); @@ -143,13 +130,6 @@ describe('where filters', () => { query: jest.fn(), }; - const nestedWhere = { - operator: Operator.AND, - operands: [ - { valueString: 'foo', operator: Operator.EQUAL, path: ['foo'] }, - { valueString: 'bar', operator: Operator.NOT_EQUAL, path: ['bar'] }, - ], - }; const expectedQuery = `{Get{Person` + `(where:{operator:And,operands:[` + @@ -157,69 +137,17 @@ describe('where filters', () => { `{operator:NotEqual,valueString:"bar",path:["bar"]}` + `]})` + `{name}}}`; - - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withWhere(nestedWhere) - .do(); - - expect(mockClient.query).toHaveBeenCalledWith(expectedQuery); - }); - - describe('queries with invalid nested where filters', () => { - const mockClient: any = { - query: jest.fn(), + const nestedWhere: WhereFilter = { + operator: 'And', + operands: [ + { valueString: 'foo', operator: 'Equal', path: ['foo'] }, + { valueString: 'bar', operator: 'NotEqual', path: ['bar'] }, + ], }; - const tests = [ - { - title: 'an empty where', - where: {}, - msg: 'where filter: operator cannot be empty', - }, - { - title: 'missing value', - where: { operator: Operator.EQUAL }, - msg: 'where filter: value cannot be empty', - }, - { - title: 'missing path', - where: { operator: Operator.EQUAL, valueString: 'foo' }, - msg: 'where filter: path cannot be empty', - }, - { - title: 'path is not an array', - where: { operator: Operator.EQUAL, valueString: 'foo', path: 'mypath' }, - msg: 'where filter: path must be an array', - }, - { - title: 'unknown value type', - where: { operator: Operator.EQUAL, valueWrong: 'foo' }, - msg: "where filter: unrecognized value prop 'valueWrong'", - }, - { - title: 'operands is not an array', - where: { operator: Operator.AND, operands: {} }, - msg: 'where filter: operands must be an array', - }, - ]; + new Getter(mockClient).withClassName('Person').withFields('name').withWhere(nestedWhere).do(); - tests.forEach((t) => { - test(t.title, () => { - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withWhere(t.where) - .do() - .then(() => { - fail('it should have errord'); - }) - .catch((e: any) => { - expect(e.toString()).toContain(t.msg); - }); - }); - }); + expect(mockClient.query).toHaveBeenCalledWith(expectedQuery); }); }); @@ -344,10 +272,7 @@ describe('nearText searchers', () => { query: jest.fn(), }; - const expectedQuery = - `{Get{Person` + - `(nearText:{concepts:["foo","bar"],autocorrect:false})` + - `{name}}}`; + const expectedQuery = `{Get{Person(nearText:{concepts:["foo","bar"],autocorrect:false}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -509,27 +434,13 @@ describe('nearText searchers', () => { query: jest.fn(), }; - const tests = [ - { - title: 'an empty nearText', - nearText: {}, - msg: 'nearText filter: concepts cannot be empty', - }, - { - title: 'concepts of wrong type', - nearText: { concepts: {} }, - msg: 'nearText filter: concepts must be an array', - }, - { - title: 'certainty of wrong type', - nearText: { concepts: ['foo'], certainty: 'foo' }, - msg: 'nearText filter: certainty must be a number', - }, - { - title: 'distance of wrong type', - nearText: { concepts: ['foo'], distance: 'foo' }, - msg: 'nearText filter: distance must be a number', - }, + interface testCase { + title: string; + nearText: NearTextArgs; + msg: string; + } + + const tests: testCase[] = [ { title: 'moveTo empty object', nearText: { concepts: ['foo'], moveTo: {} }, @@ -566,53 +477,10 @@ describe('nearText searchers', () => { }, msg: "nearText filter: moveAwayFrom must have fields 'concepts' or 'objects' and 'force'", }, - { - title: 'autocorrect of wrong type', - nearText: { concepts: ['foo'], autocorrect: 'foo' }, - msg: 'nearText filter: autocorrect must be a boolean', - }, - { - title: 'moveTo with empty objects', - nearText: { concepts: ['foo'], moveTo: { force: 0.8, objects: {} } }, - msg: 'nearText filter: moveTo.objects must be an array', - }, { title: 'moveTo with empty object in objects', nearText: { concepts: ['foo'], moveTo: { force: 0.8, objects: [{}] } }, - msg: 'nearText filter: moveTo.objects[0].id or moveTo.objects[0].beacon must be present', - }, - { - title: 'moveTo with objects[0].id not of string type', - nearText: { - concepts: ['foo'], - moveTo: { force: 0.8, objects: [{ id: 0.8 }] }, - }, - msg: 'nearText filter: moveTo.objects[0].id must be string', - }, - { - title: 'moveTo with objects[0].beacon not of string type', - nearText: { - concepts: ['foo'], - moveTo: { force: 0.8, objects: [{ beacon: 0.8 }] }, - }, - msg: 'nearText filter: moveTo.objects[0].beacon must be string', - }, - { - title: - 'moveTo with objects[0].id not of string type and objects[1].beacon not of string type', - nearText: { - concepts: ['foo'], - moveTo: { force: 0.8, objects: [{ id: 0.8 }, { beacon: 0.8 }] }, - }, - msg: 'nearText filter: moveTo.objects[0].id must be string, moveTo.objects[1].beacon must be string', - }, - { - title: 'moveAwayFrom with empty objects', - nearText: { - concepts: ['foo'], - moveAwayFrom: { force: 0.8, objects: {} }, - }, - msg: 'nearText filter: moveAwayFrom.objects must be an array', + msg: 'nearText: moveTo.objects[0].id or moveTo.objects[0].beacon must be present', }, { title: 'moveAwayFrom with empty object in objects', @@ -620,48 +488,15 @@ describe('nearText searchers', () => { concepts: ['foo'], moveAwayFrom: { force: 0.8, objects: [{}] }, }, - msg: 'nearText filter: moveAwayFrom.objects[0].id or moveAwayFrom.objects[0].beacon must be present', - }, - { - title: 'moveAwayFrom with objects[0].id not of string type', - nearText: { - concepts: ['foo'], - moveAwayFrom: { force: 0.8, objects: [{ id: 0.8 }] }, - }, - msg: 'nearText filter: moveAwayFrom.objects[0].id must be string', - }, - { - title: 'moveAwayFrom with objects[0].beacon not of string type', - nearText: { - concepts: ['foo'], - moveAwayFrom: { force: 0.8, objects: [{ beacon: 0.8 }] }, - }, - msg: 'nearText filter: moveAwayFrom.objects[0].beacon must be string', - }, - { - title: - 'moveAwayFrom with objects[0].id not of string type and objects[1].beacon not of string type', - nearText: { - concepts: ['foo'], - moveAwayFrom: { force: 0.8, objects: [{ id: 0.8 }, { beacon: 0.8 }] }, - }, - msg: 'nearText filter: moveAwayFrom.objects[0].id must be string, moveAwayFrom.objects[1].beacon must be string', + msg: 'nearText: moveAwayFrom.objects[0].id or moveAwayFrom.objects[0].beacon must be present', }, ]; tests.forEach((t) => { test(t.title, () => { - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withNearText(t.nearText) - .do() - .then(() => { - throw new Error('it should have errord'); - }) - .catch((e: any) => { - expect(e.toString()).toContain(t.msg); - }); + expect(() => { + new Getter(mockClient).withClassName('Person').withFields('name').withNearText(t.nearText); + }).toThrow(t.msg); }); }); }); @@ -690,10 +525,7 @@ describe('nearVector searchers', () => { query: jest.fn(), }; - const expectedQuery = - `{Get{Person` + - `(nearVector:{vector:[0.1234,0.9876],certainty:0.7})` + - `{name}}}`; + const expectedQuery = `{Get{Person(nearVector:{vector:[0.1234,0.9876],certainty:0.7}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -712,10 +544,7 @@ describe('nearVector searchers', () => { query: jest.fn(), }; - const expectedQuery = - `{Get{Person` + - `(nearVector:{vector:[0.1234,0.9876],distance:0.7})` + - `{name}}}`; + const expectedQuery = `{Get{Person(nearVector:{vector:[0.1234,0.9876],distance:0.7}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -728,56 +557,6 @@ describe('nearVector searchers', () => { expect(mockClient.query).toHaveBeenCalledWith(expectedQuery); }); - - describe('queries with invalid nearVector searchers', () => { - const mockClient: any = { - query: jest.fn(), - }; - - const tests = [ - { - title: 'an empty nearVector', - nearVector: {}, - msg: 'nearVector filter: vector cannot be empty', - }, - { - title: 'vector of wrong type', - nearVector: { vector: {} }, - msg: 'nearVector filter: vector must be an array', - }, - { - title: 'vector as array of wrong type', - nearVector: { vector: ['foo'] }, - msg: 'nearVector filter: vector elements must be a number', - }, - { - title: 'certainty of wrong type', - nearVector: { vector: [0.123, 0.987], certainty: 'foo' }, - msg: 'nearVector filter: certainty must be a number', - }, - { - title: 'distance of wrong type', - nearVector: { vector: [0.123, 0.987], distance: 'foo' }, - msg: 'nearVector filter: distance must be a number', - }, - ]; - - tests.forEach((t) => { - test(t.title, () => { - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withNearVector(t.nearVector) - .do() - .then(() => { - throw new Error('it should have errord'); - }) - .catch((e: any) => { - expect(e.toString()).toContain(t.msg); - }); - }); - }); - }); }); describe('nearObject searchers', () => { @@ -820,10 +599,7 @@ describe('nearObject searchers', () => { query: jest.fn(), }; - const expectedQuery = - `{Get{Person` + - `(nearObject:{id:"some-uuid",beacon:"weaviate/some-uuid",certainty:0.7})` + - `{name}}}`; + const expectedQuery = `{Get{Person(nearObject:{id:"some-uuid",beacon:"weaviate/some-uuid",certainty:0.7}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -843,10 +619,7 @@ describe('nearObject searchers', () => { query: jest.fn(), }; - const expectedQuery = - `{Get{Person` + - `(nearObject:{id:"some-uuid",beacon:"weaviate/some-uuid",distance:0.7})` + - `{name}}}`; + const expectedQuery = `{Get{Person(nearObject:{id:"some-uuid",beacon:"weaviate/some-uuid",distance:0.7}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -866,32 +639,18 @@ describe('nearObject searchers', () => { query: jest.fn(), }; - const tests = [ + interface testCase { + title: string; + nearObject: NearObjectArgs; + msg: string; + } + + const tests: testCase[] = [ { title: 'an empty nearObject', nearObject: {}, msg: 'nearObject filter: id or beacon needs to be set', }, - { - title: 'id of wrong type', - nearObject: { id: {} }, - msg: 'nearObject filter: id must be a string', - }, - { - title: 'beacon of wrong type', - nearObject: { beacon: {} }, - msg: 'nearObject filter: beacon must be a string', - }, - { - title: 'certainty of wrong type', - nearObject: { id: 'foo', certainty: 'foo' }, - msg: 'nearObject filter: certainty must be a number', - }, - { - title: 'distance of wrong type', - nearObject: { id: 'foo', distance: 'foo' }, - msg: 'nearObject filter: distance must be a number', - }, ]; tests.forEach((t) => { @@ -935,10 +694,7 @@ describe('ask searchers', () => { query: jest.fn(), }; - const expectedQuery = - `{Get{Person` + - `(ask:{question:"What is Weaviate?",properties:["prop1","prop2"]})` + - `{name}}}`; + const expectedQuery = `{Get{Person(ask:{question:"What is Weaviate?",properties:["prop1","prop2"]}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -1053,10 +809,7 @@ describe('ask searchers', () => { query: jest.fn(), }; - const expectedQuery = - `{Get{Person` + - `(ask:{question:"What is Weaviate?",autocorrect:true})` + - `{name}}}`; + const expectedQuery = `{Get{Person(ask:{question:"What is Weaviate?",autocorrect:true}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -1072,10 +825,7 @@ describe('ask searchers', () => { query: jest.fn(), }; - const expectedQuery = - `{Get{Person` + - `(ask:{question:"What is Weaviate?",autocorrect:false})` + - `{name}}}`; + const expectedQuery = `{Get{Person(ask:{question:"What is Weaviate?",autocorrect:false}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -1091,10 +841,7 @@ describe('ask searchers', () => { query: jest.fn(), }; - const expectedQuery = - `{Get{Person` + - `(ask:{question:"What is Weaviate?",rerank:true})` + - `{name}}}`; + const expectedQuery = `{Get{Person(ask:{question:"What is Weaviate?",rerank:true}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -1110,10 +857,7 @@ describe('ask searchers', () => { query: jest.fn(), }; - const expectedQuery = - `{Get{Person` + - `(ask:{question:"What is Weaviate?",rerank:false})` + - `{name}}}`; + const expectedQuery = `{Get{Person(ask:{question:"What is Weaviate?",rerank:false}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -1129,37 +873,18 @@ describe('ask searchers', () => { query: jest.fn(), }; - const tests = [ + interface testCase { + title: string; + ask: AskArgs; + msg: string; + } + + const tests: testCase[] = [ { title: 'an empty ask', ask: {}, msg: 'ask filter: question needs to be set', }, - { - title: 'question of wrong type', - ask: { question: {} }, - msg: 'ask filter: question must be a string', - }, - { - title: 'properties of wrong type', - ask: { properties: {} }, - msg: 'ask filter: properties must be an array', - }, - { - title: 'certainty of wrong type', - ask: { question: 'foo', certainty: 'foo' }, - msg: 'ask filter: certainty must be a number', - }, - { - title: 'distance of wrong type', - ask: { question: 'foo', distance: 'foo' }, - msg: 'ask filter: distance must be a number', - }, - { - title: 'autocorrect of wrong type', - ask: { question: 'foo', autocorrect: 'foo' }, - msg: 'ask filter: autocorrect must be a boolean', - }, ]; tests.forEach((t) => { @@ -1203,10 +928,7 @@ describe('nearImage searchers', () => { query: jest.fn(), }; - const expectedQuery = - `{Get{Person` + - `(nearImage:{image:"iVBORw0KGgoAAAANS",certainty:0.8})` + - `{name}}}`; + const expectedQuery = `{Get{Person(nearImage:{image:"iVBORw0KGgoAAAANS",certainty:0.8}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -1225,10 +947,7 @@ describe('nearImage searchers', () => { query: jest.fn(), }; - const expectedQuery = - `{Get{Person` + - `(nearImage:{image:"iVBORw0KGgoAAAANS",distance:0.8})` + - `{name}}}`; + const expectedQuery = `{Get{Person(nearImage:{image:"iVBORw0KGgoAAAANS",distance:0.8}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -1264,26 +983,17 @@ describe('nearImage searchers', () => { query: jest.fn(), }; - const tests = [ + interface testCase { + title: string; + nearImage: NearImageArgs; + msg: string; + } + + const tests: testCase[] = [ { title: 'an empty nearImage', nearImage: {}, - msg: 'nearImage filter: image or imageBlob must be present', - }, - { - title: 'image of wrong type', - nearImage: { image: {} }, - msg: 'nearImage filter: image must be a string', - }, - { - title: 'certainty of wrong type', - nearImage: { image: 'foo', certainty: 'foo' }, - msg: 'nearImage filter: certainty must be a number', - }, - { - title: 'distance of wrong type', - nearImage: { image: 'foo', distance: 'foo' }, - msg: 'nearImage filter: distance must be a number', + msg: 'nearImage filter: image field must be present', }, ]; @@ -1314,13 +1024,9 @@ describe('sort filters', () => { const subQuery = `(sort:[{path:["property"],order:asc}])`; const expectedQuery = `{Get{Person` + subQuery + `{name}}}`; - const sort = { path: ['property'], order: 'asc' }; + const sort: SortArgs[] = [{ path: ['property'], order: 'asc' }]; - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withSort(sort) - .do(); + new Getter(mockClient).withClassName('Person').withFields('name').withSort(sort).do(); expect(mockClient.query).toHaveBeenCalledWith(expectedQuery); }); @@ -1335,11 +1041,7 @@ describe('sort filters', () => { const sort = [{ path: ['property'], order: 'asc' }]; - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withSort(sort) - .do(); + new Getter(mockClient).withClassName('Person').withFields('name').withSort(sort).do(); expect(mockClient.query).toHaveBeenCalledWith(expectedQuery); }); @@ -1360,114 +1062,12 @@ describe('sort filters', () => { { path: ['property3'], order: 'desc' }, ]; - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withSort(sort) - .do(); + new Getter(mockClient).withClassName('Person').withFields('name').withSort(sort).do(); expect(mockClient.query).toHaveBeenCalledWith(expectedQuery); }); }); -describe('invalid sort filters', () => { - const mockClient: any = { - query: jest.fn(), - }; - - const tests = [ - { - name: 'empty filter', - sort: {}, - msg: 'Error: invalid usage: Error: sort filter: path needs to be set', - }, - { - name: '[empty filter]', - sort: [{}], - msg: 'Error: invalid usage: Error: sort filter: sort argument at 0: sort filter: path needs to be set', - }, - { - name: 'empty path', - sort: { path: [] }, - msg: 'Error: invalid usage: Error: sort filter: path cannot be empty', - }, - { - name: '[empty path]', - sort: [{ path: [] }], - msg: 'Error: invalid usage: Error: sort filter: sort argument at 0: sort filter: path cannot be empty', - }, - { - name: 'only with order', - sort: { order: 'asc' }, - msg: 'Error: invalid usage: Error: sort filter: path needs to be set', - }, - { - name: '[only with order]', - sort: [{ order: 'asc' }], - msg: 'Error: invalid usage: Error: sort filter: sort argument at 0: sort filter: path needs to be set', - }, - { - name: 'with wrong order', - sort: { order: 'asce' }, - msg: 'Error: invalid usage: Error: sort filter: order parameter not valid, possible values are: asc, desc', - }, - { - name: '[with wrong order]', - sort: [{ order: 'desce' }], - msg: 'Error: invalid usage: Error: sort filter: sort argument at 0: sort filter: order parameter not valid, possible values are: asc, desc', - }, - { - name: 'with wrong order type', - sort: { order: 1 }, - msg: 'Error: invalid usage: Error: sort filter: order must be a string', - }, - { - name: '[with wrong order type]', - sort: [{ order: 1 }], - msg: 'Error: invalid usage: Error: sort filter: sort argument at 0: sort filter: order must be a string', - }, - { - name: 'with proper path but wrong order', - sort: { path: ['prop'], order: 'asce' }, - msg: 'Error: invalid usage: Error: sort filter: order parameter not valid, possible values are: asc, desc', - }, - { - name: 'with proper path but wrong order', - sort: [{ path: ['prop'], order: 'asce' }], - msg: 'Error: invalid usage: Error: sort filter: sort argument at 0: sort filter: order parameter not valid, possible values are: asc, desc', - }, - { - name: 'with wrong path in second argument', - sort: [{ path: ['prop'] }, { path: [] }], - msg: 'Error: invalid usage: Error: sort filter: sort argument at 1: sort filter: path cannot be empty', - }, - { - name: 'with wrong path in second argument', - sort: [ - { path: ['prop'] }, - { path: ['prop'], order: 'asce' }, - { path: [] }, - ], - msg: 'Error: invalid usage: Error: sort filter: sort argument at 1: sort filter: order parameter not valid, possible values are: asc, desc, sort argument at 2: sort filter: path cannot be empty', - }, - ]; - tests.forEach((t) => { - test(t.name, () => { - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withSort(t.sort) - .do() - .then(() => { - throw new Error('it should have errord'); - }) - .catch((e: any) => { - expect(e.toString()).toEqual(t.msg); - }); - }); - }); -}); - describe('bm25 valid searchers', () => { const mockClient: any = { query: jest.fn(), @@ -1477,20 +1077,13 @@ describe('bm25 valid searchers', () => { const subQuery = `(bm25:{query:"accountant"})`; const expectedQuery = `{Get{Person` + subQuery + `{name}}}`; - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withBm25({ query: 'accountant' }) - .do(); + new Getter(mockClient).withClassName('Person').withFields('name').withBm25({ query: 'accountant' }).do(); expect(mockClient.query).toHaveBeenCalledWith(expectedQuery); }); test('query and properties', () => { - const expectedQuery = - `{Get{Person` + - `(bm25:{query:"accountant",properties:["profession","position"]})` + - `{name}}}`; + const expectedQuery = `{Get{Person(bm25:{query:"accountant",properties:["profession","position"]}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -1515,61 +1108,6 @@ describe('bm25 valid searchers', () => { }); }); -describe('bm25 invalid searchers', () => { - const mockClient: any = { - query: jest.fn(), - }; - - const tests = [ - { - title: 'an empty bm25', - bm25: {}, - msg: 'bm25 filter: query cannot be empty', - }, - { - title: 'an empty query', - bm25: { query: '' }, - msg: 'bm25 filter: query must be a string', - }, - { - title: 'query of wrong type', - bm25: { query: {} }, - msg: 'bm25 filter: query must be a string', - }, - { - title: 'an empty property', - bm25: { query: 'query', properties: [''] }, - msg: 'bm25 filter: properties must be an array of strings', - }, - { - title: 'property of wrong type', - bm25: { query: 'query', properties: [123] }, - msg: 'bm25 filter: properties must be an array of strings', - }, - { - title: 'properties of wrong type', - bm25: { query: 'query', properties: {} }, - msg: 'bm25 filter: properties must be an array of strings', - }, - ]; - - tests.forEach((t) => { - test(t.title, () => { - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withBm25(t.bm25) - .do() - .then(() => { - throw new Error('it should have errord'); - }) - .catch((e: any) => { - expect(e.toString()).toContain(t.msg); - }); - }); - }); -}); - describe('hybrid valid searchers', () => { const mockClient: any = { query: jest.fn(), @@ -1615,10 +1153,7 @@ describe('hybrid valid searchers', () => { }); test('query and vector, no alpha', () => { - const expectedQuery = - `{Get{Person` + - `(hybrid:{query:"accountant",vector:[1,2,3]})` + - `{name}}}`; + const expectedQuery = `{Get{Person(hybrid:{query:"accountant",vector:[1,2,3]}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -1630,10 +1165,7 @@ describe('hybrid valid searchers', () => { }); test('query and alpha and vector', () => { - const expectedQuery = - `{Get{Person` + - `(hybrid:{query:"accountant",alpha:0.75,vector:[1,2,3]})` + - `{name}}}`; + const expectedQuery = `{Get{Person(hybrid:{query:"accountant",alpha:0.75,vector:[1,2,3]}){name}}}`; new Getter(mockClient) .withClassName('Person') @@ -1644,63 +1176,3 @@ describe('hybrid valid searchers', () => { expect(mockClient.query).toHaveBeenCalledWith(expectedQuery); }); }); - -describe('hybrid invalid searchers', () => { - const mockClient: any = { - query: jest.fn(), - }; - - const tests = [ - { - title: 'an empty hybrid', - hybrid: {}, - msg: 'hybrid filter: query cannot be empty', - }, - { - title: 'an empty query', - hybrid: { query: '' }, - msg: 'hybrid filter: query must be a string', - }, - { - title: 'query of wrong type', - hybrid: { query: {} }, - msg: 'hybrid filter: query must be a string', - }, - { - title: 'alpha on wrong type', - hybrid: { query: 'query', alpha: 'alpha' }, - msg: 'hybrid filter: alpha must be a number', - }, - { - title: 'an empty vector', - hybrid: { query: 'query', vector: [] }, - msg: 'hybrid filter: vector must be an array of numbers', - }, - { - title: 'vector element of wrong type', - hybrid: { query: 'query', vector: ['vector'] }, - msg: 'hybrid filter: vector must be an array of numbers', - }, - { - title: 'vector of wrong type', - hybrid: { query: 'query', vector: {} }, - msg: 'hybrid filter: vector must be an array of numbers', - }, - ]; - - tests.forEach((t) => { - test(t.title, () => { - new Getter(mockClient) - .withClassName('Person') - .withFields('name') - .withHybrid(t.hybrid) - .do() - .then(() => { - throw new Error('it should have errord'); - }) - .catch((e: any) => { - expect(e.toString()).toContain(t.msg); - }); - }); - }); -}); diff --git a/src/graphql/getter.ts b/src/graphql/getter.ts index e337728b..f62bbb8d 100644 --- a/src/graphql/getter.ts +++ b/src/graphql/getter.ts @@ -1,31 +1,32 @@ import Where from './where'; -import NearText from './nearText'; -import NearVector from './nearVector'; -import Bm25 from './bm25'; -import Hybrid from './hybrid'; -import NearObject from './nearObject'; -import NearImage from './nearImage'; -import Ask from './ask'; -import Group from './group'; -import Sort from './sort'; +import NearText, { NearTextArgs } from './nearText'; +import NearVector, { NearVectorArgs } from './nearVector'; +import Bm25, { Bm25Args } from './bm25'; +import Hybrid, { HybridArgs } from './hybrid'; +import NearObject, { NearObjectArgs } from './nearObject'; +import NearImage, { NearImageArgs } from './nearImage'; +import Ask, { AskArgs } from './ask'; +import Group, { GroupArgs } from './group'; +import Sort, { SortArgs } from './sort'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { WhereFilter } from '../openapi/types'; export default class Getter extends CommandBase { private after?: string; private askString?: string; private bm25String?: string; private className?: string; - private fields: any; + private fields?: string; private groupString?: string; private hybridString?: string; private includesNearMediaFilter: boolean; - private limit: any; + private limit?: number; private nearImageString?: string; private nearObjectString?: string; private nearTextString?: string; private nearVectorString?: string; - private offset: any; + private offset?: number; private sortString?: string; private whereString?: string; @@ -34,7 +35,7 @@ export default class Getter extends CommandBase { this.includesNearMediaFilter = false; } - withFields = (fields: any) => { + withFields = (fields: string) => { this.fields = fields; return this; }; @@ -49,9 +50,9 @@ export default class Getter extends CommandBase { return this; }; - withGroup = (groupObj: any) => { + withGroup = (args: GroupArgs) => { try { - this.groupString = new Group(groupObj).toString(); + this.groupString = new Group(args).toString(); } catch (e: any) { this.addError(e.toString()); } @@ -59,7 +60,7 @@ export default class Getter extends CommandBase { return this; }; - withWhere = (whereObj: any) => { + withWhere = (whereObj: WhereFilter) => { try { this.whereString = new Where(whereObj).toString(); } catch (e: any) { @@ -68,26 +69,20 @@ export default class Getter extends CommandBase { return this; }; - withNearText = (nearTextObj: any) => { + withNearText = (args: NearTextArgs) => { if (this.includesNearMediaFilter) { - throw new Error( - 'cannot use multiple near filters in a single query' - ); + throw new Error('cannot use multiple near filters in a single query'); } - try { - this.nearTextString = new NearText(nearTextObj).toString(); - this.includesNearMediaFilter = true; - } catch (e: any) { - this.addError(e.toString()); - } + this.nearTextString = new NearText(args).toString(); + this.includesNearMediaFilter = true; return this; }; - withBm25 = (bm25Obj: any) => { + withBm25 = (args: Bm25Args) => { try { - this.bm25String = new Bm25(bm25Obj).toString(); + this.bm25String = new Bm25(args).toString(); } catch (e: any) { this.addError(e.toString()); } @@ -95,9 +90,9 @@ export default class Getter extends CommandBase { return this; }; - withHybrid = (hybridObj: any) => { + withHybrid = (args: HybridArgs) => { try { - this.hybridString = new Hybrid(hybridObj).toString(); + this.hybridString = new Hybrid(args).toString(); } catch (e: any) { this.addError(e.toString()); } @@ -105,15 +100,13 @@ export default class Getter extends CommandBase { return this; }; - withNearObject = (nearObjectObj: any) => { + withNearObject = (args: NearObjectArgs) => { if (this.includesNearMediaFilter) { - throw new Error( - 'cannot use multiple near filters in a single query' - ); + throw new Error('cannot use multiple near filters in a single query'); } try { - this.nearObjectString = new NearObject(nearObjectObj).toString(); + this.nearObjectString = new NearObject(args).toString(); this.includesNearMediaFilter = true; } catch (e: any) { this.addError(e.toString()); @@ -122,7 +115,7 @@ export default class Getter extends CommandBase { return this; }; - withAsk = (askObj: any) => { + withAsk = (askObj: AskArgs) => { try { this.askString = new Ask(askObj).toString(); } catch (e: any) { @@ -131,15 +124,13 @@ export default class Getter extends CommandBase { return this; }; - withNearImage = (nearImageObj: any) => { + withNearImage = (args: NearImageArgs) => { if (this.includesNearMediaFilter) { - throw new Error( - 'cannot use multiple near filters in a single query' - ); + throw new Error('cannot use multiple near filters in a single query'); } try { - this.nearImageString = new NearImage(nearImageObj).toString(); + this.nearImageString = new NearImage(args).toString(); this.includesNearMediaFilter = true; } catch (e: any) { this.addError(e.toString()); @@ -148,15 +139,13 @@ export default class Getter extends CommandBase { return this; }; - withNearVector = (nearVectorObj: any) => { + withNearVector = (args: NearVectorArgs) => { if (this.includesNearMediaFilter) { - throw new Error( - 'cannot use multiple near filters in a single query' - ); + throw new Error('cannot use multiple near filters in a single query'); } try { - this.nearVectorString = new NearVector(nearVectorObj).toString(); + this.nearVectorString = new NearVector(args).toString(); this.includesNearMediaFilter = true; } catch (e: any) { this.addError(e.toString()); @@ -165,41 +154,29 @@ export default class Getter extends CommandBase { return this; }; - withLimit = (limit: any) => { + withLimit = (limit: number) => { this.limit = limit; return this; }; - withOffset = (offset: any) => { + withOffset = (offset: number) => { this.offset = offset; return this; }; - withSort = (sortObj: any) => { - try { - this.sortString = new Sort(sortObj).toString(); - } catch (e: any) { - this.addError(e.toString()); - } + withSort = (args: SortArgs[]) => { + this.sortString = new Sort(args).toString(); return this; }; - validateIsSet = ( - prop: string | undefined | null, - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null, name: string, setter: string) => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } }; validate = () => { - this.validateIsSet( - this.className, - 'className', - '.withClassName(className)' - ); + this.validateIsSet(this.className, 'className', '.withClassName(className)'); this.validateIsSet(this.fields, 'fields', '.withFields(fields)'); }; @@ -208,13 +185,10 @@ export default class Getter extends CommandBase { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } - let args: any[] = []; - + let args: string[] = []; if (this.whereString) { args = [...args, `where:${this.whereString}`]; } @@ -271,8 +245,6 @@ export default class Getter extends CommandBase { params = `(${args.join(',')})`; } - return this.client.query( - `{Get{${this.className}${params}{${this.fields}}}}` - ); + return this.client.query(`{Get{${this.className}${params}{${this.fields}}}}`); }; } diff --git a/src/graphql/group.ts b/src/graphql/group.ts index 394437cd..59443e91 100644 --- a/src/graphql/group.ts +++ b/src/graphql/group.ts @@ -1,20 +1,25 @@ +export interface GroupArgs { + type: string; + force: number; +} + export default class GraphQLGroup { - private source: any; + private args: GroupArgs; - constructor(source: any) { - this.source = source; + constructor(args: GroupArgs) { + this.args = args; } toString() { let parts: any[] = []; - if (this.source.type) { + if (this.args.type) { // value is a graphQL enum, so doesn't need to be quoted - parts = [...parts, `type:${this.source.type}`]; + parts = [...parts, `type:${this.args.type}`]; } - if (this.source.force) { - parts = [...parts, `force:${this.source.force}`]; + if (this.args.force) { + parts = [...parts, `force:${this.args.force}`]; } return `{${parts.join(',')}}`; diff --git a/src/graphql/hybrid.ts b/src/graphql/hybrid.ts index 03d01fbe..2642423c 100644 --- a/src/graphql/hybrid.ts +++ b/src/graphql/hybrid.ts @@ -1,20 +1,21 @@ -import { isValidNumber, isValidNumberArray } from '../validation/number'; -import { isValidStringProperty } from '../validation/string'; +export interface HybridArgs { + alpha?: number; + query: string; + vector?: number[]; +} export default class GraphQLHybrid { private alpha?: number; - private query?: string; - private source: any; + private query: string; private vector?: number[]; - constructor(hybridObj: any) { - this.source = hybridObj; + constructor(args: HybridArgs) { + this.alpha = args.alpha; + this.query = args.query; + this.vector = args.vector; } toString() { - this.parse(); - this.validate(); - let args = [`query:${JSON.stringify(this.query)}`]; // query must always be set if (this.alpha !== undefined) { @@ -27,52 +28,4 @@ export default class GraphQLHybrid { return `{${args.join(',')}}`; } - - parse() { - for (const key in this.source) { - switch (key) { - case 'query': - this.parseQuery(this.source[key]); - break; - case 'alpha': - this.parseAlpha(this.source[key]); - break; - case 'vector': - this.parseVector(this.source[key]); - break; - default: - throw new Error(`hybrid filter: unrecognized key '${key}'`); - } - } - } - - parseQuery(query: string) { - if (!isValidStringProperty(query)) { - throw new Error('hybrid filter: query must be a string'); - } - - this.query = query; - } - - parseAlpha(alpha: number) { - if (!isValidNumber(alpha)) { - throw new Error('hybrid filter: alpha must be a number'); - } - - this.alpha = alpha; - } - - parseVector(vector: number[]) { - if (!isValidNumberArray(vector) || vector.length == 0) { - throw new Error('hybrid filter: vector must be an array of numbers'); - } - - this.vector = vector; - } - - validate() { - if (!this.query) { - throw new Error('hybrid filter: query cannot be empty'); - } - } } diff --git a/src/graphql/journey.test.ts b/src/graphql/journey.test.ts index 31cbdca1..6b362243 100644 --- a/src/graphql/journey.test.ts +++ b/src/graphql/journey.test.ts @@ -1,5 +1,4 @@ -import weaviate, { WeaviateClient } from '../index'; -import Connection from '../connection'; +import weaviate, { WeaviateClient } from '..'; describe('the graphql journey', () => { let client: WeaviateClient; @@ -58,7 +57,7 @@ describe('the graphql journey', () => { .withFields('title url wordCount') .withNearText({ concepts: ['news'], certainty: 0.1 }) .withWhere({ - operator: weaviate.filters.Operator.GREATER_THAN_EQUAL, + operator: 'GreaterThanEqual', path: ['wordCount'], valueInt: 50, }) @@ -79,7 +78,7 @@ describe('the graphql journey', () => { .withFields('title url wordCount') .withNearText({ concepts: ['news'], distance: 0.9 }) .withWhere({ - operator: weaviate.filters.Operator.GREATER_THAN_EQUAL, + operator: 'GreaterThanEqual', path: ['wordCount'], valueInt: 50, }) @@ -110,60 +109,44 @@ describe('the graphql journey', () => { test('graphql get with nearVector (with certainty)', () => { const searchVec = [ - -0.15047126, 0.061322376, -0.17812507, 0.12811552, 0.36847013, - -0.50840724, -0.10406531, 0.11413283, 0.2997712, 0.7039331, 0.22155242, - 0.1413957, 0.025396502, 0.14802167, 0.26640236, 0.15965445, -0.45570126, - -0.5215438, 0.14628491, 0.10946681, 0.0040095793, 0.017442623, -0.1988451, - -0.05362646, 0.104278944, -0.2506941, 0.2667653, 0.36438593, -0.44370207, - 0.07204353, 0.077371456, 0.14557181, 0.6026817, 0.45073593, 0.09438019, - 0.03936342, -0.20441438, 0.12333719, -0.20247602, 0.5078446, -0.06079732, - -0.02166342, 0.02165861, -0.11712191, 0.0493167, -0.012123002, 0.26458082, - -0.10784768, -0.26852348, 0.049759883, -0.39999008, -0.08977922, - 0.003169497, -0.36184034, -0.069065355, 0.18940343, 0.5684866, - -0.24626277, -0.2326087, 0.090373255, 0.33161184, -1.0541122, - -0.039116446, -0.17496277, -0.16834813, -0.0765323, -0.16189013, - -0.062876746, -0.19826415, 0.07437007, -0.018362755, 0.23634757, - -0.19062655, -0.26524994, 0.33691254, -0.1926698, 0.018848037, 0.1735524, - 0.34301907, -0.014238952, -0.07596742, -0.61302894, -0.044652265, - 0.1545376, 0.67256856, 0.08630557, 0.50236076, 0.23438522, 0.27686095, - 0.13633616, -0.27525797, 0.04282576, 0.18319897, -0.008353968, - -0.27330264, 0.12624736, -0.17051372, -0.35854533, -0.008455927, 0.154786, - -0.20306401, -0.09021733, 0.80594194, 0.036562894, -0.48894945, - -0.27981675, -0.5001396, -0.3581464, -0.057082724, -0.0051904973, - -0.3209166, 0.057098284, 0.111587055, -0.09097725, -0.213181, -0.5038173, - -0.024070809, -0.05350453, 0.13345918, -0.42136985, 0.24050911, - -0.2556207, 0.03156968, 0.4381214, 0.053237516, -0.20783865, 1.885739, - 0.28429136, -0.12231187, -0.30934808, 0.032250155, -0.32959512, - 0.08670603, -0.60112613, -0.43010503, 0.70870006, 0.3548015, -0.010406012, - 0.036294986, 0.0030629474, -0.017579105, 0.28948352, -0.48063236, - -0.39739868, 0.17860937, 0.5099417, -0.24304488, -0.12671146, - -0.018249692, -0.32057074, -0.08146134, 0.3572229, -0.47601065, - 0.35100546, -0.19663939, 0.34194613, -0.04653828, 0.47278664, -0.8723091, - -0.19756387, -0.5890681, 0.16688067, -0.23709822, -0.26478595, - -0.18792373, 0.2204168, 0.030987943, 0.15885714, -0.38817936, -0.4194334, - -0.3287098, 0.15394142, -0.09496768, 0.6561987, -0.39340565, -0.5479265, - -0.22363484, -0.1193662, 0.2014849, 0.31138006, -0.45485613, -0.9879565, - 0.3708223, 0.17318928, 0.21229307, 0.042776756, -0.077399045, 0.42621315, - -0.09917796, 0.34220153, 0.06380378, 0.14129028, -0.14563583, -0.07081333, - 0.026335392, 0.10566285, -0.28074324, -0.059861198, -0.24855351, - 0.13623764, -0.8228192, -0.15095113, 0.16250934, 0.031107651, -0.1504525, - 0.20840737, 0.12919411, -0.0926323, 0.30937102, 0.16636328, -0.36754072, - 0.035581365, -0.2799259, 0.1446048, -0.11680267, 0.13226685, 0.175023, - -0.18840964, 0.27609056, -0.09350581, 0.08284562, 0.45897093, 0.13188471, - -0.07115303, 0.18009436, 0.16689545, -0.6991295, 0.26496106, -0.29619592, - -0.19242188, -0.6362671, -0.16330126, 0.2474778, 0.37738156, -0.12921557, - -0.07843309, 0.28509396, 0.5658691, 0.16096894, 0.095068075, 0.02419672, - -0.30691084, 0.21180221, 0.21670066, 0.0027263877, 0.30853105, - -0.16187873, 0.20786561, 0.22136153, -0.008828387, -0.011165021, - 0.60076475, 0.0089871045, 0.6179727, -0.38049766, -0.08179336, - -0.15306218, -0.13186441, -0.5360041, -0.06123339, -0.06399122, - 0.21292226, -0.18383273, -0.21540102, 0.28566808, -0.29953584, - -0.36946672, 0.03341637, -0.08435299, -0.5381947, -0.28651953, 0.08704594, - -0.25493965, 0.0019178925, -0.7242109, 0.3578676, -0.55617595, - -0.01930952, 0.32922924, 0.14903364, 0.21613406, -0.11927183, 0.15165499, - -0.10101261, 0.2499076, -0.18526322, -0.057230365, 0.10008554, 0.16178907, - 0.39356324, -0.03106238, 0.09375929, 0.17185533, 0.10400415, -0.36850816, - 0.18424486, -0.081376314, 0.23645392, 0.05198973, 0.09471436, + -0.15047126, 0.061322376, -0.17812507, 0.12811552, 0.36847013, -0.50840724, -0.10406531, 0.11413283, + 0.2997712, 0.7039331, 0.22155242, 0.1413957, 0.025396502, 0.14802167, 0.26640236, 0.15965445, + -0.45570126, -0.5215438, 0.14628491, 0.10946681, 0.0040095793, 0.017442623, -0.1988451, -0.05362646, + 0.104278944, -0.2506941, 0.2667653, 0.36438593, -0.44370207, 0.07204353, 0.077371456, 0.14557181, + 0.6026817, 0.45073593, 0.09438019, 0.03936342, -0.20441438, 0.12333719, -0.20247602, 0.5078446, + -0.06079732, -0.02166342, 0.02165861, -0.11712191, 0.0493167, -0.012123002, 0.26458082, -0.10784768, + -0.26852348, 0.049759883, -0.39999008, -0.08977922, 0.003169497, -0.36184034, -0.069065355, 0.18940343, + 0.5684866, -0.24626277, -0.2326087, 0.090373255, 0.33161184, -1.0541122, -0.039116446, -0.17496277, + -0.16834813, -0.0765323, -0.16189013, -0.062876746, -0.19826415, 0.07437007, -0.018362755, 0.23634757, + -0.19062655, -0.26524994, 0.33691254, -0.1926698, 0.018848037, 0.1735524, 0.34301907, -0.014238952, + -0.07596742, -0.61302894, -0.044652265, 0.1545376, 0.67256856, 0.08630557, 0.50236076, 0.23438522, + 0.27686095, 0.13633616, -0.27525797, 0.04282576, 0.18319897, -0.008353968, -0.27330264, 0.12624736, + -0.17051372, -0.35854533, -0.008455927, 0.154786, -0.20306401, -0.09021733, 0.80594194, 0.036562894, + -0.48894945, -0.27981675, -0.5001396, -0.3581464, -0.057082724, -0.0051904973, -0.3209166, 0.057098284, + 0.111587055, -0.09097725, -0.213181, -0.5038173, -0.024070809, -0.05350453, 0.13345918, -0.42136985, + 0.24050911, -0.2556207, 0.03156968, 0.4381214, 0.053237516, -0.20783865, 1.885739, 0.28429136, + -0.12231187, -0.30934808, 0.032250155, -0.32959512, 0.08670603, -0.60112613, -0.43010503, 0.70870006, + 0.3548015, -0.010406012, 0.036294986, 0.0030629474, -0.017579105, 0.28948352, -0.48063236, -0.39739868, + 0.17860937, 0.5099417, -0.24304488, -0.12671146, -0.018249692, -0.32057074, -0.08146134, 0.3572229, + -0.47601065, 0.35100546, -0.19663939, 0.34194613, -0.04653828, 0.47278664, -0.8723091, -0.19756387, + -0.5890681, 0.16688067, -0.23709822, -0.26478595, -0.18792373, 0.2204168, 0.030987943, 0.15885714, + -0.38817936, -0.4194334, -0.3287098, 0.15394142, -0.09496768, 0.6561987, -0.39340565, -0.5479265, + -0.22363484, -0.1193662, 0.2014849, 0.31138006, -0.45485613, -0.9879565, 0.3708223, 0.17318928, + 0.21229307, 0.042776756, -0.077399045, 0.42621315, -0.09917796, 0.34220153, 0.06380378, 0.14129028, + -0.14563583, -0.07081333, 0.026335392, 0.10566285, -0.28074324, -0.059861198, -0.24855351, 0.13623764, + -0.8228192, -0.15095113, 0.16250934, 0.031107651, -0.1504525, 0.20840737, 0.12919411, -0.0926323, + 0.30937102, 0.16636328, -0.36754072, 0.035581365, -0.2799259, 0.1446048, -0.11680267, 0.13226685, + 0.175023, -0.18840964, 0.27609056, -0.09350581, 0.08284562, 0.45897093, 0.13188471, -0.07115303, + 0.18009436, 0.16689545, -0.6991295, 0.26496106, -0.29619592, -0.19242188, -0.6362671, -0.16330126, + 0.2474778, 0.37738156, -0.12921557, -0.07843309, 0.28509396, 0.5658691, 0.16096894, 0.095068075, + 0.02419672, -0.30691084, 0.21180221, 0.21670066, 0.0027263877, 0.30853105, -0.16187873, 0.20786561, + 0.22136153, -0.008828387, -0.011165021, 0.60076475, 0.0089871045, 0.6179727, -0.38049766, -0.08179336, + -0.15306218, -0.13186441, -0.5360041, -0.06123339, -0.06399122, 0.21292226, -0.18383273, -0.21540102, + 0.28566808, -0.29953584, -0.36946672, 0.03341637, -0.08435299, -0.5381947, -0.28651953, 0.08704594, + -0.25493965, 0.0019178925, -0.7242109, 0.3578676, -0.55617595, -0.01930952, 0.32922924, 0.14903364, + 0.21613406, -0.11927183, 0.15165499, -0.10101261, 0.2499076, -0.18526322, -0.057230365, 0.10008554, + 0.16178907, 0.39356324, -0.03106238, 0.09375929, 0.17185533, 0.10400415, -0.36850816, 0.18424486, + -0.081376314, 0.23645392, 0.05198973, 0.09471436, ]; return client.graphql @@ -182,60 +165,44 @@ describe('the graphql journey', () => { test('graphql get with nearVector (with distance)', () => { const searchVec = [ - -0.15047126, 0.061322376, -0.17812507, 0.12811552, 0.36847013, - -0.50840724, -0.10406531, 0.11413283, 0.2997712, 0.7039331, 0.22155242, - 0.1413957, 0.025396502, 0.14802167, 0.26640236, 0.15965445, -0.45570126, - -0.5215438, 0.14628491, 0.10946681, 0.0040095793, 0.017442623, -0.1988451, - -0.05362646, 0.104278944, -0.2506941, 0.2667653, 0.36438593, -0.44370207, - 0.07204353, 0.077371456, 0.14557181, 0.6026817, 0.45073593, 0.09438019, - 0.03936342, -0.20441438, 0.12333719, -0.20247602, 0.5078446, -0.06079732, - -0.02166342, 0.02165861, -0.11712191, 0.0493167, -0.012123002, 0.26458082, - -0.10784768, -0.26852348, 0.049759883, -0.39999008, -0.08977922, - 0.003169497, -0.36184034, -0.069065355, 0.18940343, 0.5684866, - -0.24626277, -0.2326087, 0.090373255, 0.33161184, -1.0541122, - -0.039116446, -0.17496277, -0.16834813, -0.0765323, -0.16189013, - -0.062876746, -0.19826415, 0.07437007, -0.018362755, 0.23634757, - -0.19062655, -0.26524994, 0.33691254, -0.1926698, 0.018848037, 0.1735524, - 0.34301907, -0.014238952, -0.07596742, -0.61302894, -0.044652265, - 0.1545376, 0.67256856, 0.08630557, 0.50236076, 0.23438522, 0.27686095, - 0.13633616, -0.27525797, 0.04282576, 0.18319897, -0.008353968, - -0.27330264, 0.12624736, -0.17051372, -0.35854533, -0.008455927, 0.154786, - -0.20306401, -0.09021733, 0.80594194, 0.036562894, -0.48894945, - -0.27981675, -0.5001396, -0.3581464, -0.057082724, -0.0051904973, - -0.3209166, 0.057098284, 0.111587055, -0.09097725, -0.213181, -0.5038173, - -0.024070809, -0.05350453, 0.13345918, -0.42136985, 0.24050911, - -0.2556207, 0.03156968, 0.4381214, 0.053237516, -0.20783865, 1.885739, - 0.28429136, -0.12231187, -0.30934808, 0.032250155, -0.32959512, - 0.08670603, -0.60112613, -0.43010503, 0.70870006, 0.3548015, -0.010406012, - 0.036294986, 0.0030629474, -0.017579105, 0.28948352, -0.48063236, - -0.39739868, 0.17860937, 0.5099417, -0.24304488, -0.12671146, - -0.018249692, -0.32057074, -0.08146134, 0.3572229, -0.47601065, - 0.35100546, -0.19663939, 0.34194613, -0.04653828, 0.47278664, -0.8723091, - -0.19756387, -0.5890681, 0.16688067, -0.23709822, -0.26478595, - -0.18792373, 0.2204168, 0.030987943, 0.15885714, -0.38817936, -0.4194334, - -0.3287098, 0.15394142, -0.09496768, 0.6561987, -0.39340565, -0.5479265, - -0.22363484, -0.1193662, 0.2014849, 0.31138006, -0.45485613, -0.9879565, - 0.3708223, 0.17318928, 0.21229307, 0.042776756, -0.077399045, 0.42621315, - -0.09917796, 0.34220153, 0.06380378, 0.14129028, -0.14563583, -0.07081333, - 0.026335392, 0.10566285, -0.28074324, -0.059861198, -0.24855351, - 0.13623764, -0.8228192, -0.15095113, 0.16250934, 0.031107651, -0.1504525, - 0.20840737, 0.12919411, -0.0926323, 0.30937102, 0.16636328, -0.36754072, - 0.035581365, -0.2799259, 0.1446048, -0.11680267, 0.13226685, 0.175023, - -0.18840964, 0.27609056, -0.09350581, 0.08284562, 0.45897093, 0.13188471, - -0.07115303, 0.18009436, 0.16689545, -0.6991295, 0.26496106, -0.29619592, - -0.19242188, -0.6362671, -0.16330126, 0.2474778, 0.37738156, -0.12921557, - -0.07843309, 0.28509396, 0.5658691, 0.16096894, 0.095068075, 0.02419672, - -0.30691084, 0.21180221, 0.21670066, 0.0027263877, 0.30853105, - -0.16187873, 0.20786561, 0.22136153, -0.008828387, -0.011165021, - 0.60076475, 0.0089871045, 0.6179727, -0.38049766, -0.08179336, - -0.15306218, -0.13186441, -0.5360041, -0.06123339, -0.06399122, - 0.21292226, -0.18383273, -0.21540102, 0.28566808, -0.29953584, - -0.36946672, 0.03341637, -0.08435299, -0.5381947, -0.28651953, 0.08704594, - -0.25493965, 0.0019178925, -0.7242109, 0.3578676, -0.55617595, - -0.01930952, 0.32922924, 0.14903364, 0.21613406, -0.11927183, 0.15165499, - -0.10101261, 0.2499076, -0.18526322, -0.057230365, 0.10008554, 0.16178907, - 0.39356324, -0.03106238, 0.09375929, 0.17185533, 0.10400415, -0.36850816, - 0.18424486, -0.081376314, 0.23645392, 0.05198973, 0.09471436, + -0.15047126, 0.061322376, -0.17812507, 0.12811552, 0.36847013, -0.50840724, -0.10406531, 0.11413283, + 0.2997712, 0.7039331, 0.22155242, 0.1413957, 0.025396502, 0.14802167, 0.26640236, 0.15965445, + -0.45570126, -0.5215438, 0.14628491, 0.10946681, 0.0040095793, 0.017442623, -0.1988451, -0.05362646, + 0.104278944, -0.2506941, 0.2667653, 0.36438593, -0.44370207, 0.07204353, 0.077371456, 0.14557181, + 0.6026817, 0.45073593, 0.09438019, 0.03936342, -0.20441438, 0.12333719, -0.20247602, 0.5078446, + -0.06079732, -0.02166342, 0.02165861, -0.11712191, 0.0493167, -0.012123002, 0.26458082, -0.10784768, + -0.26852348, 0.049759883, -0.39999008, -0.08977922, 0.003169497, -0.36184034, -0.069065355, 0.18940343, + 0.5684866, -0.24626277, -0.2326087, 0.090373255, 0.33161184, -1.0541122, -0.039116446, -0.17496277, + -0.16834813, -0.0765323, -0.16189013, -0.062876746, -0.19826415, 0.07437007, -0.018362755, 0.23634757, + -0.19062655, -0.26524994, 0.33691254, -0.1926698, 0.018848037, 0.1735524, 0.34301907, -0.014238952, + -0.07596742, -0.61302894, -0.044652265, 0.1545376, 0.67256856, 0.08630557, 0.50236076, 0.23438522, + 0.27686095, 0.13633616, -0.27525797, 0.04282576, 0.18319897, -0.008353968, -0.27330264, 0.12624736, + -0.17051372, -0.35854533, -0.008455927, 0.154786, -0.20306401, -0.09021733, 0.80594194, 0.036562894, + -0.48894945, -0.27981675, -0.5001396, -0.3581464, -0.057082724, -0.0051904973, -0.3209166, 0.057098284, + 0.111587055, -0.09097725, -0.213181, -0.5038173, -0.024070809, -0.05350453, 0.13345918, -0.42136985, + 0.24050911, -0.2556207, 0.03156968, 0.4381214, 0.053237516, -0.20783865, 1.885739, 0.28429136, + -0.12231187, -0.30934808, 0.032250155, -0.32959512, 0.08670603, -0.60112613, -0.43010503, 0.70870006, + 0.3548015, -0.010406012, 0.036294986, 0.0030629474, -0.017579105, 0.28948352, -0.48063236, -0.39739868, + 0.17860937, 0.5099417, -0.24304488, -0.12671146, -0.018249692, -0.32057074, -0.08146134, 0.3572229, + -0.47601065, 0.35100546, -0.19663939, 0.34194613, -0.04653828, 0.47278664, -0.8723091, -0.19756387, + -0.5890681, 0.16688067, -0.23709822, -0.26478595, -0.18792373, 0.2204168, 0.030987943, 0.15885714, + -0.38817936, -0.4194334, -0.3287098, 0.15394142, -0.09496768, 0.6561987, -0.39340565, -0.5479265, + -0.22363484, -0.1193662, 0.2014849, 0.31138006, -0.45485613, -0.9879565, 0.3708223, 0.17318928, + 0.21229307, 0.042776756, -0.077399045, 0.42621315, -0.09917796, 0.34220153, 0.06380378, 0.14129028, + -0.14563583, -0.07081333, 0.026335392, 0.10566285, -0.28074324, -0.059861198, -0.24855351, 0.13623764, + -0.8228192, -0.15095113, 0.16250934, 0.031107651, -0.1504525, 0.20840737, 0.12919411, -0.0926323, + 0.30937102, 0.16636328, -0.36754072, 0.035581365, -0.2799259, 0.1446048, -0.11680267, 0.13226685, + 0.175023, -0.18840964, 0.27609056, -0.09350581, 0.08284562, 0.45897093, 0.13188471, -0.07115303, + 0.18009436, 0.16689545, -0.6991295, 0.26496106, -0.29619592, -0.19242188, -0.6362671, -0.16330126, + 0.2474778, 0.37738156, -0.12921557, -0.07843309, 0.28509396, 0.5658691, 0.16096894, 0.095068075, + 0.02419672, -0.30691084, 0.21180221, 0.21670066, 0.0027263877, 0.30853105, -0.16187873, 0.20786561, + 0.22136153, -0.008828387, -0.011165021, 0.60076475, 0.0089871045, 0.6179727, -0.38049766, -0.08179336, + -0.15306218, -0.13186441, -0.5360041, -0.06123339, -0.06399122, 0.21292226, -0.18383273, -0.21540102, + 0.28566808, -0.29953584, -0.36946672, 0.03341637, -0.08435299, -0.5381947, -0.28651953, 0.08704594, + -0.25493965, 0.0019178925, -0.7242109, 0.3578676, -0.55617595, -0.01930952, 0.32922924, 0.14903364, + 0.21613406, -0.11927183, 0.15165499, -0.10101261, 0.2499076, -0.18526322, -0.057230365, 0.10008554, + 0.16178907, 0.39356324, -0.03106238, 0.09375929, 0.17185533, 0.10400415, -0.36850816, 0.18424486, + -0.081376314, 0.23645392, 0.05198973, 0.09471436, ]; return client.graphql @@ -515,7 +482,7 @@ describe('the graphql journey', () => { .withWhere({ path: ['title'], valueString: 'apple', - operator: weaviate.filters.Operator.EQUAL, + operator: 'Equal', }) .withLimit(10) .withFields('meta { count }') @@ -531,60 +498,44 @@ describe('the graphql journey', () => { test('graphql aggregate method with nearVector (with certainty)', () => { const searchVec = [ - -0.15047126, 0.061322376, -0.17812507, 0.12811552, 0.36847013, - -0.50840724, -0.10406531, 0.11413283, 0.2997712, 0.7039331, 0.22155242, - 0.1413957, 0.025396502, 0.14802167, 0.26640236, 0.15965445, -0.45570126, - -0.5215438, 0.14628491, 0.10946681, 0.0040095793, 0.017442623, -0.1988451, - -0.05362646, 0.104278944, -0.2506941, 0.2667653, 0.36438593, -0.44370207, - 0.07204353, 0.077371456, 0.14557181, 0.6026817, 0.45073593, 0.09438019, - 0.03936342, -0.20441438, 0.12333719, -0.20247602, 0.5078446, -0.06079732, - -0.02166342, 0.02165861, -0.11712191, 0.0493167, -0.012123002, 0.26458082, - -0.10784768, -0.26852348, 0.049759883, -0.39999008, -0.08977922, - 0.003169497, -0.36184034, -0.069065355, 0.18940343, 0.5684866, - -0.24626277, -0.2326087, 0.090373255, 0.33161184, -1.0541122, - -0.039116446, -0.17496277, -0.16834813, -0.0765323, -0.16189013, - -0.062876746, -0.19826415, 0.07437007, -0.018362755, 0.23634757, - -0.19062655, -0.26524994, 0.33691254, -0.1926698, 0.018848037, 0.1735524, - 0.34301907, -0.014238952, -0.07596742, -0.61302894, -0.044652265, - 0.1545376, 0.67256856, 0.08630557, 0.50236076, 0.23438522, 0.27686095, - 0.13633616, -0.27525797, 0.04282576, 0.18319897, -0.008353968, - -0.27330264, 0.12624736, -0.17051372, -0.35854533, -0.008455927, 0.154786, - -0.20306401, -0.09021733, 0.80594194, 0.036562894, -0.48894945, - -0.27981675, -0.5001396, -0.3581464, -0.057082724, -0.0051904973, - -0.3209166, 0.057098284, 0.111587055, -0.09097725, -0.213181, -0.5038173, - -0.024070809, -0.05350453, 0.13345918, -0.42136985, 0.24050911, - -0.2556207, 0.03156968, 0.4381214, 0.053237516, -0.20783865, 1.885739, - 0.28429136, -0.12231187, -0.30934808, 0.032250155, -0.32959512, - 0.08670603, -0.60112613, -0.43010503, 0.70870006, 0.3548015, -0.010406012, - 0.036294986, 0.0030629474, -0.017579105, 0.28948352, -0.48063236, - -0.39739868, 0.17860937, 0.5099417, -0.24304488, -0.12671146, - -0.018249692, -0.32057074, -0.08146134, 0.3572229, -0.47601065, - 0.35100546, -0.19663939, 0.34194613, -0.04653828, 0.47278664, -0.8723091, - -0.19756387, -0.5890681, 0.16688067, -0.23709822, -0.26478595, - -0.18792373, 0.2204168, 0.030987943, 0.15885714, -0.38817936, -0.4194334, - -0.3287098, 0.15394142, -0.09496768, 0.6561987, -0.39340565, -0.5479265, - -0.22363484, -0.1193662, 0.2014849, 0.31138006, -0.45485613, -0.9879565, - 0.3708223, 0.17318928, 0.21229307, 0.042776756, -0.077399045, 0.42621315, - -0.09917796, 0.34220153, 0.06380378, 0.14129028, -0.14563583, -0.07081333, - 0.026335392, 0.10566285, -0.28074324, -0.059861198, -0.24855351, - 0.13623764, -0.8228192, -0.15095113, 0.16250934, 0.031107651, -0.1504525, - 0.20840737, 0.12919411, -0.0926323, 0.30937102, 0.16636328, -0.36754072, - 0.035581365, -0.2799259, 0.1446048, -0.11680267, 0.13226685, 0.175023, - -0.18840964, 0.27609056, -0.09350581, 0.08284562, 0.45897093, 0.13188471, - -0.07115303, 0.18009436, 0.16689545, -0.6991295, 0.26496106, -0.29619592, - -0.19242188, -0.6362671, -0.16330126, 0.2474778, 0.37738156, -0.12921557, - -0.07843309, 0.28509396, 0.5658691, 0.16096894, 0.095068075, 0.02419672, - -0.30691084, 0.21180221, 0.21670066, 0.0027263877, 0.30853105, - -0.16187873, 0.20786561, 0.22136153, -0.008828387, -0.011165021, - 0.60076475, 0.0089871045, 0.6179727, -0.38049766, -0.08179336, - -0.15306218, -0.13186441, -0.5360041, -0.06123339, -0.06399122, - 0.21292226, -0.18383273, -0.21540102, 0.28566808, -0.29953584, - -0.36946672, 0.03341637, -0.08435299, -0.5381947, -0.28651953, 0.08704594, - -0.25493965, 0.0019178925, -0.7242109, 0.3578676, -0.55617595, - -0.01930952, 0.32922924, 0.14903364, 0.21613406, -0.11927183, 0.15165499, - -0.10101261, 0.2499076, -0.18526322, -0.057230365, 0.10008554, 0.16178907, - 0.39356324, -0.03106238, 0.09375929, 0.17185533, 0.10400415, -0.36850816, - 0.18424486, -0.081376314, 0.23645392, 0.05198973, 0.09471436, + -0.15047126, 0.061322376, -0.17812507, 0.12811552, 0.36847013, -0.50840724, -0.10406531, 0.11413283, + 0.2997712, 0.7039331, 0.22155242, 0.1413957, 0.025396502, 0.14802167, 0.26640236, 0.15965445, + -0.45570126, -0.5215438, 0.14628491, 0.10946681, 0.0040095793, 0.017442623, -0.1988451, -0.05362646, + 0.104278944, -0.2506941, 0.2667653, 0.36438593, -0.44370207, 0.07204353, 0.077371456, 0.14557181, + 0.6026817, 0.45073593, 0.09438019, 0.03936342, -0.20441438, 0.12333719, -0.20247602, 0.5078446, + -0.06079732, -0.02166342, 0.02165861, -0.11712191, 0.0493167, -0.012123002, 0.26458082, -0.10784768, + -0.26852348, 0.049759883, -0.39999008, -0.08977922, 0.003169497, -0.36184034, -0.069065355, 0.18940343, + 0.5684866, -0.24626277, -0.2326087, 0.090373255, 0.33161184, -1.0541122, -0.039116446, -0.17496277, + -0.16834813, -0.0765323, -0.16189013, -0.062876746, -0.19826415, 0.07437007, -0.018362755, 0.23634757, + -0.19062655, -0.26524994, 0.33691254, -0.1926698, 0.018848037, 0.1735524, 0.34301907, -0.014238952, + -0.07596742, -0.61302894, -0.044652265, 0.1545376, 0.67256856, 0.08630557, 0.50236076, 0.23438522, + 0.27686095, 0.13633616, -0.27525797, 0.04282576, 0.18319897, -0.008353968, -0.27330264, 0.12624736, + -0.17051372, -0.35854533, -0.008455927, 0.154786, -0.20306401, -0.09021733, 0.80594194, 0.036562894, + -0.48894945, -0.27981675, -0.5001396, -0.3581464, -0.057082724, -0.0051904973, -0.3209166, 0.057098284, + 0.111587055, -0.09097725, -0.213181, -0.5038173, -0.024070809, -0.05350453, 0.13345918, -0.42136985, + 0.24050911, -0.2556207, 0.03156968, 0.4381214, 0.053237516, -0.20783865, 1.885739, 0.28429136, + -0.12231187, -0.30934808, 0.032250155, -0.32959512, 0.08670603, -0.60112613, -0.43010503, 0.70870006, + 0.3548015, -0.010406012, 0.036294986, 0.0030629474, -0.017579105, 0.28948352, -0.48063236, -0.39739868, + 0.17860937, 0.5099417, -0.24304488, -0.12671146, -0.018249692, -0.32057074, -0.08146134, 0.3572229, + -0.47601065, 0.35100546, -0.19663939, 0.34194613, -0.04653828, 0.47278664, -0.8723091, -0.19756387, + -0.5890681, 0.16688067, -0.23709822, -0.26478595, -0.18792373, 0.2204168, 0.030987943, 0.15885714, + -0.38817936, -0.4194334, -0.3287098, 0.15394142, -0.09496768, 0.6561987, -0.39340565, -0.5479265, + -0.22363484, -0.1193662, 0.2014849, 0.31138006, -0.45485613, -0.9879565, 0.3708223, 0.17318928, + 0.21229307, 0.042776756, -0.077399045, 0.42621315, -0.09917796, 0.34220153, 0.06380378, 0.14129028, + -0.14563583, -0.07081333, 0.026335392, 0.10566285, -0.28074324, -0.059861198, -0.24855351, 0.13623764, + -0.8228192, -0.15095113, 0.16250934, 0.031107651, -0.1504525, 0.20840737, 0.12919411, -0.0926323, + 0.30937102, 0.16636328, -0.36754072, 0.035581365, -0.2799259, 0.1446048, -0.11680267, 0.13226685, + 0.175023, -0.18840964, 0.27609056, -0.09350581, 0.08284562, 0.45897093, 0.13188471, -0.07115303, + 0.18009436, 0.16689545, -0.6991295, 0.26496106, -0.29619592, -0.19242188, -0.6362671, -0.16330126, + 0.2474778, 0.37738156, -0.12921557, -0.07843309, 0.28509396, 0.5658691, 0.16096894, 0.095068075, + 0.02419672, -0.30691084, 0.21180221, 0.21670066, 0.0027263877, 0.30853105, -0.16187873, 0.20786561, + 0.22136153, -0.008828387, -0.011165021, 0.60076475, 0.0089871045, 0.6179727, -0.38049766, -0.08179336, + -0.15306218, -0.13186441, -0.5360041, -0.06123339, -0.06399122, 0.21292226, -0.18383273, -0.21540102, + 0.28566808, -0.29953584, -0.36946672, 0.03341637, -0.08435299, -0.5381947, -0.28651953, 0.08704594, + -0.25493965, 0.0019178925, -0.7242109, 0.3578676, -0.55617595, -0.01930952, 0.32922924, 0.14903364, + 0.21613406, -0.11927183, 0.15165499, -0.10101261, 0.2499076, -0.18526322, -0.057230365, 0.10008554, + 0.16178907, 0.39356324, -0.03106238, 0.09375929, 0.17185533, 0.10400415, -0.36850816, 0.18424486, + -0.081376314, 0.23645392, 0.05198973, 0.09471436, ]; return client.graphql @@ -604,60 +555,44 @@ describe('the graphql journey', () => { test('graphql aggregate method with nearVector (with distance)', () => { const searchVec = [ - -0.15047126, 0.061322376, -0.17812507, 0.12811552, 0.36847013, - -0.50840724, -0.10406531, 0.11413283, 0.2997712, 0.7039331, 0.22155242, - 0.1413957, 0.025396502, 0.14802167, 0.26640236, 0.15965445, -0.45570126, - -0.5215438, 0.14628491, 0.10946681, 0.0040095793, 0.017442623, -0.1988451, - -0.05362646, 0.104278944, -0.2506941, 0.2667653, 0.36438593, -0.44370207, - 0.07204353, 0.077371456, 0.14557181, 0.6026817, 0.45073593, 0.09438019, - 0.03936342, -0.20441438, 0.12333719, -0.20247602, 0.5078446, -0.06079732, - -0.02166342, 0.02165861, -0.11712191, 0.0493167, -0.012123002, 0.26458082, - -0.10784768, -0.26852348, 0.049759883, -0.39999008, -0.08977922, - 0.003169497, -0.36184034, -0.069065355, 0.18940343, 0.5684866, - -0.24626277, -0.2326087, 0.090373255, 0.33161184, -1.0541122, - -0.039116446, -0.17496277, -0.16834813, -0.0765323, -0.16189013, - -0.062876746, -0.19826415, 0.07437007, -0.018362755, 0.23634757, - -0.19062655, -0.26524994, 0.33691254, -0.1926698, 0.018848037, 0.1735524, - 0.34301907, -0.014238952, -0.07596742, -0.61302894, -0.044652265, - 0.1545376, 0.67256856, 0.08630557, 0.50236076, 0.23438522, 0.27686095, - 0.13633616, -0.27525797, 0.04282576, 0.18319897, -0.008353968, - -0.27330264, 0.12624736, -0.17051372, -0.35854533, -0.008455927, 0.154786, - -0.20306401, -0.09021733, 0.80594194, 0.036562894, -0.48894945, - -0.27981675, -0.5001396, -0.3581464, -0.057082724, -0.0051904973, - -0.3209166, 0.057098284, 0.111587055, -0.09097725, -0.213181, -0.5038173, - -0.024070809, -0.05350453, 0.13345918, -0.42136985, 0.24050911, - -0.2556207, 0.03156968, 0.4381214, 0.053237516, -0.20783865, 1.885739, - 0.28429136, -0.12231187, -0.30934808, 0.032250155, -0.32959512, - 0.08670603, -0.60112613, -0.43010503, 0.70870006, 0.3548015, -0.010406012, - 0.036294986, 0.0030629474, -0.017579105, 0.28948352, -0.48063236, - -0.39739868, 0.17860937, 0.5099417, -0.24304488, -0.12671146, - -0.018249692, -0.32057074, -0.08146134, 0.3572229, -0.47601065, - 0.35100546, -0.19663939, 0.34194613, -0.04653828, 0.47278664, -0.8723091, - -0.19756387, -0.5890681, 0.16688067, -0.23709822, -0.26478595, - -0.18792373, 0.2204168, 0.030987943, 0.15885714, -0.38817936, -0.4194334, - -0.3287098, 0.15394142, -0.09496768, 0.6561987, -0.39340565, -0.5479265, - -0.22363484, -0.1193662, 0.2014849, 0.31138006, -0.45485613, -0.9879565, - 0.3708223, 0.17318928, 0.21229307, 0.042776756, -0.077399045, 0.42621315, - -0.09917796, 0.34220153, 0.06380378, 0.14129028, -0.14563583, -0.07081333, - 0.026335392, 0.10566285, -0.28074324, -0.059861198, -0.24855351, - 0.13623764, -0.8228192, -0.15095113, 0.16250934, 0.031107651, -0.1504525, - 0.20840737, 0.12919411, -0.0926323, 0.30937102, 0.16636328, -0.36754072, - 0.035581365, -0.2799259, 0.1446048, -0.11680267, 0.13226685, 0.175023, - -0.18840964, 0.27609056, -0.09350581, 0.08284562, 0.45897093, 0.13188471, - -0.07115303, 0.18009436, 0.16689545, -0.6991295, 0.26496106, -0.29619592, - -0.19242188, -0.6362671, -0.16330126, 0.2474778, 0.37738156, -0.12921557, - -0.07843309, 0.28509396, 0.5658691, 0.16096894, 0.095068075, 0.02419672, - -0.30691084, 0.21180221, 0.21670066, 0.0027263877, 0.30853105, - -0.16187873, 0.20786561, 0.22136153, -0.008828387, -0.011165021, - 0.60076475, 0.0089871045, 0.6179727, -0.38049766, -0.08179336, - -0.15306218, -0.13186441, -0.5360041, -0.06123339, -0.06399122, - 0.21292226, -0.18383273, -0.21540102, 0.28566808, -0.29953584, - -0.36946672, 0.03341637, -0.08435299, -0.5381947, -0.28651953, 0.08704594, - -0.25493965, 0.0019178925, -0.7242109, 0.3578676, -0.55617595, - -0.01930952, 0.32922924, 0.14903364, 0.21613406, -0.11927183, 0.15165499, - -0.10101261, 0.2499076, -0.18526322, -0.057230365, 0.10008554, 0.16178907, - 0.39356324, -0.03106238, 0.09375929, 0.17185533, 0.10400415, -0.36850816, - 0.18424486, -0.081376314, 0.23645392, 0.05198973, 0.09471436, + -0.15047126, 0.061322376, -0.17812507, 0.12811552, 0.36847013, -0.50840724, -0.10406531, 0.11413283, + 0.2997712, 0.7039331, 0.22155242, 0.1413957, 0.025396502, 0.14802167, 0.26640236, 0.15965445, + -0.45570126, -0.5215438, 0.14628491, 0.10946681, 0.0040095793, 0.017442623, -0.1988451, -0.05362646, + 0.104278944, -0.2506941, 0.2667653, 0.36438593, -0.44370207, 0.07204353, 0.077371456, 0.14557181, + 0.6026817, 0.45073593, 0.09438019, 0.03936342, -0.20441438, 0.12333719, -0.20247602, 0.5078446, + -0.06079732, -0.02166342, 0.02165861, -0.11712191, 0.0493167, -0.012123002, 0.26458082, -0.10784768, + -0.26852348, 0.049759883, -0.39999008, -0.08977922, 0.003169497, -0.36184034, -0.069065355, 0.18940343, + 0.5684866, -0.24626277, -0.2326087, 0.090373255, 0.33161184, -1.0541122, -0.039116446, -0.17496277, + -0.16834813, -0.0765323, -0.16189013, -0.062876746, -0.19826415, 0.07437007, -0.018362755, 0.23634757, + -0.19062655, -0.26524994, 0.33691254, -0.1926698, 0.018848037, 0.1735524, 0.34301907, -0.014238952, + -0.07596742, -0.61302894, -0.044652265, 0.1545376, 0.67256856, 0.08630557, 0.50236076, 0.23438522, + 0.27686095, 0.13633616, -0.27525797, 0.04282576, 0.18319897, -0.008353968, -0.27330264, 0.12624736, + -0.17051372, -0.35854533, -0.008455927, 0.154786, -0.20306401, -0.09021733, 0.80594194, 0.036562894, + -0.48894945, -0.27981675, -0.5001396, -0.3581464, -0.057082724, -0.0051904973, -0.3209166, 0.057098284, + 0.111587055, -0.09097725, -0.213181, -0.5038173, -0.024070809, -0.05350453, 0.13345918, -0.42136985, + 0.24050911, -0.2556207, 0.03156968, 0.4381214, 0.053237516, -0.20783865, 1.885739, 0.28429136, + -0.12231187, -0.30934808, 0.032250155, -0.32959512, 0.08670603, -0.60112613, -0.43010503, 0.70870006, + 0.3548015, -0.010406012, 0.036294986, 0.0030629474, -0.017579105, 0.28948352, -0.48063236, -0.39739868, + 0.17860937, 0.5099417, -0.24304488, -0.12671146, -0.018249692, -0.32057074, -0.08146134, 0.3572229, + -0.47601065, 0.35100546, -0.19663939, 0.34194613, -0.04653828, 0.47278664, -0.8723091, -0.19756387, + -0.5890681, 0.16688067, -0.23709822, -0.26478595, -0.18792373, 0.2204168, 0.030987943, 0.15885714, + -0.38817936, -0.4194334, -0.3287098, 0.15394142, -0.09496768, 0.6561987, -0.39340565, -0.5479265, + -0.22363484, -0.1193662, 0.2014849, 0.31138006, -0.45485613, -0.9879565, 0.3708223, 0.17318928, + 0.21229307, 0.042776756, -0.077399045, 0.42621315, -0.09917796, 0.34220153, 0.06380378, 0.14129028, + -0.14563583, -0.07081333, 0.026335392, 0.10566285, -0.28074324, -0.059861198, -0.24855351, 0.13623764, + -0.8228192, -0.15095113, 0.16250934, 0.031107651, -0.1504525, 0.20840737, 0.12919411, -0.0926323, + 0.30937102, 0.16636328, -0.36754072, 0.035581365, -0.2799259, 0.1446048, -0.11680267, 0.13226685, + 0.175023, -0.18840964, 0.27609056, -0.09350581, 0.08284562, 0.45897093, 0.13188471, -0.07115303, + 0.18009436, 0.16689545, -0.6991295, 0.26496106, -0.29619592, -0.19242188, -0.6362671, -0.16330126, + 0.2474778, 0.37738156, -0.12921557, -0.07843309, 0.28509396, 0.5658691, 0.16096894, 0.095068075, + 0.02419672, -0.30691084, 0.21180221, 0.21670066, 0.0027263877, 0.30853105, -0.16187873, 0.20786561, + 0.22136153, -0.008828387, -0.011165021, 0.60076475, 0.0089871045, 0.6179727, -0.38049766, -0.08179336, + -0.15306218, -0.13186441, -0.5360041, -0.06123339, -0.06399122, 0.21292226, -0.18383273, -0.21540102, + 0.28566808, -0.29953584, -0.36946672, 0.03341637, -0.08435299, -0.5381947, -0.28651953, 0.08704594, + -0.25493965, 0.0019178925, -0.7242109, 0.3578676, -0.55617595, -0.01930952, 0.32922924, 0.14903364, + 0.21613406, -0.11927183, 0.15165499, -0.10101261, 0.2499076, -0.18526322, -0.057230365, 0.10008554, + 0.16178907, 0.39356324, -0.03106238, 0.09375929, 0.17185533, 0.10400415, -0.36850816, 0.18424486, + -0.081376314, 0.23645392, 0.05198973, 0.09471436, ]; return client.graphql @@ -775,60 +710,44 @@ describe('the graphql journey', () => { test('graphql aggregate method with where and nearVector (with certainty)', () => { const searchVec = [ - -0.15047126, 0.061322376, -0.17812507, 0.12811552, 0.36847013, - -0.50840724, -0.10406531, 0.11413283, 0.2997712, 0.7039331, 0.22155242, - 0.1413957, 0.025396502, 0.14802167, 0.26640236, 0.15965445, -0.45570126, - -0.5215438, 0.14628491, 0.10946681, 0.0040095793, 0.017442623, -0.1988451, - -0.05362646, 0.104278944, -0.2506941, 0.2667653, 0.36438593, -0.44370207, - 0.07204353, 0.077371456, 0.14557181, 0.6026817, 0.45073593, 0.09438019, - 0.03936342, -0.20441438, 0.12333719, -0.20247602, 0.5078446, -0.06079732, - -0.02166342, 0.02165861, -0.11712191, 0.0493167, -0.012123002, 0.26458082, - -0.10784768, -0.26852348, 0.049759883, -0.39999008, -0.08977922, - 0.003169497, -0.36184034, -0.069065355, 0.18940343, 0.5684866, - -0.24626277, -0.2326087, 0.090373255, 0.33161184, -1.0541122, - -0.039116446, -0.17496277, -0.16834813, -0.0765323, -0.16189013, - -0.062876746, -0.19826415, 0.07437007, -0.018362755, 0.23634757, - -0.19062655, -0.26524994, 0.33691254, -0.1926698, 0.018848037, 0.1735524, - 0.34301907, -0.014238952, -0.07596742, -0.61302894, -0.044652265, - 0.1545376, 0.67256856, 0.08630557, 0.50236076, 0.23438522, 0.27686095, - 0.13633616, -0.27525797, 0.04282576, 0.18319897, -0.008353968, - -0.27330264, 0.12624736, -0.17051372, -0.35854533, -0.008455927, 0.154786, - -0.20306401, -0.09021733, 0.80594194, 0.036562894, -0.48894945, - -0.27981675, -0.5001396, -0.3581464, -0.057082724, -0.0051904973, - -0.3209166, 0.057098284, 0.111587055, -0.09097725, -0.213181, -0.5038173, - -0.024070809, -0.05350453, 0.13345918, -0.42136985, 0.24050911, - -0.2556207, 0.03156968, 0.4381214, 0.053237516, -0.20783865, 1.885739, - 0.28429136, -0.12231187, -0.30934808, 0.032250155, -0.32959512, - 0.08670603, -0.60112613, -0.43010503, 0.70870006, 0.3548015, -0.010406012, - 0.036294986, 0.0030629474, -0.017579105, 0.28948352, -0.48063236, - -0.39739868, 0.17860937, 0.5099417, -0.24304488, -0.12671146, - -0.018249692, -0.32057074, -0.08146134, 0.3572229, -0.47601065, - 0.35100546, -0.19663939, 0.34194613, -0.04653828, 0.47278664, -0.8723091, - -0.19756387, -0.5890681, 0.16688067, -0.23709822, -0.26478595, - -0.18792373, 0.2204168, 0.030987943, 0.15885714, -0.38817936, -0.4194334, - -0.3287098, 0.15394142, -0.09496768, 0.6561987, -0.39340565, -0.5479265, - -0.22363484, -0.1193662, 0.2014849, 0.31138006, -0.45485613, -0.9879565, - 0.3708223, 0.17318928, 0.21229307, 0.042776756, -0.077399045, 0.42621315, - -0.09917796, 0.34220153, 0.06380378, 0.14129028, -0.14563583, -0.07081333, - 0.026335392, 0.10566285, -0.28074324, -0.059861198, -0.24855351, - 0.13623764, -0.8228192, -0.15095113, 0.16250934, 0.031107651, -0.1504525, - 0.20840737, 0.12919411, -0.0926323, 0.30937102, 0.16636328, -0.36754072, - 0.035581365, -0.2799259, 0.1446048, -0.11680267, 0.13226685, 0.175023, - -0.18840964, 0.27609056, -0.09350581, 0.08284562, 0.45897093, 0.13188471, - -0.07115303, 0.18009436, 0.16689545, -0.6991295, 0.26496106, -0.29619592, - -0.19242188, -0.6362671, -0.16330126, 0.2474778, 0.37738156, -0.12921557, - -0.07843309, 0.28509396, 0.5658691, 0.16096894, 0.095068075, 0.02419672, - -0.30691084, 0.21180221, 0.21670066, 0.0027263877, 0.30853105, - -0.16187873, 0.20786561, 0.22136153, -0.008828387, -0.011165021, - 0.60076475, 0.0089871045, 0.6179727, -0.38049766, -0.08179336, - -0.15306218, -0.13186441, -0.5360041, -0.06123339, -0.06399122, - 0.21292226, -0.18383273, -0.21540102, 0.28566808, -0.29953584, - -0.36946672, 0.03341637, -0.08435299, -0.5381947, -0.28651953, 0.08704594, - -0.25493965, 0.0019178925, -0.7242109, 0.3578676, -0.55617595, - -0.01930952, 0.32922924, 0.14903364, 0.21613406, -0.11927183, 0.15165499, - -0.10101261, 0.2499076, -0.18526322, -0.057230365, 0.10008554, 0.16178907, - 0.39356324, -0.03106238, 0.09375929, 0.17185533, 0.10400415, -0.36850816, - 0.18424486, -0.081376314, 0.23645392, 0.05198973, 0.09471436, + -0.15047126, 0.061322376, -0.17812507, 0.12811552, 0.36847013, -0.50840724, -0.10406531, 0.11413283, + 0.2997712, 0.7039331, 0.22155242, 0.1413957, 0.025396502, 0.14802167, 0.26640236, 0.15965445, + -0.45570126, -0.5215438, 0.14628491, 0.10946681, 0.0040095793, 0.017442623, -0.1988451, -0.05362646, + 0.104278944, -0.2506941, 0.2667653, 0.36438593, -0.44370207, 0.07204353, 0.077371456, 0.14557181, + 0.6026817, 0.45073593, 0.09438019, 0.03936342, -0.20441438, 0.12333719, -0.20247602, 0.5078446, + -0.06079732, -0.02166342, 0.02165861, -0.11712191, 0.0493167, -0.012123002, 0.26458082, -0.10784768, + -0.26852348, 0.049759883, -0.39999008, -0.08977922, 0.003169497, -0.36184034, -0.069065355, 0.18940343, + 0.5684866, -0.24626277, -0.2326087, 0.090373255, 0.33161184, -1.0541122, -0.039116446, -0.17496277, + -0.16834813, -0.0765323, -0.16189013, -0.062876746, -0.19826415, 0.07437007, -0.018362755, 0.23634757, + -0.19062655, -0.26524994, 0.33691254, -0.1926698, 0.018848037, 0.1735524, 0.34301907, -0.014238952, + -0.07596742, -0.61302894, -0.044652265, 0.1545376, 0.67256856, 0.08630557, 0.50236076, 0.23438522, + 0.27686095, 0.13633616, -0.27525797, 0.04282576, 0.18319897, -0.008353968, -0.27330264, 0.12624736, + -0.17051372, -0.35854533, -0.008455927, 0.154786, -0.20306401, -0.09021733, 0.80594194, 0.036562894, + -0.48894945, -0.27981675, -0.5001396, -0.3581464, -0.057082724, -0.0051904973, -0.3209166, 0.057098284, + 0.111587055, -0.09097725, -0.213181, -0.5038173, -0.024070809, -0.05350453, 0.13345918, -0.42136985, + 0.24050911, -0.2556207, 0.03156968, 0.4381214, 0.053237516, -0.20783865, 1.885739, 0.28429136, + -0.12231187, -0.30934808, 0.032250155, -0.32959512, 0.08670603, -0.60112613, -0.43010503, 0.70870006, + 0.3548015, -0.010406012, 0.036294986, 0.0030629474, -0.017579105, 0.28948352, -0.48063236, -0.39739868, + 0.17860937, 0.5099417, -0.24304488, -0.12671146, -0.018249692, -0.32057074, -0.08146134, 0.3572229, + -0.47601065, 0.35100546, -0.19663939, 0.34194613, -0.04653828, 0.47278664, -0.8723091, -0.19756387, + -0.5890681, 0.16688067, -0.23709822, -0.26478595, -0.18792373, 0.2204168, 0.030987943, 0.15885714, + -0.38817936, -0.4194334, -0.3287098, 0.15394142, -0.09496768, 0.6561987, -0.39340565, -0.5479265, + -0.22363484, -0.1193662, 0.2014849, 0.31138006, -0.45485613, -0.9879565, 0.3708223, 0.17318928, + 0.21229307, 0.042776756, -0.077399045, 0.42621315, -0.09917796, 0.34220153, 0.06380378, 0.14129028, + -0.14563583, -0.07081333, 0.026335392, 0.10566285, -0.28074324, -0.059861198, -0.24855351, 0.13623764, + -0.8228192, -0.15095113, 0.16250934, 0.031107651, -0.1504525, 0.20840737, 0.12919411, -0.0926323, + 0.30937102, 0.16636328, -0.36754072, 0.035581365, -0.2799259, 0.1446048, -0.11680267, 0.13226685, + 0.175023, -0.18840964, 0.27609056, -0.09350581, 0.08284562, 0.45897093, 0.13188471, -0.07115303, + 0.18009436, 0.16689545, -0.6991295, 0.26496106, -0.29619592, -0.19242188, -0.6362671, -0.16330126, + 0.2474778, 0.37738156, -0.12921557, -0.07843309, 0.28509396, 0.5658691, 0.16096894, 0.095068075, + 0.02419672, -0.30691084, 0.21180221, 0.21670066, 0.0027263877, 0.30853105, -0.16187873, 0.20786561, + 0.22136153, -0.008828387, -0.011165021, 0.60076475, 0.0089871045, 0.6179727, -0.38049766, -0.08179336, + -0.15306218, -0.13186441, -0.5360041, -0.06123339, -0.06399122, 0.21292226, -0.18383273, -0.21540102, + 0.28566808, -0.29953584, -0.36946672, 0.03341637, -0.08435299, -0.5381947, -0.28651953, 0.08704594, + -0.25493965, 0.0019178925, -0.7242109, 0.3578676, -0.55617595, -0.01930952, 0.32922924, 0.14903364, + 0.21613406, -0.11927183, 0.15165499, -0.10101261, 0.2499076, -0.18526322, -0.057230365, 0.10008554, + 0.16178907, 0.39356324, -0.03106238, 0.09375929, 0.17185533, 0.10400415, -0.36850816, 0.18424486, + -0.081376314, 0.23645392, 0.05198973, 0.09471436, ]; return client.graphql @@ -836,7 +755,7 @@ describe('the graphql journey', () => { .withClassName('Article') .withNearVector({ vector: searchVec, certainty: 0.7 }) .withWhere({ - operator: weaviate.filters.Operator.EQUAL, + operator: 'Equal', path: ['_id'], valueString: 'abefd256-8574-442b-9293-9205193737e0', }) @@ -853,60 +772,44 @@ describe('the graphql journey', () => { test('graphql aggregate method with where and nearVector (with distance)', () => { const searchVec = [ - -0.15047126, 0.061322376, -0.17812507, 0.12811552, 0.36847013, - -0.50840724, -0.10406531, 0.11413283, 0.2997712, 0.7039331, 0.22155242, - 0.1413957, 0.025396502, 0.14802167, 0.26640236, 0.15965445, -0.45570126, - -0.5215438, 0.14628491, 0.10946681, 0.0040095793, 0.017442623, -0.1988451, - -0.05362646, 0.104278944, -0.2506941, 0.2667653, 0.36438593, -0.44370207, - 0.07204353, 0.077371456, 0.14557181, 0.6026817, 0.45073593, 0.09438019, - 0.03936342, -0.20441438, 0.12333719, -0.20247602, 0.5078446, -0.06079732, - -0.02166342, 0.02165861, -0.11712191, 0.0493167, -0.012123002, 0.26458082, - -0.10784768, -0.26852348, 0.049759883, -0.39999008, -0.08977922, - 0.003169497, -0.36184034, -0.069065355, 0.18940343, 0.5684866, - -0.24626277, -0.2326087, 0.090373255, 0.33161184, -1.0541122, - -0.039116446, -0.17496277, -0.16834813, -0.0765323, -0.16189013, - -0.062876746, -0.19826415, 0.07437007, -0.018362755, 0.23634757, - -0.19062655, -0.26524994, 0.33691254, -0.1926698, 0.018848037, 0.1735524, - 0.34301907, -0.014238952, -0.07596742, -0.61302894, -0.044652265, - 0.1545376, 0.67256856, 0.08630557, 0.50236076, 0.23438522, 0.27686095, - 0.13633616, -0.27525797, 0.04282576, 0.18319897, -0.008353968, - -0.27330264, 0.12624736, -0.17051372, -0.35854533, -0.008455927, 0.154786, - -0.20306401, -0.09021733, 0.80594194, 0.036562894, -0.48894945, - -0.27981675, -0.5001396, -0.3581464, -0.057082724, -0.0051904973, - -0.3209166, 0.057098284, 0.111587055, -0.09097725, -0.213181, -0.5038173, - -0.024070809, -0.05350453, 0.13345918, -0.42136985, 0.24050911, - -0.2556207, 0.03156968, 0.4381214, 0.053237516, -0.20783865, 1.885739, - 0.28429136, -0.12231187, -0.30934808, 0.032250155, -0.32959512, - 0.08670603, -0.60112613, -0.43010503, 0.70870006, 0.3548015, -0.010406012, - 0.036294986, 0.0030629474, -0.017579105, 0.28948352, -0.48063236, - -0.39739868, 0.17860937, 0.5099417, -0.24304488, -0.12671146, - -0.018249692, -0.32057074, -0.08146134, 0.3572229, -0.47601065, - 0.35100546, -0.19663939, 0.34194613, -0.04653828, 0.47278664, -0.8723091, - -0.19756387, -0.5890681, 0.16688067, -0.23709822, -0.26478595, - -0.18792373, 0.2204168, 0.030987943, 0.15885714, -0.38817936, -0.4194334, - -0.3287098, 0.15394142, -0.09496768, 0.6561987, -0.39340565, -0.5479265, - -0.22363484, -0.1193662, 0.2014849, 0.31138006, -0.45485613, -0.9879565, - 0.3708223, 0.17318928, 0.21229307, 0.042776756, -0.077399045, 0.42621315, - -0.09917796, 0.34220153, 0.06380378, 0.14129028, -0.14563583, -0.07081333, - 0.026335392, 0.10566285, -0.28074324, -0.059861198, -0.24855351, - 0.13623764, -0.8228192, -0.15095113, 0.16250934, 0.031107651, -0.1504525, - 0.20840737, 0.12919411, -0.0926323, 0.30937102, 0.16636328, -0.36754072, - 0.035581365, -0.2799259, 0.1446048, -0.11680267, 0.13226685, 0.175023, - -0.18840964, 0.27609056, -0.09350581, 0.08284562, 0.45897093, 0.13188471, - -0.07115303, 0.18009436, 0.16689545, -0.6991295, 0.26496106, -0.29619592, - -0.19242188, -0.6362671, -0.16330126, 0.2474778, 0.37738156, -0.12921557, - -0.07843309, 0.28509396, 0.5658691, 0.16096894, 0.095068075, 0.02419672, - -0.30691084, 0.21180221, 0.21670066, 0.0027263877, 0.30853105, - -0.16187873, 0.20786561, 0.22136153, -0.008828387, -0.011165021, - 0.60076475, 0.0089871045, 0.6179727, -0.38049766, -0.08179336, - -0.15306218, -0.13186441, -0.5360041, -0.06123339, -0.06399122, - 0.21292226, -0.18383273, -0.21540102, 0.28566808, -0.29953584, - -0.36946672, 0.03341637, -0.08435299, -0.5381947, -0.28651953, 0.08704594, - -0.25493965, 0.0019178925, -0.7242109, 0.3578676, -0.55617595, - -0.01930952, 0.32922924, 0.14903364, 0.21613406, -0.11927183, 0.15165499, - -0.10101261, 0.2499076, -0.18526322, -0.057230365, 0.10008554, 0.16178907, - 0.39356324, -0.03106238, 0.09375929, 0.17185533, 0.10400415, -0.36850816, - 0.18424486, -0.081376314, 0.23645392, 0.05198973, 0.09471436, + -0.15047126, 0.061322376, -0.17812507, 0.12811552, 0.36847013, -0.50840724, -0.10406531, 0.11413283, + 0.2997712, 0.7039331, 0.22155242, 0.1413957, 0.025396502, 0.14802167, 0.26640236, 0.15965445, + -0.45570126, -0.5215438, 0.14628491, 0.10946681, 0.0040095793, 0.017442623, -0.1988451, -0.05362646, + 0.104278944, -0.2506941, 0.2667653, 0.36438593, -0.44370207, 0.07204353, 0.077371456, 0.14557181, + 0.6026817, 0.45073593, 0.09438019, 0.03936342, -0.20441438, 0.12333719, -0.20247602, 0.5078446, + -0.06079732, -0.02166342, 0.02165861, -0.11712191, 0.0493167, -0.012123002, 0.26458082, -0.10784768, + -0.26852348, 0.049759883, -0.39999008, -0.08977922, 0.003169497, -0.36184034, -0.069065355, 0.18940343, + 0.5684866, -0.24626277, -0.2326087, 0.090373255, 0.33161184, -1.0541122, -0.039116446, -0.17496277, + -0.16834813, -0.0765323, -0.16189013, -0.062876746, -0.19826415, 0.07437007, -0.018362755, 0.23634757, + -0.19062655, -0.26524994, 0.33691254, -0.1926698, 0.018848037, 0.1735524, 0.34301907, -0.014238952, + -0.07596742, -0.61302894, -0.044652265, 0.1545376, 0.67256856, 0.08630557, 0.50236076, 0.23438522, + 0.27686095, 0.13633616, -0.27525797, 0.04282576, 0.18319897, -0.008353968, -0.27330264, 0.12624736, + -0.17051372, -0.35854533, -0.008455927, 0.154786, -0.20306401, -0.09021733, 0.80594194, 0.036562894, + -0.48894945, -0.27981675, -0.5001396, -0.3581464, -0.057082724, -0.0051904973, -0.3209166, 0.057098284, + 0.111587055, -0.09097725, -0.213181, -0.5038173, -0.024070809, -0.05350453, 0.13345918, -0.42136985, + 0.24050911, -0.2556207, 0.03156968, 0.4381214, 0.053237516, -0.20783865, 1.885739, 0.28429136, + -0.12231187, -0.30934808, 0.032250155, -0.32959512, 0.08670603, -0.60112613, -0.43010503, 0.70870006, + 0.3548015, -0.010406012, 0.036294986, 0.0030629474, -0.017579105, 0.28948352, -0.48063236, -0.39739868, + 0.17860937, 0.5099417, -0.24304488, -0.12671146, -0.018249692, -0.32057074, -0.08146134, 0.3572229, + -0.47601065, 0.35100546, -0.19663939, 0.34194613, -0.04653828, 0.47278664, -0.8723091, -0.19756387, + -0.5890681, 0.16688067, -0.23709822, -0.26478595, -0.18792373, 0.2204168, 0.030987943, 0.15885714, + -0.38817936, -0.4194334, -0.3287098, 0.15394142, -0.09496768, 0.6561987, -0.39340565, -0.5479265, + -0.22363484, -0.1193662, 0.2014849, 0.31138006, -0.45485613, -0.9879565, 0.3708223, 0.17318928, + 0.21229307, 0.042776756, -0.077399045, 0.42621315, -0.09917796, 0.34220153, 0.06380378, 0.14129028, + -0.14563583, -0.07081333, 0.026335392, 0.10566285, -0.28074324, -0.059861198, -0.24855351, 0.13623764, + -0.8228192, -0.15095113, 0.16250934, 0.031107651, -0.1504525, 0.20840737, 0.12919411, -0.0926323, + 0.30937102, 0.16636328, -0.36754072, 0.035581365, -0.2799259, 0.1446048, -0.11680267, 0.13226685, + 0.175023, -0.18840964, 0.27609056, -0.09350581, 0.08284562, 0.45897093, 0.13188471, -0.07115303, + 0.18009436, 0.16689545, -0.6991295, 0.26496106, -0.29619592, -0.19242188, -0.6362671, -0.16330126, + 0.2474778, 0.37738156, -0.12921557, -0.07843309, 0.28509396, 0.5658691, 0.16096894, 0.095068075, + 0.02419672, -0.30691084, 0.21180221, 0.21670066, 0.0027263877, 0.30853105, -0.16187873, 0.20786561, + 0.22136153, -0.008828387, -0.011165021, 0.60076475, 0.0089871045, 0.6179727, -0.38049766, -0.08179336, + -0.15306218, -0.13186441, -0.5360041, -0.06123339, -0.06399122, 0.21292226, -0.18383273, -0.21540102, + 0.28566808, -0.29953584, -0.36946672, 0.03341637, -0.08435299, -0.5381947, -0.28651953, 0.08704594, + -0.25493965, 0.0019178925, -0.7242109, 0.3578676, -0.55617595, -0.01930952, 0.32922924, 0.14903364, + 0.21613406, -0.11927183, 0.15165499, -0.10101261, 0.2499076, -0.18526322, -0.057230365, 0.10008554, + 0.16178907, 0.39356324, -0.03106238, 0.09375929, 0.17185533, 0.10400415, -0.36850816, 0.18424486, + -0.081376314, 0.23645392, 0.05198973, 0.09471436, ]; return client.graphql @@ -914,7 +817,7 @@ describe('the graphql journey', () => { .withClassName('Article') .withNearVector({ vector: searchVec, distance: 0.3 }) .withWhere({ - operator: weaviate.filters.Operator.EQUAL, + operator: 'Equal', path: ['_id'], valueString: 'abefd256-8574-442b-9293-9205193737e0', }) @@ -938,7 +841,7 @@ describe('the graphql journey', () => { certainty: 0.7, }) .withWhere({ - operator: weaviate.filters.Operator.EQUAL, + operator: 'Equal', path: ['_id'], valueString: 'abefd256-8574-442b-9293-9205193737e0', }) @@ -962,7 +865,7 @@ describe('the graphql journey', () => { distance: 0.3, }) .withWhere({ - operator: weaviate.filters.Operator.EQUAL, + operator: 'Equal', path: ['_id'], valueString: 'abefd256-8574-442b-9293-9205193737e0', }) @@ -983,7 +886,7 @@ describe('the graphql journey', () => { .withClassName('Article') .withNearText({ concepts: ['Article'], certainty: 0.7 }) .withWhere({ - operator: weaviate.filters.Operator.EQUAL, + operator: 'Equal', path: ['_id'], valueString: 'abefd256-8574-442b-9293-9205193737e0', }) @@ -1004,7 +907,7 @@ describe('the graphql journey', () => { .withClassName('Article') .withNearText({ concepts: ['Article'], distance: 0.3 }) .withWhere({ - operator: weaviate.filters.Operator.EQUAL, + operator: 'Equal', path: ['_id'], valueString: 'abefd256-8574-442b-9293-9205193737e0', }) @@ -1133,9 +1036,7 @@ describe('the graphql journey', () => { .get() .withClassName('Article') .withFields('wordCount') - .withSort({ - path: ['wordCount'], - }) + .withSort([{ path: ['wordCount'] }]) .do() .then(function (result) { expect(result.data.Get.Article.length).toBe(3); @@ -1165,7 +1066,7 @@ describe('the graphql journey', () => { .get() .withClassName('Article') .withFields('title') - .withSort({ path: ['title'], order: 'desc' }) + .withSort([{ path: ['title'], order: 'desc' }]) .do() .then(function (result) { expect(result.data.Get.Article.length).toBe(3); @@ -1225,7 +1126,7 @@ describe('the graphql journey', () => { .withFields('_additional { id creationTimeUnix }') .withWhere({ path: ['_creationTimeUnix'], - operator: weaviate.filters.Operator.EQUAL, + operator: 'Equal', valueString: expected.data.Get.Article[0]._additional.creationTimeUnix, }) .do() @@ -1254,9 +1155,8 @@ describe('the graphql journey', () => { .withFields('_additional { id lastUpdateTimeUnix }') .withWhere({ path: ['_lastUpdateTimeUnix'], - operator: weaviate.filters.Operator.EQUAL, - valueString: - expected.data.Get.Article[0]._additional.lastUpdateTimeUnix, + operator: 'Equal', + valueString: expected.data.Get.Article[0]._additional.lastUpdateTimeUnix, }) .do() .then((res: any) => { @@ -1268,9 +1168,7 @@ describe('the graphql journey', () => { }); it('tears down and cleans up', () => { - return Promise.all([ - client.schema.classDeleter().withClassName('Article').do(), - ]); + return Promise.all([client.schema.classDeleter().withClassName('Article').do()]); }); }); diff --git a/src/graphql/nearImage.ts b/src/graphql/nearImage.ts index 94be3104..8c7c4620 100644 --- a/src/graphql/nearImage.ts +++ b/src/graphql/nearImage.ts @@ -1,19 +1,24 @@ +export interface NearImageArgs { + certainty?: number; + distance?: number; + image?: string; +} + export default class GraphQLNearImage { private certainty?: number; private distance?: number; private image?: string; - private imageBlob: any; - private source: any; - constructor(nearImageObj: any) { - this.source = nearImageObj; + constructor(args: NearImageArgs) { + this.certainty = args.certainty; + this.distance = args.distance; + this.image = args.image; } toString(wrap = true) { - this.parse(); this.validate(); - let args: any[] = []; + let args: string[] = []; if (this.image) { let img = this.image; @@ -39,50 +44,8 @@ export default class GraphQLNearImage { } validate() { - if (!this.image && !this.imageBlob) { - throw new Error('nearImage filter: image or imageBlob must be present'); - } - } - - parse() { - for (const key in this.source) { - switch (key) { - case 'image': - this.parseImage(this.source[key]); - break; - case 'certainty': - this.parseCertainty(this.source[key]); - break; - case 'distance': - this.parseDistance(this.source[key]); - break; - default: - throw new Error("nearImage filter: unrecognized key '" + key + "'"); - } - } - } - - parseImage(image: string) { - if (typeof image !== 'string') { - throw new Error('nearImage filter: image must be a string'); + if (!this.image) { + throw new Error('nearImage filter: image field must be present'); } - - this.image = image; - } - - parseCertainty(cert: number) { - if (typeof cert !== 'number') { - throw new Error('nearImage filter: certainty must be a number'); - } - - this.certainty = cert; - } - - parseDistance(dist: number) { - if (typeof dist !== 'number') { - throw new Error('nearImage filter: distance must be a number'); - } - - this.distance = dist; } } diff --git a/src/graphql/nearObject.ts b/src/graphql/nearObject.ts index 2d9c1f14..b74826a4 100644 --- a/src/graphql/nearObject.ts +++ b/src/graphql/nearObject.ts @@ -1,16 +1,24 @@ +export interface NearObjectArgs { + beacon?: string; + certainty?: number; + distance?: number; + id?: string; +} + export default class GraphQLNearObject { private beacon?: string; private certainty?: number; private distance?: number; private id?: string; - private readonly source: any; - constructor(nearObjectObj: any) { - this.source = nearObjectObj; + constructor(args: NearObjectArgs) { + this.beacon = args.beacon; + this.certainty = args.certainty; + this.distance = args.distance; + this.id = args.id; } toString(wrap = true) { - this.parse(); this.validate(); let args: any[] = []; @@ -42,57 +50,4 @@ export default class GraphQLNearObject { throw new Error('nearObject filter: id or beacon needs to be set'); } } - - parse() { - for (const key in this.source) { - switch (key) { - case 'id': - this.parseID(this.source[key]); - break; - case 'beacon': - this.parseBeacon(this.source[key]); - break; - case 'certainty': - this.parseCertainty(this.source[key]); - break; - case 'distance': - this.parseDistance(this.source[key]); - break; - default: - throw new Error("nearObject filter: unrecognized key '" + key + "'"); - } - } - } - - parseID(id: string) { - if (typeof id !== 'string') { - throw new Error('nearObject filter: id must be a string'); - } - - this.id = id; - } - - parseBeacon(beacon: string) { - if (typeof beacon !== 'string') { - throw new Error('nearObject filter: beacon must be a string'); - } - - this.beacon = beacon; - } - - parseCertainty(cert: number) { - if (typeof cert !== 'number') { - throw new Error('nearObject filter: certainty must be a number'); - } - - this.certainty = cert; - } - - parseDistance(dist: number) { - if (typeof dist !== 'number') { - throw new Error('nearObject filter: distance must be a number'); - } - - this.distance = dist; - } } diff --git a/src/graphql/nearText.ts b/src/graphql/nearText.ts index 9da946de..1089fe61 100644 --- a/src/graphql/nearText.ts +++ b/src/graphql/nearText.ts @@ -1,27 +1,44 @@ +export interface NearTextArgs { + autocorrect?: boolean; + certainty?: number; + concepts: string[]; + distance?: number; + moveAwayFrom?: Move; + moveTo?: Move; +} + +export interface Move { + objects?: MoveObject[]; + concepts?: string[]; + force?: number; +} + +export interface MoveObject { + beacon?: string; + id?: string; +} + export default class GraphQLNearText { private autocorrect?: boolean; private certainty?: number; - private concepts?: string[]; + private concepts: string[]; private distance?: number; - private moveAwayFrom: any; - private moveAwayFromConcepts?: string[]; - private moveAwayFromForce?: number; - private moveAwayFromObjects?: string; - private moveTo: any; - private moveToConcepts?: string[]; - private moveToForce?: number; - private moveToObjects?: string; - private readonly source: any; - - constructor(nearTextObj: any) { - this.source = nearTextObj; + private moveAwayFrom?: any; + private moveTo?: any; + + constructor(args: NearTextArgs) { + this.autocorrect = args.autocorrect; + this.certainty = args.certainty; + this.concepts = args.concepts; + this.distance = args.distance; + this.moveAwayFrom = args.moveAwayFrom; + this.moveTo = args.moveTo; } - toString(wrap = true) { - this.parse(); + toString(): string { this.validate(); - let args = [`concepts:${JSON.stringify(this.concepts)}`]; // concepts must always be set + let args = [`concepts:${JSON.stringify(this.concepts)}`]; if (this.certainty) { args = [...args, `certainty:${this.certainty}`]; @@ -32,41 +49,32 @@ export default class GraphQLNearText { } if (this.moveTo) { - let moveToArgs: any[] = []; - if (this.moveToConcepts) { - moveToArgs = [ - ...moveToArgs, - `concepts:${JSON.stringify(this.moveToConcepts)}`, - ]; + let moveToArgs: string[] = []; + if (this.moveTo.concepts) { + moveToArgs = [...moveToArgs, `concepts:${JSON.stringify(this.moveTo.concepts)}`]; } - if (this.moveToObjects) { - moveToArgs = [...moveToArgs, `objects:${this.moveToObjects}`]; + if (this.moveTo.objects) { + moveToArgs = [...moveToArgs, `objects:${this.parseMoveObjects('moveTo', this.moveTo.objects)}`]; } - if (this.moveToForce) { - moveToArgs = [...moveToArgs, `force:${this.moveToForce}`]; + if (this.moveTo.force) { + moveToArgs = [...moveToArgs, `force:${this.moveTo.force}`]; } args = [...args, `moveTo:{${moveToArgs.join(',')}}`]; } if (this.moveAwayFrom) { - let moveAwayFromArgs: any[] = []; - if (this.moveAwayFromConcepts) { - moveAwayFromArgs = [ - ...moveAwayFromArgs, - `concepts:${JSON.stringify(this.moveAwayFromConcepts)}`, - ]; + let moveAwayFromArgs: string[] = []; + if (this.moveAwayFrom.concepts) { + moveAwayFromArgs = [...moveAwayFromArgs, `concepts:${JSON.stringify(this.moveAwayFrom.concepts)}`]; } - if (this.moveAwayFromObjects) { + if (this.moveAwayFrom.objects) { moveAwayFromArgs = [ ...moveAwayFromArgs, - `objects:${this.moveAwayFromObjects}`, + `objects:${this.parseMoveObjects('moveAwayFrom', this.moveAwayFrom.objects)}`, ]; } - if (this.moveAwayFromForce) { - moveAwayFromArgs = [ - ...moveAwayFromArgs, - `force:${this.moveAwayFromForce}`, - ]; + if (this.moveAwayFrom.force) { + moveAwayFromArgs = [...moveAwayFromArgs, `force:${this.moveAwayFrom.force}`]; } args = [...args, `moveAwayFrom:{${moveAwayFromArgs.join(',')}}`]; } @@ -75,189 +83,46 @@ export default class GraphQLNearText { args = [...args, `autocorrect:${this.autocorrect}`]; } - if (!wrap) { - return `${args.join(',')}`; - } return `{${args.join(',')}}`; } validate() { - if (!this.concepts) { - throw new Error('nearText filter: concepts cannot be empty'); - } - if (this.moveTo) { - if (!this.moveToForce || (!this.moveToConcepts && !this.moveToObjects)) { - throw new Error( - "nearText filter: moveTo must have fields 'concepts' or 'objects' and 'force'" - ); + if (!this.moveTo.concepts && !this.moveTo.objects) { + throw new Error('nearText filter: moveTo.concepts or moveTo.objects must be present'); + } + if (!this.moveTo.force || (!this.moveTo.concepts && !this.moveTo.objects)) { + throw new Error("nearText filter: moveTo must have fields 'concepts' or 'objects' and 'force'"); } } if (this.moveAwayFrom) { - if ( - !this.moveAwayFromForce || - (!this.moveAwayFromConcepts && !this.moveAwayFromObjects) - ) { - throw new Error( - "nearText filter: moveAwayFrom must have fields 'concepts' or 'objects' and 'force'" - ); + if (!this.moveAwayFrom.concepts && !this.moveAwayFrom.objects) { + throw new Error('nearText filter: moveAwayFrom.concepts or moveAwayFrom.objects must be present'); } - } - } - - parse() { - for (const key in this.source) { - switch (key) { - case 'concepts': - this.parseConcepts(this.source[key]); - break; - case 'certainty': - this.parseCertainty(this.source[key]); - break; - case 'distance': - this.parseDistance(this.source[key]); - break; - case 'moveTo': - this.parseMoveTo(this.source[key]); - break; - case 'moveAwayFrom': - this.parseMoveAwayFrom(this.source[key]); - break; - case 'autocorrect': - this.parseAutocorrect(this.source[key]); - break; - default: - throw new Error("nearText filter: unrecognized key '" + key + "'"); + if (!this.moveAwayFrom.force || (!this.moveAwayFrom.concepts && !this.moveAwayFrom.objects)) { + throw new Error("nearText filter: moveAwayFrom must have fields 'concepts' or 'objects' and 'force'"); } } } - parseConcepts(concepts: string[]) { - if (!Array.isArray(concepts)) { - throw new Error('nearText filter: concepts must be an array'); - } - - this.concepts = concepts; - } - - parseCertainty(cert: number) { - if (typeof cert !== 'number') { - throw new Error('nearText filter: certainty must be a number'); - } - - this.certainty = cert; - } - - parseDistance(dist: number) { - if (typeof dist !== 'number') { - throw new Error('nearText filter: distance must be a number'); - } - - this.distance = dist; - } - - parseMoveTo(target: any) { - if (typeof target !== 'object') { - throw new Error('nearText filter: moveTo must be object'); - } - - if (!target.concepts && !target.objects) { - throw new Error( - 'nearText filter: moveTo.concepts or moveTo.objects must be present' - ); - } - - if (target.concepts && !Array.isArray(target.concepts)) { - throw new Error('nearText filter: moveTo.concepts must be an array'); - } - - if (target.objects && !Array.isArray(target.objects)) { - throw new Error('nearText filter: moveTo.objects must be an array'); - } - - if (target.force && typeof target.force != 'number') { - throw new Error('nearText filter: moveTo.force must be a number'); - } - - this.moveTo = true; - this.moveToConcepts = target.concepts; - this.moveToForce = target.force; - if (target.objects) { - this.moveToObjects = this.parseMoveObjects('moveTo', target.objects); - } - } - - parseMoveAwayFrom(target: any) { - if (typeof target !== 'object') { - throw new Error('nearText filter: moveAwayFrom must be object'); - } - - if (!target.concepts && !target.objects) { - throw new Error( - 'nearText filter: moveAwayFrom.concepts or moveAwayFrom.objects must be present' - ); - } - - if (target.concepts && !Array.isArray(target.concepts)) { - throw new Error( - 'nearText filter: moveAwayFrom.concepts must be an array' - ); - } - - if (target.objects && !Array.isArray(target.objects)) { - throw new Error('nearText filter: moveAwayFrom.objects must be an array'); - } - - if (target.force && typeof target.force != 'number') { - throw new Error('nearText filter: moveAwayFrom.force must be a number'); - } - - this.moveAwayFrom = true; - this.moveAwayFromConcepts = target.concepts; - this.moveAwayFromForce = target.force; - if (target.objects) { - this.moveAwayFromObjects = this.parseMoveObjects( - 'moveAwayFrom', - target.objects - ); - } - } - - parseAutocorrect(autocorrect: boolean) { - if (typeof autocorrect !== 'boolean') { - throw new Error('nearText filter: autocorrect must be a boolean'); - } - - this.autocorrect = autocorrect; - } - - parseMoveObjects(move: string, objects: any[]) { - const moveObjects = []; - const errors = []; + parseMoveObjects(move: MoveType, objects: MoveObject[]): string { + const moveObjects: string[] = []; for (const i in objects) { if (!objects[i].id && !objects[i].beacon) { - errors.push( - `${move}.objects[${i}].id or ${move}.objects[${i}].beacon must be present` - ); - } else if (objects[i].id && typeof objects[i].id !== 'string') { - errors.push(`${move}.objects[${i}].id must be string`); - } else if (objects[i].beacon && typeof objects[i].beacon !== 'string') { - errors.push(`${move}.objects[${i}].beacon must be string`); - } else { - const objs = []; - if (objects[i].id) { - objs.push(`id:"${objects[i].id}"`); - } - if (objects[i].beacon) { - objs.push(`beacon:"${objects[i].beacon}"`); - } - moveObjects.push(`{${objs.join(',')}}`); + throw new Error(`nearText: ${move}.objects[${i}].id or ${move}.objects[${i}].beacon must be present`); } - } - if (errors.length > 0) { - throw new Error(`nearText filter: ${errors.join(', ')}`); + const objs = []; + if (objects[i].id) { + objs.push(`id:"${objects[i].id}"`); + } + if (objects[i].beacon) { + objs.push(`beacon:"${objects[i].beacon}"`); + } + moveObjects.push(`{${objs.join(',')}}`); } return `[${moveObjects.join(',')}]`; } } + +type MoveType = 'moveTo' | 'moveAwayFrom'; diff --git a/src/graphql/nearVector.ts b/src/graphql/nearVector.ts index c5ae1756..9ddaebcf 100644 --- a/src/graphql/nearVector.ts +++ b/src/graphql/nearVector.ts @@ -1,17 +1,21 @@ +export interface NearVectorArgs { + certainty?: number; + distance?: number; + vector: number[]; +} + export default class GraphQLNearVector { private certainty?: number; private distance?: number; - private readonly source: any; - private vector?: number[]; + private vector: number[]; - constructor(nearVectorObj: any) { - this.source = nearVectorObj; + constructor(args: NearVectorArgs) { + this.certainty = args.certainty; + this.distance = args.distance; + this.vector = args.vector; } toString(wrap = true) { - this.parse(); - this.validate(); - let args = [`vector:${JSON.stringify(this.vector)}`]; // vector must always be set if (this.certainty) { @@ -27,58 +31,4 @@ export default class GraphQLNearVector { } return `{${args.join(',')}}`; } - - validate() { - if (!this.vector) { - throw new Error('nearVector filter: vector cannot be empty'); - } - } - - parse() { - for (const key in this.source) { - switch (key) { - case 'vector': - this.parseVector(this.source[key]); - break; - case 'certainty': - this.parseCertainty(this.source[key]); - break; - case 'distance': - this.parseDistance(this.source[key]); - break; - default: - throw new Error("nearVector filter: unrecognized key '" + key + "'"); - } - } - } - - parseVector(vector: any[]) { - if (!Array.isArray(vector)) { - throw new Error('nearVector filter: vector must be an array'); - } - - vector.forEach((elem: any) => { - if (typeof elem !== 'number') { - throw new Error('nearVector filter: vector elements must be a number'); - } - }); - - this.vector = vector; - } - - parseCertainty(cert: number) { - if (typeof cert !== 'number') { - throw new Error('nearVector filter: certainty must be a number'); - } - - this.certainty = cert; - } - - parseDistance(dist: number) { - if (typeof dist !== 'number') { - throw new Error('nearVector filter: distance must be a number'); - } - - this.distance = dist; - } } diff --git a/src/graphql/raw.test.ts b/src/graphql/raw.test.ts index 6180b125..e790dc2e 100644 --- a/src/graphql/raw.test.ts +++ b/src/graphql/raw.test.ts @@ -18,8 +18,6 @@ test('reject empty raw query', () => { }; new Raw(mockClient).do().catch((err: Error) => { - expect(err.message).toEqual( - 'invalid usage: query must be set - set with .raw().withQuery(query)' - ); + expect(err.message).toEqual('invalid usage: query must be set - set with .raw().withQuery(query)'); }); }); diff --git a/src/graphql/raw.ts b/src/graphql/raw.ts index 45f5aa44..50a25add 100644 --- a/src/graphql/raw.ts +++ b/src/graphql/raw.ts @@ -8,16 +8,12 @@ export default class RawGraphQL extends CommandBase { super(client); } - withQuery = (query: any) => { + withQuery = (query: string) => { this.query = query; return this; }; - validateIsSet = ( - prop: string | undefined | null, - name: string, - setter: string - ) => { + validateIsSet = (prop: string | undefined | null, name: string, setter: string) => { if (prop == undefined || prop == null || prop.length == 0) { this.addError(`${name} must be set - set with ${setter}`); } @@ -32,9 +28,7 @@ export default class RawGraphQL extends CommandBase { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } if (this.query) { diff --git a/src/graphql/sort.ts b/src/graphql/sort.ts index f0b3292a..2e1f239e 100644 --- a/src/graphql/sort.ts +++ b/src/graphql/sort.ts @@ -1,107 +1,30 @@ -export default class GraphQLSort { - private errors: string[]; - private order?: string; - private path?: string[]; - private sortArgs: any[]; - private source: any; - - constructor(sortObj: any) { - this.source = sortObj; - this.sortArgs = []; - this.errors = []; - } - - toString() { - this.parse(); - this.validate(); - - let args: any[] = []; +export interface SortArgs { + path: string[]; + order?: string; +} - if (this.sortArgs.length > 0) { - args = [...args, this.sortArgs]; - } else { - if (this.path) { - args = [...args, `path:${JSON.stringify(this.path)}`]; - } +export type SortOrder = 'asc' | 'desc'; - if (this.order) { - args = [...args, `order:${this.order}`]; - } - } - - if (this.sortArgs.length > 0) { - return `${args.join(',')}`; - } - return `{${args.join(',')}}`; - } +export default class GraphQLSort { + private args: SortArgs[]; - validate() { - if (this.sortArgs.length == 0) { - this.validatePath(this.path); - } + constructor(args: SortArgs[]) { + this.args = args; } - validatePath(path: any) { - if (!path) { - throw new Error('sort filter: path needs to be set'); - } - if (path.length == 0) { - throw new Error('sort filter: path cannot be empty'); - } - } + toString(): string { + const parts: string[] = []; - parse() { - for (const key in this.source) { - switch (key) { - case 'path': - this.parsePath(this.source[key]); - break; - case 'order': - this.parseOrder(this.source[key]); - break; - default: - try { - this.sortArgs = [ - ...this.sortArgs, - this.parseSortArgs(this.source[key]), - ]; - } catch (e: any) { - this.errors = [ - ...this.errors, - `sort argument at ${key}: ${e.message}`, - ]; - } + for (const arg of this.args) { + let part = `{path:${JSON.stringify(arg.path)}`; + if (arg.order) { + part = part.concat(`,order:${arg.order}}`); + } else { + part = part.concat('}'); } + parts.push(part); } - if (this.errors.length > 0) { - throw new Error(`sort filter: ${this.errors.join(', ')}`); - } - } - - parseSortArgs(args: any) { - return new GraphQLSort(args).toString(); - } - - parsePath(path: string[]) { - if (!Array.isArray(path)) { - throw new Error('sort filter: path must be an array'); - } - - this.path = path; - } - - parseOrder(order: string) { - if (typeof order !== 'string') { - throw new Error('sort filter: order must be a string'); - } - - if (order !== 'asc' && order !== 'desc') { - throw new Error( - 'sort filter: order parameter not valid, possible values are: asc, desc' - ); - } - - this.order = order; + return parts.join(','); } } diff --git a/src/graphql/where.ts b/src/graphql/where.ts index 804941ca..ce007f79 100644 --- a/src/graphql/where.ts +++ b/src/graphql/where.ts @@ -1,3 +1,5 @@ +import { WhereFilter } from '../openapi/types'; + export default class GraphQLWhere { private operands?: string; private operator?: string; @@ -6,7 +8,7 @@ export default class GraphQLWhere { private valueContent: any; private valueType?: string; - constructor(whereObj: any) { + constructor(whereObj: WhereFilter) { this.source = whereObj; } diff --git a/src/index.ts b/src/index.ts index fb266a20..c91d53a6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,19 +1,14 @@ -import Connection from './connection/index'; -import graphql, { GraphQL } from './graphql/index'; -import schema, { Schema } from './schema/index'; -import data, { Data } from './data/index'; -import classifications, { Classifications } from './classifications/index'; -import batch, { Batch } from './batch/index'; -import misc, { Misc } from './misc/index'; -import c11y, { C11y } from './c11y/index'; +import Connection from './connection'; +import graphql, { GraphQL } from './graphql'; +import schema, { Schema } from './schema'; +import data, { Data } from './data'; +import classifications, { Classifications } from './classifications'; +import batch, { Batch } from './batch'; +import misc, { Misc } from './misc'; +import c11y, { C11y } from './c11y'; import { DbVersionProvider, DbVersionSupport } from './utils/dbVersion'; -import backup, { Backup } from './backup/index'; -import backupConsts from './backup/consts'; -import batchConsts from './batch/consts'; -import filtersConsts from './filters/consts'; -import cluster, { Cluster } from './cluster/index'; -import clusterConsts from './cluster/consts'; -import replicationConsts from './data/replication/consts'; +import backup, { Backup } from './backup'; +import cluster, { Cluster } from './cluster'; import { ApiKey, AuthAccessTokenCredentials, @@ -24,10 +19,7 @@ import MetaGetter from './misc/metaGetter'; import { EmbeddedDB, EmbeddedOptions } from './embedded'; export interface ConnectionParams { - authClientSecret?: - | AuthClientCredentials - | AuthAccessTokenCredentials - | AuthUserPasswordCredentials; + authClientSecret?: AuthClientCredentials | AuthAccessTokenCredentials | AuthUserPasswordCredentials; apiKey?: ApiKey; host: string; scheme: string; @@ -82,13 +74,6 @@ const app = { return ifc; }, - // constants - backup: backupConsts, - batch: batchConsts, - filters: filtersConsts, - cluster: clusterConsts, - replication: replicationConsts, - ApiKey, AuthUserPasswordCredentials, AuthAccessTokenCredentials, @@ -113,3 +98,15 @@ function initDbVersionProvider(conn: Connection) { module.exports = app; export default app; +export * from './openapi/types'; +export * from './graphql'; +export * from './schema'; +export * from './data'; +export * from './classifications'; +export * from './batch'; +export * from './misc'; +export * from './c11y'; +export * from './backup'; +export * from './cluster'; +export * from './connection'; +export * from './embedded'; diff --git a/src/misc/index.ts b/src/misc/index.ts index cf60d9c4..575ff403 100644 --- a/src/misc/index.ts +++ b/src/misc/index.ts @@ -12,10 +12,7 @@ export interface Misc { openidConfigurationGetter: () => OpenidConfigurationGetter; } -const misc = ( - client: Connection, - dbVersionProvider: DbVersionProvider -): Misc => { +const misc = (client: Connection, dbVersionProvider: DbVersionProvider): Misc => { return { liveChecker: () => new LiveChecker(client, dbVersionProvider), readyChecker: () => new ReadyChecker(client, dbVersionProvider), diff --git a/src/misc/journey.test.ts b/src/misc/journey.test.ts index d1d37bad..dd20aca4 100644 --- a/src/misc/journey.test.ts +++ b/src/misc/journey.test.ts @@ -1,4 +1,4 @@ -import weaviate from '../index'; +import weaviate from '..'; describe('misc endpoints', () => { const client = weaviate.client({ @@ -68,9 +68,7 @@ describe('misc endpoints', () => { .then((res: any) => { expect(res.version).toBeDefined(); expect(res.modules['text2vec-contextionary'].wordCount).toBeDefined(); - expect(res.modules['text2vec-contextionary'].wordCount).toBeGreaterThan( - 100 - ); + expect(res.modules['text2vec-contextionary'].wordCount).toBeGreaterThan(100); }) .catch((e: any) => { throw new Error('it should not have errord: ' + e); diff --git a/src/misc/openidConfigurationGetter.ts b/src/misc/openidConfigurationGetter.ts index 50dd9ef5..5a94b26f 100644 --- a/src/misc/openidConfigurationGetter.ts +++ b/src/misc/openidConfigurationGetter.ts @@ -19,9 +19,7 @@ export default class OpenidConfigurationGetterGetter { return Promise.resolve(undefined); } - return Promise.reject( - new Error(`unexpected status code: ${res.status}`) - ); + return Promise.reject(new Error(`unexpected status code: ${res.status}`)); }); }; } diff --git a/src/openapi/schema.ts b/src/openapi/schema.ts new file mode 100644 index 00000000..4285e5e9 --- /dev/null +++ b/src/openapi/schema.ts @@ -0,0 +1,2430 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export interface paths { + '/': { + /** Home. Discover the REST API */ + get: operations['weaviate.root']; + }; + '/.well-known/live': { + /** Determines whether the application is alive. Can be used for kubernetes liveness probe */ + get: operations['weaviate.wellknown.liveness']; + }; + '/.well-known/ready': { + /** Determines whether the application is ready to receive traffic. Can be used for kubernetes readiness probe. */ + get: operations['weaviate.wellknown.readiness']; + }; + '/.well-known/openid-configuration': { + /** OIDC Discovery page, redirects to the token issuer if one is configured */ + get: { + responses: { + /** Successful response, inspect body */ + 200: { + schema: { + /** @description The Location to redirect to */ + href?: string; + /** @description OAuth Client ID */ + clientId?: string; + /** @description OAuth Scopes */ + scopes?: string[]; + }; + }; + /** Not found, no oidc provider present */ + 404: unknown; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + }; + '/objects': { + /** Lists all Objects in reverse order of creation, owned by the user that belongs to the used token. */ + get: operations['objects.list']; + /** Registers a new Object. Provided meta-data and schema values are validated. */ + post: operations['objects.create']; + }; + '/objects/{id}': { + /** Lists Objects. */ + get: operations['objects.get']; + /** Updates an Object's data. Given meta-data and schema values are validated. LastUpdateTime is set to the time this function is called. */ + put: operations['objects.update']; + /** Deletes an Object from the system. */ + delete: operations['objects.delete']; + /** Checks if an Object exists in the system. */ + head: operations['objects.head']; + /** Updates an Object. This method supports json-merge style patch semantics (RFC 7396). Provided meta-data and schema values are validated. LastUpdateTime is set to the time this function is called. */ + patch: operations['objects.patch']; + }; + '/objects/{className}/{id}': { + /** Get a single data object */ + get: operations['objects.class.get']; + /** Update an individual data object based on its class and uuid. */ + put: operations['objects.class.put']; + /** Delete a single data object. */ + delete: operations['objects.class.delete']; + /** Checks if a data object exists without retrieving it. */ + head: operations['objects.class.head']; + /** Update an individual data object based on its class and uuid. This method supports json-merge style patch semantics (RFC 7396). Provided meta-data and schema values are validated. LastUpdateTime is set to the time this function is called. */ + patch: operations['objects.class.patch']; + }; + '/objects/{id}/references/{propertyName}': { + /** Replace all references to a class-property. */ + put: operations['objects.references.update']; + /** Add a single reference to a class-property. */ + post: operations['objects.references.create']; + /** Delete the single reference that is given in the body from the list of references that this property has. */ + delete: operations['objects.references.delete']; + }; + '/objects/{className}/{id}/references/{propertyName}': { + /** Update all references of a property of a data object. */ + put: operations['objects.class.references.put']; + /** Add a single reference to a class-property. */ + post: operations['objects.class.references.create']; + /** Delete the single reference that is given in the body from the list of references that this property of a data object has */ + delete: operations['objects.class.references.delete']; + }; + '/objects/validate': { + /** Validate an Object's schema and meta-data. It has to be based on a schema, which is related to the given Object to be accepted by this validation. */ + post: operations['objects.validate']; + }; + '/batch/objects': { + /** Register new Objects in bulk. Provided meta-data and schema values are validated. */ + post: operations['batch.objects.create']; + /** Delete Objects in bulk that match a certain filter. */ + delete: operations['batch.objects.delete']; + }; + '/batch/references': { + /** Register cross-references between any class items (objects or objects) in bulk. */ + post: operations['batch.references.create']; + }; + '/graphql': { + /** Get an object based on GraphQL */ + post: operations['graphql.post']; + }; + '/graphql/batch': { + /** Perform a batched GraphQL query */ + post: operations['graphql.batch']; + }; + '/meta': { + /** Gives meta information about the server and can be used to provide information to another Weaviate instance that wants to interact with the current instance. */ + get: operations['meta.get']; + }; + '/schema': { + get: operations['schema.dump']; + post: operations['schema.objects.create']; + }; + '/schema/{className}': { + get: operations['schema.objects.get']; + /** Use this endpoint to alter an existing class in the schema. Note that not all settings are mutable. If an error about immutable fields is returned and you still need to update this particular setting, you will have to delete the class (and the underlying data) and recreate. This endpoint cannot be used to modify properties. Instead use POST /v1/schema/{className}/properties. A typical use case for this endpoint is to update configuration, such as the vectorIndexConfig. Note that even in mutable sections, such as vectorIndexConfig, some fields may be immutable. */ + put: operations['schema.objects.update']; + delete: operations['schema.objects.delete']; + }; + '/schema/{className}/properties': { + post: operations['schema.objects.properties.add']; + }; + '/schema/{className}/shards': { + get: operations['schema.objects.shards.get']; + }; + '/schema/{className}/shards/{shardName}': { + /** Update shard status of an Object Class */ + put: operations['schema.objects.shards.update']; + }; + '/backups/{backend}': { + /** Starts a process of creating a backup for a set of classes */ + post: operations['backups.create']; + }; + '/backups/{backend}/{id}': { + /** Returns status of backup creation attempt for a set of classes */ + get: operations['backups.create.status']; + }; + '/backups/{backend}/{id}/restore': { + /** Returns status of a backup restoration attempt for a set of classes */ + get: operations['backups.restore.status']; + /** Starts a process of restoring a backup for a set of classes */ + post: operations['backups.restore']; + }; + '/nodes': { + /** Returns status of Weaviate DB. */ + get: operations['nodes.get']; + }; + '/classifications/': { + /** Trigger a classification based on the specified params. Classifications will run in the background, use GET /classifications/ to retrieve the status of your classification. */ + post: operations['classifications.post']; + }; + '/classifications/{id}': { + /** Get status, results and metadata of a previously created classification */ + get: operations['classifications.get']; + }; +} + +export interface definitions { + Link: { + /** @description target of the link */ + href?: string; + /** @description relationship if both resources are related, e.g. 'next', 'previous', 'parent', etc. */ + rel?: string; + /** @description human readable name of the resource group */ + name?: string; + /** @description weaviate documentation about this resource group */ + documentationHref?: string; + }; + Principal: { + /** @description The username that was extracted either from the authentication information */ + username?: string; + groups?: string[]; + }; + /** @description An array of available words and contexts. */ + C11yWordsResponse: { + /** @description Weighted results for all words */ + concatenatedWord?: { + concatenatedWord?: string; + singleWords?: unknown[]; + concatenatedVector?: definitions['C11yVector']; + concatenatedNearestNeighbors?: definitions['C11yNearestNeighbors']; + }; + /** @description Weighted results for per individual word */ + individualWords?: { + word?: string; + present?: boolean; + info?: { + vector?: definitions['C11yVector']; + nearestNeighbors?: definitions['C11yNearestNeighbors']; + }; + }[]; + }; + /** @description A resource describing an extension to the contextinoary, containing both the identifier and the definition of the extension */ + C11yExtension: { + /** + * @description The new concept you want to extend. Must be an all-lowercase single word, or a space delimited compound word. Examples: 'foobarium', 'my custom concept' + * @example foobarium + */ + concept?: string; + /** @description A list of space-delimited words or a sentence describing what the custom concept is about. Avoid using the custom concept itself. An Example definition for the custom concept 'foobarium': would be 'a naturally occourring element which can only be seen by programmers' */ + definition?: string; + /** + * Format: float + * @description Weight of the definition of the new concept where 1='override existing definition entirely' and 0='ignore custom definition'. Note that if the custom concept is not present in the contextionary yet, the weight cannot be less than 1. + */ + weight?: number; + }; + /** @description C11y function to show the nearest neighbors to a word. */ + C11yNearestNeighbors: { + word?: string; + /** Format: float */ + distance?: number; + }[]; + /** @description A Vector in the Contextionary */ + C11yVector: number[]; + /** @description Receive question based on array of classes, properties and values. */ + C11yVectorBasedQuestion: { + /** @description Vectorized classname. */ + classVectors?: number[]; + /** @description Vectorized properties. */ + classProps?: { + propsVectors?: number[]; + /** @description String with valuename. */ + value?: string; + }[]; + }[]; + Deprecation: { + /** @description The id that uniquely identifies this particular deprecations (mostly used internally) */ + id?: string; + /** @description Whether the problematic API functionality is deprecated (planned to be removed) or already removed */ + status?: string; + /** @description Describes which API is effected, usually one of: REST, GraphQL */ + apiType?: string; + /** @description What this deprecation is about */ + msg?: string; + /** @description User-required object to not be affected by the (planned) removal */ + mitigation?: string; + /** @description The deprecation was introduced in this version */ + sinceVersion?: string; + /** @description A best-effort guess of which upcoming version will remove the feature entirely */ + plannedRemovalVersion?: string; + /** @description If the feature has already been removed, it was removed in this version */ + removedIn?: string; + /** + * Format: date-time + * @description If the feature has already been removed, it was removed at this timestamp + */ + removedTime?: string; + /** + * Format: date-time + * @description The deprecation was introduced in this version + */ + sinceTime?: string; + /** @description The locations within the specified API affected by this deprecation */ + locations?: string[]; + }; + /** @description An error response given by Weaviate end-points. */ + ErrorResponse: { + error?: { + message?: string; + }[]; + }; + /** @description An error response caused by a GraphQL query. */ + GraphQLError: { + locations?: { + /** Format: int64 */ + column?: number; + /** Format: int64 */ + line?: number; + }[]; + message?: string; + path?: string[]; + }; + /** @description GraphQL query based on: http://facebook.github.io/graphql/. */ + GraphQLQuery: { + /** @description The name of the operation if multiple exist in the query. */ + operationName?: string; + /** @description Query based on GraphQL syntax. */ + query?: string; + /** @description Additional variables for the query. */ + variables?: { [key: string]: unknown }; + }; + /** @description A list of GraphQL queries. */ + GraphQLQueries: definitions['GraphQLQuery'][]; + /** @description GraphQL based response: http://facebook.github.io/graphql/. */ + GraphQLResponse: { + /** @description GraphQL data object. */ + data?: { [key: string]: definitions['JsonObject'] }; + /** @description Array with errors. */ + errors?: definitions['GraphQLError'][]; + }; + /** @description A list of GraphQL responses. */ + GraphQLResponses: definitions['GraphQLResponse'][]; + /** @description Configure the inverted index built into Weaviate */ + InvertedIndexConfig: { + /** + * Format: int + * @description Asynchronous index clean up happens every n seconds + */ + cleanupIntervalSeconds?: number; + bm25?: definitions['BM25Config']; + stopwords?: definitions['StopwordConfig']; + /** @description Index each object by its internal timestamps */ + indexTimestamps?: boolean; + /** @description Index each object with the null state */ + indexNullState?: boolean; + /** @description Index length of properties */ + indexPropertyLength?: boolean; + }; + /** @description Configure how replication is executed in a cluster */ + ReplicationConfig: { + /** @description Number of times a class is replicated */ + factor?: number; + }; + /** @description tuning parameters for the BM25 algorithm */ + BM25Config: { + /** + * Format: float + * @description calibrates term-weight scaling based on the term frequency within a document + */ + k1?: number; + /** + * Format: float + * @description calibrates term-weight scaling based on the document length + */ + b?: number; + }; + /** @description fine-grained control over stopword list usage */ + StopwordConfig: { + /** @description pre-existing list of common words by language */ + preset?: string; + /** @description stopwords to be considered additionally */ + additions?: string[]; + /** @description stopwords to be removed from consideration */ + removals?: string[]; + }; + /** @description JSON object value. */ + JsonObject: { [key: string]: unknown }; + /** @description Contains meta information of the current Weaviate instance. */ + Meta: { + /** + * Format: url + * @description The url of the host. + */ + hostname?: string; + /** @description Version of weaviate you are currently running */ + version?: string; + /** @description Module-specific meta information */ + modules?: { [key: string]: unknown }; + }; + /** @description Multiple instances of references to other objects. */ + MultipleRef: definitions['SingleRef'][]; + /** @description Either a JSONPatch document as defined by RFC 6902 (from, op, path, value), or a merge document (RFC 7396). */ + PatchDocumentObject: { + /** @description A string containing a JSON Pointer value. */ + from?: string; + /** + * @description The operation to be performed. + * @enum {string} + */ + op: 'add' | 'remove' | 'replace' | 'move' | 'copy' | 'test'; + /** @description A JSON-Pointer. */ + path: string; + /** @description The value to be used within the operations. */ + value?: { [key: string]: unknown }; + merge?: definitions['Object']; + }; + /** @description Either a JSONPatch document as defined by RFC 6902 (from, op, path, value), or a merge document (RFC 7396). */ + PatchDocumentAction: { + /** @description A string containing a JSON Pointer value. */ + from?: string; + /** + * @description The operation to be performed. + * @enum {string} + */ + op: 'add' | 'remove' | 'replace' | 'move' | 'copy' | 'test'; + /** @description A JSON-Pointer. */ + path: string; + /** @description The value to be used within the operations. */ + value?: { [key: string]: unknown }; + merge?: definitions['Object']; + }; + /** @description A single peer in the network. */ + PeerUpdate: { + /** + * Format: uuid + * @description The session ID of the peer. + */ + id?: string; + /** @description Human readable name. */ + name?: string; + /** + * Format: uri + * @description The location where the peer is exposed to the internet. + */ + uri?: string; + /** @description The latest known hash of the peer's schema. */ + schemaHash?: string; + }; + /** @description List of known peers. */ + PeerUpdateList: definitions['PeerUpdate'][]; + /** @description Allow custom overrides of vector weights as math expressions. E.g. "pancake": "7" will set the weight for the word pancake to 7 in the vectorization, whereas "w * 3" would triple the originally calculated word. This is an open object, with OpenAPI Specification 3.0 this will be more detailed. See Weaviate docs for more info. In the future this will become a key/value (string/string) object. */ + VectorWeights: { [key: string]: unknown }; + /** @description This is an open object, with OpenAPI Specification 3.0 this will be more detailed. See Weaviate docs for more info. In the future this will become a key/value OR a SingleRef definition. */ + PropertySchema: { [key: string]: unknown }; + /** @description This is an open object, with OpenAPI Specification 3.0 this will be more detailed. See Weaviate docs for more info. In the future this will become a key/value OR a SingleRef definition. */ + SchemaHistory: { [key: string]: unknown }; + /** @description Definitions of semantic schemas (also see: https://github.com/weaviate/weaviate-semantic-schemas). */ + Schema: { + /** @description Semantic classes that are available. */ + classes?: definitions['Class'][]; + /** + * Format: email + * @description Email of the maintainer. + */ + maintainer?: string; + /** @description Name of the schema. */ + name?: string; + }; + Class: { + /** @description Name of the class as URI relative to the schema URL. */ + class?: string; + /** @description Name of the vector index to use, eg. (HNSW) */ + vectorIndexType?: string; + /** @description Vector-index config, that is specific to the type of index selected in vectorIndexType */ + vectorIndexConfig?: { [key: string]: unknown }; + /** @description Manage how the index should be sharded and distributed in the cluster */ + shardingConfig?: { [key: string]: unknown }; + replicationConfig?: definitions['ReplicationConfig']; + invertedIndexConfig?: definitions['InvertedIndexConfig']; + /** @description Specify how the vectors for this class should be determined. The options are either 'none' - this means you have to import a vector with each object yourself - or the name of a module that provides vectorization capabilities, such as 'text2vec-contextionary'. If left empty, it will use the globally configured default which can itself either be 'none' or a specific module. */ + vectorizer?: string; + /** @description Configuration specific to modules this Weaviate instance has installed */ + moduleConfig?: { [key: string]: unknown }; + /** @description Description of the class. */ + description?: string; + /** @description The properties of the class. */ + properties?: definitions['Property'][]; + }; + Property: { + /** @description Can be a reference to another type when it starts with a capital (for example Person), otherwise "string" or "int". */ + dataType?: string[]; + /** @description Description of the property. */ + description?: string; + /** @description Configuration specific to modules this Weaviate instance has installed */ + moduleConfig?: { [key: string]: unknown }; + /** @description Name of the property as URI relative to the schema URL. */ + name?: string; + /** @description Optional. Should this property be indexed in the inverted index. Defaults to true. If you choose false, you will not be able to use this property in where filters. This property has no affect on vectorization decisions done by modules */ + indexInverted?: boolean; + /** + * @description Determines tokenization of the property as separate words or whole field. Optional. Applies to string, string[], text and text[] data types. Allowed values are `word` (default) and `field` for string and string[], `word` (default) for text and text[]. Not supported for remaining data types + * @enum {string} + */ + tokenization?: 'word' | 'field'; + }; + /** @description The status of all the shards of a Class */ + ShardStatusList: definitions['ShardStatusGetResponse'][]; + /** @description Response body of shard status get request */ + ShardStatusGetResponse: { + /** @description Name of the shard */ + name?: string; + /** @description Status of the shard */ + status?: string; + }; + /** @description The status of a single shard */ + ShardStatus: { + /** @description Status of the shard */ + status?: string; + }; + /** @description The definition of a backup create metadata */ + BackupCreateStatusResponse: { + /** @description The ID of the backup. Must be URL-safe and work as a filesystem path, only lowercase, numbers, underscore, minus characters allowed. */ + id?: string; + /** @description Backup backend name e.g. filesystem, gcs, s3. */ + backend?: string; + /** @description destination path of backup files proper to selected backend */ + path?: string; + /** @description error message if creation failed */ + error?: string; + /** + * @description phase of backup creation process + * @default STARTED + * @enum {string} + */ + status?: 'STARTED' | 'TRANSFERRING' | 'TRANSFERRED' | 'SUCCESS' | 'FAILED'; + }; + /** @description The definition of a backup restore metadata */ + BackupRestoreStatusResponse: { + /** @description The ID of the backup. Must be URL-safe and work as a filesystem path, only lowercase, numbers, underscore, minus characters allowed. */ + id?: string; + /** @description Backup backend name e.g. filesystem, gcs, s3. */ + backend?: string; + /** @description destination path of backup files proper to selected backup backend */ + path?: string; + /** @description error message if restoration failed */ + error?: string; + /** + * @description phase of backup restoration process + * @default STARTED + * @enum {string} + */ + status?: 'STARTED' | 'TRANSFERRING' | 'TRANSFERRED' | 'SUCCESS' | 'FAILED'; + }; + /** @description Request body for creating a backup of a set of classes */ + BackupCreateRequest: { + /** @description The ID of the backup. Must be URL-safe and work as a filesystem path, only lowercase, numbers, underscore, minus characters allowed. */ + id?: string; + /** @description Custom configuration for the backup creation process */ + config?: { [key: string]: unknown }; + /** @description List of classes to include in the backup creation process */ + include?: string[]; + /** @description List of classes to exclude from the backup creation process */ + exclude?: string[]; + }; + /** @description The definition of a backup create response body */ + BackupCreateResponse: { + /** @description The ID of the backup. Must be URL-safe and work as a filesystem path, only lowercase, numbers, underscore, minus characters allowed. */ + id?: string; + /** @description The list of classes for which the backup creation process was started */ + classes?: string[]; + /** @description Backup backend name e.g. filesystem, gcs, s3. */ + backend?: string; + /** @description destination path of backup files proper to selected backend */ + path?: string; + /** @description error message if creation failed */ + error?: string; + /** + * @description phase of backup creation process + * @default STARTED + * @enum {string} + */ + status?: 'STARTED' | 'TRANSFERRING' | 'TRANSFERRED' | 'SUCCESS' | 'FAILED'; + }; + /** @description Request body for restoring a backup for a set of classes */ + BackupRestoreRequest: { + /** @description Custom configuration for the backup restoration process */ + config?: { [key: string]: unknown }; + /** @description List of classes to include in the backup restoration process */ + include?: string[]; + /** @description List of classes to exclude from the backup restoration process */ + exclude?: string[]; + }; + /** @description The definition of a backup restore response body */ + BackupRestoreResponse: { + /** @description The ID of the backup. Must be URL-safe and work as a filesystem path, only lowercase, numbers, underscore, minus characters allowed. */ + id?: string; + /** @description The list of classes for which the backup restoration process was started */ + classes?: string[]; + /** @description Backup backend name e.g. filesystem, gcs, s3. */ + backend?: string; + /** @description destination path of backup files proper to selected backend */ + path?: string; + /** @description error message if restoration failed */ + error?: string; + /** + * @description phase of backup restoration process + * @default STARTED + * @enum {string} + */ + status?: 'STARTED' | 'TRANSFERRING' | 'TRANSFERRED' | 'SUCCESS' | 'FAILED'; + }; + /** @description The summary of Weaviate's statistics. */ + NodeStats: { + /** + * Format: int + * @description The count of Weaviate's shards. + */ + shardCount?: number; + /** + * Format: int64 + * @description The total number of objects in DB. + */ + objectCount?: number; + }; + /** @description The definition of a node shard status response body */ + NodeShardStatus: { + /** @description The name of the shard. */ + name?: string; + /** @description The name of shard's class. */ + class?: string; + /** + * Format: int64 + * @description The number of objects in shard. + */ + objectCount?: number; + }; + /** @description The definition of a backup node status response body */ + NodeStatus: { + /** @description The name of the node. */ + name?: string; + /** + * @description Node's status. + * @default HEALTHY + * @enum {string} + */ + status?: 'HEALTHY' | 'UNHEALTHY' | 'UNAVAILABLE'; + /** @description The version of Weaviate. */ + version?: string; + /** @description The gitHash of Weaviate. */ + gitHash?: string; + /** @description Weaviate overall statistics. */ + stats?: definitions['NodeStats']; + /** @description The list of the shards with it's statistics. */ + shards?: definitions['NodeShardStatus'][]; + }; + /** @description The status of all of the Weaviate nodes */ + NodesStatusResponse: { + nodes?: definitions['NodeStatus'][]; + }; + /** @description Either set beacon (direct reference) or set class and schema (concept reference) */ + SingleRef: { + /** + * Format: uri + * @description If using a concept reference (rather than a direct reference), specify the desired class name here + */ + class?: string; + /** @description If using a concept reference (rather than a direct reference), specify the desired properties here */ + schema?: definitions['PropertySchema']; + /** + * Format: uri + * @description If using a direct reference, specify the URI to point to the cross-ref here. Should be in the form of weaviate://localhost/ for the example of a local cross-ref to an object + */ + beacon?: string; + /** + * Format: uri + * @description If using a direct reference, this read-only fields provides a link to the referenced resource. If 'origin' is globally configured, an absolute URI is shown - a relative URI otherwise. + */ + href?: string; + /** @description Additional Meta information about classifications if the item was part of one */ + classification?: definitions['ReferenceMetaClassification']; + }; + /** @description Additional Meta information about a single object object. */ + AdditionalProperties: { [key: string]: { [key: string]: unknown } }; + /** @description This meta field contains additional info about the classified reference property */ + ReferenceMetaClassification: { + /** + * Format: int64 + * @description overall neighbors checked as part of the classification. In most cases this will equal k, but could be lower than k - for example if not enough data was present + */ + overallCount?: number; + /** + * Format: int64 + * @description size of the winning group, a number between 1..k + */ + winningCount?: number; + /** + * Format: int64 + * @description size of the losing group, can be 0 if the winning group size euqals k + */ + losingCount?: number; + /** + * Format: float32 + * @description The lowest distance of any neighbor, regardless of whether they were in the winning or losing group + */ + closestOverallDistance?: number; + /** + * Format: float32 + * @description deprecated - do not use, to be removed in 0.23.0 + */ + winningDistance?: number; + /** + * Format: float32 + * @description Mean distance of all neighbors from the winning group + */ + meanWinningDistance?: number; + /** + * Format: float32 + * @description Closest distance of a neighbor from the winning group + */ + closestWinningDistance?: number; + /** + * Format: float32 + * @description The lowest distance of a neighbor in the losing group. Optional. If k equals the size of the winning group, there is no losing group + */ + closestLosingDistance?: number; + /** + * Format: float32 + * @description deprecated - do not use, to be removed in 0.23.0 + */ + losingDistance?: number; + /** + * Format: float32 + * @description Mean distance of all neighbors from the losing group. Optional. If k equals the size of the winning group, there is no losing group. + */ + meanLosingDistance?: number; + }; + BatchReference: { + /** + * Format: uri + * @description Long-form beacon-style URI to identify the source of the cross-ref including the property name. Should be in the form of weaviate://localhost////, where must be one of 'objects', 'objects' and and must represent the cross-ref property of source class to be used. + * @example weaviate://localhost/Zoo/a5d09582-4239-4702-81c9-92a6e0122bb4/hasAnimals + */ + from?: string; + /** + * Format: uri + * @description Short-form URI to point to the cross-ref. Should be in the form of weaviate://localhost/ for the example of a local cross-ref to an object + * @example weaviate://localhost/97525810-a9a5-4eb0-858a-71449aeb007f + */ + to?: string; + }; + BatchReferenceResponse: definitions['BatchReference'] & { + /** + * Format: object + * @description Results for this specific reference. + */ + result?: { + /** + * @default SUCCESS + * @enum {string} + */ + status?: 'SUCCESS' | 'PENDING' | 'FAILED'; + errors?: definitions['ErrorResponse']; + }; + }; + GeoCoordinates: { + /** + * Format: float + * @description The latitude of the point on earth in decimal form + */ + latitude?: number; + /** + * Format: float + * @description The longitude of the point on earth in decimal form + */ + longitude?: number; + }; + PhoneNumber: { + /** @description The raw input as the phone number is present in your raw data set. It will be parsed into the standardized formats if valid. */ + input?: string; + /** @description Read-only. Parsed result in the international format (e.g. +49 123 ...) */ + internationalFormatted?: string; + /** @description Optional. The ISO 3166-1 alpha-2 country code. This is used to figure out the correct countryCode and international format if only a national number (e.g. 0123 4567) is provided */ + defaultCountry?: string; + /** + * Format: uint64 + * @description Read-only. The numerical country code (e.g. 49) + */ + countryCode?: number; + /** + * Format: uint64 + * @description Read-only. The numerical representation of the national part + */ + national?: number; + /** @description Read-only. Parsed result in the national format (e.g. 0123 456789) */ + nationalFormatted?: string; + /** @description Read-only. Indicates whether the parsed number is a valid phone number */ + valid?: boolean; + }; + Object: { + /** @description Class of the Object, defined in the schema. */ + class?: string; + vectorWeights?: definitions['VectorWeights']; + properties?: definitions['PropertySchema']; + /** + * Format: uuid + * @description ID of the Object. + */ + id?: string; + /** + * Format: int64 + * @description Timestamp of creation of this Object in milliseconds since epoch UTC. + */ + creationTimeUnix?: number; + /** + * Format: int64 + * @description Timestamp of the last Object update in milliseconds since epoch UTC. + */ + lastUpdateTimeUnix?: number; + /** @description This object's position in the Contextionary vector space. Read-only if using a vectorizer other than 'none'. Writable and required if using 'none' as vectorizer. */ + vector?: definitions['C11yVector']; + additional?: definitions['AdditionalProperties']; + }; + ObjectsGetResponse: definitions['Object'] & { + deprecations?: definitions['Deprecation'][]; + } & { + /** + * Format: object + * @description Results for this specific Object. + */ + result?: { + /** + * @default SUCCESS + * @enum {string} + */ + status?: 'SUCCESS' | 'PENDING' | 'FAILED'; + errors?: definitions['ErrorResponse']; + }; + }; + BatchDelete: { + /** @description Outlines how to find the objects to be deleted. */ + match?: { + /** + * @description Class (name) which objects will be deleted. + * @example City + */ + class?: string; + /** @description Filter to limit the objects to be deleted. */ + where?: definitions['WhereFilter']; + }; + /** + * @description Controls the verbosity of the output, possible values are: "minimal", "verbose". Defaults to "minimal". + * @default minimal + */ + output?: string; + /** + * @description If true, objects will not be deleted yet, but merely listed. Defaults to false. + * @default false + */ + dryRun?: boolean; + }; + /** @description Delete Objects response. */ + BatchDeleteResponse: { + /** @description Outlines how to find the objects to be deleted. */ + match?: { + /** + * @description Class (name) which objects will be deleted. + * @example City + */ + class?: string; + /** @description Filter to limit the objects to be deleted. */ + where?: definitions['WhereFilter']; + }; + /** + * @description Controls the verbosity of the output, possible values are: "minimal", "verbose". Defaults to "minimal". + * @default minimal + */ + output?: string; + /** + * @description If true, objects will not be deleted yet, but merely listed. Defaults to false. + * @default false + */ + dryRun?: boolean; + results?: { + /** + * Format: int64 + * @description How many objects were matched by the filter. + */ + matches?: number; + /** + * Format: int64 + * @description The most amount of objects that can be deleted in a single query, equals QUERY_MAXIMUM_RESULTS. + */ + limit?: number; + /** + * Format: int64 + * @description How many objects were successfully deleted in this round. + */ + successful?: number; + /** + * Format: int64 + * @description How many objects should have been deleted but could not be deleted. + */ + failed?: number; + /** @description With output set to "minimal" only objects with error occurred will the be described. Successfully deleted objects would be omitted. Output set to "verbose" will list all of the objets with their respective statuses. */ + objects?: { + /** + * Format: uuid + * @description ID of the Object. + */ + id?: string; + /** + * @default SUCCESS + * @enum {string} + */ + status?: 'SUCCESS' | 'DRYRUN' | 'FAILED'; + errors?: definitions['ErrorResponse']; + }[]; + }; + }; + /** @description List of Objects. */ + ObjectsListResponse: { + /** @description The actual list of Objects. */ + objects?: definitions['Object'][]; + deprecations?: definitions['Deprecation'][]; + /** + * Format: int64 + * @description The total number of Objects for the query. The number of items in a response may be smaller due to paging. + */ + totalResults?: number; + }; + /** @description Manage classifications, trigger them and view status of past classifications. */ + Classification: { + /** + * Format: uuid + * @description ID to uniquely identify this classification run + * @example ee722219-b8ec-4db1-8f8d-5150bb1a9e0c + */ + id?: string; + /** + * @description class (name) which is used in this classification + * @example City + */ + class?: string; + /** + * @description which ref-property to set as part of the classification + * @example [ + * "inCountry" + * ] + */ + classifyProperties?: string[]; + /** + * @description base the text-based classification on these fields (of type text) + * @example [ + * "description" + * ] + */ + basedOnProperties?: string[]; + /** + * @description status of this classification + * @example running + * @enum {string} + */ + status?: 'running' | 'completed' | 'failed'; + /** @description additional meta information about the classification */ + meta?: definitions['ClassificationMeta']; + /** @description which algorithm to use for classifications */ + type?: string; + /** @description classification-type specific settings */ + settings?: { [key: string]: unknown }; + /** + * @description error message if status == failed + * @default + * @example classify xzy: something went wrong + */ + error?: string; + filters?: { + /** @description limit the objects to be classified */ + sourceWhere?: definitions['WhereFilter']; + /** @description Limit the training objects to be considered during the classification. Can only be used on types with explicit training sets, such as 'knn' */ + trainingSetWhere?: definitions['WhereFilter']; + /** @description Limit the possible sources when using an algorithm which doesn't really on training data, e.g. 'contextual'. When using an algorithm with a training set, such as 'knn', limit the training set instead */ + targetWhere?: definitions['WhereFilter']; + }; + }; + /** @description Additional information to a specific classification */ + ClassificationMeta: { + /** + * Format: date-time + * @description time when this classification was started + * @example 2017-07-21T17:32:28Z + */ + started?: string; + /** + * Format: date-time + * @description time when this classification finished + * @example 2017-07-21T17:32:28Z + */ + completed?: string; + /** + * @description number of objects which were taken into consideration for classification + * @example 147 + */ + count?: number; + /** + * @description number of objects successfully classified + * @example 140 + */ + countSucceeded?: number; + /** + * @description number of objects which could not be classified - see error message for details + * @example 7 + */ + countFailed?: number; + }; + /** @description Filter search results using a where filter */ + WhereFilter: { + /** @description combine multiple where filters, requires 'And' or 'Or' operator */ + operands?: definitions['WhereFilter'][]; + /** + * @description operator to use + * @example GreaterThanEqual + * @enum {string} + */ + operator?: + | 'And' + | 'Or' + | 'Equal' + | 'Like' + | 'Not' + | 'NotEqual' + | 'GreaterThan' + | 'GreaterThanEqual' + | 'LessThan' + | 'LessThanEqual' + | 'WithinGeoRange' + | 'IsNull'; + /** + * @description path to the property currently being filtered + * @example [ + * "inCity", + * "City", + * "name" + * ] + */ + path?: string[]; + /** + * Format: int64 + * @description value as integer + * @example 2000 + */ + valueInt?: number; + /** + * Format: float64 + * @description value as number/float + * @example 3.14 + */ + valueNumber?: number; + /** + * @description value as boolean + * @example false + */ + valueBoolean?: boolean; + /** + * @description value as string + * @example my search term + */ + valueString?: string; + /** + * @description value as text (on text props) + * @example my search term + */ + valueText?: string; + /** + * @description value as date (as string) + * @example TODO + */ + valueDate?: string; + /** @description value as geo coordinates and distance */ + valueGeoRange?: definitions['WhereFilterGeoRange']; + }; + /** @description filter within a distance of a georange */ + WhereFilterGeoRange: { + geoCoordinates?: definitions['GeoCoordinates']; + distance?: { + /** Format: float64 */ + max?: number; + }; + }; +} + +export interface parameters { + /** @description The starting ID of the result window. */ + CommonAfterParameterQuery: string; + /** + * Format: int64 + * @description The starting index of the result window. Default value is 0. + * @default 0 + */ + CommonOffsetParameterQuery: number; + /** + * Format: int64 + * @description The maximum number of items to be returned per page. Default value is set in Weaviate config. + */ + CommonLimitParameterQuery: number; + /** @description Include additional information, such as classification infos. Allowed values include: classification, vector, interpretation */ + CommonIncludeParameterQuery: string; + /** @description Determines how many replicas must acknowledge a request before it is considered successful */ + CommonConsistencyLevelParameterQuery: string; + /** @description The target node which should fulfill the request */ + CommonNodeNameParameterQuery: string; + /** @description Sort parameter to pass an information about the names of the sort fields */ + CommonSortParameterQuery: string; + /** @description Order parameter to tell how to order (asc or desc) data within given field */ + CommonOrderParameterQuery: string; + /** @description Class parameter specifies the class from which to query objects */ + CommonClassParameterQuery: string; +} + +export interface operations { + /** Home. Discover the REST API */ + 'weaviate.root': { + responses: { + /** Weaviate is alive and ready to serve content */ + 200: { + schema: { + links?: definitions['Link'][]; + }; + }; + }; + }; + /** Determines whether the application is alive. Can be used for kubernetes liveness probe */ + 'weaviate.wellknown.liveness': { + responses: { + /** The application is able to respond to HTTP requests */ + 200: unknown; + }; + }; + /** Determines whether the application is ready to receive traffic. Can be used for kubernetes readiness probe. */ + 'weaviate.wellknown.readiness': { + responses: { + /** The application has completed its start-up routine and is ready to accept traffic. */ + 200: unknown; + /** The application is currently not able to serve traffic. If other horizontal replicas of weaviate are available and they are capable of receiving traffic, all traffic should be redirected there instead. */ + 503: unknown; + }; + }; + /** Lists all Objects in reverse order of creation, owned by the user that belongs to the used token. */ + 'objects.list': { + parameters: { + query: { + /** The starting ID of the result window. */ + after?: parameters['CommonAfterParameterQuery']; + /** The starting index of the result window. Default value is 0. */ + offset?: parameters['CommonOffsetParameterQuery']; + /** The maximum number of items to be returned per page. Default value is set in Weaviate config. */ + limit?: parameters['CommonLimitParameterQuery']; + /** Include additional information, such as classification infos. Allowed values include: classification, vector, interpretation */ + include?: parameters['CommonIncludeParameterQuery']; + /** Sort parameter to pass an information about the names of the sort fields */ + sort?: parameters['CommonSortParameterQuery']; + /** Order parameter to tell how to order (asc or desc) data within given field */ + order?: parameters['CommonOrderParameterQuery']; + /** Class parameter specifies the class from which to query objects */ + class?: parameters['CommonClassParameterQuery']; + }; + }; + responses: { + /** Successful response. */ + 200: { + schema: definitions['ObjectsListResponse']; + }; + /** Malformed request. */ + 400: { + schema: definitions['ErrorResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Successful query result but no resource was found. */ + 404: unknown; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the class is defined in the configuration file? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Registers a new Object. Provided meta-data and schema values are validated. */ + 'objects.create': { + parameters: { + body: { + body: definitions['Object']; + }; + query: { + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + }; + }; + responses: { + /** Object created. */ + 200: { + schema: definitions['Object']; + }; + /** Malformed request. */ + 400: { + schema: definitions['ErrorResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the class is defined in the configuration file? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Lists Objects. */ + 'objects.get': { + parameters: { + path: { + /** Unique ID of the Object. */ + id: string; + }; + query: { + /** Include additional information, such as classification infos. Allowed values include: classification, vector, interpretation */ + include?: parameters['CommonIncludeParameterQuery']; + }; + }; + responses: { + /** Successful response. */ + 200: { + schema: definitions['Object']; + }; + /** Malformed request. */ + 400: { + schema: definitions['ErrorResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Successful query result but no resource was found. */ + 404: unknown; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Updates an Object's data. Given meta-data and schema values are validated. LastUpdateTime is set to the time this function is called. */ + 'objects.update': { + parameters: { + path: { + /** Unique ID of the Object. */ + id: string; + }; + body: { + body: definitions['Object']; + }; + query: { + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + }; + }; + responses: { + /** Successfully received. */ + 200: { + schema: definitions['Object']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Successful query result but no resource was found. */ + 404: unknown; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the class is defined in the configuration file? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Deletes an Object from the system. */ + 'objects.delete': { + parameters: { + path: { + /** Unique ID of the Object. */ + id: string; + }; + query: { + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + }; + }; + responses: { + /** Successfully deleted. */ + 204: never; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Successful query result but no resource was found. */ + 404: unknown; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Checks if an Object exists in the system. */ + 'objects.head': { + parameters: { + path: { + /** Unique ID of the Object. */ + id: string; + }; + }; + responses: { + /** Object exists. */ + 204: never; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Object doesn't exist. */ + 404: unknown; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Updates an Object. This method supports json-merge style patch semantics (RFC 7396). Provided meta-data and schema values are validated. LastUpdateTime is set to the time this function is called. */ + 'objects.patch': { + parameters: { + path: { + /** Unique ID of the Object. */ + id: string; + }; + body: { + /** RFC 7396-style patch, the body contains the object to merge into the existing object. */ + body?: definitions['Object']; + }; + query: { + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + }; + }; + responses: { + /** Successfully applied. No content provided. */ + 204: never; + /** The patch-JSON is malformed. */ + 400: unknown; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Successful query result but no resource was found. */ + 404: unknown; + /** The patch-JSON is valid but unprocessable. */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Get a single data object */ + 'objects.class.get': { + parameters: { + path: { + className: string; + /** Unique ID of the Object. */ + id: string; + }; + query: { + /** Include additional information, such as classification infos. Allowed values include: classification, vector, interpretation */ + include?: parameters['CommonIncludeParameterQuery']; + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + /** The target node which should fulfill the request */ + node_name?: parameters['CommonNodeNameParameterQuery']; + }; + }; + responses: { + /** Successful response. */ + 200: { + schema: definitions['Object']; + }; + /** Malformed request. */ + 400: { + schema: definitions['ErrorResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Successful query result but no resource was found. */ + 404: unknown; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Update an individual data object based on its class and uuid. */ + 'objects.class.put': { + parameters: { + path: { + className: string; + /** The uuid of the data object to update. */ + id: string; + }; + body: { + body: definitions['Object']; + }; + query: { + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + }; + }; + responses: { + /** Successfully received. */ + 200: { + schema: definitions['Object']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Successful query result but no resource was found. */ + 404: unknown; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the class is defined in the configuration file? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Delete a single data object. */ + 'objects.class.delete': { + parameters: { + path: { + className: string; + /** Unique ID of the Object. */ + id: string; + }; + query: { + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + }; + }; + responses: { + /** Successfully deleted. */ + 204: never; + /** Malformed request. */ + 400: { + schema: definitions['ErrorResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Successful query result but no resource was found. */ + 404: unknown; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Checks if a data object exists without retrieving it. */ + 'objects.class.head': { + parameters: { + path: { + /** The class name as defined in the schema */ + className: string; + /** The uuid of the data object */ + id: string; + }; + query: { + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + }; + }; + responses: { + /** Object exists. */ + 204: never; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Object doesn't exist. */ + 404: unknown; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Update an individual data object based on its class and uuid. This method supports json-merge style patch semantics (RFC 7396). Provided meta-data and schema values are validated. LastUpdateTime is set to the time this function is called. */ + 'objects.class.patch': { + parameters: { + path: { + /** The class name as defined in the schema */ + className: string; + /** The uuid of the data object to update. */ + id: string; + }; + body: { + /** RFC 7396-style patch, the body contains the object to merge into the existing object. */ + body?: definitions['Object']; + }; + query: { + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + }; + }; + responses: { + /** Successfully applied. No content provided. */ + 204: never; + /** The patch-JSON is malformed. */ + 400: unknown; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Successful query result but no resource was found. */ + 404: unknown; + /** The patch-JSON is valid but unprocessable. */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Replace all references to a class-property. */ + 'objects.references.update': { + parameters: { + path: { + /** Unique ID of the Object. */ + id: string; + /** Unique name of the property related to the Object. */ + propertyName: string; + }; + body: { + body: definitions['MultipleRef']; + }; + }; + responses: { + /** Successfully replaced all the references. */ + 200: unknown; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the property exists or that it is a class? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Add a single reference to a class-property. */ + 'objects.references.create': { + parameters: { + path: { + /** Unique ID of the Object. */ + id: string; + /** Unique name of the property related to the Object. */ + propertyName: string; + }; + body: { + body: definitions['SingleRef']; + }; + }; + responses: { + /** Successfully added the reference. */ + 200: unknown; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the property exists or that it is a class? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Delete the single reference that is given in the body from the list of references that this property has. */ + 'objects.references.delete': { + parameters: { + path: { + /** Unique ID of the Object. */ + id: string; + /** Unique name of the property related to the Object. */ + propertyName: string; + }; + body: { + body: definitions['SingleRef']; + }; + }; + responses: { + /** Successfully deleted. */ + 204: never; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Successful query result but no resource was found. */ + 404: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Update all references of a property of a data object. */ + 'objects.class.references.put': { + parameters: { + path: { + /** The class name as defined in the schema */ + className: string; + /** Unique ID of the Object. */ + id: string; + /** Unique name of the property related to the Object. */ + propertyName: string; + }; + body: { + body: definitions['MultipleRef']; + }; + query: { + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + }; + }; + responses: { + /** Successfully replaced all the references. */ + 200: unknown; + /** Malformed request. */ + 400: { + schema: definitions['ErrorResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Source object doesn't exist. */ + 404: unknown; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the property exists or that it is a class? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Add a single reference to a class-property. */ + 'objects.class.references.create': { + parameters: { + path: { + /** The class name as defined in the schema */ + className: string; + /** Unique ID of the Object. */ + id: string; + /** Unique name of the property related to the Object. */ + propertyName: string; + }; + body: { + body: definitions['SingleRef']; + }; + query: { + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + }; + }; + responses: { + /** Successfully added the reference. */ + 200: unknown; + /** Malformed request. */ + 400: { + schema: definitions['ErrorResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Source object doesn't exist. */ + 404: unknown; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the property exists or that it is a class? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Delete the single reference that is given in the body from the list of references that this property of a data object has */ + 'objects.class.references.delete': { + parameters: { + path: { + /** The class name as defined in the schema */ + className: string; + /** Unique ID of the Object. */ + id: string; + /** Unique name of the property related to the Object. */ + propertyName: string; + }; + body: { + body: definitions['SingleRef']; + }; + query: { + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + }; + }; + responses: { + /** Successfully deleted. */ + 204: never; + /** Malformed request. */ + 400: { + schema: definitions['ErrorResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Successful query result but no resource was found. */ + 404: { + schema: definitions['ErrorResponse']; + }; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the property exists or that it is a class? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Validate an Object's schema and meta-data. It has to be based on a schema, which is related to the given Object to be accepted by this validation. */ + 'objects.validate': { + parameters: { + body: { + body: definitions['Object']; + }; + }; + responses: { + /** Successfully validated. */ + 200: unknown; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the class is defined in the configuration file? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Register new Objects in bulk. Provided meta-data and schema values are validated. */ + 'batch.objects.create': { + parameters: { + body: { + body: { + /** @description Define which fields need to be returned. Default value is ALL */ + fields?: ('ALL' | 'class' | 'schema' | 'id' | 'creationTimeUnix')[]; + objects?: definitions['Object'][]; + }; + }; + query: { + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + }; + }; + responses: { + /** Request succeeded, see response body to get detailed information about each batched item. */ + 200: { + schema: definitions['ObjectsGetResponse'][]; + }; + /** Malformed request. */ + 400: { + schema: definitions['ErrorResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the class is defined in the configuration file? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Delete Objects in bulk that match a certain filter. */ + 'batch.objects.delete': { + parameters: { + body: { + body: definitions['BatchDelete']; + }; + query: { + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + }; + }; + responses: { + /** Request succeeded, see response body to get detailed information about each batched item. */ + 200: { + schema: definitions['BatchDeleteResponse']; + }; + /** Malformed request. */ + 400: { + schema: definitions['ErrorResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the class is defined in the configuration file? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Register cross-references between any class items (objects or objects) in bulk. */ + 'batch.references.create': { + parameters: { + body: { + /** A list of references to be batched. The ideal size depends on the used database connector. Please see the documentation of the used connector for help */ + body: definitions['BatchReference'][]; + }; + query: { + /** Determines how many replicas must acknowledge a request before it is considered successful */ + consistency_level?: parameters['CommonConsistencyLevelParameterQuery']; + }; + }; + responses: { + /** Request Successful. Warning: A successful request does not guarantee that every batched reference was successfully created. Inspect the response body to see which references succeeded and which failed. */ + 200: { + schema: definitions['BatchReferenceResponse'][]; + }; + /** Malformed request. */ + 400: { + schema: definitions['ErrorResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the class is defined in the configuration file? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Get an object based on GraphQL */ + 'graphql.post': { + parameters: { + body: { + /** The GraphQL query request parameters. */ + body: definitions['GraphQLQuery']; + }; + }; + responses: { + /** Successful query (with select). */ + 200: { + schema: definitions['GraphQLResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the class is defined in the configuration file? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Perform a batched GraphQL query */ + 'graphql.batch': { + parameters: { + body: { + /** The GraphQL queries. */ + body: definitions['GraphQLQueries']; + }; + }; + responses: { + /** Successful query (with select). */ + 200: { + schema: definitions['GraphQLResponses']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Request body is well-formed (i.e., syntactically correct), but semantically erroneous. Are you sure the class is defined in the configuration file? */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Gives meta information about the server and can be used to provide information to another Weaviate instance that wants to interact with the current instance. */ + 'meta.get': { + responses: { + /** Successful response. */ + 200: { + schema: definitions['Meta']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + 'schema.dump': { + responses: { + /** Successfully dumped the database schema. */ + 200: { + schema: definitions['Schema']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + 'schema.objects.create': { + parameters: { + body: { + objectClass: definitions['Class']; + }; + }; + responses: { + /** Added the new Object class to the schema. */ + 200: { + schema: definitions['Class']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Invalid Object class */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + 'schema.objects.get': { + parameters: { + path: { + className: string; + }; + }; + responses: { + /** Found the Class, returned as body */ + 200: { + schema: definitions['Class']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** This class does not exist */ + 404: unknown; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Use this endpoint to alter an existing class in the schema. Note that not all settings are mutable. If an error about immutable fields is returned and you still need to update this particular setting, you will have to delete the class (and the underlying data) and recreate. This endpoint cannot be used to modify properties. Instead use POST /v1/schema/{className}/properties. A typical use case for this endpoint is to update configuration, such as the vectorIndexConfig. Note that even in mutable sections, such as vectorIndexConfig, some fields may be immutable. */ + 'schema.objects.update': { + parameters: { + path: { + className: string; + }; + body: { + objectClass: definitions['Class']; + }; + }; + responses: { + /** Class was updated successfully */ + 200: { + schema: definitions['Class']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Class to be updated does not exist */ + 404: { + schema: definitions['ErrorResponse']; + }; + /** Invalid update attempt */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + 'schema.objects.delete': { + parameters: { + path: { + className: string; + }; + query: { + force?: boolean; + }; + }; + responses: { + /** Removed the Object class from the schema. */ + 200: unknown; + /** Could not delete the Object class. */ + 400: { + schema: definitions['ErrorResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + 'schema.objects.properties.add': { + parameters: { + path: { + className: string; + }; + body: { + body: definitions['Property']; + }; + }; + responses: { + /** Added the property. */ + 200: { + schema: definitions['Property']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Invalid property. */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + 'schema.objects.shards.get': { + parameters: { + path: { + className: string; + }; + }; + responses: { + /** Found the status of the shards, returned as body */ + 200: { + schema: definitions['ShardStatusList']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** This class does not exist */ + 404: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Update shard status of an Object Class */ + 'schema.objects.shards.update': { + parameters: { + path: { + className: string; + shardName: string; + }; + body: { + body: definitions['ShardStatus']; + }; + }; + responses: { + /** Shard status was updated successfully */ + 200: { + schema: definitions['ShardStatus']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Shard to be updated does not exist */ + 404: { + schema: definitions['ErrorResponse']; + }; + /** Invalid update attempt */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Starts a process of creating a backup for a set of classes */ + 'backups.create': { + parameters: { + path: { + /** Backup backend name e.g. filesystem, gcs, s3. */ + backend: string; + }; + body: { + body: definitions['BackupCreateRequest']; + }; + }; + responses: { + /** Backup create process successfully started. */ + 200: { + schema: definitions['BackupCreateResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Invalid backup creation attempt. */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Returns status of backup creation attempt for a set of classes */ + 'backups.create.status': { + parameters: { + path: { + /** Backup backend name e.g. filesystem, gcs, s3. */ + backend: string; + /** The ID of a backup. Must be URL-safe and work as a filesystem path, only lowercase, numbers, underscore, minus characters allowed. */ + id: string; + }; + }; + responses: { + /** Backup creation status successfully returned */ + 200: { + schema: definitions['BackupCreateStatusResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Not Found - Backup does not exist */ + 404: { + schema: definitions['ErrorResponse']; + }; + /** Invalid backup restoration status attempt. */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Returns status of a backup restoration attempt for a set of classes */ + 'backups.restore.status': { + parameters: { + path: { + /** Backup backend name e.g. filesystem, gcs, s3. */ + backend: string; + /** The ID of a backup. Must be URL-safe and work as a filesystem path, only lowercase, numbers, underscore, minus characters allowed. */ + id: string; + }; + }; + responses: { + /** Backup restoration status successfully returned */ + 200: { + schema: definitions['BackupRestoreStatusResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Not Found - Backup does not exist */ + 404: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Starts a process of restoring a backup for a set of classes */ + 'backups.restore': { + parameters: { + path: { + /** Backup backend name e.g. filesystem, gcs, s3. */ + backend: string; + /** The ID of a backup. Must be URL-safe and work as a filesystem path, only lowercase, numbers, underscore, minus characters allowed. */ + id: string; + }; + body: { + body: definitions['BackupRestoreRequest']; + }; + }; + responses: { + /** Backup restoration process successfully started. */ + 200: { + schema: definitions['BackupRestoreResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Not Found - Backup does not exist */ + 404: { + schema: definitions['ErrorResponse']; + }; + /** Invalid backup restoration attempt. */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Returns status of Weaviate DB. */ + 'nodes.get': { + responses: { + /** Nodes status successfully returned */ + 200: { + schema: definitions['NodesStatusResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Not Found - Backup does not exist */ + 404: { + schema: definitions['ErrorResponse']; + }; + /** Invalid backup restoration status attempt. */ + 422: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Trigger a classification based on the specified params. Classifications will run in the background, use GET /classifications/ to retrieve the status of your classification. */ + 'classifications.post': { + parameters: { + body: { + /** parameters to start a classification */ + params: definitions['Classification']; + }; + }; + responses: { + /** Successfully started classification. */ + 201: { + schema: definitions['Classification']; + }; + /** Incorrect request */ + 400: { + schema: definitions['ErrorResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; + /** Get status, results and metadata of a previously created classification */ + 'classifications.get': { + parameters: { + path: { + /** classification id */ + id: string; + }; + }; + responses: { + /** Found the classification, returned as body */ + 200: { + schema: definitions['Classification']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** Not Found - Classification does not exist */ + 404: unknown; + /** An error has occurred while trying to fulfill the request. Most likely the ErrorResponse will contain more information about the error. */ + 500: { + schema: definitions['ErrorResponse']; + }; + }; + }; +} + +export interface external {} diff --git a/src/openapi/types.ts b/src/openapi/types.ts new file mode 100644 index 00000000..160f08a9 --- /dev/null +++ b/src/openapi/types.ts @@ -0,0 +1,38 @@ +import { definitions } from './schema'; + +export type WeaviateObject = definitions['Object']; +export type WeaviateObjectsList = definitions['ObjectsListResponse']; +export type WeaviateObjectsGet = definitions['ObjectsGetResponse']; +export type Reference = definitions['SingleRef']; +export type WeaviateError = definitions['ErrorResponse']; +export type Properties = definitions['PropertySchema']; +export type Property = definitions['Property']; +export type DataObject = definitions['Object']; +// Backup +export type BackupCreateRequest = definitions['BackupCreateRequest']; +export type BackupCreateResponse = definitions['BackupCreateResponse']; +export type BackupCreateStatusResponse = definitions['BackupCreateStatusResponse']; +export type BackupRestoreRequest = definitions['BackupRestoreRequest']; +export type BackupRestoreResponse = definitions['BackupRestoreResponse']; +export type BackupRestoreStatusResponse = definitions['BackupRestoreStatusResponse']; +// Batch +export type BatchDelete = definitions['BatchDelete']; +export type BatchDeleteResponse = definitions['BatchDeleteResponse']; +export type BatchRequest = { + fields?: ('ALL' | 'class' | 'schema' | 'id' | 'creationTimeUnix')[]; + objects?: WeaviateObject[]; +}; +export type BatchReference = definitions['BatchReference']; +export type BatchReferenceResponse = definitions['BatchReferenceResponse']; +// C11y +export type C11yWordsResponse = definitions['C11yWordsResponse']; +export type C11yExtension = definitions['C11yExtension']; +// Classifications +export type Classification = definitions['Classification']; +// GraphQL +export type WhereFilter = definitions['WhereFilter']; +// Schema +export type WeaviateSchema = definitions['Schema']; +export type WeaviateClass = definitions['Class']; +export type ShardStatus = definitions['ShardStatus']; +export type ShardStatusList = definitions['ShardStatusList']; diff --git a/src/schema/classCreator.ts b/src/schema/classCreator.ts index c0d4ca01..e3a9444d 100644 --- a/src/schema/classCreator.ts +++ b/src/schema/classCreator.ts @@ -1,14 +1,15 @@ import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { WeaviateClass } from '../openapi/types'; export default class ClassCreator extends CommandBase { - private class: any; + private class!: WeaviateClass; constructor(client: Connection) { super(client); } - withClass = (classObj: any) => { + withClass = (classObj: object) => { this.class = classObj; return this; }; @@ -23,12 +24,10 @@ export default class ClassCreator extends CommandBase { this.validateClass(); } - do = () => { + do = (): Promise => { this.validateClass(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const path = `/schema`; return this.client.post(path, this.class); diff --git a/src/schema/classDeleter.ts b/src/schema/classDeleter.ts index 063cbc8d..fbbeaa60 100644 --- a/src/schema/classDeleter.ts +++ b/src/schema/classDeleter.ts @@ -16,9 +16,7 @@ export default class ClassDeleter extends CommandBase { validateClassName = () => { if (!isValidStringProperty(this.className)) { - this.addError( - 'className must be set - set with .withClassName(className)' - ); + this.addError('className must be set - set with .withClassName(className)'); } }; @@ -26,12 +24,10 @@ export default class ClassDeleter extends CommandBase { this.validateClassName(); }; - do = () => { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const path = `/schema/${this.className}`; return this.client.delete(path, undefined, false); diff --git a/src/schema/classGetter.ts b/src/schema/classGetter.ts index eb270b61..0718ee33 100644 --- a/src/schema/classGetter.ts +++ b/src/schema/classGetter.ts @@ -1,6 +1,7 @@ import { isValidStringProperty } from '../validation/string'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { WeaviateClass } from '../openapi/types'; export default class ClassGetter extends CommandBase { private className?: string; @@ -9,16 +10,14 @@ export default class ClassGetter extends CommandBase { super(client); } - withClassName = (className: any) => { + withClassName = (className: string) => { this.className = className; return this; }; validateClassName = () => { if (!isValidStringProperty(this.className)) { - this.addError( - 'className must be set - set with .withClassName(className)' - ); + this.addError('className must be set - set with .withClassName(className)'); } }; @@ -26,12 +25,10 @@ export default class ClassGetter extends CommandBase { this.validateClassName(); }; - do = () => { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const path = `/schema/${this.className}`; return this.client.get(path); diff --git a/src/schema/getter.ts b/src/schema/getter.ts index 5dd9d766..b1b1f05e 100644 --- a/src/schema/getter.ts +++ b/src/schema/getter.ts @@ -1,5 +1,6 @@ import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { WeaviateSchema } from '../openapi/types'; export default class Getter extends CommandBase { constructor(client: Connection) { @@ -10,11 +11,9 @@ export default class Getter extends CommandBase { // nothing to validate } - do = () => { + do = (): Promise => { if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const path = `/schema`; return this.client.get(path); diff --git a/src/schema/journey.test.ts b/src/schema/journey.test.ts index dd13b498..de21899f 100644 --- a/src/schema/journey.test.ts +++ b/src/schema/journey.test.ts @@ -1,4 +1,6 @@ -import weaviate, { WeaviateClient } from '../index'; +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import weaviate, { WeaviateClient } from '..'; +import { WeaviateClass, Property, WeaviateSchema, ShardStatus, ShardStatusList } from '../openapi/types'; describe('schema', () => { const client = weaviate.client({ @@ -13,7 +15,7 @@ describe('schema', () => { .classCreator() .withClass(classObj) .do() - .then((res: any) => { + .then((res: WeaviateClass) => { expect(res).toEqual(classObj); }); }); @@ -23,29 +25,14 @@ describe('schema', () => { .classGetter() .withClassName(classObj.class) .do() - .then((res: any) => { + .then((res: WeaviateClass) => { expect(res).toEqual(classObj); }); }); - it('fails to create class with property having not supported tokenization', () => { - const doomedClass = newClassObject('DoomedClass'); - doomedClass.properties[0].tokenization = 'not-supported'; - - return client.schema - .classCreator() - .withClass(doomedClass) - .do() - .catch((err: Error) => { - expect(err.message).toEqual( - 'usage error (422): {"code":606,"message":"properties.0.tokenization in body should be one of [word field]"}' - ); - }); - }); - it('extends the thing class with a new property', () => { const className = 'MyThingClass'; - const prop = { + const prop: Property = { dataType: ['string'], name: 'anotherProp', tokenization: 'field', @@ -69,7 +56,7 @@ describe('schema', () => { it('fails to extend the thing class with property having not supported tokenization (1)', () => { const className = 'MyThingClass'; - const prop = { + const prop: Property = { dataType: ['text'], name: 'yetAnotherProp', tokenization: 'field', @@ -95,7 +82,7 @@ describe('schema', () => { it('fails to extend the thing class with property having not supported tokenization (2)', () => { const className = 'MyThingClass'; - const prop = { + const prop: Property = { dataType: ['int[]'], name: 'yetAnotherProp', tokenization: 'word', @@ -123,7 +110,7 @@ describe('schema', () => { return client.schema .getter() .do() - .then((res: any) => { + .then((res: WeaviateSchema) => { expect(res).toEqual({ classes: [ { @@ -216,43 +203,43 @@ describe('schema', () => { it('gets the shards of an existing class', () => { return client.schema .shardsGetter() - .withClassName(classObj.class) + .withClassName(classObj.class!) .do() - .then((res: any) => { - res.forEach((shard: any) => { + .then((res: ShardStatusList) => { + res.forEach((shard: ShardStatus) => { expect(shard.status).toEqual('READY'); }); }); }); it('updates a shard of an existing class to readonly', async () => { - const shards = await getShards(client, classObj.class); + const shards = await getShards(client, classObj.class!); expect(Array.isArray(shards)).toBe(true); expect(shards.length).toEqual(1); return client.schema .shardUpdater() - .withClassName(classObj.class) - .withShardName(shards[0].name) + .withClassName(classObj.class!) + .withShardName(shards[0].name!) .withStatus('READONLY') .do() - .then((res: any) => { + .then((res: ShardStatus) => { expect(res.status).toEqual('READONLY'); }); }); it('updates a shard of an existing class to ready', async () => { - const shards = await getShards(client, classObj.class); + const shards = await getShards(client, classObj.class!); expect(Array.isArray(shards)).toBe(true); expect(shards.length).toEqual(1); return client.schema .shardUpdater() - .withClassName(classObj.class) - .withShardName(shards[0].name) + .withClassName(classObj.class!) + .withShardName(shards[0].name!) .withStatus('READY') .do() - .then((res: any) => { + .then((res: ShardStatus) => { expect(res.status).toEqual('READY'); }); }); @@ -260,9 +247,9 @@ describe('schema', () => { it('deletes an existing class', () => { return client.schema .classDeleter() - .withClassName(classObj.class) + .withClassName(classObj.class!) .do() - .then((res: any) => { + .then((res: void) => { expect(res).toEqual(undefined); }); }); @@ -276,7 +263,7 @@ describe('schema', () => { .classCreator() .withClass(newClass) .do() - .then((res: any) => { + .then((res: WeaviateClass) => { expect(res).toHaveProperty('shardingConfig.actualCount', 3); }); @@ -289,9 +276,9 @@ describe('schema', () => { .withClassName(newClass.class) .withStatus('READONLY') .do() - .then((res: any) => { + .then((res: ShardStatusList) => { expect(res.length).toEqual(shardCount); - res.forEach((obj: any) => { + res.forEach((obj: ShardStatus) => { expect(obj.status).toEqual('READONLY'); }); }); @@ -321,7 +308,7 @@ describe('schema', () => { .classCreator() .withClass(newClass) .do() - .then((res: any) => { + .then((res: WeaviateClass) => { expect(res).toHaveProperty('invertedIndexConfig.bm25', bm25Config); }); @@ -342,11 +329,8 @@ describe('schema', () => { .classCreator() .withClass(newClass) .do() - .then((res: any) => { - expect(res).toHaveProperty( - 'invertedIndexConfig.stopwords', - stopwordConfig - ); + .then((res: WeaviateClass) => { + expect(res).toHaveProperty('invertedIndexConfig.stopwords', stopwordConfig); }); return deleteClass(client, newClass.class); @@ -374,12 +358,9 @@ describe('schema', () => { .classCreator() .withClass(newClass) .do() - .then((res: any) => { + .then((res: WeaviateClass) => { expect(res).toHaveProperty('invertedIndexConfig.bm25', bm25Config); - expect(res).toHaveProperty( - 'invertedIndexConfig.stopwords', - stopwordConfig - ); + expect(res).toHaveProperty('invertedIndexConfig.stopwords', stopwordConfig); }); return deleteClass(client, newClass.class); @@ -394,11 +375,8 @@ describe('schema', () => { .classCreator() .withClass(newClass) .do() - .then((res: any) => { - expect(res).toHaveProperty( - 'replicationConfig.factor', - replicationFactor - ); + .then((res: WeaviateClass) => { + expect(res).toHaveProperty('replicationConfig.factor', replicationFactor); }); return deleteClass(client, newClass.class); @@ -412,7 +390,7 @@ describe('schema', () => { .classCreator() .withClass(newClass) .do() - .then((res: any) => { + .then((res: WeaviateClass) => { expect(res).toHaveProperty('replicationConfig.factor', 1); }); @@ -494,12 +472,12 @@ function newClassObject(className: string) { }; } -function getShards(client: WeaviateClient, className: string) { +function getShards(client: WeaviateClient, className: string): Promise { return client.schema .shardsGetter() .withClassName(className) .do() - .then((res: any) => { + .then((res: ShardStatusList) => { return res; }); } @@ -509,7 +487,7 @@ function deleteClass(client: WeaviateClient, className: string) { .classDeleter() .withClassName(className) .do() - .then((res: any) => { + .then((res: void) => { expect(res).toEqual(undefined); }); } diff --git a/src/schema/propertyCreator.ts b/src/schema/propertyCreator.ts index e1bbaf4f..46912733 100644 --- a/src/schema/propertyCreator.ts +++ b/src/schema/propertyCreator.ts @@ -1,10 +1,11 @@ import { isValidStringProperty } from '../validation/string'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { Property } from '../openapi/types'; export default class PropertyCreator extends CommandBase { - private className?: string; - private property: any; + private className!: string; + private property!: Property; constructor(client: Connection) { super(client); @@ -15,16 +16,14 @@ export default class PropertyCreator extends CommandBase { return this; }; - withProperty = (property: any) => { + withProperty = (property: Property) => { this.property = property; return this; }; validateClassName = () => { if (!isValidStringProperty(this.className)) { - this.addError( - 'className must be set - set with .withClassName(className)' - ); + this.addError('className must be set - set with .withClassName(className)'); } }; @@ -39,12 +38,10 @@ export default class PropertyCreator extends CommandBase { this.validateProperty(); }; - do = () => { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error('invalid usage: ' + this.errors.join(', ')) - ); + return Promise.reject(new Error('invalid usage: ' + this.errors.join(', '))); } const path = `/schema/${this.className}/properties`; return this.client.post(path, this.property); diff --git a/src/schema/shardUpdater.ts b/src/schema/shardUpdater.ts index e268c73a..61893ac2 100644 --- a/src/schema/shardUpdater.ts +++ b/src/schema/shardUpdater.ts @@ -3,9 +3,9 @@ import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; export default class ShardUpdater extends CommandBase { - private className?: string; - private shardName?: string; - private status?: string; + private className!: string; + private shardName!: string; + private status!: string; constructor(client: Connection) { super(client); @@ -18,9 +18,7 @@ export default class ShardUpdater extends CommandBase { validateClassName = () => { if (!isValidStringProperty(this.className)) { - this.addError( - 'className must be set - set with .withClassName(className)' - ); + this.addError('className must be set - set with .withClassName(className)'); } }; @@ -31,9 +29,7 @@ export default class ShardUpdater extends CommandBase { validateShardName = () => { if (!isValidStringProperty(this.shardName)) { - this.addError( - 'shardName must be set - set with .withShardName(shardName)' - ); + this.addError('shardName must be set - set with .withShardName(shardName)'); } }; @@ -57,26 +53,14 @@ export default class ShardUpdater extends CommandBase { do = () => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error(`invalid usage: ${this.errors.join(', ')}`) - ); + return Promise.reject(new Error(`invalid usage: ${this.errors.join(', ')}`)); } - return updateShard( - this.client, - this.className, - this.shardName, - this.status - ); + return updateShard(this.client, this.className, this.shardName, this.status); }; } -export function updateShard( - client: Connection, - className: any, - shardName: any, - status: any -) { +export function updateShard(client: Connection, className: string, shardName: string, status: string) { const path = `/schema/${className}/shards/${shardName}`; return client.put(path, { status: status }, true); } diff --git a/src/schema/shardsGetter.ts b/src/schema/shardsGetter.ts index 300c08d3..7efe7eb5 100644 --- a/src/schema/shardsGetter.ts +++ b/src/schema/shardsGetter.ts @@ -1,6 +1,7 @@ import { isValidStringProperty } from '../validation/string'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { ShardStatusList } from '../openapi/types'; export default class ShardsGetter extends CommandBase { private className?: string; @@ -16,9 +17,7 @@ export default class ShardsGetter extends CommandBase { validateClassName = () => { if (!isValidStringProperty(this.className)) { - this.addError( - 'className must be set - set with .withClassName(className)' - ); + this.addError('className must be set - set with .withClassName(className)'); } }; @@ -26,12 +25,10 @@ export default class ShardsGetter extends CommandBase { this.validateClassName(); }; - do = () => { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error(`invalid usage: ${this.errors.join(', ')}`) - ); + return Promise.reject(new Error(`invalid usage: ${this.errors.join(', ')}`)); } return getShards(this.client, this.className); diff --git a/src/schema/shardsUpdater.ts b/src/schema/shardsUpdater.ts index 074fc5d0..ba24a145 100644 --- a/src/schema/shardsUpdater.ts +++ b/src/schema/shardsUpdater.ts @@ -3,11 +3,12 @@ import { getShards } from './shardsGetter'; import { updateShard } from './shardUpdater'; import Connection from '../connection'; import { CommandBase } from '../validation/commandBase'; +import { ShardStatus, ShardStatusList } from '../openapi/types'; export default class ShardsUpdater extends CommandBase { - private className?: string; - private shards: any[]; - private status?: string; + private className!: string; + private shards: ShardStatusList; + private status!: string; constructor(client: Connection) { super(client); @@ -21,9 +22,7 @@ export default class ShardsUpdater extends CommandBase { validateClassName = () => { if (!isValidStringProperty(this.className)) { - this.addError( - 'className must be set - set with .withClassName(className)' - ); + this.addError('className must be set - set with .withClassName(className)'); } }; @@ -46,12 +45,7 @@ export default class ShardsUpdater extends CommandBase { updateShards = async () => { const payload: any = await Promise.all( Array.from({ length: this.shards.length }, (_, i) => - updateShard( - this.client, - this.className, - this.shards[i].name, - this.status - ) + updateShard(this.client, this.className, this.shards[i].name || '', this.status) .then((res: any) => { return { name: this.shards[i].name, status: res.status }; }) @@ -60,28 +54,24 @@ export default class ShardsUpdater extends CommandBase { ); if (this.errors.length > 0) { - return Promise.reject( - new Error(`failed to update shards: ${this.errors.join(', ')}`) - ); + return Promise.reject(new Error(`failed to update shards: ${this.errors.join(', ')}`)); } return Promise.resolve(payload); }; - do = () => { + do = (): Promise => { this.validate(); if (this.errors.length > 0) { - return Promise.reject( - new Error(`invalid usage: ${this.errors.join(', ')}`) - ); + return Promise.reject(new Error(`invalid usage: ${this.errors.join(', ')}`)); } return getShards(this.client, this.className) - .then((shards: any) => (this.shards = shards)) + .then((shards: ShardStatusList) => (this.shards = shards)) .then(() => { return this.updateShards(); }) - .then((payload: any) => { + .then((payload: ShardStatusList) => { return payload; }) .catch((err: any) => { diff --git a/src/utils/beaconPath.ts b/src/utils/beaconPath.ts index 14728d67..32bb9f1b 100644 --- a/src/utils/beaconPath.ts +++ b/src/utils/beaconPath.ts @@ -14,13 +14,11 @@ export class BeaconPath { // weaviate://localhost/class/id/ => match[2] = class, match[4] = id // weaviate://localhost/id => match[2] = id, match[4] = undefined // weaviate://localhost/id/ => match[2] = id, match[4] = undefined - this.beaconRegExp = - /^weaviate:\/\/localhost(\/([^\\/]+))?(\/([^\\/]+))?[\\/]?$/gi; + this.beaconRegExp = /^weaviate:\/\/localhost(\/([^\\/]+))?(\/([^\\/]+))?[\\/]?$/gi; } async rebuild(beacon: string) { - const support = - await this.dbVersionSupport.supportsClassNameNamespacedEndpointsPromise(); + const support = await this.dbVersionSupport.supportsClassNameNamespacedEndpointsPromise(); const match = new RegExp(this.beaconRegExp).exec(beacon); if (!match) { return beacon; diff --git a/src/utils/dbVersion.ts b/src/utils/dbVersion.ts index 3ad4450b..d0ed52ff 100644 --- a/src/utils/dbVersion.ts +++ b/src/utils/dbVersion.ts @@ -1,47 +1,45 @@ export class DbVersionSupport { - private dbVersionProvider: IDbVersionProvider; + private dbVersionProvider: VersionProvider; - constructor(dbVersionProvider: IDbVersionProvider) { + constructor(dbVersionProvider: VersionProvider) { this.dbVersionProvider = dbVersionProvider; } supportsClassNameNamespacedEndpointsPromise() { - return this.dbVersionProvider - .getVersionPromise() - .then((version?: string) => ({ - version, - supports: this.supportsClassNameNamespacedEndpoints(version), - warns: { - deprecatedNonClassNameNamespacedEndpointsForObjects: () => - console.warn( - `Usage of objects paths without className is deprecated in Weaviate ${version}. Please provide className parameter` - ), - deprecatedNonClassNameNamespacedEndpointsForReferences: () => - console.warn( - `Usage of references paths without className is deprecated in Weaviate ${version}. Please provide className parameter` - ), - deprecatedNonClassNameNamespacedEndpointsForBeacons: () => - console.warn( - `Usage of beacons paths without className is deprecated in Weaviate ${version}. Please provide className parameter` - ), - notSupportedClassNamespacedEndpointsForObjects: () => - console.warn( - `Usage of objects paths with className is not supported in Weaviate ${version}. className parameter is ignored` - ), - notSupportedClassNamespacedEndpointsForReferences: () => - console.warn( - `Usage of references paths with className is not supported in Weaviate ${version}. className parameter is ignored` - ), - notSupportedClassNamespacedEndpointsForBeacons: () => - console.warn( - `Usage of beacons paths with className is not supported in Weaviate ${version}. className parameter is ignored` - ), - notSupportedClassParameterInEndpointsForObjects: () => - console.warn( - `Usage of objects paths with class query parameter is not supported in Weaviate ${version}. class query parameter is ignored` - ), - }, - })); + return this.dbVersionProvider.getVersionPromise().then((version?: string) => ({ + version, + supports: this.supportsClassNameNamespacedEndpoints(version), + warns: { + deprecatedNonClassNameNamespacedEndpointsForObjects: () => + console.warn( + `Usage of objects paths without className is deprecated in Weaviate ${version}. Please provide className parameter` + ), + deprecatedNonClassNameNamespacedEndpointsForReferences: () => + console.warn( + `Usage of references paths without className is deprecated in Weaviate ${version}. Please provide className parameter` + ), + deprecatedNonClassNameNamespacedEndpointsForBeacons: () => + console.warn( + `Usage of beacons paths without className is deprecated in Weaviate ${version}. Please provide className parameter` + ), + notSupportedClassNamespacedEndpointsForObjects: () => + console.warn( + `Usage of objects paths with className is not supported in Weaviate ${version}. className parameter is ignored` + ), + notSupportedClassNamespacedEndpointsForReferences: () => + console.warn( + `Usage of references paths with className is not supported in Weaviate ${version}. className parameter is ignored` + ), + notSupportedClassNamespacedEndpointsForBeacons: () => + console.warn( + `Usage of beacons paths with className is not supported in Weaviate ${version}. className parameter is ignored` + ), + notSupportedClassParameterInEndpointsForObjects: () => + console.warn( + `Usage of objects paths with class query parameter is not supported in Weaviate ${version}. class query parameter is ignored` + ), + }, + })); } // >= 1.14 @@ -60,11 +58,11 @@ export class DbVersionSupport { const EMPTY_VERSION = ''; -export interface IDbVersionProvider { +export interface VersionProvider { getVersionPromise(): Promise; } -export class DbVersionProvider implements IDbVersionProvider { +export class DbVersionProvider implements VersionProvider { private versionPromise?: Promise; private readonly emptyVersionPromise: Promise; private versionGetter: () => Promise; diff --git a/src/utils/journey.test.ts b/src/utils/journey.test.ts index 7cfbad8a..9238a124 100644 --- a/src/utils/journey.test.ts +++ b/src/utils/journey.test.ts @@ -149,9 +149,7 @@ describe('db version support', () => { it('should not support', () => { const notSupportedVersions = ['0.11', '1.13.9', '1.13', '1.0']; notSupportedVersions.forEach(async (version) => { - const dbVersionProvider = new DbVersionProvider(() => - Promise.resolve(version) - ); + const dbVersionProvider = new DbVersionProvider(() => Promise.resolve(version)); const dbVersionSupport = new DbVersionSupport(dbVersionProvider); await dbVersionSupport @@ -169,9 +167,7 @@ describe('db version support', () => { it('should support', () => { const supportedVersions = ['1.14.0', '1.14.9', '1.100', '2.0', '10.11.12']; supportedVersions.forEach(async (version) => { - const dbVersionProvider = new DbVersionProvider(() => - Promise.resolve(version) - ); + const dbVersionProvider = new DbVersionProvider(() => Promise.resolve(version)); const dbVersionSupport = new DbVersionSupport(dbVersionProvider); await dbVersionSupport diff --git a/src/utils/testData.ts b/src/utils/testData.ts index c4d0eb53..f332c2a4 100644 --- a/src/utils/testData.ts +++ b/src/utils/testData.ts @@ -1,9 +1,10 @@ -import { WeaviateClient } from '../index'; +import { WeaviateClient } from '..'; +import { WeaviateObject, Property } from '../openapi/types'; export const PIZZA_CLASS_NAME = 'Pizza'; export const SOUP_CLASS_NAME = 'Soup'; -const foodProperties = [ +const foodProperties: Property[] = [ { name: 'name', dataType: ['string'], @@ -25,8 +26,7 @@ const foodProperties = [ const pizzaClass = { class: PIZZA_CLASS_NAME, - description: - 'A delicious religion like food and arguably the best export of Italy.', + description: 'A delicious religion like food and arguably the best export of Italy.', invertedIndexConfig: { indexTimestamps: true, }, @@ -39,7 +39,7 @@ const soupClass = { properties: foodProperties, }; -const pizzaObjects = [ +const pizzaObjects: WeaviateObject[] = [ { class: PIZZA_CLASS_NAME, id: '10523cdd-15a2-42f4-81fa-267fe92f7cd6', @@ -80,14 +80,13 @@ const pizzaObjects = [ }, ]; -const soupObjects = [ +const soupObjects: WeaviateObject[] = [ { class: SOUP_CLASS_NAME, id: '8c156d37-81aa-4ce9-a811-621e2702b825', properties: { name: 'ChickenSoup', - description: - 'Used by humans when their inferior genetics are attacked by microscopic organisms.', + description: 'Used by humans when their inferior genetics are attacked by microscopic organisms.', bestBefore: '2022-05-06T07:08:09+05:00', }, }, @@ -112,8 +111,8 @@ export function createTestFoodSchema(client: WeaviateClient) { export function createTestFoodData(client: WeaviateClient) { return client.batch .objectsBatcher() - .withObjects(pizzaObjects) - .withObjects(soupObjects) + .withObjects(...pizzaObjects) + .withObjects(...soupObjects) .do(); } diff --git a/test/dbVersionProvider.ts b/test/dbVersionProvider.ts index 68beff5c..610336d4 100644 --- a/test/dbVersionProvider.ts +++ b/test/dbVersionProvider.ts @@ -1,6 +1,6 @@ -import { IDbVersionProvider } from '../src/utils/dbVersion'; +import { VersionProvider } from '../src/utils/dbVersion'; -export class TestDbVersionProvider implements IDbVersionProvider { +export class TestDbVersionProvider implements VersionProvider { private version: string; constructor(version: string) {