diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 4124c0c5..87c01d56 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -8,10 +8,11 @@ on: env: WEAVIATE_124: 1.24.26 - WEAVIATE_125: 1.25.28 - WEAVIATE_126: 1.26.13 - WEAVIATE_127: 1.27.9 - WEAVIATE_128: 1.28.2 + WEAVIATE_125: 1.25.30 + WEAVIATE_126: 1.26.14 + WEAVIATE_127: 1.27.11 + WEAVIATE_128: 1.28.4 + WEAVIATE_129: 1.29.0 jobs: checks: @@ -39,9 +40,10 @@ jobs: { node: "22.x", weaviate: $WEAVIATE_125}, { node: "22.x", weaviate: $WEAVIATE_126}, { node: "22.x", weaviate: $WEAVIATE_127}, - { node: "18.x", weaviate: $WEAVIATE_128}, - { node: "20.x", weaviate: $WEAVIATE_128}, - { node: "22.x", weaviate: $WEAVIATE_128} + { node: "22.x", weaviate: $WEAVIATE_128}, + { node: "18.x", weaviate: $WEAVIATE_129}, + { node: "20.x", weaviate: $WEAVIATE_129}, + { node: "22.x", weaviate: $WEAVIATE_129} ] steps: - uses: actions/checkout@v3 diff --git a/ci/compose.sh b/ci/compose.sh index ec9a788d..beef0af4 100644 --- a/ci/compose.sh +++ b/ci/compose.sh @@ -21,5 +21,5 @@ function compose_down_all { } function all_weaviate_ports { - echo "8078 8080 8081 8082 8083 8085 8086 8087 8088 8089 8090" + echo "8078 8080 8081 8082 8083 8085 8086 8087 8088 8089 8090 8091" } diff --git a/ci/docker-compose-rbac.yml b/ci/docker-compose-rbac.yml new file mode 100644 index 00000000..57f2b13a --- /dev/null +++ b/ci/docker-compose-rbac.yml @@ -0,0 +1,31 @@ +--- +version: '3.4' +services: + weaviate-rbac: + command: + - --host + - 0.0.0.0 + - --port + - '8085' + - --scheme + - http + - --write-timeout=600s + image: semitechnologies/weaviate:${WEAVIATE_VERSION} + ports: + - 8091:8085 + - 50062:50051 + restart: on-failure:0 + environment: + ENABLE_MODULES: "generative-dummy,reranker-dummy" + PERSISTENCE_DATA_PATH: "./data-weaviate-0" + CLUSTER_IN_LOCALHOST: "true" + CLUSTER_GOSSIP_BIND_PORT: "7100" + CLUSTER_DATA_BIND_PORT: "7101" + RAFT_BOOTSTRAP_EXPECT: "1" + AUTHENTICATION_APIKEY_ENABLED: "true" + AUTHENTICATION_APIKEY_ALLOWED_KEYS: 'viewer-key,editor-key,admin-key,custom-key' + AUTHENTICATION_APIKEY_USERS: 'viewer-user,editor-user,admin-user,custom-user' + AUTHORIZATION_RBAC_ENABLED: "true" + AUTHORIZATION_ADMIN_USERS: "admin-user" + AUTHORIZATION_VIEWER_USERS: "viewer-user" +... diff --git a/package.json b/package.json index 99357dab..a6c4f981 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,8 @@ "format": "prettier --write --no-error-on-unmatched-pattern '**/*.{ts,js}' '!dist/**'", "format:check": "prettier --check --no-error-on-unmatched-pattern '**/*.{ts,js}' '!dist/**'", "format:dist": "prettier --write --no-error-on-unmatched-pattern '**/dist/**/*.{ts,js}'", - "schema": "./tools/refresh_schema.sh", - "protos": "./tools/refresh_protos.sh", + "refresh-schema": "./tools/refresh_schema.sh", + "refresh-protos": "./tools/refresh_protos.sh", "docs": "typedoc --plugin typedoc-plugin-extras --favicon public/favicon.ico --out docs/ src/" }, "repository": { diff --git a/src/collections/aggregate/index.ts b/src/collections/aggregate/index.ts index f038b93c..1dad6460 100644 --- a/src/collections/aggregate/index.ts +++ b/src/collections/aggregate/index.ts @@ -1,14 +1,16 @@ -import Connection from '../../connection/index.js'; +import Connection from '../../connection/grpc.js'; import { ConsistencyLevel } from '../../data/index.js'; import { DbVersionSupport } from '../../utils/dbVersion.js'; import { FilterValue } from '../filters/index.js'; -import { WeaviateQueryError } from '../../errors.js'; +import { WeaviateInvalidInputError, WeaviateQueryError } from '../../errors.js'; import { Aggregator } from '../../graphql/index.js'; import { PrimitiveKeys, toBase64FromMedia } from '../../index.js'; -import { Bm25QueryProperty } from '../query/types.js'; +import { Deserialize } from '../deserialize/index.js'; +import { Bm25QueryProperty, NearVectorInputType } from '../query/types.js'; +import { NearVectorInputGuards } from '../query/utils.js'; import { Serialize } from '../serialize/index.js'; export type AggregateBaseOptions = { @@ -63,10 +65,10 @@ export type AggregateBoolean = { export type AggregateDate = { count?: number; - maximum?: number; - median?: number; - minimum?: number; - mode?: number; + maximum?: string; + median?: string; + minimum?: string; + mode?: string; }; export type AggregateNumber = { @@ -87,7 +89,7 @@ export type AggregateText = { count?: number; topOccurrences?: { occurs?: number; - value?: number; + value?: string; }[]; }; @@ -328,13 +330,19 @@ export type AggregateResult | undefined = unde totalCount: number; }; +export type AggregatedGeoCoordinate = { + latitude: number; + longitude: number; + distance: number; +}; + export type AggregateGroupByResult< T, M extends PropertiesMetrics | undefined = undefined > = AggregateResult & { groupedBy: { prop: string; - value: string; + value: string | number | boolean | AggregatedGeoCoordinate | string[] | number[] | boolean[]; }; }; @@ -345,6 +353,7 @@ class AggregateManager implements Aggregate { dbVersionSupport: DbVersionSupport; consistencyLevel?: ConsistencyLevel; tenant?: string; + grpcChecker: Promise; private constructor( connection: Connection, @@ -359,11 +368,25 @@ class AggregateManager implements Aggregate { this.consistencyLevel = consistencyLevel; this.tenant = tenant; + this.grpcChecker = this.dbVersionSupport.supportsAggregateGRPC().then((res) => res.supports); + this.groupBy = { - hybrid: | undefined = undefined>( + hybrid: async >( query: string, opts: AggregateGroupByHybridOptions ): Promise[]> => { + if (await this.grpcChecker) { + const group = typeof opts.groupBy === 'string' ? { property: opts.groupBy } : opts.groupBy; + return this.grpc() + .then((aggregate) => + aggregate.withHybrid({ + ...Serialize.aggregate.hybrid(query, opts), + groupBy: Serialize.aggregate.groupBy(group), + limit: group.limit, + }) + ) + .then((reply) => Deserialize.aggregateGroupBy(reply)); + } let builder = this.base(opts?.returnMetrics, opts?.filters, opts?.groupBy).withHybrid({ query: query, alpha: opts?.alpha, @@ -377,12 +400,25 @@ class AggregateManager implements Aggregate { } return this.doGroupBy(builder); }, - nearImage: async | undefined = undefined>( + nearImage: async >( image: string | Buffer, opts: AggregateGroupByNearOptions ): Promise[]> => { + const [b64, usesGrpc] = await Promise.all([await toBase64FromMedia(image), await this.grpcChecker]); + if (usesGrpc) { + const group = typeof opts.groupBy === 'string' ? { property: opts.groupBy } : opts.groupBy; + return this.grpc() + .then((aggregate) => + aggregate.withNearImage({ + ...Serialize.aggregate.nearImage(b64, opts), + groupBy: Serialize.aggregate.groupBy(group), + limit: group.limit, + }) + ) + .then((reply) => Deserialize.aggregateGroupBy(reply)); + } const builder = this.base(opts?.returnMetrics, opts?.filters, opts?.groupBy).withNearImage({ - image: await toBase64FromMedia(image), + image: b64, certainty: opts?.certainty, distance: opts?.distance, targetVectors: opts?.targetVector ? [opts.targetVector] : undefined, @@ -392,10 +428,22 @@ class AggregateManager implements Aggregate { } return this.doGroupBy(builder); }, - nearObject: | undefined = undefined>( + nearObject: async >( id: string, opts: AggregateGroupByNearOptions ): Promise[]> => { + if (await this.grpcChecker) { + const group = typeof opts.groupBy === 'string' ? { property: opts.groupBy } : opts.groupBy; + return this.grpc() + .then((aggregate) => + aggregate.withNearObject({ + ...Serialize.aggregate.nearObject(id, opts), + groupBy: Serialize.aggregate.groupBy(group), + limit: group.limit, + }) + ) + .then((reply) => Deserialize.aggregateGroupBy(reply)); + } const builder = this.base(opts?.returnMetrics, opts?.filters, opts?.groupBy).withNearObject({ id: id, certainty: opts?.certainty, @@ -407,10 +455,22 @@ class AggregateManager implements Aggregate { } return this.doGroupBy(builder); }, - nearText: | undefined = undefined>( + nearText: async >( query: string | string[], opts: AggregateGroupByNearOptions ): Promise[]> => { + if (await this.grpcChecker) { + const group = typeof opts.groupBy === 'string' ? { property: opts.groupBy } : opts.groupBy; + return this.grpc() + .then((aggregate) => + aggregate.withNearText({ + ...Serialize.aggregate.nearText(query, opts), + groupBy: Serialize.aggregate.groupBy(group), + limit: group.limit, + }) + ) + .then((reply) => Deserialize.aggregateGroupBy(reply)); + } const builder = this.base(opts?.returnMetrics, opts?.filters, opts?.groupBy).withNearText({ concepts: Array.isArray(query) ? query : [query], certainty: opts?.certainty, @@ -422,10 +482,22 @@ class AggregateManager implements Aggregate { } return this.doGroupBy(builder); }, - nearVector: | undefined = undefined>( + nearVector: async >( vector: number[], opts: AggregateGroupByNearOptions ): Promise[]> => { + if (await this.grpcChecker) { + const group = typeof opts.groupBy === 'string' ? { property: opts.groupBy } : opts.groupBy; + return this.grpc() + .then((aggregate) => + aggregate.withNearVector({ + ...Serialize.aggregate.nearVector(vector, opts), + groupBy: Serialize.aggregate.groupBy(group), + limit: group.limit, + }) + ) + .then((reply) => Deserialize.aggregateGroupBy(reply)); + } const builder = this.base(opts?.returnMetrics, opts?.filters, opts?.groupBy).withNearVector({ vector: vector, certainty: opts?.certainty, @@ -437,22 +509,37 @@ class AggregateManager implements Aggregate { } return this.doGroupBy(builder); }, - overAll: | undefined = undefined>( + overAll: async >( opts: AggregateGroupByOptions ): Promise[]> => { + if (await this.grpcChecker) { + const group = typeof opts.groupBy === 'string' ? { property: opts.groupBy } : opts.groupBy; + return this.grpc() + .then((aggregate) => + aggregate.withFetch({ + ...Serialize.aggregate.overAll(opts), + + groupBy: Serialize.aggregate.groupBy(group), + limit: group.limit, + }) + ) + .then((reply) => Deserialize.aggregateGroupBy(reply)); + } const builder = this.base(opts?.returnMetrics, opts?.filters, opts?.groupBy); return this.doGroupBy(builder); }, }; } - query() { + private grpc = () => this.connection.aggregate(this.name, this.consistencyLevel, this.tenant); + + private gql() { return new Aggregator(this.connection); } base(metrics?: PropertiesMetrics, filters?: FilterValue, groupBy?: PropertyOf | GroupByAggregate) { let fields = 'meta { count }'; - let builder = this.query().withClassName(this.name); + let builder = this.gql().withClassName(this.name); if (metrics) { if (Array.isArray(metrics)) { fields += metrics.map((m) => this.metrics(m)).join(' '); @@ -516,10 +603,15 @@ class AggregateManager implements Aggregate { return new AggregateManager(connection, name, dbVersionSupport, consistencyLevel, tenant); } - hybrid>( + async hybrid>( query: string, opts?: AggregateHybridOptions ): Promise> { + if (await this.grpcChecker) { + return this.grpc() + .then((aggregate) => aggregate.withHybrid(Serialize.aggregate.hybrid(query, opts))) + .then((reply) => Deserialize.aggregate(reply)); + } let builder = this.base(opts?.returnMetrics, opts?.filters).withHybrid({ query: query, alpha: opts?.alpha, @@ -538,8 +630,14 @@ class AggregateManager implements Aggregate { image: string | Buffer, opts?: AggregateNearOptions ): Promise> { + const [b64, usesGrpc] = await Promise.all([await toBase64FromMedia(image), await this.grpcChecker]); + if (usesGrpc) { + return this.grpc() + .then((aggregate) => aggregate.withNearImage(Serialize.aggregate.nearImage(b64, opts))) + .then((reply) => Deserialize.aggregate(reply)); + } const builder = this.base(opts?.returnMetrics, opts?.filters).withNearImage({ - image: await toBase64FromMedia(image), + image: b64, certainty: opts?.certainty, distance: opts?.distance, targetVectors: opts?.targetVector ? [opts.targetVector] : undefined, @@ -550,10 +648,15 @@ class AggregateManager implements Aggregate { return this.do(builder); } - nearObject>( + async nearObject>( id: string, opts?: AggregateNearOptions ): Promise> { + if (await this.grpcChecker) { + return this.grpc() + .then((aggregate) => aggregate.withNearObject(Serialize.aggregate.nearObject(id, opts))) + .then((reply) => Deserialize.aggregate(reply)); + } const builder = this.base(opts?.returnMetrics, opts?.filters).withNearObject({ id: id, certainty: opts?.certainty, @@ -566,10 +669,15 @@ class AggregateManager implements Aggregate { return this.do(builder); } - nearText>( + async nearText>( query: string | string[], opts?: AggregateNearOptions ): Promise> { + if (await this.grpcChecker) { + return this.grpc() + .then((aggregate) => aggregate.withNearText(Serialize.aggregate.nearText(query, opts))) + .then((reply) => Deserialize.aggregate(reply)); + } const builder = this.base(opts?.returnMetrics, opts?.filters).withNearText({ concepts: Array.isArray(query) ? query : [query], certainty: opts?.certainty, @@ -582,10 +690,20 @@ class AggregateManager implements Aggregate { return this.do(builder); } - nearVector>( - vector: number[], + async nearVector>( + vector: NearVectorInputType, opts?: AggregateNearOptions ): Promise> { + if (await this.grpcChecker) { + return this.grpc() + .then((aggregate) => aggregate.withNearVector(Serialize.aggregate.nearVector(vector, opts))) + .then((reply) => Deserialize.aggregate(reply)); + } + if (!NearVectorInputGuards.is1DArray(vector)) { + throw new WeaviateInvalidInputError( + 'Vector can only be a 1D array of numbers when using `nearVector` with <1.29 Weaviate versions.' + ); + } const builder = this.base(opts?.returnMetrics, opts?.filters).withNearVector({ vector: vector, certainty: opts?.certainty, @@ -598,9 +716,15 @@ class AggregateManager implements Aggregate { return this.do(builder); } - overAll>(opts?: AggregateOverAllOptions): Promise> { - const builder = this.base(opts?.returnMetrics, opts?.filters); - return this.do(builder); + async overAll>( + opts?: AggregateOverAllOptions + ): Promise> { + if (await this.grpcChecker) { + return this.grpc() + .then((aggregate) => aggregate.withFetch(Serialize.aggregate.overAll(opts))) + .then((reply) => Deserialize.aggregate(reply)); + } + return this.do(this.base(opts?.returnMetrics, opts?.filters)); } do = | undefined = undefined>( diff --git a/src/collections/aggregate/integration.test.ts b/src/collections/aggregate/integration.test.ts index de636f92..f06017c0 100644 --- a/src/collections/aggregate/integration.test.ts +++ b/src/collections/aggregate/integration.test.ts @@ -436,13 +436,13 @@ describe('Testing of collection.aggregate search methods', () => { }); it('should return an aggregation on a hybrid search', async () => { - if (await client.getWeaviateVersion().then((ver) => ver.isLowerThan(1, 25, 0))) { - console.warn('Skipping test as there is a bug with this in 1.24.26 that will not be fixed'); + if (await client.getWeaviateVersion().then((ver) => ver.isLowerThan(1, 26, 0))) { + console.warn('Skipping test max vector distance not supported in 1.25.x'); return; } const result = await collection.aggregate.hybrid('test', { alpha: 0.5, - maxVectorDistance: 0, + maxVectorDistance: 1, queryProperties: ['text'], returnMetrics: collection.metrics.aggregate('text').text(['count']), }); diff --git a/src/collections/data/index.ts b/src/collections/data/index.ts index 033b595c..2f90ab46 100644 --- a/src/collections/data/index.ts +++ b/src/collections/data/index.ts @@ -190,16 +190,18 @@ const data = ( ? (Serialize.restProperties(object.properties, object.references) as T) : undefined, }; + // as any required below because server uses swagger object as interface{} in Go to perform type switching + // actual types are []number and [][]number but unions don't work in go-swagger if (Array.isArray(object.vectors)) { const requiresNamedVectorsInsertFix = await dbVersionSupport.requiresNamedVectorsInsertFix(); if (requiresNamedVectorsInsertFix.supports) { obj.vector = object.vectors; - obj.vectors = { default: object.vectors }; + obj.vectors = { default: object.vectors as any }; } else { obj.vector = object.vectors; } } else if (object.vectors) { - obj.vectors = object.vectors; + obj.vectors = object.vectors as any; } return obj; }; diff --git a/src/collections/deserialize/index.ts b/src/collections/deserialize/index.ts index d01b7b1b..588c2642 100644 --- a/src/collections/deserialize/index.ts +++ b/src/collections/deserialize/index.ts @@ -1,11 +1,32 @@ import { WeaviateDeserializationError } from '../../errors.js'; import { Tenant as TenantREST } from '../../openapi/types.js'; +import { + AggregateReply, + AggregateReply_Aggregations, + AggregateReply_Aggregations_Aggregation, + AggregateReply_Aggregations_Aggregation_Boolean, + AggregateReply_Aggregations_Aggregation_DateMessage, + AggregateReply_Aggregations_Aggregation_Integer, + AggregateReply_Aggregations_Aggregation_Number, + AggregateReply_Aggregations_Aggregation_Text, + AggregateReply_Group_GroupedBy, +} from '../../proto/v1/aggregate.js'; import { BatchObject as BatchObjectGRPC, BatchObjectsReply } from '../../proto/v1/batch.js'; import { BatchDeleteReply } from '../../proto/v1/batch_delete.js'; import { ListValue, Properties as PropertiesGrpc, Value } from '../../proto/v1/properties.js'; import { MetadataResult, PropertiesResult, SearchReply } from '../../proto/v1/search_get.js'; import { TenantActivityStatus, TenantsGetReply } from '../../proto/v1/tenants.js'; import { DbVersionSupport } from '../../utils/dbVersion.js'; +import { + AggregateBoolean, + AggregateDate, + AggregateGroupByResult, + AggregateNumber, + AggregateResult, + AggregateText, + AggregateType, + PropertiesMetrics, +} from '../index.js'; import { referenceFromObjects } from '../references/utils.js'; import { Tenant } from '../tenants/index.js'; import { @@ -36,6 +57,142 @@ export class Deserialize { return new Deserialize(supports125ListValue); } + private static aggregateBoolean( + aggregation: AggregateReply_Aggregations_Aggregation_Boolean + ): AggregateBoolean { + return { + count: aggregation.count, + percentageFalse: aggregation.percentageFalse, + percentageTrue: aggregation.percentageTrue, + totalFalse: aggregation.totalFalse, + totalTrue: aggregation.totalTrue, + }; + } + + private static aggregateDate( + aggregation: AggregateReply_Aggregations_Aggregation_DateMessage + ): AggregateDate { + const parse = (date: string | undefined) => (date !== undefined ? date : undefined); + return { + count: aggregation.count, + maximum: parse(aggregation.maximum), + median: parse(aggregation.median), + minimum: parse(aggregation.minimum), + mode: parse(aggregation.mode), + }; + } + + private static aggregateInt(aggregation: AggregateReply_Aggregations_Aggregation_Integer): AggregateNumber { + return { + count: aggregation.count, + maximum: aggregation.maximum, + mean: aggregation.mean, + median: aggregation.median, + minimum: aggregation.minimum, + mode: aggregation.mode, + sum: aggregation.sum, + }; + } + + private static aggregateNumber( + aggregation: AggregateReply_Aggregations_Aggregation_Number + ): AggregateNumber { + return { + count: aggregation.count, + maximum: aggregation.maximum, + mean: aggregation.mean, + median: aggregation.median, + minimum: aggregation.minimum, + mode: aggregation.mode, + sum: aggregation.sum, + }; + } + + private static aggregateText(aggregation: AggregateReply_Aggregations_Aggregation_Text): AggregateText { + return { + count: aggregation.count, + topOccurrences: aggregation.topOccurences?.items.map((occurrence) => { + return { + occurs: occurrence.occurs, + value: occurrence.value, + }; + }), + }; + } + + private static mapAggregate(aggregation: AggregateReply_Aggregations_Aggregation): AggregateType { + if (aggregation.boolean !== undefined) return Deserialize.aggregateBoolean(aggregation.boolean); + if (aggregation.date !== undefined) return Deserialize.aggregateDate(aggregation.date); + if (aggregation.int !== undefined) return Deserialize.aggregateInt(aggregation.int); + if (aggregation.number !== undefined) return Deserialize.aggregateNumber(aggregation.number); + // if (aggregation.reference !== undefined) return aggregation.reference; + if (aggregation.text !== undefined) return Deserialize.aggregateText(aggregation.text); + throw new WeaviateDeserializationError(`Unknown aggregation type: ${aggregation}`); + } + + private static aggregations(aggregations?: AggregateReply_Aggregations): Record { + return aggregations + ? Object.fromEntries( + aggregations.aggregations.map((aggregation) => [ + aggregation.property, + Deserialize.mapAggregate(aggregation), + ]) + ) + : {}; + } + + public static aggregate>(reply: AggregateReply): AggregateResult { + if (reply.singleResult === undefined) { + throw new WeaviateDeserializationError('No single result in aggregate response'); + } + return { + totalCount: reply.singleResult.objectsCount!, + properties: Deserialize.aggregations(reply.singleResult.aggregations) as AggregateResult< + T, + M + >['properties'], + }; + } + + public static aggregateGroupBy>( + reply: AggregateReply + ): AggregateGroupByResult[] { + if (reply.groupedResults === undefined) + throw new WeaviateDeserializationError('No grouped results in aggregate response'); + + const parse = (groupedBy?: AggregateReply_Group_GroupedBy): AggregateGroupByResult['groupedBy'] => { + if (groupedBy === undefined) + throw new WeaviateDeserializationError('No groupedBy in aggregate response'); + + let value: AggregateGroupByResult['groupedBy']['value']; + if (groupedBy.boolean !== undefined) value = groupedBy.boolean; + else if (groupedBy.booleans !== undefined) value = groupedBy.booleans.values; + else if (groupedBy.geo !== undefined) value = groupedBy.geo; + else if (groupedBy.int !== undefined) value = groupedBy.int; + else if (groupedBy.ints !== undefined) value = groupedBy.ints.values; + else if (groupedBy.number !== undefined) value = groupedBy.number; + else if (groupedBy.numbers !== undefined) value = groupedBy.numbers.values; + else if (groupedBy.text !== undefined) value = groupedBy.text; + else if (groupedBy.texts !== undefined) value = groupedBy.texts.values; + else { + console.warn(`Unknown groupBy type: ${JSON.stringify(groupedBy, null, 2)}`); + value = ''; + } + + return { + prop: groupedBy.path[0], + value, + }; + }; + return reply.groupedResults.groups.map((group) => { + return { + totalCount: group.objectsCount!, + groupedBy: parse(group.groupedBy), + properties: Deserialize.aggregations(group.aggregations) as AggregateResult['properties'], + }; + }); + } + public query(reply: SearchReply): WeaviateReturn { return { objects: reply.results.map((result) => { @@ -66,7 +223,7 @@ export class Deserialize { }; } - public groupBy(reply: SearchReply): GroupByReturn { + public queryGroupBy(reply: SearchReply): GroupByReturn { const objects: GroupByObject[] = []; const groups: Record> = {}; reply.groupByResults.forEach((result) => { diff --git a/src/collections/generate/index.ts b/src/collections/generate/index.ts index 38c1d1f4..3af6fef1 100644 --- a/src/collections/generate/index.ts +++ b/src/collections/generate/index.ts @@ -61,7 +61,9 @@ class GenerateManager implements Generate { reply: SearchReply ) { const deserialize = await Deserialize.use(this.check.dbVersionSupport); - return Serialize.isGroupBy(opts) ? deserialize.generateGroupBy(reply) : deserialize.generate(reply); + return Serialize.search.isGroupBy(opts) + ? deserialize.generateGroupBy(reply) + : deserialize.generate(reply); } public fetchObjects( @@ -72,7 +74,7 @@ class GenerateManager implements Generate { .fetchObjects(opts) .then(({ search }) => search.withFetch({ - ...Serialize.fetchObjects(opts), + ...Serialize.search.fetchObjects(opts), generative: Serialize.generative(generate), }) ) @@ -94,11 +96,8 @@ class GenerateManager implements Generate { .bm25(opts) .then(({ search }) => search.withBm25({ - ...Serialize.bm25({ query, ...opts }), + ...Serialize.search.bm25(query, opts), generative: Serialize.generative(generate), - groupBy: Serialize.isGroupBy>(opts) - ? Serialize.groupBy(opts.groupBy) - : undefined, }) ) .then((reply) => this.parseGroupByReply(opts, reply)); @@ -119,17 +118,16 @@ class GenerateManager implements Generate { .hybridSearch(opts) .then(({ search, supportsTargets, supportsVectorsForTargets, supportsWeightsForTargets }) => search.withHybrid({ - ...Serialize.hybrid({ - query, - supportsTargets, - supportsVectorsForTargets, - supportsWeightsForTargets, - ...opts, - }), + ...Serialize.search.hybrid( + { + query, + supportsTargets, + supportsVectorsForTargets, + supportsWeightsForTargets, + }, + opts + ), generative: Serialize.generative(generate), - groupBy: Serialize.isGroupBy>(opts) - ? Serialize.groupBy(opts.groupBy) - : undefined, }) ) .then((reply) => this.parseGroupByReply(opts, reply)); @@ -155,16 +153,15 @@ class GenerateManager implements Generate { .then(({ search, supportsTargets, supportsWeightsForTargets }) => toBase64FromMedia(image).then((image) => search.withNearImage({ - ...Serialize.nearImage({ - image, - supportsTargets, - supportsWeightsForTargets, - ...(opts ? opts : {}), - }), + ...Serialize.search.nearImage( + { + image, + supportsTargets, + supportsWeightsForTargets, + }, + opts + ), generative: Serialize.generative(generate), - groupBy: Serialize.isGroupBy>(opts) - ? Serialize.groupBy(opts.groupBy) - : undefined, }) ) ) @@ -186,16 +183,15 @@ class GenerateManager implements Generate { .nearSearch(opts) .then(({ search, supportsTargets, supportsWeightsForTargets }) => search.withNearObject({ - ...Serialize.nearObject({ - id, - supportsTargets, - supportsWeightsForTargets, - ...(opts ? opts : {}), - }), + ...Serialize.search.nearObject( + { + id, + supportsTargets, + supportsWeightsForTargets, + }, + opts + ), generative: Serialize.generative(generate), - groupBy: Serialize.isGroupBy>(opts) - ? Serialize.groupBy(opts.groupBy) - : undefined, }) ) .then((reply) => this.parseGroupByReply(opts, reply)); @@ -220,16 +216,15 @@ class GenerateManager implements Generate { .nearSearch(opts) .then(({ search, supportsTargets, supportsWeightsForTargets }) => search.withNearText({ - ...Serialize.nearText({ - query, - supportsTargets, - supportsWeightsForTargets, - ...(opts ? opts : {}), - }), + ...Serialize.search.nearText( + { + query, + supportsTargets, + supportsWeightsForTargets, + }, + opts + ), generative: Serialize.generative(generate), - groupBy: Serialize.isGroupBy>(opts) - ? Serialize.groupBy(opts.groupBy) - : undefined, }) ) .then((reply) => this.parseGroupByReply(opts, reply)); @@ -254,17 +249,16 @@ class GenerateManager implements Generate { .nearVector(vector, opts) .then(({ search, supportsTargets, supportsVectorsForTargets, supportsWeightsForTargets }) => search.withNearVector({ - ...Serialize.nearVector({ - vector, - supportsTargets, - supportsVectorsForTargets, - supportsWeightsForTargets, - ...(opts ? opts : {}), - }), + ...Serialize.search.nearVector( + { + vector, + supportsTargets, + supportsVectorsForTargets, + supportsWeightsForTargets, + }, + opts + ), generative: Serialize.generative(generate), - groupBy: Serialize.isGroupBy>(opts) - ? Serialize.groupBy(opts.groupBy) - : undefined, }) ) .then((reply) => this.parseGroupByReply(opts, reply)); @@ -291,75 +285,53 @@ class GenerateManager implements Generate { return this.check .nearSearch(opts) .then(({ search, supportsTargets, supportsWeightsForTargets }) => { - let reply: Promise; const args = { supportsTargets, supportsWeightsForTargets, - ...(opts ? opts : {}), }; const generative = Serialize.generative(generate); - const groupBy = Serialize.isGroupBy>(opts) - ? Serialize.groupBy(opts.groupBy) - : undefined; + let send: (media: string) => Promise; switch (type) { case 'audio': - reply = toBase64FromMedia(media).then((media) => + send = (media) => search.withNearAudio({ - ...Serialize.nearAudio({ audio: media, ...args }), + ...Serialize.search.nearAudio({ audio: media, ...args }, opts), generative, - groupBy, - }) - ); + }); break; case 'depth': - reply = toBase64FromMedia(media).then((media) => + send = (media) => search.withNearDepth({ - ...Serialize.nearDepth({ depth: media, ...args }), + ...Serialize.search.nearDepth({ depth: media, ...args }, opts), generative, - groupBy, - }) - ); + }); break; case 'image': - reply = toBase64FromMedia(media).then((media) => + send = (media) => search.withNearImage({ - ...Serialize.nearImage({ image: media, ...args }), + ...Serialize.search.nearImage({ image: media, ...args }, opts), generative, - groupBy, - }) - ); + }); break; case 'imu': - reply = toBase64FromMedia(media).then((media) => - search.withNearIMU({ - ...Serialize.nearIMU({ imu: media, ...args }), - generative, - groupBy, - }) - ); + send = (media) => + search.withNearIMU({ ...Serialize.search.nearIMU({ imu: media, ...args }, opts), generative }); break; case 'thermal': - reply = toBase64FromMedia(media).then((media) => + send = (media) => search.withNearThermal({ - ...Serialize.nearThermal({ thermal: media, ...args }), + ...Serialize.search.nearThermal({ thermal: media, ...args }, opts), generative, - groupBy, - }) - ); + }); break; case 'video': - reply = toBase64FromMedia(media).then((media) => - search.withNearVideo({ - ...Serialize.nearVideo({ video: media, ...args }), - generative, - groupBy, - }) - ); + send = (media) => + search.withNearVideo({ ...Serialize.search.nearVideo({ video: media, ...args }), generative }); break; default: throw new WeaviateInvalidInputError(`Invalid media type: ${type}`); } - return reply; + return toBase64FromMedia(media).then(send); }) .then((reply) => this.parseGroupByReply(opts, reply)); } diff --git a/src/collections/query/check.ts b/src/collections/query/check.ts index 63f02b19..291738de 100644 --- a/src/collections/query/check.ts +++ b/src/collections/query/check.ts @@ -50,7 +50,7 @@ export class Check { query: 'Bm25' | 'Hybrid', opts?: SearchOptions | GroupByOptions ) => { - if (!Serialize.isGroupBy(opts)) return; + if (!Serialize.search.isGroupBy(opts)) return; const check = await this.dbVersionSupport.supportsBm25AndHybridGroupByQueries(); if (!check.supports) throw new WeaviateUnsupportedFeatureError(check.message(query)); }; diff --git a/src/collections/query/index.ts b/src/collections/query/index.ts index 5a6c93f2..3be179d3 100644 --- a/src/collections/query/index.ts +++ b/src/collections/query/index.ts @@ -61,13 +61,15 @@ class QueryManager implements Query { reply: SearchReply ) { const deserialize = await Deserialize.use(this.check.dbVersionSupport); - return Serialize.isGroupBy(opts) ? deserialize.groupBy(reply) : deserialize.query(reply); + return Serialize.search.isGroupBy(opts) + ? deserialize.queryGroupBy(reply) + : deserialize.query(reply); } public fetchObjectById(id: string, opts?: FetchObjectByIdOptions): Promise | null> { return this.check .fetchObjectById(opts) - .then(({ search }) => search.withFetch(Serialize.fetchObjectById({ id, ...opts }))) + .then(({ search }) => search.withFetch(Serialize.search.fetchObjectById({ id, ...opts }))) .then((reply) => this.parseReply(reply)) .then((ret) => (ret.objects.length === 1 ? ret.objects[0] : null)); } @@ -75,7 +77,7 @@ class QueryManager implements Query { public fetchObjects(opts?: FetchObjectsOptions): Promise> { return this.check .fetchObjects(opts) - .then(({ search }) => search.withFetch(Serialize.fetchObjects(opts))) + .then(({ search }) => search.withFetch(Serialize.search.fetchObjects(opts))) .then((reply) => this.parseReply(reply)); } @@ -84,14 +86,7 @@ class QueryManager implements Query { public bm25(query: string, opts?: Bm25Options): QueryReturn { return this.check .bm25(opts) - .then(({ search }) => - search.withBm25({ - ...Serialize.bm25({ query, ...opts }), - groupBy: Serialize.isGroupBy>(opts) - ? Serialize.groupBy(opts.groupBy) - : undefined, - }) - ) + .then(({ search }) => search.withBm25(Serialize.search.bm25(query, opts))) .then((reply) => this.parseGroupByReply(opts, reply)); } @@ -101,18 +96,12 @@ class QueryManager implements Query { return this.check .hybridSearch(opts) .then(({ search, supportsTargets, supportsWeightsForTargets, supportsVectorsForTargets }) => - search.withHybrid({ - ...Serialize.hybrid({ - query, - supportsTargets, - supportsVectorsForTargets, - supportsWeightsForTargets, - ...opts, - }), - groupBy: Serialize.isGroupBy>(opts) - ? Serialize.groupBy(opts.groupBy) - : undefined, - }) + search.withHybrid( + Serialize.search.hybrid( + { query, supportsTargets, supportsWeightsForTargets, supportsVectorsForTargets }, + opts + ) + ) ) .then((reply) => this.parseGroupByReply(opts, reply)); } @@ -124,17 +113,16 @@ class QueryManager implements Query { .nearSearch(opts) .then(({ search, supportsTargets, supportsWeightsForTargets }) => { return toBase64FromMedia(image).then((image) => - search.withNearImage({ - ...Serialize.nearImage({ - image, - supportsTargets, - supportsWeightsForTargets, - ...(opts ? opts : {}), - }), - groupBy: Serialize.isGroupBy>(opts) - ? Serialize.groupBy(opts.groupBy) - : undefined, - }) + search.withNearImage( + Serialize.search.nearImage( + { + image, + supportsTargets, + supportsWeightsForTargets, + }, + opts + ) + ) ); }) .then((reply) => this.parseGroupByReply(opts, reply)); @@ -157,44 +145,35 @@ class QueryManager implements Query { const args = { supportsTargets, supportsWeightsForTargets, - ...(opts ? opts : {}), }; - let reply: Promise; + let send: (media: string) => Promise; switch (type) { case 'audio': - reply = toBase64FromMedia(media).then((media) => - search.withNearAudio(Serialize.nearAudio({ audio: media, ...args })) - ); + send = (media) => + search.withNearAudio(Serialize.search.nearAudio({ audio: media, ...args }, opts)); break; case 'depth': - reply = toBase64FromMedia(media).then((media) => - search.withNearDepth(Serialize.nearDepth({ depth: media, ...args })) - ); + send = (media) => + search.withNearDepth(Serialize.search.nearDepth({ depth: media, ...args }, opts)); break; case 'image': - reply = toBase64FromMedia(media).then((media) => - search.withNearImage(Serialize.nearImage({ image: media, ...args })) - ); + send = (media) => + search.withNearImage(Serialize.search.nearImage({ image: media, ...args }, opts)); break; case 'imu': - reply = toBase64FromMedia(media).then((media) => - search.withNearIMU(Serialize.nearIMU({ imu: media, ...args })) - ); + send = (media) => search.withNearIMU(Serialize.search.nearIMU({ imu: media, ...args }, opts)); break; case 'thermal': - reply = toBase64FromMedia(media).then((media) => - search.withNearThermal(Serialize.nearThermal({ thermal: media, ...args })) - ); + send = (media) => + search.withNearThermal(Serialize.search.nearThermal({ thermal: media, ...args }, opts)); break; case 'video': - reply = toBase64FromMedia(media).then((media) => - search.withNearVideo(Serialize.nearVideo({ video: media, ...args })) - ); + send = (media) => search.withNearVideo(Serialize.search.nearVideo({ video: media, ...args })); break; default: throw new WeaviateInvalidInputError(`Invalid media type: ${type}`); } - return reply; + return toBase64FromMedia(media).then(send); }) .then((reply) => this.parseGroupByReply(opts, reply)); } @@ -205,17 +184,16 @@ class QueryManager implements Query { return this.check .nearSearch(opts) .then(({ search, supportsTargets, supportsWeightsForTargets }) => - search.withNearObject({ - ...Serialize.nearObject({ - id, - supportsTargets, - supportsWeightsForTargets, - ...(opts ? opts : {}), - }), - groupBy: Serialize.isGroupBy>(opts) - ? Serialize.groupBy(opts.groupBy) - : undefined, - }) + search.withNearObject( + Serialize.search.nearObject( + { + id, + supportsTargets, + supportsWeightsForTargets, + }, + opts + ) + ) ) .then((reply) => this.parseGroupByReply(opts, reply)); } @@ -226,17 +204,16 @@ class QueryManager implements Query { return this.check .nearSearch(opts) .then(({ search, supportsTargets, supportsWeightsForTargets }) => - search.withNearText({ - ...Serialize.nearText({ - query, - supportsTargets, - supportsWeightsForTargets, - ...(opts ? opts : {}), - }), - groupBy: Serialize.isGroupBy>(opts) - ? Serialize.groupBy(opts.groupBy) - : undefined, - }) + search.withNearText( + Serialize.search.nearText( + { + query, + supportsTargets, + supportsWeightsForTargets, + }, + opts + ) + ) ) .then((reply) => this.parseGroupByReply(opts, reply)); } @@ -247,18 +224,17 @@ class QueryManager implements Query { return this.check .nearVector(vector, opts) .then(({ search, supportsTargets, supportsVectorsForTargets, supportsWeightsForTargets }) => - search.withNearVector({ - ...Serialize.nearVector({ - vector, - supportsTargets, - supportsVectorsForTargets, - supportsWeightsForTargets, - ...(opts ? opts : {}), - }), - groupBy: Serialize.isGroupBy>(opts) - ? Serialize.groupBy(opts.groupBy) - : undefined, - }) + search.withNearVector( + Serialize.search.nearVector( + { + vector, + supportsTargets, + supportsVectorsForTargets, + supportsWeightsForTargets, + }, + opts + ) + ) ) .then((reply) => this.parseGroupByReply(opts, reply)); } diff --git a/src/collections/query/types.ts b/src/collections/query/types.ts index b3954c39..b00fa7c8 100644 --- a/src/collections/query/types.ts +++ b/src/collections/query/types.ts @@ -84,12 +84,14 @@ export type Bm25QueryProperty = { weight: number; }; -/** Base options available in the `query.bm25` method */ -export type BaseBm25Options = SearchOptions & { +export type Bm25SearchOptions = { /** Which properties of the collection to perform the keyword search on. */ queryProperties?: (PrimitiveKeys | Bm25QueryProperty)[]; }; +/** Base options available in the `query.bm25` method */ +export type BaseBm25Options = SearchOptions & Bm25SearchOptions; + /** Options available in the `query.bm25` method when specifying the `groupBy` parameter. */ export type GroupByBm25Options = BaseBm25Options & { /** The group by options to apply to the search. */ @@ -99,8 +101,8 @@ export type GroupByBm25Options = BaseBm25Options & { /** Options available in the `query.bm25` method */ export type Bm25Options = BaseBm25Options | GroupByBm25Options | undefined; -/** Base options available in the `query.hybrid` method */ -export type BaseHybridOptions = SearchOptions & { +/** Options available to the hybrid search type only */ +export type HybridSearchOptions = { /** The weight of the BM25 score. If not specified, the default weight specified by the server is used. */ alpha?: number; /** The type of fusion to apply. If not specified, the default fusion type specified by the server is used. */ @@ -115,6 +117,9 @@ export type BaseHybridOptions = SearchOptions & { vector?: NearVectorInputType | HybridNearTextSubSearch | HybridNearVectorSubSearch; }; +/** Base options available in the `query.hybrid` method */ +export type BaseHybridOptions = SearchOptions & HybridSearchOptions; + export type HybridSubSearchBase = { certainty?: number; distance?: number; @@ -139,8 +144,7 @@ export type GroupByHybridOptions = BaseHybridOptions & { /** Options available in the `query.hybrid` method */ export type HybridOptions = BaseHybridOptions | GroupByHybridOptions | undefined; -/** Base options for the near search queries. */ -export type BaseNearOptions = SearchOptions & { +export type NearSearchOptions = { /** The minimum similarity score to return. Incompatible with the `distance` param. */ certainty?: number; /** The maximum distance to search. Incompatible with the `certainty` param. */ @@ -149,6 +153,9 @@ export type BaseNearOptions = SearchOptions & { targetVector?: TargetVectorInputType; }; +/** Base options for the near search queries. */ +export type BaseNearOptions = SearchOptions & NearSearchOptions; + /** Options available in the near search queries when specifying the `groupBy` parameter. */ export type GroupByNearOptions = BaseNearOptions & { /** The group by options to apply to the search. */ diff --git a/src/collections/serialize/index.ts b/src/collections/serialize/index.ts index b10d40f5..747bf00a 100644 --- a/src/collections/serialize/index.ts +++ b/src/collections/serialize/index.ts @@ -1,19 +1,10 @@ import { v4 as uuidv4 } from 'uuid'; import { WhereFilter } from '../../openapi/types.js'; -import { - BatchObject as BatchObjectGRPC, - BatchObject_MultiTargetRefProps, - BatchObject_Properties, - BatchObject_SingleTargetRefProps, -} from '../../proto/v1/batch.js'; -import { GenerativeSearch } from '../../proto/v1/generative.js'; import { BM25, CombinationMethod, - GroupBy, Hybrid, Hybrid_FusionType, - MetadataRequest, NearAudioSearch, NearDepthSearch, NearIMUSearch, @@ -24,13 +15,24 @@ import { NearThermalSearch, NearVector, NearVideoSearch, + Targets, + VectorForTarget, + WeightsForTarget, +} from '../../proto/v1/base_search.js'; +import { + BatchObject as BatchObjectGRPC, + BatchObject_MultiTargetRefProps, + BatchObject_Properties, + BatchObject_SingleTargetRefProps, +} from '../../proto/v1/batch.js'; +import { GenerativeSearch } from '../../proto/v1/generative.js'; +import { + GroupBy, + MetadataRequest, ObjectPropertiesRequest, PropertiesRequest, Rerank, SortBy as SortByGrpc, - Targets, - VectorForTarget, - WeightsForTarget, } from '../../proto/v1/search_get.js'; import { @@ -38,6 +40,14 @@ import { WeaviateSerializationError, WeaviateUnsupportedFeatureError, } from '../../errors.js'; +import { + AggregateFetchArgs, + AggregateHybridArgs, + AggregateNearImageArgs, + AggregateNearObjectArgs, + AggregateNearTextArgs, + AggregateNearVectorArgs, +} from '../../grpc/aggregator.js'; import { BaseSearchArgs, SearchBm25Args, @@ -53,6 +63,15 @@ import { SearchNearVectorArgs, SearchNearVideoArgs, } from '../../grpc/searcher.js'; +import { + AggregateRequest_Aggregation, + AggregateRequest_Aggregation_Boolean, + AggregateRequest_Aggregation_DateMessage, + AggregateRequest_Aggregation_Integer, + AggregateRequest_Aggregation_Number, + AggregateRequest_Aggregation_Text, + AggregateRequest_GroupBy, +} from '../../proto/v1/aggregate.js'; import { BooleanArrayProperties, FilterTarget, @@ -74,17 +93,30 @@ import { PrimitiveFilterValueType, PrimitiveListFilterValueType, } from '../filters/types.js'; -import { MultiTargetVectorJoin, PrimitiveKeys } from '../index.js'; +import { + AggregateBaseOptions, + AggregateHybridOptions, + AggregateNearOptions, + GroupByAggregate, + MultiTargetVectorJoin, + PrimitiveKeys, + PropertiesMetrics, +} from '../index.js'; import { BaseHybridOptions, BaseNearOptions, Bm25Options, Bm25QueryProperty, + Bm25SearchOptions, FetchObjectByIdOptions, FetchObjectsOptions, + GroupByBm25Options, + GroupByHybridOptions, + GroupByNearOptions, HybridNearTextSubSearch, HybridNearVectorSubSearch, HybridOptions, + HybridSearchOptions, NearOptions, NearTextOptions, NearVectorInputType, @@ -322,71 +354,476 @@ export class MetadataGuards { }; } -export class Serialize { - public static isNamedVectors = (opts?: BaseNearOptions): boolean => { - return Array.isArray(opts?.includeVector) || opts?.targetVector !== undefined; +class Aggregate { + private static aggregations = (returnMetrics?: PropertiesMetrics): AggregateRequest_Aggregation[] => { + if (returnMetrics === undefined) { + return []; + } + if (!Array.isArray(returnMetrics)) { + returnMetrics = [returnMetrics]; + } + return returnMetrics.map((metric) => + AggregateRequest_Aggregation.fromPartial({ + property: metric.propertyName, + boolean: + metric.kind === 'boolean' ? AggregateRequest_Aggregation_Boolean.fromPartial(metric) : undefined, + date: + metric.kind === 'date' ? AggregateRequest_Aggregation_DateMessage.fromPartial(metric) : undefined, + int: metric.kind === 'integer' ? AggregateRequest_Aggregation_Integer.fromPartial(metric) : undefined, + number: + metric.kind === 'number' ? AggregateRequest_Aggregation_Number.fromPartial(metric) : undefined, + text: + metric.kind === 'text' + ? AggregateRequest_Aggregation_Text.fromPartial({ + count: metric.count, + topOccurencesLimit: metric.minOccurrences, + topOccurences: metric.topOccurrences != undefined, + }) + : undefined, + }) + ); }; - public static isMultiTarget = (opts?: BaseNearOptions): boolean => { - return opts?.targetVector !== undefined && !TargetVectorInputGuards.isSingle(opts.targetVector); + private static common = (opts?: AggregateBaseOptions>) => { + return { + filters: opts?.filters ? Serialize.filtersGRPC(opts.filters) : undefined, + aggregations: Aggregate.aggregations(opts?.returnMetrics), + }; }; - public static isMultiWeightPerTarget = (opts?: BaseNearOptions): boolean => { - return ( - opts?.targetVector !== undefined && - TargetVectorInputGuards.isMultiJoin(opts.targetVector) && - opts.targetVector.weights !== undefined && - Object.values(opts.targetVector.weights).some(ArrayInputGuards.is1DArray) - ); + public static groupBy = (groupBy?: GroupByAggregate): AggregateRequest_GroupBy => { + return AggregateRequest_GroupBy.fromPartial({ + property: groupBy?.property, + }); }; - public static isMultiVector = (vec?: NearVectorInputType): boolean => { - return ( - vec !== undefined && - !Array.isArray(vec) && - Object.values(vec).some(ArrayInputGuards.is1DArray || ArrayInputGuards.is2DArray) - ); + public static hybrid = ( + query: string, + opts?: AggregateHybridOptions> + ): AggregateHybridArgs => { + return { + ...Aggregate.common(opts), + objectLimit: opts?.objectLimit, + hybrid: Serialize.hybridSearch({ + query: query, + supportsTargets: true, + supportsVectorsForTargets: true, + supportsWeightsForTargets: true, + ...opts, + }), + }; }; - public static isMultiVectorPerTarget = (vec?: NearVectorInputType): boolean => { - return vec !== undefined && !Array.isArray(vec) && Object.values(vec).some(ArrayInputGuards.is2DArray); + public static nearImage = ( + image: string, + opts?: AggregateNearOptions> + ): AggregateNearImageArgs => { + return { + ...Aggregate.common(opts), + objectLimit: opts?.objectLimit, + nearImage: Serialize.nearImageSearch({ + image, + supportsTargets: true, + supportsWeightsForTargets: true, + ...opts, + }), + }; + }; + + public static nearObject = ( + id: string, + opts?: AggregateNearOptions> + ): AggregateNearObjectArgs => { + return { + ...Aggregate.common(opts), + objectLimit: opts?.objectLimit, + nearObject: Serialize.nearObjectSearch({ + id, + supportsTargets: true, + supportsWeightsForTargets: true, + ...opts, + }), + }; + }; + + public static nearText = ( + query: string | string[], + opts?: AggregateNearOptions> + ): AggregateNearTextArgs => { + return { + ...Aggregate.common(opts), + objectLimit: opts?.objectLimit, + nearText: Serialize.nearTextSearch({ + query, + supportsTargets: true, + supportsWeightsForTargets: true, + ...opts, + }), + }; + }; + + public static nearVector = ( + vector: NearVectorInputType, + opts?: AggregateNearOptions> + ): AggregateNearVectorArgs => { + return { + ...Aggregate.common(opts), + objectLimit: opts?.objectLimit, + nearVector: Serialize.nearVectorSearch({ + vector, + supportsTargets: true, + supportsVectorsForTargets: true, + supportsWeightsForTargets: true, + ...opts, + }), + }; + }; + + public static overAll = (opts?: AggregateBaseOptions>): AggregateFetchArgs => + Aggregate.common(opts); +} + +class Search { + private static queryProperties = ( + properties?: QueryProperty[], + references?: QueryReference[] + ): PropertiesRequest => { + const nonRefProperties = properties?.filter((property) => typeof property === 'string') as + | string[] + | undefined; + const refProperties = references; + const objectProperties = properties?.filter((property) => typeof property === 'object') as + | QueryNested[] + | undefined; + + const resolveObjectProperty = (property: QueryNested): ObjectPropertiesRequest => { + const objProps = property.properties.filter((property) => typeof property !== 'string') as unknown; // cannot get types to work currently :( + return { + propName: property.name, + primitiveProperties: property.properties.filter( + (property) => typeof property === 'string' + ) as string[], + objectProperties: (objProps as QueryNested[]).map(resolveObjectProperty), + }; + }; + + return { + nonRefProperties: nonRefProperties === undefined ? [] : nonRefProperties, + returnAllNonrefProperties: nonRefProperties === undefined, + refProperties: refProperties + ? refProperties.map((property) => { + return { + referenceProperty: property.linkOn, + properties: Search.queryProperties(property.returnProperties as any), + metadata: Search.metadata(property.includeVector, property.returnMetadata), + targetCollection: property.targetCollection ? property.targetCollection : '', + }; + }) + : [], + objectProperties: objectProperties + ? objectProperties.map((property) => { + const objProps = property.properties.filter( + (property) => typeof property !== 'string' + ) as unknown; // cannot get types to work currently :( + return { + propName: property.name, + primitiveProperties: property.properties.filter( + (property) => typeof property === 'string' + ) as string[], + objectProperties: (objProps as QueryNested[]).map(resolveObjectProperty), + }; + }) + : [], + }; + }; + + private static metadata = ( + includeVector?: boolean | string[], + metadata?: QueryMetadata + ): MetadataRequest => { + const out: any = { + uuid: true, + vector: typeof includeVector === 'boolean' ? includeVector : false, + vectors: Array.isArray(includeVector) ? includeVector : [], + }; + if (MetadataGuards.isAll(metadata)) { + return { + ...out, + creationTimeUnix: true, + lastUpdateTimeUnix: true, + distance: true, + certainty: true, + score: true, + explainScore: true, + isConsistent: true, + }; + } + metadata?.forEach((key) => { + let weaviateKey: string; + if (key === 'creationTime') { + weaviateKey = 'creationTimeUnix'; + } else if (key === 'updateTime') { + weaviateKey = 'lastUpdateTimeUnix'; + } else { + weaviateKey = key; + } + out[weaviateKey] = true; + }); + return MetadataRequest.fromPartial(out); + }; + + private static sortBy = (sort: SortBy[]): SortByGrpc[] => { + return sort.map((sort) => { + return { + ascending: !!sort.ascending, + path: [sort.property], + }; + }); + }; + + private static rerank = (rerank: RerankOptions): Rerank => { + return Rerank.fromPartial({ + property: rerank.property as string, + query: rerank.query, + }); + }; + + public static groupBy = (groupBy?: GroupByOptions): GroupBy => { + return GroupBy.fromPartial({ + path: groupBy?.property ? [groupBy.property as string] : undefined, + numberOfGroups: groupBy?.numberOfGroups, + objectsPerGroup: groupBy?.objectsPerGroup, + }); + }; + + public static isGroupBy = (args: any): args is T => { + if (args === undefined) return false; + return args.groupBy !== undefined; }; private static common = (args?: SearchOptions): BaseSearchArgs => { const out: BaseSearchArgs = { + autocut: args?.autoLimit, limit: args?.limit, offset: args?.offset, filters: args?.filters ? Serialize.filtersGRPC(args.filters) : undefined, properties: args?.returnProperties || args?.returnReferences - ? Serialize.queryProperties(args.returnProperties, args.returnReferences) + ? Search.queryProperties(args.returnProperties, args.returnReferences) : undefined, - metadata: Serialize.metadata(args?.includeVector, args?.returnMetadata), + metadata: Search.metadata(args?.includeVector, args?.returnMetadata), }; if (args?.rerank) { - out.rerank = Serialize.rerank(args.rerank); + out.rerank = Search.rerank(args.rerank); } return out; }; + public static bm25 = (query: string, opts?: Bm25Options): SearchBm25Args => { + return { + ...Search.common(opts), + bm25Search: Serialize.bm25Search({ query, ...opts }), + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + }; + }; + public static fetchObjects = (args?: FetchObjectsOptions): SearchFetchArgs => { return { - ...Serialize.common(args), + ...Search.common(args), after: args?.after, - sortBy: args?.sort ? Serialize.sortBy(args.sort.sorts) : undefined, + sortBy: args?.sort ? Search.sortBy(args.sort.sorts) : undefined, + }; + }; + + public static fetchObjectById = (args: { id: string } & FetchObjectByIdOptions): SearchFetchArgs => { + return Search.common({ + filters: new FilterId().equal(args.id), + includeVector: args.includeVector, + returnMetadata: ['creationTime', 'updateTime', 'isConsistent'], + returnProperties: args.returnProperties, + returnReferences: args.returnReferences, + }); + }; + + public static hybrid = ( + args: { + query: string; + supportsTargets: boolean; + supportsVectorsForTargets: boolean; + supportsWeightsForTargets: boolean; + }, + opts?: HybridOptions + ): SearchHybridArgs => { + return { + ...Search.common(opts), + hybridSearch: Serialize.hybridSearch({ ...args, ...opts }), + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + }; + }; + + public static nearAudio = ( + args: { + audio: string; + supportsTargets: boolean; + supportsWeightsForTargets: boolean; + }, + opts?: NearOptions + ): SearchNearAudioArgs => { + return { + ...Search.common(opts), + nearAudio: Serialize.nearAudioSearch({ ...args, ...opts }), + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + }; + }; + + public static nearDepth = ( + args: { + depth: string; + supportsTargets: boolean; + supportsWeightsForTargets: boolean; + }, + opts?: NearOptions + ): SearchNearDepthArgs => { + return { + ...Search.common(opts), + nearDepth: Serialize.nearDepthSearch({ ...args, ...opts }), + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + }; + }; + + public static nearImage = ( + args: { + image: string; + supportsTargets: boolean; + supportsWeightsForTargets: boolean; + }, + opts?: NearOptions + ): SearchNearImageArgs => { + return { + ...Search.common(opts), + nearImage: Serialize.nearImageSearch({ ...args, ...opts }), + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + }; + }; + + public static nearIMU = ( + args: { + imu: string; + supportsTargets: boolean; + supportsWeightsForTargets: boolean; + }, + opts?: NearOptions + ): SearchNearIMUArgs => { + return { + ...Search.common(opts), + nearIMU: Serialize.nearIMUSearch({ ...args, ...opts }), + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + }; + }; + + public static nearObject = ( + args: { id: string; supportsTargets: boolean; supportsWeightsForTargets: boolean }, + opts?: NearOptions + ): SearchNearObjectArgs => { + return { + ...Search.common(opts), + nearObject: Serialize.nearObjectSearch({ ...args, ...opts }), + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + }; + }; + + public static nearText = ( + args: { + query: string | string[]; + supportsTargets: boolean; + supportsWeightsForTargets: boolean; + }, + opts?: NearTextOptions + ): SearchNearTextArgs => { + return { + ...Search.common(opts), + nearText: Serialize.nearTextSearch({ ...args, ...opts }), + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + }; + }; + + public static nearThermal = ( + args: { thermal: string; supportsTargets: boolean; supportsWeightsForTargets: boolean }, + opts?: NearOptions + ): SearchNearThermalArgs => { + return { + ...Search.common(opts), + nearThermal: Serialize.nearThermalSearch({ ...args, ...opts }), + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + }; + }; + + public static nearVector = ( + args: { + vector: NearVectorInputType; + supportsTargets: boolean; + supportsVectorsForTargets: boolean; + supportsWeightsForTargets: boolean; + }, + opts?: NearOptions + ): SearchNearVectorArgs => { + return { + ...Search.common(opts), + nearVector: Serialize.nearVectorSearch({ ...args, ...opts }), + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, + }; + }; + public static nearVideo = ( + args: { video: string; supportsTargets: boolean; supportsWeightsForTargets: boolean }, + opts?: NearOptions + ): SearchNearVideoArgs => { + return { + ...Search.common(opts), + nearVideo: Serialize.nearVideoSearch({ ...args, ...opts }), + groupBy: Search.isGroupBy>(opts) ? Search.groupBy(opts.groupBy) : undefined, }; }; +} + +export class Serialize { + static aggregate = Aggregate; + static search = Search; + + public static isNamedVectors = (opts?: BaseNearOptions): boolean => { + return Array.isArray(opts?.includeVector) || opts?.targetVector !== undefined; + }; + + public static isMultiTarget = (opts?: BaseNearOptions): boolean => { + return opts?.targetVector !== undefined && !TargetVectorInputGuards.isSingle(opts.targetVector); + }; + + public static isMultiWeightPerTarget = (opts?: BaseNearOptions): boolean => { + return ( + opts?.targetVector !== undefined && + TargetVectorInputGuards.isMultiJoin(opts.targetVector) && + opts.targetVector.weights !== undefined && + Object.values(opts.targetVector.weights).some(ArrayInputGuards.is1DArray) + ); + }; + + public static isMultiVector = (vec?: NearVectorInputType): boolean => { + return ( + vec !== undefined && + !Array.isArray(vec) && + Object.values(vec).some(ArrayInputGuards.is1DArray || ArrayInputGuards.is2DArray) + ); + }; - public static fetchObjectById = (args: { id: string } & FetchObjectByIdOptions): SearchFetchArgs => { - return { - ...Serialize.common({ - filters: new FilterId().equal(args.id), - includeVector: args.includeVector, - returnMetadata: ['creationTime', 'updateTime', 'isConsistent'], - returnProperties: args.returnProperties, - returnReferences: args.returnReferences, - }), - }; + public static isMultiVectorPerTarget = (vec?: NearVectorInputType): boolean => { + return vec !== undefined && !Array.isArray(vec) && Object.values(vec).some(ArrayInputGuards.is2DArray); + }; + + public static generative = (generative?: GenerateOptions): GenerativeSearch => { + return GenerativeSearch.fromPartial({ + singleResponsePrompt: generative?.singlePrompt, + groupedResponseTask: generative?.groupedTask, + groupedProperties: generative?.groupedProperties as string[], + }); }; private static bm25QueryProperties = ( @@ -401,15 +838,11 @@ export class Serialize { }); }; - public static bm25 = (args: { query: string } & Bm25Options): SearchBm25Args => { - return { - ...Serialize.common(args), - bm25Search: BM25.fromPartial({ - query: args.query, - properties: this.bm25QueryProperties(args.queryProperties), - }), - autocut: args.autoLimit, - }; + public static bm25Search = (args: { query: string } & Bm25SearchOptions): BM25 => { + return BM25.fromPartial({ + query: args.query, + properties: this.bm25QueryProperties(args.queryProperties), + }); }; public static isHybridVectorSearch = ( @@ -493,14 +926,14 @@ export class Serialize { } }; - public static hybrid = ( + public static hybridSearch = ( args: { query: string; supportsTargets: boolean; supportsVectorsForTargets: boolean; supportsWeightsForTargets: boolean; - } & HybridOptions - ): SearchHybridArgs => { + } & HybridSearchOptions + ): Hybrid => { const fusionType = (fusionType?: string): Hybrid_FusionType => { switch (fusionType) { case 'Ranked': @@ -512,110 +945,86 @@ export class Serialize { } }; const { targets, targetVectors, vectorBytes, nearText, nearVector } = Serialize.hybridVector(args); - return { - ...Serialize.common(args), - hybridSearch: Hybrid.fromPartial({ - query: args.query, - alpha: args.alpha ? args.alpha : 0.5, - properties: this.bm25QueryProperties(args.queryProperties), - vectorBytes: vectorBytes, - vectorDistance: args.maxVectorDistance, - fusionType: fusionType(args.fusionType), - targetVectors, - targets, - nearText, - nearVector, - }), - autocut: args.autoLimit, - }; + return Hybrid.fromPartial({ + query: args.query, + alpha: args.alpha ? args.alpha : 0.5, + properties: this.bm25QueryProperties(args.queryProperties), + vectorBytes: vectorBytes, + vectorDistance: args.maxVectorDistance, + fusionType: fusionType(args.fusionType), + targetVectors, + targets, + nearText, + nearVector, + }); }; - public static nearAudio = ( + public static nearAudioSearch = ( args: { audio: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions - ): SearchNearAudioArgs => { + ): NearAudioSearch => { const { targets, targetVectors } = Serialize.targetVector(args); - return { - ...Serialize.common(args), - nearAudio: NearAudioSearch.fromPartial({ - audio: args.audio, - certainty: args.certainty, - distance: args.distance, - targetVectors, - targets, - }), - autocut: args.autoLimit, - }; + return NearAudioSearch.fromPartial({ + audio: args.audio, + certainty: args.certainty, + distance: args.distance, + targetVectors, + targets, + }); }; - public static nearDepth = ( + public static nearDepthSearch = ( args: { depth: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions - ): SearchNearDepthArgs => { + ): NearDepthSearch => { const { targets, targetVectors } = Serialize.targetVector(args); - return { - ...Serialize.common(args), - nearDepth: NearDepthSearch.fromPartial({ - depth: args.depth, - certainty: args.certainty, - distance: args.distance, - targetVectors, - targets, - }), - autocut: args.autoLimit, - }; + return NearDepthSearch.fromPartial({ + depth: args.depth, + certainty: args.certainty, + distance: args.distance, + targetVectors, + targets, + }); }; - public static nearImage = ( + public static nearImageSearch = ( args: { image: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions - ): SearchNearImageArgs => { + ): NearImageSearch => { const { targets, targetVectors } = Serialize.targetVector(args); - return { - ...Serialize.common(args), - nearImage: NearImageSearch.fromPartial({ - image: args.image, - certainty: args.certainty, - distance: args.distance, - targetVectors, - targets, - }), - autocut: args.autoLimit, - }; + return NearImageSearch.fromPartial({ + image: args.image, + certainty: args.certainty, + distance: args.distance, + targetVectors, + targets, + }); }; - public static nearIMU = ( + public static nearIMUSearch = ( args: { imu: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions - ): SearchNearIMUArgs => { + ): NearIMUSearch => { const { targets, targetVectors } = Serialize.targetVector(args); - return { - ...Serialize.common(args), - nearIMU: NearIMUSearch.fromPartial({ - imu: args.imu, - certainty: args.certainty, - distance: args.distance, - targetVectors, - targets, - }), - autocut: args.autoLimit, - }; + return NearIMUSearch.fromPartial({ + imu: args.imu, + certainty: args.certainty, + distance: args.distance, + targetVectors, + targets, + }); }; - public static nearObject = ( + public static nearObjectSearch = ( args: { id: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions - ): SearchNearObjectArgs => { + ): NearObject => { const { targets, targetVectors } = Serialize.targetVector(args); - return { - ...Serialize.common(args), - nearObject: NearObject.fromPartial({ - id: args.id, - certainty: args.certainty, - distance: args.distance, - targetVectors, - targets, - }), - autocut: args.autoLimit, - }; + return NearObject.fromPartial({ + id: args.id, + certainty: args.certainty, + distance: args.distance, + targetVectors, + targets, + }); }; - private static nearTextSearch = (args: { + public static nearTextSearch = (args: { query: string | string[]; supportsTargets: boolean; supportsWeightsForTargets: boolean; @@ -649,42 +1058,24 @@ export class Serialize { }); }; - public static nearText = ( - args: { - query: string | string[]; - supportsTargets: boolean; - supportsWeightsForTargets: boolean; - } & NearTextOptions - ): SearchNearTextArgs => { - return { - ...Serialize.common(args), - nearText: this.nearTextSearch(args), - autocut: args.autoLimit, - }; - }; - - public static nearThermal = ( + public static nearThermalSearch = ( args: { thermal: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions - ): SearchNearThermalArgs => { + ): NearThermalSearch => { const { targets, targetVectors } = Serialize.targetVector(args); - return { - ...Serialize.common(args), - nearThermal: NearThermalSearch.fromPartial({ - thermal: args.thermal, - certainty: args.certainty, - distance: args.distance, - targetVectors, - targets, - }), - autocut: args.autoLimit, - }; + return NearThermalSearch.fromPartial({ + thermal: args.thermal, + certainty: args.certainty, + distance: args.distance, + targetVectors, + targets, + }); }; private static vectorToBytes = (vector: number[]): Uint8Array => { return new Uint8Array(new Float32Array(vector).buffer); }; - private static nearVectorSearch = (args: { + public static nearVectorSearch = (args: { vector: NearVectorInputType; supportsTargets: boolean; supportsVectorsForTargets: boolean; @@ -692,7 +1083,7 @@ export class Serialize { certainty?: number; distance?: number; targetVector?: TargetVectorInputType; - }) => { + }): NearVector => { const { targetVectors, targets, vectorBytes, vectorPerTarget, vectorForTargets } = Serialize.vectors({ ...args, argumentName: 'nearVector', @@ -773,8 +1164,10 @@ export class Serialize { }) .reduce((acc, { target, vector }) => { return ArrayInputGuards.is2DArray(vector) - ? acc.concat(vector.map((v) => ({ name: target, vectorBytes: Serialize.vectorToBytes(v) }))) - : acc.concat([{ name: target, vectorBytes: Serialize.vectorToBytes(vector) }]); + ? acc.concat( + vector.map((v) => ({ name: target, vectorBytes: Serialize.vectorToBytes(v), vectors: [] })) + ) + : acc.concat([{ name: target, vectorBytes: Serialize.vectorToBytes(vector), vectors: [] }]); }, [] as VectorForTarget[]); return args.targetVector !== undefined ? { @@ -904,36 +1297,17 @@ export class Serialize { } }; - public static nearVector = ( - args: { - vector: NearVectorInputType; - supportsTargets: boolean; - supportsVectorsForTargets: boolean; - supportsWeightsForTargets: boolean; - } & NearOptions - ): SearchNearVectorArgs => { - return { - ...Serialize.common(args), - nearVector: Serialize.nearVectorSearch(args), - autocut: args.autoLimit, - }; - }; - - public static nearVideo = ( + public static nearVideoSearch = ( args: { video: string; supportsTargets: boolean; supportsWeightsForTargets: boolean } & NearOptions - ): SearchNearVideoArgs => { + ): NearVideoSearch => { const { targets, targetVectors } = Serialize.targetVector(args); - return { - ...Serialize.common(args), - nearVideo: NearVideoSearch.fromPartial({ - video: args.video, - certainty: args.certainty, - distance: args.distance, - targetVectors, - targets, - }), - autocut: args.autoLimit, - }; + return NearVideoSearch.fromPartial({ + video: args.video, + certainty: args.certainty, + distance: args.distance, + targetVectors, + targets, + }); }; public static filtersGRPC = (filters: FilterValue): FiltersGRPC => { @@ -1129,131 +1503,6 @@ export class Serialize { } }; - private static queryProperties = ( - properties?: QueryProperty[], - references?: QueryReference[] - ): PropertiesRequest => { - const nonRefProperties = properties?.filter((property) => typeof property === 'string') as - | string[] - | undefined; - const refProperties = references; - const objectProperties = properties?.filter((property) => typeof property === 'object') as - | QueryNested[] - | undefined; - - const resolveObjectProperty = (property: QueryNested): ObjectPropertiesRequest => { - const objProps = property.properties.filter((property) => typeof property !== 'string') as unknown; // cannot get types to work currently :( - return { - propName: property.name, - primitiveProperties: property.properties.filter( - (property) => typeof property === 'string' - ) as string[], - objectProperties: (objProps as QueryNested[]).map(resolveObjectProperty), - }; - }; - - return { - nonRefProperties: nonRefProperties === undefined ? [] : nonRefProperties, - returnAllNonrefProperties: nonRefProperties === undefined, - refProperties: refProperties - ? refProperties.map((property) => { - return { - referenceProperty: property.linkOn, - properties: Serialize.queryProperties(property.returnProperties as any), - metadata: Serialize.metadata(property.includeVector, property.returnMetadata), - targetCollection: property.targetCollection ? property.targetCollection : '', - }; - }) - : [], - objectProperties: objectProperties - ? objectProperties.map((property) => { - const objProps = property.properties.filter( - (property) => typeof property !== 'string' - ) as unknown; // cannot get types to work currently :( - return { - propName: property.name, - primitiveProperties: property.properties.filter( - (property) => typeof property === 'string' - ) as string[], - objectProperties: (objProps as QueryNested[]).map(resolveObjectProperty), - }; - }) - : [], - }; - }; - - private static metadata = ( - includeVector?: boolean | string[], - metadata?: QueryMetadata - ): MetadataRequest => { - const out: any = { - uuid: true, - vector: typeof includeVector === 'boolean' ? includeVector : false, - vectors: Array.isArray(includeVector) ? includeVector : [], - }; - if (MetadataGuards.isAll(metadata)) { - return { - ...out, - creationTimeUnix: true, - lastUpdateTimeUnix: true, - distance: true, - certainty: true, - score: true, - explainScore: true, - isConsistent: true, - }; - } - metadata?.forEach((key) => { - let weaviateKey: string; - if (key === 'creationTime') { - weaviateKey = 'creationTimeUnix'; - } else if (key === 'updateTime') { - weaviateKey = 'lastUpdateTimeUnix'; - } else { - weaviateKey = key; - } - out[weaviateKey] = true; - }); - return MetadataRequest.fromPartial(out); - }; - - private static sortBy = (sort: SortBy[]): SortByGrpc[] => { - return sort.map((sort) => { - return { - ascending: !!sort.ascending, - path: [sort.property], - }; - }); - }; - - public static rerank = (rerank: RerankOptions): Rerank => { - return Rerank.fromPartial({ - property: rerank.property as string, - query: rerank.query, - }); - }; - - public static generative = (generative?: GenerateOptions): GenerativeSearch => { - return GenerativeSearch.fromPartial({ - singleResponsePrompt: generative?.singlePrompt, - groupedResponseTask: generative?.groupedTask, - groupedProperties: generative?.groupedProperties as string[], - }); - }; - - public static groupBy = (groupBy?: GroupByOptions): GroupBy => { - return GroupBy.fromPartial({ - path: groupBy?.property ? [groupBy.property as string] : undefined, - numberOfGroups: groupBy?.numberOfGroups, - objectsPerGroup: groupBy?.objectsPerGroup, - }); - }; - - public static isGroupBy = (args: any): args is T => { - if (args === undefined) return false; - return args.groupBy !== undefined; - }; - public static restProperties = ( properties: Record, references?: Record> diff --git a/src/collections/serialize/unit.test.ts b/src/collections/serialize/unit.test.ts index 2b77505e..721d1e46 100644 --- a/src/collections/serialize/unit.test.ts +++ b/src/collections/serialize/unit.test.ts @@ -13,14 +13,11 @@ import { SearchNearVideoArgs, } from '../../grpc/searcher.js'; import { Filters, Filters_Operator } from '../../proto/v1/base.js'; -import { GenerativeSearch } from '../../proto/v1/generative.js'; import { BM25, CombinationMethod, - GroupBy, Hybrid, Hybrid_FusionType, - MetadataRequest, NearAudioSearch, NearDepthSearch, NearIMUSearch, @@ -31,9 +28,10 @@ import { NearThermalSearch, NearVector, NearVideoSearch, - PropertiesRequest, Targets, -} from '../../proto/v1/search_get.js'; +} from '../../proto/v1/base_search.js'; +import { GenerativeSearch } from '../../proto/v1/generative.js'; +import { GroupBy, MetadataRequest, PropertiesRequest } from '../../proto/v1/search_get.js'; import { Filters as FiltersFactory } from '../filters/classes.js'; import filter from '../filters/index.js'; import { TargetVectorInputType } from '../query/types.js'; @@ -45,7 +43,7 @@ import { DataGuards, Serialize } from './index.js'; describe('Unit testing of Serialize', () => { it('should parse args for fetchObjects', () => { - const args = Serialize.fetchObjects({ + const args = Serialize.search.fetchObjects({ limit: 1, offset: 0, after: 'one', @@ -95,7 +93,7 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for fetchObjectById', () => { - const args = Serialize.fetchObjectById({ + const args = Serialize.search.fetchObjectById({ id: '1', includeVector: ['title'], returnProperties: ['name'], @@ -131,8 +129,7 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for bm25', () => { - const args = Serialize.bm25({ - query: 'test', + const args = Serialize.search.bm25('test', { queryProperties: ['name'], autoLimit: 1, }); @@ -147,18 +144,22 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for simple hybrid', () => { - const args = Serialize.hybrid({ - query: 'test', - queryProperties: ['name'], - alpha: 0.6, - vector: [1, 2, 3], - targetVector: 'title', - fusionType: 'Ranked', - maxVectorDistance: 0.4, - supportsTargets: false, - supportsVectorsForTargets: false, - supportsWeightsForTargets: false, - }); + const args = Serialize.search.hybrid( + { + query: 'test', + supportsTargets: false, + supportsVectorsForTargets: false, + supportsWeightsForTargets: false, + }, + { + queryProperties: ['name'], + alpha: 0.6, + vector: [1, 2, 3], + targetVector: 'title', + fusionType: 'Ranked', + maxVectorDistance: 0.4, + } + ); expect(args).toEqual({ hybridSearch: Hybrid.fromPartial({ query: 'test', @@ -174,23 +175,27 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for multi-vector & multi-target hybrid', () => { - const args = Serialize.hybrid({ - query: 'test', - queryProperties: ['name'], - alpha: 0.6, - vector: { - title: [ - [1, 2, 3], - [4, 5, 6], - ], - description: [7, 8, 9], + const args = Serialize.search.hybrid( + { + query: 'test', + supportsTargets: true, + supportsVectorsForTargets: true, + supportsWeightsForTargets: true, }, - targetVector: multiTargetVector().manualWeights({ title: [0.5, 0.5], description: 0.5 }), - fusionType: 'Ranked', - supportsTargets: true, - supportsVectorsForTargets: true, - supportsWeightsForTargets: true, - }); + { + queryProperties: ['name'], + alpha: 0.6, + vector: { + title: [ + [1, 2, 3], + [4, 5, 6], + ], + description: [7, 8, 9], + }, + targetVector: multiTargetVector().manualWeights({ title: [0.5, 0.5], description: 0.5 }), + fusionType: 'Ranked', + } + ); expect(args).toEqual({ hybridSearch: Hybrid.fromPartial({ query: 'test', @@ -228,14 +233,18 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for nearAudio', () => { - const args = Serialize.nearAudio({ - audio: 'audio', - certainty: 0.6, - distance: 0.4, - targetVector: 'audio', - supportsTargets: false, - supportsWeightsForTargets: false, - }); + const args = Serialize.search.nearAudio( + { + audio: 'audio', + supportsTargets: false, + supportsWeightsForTargets: false, + }, + { + certainty: 0.6, + distance: 0.4, + targetVector: 'audio', + } + ); expect(args).toEqual({ nearAudio: NearAudioSearch.fromPartial({ audio: 'audio', @@ -248,7 +257,7 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for nearDepth', () => { - const args = Serialize.nearDepth({ + const args = Serialize.search.nearDepth({ depth: 'depth', supportsTargets: false, supportsWeightsForTargets: false, @@ -262,7 +271,7 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for nearIMU', () => { - const args = Serialize.nearIMU({ + const args = Serialize.search.nearIMU({ imu: 'imu', supportsTargets: false, supportsWeightsForTargets: false, @@ -276,7 +285,7 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for nearImage', () => { - const args = Serialize.nearImage({ + const args = Serialize.search.nearImage({ image: 'image', supportsTargets: false, supportsWeightsForTargets: false, @@ -290,7 +299,7 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for nearObject', () => { - const args = Serialize.nearObject({ + const args = Serialize.search.nearObject({ id: 'id', supportsTargets: false, supportsWeightsForTargets: false, @@ -304,21 +313,25 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for nearText', () => { - const args = Serialize.nearText({ - query: 'test', - moveAway: { - objects: ['0'], - concepts: ['bad'], - force: 0.4, - }, - moveTo: { - objects: ['1'], - concepts: ['good'], - force: 0.6, + const args = Serialize.search.nearText( + { + query: 'test', + supportsTargets: false, + supportsWeightsForTargets: false, }, - supportsTargets: false, - supportsWeightsForTargets: false, - }); + { + moveAway: { + objects: ['0'], + concepts: ['bad'], + force: 0.4, + }, + moveTo: { + objects: ['1'], + concepts: ['good'], + force: 0.6, + }, + } + ); expect(args).toEqual({ nearText: NearTextSearch.fromPartial({ query: ['test'], @@ -338,7 +351,7 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for nearThermal', () => { - const args = Serialize.nearThermal({ + const args = Serialize.search.nearThermal({ thermal: 'thermal', supportsTargets: false, supportsWeightsForTargets: false, @@ -352,7 +365,7 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for nearVector with single vector', () => { - const args = Serialize.nearVector({ + const args = Serialize.search.nearVector({ vector: [1, 2, 3], supportsTargets: false, supportsVectorsForTargets: false, @@ -367,7 +380,7 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for nearVector with two named vectors and supportsTargets (<1.27.0)', () => { - const args = Serialize.nearVector({ + const args = Serialize.search.nearVector({ vector: { a: [1, 2, 3], b: [4, 5, 6], @@ -389,7 +402,7 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for nearVector with two named vectors and all supports (==1.27.x)', () => { - const args = Serialize.nearVector({ + const args = Serialize.search.nearVector({ vector: { a: [ [1, 2, 3], @@ -415,7 +428,7 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for nearVideo', () => { - const args = Serialize.nearVideo({ + const args = Serialize.search.nearVideo({ video: 'video', supportsTargets: false, supportsWeightsForTargets: false, @@ -444,7 +457,7 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for groupBy', () => { - const args = Serialize.groupBy({ + const args = Serialize.search.groupBy({ property: 'name', numberOfGroups: 1, objectsPerGroup: 2, @@ -457,14 +470,14 @@ describe('Unit testing of Serialize', () => { }); it('should parse args for isGroupBy', () => { - const isGroupBy = Serialize.isGroupBy({ + const isGroupBy = Serialize.search.isGroupBy({ groupBy: { property: 'name', numberOfGroups: 1, objectsPerGroup: 2, }, }); - const isNotGroupBy = Serialize.isGroupBy({}); + const isNotGroupBy = Serialize.search.isGroupBy({}); expect(isGroupBy).toEqual(true); expect(isNotGroupBy).toEqual(false); }); diff --git a/src/collections/tenants/unit.test.ts b/src/collections/tenants/unit.test.ts index b1b2e2c5..a697e550 100644 --- a/src/collections/tenants/unit.test.ts +++ b/src/collections/tenants/unit.test.ts @@ -33,6 +33,7 @@ const makeRestApp = (version: string) => { const makeGrpcApp = () => { const weaviateMockImpl: WeaviateServiceImplementation = { + aggregate: jest.fn(), tenantsGet: (request: TenantsGetRequest): Promise => Promise.resolve({ took: 0.1, diff --git a/src/connection/grpc.ts b/src/connection/grpc.ts index 79e642cd..e40f8ece 100644 --- a/src/connection/grpc.ts +++ b/src/connection/grpc.ts @@ -17,6 +17,7 @@ import TenantsManager, { Tenants } from '../grpc/tenantsManager.js'; import { DbVersionSupport, initDbVersionProvider } from '../utils/dbVersion.js'; import { WeaviateGRPCUnavailableError, WeaviateUnsupportedFeatureError } from '../errors.js'; +import Aggregator, { Aggregate } from '../grpc/aggregator.js'; import { Meta } from '../openapi/types.js'; export interface GrpcConnectionParams extends InternalConnectionParams { @@ -90,22 +91,33 @@ export default class ConnectionGRPC extends ConnectionGQL { return connection; } - search = (collection: string, consistencyLevel?: ConsistencyLevel, tenant?: string) => { + batch = (collection: string, consistencyLevel?: ConsistencyLevel, tenant?: string) => { if (this.authEnabled) { return this.login().then((token) => - this.grpc.search(collection, consistencyLevel, tenant, `Bearer ${token}`) + this.grpc.batch(collection, consistencyLevel, tenant, `Bearer ${token}`) ); } - return new Promise((resolve) => resolve(this.grpc.search(collection, consistencyLevel, tenant))); + return new Promise((resolve) => resolve(this.grpc.batch(collection, consistencyLevel, tenant))); }; - batch = (collection: string, consistencyLevel?: ConsistencyLevel, tenant?: string) => { + aggregate = (collection: string, consistencyLevel?: ConsistencyLevel, tenant?: string) => { if (this.authEnabled) { return this.login().then((token) => - this.grpc.batch(collection, consistencyLevel, tenant, `Bearer ${token}`) + this.grpc.aggregate(collection, consistencyLevel, tenant, `Bearer ${token}`) ); } - return new Promise((resolve) => resolve(this.grpc.batch(collection, consistencyLevel, tenant))); + return new Promise((resolve) => + resolve(this.grpc.aggregate(collection, consistencyLevel, tenant)) + ); + }; + + search = (collection: string, consistencyLevel?: ConsistencyLevel, tenant?: string) => { + if (this.authEnabled) { + return this.login().then((token) => + this.grpc.search(collection, consistencyLevel, tenant, `Bearer ${token}`) + ); + } + return new Promise((resolve) => resolve(this.grpc.search(collection, consistencyLevel, tenant))); }; tenants = (collection: string) => { @@ -122,13 +134,19 @@ export default class ConnectionGRPC extends ConnectionGQL { } export interface GrpcClient { - close: () => void; + aggregate: ( + collection: string, + consistencyLevel?: ConsistencyLevel, + tenant?: string, + bearerToken?: string + ) => Aggregate; batch: ( collection: string, consistencyLevel?: ConsistencyLevel, tenant?: string, bearerToken?: string ) => Batch; + close: () => void; health: () => Promise; search: ( collection: string, @@ -158,7 +176,20 @@ export const grpcClient = (config: GrpcConnectionParams & { grpcMaxMessageLength const client = clientFactory.create(WeaviateDefinition, channel); const health = clientFactory.create(HealthDefinition, channel); return { - close: () => channel.close(), + aggregate: ( + collection: string, + consistencyLevel?: ConsistencyLevel, + tenant?: string, + bearerToken?: string + ) => + Aggregator.use( + client, + collection, + new Metadata(bearerToken ? { ...config.headers, authorization: bearerToken } : config.headers), + config.timeout?.query || 30, + consistencyLevel, + tenant + ), batch: (collection: string, consistencyLevel?: ConsistencyLevel, tenant?: string, bearerToken?: string) => Batcher.use( client, @@ -168,6 +199,7 @@ export const grpcClient = (config: GrpcConnectionParams & { grpcMaxMessageLength consistencyLevel, tenant ), + close: () => channel.close(), health: () => { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), (config.timeout?.init || 2) * 1000); diff --git a/src/connection/unit.test.ts b/src/connection/unit.test.ts index 9d2919e0..ab88c586 100644 --- a/src/connection/unit.test.ts +++ b/src/connection/unit.test.ts @@ -23,6 +23,7 @@ import { WeaviateDefinition, WeaviateServiceImplementation } from '../proto/v1/w import { WeaviateRequestTimeoutError } from '../errors.js'; import weaviate, { Collection, WeaviateClient } from '../index'; +import { AggregateReply } from '../proto/v1/aggregate.js'; import { BatchObjectsReply } from '../proto/v1/batch.js'; import { BatchDeleteReply } from '../proto/v1/batch_delete.js'; import { SearchReply } from '../proto/v1/search_get.js'; @@ -231,6 +232,14 @@ const makeRestApp = (version: string) => { const makeGrpcApp = () => { const weaviateMockImpl: WeaviateServiceImplementation = { + aggregate: (): Promise => + new Promise((r) => { + setTimeout(r, 2000); + }).then(() => { + return { + took: 5000, + }; + }), tenantsGet: (): Promise => new Promise((r) => { setTimeout(r, 2000); @@ -303,7 +312,7 @@ describe('Mock testing of timeout behaviour', () => { let collection: Collection; beforeAll(async () => { - servers = await makeMockServers('1.28.2', 8954, 'localhost:8955'); + servers = await makeMockServers('1.29.0', 8954, 'localhost:8955'); client = await weaviate.connectToLocal({ port: 8954, grpcPort: 8955, timeout: { query: 1, insert: 1 } }); collection = client.collections.get(COLLECTION_NAME); }); @@ -324,6 +333,8 @@ describe('Mock testing of timeout behaviour', () => { expect(collection.data.deleteMany(collection.filter.byId().equal('123' as any))).rejects.toThrow( WeaviateRequestTimeoutError )); + it('should timeout when calling gRPC Aggregate', () => + expect(collection.aggregate.overAll()).rejects.toThrow(WeaviateRequestTimeoutError)); afterAll(() => Promise.all([servers.rest.close(), servers.grpc.shutdown()])); }); diff --git a/src/data/creator.ts b/src/data/creator.ts index 43581c66..a22912da 100644 --- a/src/data/creator.ts +++ b/src/data/creator.ts @@ -61,13 +61,15 @@ export default class Creator extends CommandBase { } }; + // as Record required below because server uses swagger object as interface{} in Go to perform type switching + // actual types are []number and [][]number but unions don't work in go-swagger payload = (): WeaviateObject => ({ tenant: this.tenant, vector: this.vector, properties: this.properties, class: this.className, id: this.id, - vectors: this.vectors, + vectors: this.vectors as Record, }); validate = () => { diff --git a/src/data/updater.ts b/src/data/updater.ts index 05fc77e7..39cf0365 100644 --- a/src/data/updater.ts +++ b/src/data/updater.ts @@ -67,13 +67,15 @@ export default class Updater extends CommandBase { return this; }; + // as Record required below because server uses swagger object as interface{} in Go to perform type switching + // actual types are []number and [][]number but unions don't work in go-swagger payload = (): WeaviateObject => ({ tenant: this.tenant, properties: this.properties, class: this.className, id: this.id, vector: this.vector, - vectors: this.vectors, + vectors: this.vectors as Record, }); validate = () => { diff --git a/src/graphql/aggregator.ts b/src/graphql/aggregator.ts index 58ffb615..1ec2b838 100644 --- a/src/graphql/aggregator.ts +++ b/src/graphql/aggregator.ts @@ -205,6 +205,7 @@ export default class Aggregator extends CommandBase { this.nearVectorString || this.limit || this.groupBy || + this.hybridString || this.tenant ) { let args: string[] = []; @@ -251,7 +252,6 @@ export default class Aggregator extends CommandBase { params = `(${args.join(',')})`; } - return this.client.query(`{Aggregate{${this.className}${params}{${this.fields}}}}`); }; } diff --git a/src/graphql/journey.test.ts b/src/graphql/journey.test.ts index de8fe70c..c3dde018 100644 --- a/src/graphql/journey.test.ts +++ b/src/graphql/journey.test.ts @@ -2378,7 +2378,7 @@ describe('named vectors test', () => { .get() .withClassName(className) .withNearVector({ - vector: res.vectors?.title as number[], + vector: res.vectors?.title as any, targetVectors: ['title'], }) .withFields('title') diff --git a/src/grpc/aggregator.ts b/src/grpc/aggregator.ts new file mode 100644 index 00000000..daf9bfa1 --- /dev/null +++ b/src/grpc/aggregator.ts @@ -0,0 +1,149 @@ +import { ConsistencyLevel } from '../data/index.js'; + +import { Metadata, ServerError, Status } from 'nice-grpc'; +import { + AggregateReply, + AggregateRequest, + AggregateRequest_Aggregation, + AggregateRequest_GroupBy, +} from '../proto/v1/aggregate.js'; +import { Filters } from '../proto/v1/base.js'; +import { + Hybrid, + NearAudioSearch, + NearDepthSearch, + NearIMUSearch, + NearImageSearch, + NearObject, + NearTextSearch, + NearThermalSearch, + NearVector, + NearVideoSearch, +} from '../proto/v1/base_search.js'; +import { WeaviateClient } from '../proto/v1/weaviate.js'; + +import { isAbortError } from 'abort-controller-x'; +import { RetryOptions } from 'nice-grpc-client-middleware-retry'; +import { + WeaviateInsufficientPermissionsError, + WeaviateQueryError, + WeaviateRequestTimeoutError, +} from '../errors.js'; +import Base from './base.js'; +import { retryOptions } from './retry.js'; + +export type BaseAggregateArgs = { + aggregations?: AggregateRequest_Aggregation[]; + filters?: Filters; + groupBy?: AggregateRequest_GroupBy; + limit?: number; + objectLimit?: number; +}; + +export type AggregateFetchArgs = BaseAggregateArgs; + +export type AggregateHybridArgs = BaseAggregateArgs & { + hybrid: Hybrid; +}; + +export type AggregateNearAudioArgs = BaseAggregateArgs & { + nearAudio: NearAudioSearch; +}; + +export type AggregateNearDepthArgs = BaseAggregateArgs & { + nearDepth: NearDepthSearch; +}; + +export type AggregateNearImageArgs = BaseAggregateArgs & { + nearImage: NearImageSearch; +}; + +export type AggregateNearIMUArgs = BaseAggregateArgs & { + nearIMU: NearIMUSearch; +}; + +export type AggregateNearObjectArgs = BaseAggregateArgs & { + nearObject: NearObject; +}; + +export type AggregateNearTextArgs = BaseAggregateArgs & { + nearText: NearTextSearch; +}; + +export type AggregateNearThermalArgs = BaseAggregateArgs & { + nearThermal: NearThermalSearch; +}; + +export type AggregateNearVectorArgs = BaseAggregateArgs & { + nearVector: NearVector; +}; + +export type AggregateNearVideoArgs = BaseAggregateArgs & { + nearVideo: NearVideoSearch; +}; + +export interface Aggregate { + withFetch: (args: AggregateFetchArgs) => Promise; + withHybrid: (args: AggregateHybridArgs) => Promise; + withNearAudio: (args: AggregateNearAudioArgs) => Promise; + withNearDepth: (args: AggregateNearDepthArgs) => Promise; + withNearImage: (args: AggregateNearImageArgs) => Promise; + withNearIMU: (args: AggregateNearIMUArgs) => Promise; + withNearObject: (args: AggregateNearObjectArgs) => Promise; + withNearText: (args: AggregateNearTextArgs) => Promise; + withNearThermal: (args: AggregateNearThermalArgs) => Promise; + withNearVector: (args: AggregateNearVectorArgs) => Promise; + withNearVideo: (args: AggregateNearVideoArgs) => Promise; +} + +export default class Aggregator extends Base implements Aggregate { + public static use( + connection: WeaviateClient, + collection: string, + metadata: Metadata, + timeout: number, + consistencyLevel?: ConsistencyLevel, + tenant?: string + ): Aggregate { + return new Aggregator(connection, collection, metadata, timeout, consistencyLevel, tenant); + } + + public withFetch = (args: AggregateFetchArgs) => this.call(AggregateRequest.fromPartial(args)); + public withHybrid = (args: AggregateHybridArgs) => this.call(AggregateRequest.fromPartial(args)); + public withNearAudio = (args: AggregateNearAudioArgs) => this.call(AggregateRequest.fromPartial(args)); + public withNearDepth = (args: AggregateNearDepthArgs) => this.call(AggregateRequest.fromPartial(args)); + public withNearImage = (args: AggregateNearImageArgs) => this.call(AggregateRequest.fromPartial(args)); + public withNearIMU = (args: AggregateNearIMUArgs) => this.call(AggregateRequest.fromPartial(args)); + public withNearObject = (args: AggregateNearObjectArgs) => this.call(AggregateRequest.fromPartial(args)); + public withNearText = (args: AggregateNearTextArgs) => this.call(AggregateRequest.fromPartial(args)); + public withNearThermal = (args: AggregateNearThermalArgs) => this.call(AggregateRequest.fromPartial(args)); + public withNearVector = (args: AggregateNearVectorArgs) => this.call(AggregateRequest.fromPartial(args)); + public withNearVideo = (args: AggregateNearVideoArgs) => this.call(AggregateRequest.fromPartial(args)); + + private call = (message: AggregateRequest) => + this.sendWithTimeout((signal: AbortSignal) => + this.connection + .aggregate( + { + ...message, + collection: this.collection, + tenant: this.tenant, + objectsCount: true, + }, + { + metadata: this.metadata, + signal, + ...retryOptions, + } + ) + .catch((err) => { + if (err instanceof ServerError && err.code === Status.PERMISSION_DENIED) { + throw new WeaviateInsufficientPermissionsError(7, err.message); + } + if (isAbortError(err)) { + throw new WeaviateRequestTimeoutError(`timed out after ${this.timeout}ms`); + } + throw new WeaviateQueryError(err.message, 'gRPC'); + }) + ); +} diff --git a/src/grpc/searcher.ts b/src/grpc/searcher.ts index 893d0c74..6dc6103e 100644 --- a/src/grpc/searcher.ts +++ b/src/grpc/searcher.ts @@ -4,9 +4,7 @@ import { Metadata, ServerError, Status } from 'nice-grpc'; import { Filters } from '../proto/v1/base.js'; import { BM25, - GroupBy, Hybrid, - MetadataRequest, NearAudioSearch, NearDepthSearch, NearIMUSearch, @@ -16,6 +14,10 @@ import { NearThermalSearch, NearVector, NearVideoSearch, +} from '../proto/v1/base_search.js'; +import { + GroupBy, + MetadataRequest, PropertiesRequest, Rerank, SearchReply, @@ -31,6 +33,7 @@ import { WeaviateQueryError, WeaviateRequestTimeoutError, } from '../errors.js'; +import { NearMediaType } from '../index.js'; import { GenerativeSearch } from '../proto/v1/generative.js'; import Base from './base.js'; import { retryOptions } from './retry.js'; @@ -103,6 +106,20 @@ export type SearchNearVideoArgs = BaseSearchArgs & { nearVideo: NearVideoSearch; }; +export type SearchNearMediaArgs = T extends 'audio' + ? SearchNearAudioArgs + : T extends 'depth' + ? SearchNearDepthArgs + : T extends 'image' + ? SearchNearImageArgs + : T extends 'imu' + ? SearchNearIMUArgs + : T extends 'thermal' + ? SearchNearThermalArgs + : T extends 'video' + ? SearchNearVideoArgs + : never; + export interface Search { withFetch: (args: SearchFetchArgs) => Promise; withBm25: (args: SearchBm25Args) => Promise; diff --git a/src/index.ts b/src/index.ts index 101bc14e..653b9c60 100644 --- a/src/index.ts +++ b/src/index.ts @@ -39,6 +39,7 @@ import { LiveChecker, OpenidConfigurationGetter, ReadyChecker } from './misc/ind import weaviateV2 from './v2/index.js'; import { ConsistencyLevel } from './data/replication.js'; +import users, { Users } from './users/index.js'; export type ProtocolParams = { /** @@ -105,6 +106,7 @@ export interface WeaviateClient { collections: Collections; oidcAuth?: OidcAuthenticator; roles: Roles; + users: Users; close: () => Promise; getMeta: () => Promise; @@ -224,6 +226,7 @@ async function client(params: ClientParams): Promise { cluster: cluster(connection), collections: collections(connection, dbVersionSupport), roles: roles(connection), + users: users(connection), close: () => Promise.resolve(connection.close()), // hedge against future changes to add I/O to .close() getMeta: () => new MetaGetter(connection).do(), getOpenIDConfig: () => new OpenidConfigurationGetter(connection.http).do(), diff --git a/src/openapi/schema.ts b/src/openapi/schema.ts index 986f4f85..d6f3bbb4 100644 --- a/src/openapi/schema.ts +++ b/src/openapi/schema.ts @@ -40,6 +40,9 @@ export interface paths { }; }; }; + '/users/own-info': { + get: operations['getOwnInfo']; + }; '/authz/roles': { get: operations['getRoles']; post: operations['createRole']; @@ -64,13 +67,16 @@ export interface paths { get: operations['getRolesForUser']; }; '/authz/users/{id}/assign': { - post: operations['assignRole']; + post: operations['assignRoleToUser']; }; '/authz/users/{id}/revoke': { - post: operations['revokeRole']; + post: operations['revokeRoleFromUser']; + }; + '/authz/groups/{id}/assign': { + post: operations['assignRoleToGroup']; }; - '/authz/users/own-roles': { - get: operations['getRolesForOwnUser']; + '/authz/groups/{id}/revoke': { + post: operations['revokeRoleFromGroup']; }; '/objects': { /** Lists all Objects in reverse order of creation, owned by the user that belongs to the used token. */ @@ -225,6 +231,13 @@ export interface paths { } export interface definitions { + UserInfo: { + /** @description The groups associated to the user */ + groups?: string[]; + roles?: definitions['Role'][]; + /** @description The username associated with the provided key */ + username: string; + }; Role: { /** @description role name */ name: string; @@ -272,6 +285,27 @@ export interface definitions { */ collection?: string; }; + /** @description resources applicable for user actions */ + users?: { + /** + * @description string or regex. if a specific name, if left empty it will be ALL or * + * @default * + */ + users?: string; + }; + /** @description resources applicable for tenant actions */ + tenants?: { + /** + * @description string or regex. if a specific collection name, if left empty it will be ALL or * + * @default * + */ + collection?: string; + /** + * @description string or regex. if a specific tenant name, if left empty it will be ALL or * + * @default * + */ + tenant?: string; + }; /** @description resources applicable for role actions */ roles?: { /** @@ -279,6 +313,12 @@ export interface definitions { * @default * */ role?: string; + /** + * @description set the scope for the manage role permission + * @default match + * @enum {string} + */ + scope?: 'all' | 'match'; }; /** @description resources applicable for collection and/or tenant actions */ collections?: { @@ -287,11 +327,6 @@ export interface definitions { * @default * */ collection?: string; - /** - * @description string or regex. if a specific tenant name, if left empty it will be ALL or * - * @default * - */ - tenant?: string; }; /** * @description allowed actions in weaviate. @@ -300,19 +335,25 @@ export interface definitions { action: | 'manage_backups' | 'read_cluster' - | 'manage_data' | 'create_data' | 'read_data' | 'update_data' | 'delete_data' | 'read_nodes' - | 'manage_roles' + | 'create_roles' | 'read_roles' - | 'manage_collections' + | 'update_roles' + | 'delete_roles' | 'create_collections' | 'read_collections' | 'update_collections' - | 'delete_collections'; + | 'delete_collections' + | 'assign_and_revoke_users' + | 'read_users' + | 'create_tenants' + | 'read_tenants' + | 'update_tenants' + | 'delete_tenants'; }; /** @description list of roles */ RolesListResponse: definitions['Role'][]; @@ -374,7 +415,7 @@ export interface definitions { /** @description A vector representation of the object in the Contextionary. If provided at object creation, this wil take precedence over any vectorizer setting. */ C11yVector: number[]; /** @description A vector representation of the object. If provided at object creation, this wil take precedence over any vectorizer setting. */ - Vector: number[]; + Vector: { [key: string]: unknown }; /** @description A map of named vectors for multi-vector representations. */ Vectors: { [key: string]: definitions['Vector'] }; /** @description Receive question based on array of classes, properties and values. */ @@ -1504,12 +1545,6 @@ export interface definitions { TenantResponse: definitions['Tenant'] & { /** @description The list of nodes that owns that tenant data. */ belongsToNodes?: string[]; - /** - * @description Experimental. The data version of the tenant is a monotonically increasing number starting from 0 which is incremented each time a tenant's data is offloaded to cloud storage. - * @default 0 - * @example 3 - */ - dataVersion?: number; }; } @@ -1576,6 +1611,20 @@ export interface operations { 503: unknown; }; }; + getOwnInfo: { + responses: { + /** Info about the user */ + 200: { + schema: definitions['UserInfo']; + }; + /** Unauthorized or invalid credentials. */ + 401: 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']; + }; + }; + }; getRoles: { responses: { /** Successful response. */ @@ -1860,7 +1909,7 @@ export interface operations { }; }; }; - assignRole: { + assignRoleToUser: { parameters: { path: { /** user name */ @@ -1887,14 +1936,16 @@ export interface operations { schema: definitions['ErrorResponse']; }; /** role or user is not found. */ - 404: unknown; + 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']; }; }; }; - revokeRole: { + revokeRoleFromUser: { parameters: { path: { /** user name */ @@ -1921,6 +1972,42 @@ export interface operations { schema: definitions['ErrorResponse']; }; /** role or user is not 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']; + }; + }; + }; + assignRoleToGroup: { + parameters: { + path: { + /** group name */ + id: string; + }; + body: { + body: { + /** @description the roles that assigned to group */ + roles?: string[]; + }; + }; + }; + responses: { + /** Role assigned successfully */ + 200: unknown; + /** Bad request */ + 400: { + schema: definitions['ErrorResponse']; + }; + /** Unauthorized or invalid credentials. */ + 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** role or group is not 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: { @@ -1928,14 +2015,34 @@ export interface operations { }; }; }; - getRolesForOwnUser: { + revokeRoleFromGroup: { + parameters: { + path: { + /** group name */ + id: string; + }; + body: { + body: { + /** @description the roles that revoked from group */ + roles?: string[]; + }; + }; + }; responses: { - /** Role assigned to own users */ - 200: { - schema: definitions['RolesListResponse']; + /** Role revoked successfully */ + 200: unknown; + /** Bad request */ + 400: { + schema: definitions['ErrorResponse']; }; /** Unauthorized or invalid credentials. */ 401: unknown; + /** Forbidden */ + 403: { + schema: definitions['ErrorResponse']; + }; + /** role or group is not 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']; diff --git a/src/openapi/types.ts b/src/openapi/types.ts index 44b7d0d8..304dd1d5 100644 --- a/src/openapi/types.ts +++ b/src/openapi/types.ts @@ -54,6 +54,7 @@ export type WeaviateMultiTenancyConfig = WeaviateClass['multiTenancyConfig']; export type WeaviateReplicationConfig = WeaviateClass['replicationConfig']; export type WeaviateShardingConfig = WeaviateClass['shardingConfig']; export type WeaviateShardStatus = definitions['ShardStatusGetResponse']; +export type WeaviateUser = definitions['UserInfo']; export type WeaviateVectorIndexConfig = WeaviateClass['vectorIndexConfig']; export type WeaviateVectorsConfig = WeaviateClass['vectorConfig']; export type WeaviateVectorConfig = definitions['VectorConfig']; diff --git a/src/proto/v1/aggregate.ts b/src/proto/v1/aggregate.ts new file mode 100644 index 00000000..9caf8d16 --- /dev/null +++ b/src/proto/v1/aggregate.ts @@ -0,0 +1,3433 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v1.176.0 +// protoc v3.19.1 +// source: v1/aggregate.proto + +/* eslint-disable */ +import Long from "long"; +import _m0 from "protobufjs/minimal.js"; +import { BooleanArray, Filters, GeoCoordinatesFilter, IntArray, NumberArray, TextArray } from "./base.js"; +import { + Hybrid, + NearAudioSearch, + NearDepthSearch, + NearImageSearch, + NearIMUSearch, + NearObject, + NearTextSearch, + NearThermalSearch, + NearVector, + NearVideoSearch, +} from "./base_search.js"; + +export const protobufPackage = "weaviate.v1"; + +export interface AggregateRequest { + /** required */ + collection: string; + /** parameters */ + tenant: string; + /** what is returned */ + objectsCount: boolean; + aggregations: AggregateRequest_Aggregation[]; + /** affects aggregation results */ + objectLimit?: number | undefined; + groupBy?: AggregateRequest_GroupBy | undefined; + limit?: + | number + | undefined; + /** matches/searches for objects */ + filters?: Filters | undefined; + hybrid?: Hybrid | undefined; + nearVector?: NearVector | undefined; + nearObject?: NearObject | undefined; + nearText?: NearTextSearch | undefined; + nearImage?: NearImageSearch | undefined; + nearAudio?: NearAudioSearch | undefined; + nearVideo?: NearVideoSearch | undefined; + nearDepth?: NearDepthSearch | undefined; + nearThermal?: NearThermalSearch | undefined; + nearImu?: NearIMUSearch | undefined; +} + +export interface AggregateRequest_Aggregation { + property: string; + int?: AggregateRequest_Aggregation_Integer | undefined; + number?: AggregateRequest_Aggregation_Number | undefined; + text?: AggregateRequest_Aggregation_Text | undefined; + boolean?: AggregateRequest_Aggregation_Boolean | undefined; + date?: AggregateRequest_Aggregation_DateMessage | undefined; + reference?: AggregateRequest_Aggregation_Reference | undefined; +} + +export interface AggregateRequest_Aggregation_Integer { + count: boolean; + type: boolean; + sum: boolean; + mean: boolean; + mode: boolean; + median: boolean; + maximum: boolean; + minimum: boolean; +} + +export interface AggregateRequest_Aggregation_Number { + count: boolean; + type: boolean; + sum: boolean; + mean: boolean; + mode: boolean; + median: boolean; + maximum: boolean; + minimum: boolean; +} + +export interface AggregateRequest_Aggregation_Text { + count: boolean; + type: boolean; + topOccurences: boolean; + topOccurencesLimit?: number | undefined; +} + +export interface AggregateRequest_Aggregation_Boolean { + count: boolean; + type: boolean; + totalTrue: boolean; + totalFalse: boolean; + percentageTrue: boolean; + percentageFalse: boolean; +} + +export interface AggregateRequest_Aggregation_DateMessage { + count: boolean; + type: boolean; + median: boolean; + mode: boolean; + maximum: boolean; + minimum: boolean; +} + +export interface AggregateRequest_Aggregation_Reference { + type: boolean; + pointingTo: boolean; +} + +export interface AggregateRequest_GroupBy { + collection: string; + property: string; +} + +export interface AggregateReply { + took: number; + singleResult?: AggregateReply_Single | undefined; + groupedResults?: AggregateReply_Grouped | undefined; +} + +export interface AggregateReply_Aggregations { + aggregations: AggregateReply_Aggregations_Aggregation[]; +} + +export interface AggregateReply_Aggregations_Aggregation { + property: string; + int?: AggregateReply_Aggregations_Aggregation_Integer | undefined; + number?: AggregateReply_Aggregations_Aggregation_Number | undefined; + text?: AggregateReply_Aggregations_Aggregation_Text | undefined; + boolean?: AggregateReply_Aggregations_Aggregation_Boolean | undefined; + date?: AggregateReply_Aggregations_Aggregation_DateMessage | undefined; + reference?: AggregateReply_Aggregations_Aggregation_Reference | undefined; +} + +export interface AggregateReply_Aggregations_Aggregation_Integer { + count?: number | undefined; + type?: string | undefined; + mean?: number | undefined; + median?: number | undefined; + mode?: number | undefined; + maximum?: number | undefined; + minimum?: number | undefined; + sum?: number | undefined; +} + +export interface AggregateReply_Aggregations_Aggregation_Number { + count?: number | undefined; + type?: string | undefined; + mean?: number | undefined; + median?: number | undefined; + mode?: number | undefined; + maximum?: number | undefined; + minimum?: number | undefined; + sum?: number | undefined; +} + +export interface AggregateReply_Aggregations_Aggregation_Text { + count?: number | undefined; + type?: string | undefined; + topOccurences?: AggregateReply_Aggregations_Aggregation_Text_TopOccurrences | undefined; +} + +export interface AggregateReply_Aggregations_Aggregation_Text_TopOccurrences { + items: AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence[]; +} + +export interface AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence { + value: string; + occurs: number; +} + +export interface AggregateReply_Aggregations_Aggregation_Boolean { + count?: number | undefined; + type?: string | undefined; + totalTrue?: number | undefined; + totalFalse?: number | undefined; + percentageTrue?: number | undefined; + percentageFalse?: number | undefined; +} + +export interface AggregateReply_Aggregations_Aggregation_DateMessage { + count?: number | undefined; + type?: string | undefined; + median?: string | undefined; + mode?: string | undefined; + maximum?: string | undefined; + minimum?: string | undefined; +} + +export interface AggregateReply_Aggregations_Aggregation_Reference { + type?: + | string + | undefined; + /** protolint:disable:next REPEATED_FIELD_NAMES_PLURALIZED */ + pointingTo: string[]; +} + +export interface AggregateReply_Single { + objectsCount?: number | undefined; + aggregations?: AggregateReply_Aggregations | undefined; +} + +export interface AggregateReply_Group { + objectsCount?: number | undefined; + aggregations?: AggregateReply_Aggregations | undefined; + groupedBy?: AggregateReply_Group_GroupedBy | undefined; +} + +export interface AggregateReply_Group_GroupedBy { + /** protolint:disable:next REPEATED_FIELD_NAMES_PLURALIZED */ + path: string[]; + text?: string | undefined; + int?: number | undefined; + boolean?: boolean | undefined; + number?: number | undefined; + texts?: TextArray | undefined; + ints?: IntArray | undefined; + booleans?: BooleanArray | undefined; + numbers?: NumberArray | undefined; + geo?: GeoCoordinatesFilter | undefined; +} + +export interface AggregateReply_Grouped { + groups: AggregateReply_Group[]; +} + +function createBaseAggregateRequest(): AggregateRequest { + return { + collection: "", + tenant: "", + objectsCount: false, + aggregations: [], + objectLimit: undefined, + groupBy: undefined, + limit: undefined, + filters: undefined, + hybrid: undefined, + nearVector: undefined, + nearObject: undefined, + nearText: undefined, + nearImage: undefined, + nearAudio: undefined, + nearVideo: undefined, + nearDepth: undefined, + nearThermal: undefined, + nearImu: undefined, + }; +} + +export const AggregateRequest = { + encode(message: AggregateRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.collection !== "") { + writer.uint32(10).string(message.collection); + } + if (message.tenant !== "") { + writer.uint32(82).string(message.tenant); + } + if (message.objectsCount !== false) { + writer.uint32(160).bool(message.objectsCount); + } + for (const v of message.aggregations) { + AggregateRequest_Aggregation.encode(v!, writer.uint32(170).fork()).ldelim(); + } + if (message.objectLimit !== undefined) { + writer.uint32(240).uint32(message.objectLimit); + } + if (message.groupBy !== undefined) { + AggregateRequest_GroupBy.encode(message.groupBy, writer.uint32(250).fork()).ldelim(); + } + if (message.limit !== undefined) { + writer.uint32(256).uint32(message.limit); + } + if (message.filters !== undefined) { + Filters.encode(message.filters, writer.uint32(322).fork()).ldelim(); + } + if (message.hybrid !== undefined) { + Hybrid.encode(message.hybrid, writer.uint32(330).fork()).ldelim(); + } + if (message.nearVector !== undefined) { + NearVector.encode(message.nearVector, writer.uint32(338).fork()).ldelim(); + } + if (message.nearObject !== undefined) { + NearObject.encode(message.nearObject, writer.uint32(346).fork()).ldelim(); + } + if (message.nearText !== undefined) { + NearTextSearch.encode(message.nearText, writer.uint32(354).fork()).ldelim(); + } + if (message.nearImage !== undefined) { + NearImageSearch.encode(message.nearImage, writer.uint32(362).fork()).ldelim(); + } + if (message.nearAudio !== undefined) { + NearAudioSearch.encode(message.nearAudio, writer.uint32(370).fork()).ldelim(); + } + if (message.nearVideo !== undefined) { + NearVideoSearch.encode(message.nearVideo, writer.uint32(378).fork()).ldelim(); + } + if (message.nearDepth !== undefined) { + NearDepthSearch.encode(message.nearDepth, writer.uint32(386).fork()).ldelim(); + } + if (message.nearThermal !== undefined) { + NearThermalSearch.encode(message.nearThermal, writer.uint32(394).fork()).ldelim(); + } + if (message.nearImu !== undefined) { + NearIMUSearch.encode(message.nearImu, writer.uint32(402).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateRequest { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.collection = reader.string(); + continue; + case 10: + if (tag !== 82) { + break; + } + + message.tenant = reader.string(); + continue; + case 20: + if (tag !== 160) { + break; + } + + message.objectsCount = reader.bool(); + continue; + case 21: + if (tag !== 170) { + break; + } + + message.aggregations.push(AggregateRequest_Aggregation.decode(reader, reader.uint32())); + continue; + case 30: + if (tag !== 240) { + break; + } + + message.objectLimit = reader.uint32(); + continue; + case 31: + if (tag !== 250) { + break; + } + + message.groupBy = AggregateRequest_GroupBy.decode(reader, reader.uint32()); + continue; + case 32: + if (tag !== 256) { + break; + } + + message.limit = reader.uint32(); + continue; + case 40: + if (tag !== 322) { + break; + } + + message.filters = Filters.decode(reader, reader.uint32()); + continue; + case 41: + if (tag !== 330) { + break; + } + + message.hybrid = Hybrid.decode(reader, reader.uint32()); + continue; + case 42: + if (tag !== 338) { + break; + } + + message.nearVector = NearVector.decode(reader, reader.uint32()); + continue; + case 43: + if (tag !== 346) { + break; + } + + message.nearObject = NearObject.decode(reader, reader.uint32()); + continue; + case 44: + if (tag !== 354) { + break; + } + + message.nearText = NearTextSearch.decode(reader, reader.uint32()); + continue; + case 45: + if (tag !== 362) { + break; + } + + message.nearImage = NearImageSearch.decode(reader, reader.uint32()); + continue; + case 46: + if (tag !== 370) { + break; + } + + message.nearAudio = NearAudioSearch.decode(reader, reader.uint32()); + continue; + case 47: + if (tag !== 378) { + break; + } + + message.nearVideo = NearVideoSearch.decode(reader, reader.uint32()); + continue; + case 48: + if (tag !== 386) { + break; + } + + message.nearDepth = NearDepthSearch.decode(reader, reader.uint32()); + continue; + case 49: + if (tag !== 394) { + break; + } + + message.nearThermal = NearThermalSearch.decode(reader, reader.uint32()); + continue; + case 50: + if (tag !== 402) { + break; + } + + message.nearImu = NearIMUSearch.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateRequest { + return { + collection: isSet(object.collection) ? globalThis.String(object.collection) : "", + tenant: isSet(object.tenant) ? globalThis.String(object.tenant) : "", + objectsCount: isSet(object.objectsCount) ? globalThis.Boolean(object.objectsCount) : false, + aggregations: globalThis.Array.isArray(object?.aggregations) + ? object.aggregations.map((e: any) => AggregateRequest_Aggregation.fromJSON(e)) + : [], + objectLimit: isSet(object.objectLimit) ? globalThis.Number(object.objectLimit) : undefined, + groupBy: isSet(object.groupBy) ? AggregateRequest_GroupBy.fromJSON(object.groupBy) : undefined, + limit: isSet(object.limit) ? globalThis.Number(object.limit) : undefined, + filters: isSet(object.filters) ? Filters.fromJSON(object.filters) : undefined, + hybrid: isSet(object.hybrid) ? Hybrid.fromJSON(object.hybrid) : undefined, + nearVector: isSet(object.nearVector) ? NearVector.fromJSON(object.nearVector) : undefined, + nearObject: isSet(object.nearObject) ? NearObject.fromJSON(object.nearObject) : undefined, + nearText: isSet(object.nearText) ? NearTextSearch.fromJSON(object.nearText) : undefined, + nearImage: isSet(object.nearImage) ? NearImageSearch.fromJSON(object.nearImage) : undefined, + nearAudio: isSet(object.nearAudio) ? NearAudioSearch.fromJSON(object.nearAudio) : undefined, + nearVideo: isSet(object.nearVideo) ? NearVideoSearch.fromJSON(object.nearVideo) : undefined, + nearDepth: isSet(object.nearDepth) ? NearDepthSearch.fromJSON(object.nearDepth) : undefined, + nearThermal: isSet(object.nearThermal) ? NearThermalSearch.fromJSON(object.nearThermal) : undefined, + nearImu: isSet(object.nearImu) ? NearIMUSearch.fromJSON(object.nearImu) : undefined, + }; + }, + + toJSON(message: AggregateRequest): unknown { + const obj: any = {}; + if (message.collection !== "") { + obj.collection = message.collection; + } + if (message.tenant !== "") { + obj.tenant = message.tenant; + } + if (message.objectsCount !== false) { + obj.objectsCount = message.objectsCount; + } + if (message.aggregations?.length) { + obj.aggregations = message.aggregations.map((e) => AggregateRequest_Aggregation.toJSON(e)); + } + if (message.objectLimit !== undefined) { + obj.objectLimit = Math.round(message.objectLimit); + } + if (message.groupBy !== undefined) { + obj.groupBy = AggregateRequest_GroupBy.toJSON(message.groupBy); + } + if (message.limit !== undefined) { + obj.limit = Math.round(message.limit); + } + if (message.filters !== undefined) { + obj.filters = Filters.toJSON(message.filters); + } + if (message.hybrid !== undefined) { + obj.hybrid = Hybrid.toJSON(message.hybrid); + } + if (message.nearVector !== undefined) { + obj.nearVector = NearVector.toJSON(message.nearVector); + } + if (message.nearObject !== undefined) { + obj.nearObject = NearObject.toJSON(message.nearObject); + } + if (message.nearText !== undefined) { + obj.nearText = NearTextSearch.toJSON(message.nearText); + } + if (message.nearImage !== undefined) { + obj.nearImage = NearImageSearch.toJSON(message.nearImage); + } + if (message.nearAudio !== undefined) { + obj.nearAudio = NearAudioSearch.toJSON(message.nearAudio); + } + if (message.nearVideo !== undefined) { + obj.nearVideo = NearVideoSearch.toJSON(message.nearVideo); + } + if (message.nearDepth !== undefined) { + obj.nearDepth = NearDepthSearch.toJSON(message.nearDepth); + } + if (message.nearThermal !== undefined) { + obj.nearThermal = NearThermalSearch.toJSON(message.nearThermal); + } + if (message.nearImu !== undefined) { + obj.nearImu = NearIMUSearch.toJSON(message.nearImu); + } + return obj; + }, + + create(base?: DeepPartial): AggregateRequest { + return AggregateRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateRequest { + const message = createBaseAggregateRequest(); + message.collection = object.collection ?? ""; + message.tenant = object.tenant ?? ""; + message.objectsCount = object.objectsCount ?? false; + message.aggregations = object.aggregations?.map((e) => AggregateRequest_Aggregation.fromPartial(e)) || []; + message.objectLimit = object.objectLimit ?? undefined; + message.groupBy = (object.groupBy !== undefined && object.groupBy !== null) + ? AggregateRequest_GroupBy.fromPartial(object.groupBy) + : undefined; + message.limit = object.limit ?? undefined; + message.filters = (object.filters !== undefined && object.filters !== null) + ? Filters.fromPartial(object.filters) + : undefined; + message.hybrid = (object.hybrid !== undefined && object.hybrid !== null) + ? Hybrid.fromPartial(object.hybrid) + : undefined; + message.nearVector = (object.nearVector !== undefined && object.nearVector !== null) + ? NearVector.fromPartial(object.nearVector) + : undefined; + message.nearObject = (object.nearObject !== undefined && object.nearObject !== null) + ? NearObject.fromPartial(object.nearObject) + : undefined; + message.nearText = (object.nearText !== undefined && object.nearText !== null) + ? NearTextSearch.fromPartial(object.nearText) + : undefined; + message.nearImage = (object.nearImage !== undefined && object.nearImage !== null) + ? NearImageSearch.fromPartial(object.nearImage) + : undefined; + message.nearAudio = (object.nearAudio !== undefined && object.nearAudio !== null) + ? NearAudioSearch.fromPartial(object.nearAudio) + : undefined; + message.nearVideo = (object.nearVideo !== undefined && object.nearVideo !== null) + ? NearVideoSearch.fromPartial(object.nearVideo) + : undefined; + message.nearDepth = (object.nearDepth !== undefined && object.nearDepth !== null) + ? NearDepthSearch.fromPartial(object.nearDepth) + : undefined; + message.nearThermal = (object.nearThermal !== undefined && object.nearThermal !== null) + ? NearThermalSearch.fromPartial(object.nearThermal) + : undefined; + message.nearImu = (object.nearImu !== undefined && object.nearImu !== null) + ? NearIMUSearch.fromPartial(object.nearImu) + : undefined; + return message; + }, +}; + +function createBaseAggregateRequest_Aggregation(): AggregateRequest_Aggregation { + return { + property: "", + int: undefined, + number: undefined, + text: undefined, + boolean: undefined, + date: undefined, + reference: undefined, + }; +} + +export const AggregateRequest_Aggregation = { + encode(message: AggregateRequest_Aggregation, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.property !== "") { + writer.uint32(10).string(message.property); + } + if (message.int !== undefined) { + AggregateRequest_Aggregation_Integer.encode(message.int, writer.uint32(18).fork()).ldelim(); + } + if (message.number !== undefined) { + AggregateRequest_Aggregation_Number.encode(message.number, writer.uint32(26).fork()).ldelim(); + } + if (message.text !== undefined) { + AggregateRequest_Aggregation_Text.encode(message.text, writer.uint32(34).fork()).ldelim(); + } + if (message.boolean !== undefined) { + AggregateRequest_Aggregation_Boolean.encode(message.boolean, writer.uint32(42).fork()).ldelim(); + } + if (message.date !== undefined) { + AggregateRequest_Aggregation_DateMessage.encode(message.date, writer.uint32(50).fork()).ldelim(); + } + if (message.reference !== undefined) { + AggregateRequest_Aggregation_Reference.encode(message.reference, writer.uint32(58).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateRequest_Aggregation { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateRequest_Aggregation(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.property = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.int = AggregateRequest_Aggregation_Integer.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.number = AggregateRequest_Aggregation_Number.decode(reader, reader.uint32()); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.text = AggregateRequest_Aggregation_Text.decode(reader, reader.uint32()); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.boolean = AggregateRequest_Aggregation_Boolean.decode(reader, reader.uint32()); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.date = AggregateRequest_Aggregation_DateMessage.decode(reader, reader.uint32()); + continue; + case 7: + if (tag !== 58) { + break; + } + + message.reference = AggregateRequest_Aggregation_Reference.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateRequest_Aggregation { + return { + property: isSet(object.property) ? globalThis.String(object.property) : "", + int: isSet(object.int) ? AggregateRequest_Aggregation_Integer.fromJSON(object.int) : undefined, + number: isSet(object.number) ? AggregateRequest_Aggregation_Number.fromJSON(object.number) : undefined, + text: isSet(object.text) ? AggregateRequest_Aggregation_Text.fromJSON(object.text) : undefined, + boolean: isSet(object.boolean) ? AggregateRequest_Aggregation_Boolean.fromJSON(object.boolean) : undefined, + date: isSet(object.date) ? AggregateRequest_Aggregation_DateMessage.fromJSON(object.date) : undefined, + reference: isSet(object.reference) + ? AggregateRequest_Aggregation_Reference.fromJSON(object.reference) + : undefined, + }; + }, + + toJSON(message: AggregateRequest_Aggregation): unknown { + const obj: any = {}; + if (message.property !== "") { + obj.property = message.property; + } + if (message.int !== undefined) { + obj.int = AggregateRequest_Aggregation_Integer.toJSON(message.int); + } + if (message.number !== undefined) { + obj.number = AggregateRequest_Aggregation_Number.toJSON(message.number); + } + if (message.text !== undefined) { + obj.text = AggregateRequest_Aggregation_Text.toJSON(message.text); + } + if (message.boolean !== undefined) { + obj.boolean = AggregateRequest_Aggregation_Boolean.toJSON(message.boolean); + } + if (message.date !== undefined) { + obj.date = AggregateRequest_Aggregation_DateMessage.toJSON(message.date); + } + if (message.reference !== undefined) { + obj.reference = AggregateRequest_Aggregation_Reference.toJSON(message.reference); + } + return obj; + }, + + create(base?: DeepPartial): AggregateRequest_Aggregation { + return AggregateRequest_Aggregation.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateRequest_Aggregation { + const message = createBaseAggregateRequest_Aggregation(); + message.property = object.property ?? ""; + message.int = (object.int !== undefined && object.int !== null) + ? AggregateRequest_Aggregation_Integer.fromPartial(object.int) + : undefined; + message.number = (object.number !== undefined && object.number !== null) + ? AggregateRequest_Aggregation_Number.fromPartial(object.number) + : undefined; + message.text = (object.text !== undefined && object.text !== null) + ? AggregateRequest_Aggregation_Text.fromPartial(object.text) + : undefined; + message.boolean = (object.boolean !== undefined && object.boolean !== null) + ? AggregateRequest_Aggregation_Boolean.fromPartial(object.boolean) + : undefined; + message.date = (object.date !== undefined && object.date !== null) + ? AggregateRequest_Aggregation_DateMessage.fromPartial(object.date) + : undefined; + message.reference = (object.reference !== undefined && object.reference !== null) + ? AggregateRequest_Aggregation_Reference.fromPartial(object.reference) + : undefined; + return message; + }, +}; + +function createBaseAggregateRequest_Aggregation_Integer(): AggregateRequest_Aggregation_Integer { + return { + count: false, + type: false, + sum: false, + mean: false, + mode: false, + median: false, + maximum: false, + minimum: false, + }; +} + +export const AggregateRequest_Aggregation_Integer = { + encode(message: AggregateRequest_Aggregation_Integer, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.count !== false) { + writer.uint32(8).bool(message.count); + } + if (message.type !== false) { + writer.uint32(16).bool(message.type); + } + if (message.sum !== false) { + writer.uint32(24).bool(message.sum); + } + if (message.mean !== false) { + writer.uint32(32).bool(message.mean); + } + if (message.mode !== false) { + writer.uint32(40).bool(message.mode); + } + if (message.median !== false) { + writer.uint32(48).bool(message.median); + } + if (message.maximum !== false) { + writer.uint32(56).bool(message.maximum); + } + if (message.minimum !== false) { + writer.uint32(64).bool(message.minimum); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateRequest_Aggregation_Integer { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateRequest_Aggregation_Integer(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.count = reader.bool(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.type = reader.bool(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.sum = reader.bool(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.mean = reader.bool(); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.mode = reader.bool(); + continue; + case 6: + if (tag !== 48) { + break; + } + + message.median = reader.bool(); + continue; + case 7: + if (tag !== 56) { + break; + } + + message.maximum = reader.bool(); + continue; + case 8: + if (tag !== 64) { + break; + } + + message.minimum = reader.bool(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateRequest_Aggregation_Integer { + return { + count: isSet(object.count) ? globalThis.Boolean(object.count) : false, + type: isSet(object.type) ? globalThis.Boolean(object.type) : false, + sum: isSet(object.sum) ? globalThis.Boolean(object.sum) : false, + mean: isSet(object.mean) ? globalThis.Boolean(object.mean) : false, + mode: isSet(object.mode) ? globalThis.Boolean(object.mode) : false, + median: isSet(object.median) ? globalThis.Boolean(object.median) : false, + maximum: isSet(object.maximum) ? globalThis.Boolean(object.maximum) : false, + minimum: isSet(object.minimum) ? globalThis.Boolean(object.minimum) : false, + }; + }, + + toJSON(message: AggregateRequest_Aggregation_Integer): unknown { + const obj: any = {}; + if (message.count !== false) { + obj.count = message.count; + } + if (message.type !== false) { + obj.type = message.type; + } + if (message.sum !== false) { + obj.sum = message.sum; + } + if (message.mean !== false) { + obj.mean = message.mean; + } + if (message.mode !== false) { + obj.mode = message.mode; + } + if (message.median !== false) { + obj.median = message.median; + } + if (message.maximum !== false) { + obj.maximum = message.maximum; + } + if (message.minimum !== false) { + obj.minimum = message.minimum; + } + return obj; + }, + + create(base?: DeepPartial): AggregateRequest_Aggregation_Integer { + return AggregateRequest_Aggregation_Integer.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateRequest_Aggregation_Integer { + const message = createBaseAggregateRequest_Aggregation_Integer(); + message.count = object.count ?? false; + message.type = object.type ?? false; + message.sum = object.sum ?? false; + message.mean = object.mean ?? false; + message.mode = object.mode ?? false; + message.median = object.median ?? false; + message.maximum = object.maximum ?? false; + message.minimum = object.minimum ?? false; + return message; + }, +}; + +function createBaseAggregateRequest_Aggregation_Number(): AggregateRequest_Aggregation_Number { + return { + count: false, + type: false, + sum: false, + mean: false, + mode: false, + median: false, + maximum: false, + minimum: false, + }; +} + +export const AggregateRequest_Aggregation_Number = { + encode(message: AggregateRequest_Aggregation_Number, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.count !== false) { + writer.uint32(8).bool(message.count); + } + if (message.type !== false) { + writer.uint32(16).bool(message.type); + } + if (message.sum !== false) { + writer.uint32(24).bool(message.sum); + } + if (message.mean !== false) { + writer.uint32(32).bool(message.mean); + } + if (message.mode !== false) { + writer.uint32(40).bool(message.mode); + } + if (message.median !== false) { + writer.uint32(48).bool(message.median); + } + if (message.maximum !== false) { + writer.uint32(56).bool(message.maximum); + } + if (message.minimum !== false) { + writer.uint32(64).bool(message.minimum); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateRequest_Aggregation_Number { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateRequest_Aggregation_Number(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.count = reader.bool(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.type = reader.bool(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.sum = reader.bool(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.mean = reader.bool(); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.mode = reader.bool(); + continue; + case 6: + if (tag !== 48) { + break; + } + + message.median = reader.bool(); + continue; + case 7: + if (tag !== 56) { + break; + } + + message.maximum = reader.bool(); + continue; + case 8: + if (tag !== 64) { + break; + } + + message.minimum = reader.bool(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateRequest_Aggregation_Number { + return { + count: isSet(object.count) ? globalThis.Boolean(object.count) : false, + type: isSet(object.type) ? globalThis.Boolean(object.type) : false, + sum: isSet(object.sum) ? globalThis.Boolean(object.sum) : false, + mean: isSet(object.mean) ? globalThis.Boolean(object.mean) : false, + mode: isSet(object.mode) ? globalThis.Boolean(object.mode) : false, + median: isSet(object.median) ? globalThis.Boolean(object.median) : false, + maximum: isSet(object.maximum) ? globalThis.Boolean(object.maximum) : false, + minimum: isSet(object.minimum) ? globalThis.Boolean(object.minimum) : false, + }; + }, + + toJSON(message: AggregateRequest_Aggregation_Number): unknown { + const obj: any = {}; + if (message.count !== false) { + obj.count = message.count; + } + if (message.type !== false) { + obj.type = message.type; + } + if (message.sum !== false) { + obj.sum = message.sum; + } + if (message.mean !== false) { + obj.mean = message.mean; + } + if (message.mode !== false) { + obj.mode = message.mode; + } + if (message.median !== false) { + obj.median = message.median; + } + if (message.maximum !== false) { + obj.maximum = message.maximum; + } + if (message.minimum !== false) { + obj.minimum = message.minimum; + } + return obj; + }, + + create(base?: DeepPartial): AggregateRequest_Aggregation_Number { + return AggregateRequest_Aggregation_Number.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateRequest_Aggregation_Number { + const message = createBaseAggregateRequest_Aggregation_Number(); + message.count = object.count ?? false; + message.type = object.type ?? false; + message.sum = object.sum ?? false; + message.mean = object.mean ?? false; + message.mode = object.mode ?? false; + message.median = object.median ?? false; + message.maximum = object.maximum ?? false; + message.minimum = object.minimum ?? false; + return message; + }, +}; + +function createBaseAggregateRequest_Aggregation_Text(): AggregateRequest_Aggregation_Text { + return { count: false, type: false, topOccurences: false, topOccurencesLimit: undefined }; +} + +export const AggregateRequest_Aggregation_Text = { + encode(message: AggregateRequest_Aggregation_Text, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.count !== false) { + writer.uint32(8).bool(message.count); + } + if (message.type !== false) { + writer.uint32(16).bool(message.type); + } + if (message.topOccurences !== false) { + writer.uint32(24).bool(message.topOccurences); + } + if (message.topOccurencesLimit !== undefined) { + writer.uint32(32).uint32(message.topOccurencesLimit); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateRequest_Aggregation_Text { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateRequest_Aggregation_Text(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.count = reader.bool(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.type = reader.bool(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.topOccurences = reader.bool(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.topOccurencesLimit = reader.uint32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateRequest_Aggregation_Text { + return { + count: isSet(object.count) ? globalThis.Boolean(object.count) : false, + type: isSet(object.type) ? globalThis.Boolean(object.type) : false, + topOccurences: isSet(object.topOccurences) ? globalThis.Boolean(object.topOccurences) : false, + topOccurencesLimit: isSet(object.topOccurencesLimit) ? globalThis.Number(object.topOccurencesLimit) : undefined, + }; + }, + + toJSON(message: AggregateRequest_Aggregation_Text): unknown { + const obj: any = {}; + if (message.count !== false) { + obj.count = message.count; + } + if (message.type !== false) { + obj.type = message.type; + } + if (message.topOccurences !== false) { + obj.topOccurences = message.topOccurences; + } + if (message.topOccurencesLimit !== undefined) { + obj.topOccurencesLimit = Math.round(message.topOccurencesLimit); + } + return obj; + }, + + create(base?: DeepPartial): AggregateRequest_Aggregation_Text { + return AggregateRequest_Aggregation_Text.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateRequest_Aggregation_Text { + const message = createBaseAggregateRequest_Aggregation_Text(); + message.count = object.count ?? false; + message.type = object.type ?? false; + message.topOccurences = object.topOccurences ?? false; + message.topOccurencesLimit = object.topOccurencesLimit ?? undefined; + return message; + }, +}; + +function createBaseAggregateRequest_Aggregation_Boolean(): AggregateRequest_Aggregation_Boolean { + return { + count: false, + type: false, + totalTrue: false, + totalFalse: false, + percentageTrue: false, + percentageFalse: false, + }; +} + +export const AggregateRequest_Aggregation_Boolean = { + encode(message: AggregateRequest_Aggregation_Boolean, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.count !== false) { + writer.uint32(8).bool(message.count); + } + if (message.type !== false) { + writer.uint32(16).bool(message.type); + } + if (message.totalTrue !== false) { + writer.uint32(24).bool(message.totalTrue); + } + if (message.totalFalse !== false) { + writer.uint32(32).bool(message.totalFalse); + } + if (message.percentageTrue !== false) { + writer.uint32(40).bool(message.percentageTrue); + } + if (message.percentageFalse !== false) { + writer.uint32(48).bool(message.percentageFalse); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateRequest_Aggregation_Boolean { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateRequest_Aggregation_Boolean(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.count = reader.bool(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.type = reader.bool(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.totalTrue = reader.bool(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.totalFalse = reader.bool(); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.percentageTrue = reader.bool(); + continue; + case 6: + if (tag !== 48) { + break; + } + + message.percentageFalse = reader.bool(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateRequest_Aggregation_Boolean { + return { + count: isSet(object.count) ? globalThis.Boolean(object.count) : false, + type: isSet(object.type) ? globalThis.Boolean(object.type) : false, + totalTrue: isSet(object.totalTrue) ? globalThis.Boolean(object.totalTrue) : false, + totalFalse: isSet(object.totalFalse) ? globalThis.Boolean(object.totalFalse) : false, + percentageTrue: isSet(object.percentageTrue) ? globalThis.Boolean(object.percentageTrue) : false, + percentageFalse: isSet(object.percentageFalse) ? globalThis.Boolean(object.percentageFalse) : false, + }; + }, + + toJSON(message: AggregateRequest_Aggregation_Boolean): unknown { + const obj: any = {}; + if (message.count !== false) { + obj.count = message.count; + } + if (message.type !== false) { + obj.type = message.type; + } + if (message.totalTrue !== false) { + obj.totalTrue = message.totalTrue; + } + if (message.totalFalse !== false) { + obj.totalFalse = message.totalFalse; + } + if (message.percentageTrue !== false) { + obj.percentageTrue = message.percentageTrue; + } + if (message.percentageFalse !== false) { + obj.percentageFalse = message.percentageFalse; + } + return obj; + }, + + create(base?: DeepPartial): AggregateRequest_Aggregation_Boolean { + return AggregateRequest_Aggregation_Boolean.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateRequest_Aggregation_Boolean { + const message = createBaseAggregateRequest_Aggregation_Boolean(); + message.count = object.count ?? false; + message.type = object.type ?? false; + message.totalTrue = object.totalTrue ?? false; + message.totalFalse = object.totalFalse ?? false; + message.percentageTrue = object.percentageTrue ?? false; + message.percentageFalse = object.percentageFalse ?? false; + return message; + }, +}; + +function createBaseAggregateRequest_Aggregation_DateMessage(): AggregateRequest_Aggregation_DateMessage { + return { count: false, type: false, median: false, mode: false, maximum: false, minimum: false }; +} + +export const AggregateRequest_Aggregation_DateMessage = { + encode(message: AggregateRequest_Aggregation_DateMessage, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.count !== false) { + writer.uint32(8).bool(message.count); + } + if (message.type !== false) { + writer.uint32(16).bool(message.type); + } + if (message.median !== false) { + writer.uint32(24).bool(message.median); + } + if (message.mode !== false) { + writer.uint32(32).bool(message.mode); + } + if (message.maximum !== false) { + writer.uint32(40).bool(message.maximum); + } + if (message.minimum !== false) { + writer.uint32(48).bool(message.minimum); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateRequest_Aggregation_DateMessage { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateRequest_Aggregation_DateMessage(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.count = reader.bool(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.type = reader.bool(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.median = reader.bool(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.mode = reader.bool(); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.maximum = reader.bool(); + continue; + case 6: + if (tag !== 48) { + break; + } + + message.minimum = reader.bool(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateRequest_Aggregation_DateMessage { + return { + count: isSet(object.count) ? globalThis.Boolean(object.count) : false, + type: isSet(object.type) ? globalThis.Boolean(object.type) : false, + median: isSet(object.median) ? globalThis.Boolean(object.median) : false, + mode: isSet(object.mode) ? globalThis.Boolean(object.mode) : false, + maximum: isSet(object.maximum) ? globalThis.Boolean(object.maximum) : false, + minimum: isSet(object.minimum) ? globalThis.Boolean(object.minimum) : false, + }; + }, + + toJSON(message: AggregateRequest_Aggregation_DateMessage): unknown { + const obj: any = {}; + if (message.count !== false) { + obj.count = message.count; + } + if (message.type !== false) { + obj.type = message.type; + } + if (message.median !== false) { + obj.median = message.median; + } + if (message.mode !== false) { + obj.mode = message.mode; + } + if (message.maximum !== false) { + obj.maximum = message.maximum; + } + if (message.minimum !== false) { + obj.minimum = message.minimum; + } + return obj; + }, + + create(base?: DeepPartial): AggregateRequest_Aggregation_DateMessage { + return AggregateRequest_Aggregation_DateMessage.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateRequest_Aggregation_DateMessage { + const message = createBaseAggregateRequest_Aggregation_DateMessage(); + message.count = object.count ?? false; + message.type = object.type ?? false; + message.median = object.median ?? false; + message.mode = object.mode ?? false; + message.maximum = object.maximum ?? false; + message.minimum = object.minimum ?? false; + return message; + }, +}; + +function createBaseAggregateRequest_Aggregation_Reference(): AggregateRequest_Aggregation_Reference { + return { type: false, pointingTo: false }; +} + +export const AggregateRequest_Aggregation_Reference = { + encode(message: AggregateRequest_Aggregation_Reference, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.type !== false) { + writer.uint32(8).bool(message.type); + } + if (message.pointingTo !== false) { + writer.uint32(16).bool(message.pointingTo); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateRequest_Aggregation_Reference { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateRequest_Aggregation_Reference(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.type = reader.bool(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.pointingTo = reader.bool(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateRequest_Aggregation_Reference { + return { + type: isSet(object.type) ? globalThis.Boolean(object.type) : false, + pointingTo: isSet(object.pointingTo) ? globalThis.Boolean(object.pointingTo) : false, + }; + }, + + toJSON(message: AggregateRequest_Aggregation_Reference): unknown { + const obj: any = {}; + if (message.type !== false) { + obj.type = message.type; + } + if (message.pointingTo !== false) { + obj.pointingTo = message.pointingTo; + } + return obj; + }, + + create(base?: DeepPartial): AggregateRequest_Aggregation_Reference { + return AggregateRequest_Aggregation_Reference.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateRequest_Aggregation_Reference { + const message = createBaseAggregateRequest_Aggregation_Reference(); + message.type = object.type ?? false; + message.pointingTo = object.pointingTo ?? false; + return message; + }, +}; + +function createBaseAggregateRequest_GroupBy(): AggregateRequest_GroupBy { + return { collection: "", property: "" }; +} + +export const AggregateRequest_GroupBy = { + encode(message: AggregateRequest_GroupBy, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.collection !== "") { + writer.uint32(10).string(message.collection); + } + if (message.property !== "") { + writer.uint32(18).string(message.property); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateRequest_GroupBy { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateRequest_GroupBy(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.collection = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.property = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateRequest_GroupBy { + return { + collection: isSet(object.collection) ? globalThis.String(object.collection) : "", + property: isSet(object.property) ? globalThis.String(object.property) : "", + }; + }, + + toJSON(message: AggregateRequest_GroupBy): unknown { + const obj: any = {}; + if (message.collection !== "") { + obj.collection = message.collection; + } + if (message.property !== "") { + obj.property = message.property; + } + return obj; + }, + + create(base?: DeepPartial): AggregateRequest_GroupBy { + return AggregateRequest_GroupBy.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateRequest_GroupBy { + const message = createBaseAggregateRequest_GroupBy(); + message.collection = object.collection ?? ""; + message.property = object.property ?? ""; + return message; + }, +}; + +function createBaseAggregateReply(): AggregateReply { + return { took: 0, singleResult: undefined, groupedResults: undefined }; +} + +export const AggregateReply = { + encode(message: AggregateReply, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.took !== 0) { + writer.uint32(13).float(message.took); + } + if (message.singleResult !== undefined) { + AggregateReply_Single.encode(message.singleResult, writer.uint32(18).fork()).ldelim(); + } + if (message.groupedResults !== undefined) { + AggregateReply_Grouped.encode(message.groupedResults, writer.uint32(26).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateReply { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 13) { + break; + } + + message.took = reader.float(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.singleResult = AggregateReply_Single.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.groupedResults = AggregateReply_Grouped.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply { + return { + took: isSet(object.took) ? globalThis.Number(object.took) : 0, + singleResult: isSet(object.singleResult) ? AggregateReply_Single.fromJSON(object.singleResult) : undefined, + groupedResults: isSet(object.groupedResults) ? AggregateReply_Grouped.fromJSON(object.groupedResults) : undefined, + }; + }, + + toJSON(message: AggregateReply): unknown { + const obj: any = {}; + if (message.took !== 0) { + obj.took = message.took; + } + if (message.singleResult !== undefined) { + obj.singleResult = AggregateReply_Single.toJSON(message.singleResult); + } + if (message.groupedResults !== undefined) { + obj.groupedResults = AggregateReply_Grouped.toJSON(message.groupedResults); + } + return obj; + }, + + create(base?: DeepPartial): AggregateReply { + return AggregateReply.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateReply { + const message = createBaseAggregateReply(); + message.took = object.took ?? 0; + message.singleResult = (object.singleResult !== undefined && object.singleResult !== null) + ? AggregateReply_Single.fromPartial(object.singleResult) + : undefined; + message.groupedResults = (object.groupedResults !== undefined && object.groupedResults !== null) + ? AggregateReply_Grouped.fromPartial(object.groupedResults) + : undefined; + return message; + }, +}; + +function createBaseAggregateReply_Aggregations(): AggregateReply_Aggregations { + return { aggregations: [] }; +} + +export const AggregateReply_Aggregations = { + encode(message: AggregateReply_Aggregations, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + for (const v of message.aggregations) { + AggregateReply_Aggregations_Aggregation.encode(v!, writer.uint32(10).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateReply_Aggregations { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply_Aggregations(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.aggregations.push(AggregateReply_Aggregations_Aggregation.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply_Aggregations { + return { + aggregations: globalThis.Array.isArray(object?.aggregations) + ? object.aggregations.map((e: any) => AggregateReply_Aggregations_Aggregation.fromJSON(e)) + : [], + }; + }, + + toJSON(message: AggregateReply_Aggregations): unknown { + const obj: any = {}; + if (message.aggregations?.length) { + obj.aggregations = message.aggregations.map((e) => AggregateReply_Aggregations_Aggregation.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): AggregateReply_Aggregations { + return AggregateReply_Aggregations.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateReply_Aggregations { + const message = createBaseAggregateReply_Aggregations(); + message.aggregations = object.aggregations?.map((e) => AggregateReply_Aggregations_Aggregation.fromPartial(e)) || + []; + return message; + }, +}; + +function createBaseAggregateReply_Aggregations_Aggregation(): AggregateReply_Aggregations_Aggregation { + return { + property: "", + int: undefined, + number: undefined, + text: undefined, + boolean: undefined, + date: undefined, + reference: undefined, + }; +} + +export const AggregateReply_Aggregations_Aggregation = { + encode(message: AggregateReply_Aggregations_Aggregation, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.property !== "") { + writer.uint32(10).string(message.property); + } + if (message.int !== undefined) { + AggregateReply_Aggregations_Aggregation_Integer.encode(message.int, writer.uint32(18).fork()).ldelim(); + } + if (message.number !== undefined) { + AggregateReply_Aggregations_Aggregation_Number.encode(message.number, writer.uint32(26).fork()).ldelim(); + } + if (message.text !== undefined) { + AggregateReply_Aggregations_Aggregation_Text.encode(message.text, writer.uint32(34).fork()).ldelim(); + } + if (message.boolean !== undefined) { + AggregateReply_Aggregations_Aggregation_Boolean.encode(message.boolean, writer.uint32(42).fork()).ldelim(); + } + if (message.date !== undefined) { + AggregateReply_Aggregations_Aggregation_DateMessage.encode(message.date, writer.uint32(50).fork()).ldelim(); + } + if (message.reference !== undefined) { + AggregateReply_Aggregations_Aggregation_Reference.encode(message.reference, writer.uint32(58).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateReply_Aggregations_Aggregation { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply_Aggregations_Aggregation(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.property = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.int = AggregateReply_Aggregations_Aggregation_Integer.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.number = AggregateReply_Aggregations_Aggregation_Number.decode(reader, reader.uint32()); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.text = AggregateReply_Aggregations_Aggregation_Text.decode(reader, reader.uint32()); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.boolean = AggregateReply_Aggregations_Aggregation_Boolean.decode(reader, reader.uint32()); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.date = AggregateReply_Aggregations_Aggregation_DateMessage.decode(reader, reader.uint32()); + continue; + case 7: + if (tag !== 58) { + break; + } + + message.reference = AggregateReply_Aggregations_Aggregation_Reference.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply_Aggregations_Aggregation { + return { + property: isSet(object.property) ? globalThis.String(object.property) : "", + int: isSet(object.int) ? AggregateReply_Aggregations_Aggregation_Integer.fromJSON(object.int) : undefined, + number: isSet(object.number) ? AggregateReply_Aggregations_Aggregation_Number.fromJSON(object.number) : undefined, + text: isSet(object.text) ? AggregateReply_Aggregations_Aggregation_Text.fromJSON(object.text) : undefined, + boolean: isSet(object.boolean) + ? AggregateReply_Aggregations_Aggregation_Boolean.fromJSON(object.boolean) + : undefined, + date: isSet(object.date) ? AggregateReply_Aggregations_Aggregation_DateMessage.fromJSON(object.date) : undefined, + reference: isSet(object.reference) + ? AggregateReply_Aggregations_Aggregation_Reference.fromJSON(object.reference) + : undefined, + }; + }, + + toJSON(message: AggregateReply_Aggregations_Aggregation): unknown { + const obj: any = {}; + if (message.property !== "") { + obj.property = message.property; + } + if (message.int !== undefined) { + obj.int = AggregateReply_Aggregations_Aggregation_Integer.toJSON(message.int); + } + if (message.number !== undefined) { + obj.number = AggregateReply_Aggregations_Aggregation_Number.toJSON(message.number); + } + if (message.text !== undefined) { + obj.text = AggregateReply_Aggregations_Aggregation_Text.toJSON(message.text); + } + if (message.boolean !== undefined) { + obj.boolean = AggregateReply_Aggregations_Aggregation_Boolean.toJSON(message.boolean); + } + if (message.date !== undefined) { + obj.date = AggregateReply_Aggregations_Aggregation_DateMessage.toJSON(message.date); + } + if (message.reference !== undefined) { + obj.reference = AggregateReply_Aggregations_Aggregation_Reference.toJSON(message.reference); + } + return obj; + }, + + create(base?: DeepPartial): AggregateReply_Aggregations_Aggregation { + return AggregateReply_Aggregations_Aggregation.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateReply_Aggregations_Aggregation { + const message = createBaseAggregateReply_Aggregations_Aggregation(); + message.property = object.property ?? ""; + message.int = (object.int !== undefined && object.int !== null) + ? AggregateReply_Aggregations_Aggregation_Integer.fromPartial(object.int) + : undefined; + message.number = (object.number !== undefined && object.number !== null) + ? AggregateReply_Aggregations_Aggregation_Number.fromPartial(object.number) + : undefined; + message.text = (object.text !== undefined && object.text !== null) + ? AggregateReply_Aggregations_Aggregation_Text.fromPartial(object.text) + : undefined; + message.boolean = (object.boolean !== undefined && object.boolean !== null) + ? AggregateReply_Aggregations_Aggregation_Boolean.fromPartial(object.boolean) + : undefined; + message.date = (object.date !== undefined && object.date !== null) + ? AggregateReply_Aggregations_Aggregation_DateMessage.fromPartial(object.date) + : undefined; + message.reference = (object.reference !== undefined && object.reference !== null) + ? AggregateReply_Aggregations_Aggregation_Reference.fromPartial(object.reference) + : undefined; + return message; + }, +}; + +function createBaseAggregateReply_Aggregations_Aggregation_Integer(): AggregateReply_Aggregations_Aggregation_Integer { + return { + count: undefined, + type: undefined, + mean: undefined, + median: undefined, + mode: undefined, + maximum: undefined, + minimum: undefined, + sum: undefined, + }; +} + +export const AggregateReply_Aggregations_Aggregation_Integer = { + encode( + message: AggregateReply_Aggregations_Aggregation_Integer, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.count !== undefined) { + writer.uint32(8).int64(message.count); + } + if (message.type !== undefined) { + writer.uint32(18).string(message.type); + } + if (message.mean !== undefined) { + writer.uint32(25).double(message.mean); + } + if (message.median !== undefined) { + writer.uint32(33).double(message.median); + } + if (message.mode !== undefined) { + writer.uint32(40).int64(message.mode); + } + if (message.maximum !== undefined) { + writer.uint32(48).int64(message.maximum); + } + if (message.minimum !== undefined) { + writer.uint32(56).int64(message.minimum); + } + if (message.sum !== undefined) { + writer.uint32(64).int64(message.sum); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateReply_Aggregations_Aggregation_Integer { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply_Aggregations_Aggregation_Integer(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.count = longToNumber(reader.int64() as Long); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.type = reader.string(); + continue; + case 3: + if (tag !== 25) { + break; + } + + message.mean = reader.double(); + continue; + case 4: + if (tag !== 33) { + break; + } + + message.median = reader.double(); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.mode = longToNumber(reader.int64() as Long); + continue; + case 6: + if (tag !== 48) { + break; + } + + message.maximum = longToNumber(reader.int64() as Long); + continue; + case 7: + if (tag !== 56) { + break; + } + + message.minimum = longToNumber(reader.int64() as Long); + continue; + case 8: + if (tag !== 64) { + break; + } + + message.sum = longToNumber(reader.int64() as Long); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply_Aggregations_Aggregation_Integer { + return { + count: isSet(object.count) ? globalThis.Number(object.count) : undefined, + type: isSet(object.type) ? globalThis.String(object.type) : undefined, + mean: isSet(object.mean) ? globalThis.Number(object.mean) : undefined, + median: isSet(object.median) ? globalThis.Number(object.median) : undefined, + mode: isSet(object.mode) ? globalThis.Number(object.mode) : undefined, + maximum: isSet(object.maximum) ? globalThis.Number(object.maximum) : undefined, + minimum: isSet(object.minimum) ? globalThis.Number(object.minimum) : undefined, + sum: isSet(object.sum) ? globalThis.Number(object.sum) : undefined, + }; + }, + + toJSON(message: AggregateReply_Aggregations_Aggregation_Integer): unknown { + const obj: any = {}; + if (message.count !== undefined) { + obj.count = Math.round(message.count); + } + if (message.type !== undefined) { + obj.type = message.type; + } + if (message.mean !== undefined) { + obj.mean = message.mean; + } + if (message.median !== undefined) { + obj.median = message.median; + } + if (message.mode !== undefined) { + obj.mode = Math.round(message.mode); + } + if (message.maximum !== undefined) { + obj.maximum = Math.round(message.maximum); + } + if (message.minimum !== undefined) { + obj.minimum = Math.round(message.minimum); + } + if (message.sum !== undefined) { + obj.sum = Math.round(message.sum); + } + return obj; + }, + + create( + base?: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_Integer { + return AggregateReply_Aggregations_Aggregation_Integer.fromPartial(base ?? {}); + }, + fromPartial( + object: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_Integer { + const message = createBaseAggregateReply_Aggregations_Aggregation_Integer(); + message.count = object.count ?? undefined; + message.type = object.type ?? undefined; + message.mean = object.mean ?? undefined; + message.median = object.median ?? undefined; + message.mode = object.mode ?? undefined; + message.maximum = object.maximum ?? undefined; + message.minimum = object.minimum ?? undefined; + message.sum = object.sum ?? undefined; + return message; + }, +}; + +function createBaseAggregateReply_Aggregations_Aggregation_Number(): AggregateReply_Aggregations_Aggregation_Number { + return { + count: undefined, + type: undefined, + mean: undefined, + median: undefined, + mode: undefined, + maximum: undefined, + minimum: undefined, + sum: undefined, + }; +} + +export const AggregateReply_Aggregations_Aggregation_Number = { + encode( + message: AggregateReply_Aggregations_Aggregation_Number, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.count !== undefined) { + writer.uint32(8).int64(message.count); + } + if (message.type !== undefined) { + writer.uint32(18).string(message.type); + } + if (message.mean !== undefined) { + writer.uint32(25).double(message.mean); + } + if (message.median !== undefined) { + writer.uint32(33).double(message.median); + } + if (message.mode !== undefined) { + writer.uint32(41).double(message.mode); + } + if (message.maximum !== undefined) { + writer.uint32(49).double(message.maximum); + } + if (message.minimum !== undefined) { + writer.uint32(57).double(message.minimum); + } + if (message.sum !== undefined) { + writer.uint32(65).double(message.sum); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateReply_Aggregations_Aggregation_Number { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply_Aggregations_Aggregation_Number(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.count = longToNumber(reader.int64() as Long); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.type = reader.string(); + continue; + case 3: + if (tag !== 25) { + break; + } + + message.mean = reader.double(); + continue; + case 4: + if (tag !== 33) { + break; + } + + message.median = reader.double(); + continue; + case 5: + if (tag !== 41) { + break; + } + + message.mode = reader.double(); + continue; + case 6: + if (tag !== 49) { + break; + } + + message.maximum = reader.double(); + continue; + case 7: + if (tag !== 57) { + break; + } + + message.minimum = reader.double(); + continue; + case 8: + if (tag !== 65) { + break; + } + + message.sum = reader.double(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply_Aggregations_Aggregation_Number { + return { + count: isSet(object.count) ? globalThis.Number(object.count) : undefined, + type: isSet(object.type) ? globalThis.String(object.type) : undefined, + mean: isSet(object.mean) ? globalThis.Number(object.mean) : undefined, + median: isSet(object.median) ? globalThis.Number(object.median) : undefined, + mode: isSet(object.mode) ? globalThis.Number(object.mode) : undefined, + maximum: isSet(object.maximum) ? globalThis.Number(object.maximum) : undefined, + minimum: isSet(object.minimum) ? globalThis.Number(object.minimum) : undefined, + sum: isSet(object.sum) ? globalThis.Number(object.sum) : undefined, + }; + }, + + toJSON(message: AggregateReply_Aggregations_Aggregation_Number): unknown { + const obj: any = {}; + if (message.count !== undefined) { + obj.count = Math.round(message.count); + } + if (message.type !== undefined) { + obj.type = message.type; + } + if (message.mean !== undefined) { + obj.mean = message.mean; + } + if (message.median !== undefined) { + obj.median = message.median; + } + if (message.mode !== undefined) { + obj.mode = message.mode; + } + if (message.maximum !== undefined) { + obj.maximum = message.maximum; + } + if (message.minimum !== undefined) { + obj.minimum = message.minimum; + } + if (message.sum !== undefined) { + obj.sum = message.sum; + } + return obj; + }, + + create( + base?: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_Number { + return AggregateReply_Aggregations_Aggregation_Number.fromPartial(base ?? {}); + }, + fromPartial( + object: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_Number { + const message = createBaseAggregateReply_Aggregations_Aggregation_Number(); + message.count = object.count ?? undefined; + message.type = object.type ?? undefined; + message.mean = object.mean ?? undefined; + message.median = object.median ?? undefined; + message.mode = object.mode ?? undefined; + message.maximum = object.maximum ?? undefined; + message.minimum = object.minimum ?? undefined; + message.sum = object.sum ?? undefined; + return message; + }, +}; + +function createBaseAggregateReply_Aggregations_Aggregation_Text(): AggregateReply_Aggregations_Aggregation_Text { + return { count: undefined, type: undefined, topOccurences: undefined }; +} + +export const AggregateReply_Aggregations_Aggregation_Text = { + encode(message: AggregateReply_Aggregations_Aggregation_Text, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.count !== undefined) { + writer.uint32(8).int64(message.count); + } + if (message.type !== undefined) { + writer.uint32(18).string(message.type); + } + if (message.topOccurences !== undefined) { + AggregateReply_Aggregations_Aggregation_Text_TopOccurrences.encode( + message.topOccurences, + writer.uint32(26).fork(), + ).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateReply_Aggregations_Aggregation_Text { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply_Aggregations_Aggregation_Text(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.count = longToNumber(reader.int64() as Long); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.type = reader.string(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.topOccurences = AggregateReply_Aggregations_Aggregation_Text_TopOccurrences.decode( + reader, + reader.uint32(), + ); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply_Aggregations_Aggregation_Text { + return { + count: isSet(object.count) ? globalThis.Number(object.count) : undefined, + type: isSet(object.type) ? globalThis.String(object.type) : undefined, + topOccurences: isSet(object.topOccurences) + ? AggregateReply_Aggregations_Aggregation_Text_TopOccurrences.fromJSON(object.topOccurences) + : undefined, + }; + }, + + toJSON(message: AggregateReply_Aggregations_Aggregation_Text): unknown { + const obj: any = {}; + if (message.count !== undefined) { + obj.count = Math.round(message.count); + } + if (message.type !== undefined) { + obj.type = message.type; + } + if (message.topOccurences !== undefined) { + obj.topOccurences = AggregateReply_Aggregations_Aggregation_Text_TopOccurrences.toJSON(message.topOccurences); + } + return obj; + }, + + create( + base?: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_Text { + return AggregateReply_Aggregations_Aggregation_Text.fromPartial(base ?? {}); + }, + fromPartial( + object: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_Text { + const message = createBaseAggregateReply_Aggregations_Aggregation_Text(); + message.count = object.count ?? undefined; + message.type = object.type ?? undefined; + message.topOccurences = (object.topOccurences !== undefined && object.topOccurences !== null) + ? AggregateReply_Aggregations_Aggregation_Text_TopOccurrences.fromPartial(object.topOccurences) + : undefined; + return message; + }, +}; + +function createBaseAggregateReply_Aggregations_Aggregation_Text_TopOccurrences(): AggregateReply_Aggregations_Aggregation_Text_TopOccurrences { + return { items: [] }; +} + +export const AggregateReply_Aggregations_Aggregation_Text_TopOccurrences = { + encode( + message: AggregateReply_Aggregations_Aggregation_Text_TopOccurrences, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + for (const v of message.items) { + AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence.encode(v!, writer.uint32(10).fork()) + .ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateReply_Aggregations_Aggregation_Text_TopOccurrences { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply_Aggregations_Aggregation_Text_TopOccurrences(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.items.push( + AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence.decode(reader, reader.uint32()), + ); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply_Aggregations_Aggregation_Text_TopOccurrences { + return { + items: globalThis.Array.isArray(object?.items) + ? object.items.map((e: any) => + AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence.fromJSON(e) + ) + : [], + }; + }, + + toJSON(message: AggregateReply_Aggregations_Aggregation_Text_TopOccurrences): unknown { + const obj: any = {}; + if (message.items?.length) { + obj.items = message.items.map((e) => + AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence.toJSON(e) + ); + } + return obj; + }, + + create( + base?: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_Text_TopOccurrences { + return AggregateReply_Aggregations_Aggregation_Text_TopOccurrences.fromPartial(base ?? {}); + }, + fromPartial( + object: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_Text_TopOccurrences { + const message = createBaseAggregateReply_Aggregations_Aggregation_Text_TopOccurrences(); + message.items = + object.items?.map((e) => + AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence.fromPartial(e) + ) || []; + return message; + }, +}; + +function createBaseAggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence(): AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence { + return { value: "", occurs: 0 }; +} + +export const AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence = { + encode( + message: AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.value !== "") { + writer.uint32(10).string(message.value); + } + if (message.occurs !== 0) { + writer.uint32(16).int64(message.occurs); + } + return writer; + }, + + decode( + input: _m0.Reader | Uint8Array, + length?: number, + ): AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.value = reader.string(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.occurs = longToNumber(reader.int64() as Long); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence { + return { + value: isSet(object.value) ? globalThis.String(object.value) : "", + occurs: isSet(object.occurs) ? globalThis.Number(object.occurs) : 0, + }; + }, + + toJSON(message: AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence): unknown { + const obj: any = {}; + if (message.value !== "") { + obj.value = message.value; + } + if (message.occurs !== 0) { + obj.occurs = Math.round(message.occurs); + } + return obj; + }, + + create( + base?: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence { + return AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence.fromPartial(base ?? {}); + }, + fromPartial( + object: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence { + const message = createBaseAggregateReply_Aggregations_Aggregation_Text_TopOccurrences_TopOccurrence(); + message.value = object.value ?? ""; + message.occurs = object.occurs ?? 0; + return message; + }, +}; + +function createBaseAggregateReply_Aggregations_Aggregation_Boolean(): AggregateReply_Aggregations_Aggregation_Boolean { + return { + count: undefined, + type: undefined, + totalTrue: undefined, + totalFalse: undefined, + percentageTrue: undefined, + percentageFalse: undefined, + }; +} + +export const AggregateReply_Aggregations_Aggregation_Boolean = { + encode( + message: AggregateReply_Aggregations_Aggregation_Boolean, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.count !== undefined) { + writer.uint32(8).int64(message.count); + } + if (message.type !== undefined) { + writer.uint32(18).string(message.type); + } + if (message.totalTrue !== undefined) { + writer.uint32(24).int64(message.totalTrue); + } + if (message.totalFalse !== undefined) { + writer.uint32(32).int64(message.totalFalse); + } + if (message.percentageTrue !== undefined) { + writer.uint32(41).double(message.percentageTrue); + } + if (message.percentageFalse !== undefined) { + writer.uint32(49).double(message.percentageFalse); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateReply_Aggregations_Aggregation_Boolean { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply_Aggregations_Aggregation_Boolean(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.count = longToNumber(reader.int64() as Long); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.type = reader.string(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.totalTrue = longToNumber(reader.int64() as Long); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.totalFalse = longToNumber(reader.int64() as Long); + continue; + case 5: + if (tag !== 41) { + break; + } + + message.percentageTrue = reader.double(); + continue; + case 6: + if (tag !== 49) { + break; + } + + message.percentageFalse = reader.double(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply_Aggregations_Aggregation_Boolean { + return { + count: isSet(object.count) ? globalThis.Number(object.count) : undefined, + type: isSet(object.type) ? globalThis.String(object.type) : undefined, + totalTrue: isSet(object.totalTrue) ? globalThis.Number(object.totalTrue) : undefined, + totalFalse: isSet(object.totalFalse) ? globalThis.Number(object.totalFalse) : undefined, + percentageTrue: isSet(object.percentageTrue) ? globalThis.Number(object.percentageTrue) : undefined, + percentageFalse: isSet(object.percentageFalse) ? globalThis.Number(object.percentageFalse) : undefined, + }; + }, + + toJSON(message: AggregateReply_Aggregations_Aggregation_Boolean): unknown { + const obj: any = {}; + if (message.count !== undefined) { + obj.count = Math.round(message.count); + } + if (message.type !== undefined) { + obj.type = message.type; + } + if (message.totalTrue !== undefined) { + obj.totalTrue = Math.round(message.totalTrue); + } + if (message.totalFalse !== undefined) { + obj.totalFalse = Math.round(message.totalFalse); + } + if (message.percentageTrue !== undefined) { + obj.percentageTrue = message.percentageTrue; + } + if (message.percentageFalse !== undefined) { + obj.percentageFalse = message.percentageFalse; + } + return obj; + }, + + create( + base?: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_Boolean { + return AggregateReply_Aggregations_Aggregation_Boolean.fromPartial(base ?? {}); + }, + fromPartial( + object: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_Boolean { + const message = createBaseAggregateReply_Aggregations_Aggregation_Boolean(); + message.count = object.count ?? undefined; + message.type = object.type ?? undefined; + message.totalTrue = object.totalTrue ?? undefined; + message.totalFalse = object.totalFalse ?? undefined; + message.percentageTrue = object.percentageTrue ?? undefined; + message.percentageFalse = object.percentageFalse ?? undefined; + return message; + }, +}; + +function createBaseAggregateReply_Aggregations_Aggregation_DateMessage(): AggregateReply_Aggregations_Aggregation_DateMessage { + return { + count: undefined, + type: undefined, + median: undefined, + mode: undefined, + maximum: undefined, + minimum: undefined, + }; +} + +export const AggregateReply_Aggregations_Aggregation_DateMessage = { + encode( + message: AggregateReply_Aggregations_Aggregation_DateMessage, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.count !== undefined) { + writer.uint32(8).int64(message.count); + } + if (message.type !== undefined) { + writer.uint32(18).string(message.type); + } + if (message.median !== undefined) { + writer.uint32(26).string(message.median); + } + if (message.mode !== undefined) { + writer.uint32(34).string(message.mode); + } + if (message.maximum !== undefined) { + writer.uint32(42).string(message.maximum); + } + if (message.minimum !== undefined) { + writer.uint32(50).string(message.minimum); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateReply_Aggregations_Aggregation_DateMessage { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply_Aggregations_Aggregation_DateMessage(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.count = longToNumber(reader.int64() as Long); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.type = reader.string(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.median = reader.string(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.mode = reader.string(); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.maximum = reader.string(); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.minimum = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply_Aggregations_Aggregation_DateMessage { + return { + count: isSet(object.count) ? globalThis.Number(object.count) : undefined, + type: isSet(object.type) ? globalThis.String(object.type) : undefined, + median: isSet(object.median) ? globalThis.String(object.median) : undefined, + mode: isSet(object.mode) ? globalThis.String(object.mode) : undefined, + maximum: isSet(object.maximum) ? globalThis.String(object.maximum) : undefined, + minimum: isSet(object.minimum) ? globalThis.String(object.minimum) : undefined, + }; + }, + + toJSON(message: AggregateReply_Aggregations_Aggregation_DateMessage): unknown { + const obj: any = {}; + if (message.count !== undefined) { + obj.count = Math.round(message.count); + } + if (message.type !== undefined) { + obj.type = message.type; + } + if (message.median !== undefined) { + obj.median = message.median; + } + if (message.mode !== undefined) { + obj.mode = message.mode; + } + if (message.maximum !== undefined) { + obj.maximum = message.maximum; + } + if (message.minimum !== undefined) { + obj.minimum = message.minimum; + } + return obj; + }, + + create( + base?: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_DateMessage { + return AggregateReply_Aggregations_Aggregation_DateMessage.fromPartial(base ?? {}); + }, + fromPartial( + object: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_DateMessage { + const message = createBaseAggregateReply_Aggregations_Aggregation_DateMessage(); + message.count = object.count ?? undefined; + message.type = object.type ?? undefined; + message.median = object.median ?? undefined; + message.mode = object.mode ?? undefined; + message.maximum = object.maximum ?? undefined; + message.minimum = object.minimum ?? undefined; + return message; + }, +}; + +function createBaseAggregateReply_Aggregations_Aggregation_Reference(): AggregateReply_Aggregations_Aggregation_Reference { + return { type: undefined, pointingTo: [] }; +} + +export const AggregateReply_Aggregations_Aggregation_Reference = { + encode( + message: AggregateReply_Aggregations_Aggregation_Reference, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.type !== undefined) { + writer.uint32(10).string(message.type); + } + for (const v of message.pointingTo) { + writer.uint32(18).string(v!); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateReply_Aggregations_Aggregation_Reference { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply_Aggregations_Aggregation_Reference(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.type = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.pointingTo.push(reader.string()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply_Aggregations_Aggregation_Reference { + return { + type: isSet(object.type) ? globalThis.String(object.type) : undefined, + pointingTo: globalThis.Array.isArray(object?.pointingTo) + ? object.pointingTo.map((e: any) => globalThis.String(e)) + : [], + }; + }, + + toJSON(message: AggregateReply_Aggregations_Aggregation_Reference): unknown { + const obj: any = {}; + if (message.type !== undefined) { + obj.type = message.type; + } + if (message.pointingTo?.length) { + obj.pointingTo = message.pointingTo; + } + return obj; + }, + + create( + base?: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_Reference { + return AggregateReply_Aggregations_Aggregation_Reference.fromPartial(base ?? {}); + }, + fromPartial( + object: DeepPartial, + ): AggregateReply_Aggregations_Aggregation_Reference { + const message = createBaseAggregateReply_Aggregations_Aggregation_Reference(); + message.type = object.type ?? undefined; + message.pointingTo = object.pointingTo?.map((e) => e) || []; + return message; + }, +}; + +function createBaseAggregateReply_Single(): AggregateReply_Single { + return { objectsCount: undefined, aggregations: undefined }; +} + +export const AggregateReply_Single = { + encode(message: AggregateReply_Single, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.objectsCount !== undefined) { + writer.uint32(8).int64(message.objectsCount); + } + if (message.aggregations !== undefined) { + AggregateReply_Aggregations.encode(message.aggregations, writer.uint32(18).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateReply_Single { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply_Single(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.objectsCount = longToNumber(reader.int64() as Long); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.aggregations = AggregateReply_Aggregations.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply_Single { + return { + objectsCount: isSet(object.objectsCount) ? globalThis.Number(object.objectsCount) : undefined, + aggregations: isSet(object.aggregations) ? AggregateReply_Aggregations.fromJSON(object.aggregations) : undefined, + }; + }, + + toJSON(message: AggregateReply_Single): unknown { + const obj: any = {}; + if (message.objectsCount !== undefined) { + obj.objectsCount = Math.round(message.objectsCount); + } + if (message.aggregations !== undefined) { + obj.aggregations = AggregateReply_Aggregations.toJSON(message.aggregations); + } + return obj; + }, + + create(base?: DeepPartial): AggregateReply_Single { + return AggregateReply_Single.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateReply_Single { + const message = createBaseAggregateReply_Single(); + message.objectsCount = object.objectsCount ?? undefined; + message.aggregations = (object.aggregations !== undefined && object.aggregations !== null) + ? AggregateReply_Aggregations.fromPartial(object.aggregations) + : undefined; + return message; + }, +}; + +function createBaseAggregateReply_Group(): AggregateReply_Group { + return { objectsCount: undefined, aggregations: undefined, groupedBy: undefined }; +} + +export const AggregateReply_Group = { + encode(message: AggregateReply_Group, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.objectsCount !== undefined) { + writer.uint32(8).int64(message.objectsCount); + } + if (message.aggregations !== undefined) { + AggregateReply_Aggregations.encode(message.aggregations, writer.uint32(18).fork()).ldelim(); + } + if (message.groupedBy !== undefined) { + AggregateReply_Group_GroupedBy.encode(message.groupedBy, writer.uint32(26).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateReply_Group { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply_Group(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.objectsCount = longToNumber(reader.int64() as Long); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.aggregations = AggregateReply_Aggregations.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.groupedBy = AggregateReply_Group_GroupedBy.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply_Group { + return { + objectsCount: isSet(object.objectsCount) ? globalThis.Number(object.objectsCount) : undefined, + aggregations: isSet(object.aggregations) ? AggregateReply_Aggregations.fromJSON(object.aggregations) : undefined, + groupedBy: isSet(object.groupedBy) ? AggregateReply_Group_GroupedBy.fromJSON(object.groupedBy) : undefined, + }; + }, + + toJSON(message: AggregateReply_Group): unknown { + const obj: any = {}; + if (message.objectsCount !== undefined) { + obj.objectsCount = Math.round(message.objectsCount); + } + if (message.aggregations !== undefined) { + obj.aggregations = AggregateReply_Aggregations.toJSON(message.aggregations); + } + if (message.groupedBy !== undefined) { + obj.groupedBy = AggregateReply_Group_GroupedBy.toJSON(message.groupedBy); + } + return obj; + }, + + create(base?: DeepPartial): AggregateReply_Group { + return AggregateReply_Group.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateReply_Group { + const message = createBaseAggregateReply_Group(); + message.objectsCount = object.objectsCount ?? undefined; + message.aggregations = (object.aggregations !== undefined && object.aggregations !== null) + ? AggregateReply_Aggregations.fromPartial(object.aggregations) + : undefined; + message.groupedBy = (object.groupedBy !== undefined && object.groupedBy !== null) + ? AggregateReply_Group_GroupedBy.fromPartial(object.groupedBy) + : undefined; + return message; + }, +}; + +function createBaseAggregateReply_Group_GroupedBy(): AggregateReply_Group_GroupedBy { + return { + path: [], + text: undefined, + int: undefined, + boolean: undefined, + number: undefined, + texts: undefined, + ints: undefined, + booleans: undefined, + numbers: undefined, + geo: undefined, + }; +} + +export const AggregateReply_Group_GroupedBy = { + encode(message: AggregateReply_Group_GroupedBy, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + for (const v of message.path) { + writer.uint32(10).string(v!); + } + if (message.text !== undefined) { + writer.uint32(18).string(message.text); + } + if (message.int !== undefined) { + writer.uint32(24).int64(message.int); + } + if (message.boolean !== undefined) { + writer.uint32(32).bool(message.boolean); + } + if (message.number !== undefined) { + writer.uint32(41).double(message.number); + } + if (message.texts !== undefined) { + TextArray.encode(message.texts, writer.uint32(50).fork()).ldelim(); + } + if (message.ints !== undefined) { + IntArray.encode(message.ints, writer.uint32(58).fork()).ldelim(); + } + if (message.booleans !== undefined) { + BooleanArray.encode(message.booleans, writer.uint32(66).fork()).ldelim(); + } + if (message.numbers !== undefined) { + NumberArray.encode(message.numbers, writer.uint32(74).fork()).ldelim(); + } + if (message.geo !== undefined) { + GeoCoordinatesFilter.encode(message.geo, writer.uint32(82).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateReply_Group_GroupedBy { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply_Group_GroupedBy(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.path.push(reader.string()); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.text = reader.string(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.int = longToNumber(reader.int64() as Long); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.boolean = reader.bool(); + continue; + case 5: + if (tag !== 41) { + break; + } + + message.number = reader.double(); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.texts = TextArray.decode(reader, reader.uint32()); + continue; + case 7: + if (tag !== 58) { + break; + } + + message.ints = IntArray.decode(reader, reader.uint32()); + continue; + case 8: + if (tag !== 66) { + break; + } + + message.booleans = BooleanArray.decode(reader, reader.uint32()); + continue; + case 9: + if (tag !== 74) { + break; + } + + message.numbers = NumberArray.decode(reader, reader.uint32()); + continue; + case 10: + if (tag !== 82) { + break; + } + + message.geo = GeoCoordinatesFilter.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply_Group_GroupedBy { + return { + path: globalThis.Array.isArray(object?.path) ? object.path.map((e: any) => globalThis.String(e)) : [], + text: isSet(object.text) ? globalThis.String(object.text) : undefined, + int: isSet(object.int) ? globalThis.Number(object.int) : undefined, + boolean: isSet(object.boolean) ? globalThis.Boolean(object.boolean) : undefined, + number: isSet(object.number) ? globalThis.Number(object.number) : undefined, + texts: isSet(object.texts) ? TextArray.fromJSON(object.texts) : undefined, + ints: isSet(object.ints) ? IntArray.fromJSON(object.ints) : undefined, + booleans: isSet(object.booleans) ? BooleanArray.fromJSON(object.booleans) : undefined, + numbers: isSet(object.numbers) ? NumberArray.fromJSON(object.numbers) : undefined, + geo: isSet(object.geo) ? GeoCoordinatesFilter.fromJSON(object.geo) : undefined, + }; + }, + + toJSON(message: AggregateReply_Group_GroupedBy): unknown { + const obj: any = {}; + if (message.path?.length) { + obj.path = message.path; + } + if (message.text !== undefined) { + obj.text = message.text; + } + if (message.int !== undefined) { + obj.int = Math.round(message.int); + } + if (message.boolean !== undefined) { + obj.boolean = message.boolean; + } + if (message.number !== undefined) { + obj.number = message.number; + } + if (message.texts !== undefined) { + obj.texts = TextArray.toJSON(message.texts); + } + if (message.ints !== undefined) { + obj.ints = IntArray.toJSON(message.ints); + } + if (message.booleans !== undefined) { + obj.booleans = BooleanArray.toJSON(message.booleans); + } + if (message.numbers !== undefined) { + obj.numbers = NumberArray.toJSON(message.numbers); + } + if (message.geo !== undefined) { + obj.geo = GeoCoordinatesFilter.toJSON(message.geo); + } + return obj; + }, + + create(base?: DeepPartial): AggregateReply_Group_GroupedBy { + return AggregateReply_Group_GroupedBy.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateReply_Group_GroupedBy { + const message = createBaseAggregateReply_Group_GroupedBy(); + message.path = object.path?.map((e) => e) || []; + message.text = object.text ?? undefined; + message.int = object.int ?? undefined; + message.boolean = object.boolean ?? undefined; + message.number = object.number ?? undefined; + message.texts = (object.texts !== undefined && object.texts !== null) + ? TextArray.fromPartial(object.texts) + : undefined; + message.ints = (object.ints !== undefined && object.ints !== null) ? IntArray.fromPartial(object.ints) : undefined; + message.booleans = (object.booleans !== undefined && object.booleans !== null) + ? BooleanArray.fromPartial(object.booleans) + : undefined; + message.numbers = (object.numbers !== undefined && object.numbers !== null) + ? NumberArray.fromPartial(object.numbers) + : undefined; + message.geo = (object.geo !== undefined && object.geo !== null) + ? GeoCoordinatesFilter.fromPartial(object.geo) + : undefined; + return message; + }, +}; + +function createBaseAggregateReply_Grouped(): AggregateReply_Grouped { + return { groups: [] }; +} + +export const AggregateReply_Grouped = { + encode(message: AggregateReply_Grouped, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + for (const v of message.groups) { + AggregateReply_Group.encode(v!, writer.uint32(10).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AggregateReply_Grouped { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAggregateReply_Grouped(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.groups.push(AggregateReply_Group.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): AggregateReply_Grouped { + return { + groups: globalThis.Array.isArray(object?.groups) + ? object.groups.map((e: any) => AggregateReply_Group.fromJSON(e)) + : [], + }; + }, + + toJSON(message: AggregateReply_Grouped): unknown { + const obj: any = {}; + if (message.groups?.length) { + obj.groups = message.groups.map((e) => AggregateReply_Group.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): AggregateReply_Grouped { + return AggregateReply_Grouped.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AggregateReply_Grouped { + const message = createBaseAggregateReply_Grouped(); + message.groups = object.groups?.map((e) => AggregateReply_Group.fromPartial(e)) || []; + return message; + }, +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +function longToNumber(long: Long): number { + if (long.gt(globalThis.Number.MAX_SAFE_INTEGER)) { + throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER"); + } + return long.toNumber(); +} + +if (_m0.util.Long !== Long) { + _m0.util.Long = Long as any; + _m0.configure(); +} + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} diff --git a/src/proto/v1/base.ts b/src/proto/v1/base.ts index 697a265c..2fcf3464 100644 --- a/src/proto/v1/base.ts +++ b/src/proto/v1/base.ts @@ -278,9 +278,53 @@ export interface GeoCoordinatesFilter { export interface Vectors { name: string; - /** for multi-vec */ + /** + * for multi-vec + * + * @deprecated + */ index: number; vectorBytes: Uint8Array; + type: Vectors_VectorType; +} + +export enum Vectors_VectorType { + VECTOR_TYPE_UNSPECIFIED = 0, + VECTOR_TYPE_SINGLE_FP32 = 1, + VECTOR_TYPE_MULTI_FP32 = 2, + UNRECOGNIZED = -1, +} + +export function vectors_VectorTypeFromJSON(object: any): Vectors_VectorType { + switch (object) { + case 0: + case "VECTOR_TYPE_UNSPECIFIED": + return Vectors_VectorType.VECTOR_TYPE_UNSPECIFIED; + case 1: + case "VECTOR_TYPE_SINGLE_FP32": + return Vectors_VectorType.VECTOR_TYPE_SINGLE_FP32; + case 2: + case "VECTOR_TYPE_MULTI_FP32": + return Vectors_VectorType.VECTOR_TYPE_MULTI_FP32; + case -1: + case "UNRECOGNIZED": + default: + return Vectors_VectorType.UNRECOGNIZED; + } +} + +export function vectors_VectorTypeToJSON(object: Vectors_VectorType): string { + switch (object) { + case Vectors_VectorType.VECTOR_TYPE_UNSPECIFIED: + return "VECTOR_TYPE_UNSPECIFIED"; + case Vectors_VectorType.VECTOR_TYPE_SINGLE_FP32: + return "VECTOR_TYPE_SINGLE_FP32"; + case Vectors_VectorType.VECTOR_TYPE_MULTI_FP32: + return "VECTOR_TYPE_MULTI_FP32"; + case Vectors_VectorType.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } } function createBaseNumberArrayProperties(): NumberArrayProperties { @@ -1933,7 +1977,7 @@ export const GeoCoordinatesFilter = { }; function createBaseVectors(): Vectors { - return { name: "", index: 0, vectorBytes: new Uint8Array(0) }; + return { name: "", index: 0, vectorBytes: new Uint8Array(0), type: 0 }; } export const Vectors = { @@ -1947,6 +1991,9 @@ export const Vectors = { if (message.vectorBytes.length !== 0) { writer.uint32(26).bytes(message.vectorBytes); } + if (message.type !== 0) { + writer.uint32(32).int32(message.type); + } return writer; }, @@ -1978,6 +2025,13 @@ export const Vectors = { message.vectorBytes = reader.bytes(); continue; + case 4: + if (tag !== 32) { + break; + } + + message.type = reader.int32() as any; + continue; } if ((tag & 7) === 4 || tag === 0) { break; @@ -1992,6 +2046,7 @@ export const Vectors = { name: isSet(object.name) ? globalThis.String(object.name) : "", index: isSet(object.index) ? globalThis.Number(object.index) : 0, vectorBytes: isSet(object.vectorBytes) ? bytesFromBase64(object.vectorBytes) : new Uint8Array(0), + type: isSet(object.type) ? vectors_VectorTypeFromJSON(object.type) : 0, }; }, @@ -2006,6 +2061,9 @@ export const Vectors = { if (message.vectorBytes.length !== 0) { obj.vectorBytes = base64FromBytes(message.vectorBytes); } + if (message.type !== 0) { + obj.type = vectors_VectorTypeToJSON(message.type); + } return obj; }, @@ -2017,6 +2075,7 @@ export const Vectors = { message.name = object.name ?? ""; message.index = object.index ?? 0; message.vectorBytes = object.vectorBytes ?? new Uint8Array(0); + message.type = object.type ?? 0; return message; }, }; diff --git a/src/proto/v1/base_search.ts b/src/proto/v1/base_search.ts new file mode 100644 index 00000000..d2e9606a --- /dev/null +++ b/src/proto/v1/base_search.ts @@ -0,0 +1,2507 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v1.176.0 +// protoc v3.19.1 +// source: v1/base_search.proto + +/* eslint-disable */ +import _m0 from "protobufjs/minimal.js"; +import { Vectors } from "./base.js"; + +export const protobufPackage = "weaviate.v1"; + +export enum CombinationMethod { + COMBINATION_METHOD_UNSPECIFIED = 0, + COMBINATION_METHOD_TYPE_SUM = 1, + COMBINATION_METHOD_TYPE_MIN = 2, + COMBINATION_METHOD_TYPE_AVERAGE = 3, + COMBINATION_METHOD_TYPE_RELATIVE_SCORE = 4, + COMBINATION_METHOD_TYPE_MANUAL = 5, + UNRECOGNIZED = -1, +} + +export function combinationMethodFromJSON(object: any): CombinationMethod { + switch (object) { + case 0: + case "COMBINATION_METHOD_UNSPECIFIED": + return CombinationMethod.COMBINATION_METHOD_UNSPECIFIED; + case 1: + case "COMBINATION_METHOD_TYPE_SUM": + return CombinationMethod.COMBINATION_METHOD_TYPE_SUM; + case 2: + case "COMBINATION_METHOD_TYPE_MIN": + return CombinationMethod.COMBINATION_METHOD_TYPE_MIN; + case 3: + case "COMBINATION_METHOD_TYPE_AVERAGE": + return CombinationMethod.COMBINATION_METHOD_TYPE_AVERAGE; + case 4: + case "COMBINATION_METHOD_TYPE_RELATIVE_SCORE": + return CombinationMethod.COMBINATION_METHOD_TYPE_RELATIVE_SCORE; + case 5: + case "COMBINATION_METHOD_TYPE_MANUAL": + return CombinationMethod.COMBINATION_METHOD_TYPE_MANUAL; + case -1: + case "UNRECOGNIZED": + default: + return CombinationMethod.UNRECOGNIZED; + } +} + +export function combinationMethodToJSON(object: CombinationMethod): string { + switch (object) { + case CombinationMethod.COMBINATION_METHOD_UNSPECIFIED: + return "COMBINATION_METHOD_UNSPECIFIED"; + case CombinationMethod.COMBINATION_METHOD_TYPE_SUM: + return "COMBINATION_METHOD_TYPE_SUM"; + case CombinationMethod.COMBINATION_METHOD_TYPE_MIN: + return "COMBINATION_METHOD_TYPE_MIN"; + case CombinationMethod.COMBINATION_METHOD_TYPE_AVERAGE: + return "COMBINATION_METHOD_TYPE_AVERAGE"; + case CombinationMethod.COMBINATION_METHOD_TYPE_RELATIVE_SCORE: + return "COMBINATION_METHOD_TYPE_RELATIVE_SCORE"; + case CombinationMethod.COMBINATION_METHOD_TYPE_MANUAL: + return "COMBINATION_METHOD_TYPE_MANUAL"; + case CombinationMethod.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + +export interface WeightsForTarget { + target: string; + weight: number; +} + +export interface Targets { + targetVectors: string[]; + combination: CombinationMethod; + /** + * deprecated in 1.26.2 - use weights_for_targets + * + * @deprecated + */ + weights: { [key: string]: number }; + weightsForTargets: WeightsForTarget[]; +} + +export interface Targets_WeightsEntry { + key: string; + value: number; +} + +export interface VectorForTarget { + name: string; + /** + * deprecated in 1.29.0 - use vectors + * + * @deprecated + */ + vectorBytes: Uint8Array; + vectors: Vectors[]; +} + +export interface Hybrid { + query: string; + properties: string[]; + /** + * protolint:disable:next REPEATED_FIELD_NAMES_PLURALIZED + * + * @deprecated + */ + vector: number[]; + alpha: number; + fusionType: Hybrid_FusionType; + /** + * deprecated in 1.29.0 - use vectors + * + * @deprecated + */ + vectorBytes: Uint8Array; + /** + * deprecated in 1.26 - use targets + * + * @deprecated + */ + targetVectors: string[]; + /** targets in msg is ignored and should not be set for hybrid */ + nearText: + | NearTextSearch + | undefined; + /** same as above. Use the target vector in the hybrid message */ + nearVector: NearVector | undefined; + targets: Targets | undefined; + vectorDistance?: number | undefined; + vectors: Vectors[]; +} + +export enum Hybrid_FusionType { + FUSION_TYPE_UNSPECIFIED = 0, + FUSION_TYPE_RANKED = 1, + FUSION_TYPE_RELATIVE_SCORE = 2, + UNRECOGNIZED = -1, +} + +export function hybrid_FusionTypeFromJSON(object: any): Hybrid_FusionType { + switch (object) { + case 0: + case "FUSION_TYPE_UNSPECIFIED": + return Hybrid_FusionType.FUSION_TYPE_UNSPECIFIED; + case 1: + case "FUSION_TYPE_RANKED": + return Hybrid_FusionType.FUSION_TYPE_RANKED; + case 2: + case "FUSION_TYPE_RELATIVE_SCORE": + return Hybrid_FusionType.FUSION_TYPE_RELATIVE_SCORE; + case -1: + case "UNRECOGNIZED": + default: + return Hybrid_FusionType.UNRECOGNIZED; + } +} + +export function hybrid_FusionTypeToJSON(object: Hybrid_FusionType): string { + switch (object) { + case Hybrid_FusionType.FUSION_TYPE_UNSPECIFIED: + return "FUSION_TYPE_UNSPECIFIED"; + case Hybrid_FusionType.FUSION_TYPE_RANKED: + return "FUSION_TYPE_RANKED"; + case Hybrid_FusionType.FUSION_TYPE_RELATIVE_SCORE: + return "FUSION_TYPE_RELATIVE_SCORE"; + case Hybrid_FusionType.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + +export interface NearVector { + /** + * protolint:disable:next REPEATED_FIELD_NAMES_PLURALIZED + * + * @deprecated + */ + vector: number[]; + certainty?: number | undefined; + distance?: + | number + | undefined; + /** + * deprecated in 1.29.0 - use vectors + * + * @deprecated + */ + vectorBytes: Uint8Array; + /** + * deprecated in 1.26 - use targets + * + * @deprecated + */ + targetVectors: string[]; + targets: + | Targets + | undefined; + /** + * deprecated in 1.26.2 - use vector_for_targets + * + * @deprecated + */ + vectorPerTarget: { [key: string]: Uint8Array }; + vectorForTargets: VectorForTarget[]; + vectors: Vectors[]; +} + +export interface NearVector_VectorPerTargetEntry { + key: string; + value: Uint8Array; +} + +export interface NearObject { + id: string; + certainty?: number | undefined; + distance?: + | number + | undefined; + /** + * deprecated in 1.26 - use targets + * + * @deprecated + */ + targetVectors: string[]; + targets: Targets | undefined; +} + +export interface NearTextSearch { + /** protolint:disable:next REPEATED_FIELD_NAMES_PLURALIZED */ + query: string[]; + certainty?: number | undefined; + distance?: number | undefined; + moveTo?: NearTextSearch_Move | undefined; + moveAway?: + | NearTextSearch_Move + | undefined; + /** + * deprecated in 1.26 - use targets + * + * @deprecated + */ + targetVectors: string[]; + targets: Targets | undefined; +} + +export interface NearTextSearch_Move { + force: number; + concepts: string[]; + uuids: string[]; +} + +export interface NearImageSearch { + image: string; + certainty?: number | undefined; + distance?: + | number + | undefined; + /** + * deprecated in 1.26 - use targets + * + * @deprecated + */ + targetVectors: string[]; + targets: Targets | undefined; +} + +export interface NearAudioSearch { + audio: string; + certainty?: number | undefined; + distance?: + | number + | undefined; + /** + * deprecated in 1.26 - use targets + * + * @deprecated + */ + targetVectors: string[]; + targets: Targets | undefined; +} + +export interface NearVideoSearch { + video: string; + certainty?: number | undefined; + distance?: + | number + | undefined; + /** + * deprecated in 1.26 - use targets + * + * @deprecated + */ + targetVectors: string[]; + targets: Targets | undefined; +} + +export interface NearDepthSearch { + depth: string; + certainty?: number | undefined; + distance?: + | number + | undefined; + /** + * deprecated in 1.26 - use targets + * + * @deprecated + */ + targetVectors: string[]; + targets: Targets | undefined; +} + +export interface NearThermalSearch { + thermal: string; + certainty?: number | undefined; + distance?: + | number + | undefined; + /** + * deprecated in 1.26 - use targets + * + * @deprecated + */ + targetVectors: string[]; + targets: Targets | undefined; +} + +export interface NearIMUSearch { + imu: string; + certainty?: number | undefined; + distance?: + | number + | undefined; + /** + * deprecated in 1.26 - use targets + * + * @deprecated + */ + targetVectors: string[]; + targets: Targets | undefined; +} + +export interface BM25 { + query: string; + properties: string[]; +} + +function createBaseWeightsForTarget(): WeightsForTarget { + return { target: "", weight: 0 }; +} + +export const WeightsForTarget = { + encode(message: WeightsForTarget, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.target !== "") { + writer.uint32(10).string(message.target); + } + if (message.weight !== 0) { + writer.uint32(21).float(message.weight); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): WeightsForTarget { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseWeightsForTarget(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.target = reader.string(); + continue; + case 2: + if (tag !== 21) { + break; + } + + message.weight = reader.float(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): WeightsForTarget { + return { + target: isSet(object.target) ? globalThis.String(object.target) : "", + weight: isSet(object.weight) ? globalThis.Number(object.weight) : 0, + }; + }, + + toJSON(message: WeightsForTarget): unknown { + const obj: any = {}; + if (message.target !== "") { + obj.target = message.target; + } + if (message.weight !== 0) { + obj.weight = message.weight; + } + return obj; + }, + + create(base?: DeepPartial): WeightsForTarget { + return WeightsForTarget.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): WeightsForTarget { + const message = createBaseWeightsForTarget(); + message.target = object.target ?? ""; + message.weight = object.weight ?? 0; + return message; + }, +}; + +function createBaseTargets(): Targets { + return { targetVectors: [], combination: 0, weights: {}, weightsForTargets: [] }; +} + +export const Targets = { + encode(message: Targets, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + for (const v of message.targetVectors) { + writer.uint32(10).string(v!); + } + if (message.combination !== 0) { + writer.uint32(16).int32(message.combination); + } + Object.entries(message.weights).forEach(([key, value]) => { + Targets_WeightsEntry.encode({ key: key as any, value }, writer.uint32(26).fork()).ldelim(); + }); + for (const v of message.weightsForTargets) { + WeightsForTarget.encode(v!, writer.uint32(34).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): Targets { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseTargets(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.targetVectors.push(reader.string()); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.combination = reader.int32() as any; + continue; + case 3: + if (tag !== 26) { + break; + } + + const entry3 = Targets_WeightsEntry.decode(reader, reader.uint32()); + if (entry3.value !== undefined) { + message.weights[entry3.key] = entry3.value; + } + continue; + case 4: + if (tag !== 34) { + break; + } + + message.weightsForTargets.push(WeightsForTarget.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): Targets { + return { + targetVectors: globalThis.Array.isArray(object?.targetVectors) + ? object.targetVectors.map((e: any) => globalThis.String(e)) + : [], + combination: isSet(object.combination) ? combinationMethodFromJSON(object.combination) : 0, + weights: isObject(object.weights) + ? Object.entries(object.weights).reduce<{ [key: string]: number }>((acc, [key, value]) => { + acc[key] = Number(value); + return acc; + }, {}) + : {}, + weightsForTargets: globalThis.Array.isArray(object?.weightsForTargets) + ? object.weightsForTargets.map((e: any) => WeightsForTarget.fromJSON(e)) + : [], + }; + }, + + toJSON(message: Targets): unknown { + const obj: any = {}; + if (message.targetVectors?.length) { + obj.targetVectors = message.targetVectors; + } + if (message.combination !== 0) { + obj.combination = combinationMethodToJSON(message.combination); + } + if (message.weights) { + const entries = Object.entries(message.weights); + if (entries.length > 0) { + obj.weights = {}; + entries.forEach(([k, v]) => { + obj.weights[k] = v; + }); + } + } + if (message.weightsForTargets?.length) { + obj.weightsForTargets = message.weightsForTargets.map((e) => WeightsForTarget.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): Targets { + return Targets.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): Targets { + const message = createBaseTargets(); + message.targetVectors = object.targetVectors?.map((e) => e) || []; + message.combination = object.combination ?? 0; + message.weights = Object.entries(object.weights ?? {}).reduce<{ [key: string]: number }>((acc, [key, value]) => { + if (value !== undefined) { + acc[key] = globalThis.Number(value); + } + return acc; + }, {}); + message.weightsForTargets = object.weightsForTargets?.map((e) => WeightsForTarget.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseTargets_WeightsEntry(): Targets_WeightsEntry { + return { key: "", value: 0 }; +} + +export const Targets_WeightsEntry = { + encode(message: Targets_WeightsEntry, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.key !== "") { + writer.uint32(10).string(message.key); + } + if (message.value !== 0) { + writer.uint32(21).float(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): Targets_WeightsEntry { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseTargets_WeightsEntry(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.key = reader.string(); + continue; + case 2: + if (tag !== 21) { + break; + } + + message.value = reader.float(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): Targets_WeightsEntry { + return { + key: isSet(object.key) ? globalThis.String(object.key) : "", + value: isSet(object.value) ? globalThis.Number(object.value) : 0, + }; + }, + + toJSON(message: Targets_WeightsEntry): unknown { + const obj: any = {}; + if (message.key !== "") { + obj.key = message.key; + } + if (message.value !== 0) { + obj.value = message.value; + } + return obj; + }, + + create(base?: DeepPartial): Targets_WeightsEntry { + return Targets_WeightsEntry.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): Targets_WeightsEntry { + const message = createBaseTargets_WeightsEntry(); + message.key = object.key ?? ""; + message.value = object.value ?? 0; + return message; + }, +}; + +function createBaseVectorForTarget(): VectorForTarget { + return { name: "", vectorBytes: new Uint8Array(0), vectors: [] }; +} + +export const VectorForTarget = { + encode(message: VectorForTarget, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.name !== "") { + writer.uint32(10).string(message.name); + } + if (message.vectorBytes.length !== 0) { + writer.uint32(18).bytes(message.vectorBytes); + } + for (const v of message.vectors) { + Vectors.encode(v!, writer.uint32(26).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): VectorForTarget { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVectorForTarget(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.name = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.vectorBytes = reader.bytes(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.vectors.push(Vectors.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): VectorForTarget { + return { + name: isSet(object.name) ? globalThis.String(object.name) : "", + vectorBytes: isSet(object.vectorBytes) ? bytesFromBase64(object.vectorBytes) : new Uint8Array(0), + vectors: globalThis.Array.isArray(object?.vectors) ? object.vectors.map((e: any) => Vectors.fromJSON(e)) : [], + }; + }, + + toJSON(message: VectorForTarget): unknown { + const obj: any = {}; + if (message.name !== "") { + obj.name = message.name; + } + if (message.vectorBytes.length !== 0) { + obj.vectorBytes = base64FromBytes(message.vectorBytes); + } + if (message.vectors?.length) { + obj.vectors = message.vectors.map((e) => Vectors.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): VectorForTarget { + return VectorForTarget.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): VectorForTarget { + const message = createBaseVectorForTarget(); + message.name = object.name ?? ""; + message.vectorBytes = object.vectorBytes ?? new Uint8Array(0); + message.vectors = object.vectors?.map((e) => Vectors.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseHybrid(): Hybrid { + return { + query: "", + properties: [], + vector: [], + alpha: 0, + fusionType: 0, + vectorBytes: new Uint8Array(0), + targetVectors: [], + nearText: undefined, + nearVector: undefined, + targets: undefined, + vectorDistance: undefined, + vectors: [], + }; +} + +export const Hybrid = { + encode(message: Hybrid, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.query !== "") { + writer.uint32(10).string(message.query); + } + for (const v of message.properties) { + writer.uint32(18).string(v!); + } + writer.uint32(26).fork(); + for (const v of message.vector) { + writer.float(v); + } + writer.ldelim(); + if (message.alpha !== 0) { + writer.uint32(37).float(message.alpha); + } + if (message.fusionType !== 0) { + writer.uint32(40).int32(message.fusionType); + } + if (message.vectorBytes.length !== 0) { + writer.uint32(50).bytes(message.vectorBytes); + } + for (const v of message.targetVectors) { + writer.uint32(58).string(v!); + } + if (message.nearText !== undefined) { + NearTextSearch.encode(message.nearText, writer.uint32(66).fork()).ldelim(); + } + if (message.nearVector !== undefined) { + NearVector.encode(message.nearVector, writer.uint32(74).fork()).ldelim(); + } + if (message.targets !== undefined) { + Targets.encode(message.targets, writer.uint32(82).fork()).ldelim(); + } + if (message.vectorDistance !== undefined) { + writer.uint32(165).float(message.vectorDistance); + } + for (const v of message.vectors) { + Vectors.encode(v!, writer.uint32(170).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): Hybrid { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHybrid(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.query = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.properties.push(reader.string()); + continue; + case 3: + if (tag === 29) { + message.vector.push(reader.float()); + + continue; + } + + if (tag === 26) { + const end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) { + message.vector.push(reader.float()); + } + + continue; + } + + break; + case 4: + if (tag !== 37) { + break; + } + + message.alpha = reader.float(); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.fusionType = reader.int32() as any; + continue; + case 6: + if (tag !== 50) { + break; + } + + message.vectorBytes = reader.bytes(); + continue; + case 7: + if (tag !== 58) { + break; + } + + message.targetVectors.push(reader.string()); + continue; + case 8: + if (tag !== 66) { + break; + } + + message.nearText = NearTextSearch.decode(reader, reader.uint32()); + continue; + case 9: + if (tag !== 74) { + break; + } + + message.nearVector = NearVector.decode(reader, reader.uint32()); + continue; + case 10: + if (tag !== 82) { + break; + } + + message.targets = Targets.decode(reader, reader.uint32()); + continue; + case 20: + if (tag !== 165) { + break; + } + + message.vectorDistance = reader.float(); + continue; + case 21: + if (tag !== 170) { + break; + } + + message.vectors.push(Vectors.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): Hybrid { + return { + query: isSet(object.query) ? globalThis.String(object.query) : "", + properties: globalThis.Array.isArray(object?.properties) + ? object.properties.map((e: any) => globalThis.String(e)) + : [], + vector: globalThis.Array.isArray(object?.vector) ? object.vector.map((e: any) => globalThis.Number(e)) : [], + alpha: isSet(object.alpha) ? globalThis.Number(object.alpha) : 0, + fusionType: isSet(object.fusionType) ? hybrid_FusionTypeFromJSON(object.fusionType) : 0, + vectorBytes: isSet(object.vectorBytes) ? bytesFromBase64(object.vectorBytes) : new Uint8Array(0), + targetVectors: globalThis.Array.isArray(object?.targetVectors) + ? object.targetVectors.map((e: any) => globalThis.String(e)) + : [], + nearText: isSet(object.nearText) ? NearTextSearch.fromJSON(object.nearText) : undefined, + nearVector: isSet(object.nearVector) ? NearVector.fromJSON(object.nearVector) : undefined, + targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, + vectorDistance: isSet(object.vectorDistance) ? globalThis.Number(object.vectorDistance) : undefined, + vectors: globalThis.Array.isArray(object?.vectors) ? object.vectors.map((e: any) => Vectors.fromJSON(e)) : [], + }; + }, + + toJSON(message: Hybrid): unknown { + const obj: any = {}; + if (message.query !== "") { + obj.query = message.query; + } + if (message.properties?.length) { + obj.properties = message.properties; + } + if (message.vector?.length) { + obj.vector = message.vector; + } + if (message.alpha !== 0) { + obj.alpha = message.alpha; + } + if (message.fusionType !== 0) { + obj.fusionType = hybrid_FusionTypeToJSON(message.fusionType); + } + if (message.vectorBytes.length !== 0) { + obj.vectorBytes = base64FromBytes(message.vectorBytes); + } + if (message.targetVectors?.length) { + obj.targetVectors = message.targetVectors; + } + if (message.nearText !== undefined) { + obj.nearText = NearTextSearch.toJSON(message.nearText); + } + if (message.nearVector !== undefined) { + obj.nearVector = NearVector.toJSON(message.nearVector); + } + if (message.targets !== undefined) { + obj.targets = Targets.toJSON(message.targets); + } + if (message.vectorDistance !== undefined) { + obj.vectorDistance = message.vectorDistance; + } + if (message.vectors?.length) { + obj.vectors = message.vectors.map((e) => Vectors.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): Hybrid { + return Hybrid.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): Hybrid { + const message = createBaseHybrid(); + message.query = object.query ?? ""; + message.properties = object.properties?.map((e) => e) || []; + message.vector = object.vector?.map((e) => e) || []; + message.alpha = object.alpha ?? 0; + message.fusionType = object.fusionType ?? 0; + message.vectorBytes = object.vectorBytes ?? new Uint8Array(0); + message.targetVectors = object.targetVectors?.map((e) => e) || []; + message.nearText = (object.nearText !== undefined && object.nearText !== null) + ? NearTextSearch.fromPartial(object.nearText) + : undefined; + message.nearVector = (object.nearVector !== undefined && object.nearVector !== null) + ? NearVector.fromPartial(object.nearVector) + : undefined; + message.targets = (object.targets !== undefined && object.targets !== null) + ? Targets.fromPartial(object.targets) + : undefined; + message.vectorDistance = object.vectorDistance ?? undefined; + message.vectors = object.vectors?.map((e) => Vectors.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseNearVector(): NearVector { + return { + vector: [], + certainty: undefined, + distance: undefined, + vectorBytes: new Uint8Array(0), + targetVectors: [], + targets: undefined, + vectorPerTarget: {}, + vectorForTargets: [], + vectors: [], + }; +} + +export const NearVector = { + encode(message: NearVector, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + writer.uint32(10).fork(); + for (const v of message.vector) { + writer.float(v); + } + writer.ldelim(); + if (message.certainty !== undefined) { + writer.uint32(17).double(message.certainty); + } + if (message.distance !== undefined) { + writer.uint32(25).double(message.distance); + } + if (message.vectorBytes.length !== 0) { + writer.uint32(34).bytes(message.vectorBytes); + } + for (const v of message.targetVectors) { + writer.uint32(42).string(v!); + } + if (message.targets !== undefined) { + Targets.encode(message.targets, writer.uint32(50).fork()).ldelim(); + } + Object.entries(message.vectorPerTarget).forEach(([key, value]) => { + NearVector_VectorPerTargetEntry.encode({ key: key as any, value }, writer.uint32(58).fork()).ldelim(); + }); + for (const v of message.vectorForTargets) { + VectorForTarget.encode(v!, writer.uint32(66).fork()).ldelim(); + } + for (const v of message.vectors) { + Vectors.encode(v!, writer.uint32(74).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): NearVector { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNearVector(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag === 13) { + message.vector.push(reader.float()); + + continue; + } + + if (tag === 10) { + const end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) { + message.vector.push(reader.float()); + } + + continue; + } + + break; + case 2: + if (tag !== 17) { + break; + } + + message.certainty = reader.double(); + continue; + case 3: + if (tag !== 25) { + break; + } + + message.distance = reader.double(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.vectorBytes = reader.bytes(); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.targetVectors.push(reader.string()); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.targets = Targets.decode(reader, reader.uint32()); + continue; + case 7: + if (tag !== 58) { + break; + } + + const entry7 = NearVector_VectorPerTargetEntry.decode(reader, reader.uint32()); + if (entry7.value !== undefined) { + message.vectorPerTarget[entry7.key] = entry7.value; + } + continue; + case 8: + if (tag !== 66) { + break; + } + + message.vectorForTargets.push(VectorForTarget.decode(reader, reader.uint32())); + continue; + case 9: + if (tag !== 74) { + break; + } + + message.vectors.push(Vectors.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): NearVector { + return { + vector: globalThis.Array.isArray(object?.vector) ? object.vector.map((e: any) => globalThis.Number(e)) : [], + certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, + distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, + vectorBytes: isSet(object.vectorBytes) ? bytesFromBase64(object.vectorBytes) : new Uint8Array(0), + targetVectors: globalThis.Array.isArray(object?.targetVectors) + ? object.targetVectors.map((e: any) => globalThis.String(e)) + : [], + targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, + vectorPerTarget: isObject(object.vectorPerTarget) + ? Object.entries(object.vectorPerTarget).reduce<{ [key: string]: Uint8Array }>((acc, [key, value]) => { + acc[key] = bytesFromBase64(value as string); + return acc; + }, {}) + : {}, + vectorForTargets: globalThis.Array.isArray(object?.vectorForTargets) + ? object.vectorForTargets.map((e: any) => VectorForTarget.fromJSON(e)) + : [], + vectors: globalThis.Array.isArray(object?.vectors) ? object.vectors.map((e: any) => Vectors.fromJSON(e)) : [], + }; + }, + + toJSON(message: NearVector): unknown { + const obj: any = {}; + if (message.vector?.length) { + obj.vector = message.vector; + } + if (message.certainty !== undefined) { + obj.certainty = message.certainty; + } + if (message.distance !== undefined) { + obj.distance = message.distance; + } + if (message.vectorBytes.length !== 0) { + obj.vectorBytes = base64FromBytes(message.vectorBytes); + } + if (message.targetVectors?.length) { + obj.targetVectors = message.targetVectors; + } + if (message.targets !== undefined) { + obj.targets = Targets.toJSON(message.targets); + } + if (message.vectorPerTarget) { + const entries = Object.entries(message.vectorPerTarget); + if (entries.length > 0) { + obj.vectorPerTarget = {}; + entries.forEach(([k, v]) => { + obj.vectorPerTarget[k] = base64FromBytes(v); + }); + } + } + if (message.vectorForTargets?.length) { + obj.vectorForTargets = message.vectorForTargets.map((e) => VectorForTarget.toJSON(e)); + } + if (message.vectors?.length) { + obj.vectors = message.vectors.map((e) => Vectors.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): NearVector { + return NearVector.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): NearVector { + const message = createBaseNearVector(); + message.vector = object.vector?.map((e) => e) || []; + message.certainty = object.certainty ?? undefined; + message.distance = object.distance ?? undefined; + message.vectorBytes = object.vectorBytes ?? new Uint8Array(0); + message.targetVectors = object.targetVectors?.map((e) => e) || []; + message.targets = (object.targets !== undefined && object.targets !== null) + ? Targets.fromPartial(object.targets) + : undefined; + message.vectorPerTarget = Object.entries(object.vectorPerTarget ?? {}).reduce<{ [key: string]: Uint8Array }>( + (acc, [key, value]) => { + if (value !== undefined) { + acc[key] = value; + } + return acc; + }, + {}, + ); + message.vectorForTargets = object.vectorForTargets?.map((e) => VectorForTarget.fromPartial(e)) || []; + message.vectors = object.vectors?.map((e) => Vectors.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseNearVector_VectorPerTargetEntry(): NearVector_VectorPerTargetEntry { + return { key: "", value: new Uint8Array(0) }; +} + +export const NearVector_VectorPerTargetEntry = { + encode(message: NearVector_VectorPerTargetEntry, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.key !== "") { + writer.uint32(10).string(message.key); + } + if (message.value.length !== 0) { + writer.uint32(18).bytes(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): NearVector_VectorPerTargetEntry { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNearVector_VectorPerTargetEntry(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.key = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.value = reader.bytes(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): NearVector_VectorPerTargetEntry { + return { + key: isSet(object.key) ? globalThis.String(object.key) : "", + value: isSet(object.value) ? bytesFromBase64(object.value) : new Uint8Array(0), + }; + }, + + toJSON(message: NearVector_VectorPerTargetEntry): unknown { + const obj: any = {}; + if (message.key !== "") { + obj.key = message.key; + } + if (message.value.length !== 0) { + obj.value = base64FromBytes(message.value); + } + return obj; + }, + + create(base?: DeepPartial): NearVector_VectorPerTargetEntry { + return NearVector_VectorPerTargetEntry.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): NearVector_VectorPerTargetEntry { + const message = createBaseNearVector_VectorPerTargetEntry(); + message.key = object.key ?? ""; + message.value = object.value ?? new Uint8Array(0); + return message; + }, +}; + +function createBaseNearObject(): NearObject { + return { id: "", certainty: undefined, distance: undefined, targetVectors: [], targets: undefined }; +} + +export const NearObject = { + encode(message: NearObject, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.certainty !== undefined) { + writer.uint32(17).double(message.certainty); + } + if (message.distance !== undefined) { + writer.uint32(25).double(message.distance); + } + for (const v of message.targetVectors) { + writer.uint32(34).string(v!); + } + if (message.targets !== undefined) { + Targets.encode(message.targets, writer.uint32(42).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): NearObject { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNearObject(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.id = reader.string(); + continue; + case 2: + if (tag !== 17) { + break; + } + + message.certainty = reader.double(); + continue; + case 3: + if (tag !== 25) { + break; + } + + message.distance = reader.double(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.targetVectors.push(reader.string()); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.targets = Targets.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): NearObject { + return { + id: isSet(object.id) ? globalThis.String(object.id) : "", + certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, + distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, + targetVectors: globalThis.Array.isArray(object?.targetVectors) + ? object.targetVectors.map((e: any) => globalThis.String(e)) + : [], + targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, + }; + }, + + toJSON(message: NearObject): unknown { + const obj: any = {}; + if (message.id !== "") { + obj.id = message.id; + } + if (message.certainty !== undefined) { + obj.certainty = message.certainty; + } + if (message.distance !== undefined) { + obj.distance = message.distance; + } + if (message.targetVectors?.length) { + obj.targetVectors = message.targetVectors; + } + if (message.targets !== undefined) { + obj.targets = Targets.toJSON(message.targets); + } + return obj; + }, + + create(base?: DeepPartial): NearObject { + return NearObject.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): NearObject { + const message = createBaseNearObject(); + message.id = object.id ?? ""; + message.certainty = object.certainty ?? undefined; + message.distance = object.distance ?? undefined; + message.targetVectors = object.targetVectors?.map((e) => e) || []; + message.targets = (object.targets !== undefined && object.targets !== null) + ? Targets.fromPartial(object.targets) + : undefined; + return message; + }, +}; + +function createBaseNearTextSearch(): NearTextSearch { + return { + query: [], + certainty: undefined, + distance: undefined, + moveTo: undefined, + moveAway: undefined, + targetVectors: [], + targets: undefined, + }; +} + +export const NearTextSearch = { + encode(message: NearTextSearch, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + for (const v of message.query) { + writer.uint32(10).string(v!); + } + if (message.certainty !== undefined) { + writer.uint32(17).double(message.certainty); + } + if (message.distance !== undefined) { + writer.uint32(25).double(message.distance); + } + if (message.moveTo !== undefined) { + NearTextSearch_Move.encode(message.moveTo, writer.uint32(34).fork()).ldelim(); + } + if (message.moveAway !== undefined) { + NearTextSearch_Move.encode(message.moveAway, writer.uint32(42).fork()).ldelim(); + } + for (const v of message.targetVectors) { + writer.uint32(50).string(v!); + } + if (message.targets !== undefined) { + Targets.encode(message.targets, writer.uint32(58).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): NearTextSearch { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNearTextSearch(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.query.push(reader.string()); + continue; + case 2: + if (tag !== 17) { + break; + } + + message.certainty = reader.double(); + continue; + case 3: + if (tag !== 25) { + break; + } + + message.distance = reader.double(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.moveTo = NearTextSearch_Move.decode(reader, reader.uint32()); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.moveAway = NearTextSearch_Move.decode(reader, reader.uint32()); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.targetVectors.push(reader.string()); + continue; + case 7: + if (tag !== 58) { + break; + } + + message.targets = Targets.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): NearTextSearch { + return { + query: globalThis.Array.isArray(object?.query) ? object.query.map((e: any) => globalThis.String(e)) : [], + certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, + distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, + moveTo: isSet(object.moveTo) ? NearTextSearch_Move.fromJSON(object.moveTo) : undefined, + moveAway: isSet(object.moveAway) ? NearTextSearch_Move.fromJSON(object.moveAway) : undefined, + targetVectors: globalThis.Array.isArray(object?.targetVectors) + ? object.targetVectors.map((e: any) => globalThis.String(e)) + : [], + targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, + }; + }, + + toJSON(message: NearTextSearch): unknown { + const obj: any = {}; + if (message.query?.length) { + obj.query = message.query; + } + if (message.certainty !== undefined) { + obj.certainty = message.certainty; + } + if (message.distance !== undefined) { + obj.distance = message.distance; + } + if (message.moveTo !== undefined) { + obj.moveTo = NearTextSearch_Move.toJSON(message.moveTo); + } + if (message.moveAway !== undefined) { + obj.moveAway = NearTextSearch_Move.toJSON(message.moveAway); + } + if (message.targetVectors?.length) { + obj.targetVectors = message.targetVectors; + } + if (message.targets !== undefined) { + obj.targets = Targets.toJSON(message.targets); + } + return obj; + }, + + create(base?: DeepPartial): NearTextSearch { + return NearTextSearch.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): NearTextSearch { + const message = createBaseNearTextSearch(); + message.query = object.query?.map((e) => e) || []; + message.certainty = object.certainty ?? undefined; + message.distance = object.distance ?? undefined; + message.moveTo = (object.moveTo !== undefined && object.moveTo !== null) + ? NearTextSearch_Move.fromPartial(object.moveTo) + : undefined; + message.moveAway = (object.moveAway !== undefined && object.moveAway !== null) + ? NearTextSearch_Move.fromPartial(object.moveAway) + : undefined; + message.targetVectors = object.targetVectors?.map((e) => e) || []; + message.targets = (object.targets !== undefined && object.targets !== null) + ? Targets.fromPartial(object.targets) + : undefined; + return message; + }, +}; + +function createBaseNearTextSearch_Move(): NearTextSearch_Move { + return { force: 0, concepts: [], uuids: [] }; +} + +export const NearTextSearch_Move = { + encode(message: NearTextSearch_Move, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.force !== 0) { + writer.uint32(13).float(message.force); + } + for (const v of message.concepts) { + writer.uint32(18).string(v!); + } + for (const v of message.uuids) { + writer.uint32(26).string(v!); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): NearTextSearch_Move { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNearTextSearch_Move(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 13) { + break; + } + + message.force = reader.float(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.concepts.push(reader.string()); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.uuids.push(reader.string()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): NearTextSearch_Move { + return { + force: isSet(object.force) ? globalThis.Number(object.force) : 0, + concepts: globalThis.Array.isArray(object?.concepts) ? object.concepts.map((e: any) => globalThis.String(e)) : [], + uuids: globalThis.Array.isArray(object?.uuids) ? object.uuids.map((e: any) => globalThis.String(e)) : [], + }; + }, + + toJSON(message: NearTextSearch_Move): unknown { + const obj: any = {}; + if (message.force !== 0) { + obj.force = message.force; + } + if (message.concepts?.length) { + obj.concepts = message.concepts; + } + if (message.uuids?.length) { + obj.uuids = message.uuids; + } + return obj; + }, + + create(base?: DeepPartial): NearTextSearch_Move { + return NearTextSearch_Move.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): NearTextSearch_Move { + const message = createBaseNearTextSearch_Move(); + message.force = object.force ?? 0; + message.concepts = object.concepts?.map((e) => e) || []; + message.uuids = object.uuids?.map((e) => e) || []; + return message; + }, +}; + +function createBaseNearImageSearch(): NearImageSearch { + return { image: "", certainty: undefined, distance: undefined, targetVectors: [], targets: undefined }; +} + +export const NearImageSearch = { + encode(message: NearImageSearch, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.image !== "") { + writer.uint32(10).string(message.image); + } + if (message.certainty !== undefined) { + writer.uint32(17).double(message.certainty); + } + if (message.distance !== undefined) { + writer.uint32(25).double(message.distance); + } + for (const v of message.targetVectors) { + writer.uint32(34).string(v!); + } + if (message.targets !== undefined) { + Targets.encode(message.targets, writer.uint32(42).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): NearImageSearch { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNearImageSearch(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.image = reader.string(); + continue; + case 2: + if (tag !== 17) { + break; + } + + message.certainty = reader.double(); + continue; + case 3: + if (tag !== 25) { + break; + } + + message.distance = reader.double(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.targetVectors.push(reader.string()); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.targets = Targets.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): NearImageSearch { + return { + image: isSet(object.image) ? globalThis.String(object.image) : "", + certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, + distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, + targetVectors: globalThis.Array.isArray(object?.targetVectors) + ? object.targetVectors.map((e: any) => globalThis.String(e)) + : [], + targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, + }; + }, + + toJSON(message: NearImageSearch): unknown { + const obj: any = {}; + if (message.image !== "") { + obj.image = message.image; + } + if (message.certainty !== undefined) { + obj.certainty = message.certainty; + } + if (message.distance !== undefined) { + obj.distance = message.distance; + } + if (message.targetVectors?.length) { + obj.targetVectors = message.targetVectors; + } + if (message.targets !== undefined) { + obj.targets = Targets.toJSON(message.targets); + } + return obj; + }, + + create(base?: DeepPartial): NearImageSearch { + return NearImageSearch.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): NearImageSearch { + const message = createBaseNearImageSearch(); + message.image = object.image ?? ""; + message.certainty = object.certainty ?? undefined; + message.distance = object.distance ?? undefined; + message.targetVectors = object.targetVectors?.map((e) => e) || []; + message.targets = (object.targets !== undefined && object.targets !== null) + ? Targets.fromPartial(object.targets) + : undefined; + return message; + }, +}; + +function createBaseNearAudioSearch(): NearAudioSearch { + return { audio: "", certainty: undefined, distance: undefined, targetVectors: [], targets: undefined }; +} + +export const NearAudioSearch = { + encode(message: NearAudioSearch, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.audio !== "") { + writer.uint32(10).string(message.audio); + } + if (message.certainty !== undefined) { + writer.uint32(17).double(message.certainty); + } + if (message.distance !== undefined) { + writer.uint32(25).double(message.distance); + } + for (const v of message.targetVectors) { + writer.uint32(34).string(v!); + } + if (message.targets !== undefined) { + Targets.encode(message.targets, writer.uint32(42).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): NearAudioSearch { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNearAudioSearch(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.audio = reader.string(); + continue; + case 2: + if (tag !== 17) { + break; + } + + message.certainty = reader.double(); + continue; + case 3: + if (tag !== 25) { + break; + } + + message.distance = reader.double(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.targetVectors.push(reader.string()); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.targets = Targets.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): NearAudioSearch { + return { + audio: isSet(object.audio) ? globalThis.String(object.audio) : "", + certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, + distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, + targetVectors: globalThis.Array.isArray(object?.targetVectors) + ? object.targetVectors.map((e: any) => globalThis.String(e)) + : [], + targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, + }; + }, + + toJSON(message: NearAudioSearch): unknown { + const obj: any = {}; + if (message.audio !== "") { + obj.audio = message.audio; + } + if (message.certainty !== undefined) { + obj.certainty = message.certainty; + } + if (message.distance !== undefined) { + obj.distance = message.distance; + } + if (message.targetVectors?.length) { + obj.targetVectors = message.targetVectors; + } + if (message.targets !== undefined) { + obj.targets = Targets.toJSON(message.targets); + } + return obj; + }, + + create(base?: DeepPartial): NearAudioSearch { + return NearAudioSearch.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): NearAudioSearch { + const message = createBaseNearAudioSearch(); + message.audio = object.audio ?? ""; + message.certainty = object.certainty ?? undefined; + message.distance = object.distance ?? undefined; + message.targetVectors = object.targetVectors?.map((e) => e) || []; + message.targets = (object.targets !== undefined && object.targets !== null) + ? Targets.fromPartial(object.targets) + : undefined; + return message; + }, +}; + +function createBaseNearVideoSearch(): NearVideoSearch { + return { video: "", certainty: undefined, distance: undefined, targetVectors: [], targets: undefined }; +} + +export const NearVideoSearch = { + encode(message: NearVideoSearch, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.video !== "") { + writer.uint32(10).string(message.video); + } + if (message.certainty !== undefined) { + writer.uint32(17).double(message.certainty); + } + if (message.distance !== undefined) { + writer.uint32(25).double(message.distance); + } + for (const v of message.targetVectors) { + writer.uint32(34).string(v!); + } + if (message.targets !== undefined) { + Targets.encode(message.targets, writer.uint32(42).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): NearVideoSearch { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNearVideoSearch(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.video = reader.string(); + continue; + case 2: + if (tag !== 17) { + break; + } + + message.certainty = reader.double(); + continue; + case 3: + if (tag !== 25) { + break; + } + + message.distance = reader.double(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.targetVectors.push(reader.string()); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.targets = Targets.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): NearVideoSearch { + return { + video: isSet(object.video) ? globalThis.String(object.video) : "", + certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, + distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, + targetVectors: globalThis.Array.isArray(object?.targetVectors) + ? object.targetVectors.map((e: any) => globalThis.String(e)) + : [], + targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, + }; + }, + + toJSON(message: NearVideoSearch): unknown { + const obj: any = {}; + if (message.video !== "") { + obj.video = message.video; + } + if (message.certainty !== undefined) { + obj.certainty = message.certainty; + } + if (message.distance !== undefined) { + obj.distance = message.distance; + } + if (message.targetVectors?.length) { + obj.targetVectors = message.targetVectors; + } + if (message.targets !== undefined) { + obj.targets = Targets.toJSON(message.targets); + } + return obj; + }, + + create(base?: DeepPartial): NearVideoSearch { + return NearVideoSearch.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): NearVideoSearch { + const message = createBaseNearVideoSearch(); + message.video = object.video ?? ""; + message.certainty = object.certainty ?? undefined; + message.distance = object.distance ?? undefined; + message.targetVectors = object.targetVectors?.map((e) => e) || []; + message.targets = (object.targets !== undefined && object.targets !== null) + ? Targets.fromPartial(object.targets) + : undefined; + return message; + }, +}; + +function createBaseNearDepthSearch(): NearDepthSearch { + return { depth: "", certainty: undefined, distance: undefined, targetVectors: [], targets: undefined }; +} + +export const NearDepthSearch = { + encode(message: NearDepthSearch, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.depth !== "") { + writer.uint32(10).string(message.depth); + } + if (message.certainty !== undefined) { + writer.uint32(17).double(message.certainty); + } + if (message.distance !== undefined) { + writer.uint32(25).double(message.distance); + } + for (const v of message.targetVectors) { + writer.uint32(34).string(v!); + } + if (message.targets !== undefined) { + Targets.encode(message.targets, writer.uint32(42).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): NearDepthSearch { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNearDepthSearch(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.depth = reader.string(); + continue; + case 2: + if (tag !== 17) { + break; + } + + message.certainty = reader.double(); + continue; + case 3: + if (tag !== 25) { + break; + } + + message.distance = reader.double(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.targetVectors.push(reader.string()); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.targets = Targets.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): NearDepthSearch { + return { + depth: isSet(object.depth) ? globalThis.String(object.depth) : "", + certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, + distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, + targetVectors: globalThis.Array.isArray(object?.targetVectors) + ? object.targetVectors.map((e: any) => globalThis.String(e)) + : [], + targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, + }; + }, + + toJSON(message: NearDepthSearch): unknown { + const obj: any = {}; + if (message.depth !== "") { + obj.depth = message.depth; + } + if (message.certainty !== undefined) { + obj.certainty = message.certainty; + } + if (message.distance !== undefined) { + obj.distance = message.distance; + } + if (message.targetVectors?.length) { + obj.targetVectors = message.targetVectors; + } + if (message.targets !== undefined) { + obj.targets = Targets.toJSON(message.targets); + } + return obj; + }, + + create(base?: DeepPartial): NearDepthSearch { + return NearDepthSearch.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): NearDepthSearch { + const message = createBaseNearDepthSearch(); + message.depth = object.depth ?? ""; + message.certainty = object.certainty ?? undefined; + message.distance = object.distance ?? undefined; + message.targetVectors = object.targetVectors?.map((e) => e) || []; + message.targets = (object.targets !== undefined && object.targets !== null) + ? Targets.fromPartial(object.targets) + : undefined; + return message; + }, +}; + +function createBaseNearThermalSearch(): NearThermalSearch { + return { thermal: "", certainty: undefined, distance: undefined, targetVectors: [], targets: undefined }; +} + +export const NearThermalSearch = { + encode(message: NearThermalSearch, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.thermal !== "") { + writer.uint32(10).string(message.thermal); + } + if (message.certainty !== undefined) { + writer.uint32(17).double(message.certainty); + } + if (message.distance !== undefined) { + writer.uint32(25).double(message.distance); + } + for (const v of message.targetVectors) { + writer.uint32(34).string(v!); + } + if (message.targets !== undefined) { + Targets.encode(message.targets, writer.uint32(42).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): NearThermalSearch { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNearThermalSearch(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.thermal = reader.string(); + continue; + case 2: + if (tag !== 17) { + break; + } + + message.certainty = reader.double(); + continue; + case 3: + if (tag !== 25) { + break; + } + + message.distance = reader.double(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.targetVectors.push(reader.string()); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.targets = Targets.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): NearThermalSearch { + return { + thermal: isSet(object.thermal) ? globalThis.String(object.thermal) : "", + certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, + distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, + targetVectors: globalThis.Array.isArray(object?.targetVectors) + ? object.targetVectors.map((e: any) => globalThis.String(e)) + : [], + targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, + }; + }, + + toJSON(message: NearThermalSearch): unknown { + const obj: any = {}; + if (message.thermal !== "") { + obj.thermal = message.thermal; + } + if (message.certainty !== undefined) { + obj.certainty = message.certainty; + } + if (message.distance !== undefined) { + obj.distance = message.distance; + } + if (message.targetVectors?.length) { + obj.targetVectors = message.targetVectors; + } + if (message.targets !== undefined) { + obj.targets = Targets.toJSON(message.targets); + } + return obj; + }, + + create(base?: DeepPartial): NearThermalSearch { + return NearThermalSearch.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): NearThermalSearch { + const message = createBaseNearThermalSearch(); + message.thermal = object.thermal ?? ""; + message.certainty = object.certainty ?? undefined; + message.distance = object.distance ?? undefined; + message.targetVectors = object.targetVectors?.map((e) => e) || []; + message.targets = (object.targets !== undefined && object.targets !== null) + ? Targets.fromPartial(object.targets) + : undefined; + return message; + }, +}; + +function createBaseNearIMUSearch(): NearIMUSearch { + return { imu: "", certainty: undefined, distance: undefined, targetVectors: [], targets: undefined }; +} + +export const NearIMUSearch = { + encode(message: NearIMUSearch, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.imu !== "") { + writer.uint32(10).string(message.imu); + } + if (message.certainty !== undefined) { + writer.uint32(17).double(message.certainty); + } + if (message.distance !== undefined) { + writer.uint32(25).double(message.distance); + } + for (const v of message.targetVectors) { + writer.uint32(34).string(v!); + } + if (message.targets !== undefined) { + Targets.encode(message.targets, writer.uint32(42).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): NearIMUSearch { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNearIMUSearch(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.imu = reader.string(); + continue; + case 2: + if (tag !== 17) { + break; + } + + message.certainty = reader.double(); + continue; + case 3: + if (tag !== 25) { + break; + } + + message.distance = reader.double(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.targetVectors.push(reader.string()); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.targets = Targets.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): NearIMUSearch { + return { + imu: isSet(object.imu) ? globalThis.String(object.imu) : "", + certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, + distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, + targetVectors: globalThis.Array.isArray(object?.targetVectors) + ? object.targetVectors.map((e: any) => globalThis.String(e)) + : [], + targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, + }; + }, + + toJSON(message: NearIMUSearch): unknown { + const obj: any = {}; + if (message.imu !== "") { + obj.imu = message.imu; + } + if (message.certainty !== undefined) { + obj.certainty = message.certainty; + } + if (message.distance !== undefined) { + obj.distance = message.distance; + } + if (message.targetVectors?.length) { + obj.targetVectors = message.targetVectors; + } + if (message.targets !== undefined) { + obj.targets = Targets.toJSON(message.targets); + } + return obj; + }, + + create(base?: DeepPartial): NearIMUSearch { + return NearIMUSearch.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): NearIMUSearch { + const message = createBaseNearIMUSearch(); + message.imu = object.imu ?? ""; + message.certainty = object.certainty ?? undefined; + message.distance = object.distance ?? undefined; + message.targetVectors = object.targetVectors?.map((e) => e) || []; + message.targets = (object.targets !== undefined && object.targets !== null) + ? Targets.fromPartial(object.targets) + : undefined; + return message; + }, +}; + +function createBaseBM25(): BM25 { + return { query: "", properties: [] }; +} + +export const BM25 = { + encode(message: BM25, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.query !== "") { + writer.uint32(10).string(message.query); + } + for (const v of message.properties) { + writer.uint32(18).string(v!); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): BM25 { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBM25(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.query = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.properties.push(reader.string()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): BM25 { + return { + query: isSet(object.query) ? globalThis.String(object.query) : "", + properties: globalThis.Array.isArray(object?.properties) + ? object.properties.map((e: any) => globalThis.String(e)) + : [], + }; + }, + + toJSON(message: BM25): unknown { + const obj: any = {}; + if (message.query !== "") { + obj.query = message.query; + } + if (message.properties?.length) { + obj.properties = message.properties; + } + return obj; + }, + + create(base?: DeepPartial): BM25 { + return BM25.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): BM25 { + const message = createBaseBM25(); + message.query = object.query ?? ""; + message.properties = object.properties?.map((e) => e) || []; + return message; + }, +}; + +function bytesFromBase64(b64: string): Uint8Array { + if ((globalThis as any).Buffer) { + return Uint8Array.from(globalThis.Buffer.from(b64, "base64")); + } else { + const bin = globalThis.atob(b64); + const arr = new Uint8Array(bin.length); + for (let i = 0; i < bin.length; ++i) { + arr[i] = bin.charCodeAt(i); + } + return arr; + } +} + +function base64FromBytes(arr: Uint8Array): string { + if ((globalThis as any).Buffer) { + return globalThis.Buffer.from(arr).toString("base64"); + } else { + const bin: string[] = []; + arr.forEach((byte) => { + bin.push(globalThis.String.fromCharCode(byte)); + }); + return globalThis.btoa(bin.join("")); + } +} + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +function isObject(value: any): boolean { + return typeof value === "object" && value !== null; +} + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} diff --git a/src/proto/v1/search_get.ts b/src/proto/v1/search_get.ts index 979279c2..a3726d8e 100644 --- a/src/proto/v1/search_get.ts +++ b/src/proto/v1/search_get.ts @@ -21,68 +21,24 @@ import { TextArrayProperties, Vectors, } from "./base.js"; +import { + BM25, + Hybrid, + NearAudioSearch, + NearDepthSearch, + NearImageSearch, + NearIMUSearch, + NearObject, + NearTextSearch, + NearThermalSearch, + NearVector, + NearVideoSearch, +} from "./base_search.js"; import { GenerativeReply, GenerativeResult, GenerativeSearch } from "./generative.js"; import { Properties } from "./properties.js"; export const protobufPackage = "weaviate.v1"; -export enum CombinationMethod { - COMBINATION_METHOD_UNSPECIFIED = 0, - COMBINATION_METHOD_TYPE_SUM = 1, - COMBINATION_METHOD_TYPE_MIN = 2, - COMBINATION_METHOD_TYPE_AVERAGE = 3, - COMBINATION_METHOD_TYPE_RELATIVE_SCORE = 4, - COMBINATION_METHOD_TYPE_MANUAL = 5, - UNRECOGNIZED = -1, -} - -export function combinationMethodFromJSON(object: any): CombinationMethod { - switch (object) { - case 0: - case "COMBINATION_METHOD_UNSPECIFIED": - return CombinationMethod.COMBINATION_METHOD_UNSPECIFIED; - case 1: - case "COMBINATION_METHOD_TYPE_SUM": - return CombinationMethod.COMBINATION_METHOD_TYPE_SUM; - case 2: - case "COMBINATION_METHOD_TYPE_MIN": - return CombinationMethod.COMBINATION_METHOD_TYPE_MIN; - case 3: - case "COMBINATION_METHOD_TYPE_AVERAGE": - return CombinationMethod.COMBINATION_METHOD_TYPE_AVERAGE; - case 4: - case "COMBINATION_METHOD_TYPE_RELATIVE_SCORE": - return CombinationMethod.COMBINATION_METHOD_TYPE_RELATIVE_SCORE; - case 5: - case "COMBINATION_METHOD_TYPE_MANUAL": - return CombinationMethod.COMBINATION_METHOD_TYPE_MANUAL; - case -1: - case "UNRECOGNIZED": - default: - return CombinationMethod.UNRECOGNIZED; - } -} - -export function combinationMethodToJSON(object: CombinationMethod): string { - switch (object) { - case CombinationMethod.COMBINATION_METHOD_UNSPECIFIED: - return "COMBINATION_METHOD_UNSPECIFIED"; - case CombinationMethod.COMBINATION_METHOD_TYPE_SUM: - return "COMBINATION_METHOD_TYPE_SUM"; - case CombinationMethod.COMBINATION_METHOD_TYPE_MIN: - return "COMBINATION_METHOD_TYPE_MIN"; - case CombinationMethod.COMBINATION_METHOD_TYPE_AVERAGE: - return "COMBINATION_METHOD_TYPE_AVERAGE"; - case CombinationMethod.COMBINATION_METHOD_TYPE_RELATIVE_SCORE: - return "COMBINATION_METHOD_TYPE_RELATIVE_SCORE"; - case CombinationMethod.COMBINATION_METHOD_TYPE_MANUAL: - return "COMBINATION_METHOD_TYPE_MANUAL"; - case CombinationMethod.UNRECOGNIZED: - default: - return "UNRECOGNIZED"; - } -} - export interface SearchRequest { /** required */ collection: string; @@ -176,214 +132,6 @@ export interface ObjectPropertiesRequest { objectProperties: ObjectPropertiesRequest[]; } -export interface WeightsForTarget { - target: string; - weight: number; -} - -export interface Targets { - targetVectors: string[]; - combination: CombinationMethod; - /** - * deprecated in 1.26.2 - use weights_for_targets - * - * @deprecated - */ - weights: { [key: string]: number }; - weightsForTargets: WeightsForTarget[]; -} - -export interface Targets_WeightsEntry { - key: string; - value: number; -} - -export interface Hybrid { - query: string; - properties: string[]; - /** - * protolint:disable:next REPEATED_FIELD_NAMES_PLURALIZED - * - * @deprecated - */ - vector: number[]; - alpha: number; - fusionType: Hybrid_FusionType; - vectorBytes: Uint8Array; - /** - * deprecated in 1.26 - use targets - * - * @deprecated - */ - targetVectors: string[]; - /** targets in msg is ignored and should not be set for hybrid */ - nearText: - | NearTextSearch - | undefined; - /** same as above. Use the target vector in the hybrid message */ - nearVector: NearVector | undefined; - targets: Targets | undefined; - vectorDistance?: number | undefined; -} - -export enum Hybrid_FusionType { - FUSION_TYPE_UNSPECIFIED = 0, - FUSION_TYPE_RANKED = 1, - FUSION_TYPE_RELATIVE_SCORE = 2, - UNRECOGNIZED = -1, -} - -export function hybrid_FusionTypeFromJSON(object: any): Hybrid_FusionType { - switch (object) { - case 0: - case "FUSION_TYPE_UNSPECIFIED": - return Hybrid_FusionType.FUSION_TYPE_UNSPECIFIED; - case 1: - case "FUSION_TYPE_RANKED": - return Hybrid_FusionType.FUSION_TYPE_RANKED; - case 2: - case "FUSION_TYPE_RELATIVE_SCORE": - return Hybrid_FusionType.FUSION_TYPE_RELATIVE_SCORE; - case -1: - case "UNRECOGNIZED": - default: - return Hybrid_FusionType.UNRECOGNIZED; - } -} - -export function hybrid_FusionTypeToJSON(object: Hybrid_FusionType): string { - switch (object) { - case Hybrid_FusionType.FUSION_TYPE_UNSPECIFIED: - return "FUSION_TYPE_UNSPECIFIED"; - case Hybrid_FusionType.FUSION_TYPE_RANKED: - return "FUSION_TYPE_RANKED"; - case Hybrid_FusionType.FUSION_TYPE_RELATIVE_SCORE: - return "FUSION_TYPE_RELATIVE_SCORE"; - case Hybrid_FusionType.UNRECOGNIZED: - default: - return "UNRECOGNIZED"; - } -} - -export interface NearTextSearch { - /** protolint:disable:next REPEATED_FIELD_NAMES_PLURALIZED */ - query: string[]; - certainty?: number | undefined; - distance?: number | undefined; - moveTo?: NearTextSearch_Move | undefined; - moveAway?: - | NearTextSearch_Move - | undefined; - /** - * deprecated in 1.26 - use targets - * - * @deprecated - */ - targetVectors: string[]; - targets: Targets | undefined; -} - -export interface NearTextSearch_Move { - force: number; - concepts: string[]; - uuids: string[]; -} - -export interface NearImageSearch { - image: string; - certainty?: number | undefined; - distance?: - | number - | undefined; - /** - * deprecated in 1.26 - use targets - * - * @deprecated - */ - targetVectors: string[]; - targets: Targets | undefined; -} - -export interface NearAudioSearch { - audio: string; - certainty?: number | undefined; - distance?: - | number - | undefined; - /** - * deprecated in 1.26 - use targets - * - * @deprecated - */ - targetVectors: string[]; - targets: Targets | undefined; -} - -export interface NearVideoSearch { - video: string; - certainty?: number | undefined; - distance?: - | number - | undefined; - /** - * deprecated in 1.26 - use targets - * - * @deprecated - */ - targetVectors: string[]; - targets: Targets | undefined; -} - -export interface NearDepthSearch { - depth: string; - certainty?: number | undefined; - distance?: - | number - | undefined; - /** - * deprecated in 1.26 - use targets - * - * @deprecated - */ - targetVectors: string[]; - targets: Targets | undefined; -} - -export interface NearThermalSearch { - thermal: string; - certainty?: number | undefined; - distance?: - | number - | undefined; - /** - * deprecated in 1.26 - use targets - * - * @deprecated - */ - targetVectors: string[]; - targets: Targets | undefined; -} - -export interface NearIMUSearch { - imu: string; - certainty?: number | undefined; - distance?: - | number - | undefined; - /** - * deprecated in 1.26 - use targets - * - * @deprecated - */ - targetVectors: string[]; - targets: Targets | undefined; -} - -export interface BM25 { - query: string; - properties: string[]; -} - export interface RefPropertiesRequest { referenceProperty: string; properties: PropertiesRequest | undefined; @@ -391,59 +139,6 @@ export interface RefPropertiesRequest { targetCollection: string; } -export interface VectorForTarget { - name: string; - vectorBytes: Uint8Array; -} - -export interface NearVector { - /** - * protolint:disable:next REPEATED_FIELD_NAMES_PLURALIZED - * - * @deprecated - */ - vector: number[]; - certainty?: number | undefined; - distance?: number | undefined; - vectorBytes: Uint8Array; - /** - * deprecated in 1.26 - use targets - * - * @deprecated - */ - targetVectors: string[]; - targets: - | Targets - | undefined; - /** - * deprecated in 1.26.2 - use vector_for_targets - * - * @deprecated - */ - vectorPerTarget: { [key: string]: Uint8Array }; - vectorForTargets: VectorForTarget[]; -} - -export interface NearVector_VectorPerTargetEntry { - key: string; - value: Uint8Array; -} - -export interface NearObject { - id: string; - certainty?: number | undefined; - distance?: - | number - | undefined; - /** - * deprecated in 1.26 - use targets - * - * @deprecated - */ - targetVectors: string[]; - targets: Targets | undefined; -} - export interface Rerank { property: string; query?: string | undefined; @@ -1646,105 +1341,31 @@ export const ObjectPropertiesRequest = { }, }; -function createBaseWeightsForTarget(): WeightsForTarget { - return { target: "", weight: 0 }; +function createBaseRefPropertiesRequest(): RefPropertiesRequest { + return { referenceProperty: "", properties: undefined, metadata: undefined, targetCollection: "" }; } -export const WeightsForTarget = { - encode(message: WeightsForTarget, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.target !== "") { - writer.uint32(10).string(message.target); - } - if (message.weight !== 0) { - writer.uint32(21).float(message.weight); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): WeightsForTarget { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseWeightsForTarget(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.target = reader.string(); - continue; - case 2: - if (tag !== 21) { - break; - } - - message.weight = reader.float(); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): WeightsForTarget { - return { - target: isSet(object.target) ? globalThis.String(object.target) : "", - weight: isSet(object.weight) ? globalThis.Number(object.weight) : 0, - }; - }, - - toJSON(message: WeightsForTarget): unknown { - const obj: any = {}; - if (message.target !== "") { - obj.target = message.target; - } - if (message.weight !== 0) { - obj.weight = message.weight; +export const RefPropertiesRequest = { + encode(message: RefPropertiesRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.referenceProperty !== "") { + writer.uint32(10).string(message.referenceProperty); } - return obj; - }, - - create(base?: DeepPartial): WeightsForTarget { - return WeightsForTarget.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): WeightsForTarget { - const message = createBaseWeightsForTarget(); - message.target = object.target ?? ""; - message.weight = object.weight ?? 0; - return message; - }, -}; - -function createBaseTargets(): Targets { - return { targetVectors: [], combination: 0, weights: {}, weightsForTargets: [] }; -} - -export const Targets = { - encode(message: Targets, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - for (const v of message.targetVectors) { - writer.uint32(10).string(v!); + if (message.properties !== undefined) { + PropertiesRequest.encode(message.properties, writer.uint32(18).fork()).ldelim(); } - if (message.combination !== 0) { - writer.uint32(16).int32(message.combination); + if (message.metadata !== undefined) { + MetadataRequest.encode(message.metadata, writer.uint32(26).fork()).ldelim(); } - Object.entries(message.weights).forEach(([key, value]) => { - Targets_WeightsEntry.encode({ key: key as any, value }, writer.uint32(26).fork()).ldelim(); - }); - for (const v of message.weightsForTargets) { - WeightsForTarget.encode(v!, writer.uint32(34).fork()).ldelim(); + if (message.targetCollection !== "") { + writer.uint32(34).string(message.targetCollection); } return writer; }, - decode(input: _m0.Reader | Uint8Array, length?: number): Targets { + decode(input: _m0.Reader | Uint8Array, length?: number): RefPropertiesRequest { const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseTargets(); + const message = createBaseRefPropertiesRequest(); while (reader.pos < end) { const tag = reader.uint32(); switch (tag >>> 3) { @@ -1753,31 +1374,28 @@ export const Targets = { break; } - message.targetVectors.push(reader.string()); + message.referenceProperty = reader.string(); continue; case 2: - if (tag !== 16) { + if (tag !== 18) { break; } - message.combination = reader.int32() as any; + message.properties = PropertiesRequest.decode(reader, reader.uint32()); continue; case 3: if (tag !== 26) { break; } - const entry3 = Targets_WeightsEntry.decode(reader, reader.uint32()); - if (entry3.value !== undefined) { - message.weights[entry3.key] = entry3.value; - } + message.metadata = MetadataRequest.decode(reader, reader.uint32()); continue; case 4: if (tag !== 34) { break; } - message.weightsForTargets.push(WeightsForTarget.decode(reader, reader.uint32())); + message.targetCollection = reader.string(); continue; } if ((tag & 7) === 4 || tag === 0) { @@ -1788,2038 +1406,45 @@ export const Targets = { return message; }, - fromJSON(object: any): Targets { + fromJSON(object: any): RefPropertiesRequest { return { - targetVectors: globalThis.Array.isArray(object?.targetVectors) - ? object.targetVectors.map((e: any) => globalThis.String(e)) - : [], - combination: isSet(object.combination) ? combinationMethodFromJSON(object.combination) : 0, - weights: isObject(object.weights) - ? Object.entries(object.weights).reduce<{ [key: string]: number }>((acc, [key, value]) => { - acc[key] = Number(value); - return acc; - }, {}) - : {}, - weightsForTargets: globalThis.Array.isArray(object?.weightsForTargets) - ? object.weightsForTargets.map((e: any) => WeightsForTarget.fromJSON(e)) - : [], + referenceProperty: isSet(object.referenceProperty) ? globalThis.String(object.referenceProperty) : "", + properties: isSet(object.properties) ? PropertiesRequest.fromJSON(object.properties) : undefined, + metadata: isSet(object.metadata) ? MetadataRequest.fromJSON(object.metadata) : undefined, + targetCollection: isSet(object.targetCollection) ? globalThis.String(object.targetCollection) : "", }; }, - toJSON(message: Targets): unknown { + toJSON(message: RefPropertiesRequest): unknown { const obj: any = {}; - if (message.targetVectors?.length) { - obj.targetVectors = message.targetVectors; - } - if (message.combination !== 0) { - obj.combination = combinationMethodToJSON(message.combination); - } - if (message.weights) { - const entries = Object.entries(message.weights); - if (entries.length > 0) { - obj.weights = {}; - entries.forEach(([k, v]) => { - obj.weights[k] = v; - }); - } + if (message.referenceProperty !== "") { + obj.referenceProperty = message.referenceProperty; } - if (message.weightsForTargets?.length) { - obj.weightsForTargets = message.weightsForTargets.map((e) => WeightsForTarget.toJSON(e)); + if (message.properties !== undefined) { + obj.properties = PropertiesRequest.toJSON(message.properties); } - return obj; - }, - - create(base?: DeepPartial): Targets { - return Targets.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): Targets { - const message = createBaseTargets(); - message.targetVectors = object.targetVectors?.map((e) => e) || []; - message.combination = object.combination ?? 0; - message.weights = Object.entries(object.weights ?? {}).reduce<{ [key: string]: number }>((acc, [key, value]) => { - if (value !== undefined) { - acc[key] = globalThis.Number(value); - } - return acc; - }, {}); - message.weightsForTargets = object.weightsForTargets?.map((e) => WeightsForTarget.fromPartial(e)) || []; - return message; - }, -}; - -function createBaseTargets_WeightsEntry(): Targets_WeightsEntry { - return { key: "", value: 0 }; -} - -export const Targets_WeightsEntry = { - encode(message: Targets_WeightsEntry, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.key !== "") { - writer.uint32(10).string(message.key); + if (message.metadata !== undefined) { + obj.metadata = MetadataRequest.toJSON(message.metadata); } - if (message.value !== 0) { - writer.uint32(21).float(message.value); + if (message.targetCollection !== "") { + obj.targetCollection = message.targetCollection; } - return writer; + return obj; }, - decode(input: _m0.Reader | Uint8Array, length?: number): Targets_WeightsEntry { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseTargets_WeightsEntry(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.key = reader.string(); - continue; - case 2: - if (tag !== 21) { - break; - } - - message.value = reader.float(); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; + create(base?: DeepPartial): RefPropertiesRequest { + return RefPropertiesRequest.fromPartial(base ?? {}); }, - - fromJSON(object: any): Targets_WeightsEntry { - return { - key: isSet(object.key) ? globalThis.String(object.key) : "", - value: isSet(object.value) ? globalThis.Number(object.value) : 0, - }; - }, - - toJSON(message: Targets_WeightsEntry): unknown { - const obj: any = {}; - if (message.key !== "") { - obj.key = message.key; - } - if (message.value !== 0) { - obj.value = message.value; - } - return obj; - }, - - create(base?: DeepPartial): Targets_WeightsEntry { - return Targets_WeightsEntry.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): Targets_WeightsEntry { - const message = createBaseTargets_WeightsEntry(); - message.key = object.key ?? ""; - message.value = object.value ?? 0; - return message; - }, -}; - -function createBaseHybrid(): Hybrid { - return { - query: "", - properties: [], - vector: [], - alpha: 0, - fusionType: 0, - vectorBytes: new Uint8Array(0), - targetVectors: [], - nearText: undefined, - nearVector: undefined, - targets: undefined, - vectorDistance: undefined, - }; -} - -export const Hybrid = { - encode(message: Hybrid, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.query !== "") { - writer.uint32(10).string(message.query); - } - for (const v of message.properties) { - writer.uint32(18).string(v!); - } - writer.uint32(26).fork(); - for (const v of message.vector) { - writer.float(v); - } - writer.ldelim(); - if (message.alpha !== 0) { - writer.uint32(37).float(message.alpha); - } - if (message.fusionType !== 0) { - writer.uint32(40).int32(message.fusionType); - } - if (message.vectorBytes.length !== 0) { - writer.uint32(50).bytes(message.vectorBytes); - } - for (const v of message.targetVectors) { - writer.uint32(58).string(v!); - } - if (message.nearText !== undefined) { - NearTextSearch.encode(message.nearText, writer.uint32(66).fork()).ldelim(); - } - if (message.nearVector !== undefined) { - NearVector.encode(message.nearVector, writer.uint32(74).fork()).ldelim(); - } - if (message.targets !== undefined) { - Targets.encode(message.targets, writer.uint32(82).fork()).ldelim(); - } - if (message.vectorDistance !== undefined) { - writer.uint32(165).float(message.vectorDistance); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): Hybrid { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseHybrid(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.query = reader.string(); - continue; - case 2: - if (tag !== 18) { - break; - } - - message.properties.push(reader.string()); - continue; - case 3: - if (tag === 29) { - message.vector.push(reader.float()); - - continue; - } - - if (tag === 26) { - const end2 = reader.uint32() + reader.pos; - while (reader.pos < end2) { - message.vector.push(reader.float()); - } - - continue; - } - - break; - case 4: - if (tag !== 37) { - break; - } - - message.alpha = reader.float(); - continue; - case 5: - if (tag !== 40) { - break; - } - - message.fusionType = reader.int32() as any; - continue; - case 6: - if (tag !== 50) { - break; - } - - message.vectorBytes = reader.bytes(); - continue; - case 7: - if (tag !== 58) { - break; - } - - message.targetVectors.push(reader.string()); - continue; - case 8: - if (tag !== 66) { - break; - } - - message.nearText = NearTextSearch.decode(reader, reader.uint32()); - continue; - case 9: - if (tag !== 74) { - break; - } - - message.nearVector = NearVector.decode(reader, reader.uint32()); - continue; - case 10: - if (tag !== 82) { - break; - } - - message.targets = Targets.decode(reader, reader.uint32()); - continue; - case 20: - if (tag !== 165) { - break; - } - - message.vectorDistance = reader.float(); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): Hybrid { - return { - query: isSet(object.query) ? globalThis.String(object.query) : "", - properties: globalThis.Array.isArray(object?.properties) - ? object.properties.map((e: any) => globalThis.String(e)) - : [], - vector: globalThis.Array.isArray(object?.vector) ? object.vector.map((e: any) => globalThis.Number(e)) : [], - alpha: isSet(object.alpha) ? globalThis.Number(object.alpha) : 0, - fusionType: isSet(object.fusionType) ? hybrid_FusionTypeFromJSON(object.fusionType) : 0, - vectorBytes: isSet(object.vectorBytes) ? bytesFromBase64(object.vectorBytes) : new Uint8Array(0), - targetVectors: globalThis.Array.isArray(object?.targetVectors) - ? object.targetVectors.map((e: any) => globalThis.String(e)) - : [], - nearText: isSet(object.nearText) ? NearTextSearch.fromJSON(object.nearText) : undefined, - nearVector: isSet(object.nearVector) ? NearVector.fromJSON(object.nearVector) : undefined, - targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, - vectorDistance: isSet(object.vectorDistance) ? globalThis.Number(object.vectorDistance) : undefined, - }; - }, - - toJSON(message: Hybrid): unknown { - const obj: any = {}; - if (message.query !== "") { - obj.query = message.query; - } - if (message.properties?.length) { - obj.properties = message.properties; - } - if (message.vector?.length) { - obj.vector = message.vector; - } - if (message.alpha !== 0) { - obj.alpha = message.alpha; - } - if (message.fusionType !== 0) { - obj.fusionType = hybrid_FusionTypeToJSON(message.fusionType); - } - if (message.vectorBytes.length !== 0) { - obj.vectorBytes = base64FromBytes(message.vectorBytes); - } - if (message.targetVectors?.length) { - obj.targetVectors = message.targetVectors; - } - if (message.nearText !== undefined) { - obj.nearText = NearTextSearch.toJSON(message.nearText); - } - if (message.nearVector !== undefined) { - obj.nearVector = NearVector.toJSON(message.nearVector); - } - if (message.targets !== undefined) { - obj.targets = Targets.toJSON(message.targets); - } - if (message.vectorDistance !== undefined) { - obj.vectorDistance = message.vectorDistance; - } - return obj; - }, - - create(base?: DeepPartial): Hybrid { - return Hybrid.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): Hybrid { - const message = createBaseHybrid(); - message.query = object.query ?? ""; - message.properties = object.properties?.map((e) => e) || []; - message.vector = object.vector?.map((e) => e) || []; - message.alpha = object.alpha ?? 0; - message.fusionType = object.fusionType ?? 0; - message.vectorBytes = object.vectorBytes ?? new Uint8Array(0); - message.targetVectors = object.targetVectors?.map((e) => e) || []; - message.nearText = (object.nearText !== undefined && object.nearText !== null) - ? NearTextSearch.fromPartial(object.nearText) - : undefined; - message.nearVector = (object.nearVector !== undefined && object.nearVector !== null) - ? NearVector.fromPartial(object.nearVector) - : undefined; - message.targets = (object.targets !== undefined && object.targets !== null) - ? Targets.fromPartial(object.targets) - : undefined; - message.vectorDistance = object.vectorDistance ?? undefined; - return message; - }, -}; - -function createBaseNearTextSearch(): NearTextSearch { - return { - query: [], - certainty: undefined, - distance: undefined, - moveTo: undefined, - moveAway: undefined, - targetVectors: [], - targets: undefined, - }; -} - -export const NearTextSearch = { - encode(message: NearTextSearch, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - for (const v of message.query) { - writer.uint32(10).string(v!); - } - if (message.certainty !== undefined) { - writer.uint32(17).double(message.certainty); - } - if (message.distance !== undefined) { - writer.uint32(25).double(message.distance); - } - if (message.moveTo !== undefined) { - NearTextSearch_Move.encode(message.moveTo, writer.uint32(34).fork()).ldelim(); - } - if (message.moveAway !== undefined) { - NearTextSearch_Move.encode(message.moveAway, writer.uint32(42).fork()).ldelim(); - } - for (const v of message.targetVectors) { - writer.uint32(50).string(v!); - } - if (message.targets !== undefined) { - Targets.encode(message.targets, writer.uint32(58).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): NearTextSearch { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseNearTextSearch(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.query.push(reader.string()); - continue; - case 2: - if (tag !== 17) { - break; - } - - message.certainty = reader.double(); - continue; - case 3: - if (tag !== 25) { - break; - } - - message.distance = reader.double(); - continue; - case 4: - if (tag !== 34) { - break; - } - - message.moveTo = NearTextSearch_Move.decode(reader, reader.uint32()); - continue; - case 5: - if (tag !== 42) { - break; - } - - message.moveAway = NearTextSearch_Move.decode(reader, reader.uint32()); - continue; - case 6: - if (tag !== 50) { - break; - } - - message.targetVectors.push(reader.string()); - continue; - case 7: - if (tag !== 58) { - break; - } - - message.targets = Targets.decode(reader, reader.uint32()); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): NearTextSearch { - return { - query: globalThis.Array.isArray(object?.query) ? object.query.map((e: any) => globalThis.String(e)) : [], - certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, - distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, - moveTo: isSet(object.moveTo) ? NearTextSearch_Move.fromJSON(object.moveTo) : undefined, - moveAway: isSet(object.moveAway) ? NearTextSearch_Move.fromJSON(object.moveAway) : undefined, - targetVectors: globalThis.Array.isArray(object?.targetVectors) - ? object.targetVectors.map((e: any) => globalThis.String(e)) - : [], - targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, - }; - }, - - toJSON(message: NearTextSearch): unknown { - const obj: any = {}; - if (message.query?.length) { - obj.query = message.query; - } - if (message.certainty !== undefined) { - obj.certainty = message.certainty; - } - if (message.distance !== undefined) { - obj.distance = message.distance; - } - if (message.moveTo !== undefined) { - obj.moveTo = NearTextSearch_Move.toJSON(message.moveTo); - } - if (message.moveAway !== undefined) { - obj.moveAway = NearTextSearch_Move.toJSON(message.moveAway); - } - if (message.targetVectors?.length) { - obj.targetVectors = message.targetVectors; - } - if (message.targets !== undefined) { - obj.targets = Targets.toJSON(message.targets); - } - return obj; - }, - - create(base?: DeepPartial): NearTextSearch { - return NearTextSearch.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): NearTextSearch { - const message = createBaseNearTextSearch(); - message.query = object.query?.map((e) => e) || []; - message.certainty = object.certainty ?? undefined; - message.distance = object.distance ?? undefined; - message.moveTo = (object.moveTo !== undefined && object.moveTo !== null) - ? NearTextSearch_Move.fromPartial(object.moveTo) - : undefined; - message.moveAway = (object.moveAway !== undefined && object.moveAway !== null) - ? NearTextSearch_Move.fromPartial(object.moveAway) - : undefined; - message.targetVectors = object.targetVectors?.map((e) => e) || []; - message.targets = (object.targets !== undefined && object.targets !== null) - ? Targets.fromPartial(object.targets) - : undefined; - return message; - }, -}; - -function createBaseNearTextSearch_Move(): NearTextSearch_Move { - return { force: 0, concepts: [], uuids: [] }; -} - -export const NearTextSearch_Move = { - encode(message: NearTextSearch_Move, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.force !== 0) { - writer.uint32(13).float(message.force); - } - for (const v of message.concepts) { - writer.uint32(18).string(v!); - } - for (const v of message.uuids) { - writer.uint32(26).string(v!); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): NearTextSearch_Move { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseNearTextSearch_Move(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 13) { - break; - } - - message.force = reader.float(); - continue; - case 2: - if (tag !== 18) { - break; - } - - message.concepts.push(reader.string()); - continue; - case 3: - if (tag !== 26) { - break; - } - - message.uuids.push(reader.string()); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): NearTextSearch_Move { - return { - force: isSet(object.force) ? globalThis.Number(object.force) : 0, - concepts: globalThis.Array.isArray(object?.concepts) ? object.concepts.map((e: any) => globalThis.String(e)) : [], - uuids: globalThis.Array.isArray(object?.uuids) ? object.uuids.map((e: any) => globalThis.String(e)) : [], - }; - }, - - toJSON(message: NearTextSearch_Move): unknown { - const obj: any = {}; - if (message.force !== 0) { - obj.force = message.force; - } - if (message.concepts?.length) { - obj.concepts = message.concepts; - } - if (message.uuids?.length) { - obj.uuids = message.uuids; - } - return obj; - }, - - create(base?: DeepPartial): NearTextSearch_Move { - return NearTextSearch_Move.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): NearTextSearch_Move { - const message = createBaseNearTextSearch_Move(); - message.force = object.force ?? 0; - message.concepts = object.concepts?.map((e) => e) || []; - message.uuids = object.uuids?.map((e) => e) || []; - return message; - }, -}; - -function createBaseNearImageSearch(): NearImageSearch { - return { image: "", certainty: undefined, distance: undefined, targetVectors: [], targets: undefined }; -} - -export const NearImageSearch = { - encode(message: NearImageSearch, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.image !== "") { - writer.uint32(10).string(message.image); - } - if (message.certainty !== undefined) { - writer.uint32(17).double(message.certainty); - } - if (message.distance !== undefined) { - writer.uint32(25).double(message.distance); - } - for (const v of message.targetVectors) { - writer.uint32(34).string(v!); - } - if (message.targets !== undefined) { - Targets.encode(message.targets, writer.uint32(42).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): NearImageSearch { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseNearImageSearch(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.image = reader.string(); - continue; - case 2: - if (tag !== 17) { - break; - } - - message.certainty = reader.double(); - continue; - case 3: - if (tag !== 25) { - break; - } - - message.distance = reader.double(); - continue; - case 4: - if (tag !== 34) { - break; - } - - message.targetVectors.push(reader.string()); - continue; - case 5: - if (tag !== 42) { - break; - } - - message.targets = Targets.decode(reader, reader.uint32()); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): NearImageSearch { - return { - image: isSet(object.image) ? globalThis.String(object.image) : "", - certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, - distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, - targetVectors: globalThis.Array.isArray(object?.targetVectors) - ? object.targetVectors.map((e: any) => globalThis.String(e)) - : [], - targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, - }; - }, - - toJSON(message: NearImageSearch): unknown { - const obj: any = {}; - if (message.image !== "") { - obj.image = message.image; - } - if (message.certainty !== undefined) { - obj.certainty = message.certainty; - } - if (message.distance !== undefined) { - obj.distance = message.distance; - } - if (message.targetVectors?.length) { - obj.targetVectors = message.targetVectors; - } - if (message.targets !== undefined) { - obj.targets = Targets.toJSON(message.targets); - } - return obj; - }, - - create(base?: DeepPartial): NearImageSearch { - return NearImageSearch.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): NearImageSearch { - const message = createBaseNearImageSearch(); - message.image = object.image ?? ""; - message.certainty = object.certainty ?? undefined; - message.distance = object.distance ?? undefined; - message.targetVectors = object.targetVectors?.map((e) => e) || []; - message.targets = (object.targets !== undefined && object.targets !== null) - ? Targets.fromPartial(object.targets) - : undefined; - return message; - }, -}; - -function createBaseNearAudioSearch(): NearAudioSearch { - return { audio: "", certainty: undefined, distance: undefined, targetVectors: [], targets: undefined }; -} - -export const NearAudioSearch = { - encode(message: NearAudioSearch, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.audio !== "") { - writer.uint32(10).string(message.audio); - } - if (message.certainty !== undefined) { - writer.uint32(17).double(message.certainty); - } - if (message.distance !== undefined) { - writer.uint32(25).double(message.distance); - } - for (const v of message.targetVectors) { - writer.uint32(34).string(v!); - } - if (message.targets !== undefined) { - Targets.encode(message.targets, writer.uint32(42).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): NearAudioSearch { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseNearAudioSearch(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.audio = reader.string(); - continue; - case 2: - if (tag !== 17) { - break; - } - - message.certainty = reader.double(); - continue; - case 3: - if (tag !== 25) { - break; - } - - message.distance = reader.double(); - continue; - case 4: - if (tag !== 34) { - break; - } - - message.targetVectors.push(reader.string()); - continue; - case 5: - if (tag !== 42) { - break; - } - - message.targets = Targets.decode(reader, reader.uint32()); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): NearAudioSearch { - return { - audio: isSet(object.audio) ? globalThis.String(object.audio) : "", - certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, - distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, - targetVectors: globalThis.Array.isArray(object?.targetVectors) - ? object.targetVectors.map((e: any) => globalThis.String(e)) - : [], - targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, - }; - }, - - toJSON(message: NearAudioSearch): unknown { - const obj: any = {}; - if (message.audio !== "") { - obj.audio = message.audio; - } - if (message.certainty !== undefined) { - obj.certainty = message.certainty; - } - if (message.distance !== undefined) { - obj.distance = message.distance; - } - if (message.targetVectors?.length) { - obj.targetVectors = message.targetVectors; - } - if (message.targets !== undefined) { - obj.targets = Targets.toJSON(message.targets); - } - return obj; - }, - - create(base?: DeepPartial): NearAudioSearch { - return NearAudioSearch.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): NearAudioSearch { - const message = createBaseNearAudioSearch(); - message.audio = object.audio ?? ""; - message.certainty = object.certainty ?? undefined; - message.distance = object.distance ?? undefined; - message.targetVectors = object.targetVectors?.map((e) => e) || []; - message.targets = (object.targets !== undefined && object.targets !== null) - ? Targets.fromPartial(object.targets) - : undefined; - return message; - }, -}; - -function createBaseNearVideoSearch(): NearVideoSearch { - return { video: "", certainty: undefined, distance: undefined, targetVectors: [], targets: undefined }; -} - -export const NearVideoSearch = { - encode(message: NearVideoSearch, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.video !== "") { - writer.uint32(10).string(message.video); - } - if (message.certainty !== undefined) { - writer.uint32(17).double(message.certainty); - } - if (message.distance !== undefined) { - writer.uint32(25).double(message.distance); - } - for (const v of message.targetVectors) { - writer.uint32(34).string(v!); - } - if (message.targets !== undefined) { - Targets.encode(message.targets, writer.uint32(42).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): NearVideoSearch { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseNearVideoSearch(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.video = reader.string(); - continue; - case 2: - if (tag !== 17) { - break; - } - - message.certainty = reader.double(); - continue; - case 3: - if (tag !== 25) { - break; - } - - message.distance = reader.double(); - continue; - case 4: - if (tag !== 34) { - break; - } - - message.targetVectors.push(reader.string()); - continue; - case 5: - if (tag !== 42) { - break; - } - - message.targets = Targets.decode(reader, reader.uint32()); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): NearVideoSearch { - return { - video: isSet(object.video) ? globalThis.String(object.video) : "", - certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, - distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, - targetVectors: globalThis.Array.isArray(object?.targetVectors) - ? object.targetVectors.map((e: any) => globalThis.String(e)) - : [], - targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, - }; - }, - - toJSON(message: NearVideoSearch): unknown { - const obj: any = {}; - if (message.video !== "") { - obj.video = message.video; - } - if (message.certainty !== undefined) { - obj.certainty = message.certainty; - } - if (message.distance !== undefined) { - obj.distance = message.distance; - } - if (message.targetVectors?.length) { - obj.targetVectors = message.targetVectors; - } - if (message.targets !== undefined) { - obj.targets = Targets.toJSON(message.targets); - } - return obj; - }, - - create(base?: DeepPartial): NearVideoSearch { - return NearVideoSearch.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): NearVideoSearch { - const message = createBaseNearVideoSearch(); - message.video = object.video ?? ""; - message.certainty = object.certainty ?? undefined; - message.distance = object.distance ?? undefined; - message.targetVectors = object.targetVectors?.map((e) => e) || []; - message.targets = (object.targets !== undefined && object.targets !== null) - ? Targets.fromPartial(object.targets) - : undefined; - return message; - }, -}; - -function createBaseNearDepthSearch(): NearDepthSearch { - return { depth: "", certainty: undefined, distance: undefined, targetVectors: [], targets: undefined }; -} - -export const NearDepthSearch = { - encode(message: NearDepthSearch, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.depth !== "") { - writer.uint32(10).string(message.depth); - } - if (message.certainty !== undefined) { - writer.uint32(17).double(message.certainty); - } - if (message.distance !== undefined) { - writer.uint32(25).double(message.distance); - } - for (const v of message.targetVectors) { - writer.uint32(34).string(v!); - } - if (message.targets !== undefined) { - Targets.encode(message.targets, writer.uint32(42).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): NearDepthSearch { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseNearDepthSearch(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.depth = reader.string(); - continue; - case 2: - if (tag !== 17) { - break; - } - - message.certainty = reader.double(); - continue; - case 3: - if (tag !== 25) { - break; - } - - message.distance = reader.double(); - continue; - case 4: - if (tag !== 34) { - break; - } - - message.targetVectors.push(reader.string()); - continue; - case 5: - if (tag !== 42) { - break; - } - - message.targets = Targets.decode(reader, reader.uint32()); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): NearDepthSearch { - return { - depth: isSet(object.depth) ? globalThis.String(object.depth) : "", - certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, - distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, - targetVectors: globalThis.Array.isArray(object?.targetVectors) - ? object.targetVectors.map((e: any) => globalThis.String(e)) - : [], - targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, - }; - }, - - toJSON(message: NearDepthSearch): unknown { - const obj: any = {}; - if (message.depth !== "") { - obj.depth = message.depth; - } - if (message.certainty !== undefined) { - obj.certainty = message.certainty; - } - if (message.distance !== undefined) { - obj.distance = message.distance; - } - if (message.targetVectors?.length) { - obj.targetVectors = message.targetVectors; - } - if (message.targets !== undefined) { - obj.targets = Targets.toJSON(message.targets); - } - return obj; - }, - - create(base?: DeepPartial): NearDepthSearch { - return NearDepthSearch.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): NearDepthSearch { - const message = createBaseNearDepthSearch(); - message.depth = object.depth ?? ""; - message.certainty = object.certainty ?? undefined; - message.distance = object.distance ?? undefined; - message.targetVectors = object.targetVectors?.map((e) => e) || []; - message.targets = (object.targets !== undefined && object.targets !== null) - ? Targets.fromPartial(object.targets) - : undefined; - return message; - }, -}; - -function createBaseNearThermalSearch(): NearThermalSearch { - return { thermal: "", certainty: undefined, distance: undefined, targetVectors: [], targets: undefined }; -} - -export const NearThermalSearch = { - encode(message: NearThermalSearch, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.thermal !== "") { - writer.uint32(10).string(message.thermal); - } - if (message.certainty !== undefined) { - writer.uint32(17).double(message.certainty); - } - if (message.distance !== undefined) { - writer.uint32(25).double(message.distance); - } - for (const v of message.targetVectors) { - writer.uint32(34).string(v!); - } - if (message.targets !== undefined) { - Targets.encode(message.targets, writer.uint32(42).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): NearThermalSearch { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseNearThermalSearch(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.thermal = reader.string(); - continue; - case 2: - if (tag !== 17) { - break; - } - - message.certainty = reader.double(); - continue; - case 3: - if (tag !== 25) { - break; - } - - message.distance = reader.double(); - continue; - case 4: - if (tag !== 34) { - break; - } - - message.targetVectors.push(reader.string()); - continue; - case 5: - if (tag !== 42) { - break; - } - - message.targets = Targets.decode(reader, reader.uint32()); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): NearThermalSearch { - return { - thermal: isSet(object.thermal) ? globalThis.String(object.thermal) : "", - certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, - distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, - targetVectors: globalThis.Array.isArray(object?.targetVectors) - ? object.targetVectors.map((e: any) => globalThis.String(e)) - : [], - targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, - }; - }, - - toJSON(message: NearThermalSearch): unknown { - const obj: any = {}; - if (message.thermal !== "") { - obj.thermal = message.thermal; - } - if (message.certainty !== undefined) { - obj.certainty = message.certainty; - } - if (message.distance !== undefined) { - obj.distance = message.distance; - } - if (message.targetVectors?.length) { - obj.targetVectors = message.targetVectors; - } - if (message.targets !== undefined) { - obj.targets = Targets.toJSON(message.targets); - } - return obj; - }, - - create(base?: DeepPartial): NearThermalSearch { - return NearThermalSearch.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): NearThermalSearch { - const message = createBaseNearThermalSearch(); - message.thermal = object.thermal ?? ""; - message.certainty = object.certainty ?? undefined; - message.distance = object.distance ?? undefined; - message.targetVectors = object.targetVectors?.map((e) => e) || []; - message.targets = (object.targets !== undefined && object.targets !== null) - ? Targets.fromPartial(object.targets) - : undefined; - return message; - }, -}; - -function createBaseNearIMUSearch(): NearIMUSearch { - return { imu: "", certainty: undefined, distance: undefined, targetVectors: [], targets: undefined }; -} - -export const NearIMUSearch = { - encode(message: NearIMUSearch, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.imu !== "") { - writer.uint32(10).string(message.imu); - } - if (message.certainty !== undefined) { - writer.uint32(17).double(message.certainty); - } - if (message.distance !== undefined) { - writer.uint32(25).double(message.distance); - } - for (const v of message.targetVectors) { - writer.uint32(34).string(v!); - } - if (message.targets !== undefined) { - Targets.encode(message.targets, writer.uint32(42).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): NearIMUSearch { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseNearIMUSearch(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.imu = reader.string(); - continue; - case 2: - if (tag !== 17) { - break; - } - - message.certainty = reader.double(); - continue; - case 3: - if (tag !== 25) { - break; - } - - message.distance = reader.double(); - continue; - case 4: - if (tag !== 34) { - break; - } - - message.targetVectors.push(reader.string()); - continue; - case 5: - if (tag !== 42) { - break; - } - - message.targets = Targets.decode(reader, reader.uint32()); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): NearIMUSearch { - return { - imu: isSet(object.imu) ? globalThis.String(object.imu) : "", - certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, - distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, - targetVectors: globalThis.Array.isArray(object?.targetVectors) - ? object.targetVectors.map((e: any) => globalThis.String(e)) - : [], - targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, - }; - }, - - toJSON(message: NearIMUSearch): unknown { - const obj: any = {}; - if (message.imu !== "") { - obj.imu = message.imu; - } - if (message.certainty !== undefined) { - obj.certainty = message.certainty; - } - if (message.distance !== undefined) { - obj.distance = message.distance; - } - if (message.targetVectors?.length) { - obj.targetVectors = message.targetVectors; - } - if (message.targets !== undefined) { - obj.targets = Targets.toJSON(message.targets); - } - return obj; - }, - - create(base?: DeepPartial): NearIMUSearch { - return NearIMUSearch.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): NearIMUSearch { - const message = createBaseNearIMUSearch(); - message.imu = object.imu ?? ""; - message.certainty = object.certainty ?? undefined; - message.distance = object.distance ?? undefined; - message.targetVectors = object.targetVectors?.map((e) => e) || []; - message.targets = (object.targets !== undefined && object.targets !== null) - ? Targets.fromPartial(object.targets) - : undefined; - return message; - }, -}; - -function createBaseBM25(): BM25 { - return { query: "", properties: [] }; -} - -export const BM25 = { - encode(message: BM25, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.query !== "") { - writer.uint32(10).string(message.query); - } - for (const v of message.properties) { - writer.uint32(18).string(v!); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): BM25 { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseBM25(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.query = reader.string(); - continue; - case 2: - if (tag !== 18) { - break; - } - - message.properties.push(reader.string()); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): BM25 { - return { - query: isSet(object.query) ? globalThis.String(object.query) : "", - properties: globalThis.Array.isArray(object?.properties) - ? object.properties.map((e: any) => globalThis.String(e)) - : [], - }; - }, - - toJSON(message: BM25): unknown { - const obj: any = {}; - if (message.query !== "") { - obj.query = message.query; - } - if (message.properties?.length) { - obj.properties = message.properties; - } - return obj; - }, - - create(base?: DeepPartial): BM25 { - return BM25.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): BM25 { - const message = createBaseBM25(); - message.query = object.query ?? ""; - message.properties = object.properties?.map((e) => e) || []; - return message; - }, -}; - -function createBaseRefPropertiesRequest(): RefPropertiesRequest { - return { referenceProperty: "", properties: undefined, metadata: undefined, targetCollection: "" }; -} - -export const RefPropertiesRequest = { - encode(message: RefPropertiesRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.referenceProperty !== "") { - writer.uint32(10).string(message.referenceProperty); - } - if (message.properties !== undefined) { - PropertiesRequest.encode(message.properties, writer.uint32(18).fork()).ldelim(); - } - if (message.metadata !== undefined) { - MetadataRequest.encode(message.metadata, writer.uint32(26).fork()).ldelim(); - } - if (message.targetCollection !== "") { - writer.uint32(34).string(message.targetCollection); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): RefPropertiesRequest { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseRefPropertiesRequest(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.referenceProperty = reader.string(); - continue; - case 2: - if (tag !== 18) { - break; - } - - message.properties = PropertiesRequest.decode(reader, reader.uint32()); - continue; - case 3: - if (tag !== 26) { - break; - } - - message.metadata = MetadataRequest.decode(reader, reader.uint32()); - continue; - case 4: - if (tag !== 34) { - break; - } - - message.targetCollection = reader.string(); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): RefPropertiesRequest { - return { - referenceProperty: isSet(object.referenceProperty) ? globalThis.String(object.referenceProperty) : "", - properties: isSet(object.properties) ? PropertiesRequest.fromJSON(object.properties) : undefined, - metadata: isSet(object.metadata) ? MetadataRequest.fromJSON(object.metadata) : undefined, - targetCollection: isSet(object.targetCollection) ? globalThis.String(object.targetCollection) : "", - }; - }, - - toJSON(message: RefPropertiesRequest): unknown { - const obj: any = {}; - if (message.referenceProperty !== "") { - obj.referenceProperty = message.referenceProperty; - } - if (message.properties !== undefined) { - obj.properties = PropertiesRequest.toJSON(message.properties); - } - if (message.metadata !== undefined) { - obj.metadata = MetadataRequest.toJSON(message.metadata); - } - if (message.targetCollection !== "") { - obj.targetCollection = message.targetCollection; - } - return obj; - }, - - create(base?: DeepPartial): RefPropertiesRequest { - return RefPropertiesRequest.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): RefPropertiesRequest { - const message = createBaseRefPropertiesRequest(); - message.referenceProperty = object.referenceProperty ?? ""; - message.properties = (object.properties !== undefined && object.properties !== null) - ? PropertiesRequest.fromPartial(object.properties) - : undefined; - message.metadata = (object.metadata !== undefined && object.metadata !== null) - ? MetadataRequest.fromPartial(object.metadata) - : undefined; - message.targetCollection = object.targetCollection ?? ""; - return message; - }, -}; - -function createBaseVectorForTarget(): VectorForTarget { - return { name: "", vectorBytes: new Uint8Array(0) }; -} - -export const VectorForTarget = { - encode(message: VectorForTarget, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.name !== "") { - writer.uint32(10).string(message.name); - } - if (message.vectorBytes.length !== 0) { - writer.uint32(18).bytes(message.vectorBytes); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): VectorForTarget { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseVectorForTarget(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.name = reader.string(); - continue; - case 2: - if (tag !== 18) { - break; - } - - message.vectorBytes = reader.bytes(); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): VectorForTarget { - return { - name: isSet(object.name) ? globalThis.String(object.name) : "", - vectorBytes: isSet(object.vectorBytes) ? bytesFromBase64(object.vectorBytes) : new Uint8Array(0), - }; - }, - - toJSON(message: VectorForTarget): unknown { - const obj: any = {}; - if (message.name !== "") { - obj.name = message.name; - } - if (message.vectorBytes.length !== 0) { - obj.vectorBytes = base64FromBytes(message.vectorBytes); - } - return obj; - }, - - create(base?: DeepPartial): VectorForTarget { - return VectorForTarget.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): VectorForTarget { - const message = createBaseVectorForTarget(); - message.name = object.name ?? ""; - message.vectorBytes = object.vectorBytes ?? new Uint8Array(0); - return message; - }, -}; - -function createBaseNearVector(): NearVector { - return { - vector: [], - certainty: undefined, - distance: undefined, - vectorBytes: new Uint8Array(0), - targetVectors: [], - targets: undefined, - vectorPerTarget: {}, - vectorForTargets: [], - }; -} - -export const NearVector = { - encode(message: NearVector, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - writer.uint32(10).fork(); - for (const v of message.vector) { - writer.float(v); - } - writer.ldelim(); - if (message.certainty !== undefined) { - writer.uint32(17).double(message.certainty); - } - if (message.distance !== undefined) { - writer.uint32(25).double(message.distance); - } - if (message.vectorBytes.length !== 0) { - writer.uint32(34).bytes(message.vectorBytes); - } - for (const v of message.targetVectors) { - writer.uint32(42).string(v!); - } - if (message.targets !== undefined) { - Targets.encode(message.targets, writer.uint32(50).fork()).ldelim(); - } - Object.entries(message.vectorPerTarget).forEach(([key, value]) => { - NearVector_VectorPerTargetEntry.encode({ key: key as any, value }, writer.uint32(58).fork()).ldelim(); - }); - for (const v of message.vectorForTargets) { - VectorForTarget.encode(v!, writer.uint32(66).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): NearVector { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseNearVector(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag === 13) { - message.vector.push(reader.float()); - - continue; - } - - if (tag === 10) { - const end2 = reader.uint32() + reader.pos; - while (reader.pos < end2) { - message.vector.push(reader.float()); - } - - continue; - } - - break; - case 2: - if (tag !== 17) { - break; - } - - message.certainty = reader.double(); - continue; - case 3: - if (tag !== 25) { - break; - } - - message.distance = reader.double(); - continue; - case 4: - if (tag !== 34) { - break; - } - - message.vectorBytes = reader.bytes(); - continue; - case 5: - if (tag !== 42) { - break; - } - - message.targetVectors.push(reader.string()); - continue; - case 6: - if (tag !== 50) { - break; - } - - message.targets = Targets.decode(reader, reader.uint32()); - continue; - case 7: - if (tag !== 58) { - break; - } - - const entry7 = NearVector_VectorPerTargetEntry.decode(reader, reader.uint32()); - if (entry7.value !== undefined) { - message.vectorPerTarget[entry7.key] = entry7.value; - } - continue; - case 8: - if (tag !== 66) { - break; - } - - message.vectorForTargets.push(VectorForTarget.decode(reader, reader.uint32())); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): NearVector { - return { - vector: globalThis.Array.isArray(object?.vector) ? object.vector.map((e: any) => globalThis.Number(e)) : [], - certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, - distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, - vectorBytes: isSet(object.vectorBytes) ? bytesFromBase64(object.vectorBytes) : new Uint8Array(0), - targetVectors: globalThis.Array.isArray(object?.targetVectors) - ? object.targetVectors.map((e: any) => globalThis.String(e)) - : [], - targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, - vectorPerTarget: isObject(object.vectorPerTarget) - ? Object.entries(object.vectorPerTarget).reduce<{ [key: string]: Uint8Array }>((acc, [key, value]) => { - acc[key] = bytesFromBase64(value as string); - return acc; - }, {}) - : {}, - vectorForTargets: globalThis.Array.isArray(object?.vectorForTargets) - ? object.vectorForTargets.map((e: any) => VectorForTarget.fromJSON(e)) - : [], - }; - }, - - toJSON(message: NearVector): unknown { - const obj: any = {}; - if (message.vector?.length) { - obj.vector = message.vector; - } - if (message.certainty !== undefined) { - obj.certainty = message.certainty; - } - if (message.distance !== undefined) { - obj.distance = message.distance; - } - if (message.vectorBytes.length !== 0) { - obj.vectorBytes = base64FromBytes(message.vectorBytes); - } - if (message.targetVectors?.length) { - obj.targetVectors = message.targetVectors; - } - if (message.targets !== undefined) { - obj.targets = Targets.toJSON(message.targets); - } - if (message.vectorPerTarget) { - const entries = Object.entries(message.vectorPerTarget); - if (entries.length > 0) { - obj.vectorPerTarget = {}; - entries.forEach(([k, v]) => { - obj.vectorPerTarget[k] = base64FromBytes(v); - }); - } - } - if (message.vectorForTargets?.length) { - obj.vectorForTargets = message.vectorForTargets.map((e) => VectorForTarget.toJSON(e)); - } - return obj; - }, - - create(base?: DeepPartial): NearVector { - return NearVector.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): NearVector { - const message = createBaseNearVector(); - message.vector = object.vector?.map((e) => e) || []; - message.certainty = object.certainty ?? undefined; - message.distance = object.distance ?? undefined; - message.vectorBytes = object.vectorBytes ?? new Uint8Array(0); - message.targetVectors = object.targetVectors?.map((e) => e) || []; - message.targets = (object.targets !== undefined && object.targets !== null) - ? Targets.fromPartial(object.targets) + fromPartial(object: DeepPartial): RefPropertiesRequest { + const message = createBaseRefPropertiesRequest(); + message.referenceProperty = object.referenceProperty ?? ""; + message.properties = (object.properties !== undefined && object.properties !== null) + ? PropertiesRequest.fromPartial(object.properties) : undefined; - message.vectorPerTarget = Object.entries(object.vectorPerTarget ?? {}).reduce<{ [key: string]: Uint8Array }>( - (acc, [key, value]) => { - if (value !== undefined) { - acc[key] = value; - } - return acc; - }, - {}, - ); - message.vectorForTargets = object.vectorForTargets?.map((e) => VectorForTarget.fromPartial(e)) || []; - return message; - }, -}; - -function createBaseNearVector_VectorPerTargetEntry(): NearVector_VectorPerTargetEntry { - return { key: "", value: new Uint8Array(0) }; -} - -export const NearVector_VectorPerTargetEntry = { - encode(message: NearVector_VectorPerTargetEntry, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.key !== "") { - writer.uint32(10).string(message.key); - } - if (message.value.length !== 0) { - writer.uint32(18).bytes(message.value); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): NearVector_VectorPerTargetEntry { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseNearVector_VectorPerTargetEntry(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.key = reader.string(); - continue; - case 2: - if (tag !== 18) { - break; - } - - message.value = reader.bytes(); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): NearVector_VectorPerTargetEntry { - return { - key: isSet(object.key) ? globalThis.String(object.key) : "", - value: isSet(object.value) ? bytesFromBase64(object.value) : new Uint8Array(0), - }; - }, - - toJSON(message: NearVector_VectorPerTargetEntry): unknown { - const obj: any = {}; - if (message.key !== "") { - obj.key = message.key; - } - if (message.value.length !== 0) { - obj.value = base64FromBytes(message.value); - } - return obj; - }, - - create(base?: DeepPartial): NearVector_VectorPerTargetEntry { - return NearVector_VectorPerTargetEntry.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): NearVector_VectorPerTargetEntry { - const message = createBaseNearVector_VectorPerTargetEntry(); - message.key = object.key ?? ""; - message.value = object.value ?? new Uint8Array(0); - return message; - }, -}; - -function createBaseNearObject(): NearObject { - return { id: "", certainty: undefined, distance: undefined, targetVectors: [], targets: undefined }; -} - -export const NearObject = { - encode(message: NearObject, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.id !== "") { - writer.uint32(10).string(message.id); - } - if (message.certainty !== undefined) { - writer.uint32(17).double(message.certainty); - } - if (message.distance !== undefined) { - writer.uint32(25).double(message.distance); - } - for (const v of message.targetVectors) { - writer.uint32(34).string(v!); - } - if (message.targets !== undefined) { - Targets.encode(message.targets, writer.uint32(42).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): NearObject { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseNearObject(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.id = reader.string(); - continue; - case 2: - if (tag !== 17) { - break; - } - - message.certainty = reader.double(); - continue; - case 3: - if (tag !== 25) { - break; - } - - message.distance = reader.double(); - continue; - case 4: - if (tag !== 34) { - break; - } - - message.targetVectors.push(reader.string()); - continue; - case 5: - if (tag !== 42) { - break; - } - - message.targets = Targets.decode(reader, reader.uint32()); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): NearObject { - return { - id: isSet(object.id) ? globalThis.String(object.id) : "", - certainty: isSet(object.certainty) ? globalThis.Number(object.certainty) : undefined, - distance: isSet(object.distance) ? globalThis.Number(object.distance) : undefined, - targetVectors: globalThis.Array.isArray(object?.targetVectors) - ? object.targetVectors.map((e: any) => globalThis.String(e)) - : [], - targets: isSet(object.targets) ? Targets.fromJSON(object.targets) : undefined, - }; - }, - - toJSON(message: NearObject): unknown { - const obj: any = {}; - if (message.id !== "") { - obj.id = message.id; - } - if (message.certainty !== undefined) { - obj.certainty = message.certainty; - } - if (message.distance !== undefined) { - obj.distance = message.distance; - } - if (message.targetVectors?.length) { - obj.targetVectors = message.targetVectors; - } - if (message.targets !== undefined) { - obj.targets = Targets.toJSON(message.targets); - } - return obj; - }, - - create(base?: DeepPartial): NearObject { - return NearObject.fromPartial(base ?? {}); - }, - fromPartial(object: DeepPartial): NearObject { - const message = createBaseNearObject(); - message.id = object.id ?? ""; - message.certainty = object.certainty ?? undefined; - message.distance = object.distance ?? undefined; - message.targetVectors = object.targetVectors?.map((e) => e) || []; - message.targets = (object.targets !== undefined && object.targets !== null) - ? Targets.fromPartial(object.targets) + message.metadata = (object.metadata !== undefined && object.metadata !== null) + ? MetadataRequest.fromPartial(object.metadata) : undefined; + message.targetCollection = object.targetCollection ?? ""; return message; }, }; diff --git a/src/proto/v1/weaviate.ts b/src/proto/v1/weaviate.ts index aecfe694..43acd7b9 100644 --- a/src/proto/v1/weaviate.ts +++ b/src/proto/v1/weaviate.ts @@ -6,6 +6,7 @@ /* eslint-disable */ import { type CallContext, type CallOptions } from "nice-grpc-common"; +import { AggregateReply, AggregateRequest } from "./aggregate.js"; import { BatchObjectsReply, BatchObjectsRequest } from "./batch.js"; import { BatchDeleteReply, BatchDeleteRequest } from "./batch_delete.js"; import { SearchReply, SearchRequest } from "./search_get.js"; @@ -50,6 +51,14 @@ export const WeaviateDefinition = { responseStream: false, options: {}, }, + aggregate: { + name: "Aggregate", + requestType: AggregateRequest, + requestStream: false, + responseType: AggregateReply, + responseStream: false, + options: {}, + }, }, } as const; @@ -64,6 +73,7 @@ export interface WeaviateServiceImplementation { context: CallContext & CallContextExt, ): Promise>; tenantsGet(request: TenantsGetRequest, context: CallContext & CallContextExt): Promise>; + aggregate(request: AggregateRequest, context: CallContext & CallContextExt): Promise>; } export interface WeaviateClient { @@ -77,6 +87,7 @@ export interface WeaviateClient { options?: CallOptions & CallOptionsExt, ): Promise; tenantsGet(request: DeepPartial, options?: CallOptions & CallOptionsExt): Promise; + aggregate(request: DeepPartial, options?: CallOptions & CallOptionsExt): Promise; } type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; diff --git a/src/roles/index.ts b/src/roles/index.ts index 0bf17846..98ec8194 100644 --- a/src/roles/index.ts +++ b/src/roles/index.ts @@ -10,37 +10,87 @@ import { PermissionsInput, Role, RolesPermission, - User, + UsersPermission, } from './types.js'; import { Map } from './util.js'; export interface Roles { + /** + * Retrieve all the roles in the system. + * + * @returns {Promise>} A map of role names to their respective roles. + */ listAll: () => Promise>; - ofCurrentUser: () => Promise>; + /** + * Retrieve a role by its name. + * + * @param {string} roleName The name of the role to retrieve. + * @returns {Promise} The role if it exists, or null if it does not. + */ byName: (roleName: string) => Promise; - byUser: (user: string) => Promise>; - assignedUsers: (roleName: string) => Promise>; + /** + * Retrieve the user IDs assigned to a role. + * + * @param {string} roleName The name of the role to retrieve the assigned user IDs for. + * @returns {Promise} The user IDs assigned to the role. + */ + assignedUserIds: (roleName: string) => Promise; + /** + * Delete a role by its name. + * + * @param {string} roleName The name of the role to delete. + * @returns {Promise} A promise that resolves when the role is deleted. + */ delete: (roleName: string) => Promise; + /** + * Create a new role. + * + * @param {string} roleName The name of the new role. + * @param {PermissionsInput} permissions The permissions to assign to the new role. + * @returns {Promise} The newly created role. + */ create: (roleName: string, permissions: PermissionsInput) => Promise; - assignToUser: (roleNames: string | string[], user: string) => Promise; + /** + * Check if a role exists. + * + * @param {string} roleName The name of the role to check for. + * @returns {Promise} A promise that resolves to true if the role exists, or false if it does not. + */ exists: (roleName: string) => Promise; - revokeFromUser: (roleNames: string | string[], user: string) => Promise; + /** + * Add permissions to a role. + * + * @param {string} roleName The name of the role to add permissions to. + * @param {PermissionsInput} permissions The permissions to add. + * @returns {Promise} A promise that resolves when the permissions are added. + */ addPermissions: (roleName: string, permissions: PermissionsInput) => Promise; + /** + * Remove permissions from a role. + * + * @param {string} roleName The name of the role to remove permissions from. + * @param {PermissionsInput} permissions The permissions to remove. + * @returns {Promise} A promise that resolves when the permissions are removed. + */ removePermissions: (roleName: string, permissions: PermissionsInput) => Promise; - hasPermission: (roleName: string, permission: Permission) => Promise; + /** + * Check if a role has the specified permissions. + * + * @param {string} roleName The name of the role to check. + * @param {Permission | Permission[]} permission The permission or permissions to check for. + * @returns {Promise} A promise that resolves to true if the role has the permissions, or false if it does not. + */ + hasPermissions: (roleName: string, permission: Permission | Permission[]) => Promise; } const roles = (connection: ConnectionREST): Roles => { return { listAll: () => connection.get('/authz/roles').then(Map.roles), - ofCurrentUser: () => connection.get('/authz/users/own-roles').then(Map.roles), byName: (roleName: string) => connection.get(`/authz/roles/${roleName}`).then(Map.roleFromWeaviate), - byUser: (user: string) => connection.get(`/authz/users/${user}/roles`).then(Map.roles), - assignedUsers: (roleName: string) => - connection.get(`/authz/roles/${roleName}/users`).then(Map.users), + assignedUserIds: (roleName: string) => connection.get(`/authz/roles/${roleName}/users`), create: (roleName: string, permissions: PermissionsInput) => { - const perms = Map.flattenPermissions(permissions).map(Map.permissionToWeaviate); + const perms = Map.flattenPermissions(permissions).flatMap(Map.permissionToWeaviate); return connection .postEmpty('/authz/roles', { name: roleName, @@ -54,23 +104,18 @@ const roles = (connection: ConnectionREST): Roles => { .get(`/authz/roles/${roleName}`) .then(() => true) .catch(() => false), - assignToUser: (roleNames: string | string[], user: string) => - connection.postEmpty(`/authz/users/${user}/assign`, { - roles: Array.isArray(roleNames) ? roleNames : [roleNames], - }), - revokeFromUser: (roleNames: string | string[], user: string) => - connection.postEmpty(`/authz/users/${user}/revoke`, { - roles: Array.isArray(roleNames) ? roleNames : [roleNames], - }), addPermissions: (roleName: string, permissions: PermissionsInput) => connection.postEmpty(`/authz/roles/${roleName}/add-permissions`, { permissions }), removePermissions: (roleName: string, permissions: PermissionsInput) => connection.postEmpty(`/authz/roles/${roleName}/remove-permissions`, { permissions }), - hasPermission: (roleName: string, permission: Permission) => - connection.postReturn( - `/authz/roles/${roleName}/has-permission`, - Map.permissionToWeaviate(permission) - ), + hasPermissions: (roleName: string, permission: Permission | Permission[]) => + Promise.all( + (Array.isArray(permission) ? permission : [permission]) + .flatMap((p) => Map.permissionToWeaviate(p)) + .map((p) => + connection.postReturn(`/authz/roles/${roleName}/has-permission`, p) + ) + ).then((r) => r.every((b) => b)), }; }; @@ -78,19 +123,15 @@ export const permissions = { backup: (args: { collection: string | string[]; manage?: boolean }): BackupsPermission[] => { const collections = Array.isArray(args.collection) ? args.collection : [args.collection]; return collections.flatMap((collection) => { - const out: BackupsPermission[] = []; - if (args.manage) { - out.push({ collection, action: 'manage_backups' }); - } + const out: BackupsPermission = { collection, actions: [] }; + if (args.manage) out.actions.push('manage_backups'); return out; }); }, cluster: (args: { read?: boolean }): ClusterPermission[] => { - const out: ClusterPermission[] = []; - if (args.read) { - out.push({ action: 'read_cluster' }); - } - return out; + const out: ClusterPermission = { actions: [] }; + if (args.read) out.actions.push('read_cluster'); + return [out]; }, collections: (args: { collection: string | string[]; @@ -101,19 +142,11 @@ export const permissions = { }): CollectionsPermission[] => { const collections = Array.isArray(args.collection) ? args.collection : [args.collection]; return collections.flatMap((collection) => { - const out: CollectionsPermission[] = []; - if (args.create_collection) { - out.push({ collection, action: 'create_collections' }); - } - if (args.read_config) { - out.push({ collection, action: 'read_collections' }); - } - if (args.update_config) { - out.push({ collection, action: 'update_collections' }); - } - if (args.delete_collection) { - out.push({ collection, action: 'delete_collections' }); - } + const out: CollectionsPermission = { collection, actions: [] }; + if (args.create_collection) out.actions.push('create_collections'); + if (args.read_config) out.actions.push('read_collections'); + if (args.update_config) out.actions.push('update_collections'); + if (args.delete_collection) out.actions.push('delete_collections'); return out; }); }, @@ -126,46 +159,64 @@ export const permissions = { }): DataPermission[] => { const collections = Array.isArray(args.collection) ? args.collection : [args.collection]; return collections.flatMap((collection) => { - const out: DataPermission[] = []; - if (args.create) { - out.push({ collection, action: 'create_data' }); - } - if (args.read) { - out.push({ collection, action: 'read_data' }); - } - if (args.update) { - out.push({ collection, action: 'update_data' }); - } - if (args.delete) { - out.push({ collection, action: 'delete_data' }); - } + const out: DataPermission = { collection, actions: [] }; + if (args.create) out.actions.push('create_data'); + if (args.read) out.actions.push('read_data'); + if (args.update) out.actions.push('update_data'); + if (args.delete) out.actions.push('delete_data'); return out; }); }, - nodes: (args: { - collection: string | string[]; - verbosity?: 'verbose' | 'minimal'; + nodes: { + minimal: (args: { read?: boolean }): NodesPermission[] => { + const out: NodesPermission = { + collection: '*', + actions: [], + verbosity: 'minimal', + }; + if (args.read) out.actions.push('read_nodes'); + return [out]; + }, + verbose: (args: { collection: string | string[]; read?: boolean }): NodesPermission[] => { + const collections = Array.isArray(args.collection) ? args.collection : [args.collection]; + return collections.flatMap((collection) => { + const out: NodesPermission = { + collection, + actions: [], + verbosity: 'verbose', + }; + if (args.read) out.actions.push('read_nodes'); + return out; + }); + }, + }, + roles: (args: { + role: string | string[]; + create?: boolean; read?: boolean; - }): NodesPermission[] => { - const collections = Array.isArray(args.collection) ? args.collection : [args.collection]; - return collections.flatMap((collection) => { - const out: NodesPermission[] = []; - if (args.read) { - out.push({ collection, action: 'read_nodes', verbosity: args.verbosity || 'verbose' }); - } + update?: boolean; + delete?: boolean; + }): RolesPermission[] => { + const roles = Array.isArray(args.role) ? args.role : [args.role]; + return roles.flatMap((role) => { + const out: RolesPermission = { role, actions: [] }; + if (args.create) out.actions.push('create_roles'); + if (args.read) out.actions.push('read_roles'); + if (args.update) out.actions.push('update_roles'); + if (args.delete) out.actions.push('delete_roles'); return out; }); }, - roles: (args: { role: string | string[]; read?: boolean; manage?: boolean }): RolesPermission[] => { - const roles = Array.isArray(args.role) ? args.role : [args.role]; - return roles.flatMap((role) => { - const out: RolesPermission[] = []; - if (args.read) { - out.push({ role, action: 'read_roles' }); - } - if (args.manage) { - out.push({ role, action: 'manage_roles' }); - } + users: (args: { + user: string | string[]; + assign_and_revoke?: boolean; + read?: boolean; + }): UsersPermission[] => { + const users = Array.isArray(args.user) ? args.user : [args.user]; + return users.flatMap((user) => { + const out: UsersPermission = { users: user, actions: [] }; + if (args.assign_and_revoke) out.actions.push('assign_and_revoke_users'); + if (args.read) out.actions.push('read_users'); return out; }); }, diff --git a/src/roles/integration.test.ts b/src/roles/integration.test.ts index fd9355e2..1b346818 100644 --- a/src/roles/integration.test.ts +++ b/src/roles/integration.test.ts @@ -1,72 +1,34 @@ -import { StartedWeaviateContainer, WeaviateContainer } from '@testcontainers/weaviate'; import weaviate, { ApiKey, Permission, Role, WeaviateClient } from '..'; -import { WeaviateInsufficientPermissionsError, WeaviateUnexpectedStatusCodeError } from '../errors'; +import { WeaviateStartUpError, WeaviateUnexpectedStatusCodeError } from '../errors'; import { DbVersion } from '../utils/dbVersion'; -const only = DbVersion.fromString(`v${process.env.WEAVIATE_VERSION!}`).isAtLeast(1, 28, 0) +const only = DbVersion.fromString(`v${process.env.WEAVIATE_VERSION!}`).isAtLeast(1, 29, 0) ? describe : describe.skip; only('Integration testing of the roles namespace', () => { let client: WeaviateClient; - let container: StartedWeaviateContainer; beforeAll(async () => { - container = await new WeaviateContainer(`semitechnologies/weaviate:${process.env.WEAVIATE_VERSION}`) - .withExposedPorts(8080, 50051) - .withEnvironment({ - AUTHENTICATION_APIKEY_ENABLED: 'true', - AUTHENTICATION_APIKEY_ALLOWED_KEYS: 'admin-key,custom-key', - AUTHENTICATION_APIKEY_USERS: 'admin-user,custom-user', - AUTHORIZATION_ADMIN_USERS: 'admin-user', - AUTHORIZATION_ENABLE_RBAC: 'true', - }) - .start(); - expect(container).toBeDefined(); client = await weaviate.connectToLocal({ - host: container.getHost(), - port: container.getMappedPort(8080), - grpcPort: container.getMappedPort(50051), + port: 8091, + grpcPort: 50062, authCredentials: new ApiKey('admin-key'), }); }); - afterAll(async () => { - await container.stop(); - }); - it('should be able to retrieve the default roles', async () => { const roles = await client.roles.listAll(); expect(Object.values(roles).length).toBeGreaterThan(0); }); - it('should fail with insufficient permissions if no key provided', async () => { - const unauthenticatedClient = await weaviate.connectToLocal({ - host: container.getHost(), - port: container.getMappedPort(8080), - grpcPort: container.getMappedPort(50051), - }); - await expect(unauthenticatedClient.roles.listAll()).rejects.toThrowError( - WeaviateInsufficientPermissionsError - ); // should be unauthenticated error, needs fixing on server - }); - - it('should fail with insufficient permissions if permission-less key provided', async () => { - const unauthenticatedClient = await weaviate.connectToLocal({ - host: container.getHost(), - port: container.getMappedPort(8080), - grpcPort: container.getMappedPort(50051), - authCredentials: new ApiKey('custom-key'), - }); - await expect(unauthenticatedClient.roles.listAll()).rejects.toThrowError( - WeaviateInsufficientPermissionsError - ); - }); - - it('should get roles by user', async () => { - const roles = await client.roles.byUser('admin-user'); - expect(Object.keys(roles).length).toBeGreaterThan(0); - }); + it('should fail to start up if no key provided', () => + expect( + weaviate.connectToLocal({ + port: 8091, + grpcPort: 50062, + }) + ).rejects.toThrowError(WeaviateStartUpError)); it('should check the existance of a real role', async () => { const exists = await client.roles.exists('admin'); @@ -90,12 +52,13 @@ only('Integration testing of the roles namespace', () => { permissions: weaviate.permissions.backup({ collection: 'Some-collection', manage: true }), expected: { name: 'backups', - backupsPermissions: [{ collection: 'Some-collection', action: 'manage_backups' }], + backupsPermissions: [{ collection: 'Some-collection', actions: ['manage_backups'] }], clusterPermissions: [], collectionsPermissions: [], dataPermissions: [], nodesPermissions: [], rolesPermissions: [], + usersPermissions: [], }, }, { @@ -104,11 +67,12 @@ only('Integration testing of the roles namespace', () => { expected: { name: 'cluster', backupsPermissions: [], - clusterPermissions: [{ action: 'read_cluster' }], + clusterPermissions: [{ actions: ['read_cluster'] }], collectionsPermissions: [], dataPermissions: [], nodesPermissions: [], rolesPermissions: [], + usersPermissions: [], }, }, { @@ -125,14 +89,15 @@ only('Integration testing of the roles namespace', () => { backupsPermissions: [], clusterPermissions: [], collectionsPermissions: [ - { collection: 'Some-collection', action: 'create_collections' }, - { collection: 'Some-collection', action: 'read_collections' }, - { collection: 'Some-collection', action: 'update_collections' }, - { collection: 'Some-collection', action: 'delete_collections' }, + { + collection: 'Some-collection', + actions: ['create_collections', 'read_collections', 'update_collections', 'delete_collections'], + }, ], dataPermissions: [], nodesPermissions: [], rolesPermissions: [], + usersPermissions: [], }, }, { @@ -150,35 +115,60 @@ only('Integration testing of the roles namespace', () => { clusterPermissions: [], collectionsPermissions: [], dataPermissions: [ - { collection: 'Some-collection', action: 'create_data' }, - { collection: 'Some-collection', action: 'read_data' }, - { collection: 'Some-collection', action: 'update_data' }, - { collection: 'Some-collection', action: 'delete_data' }, + { + collection: 'Some-collection', + actions: ['create_data', 'read_data', 'update_data', 'delete_data'], + }, ], nodesPermissions: [], rolesPermissions: [], + usersPermissions: [], }, }, { - roleName: 'nodes', - permissions: weaviate.permissions.nodes({ + roleName: 'nodes-verbose', + permissions: weaviate.permissions.nodes.verbose({ collection: 'Some-collection', - verbosity: 'verbose', read: true, }), expected: { - name: 'nodes', + name: 'nodes-verbose', + backupsPermissions: [], + clusterPermissions: [], + collectionsPermissions: [], + dataPermissions: [], + nodesPermissions: [ + { collection: 'Some-collection', verbosity: 'verbose', actions: ['read_nodes'] }, + ], + rolesPermissions: [], + usersPermissions: [], + }, + }, + { + roleName: 'nodes-minimal', + permissions: weaviate.permissions.nodes.minimal({ + read: true, + }), + expected: { + name: 'nodes-minimal', backupsPermissions: [], clusterPermissions: [], collectionsPermissions: [], dataPermissions: [], - nodesPermissions: [{ collection: 'Some-collection', verbosity: 'verbose', action: 'read_nodes' }], + nodesPermissions: [{ collection: '*', verbosity: 'minimal', actions: ['read_nodes'] }], rolesPermissions: [], + usersPermissions: [], }, }, { roleName: 'roles', - permissions: weaviate.permissions.roles({ role: 'some-role', manage: true }), + permissions: weaviate.permissions.roles({ + role: 'some-role', + create: true, + read: true, + update: true, + delete: true, + }), expected: { name: 'roles', backupsPermissions: [], @@ -186,7 +176,28 @@ only('Integration testing of the roles namespace', () => { collectionsPermissions: [], dataPermissions: [], nodesPermissions: [], - rolesPermissions: [{ role: 'some-role', action: 'manage_roles' }], + rolesPermissions: [ + { role: 'some-role', actions: ['create_roles', 'read_roles', 'update_roles', 'delete_roles'] }, + ], + usersPermissions: [], + }, + }, + { + roleName: 'users', + permissions: weaviate.permissions.users({ + user: 'some-user', + assign_and_revoke: true, + read: true, + }), + expected: { + name: 'users', + backupsPermissions: [], + clusterPermissions: [], + collectionsPermissions: [], + dataPermissions: [], + nodesPermissions: [], + rolesPermissions: [], + usersPermissions: [{ users: 'some-user', actions: ['assign_and_revoke_users', 'read_users'] }], }, }, ]; @@ -204,4 +215,12 @@ only('Integration testing of the roles namespace', () => { await expect(client.roles.byName('backups')).rejects.toThrowError(WeaviateUnexpectedStatusCodeError); await expect(client.roles.exists('backups')).resolves.toBeFalsy(); }); + + afterAll(() => + Promise.all( + ['backups', 'cluster', 'collections', 'data', 'nodes-verbose', 'nodes-minimal', 'roles', 'users'].map( + (n) => client.roles.delete(n) + ) + ) + ); }); diff --git a/src/roles/types.ts b/src/roles/types.ts index bb11d17e..86af2743 100644 --- a/src/roles/types.ts +++ b/src/roles/types.ts @@ -15,36 +15,42 @@ export type DataAction = Extract< 'create_data' | 'delete_data' | 'read_data' | 'update_data' | 'manage_data' >; export type NodesAction = Extract; -export type RolesAction = Extract; +export type RolesAction = Extract; +export type UsersAction = Extract; export type BackupsPermission = { collection: string; - action: BackupsAction; + actions: BackupsAction[]; }; export type ClusterPermission = { - action: ClusterAction; + actions: ClusterAction[]; }; export type CollectionsPermission = { collection: string; - action: CollectionsAction; + actions: CollectionsAction[]; }; export type DataPermission = { collection: string; - action: DataAction; + actions: DataAction[]; }; export type NodesPermission = { collection: string; verbosity: 'verbose' | 'minimal'; - action: NodesAction; + actions: NodesAction[]; }; export type RolesPermission = { role: string; - action: RolesAction; + actions: RolesAction[]; +}; + +export type UsersPermission = { + users: string; + actions: UsersAction[]; }; export type Role = { @@ -55,10 +61,7 @@ export type Role = { dataPermissions: DataPermission[]; nodesPermissions: NodesPermission[]; rolesPermissions: RolesPermission[]; -}; - -export type User = { - name: string; + usersPermissions: UsersPermission[]; }; export type Permission = @@ -67,6 +70,7 @@ export type Permission = | CollectionsPermission | DataPermission | NodesPermission - | RolesPermission; + | RolesPermission + | UsersPermission; export type PermissionsInput = Permission | Permission[] | Permission[][] | (Permission | Permission[])[]; diff --git a/src/roles/util.ts b/src/roles/util.ts index 299579f5..4452e5a1 100644 --- a/src/roles/util.ts +++ b/src/roles/util.ts @@ -1,4 +1,5 @@ -import { Permission as WeaviatePermission, Role as WeaviateRole } from '../openapi/types.js'; +import { Permission as WeaviatePermission, Role as WeaviateRole, WeaviateUser } from '../openapi/types.js'; +import { User } from '../users/types.js'; import { BackupsAction, BackupsPermission, @@ -14,30 +15,41 @@ import { Role, RolesAction, RolesPermission, - User, + UsersAction, + UsersPermission, } from './types.js'; export class PermissionGuards { + private static includes = (permission: Permission, ...actions: string[]): boolean => + actions.filter((a) => Array.from(permission.actions).includes(a)).length > 0; static isBackups = (permission: Permission): permission is BackupsPermission => - (permission as BackupsPermission).action === 'manage_backups'; + PermissionGuards.includes(permission, 'manage_backups'); static isCluster = (permission: Permission): permission is ClusterPermission => - (permission as ClusterPermission).action === 'read_cluster'; + PermissionGuards.includes(permission, 'read_cluster'); static isCollections = (permission: Permission): permission is CollectionsPermission => - [ + PermissionGuards.includes( + permission, 'create_collections', 'delete_collections', 'read_collections', 'update_collections', - 'manage_collections', - ].includes((permission as CollectionsPermission).action); + 'manage_collections' + ); static isData = (permission: Permission): permission is DataPermission => - ['create_data', 'delete_data', 'read_data', 'update_data', 'manage_data'].includes( - (permission as DataPermission).action + PermissionGuards.includes( + permission, + 'create_data', + 'delete_data', + 'read_data', + 'update_data', + 'manage_data' ); static isNodes = (permission: Permission): permission is NodesPermission => - (permission as NodesPermission).action === 'read_nodes'; + PermissionGuards.includes(permission, 'read_nodes'); static isRoles = (permission: Permission): permission is RolesPermission => - (permission as RolesPermission).action === 'manage_roles'; + PermissionGuards.includes(permission, 'create_role', 'read_roles', 'update_roles', 'delete_roles'); + static isUsers = (permission: Permission): permission is UsersPermission => + PermissionGuards.includes(permission, 'read_users', 'assign_and_revoke_users'); static isPermission = (permissions: PermissionsInput): permissions is Permission => !Array.isArray(permissions); static isPermissionArray = (permissions: PermissionsInput): permissions is Permission[] => @@ -56,89 +68,101 @@ export class Map { static flattenPermissions = (permissions: PermissionsInput): Permission[] => !Array.isArray(permissions) ? [permissions] : permissions.flat(2); - static permissionToWeaviate = (permission: Permission): WeaviatePermission => { + static permissionToWeaviate = (permission: Permission): WeaviatePermission[] => { if (PermissionGuards.isBackups(permission)) { - return { backups: { collection: permission.collection }, action: permission.action }; + return Array.from(permission.actions).map((action) => ({ + backups: { collection: permission.collection }, + action, + })); } else if (PermissionGuards.isCluster(permission)) { - return { action: permission.action }; + return Array.from(permission.actions).map((action) => ({ action })); } else if (PermissionGuards.isCollections(permission)) { - return { collections: { collection: permission.collection }, action: permission.action }; + return Array.from(permission.actions).map((action) => ({ + collections: { collection: permission.collection }, + action, + })); } else if (PermissionGuards.isData(permission)) { - return { data: { collection: permission.collection }, action: permission.action }; + return Array.from(permission.actions).map((action) => ({ + data: { collection: permission.collection }, + action, + })); } else if (PermissionGuards.isNodes(permission)) { - return { + return Array.from(permission.actions).map((action) => ({ nodes: { collection: permission.collection, verbosity: permission.verbosity }, - action: permission.action, - }; + action, + })); } else if (PermissionGuards.isRoles(permission)) { - return { roles: { role: permission.role }, action: permission.action }; + return Array.from(permission.actions).map((action) => ({ roles: { role: permission.role }, action })); + } else if (PermissionGuards.isUsers(permission)) { + return Array.from(permission.actions).map((action) => ({ users: { users: permission.users }, action })); } else { - throw new Error(`Unknown permission type: ${permission}`); + throw new Error(`Unknown permission type: ${JSON.stringify(permission, null, 2)}`); } }; static roleFromWeaviate = (role: WeaviateRole): Role => { - const out: Role = { - name: role.name, - backupsPermissions: [], - clusterPermissions: [], - collectionsPermissions: [], - dataPermissions: [], - nodesPermissions: [], - rolesPermissions: [], + const perms = { + backups: {} as Record, + cluster: {} as Record, + collections: {} as Record, + data: {} as Record, + nodes: {} as Record, + roles: {} as Record, + users: {} as Record, }; role.permissions.forEach((permission) => { if (permission.backups !== undefined) { - if (permission.backups.collection === undefined) { - throw new Error('Backups permission missing collection'); - } - out.backupsPermissions.push({ - collection: permission.backups?.collection, - action: permission.action as BackupsAction, - }); + const key = permission.backups.collection; + if (key === undefined) throw new Error('Backups permission missing collection'); + if (perms.backups[key] === undefined) perms.backups[key] = { collection: key, actions: [] }; + perms.backups[key].actions.push(permission.action as BackupsAction); } else if (permission.action === 'read_cluster') { - out.clusterPermissions.push({ - action: permission.action, - }); + if (perms.cluster[''] === undefined) perms.cluster[''] = { actions: [] }; + perms.cluster[''].actions.push('read_cluster'); } else if (permission.collections !== undefined) { - if (permission.collections.collection === undefined) { - throw new Error('Collections permission missing collection'); - } - out.collectionsPermissions.push({ - collection: permission.collections.collection, - action: permission.action as CollectionsAction, - }); + const key = permission.collections.collection; + if (key === undefined) throw new Error('Collections permission missing collection'); + if (perms.collections[key] === undefined) perms.collections[key] = { collection: key, actions: [] }; + perms.collections[key].actions.push(permission.action as CollectionsAction); } else if (permission.data !== undefined) { - if (permission.data.collection === undefined) { - throw new Error('Data permission missing collection'); - } - out.dataPermissions.push({ - collection: permission.data.collection, - action: permission.action as DataAction, - }); + const key = permission.data.collection; + if (key === undefined) throw new Error('Data permission missing collection'); + if (perms.data[key] === undefined) perms.data[key] = { collection: key, actions: [] }; + perms.data[key].actions.push(permission.action as DataAction); } else if (permission.nodes !== undefined) { - if (permission.nodes.collection === undefined) { - throw new Error('Nodes permission missing collection'); - } - if (permission.nodes.verbosity === undefined) { - throw new Error('Nodes permission missing verbosity'); - } - out.nodesPermissions.push({ - collection: permission.nodes.collection, - verbosity: permission.nodes.verbosity, - action: permission.action as NodesAction, - }); + let { collection } = permission.nodes; + const { verbosity } = permission.nodes; + if (verbosity === undefined) throw new Error('Nodes permission missing verbosity'); + if (verbosity === 'verbose') { + if (collection === undefined) throw new Error('Nodes permission missing collection'); + } else if (verbosity === 'minimal') collection = '*'; + else throw new Error('Nodes permission missing verbosity'); + + const key = `${collection}#${verbosity}`; + if (perms.nodes[key] === undefined) perms.nodes[key] = { collection, verbosity, actions: [] }; + perms.nodes[key].actions.push(permission.action as NodesAction); } else if (permission.roles !== undefined) { - if (permission.roles.role === undefined) { - throw new Error('Roles permission missing role'); - } - out.rolesPermissions.push({ - role: permission.roles.role, - action: permission.action as RolesAction, - }); + const key = permission.roles.role; + if (key === undefined) throw new Error('Roles permission missing role'); + if (perms.roles[key] === undefined) perms.roles[key] = { role: key, actions: [] }; + perms.roles[key].actions.push(permission.action as RolesAction); + } else if (permission.users !== undefined) { + const key = permission.users.users; + if (key === undefined) throw new Error('Users permission missing user'); + if (perms.users[key] === undefined) perms.users[key] = { users: key, actions: [] }; + perms.users[key].actions.push(permission.action as UsersAction); } }); - return out; + return { + name: role.name, + backupsPermissions: Object.values(perms.backups), + clusterPermissions: Object.values(perms.cluster), + collectionsPermissions: Object.values(perms.collections), + dataPermissions: Object.values(perms.data), + nodesPermissions: Object.values(perms.nodes), + rolesPermissions: Object.values(perms.roles), + usersPermissions: Object.values(perms.users), + }; }; static roles = (roles: WeaviateRole[]): Record => @@ -149,7 +173,11 @@ export class Map { static users = (users: string[]): Record => users.reduce((acc, user) => { - acc[user] = { name: user }; + acc[user] = { id: user }; return acc; }, {} as Record); + static user = (user: WeaviateUser): User => ({ + id: user.username, + roles: user.roles?.map(Map.roleFromWeaviate), + }); } diff --git a/src/schema/journey.test.ts b/src/schema/journey.test.ts index 5086b1b9..eb67dc5f 100644 --- a/src/schema/journey.test.ts +++ b/src/schema/journey.test.ts @@ -732,6 +732,12 @@ async function newClassObject(className: string, client: WeaviateClient): Promis dynamicEfMin: 100, ef: -1, maxConnections: 64, + multivector: (await isVer(client, 29, 0)) + ? { + aggregation: 'maxSim', + enabled: false, + } + : undefined, pq: { bitCompression: false, centroids: 256, diff --git a/src/users/index.ts b/src/users/index.ts new file mode 100644 index 00000000..353909fc --- /dev/null +++ b/src/users/index.ts @@ -0,0 +1,55 @@ +import { ConnectionREST } from '../index.js'; +import { Role as WeaviateRole, WeaviateUser } from '../openapi/types.js'; +import { Role } from '../roles/types.js'; +import { Map } from '../roles/util.js'; +import { User } from './types.js'; + +export interface Users { + /** + * Retrieve the information relevant to the currently authenticated user. + * + * @returns {Promise} The user information. + */ + getMyUser: () => Promise; + /** + * Retrieve the roles assigned to a user. + * + * @param {string} userId The ID of the user to retrieve the assigned roles for. + * @returns {Promise>} A map of role names to their respective roles. + */ + getAssignedRoles: (userId: string) => Promise>; + /** + * Assign roles to a user. + * + * @param {string | string[]} roleNames The name or names of the roles to assign. + * @param {string} userId The ID of the user to assign the roles to. + * @returns {Promise} A promise that resolves when the roles are assigned. + */ + assignRoles: (roleNames: string | string[], userId: string) => Promise; + /** + * Revoke roles from a user. + * + * @param {string | string[]} roleNames The name or names of the roles to revoke. + * @param {string} userId The ID of the user to revoke the roles from. + * @returns {Promise} A promise that resolves when the roles are revoked. + */ + revokeRoles: (roleNames: string | string[], userId: string) => Promise; +} + +const users = (connection: ConnectionREST): Users => { + return { + getMyUser: () => connection.get('/users/own-info').then(Map.user), + getAssignedRoles: (userId: string) => + connection.get(`/authz/users/${userId}/roles`).then(Map.roles), + assignRoles: (roleNames: string | string[], userId: string) => + connection.postEmpty(`/authz/users/${userId}/assign`, { + roles: Array.isArray(roleNames) ? roleNames : [roleNames], + }), + revokeRoles: (roleNames: string | string[], userId: string) => + connection.postEmpty(`/authz/users/${userId}/revoke`, { + roles: Array.isArray(roleNames) ? roleNames : [roleNames], + }), + }; +}; + +export default users; diff --git a/src/users/integration.test.ts b/src/users/integration.test.ts new file mode 100644 index 00000000..83d2ec4a --- /dev/null +++ b/src/users/integration.test.ts @@ -0,0 +1,63 @@ +import weaviate, { ApiKey } from '..'; +import { DbVersion } from '../utils/dbVersion'; + +const only = DbVersion.fromString(`v${process.env.WEAVIATE_VERSION!}`).isAtLeast(1, 29, 0) + ? describe + : describe.skip; + +only('Integration testing of the users namespace', () => { + const makeClient = (key: string) => + weaviate.connectToLocal({ + port: 8091, + grpcPort: 50062, + authCredentials: new ApiKey(key), + }); + + beforeAll(() => + makeClient('admin-key').then((c) => + c.roles.create('test', weaviate.permissions.data({ collection: 'Thing', read: true })) + ) + ); + + it('should be able to retrieve own admin user with root roles', async () => { + const user = await makeClient('admin-key').then((client) => client.users.getMyUser()); + expect(user.id).toBe('admin-user'); // defined in the compose file in the ci/ dir + expect(user.roles).toBeDefined(); + }); + + it('should be able to retrieve own custom user with no roles', async () => { + const user = await makeClient('custom-key').then((client) => client.users.getMyUser()); + expect(user.id).toBe('custom-user'); // defined in the compose file in the ci/ dir + expect(user.roles).toBeUndefined(); + }); + + it('should be able to retrieve the assigned roles of a user', async () => { + const roles = await makeClient('admin-key').then((client) => client.users.getAssignedRoles('admin-user')); + expect(roles.root).toBeDefined(); + expect(roles.root.backupsPermissions.length).toBeGreaterThan(0); + expect(roles.root.clusterPermissions.length).toBeGreaterThan(0); + expect(roles.root.collectionsPermissions.length).toBeGreaterThan(0); + expect(roles.root.dataPermissions.length).toBeGreaterThan(0); + expect(roles.root.nodesPermissions.length).toBeGreaterThan(0); + expect(roles.root.rolesPermissions.length).toBeGreaterThan(0); + }); + + it('should be able to assign a role to a user', async () => { + const adminClient = await makeClient('admin-key'); + await adminClient.users.assignRoles('test', 'custom-user'); + + const roles = await adminClient.users.getAssignedRoles('custom-user'); + expect(roles.test).toBeDefined(); + expect(roles.test.dataPermissions.length).toEqual(1); + }); + + it('should be able to revoke a role from a user', async () => { + const adminClient = await makeClient('admin-key'); + await adminClient.users.revokeRoles('test', 'custom-user'); + + const roles = await adminClient.users.getAssignedRoles('custom-user'); + expect(roles.test).toBeUndefined(); + }); + + afterAll(() => makeClient('admin-key').then((c) => c.roles.delete('test'))); +}); diff --git a/src/users/types.ts b/src/users/types.ts new file mode 100644 index 00000000..097b1c57 --- /dev/null +++ b/src/users/types.ts @@ -0,0 +1,6 @@ +import { Role } from '../roles/types.js'; + +export type User = { + id: string; + roles?: Role[]; +}; diff --git a/src/utils/dbVersion.ts b/src/utils/dbVersion.ts index 68e102e6..279537e2 100644 --- a/src/utils/dbVersion.ts +++ b/src/utils/dbVersion.ts @@ -209,6 +209,16 @@ export class DbVersionSupport { }; }); }; + + supportsAggregateGRPC = () => { + return this.dbVersionProvider.getVersion().then((version) => { + return { + version: version, + supports: version.isAtLeast(1, 29, 0), + message: this.errorMessage('Aggregate gRPC method', version.show(), '1.29.0'), + }; + }); + }; } const EMPTY_VERSION = ''; diff --git a/tools/refresh_protos.sh b/tools/refresh_protos.sh index bbcb5529..4bfb0bbf 100755 --- a/tools/refresh_protos.sh +++ b/tools/refresh_protos.sh @@ -1,26 +1,26 @@ #!/bin/bash -echo "this script assumes that you have checked out weaviate next to the client" -cd "${0%/*}/.." +branchOrTag="${1:-main}" +dir="tools" +mkdir -p ${dir} +curl -LkSs https://api.github.com/repos/weaviate/weaviate/tarball/${branchOrTag} -o ${dir}/weaviate.tar.gz +tar --strip-components=3 -C ${dir} -xvf ${dir}/weaviate.tar.gz $(tar -tf ${dir}/weaviate.tar.gz | grep '^weaviate-weaviate-[^/]\+/grpc/proto/v1') - -./node_modules/.bin/grpc_tools_node_protoc -I ../weaviate/grpc/proto \ +./node_modules/.bin/grpc_tools_node_protoc -I ${dir} \ --ts_proto_out=./src/proto \ --ts_proto_opt=forceLong==bigint \ --ts_proto_opt=esModuleInterop=true \ --ts_proto_opt=outputServices=nice-grpc,outputServices=generic-definitions,useExactTypes=false \ - ../weaviate/grpc/proto/v1/*.proto + ${dir}/v1/*.proto -./node_modules/.bin/grpc_tools_node_protoc -I ./tools \ +./node_modules/.bin/grpc_tools_node_protoc -I ${dir} \ --ts_proto_out=./src/proto/google/health/v1 \ --ts_proto_opt=forceLong==bigint \ --ts_proto_opt=esModuleInterop=true \ --ts_proto_opt=outputServices=nice-grpc,outputServices=generic-definitions,useExactTypes=false \ - ./tools/health.proto - + ${dir}/health.proto -# sed -i '' 's/import * as _m0 from/import _m0 from/g' src/proto/v1/*.ts -# sed -i '' 's/import * as _m0 from/import _m0 from/g' src/proto/google/protobuf/struct.ts +rm ${dir}/weaviate.tar.gz sed -i '' 's/\"protobufjs\/minimal\"/\"protobufjs\/minimal.js\"/g' src/proto/v1/*.ts sed -i '' 's/\"protobufjs\/minimal\"/\"protobufjs\/minimal.js\"/g' src/proto/google/protobuf/struct.ts @@ -28,12 +28,14 @@ sed -i '' 's/\"protobufjs\/minimal\"/\"protobufjs\/minimal.js\"/g' src/proto/go sed -i '' 's/google\/protobuf\/struct"/google\/protobuf\/struct.js"/g' src/proto/v1/*.ts -sed -i '' 's/\".\/base\"/\".\/base.js\"/g' src/proto/v1/*.ts -sed -i '' 's/\".\/batch\"/\".\/batch.js\"/g' src/proto/v1/*.ts -sed -i '' 's/\".\/batch_delete\"/\".\/batch_delete.js\"/g' src/proto/v1/*.ts -sed -i '' 's/\".\/generative\"/\".\/generative.js\"/g' src/proto/v1/*.ts -sed -i '' 's/\".\/properties\"/\".\/properties.js\"/g' src/proto/v1/*.ts -sed -i '' 's/\".\/search_get\"/\".\/search_get.js\"/g' src/proto/v1/*.ts -sed -i '' 's/\".\/tenants\"/\".\/tenants.js\"/g' src/proto/v1/*.ts +# replace import paths +for filepath in ${dir}/v1/*; do # loops through known protos + filename=${filepath##*/} # extract filename from path + file=${filename%.*} # remove extension + sed -i '' "s/\".\/${file}\"/\".\/${file}.js\"/g" src/proto/v1/*.ts # replace import paths + # e.g. import { Vectors } from "./base"; => import { Vectors } from "./base.js"; +done + +rm -rf ${dir}/v1 echo "done"